@smwb/onreel-git-mcp 0.2.1 → 0.3.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/README.md CHANGED
@@ -243,7 +243,8 @@ const issue = await adapter.get('7');
243
243
  try {
244
244
  await adapter.update('7', { status: 'in_progress' });
245
245
  } catch (error) {
246
- if (error instanceof TrackerError) console.log(error.failure); // 'failed' | 'unknown_issue' | 'invalid_request'
246
+ // 'failed' | 'unknown_issue' | 'invalid_request' | 'not_found' | 'unsupported' | 'conflict' | 'rate_limited'
247
+ if (error instanceof TrackerError) console.log(error.failure);
247
248
  else throw error;
248
249
  }
249
250
  ```
@@ -256,7 +257,87 @@ try {
256
257
  для `WorktreeStore`, пишет потребитель; эталон в памяти — `test/helpers/tracker-fixtures.lib.ts`.
257
258
 
258
259
  Таймаут запроса к трекеру — `TRACKER_TIMEOUT_MS` (15 с), тело ответа ошибки обрезают до
259
- `TRACKER_ERROR_BODY_MAX` (300 символов) и маскируют; 404 с `missingIsIssue` — `unknown_issue`, а не «неверный адрес».
260
+ `TRACKER_ERROR_BODY_MAX` (300 символов) и маскируют; 404 с `missingIsIssue` — `unknown_issue`, а не «неверный
261
+ адрес». 404 с заданным `missing` отдаёт его код и текст (`not_found`), статус из `conflictOn` — `conflict`,
262
+ 429 и 403, который выглядит лимитом частоты (`x-ratelimit-remaining: 0` или `retry-after`) — `rate_limited`
263
+ (подробнее — в подразделе ниже).
264
+
265
+ ### Фильтры, сортировка и страницы
266
+
267
+ `IssueQuery` — `PageQuery` плюс необязательные фильтры (D-004): `status` (категории статуса), `labels`
268
+ (должны присутствовать все перечисленные), `assignee` (в том же виде, что в `Issue.assignee`; `null` — задачи
269
+ без исполнителя), `author` (логин или slug трекера), `search` (как ищет сам трекер: у SourceCraft — префикс
270
+ заголовка, у локального — подстрока заголовка и описания), `createdAfter`/`createdBefore`/`updatedAfter`/
271
+ `updatedBefore` (мс Unix epoch, границы включительно) и `sort` — `ListSort<IssueSortField>` (`{ field, direction? }`,
272
+ где `direction` — `SortDirection`). Без `sort` — прежний порядок трекера: GitHub, GitLab, Jira и локальный отдают
273
+ новые первыми, SourceCraft — свои (старые первыми). Без `direction` — `desc`.
274
+ `comments` принимает `CommentQuery`: `updatedAfter` (мс) и `order` — `SortDirection` (`asc` по умолчанию).
275
+ Трекеры ограничивают размер страницы (GitHub и GitLab — до 100): `limit` выше потолка вернёт страницу размером
276
+ потолка.
277
+
278
+ Что умеет каждый список, описывают `IssueCapabilities` в разделе `issues` определения трекера:
279
+ `{ list: ListCapabilities<IssueFilter, IssueSortField>, comments: CommentCapabilities }`. `ListCapabilities`
280
+ перечисляет `filters` — фильтры, которые адаптер применяет (любой другой — отказ `unsupported` **до запроса**),
281
+ `clientSide` — часть `filters`, которую адаптер проверяет по полученной странице: такая страница бывает короче
282
+ `limit` и даже пустой при живом `nextCursor`, и `sorts` — поля сортировки. `CommentCapabilities` описывает
283
+ список комментариев так же: `filters` и `clientSide` по `updatedAfter` и `order` вместо `sorts` — допустимые
284
+ порядки, первый из них по умолчанию. Возможности статичны и сериализуются в JSON.
285
+ У определения без раздела читаются `LEGACY_ISSUE_CAPABILITIES` — через `issueCapabilitiesOf(definition)`:
286
+
287
+ | Трекер | `list.filters` | `list.clientSide` | `list.sorts` | `comments` |
288
+ |---|---|---|---|---|
289
+ | GitHub | все `ISSUE_FILTERS` | `status` | `created`, `updated`, `comments` | `updatedAfter`; порядок `asc` |
290
+ | GitLab | все `ISSUE_FILTERS` | `status` | `created`, `updated`, `priority`, `title` | `updatedAfter` (на странице); `asc`, `desc` |
291
+ | Jira | все `ISSUE_FILTERS` | — | `created`, `updated`, `priority`, `title` | как у GitLab |
292
+ | SourceCraft | все `ISSUE_FILTERS` | `assignee` | `created`, `updated`, `priority`, `title` | как у GitLab |
293
+ | локальный | без `author` | без `status` | — | `updatedAfter` (на странице); `asc` |
294
+
295
+ У GitHub фильтры `search` и диапазоны `created*`/`updated*` идут через Search API (30 запросов/мин,
296
+ не больше 1000 результатов). Границы времени там — квалификаторы `q` без кавычек: одна граница —
297
+ `created:>=<ISO>` или `created:<=<ISO>`, обе границы одного поля — один диапазон `created:<ISO>..<ISO>`
298
+ (два отдельных квалификатора GitHub объединяет через OR, и вместо фильтра он отдал бы почти всё, а кавычки
299
+ в дате не читает вовсе — отдал бы пустой список). У SourceCraft статус уходит в QL-фильтр
300
+ (`SOURCECRAFT_STATUS_FILTER`), но всё равно перепроверяется на странице. Правила модели, которые держат тесты:
301
+
302
+ - **R1 — проверка до запроса.** Метод списка сначала зовёт `assertListQuery`/`assertCommentQuery`: фильтр
303
+ или сортировка вне возможностей — `TrackerError('unsupported')` без единого запроса, а неверное значение
304
+ (`limit` < 1, время не целое ≥ 0, пустая строка, метка с `,` там, где трекер ждёт CSV) — `invalid_request`.
305
+ - **R2 — время.** Время в мс Unix epoch, границы включительно; наверх уходят как `isoTime(ms)` (у Jira —
306
+ UTC с округлением минут наружу: `after` вниз, `before` вверх).
307
+ - **R3 — значения.** `labels` — все должны присутствовать; `assignee` — как в `Issue.assignee`, `null` —
308
+ без исполнителя; `author` — логин или slug трекера; `search` — как ищет сам трекер.
309
+ - **R4 — умолчания.** Без `sort` — прежний порядок трекера: GitHub, GitLab, Jira и локальный отдают новые
310
+ первыми, у SourceCraft — свой порядок по умолчанию (старые первыми); без `direction` — `desc`, у комментариев
311
+ без `order` — `asc`.
312
+ - **R5 — страницы.** `clientSide`-фильтр применяется к элементам каждой полученной страницы, `nextCursor` —
313
+ курсор трекера; страницы бывают короче `limit` и пустыми.
314
+ - **R6 — экранирование.** Каждое значение пользователя, попадающее в JQL, QL SourceCraft или `q` поиска GitHub,
315
+ проходит `quoted()` (`\` и `"` экранируются); свободный текст GitHub уходит одной фразой в кавычках, так что
316
+ `repo:чужой/репозиторий` из ввода не добавит чужой репозиторий в выдачу. Даты `isoTime(ms)` в `q` — исключение:
317
+ их кладут без кавычек (значение машинное, `[0-9TZ:.-]`), иначе GitHub не найдёт ни одной задачи.
318
+ - **R7 — прежние трекеры.** Определение без раздела `issues` читается как `LEGACY_ISSUE_CAPABILITIES`
319
+ через `issueCapabilitiesOf()` — свои трекеры потребителя продолжают работать без изменений.
320
+
321
+ Помощники фильтров — публичные символы субпути: `usedFilters` (имена заполненных фильтров в порядке
322
+ констант), `assertListQuery`/`assertCommentQuery` (проверка запроса по возможностям), `issueCapabilitiesOf`,
323
+ `isoTime` (мс → ISO 8601 UTC), `inTimeRange` (включительные границы, заданная граница и неизвестное время —
324
+ не проходит), `containsText` (подстрока без учёта регистра), `quoted` (экранирование для JQL/QL/`q`),
325
+ `keysFor` (обратный поиск по таблице сопоставления). Имена фильтров и полей сортировки — константы
326
+ `ISSUE_FILTERS`, `ISSUE_SORT_FIELDS`, `COMMENT_FILTERS` и выведенные из них типы `IssueFilter`,
327
+ `IssueSortField`, `CommentFilter`. За модель отвечают запись D-004 и правило R-002.
328
+
329
+ **Новые коды отказа.** `TrackerFailure` расширен четырьмя кодами; `requestJson` выставляет их по ответу,
330
+ а потребитель сопоставляет со своим контрактом:
331
+
332
+ | `TrackerFailure` | Когда возникает | Код контракта потребителя |
333
+ |---|---|---|
334
+ | `not_found` | 404 сущности, заданный через `missing` (PR, прогон, задание) | `not_found` |
335
+ | `unsupported` | фильтр/сортировка вне возможностей, неподдержанная операция | `capability_unsupported` |
336
+ | `conflict` | статус из `conflictOn` (405/409/422): переход сейчас невозможен | `lifecycle_conflict` |
337
+ | `rate_limited` | 429, 403 с `x-ratelimit-remaining: 0` и 403 с `retry-after` (вторичные лимиты GitHub: Search API — 30 запросов/мин); задержка — из `retry-after`, иначе `x-ratelimit-reset` (GitHub), иначе `ratelimit-reset` (GitLab) | `rate_limited` |
338
+
339
+ Все четыре кода уже есть в каталоге ошибок контракта (`errorCatalog`), срез контракта не меняется.
340
+ Исчерпывающий `switch` по `TrackerFailure` у потребителя после обновления нужно дополнить.
260
341
 
261
342
  ## mcp
262
343
 
package/dist/index.js CHANGED
@@ -59,7 +59,7 @@ import {
59
59
  // package.json
60
60
  var package_default = {
61
61
  name: "@smwb/onreel-git-mcp",
62
- version: "0.2.1",
62
+ version: "0.3.0",
63
63
  description: "\u0411\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430 \u043C\u043E\u0434\u0443\u043B\u0435\u0439, \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0445 \u0438\u0437 onreel: git-\u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u044B\u0435 \u043F\u0443\u0442\u0438, \u0441\u043F\u0438\u0441\u043E\u043A \u0444\u0430\u0439\u043B\u043E\u0432 worktree, \u0436\u0438\u0437\u043D\u0435\u043D\u043D\u044B\u0439 \u0446\u0438\u043A\u043B worktree \u043F\u0440\u043E\u0442\u0438\u0432 \u043F\u043E\u0440\u0442\u0430 WorktreeStore, \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u044B \u0442\u0440\u0435\u043A\u0435\u0440\u043E\u0432 GitHub/GitLab/Jira/SourceCraft/\u043B\u043E\u043A\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0438 MCP-\u0441\u0435\u0440\u0432\u0435\u0440 \u043D\u0430 stdio",
64
64
  keywords: [
65
65
  "git",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@smwb/onreel-git-mcp\",\n \"version\": \"0.2.1\",\n \"description\": \"Библиотека модулей, выделенных из onreel: git-операции и безопасные пути, список файлов worktree, жизненный цикл worktree против порта WorktreeStore, адаптеры трекеров GitHub/GitLab/Jira/SourceCraft/локального и MCP-сервер на stdio\",\n \"keywords\": [\n \"git\",\n \"worktree\",\n \"mcp\",\n \"issue-tracker\",\n \"github\",\n \"gitlab\",\n \"jira\",\n \"sourcecraft\",\n \"onreel\",\n \"typescript\"\n ],\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=24\"\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://git.sourcecraft.dev/elfenmail/onreel-git-mcp.git\"\n },\n \"homepage\": \"https://git.sourcecraft.dev/elfenmail/onreel-git-mcp\",\n \"license\": \"MIT\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n },\n \"./git\": {\n \"types\": \"./dist/git/index.d.ts\",\n \"import\": \"./dist/git/index.js\",\n \"default\": \"./dist/git/index.js\"\n },\n \"./files\": {\n \"types\": \"./dist/files/index.d.ts\",\n \"import\": \"./dist/files/index.js\",\n \"default\": \"./dist/files/index.js\"\n },\n \"./worktree\": {\n \"types\": \"./dist/worktree/index.d.ts\",\n \"import\": \"./dist/worktree/index.js\",\n \"default\": \"./dist/worktree/index.js\"\n },\n \"./tracker\": {\n \"types\": \"./dist/tracker/index.d.ts\",\n \"import\": \"./dist/tracker/index.js\",\n \"default\": \"./dist/tracker/index.js\"\n },\n \"./mcp\": {\n \"types\": \"./dist/mcp/index.d.ts\",\n \"import\": \"./dist/mcp/index.js\",\n \"default\": \"./dist/mcp/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"build\": \"tsup && tsc -p tsconfig.build.json\",\n \"typecheck\": \"tsc -p tsconfig.json && tsc -p tsconfig.examples.json\",\n \"lint\": \"oxlint --type-aware\",\n \"test\": \"node --test \\\"test/**/*.test.ts\\\"\",\n \"changeset\": \"changeset\",\n \"version\": \"changeset version\",\n \"release\": \"npm run build && changeset publish\"\n },\n \"dependencies\": {\n \"zod\": \"^4.6.5\"\n },\n \"devDependencies\": {\n \"@changesets/cli\": \"2.29.2\",\n \"@types/node\": \"24.19.1\",\n \"oxlint\": \"1.87.0\",\n \"oxlint-tsgolint\": \"7.0.2003\",\n \"tsup\": \"8.5.1\",\n \"typescript\": \"7.0.2\"\n }\n}\n","// Корневой подпуть пакета @smwb/onreel-git-mcp: срез контракта (константы, схемы, типы, чистые\n// функции) и версия пакета. Всё без побочных эффектов при импорте (R-001). Швы ядра\n// (SecretSink, WorktreeStore, LocalIssueStore) и модули git/files/worktree/tracker/mcp\n// экспортируют свои подпути — см. exports в package.json и README.\nimport pkg from '../package.json' with { type: 'json' };\n\nexport * from './contract/contract.const.ts';\nexport * from './contract/contract.schema.ts';\nexport * from './contract/contract.types.ts';\nexport * from './contract/contract.lib.ts';\n\n// Версия пакета — из version в package.json: статический импорт JSON, его значение tsup подставляет\n// в бандл на сборке, поэтому VERSION не расходится с релизом changesets (тот правит только version).\nexport const VERSION: string = pkg.version;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,EACE,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,aAAe;AAAA,EACf,UAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,MAAQ;AAAA,EACR,SAAW;AAAA,IACT,MAAQ;AAAA,EACV;AAAA,EACA,OAAS;AAAA,IACP;AAAA,EACF;AAAA,EACA,aAAe;AAAA,EACf,eAAiB;AAAA,IACf,QAAU;AAAA,IACV,UAAY;AAAA,EACd;AAAA,EACA,YAAc;AAAA,IACZ,MAAQ;AAAA,IACR,KAAO;AAAA,EACT;AAAA,EACA,UAAY;AAAA,EACZ,SAAW;AAAA,EACX,SAAW;AAAA,IACT,KAAK;AAAA,MACH,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,WAAW;AAAA,MACT,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,cAAc;AAAA,MACZ,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,aAAa;AAAA,MACX,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,kBAAkB;AAAA,EACpB;AAAA,EACA,SAAW;AAAA,IACT,OAAS;AAAA,IACT,WAAa;AAAA,IACb,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,WAAa;AAAA,IACb,SAAW;AAAA,IACX,SAAW;AAAA,EACb;AAAA,EACA,cAAgB;AAAA,IACd,KAAO;AAAA,EACT;AAAA,EACA,iBAAmB;AAAA,IACjB,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,QAAU;AAAA,IACV,mBAAmB;AAAA,IACnB,MAAQ;AAAA,IACR,YAAc;AAAA,EAChB;AACF;;;AC1EO,IAAM,UAAkB,gBAAI;","names":[]}
1
+ {"version":3,"sources":["../package.json","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@smwb/onreel-git-mcp\",\n \"version\": \"0.3.0\",\n \"description\": \"Библиотека модулей, выделенных из onreel: git-операции и безопасные пути, список файлов worktree, жизненный цикл worktree против порта WorktreeStore, адаптеры трекеров GitHub/GitLab/Jira/SourceCraft/локального и MCP-сервер на stdio\",\n \"keywords\": [\n \"git\",\n \"worktree\",\n \"mcp\",\n \"issue-tracker\",\n \"github\",\n \"gitlab\",\n \"jira\",\n \"sourcecraft\",\n \"onreel\",\n \"typescript\"\n ],\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=24\"\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://git.sourcecraft.dev/elfenmail/onreel-git-mcp.git\"\n },\n \"homepage\": \"https://git.sourcecraft.dev/elfenmail/onreel-git-mcp\",\n \"license\": \"MIT\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n },\n \"./git\": {\n \"types\": \"./dist/git/index.d.ts\",\n \"import\": \"./dist/git/index.js\",\n \"default\": \"./dist/git/index.js\"\n },\n \"./files\": {\n \"types\": \"./dist/files/index.d.ts\",\n \"import\": \"./dist/files/index.js\",\n \"default\": \"./dist/files/index.js\"\n },\n \"./worktree\": {\n \"types\": \"./dist/worktree/index.d.ts\",\n \"import\": \"./dist/worktree/index.js\",\n \"default\": \"./dist/worktree/index.js\"\n },\n \"./tracker\": {\n \"types\": \"./dist/tracker/index.d.ts\",\n \"import\": \"./dist/tracker/index.js\",\n \"default\": \"./dist/tracker/index.js\"\n },\n \"./mcp\": {\n \"types\": \"./dist/mcp/index.d.ts\",\n \"import\": \"./dist/mcp/index.js\",\n \"default\": \"./dist/mcp/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"build\": \"tsup && tsc -p tsconfig.build.json\",\n \"typecheck\": \"tsc -p tsconfig.json && tsc -p tsconfig.examples.json\",\n \"lint\": \"oxlint --type-aware\",\n \"test\": \"node --test \\\"test/**/*.test.ts\\\"\",\n \"changeset\": \"changeset\",\n \"version\": \"changeset version\",\n \"release\": \"npm run build && changeset publish\"\n },\n \"dependencies\": {\n \"zod\": \"^4.6.5\"\n },\n \"devDependencies\": {\n \"@changesets/cli\": \"2.29.2\",\n \"@types/node\": \"24.19.1\",\n \"oxlint\": \"1.87.0\",\n \"oxlint-tsgolint\": \"7.0.2003\",\n \"tsup\": \"8.5.1\",\n \"typescript\": \"7.0.2\"\n }\n}\n","// Корневой подпуть пакета @smwb/onreel-git-mcp: срез контракта (константы, схемы, типы, чистые\n// функции) и версия пакета. Всё без побочных эффектов при импорте (R-001). Швы ядра\n// (SecretSink, WorktreeStore, LocalIssueStore) и модули git/files/worktree/tracker/mcp\n// экспортируют свои подпути — см. exports в package.json и README.\nimport pkg from '../package.json' with { type: 'json' };\n\nexport * from './contract/contract.const.ts';\nexport * from './contract/contract.schema.ts';\nexport * from './contract/contract.types.ts';\nexport * from './contract/contract.lib.ts';\n\n// Версия пакета — из version в package.json: статический импорт JSON, его значение tsup подставляет\n// в бандл на сборке, поэтому VERSION не расходится с релизом changesets (тот правит только version).\nexport const VERSION: string = pkg.version;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,EACE,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,aAAe;AAAA,EACf,UAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,MAAQ;AAAA,EACR,SAAW;AAAA,IACT,MAAQ;AAAA,EACV;AAAA,EACA,OAAS;AAAA,IACP;AAAA,EACF;AAAA,EACA,aAAe;AAAA,EACf,eAAiB;AAAA,IACf,QAAU;AAAA,IACV,UAAY;AAAA,EACd;AAAA,EACA,YAAc;AAAA,IACZ,MAAQ;AAAA,IACR,KAAO;AAAA,EACT;AAAA,EACA,UAAY;AAAA,EACZ,SAAW;AAAA,EACX,SAAW;AAAA,IACT,KAAK;AAAA,MACH,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,WAAW;AAAA,MACT,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,cAAc;AAAA,MACZ,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,aAAa;AAAA,MACX,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,kBAAkB;AAAA,EACpB;AAAA,EACA,SAAW;AAAA,IACT,OAAS;AAAA,IACT,WAAa;AAAA,IACb,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,WAAa;AAAA,IACb,SAAW;AAAA,IACX,SAAW;AAAA,EACb;AAAA,EACA,cAAgB;AAAA,IACd,KAAO;AAAA,EACT;AAAA,EACA,iBAAmB;AAAA,IACjB,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,QAAU;AAAA,IACV,mBAAmB;AAAA,IACnB,MAAQ;AAAA,IACR,YAAc;AAAA,EAChB;AACF;;;AC1EO,IAAM,UAAkB,gBAAI;","names":[]}