UNPKG

matrix-react-sdk

Version:
299 lines (241 loc) 36.2 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.MatrixClientPeg = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _memory = require("matrix-js-sdk/src/store/memory"); var utils = _interopRequireWildcard(require("matrix-js-sdk/src/utils")); var _eventTimeline = require("matrix-js-sdk/src/models/event-timeline"); var _eventTimelineSet = require("matrix-js-sdk/src/models/event-timeline-set"); var sdk = _interopRequireWildcard(require("./index")); var _createMatrixClient = _interopRequireDefault(require("./utils/createMatrixClient")); var _SettingsStore = _interopRequireDefault(require("./settings/SettingsStore")); var _MatrixActionCreators = _interopRequireDefault(require("./actions/MatrixActionCreators")); var _Modal = _interopRequireDefault(require("./Modal")); var _crypto = require("matrix-js-sdk/src/crypto"); var _MatrixClientBackedSettingsHandler = _interopRequireDefault(require("./settings/handlers/MatrixClientBackedSettingsHandler")); var StorageManager = _interopRequireWildcard(require("./utils/StorageManager")); var _IdentityAuthClient = _interopRequireDefault(require("./IdentityAuthClient")); var _SecurityManager = require("./SecurityManager"); var _QRCode = require("matrix-js-sdk/src/crypto/verification/QRCode"); var _Security = _interopRequireDefault(require("./customisations/Security")); /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd. Copyright 2017, 2018, 2019 New Vector Ltd Copyright 2019, 2020 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /** * Wrapper object for handling the js-sdk Matrix Client object in the react-sdk * Handles the creation/initialisation of client objects. * This module provides a singleton instance of this class so the 'current' * Matrix Client object is available easily. */ class _MatrixClientPeg /*:: implements IMatrixClientPeg*/ { // These are the default options used when when the // client is started in 'start'. These can be altered // at any time up to after the 'will_start_client' // event is finished processing. // the credentials used to init the current client object. // used if we tear it down & recreate it with a different store constructor() { (0, _defineProperty2.default)(this, "opts", { initialSyncLimit: 20 }); (0, _defineProperty2.default)(this, "matrixClient", null); (0, _defineProperty2.default)(this, "justRegisteredUserId", void 0); (0, _defineProperty2.default)(this, "currentClientCreds", void 0); } setIndexedDbWorkerScript(script /*: string*/ ) /*: void*/ { _createMatrixClient.default.indexedDbWorkerScript = script; } get() /*: MatrixClient*/ { return this.matrixClient; } unset() /*: void*/ { this.matrixClient = null; _MatrixActionCreators.default.stop(); } setJustRegisteredUserId(uid /*: string*/ ) /*: void*/ { this.justRegisteredUserId = uid; if (uid) { window.localStorage.setItem("mx_registration_time", String(new Date().getTime())); } } currentUserIsJustRegistered() /*: boolean*/ { return this.matrixClient && this.matrixClient.credentials.userId === this.justRegisteredUserId; } userRegisteredWithinLastHours(hours /*: number*/ ) /*: boolean*/ { try { const date = new Date(window.localStorage.getItem("mx_registration_time")); return (new Date().getTime() - date.getTime()) / 36e5 <= hours; } catch (e) { return false; } } replaceUsingCreds(creds /*: IMatrixClientCreds*/ ) /*: void*/ { this.currentClientCreds = creds; this.createClient(creds); } async assign() /*: Promise<any>*/ { for (const dbType of ['indexeddb', 'memory']) { try { const promise = this.matrixClient.store.startup(); console.log("MatrixClientPeg: waiting for MatrixClient store to initialise"); await promise; break; } catch (err) { if (dbType === 'indexeddb') { console.error('Error starting matrixclient store - falling back to memory store', err); this.matrixClient.store = new _memory.MemoryStore({ localStorage: localStorage }); } else { console.error('Failed to start memory store!', err); throw err; } } } StorageManager.trackStores(this.matrixClient); // try to initialise e2e on the new client try { // check that we have a version of the js-sdk which includes initCrypto if (!_SettingsStore.default.getValue("lowBandwidth") && this.matrixClient.initCrypto) { await this.matrixClient.initCrypto(); this.matrixClient.setCryptoTrustCrossSignedDevices(!_SettingsStore.default.getValue('e2ee.manuallyVerifyAllSessions')); await (0, _SecurityManager.tryToUnlockSecretStorageWithDehydrationKey)(this.matrixClient); StorageManager.setCryptoInitialised(true); } } catch (e) { if (e && e.name === 'InvalidCryptoStoreError') { // The js-sdk found a crypto DB too new for it to use const CryptoStoreTooNewDialog = sdk.getComponent("views.dialogs.CryptoStoreTooNewDialog"); _Modal.default.createDialog(CryptoStoreTooNewDialog); } // this can happen for a number of reasons, the most likely being // that the olm library was missing. It's not fatal. console.warn("Unable to initialise e2e", e); } const opts = utils.deepCopy(this.opts); // the react sdk doesn't work without this, so don't allow opts.pendingEventOrdering = "detached"; opts.lazyLoadMembers = true; opts.clientWellKnownPollPeriod = 2 * 60 * 60; // 2 hours // Connect the matrix client to the dispatcher and setting handlers _MatrixActionCreators.default.start(this.matrixClient); _MatrixClientBackedSettingsHandler.default.matrixClient = this.matrixClient; return opts; } async start() /*: Promise<any>*/ { const opts = await this.assign(); console.log(`MatrixClientPeg: really starting MatrixClient`); await this.get().startClient(opts); console.log(`MatrixClientPeg: MatrixClient started`); } getCredentials() /*: IMatrixClientCreds*/ { return { homeserverUrl: this.matrixClient.baseUrl, identityServerUrl: this.matrixClient.idBaseUrl, userId: this.matrixClient.credentials.userId, deviceId: this.matrixClient.getDeviceId(), accessToken: this.matrixClient.getAccessToken(), guest: this.matrixClient.isGuest() }; } getHomeserverName() /*: string*/ { const matches = /^@[^:]+:(.+)$/.exec(this.matrixClient.credentials.userId); if (matches === null || matches.length < 1) { throw new Error("Failed to derive homeserver name from user ID!"); } return matches[1]; } createClient(creds /*: IMatrixClientCreds*/ ) /*: void*/ { const opts /*: ICreateClientOpts*/ = { baseUrl: creds.homeserverUrl, idBaseUrl: creds.identityServerUrl, accessToken: creds.accessToken, userId: creds.userId, deviceId: creds.deviceId, pickleKey: creds.pickleKey, timelineSupport: true, forceTURN: !_SettingsStore.default.getValue('webRtcAllowPeerToPeer'), fallbackICEServerAllowed: !!_SettingsStore.default.getValue('fallbackICEServerAllowed'), // Gather up to 20 ICE candidates when a call arrives: this should be more than we'd // ever normally need, so effectively this should make all the gathering happen when // the call arrives. iceCandidatePoolSize: 20, verificationMethods: [_crypto.verificationMethods.SAS, _QRCode.SHOW_QR_CODE_METHOD, _crypto.verificationMethods.RECIPROCATE_QR_CODE], unstableClientRelationAggregation: true, identityServer: new _IdentityAuthClient.default(), cryptoCallbacks: {} }; // These are always installed regardless of the labs flag so that // cross-signing features can toggle on without reloading and also be // accessed immediately after login. Object.assign(opts.cryptoCallbacks, _SecurityManager.crossSigningCallbacks); if (_Security.default.getDehydrationKey) { opts.cryptoCallbacks.getDehydrationKey = _Security.default.getDehydrationKey; } this.matrixClient = (0, _createMatrixClient.default)(opts); // we're going to add eventlisteners for each matrix event tile, so the // potential number of event listeners is quite high. this.matrixClient.setMaxListeners(500); this.matrixClient.setGuest(Boolean(creds.guest)); const notifTimelineSet = new _eventTimelineSet.EventTimelineSet(null, { timelineSupport: true }); // XXX: what is our initial pagination token?! it somehow needs to be synchronised with /sync. notifTimelineSet.getLiveTimeline().setPaginationToken("", _eventTimeline.EventTimeline.BACKWARDS); this.matrixClient.setNotifTimelineSet(notifTimelineSet); } } if (!window.mxMatrixClientPeg) { window.mxMatrixClientPeg = new _MatrixClientPeg(); } const MatrixClientPeg = window.mxMatrixClientPeg; exports.MatrixClientPeg = MatrixClientPeg; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9NYXRyaXhDbGllbnRQZWcudHMiXSwibmFtZXMiOlsiX01hdHJpeENsaWVudFBlZyIsImNvbnN0cnVjdG9yIiwiaW5pdGlhbFN5bmNMaW1pdCIsInNldEluZGV4ZWREYldvcmtlclNjcmlwdCIsInNjcmlwdCIsImNyZWF0ZU1hdHJpeENsaWVudCIsImluZGV4ZWREYldvcmtlclNjcmlwdCIsImdldCIsIm1hdHJpeENsaWVudCIsInVuc2V0IiwiTWF0cml4QWN0aW9uQ3JlYXRvcnMiLCJzdG9wIiwic2V0SnVzdFJlZ2lzdGVyZWRVc2VySWQiLCJ1aWQiLCJqdXN0UmVnaXN0ZXJlZFVzZXJJZCIsIndpbmRvdyIsImxvY2FsU3RvcmFnZSIsInNldEl0ZW0iLCJTdHJpbmciLCJEYXRlIiwiZ2V0VGltZSIsImN1cnJlbnRVc2VySXNKdXN0UmVnaXN0ZXJlZCIsImNyZWRlbnRpYWxzIiwidXNlcklkIiwidXNlclJlZ2lzdGVyZWRXaXRoaW5MYXN0SG91cnMiLCJob3VycyIsImRhdGUiLCJnZXRJdGVtIiwiZSIsInJlcGxhY2VVc2luZ0NyZWRzIiwiY3JlZHMiLCJjdXJyZW50Q2xpZW50Q3JlZHMiLCJjcmVhdGVDbGllbnQiLCJhc3NpZ24iLCJkYlR5cGUiLCJwcm9taXNlIiwic3RvcmUiLCJzdGFydHVwIiwiY29uc29sZSIsImxvZyIsImVyciIsImVycm9yIiwiTWVtb3J5U3RvcmUiLCJTdG9yYWdlTWFuYWdlciIsInRyYWNrU3RvcmVzIiwiU2V0dGluZ3NTdG9yZSIsImdldFZhbHVlIiwiaW5pdENyeXB0byIsInNldENyeXB0b1RydXN0Q3Jvc3NTaWduZWREZXZpY2VzIiwic2V0Q3J5cHRvSW5pdGlhbGlzZWQiLCJuYW1lIiwiQ3J5cHRvU3RvcmVUb29OZXdEaWFsb2ciLCJzZGsiLCJnZXRDb21wb25lbnQiLCJNb2RhbCIsImNyZWF0ZURpYWxvZyIsIndhcm4iLCJvcHRzIiwidXRpbHMiLCJkZWVwQ29weSIsInBlbmRpbmdFdmVudE9yZGVyaW5nIiwibGF6eUxvYWRNZW1iZXJzIiwiY2xpZW50V2VsbEtub3duUG9sbFBlcmlvZCIsInN0YXJ0IiwiTWF0cml4Q2xpZW50QmFja2VkU2V0dGluZ3NIYW5kbGVyIiwic3RhcnRDbGllbnQiLCJnZXRDcmVkZW50aWFscyIsImhvbWVzZXJ2ZXJVcmwiLCJiYXNlVXJsIiwiaWRlbnRpdHlTZXJ2ZXJVcmwiLCJpZEJhc2VVcmwiLCJkZXZpY2VJZCIsImdldERldmljZUlkIiwiYWNjZXNzVG9rZW4iLCJnZXRBY2Nlc3NUb2tlbiIsImd1ZXN0IiwiaXNHdWVzdCIsImdldEhvbWVzZXJ2ZXJOYW1lIiwibWF0Y2hlcyIsImV4ZWMiLCJsZW5ndGgiLCJFcnJvciIsInBpY2tsZUtleSIsInRpbWVsaW5lU3VwcG9ydCIsImZvcmNlVFVSTiIsImZhbGxiYWNrSUNFU2VydmVyQWxsb3dlZCIsImljZUNhbmRpZGF0ZVBvb2xTaXplIiwidmVyaWZpY2F0aW9uTWV0aG9kcyIsIlNBUyIsIlNIT1dfUVJfQ09ERV9NRVRIT0QiLCJSRUNJUFJPQ0FURV9RUl9DT0RFIiwidW5zdGFibGVDbGllbnRSZWxhdGlvbkFnZ3JlZ2F0aW9uIiwiaWRlbnRpdHlTZXJ2ZXIiLCJJZGVudGl0eUF1dGhDbGllbnQiLCJjcnlwdG9DYWxsYmFja3MiLCJPYmplY3QiLCJjcm9zc1NpZ25pbmdDYWxsYmFja3MiLCJTZWN1cml0eUN1c3RvbWlzYXRpb25zIiwiZ2V0RGVoeWRyYXRpb25LZXkiLCJzZXRNYXhMaXN0ZW5lcnMiLCJzZXRHdWVzdCIsIkJvb2xlYW4iLCJub3RpZlRpbWVsaW5lU2V0IiwiRXZlbnRUaW1lbGluZVNldCIsImdldExpdmVUaW1lbGluZSIsInNldFBhZ2luYXRpb25Ub2tlbiIsIkV2ZW50VGltZWxpbmUiLCJCQUNLV0FSRFMiLCJzZXROb3RpZlRpbWVsaW5lU2V0IiwibXhNYXRyaXhDbGllbnRQZWciLCJNYXRyaXhDbGllbnRQZWciXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFxQkE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7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LGlCQUEzQixFQUE4QztBQUMxQ3pDLE1BQUFBLElBQUksQ0FBQ3FDLGVBQUwsQ0FBcUJJLGlCQUFyQixHQUNJRCxrQkFBdUJDLGlCQUQzQjtBQUVIOztBQUVELFNBQUsxRixZQUFMLEdBQW9CLGlDQUFtQmlELElBQW5CLENBQXBCLENBbENrRCxDQW9DbEQ7QUFDQTs7QUFDQSxTQUFLakQsWUFBTCxDQUFrQjJGLGVBQWxCLENBQWtDLEdBQWxDO0FBRUEsU0FBSzNGLFlBQUwsQ0FBa0I0RixRQUFsQixDQUEyQkMsT0FBTyxDQUFDdkUsS0FBSyxDQUFDNkMsS0FBUCxDQUFsQztBQUVBLFVBQU0yQixnQkFBZ0IsR0FBRyxJQUFJQyxrQ0FBSixDQUFxQixJQUFyQixFQUEyQjtBQUNoRHBCLE1BQUFBLGVBQWUsRUFBRTtBQUQrQixLQUEzQixDQUF6QixDQTFDa0QsQ0E2Q2xEOztBQUNBbUIsSUFBQUEsZ0JBQWdCLENBQUNFLGVBQWpCLEdBQW1DQyxrQkFBbkMsQ0FBc0QsRUFBdEQsRUFBMERDLDZCQUFjQyxTQUF4RTtBQUNBLFNBQUtuRyxZQUFMLENBQWtCb0csbUJBQWxCLENBQXNDTixnQkFBdEM7QUFDSDs7QUFsTThDOztBQXFNbkQsSUFBSSxDQUFDdkYsTUFBTSxDQUFDOEYsaUJBQVosRUFBK0I7QUFDM0I5RixFQUFBQSxNQUFNLENBQUM4RixpQkFBUCxHQUEyQixJQUFJN0csZ0JBQUosRUFBM0I7QUFDSDs7QUFFTSxNQUFNOEcsZUFBZSxHQUFHL0YsTUFBTSxDQUFDOEYsaUJBQS9CIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDE1LCAyMDE2IE9wZW5NYXJrZXQgTHRkXG5Db3B5cmlnaHQgMjAxNyBWZWN0b3IgQ3JlYXRpb25zIEx0ZC5cbkNvcHlyaWdodCAyMDE3LCAyMDE4LCAyMDE5IE5ldyBWZWN0b3IgTHRkXG5Db3B5cmlnaHQgMjAxOSwgMjAyMCBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCB7IElDcmVhdGVDbGllbnRPcHRzIH0gZnJvbSAnbWF0cml4LWpzLXNkay9zcmMvbWF0cml4JztcbmltcG9ydCB7TWF0cml4Q2xpZW50fSBmcm9tICdtYXRyaXgtanMtc2RrL3NyYy9jbGllbnQnO1xuaW1wb3J0IHtNZW1vcnlTdG9yZX0gZnJvbSAnbWF0cml4LWpzLXNkay9zcmMvc3RvcmUvbWVtb3J5JztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJ21hdHJpeC1qcy1zZGsvc3JjL3V0aWxzJztcbmltcG9ydCB7RXZlbnRUaW1lbGluZX0gZnJvbSAnbWF0cml4LWpzLXNkay9zcmMvbW9kZWxzL2V2ZW50LXRpbWVsaW5lJztcbmltcG9ydCB7RXZlbnRUaW1lbGluZVNldH0gZnJvbSAnbWF0cml4LWpzLXNkay9zcmMvbW9kZWxzL2V2ZW50LXRpbWVsaW5lLXNldCc7XG5pbXBvcnQgKiBhcyBzZGsgZnJvbSAnLi9pbmRleCc7XG5pbXBvcnQgY3JlYXRlTWF0cml4Q2xpZW50IGZyb20gJy4vdXRpbHMvY3JlYXRlTWF0cml4Q2xpZW50JztcbmltcG9ydCBTZXR0aW5nc1N0b3JlIGZyb20gJy4vc2V0dGluZ3MvU2V0dGluZ3NTdG9yZSc7XG5pbXBvcnQgTWF0cml4QWN0aW9uQ3JlYXRvcnMgZnJvbSAnLi9hY3Rpb25zL01hdHJpeEFjdGlvbkNyZWF0b3JzJztcbmltcG9ydCBNb2RhbCBmcm9tICcuL01vZGFsJztcbmltcG9ydCB7dmVyaWZpY2F0aW9uTWV0aG9kc30gZnJvbSAnbWF0cml4LWpzLXNkay9zcmMvY3J5cHRvJztcbmltcG9ydCBNYXRyaXhDbGllbnRCYWNrZWRTZXR0aW5nc0hhbmRsZXIgZnJvbSBcIi4vc2V0dGluZ3MvaGFuZGxlcnMvTWF0cml4Q2xpZW50QmFja2VkU2V0dGluZ3NIYW5kbGVyXCI7XG5pbXBvcnQgKiBhcyBTdG9yYWdlTWFuYWdlciBmcm9tICcuL3V0aWxzL1N0b3JhZ2VNYW5hZ2VyJztcbmltcG9ydCBJZGVudGl0eUF1dGhDbGllbnQgZnJvbSAnLi9JZGVudGl0eUF1dGhDbGllbnQnO1xuaW1wb3J0IHsgY3Jvc3NTaWduaW5nQ2FsbGJhY2tzLCB0cnlUb1VubG9ja1NlY3JldFN0b3JhZ2VXaXRoRGVoeWRyYXRpb25LZXkgfSBmcm9tICcuL1NlY3VyaXR5TWFuYWdlcic7XG5pbXBvcnQge1NIT1dfUVJfQ09ERV9NRVRIT0R9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9jcnlwdG8vdmVyaWZpY2F0aW9uL1FSQ29kZVwiO1xuaW1wb3J0IFNlY3VyaXR5Q3VzdG9taXNhdGlvbnMgZnJvbSBcIi4vY3VzdG9taXNhdGlvbnMvU2VjdXJpdHlcIjtcblxuZXhwb3J0IGludGVyZmFjZSBJTWF0cml4Q2xpZW50Q3JlZHMge1xuICAgIGhvbWVzZXJ2ZXJVcmw6IHN0cmluZztcbiAgICBpZGVudGl0eVNlcnZlclVybDogc3RyaW5nO1xuICAgIHVzZXJJZDogc3RyaW5nO1xuICAgIGRldmljZUlkPzogc3RyaW5nO1xuICAgIGFjY2Vzc1Rva2VuOiBzdHJpbmc7XG4gICAgZ3Vlc3Q/OiBib29sZWFuO1xuICAgIHBpY2tsZUtleT86IHN0cmluZztcbiAgICBmcmVzaExvZ2luPzogYm9vbGVhbjtcbn1cblxuLy8gVE9ETzogTW92ZSB0aGlzIHRvIHRoZSBqcy1zZGtcbmV4cG9ydCBpbnRlcmZhY2UgSU9wdHMge1xuICAgIGluaXRpYWxTeW5jTGltaXQ/OiBudW1iZXI7XG4gICAgcGVuZGluZ0V2ZW50T3JkZXJpbmc/OiBcImRldGFjaGVkXCIgfCBcImNocm9ub2xvZ2ljYWxcIjtcbiAgICBsYXp5TG9hZE1lbWJlcnM/OiBib29sZWFuO1xuICAgIGNsaWVudFdlbGxLbm93blBvbGxQZXJpb2Q/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSU1hdHJpeENsaWVudFBlZyB7XG4gICAgb3B0czogSU9wdHM7XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBzY3JpcHQgaHJlZiBwYXNzZWQgdG8gdGhlIEluZGV4ZWREQiB3ZWIgd29ya2VyXG4gICAgICogSWYgc2V0LCBhIHNlcGFyYXRlIHdlYiB3b3JrZXIgd2lsbCBiZSBzdGFydGVkIHRvIHJ1biB0aGUgSW5kZXhlZERCXG4gICAgICogcXVlcmllcyBvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzY3JpcHQgaHJlZiB0byB0aGUgc2NyaXB0IHRvIGJlIHBhc3NlZCB0byB0aGUgd2ViIHdvcmtlclxuICAgICAqL1xuICAgIHNldEluZGV4ZWREYldvcmtlclNjcmlwdChzY3JpcHQ6IHN0cmluZyk6IHZvaWQ7XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHNlcnZlciBuYW1lIG9mIHRoZSB1c2VyJ3MgaG9tZXNlcnZlclxuICAgICAqIFRocm93cyBhbiBlcnJvciBpZiB1bmFibGUgdG8gZGVkdWNlIHRoZSBob21lc2VydmVyIG5hbWVcbiAgICAgKiAoZWcuIGlmIHRoZSB1c2VyIGlzIG5vdCBsb2dnZWQgaW4pXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgaG9tZXNlcnZlciBuYW1lLCBpZiBwcmVzZW50LlxuICAgICAqL1xuICAgIGdldEhvbWVzZXJ2ZXJOYW1lKCk6IHN0cmluZztcblxuICAgIGdldCgpOiBNYXRyaXhDbGllbnQ7XG4gICAgdW5zZXQoKTogdm9pZDtcbiAgICBhc3NpZ24oKTogUHJvbWlzZTxhbnk+O1xuICAgIHN0YXJ0KCk6IFByb21pc2U8YW55PjtcblxuICAgIGdldENyZWRlbnRpYWxzKCk6IElNYXRyaXhDbGllbnRDcmVkcztcblxuICAgIC8qKlxuICAgICAqIElmIHdlJ3ZlIHJlZ2lzdGVyZWQgYSB1c2VyIElEIHdlIHNldCB0aGlzIHRvIHRoZSBJRCBvZiB0aGVcbiAgICAgKiB1c2VyIHdlJ3ZlIGp1c3QgcmVnaXN0ZXJlZC4gSWYgdGhleSB0aGVuIGdvICYgbG9nIGluLCB3ZVxuICAgICAqIGNhbiBzZW5kIHRoZW0gdG8gdGhlIHdlbGNvbWUgdXNlciAob2J2aW91c2x5IHRoaXMgZG9lc24ndFxuICAgICAqIGd1YXJlbnRlZSB0aGV5J2xsIGdldCBhIGNoYXQgd2l0aCB0aGUgd2VsY29tZSB1c2VyKS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1aWQgVGhlIHVzZXIgSUQgb2YgdGhlIHVzZXIgd2UndmUganVzdCByZWdpc3RlcmVkXG4gICAgICovXG4gICAgc2V0SnVzdFJlZ2lzdGVyZWRVc2VySWQodWlkOiBzdHJpbmcpOiB2b2lkO1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjdXJyZW50IHVzZXIgaGFzIGp1c3QgYmVlbiByZWdpc3RlcmVkIGJ5IHRoaXNcbiAgICAgKiBjbGllbnQgYXMgZGV0ZXJtaW5lZCBieSBzZXRKdXN0UmVnaXN0ZXJlZFVzZXJJZCgpXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7Ym9vbH0gVHJ1ZSBpZiB1c2VyIGhhcyBqdXN0IGJlZW4gcmVnaXN0ZXJlZFxuICAgICAqL1xuICAgIGN1cnJlbnRVc2VySXNKdXN0UmVnaXN0ZXJlZCgpOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogSWYgdGhlIGN1cnJlbnQgdXNlciBoYXMgYmVlbiByZWdpc3RlcmVkIGJ5IHRoaXMgZGV2aWNlIHRoZW4gdGhpc1xuICAgICAqIHJldHVybnMgYSBib29sZWFuIG9mIHdoZXRoZXIgaXQgd2FzIHdpdGhpbiB0aGUgbGFzdCBOIGhvdXJzIGdpdmVuLlxuICAgICAqL1xuICAgIHVzZXJSZWdpc3RlcmVkV2l0aGluTGFzdEhvdXJzKGhvdXJzOiBudW1iZXIpOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogUmVwbGFjZSB0aGlzIE1hdHJpeENsaWVudFBlZydzIGNsaWVudCB3aXRoIGEgY2xpZW50IGluc3RhbmNlIHRoYXQgaGFzXG4gICAgICogaG9tZXNlcnZlciAvIGlkZW50aXR5IHNlcnZlciBVUkxzIGFuZCBhY3RpdmUgY3JlZGVudGlhbHNcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7SU1hdHJpeENsaWVudENyZWRzfSBjcmVkcyBUaGUgbmV3IGNyZWRlbnRpYWxzIHRvIHVzZS5cbiAgICAgKi9cbiAgICByZXBsYWNlVXNpbmdDcmVkcyhjcmVkczogSU1hdHJpeENsaWVudENyZWRzKTogdm9pZDtcbn1cblxuLyoqXG4gKiBXcmFwcGVyIG9iamVjdCBmb3IgaGFuZGxpbmcgdGhlIGpzLXNkayBNYXRyaXggQ2xpZW50IG9iamVjdCBpbiB0aGUgcmVhY3Qtc2RrXG4gKiBIYW5kbGVzIHRoZSBjcmVhdGlvbi9pbml0aWFsaXNhdGlvbiBvZiBjbGllbnQgb2JqZWN0cy5cbiAqIFRoaXMgbW9kdWxlIHByb3ZpZGVzIGEgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoaXMgY2xhc3Mgc28gdGhlICdjdXJyZW50J1xuICogTWF0cml4IENsaWVudCBvYmplY3QgaXMgYXZhaWxhYmxlIGVhc2lseS5cbiAqL1xuY2xhc3MgX01hdHJpeENsaWVudFBlZyBpbXBsZW1lbnRzIElNYXRyaXhDbGllbnRQZWcge1xuICAgIC8vIFRoZXNlIGFyZSB0aGUgZGVmYXVsdCBvcHRpb25zIHVzZWQgd2hlbiB3aGVuIHRoZVxuICAgIC8vIGNsaWVudCBpcyBzdGFydGVkIGluICdzdGFydCcuIFRoZXNlIGNhbiBiZSBhbHRlcmVkXG4gICAgLy8gYXQgYW55IHRpbWUgdXAgdG8gYWZ0ZXIgdGhlICd3aWxsX3N0YXJ0X2NsaWVudCdcbiAgICAvLyBldmVudCBpcyBmaW5pc2hlZCBwcm9jZXNzaW5nLlxuICAgIHB1YmxpYyBvcHRzOiBJT3B0cyA9IHtcbiAgICAgICAgaW5pdGlhbFN5bmNMaW1pdDogMjAsXG4gICAgfTtcblxuICAgIHByaXZhdGUgbWF0cml4Q2xpZW50OiBNYXRyaXhDbGllbnQgPSBudWxsO1xuICAgIHByaXZhdGUganVzdFJlZ2lzdGVyZWRVc2VySWQ6IHN0cmluZztcblxuICAgIC8vIHRoZSBjcmVkZW50aWFscyB1c2VkIHRvIGluaXQgdGhlIGN1cnJlbnQgY2xpZW50IG9iamVjdC5cbiAgICAvLyB1c2VkIGlmIHdlIHRlYXIgaXQgZG93biAmIHJlY3JlYXRlIGl0IHdpdGggYSBkaWZmZXJlbnQgc3RvcmVcbiAgICBwcml2YXRlIGN1cnJlbnRDbGllbnRDcmVkczogSU1hdHJpeENsaWVudENyZWRzO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgfVxuXG4gICAgcHVibGljIHNldEluZGV4ZWREYldvcmtlclNjcmlwdChzY3JpcHQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjcmVhdGVNYXRyaXhDbGllbnQuaW5kZXhlZERiV29ya2VyU2NyaXB0ID0gc2NyaXB0O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQoKTogTWF0cml4Q2xpZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWF0cml4Q2xpZW50O1xuICAgIH1cblxuICAgIHB1YmxpYyB1bnNldCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5tYXRyaXhDbGllbnQgPSBudWxsO1xuXG4gICAgICAgIE1hdHJpeEFjdGlvbkNyZWF0b3JzLnN0b3AoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0SnVzdFJlZ2lzdGVyZWRVc2VySWQodWlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5qdXN0UmVnaXN0ZXJlZFVzZXJJZCA9IHVpZDtcbiAgICAgICAgaWYgKHVpZCkge1xuICAgICAgICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKFwibXhfcmVnaXN0cmF0aW9uX3RpbWVcIiwgU3RyaW5nKG5ldyBEYXRlKCkuZ2V0VGltZSgpKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY3VycmVudFVzZXJJc0p1c3RSZWdpc3RlcmVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgdGhpcy5tYXRyaXhDbGllbnQgJiZcbiAgICAgICAgICAgIHRoaXMubWF0cml4Q2xpZW50LmNyZWRlbnRpYWxzLnVzZXJJZCA9PT0gdGhpcy5qdXN0UmVnaXN0ZXJlZFVzZXJJZFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyB1c2VyUmVnaXN0ZXJlZFdpdGhpbkxhc3RIb3Vycyhob3VyczogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUod2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKFwibXhfcmVnaXN0cmF0aW9uX3RpbWVcIikpO1xuICAgICAgICAgICAgcmV0dXJuICgobmV3IERhdGUoKS5nZXRUaW1lKCkgLSBkYXRlLmdldFRpbWUoKSkgLyAzNmU1KSA8PSBob3VycztcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHJlcGxhY2VVc2luZ0NyZWRzKGNyZWRzOiBJTWF0cml4Q2xpZW50Q3JlZHMpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jdXJyZW50Q2xpZW50Q3JlZHMgPSBjcmVkcztcbiAgICAgICAgdGhpcy5jcmVhdGVDbGllbnQoY3JlZHMpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBhc3NpZ24oKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgZm9yIChjb25zdCBkYlR5cGUgb2YgWydpbmRleGVkZGInLCAnbWVtb3J5J10pIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMubWF0cml4Q2xpZW50LnN0b3JlLnN0YXJ0dXAoKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIk1hdHJpeENsaWVudFBlZzogd2FpdGluZyBmb3IgTWF0cml4Q2xpZW50IHN0b3JlIHRvIGluaXRpYWxpc2VcIik7XG4gICAgICAgICAgICAgICAgYXdhaXQgcHJvbWlzZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIGlmIChkYlR5cGUgPT09ICdpbmRleGVkZGInKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHN0YXJ0aW5nIG1hdHJpeGNsaWVudCBzdG9yZSAtIGZhbGxpbmcgYmFjayB0byBtZW1vcnkgc3RvcmUnLCBlcnIpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdHJpeENsaWVudC5zdG9yZSA9IG5ldyBNZW1vcnlTdG9yZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2NhbFN0b3JhZ2U6IGxvY2FsU3RvcmFnZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIHN0YXJ0IG1lbW9yeSBzdG9yZSEnLCBlcnIpO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgU3RvcmFnZU1hbmFnZXIudHJhY2tTdG9yZXModGhpcy5tYXRyaXhDbGllbnQpO1xuXG4gICAgICAgIC8vIHRyeSB0byBpbml0aWFsaXNlIGUyZSBvbiB0aGUgbmV3IGNsaWVudFxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCB3ZSBoYXZlIGEgdmVyc2lvbiBvZiB0aGUganMtc2RrIHdoaWNoIGluY2x1ZGVzIGluaXRDcnlwdG9cbiAgICAgICAgICAgIGlmICghU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZShcImxvd0JhbmR3aWR0aFwiKSAmJiB0aGlzLm1hdHJpeENsaWVudC5pbml0Q3J5cHRvKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5tYXRyaXhDbGllbnQuaW5pdENyeXB0bygpO1xuICAgICAgICAgICAgICAgIHRoaXMubWF0cml4Q2xpZW50LnNldENyeXB0b1RydXN0Q3Jvc3NTaWduZWREZXZpY2VzKFxuICAgICAgICAgICAgICAgICAgICAhU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZSgnZTJlZS5tYW51YWxseVZlcmlmeUFsbFNlc3Npb25zJyksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0cnlUb1VubG9ja1NlY3JldFN0b3JhZ2VXaXRoRGVoeWRyYXRpb25LZXkodGhpcy5tYXRyaXhDbGllbnQpO1xuICAgICAgICAgICAgICAgIFN0b3JhZ2VNYW5hZ2VyLnNldENyeXB0b0luaXRpYWxpc2VkKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoZSAmJiBlLm5hbWUgPT09ICdJbnZhbGlkQ3J5cHRvU3RvcmVFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAvLyBUaGUganMtc2RrIGZvdW5kIGEgY3J5cHRvIERCIHRvbyBuZXcgZm9yIGl0IHRvIHVzZVxuICAgICAgICAgICAgICAgIGNvbnN0IENyeXB0b1N0b3JlVG9vTmV3RGlhbG9nID1cbiAgICAgICAgICAgICAgICAgICAgc2RrLmdldENvbXBvbmVudChcInZpZXdzLmRpYWxvZ3MuQ3J5cHRvU3RvcmVUb29OZXdEaWFsb2dcIik7XG4gICAgICAgICAgICAgICAgTW9kYWwuY3JlYXRlRGlhbG9nKENyeXB0b1N0b3JlVG9vTmV3RGlhbG9nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHRoaXMgY2FuIGhhcHBlbiBmb3IgYSBudW1iZXIgb2YgcmVhc29ucywgdGhlIG1vc3QgbGlrZWx5IGJlaW5nXG4gICAgICAgICAgICAvLyB0aGF0IHRoZSBvbG0gbGlicmFyeSB3YXMgbWlzc2luZy4gSXQncyBub3QgZmF0YWwuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCJVbmFibGUgdG8gaW5pdGlhbGlzZSBlMmVcIiwgZSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBvcHRzID0gdXRpbHMuZGVlcENvcHkodGhpcy5vcHRzKTtcbiAgICAgICAgLy8gdGhlIHJlYWN0IHNkayBkb2Vzbid0IHdvcmsgd2l0aG91dCB0aGlzLCBzbyBkb24ndCBhbGxvd1xuICAgICAgICBvcHRzLnBlbmRpbmdFdmVudE9yZGVyaW5nID0gXCJkZXRhY2hlZFwiO1xuICAgICAgICBvcHRzLmxhenlMb2FkTWVtYmVycyA9IHRydWU7XG4gICAgICAgIG9wdHMuY2xpZW50V2VsbEtub3duUG9sbFBlcmlvZCA9IDIgKiA2MCAqIDYwOyAvLyAyIGhvdXJzXG5cbiAgICAgICAgLy8gQ29ubmVjdCB0aGUgbWF0cml4IGNsaWVudCB0byB0aGUgZGlzcGF0Y2hlciBhbmQgc2V0dGluZyBoYW5kbGVyc1xuICAgICAgICBNYXRyaXhBY3Rpb25DcmVhdG9ycy5zdGFydCh0aGlzLm1hdHJpeENsaWVudCk7XG4gICAgICAgIE1hdHJpeENsaWVudEJhY2tlZFNldHRpbmdzSGFuZGxlci5tYXRyaXhDbGllbnQgPSB0aGlzLm1hdHJpeENsaWVudDtcblxuICAgICAgICByZXR1cm4gb3B0cztcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgc3RhcnQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgY29uc3Qgb3B0cyA9IGF3YWl0IHRoaXMuYXNzaWduKCk7XG5cbiAgICAgICAgY29uc29sZS5sb2coYE1hdHJpeENsaWVudFBlZzogcmVhbGx5IHN0YXJ0aW5nIE1hdHJpeENsaWVudGApO1xuICAgICAgICBhd2FpdCB0aGlzLmdldCgpLnN0YXJ0Q2xpZW50KG9wdHMpO1xuICAgICAgICBjb25zb2xlLmxvZyhgTWF0cml4Q2xpZW50UGVnOiBNYXRyaXhDbGllbnQgc3RhcnRlZGApO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRDcmVkZW50aWFscygpOiBJTWF0cml4Q2xpZW50Q3JlZHMge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaG9tZXNlcnZlclVybDogdGhpcy5tYXRyaXhDbGllbnQuYmFzZVVybCxcbiAgICAgICAgICAgIGlkZW50aXR5U2VydmVyVXJsOiB0aGlzLm1hdHJpeENsaWVudC5pZEJhc2VVcmwsXG4gICAgICAgICAgICB1c2VySWQ6IHRoaXMubWF0cml4Q2xpZW50LmNyZWRlbnRpYWxzLnVzZXJJZCxcbiAgICAgICAgICAgIGRldmljZUlkOiB0aGlzLm1hdHJpeENsaWVudC5nZXREZXZpY2VJZCgpLFxuICAgICAgICAgICAgYWNjZXNzVG9rZW46IHRoaXMubWF0cml4Q2xpZW50LmdldEFjY2Vzc1Rva2VuKCksXG4gICAgICAgICAgICBndWVzdDogdGhpcy5tYXRyaXhDbGllbnQuaXNHdWVzdCgpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRIb21lc2VydmVyTmFtZSgpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBtYXRjaGVzID0gL15AW146XSs6KC4rKSQvLmV4ZWModGhpcy5tYXRyaXhDbGllbnQuY3JlZGVudGlhbHMudXNlcklkKTtcbiAgICAgICAgaWYgKG1hdGNoZXMgPT09IG51bGwgfHwgbWF0Y2hlcy5sZW5ndGggPCAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gZGVyaXZlIGhvbWVzZXJ2ZXIgbmFtZSBmcm9tIHVzZXIgSUQhXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXRjaGVzWzFdO1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlQ2xpZW50KGNyZWRzOiBJTWF0cml4Q2xpZW50Q3JlZHMpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb3B0czogSUNyZWF0ZUNsaWVudE9wdHMgPSB7XG4gICAgICAgICAgICBiYXNlVXJsOiBjcmVkcy5ob21lc2VydmVyVXJsLFxuICAgICAgICAgICAgaWRCYXNlVXJsOiBjcmVkcy5pZGVudGl0eVNlcnZlclVybCxcbiAgICAgICAgICAgIGFjY2Vzc1Rva2VuOiBjcmVkcy5hY2Nlc3NUb2tlbixcbiAgICAgICAgICAgIHVzZXJJZDogY3JlZHMudXNlcklkLFxuICAgICAgICAgICAgZGV2aWNlSWQ6IGNyZWRzLmRldmljZUlkLFxuICAgICAgICAgICAgcGlja2xlS2V5OiBjcmVkcy5waWNrbGVLZXksXG4gICAgICAgICAgICB0aW1lbGluZVN1cHBvcnQ6IHRydWUsXG4gICAgICAgICAgICBmb3JjZVRVUk46ICFTZXR0aW5nc1N0b3JlLmdldFZhbHVlKCd3ZWJSdGNBbGxvd1BlZXJUb1BlZXInKSxcbiAgICAgICAgICAgIGZhbGxiYWNrSUNFU2VydmVyQWxsb3dlZDogISFTZXR0aW5nc1N0b3JlLmdldFZhbHVlKCdmYWxsYmFja0lDRVNlcnZlckFsbG93ZWQnKSxcbiAgICAgICAgICAgIC8vIEdhdGhlciB1cCB0byAyMCBJQ0UgY2FuZGlkYXRlcyB3aGVuIGEgY2FsbCBhcnJpdmVzOiB0aGlzIHNob3VsZCBiZSBtb3JlIHRoYW4gd2UnZFxuICAgICAgICAgICAgLy8gZXZlciBub3JtYWxseSBuZWVkLCBzbyBlZmZlY3RpdmVseSB0aGlzIHNob3VsZCBtYWtlIGFsbCB0aGUgZ2F0aGVyaW5nIGhhcHBlbiB3aGVuXG4gICAgICAgICAgICAvLyB0aGUgY2FsbCBhcnJpdmVzLlxuICAgICAgICAgICAgaWNlQ2FuZGlkYXRlUG9vbFNpemU6IDIwLFxuICAgICAgICAgICAgdmVyaWZpY2F0aW9uTWV0aG9kczogW1xuICAgICAgICAgICAgICAgIHZlcmlmaWNhdGlvbk1ldGhvZHMuU0FTLFxuICAgICAgICAgICAgICAgIFNIT1dfUVJfQ09ERV9NRVRIT0QsXG4gICAgICAgICAgICAgICAgdmVyaWZpY2F0aW9uTWV0aG9kcy5SRUNJUFJPQ0FURV9RUl9DT0RFLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHVuc3RhYmxlQ2xpZW50UmVsYXRpb25BZ2dyZWdhdGlvbjogdHJ1ZSxcbiAgICAgICAgICAgIGlkZW50aXR5U2VydmVyOiBuZXcgSWRlbnRpdHlBdXRoQ2xpZW50KCksXG4gICAgICAgICAgICBjcnlwdG9DYWxsYmFja3M6IHt9LFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFRoZXNlIGFyZSBhbHdheXMgaW5zdGFsbGVkIHJlZ2FyZGxlc3Mgb2YgdGhlIGxhYnMgZmxhZyBzbyB0aGF0XG4gICAgICAgIC8vIGNyb3NzLXNpZ25pbmcgZmVhdHVyZXMgY2FuIHRvZ2dsZSBvbiB3aXRob3V0IHJlbG9hZGluZyBhbmQgYWxzbyBiZVxuICAgICAgICAvLyBhY2Nlc3NlZCBpbW1lZGlhdGVseSBhZnRlciBsb2dpbi5cbiAgICAgICAgT2JqZWN0LmFzc2lnbihvcHRzLmNyeXB0b0NhbGxiYWNrcywgY3Jvc3NTaWduaW5nQ2FsbGJhY2tzKTtcbiAgICAgICAgaWYgKFNlY3VyaXR5Q3VzdG9taXNhdGlvbnMuZ2V0RGVoeWRyYXRpb25LZXkpIHtcbiAgICAgICAgICAgIG9wdHMuY3J5cHRvQ2FsbGJhY2tzLmdldERlaHlkcmF0aW9uS2V5ID1cbiAgICAgICAgICAgICAgICBTZWN1cml0eUN1c3RvbWlzYXRpb25zLmdldERlaHlkcmF0aW9uS2V5O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tYXRyaXhDbGllbnQgPSBjcmVhdGVNYXRyaXhDbGllbnQob3B0cyk7XG5cbiAgICAgICAgLy8gd2UncmUgZ29pbmcgdG8gYWRkIGV2ZW50bGlzdGVuZXJzIGZvciBlYWNoIG1hdHJpeCBldmVudCB0aWxlLCBzbyB0aGVcbiAgICAgICAgLy8gcG90ZW50aWFsIG51bWJlciBvZiBldmVudCBsaXN0ZW5lcnMgaXMgcXVpdGUgaGlnaC5cbiAgICAgICAgdGhpcy5tYXRyaXhDbGllbnQuc2V0TWF4TGlzdGVuZXJzKDUwMCk7XG5cbiAgICAgICAgdGhpcy5tYXRyaXhDbGllbnQuc2V0R3Vlc3QoQm9vbGVhbihjcmVkcy5ndWVzdCkpO1xuXG4gICAgICAgIGNvbnN0IG5vdGlmVGltZWxpbmVTZXQgPSBuZXcgRXZlbnRUaW1lbGluZVNldChudWxsLCB7XG4gICAgICAgICAgICB0aW1lbGluZVN1cHBvcnQ6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBYWFg6IHdoYXQgaXMgb3VyIGluaXRpYWwgcGFnaW5hdGlvbiB0b2tlbj8hIGl0IHNvbWVob3cgbmVlZHMgdG8gYmUgc3luY2hyb25pc2VkIHdpdGggL3N5bmMuXG4gICAgICAgIG5vdGlmVGltZWxpbmVTZXQuZ2V0TGl2ZVRpbWVsaW5lKCkuc2V0UGFnaW5hdGlvblRva2VuKFwiXCIsIEV2ZW50VGltZWxpbmUuQkFDS1dBUkRTKTtcbiAgICAgICAgdGhpcy5tYXRyaXhDbGllbnQuc2V0Tm90aWZUaW1lbGluZVNldChub3RpZlRpbWVsaW5lU2V0KTtcbiAgICB9XG59XG5cbmlmICghd2luZG93Lm14TWF0cml4Q2xpZW50UGVnKSB7XG4gICAgd2luZG93Lm14TWF0cml4Q2xpZW50UGVnID0gbmV3IF9NYXRyaXhDbGllbnRQZWcoKTtcbn1cblxuZXhwb3J0IGNvbnN0IE1hdHJpeENsaWVudFBlZyA9IHdpbmRvdy5teE1hdHJpeENsaWVudFBlZztcbiJdfQ==