@aws/cloudfront-hosting-toolkit
Version:
CloudFront Hosting Toolkit offers the convenience of a managed frontend hosting service while retaining full control over the hosting and deployment infrastructure to make it your own.
184 lines (181 loc) • 30.5 kB
JavaScript
;
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getUserDomainPreference = exports.copyCffIfNotExists = exports.copyBuildConfigIfNotExists = exports.init_s3 = exports.saveAndLogConfiguration = exports.init_repository = void 0;
const fs_1 = __importDefault(require("fs"));
const prompt_questions_1 = require("../utils/prompt_questions");
const helper_1 = require("../utils/helper");
const constants_1 = require("../shared/constants");
async function handleInitCommand(s3) {
s3 ? await init_s3() : await init_repository();
}
exports.default = handleInitCommand;
async function init_repository() {
console.log("\n--------------------- Static hosting configuration wizard : GitHub Source Code Repository Based -------------------\n");
let currentHostingConfig = {
repoUrl: "",
branchName: "",
framework: "",
domainName: undefined,
hostedZoneId: undefined,
};
if ((0, helper_1.doesHostingConfigurationFileExist)()) {
const loadedConfig = await (0, helper_1.loadHostingConfiguration)();
if ((0, helper_1.isRepoConfig)(loadedConfig)) {
currentHostingConfig = loadedConfig;
}
}
console.log(`\n\n To facilitate the deployment of the necessary infrastructure for website hosting, certain information is required.\n ${constants_1.TOOL_NAME} will aim to find as much relevant data as possible.\n\n`);
let identifiedRepositoryUrl, identifiedBranchName, identifiedFrameworkName;
//check github configuration
console.log("Collecting information about the GitHub repository from " +
(0, helper_1.getCLIExecutionFolder)());
identifiedRepositoryUrl = (0, helper_1.getGitRemote)();
identifiedBranchName = (0, helper_1.getGitBranch)();
const repoQuestions = await (0, helper_1.startPrompt)((0, prompt_questions_1.getGithubRepositoryQuestions)(currentHostingConfig.repoUrl
? currentHostingConfig.repoUrl
: identifiedRepositoryUrl, currentHostingConfig.branchName
? currentHostingConfig.branchName
: identifiedBranchName));
console.log("\nCollecting information about the frontend framework used to enable the provision of the appropriate build configuration.");
identifiedFrameworkName = await (0, helper_1.detectFrontendFramework)((0, helper_1.getCLIExecutionFolder)());
const frameworkSelection = await (0, helper_1.startPrompt)((0, prompt_questions_1.getFrameworkSelectionQuestions)(currentHostingConfig.framework
? currentHostingConfig.framework
: identifiedFrameworkName));
const repositoryUrl = repoQuestions.repoUrl;
const branchName = repoQuestions.branchName;
const frameworkName = frameworkSelection.framework;
if (frameworkName === "exit") {
process.exit(0);
}
console.log("\n");
const { domainName, hostedZoneId } = await getUserDomainPreference(currentHostingConfig);
console.log("\n----------------------------------------------------");
console.log(`Here is the configuration that has been generated and saved to ${constants_1.TOOL_NAME}/${constants_1.CONFIG_FILE_NAME} file.:`);
console.log("> GitHub repository: " + repositoryUrl + "/" + branchName);
console.log("> Framework: " + frameworkName);
console.log("> Domain name: " + (domainName ? domainName : "No"));
console.log(hostedZoneId ? "> Hosted zone ID: " + hostedZoneId : "");
console.log("\n--");
copyBuildConfigIfNotExists("hosting_" + frameworkName + ".yml");
copyCffIfNotExists("index_" + frameworkName + ".js");
const newHostingConfiguration = {
repoUrl: repositoryUrl,
branchName: branchName,
framework: frameworkName,
...(domainName ? { domainName } : {}),
...(hostedZoneId ? { hostedZoneId } : {}),
};
saveAndLogConfiguration(newHostingConfiguration);
}
exports.init_repository = init_repository;
function saveAndLogConfiguration(newHostingConfiguration) {
const jsonHostingConfiguration = JSON.stringify(newHostingConfiguration, null, 2);
fs_1.default.writeFileSync((0, helper_1.getConfigFilePath)(), jsonHostingConfiguration);
console.log(`> Configuration file generated ${(0, helper_1.getConfigFilePath)()}`);
console.log(`> Build configuration generated ${(0, helper_1.getBuildConfigFilePath)()}`);
console.log(`> CloudFront Function source code generated ${(0, helper_1.getCffConfigFilePath)()}`);
console.log(`\n\nThe initialization process has been completed. You may now execute '${constants_1.TOOL_NAME} deploy' to deploy the infrastructure.\n`);
}
exports.saveAndLogConfiguration = saveAndLogConfiguration;
async function init_s3() {
console.log("\n--------------------- Static hosting configuration wizard: S3 Source Code Repository Based -------------------\n");
let currentHostingConfig = {
s3bucket: "",
s3path: "",
domainName: undefined,
hostedZoneId: undefined,
};
if ((0, helper_1.doesHostingConfigurationFileExist)()) {
const loadedConfig = await (0, helper_1.loadHostingConfiguration)();
if ((0, helper_1.isS3Config)(loadedConfig)) {
currentHostingConfig = loadedConfig;
}
}
const s3questions = await (0, helper_1.startPrompt)((0, prompt_questions_1.getS3BucketConfigurationQuestions)(currentHostingConfig.s3bucket, currentHostingConfig.s3path));
const { domainName, hostedZoneId } = await getUserDomainPreference(currentHostingConfig);
console.log("\n----------------------------------------------------");
console.log("Please review the following captured information:");
console.log("> S3 Bucket: " + s3questions.s3bucket);
console.log("> S3 Prefix: " + s3questions.s3path);
console.log("> Domain name: " + (domainName ? domainName : "No"));
console.log(hostedZoneId ? "> Hosted zone ID: " + hostedZoneId : "");
console.log("\n--");
copyBuildConfigIfNotExists("s3_build_config.yml");
copyCffIfNotExists("index_basic.js");
const newHostingConfiguration = {
s3bucket: s3questions.s3bucket,
s3path: s3questions.s3path,
...(domainName ? { domainName } : {}),
...(hostedZoneId ? { hostedZoneId } : {}),
};
saveAndLogConfiguration(newHostingConfiguration);
}
exports.init_s3 = init_s3;
/**
* Copies a build configuration template to the tool folder if it does not already exist.
*
* @param frameworkName - The name of the framework to determine the source build configuration file.
*/
function copyBuildConfigIfNotExists(fileName) {
const srcBuildConfigFile = (0, helper_1.getBuildConfigTemplatesFolder)() + "/" + fileName;
if (!fs_1.default.existsSync((0, helper_1.getToolFolder)())) {
fs_1.default.mkdirSync((0, helper_1.getToolFolder)());
}
if (!fs_1.default.existsSync((0, helper_1.getBuildConfigFilePath)())) {
fs_1.default.copyFileSync(srcBuildConfigFile, (0, helper_1.getBuildConfigFilePath)());
}
}
exports.copyBuildConfigIfNotExists = copyBuildConfigIfNotExists;
function copyCffIfNotExists(fileName) {
const srcBuildConfigFile = (0, helper_1.getCffTemplatesFolder)() + "/" + fileName;
if (!fs_1.default.existsSync((0, helper_1.getToolFolder)())) {
fs_1.default.mkdirSync((0, helper_1.getToolFolder)());
}
if (!fs_1.default.existsSync((0, helper_1.getCffConfigFilePath)())) {
fs_1.default.copyFileSync(srcBuildConfigFile, (0, helper_1.getCffConfigFilePath)());
}
}
exports.copyCffIfNotExists = copyCffIfNotExists;
async function getUserDomainPreference(currentHostingConfig) {
const withDomainName = await (0, helper_1.startPrompt)((0, prompt_questions_1.getDomainNameQuestion)(currentHostingConfig.domainName));
if (withDomainName.value === "yes") {
const domainNamePrompt = await (0, helper_1.startPrompt)((0, prompt_questions_1.domainNameDetailsQuestions)(currentHostingConfig.domainName));
if (domainNamePrompt.registrar === "current") {
const hostedZone = await (0, helper_1.startPrompt)((0, prompt_questions_1.hostedZoneIdQuestion)(currentHostingConfig.hostedZoneId));
return {
domainName: domainNamePrompt.domainName,
hostedZoneId: hostedZone.hostedZoneId,
};
}
else {
return {
domainName: domainNamePrompt.domainName,
hostedZoneId: undefined,
};
}
}
else {
return {
domainName: undefined,
hostedZoneId: undefined,
};
}
}
exports.getUserDomainPreference = getUserDomainPreference;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImluaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7RUFjRTs7Ozs7O0FBRUYsNENBQW9CO0FBRXBCLGdFQU9tQztBQUVuQyw0Q0FnQnlCO0FBQ3pCLG1EQUFrRTtBQUduRCxLQUFLLFVBQVUsaUJBQWlCLENBQUMsRUFBVztJQUN6RCxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sZUFBZSxFQUFFLENBQUM7QUFDakQsQ0FBQztBQUZELG9DQUVDO0FBRU0sS0FBSyxVQUFVLGVBQWU7SUFDbkMsT0FBTyxDQUFDLEdBQUcsQ0FDVCx5SEFBeUgsQ0FDMUgsQ0FBQztJQUVGLElBQUksb0JBQW9CLEdBQXlCO1FBQy9DLE9BQU8sRUFBRSxFQUFFO1FBQ1gsVUFBVSxFQUFFLEVBQUU7UUFDZCxTQUFTLEVBQUUsRUFBRTtRQUNiLFVBQVUsRUFBRSxTQUFTO1FBQ3JCLFlBQVksRUFBRSxTQUFTO0tBQ3hCLENBQUM7SUFFRixJQUFJLElBQUEsMENBQWlDLEdBQUUsRUFBRSxDQUFDO1FBQ3hDLE1BQU0sWUFBWSxHQUFHLE1BQU0sSUFBQSxpQ0FBd0IsR0FBRSxDQUFDO1FBRXRELElBQUksSUFBQSxxQkFBWSxFQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDL0Isb0JBQW9CLEdBQUcsWUFBWSxDQUFDO1FBQ3RDLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FDVCw2SEFBNkgscUJBQVMsMERBQTBELENBQ2pNLENBQUM7SUFFRixJQUFJLHVCQUErQixFQUNqQyxvQkFBNEIsRUFDNUIsdUJBQStCLENBQUM7SUFFbEMsNEJBQTRCO0lBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQ1QsMERBQTBEO1FBQ3hELElBQUEsOEJBQXFCLEdBQUUsQ0FDMUIsQ0FBQztJQUNGLHVCQUF1QixHQUFHLElBQUEscUJBQVksR0FB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SUFFRixJQUFJLGNBQWMsQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDbkMsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLElBQUEsb0JBQVcsRUFDeEMsSUFBQSw2Q0FBMEIsRUFBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsQ0FDNUQsQ0FBQztRQUVGLElBQUksZ0JBQWdCLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzdDLE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBQSxvQkFBVyxFQUNsQyxJQUFBLHVDQUFvQixFQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxDQUN4RCxDQUFDO1lBRUYsT0FBTztnQkFDTCxVQUFVLEVBQUUsZ0JBQWdCLENBQUMsVUFBVTtnQkFDdkMsWUFBWSxFQUFFLFVBQVUsQ0FBQyxZQUFZO2FBQ3RDLENBQUM7UUFDSixDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU87Z0JBQ0wsVUFBVSxFQUFFLGdCQUFnQixDQUFDLFVBQVU7Z0JBQ3ZDLFlBQVksRUFBRSxTQUFTO2FBQ3hCLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztTQUFNLENBQUM7UUFDTixPQUFPO1lBQ0wsVUFBVSxFQUFFLFNBQVM7WUFDckIsWUFBWSxFQUFFLFNBQVM7U0FDeEIsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDO0FBakNELDBEQWlDQyIsInNvdXJjZXNDb250ZW50IjpbIiMhL3Vzci9iaW4vZW52IG5vZGVcclxuLypcclxuICBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cclxuICBcclxuICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpLlxyXG4gIFlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cclxuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICBcclxuICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcbiAgXHJcbiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxyXG4gIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcclxuICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cclxuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXHJcbiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiovXHJcblxyXG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XHJcblxyXG5pbXBvcnQge1xyXG4gIGdldEZyYW1ld29ya1NlbGVjdGlvblF1ZXN0aW9ucyxcclxuICBkb21haW5OYW1lRGV0YWlsc1F1ZXN0aW9ucyxcclxuICBnZXRHaXRodWJSZXBvc2l0b3J5UXVlc3Rpb25zLFxyXG4gIGdldFMzQnVja2V0Q29uZmlndXJhdGlvblF1ZXN0aW9ucyxcclxuICBnZXREb21haW5OYW1lUXVlc3Rpb24sXHJcbiAgaG9zdGVkWm9uZUlkUXVlc3Rpb24sXHJcbn0gZnJvbSBcIi4uL3V0aWxzL3Byb21wdF9xdWVzdGlvbnNcIjtcclxuXHJcbmltcG9ydCB7XHJcbiAgZ2V0Q0xJRXhlY3V0aW9uRm9sZGVyLFxyXG4gIGdldFRvb2xGb2xkZXIsXHJcbiAgZ2V0Q29uZmlnRmlsZVBhdGgsXHJcbiAgZ2V0QnVpbGRDb25maWdGaWxlUGF0aCxcclxuICBnZXRCdWlsZENvbmZpZ1RlbXBsYXRlc0ZvbGRlcixcclxuICBzdGFydFByb21wdCxcclxuICBsb2FkSG9zdGluZ0NvbmZpZ3VyYXRpb24sXHJcbiAgaXNSZXBvQ29uZmlnLFxyXG4gIGlzUzNDb25maWcsXHJcbiAgZ2V0R2l0UmVtb3RlLFxyXG4gIGdldEdpdEJyYW5jaCxcclxuICBkb2VzSG9zdGluZ0NvbmZpZ3VyYXRpb25GaWxlRXhpc3QsXHJcbiAgZGV0ZWN0RnJvbnRlbmRGcmFtZXdvcmssXHJcbiAgZ2V0Q2ZmVGVtcGxhdGVzRm9sZGVyLFxyXG4gIGdldENmZkNvbmZpZ0ZpbGVQYXRoLFxyXG59IGZyb20gXCIuLi91dGlscy9oZWxwZXJcIjtcclxuaW1wb3J0IHsgQ09ORklHX0ZJTEVfTkFNRSwgVE9PTF9OQU1FIH0gZnJvbSBcIi4uL3NoYXJlZC9jb25zdGFudHNcIjtcclxuaW1wb3J0IHsgSG9zdGluZ0NvbmZpZ3VyYXRpb24gfSBmcm9tIFwiLi4vc2hhcmVkL3R5cGVzXCI7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBhc3luYyBmdW5jdGlvbiBoYW5kbGVJbml0Q29tbWFuZChzMzogYm9vbGVhbikge1xyXG4gIHMzID8gYXdhaXQgaW5pdF9zMygpIDogYXdhaXQgaW5pdF9yZXBvc2l0b3J5KCk7XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbml0X3JlcG9zaXRvcnkoKSB7XHJcbiAgY29uc29sZS5sb2coXHJcbiAgICBcIlxcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLSBTdGF0aWMgaG9zdGluZyBjb25maWd1cmF0aW9uIHdpemFyZCA6IEdpdEh1YiBTb3VyY2UgQ29kZSBSZXBvc2l0b3J5IEJhc2VkIC0tLS0tLS0tLS0tLS0tLS0tLS1cXG5cIlxyXG4gICk7XHJcblxyXG4gIGxldCBjdXJyZW50SG9zdGluZ0NvbmZpZzogSG9zdGluZ0NvbmZpZ3VyYXRpb24gPSB7XHJcbiAgICByZXBvVXJsOiBcIlwiLFxyXG4gICAgYnJhbmNoTmFtZTogXCJcIixcclxuICAgIGZyYW1ld29yazogXCJcIixcclxuICAgIGRvbWFpbk5hbWU6IHVuZGVmaW5lZCxcclxuICAgIGhvc3RlZFpvbmVJZDogdW5kZWZpbmVkLFxyXG4gIH07XHJcblxyXG4gIGlmIChkb2VzSG9zdGluZ0NvbmZpZ3VyYXRpb25GaWxlRXhpc3QoKSkge1xyXG4gICAgY29uc3QgbG9hZGVkQ29uZmlnID0gYXdhaXQgbG9hZEhvc3RpbmdDb25maWd1cmF0aW9uKCk7XHJcblxyXG4gICAgaWYgKGlzUmVwb0NvbmZpZyhsb2FkZWRDb25maWcpKSB7XHJcbiAgICAgIGN1cnJlbnRIb3N0aW5nQ29uZmlnID0gbG9hZGVkQ29uZmlnO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY29uc29sZS5sb2coXHJcbiAgICBgXFxuXFxuIFRvIGZhY2lsaXRhdGUgdGhlIGRlcGxveW1lbnQgb2YgdGhlIG5lY2Vzc2FyeSBpbmZyYXN0cnVjdHVyZSBmb3Igd2Vic2l0ZSBob3N0aW5nLCBjZXJ0YWluIGluZm9ybWF0aW9uIGlzIHJlcXVpcmVkLlxcbiAke1RPT0xfTkFNRX0gd2lsbCBhaW0gdG8gZmluZCBhcyBtdWNoIHJlbGV2YW50IGRhdGEgYXMgcG9zc2libGUuXFxuXFxuYFxyXG4gICk7XHJcblxyXG4gIGxldCBpZGVudGlmaWVkUmVwb3NpdG9yeVVybDogc3RyaW5nLFxyXG4gICAgaWRlbnRpZmllZEJyYW5jaE5hbWU6IHN0cmluZyxcclxuICAgIGlkZW50aWZpZWRGcmFtZXdvcmtOYW1lOiBzdHJpbmc7XHJcblxyXG4gIC8vY2hlY2sgZ2l0aHViIGNvbmZpZ3VyYXRpb25cclxuICBjb25zb2xlLmxvZyhcclxuICAgIFwiQ29sbGVjdGluZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgR2l0SHViIHJlcG9zaXRvcnkgZnJvbSBcIiArXHJcbiAgICAgIGdldENMSUV4ZWN1dGlvbkZvbGRlcigpXHJcbiAgKTtcclxuICBpZGVudGlmaWVkUmVwb3NpdG9yeVVybCA9IGdldEdpdFJlbW90ZSgpO1xyXG5cclxuICBpZGVudGlmaWVkQnJhbmNoTmFtZSA9IGdldEdpdEJyYW5jaCgpO1xyXG5cclxuICBjb25zdCByZXBvUXVlc3Rpb25zID0gYXdhaXQgc3RhcnRQcm9tcHQoXHJcbiAgICBnZXRHaXRodWJSZXBvc2l0b3J5UXVlc3Rpb25zKFxyXG4gICAgICBjdXJyZW50SG9zdGluZ0NvbmZpZy5yZXBvVXJsXHJcbiAgICAgICAgPyBjdXJyZW50SG9zdGluZ0NvbmZpZy5yZXBvVXJsXHJcbiAgICAgICAgOiBpZGVudGlmaWVkUmVwb3NpdG9yeVVybCxcclxuICAgICAgY3VycmVudEhvc3RpbmdDb25maWcuYnJhbmNoTmFtZVxyXG4gICAgICAgID8gY3VycmVudEhvc3RpbmdDb25maWcuYnJhbmNoTmFtZVxyXG4gICAgICAgIDogaWRlbnRpZmllZEJyYW5jaE5hbWVcclxuICAgIClcclxuICApO1xyXG5cclxuICBjb25zb2xlLmxvZyhcclxuICAgIFwiXFxuQ29sbGVjdGluZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZnJvbnRlbmQgZnJhbWV3b3JrIHVzZWQgdG8gZW5hYmxlIHRoZSBwcm92aXNpb24gb2YgdGhlIGFwcHJvcHJpYXRlIGJ1aWxkIGNvbmZpZ3VyYXRpb24uXCJcclxuICApO1xyXG4gIGlkZW50aWZpZWRGcmFtZXdvcmtOYW1lID0gYXdhaXQgZGV0ZWN0RnJvbnRlbmRGcmFtZXdvcmsoXHJcbiAgICBnZXRDTElFeGVjdXRpb25Gb2xkZXIoKVxyXG4gICk7XHJcblxyXG5cclxuICAgICBcclxuXHJcbiAgY29uc3QgZnJhbWV3b3JrU2VsZWN0aW9uID0gYXdhaXQgc3RhcnRQcm9tcHQoXHJcbiAgICBnZXRGcmFtZXdvcmtTZWxlY3Rpb25RdWVzdGlvbnMoXHJcbiAgICAgIGN1cnJlbnRIb3N0aW5nQ29uZmlnLmZyYW1ld29ya1xyXG4gICAgICAgID8gY3VycmVudEhvc3RpbmdDb25maWcuZnJhbWV3b3JrXHJcbiAgICAgICAgOiBpZGVudGlmaWVkRnJhbWV3b3JrTmFtZVxyXG4gICAgKVxyXG4gICk7XHJcblxyXG4gIGNvbnN0IHJlcG9zaXRvcnlVcmwgPSByZXBvUXVlc3Rpb25zLnJlcG9Vcmw7XHJcbiAgY29uc3QgYnJhbmNoTmFtZSA9IHJlcG9RdWVzdGlvbnMuYnJhbmNoTmFtZTtcclxuICBjb25zdCBmcmFtZXdvcmtOYW1lID0gZnJhbWV3b3JrU2VsZWN0aW9uLmZyYW1ld29yaztcclxuICBpZihmcmFtZXdvcmtOYW1lID09PSBcImV4aXRcIil7XHJcbiAgICBwcm9jZXNzLmV4aXQoMCk7XHJcbiAgfVxyXG4gIGNvbnNvbGUubG9nKFwiXFxuXCIpO1xyXG4gIGNvbnN0IHsgZG9tYWluTmFtZSwgaG9zdGVkWm9uZUlkIH0gPSBhd2FpdCBnZXRVc2VyRG9tYWluUHJlZmVyZW5jZShcclxuICAgIGN1cnJlbnRIb3N0aW5nQ29uZmlnXHJcbiAgKTtcclxuXHJcbiAgY29uc29sZS5sb2coXCJcXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXCIpO1xyXG4gIGNvbnNvbGUubG9nKFxyXG4gICAgYEhlcmUgaXMgdGhlIGNvbmZpZ3VyYXRpb24gdGhhdCBoYXMgYmVlbiBnZW5lcmF0ZWQgYW5kIHNhdmVkIHRvICR7VE9PTF9OQU1FfS8ke0NPTkZJR19GSUxFX05BTUV9IGZpbGUuOmBcclxuICApO1xyXG4gIGNvbnNvbGUubG9nKFwiPiAgICAgICBHaXRIdWIgcmVwb3NpdG9yeTogXCIgKyByZXBvc2l0b3J5VXJsICsgXCIvXCIgKyBicmFuY2hOYW1lKTtcclxuICBjb25zb2xlLmxvZyhcIj4gICAgICAgRnJhbWV3b3JrOiBcIiArIGZyYW1ld29ya05hbWUpO1xyXG4gIGNvbnNvbGUubG9nKFwiPiAgICAgICBEb21haW4gbmFtZTogXCIgKyAoZG9tYWluTmFtZSA/IGRvbWFpbk5hbWUgOiBcIk5vXCIpKTtcclxuICBjb25zb2xlLmxvZyhob3N0ZWRab25lSWQgPyBcIj4gICAgICAgSG9zdGVkIHpvbmUgSUQ6IFwiICsgaG9zdGVkWm9uZUlkIDogXCJcIik7XHJcblxyXG4gIGNvbnNvbGUubG9nKFwiXFxuLS1cIik7XHJcblxyXG4gIGNvcHlCdWlsZENvbmZpZ0lmTm90RXhpc3RzKFwiaG9zdGluZ19cIiArIGZyYW1ld29ya05hbWUgKyBcIi55bWxcIik7XHJcbiAgY29weUNmZklmTm90RXhpc3RzKFwiaW5kZXhfXCIgKyBmcmFtZXdvcmtOYW1lICsgXCIuanNcIilcclxuXHJcblxyXG4gIGNvbnN0IG5ld0hvc3RpbmdDb25maWd1cmF0aW9uOiBIb3N0aW5nQ29uZmlndXJhdGlvbiA9IHtcclxuICAgIHJlcG9Vcmw6IHJlcG9zaXRvcnlVcmwsXHJcbiAgICBicmFuY2hOYW1lOiBicmFuY2hOYW1lLFxyXG4gICAgZnJhbWV3b3JrOiBmcmFtZXdvcmtOYW1lLFxyXG4gICAgLi4uKGRvbWFpbk5hbWUgPyB7IGRvbWFpbk5hbWUgfSA6IHt9KSxcclxuICAgIC4uLihob3N0ZWRab25lSWQgPyB7IGhvc3RlZFpvbmVJZCB9IDoge30pLFxyXG4gIH07XHJcblxyXG4gIHNhdmVBbmRMb2dDb25maWd1cmF0aW9uKG5ld0hvc3RpbmdDb25maWd1cmF0aW9uKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNhdmVBbmRMb2dDb25maWd1cmF0aW9uKFxyXG4gIG5ld0hvc3RpbmdDb25maWd1cmF0aW9uOiBIb3N0aW5nQ29uZmlndXJhdGlvblxyXG4pOiB2b2lkIHtcclxuICBjb25zdCBqc29uSG9zdGluZ0NvbmZpZ3VyYXRpb24gPSBKU09OLnN0cmluZ2lmeShcclxuICAgIG5ld0hvc3RpbmdDb25maWd1cmF0aW9uLFxyXG4gICAgbnVsbCxcclxuICAgIDJcclxuICApO1xyXG5cclxuICBmcy53cml0ZUZpbGVTeW5jKGdldENvbmZpZ0ZpbGVQYXRoKCksIGpzb25Ib3N0aW5nQ29uZmlndXJhdGlvbik7XHJcblxyXG4gIGNvbnNvbGUubG9nKGA+ICAgICAgIENvbmZpZ3VyYXRpb24gZmlsZSBnZW5lcmF0ZWQgJHtnZXRDb25maWdGaWxlUGF0aCgpfWApO1xyXG4gIGNvbnNvbGUubG9nKFxyXG4gICAgYD4gICAgICAgQnVpbGQgY29uZmlndXJhdGlvbiBnZW5lcmF0ZWQgJHtnZXRCdWlsZENvbmZpZ0ZpbGVQYXRoKCl9YFxyXG4gICk7XHJcbiAgY29uc29sZS5sb2coXHJcbiAgICBgPiAgICAgICBDbG91ZEZyb250IEZ1bmN0aW9uIHNvdXJjZSBjb2RlIGdlbmVyYXRlZCAke2dldENmZkNvbmZpZ0ZpbGVQYXRoKCl9YFxyXG4gICk7XHJcblxyXG4gIGNvbnNvbGUubG9nKFxyXG4gICAgYFxcblxcblRoZSBpbml0aWFsaXphdGlvbiBwcm9jZXNzIGhhcyBiZWVuIGNvbXBsZXRlZC4gWW91IG1heSBub3cgZXhlY3V0ZSAnJHtUT09MX05BTUV9IGRlcGxveScgdG8gZGVwbG95IHRoZSBpbmZyYXN0cnVjdHVyZS5cXG5gXHJcbiAgKTtcclxuXHJcbiAgXHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbml0X3MzKCkge1xyXG4gIGNvbnNvbGUubG9nKFxyXG4gICAgXCJcXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0gU3RhdGljIGhvc3RpbmcgY29uZmlndXJhdGlvbiB3aXphcmQ6IFMzIFNvdXJjZSBDb2RlIFJlcG9zaXRvcnkgQmFzZWQgLS0tLS0tLS0tLS0tLS0tLS0tLVxcblwiXHJcbiAgKTtcclxuICBsZXQgY3VycmVudEhvc3RpbmdDb25maWc6IEhvc3RpbmdDb25maWd1cmF0aW9uID0ge1xyXG4gICAgczNidWNrZXQ6IFwiXCIsXHJcbiAgICBzM3BhdGg6IFwiXCIsXHJcbiAgICBkb21haW5OYW1lOiB1bmRlZmluZWQsXHJcbiAgICBob3N0ZWRab25lSWQ6IHVuZGVmaW5lZCxcclxuICB9O1xyXG5cclxuICBpZiAoZG9lc0hvc3RpbmdDb25maWd1cmF0aW9uRmlsZUV4aXN0KCkpIHtcclxuICAgIGNvbnN0IGxvYWRlZENvbmZpZyA9IGF3YWl0IGxvYWRIb3N0aW5nQ29uZmlndXJhdGlvbigpO1xyXG5cclxuICAgIGlmIChpc1MzQ29uZmlnKGxvYWRlZENvbmZpZykpIHtcclxuICAgICAgY3VycmVudEhvc3RpbmdDb25maWcgPSBsb2FkZWRDb25maWc7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjb25zdCBzM3F1ZXN0aW9ucyA9IGF3YWl0IHN0YXJ0UHJvbXB0KFxyXG4gICAgZ2V0UzNCdWNrZXRDb25maWd1cmF0aW9uUXVlc3Rpb25zKFxyXG4gICAgICBjdXJyZW50SG9zdGluZ0NvbmZpZy5zM2J1Y2tldCxcclxuICAgICAgY3VycmVudEhvc3RpbmdDb25maWcuczNwYXRoXHJcbiAgICApXHJcbiAgKTtcclxuXHJcbiAgY29uc3QgeyBkb21haW5OYW1lLCBob3N0ZWRab25lSWQgfSA9IGF3YWl0IGdldFVzZXJEb21haW5QcmVmZXJlbmNlKFxyXG4gICAgY3VycmVudEhvc3RpbmdDb25maWdcclxuICApO1xyXG5cclxuICBjb25zb2xlLmxvZyhcIlxcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cIik7XHJcbiAgY29uc29sZS5sb2coXCJQbGVhc2UgcmV2aWV3IHRoZSBmb2xsb3dpbmcgY2FwdHVyZWQgaW5mb3JtYXRpb246XCIpO1xyXG4gIGNvbnNvbGUubG9nKFwiPiAgICAgICBTMyBCdWNrZXQ6IFwiICsgczNxdWVzdGlvbnMuczNidWNrZXQpO1xyXG4gIGNvbnNvbGUubG9nKFwiPiAgICAgICBTMyBQcmVmaXg6IFwiICsgczNxdWVzdGlvbnMuczNwYXRoKTtcclxuICBjb25zb2xlLmxvZyhcIj4gICAgICAgRG9tYWluIG5hbWU6IFwiICsgKGRvbWFpbk5hbWUgPyBkb21haW5OYW1lIDogXCJOb1wiKSk7XHJcbiAgY29uc29sZS5sb2coaG9zdGVkWm9uZUlkID8gXCI+ICAgICAgIEhvc3RlZCB6b25lIElEOiBcIiArIGhvc3RlZFpvbmVJZCA6IFwiXCIpO1xyXG5cclxuICBjb25zb2xlLmxvZyhcIlxcbi0tXCIpO1xyXG5cclxuICBjb3B5QnVpbGRDb25maWdJZk5vdEV4aXN0cyhcInMzX2J1aWxkX2NvbmZpZy55bWxcIik7XHJcbiAgY29weUNmZklmTm90RXhpc3RzKFwiaW5kZXhfYmFzaWMuanNcIilcclxuXHJcbiAgY29uc3QgbmV3SG9zdGluZ0NvbmZpZ3VyYXRpb246IEhvc3RpbmdDb25maWd1cmF0aW9uID0ge1xyXG4gICAgczNidWNrZXQ6IHMzcXVlc3Rpb25zLnMzYnVja2V0LFxyXG4gICAgczNwYXRoOiBzM3F1ZXN0aW9ucy5zM3BhdGgsXHJcbiAgICAuLi4oZG9tYWluTmFtZSA/IHsgZG9tYWluTmFtZSB9IDoge30pLFxyXG4gICAgLi4uKGhvc3RlZFpvbmVJZCA/IHsgaG9zdGVkWm9uZUlkIH0gOiB7fSksXHJcbiAgfTtcclxuXHJcbiAgc2F2ZUFuZExvZ0NvbmZpZ3VyYXRpb24obmV3SG9zdGluZ0NvbmZpZ3VyYXRpb24pO1xyXG59XHJcblxyXG4vKipcclxuICogQ29waWVzIGEgYnVpbGQgY29uZmlndXJhdGlvbiB0ZW1wbGF0ZSB0byB0aGUgdG9vbCBmb2xkZXIgaWYgaXQgZG9lcyBub3QgYWxyZWFkeSBleGlzdC5cclxuICpcclxuICogQHBhcmFtIGZyYW1ld29ya05hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZnJhbWV3b3JrIHRvIGRldGVybWluZSB0aGUgc291cmNlIGJ1aWxkIGNvbmZpZ3VyYXRpb24gZmlsZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjb3B5QnVpbGRDb25maWdJZk5vdEV4aXN0cyhmaWxlTmFtZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgY29uc3Qgc3JjQnVpbGRDb25maWdGaWxlOiBzdHJpbmcgPVxyXG4gICAgZ2V0QnVpbGRDb25maWdUZW1wbGF0ZXNGb2xkZXIoKSArIFwiL1wiICsgZmlsZU5hbWU7XHJcblxyXG4gIGlmICghZnMuZXhpc3RzU3luYyhnZXRUb29sRm9sZGVyKCkpKSB7XHJcbiAgICBmcy5ta2RpclN5bmMoZ2V0VG9vbEZvbGRlcigpKTtcclxuICB9XHJcblxyXG4gIGlmICghZnMuZXhpc3RzU3luYyhnZXRCdWlsZENvbmZpZ0ZpbGVQYXRoKCkpKSB7XHJcbiAgICBmcy5jb3B5RmlsZVN5bmMoc3JjQnVpbGRDb25maWdGaWxlLCBnZXRCdWlsZENvbmZpZ0ZpbGVQYXRoKCkpO1xyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNvcHlDZmZJZk5vdEV4aXN0cyhmaWxlTmFtZTogc3RyaW5nKTogdm9pZCB7XHJcblxyXG4gIGNvbnN0IHNyY0J1aWxkQ29uZmlnRmlsZTogc3RyaW5nID1cclxuICAgIGdldENmZlRlbXBsYXRlc0ZvbGRlcigpICsgXCIvXCIgKyBmaWxlTmFtZTtcclxuXHJcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGdldFRvb2xGb2xkZXIoKSkpIHtcclxuICAgIGZzLm1rZGlyU3luYyhnZXRUb29sRm9sZGVyKCkpO1xyXG4gIH1cclxuXHJcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGdldENmZkNvbmZpZ0ZpbGVQYXRoKCkpKSB7XHJcbiAgICBmcy5jb3B5RmlsZVN5bmMoc3JjQnVpbGRDb25maWdGaWxlLCBnZXRDZmZDb25maWdGaWxlUGF0aCgpKTtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRVc2VyRG9tYWluUHJlZmVyZW5jZShcclxuICBjdXJyZW50SG9zdGluZ0NvbmZpZzogSG9zdGluZ0NvbmZpZ3VyYXRpb25cclxuKSB7XHJcbiAgY29uc3Qgd2l0aERvbWFpbk5hbWUgPSBhd2FpdCBzdGFydFByb21wdChcclxuICAgIGdldERvbWFpbk5hbWVRdWVzdGlvbihjdXJyZW50SG9zdGluZ0NvbmZpZy5kb21haW5OYW1lKVxyXG4gICk7XHJcblxyXG4gIGlmICh3aXRoRG9tYWluTmFtZS52YWx1ZSA9PT0gXCJ5ZXNcIikge1xyXG4gICAgY29uc3QgZG9tYWluTmFtZVByb21wdCA9IGF3YWl0IHN0YXJ0UHJvbXB0KFxyXG4gICAgICBkb21haW5OYW1lRGV0YWlsc1F1ZXN0aW9ucyhjdXJyZW50SG9zdGluZ0NvbmZpZy5kb21haW5OYW1lKVxyXG4gICAgKTtcclxuXHJcbiAgICBpZiAoZG9tYWluTmFtZVByb21wdC5yZWdpc3RyYXIgPT09IFwiY3VycmVudFwiKSB7XHJcbiAgICAgIGNvbnN0IGhvc3RlZFpvbmUgPSBhd2FpdCBzdGFydFByb21wdChcclxuICAgICAgICBob3N0ZWRab25lSWRRdWVzdGlvbihjdXJyZW50SG9zdGluZ0NvbmZpZy5ob3N0ZWRab25lSWQpXHJcbiAgICAgICk7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGRvbWFpbk5hbWU6IGRvbWFpbk5hbWVQcm9tcHQuZG9tYWluTmFtZSxcclxuICAgICAgICBob3N0ZWRab25lSWQ6IGhvc3RlZFpvbmUuaG9zdGVkWm9uZUlkLFxyXG4gICAgICB9O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBkb21haW5OYW1lOiBkb21haW5OYW1lUHJvbXB0LmRvbWFpbk5hbWUsXHJcbiAgICAgICAgaG9zdGVkWm9uZUlkOiB1bmRlZmluZWQsXHJcbiAgICAgIH07XHJcbiAgICB9XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGRvbWFpbk5hbWU6IHVuZGVmaW5lZCxcclxuICAgICAgaG9zdGVkWm9uZUlkOiB1bmRlZmluZWQsXHJcbiAgICB9O1xyXG4gIH1cclxufVxyXG4iXX0=