@cloudbase/auth 3.1.7 → 3.1.9

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.
@@ -0,0 +1,77 @@
1
+ import type { authModels } from '@cloudbase/oauth';
2
+ import type { SignUpRes } from './type';
3
+ export declare class WeixinAuthProvider {
4
+ constructor(_options: {
5
+ authInstance: any;
6
+ appid: string;
7
+ scope: string;
8
+ });
9
+ signInWithRedirect(): void;
10
+ getRedirectResult(_options?: {
11
+ createUser?: boolean;
12
+ syncUserInfo?: boolean;
13
+ }): Promise<any>;
14
+ getLinkRedirectResult(_options?: {
15
+ withUnionId?: boolean;
16
+ }): Promise<void>;
17
+ }
18
+ export declare class CustomAuthProvider {
19
+ private authInstance;
20
+ constructor(options: {
21
+ authInstance: any;
22
+ });
23
+ signIn(ticket: string): Promise<void>;
24
+ }
25
+ export declare class AnonymousAuthProvider {
26
+ private authInstance;
27
+ constructor(options: {
28
+ authInstance: any;
29
+ });
30
+ signIn(): Promise<void>;
31
+ }
32
+ export declare abstract class AuthV1Compat {
33
+ abstract readonly config: any;
34
+ weixinAuthProvider(options: {
35
+ appid: string;
36
+ scope: string;
37
+ }): WeixinAuthProvider;
38
+ customAuthProvider(): CustomAuthProvider;
39
+ anonymousAuthProvider(): AnonymousAuthProvider;
40
+ signUpWithEmailAndPassword(email: string, password: string): Promise<SignUpRes>;
41
+ signInWithEmailAndPassword(email: string, password: string): Promise<any>;
42
+ sendPasswordResetEmail(email: string): Promise<void>;
43
+ signInWithUsernameAndPassword(username: string, password: string): Promise<any>;
44
+ sendPhoneCode(phoneNumber: string): Promise<boolean>;
45
+ signUpWithPhoneCode(phoneNumber: string, phoneCode: string, password?: string): Promise<any>;
46
+ signInWithPhoneCodeOrPassword(params: {
47
+ phoneNumber: string;
48
+ phoneCode?: string;
49
+ password?: string;
50
+ }): Promise<any>;
51
+ forceResetPwdByPhoneCode(params: {
52
+ phoneNumber: string;
53
+ phoneCode: string;
54
+ password: string;
55
+ }): Promise<any>;
56
+ shouldRefreshAccessToken(_callback: () => boolean): void;
57
+ onLoginStateExpired(callback: Function): void;
58
+ onAccessTokenRefreshed(callback: Function): void;
59
+ onAnonymousConverted(callback: Function): void;
60
+ onLoginTypeChanged(callback: Function): void;
61
+ abstract signIn(params: authModels.SignInRequest): Promise<any>;
62
+ abstract signUp(params: authModels.SignUpRequest & {
63
+ phone?: string;
64
+ }): Promise<SignUpRes>;
65
+ abstract signInWithCustomTicket(getTickFn?: authModels.GetCustomSignTicketFn): Promise<any>;
66
+ abstract signInAnonymously(params: any): Promise<any>;
67
+ abstract getVerification(params: any, options?: any): Promise<authModels.GetVerificationResponse>;
68
+ abstract resetPassword(params: authModels.ResetPasswordRequest): Promise<void>;
69
+ abstract onLoginStateChanged(callback: Function): Promise<void>;
70
+ abstract onAuthStateChange(callback: any): any;
71
+ abstract createLoginState(params?: any, options?: any): Promise<any>;
72
+ abstract signInWithOAuth(params: any): Promise<any>;
73
+ abstract grantProviderToken(params: authModels.GrantProviderTokenRequest): Promise<authModels.GrantProviderTokenResponse>;
74
+ abstract bindWithProvider(params: authModels.BindWithProviderRequest): Promise<void>;
75
+ protected abstract formatPhone(phone: string): string;
76
+ }
77
+ export declare function applyUserV1Compat(UserClass: any): void;
@@ -0,0 +1,419 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ import { LOGIN_STATE_CHANGED_TYPE, AUTH_STATE_CHANGED_TYPE, } from '@cloudbase/oauth';
49
+ import { throwError, ERRORS, } from './utilities';
50
+ var WeixinAuthProvider = (function () {
51
+ function WeixinAuthProvider(_options) {
52
+ }
53
+ WeixinAuthProvider.prototype.signInWithRedirect = function () {
54
+ throw new Error('[v1 兼容] WeixinAuthProvider.signInWithRedirect() 在当前版本中无法实现。'
55
+ + ' 建议使用 auth.signInWithOAuth({ provider: \'providerId\' }) 替代。');
56
+ };
57
+ WeixinAuthProvider.prototype.getRedirectResult = function (_options) {
58
+ return __awaiter(this, void 0, void 0, function () {
59
+ return __generator(this, function (_a) {
60
+ throw new Error('[v1 兼容] WeixinAuthProvider.getRedirectResult() 在当前版本中无法实现。'
61
+ + ' 建议使用 auth.verifyOAuth({ code, state, provider }) 替代。');
62
+ });
63
+ });
64
+ };
65
+ WeixinAuthProvider.prototype.getLinkRedirectResult = function (_options) {
66
+ return __awaiter(this, void 0, void 0, function () {
67
+ return __generator(this, function (_a) {
68
+ throw new Error('[v1 兼容] WeixinAuthProvider.getLinkRedirectResult() 在当前版本中无法实现。'
69
+ + ' 建议使用 auth.linkIdentity({ provider: \'providerId\' }) 替代。');
70
+ });
71
+ });
72
+ };
73
+ return WeixinAuthProvider;
74
+ }());
75
+ export { WeixinAuthProvider };
76
+ var CustomAuthProvider = (function () {
77
+ function CustomAuthProvider(options) {
78
+ this.authInstance = options.authInstance;
79
+ }
80
+ CustomAuthProvider.prototype.signIn = function (ticket) {
81
+ return __awaiter(this, void 0, void 0, function () {
82
+ return __generator(this, function (_a) {
83
+ switch (_a.label) {
84
+ case 0: return [4, this.authInstance.signInWithCustomTicket(function () { return Promise.resolve(ticket); })];
85
+ case 1:
86
+ _a.sent();
87
+ return [2];
88
+ }
89
+ });
90
+ });
91
+ };
92
+ return CustomAuthProvider;
93
+ }());
94
+ export { CustomAuthProvider };
95
+ var AnonymousAuthProvider = (function () {
96
+ function AnonymousAuthProvider(options) {
97
+ this.authInstance = options.authInstance;
98
+ }
99
+ AnonymousAuthProvider.prototype.signIn = function () {
100
+ return __awaiter(this, void 0, void 0, function () {
101
+ return __generator(this, function (_a) {
102
+ switch (_a.label) {
103
+ case 0: return [4, this.authInstance.signInAnonymously({})];
104
+ case 1:
105
+ _a.sent();
106
+ return [2];
107
+ }
108
+ });
109
+ });
110
+ };
111
+ return AnonymousAuthProvider;
112
+ }());
113
+ export { AnonymousAuthProvider };
114
+ var AuthV1Compat = (function () {
115
+ function AuthV1Compat() {
116
+ }
117
+ AuthV1Compat.prototype.weixinAuthProvider = function (options) {
118
+ return new WeixinAuthProvider({
119
+ authInstance: this,
120
+ appid: options.appid,
121
+ scope: options.scope,
122
+ });
123
+ };
124
+ AuthV1Compat.prototype.customAuthProvider = function () {
125
+ return new CustomAuthProvider({
126
+ authInstance: this,
127
+ });
128
+ };
129
+ AuthV1Compat.prototype.anonymousAuthProvider = function () {
130
+ return new AnonymousAuthProvider({
131
+ authInstance: this,
132
+ });
133
+ };
134
+ AuthV1Compat.prototype.signUpWithEmailAndPassword = function (email, password) {
135
+ return __awaiter(this, void 0, void 0, function () {
136
+ return __generator(this, function (_a) {
137
+ switch (_a.label) {
138
+ case 0:
139
+ if (typeof email !== 'string') {
140
+ throwError(ERRORS.INVALID_PARAMS, 'email must be a string');
141
+ }
142
+ if (typeof password !== 'string') {
143
+ throwError(ERRORS.INVALID_PARAMS, 'password must be a string');
144
+ }
145
+ return [4, this.signUp({
146
+ email: email,
147
+ password: password,
148
+ })];
149
+ case 1: return [2, _a.sent()];
150
+ }
151
+ });
152
+ });
153
+ };
154
+ AuthV1Compat.prototype.signInWithEmailAndPassword = function (email, password) {
155
+ return __awaiter(this, void 0, void 0, function () {
156
+ return __generator(this, function (_a) {
157
+ switch (_a.label) {
158
+ case 0:
159
+ if (typeof email !== 'string') {
160
+ throwError(ERRORS.INVALID_PARAMS, 'email must be a string');
161
+ }
162
+ if (typeof password !== 'string') {
163
+ throwError(ERRORS.INVALID_PARAMS, 'password must be a string');
164
+ }
165
+ return [4, this.signIn({
166
+ username: email,
167
+ password: password,
168
+ })];
169
+ case 1:
170
+ _a.sent();
171
+ return [2, this.createLoginState()];
172
+ }
173
+ });
174
+ });
175
+ };
176
+ AuthV1Compat.prototype.sendPasswordResetEmail = function (email) {
177
+ return __awaiter(this, void 0, void 0, function () {
178
+ return __generator(this, function (_a) {
179
+ switch (_a.label) {
180
+ case 0:
181
+ if (typeof email !== 'string') {
182
+ throwError(ERRORS.INVALID_PARAMS, 'email must be a string');
183
+ }
184
+ return [4, this.getVerification({ email: email })];
185
+ case 1:
186
+ _a.sent();
187
+ return [2];
188
+ }
189
+ });
190
+ });
191
+ };
192
+ AuthV1Compat.prototype.signInWithUsernameAndPassword = function (username, password) {
193
+ return __awaiter(this, void 0, void 0, function () {
194
+ return __generator(this, function (_a) {
195
+ switch (_a.label) {
196
+ case 0:
197
+ if (typeof username !== 'string') {
198
+ throwError(ERRORS.INVALID_PARAMS, 'username must be a string');
199
+ }
200
+ if (typeof password !== 'string') {
201
+ throwError(ERRORS.INVALID_PARAMS, 'password must be a string');
202
+ }
203
+ return [4, this.signIn({
204
+ username: username,
205
+ password: password,
206
+ })];
207
+ case 1:
208
+ _a.sent();
209
+ return [2, this.createLoginState()];
210
+ }
211
+ });
212
+ });
213
+ };
214
+ AuthV1Compat.prototype.sendPhoneCode = function (phoneNumber) {
215
+ return __awaiter(this, void 0, void 0, function () {
216
+ var formattedPhone;
217
+ return __generator(this, function (_a) {
218
+ switch (_a.label) {
219
+ case 0:
220
+ if (typeof phoneNumber !== 'string') {
221
+ throwError(ERRORS.INVALID_PARAMS, 'phoneNumber must be a string');
222
+ }
223
+ formattedPhone = this.formatPhone(phoneNumber);
224
+ return [4, this.getVerification({ phone_number: formattedPhone })];
225
+ case 1:
226
+ _a.sent();
227
+ return [2, true];
228
+ }
229
+ });
230
+ });
231
+ };
232
+ AuthV1Compat.prototype.signUpWithPhoneCode = function (phoneNumber, phoneCode, password) {
233
+ return __awaiter(this, void 0, void 0, function () {
234
+ var formattedPhone;
235
+ return __generator(this, function (_a) {
236
+ switch (_a.label) {
237
+ case 0:
238
+ if (typeof phoneNumber !== 'string') {
239
+ throwError(ERRORS.INVALID_PARAMS, 'phoneNumber must be a string');
240
+ }
241
+ if (typeof phoneCode !== 'string') {
242
+ throwError(ERRORS.INVALID_PARAMS, 'phoneCode must be a string');
243
+ }
244
+ formattedPhone = this.formatPhone(phoneNumber);
245
+ return [4, this.signUp(__assign({ phone_number: formattedPhone, verification_code: phoneCode }, (password ? { password: password } : {})))];
246
+ case 1:
247
+ _a.sent();
248
+ return [2, this.createLoginState()];
249
+ }
250
+ });
251
+ });
252
+ };
253
+ AuthV1Compat.prototype.signInWithPhoneCodeOrPassword = function (params) {
254
+ return __awaiter(this, void 0, void 0, function () {
255
+ var phoneNumber, phoneCode, password, formattedPhone;
256
+ return __generator(this, function (_a) {
257
+ switch (_a.label) {
258
+ case 0:
259
+ phoneNumber = params.phoneNumber, phoneCode = params.phoneCode, password = params.password;
260
+ if (typeof phoneNumber !== 'string') {
261
+ throwError(ERRORS.INVALID_PARAMS, 'phoneNumber must be a string');
262
+ }
263
+ formattedPhone = this.formatPhone(phoneNumber);
264
+ if (!password) return [3, 2];
265
+ return [4, this.signIn({
266
+ username: formattedPhone,
267
+ password: password,
268
+ })];
269
+ case 1:
270
+ _a.sent();
271
+ return [3, 5];
272
+ case 2:
273
+ if (!phoneCode) return [3, 4];
274
+ return [4, this.signIn({
275
+ username: formattedPhone,
276
+ verification_token: phoneCode,
277
+ })];
278
+ case 3:
279
+ _a.sent();
280
+ return [3, 5];
281
+ case 4:
282
+ throwError(ERRORS.INVALID_PARAMS, 'phoneCode or password must be provided');
283
+ _a.label = 5;
284
+ case 5: return [2, this.createLoginState()];
285
+ }
286
+ });
287
+ });
288
+ };
289
+ AuthV1Compat.prototype.forceResetPwdByPhoneCode = function (params) {
290
+ return __awaiter(this, void 0, void 0, function () {
291
+ var phoneNumber, phoneCode, password, formattedPhone;
292
+ return __generator(this, function (_a) {
293
+ switch (_a.label) {
294
+ case 0:
295
+ phoneNumber = params.phoneNumber, phoneCode = params.phoneCode, password = params.password;
296
+ if (typeof phoneNumber !== 'string') {
297
+ throwError(ERRORS.INVALID_PARAMS, 'phoneNumber must be a string');
298
+ }
299
+ if (typeof phoneCode !== 'string') {
300
+ throwError(ERRORS.INVALID_PARAMS, 'phoneCode must be a string');
301
+ }
302
+ if (typeof password !== 'string') {
303
+ throwError(ERRORS.INVALID_PARAMS, 'password must be a string');
304
+ }
305
+ formattedPhone = this.formatPhone(phoneNumber);
306
+ return [4, this.resetPassword({
307
+ phone_number: formattedPhone,
308
+ new_password: password,
309
+ verification_token: phoneCode,
310
+ })];
311
+ case 1:
312
+ _a.sent();
313
+ return [4, this.signIn({
314
+ username: formattedPhone,
315
+ password: password,
316
+ })];
317
+ case 2:
318
+ _a.sent();
319
+ return [2, this.createLoginState()];
320
+ }
321
+ });
322
+ });
323
+ };
324
+ AuthV1Compat.prototype.shouldRefreshAccessToken = function (_callback) {
325
+ throw new Error('[v1 兼容] shouldRefreshAccessToken() 在当前版本中无法实现。'
326
+ + ' 建议使用 auth.onAuthStateChange(callback) 来监听 TOKEN_REFRESHED 事件替代。');
327
+ };
328
+ AuthV1Compat.prototype.onLoginStateExpired = function (callback) {
329
+ var _this = this;
330
+ this.onLoginStateChanged(function (params) {
331
+ if ((params === null || params === void 0 ? void 0 : params.eventType) === LOGIN_STATE_CHANGED_TYPE.CREDENTIALS_ERROR) {
332
+ callback.call(_this);
333
+ }
334
+ });
335
+ };
336
+ AuthV1Compat.prototype.onAccessTokenRefreshed = function (callback) {
337
+ var _this = this;
338
+ this.onAuthStateChange(function (event) {
339
+ if (event === AUTH_STATE_CHANGED_TYPE.TOKEN_REFRESHED) {
340
+ callback.call(_this);
341
+ }
342
+ });
343
+ };
344
+ AuthV1Compat.prototype.onAnonymousConverted = function (callback) {
345
+ var _this = this;
346
+ this.onAuthStateChange(function (event) {
347
+ if (event === AUTH_STATE_CHANGED_TYPE.SIGNED_IN) {
348
+ callback.call(_this);
349
+ }
350
+ });
351
+ };
352
+ AuthV1Compat.prototype.onLoginTypeChanged = function (callback) {
353
+ var _this = this;
354
+ this.onAuthStateChange(function (event) {
355
+ if (event === AUTH_STATE_CHANGED_TYPE.SIGNED_IN || event === AUTH_STATE_CHANGED_TYPE.SIGNED_OUT) {
356
+ callback.call(_this);
357
+ }
358
+ });
359
+ };
360
+ return AuthV1Compat;
361
+ }());
362
+ export { AuthV1Compat };
363
+ export function applyUserV1Compat(UserClass) {
364
+ UserClass.prototype.linkWithTicket = function (_ticket) {
365
+ return __awaiter(this, void 0, void 0, function () {
366
+ return __generator(this, function (_a) {
367
+ throw new Error('[v1 兼容] User.linkWithTicket() 在当前版本中无法实现。'
368
+ + ' 建议使用 auth.signInWithCustomTicket(() => Promise.resolve(ticket)) 替代。');
369
+ });
370
+ });
371
+ };
372
+ UserClass.prototype.linkWithRedirect = function (_provider) {
373
+ throw new Error('[v1 兼容] User.linkWithRedirect() 在当前版本中无法实现。'
374
+ + ' 建议使用 auth.linkIdentity({ provider: \'providerId\' }) 替代。');
375
+ };
376
+ UserClass.prototype.updateEmail = function (newEmail, _password) {
377
+ return __awaiter(this, void 0, void 0, function () {
378
+ return __generator(this, function (_a) {
379
+ switch (_a.label) {
380
+ case 0:
381
+ if (typeof newEmail !== 'string') {
382
+ throwError(ERRORS.INVALID_PARAMS, 'newEmail must be a string');
383
+ }
384
+ return [4, this.updateUserBasicInfo({
385
+ email: newEmail,
386
+ })];
387
+ case 1:
388
+ _a.sent();
389
+ return [2];
390
+ }
391
+ });
392
+ });
393
+ };
394
+ UserClass.prototype.linkWithPhoneNumber = function (_phoneNumber, _phoneCode) {
395
+ return __awaiter(this, void 0, void 0, function () {
396
+ return __generator(this, function (_a) {
397
+ throw new Error('[v1 兼容] User.linkWithPhoneNumber() 在当前版本中无法实现。'
398
+ + ' 建议使用 auth.bindPhoneNumber({ phone_number, verification_token, sudo_token }) 替代。');
399
+ });
400
+ });
401
+ };
402
+ UserClass.prototype.updatePhoneNumber = function (_phoneNumber, _phoneCode) {
403
+ return __awaiter(this, void 0, void 0, function () {
404
+ return __generator(this, function (_a) {
405
+ throw new Error('[v1 兼容] User.updatePhoneNumber() 在当前版本中无法实现。'
406
+ + ' 建议使用 auth.updateUser({ phone: newPhoneNumber }) 替代。');
407
+ });
408
+ });
409
+ };
410
+ UserClass.prototype.unlink = function (_loginType) {
411
+ return __awaiter(this, void 0, void 0, function () {
412
+ return __generator(this, function (_a) {
413
+ throw new Error('[v1 兼容] User.unlink() 在当前版本中无法实现。'
414
+ + ' 建议使用 auth.unlinkIdentity({ provider: loginType }) 替代。');
415
+ });
416
+ });
417
+ };
418
+ }
419
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidjEtY29tcGF0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3YxLWNvbXBhdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVFBLE9BQU8sRUFDTCx3QkFBd0IsRUFDeEIsdUJBQXVCLEdBQ3hCLE1BQU0sa0JBQWtCLENBQUE7QUFDekIsT0FBTyxFQUNMLFVBQVUsRUFDVixNQUFNLEdBQ1AsTUFBTSxhQUFhLENBQUE7QUFXcEI7SUFDRSw0QkFBWSxRQUlYO0lBRUQsQ0FBQztJQU1NLCtDQUFrQixHQUF6QjtRQUNFLE1BQU0sSUFBSSxLQUFLLENBQUMsNkRBQTZEO2NBQ3pFLDhEQUE4RCxDQUFFLENBQUE7SUFDdEUsQ0FBQztJQU1ZLDhDQUFpQixHQUE5QixVQUErQixRQUc5Qjs7O2dCQUNDLE1BQU0sSUFBSSxLQUFLLENBQUMsNERBQTREO3NCQUN4RSx1REFBdUQsQ0FBRSxDQUFBOzs7S0FDOUQ7SUFNWSxrREFBcUIsR0FBbEMsVUFBbUMsUUFFbEM7OztnQkFDQyxNQUFNLElBQUksS0FBSyxDQUFDLGdFQUFnRTtzQkFDNUUsMkRBQTJELENBQUUsQ0FBQTs7O0tBQ2xFO0lBQ0gseUJBQUM7QUFBRCxDQUFDLEFBeENELElBd0NDOztBQVFEO0lBR0UsNEJBQVksT0FFWDtRQUNDLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQTtJQUMxQyxDQUFDO0lBT1ksbUNBQU0sR0FBbkIsVUFBb0IsTUFBYzs7Ozs0QkFFaEMsV0FBTSxJQUFJLENBQUMsWUFBWSxDQUFDLHNCQUFzQixDQUFDLGNBQU0sT0FBQSxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUF2QixDQUF1QixDQUFDLEVBQUE7O3dCQUE3RSxTQUE2RSxDQUFBOzs7OztLQUM5RTtJQUNILHlCQUFDO0FBQUQsQ0FBQyxBQWxCRCxJQWtCQzs7QUFRRDtJQUdFLCtC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QUFTLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxVQUFnQixRQUFnQixFQUFFLFNBQWtCOzs7Ozt3QkFDcEYsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLEVBQUU7NEJBQ2hDLFVBQVUsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLDJCQUEyQixDQUFDLENBQUE7eUJBQy9EO3dCQUdELFdBQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDO2dDQUM3QixLQUFLLEVBQUUsUUFBUTs2QkFDaEIsQ0FBQyxFQUFBOzt3QkFGRixTQUVFLENBQUE7Ozs7O0tBQ0gsQ0FBQTtJQU9ELFNBQVMsQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEdBQUcsVUFBZ0IsWUFBb0IsRUFBRSxVQUFrQjs7O2dCQUNoRyxNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFnRDtzQkFDNUQsa0ZBQWtGLENBQUUsQ0FBQTs7O0tBQ3pGLENBQUE7SUFPRCxTQUFTLENBQUMsU0FBUyxDQUFDLGlCQUFpQixHQUFHLFVBQWdCLFlBQW9CLEVBQUUsVUFBa0I7OztnQkFDOUYsTUFBTSxJQUFJLEtBQUssQ0FBQyw4Q0FBOEM7c0JBQzFELHNEQUFzRCxDQUFFLENBQUE7OztLQUM3RCxDQUFBO0lBT0QsU0FBUyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsVUFBZ0IsVUFBa0I7OztnQkFDN0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQ0FBbUM7c0JBQy9DLHdEQUF3RCxDQUFFLENBQUE7OztLQUMvRCxDQUFBO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11c2VsZXNzLWNvbnN0cnVjdG9yICovXG4vKipcbiAqIHYxIOWFvOWuueWxglxuICog5pys5paH5Lu25YyF5ZCrIHYxIOeJiOacrOeahCBQcm92aWRlciDnsbvjgIFBdXRoIHYxIOWFvOWuueaWueazleWSjCBVc2VyIHYxIOWFvOWuueaWueazleOAglxuICogQXV0aCDnsbvpgJrov4cgZXh0ZW5kcyBBdXRoVjFDb21wYXQg5p2l57un5om/IHYxIOaWueazleOAglxuICogVXNlciDnsbvpgJrov4cgYXBwbHlVc2VyVjFDb21wYXQgbWl4aW4g5p2l5omp5bGVIHYxIOaWueazleOAglxuICovXG5pbXBvcnQgdHlwZSB7IGF1dGhNb2RlbHMgfSBmcm9tICdAY2xvdWRiYXNlL29hdXRoJ1xuaW1wb3J0IHtcbiAgTE9HSU5fU1RBVEVfQ0hBTkdFRF9UWVBFLFxuICBBVVRIX1NUQVRFX0NIQU5HRURfVFlQRSxcbn0gZnJvbSAnQGNsb3VkYmFzZS9vYXV0aCdcbmltcG9ydCB7XG4gIHRocm93RXJyb3IsXG4gIEVSUk9SUyxcbn0gZnJvbSAnLi91dGlsaXRpZXMnXG5pbXBvcnQgdHlwZSB7IFNpZ25VcFJlcyB9IGZyb20gJy4vdHlwZSdcblxuLy8gPT09PT09PT09PSB2MSDlhbzlrrkgUHJvdmlkZXIg57G7ID09PT09PT09PT1cblxuLyoqXG4gKiB2MSDlvq7kv6HnmbvlvZUgUHJvdmlkZXJcbiAqIOS9v+eUqOaWueW8jzogYXV0aC53ZWl4aW5BdXRoUHJvdmlkZXIoeyBhcHBpZCwgc2NvcGUgfSkuc2lnbkluV2l0aFJlZGlyZWN0KClcbiAqXG4gKiBAZGVwcmVjYXRlZCB2MSDlhbzlrrkgQVBJ44CC5bu66K6u5L2/55SoIGF1dGguc2lnbkluV2l0aE9BdXRoKHsgcHJvdmlkZXIgfSkg5pu/5Luj44CCXG4gKi9cbmV4cG9ydCBjbGFzcyBXZWl4aW5BdXRoUHJvdmlkZXIge1xuICBjb25zdHJ1Y3Rvcihfb3B0aW9uczoge1xuICAgIGF1dGhJbnN0YW5jZTogYW55XG4gICAgYXBwaWQ6IHN0cmluZ1xuICAgIHNjb3BlOiBzdHJpbmdcbiAgfSkge1xuICAgIC8vIHYxIOWFvOWuueexu++8jOaJgOacieaWueazleWdh+aKm+WHuuW8guW4uOaPkOekuuabv+S7o+aWueahiFxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHYxIOWFvOWuuSBBUEnjgIJcbiAgICog5bu66K6u5L2/55SoIGF1dGguc2lnbkluV2l0aE9BdXRoKHsgcHJvdmlkZXI6ICdwcm92aWRlcklkJyB9KSDmm7/ku6PjgIJcbiAgICovXG4gIHB1YmxpYyBzaWduSW5XaXRoUmVkaXJlY3QoKTogdm9pZCB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdbdjEg5YW85a65XSBXZWl4aW5BdXRoUHJvdmlkZXIuc2lnbkluV2l0aFJlZGlyZWN0KCkg5Zyo5b2T5YmN54mI5pys5Lit5peg5rOV5a6e546w44CCJ1xuICAgICAgKyAnIOW7uuiuruS9v+eUqCBhdXRoLnNpZ25JbldpdGhPQXV0aCh7IHByb3ZpZGVyOiBcXCdwcm92aWRlcklkXFwnIH0pIOabv+S7o+OAgicsKVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHYxIOWFvOWuuSBBUEnjgIJcbiAgICog5bu66K6u5L2/55SoIGF1dGgudmVyaWZ5T0F1dGgoeyBjb2RlLCBzdGF0ZSwgcHJvdmlkZXIgfSkg5pu/5Luj44CCXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0UmVkaXJlY3RSZXN1bHQoX29wdGlvbnM/OiB7XG4gICAgY3JlYXRlVXNlcj86IGJvb2xlYW5cbiAgICBzeW5jVXNlckluZm8/OiBib29sZWFuXG4gIH0pOiBQcm9taXNlPGFueT4ge1xuICAgIHRocm93IG5ldyBFcnJvcignW3YxIOWFvOWuuV0gV2VpeGluQXV0aFByb3ZpZGVyLmdldFJlZGlyZWN0UmVzdWx0KCkg5Zyo5b2T5YmN54mI5pys5Lit5peg5rOV5a6e546w44CCJ1xuICAgICAgKyAnIOW7uuiuruS9v+eUqCBhdXRoLnZlcmlmeU9BdXRoKHsgY29kZSwgc3RhdGUsIHByb3ZpZGVyIH0pIOabv+S7o+OAgicsKVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHYxIOWFvOWuuSBBUEnjgIJcbiAgICog5bu66K6u5L2/55SoIGF1dGgubGlua0lkZW50aXR5KHsgcHJvdmlkZXI6ICdwcm92aWRlcklkJyB9KSDmm7/ku6PjgIJcbiAgICovXG4gIHB1YmxpYyBhc3luYyBnZXRMaW5rUmVkaXJlY3RSZXN1bHQoX29wdGlvbnM/OiB7XG4gICAgd2l0aFVuaW9uSWQ/OiBib29sZWFuXG4gIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1t2MSDlhbzlrrldIFdlaXhpbkF1dGhQcm92aWRlci5nZXRMaW5rUmVkaXJlY3RSZXN1bHQoKSDlnKjlvZPliY3niYjmnKzkuK3ml6Dms5Xlrp7njrDjgIInXG4gICAgICArICcg5bu66K6u5L2/55SoIGF1dGgubGlua0lkZW50aXR5KHsgcHJvdmlkZXI6IFxcJ3Byb3ZpZGVySWRcXCcgfSkg5pu/5Luj44CCJywpXG4gIH1cbn1cblxuLyoqXG4gKiB2MSDoh6rlrprkuYnnmbvlvZUgUHJvdmlkZXJcbiAqIOS9v+eUqOaWueW8jzogYXV0aC5jdXN0b21BdXRoUHJvdmlkZXIoKS5zaWduSW4odGlja2V0KVxuICpcbiAqIEBkZXByZWNhdGVkIHYxIOWFvOWuuSBBUEnjgILlu7rorq7kvb/nlKggYXV0aC5zaWduSW5XaXRoQ3VzdG9tVGlja2V0KCgpID0+IFByb21pc2UucmVzb2x2ZSh0aWNrZXQpKSDmm7/ku6PjgIJcbiAqL1xuZXhwb3J0IGNsYXNzIEN1c3RvbUF1dGhQcm92aWRlciB7XG4gIHByaXZhdGUgYXV0aEluc3RhbmNlOiBhbnlcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiB7XG4gICAgYXV0aEluc3RhbmNlOiBhbnlcbiAgfSkge1xuICAgIHRoaXMuYXV0aEluc3RhbmNlID0gb3B0aW9ucy5hdXRoSW5zdGFuY2VcbiAgfVxuXG4gIC8qKlxuICAgKiDkvb/nlKjoh6rlrprkuYnnmbvlvZXlh63mja4gdGlja2V0IOeZu+W9leS6keW8gOWPkVxuICAgKiBAcGFyYW0gdGlja2V0IOiHquWumuS5ieeZu+W9lSB0aWNrZXRcbiAgICogQGRlcHJlY2F0ZWQgdjEg5YW85a65IEFQSeOAguW7uuiuruS9v+eUqCBhdXRoLnNpZ25JbldpdGhDdXN0b21UaWNrZXQoKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHRpY2tldCkpIOabv+S7o+OAglxuICAgKi9cbiAgcHVibGljIGFzeW5jIHNpZ25Jbih0aWNrZXQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIOS9v+eUqCBBdXRoIOW3suacieeahCBzaWduSW5XaXRoQ3VzdG9tVGlja2V0IOaWueazlVxuICAgIGF3YWl0IHRoaXMuYXV0aEluc3RhbmNlLnNpZ25JbldpdGhDdXN0b21UaWNrZXQoKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHRpY2tldCkpXG4gIH1cbn1cblxuLyoqXG4gKiB2MSDljL/lkI3nmbvlvZUgUHJvdmlkZXJcbiAqIOS9v+eUqOaWueW8jzogYXV0aC5hbm9ueW1vdXNBdXRoUHJvdmlkZXIoKS5zaWduSW4oKVxuICpcbiAqIEBkZXByZWNhdGVkIHYxIOWFvOWuuSBBUEnjgILlu7rorq7kvb/nlKggYXV0aC5zaWduSW5Bbm9ueW1vdXNseSh7fSkg5pu/5Luj44CCXG4gKi9cbmV4cG9ydCBjbGFzcyBBbm9ueW1vdXNBdXRoUHJvdmlkZXIge1xuICBwcml2YXRlIGF1dGhJbnN0YW5jZTogYW55XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczoge1xuICAgIGF1dGhJbnN0YW5jZTogYW55XG4gIH0pIHtcbiAgICB0aGlzLmF1dGhJbnN0YW5jZSA9IG9wdGlvbnMuYXV0aEluc3RhbmNlXG4gIH1cblxuICAvKipcbiAgICog5Yy/5ZCN55m75b2V5LqR5byA5Y+RXG4gICAqIEBkZXByZWNhdGVkIHYxIOWFvOWuuSBBUEnjgILlu7rorq7kvb/nlKggYXV0aC5zaWduSW5Bbm9ueW1vdXNseSh7fSkg5pu/5Luj44CCXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc2lnbkluKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIOS9v+eUqCBBdXRoIOW3suacieeahCBzaWduSW5Bbm9ueW1vdXNseSDmlrnms5VcbiAgICBhd2FpdCB0aGlzLmF1dGhJbnN0YW5jZS5zaWduSW5Bbm9ueW1vdXNseSh7fSlcbiAgfVxufVxuXG4vLyA9PT09PT09PT09IEF1dGggdjEg5YW85a655Z+657G7ID09PT09PT09PT1cblxuLyoqXG4gKiBBdXRoVjFDb21wYXQg5Z+657G777yM5o+Q5L6bIHYxIOeJiOacrOeahOWFvOWuuSBBUEkg5pa55rOV44CCXG4gKiBBdXRoIOexu+mAmui/hyBleHRlbmRzIEF1dGhWMUNvbXBhdCDmnaXnu6fmib/ov5nkupvmlrnms5XjgIJcbiAqXG4gKiDms6jmhI/vvJrmraTnsbvkuK3nmoTmlrnms5XpgJrov4cgdGhpcyDorr/pl67lrZDnsbsgQXV0aCDnmoTmlrnms5XlkozlsZ7mgKfvvIxcbiAqIOWMheaLrDogc2lnbkluLCBzaWduVXAsIHNpZ25JbldpdGhDdXN0b21UaWNrZXQsIHNpZ25JbkFub255bW91c2x5LFxuICogZ2V0VmVyaWZpY2F0aW9uLCByZXNldFBhc3N3b3JkLCBvbkxvZ2luU3RhdGVDaGFuZ2VkLCBvbkF1dGhTdGF0ZUNoYW5nZSxcbiAqIGNyZWF0ZUxvZ2luU3RhdGUsIGZvcm1hdFBob25lLCBjb25maWcsIHNpZ25JbldpdGhPQXV0aCDnrYnjgIJcbiAqL1xuLy8gZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L21lbWJlci1vcmRlcmluZyAtLSBhYnN0cmFjdCDln7rnsbvkuK0gYWJzdHJhY3Qg5aOw5piO5LiOIHB1YmxpYyDmlrnms5XmjpLluo/kuI3pgILnlKjluLjop4Top4TliJlcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBdXRoVjFDb21wYXQge1xuICBhYnN0cmFjdCByZWFkb25seSBjb25maWc6IGFueVxuXG4gIC8vID09PT09PT09PT0gdjEg5YW85a65IEFQSSDmlrnms5UgPT09PT09PT09PVxuXG4gIC8qKlxuICAgKiB2MSBBUEk6IOiOt+WPlueUqOS6juW+ruS/oeeZu+W9leeahCBXZWl4aW5BdXRoUHJvdmlkZXIgLy8gY3NwZWxsOmlnbm9yZSB3ZWl4aW4gV2VpeGluXG4gICAqIEBkZXByZWNhdGVkIOW7uuiuruS9v+eUqCBhdXRoLnNpZ25JbldpdGhPQXV0aCh7IHByb3ZpZGVyOiBhcHBpZCB9KSDmm7/ku6PjgIJcbiAgICovXG4gIHB1YmxpYyB3ZWl4aW5BdXRoUHJvdmlkZXIob3B0aW9uczogeyBhcHBpZDogc3RyaW5nOyBzY29wZTogc3RyaW5nIH0pOiBXZWl4aW5BdXRoUHJvdmlkZXIge1xuICAgIHJldHVybiBuZXcgV2VpeGluQXV0aFByb3ZpZGVyKHtcbiAgICAgIGF1dGhJbnN0YW5jZTogdGhpcyxcbiAgICAgIGFwcGlkOiBvcHRpb25zLmFwcGlkLFxuICAgICAgc2NvcGU6IG9wdGlvbnMuc2NvcGUsXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiB2MSBBUEk6IOiOt+WPlueUqOS6juiHquWumuS5ieeZu+W9leeahCBDdXN0b21BdXRoUHJvdmlkZXJcbiAgICogQGRlcHJlY2F0ZWQg5bu66K6u5L2/55SoIGF1dGguc2lnbkluV2l0aEN1c3RvbVRpY2tldCgoKSA9PiBQcm9taXNlLnJlc29sdmUodGlja2V0KSkg5pu/5Luj44CCXG4gICAqL1xuICBwdWJsaWMgY3VzdG9tQXV0aFByb3ZpZGVyKCk6IEN1c3RvbUF1dGhQcm92aWRlciB7XG4gICAgcmV0dXJuIG5ldyBDdXN0b21BdXRoUHJvdmlkZXIoe1xuICAgICAgYXV0aEluc3RhbmNlOiB0aGlzLFxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogdjEgQVBJOiDojrflj5bnlKjkuo7ljL/lkI3nmbvlvZXnmoQgQW5vbnltb3VzQXV0aFByb3ZpZGVyXG4gICAqIEBkZXByZWNhdGVkIOW7uuiuruS9v+eUqCBhdXRoLnNpZ25JbkFub255bW91c2x5KHt9KSDmm7/ku6PjgIJcbiAgICovXG4gIHB1YmxpYyBhbm9ueW1vdXNBdXRoUHJvdmlkZXIoKTogQW5vbnltb3VzQXV0aFByb3ZpZGVyIHtcbiAgICByZXR1cm4gbmV3IEFub255bW91c0F1dGhQcm92aWRlcih7XG4gICAgICBhdXRoSW5zdGFuY2U6IHRoaXMsXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiB2MSBBUEk6IOS9v+eUqOmCrueuseWSjOWvhueggeazqOWGjOS6keW8gOWPkei0puaIt1xuICAgKiBAZGVwcmVjYXRlZCDlu7rorq7kvb/nlKggYXV0aC5zaWduVXAoeyBlbWFpbCwgcGFzc3dvcmQgfSkg5pu/5Luj44CCXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc2lnblVwV2l0aEVtYWlsQW5kUGFzc3dvcmQoZW1haWw6IHN0cmluZywgcGFzc3dvcmQ6IHN0cmluZyk6IFByb21pc2U8U2lnblVwUmVzPiB7XG4gICAgaWYgKHR5cGVvZiBlbWFpbCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93RXJyb3IoRVJST1JTLklOVkFMSURfUEFSQU1TLCAnZW1haWwgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgcGFzc3dvcmQgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvd0Vycm9yKEVSUk9SUy5JTlZBTElEX1BBUkFNUywgJ3Bhc3N3b3JkIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cblxuICAgIC8vIOS9v+eUqCBBdXRoIOW3suacieeahCBzaWduVXAg5pa55rOVXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuc2lnblVwKHtcbiAgICAgIGVtYWlsLFxuICAgICAgcGFzc3dvcmQsXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiB2MSBBUEk6IOS9v+eUqOmCrueuseWSjOWvhueggeeZu+W9leS6keW8gOWPkVxuICAgKiBAZGVwcmVjYXRlZCDlu7rorq7kvb/nlKggYXV0aC5zaWduSW5XaXRoUGFzc3dvcmQoeyBlbWFpbCwgcGFzc3dvcmQgfSkg5pu/5Luj44CCXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc2lnbkluV2l0aEVtYWlsQW5kUGFzc3dvcmQoZW1haWw6IHN0cmluZywgcGFzc3dvcmQ6IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKHR5cGVvZiBlbWFpbCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93RXJyb3IoRVJST1JTLklOVkFMSURfUEFSQU1TLCAnZW1haWwgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgcGFzc3dvcmQgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvd0Vycm9yKEVSUk9SUy5JTlZBTElEX1BBUkFNUywgJ3Bhc3N3b3JkIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cblxuICAgIC8vIOS9v+eUqCBBdXRoIOW3suacieeahCBzaWduSW4g5pa55rOVXG4gICAgYXdhaXQgdGhpcy5zaWduSW4oe1xuICAgICAgdXNlcm5hbWU6IGVtYWlsLFxuICAgICAgcGFzc3dvcmQsXG4gICAgfSlcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVMb2dpblN0YXRlKClcbiAgfVxuXG4gIC8qKlxuICAgKiB2MSBBUEk6IOWPkemAgemHjee9ruWvhueggeeahOmCruS7tlxuICAgKiBAZGVwcmVjYXRlZCDlu7rorq7kvb/nlKggYXV0aC5yZXNldFBhc3N3b3JkRm9yRW1haWwoZW1haWwpIOabv+S7o+OAglxuICAgKi9cbiAgcHVibGljIGFzeW5jIHNlbmRQYXNzd29yZFJlc2V0RW1haWwoZW1haWw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0eXBlb2YgZW1haWwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvd0Vycm9yKEVSUk9SUy5JTlZBTElEX1BBUkFNUywgJ2VtYWlsIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cblxuICAgIC8vIOS9v+eUqCBBdXRoIOW3suacieeahCBnZXRWZXJpZmljYXRpb24g5pa55rOVXG4gICAgYXdhaXQgdGhpcy5nZXRWZXJpZmljYXRpb24oeyBlbWFpbCB9KVxuICB9XG5cbiAgLyoqXG4gICAqIHYxIEFQSTog5L2/55So55So5oi35ZCN5a+G56CB55m75b2V5LqR5byA5Y+RXG4gICAqIEBkZXByZWNhdGVkIOW7uuiuruS9v+eUqCBhdXRoLnNpZ25JbldpdGhQYXNzd29yZCh7IHVzZXJuYW1lLCBwYXNzd29yZCB9KSDmm7/ku6PjgIJcbiAgICovXG4gIHB1YmxpYyBhc3luYyBzaWduSW5XaXRoVXNlcm5hbWVBbmRQYXNzd29yZCh1c2VybmFtZTogc3RyaW5nLCBwYXNzd29yZDogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICBpZiAodHlwZW9mIHVzZXJuYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3dFcnJvcihFUlJPUlMuSU5WQUxJRF9QQVJBTVMsICd1c2VybmFtZSBtdXN0IGJlIGEgc3RyaW5nJylcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwYXNzd29yZCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93RXJyb3IoRVJST1JTLklOVkFMSURfUEFSQU1TLCAncGFzc3dvcmQgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuXG4gICAgLy8g5L2/55SoIEF1dGgg5bey5pyJ55qEIHNpZ25JbiDmlrnms5VcbiAgICBhd2FpdCB0aGlzLnNpZ25Jbih7XG4gICAgICB1c2VybmFtZSxcbiAgICAgIHBhc3N3b3JkLFxuICAgIH0pXG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlTG9naW5TdGF0ZSgpXG4gIH1cblxuICAvKipcbiAgICogdjEgQVBJOiDlj5HpgIHmiYvmnLrpqozor4HnoIFcbiAgICogQGRlcHJlY2F0ZWQg5bu66K6u5L2/55SoIGF1dGguc2lnbkluV2l0aE90cCh7IHBob25lIH0pIOaIliBhdXRoLmdldFZlcmlmaWNhdGlvbih7IHBob25lX251bWJlciB9KSDmm7/ku6PjgIJcbiAgICovXG4gIHB1YmxpYyBhc3luYyBzZW5kUGhvbmVDb2RlKHBob25lTnVtYmVyOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAodHlwZW9mIHBob25lTnVtYmVyICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3dFcnJvcihFUlJPUlMuSU5WQUxJRF9QQVJBTVMsICdwaG9uZU51bWJlciBtdXN0IGJlIGEgc3RyaW5nJylcbiAgICB9XG5cbiAgICAvLyDkvb/nlKggQXV0aCDlt7LmnInnmoQgZ2V0VmVyaWZpY2F0aW9uIOaWueazlVxuICAgIGNvbnN0IGZvcm1hdHRlZFBob25lID0gdGhpcy5mb3JtYXRQaG9uZShwaG9uZU51bWJlcilcbiAgICBhd2FpdCB0aGlzLmdldFZlcmlmaWNhdGlvbih7IHBob25lX251bWJlcjogZm9ybWF0dGVkUGhvbmUgfSlcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIHYxIEFQSTog5omL5py65Y+35rOo5YaM77yI5pSv5oyB55+t5L+h6aqM6K+B56CBK+WvhueggeaWueW8j++8iVxuICAgKiBAZGVwcmVjYXRlZCDlu7rorq7kvb/nlKggYXV0aC5zaWduVXAoeyBwaG9uZV9udW1iZXIsIHZlcmlmaWNhdGlvbl9jb2RlLCBwYXNzd29yZD8gfSkg5pu/5Luj44CCXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc2lnblVwV2l0aFBob25lQ29kZShwaG9uZU51bWJlcjogc3RyaW5nLCBwaG9uZUNvZGU6IHN0cmluZywgcGFzc3dvcmQ/OiBzdHJpbmcpOiBQcm9taXNlPGFueT4ge1xuICAgIGlmICh0eXBlb2YgcGhvbmVOdW1iZXIgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvd0Vycm9yKEVSUk9SUy5JTlZBTElEX1BBUkFNUywgJ3Bob25lTnVtYmVyIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHBob25lQ29kZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93RXJyb3IoRVJST1JTLklOVkFMSURfUEFSQU1TLCAncGhvbmVDb2RlIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cblxuICAgIGNvbnN0IGZvcm1hdHRlZFBob25lID0gdGhpcy5mb3JtYXRQaG9uZShwaG9uZU51bWJlcilcblxuICAgIC8vIOS9v+eUqCBBdXRoIOW3suacieeahCBzaWduVXAg5pa55rOVXG4gICAgYXdhaXQgdGhpcy5zaWduVXAoe1xuICAgICAgcGhvbmVfbnVtYmVyOiBmb3JtYXR0ZWRQaG9uZSxcbiAgICAgIHZlcmlmaWNhdGlvbl9jb2RlOiBwaG9uZUNvZGUsXG4gICAgICAuLi4ocGFzc3dvcmQgPyB7IHBhc3N3b3JkIH0gOiB7fSksXG4gICAgfSlcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVMb2dpblN0YXRlKClcbiAgfVxuXG4gIC8qKlxuICAgKiB2MSBBUEk6IOaJi+acuuWPt+eZu+W9le+8iOaUr+aMgeefreS/oemqjOivgeeggSBvciDlr4bnoIHmlrnlvI/vvIlcbiAgICogQGRlcHJlY2F0ZWQg5a+G56CB5pa55byP5bu66K6u5L2/55SoIGF1dGguc2lnbkluV2l0aFBhc3N3b3JkKHsgcGhvbmUsIHBhc3N3b3JkIH0pIOabv+S7o++8m1xuICAgKiDpqozor4HnoIHmlrnlvI/lu7rorq7kvb/nlKggYXV0aC5zaWduSW5XaXRoT3RwKHsgcGhvbmUgfSkg5pu/5Luj44CCXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc2lnbkluV2l0aFBob25lQ29kZU9yUGFzc3dvcmQocGFyYW1zOiB7XG4gICAgcGhvbmVOdW1iZXI6IHN0cmluZ1xuICAgIHBob25lQ29kZT86IHN0cmluZ1xuICAgIHBhc3N3b3JkPzogc3RyaW5nXG4gIH0pOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IHsgcGhvbmVOdW1iZXIsIHBob25lQ29kZSwgcGFzc3dvcmQgfSA9IHBhcmFtc1xuICAgIGlmICh0eXBlb2YgcGhvbmVOdW1iZXIgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvd0Vycm9yKEVSUk9SUy5JTlZBTElEX1BBUkFNUywgJ3Bob25lTnVtYmVyIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cblxuICAgIGNvbnN0IGZvcm1hdHRlZFBob25lID0gdGhpcy5mb3JtYXRQaG9uZShwaG9uZU51bWJlcilcblxuICAgIGlmIChwYXNzd29yZCkge1xuICAgICAgLy8g5L2/55SoIEF1dGgg5bey5pyJ55qEIHNpZ25JbiDmlrnms5Xov5vooYzlr4bnoIHnmbvlvZVcbiAgICAgIGF3YWl0IHRoaXMuc2lnbkluKHtcbiAgICAgICAgdXNlcm5hbWU6IGZvcm1hdHRlZFBob25lLFxuICAgICAgICBwYXNzd29yZCxcbiAgICAgIH0pXG4gICAgfSBlbHNlIGlmIChwaG9uZUNvZGUpIHtcbiAgICAgIC8vIOS9v+eUqCBBdXRoIOW3suacieeahCBzaWduSW4g5pa55rOV6L+b6KGM6aqM6K+B56CB55m75b2VXG4gICAgICBhd2FpdCB0aGlzLnNpZ25Jbih7XG4gICAgICAgIHVzZXJuYW1lOiBmb3JtYXR0ZWRQaG9uZSxcbiAgICAgICAgdmVyaWZpY2F0aW9uX3Rva2VuOiBwaG9uZUNvZGUsXG4gICAgICB9IGFzIGFueSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3dFcnJvcihFUlJPUlMuSU5WQUxJRF9QQVJBTVMsICdwaG9uZUNvZGUgb3IgcGFzc3dvcmQgbXVzdCBiZSBwcm92aWRlZCcpXG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNyZWF0ZUxvZ2luU3RhdGUoKVxuICB9XG5cbiAgLyoqXG4gICAqIHYxIEFQSTog5omL5py65Y+35by65Yi26YeN572u5a+G56CBXG4gICAqIEBkZXByZWNhdGVkIOW7uuiuruS9v+eUqCBhdXRoLnJlc2V0UGFzc3dvcmRGb3JFbWFpbChwaG9uZU51bWJlcikg5pu/5Luj44CCXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZm9yY2VSZXNldFB3ZEJ5UGhvbmVDb2RlKHBhcmFtczoge1xuICAgIHBob25lTnVtYmVyOiBzdHJpbmdcbiAgICBwaG9uZUNvZGU6IHN0cmluZ1xuICAgIHBhc3N3b3JkOiBzdHJpbmdcbiAgfSk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgeyBwaG9uZU51bWJlciwgcGhvbmVDb2RlLCBwYXNzd29yZCB9ID0gcGFyYW1zXG4gICAgaWYgKHR5cGVvZiBwaG9uZU51bWJlciAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93RXJyb3IoRVJST1JTLklOVkFMSURfUEFSQU1TLCAncGhvbmVOdW1iZXIgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgcGhvbmVDb2RlICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3dFcnJvcihFUlJPUlMuSU5WQUxJRF9QQVJBTVMsICdwaG9uZUNvZGUgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgcGFzc3dvcmQgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvd0Vycm9yKEVSUk9SUy5JTlZBTElEX1BBUkFNUywgJ3Bhc3N3b3JkIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cblxuICAgIGNvbnN0IGZvcm1hdHRlZFBob25lID0gdGhpcy5mb3JtYXRQaG9uZShwaG9uZU51bWJlcilcblxuICAgIC8vIOS9v+eUqCBBdXRoIOW3suacieeahCByZXNldFBhc3N3b3JkIOaWueazlVxuICAgIGF3YWl0IHRoaXMucmVzZXRQYXNzd29yZCh7XG4gICAgICBwaG9uZV9udW1iZXI6IGZvcm1hdHRlZFBob25lLFxuICAgICAgbmV3X3Bhc3N3b3JkOiBwYXNzd29yZCxcbiAgICAgIHZlcmlmaWNhdGlvbl90b2tlbjogcGhvbmVDb2RlLFxuICAgIH0pXG5cbiAgICAvLyDph43nva7lr4bnoIHmiJDlip/lkI7kvb/nlKggQXV0aCDlt7LmnInnmoQgc2lnbkluIOaWueazleiHquWKqOeZu+W9lVxuICAgIGF3YWl0IHRoaXMuc2lnbkluKHtcbiAgICAgIHVzZXJuYW1lOiBmb3JtYXR0ZWRQaG9uZSxcbiAgICAgIHBhc3N3b3JkLFxuICAgIH0pXG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlTG9naW5TdGF0ZSgpXG4gIH1cblxuICAvKipcbiAgICogdjEgQVBJOiDmjqXmlLbkuIDkuKrlm57osIPlh73mlbDvvIzlnKjliLfmlrDnn63mnJ/orr/pl67ku6TniYzliY3osIPnlKjvvIzmoLnmja7ov5Tlm57lgLzlhrPlrprmmK/lkKbliLfmlrBcbiAgICogQGRlcHJlY2F0ZWQgdjEg5YW85a65IEFQSe+8jOW9k+WJjSB2MyBTREsg5Lit5peg55u05o6l5a+55bqU5pa55rOV44CCXG4gICAqIOW7uuiuruS9v+eUqCBhdXRoLm9uQXV0aFN0YXRlQ2hhbmdlKGNhbGxiYWNrKSDnm5HlkKwgVE9LRU5fUkVGUkVTSEVEIOS6i+S7tuabv+S7o+OAglxuICAgKi9cbiAgcHVibGljIHNob3VsZFJlZnJlc2hBY2Nlc3NUb2tlbihfY2FsbGJhY2s6ICgpID0+IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1t2MSDlhbzlrrldIHNob3VsZFJlZnJlc2hBY2Nlc3NUb2tlbigpIOWcqOW9k+WJjeeJiOacrOS4reaXoOazleWunueOsOOAgidcbiAgICAgICsgJyDlu7rorq7kvb/nlKggYXV0aC5vbkF1dGhTdGF0ZUNoYW5nZShjYWxsYmFjaykg5p2l55uR5ZCsIFRPS0VOX1JFRlJFU0hFRCDkuovku7bmm7/ku6PjgIInLClcbiAgfVxuXG4gIC8qKlxuICAgKiB2MSBBUEk6IOaOpeaUtuS4gOS4quWbnuiwg+WHveaVsO+8jOWcqOeZu+W9leeKtuaAgei/h+acn+aXtuiwg+eUqFxuICAgKiBAZGVwcmVjYXRlZCDlu7rorq7kvb/nlKggYXV0aC5vbkF1dGhTdGF0ZUNoYW5nZShjYWxsYmFjaykg5pu/5Luj77yM55uR5ZCsIFNJR05FRF9PVVQg5LqL5Lu244CCXG4gICAqL1xuICBwdWJsaWMgb25Mb2dpblN0YXRlRXhwaXJlZChjYWxsYmFjazogRnVuY3Rpb24pOiB2b2lkIHtcbiAgICAvLyDkvb/nlKggQXV0aCDlt7LmnInnmoQgb25Mb2dpblN0YXRlQ2hhbmdlZCDmlrnms5VcbiAgICB0aGlzLm9uTG9naW5TdGF0ZUNoYW5nZWQoKHBhcmFtcykgPT4ge1xuICAgICAgaWYgKHBhcmFtcz8uZXZlbnRUeXBlID09PSBMT0dJTl9TVEFURV9DSEFOR0VEX1RZUEUuQ1JFREVOVElBTFNfRVJST1IpIHtcbiAgICAgICAgY2FsbGJhY2suY2FsbCh0aGlzKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogdjEgQVBJOiDmjqXmlLbkuIDkuKrlm57osIPlh73mlbDvvIzlnKjnn63mnJ/orr/pl67ku6TniYzliLfmlrDlkI7osIPnlKhcbiAgICogQGRlcHJlY2F0ZWQg5bu66K6u5L2/55SoIGF1dGgub25BdXRoU3RhdGVDaGFuZ2UoY2FsbGJhY2spIOabv+S7o++8jOebkeWQrCBUT0tFTl9SRUZSRVNIRUQg5LqL5Lu244CCXG4gICAqL1xuICBwdWJsaWMgb25BY2Nlc3NUb2tlblJlZnJlc2hlZChjYWxsYmFjazogRnVuY3Rpb24pOiB2b2lkIHtcbiAgICAvLyDkvb/nlKggQXV0aCDlt7LmnInnmoQgb25BdXRoU3RhdGVDaGFuZ2Ug5pa55rOVXG4gICAgdGhpcy5vbkF1dGhTdGF0ZUNoYW5nZSgoZXZlbnQpID0+IHtcbiAgICAgIGlmIChldmVudCA9PT0gQVVUSF9TVEFURV9DSEFOR0VEX1RZUEUuVE9LRU5fUkVGUkVTSEVEKSB7XG4gICAgICAgIGNhbGxiYWNrLmNhbGwodGhpcylcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIHYxIEFQSTog5o6l5pS25LiA5Liq5Zue6LCD5Ye95pWw77yM5Zyo5Yy/5ZCN55m75b2V54q25oCB6KKr6L2s5o2i5ZCO6LCD55SoXG4gICAqIEBkZXByZWNhdGVkIOW7uuiuruS9v+eUqCBhdXRoLm9uQXV0aFN0YXRlQ2hhbmdlKGNhbGxiYWNrKSDmm7/ku6PvvIznm5HlkKwgU0lHTkVEX0lOIOS6i+S7tuOAglxuICAgKi9cbiAgcHVibGljIG9uQW5vbnltb3VzQ29udmVydGVkKGNhbGxiYWNrOiBGdW5jdGlvbik6IHZvaWQge1xuICAgIC8vIOS9v+eUqCBBdXRoIOW3suacieeahCBvbkF1dGhTdGF0ZUNoYW5nZSDmlrnms5VcbiAgICB0aGlzLm9uQXV0aFN0YXRlQ2hhbmdlKChldmVudCkgPT4ge1xuICAgICAgaWYgKGV2ZW50ID09PSBBVVRIX1NUQVRFX0NIQU5HRURfVFlQRS5TSUdORURfSU4pIHtcbiAgICAgICAgY2FsbGJhY2suY2FsbCh0aGlzKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogdjEgQVBJOiDmjqXmlLbkuIDkuKrlm57osIPlh73mlbDvvIzlnKjnmbvlvZXnsbvlnovlj5HnlJ/lj5jljJblkI7osIPnlKhcbiAgICogQGRlcHJlY2F0ZWQg5bu66K6u5L2/55SoIGF1dGgub25BdXRoU3RhdGVDaGFuZ2UoY2FsbGJhY2spIOabv+S7o++8jOebkeWQrCBTSUdORURfSU4gLyBTSUdORURfT1VUIOS6i+S7tuOAglxuICAgKi9cbiAgcHVibGljIG9uTG9naW5UeXBlQ2hhbmdlZChjYWxsYmFjazogRnVuY3Rpb24pOiB2b2lkIHtcbiAgICAvLyDkvb/nlKggQXV0aCDlt7LmnInnmoQgb25BdXRoU3RhdGVDaGFuZ2Ug5pa55rOVXG4gICAgdGhpcy5vbkF1dGhTdGF0ZUNoYW5nZSgoZXZlbnQpID0+IHtcbiAgICAgIGlmIChldmVudCA9PT0gQVVUSF9TVEFURV9DSEFOR0VEX1RZUEUuU0lHTkVEX0lOIHx8IGV2ZW50ID09PSBBVVRIX1NUQVRFX0NIQU5HRURfVFlQRS5TSUdORURfT1VUKSB7XG4gICAgICAgIGNhbGxiYWNrLmNhbGwodGhpcylcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLy8gPT09PT09PT09PSDlo7DmmI7lrZDnsbsgQXV0aCDpnIDopoHmj5DkvpvnmoTmlrnms5Uv5bGe5oCnID09PT09PT09PT1cbiAgYWJzdHJhY3Qgc2lnbkluKHBhcmFtczogYXV0aE1vZGVscy5TaWduSW5SZXF1ZXN0KTogUHJvbWlzZTxhbnk+XG4gIGFic3RyYWN0IHNpZ25VcChwYXJhbXM6IGF1dGhNb2RlbHMuU2lnblVwUmVxdWVzdCAmIHsgcGhvbmU/OiBzdHJpbmcgfSk6IFByb21pc2U8U2lnblVwUmVzPlxuICBhYnN0cmFjdCBzaWduSW5XaXRoQ3VzdG9tVGlja2V0KGdldFRpY2tGbj86IGF1dGhNb2RlbHMuR2V0Q3VzdG9tU2lnblRpY2tldEZuKTogUHJvbWlzZTxhbnk+XG4gIGFic3RyYWN0IHNpZ25JbkFub255bW91c2x5KHBhcmFtczogYW55KTogUHJvbWlzZTxhbnk+XG4gIGFic3RyYWN0IGdldFZlcmlmaWNhdGlvbihwYXJhbXM6IGFueSwgb3B0aW9ucz86IGFueSk6IFByb21pc2U8YXV0aE1vZGVscy5HZXRWZXJpZmljYXRpb25SZXNwb25zZT5cbiAgYWJzdHJhY3QgcmVzZXRQYXNzd29yZChwYXJhbXM6IGF1dGhNb2RlbHMuUmVzZXRQYXNzd29yZFJlcXVlc3QpOiBQcm9taXNlPHZvaWQ+XG4gIGFic3RyYWN0IG9uTG9naW5TdGF0ZUNoYW5nZWQoY2FsbGJhY2s6IEZ1bmN0aW9uKTogUHJvbWlzZTx2b2lkPlxuICBhYnN0cmFjdCBvbkF1dGhTdGF0ZUNoYW5nZShjYWxsYmFjazogYW55KTogYW55XG4gIGFic3RyYWN0IGNyZWF0ZUxvZ2luU3RhdGUocGFyYW1zPzogYW55LCBvcHRpb25zPzogYW55KTogUHJvbWlzZTxhbnk+XG4gIGFic3RyYWN0IHNpZ25JbldpdGhPQXV0aChwYXJhbXM6IGFueSk6IFByb21pc2U8YW55PlxuICBhYnN0cmFjdCBncmFudFByb3ZpZGVyVG9rZW4ocGFyYW1zOiBhdXRoTW9kZWxzLkdyYW50UHJvdmlkZXJUb2tlblJlcXVlc3QpOiBQcm9taXNlPGF1dGhNb2RlbHMuR3JhbnRQcm92aWRlclRva2VuUmVzcG9uc2U+XG4gIGFic3RyYWN0IGJpbmRXaXRoUHJvdmlkZXIocGFyYW1zOiBhdXRoTW9kZWxzLkJpbmRXaXRoUHJvdmlkZXJSZXF1ZXN0KTogUHJvbWlzZTx2b2lkPlxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZm9ybWF0UGhvbmUocGhvbmU6IHN0cmluZyk6IHN0cmluZ1xufVxuXG4vLyA9PT09PT09PT09IFVzZXIgdjEg5YW85a65IG1peGluID09PT09PT09PT1cblxuLyoqXG4gKiDlsIYgdjEg5YW85a655pa55rOV5bqU55So5YiwIFVzZXIg57G755qEIHByb3RvdHlwZSDkuIrjgIJcbiAqIOWcqCBpbmRleC50cyDkuK3osIPnlKg6IGFwcGx5VXNlclYxQ29tcGF0KFVzZXIpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVVzZXJWMUNvbXBhdChVc2VyQ2xhc3M6IGFueSk6IHZvaWQge1xuICAvKipcbiAgICogdjEgQVBJOiDlsIblvZPliY3otKbmiLfkuI7oh6rlrprkuYnnmbvlvZUgVGlja2V0IOi/m+ihjOe7keWumlxuICAgKiBAZGVwcmVjYXRlZCB2MSDlhbzlrrkgQVBJ77yM5b2T5YmN54mI5pys5Lit5peg5rOV55u05o6l5a6e546w44CCXG4gICAqIOW7uuiuruS9v+eUqCBhdXRoLnNpZ25JbldpdGhDdXN0b21UaWNrZXQoKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHRpY2tldCkpIOabv+S7o+OAglxuICAgKi9cbiAgVXNlckNsYXNzLnByb3RvdHlwZS5saW5rV2l0aFRpY2tldCA9IGFzeW5jIGZ1bmN0aW9uIChfdGlja2V0OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1t2MSDlhbzlrrldIFVzZXIubGlua1dpdGhUaWNrZXQoKSDlnKjlvZPliY3niYjmnKzkuK3ml6Dms5Xlrp7njrDjgIInXG4gICAgICArICcg5bu66K6u5L2/55SoIGF1dGguc2lnbkluV2l0aEN1c3RvbVRpY2tldCgoKSA9PiBQcm9taXNlLnJlc29sdmUodGlja2V0KSkg5pu/5Luj44CCJywpXG4gIH1cblxuICAvKipcbiAgICogdjEgQVBJOiDlsIblvZPliY3otKbmiLfkuI7nrKzkuInmlrnpibTmnYPmj5DkvpvmlrnvvIjku6Xph43lrprlkJHlvaLlvI/vvInov5vooYznu5HlrppcbiAgICogQGRlcHJlY2F0ZWQg5bu66K6u5L2/55SoIGF1dGgubGlua0lkZW50aXR5KHsgcHJvdmlkZXI6ICdwcm92aWRlcklkJyB9KSDmm7/ku6PjgIJcbiAgICovXG4gIFVzZXJDbGFzcy5wcm90b3R5cGUubGlua1dpdGhSZWRpcmVjdCA9IGZ1bmN0aW9uIChfcHJvdmlkZXI6IGFueSk6IHZvaWQge1xuICAgIHRocm93IG5ldyBFcnJvcignW3YxIOWFvOWuuV0gVXNlci5saW5rV2l0aFJlZGlyZWN0KCkg5Zyo5b2T5YmN54mI5pys5Lit5peg5rOV5a6e546w44CCJ1xuICAgICAgKyAnIOW7uuiuruS9v+eUqCBhdXRoLmxpbmtJZGVudGl0eSh7IHByb3ZpZGVyOiBcXCdwcm92aWRlcklkXFwnIH0pIOabv+S7o+OAgicsKVxuICB9XG5cbiAgLyoqXG4gICAqIHYxIEFQSTog5pu05paw5b2T5YmN55qE55m75b2V6YKu566xXG4gICAqIEBkZXByZWNhdGVkIOW7uuiuruS9v+eUqCBhdXRoLnVwZGF0ZVVzZXIoeyBlbWFpbDogbmV3RW1haWwgfSkg5pu/5Luj44CCXG4gICAqL1xuICBVc2VyQ2xhc3MucHJvdG90eXBlLnVwZGF0ZUVtYWlsID0gYXN5bmMgZnVuY3Rpb24gKG5ld0VtYWlsOiBzdHJpbmcsIF9wYXNzd29yZD86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0eXBlb2YgbmV3RW1haWwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvd0Vycm9yKEVSUk9SUy5JTlZBTElEX1BBUkFNUywgJ25ld0VtYWlsIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cblxuICAgIC8vIOS9v+eUqCBVc2VyIOW3suacieeahCB1cGRhdGVVc2VyQmFzaWNJbmZvIOaWueazlVxuICAgIGF3YWl0IHRoaXMudXBkYXRlVXNlckJhc2ljSW5mbyh7XG4gICAgICBlbWFpbDogbmV3RW1haWwsXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiB2MSBBUEk6IOe7keWumuaJi+acuuWPt1xuICAgKiBAZGVwcmVjYXRlZCB2MSDlhbzlrrkgQVBJ77yM5b2T5YmN54mI5pys5Lit5peg5rOV55u05o6l5ZyoIFVzZXIg5LiK5a6e546w44CCXG4gICAqIOW7uuiuruS9v+eUqCBhdXRoLmJpbmRQaG9uZU51bWJlcih7IHBob25lX251bWJlciwgdmVyaWZpY2F0aW9uX3Rva2VuLCBzdWRvX3Rva2VuIH0pIOabv+S7o+OAglxuICAgKi9cbiAgVXNlckNsYXNzLnByb3RvdHlwZS5saW5rV2l0aFBob25lTnVtYmVyID0gYXN5bmMgZnVuY3Rpb24gKF9waG9uZU51bWJlcjogc3RyaW5nLCBfcGhvbmVDb2RlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1t2MSDlhbzlrrldIFVzZXIubGlua1dpdGhQaG9uZU51bWJlcigpIOWcqOW9k+WJjeeJiOacrOS4reaXoOazleWunueOsOOAgidcbiAgICAgICsgJyDlu7rorq7kvb/nlKggYXV0aC5iaW5kUGhvbmVOdW1iZXIoeyBwaG9uZV9udW1iZXIsIHZlcmlmaWNhdGlvbl90b2tlbiwgc3Vkb190b2tlbiB9KSDmm7/ku6PjgIInLClcbiAgfVxuXG4gIC8qKlxuICAgKiB2MSBBUEk6IOabtOaWsOaJi+acuuWPt1xuICAgKiBAZGVwcmVjYXRlZCB2MSDlhbzlrrkgQVBJ77yM5b2T5YmN54mI5pys5Lit5peg5rOV55u05o6l5ZyoIFVzZXIg5LiK5a6e546w44CCXG4gICAqIOW7uuiuruS9v+eUqCBhdXRoLnVwZGF0ZVVzZXIoeyBwaG9uZTogbmV3UGhvbmVOdW1iZXIgfSkg5pu/5Luj44CCXG4gICAqL1xuICBVc2VyQ2xhc3MucHJvdG90eXBlLnVwZGF0ZVBob25lTnVtYmVyID0gYXN5bmMgZnVuY3Rpb24gKF9waG9uZU51bWJlcjogc3RyaW5nLCBfcGhvbmVDb2RlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1t2MSDlhbzlrrldIFVzZXIudXBkYXRlUGhvbmVOdW1iZXIoKSDlnKjlvZPliY3niYjmnKzkuK3ml6Dms5Xlrp7njrDjgIInXG4gICAgICArICcg5bu66K6u5L2/55SoIGF1dGgudXBkYXRlVXNlcih7IHBob25lOiBuZXdQaG9uZU51bWJlciB9KSDmm7/ku6PjgIInLClcbiAgfVxuXG4gIC8qKlxuICAgKiB2MSBBUEk6IOino+e7keafkOS4queZu+W9leaWueW8j1xuICAgKiBAZGVwcmVjYXRlZCB2MSDlhbzlrrkgQVBJ77yM5b2T5YmN54mI5pys5Lit5peg5rOV55u05o6l5ZyoIFVzZXIg5LiK5a6e546w44CCXG4gICAqIOW7uuiuruS9v+eUqCBhdXRoLnVubGlua0lkZW50aXR5KHsgcHJvdmlkZXI6IGxvZ2luVHlwZSB9KSDmm7/ku6PjgIJcbiAgICovXG4gIFVzZXJDbGFzcy5wcm90b3R5cGUudW5saW5rID0gYXN5bmMgZnVuY3Rpb24gKF9sb2dpblR5cGU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRocm93IG5ldyBFcnJvcignW3YxIOWFvOWuuV0gVXNlci51bmxpbmsoKSDlnKjlvZPliY3niYjmnKzkuK3ml6Dms5Xlrp7njrDjgIInXG4gICAgICArICcg5bu66K6u5L2/55SoIGF1dGgudW5saW5rSWRlbnRpdHkoeyBwcm92aWRlcjogbG9naW5UeXBlIH0pIOabv+S7o+OAgicsKVxuICB9XG59XG4iXX0=