jsii-release
Version:
Release jsii modules to multiple package managers
316 lines • 28.1 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.clone = clone;
exports.detectGHE = detectGHE;
exports.getToken = getToken;
exports.detectSSH = detectSSH;
exports.diffIndex = diffIndex;
exports.add = add;
exports.rm = rm;
exports.commit = commit;
exports.init = init;
exports.tag = tag;
exports.push = push;
exports.checkout = checkout;
exports.username = username;
exports.email = email;
exports.identify = identify;
exports.branchExistsOnRemote = branchExistsOnRemote;
exports.repositorySlug = repositorySlug;
exports.parseRepositorySlug = parseRepositorySlug;
exports.head = head;
const shell = __importStar(require("./shell"));
/**
* Clones a repository from GitHub. Requires a `GITHUB_TOKEN` env variable.
*
* @param repositoryUrl the repository to clone.
* @param targetDir the clone directory.
*/
function clone(repositoryUrl, targetDir, { depth = 1, tags = false, branch } = {}) {
const cmd = ['git', 'clone'];
if (depth) {
cmd.push(`--depth ${depth}`);
}
if (branch) {
cmd.push(`--branch ${branch}`);
}
if (tags) {
cmd.push('--tags');
}
cmd.push(tryDetectRepositoryUrl(repositoryUrl));
cmd.push(targetDir);
shell.run(cmd.join(' '));
}
function tryDetectRepositoryUrl(repositoryUrl) {
const gitHubUseSsh = detectSSH();
if (gitHubUseSsh) {
const sshRepositoryUrl = repositoryUrl.replace('/', ':');
return `git@${sshRepositoryUrl}.git`;
}
const gitHubToken = getToken(detectGHE());
if (!gitHubToken) {
throw new Error('GITHUB_TOKEN env variable is required when GITHUB_USE_SSH env variable is not used');
}
return `https://x-access-token:${gitHubToken}@${repositoryUrl}.git`;
}
/**
* Checks if the current environment is an GHE environment.
*
* This check is using GITHUB_API_URL set in GitHub Actions workflow, as well as common gh cli env variables.
* https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables
* https://cli.github.com/manual/gh_help_environment
*
* @return - `true` if GH_HOST or GITHUB_API_URL env var are defined and not equal to the public github endpoint, otherwise `false`
*/
function detectGHE() {
const githubApiUrl = process.env.GITHUB_API_URL;
const ghHost = process.env.GH_HOST;
return (Boolean(ghHost) && ghHost.trim().toLowerCase() != 'github.com')
|| (Boolean(githubApiUrl) && githubApiUrl.trim().toLowerCase() != 'https://api.github.com');
}
/**
* Returns an appropriate github token from the environment.
*
* @return GH_ENTERPRISE_TOKEN or GITHUB_ENTERPRISE_TOKEN or GITHUB_TOKEN if in an GHE environment, otherwise GITHUB_TOKEN
*/
function getToken(isGHE) {
if (isGHE) {
const githubEnterpiseToken = process.env.GH_ENTERPRISE_TOKEN ?? process.env.GITHUB_ENTERPRISE_TOKEN ?? process.env.GITHUB_TOKEN;
return githubEnterpiseToken;
}
return process.env.GITHUB_TOKEN;
}
/**
* Checks if SSH should be used to clone repo.
* This checks the presence and values of the GIT_USE_SSH env variable and the deprecated GITHUB_USE_SSH for legacy reason. Returns true if either of these env vars are defined and not falsy.
*/
function detectSSH() {
return Boolean(process.env.GIT_USE_SSH ?? process.env.GITHUB_USE_SSH);
}
/**
* Query the git index for changes.
*
* @return True if changes exist, False otherwise.
*/
function diffIndex() {
try {
shell.run('git diff-index --exit-code HEAD --');
return false;
}
catch (err) {
return true;
}
}
/**
* Add files to the index.
*
* @param p the path.
*/
function add(p) {
shell.run(`git add ${p}`);
}
/**
* Remove files from the working tree and from the index
*
* @param p the path.
*/
function rm(p, options = {}) {
const cmd = ['git', 'rm'];
if (options.recursive) {
cmd.push('-r');
}
cmd.push(p);
shell.run(cmd.join(' '));
}
/**
* Commit.
*
* @param message the commit message.
*/
function commit(message) {
shell.run(`git commit -m "${message}"`);
}
/**
* Initialize a repository.
*/
function init() {
shell.run('git init');
}
/**
* Cerate a tag.
*
* @param name tag name.
* @returns true if the tag was created, false if it already exists.
*/
function tag(name) {
try {
shell.run(`git tag -a ${name} -m ${name}`, { capture: true });
return true;
}
catch (e) {
if (e instanceof Error && e.message.includes('already exists')) {
return false;
}
throw e;
}
}
/**
* Push a ref to origin.
*
* @param ref the ref
*/
function push(ref) {
shell.run(`git push origin ${ref}`);
}
/**
* Checkout to a new branch. Creates a new one if `options.createIfMissing` is True and the branch doesn't exist.
*
* @param branch the branch.
* @param options options.
*/
function checkout(branch, options) {
if (options.createIfMissing) {
try {
shell.run(`git show-branch origin/${branch}`, { capture: true });
}
catch (e) {
if (e instanceof Error && e.message.includes('fatal: bad sha1 reference')) {
console.log('Remote branch not found, creating new branch.');
shell.run(`git checkout -B ${branch}`);
return;
}
}
}
shell.run(`git checkout ${branch}`);
}
/**
* Fetch the configured git user name for the current directory.
* Returns undefined if not configured.
*/
function username() {
try {
return shell.run('git config user.name', { capture: true });
}
catch (err) {
if (err instanceof Error) {
console.warn(err.message);
}
return undefined;
}
}
/**
* Fetch the configured git user email for the current directory.
* Returns undefined if not configured.
*/
function email() {
try {
return shell.run('git config user.email', { capture: true });
}
catch (err) {
if (err instanceof Error) {
console.warn(err.message);
}
return undefined;
}
}
/**
* Identify the committer with a username and email.
*
* @param user the username.
* @param email the email address.
*/
function identify(user, address) {
shell.run(`git config user.name "${user}"`);
shell.run(`git config user.email "${address}"`);
}
/**
* Does the given branch exists on the remote.
*/
function branchExistsOnRemote(repositoryUrl, branch) {
return shell.check(`git ls-remote --exit-code --heads ${tryDetectRepositoryUrl(repositoryUrl)} ${branch}`, { capture: true });
}
/**
* Returns the `owner/repo` slug of the `origin` remote in the current
* directory, or undefined if it cannot be determined (e.g. not in a git
* repository, or no `origin` remote configured).
*/
function repositorySlug() {
try {
const url = shell.run('git remote get-url origin', { capture: true });
return parseRepositorySlug(url);
}
catch {
return undefined;
}
}
/**
* Extracts the `owner/repo` slug from a git remote URL.
*
* Supports HTTPS (`https://github.com/owner/repo.git`), SSH
* (`git@github.com:owner/repo.git`, `ssh://git@github.com/owner/repo.git`)
* and URLs without a `.git` suffix.
*
* @returns the `owner/repo` slug, or undefined if it cannot be determined
*/
function parseRepositorySlug(url) {
const path = url
.trim()
.replace(/\.git$/, '')
// drop the scheme (https://, ssh://, git+ssh://, ...)
.replace(/^[a-z+]+:\/\//, '')
// normalize scp-like ssh syntax (git@host:owner/repo) to a path
.replace(/^git@[^:/]+[:/]/, '')
// strip a leading host segment (github.com/owner/repo)
.replace(/^[^/]+\.[^/]+\//, '');
const parts = path.split('/').filter(Boolean);
if (parts.length !== 2) {
return undefined;
}
return parts.join('/');
}
/**
* Returns the commit hash of HEAD in the current directory, or undefined if
* it cannot be determined (e.g. not in a git repository).
*/
function head() {
try {
return shell.run('git rev-parse HEAD', { capture: true });
}
catch {
return undefined;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2l0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hlbHAvZ2l0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBeUJBLHNCQW1CQztBQXlCRCw4QkFNQztBQVFELDRCQU1DO0FBT0QsOEJBRUM7QUFPRCw4QkFPQztBQU9ELGtCQUVDO0FBT0QsZ0JBU0M7QUFPRCx3QkFFQztBQUtELG9CQUVDO0FBUUQsa0JBVUM7QUFPRCxvQkFFQztBQVFELDRCQWFDO0FBTUQsNEJBU0M7QUFNRCxzQkFTQztBQVFELDRCQUdDO0FBS0Qsb0RBRUM7QUFPRCx3Q0FPQztBQVdELGtEQWVDO0FBTUQsb0JBTUM7QUE3U0QsK0NBQWlDO0FBbUJqQzs7Ozs7R0FLRztBQUNILFNBQWdCLEtBQUssQ0FBQyxhQUFxQixFQUFFLFNBQWlCLEVBQUUsRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLElBQUksR0FBRyxLQUFLLEVBQUUsTUFBTSxLQUFtQixFQUFFO0lBQ3BILE1BQU0sR0FBRyxHQUFHLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRTdCLElBQUksS0FBSyxFQUFFLENBQUM7UUFDVixHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRUQsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUNYLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRCxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ1QsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBRUQsR0FBRyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO0lBQ2hELEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFcEIsS0FBSyxDQUFDLEdB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Q0FBQztJQUNuQixDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQixJQUFJO0lBQ2xCLElBQUksQ0FBQztRQUNILE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHNoZWxsIGZyb20gJy4vc2hlbGwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENsb25lT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBAZGVmYXVsdCAxXG4gICAqL1xuICByZWFkb25seSBkZXB0aD86IG51bWJlcjtcblxuICAvKipcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHRhZ3M/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBAZGVmYXVsdCAtIGRlZmF1bHQgYnJhbmNoXG4gICAqL1xuICByZWFkb25seSBicmFuY2g/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ2xvbmVzIGEgcmVwb3NpdG9yeSBmcm9tIEdpdEh1Yi4gUmVxdWlyZXMgYSBgR0lUSFVCX1RPS0VOYCBlbnYgdmFyaWFibGUuXG4gKlxuICogQHBhcmFtIHJlcG9zaXRvcnlVcmwgdGhlIHJlcG9zaXRvcnkgdG8gY2xvbmUuXG4gKiBAcGFyYW0gdGFyZ2V0RGlyIHRoZSBjbG9uZSBkaXJlY3RvcnkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZShyZXBvc2l0b3J5VXJsOiBzdHJpbmcsIHRhcmdldERpcjogc3RyaW5nLCB7IGRlcHRoID0gMSwgdGFncyA9IGZhbHNlLCBicmFuY2ggfTogQ2xvbmVPcHRpb25zID0ge30pIHtcbiAgY29uc3QgY21kID0gWydnaXQnLCAnY2xvbmUnXTtcblxuICBpZiAoZGVwdGgpIHtcbiAgICBjbWQucHVzaChgLS1kZXB0aCAke2RlcHRofWApO1xuICB9XG5cbiAgaWYgKGJyYW5jaCkge1xuICAgIGNtZC5wdXNoKGAtLWJyYW5jaCAke2JyYW5jaH1gKTtcbiAgfVxuXG4gIGlmICh0YWdzKSB7XG4gICAgY21kLnB1c2goJy0tdGFncycpO1xuICB9XG5cbiAgY21kLnB1c2godHJ5RGV0ZWN0UmVwb3NpdG9yeVVybChyZXBvc2l0b3J5VXJsKSk7XG4gIGNtZC5wdXNoKHRhcmdldERpcik7XG5cbiAgc2hlbGwucnVuKGNtZC5qb2luKCcgJykpO1xufVxuXG5mdW5jdGlvbiB0cnlEZXRlY3RSZXBvc2l0b3J5VXJsKHJlcG9zaXRvcnlVcmw6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGdpdEh1YlVzZVNzaCA9IGRldGVjdFNTSCgpO1xuICBpZiAoZ2l0SHViVXNlU3NoKSB7XG4gICAgY29uc3Qgc3NoUmVwb3NpdG9yeVVybCA9IHJlcG9zaXRvcnlVcmwucmVwbGFjZSgnLycsICc6Jyk7XG4gICAgcmV0dXJuIGBnaXRAJHtzc2hSZXBvc2l0b3J5VXJsfS5naXRgO1xuICB9XG5cbiAgY29uc3QgZ2l0SHViVG9rZW4gPSBnZXRUb2tlbihkZXRlY3RHSEUoKSk7XG4gIGlmICghZ2l0SHViVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dJVEhVQl9UT0tFTiBlbnYgdmFyaWFibGUgaXMgcmVxdWlyZWQgd2hlbiBHSVRIVUJfVVNFX1NTSCBlbnYgdmFyaWFibGUgaXMgbm90IHVzZWQnKTtcbiAgfVxuICByZXR1cm4gYGh0dHBzOi8veC1hY2Nlc3MtdG9rZW46JHtnaXRIdWJUb2tlbn1AJHtyZXBvc2l0b3J5VXJsfS5naXRgO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBpcyBhbiBHSEUgZW52aXJvbm1lbnQuXG4gKlxuICogVGhpcyBjaGVjayBpcyB1c2luZyBHSVRIVUJfQVBJX1VSTCBzZXQgaW4gR2l0SHViIEFjdGlvbnMgd29ya2Zsb3csIGFzIHdlbGwgYXMgY29tbW9uIGdoIGNsaSBlbnYgdmFyaWFibGVzLlxuICogaHR0cHM6Ly9kb2NzLmdpdGh1Yi5jb20vZW4vYWN0aW9ucy9sZWFybi1naXRodWItYWN0aW9ucy92YXJpYWJsZXMjZGVmYXVsdC1lbnZpcm9ubWVudC12YXJpYWJsZXNcbiAqIGh0dHBzOi8vY2xpLmdpdGh1Yi5jb20vbWFudWFsL2doX2hlbHBfZW52aXJvbm1lbnRcbiAqXG4gKiBAcmV0dXJuIC0gYHRydWVgIGlmIEdIX0hPU1Qgb3IgR0lUSFVCX0FQSV9VUkwgZW52IHZhciBhcmUgZGVmaW5lZCBhbmQgbm90IGVxdWFsIHRvIHRoZSBwdWJsaWMgZ2l0aHViIGVuZHBvaW50LCBvdGhlcndpc2UgYGZhbHNlYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZGV0ZWN0R0hFKCk6IGJvb2xlYW4ge1xuICBjb25zdCBnaXRodWJBcGlVcmwgPSBwcm9jZXNzLmVudi5HSVRIVUJfQVBJX1VSTDtcbiAgY29uc3QgZ2hIb3N0ID0gcHJvY2Vzcy5lbnYuR0hfSE9TVDtcblxuICByZXR1cm4gKEJvb2xlYW4oZ2hIb3N0KSAmJiBnaEhvc3QhLnRyaW0oKS50b0xvd2VyQ2FzZSgpICE9ICdnaXRodWIuY29tJylcbiAgICB8fCAoQm9vbGVhbihnaXRodWJBcGlVcmwpICYmIGdpdGh1YkFwaVVybCEudHJpbSgpLnRvTG93ZXJDYXNlKCkgIT0gJ2h0dHBzOi8vYXBpLmdpdGh1Yi5jb20nKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIGFwcHJvcHJpYXRlIGdpdGh1YiB0b2tlbiBmcm9tIHRoZSBlbnZpcm9ubWVudC5cbiAqXG4gKiBAcmV0dXJuIEdIX0VOVEVSUFJJU0VfVE9LRU4gb3IgR0lUSFVCX0VOVEVSUFJJU0VfVE9LRU4gb3IgR0lUSFVCX1RPS0VOIGlmIGluIGFuIEdIRSBlbnZpcm9ubWVudCwgb3RoZXJ3aXNlIEdJVEhVQl9UT0tFTlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUb2tlbihpc0dIRTogYm9vbGVhbik6IChzdHJpbmcgfCB1bmRlZmluZWQpIHtcbiAgaWYgKGlzR0hFKSB7XG4gICAgY29uc3QgZ2l0aHViRW50ZXJwaXNlVG9rZW4gPSBwcm9jZXNzLmVudi5HSF9FTlRFUlBSSVNFX1RPS0VOID8/IHByb2Nlc3MuZW52LkdJVEhVQl9FTlRFUlBSSVNFX1RPS0VOID8/IHByb2Nlc3MuZW52LkdJVEhVQl9UT0tFTjtcbiAgICByZXR1cm4gZ2l0aHViRW50ZXJwaXNlVG9rZW47XG4gIH1cbiAgcmV0dXJuIHByb2Nlc3MuZW52LkdJVEhVQl9UT0tFTjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgU1NIIHNob3VsZCBiZSB1c2VkIHRvIGNsb25lIHJlcG8uXG4gKiBUaGlzIGNoZWNrcyB0aGUgcHJlc2VuY2UgYW5kIHZhbHVlcyBvZiB0aGUgR0lUX1VTRV9TU0ggZW52IHZhcmlhYmxlIGFuZCB0aGUgZGVwcmVjYXRlZCBHSVRIVUJfVVNFX1NTSCBmb3IgbGVnYWN5IHJlYXNvbi4gUmV0dXJucyB0cnVlIGlmIGVpdGhlciBvZiB0aGVzZSBlbnYgdmFycyBhcmUgZGVmaW5lZCBhbmQgbm90IGZhbHN5LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkZXRlY3RTU0goKTogYm9vbGVhbiB7XG4gIHJldHVybiBCb29sZWFuKHByb2Nlc3MuZW52LkdJVF9VU0VfU1NIID8/IHByb2Nlc3MuZW52LkdJVEhVQl9VU0VfU1NIKTtcbn1cblxuLyoqXG4gKiBRdWVyeSB0aGUgZ2l0IGluZGV4IGZvciBjaGFuZ2VzLlxuICpcbiAqIEByZXR1cm4gVHJ1ZSBpZiBjaGFuZ2VzIGV4aXN0LCBGYWxzZSBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaWZmSW5kZXgoKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgc2hlbGwucnVuKCdnaXQgZGlmZi1pbmRleCAtLWV4aXQtY29kZSBIRUFEIC0tJyk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG4vKipcbiAqIEFkZCBmaWxlcyB0byB0aGUgaW5kZXguXG4gKlxuICogQHBhcmFtIHAgdGhlIHBhdGguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGQocDogc3RyaW5nKSB7XG4gIHNoZWxsLnJ1bihgZ2l0IGFkZCAke3B9YCk7XG59XG5cbi8qKlxuICogUmVtb3ZlIGZpbGVzIGZyb20gdGhlIHdvcmtpbmcgdHJlZSBhbmQgZnJvbSB0aGUgaW5kZXhcbiAqXG4gKiBAcGFyYW0gcCB0aGUgcGF0aC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJtKHA6IHN0cmluZywgb3B0aW9uczogeyByZWN1cnNpdmU/OiBib29sZWFuIH0gPSB7fSkge1xuICBjb25zdCBjbWQgPSBbJ2dpdCcsICdybSddO1xuICBpZiAob3B0aW9ucy5yZWN1cnNpdmUpIHtcbiAgICBjbWQucHVzaCgnLXInKTtcbiAgfVxuXG4gIGNtZC5wdXNoKHApO1xuXG4gIHNoZWxsLnJ1bihjbWQuam9pbignICcpKTtcbn1cblxuLyoqXG4gKiBDb21taXQuXG4gKlxuICogQHBhcmFtIG1lc3NhZ2UgdGhlIGNvbW1pdCBtZXNzYWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tbWl0KG1lc3NhZ2U6IHN0cmluZykge1xuICBzaGVsbC5ydW4oYGdpdCBjb21taXQgLW0gXCIke21lc3NhZ2V9XCJgKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIGEgcmVwb3NpdG9yeS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXQoKSB7XG4gIHNoZWxsLnJ1bignZ2l0IGluaXQnKTtcbn1cblxuLyoqXG4gKiBDZXJhdGUgYSB0YWcuXG4gKlxuICogQHBhcmFtIG5hbWUgdGFnIG5hbWUuXG4gKiBAcmV0dXJucyB0cnVlIGlmIHRoZSB0YWcgd2FzIGNyZWF0ZWQsIGZhbHNlIGlmIGl0IGFscmVhZHkgZXhpc3RzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdGFnKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIHNoZWxsLnJ1bihgZ2l0IHRhZyAtYSAke25hbWV9IC1tICR7bmFtZX1gLCB7IGNhcHR1cmU6IHRydWUgfSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yICYmIGUubWVzc2FnZS5pbmNsdWRlcygnYWxyZWFkeSBleGlzdHMnKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0aHJvdyBlO1xuICB9XG59XG5cbi8qKlxuICogUHVzaCBhIHJlZiB0byBvcmlnaW4uXG4gKlxuICogQHBhcmFtIHJlZiB0aGUgcmVmXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwdXNoKHJlZjogc3RyaW5nKSB7XG4gIHNoZWxsLnJ1bihgZ2l0IHB1c2ggb3JpZ2luICR7cmVmfWApO1xufVxuXG4vKipcbiAqIENoZWNrb3V0IHRvIGEgbmV3IGJyYW5jaC4gQ3JlYXRlcyBhIG5ldyBvbmUgaWYgYG9wdGlvbnMuY3JlYXRlSWZNaXNzaW5nYCBpcyBUcnVlIGFuZCB0aGUgYnJhbmNoIGRvZXNuJ3QgZXhpc3QuXG4gKlxuICogQHBhcmFtIGJyYW5jaCB0aGUgYnJhbmNoLlxuICogQHBhcmFtIG9wdGlvbnMgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrb3V0KGJyYW5jaDogc3RyaW5nLCBvcHRpb25zOiB7IGNyZWF0ZUlmTWlzc2luZz86IGJvb2xlYW4gfSApIHtcbiAgaWYgKG9wdGlvbnMuY3JlYXRlSWZNaXNzaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIHNoZWxsLnJ1bihgZ2l0IHNob3ctYnJhbmNoIG9yaWdpbi8ke2JyYW5jaH1gLCB7IGNhcHR1cmU6IHRydWUgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvciAmJiBlLm1lc3NhZ2UuaW5jbHVkZXMoJ2ZhdGFsOiBiYWQgc2hhMSByZWZlcmVuY2UnKSkge1xuICAgICAgICBjb25zb2xlLmxvZygnUmVtb3RlIGJyYW5jaCBub3QgZm91bmQsIGNyZWF0aW5nIG5ldyBicmFuY2guJyk7XG4gICAgICAgIHNoZWxsLnJ1bihgZ2l0IGNoZWNrb3V0IC1CICR7YnJhbmNofWApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHNoZWxsLnJ1bihgZ2l0IGNoZWNrb3V0ICR7YnJhbmNofWApO1xufVxuXG4vKipcbiAqIEZldGNoIHRoZSBjb25maWd1cmVkIGdpdCB1c2VyIG5hbWUgZm9yIHRoZSBjdXJyZW50IGRpcmVjdG9yeS5cbiAqIFJldHVybnMgdW5kZWZpbmVkIGlmIG5vdCBjb25maWd1cmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlcm5hbWUoKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHNoZWxsLnJ1bignZ2l0IGNvbmZpZyB1c2VyLm5hbWUnLCB7IGNhcHR1cmU6IHRydWUgfSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgY29uc29sZS53YXJuKGVyci5tZXNzYWdlKTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIEZldGNoIHRoZSBjb25maWd1cmVkIGdpdCB1c2VyIGVtYWlsIGZvciB0aGUgY3VycmVudCBkaXJlY3RvcnkuXG4gKiBSZXR1cm5zIHVuZGVmaW5lZCBpZiBub3QgY29uZmlndXJlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVtYWlsKCkge1xuICB0cnkge1xuICAgIHJldHVybiBzaGVsbC5ydW4oJ2dpdCBjb25maWcgdXNlci5lbWFpbCcsIHsgY2FwdHVyZTogdHJ1ZSB9KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBjb25zb2xlLndhcm4oZXJyLm1lc3NhZ2UpO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKlxuICogSWRlbnRpZnkgdGhlIGNvbW1pdHRlciB3aXRoIGEgdXNlcm5hbWUgYW5kIGVtYWlsLlxuICpcbiAqIEBwYXJhbSB1c2VyIHRoZSB1c2VybmFtZS5cbiAqIEBwYXJhbSBlbWFpbCB0aGUgZW1haWwgYWRkcmVzcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aWZ5KHVzZXI6IHN0cmluZywgYWRkcmVzczogc3RyaW5nKSB7XG4gIHNoZWxsLnJ1bihgZ2l0IGNvbmZpZyB1c2VyLm5hbWUgXCIke3VzZXJ9XCJgKTtcbiAgc2hlbGwucnVuKGBnaXQgY29uZmlnIHVzZXIuZW1haWwgXCIke2FkZHJlc3N9XCJgKTtcbn1cblxuLyoqXG4gKiBEb2VzIHRoZSBnaXZlbiBicmFuY2ggZXhpc3RzIG9uIHRoZSByZW1vdGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBicmFuY2hFeGlzdHNPblJlbW90ZShyZXBvc2l0b3J5VXJsOiBzdHJpbmcsIGJyYW5jaDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBzaGVsbC5jaGVjayhgZ2l0IGxzLXJlbW90ZSAtLWV4aXQtY29kZSAtLWhlYWRzICR7dHJ5RGV0ZWN0UmVwb3NpdG9yeVVybChyZXBvc2l0b3J5VXJsKX0gJHticmFuY2h9YCwgeyBjYXB0dXJlOiB0cnVlIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGBvd25lci9yZXBvYCBzbHVnIG9mIHRoZSBgb3JpZ2luYCByZW1vdGUgaW4gdGhlIGN1cnJlbnRcbiAqIGRpcmVjdG9yeSwgb3IgdW5kZWZpbmVkIGlmIGl0IGNhbm5vdCBiZSBkZXRlcm1pbmVkIChlLmcuIG5vdCBpbiBhIGdpdFxuICogcmVwb3NpdG9yeSwgb3Igbm8gYG9yaWdpbmAgcmVtb3RlIGNvbmZpZ3VyZWQpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVwb3NpdG9yeVNsdWcoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgdHJ5IHtcbiAgICBjb25zdCB1cmwgPSBzaGVsbC5ydW4oJ2dpdCByZW1vdGUgZ2V0LXVybCBvcmlnaW4nLCB7IGNhcHR1cmU6IHRydWUgfSk7XG4gICAgcmV0dXJuIHBhcnNlUmVwb3NpdG9yeVNsdWcodXJsKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIEV4dHJhY3RzIHRoZSBgb3duZXIvcmVwb2Agc2x1ZyBmcm9tIGEgZ2l0IHJlbW90ZSBVUkwuXG4gKlxuICogU3VwcG9ydHMgSFRUUFMgKGBodHRwczovL2dpdGh1Yi5jb20vb3duZXIvcmVwby5naXRgKSwgU1NIXG4gKiAoYGdpdEBnaXRodWIuY29tOm93bmVyL3JlcG8uZ2l0YCwgYHNzaDovL2dpdEBnaXRodWIuY29tL293bmVyL3JlcG8uZ2l0YClcbiAqIGFuZCBVUkxzIHdpdGhvdXQgYSBgLmdpdGAgc3VmZml4LlxuICpcbiAqIEByZXR1cm5zIHRoZSBgb3duZXIvcmVwb2Agc2x1Zywgb3IgdW5kZWZpbmVkIGlmIGl0IGNhbm5vdCBiZSBkZXRlcm1pbmVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVJlcG9zaXRvcnlTbHVnKHVybDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcGF0aCA9IHVybFxuICAgIC50cmltKClcbiAgICAucmVwbGFjZSgvXFwuZ2l0JC8sICcnKVxuICAgIC8vIGRyb3AgdGhlIHNjaGVtZSAoaHR0cHM6Ly8sIHNzaDovLywgZ2l0K3NzaDovLywgLi4uKVxuICAgIC5yZXBsYWNlKC9eW2EteitdKzpcXC9cXC8vLCAnJylcbiAgICAvLyBub3JtYWxpemUgc2NwLWxpa2Ugc3NoIHN5bnRheCAoZ2l0QGhvc3Q6b3duZXIvcmVwbykgdG8gYSBwYXRoXG4gICAgLnJlcGxhY2UoL15naXRAW146L10rWzovXS8sICcnKVxuICAgIC8vIHN0cmlwIGEgbGVhZGluZyBob3N0IHNlZ21lbnQgKGdpdGh1Yi5jb20vb3duZXIvcmVwbylcbiAgICAucmVwbGFjZSgvXlteL10rXFwuW14vXStcXC8vLCAnJyk7XG4gIGNvbnN0IHBhcnRzID0gcGF0aC5zcGxpdCgnLycpLmZpbHRlcihCb29sZWFuKTtcbiAgaWYgKHBhcnRzLmxlbmd0aCAhPT0gMikge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIHBhcnRzLmpvaW4oJy8nKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBjb21taXQgaGFzaCBvZiBIRUFEIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSwgb3IgdW5kZWZpbmVkIGlmXG4gKiBpdCBjYW5ub3QgYmUgZGV0ZXJtaW5lZCAoZS5nLiBub3QgaW4gYSBnaXQgcmVwb3NpdG9yeSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoZWFkKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHNoZWxsLnJ1bignZ2l0IHJldi1wYXJzZSBIRUFEJywgeyBjYXB0dXJlOiB0cnVlIH0pO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG4iXX0=