@weavix/tracker-plugin-sdk 0.0.1 → 0.0.2

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/README.md CHANGED
@@ -283,6 +283,145 @@ import type {
283
283
  } from '@weavix/tracker-plugin-sdk';
284
284
  ```
285
285
 
286
+ ## Вызов внешних API
287
+
288
+ Методы `hostApi` для работы с внешними API через прокси хоста: проверка и запрос учётных данных пользователя по доменам из манифеста и выполнение HTTP-запросов от имени плагина.
289
+
290
+ Домены и схемы авторизации задаются в манифесте плагина в `permissions.external`.
291
+
292
+ ```typescript
293
+ import { hostApi } from '@weavix/tracker-plugin-sdk';
294
+
295
+ // Проверить, указал ли пользователь авторизационные данные для доменов, и при необходимости запросить их через диалог
296
+ const { success } = await hostApi.externalApiAuthCheckAndRequest({
297
+ domains: ['api.example.com'],
298
+ });
299
+ if (!success) {
300
+ // пользователь отменил диалог или истёк таймаут ожидания
301
+ return;
302
+ }
303
+
304
+ // Прокси-вызов внешнего API (учётные данные подставляет хост)
305
+ const { status, body } = await hostApi.externalApiCall({
306
+ url: 'https://api.example.com/v1/items',
307
+ method: 'GET',
308
+ });
309
+ ```
310
+
311
+ Типичный сценарий: `externalApiAuthCheckAndRequest` (или пара `externalApiAuthGetStatus` + `externalApiAuthRequest`) → `externalApiCall`. Отзыв сохранённых данных — `externalApiAuthRevoke`.
312
+
313
+ ### `hostApi.externalApiAuthGetStatus(payload)`
314
+
315
+ Возвращает статус учётных данных пользователя по доменам.
316
+
317
+ | Параметр | Тип | По умолчанию | Описание |
318
+ |----------|-----|--------------|----------|
319
+ | `domains` | `string[] \| undefined` | все домены плагина | Список доменов для проверки |
320
+ | `contextType` | `'user' \| 'organization' \| undefined` | — | Тип контекста учётных данных (в контракте payload) |
321
+
322
+ **Возвращает:** `Promise<{ domains: ExternalApiAuthGetStatusDomain[] }>`.
323
+
324
+ Если `domains` не передан или пуст, хост запрашивает статус по всем доменам плагина.
325
+
326
+ ### `hostApi.externalApiAuthRequest(payload)`
327
+
328
+ Показывает пользователю диалог ввода учётных данных для указанных доменов. При успешном подтверждении хост сохраняет credentials.
329
+
330
+ | Параметр | Тип | По умолчанию | Описание |
331
+ |----------|-----|--------------|----------|
332
+ | `domains` | `ExternalApiDomainInfo[]` | — | Домены (обязательно, минимум один) |
333
+
334
+ **`ExternalApiDomainInfo`:**
335
+
336
+ | Поле | Тип | Описание |
337
+ |------|-----|----------|
338
+ | `domain` | `string` | Домен из манифеста |
339
+ | `instructions` | `string \| { en?: string; ru?: string }` | Подсказка в диалоге (опционально) |
340
+
341
+ **Возвращает:** `Promise<{ success: boolean }>`. `success: false` — пользователь закрыл диалог или не завершил авторизацию. Ожидание ответа пользователя ограничено по времени (около 5 минут).
342
+
343
+ ### `hostApi.externalApiAuthRevoke(payload)`
344
+
345
+ Отзывает сохранённую аутентификацию для указанных доменов.
346
+
347
+ | Параметр | Тип | По умолчанию | Описание |
348
+ |----------|-----|--------------|----------|
349
+ | `domains` | `string[]` | — | Домены для отзыва (обязательно, минимум один) |
350
+ | `contextType` | `'user' \| 'organization' \| undefined` | — | Тип контекста учётных данных (в контракте payload) |
351
+
352
+ **Возвращает:** `Promise<{ success: boolean }>`. `success: true`, если отзыв прошёл для всех переданных доменов.
353
+
354
+ ### `hostApi.externalApiAuthCheckAndRequest(payload)`
355
+
356
+ Комбинирует проверку статуса и запрос credentials только для неаутентифицированных доменов. Payload совпадает с `externalApiAuthGetStatus`.
357
+
358
+ | Параметр | Тип | По умолчанию | Описание |
359
+ |----------|-----|--------------|----------|
360
+ | `domains` | `string[] \| undefined` | все домены плагина | Домены для проверки |
361
+ | `contextType` | `'user' \| 'organization' \| undefined` | — | Тип контекста (в контракте payload) |
362
+
363
+ **Возвращает:** `Promise<{ success: boolean }>`. Если все домены уже аутентифицированы — сразу `{ success: true }` без диалога. Иначе показывается тот же диалог, что и у `externalApiAuthRequest`; при успехе credentials сохраняются.
364
+
365
+ ### `hostApi.externalApiCall(payload)`
366
+
367
+ Выполняет HTTP-запрос к внешнему API через прокси платформы. URL должен относиться к домену, разрешённому в `permissions.external`; заголовки авторизации подставляет хост.
368
+
369
+ | Параметр | Тип | По умолчанию | Описание |
370
+ |----------|-----|--------------|----------|
371
+ | `url` | `string` | — | Полный URL запроса (обязательный) |
372
+ | `method` | `'GET' \| 'POST' \| 'PUT' \| 'PATCH' \| 'DELETE'` | — | HTTP-метод (обязательный) |
373
+ | `headers` | `Record<string, string>` | — | Дополнительные заголовки |
374
+ | `body` | `Record<string, unknown>` | — | Тело запроса (для методов с телом) |
375
+ | `timeoutMs` | `number` | — | Таймаут запроса в миллисекундах |
376
+ | `contextType` | `'user' \| 'organization' \| undefined` | — | Контекст учётных данных для прокси |
377
+
378
+ **Возвращает:** `Promise<{ status: number; headers?: Record<string, string>; body?: Record<string, unknown> }>`.
379
+
380
+ При ошибке прокси-запроса (ответ платформы с `status`, `code`, `message`) метод бросает `PluginActionError` с кодом `EXTERNAL_API_CALL_ERROR` (`1013`); детали — в `errorData` (`status`, `message`, `code`, `title`).
381
+
382
+ ### Ошибки
383
+
384
+ | Код | Константа | Когда |
385
+ |-----|-----------|-------|
386
+ | `1013` | `EXTERNAL_API_CALL_ERROR` | Прокси-вызов `externalApiCall` завершился ошибкой |
387
+
388
+ ```typescript
389
+ import {
390
+ EXTERNAL_API_CALL_ERROR,
391
+ PluginActionError,
392
+ hostApi,
393
+ } from '@weavix/tracker-plugin-sdk';
394
+
395
+ try {
396
+ await hostApi.externalApiCall({ url: 'https://api.example.com/x', method: 'GET' });
397
+ } catch (e) {
398
+ if (e instanceof PluginActionError && e.code === EXTERNAL_API_CALL_ERROR) {
399
+ console.log(e.errorData);
400
+ }
401
+ }
402
+ ```
403
+
404
+ ### Типы
405
+
406
+ ```typescript
407
+ import type {
408
+ AuthContextType,
409
+ ExternalApiAuthGetStatusPayload,
410
+ ExternalApiAuthGetStatusResult,
411
+ ExternalApiAuthGetStatusDomain,
412
+ ExternalApiAuthRequestPayload,
413
+ ExternalApiAuthRequestResult,
414
+ ExternalApiAuthRevokePayload,
415
+ ExternalApiAuthRevokeResult,
416
+ ExternalApiAuthCheckAndRequestPayload,
417
+ ExternalApiAuthCheckAndRequestResult,
418
+ ExternalApiCallPayload,
419
+ ExternalApiCallResult,
420
+ ExternalApiDomainInfo,
421
+ PluginProxyMethod,
422
+ } from '@weavix/tracker-plugin-sdk';
423
+ ```
424
+
286
425
  ## Обработка ошибок
287
426
 
288
427
  ```typescript
@@ -309,6 +448,11 @@ try {
309
448
  - `updateContentSize(request)` — обновление высоты контейнера плагина
310
449
  - `notifyReady()` — уведомление хоста о готовности плагина
311
450
  - `disableAutoResize()` — отключение автоматического изменения размера
451
+ - `externalApiAuthGetStatus(payload)` — статус аутентификации по доменам
452
+ - `externalApiAuthRequest(payload)` — диалог запроса учётных данных
453
+ - `externalApiAuthRevoke(payload)` — отзыв аутентификации
454
+ - `externalApiAuthCheckAndRequest(payload)` — проверка и запрос credentials для неаутентифицированных доменов
455
+ - `externalApiCall(payload)` — прокси HTTP к внешнему API
312
456
 
313
457
  ### `uiApi`
314
458
 
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trackerApi.d.ts","sourceRoot":"","sources":["../../src/api/trackerApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,qBAAqB,IAAI,eAAe,EAC7C,KAAK,qBAAqB,IAAI,eAAe,EAEhD,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,qBAAqB,GAAG,eAAe,CAAC;AACpD,MAAM,MAAM,qBAAqB,GAAG,eAAe,CAAC;AAEpD,KAAK,SAAS,CAAC,CAAC,IAAI;KACf,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,GAC7D,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,GACrE,KAAK;CACd,CAAC;AAEF,MAAM,WAAW,YAAY;IACzB,GAAG,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;IAChC,IAAI,EAAE,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAClC,GAAG,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;IAChC,KAAK,EAAE,SAAS,CAAC,iBAAiB,CAAC,CAAC;IACpC,MAAM,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,UAAU;IACvB,EAAE,EAAE,YAAY,CAAC;CACpB;AAED,eAAO,MAAM,UAAU,EAAgC,UAAU,CAAC"}
@@ -7,7 +7,7 @@ export { getHandler, setHandler } from '@weavix/tracker-core';
7
7
  export type { GetDataResultMap, HandlerFunction, Handlers, HttpMethod } from '@weavix/tracker-core';
8
8
  export { dispatchHostEvent, on, resetEventBus } from '../../plugin-sdk-core/src/index.ts';
9
9
  export type { EventMessage, HostEventCallback, HostEventContract, HostEventMethod, Unsubscribe, } from '../../plugin-sdk-core/src/index.ts';
10
- export { BAD_KEY, DATA_TOO_LARGE, METHOD_NOT_SUPPORTED, MISSING_REQUIRED_SCOPE, PLUGIN_ID_IS_NOT_CORRECT, PLUGIN_ID_OR_SLOT_NOT_PROVIDED, PluginActionError, UNKNOWN_ERROR, VALIDATION_ERROR, VERSION_CONFLICT, } from '../../plugin-sdk-core/src/index.ts';
10
+ export { BAD_KEY, DATA_TOO_LARGE, EXTERNAL_API_CALL_ERROR, METHOD_NOT_SUPPORTED, MISSING_REQUIRED_SCOPE, PLUGIN_ID_IS_NOT_CORRECT, PLUGIN_ID_OR_SLOT_NOT_PROVIDED, PluginActionError, UNKNOWN_ERROR, VALIDATION_ERROR, VERSION_CONFLICT, } from '../../plugin-sdk-core/src/index.ts';
11
11
  export type { BasicContext, ContextLevel, Theme } from '../../plugin-sdk-core/src/index.ts';
12
12
  export type { Attachment, AttachmentViewerActionSlotContext, BoardTabSlotContext, GoalSlotContext, Issue, IssueCommentActionSlotContext, LocalizedString, MetaEntityV2, PortfolioSlotContext, ProjectSlotContext, SlotContextMap, TriggerActionData, TriggerCreateActionsSlotContext, TriggerEditActionsSlotContext, } from '@weavix/tracker-core';
13
13
  export { uiApi } from '../../plugin-sdk-core/src/index.ts';
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EACR,UAAU,EACV,qBAAqB,EACrB,qBAAqB,EACrB,YAAY,GACf,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAGjE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC9D,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGpG,OAAO,EAAE,iBAAiB,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACxE,YAAY,EACR,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,WAAW,GACd,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACH,OAAO,EACP,cAAc,EACd,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,8BAA8B,EAC9B,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACnB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC1E,YAAY,EACR,UAAU,EACV,iCAAiC,EACjC,mBAAmB,EACnB,eAAe,EACf,KAAK,EACL,6BAA6B,EAC7B,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,+BAA+B,EAC/B,6BAA6B,GAChC,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGjG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,YAAY,EACR,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,GAChB,MAAM,sBAAsB,CAAC"}
package/dist/index.mjs CHANGED
@@ -1,28 +1,29 @@
1
- import { trackerApi as r } from "@weavix/tracker-core";
2
- import { getHandler as o, getLocalizedString as E, hostApi as R, setHandler as i, storageApi as A } from "@weavix/tracker-core";
3
- import { BAD_KEY as N, DATA_TOO_LARGE as p, METHOD_NOT_SUPPORTED as T, MISSING_REQUIRED_SCOPE as D, PLUGIN_ID_IS_NOT_CORRECT as a, PLUGIN_ID_OR_SLOT_NOT_PROVIDED as n, PluginActionError as s, UNKNOWN_ERROR as S, VALIDATION_ERROR as c, VERSION_CONFLICT as L, dispatchHostEvent as P, getField as g, on as d, resetEventBus as l, uiApi as C } from "@weavix/sdk-core";
4
- const e = r;
1
+ import { trackerApi as _ } from "@weavix/tracker-core";
2
+ import { getHandler as R, getLocalizedString as E, hostApi as A, setHandler as o, storageApi as i } from "@weavix/tracker-core";
3
+ import { BAD_KEY as N, DATA_TOO_LARGE as T, EXTERNAL_API_CALL_ERROR as p, METHOD_NOT_SUPPORTED as D, MISSING_REQUIRED_SCOPE as L, PLUGIN_ID_IS_NOT_CORRECT as a, PLUGIN_ID_OR_SLOT_NOT_PROVIDED as n, PluginActionError as s, UNKNOWN_ERROR as P, VALIDATION_ERROR as S, VERSION_CONFLICT as c, dispatchHostEvent as g, getField as C, on as d, resetEventBus as l, uiApi as U } from "@weavix/sdk-core";
4
+ const t = _;
5
5
  export {
6
6
  N as BAD_KEY,
7
- p as DATA_TOO_LARGE,
8
- T as METHOD_NOT_SUPPORTED,
9
- D as MISSING_REQUIRED_SCOPE,
7
+ T as DATA_TOO_LARGE,
8
+ p as EXTERNAL_API_CALL_ERROR,
9
+ D as METHOD_NOT_SUPPORTED,
10
+ L as MISSING_REQUIRED_SCOPE,
10
11
  a as PLUGIN_ID_IS_NOT_CORRECT,
11
12
  n as PLUGIN_ID_OR_SLOT_NOT_PROVIDED,
12
13
  s as PluginActionError,
13
- S as UNKNOWN_ERROR,
14
- c as VALIDATION_ERROR,
15
- L as VERSION_CONFLICT,
16
- P as dispatchHostEvent,
17
- g as getField,
18
- o as getHandler,
14
+ P as UNKNOWN_ERROR,
15
+ S as VALIDATION_ERROR,
16
+ c as VERSION_CONFLICT,
17
+ g as dispatchHostEvent,
18
+ C as getField,
19
+ R as getHandler,
19
20
  E as getLocalizedString,
20
- R as hostApi,
21
+ A as hostApi,
21
22
  d as on,
22
23
  l as resetEventBus,
23
- i as setHandler,
24
- A as storageApi,
25
- e as trackerApi,
26
- C as uiApi
24
+ o as setHandler,
25
+ i as storageApi,
26
+ t as trackerApi,
27
+ U as uiApi
27
28
  };
28
29
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weavix/tracker-plugin-sdk",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "exports": {
5
5
  ".": {
6
6
  "types": "./dist/index.d.ts",
@@ -22,15 +22,15 @@
22
22
  "access": "public"
23
23
  },
24
24
  "peerDependencies": {
25
- "@weavix/sdk-core": "^0.0.3",
25
+ "@weavix/sdk-core": "^0.0.4",
26
26
  "@weavix/tracker-api-types": ">=0.0.0",
27
- "@weavix/tracker-core": "^0.0.1"
27
+ "@weavix/tracker-core": "^0.0.2"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/jest": "*",
31
31
  "@weavix/tracker-api-types": "*",
32
32
  "@weavix/sdk-core": "0.0.0",
33
- "@weavix/tracker-core": "0.0.1"
33
+ "@weavix/tracker-core": "0.0.2"
34
34
  },
35
35
  "scripts": {
36
36
  "build": "vite build",
@@ -1 +0,0 @@
1
- {"version":3,"file":"trackerApi.d.ts","sourceRoot":"","sources":["../../../../src/api/trackerApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,qBAAqB,IAAI,eAAe,EAC7C,KAAK,qBAAqB,IAAI,eAAe,EAEhD,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,qBAAqB,GAAG,eAAe,CAAC;AACpD,MAAM,MAAM,qBAAqB,GAAG,eAAe,CAAC;AAEpD,KAAK,SAAS,CAAC,CAAC,IAAI;KACf,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,GAC7D,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,GACrE,KAAK;CACd,CAAC;AAEF,MAAM,WAAW,YAAY;IACzB,GAAG,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;IAChC,IAAI,EAAE,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAClC,GAAG,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;IAChC,KAAK,EAAE,SAAS,CAAC,iBAAiB,CAAC,CAAC;IACpC,MAAM,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,UAAU;IACvB,EAAE,EAAE,YAAY,CAAC;CACpB;AAED,eAAO,MAAM,UAAU,EAAgC,UAAU,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EACR,UAAU,EACV,qBAAqB,EACrB,qBAAqB,EACrB,YAAY,GACf,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAGjE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC9D,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGpG,OAAO,EAAE,iBAAiB,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACxE,YAAY,EACR,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,WAAW,GACd,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACH,OAAO,EACP,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,8BAA8B,EAC9B,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACnB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC1E,YAAY,EACR,UAAU,EACV,iCAAiC,EACjC,mBAAmB,EACnB,eAAe,EACf,KAAK,EACL,6BAA6B,EAC7B,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,+BAA+B,EAC/B,6BAA6B,GAChC,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGjG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,YAAY,EACR,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,GAChB,MAAM,sBAAsB,CAAC"}