UNPKG

@selfage/bundler_cli

Version:

CLI for bundling and running bundled frontend or backend TypeScript files.

196 lines 36.3 kB
#!/usr/bin/env node "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const path = require("path"); const bundler_1 = require("./bundler"); const runner_in_node_1 = require("./runner_in_node"); const runner_in_puppeteer_1 = require("./runner_in_puppeteer"); const to_unix_path_1 = require("./to_unix_path"); const web_app_bundler_1 = require("./web_app_bundler"); const web_server_bundler_1 = require("./web_server_bundler"); const commander_1 = require("commander"); require("source-map-support/register"); let EXTRA_FILES_OPTION = [ "-e, --extra-files <extraFiles...>", `Extra TypeScript files to be bundled together with and before the source ` + `file.`, ]; let INLINE_JS_CODE_OPTION = [ "-i, --inline-js <inlineJs...>", `Inline JavaScript code to be bundled together with and before all files.`, ]; let ASSET_EXT_OPTION = [ "-a, --asset-exts <assetExts...>", `A list of file exts that are treated as assets. E.g., with ` + `"-a .png .jpg", you could \`import imagePath = require('./image.png')\` ` + `which enables \`<img src={imagePath}>\` or ` + `\`fs.readFileSync(imagePath)\`. If not provided, it will look for ` + `\`assetExts\` field in ./package.json which should be a list of strings.`, ]; let SKIP_MINIFY_OPTION = [ "-s, --skip-minify", `Skip minification when bundling. Useful for inspecting bundling issues.`, ]; let DEBUG_OPTION = [ "-d, --debug", "Include inline source map and inline source.", ]; let TSCONFIG_FILE_OPTION = [ "-c, --tsconfig-file <file>", `The file path to tsconfig.json. If not provided, it will try to look for ` + `it at the current working directory.`, ]; let ENTRIES_CONFIG_FILE_OPTION = [ "-ec, --entries-config-file <entriesConfigFile>", `A config file to specify a list of entry files, each of which should ` + `be a single page application. Loop for "WebAppEntries" in ` + `https://github.com/selfage/bundler_cli/blob/main/web_app_entries_def.ts ` + `for its schema. Its directory is the base that all imported assets ` + `should be relative to, and a web server can serve files at this ` + `directory. If not provided, it will look for ./${web_app_bundler_1.DEFAULT_ENTRIES_CONFIG_FILE}.`, ]; let FROM_DIR_OPTION = [ "-f, --from-dir <fromDir>", `The directoy to copy from. If not provided, it will be the current ` + `working directory.`, ]; let TO_DIR_OPTION = [ "-t, --to-dir <toDir>", `The directoy to copy to. If not provided, or when <toDir> equals ` + `<fromDir>, no copies happen.`, ]; let BASE_DIR_OPTION = [ "-b, --base-dir <baseDir>", `The base directory that all imported assets should be relative to, such ` + `that a web server can serve files at this directory. If not provided, ` + `it will be the current working directory.`, ]; let OUT_DIR_OPTION = [ "-o, --out-dir <outDir>", `The output directory to where files will be copied. If not provided, or ` + `when <outDir> equals <baseDir>, no copies happen.`, ]; let PORT_OPTION = [ "-p, --port <port>", `The port number to start your local server. Default to 8000.`, ]; let NO_HEADLESS_BROWSER_OPTION = [ "-nh, --no-headless", `Turn off running the browser in headless mode.`, ]; function main() { let packageConfig = JSON.parse(fs.readFileSync(path.join(__dirname, "package.json")).toString()); let program = new commander_1.Command(); program.version(packageConfig.version); program .command("bundleForNode <sourceFile> <outputFile>") .alias("bfn") .description(`Compile and bundle from a TypeScript source file that can be run in ` + `Node. Both file exts can be neglected and are always fixed as .ts ` + `and .js respectively. Npm modules are not actually bundled due to ` + `many of them not compatible with bundling.`) .option(FROM_DIR_OPTION[0], FROM_DIR_OPTION[1]) .option(TO_DIR_OPTION[0], TO_DIR_OPTION[1]) .option(EXTRA_FILES_OPTION[0], EXTRA_FILES_OPTION[1]) .option(INLINE_JS_CODE_OPTION[0], INLINE_JS_CODE_OPTION[1]) .option(ASSET_EXT_OPTION[0], ASSET_EXT_OPTION[1]) .option(SKIP_MINIFY_OPTION[0], SKIP_MINIFY_OPTION[1]) .option(DEBUG_OPTION[0], DEBUG_OPTION[1]) .option(TSCONFIG_FILE_OPTION[0], TSCONFIG_FILE_OPTION[1]) .action(async (sourceFile, outputFile, options) => { await (0, bundler_1.bundleForNode)((0, to_unix_path_1.toUnixPath)(sourceFile), (0, to_unix_path_1.toUnixPath)(outputFile), (0, to_unix_path_1.toUnixPath)(options.fromDir), (0, to_unix_path_1.toUnixPath)(options.toDir), (0, to_unix_path_1.toUnixPathFromBundleOptions)(options)); }); program .command("runInNode <sourceFile> [pass-through-args...]") .alias("nrun") .description(`Compile and bundle from a TypeScript source file, and run the bundled ` + `JavaScript file in Node. The file ext can be neglected and is ` + `always fixed as .ts. "--" is needed in between <sourceFile> and ` + `pass through arguments.`) .option(EXTRA_FILES_OPTION[0], EXTRA_FILES_OPTION[1]) .option(INLINE_JS_CODE_OPTION[0], INLINE_JS_CODE_OPTION[1]) .option(ASSET_EXT_OPTION[0], ASSET_EXT_OPTION[1]) .option(SKIP_MINIFY_OPTION[0], SKIP_MINIFY_OPTION[1]) .option(DEBUG_OPTION[0], DEBUG_OPTION[1]) .option(TSCONFIG_FILE_OPTION[0], TSCONFIG_FILE_OPTION[1]) .action((sourceFile, passThroughArgs, options) => (0, runner_in_node_1.runInNode)((0, to_unix_path_1.toUnixPath)(sourceFile), (0, to_unix_path_1.toUnixPathFromBundleOptions)(options), passThroughArgs)); program .command("bundleForBrowser <sourceFile> <outputFile>") .alias("bfb") .description(`Compile and bundle from a TypeScript source file that can be run in ` + `Browser. Both file exts can be neglected and are always fixed as ` + `.ts and .js respectively.`) .option(BASE_DIR_OPTION[0], BASE_DIR_OPTION[1]) .option(OUT_DIR_OPTION[0], OUT_DIR_OPTION[1]) .option(EXTRA_FILES_OPTION[0], EXTRA_FILES_OPTION[1]) .option(INLINE_JS_CODE_OPTION[0], INLINE_JS_CODE_OPTION[1]) .option(ASSET_EXT_OPTION[0], ASSET_EXT_OPTION[1]) .option(SKIP_MINIFY_OPTION[0], SKIP_MINIFY_OPTION[1]) .option(DEBUG_OPTION[0], DEBUG_OPTION[1]) .option(TSCONFIG_FILE_OPTION[0], TSCONFIG_FILE_OPTION[1]) .action(async (sourceFile, outputFile, options) => { await (0, bundler_1.bundleForBrowser)((0, to_unix_path_1.toUnixPath)(sourceFile), (0, to_unix_path_1.toUnixPath)(outputFile), (0, to_unix_path_1.toUnixPath)(options.baseDir), (0, to_unix_path_1.toUnixPath)(options.outDir), (0, to_unix_path_1.toUnixPathFromBundleOptions)(options)); }); program .command("runInPuppeteer <sourceFile> [pass-through-args...]") .alias("prun") .description(`Compile and bundle from a TypeScript source file, and run the bundled ` + `JavaScript file in Puppeteer, i.e., headless Chrome. The file ext ` + `can be neglected and is always fixed as .ts. "--" is needed in ` + `between <sourceFile> and pass through arguments.`) .option(BASE_DIR_OPTION[0], BASE_DIR_OPTION[1]) .option(EXTRA_FILES_OPTION[0], EXTRA_FILES_OPTION[1]) .option(INLINE_JS_CODE_OPTION[0], INLINE_JS_CODE_OPTION[1]) .option(ASSET_EXT_OPTION[0], ASSET_EXT_OPTION[1]) .option(SKIP_MINIFY_OPTION[0], SKIP_MINIFY_OPTION[1]) .option(DEBUG_OPTION[0], DEBUG_OPTION[1]) .option(TSCONFIG_FILE_OPTION[0], TSCONFIG_FILE_OPTION[1]) .option(PORT_OPTION[0], PORT_OPTION[1], (value) => parseInt(value, 10)) .option(NO_HEADLESS_BROWSER_OPTION[0], NO_HEADLESS_BROWSER_OPTION[1]) .action((sourceFile, passThroughArgs, options) => (0, runner_in_puppeteer_1.runInPuppeteer)((0, to_unix_path_1.toUnixPath)(sourceFile), (0, to_unix_path_1.toUnixPath)(options.baseDir), options.port, options.headless, (0, to_unix_path_1.toUnixPathFromBundleOptions)(options), passThroughArgs)); program .command("bundleWebApps") .alias("bwa") .description(`Bundle all TypeScript source files based on <entriesConfig>, generate ` + `HTML files pointing to the bundled JS files respectively, compress ` + `them with Gzip, collect a list of all bundled JS & HTML file paths ` + `and asset file paths to <bundledResources>, and finally copy those ` + `files into <outDir> where your web server can be started.`) .option(ENTRIES_CONFIG_FILE_OPTION[0], ENTRIES_CONFIG_FILE_OPTION[1]) .option("-br, --bundled-resources-file <bundledResourcesFile>", `An output file generated after bundling, containing a JSON array of ` + `files that need to be copied to <outDir> and served in your web ` + `server. If not provided, it will write to ` + `./${web_app_bundler_1.DEFAULT_BUNDLED_RESOURCES_FILE}.`) .option(OUT_DIR_OPTION[0], OUT_DIR_OPTION[1]) .option(EXTRA_FILES_OPTION[0], EXTRA_FILES_OPTION[1]) .option(INLINE_JS_CODE_OPTION[0], INLINE_JS_CODE_OPTION[1]) .option(ASSET_EXT_OPTION[0], ASSET_EXT_OPTION[1]) .option(SKIP_MINIFY_OPTION[0], SKIP_MINIFY_OPTION[1]) .option(DEBUG_OPTION[0], DEBUG_OPTION[1]) .option(TSCONFIG_FILE_OPTION[0], TSCONFIG_FILE_OPTION[1]) .action((options) => (0, web_app_bundler_1.bundleWebApps)((0, to_unix_path_1.toUnixPath)(options.entriesConfigFile), (0, to_unix_path_1.toUnixPath)(options.bundledResourcesFile), (0, to_unix_path_1.toUnixPath)(options.outDir), (0, to_unix_path_1.toUnixPathFromBundleOptions)(options))); program .command("bundleWebServer <serverSourceFile> <serverOutputFile>") .alias("bws") .description(`Bundle a TypeScript source file as the server's main file and output. ` + `Both file exts can be neglected and are always fixed as .ts and .js ` + `respectively. Npm modules are not actually bundled due to many of ` + `them not compatible with bundling. It will also bundle web apps ` + `based on <entriesConfigFile> as well as <baseDir>. Finally, all ` + `bundled files and imported or extra assets will be copied from ` + `<fromDir> to <toDir>, without any source file or intermediate file.`) .option(ENTRIES_CONFIG_FILE_OPTION[0], ENTRIES_CONFIG_FILE_OPTION[1]) .option(FROM_DIR_OPTION[0], FROM_DIR_OPTION[1]) .option(TO_DIR_OPTION[0], TO_DIR_OPTION[1]) .option(EXTRA_FILES_OPTION[0], EXTRA_FILES_OPTION[1]) .option(INLINE_JS_CODE_OPTION[0], INLINE_JS_CODE_OPTION[1]) .option(ASSET_EXT_OPTION[0], ASSET_EXT_OPTION[1]) .option(SKIP_MINIFY_OPTION[0], SKIP_MINIFY_OPTION[1]) .option(DEBUG_OPTION[0], DEBUG_OPTION[1]) .option(TSCONFIG_FILE_OPTION[0], TSCONFIG_FILE_OPTION[1]) .action((serverSourceFile, serverOutputFile, options) => (0, web_server_bundler_1.bundleWebServer)((0, to_unix_path_1.toUnixPath)(serverSourceFile), (0, to_unix_path_1.toUnixPath)(serverOutputFile), (0, to_unix_path_1.toUnixPath)(options.entriesConfigFile), (0, to_unix_path_1.toUnixPath)(options.fromDir), (0, to_unix_path_1.toUnixPath)(options.toDir), (0, to_unix_path_1.toUnixPathFromBundleOptions)(options))); program.parse(); } main(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1haW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EseUJBQTBCO0FBQzFCLDZCQUE4QjtBQUM5Qix1Q0FBNEQ7QUFDNUQscURBQTZDO0FBQzdDLCtEQUF1RDtBQUN2RCxpREFBeUU7QUFDekUsdURBSTJCO0FBQzNCLDZEQUF1RDtBQUN2RCx5Q0FBb0M7QUFDcEMsdUNBQXFDO0FBRXJDLElBQUksa0JBQWtCLEdBQUc7SUFDdkIsbUNBQW1DO0lBQ25DLDJFQUEyRTtRQUN6RSxPQUFPO0NBQ1YsQ0FBQztBQUNGLElBQUkscUJBQXFCLEdBQUc7SUFDMUIsK0JBQStCO0lBQy9CLDBFQUEwRTtDQUMzRSxDQUFDO0FBQ0YsSUFBSSxnQkFBZ0IsR0FBRztJQUNyQixpQ0FBaUM7SUFDakMsNkRBQTZEO1FBQzNELDBFQUEwRTtRQUMxRSw2Q0FBNkM7UUFDN0Msb0VBQW9FO1FBQ3BFLDBFQUEwRTtDQUM3RSxDQUFDO0FBQ0YsSUFBSSxrQkFBa0IsR0FBRztJQUN2QixtQkFBbUI7SUFDbkIseUVBQXlFO0NBQzFFLENBQUM7QUFDRixJQUFJLFlBQVksR0FBRztJQUNqQixhQUFhO0lBQ2IsOENBQThDO0NBQy9DLENBQUM7QUFDRixJQUFJLG9CQUFvQixHQUFHO0lBQ3pCLDRCQUE0QjtJQUM1QiwyRUFBMkU7UUFDekUsc0NBQXNDO0NBQ3pDLENBQUM7QUFDRixJQUFJLDBCQUEwQixHQUFHO0lBQy9CLGdEQUFnRDtJQUNoRCx1RUFBdUU7UUFDckUsNERBQTREO1FBQzVELDBFQUEwRTtRQUMxRSxxRUFBcUU7UUFDckUsa0VBQWtFO1FBQ2xFLGtEQUFrRCw2Q0FBMkIsR0FBRztDQUNuRixDQUFDO0FBQ0YsSUFBSSxlQUFlLEdBQUc7SUFDcEIsMEJBQTBCO0lBQzFCLHFFQUFxRTtRQUNuRSxvQkFBb0I7Q0FDdkIsQ0FBQztBQUNGLElBQUksYUFBYSxHQUFHO0lBQ2xCLHNCQUFzQjtJQUN0QixtRUFBbUU7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QUMsRUFDekIsSUFBQSwwQ0FBMkIsRUFBQyxPQUFPLENBQUMsQ0FDckMsQ0FDRixDQUFDO0lBQ0osT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ2xCLENBQUM7QUFFRCxJQUFJLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIiMhL3Vzci9iaW4vZW52IG5vZGVcbmltcG9ydCBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcbmltcG9ydCBwYXRoID0gcmVxdWlyZShcInBhdGhcIik7XG5pbXBvcnQgeyBidW5kbGVGb3JCcm93c2VyLCBidW5kbGVGb3JOb2RlIH0gZnJvbSBcIi4vYnVuZGxlclwiO1xuaW1wb3J0IHsgcnVuSW5Ob2RlIH0gZnJvbSBcIi4vcnVubmVyX2luX25vZGVcIjtcbmltcG9ydCB7IHJ1bkluUHVwcGV0ZWVyIH0gZnJvbSBcIi4vcnVubmVyX2luX3B1cHBldGVlclwiO1xuaW1wb3J0IHsgdG9Vbml4UGF0aCwgdG9Vbml4UGF0aEZyb21CdW5kbGVPcHRpb25zIH0gZnJvbSBcIi4vdG9fdW5peF9wYXRoXCI7XG5pbXBvcnQge1xuICBERUZBVUxUX0JVTkRMRURfUkVTT1VSQ0VTX0ZJTEUsXG4gIERFRkFVTFRfRU5UUklFU19DT05GSUdfRklMRSxcbiAgYnVuZGxlV2ViQXBwcyxcbn0gZnJvbSBcIi4vd2ViX2FwcF9idW5kbGVyXCI7XG5pbXBvcnQgeyBidW5kbGVXZWJTZXJ2ZXIgfSBmcm9tIFwiLi93ZWJfc2VydmVyX2J1bmRsZXJcIjtcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tIFwiY29tbWFuZGVyXCI7XG5pbXBvcnQgXCJzb3VyY2UtbWFwLXN1cHBvcnQvcmVnaXN0ZXJcIjtcblxubGV0IEVYVFJBX0ZJTEVTX09QVElPTiA9IFtcbiAgXCItZSwgLS1leHRyYS1maWxlcyA8ZXh0cmFGaWxlcy4uLj5cIixcbiAgYEV4dHJhIFR5cGVTY3JpcHQgZmlsZXMgdG8gYmUgYnVuZGxlZCB0b2dldGhlciB3aXRoIGFuZCBiZWZvcmUgdGhlIHNvdXJjZSBgICtcbiAgICBgZmlsZS5gLFxuXTtcbmxldCBJTkxJTkVfSlNfQ09ERV9PUFRJT04gPSBbXG4gIFwiLWksIC0taW5saW5lLWpzIDxpbmxpbmVKcy4uLj5cIixcbiAgYElubGluZSBKYXZhU2NyaXB0IGNvZGUgdG8gYmUgYnVuZGxlZCB0b2dldGhlciB3aXRoIGFuZCBiZWZvcmUgYWxsIGZpbGVzLmAsXG5dO1xubGV0IEFTU0VUX0VYVF9PUFRJT04gPSBbXG4gIFwiLWEsIC0tYXNzZXQtZXh0cyA8YXNzZXRFeHRzLi4uPlwiLFxuICBgQSBsaXN0IG9mIGZpbGUgZXh0cyB0aGF0IGFyZSB0cmVhdGVkIGFzIGFzc2V0cy4gRS5nLiwgd2l0aCBgICtcbiAgICBgXCItYSAucG5nIC5qcGdcIiwgeW91IGNvdWxkIFxcYGltcG9ydCBpbWFnZVBhdGggPSByZXF1aXJlKCcuL2ltYWdlLnBuZycpXFxgIGAgK1xuICAgIGB3aGljaCBlbmFibGVzIFxcYDxpbWcgc3JjPXtpbWFnZVBhdGh9PlxcYCBvciBgICtcbiAgICBgXFxgZnMucmVhZEZpbGVTeW5jKGltYWdlUGF0aClcXGAuIElmIG5vdCBwcm92aWRlZCwgaXQgd2lsbCBsb29rIGZvciBgICtcbiAgICBgXFxgYXNzZXRFeHRzXFxgIGZpZWxkIGluIC4vcGFja2FnZS5qc29uIHdoaWNoIHNob3VsZCBiZSBhIGxpc3Qgb2Ygc3RyaW5ncy5gLFxuXTtcbmxldCBTS0lQX01JTklGWV9PUFRJT04gPSBbXG4gIFwiLXMsIC0tc2tpcC1taW5pZnlcIixcbiAgYFNraXAgbWluaWZpY2F0aW9uIHdoZW4gYnVuZGxpbmcuIFVzZWZ1bCBmb3IgaW5zcGVjdGluZyBidW5kbGluZyBpc3N1ZXMuYCxcbl07XG5sZXQgREVCVUdfT1BUSU9OID0gW1xuICBcIi1kLCAtLWRlYnVnXCIsXG4gIFwiSW5jbHVkZSBpbmxpbmUgc291cmNlIG1hcCBhbmQgaW5saW5lIHNvdXJjZS5cIixcbl07XG5sZXQgVFNDT05GSUdfRklMRV9PUFRJT04gPSBbXG4gIFwiLWMsIC0tdHNjb25maWctZmlsZSA8ZmlsZT5cIixcbiAgYFRoZSBmaWxlIHBhdGggdG8gdHNjb25maWcuanNvbi4gSWYgbm90IHByb3ZpZGVkLCBpdCB3aWxsIHRyeSB0byBsb29rIGZvciBgICtcbiAgICBgaXQgYXQgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuYCxcbl07XG5sZXQgRU5UUklFU19DT05GSUdfRklMRV9PUFRJT04gPSBbXG4gIFwiLWVjLCAtLWVudHJpZXMtY29uZmlnLWZpbGUgPGVudHJpZXNDb25maWdGaWxlPlwiLFxuICBgQSBjb25maWcgZmlsZSB0byBzcGVjaWZ5IGEgbGlzdCBvZiBlbnRyeSBmaWxlcywgZWFjaCBvZiB3aGljaCBzaG91bGQgYCArXG4gICAgYGJlIGEgc2luZ2xlIHBhZ2UgYXBwbGljYXRpb24uIExvb3AgZm9yIFwiV2ViQXBwRW50cmllc1wiIGluIGAgK1xuICAgIGBodHRwczovL2dpdGh1Yi5jb20vc2VsZmFnZS9idW5kbGVyX2NsaS9ibG9iL21haW4vd2ViX2FwcF9lbnRyaWVzX2RlZi50cyBgICtcbiAgICBgZm9yIGl0cyBzY2hlbWEuIEl0cyBkaXJlY3RvcnkgaXMgdGhlIGJhc2UgdGhhdCBhbGwgaW1wb3J0ZWQgYXNzZXRzIGAgK1xuICAgIGBzaG91bGQgYmUgcmVsYXRpdmUgdG8sIGFuZCBhIHdlYiBzZXJ2ZXIgY2FuIHNlcnZlIGZpbGVzIGF0IHRoaXMgYCArXG4gICAgYGRpcmVjdG9yeS4gSWYgbm90IHByb3ZpZGVkLCBpdCB3aWxsIGxvb2sgZm9yIC4vJHtERUZBVUxUX0VOVFJJRVNfQ09ORklHX0ZJTEV9LmAsXG5dO1xubGV0IEZST01fRElSX09QVElPTiA9IFtcbiAgXCItZiwgLS1mcm9tLWRpciA8ZnJvbURpcj5cIixcbiAgYFRoZSBkaXJlY3RveSB0byBjb3B5IGZyb20uIElmIG5vdCBwcm92aWRlZCwgaXQgd2lsbCBiZSB0aGUgY3VycmVudCBgICtcbiAgICBgd29ya2luZyBkaXJlY3RvcnkuYCxcbl07XG5sZXQgVE9fRElSX09QVElPTiA9IFtcbiAgXCItdCwgLS10by1kaXIgPHRvRGlyPlwiLFxuICBgVGhlIGRpcmVjdG95IHRvIGNvcHkgdG8uIElmIG5vdCBwcm92aWRlZCwgb3Igd2hlbiA8dG9EaXI+IGVxdWFscyBgICtcbiAgICBgPGZyb21EaXI+LCBubyBjb3BpZXMgaGFwcGVuLmAsXG5dO1xubGV0IEJBU0VfRElSX09QVElPTiA9IFtcbiAgXCItYiwgLS1iYXNlLWRpciA8YmFzZURpcj5cIixcbiAgYFRoZSBiYXNlIGRpcmVjdG9yeSB0aGF0IGFsbCBpbXBvcnRlZCBhc3NldHMgc2hvdWxkIGJlIHJlbGF0aXZlIHRvLCBzdWNoIGAgK1xuICAgIGB0aGF0IGEgd2ViIHNlcnZlciBjYW4gc2VydmUgZmlsZXMgYXQgdGhpcyBkaXJlY3RvcnkuIElmIG5vdCBwcm92aWRlZCwgYCArXG4gICAgYGl0IHdpbGwgYmUgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuYCxcbl07XG5sZXQgT1VUX0RJUl9PUFRJT04gPSBbXG4gIFwiLW8sIC0tb3V0LWRpciA8b3V0RGlyPlwiLFxuICBgVGhlIG91dHB1dCBkaXJlY3RvcnkgdG8gd2hlcmUgZmlsZXMgd2lsbCBiZSBjb3BpZWQuIElmIG5vdCBwcm92aWRlZCwgb3IgYCArXG4gICAgYHdoZW4gPG91dERpcj4gZXF1YWxzIDxiYXNlRGlyPiwgbm8gY29waWVzIGhhcHBlbi5gLFxuXTtcbmxldCBQT1JUX09QVElPTiA9IFtcbiAgXCItcCwgLS1wb3J0IDxwb3J0PlwiLFxuICBgVGhlIHBvcnQgbnVtYmVyIHRvIHN0YXJ0IHlvdXIgbG9jYWwgc2VydmVyLiBEZWZhdWx0IHRvIDgwMDAuYCxcbl07XG5sZXQgTk9fSEVBRExFU1NfQlJPV1NFUl9PUFRJT04gPSBbXG4gIFwiLW5oLCAtLW5vLWhlYWRsZXNzXCIsXG4gIGBUdXJuIG9mZiBydW5uaW5nIHRoZSBicm93c2VyIGluIGhlYWRsZXNzIG1vZGUuYCxcbl07XG5cbmZ1bmN0aW9uIG1haW4oKTogdm9pZCB7XG4gIGxldCBwYWNrYWdlQ29uZmlnID0gSlNPTi5wYXJzZShcbiAgICBmcy5yZWFkRmlsZVN5bmMocGF0aC5qb2luKF9fZGlybmFtZSwgXCJwYWNrYWdlLmpzb25cIikpLnRvU3RyaW5nKCksXG4gICk7XG4gIGxldCBwcm9ncmFtID0gbmV3IENvbW1hbmQoKTtcbiAgcHJvZ3JhbS52ZXJzaW9uKHBhY2thZ2VDb25maWcudmVyc2lvbik7XG4gIHByb2dyYW1cbiAgICAuY29tbWFuZChcImJ1bmRsZUZvck5vZGUgPHNvdXJjZUZpbGU+IDxvdXRwdXRGaWxlPlwiKVxuICAgIC5hbGlhcyhcImJmblwiKVxuICAgIC5kZXNjcmlwdGlvbihcbiAgICAgIGBDb21waWxlIGFuZCBidW5kbGUgZnJvbSBhIFR5cGVTY3JpcHQgc291cmNlIGZpbGUgdGhhdCBjYW4gYmUgcnVuIGluIGAgK1xuICAgICAgICBgTm9kZS4gQm90aCBmaWxlIGV4dHMgY2FuIGJlIG5lZ2xlY3RlZCBhbmQgYXJlIGFsd2F5cyBmaXhlZCBhcyAudHMgYCArXG4gICAgICAgIGBhbmQgLmpzIHJlc3BlY3RpdmVseS4gTnBtIG1vZHVsZXMgYXJlIG5vdCBhY3R1YWxseSBidW5kbGVkIGR1ZSB0byBgICtcbiAgICAgICAgYG1hbnkgb2YgdGhlbSBub3QgY29tcGF0aWJsZSB3aXRoIGJ1bmRsaW5nLmAsXG4gICAgKVxuICAgIC5vcHRpb24oRlJPTV9ESVJfT1BUSU9OWzBdLCBGUk9NX0RJUl9PUFRJT05bMV0pXG4gICAgLm9wdGlvbihUT19ESVJfT1BUSU9OWzBdLCBUT19ESVJfT1BUSU9OWzFdKVxuICAgIC5vcHRpb24oRVhUUkFfRklMRVNfT1BUSU9OWzBdLCBFWFRSQV9GSUxFU19PUFRJT05bMV0pXG4gICAgLm9wdGlvbihJTkxJTkVfSlNfQ09ERV9PUFRJT05bMF0sIElOTElORV9KU19DT0RFX09QVElPTlsxXSlcbiAgICAub3B0aW9uKEFTU0VUX0VYVF9PUFRJT05bMF0sIEFTU0VUX0VYVF9PUFRJT05bMV0pXG4gICAgLm9wdGlvbihTS0lQX01JTklGWV9PUFRJT05bMF0sIFNLSVBfTUlOSUZZX09QVElPTlsxXSlcbiAgICAub3B0aW9uKERFQlVHX09QVElPTlswXSwgREVCVUdfT1BUSU9OWzFdKVxuICAgIC5vcHRpb24oVFNDT05GSUdfRklMRV9PUFRJT05bMF0sIFRTQ09ORklHX0ZJTEVfT1BUSU9OWzFdKVxuICAgIC5hY3Rpb24oYXN5bmMgKHNvdXJjZUZpbGUsIG91dHB1dEZpbGUsIG9wdGlvbnMpID0+IHtcbiAgICAgIGF3YWl0IGJ1bmRsZUZvck5vZGUoXG4gICAgICAgIHRvVW5peFBhdGgoc291cmNlRmlsZSksXG4gICAgICAgIHRvVW5peFBhdGgob3V0cHV0RmlsZSksXG4gICAgICAgIHRvVW5peFBhdGgob3B0aW9ucy5mcm9tRGlyKSxcbiAgICAgICAgdG9Vbml4UGF0aChvcHRpb25zLnRvRGlyKSxcbiAgICAgICAgdG9Vbml4UGF0aEZyb21CdW5kbGVPcHRpb25zKG9wdGlvbnMpLFxuICAgICAgKTtcbiAgICB9KTtcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKFwicnVuSW5Ob2RlIDxzb3VyY2VGaWxlPiBbcGFzcy10aHJvdWdoLWFyZ3MuLi5dXCIpXG4gICAgLmFsaWFzKFwibnJ1blwiKVxuICAgIC5kZXNjcmlwdGlvbihcbiAgICAgIGBDb21waWxlIGFuZCBidW5kbGUgZnJvbSBhIFR5cGVTY3JpcHQgc291cmNlIGZpbGUsIGFuZCBydW4gdGhlIGJ1bmRsZWQgYCArXG4gICAgICAgIGBKYXZhU2NyaXB0IGZpbGUgaW4gTm9kZS4gVGhlIGZpbGUgZXh0IGNhbiBiZSBuZWdsZWN0ZWQgYW5kIGlzIGAgK1xuICAgICAgICBgYWx3YXlzIGZpeGVkIGFzIC50cy4gXCItLVwiIGlzIG5lZWRlZCBpbiBiZXR3ZWVuIDxzb3VyY2VGaWxlPiBhbmQgYCArXG4gICAgICAgIGBwYXNzIHRocm91Z2ggYXJndW1lbnRzLmAsXG4gICAgKVxuICAgIC5vcHRpb24oRVhUUkFfRklMRVNfT1BUSU9OWzBdLCBFWFRSQV9GSUxFU19PUFRJT05bMV0pXG4gICAgLm9wdGlvbihJTkxJTkVfSlNfQ09ERV9PUFRJT05bMF0sIElOTElORV9KU19DT0RFX09QVElPTlsxXSlcbiAgICAub3B0aW9uKEFTU0VUX0VYVF9PUFRJT05bMF0sIEFTU0VUX0VYVF9PUFRJT05bMV0pXG4gICAgLm9wdGlvbihTS0lQX01JTklGWV9PUFRJT05bMF0sIFNLSVBfTUlOSUZZX09QVElPTlsxXSlcbiAgICAub3B0aW9uKERFQlVHX09QVElPTlswXSwgREVCVUdfT1BUSU9OWzFdKVxuICAgIC5vcHRpb24oVFNDT05GSUdfRklMRV9PUFRJT05bMF0sIFRTQ09ORklHX0ZJTEVfT1BUSU9OWzFdKVxuICAgIC5hY3Rpb24oKHNvdXJjZUZpbGUsIHBhc3NUaHJvdWdoQXJncywgb3B0aW9ucykgPT5cbiAgICAgIHJ1bkluTm9kZShcbiAgICAgICAgdG9Vbml4UGF0aChzb3VyY2VGaWxlKSxcbiAgICAgICAgdG9Vbml4UGF0aEZyb21CdW5kbGVPcHRpb25zKG9wdGlvbnMpLFxuICAgICAgICBwYXNzVGhyb3VnaEFyZ3MgYXMgQXJyYXk8c3RyaW5nPixcbiAgICAgICksXG4gICAgKTtcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKFwiYnVuZGxlRm9yQnJvd3NlciA8c291cmNlRmlsZT4gPG91dHB1dEZpbGU+XCIpXG4gICAgLmFsaWFzKFwiYmZiXCIpXG4gICAgLmRlc2NyaXB0aW9uKFxuICAgICAgYENvbXBpbGUgYW5kIGJ1bmRsZSBmcm9tIGEgVHlwZVNjcmlwdCBzb3VyY2UgZmlsZSB0aGF0IGNhbiBiZSBydW4gaW4gYCArXG4gICAgICAgIGBCcm93c2VyLiBCb3RoIGZpbGUgZXh0cyBjYW4gYmUgbmVnbGVjdGVkIGFuZCBhcmUgYWx3YXlzIGZpeGVkIGFzIGAgK1xuICAgICAgICBgLnRzIGFuZCAuanMgcmVzcGVjdGl2ZWx5LmAsXG4gICAgKVxuICAgIC5vcHRpb24oQkFTRV9ESVJfT1BUSU9OWzBdLCBCQVNFX0RJUl9PUFRJT05bMV0pXG4gICAgLm9wdGlvbihPVVRfRElSX09QVElPTlswXSwgT1VUX0RJUl9PUFRJT05bMV0pXG4gICAgLm9wdGlvbihFWFRSQV9GSUxFU19PUFRJT05bMF0sIEVYVFJBX0ZJTEVTX09QVElPTlsxXSlcbiAgICAub3B0aW9uKElOTElORV9KU19DT0RFX09QVElPTlswXSwgSU5MSU5FX0pTX0NPREVfT1BUSU9OWzFdKVxuICAgIC5vcHRpb24oQVNTRVRfRVhUX09QVElPTlswXSwgQVNTRVRfRVhUX09QVElPTlsxXSlcbiAgICAub3B0aW9uKFNLSVBfTUlOSUZZX09QVElPTlswXSwgU0tJUF9NSU5JRllfT1BUSU9OWzFdKVxuICAgIC5vcHRpb24oREVCVUdfT1BUSU9OWzBdLCBERUJVR19PUFRJT05bMV0pXG4gICAgLm9wdGlvbihUU0NPTkZJR19GSUxFX09QVElPTlswXSwgVFNDT05GSUdfRklMRV9PUFRJT05bMV0pXG4gICAgLmFjdGlvbihhc3luYyAoc291cmNlRmlsZSwgb3V0cHV0RmlsZSwgb3B0aW9ucykgPT4ge1xuICAgICAgYXdhaXQgYnVuZGxlRm9yQnJvd3NlcihcbiAgICAgICAgdG9Vbml4UGF0aChzb3VyY2VGaWxlKSxcbiAgICAgICAgdG9Vbml4UGF0aChvdXRwdXRGaWxlKSxcbiAgICAgICAgdG9Vbml4UGF0aChvcHRpb25zLmJhc2VEaXIpLFxuICAgICAgICB0b1VuaXhQYXRoKG9wdGlvbnMub3V0RGlyKSxcbiAgICAgICAgdG9Vbml4UGF0aEZyb21CdW5kbGVPcHRpb25zKG9wdGlvbnMpLFxuICAgICAgKTtcbiAgICB9KTtcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKFwicnVuSW5QdXBwZXRlZXIgPHNvdXJjZUZpbGU+IFtwYXNzLXRocm91Z2gtYXJncy4uLl1cIilcbiAgICAuYWxpYXMoXCJwcnVuXCIpXG4gICAgLmRlc2NyaXB0aW9uKFxuICAgICAgYENvbXBpbGUgYW5kIGJ1bmRsZSBmcm9tIGEgVHlwZVNjcmlwdCBzb3VyY2UgZmlsZSwgYW5kIHJ1biB0aGUgYnVuZGxlZCBgICtcbiAgICAgICAgYEphdmFTY3JpcHQgZmlsZSBpbiBQdXBwZXRlZXIsIGkuZS4sIGhlYWRsZXNzIENocm9tZS4gVGhlIGZpbGUgZXh0IGAgK1xuICAgICAgICBgY2FuIGJlIG5lZ2xlY3RlZCBhbmQgaXMgYWx3YXlzIGZpeGVkIGFzIC50cy4gXCItLVwiIGlzIG5lZWRlZCBpbiBgICtcbiAgICAgICAgYGJldHdlZW4gPHNvdXJjZUZpbGU+IGFuZCBwYXNzIHRocm91Z2ggYXJndW1lbnRzLmAsXG4gICAgKVxuICAgIC5vcHRpb24oQkFTRV9ESVJfT1BUSU9OWzBdLCBCQVNFX0RJUl9PUFRJT05bMV0pXG4gICAgLm9wdGlvbihFWFRSQV9GSUxFU19PUFRJT05bMF0sIEVYVFJBX0ZJTEVTX09QVElPTlsxXSlcbiAgICAub3B0aW9uKElOTElORV9KU19DT0RFX09QVElPTlswXSwgSU5MSU5FX0pTX0NPREVfT1BUSU9OWzFdKVxuICAgIC5vcHRpb24oQVNTRVRfRVhUX09QVElPTlswXSwgQVNTRVRfRVhUX09QVElPTlsxXSlcbiAgICAub3B0aW9uKFNLSVBfTUlOSUZZX09QVElPTlswXSwgU0tJUF9NSU5JRllfT1BUSU9OWzFdKVxuICAgIC5vcHRpb24oREVCVUdfT1BUSU9OWzBdLCBERUJVR19PUFRJT05bMV0pXG4gICAgLm9wdGlvbihUU0NPTkZJR19GSUxFX09QVElPTlswXSwgVFNDT05GSUdfRklMRV9PUFRJT05bMV0pXG4gICAgLm9wdGlvbihQT1JUX09QVElPTlswXSwgUE9SVF9PUFRJT05bMV0sICh2YWx1ZSkgPT4gcGFyc2VJbnQodmFsdWUsIDEwKSlcbiAgICAub3B0aW9uKE5PX0hFQURMRVNTX0JST1dTRVJfT1BUSU9OWzBdLCBOT19IRUFETEVTU19CUk9XU0VSX09QVElPTlsxXSlcbiAgICAuYWN0aW9uKChzb3VyY2VGaWxlLCBwYXNzVGhyb3VnaEFyZ3MsIG9wdGlvbnMpID0+XG4gICAgICBydW5JblB1cHBldGVlcihcbiAgICAgICAgdG9Vbml4UGF0aChzb3VyY2VGaWxlKSxcbiAgICAgICAgdG9Vbml4UGF0aChvcHRpb25zLmJhc2VEaXIpLFxuICAgICAgICBvcHRpb25zLnBvcnQgYXMgbnVtYmVyLFxuICAgICAgICBvcHRpb25zLmhlYWRsZXNzIGFzIGJvb2xlYW4sXG4gICAgICAgIHRvVW5peFBhdGhGcm9tQnVuZGxlT3B0aW9ucyhvcHRpb25zKSxcbiAgICAgICAgcGFzc1Rocm91Z2hBcmdzIGFzIEFycmF5PHN0cmluZz4sXG4gICAgICApLFxuICAgICk7XG4gIHByb2dyYW1cbiAgICAuY29tbWFuZChcImJ1bmRsZVdlYkFwcHNcIilcbiAgICAuYWxpYXMoXCJid2FcIilcbiAgICAuZGVzY3JpcHRpb24oXG4gICAgICBgQnVuZGxlIGFsbCBUeXBlU2NyaXB0IHNvdXJjZSBmaWxlcyBiYXNlZCBvbiA8ZW50cmllc0NvbmZpZz4sIGdlbmVyYXRlIGAgK1xuICAgICAgICBgSFRNTCBmaWxlcyBwb2ludGluZyB0byB0aGUgYnVuZGxlZCBKUyBmaWxlcyByZXNwZWN0aXZlbHksIGNvbXByZXNzIGAgK1xuICAgICAgICBgdGhlbSB3aXRoIEd6aXAsIGNvbGxlY3QgYSBsaXN0IG9mIGFsbCBidW5kbGVkIEpTICYgSFRNTCBmaWxlIHBhdGhzIGAgK1xuICAgICAgICBgYW5kIGFzc2V0IGZpbGUgcGF0aHMgdG8gPGJ1bmRsZWRSZXNvdXJjZXM+LCBhbmQgZmluYWxseSBjb3B5IHRob3NlIGAgK1xuICAgICAgICBgZmlsZXMgaW50byA8b3V0RGlyPiB3aGVyZSB5b3VyIHdlYiBzZXJ2ZXIgY2FuIGJlIHN0YXJ0ZWQuYCxcbiAgICApXG4gICAgLm9wdGlvbihFTlRSSUVTX0NPTkZJR19GSUxFX09QVElPTlswXSwgRU5UUklFU19DT05GSUdfRklMRV9PUFRJT05bMV0pXG4gICAgLm9wdGlvbihcbiAgICAgIFwiLWJyLCAtLWJ1bmRsZWQtcmVzb3VyY2VzLWZpbGUgPGJ1bmRsZWRSZXNvdXJjZXNGaWxlPlwiLFxuICAgICAgYEFuIG91dHB1dCBmaWxlIGdlbmVyYXRlZCBhZnRlciBidW5kbGluZywgY29udGFpbmluZyBhIEpTT04gYXJyYXkgb2YgYCArXG4gICAgICAgIGBmaWxlcyB0aGF0IG5lZWQgdG8gYmUgY29waWVkIHRvIDxvdXREaXI+IGFuZCBzZXJ2ZWQgaW4geW91ciB3ZWIgYCArXG4gICAgICAgIGBzZXJ2ZXIuIElmIG5vdCBwcm92aWRlZCwgaXQgd2lsbCB3cml0ZSB0byBgICtcbiAgICAgICAgYC4vJHtERUZBVUxUX0JVTkRMRURfUkVTT1VSQ0VTX0ZJTEV9LmAsXG4gICAgKVxuICAgIC5vcHRpb24oT1VUX0RJUl9PUFRJT05bMF0sIE9VVF9ESVJfT1BUSU9OWzFdKVxuICAgIC5vcHRpb24oRVhUUkFfRklMRVNfT1BUSU9OWzBdLCBFWFRSQV9GSUxFU19PUFRJT05bMV0pXG4gICAgLm9wdGlvbihJTkxJTkVfSlNfQ09ERV9PUFRJT05bMF0sIElOTElORV9KU19DT0RFX09QVElPTlsxXSlcbiAgICAub3B0aW9uKEFTU0VUX0VYVF9PUFRJT05bMF0sIEFTU0VUX0VYVF9PUFRJT05bMV0pXG4gICAgLm9wdGlvbihTS0lQX01JTklGWV9PUFRJT05bMF0sIFNLSVBfTUlOSUZZX09QVElPTlsxXSlcbiAgICAub3B0aW9uKERFQlVHX09QVElPTlswXSwgREVCVUdfT1BUSU9OWzFdKVxuICAgIC5vcHRpb24oVFNDT05GSUdfRklMRV9PUFRJT05bMF0sIFRTQ09ORklHX0ZJTEVfT1BUSU9OWzFdKVxuICAgIC5hY3Rpb24oKG9wdGlvbnMpID0+XG4gICAgICBidW5kbGVXZWJBcHBzKFxuICAgICAgICB0b1VuaXhQYXRoKG9wdGlvbnMuZW50cmllc0NvbmZpZ0ZpbGUpLFxuICAgICAgICB0b1VuaXhQYXRoKG9wdGlvbnMuYnVuZGxlZFJlc291cmNlc0ZpbGUpLFxuICAgICAgICB0b1VuaXhQYXRoKG9wdGlvbnMub3V0RGlyKSxcbiAgICAgICAgdG9Vbml4UGF0aEZyb21CdW5kbGVPcHRpb25zKG9wdGlvbnMpLFxuICAgICAgKSxcbiAgICApO1xuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoXCJidW5kbGVXZWJTZXJ2ZXIgPHNlcnZlclNvdXJjZUZpbGU+IDxzZXJ2ZXJPdXRwdXRGaWxlPlwiKVxuICAgIC5hbGlhcyhcImJ3c1wiKVxuICAgIC5kZXNjcmlwdGlvbihcbiAgICAgIGBCdW5kbGUgYSBUeXBlU2NyaXB0IHNvdXJjZSBmaWxlIGFzIHRoZSBzZXJ2ZXIncyBtYWluIGZpbGUgYW5kIG91dHB1dC4gYCArXG4gICAgICAgIGBCb3RoIGZpbGUgZXh0cyBjYW4gYmUgbmVnbGVjdGVkIGFuZCBhcmUgYWx3YXlzIGZpeGVkIGFzIC50cyBhbmQgLmpzIGAgK1xuICAgICAgICBgcmVzcGVjdGl2ZWx5LiBOcG0gbW9kdWxlcyBhcmUgbm90IGFjdHVhbGx5IGJ1bmRsZWQgZHVlIHRvIG1hbnkgb2YgYCArXG4gICAgICAgIGB0aGVtIG5vdCBjb21wYXRpYmxlIHdpdGggYnVuZGxpbmcuIEl0IHdpbGwgYWxzbyBidW5kbGUgd2ViIGFwcHMgYCArXG4gICAgICAgIGBiYXNlZCBvbiA8ZW50cmllc0NvbmZpZ0ZpbGU+IGFzIHdlbGwgYXMgPGJhc2VEaXI+LiBGaW5hbGx5LCBhbGwgYCArXG4gICAgICAgIGBidW5kbGVkIGZpbGVzIGFuZCBpbXBvcnRlZCBvciBleHRyYSBhc3NldHMgd2lsbCBiZSBjb3BpZWQgZnJvbSBgICtcbiAgICAgICAgYDxmcm9tRGlyPiB0byA8dG9EaXI+LCB3aXRob3V0IGFueSBzb3VyY2UgZmlsZSBvciBpbnRlcm1lZGlhdGUgZmlsZS5gLFxuICAgIClcbiAgICAub3B0aW9uKEVOVFJJRVNfQ09ORklHX0ZJTEVfT1BUSU9OWzBdLCBFTlRSSUVTX0NPTkZJR19GSUxFX09QVElPTlsxXSlcbiAgICAub3B0aW9uKEZST01fRElSX09QVElPTlswXSwgRlJPTV9ESVJfT1BUSU9OWzFdKVxuICAgIC5vcHRpb24oVE9fRElSX09QVElPTlswXSwgVE9fRElSX09QVElPTlsxXSlcbiAgICAub3B0aW9uKEVYVFJBX0ZJTEVTX09QVElPTlswXSwgRVhUUkFfRklMRVNfT1BUSU9OWzFdKVxuICAgIC5vcHRpb24oSU5MSU5FX0pTX0NPREVfT1BUSU9OWzBdLCBJTkxJTkVfSlNfQ09ERV9PUFRJT05bMV0pXG4gICAgLm9wdGlvbihBU1NFVF9FWFRfT1BUSU9OWzBdLCBBU1NFVF9FWFRfT1BUSU9OWzFdKVxuICAgIC5vcHRpb24oU0tJUF9NSU5JRllfT1BUSU9OWzBdLCBTS0lQX01JTklGWV9PUFRJT05bMV0pXG4gICAgLm9wdGlvbihERUJVR19PUFRJT05bMF0sIERFQlVHX09QVElPTlsxXSlcbiAgICAub3B0aW9uKFRTQ09ORklHX0ZJTEVfT1BUSU9OWzBdLCBUU0NPTkZJR19GSUxFX09QVElPTlsxXSlcbiAgICAuYWN0aW9uKChzZXJ2ZXJTb3VyY2VGaWxlLCBzZXJ2ZXJPdXRwdXRGaWxlLCBvcHRpb25zKSA9PlxuICAgICAgYnVuZGxlV2ViU2VydmVyKFxuICAgICAgICB0b1VuaXhQYXRoKHNlcnZlclNvdXJjZUZpbGUpLFxuICAgICAgICB0b1VuaXhQYXRoKHNlcnZlck91dHB1dEZpbGUpLFxuICAgICAgICB0b1VuaXhQYXRoKG9wdGlvbnMuZW50cmllc0NvbmZpZ0ZpbGUpLFxuICAgICAgICB0b1VuaXhQYXRoKG9wdGlvbnMuZnJvbURpciksXG4gICAgICAgIHRvVW5peFBhdGgob3B0aW9ucy50b0RpciksXG4gICAgICAgIHRvVW5peFBhdGhGcm9tQnVuZGxlT3B0aW9ucyhvcHRpb25zKSxcbiAgICAgICksXG4gICAgKTtcbiAgcHJvZ3JhbS5wYXJzZSgpO1xufVxuXG5tYWluKCk7XG4iXX0=