electron-compile
Version:
Electron supporting package to compile JS and CSS in Electron applications
552 lines (453 loc) • 55.9 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createCompilerHostFromProjectRoot = exports.createCompilerHostFromConfigFile = exports.createCompilerHostFromBabelRc = undefined;
/**
* Creates a compiler host from a .babelrc file. This method is usually called
* from {@link createCompilerHostFromProjectRoot} instead of used directly.
*
* @param {string} file The path to a .babelrc file
*
* @param {string} rootCacheDir (optional) The directory to use as a cache.
*
* @return {Promise<CompilerHost>} A set-up compiler host
*/
let createCompilerHostFromBabelRc = exports.createCompilerHostFromBabelRc = (() => {
var _ref = _asyncToGenerator(function* (file) {
let rootCacheDir = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
let sourceMapPath = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
let info = JSON.parse((yield _promise.pfs.readFile(file, 'utf8')));
// package.json
if ('babel' in info) {
info = info.babel;
}
if ('env' in info) {
let ourEnv = process.env.BABEL_ENV || process.env.NODE_ENV || 'development';
info = info.env[ourEnv];
}
// Are we still package.json (i.e. is there no babel info whatsoever?)
if ('name' in info && 'version' in info) {
let appRoot = _path2.default.dirname(file);
return createCompilerHostFromConfiguration({
appRoot: appRoot,
options: getDefaultConfiguration(appRoot),
rootCacheDir,
sourceMapPath
});
}
return createCompilerHostFromConfiguration({
appRoot: _path2.default.dirname(file),
options: {
'application/javascript': info
},
rootCacheDir,
sourceMapPath
});
});
return function createCompilerHostFromBabelRc(_x5) {
return _ref.apply(this, arguments);
};
})();
/**
* Creates a compiler host from a .compilerc file. This method is usually called
* from {@link createCompilerHostFromProjectRoot} instead of used directly.
*
* @param {string} file The path to a .compilerc file
*
* @param {string} rootCacheDir (optional) The directory to use as a cache.
*
* @return {Promise<CompilerHost>} A set-up compiler host
*/
let createCompilerHostFromConfigFile = exports.createCompilerHostFromConfigFile = (() => {
var _ref2 = _asyncToGenerator(function* (file) {
let rootCacheDir = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
let sourceMapPath = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
let info = JSON.parse((yield _promise.pfs.readFile(file, 'utf8')));
if ('env' in info) {
let ourEnv = process.env.ELECTRON_COMPILE_ENV || process.env.NODE_ENV || 'development';
info = info.env[ourEnv];
}
return createCompilerHostFromConfiguration({
appRoot: _path2.default.dirname(file),
options: info,
rootCacheDir,
sourceMapPath
});
});
return function createCompilerHostFromConfigFile(_x8) {
return _ref2.apply(this, arguments);
};
})();
/**
* Creates a configured {@link CompilerHost} instance from the project root
* directory. This method first searches for a .compilerc (or .compilerc.json), then falls back to the
* default locations for Babel configuration info. If neither are found, defaults
* to standard settings
*
* @param {string} rootDir The root application directory (i.e. the directory
* that has the app's package.json)
*
* @param {string} rootCacheDir (optional) The directory to use as a cache.
*
* @param {string} sourceMapPath (optional) The directory to store sourcemap separately
* if compiler option enabled to emit.
*
* @return {Promise<CompilerHost>} A set-up compiler host
*/
let createCompilerHostFromProjectRoot = exports.createCompilerHostFromProjectRoot = (() => {
var _ref3 = _asyncToGenerator(function* (rootDir) {
let rootCacheDir = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
let sourceMapPath = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
let compilerc = _path2.default.join(rootDir, '.compilerc');
if (statSyncNoException(compilerc)) {
d(`Found a .compilerc at ${compilerc}, using it`);
return yield createCompilerHostFromConfigFile(compilerc, rootCacheDir, sourceMapPath);
}
compilerc += '.json';
if (statSyncNoException(compilerc)) {
d(`Found a .compilerc at ${compilerc}, using it`);
return yield createCompilerHostFromConfigFile(compilerc, rootCacheDir, sourceMapPath);
}
let babelrc = _path2.default.join(rootDir, '.babelrc');
if (statSyncNoException(babelrc)) {
d(`Found a .babelrc at ${babelrc}, using it`);
return yield createCompilerHostFromBabelRc(babelrc, rootCacheDir, sourceMapPath);
}
d(`Using package.json or default parameters at ${rootDir}`);
return yield createCompilerHostFromBabelRc(_path2.default.join(rootDir, 'package.json'), rootCacheDir, sourceMapPath);
});
return function createCompilerHostFromProjectRoot(_x11) {
return _ref3.apply(this, arguments);
};
})();
exports.initializeGlobalHooks = initializeGlobalHooks;
exports.init = init;
exports.createCompilerHostFromConfiguration = createCompilerHostFromConfiguration;
exports.createCompilerHostFromBabelRcSync = createCompilerHostFromBabelRcSync;
exports.createCompilerHostFromConfigFileSync = createCompilerHostFromConfigFileSync;
exports.createCompilerHostFromProjectRootSync = createCompilerHostFromProjectRootSync;
exports.calculateDefaultCompileCacheDirectory = calculateDefaultCompileCacheDirectory;
exports.getDefaultConfiguration = getDefaultConfiguration;
exports.createCompilers = createCompilers;
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _zlib = require('zlib');
var _zlib2 = _interopRequireDefault(_zlib);
var _mkdirp = require('mkdirp');
var _mkdirp2 = _interopRequireDefault(_mkdirp);
var _promise = require('./promise');
var _fileChangeCache = require('./file-change-cache');
var _fileChangeCache2 = _interopRequireDefault(_fileChangeCache);
var _compilerHost = require('./compiler-host');
var _compilerHost2 = _interopRequireDefault(_compilerHost);
var _requireHook = require('./require-hook');
var _requireHook2 = _interopRequireDefault(_requireHook);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const d = require('debug')('electron-compile:config-parser');
// NB: We intentionally delay-load this so that in production, you can create
// cache-only versions of these compilers
let allCompilerClasses = null;
function statSyncNoException(fsPath) {
if ('statSyncNoException' in _fs2.default) {
return _fs2.default.statSyncNoException(fsPath);
}
try {
return _fs2.default.statSync(fsPath);
} catch (e) {
return null;
}
}
/**
* Initialize the global hooks (protocol hook for file:, node.js hook)
* independent of initializing the compiler. This method is usually called by
* init instead of directly
*
* @param {CompilerHost} compilerHost The compiler host to use.
*
*/
function initializeGlobalHooks(compilerHost) {
let isProduction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
let globalVar = global || window;
globalVar.globalCompilerHost = compilerHost;
(0, _requireHook2.default)(compilerHost, isProduction);
if ('type' in process && process.type === 'browser') {
var _require = require('electron');
const app = _require.app;
var _require2 = require('./protocol-hook');
const initializeProtocolHook = _require2.initializeProtocolHook;
let protoify = function () {
initializeProtocolHook(compilerHost);
};
if (app.isReady()) {
protoify();
} else {
app.on('ready', protoify);
}
}
}
/**
* Initialize electron-compile and set it up, either for development or
* production use. This is almost always the only method you need to use in order
* to use electron-compile.
*
* @param {string} appRoot The top-level directory for your application (i.e.
* the one which has your package.json).
*
* @param {string} mainModule The module to require in, relative to the module
* calling init, that will start your app. Write this
* as if you were writing a require call from here.
*
* @param {bool} productionMode If explicitly True/False, will set read-only
* mode to be disabled/enabled. If not, we'll
* guess based on the presence of a production
* cache.
*
* @param {string} cacheDir If not passed in, read-only will look in
* `appRoot/.cache` and dev mode will compile to a
* temporary directory. If it is passed in, both modes
* will cache to/from `appRoot/{cacheDir}`
*
* @param {string} sourceMapPath (optional) The directory to store sourcemap separately
* if compiler option enabled to emit.
* Default to cachePath if not specified, will be ignored for read-only mode.
*/
function init(appRoot, mainModule) {
let productionMode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
let cacheDir = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
let sourceMapPath = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
let compilerHost = null;
let rootCacheDir = _path2.default.join(appRoot, cacheDir || '.cache');
if (productionMode === null) {
productionMode = !!statSyncNoException(rootCacheDir);
}
if (productionMode) {
compilerHost = _compilerHost2.default.createReadonlyFromConfigurationSync(rootCacheDir, appRoot);
} else {
// if cacheDir was passed in, pass it along. Otherwise, default to a tempdir.
const cachePath = cacheDir ? rootCacheDir : null;
const mapPath = sourceMapPath ? _path2.default.join(appRoot, sourceMapPath) : cachePath;
compilerHost = createCompilerHostFromProjectRootSync(appRoot, cachePath, mapPath);
}
initializeGlobalHooks(compilerHost, productionMode);
require.main.require(mainModule);
}
/**
* Creates a {@link CompilerHost} with the given information. This method is
* usually called by {@link createCompilerHostFromProjectRoot}.
*
* @private
*/
function createCompilerHostFromConfiguration(info) {
let compilers = createCompilers();
let rootCacheDir = info.rootCacheDir || calculateDefaultCompileCacheDirectory();
const sourceMapPath = info.sourceMapPath || info.rootCacheDir;
if (info.sourceMapPath) {
createSourceMapDirectory(sourceMapPath);
}
d(`Creating CompilerHost: ${JSON.stringify(info)}, rootCacheDir = ${rootCacheDir}, sourceMapPath = ${sourceMapPath}`);
let fileChangeCache = new _fileChangeCache2.default(info.appRoot);
let compilerInfo = _path2.default.join(rootCacheDir, 'compiler-info.json.gz');
let json = {};
if (_fs2.default.existsSync(compilerInfo)) {
let buf = _fs2.default.readFileSync(compilerInfo);
json = JSON.parse(_zlib2.default.gunzipSync(buf));
fileChangeCache = _fileChangeCache2.default.loadFromData(json.fileChangeCache, info.appRoot, false);
}
Object.keys(info.options || {}).forEach(x => {
let opts = info.options[x];
if (!(x in compilers)) {
throw new Error(`Found compiler settings for missing compiler: ${x}`);
}
// NB: Let's hope this isn't a valid compiler option...
if (opts.passthrough) {
compilers[x] = compilers['text/plain'];
delete opts.passthrough;
}
d(`Setting options for ${x}: ${JSON.stringify(opts)}`);
compilers[x].compilerOptions = opts;
});
let ret = new _compilerHost2.default(rootCacheDir, compilers, fileChangeCache, false, compilers['text/plain'], null, json.mimeTypesToRegister);
// NB: It's super important that we guarantee that the configuration is saved
// out, because we'll need to re-read it in the renderer process
d(`Created compiler host with options: ${JSON.stringify(info)}`);
ret.saveConfigurationSync();
return ret;
}function createCompilerHostFromBabelRcSync(file) {
let rootCacheDir = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
let sourceMapPath = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
let info = JSON.parse(_fs2.default.readFileSync(file, 'utf8'));
// package.json
if ('babel' in info) {
info = info.babel;
}
if ('env' in info) {
let ourEnv = process.env.BABEL_ENV || process.env.NODE_ENV || 'development';
info = info.env[ourEnv];
}
// Are we still package.json (i.e. is there no babel info whatsoever?)
if ('name' in info && 'version' in info) {
let appRoot = _path2.default.dirname(file);
return createCompilerHostFromConfiguration({
appRoot: appRoot,
options: getDefaultConfiguration(appRoot),
rootCacheDir,
sourceMapPath
});
}
return createCompilerHostFromConfiguration({
appRoot: _path2.default.dirname(file),
options: {
'application/javascript': info
},
rootCacheDir,
sourceMapPath
});
}
function createCompilerHostFromConfigFileSync(file) {
let rootCacheDir = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
let sourceMapPath = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
let info = JSON.parse(_fs2.default.readFileSync(file, 'utf8'));
if ('env' in info) {
let ourEnv = process.env.ELECTRON_COMPILE_ENV || process.env.NODE_ENV || 'development';
info = info.env[ourEnv];
}
return createCompilerHostFromConfiguration({
appRoot: _path2.default.dirname(file),
options: info,
rootCacheDir,
sourceMapPath
});
}
function createCompilerHostFromProjectRootSync(rootDir) {
let rootCacheDir = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
let sourceMapPath = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
let compilerc = _path2.default.join(rootDir, '.compilerc');
if (statSyncNoException(compilerc)) {
d(`Found a .compilerc at ${compilerc}, using it`);
return createCompilerHostFromConfigFileSync(compilerc, rootCacheDir, sourceMapPath);
}
let babelrc = _path2.default.join(rootDir, '.babelrc');
if (statSyncNoException(babelrc)) {
d(`Found a .babelrc at ${babelrc}, using it`);
return createCompilerHostFromBabelRcSync(babelrc, rootCacheDir, sourceMapPath);
}
d(`Using package.json or default parameters at ${rootDir}`);
return createCompilerHostFromBabelRcSync(_path2.default.join(rootDir, 'package.json'), rootCacheDir, sourceMapPath);
}
/**
* Returns what electron-compile would use as a default rootCacheDir. Usually only
* used for debugging purposes
*
* @return {string} A path that may or may not exist where electron-compile would
* set up a development mode cache.
*/
function calculateDefaultCompileCacheDirectory() {
let tmpDir = process.env.TEMP || process.env.TMPDIR || '/tmp';
let hash = require('crypto').createHash('md5').update(process.execPath).digest('hex');
let cacheDir = _path2.default.join(tmpDir, `compileCache_${hash}`);
_mkdirp2.default.sync(cacheDir);
d(`Using default cache directory: ${cacheDir}`);
return cacheDir;
}
function createSourceMapDirectory(sourceMapPath) {
_mkdirp2.default.sync(sourceMapPath);
d(`Using separate sourcemap path at ${sourceMapPath}`);
}
function getElectronVersion(rootDir) {
if (process.versions.electron) {
return process.versions.electron;
}
let ourPkgJson = require(_path2.default.join(rootDir, 'package.json'));
let version = ['electron-prebuilt-compile', 'electron'].map(mod => {
if (ourPkgJson.devDependencies && ourPkgJson.devDependencies[mod]) {
// NB: lol this code
let verRange = ourPkgJson.devDependencies[mod];
let m = verRange.match(/(\d+\.\d+\.\d+)/);
if (m && m[1]) return m[1];
}
try {
return process.mainModule.require(`${mod}/package.json`).version;
} catch (e) {
// NB: This usually doesn't work, but sometimes maybe?
}
try {
let p = _path2.default.join(rootDir, mod, 'package.json');
return require(p).version;
} catch (e) {
return null;
}
}).find(x => !!x);
if (!version) {
throw new Error("Can't automatically discover the version of Electron, you probably need a .compilerc file");
}
return version;
}
/**
* Returns the default .configrc if no configuration information can be found.
*
* @return {Object} A list of default config settings for electron-compiler.
*/
function getDefaultConfiguration(rootDir) {
return {
'application/javascript': {
"presets": [["env", {
"targets": {
"electron": getElectronVersion(rootDir)
}
}], "react"],
"sourceMaps": "inline"
}
};
}
/**
* Allows you to create new instances of all compilers that are supported by
* electron-compile and use them directly. Currently supports Babel, CoffeeScript,
* TypeScript, Less, and Jade.
*
* @return {Object} An Object whose Keys are MIME types, and whose values
* are instances of @{link CompilerBase}.
*/
function createCompilers() {
if (!allCompilerClasses) {
// First we want to see if electron-compilers itself has been installed with
// devDependencies. If that's not the case, check to see if
// electron-compilers is installed as a peer dependency (probably as a
// devDependency of the root project).
const locations = ['electron-compilers', '../../electron-compilers'];
for (let location of locations) {
try {
allCompilerClasses = require(location);
} catch (e) {
// Yolo
}
}
if (!allCompilerClasses) {
throw new Error("Electron compilers not found but were requested to be loaded");
}
}
// NB: Note that this code is carefully set up so that InlineHtmlCompiler
// (i.e. classes with `createFromCompilers`) initially get an empty object,
// but will have a reference to the final result of what we return, which
// resolves the circular dependency we'd otherwise have here.
let ret = {};
let instantiatedClasses = allCompilerClasses.map(Klass => {
if ('createFromCompilers' in Klass) {
return Klass.createFromCompilers(ret);
} else {
return new Klass();
}
});
instantiatedClasses.reduce((acc, x) => {
let Klass = Object.getPrototypeOf(x).constructor;
for (let type of Klass.getInputMimeTypes()) {
acc[type] = x;
}
return acc;
}, ret);
return ret;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25maWctcGFyc2VyLmpzIl0sIm5hbWVzIjpbImZpbGUiLCJyb290Q2FjaGVEaXIiLCJzb3VyY2VNYXBQYXRoIiwiaW5mbyIsIkpTT04iLCJwYXJzZSIsInBmcyIsInJlYWRGaWxlIiwiYmFiZWwiLCJvdXJFbnYiLCJwcm9jZXNzIiwiZW52IiwiQkFCRUxfRU5WIiwiTk9ERV9FTlYiLCJhcHBSb290IiwicGF0aCIsImRpcm5hbWUiLCJjcmVhdGVDb21waWxlckhvc3RGcm9tQ29uZmlndXJhdGlvbiIsIm9wdGlvbnMiLCJnZXREZWZhdWx0Q29uZmlndXJhdGlvbiIsImNyZWF0ZUNvbXBpbGVySG9zdEZyb21CYWJlbFJjIiwiRUxFQ1RST05fQ09NUElMRV9FTlYiLCJjcmVhdGVDb21waWxlckhvc3RGcm9tQ29uZmlnRmlsZSIsInJvb3REaXIiLCJjb21waWxlcmMiLCJqb2luIiwic3RhdFN5bmNOb0V4Y2VwdGlvbiIsImQiLCJiYWJlbHJjIiwiY3JlYXRlQ29tcGlsZXJIb3N0RnJvbVByb2plY3RSb290IiwiaW5pdGlhbGl6ZUdsb2JhbEhvb2tzIiwiaW5pdCIsImNyZWF0ZUNvbXBpbGVySG9zdEZyb21CYWJlbFJjU3luYyIsImNyZWF0ZUNvbXBpbGVySG9zdEZyb21Db25maWdGaWxlU3luYyIsImNyZWF0ZUNvbXBpbGVySG9zdEZyb21Qcm9qZWN0Um9vdFN5bmMiLCJjYWxjdWxhdGVEZWZhdWx0Q29tcGlsZUNhY2hlRGlyZWN0b3J5IiwiY3JlYXRlQ29tcGlsZXJzIiwicmVxdWlyZSIsImFsbENvbXBpbGVyQ2xhc3NlcyIsImZzUGF0aCIsImZzIiwic3RhdFN5bmMiLCJlIiwiY29tcGlsZXJIb3N0IiwiaXNQcm9kdWN0aW9uIiwiZ2xvYmFsVmFyIiwiZ2xvYmFsIiwid2luZG93IiwiZ2xvYmFsQ29tcGlsZXJIb3N0IiwidHlwZSIsImFwcCIsImluaXRpYWxpemVQcm90b2NvbEhvb2siLCJwcm90b2lmeSIsImlzUmVhZHkiLCJvbiIsIm1haW5Nb2R1bGUiLCJwcm9kdWN0aW9uTW9kZSIsImNhY2hlRGlyIiwiQ29tcGlsZXJIb3N0IiwiY3JlYXRlUmVhZG9ubHlGcm9tQ29uZmlndXJhdGlvblN5bmMiLCJjYWNoZVBhdGgiLCJtYXBQYXRoIiwibWFpbiIsImNvbXBpbGVycyIsImNyZWF0ZVNvdXJjZU1hcERpcmVjdG9yeSIsInN0cmluZ2lmeSIsImZpbGVDaGFuZ2VDYWNoZSIsIkZpbGVDaGFuZ2VkQ2FjaGUiLCJjb21waWxlckluZm8iLCJqc29uIiwiZXhpc3RzU3luYyIsImJ1ZiIsInJlYWRGaWxlU3luYyIsInpsaWIiLCJndW56aXBTeW5jIiwibG9hZEZyb21EYXRhIiwiT2JqZWN0Iiwia2V5cyIsImZvckVhY2giLCJ4Iiwib3B0cyIsIkVycm9yIiwicGFzc3Rocm91Z2giLCJjb21waWxlck9wdGlvbnMiLCJyZXQiLCJtaW1lVHlwZXNUb1JlZ2lzdGVyIiwic2F2ZUNvbmZpZ3VyYXRpb25TeW5jIiwidG1wRGlyIiwiVEVNUCIsIlRNUERJUiIsImhhc2giLCJjcmVhdGVIYXNoIiwidXBkYXRlIiwiZXhlY1BhdGgiLCJkaWdlc3QiLCJta2RpcnAiLCJzeW5jIiwiZ2V0RWxlY3Ryb25WZXJzaW9uIiwidmVyc2lvbnMiLCJlbGVjdHJvbiIsIm91clBrZ0pzb24iLCJ2ZXJzaW9uIiwibWFwIiwibW9kIiwiZGV2RGVwZW5kZW5jaWVzIiwidmVyUmFuZ2UiLCJtIiwibWF0Y2giLCJwIiwiZmluZCIsImxvY2F0aW9ucyIsImxvY2F0aW9uIiwiaW5zdGFudGlhdGVkQ2xhc3NlcyIsIktsYXNzIiwiY3JlYXRlRnJvbUNvbXBpbGVycyIsInJlZHVjZSIsImFjYyIsImdldFByb3RvdHlwZU9mIiwiY29uc3RydWN0b3IiLCJnZXRJbnB1dE1pbWVUeXBlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQTRKQTs7Ozs7Ozs7Ozs7K0JBVU8sV0FBNkNBLElBQTdDLEVBQTRGO0FBQUEsUUFBekNDLFlBQXlDLHVFQUE1QixJQUE0QjtBQUFBLFFBQXRCQyxhQUFzQix1RUFB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QUFDQTtBQUNBLE1BQUlHLE1BQU0sRUFBVjtBQUNBLE1BQUk0QixzQkFBc0IxRSxtQkFBbUJnRSxHQUFuQixDQUF3QlcsS0FBRCxJQUFXO0FBQzFELFFBQUkseUJBQXlCQSxLQUE3QixFQUFvQztBQUNsQyxhQUFPQSxNQUFNQyxtQkFBTixDQUEwQjlCLEdBQTFCLENBQVA7QUFDRCxLQUZELE1BRU87QUFDTCxhQUFPLElBQUk2QixLQUFKLEVBQVA7QUFDRDtBQUNGLEdBTnlCLENBQTFCOztBQVFBRCxzQkFBb0JHLE1BQXBCLENBQTJCLENBQUNDLEdBQUQsRUFBS3JDLENBQUwsS0FBVztBQUNwQyxRQUFJa0MsUUFBUXJDLE9BQU95QyxjQUFQLENBQXNCdEMsQ0FBdEIsRUFBeUJ1QyxXQUFyQzs7QUFFQSxTQUFLLElBQUlyRSxJQUFULElBQWlCZ0UsTUFBTU0saUJBQU4sRUFBakIsRUFBNEM7QUFBRUgsVUFBSW5FLElBQUosSUFBWThCLENBQVo7QUFBZ0I7QUFDOUQsV0FBT3FDLEdBQVA7QUFDRCxHQUxELEVBS0doQyxHQUxIOztBQU9BLFNBQU9BLEdBQVA7QUFDRCIsImZpbGUiOiJjb25maWctcGFyc2VyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHpsaWIgZnJvbSAnemxpYic7XG5pbXBvcnQgbWtkaXJwIGZyb20gJ21rZGlycCc7XG5pbXBvcnQge3Bmc30gZnJvbSAnLi9wcm9taXNlJztcblxuaW1wb3J0IEZpbGVDaGFuZ2VkQ2FjaGUgZnJvbSAnLi9maWxlLWNoYW5nZS1jYWNoZSc7XG5pbXBvcnQgQ29tcGlsZXJIb3N0IGZyb20gJy4vY29tcGlsZXItaG9zdCc7XG5pbXBvcnQgcmVnaXN0ZXJSZXF1aXJlRXh0ZW5zaW9uIGZyb20gJy4vcmVxdWlyZS1ob29rJztcblxuY29uc3QgZCA9IHJlcXVpcmUoJ2RlYnVnJykoJ2VsZWN0cm9uLWNvbXBpbGU6Y29uZmlnLXBhcnNlcicpO1xuXG4vLyBOQjogV2UgaW50ZW50aW9uYWxseSBkZWxheS1sb2FkIHRoaXMgc28gdGhhdCBpbiBwcm9kdWN0aW9uLCB5b3UgY2FuIGNyZWF0ZVxuLy8gY2FjaGUtb25seSB2ZXJzaW9ucyBvZiB0aGVzZSBjb21waWxlcnNcbmxldCBhbGxDb21waWxlckNsYXNzZXMgPSBudWxsO1xuXG5mdW5jdGlvbiBzdGF0U3luY05vRXhjZXB0aW9uKGZzUGF0aCkge1xuICBpZiAoJ3N0YXRTeW5jTm9FeGNlcHRpb24nIGluIGZzKSB7XG4gICAgcmV0dXJuIGZzLnN0YXRTeW5jTm9FeGNlcHRpb24oZnNQYXRoKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGZzLnN0YXRTeW5jKGZzUGF0aCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5cbi8qKlxuICogSW5pdGlhbGl6ZSB0aGUgZ2xvYmFsIGhvb2tzIChwcm90b2NvbCBob29rIGZvciBmaWxlOiwgbm9kZS5qcyBob29rKVxuICogaW5kZXBlbmRlbnQgb2YgaW5pdGlhbGl6aW5nIHRoZSBjb21waWxlci4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWQgYnlcbiAqIGluaXQgaW5zdGVhZCBvZiBkaXJlY3RseVxuICpcbiAqIEBwYXJhbSB7Q29tcGlsZXJIb3N0fSBjb21waWxlckhvc3QgIFRoZSBjb21waWxlciBob3N0IHRvIHVzZS5cbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0aWFsaXplR2xvYmFsSG9va3MoY29tcGlsZXJIb3N0LCBpc1Byb2R1Y3Rpb249ZmFsc2UpIHtcbiAgbGV0IGdsb2JhbFZhciA9IChnbG9iYWwgfHwgd2luZG93KTtcbiAgZ2xvYmFsVmFyLmdsb2JhbENvbXBpbGVySG9zdCA9IGNvbXBpbGVySG9zdDtcblxuICByZWdpc3RlclJlcXVpcmVFeHRlbnNpb24oY29tcGlsZXJIb3N0LCBpc1Byb2R1Y3Rpb24pO1xuXG4gIGlmICgndHlwZScgaW4gcHJvY2VzcyAmJiBwcm9jZXNzLnR5cGUgPT09ICdicm93c2VyJykge1xuICAgIGNvbnN0IHsgYXBwIH0gPSByZXF1aXJlKCdlbGVjdHJvbicpO1xuICAgIGNvbnN0IHsgaW5pdGlhbGl6ZVByb3RvY29sSG9vayB9ID0gcmVxdWlyZSgnLi9wcm90b2NvbC1ob29rJyk7XG5cbiAgICBsZXQgcHJvdG9pZnkgPSBmdW5jdGlvbigpIHsgaW5pdGlhbGl6ZVByb3RvY29sSG9vayhjb21waWxlckhvc3QpOyB9O1xuICAgIGlmIChhcHAuaXNSZWFkeSgpKSB7XG4gICAgICBwcm90b2lmeSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhcHAub24oJ3JlYWR5JywgcHJvdG9pZnkpO1xuICAgIH1cbiAgfVxufVxuXG5cbi8qKlxuICogSW5pdGlhbGl6ZSBlbGVjdHJvbi1jb21waWxlIGFuZCBzZXQgaXQgdXAsIGVpdGhlciBmb3IgZGV2ZWxvcG1lbnQgb3JcbiAqIHByb2R1Y3Rpb24gdXNlLiBUaGlzIGlzIGFsbW9zdCBhbHdheXMgdGhlIG9ubHkgbWV0aG9kIHlvdSBuZWVkIHRvIHVzZSBpbiBvcmRlclxuICogdG8gdXNlIGVsZWN0cm9uLWNvbXBpbGUuXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBhcHBSb290ICBUaGUgdG9wLWxldmVsIGRpcmVjdG9yeSBmb3IgeW91ciBhcHBsaWNhdGlvbiAoaS5lLlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgb25lIHdoaWNoIGhhcyB5b3VyIHBhY2thZ2UuanNvbikuXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBtYWluTW9kdWxlICBUaGUgbW9kdWxlIHRvIHJlcXVpcmUgaW4sIHJlbGF0aXZlIHRvIHRoZSBtb2R1bGVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGluZyBpbml0LCB0aGF0IHdpbGwgc3RhcnQgeW91ciBhcHAuIFdyaXRlIHRoaXNcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXMgaWYgeW91IHdlcmUgd3JpdGluZyBhIHJlcXVpcmUgY2FsbCBmcm9tIGhlcmUuXG4gKlxuICogQHBhcmFtICB7Ym9vbH0gcHJvZHVjdGlvbk1vZGUgICBJZiBleHBsaWNpdGx5IFRydWUvRmFsc2UsIHdpbGwgc2V0IHJlYWQtb25seVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlIHRvIGJlIGRpc2FibGVkL2VuYWJsZWQuIElmIG5vdCwgd2UnbGxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3Vlc3MgYmFzZWQgb24gdGhlIHByZXNlbmNlIG9mIGEgcHJvZHVjdGlvblxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGNhY2hlRGlyICBJZiBub3QgcGFzc2VkIGluLCByZWFkLW9ubHkgd2lsbCBsb29rIGluXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgYXBwUm9vdC8uY2FjaGVgIGFuZCBkZXYgbW9kZSB3aWxsIGNvbXBpbGUgdG8gYVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcG9yYXJ5IGRpcmVjdG9yeS4gSWYgaXQgaXMgcGFzc2VkIGluLCBib3RoIG1vZGVzXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxsIGNhY2hlIHRvL2Zyb20gYGFwcFJvb3Qve2NhY2hlRGlyfWBcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlTWFwUGF0aCAob3B0aW9uYWwpIFRoZSBkaXJlY3RvcnkgdG8gc3RvcmUgc291cmNlbWFwIHNlcGFyYXRlbHlcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGNvbXBpbGVyIG9wdGlvbiBlbmFibGVkIHRvIGVtaXQuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0IHRvIGNhY2hlUGF0aCBpZiBub3Qgc3BlY2lmaWVkLCB3aWxsIGJlIGlnbm9yZWQgZm9yIHJlYWQtb25seSBtb2RlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5pdChhcHBSb290LCBtYWluTW9kdWxlLCBwcm9kdWN0aW9uTW9kZSA9IG51bGwsIGNhY2hlRGlyID0gbnVsbCwgc291cmNlTWFwUGF0aCA9IG51bGwpIHtcbiAgbGV0IGNvbXBpbGVySG9zdCA9IG51bGw7XG4gIGxldCByb290Q2FjaGVEaXIgPSBwYXRoLmpvaW4oYXBwUm9vdCwgY2FjaGVEaXIgfHwgJy5jYWNoZScpO1xuXG4gIGlmIChwcm9kdWN0aW9uTW9kZSA9PT0gbnVsbCkge1xuICAgIHByb2R1Y3Rpb25Nb2RlID0gISFzdGF0U3luY05vRXhjZXB0aW9uKHJvb3RDYWNoZURpcik7XG4gIH1cblxuICBpZiAocHJvZHVjdGlvbk1vZGUpIHtcbiAgICBjb21waWxlckhvc3QgPSBDb21waWxlckhvc3QuY3JlYXRlUmVhZG9ubHlGcm9tQ29uZmlndXJhdGlvblN5bmMocm9vdENhY2hlRGlyLCBhcHBSb290KTtcbiAgfSBlbHNlIHtcbiAgICAvLyBpZiBjYWNoZURpciB3YXMgcGFzc2VkIGluLCBwYXNzIGl0IGFsb25nLiBPdGhlcndpc2UsIGRlZmF1bHQgdG8gYSB0ZW1wZGlyLlxuICAgIGNvbnN0IGNhY2hlUGF0aCA9IGNhY2hlRGlyID8gcm9vdENhY2hlRGlyIDogbnVsbDtcbiAgICBjb25zdCBtYXBQYXRoID0gc291cmNlTWFwUGF0aCA/IHBhdGguam9pbihhcHBSb290LCBzb3VyY2VNYXBQYXRoKSA6IGNhY2hlUGF0aDtcbiAgICBjb21waWxlckhvc3QgPSBjcmVhdGVDb21waWxlckhvc3RGcm9tUHJvamVjdFJvb3RTeW5jKGFwcFJvb3QsIGNhY2hlUGF0aCwgbWFwUGF0aCk7XG4gIH1cblxuICBpbml0aWFsaXplR2xvYmFsSG9va3MoY29tcGlsZXJIb3N0LCBwcm9kdWN0aW9uTW9kZSk7XG4gIHJlcXVpcmUubWFpbi5yZXF1aXJlKG1haW5Nb2R1bGUpO1xufVxuXG5cbi8qKlxuICogQ3JlYXRlcyBhIHtAbGluayBDb21waWxlckhvc3R9IHdpdGggdGhlIGdpdmVuIGluZm9ybWF0aW9uLiBUaGlzIG1ldGhvZCBpc1xuICogdXN1YWxseSBjYWxsZWQgYnkge0BsaW5rIGNyZWF0ZUNvbXBpbGVySG9zdEZyb21Qcm9qZWN0Um9vdH0uXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNvbXBpbGVySG9zdEZyb21Db25maWd1cmF0aW9uKGluZm8pIHtcbiAgbGV0IGNvbXBpbGVycyA9IGNyZWF0ZUNvbXBpbGVycygpO1xuICBsZXQgcm9vdENhY2hlRGlyID0gaW5mby5yb290Q2FjaGVEaXIgfHwgY2FsY3VsYXRlRGVmYXVsdENvbXBpbGVDYWNoZURpcmVjdG9yeSgpO1xuICBjb25zdCBzb3VyY2VNYXBQYXRoID0gaW5mby5zb3VyY2VNYXBQYXRoIHx8IGluZm8ucm9vdENhY2hlRGlyO1xuXG4gIGlmIChpbmZvLnNvdXJjZU1hcFBhdGgpIHtcbiAgICBjcmVhdGVTb3VyY2VNYXBEaXJlY3Rvcnkoc291cmNlTWFwUGF0aCk7XG4gIH1cblxuICBkKGBDcmVhdGluZyBDb21waWxlckhvc3Q6ICR7SlNPTi5zdHJpbmdpZnkoaW5mbyl9LCByb290Q2FjaGVEaXIgPSAke3Jvb3RDYWNoZURpcn0sIHNvdXJjZU1hcFBhdGggPSAke3NvdXJjZU1hcFBhdGh9YCk7XG4gIGxldCBmaWxlQ2hhbmdlQ2FjaGUgPSBuZXcgRmlsZUNoYW5nZWRDYWNoZShpbmZvLmFwcFJvb3QpO1xuXG4gIGxldCBjb21waWxlckluZm8gPSBwYXRoLmpvaW4ocm9vdENhY2hlRGlyLCAnY29tcGlsZXItaW5mby5qc29uLmd6Jyk7XG4gIGxldCBqc29uID0ge307XG4gIGlmIChmcy5leGlzdHNTeW5jKGNvbXBpbGVySW5mbykpIHtcbiAgICBsZXQgYnVmID0gZnMucmVhZEZpbGVTeW5jKGNvbXBpbGVySW5mbyk7XG4gICAganNvbiA9IEpTT04ucGFyc2UoemxpYi5ndW56aXBTeW5jKGJ1ZikpO1xuICAgIGZpbGVDaGFuZ2VDYWNoZSA9IEZpbGVDaGFuZ2VkQ2FjaGUubG9hZEZyb21EYXRhKGpzb24uZmlsZUNoYW5nZUNhY2hlLCBpbmZvLmFwcFJvb3QsIGZhbHNlKTtcbiAgfVxuXG4gIE9iamVjdC5rZXlzKGluZm8ub3B0aW9ucyB8fCB7fSkuZm9yRWFjaCgoeCkgPT4ge1xuICAgIGxldCBvcHRzID0gaW5mby5vcHRpb25zW3hdO1xuICAgIGlmICghKHggaW4gY29tcGlsZXJzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGb3VuZCBjb21waWxlciBzZXR0aW5ncyBmb3IgbWlzc2luZyBjb21waWxlcjogJHt4fWApO1xuICAgIH1cblxuICAgIC8vIE5COiBMZXQncyBob3BlIHRoaXMgaXNuJ3QgYSB2YWxpZCBjb21waWxlciBvcHRpb24uLi5cbiAgICBpZiAob3B0cy5wYXNzdGhyb3VnaCkge1xuICAgICAgY29tcGlsZXJzW3hdID0gY29tcGlsZXJzWyd0ZXh0L3BsYWluJ107XG4gICAgICBkZWxldGUgb3B0cy5wYXNzdGhyb3VnaDtcbiAgICB9XG5cbiAgICBkKGBTZXR0aW5nIG9wdGlvbnMgZm9yICR7eH06ICR7SlNPTi5zdHJpbmdpZnkob3B0cyl9YCk7XG4gICAgY29tcGlsZXJzW3hdLmNvbXBpbGVyT3B0aW9ucyA9IG9wdHM7XG4gIH0pO1xuXG4gIGxldCByZXQgPSBuZXcgQ29tcGlsZXJIb3N0KHJvb3RDYWNoZURpciwgY29tcGlsZXJzLCBmaWxlQ2hhbmdlQ2FjaGUsIGZhbHNlLCBjb21waWxlcnNbJ3RleHQvcGxhaW4nXSwgbnVsbCwganNvbi5taW1lVHlwZXNUb1JlZ2lzdGVyKTtcblxuICAvLyBOQjogSXQncyBzdXBlciBpbXBvcnRhbnQgdGhhdCB3ZSBndWFyYW50ZWUgdGhhdCB0aGUgY29uZmlndXJhdGlvbiBpcyBzYXZlZFxuICAvLyBvdXQsIGJlY2F1c2Ugd2UnbGwgbmVlZCB0byByZS1yZWFkIGl0IGluIHRoZSByZW5kZXJlciBwcm9jZXNzXG4gIGQoYENyZWF0ZWQgY29tcGlsZXIgaG9zdCB3aXRoIG9wdGlvbnM6ICR7SlNPTi5zdHJpbmdpZnkoaW5mbyl9YCk7XG4gIHJldC5zYXZlQ29uZmlndXJhdGlvblN5bmMoKTtcbiAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgY29tcGlsZXIgaG9zdCBmcm9tIGEgLmJhYmVscmMgZmlsZS4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWRcbiAqIGZyb20ge0BsaW5rIGNyZWF0ZUNvbXBpbGVySG9zdEZyb21Qcm9qZWN0Um9vdH0gaW5zdGVhZCBvZiB1c2VkIGRpcmVjdGx5LlxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gZmlsZSAgVGhlIHBhdGggdG8gYSAuYmFiZWxyYyBmaWxlXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSByb290Q2FjaGVEaXIgKG9wdGlvbmFsKSAgVGhlIGRpcmVjdG9yeSB0byB1c2UgYXMgYSBjYWNoZS5cbiAqXG4gKiBAcmV0dXJuIHtQcm9taXNlPENvbXBpbGVySG9zdD59ICBBIHNldC11cCBjb21waWxlciBob3N0XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVDb21waWxlckhvc3RGcm9tQmFiZWxSYyhmaWxlLCByb290Q2FjaGVEaXI9bnVsbCwgc291cmNlTWFwUGF0aCA9IG51bGwpIHtcbiAgbGV0IGluZm8gPSBKU09OLnBhcnNlKGF3YWl0IHBmcy5yZWFkRmlsZShmaWxlLCAndXRmOCcpKTtcblxuICAvLyBwYWNrYWdlLmpzb25cbiAgaWYgKCdiYWJlbCcgaW4gaW5mbykge1xuICAgIGluZm8gPSBpbmZvLmJhYmVsO1xuICB9XG5cbiAgaWYgKCdlbnYnIGluIGluZm8pIHtcbiAgICBsZXQgb3VyRW52ID0gcHJvY2Vzcy5lbnYuQkFCRUxfRU5WIHx8IHByb2Nlc3MuZW52Lk5PREVfRU5WIHx8ICdkZXZlbG9wbWVudCc7XG4gICAgaW5mbyA9IGluZm8uZW52W291ckVudl07XG4gIH1cblxuICAvLyBBcmUgd2Ugc3RpbGwgcGFja2FnZS5qc29uIChpLmUuIGlzIHRoZXJlIG5vIGJhYmVsIGluZm8gd2hhdHNvZXZlcj8pXG4gIGlmICgnbmFtZScgaW4gaW5mbyAmJiAndmVyc2lvbicgaW4gaW5mbykge1xuICAgIGxldCBhcHBSb290ID0gcGF0aC5kaXJuYW1lKGZpbGUpO1xuICAgIHJldHVybiBjcmVhdGVDb21waWxlckhvc3RGcm9tQ29uZmlndXJhdGlvbih7XG4gICAgICBhcHBSb290OiBhcHBSb290LFxuICAgICAgb3B0aW9uczogZ2V0RGVmYXVsdENvbmZpZ3VyYXRpb24oYXBwUm9vdCksXG4gICAgICByb290Q2FjaGVEaXIsXG4gICAgICBzb3VyY2VNYXBQYXRoXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gY3JlYXRlQ29tcGlsZXJIb3N0RnJvbUNvbmZpZ3VyYXRpb24oe1xuICAgIGFwcFJvb3Q6IHBhdGguZGlybmFtZShmaWxlKSxcbiAgICBvcHRpb25zOiB7XG4gICAgICAnYXBwbGljYXRpb24vamF2YXNjcmlwdCc6IGluZm9cbiAgICB9LFxuICAgIHJvb3RDYWNoZURpcixcbiAgICBzb3VyY2VNYXBQYXRoXG4gIH0pO1xufVxuXG5cbi8qKlxuICogQ3JlYXRlcyBhIGNvbXBpbGVyIGhvc3QgZnJvbSBhIC5jb21waWxlcmMgZmlsZS4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBjYWxsZWRcbiAqIGZyb20ge0BsaW5rIGNyZWF0ZUNvbXBpbGVySG9zdEZyb21Qcm9qZWN0Um9vdH0gaW5zdGVhZCBvZiB1c2VkIGRpcmVjdGx5LlxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gZmlsZSAgVGhlIHBhdGggdG8gYSAuY29tcGlsZXJjIGZpbGVcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHJvb3RDYWNoZURpciAob3B0aW9uYWwpICBUaGUgZGlyZWN0b3J5IHRvIHVzZSBhcyBhIGNhY2hlLlxuICpcbiAqIEByZXR1cm4ge1Byb21pc2U8Q29tcGlsZXJIb3N0Pn0gIEEgc2V0LXVwIGNvbXBpbGVyIGhvc3RcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUNvbXBpbGVySG9zdEZyb21Db25maWdGaWxlKGZpbGUsIHJvb3RDYWNoZURpcj1udWxsLCBzb3VyY2VNYXBQYXRoID0gbnVsbCkge1xuICBsZXQgaW5mbyA9IEpTT04ucGFyc2UoYXdhaXQgcGZzLnJlYWRGaWxlKGZpbGUsICd1dGY4JykpO1xuXG4gIGlmICgnZW52JyBpbiBpbmZvKSB7XG4gICAgbGV0IG91ckVudiA9IHByb2Nlc3MuZW52LkVMRUNUUk9OX0NPTVBJTEVfRU5WIHx8IHByb2Nlc3MuZW52Lk5PREVfRU5WIHx8ICdkZXZlbG9wbWVudCc7XG4gICAgaW5mbyA9IGluZm8uZW52W291ckVudl07XG4gIH1cblxuICByZXR1cm4gY3JlYXRlQ29tcGlsZXJIb3N0RnJvbUNvbmZpZ3VyYXRpb24oe1xuICAgIGFwcFJvb3Q6IHBhdGguZGlybmFtZShmaWxlKSxcbiAgICBvcHRpb25zOiBpbmZvLFxuICAgIHJvb3RDYWNoZURpcixcbiAgICBzb3VyY2VNYXBQYXRoXG4gIH0pO1xufVxuXG5cbi8qKlxuICogQ3JlYXRlcyBhIGNvbmZpZ3VyZWQge0BsaW5rIENvbXBpbGVySG9zdH0gaW5zdGFuY2UgZnJvbSB0aGUgcHJvamVjdCByb290XG4gKiBkaXJlY3RvcnkuIFRoaXMgbWV0aG9kIGZpcnN0IHNlYXJjaGVzIGZvciBhIC5jb21waWxlcmMgKG9yIC5jb21waWxlcmMuanNvbiksIHRoZW4gZmFsbHMgYmFjayB0byB0aGVcbiAqIGRlZmF1bHQgbG9jYXRpb25zIGZvciBCYWJlbCBjb25maWd1cmF0aW9uIGluZm8uIElmIG5laXRoZXIgYXJlIGZvdW5kLCBkZWZhdWx0c1xuICogdG8gc3RhbmRhcmQgc2V0dGluZ3NcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHJvb3REaXIgIFRoZSByb290IGFwcGxpY2F0aW9uIGRpcmVjdG9yeSAoaS5lLiB0aGUgZGlyZWN0b3J5XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQgaGFzIHRoZSBhcHAncyBwYWNrYWdlLmpzb24pXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSByb290Q2FjaGVEaXIgKG9wdGlvbmFsKSAgVGhlIGRpcmVjdG9yeSB0byB1c2UgYXMgYSBjYWNoZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlTWFwUGF0aCAob3B0aW9uYWwpIFRoZSBkaXJlY3RvcnkgdG8gc3RvcmUgc291cmNlbWFwIHNlcGFyYXRlbHlcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGNvbXBpbGVyIG9wdGlvbiBlbmFibGVkIHRvIGVtaXQuXG4gKlxuICogQHJldHVybiB7UHJvbWlzZTxDb21waWxlckhvc3Q+fSAgQSBzZXQtdXAgY29tcGlsZXIgaG9zdFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlQ29tcGlsZXJIb3N0RnJvbVByb2plY3RSb290KHJvb3REaXIsIHJvb3RDYWNoZURpciA9IG51bGwsIHNvdXJjZU1hcFBhdGggPSBudWxsKSB7XG4gIGxldCBjb21waWxlcmMgPSBwYXRoLmpvaW4ocm9vdERpciwgJy5jb21waWxlcmMnKTtcbiAgaWYgKHN0YXRTeW5jTm9FeGNlcHRpb24oY29tcGlsZXJjKSkge1xuICAgIGQoYEZvdW5kIGEgLmNvbXBpbGVyYyBhdCAke2NvbXBpbGVyY30sIHVzaW5nIGl0YCk7XG4gICAgcmV0dXJuIGF3YWl0IGNyZWF0ZUNvbXBpbGVySG9zdEZyb21Db25maWdGaWxlKGNvbXBpbGVyYywgcm9vdENhY2hlRGlyLCBzb3VyY2VNYXBQYXRoKTtcbiAgfVxuICBjb21waWxlcmMgKz0gJy5qc29uJztcbiAgaWYgKHN0YXRTeW5jTm9FeGNlcHRpb24oY29tcGlsZXJjKSkge1xuICAgIGQoYEZvdW5kIGEgLmNvbXBpbGVyYyBhdCAke2NvbXBpbGVyY30sIHVzaW5nIGl0YCk7XG4gICAgcmV0dXJuIGF3YWl0IGNyZWF0ZUNvbXBpbGVySG9zdEZyb21Db25maWdGaWxlKGNvbXBpbGVyYywgcm9vdENhY2hlRGlyLCBzb3VyY2VNYXBQYXRoKTtcbiAgfVxuXG4gIGxldCBiYWJlbHJjID0gcGF0aC5qb2luKHJvb3REaXIsICcuYmFiZWxyYycpO1xuICBpZiAoc3RhdFN5bmNOb0V4Y2VwdGlvbihiYWJlbHJjKSkge1xuICAgIGQoYEZvdW5kIGEgLmJhYmVscmMgYXQgJHtiYWJlbHJjfSwgdXNpbmcgaXRgKTtcbiAgICByZXR1cm4gYXdhaXQgY3JlYXRlQ29tcGlsZXJIb3N0RnJvbUJhYmVsUmMoYmFiZWxyYywgcm9vdENhY2hlRGlyLCBzb3VyY2VNYXBQYXRoKTtcbiAgfVxuXG4gIGQoYFVzaW5nIHBhY2thZ2UuanNvbiBvciBkZWZhdWx0IHBhcmFtZXRlcnMgYXQgJHtyb290RGlyfWApO1xuICByZXR1cm4gYXdhaXQgY3JlYXRlQ29tcGlsZXJIb3N0RnJvbUJhYmVsUmMocGF0aC5qb2luKHJvb3REaXIsICdwYWNrYWdlLmpzb24nKSwgcm9vdENhY2hlRGlyLCBzb3VyY2VNYXBQYXRoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNvbXBpbGVySG9zdEZyb21CYWJlbFJjU3luYyhmaWxlLCByb290Q2FjaGVEaXI9bnVsbCwgc291cmNlTWFwUGF0aCA9IG51bGwpIHtcbiAgbGV0IGluZm8gPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhmaWxlLCAndXRmOCcpKTtcblxuICAvLyBwYWNrYWdlLmpzb25cbiAgaWYgKCdiYWJlbCcgaW4gaW5mbykge1xuICAgIGluZm8gPSBpbmZvLmJhYmVsO1xuICB9XG5cbiAgaWYgKCdlbnYnIGluIGluZm8pIHtcbiAgICBsZXQgb3VyRW52ID0gcHJvY2Vzcy5lbnYuQkFCRUxfRU5WIHx8IHByb2Nlc3MuZW52Lk5PREVfRU5WIHx8ICdkZXZlbG9wbWVudCc7XG4gICAgaW5mbyA9IGluZm8uZW52W291ckVudl07XG4gIH1cblxuICAvLyBBcmUgd2Ugc3RpbGwgcGFja2FnZS5qc29uIChpLmUuIGlzIHRoZXJlIG5vIGJhYmVsIGluZm8gd2hhdHNvZXZlcj8pXG4gIGlmICgnbmFtZScgaW4gaW5mbyAmJiAndmVyc2lvbicgaW4gaW5mbykge1xuICAgIGxldCBhcHBSb290ID0gcGF0aC5kaXJuYW1lKGZpbGUpXG4gICAgcmV0dXJuIGNyZWF0ZUNvbXBpbGVySG9zdEZyb21Db25maWd1cmF0aW9uKHtcbiAgICAgIGFwcFJvb3Q6IGFwcFJvb3QsXG4gICAgICBvcHRpb25zOiBnZXREZWZhdWx0Q29uZmlndXJhdGlvbihhcHBSb290KSxcbiAgICAgIHJvb3RDYWNoZURpcixcbiAgICAgIHNvdXJjZU1hcFBhdGhcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVDb21waWxlckhvc3RGcm9tQ29uZmlndXJhdGlvbih7XG4gICAgYXBwUm9vdDogcGF0aC5kaXJuYW1lKGZpbGUpLFxuICAgIG9wdGlvbnM6IHtcbiAgICAgICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0JzogaW5mb1xuICAgIH0sXG4gICAgcm9vdENhY2hlRGlyLFxuICAgIHNvdXJjZU1hcFBhdGhcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDb21waWxlckhvc3RGcm9tQ29uZmlnRmlsZVN5bmMoZmlsZSwgcm9vdENhY2hlRGlyPW51bGwsIHNvdXJjZU1hcFBhdGggPSBudWxsKSB7XG4gIGxldCBpbmZvID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoZmlsZSwgJ3V0ZjgnKSk7XG5cbiAgaWYgKCdlbnYnIGluIGluZm8pIHtcbiAgICBsZXQgb3VyRW52ID0gcHJvY2Vzcy5lbnYuRUxFQ1RST05fQ09NUElMRV9FTlYgfHwgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgfHwgJ2RldmVsb3BtZW50JztcbiAgICBpbmZvID0gaW5mby5lbnZbb3VyRW52XTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVDb21waWxlckhvc3RGcm9tQ29uZmlndXJhdGlvbih7XG4gICAgYXBwUm9vdDogcGF0aC5kaXJuYW1lKGZpbGUpLFxuICAgIG9wdGlvbnM6IGluZm8sXG4gICAgcm9vdENhY2hlRGlyLFxuICAgIHNvdXJjZU1hcFBhdGhcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDb21waWxlckhvc3RGcm9tUHJvamVjdFJvb3RTeW5jKHJvb3REaXIsIHJvb3RDYWNoZURpciA9IG51bGwsIHNvdXJjZU1hcFBhdGggPSBudWxsKSB7XG4gIGxldCBjb21waWxlcmMgPSBwYXRoLmpvaW4ocm9vdERpciwgJy5jb21waWxlcmMnKTtcbiAgaWYgKHN0YXRTeW5jTm9FeGNlcHRpb24oY29tcGlsZXJjKSkge1xuICAgIGQoYEZvdW5kIGEgLmNvbXBpbGVyYyBhdCAke2NvbXBpbGVyY30sIHVzaW5nIGl0YCk7XG4gICAgcmV0dXJuIGNyZWF0ZUNvbXBpbGVySG9zdEZyb21Db25maWdGaWxlU3luYyhjb21waWxlcmMsIHJvb3RDYWNoZURpciwgc291cmNlTWFwUGF0aCk7XG4gIH1cblxuICBsZXQgYmFiZWxyYyA9IHBhdGguam9pbihyb290RGlyLCAnLmJhYmVscmMnKTtcbiAgaWYgKHN0YXRTeW5jTm9FeGNlcHRp