parse-server 9.5.2-alpha.3 → 9.5.2-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -71,7 +71,9 @@
71
71
  const {
72
72
  Parse
73
73
  } = require('parse/node');
74
- const httpsRequest = require('./httpsRequest');
74
+ const jwksClient = require('jwks-rsa');
75
+ const jwt = require('jsonwebtoken');
76
+ const authUtils = require('./utils');
75
77
  const arraysEqual = (_arr1, _arr2) => {
76
78
  if (!Array.isArray(_arr1) || !Array.isArray(_arr2) || _arr1.length !== _arr2.length) {
77
79
  return false;
@@ -85,13 +87,30 @@ const arraysEqual = (_arr1, _arr2) => {
85
87
  }
86
88
  return true;
87
89
  };
88
- const handleAuth = async ({
90
+ const getKeycloakKeyByKeyId = async (keyId, jwksUri, cacheMaxEntries, cacheMaxAge) => {
91
+ const client = jwksClient({
92
+ jwksUri,
93
+ cache: true,
94
+ cacheMaxEntries,
95
+ cacheMaxAge
96
+ });
97
+ let key;
98
+ try {
99
+ key = await authUtils.getSigningKey(client, keyId);
100
+ } catch {
101
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Unable to find matching key for Key ID: ${keyId}`);
102
+ }
103
+ return key;
104
+ };
105
+ const verifyAccessToken = async ({
89
106
  access_token,
90
107
  id,
91
108
  roles,
92
109
  groups
93
110
  } = {}, {
94
- config
111
+ config,
112
+ cacheMaxEntries,
113
+ cacheMaxAge
95
114
  } = {}) => {
96
115
  if (!(access_token && id)) {
97
116
  throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Missing access token and/or User id');
@@ -99,45 +118,46 @@ const handleAuth = async ({
99
118
  if (!config || !(config['auth-server-url'] && config['realm'])) {
100
119
  throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Missing keycloak configuration');
101
120
  }
121
+ if (!config['client-id']) {
122
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Keycloak auth is not configured. Missing client-id.');
123
+ }
124
+ const expectedIssuer = `${config['auth-server-url']}/realms/${config['realm']}`;
125
+ const jwksUri = `${config['auth-server-url']}/realms/${config['realm']}/protocol/openid-connect/certs`;
126
+ const {
127
+ kid: keyId
128
+ } = authUtils.getHeaderFromToken(access_token);
129
+ const ONE_HOUR_IN_MS = 3600000;
130
+ cacheMaxAge = cacheMaxAge || ONE_HOUR_IN_MS;
131
+ cacheMaxEntries = cacheMaxEntries || 5;
132
+ const keycloakKey = await getKeycloakKeyByKeyId(keyId, jwksUri, cacheMaxEntries, cacheMaxAge);
133
+ const signingKey = keycloakKey.publicKey || keycloakKey.rsaPublicKey;
134
+ let jwtClaims;
102
135
  try {
103
- const response = await httpsRequest.get({
104
- host: config['auth-server-url'],
105
- path: `/realms/${config['realm']}/protocol/openid-connect/userinfo`,
106
- headers: {
107
- Authorization: 'Bearer ' + access_token
108
- }
136
+ jwtClaims = jwt.verify(access_token, signingKey, {
137
+ algorithms: ['RS256']
109
138
  });
110
- if (response && response.data && response.data.sub == id && arraysEqual(response.data.roles, roles) && arraysEqual(response.data.groups, groups)) {
111
- return;
112
- }
139
+ } catch (exception) {
140
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${exception.message}`);
141
+ }
142
+ if (jwtClaims.iss !== expectedIssuer) {
143
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `access token not issued by correct provider - expected: ${expectedIssuer} | from: ${jwtClaims.iss}`);
144
+ }
145
+ if (jwtClaims.azp !== config['client-id']) {
146
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `access token is not authorized for this client - expected: ${config['client-id']} | from: ${jwtClaims.azp}`);
147
+ }
148
+ if (jwtClaims.sub !== id) {
149
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'auth data is invalid for this user.');
150
+ }
151
+ const rolesMatch = jwtClaims.roles === roles || arraysEqual(jwtClaims.roles, roles);
152
+ const groupsMatch = jwtClaims.groups === groups || arraysEqual(jwtClaims.groups, groups);
153
+ if (!rolesMatch || !groupsMatch) {
113
154
  throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid authentication');
114
- } catch (e) {
115
- if (e instanceof Parse.Error) {
116
- throw e;
117
- }
118
- const error = JSON.parse(e.text);
119
- if (error.error_description) {
120
- throw new Parse.Error(Parse.Error.HOSTING_ERROR, error.error_description);
121
- } else {
122
- throw new Parse.Error(Parse.Error.HOSTING_ERROR, 'Could not connect to the authentication server');
123
- }
124
155
  }
156
+ return jwtClaims;
125
157
  };
126
-
127
- /*
128
- @param {Object} authData: the client provided authData
129
- @param {string} authData.access_token: the access_token retrieved from client authentication in Keycloak
130
- @param {string} authData.id: the id retrieved from client authentication in Keycloak
131
- @param {Array} authData.roles: the roles retrieved from client authentication in Keycloak
132
- @param {Array} authData.groups: the groups retrieved from client authentication in Keycloak
133
- @param {Object} options: additional options
134
- @param {Object} options.config: the config object passed during Parse Server instantiation
135
- */
136
158
  function validateAuthData(authData, options = {}) {
137
- return handleAuth(authData, options);
159
+ return verifyAccessToken(authData, options);
138
160
  }
139
-
140
- // Returns a promise that fulfills if this app id is valid.
141
161
  function validateAppId() {
142
162
  return Promise.resolve();
143
163
  }
@@ -145,4 +165,4 @@ module.exports = {
145
165
  validateAppId,
146
166
  validateAuthData
147
167
  };
148
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJhcnJheXNFcXVhbCIsIl9hcnIxIiwiX2FycjIiLCJBcnJheSIsImlzQXJyYXkiLCJsZW5ndGgiLCJhcnIxIiwiY29uY2F0Iiwic29ydCIsImFycjIiLCJpIiwiaGFuZGxlQXV0aCIsImFjY2Vzc190b2tlbiIsImlkIiwicm9sZXMiLCJncm91cHMiLCJjb25maWciLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJyZXNwb25zZSIsImdldCIsImhvc3QiLCJwYXRoIiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJkYXRhIiwic3ViIiwiZSIsImVycm9yIiwiSlNPTiIsInBhcnNlIiwidGV4dCIsImVycm9yX2Rlc2NyaXB0aW9uIiwiSE9TVElOR19FUlJPUiIsInZhbGlkYXRlQXV0aERhdGEiLCJhdXRoRGF0YSIsIm9wdGlvbnMiLCJ2YWxpZGF0ZUFwcElkIiwiUHJvbWlzZSIsInJlc29sdmUiLCJtb2R1bGUiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0FkYXB0ZXJzL0F1dGgva2V5Y2xvYWsuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQYXJzZSBTZXJ2ZXIgYXV0aGVudGljYXRpb24gYWRhcHRlciBmb3IgS2V5Y2xvYWsuXG4gKlxuICogQGNsYXNzIEtleWNsb2FrQWRhcHRlclxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgYWRhcHRlciBjb25maWd1cmF0aW9uIG9wdGlvbnMuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucy5jb25maWcgLSBUaGUgS2V5Y2xvYWsgY29uZmlndXJhdGlvbiBvYmplY3QsIHR5cGljYWxseSBsb2FkZWQgZnJvbSBhIEpTT04gZmlsZS5cbiAqIEBwYXJhbSB7U3RyaW5nfSBvcHRpb25zLmNvbmZpZy5hdXRoLXNlcnZlci11cmwgLSBUaGUgS2V5Y2xvYWsgYXV0aGVudGljYXRpb24gc2VydmVyIFVSTC5cbiAqIEBwYXJhbSB7U3RyaW5nfSBvcHRpb25zLmNvbmZpZy5yZWFsbSAtIFRoZSBLZXljbG9hayByZWFsbSBuYW1lLlxuICogQHBhcmFtIHtTdHJpbmd9IG9wdGlvbnMuY29uZmlnLmNsaWVudC1pZCAtIFRoZSBLZXljbG9hayBjbGllbnQgSUQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGF1dGhEYXRhIC0gVGhlIGF1dGhlbnRpY2F0aW9uIGRhdGEgcHJvdmlkZWQgYnkgdGhlIGNsaWVudC5cbiAqIEBwYXJhbSB7U3RyaW5nfSBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4gLSBUaGUgS2V5Y2xvYWsgYWNjZXNzIHRva2VuIHJldHJpZXZlZCBkdXJpbmcgY2xpZW50IGF1dGhlbnRpY2F0aW9uLlxuICogQHBhcmFtIHtTdHJpbmd9IGF1dGhEYXRhLmlkIC0gVGhlIHVzZXIgSUQgcmV0cmlldmVkIGZyb20gS2V5Y2xvYWsgZHVyaW5nIGNsaWVudCBhdXRoZW50aWNhdGlvbi5cbiAqIEBwYXJhbSB7QXJyYXl9IFthdXRoRGF0YS5yb2xlc10gLSBUaGUgcm9sZXMgYXNzaWduZWQgdG8gdGhlIHVzZXIgaW4gS2V5Y2xvYWsgKG9wdGlvbmFsKS5cbiAqIEBwYXJhbSB7QXJyYXl9IFthdXRoRGF0YS5ncm91cHNdIC0gVGhlIGdyb3VwcyBhc3NpZ25lZCB0byB0aGUgdXNlciBpbiBLZXljbG9hayAob3B0aW9uYWwpLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogIyMgUGFyc2UgU2VydmVyIENvbmZpZ3VyYXRpb25cbiAqIFRvIGNvbmZpZ3VyZSBQYXJzZSBTZXJ2ZXIgZm9yIEtleWNsb2FrIGF1dGhlbnRpY2F0aW9uLCB1c2UgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6XG4gKiBgYGBqYXZhc2NyaXB0XG4gKiB7XG4gKiAgIFwiYXV0aFwiOiB7XG4gKiAgICAgXCJrZXljbG9ha1wiOiB7XG4gKiAgICAgICBcImNvbmZpZ1wiOiByZXF1aXJlKCcuL2F1dGgva2V5Y2xvYWsuanNvbicpXG4gKiAgICAgfVxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqIEVuc3VyZSB0aGUgYGtleWNsb2FrLmpzb25gIGNvbmZpZ3VyYXRpb24gZmlsZSBpcyBnZW5lcmF0ZWQgZnJvbSBLZXljbG9haydzIHNldHVwIGd1aWRlIGFuZCBpbmNsdWRlczpcbiAqIC0gYGF1dGgtc2VydmVyLXVybGA6IFRoZSBLZXljbG9hayBhdXRoZW50aWNhdGlvbiBzZXJ2ZXIgVVJMLlxuICogLSBgcmVhbG1gOiBUaGUgS2V5Y2xvYWsgcmVhbG0gbmFtZS5cbiAqIC0gYGNsaWVudC1pZGA6IFRoZSBLZXljbG9hayBjbGllbnQgSUQuXG4gKlxuICogIyMgQXV0aCBEYXRhXG4gKiBUaGUgYWRhcHRlciByZXF1aXJlcyB0aGUgZm9sbG93aW5nIGBhdXRoRGF0YWAgZmllbGRzOlxuICogLSBgYWNjZXNzX3Rva2VuYDogVGhlIEtleWNsb2FrIGFjY2VzcyB0b2tlbiByZXRyaWV2ZWQgZHVyaW5nIGNsaWVudCBhdXRoZW50aWNhdGlvbi5cbiAqIC0gYGlkYDogVGhlIHVzZXIgSUQgcmV0cmlldmVkIGZyb20gS2V5Y2xvYWsgZHVyaW5nIGNsaWVudCBhdXRoZW50aWNhdGlvbi5cbiAqIC0gYHJvbGVzYCAob3B0aW9uYWwpOiBUaGUgcm9sZXMgYXNzaWduZWQgdG8gdGhlIHVzZXIgaW4gS2V5Y2xvYWsuXG4gKiAtIGBncm91cHNgIChvcHRpb25hbCk6IFRoZSBncm91cHMgYXNzaWduZWQgdG8gdGhlIHVzZXIgaW4gS2V5Y2xvYWsuXG4gKlxuICogIyMgQXV0aCBQYXlsb2FkIEV4YW1wbGVcbiAqICMjIyBFeGFtcGxlIEF1dGggRGF0YVxuICogYGBganNvblxuICoge1xuICogICBcImtleWNsb2FrXCI6IHtcbiAqICAgICBcImFjY2Vzc190b2tlblwiOiBcImFuIGF1dGhvcml6ZWQgS2V5Y2xvYWsgYWNjZXNzIHRva2VuIGZvciB0aGUgdXNlclwiLFxuICogICAgIFwiaWRcIjogXCJ1c2VyJ3MgS2V5Y2xvYWsgSUQgYXMgYSBzdHJpbmdcIixcbiAqICAgICBcInJvbGVzXCI6IFtcImFkbWluXCIsIFwidXNlclwiXSxcbiAqICAgICBcImdyb3Vwc1wiOiBbXCJncm91cDFcIiwgXCJncm91cDJcIl1cbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogIyMgTm90ZXNcbiAqIC0gUGFyc2UgU2VydmVyIHZhbGlkYXRlcyB0aGUgcHJvdmlkZWQgYGF1dGhEYXRhYCBieSBtYWtpbmcgYSBgdXNlcmluZm9gIGNhbGwgdG8gS2V5Y2xvYWsgYW5kIGVuc3VyZXMgdGhlIGF0dHJpYnV0ZXMgbWF0Y2ggdGhvc2UgcmV0dXJuZWQgYnkgS2V5Y2xvYWsuXG4gKlxuICogIyMgS2V5Y2xvYWsgQ29uZmlndXJhdGlvblxuICogVG8gY29uZmlndXJlIEtleWNsb2FrLCBjb3B5IHRoZSBKU09OIGNvbmZpZ3VyYXRpb24gZmlsZSBnZW5lcmF0ZWQgZnJvbSBLZXljbG9haydzIHNldHVwIGd1aWRlOlxuICogLSBbS2V5Y2xvYWsgU2VjdXJpbmcgQXBwcyBEb2N1bWVudGF0aW9uXShodHRwczovL3d3dy5rZXljbG9hay5vcmcvZG9jcy9sYXRlc3Qvc2VjdXJpbmdfYXBwcy9pbmRleC5odG1sI19qYXZhc2NyaXB0X2FkYXB0ZXIpXG4gKlxuICogUGxhY2UgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZSBvbiB5b3VyIHNlcnZlciwgZm9yIGV4YW1wbGU6XG4gKiAtIGBhdXRoL2tleWNsb2FrLmpzb25gXG4gKlxuICogRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gS2V5Y2xvYWsgYXV0aGVudGljYXRpb24sIHNlZTpcbiAqIC0gW1NlY3VyaW5nIEFwcHMgRG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly93d3cua2V5Y2xvYWsub3JnL2RvY3MvbGF0ZXN0L3NlY3VyaW5nX2FwcHMvKVxuICogLSBbU2VydmVyIEFkbWluaXN0cmF0aW9uIERvY3VtZW50YXRpb25dKGh0dHBzOi8vd3d3LmtleWNsb2FrLm9yZy9kb2NzL2xhdGVzdC9zZXJ2ZXJfYWRtaW4vKVxuICovXG5cbmNvbnN0IHsgUGFyc2UgfSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbmNvbnN0IGFycmF5c0VxdWFsID0gKF9hcnIxLCBfYXJyMikgPT4ge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoX2FycjEpIHx8ICFBcnJheS5pc0FycmF5KF9hcnIyKSB8fCBfYXJyMS5sZW5ndGggIT09IF9hcnIyLmxlbmd0aCkgeyByZXR1cm4gZmFsc2U7IH1cblxuICB2YXIgYXJyMSA9IF9hcnIxLmNvbmNhdCgpLnNvcnQoKTtcbiAgdmFyIGFycjIgPSBfYXJyMi5jb25jYXQoKS5zb3J0KCk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIxLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGFycjFbaV0gIT09IGFycjJbaV0pIHsgcmV0dXJuIGZhbHNlOyB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmNvbnN0IGhhbmRsZUF1dGggPSBhc3luYyAoeyBhY2Nlc3NfdG9rZW4sIGlkLCByb2xlcywgZ3JvdXBzIH0gPSB7fSwgeyBjb25maWcgfSA9IHt9KSA9PiB7XG4gIGlmICghKGFjY2Vzc190b2tlbiAmJiBpZCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ01pc3NpbmcgYWNjZXNzIHRva2VuIGFuZC9vciBVc2VyIGlkJyk7XG4gIH1cbiAgaWYgKCFjb25maWcgfHwgIShjb25maWdbJ2F1dGgtc2VydmVyLXVybCddICYmIGNvbmZpZ1sncmVhbG0nXSkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ01pc3Npbmcga2V5Y2xvYWsgY29uZmlndXJhdGlvbicpO1xuICB9XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBodHRwc1JlcXVlc3QuZ2V0KHtcbiAgICAgIGhvc3Q6IGNvbmZpZ1snYXV0aC1zZXJ2ZXItdXJsJ10sXG4gICAgICBwYXRoOiBgL3JlYWxtcy8ke2NvbmZpZ1sncmVhbG0nXX0vcHJvdG9jb2wvb3BlbmlkLWNvbm5lY3QvdXNlcmluZm9gLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICBBdXRob3JpemF0aW9uOiAnQmVhcmVyICcgKyBhY2Nlc3NfdG9rZW4sXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGlmIChcbiAgICAgIHJlc3BvbnNlICYmXG4gICAgICByZXNwb25zZS5kYXRhICYmXG4gICAgICByZXNwb25zZS5kYXRhLnN1YiA9PSBpZCAmJlxuICAgICAgYXJyYXlzRXF1YWwocmVzcG9uc2UuZGF0YS5yb2xlcywgcm9sZXMpICYmXG4gICAgICBhcnJheXNFcXVhbChyZXNwb25zZS5kYXRhLmdyb3VwcywgZ3JvdXBzKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgYXV0aGVudGljYXRpb24nKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChlIGluc3RhbmNlb2YgUGFyc2UuRXJyb3IpIHtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICAgIGNvbnN0IGVycm9yID0gSlNPTi5wYXJzZShlLnRleHQpO1xuICAgIGlmIChlcnJvci5lcnJvcl9kZXNjcmlwdGlvbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkhPU1RJTkdfRVJST1IsIGVycm9yLmVycm9yX2Rlc2NyaXB0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5IT1NUSU5HX0VSUk9SLFxuICAgICAgICAnQ291bGQgbm90IGNvbm5lY3QgdG8gdGhlIGF1dGhlbnRpY2F0aW9uIHNlcnZlcidcbiAgICAgICk7XG4gICAgfVxuICB9XG59O1xuXG4vKlxuICBAcGFyYW0ge09iamVjdH0gYXV0aERhdGE6IHRoZSBjbGllbnQgcHJvdmlkZWQgYXV0aERhdGFcbiAgQHBhcmFtIHtzdHJpbmd9IGF1dGhEYXRhLmFjY2Vzc190b2tlbjogdGhlIGFjY2Vzc190b2tlbiByZXRyaWV2ZWQgZnJvbSBjbGllbnQgYXV0aGVudGljYXRpb24gaW4gS2V5Y2xvYWtcbiAgQHBhcmFtIHtzdHJpbmd9IGF1dGhEYXRhLmlkOiB0aGUgaWQgcmV0cmlldmVkIGZyb20gY2xpZW50IGF1dGhlbnRpY2F0aW9uIGluIEtleWNsb2FrXG4gIEBwYXJhbSB7QXJyYXl9ICBhdXRoRGF0YS5yb2xlczogdGhlIHJvbGVzIHJldHJpZXZlZCBmcm9tIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpbiBLZXljbG9ha1xuICBAcGFyYW0ge0FycmF5fSAgYXV0aERhdGEuZ3JvdXBzOiB0aGUgZ3JvdXBzIHJldHJpZXZlZCBmcm9tIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpbiBLZXljbG9ha1xuICBAcGFyYW0ge09iamVjdH0gb3B0aW9uczogYWRkaXRpb25hbCBvcHRpb25zXG4gIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLmNvbmZpZzogdGhlIGNvbmZpZyBvYmplY3QgcGFzc2VkIGR1cmluZyBQYXJzZSBTZXJ2ZXIgaW5zdGFudGlhdGlvblxuKi9cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMgPSB7fSkge1xuICByZXR1cm4gaGFuZGxlQXV0aChhdXRoRGF0YSwgb3B0aW9ucyk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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
168
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJqd2tzQ2xpZW50Iiwiand0IiwiYXV0aFV0aWxzIiwiYXJyYXlzRXF1YWwiLCJfYXJyMSIsIl9hcnIyIiwiQXJyYXkiLCJpc0FycmF5IiwibGVuZ3RoIiwiYXJyMSIsImNvbmNhdCIsInNvcnQiLCJhcnIyIiwiaSIsImdldEtleWNsb2FrS2V5QnlLZXlJZCIsImtleUlkIiwiandrc1VyaSIsImNhY2hlTWF4RW50cmllcyIsImNhY2hlTWF4QWdlIiwiY2xpZW50IiwiY2FjaGUiLCJrZXkiLCJnZXRTaWduaW5nS2V5IiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmVyaWZ5QWNjZXNzVG9rZW4iLCJhY2Nlc3NfdG9rZW4iLCJpZCIsInJvbGVzIiwiZ3JvdXBzIiwiY29uZmlnIiwiZXhwZWN0ZWRJc3N1ZXIiLCJraWQiLCJnZXRIZWFkZXJGcm9tVG9rZW4iLCJPTkVfSE9VUl9JTl9NUyIsImtleWNsb2FrS2V5Iiwic2lnbmluZ0tleSIsInB1YmxpY0tleSIsInJzYVB1YmxpY0tleSIsImp3dENsYWltcyIsInZlcmlmeSIsImFsZ29yaXRobXMiLCJleGNlcHRpb24iLCJtZXNzYWdlIiwiaXNzIiwiYXpwIiwic3ViIiwicm9sZXNNYXRjaCIsImdyb3Vwc01hdGNoIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvQWRhcHRlcnMvQXV0aC9rZXljbG9hay5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBhcnNlIFNlcnZlciBhdXRoZW50aWNhdGlvbiBhZGFwdGVyIGZvciBLZXljbG9hay5cbiAqXG4gKiBAY2xhc3MgS2V5Y2xvYWtBZGFwdGVyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBhZGFwdGVyIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLmNvbmZpZyAtIFRoZSBLZXljbG9hayBjb25maWd1cmF0aW9uIG9iamVjdCwgdHlwaWNhbGx5IGxvYWRlZCBmcm9tIGEgSlNPTiBmaWxlLlxuICogQHBhcmFtIHtTdHJpbmd9IG9wdGlvbnMuY29uZmlnLmF1dGgtc2VydmVyLXVybCAtIFRoZSBLZXljbG9hayBhdXRoZW50aWNhdGlvbiBzZXJ2ZXIgVVJMLlxuICogQHBhcmFtIHtTdHJpbmd9IG9wdGlvbnMuY29uZmlnLnJlYWxtIC0gVGhlIEtleWNsb2FrIHJlYWxtIG5hbWUuXG4gKiBAcGFyYW0ge1N0cmluZ30gb3B0aW9ucy5jb25maWcuY2xpZW50LWlkIC0gVGhlIEtleWNsb2FrIGNsaWVudCBJRC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gYXV0aERhdGEgLSBUaGUgYXV0aGVudGljYXRpb24gZGF0YSBwcm92aWRlZCBieSB0aGUgY2xpZW50LlxuICogQHBhcmFtIHtTdHJpbmd9IGF1dGhEYXRhLmFjY2Vzc190b2tlbiAtIFRoZSBLZXljbG9hayBhY2Nlc3MgdG9rZW4gcmV0cmlldmVkIGR1cmluZyBjbGllbnQgYXV0aGVudGljYXRpb24uXG4gKiBAcGFyYW0ge1N0cmluZ30gYXV0aERhdGEuaWQgLSBUaGUgdXNlciBJRCByZXRyaWV2ZWQgZnJvbSBLZXljbG9hayBkdXJpbmcgY2xpZW50IGF1dGhlbnRpY2F0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2F1dGhEYXRhLnJvbGVzXSAtIFRoZSByb2xlcyBhc3NpZ25lZCB0byB0aGUgdXNlciBpbiBLZXljbG9hayAob3B0aW9uYWwpLlxuICogQHBhcmFtIHtBcnJheX0gW2F1dGhEYXRhLmdyb3Vwc10gLSBUaGUgZ3JvdXBzIGFzc2lnbmVkIHRvIHRoZSB1c2VyIGluIEtleWNsb2FrIChvcHRpb25hbCkuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiAjIyBQYXJzZSBTZXJ2ZXIgQ29uZmlndXJhdGlvblxuICogVG8gY29uZmlndXJlIFBhcnNlIFNlcnZlciBmb3IgS2V5Y2xvYWsgYXV0aGVudGljYXRpb24sIHVzZSB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIHtcbiAqICAgXCJhdXRoXCI6IHtcbiAqICAgICBcImtleWNsb2FrXCI6IHtcbiAqICAgICAgIFwiY29uZmlnXCI6IHJlcXVpcmUoJy4vYXV0aC9rZXljbG9hay5qc29uJylcbiAqICAgICB9XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICogRW5zdXJlIHRoZSBga2V5Y2xvYWsuanNvbmAgY29uZmlndXJhdGlvbiBmaWxlIGlzIGdlbmVyYXRlZCBmcm9tIEtleWNsb2FrJ3Mgc2V0dXAgZ3VpZGUgYW5kIGluY2x1ZGVzOlxuICogLSBgYXV0aC1zZXJ2ZXItdXJsYDogVGhlIEtleWNsb2FrIGF1dGhlbnRpY2F0aW9uIHNlcnZlciBVUkwuXG4gKiAtIGByZWFsbWA6IFRoZSBLZXljbG9hayByZWFsbSBuYW1lLlxuICogLSBgY2xpZW50LWlkYDogVGhlIEtleWNsb2FrIGNsaWVudCBJRC5cbiAqXG4gKiAjIyBBdXRoIERhdGFcbiAqIFRoZSBhZGFwdGVyIHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgYGF1dGhEYXRhYCBmaWVsZHM6XG4gKiAtIGBhY2Nlc3NfdG9rZW5gOiBUaGUgS2V5Y2xvYWsgYWNjZXNzIHRva2VuIHJldHJpZXZlZCBkdXJpbmcgY2xpZW50IGF1dGhlbnRpY2F0aW9uLlxuICogLSBgaWRgOiBUaGUgdXNlciBJRCByZXRyaWV2ZWQgZnJvbSBLZXljbG9hayBkdXJpbmcgY2xpZW50IGF1dGhlbnRpY2F0aW9uLlxuICogLSBgcm9sZXNgIChvcHRpb25hbCk6IFRoZSByb2xlcyBhc3NpZ25lZCB0byB0aGUgdXNlciBpbiBLZXljbG9hay5cbiAqIC0gYGdyb3Vwc2AgKG9wdGlvbmFsKTogVGhlIGdyb3VwcyBhc3NpZ25lZCB0byB0aGUgdXNlciBpbiBLZXljbG9hay5cbiAqXG4gKiAjIyBBdXRoIFBheWxvYWQgRXhhbXBsZVxuICogIyMjIEV4YW1wbGUgQXV0aCBEYXRhXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwia2V5Y2xvYWtcIjoge1xuICogICAgIFwiYWNjZXNzX3Rva2VuXCI6IFwiYW4gYXV0aG9yaXplZCBLZXljbG9hayBhY2Nlc3MgdG9rZW4gZm9yIHRoZSB1c2VyXCIsXG4gKiAgICAgXCJpZFwiOiBcInVzZXIncyBLZXljbG9hayBJRCBhcyBhIHN0cmluZ1wiLFxuICogICAgIFwicm9sZXNcIjogW1wiYWRtaW5cIiwgXCJ1c2VyXCJdLFxuICogICAgIFwiZ3JvdXBzXCI6IFtcImdyb3VwMVwiLCBcImdyb3VwMlwiXVxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyBOb3Rlc1xuICogLSBQYXJzZSBTZXJ2ZXIgdmFsaWRhdGVzIHRoZSBwcm92aWRlZCBgYXV0aERhdGFgIGJ5IG1ha2luZyBhIGB1c2VyaW5mb2AgY2FsbCB0byBLZXljbG9hayBhbmQgZW5zdXJlcyB0aGUgYXR0cmlidXRlcyBtYXRjaCB0aG9zZSByZXR1cm5lZCBieSBLZXljbG9hay5cbiAqXG4gKiAjIyBLZXljbG9hayBDb25maWd1cmF0aW9uXG4gKiBUbyBjb25maWd1cmUgS2V5Y2xvYWssIGNvcHkgdGhlIEpTT04gY29uZmlndXJhdGlvbiBmaWxlIGdlbmVyYXRlZCBmcm9tIEtleWNsb2FrJ3Mgc2V0dXAgZ3VpZGU6XG4gKiAtIFtLZXljbG9hayBTZWN1cmluZyBBcHBzIERvY3VtZW50YXRpb25dKGh0dHBzOi8vd3d3LmtleWNsb2FrLm9yZy9kb2NzL2xhdGVzdC9zZWN1cmluZ19hcHBzL2luZGV4Lmh0bWwjX2phdmFzY3JpcHRfYWRhcHRlcilcbiAqXG4gKiBQbGFjZSB0aGUgY29uZmlndXJhdGlvbiBmaWxlIG9uIHlvdXIgc2VydmVyLCBmb3IgZXhhbXBsZTpcbiAqIC0gYGF1dGgva2V5Y2xvYWsuanNvbmBcbiAqXG4gKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBLZXljbG9hayBhdXRoZW50aWNhdGlvbiwgc2VlOlxuICogLSBbU2VjdXJpbmcgQXBwcyBEb2N1bWVudGF0aW9uXShodHRwczovL3d3dy5rZXljbG9hay5vcmcvZG9jcy9sYXRlc3Qvc2VjdXJpbmdfYXBwcy8pXG4gKiAtIFtTZXJ2ZXIgQWRtaW5pc3RyYXRpb24gRG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly93d3cua2V5Y2xvYWsub3JnL2RvY3MvbGF0ZXN0L3NlcnZlcl9hZG1pbi8pXG4gKi9cblxuY29uc3QgeyBQYXJzZSB9ID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpO1xuY29uc3Qgandrc0NsaWVudCA9IHJlcXVpcmUoJ2p3a3MtcnNhJyk7XG5jb25zdCBqd3QgPSByZXF1aXJlKCdqc29ud2VidG9rZW4nKTtcbmNvbnN0IGF1dGhVdGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxuY29uc3QgYXJyYXlzRXF1YWwgPSAoX2FycjEsIF9hcnIyKSA9PiB7XG4gIGlmICghQXJyYXkuaXNBcnJheShfYXJyMSkgfHwgIUFycmF5LmlzQXJyYXkoX2FycjIpIHx8IF9hcnIxLmxlbmd0aCAhPT0gX2FycjIubGVuZ3RoKSB7IHJldHVybiBmYWxzZTsgfVxuXG4gIHZhciBhcnIxID0gX2FycjEuY29uY2F0KCkuc29ydCgpO1xuICB2YXIgYXJyMiA9IF9hcnIyLmNvbmNhdCgpLnNvcnQoKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGFycjEubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoYXJyMVtpXSAhPT0gYXJyMltpXSkgeyByZXR1cm4gZmFsc2U7IH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuY29uc3QgZ2V0S2V5Y2xvYWtLZXlCeUtleUlkID0gYXN5bmMgKGtleUlkLCBqd2tzVXJpLCBjYWNoZU1heEVudHJpZXMsIGNhY2hlTWF4QWdlKSA9PiB7XG4gIGNvbnN0IGNsaWVudCA9IGp3a3NDbGllbnQoe1xuICAgIGp3a3NVcmksXG4gICAgY2FjaGU6IHRydWUsXG4gICAgY2FjaGVNYXhFbnRyaWVzLFxuICAgIGNhY2hlTWF4QWdlLFxuICB9KTtcblxuICBsZXQga2V5O1xuICB0cnkge1xuICAgIGtleSA9IGF3YWl0IGF1dGhVdGlscy5nZXRTaWduaW5nS2V5KGNsaWVudCwga2V5SWQpO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgYFVuYWJsZSB0byBmaW5kIG1hdGNoaW5nIGtleSBmb3IgS2V5IElEOiAke2tleUlkfWBcbiAgICApO1xuICB9XG4gIHJldHVybiBrZXk7XG59O1xuXG5jb25zdCB2ZXJpZnlBY2Nlc3NUb2tlbiA9IGFzeW5jIChcbiAgeyBhY2Nlc3NfdG9rZW4sIGlkLCByb2xlcywgZ3JvdXBzIH0gPSB7fSxcbiAgeyBjb25maWcsIGNhY2hlTWF4RW50cmllcywgY2FjaGVNYXhBZ2UgfSA9IHt9XG4pID0+IHtcbiAgaWYgKCEoYWNjZXNzX3Rva2VuICYmIGlkKSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnTWlzc2luZyBhY2Nlc3MgdG9rZW4gYW5kL29yIFVzZXIgaWQnKTtcbiAgfVxuICBpZiAoIWNvbmZpZyB8fCAhKGNvbmZpZ1snYXV0aC1zZXJ2ZXItdXJsJ10gJiYgY29uZmlnWydyZWFsbSddKSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnTWlzc2luZyBrZXljbG9hayBjb25maWd1cmF0aW9uJyk7XG4gIH1cbiAgaWYgKCFjb25maWdbJ2NsaWVudC1pZCddKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICdLZXljbG9hayBhdXRoIGlzIG5vdCBjb25maWd1cmVkLiBNaXNzaW5nIGNsaWVudC1pZC4nXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IGV4cGVjdGVkSXNzdWVyID0gYCR7Y29uZmlnWydhdXRoLXNlcnZlci11cmwnXX0vcmVhbG1zLyR7Y29uZmlnWydyZWFsbSddfWA7XG4gIGNvbnN0IGp3a3NVcmkgPSBgJHtjb25maWdbJ2F1dGgtc2VydmVyLXVybCddfS9yZWFsbXMvJHtjb25maWdbJ3JlYWxtJ119L3Byb3RvY29sL29wZW5pZC1jb25uZWN0L2NlcnRzYDtcblxuICBjb25zdCB7IGtpZDoga2V5SWQgfSA9IGF1dGhVdGlscy5nZXRIZWFkZXJGcm9tVG9rZW4oYWNjZXNzX3Rva2VuKTtcbiAgY29uc3QgT05FX0hPVVJfSU5fTVMgPSAzNjAwMDAwO1xuXG4gIGNhY2hlTWF4QWdlID0gY2FjaGVNYXhBZ2UgfHwgT05FX0hPVVJfSU5fTVM7XG4gIGNhY2hlTWF4RW50cmllcyA9IGNhY2hlTWF4RW50cmllcyB8fCA1O1xuXG4gIGNvbnN0IGtleWNsb2FrS2V5ID0gYXdhaXQgZ2V0S2V5Y2xvYWtLZXlCeUtleUlkKGtleUlkLCBqd2tzVXJpLCBjYWNoZU1heEVudHJpZXMsIGNhY2hlTWF4QWdlKTtcbiAgY29uc3Qgc2lnbmluZ0tleSA9IGtleWNsb2FrS2V5LnB1YmxpY0tleSB8fCBrZXljbG9ha0tleS5yc2FQdWJsaWNLZXk7XG5cbiAgbGV0IGp3dENsYWltcztcbiAgdHJ5IHtcbiAgICBqd3RDbGFpbXMgPSBqd3QudmVyaWZ5KGFjY2Vzc190b2tlbiwgc2lnbmluZ0tleSwge1xuICAgICAgYWxnb3JpdGhtczogWydSUzI1NiddLFxuICAgIH0pO1xuICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYCR7ZXhjZXB0aW9uLm1lc3NhZ2V9YCk7XG4gIH1cblxuICBpZiAoand0Q2xhaW1zLmlzcyAhPT0gZXhwZWN0ZWRJc3N1ZXIpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgYGFjY2VzcyB0b2tlbiBub3QgaXNzdWVkIGJ5IGNvcnJlY3QgcHJvdmlkZXIgLSBleHBlY3RlZDogJHtleHBlY3RlZElzc3Vlcn0gfCBmcm9tOiAke2p3dENsYWltcy5pc3N9YFxuICAgICk7XG4gIH1cblxuICBpZiAoand0Q2xhaW1zLmF6cCAhPT0gY29uZmlnWydjbGllbnQtaWQnXSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgYWNjZXNzIHRva2VuIGlzIG5vdCBhdXRob3JpemVkIGZvciB0aGlzIGNsaWVudCAtIGV4cGVjdGVkOiAke2NvbmZpZ1snY2xpZW50LWlkJ119IHwgZnJvbTogJHtqd3RDbGFpbXMuYXpwfWBcbiAgICApO1xuICB9XG5cbiAgaWYgKGp3dENsYWltcy5zdWIgIT09IGlkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdhdXRoIGRhdGEgaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9XG5cbiAgY29uc3Qgcm9sZXNNYXRjaCA9IGp3dENsYWltcy5yb2xlcyA9PT0gcm9sZXMgfHwgYXJyYXlzRXF1YWwoand0Q2xhaW1zLnJvbGVzLCByb2xlcyk7XG4gIGNvbnN0IGdyb3Vwc01hdGNoID0gand0Q2xhaW1zLmdyb3VwcyA9PT0gZ3JvdXBzIHx8IGFycmF5c0VxdWFsKGp3dENsYWltcy5ncm91cHMsIGdyb3Vwcyk7XG5cbiAgaWYgKCFyb2xlc01hdGNoIHx8ICFncm91cHNNYXRjaCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCBhdXRoZW50aWNhdGlvbicpO1xuICB9XG5cbiAgcmV0dXJuIGp3dENsYWltcztcbn07XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMgPSB7fSkge1xuICByZXR1cm4gdmVyaWZ5QWNjZXNzVG9rZW4oYXV0aERhdGEsIG9wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxNQUFNO0VBQUVBO0FBQU0sQ0FBQyxHQUFHQyxPQUFPLENBQUMsWUFBWSxDQUFDO0FBQ3ZDLE1BQU1DLFVBQVUsR0FBR0QsT0FBTyxDQUFDLFVBQVUsQ0FBQztBQUN0QyxNQUFNRSxHQUFHLEdBQUdGLE9BQU8sQ0FBQyxjQUFjLENBQUM7QUFDbkMsTUFBTUcsU0FBUyxHQUFHSCxPQUFPLENBQUMsU0FBUyxDQUFDO0FBRXBDLE1BQU1JLFdBQVcsR0FBR0EsQ0FBQ0MsS0FBSyxFQUFFQyxLQUFLLEtBQUs7RUFDcEMsSUFBSSxDQUFDQyxLQUFLLENBQUNDLE9BQU8sQ0FBQ0gsS0FBSyxDQUFDLElBQUksQ0FBQ0UsS0FBSyxDQUFDQyxPQUFPLENBQUNGLEtBQUssQ0FBQyxJQUFJRCxLQUFLLENBQUNJLE1BQU0sS0FBS0gsS0FBSyxDQUFDRyxNQUFNLEVBQUU7SUFBRSxPQUFPLEtBQUs7RUFBRTtFQUVyRyxJQUFJQyxJQUFJLEdBQUdMLEtBQUss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