@proteinjs/user-server 1.21.1 → 1.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/generated/index.d.ts.map +1 -1
  3. package/dist/generated/index.js +5 -1
  4. package/dist/generated/index.js.map +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/src/authentication/PasswordResetToken.d.ts +43 -12
  8. package/dist/src/authentication/PasswordResetToken.d.ts.map +1 -1
  9. package/dist/src/authentication/PasswordResetToken.js +86 -21
  10. package/dist/src/authentication/PasswordResetToken.js.map +1 -1
  11. package/dist/src/routes/devLogin.d.ts +1 -1
  12. package/dist/src/routes/devLogin.js +1 -1
  13. package/dist/src/routes/devMail.d.ts +4 -0
  14. package/dist/src/routes/devMail.d.ts.map +1 -0
  15. package/dist/src/routes/devMail.js +119 -0
  16. package/dist/src/routes/devMail.js.map +1 -0
  17. package/dist/src/routes/executePasswordReset.d.ts +2 -1
  18. package/dist/src/routes/executePasswordReset.d.ts.map +1 -1
  19. package/dist/src/routes/executePasswordReset.js +9 -7
  20. package/dist/src/routes/executePasswordReset.js.map +1 -1
  21. package/dist/src/routes/initiatePasswordReset.d.ts +3 -2
  22. package/dist/src/routes/initiatePasswordReset.d.ts.map +1 -1
  23. package/dist/src/routes/initiatePasswordReset.js +30 -27
  24. package/dist/src/routes/initiatePasswordReset.js.map +1 -1
  25. package/dist/test/DbTraffic.d.ts +29 -0
  26. package/dist/test/DbTraffic.d.ts.map +1 -0
  27. package/dist/test/DbTraffic.js +106 -0
  28. package/dist/test/DbTraffic.js.map +1 -0
  29. package/dist/test/DevLoginBootstrapAdmin.test.js +3 -4
  30. package/dist/test/DevLoginBootstrapAdmin.test.js.map +1 -1
  31. package/dist/test/DevLoginStaleCookieFirstHit.test.js +1 -1
  32. package/dist/test/DevLoginStaleCookieFirstHit.test.js.map +1 -1
  33. package/dist/test/DevMail.test.d.ts +2 -0
  34. package/dist/test/DevMail.test.d.ts.map +1 -0
  35. package/dist/test/DevMail.test.js +250 -0
  36. package/dist/test/DevMail.test.js.map +1 -0
  37. package/dist/test/ExecutePasswordReset.test.js +513 -124
  38. package/dist/test/ExecutePasswordReset.test.js.map +1 -1
  39. package/dist/test/InitiatePasswordReset.test.d.ts +2 -0
  40. package/dist/test/InitiatePasswordReset.test.d.ts.map +1 -0
  41. package/dist/test/InitiatePasswordReset.test.js +415 -0
  42. package/dist/test/InitiatePasswordReset.test.js.map +1 -0
  43. package/dist/test/LogCapture.d.ts +22 -0
  44. package/dist/test/LogCapture.d.ts.map +1 -0
  45. package/dist/test/LogCapture.js +127 -0
  46. package/dist/test/LogCapture.js.map +1 -0
  47. package/dist/test/MalformedResetTokens.d.ts +11 -0
  48. package/dist/test/MalformedResetTokens.d.ts.map +1 -0
  49. package/dist/test/MalformedResetTokens.js +35 -0
  50. package/dist/test/MalformedResetTokens.js.map +1 -0
  51. package/dist/test/ValidateResetToken.test.js +156 -33
  52. package/dist/test/ValidateResetToken.test.js.map +1 -1
  53. package/dist/test/emulatorLock.test.d.ts +2 -0
  54. package/dist/test/emulatorLock.test.d.ts.map +1 -0
  55. package/dist/test/emulatorLock.test.js +32 -0
  56. package/dist/test/emulatorLock.test.js.map +1 -0
  57. package/dist/test/emulatorLockName.test.d.ts +2 -0
  58. package/dist/test/emulatorLockName.test.d.ts.map +1 -0
  59. package/dist/test/emulatorLockName.test.js +36 -0
  60. package/dist/test/emulatorLockName.test.js.map +1 -0
  61. package/generated/index.ts +5 -1
  62. package/index.ts +1 -1
  63. package/jest.config.js +2 -2
  64. package/package.json +4 -4
  65. package/src/authentication/PasswordResetToken.ts +74 -20
  66. package/src/routes/devLogin.ts +1 -1
  67. package/src/routes/devMail.ts +72 -0
  68. package/src/routes/executePasswordReset.ts +3 -2
  69. package/src/routes/initiatePasswordReset.ts +20 -17
  70. package/test/DbTraffic.ts +43 -0
  71. package/test/DevLoginBootstrapAdmin.test.ts +3 -4
  72. package/test/DevLoginStaleCookieFirstHit.test.ts +1 -1
  73. package/test/DevMail.test.ts +151 -0
  74. package/test/ExecutePasswordReset.test.ts +308 -70
  75. package/test/InitiatePasswordReset.test.ts +250 -0
  76. package/test/LogCapture.ts +54 -0
  77. package/test/MalformedResetTokens.ts +27 -0
  78. package/test/ValidateResetToken.test.ts +108 -24
  79. package/test/emulatorLock.js +5 -6
  80. package/test/emulatorLock.test.ts +32 -0
  81. package/test/emulatorLockName.test.ts +33 -0
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ 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;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var email_server_1 = require("@proteinjs/email-server");
40
+ var devMail_1 = require("../src/routes/devMail");
41
+ /**
42
+ * `GET /dev/mail` and `GET /dev/mail/<id>` — the dev-only door onto the mail sink, gated exactly
43
+ * like `/dev/login`: `DEVELOPMENT` AND `DEV_AUTO_LOGIN_EMAIL`, else 404 as if unregistered. With
44
+ * the gates open, the last invite a development sender recorded is readable — its link off the
45
+ * list, its rendered html off the message — so a lane never needs a real inbox. No database:
46
+ * the sink is the process's own ring.
47
+ */
48
+ var ENV_EMAIL = 'dev@test.local';
49
+ var invoke = function (route, _a) {
50
+ var _b = _a === void 0 ? {} : _a, query = _b.query, params = _b.params;
51
+ return __awaiter(void 0, void 0, void 0, function () {
52
+ var outcome, response;
53
+ return __generator(this, function (_c) {
54
+ switch (_c.label) {
55
+ case 0:
56
+ outcome = {};
57
+ response = {
58
+ status: function (code) {
59
+ outcome.status = code;
60
+ return this;
61
+ },
62
+ type: function (kind) {
63
+ outcome.type = kind;
64
+ return this;
65
+ },
66
+ send: function (body) {
67
+ outcome.body = body;
68
+ },
69
+ json: function (body) {
70
+ outcome.body = body;
71
+ },
72
+ };
73
+ return [4 /*yield*/, route.onRequest({ query: query !== null && query !== void 0 ? query : {}, params: params !== null && params !== void 0 ? params : {} }, response)];
74
+ case 1:
75
+ _c.sent();
76
+ return [2 /*return*/, outcome];
77
+ }
78
+ });
79
+ });
80
+ };
81
+ var INVITE_LINK = 'http://localhost:7985/auth/signup?token=abc123';
82
+ var INVITE_HTML = "<html><body><p>You are invited.</p><a href=\"".concat(INVITE_LINK, "\">Accept</a></body></html>");
83
+ /** The product's path onto the sink: a development sender with a real-looking SMTP config, no opt-in. */
84
+ var sendInviteThroughSender = function (to) { return __awaiter(void 0, void 0, void 0, function () {
85
+ return __generator(this, function (_a) {
86
+ switch (_a.label) {
87
+ case 0: return [4 /*yield*/, new email_server_1.EmailSender({
88
+ host: 'smtp.test.local',
89
+ port: 465,
90
+ secure: true,
91
+ auth: { user: 'mailbox@test.local', pass: 'unused' },
92
+ from: '"Example" <hi@example.com>',
93
+ }).sendEmail({ to: to, subject: "You're invited", text: "Accept your invite: ".concat(INVITE_LINK), html: INVITE_HTML })];
94
+ case 1:
95
+ _a.sent();
96
+ return [2 /*return*/];
97
+ }
98
+ });
99
+ }); };
100
+ describe('devMail routes', function () {
101
+ var originalEnv = {
102
+ DEVELOPMENT: process.env.DEVELOPMENT,
103
+ DEV_AUTO_LOGIN_EMAIL: process.env.DEV_AUTO_LOGIN_EMAIL,
104
+ EMAIL_TRANSPORT: process.env.EMAIL_TRANSPORT,
105
+ EMAIL_ALLOW_REAL_SEND: process.env.EMAIL_ALLOW_REAL_SEND,
106
+ };
107
+ beforeEach(function () {
108
+ process.env.DEVELOPMENT = 'true';
109
+ process.env.DEV_AUTO_LOGIN_EMAIL = ENV_EMAIL;
110
+ delete process.env.EMAIL_TRANSPORT;
111
+ delete process.env.EMAIL_ALLOW_REAL_SEND;
112
+ email_server_1.MailSink.get().clear();
113
+ });
114
+ afterEach(function () {
115
+ for (var _i = 0, _a = Object.entries(originalEnv); _i < _a.length; _i++) {
116
+ var _b = _a[_i], key = _b[0], value = _b[1];
117
+ if (value === undefined) {
118
+ delete process.env[key];
119
+ }
120
+ else {
121
+ process.env[key] = value;
122
+ }
123
+ }
124
+ });
125
+ it("lists the last sent messages newest first — the invite's recipient, subject, first link and timestamp — and the message renders its html", function () { return __awaiter(void 0, void 0, void 0, function () {
126
+ var list, messages, message;
127
+ return __generator(this, function (_a) {
128
+ switch (_a.label) {
129
+ case 0: return [4 /*yield*/, sendInviteThroughSender('earlier@test.local')];
130
+ case 1:
131
+ _a.sent();
132
+ return [4 /*yield*/, sendInviteThroughSender('lane-after@test.local')];
133
+ case 2:
134
+ _a.sent();
135
+ return [4 /*yield*/, invoke(devMail_1.devMail)];
136
+ case 3:
137
+ list = _a.sent();
138
+ expect(list.status).toBe(200);
139
+ messages = list.body.messages;
140
+ expect(messages).toHaveLength(2);
141
+ expect(messages[0]).toMatchObject({
142
+ to: ['lane-after@test.local'],
143
+ subject: "You're invited",
144
+ link: INVITE_LINK,
145
+ from: 'hi@example.com',
146
+ refused: true,
147
+ });
148
+ expect(typeof messages[0].id).toBe('string');
149
+ expect(Date.parse(String(messages[0].at))).not.toBeNaN();
150
+ expect(messages[0].url).toBe("/dev/mail/".concat(messages[0].id));
151
+ expect(messages[1].to).toEqual(['earlier@test.local']);
152
+ return [4 /*yield*/, invoke(devMail_1.devMailMessage, { params: { id: String(messages[0].id) } })];
153
+ case 4:
154
+ message = _a.sent();
155
+ expect(message.status).toBe(200);
156
+ expect(message.type).toBe('html');
157
+ expect(message.body).toBe(INVITE_HTML);
158
+ return [2 /*return*/];
159
+ }
160
+ });
161
+ }); });
162
+ it('?n= bounds the list; a text-only message renders as text; an unknown id is 404', function () { return __awaiter(void 0, void 0, void 0, function () {
163
+ var one, all, messages, plain, _a;
164
+ return __generator(this, function (_b) {
165
+ switch (_b.label) {
166
+ case 0:
167
+ process.env.EMAIL_TRANSPORT = 'sink';
168
+ return [4 /*yield*/, new email_server_1.EmailSender({ host: 'h', port: 465, secure: true, from: '"Example" <hi@example.com>' }).sendEmail({
169
+ to: 'a@test.local',
170
+ subject: 'Plain',
171
+ text: 'just text',
172
+ })];
173
+ case 1:
174
+ _b.sent();
175
+ return [4 /*yield*/, sendInviteThroughSender('b@test.local')];
176
+ case 2:
177
+ _b.sent();
178
+ return [4 /*yield*/, invoke(devMail_1.devMail, { query: { n: '1' } })];
179
+ case 3:
180
+ one = _b.sent();
181
+ expect(one.body.messages).toHaveLength(1);
182
+ return [4 /*yield*/, invoke(devMail_1.devMail, { query: { n: 'garbage' } })];
183
+ case 4:
184
+ all = _b.sent();
185
+ messages = all.body.messages;
186
+ expect(messages.map(function (m) { return m.subject; })).toEqual(["You're invited", 'Plain']);
187
+ expect(messages[1].refused).toBe(false);
188
+ return [4 /*yield*/, invoke(devMail_1.devMailMessage, { params: { id: messages[1].id } })];
189
+ case 5:
190
+ plain = _b.sent();
191
+ expect(plain.status).toBe(200);
192
+ expect(plain.type).toBe('text');
193
+ expect(plain.body).toBe('just text');
194
+ _a = expect;
195
+ return [4 /*yield*/, invoke(devMail_1.devMailMessage, { params: { id: 'nope' } })];
196
+ case 6:
197
+ _a.apply(void 0, [(_b.sent()).status]).toBe(404);
198
+ return [2 /*return*/];
199
+ }
200
+ });
201
+ }); });
202
+ it('DEVELOPMENT unset → 404 on both paths, even with messages in the sink', function () { return __awaiter(void 0, void 0, void 0, function () {
203
+ var record, _a, _b;
204
+ return __generator(this, function (_c) {
205
+ switch (_c.label) {
206
+ case 0: return [4 /*yield*/, sendInviteThroughSender('lane@test.local')];
207
+ case 1:
208
+ _c.sent();
209
+ record = email_server_1.MailSink.get().list()[0];
210
+ delete process.env.DEVELOPMENT;
211
+ _a = expect;
212
+ return [4 /*yield*/, invoke(devMail_1.devMail)];
213
+ case 2:
214
+ _a.apply(void 0, [(_c.sent()).status]).toBe(404);
215
+ _b = expect;
216
+ return [4 /*yield*/, invoke(devMail_1.devMailMessage, { params: { id: record.id } })];
217
+ case 3:
218
+ _b.apply(void 0, [(_c.sent()).status]).toBe(404);
219
+ return [2 /*return*/];
220
+ }
221
+ });
222
+ }); });
223
+ it('DEV_AUTO_LOGIN_EMAIL unset (or blank) → 404 on both paths', function () { return __awaiter(void 0, void 0, void 0, function () {
224
+ var record, _a, _b, _c;
225
+ return __generator(this, function (_d) {
226
+ switch (_d.label) {
227
+ case 0: return [4 /*yield*/, sendInviteThroughSender('lane@test.local')];
228
+ case 1:
229
+ _d.sent();
230
+ record = email_server_1.MailSink.get().list()[0];
231
+ delete process.env.DEV_AUTO_LOGIN_EMAIL;
232
+ _a = expect;
233
+ return [4 /*yield*/, invoke(devMail_1.devMail)];
234
+ case 2:
235
+ _a.apply(void 0, [(_d.sent()).status]).toBe(404);
236
+ _b = expect;
237
+ return [4 /*yield*/, invoke(devMail_1.devMailMessage, { params: { id: record.id } })];
238
+ case 3:
239
+ _b.apply(void 0, [(_d.sent()).status]).toBe(404);
240
+ process.env.DEV_AUTO_LOGIN_EMAIL = ' ';
241
+ _c = expect;
242
+ return [4 /*yield*/, invoke(devMail_1.devMail)];
243
+ case 4:
244
+ _c.apply(void 0, [(_d.sent()).status]).toBe(404);
245
+ return [2 /*return*/];
246
+ }
247
+ });
248
+ }); });
249
+ });
250
+ //# sourceMappingURL=DevMail.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevMail.test.js","sourceRoot":"","sources":["../../test/DevMail.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wDAAgE;AAChE,iDAAgE;AAEhE;;;;;;GAMG;AAEH,IAAM,SAAS,GAAG,gBAAgB,CAAC;AAInC,IAAM,MAAM,GAAG,UACb,KAAqB,EACrB,EAA4F;QAA5F,qBAA0F,EAAE,KAAA,EAA1F,KAAK,WAAA,EAAE,MAAM,YAAA;;;;;;oBAET,OAAO,GAAY,EAAE,CAAC;oBACtB,QAAQ,GAAG;wBACf,MAAM,YAAC,IAAY;4BACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;4BACtB,OAAO,IAAI,CAAC;wBACd,CAAC;wBACD,IAAI,YAAC,IAAY;4BACf,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;4BACpB,OAAO,IAAI,CAAC;wBACd,CAAC;wBACD,IAAI,YAAC,IAAc;4BACjB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;wBACtB,CAAC;wBACD,IAAI,YAAC,IAAa;4BAChB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;wBACtB,CAAC;qBACF,CAAC;oBACF,qBAAM,KAAK,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,EAAE,MAAM,EAAE,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,EAAW,EAAE,QAAiB,CAAC,EAAA;;oBAA/F,SAA+F,CAAC;oBAChG,sBAAO,OAAO,EAAC;;;;CAChB,CAAC;AAEF,IAAM,WAAW,GAAG,gDAAgD,CAAC;AACrE,IAAM,WAAW,GAAG,uDAA+C,WAAW,gCAA4B,CAAC;AAE3G,yGAAyG;AACzG,IAAM,uBAAuB,GAAG,UAAO,EAAU;;;oBAC/C,qBAAM,IAAI,0BAAW,CAAC;oBACpB,IAAI,EAAE,iBAAiB;oBACvB,IAAI,EAAE,GAAG;oBACT,MAAM,EAAE,IAAI;oBACZ,IAAI,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACpD,IAAI,EAAE,4BAA4B;iBACnC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,IAAA,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,8BAAuB,WAAW,CAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAA;;gBAN9G,SAM8G,CAAC;;;;KAChH,CAAC;AAEF,QAAQ,CAAC,gBAAgB,EAAE;IACzB,IAAM,WAAW,GAAG;QAClB,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW;QACpC,oBAAoB,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;QACtD,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe;QAC5C,qBAAqB,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB;KACzD,CAAC;IAEF,UAAU,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,SAAS,CAAC;QAC7C,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QACnC,OAAO,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;QACzC,uBAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC;QACR,KAA2B,UAA2B,EAA3B,KAAA,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAA3B,cAA2B,EAA3B,IAA2B,EAAE;YAA7C,IAAA,WAAY,EAAX,GAAG,QAAA,EAAE,KAAK,QAAA;YACpB,IAAI,KAAK,KAAK,SAAS,EAAE;gBACvB,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;aACzB;iBAAM;gBACL,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;aAC1B;SACF;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0IAA0I,EAAE;;;;wBAC7I,qBAAM,uBAAuB,CAAC,oBAAoB,CAAC,EAAA;;oBAAnD,SAAmD,CAAC;oBACpD,qBAAM,uBAAuB,CAAC,uBAAuB,CAAC,EAAA;;oBAAtD,SAAsD,CAAC;oBAE1C,qBAAM,MAAM,CAAC,iBAAO,CAAC,EAAA;;oBAA5B,IAAI,GAAG,SAAqB;oBAClC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACtB,QAAQ,GAAK,IAAI,CAAC,IAAoD,SAA9D,CAA+D;oBAC/E,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oBACjC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;wBAChC,EAAE,EAAE,CAAC,uBAAuB,CAAC;wBAC7B,OAAO,EAAE,gBAAgB;wBACzB,IAAI,EAAE,WAAW;wBACjB,IAAI,EAAE,gBAAgB;wBACtB,OAAO,EAAE,IAAI;qBACd,CAAC,CAAC;oBACH,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAC7C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;oBACzD,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,oBAAa,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAE,CAAC,CAAC;oBAC5D,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;oBAEvC,qBAAM,MAAM,CAAC,wBAAc,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAA;;oBAAlF,OAAO,GAAG,SAAwE;oBACxF,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACjC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBAClC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;;;;SACxC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE;;;;;oBACnF,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,MAAM,CAAC;oBACrC,qBAAM,IAAI,0BAAW,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC,CAAC,SAAS,CAAC;4BAC1G,EAAE,EAAE,cAAc;4BAClB,OAAO,EAAE,OAAO;4BAChB,IAAI,EAAE,WAAW;yBAClB,CAAC,EAAA;;oBAJF,SAIE,CAAC;oBACH,qBAAM,uBAAuB,CAAC,cAAc,CAAC,EAAA;;oBAA7C,SAA6C,CAAC;oBAElC,qBAAM,MAAM,CAAC,iBAAO,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,EAAA;;oBAAlD,GAAG,GAAG,SAA4C;oBACxD,MAAM,CAAE,GAAG,CAAC,IAAgC,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oBAC3D,qBAAM,MAAM,CAAC,iBAAO,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,EAAA;;oBAAxD,GAAG,GAAG,SAAkD;oBACtD,QAAQ,GAAK,GAAG,CAAC,IAA8E,SAAvF,CAAwF;oBACxG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC,CAAC,OAAO,EAAT,CAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC;oBAC5E,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAE1B,qBAAM,MAAM,CAAC,wBAAc,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAA;;oBAAxE,KAAK,GAAG,SAAgE;oBAC9E,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAC/B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBAChC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;oBAErC,KAAA,MAAM,CAAA;oBAAE,qBAAM,MAAM,CAAC,wBAAc,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAA;;oBAAhE,kBAAO,CAAC,SAAwD,CAAC,CAAC,MAAM,EAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;;;;SACrF,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE;;;;wBAC1E,qBAAM,uBAAuB,CAAC,iBAAiB,CAAC,EAAA;;oBAAhD,SAAgD,CAAC;oBAC1C,MAAM,GAAI,uBAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,GAAzB,CAA0B;oBACvC,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;oBAE/B,KAAA,MAAM,CAAA;oBAAE,qBAAM,MAAM,CAAC,iBAAO,CAAC,EAAA;;oBAA7B,kBAAO,CAAC,SAAqB,CAAC,CAAC,MAAM,EAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACjD,KAAA,MAAM,CAAA;oBAAE,qBAAM,MAAM,CAAC,wBAAc,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,EAAA;;oBAAnE,kBAAO,CAAC,SAA2D,CAAC,CAAC,MAAM,EAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;;;;SACxF,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE;;;;wBAC9D,qBAAM,uBAAuB,CAAC,iBAAiB,CAAC,EAAA;;oBAAhD,SAAgD,CAAC;oBAC1C,MAAM,GAAI,uBAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,GAAzB,CAA0B;oBAEvC,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;oBACxC,KAAA,MAAM,CAAA;oBAAE,qBAAM,MAAM,CAAC,iBAAO,CAAC,EAAA;;oBAA7B,kBAAO,CAAC,SAAqB,CAAC,CAAC,MAAM,EAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACjD,KAAA,MAAM,CAAA;oBAAE,qBAAM,MAAM,CAAC,wBAAc,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,EAAA;;oBAAnE,kBAAO,CAAC,SAA2D,CAAC,CAAC,MAAM,EAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAEvF,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,KAAK,CAAC;oBACzC,KAAA,MAAM,CAAA;oBAAE,qBAAM,MAAM,CAAC,iBAAO,CAAC,EAAA;;oBAA7B,kBAAO,CAAC,SAAqB,CAAC,CAAC,MAAM,EAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;;;;SAClD,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}