@driveflux/reporter 5.1.4 → 5.2.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.
package/dist/index.js CHANGED
@@ -1,323 +1,375 @@
1
- // src/index.ts
2
- import { isAProblem } from "@driveflux/problem";
3
- import { singleton as singleton2 } from "@driveflux/singleton";
4
- import { omit as omit2 } from "@driveflux/utils";
5
-
6
- // src/config.ts
7
- import { ProblemSeverity } from "@driveflux/problem";
8
- import { singleton } from "@driveflux/singleton";
9
- var getConfig = () => ({
10
- isProd: process.env.APP_ENV === "production",
11
- deferReporting: typeof process.env.REPORTER_DEFER === "string" && process.env.REPORTER_DEFER !== "" ? process.env.REPORTER_DEFER === "true" : true,
12
- slack: {
13
- errorChannelId: process.env.SLACK_ERROR_CHANNEL,
14
- token: process.env.SLACK_TOKEN,
15
- minimumSeverity: ProblemSeverity.CRITICAL
16
- },
17
- drivers: {
18
- slack: process.env.REPORTER_USE_SLACK === "true",
19
- rollbar: process.env.REPORTER_USE_ROLLBAR === "true",
20
- console: process.env.REPORTER_USE_CONSOLE !== "false"
21
- },
22
- rollbar: {
23
- accessToken: process.env.ROLLBAR_ACCESS_TOKEN,
24
- enabled: true,
25
- captureUncaught: true,
26
- captureUnhandledRejections: true,
27
- environment: process.env.APP_ENV || process.env.NODE_ENV
28
- }
29
- });
30
- var config = singleton("reporterConfig", getConfig());
31
- var resetConfig = () => {
32
- config = singleton("reporterConfig", getConfig(), true);
33
- return config;
34
- };
35
- var setConfig = (key, value) => {
36
- config[key] = value;
37
- };
38
-
39
- // src/drivers/console.ts
40
- var ConsoleDriver = class {
41
- payload;
42
- async reportError(err, _) {
43
- console.error("An error happened");
44
- console.error("Error", err);
45
- console.error("Payload", this.payload);
46
- }
47
- async reportProblem(problem) {
48
- console.error("A problem happened");
49
- console.error("Problem", problem);
50
- console.error("Payload", this.payload);
51
- }
52
- setReporterPayload(payload) {
53
- this.payload = payload;
54
- }
55
- };
56
-
57
- // src/drivers/rollbar.ts
58
- import Rollbar from "rollbar";
59
- var RollbarDriver = class {
60
- rollbar;
61
- constructor(rollbarConfig) {
62
- this.rollbar = new Rollbar(rollbarConfig);
63
- }
64
- async reportError(err, metadata) {
65
- this.rollbar.error(err, metadata.request || {}, metadata.others);
66
- }
67
- async reportProblem(problem) {
68
- await new Promise((resolve) => {
69
- this.rollbar.error(
70
- problem.privateMetadata?.error || new Error(problem.message || problem.code),
71
- problem.privateMetadata?.request,
72
- problem.privateMetadata || {},
73
- (error) => {
74
- resolve(error);
75
- }
76
- );
77
- });
78
- }
79
- setReporterPayload(payload) {
80
- this.rollbar.configure({ payload });
81
- }
82
- };
83
-
84
- // src/drivers/slack.ts
85
- import { enhancedFetch } from "@driveflux/fetch";
86
- import { ProblemSeverity as ProblemSeverity2, hasSeverityGte } from "@driveflux/problem";
87
- import { isEmpty, omit } from "@driveflux/utils";
88
- import { flatten } from "flat";
89
- var lines = (object) => {
90
- return {
91
- type: "section",
92
- fields: Object.keys(object).map((key) => ({
93
- type: "mrkdwn",
94
- body: `*${key}:*
95
- ${JSON.stringify(object[key])}`
96
- }))
97
- };
98
- };
99
- var SlackDriver = class {
100
- accessToken;
101
- payload = {};
102
- channel;
103
- constructor(slackConfig) {
104
- this.accessToken = slackConfig.token;
105
- this.channel = slackConfig.errorChannelId;
106
- }
107
- async reportError(err, metadata) {
108
- const blocks = [
109
- {
110
- type: "header",
111
- text: {
112
- type: "mrkdwn",
113
- text: ":fire: Unexpected error happened",
114
- emoji: true
115
- }
116
- },
117
- {
118
- type: "section",
119
- text: {
120
- type: "mrkdwn",
121
- text: err.message
122
- }
123
- }
124
- ];
125
- this.standardBody(blocks, metadata);
126
- await this.slack(blocks);
127
- }
128
- async reportProblem(problem) {
129
- if (!hasSeverityGte(problem, config.slack?.minimumSeverity || ProblemSeverity2.CRITICAL)) {
130
- return;
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
2
+ try {
3
+ var info = gen[key](arg);
4
+ var value = info.value;
5
+ } catch (error) {
6
+ reject(error);
7
+ return;
131
8
  }
132
- const blocks = [
133
- {
134
- type: "header",
135
- text: {
136
- type: "plain_text",
137
- text: "Problem",
138
- emoji: true
139
- }
140
- },
141
- {
142
- type: "section",
143
- text: {
144
- type: "mrkdwn",
145
- text: `*Code:*: ${problem.code}
146
- *Message:* ${problem.message}`
147
- }
148
- }
149
- ];
150
- this.standardBody(blocks, problem.metadata);
151
- await this.slack(blocks);
152
- }
153
- setReporterPayload(payload) {
154
- this.payload = payload;
155
- }
156
- async slack(blocks) {
157
- return await enhancedFetch("https://slack.com/api/chat.postMessage", {
158
- method: "POST",
159
- headers: {
160
- Authorization: `Bearer ${this.accessToken}`
161
- },
162
- body: JSON.stringify({
163
- channel: this.channel,
164
- blocks
165
- })
166
- });
167
- }
168
- standardBody(blocks, metadata) {
169
- if (metadata?.request) {
170
- blocks.push({
171
- type: "section",
172
- text: {
173
- type: "plain_text",
174
- text: "Request:"
175
- }
176
- });
177
- blocks.push({
178
- type: "section",
179
- fields: [
180
- {
181
- type: "mrkdwn",
182
- body: `*URL:*
183
- ${metadata.request?.url}`
184
- },
185
- {
186
- type: "mrkdwn",
187
- body: `*Method:*
188
- ${metadata.request?.method}`
189
- }
190
- ]
191
- });
9
+ if (info.done) {
10
+ resolve(value);
11
+ } else {
12
+ Promise.resolve(value).then(_next, _throw);
13
+ }
14
+ }
15
+ function _async_to_generator(fn) {
16
+ return function() {
17
+ var self = this, args = arguments;
18
+ return new Promise(function(resolve, reject) {
19
+ var gen = fn.apply(self, args);
20
+ function _next(value) {
21
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
22
+ }
23
+ function _throw(err) {
24
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
25
+ }
26
+ _next(undefined);
27
+ });
28
+ };
29
+ }
30
+ function _define_property(obj, key, value) {
31
+ if (key in obj) {
32
+ Object.defineProperty(obj, key, {
33
+ value: value,
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true
37
+ });
38
+ } else {
39
+ obj[key] = value;
192
40
  }
193
- if (metadata) {
194
- blocks.push({
195
- type: "section",
196
- text: {
197
- type: "plain_text",
198
- text: "Other Information:"
41
+ return obj;
42
+ }
43
+ function _object_spread(target) {
44
+ for(var i = 1; i < arguments.length; i++){
45
+ var source = arguments[i] != null ? arguments[i] : {};
46
+ var ownKeys = Object.keys(source);
47
+ if (typeof Object.getOwnPropertySymbols === "function") {
48
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
49
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
50
+ }));
199
51
  }
200
- });
201
- blocks.push(lines(flatten(omit(metadata, "request"))));
52
+ ownKeys.forEach(function(key) {
53
+ _define_property(target, key, source[key]);
54
+ });
202
55
  }
203
- if (!isEmpty(this.payload)) {
204
- blocks.push({
205
- type: "section",
206
- text: {
207
- type: "plain_text",
208
- text: "Other Information:"
56
+ return target;
57
+ }
58
+ function ownKeys(object, enumerableOnly) {
59
+ var keys = Object.keys(object);
60
+ if (Object.getOwnPropertySymbols) {
61
+ var symbols = Object.getOwnPropertySymbols(object);
62
+ if (enumerableOnly) {
63
+ symbols = symbols.filter(function(sym) {
64
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
65
+ });
209
66
  }
210
- });
211
- blocks.push(lines(flatten(this.payload)));
67
+ keys.push.apply(keys, symbols);
212
68
  }
213
- }
214
- };
215
-
216
- // src/index.ts
217
- var problemsAndErrorsToReport = singleton2("reporterProblemsAndErrors", /* @__PURE__ */ new Set());
218
- var customDrivers = singleton2("reporterCustomDrivers", /* @__PURE__ */ new Map());
219
- var addDriver = (name, reporter, enabled = true) => {
220
- customDrivers.set(name, {
221
- enabled,
222
- reporter
223
- });
224
- };
225
- var getDriver = (driver) => {
226
- switch (driver) {
227
- case "console":
228
- return new ConsoleDriver();
229
- case "rollbar":
230
- return new RollbarDriver(config.rollbar);
231
- case "slack": {
232
- if (!config.slack) {
233
- throw new Error(`Slack config missing`);
234
- }
235
- return new SlackDriver(config.slack);
69
+ return keys;
70
+ }
71
+ function _object_spread_props(target, source) {
72
+ source = source != null ? source : {};
73
+ if (Object.getOwnPropertyDescriptors) {
74
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
75
+ } else {
76
+ ownKeys(Object(source)).forEach(function(key) {
77
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
78
+ });
236
79
  }
237
- default: {
238
- const customDriver = customDrivers.get(driver);
239
- if (!customDriver) {
240
- throw new Error(`Driver ${driver} not found.`);
241
- }
242
- return customDriver.reporter;
80
+ return target;
81
+ }
82
+ function _ts_generator(thisArg, body) {
83
+ var f, y, t, g, _ = {
84
+ label: 0,
85
+ sent: function() {
86
+ if (t[0] & 1) throw t[1];
87
+ return t[1];
88
+ },
89
+ trys: [],
90
+ ops: []
91
+ };
92
+ return g = {
93
+ next: verb(0),
94
+ "throw": verb(1),
95
+ "return": verb(2)
96
+ }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
97
+ return this;
98
+ }), g;
99
+ function verb(n) {
100
+ return function(v) {
101
+ return step([
102
+ n,
103
+ v
104
+ ]);
105
+ };
243
106
  }
244
- }
245
- };
246
- var getDrivers = () => {
247
- return Object.keys(config.drivers).map((driver) => {
248
- if (config.drivers[driver] || customDrivers.get(driver)?.enabled) {
249
- return getDriver(driver);
107
+ function step(op) {
108
+ if (f) throw new TypeError("Generator is already executing.");
109
+ while(_)try {
110
+ 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;
111
+ if (y = 0, t) op = [
112
+ op[0] & 2,
113
+ t.value
114
+ ];
115
+ switch(op[0]){
116
+ case 0:
117
+ case 1:
118
+ t = op;
119
+ break;
120
+ case 4:
121
+ _.label++;
122
+ return {
123
+ value: op[1],
124
+ done: false
125
+ };
126
+ case 5:
127
+ _.label++;
128
+ y = op[1];
129
+ op = [
130
+ 0
131
+ ];
132
+ continue;
133
+ case 7:
134
+ op = _.ops.pop();
135
+ _.trys.pop();
136
+ continue;
137
+ default:
138
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
139
+ _ = 0;
140
+ continue;
141
+ }
142
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
143
+ _.label = op[1];
144
+ break;
145
+ }
146
+ if (op[0] === 6 && _.label < t[1]) {
147
+ _.label = t[1];
148
+ t = op;
149
+ break;
150
+ }
151
+ if (t && _.label < t[2]) {
152
+ _.label = t[2];
153
+ _.ops.push(op);
154
+ break;
155
+ }
156
+ if (t[2]) _.ops.pop();
157
+ _.trys.pop();
158
+ continue;
159
+ }
160
+ op = body.call(thisArg, _);
161
+ } catch (e) {
162
+ op = [
163
+ 6,
164
+ e
165
+ ];
166
+ y = 0;
167
+ } finally{
168
+ f = t = 0;
169
+ }
170
+ if (op[0] & 5) throw op[1];
171
+ return {
172
+ value: op[0] ? op[1] : void 0,
173
+ done: true
174
+ };
250
175
  }
251
- return;
252
- }).filter((d) => d);
253
- };
254
- var reportError = async (err, metadata = {}, sync) => {
255
- const defer = typeof sync === "boolean" ? !sync : config.deferReporting;
256
- if (defer) {
257
- problemsAndErrorsToReport.add(err);
258
- } else {
259
- await commitSingleError(err, metadata);
260
- }
261
- return err;
262
- };
263
- var reportProblem = async (problem, sync) => {
264
- const defer = typeof sync === "boolean" ? !sync : config.deferReporting;
265
- if (defer) {
266
- problemsAndErrorsToReport.add(problem);
267
- } else {
268
- await commitSingleProblem(problem);
269
- }
270
- return problem;
271
- };
272
- var commitReportingErrors = async () => {
273
- const promises = [];
274
- const problemsToReport = problemsAndErrorsToReport.values();
275
- problemsAndErrorsToReport.clear();
276
- for (const err of problemsToReport) {
277
- promises.push(isAProblem(err) ? commitSingleProblem(err) : commitSingleError(err));
278
- }
279
- await Promise.allSettled(promises);
176
+ }
177
+ import { isAProblem } from '@driveflux/problem';
178
+ import { singleton } from '@driveflux/singleton';
179
+ import { omit } from '@driveflux/utils';
180
+ import { config } from './config.js';
181
+ import { ConsoleDriver } from './drivers/console.js';
182
+ import { RollbarDriver } from './drivers/rollbar.js';
183
+ import { SlackDriver } from './drivers/slack.js';
184
+ export * from './config.js';
185
+ var problemsAndErrorsToReport = singleton('reporterProblemsAndErrors', new Set());
186
+ var customDrivers = singleton('reporterCustomDrivers', new Map());
187
+ export var addDriver = function(name, reporter) {
188
+ var enabled = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : true;
189
+ customDrivers.set(name, {
190
+ enabled: enabled,
191
+ reporter: reporter
192
+ });
280
193
  };
281
- var commitSingleError = (err, metadata = {}) => {
282
- return Promise.allSettled(
283
- getDrivers().map((driver) => {
284
- return driver.reportError(err, {
285
- request: metadata.request,
286
- others: omit2(metadata, "request")
287
- });
288
- })
289
- );
194
+ export var getDriver = function(driver) {
195
+ switch(driver){
196
+ case 'console':
197
+ return new ConsoleDriver();
198
+ case 'rollbar':
199
+ return new RollbarDriver(config.rollbar);
200
+ case 'slack':
201
+ {
202
+ if (!config.slack) {
203
+ throw new Error("Slack config missing");
204
+ }
205
+ return new SlackDriver(config.slack);
206
+ }
207
+ default:
208
+ {
209
+ var customDriver = customDrivers.get(driver);
210
+ if (!customDriver) {
211
+ throw new Error("Driver ".concat(driver, " not found."));
212
+ }
213
+ return customDriver.reporter;
214
+ }
215
+ }
290
216
  };
291
- var commitSingleProblem = (problem) => {
292
- return Promise.allSettled(
293
- getDrivers().map((driver) => {
294
- return driver.reportProblem({
295
- ...problem,
296
- privateMetadata: {
297
- request: problem.privateMetadata?.request,
298
- others: {
299
- ...problem.metadata,
300
- ...problem.privateMetadata ? omit2(problem.privateMetadata, "request") : void 0
301
- }
217
+ var getDrivers = function() {
218
+ return Object.keys(config.drivers).map(function(driver) {
219
+ var _customDrivers_get;
220
+ if (config.drivers[driver] || ((_customDrivers_get = customDrivers.get(driver)) === null || _customDrivers_get === void 0 ? void 0 : _customDrivers_get.enabled)) {
221
+ return getDriver(driver);
302
222
  }
303
- });
304
- })
305
- );
223
+ return;
224
+ }).filter(function(d) {
225
+ return d;
226
+ });
306
227
  };
307
- var setReporterPayload = (payload) => {
308
- getDrivers().forEach((driver) => {
309
- driver.setReporterPayload(payload);
310
- });
228
+ export var reportError = function() {
229
+ var _ref = _async_to_generator(function(err) {
230
+ var metadata, sync, defer;
231
+ var _arguments = arguments;
232
+ return _ts_generator(this, function(_state) {
233
+ switch(_state.label){
234
+ case 0:
235
+ metadata = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, sync = _arguments.length > 2 ? _arguments[2] : void 0;
236
+ defer = typeof sync === 'boolean' ? !sync : config.deferReporting;
237
+ if (!defer) return [
238
+ 3,
239
+ 1
240
+ ];
241
+ problemsAndErrorsToReport.add(err);
242
+ return [
243
+ 3,
244
+ 3
245
+ ];
246
+ case 1:
247
+ return [
248
+ 4,
249
+ commitSingleError(err, metadata)
250
+ ];
251
+ case 2:
252
+ _state.sent();
253
+ _state.label = 3;
254
+ case 3:
255
+ return [
256
+ 2,
257
+ err
258
+ ];
259
+ }
260
+ });
261
+ });
262
+ return function reportError(err) {
263
+ return _ref.apply(this, arguments);
264
+ };
265
+ }();
266
+ /**
267
+ *
268
+ * @todo make function
269
+ * @param problem
270
+ */ export var reportProblem = function() {
271
+ var _ref = _async_to_generator(function(problem, sync) {
272
+ var defer;
273
+ return _ts_generator(this, function(_state) {
274
+ switch(_state.label){
275
+ case 0:
276
+ defer = typeof sync === 'boolean' ? !sync : config.deferReporting;
277
+ if (!defer) return [
278
+ 3,
279
+ 1
280
+ ];
281
+ problemsAndErrorsToReport.add(problem);
282
+ return [
283
+ 3,
284
+ 3
285
+ ];
286
+ case 1:
287
+ return [
288
+ 4,
289
+ commitSingleProblem(problem)
290
+ ];
291
+ case 2:
292
+ _state.sent();
293
+ _state.label = 3;
294
+ case 3:
295
+ return [
296
+ 2,
297
+ problem
298
+ ];
299
+ }
300
+ });
301
+ });
302
+ return function reportProblem(problem, sync) {
303
+ return _ref.apply(this, arguments);
304
+ };
305
+ }();
306
+ export var commitReportingErrors = function() {
307
+ var _ref = _async_to_generator(function() {
308
+ var promises, problemsToReport, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _$err;
309
+ return _ts_generator(this, function(_state) {
310
+ switch(_state.label){
311
+ case 0:
312
+ promises = [];
313
+ problemsToReport = problemsAndErrorsToReport.values();
314
+ problemsAndErrorsToReport.clear();
315
+ _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
316
+ try {
317
+ for(_iterator = problemsToReport[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
318
+ _$err = _step.value;
319
+ promises.push(isAProblem(_$err) ? commitSingleProblem(_$err) : commitSingleError(_$err));
320
+ }
321
+ } catch (err) {
322
+ _didIteratorError = true;
323
+ _iteratorError = err;
324
+ } finally{
325
+ try {
326
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
327
+ _iterator.return();
328
+ }
329
+ } finally{
330
+ if (_didIteratorError) {
331
+ throw _iteratorError;
332
+ }
333
+ }
334
+ }
335
+ return [
336
+ 4,
337
+ Promise.allSettled(promises)
338
+ ];
339
+ case 1:
340
+ _state.sent();
341
+ return [
342
+ 2
343
+ ];
344
+ }
345
+ });
346
+ });
347
+ return function commitReportingErrors() {
348
+ return _ref.apply(this, arguments);
349
+ };
350
+ }();
351
+ var commitSingleError = function(err) {
352
+ var metadata = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
353
+ return Promise.allSettled(getDrivers().map(function(driver) {
354
+ return driver.reportError(err, {
355
+ request: metadata.request,
356
+ others: omit(metadata, 'request')
357
+ });
358
+ }));
359
+ };
360
+ var commitSingleProblem = function(problem) {
361
+ return Promise.allSettled(getDrivers().map(function(driver) {
362
+ var _problem_privateMetadata;
363
+ return driver.reportProblem(_object_spread_props(_object_spread({}, problem), {
364
+ privateMetadata: {
365
+ request: (_problem_privateMetadata = problem.privateMetadata) === null || _problem_privateMetadata === void 0 ? void 0 : _problem_privateMetadata.request,
366
+ others: _object_spread({}, problem.metadata, problem.privateMetadata ? omit(problem.privateMetadata, 'request') : undefined)
367
+ }
368
+ }));
369
+ }));
311
370
  };
312
- export {
313
- addDriver,
314
- commitReportingErrors,
315
- config,
316
- getDriver,
317
- reportError,
318
- reportProblem,
319
- resetConfig,
320
- setConfig,
321
- setReporterPayload
371
+ export var setReporterPayload = function(payload) {
372
+ getDrivers().forEach(function(driver) {
373
+ driver.setReporterPayload(payload);
374
+ });
322
375
  };
323
- //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAEjD,MAAM,WAAW,QAAQ;IACvB,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1D,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9C,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAA;CACvD;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,CAAC,EAAE,OAAO,MAAM,EAAE,eAAe,CAAA;IACxC,MAAM,CAAC,EAAE,GAAG,CAAA;CACb,CAAA;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAA;CACd"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAEjD,MAAM,WAAW,QAAQ;IACxB,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1D,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9C,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAA;CACtD;AAED,MAAM,MAAM,QAAQ,GAAG;IACtB,OAAO,CAAC,EAAE,OAAO,MAAM,EAAE,eAAe,CAAA;IACxC,MAAM,CAAC,EAAE,GAAG,CAAA;CACZ,CAAA;AAED,MAAM,WAAW,QAAQ;IACxB,KAAK,EAAE,MAAM,CAAA;CACb"}