"use strict"; var _util = require("util"); var _triggers = require("./triggers"); var _logger = require("./logger"); var _RestQuery = _interopRequireDefault(require("./RestQuery")); var _RestWrite = _interopRequireDefault(require("./RestWrite")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } const Parse = require('parse/node'); // An Auth object tells you who is requesting something and whether // the master key was used. // userObject is a Parse.User and can be null if there's no user. function Auth({ config, cacheController = undefined, isMaster = false, isMaintenance = false, isReadOnly = false, user, installationId }) { this.config = config; this.cacheController = cacheController || config && config.cacheController; this.installationId = installationId; this.isMaster = isMaster; this.isMaintenance = isMaintenance; this.user = user; this.isReadOnly = isReadOnly; // Assuming a users roles won't change during a single request, we'll // only load them once. this.userRoles = []; this.fetchedRoles = false; this.rolePromise = null; } // Whether this auth could possibly modify the given user id. // It still could be forbidden via ACLs even if this returns true. Auth.prototype.isUnauthenticated = function () { if (this.isMaster) { return false; } if (this.isMaintenance) { return false; } if (this.user) { return false; } return true; }; // A helper to get a master-level Auth object function master(config) { return new Auth({ config, isMaster: true }); } // A helper to get a maintenance-level Auth object function maintenance(config) { return new Auth({ config, isMaintenance: true }); } // A helper to get a master-level Auth object function readOnly(config) { return new Auth({ config, isMaster: true, isReadOnly: true }); } // A helper to get a nobody-level Auth object function nobody(config) { return new Auth({ config, isMaster: false }); } /** * Checks whether session should be updated based on last update time & session length. */ function shouldUpdateSessionExpiry(config, session) { const resetAfter = config.sessionLength / 2; const lastUpdated = new Date(session === null || session === void 0 ? void 0 : session.updatedAt); const skipRange = new Date(); skipRange.setTime(skipRange.getTime() - resetAfter * 1000); return lastUpdated <= skipRange; } const throttle = {}; const renewSessionIfNeeded = async ({ config, session, sessionToken }) => { if (!(config !== null && config !== void 0 && config.extendSessionOnUse)) { return; } clearTimeout(throttle[sessionToken]); throttle[sessionToken] = setTimeout(async () => { try { if (!session) { const query = await (0, _RestQuery.default)({ method: _RestQuery.default.Method.get, config, auth: master(config), runBeforeFind: false, className: '_Session', restWhere: { sessionToken }, restOptions: { limit: 1 } }); const { results } = await query.execute(); session = results[0]; } if (!shouldUpdateSessionExpiry(config, session) || !session) { return; } const expiresAt = config.generateSessionExpiresAt(); await new _RestWrite.default(config, master(config), '_Session', { objectId: session.objectId }, { expiresAt: Parse._encode(expiresAt) }).execute(); } catch (e) { if ((e === null || e === void 0 ? void 0 : e.code) !== Parse.Error.OBJECT_NOT_FOUND) { _logger.logger.error('Could not update session expiry: ', e); } } }, 500); }; // Returns a promise that resolves to an Auth object const getAuthForSessionToken = async function ({ config, cacheController, sessionToken, installationId }) { cacheController = cacheController || config && config.cacheController; if (cacheController) { const userJSON = await cacheController.user.get(sessionToken); if (userJSON) { const cachedUser = Parse.Object.fromJSON(userJSON); renewSessionIfNeeded({ config, sessionToken }); return Promise.resolve(new Auth({ config, cacheController, isMaster: false, installationId, user: cachedUser })); } } let results; if (config) { const restOptions = { limit: 1, include: 'user' }; const RestQuery = require('./RestQuery'); const query = await RestQuery({ method: RestQuery.Method.get, config, runBeforeFind: false, auth: master(config), className: '_Session', restWhere: { sessionToken }, restOptions }); results = (await query.execute()).results; } else { results = (await new Parse.Query(Parse.Session).limit(1).include('user').equalTo('sessionToken', sessionToken).find({ useMasterKey: true })).map(obj => obj.toJSON()); } if (results.length !== 1 || !results[0]['user']) { throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); } const session = results[0]; const now = new Date(), expiresAt = session.expiresAt ? new Date(session.expiresAt.iso) : undefined; if (expiresAt < now) { throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token is expired.'); } const obj = session.user; if (typeof obj['objectId'] === 'string' && obj['objectId'].startsWith('role:')) { throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Invalid object ID.'); } delete obj.password; obj['className'] = '_User'; obj['sessionToken'] = sessionToken; if (cacheController) { cacheController.user.put(sessionToken, obj); } renewSessionIfNeeded({ config, session, sessionToken }); const userObject = Parse.Object.fromJSON(obj); return new Auth({ config, cacheController, isMaster: false, installationId, user: userObject }); }; var getAuthForLegacySessionToken = async function ({ config, sessionToken, installationId }) { var restOptions = { limit: 1 }; const RestQuery = require('./RestQuery'); var query = await RestQuery({ method: RestQuery.Method.get, config, runBeforeFind: false, auth: master(config), className: '_User', restWhere: { _session_token: sessionToken }, restOptions }); return query.execute().then(response => { var results = response.results; if (results.length !== 1) { throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'invalid legacy session token'); } const obj = results[0]; obj.className = '_User'; const userObject = Parse.Object.fromJSON(obj); return new Auth({ config, isMaster: false, installationId, user: userObject }); }); }; // Returns a promise that resolves to an array of role names Auth.prototype.getUserRoles = function () { if (this.isMaster || this.isMaintenance || !this.user) { return Promise.resolve([]); } if (this.fetchedRoles) { return Promise.resolve(this.userRoles); } if (this.rolePromise) { return this.rolePromise; } this.rolePromise = this._loadRoles(); return this.rolePromise; }; Auth.prototype.getRolesForUser = async function () { //Stack all Parse.Role const results = []; if (this.config) { const restWhere = { users: { __type: 'Pointer', className: '_User', objectId: this.user.id } }; const RestQuery = require('./RestQuery'); const query = await RestQuery({ method: RestQuery.Method.find, runBeforeFind: false, config: this.config, auth: master(this.config), className: '_Role', restWhere }); await query.each(result => results.push(result)); } else { await new Parse.Query(Parse.Role).equalTo('users', this.user).each(result => results.push(result.toJSON()), { useMasterKey: true }); } return results; }; // Iterates through the role tree and compiles a user's roles Auth.prototype._loadRoles = async function () { if (this.cacheController) { const cachedRoles = await this.cacheController.role.get(this.user.id); if (cachedRoles != null) { this.fetchedRoles = true; this.userRoles = cachedRoles; return cachedRoles; } } // First get the role ids this user is directly a member of const results = await this.getRolesForUser(); if (!results.length) { this.userRoles = []; this.fetchedRoles = true; this.rolePromise = null; this.cacheRoles(); return this.userRoles; } const rolesMap = results.reduce((m, r) => { m.names.push(r.name); m.ids.push(r.objectId); return m; }, { ids: [], names: [] }); // run the recursive finding const roleNames = await this._getAllRolesNamesForRoleIds(rolesMap.ids, rolesMap.names); this.userRoles = roleNames.map(r => { return 'role:' + r; }); this.fetchedRoles = true; this.rolePromise = null; this.cacheRoles(); return this.userRoles; }; Auth.prototype.cacheRoles = function () { if (!this.cacheController) { return false; } this.cacheController.role.put(this.user.id, Array(...this.userRoles)); return true; }; Auth.prototype.clearRoleCache = function (sessionToken) { if (!this.cacheController) { return false; } this.cacheController.role.del(this.user.id); this.cacheController.user.del(sessionToken); return true; }; Auth.prototype.getRolesByIds = async function (ins) { const results = []; // Build an OR query across all parentRoles if (!this.config) { await new Parse.Query(Parse.Role).containedIn('roles', ins.map(id => { const role = new Parse.Object(Parse.Role); role.id = id; return role; })).each(result => results.push(result.toJSON()), { useMasterKey: true }); } else { const roles = ins.map(id => { return { __type: 'Pointer', className: '_Role', objectId: id }; }); const restWhere = { roles: { $in: roles } }; const RestQuery = require('./RestQuery'); const query = await RestQuery({ method: RestQuery.Method.find, config: this.config, runBeforeFind: false, auth: master(this.config), className: '_Role', restWhere }); await query.each(result => results.push(result)); } return results; }; // Given a list of roleIds, find all the parent roles, returns a promise with all names Auth.prototype._getAllRolesNamesForRoleIds = function (roleIDs, names = [], queriedRoles = {}) { const ins = roleIDs.filter(roleID => { const wasQueried = queriedRoles[roleID] !== true; queriedRoles[roleID] = true; return wasQueried; }); // all roles are accounted for, return the names if (ins.length == 0) { return Promise.resolve([...new Set(names)]); } return this.getRolesByIds(ins).then(results => { // Nothing found if (!results.length) { return Promise.resolve(names); } // Map the results with all Ids and names const resultMap = results.reduce((memo, role) => { memo.names.push(role.name); memo.ids.push(role.objectId); return memo; }, { ids: [], names: [] }); // store the new found names names = names.concat(resultMap.names); // find the next ones, circular roles will be cut return this._getAllRolesNamesForRoleIds(resultMap.ids, names, queriedRoles); }).then(names => { return Promise.resolve([...new Set(names)]); }); }; const findUsersWithAuthData = (config, authData) => { const providers = Object.keys(authData); const query = providers.reduce((memo, provider) => { if (!authData[provider] || authData && !authData[provider].id) { return memo; } const queryKey = `authData.${provider}.id`; const query = {}; query[queryKey] = authData[provider].id; memo.push(query); return memo; }, []).filter(q => { return typeof q !== 'undefined'; }); return query.length > 0 ? config.database.find('_User', { $or: query }, { limit: 2 }) : Promise.resolve([]); }; const hasMutatedAuthData = (authData, userAuthData) => { if (!userAuthData) return { hasMutatedAuthData: true, mutatedAuthData: authData }; const mutatedAuthData = {}; Object.keys(authData).forEach(provider => { // Anonymous provider is not handled this way if (provider === 'anonymous') return; const providerData = authData[provider]; const userProviderAuthData = userAuthData[provider]; if (!(0, _util.isDeepStrictEqual)(providerData, userProviderAuthData)) { mutatedAuthData[provider] = providerData; } }); const hasMutatedAuthData = Object.keys(mutatedAuthData).length !== 0; return { hasMutatedAuthData, mutatedAuthData }; }; const checkIfUserHasProvidedConfiguredProvidersForLogin = (req = {}, authData = {}, userAuthData = {}, config) => { const savedUserProviders = Object.keys(userAuthData).map(provider => ({ name: provider, adapter: config.authDataManager.getValidatorForProvider(provider).adapter })); const hasProvidedASoloProvider = savedUserProviders.some(provider => provider && provider.adapter && provider.adapter.policy === 'solo' && authData[provider.name]); // Solo providers can be considered as safe, so we do not have to check if the user needs // to provide an additional provider to login. An auth adapter with "solo" (like webauthn) means // no "additional" auth needs to be provided to login (like OTP, MFA) if (hasProvidedASoloProvider) { return; } const additionProvidersNotFound = []; const hasProvidedAtLeastOneAdditionalProvider = savedUserProviders.some(provider => { let policy = provider.adapter.policy; if (typeof policy === 'function') { const requestObject = { ip: req.config.ip, user: req.auth.user, master: req.auth.isMaster }; policy = policy.call(provider.adapter, requestObject, userAuthData[provider.name]); } if (policy === 'additional') { if (authData[provider.name]) { return true; } else { // Push missing provider for error message additionProvidersNotFound.push(provider.name); } } }); if (hasProvidedAtLeastOneAdditionalProvider || !additionProvidersNotFound.length) { return; } throw new Parse.Error(Parse.Error.OTHER_CAUSE, `Missing additional authData ${additionProvidersNotFound.join(',')}`); }; // Validate each authData step-by-step and return the provider responses const handleAuthDataValidation = async (authData, req, foundUser) => { let user; if (foundUser) { user = Parse.User.fromJSON(_objectSpread({ className: '_User' }, foundUser)); // Find user by session and current objectId; only pass user if it's the current user or master key is provided } else if (req.auth && req.auth.user && typeof req.getUserId === 'function' && req.getUserId() === req.auth.user.id || req.auth && req.auth.isMaster && typeof req.getUserId === 'function' && req.getUserId()) { user = new Parse.User(); user.id = req.auth.isMaster ? req.getUserId() : req.auth.user.id; await user.fetch({ useMasterKey: true }); } const { updatedObject } = req.buildParseObjects(); const requestObject = (0, _triggers.getRequestObject)(undefined, req.auth, updatedObject, user, req.config); // Perform validation as step-by-step pipeline for better error consistency // and also to avoid to trigger a provider (like OTP SMS) if another one fails const acc = { authData: {}, authDataResponse: {} }; const authKeys = Object.keys(authData).sort(); for (const provider of authKeys) { let method = ''; try { if (authData[provider] === null) { acc.authData[provider] = null; continue; } const { validator } = req.config.authDataManager.getValidatorForProvider(provider); const authProvider = (req.config.auth || {})[provider] || {}; if (!validator || authProvider.enabled === false) { throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); } let validationResult = await validator(authData[provider], req, user, requestObject); method = validationResult && validationResult.method; requestObject.triggerName = method; if (validationResult && validationResult.validator) { validationResult = await validationResult.validator(); } if (!validationResult) { acc.authData[provider] = authData[provider]; continue; } if (!Object.keys(validationResult).length) { acc.authData[provider] = authData[provider]; continue; } if (validationResult.response) { acc.authDataResponse[provider] = validationResult.response; } // Some auth providers after initialization will avoid to replace authData already stored if (!validationResult.doNotSave) { acc.authData[provider] = validationResult.save || authData[provider]; } } catch (err) { const e = (0, _triggers.resolveError)(err, { code: Parse.Error.SCRIPT_FAILED, message: 'Auth failed. Unknown error.' }); const userString = req.auth && req.auth.user ? req.auth.user.id : req.data.objectId || undefined; _logger.logger.error(`Failed running auth step ${method} for ${provider} for user ${userString} with Error: ` + JSON.stringify(e), { authenticationStep: method, error: e, user: userString, provider }); throw e; } } return acc; }; module.exports = { Auth, master, maintenance, nobody, readOnly, shouldUpdateSessionExpiry, getAuthForSessionToken, getAuthForLegacySessionToken, findUsersWithAuthData, hasMutatedAuthData, checkIfUserHasProvidedConfiguredProvidersForLogin, handleAuthDataValidation }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdXRpbCIsInJlcXVpcmUiLCJfdHJpZ2dlcnMiLCJfbG9nZ2VyIiwiX1Jlc3RRdWVyeSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfUmVzdFdyaXRlIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0Iiwib3duS2V5cyIsInIiLCJ0IiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsIm8iLCJmaWx0ZXIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJlbnVtZXJhYmxlIiwicHVzaCIsImFwcGx5IiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiX3RvUHJvcGVydHlLZXkiLCJ2YWx1ZSIsImNvbmZpZ3VyYWJsZSIsIndyaXRhYmxlIiwiaSIsIl90b1ByaW1pdGl2ZSIsIlN5bWJvbCIsInRvUHJpbWl0aXZlIiwiY2FsbCIsIlR5cGVFcnJvciIsIlN0cmluZyIsIk51bWJlciIsIlBhcnNlIiwiQXV0aCIsImNvbmZpZyIsImNhY2hlQ29udHJvbGxlciIsInVuZGVmaW5lZCIsImlzTWFzdGVyIiwiaXNNYWludGVuYW5jZSIsImlzUmVhZE9ubHkiLCJ1c2VyIiwiaW5zdGFsbGF0aW9uSWQiLCJ1c2VyUm9sZXMiLCJmZXRjaGVkUm9sZXMiLCJyb2xlUHJvbWlzZSIsInByb3RvdHlwZSIsImlzVW5hdXRoZW50aWNhdGVkIiwibWFzdGVyIiwibWFpbnRlbmFuY2UiLCJyZWFkT25seSIsIm5vYm9keSIsInNob3VsZFVwZGF0ZVNlc3Npb25FeHBpcnkiLCJzZXNzaW9uIiwicmVzZXRBZnRlciIsInNlc3Npb25MZW5ndGgiLCJsYXN0VXBkYXRlZCIsIkRhdGUiLCJ1cGRhdGVkQXQiLCJza2lwUmFuZ2UiLCJzZXRUaW1lIiwiZ2V0VGltZSIsInRocm90dGxlIiwicmVuZXdTZXNzaW9uSWZOZWVkZWQiLCJzZXNzaW9uVG9rZW4iLCJleHRlbmRTZXNzaW9uT25Vc2UiLCJjbGVhclRpbWVvdXQiLCJzZXRUaW1lb3V0IiwicXVlcnkiLCJSZXN0UXVlcnkiLCJtZXRob2QiLCJNZXRob2QiLCJnZXQiLCJhdXRoIiwicnVuQmVmb3JlRmluZCIsImNsYXNzTmFtZSIsInJlc3RXaGVyZSIsInJlc3RPcHRpb25zIiwibGltaXQiLCJyZXN1bHRzIiwiZXhlY3V0ZSIsImV4cGlyZXNBdCIsImdlbmVyYXRlU2Vzc2lvbkV4cGlyZXNBdCIsIlJlc3RXcml0ZSIsIm9iamVjdElkIiwiX2VuY29kZSIsImNvZGUiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJsb2dnZXIiLCJlcnJvciIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJ1c2VySlNPTiIsImNhY2hlZFVzZXIiLCJmcm9tSlNPTiIsIlByb21pc2UiLCJyZXNvbHZlIiwiaW5jbHVkZSIsIlF1ZXJ5IiwiU2Vzc2lvbiIsImVxdWFsVG8iLCJmaW5kIiwidXNlTWFzdGVyS2V5IiwibWFwIiwib2JqIiwidG9KU09OIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwibm93IiwiaXNvIiwic3RhcnRzV2l0aCIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsInBhc3N3b3JkIiwicHV0IiwidXNlck9iamVjdCIsImdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4iLCJfc2Vzc2lvbl90b2tlbiIsInRoZW4iLCJyZXNwb25zZSIsImdldFVzZXJSb2xlcyIsIl9sb2FkUm9sZXMiLCJnZXRSb2xlc0ZvclVzZXIiLCJ1c2VycyIsIl9fdHlwZSIsImlkIiwiZWFjaCIsInJlc3VsdCIsIlJvbGUiLCJjYWNoZWRSb2xlcyIsInJvbGUiLCJjYWNoZVJvbGVzIiwicm9sZXNNYXAiLCJyZWR1Y2UiLCJtIiwibmFtZXMiLCJuYW1lIiwiaWRzIiwicm9sZU5hbWVzIiwiX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzIiwiQXJyYXkiLCJjbGVhclJvbGVDYWNoZSIsImRlbCIsImdldFJvbGVzQnlJZHMiLCJpbnMiLCJjb250YWluZWRJbiIsInJvbGVzIiwiJGluIiwicm9sZUlEcyIsInF1ZXJpZWRSb2xlcyIsInJvbGVJRCIsIndhc1F1ZXJpZWQiLCJTZXQiLCJyZXN1bHRNYXAiLCJtZW1vIiwiY29uY2F0IiwiZmluZFVzZXJzV2l0aEF1dGhEYXRhIiwiYXV0aERhdGEiLCJwcm92aWRlcnMiLCJwcm92aWRlciIsInF1ZXJ5S2V5IiwicSIsImRhdGFiYXNlIiwiJG9yIiwiaGFzTXV0YXRlZEF1dGhEYXRhIiwidXNlckF1dGhEYXRhIiwibXV0YXRlZEF1dGhEYXRhIiwicHJvdmlkZXJEYXRhIiwidXNlclByb3ZpZGVyQXV0aERhdGEiLCJpc0RlZXBTdHJpY3RFcXVhbCIsImNoZWNrSWZVc2VySGFzUHJvdmlkZWRDb25maWd1cmVkUHJvdmlkZXJzRm9yTG9naW4iLCJyZXEiLCJzYXZlZFVzZXJQcm92aWRlcnMiLCJhZGFwdGVyIiwiYXV0aERhdGFNYW5hZ2VyIiwiZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIiLCJoYXNQcm92aWRlZEFTb2xvUHJvdmlkZXIiLCJzb21lIiwicG9saWN5IiwiYWRkaXRpb25Qcm92aWRlcnNOb3RGb3VuZCIsImhhc1Byb3ZpZGVkQXRMZWFzdE9uZUFkZGl0aW9uYWxQcm92aWRlciIsInJlcXVlc3RPYmplY3QiLCJpcCIsIk9USEVSX0NBVVNFIiwiam9pbiIsImhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbiIsImZvdW5kVXNlciIsIlVzZXIiLCJnZXRVc2VySWQiLCJmZXRjaCIsInVwZGF0ZWRPYmplY3QiLCJidWlsZFBhcnNlT2JqZWN0cyIsImdldFJlcXVlc3RPYmplY3QiLCJhY2MiLCJhdXRoRGF0YVJlc3BvbnNlIiwiYXV0aEtleXMiLCJzb3J0IiwidmFsaWRhdG9yIiwiYXV0aFByb3ZpZGVyIiwiZW5hYmxlZCIsIlVOU1VQUE9SVEVEX1NFUlZJQ0UiLCJ2YWxpZGF0aW9uUmVzdWx0IiwidHJpZ2dlck5hbWUiLCJkb05vdFNhdmUiLCJzYXZlIiwiZXJyIiwicmVzb2x2ZUVycm9yIiwiU0NSSVBUX0ZBSUxFRCIsIm1lc3NhZ2UiLCJ1c2VyU3RyaW5nIiwiZGF0YSIsIkpTT04iLCJzdHJpbmdpZnkiLCJhdXRoZW50aWNhdGlvblN0ZXAiLCJtb2R1bGUiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vc3JjL0F1dGguanMiXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5pbXBvcnQgeyBpc0RlZXBTdHJpY3RFcXVhbCB9IGZyb20gJ3V0aWwnO1xuaW1wb3J0IHsgZ2V0UmVxdWVzdE9iamVjdCwgcmVzb2x2ZUVycm9yIH0gZnJvbSAnLi90cmlnZ2Vycyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgUmVzdFF1ZXJ5IGZyb20gJy4vUmVzdFF1ZXJ5JztcbmltcG9ydCBSZXN0V3JpdGUgZnJvbSAnLi9SZXN0V3JpdGUnO1xuXG4vLyBBbiBBdXRoIG9iamVjdCB0ZWxscyB5b3Ugd2hvIGlzIHJlcXVlc3Rpbmcgc29tZXRoaW5nIGFuZCB3aGV0aGVyXG4vLyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbi8vIHVzZXJPYmplY3QgaXMgYSBQYXJzZS5Vc2VyIGFuZCBjYW4gYmUgbnVsbCBpZiB0aGVyZSdzIG5vIHVzZXIuXG5mdW5jdGlvbiBBdXRoKHtcbiAgY29uZmlnLFxuICBjYWNoZUNvbnRyb2xsZXIgPSB1bmRlZmluZWQsXG4gIGlzTWFzdGVyID0gZmFsc2UsXG4gIGlzTWFpbnRlbmFuY2UgPSBmYWxzZSxcbiAgaXNSZWFkT25seSA9IGZhbHNlLFxuICB1c2VyLFxuICBpbnN0YWxsYXRpb25JZCxcbn0pIHtcbiAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gIHRoaXMuY2FjaGVDb250cm9sbGVyID0gY2FjaGVDb250cm9sbGVyIHx8IChjb25maWcgJiYgY29uZmlnLmNhY2hlQ29udHJvbGxlcik7XG4gIHRoaXMuaW5zdGFsbGF0aW9uSWQgPSBpbnN0YWxsYXRpb25JZDtcbiAgdGhpcy5pc01hc3RlciA9IGlzTWFzdGVyO1xuICB0aGlzLmlzTWFpbnRlbmFuY2UgPSBpc01haW50ZW5hbmNlO1xuICB0aGlzLnVzZXIgPSB1c2VyO1xuICB0aGlzLmlzUmVhZE9ubHkgPSBpc1JlYWRPbmx5O1xuXG4gIC8vIEFzc3VtaW5nIGEgdXNlcnMgcm9sZXMgd29uJ3QgY2hhbmdlIGR1cmluZyBhIHNpbmdsZSByZXF1ZXN0LCB3ZSdsbFxuICAvLyBvbmx5IGxvYWQgdGhlbSBvbmNlLlxuICB0aGlzLnVzZXJSb2xlcyA9IFtdO1xuICB0aGlzLmZldGNoZWRSb2xlcyA9IGZhbHNlO1xuICB0aGlzLnJvbGVQcm9taXNlID0gbnVsbDtcbn1cblxuLy8gV2hldGhlciB0aGlzIGF1dGggY291bGQgcG9zc2libHkgbW9kaWZ5IHRoZSBnaXZlbiB1c2VyIGlkLlxuLy8gSXQgc3RpbGwgY291bGQgYmUgZm9yYmlkZGVuIHZpYSBBQ0xzIGV2ZW4gaWYgdGhpcyByZXR1cm5zIHRydWUuXG5BdXRoLnByb3RvdHlwZS5pc1VuYXV0aGVudGljYXRlZCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuaXNNYXN0ZXIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHRoaXMuaXNNYWludGVuYW5jZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodGhpcy51c2VyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuLy8gQSBoZWxwZXIgdG8gZ2V0IGEgbWFzdGVyLWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiBtYXN0ZXIoY29uZmlnKSB7XG4gIHJldHVybiBuZXcgQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXI6IHRydWUgfSk7XG59XG5cbi8vIEEgaGVscGVyIHRvIGdldCBhIG1haW50ZW5hbmNlLWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiBtYWludGVuYW5jZShjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBBdXRoKHsgY29uZmlnLCBpc01haW50ZW5hbmNlOiB0cnVlIH0pO1xufVxuXG4vLyBBIGhlbHBlciB0byBnZXQgYSBtYXN0ZXItbGV2ZWwgQXV0aCBvYmplY3RcbmZ1bmN0aW9uIHJlYWRPbmx5KGNvbmZpZykge1xuICByZXR1cm4gbmV3IEF1dGgoeyBjb25maWcsIGlzTWFzdGVyOiB0cnVlLCBpc1JlYWRPbmx5OiB0cnVlIH0pO1xufVxuXG4vLyBBIGhlbHBlciB0byBnZXQgYSBub2JvZHktbGV2ZWwgQXV0aCBvYmplY3RcbmZ1bmN0aW9uIG5vYm9keShjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBBdXRoKHsgY29uZmlnLCBpc01hc3RlcjogZmFsc2UgfSk7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgc2Vzc2lvbiBzaG91bGQgYmUgdXBkYXRlZCBiYXNlZCBvbiBsYXN0IHVwZGF0ZSB0aW1lICYgc2Vzc2lvbiBsZW5ndGguXG4gKi9cbmZ1bmN0aW9uIHNob3VsZFVwZGF0ZVNlc3Npb25FeHBpcnkoY29uZmlnLCBzZXNzaW9uKSB7XG4gIGNvbnN0IHJlc2V0QWZ0ZXIgPSBjb25maWcuc2Vzc2lvbkxlbmd0aCAvIDI7XG4gIGNvbnN0IGxhc3RVcGRhdGVkID0gbmV3IERhdGUoc2Vzc2lvbj8udXBkYXRlZEF0KTtcbiAgY29uc3Qgc2tpcFJhbmdlID0gbmV3IERhdGUoKTtcbiAgc2tpcFJhbmdlLnNldFRpbWUoc2tpcFJhbmdlLmdldFRpbWUoKSAtIHJlc2V0QWZ0ZXIgKiAxMDAwKTtcbiAgcmV0dXJuIGxhc3RVcGRhdGVkIDw9IHNraXBSYW5nZTtcbn1cblxuY29uc3QgdGhyb3R0bGUgPSB7fTtcbmNvbnN0IHJlbmV3U2Vzc2lvbklmTmVlZGVkID0gYXN5bmMgKHsgY29uZmlnLCBzZXNzaW9uLCBzZXNzaW9uVG9rZW4gfSkgPT4ge1xuICBpZiAoIWNvbmZpZz8uZXh0ZW5kU2Vzc2lvbk9uVXNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNsZWFyVGltZW91dCh0aHJvdHRsZVtzZXNzaW9uVG9rZW5dKTtcbiAgdGhyb3R0bGVbc2Vzc2lvblRva2VuXSA9IHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBpZiAoIXNlc3Npb24pIHtcbiAgICAgICAgY29uc3QgcXVlcnkgPSBhd2FpdCBSZXN0UXVlcnkoe1xuICAgICAgICAgIG1ldGhvZDogUmVzdFF1ZXJ5Lk1ldGhvZC5nZXQsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGF1dGg6IG1hc3Rlcihjb25maWcpLFxuICAgICAgICAgIHJ1bkJlZm9yZUZpbmQ6IGZhbHNlLFxuICAgICAgICAgIGNsYXNzTmFtZTogJ19TZXNzaW9uJyxcbiAgICAgICAgICByZXN0V2hlcmU6IHsgc2Vzc2lvblRva2VuIH0sXG4gICAgICAgICAgcmVzdE9wdGlvbnM6IHsgbGltaXQ6IDEgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHsgcmVzdWx0cyB9ID0gYXdhaXQgcXVlcnkuZXhlY3V0ZSgpO1xuICAgICAgICBzZXNzaW9uID0gcmVzdWx0c1swXTtcbiAgICAgIH1cbiAgICAgIGlmICghc2hvdWxkVXBkYXRlU2Vzc2lvbkV4cGlyeShjb25maWcsIHNlc3Npb24pIHx8ICFzZXNzaW9uKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGV4cGlyZXNBdCA9IGNvbmZpZy5nZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQoKTtcbiAgICAgIGF3YWl0IG5ldyBSZXN0V3JpdGUoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgbWFzdGVyKGNvbmZpZyksXG4gICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgIHsgb2JqZWN0SWQ6IHNlc3Npb24ub2JqZWN0SWQgfSxcbiAgICAgICAgeyBleHBpcmVzQXQ6IFBhcnNlLl9lbmNvZGUoZXhwaXJlc0F0KSB9XG4gICAgICApLmV4ZWN1dGUoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoZT8uY29kZSAhPT0gUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ0NvdWxkIG5vdCB1cGRhdGUgc2Vzc2lvbiBleHBpcnk6ICcsIGUpO1xuICAgICAgfVxuICAgIH1cbiAgfSwgNTAwKTtcbn07XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gQXV0aCBvYmplY3RcbmNvbnN0IGdldEF1dGhGb3JTZXNzaW9uVG9rZW4gPSBhc3luYyBmdW5jdGlvbiAoe1xuICBjb25maWcsXG4gIGNhY2hlQ29udHJvbGxlcixcbiAgc2Vzc2lvblRva2VuLFxuICBpbnN0YWxsYXRpb25JZCxcbn0pIHtcbiAgY2FjaGVDb250cm9sbGVyID0gY2FjaGVDb250cm9sbGVyIHx8IChjb25maWcgJiYgY29uZmlnLmNhY2hlQ29udHJvbGxlcik7XG4gIGlmIChjYWNoZUNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCB1c2VySlNPTiA9IGF3YWl0IGNhY2hlQ29udHJvbGxlci51c2VyLmdldChzZXNzaW9uVG9rZW4pO1xuICAgIGlmICh1c2VySlNPTikge1xuICAgICAgY29uc3QgY2FjaGVkVXNlciA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTih1c2VySlNPTik7XG4gICAgICByZW5ld1Nlc3Npb25JZk5lZWRlZCh7IGNvbmZpZywgc2Vzc2lvblRva2VuIH0pO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgbmV3IEF1dGgoe1xuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgICAgICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgICAgICAgIGluc3RhbGxhdGlvbklkLFxuICAgICAgICAgIHVzZXI6IGNhY2hlZFVzZXIsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGxldCByZXN1bHRzO1xuICBpZiAoY29uZmlnKSB7XG4gICAgY29uc3QgcmVzdE9wdGlvbnMgPSB7XG4gICAgICBsaW1pdDogMSxcbiAgICAgIGluY2x1ZGU6ICd1c2VyJyxcbiAgICB9O1xuICAgIGNvbnN0IFJlc3RRdWVyeSA9IHJlcXVpcmUoJy4vUmVzdFF1ZXJ5Jyk7XG4gICAgY29uc3QgcXVlcnkgPSBhd2FpdCBSZXN0UXVlcnkoe1xuICAgICAgbWV0aG9kOiBSZXN0UXVlcnkuTWV0aG9kLmdldCxcbiAgICAgIGNvbmZpZyxcbiAgICAgIHJ1bkJlZm9yZUZpbmQ6IGZhbHNlLFxuICAgICAgYXV0aDogbWFzdGVyKGNvbmZpZyksXG4gICAgICBjbGFzc05hbWU6ICdfU2Vzc2lvbicsXG4gICAgICByZXN0V2hlcmU6IHsgc2Vzc2lvblRva2VuIH0sXG4gICAgICByZXN0T3B0aW9ucyxcbiAgICB9KTtcbiAgICByZXN1bHRzID0gKGF3YWl0IHF1ZXJ5LmV4ZWN1dGUoKSkucmVzdWx0cztcbiAgfSBlbHNlIHtcbiAgICByZXN1bHRzID0gKFxuICAgICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlNlc3Npb24pXG4gICAgICAgIC5saW1pdCgxKVxuICAgICAgICAuaW5jbHVkZSgndXNlcicpXG4gICAgICAgIC5lcXVhbFRvKCdzZXNzaW9uVG9rZW4nLCBzZXNzaW9uVG9rZW4pXG4gICAgICAgIC5maW5kKHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pXG4gICAgKS5tYXAob2JqID0+IG9iai50b0pTT04oKSk7XG4gIH1cblxuICBpZiAocmVzdWx0cy5sZW5ndGggIT09IDEgfHwgIXJlc3VsdHNbMF1bJ3VzZXInXSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgfVxuICBjb25zdCBzZXNzaW9uID0gcmVzdWx0c1swXTtcbiAgY29uc3Qgbm93ID0gbmV3IERhdGUoKSxcbiAgICBleHBpcmVzQXQgPSBzZXNzaW9uLmV4cGlyZXNBdCA/IG5ldyBEYXRlKHNlc3Npb24uZXhwaXJlc0F0LmlzbykgOiB1bmRlZmluZWQ7XG4gIGlmIChleHBpcmVzQXQgPCBub3cpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnU2Vzc2lvbiB0b2tlbiBpcyBleHBpcmVkLicpO1xuICB9XG4gIGNvbnN0IG9iaiA9IHNlc3Npb24udXNlcjtcblxuICBpZiAodHlwZW9mIG9ialsnb2JqZWN0SWQnXSA9PT0gJ3N0cmluZycgJiYgb2JqWydvYmplY3RJZCddLnN0YXJ0c1dpdGgoJ3JvbGU6JykpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLCAnSW52YWxpZCBvYmplY3QgSUQuJyk7XG4gIH1cblxuICBkZWxldGUgb2JqLnBhc3N3b3JkO1xuICBvYmpbJ2NsYXNzTmFtZSddID0gJ19Vc2VyJztcbiAgb2JqWydzZXNzaW9uVG9rZW4nXSA9IHNlc3Npb25Ub2tlbjtcbiAgaWYgKGNhY2hlQ29udHJvbGxlcikge1xuICAgIGNhY2hlQ29udHJvbGxlci51c2VyLnB1dChzZXNzaW9uVG9rZW4sIG9iaik7XG4gIH1cbiAgcmVuZXdTZXNzaW9uSWZOZWVkZWQoeyBjb25maWcsIHNlc3Npb24sIHNlc3Npb25Ub2tlbiB9KTtcbiAgY29uc3QgdXNlck9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmopO1xuICByZXR1cm4gbmV3IEF1dGgoe1xuICAgIGNvbmZpZyxcbiAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgIGluc3RhbGxhdGlvbklkLFxuICAgIHVzZXI6IHVzZXJPYmplY3QsXG4gIH0pO1xufTtcblxudmFyIGdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4gPSBhc3luYyBmdW5jdGlvbiAoeyBjb25maWcsIHNlc3Npb25Ub2tlbiwgaW5zdGFsbGF0aW9uSWQgfSkge1xuICB2YXIgcmVzdE9wdGlvbnMgPSB7XG4gICAgbGltaXQ6IDEsXG4gIH07XG4gIGNvbnN0IFJlc3RRdWVyeSA9IHJlcXVpcmUoJy4vUmVzdFF1ZXJ5Jyk7XG4gIHZhciBxdWVyeSA9IGF3YWl0IFJlc3RRdWVyeSh7XG4gICAgbWV0aG9kOiBSZXN0UXVlcnkuTWV0aG9kLmdldCxcbiAgICBjb25maWcsXG4gICAgcnVuQmVmb3JlRmluZDogZmFsc2UsXG4gICAgYXV0aDogbWFzdGVyKGNvbmZpZyksXG4gICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgIHJlc3RXaGVyZTogeyBfc2Vzc2lvbl90b2tlbjogc2Vzc2lvblRva2VuIH0sXG4gICAgcmVzdE9wdGlvbnMsXG4gIH0pO1xuICByZXR1cm4gcXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHZhciByZXN1bHRzID0gcmVzcG9uc2UucmVzdWx0cztcbiAgICBpZiAocmVzdWx0cy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdpbnZhbGlkIGxlZ2FjeSBzZXNzaW9uIHRva2VuJyk7XG4gICAgfVxuICAgIGNvbnN0IG9iaiA9IHJlc3VsdHNbMF07XG4gICAgb2JqLmNsYXNzTmFtZSA9ICdfVXNlcic7XG4gICAgY29uc3QgdXNlck9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmopO1xuICAgIHJldHVybiBuZXcgQXV0aCh7XG4gICAgICBjb25maWcsXG4gICAgICBpc01hc3RlcjogZmFsc2UsXG4gICAgICBpbnN0YWxsYXRpb25JZCxcbiAgICAgIHVzZXI6IHVzZXJPYmplY3QsXG4gICAgfSk7XG4gIH0pO1xufTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiByb2xlIG5hbWVzXG5BdXRoLnByb3RvdHlwZS5nZXRVc2VyUm9sZXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmlzTWFzdGVyIHx8IHRoaXMuaXNNYWludGVuYW5jZSB8fCAhdGhpcy51c2VyKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShbXSk7XG4gIH1cbiAgaWYgKHRoaXMuZmV0Y2hlZFJvbGVzKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLnVzZXJSb2xlcyk7XG4gIH1cbiAgaWYgKHRoaXMucm9sZVByb21pc2UpIHtcbiAgICByZXR1cm4gdGhpcy5yb2xlUHJvbWlzZTtcbiAgfVxuICB0aGlzLnJvbGVQcm9taXNlID0gdGhpcy5fbG9hZFJvbGVzKCk7XG4gIHJldHVybiB0aGlzLnJvbGVQcm9taXNlO1xufTtcblxuQXV0aC5wcm90b3R5cGUuZ2V0Um9sZXNGb3JVc2VyID0gYXN5bmMgZnVuY3Rpb24gKCkge1xuICAvL1N0YWNrIGFsbCBQYXJzZS5Sb2xlXG4gIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgaWYgKHRoaXMuY29uZmlnKSB7XG4gICAgY29uc3QgcmVzdFdoZXJlID0ge1xuICAgICAgdXNlcnM6IHtcbiAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgICAgb2JqZWN0SWQ6IHRoaXMudXNlci5pZCxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCBSZXN0UXVlcnkgPSByZXF1aXJlKCcuL1Jlc3RRdWVyeScpO1xuICAgIGNvbnN0IHF1ZXJ5ID0gYXdhaXQgUmVzdFF1ZXJ5KHtcbiAgICAgIG1ldGhvZDogUmVzdFF1ZXJ5Lk1ldGhvZC5maW5kLFxuICAgICAgcnVuQmVmb3JlRmluZDogZmFsc2UsXG4gICAgICBjb25maWc6IHRoaXMuY29uZmlnLFxuICAgICAgYXV0aDogbWFzdGVyKHRoaXMuY29uZmlnKSxcbiAgICAgIGNsYXNzTmFtZTogJ19Sb2xlJyxcbiAgICAgIHJlc3RXaGVyZSxcbiAgICB9KTtcbiAgICBhd2FpdCBxdWVyeS5lYWNoKHJlc3VsdCA9PiByZXN1bHRzLnB1c2gocmVzdWx0KSk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlJvbGUpXG4gICAgICAuZXF1YWxUbygndXNlcnMnLCB0aGlzLnVzZXIpXG4gICAgICAuZWFjaChyZXN1bHQgPT4gcmVzdWx0cy5wdXNoKHJlc3VsdC50b0pTT04oKSksIHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gSXRlcmF0ZXMgdGhyb3VnaCB0aGUgcm9sZSB0cmVlIGFuZCBjb21waWxlcyBhIHVzZXIncyByb2xlc1xuQXV0aC5wcm90b3R5cGUuX2xvYWRSb2xlcyA9IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2FjaGVDb250cm9sbGVyKSB7XG4gICAgY29uc3QgY2FjaGVkUm9sZXMgPSBhd2FpdCB0aGlzLmNhY2hlQ29udHJvbGxlci5yb2xlLmdldCh0aGlzLnVzZXIuaWQpO1xuICAgIGlmIChjYWNoZWRSb2xlcyAhPSBudWxsKSB7XG4gICAgICB0aGlzLmZldGNoZWRSb2xlcyA9IHRydWU7XG4gICAgICB0aGlzLnVzZXJSb2xlcyA9IGNhY2hlZFJvbGVzO1xuICAgICAgcmV0dXJuIGNhY2hlZFJvbGVzO1xuICAgIH1cbiAgfVxuXG4gIC8vIEZpcnN0IGdldCB0aGUgcm9sZSBpZHMgdGhpcyB1c2VyIGlzIGRpcmVjdGx5IGEgbWVtYmVyIG9mXG4gIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmdldFJvbGVzRm9yVXNlcigpO1xuICBpZiAoIXJlc3VsdHMubGVuZ3RoKSB7XG4gICAgdGhpcy51c2VyUm9sZXMgPSBbXTtcbiAgICB0aGlzLmZldGNoZWRSb2xlcyA9IHRydWU7XG4gICAgdGhpcy5yb2xlUHJvbWlzZSA9IG51bGw7XG5cbiAgICB0aGlzLmNhY2hlUm9sZXMoKTtcbiAgICByZXR1cm4gdGhpcy51c2VyUm9sZXM7XG4gIH1cblxuICBjb25zdCByb2xlc01hcCA9IHJlc3VsdHMucmVkdWNlKFxuICAgIChtLCByKSA9PiB7XG4gICAgICBtLm5hbWVzLnB1c2goci5uYW1lKTtcbiAgICAgIG0uaWRzLnB1c2goci5vYmplY3RJZCk7XG4gICAgICByZXR1cm4gbTtcbiAgICB9LFxuICAgIHsgaWRzOiBbXSwgbmFtZXM6IFtdIH1cbiAgKTtcblxuICAvLyBydW4gdGhlIHJlY3Vyc2l2ZSBmaW5kaW5nXG4gIGNvbnN0IHJvbGVOYW1lcyA9IGF3YWl0IHRoaXMuX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzKHJvbGVzTWFwLmlkcywgcm9sZXNNYXAubmFtZXMpO1xuICB0aGlzLnVzZXJSb2xlcyA9IHJvbGVOYW1lcy5tYXAociA9PiB7XG4gICAgcmV0dXJuICdyb2xlOicgKyByO1xuICB9KTtcbiAgdGhpcy5mZXRjaGVkUm9sZXMgPSB0cnVlO1xuICB0aGlzLnJvbGVQcm9taXNlID0gbnVsbDtcbiAgdGhpcy5jYWNoZVJvbGVzKCk7XG4gIHJldHVybiB0aGlzLnVzZXJSb2xlcztcbn07XG5cbkF1dGgucHJvdG90eXBlLmNhY2hlUm9sZXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5jYWNoZUNvbnRyb2xsZXIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdGhpcy5jYWNoZUNvbnRyb2xsZXIucm9sZS5wdXQodGhpcy51c2VyLmlkLCBBcnJheSguLi50aGlzLnVzZXJSb2xlcykpO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkF1dGgucHJvdG90eXBlLmNsZWFyUm9sZUNhY2hlID0gZnVuY3Rpb24gKHNlc3Npb25Ub2tlbikge1xuICBpZiAoIXRoaXMuY2FjaGVDb250cm9sbGVyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHRoaXMuY2FjaGVDb250cm9sbGVyLnJvbGUuZGVsKHRoaXMudXNlci5pZCk7XG4gIHRoaXMuY2FjaGVDb250cm9sbGVyLnVzZXIuZGVsKHNlc3Npb25Ub2tlbik7XG4gIHJldHVybiB0cnVlO1xufTtcblxuQXV0aC5wcm90b3R5cGUuZ2V0Um9sZXNCeUlkcyA9IGFzeW5jIGZ1bmN0aW9uIChpbnMpIHtcbiAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICAvLyBCdWlsZCBhbiBPUiBxdWVyeSBhY3Jvc3MgYWxsIHBhcmVudFJvbGVzXG4gIGlmICghdGhpcy5jb25maWcpIHtcbiAgICBhd2FpdCBuZXcgUGFyc2UuUXVlcnkoUGFyc2UuUm9sZSlcbiAgICAgIC5jb250YWluZWRJbihcbiAgICAgICAgJ3JvbGVzJyxcbiAgICAgICAgaW5zLm1hcChpZCA9PiB7XG4gICAgICAgICAgY29uc3Qgcm9sZSA9IG5ldyBQYXJzZS5PYmplY3QoUGFyc2UuUm9sZSk7XG4gICAgICAgICAgcm9sZS5pZCA9IGlkO1xuICAgICAgICAgIHJldHVybiByb2xlO1xuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmVhY2gocmVzdWx0ID0+IHJlc3VsdHMucHVzaChyZXN1bHQudG9KU09OKCkpLCB7IHVzZU1hc3RlcktleTogdHJ1ZSB9KTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCByb2xlcyA9IGlucy5tYXAoaWQgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgIGNsYXNzTmFtZTogJ19Sb2xlJyxcbiAgICAgICAgb2JqZWN0SWQ6IGlkLFxuICAgICAgfTtcbiAgICB9KTtcbiAgICBjb25zdCByZXN0V2hlcmUgPSB7IHJvbGVzOiB7ICRpbjogcm9sZXMgfSB9O1xuICAgIGNvbnN0IFJlc3RRdWVyeSA9IHJlcXVpcmUoJy4vUmVzdFF1ZXJ5Jyk7XG4gICAgY29uc3QgcXVlcnkgPSBhd2FpdCBSZXN0UXVlcnkoe1xuICAgICAgbWV0aG9kOiBSZXN0UXVlcnkuTWV0aG9kLmZpbmQsXG4gICAgICBjb25maWc6IHRoaXMuY29uZmlnLFxuICAgICAgcnVuQmVmb3JlRmluZDogZmFsc2UsXG4gICAgICBhdXRoOiBtYXN0ZXIodGhpcy5jb25maWcpLFxuICAgICAgY2xhc3NOYW1lOiAnX1JvbGUnLFxuICAgICAgcmVzdFdoZXJlLFxuICAgIH0pO1xuICAgIGF3YWl0IHF1ZXJ5LmVhY2gocmVzdWx0ID0+IHJlc3VsdHMucHVzaChyZXN1bHQpKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0cztcbn07XG5cbi8vIEdpdmVuIGEgbGlzdCBvZiByb2xlSWRzLCBmaW5kIGFsbCB0aGUgcGFyZW50IHJvbGVzLCByZXR1cm5zIGEgcHJvbWlzZSB3aXRoIGFsbCBuYW1lc1xuQXV0aC5wcm90b3R5cGUuX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzID0gZnVuY3Rpb24gKHJvbGVJRHMsIG5hbWVzID0gW10sIHF1ZXJpZWRSb2xlcyA9IHt9KSB7XG4gIGNvbnN0IGlucyA9IHJvbGVJRHMuZmlsdGVyKHJvbGVJRCA9PiB7XG4gICAgY29uc3Qgd2FzUXVlcmllZCA9IHF1ZXJpZWRSb2xlc1tyb2xlSURdICE9PSB0cnVlO1xuICAgIHF1ZXJpZWRSb2xlc1tyb2xlSURdID0gdHJ1ZTtcbiAgICByZXR1cm4gd2FzUXVlcmllZDtcbiAgfSk7XG5cbiAgLy8gYWxsIHJvbGVzIGFyZSBhY2NvdW50ZWQgZm9yLCByZXR1cm4gdGhlIG5hbWVzXG4gIGlmIChpbnMubGVuZ3RoID09IDApIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFsuLi5uZXcgU2V0KG5hbWVzKV0pO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuZ2V0Um9sZXNCeUlkcyhpbnMpXG4gICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAvLyBOb3RoaW5nIGZvdW5kXG4gICAgICBpZiAoIXJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmFtZXMpO1xuICAgICAgfVxuICAgICAgLy8gTWFwIHRoZSByZXN1bHRzIHdpdGggYWxsIElkcyBhbmQgbmFtZXNcbiAgICAgIGNvbnN0IHJlc3VsdE1hcCA9IHJlc3VsdHMucmVkdWNlKFxuICAgICAgICAobWVtbywgcm9sZSkgPT4ge1xuICAgICAgICAgIG1lbW8ubmFtZXMucHVzaChyb2xlLm5hbWUpO1xuICAgICAgICAgIG1lbW8uaWRzLnB1c2gocm9sZS5vYmplY3RJZCk7XG4gICAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICAgIH0sXG4gICAgICAgIHsgaWRzOiBbXSwgbmFtZXM6IFtdIH1cbiAgICAgICk7XG4gICAgICAvLyBzdG9yZSB0aGUgbmV3IGZvdW5kIG5hbWVzXG4gICAgICBuYW1lcyA9IG5hbWVzLmNvbmNhdChyZXN1bHRNYXAubmFtZXMpO1xuICAgICAgLy8gZmluZCB0aGUgbmV4dCBvbmVzLCBjaXJjdWxhciByb2xlcyB3aWxsIGJlIGN1dFxuICAgICAgcmV0dXJuIHRoaXMuX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzKHJlc3VsdE1hcC5pZHMsIG5hbWVzLCBxdWVyaWVkUm9sZXMpO1xuICAgIH0pXG4gICAgLnRoZW4obmFtZXMgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShbLi4ubmV3IFNldChuYW1lcyldKTtcbiAgICB9KTtcbn07XG5cbmNvbnN0IGZpbmRVc2Vyc1dpdGhBdXRoRGF0YSA9IChjb25maWcsIGF1dGhEYXRhKSA9PiB7XG4gIGNvbnN0IHByb3ZpZGVycyA9IE9iamVjdC5rZXlzKGF1dGhEYXRhKTtcbiAgY29uc3QgcXVlcnkgPSBwcm92aWRlcnNcbiAgICAucmVkdWNlKChtZW1vLCBwcm92aWRlcikgPT4ge1xuICAgICAgaWYgKCFhdXRoRGF0YVtwcm92aWRlcl0gfHwgKGF1dGhEYXRhICYmICFhdXRoRGF0YVtwcm92aWRlcl0uaWQpKSB7XG4gICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgfVxuICAgICAgY29uc3QgcXVlcnlLZXkgPSBgYXV0aERhdGEuJHtwcm92aWRlcn0uaWRgO1xuICAgICAgY29uc3QgcXVlcnkgPSB7fTtcbiAgICAgIHF1ZXJ5W3F1ZXJ5S2V5XSA9IGF1dGhEYXRhW3Byb3ZpZGVyXS5pZDtcbiAgICAgIG1lbW8ucHVzaChxdWVyeSk7XG4gICAgICByZXR1cm4gbWVtbztcbiAgICB9LCBbXSlcbiAgICAuZmlsdGVyKHEgPT4ge1xuICAgICAgcmV0dXJuIHR5cGVvZiBxICE9PSAndW5kZWZpbmVkJztcbiAgICB9KTtcblxuICByZXR1cm4gcXVlcnkubGVuZ3RoID4gMFxuICAgID8gY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgeyAkb3I6IHF1ZXJ5IH0sIHsgbGltaXQ6IDIgfSlcbiAgICA6IFByb21pc2UucmVzb2x2ZShbXSk7XG59O1xuXG5jb25zdCBoYXNNdXRhdGVkQXV0aERhdGEgPSAoYXV0aERhdGEsIHVzZXJBdXRoRGF0YSkgPT4ge1xuICBpZiAoIXVzZXJBdXRoRGF0YSkgcmV0dXJuIHsgaGFzTXV0YXRlZEF1dGhEYXRhOiB0cnVlLCBtdXRhdGVkQXV0aERhdGE6IGF1dGhEYXRhIH07XG4gIGNvbnN0IG11dGF0ZWRBdXRoRGF0YSA9IHt9O1xuICBPYmplY3Qua2V5cyhhdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgLy8gQW5vbnltb3VzIHByb3ZpZGVyIGlzIG5vdCBoYW5kbGVkIHRoaXMgd2F5XG4gICAgaWYgKHByb3ZpZGVyID09PSAnYW5vbnltb3VzJykgcmV0dXJuO1xuICAgIGNvbnN0IHByb3ZpZGVyRGF0YSA9IGF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICBjb25zdCB1c2VyUHJvdmlkZXJBdXRoRGF0YSA9IHVzZXJBdXRoRGF0YVtwcm92aWRlcl07XG4gICAgaWYgKCFpc0RlZXBTdHJpY3RFcXVhbChwcm92aWRlckRhdGEsIHVzZXJQcm92aWRlckF1dGhEYXRhKSkge1xuICAgICAgbXV0YXRlZEF1dGhEYXRhW3Byb3ZpZGVyXSA9IHByb3ZpZGVyRGF0YTtcbiAgICB9XG4gIH0pO1xuICBjb25zdCBoYXNNdXRhdGVkQXV0aERhdGEgPSBPYmplY3Qua2V5cyhtdXRhdGVkQXV0aERhdGEpLmxlbmd0aCAhPT0gMDtcbiAgcmV0dXJuIHsgaGFzTXV0YXRlZEF1dGhEYXRhLCBtdXRhdGVkQXV0aERhdGEgfTtcbn07XG5cbmNvbnN0IGNoZWNrSWZVc2VySGFzUHJvdmlkZWRDb25maWd1cmVkUHJvdmlkZXJzRm9yTG9naW4gPSAoXG4gIHJlcSA9IHt9LFxuICBhdXRoRGF0YSA9IHt9LFxuICB1c2VyQXV0aERhdGEgPSB7fSxcbiAgY29uZmlnXG4pID0+IHtcbiAgY29uc3Qgc2F2ZWRVc2VyUHJvdmlkZXJzID0gT2JqZWN0LmtleXModXNlckF1dGhEYXRhKS5tYXAocHJvdmlkZXIgPT4gKHtcbiAgICBuYW1lOiBwcm92aWRlcixcbiAgICBhZGFwdGVyOiBjb25maWcuYXV0aERhdGFNYW5hZ2VyLmdldFZhbGlkYXRvckZvclByb3ZpZGVyKHByb3ZpZGVyKS5hZGFwdGVyLFxuICB9KSk7XG5cbiAgY29uc3QgaGFzUHJvdmlkZWRBU29sb1Byb3ZpZGVyID0gc2F2ZWRVc2VyUHJvdmlkZXJzLnNvbWUoXG4gICAgcHJvdmlkZXIgPT5cbiAgICAgIHByb3ZpZGVyICYmIHByb3ZpZGVyLmFkYXB0ZXIgJiYgcHJvdmlkZXIuYWRhcHRlci5wb2xpY3kgPT09ICdzb2xvJyAmJiBhdXRoRGF0YVtwcm92aWRlci5uYW1lXVxuICApO1xuXG4gIC8vIFNvbG8gcHJvdmlkZXJzIGNhbiBiZSBjb25zaWRlcmVkIGFzIHNhZmUsIHNvIHdlIGRvIG5vdCBoYXZlIHRvIGNoZWNrIGlmIHRoZSB1c2VyIG5lZWRzXG4gIC8vIHRvIHByb3ZpZGUgYW4gYWRkaXRpb25hbCBwcm92aWRlciB0byBsb2dpbi4gQW4gYXV0aCBhZGFwdGVyIHdpdGggXCJzb2xvXCIgKGxpa2Ugd2ViYXV0aG4pIG1lYW5zXG4gIC8vIG5vIFwiYWRkaXRpb25hbFwiIGF1dGggbmVlZHMgdG8gYmUgcHJvdmlkZWQgdG8gbG9naW4gKGxpa2UgT1RQLCBNRkEpXG4gIGlmIChoYXNQcm92aWRlZEFTb2xvUHJvdmlkZXIpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBhZGRpdGlvblByb3ZpZGVyc05vdEZvdW5kID0gW107XG4gIGNvbnN0IGhhc1Byb3ZpZGVkQXRMZWFzdE9uZUFkZGl0aW9uYWxQcm92aWRlciA9IHNhdmVkVXNlclByb3ZpZGVycy5zb21lKHByb3ZpZGVyID0+IHtcbiAgICBsZXQgcG9saWN5ID0gcHJvdmlkZXIuYWRhcHRlci5wb2xpY3k7XG4gICAgaWYgKHR5cGVvZiBwb2xpY3kgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnN0IHJlcXVlc3RPYmplY3QgPSB7XG4gICAgICAgIGlwOiByZXEuY29uZmlnLmlwLFxuICAgICAgICB1c2VyOiByZXEuYXV0aC51c2VyLFxuICAgICAgICBtYXN0ZXI6IHJlcS5hdXRoLmlzTWFzdGVyLFxuICAgICAgfTtcbiAgICAgIHBvbGljeSA9IHBvbGljeS5jYWxsKHByb3ZpZGVyLmFkYXB0ZXIsIHJlcXVlc3RPYmplY3QsIHVzZXJBdXRoRGF0YVtwcm92aWRlci5uYW1lXSk7XG4gICAgfVxuICAgIGlmIChwb2xpY3kgPT09ICdhZGRpdGlvbmFsJykge1xuICAgICAgaWYgKGF1dGhEYXRhW3Byb3ZpZGVyLm5hbWVdKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gUHVzaCBtaXNzaW5nIHByb3ZpZGVyIGZvciBlcnJvciBtZXNzYWdlXG4gICAgICAgIGFkZGl0aW9uUHJvdmlkZXJzTm90Rm91bmQucHVzaChwcm92aWRlci5uYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICBpZiAoaGFzUHJvdmlkZWRBdExlYXN0T25lQWRkaXRpb25hbFByb3ZpZGVyIHx8ICFhZGRpdGlvblByb3ZpZGVyc05vdEZvdW5kLmxlbmd0aCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICBQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSxcbiAgICBgTWlzc2luZyBhZGRpdGlvbmFsIGF1dGhEYXRhICR7YWRkaXRpb25Qcm92aWRlcnNOb3RGb3VuZC5qb2luKCcsJyl9YFxuICApO1xufTtcblxuLy8gVmFsaWRhdGUgZWFjaCBhdXRoRGF0YSBzdGVwLWJ5LXN0ZXAgYW5kIHJldHVybiB0aGUgcHJvdmlkZXIgcmVzcG9uc2VzXG5jb25zdCBoYW5kbGVBdXRoRGF0YVZhbGlkYXRpb24gPSBhc3luYyAoYXV0aERhdGEsIHJlcSwgZm91bmRVc2VyKSA9PiB7XG4gIGxldCB1c2VyO1xuICBpZiAoZm91bmRVc2VyKSB7XG4gICAgdXNlciA9IFBhcnNlLlVzZXIuZnJvbUpTT04oeyBjbGFzc05hbWU6ICdfVXNlcicsIC4uLmZvdW5kVXNlciB9KTtcbiAgICAvLyBGaW5kIHVzZXIgYnkgc2Vzc2lvbiBhbmQgY3VycmVudCBvYmplY3RJZDsgb25seSBwYXNzIHVzZXIgaWYgaXQncyB0aGUgY3VycmVudCB1c2VyIG9yIG1hc3RlciBrZXkgaXMgcHJvdmlkZWRcbiAgfSBlbHNlIGlmIChcbiAgICAocmVxLmF1dGggJiZcbiAgICAgIHJlcS5hdXRoLnVzZXIgJiZcbiAgICAgIHR5cGVvZiByZXEuZ2V0VXNlcklkID09PSAnZnVuY3Rpb24nICYmXG4gICAgICByZXEuZ2V0VXNlcklkKCkgPT09IHJlcS5hdXRoLnVzZXIuaWQpIHx8XG4gICAgKHJlcS5hdXRoICYmIHJlcS5hdXRoLmlzTWFzdGVyICYmIHR5cGVvZiByZXEuZ2V0VXNlcklkID09PSAnZnVuY3Rpb24nICYmIHJlcS5nZXRVc2VySWQoKSlcbiAgKSB7XG4gICAgdXNlciA9IG5ldyBQYXJzZS5Vc2VyKCk7XG4gICAgdXNlci5pZCA9IHJlcS5hdXRoLmlzTWFzdGVyID8gcmVxLmdldFVzZXJJZCgpIDogcmVxLmF1dGgudXNlci5pZDtcbiAgICBhd2FpdCB1c2VyLmZldGNoKHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pO1xuICB9XG5cbiAgY29uc3QgeyB1cGRhdGVkT2JqZWN0IH0gPSByZXEuYnVpbGRQYXJzZU9iamVjdHMoKTtcbiAgY29uc3QgcmVxdWVzdE9iamVjdCA9IGdldFJlcXVlc3RPYmplY3QodW5kZWZpbmVkLCByZXEuYXV0aCwgdXBkYXRlZE9iamVjdCwgdXNlciwgcmVxLmNvbmZpZyk7XG4gIC8vIFBlcmZvcm0gdmFsaWRhdGlvbiBhcyBzdGVwLWJ5LXN0ZXAgcGlwZWxpbmUgZm9yIGJldHRlciBlcnJvciBjb25zaXN0ZW5jeVxuICAvLyBhbmQgYWxzbyB0byBhdm9pZCB0byB0cmlnZ2VyIGEgcHJvdmlkZXIgKGxpa2UgT1RQIFNNUykgaWYgYW5vdGhlciBvbmUgZmFpbHNcbiAgY29uc3QgYWNjID0geyBhdXRoRGF0YToge30sIGF1dGhEYXRhUmVzcG9uc2U6IHt9IH07XG4gIGNvbnN0IGF1dGhLZXlzID0gT2JqZWN0LmtleXMoYXV0aERhdGEpLnNvcnQoKTtcbiAgZm9yIChjb25zdCBwcm92aWRlciBvZiBhdXRoS2V5cykge1xuICAgIGxldCBtZXRob2QgPSAnJztcbiAgICB0cnkge1xuICAgICAgaWYgKGF1dGhEYXRhW3Byb3ZpZGVyXSA9PT0gbnVsbCkge1xuICAgICAgICBhY2MuYXV0aERhdGFbcHJvdmlkZXJdID0gbnVsbDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCB7IHZhbGlkYXRvciB9ID0gcmVxLmNvbmZpZy5hdXRoRGF0YU1hbmFnZXIuZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIocHJvdmlkZXIpO1xuICAgICAgY29uc3QgYXV0aFByb3ZpZGVyID0gKHJlcS5jb25maWcuYXV0aCB8fCB7fSlbcHJvdmlkZXJdIHx8IHt9O1xuICAgICAgaWYgKCF2YWxpZGF0b3IgfHwgYXV0aFByb3ZpZGVyLmVuYWJsZWQgPT09IGZhbHNlKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5VTlNVUFBPUlRFRF9TRVJWSUNFLFxuICAgICAgICAgICdUaGlzIGF1dGhlbnRpY2F0aW9uIG1ldGhvZCBpcyB1bnN1cHBvcnRlZC4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBsZXQgdmFsaWRhdGlvblJlc3VsdCA9IGF3YWl0IHZhbGlkYXRvcihhdXRoRGF0YVtwcm92aWRlcl0sIHJlcSwgdXNlciwgcmVxdWVzdE9iamVjdCk7XG4gICAgICBtZXRob2QgPSB2YWxpZGF0aW9uUmVzdWx0ICYmIHZhbGlkYXRpb25SZXN1bHQubWV0aG9kO1xuICAgICAgcmVxdWVzdE9iamVjdC50cmlnZ2VyTmFtZSA9IG1ldGhvZDtcbiAgICAgIGlmICh2YWxpZGF0aW9uUmVzdWx0ICYmIHZhbGlkYXRpb25SZXN1bHQudmFsaWRhdG9yKSB7XG4gICAgICAgIHZhbGlkYXRpb25SZXN1bHQgPSBhd2FpdCB2YWxpZGF0aW9uUmVzdWx0LnZhbGlkYXRvcigpO1xuICAgICAgfVxuICAgICAgaWYgKCF2YWxpZGF0aW9uUmVzdWx0KSB7XG4gICAgICAgIGFjYy5hdXRoRGF0YVtwcm92aWRlcl0gPSBhdXRoRGF0YVtwcm92aWRlcl07XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKCFPYmplY3Qua2V5cyh2YWxpZGF0aW9uUmVzdWx0KS5sZW5ndGgpIHtcbiAgICAgICAgYWNjLmF1dGhEYXRhW3Byb3ZpZGVyXSA9IGF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmICh2YWxpZGF0aW9uUmVzdWx0LnJlc3BvbnNlKSB7XG4gICAgICAgIGFjYy5hdXRoRGF0YVJlc3BvbnNlW3Byb3ZpZGVyXSA9IHZhbGlkYXRpb25SZXN1bHQucmVzcG9uc2U7XG4gICAgICB9XG4gICAgICAvLyBTb21lIGF1dGggcHJvdmlkZXJzIGFmdGVyIGluaXRpYWxpemF0aW9uIHdpbGwgYXZvaWQgdG8gcmVwbGFjZSBhdXRoRGF0YSBhbHJlYWR5IHN0b3JlZFxuICAgICAgaWYgKCF2YWxpZGF0aW9uUmVzdWx0LmRvTm90U2F2ZSkge1xuICAgICAgICBhY2MuYXV0aERhdGFbcHJvdmlkZXJdID0gdmFsaWRhdGlvblJlc3VsdC5zYXZlIHx8IGF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnN0IGUgPSByZXNvbHZlRXJyb3IoZXJyLCB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQsXG4gICAgICAgIG1lc3NhZ2U6ICdBdXRoIGZhaWxlZC4gVW5rbm93biBlcnJvci4nLFxuICAgICAgfSk7XG4gICAgICBjb25zdCB1c2VyU3RyaW5nID1cbiAgICAgICAgcmVxLmF1dGggJiYgcmVxLmF1dGgudXNlciA/IHJlcS5hdXRoLnVzZXIuaWQgOiByZXEuZGF0YS5vYmplY3RJZCB8fCB1bmRlZmluZWQ7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgIGBGYWlsZWQgcnVubmluZyBhdXRoIHN0ZXAgJHttZXRob2R9IGZvciAke3Byb3ZpZGVyfSBmb3IgdXNlciAke3VzZXJTdHJpbmd9IHdpdGggRXJyb3I6IGAgK1xuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGUpLFxuICAgICAgICB7XG4gICAgICAgICAgYXV0aGVudGljYXRpb25TdGVwOiBtZXRob2QsXG4gICAgICAgICAgZXJyb3I6IGUsXG4gICAgICAgICAgdXNlcjogdXNlclN0cmluZyxcbiAgICAgICAgICBwcm92aWRlcixcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG4gIHJldHVybiBhY2M7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQXV0aCxcbiAgbWFzdGVyLFxuICBtYWludGVuYW5jZSxcbiAgbm9ib2R5LFxuICByZWFkT25seSxcbiAgc2hvdWxkVXBkYXRlU2Vzc2lvbkV4cGlyeSxcbiAgZ2V0QXV0aEZvclNlc3Npb25Ub2tlbixcbiAgZ2V0QXV0aEZvckxlZ2FjeVNlc3Npb25Ub2tlbixcbiAgZmluZFVzZXJzV2l0aEF1dGhEYXRhLFxuICBoYXNNdXRhdGVkQXV0aERhdGEsXG4gIGNoZWNrSWZVc2VySGFzUHJvdmlkZWRDb25maWd1cmVkUHJvdmlkZXJzRm9yTG9naW4sXG4gIGhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbixcbn07XG4iXSwibWFwcGluZ3MiOiI7O0FBQ0EsSUFBQUEsS0FBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsU0FBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsT0FBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsVUFBQSxHQUFBQyxzQkFBQSxDQUFBSixPQUFBO0FBQ0EsSUFBQUssVUFBQSxHQUFBRCxz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