@rt-tools/ui-kit-v2 0.22.0 → 0.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 (28) hide show
  1. package/fesm2022/rt-tools-ui-kit-v2-core.mjs +1 -0
  2. package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
  3. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +4 -2
  4. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
  5. package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +1 -0
  6. package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -1
  7. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +11 -0
  8. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -1
  9. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +172 -26
  10. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
  11. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +11 -6
  12. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -1
  13. package/package.json +1 -1
  14. package/rt-tools-ui-kit-v2-0.22.1.tgz +0 -0
  15. package/src/assets/icons-material/folder.fill.svg +5 -0
  16. package/src/assets/icons-material/folder.svg +5 -0
  17. package/src/lib/components/dynamic-selector/CONTEXT.md +2 -1
  18. package/src/lib/components/scroll-area/CONTEXT.md +5 -1
  19. package/src/lib/components/side-menu/CONTEXT.md +17 -1
  20. package/src/lib/components/side-menu/favorites/rt-side-menu-favorites.component.scss +9 -0
  21. package/src/lib/components/side-menu/rt-side-menu.component.scss +42 -15
  22. package/src/lib/components/side-menu/stories/component/test-side-menu-cell.component.scss +34 -0
  23. package/src/lib/components/side-menu/sub-item/rt-side-menu-sub-item.component.scss +75 -14
  24. package/src/lib/components/toast/CONTEXT.md +2 -0
  25. package/types/rt-tools-ui-kit-v2-core.d.ts +12 -2
  26. package/types/rt-tools-ui-kit-v2-side-menu.d.ts +60 -8
  27. package/types/rt-tools-ui-kit-v2-toast.d.ts +1 -0
  28. package/rt-tools-ui-kit-v2-0.22.0.tgz +0 -0
@@ -191,6 +191,7 @@ const iconMaterialMap = [
191
191
  why: 'две горизонтальные полосы; рисунок дорисован по слову владельца — им таблица первого кита показывает сравнение «равно»',
192
192
  },
193
193
  { from: 'edit', to: 'pencil', why: 'карандаш, один в один' },
194
+ { from: 'folder', to: 'folder', why: SAME_NAME },
194
195
  { from: 'fork_spoon', to: 'fork-spoon', why: SAME_NAME },
195
196
  { from: 'fullscreen', to: 'fullscreen', why: SAME_NAME },
196
197
  { from: 'fullscreen_exit', to: 'window-minimize', why: 'уголки внутрь — пара к fullscreen, выход из полного экрана в шапке чата' },
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-icon.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/icon/icon-categories.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon-font.service.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon-material-map.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon-glyph.logic.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon.const.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon.registry.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon.component.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon.component.html","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon.providers.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-tools-ui-kit-v2-icon.ts"],"sourcesContent":["import { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\n/**\n * Категории иконок rt-icon. 11 buckets: 8 prefix-based + Social (префикс `social-`) + Custom\n * (префикс `ico-`) + Misc (fallback).\n * Порядок фиксирован — соответствует порядку отображения в Catalog story (rt-icon.stories.ts).\n *\n * Аннотация типа намеренно не указывается: явный `readonly string[]` потерял бы узкий\n * литеральный тип, нужный для {@link TIconCategory}. `as const` сохраняет литеральные ключи.\n */\n// eslint-disable-next-line @typescript-eslint/typedef -- аннотация стёрла бы литеральный тип, на котором стоит TIconCategory\nexport const CATEGORY_ORDER = [\n 'Navigation',\n 'Alignment & Sorting',\n 'Status',\n 'Time & Calendar',\n 'Communication',\n 'Documents',\n 'People',\n 'Commerce',\n 'Social',\n 'Custom',\n 'Misc',\n] as const;\n\n/** Литеральный union из {@link CATEGORY_ORDER}. */\nexport type TIconCategory = (typeof CATEGORY_ORDER)[number];\n\n/**\n * Правило маппинга имени иконки в категорию.\n * Порядок правил в {@link ICON_CATEGORY_RULES} важен: первое совпавшее правило выигрывает.\n */\ninterface IIconCategoryRule {\n readonly category: TIconCategory;\n readonly match: (name: string) => boolean;\n}\n\nfunction startsWithAny(name: string, prefixes: readonly string[]): boolean {\n return prefixes.some((p: string): boolean => name.startsWith(p));\n}\n\nfunction isOneOf(name: string, names: readonly string[]): boolean {\n return names.includes(name);\n}\n\nfunction matchPrefixOrExact(prefixes: readonly string[], exact: readonly string[]): (name: string) => boolean {\n return (name: string): boolean => startsWithAny(name, prefixes) || isOneOf(name, exact);\n}\n\n/**\n * Упорядоченный список правил категоризации.\n * `Custom` — единственная категория по строгому префиксу `ico-` и проверяется первой,\n * чтобы исключить конфликты с другими prefix-based категориями.\n * `Misc` — fallback в {@link categoryOf}, отдельным правилом не описывается.\n */\nexport const ICON_CATEGORY_RULES: readonly IIconCategoryRule[] = [\n // Знаки соцсетей — цветные, со своей заливкой в файле; в каталоге они стоят своим рядом,\n // чтобы не смешиваться с одноцветными, которые красит тема.\n { category: 'Social', match: (n: string): boolean => n.startsWith('social-') },\n { category: 'Custom', match: (n: string): boolean => n.startsWith('ico-') },\n {\n category: 'Navigation',\n match: matchPrefixOrExact(['arrow', 'arrows', 'angle', 'chevron', 'directions'], []),\n },\n {\n category: 'Alignment & Sorting',\n match: matchPrefixOrExact(['align', 'sort', 'bars', 'ellipsis', 'sliders', 'filter', 'th'], []),\n },\n {\n category: 'Status',\n match: matchPrefixOrExact(['check', 'times', 'ban', 'exclamation', 'info', 'eye', 'lock', 'unlock', 'shield'], ['spinner', 'stop']),\n },\n {\n category: 'Time & Calendar',\n match: matchPrefixOrExact(['alarm', 'calendar'], ['clock']),\n },\n {\n category: 'Communication',\n match: matchPrefixOrExact(['comment', 'share'], ['bell', 'bot', 'telegram', 'at', 'email', 'send', 'phone', 'mobile']),\n },\n {\n category: 'Documents',\n match: matchPrefixOrExact(['attach', 'file', 'folder', 'bookmark'], ['book', 'copy', 'clone', 'tag', 'tags']),\n },\n {\n category: 'People',\n match: matchPrefixOrExact(['user'], ['users', 'id-card']),\n },\n {\n category: 'Commerce',\n match: (n: string): boolean => isOneOf(n, ['wallet', 'money-bill', 'ticket', 'credit-card']),\n },\n];\n\n/**\n * Возвращает категорию для имени иконки.\n * Первое совпавшее правило в {@link ICON_CATEGORY_RULES} выигрывает; иначе — `Misc`.\n */\nexport function categoryOf(name: IRtIcon.Name): TIconCategory {\n for (const rule of ICON_CATEGORY_RULES) {\n if (rule.match(name)) {\n return rule.category;\n }\n }\n return 'Misc';\n}\n","import { DOCUMENT } from '@angular/common';\nimport { Injectable, InjectionToken, Signal, WritableSignal, inject, signal } from '@angular/core';\n\nimport { PlatformService } from '@rt-tools/core';\n\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\n/**\n * Как значки приложения рисуют имя Material. Задаётся третьим аргументом `provideRtIcons()`;\n * по умолчанию `map-first` — пара из перечня кита, а без пары шрифт.\n */\nexport const RT_ICON_GLYPH_STRATEGY: InjectionToken<IRtIcon.GlyphStrategy> = new InjectionToken<IRtIcon.GlyphStrategy>(\n 'RT_ICON_GLYPH_STRATEGY',\n {\n providedIn: 'root',\n factory: (): IRtIcon.GlyphStrategy => 'map-first',\n }\n);\n\n/**\n * Готовность шрифтов страницы — одна на все значки.\n *\n * Лигатура до готовности шрифта рисуется словом в запасном шрифте: значок прячет её, пока страница\n * не сказала, что шрифты готовы. Кит шрифт не везёт и семью не знает, поэтому ждёт общую готовность,\n * а не загрузку одной семьи. На сервере шрифтов нет — лигатура там скрыта. Браузер без интерфейса\n * шрифтов ждать нечем, и лигатура показывается сразу.\n */\n@Injectable({ providedIn: 'root' })\nexport class RtIconFontService {\n readonly #ready: WritableSignal<boolean> = signal<boolean>(false);\n\n readonly #isBrowser: boolean = inject(PlatformService).isPlatformBrowser;\n\n readonly #document: Document = inject(DOCUMENT);\n\n public readonly ready: Signal<boolean> = this.#ready.asReadonly();\n\n constructor() {\n this.#watchFonts();\n }\n\n #watchFonts(): void {\n if (!this.#isBrowser) {\n return;\n }\n const fonts: FontFaceSet | undefined = this.#document.fonts;\n if (!fonts) {\n this.#ready.set(true);\n return;\n }\n void fonts.ready.then((): void => this.#ready.set(true));\n }\n}\n","import { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\n/**\n * Соответствие значков первого кита значкам этого набора.\n *\n * Первый кит рисует значки шрифтом Material: имя стоит прямо в шаблоне. Здесь у каждого такого\n * имени ровно одна пара — иначе один и тот же смысл приезжает на разные экраны разными\n * рисунками, а переезжающий выбирает значок заново на каждом экране.\n *\n * Перечень закрывает имена, которые видны поиском: голое слово в шаблоне, слово в тернарнике и\n * слово внутри разбора по виду фильтра. Имена, подставляемые выражением, сюда не попадают: они\n * приезжают из данных приложения и деревом кита не видны. Это граница перечня, а не его пробел.\n *\n * Пара ведёт на имя из фрейма, а не на своё с приставкой `ico-`, там где есть оба. Имён из\n * фрейма 229 против 118, и они одной рисовки: смешанный набор дал бы разнобой на экране. Восемь\n * таких пар помечены доводом — их можно переложить на свои одним местом.\n *\n * Имя без пары стоит здесь же, с причиной: молчание об имени неотличимо от того, что о нём\n * забыли. Дорисовка недостающего — работа рисующего, и она вынесена за границу задачи.\n *\n * Держит перечень `tools/check-icon-map.mjs`: каждая пара ведёт на имя союза и на существующий\n * файл, имена не повторяются, причина у имени без пары не пуста.\n */\n\n/** Довод самой частой пары: имя первого кита и имя набора совпали после замены подчёркиваний. */\nconst SAME_NAME: string = 'совпадает именем';\n\n/** Одна запись перечня: имя первого кита и то, чем оно закрывается здесь. */\nexport interface IRtIconMaterialEntry {\n /** Имя значка первого кита — так, как оно стоит в его шаблоне. */\n readonly from: string;\n\n /** Имя этого набора либо `null`, если рисунка в наборе нет. */\n readonly to: IRtIcon.Name | null;\n\n /** Довод к паре либо причина, по которой пары нет. Пустым не бывает. */\n readonly why: string;\n}\n\nexport const iconMaterialMap: readonly IRtIconMaterialEntry[] = [\n { from: 'account_circle', to: 'ico-user', why: 'силуэт человека; у user уже стоит рисунок person, поэтому пара на двойнике ico-user' },\n { from: 'add', to: 'ico-plus', why: 'простой плюс есть только в своей рисовке — во фрейме плюс лишь в круге и в составных' },\n { from: 'arrow_back', to: 'arrow-left', why: 'стрелка влево, один в один' },\n { from: 'arrow_forward', to: 'arrow-right', why: 'стрелка вправо, один в один' },\n { from: 'auto_awesome', to: 'sparkle', why: 'знак ИИ: большая и малая четырёхлучевые искры' },\n { from: 'backup', to: 'cloud-upload', why: 'у Material backup — облако со стрелкой вверх, это оно и есть' },\n { from: 'block', to: 'ban', why: 'круг с перечёркиванием, один в один' },\n { from: 'chat', to: 'comment', why: 'облачко реплики, ближний: у Material оно квадратное, здесь круглое' },\n { from: 'chat_error', to: 'chat-error', why: SAME_NAME },\n { from: 'chevron_left', to: 'chevron-left', why: SAME_NAME },\n { from: 'chevron_right', to: 'chevron-right', why: SAME_NAME },\n { from: 'close', to: 'close', why: `${SAME_NAME}; есть двойник ico-close` },\n { from: 'content_copy', to: 'copy', why: 'два листа, один в один; есть двойник ico-copy' },\n { from: 'dashboard', to: 'th-large', why: 'ближний: у Material четыре разных плитки, здесь четыре равных' },\n { from: 'delete', to: 'trash', why: 'корзина, один в один; есть двойник ico-trash' },\n { from: 'delete_forever', to: 'trash-x', why: 'корзина с крестом, дорисована в своём наборе для кнопки очистки списка' },\n { from: 'done', to: 'check', why: 'галочка, один в один; есть двойник ico-check' },\n { from: 'email', to: 'email', why: 'конверт, один в один' },\n { from: 'download', to: 'ico-download', why: 'простая стрелка вниз есть только в своей рисовке — во фрейме лишь облако' },\n {\n from: 'drag_handle',\n to: 'equals',\n why: 'две горизонтальные полосы; рисунок дорисован по слову владельца — им таблица первого кита показывает сравнение «равно»',\n },\n { from: 'edit', to: 'pencil', why: 'карандаш, один в один' },\n { from: 'fork_spoon', to: 'fork-spoon', why: SAME_NAME },\n { from: 'fullscreen', to: 'fullscreen', why: SAME_NAME },\n { from: 'fullscreen_exit', to: 'window-minimize', why: 'уголки внутрь — пара к fullscreen, выход из полного экрана в шапке чата' },\n { from: 'history', to: 'history', why: SAME_NAME },\n { from: 'home', to: 'home', why: SAME_NAME },\n { from: 'info', to: 'info-circle', why: 'круг с буквой i — так рисует Material; голое info в наборе другое' },\n { from: 'insert_chart', to: 'chart-bar', why: 'столбики диаграммы, ближний: у Material они в рамке' },\n { from: 'keyboard_arrow_down', to: 'chevron-down', why: 'шеврон вниз, один в один; есть двойник ico-chevron-down' },\n { from: 'layers', to: 'layers', why: SAME_NAME },\n { from: 'light_mode', to: 'ico-sun', why: 'солнце, один в один; простого солнца во фрейме нет' },\n { from: 'local_offer', to: 'tag', why: 'ярлык, один в один' },\n { from: 'logout', to: 'ico-exit', why: 'дверь со стрелкой наружу, один в один' },\n { from: 'menu', to: 'bars', why: 'три полосы, один в один' },\n { from: 'monitoring', to: 'chart-line', why: 'ближний: у Material ломаная над осями, здесь ломаная' },\n { from: 'moon_stars', to: 'moon', why: 'ближний: месяц без звёзд' },\n { from: 'more_horiz', to: 'ellipsis-h', why: 'три точки по горизонтали' },\n { from: 'more_vert', to: 'ellipsis-v', why: 'три точки по вертикали' },\n { from: 'open_in_new', to: 'external-link', why: 'квадрат со стрелкой наружу' },\n {\n from: 'open_with',\n to: 'arrows',\n why: 'четыре стрелки из центра; рисунок дорисован — им панель колонок первого кита показывает ручку перетаскивания',\n },\n { from: 'person', to: 'user', why: 'силуэт человека, один в один; есть двойник ico-user' },\n { from: 'person_off', to: 'user-off', why: 'силуэт человека, перечёркнутый наискось; рисунок дорисован по слову владельца' },\n { from: 'push_pin', to: 'pin', why: 'канцелярская булавка; рисунок дорисован — ею первый кит закрепляет подменю' },\n { from: 'refresh', to: 'refresh', why: SAME_NAME },\n { from: 'remove', to: 'minus', why: 'горизонтальная черта, один в один' },\n { from: 'search', to: 'search', why: `${SAME_NAME}; есть двойник ico-search` },\n { from: 'settings', to: 'cog', why: 'шестерёнка, один в один' },\n { from: 'star', to: 'star', why: SAME_NAME },\n { from: 'sync', to: 'sync', why: SAME_NAME },\n { from: 'thumb_down', to: 'thumb-down', why: 'палец вниз, один в один' },\n { from: 'thumb_up', to: 'thumb-up', why: 'палец вверх, один в один' },\n { from: 'troubleshoot', to: 'troubleshoot', why: SAME_NAME },\n { from: 'view_column', to: 'table', why: 'ближний: у Material это колонки, здесь таблица — решение владельца' },\n { from: 'visibility', to: 'eye', why: 'глаз, один в один; есть двойник ico-eye' },\n { from: 'visibility_off', to: 'eye-slash', why: 'перечёркнутый глаз, один в один' },\n\n { from: 'zoom_in', to: 'search-plus', why: 'лупа с плюсом, один в один' },\n];\n\n/**\n * Имена кита, у которых в материальном наборе лежит свой рисунок.\n *\n * Считается из перечня, а не пишется списком: свой список разошёлся бы с перечнем молча — реестр\n * ходил бы за файлом, которого нет, или не ходил бы за лежащим.\n */\nexport const iconMaterialDrawn: ReadonlySet<IRtIcon.Name> = new Set<IRtIcon.Name>(\n iconMaterialMap\n .map((entry: IRtIconMaterialEntry): IRtIcon.Name | null => entry.to)\n .filter((name: IRtIcon.Name | null): name is IRtIcon.Name => name !== null)\n);\n","import { iconMaterialMap, IRtIconMaterialEntry } from './rt-icon-material-map';\nimport { iconsName } from '@rt-tools/ui-kit-v2/core';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\nconst KIT_NAMES: ReadonlySet<string> = new Set<string>(iconsName);\n\n/** Имя лигатуры Material Symbols: строчные латинские буквы, цифры и подчёркивание. */\nconst LIGATURE_NAME: RegExp = /^[a-z0-9_]+$/;\n\n/** Имя значка кита — то, что рисует спрайт; остальное кит своим рисунком не закрывает. */\nexport function isKitIconName(name: string): name is IRtIcon.Name {\n return KIT_NAMES.has(name);\n}\n\n/** Пара имени Material из перечня кита; `null` — пары нет или имени нет. */\nexport function materialPairOf(glyph: string | null | undefined): IRtIcon.Name | null {\n if (!glyph) {\n return null;\n }\n return iconMaterialMap.find((entry: IRtIconMaterialEntry): boolean => entry.from === glyph)?.to ?? null;\n}\n\nfunction kitOrPairOf(glyph: string): IRtIcon.Name | null {\n return isKitIconName(glyph) ? glyph : materialPairOf(glyph);\n}\n\n/** Имя кита, которое шрифт нарисовать не может: дефис или заглавная буква. Лигатура — `null`. */\nfunction unlettered(glyph: string): IRtIcon.Name | null {\n return isKitIconName(glyph) && !LIGATURE_NAME.test(glyph) ? glyph : null;\n}\n\n/**\n * Чем рисуется значок: своим рисунком кита или лигатурой шрифта Material.\n *\n * Имя кита выигрывает у имени Material, если названы оба. Имя Material по способу `map-first`\n * берёт пару из перечня, а без пары — шрифт; по способу `font` — шрифт сразу. Имя кита, которое шрифт\n * нарисовать не может (`ico-plus`, `docBox`), и по способу `font` рисуется рисунком кита: иначе в\n * значке стоит текст имени. Имя кита, совпавшее с лигатурой (`search`), по `font` — шрифт. Материальный рисунок\n * для пары выбирает уже сам значок по признаку набора над собой: это не дело разбора.\n *\n * `null` — значку нечего рисовать.\n */\nexport function resolveIconGlyph(\n name: IRtIcon.Name | null | undefined,\n glyph: string | null | undefined,\n strategy: IRtIcon.GlyphStrategy\n): IRtIcon.Resolved | null {\n if (name) {\n return { kind: 'kit', name };\n }\n if (!glyph) {\n return null;\n }\n const pair: IRtIcon.Name | null = strategy === 'map-first' ? kitOrPairOf(glyph) : unlettered(glyph);\n return pair === null ? { kind: 'font', glyph } : { kind: 'kit', name: pair };\n}\n","/**\n * Имена, которыми набор значков виден со стороны страницы.\n *\n * Отдельный файл, а не константы реестра: те же имена читает обвязка снимков витрины, а она идёт\n * под Playwright и ни одного объявления Angular поднять не может. Своя копия там уже стояла —\n * второе объявление того же значения расходится с первым молча: ожидание набора ищет один узел,\n * а реестр создаёт другой, и кадр выходит без значков.\n */\n\n/** Селектор inline-sprite, создаваемого один раз при первом обращении. */\nexport const RT_ICON_SPRITE_ID: string = 'rt-icon-sprite';\n\n/** Префикс `id` для inline-sprite символов. Изолирует от внешних `id` на странице. */\nexport const RT_ICON_SYMBOL_ID_PREFIX: string = 'rt-icon-';\n\n/**\n * Префикс `id` символов материального набора. Свой, а не общий: наборов на странице бывает два —\n * признак набора стоит и на корне, и на контейнере, — а один `id` держит один рисунок. С общим\n * префиксом второй набор молча забирал бы символ первого.\n */\nexport const RT_ICON_MATERIAL_SYMBOL_ID_PREFIX: string = 'rt-icon-material-';\n\n/** Префикс `id` залитых рисунков материального набора: у имени их два, и `id` у каждого свой. */\nexport const RT_ICON_MATERIAL_FILL_SYMBOL_ID_PREFIX: string = 'rt-icon-material-fill-';\n\n/**\n * Атрибут, который переключает только набор рисунков значков: токенов набора оформления он не\n * несёт. Ставится на контейнер со значением `'material'` там, где значки нужны материальные, а\n * остальной вид — свой.\n */\nexport const RT_ICON_PRESET_ATTRIBUTE: string = 'data-rt-icon-preset';\n\n/**\n * Селекторы, которыми страница объявляет материальный набор значков: признак набора оформления\n * и признак одних значков. Стили читают только первые два — токены под третьим не меняются.\n */\nexport const RT_ICON_MATERIAL_PRESET_SELECTOR: string = `[data-preset='material'],.rt-preset-material,[${RT_ICON_PRESET_ATTRIBUTE}='material']`;\n","import { DOCUMENT } from '@angular/common';\nimport { HttpClient } from '@angular/common/http';\nimport { Injectable, InjectionToken, inject } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { EMPTY, Observable, Subject, catchError, map, mergeMap, tap } from 'rxjs';\n\nimport { PlatformService } from '@rt-tools/core';\n\nimport {\n RT_ICON_MATERIAL_FILL_SYMBOL_ID_PREFIX,\n RT_ICON_MATERIAL_SYMBOL_ID_PREFIX,\n RT_ICON_SPRITE_ID,\n RT_ICON_SYMBOL_ID_PREFIX,\n} from './rt-icon.const';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\n/**\n * Адрес, по которому приложение публикует набор из `assets/icons` пакета.\n * Умолчание годится, когда сборка кладёт набор в корень статики; свой адрес\n * задаётся аргументом `provideRtIcons()`.\n */\nexport const RT_ICONS_BASE_URL: InjectionToken<string> = new InjectionToken<string>('RT_ICONS_BASE_URL', {\n providedIn: 'root',\n factory: (): string => '/icons',\n});\n\n/**\n * Адрес материального набора значков. Отдельный от своего: два набора стоят рядом, и приложение\n * кладёт их двумя папками.\n */\nexport const RT_ICONS_MATERIAL_BASE_URL: InjectionToken<string> = new InjectionToken<string>('RT_ICONS_MATERIAL_BASE_URL', {\n providedIn: 'root',\n factory: (): string => '/icons-material',\n});\n\n@Injectable({ providedIn: 'root' })\nexport class RtIconRegistry {\n readonly #http: HttpClient = inject(HttpClient);\n readonly #doc: Document = inject(DOCUMENT);\n readonly #baseUrl: string = inject(RT_ICONS_BASE_URL);\n readonly #materialBaseUrl: string = inject(RT_ICONS_MATERIAL_BASE_URL);\n readonly #platform: PlatformService = inject(PlatformService);\n\n /**\n * Имена, за которыми уже сходили: второй раз в сеть за ними не ходят. Ключ несёт набор —\n * одно имя приезжает двумя разными рисунками, и общий ключ отдал бы второму первый.\n */\n readonly #requested: Set<string> = new Set<string>();\n\n /** Имена, которые попросила разметка. Загрузку по ним ведёт подписка из конструктора. */\n readonly #requestSource: Subject<IRtIconRequest> = new Subject<IRtIconRequest>();\n\n constructor() {\n // Потоки складываются, а не вытесняют друг друга: странице нужны все спрошенные\n // значки, а не последний из них.\n this.#requestSource\n .pipe(\n mergeMap((asked: IRtIconRequest): Observable<void> => this.#load(asked)),\n takeUntilDestroyed()\n )\n .subscribe();\n }\n\n /**\n * Имя symbol для `<use href=\"#X\">`. Возвращает строку с ведущим `#`.\n *\n * Набор назван явно, а не выведен из страницы: одна и та же страница держит оба набора\n * рядом — признак стоит и на корне, и на контейнере, — и вывод по странице дал бы обоим\n * один ответ.\n */\n public symbolHref(name: IRtIcon.Name, drawing: IRtIcon.Drawing = 'base'): string {\n return `#${this.#symbolId(name, drawing)}`;\n }\n\n /**\n * Просит значок по имени: грузит файл и дописывает `<symbol>` в спрайт страницы.\n *\n * Ответа зовущий не ждёт и потока не получает: разметка рисует ссылку на символ сразу, а\n * браузер дорисовывает её, когда символ приезжает. Подписка живёт здесь и только здесь —\n * иначе каждая разметка гасила бы её сама, а таких мест у значка два.\n */\n public request(name: IRtIcon.Name, drawing: IRtIcon.Drawing = 'base'): void {\n const id: string = this.#symbolId(name, drawing);\n // На сервере относительных запросов к статике нет вовсе: значок дорисуется после\n // гидрации, когда разметка попросит его снова уже в браузере.\n if (!this.#platform.isPlatformBrowser || this.#requested.has(id)) {\n return;\n }\n this.#requested.add(id);\n // Символ уже лежит в спрайте страницы: его положила соседняя история витрины или\n // сама страница до старта приложения. Запроса не уходит вовсе.\n if (this.#doc.getElementById(id)) {\n return;\n }\n this.#requestSource.next({ name, drawing });\n }\n\n #load(asked: IRtIconRequest): Observable<void> {\n if (asked.drawing === 'base') {\n return this.#loadInto(asked, `${this.#baseUrl}/${asked.name}.svg`, EMPTY);\n }\n\n // Материальный рисунок, который не приехал, закрывается своим. Материальный набор —\n // слой переопределений: имени, которого в нём нет, кит и так рисует свой рисунок, и\n // не приехавший файл обязан вести себя так же. Иначе страница, объявившая набор, но\n // не опубликовавшая его папку, показывает пустое место там, где обещан значок, —\n // разметка при этом верна, и промах виден только глазами. Залитый, которого нет,\n // сперва закрывается контурным того же набора.\n const own: Observable<void> = this.#loadInto(asked, `${this.#baseUrl}/${asked.name}.svg`, EMPTY);\n const outlined: Observable<void> =\n asked.drawing === 'material-fill' ? this.#loadInto(asked, `${this.#materialBaseUrl}/${asked.name}.svg`, own) : own;\n const file: string = asked.drawing === 'material-fill' ? `${asked.name}.fill.svg` : `${asked.name}.svg`;\n\n return this.#loadInto(asked, `${this.#materialBaseUrl}/${file}`, outlined);\n }\n\n /**\n * Рисунок по адресу под именем символа, которое просила разметка: подмена ссылки разметке\n * не нужна. Отказ одного имени гасит только его значок — иначе один промах в наборе ронял бы\n * всю страницу, а соседние значки уже приехали.\n */\n #loadInto(asked: IRtIconRequest, url: string, fallback: Observable<void>): Observable<void> {\n return this.#http.get(url, { responseType: 'text' }).pipe(\n tap((raw: string): void => this.#mountSymbol(asked, raw)),\n map((): void => undefined),\n catchError((): Observable<void> => fallback)\n );\n }\n\n #symbolId(name: IRtIcon.Name, drawing: IRtIcon.Drawing): string {\n const prefix: Record<IRtIcon.Drawing, string> = {\n base: RT_ICON_SYMBOL_ID_PREFIX,\n material: RT_ICON_MATERIAL_SYMBOL_ID_PREFIX,\n 'material-fill': RT_ICON_MATERIAL_FILL_SYMBOL_ID_PREFIX,\n };\n return `${prefix[drawing]}${name}`;\n }\n\n #mountSymbol(asked: IRtIconRequest, raw: string): void {\n const symbol: SVGSymbolElement = this.#doc.createElementNS('http://www.w3.org/2000/svg', 'symbol');\n symbol.id = this.#symbolId(asked.name, asked.drawing);\n symbol.setAttribute('viewBox', this.#viewBox(raw));\n symbol.innerHTML = this.#inner(raw);\n this.#sprite().appendChild(symbol);\n }\n\n #viewBox(raw: string): string {\n const viewBoxMatch: RegExpExecArray | null = /viewBox=\"([^\"]+)\"/.exec(raw);\n return viewBoxMatch ? viewBoxMatch[1] : '0 0 24 24';\n }\n\n #inner(raw: string): string {\n // Тело корневого `<svg>` без него самого: оно и становится телом `<symbol>`.\n return raw\n .replace(/<\\?xml[\\s\\S]*?\\?>/g, '')\n .replace(/<!DOCTYPE[\\s\\S]*?>/g, '')\n .replace(/<svg\\b[^>]*>/i, '')\n .replace(/<\\/svg>\\s*$/i, '')\n .trim();\n }\n\n #sprite(): SVGSVGElement {\n const existing: SVGSVGElement | null = this.#doc.querySelector<SVGSVGElement>(`svg#${RT_ICON_SPRITE_ID}`);\n if (existing) {\n return existing;\n }\n const sprite: SVGSVGElement = this.#doc.createElementNS('http://www.w3.org/2000/svg', 'svg');\n sprite.id = RT_ICON_SPRITE_ID;\n sprite.setAttribute('aria-hidden', 'true');\n sprite.setAttribute('style', 'position:absolute;width:0;height:0;overflow:hidden;');\n this.#doc.body.insertBefore(sprite, this.#doc.body.firstChild);\n return sprite;\n }\n}\n\n/** Что просит разметка: имя значка и рисунок, который за ним стоит. */\ninterface IRtIconRequest {\n readonly name: IRtIcon.Name;\n readonly drawing: IRtIcon.Drawing;\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n afterNextRender,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n numberAttribute,\n signal,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_ICON_GLYPH_STRATEGY, RtIconFontService } from './rt-icon-font.service';\nimport { resolveIconGlyph } from './rt-icon-glyph.logic';\nimport { iconMaterialDrawn } from './rt-icon-material-map';\nimport { RT_ICON_MATERIAL_PRESET_SELECTOR } from './rt-icon.const';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconRegistry } from './rt-icon.registry';\n\n/* Ступень — свойство, которое приложение задаёт правилом на значке или на его предке; умолчание —\n шаг шкалы размеров кита, те же пиксели, что стояли здесь числом. Имя `--rt-icon-step-*`, а не\n `--rt-icon-size-*`: те объявляет на корне страницы первый кит со своими значениями (md — 24px),\n и в приложении с обоими китами каждый значок второго вырос бы. */\nconst SIZES: Readonly<Record<IRtIcon.Size, string>> = Object.freeze({\n xs: 'var(--rt-icon-step-xs, var(--rt-size-3))',\n sm: 'var(--rt-icon-step-sm, var(--rt-size-4))',\n md: 'var(--rt-icon-step-md, var(--rt-size-5))',\n lg: 'var(--rt-icon-step-lg, var(--rt-size-6))',\n xl: 'var(--rt-icon-step-xl, var(--rt-size-8))',\n '2xl': 'var(--rt-icon-step-2xl, var(--rt-size-10))',\n '3xl': 'var(--rt-icon-step-3xl, var(--rt-size-12))',\n '4xl': 'var(--rt-icon-step-4xl, var(--rt-size-16))',\n});\n\n/* Пиксели ступеней по умолчанию — оптический размер лигатуры. Без оси `opsz` в настройках шрифта\n браузер ставил её по размеру шрифта, и умолчание повторяет это: значок, которому приложение оси\n не задало, рисуется как прежде. */\nconst STEP_PX: Readonly<Record<IRtIcon.Size, number>> = Object.freeze({\n xs: 12,\n sm: 16,\n md: 20,\n lg: 24,\n xl: 32,\n '2xl': 40,\n '3xl': 48,\n '4xl': 64,\n});\n\n/* Без переданного цвета значок цвета не пишет: `currentColor` строкой стиля перебивал правило\n стилей, которое красит значок снаружи, — значок опасного пункта меню оставался цвета текста. */\n// Каждый тон можно переназначить свойством сверху: поле ввода называет так тон своего значка в\n// наборе оформления. Цвет стоит встроенным стилем, и правилом его не перебить.\nconst COLORS: Readonly<Record<IRtIcon.Color, string | null>> = Object.freeze({\n current: null,\n primary: 'var(--rt-icon-color-primary, var(--rt-color-action-primary-on-surface))',\n muted: 'var(--rt-icon-color-muted, var(--rt-neutral-600))',\n disabled: 'var(--rt-icon-color-disabled, var(--rt-color-text-disabled))',\n info: 'var(--rt-icon-color-info, var(--rt-color-state-info))',\n success: 'var(--rt-icon-color-success, var(--rt-color-state-success))',\n warning: 'var(--rt-icon-color-warning, var(--rt-color-state-warning))',\n danger: 'var(--rt-icon-color-danger, var(--rt-color-state-danger))',\n inverse: 'var(--rt-icon-color-inverse, var(--rt-color-text-inverse))',\n});\n\nfunction isSizeStep(value: string): value is IRtIcon.Size {\n return Object.hasOwn(SIZES, value);\n}\n\n/** Ступень остаётся ступенью, число — пикселями. Числовая строка читается числом, прочее — ступенью `md`. */\nfunction toSize(value: IRtIcon.SizeInput | string): IRtIcon.SizeInput {\n let size: IRtIcon.SizeInput = typeof value === 'number' || isSizeStep(value) ? value : numberAttribute(value, 0);\n if (typeof size === 'number' && size <= 0) {\n size = 'md';\n }\n return size;\n}\n\nconst BEM_BLOCK: string = 'rt-icon';\n\n@Component({\n selector: 'rt-icon',\n templateUrl: './rt-icon.component.html',\n styleUrls: ['./rt-icon.component.scss'],\n imports: [BlockDirective, ElemDirective, ModDirective],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: BEM_BLOCK,\n '[attr.aria-hidden]': \"'true'\",\n '[style.width]': 'sizeValue()',\n '[style.height]': 'sizeValue()',\n '[style.color]': 'colorValue()',\n '[style.transform]': 'rotateStyle()',\n '[class.rt-icon--spin]': 'spin()',\n },\n})\nexport class RtIconComponent {\n readonly #registry: RtIconRegistry = inject(RtIconRegistry);\n readonly #host: ElementRef<HTMLElement> = inject(ElementRef);\n readonly #strategy: IRtIcon.GlyphStrategy = inject(RT_ICON_GLYPH_STRATEGY);\n readonly #fontReady: Signal<boolean> = inject(RtIconFontService).ready;\n\n /**\n * Набор, объявленный разметкой над этим значком.\n *\n * Читается у разметки, а не выбирается стилями: ссылку на символ спрайта CSS подменить нечем,\n * и второй `<use>` рядом с первым тоже не годится — он вечно указывает на символ, за которым\n * никто не ходил, а обвязка снимков ждёт, пока нарисуется каждый.\n *\n * Спрашивается ближайший предок, а не корень страницы: признак набора стоит и на контейнере,\n * и на одной странице законно живут оба набора рядом.\n *\n * Один раз после первой отрисовки: на сервере разметки нет вовсе, а признак набора страница\n * по ходу жизни не переставляет — его ставит приложение своей разметкой.\n */\n readonly #preset: WritableSignal<IRtIcon.Preset> = signal<IRtIcon.Preset>('base');\n\n /** Чем рисуется значок: именем кита или лигатурой шрифта. Ни имени, ни глифа — пустое место. */\n protected readonly resolved: Signal<IRtIcon.Resolved | null> = computed((): IRtIcon.Resolved | null =>\n resolveIconGlyph(this.name(), this.glyph(), this.glyphStrategy() ?? this.#strategy)\n );\n\n protected readonly kitName: Signal<IRtIcon.Name | null> = computed((): IRtIcon.Name | null => {\n const resolved: IRtIcon.Resolved | null = this.resolved();\n return resolved?.kind === 'kit' ? resolved.name : null;\n });\n\n protected readonly fontGlyph: Signal<string | null> = computed((): string | null => {\n const resolved: IRtIcon.Resolved | null = this.resolved();\n return resolved?.kind === 'font' ? resolved.glyph : null;\n });\n\n /** Лигатура прячется, пока шрифты страницы не готовы: до того она рисуется словом. */\n protected readonly glyphMods: Signal<Record<string, boolean>> = computed((): Record<string, boolean> => ({\n filled: this.fill(),\n pending: !this.#fontReady(),\n }));\n\n protected readonly href: Signal<string | null> = computed((): string | null => {\n const name: IRtIcon.Name | null = this.kitName();\n return name === null ? null : this.#registry.symbolHref(name, this.drawing());\n });\n\n /**\n * Набор, которым рисуется этот значок. Материальный закрывает не все имена кита — он слой\n * переопределений, как набор оформления: имя без материального рисунка рисуется своим, и это\n * не пробел.\n */\n protected readonly preset: Signal<IRtIcon.Preset> = computed((): IRtIcon.Preset => {\n const name: IRtIcon.Name | null = this.kitName();\n return this.#preset() === 'material' && name !== null && iconMaterialDrawn.has(name) ? 'material' : 'base';\n });\n\n /** Рисунок значка: залитый бывает только у материального набора, свой набор заливки не знает. */\n protected readonly drawing: Signal<IRtIcon.Drawing> = computed((): IRtIcon.Drawing => {\n if (this.preset() === 'base') {\n return 'base';\n }\n return this.fill() ? 'material-fill' : 'material';\n });\n\n /** Длина CSS стороны значка: ступень — её свойство `--rt-icon-step-*`, число — пиксели. */\n protected readonly sizeValue: Signal<string> = computed((): string => {\n const size: IRtIcon.SizeInput = this.size();\n return typeof size === 'number' ? `${size}px` : SIZES[size];\n });\n\n /** Оптический размер лигатуры, пока приложение не задало `--rt-icon-glyph-opsz`: сторона значка в пикселях. */\n protected readonly opticalSize: Signal<number> = computed((): number => {\n const size: IRtIcon.SizeInput = this.size();\n return typeof size === 'number' ? size : STEP_PX[size];\n });\n\n protected readonly colorValue: Signal<string | null> = computed((): string | null => COLORS[this.color()]);\n\n protected readonly rotateStyle: Signal<string | null> = computed((): string | null => {\n const r: number | null = this.rotate();\n return r !== null && r !== 0 ? `rotate(${r}deg)` : null;\n });\n\n /** Имя кита. Стоит рядом с глифом и побеждает его, когда переданы оба. */\n public readonly name: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n /**\n * Имя Material вместо имени кита. Как оно рисуется — парой из перечня кита или лигатурой\n * шрифта Material Symbols — решает настройка `glyphStrategy` у `provideRtIcons()`. Шрифт\n * приложение подключает само; семья берётся из свойства `--rt-icon-glyph-font`.\n */\n public readonly glyph: InputSignal<string | null> = input<string | null>(null);\n\n /**\n * Как рисовать имя Material у этого значка. Перекрывает `glyphStrategy` из `provideRtIcons()`;\n * `null` — берётся настройка приложения. Дефолт `null`.\n */\n public readonly glyphStrategy: InputSignal<IRtIcon.GlyphStrategy | null> = input<IRtIcon.GlyphStrategy | null>(null);\n\n /**\n * Ступень размера или число пикселей — для размеров между ступенями и крупнее последней.\n * Числовая строка из статического атрибута читается числом, прочая строка вне ступеней — `md`.\n * Внутри вход хранит ступень или положительное число пикселей.\n */\n public readonly size: InputSignalWithTransform<IRtIcon.SizeInput, IRtIcon.SizeInput | string> = input<\n IRtIcon.SizeInput,\n IRtIcon.SizeInput | string\n >('md', { transform: toSize });\n\n public readonly color: InputSignal<IRtIcon.Color> = input<IRtIcon.Color>('current');\n\n /**\n * Залитый рисунок вместо контурного — как `FILL 1` у значка первого кита. Действует в\n * материальном наборе; свой набор рисует значок одним рисунком. Дефолт `false`.\n */\n public readonly fill: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /**\n * Значок вращается — как индикатор занятости внутри кнопки или строки. Когда система просит\n * меньше движения, вращение медленнее. Поворот на время вращения уступает ему. Дефолт `false`.\n */\n public readonly spin: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly rotate: InputSignalWithTransform<number | null, TRotateInput> = input<number | null, TRotateInput>(null, {\n transform: (v: TRotateInput): number | null => {\n if (v === null || v === '') {\n return null;\n }\n return numberAttribute(v, 0);\n },\n });\n\n constructor() {\n // Значок едет по запросу имени, а не вперёд всем набором: страница платит за то, что\n // нарисовала. Смена имени просит новое — прежний символ остаётся в спрайте.\n effect((): void => {\n const name: IRtIcon.Name | null = this.kitName();\n if (name !== null) {\n this.#registry.request(name, this.drawing());\n }\n });\n\n // Разметка над значком видна только в браузере и только после первой отрисовки:\n // контейнер с признаком набора рисует то же приложение.\n afterNextRender((): void => {\n if (this.#host.nativeElement.closest(RT_ICON_MATERIAL_PRESET_SELECTOR)) {\n this.#preset.set('material');\n }\n });\n }\n}\n\ntype TRotateInput = number | string | null;\n","<ng-container rtBlock=\"rt-icon\">\n @if (href(); as symbol) {\n <svg focusable=\"false\" aria-hidden=\"true\" [attr.viewBox]=\"'0 0 24 24'\">\n <use [attr.href]=\"symbol\" />\n </svg>\n } @else if (fontGlyph(); as ligature) {\n <span\n rtElem=\"glyph\"\n aria-hidden=\"true\"\n [rtMod]=\"glyphMods()\"\n [style.font-size]=\"sizeValue()\"\n [style.--rt-icon-glyph-opsz-auto]=\"opticalSize()\">\n {{ ligature }}\n </span>\n }\n</ng-container>\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport { RT_ICON_GLYPH_STRATEGY } from './rt-icon-font.service';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RT_ICONS_BASE_URL, RT_ICONS_MATERIAL_BASE_URL } from './rt-icon.registry';\n\n/**\n * Называет адрес, по которому приложение опубликовало набор значков `rt-icon`.\n *\n * ```typescript\n * export function withCoreProviders(): EnvironmentProviders {\n * return makeEnvironmentProviders([\n * provideHttpClient(...),\n * provideRtStorage(),\n * provideRtIcons(),\n * ]);\n * }\n * ```\n *\n * Вперёд отсюда не грузится ничего: значок едет тогда, когда его попросила разметка, и платит\n * за него та страница, которая его нарисовала. Сборка спрайта и загрузка — дело `RtIconRegistry`.\n *\n * Сами файлы приложение публикует само — набор лежит в `assets/icons` пакета, и сборка копирует\n * его в свою статику.\n *\n * Наборов значков два: свой и материальный. Второй нужен только приложению, которое объявляет\n * материальный набор оформления, и адрес у него свой — набор лежит в `assets/icons-material`.\n *\n * Третий аргумент — настройки значков. `glyphStrategy` говорит, как рисуется имя Material на входе\n * `glyph`: `map-first` (по умолчанию) — пара из перечня кита, а без пары шрифт Material Symbols;\n * `font` — шрифт для любого имени. Шрифт приложение подключает само.\n *\n * @param baseUrl Адрес опубликованного набора. По умолчанию `/icons`.\n * @param materialBaseUrl Адрес материального набора. По умолчанию `/icons-material`.\n * @param options Настройки значков.\n */\nexport function provideRtIcons(baseUrl?: string, materialBaseUrl?: string, options?: IRtIconsOptions): EnvironmentProviders {\n return makeEnvironmentProviders([\n ...(baseUrl === undefined ? [] : [{ provide: RT_ICONS_BASE_URL, useValue: baseUrl }]),\n ...(materialBaseUrl === undefined ? [] : [{ provide: RT_ICONS_MATERIAL_BASE_URL, useValue: materialBaseUrl }]),\n ...(options?.glyphStrategy === undefined ? [] : [{ provide: RT_ICON_GLYPH_STRATEGY, useValue: options.glyphStrategy }]),\n ]);\n}\n\n/** Настройки значков приложения — третий аргумент `provideRtIcons()`. */\nexport interface IRtIconsOptions {\n readonly glyphStrategy?: IRtIcon.GlyphStrategy;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-icon.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/icon/icon-categories.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon-font.service.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon-material-map.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon-glyph.logic.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon.const.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon.registry.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon.component.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon.component.html","../../../projects/ui-kit-v2/src/lib/components/icon/rt-icon.providers.ts","../../../projects/ui-kit-v2/src/lib/components/icon/rt-tools-ui-kit-v2-icon.ts"],"sourcesContent":["import { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\n/**\n * Категории иконок rt-icon. 11 buckets: 8 prefix-based + Social (префикс `social-`) + Custom\n * (префикс `ico-`) + Misc (fallback).\n * Порядок фиксирован — соответствует порядку отображения в Catalog story (rt-icon.stories.ts).\n *\n * Аннотация типа намеренно не указывается: явный `readonly string[]` потерял бы узкий\n * литеральный тип, нужный для {@link TIconCategory}. `as const` сохраняет литеральные ключи.\n */\n// eslint-disable-next-line @typescript-eslint/typedef -- аннотация стёрла бы литеральный тип, на котором стоит TIconCategory\nexport const CATEGORY_ORDER = [\n 'Navigation',\n 'Alignment & Sorting',\n 'Status',\n 'Time & Calendar',\n 'Communication',\n 'Documents',\n 'People',\n 'Commerce',\n 'Social',\n 'Custom',\n 'Misc',\n] as const;\n\n/** Литеральный union из {@link CATEGORY_ORDER}. */\nexport type TIconCategory = (typeof CATEGORY_ORDER)[number];\n\n/**\n * Правило маппинга имени иконки в категорию.\n * Порядок правил в {@link ICON_CATEGORY_RULES} важен: первое совпавшее правило выигрывает.\n */\ninterface IIconCategoryRule {\n readonly category: TIconCategory;\n readonly match: (name: string) => boolean;\n}\n\nfunction startsWithAny(name: string, prefixes: readonly string[]): boolean {\n return prefixes.some((p: string): boolean => name.startsWith(p));\n}\n\nfunction isOneOf(name: string, names: readonly string[]): boolean {\n return names.includes(name);\n}\n\nfunction matchPrefixOrExact(prefixes: readonly string[], exact: readonly string[]): (name: string) => boolean {\n return (name: string): boolean => startsWithAny(name, prefixes) || isOneOf(name, exact);\n}\n\n/**\n * Упорядоченный список правил категоризации.\n * `Custom` — единственная категория по строгому префиксу `ico-` и проверяется первой,\n * чтобы исключить конфликты с другими prefix-based категориями.\n * `Misc` — fallback в {@link categoryOf}, отдельным правилом не описывается.\n */\nexport const ICON_CATEGORY_RULES: readonly IIconCategoryRule[] = [\n // Знаки соцсетей — цветные, со своей заливкой в файле; в каталоге они стоят своим рядом,\n // чтобы не смешиваться с одноцветными, которые красит тема.\n { category: 'Social', match: (n: string): boolean => n.startsWith('social-') },\n { category: 'Custom', match: (n: string): boolean => n.startsWith('ico-') },\n {\n category: 'Navigation',\n match: matchPrefixOrExact(['arrow', 'arrows', 'angle', 'chevron', 'directions'], []),\n },\n {\n category: 'Alignment & Sorting',\n match: matchPrefixOrExact(['align', 'sort', 'bars', 'ellipsis', 'sliders', 'filter', 'th'], []),\n },\n {\n category: 'Status',\n match: matchPrefixOrExact(['check', 'times', 'ban', 'exclamation', 'info', 'eye', 'lock', 'unlock', 'shield'], ['spinner', 'stop']),\n },\n {\n category: 'Time & Calendar',\n match: matchPrefixOrExact(['alarm', 'calendar'], ['clock']),\n },\n {\n category: 'Communication',\n match: matchPrefixOrExact(['comment', 'share'], ['bell', 'bot', 'telegram', 'at', 'email', 'send', 'phone', 'mobile']),\n },\n {\n category: 'Documents',\n match: matchPrefixOrExact(['attach', 'file', 'folder', 'bookmark'], ['book', 'copy', 'clone', 'tag', 'tags']),\n },\n {\n category: 'People',\n match: matchPrefixOrExact(['user'], ['users', 'id-card']),\n },\n {\n category: 'Commerce',\n match: (n: string): boolean => isOneOf(n, ['wallet', 'money-bill', 'ticket', 'credit-card']),\n },\n];\n\n/**\n * Возвращает категорию для имени иконки.\n * Первое совпавшее правило в {@link ICON_CATEGORY_RULES} выигрывает; иначе — `Misc`.\n */\nexport function categoryOf(name: IRtIcon.Name): TIconCategory {\n for (const rule of ICON_CATEGORY_RULES) {\n if (rule.match(name)) {\n return rule.category;\n }\n }\n return 'Misc';\n}\n","import { DOCUMENT } from '@angular/common';\nimport { Injectable, InjectionToken, Signal, WritableSignal, inject, signal } from '@angular/core';\n\nimport { PlatformService } from '@rt-tools/core';\n\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\n/**\n * Как значки приложения рисуют имя Material. Задаётся третьим аргументом `provideRtIcons()`;\n * по умолчанию `map-first` — пара из перечня кита, а без пары шрифт.\n */\nexport const RT_ICON_GLYPH_STRATEGY: InjectionToken<IRtIcon.GlyphStrategy> = new InjectionToken<IRtIcon.GlyphStrategy>(\n 'RT_ICON_GLYPH_STRATEGY',\n {\n providedIn: 'root',\n factory: (): IRtIcon.GlyphStrategy => 'map-first',\n }\n);\n\n/**\n * Готовность шрифтов страницы — одна на все значки.\n *\n * Лигатура до готовности шрифта рисуется словом в запасном шрифте: значок прячет её, пока страница\n * не сказала, что шрифты готовы. Кит шрифт не везёт и семью не знает, поэтому ждёт общую готовность,\n * а не загрузку одной семьи. На сервере шрифтов нет — лигатура там скрыта. Браузер без интерфейса\n * шрифтов ждать нечем, и лигатура показывается сразу.\n */\n@Injectable({ providedIn: 'root' })\nexport class RtIconFontService {\n readonly #ready: WritableSignal<boolean> = signal<boolean>(false);\n\n readonly #isBrowser: boolean = inject(PlatformService).isPlatformBrowser;\n\n readonly #document: Document = inject(DOCUMENT);\n\n public readonly ready: Signal<boolean> = this.#ready.asReadonly();\n\n constructor() {\n this.#watchFonts();\n }\n\n #watchFonts(): void {\n if (!this.#isBrowser) {\n return;\n }\n const fonts: FontFaceSet | undefined = this.#document.fonts;\n if (!fonts) {\n this.#ready.set(true);\n return;\n }\n void fonts.ready.then((): void => this.#ready.set(true));\n }\n}\n","import { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\n/**\n * Соответствие значков первого кита значкам этого набора.\n *\n * Первый кит рисует значки шрифтом Material: имя стоит прямо в шаблоне. Здесь у каждого такого\n * имени ровно одна пара — иначе один и тот же смысл приезжает на разные экраны разными\n * рисунками, а переезжающий выбирает значок заново на каждом экране.\n *\n * Перечень закрывает имена, которые видны поиском: голое слово в шаблоне, слово в тернарнике и\n * слово внутри разбора по виду фильтра. Имена, подставляемые выражением, сюда не попадают: они\n * приезжают из данных приложения и деревом кита не видны. Это граница перечня, а не его пробел.\n *\n * Пара ведёт на имя из фрейма, а не на своё с приставкой `ico-`, там где есть оба. Имён из\n * фрейма 229 против 118, и они одной рисовки: смешанный набор дал бы разнобой на экране. Восемь\n * таких пар помечены доводом — их можно переложить на свои одним местом.\n *\n * Имя без пары стоит здесь же, с причиной: молчание об имени неотличимо от того, что о нём\n * забыли. Дорисовка недостающего — работа рисующего, и она вынесена за границу задачи.\n *\n * Держит перечень `tools/check-icon-map.mjs`: каждая пара ведёт на имя союза и на существующий\n * файл, имена не повторяются, причина у имени без пары не пуста.\n */\n\n/** Довод самой частой пары: имя первого кита и имя набора совпали после замены подчёркиваний. */\nconst SAME_NAME: string = 'совпадает именем';\n\n/** Одна запись перечня: имя первого кита и то, чем оно закрывается здесь. */\nexport interface IRtIconMaterialEntry {\n /** Имя значка первого кита — так, как оно стоит в его шаблоне. */\n readonly from: string;\n\n /** Имя этого набора либо `null`, если рисунка в наборе нет. */\n readonly to: IRtIcon.Name | null;\n\n /** Довод к паре либо причина, по которой пары нет. Пустым не бывает. */\n readonly why: string;\n}\n\nexport const iconMaterialMap: readonly IRtIconMaterialEntry[] = [\n { from: 'account_circle', to: 'ico-user', why: 'силуэт человека; у user уже стоит рисунок person, поэтому пара на двойнике ico-user' },\n { from: 'add', to: 'ico-plus', why: 'простой плюс есть только в своей рисовке — во фрейме плюс лишь в круге и в составных' },\n { from: 'arrow_back', to: 'arrow-left', why: 'стрелка влево, один в один' },\n { from: 'arrow_forward', to: 'arrow-right', why: 'стрелка вправо, один в один' },\n { from: 'auto_awesome', to: 'sparkle', why: 'знак ИИ: большая и малая четырёхлучевые искры' },\n { from: 'backup', to: 'cloud-upload', why: 'у Material backup — облако со стрелкой вверх, это оно и есть' },\n { from: 'block', to: 'ban', why: 'круг с перечёркиванием, один в один' },\n { from: 'chat', to: 'comment', why: 'облачко реплики, ближний: у Material оно квадратное, здесь круглое' },\n { from: 'chat_error', to: 'chat-error', why: SAME_NAME },\n { from: 'chevron_left', to: 'chevron-left', why: SAME_NAME },\n { from: 'chevron_right', to: 'chevron-right', why: SAME_NAME },\n { from: 'close', to: 'close', why: `${SAME_NAME}; есть двойник ico-close` },\n { from: 'content_copy', to: 'copy', why: 'два листа, один в один; есть двойник ico-copy' },\n { from: 'dashboard', to: 'th-large', why: 'ближний: у Material четыре разных плитки, здесь четыре равных' },\n { from: 'delete', to: 'trash', why: 'корзина, один в один; есть двойник ico-trash' },\n { from: 'delete_forever', to: 'trash-x', why: 'корзина с крестом, дорисована в своём наборе для кнопки очистки списка' },\n { from: 'done', to: 'check', why: 'галочка, один в один; есть двойник ico-check' },\n { from: 'email', to: 'email', why: 'конверт, один в один' },\n { from: 'download', to: 'ico-download', why: 'простая стрелка вниз есть только в своей рисовке — во фрейме лишь облако' },\n {\n from: 'drag_handle',\n to: 'equals',\n why: 'две горизонтальные полосы; рисунок дорисован по слову владельца — им таблица первого кита показывает сравнение «равно»',\n },\n { from: 'edit', to: 'pencil', why: 'карандаш, один в один' },\n { from: 'folder', to: 'folder', why: SAME_NAME },\n { from: 'fork_spoon', to: 'fork-spoon', why: SAME_NAME },\n { from: 'fullscreen', to: 'fullscreen', why: SAME_NAME },\n { from: 'fullscreen_exit', to: 'window-minimize', why: 'уголки внутрь — пара к fullscreen, выход из полного экрана в шапке чата' },\n { from: 'history', to: 'history', why: SAME_NAME },\n { from: 'home', to: 'home', why: SAME_NAME },\n { from: 'info', to: 'info-circle', why: 'круг с буквой i — так рисует Material; голое info в наборе другое' },\n { from: 'insert_chart', to: 'chart-bar', why: 'столбики диаграммы, ближний: у Material они в рамке' },\n { from: 'keyboard_arrow_down', to: 'chevron-down', why: 'шеврон вниз, один в один; есть двойник ico-chevron-down' },\n { from: 'layers', to: 'layers', why: SAME_NAME },\n { from: 'light_mode', to: 'ico-sun', why: 'солнце, один в один; простого солнца во фрейме нет' },\n { from: 'local_offer', to: 'tag', why: 'ярлык, один в один' },\n { from: 'logout', to: 'ico-exit', why: 'дверь со стрелкой наружу, один в один' },\n { from: 'menu', to: 'bars', why: 'три полосы, один в один' },\n { from: 'monitoring', to: 'chart-line', why: 'ближний: у Material ломаная над осями, здесь ломаная' },\n { from: 'moon_stars', to: 'moon', why: 'ближний: месяц без звёзд' },\n { from: 'more_horiz', to: 'ellipsis-h', why: 'три точки по горизонтали' },\n { from: 'more_vert', to: 'ellipsis-v', why: 'три точки по вертикали' },\n { from: 'open_in_new', to: 'external-link', why: 'квадрат со стрелкой наружу' },\n {\n from: 'open_with',\n to: 'arrows',\n why: 'четыре стрелки из центра; рисунок дорисован — им панель колонок первого кита показывает ручку перетаскивания',\n },\n { from: 'person', to: 'user', why: 'силуэт человека, один в один; есть двойник ico-user' },\n { from: 'person_off', to: 'user-off', why: 'силуэт человека, перечёркнутый наискось; рисунок дорисован по слову владельца' },\n { from: 'push_pin', to: 'pin', why: 'канцелярская булавка; рисунок дорисован — ею первый кит закрепляет подменю' },\n { from: 'refresh', to: 'refresh', why: SAME_NAME },\n { from: 'remove', to: 'minus', why: 'горизонтальная черта, один в один' },\n { from: 'search', to: 'search', why: `${SAME_NAME}; есть двойник ico-search` },\n { from: 'settings', to: 'cog', why: 'шестерёнка, один в один' },\n { from: 'star', to: 'star', why: SAME_NAME },\n { from: 'sync', to: 'sync', why: SAME_NAME },\n { from: 'thumb_down', to: 'thumb-down', why: 'палец вниз, один в один' },\n { from: 'thumb_up', to: 'thumb-up', why: 'палец вверх, один в один' },\n { from: 'troubleshoot', to: 'troubleshoot', why: SAME_NAME },\n { from: 'view_column', to: 'table', why: 'ближний: у Material это колонки, здесь таблица — решение владельца' },\n { from: 'visibility', to: 'eye', why: 'глаз, один в один; есть двойник ico-eye' },\n { from: 'visibility_off', to: 'eye-slash', why: 'перечёркнутый глаз, один в один' },\n\n { from: 'zoom_in', to: 'search-plus', why: 'лупа с плюсом, один в один' },\n];\n\n/**\n * Имена кита, у которых в материальном наборе лежит свой рисунок.\n *\n * Считается из перечня, а не пишется списком: свой список разошёлся бы с перечнем молча — реестр\n * ходил бы за файлом, которого нет, или не ходил бы за лежащим.\n */\nexport const iconMaterialDrawn: ReadonlySet<IRtIcon.Name> = new Set<IRtIcon.Name>(\n iconMaterialMap\n .map((entry: IRtIconMaterialEntry): IRtIcon.Name | null => entry.to)\n .filter((name: IRtIcon.Name | null): name is IRtIcon.Name => name !== null)\n);\n","import { iconMaterialMap, IRtIconMaterialEntry } from './rt-icon-material-map';\nimport { iconsName } from '@rt-tools/ui-kit-v2/core';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\nconst KIT_NAMES: ReadonlySet<string> = new Set<string>(iconsName);\n\n/** Имя лигатуры Material Symbols: строчные латинские буквы, цифры и подчёркивание. */\nconst LIGATURE_NAME: RegExp = /^[a-z0-9_]+$/;\n\n/** Имя значка кита — то, что рисует спрайт; остальное кит своим рисунком не закрывает. */\nexport function isKitIconName(name: string): name is IRtIcon.Name {\n return KIT_NAMES.has(name);\n}\n\n/** Пара имени Material из перечня кита; `null` — пары нет или имени нет. */\nexport function materialPairOf(glyph: string | null | undefined): IRtIcon.Name | null {\n if (!glyph) {\n return null;\n }\n return iconMaterialMap.find((entry: IRtIconMaterialEntry): boolean => entry.from === glyph)?.to ?? null;\n}\n\nfunction kitOrPairOf(glyph: string): IRtIcon.Name | null {\n return isKitIconName(glyph) ? glyph : materialPairOf(glyph);\n}\n\n/** Имя кита, которое шрифт нарисовать не может: дефис или заглавная буква. Лигатура — `null`. */\nfunction unlettered(glyph: string): IRtIcon.Name | null {\n return isKitIconName(glyph) && !LIGATURE_NAME.test(glyph) ? glyph : null;\n}\n\n/**\n * Чем рисуется значок: своим рисунком кита или лигатурой шрифта Material.\n *\n * Имя кита выигрывает у имени Material, если названы оба. Имя Material по способу `map-first`\n * берёт пару из перечня, а без пары — шрифт; по способу `font` — шрифт сразу. Имя кита, которое шрифт\n * нарисовать не может (`ico-plus`, `docBox`), и по способу `font` рисуется рисунком кита: иначе в\n * значке стоит текст имени. Имя кита, совпавшее с лигатурой (`search`), по `font` — шрифт. Материальный рисунок\n * для пары выбирает уже сам значок по признаку набора над собой: это не дело разбора.\n *\n * `null` — значку нечего рисовать.\n */\nexport function resolveIconGlyph(\n name: IRtIcon.Name | null | undefined,\n glyph: string | null | undefined,\n strategy: IRtIcon.GlyphStrategy\n): IRtIcon.Resolved | null {\n if (name) {\n return { kind: 'kit', name };\n }\n if (!glyph) {\n return null;\n }\n const pair: IRtIcon.Name | null = strategy === 'map-first' ? kitOrPairOf(glyph) : unlettered(glyph);\n return pair === null ? { kind: 'font', glyph } : { kind: 'kit', name: pair };\n}\n","/**\n * Имена, которыми набор значков виден со стороны страницы.\n *\n * Отдельный файл, а не константы реестра: те же имена читает обвязка снимков витрины, а она идёт\n * под Playwright и ни одного объявления Angular поднять не может. Своя копия там уже стояла —\n * второе объявление того же значения расходится с первым молча: ожидание набора ищет один узел,\n * а реестр создаёт другой, и кадр выходит без значков.\n */\n\n/** Селектор inline-sprite, создаваемого один раз при первом обращении. */\nexport const RT_ICON_SPRITE_ID: string = 'rt-icon-sprite';\n\n/** Префикс `id` для inline-sprite символов. Изолирует от внешних `id` на странице. */\nexport const RT_ICON_SYMBOL_ID_PREFIX: string = 'rt-icon-';\n\n/**\n * Префикс `id` символов материального набора. Свой, а не общий: наборов на странице бывает два —\n * признак набора стоит и на корне, и на контейнере, — а один `id` держит один рисунок. С общим\n * префиксом второй набор молча забирал бы символ первого.\n */\nexport const RT_ICON_MATERIAL_SYMBOL_ID_PREFIX: string = 'rt-icon-material-';\n\n/** Префикс `id` залитых рисунков материального набора: у имени их два, и `id` у каждого свой. */\nexport const RT_ICON_MATERIAL_FILL_SYMBOL_ID_PREFIX: string = 'rt-icon-material-fill-';\n\n/**\n * Атрибут, который переключает только набор рисунков значков: токенов набора оформления он не\n * несёт. Ставится на контейнер со значением `'material'` там, где значки нужны материальные, а\n * остальной вид — свой.\n */\nexport const RT_ICON_PRESET_ATTRIBUTE: string = 'data-rt-icon-preset';\n\n/**\n * Селекторы, которыми страница объявляет материальный набор значков: признак набора оформления\n * и признак одних значков. Стили читают только первые два — токены под третьим не меняются.\n */\nexport const RT_ICON_MATERIAL_PRESET_SELECTOR: string = `[data-preset='material'],.rt-preset-material,[${RT_ICON_PRESET_ATTRIBUTE}='material']`;\n","import { DOCUMENT } from '@angular/common';\nimport { HttpClient } from '@angular/common/http';\nimport { Injectable, InjectionToken, inject } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { EMPTY, Observable, Subject, catchError, map, mergeMap, tap } from 'rxjs';\n\nimport { PlatformService } from '@rt-tools/core';\n\nimport {\n RT_ICON_MATERIAL_FILL_SYMBOL_ID_PREFIX,\n RT_ICON_MATERIAL_SYMBOL_ID_PREFIX,\n RT_ICON_SPRITE_ID,\n RT_ICON_SYMBOL_ID_PREFIX,\n} from './rt-icon.const';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\n/**\n * Адрес, по которому приложение публикует набор из `assets/icons` пакета.\n * Умолчание годится, когда сборка кладёт набор в корень статики; свой адрес\n * задаётся аргументом `provideRtIcons()`.\n */\nexport const RT_ICONS_BASE_URL: InjectionToken<string> = new InjectionToken<string>('RT_ICONS_BASE_URL', {\n providedIn: 'root',\n factory: (): string => '/icons',\n});\n\n/**\n * Адрес материального набора значков. Отдельный от своего: два набора стоят рядом, и приложение\n * кладёт их двумя папками.\n */\nexport const RT_ICONS_MATERIAL_BASE_URL: InjectionToken<string> = new InjectionToken<string>('RT_ICONS_MATERIAL_BASE_URL', {\n providedIn: 'root',\n factory: (): string => '/icons-material',\n});\n\n@Injectable({ providedIn: 'root' })\nexport class RtIconRegistry {\n readonly #http: HttpClient = inject(HttpClient);\n readonly #doc: Document = inject(DOCUMENT);\n readonly #baseUrl: string = inject(RT_ICONS_BASE_URL);\n readonly #materialBaseUrl: string = inject(RT_ICONS_MATERIAL_BASE_URL);\n readonly #platform: PlatformService = inject(PlatformService);\n\n /**\n * Имена, за которыми уже сходили: второй раз в сеть за ними не ходят. Ключ несёт набор —\n * одно имя приезжает двумя разными рисунками, и общий ключ отдал бы второму первый.\n */\n readonly #requested: Set<string> = new Set<string>();\n\n /** Имена, которые попросила разметка. Загрузку по ним ведёт подписка из конструктора. */\n readonly #requestSource: Subject<IRtIconRequest> = new Subject<IRtIconRequest>();\n\n constructor() {\n // Потоки складываются, а не вытесняют друг друга: странице нужны все спрошенные\n // значки, а не последний из них.\n this.#requestSource\n .pipe(\n mergeMap((asked: IRtIconRequest): Observable<void> => this.#load(asked)),\n takeUntilDestroyed()\n )\n .subscribe();\n }\n\n /**\n * Имя symbol для `<use href=\"#X\">`. Возвращает строку с ведущим `#`.\n *\n * Набор назван явно, а не выведен из страницы: одна и та же страница держит оба набора\n * рядом — признак стоит и на корне, и на контейнере, — и вывод по странице дал бы обоим\n * один ответ.\n */\n public symbolHref(name: IRtIcon.Name, drawing: IRtIcon.Drawing = 'base'): string {\n return `#${this.#symbolId(name, drawing)}`;\n }\n\n /**\n * Просит значок по имени: грузит файл и дописывает `<symbol>` в спрайт страницы.\n *\n * Ответа зовущий не ждёт и потока не получает: разметка рисует ссылку на символ сразу, а\n * браузер дорисовывает её, когда символ приезжает. Подписка живёт здесь и только здесь —\n * иначе каждая разметка гасила бы её сама, а таких мест у значка два.\n */\n public request(name: IRtIcon.Name, drawing: IRtIcon.Drawing = 'base'): void {\n const id: string = this.#symbolId(name, drawing);\n // На сервере относительных запросов к статике нет вовсе: значок дорисуется после\n // гидрации, когда разметка попросит его снова уже в браузере.\n if (!this.#platform.isPlatformBrowser || this.#requested.has(id)) {\n return;\n }\n this.#requested.add(id);\n // Символ уже лежит в спрайте страницы: его положила соседняя история витрины или\n // сама страница до старта приложения. Запроса не уходит вовсе.\n if (this.#doc.getElementById(id)) {\n return;\n }\n this.#requestSource.next({ name, drawing });\n }\n\n #load(asked: IRtIconRequest): Observable<void> {\n if (asked.drawing === 'base') {\n return this.#loadInto(asked, `${this.#baseUrl}/${asked.name}.svg`, EMPTY);\n }\n\n // Материальный рисунок, который не приехал, закрывается своим. Материальный набор —\n // слой переопределений: имени, которого в нём нет, кит и так рисует свой рисунок, и\n // не приехавший файл обязан вести себя так же. Иначе страница, объявившая набор, но\n // не опубликовавшая его папку, показывает пустое место там, где обещан значок, —\n // разметка при этом верна, и промах виден только глазами. Залитый, которого нет,\n // сперва закрывается контурным того же набора.\n const own: Observable<void> = this.#loadInto(asked, `${this.#baseUrl}/${asked.name}.svg`, EMPTY);\n const outlined: Observable<void> =\n asked.drawing === 'material-fill' ? this.#loadInto(asked, `${this.#materialBaseUrl}/${asked.name}.svg`, own) : own;\n const file: string = asked.drawing === 'material-fill' ? `${asked.name}.fill.svg` : `${asked.name}.svg`;\n\n return this.#loadInto(asked, `${this.#materialBaseUrl}/${file}`, outlined);\n }\n\n /**\n * Рисунок по адресу под именем символа, которое просила разметка: подмена ссылки разметке\n * не нужна. Отказ одного имени гасит только его значок — иначе один промах в наборе ронял бы\n * всю страницу, а соседние значки уже приехали.\n */\n #loadInto(asked: IRtIconRequest, url: string, fallback: Observable<void>): Observable<void> {\n return this.#http.get(url, { responseType: 'text' }).pipe(\n tap((raw: string): void => this.#mountSymbol(asked, raw)),\n map((): void => undefined),\n catchError((): Observable<void> => fallback)\n );\n }\n\n #symbolId(name: IRtIcon.Name, drawing: IRtIcon.Drawing): string {\n const prefix: Record<IRtIcon.Drawing, string> = {\n base: RT_ICON_SYMBOL_ID_PREFIX,\n material: RT_ICON_MATERIAL_SYMBOL_ID_PREFIX,\n 'material-fill': RT_ICON_MATERIAL_FILL_SYMBOL_ID_PREFIX,\n };\n return `${prefix[drawing]}${name}`;\n }\n\n #mountSymbol(asked: IRtIconRequest, raw: string): void {\n const symbol: SVGSymbolElement = this.#doc.createElementNS('http://www.w3.org/2000/svg', 'symbol');\n symbol.id = this.#symbolId(asked.name, asked.drawing);\n symbol.setAttribute('viewBox', this.#viewBox(raw));\n symbol.innerHTML = this.#inner(raw);\n this.#sprite().appendChild(symbol);\n }\n\n #viewBox(raw: string): string {\n const viewBoxMatch: RegExpExecArray | null = /viewBox=\"([^\"]+)\"/.exec(raw);\n return viewBoxMatch ? viewBoxMatch[1] : '0 0 24 24';\n }\n\n #inner(raw: string): string {\n // Тело корневого `<svg>` без него самого: оно и становится телом `<symbol>`.\n return raw\n .replace(/<\\?xml[\\s\\S]*?\\?>/g, '')\n .replace(/<!DOCTYPE[\\s\\S]*?>/g, '')\n .replace(/<svg\\b[^>]*>/i, '')\n .replace(/<\\/svg>\\s*$/i, '')\n .trim();\n }\n\n #sprite(): SVGSVGElement {\n const existing: SVGSVGElement | null = this.#doc.querySelector<SVGSVGElement>(`svg#${RT_ICON_SPRITE_ID}`);\n if (existing) {\n return existing;\n }\n const sprite: SVGSVGElement = this.#doc.createElementNS('http://www.w3.org/2000/svg', 'svg');\n sprite.id = RT_ICON_SPRITE_ID;\n sprite.setAttribute('aria-hidden', 'true');\n sprite.setAttribute('style', 'position:absolute;width:0;height:0;overflow:hidden;');\n this.#doc.body.insertBefore(sprite, this.#doc.body.firstChild);\n return sprite;\n }\n}\n\n/** Что просит разметка: имя значка и рисунок, который за ним стоит. */\ninterface IRtIconRequest {\n readonly name: IRtIcon.Name;\n readonly drawing: IRtIcon.Drawing;\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n afterNextRender,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n numberAttribute,\n signal,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_ICON_GLYPH_STRATEGY, RtIconFontService } from './rt-icon-font.service';\nimport { resolveIconGlyph } from './rt-icon-glyph.logic';\nimport { iconMaterialDrawn } from './rt-icon-material-map';\nimport { RT_ICON_MATERIAL_PRESET_SELECTOR } from './rt-icon.const';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconRegistry } from './rt-icon.registry';\n\n/* Ступень — свойство, которое приложение задаёт правилом на значке или на его предке; умолчание —\n шаг шкалы размеров кита, те же пиксели, что стояли здесь числом. Имя `--rt-icon-step-*`, а не\n `--rt-icon-size-*`: те объявляет на корне страницы первый кит со своими значениями (md — 24px),\n и в приложении с обоими китами каждый значок второго вырос бы. */\nconst SIZES: Readonly<Record<IRtIcon.Size, string>> = Object.freeze({\n xs: 'var(--rt-icon-step-xs, var(--rt-size-3))',\n sm: 'var(--rt-icon-step-sm, var(--rt-size-4))',\n md: 'var(--rt-icon-step-md, var(--rt-size-5))',\n lg: 'var(--rt-icon-step-lg, var(--rt-size-6))',\n xl: 'var(--rt-icon-step-xl, var(--rt-size-8))',\n '2xl': 'var(--rt-icon-step-2xl, var(--rt-size-10))',\n '3xl': 'var(--rt-icon-step-3xl, var(--rt-size-12))',\n '4xl': 'var(--rt-icon-step-4xl, var(--rt-size-16))',\n});\n\n/* Пиксели ступеней по умолчанию — оптический размер лигатуры. Без оси `opsz` в настройках шрифта\n браузер ставил её по размеру шрифта, и умолчание повторяет это: значок, которому приложение оси\n не задало, рисуется как прежде. */\nconst STEP_PX: Readonly<Record<IRtIcon.Size, number>> = Object.freeze({\n xs: 12,\n sm: 16,\n md: 20,\n lg: 24,\n xl: 32,\n '2xl': 40,\n '3xl': 48,\n '4xl': 64,\n});\n\n/* Без переданного цвета значок цвета не пишет: `currentColor` строкой стиля перебивал правило\n стилей, которое красит значок снаружи, — значок опасного пункта меню оставался цвета текста. */\n// Каждый тон можно переназначить свойством сверху: поле ввода называет так тон своего значка в\n// наборе оформления. Цвет стоит встроенным стилем, и правилом его не перебить.\nconst COLORS: Readonly<Record<IRtIcon.Color, string | null>> = Object.freeze({\n current: null,\n primary: 'var(--rt-icon-color-primary, var(--rt-color-action-primary-on-surface))',\n muted: 'var(--rt-icon-color-muted, var(--rt-neutral-600))',\n disabled: 'var(--rt-icon-color-disabled, var(--rt-color-text-disabled))',\n info: 'var(--rt-icon-color-info, var(--rt-color-state-info))',\n success: 'var(--rt-icon-color-success, var(--rt-color-state-success))',\n warning: 'var(--rt-icon-color-warning, var(--rt-color-state-warning))',\n danger: 'var(--rt-icon-color-danger, var(--rt-color-state-danger))',\n inverse: 'var(--rt-icon-color-inverse, var(--rt-color-text-inverse))',\n});\n\nfunction isSizeStep(value: string): value is IRtIcon.Size {\n return Object.hasOwn(SIZES, value);\n}\n\n/** Ступень остаётся ступенью, число — пикселями. Числовая строка читается числом, прочее — ступенью `md`. */\nfunction toSize(value: IRtIcon.SizeInput | string): IRtIcon.SizeInput {\n let size: IRtIcon.SizeInput = typeof value === 'number' || isSizeStep(value) ? value : numberAttribute(value, 0);\n if (typeof size === 'number' && size <= 0) {\n size = 'md';\n }\n return size;\n}\n\nconst BEM_BLOCK: string = 'rt-icon';\n\n@Component({\n selector: 'rt-icon',\n templateUrl: './rt-icon.component.html',\n styleUrls: ['./rt-icon.component.scss'],\n imports: [BlockDirective, ElemDirective, ModDirective],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: BEM_BLOCK,\n '[attr.aria-hidden]': \"'true'\",\n '[style.width]': 'sizeValue()',\n '[style.height]': 'sizeValue()',\n '[style.color]': 'colorValue()',\n '[style.transform]': 'rotateStyle()',\n '[class.rt-icon--spin]': 'spin()',\n },\n})\nexport class RtIconComponent {\n readonly #registry: RtIconRegistry = inject(RtIconRegistry);\n readonly #host: ElementRef<HTMLElement> = inject(ElementRef);\n readonly #strategy: IRtIcon.GlyphStrategy = inject(RT_ICON_GLYPH_STRATEGY);\n readonly #fontReady: Signal<boolean> = inject(RtIconFontService).ready;\n\n /**\n * Набор, объявленный разметкой над этим значком.\n *\n * Читается у разметки, а не выбирается стилями: ссылку на символ спрайта CSS подменить нечем,\n * и второй `<use>` рядом с первым тоже не годится — он вечно указывает на символ, за которым\n * никто не ходил, а обвязка снимков ждёт, пока нарисуется каждый.\n *\n * Спрашивается ближайший предок, а не корень страницы: признак набора стоит и на контейнере,\n * и на одной странице законно живут оба набора рядом.\n *\n * Один раз после первой отрисовки: на сервере разметки нет вовсе, а признак набора страница\n * по ходу жизни не переставляет — его ставит приложение своей разметкой.\n */\n readonly #preset: WritableSignal<IRtIcon.Preset> = signal<IRtIcon.Preset>('base');\n\n /** Чем рисуется значок: именем кита или лигатурой шрифта. Ни имени, ни глифа — пустое место. */\n protected readonly resolved: Signal<IRtIcon.Resolved | null> = computed((): IRtIcon.Resolved | null =>\n resolveIconGlyph(this.name(), this.glyph(), this.glyphStrategy() ?? this.#strategy)\n );\n\n protected readonly kitName: Signal<IRtIcon.Name | null> = computed((): IRtIcon.Name | null => {\n const resolved: IRtIcon.Resolved | null = this.resolved();\n return resolved?.kind === 'kit' ? resolved.name : null;\n });\n\n protected readonly fontGlyph: Signal<string | null> = computed((): string | null => {\n const resolved: IRtIcon.Resolved | null = this.resolved();\n return resolved?.kind === 'font' ? resolved.glyph : null;\n });\n\n /** Лигатура прячется, пока шрифты страницы не готовы: до того она рисуется словом. */\n protected readonly glyphMods: Signal<Record<string, boolean>> = computed((): Record<string, boolean> => ({\n filled: this.fill(),\n pending: !this.#fontReady(),\n }));\n\n protected readonly href: Signal<string | null> = computed((): string | null => {\n const name: IRtIcon.Name | null = this.kitName();\n return name === null ? null : this.#registry.symbolHref(name, this.drawing());\n });\n\n /**\n * Набор, которым рисуется этот значок. Материальный закрывает не все имена кита — он слой\n * переопределений, как набор оформления: имя без материального рисунка рисуется своим, и это\n * не пробел.\n */\n protected readonly preset: Signal<IRtIcon.Preset> = computed((): IRtIcon.Preset => {\n const name: IRtIcon.Name | null = this.kitName();\n return this.#preset() === 'material' && name !== null && iconMaterialDrawn.has(name) ? 'material' : 'base';\n });\n\n /** Рисунок значка: залитый бывает только у материального набора, свой набор заливки не знает. */\n protected readonly drawing: Signal<IRtIcon.Drawing> = computed((): IRtIcon.Drawing => {\n if (this.preset() === 'base') {\n return 'base';\n }\n return this.fill() ? 'material-fill' : 'material';\n });\n\n /** Длина CSS стороны значка: ступень — её свойство `--rt-icon-step-*`, число — пиксели. */\n protected readonly sizeValue: Signal<string> = computed((): string => {\n const size: IRtIcon.SizeInput = this.size();\n return typeof size === 'number' ? `${size}px` : SIZES[size];\n });\n\n /** Оптический размер лигатуры, пока приложение не задало `--rt-icon-glyph-opsz`: сторона значка в пикселях. */\n protected readonly opticalSize: Signal<number> = computed((): number => {\n const size: IRtIcon.SizeInput = this.size();\n return typeof size === 'number' ? size : STEP_PX[size];\n });\n\n protected readonly colorValue: Signal<string | null> = computed((): string | null => COLORS[this.color()]);\n\n protected readonly rotateStyle: Signal<string | null> = computed((): string | null => {\n const r: number | null = this.rotate();\n return r !== null && r !== 0 ? `rotate(${r}deg)` : null;\n });\n\n /** Имя кита. Стоит рядом с глифом и побеждает его, когда переданы оба. */\n public readonly name: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n /**\n * Имя Material вместо имени кита. Как оно рисуется — парой из перечня кита или лигатурой\n * шрифта Material Symbols — решает настройка `glyphStrategy` у `provideRtIcons()`. Шрифт\n * приложение подключает само; семья берётся из свойства `--rt-icon-glyph-font`.\n */\n public readonly glyph: InputSignal<string | null> = input<string | null>(null);\n\n /**\n * Как рисовать имя Material у этого значка. Перекрывает `glyphStrategy` из `provideRtIcons()`;\n * `null` — берётся настройка приложения. Дефолт `null`.\n */\n public readonly glyphStrategy: InputSignal<IRtIcon.GlyphStrategy | null> = input<IRtIcon.GlyphStrategy | null>(null);\n\n /**\n * Ступень размера или число пикселей — для размеров между ступенями и крупнее последней.\n * Числовая строка из статического атрибута читается числом, прочая строка вне ступеней — `md`.\n * Внутри вход хранит ступень или положительное число пикселей.\n */\n public readonly size: InputSignalWithTransform<IRtIcon.SizeInput, IRtIcon.SizeInput | string> = input<\n IRtIcon.SizeInput,\n IRtIcon.SizeInput | string\n >('md', { transform: toSize });\n\n public readonly color: InputSignal<IRtIcon.Color> = input<IRtIcon.Color>('current');\n\n /**\n * Залитый рисунок вместо контурного — как `FILL 1` у значка первого кита. Действует в\n * материальном наборе; свой набор рисует значок одним рисунком. Дефолт `false`.\n */\n public readonly fill: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /**\n * Значок вращается — как индикатор занятости внутри кнопки или строки. Когда система просит\n * меньше движения, вращение медленнее. Поворот на время вращения уступает ему. Дефолт `false`.\n */\n public readonly spin: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly rotate: InputSignalWithTransform<number | null, TRotateInput> = input<number | null, TRotateInput>(null, {\n transform: (v: TRotateInput): number | null => {\n if (v === null || v === '') {\n return null;\n }\n return numberAttribute(v, 0);\n },\n });\n\n constructor() {\n // Значок едет по запросу имени, а не вперёд всем набором: страница платит за то, что\n // нарисовала. Смена имени просит новое — прежний символ остаётся в спрайте.\n effect((): void => {\n const name: IRtIcon.Name | null = this.kitName();\n if (name !== null) {\n this.#registry.request(name, this.drawing());\n }\n });\n\n // Разметка над значком видна только в браузере и только после первой отрисовки:\n // контейнер с признаком набора рисует то же приложение.\n afterNextRender((): void => {\n if (this.#host.nativeElement.closest(RT_ICON_MATERIAL_PRESET_SELECTOR)) {\n this.#preset.set('material');\n }\n });\n }\n}\n\ntype TRotateInput = number | string | null;\n","<ng-container rtBlock=\"rt-icon\">\n @if (href(); as symbol) {\n <svg focusable=\"false\" aria-hidden=\"true\" [attr.viewBox]=\"'0 0 24 24'\">\n <use [attr.href]=\"symbol\" />\n </svg>\n } @else if (fontGlyph(); as ligature) {\n <span\n rtElem=\"glyph\"\n aria-hidden=\"true\"\n [rtMod]=\"glyphMods()\"\n [style.font-size]=\"sizeValue()\"\n [style.--rt-icon-glyph-opsz-auto]=\"opticalSize()\">\n {{ ligature }}\n </span>\n }\n</ng-container>\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport { RT_ICON_GLYPH_STRATEGY } from './rt-icon-font.service';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RT_ICONS_BASE_URL, RT_ICONS_MATERIAL_BASE_URL } from './rt-icon.registry';\n\n/**\n * Называет адрес, по которому приложение опубликовало набор значков `rt-icon`.\n *\n * ```typescript\n * export function withCoreProviders(): EnvironmentProviders {\n * return makeEnvironmentProviders([\n * provideHttpClient(...),\n * provideRtStorage(),\n * provideRtIcons(),\n * ]);\n * }\n * ```\n *\n * Вперёд отсюда не грузится ничего: значок едет тогда, когда его попросила разметка, и платит\n * за него та страница, которая его нарисовала. Сборка спрайта и загрузка — дело `RtIconRegistry`.\n *\n * Сами файлы приложение публикует само — набор лежит в `assets/icons` пакета, и сборка копирует\n * его в свою статику.\n *\n * Наборов значков два: свой и материальный. Второй нужен только приложению, которое объявляет\n * материальный набор оформления, и адрес у него свой — набор лежит в `assets/icons-material`.\n *\n * Третий аргумент — настройки значков. `glyphStrategy` говорит, как рисуется имя Material на входе\n * `glyph`: `map-first` (по умолчанию) — пара из перечня кита, а без пары шрифт Material Symbols;\n * `font` — шрифт для любого имени. Шрифт приложение подключает само.\n *\n * @param baseUrl Адрес опубликованного набора. По умолчанию `/icons`.\n * @param materialBaseUrl Адрес материального набора. По умолчанию `/icons-material`.\n * @param options Настройки значков.\n */\nexport function provideRtIcons(baseUrl?: string, materialBaseUrl?: string, options?: IRtIconsOptions): EnvironmentProviders {\n return makeEnvironmentProviders([\n ...(baseUrl === undefined ? [] : [{ provide: RT_ICONS_BASE_URL, useValue: baseUrl }]),\n ...(materialBaseUrl === undefined ? [] : [{ provide: RT_ICONS_MATERIAL_BASE_URL, useValue: materialBaseUrl }]),\n ...(options?.glyphStrategy === undefined ? [] : [{ provide: RT_ICON_GLYPH_STRATEGY, useValue: options.glyphStrategy }]),\n ]);\n}\n\n/** Настройки значков приложения — третий аргумент `provideRtIcons()`. */\nexport interface IRtIconsOptions {\n readonly glyphStrategy?: IRtIcon.GlyphStrategy;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;AAEA;;;;;;;AAOG;AACH;AACO,MAAM,cAAc,GAAG;IAC1B,YAAY;IACZ,qBAAqB;IACrB,QAAQ;IACR,iBAAiB;IACjB,eAAe;IACf,WAAW;IACX,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,MAAM;;AAeV,SAAS,aAAa,CAAC,IAAY,EAAE,QAA2B,EAAA;AAC5D,IAAA,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAS,KAAc,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACpE;AAEA,SAAS,OAAO,CAAC,IAAY,EAAE,KAAwB,EAAA;AACnD,IAAA,OAAO,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC/B;AAEA,SAAS,kBAAkB,CAAC,QAA2B,EAAE,KAAwB,EAAA;AAC7E,IAAA,OAAO,CAAC,IAAY,KAAc,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;AAC3F;AAEA;;;;;AAKG;AACI,MAAM,mBAAmB,GAAiC;;;AAG7D,IAAA,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAS,KAAc,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;AAC9E,IAAA,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAS,KAAc,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;AAC3E,IAAA;AACI,QAAA,QAAQ,EAAE,YAAY;AACtB,QAAA,KAAK,EAAE,kBAAkB,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC;AACvF,KAAA;AACD,IAAA;AACI,QAAA,QAAQ,EAAE,qBAAqB;QAC/B,KAAK,EAAE,kBAAkB,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;AAClG,KAAA;AACD,IAAA;AACI,QAAA,QAAQ,EAAE,QAAQ;AAClB,QAAA,KAAK,EAAE,kBAAkB,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACtI,KAAA;AACD,IAAA;AACI,QAAA,QAAQ,EAAE,iBAAiB;AAC3B,QAAA,KAAK,EAAE,kBAAkB,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;AAC9D,KAAA;AACD,IAAA;AACI,QAAA,QAAQ,EAAE,eAAe;QACzB,KAAK,EAAE,kBAAkB,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AACzH,KAAA;AACD,IAAA;AACI,QAAA,QAAQ,EAAE,WAAW;QACrB,KAAK,EAAE,kBAAkB,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AAChH,KAAA;AACD,IAAA;AACI,QAAA,QAAQ,EAAE,QAAQ;AAClB,QAAA,KAAK,EAAE,kBAAkB,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAC5D,KAAA;AACD,IAAA;AACI,QAAA,QAAQ,EAAE,UAAU;AACpB,QAAA,KAAK,EAAE,CAAC,CAAS,KAAc,OAAO,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AAC/F,KAAA;;AAGL;;;AAGG;AACG,SAAU,UAAU,CAAC,IAAkB,EAAA;AACzC,IAAA,KAAK,MAAM,IAAI,IAAI,mBAAmB,EAAE;AACpC,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;YAClB,OAAO,IAAI,CAAC,QAAQ;QACxB;IACJ;AACA,IAAA,OAAO,MAAM;AACjB;;AClGA;;;AAGG;MACU,sBAAsB,GAA0C,IAAI,cAAc,CAC3F,wBAAwB,EACxB;AACI,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAA6B,WAAW;AACpD,CAAA;AAGL;;;;;;;AAOG;MAEU,iBAAiB,CAAA;AACjB,IAAA,MAAM;AAEN,IAAA,UAAU;AAEV,IAAA,SAAS;AAIlB,IAAA,WAAA,GAAA;QARS,IAAA,CAAA,MAAM,GAA4B,MAAM,CAAU,KAAK;mFAAC;AAExD,QAAA,IAAA,CAAA,UAAU,GAAY,MAAM,CAAC,eAAe,CAAC,CAAC,iBAAiB;AAE/D,QAAA,IAAA,CAAA,SAAS,GAAa,MAAM,CAAC,QAAQ,CAAC;AAE/B,QAAA,IAAA,CAAA,KAAK,GAAoB,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;QAG7D,IAAI,CAAC,WAAW,EAAE;IACtB;IAEA,WAAW,GAAA;AACP,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YAClB;QACJ;AACA,QAAA,MAAM,KAAK,GAA4B,IAAI,CAAC,SAAS,CAAC,KAAK;QAC3D,IAAI,CAAC,KAAK,EAAE;AACR,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YACrB;QACJ;AACA,QAAA,KAAK,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAY,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5D;8GAvBS,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAjB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,cADJ,MAAM,EAAA,CAAA,CAAA;;2FACnB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAD7B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACzBlC;;;;;;;;;;;;;;;;;;;;AAoBG;AAEH;AACA,MAAM,SAAS,GAAW,kBAAkB;AAcrC,MAAM,eAAe,GAAoC;IAC5D,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,qFAAqF,EAAE;IACtI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,sFAAsF,EAAE;IAC5H,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,4BAA4B,EAAE;IAC3E,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE,6BAA6B,EAAE;IAChF,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,+CAA+C,EAAE;IAC7F,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,8DAA8D,EAAE;IAC3G,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,qCAAqC,EAAE;IACxE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,oEAAoE,EAAE;IAC1G,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,SAAS,EAAE;IACxD,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,EAAE;IAC5D,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,eAAe,EAAE,GAAG,EAAE,SAAS,EAAE;AAC9D,IAAA,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAA,EAAG,SAAS,0BAA0B,EAAE;IAC3E,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,+CAA+C,EAAE;IAC1F,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,+DAA+D,EAAE;IAC3G,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,8CAA8C,EAAE;IACpF,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,wEAAwE,EAAE;IACxH,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,8CAA8C,EAAE;IAClF,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,sBAAsB,EAAE;IAC3D,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,0EAA0E,EAAE;AACzH,IAAA;AACI,QAAA,IAAI,EAAE,aAAa;AACnB,QAAA,EAAE,EAAE,QAAQ;AACZ,QAAA,GAAG,EAAE,wHAAwH;AAChI,KAAA;IACD,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,uBAAuB,EAAE;IAC5D,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE;IAChD,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,SAAS,EAAE;IACxD,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,SAAS,EAAE;IACxD,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,yEAAyE,EAAE;IAClI,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE;IAClD,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE;IAC5C,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE,mEAAmE,EAAE;IAC7G,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,qDAAqD,EAAE;IACrG,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,yDAAyD,EAAE;IACnH,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE;IAChD,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,oDAAoD,EAAE;IAChG,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,oBAAoB,EAAE;IAC7D,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,uCAAuC,EAAE;IAChF,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,yBAAyB,EAAE;IAC5D,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,sDAAsD,EAAE;IACrG,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,0BAA0B,EAAE;IACnE,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,0BAA0B,EAAE;IACzE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,wBAAwB,EAAE;IACtE,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,eAAe,EAAE,GAAG,EAAE,4BAA4B,EAAE;AAC/E,IAAA;AACI,QAAA,IAAI,EAAE,WAAW;AACjB,QAAA,EAAE,EAAE,QAAQ;AACZ,QAAA,GAAG,EAAE,8GAA8G;AACtH,KAAA;IACD,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,qDAAqD,EAAE;IAC1F,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,+EAA+E,EAAE;IAC5H,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,4EAA4E,EAAE;IAClH,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE;IAClD,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,mCAAmC,EAAE;AACzE,IAAA,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAA,EAAG,SAAS,2BAA2B,EAAE;IAC9E,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,yBAAyB,EAAE;IAC/D,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE;IAC5C,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE;IAC5C,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,yBAAyB,EAAE;IACxE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,0BAA0B,EAAE;IACrE,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,EAAE;IAC5D,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,oEAAoE,EAAE;IAC/G,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,yCAAyC,EAAE;IACjF,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,iCAAiC,EAAE;IAEnF,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE,4BAA4B,EAAE;;AAG7E;;;;;AAKG;AACI,MAAM,iBAAiB,GAA8B,IAAI,GAAG,CAC/D;KACK,GAAG,CAAC,CAAC,KAA2B,KAA0B,KAAK,CAAC,EAAE;KAClE,MAAM,CAAC,CAAC,IAAyB,KAA2B,IAAI,KAAK,IAAI,CAAC;;ACjHnF,MAAM,SAAS,GAAwB,IAAI,GAAG,CAAS,SAAS,CAAC;AAEjE;AACA,MAAM,aAAa,GAAW,cAAc;AAE5C;AACM,SAAU,aAAa,CAAC,IAAY,EAAA;AACtC,IAAA,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AAC9B;AAEA;AACM,SAAU,cAAc,CAAC,KAAgC,EAAA;IAC3D,IAAI,CAAC,KAAK,EAAE;AACR,QAAA,OAAO,IAAI;IACf;AACA,IAAA,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,KAA2B,KAAc,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,EAAE,EAAE,IAAI,IAAI;AAC3G;AAEA,SAAS,WAAW,CAAC,KAAa,EAAA;AAC9B,IAAA,OAAO,aAAa,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC;AAC/D;AAEA;AACA,SAAS,UAAU,CAAC,KAAa,EAAA;IAC7B,OAAO,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI;AAC5E;AAEA;;;;;;;;;;AAUG;SACa,gBAAgB,CAC5B,IAAqC,EACrC,KAAgC,EAChC,QAA+B,EAAA;IAE/B,IAAI,IAAI,EAAE;AACN,QAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;IAChC;IACA,IAAI,CAAC,KAAK,EAAE;AACR,QAAA,OAAO,IAAI;IACf;AACA,IAAA,MAAM,IAAI,GAAwB,QAAQ,KAAK,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC;IACnG,OAAO,IAAI,KAAK,IAAI,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE;AAChF;;ACvDA;;;;;;;AAOG;AAEH;AACO,MAAM,iBAAiB,GAAW;AAEzC;AACO,MAAM,wBAAwB,GAAW;AAEhD;;;;AAIG;AACI,MAAM,iCAAiC,GAAW;AAEzD;AACO,MAAM,sCAAsC,GAAW;AAE9D;;;;AAIG;AACI,MAAM,wBAAwB,GAAW;AAEhD;;;AAGG;AACI,MAAM,gCAAgC,GAAW,CAAA,8CAAA,EAAiD,wBAAwB;;ACnBjI;;;;AAIG;MACU,iBAAiB,GAA2B,IAAI,cAAc,CAAS,mBAAmB,EAAE;AACrG,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAc,QAAQ;AAClC,CAAA;AAED;;;AAGG;MACU,0BAA0B,GAA2B,IAAI,cAAc,CAAS,4BAA4B,EAAE;AACvH,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAc,iBAAiB;AAC3C,CAAA;MAGY,cAAc,CAAA;AACd,IAAA,KAAK,GAAe,MAAM,CAAC,UAAU,CAAC;AACtC,IAAA,IAAI,GAAa,MAAM,CAAC,QAAQ,CAAC;AACjC,IAAA,QAAQ,GAAW,MAAM,CAAC,iBAAiB,CAAC;AAC5C,IAAA,gBAAgB,GAAW,MAAM,CAAC,0BAA0B,CAAC;AAC7D,IAAA,SAAS,GAAoB,MAAM,CAAC,eAAe,CAAC;AAE7D;;;AAGG;AACM,IAAA,UAAU,GAAgB,IAAI,GAAG,EAAU;;AAG3C,IAAA,cAAc,GAA4B,IAAI,OAAO,EAAkB;AAEhF,IAAA,WAAA,GAAA;;;AAGI,QAAA,IAAI,CAAC;AACA,aAAA,IAAI,CACD,QAAQ,CAAC,CAAC,KAAqB,KAAuB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EACxE,kBAAkB,EAAE;AAEvB,aAAA,SAAS,EAAE;IACpB;AAEA;;;;;;AAMG;AACI,IAAA,UAAU,CAAC,IAAkB,EAAE,OAAA,GAA2B,MAAM,EAAA;QACnE,OAAO,CAAA,CAAA,EAAI,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA,CAAE;IAC9C;AAEA;;;;;;AAMG;AACI,IAAA,OAAO,CAAC,IAAkB,EAAE,OAAA,GAA2B,MAAM,EAAA;QAChE,MAAM,EAAE,GAAW,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC;;;AAGhD,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAC9D;QACJ;AACA,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;;;QAGvB,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE;YAC9B;QACJ;QACA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC/C;AAEA,IAAA,KAAK,CAAC,KAAqB,EAAA;AACvB,QAAA,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,EAAE;AAC1B,YAAA,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAA,CAAA,EAAI,KAAK,CAAC,IAAI,MAAM,EAAE,KAAK,CAAC;QAC7E;;;;;;;QAQA,MAAM,GAAG,GAAqB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA,EAAG,IAAI,CAAC,QAAQ,CAAA,CAAA,EAAI,KAAK,CAAC,IAAI,MAAM,EAAE,KAAK,CAAC;AAChG,QAAA,MAAM,QAAQ,GACV,KAAK,CAAC,OAAO,KAAK,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA,EAAG,IAAI,CAAC,gBAAgB,CAAA,CAAA,EAAI,KAAK,CAAC,IAAI,CAAA,IAAA,CAAM,EAAE,GAAG,CAAC,GAAG,GAAG;QACtH,MAAM,IAAI,GAAW,KAAK,CAAC,OAAO,KAAK,eAAe,GAAG,CAAA,EAAG,KAAK,CAAC,IAAI,CAAA,SAAA,CAAW,GAAG,GAAG,KAAK,CAAC,IAAI,CAAA,IAAA,CAAM;AAEvG,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA,EAAG,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAA,CAAE,EAAE,QAAQ,CAAC;IAC9E;AAEA;;;;AAIG;AACH,IAAA,SAAS,CAAC,KAAqB,EAAE,GAAW,EAAE,QAA0B,EAAA;QACpE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,CACrD,GAAG,CAAC,CAAC,GAAW,KAAW,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EACzD,GAAG,CAAC,MAAY,SAAS,CAAC,EAC1B,UAAU,CAAC,MAAwB,QAAQ,CAAC,CAC/C;IACL;IAEA,SAAS,CAAC,IAAkB,EAAE,OAAwB,EAAA;AAClD,QAAA,MAAM,MAAM,GAAoC;AAC5C,YAAA,IAAI,EAAE,wBAAwB;AAC9B,YAAA,QAAQ,EAAE,iCAAiC;AAC3C,YAAA,eAAe,EAAE,sCAAsC;SAC1D;QACD,OAAO,CAAA,EAAG,MAAM,CAAC,OAAO,CAAC,CAAA,EAAG,IAAI,EAAE;IACtC;IAEA,YAAY,CAAC,KAAqB,EAAE,GAAW,EAAA;AAC3C,QAAA,MAAM,MAAM,GAAqB,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,4BAA4B,EAAE,QAAQ,CAAC;AAClG,QAAA,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC;AACrD,QAAA,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAClD,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QACnC,IAAI,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC;IACtC;AAEA,IAAA,QAAQ,CAAC,GAAW,EAAA;QAChB,MAAM,YAAY,GAA2B,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;AAC1E,QAAA,OAAO,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,WAAW;IACvD;AAEA,IAAA,MAAM,CAAC,GAAW,EAAA;;AAEd,QAAA,OAAO;AACF,aAAA,OAAO,CAAC,oBAAoB,EAAE,EAAE;AAChC,aAAA,OAAO,CAAC,qBAAqB,EAAE,EAAE;AACjC,aAAA,OAAO,CAAC,eAAe,EAAE,EAAE;AAC3B,aAAA,OAAO,CAAC,cAAc,EAAE,EAAE;AAC1B,aAAA,IAAI,EAAE;IACf;IAEA,OAAO,GAAA;AACH,QAAA,MAAM,QAAQ,GAAyB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAgB,CAAA,IAAA,EAAO,iBAAiB,CAAA,CAAE,CAAC;QACzG,IAAI,QAAQ,EAAE;AACV,YAAA,OAAO,QAAQ;QACnB;AACA,QAAA,MAAM,MAAM,GAAkB,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,4BAA4B,EAAE,KAAK,CAAC;AAC5F,QAAA,MAAM,CAAC,EAAE,GAAG,iBAAiB;AAC7B,QAAA,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC;AAC1C,QAAA,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,qDAAqD,CAAC;AACnF,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;AAC9D,QAAA,OAAO,MAAM;IACjB;8GAxIS,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAd,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,cAAc,cADD,MAAM,EAAA,CAAA,CAAA;;2FACnB,cAAc,EAAA,UAAA,EAAA,CAAA;kBAD1B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACPlC;;;AAGoE;AACpE,MAAM,KAAK,GAA2C,MAAM,CAAC,MAAM,CAAC;AAChE,IAAA,EAAE,EAAE,0CAA0C;AAC9C,IAAA,EAAE,EAAE,0CAA0C;AAC9C,IAAA,EAAE,EAAE,0CAA0C;AAC9C,IAAA,EAAE,EAAE,0CAA0C;AAC9C,IAAA,EAAE,EAAE,0CAA0C;AAC9C,IAAA,KAAK,EAAE,4CAA4C;AACnD,IAAA,KAAK,EAAE,4CAA4C;AACnD,IAAA,KAAK,EAAE,4CAA4C;AACtD,CAAA,CAAC;AAEF;;AAEqC;AACrC,MAAM,OAAO,GAA2C,MAAM,CAAC,MAAM,CAAC;AAClE,IAAA,EAAE,EAAE,EAAE;AACN,IAAA,EAAE,EAAE,EAAE;AACN,IAAA,EAAE,EAAE,EAAE;AACN,IAAA,EAAE,EAAE,EAAE;AACN,IAAA,EAAE,EAAE,EAAE;AACN,IAAA,KAAK,EAAE,EAAE;AACT,IAAA,KAAK,EAAE,EAAE;AACT,IAAA,KAAK,EAAE,EAAE;AACZ,CAAA,CAAC;AAEF;AACkG;AAClG;AACA;AACA,MAAM,MAAM,GAAmD,MAAM,CAAC,MAAM,CAAC;AACzE,IAAA,OAAO,EAAE,IAAI;AACb,IAAA,OAAO,EAAE,yEAAyE;AAClF,IAAA,KAAK,EAAE,mDAAmD;AAC1D,IAAA,QAAQ,EAAE,8DAA8D;AACxE,IAAA,IAAI,EAAE,uDAAuD;AAC7D,IAAA,OAAO,EAAE,6DAA6D;AACtE,IAAA,OAAO,EAAE,6DAA6D;AACtE,IAAA,MAAM,EAAE,2DAA2D;AACnE,IAAA,OAAO,EAAE,4DAA4D;AACxE,CAAA,CAAC;AAEF,SAAS,UAAU,CAAC,KAAa,EAAA;IAC7B,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC;AACtC;AAEA;AACA,SAAS,MAAM,CAAC,KAAiC,EAAA;IAC7C,IAAI,IAAI,GAAsB,OAAO,KAAK,KAAK,QAAQ,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC;IAChH,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,CAAC,EAAE;QACvC,IAAI,GAAG,IAAI;IACf;AACA,IAAA,OAAO,IAAI;AACf;AAEA,MAAM,SAAS,GAAW,SAAS;MAmBtB,eAAe,CAAA;AACf,IAAA,SAAS;AACT,IAAA,KAAK;AACL,IAAA,SAAS;AACT,IAAA,UAAU;AAEnB;;;;;;;;;;;;AAYG;AACM,IAAA,OAAO;AAsHhB,IAAA,WAAA,GAAA;AAxIS,QAAA,IAAA,CAAA,SAAS,GAAmB,MAAM,CAAC,cAAc,CAAC;AAClD,QAAA,IAAA,CAAA,KAAK,GAA4B,MAAM,CAAC,UAAU,CAAC;AACnD,QAAA,IAAA,CAAA,SAAS,GAA0B,MAAM,CAAC,sBAAsB,CAAC;AACjE,QAAA,IAAA,CAAA,UAAU,GAAoB,MAAM,CAAC,iBAAiB,CAAC,CAAC,KAAK;AAEtE;;;;;;;;;;;;AAYG;QACM,IAAA,CAAA,OAAO,GAAmC,MAAM,CAAiB,MAAM;oFAAC;;QAG9D,IAAA,CAAA,QAAQ,GAAoC,QAAQ,CAAC,MACpE,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC;qFACtF;AAEkB,QAAA,IAAA,CAAA,OAAO,GAAgC,QAAQ,CAAC,MAA0B;AACzF,YAAA,MAAM,QAAQ,GAA4B,IAAI,CAAC,QAAQ,EAAE;AACzD,YAAA,OAAO,QAAQ,EAAE,IAAI,KAAK,KAAK,GAAG,QAAQ,CAAC,IAAI,GAAG,IAAI;QAC1D,CAAC;oFAAC;AAEiB,QAAA,IAAA,CAAA,SAAS,GAA0B,QAAQ,CAAC,MAAoB;AAC/E,YAAA,MAAM,QAAQ,GAA4B,IAAI,CAAC,QAAQ,EAAE;AACzD,YAAA,OAAO,QAAQ,EAAE,IAAI,KAAK,MAAM,GAAG,QAAQ,CAAC,KAAK,GAAG,IAAI;QAC5D,CAAC;sFAAC;;AAGiB,QAAA,IAAA,CAAA,SAAS,GAAoC,QAAQ,CAAC,OAAgC;AACrG,YAAA,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE;AACnB,YAAA,OAAO,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE;SAC9B,CAAC;sFAAC;AAEgB,QAAA,IAAA,CAAA,IAAI,GAA0B,QAAQ,CAAC,MAAoB;AAC1E,YAAA,MAAM,IAAI,GAAwB,IAAI,CAAC,OAAO,EAAE;YAChD,OAAO,IAAI,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;QACjF,CAAC;iFAAC;AAEF;;;;AAIG;AACgB,QAAA,IAAA,CAAA,MAAM,GAA2B,QAAQ,CAAC,MAAqB;AAC9E,YAAA,MAAM,IAAI,GAAwB,IAAI,CAAC,OAAO,EAAE;YAChD,OAAO,IAAI,CAAC,OAAO,EAAE,KAAK,UAAU,IAAI,IAAI,KAAK,IAAI,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,UAAU,GAAG,MAAM;QAC9G,CAAC;mFAAC;;AAGiB,QAAA,IAAA,CAAA,OAAO,GAA4B,QAAQ,CAAC,MAAsB;AACjF,YAAA,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,MAAM,EAAE;AAC1B,gBAAA,OAAO,MAAM;YACjB;AACA,YAAA,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,eAAe,GAAG,UAAU;QACrD,CAAC;oFAAC;;AAGiB,QAAA,IAAA,CAAA,SAAS,GAAmB,QAAQ,CAAC,MAAa;AACjE,YAAA,MAAM,IAAI,GAAsB,IAAI,CAAC,IAAI,EAAE;AAC3C,YAAA,OAAO,OAAO,IAAI,KAAK,QAAQ,GAAG,CAAA,EAAG,IAAI,CAAA,EAAA,CAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QAC/D,CAAC;sFAAC;;AAGiB,QAAA,IAAA,CAAA,WAAW,GAAmB,QAAQ,CAAC,MAAa;AACnE,YAAA,MAAM,IAAI,GAAsB,IAAI,CAAC,IAAI,EAAE;AAC3C,YAAA,OAAO,OAAO,IAAI,KAAK,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QAC1D,CAAC;wFAAC;AAEiB,QAAA,IAAA,CAAA,UAAU,GAA0B,QAAQ,CAAC,MAAqB,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;uFAAC;AAEvF,QAAA,IAAA,CAAA,WAAW,GAA0B,QAAQ,CAAC,MAAoB;AACjF,YAAA,MAAM,CAAC,GAAkB,IAAI,CAAC,MAAM,EAAE;AACtC,YAAA,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,CAAA,IAAA,CAAM,GAAG,IAAI;QAC3D,CAAC;wFAAC;;QAGc,IAAA,CAAA,IAAI,GAAqC,KAAK,CAAsB,IAAI;iFAAC;AAEzF;;;;AAIG;QACa,IAAA,CAAA,KAAK,GAA+B,KAAK,CAAgB,IAAI;kFAAC;AAE9E;;;AAGG;QACa,IAAA,CAAA,aAAa,GAA8C,KAAK,CAA+B,IAAI;0FAAC;AAEpH;;;;AAIG;QACa,IAAA,CAAA,IAAI,GAA4E,KAAK,CAGnG,IAAI,4EAAI,SAAS,EAAE,MAAM,EAAA,CAAG;QAEd,IAAA,CAAA,KAAK,GAA+B,KAAK,CAAgB,SAAS;kFAAC;AAEnF;;;AAGG;QACa,IAAA,CAAA,IAAI,GAAoD,KAAK,CAAwB,KAAK,4EACtG,SAAS,EAAE,gBAAgB,EAAA,CAC7B;AAEF;;;AAGG;QACa,IAAA,CAAA,IAAI,GAAoD,KAAK,CAAwB,KAAK,4EACtG,SAAS,EAAE,gBAAgB,EAAA,CAC7B;QAEc,IAAA,CAAA,MAAM,GAA0D,KAAK,CAA8B,IAAI,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,QAAA,EAAA,8BAAA,EAAA,CAAA,EACnH,SAAS,EAAE,CAAC,CAAe,KAAmB;gBAC1C,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE;AACxB,oBAAA,OAAO,IAAI;gBACf;AACA,gBAAA,OAAO,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;AAChC,YAAA,CAAC,GACH;;;QAKE,MAAM,CAAC,MAAW;AACd,YAAA,MAAM,IAAI,GAAwB,IAAI,CAAC,OAAO,EAAE;AAChD,YAAA,IAAI,IAAI,KAAK,IAAI,EAAE;AACf,gBAAA,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;YAChD;AACJ,QAAA,CAAC,CAAC;;;QAIF,eAAe,CAAC,MAAW;YACvB,IAAI,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,gCAAgC,CAAC,EAAE;AACpE,gBAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;YAChC;AACJ,QAAA,CAAC,CAAC;IACN;8GA1JS,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAf,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAe,kxCC1G5B,+iBAgBA,EAAA,MAAA,EAAA,CAAA,ooCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED6Ec,cAAc,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,aAAa,wEAAE,YAAY,EAAA,QAAA,EAAA,SAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA,CAAA;;2FAa5C,eAAe,EAAA,UAAA,EAAA,CAAA;kBAjB3B,SAAS;AACI,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,SAAS,WAGV,CAAC,cAAc,EAAE,aAAa,EAAE,YAAY,CAAC,EAAA,eAAA,EACrC,uBAAuB,CAAC,MAAM,EAAA,aAAA,EAChC,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAC/B;AACF,wBAAA,KAAK,EAAE,SAAS;AAChB,wBAAA,oBAAoB,EAAE,QAAQ;AAC9B,wBAAA,eAAe,EAAE,aAAa;AAC9B,wBAAA,gBAAgB,EAAE,aAAa;AAC/B,wBAAA,eAAe,EAAE,cAAc;AAC/B,wBAAA,mBAAmB,EAAE,eAAe;AACpC,wBAAA,uBAAuB,EAAE,QAAQ;AACpC,qBAAA,EAAA,QAAA,EAAA,+iBAAA,EAAA,MAAA,EAAA,CAAA,ooCAAA,CAAA,EAAA;;;AElGL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BG;SACa,cAAc,CAAC,OAAgB,EAAE,eAAwB,EAAE,OAAyB,EAAA;AAChG,IAAA,OAAO,wBAAwB,CAAC;QAC5B,IAAI,OAAO,KAAK,SAAS,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACrF,IAAI,eAAe,KAAK,SAAS,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,0BAA0B,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC;QAC9G,IAAI,OAAO,EAAE,aAAa,KAAK,SAAS,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;AAC1H,KAAA,CAAC;AACN;;AC1CA;;AAEG;;;;"}
@@ -103,6 +103,8 @@ class RtScrollAreaComponent {
103
103
  #watchedFooter;
104
104
  /** Наблюдение поставлено: тело и подвал могут быть и пустыми, флаг отличает «снято» от «нечего смотреть». */
105
105
  #isWatching;
106
+ /** Перемер по концу перехода или анимации внутри тела; одна ссылка — чтобы снять тот же слушатель. */
107
+ #onSettled;
106
108
  constructor() {
107
109
  this.t = inject(RT_KIT_LABELS);
108
110
  this.bodyRef = viewChild('body', /* @ts-ignore */
@@ -153,6 +155,8 @@ class RtScrollAreaComponent {
153
155
  this.#watchedFooter = null;
154
156
  /** Наблюдение поставлено: тело и подвал могут быть и пустыми, флаг отличает «снято» от «нечего смотреть». */
155
157
  this.#isWatching = false;
158
+ /** Перемер по концу перехода или анимации внутри тела; одна ссылка — чтобы снять тот же слушатель. */
159
+ this.#onSettled = () => this.onBodyScroll();
156
160
  // Наблюдатели живут, только пока признак включён: выключенный признак ничего не рисует, а
157
161
  // наблюдатель состава с поддеревом заставлял бы браузер пересчитывать раскладку на каждую
158
162
  // правку внутри тела у каждой области экрана. Включение ставит их, выключение снимает.
@@ -233,6 +237,11 @@ class RtScrollAreaComponent {
233
237
  });
234
238
  this.#contentWatch.observe(body, { childList: true, subtree: true, characterData: true });
235
239
  }
240
+ // Раскрытая папка дорастает переходом высоты от нуля: состав меняется в миг вставки, когда
241
+ // высота ещё ноль, а наблюдатель размера пропускал конец роста. Конец перехода и анимации
242
+ // всплывает к телу и перемеряет его по вставшей высоте.
243
+ body.addEventListener('transitionend', this.#onSettled);
244
+ body.addEventListener('animationend', this.#onSettled);
236
245
  }
237
246
  /**
238
247
  * Размер наблюдается у тела, у каждого его прямого потомка и у подвала. Подвал — наравне с
@@ -254,6 +263,8 @@ class RtScrollAreaComponent {
254
263
  }
255
264
  }
256
265
  #unwatch() {
266
+ this.#watchedBody?.removeEventListener('transitionend', this.#onSettled);
267
+ this.#watchedBody?.removeEventListener('animationend', this.#onSettled);
257
268
  this.#sizeWatch?.disconnect();
258
269
  this.#sizeWatch = null;
259
270
  this.#contentWatch?.disconnect();
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-scroll-area.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/scroll-area/rt-scroll-area.directives.ts","../../../projects/ui-kit-v2/src/lib/components/scroll-area/rt-scroll-area.component.ts","../../../projects/ui-kit-v2/src/lib/components/scroll-area/rt-scroll-area.component.html","../../../projects/ui-kit-v2/src/lib/components/scroll-area/rt-tools-ui-kit-v2-scroll-area.ts"],"sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\n\n/**\n * Маркеры частей области прокрутки — своим файлом, как у соседних семей.\n *\n * Каждый маркер держит свой шаблон и не знает об области ничего: область читает маркеры среди\n * своего содержимого и берёт у них шаблон. Часть, которую потребитель не объявил, для области\n * просто отсутствует — рисовать нечего.\n */\n\n/**\n * Шапка области: стоит сверху и не прокручивается.\n *\n * @example\n * ```html\n * <rt-scroll-area>\n * <ng-container *rtScrollAreaHeader>\n * <h3>Заголовок</h3>\n * </ng-container>\n * </rt-scroll-area>\n * ```\n */\n@Directive({\n selector: '[rtScrollAreaHeader]',\n})\nexport class RtScrollAreaHeaderDirective {\n public readonly templateRef: TemplateRef<void> = inject<TemplateRef<void>>(TemplateRef);\n}\n\n/** Тело области: единственная часть, которая прокручивается. */\n@Directive({\n selector: '[rtScrollAreaContent]',\n})\nexport class RtScrollAreaContentDirective {\n public readonly templateRef: TemplateRef<void> = inject<TemplateRef<void>>(TemplateRef);\n}\n\n/** Подвал области: стоит снизу и не прокручивается. */\n@Directive({\n selector: '[rtScrollAreaFooter]',\n})\nexport class RtScrollAreaFooterDirective {\n public readonly templateRef: TemplateRef<void> = inject<TemplateRef<void>>(TemplateRef);\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n afterRenderEffect,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n contentChild,\n DestroyRef,\n ElementRef,\n inject,\n input,\n InputSignalWithTransform,\n signal,\n Signal,\n viewChild,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\nimport { TNullable } from '@rt-tools/utils';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { RtScrollAreaContentDirective, RtScrollAreaFooterDirective, RtScrollAreaHeaderDirective } from './rt-scroll-area.directives';\n\nconst BEM_BLOCK: string = 'rt-scroll-area';\n\n/**\n * Целый пункт запаса при сравнении прокрутки с высотой.\n *\n * Дробная высота строки оставляет остаток, при котором прокрутка уже в самом низу, а разность\n * всё ещё больше нуля: без запаса признак непоказанного висел бы навсегда.\n */\nconst BOTTOM_SLACK_PX: number = 1;\n\n/**\n * Область прокрутки: шапка и подвал стоят, тело прокручивается.\n *\n * Части объявляет потребитель — по директиве на каждую. Необъявленная часть не рисуется вовсе:\n * пустая шапка это полоса отступа над списком, а высоту она забирает у тела, ради которого\n * область и открыли.\n *\n * Договорённость — `docs/specs/ui-kit-v2/scroll-area/`.\n */\n@Component({\n selector: 'rt-scroll-area',\n templateUrl: './rt-scroll-area.component.html',\n styleUrls: ['./rt-scroll-area.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n NgTemplateOutlet,\n\n // standalone components / directives\n RtIconComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ],\n host: { class: BEM_BLOCK },\n})\nexport class RtScrollAreaComponent {\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly bodyRef: Signal<TNullable<ElementRef<HTMLElement>>> = viewChild<ElementRef<HTMLElement>>('body');\n protected readonly footerRef: Signal<TNullable<ElementRef<HTMLElement>>> = viewChild<ElementRef<HTMLElement>>('foot');\n\n /**\n * Ниже окна области ещё есть содержимое. Считается по трём числам самого узла, а не по числу\n * пунктов: область не знает, что ей подали, и высота строки у каждого потребителя своя.\n */\n protected readonly hasMoreBelow: WritableSignal<boolean> = signal(false);\n\n /**\n * На сколько полоса растушёвки поднята над низом области. Она обязана кончиться там, где\n * начинается содержимое подвала: разделитель потребитель рисует первой его строкой, и полоса,\n * оборвавшаяся выше, оставляет до него чистый фон. Считается замером — верхний отступ подвала\n * потребитель пишет как хочет, и вычесть его в стилях не из чего. Без подвала полоса стоит у\n * самого низа.\n */\n protected readonly hintBottom: WritableSignal<number> = signal(0);\n\n public readonly headerTpl: Signal<TNullable<RtScrollAreaHeaderDirective>> = contentChild(RtScrollAreaHeaderDirective);\n public readonly contentTpl: Signal<TNullable<RtScrollAreaContentDirective>> = contentChild(RtScrollAreaContentDirective);\n public readonly footerTpl: Signal<TNullable<RtScrollAreaFooterDirective>> = contentChild(RtScrollAreaFooterDirective);\n\n /**\n * Признак того, что снизу осталось непоказанное. Выключен по умолчанию: область рисуют\n * десятки экранов, и признак, поставленный безусловно, сдвинул бы вид каждому из них.\n */\n public readonly isScrollHintShown: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n /**\n * Наблюдатель за размером тела, его содержимого и подвала. Событие прокрутки приходит только\n * после движения руки, а список не влезает уже в первую минуту показа: без наблюдателя признак\n * появлялся бы у того, кто и так догадался прокрутить, и молчал у того, кому он нужен.\n */\n #sizeWatch: TNullable<ResizeObserver> = null;\n\n /**\n * Наблюдатель за составом тела. Тело — окно постоянной высоты, и когда список дорастает под ним,\n * размер тела не меняется: наблюдатель размера молчит. Пришедшие узлы ставятся под наблюдение\n * размера здесь же — их высота меняется и после того, как они легли.\n */\n #contentWatch: TNullable<MutationObserver> = null;\n\n /** Узлы, за которыми наблюдают сейчас: пересозданное тело или подвал ставятся под наблюдение заново. */\n #watchedBody: HTMLElement | null = null;\n #watchedFooter: HTMLElement | null = null;\n\n /** Наблюдение поставлено: тело и подвал могут быть и пустыми, флаг отличает «снято» от «нечего смотреть». */\n #isWatching: boolean = false;\n\n constructor() {\n // Наблюдатели живут, только пока признак включён: выключенный признак ничего не рисует, а\n // наблюдатель состава с поддеревом заставлял бы браузер пересчитывать раскладку на каждую\n // правку внутри тела у каждой области экрана. Включение ставит их, выключение снимает.\n afterRenderEffect((): void => {\n const body: HTMLElement | null = this.bodyRef()?.nativeElement ?? null;\n const footer: HTMLElement | null = this.footerRef()?.nativeElement ?? null;\n\n if (!this.isScrollHintShown()) {\n this.#unwatch();\n this.hasMoreBelow.set(false);\n\n return;\n }\n\n this.onBodyScroll();\n\n if (!this.#isWatching || body !== this.#watchedBody || footer !== this.#watchedFooter) {\n this.#watch(body, footer);\n }\n });\n\n this.#destroyRef.onDestroy((): void => this.#unwatch());\n }\n\n /**\n * Нажатие на значок уводит тело к самому низу. Нажатие останавливается здесь и в содержимое\n * под значком не уходит: под ним живой пункт, и человек, целившийся в подсказку, уехал бы на\n * чужой экран.\n */\n public onScrollHintClick(event: Event): void {\n event.preventDefault();\n event.stopPropagation();\n\n const body: TNullable<ElementRef<HTMLElement>> = this.bodyRef();\n\n if (!body) {\n return;\n }\n\n body.nativeElement.scrollTo({ top: body.nativeElement.scrollHeight, behavior: 'smooth' });\n }\n\n public onBodyScroll(): void {\n // Выключенный признак не рисуется, и замер для него — чтение раскладки на каждое движение.\n if (!this.isScrollHintShown()) {\n return;\n }\n\n this.#measureHintBottom();\n\n const body: TNullable<ElementRef<HTMLElement>> = this.bodyRef();\n\n if (!body) {\n this.hasMoreBelow.set(false);\n\n return;\n }\n\n const node: HTMLElement = body.nativeElement;\n\n this.hasMoreBelow.set(node.scrollHeight - node.scrollTop - node.clientHeight > BOTTOM_SLACK_PX);\n }\n\n /**\n * Подъём полосы над низом области: высота подвала без его верхнего отступа. Ровно на этом\n * месте начинается содержимое подвала, и до него полоса и должна доходить.\n */\n #measureHintBottom(): void {\n const footer: TNullable<ElementRef<HTMLElement>> = this.footerRef();\n\n if (!footer) {\n this.hintBottom.set(0);\n\n return;\n }\n\n const node: HTMLElement = footer.nativeElement;\n const paddingTop: number = parseFloat(getComputedStyle(node).paddingTop) || 0;\n\n this.hintBottom.set(Math.max(node.offsetHeight - paddingTop, 0));\n }\n\n /** Ставит под наблюдение нынешние тело и подвал; прежние наблюдатели снимаются. */\n #watch(body: HTMLElement | null, footer: HTMLElement | null): void {\n this.#unwatch();\n this.#watchedBody = body;\n this.#watchedFooter = footer;\n this.#isWatching = true;\n\n if (!body) {\n return;\n }\n\n if (typeof ResizeObserver !== 'undefined') {\n this.#sizeWatch = new ResizeObserver((): void => this.onBodyScroll());\n this.#observeSizes();\n }\n\n if (typeof MutationObserver !== 'undefined') {\n this.#contentWatch = new MutationObserver((): void => {\n this.#observeSizes();\n this.onBodyScroll();\n });\n this.#contentWatch.observe(body, { childList: true, subtree: true, characterData: true });\n }\n }\n\n /**\n * Размер наблюдается у тела, у каждого его прямого потомка и у подвала. Подвал — наравне с\n * телом: от его высоты считается подъём полосы, и не наблюдавшаяся, она осталась бы стоять по\n * прежней высоте подвала и наехала бы на его первую строку.\n */\n #observeSizes(): void {\n const watch: TNullable<ResizeObserver> = this.#sizeWatch;\n const body: HTMLElement | null = this.#watchedBody;\n\n if (!watch || !body) {\n return;\n }\n\n // Состав тела сменился — ушедшие узлы снимаются вместе со всеми, пришедшие ставятся заново.\n watch.disconnect();\n watch.observe(body);\n Array.from(body.children).forEach((child: Element): void => watch.observe(child));\n\n if (this.#watchedFooter) {\n watch.observe(this.#watchedFooter);\n }\n }\n\n #unwatch(): void {\n this.#sizeWatch?.disconnect();\n this.#sizeWatch = null;\n this.#contentWatch?.disconnect();\n this.#contentWatch = null;\n this.#watchedBody = null;\n this.#watchedFooter = null;\n this.#isWatching = false;\n }\n}\n","<ng-container rtBlock=\"rt-scroll-area\">\n @if (headerTpl()) {\n <div rtElem=\"header\" qa-dataid=\"scroll-area-header\">\n <ng-container [ngTemplateOutlet]=\"headerTpl()?.templateRef ?? null\" />\n </div>\n }\n\n @if (contentTpl()) {\n <div #body rtElem=\"body\" qa-dataid=\"scroll-area-body\" (scroll)=\"onBodyScroll()\">\n <ng-container [ngTemplateOutlet]=\"contentTpl()?.templateRef ?? null\" />\n </div>\n }\n\n @if (footerTpl()) {\n <div #foot rtElem=\"footer\" qa-dataid=\"scroll-area-footer\">\n <ng-container [ngTemplateOutlet]=\"footerTpl()?.templateRef ?? null\" />\n </div>\n }\n\n <!--\n Признак того, что снизу осталось непоказанное: край списка, ровно обрезанный подвалом,\n читается как конец списка, и человек считает, что пункт пропал. Полоса живёт на хосте, а\n не внутри тела: тело обрезает всё по своему краю, и полоса обрывалась бы на верхнем\n отступе подвала — между ней и разделителем, который потребитель рисует первой строкой\n подвала, оставалась бы полоса чистого фона.\n -->\n @if (isScrollHintShown() && hasMoreBelow()) {\n <div rtElem=\"scroll-hint\" qa-dataid=\"scroll-area-scroll-hint\" [style.bottom.px]=\"hintBottom()\">\n <rt-icon\n rtElem=\"scroll-hint-icon\"\n qa-dataid=\"scroll-area-scroll-hint-icon\"\n name=\"chevron-down\"\n size=\"md\"\n role=\"button\"\n tabindex=\"0\"\n rtTooltipPlacement=\"top\"\n [rtTooltip]=\"t().uiScrollDown\"\n [attr.aria-label]=\"t().uiScrollDown\"\n (click)=\"onScrollHintClick($event)\"\n (keydown.enter)=\"onScrollHintClick($event)\" />\n </div>\n }\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-scroll-area.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/scroll-area/rt-scroll-area.directives.ts","../../../projects/ui-kit-v2/src/lib/components/scroll-area/rt-scroll-area.component.ts","../../../projects/ui-kit-v2/src/lib/components/scroll-area/rt-scroll-area.component.html","../../../projects/ui-kit-v2/src/lib/components/scroll-area/rt-tools-ui-kit-v2-scroll-area.ts"],"sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\n\n/**\n * Маркеры частей области прокрутки — своим файлом, как у соседних семей.\n *\n * Каждый маркер держит свой шаблон и не знает об области ничего: область читает маркеры среди\n * своего содержимого и берёт у них шаблон. Часть, которую потребитель не объявил, для области\n * просто отсутствует — рисовать нечего.\n */\n\n/**\n * Шапка области: стоит сверху и не прокручивается.\n *\n * @example\n * ```html\n * <rt-scroll-area>\n * <ng-container *rtScrollAreaHeader>\n * <h3>Заголовок</h3>\n * </ng-container>\n * </rt-scroll-area>\n * ```\n */\n@Directive({\n selector: '[rtScrollAreaHeader]',\n})\nexport class RtScrollAreaHeaderDirective {\n public readonly templateRef: TemplateRef<void> = inject<TemplateRef<void>>(TemplateRef);\n}\n\n/** Тело области: единственная часть, которая прокручивается. */\n@Directive({\n selector: '[rtScrollAreaContent]',\n})\nexport class RtScrollAreaContentDirective {\n public readonly templateRef: TemplateRef<void> = inject<TemplateRef<void>>(TemplateRef);\n}\n\n/** Подвал области: стоит снизу и не прокручивается. */\n@Directive({\n selector: '[rtScrollAreaFooter]',\n})\nexport class RtScrollAreaFooterDirective {\n public readonly templateRef: TemplateRef<void> = inject<TemplateRef<void>>(TemplateRef);\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n afterRenderEffect,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n contentChild,\n DestroyRef,\n ElementRef,\n inject,\n input,\n InputSignalWithTransform,\n signal,\n Signal,\n viewChild,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\nimport { TNullable } from '@rt-tools/utils';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { RtScrollAreaContentDirective, RtScrollAreaFooterDirective, RtScrollAreaHeaderDirective } from './rt-scroll-area.directives';\n\nconst BEM_BLOCK: string = 'rt-scroll-area';\n\n/**\n * Целый пункт запаса при сравнении прокрутки с высотой.\n *\n * Дробная высота строки оставляет остаток, при котором прокрутка уже в самом низу, а разность\n * всё ещё больше нуля: без запаса признак непоказанного висел бы навсегда.\n */\nconst BOTTOM_SLACK_PX: number = 1;\n\n/**\n * Область прокрутки: шапка и подвал стоят, тело прокручивается.\n *\n * Части объявляет потребитель — по директиве на каждую. Необъявленная часть не рисуется вовсе:\n * пустая шапка это полоса отступа над списком, а высоту она забирает у тела, ради которого\n * область и открыли.\n *\n * Договорённость — `docs/specs/ui-kit-v2/scroll-area/`.\n */\n@Component({\n selector: 'rt-scroll-area',\n templateUrl: './rt-scroll-area.component.html',\n styleUrls: ['./rt-scroll-area.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n NgTemplateOutlet,\n\n // standalone components / directives\n RtIconComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ],\n host: { class: BEM_BLOCK },\n})\nexport class RtScrollAreaComponent {\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly bodyRef: Signal<TNullable<ElementRef<HTMLElement>>> = viewChild<ElementRef<HTMLElement>>('body');\n protected readonly footerRef: Signal<TNullable<ElementRef<HTMLElement>>> = viewChild<ElementRef<HTMLElement>>('foot');\n\n /**\n * Ниже окна области ещё есть содержимое. Считается по трём числам самого узла, а не по числу\n * пунктов: область не знает, что ей подали, и высота строки у каждого потребителя своя.\n */\n protected readonly hasMoreBelow: WritableSignal<boolean> = signal(false);\n\n /**\n * На сколько полоса растушёвки поднята над низом области. Она обязана кончиться там, где\n * начинается содержимое подвала: разделитель потребитель рисует первой его строкой, и полоса,\n * оборвавшаяся выше, оставляет до него чистый фон. Считается замером — верхний отступ подвала\n * потребитель пишет как хочет, и вычесть его в стилях не из чего. Без подвала полоса стоит у\n * самого низа.\n */\n protected readonly hintBottom: WritableSignal<number> = signal(0);\n\n public readonly headerTpl: Signal<TNullable<RtScrollAreaHeaderDirective>> = contentChild(RtScrollAreaHeaderDirective);\n public readonly contentTpl: Signal<TNullable<RtScrollAreaContentDirective>> = contentChild(RtScrollAreaContentDirective);\n public readonly footerTpl: Signal<TNullable<RtScrollAreaFooterDirective>> = contentChild(RtScrollAreaFooterDirective);\n\n /**\n * Признак того, что снизу осталось непоказанное. Выключен по умолчанию: область рисуют\n * десятки экранов, и признак, поставленный безусловно, сдвинул бы вид каждому из них.\n */\n public readonly isScrollHintShown: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n /**\n * Наблюдатель за размером тела, его содержимого и подвала. Событие прокрутки приходит только\n * после движения руки, а список не влезает уже в первую минуту показа: без наблюдателя признак\n * появлялся бы у того, кто и так догадался прокрутить, и молчал у того, кому он нужен.\n */\n #sizeWatch: TNullable<ResizeObserver> = null;\n\n /**\n * Наблюдатель за составом тела. Тело — окно постоянной высоты, и когда список дорастает под ним,\n * размер тела не меняется: наблюдатель размера молчит. Пришедшие узлы ставятся под наблюдение\n * размера здесь же — их высота меняется и после того, как они легли.\n */\n #contentWatch: TNullable<MutationObserver> = null;\n\n /** Узлы, за которыми наблюдают сейчас: пересозданное тело или подвал ставятся под наблюдение заново. */\n #watchedBody: HTMLElement | null = null;\n #watchedFooter: HTMLElement | null = null;\n\n /** Наблюдение поставлено: тело и подвал могут быть и пустыми, флаг отличает «снято» от «нечего смотреть». */\n #isWatching: boolean = false;\n\n /** Перемер по концу перехода или анимации внутри тела; одна ссылка — чтобы снять тот же слушатель. */\n readonly #onSettled: () => void = (): void => this.onBodyScroll();\n\n constructor() {\n // Наблюдатели живут, только пока признак включён: выключенный признак ничего не рисует, а\n // наблюдатель состава с поддеревом заставлял бы браузер пересчитывать раскладку на каждую\n // правку внутри тела у каждой области экрана. Включение ставит их, выключение снимает.\n afterRenderEffect((): void => {\n const body: HTMLElement | null = this.bodyRef()?.nativeElement ?? null;\n const footer: HTMLElement | null = this.footerRef()?.nativeElement ?? null;\n\n if (!this.isScrollHintShown()) {\n this.#unwatch();\n this.hasMoreBelow.set(false);\n\n return;\n }\n\n this.onBodyScroll();\n\n if (!this.#isWatching || body !== this.#watchedBody || footer !== this.#watchedFooter) {\n this.#watch(body, footer);\n }\n });\n\n this.#destroyRef.onDestroy((): void => this.#unwatch());\n }\n\n /**\n * Нажатие на значок уводит тело к самому низу. Нажатие останавливается здесь и в содержимое\n * под значком не уходит: под ним живой пункт, и человек, целившийся в подсказку, уехал бы на\n * чужой экран.\n */\n public onScrollHintClick(event: Event): void {\n event.preventDefault();\n event.stopPropagation();\n\n const body: TNullable<ElementRef<HTMLElement>> = this.bodyRef();\n\n if (!body) {\n return;\n }\n\n body.nativeElement.scrollTo({ top: body.nativeElement.scrollHeight, behavior: 'smooth' });\n }\n\n public onBodyScroll(): void {\n // Выключенный признак не рисуется, и замер для него — чтение раскладки на каждое движение.\n if (!this.isScrollHintShown()) {\n return;\n }\n\n this.#measureHintBottom();\n\n const body: TNullable<ElementRef<HTMLElement>> = this.bodyRef();\n\n if (!body) {\n this.hasMoreBelow.set(false);\n\n return;\n }\n\n const node: HTMLElement = body.nativeElement;\n\n this.hasMoreBelow.set(node.scrollHeight - node.scrollTop - node.clientHeight > BOTTOM_SLACK_PX);\n }\n\n /**\n * Подъём полосы над низом области: высота подвала без его верхнего отступа. Ровно на этом\n * месте начинается содержимое подвала, и до него полоса и должна доходить.\n */\n #measureHintBottom(): void {\n const footer: TNullable<ElementRef<HTMLElement>> = this.footerRef();\n\n if (!footer) {\n this.hintBottom.set(0);\n\n return;\n }\n\n const node: HTMLElement = footer.nativeElement;\n const paddingTop: number = parseFloat(getComputedStyle(node).paddingTop) || 0;\n\n this.hintBottom.set(Math.max(node.offsetHeight - paddingTop, 0));\n }\n\n /** Ставит под наблюдение нынешние тело и подвал; прежние наблюдатели снимаются. */\n #watch(body: HTMLElement | null, footer: HTMLElement | null): void {\n this.#unwatch();\n this.#watchedBody = body;\n this.#watchedFooter = footer;\n this.#isWatching = true;\n\n if (!body) {\n return;\n }\n\n if (typeof ResizeObserver !== 'undefined') {\n this.#sizeWatch = new ResizeObserver((): void => this.onBodyScroll());\n this.#observeSizes();\n }\n\n if (typeof MutationObserver !== 'undefined') {\n this.#contentWatch = new MutationObserver((): void => {\n this.#observeSizes();\n this.onBodyScroll();\n });\n this.#contentWatch.observe(body, { childList: true, subtree: true, characterData: true });\n }\n\n // Раскрытая папка дорастает переходом высоты от нуля: состав меняется в миг вставки, когда\n // высота ещё ноль, а наблюдатель размера пропускал конец роста. Конец перехода и анимации\n // всплывает к телу и перемеряет его по вставшей высоте.\n body.addEventListener('transitionend', this.#onSettled);\n body.addEventListener('animationend', this.#onSettled);\n }\n\n /**\n * Размер наблюдается у тела, у каждого его прямого потомка и у подвала. Подвал — наравне с\n * телом: от его высоты считается подъём полосы, и не наблюдавшаяся, она осталась бы стоять по\n * прежней высоте подвала и наехала бы на его первую строку.\n */\n #observeSizes(): void {\n const watch: TNullable<ResizeObserver> = this.#sizeWatch;\n const body: HTMLElement | null = this.#watchedBody;\n\n if (!watch || !body) {\n return;\n }\n\n // Состав тела сменился — ушедшие узлы снимаются вместе со всеми, пришедшие ставятся заново.\n watch.disconnect();\n watch.observe(body);\n Array.from(body.children).forEach((child: Element): void => watch.observe(child));\n\n if (this.#watchedFooter) {\n watch.observe(this.#watchedFooter);\n }\n }\n\n #unwatch(): void {\n this.#watchedBody?.removeEventListener('transitionend', this.#onSettled);\n this.#watchedBody?.removeEventListener('animationend', this.#onSettled);\n this.#sizeWatch?.disconnect();\n this.#sizeWatch = null;\n this.#contentWatch?.disconnect();\n this.#contentWatch = null;\n this.#watchedBody = null;\n this.#watchedFooter = null;\n this.#isWatching = false;\n }\n}\n","<ng-container rtBlock=\"rt-scroll-area\">\n @if (headerTpl()) {\n <div rtElem=\"header\" qa-dataid=\"scroll-area-header\">\n <ng-container [ngTemplateOutlet]=\"headerTpl()?.templateRef ?? null\" />\n </div>\n }\n\n @if (contentTpl()) {\n <div #body rtElem=\"body\" qa-dataid=\"scroll-area-body\" (scroll)=\"onBodyScroll()\">\n <ng-container [ngTemplateOutlet]=\"contentTpl()?.templateRef ?? null\" />\n </div>\n }\n\n @if (footerTpl()) {\n <div #foot rtElem=\"footer\" qa-dataid=\"scroll-area-footer\">\n <ng-container [ngTemplateOutlet]=\"footerTpl()?.templateRef ?? null\" />\n </div>\n }\n\n <!--\n Признак того, что снизу осталось непоказанное: край списка, ровно обрезанный подвалом,\n читается как конец списка, и человек считает, что пункт пропал. Полоса живёт на хосте, а\n не внутри тела: тело обрезает всё по своему краю, и полоса обрывалась бы на верхнем\n отступе подвала — между ней и разделителем, который потребитель рисует первой строкой\n подвала, оставалась бы полоса чистого фона.\n -->\n @if (isScrollHintShown() && hasMoreBelow()) {\n <div rtElem=\"scroll-hint\" qa-dataid=\"scroll-area-scroll-hint\" [style.bottom.px]=\"hintBottom()\">\n <rt-icon\n rtElem=\"scroll-hint-icon\"\n qa-dataid=\"scroll-area-scroll-hint-icon\"\n name=\"chevron-down\"\n size=\"md\"\n role=\"button\"\n tabindex=\"0\"\n rtTooltipPlacement=\"top\"\n [rtTooltip]=\"t().uiScrollDown\"\n [attr.aria-label]=\"t().uiScrollDown\"\n (click)=\"onScrollHintClick($event)\"\n (keydown.enter)=\"onScrollHintClick($event)\" />\n </div>\n }\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}