@progalaxyelabs/ngx-stonescriptphp-client 1.0.0 → 1.1.0

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 (83) hide show
  1. package/HLD.md +31 -0
  2. package/LICENSE +21 -0
  3. package/README.md +89 -2
  4. package/{lib → dist}/api-connection.service.d.ts +1 -3
  5. package/dist/api-connection.service.d.ts.map +1 -0
  6. package/dist/api-connection.service.js +314 -0
  7. package/dist/api-connection.service.js.map +1 -0
  8. package/{lib → dist}/api-response.model.d.ts +1 -0
  9. package/dist/api-response.model.d.ts.map +1 -0
  10. package/dist/api-response.model.js +51 -0
  11. package/dist/api-response.model.js.map +1 -0
  12. package/dist/auth.service.d.ts +4 -0
  13. package/dist/auth.service.d.ts.map +1 -0
  14. package/dist/auth.service.js +16 -0
  15. package/dist/auth.service.js.map +1 -0
  16. package/{lib → dist}/csrf.service.d.ts +1 -3
  17. package/dist/csrf.service.d.ts.map +1 -0
  18. package/dist/csrf.service.js +47 -0
  19. package/dist/csrf.service.js.map +1 -0
  20. package/dist/db.service.d.ts +4 -0
  21. package/dist/db.service.d.ts.map +1 -0
  22. package/dist/db.service.js +16 -0
  23. package/dist/db.service.js.map +1 -0
  24. package/{fesm2022/progalaxyelabs-ngx-stonescriptphp-client.mjs → dist/esm/api-connection.service.js} +28 -276
  25. package/dist/esm/api-connection.service.js.map +1 -0
  26. package/dist/esm/api-response.model.js +47 -0
  27. package/dist/esm/api-response.model.js.map +1 -0
  28. package/dist/esm/auth.service.js +13 -0
  29. package/dist/esm/auth.service.js.map +1 -0
  30. package/dist/esm/csrf.service.js +44 -0
  31. package/dist/esm/csrf.service.js.map +1 -0
  32. package/dist/esm/db.service.js +13 -0
  33. package/dist/esm/db.service.js.map +1 -0
  34. package/dist/esm/index.js +13 -0
  35. package/dist/esm/index.js.map +1 -0
  36. package/dist/esm/my-environment.model.js +29 -0
  37. package/dist/esm/my-environment.model.js.map +1 -0
  38. package/dist/esm/ngx-stonescriptphp-client.module.js +25 -0
  39. package/dist/esm/ngx-stonescriptphp-client.module.js.map +1 -0
  40. package/dist/esm/signin-status.service.js +23 -0
  41. package/dist/esm/signin-status.service.js.map +1 -0
  42. package/dist/esm/token.service.js +61 -0
  43. package/dist/esm/token.service.js.map +1 -0
  44. package/dist/index.d.ts +10 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +16 -0
  47. package/dist/index.js.map +1 -0
  48. package/{lib → dist}/my-environment.model.d.ts +1 -0
  49. package/dist/my-environment.model.d.ts.map +1 -0
  50. package/dist/my-environment.model.js +33 -0
  51. package/dist/my-environment.model.js.map +1 -0
  52. package/dist/ngx-stonescriptphp-client.module.d.ts +6 -0
  53. package/dist/ngx-stonescriptphp-client.module.d.ts.map +1 -0
  54. package/dist/ngx-stonescriptphp-client.module.js +28 -0
  55. package/dist/ngx-stonescriptphp-client.module.js.map +1 -0
  56. package/{lib → dist}/signin-status.service.d.ts +1 -3
  57. package/dist/signin-status.service.d.ts.map +1 -0
  58. package/dist/signin-status.service.js +26 -0
  59. package/dist/signin-status.service.js.map +1 -0
  60. package/{lib → dist}/token.service.d.ts +1 -3
  61. package/dist/token.service.d.ts.map +1 -0
  62. package/dist/token.service.js +64 -0
  63. package/dist/token.service.js.map +1 -0
  64. package/docs/AUTH_COMPATIBILITY.md +310 -0
  65. package/docs/CHANGELOG.md +261 -0
  66. package/package.json +59 -18
  67. package/esm2022/lib/api-connection.service.mjs +0 -304
  68. package/esm2022/lib/api-response.model.mjs +0 -44
  69. package/esm2022/lib/auth.service.mjs +0 -14
  70. package/esm2022/lib/csrf.service.mjs +0 -46
  71. package/esm2022/lib/db.service.mjs +0 -14
  72. package/esm2022/lib/my-environment.model.mjs +0 -31
  73. package/esm2022/lib/ngx-stonescriptphp-client/ngx-stonescriptphp-client.module.mjs +0 -27
  74. package/esm2022/lib/signin-status.service.mjs +0 -23
  75. package/esm2022/lib/token.service.mjs +0 -63
  76. package/esm2022/progalaxyelabs-ngx-stonescriptphp-client.mjs +0 -5
  77. package/esm2022/public-api.mjs +0 -13
  78. package/fesm2022/progalaxyelabs-ngx-stonescriptphp-client.mjs.map +0 -1
  79. package/index.d.ts +0 -5
  80. package/lib/auth.service.d.ts +0 -6
  81. package/lib/db.service.d.ts +0 -6
  82. package/lib/ngx-stonescriptphp-client/ngx-stonescriptphp-client.module.d.ts +0 -10
  83. package/public-api.d.ts +0 -9
@@ -1,304 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { ApiResponse } from './api-response.model';
3
- import * as i0 from "@angular/core";
4
- import * as i1 from "./token.service";
5
- import * as i2 from "./signin-status.service";
6
- import * as i3 from "./my-environment.model";
7
- import * as i4 from "./csrf.service";
8
- export class ApiConnectionService {
9
- constructor(tokens, signinStatus, environment, csrf) {
10
- this.tokens = tokens;
11
- this.signinStatus = signinStatus;
12
- this.environment = environment;
13
- this.csrf = csrf;
14
- this.host = ''; // contains trailing slash
15
- this.accessToken = '';
16
- this.host = environment.apiServer.host;
17
- // Set default auth config based on mode
18
- this.authConfig = {
19
- mode: environment.auth?.mode || 'cookie',
20
- refreshEndpoint: environment.auth?.refreshEndpoint,
21
- useCsrf: environment.auth?.useCsrf,
22
- refreshTokenCookieName: environment.auth?.refreshTokenCookieName || 'refresh_token',
23
- csrfTokenCookieName: environment.auth?.csrfTokenCookieName || 'csrf_token',
24
- csrfHeaderName: environment.auth?.csrfHeaderName || 'X-CSRF-Token'
25
- };
26
- // Set default refresh endpoint based on mode if not specified
27
- if (!this.authConfig.refreshEndpoint) {
28
- this.authConfig.refreshEndpoint = this.authConfig.mode === 'cookie'
29
- ? '/auth/refresh'
30
- : '/user/refresh_access';
31
- }
32
- // Set default CSRF setting based on mode if not specified
33
- if (this.authConfig.useCsrf === undefined) {
34
- this.authConfig.useCsrf = this.authConfig.mode === 'cookie';
35
- }
36
- }
37
- async request(url, options, data) {
38
- try {
39
- if (data !== null) {
40
- const body = JSON.stringify(data);
41
- if (body) {
42
- options.body = body;
43
- }
44
- else {
45
- options.body = {};
46
- }
47
- }
48
- const accessTokenIncluded = this.includeAccessToken(options);
49
- let response = await fetch(url, options);
50
- if ((response.status === 401) && accessTokenIncluded) {
51
- response = await this.refreshAccessTokenAndRetry(url, options, response);
52
- }
53
- if (response.ok) {
54
- const json = await (response.json());
55
- return (new ApiResponse(json.status, json.data, json.message));
56
- }
57
- if (response.status === 401) {
58
- this.signinStatus.signedOut();
59
- }
60
- return this.handleError(response);
61
- }
62
- catch (error) {
63
- return this.handleError(error);
64
- }
65
- }
66
- handleError(error) {
67
- console.error(`Backend returned code ${error.status}, ` +
68
- `full error: `, error);
69
- return new ApiResponse('error');
70
- }
71
- async get(endpoint, queryParamsObj) {
72
- const url = this.host + endpoint.replace(/^\/+/, '') + this.buildQueryString(queryParamsObj);
73
- const fetchOptions = {
74
- mode: 'cors',
75
- redirect: 'error'
76
- };
77
- return this.request(url, fetchOptions, null);
78
- }
79
- async post(pathWithQueryParams, data) {
80
- const url = this.host + pathWithQueryParams.replace(/^\/+/, '');
81
- const fetchOptions = {
82
- method: 'POST',
83
- mode: 'cors',
84
- redirect: 'error',
85
- headers: {
86
- 'Content-Type': 'application/json'
87
- },
88
- body: JSON.stringify(data)
89
- };
90
- return this.request(url, fetchOptions, data);
91
- }
92
- async put(pathWithQueryParams, data) {
93
- const url = this.host + pathWithQueryParams.replace(/^\/+/, '');
94
- const fetchOptions = {
95
- method: 'PUT',
96
- mode: 'cors',
97
- redirect: 'error',
98
- headers: {
99
- 'Content-Type': 'application/json'
100
- },
101
- body: JSON.stringify(data)
102
- };
103
- return this.request(url, fetchOptions, data);
104
- }
105
- async patch(pathWithQueryParams, data) {
106
- const url = this.host + pathWithQueryParams.replace(/^\/+/, '');
107
- const fetchOptions = {
108
- method: 'PATCH',
109
- mode: 'cors',
110
- redirect: 'error',
111
- headers: {
112
- 'Content-Type': 'application/json'
113
- },
114
- body: JSON.stringify(data)
115
- };
116
- return this.request(url, fetchOptions, data);
117
- }
118
- async delete(endpoint, queryParamsObj) {
119
- const url = this.host + endpoint.replace(/^\/+/, '') + this.buildQueryString(queryParamsObj);
120
- const fetchOptions = {
121
- method: 'DELETE',
122
- mode: 'cors',
123
- redirect: 'error'
124
- };
125
- return this.request(url, fetchOptions, null);
126
- }
127
- // async postFormWithFiles(pathWithQueryParams: string, formData: FormData): Promise<ApiResponse | null> {
128
- // const url = this.host + pathWithQueryParams.replace(/^\/+/, '')
129
- // try {
130
- // const fetchOptions: RequestInit = {
131
- // method: 'POST',
132
- // mode: 'cors',
133
- // redirect: 'error',
134
- // body: formData
135
- // }
136
- // const accessTokenIncluded = this.includeAccessToken(fetchOptions)
137
- // let response: Response = await fetch(url, fetchOptions)
138
- // if ((response.status === 401) && accessTokenIncluded) {
139
- // response = await this.refreshAccessTokenAndRetry(url, fetchOptions, response)
140
- // }
141
- // if (response.ok) {
142
- // return ((await (response.json()) as ApiResponse))
143
- // }
144
- // return this.handleError(response)
145
- // } catch (error) {
146
- // return this.handleError(error)
147
- // }
148
- // }
149
- includeAccessToken(options) {
150
- this.accessToken = this.tokens.getAccessToken();
151
- if (!this.accessToken) {
152
- return false;
153
- }
154
- if (!options.headers) {
155
- options.headers = {};
156
- }
157
- options.headers['Authorization'] = 'Bearer ' + this.accessToken;
158
- return true;
159
- }
160
- async refreshAccessTokenAndRetry(url, fetchOptions, response) {
161
- const refreshStatusOk = await this.refreshAccessToken();
162
- if (!refreshStatusOk) {
163
- return response;
164
- }
165
- fetchOptions.headers['Authorization'] = 'Bearer ' + this.accessToken;
166
- response = await fetch(url, fetchOptions);
167
- return response;
168
- }
169
- async refreshAccessToken() {
170
- if (this.authConfig.mode === 'none') {
171
- return false;
172
- }
173
- if (this.authConfig.mode === 'cookie') {
174
- return await this.refreshAccessTokenCookieMode();
175
- }
176
- else {
177
- return await this.refreshAccessTokenBodyMode();
178
- }
179
- }
180
- /**
181
- * Refresh access token using cookie-based auth (StoneScriptPHP v2.1.x default)
182
- */
183
- async refreshAccessTokenCookieMode() {
184
- try {
185
- const refreshTokenUrl = this.host + this.authConfig.refreshEndpoint.replace(/^\/+/, '');
186
- const headers = {
187
- 'Content-Type': 'application/json'
188
- };
189
- // Add CSRF token if enabled
190
- if (this.authConfig.useCsrf) {
191
- const csrfToken = this.csrf.getCsrfToken(this.authConfig.csrfTokenCookieName);
192
- if (!csrfToken) {
193
- console.error('CSRF token not found in cookie');
194
- return false;
195
- }
196
- headers[this.authConfig.csrfHeaderName] = csrfToken;
197
- }
198
- let refreshTokenResponse = await fetch(refreshTokenUrl, {
199
- method: 'POST',
200
- mode: 'cors',
201
- credentials: 'include',
202
- redirect: 'error',
203
- headers: headers
204
- });
205
- if (!refreshTokenResponse.ok) {
206
- this.accessToken = '';
207
- this.tokens.clear();
208
- return false;
209
- }
210
- let refreshAccessData = await refreshTokenResponse.json();
211
- if (!refreshAccessData || refreshAccessData.status !== 'ok') {
212
- return false;
213
- }
214
- // Extract access token from response
215
- const newAccessToken = refreshAccessData.data?.access_token || refreshAccessData.access_token;
216
- if (!newAccessToken) {
217
- console.error('No access token in refresh response');
218
- return false;
219
- }
220
- // Store new access token (refresh token is in httpOnly cookie)
221
- this.tokens.setAccessToken(newAccessToken);
222
- this.accessToken = newAccessToken;
223
- return true;
224
- }
225
- catch (error) {
226
- console.error('Token refresh failed (cookie mode):', error);
227
- this.accessToken = '';
228
- this.tokens.clear();
229
- return false;
230
- }
231
- }
232
- /**
233
- * Refresh access token using body-based auth (legacy mode)
234
- */
235
- async refreshAccessTokenBodyMode() {
236
- try {
237
- const refreshToken = this.tokens.getRefreshToken();
238
- if (!refreshToken) {
239
- return false;
240
- }
241
- const refreshTokenUrl = this.host + this.authConfig.refreshEndpoint.replace(/^\/+/, '');
242
- let refreshTokenResponse = await fetch(refreshTokenUrl, {
243
- method: 'POST',
244
- mode: 'cors',
245
- redirect: 'error',
246
- headers: {
247
- 'Content-Type': 'application/json'
248
- },
249
- body: JSON.stringify({
250
- access_token: this.accessToken,
251
- refresh_token: refreshToken
252
- })
253
- });
254
- if (!refreshTokenResponse.ok) {
255
- this.accessToken = '';
256
- this.tokens.clear();
257
- return false;
258
- }
259
- let refreshAccessData = await refreshTokenResponse.json();
260
- if (!refreshAccessData) {
261
- return false;
262
- }
263
- const newAccessToken = refreshAccessData.data?.access_token || refreshAccessData.access_token;
264
- if (!newAccessToken) {
265
- console.error('No access token in refresh response');
266
- return false;
267
- }
268
- this.tokens.setTokens(newAccessToken, refreshToken);
269
- this.accessToken = newAccessToken;
270
- return true;
271
- }
272
- catch (error) {
273
- console.error('Token refresh failed (body mode):', error);
274
- this.accessToken = '';
275
- this.tokens.clear();
276
- return false;
277
- }
278
- }
279
- buildQueryString(options) {
280
- if (options === undefined) {
281
- return '';
282
- }
283
- const array = [];
284
- for (let key in options) {
285
- if (options.hasOwnProperty(key) && (options[key] !== null) && (options[key] !== undefined)) {
286
- array.push(encodeURIComponent(key) + "=" + encodeURIComponent(options[key]));
287
- }
288
- }
289
- const str = array.join('&');
290
- if (str !== '') {
291
- return '?' + str;
292
- }
293
- return '';
294
- }
295
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ApiConnectionService, deps: [{ token: i1.TokenService }, { token: i2.SigninStatusService }, { token: i3.MyEnvironmentModel }, { token: i4.CsrfService }], target: i0.ɵɵFactoryTarget.Injectable }); }
296
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ApiConnectionService, providedIn: 'root' }); }
297
- }
298
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ApiConnectionService, decorators: [{
299
- type: Injectable,
300
- args: [{
301
- providedIn: 'root'
302
- }]
303
- }], ctorParameters: function () { return [{ type: i1.TokenService }, { type: i2.SigninStatusService }, { type: i3.MyEnvironmentModel }, { type: i4.CsrfService }]; } });
304
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLWNvbm5lY3Rpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zdG9uZXNjcmlwdHBocC1jbGllbnQvc3JjL2xpYi9hcGktY29ubmVjdGlvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHM0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDOzs7Ozs7QUFPbkQsTUFBTSxPQUFPLG9CQUFvQjtJQVE3QixZQUNZLE1BQW9CLEVBQ3BCLFlBQWlDLEVBQ2pDLFdBQStCLEVBQy9CLElBQWlCO1FBSGpCLFdBQU0sR0FBTixNQUFNLENBQWM7UUFDcEIsaUJBQVksR0FBWixZQUFZLENBQXFCO1FBQ2pDLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtRQUMvQixTQUFJLEdBQUosSUFBSSxDQUFhO1FBVnJCLFNBQUksR0FBRyxFQUFFLENBQUEsQ0FBQywwQkFBMEI7UUFFcEMsZ0JBQVcsR0FBRyxFQUFFLENBQUE7UUFVcEIsSUFBSSxDQUFDLElBQUksR0FBRyxXQUFXLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQTtRQUV0Qyx3Q0FBd0M7UUFDeEMsSUFBSSxDQUFDLFVBQVUsR0FBRztZQUNkLElBQUksRUFBRSxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksSUFBSSxRQUFRO1lBQ3hDLGVBQWUsRUFBRSxXQUFXLENBQUMsSUFBSSxFQUFFLGVBQWU7WUFDbEQsT0FBTyxFQUFFLFdBQVcsQ0FBQyxJQUFJLEVBQUUsT0FBTztZQUNsQyxzQkFBc0IsRUFBRSxXQUFXLENBQUMsSUFBSSxFQUFFLHNCQUFzQixJQUFJLGVBQWU7WUFDbkYsbUJBQW1CLEVBQUUsV0FBVyxDQUFDLElBQUksRUFBRSxtQkFBbUIsSUFBSSxZQUFZO1lBQzFFLGNBQWMsRUFBRSxXQUFXLENBQUMsSUFBSSxFQUFFLGNBQWMsSUFB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QyxPQUFhO1FBQzFCLElBQUksT0FBTyxLQUFLLFNBQVMsRUFBRTtZQUN2QixPQUFPLEVBQUUsQ0FBQTtTQUNaO1FBRUQsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFBO1FBQ2hCLEtBQUssSUFBSSxHQUFHLElBQUksT0FBTyxFQUFFO1lBQ3JCLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxTQUFTLENBQUMsRUFBRTtnQkFDeEYsS0FBSyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsa0JBQWtCLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQTthQUMvRTtTQUNKO1FBQ0QsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUMzQixJQUFJLEdBQUcsS0FBSyxFQUFFLEVBQUU7WUFDWixPQUFPLEdBQUcsR0FBRyxHQUFHLENBQUE7U0FDbkI7UUFFRCxPQUFPLEVBQUUsQ0FBQTtJQUNiLENBQUM7K0dBalZRLG9CQUFvQjttSEFBcEIsb0JBQW9CLGNBRmpCLE1BQU07OzRGQUVULG9CQUFvQjtrQkFIaEMsVUFBVTttQkFBQztvQkFDUixVQUFVLEVBQUUsTUFBTTtpQkFDckIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBUb2tlblNlcnZpY2UgfSBmcm9tICcuL3Rva2VuLnNlcnZpY2UnO1xuaW1wb3J0IHsgU2lnbmluU3RhdHVzU2VydmljZSB9IGZyb20gJy4vc2lnbmluLXN0YXR1cy5zZXJ2aWNlJztcbmltcG9ydCB7IEFwaVJlc3BvbnNlIH0gZnJvbSAnLi9hcGktcmVzcG9uc2UubW9kZWwnO1xuaW1wb3J0IHsgTXlFbnZpcm9ubWVudE1vZGVsLCBBdXRoQ29uZmlnIH0gZnJvbSAnLi9teS1lbnZpcm9ubWVudC5tb2RlbCc7XG5pbXBvcnQgeyBDc3JmU2VydmljZSB9IGZyb20gJy4vY3NyZi5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoe1xuICAgIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBBcGlDb25uZWN0aW9uU2VydmljZSB7XG5cbiAgICBwcml2YXRlIGhvc3QgPSAnJyAvLyBjb250YWlucyB0cmFpbGluZyBzbGFzaFxuXG4gICAgcHJpdmF0ZSBhY2Nlc3NUb2tlbiA9ICcnXG5cbiAgICBwcml2YXRlIGF1dGhDb25maWc6IEF1dGhDb25maWdcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIHRva2VuczogVG9rZW5TZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHNpZ25pblN0YXR1czogU2lnbmluU3RhdHVzU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBlbnZpcm9ubWVudDogTXlFbnZpcm9ubWVudE1vZGVsLFxuICAgICAgICBwcml2YXRlIGNzcmY6IENzcmZTZXJ2aWNlXG4gICAgKSB7XG4gICAgICAgIHRoaXMuaG9zdCA9IGVudmlyb25tZW50LmFwaVNlcnZlci5ob3N0XG5cbiAgICAgICAgLy8gU2V0IGRlZmF1bHQgYXV0aCBjb25maWcgYmFzZWQgb24gbW9kZVxuICAgICAgICB0aGlzLmF1dGhDb25maWcgPSB7XG4gICAgICAgICAgICBtb2RlOiBlbnZpcm9ubWVudC5hdXRoPy5tb2RlIHx8ICdjb29raWUnLFxuICAgICAgICAgICAgcmVmcmVzaEVuZHBvaW50OiBlbnZpcm9ubWVudC5hdXRoPy5yZWZyZXNoRW5kcG9pbnQsXG4gICAgICAgICAgICB1c2VDc3JmOiBlbnZpcm9ubWVudC5hdXRoPy51c2VDc3JmLFxuICAgICAgICAgICAgcmVmcmVzaFRva2VuQ29va2llTmFtZTogZW52aXJvbm1lbnQuYXV0aD8ucmVmcmVzaFRva2VuQ29va2llTmFtZSB8fCAncmVmcmVzaF90b2tlbicsXG4gICAgICAgICAgICBjc3JmVG9rZW5Db29raWVOYW1lOiBlbnZpcm9ubWVudC5hdXRoPy5jc3JmVG9rZW5Db29raWVOYW1lIHx8ICdjc3JmX3Rva2VuJyxcbiAgICAgICAgICAgIGNzcmZIZWFkZXJOYW1lOiBlbnZpcm9ubWVudC5hdXRoPy5jc3JmSGVhZGVyTmFtZSB8fCAnWC1DU1JGLVRva2VuJ1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGRlZmF1bHQgcmVmcmVzaCBlbmRwb2ludCBiYXNlZCBvbiBtb2RlIGlmIG5vdCBzcGVjaWZpZWRcbiAgICAgICAgaWYgKCF0aGlzLmF1dGhDb25maWcucmVmcmVzaEVuZHBvaW50KSB7XG4gICAgICAgICAgICB0aGlzLmF1dGhDb25maWcucmVmcmVzaEVuZHBvaW50ID0gdGhpcy5hdXRoQ29uZmlnLm1vZGUgPT09ICdjb29raWUnXG4gICAgICAgICAgICAgICAgPyAnL2F1dGgvcmVmcmVzaCdcbiAgICAgICAgICAgICAgICA6ICcvdXNlci9yZWZyZXNoX2FjY2VzcydcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBkZWZhdWx0IENTUkYgc2V0dGluZyBiYXNlZCBvbiBtb2RlIGlmIG5vdCBzcGVjaWZpZWRcbiAgICAgICAgaWYgKHRoaXMuYXV0aENvbmZpZy51c2VDc3JmID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYXV0aENvbmZpZy51c2VDc3JmID0gdGhpcy5hdXRoQ29uZmlnLm1vZGUgPT09ICdjb29raWUnXG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIHByaXZhdGUgYXN5bmMgcmVxdWVzdDxEYXRhVHlwZT4odXJsOiBzdHJpbmcsIG9wdGlvbnM6IGFueSwgZGF0YTogYW55IHwgbnVsbCk6IFByb21pc2U8QXBpUmVzcG9uc2U8RGF0YVR5cGU+PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmKGRhdGEgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBib2R5ID0gSlNPTi5zdHJpbmdpZnkoZGF0YSlcbiAgICAgICAgICAgICAgICBpZihib2R5KSB7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuYm9keSA9IGJvZHlcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmJvZHkgPSB7fVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgYWNjZXNzVG9rZW5JbmNsdWRlZCA9IHRoaXMuaW5jbHVkZUFjY2Vzc1Rva2VuKG9wdGlvbnMpXG5cbiAgICAgICAgICAgIGxldCByZXNwb25zZTogUmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwsIG9wdGlvbnMpXG5cbiAgICAgICAgICAgIGlmICgocmVzcG9uc2Uuc3RhdHVzID09PSA0MDEpICYmIGFjY2Vzc1Rva2VuSW5jbHVkZWQpIHtcbiAgICAgICAgICAgICAgICByZXNwb25zZSA9IGF3YWl0IHRoaXMucmVmcmVzaEFjY2Vzc1Rva2VuQW5kUmV0cnkodXJsLCBvcHRpb25zLCByZXNwb25zZSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgY29uc3QganNvbiA9IGF3YWl0IChyZXNwb25zZS5qc29uKCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIChuZXcgQXBpUmVzcG9uc2U8RGF0YVR5cGU+KGpzb24uc3RhdHVzLCBqc29uLmRhdGEsIGpzb24ubWVzc2FnZSkpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2lnbmluU3RhdHVzLnNpZ25lZE91dCgpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZUVycm9yPERhdGFUeXBlPihyZXNwb25zZSlcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZUVycm9yPERhdGFUeXBlPihlcnJvcilcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlRXJyb3I8RGF0YVR5cGU+KGVycm9yOiBhbnkpOiBBcGlSZXNwb25zZTxEYXRhVHlwZT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgYEJhY2tlbmQgcmV0dXJuZWQgY29kZSAke2Vycm9yLnN0YXR1c30sIGAgK1xuICAgICAgICAgICAgYGZ1bGwgZXJyb3I6IGAsIGVycm9yKTtcbiAgICAgICAgcmV0dXJuIG5ldyBBcGlSZXNwb25zZTxEYXRhVHlwZT4oJ2Vycm9yJylcbiAgICB9XG5cbiAgICBhc3luYyBnZXQ8RGF0YVR5cGU+KGVuZHBvaW50OiBzdHJpbmcsIHF1ZXJ5UGFyYW1zT2JqPzogYW55ICk6IFByb21pc2U8QXBpUmVzcG9uc2U8RGF0YVR5cGU+PiB7XG4gICAgICAgIGNvbnN0IHVybCA9IHRoaXMuaG9zdCArIGVuZHBvaW50LnJlcGxhY2UoL15cXC8rLywgJycpICsgdGhpcy5idWlsZFF1ZXJ5U3RyaW5nKHF1ZXJ5UGFyYW1zT2JqKVxuICAgICAgICBjb25zdCBmZXRjaE9wdGlvbnM6IFJlcXVlc3RJbml0ID0ge1xuICAgICAgICAgICAgbW9kZTogJ2NvcnMnLFxuICAgICAgICAgICAgcmVkaXJlY3Q6ICdlcnJvcidcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KHVybCwgZmV0Y2hPcHRpb25zLCBudWxsKVxuICAgIH1cblxuICAgIGFzeW5jIHBvc3Q8RGF0YVR5cGU+KHBhdGhXaXRoUXVlcnlQYXJhbXM6IHN0cmluZywgZGF0YTogYW55KTogUHJvbWlzZTxBcGlSZXNwb25zZTxEYXRhVHlwZT4+IHtcbiAgICAgICAgY29uc3QgdXJsID0gdGhpcy5ob3N0ICsgcGF0aFdpdGhRdWVyeVBhcmFtcy5yZXBsYWNlKC9eXFwvKy8sICcnKVxuICAgICAgICBjb25zdCBmZXRjaE9wdGlvbnM6IFJlcXVlc3RJbml0ID0ge1xuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBtb2RlOiAnY29ycycsXG4gICAgICAgICAgICByZWRpcmVjdDogJ2Vycm9yJyxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoZGF0YSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KHVybCwgZmV0Y2hPcHRpb25zLCBkYXRhKVxuICAgIH1cblxuICAgIGFzeW5jIHB1dDxEYXRhVHlwZT4ocGF0aFdpdGhRdWVyeVBhcmFtczogc3RyaW5nLCBkYXRhOiBhbnkpOiBQcm9taXNlPEFwaVJlc3BvbnNlPERhdGFUeXBlPj4ge1xuICAgICAgICBjb25zdCB1cmwgPSB0aGlzLmhvc3QgKyBwYXRoV2l0aFF1ZXJ5UGFyYW1zLnJlcGxhY2UoL15cXC8rLywgJycpXG4gICAgICAgIGNvbnN0IGZldGNoT3B0aW9uczogUmVxdWVzdEluaXQgPSB7XG4gICAgICAgICAgICBtZXRob2Q6ICdQVVQnLFxuICAgICAgICAgICAgbW9kZTogJ2NvcnMnLFxuICAgICAgICAgICAgcmVkaXJlY3Q6ICdlcnJvcicsXG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGRhdGEpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCh1cmwsIGZldGNoT3B0aW9ucywgZGF0YSlcbiAgICB9XG5cbiAgICBhc3luYyBwYXRjaDxEYXRhVHlwZT4ocGF0aFdpdGhRdWVyeVBhcmFtczogc3RyaW5nLCBkYXRhOiBhbnkpOiBQcm9taXNlPEFwaVJlc3BvbnNlPERhdGFUeXBlPj4ge1xuICAgICAgICBjb25zdCB1cmwgPSB0aGlzLmhvc3QgKyBwYXRoV2l0aFF1ZXJ5UGFyYW1zLnJlcGxhY2UoL15cXC8rLywgJycpXG4gICAgICAgIGNvbnN0IGZldGNoT3B0aW9uczogUmVxdWVzdEluaXQgPSB7XG4gICAgICAgICAgICBtZXRob2Q6ICdQQVRDSCcsXG4gICAgICAgICAgICBtb2RlOiAnY29ycycsXG4gICAgICAgICAgICByZWRpcmVjdDogJ2Vycm9yJyxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoZGF0YSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KHVybCwgZmV0Y2hPcHRpb25zLCBkYXRhKVxuICAgIH1cblxuICAgIGFzeW5jIGRlbGV0ZTxEYXRhVHlwZT4oZW5kcG9pbnQ6IHN0cmluZywgcXVlcnlQYXJhbXNPYmo/OiBhbnkpOiBQcm9taXNlPEFwaVJlc3BvbnNlPERhdGFUeXBlPj4ge1xuICAgICAgICBjb25zdCB1cmwgPSB0aGlzLmhvc3QgKyBlbmRwb2ludC5yZXBsYWNlKC9eXFwvKy8sICcnKSArIHRoaXMuYnVpbGRRdWVyeVN0cmluZyhxdWVyeVBhcmFtc09iailcbiAgICAgICAgY29uc3QgZmV0Y2hPcHRpb25zOiBSZXF1ZXN0SW5pdCA9IHtcbiAgICAgICAgICAgIG1ldGhvZDogJ0RFTEVURScsXG4gICAgICAgICAgICBtb2RlOiAnY29ycycsXG4gICAgICAgICAgICByZWRpcmVjdDogJ2Vycm9yJ1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QodXJsLCBmZXRjaE9wdGlvbnMsIG51bGwpXG4gICAgfVxuXG4gICAgLy8gYXN5bmMgcG9zdEZvcm1XaXRoRmlsZXMocGF0aFdpdGhRdWVyeVBhcmFtczogc3RyaW5nLCBmb3JtRGF0YTogRm9ybURhdGEpOiBQcm9taXNlPEFwaVJlc3BvbnNlIHwgbnVsbD4ge1xuICAgIC8vICAgICBjb25zdCB1cmwgPSB0aGlzLmhvc3QgKyBwYXRoV2l0aFF1ZXJ5UGFyYW1zLnJlcGxhY2UoL15cXC8rLywgJycpXG4gICAgLy8gICAgIHRyeSB7XG4gICAgLy8gICAgICAgICBjb25zdCBmZXRjaE9wdGlvbnM6IFJlcXVlc3RJbml0ID0ge1xuICAgIC8vICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgIC8vICAgICAgICAgICAgIG1vZGU6ICdjb3JzJyxcbiAgICAvLyAgICAgICAgICAgICByZWRpcmVjdDogJ2Vycm9yJyxcbiAgICAvLyAgICAgICAgICAgICBib2R5OiBmb3JtRGF0YVxuICAgIC8vICAgICAgICAgfVxuXG4gICAgLy8gICAgICAgICBjb25zdCBhY2Nlc3NUb2tlbkluY2x1ZGVkID0gdGhpcy5pbmNsdWRlQWNjZXNzVG9rZW4oZmV0Y2hPcHRpb25zKVxuXG4gICAgLy8gICAgICAgICBsZXQgcmVzcG9uc2U6IFJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsLCBmZXRjaE9wdGlvbnMpXG5cbiAgICAvLyAgICAgICAgIGlmICgocmVzcG9uc2Uuc3RhdHVzID09PSA0MDEpICYmIGFjY2Vzc1Rva2VuSW5jbHVkZWQpIHtcbiAgICAvLyAgICAgICAgICAgICByZXNwb25zZSA9IGF3YWl0IHRoaXMucmVmcmVzaEFjY2Vzc1Rva2VuQW5kUmV0cnkodXJsLCBmZXRjaE9wdGlvbnMsIHJlc3BvbnNlKVxuICAgIC8vICAgICAgICAgfVxuXG4gICAgLy8gICAgICAgICBpZiAocmVzcG9uc2Uub2spIHtcbiAgICAvLyAgICAgICAgICAgICByZXR1cm4gKChhd2FpdCAocmVzcG9uc2UuanNvbigpKSBhcyBBcGlSZXNwb25zZSkpXG4gICAgLy8gICAgICAgICB9XG5cbiAgICAvLyAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZUVycm9yKHJlc3BvbnNlKVxuICAgIC8vICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgIC8vICAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRXJyb3IoZXJyb3IpXG4gICAgLy8gICAgIH1cbiAgICAvLyB9XG5cbiAgICBwcml2YXRlIGluY2x1ZGVBY2Nlc3NUb2tlbihvcHRpb25zOiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgdGhpcy5hY2Nlc3NUb2tlbiA9IHRoaXMudG9rZW5zLmdldEFjY2Vzc1Rva2VuKClcbiAgICAgICAgaWYgKCF0aGlzLmFjY2Vzc1Rva2VuKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghb3B0aW9ucy5oZWFkZXJzKSB7XG4gICAgICAgICAgICBvcHRpb25zLmhlYWRlcnMgPSB7fVxuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMuaGVhZGVyc1snQXV0aG9yaXphdGlvbiddID0gJ0JlYXJlciAnICsgdGhpcy5hY2Nlc3NUb2tlblxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmVmcmVzaEFjY2Vzc1Rva2VuQW5kUmV0cnkodXJsOiBzdHJpbmcsIGZldGNoT3B0aW9uczogYW55LCByZXNwb25zZTogUmVzcG9uc2UpOiBQcm9taXNlPFJlc3BvbnNlPiB7XG5cbiAgICAgICAgY29uc3QgcmVmcmVzaFN0YXR1c09rID0gYXdhaXQgdGhpcy5yZWZyZXNoQWNjZXNzVG9rZW4oKVxuICAgICAgICBpZiAoIXJlZnJlc2hTdGF0dXNPaykge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlXG4gICAgICAgIH1cblxuICAgICAgICBmZXRjaE9wdGlvbnMuaGVhZGVyc1snQXV0aG9yaXphdGlvbiddID0gJ0JlYXJlciAnICsgdGhpcy5hY2Nlc3NUb2tlblxuICAgICAgICByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCwgZmV0Y2hPcHRpb25zKVxuICAgICAgICByZXR1cm4gcmVzcG9uc2VcbiAgICB9XG5cbiAgICBhc3luYyByZWZyZXNoQWNjZXNzVG9rZW4oKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIGlmICh0aGlzLmF1dGhDb25maWcubW9kZSA9PT0gJ25vbmUnKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmF1dGhDb25maWcubW9kZSA9PT0gJ2Nvb2tpZScpIHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlZnJlc2hBY2Nlc3NUb2tlbkNvb2tpZU1vZGUoKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmVmcmVzaEFjY2Vzc1Rva2VuQm9keU1vZGUoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVmcmVzaCBhY2Nlc3MgdG9rZW4gdXNpbmcgY29va2llLWJhc2VkIGF1dGggKFN0b25lU2NyaXB0UEhQIHYyLjEueCBkZWZhdWx0KVxuICAgICAqL1xuICAgIHByaXZhdGUgYXN5bmMgcmVmcmVzaEFjY2Vzc1Rva2VuQ29va2llTW9kZSgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlZnJlc2hUb2tlblVybCA9IHRoaXMuaG9zdCArIHRoaXMuYXV0aENvbmZpZy5yZWZyZXNoRW5kcG9pbnQhLnJlcGxhY2UoL15cXC8rLywgJycpXG4gICAgICAgICAgICBjb25zdCBoZWFkZXJzOiBhbnkgPSB7XG4gICAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBZGQgQ1NSRiB0b2tlbiBpZiBlbmFibGVkXG4gICAgICAgICAgICBpZiAodGhpcy5hdXRoQ29uZmlnLnVzZUNzcmYpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjc3JmVG9rZW4gPSB0aGlzLmNzcmYuZ2V0Q3NyZlRva2VuKHRoaXMuYXV0aENvbmZpZy5jc3JmVG9rZW5Db29raWVOYW1lISlcbiAgICAgICAgICAgICAgICBpZiAoIWNzcmZUb2tlbikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdDU1JGIHRva2VuIG5vdCBmb3VuZCBpbiBjb29raWUnKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaGVhZGVyc1t0aGlzLmF1dGhDb25maWcuY3NyZkhlYWRlck5hbWUhXSA9IGNzcmZUb2tlblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgcmVmcmVzaFRva2VuUmVzcG9uc2UgPSBhd2FpdCBmZXRjaChyZWZyZXNoVG9rZW5VcmwsIHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBtb2RlOiAnY29ycycsXG4gICAgICAgICAgICAgICAgY3JlZGVudGlhbHM6ICdpbmNsdWRlJywgLy8gSW1wb3J0YW50OiBzZW5kIGNvb2tpZXNcbiAgICAgICAgICAgICAgICByZWRpcmVjdDogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBpZiAoIXJlZnJlc2hUb2tlblJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NUb2tlbiA9ICcnXG4gICAgICAgICAgICAgICAgdGhpcy50b2tlbnMuY2xlYXIoKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgcmVmcmVzaEFjY2Vzc0RhdGEgPSBhd2FpdCByZWZyZXNoVG9rZW5SZXNwb25zZS5qc29uKClcbiAgICAgICAgICAgIGlmICghcmVmcmVzaEFjY2Vzc0RhdGEgfHwgcmVmcmVzaEFjY2Vzc0RhdGEuc3RhdHVzICE9PSAnb2snKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEV4dHJhY3QgYWNjZXNzIHRva2VuIGZyb20gcmVzcG9uc2VcbiAgICAgICAgICAgIGNvbnN0IG5ld0FjY2Vzc1Rva2VuID0gcmVmcmVzaEFjY2Vzc0RhdGEuZGF0YT8uYWNjZXNzX3Rva2VuIHx8IHJlZnJlc2hBY2Nlc3NEYXRhLmFjY2Vzc190b2tlblxuICAgICAgICAgICAgaWYgKCFuZXdBY2Nlc3NUb2tlbikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ05vIGFjY2VzcyB0b2tlbiBpbiByZWZyZXNoIHJlc3BvbnNlJylcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gU3RvcmUgbmV3IGFjY2VzcyB0b2tlbiAocmVmcmVzaCB0b2tlbiBpcyBpbiBodHRwT25seSBjb29raWUpXG4gICAgICAgICAgICB0aGlzLnRva2Vucy5zZXRBY2Nlc3NUb2tlbihuZXdBY2Nlc3NUb2tlbilcbiAgICAgICAgICAgIHRoaXMuYWNjZXNzVG9rZW4gPSBuZXdBY2Nlc3NUb2tlblxuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignVG9rZW4gcmVmcmVzaCBmYWlsZWQgKGNvb2tpZSBtb2RlKTonLCBlcnJvcilcbiAgICAgICAgICAgIHRoaXMuYWNjZXNzVG9rZW4gPSAnJ1xuICAgICAgICAgICAgdGhpcy50b2tlbnMuY2xlYXIoKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWZyZXNoIGFjY2VzcyB0b2tlbiB1c2luZyBib2R5LWJhc2VkIGF1dGggKGxlZ2FjeSBtb2RlKVxuICAgICAqL1xuICAgIHByaXZhdGUgYXN5bmMgcmVmcmVzaEFjY2Vzc1Rva2VuQm9keU1vZGUoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZWZyZXNoVG9rZW4gPSB0aGlzLnRva2Vucy5nZXRSZWZyZXNoVG9rZW4oKVxuICAgICAgICAgICAgaWYgKCFyZWZyZXNoVG9rZW4pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcmVmcmVzaFRva2VuVXJsID0gdGhpcy5ob3N0ICsgdGhpcy5hdXRoQ29uZmlnLnJlZnJlc2hFbmRwb2ludCEucmVwbGFjZSgvXlxcLysvLCAnJylcbiAgICAgICAgICAgIGxldCByZWZyZXNoVG9rZW5SZXNwb25zZSA9IGF3YWl0IGZldGNoKHJlZnJlc2hUb2tlblVybCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIG1vZGU6ICdjb3JzJyxcbiAgICAgICAgICAgICAgICByZWRpcmVjdDogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbidcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgYWNjZXNzX3Rva2VuOiB0aGlzLmFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgICAgICAgICByZWZyZXNoX3Rva2VuOiByZWZyZXNoVG9rZW5cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaWYgKCFyZWZyZXNoVG9rZW5SZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzVG9rZW4gPSAnJ1xuICAgICAgICAgICAgICAgIHRoaXMudG9rZW5zLmNsZWFyKClcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHJlZnJlc2hBY2Nlc3NEYXRhID0gYXdhaXQgcmVmcmVzaFRva2VuUmVzcG9uc2UuanNvbigpXG4gICAgICAgICAgICBpZiAoIXJlZnJlc2hBY2Nlc3NEYXRhKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IG5ld0FjY2Vzc1Rva2VuID0gcmVmcmVzaEFjY2Vzc0RhdGEuZGF0YT8uYWNjZXNzX3Rva2VuIHx8IHJlZnJlc2hBY2Nlc3NEYXRhLmFjY2Vzc190b2tlblxuICAgICAgICAgICAgaWYgKCFuZXdBY2Nlc3NUb2tlbikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ05vIGFjY2VzcyB0b2tlbiBpbiByZWZyZXNoIHJlc3BvbnNlJylcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy50b2tlbnMuc2V0VG9rZW5zKG5ld0FjY2Vzc1Rva2VuLCByZWZyZXNoVG9rZW4pXG4gICAgICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuID0gbmV3QWNjZXNzVG9rZW5cblxuICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1Rva2VuIHJlZnJlc2ggZmFpbGVkIChib2R5IG1vZGUpOicsIGVycm9yKVxuICAgICAgICAgICAgdGhpcy5hY2Nlc3NUb2tlbiA9ICcnXG4gICAgICAgICAgICB0aGlzLnRva2Vucy5jbGVhcigpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGJ1aWxkUXVlcnlTdHJpbmcob3B0aW9ucz86IGFueSk6IHN0cmluZyB7XG4gICAgICAgIGlmIChvcHRpb25zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiAnJ1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYXJyYXkgPSBbXVxuICAgICAgICBmb3IgKGxldCBrZXkgaW4gb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiAob3B0aW9uc1trZXldICE9PSBudWxsKSAmJiAob3B0aW9uc1trZXldICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICAgICAgICAgICAgYXJyYXkucHVzaChlbmNvZGVVUklDb21wb25lbnQoa2V5KSArIFwiPVwiICsgZW5jb2RlVVJJQ29tcG9uZW50KG9wdGlvbnNba2V5XSkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RyID0gYXJyYXkuam9pbignJicpXG4gICAgICAgIGlmIChzdHIgIT09ICcnKSB7XG4gICAgICAgICAgICByZXR1cm4gJz8nICsgc3RyXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gJydcbiAgICB9XG59XG4iXX0=
@@ -1,44 +0,0 @@
1
- export class ApiResponse {
2
- constructor(status, data = {}, message = '') {
3
- this.status = status;
4
- this.data = data;
5
- this.message = message;
6
- }
7
- onOk(callback) {
8
- if (this.status === 'ok') {
9
- callback(this.data);
10
- }
11
- return this;
12
- }
13
- onNotOk(callback) {
14
- if (this.status === 'not ok') {
15
- callback(this.message, this.data);
16
- }
17
- return this;
18
- }
19
- onError(callback) {
20
- if (this.status === 'error') {
21
- callback();
22
- }
23
- return this;
24
- }
25
- isSuccess() {
26
- return this.status === 'ok';
27
- }
28
- isError() {
29
- return this.status === 'error' || this.status === 'not ok';
30
- }
31
- getData() {
32
- return this.data || null;
33
- }
34
- getError() {
35
- return this.message || 'Unknown error';
36
- }
37
- getStatus() {
38
- return this.status;
39
- }
40
- getMessage() {
41
- return this.message;
42
- }
43
- }
44
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLXJlc3BvbnNlLm1vZGVsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0b25lc2NyaXB0cGhwLWNsaWVudC9zcmMvbGliL2FwaS1yZXNwb25zZS5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLE9BQU8sV0FBVztJQUtwQixZQUFZLE1BQWMsRUFBRSxPQUFZLEVBQUUsRUFBRSxVQUFrQixFQUFFO1FBQzVELElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFBO1FBQ3BCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFBO1FBQ2hCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBO0lBQzFCLENBQUM7SUFFRCxJQUFJLENBQUMsUUFBa0M7UUFDbkMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLElBQUksRUFBRTtZQUN0QixRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1NBQ3RCO1FBQ0QsT0FBTyxJQUFJLENBQUE7SUFDZixDQUFDO0lBRUQsT0FBTyxDQUFDLFFBQW1EO1FBQ3ZELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxRQUFRLEVBQUU7WUFDMUIsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1NBQ3BDO1FBQ0QsT0FBTyxJQUFJLENBQUE7SUFDZixDQUFDO0lBRUQsT0FBTyxDQUFDLFFBQW9CO1FBQ3hCLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxPQUFPLEVBQUU7WUFDekIsUUFBUSxFQUFFLENBQUE7U0FDYjtRQUNELE9BQU8sSUFBSSxDQUFBO0lBQ2YsQ0FBQztJQUVELFNBQVM7UUFDTCxPQUFPLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFBO0lBQy9CLENBQUM7SUFFRCxPQUFPO1FBQ0gsT0FBTyxJQUFJLENBQUMsTUFBTSxLQUFLLE9BQU8sSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLFFBQVEsQ0FBQTtJQUM5RCxDQUFDO0lBRUQsT0FBTztRQUNILE9BQU8sSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUE7SUFDNUIsQ0FBQztJQUVELFFBQVE7UUFDSixPQUFPLElBQUksQ0FBQyxPQUFPLElBQUksZUFBZSxDQUFBO0lBQzFDLENBQUM7SUFFRCxTQUFTO1FBQ0wsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFBO0lBQ3RCLENBQUM7SUFFRCxVQUFVO1FBQ04sT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjbGFzcyBBcGlSZXNwb25zZTxEYXRhVHlwZT4ge1xuICAgIHByaXZhdGUgc3RhdHVzOiBzdHJpbmdcbiAgICBwcml2YXRlIGRhdGE6IGFueVxuICAgIHByaXZhdGUgbWVzc2FnZTogc3RyaW5nXG5cbiAgICBjb25zdHJ1Y3RvcihzdGF0dXM6IHN0cmluZywgZGF0YTogYW55ID0ge30sIG1lc3NhZ2U6IHN0cmluZyA9ICcnKSB7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzXG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGFcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZVxuICAgIH1cblxuICAgIG9uT2soY2FsbGJhY2s6IChkYXRhOiBEYXRhVHlwZSkgPT4gdm9pZCk6IEFwaVJlc3BvbnNlPERhdGFUeXBlPiB7XG4gICAgICAgIGlmICh0aGlzLnN0YXR1cyA9PT0gJ29rJykge1xuICAgICAgICAgICAgY2FsbGJhY2sodGhpcy5kYXRhKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgb25Ob3RPayhjYWxsYmFjazogKG1lc3NhZ2U6IHN0cmluZywgZGF0YTogRGF0YVR5cGUpID0+IHZvaWQpOiBBcGlSZXNwb25zZTxEYXRhVHlwZT4ge1xuICAgICAgICBpZiAodGhpcy5zdGF0dXMgPT09ICdub3Qgb2snKSB7XG4gICAgICAgICAgICBjYWxsYmFjayh0aGlzLm1lc3NhZ2UsIHRoaXMuZGF0YSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIG9uRXJyb3IoY2FsbGJhY2s6ICgpID0+IHZvaWQpOiBBcGlSZXNwb25zZTxEYXRhVHlwZT4ge1xuICAgICAgICBpZiAodGhpcy5zdGF0dXMgPT09ICdlcnJvcicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKClcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIGlzU3VjY2VzcygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdHVzID09PSAnb2snXG4gICAgfVxuXG4gICAgaXNFcnJvcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdHVzID09PSAnZXJyb3InIHx8IHRoaXMuc3RhdHVzID09PSAnbm90IG9rJ1xuICAgIH1cblxuICAgIGdldERhdGEoKTogRGF0YVR5cGUgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YSB8fCBudWxsXG4gICAgfVxuXG4gICAgZ2V0RXJyb3IoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWVzc2FnZSB8fCAnVW5rbm93biBlcnJvcidcbiAgICB9XG5cbiAgICBnZXRTdGF0dXMoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdHVzXG4gICAgfVxuXG4gICAgZ2V0TWVzc2FnZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5tZXNzYWdlXG4gICAgfVxufSJdfQ==
@@ -1,14 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import * as i0 from "@angular/core";
3
- export class AuthService {
4
- constructor() { }
5
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthService, providedIn: 'root' }); }
7
- }
8
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthService, decorators: [{
9
- type: Injectable,
10
- args: [{
11
- providedIn: 'root'
12
- }]
13
- }], ctorParameters: function () { return []; } });
14
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0b25lc2NyaXB0cGhwLWNsaWVudC9zcmMvbGliL2F1dGguc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQUszQyxNQUFNLE9BQU8sV0FBVztJQUV0QixnQkFBZ0IsQ0FBQzsrR0FGTixXQUFXO21IQUFYLFdBQVcsY0FGVixNQUFNOzs0RkFFUCxXQUFXO2tCQUh2QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgQXV0aFNlcnZpY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkgeyB9XG59XG4iXX0=
@@ -1,46 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import * as i0 from "@angular/core";
3
- /**
4
- * CSRF Token Service
5
- *
6
- * Manages CSRF tokens for cookie-based authentication.
7
- * Reads CSRF token from cookies and provides it for request headers.
8
- */
9
- export class CsrfService {
10
- /**
11
- * Get CSRF token from cookie
12
- */
13
- getCsrfToken(cookieName = 'csrf_token') {
14
- const cookies = document.cookie.split(';');
15
- for (const cookie of cookies) {
16
- const [name, value] = cookie.trim().split('=');
17
- if (name === cookieName) {
18
- return decodeURIComponent(value);
19
- }
20
- }
21
- return null;
22
- }
23
- /**
24
- * Check if CSRF token exists
25
- */
26
- hasCsrfToken(cookieName = 'csrf_token') {
27
- return this.getCsrfToken(cookieName) !== null;
28
- }
29
- /**
30
- * Clear CSRF token (for logout)
31
- * Note: Client-side deletion is limited for httpOnly cookies
32
- */
33
- clearCsrfToken(cookieName = 'csrf_token') {
34
- // Can only clear non-httpOnly cookies
35
- document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
36
- }
37
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CsrfService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
38
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CsrfService, providedIn: 'root' }); }
39
- }
40
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CsrfService, decorators: [{
41
- type: Injectable,
42
- args: [{
43
- providedIn: 'root'
44
- }]
45
- }] });
46
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3NyZi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0b25lc2NyaXB0cGhwLWNsaWVudC9zcmMvbGliL2NzcmYuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQUUzQzs7Ozs7R0FLRztBQUlILE1BQU0sT0FBTyxXQUFXO0lBRXBCOztPQUVHO0lBQ0gsWUFBWSxDQUFDLGFBQXFCLFlBQVk7UUFDMUMsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDM0MsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUU7WUFDMUIsTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQy9DLElBQUksSUFBSSxLQUFLLFVBQVUsRUFBRTtnQkFDckIsT0FBTyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUNwQztTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsWUFBWSxDQUFDLGFBQXFCLFlBQVk7UUFDMUMsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxLQUFLLElBQUksQ0FBQztJQUNsRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsY0FBYyxDQUFDLGFBQXFCLFlBQVk7UUFDNUMsc0NBQXNDO1FBQ3RDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsR0FBRyxVQUFVLG1EQUFtRCxDQUFDO0lBQ3ZGLENBQUM7K0dBOUJRLFdBQVc7bUhBQVgsV0FBVyxjQUZSLE1BQU07OzRGQUVULFdBQVc7a0JBSHZCLFVBQVU7bUJBQUM7b0JBQ1IsVUFBVSxFQUFFLE1BQU07aUJBQ3JCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG4vKipcbiAqIENTUkYgVG9rZW4gU2VydmljZVxuICpcbiAqIE1hbmFnZXMgQ1NSRiB0b2tlbnMgZm9yIGNvb2tpZS1iYXNlZCBhdXRoZW50aWNhdGlvbi5cbiAqIFJlYWRzIENTUkYgdG9rZW4gZnJvbSBjb29raWVzIGFuZCBwcm92aWRlcyBpdCBmb3IgcmVxdWVzdCBoZWFkZXJzLlxuICovXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIENzcmZTZXJ2aWNlIHtcblxuICAgIC8qKlxuICAgICAqIEdldCBDU1JGIHRva2VuIGZyb20gY29va2llXG4gICAgICovXG4gICAgZ2V0Q3NyZlRva2VuKGNvb2tpZU5hbWU6IHN0cmluZyA9ICdjc3JmX3Rva2VuJyk6IHN0cmluZyB8IG51bGwge1xuICAgICAgICBjb25zdCBjb29raWVzID0gZG9jdW1lbnQuY29va2llLnNwbGl0KCc7Jyk7XG4gICAgICAgIGZvciAoY29uc3QgY29va2llIG9mIGNvb2tpZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IFtuYW1lLCB2YWx1ZV0gPSBjb29raWUudHJpbSgpLnNwbGl0KCc9Jyk7XG4gICAgICAgICAgICBpZiAobmFtZSA9PT0gY29va2llTmFtZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQodmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIENTUkYgdG9rZW4gZXhpc3RzXG4gICAgICovXG4gICAgaGFzQ3NyZlRva2VuKGNvb2tpZU5hbWU6IHN0cmluZyA9ICdjc3JmX3Rva2VuJyk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDc3JmVG9rZW4oY29va2llTmFtZSkgIT09IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2xlYXIgQ1NSRiB0b2tlbiAoZm9yIGxvZ291dClcbiAgICAgKiBOb3RlOiBDbGllbnQtc2lkZSBkZWxldGlvbiBpcyBsaW1pdGVkIGZvciBodHRwT25seSBjb29raWVzXG4gICAgICovXG4gICAgY2xlYXJDc3JmVG9rZW4oY29va2llTmFtZTogc3RyaW5nID0gJ2NzcmZfdG9rZW4nKTogdm9pZCB7XG4gICAgICAgIC8vIENhbiBvbmx5IGNsZWFyIG5vbi1odHRwT25seSBjb29raWVzXG4gICAgICAgIGRvY3VtZW50LmNvb2tpZSA9IGAke2Nvb2tpZU5hbWV9PTsgZXhwaXJlcz1UaHUsIDAxIEphbiAxOTcwIDAwOjAwOjAwIFVUQzsgcGF0aD0vO2A7XG4gICAgfVxufVxuIl19
@@ -1,14 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import * as i0 from "@angular/core";
3
- export class DbService {
4
- constructor() { }
5
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DbService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DbService, providedIn: 'root' }); }
7
- }
8
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DbService, decorators: [{
9
- type: Injectable,
10
- args: [{
11
- providedIn: 'root'
12
- }]
13
- }], ctorParameters: function () { return []; } });
14
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zdG9uZXNjcmlwdHBocC1jbGllbnQvc3JjL2xpYi9kYi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBSzNDLE1BQU0sT0FBTyxTQUFTO0lBRXBCLGdCQUFnQixDQUFDOytHQUZOLFNBQVM7bUhBQVQsU0FBUyxjQUZSLE1BQU07OzRGQUVQLFNBQVM7a0JBSHJCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBEYlNlcnZpY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkgeyB9XG59XG4iXX0=
@@ -1,31 +0,0 @@
1
- export class MyEnvironmentModel {
2
- constructor() {
3
- this.production = true;
4
- this.firebase = {
5
- projectId: '',
6
- appId: '',
7
- databaseURL: '',
8
- storageBucket: '',
9
- locationId: '',
10
- apiKey: '',
11
- authDomain: '',
12
- messagingSenderId: '',
13
- measurementId: ''
14
- };
15
- this.apiServer = { host: '' };
16
- this.chatServer = { host: '' };
17
- /**
18
- * Authentication configuration
19
- * @default { mode: 'cookie', refreshEndpoint: '/auth/refresh', useCsrf: true }
20
- */
21
- this.auth = {
22
- mode: 'cookie',
23
- refreshEndpoint: '/auth/refresh',
24
- useCsrf: true,
25
- refreshTokenCookieName: 'refresh_token',
26
- csrfTokenCookieName: 'csrf_token',
27
- csrfHeaderName: 'X-CSRF-Token'
28
- };
29
- }
30
- }
31
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXktZW52aXJvbm1lbnQubW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc3RvbmVzY3JpcHRwaHAtY2xpZW50L3NyYy9saWIvbXktZW52aXJvbm1lbnQubW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBMENBLE1BQU0sT0FBTyxrQkFBa0I7SUFBL0I7UUFDSSxlQUFVLEdBQVksSUFBSSxDQUFBO1FBQzFCLGFBQVEsR0FVSjtZQUNJLFNBQVMsRUFBRSxFQUFFO1lBQ2IsS0FBSyxFQUFFLEVBQUU7WUFDVCxXQUFXLEVBQUUsRUFBRTtZQUNmLGFBQWEsRUFBRSxFQUFFO1lBQ2pCLFVBQVUsRUFBRSxFQUFFO1lBQ2QsTUFBTSxFQUFFLEVBQUU7WUFDVixVQUFVLEVBQUUsRUFBRTtZQUNkLGlCQUFpQixFQUFFLEVBQUU7WUFDckIsYUFBYSxFQUFFLEVBQUU7U0FDcEIsQ0FBQTtRQUNMLGNBQVMsR0FFTCxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQTtRQUNoQixlQUFVLEdBRU4sRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUE7UUFFaEI7OztXQUdHO1FBQ0gsU0FBSSxHQUFnQjtZQUNoQixJQUFJLEVBQUUsUUFBUTtZQUNkLGVBQWUsRUFBRSxlQUFlO1lBQ2hDLE9BQU8sRUFBRSxJQUFJO1lBQ2Isc0JBQXNCLEVBQUUsZUFBZTtZQUN2QyxtQkFBbUIsRUFBRSxZQUFZO1lBQ2pDLGNBQWMsRUFBRSxjQUFjO1NBQ2pDLENBQUM7SUFDTixDQUFDO0NBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgdHlwZSBBdXRoTW9kZSA9ICdjb29raWUnIHwgJ2JvZHknIHwgJ25vbmUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEF1dGhDb25maWcge1xuICAgIC8qKlxuICAgICAqIEF1dGhlbnRpY2F0aW9uIG1vZGU6XG4gICAgICogLSAnY29va2llJzogVXNlIGh0dHBPbmx5IGNvb2tpZXMgKyBDU1JGIHRva2VucyAocmVjb21tZW5kZWQsIG1hdGNoZXMgU3RvbmVTY3JpcHRQSFAgdjIuMS54KVxuICAgICAqIC0gJ2JvZHknOiBTZW5kIHRva2VucyBpbiByZXF1ZXN0IGJvZHkgKGxlZ2FjeSBtb2RlKVxuICAgICAqIC0gJ25vbmUnOiBObyBhdXRvbWF0aWMgdG9rZW4gcmVmcmVzaFxuICAgICAqL1xuICAgIG1vZGU6IEF1dGhNb2RlO1xuXG4gICAgLyoqXG4gICAgICogVG9rZW4gcmVmcmVzaCBlbmRwb2ludCBwYXRoXG4gICAgICogQGRlZmF1bHQgJy9hdXRoL3JlZnJlc2gnIGZvciBjb29raWUgbW9kZSwgJy91c2VyL3JlZnJlc2hfYWNjZXNzJyBmb3IgYm9keSBtb2RlXG4gICAgICovXG4gICAgcmVmcmVzaEVuZHBvaW50Pzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogRW5hYmxlIENTUkYgdG9rZW4gc3VwcG9ydCAocmVxdWlyZWQgZm9yIGNvb2tpZSBtb2RlKVxuICAgICAqIEBkZWZhdWx0IHRydWUgZm9yIGNvb2tpZSBtb2RlLCBmYWxzZSBmb3IgYm9keSBtb2RlXG4gICAgICovXG4gICAgdXNlQ3NyZj86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBDb29raWUgbmFtZSBmb3IgcmVmcmVzaCB0b2tlblxuICAgICAqIEBkZWZhdWx0ICdyZWZyZXNoX3Rva2VuJ1xuICAgICAqL1xuICAgIHJlZnJlc2hUb2tlbkNvb2tpZU5hbWU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDb29raWUgbmFtZSBmb3IgQ1NSRiB0b2tlblxuICAgICAqIEBkZWZhdWx0ICdjc3JmX3Rva2VuJ1xuICAgICAqL1xuICAgIGNzcmZUb2tlbkNvb2tpZU5hbWU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDU1JGIGhlYWRlciBuYW1lXG4gICAgICogQGRlZmF1bHQgJ1gtQ1NSRi1Ub2tlbidcbiAgICAgKi9cbiAgICBjc3JmSGVhZGVyTmFtZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIE15RW52aXJvbm1lbnRNb2RlbCB7XG4gICAgcHJvZHVjdGlvbjogYm9vbGVhbiA9IHRydWVcbiAgICBmaXJlYmFzZToge1xuICAgICAgICBwcm9qZWN0SWQ6IHN0cmluZ1xuICAgICAgICBhcHBJZDogc3RyaW5nXG4gICAgICAgIGRhdGFiYXNlVVJMOiBzdHJpbmdcbiAgICAgICAgc3RvcmFnZUJ1Y2tldDogc3RyaW5nXG4gICAgICAgIGxvY2F0aW9uSWQ6IHN0cmluZ1xuICAgICAgICBhcGlLZXk6IHN0cmluZ1xuICAgICAgICBhdXRoRG9tYWluOiBzdHJpbmdcbiAgICAgICAgbWVzc2FnaW5nU2VuZGVySWQ6IHN0cmluZ1xuICAgICAgICBtZWFzdXJlbWVudElkOiBzdHJpbmdcbiAgICB9ID0ge1xuICAgICAgICAgICAgcHJvamVjdElkOiAnJyxcbiAgICAgICAgICAgIGFwcElkOiAnJyxcbiAgICAgICAgICAgIGRhdGFiYXNlVVJMOiAnJyxcbiAgICAgICAgICAgIHN0b3JhZ2VCdWNrZXQ6ICcnLFxuICAgICAgICAgICAgbG9jYXRpb25JZDogJycsXG4gICAgICAgICAgICBhcGlLZXk6ICcnLFxuICAgICAgICAgICAgYXV0aERvbWFpbjogJycsXG4gICAgICAgICAgICBtZXNzYWdpbmdTZW5kZXJJZDogJycsXG4gICAgICAgICAgICBtZWFzdXJlbWVudElkOiAnJ1xuICAgICAgICB9XG4gICAgYXBpU2VydmVyOiB7XG4gICAgICAgIGhvc3Q6IHN0cmluZ1xuICAgIH0gPSB7IGhvc3Q6ICcnIH1cbiAgICBjaGF0U2VydmVyOiB7XG4gICAgICAgIGhvc3Q6IHN0cmluZ1xuICAgIH0gPSB7IGhvc3Q6ICcnIH1cblxuICAgIC8qKlxuICAgICAqIEF1dGhlbnRpY2F0aW9uIGNvbmZpZ3VyYXRpb25cbiAgICAgKiBAZGVmYXVsdCB7IG1vZGU6ICdjb29raWUnLCByZWZyZXNoRW5kcG9pbnQ6ICcvYXV0aC9yZWZyZXNoJywgdXNlQ3NyZjogdHJ1ZSB9XG4gICAgICovXG4gICAgYXV0aD86IEF1dGhDb25maWcgPSB7XG4gICAgICAgIG1vZGU6ICdjb29raWUnLFxuICAgICAgICByZWZyZXNoRW5kcG9pbnQ6ICcvYXV0aC9yZWZyZXNoJyxcbiAgICAgICAgdXNlQ3NyZjogdHJ1ZSxcbiAgICAgICAgcmVmcmVzaFRva2VuQ29va2llTmFtZTogJ3JlZnJlc2hfdG9rZW4nLFxuICAgICAgICBjc3JmVG9rZW5Db29raWVOYW1lOiAnY3NyZl90b2tlbicsXG4gICAgICAgIGNzcmZIZWFkZXJOYW1lOiAnWC1DU1JGLVRva2VuJ1xuICAgIH07XG59Il19
@@ -1,27 +0,0 @@
1
- import { NgModule } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { MyEnvironmentModel } from '../my-environment.model';
4
- import * as i0 from "@angular/core";
5
- export class NgxStoneScriptPhpClientModule {
6
- static forRoot(environment) {
7
- return {
8
- ngModule: NgxStoneScriptPhpClientModule,
9
- providers: [
10
- { provide: MyEnvironmentModel, useValue: environment }
11
- ]
12
- };
13
- }
14
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgxStoneScriptPhpClientModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
15
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: NgxStoneScriptPhpClientModule, imports: [CommonModule] }); }
16
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgxStoneScriptPhpClientModule, imports: [CommonModule] }); }
17
- }
18
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgxStoneScriptPhpClientModule, decorators: [{
19
- type: NgModule,
20
- args: [{
21
- declarations: [],
22
- imports: [
23
- CommonModule
24
- ]
25
- }]
26
- }] });
27
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXN0b25lc2NyaXB0cGhwLWNsaWVudC5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc3RvbmVzY3JpcHRwaHAtY2xpZW50L3NyYy9saWIvbmd4LXN0b25lc2NyaXB0cGhwLWNsaWVudC9uZ3gtc3RvbmVzY3JpcHRwaHAtY2xpZW50Lm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXVCLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM5RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7O0FBVTdELE1BQU0sT0FBTyw2QkFBNkI7SUFDL0IsTUFBTSxDQUFDLE9BQU8sQ0FBQyxXQUErQjtRQUNqRCxPQUFPO1lBQ0gsUUFBUSxFQUFFLDZCQUE2QjtZQUN2QyxTQUFTLEVBQUU7Z0JBQ1AsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRTthQUN6RDtTQUNKLENBQUE7SUFDTCxDQUFDOytHQVJRLDZCQUE2QjtnSEFBN0IsNkJBQTZCLFlBSGxDLFlBQVk7Z0hBR1AsNkJBQTZCLFlBSGxDLFlBQVk7OzRGQUdQLDZCQUE2QjtrQkFOekMsUUFBUTttQkFBQztvQkFDTixZQUFZLEVBQUUsRUFBRTtvQkFDaEIsT0FBTyxFQUFFO3dCQUNMLFlBQVk7cUJBQ2Y7aUJBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNb2R1bGVXaXRoUHJvdmlkZXJzLCBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IE15RW52aXJvbm1lbnRNb2RlbCB9IGZyb20gJy4uL215LWVudmlyb25tZW50Lm1vZGVsJztcblxuXG5cbkBOZ01vZHVsZSh7XG4gICAgZGVjbGFyYXRpb25zOiBbXSxcbiAgICBpbXBvcnRzOiBbXG4gICAgICAgIENvbW1vbk1vZHVsZVxuICAgIF1cbn0pXG5leHBvcnQgY2xhc3MgTmd4U3RvbmVTY3JpcHRQaHBDbGllbnRNb2R1bGUge1xuICAgIHB1YmxpYyBzdGF0aWMgZm9yUm9vdChlbnZpcm9ubWVudDogTXlFbnZpcm9ubWVudE1vZGVsKTogTW9kdWxlV2l0aFByb3ZpZGVyczxOZ3hTdG9uZVNjcmlwdFBocENsaWVudE1vZHVsZT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbmdNb2R1bGU6IE5neFN0b25lU2NyaXB0UGhwQ2xpZW50TW9kdWxlLFxuICAgICAgICAgICAgcHJvdmlkZXJzOiBbXG4gICAgICAgICAgICAgICAgeyBwcm92aWRlOiBNeUVudmlyb25tZW50TW9kZWwsIHVzZVZhbHVlOiBlbnZpcm9ubWVudCB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=
@@ -1,23 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { BehaviorSubject } from 'rxjs';
3
- import * as i0 from "@angular/core";
4
- export class SigninStatusService {
5
- constructor() {
6
- this.status = new BehaviorSubject(false);
7
- }
8
- signedOut() {
9
- this.status.next(false);
10
- }
11
- signedIn() {
12
- this.status.next(true);
13
- }
14
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SigninStatusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
15
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SigninStatusService, providedIn: 'root' }); }
16
- }
17
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SigninStatusService, decorators: [{
18
- type: Injectable,
19
- args: [{
20
- providedIn: 'root'
21
- }]
22
- }], ctorParameters: function () { return []; } });
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmluLXN0YXR1cy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0b25lc2NyaXB0cGhwLWNsaWVudC9zcmMvbGliL3NpZ25pbi1zdGF0dXMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7O0FBS3ZDLE1BQU0sT0FBTyxtQkFBbUI7SUFHNUI7UUFDSSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFBO0lBQ3JELENBQUM7SUFFRCxTQUFTO1FBQ0wsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDM0IsQ0FBQztJQUVELFFBQVE7UUFDSixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUMxQixDQUFDOytHQWJRLG1CQUFtQjttSEFBbkIsbUJBQW1CLGNBRmhCLE1BQU07OzRGQUVULG1CQUFtQjtrQkFIL0IsVUFBVTttQkFBQztvQkFDUixVQUFVLEVBQUUsTUFBTTtpQkFDckIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuQEluamVjdGFibGUoe1xuICAgIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBTaWduaW5TdGF0dXNTZXJ2aWNlIHtcbiAgICBwdWJsaWMgc3RhdHVzOiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj5cblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnN0YXR1cyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpXG4gICAgfVxuXG4gICAgc2lnbmVkT3V0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnN0YXR1cy5uZXh0KGZhbHNlKVxuICAgIH1cblxuICAgIHNpZ25lZEluKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnN0YXR1cy5uZXh0KHRydWUpXG4gICAgfVxufVxuIl19