android-manifest.js 29.1 KB
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

require("source-map-support/register");

var _teen_process = require("teen_process");

var _logger = _interopRequireDefault(require("../logger.js"));

var _helpers = require("../helpers.js");

var _appiumSupport = require("appium-support");

var _lodash = _interopRequireDefault(require("lodash"));

var _path = _interopRequireDefault(require("path"));

var _adbkitApkreader = _interopRequireDefault(require("adbkit-apkreader"));

let manifestMethods = {};

manifestMethods.packageAndLaunchActivityFromManifest = async function packageAndLaunchActivityFromManifest(appPath) {
  if (appPath.endsWith(_helpers.APKS_EXTENSION)) {
    appPath = await this.extractBaseApk(appPath);
  }

  const apkReader = await _adbkitApkreader.default.open(appPath);
  const manifest = await apkReader.readManifest();
  const {
    pkg,
    activity
  } = (0, _helpers.parseManifest)(manifest);

  _logger.default.info(`Package name: '${pkg}'`);

  _logger.default.info(`Main activity name: '${activity}'`);

  return {
    apkPackage: pkg,
    apkActivity: activity
  };
};

manifestMethods.targetSdkVersionFromManifest = async function targetSdkVersionFromManifest(appPath) {
  _logger.default.debug(`Extracting target SDK version of '${appPath}'`);

  const originalAppPath = appPath;

  if (appPath.endsWith(_helpers.APKS_EXTENSION)) {
    appPath = await this.extractBaseApk(appPath);
  }

  const getTargetSdkViaApkReader = async () => {
    const apkReader = await _adbkitApkreader.default.open(appPath);
    const manifest = await apkReader.readManifest();

    if (manifest.usesSdk && _lodash.default.isInteger(manifest.usesSdk.targetSdkVersion)) {
      return manifest.usesSdk.targetSdkVersion;
    }

    throw new Error('Cannot find the information about targetSdkVersion in the manifest');
  };

  const getTargetSdkViaAapt = async () => {
    await this.initAapt();
    const args = ['dump', 'badging', appPath];
    const {
      stdout
    } = await (0, _teen_process.exec)(this.binaries.aapt, args);
    const targetSdkVersion = /targetSdkVersion:'([^']+)'/g.exec(stdout);

    if (!targetSdkVersion) {
      _logger.default.debug(stdout);

      throw new Error('Cannot parse the command output');
    }

    return parseInt(targetSdkVersion[1], 10);
  };

  const versionGetters = [['ApkReader', getTargetSdkViaApkReader], ['aapt', getTargetSdkViaAapt]];

  for (const [toolName, versionGetter] of versionGetters) {
    try {
      return await versionGetter();
    } catch (e) {
      _logger.default.info(`Cannot extract targetSdkVersion of '${originalAppPath}' using ${toolName}. ` + `Original error: ${e.message}`);
    }
  }

  throw new Error(`Cannot extract the target SDK version number of '${originalAppPath}' using either of ` + `${JSON.stringify(versionGetters.map(pair => pair[0]))} tools. ` + `Check the server log for more details`);
};

manifestMethods.targetSdkVersionUsingPKG = async function targetSdkVersionUsingPKG(pkg, cmdOutput = null) {
  let stdout = cmdOutput || (await this.shell(['dumpsys', 'package', pkg]));
  let targetSdkVersion = new RegExp(/targetSdk=([^\s\s]+)/g).exec(stdout);

  if (targetSdkVersion && targetSdkVersion.length >= 2) {
    targetSdkVersion = targetSdkVersion[1];
  } else {
    targetSdkVersion = 0;
  }

  return parseInt(targetSdkVersion, 10);
};

manifestMethods.compileManifest = async function compileManifest(manifest, manifestPackage, targetPackage) {
  const {
    platform,
    platformPath
  } = await (0, _helpers.getAndroidPlatformAndPath)();

  if (!platform) {
    throw new Error('Cannot compile the manifest. The required platform does not exist (API level >= 17)');
  }

  const resultPath = `${manifest}.apk`;

  const androidJarPath = _path.default.resolve(platformPath, 'android.jar');

  if (await _appiumSupport.fs.exists(resultPath)) {
    await _appiumSupport.fs.rimraf(resultPath);
  }

  try {
    await this.initAapt2();
    const args = ['link', '-o', resultPath, '--manifest', manifest, '--rename-manifest-package', manifestPackage, '--rename-instrumentation-target-package', targetPackage, '-I', androidJarPath, '-v'];

    _logger.default.debug(`Compiling the manifest using '${_appiumSupport.util.quote([this.binaries.aapt2, ...args])}'`);

    await (0, _teen_process.exec)(this.binaries.aapt2, args);
  } catch (e) {
    _logger.default.debug('Cannot compile the manifest using aapt2. Defaulting to aapt. ' + `Original error: ${e.stderr || e.message}`);

    await this.initAapt();
    const args = ['package', '-M', manifest, '--rename-manifest-package', manifestPackage, '--rename-instrumentation-target-package', targetPackage, '-I', androidJarPath, '-F', resultPath, '-f'];

    _logger.default.debug(`Compiling the manifest using '${_appiumSupport.util.quote([this.binaries.aapt, ...args])}'`);

    try {
      await (0, _teen_process.exec)(this.binaries.aapt, args);
    } catch (e1) {
      throw new Error(`Cannot compile the manifest. Original error: ${e1.stderr || e1.message}`);
    }
  }

  _logger.default.debug(`Compiled the manifest at '${resultPath}'`);
};

manifestMethods.insertManifest = async function insertManifest(manifest, srcApk, dstApk) {
  _logger.default.debug(`Inserting manifest '${manifest}', src: '${srcApk}', dst: '${dstApk}'`);

  await _appiumSupport.zip.assertValidZip(srcApk);
  await (0, _helpers.unzipFile)(`${manifest}.apk`);

  const manifestName = _path.default.basename(manifest);

  try {
    await this.initAapt();
    await _appiumSupport.fs.copyFile(srcApk, dstApk);

    _logger.default.debug('Moving manifest');

    try {
      await (0, _teen_process.exec)(this.binaries.aapt, ['remove', dstApk, manifestName]);
    } catch (ign) {}

    await (0, _teen_process.exec)(this.binaries.aapt, ['add', dstApk, manifestName], {
      cwd: _path.default.dirname(manifest)
    });
  } catch (e) {
    _logger.default.debug('Cannot insert manifest using aapt. Defaulting to zip. ' + `Original error: ${e.stderr || e.message}`);

    const tmpRoot = await _appiumSupport.tempDir.openDir();

    try {
      _logger.default.debug(`Extracting the source apk at '${srcApk}'`);

      await _appiumSupport.zip.extractAllTo(srcApk, tmpRoot);

      _logger.default.debug('Moving manifest');

      await _appiumSupport.fs.mv(manifest, _path.default.resolve(tmpRoot, manifestName));

      _logger.default.debug(`Collecting the destination apk at '${dstApk}'`);

      await _appiumSupport.zip.toArchive(dstApk, {
        cwd: tmpRoot
      });
    } finally {
      await _appiumSupport.fs.rimraf(tmpRoot);
    }
  }

  _logger.default.debug(`Manifest insertion into '${dstApk}' is completed`);
};

manifestMethods.hasInternetPermissionFromManifest = async function hasInternetPermissionFromManifest(appPath) {
  _logger.default.debug(`Checking if '${appPath}' requires internet access permission in the manifest`);

  if (appPath.endsWith(_helpers.APKS_EXTENSION)) {
    appPath = await this.extractBaseApk(appPath);
  }

  const apkReader = await _adbkitApkreader.default.open(appPath);
  const manifest = await apkReader.readManifest();
  return (manifest.usesPermissions || []).some(({
    name
  }) => name === 'android.permission.INTERNET');
};

var _default = manifestMethods;
exports.default = _default;require('source-map-support').install();


//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi90b29scy9hbmRyb2lkLW1hbmlmZXN0LmpzIl0sIm5hbWVzIjpbIm1hbmlmZXN0TWV0aG9kcyIsInBhY2thZ2VBbmRMYXVuY2hBY3Rpdml0eUZyb21NYW5pZmVzdCIsImFwcFBhdGgiLCJlbmRzV2l0aCIsIkFQS1NfRVhURU5TSU9OIiwiZXh0cmFjdEJhc2VBcGsiLCJhcGtSZWFkZXIiLCJBcGtSZWFkZXIiLCJvcGVuIiwibWFuaWZlc3QiLCJyZWFkTWFuaWZlc3QiLCJwa2ciLCJhY3Rpdml0eSIsImxvZyIsImluZm8iLCJhcGtQYWNrYWdlIiwiYXBrQWN0aXZpdHkiLCJ0YXJnZXRTZGtWZXJzaW9uRnJvbU1hbmlmZXN0IiwiZGVidWciLCJvcmlnaW5hbEFwcFBhdGgiLCJnZXRUYXJnZXRTZGtWaWFBcGtSZWFkZXIiLCJ1c2VzU2RrIiwiXyIsImlzSW50ZWdlciIsInRhcmdldFNka1ZlcnNpb24iLCJFcnJvciIsImdldFRhcmdldFNka1ZpYUFhcHQiLCJpbml0QWFwdCIsImFyZ3MiLCJzdGRvdXQiLCJiaW5hcmllcyIsImFhcHQiLCJleGVjIiwicGFyc2VJbnQiLCJ2ZXJzaW9uR2V0dGVycyIsInRvb2xOYW1lIiwidmVyc2lvbkdldHRlciIsImUiLCJtZXNzYWdlIiwiSlNPTiIsInN0cmluZ2lmeSIsIm1hcCIsInBhaXIiLCJ0YXJnZXRTZGtWZXJzaW9uVXNpbmdQS0ciLCJjbWRPdXRwdXQiLCJzaGVsbCIsIlJlZ0V4cCIsImxlbmd0aCIsImNvbXBpbGVNYW5pZmVzdCIsIm1hbmlmZXN0UGFja2FnZSIsInRhcmdldFBhY2thZ2UiLCJwbGF0Zm9ybSIsInBsYXRmb3JtUGF0aCIsInJlc3VsdFBhdGgiLCJhbmRyb2lkSmFyUGF0aCIsInBhdGgiLCJyZXNvbHZlIiwiZnMiLCJleGlzdHMiLCJyaW1yYWYiLCJpbml0QWFwdDIiLCJ1dGlsIiwicXVvdGUiLCJhYXB0MiIsInN0ZGVyciIsImUxIiwiaW5zZXJ0TWFuaWZlc3QiLCJzcmNBcGsiLCJkc3RBcGsiLCJ6aXAiLCJhc3NlcnRWYWxpZFppcCIsIm1hbmlmZXN0TmFtZSIsImJhc2VuYW1lIiwiY29weUZpbGUiLCJpZ24iLCJjd2QiLCJkaXJuYW1lIiwidG1wUm9vdCIsInRlbXBEaXIiLCJvcGVuRGlyIiwiZXh0cmFjdEFsbFRvIiwibXYiLCJ0b0FyY2hpdmUiLCJoYXNJbnRlcm5ldFBlcm1pc3Npb25Gcm9tTWFuaWZlc3QiLCJ1c2VzUGVybWlzc2lvbnMiLCJzb21lIiwibmFtZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFHQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQSxJQUFJQSxlQUFlLEdBQUcsRUFBdEI7O0FBZ0JBQSxlQUFlLENBQUNDLG9DQUFoQixHQUF1RCxlQUFlQSxvQ0FBZixDQUFxREMsT0FBckQsRUFBOEQ7QUFDbkgsTUFBSUEsT0FBTyxDQUFDQyxRQUFSLENBQWlCQyx1QkFBakIsQ0FBSixFQUFzQztBQUNwQ0YsSUFBQUEsT0FBTyxHQUFHLE1BQU0sS0FBS0csY0FBTCxDQUFvQkgsT0FBcEIsQ0FBaEI7QUFDRDs7QUFFRCxRQUFNSSxTQUFTLEdBQUcsTUFBTUMseUJBQVVDLElBQVYsQ0FBZU4sT0FBZixDQUF4QjtBQUNBLFFBQU1PLFFBQVEsR0FBRyxNQUFNSCxTQUFTLENBQUNJLFlBQVYsRUFBdkI7QUFDQSxRQUFNO0FBQUNDLElBQUFBLEdBQUQ7QUFBTUMsSUFBQUE7QUFBTixNQUFrQiw0QkFBY0gsUUFBZCxDQUF4Qjs7QUFDQUksa0JBQUlDLElBQUosQ0FBVSxrQkFBaUJILEdBQUksR0FBL0I7O0FBQ0FFLGtCQUFJQyxJQUFKLENBQVUsd0JBQXVCRixRQUFTLEdBQTFDOztBQUNBLFNBQU87QUFDTEcsSUFBQUEsVUFBVSxFQUFFSixHQURQO0FBRUxLLElBQUFBLFdBQVcsRUFBRUo7QUFGUixHQUFQO0FBSUQsQ0FkRDs7QUF3QkFaLGVBQWUsQ0FBQ2lCLDRCQUFoQixHQUErQyxlQUFlQSw0QkFBZixDQUE2Q2YsT0FBN0MsRUFBc0Q7QUFDbkdXLGtC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QXNCTixZQUF0QixDQUFoQixDQUFOOztBQUNBMUQsc0JBQUlLLEtBQUosQ0FBVyxzQ0FBcUNrRCxNQUFPLEdBQXZEOztBQUNBLFlBQU1DLG1CQUFJYSxTQUFKLENBQWNkLE1BQWQsRUFBc0I7QUFDMUJPLFFBQUFBLEdBQUcsRUFBRUU7QUFEcUIsT0FBdEIsQ0FBTjtBQUdELEtBWkQsU0FZVTtBQUNSLFlBQU1wQixrQkFBR0UsTUFBSCxDQUFVa0IsT0FBVixDQUFOO0FBQ0Q7QUFDRjs7QUFDRGhFLGtCQUFJSyxLQUFKLENBQVcsNEJBQTJCa0QsTUFBTyxnQkFBN0M7QUFDRCxDQXRDRDs7QUE4Q0FwRSxlQUFlLENBQUNtRixpQ0FBaEIsR0FBb0QsZUFBZUEsaUNBQWYsQ0FBa0RqRixPQUFsRCxFQUEyRDtBQUM3R1csa0JBQUlLLEtBQUosQ0FBVyxnQkFBZWhCLE9BQVEsdURBQWxDOztBQUNBLE1BQUlBLE9BQU8sQ0FBQ0MsUUFBUixDQUFpQkMsdUJBQWpCLENBQUosRUFBc0M7QUFDcENGLElBQUFBLE9BQU8sR0FBRyxNQUFNLEtBQUtHLGNBQUwsQ0FBb0JILE9BQXBCLENBQWhCO0FBQ0Q7O0FBRUQsUUFBTUksU0FBUyxHQUFHLE1BQU1DLHlCQUFVQyxJQUFWLENBQWVOLE9BQWYsQ0FBeEI7QUFDQSxRQUFNTyxRQUFRLEdBQUcsTUFBTUgsU0FBUyxDQUFDSSxZQUFWLEVBQXZCO0FBQ0EsU0FBTyxDQUFDRCxRQUFRLENBQUMyRSxlQUFULElBQTRCLEVBQTdCLEVBQWlDQyxJQUFqQyxDQUFzQyxDQUFDO0FBQUNDLElBQUFBO0FBQUQsR0FBRCxLQUFZQSxJQUFJLEtBQUssNkJBQTNELENBQVA7QUFDRCxDQVREOztlQVdldEYsZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGV4ZWMgfSBmcm9tICd0ZWVuX3Byb2Nlc3MnO1xuaW1wb3J0IGxvZyBmcm9tICcuLi9sb2dnZXIuanMnO1xuaW1wb3J0IHtcbiAgZ2V0QW5kcm9pZFBsYXRmb3JtQW5kUGF0aCwgdW56aXBGaWxlLFxuICBBUEtTX0VYVEVOU0lPTiwgcGFyc2VNYW5pZmVzdCB9IGZyb20gJy4uL2hlbHBlcnMuanMnO1xuaW1wb3J0IHsgZnMsIHppcCwgdGVtcERpciwgdXRpbCB9IGZyb20gJ2FwcGl1bS1zdXBwb3J0JztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBBcGtSZWFkZXIgZnJvbSAnYWRia2l0LWFwa3JlYWRlcic7XG5cbmxldCBtYW5pZmVzdE1ldGhvZHMgPSB7fTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBBUEtJbmZvXG4gKiBAcHJvcGVydHkge3N0cmluZ30gYXBrUGFja2FnZSAtIFRoZSBuYW1lIG9mIGFwcGxpY2F0aW9uIHBhY2thZ2UsIGZvciBleGFtcGxlICdjb20uYWNtZS5hcHAnLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGFwa0FjdGl2aXR5IC0gVGhlIG5hbWUgb2YgbWFpbiBhcHBsaWNhdGlvbiBhY3Rpdml0eS5cbiAqL1xuXG4vKipcbiAqIEV4dHJhY3QgcGFja2FnZSBhbmQgbWFpbiBhY3Rpdml0eSBuYW1lIGZyb20gYXBwbGljYXRpb24gbWFuaWZlc3QuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGFwcFBhdGggLSBUaGUgZnVsbCBwYXRoIHRvIGFwcGxpY2F0aW9uIC5hcGsocykgcGFja2FnZVxuICogQHJldHVybiB7QVBLSW5mb30gVGhlIHBhcnNlZCBhcHBsaWNhdGlvbiBpbmZvLlxuICogQHRocm93cyB7ZXJyb3J9IElmIHRoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSBnZXR0aW5nIHRoZSBkYXRhIGZyb20gdGhlIGdpdmVuXG4gKiAgICAgICAgICAgICAgICAgYXBwbGljYXRpb24gcGFja2FnZS5cbiAqL1xubWFuaWZlc3RNZXRob2RzLnBhY2thZ2VBbmRMYXVuY2hBY3Rpdml0eUZyb21NYW5pZmVzdCA9IGFzeW5jIGZ1bmN0aW9uIHBhY2thZ2VBbmRMYXVuY2hBY3Rpdml0eUZyb21NYW5pZmVzdCAoYXBwUGF0aCkge1xuICBpZiAoYXBwUGF0aC5lbmRzV2l0aChBUEtTX0VYVEVOU0lPTikpIHtcbiAgICBhcHBQYXRoID0gYXdhaXQgdGhpcy5leHRyYWN0QmFzZUFwayhhcHBQYXRoKTtcbiAgfVxuXG4gIGNvbnN0IGFwa1JlYWRlciA9IGF3YWl0IEFwa1JlYWRlci5vcGVuKGFwcFBhdGgpO1xuICBjb25zdCBtYW5pZmVzdCA9IGF3YWl0IGFwa1JlYWRlci5yZWFkTWFuaWZlc3QoKTtcbiAgY29uc3Qge3BrZywgYWN0aXZpdHl9ID0gcGFyc2VNYW5pZmVzdChtYW5pZmVzdCk7XG4gIGxvZy5pbmZvKGBQYWNrYWdlIG5hbWU6ICcke3BrZ30nYCk7XG4gIGxvZy5pbmZvKGBNYWluIGFjdGl2aXR5IG5hbWU6ICcke2FjdGl2aXR5fSdgKTtcbiAgcmV0dXJuIHtcbiAgICBhcGtQYWNrYWdlOiBwa2csXG4gICAgYXBrQWN0aXZpdHk6IGFjdGl2aXR5LFxuICB9O1xufTtcblxuLyoqXG4gKiBFeHRyYWN0IHRhcmdldCBTREsgdmVyc2lvbiBmcm9tIGFwcGxpY2F0aW9uIG1hbmlmZXN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBhcHBQYXRoIC0gVGhlIGZ1bGwgcGF0aCB0byAuYXBrKHMpIHBhY2thZ2UuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSB2ZXJzaW9uIG9mIHRoZSB0YXJnZXQgU0RLLlxuICogQHRocm93cyB7ZXJyb3J9IElmIHRoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSBnZXR0aW5nIHRoZSBkYXRhIGZyb20gdGhlIGdpdmVuXG4gKiAgICAgICAgICAgICAgICAgYXBwbGljYXRpb24gcGFja2FnZS5cbiAqL1xubWFuaWZlc3RNZXRob2RzLnRhcmdldFNka1ZlcnNpb25Gcm9tTWFuaWZlc3QgPSBhc3luYyBmdW5jdGlvbiB0YXJnZXRTZGtWZXJzaW9uRnJvbU1hbmlmZXN0IChhcHBQYXRoKSB7XG4gIGxvZy5kZWJ1ZyhgRXh0cmFjdGluZyB0YXJnZXQgU0RLIHZlcnNpb24gb2YgJyR7YXBwUGF0aH0nYCk7XG4gIGNvbnN0IG9yaWdpbmFsQXBwUGF0aCA9IGFwcFBhdGg7XG4gIGlmIChhcHBQYXRoLmVuZHNXaXRoKEFQS1NfRVhURU5TSU9OKSkge1xuICAgIGFwcFBhdGggPSBhd2FpdCB0aGlzLmV4dHJhY3RCYXNlQXBrKGFwcFBhdGgpO1xuICB9XG5cbiAgY29uc3QgZ2V0VGFyZ2V0U2RrVmlhQXBrUmVhZGVyID0gYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGFwa1JlYWRlciA9IGF3YWl0IEFwa1JlYWRlci5vcGVuKGFwcFBhdGgpO1xuICAgIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgYXBrUmVhZGVyLnJlYWRNYW5pZmVzdCgpO1xuICAgIGlmIChtYW5pZmVzdC51c2VzU2RrICYmIF8uaXNJbnRlZ2VyKG1hbmlmZXN0LnVzZXNTZGsudGFyZ2V0U2RrVmVyc2lvbikpIHtcbiAgICAgIHJldHVybiBtYW5pZmVzdC51c2VzU2RrLnRhcmdldFNka1ZlcnNpb247XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGZpbmQgdGhlIGluZm9ybWF0aW9uIGFib3V0IHRhcmdldFNka1ZlcnNpb24gaW4gdGhlIG1hbmlmZXN0Jyk7XG4gIH07XG4gIGNvbnN0IGdldFRhcmdldFNka1ZpYUFhcHQgPSBhc3luYyAoKSA9PiB7XG4gICAgYXdhaXQgdGhpcy5pbml0QWFwdCgpO1xuICAgIGNvbnN0IGFyZ3MgPSBbJ2R1bXAnLCAnYmFkZ2luZycsIGFwcFBhdGhdO1xuICAgIGNvbnN0IHtzdGRvdXR9ID0gYXdhaXQgZXhlYyh0aGlzLmJpbmFyaWVzLmFhcHQsIGFyZ3MpO1xuICAgIGNvbnN0IHRhcmdldFNka1ZlcnNpb24gPSAvdGFyZ2V0U2RrVmVyc2lvbjonKFteJ10rKScvZy5leGVjKHN0ZG91dCk7XG4gICAgaWYgKCF0YXJnZXRTZGtWZXJzaW9uKSB7XG4gICAgICBsb2cuZGVidWcoc3Rkb3V0KTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHBhcnNlIHRoZSBjb21tYW5kIG91dHB1dCcpO1xuICAgIH1cbiAgICByZXR1cm4gcGFyc2VJbnQodGFyZ2V0U2RrVmVyc2lvblsxXSwgMTApO1xuICB9O1xuICBjb25zdCB2ZXJzaW9uR2V0dGVycyA9IFtcbiAgICBbJ0Fwa1JlYWRlcicsIGdldFRhcmdldFNka1ZpYUFwa1JlYWRlcl0sXG4gICAgWydhYXB0JywgZ2V0VGFyZ2V0U2RrVmlhQWFwdF0sXG4gIF07XG4gIGZvciAoY29uc3QgW3Rvb2xOYW1lLCB2ZXJzaW9uR2V0dGVyXSBvZiB2ZXJzaW9uR2V0dGVycykge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgdmVyc2lvbkdldHRlcigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvZy5pbmZvKGBDYW5ub3QgZXh0cmFjdCB0YXJnZXRTZGtWZXJzaW9uIG9mICcke29yaWdpbmFsQXBwUGF0aH0nIHVzaW5nICR7dG9vbE5hbWV9LiBgICtcbiAgICAgICAgYE9yaWdpbmFsIGVycm9yOiAke2UubWVzc2FnZX1gKTtcbiAgICB9XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZXh0cmFjdCB0aGUgdGFyZ2V0IFNESyB2ZXJzaW9uIG51bWJlciBvZiAnJHtvcmlnaW5hbEFwcFBhdGh9JyB1c2luZyBlaXRoZXIgb2YgYCArXG4gICAgYCR7SlNPTi5zdHJpbmdpZnkodmVyc2lvbkdldHRlcnMubWFwKChwYWlyKSA9PiBwYWlyWzBdKSl9IHRvb2xzLiBgICtcbiAgICBgQ2hlY2sgdGhlIHNlcnZlciBsb2cgZm9yIG1vcmUgZGV0YWlsc2ApO1xufTtcblxuLyoqXG4gKiBFeHRyYWN0IHRhcmdldCBTREsgdmVyc2lvbiBmcm9tIHBhY2thZ2UgaW5mb3JtYXRpb24uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBrZyAtIFRoZSBjbGFzcyBuYW1lIG9mIHRoZSBwYWNrYWdlIGluc3RhbGxlZCBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKiBAcGFyYW0gez9zdHJpbmd9IGNtZE91dHB1dCAtIE9wdGlvbmFsIHBhcmFtZXRlciBjb250YWluaW5nIHRoZSBvdXRwdXQgb2ZcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2R1bXBzeXMgcGFja2FnZV8gY29tbWFuZC4gSXQgbWF5IHNwZWVkIHVwIHRoZSBtZXRob2QgZXhlY3V0aW9uLlxuICogQHJldHVybiB7bnVtYmVyfSBUaGUgdmVyc2lvbiBvZiB0aGUgdGFyZ2V0IFNESy5cbiAqL1xubWFuaWZlc3RNZXRob2RzLnRhcmdldFNka1ZlcnNpb25Vc2luZ1BLRyA9IGFzeW5jIGZ1bmN0aW9uIHRhcmdldFNka1ZlcnNpb25Vc2luZ1BLRyAocGtnLCBjbWRPdXRwdXQgPSBudWxsKSB7XG4gIGxldCBzdGRvdXQgPSBjbWRPdXRwdXQgfHwgYXdhaXQgdGhpcy5zaGVsbChbJ2R1bXBzeXMnLCAncGFja2FnZScsIHBrZ10pO1xuICBsZXQgdGFyZ2V0U2RrVmVyc2lvbiA9IG5ldyBSZWdFeHAoL3RhcmdldFNkaz0oW15cXHNcXHNdKykvZykuZXhlYyhzdGRvdXQpO1xuICBpZiAodGFyZ2V0U2RrVmVyc2lvbiAmJiB0YXJnZXRTZGtWZXJzaW9uLmxlbmd0aCA+PSAyKSB7XG4gICAgdGFyZ2V0U2RrVmVyc2lvbiA9IHRhcmdldFNka1ZlcnNpb25bMV07XG4gIH0gZWxzZSB7XG4gICAgLy8gdGFyZ2V0U2RrIG5vdCBmb3VuZCBpbiB0aGUgZHVtcCwgYXNzaWduaW5nIDAgdG8gdGFyZ2V0U2RrVmVyc2lvblxuICAgIHRhcmdldFNka1ZlcnNpb24gPSAwO1xuICB9XG4gIHJldHVybiBwYXJzZUludCh0YXJnZXRTZGtWZXJzaW9uLCAxMCk7XG59O1xuXG4vKipcbiAqIENyZWF0ZSBiaW5hcnkgcmVwcmVzZW50YXRpb24gb2YgcGFja2FnZSBtYW5pZmVzdCAodXN1YWxseSBBbmRyb2lkTWFuaWZlc3QueG1sKS5cbiAqIGAke21hbmlmZXN0fS5hcGtgIGZpbGUgd2lsbCBiZSBjcmVhdGVkIGFzIHRoZSByZXN1bHQgb2YgdGhpcyBtZXRob2RcbiAqIGNvbnRhaW5pbmcgdGhlIGNvbXBpbGVkIG1hbmlmZXN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtYW5pZmVzdCAtIEZ1bGwgcGF0aCB0byB0aGUgaW5pdGlhbCBtYW5pZmVzdCB0ZW1wbGF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IG1hbmlmZXN0UGFja2FnZSAtIFRoZSBuYW1lIG9mIHRoZSBtYW5pZmVzdCBwYWNrYWdlXG4gKiBAcGFyYW0ge3N0cmluZ30gdGFyZ2V0UGFja2FnZSAtIFRoZSBuYW1lIG9mIHRoZSBkZXN0aW5hdGlvbiBwYWNrYWdlXG4gKi9cbm1hbmlmZXN0TWV0aG9kcy5jb21waWxlTWFuaWZlc3QgPSBhc3luYyBmdW5jdGlvbiBjb21waWxlTWFuaWZlc3QgKG1hbmlmZXN0LCBtYW5pZmVzdFBhY2thZ2UsIHRhcmdldFBhY2thZ2UpIHtcbiAgY29uc3Qge3BsYXRmb3JtLCBwbGF0Zm9ybVBhdGh9ID0gYXdhaXQgZ2V0QW5kcm9pZFBsYXRmb3JtQW5kUGF0aCgpO1xuICBpZiAoIXBsYXRmb3JtKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgY29tcGlsZSB0aGUgbWFuaWZlc3QuIFRoZSByZXF1aXJlZCBwbGF0Zm9ybSBkb2VzIG5vdCBleGlzdCAoQVBJIGxldmVsID49IDE3KScpO1xuICB9XG4gIGNvbnN0IHJlc3VsdFBhdGggPSBgJHttYW5pZmVzdH0uYXBrYDtcbiAgY29uc3QgYW5kcm9pZEphclBhdGggPSBwYXRoLnJlc29sdmUocGxhdGZvcm1QYXRoLCAnYW5kcm9pZC5qYXInKTtcbiAgaWYgKGF3YWl0IGZzLmV4aXN0cyhyZXN1bHRQYXRoKSkge1xuICAgIGF3YWl0IGZzLnJpbXJhZihyZXN1bHRQYXRoKTtcbiAgfVxuICB0cnkge1xuICAgIGF3YWl0IHRoaXMuaW5pdEFhcHQyKCk7XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIuYW5kcm9pZC5jb20vc3R1ZGlvL2NvbW1hbmQtbGluZS9hYXB0MlxuICAgIGNvbnN0IGFyZ3MgPSBbXG4gICAgICAnbGluaycsXG4gICAgICAnLW8nLCByZXN1bHRQYXRoLFxuICAgICAgJy0tbWFuaWZlc3QnLCBtYW5pZmVzdCxcbiAgICAgICctLXJlbmFtZS1tYW5pZmVzdC1wYWNrYWdlJywgbWFuaWZlc3RQYWNrYWdlLFxuICAgICAgJy0tcmVuYW1lLWluc3RydW1lbnRhdGlvbi10YXJnZXQtcGFja2FnZScsIHRhcmdldFBhY2thZ2UsXG4gICAgICAnLUknLCBhbmRyb2lkSmFyUGF0aCxcbiAgICAgICctdicsXG4gICAgXTtcbiAgICBsb2cuZGVidWcoYENvbXBpbGluZyB0aGUgbWFuaWZlc3QgdXNpbmcgJyR7dXRpbC5xdW90ZShbdGhpcy5iaW5hcmllcy5hYXB0MiwgLi4uYXJnc10pfSdgKTtcbiAgICBhd2FpdCBleGVjKHRoaXMuYmluYXJpZXMuYWFwdDIsIGFyZ3MpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nLmRlYnVnKCdDYW5ub3QgY29tcGlsZSB0aGUgbWFuaWZlc3QgdXNpbmcgYWFwdDIuIERlZmF1bHRpbmcgdG8gYWFwdC4gJyArXG4gICAgICBgT3JpZ2luYWwgZXJyb3I6ICR7ZS5zdGRlcnIgfHwgZS5tZXNzYWdlfWApO1xuICAgIGF3YWl0IHRoaXMuaW5pdEFhcHQoKTtcbiAgICBjb25zdCBhcmdzID0gW1xuICAgICAgJ3BhY2thZ2UnLFxuICAgICAgJy1NJywgbWFuaWZlc3QsXG4gICAgICAnLS1yZW5hbWUtbWFuaWZlc3QtcGFja2FnZScsIG1hbmlmZXN0UGFja2FnZSxcbiAgICAgICctLXJlbmFtZS1pbnN0cnVtZW50YXRpb24tdGFyZ2V0LXBhY2thZ2UnLCB0YXJnZXRQYWNrYWdlLFxuICAgICAgJy1JJywgYW5kcm9pZEphclBhdGgsXG4gICAgICAnLUYnLCByZXN1bHRQYXRoLFxuICAgICAgJy1mJyxcbiAgICBdO1xuICAgIGxvZy5kZWJ1ZyhgQ29tcGlsaW5nIHRoZSBtYW5pZmVzdCB1c2luZyAnJHt1dGlsLnF1b3RlKFt0aGlzLmJpbmFyaWVzLmFhcHQsIC4uLmFyZ3NdKX0nYCk7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGV4ZWModGhpcy5iaW5hcmllcy5hYXB0LCBhcmdzKTtcbiAgICB9IGNhdGNoIChlMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY29tcGlsZSB0aGUgbWFuaWZlc3QuIE9yaWdpbmFsIGVycm9yOiAke2UxLnN0ZGVyciB8fCBlMS5tZXNzYWdlfWApO1xuICAgIH1cbiAgfVxuICBsb2cuZGVidWcoYENvbXBpbGVkIHRoZSBtYW5pZmVzdCBhdCAnJHtyZXN1bHRQYXRofSdgKTtcbn07XG5cbi8qKlxuICogUmVwbGFjZS9pbnNlcnQgdGhlIHNwZWNpYWxseSBwcmVjb21waWxlZCBtYW5pZmVzdCBmaWxlIGludG8gdGhlXG4gKiBwYXJ0aWN1bGFyIHBhY2thZ2UuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG1hbmlmZXN0IC0gRnVsbCBwYXRoIHRvIHRoZSBwcmVjb21waWxlZCBtYW5pZmVzdFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlZCBieSBgY29tcGlsZU1hbmlmZXN0YCBtZXRob2QgY2FsbFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aG91dCAuYXBrIGV4dGVuc2lvblxuICogQHBhcmFtIHtzdHJpbmd9IHNyY0FwayAtIEZ1bGwgcGF0aCB0byB0aGUgZXhpc3RpbmcgdmFsaWQgYXBwbGljYXRpb24gcGFja2FnZSwgd2hlcmVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIG1hbmlmZXN0IGhhcyB0byBiZSBpbnNldHJlZCB0by4gVGhpcyBwYWNrYWdlXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsbCBOT1QgYmUgbW9kaWZpZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZHN0QXBrIC0gRnVsbCBwYXRoIHRvIHRoZSByZXN1bHRpbmcgcGFja2FnZS5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICBUaGUgZmlsZSB3aWxsIGJlIG92ZXJyaWRkZW4gaWYgaXQgYWxyZWFkeSBleGlzdHMuXG4gKi9cbm1hbmlmZXN0TWV0aG9kcy5pbnNlcnRNYW5pZmVzdCA9IGFzeW5jIGZ1bmN0aW9uIGluc2VydE1hbmlmZXN0IChtYW5pZmVzdCwgc3JjQXBrLCBkc3RBcGspIHtcbiAgbG9nLmRlYnVnKGBJbnNlcnRpbmcgbWFuaWZlc3QgJyR7bWFuaWZlc3R9Jywgc3JjOiAnJHtzcmNBcGt9JywgZHN0OiAnJHtkc3RBcGt9J2ApO1xuICBhd2FpdCB6aXAuYXNzZXJ0VmFsaWRaaXAoc3JjQXBrKTtcbiAgYXdhaXQgdW56aXBGaWxlKGAke21hbmlmZXN0fS5hcGtgKTtcbiAgY29uc3QgbWFuaWZlc3ROYW1lID0gcGF0aC5iYXNlbmFtZShtYW5pZmVzdCk7XG4gIHRyeSB7XG4gICAgYXdhaXQgdGhpcy5pbml0QWFwdCgpO1xuICAgIGF3YWl0IGZzLmNvcHlGaWxlKHNyY0FwaywgZHN0QXBrKTtcbiAgICBsb2cuZGVidWcoJ01vdmluZyBtYW5pZmVzdCcpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBleGVjKHRoaXMuYmluYXJpZXMuYWFwdCwgW1xuICAgICAgICAncmVtb3ZlJywgZHN0QXBrLCBtYW5pZmVzdE5hbWVcbiAgICAgIF0pO1xuICAgIH0gY2F0Y2ggKGlnbikge31cbiAgICBhd2FpdCBleGVjKHRoaXMuYmluYXJpZXMuYWFwdCwgW1xuICAgICAgJ2FkZCcsIGRzdEFwaywgbWFuaWZlc3ROYW1lXG4gICAgXSwge2N3ZDogcGF0aC5kaXJuYW1lKG1hbmlmZXN0KX0pO1xuICB9IGNhdGNoIChlKSB7XG4gICAgbG9nLmRlYnVnKCdDYW5ub3QgaW5zZXJ0IG1hbmlmZXN0IHVzaW5nIGFhcHQuIERlZmF1bHRpbmcgdG8gemlwLiAnICtcbiAgICAgIGBPcmlnaW5hbCBlcnJvcjogJHtlLnN0ZGVyciB8fCBlLm1lc3NhZ2V9YCk7XG4gICAgY29uc3QgdG1wUm9vdCA9IGF3YWl0IHRlbXBEaXIub3BlbkRpcigpO1xuICAgIHRyeSB7XG4gICAgICAvLyBVbmZvcnR1bmF0ZWx5IE5vZGVKUyBkb2VzIG5vdCBwcm92aWRlIGFueSByZWxpYWJsZSBtZXRob2RzXG4gICAgICAvLyB0byByZXBsYWNlIGZpbGVzIGluc2lkZSB6aXAgYXJjaGl2ZXMgd2l0aG91dCBsb2FkaW5nIHRoZVxuICAgICAgLy8gd2hvbGUgYXJjaGl2ZSBjb250ZW50IGludG8gUkFNXG4gICAgICBsb2cuZGVidWcoYEV4dHJhY3RpbmcgdGhlIHNvdXJjZSBhcGsgYXQgJyR7c3JjQXBrfSdgKTtcbiAgICAgIGF3YWl0IHppcC5leHRyYWN0QWxsVG8oc3JjQXBrLCB0bXBSb290KTtcbiAgICAgIGxvZy5kZWJ1ZygnTW92aW5nIG1hbmlmZXN0Jyk7XG4gICAgICBhd2FpdCBmcy5tdihtYW5pZmVzdCwgcGF0aC5yZXNvbHZlKHRtcFJvb3QsIG1hbmlmZXN0TmFtZSkpO1xuICAgICAgbG9nLmRlYnVnKGBDb2xsZWN0aW5nIHRoZSBkZXN0aW5hdGlvbiBhcGsgYXQgJyR7ZHN0QXBrfSdgKTtcbiAgICAgIGF3YWl0IHppcC50b0FyY2hpdmUoZHN0QXBrLCB7XG4gICAgICAgIGN3ZDogdG1wUm9vdCxcbiAgICAgIH0pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBmcy5yaW1yYWYodG1wUm9vdCk7XG4gICAgfVxuICB9XG4gIGxvZy5kZWJ1ZyhgTWFuaWZlc3QgaW5zZXJ0aW9uIGludG8gJyR7ZHN0QXBrfScgaXMgY29tcGxldGVkYCk7XG59O1xuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgcGFja2FnZSBtYW5pZmVzdCBjb250YWlucyBJbnRlcm5ldCBwZXJtaXNzaW9ucy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gYXBwUGF0aCAtIFRoZSBmdWxsIHBhdGggdG8gLmFwayhzKSBwYWNrYWdlLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWFuaWZlc3QgcmVxdWlyZXMgSW50ZXJuZXQgYWNjZXNzIHBlcm1pc3Npb24uXG4gKi9cbm1hbmlmZXN0TWV0aG9kcy5oYXNJbnRlcm5ldFBlcm1pc3Npb25Gcm9tTWFuaWZlc3QgPSBhc3luYyBmdW5jdGlvbiBoYXNJbnRlcm5ldFBlcm1pc3Npb25Gcm9tTWFuaWZlc3QgKGFwcFBhdGgpIHtcbiAgbG9nLmRlYnVnKGBDaGVja2luZyBpZiAnJHthcHBQYXRofScgcmVxdWlyZXMgaW50ZXJuZXQgYWNjZXNzIHBlcm1pc3Npb24gaW4gdGhlIG1hbmlmZXN0YCk7XG4gIGlmIChhcHBQYXRoLmVuZHNXaXRoKEFQS1NfRVhURU5TSU9OKSkge1xuICAgIGFwcFBhdGggPSBhd2FpdCB0aGlzLmV4dHJhY3RCYXNlQXBrKGFwcFBhdGgpO1xuICB9XG5cbiAgY29uc3QgYXBrUmVhZGVyID0gYXdhaXQgQXBrUmVhZGVyLm9wZW4oYXBwUGF0aCk7XG4gIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgYXBrUmVhZGVyLnJlYWRNYW5pZmVzdCgpO1xuICByZXR1cm4gKG1hbmlmZXN0LnVzZXNQZXJtaXNzaW9ucyB8fCBbXSkuc29tZSgoe25hbWV9KSA9PiBuYW1lID09PSAnYW5kcm9pZC5wZXJtaXNzaW9uLklOVEVSTkVUJyk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBtYW5pZmVzdE1ldGhvZHM7XG4iXSwiZmlsZSI6ImxpYi90b29scy9hbmRyb2lkLW1hbmlmZXN0LmpzIiwic291cmNlUm9vdCI6Ii4uLy4uLy4uIn0=