@beiguancyc/parse-server 9.9.0-ruixiang.1

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.
Files changed (251) hide show
  1. package/LICENSE +176 -0
  2. package/NOTICE +10 -0
  3. package/README.md +1311 -0
  4. package/bin/parse-live-query-server +3 -0
  5. package/bin/parse-server +3 -0
  6. package/lib/AccountLockout.js +149 -0
  7. package/lib/Adapters/AdapterLoader.js +60 -0
  8. package/lib/Adapters/Analytics/AnalyticsAdapter.js +32 -0
  9. package/lib/Adapters/Auth/AuthAdapter.js +132 -0
  10. package/lib/Adapters/Auth/BaseCodeAuthAdapter.js +119 -0
  11. package/lib/Adapters/Auth/OAuth1Client.js +204 -0
  12. package/lib/Adapters/Auth/apple.js +125 -0
  13. package/lib/Adapters/Auth/facebook.js +187 -0
  14. package/lib/Adapters/Auth/gcenter.js +217 -0
  15. package/lib/Adapters/Auth/github.js +125 -0
  16. package/lib/Adapters/Auth/google.js +122 -0
  17. package/lib/Adapters/Auth/gpgames.js +125 -0
  18. package/lib/Adapters/Auth/httpsRequest.js +41 -0
  19. package/lib/Adapters/Auth/index.js +248 -0
  20. package/lib/Adapters/Auth/instagram.js +118 -0
  21. package/lib/Adapters/Auth/janraincapture.js +85 -0
  22. package/lib/Adapters/Auth/janrainengage.js +57 -0
  23. package/lib/Adapters/Auth/keycloak.js +168 -0
  24. package/lib/Adapters/Auth/ldap.js +193 -0
  25. package/lib/Adapters/Auth/line.js +125 -0
  26. package/lib/Adapters/Auth/linkedin.js +117 -0
  27. package/lib/Adapters/Auth/meetup.js +44 -0
  28. package/lib/Adapters/Auth/mfa.js +334 -0
  29. package/lib/Adapters/Auth/microsoft.js +111 -0
  30. package/lib/Adapters/Auth/oauth2.js +115 -0
  31. package/lib/Adapters/Auth/phantauth.js +53 -0
  32. package/lib/Adapters/Auth/qq.js +113 -0
  33. package/lib/Adapters/Auth/spotify.js +115 -0
  34. package/lib/Adapters/Auth/twitter.js +197 -0
  35. package/lib/Adapters/Auth/utils.js +28 -0
  36. package/lib/Adapters/Auth/vkontakte.js +55 -0
  37. package/lib/Adapters/Auth/wechat.js +110 -0
  38. package/lib/Adapters/Auth/weibo.js +141 -0
  39. package/lib/Adapters/Cache/CacheAdapter.js +40 -0
  40. package/lib/Adapters/Cache/InMemoryCache.js +61 -0
  41. package/lib/Adapters/Cache/InMemoryCacheAdapter.js +34 -0
  42. package/lib/Adapters/Cache/LRUCache.js +35 -0
  43. package/lib/Adapters/Cache/NullCacheAdapter.js +26 -0
  44. package/lib/Adapters/Cache/RedisCacheAdapter.js +109 -0
  45. package/lib/Adapters/Cache/SchemaCache.js +25 -0
  46. package/lib/Adapters/Email/MailAdapter.js +32 -0
  47. package/lib/Adapters/Files/FilesAdapter.js +129 -0
  48. package/lib/Adapters/Files/GridFSBucketAdapter.js +280 -0
  49. package/lib/Adapters/Files/GridStoreAdapter.js +5 -0
  50. package/lib/Adapters/Logger/LoggerAdapter.js +27 -0
  51. package/lib/Adapters/Logger/WinstonLogger.js +107 -0
  52. package/lib/Adapters/Logger/WinstonLoggerAdapter.js +63 -0
  53. package/lib/Adapters/MessageQueue/EventEmitterMQ.js +55 -0
  54. package/lib/Adapters/PubSub/EventEmitterPubSub.js +53 -0
  55. package/lib/Adapters/PubSub/PubSubAdapter.js +34 -0
  56. package/lib/Adapters/PubSub/RedisPubSub.js +49 -0
  57. package/lib/Adapters/Push/PushAdapter.js +40 -0
  58. package/lib/Adapters/Storage/Mongo/MongoCollection.js +212 -0
  59. package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +334 -0
  60. package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +1047 -0
  61. package/lib/Adapters/Storage/Mongo/MongoTransform.js +1397 -0
  62. package/lib/Adapters/Storage/Postgres/PostgresClient.js +38 -0
  63. package/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +73 -0
  64. package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +2409 -0
  65. package/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql +11 -0
  66. package/lib/Adapters/Storage/Postgres/sql/array/add.sql +11 -0
  67. package/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql +14 -0
  68. package/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql +14 -0
  69. package/lib/Adapters/Storage/Postgres/sql/array/contains.sql +11 -0
  70. package/lib/Adapters/Storage/Postgres/sql/array/remove.sql +11 -0
  71. package/lib/Adapters/Storage/Postgres/sql/index.js +32 -0
  72. package/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql +19 -0
  73. package/lib/Adapters/Storage/StorageAdapter.js +2 -0
  74. package/lib/Adapters/WebSocketServer/WSAdapter.js +35 -0
  75. package/lib/Adapters/WebSocketServer/WSSAdapter.js +66 -0
  76. package/lib/Auth.js +687 -0
  77. package/lib/AuthDataLock.js +53 -0
  78. package/lib/ClientSDK.js +39 -0
  79. package/lib/Config.js +879 -0
  80. package/lib/Controllers/AdaptableController.js +72 -0
  81. package/lib/Controllers/AnalyticsController.js +43 -0
  82. package/lib/Controllers/CacheController.js +71 -0
  83. package/lib/Controllers/DatabaseController.js +1685 -0
  84. package/lib/Controllers/FilesController.js +122 -0
  85. package/lib/Controllers/HooksController.js +254 -0
  86. package/lib/Controllers/LiveQueryController.js +72 -0
  87. package/lib/Controllers/LoggerController.js +222 -0
  88. package/lib/Controllers/ParseGraphQLController.js +294 -0
  89. package/lib/Controllers/PushController.js +224 -0
  90. package/lib/Controllers/SchemaController.js +1563 -0
  91. package/lib/Controllers/UserController.js +364 -0
  92. package/lib/Controllers/index.js +251 -0
  93. package/lib/Controllers/types.js +2 -0
  94. package/lib/Deprecator/Deprecations.js +100 -0
  95. package/lib/Deprecator/Deprecator.js +140 -0
  96. package/lib/Error.js +50 -0
  97. package/lib/FileUrlValidator.js +69 -0
  98. package/lib/GraphQL/ParseGraphQLSchema.js +375 -0
  99. package/lib/GraphQL/ParseGraphQLServer.js +241 -0
  100. package/lib/GraphQL/helpers/objectsMutations.js +30 -0
  101. package/lib/GraphQL/helpers/objectsQueries.js +246 -0
  102. package/lib/GraphQL/helpers/queryComplexity.js +138 -0
  103. package/lib/GraphQL/loaders/configMutations.js +87 -0
  104. package/lib/GraphQL/loaders/configQueries.js +79 -0
  105. package/lib/GraphQL/loaders/defaultGraphQLMutations.js +21 -0
  106. package/lib/GraphQL/loaders/defaultGraphQLQueries.js +23 -0
  107. package/lib/GraphQL/loaders/defaultGraphQLTypes.js +1099 -0
  108. package/lib/GraphQL/loaders/defaultRelaySchema.js +53 -0
  109. package/lib/GraphQL/loaders/filesMutations.js +107 -0
  110. package/lib/GraphQL/loaders/functionsMutations.js +77 -0
  111. package/lib/GraphQL/loaders/parseClassMutations.js +267 -0
  112. package/lib/GraphQL/loaders/parseClassQueries.js +126 -0
  113. package/lib/GraphQL/loaders/parseClassTypes.js +493 -0
  114. package/lib/GraphQL/loaders/schemaDirectives.js +62 -0
  115. package/lib/GraphQL/loaders/schemaMutations.js +161 -0
  116. package/lib/GraphQL/loaders/schemaQueries.js +80 -0
  117. package/lib/GraphQL/loaders/schemaTypes.js +341 -0
  118. package/lib/GraphQL/loaders/usersMutations.js +433 -0
  119. package/lib/GraphQL/loaders/usersQueries.js +90 -0
  120. package/lib/GraphQL/parseGraphQLUtils.js +71 -0
  121. package/lib/GraphQL/transformers/className.js +14 -0
  122. package/lib/GraphQL/transformers/constraintType.js +53 -0
  123. package/lib/GraphQL/transformers/inputType.js +51 -0
  124. package/lib/GraphQL/transformers/mutation.js +280 -0
  125. package/lib/GraphQL/transformers/outputType.js +51 -0
  126. package/lib/GraphQL/transformers/query.js +237 -0
  127. package/lib/GraphQL/transformers/schemaFields.js +99 -0
  128. package/lib/InstallationDedup.js +178 -0
  129. package/lib/KeyPromiseQueue.js +48 -0
  130. package/lib/LiveQuery/Client.js +90 -0
  131. package/lib/LiveQuery/Id.js +20 -0
  132. package/lib/LiveQuery/ParseCloudCodePublisher.js +54 -0
  133. package/lib/LiveQuery/ParseLiveQueryServer.js +1071 -0
  134. package/lib/LiveQuery/ParsePubSub.js +37 -0
  135. package/lib/LiveQuery/ParseWebSocketServer.js +66 -0
  136. package/lib/LiveQuery/QueryTools.js +443 -0
  137. package/lib/LiveQuery/RequestSchema.js +161 -0
  138. package/lib/LiveQuery/SessionTokenCache.js +51 -0
  139. package/lib/LiveQuery/Subscription.js +47 -0
  140. package/lib/LiveQuery/equalObjects.js +50 -0
  141. package/lib/Options/Definitions.js +1599 -0
  142. package/lib/Options/docs.js +389 -0
  143. package/lib/Options/index.js +12 -0
  144. package/lib/Options/parsers.js +89 -0
  145. package/lib/Page.js +44 -0
  146. package/lib/ParseMessageQueue.js +24 -0
  147. package/lib/ParseServer.js +632 -0
  148. package/lib/ParseServerRESTController.js +173 -0
  149. package/lib/PromiseRouter.js +208 -0
  150. package/lib/Push/PushQueue.js +67 -0
  151. package/lib/Push/PushWorker.js +101 -0
  152. package/lib/Push/utils.js +129 -0
  153. package/lib/RestQuery.js +1208 -0
  154. package/lib/RestWrite.js +1671 -0
  155. package/lib/Routers/AggregateRouter.js +150 -0
  156. package/lib/Routers/AnalyticsRouter.js +26 -0
  157. package/lib/Routers/AudiencesRouter.js +54 -0
  158. package/lib/Routers/ClassesRouter.js +191 -0
  159. package/lib/Routers/CloudCodeRouter.js +87 -0
  160. package/lib/Routers/FeaturesRouter.js +72 -0
  161. package/lib/Routers/FilesRouter.js +772 -0
  162. package/lib/Routers/FunctionsRouter.js +341 -0
  163. package/lib/Routers/GlobalConfigRouter.js +123 -0
  164. package/lib/Routers/GraphQLRouter.js +41 -0
  165. package/lib/Routers/HooksRouter.js +121 -0
  166. package/lib/Routers/IAPValidationRouter.js +113 -0
  167. package/lib/Routers/InstallationsRouter.js +46 -0
  168. package/lib/Routers/LogsRouter.js +57 -0
  169. package/lib/Routers/PagesRouter.js +676 -0
  170. package/lib/Routers/PurgeRouter.js +45 -0
  171. package/lib/Routers/PushRouter.js +75 -0
  172. package/lib/Routers/RolesRouter.js +33 -0
  173. package/lib/Routers/SchemasRouter.js +118 -0
  174. package/lib/Routers/SecurityRouter.js +34 -0
  175. package/lib/Routers/SessionsRouter.js +126 -0
  176. package/lib/Routers/UsersRouter.js +733 -0
  177. package/lib/SchemaMigrations/DefinedSchemas.js +379 -0
  178. package/lib/SchemaMigrations/Migrations.js +30 -0
  179. package/lib/Security/Check.js +109 -0
  180. package/lib/Security/CheckGroup.js +44 -0
  181. package/lib/Security/CheckGroups/CheckGroupDatabase.js +44 -0
  182. package/lib/Security/CheckGroups/CheckGroupServerConfig.js +160 -0
  183. package/lib/Security/CheckGroups/CheckGroups.js +21 -0
  184. package/lib/Security/CheckRunner.js +213 -0
  185. package/lib/SharedRest.js +34 -0
  186. package/lib/StatusHandler.js +329 -0
  187. package/lib/TestUtils.js +87 -0
  188. package/lib/Utils.js +577 -0
  189. package/lib/batch.js +185 -0
  190. package/lib/cache.js +12 -0
  191. package/lib/cli/definitions/parse-live-query-server.js +9 -0
  192. package/lib/cli/definitions/parse-server.js +9 -0
  193. package/lib/cli/parse-live-query-server.js +14 -0
  194. package/lib/cli/parse-server.js +101 -0
  195. package/lib/cli/utils/commander.js +132 -0
  196. package/lib/cli/utils/runner.js +53 -0
  197. package/lib/cloud-code/Parse.Cloud.js +797 -0
  198. package/lib/cloud-code/Parse.Server.js +21 -0
  199. package/lib/cryptoUtils.js +54 -0
  200. package/lib/defaults.js +58 -0
  201. package/lib/deprecated.js +12 -0
  202. package/lib/index.js +89 -0
  203. package/lib/logger.js +40 -0
  204. package/lib/middlewares.js +810 -0
  205. package/lib/password.js +40 -0
  206. package/lib/request.js +175 -0
  207. package/lib/requiredParameter.js +11 -0
  208. package/lib/rest.js +264 -0
  209. package/lib/triggers.js +949 -0
  210. package/lib/vendor/README.md +8 -0
  211. package/lib/vendor/mongodbUrl.js +1012 -0
  212. package/package.json +172 -0
  213. package/postinstall.js +38 -0
  214. package/public/custom_json.html +17 -0
  215. package/public/custom_json.json +23 -0
  216. package/public/custom_page.html +15 -0
  217. package/public/de/email_verification_link_expired.html +24 -0
  218. package/public/de/email_verification_link_invalid.html +21 -0
  219. package/public/de/email_verification_send_fail.html +21 -0
  220. package/public/de/email_verification_send_success.html +19 -0
  221. package/public/de/email_verification_success.html +18 -0
  222. package/public/de/password_reset.html +65 -0
  223. package/public/de/password_reset_link_invalid.html +19 -0
  224. package/public/de/password_reset_success.html +18 -0
  225. package/public/de-AT/email_verification_link_expired.html +24 -0
  226. package/public/de-AT/email_verification_link_invalid.html +21 -0
  227. package/public/de-AT/email_verification_send_fail.html +21 -0
  228. package/public/de-AT/email_verification_send_success.html +19 -0
  229. package/public/de-AT/email_verification_success.html +18 -0
  230. package/public/de-AT/password_reset.html +65 -0
  231. package/public/de-AT/password_reset_link_invalid.html +19 -0
  232. package/public/de-AT/password_reset_success.html +18 -0
  233. package/public/email_verification_link_expired.html +24 -0
  234. package/public/email_verification_link_invalid.html +21 -0
  235. package/public/email_verification_send_fail.html +21 -0
  236. package/public/email_verification_send_success.html +19 -0
  237. package/public/email_verification_success.html +18 -0
  238. package/public/password_reset.html +65 -0
  239. package/public/password_reset_link_invalid.html +19 -0
  240. package/public/password_reset_success.html +18 -0
  241. package/types/@types/@parse/fs-files-adapter/index.d.ts +5 -0
  242. package/types/@types/deepcopy/index.d.ts +5 -0
  243. package/types/LiveQuery/ParseLiveQueryServer.d.ts +40 -0
  244. package/types/Options/index.d.ts +320 -0
  245. package/types/ParseServer.d.ts +65 -0
  246. package/types/eslint.config.mjs +30 -0
  247. package/types/index.d.ts +21 -0
  248. package/types/logger.d.ts +2 -0
  249. package/types/tests.ts +44 -0
  250. package/types/tsconfig.json +24 -0
  251. package/views/choose_password +215 -0
@@ -0,0 +1,364 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.UserController = void 0;
7
+ var _cryptoUtils = require("../cryptoUtils");
8
+ var _triggers = require("../triggers");
9
+ var _AdaptableController = _interopRequireDefault(require("./AdaptableController"));
10
+ var _MailAdapter = _interopRequireDefault(require("../Adapters/Email/MailAdapter"));
11
+ var _rest = _interopRequireDefault(require("../rest"));
12
+ var _node = _interopRequireDefault(require("parse/node"));
13
+ var _AccountLockout = _interopRequireDefault(require("../AccountLockout"));
14
+ var _Config = _interopRequireDefault(require("../Config"));
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
+ var RestQuery = require('../RestQuery');
17
+ var Auth = require('../Auth');
18
+ class UserController extends _AdaptableController.default {
19
+ constructor(adapter, appId, options = {}) {
20
+ super(adapter, appId, options);
21
+ }
22
+ get config() {
23
+ return _Config.default.get(this.appId);
24
+ }
25
+ validateAdapter(adapter) {
26
+ // Allow no adapter
27
+ if (!adapter && !this.shouldVerifyEmails) {
28
+ return;
29
+ }
30
+ super.validateAdapter(adapter);
31
+ }
32
+ expectedAdapterType() {
33
+ return _MailAdapter.default;
34
+ }
35
+ get shouldVerifyEmails() {
36
+ return (this.config || this.options).verifyUserEmails;
37
+ }
38
+ async setEmailVerifyToken(user, req, storage = {}) {
39
+ const shouldSendEmail = this.shouldVerifyEmails === true || typeof this.shouldVerifyEmails === 'function' && (await Promise.resolve(this.shouldVerifyEmails(req))) === true;
40
+ if (!shouldSendEmail) {
41
+ return false;
42
+ }
43
+ storage.sendVerificationEmail = true;
44
+ user._email_verify_token = (0, _cryptoUtils.randomString)(25);
45
+ if (!storage.fieldsChangedByTrigger || !storage.fieldsChangedByTrigger.includes('emailVerified')) {
46
+ user.emailVerified = false;
47
+ }
48
+ if (this.config.emailVerifyTokenValidityDuration) {
49
+ user._email_verify_token_expires_at = _node.default._encode(this.config.generateEmailVerifyTokenExpiresAt());
50
+ }
51
+ return true;
52
+ }
53
+ async verifyEmail(token) {
54
+ if (!this.shouldVerifyEmails) {
55
+ // Trying to verify email when not enabled
56
+ // TODO: Better error here.
57
+ throw undefined;
58
+ }
59
+ const query = {
60
+ _email_verify_token: token
61
+ };
62
+ const updateFields = {
63
+ emailVerified: true,
64
+ _email_verify_token: {
65
+ __op: 'Delete'
66
+ }
67
+ };
68
+
69
+ // if the email verify token needs to be validated then
70
+ // add additional query params and additional fields that need to be updated
71
+ if (this.config.emailVerifyTokenValidityDuration) {
72
+ query.emailVerified = false;
73
+ query._email_verify_token_expires_at = {
74
+ $gt: _node.default._encode(new Date())
75
+ };
76
+ updateFields._email_verify_token_expires_at = {
77
+ __op: 'Delete'
78
+ };
79
+ }
80
+ const maintenanceAuth = Auth.maintenance(this.config);
81
+ const restQuery = await RestQuery({
82
+ method: RestQuery.Method.get,
83
+ config: this.config,
84
+ auth: maintenanceAuth,
85
+ className: '_User',
86
+ restWhere: query
87
+ });
88
+ const result = await restQuery.execute();
89
+ if (result.results.length) {
90
+ query.objectId = result.results[0].objectId;
91
+ }
92
+ return await _rest.default.update(this.config, maintenanceAuth, '_User', query, updateFields);
93
+ }
94
+ async checkResetTokenValidity(token) {
95
+ const results = await this.config.database.find('_User', {
96
+ _perishable_token: token
97
+ }, {
98
+ limit: 1
99
+ }, Auth.maintenance(this.config));
100
+ if (results.length !== 1) {
101
+ throw 'Failed to reset password: username / email / token is invalid';
102
+ }
103
+ if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) {
104
+ let expiresDate = results[0]._perishable_token_expires_at;
105
+ if (expiresDate && expiresDate.__type == 'Date') {
106
+ expiresDate = new Date(expiresDate.iso);
107
+ }
108
+ if (expiresDate < new Date()) {
109
+ throw 'The password reset link has expired';
110
+ }
111
+ }
112
+ return results[0];
113
+ }
114
+ async getUserIfNeeded(user) {
115
+ var where = {};
116
+ if (user.username) {
117
+ where.username = user.username;
118
+ }
119
+ if (user.email) {
120
+ where.email = user.email;
121
+ }
122
+ if (user._email_verify_token) {
123
+ where._email_verify_token = user._email_verify_token;
124
+ }
125
+ var query = await RestQuery({
126
+ method: RestQuery.Method.get,
127
+ config: this.config,
128
+ runBeforeFind: false,
129
+ auth: Auth.master(this.config),
130
+ className: '_User',
131
+ restWhere: where
132
+ });
133
+ const result = await query.execute();
134
+ if (result.results.length != 1) {
135
+ throw undefined;
136
+ }
137
+ return result.results[0];
138
+ }
139
+ async sendVerificationEmail(user, req) {
140
+ if (!this.shouldVerifyEmails) {
141
+ return;
142
+ }
143
+ const token = encodeURIComponent(user._email_verify_token);
144
+ // We may need to fetch the user in case of update email; only use the `fetchedUser`
145
+ // from this point onwards; do not use the `user` as it may not contain all fields.
146
+ const fetchedUser = await this.getUserIfNeeded(user);
147
+ let shouldSendEmail = this.config.sendUserEmailVerification;
148
+ if (typeof shouldSendEmail === 'function') {
149
+ const response = await Promise.resolve(this.config.sendUserEmailVerification({
150
+ user: _node.default.Object.fromJSON({
151
+ className: '_User',
152
+ ...fetchedUser
153
+ }),
154
+ master: req.auth?.isMaster
155
+ }));
156
+ shouldSendEmail = !!response;
157
+ }
158
+ if (!shouldSendEmail) {
159
+ return;
160
+ }
161
+ const link = buildEmailLink(this.config.verifyEmailURL, token, this.config);
162
+ const options = {
163
+ appName: this.config.appName,
164
+ link: link,
165
+ user: (0, _triggers.inflate)('_User', fetchedUser)
166
+ };
167
+ if (this.adapter.sendVerificationEmail) {
168
+ this.adapter.sendVerificationEmail(options);
169
+ } else {
170
+ this.adapter.sendMail(this.defaultVerificationEmail(options));
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Regenerates the given user's email verification token
176
+ *
177
+ * @param user
178
+ * @returns {*}
179
+ */
180
+ async regenerateEmailVerifyToken(user, master, installationId, ip) {
181
+ const {
182
+ _email_verify_token
183
+ } = user;
184
+ let {
185
+ _email_verify_token_expires_at
186
+ } = user;
187
+ if (_email_verify_token_expires_at && _email_verify_token_expires_at.__type === 'Date') {
188
+ _email_verify_token_expires_at = _email_verify_token_expires_at.iso;
189
+ }
190
+ if (this.config.emailVerifyTokenReuseIfValid && this.config.emailVerifyTokenValidityDuration && _email_verify_token && new Date() < new Date(_email_verify_token_expires_at)) {
191
+ return Promise.resolve(true);
192
+ }
193
+ const shouldSend = await this.setEmailVerifyToken(user, {
194
+ object: _node.default.User.fromJSON(Object.assign({
195
+ className: '_User'
196
+ }, user)),
197
+ master,
198
+ installationId,
199
+ ip,
200
+ resendRequest: true
201
+ });
202
+ if (!shouldSend) {
203
+ return;
204
+ }
205
+ return this.config.database.update('_User', {
206
+ username: user.username
207
+ }, user);
208
+ }
209
+ async resendVerificationEmail(username, req, token) {
210
+ const aUser = await this.getUserIfNeeded({
211
+ username,
212
+ _email_verify_token: token
213
+ });
214
+ if (!aUser || aUser.emailVerified) {
215
+ throw undefined;
216
+ }
217
+ const generate = await this.regenerateEmailVerifyToken(aUser, req.auth?.isMaster, req.auth?.installationId, req.ip);
218
+ if (generate) {
219
+ this.sendVerificationEmail(aUser, req);
220
+ }
221
+ }
222
+ setPasswordResetToken(email) {
223
+ const token = {
224
+ _perishable_token: (0, _cryptoUtils.randomString)(25)
225
+ };
226
+ if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) {
227
+ token._perishable_token_expires_at = _node.default._encode(this.config.generatePasswordResetTokenExpiresAt());
228
+ }
229
+ return this.config.database.update('_User', {
230
+ $or: [{
231
+ email
232
+ }, {
233
+ username: email,
234
+ email: {
235
+ $exists: false
236
+ }
237
+ }]
238
+ }, token, {}, true);
239
+ }
240
+ async sendPasswordResetEmail(email) {
241
+ if (!this.adapter) {
242
+ throw 'Trying to send a reset password but no adapter is set';
243
+ // TODO: No adapter?
244
+ }
245
+ let user;
246
+ if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenReuseIfValid && this.config.passwordPolicy.resetTokenValidityDuration) {
247
+ const results = await this.config.database.find('_User', {
248
+ $or: [{
249
+ email,
250
+ _perishable_token: {
251
+ $exists: true
252
+ }
253
+ }, {
254
+ username: email,
255
+ email: {
256
+ $exists: false
257
+ },
258
+ _perishable_token: {
259
+ $exists: true
260
+ }
261
+ }]
262
+ }, {
263
+ limit: 1
264
+ }, Auth.maintenance(this.config));
265
+ if (results.length == 1) {
266
+ let expiresDate = results[0]._perishable_token_expires_at;
267
+ if (expiresDate && expiresDate.__type == 'Date') {
268
+ expiresDate = new Date(expiresDate.iso);
269
+ }
270
+ if (expiresDate > new Date()) {
271
+ user = results[0];
272
+ }
273
+ }
274
+ }
275
+ if (!user || !user._perishable_token) {
276
+ user = await this.setPasswordResetToken(email);
277
+ }
278
+ const token = encodeURIComponent(user._perishable_token);
279
+ const link = buildEmailLink(this.config.requestResetPasswordURL, token, this.config);
280
+ const options = {
281
+ appName: this.config.appName,
282
+ link: link,
283
+ user: (0, _triggers.inflate)('_User', user)
284
+ };
285
+ if (this.adapter.sendPasswordResetEmail) {
286
+ this.adapter.sendPasswordResetEmail(options);
287
+ } else {
288
+ this.adapter.sendMail(this.defaultResetPasswordEmail(options));
289
+ }
290
+ return Promise.resolve(user);
291
+ }
292
+ async updatePassword(token, password) {
293
+ try {
294
+ const rawUser = await this.checkResetTokenValidity(token);
295
+ let user;
296
+ try {
297
+ user = await updateUserPassword(rawUser, password, this.config);
298
+ } catch (error) {
299
+ if (error && error.code === _node.default.Error.OBJECT_NOT_FOUND) {
300
+ throw 'Failed to reset password: username / email / token is invalid';
301
+ }
302
+ throw error;
303
+ }
304
+ const accountLockoutPolicy = new _AccountLockout.default(user, this.config);
305
+ return await accountLockoutPolicy.unlockAccount();
306
+ } catch (error) {
307
+ if (error && error.message) {
308
+ // in case of Parse.Error, fail with the error message only
309
+ return Promise.reject(error.message);
310
+ }
311
+ return Promise.reject(error);
312
+ }
313
+ }
314
+ defaultVerificationEmail({
315
+ link,
316
+ user,
317
+ appName
318
+ }) {
319
+ const text = 'Hi,\n\n' + 'You are being asked to confirm the e-mail address ' + user.get('email') + ' with ' + appName + '\n\n' + '' + 'Click here to confirm it:\n' + link;
320
+ const to = user.get('email');
321
+ const subject = 'Please verify your e-mail for ' + appName;
322
+ return {
323
+ text,
324
+ to,
325
+ subject
326
+ };
327
+ }
328
+ defaultResetPasswordEmail({
329
+ link,
330
+ user,
331
+ appName
332
+ }) {
333
+ const text = 'Hi,\n\n' + 'You requested to reset your password for ' + appName + (user.get('username') ? " (your username is '" + user.get('username') + "')" : '') + '.\n\n' + '' + 'Click here to reset it:\n' + link;
334
+ const to = user.get('email') || user.get('username');
335
+ const subject = 'Password Reset for ' + appName;
336
+ return {
337
+ text,
338
+ to,
339
+ subject
340
+ };
341
+ }
342
+ }
343
+
344
+ // Mark this private
345
+ exports.UserController = UserController;
346
+ function updateUserPassword(user, password, config) {
347
+ return _rest.default.update(config, Auth.master(config), '_User', {
348
+ objectId: user.objectId,
349
+ _perishable_token: user._perishable_token
350
+ }, {
351
+ password: password
352
+ }).then(() => user);
353
+ }
354
+ function buildEmailLink(destination, token, config) {
355
+ token = `token=${token}`;
356
+ if (config.parseFrameURL) {
357
+ const destinationWithoutHost = destination.replace(config.publicServerURL, '');
358
+ return `${config.parseFrameURL}?link=${encodeURIComponent(destinationWithoutHost)}&${token}`;
359
+ } else {
360
+ return `${destination}?${token}`;
361
+ }
362
+ }
363
+ var _default = exports.default = UserController;
364
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY3J5cHRvVXRpbHMiLCJyZXF1aXJlIiwiX3RyaWdnZXJzIiwiX0FkYXB0YWJsZUNvbnRyb2xsZXIiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX01haWxBZGFwdGVyIiwiX3Jlc3QiLCJfbm9kZSIsIl9BY2NvdW50TG9ja291dCIsIl9Db25maWciLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJSZXN0UXVlcnkiLCJBdXRoIiwiVXNlckNvbnRyb2xsZXIiLCJBZGFwdGFibGVDb250cm9sbGVyIiwiY29uc3RydWN0b3IiLCJhZGFwdGVyIiwiYXBwSWQiLCJvcHRpb25zIiwiY29uZmlnIiwiQ29uZmlnIiwiZ2V0IiwidmFsaWRhdGVBZGFwdGVyIiwic2hvdWxkVmVyaWZ5RW1haWxzIiwiZXhwZWN0ZWRBZGFwdGVyVHlwZSIsIk1haWxBZGFwdGVyIiwidmVyaWZ5VXNlckVtYWlscyIsInNldEVtYWlsVmVyaWZ5VG9rZW4iLCJ1c2VyIiwicmVxIiwic3RvcmFnZSIsInNob3VsZFNlbmRFbWFpbCIsIlByb21pc2UiLCJyZXNvbHZlIiwic2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwiX2VtYWlsX3ZlcmlmeV90b2tlbiIsInJhbmRvbVN0cmluZyIsImZpZWxkc0NoYW5nZWRCeVRyaWdnZXIiLCJpbmNsdWRlcyIsImVtYWlsVmVyaWZpZWQiLCJlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbiIsIl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCIsIlBhcnNlIiwiX2VuY29kZSIsImdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdCIsInZlcmlmeUVtYWlsIiwidG9rZW4iLCJ1bmRlZmluZWQiLCJxdWVyeSIsInVwZGF0ZUZpZWxkcyIsIl9fb3AiLCIkZ3QiLCJEYXRlIiwibWFpbnRlbmFuY2VBdXRoIiwibWFpbnRlbmFuY2UiLCJyZXN0UXVlcnkiLCJtZXRob2QiLCJNZXRob2QiLCJhdXRoIiwiY2xhc3NOYW1lIiwicmVzdFdoZXJlIiwicmVzdWx0IiwiZXhlY3V0ZSIsInJlc3VsdHMiLCJsZW5ndGgiLCJvYmplY3RJZCIsInJlc3QiLCJ1cGRhdGUiLCJjaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSIsImRhdGFiYXNlIiwiZmluZCIsIl9wZXJpc2hhYmxlX3Rva2VuIiwibGltaXQiLCJwYXNzd29yZFBvbGljeSIsInJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwiZXhwaXJlc0RhdGUiLCJfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0IiwiX190eXBlIiwiaXNvIiwiZ2V0VXNlcklmTmVlZGVkIiwid2hlcmUiLCJ1c2VybmFtZSIsImVtYWlsIiwicnVuQmVmb3JlRmluZCIsIm1hc3RlciIsImVuY29kZVVSSUNvbXBvbmVudCIsImZldGNoZWRVc2VyIiwic2VuZFVzZXJFbWFpbFZlcmlmaWNhdGlvbiIsInJlc3BvbnNlIiwiT2JqZWN0IiwiZnJvbUpTT04iLCJpc01hc3RlciIsImxpbmsiLCJidWlsZEVtYWlsTGluayIsInZlcmlmeUVtYWlsVVJMIiwiYXBwTmFtZSIsImluZmxhdGUiLCJzZW5kTWFpbCIsImRlZmF1bHRWZXJpZmljYXRpb25FbWFpbCIsInJlZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuIiwiaW5zdGFsbGF0aW9uSWQiLCJpcCIsImVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQiLCJzaG91bGRTZW5kIiwib2JqZWN0IiwiVXNlciIsImFzc2lnbiIsInJlc2VuZFJlcXVlc3QiLCJyZXNlbmRWZXJpZmljYXRpb25FbWFpbCIsImFVc2VyIiwiZ2VuZXJhdGUiLCJzZXRQYXNzd29yZFJlc2V0VG9rZW4iLCJnZW5lcmF0ZVBhc3N3b3JkUmVzZXRUb2tlbkV4cGlyZXNBdCIsIiRvciIsIiRleGlzdHMiLCJzZW5kUGFzc3dvcmRSZXNldEVtYWlsIiwicmVzZXRUb2tlblJldXNlSWZWYWxpZCIsInJlcXVlc3RSZXNldFBhc3N3b3JkVVJMIiwiZGVmYXVsdFJlc2V0UGFzc3dvcmRFbWFpbCIsInVwZGF0ZVBhc3N3b3JkIiwicGFzc3dvcmQiLCJyYXdVc2VyIiwidXBkYXRlVXNlclBhc3N3b3JkIiwiZXJyb3IiLCJjb2RlIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiYWNjb3VudExvY2tvdXRQb2xpY3kiLCJBY2NvdW50TG9ja291dCIsInVubG9ja0FjY291bnQiLCJtZXNzYWdlIiwicmVqZWN0IiwidGV4dCIsInRvIiwic3ViamVjdCIsImV4cG9ydHMiLCJ0aGVuIiwiZGVzdGluYXRpb24iLCJwYXJzZUZyYW1lVVJMIiwiZGVzdGluYXRpb25XaXRob3V0SG9zdCIsInJlcGxhY2UiLCJwdWJsaWNTZXJ2ZXJVUkwiLCJfZGVmYXVsdCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Vc2VyQ29udHJvbGxlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByYW5kb21TdHJpbmcgfSBmcm9tICcuLi9jcnlwdG9VdGlscyc7XG5pbXBvcnQgeyBpbmZsYXRlIH0gZnJvbSAnLi4vdHJpZ2dlcnMnO1xuaW1wb3J0IEFkYXB0YWJsZUNvbnRyb2xsZXIgZnJvbSAnLi9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCBNYWlsQWRhcHRlciBmcm9tICcuLi9BZGFwdGVycy9FbWFpbC9NYWlsQWRhcHRlcic7XG5pbXBvcnQgcmVzdCBmcm9tICcuLi9yZXN0JztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBBY2NvdW50TG9ja291dCBmcm9tICcuLi9BY2NvdW50TG9ja291dCc7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5cbnZhciBSZXN0UXVlcnkgPSByZXF1aXJlKCcuLi9SZXN0UXVlcnknKTtcbnZhciBBdXRoID0gcmVxdWlyZSgnLi4vQXV0aCcpO1xuXG5leHBvcnQgY2xhc3MgVXNlckNvbnRyb2xsZXIgZXh0ZW5kcyBBZGFwdGFibGVDb250cm9sbGVyIHtcbiAgY29uc3RydWN0b3IoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMgPSB7fSkge1xuICAgIHN1cGVyKGFkYXB0ZXIsIGFwcElkLCBvcHRpb25zKTtcbiAgfVxuXG4gIGdldCBjb25maWcoKSB7XG4gICAgcmV0dXJuIENvbmZpZy5nZXQodGhpcy5hcHBJZCk7XG4gIH1cblxuICB2YWxpZGF0ZUFkYXB0ZXIoYWRhcHRlcikge1xuICAgIC8vIEFsbG93IG5vIGFkYXB0ZXJcbiAgICBpZiAoIWFkYXB0ZXIgJiYgIXRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHN1cGVyLnZhbGlkYXRlQWRhcHRlcihhZGFwdGVyKTtcbiAgfVxuXG4gIGV4cGVjdGVkQWRhcHRlclR5cGUoKSB7XG4gICAgcmV0dXJuIE1haWxBZGFwdGVyO1xuICB9XG5cbiAgZ2V0IHNob3VsZFZlcmlmeUVtYWlscygpIHtcbiAgICByZXR1cm4gKHRoaXMuY29uZmlnIHx8IHRoaXMub3B0aW9ucykudmVyaWZ5VXNlckVtYWlscztcbiAgfVxuXG4gIGFzeW5jIHNldEVtYWlsVmVyaWZ5VG9rZW4odXNlciwgcmVxLCBzdG9yYWdlID0ge30pIHtcbiAgICBjb25zdCBzaG91bGRTZW5kRW1haWwgPVxuICAgICAgdGhpcy5zaG91bGRWZXJpZnlFbWFpbHMgPT09IHRydWUgfHxcbiAgICAgICh0eXBlb2YgdGhpcy5zaG91bGRWZXJpZnlFbWFpbHMgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgICAgKGF3YWl0IFByb21pc2UucmVzb2x2ZSh0aGlzLnNob3VsZFZlcmlmeUVtYWlscyhyZXEpKSkgPT09IHRydWUpO1xuICAgIGlmICghc2hvdWxkU2VuZEVtYWlsKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHN0b3JhZ2Uuc2VuZFZlcmlmaWNhdGlvbkVtYWlsID0gdHJ1ZTtcbiAgICB1c2VyLl9lbWFpbF92ZXJpZnlfdG9rZW4gPSByYW5kb21TdHJpbmcoMjUpO1xuICAgIGlmIChcbiAgICAgICFzdG9yYWdlLmZpZWxkc0NoYW5nZWRCeVRyaWdnZXIgfHxcbiAgICAgICFzdG9yYWdlLmZpZWxkc0NoYW5nZWRCeVRyaWdnZXIuaW5jbHVkZXMoJ2VtYWlsVmVyaWZpZWQnKVxuICAgICkge1xuICAgICAgdXNlci5lbWFpbFZlcmlmaWVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnLmVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICB1c2VyLl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCA9IFBhcnNlLl9lbmNvZGUoXG4gICAgICAgIHRoaXMuY29uZmlnLmdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdCgpXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGFzeW5jIHZlcmlmeUVtYWlsKHRva2VuKSB7XG4gICAgaWYgKCF0aGlzLnNob3VsZFZlcmlmeUVtYWlscykge1xuICAgICAgLy8gVHJ5aW5nIHRvIHZlcmlmeSBlbWFpbCB3aGVuIG5vdCBlbmFibGVkXG4gICAgICAvLyBUT0RPOiBCZXR0ZXIgZXJyb3IgaGVyZS5cbiAgICAgIHRocm93IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBxdWVyeSA9IHsgX2VtYWlsX3ZlcmlmeV90b2tlbjogdG9rZW4gfTtcbiAgICBjb25zdCB1cGRhdGVGaWVsZHMgPSB7XG4gICAgICBlbWFpbFZlcmlmaWVkOiB0cnVlLFxuICAgICAgX2VtYWlsX3ZlcmlmeV90b2tlbjogeyBfX29wOiAnRGVsZXRlJyB9LFxuICAgIH07XG5cbiAgICAvLyBpZiB0aGUgZW1haWwgdmVyaWZ5IHRva2VuIG5lZWRzIHRvIGJlIHZhbGlkYXRlZCB0aGVuXG4gICAgLy8gYWRkIGFkZGl0aW9uYWwgcXVlcnkgcGFyYW1zIGFuZCBhZGRpdGlvbmFsIGZpZWxkcyB0aGF0IG5lZWQgdG8gYmUgdXBkYXRlZFxuICAgIGlmICh0aGlzLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgcXVlcnkuZW1haWxWZXJpZmllZCA9IGZhbHNlO1xuICAgICAgcXVlcnkuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0geyAkZ3Q6IFBhcnNlLl9lbmNvZGUobmV3IERhdGUoKSkgfTtcblxuICAgICAgdXBkYXRlRmllbGRzLl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCA9IHsgX19vcDogJ0RlbGV0ZScgfTtcbiAgICB9XG4gICAgY29uc3QgbWFpbnRlbmFuY2VBdXRoID0gQXV0aC5tYWludGVuYW5jZSh0aGlzLmNvbmZpZyk7XG4gICAgY29uc3QgcmVzdFF1ZXJ5ID0gYXdhaXQgUmVzdFF1ZXJ5KHtcbiAgICAgIG1ldGhvZDogUmVzdFF1ZXJ5Lk1ldGhvZC5nZXQsXG4gICAgICBjb25maWc6IHRoaXMuY29uZmlnLFxuICAgICAgYXV0aDogbWFpbnRlbmFuY2VBdXRoLFxuICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgcmVzdFdoZXJlOiBxdWVyeSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3RRdWVyeS5leGVjdXRlKCk7XG4gICAgaWYgKHJlc3VsdC5yZXN1bHRzLmxlbmd0aCkge1xuICAgICAgcXVlcnkub2JqZWN0SWQgPSByZXN1bHQucmVzdWx0c1swXS5vYmplY3RJZDtcbiAgICB9XG4gICAgcmV0dXJuIGF3YWl0IHJlc3QudXBkYXRlKHRoaXMuY29uZmlnLCBtYWludGVuYW5jZUF1dGgsICdfVXNlcicsIHF1ZXJ5LCB1cGRhdGVGaWVsZHMpO1xuICB9XG5cbiAgYXN5bmMgY2hlY2tSZXNldFRva2VuVmFsaWRpdHkodG9rZW4pIHtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZChcbiAgICAgICdfVXNlcicsXG4gICAgICB7XG4gICAgICAgIF9wZXJpc2hhYmxlX3Rva2VuOiB0b2tlbixcbiAgICAgIH0sXG4gICAgICB7IGxpbWl0OiAxIH0sXG4gICAgICBBdXRoLm1haW50ZW5hbmNlKHRoaXMuY29uZmlnKVxuICAgICk7XG4gICAgaWYgKHJlc3VsdHMubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyAnRmFpbGVkIHRvIHJlc2V0IHBhc3N3b3JkOiB1c2VybmFtZSAvIGVtYWlsIC8gdG9rZW4gaXMgaW52YWxpZCc7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICBsZXQgZXhwaXJlc0RhdGUgPSByZXN1bHRzWzBdLl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQ7XG4gICAgICBpZiAoZXhwaXJlc0RhdGUgJiYgZXhwaXJlc0RhdGUuX190eXBlID09ICdEYXRlJykge1xuICAgICAgICBleHBpcmVzRGF0ZSA9IG5ldyBEYXRlKGV4cGlyZXNEYXRlLmlzbyk7XG4gICAgICB9XG4gICAgICBpZiAoZXhwaXJlc0RhdGUgPCBuZXcgRGF0ZSgpKSB7XG4gICAgICAgIHRocm93ICdUaGUgcGFzc3dvcmQgcmVzZXQgbGluayBoYXMgZXhwaXJlZCc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdHNbMF07XG4gIH1cblxuICBhc3luYyBnZXRVc2VySWZOZWVkZWQodXNlcikge1xuICAgIHZhciB3aGVyZSA9IHt9O1xuICAgIGlmICh1c2VyLnVzZXJuYW1lKSB7XG4gICAgICB3aGVyZS51c2VybmFtZSA9IHVzZXIudXNlcm5hbWU7XG4gICAgfVxuICAgIGlmICh1c2VyLmVtYWlsKSB7XG4gICAgICB3aGVyZS5lbWFpbCA9IHVzZXIuZW1haWw7XG4gICAgfVxuICAgIGlmICh1c2VyLl9lbWFpbF92ZXJpZnlfdG9rZW4pIHtcbiAgICAgIHdoZXJlLl9lbWFpbF92ZXJpZnlfdG9rZW4gPSB1c2VyLl9lbWFpbF92ZXJpZnlfdG9rZW47XG4gICAgfVxuXG4gICAgdmFyIHF1ZXJ5ID0gYXdhaXQgUmVzdFF1ZXJ5KHtcbiAgICAgIG1ldGhvZDogUmVzdFF1ZXJ5Lk1ldGhvZC5nZXQsXG4gICAgICBjb25maWc6IHRoaXMuY29uZmlnLFxuICAgICAgcnVuQmVmb3JlRmluZDogZmFsc2UsXG4gICAgICBhdXRoOiBBdXRoLm1hc3Rlcih0aGlzLmNvbmZpZyksXG4gICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICByZXN0V2hlcmU6IHdoZXJlLFxuICAgIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHF1ZXJ5LmV4ZWN1dGUoKTtcbiAgICBpZiAocmVzdWx0LnJlc3VsdHMubGVuZ3RoICE9IDEpIHtcbiAgICAgIHRocm93IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdC5yZXN1bHRzWzBdO1xuICB9XG5cbiAgYXN5bmMgc2VuZFZlcmlmaWNhdGlvbkVtYWlsKHVzZXIsIHJlcSkge1xuICAgIGlmICghdGhpcy5zaG91bGRWZXJpZnlFbWFpbHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdG9rZW4gPSBlbmNvZGVVUklDb21wb25lbnQodXNlci5fZW1haWxfdmVyaWZ5X3Rva2VuKTtcbiAgICAvLyBXZSBtYXkgbmVlZCB0byBmZXRjaCB0aGUgdXNlciBpbiBjYXNlIG9mIHVwZGF0ZSBlbWFpbDsgb25seSB1c2UgdGhlIGBmZXRjaGVkVXNlcmBcbiAgICAvLyBmcm9tIHRoaXMgcG9pbnQgb253YXJkczsgZG8gbm90IHVzZSB0aGUgYHVzZXJgIGFzIGl0IG1heSBub3QgY29udGFpbiBhbGwgZmllbGRzLlxuICAgIGNvbnN0IGZldGNoZWRVc2VyID0gYXdhaXQgdGhpcy5nZXRVc2VySWZOZWVkZWQodXNlcik7XG4gICAgbGV0IHNob3VsZFNlbmRFbWFpbCA9IHRoaXMuY29uZmlnLnNlbmRVc2VyRW1haWxWZXJpZmljYXRpb247XG4gICAgaWYgKHR5cGVvZiBzaG91bGRTZW5kRW1haWwgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICB0aGlzLmNvbmZpZy5zZW5kVXNlckVtYWlsVmVyaWZpY2F0aW9uKHtcbiAgICAgICAgICB1c2VyOiBQYXJzZS5PYmplY3QuZnJvbUpTT04oeyBjbGFzc05hbWU6ICdfVXNlcicsIC4uLmZldGNoZWRVc2VyIH0pLFxuICAgICAgICAgIG1hc3RlcjogcmVxLmF1dGg/LmlzTWFzdGVyLFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIHNob3VsZFNlbmRFbWFpbCA9ICEhcmVzcG9uc2U7XG4gICAgfVxuICAgIGlmICghc2hvdWxkU2VuZEVtYWlsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGxpbmsgPSBidWlsZEVtYWlsTGluayh0aGlzLmNvbmZpZy52ZXJpZnlFbWFpbFVSTCwgdG9rZW4sIHRoaXMuY29uZmlnKTtcbiAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgYXBwTmFtZTogdGhpcy5jb25maWcuYXBwTmFtZSxcbiAgICAgIGxpbms6IGxpbmssXG4gICAgICB1c2VyOiBpbmZsYXRlKCdfVXNlcicsIGZldGNoZWRVc2VyKSxcbiAgICB9O1xuICAgIGlmICh0aGlzLmFkYXB0ZXIuc2VuZFZlcmlmaWNhdGlvbkVtYWlsKSB7XG4gICAgICB0aGlzLmFkYXB0ZXIuc2VuZFZlcmlmaWNhdGlvbkVtYWlsKG9wdGlvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFkYXB0ZXIuc2VuZE1haWwodGhpcy5kZWZhdWx0VmVyaWZpY2F0aW9uRW1haWwob3B0aW9ucykpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdlbmVyYXRlcyB0aGUgZ2l2ZW4gdXNlcidzIGVtYWlsIHZlcmlmaWNhdGlvbiB0b2tlblxuICAgKlxuICAgKiBAcGFyYW0gdXNlclxuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIGFzeW5jIHJlZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuKHVzZXIsIG1hc3RlciwgaW5zdGFsbGF0aW9uSWQsIGlwKSB7XG4gICAgY29uc3QgeyBfZW1haWxfdmVyaWZ5X3Rva2VuIH0gPSB1c2VyO1xuICAgIGxldCB7IF9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCB9ID0gdXNlcjtcbiAgICBpZiAoX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ICYmIF9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdC5fX3R5cGUgPT09ICdEYXRlJykge1xuICAgICAgX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0gX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0LmlzbztcbiAgICB9XG4gICAgaWYgKFxuICAgICAgdGhpcy5jb25maWcuZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCAmJlxuICAgICAgdGhpcy5jb25maWcuZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24gJiZcbiAgICAgIF9lbWFpbF92ZXJpZnlfdG9rZW4gJiZcbiAgICAgIG5ldyBEYXRlKCkgPCBuZXcgRGF0ZShfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQpXG4gICAgKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuICAgIH1cbiAgICBjb25zdCBzaG91bGRTZW5kID0gYXdhaXQgdGhpcy5zZXRFbWFpbFZlcmlmeVRva2VuKHVzZXIsIHtcbiAgICAgIG9iamVjdDogUGFyc2UuVXNlci5mcm9tSlNPTihPYmplY3QuYXNzaWduKHsgY2xhc3NOYW1lOiAnX1VzZXInIH0sIHVzZXIpKSxcbiAgICAgIG1hc3RlcixcbiAgICAgIGluc3RhbGxhdGlvbklkLFxuICAgICAgaXAsXG4gICAgICByZXNlbmRSZXF1ZXN0OiB0cnVlXG4gICAgfSk7XG4gICAgaWYgKCFzaG91bGRTZW5kKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoJ19Vc2VyJywgeyB1c2VybmFtZTogdXNlci51c2VybmFtZSB9LCB1c2VyKTtcbiAgfVxuXG4gIGFzeW5jIHJlc2VuZFZlcmlmaWNhdGlvbkVtYWlsKHVzZXJuYW1lLCByZXEsIHRva2VuKSB7XG4gICAgY29uc3QgYVVzZXIgPSBhd2FpdCB0aGlzLmdldFVzZXJJZk5lZWRlZCh7IHVzZXJuYW1lLCBfZW1haWxfdmVyaWZ5X3Rva2VuOiB0b2tlbiB9KTtcbiAgICBpZiAoIWFVc2VyIHx8IGFVc2VyLmVtYWlsVmVyaWZpZWQpIHtcbiAgICAgIHRocm93IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY29uc3QgZ2VuZXJhdGUgPSBhd2FpdCB0aGlzLnJlZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuKGFVc2VyLCByZXEuYXV0aD8uaXNNYXN0ZXIsIHJlcS5hdXRoPy5pbnN0YWxsYXRpb25JZCwgcmVxLmlwKTtcbiAgICBpZiAoZ2VuZXJhdGUpIHtcbiAgICAgIHRoaXMuc2VuZFZlcmlmaWNhdGlvbkVtYWlsKGFVc2VyLCByZXEpO1xuICAgIH1cbiAgfVxuXG4gIHNldFBhc3N3b3JkUmVzZXRUb2tlbihlbWFpbCkge1xuICAgIGNvbnN0IHRva2VuID0geyBfcGVyaXNoYWJsZV90b2tlbjogcmFuZG9tU3RyaW5nKDI1KSB9O1xuXG4gICAgaWYgKHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICB0b2tlbi5fcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0ID0gUGFyc2UuX2VuY29kZShcbiAgICAgICAgdGhpcy5jb25maWcuZ2VuZXJhdGVQYXNzd29yZFJlc2V0VG9rZW5FeHBpcmVzQXQoKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UudXBkYXRlKFxuICAgICAgJ19Vc2VyJyxcbiAgICAgIHsgJG9yOiBbeyBlbWFpbCB9LCB7IHVzZXJuYW1lOiBlbWFpbCwgZW1haWw6IHsgJGV4aXN0czogZmFsc2UgfSB9XSB9LFxuICAgICAgdG9rZW4sXG4gICAgICB7fSxcbiAgICAgIHRydWVcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgc2VuZFBhc3N3b3JkUmVzZXRFbWFpbChlbWFpbCkge1xuICAgIGlmICghdGhpcy5hZGFwdGVyKSB7XG4gICAgICB0aHJvdyAnVHJ5aW5nIHRvIHNlbmQgYSByZXNldCBwYXNzd29yZCBidXQgbm8gYWRhcHRlciBpcyBzZXQnO1xuICAgICAgLy8gIFRPRE86IE5vIGFkYXB0ZXI/XG4gICAgfVxuICAgIGxldCB1c2VyO1xuICAgIGlmIChcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmXG4gICAgICB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5yZXNldFRva2VuUmV1c2VJZlZhbGlkICYmXG4gICAgICB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvblxuICAgICkge1xuICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuY29uZmlnLmRhdGFiYXNlLmZpbmQoXG4gICAgICAgICdfVXNlcicsXG4gICAgICAgIHtcbiAgICAgICAgICAkb3I6IFtcbiAgICAgICAgICAgIHsgZW1haWwsIF9wZXJpc2hhYmxlX3Rva2VuOiB7ICRleGlzdHM6IHRydWUgfSB9LFxuICAgICAgICAgICAgeyB1c2VybmFtZTogZW1haWwsIGVtYWlsOiB7ICRleGlzdHM6IGZhbHNlIH0sIF9wZXJpc2hhYmxlX3Rva2VuOiB7ICRleGlzdHM6IHRydWUgfSB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIHsgbGltaXQ6IDEgfSxcbiAgICAgICAgQXV0aC5tYWludGVuYW5jZSh0aGlzLmNvbmZpZylcbiAgICAgICk7XG4gICAgICBpZiAocmVzdWx0cy5sZW5ndGggPT0gMSkge1xuICAgICAgICBsZXQgZXhwaXJlc0RhdGUgPSByZXN1bHRzWzBdLl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQ7XG4gICAgICAgIGlmIChleHBpcmVzRGF0ZSAmJiBleHBpcmVzRGF0ZS5fX3R5cGUgPT0gJ0RhdGUnKSB7XG4gICAgICAgICAgZXhwaXJlc0RhdGUgPSBuZXcgRGF0ZShleHBpcmVzRGF0ZS5pc28pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChleHBpcmVzRGF0ZSA+IG5ldyBEYXRlKCkpIHtcbiAgICAgICAgICB1c2VyID0gcmVzdWx0c1swXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIXVzZXIgfHwgIXVzZXIuX3BlcmlzaGFibGVfdG9rZW4pIHtcbiAgICAgIHVzZXIgPSBhd2FpdCB0aGlzLnNldFBhc3N3b3JkUmVzZXRUb2tlbihlbWFpbCk7XG4gICAgfVxuICAgIGNvbnN0IHRva2VuID0gZW5jb2RlVVJJQ29tcG9uZW50KHVzZXIuX3BlcmlzaGFibGVfdG9rZW4pO1xuICAgIGNvbnN0IGxpbmsgPSBidWlsZEVtYWlsTGluayh0aGlzLmNvbmZpZy5yZXF1ZXN0UmVzZXRQYXNzd29yZFVSTCwgdG9rZW4sIHRoaXMuY29uZmlnKTtcbiAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgYXBwTmFtZTogdGhpcy5jb25maWcuYXBwTmFtZSxcbiAgICAgIGxpbms6IGxpbmssXG4gICAgICB1c2VyOiBpbmZsYXRlKCdfVXNlcicsIHVzZXIpLFxuICAgIH07XG5cbiAgICBpZiAodGhpcy5hZGFwdGVyLnNlbmRQYXNzd29yZFJlc2V0RW1haWwpIHtcbiAgICAgIHRoaXMuYWRhcHRlci5zZW5kUGFzc3dvcmRSZXNldEVtYWlsKG9wdGlvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFkYXB0ZXIuc2VuZE1haWwodGhpcy5kZWZhdWx0UmVzZXRQYXNzd29yZEVtYWlsKG9wdGlvbnMpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVzZXIpO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlUGFzc3dvcmQodG9rZW4sIHBhc3N3b3JkKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhd1VzZXIgPSBhd2FpdCB0aGlzLmNoZWNrUmVzZXRUb2tlblZhbGlkaXR5KHRva2VuKTtcbiAgICAgIGxldCB1c2VyO1xuICAgICAgdHJ5IHtcbiAgICAgICAgdXNlciA9IGF3YWl0IHVwZGF0ZVVzZXJQYXNzd29yZChyYXdVc2VyLCBwYXNzd29yZCwgdGhpcy5jb25maWcpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yICYmIGVycm9yLmNvZGUgPT09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgICB0aHJvdyAnRmFpbGVkIHRvIHJlc2V0IHBhc3N3b3JkOiB1c2VybmFtZSAvIGVtYWlsIC8gdG9rZW4gaXMgaW52YWxpZCc7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFjY291bnRMb2Nrb3V0UG9saWN5ID0gbmV3IEFjY291bnRMb2Nrb3V0KHVzZXIsIHRoaXMuY29uZmlnKTtcbiAgICAgIHJldHVybiBhd2FpdCBhY2NvdW50TG9ja291dFBvbGljeS51bmxvY2tBY2NvdW50KCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciAmJiBlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgIC8vIGluIGNhc2Ugb2YgUGFyc2UuRXJyb3IsIGZhaWwgd2l0aCB0aGUgZXJyb3IgbWVzc2FnZSBvbmx5XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvci5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgZGVmYXVsdFZlcmlmaWNhdGlvbkVtYWlsKHsgbGluaywgdXNlciwgYXBwTmFtZSB9KSB7XG4gICAgY29uc3QgdGV4dCA9XG4gICAgICAnSGksXFxuXFxuJyArXG4gICAgICAnWW91IGFyZSBiZWluZyBhc2tlZCB0byBjb25maXJtIHRoZSBlLW1haWwgYWRkcmVzcyAnICtcbiAgICAgIHVzZXIuZ2V0KCdlbWFpbCcpICtcbiAgICAgICcgd2l0aCAnICtcbiAgICAgIGFwcE5hbWUgK1xuICAgICAgJ1xcblxcbicgK1xuICAgICAgJycgK1xuICAgICAgJ0NsaWNrIGhlcmUgdG8gY29uZmlybSBpdDpcXG4nICtcbiAgICAgIGxpbms7XG4gICAgY29uc3QgdG8gPSB1c2VyLmdldCgnZW1haWwnKTtcbiAgICBjb25zdCBzdWJqZWN0ID0gJ1BsZWFzZSB2ZXJpZnkgeW91ciBlLW1haWwgZm9yICcgKyBhcHBOYW1lO1xuICAgIHJldHVybiB7IHRleHQsIHRvLCBzdWJqZWN0IH07XG4gIH1cblxuICBkZWZhdWx0UmVzZXRQYXNzd29yZEVtYWlsKHsgbGluaywgdXNlciwgYXBwTmFtZSB9KSB7XG4gICAgY29uc3QgdGV4dCA9XG4gICAgICAnSGksXFxuXFxuJyArXG4gICAgICAnWW91IHJlcXVlc3RlZCB0byByZXNldCB5b3VyIHBhc3N3b3JkIGZvciAnICtcbiAgICAgIGFwcE5hbWUgK1xuICAgICAgKHVzZXIuZ2V0KCd1c2VybmFtZScpID8gXCIgKHlvdXIgdXNlcm5hbWUgaXMgJ1wiICsgdXNlci5nZXQoJ3VzZXJuYW1lJykgKyBcIicpXCIgOiAnJykgK1xuICAgICAgJy5cXG5cXG4nICtcbiAgICAgICcnICtcbiAgICAgICdDbGljayBoZXJlIHRvIHJlc2V0IGl0OlxcbicgK1xuICAgICAgbGluaztcbiAgICBjb25zdCB0byA9IHVzZXIuZ2V0KCdlbWFpbCcpIHx8IHVzZXIuZ2V0KCd1c2VybmFtZScpO1xuICAgIGNvbnN0IHN1YmplY3QgPSAnUGFzc3dvcmQgUmVzZXQgZm9yICcgKyBhcHBOYW1lO1xuICAgIHJldHVybiB7IHRleHQsIHRvLCBzdWJqZWN0IH07XG4gIH1cbn1cblxuLy8gTWFyayB0aGlzIHByaXZhdGVcbmZ1bmN0aW9uIHVwZGF0ZVVzZXJQYXNzd29yZCh1c2VyLCBwYXNzd29yZCwgY29uZmlnKSB7XG4gIHJldHVybiByZXN0XG4gICAgLnVwZGF0ZShcbiAgICAgIGNvbmZpZyxcbiAgICAgIEF1dGgubWFzdGVyKGNvbmZpZyksXG4gICAgICAnX1VzZXInLFxuICAgICAgeyBvYmplY3RJZDogdXNlci5vYmplY3RJZCwgX3BlcmlzaGFibGVfdG9rZW46IHVzZXIuX3BlcmlzaGFibGVfdG9rZW4gfSxcbiAgICAgIHtcbiAgICAgICAgcGFzc3dvcmQ6IHBhc3N3b3JkLFxuICAgICAgfVxuICAgIClcbiAgICAudGhlbigoKSA9PiB1c2VyKTtcbn1cblxuZnVuY3Rpb24gYnVpbGRFbWFpbExpbmsoZGVzdGluYXRpb24sIHRva2VuLCBjb25maWcpIHtcbiAgdG9rZW4gPSBgdG9rZW49JHt0b2tlbn1gO1xuICBpZiAoY29uZmlnLnBhcnNlRnJhbWVVUkwpIHtcbiAgICBjb25zdCBkZXN0aW5hdGlvbldpdGhvdXRIb3N0ID0gZGVzdGluYXRpb24ucmVwbGFjZShjb25maWcucHVibGljU2VydmVyVVJMLCAnJyk7XG5cbiAgICByZXR1cm4gYCR7Y29uZmlnLnBhcnNlRnJhbWVVUkx9P2xpbms9JHtlbmNvZGVVUklDb21wb25lbnQoZGVzdGluYXRpb25XaXRob3V0SG9zdCl9JiR7dG9rZW59YDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYCR7ZGVzdGluYXRpb259PyR7dG9rZW59YDtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVc2VyQ29udHJvbGxlcjtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBQUEsWUFBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsU0FBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsb0JBQUEsR0FBQUMsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFJLFlBQUEsR0FBQUQsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFLLEtBQUEsR0FBQUYsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFNLEtBQUEsR0FBQUgsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFPLGVBQUEsR0FBQUosc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFRLE9BQUEsR0FBQUwsc0JBQUEsQ0FBQUgsT0FBQTtBQUErQixTQUFBRyx1QkFBQU0sQ0FBQSxXQUFBQSxD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