UNPKG

appium-ios-simulator

Version:
815 lines (641 loc) 52.9 kB
require('source-map-support').install(); 'use strict'; var _regeneratorRuntime = require('babel-runtime/regenerator')['default']; var _getIterator = require('babel-runtime/core-js/get-iterator')['default']; var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default']; var _this = this; var _chai = require('chai'); var _chai2 = _interopRequireDefault(_chai); var _chaiAsPromised = require('chai-as-promised'); var _chaiAsPromised2 = _interopRequireDefault(_chaiAsPromised); var _libSettings = require('../../lib/settings'); var _libSimulatorXcode6 = require('../../lib/simulator-xcode-6'); var _libSimulatorXcode62 = _interopRequireDefault(_libSimulatorXcode6); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _appiumSupport = require('appium-support'); var _sinon = require('sinon'); var _sinon2 = _interopRequireDefault(_sinon); var _asyncbox = require('asyncbox'); var SIM_DIRECTORY = _path2['default'].resolve('test/assets/'); _chai2['default'].should(); var expect = _chai2['default'].expect; _chai2['default'].use(_chaiAsPromised2['default']); describe('settings', function () { var sim = undefined; before(function () { // create a simulator object that returns our fixture directory sim = new _libSimulatorXcode62['default'](); _sinon2['default'].stub(sim, 'getDir').returns(SIM_DIRECTORY); }); describe('general plist handling', function () { var plist = _path2['default'].resolve('test/assets/sample.plist'); var expectedField = 'com.apple.locationd.bundle-/System/Library/PrivateFrameworks/Parsec.framework'; var tmpPlist = undefined; beforeEach(function callee$2$0() { var temp; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap(_appiumSupport.tempDir.path()); case 2: temp = context$3$0.sent; tmpPlist = _path2['default'].resolve(temp, 'sample.plist'); context$3$0.next = 6; return _regeneratorRuntime.awrap(_appiumSupport.fs.copyFile(plist, tmpPlist)); case 6: case 'end': return context$3$0.stop(); } }, null, _this); }); afterEach(function callee$2$0() { return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap(_appiumSupport.fs.unlink(tmpPlist)); case 2: case 'end': return context$3$0.stop(); } }, null, _this); }); it('should update a plist', function callee$2$0() { var originalData, updatedData; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap((0, _libSettings.read)(tmpPlist)); case 2: originalData = context$3$0.sent; originalData[expectedField].Whitelisted = true; context$3$0.next = 6; return _regeneratorRuntime.awrap((0, _libSettings.update)(tmpPlist, originalData)); case 6: context$3$0.next = 8; return _regeneratorRuntime.awrap((0, _libSettings.read)(tmpPlist)); case 8: updatedData = context$3$0.sent; updatedData[expectedField].Whitelisted.should.be['true']; originalData.should.eql(updatedData); case 11: case 'end': return context$3$0.stop(); } }, null, _this); }); it('should read a plist', function callee$2$0() { var data; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap((0, _libSettings.read)(tmpPlist)); case 2: data = context$3$0.sent; data[expectedField].should.be.an['instanceof'](Object); case 4: case 'end': return context$3$0.stop(); } }, null, _this); }); }); describe('location services', function () { var clientFixtureFile = _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Caches', 'locationd', 'clients-fixture.plist'); var clientFile = _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Caches', 'locationd', 'clients.plist'); var cacheFixtureFiles = [_path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Caches', 'locationd', 'cache-fixture.plist'), _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Preferences', 'com.apple.locationd-fixture.plist')]; var cacheFiles = [_path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Caches', 'locationd', 'cache.plist'), _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Preferences', 'com.apple.locationd.plist')]; beforeEach(function callee$2$0() { var i; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap(_appiumSupport.fs.copyFile(clientFixtureFile, clientFile)); case 2: i = 0; case 3: if (!(i < cacheFiles.length)) { context$3$0.next = 9; break; } context$3$0.next = 6; return _regeneratorRuntime.awrap(_appiumSupport.fs.copyFile(cacheFixtureFiles[i], cacheFiles[i])); case 6: i++; context$3$0.next = 3; break; case 9: case 'end': return context$3$0.stop(); } }, null, _this); }); afterEach(function callee$2$0() { var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, file; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap(_appiumSupport.fs.unlink(clientFile)); case 2: _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; context$3$0.prev = 5; _iterator = _getIterator(cacheFiles); case 7: if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { context$3$0.next = 14; break; } file = _step.value; context$3$0.next = 11; return _regeneratorRuntime.awrap(_appiumSupport.fs.unlink(file)); case 11: _iteratorNormalCompletion = true; context$3$0.next = 7; break; case 14: context$3$0.next = 20; break; case 16: context$3$0.prev = 16; context$3$0.t0 = context$3$0['catch'](5); _didIteratorError = true; _iteratorError = context$3$0.t0; case 20: context$3$0.prev = 20; context$3$0.prev = 21; if (!_iteratorNormalCompletion && _iterator['return']) { _iterator['return'](); } case 23: context$3$0.prev = 23; if (!_didIteratorError) { context$3$0.next = 26; break; } throw _iteratorError; case 26: return context$3$0.finish(23); case 27: return context$3$0.finish(20); case 28: case 'end': return context$3$0.stop(); } }, null, _this, [[5, 16, 20, 28], [21,, 23, 27]]); }); describe('client plist', function () { var data = undefined; var weirdLocKey = 'com.apple.locationd.bundle-/System/Library/' + 'PrivateFrameworks/AOSNotification.framework'; beforeEach(function callee$3$0() { return _regeneratorRuntime.async(function callee$3$0$(context$4$0) { while (1) switch (context$4$0.prev = context$4$0.next) { case 0: context$4$0.next = 2; return _regeneratorRuntime.awrap((0, _libSettings.read)(clientFile)); case 2: data = context$4$0.sent; expect(data['com.apple.mobilesafari']).to.not.exist; expect(data[weirdLocKey]).to.not.exist; case 5: case 'end': return context$4$0.stop(); } }, null, _this); }); it('should update', function callee$3$0() { var finalData; return _regeneratorRuntime.async(function callee$3$0$(context$4$0) { while (1) switch (context$4$0.prev = context$4$0.next) { case 0: context$4$0.next = 2; return _regeneratorRuntime.awrap((0, _libSettings.updateLocationSettings)(sim, 'com.apple.mobilesafari', true)); case 2: context$4$0.next = 4; return _regeneratorRuntime.awrap((0, _libSettings.read)(clientFile)); case 4: finalData = context$4$0.sent; finalData.should.not.eql(data); finalData['com.apple.mobilesafari'].should.exist; finalData['com.apple.mobilesafari'].Authorized.should.be['true']; case 8: case 'end': return context$4$0.stop(); } }, null, _this); }); it('should update an already existing bundle without changing anything but Authorized', function callee$3$0() { var finalData, originalRecord, updatedRecord; return _regeneratorRuntime.async(function callee$3$0$(context$4$0) { while (1) switch (context$4$0.prev = context$4$0.next) { case 0: context$4$0.next = 2; return _regeneratorRuntime.awrap((0, _libSettings.updateLocationSettings)(sim, 'io.appium.test', true)); case 2: context$4$0.next = 4; return _regeneratorRuntime.awrap((0, _libSettings.read)(clientFile)); case 4: finalData = context$4$0.sent; finalData.should.not.eql(data); originalRecord = data['io.appium.test']; updatedRecord = finalData['io.appium.test']; updatedRecord.Whitelisted.should.equal(originalRecord.Whitelisted); updatedRecord.Executable.should.equal(originalRecord.Executable); updatedRecord.Registered.should.equal(originalRecord.Registered); updatedRecord.Authorized.should.not.equal(originalRecord.Authorized); case 12: case 'end': return context$4$0.stop(); } }, null, _this); }); it('should update with weird location key', function callee$3$0() { var finalData; return _regeneratorRuntime.async(function callee$3$0$(context$4$0) { while (1) switch (context$4$0.prev = context$4$0.next) { case 0: context$4$0.next = 2; return _regeneratorRuntime.awrap((0, _libSettings.updateLocationSettings)(sim, 'com.apple.mobilesafari', true)); case 2: context$4$0.next = 4; return _regeneratorRuntime.awrap((0, _libSettings.read)(clientFile)); case 4: finalData = context$4$0.sent; finalData.should.not.eql(data); finalData[weirdLocKey].should.exist; case 7: case 'end': return context$4$0.stop(); } }, null, _this); }); }); describe('cache plists', function () { it('should update both files', function callee$3$0() { var _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, file, finalData; return _regeneratorRuntime.async(function callee$3$0$(context$4$0) { while (1) switch (context$4$0.prev = context$4$0.next) { case 0: context$4$0.next = 2; return _regeneratorRuntime.awrap((0, _libSettings.updateLocationSettings)(sim, 'com.apple.mobilesafari', true)); case 2: _iteratorNormalCompletion2 = true; _didIteratorError2 = false; _iteratorError2 = undefined; context$4$0.prev = 5; _iterator2 = _getIterator(cacheFiles); case 7: if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) { context$4$0.next = 18; break; } file = _step2.value; context$4$0.next = 11; return _regeneratorRuntime.awrap((0, _libSettings.read)(file)); case 11: finalData = context$4$0.sent; finalData['com.apple.mobilesafari'].should.exist; finalData['com.apple.mobilesafari'].LastFenceActivityTimestamp.should.equal(412122103.232983); finalData['com.apple.mobilesafari'].CleanShutdown.should.be['true']; case 15: _iteratorNormalCompletion2 = true; context$4$0.next = 7; break; case 18: context$4$0.next = 24; break; case 20: context$4$0.prev = 20; context$4$0.t0 = context$4$0['catch'](5); _didIteratorError2 = true; _iteratorError2 = context$4$0.t0; case 24: context$4$0.prev = 24; context$4$0.prev = 25; if (!_iteratorNormalCompletion2 && _iterator2['return']) { _iterator2['return'](); } case 27: context$4$0.prev = 27; if (!_didIteratorError2) { context$4$0.next = 30; break; } throw _iteratorError2; case 30: return context$4$0.finish(27); case 31: return context$4$0.finish(24); case 32: case 'end': return context$4$0.stop(); } }, null, _this, [[5, 20, 24, 32], [25,, 27, 31]]); }); }); }); describe('updateLocale', function () { var globalPlistFixtureFile = _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Preferences', '.GlobalPreferences-fixture.plist'); var globalPlistFile = _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'Preferences', '.GlobalPreferences.plist'); beforeEach(function callee$2$0() { return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap(_appiumSupport.fs.copyFile(globalPlistFixtureFile, globalPlistFile)); case 2: case 'end': return context$3$0.stop(); } }, null, _this); }); afterEach(function callee$2$0() { return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap(_appiumSupport.fs.unlink(globalPlistFile)); case 2: case 'end': return context$3$0.stop(); } }, null, _this); }); it('should update language', function callee$2$0() { var originalData, finalData; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile)); case 2: originalData = context$3$0.sent; context$3$0.next = 5; return _regeneratorRuntime.awrap((0, _libSettings.updateLocale)(sim, 'rr')); case 5: context$3$0.next = 7; return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile)); case 7: finalData = context$3$0.sent; finalData.should.not.eql(originalData); finalData.AppleLanguages.should.include('rr'); case 10: case 'end': return context$3$0.stop(); } }, null, _this); }); it('should not do anything when language is already present', function callee$2$0() { var originalData; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile)); case 2: originalData = context$3$0.sent; context$3$0.next = 5; return _regeneratorRuntime.awrap((0, _libSettings.updateLocale)(sim, 'en')); case 5: context$3$0.next = 7; return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile)); case 7: context$3$0.t0 = originalData; context$3$0.sent.should.eql(context$3$0.t0); case 9: case 'end': return context$3$0.stop(); } }, null, _this); }); it('should update locale', function callee$2$0() { var originalData, finalData; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile)); case 2: originalData = context$3$0.sent; context$3$0.next = 5; return _regeneratorRuntime.awrap((0, _libSettings.updateLocale)(sim, undefined, 'fr_US')); case 5: context$3$0.next = 7; return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile)); case 7: finalData = context$3$0.sent; finalData.should.not.eql(originalData); finalData.AppleLanguages.should.eql(originalData.AppleLanguages); finalData.AppleLocale.should.include('fr_US'); case 11: case 'end': return context$3$0.stop(); } }, null, _this); }); it('should update calendarFormat', function callee$2$0() { var originalData, finalData; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile)); case 2: originalData = context$3$0.sent; context$3$0.next = 5; return _regeneratorRuntime.awrap((0, _libSettings.updateLocale)(sim, undefined, undefined, 'something')); case 5: context$3$0.next = 7; return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile)); case 7: finalData = context$3$0.sent; finalData.should.not.eql(originalData); finalData.AppleLanguages.should.eql(originalData.AppleLanguages); finalData.AppleLocale.should.include('@calendar=something'); case 11: case 'end': return context$3$0.stop(); } }, null, _this); }); it('should preserve the calendarFormat when updating locale alone', function callee$2$0() { var originalData, intermediateData, finalData; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile)); case 2: originalData = context$3$0.sent; context$3$0.next = 5; return _regeneratorRuntime.awrap((0, _libSettings.updateLocale)(sim, undefined, undefined, 'something')); case 5: context$3$0.next = 7; return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile)); case 7: intermediateData = context$3$0.sent; intermediateData.should.not.eql(originalData); intermediateData.AppleLanguages.should.eql(originalData.AppleLanguages); intermediateData.AppleLocale.should.include('@calendar=something'); // udpate with a new locale context$3$0.next = 13; return _regeneratorRuntime.awrap((0, _libSettings.updateLocale)(sim, undefined, 'fr_US')); case 13: context$3$0.next = 15; return _regeneratorRuntime.awrap((0, _libSettings.read)(globalPlistFile)); case 15: finalData = context$3$0.sent; finalData.should.not.eql(intermediateData); finalData.AppleLanguages.should.eql(originalData.AppleLanguages); finalData.AppleLocale.should.eql('fr_US@calendar=something'); case 19: case 'end': return context$3$0.stop(); } }, null, _this); }); }); describe('updateSafariUserSettings', function () { var fixtureFiles = [_path2['default'].resolve(SIM_DIRECTORY, 'Library', 'ConfigurationProfiles', 'EffectiveUserSettings-fixture.plist'), _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'ConfigurationProfiles', 'UserSettings-fixture.plist'), _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'ConfigurationProfiles', 'PublicInfo', 'PublicEffectiveUserSettings-fixture.plist')]; var realFiles = [_path2['default'].resolve(SIM_DIRECTORY, 'Library', 'ConfigurationProfiles', 'EffectiveUserSettings.plist'), _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'ConfigurationProfiles', 'UserSettings.plist'), _path2['default'].resolve(SIM_DIRECTORY, 'Library', 'ConfigurationProfiles', 'PublicInfo', 'PublicEffectiveUserSettings.plist')]; beforeEach(function callee$2$0() { var i; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: i = 0; case 1: if (!(i < fixtureFiles.length)) { context$3$0.next = 7; break; } context$3$0.next = 4; return _regeneratorRuntime.awrap(_appiumSupport.fs.copyFile(fixtureFiles[i], realFiles[i])); case 4: i++; context$3$0.next = 1; break; case 7: case 'end': return context$3$0.stop(); } }, null, _this); }); afterEach(function callee$2$0() { var _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, file; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: _iteratorNormalCompletion3 = true; _didIteratorError3 = false; _iteratorError3 = undefined; context$3$0.prev = 3; _iterator3 = _getIterator(realFiles); case 5: if (_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done) { context$3$0.next = 12; break; } file = _step3.value; context$3$0.next = 9; return _regeneratorRuntime.awrap(_appiumSupport.fs.unlink(file)); case 9: _iteratorNormalCompletion3 = true; context$3$0.next = 5; break; case 12: context$3$0.next = 18; break; case 14: context$3$0.prev = 14; context$3$0.t0 = context$3$0['catch'](3); _didIteratorError3 = true; _iteratorError3 = context$3$0.t0; case 18: context$3$0.prev = 18; context$3$0.prev = 19; if (!_iteratorNormalCompletion3 && _iterator3['return']) { _iterator3['return'](); } case 21: context$3$0.prev = 21; if (!_didIteratorError3) { context$3$0.next = 24; break; } throw _iteratorError3; case 24: return context$3$0.finish(21); case 25: return context$3$0.finish(18); case 26: case 'end': return context$3$0.stop(); } }, null, _this, [[3, 14, 18, 26], [19,, 21, 25]]); }); function getData() { return _regeneratorRuntime.async(function getData$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: return context$3$0.abrupt('return', (0, _asyncbox.asyncmap)(realFiles, function (file) { return (0, _libSettings.read)(file); }, true)); case 1: case 'end': return context$3$0.stop(); } }, null, this); } it('should update all the files', function callee$2$0() { var originalData, settingSet, finalData, i; return _regeneratorRuntime.async(function callee$2$0$(context$3$0) { while (1) switch (context$3$0.prev = context$3$0.next) { case 0: context$3$0.next = 2; return _regeneratorRuntime.awrap(getData()); case 2: originalData = context$3$0.sent; settingSet = { WebKitJavaScriptEnabled: false, WebKitJavaScriptCanOpenWindowsAutomatically: false, WarnAboutFraudulentWebsites: false }; context$3$0.next = 6; return _regeneratorRuntime.awrap((0, _libSettings.updateSafariUserSettings)(sim, settingSet)); case 6: context$3$0.next = 8; return _regeneratorRuntime.awrap(getData()); case 8: finalData = context$3$0.sent; for (i = 0; i < realFiles.length; i++) { finalData[i].should.not.eql(originalData[i]); finalData[i].restrictedBool.safariAllowJavaScript.value.should.be['false']; finalData[i].restrictedBool.safariAllowPopups.value.should.be['false']; finalData[i].restrictedBool.safariForceFraudWarning.value.should.be['true']; } case 10: case 'end': return context$3$0.stop(); } }, null, _this); }); }); }); // get rid of the temporary plist we made // make a copy of the clients plist // and the cache plists // get rid of the temporary plist we made // get rid of the temporary plist we made // get a calendar format into the plist // make a copy of the fixture // get rid of the temporary plists we made // check the update //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvdW5pdC9zZXR0aW5ncy1zcGVjcy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7b0JBRWlCLE1BQU07Ozs7OEJBQ0ksa0JBQWtCOzs7OzJCQUVKLG9CQUFvQjs7a0NBQ2pDLDZCQUE2Qjs7OztvQkFDeEMsTUFBTTs7Ozs2QkFDSyxnQkFBZ0I7O3FCQUMxQixPQUFPOzs7O3dCQUNBLFVBQVU7O0FBR25DLElBQU0sYUFBYSxHQUFHLGtCQUFLLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQzs7QUFFbkQsa0JBQUssTUFBTSxFQUFFLENBQUM7QUFDZCxJQUFJLE1BQU0sR0FBRyxrQkFBSyxNQUFNLENBQUM7QUFDekIsa0JBQUssR0FBRyw2QkFBZ0IsQ0FBQzs7QUFFekIsUUFBUSxDQUFDLFVBQVUsRUFBRSxZQUFNO0FBQ3pCLE1BQUksR0FBRyxZQUFBLENBQUM7QUFDUixRQUFNLENBQUMsWUFBTTs7QUFFWCxPQUFHLEdBQUcscUNBQXFCLENBQUM7QUFDNUIsdUJBQU0sSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7R0FDbEQsQ0FBQyxDQUFDOztBQUVILFVBQVEsQ0FBQyx3QkFBd0IsRUFBRSxZQUFNO0FBQ3ZDLFFBQU0sS0FBSyxHQUFHLGtCQUFLLE9BQU8sQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO0FBQ3ZELFFBQU0sYUFBYSxHQUFHLCtFQUErRSxDQUFDO0FBQ3RHLFFBQUksUUFBUSxZQUFBLENBQUM7O0FBRWIsY0FBVSxDQUFDO1VBQ0wsSUFBSTs7Ozs7NkNBQVMsdUJBQVEsSUFBSSxFQUFFOzs7QUFBM0IsZ0JBQUk7O0FBQ1Isb0JBQVEsR0FBRyxrQkFBSyxPQUFPLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxDQUFDOzs2Q0FDeEMsa0JBQUcsUUFBUSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUM7Ozs7Ozs7S0FDbkMsQ0FBQyxDQUFDOztBQUVILGFBQVMsQ0FBQzs7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QzlCLHlEQUEyQyxFQUFFLEtBQUs7QUFDbEQseUNBQTJCLEVBQUUsS0FBSzthQUNuQzs7NkNBQ0ssMkNBQXlCLEdBQUcsRUFBRSxVQUFVLENBQUM7Ozs7NkNBR3pCLE9BQU8sRUFBRTs7O0FBQTNCLHFCQUFTOztBQUNiLGlCQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDekMsdUJBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3Qyx1QkFBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsU0FBTSxDQUFDO0FBQ3hFLHVCQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxTQUFNLENBQUM7QUFDcEUsdUJBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsdUJBQXVCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLFFBQUssQ0FBQzthQUMxRTs7Ozs7OztLQUNGLENBQUMsQ0FBQztHQUNKLENBQUMsQ0FBQztDQUNKLENBQUMsQ0FBQyIsImZpbGUiOiJ0ZXN0L3VuaXQvc2V0dGluZ3Mtc3BlY3MuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0cmFuc3BpbGU6bW9jaGFcblxuaW1wb3J0IGNoYWkgZnJvbSAnY2hhaSc7XG5pbXBvcnQgY2hhaUFzUHJvbWlzZWQgZnJvbSAnY2hhaS1hcy1wcm9taXNlZCc7XG5pbXBvcnQgeyB1cGRhdGUsIHJlYWQsIHVwZGF0ZUxvY2F0aW9uU2V0dGluZ3MsIHVwZGF0ZUxvY2FsZSxcbiAgICAgICAgIHVwZGF0ZVNhZmFyaVVzZXJTZXR0aW5ncyB9IGZyb20gJy4uLy4uL2xpYi9zZXR0aW5ncyc7XG5pbXBvcnQgU2ltdWxhdG9yWGNvZGU2IGZyb20gJy4uLy4uL2xpYi9zaW11bGF0b3IteGNvZGUtNic7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IHRlbXBEaXIsIGZzIH0gZnJvbSAnYXBwaXVtLXN1cHBvcnQnO1xuaW1wb3J0IHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCB7IGFzeW5jbWFwIH0gZnJvbSAnYXN5bmNib3gnO1xuXG5cbmNvbnN0IFNJTV9ESVJFQ1RPUlkgPSBwYXRoLnJlc29sdmUoJ3Rlc3QvYXNzZXRzLycpO1xuXG5jaGFpLnNob3VsZCgpO1xubGV0IGV4cGVjdCA9IGNoYWkuZXhwZWN0O1xuY2hhaS51c2UoY2hhaUFzUHJvbWlzZWQpO1xuXG5kZXNjcmliZSgnc2V0dGluZ3MnLCAoKSA9PiB7XG4gIGxldCBzaW07XG4gIGJlZm9yZSgoKSA9PiB7XG4gICAgLy8gY3JlYXRlIGEgc2ltdWxhdG9yIG9iamVjdCB0aGF0IHJldHVybnMgb3VyIGZpeHR1cmUgZGlyZWN0b3J5XG4gICAgc2ltID0gbmV3IFNpbXVsYXRvclhjb2RlNigpO1xuICAgIHNpbm9uLnN0dWIoc2ltLCAnZ2V0RGlyJykucmV0dXJucyhTSU1fRElSRUNUT1JZKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2dlbmVyYWwgcGxpc3QgaGFuZGxpbmcnLCAoKSA9PiB7XG4gICAgY29uc3QgcGxpc3QgPSBwYXRoLnJlc29sdmUoJ3Rlc3QvYXNzZXRzL3NhbXBsZS5wbGlzdCcpO1xuICAgIGNvbnN0IGV4cGVjdGVkRmllbGQgPSAnY29tLmFwcGxlLmxvY2F0aW9uZC5idW5kbGUtL1N5c3RlbS9MaWJyYXJ5L1ByaXZhdGVGcmFtZXdvcmtzL1BhcnNlYy5mcmFtZXdvcmsnO1xuICAgIGxldCB0bXBQbGlzdDtcblxuICAgIGJlZm9yZUVhY2goYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IHRlbXAgPSBhd2FpdCB0ZW1wRGlyLnBhdGgoKTtcbiAgICAgIHRtcFBsaXN0ID0gcGF0aC5yZXNvbHZlKHRlbXAsICdzYW1wbGUucGxpc3QnKTtcbiAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKHBsaXN0LCB0bXBQbGlzdCk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gZ2V0IHJpZCBvZiB0aGUgdGVtcG9yYXJ5IHBsaXN0IHdlIG1hZGVcbiAgICAgIGF3YWl0IGZzLnVubGluayh0bXBQbGlzdCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHVwZGF0ZSBhIHBsaXN0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IG9yaWdpbmFsRGF0YSA9IGF3YWl0IHJlYWQodG1wUGxpc3QpO1xuICAgICAgb3JpZ2luYWxEYXRhW2V4cGVjdGVkRmllbGRdXG4gICAgICAgIC5XaGl0ZWxpc3RlZCA9IHRydWU7XG4gICAgICBhd2FpdCB1cGRhdGUodG1wUGxpc3QsIG9yaWdpbmFsRGF0YSk7XG4gICAgICBsZXQgdXBkYXRlZERhdGEgPSBhd2FpdCByZWFkKHRtcFBsaXN0KTtcblxuICAgICAgdXBkYXRlZERhdGFbZXhwZWN0ZWRGaWVsZF1cbiAgICAgICAgLldoaXRlbGlzdGVkLnNob3VsZC5iZS50cnVlO1xuXG4gICAgICBvcmlnaW5hbERhdGEuc2hvdWxkLmVxbCh1cGRhdGVkRGF0YSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlYWQgYSBwbGlzdCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBkYXRhID0gYXdhaXQgcmVhZCh0bXBQbGlzdCk7XG4gICAgICBkYXRhW2V4cGVjdGVkRmllbGRdXG4gICAgICAgIC5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihPYmplY3QpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnbG9jYXRpb24gc2VydmljZXMnLCAoKSA9PiB7XG4gICAgY29uc3QgY2xpZW50Rml4dHVyZUZpbGUgPSBwYXRoLnJlc29sdmUoU0lNX0RJUkVDVE9SWSwgJ0xpYnJhcnknLCAnQ2FjaGVzJywgJ2xvY2F0aW9uZCcsICdjbGllbnRzLWZpeHR1cmUucGxpc3QnKTtcbiAgICBjb25zdCBjbGllbnRGaWxlID0gcGF0aC5yZXNvbHZlKFNJTV9ESVJFQ1RPUlksICdMaWJyYXJ5JywgJ0NhY2hlcycsICdsb2NhdGlvbmQnLCAnY2xpZW50cy5wbGlzdCcpO1xuICAgIGNvbnN0IGNhY2hlRml4dHVyZUZpbGVzID0gW1xuICAgICAgcGF0aC5yZXNvbHZlKFNJTV9ESVJFQ1RPUlksICdMaWJyYXJ5JywgJ0NhY2hlcycsICdsb2NhdGlvbmQnLCAnY2FjaGUtZml4dHVyZS5wbGlzdCcpLFxuICAgICAgcGF0aC5yZXNvbHZlKFNJTV9ESVJFQ1RPUlksICdMaWJyYXJ5JywgJ1ByZWZlcmVuY2VzJywgJ2NvbS5hcHBsZS5sb2NhdGlvbmQtZml4dHVyZS5wbGlzdCcpXG4gICAgXTtcbiAgICBjb25zdCBjYWNoZUZpbGVzID0gW1xuICAgICAgcGF0aC5yZXNvbHZlKFNJTV9ESVJFQ1RPUlksICdMaWJyYXJ5JywgJ0NhY2hlcycsICdsb2NhdGlvbmQnLCAnY2FjaGUucGxpc3QnKSxcbiAgICAgIHBhdGgucmVzb2x2ZShTSU1fRElSRUNUT1JZLCAnTGlicmFyeScsICdQcmVmZXJlbmNlcycsICdjb20uYXBwbGUubG9jYXRpb25kLnBsaXN0JylcbiAgICBdO1xuICAgIGJlZm9yZUVhY2goYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gbWFrZSBhIGNvcHkgb2YgdGhlIGNsaWVudHMgcGxpc3RcbiAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKGNsaWVudEZpeHR1cmVGaWxlLCBjbGllbnRGaWxlKTtcblxuICAgICAgLy8gYW5kIHRoZSBjYWNoZSBwbGlzdHNcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2FjaGVGaWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBhd2FpdCBmcy5jb3B5RmlsZShjYWNoZUZpeHR1cmVGaWxlc1tpXSwgY2FjaGVGaWxlc1tpXSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgYWZ0ZXJFYWNoKGFzeW5jICgpID0+IHtcbiAgICAgIC8vIGdldCByaWQgb2YgdGhlIHRlbXBvcmFyeSBwbGlzdCB3ZSBtYWRlXG4gICAgICBhd2FpdCBmcy51bmxpbmsoY2xpZW50RmlsZSk7XG4gICAgICBmb3IgKGxldCBmaWxlIG9mIGNhY2hlRmlsZXMpIHtcbiAgICAgICAgYXdhaXQgZnMudW5saW5rKGZpbGUpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NsaWVudCBwbGlzdCcsICgpID0+IHtcbiAgICAgIGxldCBkYXRhO1xuICAgICAgY29uc3Qgd2VpcmRMb2NLZXkgPSAnY29tLmFwcGxlLmxvY2F0aW9uZC5idW5kbGUtL1N5c3RlbS9MaWJyYXJ5LycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAnUHJpdmF0ZUZyYW1ld29ya3MvQU9TTm90aWZpY2F0aW9uLmZyYW1ld29yayc7XG4gICAgICBiZWZvcmVFYWNoKGFzeW5jICgpID0+IHtcbiAgICAgICAgZGF0YSA9IGF3YWl0IHJlYWQoY2xpZW50RmlsZSk7XG4gICAgICAgIGV4cGVjdChkYXRhWydjb20uYXBwbGUubW9iaWxlc2FmYXJpJ10pLnRvLm5vdC5leGlzdDtcbiAgICAgICAgZXhwZWN0KGRhdGFbd2VpcmRMb2NLZXldKS50by5ub3QuZXhpc3Q7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB1cGRhdGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHVwZGF0ZUxvY2F0aW9uU2V0dGluZ3Moc2ltLCAnY29tLmFwcGxlLm1vYmlsZXNhZmFyaScsIHRydWUpO1xuXG4gICAgICAgIGxldCBmaW5hbERhdGEgPSBhd2FpdCByZWFkKGNsaWVudEZpbGUpO1xuICAgICAgICBmaW5hbERhdGEuc2hvdWxkLm5vdC5lcWwoZGF0YSk7XG4gICAgICAgIGZpbmFsRGF0YVsnY29tLmFwcGxlLm1vYmlsZXNhZmFyaSddLnNob3VsZC5leGlzdDtcbiAgICAgICAgZmluYWxEYXRhWydjb20uYXBwbGUubW9iaWxlc2FmYXJpJ10uQXV0aG9yaXplZC5zaG91bGQuYmUudHJ1ZTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHVwZGF0ZSBhbiBhbHJlYWR5IGV4aXN0aW5nIGJ1bmRsZSB3aXRob3V0IGNoYW5naW5nIGFueXRoaW5nIGJ1dCBBdXRob3JpemVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB1cGRhdGVMb2NhdGlvblNldHRpbmdzKHNpbSwgJ2lvLmFwcGl1bS50ZXN0JywgdHJ1ZSk7XG5cbiAgICAgICAgbGV0IGZpbmFsRGF0YSA9IGF3YWl0IHJlYWQoY2xpZW50RmlsZSk7XG4gICAgICAgIGZpbmFsRGF0YS5zaG91bGQubm90LmVxbChkYXRhKTtcblxuICAgICAgICBsZXQgb3JpZ2luYWxSZWNvcmQgPSBkYXRhWydpby5hcHBpdW0udGVzdCddO1xuICAgICAgICBsZXQgdXBkYXRlZFJlY29yZCA9IGZpbmFsRGF0YVsnaW8uYXBwaXVtLnRlc3QnXTtcbiAgICAgICAgdXBkYXRlZFJlY29yZC5XaGl0ZWxpc3RlZC5zaG91bGQuZXF1YWwob3JpZ2luYWxSZWNvcmQuV2hpdGVsaXN0ZWQpO1xuICAgICAgICB1cGRhdGVkUmVjb3JkLkV4ZWN1dGFibGUuc2hvdWxkLmVxdWFsKG9yaWdpbmFsUmVjb3JkLkV4ZWN1dGFibGUpO1xuICAgICAgICB1cGRhdGVkUmVjb3JkLlJlZ2lzdGVyZWQuc2hvdWxkLmVxdWFsKG9yaWdpbmFsUmVjb3JkLlJlZ2lzdGVyZWQpO1xuICAgICAgICB1cGRhdGVkUmVjb3JkLkF1dGhvcml6ZWQuc2hvdWxkLm5vdC5lcXVhbChvcmlnaW5hbFJlY29yZC5BdXRob3JpemVkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHVwZGF0ZSB3aXRoIHdlaXJkIGxvY2F0aW9uIGtleScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgdXBkYXRlTG9jYXRpb25TZXR0aW5ncyhzaW0sICdjb20uYXBwbGUubW9iaWxlc2FmYXJpJywgdHJ1ZSk7XG5cbiAgICAgICAgbGV0IGZpbmFsRGF0YSA9IGF3YWl0IHJlYWQoY2xpZW50RmlsZSk7XG4gICAgICAgIGZpbmFsRGF0YS5zaG91bGQubm90LmVxbChkYXRhKTtcbiAgICAgICAgZmluYWxEYXRhW3dlaXJkTG9jS2V5XS5zaG91bGQuZXhpc3Q7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjYWNoZSBwbGlzdHMnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHVwZGF0ZSBib3RoIGZpbGVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB1cGRhdGVMb2NhdGlvblNldHRpbmdzKHNpbSwgJ2NvbS5hcHBsZS5tb2JpbGVzYWZhcmknLCB0cnVlKTtcblxuICAgICAgICBmb3IgKGxldCBmaWxlIG9mIGNhY2hlRmlsZXMpIHtcbiAgICAgICAgICBsZXQgZmluYWxEYXRhID0gYXdhaXQgcmVhZChmaWxlKTtcbiAgICAgICAgICBmaW5hbERhdGFbJ2NvbS5hcHBsZS5tb2JpbGVzYWZhcmknXS5zaG91bGQuZXhpc3Q7XG4gICAgICAgICAgZmluYWxEYXRhWydjb20uYXBwbGUubW9iaWxlc2FmYXJpJ10uTGFzdEZlbmNlQWN0aXZpdHlUaW1lc3RhbXAuc2hvdWxkLmVxdWFsKDQxMjEyMjEwMy4yMzI5ODMpO1xuICAgICAgICAgIGZpbmFsRGF0YVsnY29tLmFwcGxlLm1vYmlsZXNhZmFyaSddLkNsZWFuU2h1dGRvd24uc2hvdWxkLmJlLnRydWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndXBkYXRlTG9jYWxlJywgKCkgPT4ge1xuICAgIGNvbnN0IGdsb2JhbFBsaXN0Rml4dHVyZUZpbGUgPSBwYXRoLnJlc29sdmUoU0lNX0RJUkVDVE9SWSwgJ0xpYnJhcnknLCAnUHJlZmVyZW5jZXMnLCAnLkdsb2JhbFByZWZlcmVuY2VzLWZpeHR1cmUucGxpc3QnKTtcbiAgICBjb25zdCBnbG9iYWxQbGlzdEZpbGUgPSBwYXRoLnJlc29sdmUoU0lNX0RJUkVDVE9SWSwgJ0xpYnJhcnknLCAnUHJlZmVyZW5jZXMnLCAnLkdsb2JhbFByZWZlcmVuY2VzLnBsaXN0Jyk7XG5cbiAgICBiZWZvcmVFYWNoKGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKGdsb2JhbFBsaXN0Rml4dHVyZUZpbGUsIGdsb2JhbFBsaXN0RmlsZSk7XG4gICAgfSk7XG4gICAgYWZ0ZXJFYWNoKGFzeW5jICgpID0+IHtcbiAgICAgIC8vIGdldCByaWQgb2YgdGhlIHRlbXBvcmFyeSBwbGlzdCB3ZSBtYWRlXG4gICAgICBhd2FpdCBmcy51bmxpbmsoZ2xvYmFsUGxpc3RGaWxlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdXBkYXRlIGxhbmd1YWdlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IG9yaWdpbmFsRGF0YSA9IGF3YWl0IHJlYWQoZ2xvYmFsUGxpc3RGaWxlKTtcblxuICAgICAgYXdhaXQgdXBkYXRlTG9jYWxlKHNpbSwgJ3JyJyk7XG4gICAgICBsZXQgZmluYWxEYXRhID0gYXdhaXQgcmVhZChnbG9iYWxQbGlzdEZpbGUpO1xuICAgICAgZmluYWxEYXRhLnNob3VsZC5ub3QuZXFsKG9yaWdpbmFsRGF0YSk7XG4gICAgICBmaW5hbERhdGEuQXBwbGVMYW5ndWFnZXMuc2hvdWxkLmluY2x1ZGUoJ3JyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBkbyBhbnl0aGluZyB3aGVuIGxhbmd1YWdlIGlzIGFscmVhZHkgcHJlc2VudCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBvcmlnaW5hbERhdGEgPSBhd2FpdCByZWFkKGdsb2JhbFBsaXN0RmlsZSk7XG5cbiAgICAgIGF3YWl0IHVwZGF0ZUxvY2FsZShzaW0sICdlbicpO1xuICAgICAgKGF3YWl0IHJlYWQoZ2xvYmFsUGxpc3RGaWxlKSkuc2hvdWxkLmVxbChvcmlnaW5hbERhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1cGRhdGUgbG9jYWxlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IG9yaWdpbmFsRGF0YSA9IGF3YWl0IHJlYWQoZ2xvYmFsUGxpc3RGaWxlKTtcblxuICAgICAgYXdhaXQgdXBkYXRlTG9jYWxlKHNpbSwgdW5kZWZpbmVkLCAnZnJfVVMnKTtcbiAgICAgIGxldCBmaW5hbERhdGEgPSBhd2FpdCByZWFkKGdsb2JhbFBsaXN0RmlsZSk7XG4gICAgICBmaW5hbERhdGEuc2hvdWxkLm5vdC5lcWwob3JpZ2luYWxEYXRhKTtcbiAgICAgIGZpbmFsRGF0YS5BcHBsZUxhbmd1YWdlcy5zaG91bGQuZXFsKG9yaWdpbmFsRGF0YS5BcHBsZUxhbmd1YWdlcyk7XG4gICAgICBmaW5hbERhdGEuQXBwbGVMb2NhbGUuc2hvdWxkLmluY2x1ZGUoJ2ZyX1VTJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHVwZGF0ZSBjYWxlbmRhckZvcm1hdCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBvcmlnaW5hbERhdGEgPSBhd2FpdCByZWFkKGdsb2JhbFBsaXN0RmlsZSk7XG5cbiAgICAgIGF3YWl0IHVwZGF0ZUxvY2FsZShzaW0sIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnc29tZXRoaW5nJyk7XG4gICAgICBsZXQgZmluYWxEYXRhID0gYXdhaXQgcmVhZChnbG9iYWxQbGlzdEZpbGUpO1xuICAgICAgZmluYWxEYXRhLnNob3VsZC5ub3QuZXFsKG9yaWdpbmFsRGF0YSk7XG4gICAgICBmaW5hbERhdGEuQXBwbGVMYW5ndWFnZXMuc2hvdWxkLmVxbChvcmlnaW5hbERhdGEuQXBwbGVMYW5ndWFnZXMpO1xuICAgICAgZmluYWxEYXRhLkFwcGxlTG9jYWxlLnNob3VsZC5pbmNsdWRlKCdAY2FsZW5kYXI9c29tZXRoaW5nJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByZXNlcnZlIHRoZSBjYWxlbmRhckZvcm1hdCB3aGVuIHVwZGF0aW5nIGxvY2FsZSBhbG9uZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBvcmlnaW5hbERhdGEgPSBhd2FpdCByZWFkKGdsb2JhbFBsaXN0RmlsZSk7XG5cbiAgICAgIC8vIGdldCBhIGNhbGVuZGFyIGZvcm1hdCBpbnRvIHRoZSBwbGlzdFxuICAgICAgYXdhaXQgdXBkYXRlTG9jYWxlKHNpbSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsICdzb21ldGhpbmcnKTtcbiAgICAgIGxldCBpbnRlcm1lZGlhdGVEYXRhID0gYXdhaXQgcmVhZChnbG9iYWxQbGlzdEZpbGUpO1xuICAgICAgaW50ZXJtZWRpYXRlRGF0YS5zaG91bGQubm90LmVxbChvcmlnaW5hbERhdGEpO1xuICAgICAgaW50ZXJtZWRpYXRlRGF0YS5BcHBsZUxhbmd1YWdlcy5zaG91bGQuZXFsKG9yaWdpbmFsRGF0YS5BcHBsZUxhbmd1YWdlcyk7XG4gICAgICBpbnRlcm1lZGlhdGVEYXRhLkFwcGxlTG9jYWxlLnNob3VsZC5pbmNsdWRlKCdAY2FsZW5kYXI9c29tZXRoaW5nJyk7XG5cbiAgICAgIC8vIHVkcGF0ZSB3aXRoIGEgbmV3IGxvY2FsZVxuICAgICAgYXdhaXQgdXBkYXRlTG9jYWxlKHNpbSwgdW5kZWZpbmVkLCAnZnJfVVMnKTtcbiAgICAgIGxldCBmaW5hbERhdGEgPSBhd2FpdCByZWFkKGdsb2JhbFBsaXN0RmlsZSk7XG4gICAgICBmaW5hbERhdGEuc2hvdWxkLm5vdC5lcWwoaW50ZXJtZWRpYXRlRGF0YSk7XG4gICAgICBmaW5hbERhdGEuQXBwbGVMYW5ndWFnZXMuc2hvdWxkLmVxbChvcmlnaW5hbERhdGE