@raqm/ui 0.0.0-stage → 0.1.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 (178) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/LICENSE +21 -0
  3. package/NOTICE.md +28 -0
  4. package/README.md +126 -3
  5. package/combobox/README.md +17 -0
  6. package/fesm2022/raqm-ui-accordion.mjs +414 -0
  7. package/fesm2022/raqm-ui-accordion.mjs.map +1 -0
  8. package/fesm2022/raqm-ui-alert-dialog.mjs +457 -0
  9. package/fesm2022/raqm-ui-alert-dialog.mjs.map +1 -0
  10. package/fesm2022/raqm-ui-alert.mjs +195 -0
  11. package/fesm2022/raqm-ui-alert.mjs.map +1 -0
  12. package/fesm2022/raqm-ui-aspect-ratio.mjs +66 -0
  13. package/fesm2022/raqm-ui-aspect-ratio.mjs.map +1 -0
  14. package/fesm2022/raqm-ui-attachment.mjs +435 -0
  15. package/fesm2022/raqm-ui-attachment.mjs.map +1 -0
  16. package/fesm2022/raqm-ui-avatar.mjs +337 -0
  17. package/fesm2022/raqm-ui-avatar.mjs.map +1 -0
  18. package/fesm2022/raqm-ui-badge.mjs +68 -0
  19. package/fesm2022/raqm-ui-badge.mjs.map +1 -0
  20. package/fesm2022/raqm-ui-breadcrumb.mjs +309 -0
  21. package/fesm2022/raqm-ui-breadcrumb.mjs.map +1 -0
  22. package/fesm2022/raqm-ui-button-group.mjs +138 -0
  23. package/fesm2022/raqm-ui-button-group.mjs.map +1 -0
  24. package/fesm2022/raqm-ui-button.mjs +295 -0
  25. package/fesm2022/raqm-ui-button.mjs.map +1 -0
  26. package/fesm2022/raqm-ui-calendar.mjs +1394 -0
  27. package/fesm2022/raqm-ui-calendar.mjs.map +1 -0
  28. package/fesm2022/raqm-ui-card.mjs +331 -0
  29. package/fesm2022/raqm-ui-card.mjs.map +1 -0
  30. package/fesm2022/raqm-ui-carousel.mjs +410 -0
  31. package/fesm2022/raqm-ui-carousel.mjs.map +1 -0
  32. package/fesm2022/raqm-ui-checkbox.mjs +86 -0
  33. package/fesm2022/raqm-ui-checkbox.mjs.map +1 -0
  34. package/fesm2022/raqm-ui-collapsible.mjs +266 -0
  35. package/fesm2022/raqm-ui-collapsible.mjs.map +1 -0
  36. package/fesm2022/raqm-ui-combobox.mjs +1584 -0
  37. package/fesm2022/raqm-ui-combobox.mjs.map +1 -0
  38. package/fesm2022/raqm-ui-command.mjs +1210 -0
  39. package/fesm2022/raqm-ui-command.mjs.map +1 -0
  40. package/fesm2022/raqm-ui-context-menu.mjs +723 -0
  41. package/fesm2022/raqm-ui-context-menu.mjs.map +1 -0
  42. package/fesm2022/raqm-ui-dialog.mjs +1214 -0
  43. package/fesm2022/raqm-ui-dialog.mjs.map +1 -0
  44. package/fesm2022/raqm-ui-drawer.mjs +687 -0
  45. package/fesm2022/raqm-ui-drawer.mjs.map +1 -0
  46. package/fesm2022/raqm-ui-dropdown-menu.mjs +1168 -0
  47. package/fesm2022/raqm-ui-dropdown-menu.mjs.map +1 -0
  48. package/fesm2022/raqm-ui-empty.mjs +272 -0
  49. package/fesm2022/raqm-ui-empty.mjs.map +1 -0
  50. package/fesm2022/raqm-ui-field.mjs +517 -0
  51. package/fesm2022/raqm-ui-field.mjs.map +1 -0
  52. package/fesm2022/raqm-ui-hover-card.mjs +828 -0
  53. package/fesm2022/raqm-ui-hover-card.mjs.map +1 -0
  54. package/fesm2022/raqm-ui-input-group.mjs +270 -0
  55. package/fesm2022/raqm-ui-input-group.mjs.map +1 -0
  56. package/fesm2022/raqm-ui-input-otp.mjs +788 -0
  57. package/fesm2022/raqm-ui-input-otp.mjs.map +1 -0
  58. package/fesm2022/raqm-ui-input.mjs +73 -0
  59. package/fesm2022/raqm-ui-input.mjs.map +1 -0
  60. package/fesm2022/raqm-ui-item.mjs +495 -0
  61. package/fesm2022/raqm-ui-item.mjs.map +1 -0
  62. package/fesm2022/raqm-ui-kbd.mjs +80 -0
  63. package/fesm2022/raqm-ui-kbd.mjs.map +1 -0
  64. package/fesm2022/raqm-ui-label.mjs +44 -0
  65. package/fesm2022/raqm-ui-label.mjs.map +1 -0
  66. package/fesm2022/raqm-ui-menubar.mjs +536 -0
  67. package/fesm2022/raqm-ui-menubar.mjs.map +1 -0
  68. package/fesm2022/raqm-ui-native-select.mjs +131 -0
  69. package/fesm2022/raqm-ui-native-select.mjs.map +1 -0
  70. package/fesm2022/raqm-ui-navigation-menu.mjs +1399 -0
  71. package/fesm2022/raqm-ui-navigation-menu.mjs.map +1 -0
  72. package/fesm2022/raqm-ui-overlay-internal.mjs +185 -0
  73. package/fesm2022/raqm-ui-overlay-internal.mjs.map +1 -0
  74. package/fesm2022/raqm-ui-pagination.mjs +440 -0
  75. package/fesm2022/raqm-ui-pagination.mjs.map +1 -0
  76. package/fesm2022/raqm-ui-popover.mjs +1495 -0
  77. package/fesm2022/raqm-ui-popover.mjs.map +1 -0
  78. package/fesm2022/raqm-ui-progress.mjs +369 -0
  79. package/fesm2022/raqm-ui-progress.mjs.map +1 -0
  80. package/fesm2022/raqm-ui-questionnaire.mjs +1005 -0
  81. package/fesm2022/raqm-ui-questionnaire.mjs.map +1 -0
  82. package/fesm2022/raqm-ui-radio-group.mjs +151 -0
  83. package/fesm2022/raqm-ui-radio-group.mjs.map +1 -0
  84. package/fesm2022/raqm-ui-resizable.mjs +439 -0
  85. package/fesm2022/raqm-ui-resizable.mjs.map +1 -0
  86. package/fesm2022/raqm-ui-scroll-area.mjs +510 -0
  87. package/fesm2022/raqm-ui-scroll-area.mjs.map +1 -0
  88. package/fesm2022/raqm-ui-select.mjs +1073 -0
  89. package/fesm2022/raqm-ui-select.mjs.map +1 -0
  90. package/fesm2022/raqm-ui-separator.mjs +103 -0
  91. package/fesm2022/raqm-ui-separator.mjs.map +1 -0
  92. package/fesm2022/raqm-ui-sheet.mjs +411 -0
  93. package/fesm2022/raqm-ui-sheet.mjs.map +1 -0
  94. package/fesm2022/raqm-ui-sidebar.mjs +1784 -0
  95. package/fesm2022/raqm-ui-sidebar.mjs.map +1 -0
  96. package/fesm2022/raqm-ui-skeleton.mjs +50 -0
  97. package/fesm2022/raqm-ui-skeleton.mjs.map +1 -0
  98. package/fesm2022/raqm-ui-slider.mjs +609 -0
  99. package/fesm2022/raqm-ui-slider.mjs.map +1 -0
  100. package/fesm2022/raqm-ui-spinner.mjs +137 -0
  101. package/fesm2022/raqm-ui-spinner.mjs.map +1 -0
  102. package/fesm2022/raqm-ui-switch.mjs +109 -0
  103. package/fesm2022/raqm-ui-switch.mjs.map +1 -0
  104. package/fesm2022/raqm-ui-table.mjs +271 -0
  105. package/fesm2022/raqm-ui-table.mjs.map +1 -0
  106. package/fesm2022/raqm-ui-tabs.mjs +536 -0
  107. package/fesm2022/raqm-ui-tabs.mjs.map +1 -0
  108. package/fesm2022/raqm-ui-textarea.mjs +37 -0
  109. package/fesm2022/raqm-ui-textarea.mjs.map +1 -0
  110. package/fesm2022/raqm-ui-toast.mjs +918 -0
  111. package/fesm2022/raqm-ui-toast.mjs.map +1 -0
  112. package/fesm2022/raqm-ui-toggle-group.mjs +462 -0
  113. package/fesm2022/raqm-ui-toggle-group.mjs.map +1 -0
  114. package/fesm2022/raqm-ui-toggle.mjs +158 -0
  115. package/fesm2022/raqm-ui-toggle.mjs.map +1 -0
  116. package/fesm2022/raqm-ui-tooltip.mjs +1226 -0
  117. package/fesm2022/raqm-ui-tooltip.mjs.map +1 -0
  118. package/fesm2022/raqm-ui.mjs +50 -0
  119. package/input-otp/README.md +12 -0
  120. package/package.json +275 -3
  121. package/styles/theme.css +4324 -0
  122. package/types/raqm-ui-accordion.d.ts +124 -0
  123. package/types/raqm-ui-alert-dialog.d.ts +81 -0
  124. package/types/raqm-ui-alert.d.ts +29 -0
  125. package/types/raqm-ui-aspect-ratio.d.ts +13 -0
  126. package/types/raqm-ui-attachment.d.ts +72 -0
  127. package/types/raqm-ui-avatar.d.ts +67 -0
  128. package/types/raqm-ui-badge.d.ts +20 -0
  129. package/types/raqm-ui-breadcrumb.d.ts +35 -0
  130. package/types/raqm-ui-button-group.d.ts +27 -0
  131. package/types/raqm-ui-button.d.ts +80 -0
  132. package/types/raqm-ui-calendar.d.ts +359 -0
  133. package/types/raqm-ui-card.d.ts +34 -0
  134. package/types/raqm-ui-carousel.d.ts +81 -0
  135. package/types/raqm-ui-checkbox.d.ts +24 -0
  136. package/types/raqm-ui-collapsible.d.ts +72 -0
  137. package/types/raqm-ui-combobox.d.ts +405 -0
  138. package/types/raqm-ui-command.d.ts +256 -0
  139. package/types/raqm-ui-context-menu.d.ts +196 -0
  140. package/types/raqm-ui-dialog.d.ts +232 -0
  141. package/types/raqm-ui-drawer.d.ts +121 -0
  142. package/types/raqm-ui-dropdown-menu.d.ts +319 -0
  143. package/types/raqm-ui-empty.d.ts +35 -0
  144. package/types/raqm-ui-field.d.ts +88 -0
  145. package/types/raqm-ui-hover-card.d.ts +139 -0
  146. package/types/raqm-ui-input-group.d.ts +45 -0
  147. package/types/raqm-ui-input-otp.d.ts +197 -0
  148. package/types/raqm-ui-input.d.ts +16 -0
  149. package/types/raqm-ui-item.d.ts +71 -0
  150. package/types/raqm-ui-kbd.d.ts +12 -0
  151. package/types/raqm-ui-label.d.ts +6 -0
  152. package/types/raqm-ui-menubar.d.ts +159 -0
  153. package/types/raqm-ui-native-select.d.ts +23 -0
  154. package/types/raqm-ui-navigation-menu.d.ts +230 -0
  155. package/types/raqm-ui-overlay-internal.d.ts +5 -0
  156. package/types/raqm-ui-pagination.d.ts +84 -0
  157. package/types/raqm-ui-popover.d.ts +235 -0
  158. package/types/raqm-ui-progress.d.ts +79 -0
  159. package/types/raqm-ui-questionnaire.d.ts +217 -0
  160. package/types/raqm-ui-radio-group.d.ts +48 -0
  161. package/types/raqm-ui-resizable.d.ts +98 -0
  162. package/types/raqm-ui-scroll-area.d.ts +132 -0
  163. package/types/raqm-ui-select.d.ts +205 -0
  164. package/types/raqm-ui-separator.d.ts +21 -0
  165. package/types/raqm-ui-sheet.d.ts +79 -0
  166. package/types/raqm-ui-sidebar.d.ts +285 -0
  167. package/types/raqm-ui-skeleton.d.ts +6 -0
  168. package/types/raqm-ui-slider.d.ts +129 -0
  169. package/types/raqm-ui-spinner.d.ts +32 -0
  170. package/types/raqm-ui-switch.d.ts +32 -0
  171. package/types/raqm-ui-table.d.ts +36 -0
  172. package/types/raqm-ui-tabs.d.ts +154 -0
  173. package/types/raqm-ui-textarea.d.ts +6 -0
  174. package/types/raqm-ui-toast.d.ts +190 -0
  175. package/types/raqm-ui-toggle-group.d.ts +167 -0
  176. package/types/raqm-ui-toggle.d.ts +42 -0
  177. package/types/raqm-ui-tooltip.d.ts +207 -0
  178. package/types/raqm-ui.d.ts +50 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raqm-ui-select.mjs","names":[],"sources":["../../../projects/ui/select/select-model.ts","../../../projects/ui/select/select-control.ts","../../../projects/ui/select/select-effects.ts","../../../projects/ui/select/select-keyboard.ts","../../../projects/ui/select/select-overlay.ts","../../../projects/ui/select/select-position.ts","../../../projects/ui/select/select-scrolling.ts","../../../projects/ui/select/select-view-state.ts","../../../projects/ui/select/select.ts","../../../projects/ui/select/select.html"],"sourcesContent":["// Select model: the popup constants, the render shapes and the small pure helpers every\r\n// select file reads.\r\n\r\nimport { Highlightable } from '@angular/cdk/a11y';\r\nimport { Directionality } from '@angular/cdk/bidi';\r\n\r\nimport { RaqmSelectEntry, RaqmSelectGroup, RaqmSelectOption } from './select.types';\r\n\r\nexport const OVERLAY_GAP = 4;\r\n\r\n// Minimum distance kept from every viewport edge, in CSS pixels; also the CDK `withViewportMargin`.\r\nexport const VIEWPORT_MARGIN = 10;\r\n\r\n// Available-height inset around the anchor; the popup shrinks as the trigger nears a viewport edge.\r\nexport const ANCHOR_CLEARANCE = 9;\r\n\r\nexport const SCROLL_STEP = 120;\r\n\r\n// Pointer-rest cadence: one whole row per 40ms, plus the edge tolerance for range-end snapping.\r\nexport const AUTO_SCROLL_INTERVAL_MS = 40;\r\nexport const SCROLL_EDGE_TOLERANCE_PX = 1;\r\n\r\nexport interface RaqmSelectOptionView {\r\n readonly option: RaqmSelectOption;\r\n readonly id: string;\r\n readonly index: number;\r\n}\r\n\r\nexport interface RaqmSelectChunkView {\r\n readonly key: string;\r\n readonly label: string | null;\r\n readonly labelId: string | null;\r\n readonly separatorBefore: boolean;\r\n readonly options: RaqmSelectOptionView[];\r\n}\r\n\r\n// A `RaqmSelectEntry` is a group when it carries an `options` array.\r\nexport function isSelectGroup(entry: RaqmSelectEntry): entry is RaqmSelectGroup {\r\n return Array.isArray((entry as RaqmSelectGroup).options);\r\n}\r\n\r\n// Normalises any value a Forms directive may write into the string-or-null model.\r\nexport function normalizeValue(value: unknown): string | null {\r\n return typeof value === 'string' ? value : null;\r\n}\r\n\r\n// Direction precedence: explicit `dir`, computed style, then the injected CDK value.\r\nexport function resolveSelectDirection(\r\n dir: 'ltr' | 'rtl' | undefined,\r\n element: HTMLElement,\r\n directionality: Directionality | null,\r\n): 'ltr' | 'rtl' {\r\n const explicit = dir;\r\n if (explicit === 'ltr' || explicit === 'rtl') {\r\n return explicit;\r\n }\r\n const computed = getComputedStyle(element).direction;\r\n if (computed === 'rtl') {\r\n return 'rtl';\r\n }\r\n return directionality?.value ?? 'ltr';\r\n}\r\n\r\n// Key-manager wrapper: the active row is tracked as an id, never written to the DOM.\r\nexport class RaqmSelectOptionRef implements Highlightable {\r\n constructor(\r\n readonly view: RaqmSelectOptionView,\r\n private readonly activate: (ref: RaqmSelectOptionRef) => void,\r\n ) {}\r\n\r\n get disabled(): boolean {\r\n return this.view.option.disabled === true;\r\n }\r\n\r\n // Typeahead matches the option's label, never its icon.\r\n getLabel(): string {\r\n return this.view.option.label;\r\n }\r\n\r\n setActiveStyles(): void {\r\n this.activate(this);\r\n }\r\n\r\n setInactiveStyles(): void {}\r\n}\r\n","// Select Forms and selection: the value accessor, the single commit path and the\r\n// development-only duplicate-value report.\r\n\r\nimport { isDevMode } from '@angular/core';\r\n\r\nimport { normalizeValue, RaqmSelectOptionView } from './select-model';\r\nimport { RaqmSelectOption } from './select.types';\r\n\r\nexport interface RaqmSelectControlHost {\r\n effectiveDisabled(): boolean;\r\n selected(): string | null;\r\n setSelected(value: string | null): void;\r\n emit(value: string | null): void;\r\n close(touched: boolean): void;\r\n setCvaDisabled(value: boolean): void;\r\n optionViews(): readonly RaqmSelectOptionView[];\r\n}\r\n\r\nexport class RaqmSelectControl {\r\n private onChange: ((value: string | null) => void) | undefined;\r\n private onTouched: (() => void) | undefined;\r\n\r\n constructor(private readonly host: RaqmSelectControlHost) {}\r\n\r\n /** Writes an external value without emitting or marking touched; non-strings become `null`. */\r\n writeValue(value: unknown): void {\r\n this.host.setSelected(normalizeValue(value));\r\n }\r\n\r\n registerOnChange(fn: (value: string | null) => void): void {\r\n this.onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n /** ORs a Forms disabled state with the explicit input and closes the popup. */\r\n setDisabledState(isDisabled: boolean): void {\r\n this.host.setCvaDisabled(isDisabled);\r\n if (isDisabled) {\r\n this.host.close(false);\r\n }\r\n }\r\n\r\n onOptionClick(option: RaqmSelectOption): void {\r\n if (option.disabled === true) {\r\n return;\r\n }\r\n this.commitSelection(option.value);\r\n }\r\n\r\n // The single selection path for pointer and keyboard; the same value emits nothing.\r\n commitSelection(value: string | null): void {\r\n if (this.host.effectiveDisabled()) {\r\n return;\r\n }\r\n if (this.host.selected() === value) {\r\n this.host.close(true);\r\n return;\r\n }\r\n this.host.setSelected(value);\r\n this.onChange?.(value);\r\n this.host.emit(value);\r\n this.host.close(true);\r\n }\r\n\r\n markTouched(): void {\r\n this.onTouched?.();\r\n }\r\n\r\n // Duplicate option values (including duplicate `null`) are reported in development.\r\n reportDuplicateValues(): void {\r\n if (!isDevMode()) {\r\n return;\r\n }\r\n const seen = new Set<string | null>();\r\n const duplicates = new Set<string | null>();\r\n for (const view of this.host.optionViews()) {\r\n const value = view.option.value;\r\n if (seen.has(value)) {\r\n duplicates.add(value);\r\n } else {\r\n seen.add(value);\r\n }\r\n }\r\n if (duplicates.size > 0) {\r\n console.error(\r\n `[raqm-select] Duplicate option value(s) ${[...duplicates]\r\n .map((value) => JSON.stringify(value))\r\n .join(', ')}; Select option values must be unique.`,\r\n );\r\n }\r\n }\r\n}\r\n","// Select effects: the duplicate-value guard, the in-place alignment re-apply and the\r\n// disabled-while-open close, registered from the component constructor.\r\n\r\nimport { effect, untracked } from '@angular/core';\r\n\r\nexport interface RaqmSelectEffectsHost {\r\n reportDuplicateValues(): void;\r\n reactToAlignmentChange(): void;\r\n effectiveDisabled(): boolean;\r\n open(): boolean;\r\n close(touched: boolean): void;\r\n}\r\n\r\nexport function connectSelectEffects(host: RaqmSelectEffectsHost): void {\r\n // Development-only duplicate-value guard, re-run when the items change.\r\n effect(() => host.reportDuplicateValues());\r\n\r\n // Re-applies alignment in place when the mode input changes while open.\r\n effect(() => host.reactToAlignmentChange());\r\n\r\n // A control disabled while open is closed, so trigger and popup can never disagree.\r\n effect(() => {\r\n if (host.effectiveDisabled() && host.open()) {\r\n untracked(() => host.close(false));\r\n }\r\n });\r\n}\r\n","// Select keyboard and pointer: the key manager, the trigger key map, hover routing and\r\n// the initial active row.\r\n\r\nimport { Injector, Signal } from '@angular/core';\r\n\r\nimport { ActiveDescendantKeyManager } from '@angular/cdk/a11y';\r\nimport { OverlayRef } from '@angular/cdk/overlay';\r\n\r\nimport { RaqmSelectOptionRef, RaqmSelectOptionView } from './select-model';\r\n\r\nexport interface RaqmSelectKeyboardHost {\r\n optionRefs(): Signal<RaqmSelectOptionRef[]>;\r\n optionViews(): readonly RaqmSelectOptionView[];\r\n selected(): string | null;\r\n activeId(): string | null;\r\n open(): boolean;\r\n element(): HTMLElement;\r\n overlayRef(): OverlayRef | undefined;\r\n openPopup(): void;\r\n close(touched: boolean): void;\r\n markTouched(): void;\r\n commitSelection(value: string | null): void;\r\n setActiveId(id: string | null): void;\r\n}\r\n\r\nexport class RaqmSelectKeyboard {\r\n // Optional: `init` builds it once `items` is bound.\r\n private keyManager: ActiveDescendantKeyManager<RaqmSelectOptionRef> | undefined;\r\n\r\n constructor(\r\n private readonly injector: Injector,\r\n private readonly host: RaqmSelectKeyboardHost,\r\n ) {}\r\n\r\n /**\r\n * Creates the key manager once `items` is bound.\r\n *\r\n * Building it in the constructor would read the required `items` input before Angular binds it\r\n * (`NG0950`).\r\n */\r\n init(): void {\r\n this.keyManager = new ActiveDescendantKeyManager<RaqmSelectOptionRef>(\r\n this.host.optionRefs(),\r\n this.injector,\r\n )\r\n .withWrap(false)\r\n .withVerticalOrientation(true)\r\n .withHomeAndEnd(true)\r\n .withTypeAhead();\r\n }\r\n\r\n destroy(): void {\r\n this.keyManager?.destroy();\r\n }\r\n\r\n /** Handles every trigger key, open or closed. */\r\n onTriggerKeydown(event: KeyboardEvent): void {\r\n if (!this.host.open()) {\r\n if (\r\n event.key === 'ArrowDown' ||\r\n event.key === 'ArrowUp' ||\r\n event.key === 'Enter' ||\r\n event.key === ' '\r\n ) {\r\n event.preventDefault();\r\n this.host.openPopup();\r\n }\r\n return;\r\n }\r\n\r\n switch (event.key) {\r\n case 'Escape':\r\n // Escape closes without committing.\r\n event.preventDefault();\r\n this.host.close(true);\r\n return;\r\n case 'Tab':\r\n // Tab closes and lets focus continue; there is no focus trap.\r\n this.host.close(true);\r\n return;\r\n case 'Enter':\r\n case ' ':\r\n event.preventDefault();\r\n this.commitActiveOption();\r\n return;\r\n default:\r\n this.keyManager?.onKeydown(event);\r\n }\r\n }\r\n\r\n /** Marks the control touched when focus leaves the whole composite. */\r\n onTriggerBlur(event: FocusEvent): void {\r\n const next = event.relatedTarget as Node | null;\r\n const overlayElement = this.host.overlayRef()?.overlayElement;\r\n if (next && (this.host.element().contains(next) || overlayElement?.contains(next) === true)) {\r\n return;\r\n }\r\n if (this.host.open()) {\r\n this.host.close(true);\r\n } else {\r\n this.host.markTouched();\r\n }\r\n }\r\n\r\n /** Routes hover through the key manager, so paint, `aria-activedescendant` and the active item agree. */\r\n onOptionPointerMove(view: RaqmSelectOptionView): void {\r\n if (view.option.disabled === true) {\r\n return;\r\n }\r\n if (this.host.activeId() === view.id) {\r\n return;\r\n }\r\n const index = this.host.optionViews().findIndex((candidate) => candidate.id === view.id);\r\n if (index === -1) {\r\n return;\r\n }\r\n this.keyManager?.setActiveItem(index);\r\n }\r\n\r\n /** Clears the active option on leaving the list, so the next ArrowDown restarts at the top. */\r\n onOptionPointerLeave(event: PointerEvent): void {\r\n if (event.pointerType === 'touch') {\r\n return;\r\n }\r\n const related = event.relatedTarget;\r\n if (related instanceof Element && related.closest('.raqm-select-option')) {\r\n return;\r\n }\r\n this.resetActive();\r\n }\r\n\r\n /** Clears the key manager's item and `activeId` together; an absent `aria-activedescendant` is valid ARIA 1.2. */\r\n resetActive(): void {\r\n this.keyManager?.setActiveItem(-1);\r\n this.host.setActiveId(null);\r\n }\r\n\r\n private commitActiveOption(): void {\r\n const active = this.keyManager?.activeItem;\r\n if (!active || active.disabled) {\r\n return;\r\n }\r\n this.host.commitSelection(active.view.option.value);\r\n }\r\n\r\n // The selected option when enabled, else the first enabled one; unset when nothing is enabled.\r\n setInitialActive(): void {\r\n const views = this.host.optionViews();\r\n if (views.length === 0) {\r\n return;\r\n }\r\n const selected = this.host.selected();\r\n let index = views.findIndex(\r\n (view) => view.option.value === selected && view.option.disabled !== true,\r\n );\r\n if (index === -1) {\r\n index = views.findIndex((view) => view.option.disabled !== true);\r\n }\r\n if (index === -1) {\r\n return;\r\n }\r\n this.keyManager?.setActiveItem(index);\r\n }\r\n}\r\n","// Select popup lifecycle: creation, the page-scroll lock, the detach paths and teardown.\r\n\r\nimport { TemplateRef, ViewContainerRef } from '@angular/core';\r\n\r\nimport { Overlay, OverlayConfig, OverlayRef, ScrollStrategy } from '@angular/cdk/overlay';\r\nimport { TemplatePortal } from '@angular/cdk/portal';\r\nimport { registerOverlayOwnership } from '@raqm/ui/overlay-internal';\r\n\r\nimport { RaqmSelectPosition } from './select-position';\r\nimport { RaqmSelectScrolling } from './select-scrolling';\r\n\r\nexport interface RaqmSelectOverlayHost {\r\n open(): boolean;\r\n effectiveDisabled(): boolean;\r\n trigger(): HTMLElement;\r\n popupTemplate(): TemplateRef<unknown>;\r\n direction(): 'ltr' | 'rtl';\r\n alignItemWithTrigger(): boolean;\r\n setOpen(value: boolean): void;\r\n setActiveId(id: string | null): void;\r\n setOverlayDir(dir: 'ltr' | 'rtl'): void;\r\n setInitialActive(): void;\r\n markTouched(): void;\r\n setCanScrollUp(value: boolean): void;\r\n setCanScrollDown(value: boolean): void;\r\n}\r\n\r\nexport class RaqmSelectOverlay {\r\n private overlayRef: OverlayRef | undefined;\r\n\r\n // CDK block scroll strategy while open, disabled on every teardown path so the lock cannot leak.\r\n private scrollStrategy?: ScrollStrategy;\r\n\r\n // Backdrop subscription, torn down on every close.\r\n private overlaySubscription: { unsubscribe(): void } | undefined;\r\n\r\n private overlayDetachSubscription: { unsubscribe(): void } | undefined;\r\n\r\n constructor(\r\n private readonly overlay: Overlay,\r\n private readonly viewContainerRef: ViewContainerRef,\r\n private readonly position: RaqmSelectPosition,\r\n private readonly scrolling: RaqmSelectScrolling,\r\n private readonly host: RaqmSelectOverlayHost,\r\n ) {}\r\n\r\n get ref(): OverlayRef | undefined {\r\n return this.overlayRef;\r\n }\r\n\r\n openPopup(): void {\r\n if (this.host.open() || this.host.effectiveDisabled()) {\r\n return;\r\n }\r\n\r\n this.position.resetDeactivation();\r\n\r\n const trigger = this.host.trigger();\r\n const direction = this.host.direction();\r\n this.host.setOverlayDir(direction);\r\n\r\n const aligned = this.host.alignItemWithTrigger();\r\n const strategy = this.overlay.position().flexibleConnectedTo(trigger);\r\n this.position.configureStrategy(strategy, aligned);\r\n\r\n const config: OverlayConfig = {\r\n positionStrategy: strategy,\r\n // Modal for the page: pins <html> and reserves the scrollbar, so opening shifts nothing.\r\n scrollStrategy: this.overlay.scrollStrategies.block(),\r\n hasBackdrop: true,\r\n backdropClass: 'cdk-overlay-transparent-backdrop',\r\n panelClass: 'raqm-select-overlay-pane',\r\n // A route change disposes the overlay rather than orphaning it.\r\n disposeOnNavigation: true,\r\n // Fixed to the trigger width; the 9rem floor lives in `.raqm-select-popup { min-inline-size }`.\r\n width: trigger.getBoundingClientRect().width,\r\n direction,\r\n };\r\n\r\n this.position.bind(strategy, aligned);\r\n this.scrollStrategy = config.scrollStrategy;\r\n this.overlayRef = this.overlay.create(config);\r\n registerOverlayOwnership(trigger, this.overlayRef);\r\n this.overlayRef.attach(new TemplatePortal(this.host.popupTemplate(), this.viewContainerRef));\r\n\r\n this.host.setOpen(true);\r\n this.host.setActiveId(null);\r\n if (aligned) {\r\n // Bound before setting and scrolling the active item, so the measure sees a stable popup.\r\n this.position.boundPopupHeight();\r\n }\r\n this.host.setInitialActive();\r\n this.scrolling.attach();\r\n this.scrolling.updateAffordances();\r\n if (aligned) {\r\n this.position.alignPopup();\r\n }\r\n\r\n this.overlaySubscription = this.overlayRef.backdropClick().subscribe(() => this.close(true));\r\n this.overlayDetachSubscription = this.overlayRef\r\n .detachments()\r\n .subscribe(() => this.handleOverlayDetached());\r\n }\r\n\r\n close(touched: boolean): void {\r\n this.destroyOverlay();\r\n if (touched) {\r\n this.host.markTouched();\r\n }\r\n }\r\n\r\n destroy(): void {\r\n this.destroyOverlay();\r\n }\r\n\r\n // Listeners, the page lock and the auto-scroll loop are released before immediate disposal.\r\n private destroyOverlay(): void {\r\n const overlayRef = this.overlayRef;\r\n // Unsubscribe before disposing, so our own dispose cannot re-enter the detach handler.\r\n this.overlaySubscription?.unsubscribe();\r\n this.overlaySubscription = undefined;\r\n this.overlayDetachSubscription?.unsubscribe();\r\n this.overlayDetachSubscription = undefined;\r\n this.releaseOverlayTracking();\r\n this.overlayRef = undefined;\r\n this.position.resetAfterClose();\r\n this.host.setOpen(false);\r\n this.host.setActiveId(null);\r\n this.host.setCanScrollUp(false);\r\n this.host.setCanScrollDown(false);\r\n overlayRef?.dispose();\r\n }\r\n\r\n private handleOverlayDetached(): void {\r\n this.overlaySubscription?.unsubscribe();\r\n this.overlaySubscription = undefined;\r\n this.overlayDetachSubscription?.unsubscribe();\r\n this.overlayDetachSubscription = undefined;\r\n this.releaseOverlayTracking();\r\n this.overlayRef = undefined;\r\n this.position.resetAfterDetach();\r\n this.host.setOpen(false);\r\n this.host.setActiveId(null);\r\n this.host.setCanScrollUp(false);\r\n this.host.setCanScrollDown(false);\r\n }\r\n\r\n // Releases listeners, the page-scroll lock and any inline height bound, on every close path.\r\n private releaseOverlayTracking(): void {\r\n this.scrolling.release();\r\n // Disabled explicitly: a popover-mode detach can tear the overlay down without disposing it,\r\n // which would otherwise leave the page locked.\r\n this.scrollStrategy?.disable();\r\n this.scrollStrategy = undefined;\r\n this.position.releaseSubscription();\r\n // `alignPopup` writes an inline `max-height`; clear it so no bound leaks into a later open.\r\n const popupElement =\r\n this.overlayRef?.overlayElement.querySelector<HTMLElement>('.raqm-select-popup');\r\n if (popupElement) {\r\n popupElement.style.maxHeight = '';\r\n }\r\n }\r\n}\r\n","// Select placement: the connected position strategy, the item-aligned measure, its edge\r\n// fallbacks and the tracked side it reports.\r\n\r\nimport { untracked } from '@angular/core';\r\n\r\nimport {\r\n ConnectedPosition,\r\n FlexibleConnectedPositionStrategy,\r\n OverlayRef,\r\n} from '@angular/cdk/overlay';\r\nimport { ViewportRuler } from '@angular/cdk/scrolling';\r\n\r\nimport {\r\n ANCHOR_CLEARANCE,\r\n OVERLAY_GAP,\r\n SCROLL_EDGE_TOLERANCE_PX,\r\n VIEWPORT_MARGIN,\r\n} from './select-model';\r\n\r\nexport interface RaqmSelectPositionHost {\r\n overlayRef(): OverlayRef | undefined;\r\n trigger(): HTMLElement;\r\n activeId(): string | null;\r\n alignItemWithTrigger(): boolean;\r\n open(): boolean;\r\n setAlignmentSide(side: 'none' | 'bottom' | 'top'): void;\r\n updateScrollAffordances(): void;\r\n popupScrollElement(): HTMLElement | null;\r\n}\r\n\r\nexport class RaqmSelectPosition {\r\n // Kept so the aligned offset can be applied.\r\n private positionStrategy: FlexibleConnectedPositionStrategy | undefined;\r\n\r\n // The side the position strategy applied for a below popup (below or flipped above).\r\n private positionSubscription: { unsubscribe(): void } | undefined;\r\n\r\n // The alignment mode currently applied, so an input change while open can be detected.\r\n private appliedAligned: boolean | undefined;\r\n\r\n // Sticky for one open once the aligned popup falls back to anchored placement near an edge.\r\n private alignmentDeactivated = false;\r\n\r\n constructor(\r\n private readonly viewportRuler: ViewportRuler,\r\n private readonly host: RaqmSelectPositionHost,\r\n ) {}\r\n\r\n // A new open re-evaluates the edge fallback.\r\n resetDeactivation(): void {\r\n this.alignmentDeactivated = false;\r\n }\r\n\r\n // Aligned connects the selected row to the trigger; below prefers below and falls back above.\r\n private positionsFor(aligned: boolean): ConnectedPosition[] {\r\n if (aligned) {\r\n return [{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'top' }];\r\n }\r\n return [\r\n {\r\n originX: 'start',\r\n originY: 'bottom',\r\n overlayX: 'start',\r\n overlayY: 'top',\r\n offsetY: OVERLAY_GAP,\r\n },\r\n {\r\n originX: 'start',\r\n originY: 'top',\r\n overlayX: 'start',\r\n overlayY: 'bottom',\r\n offsetY: -OVERLAY_GAP,\r\n },\r\n ];\r\n }\r\n\r\n configureStrategy(strategy: FlexibleConnectedPositionStrategy, aligned: boolean): void {\r\n strategy\r\n .withPositions(this.positionsFor(aligned))\r\n // Aligned mode sizes itself so the offset can be clamped; below mode lets the CDK fit it.\r\n .withFlexibleDimensions(!aligned)\r\n .withGrowAfterOpen(!aligned)\r\n .withPush(!aligned)\r\n .withViewportMargin(VIEWPORT_MARGIN);\r\n }\r\n\r\n // Takes ownership of the live strategy, its applied mode and its side reporting.\r\n bind(strategy: FlexibleConnectedPositionStrategy, aligned: boolean): void {\r\n this.positionStrategy = strategy;\r\n this.appliedAligned = aligned;\r\n // Item-aligned popups carry no side; a below popup reports the side the CDK actually applies.\r\n this.host.setAlignmentSide(aligned ? 'none' : 'bottom');\r\n this.positionSubscription = strategy.positionChanges.subscribe((change) => {\r\n if (this.appliedAligned === false) {\r\n this.host.setAlignmentSide(change.connectionPair.originY === 'bottom' ? 'bottom' : 'top');\r\n }\r\n });\r\n }\r\n\r\n releaseSubscription(): void {\r\n this.positionSubscription?.unsubscribe();\r\n this.positionSubscription = undefined;\r\n }\r\n\r\n resetAfterClose(): void {\r\n this.positionStrategy = undefined;\r\n this.appliedAligned = undefined;\r\n this.alignmentDeactivated = false;\r\n }\r\n\r\n resetAfterDetach(): void {\r\n this.positionStrategy = undefined;\r\n this.appliedAligned = undefined;\r\n }\r\n\r\n reactToAlignmentChange(): void {\r\n const aligned = this.host.alignItemWithTrigger();\r\n const isOpen = this.host.open();\r\n if (!isOpen || aligned === this.appliedAligned) {\r\n return;\r\n }\r\n // Untracked so the re-apply's DOM reads never become dependencies of this effect.\r\n untracked(() => this.applyAlignmentMode(aligned));\r\n }\r\n\r\n applyAlignmentMode(aligned: boolean): void {\r\n const overlayRef = this.host.overlayRef();\r\n const strategy = this.positionStrategy;\r\n if (!overlayRef || !strategy) {\r\n return;\r\n }\r\n const popupElement = overlayRef.overlayElement.querySelector<HTMLElement>('.raqm-select-popup');\r\n\r\n this.configureStrategy(strategy, aligned);\r\n this.appliedAligned = aligned;\r\n\r\n if (aligned) {\r\n this.host.setAlignmentSide('none');\r\n // An explicit mode change re-evaluates the edge fallback.\r\n this.alignmentDeactivated = false;\r\n this.boundPopupHeight();\r\n this.alignPopup();\r\n } else {\r\n // Clear the aligned offset and inline bound, then let the CDK size the below popup.\r\n strategy.withDefaultOffsetY(0);\r\n if (popupElement) {\r\n popupElement.style.maxHeight = '';\r\n }\r\n overlayRef.updatePosition();\r\n }\r\n this.host.updateScrollAffordances();\r\n }\r\n\r\n // Single bounded post-render measure that aligns the selected row over the trigger.\r\n alignPopup(): void {\r\n const overlayRef = this.host.overlayRef();\r\n const strategy = this.positionStrategy;\r\n if (\r\n !overlayRef ||\r\n !strategy ||\r\n !this.host.alignItemWithTrigger() ||\r\n this.alignmentDeactivated\r\n ) {\r\n return;\r\n }\r\n\r\n const triggerElement = this.host.trigger();\r\n const popupElement = overlayRef.overlayElement.querySelector<HTMLElement>('.raqm-select-popup');\r\n const activeId = this.host.activeId();\r\n const rowElement = activeId\r\n ? overlayRef.overlayElement.querySelector<HTMLElement>(`[id=\"${activeId}\"]`)\r\n : null;\r\n if (!popupElement || !rowElement) {\r\n overlayRef.updatePosition();\r\n return;\r\n }\r\n\r\n // One synchronous, position-independent measure: the overlay's own rect is not a usable frame\r\n // here, and `offsetTop` is valid because `.raqm-select-popup` is the positioned scroll container.\r\n const viewport = this.viewportRuler.getViewportSize();\r\n const triggerRect = triggerElement.getBoundingClientRect();\r\n const rowCenterInPopup =\r\n rowElement.offsetTop - popupElement.scrollTop + rowElement.offsetHeight / 2;\r\n // Moves the selected row's centre onto the trigger's centre.\r\n const desired = triggerRect.height / 2 - rowCenterInPopup;\r\n\r\n // The height is fitted to the collision boundary rather than sliding the popup, which would\r\n // break the row-over-trigger alignment.\r\n const boundaryTop = VIEWPORT_MARGIN;\r\n const boundaryBottom = viewport.height - VIEWPORT_MARGIN;\r\n const alignedTop = triggerRect.top + desired;\r\n let offset = desired;\r\n let height = popupElement.getBoundingClientRect().height;\r\n let heightReduced = false;\r\n\r\n const bottomOverflow = alignedTop + height - boundaryBottom;\r\n if (bottomOverflow > 0) {\r\n height = Math.max(0, height - bottomOverflow);\r\n popupElement.style.maxHeight = `${height}px`;\r\n heightReduced = true;\r\n }\r\n // Near the top edge the bottom is preserved instead and the popup shifts down.\r\n const shift = boundaryTop - alignedTop;\r\n if (shift > 0) {\r\n offset += shift;\r\n height = Math.max(0, height - shift);\r\n popupElement.style.maxHeight = `${height}px`;\r\n heightReduced = true;\r\n }\r\n\r\n // Item-alignment is deactivated here rather than shrunk further, so the popup falls back to\r\n // anchored placement and gets the full height above the trigger.\r\n if (this.shouldDeactivateAlignment(triggerRect, height, viewport.height)) {\r\n this.deactivateAlignment();\r\n return;\r\n }\r\n\r\n strategy.withDefaultOffsetY(offset);\r\n overlayRef.updatePosition();\r\n // A shrunk popup has a different scroll range, so refresh the affordances.\r\n if (heightReduced) {\r\n this.host.updateScrollAffordances();\r\n }\r\n }\r\n\r\n // Bounds the popup's block size to the room around its anchor before the measure.\r\n boundPopupHeight(): void {\r\n const popupElement = this.host\r\n .overlayRef()\r\n ?.overlayElement.querySelector<HTMLElement>('.raqm-select-popup');\r\n if (!popupElement) {\r\n return;\r\n }\r\n // The anchor rect and viewport ruler are settled here: this runs after `attach()`.\r\n const triggerRect = this.host.trigger().getBoundingClientRect();\r\n const viewport = this.viewportRuler.getViewportSize();\r\n const spaceAbove = triggerRect.top - ANCHOR_CLEARANCE;\r\n const spaceBelow = viewport.height - triggerRect.bottom - ANCHOR_CLEARANCE;\r\n popupElement.style.maxHeight = `${Math.max(0, Math.max(spaceAbove, spaceBelow))}px`;\r\n }\r\n\r\n // Deactivated within 20px of the aligned collision boundary, or below the 100px minimum height.\r\n private shouldDeactivateAlignment(\r\n triggerRect: DOMRect,\r\n height: number,\r\n viewportHeight: number,\r\n ): boolean {\r\n // A 10px margin is reserved on both sides of the aligned geometry.\r\n const triggerCollisionThreshold = 20;\r\n const boundaryHeight = viewportHeight - VIEWPORT_MARGIN * 2;\r\n const minimumAlignedHeight = 100;\r\n const contentHeight = this.host.popupScrollElement()?.scrollHeight ?? 0;\r\n return (\r\n triggerRect.top < triggerCollisionThreshold ||\r\n triggerRect.bottom > boundaryHeight - triggerCollisionThreshold ||\r\n Math.ceil(height) + SCROLL_EDGE_TOLERANCE_PX < Math.min(contentHeight, minimumAlignedHeight)\r\n );\r\n }\r\n\r\n // Stops item-alignment for the rest of this open; `data-raqm-align` keeps the prop's value.\r\n private deactivateAlignment(): void {\r\n const overlayRef = this.host.overlayRef();\r\n const strategy = this.positionStrategy;\r\n if (!overlayRef || !strategy) {\r\n return;\r\n }\r\n this.alignmentDeactivated = true;\r\n this.appliedAligned = false;\r\n const popupElement = overlayRef.overlayElement.querySelector<HTMLElement>('.raqm-select-popup');\r\n if (popupElement) {\r\n popupElement.style.maxHeight = '';\r\n }\r\n strategy.withDefaultOffsetY(0);\r\n this.configureStrategy(strategy, false);\r\n overlayRef.updatePosition();\r\n this.host.updateScrollAffordances();\r\n }\r\n}\r\n","// Select popup scrolling: the bounded row reveal, the scroll affordances and the\r\n// pointer-rest auto-scroll loop.\r\n\r\nimport { OverlayRef } from '@angular/cdk/overlay';\r\nimport { ViewportRuler } from '@angular/cdk/scrolling';\r\n\r\nimport { AUTO_SCROLL_INTERVAL_MS, SCROLL_EDGE_TOLERANCE_PX, SCROLL_STEP } from './select-model';\r\n\r\nexport interface RaqmSelectScrollingHost {\r\n overlayRef(): OverlayRef | undefined;\r\n resetActive(): void;\r\n setCanScrollUp(value: boolean): void;\r\n setCanScrollDown(value: boolean): void;\r\n}\r\n\r\nexport class RaqmSelectScrolling {\r\n private autoScrollTimer?: ReturnType<typeof setInterval>;\r\n private autoScrollDirection: 'up' | 'down' | null = null;\r\n\r\n // The popup's passive scroll listener teardown, removed on close/destroy.\r\n private scrollCleanup: (() => void) | undefined;\r\n\r\n // Viewport-resize subscription that refreshes the scroll affordances.\r\n private viewportSubscription: { unsubscribe(): void } | undefined;\r\n\r\n constructor(\r\n private readonly viewportRuler: ViewportRuler,\r\n private readonly host: RaqmSelectScrollingHost,\r\n ) {}\r\n\r\n // One bounded assignment, no polling.\r\n scrollOptionIntoView(id: string | null): void {\r\n const overlayRef = this.host.overlayRef();\r\n if (!overlayRef || !id) {\r\n return;\r\n }\r\n const popupElement = overlayRef.overlayElement.querySelector<HTMLElement>('.raqm-select-popup');\r\n const rowElement = overlayRef.overlayElement.querySelector<HTMLElement>(`[id=\"${id}\"]`);\r\n if (!popupElement || !rowElement) {\r\n return;\r\n }\r\n const rowTop = rowElement.offsetTop;\r\n const rowBottom = rowTop + rowElement.offsetHeight;\r\n const viewTop = popupElement.scrollTop;\r\n const viewBottom = viewTop + popupElement.clientHeight;\r\n if (rowTop < viewTop) {\r\n popupElement.scrollTop = rowTop;\r\n } else if (rowBottom > viewBottom) {\r\n popupElement.scrollTop = rowBottom - popupElement.clientHeight;\r\n }\r\n }\r\n\r\n // Keeps the scroll affordances in sync while open; `release` removes both.\r\n attach(): void {\r\n const popupElement = this.host\r\n .overlayRef()\r\n ?.overlayElement.querySelector<HTMLElement>('.raqm-select-popup');\r\n if (popupElement) {\r\n const handler = (): void => this.updateAffordances();\r\n popupElement.addEventListener('scroll', handler, { passive: true });\r\n this.scrollCleanup = () => popupElement.removeEventListener('scroll', handler);\r\n }\r\n this.viewportSubscription = this.viewportRuler\r\n .change()\r\n .subscribe(() => this.updateAffordances());\r\n }\r\n\r\n // Releases the listeners and stops the auto-scroll loop, on every close path.\r\n release(): void {\r\n this.stopAutoScroll();\r\n this.scrollCleanup?.();\r\n this.scrollCleanup = undefined;\r\n this.viewportSubscription?.unsubscribe();\r\n this.viewportSubscription = undefined;\r\n }\r\n\r\n // One bounded read showing each affordance only when content exists that way.\r\n updateAffordances(): void {\r\n const popupElement = this.host\r\n .overlayRef()\r\n ?.overlayElement.querySelector<HTMLElement>('.raqm-select-popup');\r\n if (!popupElement) {\r\n this.host.setCanScrollUp(false);\r\n this.host.setCanScrollDown(false);\r\n return;\r\n }\r\n const { scrollTop, clientHeight, scrollHeight } = popupElement;\r\n this.host.setCanScrollUp(scrollTop > 0);\r\n this.host.setCanScrollDown(scrollTop + clientHeight < scrollHeight - 1);\r\n }\r\n\r\n scrollByStep(direction: 'up' | 'down'): void {\r\n const popupElement = this.host\r\n .overlayRef()\r\n ?.overlayElement.querySelector<HTMLElement>('.raqm-select-popup');\r\n if (!popupElement) {\r\n return;\r\n }\r\n popupElement.scrollTop += direction === 'up' ? -SCROLL_STEP : SCROLL_STEP;\r\n this.updateAffordances();\r\n }\r\n\r\n // Resolved on demand because the overlay is recreated per open.\r\n popupScrollElement(): HTMLElement | null {\r\n return (\r\n this.host.overlayRef()?.overlayElement.querySelector<HTMLElement>('.raqm-select-popup') ??\r\n null\r\n );\r\n }\r\n\r\n // Clamps into `[0, max]`, snapping a value within the 1px tolerance onto the nearest edge.\r\n private normalizeScrollOffset(value: number, max: number): number {\r\n if (max <= 0) {\r\n return 0;\r\n }\r\n const clamped = Math.max(0, Math.min(value, max));\r\n const withinStart = clamped <= SCROLL_EDGE_TOLERANCE_PX;\r\n const withinEnd = max - clamped <= SCROLL_EDGE_TOLERANCE_PX;\r\n if (withinStart && withinEnd) {\r\n return clamped <= max - clamped ? 0 : max;\r\n }\r\n if (withinStart) {\r\n return 0;\r\n }\r\n if (withinEnd) {\r\n return max;\r\n }\r\n return clamped;\r\n }\r\n\r\n // One tick scrolls the adjacent whole row into view rather than a fixed pixel step, then stops\r\n // at the range end.\r\n private scrollArrowStep(direction: 'up' | 'down'): void {\r\n // Each tick clears the active option, so no accent paints while the pointer rests on an arrow.\r\n this.host.resetActive();\r\n const popupElement = this.popupScrollElement();\r\n if (!popupElement) {\r\n this.stopAutoScroll();\r\n return;\r\n }\r\n const isUp = direction === 'up';\r\n const arrowElement = this.host\r\n .overlayRef()\r\n ?.overlayElement.querySelector<HTMLElement>(\r\n isUp ? '.raqm-select-scroll-button--up' : '.raqm-select-scroll-button--down',\r\n );\r\n const arrowHeight = arrowElement?.offsetHeight ?? 0;\r\n const rows = Array.from(popupElement.querySelectorAll<HTMLElement>('.raqm-select-option'));\r\n const maxScrollTop = Math.max(0, popupElement.scrollHeight - popupElement.clientHeight);\r\n const scrollTop = this.normalizeScrollOffset(popupElement.scrollTop, maxScrollTop);\r\n if (scrollTop !== popupElement.scrollTop) {\r\n popupElement.scrollTop = scrollTop;\r\n }\r\n // Already at the range end in this direction: stop rather than spin.\r\n if (scrollTop === (isUp ? 0 : maxScrollTop)) {\r\n this.stopAutoScroll();\r\n this.updateAffordances();\r\n return;\r\n }\r\n let target = maxScrollTop;\r\n if (rows.length > 0) {\r\n if (isUp) {\r\n let firstVisibleIndex = 0;\r\n const visibleTop = scrollTop + arrowHeight - SCROLL_EDGE_TOLERANCE_PX;\r\n for (let i = 0; i < rows.length; i += 1) {\r\n if (rows[i].offsetTop >= visibleTop) {\r\n firstVisibleIndex = i;\r\n break;\r\n }\r\n }\r\n const targetIndex = Math.max(0, firstVisibleIndex - 1);\r\n const targetRow = rows[targetIndex];\r\n target =\r\n targetIndex < firstVisibleIndex && targetRow ? targetRow.offsetTop - arrowHeight : 0;\r\n } else {\r\n let lastVisibleIndex = rows.length - 1;\r\n const visibleBottom =\r\n scrollTop + popupElement.clientHeight - arrowHeight + SCROLL_EDGE_TOLERANCE_PX;\r\n for (let i = 0; i < rows.length; i += 1) {\r\n if (rows[i].offsetTop + rows[i].offsetHeight > visibleBottom) {\r\n lastVisibleIndex = Math.max(0, i - 1);\r\n break;\r\n }\r\n }\r\n const targetIndex = Math.min(rows.length - 1, lastVisibleIndex + 1);\r\n const targetRow = rows[targetIndex];\r\n target =\r\n targetIndex > lastVisibleIndex && targetRow\r\n ? targetRow.offsetTop + targetRow.offsetHeight - popupElement.clientHeight + arrowHeight\r\n : maxScrollTop;\r\n }\r\n }\r\n const nextScrollTop = this.normalizeScrollOffset(target, maxScrollTop);\r\n // Skipped when it would re-trigger scroll events forever.\r\n if (Math.abs(popupElement.scrollTop - nextScrollTop) > SCROLL_EDGE_TOLERANCE_PX) {\r\n popupElement.scrollTop = nextScrollTop;\r\n }\r\n this.updateAffordances();\r\n }\r\n\r\n // One whole-row step every 40ms until the pointer leaves, the popup closes or the range ends.\r\n startAutoScroll(direction: 'up' | 'down'): void {\r\n if (this.autoScrollDirection === direction) {\r\n return;\r\n }\r\n this.stopAutoScroll();\r\n this.autoScrollDirection = direction;\r\n // Nulled as soon as the pointer reaches the arrow, not on the first tick.\r\n this.host.resetActive();\r\n this.autoScrollTimer = setInterval(() => {\r\n this.scrollArrowStep(direction);\r\n }, AUTO_SCROLL_INTERVAL_MS);\r\n }\r\n\r\n stopAutoScroll(): void {\r\n if (this.autoScrollTimer !== undefined) {\r\n clearInterval(this.autoScrollTimer);\r\n this.autoScrollTimer = undefined;\r\n }\r\n this.autoScrollDirection = null;\r\n }\r\n}\r\n","// Select derived state: the control ids, the chunk/option render shapes, the trigger text\r\n// and the writable signals the popup lifecycle and the template share.\r\n\r\nimport { computed, signal } from '@angular/core';\r\n\r\nimport {\r\n RaqmSelectChunkView,\r\n RaqmSelectOptionRef,\r\n RaqmSelectOptionView,\r\n isSelectGroup,\r\n} from './select-model';\r\nimport { RaqmSelectEntry, RaqmSelectOption } from './select.types';\r\n\r\nexport interface RaqmSelectViewStateHost {\r\n items(): readonly RaqmSelectEntry[];\r\n inputId(): string;\r\n autoId: string;\r\n selected(): string | null;\r\n scrollOptionIntoView(id: string | null): void;\r\n}\r\n\r\nexport class RaqmSelectViewState {\r\n readonly cvaDisabled = signal<boolean>(false);\r\n\r\n readonly open = signal<boolean>(false);\r\n\r\n // The active option id, `null` when none; drives the highlight and `aria-activedescendant`.\r\n readonly activeId = signal<string | null>(null);\r\n\r\n // Direction resolved at open time and applied to the popup and overlay.\r\n readonly overlayDir = signal<'ltr' | 'rtl'>('ltr');\r\n\r\n readonly canScrollUp = signal<boolean>(false);\r\n readonly canScrollDown = signal<boolean>(false);\r\n // `data-raqm-side`: `none` while item-aligned, else the resolved anchor side.\r\n readonly alignmentSide = signal<'none' | 'bottom' | 'top'>('none');\r\n\r\n readonly resolvedInputId = computed(() => this.host.inputId() || this.host.autoId);\r\n\r\n readonly labelId = computed(() => `${this.resolvedInputId()}-label`);\r\n\r\n /** Id of the popup listbox, referenced by `aria-controls`. */\r\n readonly listboxId = computed(() => `${this.resolvedInputId()}-listbox`);\r\n\r\n readonly chunks = computed<RaqmSelectChunkView[]>(() => {\r\n const baseId = this.resolvedInputId();\r\n const chunks: RaqmSelectChunkView[] = [];\r\n let optionIndex = 0;\r\n let chunkIndex = 0;\r\n let loose: RaqmSelectChunkView | null = null;\r\n\r\n const nextView = (option: RaqmSelectOption): RaqmSelectOptionView => {\r\n const view: RaqmSelectOptionView = {\r\n option,\r\n id: `${baseId}-option-${optionIndex}`,\r\n index: optionIndex,\r\n };\r\n optionIndex++;\r\n return view;\r\n };\r\n\r\n for (const entry of this.host.items()) {\r\n if (isSelectGroup(entry)) {\r\n loose = null;\r\n chunks.push({\r\n key: `${baseId}-group-${chunkIndex}`,\r\n label: entry.label,\r\n labelId: `${baseId}-group-label-${chunkIndex}`,\r\n separatorBefore: entry.separatorBefore === true,\r\n options: entry.options.map(nextView),\r\n });\r\n chunkIndex++;\r\n continue;\r\n }\r\n if (loose === null) {\r\n loose = {\r\n key: `${baseId}-loose-${chunkIndex}`,\r\n label: null,\r\n labelId: null,\r\n separatorBefore: false,\r\n options: [],\r\n };\r\n chunks.push(loose);\r\n chunkIndex++;\r\n }\r\n loose.options.push(nextView(entry));\r\n }\r\n return chunks;\r\n });\r\n\r\n readonly optionViews = computed<RaqmSelectOptionView[]>(() =>\r\n this.chunks().flatMap((chunk) => chunk.options),\r\n );\r\n\r\n // Rebuilt only when the items or ids change, so navigation never invalidates the active item.\r\n readonly optionRefs = computed<RaqmSelectOptionRef[]>(() =>\r\n this.optionViews().map(\r\n (view) =>\r\n new RaqmSelectOptionRef(view, (ref) => {\r\n this.activeId.set(ref.view.id);\r\n // Bounded single scroll, no loop.\r\n this.host.scrollOptionIntoView(ref.view.id);\r\n }),\r\n ),\r\n );\r\n\r\n // Trigger text for the current value, or `null` when nothing matches; an unknown programmatic\r\n // value is kept but never given invented text. `triggerLabel` overrides `label` here only.\r\n readonly selectedLabel = computed<string | null>(() => {\r\n const value = this.host.selected();\r\n const match = this.optionViews().find((view) => view.option.value === value);\r\n return match ? (match.option.triggerLabel ?? match.option.label) : null;\r\n });\r\n\r\n constructor(private readonly host: RaqmSelectViewStateHost) {}\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ElementRef,\r\n Injector,\r\n OnDestroy,\r\n OnInit,\r\n TemplateRef,\r\n ViewContainerRef,\r\n booleanAttribute,\r\n computed,\r\n forwardRef,\r\n inject,\r\n input,\r\n linkedSignal,\r\n output,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { NgTemplateOutlet } from '@angular/common';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\r\n\r\nimport { Directionality } from '@angular/cdk/bidi';\r\nimport { Overlay, ViewportRuler } from '@angular/cdk/overlay';\r\n\r\nimport { RaqmSelectControl } from './select-control';\r\nimport { connectSelectEffects } from './select-effects';\r\nimport { RaqmSelectKeyboard } from './select-keyboard';\r\nimport { RaqmSelectOptionView, resolveSelectDirection } from './select-model';\r\nimport { RaqmSelectOverlay } from './select-overlay';\r\nimport { RaqmSelectPosition } from './select-position';\r\nimport { RaqmSelectScrolling } from './select-scrolling';\r\nimport { RaqmSelectEntry, RaqmSelectOption } from './select.types';\r\nimport { RaqmSelectViewState } from './select-view-state';\r\n\r\nlet nextSelectId = 0;\r\n\r\n/**\r\n * A single-select popup exposed as an ARIA 1.2 combobox.\r\n *\r\n * @remarks\r\n * The host is not the control: the internal `<button type=\"button\">` carries `role=\"combobox\"` and\r\n * the popup is an overlay `role=\"listbox\"` of `role=\"option\"` rows. The host has no role or tab\r\n * stop, so an application label must target `inputId`; a supplied `label` renders an internal\r\n * `<label [for]>`, and the placeholder never becomes the accessible name. Focus stays on the\r\n * trigger via the active-descendant pattern, with a label-only typeahead and no focus trap.\r\n * Bind either `[(value)]` or one Forms directive: `writeValue` normalises non-strings to `null` and\r\n * never emits nor marks dirty, while a committed selection calls the change callback once.\r\n * `alignItemWithTrigger` measures once, so the selected row sits over the trigger.\r\n */\r\n@Component({\r\n selector: 'raqm-select',\r\n imports: [NgTemplateOutlet],\r\n templateUrl: './select.html',\r\n styleUrl: './select.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n providers: [\r\n // Forms value accessor; `value`/`valueChange` stay the plain two-way API.\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => RaqmSelect),\r\n multi: true,\r\n },\r\n ],\r\n host: {\r\n class: 'raqm-select',\r\n '[attr.data-raqm-disabled]': 'effectiveDisabled() ? \"true\" : null',\r\n '[attr.data-raqm-invalid]': 'invalid() ? \"true\" : null',\r\n '[attr.data-raqm-open]': 'open() ? \"true\" : null',\r\n },\r\n})\r\nexport class RaqmSelect implements ControlValueAccessor, OnInit, OnDestroy {\r\n private readonly host = inject(ElementRef<HTMLElement>);\r\n\r\n private readonly overlay = inject(Overlay);\r\n private readonly viewportRuler = inject(ViewportRuler);\r\n\r\n private readonly directionality = inject(Directionality, { optional: true });\r\n\r\n private readonly viewContainerRef = inject(ViewContainerRef);\r\n\r\n // The internal trigger button — the single tab stop.\r\n private readonly triggerRef = viewChild.required<ElementRef<HTMLButtonElement>>('trigger');\r\n\r\n private readonly popupTemplate = viewChild.required('popup', {\r\n read: TemplateRef,\r\n });\r\n\r\n private readonly autoId = `raqm-select-${++nextSelectId}`;\r\n\r\n // Captured so the key manager can be built in `ngOnInit`, which has no injection context.\r\n private readonly injector = inject(Injector);\r\n\r\n readonly items = input.required<readonly RaqmSelectEntry[]>();\r\n\r\n readonly value = input<string | null>(null);\r\n\r\n readonly valueChange = output<string | null>();\r\n\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n\r\n /** Text shown when no option label matches; app-owned, no default. */\r\n readonly placeholder = input<string | null>(null);\r\n\r\n /** Aligns the selected row over the trigger. */\r\n readonly alignItemWithTrigger = input(true, { transform: booleanAttribute });\r\n\r\n readonly dir = input<'ltr' | 'rtl' | undefined>(undefined);\r\n\r\n /** Id of the real trigger button; generated when absent. */\r\n readonly inputId = input<string>('');\r\n\r\n /** Optional internal label text, rendered as a `<label [for]>`. */\r\n readonly label = input<string | undefined>(undefined);\r\n\r\n /** External label id(s); takes precedence over `label`. */\r\n readonly labelledBy = input<string | undefined>(undefined);\r\n\r\n readonly describedBy = input<string | undefined>(undefined);\r\n\r\n /** Application-owned invalid state; drives `aria-invalid`. */\r\n readonly invalid = input(false, { transform: booleanAttribute });\r\n\r\n // Re-derived from `value`, so a controlled binding re-asserts ownership of the user's pick.\r\n readonly selected = linkedSignal<string | null>(() => this.value());\r\n\r\n private readonly state: RaqmSelectViewState = new RaqmSelectViewState({\r\n items: () => this.items(),\r\n inputId: () => this.inputId(),\r\n autoId: this.autoId,\r\n selected: () => this.selected(),\r\n scrollOptionIntoView: (id) => this.scrolling.scrollOptionIntoView(id),\r\n });\r\n\r\n readonly resolvedInputId = this.state.resolvedInputId;\r\n readonly labelId = this.state.labelId;\r\n /** Id of the popup listbox, referenced by `aria-controls`. */\r\n readonly listboxId = this.state.listboxId;\r\n readonly chunks = this.state.chunks;\r\n // Trigger text for the current value, or `null` when nothing matches.\r\n readonly selectedLabel = this.state.selectedLabel;\r\n\r\n readonly effectiveDisabled = computed(() => this.disabled() || this.state.cvaDisabled());\r\n\r\n readonly open = this.state.open;\r\n // The active option id, `null` when none; drives the highlight and `aria-activedescendant`.\r\n readonly activeId = this.state.activeId;\r\n // Direction resolved at open time and applied to the popup and overlay.\r\n readonly overlayDir = this.state.overlayDir;\r\n readonly canScrollUp = this.state.canScrollUp;\r\n readonly canScrollDown = this.state.canScrollDown;\r\n // `data-raqm-side`: `none` while item-aligned, else the resolved anchor side.\r\n readonly alignmentSide = this.state.alignmentSide;\r\n\r\n private readonly control: RaqmSelectControl = new RaqmSelectControl({\r\n effectiveDisabled: () => this.effectiveDisabled(),\r\n selected: () => this.selected(),\r\n setSelected: (value) => this.selected.set(value),\r\n emit: (value) => this.valueChange.emit(value),\r\n close: (touched) => this.layer.close(touched),\r\n setCvaDisabled: (value) => this.state.cvaDisabled.set(value),\r\n optionViews: () => this.state.optionViews(),\r\n });\r\n\r\n private readonly position: RaqmSelectPosition = new RaqmSelectPosition(this.viewportRuler, {\r\n overlayRef: () => this.layer.ref,\r\n trigger: () => this.triggerRef().nativeElement,\r\n activeId: () => this.state.activeId(),\r\n alignItemWithTrigger: () => this.alignItemWithTrigger(),\r\n open: () => this.state.open(),\r\n setAlignmentSide: (side) => this.state.alignmentSide.set(side),\r\n updateScrollAffordances: () => this.scrolling.updateAffordances(),\r\n popupScrollElement: () => this.scrolling.popupScrollElement(),\r\n });\r\n\r\n private readonly scrolling: RaqmSelectScrolling = new RaqmSelectScrolling(this.viewportRuler, {\r\n overlayRef: () => this.layer.ref,\r\n resetActive: () => this.keyboard.resetActive(),\r\n setCanScrollUp: (value) => this.state.canScrollUp.set(value),\r\n setCanScrollDown: (value) => this.state.canScrollDown.set(value),\r\n });\r\n\r\n private readonly layer: RaqmSelectOverlay = new RaqmSelectOverlay(\r\n this.overlay,\r\n this.viewContainerRef,\r\n this.position,\r\n this.scrolling,\r\n {\r\n open: () => this.state.open(),\r\n effectiveDisabled: () => this.effectiveDisabled(),\r\n trigger: () => this.triggerRef().nativeElement,\r\n popupTemplate: () => this.popupTemplate(),\r\n direction: () =>\r\n resolveSelectDirection(this.dir(), this.host.nativeElement, this.directionality),\r\n alignItemWithTrigger: () => this.alignItemWithTrigger(),\r\n setOpen: (value) => this.state.open.set(value),\r\n setActiveId: (id) => this.state.activeId.set(id),\r\n setOverlayDir: (dir) => this.state.overlayDir.set(dir),\r\n setInitialActive: () => this.keyboard.setInitialActive(),\r\n markTouched: () => this.control.markTouched(),\r\n setCanScrollUp: (value) => this.state.canScrollUp.set(value),\r\n setCanScrollDown: (value) => this.state.canScrollDown.set(value),\r\n },\r\n );\r\n\r\n private readonly keyboard: RaqmSelectKeyboard = new RaqmSelectKeyboard(this.injector, {\r\n optionRefs: () => this.state.optionRefs,\r\n optionViews: () => this.state.optionViews(),\r\n selected: () => this.selected(),\r\n activeId: () => this.state.activeId(),\r\n open: () => this.state.open(),\r\n element: () => this.host.nativeElement,\r\n overlayRef: () => this.layer.ref,\r\n openPopup: () => this.layer.openPopup(),\r\n close: (touched) => this.layer.close(touched),\r\n markTouched: () => this.control.markTouched(),\r\n commitSelection: (value) => this.control.commitSelection(value),\r\n setActiveId: (id) => this.state.activeId.set(id),\r\n });\r\n\r\n constructor() {\r\n connectSelectEffects({\r\n reportDuplicateValues: () => this.control.reportDuplicateValues(),\r\n reactToAlignmentChange: () => this.position.reactToAlignmentChange(),\r\n effectiveDisabled: () => this.effectiveDisabled(),\r\n open: () => this.state.open(),\r\n close: (touched) => this.layer.close(touched),\r\n });\r\n }\r\n\r\n ngOnInit(): void {\r\n this.keyboard.init();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.keyboard.destroy();\r\n this.layer.destroy();\r\n }\r\n\r\n /** Writes an external value without emitting or marking touched; non-strings become `null`. */\r\n writeValue(value: unknown): void {\r\n this.control.writeValue(value);\r\n }\r\n\r\n registerOnChange(fn: (value: string | null) => void): void {\r\n this.control.registerOnChange(fn);\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.control.registerOnTouched(fn);\r\n }\r\n\r\n /** ORs a Forms disabled state with the explicit input and closes the popup. */\r\n setDisabledState(isDisabled: boolean): void {\r\n this.control.setDisabledState(isDisabled);\r\n }\r\n\r\n /** Opens the popup when closed, closes it when open. */\r\n toggle(): void {\r\n if (this.open()) {\r\n this.close(true);\r\n } else {\r\n this.openPopup();\r\n }\r\n }\r\n\r\n /** Handles every trigger key, open or closed. */\r\n onTriggerKeydown(event: KeyboardEvent): void {\r\n this.keyboard.onTriggerKeydown(event);\r\n }\r\n\r\n /** Marks the control touched when focus leaves the whole composite. */\r\n onTriggerBlur(event: FocusEvent): void {\r\n this.keyboard.onTriggerBlur(event);\r\n }\r\n\r\n onOptionClick(option: RaqmSelectOption): void {\r\n this.control.onOptionClick(option);\r\n }\r\n\r\n /** Routes hover through the key manager, so paint, `aria-activedescendant` and the active item agree. */\r\n onOptionPointerMove(view: RaqmSelectOptionView): void {\r\n this.keyboard.onOptionPointerMove(view);\r\n }\r\n\r\n /** Clears the active option on leaving the list, so the next ArrowDown restarts at the top. */\r\n onOptionPointerLeave(event: PointerEvent): void {\r\n this.keyboard.onOptionPointerLeave(event);\r\n }\r\n\r\n scrollByStep(direction: 'up' | 'down'): void {\r\n this.scrolling.scrollByStep(direction);\r\n }\r\n\r\n startAutoScroll(direction: 'up' | 'down'): void {\r\n this.scrolling.startAutoScroll(direction);\r\n }\r\n\r\n stopAutoScroll(): void {\r\n this.scrolling.stopAutoScroll();\r\n }\r\n\r\n private openPopup(): void {\r\n this.layer.openPopup();\r\n }\r\n\r\n private close(touched: boolean): void {\r\n this.layer.close(touched);\r\n }\r\n}\r\n","@if (label(); as labelText) {\r\n <!-- `for` targets the real trigger button, not the custom-element host. -->\r\n <label class=\"raqm-select-label\" [attr.for]=\"resolvedInputId()\" [attr.id]=\"labelId()\">\r\n {{ labelText }}\r\n </label>\r\n}\r\n\r\n<!-- The control: a native button with combobox semantics and the single tab stop. -->\r\n<button\r\n #trigger\r\n type=\"button\"\r\n class=\"raqm-select-trigger\"\r\n role=\"combobox\"\r\n aria-haspopup=\"listbox\"\r\n [attr.id]=\"resolvedInputId()\"\r\n [attr.aria-expanded]=\"open()\"\r\n [attr.aria-controls]=\"open() ? listboxId() : null\"\r\n [attr.aria-activedescendant]=\"open() ? activeId() : null\"\r\n [attr.aria-labelledby]=\"labelledBy() ?? null\"\r\n [attr.aria-describedby]=\"describedBy() ?? null\"\r\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\r\n [attr.data-raqm-placeholder]=\"selectedLabel() === null ? '' : null\"\r\n [disabled]=\"effectiveDisabled()\"\r\n (click)=\"toggle()\"\r\n (keydown)=\"onTriggerKeydown($event)\"\r\n (blur)=\"onTriggerBlur($event)\"\r\n>\r\n <span class=\"raqm-select-value\">{{ selectedLabel() ?? placeholder() }}</span>\r\n\r\n <svg\r\n class=\"raqm-select-trigger-icon\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n</button>\r\n\r\n<!-- Instantiated into a CDK overlay; its nodes come from this view, so component styles apply. -->\r\n<ng-template #popup>\r\n <div\r\n class=\"raqm-select-popup\"\r\n [attr.dir]=\"overlayDir()\"\r\n [attr.data-raqm-align]=\"alignItemWithTrigger()\"\r\n [attr.data-raqm-side]=\"alignmentSide()\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n >\r\n <!-- Pointer-only affordance; `visibility` keeps the layout and measure stable. -->\r\n <div\r\n class=\"raqm-select-scroll-button raqm-select-scroll-button--up\"\r\n [class.raqm-select-scroll-button--hidden]=\"!canScrollUp()\"\r\n aria-hidden=\"true\"\r\n (pointermove)=\"startAutoScroll('up')\"\r\n (pointerleave)=\"stopAutoScroll()\"\r\n (click)=\"scrollByStep('up')\"\r\n >\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"m18 15-6-6-6 6\" />\r\n </svg>\r\n </div>\r\n\r\n <div\r\n class=\"raqm-select-list\"\r\n role=\"listbox\"\r\n [attr.id]=\"listboxId()\"\r\n [attr.aria-labelledby]=\"label() ? labelId() : (labelledBy() ?? null)\"\r\n >\r\n <!-- One row shared by grouped and loose chunks, so loose options are direct listbox children. -->\r\n <ng-template #optionList let-options>\r\n @for (view of options; track view.id) {\r\n <div\r\n class=\"raqm-select-option\"\r\n role=\"option\"\r\n [id]=\"view.id\"\r\n [attr.aria-selected]=\"selected() === view.option.value\"\r\n [attr.aria-disabled]=\"view.option.disabled ? 'true' : null\"\r\n [class.raqm-select-option--active]=\"view.id === activeId()\"\r\n [attr.data-raqm-highlighted]=\"view.id === activeId() ? '' : null\"\r\n (pointermove)=\"onOptionPointerMove(view)\"\r\n (pointerleave)=\"onOptionPointerLeave($event)\"\r\n (click)=\"onOptionClick(view.option)\"\r\n >\r\n <span class=\"raqm-select-item-indicator\" aria-hidden=\"true\">\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"M20 6 9 17l-5-5\" />\r\n </svg>\r\n </span>\r\n <span class=\"raqm-select-item-text\">{{ view.option.label }}</span>\r\n </div>\r\n }\r\n </ng-template>\r\n\r\n @for (chunk of chunks(); track chunk.key) {\r\n @if (chunk.separatorBefore) {\r\n <!-- Decorative, non-focusable separator. -->\r\n <div class=\"raqm-select-separator\" role=\"separator\" aria-orientation=\"horizontal\"></div>\r\n }\r\n @if (chunk.label; as groupLabel) {\r\n <!-- A labelled explicit group. -->\r\n <div class=\"raqm-select-group\" role=\"group\" [attr.aria-labelledby]=\"chunk.labelId\">\r\n <div class=\"raqm-select-group-label\" [attr.id]=\"chunk.labelId\">\r\n {{ groupLabel }}\r\n </div>\r\n <ng-container\r\n [ngTemplateOutlet]=\"optionList\"\r\n [ngTemplateOutletContext]=\"{ $implicit: chunk.options }\"\r\n />\r\n </div>\r\n } @else {\r\n <!-- A loose run keeps the same unnamed `role=\"group\"` padding, which sets the popup height. -->\r\n <div class=\"raqm-select-group\" role=\"group\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"optionList\"\r\n [ngTemplateOutletContext]=\"{ $implicit: chunk.options }\"\r\n />\r\n </div>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Pointer-only, non-focusable affordance; see the note above. -->\r\n <div\r\n class=\"raqm-select-scroll-button raqm-select-scroll-button--down\"\r\n [class.raqm-select-scroll-button--hidden]=\"!canScrollDown()\"\r\n aria-hidden=\"true\"\r\n (pointermove)=\"startAutoScroll('down')\"\r\n (pointerleave)=\"stopAutoScroll()\"\r\n (click)=\"scrollByStep('down')\"\r\n >\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n </div>\r\n </div>\r\n</ng-template>\r\n"],"mappings":";;;;;;;;;AAqCA,SAAgB,cAAc,OAAsB;CAClD,OAAO,MAAM,QAAS,MAA0B,OAAO;AACzD;AAGA,SAAgB,eAAe,OAAc;CAC3C,OAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAGA,SAAgB,uBACd,KACA,SACA,gBAAqC;CAErC,MAAM,WAAW;CACjB,IAAI,aAAa,SAAS,aAAa,OACrC,OAAO;CAGT,IADiB,iBAAiB,OAAO,CAAC,CAAC,cAC1B,OACf,OAAO;CAET,OAAO,gBAAgB,SAAS;AAClC;AAGA,IAAa,sBAAb,MAAgC;CAEnB;CACQ;CAFnB,YACW,MACQ,UAA4C;EADpD,KAAA,OAAA;EACQ,KAAA,WAAA;CAChB;CAEH,IAAI,WAAQ;EACV,OAAO,KAAK,KAAK,OAAO,aAAa;CACvC;CAGA,WAAQ;EACN,OAAO,KAAK,KAAK,OAAO;CAC1B;CAEA,kBAAe;EACb,KAAK,SAAS,IAAI;CACpB;CAEA,oBAAiB,CAAU;AAC5B;AClED,IAAa,oBAAb,MAA8B;CAIC;CAHrB;CACA;CAER,YAA6B,MAA2B;EAA3B,KAAA,OAAA;CAA8B;CAG3D,WAAW,OAAc;EACvB,KAAK,KAAK,YAAY,eAAe,KAAK,CAAC;CAC7C;CAEA,iBAAiB,IAAkC;EACjD,KAAK,WAAW;CAClB;CAEA,kBAAkB,IAAc;EAC9B,KAAK,YAAY;CACnB;CAGA,iBAAiB,YAAmB;EAClC,KAAK,KAAK,eAAe,UAAU;EACnC,IAAI,YACF,KAAK,KAAK,MAAM,KAAK;CAEzB;CAEA,cAAc,QAAwB;EACpC,IAAI,OAAO,aAAa,MACtB;EAEF,KAAK,gBAAgB,OAAO,KAAK;CACnC;CAGA,gBAAgB,OAAoB;EAClC,IAAI,KAAK,KAAK,kBAAiB,GAC7B;EAEF,IAAI,KAAK,KAAK,SAAQ,MAAO,OAAO;GAClC,KAAK,KAAK,MAAM,IAAI;GACpB;EACF;EACA,KAAK,KAAK,YAAY,KAAK;EAC3B,KAAK,WAAW,KAAK;EACrB,KAAK,KAAK,KAAK,KAAK;EACpB,KAAK,KAAK,MAAM,IAAI;CACtB;CAEA,cAAW;EACT,KAAK,YAAW;CAClB;CAGA,wBAAqB;EACnB,IAAI,CAAC,UAAS,GACZ;EAEF,MAAM,uBAAO,IAAI,IAAG;EACpB,MAAM,6BAAa,IAAI,IAAG;EAC1B,KAAK,MAAM,QAAQ,KAAK,KAAK,YAAW,GAAI;GAC1C,MAAM,QAAQ,KAAK,OAAO;GAC1B,IAAI,KAAK,IAAI,KAAK,GAChB,WAAW,IAAI,KAAK;QAEpB,KAAK,IAAI,KAAK;EAElB;EACA,IAAI,WAAW,OAAO,GACpB,QAAQ,MACN,2CAA2C,CAAC,GAAG,UAAU,CAAC,CACvD,KAAK,UAAU,KAAK,UAAU,KAAK,CAAC,CAAC,CACrC,KAAK,IAAI,EAAC,uCAAwC;CAG3D;AACD;ACjFD,SAAgB,qBAAqB,MAA2B;CAE9D,aAAa,KAAK,sBAAqB,CAAE;CAGzC,aAAa,KAAK,uBAAsB,CAAE;CAG1C,aAAY;EACV,IAAI,KAAK,kBAAiB,KAAM,KAAK,KAAI,GACvC,gBAAgB,KAAK,MAAM,KAAK,CAAC;CAErC,CAAC;AACH;ACDA,IAAa,qBAAb,MAA+B;CAKV;CACA;CAJX;CAER,YACmB,UACA,MAA4B;EAD5B,KAAA,WAAA;EACA,KAAA,OAAA;CAChB;CAQH,OAAI;EACF,KAAK,aAAa,IAAI,2BACpB,KAAK,KAAK,WAAU,GACpB,KAAK,QAAQ,CACd,CACE,SAAS,KAAK,CAAC,CACf,wBAAwB,IAAI,CAAC,CAC7B,eAAe,IAAI,CAAC,CACpB,cAAa;CAClB;CAEA,UAAO;EACL,KAAK,YAAY,QAAO;CAC1B;CAGA,iBAAiB,OAAoB;EACnC,IAAI,CAAC,KAAK,KAAK,KAAI,GAAI;GACrB,IACE,MAAM,QAAQ,eACd,MAAM,QAAQ,aACd,MAAM,QAAQ,WACd,MAAM,QAAQ,KACd;IACA,MAAM,eAAc;IACpB,KAAK,KAAK,UAAS;GACrB;GACA;EACF;EAEA,QAAQ,MAAM,KAAd;GACE,KAAK;IAEH,MAAM,eAAc;IACpB,KAAK,KAAK,MAAM,IAAI;IACpB;GACF,KAAK;IAEH,KAAK,KAAK,MAAM,IAAI;IACpB;GACF,KAAK;GACL,KAAK;IACH,MAAM,eAAc;IACpB,KAAK,mBAAkB;IACvB;GACF,SACE,KAAK,YAAY,UAAU,KAAK;EACpC;CACF;CAGA,cAAc,OAAiB;EAC7B,MAAM,OAAO,MAAM;EACnB,MAAM,iBAAiB,KAAK,KAAK,WAAU,CAAE,EAAE;EAC/C,IAAI,SAAS,KAAK,KAAK,QAAO,CAAE,CAAC,SAAS,IAAI,KAAK,gBAAgB,SAAS,IAAI,MAAM,OACpF;EAEF,IAAI,KAAK,KAAK,KAAI,GAChB,KAAK,KAAK,MAAM,IAAI;OAEpB,KAAK,KAAK,YAAW;CAEzB;CAGA,oBAAoB,MAA0B;EAC5C,IAAI,KAAK,OAAO,aAAa,MAC3B;EAEF,IAAI,KAAK,KAAK,SAAQ,MAAO,KAAK,IAChC;EAEF,MAAM,QAAQ,KAAK,KAAK,YAAW,CAAE,CAAC,WAAW,cAAc,UAAU,OAAO,KAAK,EAAE;EACvF,IAAI,UAAU,IACZ;EAEF,KAAK,YAAY,cAAc,KAAK;CACtC;CAGA,qBAAqB,OAAmB;EACtC,IAAI,MAAM,gBAAgB,SACxB;EAEF,MAAM,UAAU,MAAM;EACtB,IAAI,mBAAmB,WAAW,QAAQ,QAAQ,qBAAqB,GACrE;EAEF,KAAK,YAAW;CAClB;CAGA,cAAW;EACT,KAAK,YAAY,cAAc,EAAE;EACjC,KAAK,KAAK,YAAY,IAAI;CAC5B;CAEQ,qBAAkB;EACxB,MAAM,SAAS,KAAK,YAAY;EAChC,IAAI,CAAC,UAAU,OAAO,UACpB;EAEF,KAAK,KAAK,gBAAgB,OAAO,KAAK,OAAO,KAAK;CACpD;CAGA,mBAAgB;EACd,MAAM,QAAQ,KAAK,KAAK,YAAW;EACnC,IAAI,MAAM,WAAW,GACnB;EAEF,MAAM,WAAW,KAAK,KAAK,SAAQ;EACnC,IAAI,QAAQ,MAAM,WACf,SAAS,KAAK,OAAO,UAAU,YAAY,KAAK,OAAO,aAAa,IAAI;EAE3E,IAAI,UAAU,IACZ,QAAQ,MAAM,WAAW,SAAS,KAAK,OAAO,aAAa,IAAI;EAEjE,IAAI,UAAU,IACZ;EAEF,KAAK,YAAY,cAAc,KAAK;CACtC;AACD;ACxID,IAAa,oBAAb,MAA8B;CAYT;CACA;CACA;CACA;CACA;CAfX;CAGA;CAGA;CAEA;CAER,YACmB,SACA,kBACA,UACA,WACA,MAA2B;EAJ3B,KAAA,UAAA;EACA,KAAA,mBAAA;EACA,KAAA,WAAA;EACA,KAAA,YAAA;EACA,KAAA,OAAA;CAChB;CAEH,IAAI,MAAG;EACL,OAAO,KAAK;CACd;CAEA,YAAS;EACP,IAAI,KAAK,KAAK,KAAI,KAAM,KAAK,KAAK,kBAAiB,GACjD;EAGF,KAAK,SAAS,kBAAiB;EAE/B,MAAM,UAAU,KAAK,KAAK,QAAO;EACjC,MAAM,YAAY,KAAK,KAAK,UAAS;EACrC,KAAK,KAAK,cAAc,SAAS;EAEjC,MAAM,UAAU,KAAK,KAAK,qBAAoB;EAC9C,MAAM,WAAW,KAAK,QAAQ,SAAQ,CAAE,CAAC,oBAAoB,OAAO;EACpE,KAAK,SAAS,kBAAkB,UAAU,OAAO;EAEjD,MAAM,SAAwB;GAC5B,kBAAkB;GAElB,gBAAgB,KAAK,QAAQ,iBAAiB,MAAK;GACnD,aAAa;GACb,eAAe;GACf,YAAY;GAEZ,qBAAqB;GAErB,OAAO,QAAQ,sBAAqB,CAAE,CAAC;GACvC;EACD;EAED,KAAK,SAAS,KAAK,UAAU,OAAO;EACpC,KAAK,iBAAiB,OAAO;EAC7B,KAAK,aAAa,KAAK,QAAQ,OAAO,MAAM;EAC5C,yBAAyB,SAAS,KAAK,UAAU;EACjD,KAAK,WAAW,OAAO,IAAI,eAAe,KAAK,KAAK,cAAa,GAAI,KAAK,gBAAgB,CAAC;EAE3F,KAAK,KAAK,QAAQ,IAAI;EACtB,KAAK,KAAK,YAAY,IAAI;EAC1B,IAAI,SAEF,KAAK,SAAS,iBAAgB;EAEhC,KAAK,KAAK,iBAAgB;EAC1B,KAAK,UAAU,OAAM;EACrB,KAAK,UAAU,kBAAiB;EAChC,IAAI,SACF,KAAK,SAAS,WAAU;EAG1B,KAAK,sBAAsB,KAAK,WAAW,cAAa,CAAE,CAAC,gBAAgB,KAAK,MAAM,IAAI,CAAC;EAC3F,KAAK,4BAA4B,KAAK,WACnC,YAAW,CAAE,CACb,gBAAgB,KAAK,sBAAqB,CAAE;CACjD;CAEA,MAAM,SAAgB;EACpB,KAAK,eAAc;EACnB,IAAI,SACF,KAAK,KAAK,YAAW;CAEzB;CAEA,UAAO;EACL,KAAK,eAAc;CACrB;CAGQ,iBAAc;EACpB,MAAM,aAAa,KAAK;EAExB,KAAK,qBAAqB,YAAW;EACrC,KAAK,sBAAsB;EAC3B,KAAK,2BAA2B,YAAW;EAC3C,KAAK,4BAA4B;EACjC,KAAK,uBAAsB;EAC3B,KAAK,aAAa;EAClB,KAAK,SAAS,gBAAe;EAC7B,KAAK,KAAK,QAAQ,KAAK;EACvB,KAAK,KAAK,YAAY,IAAI;EAC1B,KAAK,KAAK,eAAe,KAAK;EAC9B,KAAK,KAAK,iBAAiB,KAAK;EAChC,YAAY,QAAO;CACrB;CAEQ,wBAAqB;EAC3B,KAAK,qBAAqB,YAAW;EACrC,KAAK,sBAAsB;EAC3B,KAAK,2BAA2B,YAAW;EAC3C,KAAK,4BAA4B;EACjC,KAAK,uBAAsB;EAC3B,KAAK,aAAa;EAClB,KAAK,SAAS,iBAAgB;EAC9B,KAAK,KAAK,QAAQ,KAAK;EACvB,KAAK,KAAK,YAAY,IAAI;EAC1B,KAAK,KAAK,eAAe,KAAK;EAC9B,KAAK,KAAK,iBAAiB,KAAK;CAClC;CAGQ,yBAAsB;EAC5B,KAAK,UAAU,QAAO;EAGtB,KAAK,gBAAgB,QAAO;EAC5B,KAAK,iBAAiB;EACtB,KAAK,SAAS,oBAAmB;EAEjC,MAAM,eACJ,KAAK,YAAY,eAAe,cAA2B,oBAAoB;EACjF,IAAI,cACF,aAAa,MAAM,YAAY;CAEnC;AACD;ACpID,IAAa,qBAAb,MAA+B;CAcV;CACA;CAbX;CAGA;CAGA;CAGA,uBAAuB;CAE/B,YACmB,eACA,MAA4B;EAD5B,KAAA,gBAAA;EACA,KAAA,OAAA;CAChB;CAGH,oBAAiB;EACf,KAAK,uBAAuB;CAC9B;CAGQ,aAAa,SAAgB;EACnC,IAAI,SACF,OAAO,CAAC;GAAE,SAAS;GAAS,SAAS;GAAO,UAAU;GAAS,UAAU;EAAK,CAAE;EAElF,OAAO,CACL;GACE,SAAS;GACT,SAAS;GACT,UAAU;GACV,UAAU;GACV,SAAA;EACD,GACD;GACE,SAAS;GACT,SAAS;GACT,UAAU;GACV,UAAU;GACV,SAAS;EACV,CACF;CACH;CAEA,kBAAkB,UAA6C,SAAgB;EAC7E,SACG,cAAc,KAAK,aAAa,OAAO,CAAC,CAAC,CAEzC,uBAAuB,CAAC,OAAO,CAAC,CAChC,kBAAkB,CAAC,OAAO,CAAC,CAC3B,SAAS,CAAC,OAAO,CAAC,CAClB,mBAAA,EAAkC;CACvC;CAGA,KAAK,UAA6C,SAAgB;EAChE,KAAK,mBAAmB;EACxB,KAAK,iBAAiB;EAEtB,KAAK,KAAK,iBAAiB,UAAU,SAAS,QAAQ;EACtD,KAAK,uBAAuB,SAAS,gBAAgB,WAAW,WAAU;GACxE,IAAI,KAAK,mBAAmB,OAC1B,KAAK,KAAK,iBAAiB,OAAO,eAAe,YAAY,WAAW,WAAW,KAAK;EAE5F,CAAC;CACH;CAEA,sBAAmB;EACjB,KAAK,sBAAsB,YAAW;EACtC,KAAK,uBAAuB;CAC9B;CAEA,kBAAe;EACb,KAAK,mBAAmB;EACxB,KAAK,iBAAiB;EACtB,KAAK,uBAAuB;CAC9B;CAEA,mBAAgB;EACd,KAAK,mBAAmB;EACxB,KAAK,iBAAiB;CACxB;CAEA,yBAAsB;EACpB,MAAM,UAAU,KAAK,KAAK,qBAAoB;EAE9C,IAAI,CADW,KAAK,KAAK,KACpB,KAAU,YAAY,KAAK,gBAC9B;EAGF,gBAAgB,KAAK,mBAAmB,OAAO,CAAC;CAClD;CAEA,mBAAmB,SAAgB;EACjC,MAAM,aAAa,KAAK,KAAK,WAAU;EACvC,MAAM,WAAW,KAAK;EACtB,IAAI,CAAC,cAAc,CAAC,UAClB;EAEF,MAAM,eAAe,WAAW,eAAe,cAA2B,oBAAoB;EAE9F,KAAK,kBAAkB,UAAU,OAAO;EACxC,KAAK,iBAAiB;EAEtB,IAAI,SAAS;GACX,KAAK,KAAK,iBAAiB,MAAM;GAEjC,KAAK,uBAAuB;GAC5B,KAAK,iBAAgB;GACrB,KAAK,WAAU;EACjB,OAAO;GAEL,SAAS,mBAAmB,CAAC;GAC7B,IAAI,cACF,aAAa,MAAM,YAAY;GAEjC,WAAW,eAAc;EAC3B;EACA,KAAK,KAAK,wBAAuB;CACnC;CAGA,aAAU;EACR,MAAM,aAAa,KAAK,KAAK,WAAU;EACvC,MAAM,WAAW,KAAK;EACtB,IACE,CAAC,cACD,CAAC,YACD,CAAC,KAAK,KAAK,qBAAoB,KAC/B,KAAK,sBAEL;EAGF,MAAM,iBAAiB,KAAK,KAAK,QAAO;EACxC,MAAM,eAAe,WAAW,eAAe,cAA2B,oBAAoB;EAC9F,MAAM,WAAW,KAAK,KAAK,SAAQ;EACnC,MAAM,aAAa,WACf,WAAW,eAAe,cAA2B,QAAQ,SAAQ,GAAI,IACzE;EACJ,IAAI,CAAC,gBAAgB,CAAC,YAAY;GAChC,WAAW,eAAc;GACzB;EACF;EAIA,MAAM,WAAW,KAAK,cAAc,gBAAe;EACnD,MAAM,cAAc,eAAe,sBAAqB;EACxD,MAAM,mBACJ,WAAW,YAAY,aAAa,YAAY,WAAW,eAAe;EAE5E,MAAM,UAAU,YAAY,SAAS,IAAI;EAIzC,MAAM,cAAA;EACN,MAAM,iBAAiB,SAAS,SAAA;EAChC,MAAM,aAAa,YAAY,MAAM;EACrC,IAAI,SAAS;EACb,IAAI,SAAS,aAAa,sBAAqB,CAAE,CAAC;EAClD,IAAI,gBAAgB;EAEpB,MAAM,iBAAiB,aAAa,SAAS;EAC7C,IAAI,iBAAiB,GAAG;GACtB,SAAS,KAAK,IAAI,GAAG,SAAS,cAAc;GAC5C,aAAa,MAAM,YAAY,GAAG,OAAM;GACxC,gBAAgB;EAClB;EAEA,MAAM,QAAQ,cAAc;EAC5B,IAAI,QAAQ,GAAG;GACb,UAAU;GACV,SAAS,KAAK,IAAI,GAAG,SAAS,KAAK;GACnC,aAAa,MAAM,YAAY,GAAG,OAAM;GACxC,gBAAgB;EAClB;EAIA,IAAI,KAAK,0BAA0B,aAAa,QAAQ,SAAS,MAAM,GAAG;GACxE,KAAK,oBAAmB;GACxB;EACF;EAEA,SAAS,mBAAmB,MAAM;EAClC,WAAW,eAAc;EAEzB,IAAI,eACF,KAAK,KAAK,wBAAuB;CAErC;CAGA,mBAAgB;EACd,MAAM,eAAe,KAAK,KACvB,WAAU,CAAE,EACX,eAAe,cAA2B,oBAAoB;EAClE,IAAI,CAAC,cACH;EAGF,MAAM,cAAc,KAAK,KAAK,QAAO,CAAE,CAAC,sBAAqB;EAC7D,MAAM,WAAW,KAAK,cAAc,gBAAe;EACnD,MAAM,aAAa,YAAY,MAAA;EAC/B,MAAM,aAAa,SAAS,SAAS,YAAY,SAAA;EACjD,aAAa,MAAM,YAAY,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,YAAY,UAAU,CAAC,EAAC;CACjF;CAGQ,0BACN,aACA,QACA,gBAAsB;EAGtB,MAAM,4BAA4B;EAClC,MAAM,iBAAiB,iBAAA;EACvB,MAAM,uBAAuB;EAC7B,MAAM,gBAAgB,KAAK,KAAK,mBAAkB,CAAE,EAAE,gBAAgB;EACtE,OACE,YAAY,MAAM,6BAClB,YAAY,SAAS,iBAAiB,6BACtC,KAAK,KAAK,MAAM,IAAA,IAA+B,KAAK,IAAI,eAAe,oBAAoB;CAE/F;CAGQ,sBAAmB;EACzB,MAAM,aAAa,KAAK,KAAK,WAAU;EACvC,MAAM,WAAW,KAAK;EACtB,IAAI,CAAC,cAAc,CAAC,UAClB;EAEF,KAAK,uBAAuB;EAC5B,KAAK,iBAAiB;EACtB,MAAM,eAAe,WAAW,eAAe,cAA2B,oBAAoB;EAC9F,IAAI,cACF,aAAa,MAAM,YAAY;EAEjC,SAAS,mBAAmB,CAAC;EAC7B,KAAK,kBAAkB,UAAU,KAAK;EACtC,WAAW,eAAc;EACzB,KAAK,KAAK,wBAAuB;CACnC;AACD;ACtQD,IAAa,sBAAb,MAAgC;CAWX;CACA;CAXX;CACA,sBAA4C;CAG5C;CAGA;CAER,YACmB,eACA,MAA6B;EAD7B,KAAA,gBAAA;EACA,KAAA,OAAA;CAChB;CAGH,qBAAqB,IAAiB;EACpC,MAAM,aAAa,KAAK,KAAK,WAAU;EACvC,IAAI,CAAC,cAAc,CAAC,IAClB;EAEF,MAAM,eAAe,WAAW,eAAe,cAA2B,oBAAoB;EAC9F,MAAM,aAAa,WAAW,eAAe,cAA2B,QAAQ,GAAE,GAAI;EACtF,IAAI,CAAC,gBAAgB,CAAC,YACpB;EAEF,MAAM,SAAS,WAAW;EAC1B,MAAM,YAAY,SAAS,WAAW;EACtC,MAAM,UAAU,aAAa;EAC7B,MAAM,aAAa,UAAU,aAAa;EAC1C,IAAI,SAAS,SACX,aAAa,YAAY;OACpB,IAAI,YAAY,YACrB,aAAa,YAAY,YAAY,aAAa;CAEtD;CAGA,SAAM;EACJ,MAAM,eAAe,KAAK,KACvB,WAAU,CAAE,EACX,eAAe,cAA2B,oBAAoB;EAClE,IAAI,cAAc;GAChB,MAAM,gBAAsB,KAAK,kBAAiB;GAClD,aAAa,iBAAiB,UAAU,SAAS,EAAE,SAAS,KAAI,CAAE;GAClE,KAAK,sBAAsB,aAAa,oBAAoB,UAAU,OAAO;EAC/E;EACA,KAAK,uBAAuB,KAAK,cAC9B,OAAM,CAAE,CACR,gBAAgB,KAAK,kBAAiB,CAAE;CAC7C;CAGA,UAAO;EACL,KAAK,eAAc;EACnB,KAAK,gBAAe;EACpB,KAAK,gBAAgB;EACrB,KAAK,sBAAsB,YAAW;EACtC,KAAK,uBAAuB;CAC9B;CAGA,oBAAiB;EACf,MAAM,eAAe,KAAK,KACvB,WAAU,CAAE,EACX,eAAe,cAA2B,oBAAoB;EAClE,IAAI,CAAC,cAAc;GACjB,KAAK,KAAK,eAAe,KAAK;GAC9B,KAAK,KAAK,iBAAiB,KAAK;GAChC;EACF;EACA,MAAM,EAAE,WAAW,cAAc,iBAAiB;EAClD,KAAK,KAAK,eAAe,YAAY,CAAC;EACtC,KAAK,KAAK,iBAAiB,YAAY,eAAe,eAAe,CAAC;CACxE;CAEA,aAAa,WAAwB;EACnC,MAAM,eAAe,KAAK,KACvB,WAAU,CAAE,EACX,eAAe,cAA2B,oBAAoB;EAClE,IAAI,CAAC,cACH;EAEF,aAAa,aAAa,cAAc,OAAO,OAAA;EAC/C,KAAK,kBAAiB;CACxB;CAGA,qBAAkB;EAChB,OACE,KAAK,KAAK,WAAU,CAAE,EAAE,eAAe,cAA2B,oBAAoB,KACtF;CAEJ;CAGQ,sBAAsB,OAAe,KAAW;EACtD,IAAI,OAAO,GACT,OAAO;EAET,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,GAAG,CAAC;EAChD,MAAM,cAAc,WAAA;EACpB,MAAM,YAAY,MAAM,WAAA;EACxB,IAAI,eAAe,WACjB,OAAO,WAAW,MAAM,UAAU,IAAI;EAExC,IAAI,aACF,OAAO;EAET,IAAI,WACF,OAAO;EAET,OAAO;CACT;CAIQ,gBAAgB,WAAwB;EAE9C,KAAK,KAAK,YAAW;EACrB,MAAM,eAAe,KAAK,mBAAkB;EAC5C,IAAI,CAAC,cAAc;GACjB,KAAK,eAAc;GACnB;EACF;EACA,MAAM,OAAO,cAAc;EAM3B,MAAM,eALe,KAAK,KACvB,WAAU,CAAE,EACX,eAAe,cACf,OAAO,mCAAmC,kCAAkC,EAE5D,EAAc,gBAAgB;EAClD,MAAM,OAAO,MAAM,KAAK,aAAa,iBAA8B,qBAAqB,CAAC;EACzF,MAAM,eAAe,KAAK,IAAI,GAAG,aAAa,eAAe,aAAa,YAAY;EACtF,MAAM,YAAY,KAAK,sBAAsB,aAAa,WAAW,YAAY;EACjF,IAAI,cAAc,aAAa,WAC7B,aAAa,YAAY;EAG3B,IAAI,eAAe,OAAO,IAAI,eAAe;GAC3C,KAAK,eAAc;GACnB,KAAK,kBAAiB;GACtB;EACF;EACA,IAAI,SAAS;EACb,IAAI,KAAK,SAAS,GAAG;GACnB,IAAI,MAAM;IACR,IAAI,oBAAoB;IACxB,MAAM,aAAa,YAAY,cAAA;IAC/B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GACpC,IAAI,KAAK,EAAE,CAAC,aAAa,YAAY;KACnC,oBAAoB;KACpB;IACF;IAEF,MAAM,cAAc,KAAK,IAAI,GAAG,oBAAoB,CAAC;IACrD,MAAM,YAAY,KAAK;IACvB,SACE,cAAc,qBAAqB,YAAY,UAAU,YAAY,cAAc;GACvF,OAAO;IACL,IAAI,mBAAmB,KAAK,SAAS;IACrC,MAAM,gBACJ,YAAY,aAAa,eAAe,cAAA;IAC1C,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GACpC,IAAI,KAAK,EAAE,CAAC,YAAY,KAAK,EAAE,CAAC,eAAe,eAAe;KAC5D,mBAAmB,KAAK,IAAI,GAAG,IAAI,CAAC;KACpC;IACF;IAEF,MAAM,cAAc,KAAK,IAAI,KAAK,SAAS,GAAG,mBAAmB,CAAC;IAClE,MAAM,YAAY,KAAK;IACvB,SACE,cAAc,oBAAoB,YAC9B,UAAU,YAAY,UAAU,eAAe,aAAa,eAAe,cAC3E;GACR;EACF;EACA,MAAM,gBAAgB,KAAK,sBAAsB,QAAQ,YAAY;EAErE,IAAI,KAAK,IAAI,aAAa,YAAY,aAAa,IAAA,GACjD,aAAa,YAAY;EAE3B,KAAK,kBAAiB;CACxB;CAGA,gBAAgB,WAAwB;EACtC,IAAI,KAAK,wBAAwB,WAC/B;EAEF,KAAK,eAAc;EACnB,KAAK,sBAAsB;EAE3B,KAAK,KAAK,YAAW;EACrB,KAAK,kBAAkB,kBAAiB;GACtC,KAAK,gBAAgB,SAAS;EAChC,GAAA,EAA0B;CAC5B;CAEA,iBAAc;EACZ,IAAI,KAAK,oBAAoB,QAAW;GACtC,cAAc,KAAK,eAAe;GAClC,KAAK,kBAAkB;EACzB;EACA,KAAK,sBAAsB;CAC7B;AACD;ACxMD,IAAa,sBAAb,MAAgC;CA6FD;CA5FpB,cAAc,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAEpC,OAAO,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAG7B,WAAW,OAAsB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAGtC,aAAa,OAAsB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAEzC,cAAc,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CACpC,gBAAgB,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAEtC,gBAAgB,OAAkC,QAAO,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAEzD,kBAAkB,eAAe,KAAK,KAAK,QAAO,KAAM,KAAK,KAAK,QAAO,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;CAEzE,UAAU,eAAe,GAAG,KAAK,gBAAe,EAAE,SAAS,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAG3D,YAAY,eAAe,GAAG,KAAK,gBAAe,EAAE,WAAW,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAE/D,SAAS,eAAqC;EACrD,MAAM,SAAS,KAAK,gBAAe;EACnC,MAAM,SAAgC,CAAA;EACtC,IAAI,cAAc;EAClB,IAAI,aAAa;EACjB,IAAI,QAAoC;EAExC,MAAM,YAAY,WAAkD;GAClE,MAAM,OAA6B;IACjC;IACA,IAAI,GAAG,OAAM,UAAW;IACxB,OAAO;GACR;GACD;GACA,OAAO;EACT;EAEA,KAAK,MAAM,SAAS,KAAK,KAAK,MAAK,GAAI;GACrC,IAAI,cAAc,KAAK,GAAG;IACxB,QAAQ;IACR,OAAO,KAAK;KACV,KAAK,GAAG,OAAM,SAAU;KACxB,OAAO,MAAM;KACb,SAAS,GAAG,OAAM,eAAgB;KAClC,iBAAiB,MAAM,oBAAoB;KAC3C,SAAS,MAAM,QAAQ,IAAI,QAAQ;IACpC,CAAA;IACD;IACA;GACF;GACA,IAAI,UAAU,MAAM;IAClB,QAAQ;KACN,KAAK,GAAG,OAAM,SAAU;KACxB,OAAO;KACP,SAAS;KACT,iBAAiB;KACjB,SAAS,CAAA;IACV;IACD,OAAO,KAAK,KAAK;IACjB;GACF;GACA,MAAM,QAAQ,KAAK,SAAS,KAAK,CAAC;EACpC;EACA,OAAO;CACT,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAEO,cAAc,eACrB,KAAK,OAAM,CAAE,CAAC,SAAS,UAAU,MAAM,OAAO,GAC/C,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAGQ,aAAa,eACpB,KAAK,YAAW,CAAE,CAAC,KAChB,SACC,IAAI,oBAAoB,OAAO,QAAO;EACpC,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE;EAE7B,KAAK,KAAK,qBAAqB,IAAI,KAAK,EAAE;CAC5C,CAAC,CAAC,GAEP,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAIQ,gBAAgB,eAA6B;EACpD,MAAM,QAAQ,KAAK,KAAK,SAAQ;EAChC,MAAM,QAAQ,KAAK,YAAW,CAAE,CAAC,MAAM,SAAS,KAAK,OAAO,UAAU,KAAK;EAC3E,OAAO,QAAS,MAAM,OAAO,gBAAgB,MAAM,OAAO,QAAS;CACrE,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAEF,YAA6B,MAA6B;EAA7B,KAAA,OAAA;CAAgC;AAC9D;ACjFD,IAAI,eAAe;AAoCnB,IAAa,aAAb,MAAa,WAAU;CACJ,OAAO,OAAO,UAAuB;CAErC,UAAU,OAAO,OAAO;CACxB,gBAAgB,OAAO,aAAa;CAEpC,iBAAiB,OAAO,gBAAgB,EAAE,UAAU,KAAI,CAAE;CAE1D,mBAAmB,OAAO,gBAAgB;CAG1C,aAAa,UAAU,SAAwC,WAAU,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAEzE,gBAAgB,UAAU,SAAS,SAAO;EAAA,GAAA,YAAA,EAAA,WAAA,gBAAA,+BAAA,CAAA;EACzD,MAAM;CAAW,CAAA;CAGF,SAAS,eAAe,EAAE;CAG1B,WAAW,OAAO,QAAQ;CAElC,QAAQ,MAAM,SAAsC,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAEpD,QAAQ,MAAqB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAElC,cAAc,OAAM;CAEpB,WAAW,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CAGrD,cAAc,MAAqB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAGxC,uBAAuB,MAAM,MAAI;EAAA,GAAA,YAAA,EAAA,WAAA,uBAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CAEhE,MAAM,MAAiC,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,MAAA,CAAA,+BAAA,CAAA,CAAA;CAGjD,UAAU,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CAG3B,QAAQ,MAA0B,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAG5C,aAAa,MAA0B,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAEjD,cAAc,MAA0B,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAGlD,UAAU,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,UAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CAGpD,WAAW,mBAAkC,KAAK,MAAK,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAElD,QAA6B,IAAI,oBAAoB;EACpE,aAAa,KAAK,MAAK;EACvB,eAAe,KAAK,QAAO;EAC3B,QAAQ,KAAK;EACb,gBAAgB,KAAK,SAAQ;EAC7B,uBAAuB,OAAO,KAAK,UAAU,qBAAqB,EAAE;CACrE,CAAA;CAEQ,kBAAkB,KAAK,MAAM;CAC7B,UAAU,KAAK,MAAM;CAErB,YAAY,KAAK,MAAM;CACvB,SAAS,KAAK,MAAM;CAEpB,gBAAgB,KAAK,MAAM;CAE3B,oBAAoB,eAAe,KAAK,SAAQ,KAAM,KAAK,MAAM,YAAW,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,oBAAA,CAAA,+BAAA,CAAA,CAAA;CAE/E,OAAO,KAAK,MAAM;CAElB,WAAW,KAAK,MAAM;CAEtB,aAAa,KAAK,MAAM;CACxB,cAAc,KAAK,MAAM;CACzB,gBAAgB,KAAK,MAAM;CAE3B,gBAAgB,KAAK,MAAM;CAEnB,UAA6B,IAAI,kBAAkB;EAClE,yBAAyB,KAAK,kBAAiB;EAC/C,gBAAgB,KAAK,SAAQ;EAC7B,cAAc,UAAU,KAAK,SAAS,IAAI,KAAK;EAC/C,OAAO,UAAU,KAAK,YAAY,KAAK,KAAK;EAC5C,QAAQ,YAAY,KAAK,MAAM,MAAM,OAAO;EAC5C,iBAAiB,UAAU,KAAK,MAAM,YAAY,IAAI,KAAK;EAC3D,mBAAmB,KAAK,MAAM,YAAW;CAC1C,CAAA;CAEgB,WAA+B,IAAI,mBAAmB,KAAK,eAAe;EACzF,kBAAkB,KAAK,MAAM;EAC7B,eAAe,KAAK,WAAU,CAAE,CAAC;EACjC,gBAAgB,KAAK,MAAM,SAAQ;EACnC,4BAA4B,KAAK,qBAAoB;EACrD,YAAY,KAAK,MAAM,KAAI;EAC3B,mBAAmB,SAAS,KAAK,MAAM,cAAc,IAAI,IAAI;EAC7D,+BAA+B,KAAK,UAAU,kBAAiB;EAC/D,0BAA0B,KAAK,UAAU,mBAAkB;CAC5D,CAAA;CAEgB,YAAiC,IAAI,oBAAoB,KAAK,eAAe;EAC5F,kBAAkB,KAAK,MAAM;EAC7B,mBAAmB,KAAK,SAAS,YAAW;EAC5C,iBAAiB,UAAU,KAAK,MAAM,YAAY,IAAI,KAAK;EAC3D,mBAAmB,UAAU,KAAK,MAAM,cAAc,IAAI,KAAK;CAChE,CAAA;CAEgB,QAA2B,IAAI,kBAC9C,KAAK,SACL,KAAK,kBACL,KAAK,UACL,KAAK,WACL;EACE,YAAY,KAAK,MAAM,KAAI;EAC3B,yBAAyB,KAAK,kBAAiB;EAC/C,eAAe,KAAK,WAAU,CAAE,CAAC;EACjC,qBAAqB,KAAK,cAAa;EACvC,iBACE,uBAAuB,KAAK,IAAG,GAAI,KAAK,KAAK,eAAe,KAAK,cAAc;EACjF,4BAA4B,KAAK,qBAAoB;EACrD,UAAU,UAAU,KAAK,MAAM,KAAK,IAAI,KAAK;EAC7C,cAAc,OAAO,KAAK,MAAM,SAAS,IAAI,EAAE;EAC/C,gBAAgB,QAAQ,KAAK,MAAM,WAAW,IAAI,GAAG;EACrD,wBAAwB,KAAK,SAAS,iBAAgB;EACtD,mBAAmB,KAAK,QAAQ,YAAW;EAC3C,iBAAiB,UAAU,KAAK,MAAM,YAAY,IAAI,KAAK;EAC3D,mBAAmB,UAAU,KAAK,MAAM,cAAc,IAAI,KAAK;CAChE,CAAA;CAGc,WAA+B,IAAI,mBAAmB,KAAK,UAAU;EACpF,kBAAkB,KAAK,MAAM;EAC7B,mBAAmB,KAAK,MAAM,YAAW;EACzC,gBAAgB,KAAK,SAAQ;EAC7B,gBAAgB,KAAK,MAAM,SAAQ;EACnC,YAAY,KAAK,MAAM,KAAI;EAC3B,eAAe,KAAK,KAAK;EACzB,kBAAkB,KAAK,MAAM;EAC7B,iBAAiB,KAAK,MAAM,UAAS;EACrC,QAAQ,YAAY,KAAK,MAAM,MAAM,OAAO;EAC5C,mBAAmB,KAAK,QAAQ,YAAW;EAC3C,kBAAkB,UAAU,KAAK,QAAQ,gBAAgB,KAAK;EAC9D,cAAc,OAAO,KAAK,MAAM,SAAS,IAAI,EAAE;CAChD,CAAA;CAED,cAAA;EACE,qBAAqB;GACnB,6BAA6B,KAAK,QAAQ,sBAAqB;GAC/D,8BAA8B,KAAK,SAAS,uBAAsB;GAClE,yBAAyB,KAAK,kBAAiB;GAC/C,YAAY,KAAK,MAAM,KAAI;GAC3B,QAAQ,YAAY,KAAK,MAAM,MAAM,OAAO;EAC7C,CAAA;CACH;CAEA,WAAQ;EACN,KAAK,SAAS,KAAI;CACpB;CAEA,cAAW;EACT,KAAK,SAAS,QAAO;EACrB,KAAK,MAAM,QAAO;CACpB;CAGA,WAAW,OAAc;EACvB,KAAK,QAAQ,WAAW,KAAK;CAC/B;CAEA,iBAAiB,IAAkC;EACjD,KAAK,QAAQ,iBAAiB,EAAE;CAClC;CAEA,kBAAkB,IAAc;EAC9B,KAAK,QAAQ,kBAAkB,EAAE;CACnC;CAGA,iBAAiB,YAAmB;EAClC,KAAK,QAAQ,iBAAiB,UAAU;CAC1C;CAGA,SAAM;EACJ,IAAI,KAAK,KAAI,GACX,KAAK,MAAM,IAAI;OAEf,KAAK,UAAS;CAElB;CAGA,iBAAiB,OAAoB;EACnC,KAAK,SAAS,iBAAiB,KAAK;CACtC;CAGA,cAAc,OAAiB;EAC7B,KAAK,SAAS,cAAc,KAAK;CACnC;CAEA,cAAc,QAAwB;EACpC,KAAK,QAAQ,cAAc,MAAM;CACnC;CAGA,oBAAoB,MAA0B;EAC5C,KAAK,SAAS,oBAAoB,IAAI;CACxC;CAGA,qBAAqB,OAAmB;EACtC,KAAK,SAAS,qBAAqB,KAAK;CAC1C;CAEA,aAAa,WAAwB;EACnC,KAAK,UAAU,aAAa,SAAS;CACvC;CAEA,gBAAgB,WAAwB;EACtC,KAAK,UAAU,gBAAgB,SAAS;CAC1C;CAEA,iBAAc;EACZ,KAAK,UAAU,eAAc;CAC/B;CAEQ,YAAS;EACf,KAAK,MAAM,UAAS;CACtB;CAEQ,MAAM,SAAgB;EAC5B,KAAK,MAAM,MAAM,OAAO;CAC1B;CA7OW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAU,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAV,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAU,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,aAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,sBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,KAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,YAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,aAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,SAAA,EAAA,aAAA,cAAA;EAAA,MAAA;GAAA,YAAA;IAAA,2BAAA;IAAA,0BAAA;IAAA,uBAAA;GAAA;GAAA,gBAAA;EAAA;EAAA,WAfV,CAET;GACE,SAAS;GACT,aAAa,iBAAiB,UAAU;GACxC,OAAO;EACR,CACF;EAAA,aAAA,CAAA;GAAA,cAAA;GAAA,OAAA;GAAA,WAAA,CAAA,SAAA;GAAA,aAAA;GAAA,UAAA;EAAA,GAAA;GAAA,cAAA;GAAA,OAAA;GAAA,WAAA,CAAA,OAAA;GAAA,aAAA;GAAA,MAsBO;GAAW,UAAA;EAAA,CAAA;EAAA,UAAA;EAAA,UCpFrB;EAuKA,QAAA,CAAA,u4KAAA;EAAA,cAAA,CAAA;GAAA,MAAA;GAAA,MDpHY;GAAgB,UAAA;GAAA,QAAA;IAAA;IAAA;IAAA;GAAA;EAAA,CAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAmBf,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAU,YAAA,CAAA;EArBtB,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAa,SACd,CAAC,gBAAgB;GAAC,iBAGV,wBAAwB;GAAM,WACpC,CAET;IACE,SAAS;IACT,aAAa,iBAAgB,UAAW;IACxC,OAAO;GACR,CACF;GAAA,MACK;IACJ,OAAO;IACP,6BAA6B;IAC7B,4BAA4B;IAC5B,yBAAyB;GAC1B;GAAA,UAAA;GAAA,QAAA,CAAA,u4KAAA;EAAA,CAAA;CAa+E,CAAA;CAAA,sBAAA,CAAA;CAAA,gBAAA;EAAA,YAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,WAAS,EAAA,UAAA,KAAA,CAAA;EAAA,CAAA;EAAA,eAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAErC,SAAO;IACzD,MAAM;IACP,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,OAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,OAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,aAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,aAAA;EAAA,CAAA;EAAA,UAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,aAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,sBAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,KAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,OAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,YAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,aAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;CAAA;AAAA,CAAA"}
@@ -0,0 +1,103 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, booleanAttribute, computed, input } from "@angular/core";
3
+ var RaqmSeparator = class RaqmSeparator {
4
+ horizontal = input(false, {
5
+ ...ngDevMode ? { debugName: "horizontal" } : /* istanbul ignore next */ {},
6
+ transform: booleanAttribute
7
+ });
8
+ vertical = input(false, {
9
+ ...ngDevMode ? { debugName: "vertical" } : /* istanbul ignore next */ {},
10
+ transform: booleanAttribute
11
+ });
12
+ orientation = computed(() => {
13
+ const vertical = this.vertical();
14
+ if (this.horizontal() && vertical) throw new Error("raqm-separator: use either horizontal or vertical, not both.");
15
+ return vertical ? "vertical" : "horizontal";
16
+ }, ...ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []);
17
+ static ɵfac = i0.ɵɵngDeclareFactory({
18
+ minVersion: "12.0.0",
19
+ version: "22.2.2",
20
+ ngImport: i0,
21
+ type: RaqmSeparator,
22
+ deps: [],
23
+ target: i0.ɵɵFactoryTarget.Component
24
+ });
25
+ static ɵcmp = i0.ɵɵngDeclareComponent({
26
+ minVersion: "17.1.0",
27
+ version: "22.2.2",
28
+ type: RaqmSeparator,
29
+ isStandalone: true,
30
+ selector: "raqm-separator",
31
+ inputs: {
32
+ horizontal: {
33
+ classPropertyName: "horizontal",
34
+ publicName: "horizontal",
35
+ isSignal: true,
36
+ isRequired: false,
37
+ transformFunction: null
38
+ },
39
+ vertical: {
40
+ classPropertyName: "vertical",
41
+ publicName: "vertical",
42
+ isSignal: true,
43
+ isRequired: false,
44
+ transformFunction: null
45
+ }
46
+ },
47
+ host: {
48
+ attributes: { "role": "separator" },
49
+ properties: {
50
+ "attr.data-raqm-vertical": "orientation() === \"vertical\" ? \"\" : null",
51
+ "attr.aria-orientation": "orientation()"
52
+ },
53
+ classAttribute: "raqm-separator"
54
+ },
55
+ ngImport: i0,
56
+ template: "",
57
+ isInline: true,
58
+ styles: [":host{display:block;flex-shrink:0;background-color:var(--raqm-border)}:host(:not([data-raqm-vertical])){inline-size:100%;block-size:1px}:host([data-raqm-vertical]){inline-size:1px;block-size:auto;align-self:stretch}\n"],
59
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
60
+ });
61
+ };
62
+ i0.ɵɵngDeclareClassMetadata({
63
+ minVersion: "12.0.0",
64
+ version: "22.2.2",
65
+ ngImport: i0,
66
+ type: RaqmSeparator,
67
+ decorators: [{
68
+ type: Component,
69
+ args: [{
70
+ selector: "raqm-separator",
71
+ template: "",
72
+ changeDetection: ChangeDetectionStrategy.OnPush,
73
+ host: {
74
+ class: "raqm-separator",
75
+ "[attr.data-raqm-vertical]": "orientation() === \"vertical\" ? \"\" : null",
76
+ "[attr.aria-orientation]": "orientation()",
77
+ role: "separator"
78
+ },
79
+ styles: [":host{display:block;flex-shrink:0;background-color:var(--raqm-border)}:host(:not([data-raqm-vertical])){inline-size:100%;block-size:1px}:host([data-raqm-vertical]){inline-size:1px;block-size:auto;align-self:stretch}\n"]
80
+ }]
81
+ }],
82
+ propDecorators: {
83
+ horizontal: [{
84
+ type: i0.Input,
85
+ args: [{
86
+ isSignal: true,
87
+ alias: "horizontal",
88
+ required: false
89
+ }]
90
+ }],
91
+ vertical: [{
92
+ type: i0.Input,
93
+ args: [{
94
+ isSignal: true,
95
+ alias: "vertical",
96
+ required: false
97
+ }]
98
+ }]
99
+ }
100
+ });
101
+ export { RaqmSeparator };
102
+
103
+ //# sourceMappingURL=raqm-ui-separator.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raqm-ui-separator.mjs","names":[],"sources":["../../../projects/ui/separator/separator.ts"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n booleanAttribute,\r\n computed,\r\n input,\r\n} from '@angular/core';\r\n\r\n/** Raqm separator — a one-pixel semantic divider; neither axis attribute means horizontal. */\r\n@Component({\r\n selector: 'raqm-separator',\r\n template: '',\r\n styles: [\r\n `\r\n :host {\r\n display: block;\r\n flex-shrink: 0;\r\n background-color: var(--raqm-border);\r\n }\r\n\r\n :host(:not([data-raqm-vertical])) {\r\n inline-size: 100%;\r\n block-size: 1px;\r\n }\r\n\r\n :host([data-raqm-vertical]) {\r\n inline-size: 1px;\r\n block-size: auto;\r\n align-self: stretch;\r\n }\r\n `,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'raqm-separator',\r\n '[attr.data-raqm-vertical]': 'orientation() === \"vertical\" ? \"\" : null',\r\n '[attr.aria-orientation]': 'orientation()',\r\n role: 'separator',\r\n },\r\n})\r\nexport class RaqmSeparator {\r\n readonly horizontal = input(false, { transform: booleanAttribute });\r\n readonly vertical = input(false, { transform: booleanAttribute });\r\n\r\n /** The resolved axis; setting both attributes throws. */\r\n protected readonly orientation = computed<'horizontal' | 'vertical'>(() => {\r\n const vertical = this.vertical();\r\n if (this.horizontal() && vertical) {\r\n throw new Error('raqm-separator: use either horizontal or vertical, not both.');\r\n }\r\n return vertical ? 'vertical' : 'horizontal';\r\n });\r\n}\r\n"],"mappings":";;AAwCA,IAAa,gBAAb,MAAa,cAAa;CACf,aAAa,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,aAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CACvD,WAAW,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CAG3C,cAAc,eAAyC;EACxE,MAAM,WAAW,KAAK,SAAQ;EAC9B,IAAI,KAAK,WAAU,KAAM,UACvB,MAAM,IAAI,MAAM,8DAA8D;EAEhF,OAAO,WAAW,aAAa;CACjC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAXS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAa,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAb,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAa,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,YAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,MAAA;GAAA,YAAA,EAAA,QAAA,YAAA;GAAA,YAAA;IAAA,2BAAA;IAAA,yBAAA;GAAA;GAAA,gBAAA;EAAA;EAAA,UAAA;EAAA,UA7Bd;EAAE,UAAA;EAAA,QAAA,CAAA,2NAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AA6BD,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAa,YAAA,CAAA;EA/BzB,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAgB,UAChB;GAAE,iBAqBK,wBAAwB;GAAM,MACzC;IACJ,OAAO;IACP,6BAA6B;IAC7B,2BAA2B;IAC3B,MAAM;GACP;GAAA,QAAA,CAAA,2NAAA;EAAA,CAAA"}