projen
Version:
CDK for software projects
118 lines • 19.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AutoApprove = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const github_credentials_1 = require("./github-credentials");
const pull_request_source_1 = require("./pull-request-source");
const workflows_model_1 = require("./workflows-model");
const component_1 = require("../component");
const DEFAULT_USERNAMES = ["github-actions[bot]"];
const JOB_ID = "approve";
/**
* Auto approve pull requests that meet a criteria
*/
class AutoApprove extends component_1.Component {
static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.github.AutoApprove", version: "0.104.8" };
label;
workflow;
sources;
sourcesProvided;
allowedUsernames;
constructor(github, options = {}) {
super(github.project);
if (options.sources && options.allowedUsernames) {
throw new Error("Only one of 'sources' or 'allowedUsernames' may be specified, not both. Remove the deprecated 'allowedUsernames'.");
}
if (options.credentials && options.secret) {
throw new Error("Only one of 'credentials' or 'secret' may be specified, not both. Remove the deprecated 'secret'.");
}
this.label = options.label ?? "auto-approve";
this.allowedUsernames = options.allowedUsernames;
this.sourcesProvided = options.sources !== undefined;
this.sources = [...(options.sources ?? [])];
const credentials = options.credentials ??
github_credentials_1.GithubCredentials.fromPersonalAccessToken({
secret: options.secret ?? "GITHUB_TOKEN",
});
const approveJob = {
...github.runsOnConfig(options),
permissions: {
pullRequests: workflows_model_1.JobPermission.WRITE,
},
if: (() => this.renderCondition()),
environment: credentials.environment,
steps: [
...credentials.setupSteps,
{
run: 'gh pr review --approve "$PR_NUMBER" --repo "$GH_REPO"',
env: {
GH_TOKEN: credentials.tokenRef,
GH_REPO: "${{ github.repository }}",
PR_NUMBER: "${{ github.event.pull_request.number }}",
},
},
],
};
this.workflow = github.addWorkflow("auto-approve");
this.workflow.on({
// The 'pull request' event gives the workflow 'read-only' permissions on some
// pull requests (such as the ones from dependabot) when using the `GITHUB_TOKEN`
// security token. This prevents the workflow from approving these pull requests.
// Github has placed this guard so as to prevent security attacks by simply opening
// a pull request and triggering a workflow on a commit that was not vetted to make
// unintended changes to the repository.
//
// Instead use the 'pull request target' event here that gives the Github workflow
// 'read-write' permissions. This is safe because, this event, unlike the 'pull request'
// event references the BASE commit of the pull request and not the HEAD commit.
pullRequestTarget: {
types: [
"labeled",
"opened",
"synchronize",
"reopened",
"ready_for_review",
],
},
});
this.workflow.addJobs({ [JOB_ID]: approveJob });
}
/**
* Auto-approve pull requests from this source, in addition to the configured sources.
*
* Adding a source replaces the default source.
*/
addSource(source) {
if (this.allowedUsernames) {
throw new Error("Cannot add sources while the deprecated 'allowedUsernames' is used. Replace 'allowedUsernames' with 'sources: [PullRequestSource.fromUsers({ logins })]'.");
}
this.sourcesProvided = true;
this.sources.push(source);
}
renderCondition() {
const label = `contains(github.event.pull_request.labels.*.name, '${this.label.replace(/'/g, "''")}')`;
if (this.allowedUsernames) {
if (this.allowedUsernames.length === 0) {
return label;
}
const users = this.allowedUsernames
.map((u) => `github.event.pull_request.user.login == '${u}'`)
.join(" || ");
return `${label} && (${users})`;
}
const sources = this.sourcesProvided
? this.sources
: [pull_request_source_1.PullRequestSource.fromUsers({ logins: DEFAULT_USERNAMES })];
if (sources.length === 0) {
throw new Error("AutoApprove has no sources, so no pull request would ever be approved. Add at least one source with the 'sources' option or 'AutoApprove.addSource()'.");
}
// Keeps the rendered condition of the default source stable.
if (sources.length === 1) {
return `${label} && ${sources[0]._toCondition()}`;
}
const conditions = sources.map((s) => s._toCondition()).join(" || ");
return `${label} && (${conditions})`;
}
}
exports.AutoApprove = AutoApprove;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0by1hcHByb3ZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2dpdGh1Yi9hdXRvLWFwcHJvdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUNBLDZEQUF5RDtBQUN6RCwrREFBMEQ7QUFHMUQsdURBQWtEO0FBQ2xELDRDQUF5QztBQUd6QyxNQUFNLGlCQUFpQixHQUFHLENBQUMscUJBQXFCLENBQUMsQ0FBQztBQUNsRCxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUM7QUFnRXpCOztHQUVHO0FBQ0gsTUFBYSxXQUFZLFNBQVEscUJBQVM7O0lBQ3hCLEtBQUssQ0FBUztJQUViLFFBQVEsQ0FBaUI7SUFDekIsT0FBTyxDQUFzQjtJQUN0QyxlQUFlLENBQVU7SUFDaEIsZ0JBQWdCLENBQVk7SUFFN0MsWUFBWSxNQUFjLEVBQUUsVUFBOEIsRUFBRTtRQUMxRCxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXRCLElBQUksT0FBTyxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUNoRCxNQUFNLElBQUksS0FBSyxDQUNiLG1IQUFtSCxDQUNwSCxDQUFDO1FBQ0osQ0FBQztRQUNELElBQUksT0FBTyxDQUFDLFdBQVcsSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDMUMsTUFBTSxJQUFJLEtBQUssQ0FDYixtR0FBbUcsQ0FDcEcsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLElBQUksY0FBYyxDQUFDO1FBQzdDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7UUFDakQsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMsT0FBTyxLQUFLLFNBQVMsQ0FBQztRQUNyRCxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxPQUFPLElBQUksRUFBRSxD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QztZQUN6QixNQUFNLElBQUksS0FBSyxDQUNiLHdKQUF3SixDQUN6SixDQUFDO1FBQ0osQ0FBQztRQUVELDZEQUE2RDtRQUM3RCxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDekIsT0FBTyxHQUFHLEtBQUssT0FBTyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQztRQUNwRCxDQUFDO1FBQ0QsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JFLE9BQU8sR0FBRyxLQUFLLFFBQVEsVUFBVSxHQUFHLENBQUM7SUFDdkMsQ0FBQzs7QUExSEgsa0NBMkhDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBHaXRIdWIgfSBmcm9tIFwiLi9naXRodWJcIjtcbmltcG9ydCB7IEdpdGh1YkNyZWRlbnRpYWxzIH0gZnJvbSBcIi4vZ2l0aHViLWNyZWRlbnRpYWxzXCI7XG5pbXBvcnQgeyBQdWxsUmVxdWVzdFNvdXJjZSB9IGZyb20gXCIuL3B1bGwtcmVxdWVzdC1zb3VyY2VcIjtcbmltcG9ydCB0eXBlIHsgR2l0aHViV29ya2Zsb3cgfSBmcm9tIFwiLi93b3JrZmxvd3NcIjtcbmltcG9ydCB0eXBlIHsgSm9iIH0gZnJvbSBcIi4vd29ya2Zsb3dzLW1vZGVsXCI7XG5pbXBvcnQgeyBKb2JQZXJtaXNzaW9uIH0gZnJvbSBcIi4vd29ya2Zsb3dzLW1vZGVsXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi4vY29tcG9uZW50XCI7XG5pbXBvcnQgdHlwZSB7IFJ1bnNPbk9wdGlvbnMgfSBmcm9tIFwiLi4vcnVubmVyLW9wdGlvbnNcIjtcblxuY29uc3QgREVGQVVMVF9VU0VSTkFNRVMgPSBbXCJnaXRodWItYWN0aW9uc1tib3RdXCJdO1xuY29uc3QgSk9CX0lEID0gXCJhcHByb3ZlXCI7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgJ0F1dG9BcHByb3ZlJ1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dG9BcHByb3ZlT3B0aW9ucyBleHRlbmRzIFJ1bnNPbk9wdGlvbnMge1xuICAvKipcbiAgICogT25seSBwdWxsIHJlcXVlc3RzIGZyb20gb25lIG9mIHRoZXNlIHNvdXJjZXMgd2lsbCBiZSBhdXRvLWFwcHJvdmVkLlxuICAgKlxuICAgKiBDb21wb25lbnRzIHRoYXQgY3JlYXRlIHB1bGwgcmVxdWVzdHMgY2FuIGFkZCBtb3JlIHNvdXJjZXMgd2l0aCBgQXV0b0FwcHJvdmUuYWRkU291cmNlKClgLlxuICAgKiBQcm92aWRpbmcgc291cmNlcywgZWl0aGVyIGhlcmUgb3Igd2l0aCBgYWRkU291cmNlKClgLCByZXBsYWNlcyB0aGUgZGVmYXVsdCBzb3VyY2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IFtQdWxsUmVxdWVzdFNvdXJjZS5mcm9tVXNlcnMoeyBsb2dpbnM6IFtcImdpdGh1Yi1hY3Rpb25zW2JvdF1cIl0gfSldXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VzPzogUHVsbFJlcXVlc3RTb3VyY2VbXTtcblxuICAvKipcbiAgICogT25seSBwdWxsIHJlcXVlc3RzIGF1dGhvcmVkIGJ5IHRoZXNlIEdpdGh1YiB1c2VybmFtZXMgd2lsbCBiZSBhdXRvLWFwcHJvdmVkLlxuICAgKlxuICAgKiBBbiBlbXB0eSBsaXN0IGFwcHJvdmVzIHB1bGwgcmVxdWVzdHMgZnJvbSBhbnkgdXNlci5cbiAgICpcbiAgICogQGRlZmF1bHQgWydnaXRodWItYWN0aW9uc1tib3RdJ11cbiAgICogQGRlcHJlY2F0ZWQgVXNlIGBzb3VyY2VzYCB3aXRoIGBQdWxsUmVxdWVzdFNvdXJjZS5mcm9tVXNlcnMoeyBsb2dpbnMgfSlgIGluc3RlYWQuXG4gICAqL1xuICByZWFkb25seSBhbGxvd2VkVXNlcm5hbWVzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIE9ubHkgcHVsbCByZXF1ZXN0cyB3aXRoIHRoaXMgbGFiZWwgd2lsbCBiZSBhdXRvLWFwcHJvdmVkLlxuICAgKlxuICAgKiBUaGlzIGlzIHJlcXVpcmVkIGluIGFkZGl0aW9uIHRvIG1hdGNoaW5nIG9uZSBvZiB0aGUgYHNvdXJjZXNgLlxuICAgKlxuICAgKiBAZGVmYXVsdCAnYXV0by1hcHByb3ZlJ1xuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWw/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBjcmVkZW50aWFscyB1c2VkIHRvIGFwcHJvdmUgcHVsbCByZXF1ZXN0cy5cbiAgICpcbiAgICogR2l0aHViIGZvcmJpZHMgYW4gaWRlbnRpdHkgdG8gYXBwcm92ZSBpdHMgb3duIHB1bGwgcmVxdWVzdC5cbiAgICogVGhlc2UgY3JlZGVudGlhbHMgbXVzdCBiZWxvbmcgdG8gYSBkaWZmZXJlbnQgaWRlbnRpdHkgdGhhbiB0aGUgb25lIGNyZWF0aW5nIHRoZSBwdWxsIHJlcXVlc3RzLlxuICAgKiBVc2UgYGVudmlyb25tZW50YCBvbiB0aGUgY3JlZGVudGlhbHMgdG8gcmVzdHJpY3Qgd2hpY2ggYnJhbmNoZXMgY2FuIGFjY2VzcyB0aGVtLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRoZSB3b3JrZmxvdydzIGBHSVRIVUJfVE9LRU5gXG4gICAqL1xuICByZWFkb25seSBjcmVkZW50aWFscz86IEdpdGh1YkNyZWRlbnRpYWxzO1xuXG4gIC8qKlxuICAgKiBBIEdpdEh1YiBzZWNyZXQgbmFtZSB3aGljaCBjb250YWlucyBhIEdpdEh1YiBBY2Nlc3MgVG9rZW5cbiAgICogd2l0aCB3cml0ZSBwZXJtaXNzaW9ucyBmb3IgdGhlIGBwdWxsX3JlcXVlc3RgIHNjb3BlLlxuICAgKlxuICAgKiBUaGlzIHRva2VuIGlzIHVzZWQgdG8gYXBwcm92ZSBwdWxsIHJlcXVlc3RzLlxuICAgKlxuICAgKiBHaXRodWIgZm9yYmlkcyBhbiBpZGVudGl0eSB0byBhcHByb3ZlIGl0cyBvd24gcHVsbCByZXF1ZXN0LlxuICAgKiBJZiB5b3VyIHByb2plY3QgcHJvZHVjZXMgYXV0b21hdGVkIHB1bGwgcmVxdWVzdHMgdXNpbmcgdGhlIEdpdGh1YiBkZWZhdWx0IHRva2VuIC1cbiAgICoge0BsaW5rIGh0dHBzOi8vZG9jcy5naXRodWIuY29tL2VuL2FjdGlvbnMvcmVmZXJlbmNlL2F1dGhlbnRpY2F0aW9uLWluLWEtd29ya2Zsb3cgYEdJVEhVQl9UT0tFTmAgfVxuICAgKiAtIHRoYXQgeW91IHdvdWxkIGxpa2UgYXV0byBhcHByb3ZlZCwgc3VjaCBhcyB3aGVuIHVzaW5nIHRoZSBgZGVwc1VwZ3JhZGVgIHByb3BlcnR5IGluXG4gICAqIGBOb2RlUHJvamVjdE9wdGlvbnNgLCB0aGVuIHlvdSBtdXN0IHVzZSBhIGRpZmZlcmVudCB0b2tlbiBoZXJlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcIkdJVEhVQl9UT0tFTlwiXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgY3JlZGVudGlhbHNgIHdpdGggYEdpdGh1YkNyZWRlbnRpYWxzLmZyb21QZXJzb25hbEFjY2Vzc1Rva2VuKHsgc2VjcmV0IH0pYCBpbnN0ZWFkLlxuICAgKi9cbiAgcmVhZG9ubHkgc2VjcmV0Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEF1dG8gYXBwcm92ZSBwdWxsIHJlcXVlc3RzIHRoYXQgbWVldCBhIGNyaXRlcmlhXG4gKi9cbmV4cG9ydCBjbGFzcyBBdXRvQXBwcm92ZSBleHRlbmRzIENvbXBvbmVudCB7XG4gIHB1YmxpYyByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgd29ya2Zsb3c6IEdpdGh1YldvcmtmbG93O1xuICBwcml2YXRlIHJlYWRvbmx5IHNvdXJjZXM6IFB1bGxSZXF1ZXN0U291cmNlW107XG4gIHByaXZhdGUgc291cmNlc1Byb3ZpZGVkOiBib29sZWFuO1xuICBwcml2YXRlIHJlYWRvbmx5IGFsbG93ZWRVc2VybmFtZXM/OiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3RvcihnaXRodWI6IEdpdEh1Yiwgb3B0aW9uczogQXV0b0FwcHJvdmVPcHRpb25zID0ge30pIHtcbiAgICBzdXBlcihnaXRodWIucHJvamVjdCk7XG5cbiAgICBpZiAob3B0aW9ucy5zb3VyY2VzICYmIG9wdGlvbnMuYWxsb3dlZFVzZXJuYW1lcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIk9ubHkgb25lIG9mICdzb3VyY2VzJyBvciAnYWxsb3dlZFVzZXJuYW1lcycgbWF5IGJlIHNwZWNpZmllZCwgbm90IGJvdGguIFJlbW92ZSB0aGUgZGVwcmVjYXRlZCAnYWxsb3dlZFVzZXJuYW1lcycuXCIsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5jcmVkZW50aWFscyAmJiBvcHRpb25zLnNlY3JldCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIk9ubHkgb25lIG9mICdjcmVkZW50aWFscycgb3IgJ3NlY3JldCcgbWF5IGJlIHNwZWNpZmllZCwgbm90IGJvdGguIFJlbW92ZSB0aGUgZGVwcmVjYXRlZCAnc2VjcmV0Jy5cIixcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5sYWJlbCA9IG9wdGlvbnMubGFiZWwgPz8gXCJhdXRvLWFwcHJvdmVcIjtcbiAgICB0aGlzLmFsbG93ZWRVc2VybmFtZXMgPSBvcHRpb25zLmFsbG93ZWRVc2VybmFtZXM7XG4gICAgdGhpcy5zb3VyY2VzUHJvdmlkZWQgPSBvcHRpb25zLnNvdXJjZXMgIT09IHVuZGVmaW5lZDtcbiAgICB0aGlzLnNvdXJjZXMgPSBbLi4uKG9wdGlvbnMuc291cmNlcyA/PyBbXSldO1xuXG4gICAgY29uc3QgY3JlZGVudGlhbHMgPVxuICAgICAgb3B0aW9ucy5jcmVkZW50aWFscyA/P1xuICAgICAgR2l0aHViQ3JlZGVudGlhbHMuZnJvbVBlcnNvbmFsQWNjZXNzVG9rZW4oe1xuICAgICAgICBzZWNyZXQ6IG9wdGlvbnMuc2VjcmV0ID8/IFwiR0lUSFVCX1RPS0VOXCIsXG4gICAgICB9KTtcblxuICAgIGNvbnN0IGFwcHJvdmVKb2I6IEpvYiA9IHtcbiAgICAgIC4uLmdpdGh1Yi5ydW5zT25Db25maWcob3B0aW9ucyksXG4gICAgICBwZXJtaXNzaW9uczoge1xuICAgICAgICBwdWxsUmVxdWVzdHM6IEpvYlBlcm1pc3Npb24uV1JJVEUsXG4gICAgICB9LFxuICAgICAgaWY6ICgoKSA9PiB0aGlzLnJlbmRlckNvbmRpdGlvbigpKSBhcyBhbnksXG4gICAgICBlbnZpcm9ubWVudDogY3JlZGVudGlhbHMuZW52aXJvbm1lbnQsXG4gICAgICBzdGVwczogW1xuICAgICAgICAuLi5jcmVkZW50aWFscy5zZXR1cFN0ZXBzLFxuICAgICAgICB7XG4gICAgICAgICAgcnVuOiAnZ2ggcHIgcmV2aWV3IC0tYXBwcm92ZSBcIiRQUl9OVU1CRVJcIiAtLXJlcG8gXCIkR0hfUkVQT1wiJyxcbiAgICAgICAgICBlbnY6IHtcbiAgICAgICAgICAgIEdIX1RPS0VOOiBjcmVkZW50aWFscy50b2tlblJlZixcbiAgICAgICAgICAgIEdIX1JFUE86IFwiJHt7IGdpdGh1Yi5yZXBvc2l0b3J5IH19XCIsXG4gICAgICAgICAgICBQUl9OVU1CRVI6IFwiJHt7IGdpdGh1Yi5ldmVudC5wdWxsX3JlcXVlc3QubnVtYmVyIH19XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIHRoaXMud29ya2Zsb3cgPSBnaXRodWIuYWRkV29ya2Zsb3coXCJhdXRvLWFwcHJvdmVcIik7XG4gICAgdGhpcy53b3JrZmxvdy5vbih7XG4gICAgICAvLyBUaGUgJ3B1bGwgcmVxdWVzdCcgZXZlbnQgZ2l2ZXMgdGhlIHdvcmtmbG93ICdyZWFkLW9ubHknIHBlcm1pc3Npb25zIG9uIHNvbWVcbiAgICAgIC8vIHB1bGwgcmVxdWVzdHMgKHN1Y2ggYXMgdGhlIG9uZXMgZnJvbSBkZXBlbmRhYm90KSB3aGVuIHVzaW5nIHRoZSBgR0lUSFVCX1RPS0VOYFxuICAgICAgLy8gc2VjdXJpdHkgdG9rZW4uIFRoaXMgcHJldmVudHMgdGhlIHdvcmtmbG93IGZyb20gYXBwcm92aW5nIHRoZXNlIHB1bGwgcmVxdWVzdHMuXG4gICAgICAvLyBHaXRodWIgaGFzIHBsYWNlZCB0aGlzIGd1YXJkIHNvIGFzIHRvIHByZXZlbnQgc2VjdXJpdHkgYXR0YWNrcyBieSBzaW1wbHkgb3BlbmluZ1xuICAgICAgLy8gYSBwdWxsIHJlcXVlc3QgYW5kIHRyaWdnZXJpbmcgYSB3b3JrZmxvdyBvbiBhIGNvbW1pdCB0aGF0IHdhcyBub3QgdmV0dGVkIHRvIG1ha2VcbiAgICAgIC8vIHVuaW50ZW5kZWQgY2hhbmdlcyB0byB0aGUgcmVwb3NpdG9yeS5cbiAgICAgIC8vXG4gICAgICAvLyBJbnN0ZWFkIHVzZSB0aGUgJ3B1bGwgcmVxdWVzdCB0YXJnZXQnIGV2ZW50IGhlcmUgdGhhdCBnaXZlcyB0aGUgR2l0aHViIHdvcmtmbG93XG4gICAgICAvLyAncmVhZC13cml0ZScgcGVybWlzc2lvbnMuIFRoaXMgaXMgc2FmZSBiZWNhdXNlLCB0aGlzIGV2ZW50LCB1bmxpa2UgdGhlICdwdWxsIHJlcXVlc3QnXG4gICAgICAvLyBldmVudCByZWZlcmVuY2VzIHRoZSBCQVNFIGNvbW1pdCBvZiB0aGUgcHVsbCByZXF1ZXN0IGFuZCBub3QgdGhlIEhFQUQgY29tbWl0LlxuICAgICAgcHVsbFJlcXVlc3RUYXJnZXQ6IHtcbiAgICAgICAgdHlwZXM6IFtcbiAgICAgICAgICBcImxhYmVsZWRcIixcbiAgICAgICAgICBcIm9wZW5lZFwiLFxuICAgICAgICAgIFwic3luY2hyb25pemVcIixcbiAgICAgICAgICBcInJlb3BlbmVkXCIsXG4gICAgICAgICAgXCJyZWFkeV9mb3JfcmV2aWV3XCIsXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgIH0pO1xuICAgIHRoaXMud29ya2Zsb3cuYWRkSm9icyh7IFtKT0JfSURdOiBhcHByb3ZlSm9iIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEF1dG8tYXBwcm92ZSBwdWxsIHJlcXVlc3RzIGZyb20gdGhpcyBzb3VyY2UsIGluIGFkZGl0aW9uIHRvIHRoZSBjb25maWd1cmVkIHNvdXJjZXMuXG4gICAqXG4gICAqIEFkZGluZyBhIHNvdXJjZSByZXBsYWNlcyB0aGUgZGVmYXVsdCBzb3VyY2UuXG4gICAqL1xuICBwdWJsaWMgYWRkU291cmNlKHNvdXJjZTogUHVsbFJlcXVlc3RTb3VyY2UpIHtcbiAgICBpZiAodGhpcy5hbGxvd2VkVXNlcm5hbWVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiQ2Fubm90IGFkZCBzb3VyY2VzIHdoaWxlIHRoZSBkZXByZWNhdGVkICdhbGxvd2VkVXNlcm5hbWVzJyBpcyB1c2VkLiBSZXBsYWNlICdhbGxvd2VkVXNlcm5hbWVzJyB3aXRoICdzb3VyY2VzOiBbUHVsbFJlcXVlc3RTb3VyY2UuZnJvbVVzZXJzKHsgbG9naW5zIH0pXScuXCIsXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLnNvdXJjZXNQcm92aWRlZCA9IHRydWU7XG4gICAgdGhpcy5zb3VyY2VzLnB1c2goc291cmNlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyQ29uZGl0aW9uKCk6IHN0cmluZyB7XG4gICAgY29uc3QgbGFiZWwgPSBgY29udGFpbnMoZ2l0aHViLmV2ZW50LnB1bGxfcmVxdWVzdC5sYWJlbHMuKi5uYW1lLCAnJHt0aGlzLmxhYmVsLnJlcGxhY2UoLycvZywgXCInJ1wiKX0nKWA7XG5cbiAgICBpZiAodGhpcy5hbGxvd2VkVXNlcm5hbWVzKSB7XG4gICAgICBpZiAodGhpcy5hbGxvd2VkVXNlcm5hbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbGFiZWw7XG4gICAgICB9XG4gICAgICBjb25zdCB1c2VycyA9IHRoaXMuYWxsb3dlZFVzZXJuYW1lc1xuICAgICAgICAubWFwKCh1KSA9PiBgZ2l0aHViLmV2ZW50LnB1bGxfcmVxdWVzdC51c2VyLmxvZ2luID09ICcke3V9J2ApXG4gICAgICAgIC5qb2luKFwiIHx8IFwiKTtcbiAgICAgIHJldHVybiBgJHtsYWJlbH0gJiYgKCR7dXNlcnN9KWA7XG4gICAgfVxuXG4gICAgY29uc3Qgc291cmNlcyA9IHRoaXMuc291cmNlc1Byb3ZpZGVkXG4gICAgICA/IHRoaXMuc291cmNlc1xuICAgICAgOiBbUHVsbFJlcXVlc3RTb3VyY2UuZnJvbVVzZXJzKHsgbG9naW5zOiBERUZBVUxUX1VTRVJOQU1FUyB9KV07XG5cbiAgICBpZiAoc291cmNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJBdXRvQXBwcm92ZSBoYXMgbm8gc291cmNlcywgc28gbm8gcHVsbCByZXF1ZXN0IHdvdWxkIGV2ZXIgYmUgYXBwcm92ZWQuIEFkZCBhdCBsZWFzdCBvbmUgc291cmNlIHdpdGggdGhlICdzb3VyY2VzJyBvcHRpb24gb3IgJ0F1dG9BcHByb3ZlLmFkZFNvdXJjZSgpJy5cIixcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gS2VlcHMgdGhlIHJlbmRlcmVkIGNvbmRpdGlvbiBvZiB0aGUgZGVmYXVsdCBzb3VyY2Ugc3RhYmxlLlxuICAgIGlmIChzb3VyY2VzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIGAke2xhYmVsfSAmJiAke3NvdXJjZXNbMF0uX3RvQ29uZGl0aW9uKCl9YDtcbiAgICB9XG4gICAgY29uc3QgY29uZGl0aW9ucyA9IHNvdXJjZXMubWFwKChzKSA9PiBzLl90b0NvbmRpdGlvbigpKS5qb2luKFwiIHx8IFwiKTtcbiAgICByZXR1cm4gYCR7bGFiZWx9ICYmICgke2NvbmRpdGlvbnN9KWA7XG4gIH1cbn1cbiJdfQ==