appium-adb 8.17.0 → 8.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,6 +21,10 @@ var _asyncbox = require("asyncbox");
21
21
 
22
22
  var _utf = require("utf7");
23
23
 
24
+ var _teen_process = require("teen_process");
25
+
26
+ var _bluebird = _interopRequireDefault(require("bluebird"));
27
+
24
28
  const SETTINGS_HELPER_ID = 'io.appium.settings';
25
29
  const SETTINGS_HELPER_MAIN_ACTIVITY = '.Settings';
26
30
  const WIFI_CONNECTION_SETTING_RECEIVER = `${SETTINGS_HELPER_ID}/.receivers.WiFiConnectionSettingReceiver`;
@@ -45,6 +49,9 @@ const APPIUM_IME = `${SETTINGS_HELPER_ID}/.AppiumIME`;
45
49
  const UNICODE_IME = `${SETTINGS_HELPER_ID}/.UnicodeIME`;
46
50
  const DEFAULT_SATELLITES_COUNT = 12;
47
51
  const DEFAULT_ALTITUDE = 0.0;
52
+ const LOCATION_TRACKER_TAG = 'LocationTracker';
53
+ const GPS_CACHE_REFRESHED_LOGS = ['The current location has been successfully retrieved from Play Services', 'The current location has been successfully retrieved from Location Manager'];
54
+ const GPS_COORDINATES_PATTERN = /data="(-?[\d.]+)\s+(-?[\d.]+)\s+(-?[\d.]+)"/;
48
55
  const commands = {};
49
56
 
50
57
  commands.requireRunningSettingsApp = async function requireRunningSettingsApp(opts = {}) {
@@ -193,10 +200,10 @@ commands.getGeoLocation = async function getGeoLocation() {
193
200
  try {
194
201
  output = await this.shell(['am', 'broadcast', '-n', LOCATION_RECEIVER, '-a', LOCATION_RETRIEVAL_ACTION]);
195
202
  } catch (err) {
196
- throw new Error(`Cannot retrieve the current geo coordinates from the device. ` + `Make sure the Appium Settings application is up to date and has location permissions. Also the location ` + `services must be enabled on the device. Original error: ${err.message}`);
203
+ throw new Error(`Cannot retrieve the current geo coordinates from the device. ` + `Make sure the Appium Settings application is up to date and has location permissions. Also the location ` + `services must be enabled on the device. Original error: ${err.stderr || err.stdout || err.message}`);
197
204
  }
198
205
 
199
- const match = /data="(-?[\d.]+)\s+(-?[\d.]+)\s+(-?[\d.]+)"/.exec(output);
206
+ const match = GPS_COORDINATES_PATTERN.exec(output);
200
207
 
201
208
  if (!match) {
202
209
  throw new Error(`Cannot parse the actual location values from the command output: ${output}`);
@@ -213,6 +220,51 @@ commands.getGeoLocation = async function getGeoLocation() {
213
220
  return location;
214
221
  };
215
222
 
223
+ commands.refreshGeoLocationCache = async function refreshGeoLocationCache(timeoutMs = 20000) {
224
+ let logcatMonitor;
225
+ let monitoringPromise;
226
+
227
+ if (timeoutMs > 0) {
228
+ const cmd = [...this.adb.defaultArgs, 'logcat', '-s', LOCATION_TRACKER_TAG];
229
+ logcatMonitor = new _teen_process.SubProcess(this.adb.path, cmd);
230
+ const timeoutErrorMsg = `The GPS cache has not been refreshed within ${timeoutMs}ms timeout. ` + `Please make sure the device under test has Appium Settings app installed and running. ` + `Also, it is required that the device has Google Play Services installed or is running ` + `Android 10+ otherwise.`;
231
+ monitoringPromise = new _bluebird.default((resolve, reject) => {
232
+ setTimeout(() => reject(new Error(timeoutErrorMsg)), timeoutMs);
233
+ logcatMonitor.on('exit', () => reject(new Error(timeoutErrorMsg)));
234
+ ['lines-stderr', 'lines-stdout'].map(evt => logcatMonitor.on(evt, lines => {
235
+ if (lines.some(line => GPS_CACHE_REFRESHED_LOGS.some(x => line.includes(x)))) {
236
+ resolve();
237
+ }
238
+ }));
239
+ });
240
+ await logcatMonitor.start(0);
241
+ }
242
+
243
+ try {
244
+ await this.shell(['am', 'broadcast', '-n', LOCATION_RECEIVER, '-a', LOCATION_RETRIEVAL_ACTION, '--ez', 'forceUpdate', 'true']);
245
+ } catch (err) {
246
+ throw new Error(`Cannot refresh the GPS cache on the device. ` + `Make sure the Appium Settings application is up to date and has location permissions. Also the location ` + `services must be enabled on the device. Original error: ${err.stderr || err.stdout || err.message}`);
247
+ }
248
+
249
+ if (logcatMonitor && monitoringPromise) {
250
+ const timer = new _appiumSupport.timing.Timer().start();
251
+
252
+ _logger.default.debug(`Waiting up to ${timeoutMs}ms for the GPS cache to be refreshed`);
253
+
254
+ try {
255
+ await monitoringPromise;
256
+
257
+ _logger.default.info(`The GPS cache has been successfully refreshed after ` + `${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
258
+ } finally {
259
+ if (logcatMonitor.isRunning) {
260
+ await logcatMonitor.stop();
261
+ }
262
+ }
263
+ } else {
264
+ _logger.default.info('The request to refresh the GPS cache has been sent. Skipping waiting for its result.');
265
+ }
266
+ };
267
+
216
268
  commands.performEditorAction = async function performEditorAction(action) {
217
269
  _logger.default.debug(`Performing editor action: ${action}`);
218
270
 
@@ -307,4 +359,4 @@ var _default = commands;
307
359
  exports.default = _default;require('source-map-support').install();
308
360
 
309
361
 
310
- //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi90b29scy9zZXR0aW5ncy1jbGllbnQtY29tbWFuZHMuanMiXSwibmFtZXMiOlsiU0VUVElOR1NfSEVMUEVSX0lEIiwiU0VUVElOR1NfSEVMUEVSX01BSU5fQUNUSVZJVFkiLCJXSUZJX0NPTk5FQ1RJT05fU0VUVElOR19SRUNFSVZFUiIsIldJRklfQ09OTkVDVElPTl9TRVRUSU5HX0FDVElPTiIsIkRBVEFfQ09OTkVDVElPTl9TRVRUSU5HX1JFQ0VJVkVSIiwiREFUQV9DT05ORUNUSU9OX1NFVFRJTkdfQUNUSU9OIiwiQU5JTUFUSU9OX1NFVFRJTkdfUkVDRUlWRVIiLCJBTklNQVRJT05fU0VUVElOR19BQ1RJT04iLCJMT0NBTEVfU0VUVElOR19SRUNFSVZFUiIsIkxPQ0FMRV9TRVRUSU5HX0FDVElPTiIsIkxPQ0FUSU9OX1NFUlZJQ0UiLCJMT0NBVElPTl9SRUNFSVZFUiIsIkxPQ0FUSU9OX1JFVFJJRVZBTF9BQ1RJT04iLCJDTElQQk9BUkRfUkVDRUlWRVIiLCJDTElQQk9BUkRfUkVUUklFVkFMX0FDVElPTiIsIk5PVElGSUNBVElPTlNfUkVUUklFVkFMX0FDVElPTiIsIlNNU19MSVNUX1JFQ0VJVkVSIiwiU01TX0xJU1RfUkVUUklFVkFMX0FDVElPTiIsIk1FRElBX1NDQU5fUkVDRUlWRVIiLCJNRURJQV9TQ0FOX0FDVElPTiIsIkFQUElVTV9JTUUiLCJVTklDT0RFX0lNRSIsIkRFRkFVTFRfU0FURUxMSVRFU19DT1VOVCIsIkRFRkFVTFRfQUxUSVRVREUiLCJjb21tYW5kcyIsInJlcXVpcmVSdW5uaW5nU2V0dGluZ3NBcHAiLCJvcHRzIiwicHJvY2Vzc0V4aXN0cyIsImxvZyIsImRlYnVnIiwidGltZW91dCIsInN0YXJ0QXBwIiwicGtnIiwiYWN0aXZpdHkiLCJhY3Rpb24iLCJjYXRlZ29yeSIsInN0b3BBcHAiLCJ3YWl0Rm9yTGF1bmNoIiwid2FpdE1zIiwiaW50ZXJ2YWxNcyIsImVyciIsIkVycm9yIiwic2V0V2lmaVN0YXRlIiwib24iLCJpc0VtdWxhdG9yIiwic2hlbGwiLCJwcml2aWxlZ2VkIiwiZ2V0QXBpTGV2ZWwiLCJzZXREYXRhU3RhdGUiLCJzZXRBbmltYXRpb25TdGF0ZSIsInNldERldmljZVN5c0xvY2FsZVZpYVNldHRpbmdBcHAiLCJsYW5ndWFnZSIsImNvdW50cnkiLCJzY3JpcHQiLCJwYXJhbXMiLCJ0b0xvd2VyQ2FzZSIsInRvVXBwZXJDYXNlIiwicHVzaCIsInNldEdlb0xvY2F0aW9uIiwibG9jYXRpb24iLCJmb3JtYXRMb2NhdGlvblZhbHVlIiwidmFsdWVOYW1lIiwiaXNSZXF1aXJlZCIsInV0aWwiLCJoYXNWYWx1ZSIsImZsb2F0VmFsdWUiLCJwYXJzZUZsb2F0IiwiaXNOYU4iLCJfIiwiY2VpbCIsImxvbmdpdHVkZSIsImxhdGl0dWRlIiwiYWx0aXR1ZGUiLCJzcGVlZCIsImFyZ3MiLCJpc05pbCIsInNhdGVsbGl0ZXMiLCJwYXJzZUludCIsIk51bWJlciIsImxlbmd0aCIsInJlc2V0VGVsbmV0QXV0aFRva2VuIiwiYWRiRXhlYyIsIm1hcCIsImFyZyIsInJlcGxhY2UiLCJnZXRHZW9Mb2NhdGlvbiIsIm91dHB1dCIsIm1lc3NhZ2UiLCJtYXRjaCIsImV4ZWMiLCJKU09OIiwic3RyaW5naWZ5IiwicGVyZm9ybUVkaXRvckFjdGlvbiIsInJ1bkluSW1lQ29udGV4dCIsImdldENsaXBib2FyZCIsInJldHJpZXZlQ2xpcGJvYXJkIiwidHJpbSIsImdldE5vdGlmaWNhdGlvbnMiLCJnZXRTbXNMaXN0IiwibWF4IiwidHlwZVVuaWNvZGUiLCJ0ZXh0IiwicGx1cmFsaXplIiwiaW5wdXRUZXh0IiwiaW1hcCIsImVuY29kZSIsInNjYW5NZWRpYSIsImRlc3RpbmF0aW9uIiwiaW5jbHVkZXMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUEsTUFBTUEsa0JBQWtCLEdBQUcsb0JBQTNCO0FBQ0EsTUFBTUMsNkJBQTZCLEdBQUcsV0FBdEM7QUFDQSxNQUFNQyxn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QixNQUFYLEVBQW1CLFdBQW5CLENBQUwsRUFBc0M7QUFDcEMsVUFBTSxJQUFJN0MsS0FBSixDQUFXLGlDQUFnQ2tFLFdBQVksS0FBN0MsR0FDYixrREFERyxDQUFOO0FBRUQ7QUFDRixDQVpEOztlQWNlbkYsUSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBsb2cgZnJvbSAnLi4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IHBhcnNlSnNvbkRhdGEgfSBmcm9tICcuLi9oZWxwZXJzLmpzJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyB1dGlsIH0gZnJvbSAnYXBwaXVtLXN1cHBvcnQnO1xuaW1wb3J0IHsgd2FpdEZvckNvbmRpdGlvbiB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7IGltYXAgfSBmcm9tICd1dGY3JztcblxuY29uc3QgU0VUVElOR1NfSEVMUEVSX0lEID0gJ2lvLmFwcGl1bS5zZXR0aW5ncyc7XG5jb25zdCBTRVRUSU5HU19IRUxQRVJfTUFJTl9BQ1RJVklUWSA9ICcuU2V0dGluZ3MnO1xuY29uc3QgV0lGSV9DT05ORUNUSU9OX1NFVFRJTkdfUkVDRUlWRVIgPSBgJHtTRVRUSU5HU19IRUxQRVJfSUR9Ly5yZWNlaXZlcnMuV2lGaUNvbm5lY3Rpb25TZXR0aW5nUmVjZWl2ZXJgO1xuY29uc3QgV0lGSV9DT05ORUNUSU9OX1NFVFRJTkdfQUNUSU9OID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS53aWZpYDtcbmNvbnN0IERBVEFfQ09OTkVDVElPTl9TRVRUSU5HX1JFQ0VJVkVSID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS8ucmVjZWl2ZXJzLkRhdGFDb25uZWN0aW9uU2V0dGluZ1JlY2VpdmVyYDtcbmNvbnN0IERBVEFfQ09OTkVDVElPTl9TRVRUSU5HX0FDVElPTiA9IGAke1NFVFRJTkdTX0hFTFBFUl9JRH0uZGF0YV9jb25uZWN0aW9uYDtcbmNvbnN0IEFOSU1BVElPTl9TRVRUSU5HX1JFQ0VJVkVSID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS8ucmVjZWl2ZXJzLkFuaW1hdGlvblNldHRpbmdSZWNlaXZlcmA7XG5jb25zdCBBTklNQVRJT05fU0VUVElOR19BQ1RJT04gPSBgJHtTRVRUSU5HU19IRUxQRVJfSUR9LmFuaW1hdGlvbmA7XG5jb25zdCBMT0NBTEVfU0VUVElOR19SRUNFSVZFUiA9IGAke1NFVFRJTkdTX0hFTFBFUl9JRH0vLnJlY2VpdmVycy5Mb2NhbGVTZXR0aW5nUmVjZWl2ZXJgO1xuY29uc3QgTE9DQUxFX1NFVFRJTkdfQUNUSU9OID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS5sb2NhbGVgO1xuY29uc3QgTE9DQVRJT05fU0VSVklDRSA9IGAke1NFVFRJTkdTX0hFTFBFUl9JRH0vLkxvY2F0aW9uU2VydmljZWA7XG5jb25zdCBMT0NBVElPTl9SRUNFSVZFUiA9IGAke1NFVFRJTkdTX0hFTFBFUl9JRH0vLnJlY2VpdmVycy5Mb2NhdGlvbkluZm9SZWNlaXZlcmA7XG5jb25zdCBMT0NBVElPTl9SRVRSSUVWQUxfQUNUSU9OID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS5sb2NhdGlvbmA7XG5jb25zdCBDTElQQk9BUkRfUkVDRUlWRVIgPSBgJHtTRVRUSU5HU19IRUxQRVJfSUR9Ly5yZWNlaXZlcnMuQ2xpcGJvYXJkUmVjZWl2ZXJgO1xuY29uc3QgQ0xJUEJPQVJEX1JFVFJJRVZBTF9BQ1RJT04gPSBgJHtTRVRUSU5HU19IRUxQRVJfSUR9LmNsaXBib2FyZC5nZXRgO1xuY29uc3QgTk9USUZJQ0FUSU9OU19SRVRSSUVWQUxfQUNUSU9OID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS5ub3RpZmljYXRpb25zYDtcbmNvbnN0IFNNU19MSVNUX1JFQ0VJVkVSID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS8ucmVjZWl2ZXJzLlNtc1JlYWRlcmA7XG5jb25zdCBTTVNfTElTVF9SRVRSSUVWQUxfQUNUSU9OID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS5zbXMucmVhZGA7XG5jb25zdCBNRURJQV9TQ0FOX1JFQ0VJVkVSID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS8ucmVjZWl2ZXJzLk1lZGlhU2Nhbm5lclJlY2VpdmVyYDtcbmNvbnN0IE1FRElBX1NDQU5fQUNUSU9OID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS5zY2FuX21lZGlhYDtcbmNvbnN0IEFQUElVTV9JTUUgPSBgJHtTRVRUSU5HU19IRUxQRVJfSUR9Ly5BcHBpdW1JTUVgO1xuY29uc3QgVU5JQ09ERV9JTUUgPSBgJHtTRVRUSU5HU19IRUxQRVJfSUR9Ly5Vbmljb2RlSU1FYDtcbmNvbnN0IERFRkFVTFRfU0FURUxMSVRFU19DT1VOVCA9IDEyO1xuY29uc3QgREVGQVVMVF9BTFRJVFVERSA9IDAuMDtcblxuXG5jb25zdCBjb21tYW5kcyA9IHt9O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFNldHRpbmdzQXBwU3RhcnR1cE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB0aW1lb3V0IFs1MDAwXSBUaGUgbWF4aW11bSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzXG4gKiB0byB3YWl0IHVudGlsIHRoZSBhcHAgaGFzIHN0YXJ0ZWRcbiAqL1xuXG4vKipcbiAqIEVuc3VyZXMgdGhhdCBBcHBpdW0gU2V0dGluZ3MgaGVscGVyIGFwcGxpY2F0aW9uIGlzIHJ1bm5pbmdcbiAqIGFuZCBzdGFydHMgaXQgaWYgbmVjZXNzYXJ5XG4gKlxuICogQHBhcmFtIHtTZXR0aW5nc0FwcFN0YXJ0dXBPcHRpb25zfSBvcHRzXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgQXBwaXVtIFNldHRpbmdzIGhhcyBmYWlsZWQgdG8gc3RhcnRcbiAqIEByZXR1cm5zIHtBREJ9IHNlbGYgaW5zdGFuY2UgZm9yIGNoYWluaW5nXG4gKi9cbmNvbW1hbmRzLnJlcXVpcmVSdW5uaW5nU2V0dGluZ3NBcHAgPSBhc3luYyBmdW5jdGlvbiByZXF1aXJlUnVubmluZ1NldHRpbmdzQXBwIChvcHRzID0ge30pIHtcbiAgaWYgKGF3YWl0IHRoaXMucHJvY2Vzc0V4aXN0cyhTRVRUSU5HU19IRUxQRVJfSUQpKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBsb2cuZGVidWcoJ1N0YXJ0aW5nIEFwcGl1bSBTZXR0aW5ncyBhcHAnKTtcbiAgY29uc3Qge1xuICAgIHRpbWVvdXQgPSA1MDAwLFxuICB9ID0gb3B0cztcbiAgYXdhaXQgdGhpcy5zdGFydEFwcCh7XG4gICAgcGtnOiBTRVRUSU5HU19IRUxQRVJfSUQsXG4gICAgYWN0aXZpdHk6IFNFVFRJTkdTX0hFTFBFUl9NQUlOX0FDVElWSVRZLFxuICAgIGFjdGlvbjogJ2FuZHJvaWQuaW50ZW50LmFjdGlvbi5NQUlOJyxcbiAgICBjYXRlZ29yeTogJ2FuZHJvaWQuaW50ZW50LmNhdGVnb3J5LkxBVU5DSEVSJyxcbiAgICBzdG9wQXBwOiBmYWxzZSxcbiAgICB3YWl0Rm9yTGF1bmNoOiBmYWxzZSxcbiAgfSk7XG4gIHRyeSB7XG4gICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiBhd2FpdCB0aGlzLnByb2Nlc3NFeGlzdHMoU0VUVElOR1NfSEVMUEVSX0lEKSwge1xuICAgICAgd2FpdE1zOiB0aW1lb3V0LFxuICAgICAgaW50ZXJ2YWxNczogMzAwLFxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEFwcGl1bSBTZXR0aW5ncyBhcHAgaXMgbm90IHJ1bm5pbmcgYWZ0ZXIgJHt0aW1lb3V0fW1zYCk7XG4gIH1cbn07XG5cbi8qKlxuICogQ2hhbmdlIHRoZSBzdGF0ZSBvZiBXaUZpIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG9uIC0gVHJ1ZSB0byBlbmFibGUgYW5kIGZhbHNlIHRvIGRpc2FibGUgaXQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGlzRW11bGF0b3IgW2ZhbHNlXSAtIFNldCBpdCB0byB0cnVlIGlmIHRoZSBkZXZpY2UgdW5kZXIgdGVzdFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBhbiBlbXVsYXRvciByYXRoZXIgdGhhbiBhIHJlYWwgZGV2aWNlLlxuICovXG5jb21tYW5kcy5zZXRXaWZpU3RhdGUgPSBhc3luYyBmdW5jdGlvbiBzZXRXaWZpU3RhdGUgKG9uLCBpc0VtdWxhdG9yID0gZmFsc2UpIHtcbiAgaWYgKGlzRW11bGF0b3IpIHtcbiAgICAvLyBUaGUgc3ZjIGNvbW1hbmQgZG9lcyBub3QgcmVxdWlyZSB0byBiZSByb290IHNpbmNlIEFQSSAyNlxuICAgIGF3YWl0IHRoaXMuc2hlbGwoWydzdmMnLCAnd2lmaScsIG9uID8gJ2VuYWJsZScgOiAnZGlzYWJsZSddLCB7XG4gICAgICBwcml2aWxlZ2VkOiBhd2FpdCB0aGlzLmdldEFwaUxldmVsKCkgPCAyNixcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBhd2FpdCB0aGlzLnNoZWxsKFtcbiAgICAgICdhbScsICdicm9hZGNhc3QnLFxuICAgICAgJy1hJywgV0lGSV9DT05ORUNUSU9OX1NFVFRJTkdfQUNUSU9OLFxuICAgICAgJy1uJywgV0lGSV9DT05ORUNUSU9OX1NFVFRJTkdfUkVDRUlWRVIsXG4gICAgICAnLS1lcycsICdzZXRzdGF0dXMnLCBvbiA/ICdlbmFibGUnIDogJ2Rpc2FibGUnXG4gICAgXSk7XG4gIH1cbn07XG5cbi8qKlxuICogQ2hhbmdlIHRoZSBzdGF0ZSBvZiBEYXRhIHRyYW5zZmVyIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG9uIC0gVHJ1ZSB0byBlbmFibGUgYW5kIGZhbHNlIHRvIGRpc2FibGUgaXQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGlzRW11bGF0b3IgW2ZhbHNlXSAtIFNldCBpdCB0byB0cnVlIGlmIHRoZSBkZXZpY2UgdW5kZXIgdGVzdFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBhbiBlbXVsYXRvciByYXRoZXIgdGhhbiBhIHJlYWwgZGV2aWNlLlxuICovXG5jb21tYW5kcy5zZXREYXRhU3RhdGUgPSBhc3luYyBmdW5jdGlvbiBzZXREYXRhU3RhdGUgKG9uLCBpc0VtdWxhdG9yID0gZmFsc2UpIHtcbiAgaWYgKGlzRW11bGF0b3IpIHtcbiAgICAvLyBUaGUgc3ZjIGNvbW1hbmQgZG9lcyBub3QgcmVxdWlyZSB0byBiZSByb290IHNpbmNlIEFQSSAyNlxuICAgIGF3YWl0IHRoaXMuc2hlbGwoWydzdmMnLCAnZGF0YScsIG9uID8gJ2VuYWJsZScgOiAnZGlzYWJsZSddLCB7XG4gICAgICBwcml2aWxlZ2VkOiBhd2FpdCB0aGlzLmdldEFwaUxldmVsKCkgPCAyNixcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBhd2FpdCB0aGlzLnNoZWxsKFtcbiAgICAgICdhbScsICdicm9hZGNhc3QnLFxuICAgICAgJy1hJywgREFUQV9DT05ORUNUSU9OX1NFVFRJTkdfQUNUSU9OLFxuICAgICAgJy1uJywgREFUQV9DT05ORUNUSU9OX1NFVFRJTkdfUkVDRUlWRVIsXG4gICAgICAnLS1lcycsICdzZXRzdGF0dXMnLCBvbiA/ICdlbmFibGUnIDogJ2Rpc2FibGUnXG4gICAgXSk7XG4gIH1cbn07XG5cbi8qKlxuICogQ2hhbmdlIHRoZSBzdGF0ZSBvZiBhbmltYXRpb24gb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICogQW5pbWF0aW9uIG9uIHRoZSBkZXZpY2UgaXMgY29udHJvbGxlZCBieSB0aGUgZm9sbG93aW5nIGdsb2JhbCBwcm9wZXJ0aWVzOlxuICogW0FOSU1BVE9SX0RVUkFUSU9OX1NDQUxFXXtAbGluayBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvYW5kcm9pZC9wcm92aWRlci9TZXR0aW5ncy5HbG9iYWwuaHRtbCNBTklNQVRPUl9EVVJBVElPTl9TQ0FMRX0sXG4gKiBbVFJBTlNJVElPTl9BTklNQVRJT05fU0NBTEVde0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLmFuZHJvaWQuY29tL3JlZmVyZW5jZS9hbmRyb2lkL3Byb3ZpZGVyL1NldHRpbmdzLkdsb2JhbC5odG1sI1RSQU5TSVRJT05fQU5JTUFUSU9OX1NDQUxFfSxcbiAqIFtXSU5ET1dfQU5JTUFUSU9OX1NDQUxFXXtAbGluayBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvYW5kcm9pZC9wcm92aWRlci9TZXR0aW5ncy5HbG9iYWwuaHRtbCNXSU5ET1dfQU5JTUFUSU9OX1NDQUxFfS5cbiAqIFRoaXMgbWV0aG9kIHNldHMgYWxsIHRoaXMgcHJvcGVydGllcyB0byAwLjAgdG8gZGlzYWJsZSAoMS4wIHRvIGVuYWJsZSkgYW5pbWF0aW9uLlxuICpcbiAqIFR1cm5pbmcgb2ZmIGFuaW1hdGlvbiBtaWdodCBiZSB1c2VmdWwgdG8gaW1wcm92ZSBzdGFiaWxpdHlcbiAqIGFuZCByZWR1Y2UgdGVzdHMgZXhlY3V0aW9uIHRpbWUuXG4gKlxuICogQHBhcmFtIHtib29sZWFufSBvbiAtIFRydWUgdG8gZW5hYmxlIGFuZCBmYWxzZSB0byBkaXNhYmxlIGl0LlxuICovXG5jb21tYW5kcy5zZXRBbmltYXRpb25TdGF0ZSA9IGFzeW5jIGZ1bmN0aW9uIHNldEFuaW1hdGlvblN0YXRlIChvbikge1xuICBhd2FpdCB0aGlzLnNoZWxsKFtcbiAgICAnYW0nLCAnYnJvYWRjYXN0JyxcbiAgICAnLWEnLCBBTklNQVRJT05fU0VUVElOR19BQ1RJT04sXG4gICAgJy1uJywgQU5JTUFUSU9OX1NFVFRJTkdfUkVDRUlWRVIsXG4gICAgJy0tZXMnLCAnc2V0c3RhdHVzJywgb24gPyAnZW5hYmxlJyA6ICdkaXNhYmxlJ1xuICBdKTtcbn07XG5cbi8qKlxuICogQ2hhbmdlIHRoZSBsb2NhbGUgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LiBEb24ndCBuZWVkIHRvIHJlYm9vdCB0aGUgZGV2aWNlIGFmdGVyIGNoYW5naW5nIHRoZSBsb2NhbGUuXG4gKiBUaGlzIG1ldGhvZCBzZXRzIGFuIGFyYml0cmFyeSBsb2NhbGUgZm9sbG93aW5nOlxuICogICBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvamF2YS91dGlsL0xvY2FsZS5odG1sXG4gKiAgIGh0dHBzOi8vZGV2ZWxvcGVyLmFuZHJvaWQuY29tL3JlZmVyZW5jZS9qYXZhL3V0aWwvTG9jYWxlLmh0bWwjTG9jYWxlKGphdmEubGFuZy5TdHJpbmcsJTIwamF2YS5sYW5nLlN0cmluZylcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbGFuZ3VhZ2UgLSBMYW5ndWFnZS4gZS5nLiBlbiwgamFcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb3VudHJ5IC0gQ291bnRyeS4gZS5nLiBVUywgSlBcbiAqIEBwYXJhbSB7P3N0cmluZ30gc2NyaXB0IC0gU2NyaXB0LiBlLmcuIEhhbnMgaW4gYHpoLUhhbnMtQ05gXG4gKi9cbmNvbW1hbmRzLnNldERldmljZVN5c0xvY2FsZVZpYVNldHRpbmdBcHAgPSBhc3luYyBmdW5jdGlvbiBzZXREZXZpY2VTeXNMb2NhbGVWaWFTZXR0aW5nQXBwIChsYW5ndWFnZSwgY291bnRyeSwgc2NyaXB0ID0gbnVsbCkge1xuICBjb25zdCBwYXJhbXMgPSBbXG4gICAgJ2FtJywgJ2Jyb2FkY2FzdCcsXG4gICAgJy1hJywgTE9DQUxFX1NFVFRJTkdfQUNUSU9OLFxuICAgICctbicsIExPQ0FMRV9TRVRUSU5HX1JFQ0VJVkVSLFxuICAgICctLWVzJywgJ2xhbmcnLCBsYW5ndWFnZS50b0xvd2VyQ2FzZSgpLFxuICAgICctLWVzJywgJ2NvdW50cnknLCBjb3VudHJ5LnRvVXBwZXJDYXNlKClcbiAgXTtcblxuICBpZiAoc2NyaXB0KSB7XG4gICAgcGFyYW1zLnB1c2goJy0tZXMnLCAnc2NyaXB0Jywgc2NyaXB0KTtcbiAgfVxuXG4gIGF3YWl0IHRoaXMuc2hlbGwocGFyYW1zKTtcbn07XG5cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBMb2NhdGlvblxuICogQHByb3BlcnR5IHtudW1iZXJ8c3RyaW5nfSBsb25naXR1ZGUgLSBWYWxpZCBsb25naXR1ZGUgdmFsdWUuXG4gKiBAcHJvcGVydHkge251bWJlcnxzdHJpbmd9IGxhdGl0dWRlIC0gVmFsaWQgbGF0aXR1ZGUgdmFsdWUuXG4gKiBAcHJvcGVydHkgez9udW1iZXJ8c3RyaW5nfSBhbHRpdHVkZSAtIFZhbGlkIGFsdGl0dWRlIHZhbHVlLlxuICogQHByb3BlcnR5IHs/bnVtYmVyfHN0cmluZ30gc2F0ZWxsaXRlcyBbMTJdIC0gTnVtYmVyIG9mIHNhdGVsbGl0ZXMgYmVpbmcgdHJhY2tlZCAoMS0xMikuXG4gKiBUaGlzIHZhbHVlIGlzIGlnbm9yZWQgb24gcmVhbCBkZXZpY2VzLlxuICogQHByb3BlcnR5IHs/bnVtYmVyfHN0cmluZ30gc3BlZWQgLSBWYWxpZCBzcGVlZCB2YWx1ZS5cbiAqIFNob3VsZCBiZSBncmVhdGVyIHRoYW4gMC4wIG1ldGVycy9zZWNvbmQgZm9yIHJlYWwgZGV2aWNlcyBvciAwLjAga25vdHNcbiAqIGZvciBlbXVsYXRvcnMuXG4gKi9cblxuLyoqXG4gKiBFbXVsYXRlIGdlb2xvY2F0aW9uIGNvb3JkaW5hdGVzIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqXG4gKiBAcGFyYW0ge0xvY2F0aW9ufSBsb2NhdGlvbiAtIExvY2F0aW9uIG9iamVjdC4gVGhlIGBhbHRpdHVkZWAgdmFsdWUgaXMgaWdub3JlZFxuICogd2hpbGUgbW9ja2luZyB0aGUgcG9zaXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGlzRW11bGF0b3IgW2ZhbHNlXSAtIFNldCBpdCB0byB0cnVlIGlmIHRoZSBkZXZpY2UgdW5kZXIgdGVzdFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBhbiBlbXVsYXRvciByYXRoZXIgdGhhbiBhIHJlYWwgZGV2aWNlLlxuICovXG5jb21tYW5kcy5zZXRHZW9Mb2NhdGlvbiA9IGFzeW5jIGZ1bmN0aW9uIHNldEdlb0xvY2F0aW9uIChsb2NhdGlvbiwgaXNFbXVsYXRvciA9IGZhbHNlKSB7XG4gIGNvbnN0IGZvcm1hdExvY2F0aW9uVmFsdWUgPSAodmFsdWVOYW1lLCBpc1JlcXVpcmVkID0gdHJ1ZSkgPT4ge1xuICAgIGlmICghdXRpbC5oYXNWYWx1ZShsb2NhdGlvblt2YWx1ZU5hbWVdKSkge1xuICAgICAgaWYgKGlzUmVxdWlyZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3ZhbHVlTmFtZX0gbXVzdCBiZSBwcm92aWRlZGApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IGZsb2F0VmFsdWUgPSBwYXJzZUZsb2F0KGxvY2F0aW9uW3ZhbHVlTmFtZV0pO1xuICAgIGlmICghaXNOYU4oZmxvYXRWYWx1ZSkpIHtcbiAgICAgIHJldHVybiBgJHtfLmNlaWwoZmxvYXRWYWx1ZSwgNSl9YDtcbiAgICB9XG4gICAgaWYgKGlzUmVxdWlyZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt2YWx1ZU5hbWV9IGlzIGV4cGVjdGVkIHRvIGJlIGEgdmFsaWQgZmxvYXQgbnVtYmVyLiBgICtcbiAgICAgICAgYCcke2xvY2F0aW9uW3ZhbHVlTmFtZV19JyBpcyBnaXZlbiBpbnN0ZWFkYCk7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9O1xuICBjb25zdCBsb25naXR1ZGUgPSBmb3JtYXRMb2NhdGlvblZhbHVlKCdsb25naXR1ZGUnKTtcbiAgY29uc3QgbGF0aXR1ZGUgPSBmb3JtYXRMb2NhdGlvblZhbHVlKCdsYXRpdHVkZScpO1xuICBjb25zdCBhbHRpdHVkZSA9IGZvcm1hdExvY2F0aW9uVmFsdWUoJ2FsdGl0dWRlJywgZmFsc2UpO1xuICBjb25zdCBzcGVlZCA9IGZvcm1hdExvY2F0aW9uVmFsdWUoJ3NwZWVkJywgZmFsc2UpO1xuICBpZiAoaXNFbXVsYXRvcikge1xuICAgIGNvbnN0IGFyZ3MgPSBbbG9uZ2l0dWRlLCBsYXRpdHVkZV07XG4gICAgaWYgKCFfLmlzTmlsKGFsdGl0dWRlKSkge1xuICAgICAgYXJncy5wdXNoKGFsdGl0dWRlKTtcbiAgICB9XG4gICAgY29uc3Qgc2F0ZWxsaXRlcyA9IHBhcnNlSW50KGxvY2F0aW9uLnNhdGVsbGl0ZXMsIDEwKTtcbiAgICBpZiAoIU51bWJlci5pc05hTihzYXRlbGxpdGVzKSAmJiBzYXRlbGxpdGVzID4gMCAmJiBzYXRlbGxpdGVzIDw9IDEyKSB7XG4gICAgICBpZiAoYXJncy5sZW5ndGggPCAzKSB7XG4gICAgICAgIGFyZ3MucHVzaChgJHtERUZBVUxUX0FMVElUVURFfWApO1xuICAgICAgfVxuICAgICAgYXJncy5wdXNoKGAke3NhdGVsbGl0ZXN9YCk7XG4gICAgfVxuICAgIGlmICghXy5pc05pbChzcGVlZCkpIHtcbiAgICAgIGlmIChhcmdzLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgYXJncy5wdXNoKGAke0RFRkFVTFRfQUxUSVRVREV9YCk7XG4gICAgICB9XG4gICAgICBpZiAoYXJncy5sZW5ndGggPCA0KSB7XG4gICAgICAgIGFyZ3MucHVzaChgJHtERUZBVUxUX1NBVEVMTElURVNfQ09VTlR9YCk7XG4gICAgICB9XG4gICAgICBhcmdzLnB1c2goc3BlZWQpO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLnJlc2V0VGVsbmV0QXV0aFRva2VuKCk7XG4gICAgYXdhaXQgdGhpcy5hZGJFeGVjKFsnZW11JywgJ2dlbycsICdmaXgnLCAuLi5hcmdzXSk7XG4gICAgLy8gQSB3b3JrYXJvdW5kIGZvciBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2FuZHJvaWQvaXNzdWVzL2RldGFpbD9pZD0yMDYxODBcbiAgICBhd2FpdCB0aGlzLmFkYkV4ZWMoWydlbXUnLCAnZ2VvJywgJ2ZpeCcsIC4uLihhcmdzLm1hcCgoYXJnKSA9PiBhcmcucmVwbGFjZSgnLicsICcsJykpKV0pO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGFyZ3MgPSBbXG4gICAgICAnYW0nLCAnc3RhcnRzZXJ2aWNlJyxcbiAgICAgICctZScsICdsb25naXR1ZGUnLCBsb25naXR1ZGUsXG4gICAgICAnLWUnLCAnbGF0aXR1ZGUnLCBsYXRpdHVkZSxcbiAgICBdO1xuICAgIGlmICh1dGlsLmhhc1ZhbHVlKGFsdGl0dWRlKSkge1xuICAgICAgYXJncy5wdXNoKCctZScsICdhbHRpdHVkZScsIGFsdGl0dWRlKTtcbiAgICB9XG4gICAgaWYgKHV0aWwuaGFzVmFsdWUoc3BlZWQpKSB7XG4gICAgICBhcmdzLnB1c2goJy1lJywgJ3NwZWVkJywgc3BlZWQpO1xuICAgIH1cbiAgICBhcmdzLnB1c2goTE9DQVRJT05fU0VSVklDRSk7XG4gICAgYXdhaXQgdGhpcy5zaGVsbChhcmdzKTtcbiAgfVxufTtcblxuLyoqXG4gKiBHZXQgdGhlIGN1cnJlbnQgZ2VvIGxvY2F0aW9uIGZyb20gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICpcbiAqIEByZXR1cm5zIHtMb2NhdGlvbn0gVGhlIGN1cnJlbnQgbG9jYXRpb25cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgY3VycmVudCBsb2NhdGlvbiBjYW5ub3QgYmUgcmV0cmlldmVkXG4gKi9cbmNvbW1hbmRzLmdldEdlb0xvY2F0aW9uID0gYXN5bmMgZnVuY3Rpb24gZ2V0R2VvTG9jYXRpb24gKCkge1xuICBsZXQgb3V0cHV0O1xuICB0cnkge1xuICAgIG91dHB1dCA9IGF3YWl0IHRoaXMuc2hlbGwoW1xuICAgICAgJ2FtJywgJ2Jyb2FkY2FzdCcsXG4gICAgICAnLW4nLCBMT0NBVElPTl9SRUNFSVZFUixcbiAgICAgICctYScsIExPQ0FUSU9OX1JFVFJJRVZBTF9BQ1RJT04sXG4gICAgXSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHJldHJpZXZlIHRoZSBjdXJyZW50IGdlbyBjb29yZGluYXRlcyBmcm9tIHRoZSBkZXZpY2UuIGAgK1xuICAgICAgYE1ha2Ugc3VyZSB0aGUgQXBwaXVtIFNldHRpbmdzIGFwcGxpY2F0aW9uIGlzIHVwIHRvIGRhdGUgYW5kIGhhcyBsb2NhdGlvbiBwZXJtaXNzaW9ucy4gQWxzbyB0aGUgbG9jYXRpb24gYCArXG4gICAgICBgc2VydmljZXMgbXVzdCBiZSBlbmFibGVkIG9uIHRoZSBkZXZpY2UuIE9yaWdpbmFsIGVycm9yOiAke2Vyci5tZXNzYWdlfWApO1xuICB9XG5cbiAgY29uc3QgbWF0Y2ggPSAvZGF0YT1cIigtP1tcXGQuXSspXFxzKygtP1tcXGQuXSspXFxzKygtP1tcXGQuXSspXCIvLmV4ZWMob3V0cHV0KTtcbiAgaWYgKCFtYXRjaCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHBhcnNlIHRoZSBhY3R1YWwgbG9jYXRpb24gdmFsdWVzIGZyb20gdGhlIGNvbW1hbmQgb3V0cHV0OiAke291dHB1dH1gKTtcbiAgfVxuICBjb25zdCBsb2NhdGlvbiA9IHtcbiAgICBsYXRpdHVkZTogbWF0Y2hbMV0sXG4gICAgbG9uZ2l0dWRlOiBtYXRjaFsyXSxcbiAgICBhbHRpdHVkZTogbWF0Y2hbM10sXG4gIH07XG4gIGxvZy5kZWJ1ZyhgR290IGdlbyBjb29yZGluYXRlczogJHtKU09OLnN0cmluZ2lmeShsb2NhdGlvbil9YCk7XG4gIHJldHVybiBsb2NhdGlvbjtcbn07XG5cbi8qKlxuICogUGVyZm9ybXMgdGhlIGdpdmVuIGVkaXRvciBhY3Rpb24gb24gdGhlIGZvY3VzZWQgaW5wdXQgZmllbGQuXG4gKiBUaGlzIG1ldGhvZCByZXF1aXJlcyBBcHBpdW0gU2V0dGluZ3MgaGVscGVyIHRvIGJlIGluc3RhbGxlZCBvbiB0aGUgZGV2aWNlLlxuICogTm8gZXhjZXB0aW9uIGlzIHRocm93biBpZiB0aGVyZSB3YXMgYSBmYWlsdXJlIHdoaWxlIHBlcmZvcm1pbmcgdGhlIGFjdGlvbi5cbiAqIFlvdSBtdXN0IGludmVzdGlnYXRlIHRoZSBsb2djYXQgb3V0cHV0IGlmIHNvbWV0aGluZyBkaWQgbm90IHdvcmsgYXMgZXhwZWN0ZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBhY3Rpb24gLSBFaXRoZXIgYWN0aW9uIGNvZGUgb3IgbmFtZS4gVGhlIGZvbGxvd2luZyBhY3Rpb25cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMgYXJlIHN1cHBvcnRlZDogYG5vcm1hbCwgdW5zcGVjaWZpZWQsIG5vbmUsXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvLCBzZWFyY2gsIHNlbmQsIG5leHQsIGRvbmUsIHByZXZpb3VzYFxuICovXG5jb21tYW5kcy5wZXJmb3JtRWRpdG9yQWN0aW9uID0gYXN5bmMgZnVuY3Rpb24gcGVyZm9ybUVkaXRvckFjdGlvbiAoYWN0aW9uKSB7XG4gIGxvZy5kZWJ1ZyhgUGVyZm9ybWluZyBlZGl0b3IgYWN0aW9uOiAke2FjdGlvbn1gKTtcbiAgYXdhaXQgdGhpcy5ydW5JbkltZUNvbnRleHQoQVBQSVVNX0lNRSxcbiAgICBhc3luYyAoKSA9PiBhd2FpdCB0aGlzLnNoZWxsKFsnaW5wdXQnLCAndGV4dCcsIGAvJHthY3Rpb259L2BdKSk7XG59O1xuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgdGV4dCBjb250ZW50IG9mIHRoZSBkZXZpY2UncyBjbGlwYm9hcmQuXG4gKiBUaGUgbWV0aG9kIHdvcmtzIGZvciBBbmRyb2lkIGJlbG93IGFuZCBhYm92ZSAyOS5cbiAqIEl0IHRlbW9yYXJpbHkgZW5mb3JjZXMgdGhlIElNRSBzZXR0aW5nIGluIG9yZGVyIHRvIHdvcmthcm91bmRcbiAqIHNlY3VyaXR5IGxpbWl0YXRpb25zIGlmIG5lZWRlZC5cbiAqIFRoaXMgbWV0aG9kIG9ubHkgd29ya3MgaWYgQXBwaXVtIFNldHRpbmdzIHYuIDIuMTUrIGlzIGluc3RhbGxlZFxuICogb24gdGhlIGRldmljZSB1bmRlciB0ZXN0XG4gKlxuICogQHJldHVybnMge3N0cmluZ30gVGhlIGFjdHVhbCBjb250ZW50IG9mIHRoZSBtYWluIGNsaXBib2FyZCBhc1xuICogYmFzZTY0LWVuY29kZWQgc3RyaW5nIG9yIGFuIGVtcHR5IHN0cmluZyBpZiB0aGUgY2xpcGJvYXJkIGlzIGVtcHR5XG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlcmUgd2FzIGEgcHJvYmxlbSB3aGlsZSBnZXR0aW5nIHRoZVxuICogY2xpcGJvYXJkIGNvbnRhbnRcbiAqL1xuY29tbWFuZHMuZ2V0Q2xpcGJvYXJkID0gYXN5bmMgZnVuY3Rpb24gZ2V0Q2xpcGJvYXJkICgpIHtcbiAgbG9nLmRlYnVnKCdHZXR0aW5nIHRoZSBjbGlwYm9hcmQgY29udGVudCcpO1xuICBjb25zdCByZXRyaWV2ZUNsaXBib2FyZCA9IGFzeW5jICgpID0+IGF3YWl0IHRoaXMuc2hlbGwoW1xuICAgICdhbScsICdicm9hZGNhc3QnLFxuICAgICctbicsIENMSVBCT0FSRF9SRUNFSVZFUixcbiAgICAnLWEnLCBDTElQQk9BUkRfUkVUUklFVkFMX0FDVElPTixcbiAgXSk7XG4gIGxldCBvdXRwdXQ7XG4gIHRyeSB7XG4gICAgb3V0cHV0ID0gKGF3YWl0IHRoaXMuZ2V0QXBpTGV2ZWwoKSA+PSAyOSlcbiAgICAgID8gKGF3YWl0IHRoaXMucnVuSW5JbWVDb250ZXh0KEFQUElVTV9JTUUsIHJldHJpZXZlQ2xpcGJvYXJkKSlcbiAgICAgIDogKGF3YWl0IHJldHJpZXZlQ2xpcGJvYXJkKCkpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCByZXRyaWV2ZSB0aGUgY3VycmVudCBjbGlwYm9hcmQgY29udGVudCBmcm9tIHRoZSBkZXZpY2UuIGAgK1xuICAgICAgYE1ha2Ugc3VyZSB0aGUgQXBwaXVtIFNldHRpbmdzIGFwcGxpY2F0aW9uIGlzIHVwIHRvIGRhdGUuIGAgK1xuICAgICAgYE9yaWdpbmFsIGVycm9yOiAke2Vyci5tZXNzYWdlfWApO1xuICB9XG5cbiAgY29uc3QgbWF0Y2ggPSAvZGF0YT1cIihbXlwiXSopXCIvLmV4ZWMob3V0cHV0KTtcbiAgaWYgKCFtYXRjaCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHBhcnNlIHRoZSBhY3R1YWwgY2xpYm9hcmQgY29udGVudCBmcm9tIHRoZSBjb21tYW5kIG91dHB1dDogJHtvdXRwdXR9YCk7XG4gIH1cbiAgcmV0dXJuIF8udHJpbShtYXRjaFsxXSk7XG59O1xuXG4vKipcbiAqIFJldHJpZXZlcyBBbmRyb2lkIG5vdGlmaWNhdGlvbnMgdmlhIEFwcGl1bSBTZXR0aW5ncyBoZWxwZXIuXG4gKiBBcHBpdW0gU2V0dGluZ3MgYXBwIGl0c2VsZiBtdXN0IGJlICptYW51YWxseSogZ3JhbnRlZCB0byBhY2Nlc3Mgbm90aWZpY2F0aW9uc1xuICogdW5kZXIgZGV2aWNlIFNldHRpbmdzIGluIG9yZGVyIHRvIG1ha2UgdGhpcyBmZWF0dXJlIHdvcmtpbmcuXG4gKiBBcHBpdW0gU2V0dGluZ3MgaGVscGVyIGtlZXBzIGFsbCB0aGUgYWN0aXZlIG5vdGlmaWNhdGlvbnMgcGx1c1xuICogbm90aWZpY2F0aW9ucyB0aGF0IGFwcGVhcmVkIHdoaWxlIGl0IHdhcyBydW5uaW5nIGluIHRoZSBpbnRlcm5hbCBidWZmZXIsXG4gKiBidXQgbm8gbW9yZSB0aGFuIDEwMCBpdGVtcyBhbHRvZ2V0aGVyLiBOZXdseSBhcHBlYXJlZCBub3RpZmljYXRpb25zXG4gKiBhcmUgYWx3YXlzIGFkZGVkIHRvIHRoZSBoZWFkIG9mIHRoZSBub3RpZmljYXRpb25zIGFycmF5LlxuICogVGhlIGBpc1JlbW92ZWRgIGZsYWcgaXMgc2V0IHRvIGB0cnVlYCBmb3Igbm90aWZpY2F0aW9ucyB0aGF0IGhhdmUgYmVlbiByZW1vdmVkLlxuICpcbiAqIFNlZSBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvYW5kcm9pZC9zZXJ2aWNlL25vdGlmaWNhdGlvbi9TdGF0dXNCYXJOb3RpZmljYXRpb25cbiAqIGFuZCBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvYW5kcm9pZC9hcHAvTm90aWZpY2F0aW9uLmh0bWxcbiAqIGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGF2YWlsYWJsZSBub3RpZmljYXRpb24gcHJvcGVydGllcyBhbmQgdGhlaXIgdmFsdWVzLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBleGFtcGxlIG91dHB1dCBpczpcbiAqIGBgYGpzb25cbiAqIHtcbiAqICAgXCJzdGF0dXNCYXJOb3RpZmljYXRpb25zXCI6W1xuICogICAgIHtcbiAqICAgICAgIFwiaXNHcm91cFwiOmZhbHNlLFxuICogICAgICAgXCJwYWNrYWdlTmFtZVwiOlwiaW8uYXBwaXVtLnNldHRpbmdzXCIsXG4gKiAgICAgICBcImlzQ2xlYXJhYmxlXCI6ZmFsc2UsXG4gKiAgICAgICBcImlzT25nb2luZ1wiOnRydWUsXG4gKiAgICAgICBcImlkXCI6MSxcbiAqICAgICAgIFwidGFnXCI6bnVsbCxcbiAqICAgICAgIFwibm90aWZpY2F0aW9uXCI6e1xuICogICAgICAgICBcInRpdGxlXCI6bnVsbCxcbiAqICAgICAgICAgXCJiaWdUaXRsZVwiOlwiQXBwaXVtIFNldHRpbmdzXCIsXG4gKiAgICAgICAgIFwidGV4dFwiOm51bGwsXG4gKiAgICAgICAgIFwiYmlnVGV4dFwiOlwiS2VlcCB0aGlzIHNlcnZpY2UgcnVubmluZywgc28gQXBwaXVtIGZvciBBbmRyb2lkIGNhbiBwcm9wZXJseSBpbnRlcmFjdCB3aXRoIHNldmVyYWwgc3lzdGVtIEFQSXNcIixcbiAqICAgICAgICAgXCJ0aWNrZXJUZXh0XCI6bnVsbCxcbiAqICAgICAgICAgXCJzdWJUZXh0XCI6bnVsbCxcbiAqICAgICAgICAgXCJpbmZvVGV4dFwiOm51bGwsXG4gKiAgICAgICAgIFwidGVtcGxhdGVcIjpcImFuZHJvaWQuYXBwLk5vdGlmaWNhdGlvbiRCaWdUZXh0U3R5bGVcIlxuICogICAgICAgfSxcbiAqICAgICAgIFwidXNlckhhbmRsZVwiOjAsXG4gKiAgICAgICBcImdyb3VwS2V5XCI6XCIwfGlvLmFwcGl1bS5zZXR0aW5nc3wxfG51bGx8MTAxMzNcIixcbiAqICAgICAgIFwib3ZlcnJpZGVHcm91cEtleVwiOm51bGwsXG4gKiAgICAgICBcInBvc3RUaW1lXCI6MTU3Njg1MzUxODg1MCxcbiAqICAgICAgIFwia2V5XCI6XCIwfGlvLmFwcGl1bS5zZXR0aW5nc3wxfG51bGx8MTAxMzNcIixcbiAqICAgICAgIFwiaXNSZW1vdmVkXCI6ZmFsc2VcbiAqICAgICB9XG4gKiAgIF1cbiAqIH1cbiAqIGBgYFxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSBnZXR0aW5nIHRoZSBub3RpZmljYXRpb25zIGxpc3RcbiAqL1xuY29tbWFuZHMuZ2V0Tm90aWZpY2F0aW9ucyA9IGFzeW5jIGZ1bmN0aW9uIGdldE5vdGlmaWNhdGlvbnMgKCkge1xuICBsb2cuZGVidWcoJ1JldHJpZXZpbmcgbm90aWZpY2F0aW9ucycpO1xuICAvLyBTb21laG93IHByb3ZpZGluZyB0aGUgYC1uYCBhcmcgdG8gdGhlIGBhbWAgdW5kZXJuZWF0aFxuICAvLyByZW5kZXJzIHRoZSBicm9hZGNhc3QgdG8gZmFpbCBpbnN0ZWFkIG9mIHN0YXJ0aW5nIHRoZVxuICAvLyBBcHBpdW0gU2V0dGluZ3MgYXBwLiBUaGlzIG9ubHkgaGFwcGVucyB0byB0aGUgbm90aWZpY2F0aW9uc1xuICAvLyByZWNlaXZlclxuICBhd2FpdCB0aGlzLnJlcXVpcmVSdW5uaW5nU2V0dGluZ3NBcHAoKTtcbiAgbGV0IG91dHB1dDtcbiAgdHJ5IHtcbiAgICBvdXRwdXQgPSBhd2FpdCB0aGlzLnNoZWxsKFtcbiAgICAgICdhbScsICdicm9hZGNhc3QnLFxuICAgICAgJy1hJywgTk9USUZJQ0FUSU9OU19SRVRSSUVWQUxfQUNUSU9OLFxuICAgIF0pO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCByZXRyaWV2ZSBub3RpZmljYXRpb25zIGZyb20gdGhlIGRldmljZS4gYCArXG4gICAgICBgTWFrZSBzdXJlIHRoZSBBcHBpdW0gU2V0dGluZ3MgYXBwbGljYXRpb24gaXMgaW5zdGFsbGVkIGFuZCBpcyB1cCB0byBkYXRlLiBgICtcbiAgICAgIGBPcmlnaW5hbCBlcnJvcjogJHtlcnIubWVzc2FnZX1gKTtcbiAgfVxuICByZXR1cm4gcGFyc2VKc29uRGF0YShvdXRwdXQsICdub3RpZmljYXRpb25zJyk7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFNtc0xpc3RPcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWF4IFsxMDBdIC0gVGhlIG1heGltdW0gY291bnQgb2YgcmVjZW50IG1lc3NhZ2VzXG4gKiB0byByZXRyaWV2ZVxuICovXG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSBsaXN0IG9mIHRoZSBtb3N0IHJlY2VudCBTTVNcbiAqIHByb3BlcnRpZXMgbGlzdCB2aWEgQXBwaXVtIFNldHRpbmdzIGhlbHBlci5cbiAqIE1lc3NhZ2VzIGFyZSBzb3J0ZWQgYnkgZGF0ZSBpbiBkZXNjZW5kaW5nIG9yZGVyLlxuICpcbiAqIEBwYXJhbSB7U21zTGlzdE9wdGlvbnN9IG9wdHNcbiAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBleGFtcGxlIG91dHB1dCBpczpcbiAqIGBgYGpzb25cbiAqIHtcbiAqICAgXCJpdGVtc1wiOltcbiAqICAgICB7XG4gKiAgICAgICBcImlkXCI6XCIyXCIsXG4gKiAgICAgICBcImFkZHJlc3NcIjpcIisxMjM0NTY3ODlcIixcbiAqICAgICAgIFwicGVyc29uXCI6bnVsbCxcbiAqICAgICAgIFwiZGF0ZVwiOlwiMTU4MTkzNjQyMjIwM1wiLFxuICogICAgICAgXCJyZWFkXCI6XCIwXCIsXG4gKiAgICAgICBcInN0YXR1c1wiOlwiLTFcIixcbiAqICAgICAgIFwidHlwZVwiOlwiMVwiLFxuICogICAgICAgXCJzdWJqZWN0XCI6bnVsbCxcbiAqICAgICAgIFwiYm9keVwiOlwiXFxcInRleHQgbWVzc2FnZTJcXFwiXCIsXG4gKiAgICAgICBcInNlcnZpY2VDZW50ZXJcIjpudWxsXG4gKiAgICAgfSxcbiAqICAgICB7XG4gKiAgICAgICBcImlkXCI6XCIxXCIsXG4gKiAgICAgICBcImFkZHJlc3NcIjpcIisxMjM0NTY3ODlcIixcbiAqICAgICAgIFwicGVyc29uXCI6bnVsbCxcbiAqICAgICAgIFwiZGF0ZVwiOlwiMTU4MTkzNjM4Mjc0MFwiLFxuICogICAgICAgXCJyZWFkXCI6XCIwXCIsXG4gKiAgICAgICBcInN0YXR1c1wiOlwiLTFcIixcbiAqICAgICAgIFwidHlwZVwiOlwiMVwiLFxuICogICAgICAgXCJzdWJqZWN0XCI6bnVsbCxcbiAqICAgICAgIFwiYm9keVwiOlwiXFxcInRleHQgbWVzc2FnZVxcXCJcIixcbiAqICAgICAgIFwic2VydmljZUNlbnRlclwiOm51bGxcbiAqICAgICB9XG4gKiAgIF0sXG4gKiAgIFwidG90YWxcIjoyXG4gKiB9XG4gKiBgYGBcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgZ2V0dGluZyB0aGUgU01TIGxpc3RcbiAqL1xuY29tbWFuZHMuZ2V0U21zTGlzdCA9IGFzeW5jIGZ1bmN0aW9uIGdldFNtc0xpc3QgKG9wdHMgPSB7fSkge1xuICBsb2cuZGVidWcoJ1JldHJpZXZpbmcgdGhlIHJlY2VudCBTTVMgbWVzc2FnZXMnKTtcbiAgY29uc3QgYXJncyA9IFtcbiAgICAnYW0nLCAnYnJvYWRjYXN0JyxcbiAgICAnLW4nLCBTTVNfTElTVF9SRUNFSVZFUixcbiAgICAnLWEnLCBTTVNfTElTVF9SRVRSSUVWQUxfQUNUSU9OLFxuICBdO1xuICBpZiAob3B0cy5tYXgpIHtcbiAgICBhcmdzLnB1c2goJy0tZXMnLCAnbWF4Jywgb3B0cy5tYXgpO1xuICB9XG4gIGxldCBvdXRwdXQ7XG4gIHRyeSB7XG4gICAgb3V0cHV0ID0gYXdhaXQgdGhpcy5zaGVsbChhcmdzKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgcmV0cmlldmUgU01TIGxpc3QgZnJvbSB0aGUgZGV2aWNlLiBgICtcbiAgICAgIGBNYWtlIHN1cmUgdGhlIEFwcGl1bSBTZXR0aW5ncyBhcHBsaWNhdGlvbiBpcyBpbnN0YWxsZWQgYW5kIGlzIHVwIHRvIGRhdGUuIGAgK1xuICAgICAgYE9yaWdpbmFsIGVycm9yOiAke2Vyci5tZXNzYWdlfWApO1xuICB9XG4gIHJldHVybiBwYXJzZUpzb25EYXRhKG91dHB1dCwgJ1NNUyBsaXN0Jyk7XG59O1xuXG4vKipcbiAqIFR5cGVzIHRoZSBnaXZlbiBVbmljb2RlIHN0cmluZy5cbiAqIEl0IGlzIGV4cGVjdGVkIHRoYXQgdGhlIGZvY3VzIGlzIGFscmVhZHkgcHV0XG4gKiB0byB0aGUgZGVzdGluYXRpb24gaW5wdXQgZmllbGQgYmVmb3JlIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCBUaGUgc3RyaW5nIHRvIHR5cGVcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIGlucHV0IHRleHQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gYWRiXG4gKi9cbmNvbW1hbmRzLnR5cGVVbmljb2RlID0gYXN5bmMgZnVuY3Rpb24gdHlwZVVuaWNvZGUgKHRleHQpIHtcbiAgaWYgKF8uaXNOaWwodGV4dCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB0ZXh0ID0gYCR7dGV4dH1gO1xuICBsb2cuZGVidWcoYFR5cGluZyAke3V0aWwucGx1cmFsaXplKCdjaGFyYWN0ZXInLCB0ZXh0Lmxlbmd0aCwgdHJ1ZSl9YCk7XG4gIGlmICghdGV4dCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBhd2FpdCB0aGlzLnJ1bkluSW1lQ29udGV4dChcbiAgICBVTklDT0RFX0lNRSwgYXN5bmMgKCkgPT4gYXdhaXQgdGhpcy5pbnB1dFRleHQoaW1hcC5lbmNvZGUodGV4dCkpXG4gICk7XG4gIHJldHVybiB0cnVlO1xufTtcblxuLyoqXG4gKiBQZXJmb3JtcyByZWN1cnNpdmUgbWVkaWEgc2NhbiBhdCB0aGUgZ2l2ZW4gZGVzdGluYXRpb24uXG4gKiBBbGwgc3VjY2Vzc2Z1bGx5IHNjYW5uZWQgaXRlbXMgYXJlIGJlaW5nIGFkZGVkIHRvIHRoZSBkZXZpY2Unc1xuICogbWVkaWEgbGlicmFyeS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZGVzdGluYXRpb24gRmlsZS9mb2xkZXIgcGF0aCBvbiB0aGUgcmVtb3RlIGRldmljZS5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGVyZSB3YXMgYW4gdW5leHBlY3RlZCBlcnJvciBieSBzY2FubmluZy5cbiAqL1xuY29tbWFuZHMuc2Nhbk1lZGlhID0gYXN5bmMgZnVuY3Rpb24gc2Nhbk1lZGlhIChkZXN0aW5hdGlvbikge1xuICBsb2cuZGVidWcoYFNjYW5uaW5nICcke2Rlc3RpbmF0aW9ufScgZm9yIG1lZGlhIGZpbGVzYCk7XG4gIGNvbnN0IG91dHB1dCA9IGF3YWl0IHRoaXMuc2hlbGwoW1xuICAgICdhbScsICdicm9hZGNhc3QnLFxuICAgICctbicsIE1FRElBX1NDQU5fUkVDRUlWRVIsXG4gICAgJy1hJywgTUVESUFfU0NBTl9BQ1RJT04sXG4gICAgJy0tZXMnLCAncGF0aCcsIGRlc3RpbmF0aW9uXG4gIF0pO1xuICBpZiAoIV8uaW5jbHVkZXMob3V0cHV0LCAncmVzdWx0PS0xJykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIG1lZGlhIGNvdWxkIGJlIHNjYW5uZWQgYXQgJyR7ZGVzdGluYXRpb259Jy4gYCArXG4gICAgICBgQ2hlY2sgdGhlIGRldmljZSBsb2djYXQgb3V0cHV0IGZvciBtb3JlIGRldGFpbHMuYCk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbW1hbmRzO1xuIl0sImZpbGUiOiJsaWIvdG9vbHMvc2V0dGluZ3MtY2xpZW50LWNvbW1hbmRzLmpzIiwic291cmNlUm9vdCI6Ii4uLy4uLy4uIn0=
362
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi90b29scy9zZXR0aW5ncy1jbGllbnQtY29tbWFuZHMuanMiXSwibmFtZXMiOlsiU0VUVElOR1NfSEVMUEVSX0lEIiwiU0VUVElOR1NfSEVMUEVSX01BSU5fQUNUSVZJVFkiLCJXSUZJX0NPTk5FQ1RJT05fU0VUVElOR19SRUNFSVZFUiIsIldJRklfQ09OTkVDVElPTl9TRVRUSU5HX0FDVElPTiIsIkRBVEFfQ09OTkVDVElPTl9TRVRUSU5HX1JFQ0VJVkVSIiwiREFUQV9DT05ORUNUSU9OX1NFVFRJTkdfQUNUSU9OIiwiQU5JTUFUSU9OX1NFVFRJTkdfUkVDRUlWRVIiLCJBTklNQVRJT05fU0VUVElOR19BQ1RJT04iLCJMT0NBTEVfU0VUVElOR19SRUNFSVZFUiIsIkxPQ0FMRV9TRVRUSU5HX0FDVElPTiIsIkxPQ0FUSU9OX1NFUlZJQ0UiLCJMT0NBVElPTl9SRUNFSVZFUiIsIkxPQ0FUSU9OX1JFVFJJRVZBTF9BQ1RJT04iLCJDTElQQk9BUkRfUkVDRUlWRVIiLCJDTElQQk9BUkRfUkVUUklFVkFMX0FDVElPTiIsIk5PVElGSUNBVElPTlNfUkVUUklFVkFMX0FDVElPTiIsIlNNU19MSVNUX1JFQ0VJVkVSIiwiU01TX0xJU1RfUkVUUklFVkFMX0FDVElPTiIsIk1FRElBX1NDQU5fUkVDRUlWRVIiLCJNRURJQV9TQ0FOX0FDVElPTiIsIkFQUElVTV9JTUUiLCJVTklDT0RFX0lNRSIsIkRFRkFVTFRfU0FURUxMSVRFU19DT1VOVCIsIkRFRkFVTFRfQUxUSVRVREUiLCJMT0NBVElPTl9UUkFDS0VSX1RBRyIsIkdQU19DQUNIRV9SRUZSRVNIRURfTE9HUyIsIkdQU19DT09SRElOQVRFU19QQVRURVJOIiwiY29tbWFuZHMiLCJyZXF1aXJlUnVubmluZ1NldHRpbmdzQXBwIiwib3B0cyIsInByb2Nlc3NFeGlzdHMiLCJsb2ciLCJkZWJ1ZyIsInRpbWVvdXQiLCJzdGFydEFwcCIsInBrZyIsImFjdGl2aXR5IiwiYWN0aW9uIiwiY2F0ZWdvcnkiLCJzdG9wQXBwIiwid2FpdEZvckxhdW5jaCIsIndhaXRNcyIsImludGVydmFsTXMiLCJlcnIiLCJFcnJvciIsInNldFdpZmlTdGF0ZSIsIm9uIiwiaXNFbXVsYXRvciIsInNoZWxsIiwicHJpdmlsZWdlZCIsImdldEFwaUxldmVsIiwic2V0RGF0YVN0YXRlIiwic2V0QW5pbWF0aW9uU3RhdGUiLCJzZXREZXZpY2VTeXNMb2NhbGVWaWFTZXR0aW5nQXBwIiwibGFuZ3VhZ2UiLCJjb3VudHJ5Iiwic2NyaXB0IiwicGFyYW1zIiwidG9Mb3dlckNhc2UiLCJ0b1VwcGVyQ2FzZSIsInB1c2giLCJzZXRHZW9Mb2NhdGlvbiIsImxvY2F0aW9uIiwiZm9ybWF0TG9jYXRpb25WYWx1ZSIsInZhbHVlTmFtZSIsImlzUmVxdWlyZWQiLCJ1dGlsIiwiaGFzVmFsdWUiLCJmbG9hdFZhbHVlIiwicGFyc2VGbG9hdCIsImlzTmFOIiwiXyIsImNlaWwiLCJsb25naXR1ZGUiLCJsYXRpdHVkZSIsImFsdGl0dWRlIiwic3BlZWQiLCJhcmdzIiwiaXNOaWwiLCJzYXRlbGxpdGVzIiwicGFyc2VJbnQiLCJOdW1iZXIiLCJsZW5ndGgiLCJyZXNldFRlbG5ldEF1dGhUb2tlbiIsImFkYkV4ZWMiLCJtYXAiLCJhcmciLCJyZXBsYWNlIiwiZ2V0R2VvTG9jYXRpb24iLCJvdXRwdXQiLCJzdGRlcnIiLCJzdGRvdXQiLCJtZXNzYWdlIiwibWF0Y2giLCJleGVjIiwiSlNPTiIsInN0cmluZ2lmeSIsInJlZnJlc2hHZW9Mb2NhdGlvbkNhY2hlIiwidGltZW91dE1zIiwibG9nY2F0TW9uaXRvciIsIm1vbml0b3JpbmdQcm9taXNlIiwiY21kIiwiYWRiIiwiZGVmYXVsdEFyZ3MiLCJTdWJQcm9jZXNzIiwicGF0aCIsInRpbWVvdXRFcnJvck1zZyIsIkIiLCJyZXNvbHZlIiwicmVqZWN0Iiwic2V0VGltZW91dCIsImV2dCIsImxpbmVzIiwic29tZSIsImxpbmUiLCJ4IiwiaW5jbHVkZXMiLCJzdGFydCIsInRpbWVyIiwidGltaW5nIiwiVGltZXIiLCJpbmZvIiwiZ2V0RHVyYXRpb24iLCJhc01pbGxpU2Vjb25kcyIsInRvRml4ZWQiLCJpc1J1bm5pbmciLCJzdG9wIiwicGVyZm9ybUVkaXRvckFjdGlvbiIsInJ1bkluSW1lQ29udGV4dCIsImdldENsaXBib2FyZCIsInJldHJpZXZlQ2xpcGJvYXJkIiwidHJpbSIsImdldE5vdGlmaWNhdGlvbnMiLCJnZXRTbXNMaXN0IiwibWF4IiwidHlwZVVuaWNvZGUiLCJ0ZXh0IiwicGx1cmFsaXplIiwiaW5wdXRUZXh0IiwiaW1hcCIsImVuY29kZSIsInNjYW5NZWRpYSIsImRlc3RpbmF0aW9uIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBLE1BQU1BLGtCQUFrQixHQUFHLG9CQUEzQjtBQUNBLE1BQU1DLDZCQUE2QixHQUFHLFdBQXRDO0FBQ0EsTUFBTUMsZ0NBQWdDLEdBQUksR0FBRUYsa0JBQW1CLDJDQUEvRDtBQUNBLE1BQU1HLDhCQUE4QixHQUFJLEdBQUVILGtCQUFtQixPQUE3RDtBQUNBLE1BQU1JLGdDQUFnQyxHQUFJLEdBQUVKLGtCQUFtQiwyQ0FBL0Q7QUFDQSxNQUFNSyw4QkFBOEIsR0FBSSxHQUFFTCxrQkFBbUIsa0JBQTdEO0FBQ0EsTUFBTU0sMEJBQTBCLEdBQUksR0FBRU4sa0JBQW1CLHNDQUF6RDtBQUNBLE1BQU1PLHdCQUF3QixHQUFJLEdBQUVQLGtCQUFtQixZQUF2RDtBQUNBLE1BQU1RLHVCQUF1QixHQUFJLEdBQUVSLGtCQUFtQixtQ0FBdEQ7QUFDQSxNQUFNUyxxQkFBcUIsR0FBSSxHQUFFVCxrQkFBbUIsU0FBcEQ7QUFDQSxNQUFNVSxnQkFBZ0IsR0FBSSxHQUFFVixrQkFBbUIsbUJBQS9DO0FBQ0EsTUFBTVcsaUJBQWlCLEdBQUksR0FBRVgsa0JBQW1CLGtDQUFoRDtBQUNBLE1BQU1ZLHlCQUF5QixHQUFJLEdBQUVaLGtCQUFtQixXQUF4RDtBQUNBLE1BQU1hLGtCQUFrQixHQUFJLEdBQUViLGtC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LEVBQTRCRCxJQUFJLENBQUN0RCxNQUFqQyxFQUF5QyxJQUF6QyxDQUErQyxFQUFuRTs7QUFDQSxNQUFJLENBQUNzRCxJQUFMLEVBQVc7QUFDVCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxRQUFNLEtBQUtSLGVBQUwsQ0FDSjNHLFdBREksRUFDUyxZQUFZLE1BQU0sS0FBS3FILFNBQUwsQ0FBZUMsVUFBS0MsTUFBTCxDQUFZSixJQUFaLENBQWYsQ0FEM0IsQ0FBTjtBQUdBLFNBQU8sSUFBUDtBQUNELENBZEQ7O0FBd0JBN0csUUFBUSxDQUFDa0gsU0FBVCxHQUFxQixlQUFlQSxTQUFmLENBQTBCQyxXQUExQixFQUF1QztBQUMxRC9HLGtCQUFJQyxLQUFKLENBQVcsYUFBWThHLFdBQVksbUJBQW5DOztBQUNBLFFBQU1yRCxNQUFNLEdBQUcsTUFBTSxLQUFLekMsS0FBTCxDQUFXLENBQzlCLElBRDhCLEVBQ3hCLFdBRHdCLEVBRTlCLElBRjhCLEVBRXhCOUIsbUJBRndCLEVBRzlCLElBSDhCLEVBR3hCQyxpQkFId0IsRUFJOUIsTUFKOEIsRUFJdEIsTUFKc0IsRUFJZDJILFdBSmMsQ0FBWCxDQUFyQjs7QUFNQSxNQUFJLENBQUN2RSxnQkFBRTZDLFFBQUYsQ0FBVzNCLE1BQVgsRUFBbUIsV0FBbkIsQ0FBTCxFQUFzQztBQUNwQyxVQUFNLElBQUk3QyxLQUFKLENBQVcsaUNBQWdDa0csV0FBWSxLQUE3QyxHQUNiLGtEQURHLENBQU47QUFFRDtBQUNGLENBWkQ7O2VBY2VuSCxRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGxvZyBmcm9tICcuLi9sb2dnZXIuanMnO1xuaW1wb3J0IHsgcGFyc2VKc29uRGF0YSB9IGZyb20gJy4uL2hlbHBlcnMuanMnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IHV0aWwsIHRpbWluZyB9IGZyb20gJ2FwcGl1bS1zdXBwb3J0JztcbmltcG9ydCB7IHdhaXRGb3JDb25kaXRpb24gfSBmcm9tICdhc3luY2JveCc7XG5pbXBvcnQgeyBpbWFwIH0gZnJvbSAndXRmNyc7XG5pbXBvcnQgeyBTdWJQcm9jZXNzIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcblxuY29uc3QgU0VUVElOR1NfSEVMUEVSX0lEID0gJ2lvLmFwcGl1bS5zZXR0aW5ncyc7XG5jb25zdCBTRVRUSU5HU19IRUxQRVJfTUFJTl9BQ1RJVklUWSA9ICcuU2V0dGluZ3MnO1xuY29uc3QgV0lGSV9DT05ORUNUSU9OX1NFVFRJTkdfUkVDRUlWRVIgPSBgJHtTRVRUSU5HU19IRUxQRVJfSUR9Ly5yZWNlaXZlcnMuV2lGaUNvbm5lY3Rpb25TZXR0aW5nUmVjZWl2ZXJgO1xuY29uc3QgV0lGSV9DT05ORUNUSU9OX1NFVFRJTkdfQUNUSU9OID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS53aWZpYDtcbmNvbnN0IERBVEFfQ09OTkVDVElPTl9TRVRUSU5HX1JFQ0VJVkVSID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS8ucmVjZWl2ZXJzLkRhdGFDb25uZWN0aW9uU2V0dGluZ1JlY2VpdmVyYDtcbmNvbnN0IERBVEFfQ09OTkVDVElPTl9TRVRUSU5HX0FDVElPTiA9IGAke1NFVFRJTkdTX0hFTFBFUl9JRH0uZGF0YV9jb25uZWN0aW9uYDtcbmNvbnN0IEFOSU1BVElPTl9TRVRUSU5HX1JFQ0VJVkVSID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS8ucmVjZWl2ZXJzLkFuaW1hdGlvblNldHRpbmdSZWNlaXZlcmA7XG5jb25zdCBBTklNQVRJT05fU0VUVElOR19BQ1RJT04gPSBgJHtTRVRUSU5HU19IRUxQRVJfSUR9LmFuaW1hdGlvbmA7XG5jb25zdCBMT0NBTEVfU0VUVElOR19SRUNFSVZFUiA9IGAke1NFVFRJTkdTX0hFTFBFUl9JRH0vLnJlY2VpdmVycy5Mb2NhbGVTZXR0aW5nUmVjZWl2ZXJgO1xuY29uc3QgTE9DQUxFX1NFVFRJTkdfQUNUSU9OID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS5sb2NhbGVgO1xuY29uc3QgTE9DQVRJT05fU0VSVklDRSA9IGAke1NFVFRJTkdTX0hFTFBFUl9JRH0vLkxvY2F0aW9uU2VydmljZWA7XG5jb25zdCBMT0NBVElPTl9SRUNFSVZFUiA9IGAke1NFVFRJTkdTX0hFTFBFUl9JRH0vLnJlY2VpdmVycy5Mb2NhdGlvbkluZm9SZWNlaXZlcmA7XG5jb25zdCBMT0NBVElPTl9SRVRSSUVWQUxfQUNUSU9OID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS5sb2NhdGlvbmA7XG5jb25zdCBDTElQQk9BUkRfUkVDRUlWRVIgPSBgJHtTRVRUSU5HU19IRUxQRVJfSUR9Ly5yZWNlaXZlcnMuQ2xpcGJvYXJkUmVjZWl2ZXJgO1xuY29uc3QgQ0xJUEJPQVJEX1JFVFJJRVZBTF9BQ1RJT04gPSBgJHtTRVRUSU5HU19IRUxQRVJfSUR9LmNsaXBib2FyZC5nZXRgO1xuY29uc3QgTk9USUZJQ0FUSU9OU19SRVRSSUVWQUxfQUNUSU9OID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS5ub3RpZmljYXRpb25zYDtcbmNvbnN0IFNNU19MSVNUX1JFQ0VJVkVSID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS8ucmVjZWl2ZXJzLlNtc1JlYWRlcmA7XG5jb25zdCBTTVNfTElTVF9SRVRSSUVWQUxfQUNUSU9OID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS5zbXMucmVhZGA7XG5jb25zdCBNRURJQV9TQ0FOX1JFQ0VJVkVSID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS8ucmVjZWl2ZXJzLk1lZGlhU2Nhbm5lclJlY2VpdmVyYDtcbmNvbnN0IE1FRElBX1NDQU5fQUNUSU9OID0gYCR7U0VUVElOR1NfSEVMUEVSX0lEfS5zY2FuX21lZGlhYDtcbmNvbnN0IEFQUElVTV9JTUUgPSBgJHtTRVRUSU5HU19IRUxQRVJfSUR9Ly5BcHBpdW1JTUVgO1xuY29uc3QgVU5JQ09ERV9JTUUgPSBgJHtTRVRUSU5HU19IRUxQRVJfSUR9Ly5Vbmljb2RlSU1FYDtcbmNvbnN0IERFRkFVTFRfU0FURUxMSVRFU19DT1VOVCA9IDEyO1xuY29uc3QgREVGQVVMVF9BTFRJVFVERSA9IDAuMDtcbmNvbnN0IExPQ0FUSU9OX1RSQUNLRVJfVEFHID0gJ0xvY2F0aW9uVHJhY2tlcic7XG5jb25zdCBHUFNfQ0FDSEVfUkVGUkVTSEVEX0xPR1MgPSBbXG4gICdUaGUgY3VycmVudCBsb2NhdGlvbiBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmV0cmlldmVkIGZyb20gUGxheSBTZXJ2aWNlcycsXG4gICdUaGUgY3VycmVudCBsb2NhdGlvbiBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmV0cmlldmVkIGZyb20gTG9jYXRpb24gTWFuYWdlcidcbl07XG5cbmNvbnN0IEdQU19DT09SRElOQVRFU19QQVRURVJOID0gL2RhdGE9XCIoLT9bXFxkLl0rKVxccysoLT9bXFxkLl0rKVxccysoLT9bXFxkLl0rKVwiLztcblxuY29uc3QgY29tbWFuZHMgPSB7fTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTZXR0aW5nc0FwcFN0YXJ0dXBPcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcn0gdGltZW91dCBbNTAwMF0gVGhlIG1heGltdW0gbnVtYmVyIG9mIG1pbGxpc2Vjb25kc1xuICogdG8gd2FpdCB1bnRpbCB0aGUgYXBwIGhhcyBzdGFydGVkXG4gKi9cblxuLyoqXG4gKiBFbnN1cmVzIHRoYXQgQXBwaXVtIFNldHRpbmdzIGhlbHBlciBhcHBsaWNhdGlvbiBpcyBydW5uaW5nXG4gKiBhbmQgc3RhcnRzIGl0IGlmIG5lY2Vzc2FyeVxuICpcbiAqIEBwYXJhbSB7U2V0dGluZ3NBcHBTdGFydHVwT3B0aW9uc30gb3B0c1xuICogQHRocm93cyB7RXJyb3J9IElmIEFwcGl1bSBTZXR0aW5ncyBoYXMgZmFpbGVkIHRvIHN0YXJ0XG4gKiBAcmV0dXJucyB7QURCfSBzZWxmIGluc3RhbmNlIGZvciBjaGFpbmluZ1xuICovXG5jb21tYW5kcy5yZXF1aXJlUnVubmluZ1NldHRpbmdzQXBwID0gYXN5bmMgZnVuY3Rpb24gcmVxdWlyZVJ1bm5pbmdTZXR0aW5nc0FwcCAob3B0cyA9IHt9KSB7XG4gIGlmIChhd2FpdCB0aGlzLnByb2Nlc3NFeGlzdHMoU0VUVElOR1NfSEVMUEVSX0lEKSkge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbG9nLmRlYnVnKCdTdGFydGluZyBBcHBpdW0gU2V0dGluZ3MgYXBwJyk7XG4gIGNvbnN0IHtcbiAgICB0aW1lb3V0ID0gNTAwMCxcbiAgfSA9IG9wdHM7XG4gIGF3YWl0IHRoaXMuc3RhcnRBcHAoe1xuICAgIHBrZzogU0VUVElOR1NfSEVMUEVSX0lELFxuICAgIGFjdGl2aXR5OiBTRVRUSU5HU19IRUxQRVJfTUFJTl9BQ1RJVklUWSxcbiAgICBhY3Rpb246ICdhbmRyb2lkLmludGVudC5hY3Rpb24uTUFJTicsXG4gICAgY2F0ZWdvcnk6ICdhbmRyb2lkLmludGVudC5jYXRlZ29yeS5MQVVOQ0hFUicsXG4gICAgc3RvcEFwcDogZmFsc2UsXG4gICAgd2FpdEZvckxhdW5jaDogZmFsc2UsXG4gIH0pO1xuICB0cnkge1xuICAgIGF3YWl0IHdhaXRGb3JDb25kaXRpb24oYXN5bmMgKCkgPT4gYXdhaXQgdGhpcy5wcm9jZXNzRXhpc3RzKFNFVFRJTkdTX0hFTFBFUl9JRCksIHtcbiAgICAgIHdhaXRNczogdGltZW91dCxcbiAgICAgIGludGVydmFsTXM6IDMwMCxcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBBcHBpdW0gU2V0dGluZ3MgYXBwIGlzIG5vdCBydW5uaW5nIGFmdGVyICR7dGltZW91dH1tc2ApO1xuICB9XG59O1xuXG4vKipcbiAqIENoYW5nZSB0aGUgc3RhdGUgb2YgV2lGaSBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHBhcmFtIHtib29sZWFufSBvbiAtIFRydWUgdG8gZW5hYmxlIGFuZCBmYWxzZSB0byBkaXNhYmxlIGl0LlxuICogQHBhcmFtIHtib29sZWFufSBpc0VtdWxhdG9yIFtmYWxzZV0gLSBTZXQgaXQgdG8gdHJ1ZSBpZiB0aGUgZGV2aWNlIHVuZGVyIHRlc3RcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgYW4gZW11bGF0b3IgcmF0aGVyIHRoYW4gYSByZWFsIGRldmljZS5cbiAqL1xuY29tbWFuZHMuc2V0V2lmaVN0YXRlID0gYXN5bmMgZnVuY3Rpb24gc2V0V2lmaVN0YXRlIChvbiwgaXNFbXVsYXRvciA9IGZhbHNlKSB7XG4gIGlmIChpc0VtdWxhdG9yKSB7XG4gICAgLy8gVGhlIHN2YyBjb21tYW5kIGRvZXMgbm90IHJlcXVpcmUgdG8gYmUgcm9vdCBzaW5jZSBBUEkgMjZcbiAgICBhd2FpdCB0aGlzLnNoZWxsKFsnc3ZjJywgJ3dpZmknLCBvbiA/ICdlbmFibGUnIDogJ2Rpc2FibGUnXSwge1xuICAgICAgcHJpdmlsZWdlZDogYXdhaXQgdGhpcy5nZXRBcGlMZXZlbCgpIDwgMjYsXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgdGhpcy5zaGVsbChbXG4gICAgICAnYW0nLCAnYnJvYWRjYXN0JyxcbiAgICAgICctYScsIFdJRklfQ09OTkVDVElPTl9TRVRUSU5HX0FDVElPTixcbiAgICAgICctbicsIFdJRklfQ09OTkVDVElPTl9TRVRUSU5HX1JFQ0VJVkVSLFxuICAgICAgJy0tZXMnLCAnc2V0c3RhdHVzJywgb24gPyAnZW5hYmxlJyA6ICdkaXNhYmxlJ1xuICAgIF0pO1xuICB9XG59O1xuXG4vKipcbiAqIENoYW5nZSB0aGUgc3RhdGUgb2YgRGF0YSB0cmFuc2ZlciBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHBhcmFtIHtib29sZWFufSBvbiAtIFRydWUgdG8gZW5hYmxlIGFuZCBmYWxzZSB0byBkaXNhYmxlIGl0LlxuICogQHBhcmFtIHtib29sZWFufSBpc0VtdWxhdG9yIFtmYWxzZV0gLSBTZXQgaXQgdG8gdHJ1ZSBpZiB0aGUgZGV2aWNlIHVuZGVyIHRlc3RcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgYW4gZW11bGF0b3IgcmF0aGVyIHRoYW4gYSByZWFsIGRldmljZS5cbiAqL1xuY29tbWFuZHMuc2V0RGF0YVN0YXRlID0gYXN5bmMgZnVuY3Rpb24gc2V0RGF0YVN0YXRlIChvbiwgaXNFbXVsYXRvciA9IGZhbHNlKSB7XG4gIGlmIChpc0VtdWxhdG9yKSB7XG4gICAgLy8gVGhlIHN2YyBjb21tYW5kIGRvZXMgbm90IHJlcXVpcmUgdG8gYmUgcm9vdCBzaW5jZSBBUEkgMjZcbiAgICBhd2FpdCB0aGlzLnNoZWxsKFsnc3ZjJywgJ2RhdGEnLCBvbiA/ICdlbmFibGUnIDogJ2Rpc2FibGUnXSwge1xuICAgICAgcHJpdmlsZWdlZDogYXdhaXQgdGhpcy5nZXRBcGlMZXZlbCgpIDwgMjYsXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgdGhpcy5zaGVsbChbXG4gICAgICAnYW0nLCAnYnJvYWRjYXN0JyxcbiAgICAgICctYScsIERBVEFfQ09OTkVDVElPTl9TRVRUSU5HX0FDVElPTixcbiAgICAgICctbicsIERBVEFfQ09OTkVDVElPTl9TRVRUSU5HX1JFQ0VJVkVSLFxuICAgICAgJy0tZXMnLCAnc2V0c3RhdHVzJywgb24gPyAnZW5hYmxlJyA6ICdkaXNhYmxlJ1xuICAgIF0pO1xuICB9XG59O1xuXG4vKipcbiAqIENoYW5nZSB0aGUgc3RhdGUgb2YgYW5pbWF0aW9uIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqIEFuaW1hdGlvbiBvbiB0aGUgZGV2aWNlIGlzIGNvbnRyb2xsZWQgYnkgdGhlIGZvbGxvd2luZyBnbG9iYWwgcHJvcGVydGllczpcbiAqIFtBTklNQVRPUl9EVVJBVElPTl9TQ0FMRV17QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIuYW5kcm9pZC5jb20vcmVmZXJlbmNlL2FuZHJvaWQvcHJvdmlkZXIvU2V0dGluZ3MuR2xvYmFsLmh0bWwjQU5JTUFUT1JfRFVSQVRJT05fU0NBTEV9LFxuICogW1RSQU5TSVRJT05fQU5JTUFUSU9OX1NDQUxFXXtAbGluayBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvYW5kcm9pZC9wcm92aWRlci9TZXR0aW5ncy5HbG9iYWwuaHRtbCNUUkFOU0lUSU9OX0FOSU1BVElPTl9TQ0FMRX0sXG4gKiBbV0lORE9XX0FOSU1BVElPTl9TQ0FMRV17QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIuYW5kcm9pZC5jb20vcmVmZXJlbmNlL2FuZHJvaWQvcHJvdmlkZXIvU2V0dGluZ3MuR2xvYmFsLmh0bWwjV0lORE9XX0FOSU1BVElPTl9TQ0FMRX0uXG4gKiBUaGlzIG1ldGhvZCBzZXRzIGFsbCB0aGlzIHByb3BlcnRpZXMgdG8gMC4wIHRvIGRpc2FibGUgKDEuMCB0byBlbmFibGUpIGFuaW1hdGlvbi5cbiAqXG4gKiBUdXJuaW5nIG9mZiBhbmltYXRpb24gbWlnaHQgYmUgdXNlZnVsIHRvIGltcHJvdmUgc3RhYmlsaXR5XG4gKiBhbmQgcmVkdWNlIHRlc3RzIGV4ZWN1dGlvbiB0aW1lLlxuICpcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gb24gLSBUcnVlIHRvIGVuYWJsZSBhbmQgZmFsc2UgdG8gZGlzYWJsZSBpdC5cbiAqL1xuY29tbWFuZHMuc2V0QW5pbWF0aW9uU3RhdGUgPSBhc3luYyBmdW5jdGlvbiBzZXRBbmltYXRpb25TdGF0ZSAob24pIHtcbiAgYXdhaXQgdGhpcy5zaGVsbChbXG4gICAgJ2FtJywgJ2Jyb2FkY2FzdCcsXG4gICAgJy1hJywgQU5JTUFUSU9OX1NFVFRJTkdfQUNUSU9OLFxuICAgICctbicsIEFOSU1BVElPTl9TRVRUSU5HX1JFQ0VJVkVSLFxuICAgICctLWVzJywgJ3NldHN0YXR1cycsIG9uID8gJ2VuYWJsZScgOiAnZGlzYWJsZSdcbiAgXSk7XG59O1xuXG4vKipcbiAqIENoYW5nZSB0aGUgbG9jYWxlIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC4gRG9uJ3QgbmVlZCB0byByZWJvb3QgdGhlIGRldmljZSBhZnRlciBjaGFuZ2luZyB0aGUgbG9jYWxlLlxuICogVGhpcyBtZXRob2Qgc2V0cyBhbiBhcmJpdHJhcnkgbG9jYWxlIGZvbGxvd2luZzpcbiAqICAgaHR0cHM6Ly9kZXZlbG9wZXIuYW5kcm9pZC5jb20vcmVmZXJlbmNlL2phdmEvdXRpbC9Mb2NhbGUuaHRtbFxuICogICBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvamF2YS91dGlsL0xvY2FsZS5odG1sI0xvY2FsZShqYXZhLmxhbmcuU3RyaW5nLCUyMGphdmEubGFuZy5TdHJpbmcpXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGxhbmd1YWdlIC0gTGFuZ3VhZ2UuIGUuZy4gZW4sIGphXG4gKiBAcGFyYW0ge3N0cmluZ30gY291bnRyeSAtIENvdW50cnkuIGUuZy4gVVMsIEpQXG4gKiBAcGFyYW0gez9zdHJpbmd9IHNjcmlwdCAtIFNjcmlwdC4gZS5nLiBIYW5zIGluIGB6aC1IYW5zLUNOYFxuICovXG5jb21tYW5kcy5zZXREZXZpY2VTeXNMb2NhbGVWaWFTZXR0aW5nQXBwID0gYXN5bmMgZnVuY3Rpb24gc2V0RGV2aWNlU3lzTG9jYWxlVmlhU2V0dGluZ0FwcCAobGFuZ3VhZ2UsIGNvdW50cnksIHNjcmlwdCA9IG51bGwpIHtcbiAgY29uc3QgcGFyYW1zID0gW1xuICAgICdhbScsICdicm9hZGNhc3QnLFxuICAgICctYScsIExPQ0FMRV9TRVRUSU5HX0FDVElPTixcbiAgICAnLW4nLCBMT0NBTEVfU0VUVElOR19SRUNFSVZFUixcbiAgICAnLS1lcycsICdsYW5nJywgbGFuZ3VhZ2UudG9Mb3dlckNhc2UoKSxcbiAgICAnLS1lcycsICdjb3VudHJ5JywgY291bnRyeS50b1VwcGVyQ2FzZSgpXG4gIF07XG5cbiAgaWYgKHNjcmlwdCkge1xuICAgIHBhcmFtcy5wdXNoKCctLWVzJywgJ3NjcmlwdCcsIHNjcmlwdCk7XG4gIH1cblxuICBhd2FpdCB0aGlzLnNoZWxsKHBhcmFtcyk7XG59O1xuXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gTG9jYXRpb25cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfHN0cmluZ30gbG9uZ2l0dWRlIC0gVmFsaWQgbG9uZ2l0dWRlIHZhbHVlLlxuICogQHByb3BlcnR5IHtudW1iZXJ8c3RyaW5nfSBsYXRpdHVkZSAtIFZhbGlkIGxhdGl0dWRlIHZhbHVlLlxuICogQHByb3BlcnR5IHs/bnVtYmVyfHN0cmluZ30gYWx0aXR1ZGUgLSBWYWxpZCBhbHRpdHVkZSB2YWx1ZS5cbiAqIEBwcm9wZXJ0eSB7P251bWJlcnxzdHJpbmd9IHNhdGVsbGl0ZXMgWzEyXSAtIE51bWJlciBvZiBzYXRlbGxpdGVzIGJlaW5nIHRyYWNrZWQgKDEtMTIpLlxuICogVGhpcyB2YWx1ZSBpcyBpZ25vcmVkIG9uIHJlYWwgZGV2aWNlcy5cbiAqIEBwcm9wZXJ0eSB7P251bWJlcnxzdHJpbmd9IHNwZWVkIC0gVmFsaWQgc3BlZWQgdmFsdWUuXG4gKiBTaG91bGQgYmUgZ3JlYXRlciB0aGFuIDAuMCBtZXRlcnMvc2Vjb25kIGZvciByZWFsIGRldmljZXMgb3IgMC4wIGtub3RzXG4gKiBmb3IgZW11bGF0b3JzLlxuICovXG5cbi8qKlxuICogRW11bGF0ZSBnZW9sb2NhdGlvbiBjb29yZGluYXRlcyBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHBhcmFtIHtMb2NhdGlvbn0gbG9jYXRpb24gLSBMb2NhdGlvbiBvYmplY3QuIFRoZSBgYWx0aXR1ZGVgIHZhbHVlIGlzIGlnbm9yZWRcbiAqIHdoaWxlIG1vY2tpbmcgdGhlIHBvc2l0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBpc0VtdWxhdG9yIFtmYWxzZV0gLSBTZXQgaXQgdG8gdHJ1ZSBpZiB0aGUgZGV2aWNlIHVuZGVyIHRlc3RcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMgYW4gZW11bGF0b3IgcmF0aGVyIHRoYW4gYSByZWFsIGRldmljZS5cbiAqL1xuY29tbWFuZHMuc2V0R2VvTG9jYXRpb24gPSBhc3luYyBmdW5jdGlvbiBzZXRHZW9Mb2NhdGlvbiAobG9jYXRpb24sIGlzRW11bGF0b3IgPSBmYWxzZSkge1xuICBjb25zdCBmb3JtYXRMb2NhdGlvblZhbHVlID0gKHZhbHVlTmFtZSwgaXNSZXF1aXJlZCA9IHRydWUpID0+IHtcbiAgICBpZiAoIXV0aWwuaGFzVmFsdWUobG9jYXRpb25bdmFsdWVOYW1lXSkpIHtcbiAgICAgIGlmIChpc1JlcXVpcmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt2YWx1ZU5hbWV9IG11c3QgYmUgcHJvdmlkZWRgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCBmbG9hdFZhbHVlID0gcGFyc2VGbG9hdChsb2NhdGlvblt2YWx1ZU5hbWVdKTtcbiAgICBpZiAoIWlzTmFOKGZsb2F0VmFsdWUpKSB7XG4gICAgICByZXR1cm4gYCR7Xy5jZWlsKGZsb2F0VmFsdWUsIDUpfWA7XG4gICAgfVxuICAgIGlmIChpc1JlcXVpcmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dmFsdWVOYW1lfSBpcyBleHBlY3RlZCB0byBiZSBhIHZhbGlkIGZsb2F0IG51bWJlci4gYCArXG4gICAgICAgIGAnJHtsb2NhdGlvblt2YWx1ZU5hbWVdfScgaXMgZ2l2ZW4gaW5zdGVhZGApO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcbiAgY29uc3QgbG9uZ2l0dWRlID0gZm9ybWF0TG9jYXRpb25WYWx1ZSgnbG9uZ2l0dWRlJyk7XG4gIGNvbnN0IGxhdGl0dWRlID0gZm9ybWF0TG9jYXRpb25WYWx1ZSgnbGF0aXR1ZGUnKTtcbiAgY29uc3QgYWx0aXR1ZGUgPSBmb3JtYXRMb2NhdGlvblZhbHVlKCdhbHRpdHVkZScsIGZhbHNlKTtcbiAgY29uc3Qgc3BlZWQgPSBmb3JtYXRMb2NhdGlvblZhbHVlKCdzcGVlZCcsIGZhbHNlKTtcbiAgaWYgKGlzRW11bGF0b3IpIHtcbiAgICBjb25zdCBhcmdzID0gW2xvbmdpdHVkZSwgbGF0aXR1ZGVdO1xuICAgIGlmICghXy5pc05pbChhbHRpdHVkZSkpIHtcbiAgICAgIGFyZ3MucHVzaChhbHRpdHVkZSk7XG4gICAgfVxuICAgIGNvbnN0IHNhdGVsbGl0ZXMgPSBwYXJzZUludChsb2NhdGlvbi5zYXRlbGxpdGVzLCAxMCk7XG4gICAgaWYgKCFOdW1iZXIuaXNOYU4oc2F0ZWxsaXRlcykgJiYgc2F0ZWxsaXRlcyA+IDAgJiYgc2F0ZWxsaXRlcyA8PSAxMikge1xuICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgMykge1xuICAgICAgICBhcmdzLnB1c2goYCR7REVGQVVMVF9BTFRJVFVERX1gKTtcbiAgICAgIH1cbiAgICAgIGFyZ3MucHVzaChgJHtzYXRlbGxpdGVzfWApO1xuICAgIH1cbiAgICBpZiAoIV8uaXNOaWwoc3BlZWQpKSB7XG4gICAgICBpZiAoYXJncy5sZW5ndGggPCAzKSB7XG4gICAgICAgIGFyZ3MucHVzaChgJHtERUZBVUxUX0FMVElUVURFfWApO1xuICAgICAgfVxuICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgNCkge1xuICAgICAgICBhcmdzLnB1c2goYCR7REVGQVVMVF9TQVRFTExJVEVTX0NPVU5UfWApO1xuICAgICAgfVxuICAgICAgYXJncy5wdXNoKHNwZWVkKTtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5yZXNldFRlbG5ldEF1dGhUb2tlbigpO1xuICAgIGF3YWl0IHRoaXMuYWRiRXhlYyhbJ2VtdScsICdnZW8nLCAnZml4JywgLi4uYXJnc10pO1xuICAgIC8vIEEgd29ya2Fyb3VuZCBmb3IgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9hbmRyb2lkL2lzc3Vlcy9kZXRhaWw/aWQ9MjA2MTgwXG4gICAgYXdhaXQgdGhpcy5hZGJFeGVjKFsnZW11JywgJ2dlbycsICdmaXgnLCAuLi4oYXJncy5tYXAoKGFyZykgPT4gYXJnLnJlcGxhY2UoJy4nLCAnLCcpKSldKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBhcmdzID0gW1xuICAgICAgJ2FtJywgJ3N0YXJ0c2VydmljZScsXG4gICAgICAnLWUnLCAnbG9uZ2l0dWRlJywgbG9uZ2l0dWRlLFxuICAgICAgJy1lJywgJ2xhdGl0dWRlJywgbGF0aXR1ZGUsXG4gICAgXTtcbiAgICBpZiAodXRpbC5oYXNWYWx1ZShhbHRpdHVkZSkpIHtcbiAgICAgIGFyZ3MucHVzaCgnLWUnLCAnYWx0aXR1ZGUnLCBhbHRpdHVkZSk7XG4gICAgfVxuICAgIGlmICh1dGlsLmhhc1ZhbHVlKHNwZWVkKSkge1xuICAgICAgYXJncy5wdXNoKCctZScsICdzcGVlZCcsIHNwZWVkKTtcbiAgICB9XG4gICAgYXJncy5wdXNoKExPQ0FUSU9OX1NFUlZJQ0UpO1xuICAgIGF3YWl0IHRoaXMuc2hlbGwoYXJncyk7XG4gIH1cbn07XG5cbi8qKlxuICogR2V0IHRoZSBjdXJyZW50IGNhY2hlZCBHUFMgbG9jYXRpb24gZnJvbSB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHJldHVybnMge0xvY2F0aW9ufSBUaGUgY3VycmVudCBsb2NhdGlvblxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBjdXJyZW50IGxvY2F0aW9uIGNhbm5vdCBiZSByZXRyaWV2ZWRcbiAqL1xuY29tbWFuZHMuZ2V0R2VvTG9jYXRpb24gPSBhc3luYyBmdW5jdGlvbiBnZXRHZW9Mb2NhdGlvbiAoKSB7XG4gIGxldCBvdXRwdXQ7XG4gIHRyeSB7XG4gICAgb3V0cHV0ID0gYXdhaXQgdGhpcy5zaGVsbChbXG4gICAgICAnYW0nLCAnYnJvYWRjYXN0JyxcbiAgICAgICctbicsIExPQ0FUSU9OX1JFQ0VJVkVSLFxuICAgICAgJy1hJywgTE9DQVRJT05fUkVUUklFVkFMX0FDVElPTixcbiAgICBdKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgcmV0cmlldmUgdGhlIGN1cnJlbnQgZ2VvIGNvb3JkaW5hdGVzIGZyb20gdGhlIGRldmljZS4gYCArXG4gICAgICBgTWFrZSBzdXJlIHRoZSBBcHBpdW0gU2V0dGluZ3MgYXBwbGljYXRpb24gaXMgdXAgdG8gZGF0ZSBhbmQgaGFzIGxvY2F0aW9uIHBlcm1pc3Npb25zLiBBbHNvIHRoZSBsb2NhdGlvbiBgICtcbiAgICAgIGBzZXJ2aWNlcyBtdXN0IGJlIGVuYWJsZWQgb24gdGhlIGRldmljZS4gT3JpZ2luYWwgZXJyb3I6ICR7ZXJyLnN0ZGVyciB8fCBlcnIuc3Rkb3V0IHx8IGVyci5tZXNzYWdlfWApO1xuICB9XG5cbiAgY29uc3QgbWF0Y2ggPSBHUFNfQ09PUkRJTkFURVNfUEFUVEVSTi5leGVjKG91dHB1dCk7XG4gIGlmICghbWF0Y2gpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBwYXJzZSB0aGUgYWN0dWFsIGxvY2F0aW9uIHZhbHVlcyBmcm9tIHRoZSBjb21tYW5kIG91dHB1dDogJHtvdXRwdXR9YCk7XG4gIH1cbiAgY29uc3QgbG9jYXRpb24gPSB7XG4gICAgbGF0aXR1ZGU6IG1hdGNoWzFdLFxuICAgIGxvbmdpdHVkZTogbWF0Y2hbMl0sXG4gICAgYWx0aXR1ZGU6IG1hdGNoWzNdLFxuICB9O1xuICBsb2cuZGVidWcoYEdvdCBnZW8gY29vcmRpbmF0ZXM6ICR7SlNPTi5zdHJpbmdpZnkobG9jYXRpb24pfWApO1xuICByZXR1cm4gbG9jYXRpb247XG59O1xuXG4vKipcbiAqIFNlbmRzIGFuIGFzeW5jIHJlcXVlc3QgdG8gcmVmcmVzaCB0aGUgR1BTIGNhY2hlLlxuICogVGhpcyBmZWF0dXJlIG9ubHkgd29ya3MgaWYgdGhlIGRldmljZSB1bmRlciB0ZXN0IGhhc1xuICogR29vZ2xlIFBsYXkgU2VydmljZXMgaW5zdGFsbGVkLiBJbiBjYXNlIHRoZSB2YW5pbGxhXG4gKiBMb2NhdGlvbk1hbmFnZXIgaXMgdXNlZCB0aGUgZGV2aWNlIEFQSSBsZXZlbCBtdXN0IGJlIGF0XG4gKiB2ZXJzaW9uIDMwIChBbmRyb2lkIFIpIG9yIGhpZ2hlci5cbiAqXG4gKiBAcGFyYW0gdGltZW91dE1zIFsyMDAwMF0gVGhlIG1heGltdW0gbnVtYmVyIG9mIG1pbGxpc2Vjb25kc1xuICogdG8gYmxvY2sgdW50aWwgR1BTIGNhY2hlIGlzIHJlZnJlc2hlZC4gUHJvdmlkaW5nIHplcm8gb3IgYSBuZWdhdGl2ZVxuICogdmFsdWUgdG8gaXQgc2tpcHMgd2FpdGluZyBjb21wbGV0ZWx5LlxuICpcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgR1BTIGNhY2hlIGNhbm5vdCBiZSByZWZyZXNoZWQuXG4gKi9cbmNvbW1hbmRzLnJlZnJlc2hHZW9Mb2NhdGlvbkNhY2hlID0gYXN5bmMgZnVuY3Rpb24gcmVmcmVzaEdlb0xvY2F0aW9uQ2FjaGUgKHRpbWVvdXRNcyA9IDIwMDAwKSB7XG4gIGxldCBsb2djYXRNb25pdG9yO1xuICBsZXQgbW9uaXRvcmluZ1Byb21pc2U7XG5cbiAgaWYgKHRpbWVvdXRNcyA+IDApIHtcbiAgICBjb25zdCBjbWQgPSBbXG4gICAgICAuLi50aGlzLmFkYi5kZWZhdWx0QXJncyxcbiAgICAgICdsb2djYXQnLCAnLXMnLCBMT0NBVElPTl9UUkFDS0VSX1RBRyxcbiAgICBdO1xuICAgIGxvZ2NhdE1vbml0b3IgPSBuZXcgU3ViUHJvY2Vzcyh0aGlzLmFkYi5wYXRoLCBjbWQpO1xuICAgIGNvbnN0IHRpbWVvdXRFcnJvck1zZyA9IGBUaGUgR1BTIGNhY2hlIGhhcyBub3QgYmVlbiByZWZyZXNoZWQgd2l0aGluICR7dGltZW91dE1zfW1zIHRpbWVvdXQuIGAgK1xuICAgICAgYFBsZWFzZSBtYWtlIHN1cmUgdGhlIGRldmljZSB1bmRlciB0ZXN0IGhhcyBBcHBpdW0gU2V0dGluZ3MgYXBwIGluc3RhbGxlZCBhbmQgcnVubmluZy4gYCArXG4gICAgICBgQWxzbywgaXQgaXMgcmVxdWlyZWQgdGhhdCB0aGUgZGV2aWNlIGhhcyBHb29nbGUgUGxheSBTZXJ2aWNlcyBpbnN0YWxsZWQgb3IgaXMgcnVubmluZyBgICtcbiAgICAgIGBBbmRyb2lkIDEwKyBvdGhlcndpc2UuYDtcbiAgICBtb25pdG9yaW5nUHJvbWlzZSA9IG5ldyBCKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcih0aW1lb3V0RXJyb3JNc2cpKSwgdGltZW91dE1zKTtcblxuICAgICAgbG9nY2F0TW9uaXRvci5vbignZXhpdCcsICgpID0+IHJlamVjdChuZXcgRXJyb3IodGltZW91dEVycm9yTXNnKSkpO1xuICAgICAgWydsaW5lcy1zdGRlcnInLCAnbGluZXMtc3Rkb3V0J10ubWFwKChldnQpID0+IGxvZ2NhdE1vbml0b3Iub24oZXZ0LCAobGluZXMpID0+IHtcbiAgICAgICAgaWYgKGxpbmVzLnNvbWUoKGxpbmUpID0+IEdQU19DQUNIRV9SRUZSRVNIRURfTE9HUy5zb21lKCh4KSA9PiBsaW5lLmluY2x1ZGVzKHgpKSkpIHtcbiAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pKTtcbiAgICB9KTtcbiAgICBhd2FpdCBsb2djYXRNb25pdG9yLnN0YXJ0KDApO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCB0aGlzLnNoZWxsKFtcbiAgICAgICdhbScsICdicm9hZGNhc3QnLFxuICAgICAgJy1uJywgTE9DQVRJT05fUkVDRUlWRVIsXG4gICAgICAnLWEnLCBMT0NBVElPTl9SRVRSSUVWQUxfQUNUSU9OLFxuICAgICAgJy0tZXonLCAnZm9yY2VVcGRhdGUnLCAndHJ1ZScsXG4gICAgXSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHJlZnJlc2ggdGhlIEdQUyBjYWNoZSBvbiB0aGUgZGV2aWNlLiBgICtcbiAgICAgIGBNYWtlIHN1cmUgdGhlIEFwcGl1bSBTZXR0aW5ncyBhcHBsaWNhdGlvbiBpcyB1cCB0byBkYXRlIGFuZCBoYXMgbG9jYXRpb24gcGVybWlzc2lvbnMuIEFsc28gdGhlIGxvY2F0aW9uIGAgK1xuICAgICAgYHNlcnZpY2VzIG11c3QgYmUgZW5hYmxlZCBvbiB0aGUgZGV2aWNlLiBPcmlnaW5hbCBlcnJvcjogJHtlcnIuc3RkZXJyIHx8IGVyci5zdGRvdXQgfHwgZXJyLm1lc3NhZ2V9YCk7XG4gIH1cblxuICBpZiAobG9nY2F0TW9uaXRvciAmJiBtb25pdG9yaW5nUHJvbWlzZSkge1xuICAgIGNvbnN0IHRpbWVyID0gbmV3IHRpbWluZy5UaW1lcigpLnN0YXJ0KCk7XG4gICAgbG9nLmRlYnVnKGBXYWl0aW5nIHVwIHRvICR7dGltZW91dE1zfW1zIGZvciB0aGUgR1BTIGNhY2hlIHRvIGJlIHJlZnJlc2hlZGApO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBtb25pdG9yaW5nUHJvbWlzZTtcbiAgICAgIGxvZy5pbmZvKGBUaGUgR1BTIGNhY2hlIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSByZWZyZXNoZWQgYWZ0ZXIgYCArXG4gICAgICAgIGAke3RpbWVyLmdldER1cmF0aW9uKCkuYXNNaWxsaVNlY29uZHMudG9GaXhlZCgwKX1tc2ApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAobG9nY2F0TW9uaXRvci5pc1J1bm5pbmcpIHtcbiAgICAgICAgYXdhaXQgbG9nY2F0TW9uaXRvci5zdG9wKCk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGxvZy5pbmZvKCdUaGUgcmVxdWVzdCB0byByZWZyZXNoIHRoZSBHUFMgY2FjaGUgaGFzIGJlZW4gc2VudC4gU2tpcHBpbmcgd2FpdGluZyBmb3IgaXRzIHJlc3VsdC4nKTtcbiAgfVxufTtcblxuLyoqXG4gKiBQZXJmb3JtcyB0aGUgZ2l2ZW4gZWRpdG9yIGFjdGlvbiBvbiB0aGUgZm9jdXNlZCBpbnB1dCBmaWVsZC5cbiAqIFRoaXMgbWV0aG9kIHJlcXVpcmVzIEFwcGl1bSBTZXR0aW5ncyBoZWxwZXIgdG8gYmUgaW5zdGFsbGVkIG9uIHRoZSBkZXZpY2UuXG4gKiBObyBleGNlcHRpb24gaXMgdGhyb3duIGlmIHRoZXJlIHdhcyBhIGZhaWx1cmUgd2hpbGUgcGVyZm9ybWluZyB0aGUgYWN0aW9uLlxuICogWW91IG11c3QgaW52ZXN0aWdhdGUgdGhlIGxvZ2NhdCBvdXRwdXQgaWYgc29tZXRoaW5nIGRpZCBub3Qgd29yayBhcyBleHBlY3RlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGFjdGlvbiAtIEVpdGhlciBhY3Rpb24gY29kZSBvciBuYW1lLiBUaGUgZm9sbG93aW5nIGFjdGlvblxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcyBhcmUgc3VwcG9ydGVkOiBgbm9ybWFsLCB1bnNwZWNpZmllZCwgbm9uZSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ28sIHNlYXJjaCwgc2VuZCwgbmV4dCwgZG9uZSwgcHJldmlvdXNgXG4gKi9cbmNvbW1hbmRzLnBlcmZvcm1FZGl0b3JBY3Rpb24gPSBhc3luYyBmdW5jdGlvbiBwZXJmb3JtRWRpdG9yQWN0aW9uIChhY3Rpb24pIHtcbiAgbG9nLmRlYnVnKGBQZXJmb3JtaW5nIGVkaXRvciBhY3Rpb246ICR7YWN0aW9ufWApO1xuICBhd2FpdCB0aGlzLnJ1bkluSW1lQ29udGV4dChBUFBJVU1fSU1FLFxuICAgIGFzeW5jICgpID0+IGF3YWl0IHRoaXMuc2hlbGwoWydpbnB1dCcsICd0ZXh0JywgYC8ke2FjdGlvbn0vYF0pKTtcbn07XG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhlIGRldmljZSdzIGNsaXBib2FyZC5cbiAqIFRoZSBtZXRob2Qgd29ya3MgZm9yIEFuZHJvaWQgYmVsb3cgYW5kIGFib3ZlIDI5LlxuICogSXQgdGVtb3JhcmlseSBlbmZvcmNlcyB0aGUgSU1FIHNldHRpbmcgaW4gb3JkZXIgdG8gd29ya2Fyb3VuZFxuICogc2VjdXJpdHkgbGltaXRhdGlvbnMgaWYgbmVlZGVkLlxuICogVGhpcyBtZXRob2Qgb25seSB3b3JrcyBpZiBBcHBpdW0gU2V0dGluZ3Mgdi4gMi4xNSsgaXMgaW5zdGFsbGVkXG4gKiBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYWN0dWFsIGNvbnRlbnQgb2YgdGhlIG1haW4gY2xpcGJvYXJkIGFzXG4gKiBiYXNlNjQtZW5jb2RlZCBzdHJpbmcgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIHRoZSBjbGlwYm9hcmQgaXMgZW1wdHlcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGVyZSB3YXMgYSBwcm9ibGVtIHdoaWxlIGdldHRpbmcgdGhlXG4gKiBjbGlwYm9hcmQgY29udGFudFxuICovXG5jb21tYW5kcy5nZXRDbGlwYm9hcmQgPSBhc3luYyBmdW5jdGlvbiBnZXRDbGlwYm9hcmQgKCkge1xuICBsb2cuZGVidWcoJ0dldHRpbmcgdGhlIGNsaXBib2FyZCBjb250ZW50Jyk7XG4gIGNvbnN0IHJldHJpZXZlQ2xpcGJvYXJkID0gYXN5bmMgKCkgPT4gYXdhaXQgdGhpcy5zaGVsbChbXG4gICAgJ2FtJywgJ2Jyb2FkY2FzdCcsXG4gICAgJy1uJywgQ0xJUEJPQVJEX1JFQ0VJVkVSLFxuICAgICctYScsIENMSVBCT0FSRF9SRVRSSUVWQUxfQUNUSU9OLFxuICBdKTtcbiAgbGV0IG91dHB1dDtcbiAgdHJ5IHtcbiAgICBvdXRwdXQgPSAoYXdhaXQgdGhpcy5nZXRBcGlMZXZlbCgpID49IDI5KVxuICAgICAgPyAoYXdhaXQgdGhpcy5ydW5JbkltZUNvbnRleHQoQVBQSVVNX0lNRSwgcmV0cmlldmVDbGlwYm9hcmQpKVxuICAgICAgOiAoYXdhaXQgcmV0cmlldmVDbGlwYm9hcmQoKSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHJldHJpZXZlIHRoZSBjdXJyZW50IGNsaXBib2FyZCBjb250ZW50IGZyb20gdGhlIGRldmljZS4gYCArXG4gICAgICBgTWFrZSBzdXJlIHRoZSBBcHBpdW0gU2V0dGluZ3MgYXBwbGljYXRpb24gaXMgdXAgdG8gZGF0ZS4gYCArXG4gICAgICBgT3JpZ2luYWwgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gIH1cblxuICBjb25zdCBtYXRjaCA9IC9kYXRhPVwiKFteXCJdKilcIi8uZXhlYyhvdXRwdXQpO1xuICBpZiAoIW1hdGNoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgcGFyc2UgdGhlIGFjdHVhbCBjbGlib2FyZCBjb250ZW50IGZyb20gdGhlIGNvbW1hbmQgb3V0cHV0OiAke291dHB1dH1gKTtcbiAgfVxuICByZXR1cm4gXy50cmltKG1hdGNoWzFdKTtcbn07XG5cbi8qKlxuICogUmV0cmlldmVzIEFuZHJvaWQgbm90aWZpY2F0aW9ucyB2aWEgQXBwaXVtIFNldHRpbmdzIGhlbHBlci5cbiAqIEFwcGl1bSBTZXR0aW5ncyBhcHAgaXRzZWxmIG11c3QgYmUgKm1hbnVhbGx5KiBncmFudGVkIHRvIGFjY2VzcyBub3RpZmljYXRpb25zXG4gKiB1bmRlciBkZXZpY2UgU2V0dGluZ3MgaW4gb3JkZXIgdG8gbWFrZSB0aGlzIGZlYXR1cmUgd29ya2luZy5cbiAqIEFwcGl1bSBTZXR0aW5ncyBoZWxwZXIga2VlcHMgYWxsIHRoZSBhY3RpdmUgbm90aWZpY2F0aW9ucyBwbHVzXG4gKiBub3RpZmljYXRpb25zIHRoYXQgYXBwZWFyZWQgd2hpbGUgaXQgd2FzIHJ1bm5pbmcgaW4gdGhlIGludGVybmFsIGJ1ZmZlcixcbiAqIGJ1dCBubyBtb3JlIHRoYW4gMTAwIGl0ZW1zIGFsdG9nZXRoZXIuIE5ld2x5IGFwcGVhcmVkIG5vdGlmaWNhdGlvbnNcbiAqIGFyZSBhbHdheXMgYWRkZWQgdG8gdGhlIGhlYWQgb2YgdGhlIG5vdGlmaWNhdGlvbnMgYXJyYXkuXG4gKiBUaGUgYGlzUmVtb3ZlZGAgZmxhZyBpcyBzZXQgdG8gYHRydWVgIGZvciBub3RpZmljYXRpb25zIHRoYXQgaGF2ZSBiZWVuIHJlbW92ZWQuXG4gKlxuICogU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLmFuZHJvaWQuY29tL3JlZmVyZW5jZS9hbmRyb2lkL3NlcnZpY2Uvbm90aWZpY2F0aW9uL1N0YXR1c0Jhck5vdGlmaWNhdGlvblxuICogYW5kIGh0dHBzOi8vZGV2ZWxvcGVyLmFuZHJvaWQuY29tL3JlZmVyZW5jZS9hbmRyb2lkL2FwcC9Ob3RpZmljYXRpb24uaHRtbFxuICogZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gYXZhaWxhYmxlIG5vdGlmaWNhdGlvbiBwcm9wZXJ0aWVzIGFuZCB0aGVpciB2YWx1ZXMuXG4gKlxuICogQHJldHVybnMge09iamVjdH0gVGhlIGV4YW1wbGUgb3V0cHV0IGlzOlxuICogYGBganNvblxuICoge1xuICogICBcInN0YXR1c0Jhck5vdGlmaWNhdGlvbnNcIjpbXG4gKiAgICAge1xuICogICAgICAgXCJpc0dyb3VwXCI6ZmFsc2UsXG4gKiAgICAgICBcInBhY2thZ2VOYW1lXCI6XCJpby5hcHBpdW0uc2V0dGluZ3NcIixcbiAqICAgICAgIFwiaXNDbGVhcmFibGVcIjpmYWxzZSxcbiAqICAgICAgIFwiaXNPbmdvaW5nXCI6dHJ1ZSxcbiAqICAgICAgIFwiaWRcIjoxLFxuICogICAgICAgXCJ0YWdcIjpudWxsLFxuICogICAgICAgXCJub3RpZmljYXRpb25cIjp7XG4gKiAgICAgICAgIFwidGl0bGVcIjpudWxsLFxuICogICAgICAgICBcImJpZ1RpdGxlXCI6XCJBcHBpdW0gU2V0dGluZ3NcIixcbiAqICAgICAgICAgXCJ0ZXh0XCI6bnVsbCxcbiAqICAgICAgICAgXCJiaWdUZXh0XCI6XCJLZWVwIHRoaXMgc2VydmljZSBydW5uaW5nLCBzbyBBcHBpdW0gZm9yIEFuZHJvaWQgY2FuIHByb3Blcmx5IGludGVyYWN0IHdpdGggc2V2ZXJhbCBzeXN0ZW0gQVBJc1wiLFxuICogICAgICAgICBcInRpY2tlclRleHRcIjpudWxsLFxuICogICAgICAgICBcInN1YlRleHRcIjpudWxsLFxuICogICAgICAgICBcImluZm9UZXh0XCI6bnVsbCxcbiAqICAgICAgICAgXCJ0ZW1wbGF0ZVwiOlwiYW5kcm9pZC5hcHAuTm90aWZpY2F0aW9uJEJpZ1RleHRTdHlsZVwiXG4gKiAgICAgICB9LFxuICogICAgICAgXCJ1c2VySGFuZGxlXCI6MCxcbiAqICAgICAgIFwiZ3JvdXBLZXlcIjpcIjB8aW8uYXBwaXVtLnNldHRpbmdzfDF8bnVsbHwxMDEzM1wiLFxuICogICAgICAgXCJvdmVycmlkZUdyb3VwS2V5XCI6bnVsbCxcbiAqICAgICAgIFwicG9zdFRpbWVcIjoxNTc2ODUzNTE4ODUwLFxuICogICAgICAgXCJrZXlcIjpcIjB8aW8uYXBwaXVtLnNldHRpbmdzfDF8bnVsbHwxMDEzM1wiLFxuICogICAgICAgXCJpc1JlbW92ZWRcIjpmYWxzZVxuICogICAgIH1cbiAqICAgXVxuICogfVxuICogYGBgXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlcmUgd2FzIGFuIGVycm9yIHdoaWxlIGdldHRpbmcgdGhlIG5vdGlmaWNhdGlvbnMgbGlzdFxuICovXG5jb21tYW5kcy5nZXROb3RpZmljYXRpb25zID0gYXN5bmMgZnVuY3Rpb24gZ2V0Tm90aWZpY2F0aW9ucyAoKSB7XG4gIGxvZy5kZWJ1ZygnUmV0cmlldmluZyBub3RpZmljYXRpb25zJyk7XG4gIC8vIFNvbWVob3cgcHJvdmlkaW5nIHRoZSBgLW5gIGFyZyB0byB0aGUgYGFtYCB1bmRlcm5lYXRoXG4gIC8vIHJlbmRlcnMgdGhlIGJyb2FkY2FzdCB0byBmYWlsIGluc3RlYWQgb2Ygc3RhcnRpbmcgdGhlXG4gIC8vIEFwcGl1bSBTZXR0aW5ncyBhcHAuIFRoaXMgb25seSBoYXBwZW5zIHRvIHRoZSBub3RpZmljYXRpb25zXG4gIC8vIHJlY2VpdmVyXG4gIGF3YWl0IHRoaXMucmVxdWlyZVJ1bm5pbmdTZXR0aW5nc0FwcCgpO1xuICBsZXQgb3V0cHV0O1xuICB0cnkge1xuICAgIG91dHB1dCA9IGF3YWl0IHRoaXMuc2hlbGwoW1xuICAgICAgJ2FtJywgJ2Jyb2FkY2FzdCcsXG4gICAgICAnLWEnLCBOT1RJRklDQVRJT05TX1JFVFJJRVZBTF9BQ1RJT04sXG4gICAgXSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHJldHJpZXZlIG5vdGlmaWNhdGlvbnMgZnJvbSB0aGUgZGV2aWNlLiBgICtcbiAgICAgIGBNYWtlIHN1cmUgdGhlIEFwcGl1bSBTZXR0aW5ncyBhcHBsaWNhdGlvbiBpcyBpbnN0YWxsZWQgYW5kIGlzIHVwIHRvIGRhdGUuIGAgK1xuICAgICAgYE9yaWdpbmFsIGVycm9yOiAke2Vyci5tZXNzYWdlfWApO1xuICB9XG4gIHJldHVybiBwYXJzZUpzb25EYXRhKG91dHB1dCwgJ25vdGlmaWNhdGlvbnMnKTtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gU21zTGlzdE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtYXggWzEwMF0gLSBUaGUgbWF4aW11bSBjb3VudCBvZiByZWNlbnQgbWVzc2FnZXNcbiAqIHRvIHJldHJpZXZlXG4gKi9cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGxpc3Qgb2YgdGhlIG1vc3QgcmVjZW50IFNNU1xuICogcHJvcGVydGllcyBsaXN0IHZpYSBBcHBpdW0gU2V0dGluZ3MgaGVscGVyLlxuICogTWVzc2FnZXMgYXJlIHNvcnRlZCBieSBkYXRlIGluIGRlc2NlbmRpbmcgb3JkZXIuXG4gKlxuICogQHBhcmFtIHtTbXNMaXN0T3B0aW9uc30gb3B0c1xuICogQHJldHVybnMge09iamVjdH0gVGhlIGV4YW1wbGUgb3V0cHV0IGlzOlxuICogYGBganNvblxuICoge1xuICogICBcIml0ZW1zXCI6W1xuICogICAgIHtcbiAqICAgICAgIFwiaWRcIjpcIjJcIixcbiAqICAgICAgIFwiYWRkcmVzc1wiOlwiKzEyMzQ1Njc4OVwiLFxuICogICAgICAgXCJwZXJzb25cIjpudWxsLFxuICogICAgICAgXCJkYXRlXCI6XCIxNTgxOTM2NDIyMjAzXCIsXG4gKiAgICAgICBcInJlYWRcIjpcIjBcIixcbiAqICAgICAgIFwic3RhdHVzXCI6XCItMVwiLFxuICogICAgICAgXCJ0eXBlXCI6XCIxXCIsXG4gKiAgICAgICBcInN1YmplY3RcIjpudWxsLFxuICogICAgICAgXCJib2R5XCI6XCJcXFwidGV4dCBtZXNzYWdlMlxcXCJcIixcbiAqICAgICAgIFwic2VydmljZUNlbnRlclwiOm51bGxcbiAqICAgICB9LFxuICogICAgIHtcbiAqICAgICAgIFwiaWRcIjpcIjFcIixcbiAqICAgICAgIFwiYWRkcmVzc1wiOlwiKzEyMzQ1Njc4OVwiLFxuICogICAgICAgXCJwZXJzb25cIjpudWxsLFxuICogICAgICAgXCJkYXRlXCI6XCIxNTgxOTM2MzgyNzQwXCIsXG4gKiAgICAgICBcInJlYWRcIjpcIjBcIixcbiAqICAgICAgIFwic3RhdHVzXCI6XCItMVwiLFxuICogICAgICAgXCJ0eXBlXCI6XCIxXCIsXG4gKiAgICAgICBcInN1YmplY3RcIjpudWxsLFxuICogICAgICAgXCJib2R5XCI6XCJcXFwidGV4dCBtZXNzYWdlXFxcIlwiLFxuICogICAgICAgXCJzZXJ2aWNlQ2VudGVyXCI6bnVsbFxuICogICAgIH1cbiAqICAgXSxcbiAqICAgXCJ0b3RhbFwiOjJcbiAqIH1cbiAqIGBgYFxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSBnZXR0aW5nIHRoZSBTTVMgbGlzdFxuICovXG5jb21tYW5kcy5nZXRTbXNMaXN0ID0gYXN5bmMgZnVuY3Rpb24gZ2V0U21zTGlzdCAob3B0cyA9IHt9KSB7XG4gIGxvZy5kZWJ1ZygnUmV0cmlldmluZyB0aGUgcmVjZW50IFNNUyBtZXNzYWdlcycpO1xuICBjb25zdCBhcmdzID0gW1xuICAgICdhbScsICdicm9hZGNhc3QnLFxuICAgICctbicsIFNNU19MSVNUX1JFQ0VJVkVSLFxuICAgICctYScsIFNNU19MSVNUX1JFVFJJRVZBTF9BQ1RJT04sXG4gIF07XG4gIGlmIChvcHRzLm1heCkge1xuICAgIGFyZ3MucHVzaCgnLS1lcycsICdtYXgnLCBvcHRzLm1heCk7XG4gIH1cbiAgbGV0IG91dHB1dDtcbiAgdHJ5IHtcbiAgICBvdXRwdXQgPSBhd2FpdCB0aGlzLnNoZWxsKGFyZ3MpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCByZXRyaWV2ZSBTTVMgbGlzdCBmcm9tIHRoZSBkZXZpY2UuIGAgK1xuICAgICAgYE1ha2Ugc3VyZSB0aGUgQXBwaXVtIFNldHRpbmdzIGFwcGxpY2F0aW9uIGlzIGluc3RhbGxlZCBhbmQgaXMgdXAgdG8gZGF0ZS4gYCArXG4gICAgICBgT3JpZ2luYWwgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gIH1cbiAgcmV0dXJuIHBhcnNlSnNvbkRhdGEob3V0cHV0LCAnU01TIGxpc3QnKTtcbn07XG5cbi8qKlxuICogVHlwZXMgdGhlIGdpdmVuIFVuaWNvZGUgc3RyaW5nLlxuICogSXQgaXMgZXhwZWN0ZWQgdGhhdCB0aGUgZm9jdXMgaXMgYWxyZWFkeSBwdXRcbiAqIHRvIHRoZSBkZXN0aW5hdGlvbiBpbnB1dCBmaWVsZCBiZWZvcmUgdGhpcyBtZXRob2QgaXMgY2FsbGVkLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IFRoZSBzdHJpbmcgdG8gdHlwZVxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgaW5wdXQgdGV4dCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgc2VudCB0byBhZGJcbiAqL1xuY29tbWFuZHMudHlwZVVuaWNvZGUgPSBhc3luYyBmdW5jdGlvbiB0eXBlVW5pY29kZSAodGV4dCkge1xuICBpZiAoXy5pc05pbCh0ZXh0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHRleHQgPSBgJHt0ZXh0fWA7XG4gIGxvZy5kZWJ1ZyhgVHlwaW5nICR7dXRpbC5wbHVyYWxpemUoJ2NoYXJhY3RlcicsIHRleHQubGVuZ3RoLCB0cnVlKX1gKTtcbiAgaWYgKCF0ZXh0KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGF3YWl0IHRoaXMucnVuSW5JbWVDb250ZXh0KFxuICAgIFVOSUNPREVfSU1FLCBhc3luYyAoKSA9PiBhd2FpdCB0aGlzLmlucHV0VGV4dChpbWFwLmVuY29kZSh0ZXh0KSlcbiAgKTtcbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIFBlcmZvcm1zIHJlY3Vyc2l2ZSBtZWRpYSBzY2FuIGF0IHRoZSBnaXZlbiBkZXN0aW5hdGlvbi5cbiAqIEFsbCBzdWNjZXNzZnVsbHkgc2Nhbm5lZCBpdGVtcyBhcmUgYmVpbmcgYWRkZWQgdG8gdGhlIGRldmljZSdzXG4gKiBtZWRpYSBsaWJyYXJ5LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBkZXN0aW5hdGlvbiBGaWxlL2ZvbGRlciBwYXRoIG9uIHRoZSByZW1vdGUgZGV2aWNlLlxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZXJlIHdhcyBhbiB1bmV4cGVjdGVkIGVycm9yIGJ5IHNjYW5uaW5nLlxuICovXG5jb21tYW5kcy5zY2FuTWVkaWEgPSBhc3luYyBmdW5jdGlvbiBzY2FuTWVkaWEgKGRlc3RpbmF0aW9uKSB7XG4gIGxvZy5kZWJ1ZyhgU2Nhbm5pbmcgJyR7ZGVzdGluYXRpb259JyBmb3IgbWVkaWEgZmlsZXNgKTtcbiAgY29uc3Qgb3V0cHV0ID0gYXdhaXQgdGhpcy5zaGVsbChbXG4gICAgJ2FtJywgJ2Jyb2FkY2FzdCcsXG4gICAgJy1uJywgTUVESUFfU0NBTl9SRUNFSVZFUixcbiAgICAnLWEnLCBNRURJQV9TQ0FOX0FDVElPTixcbiAgICAnLS1lcycsICdwYXRoJywgZGVzdGluYXRpb25cbiAgXSk7XG4gIGlmICghXy5pbmNsdWRlcyhvdXRwdXQsICdyZXN1bHQ9LTEnKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgTm8gbWVkaWEgY291bGQgYmUgc2Nhbm5lZCBhdCAnJHtkZXN0aW5hdGlvbn0nLiBgICtcbiAgICAgIGBDaGVjayB0aGUgZGV2aWNlIGxvZ2NhdCBvdXRwdXQgZm9yIG1vcmUgZGV0YWlscy5gKTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgY29tbWFuZHM7XG4iXSwiZmlsZSI6ImxpYi90b29scy9zZXR0aW5ncy1jbGllbnQtY29tbWFuZHMuanMiLCJzb3VyY2VSb290IjoiLi4vLi4vLi4ifQ==
@@ -1,9 +1,11 @@
1
1
  import log from '../logger.js';
2
2
  import { parseJsonData } from '../helpers.js';
3
3
  import _ from 'lodash';
4
- import { util } from 'appium-support';
4
+ import { util, timing } from 'appium-support';
5
5
  import { waitForCondition } from 'asyncbox';
6
6
  import { imap } from 'utf7';
7
+ import { SubProcess } from 'teen_process';
8
+ import B from 'bluebird';
7
9
 
8
10
  const SETTINGS_HELPER_ID = 'io.appium.settings';
9
11
  const SETTINGS_HELPER_MAIN_ACTIVITY = '.Settings';
@@ -29,7 +31,13 @@ const APPIUM_IME = `${SETTINGS_HELPER_ID}/.AppiumIME`;
29
31
  const UNICODE_IME = `${SETTINGS_HELPER_ID}/.UnicodeIME`;
30
32
  const DEFAULT_SATELLITES_COUNT = 12;
31
33
  const DEFAULT_ALTITUDE = 0.0;
34
+ const LOCATION_TRACKER_TAG = 'LocationTracker';
35
+ const GPS_CACHE_REFRESHED_LOGS = [
36
+ 'The current location has been successfully retrieved from Play Services',
37
+ 'The current location has been successfully retrieved from Location Manager'
38
+ ];
32
39
 
40
+ const GPS_COORDINATES_PATTERN = /data="(-?[\d.]+)\s+(-?[\d.]+)\s+(-?[\d.]+)"/;
33
41
 
34
42
  const commands = {};
35
43
 
@@ -255,7 +263,7 @@ commands.setGeoLocation = async function setGeoLocation (location, isEmulator =
255
263
  };
256
264
 
257
265
  /**
258
- * Get the current geo location from the device under test.
266
+ * Get the current cached GPS location from the device under test.
259
267
  *
260
268
  * @returns {Location} The current location
261
269
  * @throws {Error} If the current location cannot be retrieved
@@ -271,10 +279,10 @@ commands.getGeoLocation = async function getGeoLocation () {
271
279
  } catch (err) {
272
280
  throw new Error(`Cannot retrieve the current geo coordinates from the device. ` +
273
281
  `Make sure the Appium Settings application is up to date and has location permissions. Also the location ` +
274
- `services must be enabled on the device. Original error: ${err.message}`);
282
+ `services must be enabled on the device. Original error: ${err.stderr || err.stdout || err.message}`);
275
283
  }
276
284
 
277
- const match = /data="(-?[\d.]+)\s+(-?[\d.]+)\s+(-?[\d.]+)"/.exec(output);
285
+ const match = GPS_COORDINATES_PATTERN.exec(output);
278
286
  if (!match) {
279
287
  throw new Error(`Cannot parse the actual location values from the command output: ${output}`);
280
288
  }
@@ -287,6 +295,76 @@ commands.getGeoLocation = async function getGeoLocation () {
287
295
  return location;
288
296
  };
289
297
 
298
+ /**
299
+ * Sends an async request to refresh the GPS cache.
300
+ * This feature only works if the device under test has
301
+ * Google Play Services installed. In case the vanilla
302
+ * LocationManager is used the device API level must be at
303
+ * version 30 (Android R) or higher.
304
+ *
305
+ * @param timeoutMs [20000] The maximum number of milliseconds
306
+ * to block until GPS cache is refreshed. Providing zero or a negative
307
+ * value to it skips waiting completely.
308
+ *
309
+ * @throws {Error} If the GPS cache cannot be refreshed.
310
+ */
311
+ commands.refreshGeoLocationCache = async function refreshGeoLocationCache (timeoutMs = 20000) {
312
+ let logcatMonitor;
313
+ let monitoringPromise;
314
+
315
+ if (timeoutMs > 0) {
316
+ const cmd = [
317
+ ...this.adb.defaultArgs,
318
+ 'logcat', '-s', LOCATION_TRACKER_TAG,
319
+ ];
320
+ logcatMonitor = new SubProcess(this.adb.path, cmd);
321
+ const timeoutErrorMsg = `The GPS cache has not been refreshed within ${timeoutMs}ms timeout. ` +
322
+ `Please make sure the device under test has Appium Settings app installed and running. ` +
323
+ `Also, it is required that the device has Google Play Services installed or is running ` +
324
+ `Android 10+ otherwise.`;
325
+ monitoringPromise = new B((resolve, reject) => {
326
+ setTimeout(() => reject(new Error(timeoutErrorMsg)), timeoutMs);
327
+
328
+ logcatMonitor.on('exit', () => reject(new Error(timeoutErrorMsg)));
329
+ ['lines-stderr', 'lines-stdout'].map((evt) => logcatMonitor.on(evt, (lines) => {
330
+ if (lines.some((line) => GPS_CACHE_REFRESHED_LOGS.some((x) => line.includes(x)))) {
331
+ resolve();
332
+ }
333
+ }));
334
+ });
335
+ await logcatMonitor.start(0);
336
+ }
337
+
338
+ try {
339
+ await this.shell([
340
+ 'am', 'broadcast',
341
+ '-n', LOCATION_RECEIVER,
342
+ '-a', LOCATION_RETRIEVAL_ACTION,
343
+ '--ez', 'forceUpdate', 'true',
344
+ ]);
345
+ } catch (err) {
346
+ throw new Error(`Cannot refresh the GPS cache on the device. ` +
347
+ `Make sure the Appium Settings application is up to date and has location permissions. Also the location ` +
348
+ `services must be enabled on the device. Original error: ${err.stderr || err.stdout || err.message}`);
349
+ }
350
+
351
+ if (logcatMonitor && monitoringPromise) {
352
+ const timer = new timing.Timer().start();
353
+ log.debug(`Waiting up to ${timeoutMs}ms for the GPS cache to be refreshed`);
354
+ try {
355
+ await monitoringPromise;
356
+ log.info(`The GPS cache has been successfully refreshed after ` +
357
+ `${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
358
+ } finally {
359
+ if (logcatMonitor.isRunning) {
360
+ await logcatMonitor.stop();
361
+ }
362
+ }
363
+ } else {
364
+ log.info('The request to refresh the GPS cache has been sent. Skipping waiting for its result.');
365
+ }
366
+ };
367
+
290
368
  /**
291
369
  * Performs the given editor action on the focused input field.
292
370
  * This method requires Appium Settings helper to be installed on the device.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-adb",
3
- "version": "8.17.0",
3
+ "version": "8.18.0",
4
4
  "description": "Android Debug Bridge interface",
5
5
  "main": "./build/index.js",
6
6
  "scripts": {