ngwr 14.8.0 → 14.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -332
- package/alert/styles/_index.scss +10 -0
- package/avatar/styles/_index.scss +18 -7
- package/badge/styles/_index.scss +7 -0
- package/badge/styles/_tag.scss +7 -1
- package/button/styles/_index.scss +6 -0
- package/cascader/styles/_rules.scss +1 -1
- package/checkbox/styles/_index.scss +4 -0
- package/command-palette/styles/_index.scss +1 -1
- package/divider/styles/_index.scss +2 -0
- package/editor/styles/_index.scss +441 -0
- package/fesm2022/ngwr-action-sheet-testing.mjs.map +1 -1
- package/fesm2022/ngwr-action-sheet.mjs +3 -3
- package/fesm2022/ngwr-action-sheet.mjs.map +1 -1
- package/fesm2022/ngwr-affix.mjs +3 -3
- package/fesm2022/ngwr-affix.mjs.map +1 -1
- package/fesm2022/ngwr-alert.mjs +3 -3
- package/fesm2022/ngwr-alert.mjs.map +1 -1
- package/fesm2022/ngwr-anchor.mjs +3 -3
- package/fesm2022/ngwr-anchor.mjs.map +1 -1
- package/fesm2022/ngwr-aurora.mjs +3 -3
- package/fesm2022/ngwr-aurora.mjs.map +1 -1
- package/fesm2022/ngwr-avatar.mjs +3 -3
- package/fesm2022/ngwr-avatar.mjs.map +1 -1
- package/fesm2022/ngwr-back-top.mjs +3 -3
- package/fesm2022/ngwr-back-top.mjs.map +1 -1
- package/fesm2022/ngwr-badge.mjs +28 -13
- package/fesm2022/ngwr-badge.mjs.map +1 -1
- package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-bar-chart.mjs +3 -3
- package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
- package/fesm2022/ngwr-blur-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-blur-text.mjs +3 -3
- package/fesm2022/ngwr-blur-text.mjs.map +1 -1
- package/fesm2022/ngwr-border-glow-testing.mjs.map +1 -1
- package/fesm2022/ngwr-border-glow.mjs +3 -3
- package/fesm2022/ngwr-border-glow.mjs.map +1 -1
- package/fesm2022/ngwr-breadcrumbs.mjs +6 -6
- package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
- package/fesm2022/ngwr-burger.mjs +3 -3
- package/fesm2022/ngwr-burger.mjs.map +1 -1
- package/fesm2022/ngwr-button-testing.mjs.map +1 -1
- package/fesm2022/ngwr-button.mjs +6 -6
- package/fesm2022/ngwr-button.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-heatmap.mjs +3 -3
- package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
- package/fesm2022/ngwr-calendar.mjs +3 -3
- package/fesm2022/ngwr-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-card.mjs +9 -9
- package/fesm2022/ngwr-card.mjs.map +1 -1
- package/fesm2022/ngwr-carousel-testing.mjs.map +1 -1
- package/fesm2022/ngwr-carousel.mjs +6 -6
- package/fesm2022/ngwr-carousel.mjs.map +1 -1
- package/fesm2022/ngwr-cascader-testing.mjs.map +1 -1
- package/fesm2022/ngwr-cascader.mjs +4 -4
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox.mjs +6 -6
- package/fesm2022/ngwr-checkbox.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text.mjs +3 -3
- package/fesm2022/ngwr-circular-text.mjs.map +1 -1
- package/fesm2022/ngwr-click-spark.mjs +3 -3
- package/fesm2022/ngwr-click-spark.mjs.map +1 -1
- package/fesm2022/ngwr-clipboard.mjs +3 -3
- package/fesm2022/ngwr-clipboard.mjs.map +1 -1
- package/fesm2022/ngwr-collapse-testing.mjs.map +1 -1
- package/fesm2022/ngwr-collapse.mjs +9 -9
- package/fesm2022/ngwr-collapse.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker.mjs +6 -6
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-command-palette-testing.mjs.map +1 -1
- package/fesm2022/ngwr-command-palette.mjs +3 -3
- package/fesm2022/ngwr-command-palette.mjs.map +1 -1
- package/fesm2022/ngwr-compare.mjs +3 -3
- package/fesm2022/ngwr-compare.mjs.map +1 -1
- package/fesm2022/ngwr-confetti.mjs +3 -3
- package/fesm2022/ngwr-confetti.mjs.map +1 -1
- package/fesm2022/ngwr-config.mjs.map +1 -1
- package/fesm2022/ngwr-context-menu-testing.mjs.map +1 -1
- package/fesm2022/ngwr-context-menu.mjs +12 -12
- package/fesm2022/ngwr-context-menu.mjs.map +1 -1
- package/fesm2022/ngwr-cookie.mjs +3 -3
- package/fesm2022/ngwr-cookie.mjs.map +1 -1
- package/fesm2022/ngwr-counter.mjs +6 -6
- package/fesm2022/ngwr-counter.mjs.map +1 -1
- package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
- package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
- package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
- package/fesm2022/ngwr-date-adapters-luxon.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker.mjs +21 -21
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/ngwr-date.mjs +3 -3
- package/fesm2022/ngwr-date.mjs.map +1 -1
- package/fesm2022/ngwr-decrypt-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-decrypt-text.mjs +3 -3
- package/fesm2022/ngwr-decrypt-text.mjs.map +1 -1
- package/fesm2022/ngwr-density.mjs +6 -6
- package/fesm2022/ngwr-density.mjs.map +1 -1
- package/fesm2022/ngwr-descriptions.mjs +6 -6
- package/fesm2022/ngwr-descriptions.mjs.map +1 -1
- package/fesm2022/ngwr-dialog-testing.mjs.map +1 -1
- package/fesm2022/ngwr-dialog.mjs +15 -15
- package/fesm2022/ngwr-dialog.mjs.map +1 -1
- package/fesm2022/ngwr-directives.mjs +12 -12
- package/fesm2022/ngwr-directives.mjs.map +1 -1
- package/fesm2022/ngwr-divider.mjs +3 -3
- package/fesm2022/ngwr-divider.mjs.map +1 -1
- package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-donut-chart.mjs +3 -3
- package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
- package/fesm2022/ngwr-drag-drop.mjs +6 -6
- package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
- package/fesm2022/ngwr-drawer-testing.mjs.map +1 -1
- package/fesm2022/ngwr-drawer.mjs +18 -18
- package/fesm2022/ngwr-drawer.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown-testing.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown.mjs +9 -9
- package/fesm2022/ngwr-dropdown.mjs.map +1 -1
- package/fesm2022/ngwr-editor-testing.mjs +568 -0
- package/fesm2022/ngwr-editor-testing.mjs.map +1 -0
- package/fesm2022/ngwr-editor.mjs +2601 -0
- package/fesm2022/ngwr-editor.mjs.map +1 -0
- package/fesm2022/ngwr-empty.mjs +3 -3
- package/fesm2022/ngwr-empty.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
- package/fesm2022/ngwr-event-calendar.mjs +6 -6
- package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text.mjs +3 -3
- package/fesm2022/ngwr-falling-text.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload-testing.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload.mjs +3 -3
- package/fesm2022/ngwr-file-upload.mjs.map +1 -1
- package/fesm2022/ngwr-form-testing.mjs.map +1 -1
- package/fesm2022/ngwr-form.mjs +9 -9
- package/fesm2022/ngwr-form.mjs.map +1 -1
- package/fesm2022/ngwr-fuzzy-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
- package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
- package/fesm2022/ngwr-gauge-testing.mjs.map +1 -1
- package/fesm2022/ngwr-gauge.mjs +3 -3
- package/fesm2022/ngwr-gauge.mjs.map +1 -1
- package/fesm2022/ngwr-glitch-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-glitch-text.mjs +3 -3
- package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
- package/fesm2022/ngwr-gradient-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-gradient-text.mjs +3 -3
- package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
- package/fesm2022/ngwr-graph-testing.mjs.map +1 -1
- package/fesm2022/ngwr-graph.mjs +6 -6
- package/fesm2022/ngwr-graph.mjs.map +1 -1
- package/fesm2022/ngwr-hotkey.mjs +6 -6
- package/fesm2022/ngwr-hotkey.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ar.mjs +29 -0
- package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-cs.mjs +29 -0
- package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-de.mjs +29 -0
- package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-en.mjs +34 -0
- package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-es.mjs +29 -0
- package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-fr.mjs +29 -0
- package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-he.mjs +29 -0
- package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-hi.mjs +29 -0
- package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-id.mjs +29 -0
- package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-it.mjs +29 -0
- package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ja.mjs +29 -0
- package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ko.mjs +29 -0
- package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-nl.mjs +29 -0
- package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pl.mjs +29 -0
- package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-pt.mjs +29 -0
- package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-ru.mjs +29 -0
- package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-sv.mjs +29 -0
- package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-tr.mjs +29 -0
- package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-uk.mjs +29 -0
- package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-vi.mjs +29 -0
- package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh-TW.mjs +29 -0
- package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
- package/fesm2022/ngwr-i18n-zh.mjs +29 -0
- package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
- package/fesm2022/ngwr-i18n.mjs +9 -9
- package/fesm2022/ngwr-i18n.mjs.map +1 -1
- package/fesm2022/ngwr-icon-adapters-feather.mjs.map +1 -1
- package/fesm2022/ngwr-icon-adapters-lucide.mjs.map +1 -1
- package/fesm2022/ngwr-icon.mjs +6 -6
- package/fesm2022/ngwr-icon.mjs.map +1 -1
- package/fesm2022/ngwr-image-cropper-testing.mjs.map +1 -1
- package/fesm2022/ngwr-image-cropper.mjs +3 -3
- package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
- package/fesm2022/ngwr-input-number-testing.mjs.map +1 -1
- package/fesm2022/ngwr-input-number.mjs +3 -3
- package/fesm2022/ngwr-input-number.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp-testing.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp.mjs +3 -3
- package/fesm2022/ngwr-input-otp.mjs.map +1 -1
- package/fesm2022/ngwr-input-testing.mjs.map +1 -1
- package/fesm2022/ngwr-input.mjs +15 -15
- package/fesm2022/ngwr-input.mjs.map +1 -1
- package/fesm2022/ngwr-keyboard.mjs +3 -3
- package/fesm2022/ngwr-keyboard.mjs.map +1 -1
- package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
- package/fesm2022/ngwr-knob.mjs +3 -3
- package/fesm2022/ngwr-knob.mjs.map +1 -1
- package/fesm2022/ngwr-layout.mjs +15 -15
- package/fesm2022/ngwr-layout.mjs.map +1 -1
- package/fesm2022/ngwr-lightbox-testing.mjs.map +1 -1
- package/fesm2022/ngwr-lightbox.mjs +3 -3
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -1
- package/fesm2022/ngwr-line-chart.mjs +3 -3
- package/fesm2022/ngwr-line-chart.mjs.map +1 -1
- package/fesm2022/ngwr-list.mjs +6 -6
- package/fesm2022/ngwr-list.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar.mjs +6 -6
- package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
- package/fesm2022/ngwr-markdown-testing.mjs.map +1 -1
- package/fesm2022/ngwr-markdown.mjs +798 -17
- package/fesm2022/ngwr-markdown.mjs.map +1 -1
- package/fesm2022/ngwr-marquee-testing.mjs.map +1 -1
- package/fesm2022/ngwr-marquee.mjs +3 -3
- package/fesm2022/ngwr-marquee.mjs.map +1 -1
- package/fesm2022/ngwr-media.mjs +3 -3
- package/fesm2022/ngwr-media.mjs.map +1 -1
- package/fesm2022/ngwr-mention-testing.mjs.map +1 -1
- package/fesm2022/ngwr-mention.mjs +6 -6
- package/fesm2022/ngwr-mention.mjs.map +1 -1
- package/fesm2022/ngwr-meta.mjs +6 -6
- package/fesm2022/ngwr-meta.mjs.map +1 -1
- package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -1
- package/fesm2022/ngwr-meter-group.mjs +3 -3
- package/fesm2022/ngwr-meter-group.mjs.map +1 -1
- package/fesm2022/ngwr-overlay.mjs +6 -6
- package/fesm2022/ngwr-overlay.mjs.map +1 -1
- package/fesm2022/ngwr-page-header.mjs +3 -3
- package/fesm2022/ngwr-page-header.mjs.map +1 -1
- package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
- package/fesm2022/ngwr-pagination.mjs +3 -3
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-pipes.mjs +21 -21
- package/fesm2022/ngwr-pipes.mjs.map +1 -1
- package/fesm2022/ngwr-platform.mjs +9 -9
- package/fesm2022/ngwr-platform.mjs.map +1 -1
- package/fesm2022/ngwr-popconfirm-testing.mjs.map +1 -1
- package/fesm2022/ngwr-popconfirm.mjs +6 -6
- package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
- package/fesm2022/ngwr-popover-testing.mjs.map +1 -1
- package/fesm2022/ngwr-popover.mjs +12 -12
- package/fesm2022/ngwr-popover.mjs.map +1 -1
- package/fesm2022/ngwr-progress.mjs +3 -3
- package/fesm2022/ngwr-progress.mjs.map +1 -1
- package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
- package/fesm2022/ngwr-pull-to-refresh.mjs.map +1 -1
- package/fesm2022/ngwr-qr.mjs +3 -3
- package/fesm2022/ngwr-qr.mjs.map +1 -1
- package/fesm2022/ngwr-radio-testing.mjs.map +1 -1
- package/fesm2022/ngwr-radio.mjs +6 -6
- package/fesm2022/ngwr-radio.mjs.map +1 -1
- package/fesm2022/ngwr-rating-testing.mjs.map +1 -1
- package/fesm2022/ngwr-rating.mjs +3 -3
- package/fesm2022/ngwr-rating.mjs.map +1 -1
- package/fesm2022/ngwr-result.mjs +12 -12
- package/fesm2022/ngwr-result.mjs.map +1 -1
- package/fesm2022/ngwr-rotating-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-rotating-text.mjs +3 -3
- package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
- package/fesm2022/ngwr-schema-form.mjs +3 -3
- package/fesm2022/ngwr-schema-form.mjs.map +1 -1
- package/fesm2022/ngwr-scroll.mjs +3 -3
- package/fesm2022/ngwr-scroll.mjs.map +1 -1
- package/fesm2022/ngwr-segmented-testing.mjs.map +1 -1
- package/fesm2022/ngwr-segmented.mjs +3 -3
- package/fesm2022/ngwr-segmented.mjs.map +1 -1
- package/fesm2022/ngwr-select-testing.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +12 -12
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text.mjs +6 -6
- package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
- package/fesm2022/ngwr-sidebar.mjs +3 -3
- package/fesm2022/ngwr-sidebar.mjs.map +1 -1
- package/fesm2022/ngwr-skeleton.mjs +3 -3
- package/fesm2022/ngwr-skeleton.mjs.map +1 -1
- package/fesm2022/ngwr-slider-testing.mjs.map +1 -1
- package/fesm2022/ngwr-slider.mjs +3 -3
- package/fesm2022/ngwr-slider.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline-testing.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline.mjs +3 -3
- package/fesm2022/ngwr-sparkline.mjs.map +1 -1
- package/fesm2022/ngwr-speed-dial-testing.mjs.map +1 -1
- package/fesm2022/ngwr-speed-dial.mjs +3 -3
- package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
- package/fesm2022/ngwr-spinner.mjs +3 -3
- package/fesm2022/ngwr-spinner.mjs.map +1 -1
- package/fesm2022/ngwr-splash-cursor-testing.mjs.map +1 -1
- package/fesm2022/ngwr-splash-cursor.mjs +3 -3
- package/fesm2022/ngwr-splash-cursor.mjs.map +1 -1
- package/fesm2022/ngwr-split-text-testing.mjs.map +1 -1
- package/fesm2022/ngwr-split-text.mjs +3 -3
- package/fesm2022/ngwr-split-text.mjs.map +1 -1
- package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
- package/fesm2022/ngwr-splitter.mjs +3 -3
- package/fesm2022/ngwr-splitter.mjs.map +1 -1
- package/fesm2022/ngwr-spotlight-card-testing.mjs.map +1 -1
- package/fesm2022/ngwr-spotlight-card.mjs +6 -6
- package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
- package/fesm2022/ngwr-squircle.mjs +6 -6
- package/fesm2022/ngwr-squircle.mjs.map +1 -1
- package/fesm2022/ngwr-star-border-testing.mjs.map +1 -1
- package/fesm2022/ngwr-star-border.mjs +3 -3
- package/fesm2022/ngwr-star-border.mjs.map +1 -1
- package/fesm2022/ngwr-statistic.mjs +9 -9
- package/fesm2022/ngwr-statistic.mjs.map +1 -1
- package/fesm2022/ngwr-stepper-testing.mjs.map +1 -1
- package/fesm2022/ngwr-stepper.mjs +6 -6
- package/fesm2022/ngwr-stepper.mjs.map +1 -1
- package/fesm2022/ngwr-storage.mjs +3 -3
- package/fesm2022/ngwr-storage.mjs.map +1 -1
- package/fesm2022/ngwr-switch-testing.mjs.map +1 -1
- package/fesm2022/ngwr-switch.mjs +3 -3
- package/fesm2022/ngwr-switch.mjs.map +1 -1
- package/fesm2022/ngwr-table-testing.mjs.map +1 -1
- package/fesm2022/ngwr-table.mjs +18 -18
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-tabs-router.mjs +3 -3
- package/fesm2022/ngwr-tabs-router.mjs.map +1 -1
- package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tabs.mjs +6 -6
- package/fesm2022/ngwr-tabs.mjs.map +1 -1
- package/fesm2022/ngwr-textarea-testing.mjs.map +1 -1
- package/fesm2022/ngwr-textarea.mjs +3 -3
- package/fesm2022/ngwr-textarea.mjs.map +1 -1
- package/fesm2022/ngwr-theme.mjs +3 -3
- package/fesm2022/ngwr-theme.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card.mjs +6 -6
- package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
- package/fesm2022/ngwr-timeline.mjs +6 -6
- package/fesm2022/ngwr-timeline.mjs.map +1 -1
- package/fesm2022/ngwr-toast-testing.mjs.map +1 -1
- package/fesm2022/ngwr-toast.mjs +9 -9
- package/fesm2022/ngwr-toast.mjs.map +1 -1
- package/fesm2022/ngwr-toolbar.mjs +3 -3
- package/fesm2022/ngwr-toolbar.mjs.map +1 -1
- package/fesm2022/ngwr-tour-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tour.mjs +6 -6
- package/fesm2022/ngwr-tour.mjs.map +1 -1
- package/fesm2022/ngwr-transfer-testing.mjs.map +1 -1
- package/fesm2022/ngwr-transfer.mjs +3 -3
- package/fesm2022/ngwr-transfer.mjs.map +1 -1
- package/fesm2022/ngwr-tree-testing.mjs.map +1 -1
- package/fesm2022/ngwr-tree.mjs +3 -3
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter-testing.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter.mjs +3 -3
- package/fesm2022/ngwr-typewriter.mjs.map +1 -1
- package/fesm2022/ngwr-typography.mjs +7 -3
- package/fesm2022/ngwr-typography.mjs.map +1 -1
- package/fesm2022/ngwr-utils.mjs.map +1 -1
- package/fesm2022/ngwr-validators.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
- package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
- package/fesm2022/ngwr-waves-testing.mjs.map +1 -1
- package/fesm2022/ngwr-waves.mjs +3 -3
- package/fesm2022/ngwr-waves.mjs.map +1 -1
- package/fesm2022/ngwr-window-testing.mjs.map +1 -1
- package/fesm2022/ngwr-window.mjs +12 -12
- package/fesm2022/ngwr-window.mjs.map +1 -1
- package/form/styles/_index.scss +5 -0
- package/i18n/ar.json +29 -0
- package/i18n/cs.json +29 -0
- package/i18n/de.json +29 -0
- package/i18n/en.json +29 -0
- package/i18n/es.json +29 -0
- package/i18n/fr.json +29 -0
- package/i18n/he.json +29 -0
- package/i18n/hi.json +29 -0
- package/i18n/id.json +29 -0
- package/i18n/it.json +29 -0
- package/i18n/ja.json +29 -0
- package/i18n/ko.json +29 -0
- package/i18n/nl.json +29 -0
- package/i18n/pl.json +29 -0
- package/i18n/pt.json +29 -0
- package/i18n/ru.json +29 -0
- package/i18n/sv.json +29 -0
- package/i18n/tr.json +29 -0
- package/i18n/uk.json +29 -0
- package/i18n/vi.json +29 -0
- package/i18n/zh-TW.json +29 -0
- package/i18n/zh.json +29 -0
- package/input/styles/_index.scss +5 -1
- package/input-otp/styles/_index.scss +5 -5
- package/llms-full.txt +11 -1
- package/llms.txt +188 -132
- package/mcp/providers.js +2 -2
- package/mcp/server.js +1 -1
- package/overlay/styles/_arrow.scss +3 -0
- package/package.json +43 -2
- package/progress/styles/_index.scss +4 -0
- package/radio/styles/_index.scss +4 -1
- package/schematics/use/symbol-map.json +1 -0
- package/select/styles/_index.scss +3 -3
- package/sidebar/styles/_index.scss +10 -0
- package/skeleton/styles/_index.scss +3 -0
- package/skills/ngwr/SKILL.md +5 -5
- package/skills/ngwr/references/catalog.md +2 -0
- package/skills/ngwr/references/setup.md +3 -3
- package/styles.scss +1 -0
- package/table/styles/_index.scss +7 -0
- package/textarea/styles/_index.scss +12 -3
- package/theme/styles/_colors.scss +39 -13
- package/theme/styles/_contrast.scss +9 -7
- package/toast/styles/_index.scss +4 -0
- package/tree/styles/_index.scss +1 -1
- package/types/ngwr-badge.d.ts +22 -7
- package/types/ngwr-config.d.ts +12 -0
- package/types/ngwr-editor-testing.d.ts +378 -0
- package/types/ngwr-editor.d.ts +449 -0
- package/types/ngwr-markdown.d.ts +61 -2
- package/types/ngwr-typography.d.ts +4 -0
- package/types/ngwr-version.d.ts +1 -1
- package/typography/styles/_index.scss +16 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-list.mjs","sources":["../../../projects/lib/list/list.ts","../../../projects/lib/list/list-item.ts","../../../projects/lib/list/list-item.html","../../../projects/lib/list/ngwr-list.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\n/**\n * Generic list container. Renders `<ul role=\"list\">` with optional\n * borders, dividers between items, and dense (compact) padding. Project\n * `<wr-list-item>` children — they pick up the container's settings\n * through CSS cascade, no DI needed.\n *\n * @example\n * ```html\n * <wr-list bordered dividers>\n * <wr-list-item>\n * <wr-icon ngProjectAs=\"[wrListItemLeading]\" name=\"folder\" />\n * Reports\n * <span ngProjectAs=\"[wrListItemTrailing]\">12</span>\n * </wr-list-item>\n * <wr-list-item interactive (click)=\"open(item)\">\n * Click anywhere on this row\n * </wr-list-item>\n * </wr-list>\n * ```\n *\n * @see https://ngwr.dev/reference/components/list\n */\n@Component({\n selector: 'wr-list',\n template: '<ul class=\"wr-list__items\" role=\"list\"><ng-content /></ul>',\n styleUrl: './list.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[attr.aria-label]': 'ariaLabel() || null',\n },\n})\nexport class WrList {\n /** Wrap the list in a card-style border + radius. @default false */\n readonly bordered = input(false, { transform: coerceBooleanProperty });\n\n /** Draw a thin divider between items. @default false */\n readonly dividers = input(false, { transform: coerceBooleanProperty });\n\n /** Use compact padding on every item. @default false */\n readonly dense = input(false, { transform: coerceBooleanProperty });\n\n /** Optional accessible label for the list. */\n readonly ariaLabel = input<string>('');\n\n protected readonly classes = computed(() => {\n const parts = ['wr-list'];\n if (this.bordered()) parts.push('wr-list--bordered');\n if (this.dividers()) parts.push('wr-list--dividers');\n if (this.dense()) parts.push('wr-list--dense');\n return parts.join(' ');\n });\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\n/**\n * Row inside `<wr-list>`. Three projection slots:\n *\n * - `[wrListItemLeading]` — icon, avatar, status dot, etc.\n * - default — main label / body\n * - `[wrListItemTrailing]` — meta value, action button, chevron\n *\n * Set `interactive` to get hover and cursor styles, a tab stop, and Enter /\n * Space activation. The role stays `listitem`: the row lives inside a\n * `<ul role=\"list\">`, where a `button` or `option` child role would break the\n * structure the container promises. That means an interactive row ANNOUNCES as\n * a list item rather than as a control — deliberate, but worth knowing when the\n * whole row is the only way to reach an action. Where the action needs to be\n * announced as one, project a real button into `[wrListItemTrailing]`.\n *\n * @example\n * ```html\n * <wr-list-item>Plain row</wr-list-item>\n *\n * <wr-list-item interactive (click)=\"onPick(item)\">\n * <wr-icon ngProjectAs=\"[wrListItemLeading]\" name=\"folder\" />\n * Reports\n * <span ngProjectAs=\"[wrListItemTrailing]\">12</span>\n * </wr-list-item>\n * ```\n */\n@Component({\n selector: 'wr-list-item',\n templateUrl: './list-item.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n role: 'listitem',\n '[attr.tabindex]': 'interactive() ? \"0\" : null',\n '[attr.aria-disabled]': 'disabled() || null',\n '(keydown.enter)': 'onActivate($event)',\n '(keydown.space)': 'onActivate($event)',\n },\n})\nexport class WrListItem {\n /** Adds hover / cursor styles + keyboard activation. @default false */\n readonly interactive = input(false, { transform: coerceBooleanProperty });\n\n /** Visual disabled state. Suppresses hover + keyboard activation. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-list__item'];\n if (this.interactive()) parts.push('wr-list__item--interactive');\n if (this.disabled()) parts.push('wr-list__item--disabled');\n return parts.join(' ');\n });\n\n protected onActivate(event: Event): void {\n if (!this.interactive() || this.disabled()) return;\n event.preventDefault();\n (event.currentTarget as HTMLElement).click();\n }\n}\n","<span class=\"wr-list__leading\"><ng-content select=\"[wrListItemLeading]\" /></span>\n<span class=\"wr-list__body\"><ng-content /></span>\n<span class=\"wr-list__trailing\"><ng-content select=\"[wrListItemTrailing]\" /></span>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ngwr-list.mjs","sources":["../../../projects/lib/list/list.ts","../../../projects/lib/list/list-item.ts","../../../projects/lib/list/list-item.html","../../../projects/lib/list/ngwr-list.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\n/**\n * Generic list container. Renders `<ul role=\"list\">` with optional\n * borders, dividers between items, and dense (compact) padding. Project\n * `<wr-list-item>` children — they pick up the container's settings\n * through CSS cascade, no DI needed.\n *\n * @example\n * ```html\n * <wr-list bordered dividers>\n * <wr-list-item>\n * <wr-icon ngProjectAs=\"[wrListItemLeading]\" name=\"folder\" />\n * Reports\n * <span ngProjectAs=\"[wrListItemTrailing]\">12</span>\n * </wr-list-item>\n * <wr-list-item interactive (click)=\"open(item)\">\n * Click anywhere on this row\n * </wr-list-item>\n * </wr-list>\n * ```\n *\n * @see https://ngwr.dev/reference/components/list\n */\n@Component({\n selector: 'wr-list',\n template: '<ul class=\"wr-list__items\" role=\"list\"><ng-content /></ul>',\n styleUrl: './list.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[attr.aria-label]': 'ariaLabel() || null',\n },\n})\nexport class WrList {\n /** Wrap the list in a card-style border + radius. @default false */\n readonly bordered = input(false, { transform: coerceBooleanProperty });\n\n /** Draw a thin divider between items. @default false */\n readonly dividers = input(false, { transform: coerceBooleanProperty });\n\n /** Use compact padding on every item. @default false */\n readonly dense = input(false, { transform: coerceBooleanProperty });\n\n /** Optional accessible label for the list. */\n readonly ariaLabel = input<string>('');\n\n protected readonly classes = computed(() => {\n const parts = ['wr-list'];\n if (this.bordered()) parts.push('wr-list--bordered');\n if (this.dividers()) parts.push('wr-list--dividers');\n if (this.dense()) parts.push('wr-list--dense');\n return parts.join(' ');\n });\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\n/**\n * Row inside `<wr-list>`. Three projection slots:\n *\n * - `[wrListItemLeading]` — icon, avatar, status dot, etc.\n * - default — main label / body\n * - `[wrListItemTrailing]` — meta value, action button, chevron\n *\n * Set `interactive` to get hover and cursor styles, a tab stop, and Enter /\n * Space activation. The role stays `listitem`: the row lives inside a\n * `<ul role=\"list\">`, where a `button` or `option` child role would break the\n * structure the container promises. That means an interactive row ANNOUNCES as\n * a list item rather than as a control — deliberate, but worth knowing when the\n * whole row is the only way to reach an action. Where the action needs to be\n * announced as one, project a real button into `[wrListItemTrailing]`.\n *\n * @example\n * ```html\n * <wr-list-item>Plain row</wr-list-item>\n *\n * <wr-list-item interactive (click)=\"onPick(item)\">\n * <wr-icon ngProjectAs=\"[wrListItemLeading]\" name=\"folder\" />\n * Reports\n * <span ngProjectAs=\"[wrListItemTrailing]\">12</span>\n * </wr-list-item>\n * ```\n */\n@Component({\n selector: 'wr-list-item',\n templateUrl: './list-item.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n role: 'listitem',\n '[attr.tabindex]': 'interactive() ? \"0\" : null',\n '[attr.aria-disabled]': 'disabled() || null',\n '(keydown.enter)': 'onActivate($event)',\n '(keydown.space)': 'onActivate($event)',\n },\n})\nexport class WrListItem {\n /** Adds hover / cursor styles + keyboard activation. @default false */\n readonly interactive = input(false, { transform: coerceBooleanProperty });\n\n /** Visual disabled state. Suppresses hover + keyboard activation. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-list__item'];\n if (this.interactive()) parts.push('wr-list__item--interactive');\n if (this.disabled()) parts.push('wr-list__item--disabled');\n return parts.join(' ');\n });\n\n protected onActivate(event: Event): void {\n if (!this.interactive() || this.disabled()) return;\n event.preventDefault();\n (event.currentTarget as HTMLElement).click();\n }\n}\n","<span class=\"wr-list__leading\"><ng-content select=\"[wrListItemLeading]\" /></span>\n<span class=\"wr-list__body\"><ng-content /></span>\n<span class=\"wr-list__trailing\"><ng-content select=\"[wrListItemTrailing]\" /></span>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-loading-bar-router.mjs","sources":["../../../projects/lib/loading-bar/router/provide-wr-loading-bar-router.ts","../../../projects/lib/loading-bar/router/public-api.ts","../../../projects/lib/loading-bar/router/ngwr-loading-bar-router.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n DestroyRef,\n type EnvironmentProviders,\n PLATFORM_ID,\n inject,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n} from '@angular/core';\nimport { NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router';\n\nimport { WrLoadingBar } from 'ngwr/loading-bar';\n\n/**\n * Drive {@link WrLoadingBar} from router navigations: `NavigationStart` takes a\n * slot, and each of `NavigationEnd` / `NavigationCancel` / `NavigationError`\n * releases one.\n *\n * @example\n * ```ts\n * import { provideWrLoadingBarRouter } from 'ngwr/loading-bar/router';\n *\n * bootstrapApplication(App, {\n * providers: [provideRouter(routes), provideWrLoadingBarRouter()],\n * });\n * ```\n *\n * **Why this is a call and not the default.** `WrLoadingBar` used to inject\n * `Router` itself, so navigations drove the bar with no configuration — and\n * every app that rendered `<wr-loading-bar>` paid 66.3 kB of `@angular/router`\n * for it, two thirds of the entry point's total cost, whether or not it had\n * routes. `{ optional: true }` does not help: an optional inject still names the\n * class as the token, and it measured byte-for-byte identical to a required one.\n * An automatic integration and a router-free bundle cannot both exist in a\n * statically linked app, so the automatic half moved here.\n */\nexport function provideWrLoadingBarRouter(): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideEnvironmentInitializer(() => {\n // Browser only. During prerender the initial navigation runs the whole\n // cycle in the Node worker — including the bar's 150 ms interval — and\n // leaves `progress` at 1, because the reset that clears it is deferred and\n // the HTML is serialized first: every prerendered page then ships a\n // full-width bar across the top until hydration.\n if (!isPlatformBrowser(inject(PLATFORM_ID))) return;\n\n const bar = inject(WrLoadingBar);\n const destroyRef = inject(DestroyRef);\n const sub = inject(Router).events.subscribe(event => {\n if (event instanceof NavigationStart) bar.start();\n else if (\n event instanceof NavigationEnd ||\n event instanceof NavigationCancel ||\n event instanceof NavigationError\n ) {\n bar.complete();\n }\n });\n destroyRef.onDestroy(() => sub.unsubscribe());\n }),\n ]);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nexport { provideWrLoadingBarRouter } from './provide-wr-loading-bar-router';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;AAAA;;;;;AAKG;AAeH;;;;;;;;;;;;;;;;;;;;;;AAsBG;SACa,yBAAyB,GAAA;AACvC,IAAA,OAAO,wBAAwB,CAAC;QAC9B,6BAA6B,CAAC,MAAK;;;;;;AAMjC,YAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBAAE;AAE7C,YAAA,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC;AAChC,YAAA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AACrC,YAAA,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,IAAG;gBAClD,IAAI,KAAK,YAAY,eAAe;oBAAE,GAAG,CAAC,KAAK,EAAE;qBAC5C,IACH,KAAK,YAAY,aAAa;AAC9B,oBAAA,KAAK,YAAY,gBAAgB;oBACjC,KAAK,YAAY,eAAe,EAChC;oBACA,GAAG,CAAC,QAAQ,EAAE;gBAChB;AACF,YAAA,CAAC,CAAC;YACF,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;AAC/C,QAAA,CAAC,CAAC;AACH,KAAA,CAAC;AACJ;;ACpEA;;;;;AAKG;;ACLH;;AAEG
|
|
1
|
+
{"version":3,"file":"ngwr-loading-bar-router.mjs","sources":["../../../projects/lib/loading-bar/router/provide-wr-loading-bar-router.ts","../../../projects/lib/loading-bar/router/public-api.ts","../../../projects/lib/loading-bar/router/ngwr-loading-bar-router.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n DestroyRef,\n type EnvironmentProviders,\n PLATFORM_ID,\n inject,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n} from '@angular/core';\nimport { NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router';\n\nimport { WrLoadingBar } from 'ngwr/loading-bar';\n\n/**\n * Drive {@link WrLoadingBar} from router navigations: `NavigationStart` takes a\n * slot, and each of `NavigationEnd` / `NavigationCancel` / `NavigationError`\n * releases one.\n *\n * @example\n * ```ts\n * import { provideWrLoadingBarRouter } from 'ngwr/loading-bar/router';\n *\n * bootstrapApplication(App, {\n * providers: [provideRouter(routes), provideWrLoadingBarRouter()],\n * });\n * ```\n *\n * **Why this is a call and not the default.** `WrLoadingBar` used to inject\n * `Router` itself, so navigations drove the bar with no configuration — and\n * every app that rendered `<wr-loading-bar>` paid 66.3 kB of `@angular/router`\n * for it, two thirds of the entry point's total cost, whether or not it had\n * routes. `{ optional: true }` does not help: an optional inject still names the\n * class as the token, and it measured byte-for-byte identical to a required one.\n * An automatic integration and a router-free bundle cannot both exist in a\n * statically linked app, so the automatic half moved here.\n */\nexport function provideWrLoadingBarRouter(): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideEnvironmentInitializer(() => {\n // Browser only. During prerender the initial navigation runs the whole\n // cycle in the Node worker — including the bar's 150 ms interval — and\n // leaves `progress` at 1, because the reset that clears it is deferred and\n // the HTML is serialized first: every prerendered page then ships a\n // full-width bar across the top until hydration.\n if (!isPlatformBrowser(inject(PLATFORM_ID))) return;\n\n const bar = inject(WrLoadingBar);\n const destroyRef = inject(DestroyRef);\n const sub = inject(Router).events.subscribe(event => {\n if (event instanceof NavigationStart) bar.start();\n else if (\n event instanceof NavigationEnd ||\n event instanceof NavigationCancel ||\n event instanceof NavigationError\n ) {\n bar.complete();\n }\n });\n destroyRef.onDestroy(() => sub.unsubscribe());\n }),\n ]);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nexport { provideWrLoadingBarRouter } from './provide-wr-loading-bar-router';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;AAAA;;;;;AAKG;AAeH;;;;;;;;;;;;;;;;;;;;;;AAsBG;SACa,yBAAyB,GAAA;AACvC,IAAA,OAAO,wBAAwB,CAAC;QAC9B,6BAA6B,CAAC,MAAK;;;;;;AAMjC,YAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBAAE;AAE7C,YAAA,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC;AAChC,YAAA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AACrC,YAAA,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,IAAG;gBAClD,IAAI,KAAK,YAAY,eAAe;oBAAE,GAAG,CAAC,KAAK,EAAE;qBAC5C,IACH,KAAK,YAAY,aAAa;AAC9B,oBAAA,KAAK,YAAY,gBAAgB;oBACjC,KAAK,YAAY,eAAe,EAChC;oBACA,GAAG,CAAC,QAAQ,EAAE;gBAChB;AACF,YAAA,CAAC,CAAC;YACF,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;AAC/C,QAAA,CAAC,CAAC;AACH,KAAA,CAAC;AACJ;;ACpEA;;;;;AAKG;;ACLH;;AAEG;;"}
|
|
@@ -131,10 +131,10 @@ class WrLoadingBar {
|
|
|
131
131
|
this._progress.set(0);
|
|
132
132
|
}, 220);
|
|
133
133
|
}
|
|
134
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
135
|
-
static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.
|
|
134
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrLoadingBar, deps: [], target: i0.ɵɵFactoryTarget.Service });
|
|
135
|
+
static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.7", ngImport: i0, type: WrLoadingBar });
|
|
136
136
|
}
|
|
137
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
137
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrLoadingBar, decorators: [{
|
|
138
138
|
type: Service
|
|
139
139
|
}] });
|
|
140
140
|
|
|
@@ -173,10 +173,10 @@ class WrLoadingBarComponent {
|
|
|
173
173
|
bar = inject(WrLoadingBar);
|
|
174
174
|
active = computed(() => this.bar.state() !== 'idle', /* @ts-ignore */
|
|
175
175
|
...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
|
|
176
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
177
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.
|
|
176
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrLoadingBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
177
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: WrLoadingBarComponent, isStandalone: true, selector: "wr-loading-bar", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-loading-bar" }, ngImport: i0, template: "<div class=\"wr-loading-bar__track\" [class.wr-loading-bar--active]=\"active()\">\n <div\n class=\"wr-loading-bar__fill\"\n [style.width.%]=\"bar.progress() * 100\"\n [style.background]=\"color()\"\n [style.height]=\"height()\"\n ></div>\n</div>\n", styles: [".wr-loading-bar{position:fixed;top:0;inset-inline:0;z-index:var(--wr-z-top, 9999);pointer-events:none}.wr-loading-bar__track{width:100%;overflow:hidden;opacity:0;transition:opacity .2s ease}.wr-loading-bar--active{opacity:1}.wr-loading-bar__fill{width:0;height:2px;background:var(--wr-color-primary);box-shadow:0 0 8px rgb(var(--wr-color-primary-rgb)/60%);transition:width .15s ease-out,opacity .2s ease}\n"], encapsulation: i0.ViewEncapsulation.None });
|
|
178
178
|
}
|
|
179
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
179
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrLoadingBarComponent, decorators: [{
|
|
180
180
|
type: Component,
|
|
181
181
|
args: [{ selector: 'wr-loading-bar', encapsulation: ViewEncapsulation.None, host: { class: 'wr-loading-bar' }, template: "<div class=\"wr-loading-bar__track\" [class.wr-loading-bar--active]=\"active()\">\n <div\n class=\"wr-loading-bar__fill\"\n [style.width.%]=\"bar.progress() * 100\"\n [style.background]=\"color()\"\n [style.height]=\"height()\"\n ></div>\n</div>\n", styles: [".wr-loading-bar{position:fixed;top:0;inset-inline:0;z-index:var(--wr-z-top, 9999);pointer-events:none}.wr-loading-bar__track{width:100%;overflow:hidden;opacity:0;transition:opacity .2s ease}.wr-loading-bar--active{opacity:1}.wr-loading-bar__fill{width:0;height:2px;background:var(--wr-color-primary);box-shadow:0 0 8px rgb(var(--wr-color-primary-rgb)/60%);transition:width .15s ease-out,opacity .2s ease}\n"] }]
|
|
182
182
|
}], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }] } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-loading-bar.mjs","sources":["../../../projects/lib/loading-bar/services/loading-bar.ts","../../../projects/lib/loading-bar/loading-bar.component.ts","../../../projects/lib/loading-bar/loading-bar.component.html","../../../projects/lib/loading-bar/ngwr-loading-bar.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport { Service, PLATFORM_ID, type Signal, computed, inject, signal } from '@angular/core';\n\nimport type { WrLoadingState } from '../interfaces';\n\n/**\n * Singleton state machine for a top-of-page progress indicator: a counter of\n * in-flight tasks and a tween between 0 and 1, driven through `start()` /\n * `complete()`.\n *\n * Pair with `<wr-loading-bar>` to render the bar at the top of your shell.\n *\n * It knows nothing about the router on purpose. Naming `Router` here — even\n * `{ optional: true }`, which is byte-for-byte identical to a required inject —\n * put 66.3 kB of `@angular/router` into every app that rendered the bar,\n * two thirds of what `ngwr/loading-bar` cost and 27× the component's own code.\n * Call `provideWrLoadingBarRouter()` from `ngwr/loading-bar/router` to have\n * navigations drive it.\n *\n * @example\n * ```ts\n * // From an HttpInterceptor:\n * const bar = inject(WrLoadingBar);\n * bar.start();\n * return next(req).pipe(finalize(() => bar.complete()));\n * ```\n *\n * @see https://ngwr.dev/reference/services/loading-bar\n */\n@Service()\nexport class WrLoadingBar {\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /** Live count of pending \"tasks\" (manual + router). */\n private readonly count = signal(0);\n\n /** Tween value `[0, 1]` — the bar's actual width. */\n private readonly _progress = signal(0);\n readonly progress: Signal<number> = this._progress.asReadonly();\n\n readonly state: Signal<WrLoadingState> = computed(() => {\n if (this.count() > 0) return 'running';\n return this._progress() > 0 ? 'completing' : 'idle';\n });\n\n private timer: ReturnType<typeof setInterval> | null = null;\n private holdTimer: ReturnType<typeof setTimeout> | null = null;\n\n /** Reserve a slot. The bar starts trickling as long as `count > 0`. */\n start(): void {\n if (this.count() === 0) this.beginTrickle();\n this.count.update(v => v + 1);\n }\n\n /** Release a slot. When the last one closes, the bar fast-forwards to 100% then resets. */\n complete(): void {\n // Only a call that actually RELEASED something may finish. `Math.max` turns\n // a stray `complete()` into a no-op on the count, but the old code still\n // read the resulting zero as \"the last task just ended\" and flashed the bar\n // to 100% — reachable from a `finalize` that runs twice, or any\n // `complete()` after a `reset()`.\n if (this.count() === 0) return;\n this.count.update(v => v - 1);\n if (this.count() === 0) this.finish();\n }\n\n /** Cancel without animating the bar to 100%. Resets immediately. */\n reset(): void {\n this.count.set(0);\n this.stopTrickle();\n this.clearHold();\n this._progress.set(0);\n }\n\n // Internals\n\n private beginTrickle(): void {\n this.stopTrickle();\n this.clearHold();\n\n // Nothing paints during prerender, so there is nothing to animate. The\n // count still moves — a task really is in flight — but no 150 ms interval\n // is left spinning inside the render worker, and the serialized bar stays\n // at zero width whether or not the task finishes before serialization.\n if (!this.isBrowser) return;\n\n // Unconditionally, not `if (progress === 0)`. A task that starts inside the\n // 220 ms hold found progress at 1, kept it, and then trickled the WRONG WAY:\n // `p + (0.9 - p) * 0.08` approaches 0.9 from above, so the bar sat at ~99%\n // and crept backwards for the whole task. A redirecting route guard hits\n // that window on every navigation.\n this._progress.set(0.08);\n this.timer = setInterval(() => {\n const p = this._progress();\n // Approach 90% asymptotically — we want the user-visible final jump\n // to clearly indicate completion.\n const next = p + (0.9 - p) * 0.08;\n this._progress.set(next);\n }, 150);\n }\n\n private stopTrickle(): void {\n if (this.timer === null) return;\n clearInterval(this.timer);\n this.timer = null;\n }\n\n private clearHold(): void {\n if (this.holdTimer === null) return;\n clearTimeout(this.holdTimer);\n this.holdTimer = null;\n }\n\n private finish(): void {\n this.stopTrickle();\n this.clearHold();\n\n // Nothing animates during prerender and nothing will run the reset before\n // the HTML is serialized, so there is no 100% worth holding — go straight\n // to rest and leave the markup clean.\n if (!this.isBrowser) {\n this._progress.set(0);\n return;\n }\n\n this._progress.set(1);\n // Give the bar a moment to render the final 100% width before resetting.\n // The handle is kept so a later cycle's hold is not cut short by this\n // one's leftover timer.\n this.holdTimer = setTimeout(() => {\n this.holdTimer = null;\n if (this.count() === 0) this._progress.set(0);\n }, 220);\n }\n}\n\nexport type { WrLoadingState } from '../interfaces';\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, inject, input } from '@angular/core';\n\nimport { WrLoadingBar } from './services/loading-bar';\n\n/**\n * Thin progress bar fixed to the top of the viewport.\n *\n * Drop one at the root of your shell. Reads the singleton {@link WrLoadingBar},\n * which is driven manually by `start()` / `complete()` — an HTTP interceptor, a\n * long save, anything with a beginning and an end.\n *\n * Router navigations drive it too, but only once you add\n * `provideWrLoadingBarRouter()` from `ngwr/loading-bar/router`. That is an opt-in\n * because the subscription is what pulls `@angular/router` into the bundle: this\n * component is 2.4 kB of its own code and used to carry 66 kB of router into\n * apps that never routed.\n *\n * @example\n * ```html\n * <wr-loading-bar /> <!-- top, primary color -->\n * <wr-loading-bar color=\"#9b51e0\" height=\"3px\" />\n * ```\n */\n@Component({\n selector: 'wr-loading-bar',\n templateUrl: './loading-bar.component.html',\n styleUrl: './loading-bar.scss',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-loading-bar' },\n})\nexport class WrLoadingBarComponent {\n /** Bar colour. Defaults to the primary brand colour. */\n readonly color = input<string>('var(--wr-color-primary)');\n\n /** Bar height. */\n readonly height = input<string>('2px');\n\n protected readonly bar = inject(WrLoadingBar);\n\n protected readonly active = computed(() => this.bar.state() !== 'idle');\n}\n","<div class=\"wr-loading-bar__track\" [class.wr-loading-bar--active]=\"active()\">\n <div\n class=\"wr-loading-bar__fill\"\n [style.width.%]=\"bar.progress() * 100\"\n [style.background]=\"color()\"\n [style.height]=\"height()\"\n ></div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngwr-loading-bar.mjs","sources":["../../../projects/lib/loading-bar/services/loading-bar.ts","../../../projects/lib/loading-bar/loading-bar.component.ts","../../../projects/lib/loading-bar/loading-bar.component.html","../../../projects/lib/loading-bar/ngwr-loading-bar.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport { Service, PLATFORM_ID, type Signal, computed, inject, signal } from '@angular/core';\n\nimport type { WrLoadingState } from '../interfaces';\n\n/**\n * Singleton state machine for a top-of-page progress indicator: a counter of\n * in-flight tasks and a tween between 0 and 1, driven through `start()` /\n * `complete()`.\n *\n * Pair with `<wr-loading-bar>` to render the bar at the top of your shell.\n *\n * It knows nothing about the router on purpose. Naming `Router` here — even\n * `{ optional: true }`, which is byte-for-byte identical to a required inject —\n * put 66.3 kB of `@angular/router` into every app that rendered the bar,\n * two thirds of what `ngwr/loading-bar` cost and 27× the component's own code.\n * Call `provideWrLoadingBarRouter()` from `ngwr/loading-bar/router` to have\n * navigations drive it.\n *\n * @example\n * ```ts\n * // From an HttpInterceptor:\n * const bar = inject(WrLoadingBar);\n * bar.start();\n * return next(req).pipe(finalize(() => bar.complete()));\n * ```\n *\n * @see https://ngwr.dev/reference/services/loading-bar\n */\n@Service()\nexport class WrLoadingBar {\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /** Live count of pending \"tasks\" (manual + router). */\n private readonly count = signal(0);\n\n /** Tween value `[0, 1]` — the bar's actual width. */\n private readonly _progress = signal(0);\n readonly progress: Signal<number> = this._progress.asReadonly();\n\n readonly state: Signal<WrLoadingState> = computed(() => {\n if (this.count() > 0) return 'running';\n return this._progress() > 0 ? 'completing' : 'idle';\n });\n\n private timer: ReturnType<typeof setInterval> | null = null;\n private holdTimer: ReturnType<typeof setTimeout> | null = null;\n\n /** Reserve a slot. The bar starts trickling as long as `count > 0`. */\n start(): void {\n if (this.count() === 0) this.beginTrickle();\n this.count.update(v => v + 1);\n }\n\n /** Release a slot. When the last one closes, the bar fast-forwards to 100% then resets. */\n complete(): void {\n // Only a call that actually RELEASED something may finish. `Math.max` turns\n // a stray `complete()` into a no-op on the count, but the old code still\n // read the resulting zero as \"the last task just ended\" and flashed the bar\n // to 100% — reachable from a `finalize` that runs twice, or any\n // `complete()` after a `reset()`.\n if (this.count() === 0) return;\n this.count.update(v => v - 1);\n if (this.count() === 0) this.finish();\n }\n\n /** Cancel without animating the bar to 100%. Resets immediately. */\n reset(): void {\n this.count.set(0);\n this.stopTrickle();\n this.clearHold();\n this._progress.set(0);\n }\n\n // Internals\n\n private beginTrickle(): void {\n this.stopTrickle();\n this.clearHold();\n\n // Nothing paints during prerender, so there is nothing to animate. The\n // count still moves — a task really is in flight — but no 150 ms interval\n // is left spinning inside the render worker, and the serialized bar stays\n // at zero width whether or not the task finishes before serialization.\n if (!this.isBrowser) return;\n\n // Unconditionally, not `if (progress === 0)`. A task that starts inside the\n // 220 ms hold found progress at 1, kept it, and then trickled the WRONG WAY:\n // `p + (0.9 - p) * 0.08` approaches 0.9 from above, so the bar sat at ~99%\n // and crept backwards for the whole task. A redirecting route guard hits\n // that window on every navigation.\n this._progress.set(0.08);\n this.timer = setInterval(() => {\n const p = this._progress();\n // Approach 90% asymptotically — we want the user-visible final jump\n // to clearly indicate completion.\n const next = p + (0.9 - p) * 0.08;\n this._progress.set(next);\n }, 150);\n }\n\n private stopTrickle(): void {\n if (this.timer === null) return;\n clearInterval(this.timer);\n this.timer = null;\n }\n\n private clearHold(): void {\n if (this.holdTimer === null) return;\n clearTimeout(this.holdTimer);\n this.holdTimer = null;\n }\n\n private finish(): void {\n this.stopTrickle();\n this.clearHold();\n\n // Nothing animates during prerender and nothing will run the reset before\n // the HTML is serialized, so there is no 100% worth holding — go straight\n // to rest and leave the markup clean.\n if (!this.isBrowser) {\n this._progress.set(0);\n return;\n }\n\n this._progress.set(1);\n // Give the bar a moment to render the final 100% width before resetting.\n // The handle is kept so a later cycle's hold is not cut short by this\n // one's leftover timer.\n this.holdTimer = setTimeout(() => {\n this.holdTimer = null;\n if (this.count() === 0) this._progress.set(0);\n }, 220);\n }\n}\n\nexport type { WrLoadingState } from '../interfaces';\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, inject, input } from '@angular/core';\n\nimport { WrLoadingBar } from './services/loading-bar';\n\n/**\n * Thin progress bar fixed to the top of the viewport.\n *\n * Drop one at the root of your shell. Reads the singleton {@link WrLoadingBar},\n * which is driven manually by `start()` / `complete()` — an HTTP interceptor, a\n * long save, anything with a beginning and an end.\n *\n * Router navigations drive it too, but only once you add\n * `provideWrLoadingBarRouter()` from `ngwr/loading-bar/router`. That is an opt-in\n * because the subscription is what pulls `@angular/router` into the bundle: this\n * component is 2.4 kB of its own code and used to carry 66 kB of router into\n * apps that never routed.\n *\n * @example\n * ```html\n * <wr-loading-bar /> <!-- top, primary color -->\n * <wr-loading-bar color=\"#9b51e0\" height=\"3px\" />\n * ```\n */\n@Component({\n selector: 'wr-loading-bar',\n templateUrl: './loading-bar.component.html',\n styleUrl: './loading-bar.scss',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-loading-bar' },\n})\nexport class WrLoadingBarComponent {\n /** Bar colour. Defaults to the primary brand colour. */\n readonly color = input<string>('var(--wr-color-primary)');\n\n /** Bar height. */\n readonly height = input<string>('2px');\n\n protected readonly bar = inject(WrLoadingBar);\n\n protected readonly active = computed(() => this.bar.state() !== 'idle');\n}\n","<div class=\"wr-loading-bar__track\" [class.wr-loading-bar--active]=\"active()\">\n <div\n class=\"wr-loading-bar__fill\"\n [style.width.%]=\"bar.progress() * 100\"\n [style.background]=\"color()\"\n [style.height]=\"height()\"\n ></div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngwr-markdown-testing.mjs","sources":["../../../projects/lib/markdown/testing/wr-markdown-code-block-harness.ts","../../../projects/lib/markdown/testing/wr-markdown-harness-text.ts","../../../projects/lib/markdown/testing/wr-markdown-harness.ts","../../../projects/lib/markdown/testing/ngwr-markdown-testing.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\n\nimport type { WrMarkdownCodeBlockHarnessFilters } from './interfaces';\n\n/**\n * Test harness for one fenced code block of a `<wr-markdown>` document.\n *\n * A block of its own rather than a field on the document harness, because it is\n * the one piece of rendered markdown that has BEHAVIOUR: it carries a language, it\n * may or may not be coloured yet, and it may offer a copy button — three states\n * that belong to the block and not to the page it is on.\n *\n * Its host is the `.wr-markdown__code-block` wrapper, which is what holds the\n * `<pre>` and the copy button together. Blocks nested inside a quote or a list item\n * are blocks too, and this harness finds them: `<wr-markdown>` renders them the\n * same way, and the copy affordance is theirs as well.\n *\n * @example\n * ```ts\n * const block = await (await loader.getHarness(WrMarkdownHarness)).getCodeBlock({ language: 'ts' });\n *\n * expect(await block.getCode()).toBe('const a = 1;');\n * await block.copy();\n * ```\n *\n * @see https://ngwr.dev/reference/components/markdown\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrMarkdownCodeBlockHarness extends ComponentHarness {\n static hostSelector = '.wr-markdown__code-block';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrMarkdownCodeBlockHarnessFilters = {}): HarnessPredicate<WrMarkdownCodeBlockHarness> {\n return new HarnessPredicate(WrMarkdownCodeBlockHarness, options)\n .addOption('language', options.language, (harness, language) =>\n HarnessPredicate.stringMatches(harness.getLanguage(), language)\n )\n .addOption('code', options.code, (harness, code) => HarnessPredicate.stringMatches(harness.getCode(), code));\n }\n\n private readonly pre = this.locatorFor('pre.wr-markdown__pre');\n private readonly code = this.locatorFor('code.wr-markdown__code');\n private readonly copyButton = this.locatorForOptional('button.wr-markdown__copy');\n\n /**\n * The block's language — the info string's first word, lowercased — or `null` for\n * a bare fence.\n *\n * Read from `data-language`, which is the only place it reaches the DOM, and the\n * reason it is there at all: a highlighter picks a grammar by it, and the\n * showcase's markdown export needs it to re-fence the block. `null` is a real\n * answer, not a gap: a bare fence names no grammar, so nothing is ever asked to\n * colour it.\n */\n async getLanguage(): Promise<string | null> {\n return (await this.code()).getAttribute('data-language');\n }\n\n /**\n * The block's code, EXACTLY — every space, every blank line, every newline.\n *\n * Nothing is collapsed here, unlike every prose read on the document harness,\n * and it is read off the `<pre>` rather than off the host so the copy button is\n * not part of the answer. Two failures live in this one string. Angular strips\n * whitespace-only text nodes from templates, so the code has to arrive as an\n * interpolation — a template that types it instead loses the indentation. And a\n * HIGHLIGHTED block is not one text node but a span per token: what separates its\n * lines is a real `\\n` interpolated between them, so a spec that only ever\n * asserts the unhighlighted case would not notice a highlighted block copying out\n * as one run-together line.\n */\n async getCode(): Promise<string> {\n return (await (await this.pre()).getProperty<string | null>('textContent')) ?? '';\n }\n\n /**\n * Whether the block is coloured right now.\n *\n * A block is plain text until a highlighter answers for it, and that is the\n * intended order rather than a compromise: a grammar engine loads WASM, and\n * blocking on it would leave the reader with an empty box instead of their code.\n * So this is `false` with no `WR_MARKDOWN_HIGHLIGHTER` provided, `false` for a\n * language the highlighter declined or threw on, `false` under SSR — a\n * highlighter resolving after prerender cannot contribute to the HTML — and\n * `false` for the first render of an async one.\n */\n async isHighlighted(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-markdown__line')()) !== null;\n }\n\n /**\n * Whether this block offers a copy button.\n *\n * Two conditions, and both are the component's policy rather than an accident:\n * `copyable` has to be on (bound, or defaulted through\n * `provideWrConfig({ markdown: { copyable: true } })`), and the fence has to be\n * CLOSED. Mid-stream a block's code is not all there, and a button that copies\n * half a snippet is worse than no button.\n */\n async canCopy(): Promise<boolean> {\n return (await this.copyButton()) !== null;\n }\n\n /**\n * The copy button's accessible name, or `null` when there is no button.\n *\n * Worth reading rather than assuming, because it is the whole of the copy\n * feedback: the button swaps its label — and its icon — for the \"copied\" one for\n * two seconds after a successful write, and both strings come from the i18n\n * catalog (`markdown.copy` / `markdown.copied`) or the matching inputs. Which is\n * also why this harness reports the name instead of a `isCopied()` boolean: only\n * the consuming app knows which of its own two strings means which.\n */\n async getCopyLabel(): Promise<string | null> {\n const button = await this.copyButton();\n return button ? button.getAttribute('aria-label') : null;\n }\n\n /**\n * Copy the block, the way a pointer does.\n *\n * Throws when there is no button, naming both reasons — a silent no-op here\n * surfaces as an empty clipboard assertion several lines later. Note what a\n * successful click needs from the environment: the directive behind the button\n * writes through `navigator.clipboard`, which jsdom does not implement at all, so\n * a unit test has to stand one in before the write can succeed and the label can\n * swap.\n */\n async copy(): Promise<void> {\n const button = await this.copyButton();\n if (!button) {\n throw new Error(\n 'WrMarkdownCodeBlockHarness.copy(): this block has no copy button. Either `copyable` is off — it ' +\n 'falls back to `markdown.copyable` from provideWrConfig(), then to false — or the fence is still ' +\n 'open, and <wr-markdown> only offers one on a CLOSED block.'\n );\n }\n await button.click();\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\n/**\n * Collapse the whitespace of a prose read to the line a reader sees.\n *\n * `TestElement.text()` only trims the ends, and markdown prose is never one text\n * node: a paragraph is text spliced with `<strong>`, `<code>` and `<a>`, and a\n * SOFT line break inside it is rendered as a real `\\n` — the parser keeps it as\n * whitespace and lets CSS collapse it, which is what CommonMark asks for. Reading\n * `textContent` raw therefore reports a paragraph the author wrote on three lines\n * as three lines, while the browser shows one; every run becomes a single space so\n * a spec can assert what is on screen.\n *\n * Deliberately NOT used on a code block. There the whitespace IS the content —\n * indentation, blank lines, the newlines between highlighted lines — so\n * `WrMarkdownCodeBlockHarness.getCode()` reads it exactly and this function never\n * touches it.\n */\nexport function wrMarkdownHarnessText(text: string): string {\n return text.replace(/\\s+/g, ' ').trim();\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate, type TestElement } from '@angular/cdk/testing';\n\nimport type {\n WrMarkdownCodeBlockHarnessFilters,\n WrMarkdownHarnessAlign,\n WrMarkdownHarnessFilters,\n WrMarkdownHarnessHeading,\n WrMarkdownHarnessImage,\n WrMarkdownHarnessLink,\n WrMarkdownHarnessTable,\n WrMarkdownHarnessTaskItem,\n} from './interfaces';\nimport { WrMarkdownCodeBlockHarness } from './wr-markdown-code-block-harness';\nimport { wrMarkdownHarnessText } from './wr-markdown-harness-text';\n\n/**\n * The task-state label — hidden from the page, read out in front of the item.\n *\n * Left out of every prose read here, so a spec asserting an item's text does not\n * have to know that `'Done: '` is spliced in front of it. It is not lost: it is a\n * field of its own on {@link WrMarkdownHarnessTaskItem}, which is where its\n * absence is a failure rather than a nuisance.\n */\nconst SR_ONLY = '.wr-markdown__sr-only';\n\n/** The alignment the renderer wrote as an inline style, if it wrote one. */\nconst TEXT_ALIGN_RE = /text-align:\\s*([a-z]+)/;\n\n/** Every prose read goes through here: collapsed, and without the hidden labels. */\nasync function proseText(element: TestElement): Promise<string> {\n return wrMarkdownHarnessText(await element.text({ exclude: SR_ONLY }));\n}\n\n/**\n * A cell's or a header's alignment, read off the inline `style` attribute.\n *\n * Not through `getCssValue()`, and the difference is not cosmetic: a column the\n * delimiter row said nothing about carries no declaration at all, and computed\n * style answers for it anyway — with whatever the user-agent stylesheet says a\n * `<th>` or a `<td>` is aligned to. That makes \"no alignment\" indistinguishable\n * from `center`, in the one direction that matters (a `<th>` centres by default),\n * and it makes the answer depend on the browser rather than on the document. The\n * attribute is what the component wrote, which is the fact being asserted.\n */\nasync function alignOf(cell: TestElement): Promise<WrMarkdownHarnessAlign> {\n const match = TEXT_ALIGN_RE.exec((await cell.getAttribute('style')) ?? '');\n\n switch (match?.[1]) {\n case 'start':\n return 'start';\n case 'center':\n return 'center';\n case 'end':\n return 'end';\n default:\n return null;\n }\n}\n\n/**\n * One body row of a rendered table.\n *\n * Not exported, and not because rows do not matter: a `TestElement` cannot be\n * queried INTO, so reading one row's own cells needs a harness rooted on that row.\n * Nothing here is drivable — rendered prose is inert — so the row's job is to hand\n * its cells up to {@link WrMarkdownHarness.getTables}, which is where a consumer\n * asserts the whole table in one comparison.\n */\nclass WrMarkdownTableRowReader extends ComponentHarness {\n /** Body rows only: the header row lives in the `<thead>`. */\n static hostSelector = 'tbody tr';\n\n async getCellTexts(): Promise<string[]> {\n const cells = await this.locatorForAll('.wr-markdown__td')();\n return Promise.all(cells.map(cell => proseText(cell)));\n }\n}\n\n/**\n * One rendered task-list item — a harness for the same reason as the row reader.\n *\n * Its three reads have to be SCOPED to the item: querying the tick and the hidden\n * label from the document root would hand every item in the document the first\n * one's state, which is the kind of green spec that reports a broken checklist as\n * intact. A nested task list lives inside its parent `<li>`, and the parent's own\n * tick and label are rendered before it — so the first match under an item is\n * always the item's own.\n */\nclass WrMarkdownTaskItemReader extends ComponentHarness {\n static hostSelector = '.wr-markdown__item--task';\n\n private readonly tick = this.locatorForOptional('.wr-markdown__task--checked');\n private readonly stateLabel = this.locatorForOptional(SR_ONLY);\n\n async read(): Promise<WrMarkdownHarnessTaskItem> {\n const label = await this.stateLabel();\n\n return {\n text: await proseText(await this.host()),\n checked: (await this.tick()) !== null,\n stateLabel: label ? await label.text() : null,\n };\n }\n}\n\n/** One rendered table — see {@link WrMarkdownTableRowReader} for why this is a harness. */\nclass WrMarkdownTableReader extends ComponentHarness {\n static hostSelector = 'table.wr-markdown__table';\n\n async read(): Promise<WrMarkdownHarnessTable> {\n const headers = await this.locatorForAll('th.wr-markdown__th')();\n const rows = await this.locatorForAll(WrMarkdownTableRowReader)();\n\n return {\n headers: await Promise.all(headers.map(header => proseText(header))),\n rows: await Promise.all(rows.map(row => row.getCellTexts())),\n align: await Promise.all(headers.map(header => alignOf(header))),\n };\n }\n}\n\n/**\n * Test harness for `<wr-markdown>`, with {@link WrMarkdownCodeBlockHarness} for one\n * fenced code block.\n *\n * What a consumer of a markdown renderer actually asserts is that a piece of\n * SOURCE became the right DOM, so everything here reads rendered elements: the\n * heading levels, the `href` / `target` / `rel` triple on a link, the tick state of\n * a task item, a table as a rectangle of text. The parse tree is not exposed on\n * purpose — `parseMarkdown()` is a pure function with its own spec, and a harness\n * that reported its nodes would pass straight through the half that breaks people,\n * which is the template between the tree and the page.\n *\n * Three things worth knowing before writing expectations:\n *\n * - **Prose reads are whitespace-collapsed, code is not.** A soft line break inside\n * a paragraph is a real `\\n` in the DOM (CommonMark says CSS collapses it), so\n * every text answer here is normalized to the line a reader sees.\n * {@link WrMarkdownCodeBlockHarness.getCode} is the exception and reads its\n * snippet exactly.\n * - **The hidden task-state labels are left out of prose.** They are announced text,\n * not visible text; {@link getTaskItems} reports them as a field.\n * - **Everything is flat and in document order.** Markdown nests — a quote holds\n * blocks, a list item holds blocks — and these readers do not re-derive that\n * hierarchy: {@link getCodeBlocks} finds a block inside a quote, and a nested\n * list item's text is part of its parent's, because that is what the DOM says.\n *\n * @example\n * ```ts\n * const md = await loader.getHarness(WrMarkdownHarness);\n *\n * expect(await md.getHeadings()).toEqual([{ level: 1, text: 'Release notes', id: 'release-notes' }]);\n * expect(await md.getLinks()).toEqual([\n * { text: 'the docs', href: 'https://ngwr.dev', title: null, target: '_blank', rel: 'noopener noreferrer' },\n * ]);\n * ```\n *\n * @see https://ngwr.dev/reference/components/markdown\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrMarkdownHarness extends ComponentHarness {\n static hostSelector = 'wr-markdown';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrMarkdownHarnessFilters = {}): HarnessPredicate<WrMarkdownHarness> {\n return new HarnessPredicate(WrMarkdownHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))\n .addOption('headingText', options.headingText, async (harness, text) => {\n for (const heading of await harness.getHeadings()) {\n if (await HarnessPredicate.stringMatches(heading.text, text)) return true;\n }\n return false;\n })\n .addOption('codeLanguage', options.codeLanguage, async (harness, language) => {\n for (const block of await harness.getCodeBlocks()) {\n if (await HarnessPredicate.stringMatches(block.getLanguage(), language)) return true;\n }\n return false;\n })\n .addOption(\n 'streaming',\n options.streaming,\n async (harness, streaming) => (await harness.isStreaming()) === streaming\n );\n }\n\n /**\n * The whole document as text — whitespace collapsed, the hidden task-state labels\n * left out.\n *\n * The coarse read, and the useful one for the security cases: raw HTML in the\n * source is ESCAPED rather than rendered, so `<img onerror=…>` shows up here as\n * characters, and a refused `javascript:` URL leaves its label behind as text with\n * no anchor around it. A code block's newlines are collapsed like everything else\n * — {@link getCodeBlocks} is where a snippet stays exact.\n *\n * It is `textContent`, which means sibling BLOCKS are not separated: a document of\n * `<h1>Title</h1><p>Body</p>` reads as `'TitleBody'`, because the renderer emits\n * no whitespace between them and none is invented here. Assert a fragment with\n * `toContain`, or read the blocks themselves — {@link getHeadings},\n * {@link getParagraphs} — when the boundary matters.\n */\n async getText(): Promise<string> {\n return proseText(await this.host());\n }\n\n /**\n * Whether the component rendered nothing at all.\n *\n * True for an empty `value`, and for one that parses to nothing — a lone `<!--`\n * or whitespace. Distinct from `getText() === ''`, which a document made only of\n * a thematic break or an image would also answer.\n */\n async isEmpty(): Promise<boolean> {\n const host = await this.host();\n if ((await host.getProperty<number>('childElementCount')) > 0) return false;\n return (await this.getText()) === '';\n }\n\n /**\n * Whether the document is being streamed.\n *\n * Read from the `--streaming` host modifier rather than from the input, because\n * the modifier is the whole public API of the feature on the styling side: it is\n * what paints the caret after the last block. What it does NOT say is that\n * partial-safe parsing is on — the same input drives both, but only this reaches\n * the DOM.\n */\n async isStreaming(): Promise<boolean> {\n return (await this.host()).hasClass('wr-markdown--streaming');\n }\n\n /** Every heading, in document order. */\n async getHeadings(): Promise<WrMarkdownHarnessHeading[]> {\n const headings = await this.locatorForAll('.wr-markdown__heading')();\n\n return Promise.all(\n headings.map(async heading => ({\n // `H3` → 3. The element is where the level lives; see the field's docs.\n level: Number.parseInt((await heading.getProperty<string>('tagName')).slice(1), 10),\n text: await proseText(heading),\n id: await heading.getAttribute('id'),\n }))\n );\n }\n\n /**\n * The text of every paragraph, in document order.\n *\n * Including the ones inside a LOOSE list item — CommonMark drops the `<p>` in a\n * tight list and keeps it in a loose one, which is what stops a one-line list from\n * rendering double-spaced, so an empty answer for `- a\\n- b` is the correct one\n * rather than a missed paragraph.\n */\n async getParagraphs(): Promise<string[]> {\n const paragraphs = await this.locatorForAll('.wr-markdown__paragraph')();\n return Promise.all(paragraphs.map(paragraph => proseText(paragraph)));\n }\n\n /**\n * Every link, in document order, with the attributes that make it safe.\n *\n * A URL the renderer refused is NOT here — it renders as plain text instead of as\n * a live anchor that announces as a link and does nothing — so an empty answer\n * where a link was expected is the sanitizer speaking, and {@link getText} still\n * has the label.\n */\n async getLinks(): Promise<WrMarkdownHarnessLink[]> {\n const links = await this.locatorForAll('.wr-markdown__link')();\n\n return Promise.all(\n links.map(async link => ({\n text: await proseText(link),\n href: await link.getAttribute('href'),\n title: await link.getAttribute('title'),\n target: await link.getAttribute('target'),\n rel: await link.getAttribute('rel'),\n }))\n );\n }\n\n /**\n * Every image, in document order.\n *\n * A refused source renders no image at all and leaves the alt text as prose,\n * which is the information the author actually wrote — so assert this together\n * with {@link getText} when the point is the refusal.\n */\n async getImages(): Promise<WrMarkdownHarnessImage[]> {\n const images = await this.locatorForAll('.wr-markdown__image')();\n\n return Promise.all(\n images.map(async image => ({\n src: await image.getAttribute('src'),\n alt: await image.getAttribute('alt'),\n title: await image.getAttribute('title'),\n }))\n );\n }\n\n /**\n * The text of every inline code span, in document order.\n *\n * A different element from a fenced block (`<code>` on its own, not inside a\n * `<pre>`), and never one of {@link getCodeBlocks}. Read exactly rather than\n * collapsed, for the same reason a block is: this is code, and the spacing in it\n * is content.\n */\n async getInlineCode(): Promise<string[]> {\n const spans = await this.locatorForAll('.wr-markdown__code-inline')();\n return Promise.all(spans.map(async span => (await span.getProperty<string | null>('textContent')) ?? ''));\n }\n\n /**\n * The fenced code blocks, in document order — nested ones included.\n *\n * A block inside a quote or a list item is a block: it renders the same way and it\n * gets the same copy affordance, so leaving it out would report a document as\n * having no code because its snippet is indented under a bullet.\n */\n async getCodeBlocks(filters: WrMarkdownCodeBlockHarnessFilters = {}): Promise<WrMarkdownCodeBlockHarness[]> {\n return this.locatorForAll(WrMarkdownCodeBlockHarness.with(filters))();\n }\n\n /**\n * The first code block matching the filters.\n *\n * Throws when nothing matches, naming the languages the document does offer —\n * a `getCodeBlocks(…)[0]` that quietly resolves to `undefined` fails several lines\n * later, on an unrelated line, with `Cannot read properties of undefined`.\n */\n async getCodeBlock(filters: WrMarkdownCodeBlockHarnessFilters = {}): Promise<WrMarkdownCodeBlockHarness> {\n const [block] = await this.getCodeBlocks(filters);\n if (block) return block;\n\n const languages = await Promise.all((await this.getCodeBlocks()).map(other => other.getLanguage()));\n const offered =\n languages.length > 0\n ? `This document has ${languages.length} block(s), in: ${languages.map(name => name ?? '(none)').join(', ')}.`\n : 'This document renders no code blocks at all.';\n\n throw new Error(`WrMarkdownHarness.getCodeBlock(): no block matched ${JSON.stringify(filters)}. ${offered}`);\n }\n\n /**\n * The text of every list item, in document order.\n *\n * Bullets, numbers and task items alike — a task item's tick state is in\n * {@link getTaskItems} instead. NESTING is not re-derived: a nested list lives\n * INSIDE its parent `<li>` (which is what makes the list's accessibility tree\n * valid), so a parent's text contains its children's, and each child is also an\n * entry of its own.\n */\n async getListItems(): Promise<string[]> {\n const items = await this.locatorForAll('.wr-markdown__item')();\n return Promise.all(items.map(item => proseText(item)));\n }\n\n /**\n * Every task-list item (`- [x]` / `- [ ]`), in document order.\n *\n * Ordinary items are not here, so the count is the number of checkboxes in the\n * document. Both halves of each entry are worth asserting: the `checked` flag is\n * what a reader sees, and `stateLabel` is the only thing a screen reader gets —\n * the tick itself is `aria-hidden`.\n */\n async getTaskItems(): Promise<WrMarkdownHarnessTaskItem[]> {\n const items = await this.locatorForAll(WrMarkdownTaskItemReader)();\n return Promise.all(items.map(item => item.read()));\n }\n\n /** Every table, in document order, each as a rectangle of text plus its alignment. */\n async getTables(): Promise<WrMarkdownHarnessTable[]> {\n const tables = await this.locatorForAll(WrMarkdownTableReader)();\n return Promise.all(tables.map(table => table.read()));\n }\n\n /**\n * The text of every blockquote, in document order.\n *\n * A quote holds BLOCKS, so this is everything inside it collapsed to one line —\n * its paragraphs are also in {@link getParagraphs} and a snippet inside it is\n * also one of {@link getCodeBlocks}.\n */\n async getQuotes(): Promise<string[]> {\n const quotes = await this.locatorForAll('.wr-markdown__quote')();\n return Promise.all(quotes.map(quote => proseText(quote)));\n }\n\n /**\n * How many thematic breaks the document rendered.\n *\n * A count rather than a list because an `<hr>` has no content — and it is worth\n * counting: `---` is the one construct this renderer resolves differently from\n * some others (it is always a break here, never a setext heading underline), so a\n * document that lost a rule gained a heading somewhere.\n */\n async getRuleCount(): Promise<number> {\n return (await this.locatorForAll('.wr-markdown__rule')()).length;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngwr-markdown-testing.mjs","sources":["../../../projects/lib/markdown/testing/wr-markdown-code-block-harness.ts","../../../projects/lib/markdown/testing/wr-markdown-harness-text.ts","../../../projects/lib/markdown/testing/wr-markdown-harness.ts","../../../projects/lib/markdown/testing/ngwr-markdown-testing.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\n\nimport type { WrMarkdownCodeBlockHarnessFilters } from './interfaces';\n\n/**\n * Test harness for one fenced code block of a `<wr-markdown>` document.\n *\n * A block of its own rather than a field on the document harness, because it is\n * the one piece of rendered markdown that has BEHAVIOUR: it carries a language, it\n * may or may not be coloured yet, and it may offer a copy button — three states\n * that belong to the block and not to the page it is on.\n *\n * Its host is the `.wr-markdown__code-block` wrapper, which is what holds the\n * `<pre>` and the copy button together. Blocks nested inside a quote or a list item\n * are blocks too, and this harness finds them: `<wr-markdown>` renders them the\n * same way, and the copy affordance is theirs as well.\n *\n * @example\n * ```ts\n * const block = await (await loader.getHarness(WrMarkdownHarness)).getCodeBlock({ language: 'ts' });\n *\n * expect(await block.getCode()).toBe('const a = 1;');\n * await block.copy();\n * ```\n *\n * @see https://ngwr.dev/reference/components/markdown\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrMarkdownCodeBlockHarness extends ComponentHarness {\n static hostSelector = '.wr-markdown__code-block';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrMarkdownCodeBlockHarnessFilters = {}): HarnessPredicate<WrMarkdownCodeBlockHarness> {\n return new HarnessPredicate(WrMarkdownCodeBlockHarness, options)\n .addOption('language', options.language, (harness, language) =>\n HarnessPredicate.stringMatches(harness.getLanguage(), language)\n )\n .addOption('code', options.code, (harness, code) => HarnessPredicate.stringMatches(harness.getCode(), code));\n }\n\n private readonly pre = this.locatorFor('pre.wr-markdown__pre');\n private readonly code = this.locatorFor('code.wr-markdown__code');\n private readonly copyButton = this.locatorForOptional('button.wr-markdown__copy');\n\n /**\n * The block's language — the info string's first word, lowercased — or `null` for\n * a bare fence.\n *\n * Read from `data-language`, which is the only place it reaches the DOM, and the\n * reason it is there at all: a highlighter picks a grammar by it, and the\n * showcase's markdown export needs it to re-fence the block. `null` is a real\n * answer, not a gap: a bare fence names no grammar, so nothing is ever asked to\n * colour it.\n */\n async getLanguage(): Promise<string | null> {\n return (await this.code()).getAttribute('data-language');\n }\n\n /**\n * The block's code, EXACTLY — every space, every blank line, every newline.\n *\n * Nothing is collapsed here, unlike every prose read on the document harness,\n * and it is read off the `<pre>` rather than off the host so the copy button is\n * not part of the answer. Two failures live in this one string. Angular strips\n * whitespace-only text nodes from templates, so the code has to arrive as an\n * interpolation — a template that types it instead loses the indentation. And a\n * HIGHLIGHTED block is not one text node but a span per token: what separates its\n * lines is a real `\\n` interpolated between them, so a spec that only ever\n * asserts the unhighlighted case would not notice a highlighted block copying out\n * as one run-together line.\n */\n async getCode(): Promise<string> {\n return (await (await this.pre()).getProperty<string | null>('textContent')) ?? '';\n }\n\n /**\n * Whether the block is coloured right now.\n *\n * A block is plain text until a highlighter answers for it, and that is the\n * intended order rather than a compromise: a grammar engine loads WASM, and\n * blocking on it would leave the reader with an empty box instead of their code.\n * So this is `false` with no `WR_MARKDOWN_HIGHLIGHTER` provided, `false` for a\n * language the highlighter declined or threw on, `false` under SSR — a\n * highlighter resolving after prerender cannot contribute to the HTML — and\n * `false` for the first render of an async one.\n */\n async isHighlighted(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-markdown__line')()) !== null;\n }\n\n /**\n * Whether this block offers a copy button.\n *\n * Two conditions, and both are the component's policy rather than an accident:\n * `copyable` has to be on (bound, or defaulted through\n * `provideWrConfig({ markdown: { copyable: true } })`), and the fence has to be\n * CLOSED. Mid-stream a block's code is not all there, and a button that copies\n * half a snippet is worse than no button.\n */\n async canCopy(): Promise<boolean> {\n return (await this.copyButton()) !== null;\n }\n\n /**\n * The copy button's accessible name, or `null` when there is no button.\n *\n * Worth reading rather than assuming, because it is the whole of the copy\n * feedback: the button swaps its label — and its icon — for the \"copied\" one for\n * two seconds after a successful write, and both strings come from the i18n\n * catalog (`markdown.copy` / `markdown.copied`) or the matching inputs. Which is\n * also why this harness reports the name instead of a `isCopied()` boolean: only\n * the consuming app knows which of its own two strings means which.\n */\n async getCopyLabel(): Promise<string | null> {\n const button = await this.copyButton();\n return button ? button.getAttribute('aria-label') : null;\n }\n\n /**\n * Copy the block, the way a pointer does.\n *\n * Throws when there is no button, naming both reasons — a silent no-op here\n * surfaces as an empty clipboard assertion several lines later. Note what a\n * successful click needs from the environment: the directive behind the button\n * writes through `navigator.clipboard`, which jsdom does not implement at all, so\n * a unit test has to stand one in before the write can succeed and the label can\n * swap.\n */\n async copy(): Promise<void> {\n const button = await this.copyButton();\n if (!button) {\n throw new Error(\n 'WrMarkdownCodeBlockHarness.copy(): this block has no copy button. Either `copyable` is off — it ' +\n 'falls back to `markdown.copyable` from provideWrConfig(), then to false — or the fence is still ' +\n 'open, and <wr-markdown> only offers one on a CLOSED block.'\n );\n }\n await button.click();\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\n/**\n * Collapse the whitespace of a prose read to the line a reader sees.\n *\n * `TestElement.text()` only trims the ends, and markdown prose is never one text\n * node: a paragraph is text spliced with `<strong>`, `<code>` and `<a>`, and a\n * SOFT line break inside it is rendered as a real `\\n` — the parser keeps it as\n * whitespace and lets CSS collapse it, which is what CommonMark asks for. Reading\n * `textContent` raw therefore reports a paragraph the author wrote on three lines\n * as three lines, while the browser shows one; every run becomes a single space so\n * a spec can assert what is on screen.\n *\n * Deliberately NOT used on a code block. There the whitespace IS the content —\n * indentation, blank lines, the newlines between highlighted lines — so\n * `WrMarkdownCodeBlockHarness.getCode()` reads it exactly and this function never\n * touches it.\n */\nexport function wrMarkdownHarnessText(text: string): string {\n return text.replace(/\\s+/g, ' ').trim();\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate, type TestElement } from '@angular/cdk/testing';\n\nimport type {\n WrMarkdownCodeBlockHarnessFilters,\n WrMarkdownHarnessAlign,\n WrMarkdownHarnessFilters,\n WrMarkdownHarnessHeading,\n WrMarkdownHarnessImage,\n WrMarkdownHarnessLink,\n WrMarkdownHarnessTable,\n WrMarkdownHarnessTaskItem,\n} from './interfaces';\nimport { WrMarkdownCodeBlockHarness } from './wr-markdown-code-block-harness';\nimport { wrMarkdownHarnessText } from './wr-markdown-harness-text';\n\n/**\n * The task-state label — hidden from the page, read out in front of the item.\n *\n * Left out of every prose read here, so a spec asserting an item's text does not\n * have to know that `'Done: '` is spliced in front of it. It is not lost: it is a\n * field of its own on {@link WrMarkdownHarnessTaskItem}, which is where its\n * absence is a failure rather than a nuisance.\n */\nconst SR_ONLY = '.wr-markdown__sr-only';\n\n/** The alignment the renderer wrote as an inline style, if it wrote one. */\nconst TEXT_ALIGN_RE = /text-align:\\s*([a-z]+)/;\n\n/** Every prose read goes through here: collapsed, and without the hidden labels. */\nasync function proseText(element: TestElement): Promise<string> {\n return wrMarkdownHarnessText(await element.text({ exclude: SR_ONLY }));\n}\n\n/**\n * A cell's or a header's alignment, read off the inline `style` attribute.\n *\n * Not through `getCssValue()`, and the difference is not cosmetic: a column the\n * delimiter row said nothing about carries no declaration at all, and computed\n * style answers for it anyway — with whatever the user-agent stylesheet says a\n * `<th>` or a `<td>` is aligned to. That makes \"no alignment\" indistinguishable\n * from `center`, in the one direction that matters (a `<th>` centres by default),\n * and it makes the answer depend on the browser rather than on the document. The\n * attribute is what the component wrote, which is the fact being asserted.\n */\nasync function alignOf(cell: TestElement): Promise<WrMarkdownHarnessAlign> {\n const match = TEXT_ALIGN_RE.exec((await cell.getAttribute('style')) ?? '');\n\n switch (match?.[1]) {\n case 'start':\n return 'start';\n case 'center':\n return 'center';\n case 'end':\n return 'end';\n default:\n return null;\n }\n}\n\n/**\n * One body row of a rendered table.\n *\n * Not exported, and not because rows do not matter: a `TestElement` cannot be\n * queried INTO, so reading one row's own cells needs a harness rooted on that row.\n * Nothing here is drivable — rendered prose is inert — so the row's job is to hand\n * its cells up to {@link WrMarkdownHarness.getTables}, which is where a consumer\n * asserts the whole table in one comparison.\n */\nclass WrMarkdownTableRowReader extends ComponentHarness {\n /** Body rows only: the header row lives in the `<thead>`. */\n static hostSelector = 'tbody tr';\n\n async getCellTexts(): Promise<string[]> {\n const cells = await this.locatorForAll('.wr-markdown__td')();\n return Promise.all(cells.map(cell => proseText(cell)));\n }\n}\n\n/**\n * One rendered task-list item — a harness for the same reason as the row reader.\n *\n * Its three reads have to be SCOPED to the item: querying the tick and the hidden\n * label from the document root would hand every item in the document the first\n * one's state, which is the kind of green spec that reports a broken checklist as\n * intact. A nested task list lives inside its parent `<li>`, and the parent's own\n * tick and label are rendered before it — so the first match under an item is\n * always the item's own.\n */\nclass WrMarkdownTaskItemReader extends ComponentHarness {\n static hostSelector = '.wr-markdown__item--task';\n\n private readonly tick = this.locatorForOptional('.wr-markdown__task--checked');\n private readonly stateLabel = this.locatorForOptional(SR_ONLY);\n\n async read(): Promise<WrMarkdownHarnessTaskItem> {\n const label = await this.stateLabel();\n\n return {\n text: await proseText(await this.host()),\n checked: (await this.tick()) !== null,\n stateLabel: label ? await label.text() : null,\n };\n }\n}\n\n/** One rendered table — see {@link WrMarkdownTableRowReader} for why this is a harness. */\nclass WrMarkdownTableReader extends ComponentHarness {\n static hostSelector = 'table.wr-markdown__table';\n\n async read(): Promise<WrMarkdownHarnessTable> {\n const headers = await this.locatorForAll('th.wr-markdown__th')();\n const rows = await this.locatorForAll(WrMarkdownTableRowReader)();\n\n return {\n headers: await Promise.all(headers.map(header => proseText(header))),\n rows: await Promise.all(rows.map(row => row.getCellTexts())),\n align: await Promise.all(headers.map(header => alignOf(header))),\n };\n }\n}\n\n/**\n * Test harness for `<wr-markdown>`, with {@link WrMarkdownCodeBlockHarness} for one\n * fenced code block.\n *\n * What a consumer of a markdown renderer actually asserts is that a piece of\n * SOURCE became the right DOM, so everything here reads rendered elements: the\n * heading levels, the `href` / `target` / `rel` triple on a link, the tick state of\n * a task item, a table as a rectangle of text. The parse tree is not exposed on\n * purpose — `parseMarkdown()` is a pure function with its own spec, and a harness\n * that reported its nodes would pass straight through the half that breaks people,\n * which is the template between the tree and the page.\n *\n * Three things worth knowing before writing expectations:\n *\n * - **Prose reads are whitespace-collapsed, code is not.** A soft line break inside\n * a paragraph is a real `\\n` in the DOM (CommonMark says CSS collapses it), so\n * every text answer here is normalized to the line a reader sees.\n * {@link WrMarkdownCodeBlockHarness.getCode} is the exception and reads its\n * snippet exactly.\n * - **The hidden task-state labels are left out of prose.** They are announced text,\n * not visible text; {@link getTaskItems} reports them as a field.\n * - **Everything is flat and in document order.** Markdown nests — a quote holds\n * blocks, a list item holds blocks — and these readers do not re-derive that\n * hierarchy: {@link getCodeBlocks} finds a block inside a quote, and a nested\n * list item's text is part of its parent's, because that is what the DOM says.\n *\n * @example\n * ```ts\n * const md = await loader.getHarness(WrMarkdownHarness);\n *\n * expect(await md.getHeadings()).toEqual([{ level: 1, text: 'Release notes', id: 'release-notes' }]);\n * expect(await md.getLinks()).toEqual([\n * { text: 'the docs', href: 'https://ngwr.dev', title: null, target: '_blank', rel: 'noopener noreferrer' },\n * ]);\n * ```\n *\n * @see https://ngwr.dev/reference/components/markdown\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrMarkdownHarness extends ComponentHarness {\n static hostSelector = 'wr-markdown';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrMarkdownHarnessFilters = {}): HarnessPredicate<WrMarkdownHarness> {\n return new HarnessPredicate(WrMarkdownHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))\n .addOption('headingText', options.headingText, async (harness, text) => {\n for (const heading of await harness.getHeadings()) {\n if (await HarnessPredicate.stringMatches(heading.text, text)) return true;\n }\n return false;\n })\n .addOption('codeLanguage', options.codeLanguage, async (harness, language) => {\n for (const block of await harness.getCodeBlocks()) {\n if (await HarnessPredicate.stringMatches(block.getLanguage(), language)) return true;\n }\n return false;\n })\n .addOption(\n 'streaming',\n options.streaming,\n async (harness, streaming) => (await harness.isStreaming()) === streaming\n );\n }\n\n /**\n * The whole document as text — whitespace collapsed, the hidden task-state labels\n * left out.\n *\n * The coarse read, and the useful one for the security cases: raw HTML in the\n * source is ESCAPED rather than rendered, so `<img onerror=…>` shows up here as\n * characters, and a refused `javascript:` URL leaves its label behind as text with\n * no anchor around it. A code block's newlines are collapsed like everything else\n * — {@link getCodeBlocks} is where a snippet stays exact.\n *\n * It is `textContent`, which means sibling BLOCKS are not separated: a document of\n * `<h1>Title</h1><p>Body</p>` reads as `'TitleBody'`, because the renderer emits\n * no whitespace between them and none is invented here. Assert a fragment with\n * `toContain`, or read the blocks themselves — {@link getHeadings},\n * {@link getParagraphs} — when the boundary matters.\n */\n async getText(): Promise<string> {\n return proseText(await this.host());\n }\n\n /**\n * Whether the component rendered nothing at all.\n *\n * True for an empty `value`, and for one that parses to nothing — a lone `<!--`\n * or whitespace. Distinct from `getText() === ''`, which a document made only of\n * a thematic break or an image would also answer.\n */\n async isEmpty(): Promise<boolean> {\n const host = await this.host();\n if ((await host.getProperty<number>('childElementCount')) > 0) return false;\n return (await this.getText()) === '';\n }\n\n /**\n * Whether the document is being streamed.\n *\n * Read from the `--streaming` host modifier rather than from the input, because\n * the modifier is the whole public API of the feature on the styling side: it is\n * what paints the caret after the last block. What it does NOT say is that\n * partial-safe parsing is on — the same input drives both, but only this reaches\n * the DOM.\n */\n async isStreaming(): Promise<boolean> {\n return (await this.host()).hasClass('wr-markdown--streaming');\n }\n\n /** Every heading, in document order. */\n async getHeadings(): Promise<WrMarkdownHarnessHeading[]> {\n const headings = await this.locatorForAll('.wr-markdown__heading')();\n\n return Promise.all(\n headings.map(async heading => ({\n // `H3` → 3. The element is where the level lives; see the field's docs.\n level: Number.parseInt((await heading.getProperty<string>('tagName')).slice(1), 10),\n text: await proseText(heading),\n id: await heading.getAttribute('id'),\n }))\n );\n }\n\n /**\n * The text of every paragraph, in document order.\n *\n * Including the ones inside a LOOSE list item — CommonMark drops the `<p>` in a\n * tight list and keeps it in a loose one, which is what stops a one-line list from\n * rendering double-spaced, so an empty answer for `- a\\n- b` is the correct one\n * rather than a missed paragraph.\n */\n async getParagraphs(): Promise<string[]> {\n const paragraphs = await this.locatorForAll('.wr-markdown__paragraph')();\n return Promise.all(paragraphs.map(paragraph => proseText(paragraph)));\n }\n\n /**\n * Every link, in document order, with the attributes that make it safe.\n *\n * A URL the renderer refused is NOT here — it renders as plain text instead of as\n * a live anchor that announces as a link and does nothing — so an empty answer\n * where a link was expected is the sanitizer speaking, and {@link getText} still\n * has the label.\n */\n async getLinks(): Promise<WrMarkdownHarnessLink[]> {\n const links = await this.locatorForAll('.wr-markdown__link')();\n\n return Promise.all(\n links.map(async link => ({\n text: await proseText(link),\n href: await link.getAttribute('href'),\n title: await link.getAttribute('title'),\n target: await link.getAttribute('target'),\n rel: await link.getAttribute('rel'),\n }))\n );\n }\n\n /**\n * Every image, in document order.\n *\n * A refused source renders no image at all and leaves the alt text as prose,\n * which is the information the author actually wrote — so assert this together\n * with {@link getText} when the point is the refusal.\n */\n async getImages(): Promise<WrMarkdownHarnessImage[]> {\n const images = await this.locatorForAll('.wr-markdown__image')();\n\n return Promise.all(\n images.map(async image => ({\n src: await image.getAttribute('src'),\n alt: await image.getAttribute('alt'),\n title: await image.getAttribute('title'),\n }))\n );\n }\n\n /**\n * The text of every inline code span, in document order.\n *\n * A different element from a fenced block (`<code>` on its own, not inside a\n * `<pre>`), and never one of {@link getCodeBlocks}. Read exactly rather than\n * collapsed, for the same reason a block is: this is code, and the spacing in it\n * is content.\n */\n async getInlineCode(): Promise<string[]> {\n const spans = await this.locatorForAll('.wr-markdown__code-inline')();\n return Promise.all(spans.map(async span => (await span.getProperty<string | null>('textContent')) ?? ''));\n }\n\n /**\n * The fenced code blocks, in document order — nested ones included.\n *\n * A block inside a quote or a list item is a block: it renders the same way and it\n * gets the same copy affordance, so leaving it out would report a document as\n * having no code because its snippet is indented under a bullet.\n */\n async getCodeBlocks(filters: WrMarkdownCodeBlockHarnessFilters = {}): Promise<WrMarkdownCodeBlockHarness[]> {\n return this.locatorForAll(WrMarkdownCodeBlockHarness.with(filters))();\n }\n\n /**\n * The first code block matching the filters.\n *\n * Throws when nothing matches, naming the languages the document does offer —\n * a `getCodeBlocks(…)[0]` that quietly resolves to `undefined` fails several lines\n * later, on an unrelated line, with `Cannot read properties of undefined`.\n */\n async getCodeBlock(filters: WrMarkdownCodeBlockHarnessFilters = {}): Promise<WrMarkdownCodeBlockHarness> {\n const [block] = await this.getCodeBlocks(filters);\n if (block) return block;\n\n const languages = await Promise.all((await this.getCodeBlocks()).map(other => other.getLanguage()));\n const offered =\n languages.length > 0\n ? `This document has ${languages.length} block(s), in: ${languages.map(name => name ?? '(none)').join(', ')}.`\n : 'This document renders no code blocks at all.';\n\n throw new Error(`WrMarkdownHarness.getCodeBlock(): no block matched ${JSON.stringify(filters)}. ${offered}`);\n }\n\n /**\n * The text of every list item, in document order.\n *\n * Bullets, numbers and task items alike — a task item's tick state is in\n * {@link getTaskItems} instead. NESTING is not re-derived: a nested list lives\n * INSIDE its parent `<li>` (which is what makes the list's accessibility tree\n * valid), so a parent's text contains its children's, and each child is also an\n * entry of its own.\n */\n async getListItems(): Promise<string[]> {\n const items = await this.locatorForAll('.wr-markdown__item')();\n return Promise.all(items.map(item => proseText(item)));\n }\n\n /**\n * Every task-list item (`- [x]` / `- [ ]`), in document order.\n *\n * Ordinary items are not here, so the count is the number of checkboxes in the\n * document. Both halves of each entry are worth asserting: the `checked` flag is\n * what a reader sees, and `stateLabel` is the only thing a screen reader gets —\n * the tick itself is `aria-hidden`.\n */\n async getTaskItems(): Promise<WrMarkdownHarnessTaskItem[]> {\n const items = await this.locatorForAll(WrMarkdownTaskItemReader)();\n return Promise.all(items.map(item => item.read()));\n }\n\n /** Every table, in document order, each as a rectangle of text plus its alignment. */\n async getTables(): Promise<WrMarkdownHarnessTable[]> {\n const tables = await this.locatorForAll(WrMarkdownTableReader)();\n return Promise.all(tables.map(table => table.read()));\n }\n\n /**\n * The text of every blockquote, in document order.\n *\n * A quote holds BLOCKS, so this is everything inside it collapsed to one line —\n * its paragraphs are also in {@link getParagraphs} and a snippet inside it is\n * also one of {@link getCodeBlocks}.\n */\n async getQuotes(): Promise<string[]> {\n const quotes = await this.locatorForAll('.wr-markdown__quote')();\n return Promise.all(quotes.map(quote => proseText(quote)));\n }\n\n /**\n * How many thematic breaks the document rendered.\n *\n * A count rather than a list because an `<hr>` has no content — and it is worth\n * counting: `---` is the one construct this renderer resolves differently from\n * some others (it is always a break here, never a setext heading underline), so a\n * document that lost a rule gained a heading somewhere.\n */\n async getRuleCount(): Promise<number> {\n return (await this.locatorForAll('.wr-markdown__rule')()).length;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAMH;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AACG,MAAO,0BAA2B,SAAQ,gBAAgB,CAAA;AAC9D,IAAA,OAAO,YAAY,GAAG,0BAA0B;;AAGhD,IAAA,OAAO,IAAI,CAAC,OAAA,GAA6C,EAAE,EAAA;AACzD,QAAA,OAAO,IAAI,gBAAgB,CAAC,0BAA0B,EAAE,OAAO;aAC5D,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,KACzD,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC;aAEhE,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;IAChH;AAEiB,IAAA,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC;AAC7C,IAAA,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,wBAAwB,CAAC;AAChD,IAAA,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,0BAA0B,CAAC;AAEjF;;;;;;;;;AASG;AACH,IAAA,MAAM,WAAW,GAAA;AACf,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,eAAe,CAAC;IAC1D;AAEA;;;;;;;;;;;;AAYG;AACH,IAAA,MAAM,OAAO,GAAA;AACX,QAAA,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,CAAgB,aAAa,CAAC,KAAK,EAAE;IACnF;AAEA;;;;;;;;;;AAUG;AACH,IAAA,MAAM,aAAa,GAAA;AACjB,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,oBAAoB,CAAC,EAAE,MAAM,IAAI;IACzE;AAEA;;;;;;;;AAQG;AACH,IAAA,MAAM,OAAO,GAAA;QACX,OAAO,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,MAAM,IAAI;IAC3C;AAEA;;;;;;;;;AASG;AACH,IAAA,MAAM,YAAY,GAAA;AAChB,QAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE;AACtC,QAAA,OAAO,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,IAAI;IAC1D;AAEA;;;;;;;;;AASG;AACH,IAAA,MAAM,IAAI,GAAA;AACR,QAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE;QACtC,IAAI,CAAC,MAAM,EAAE;YACX,MAAM,IAAI,KAAK,CACb,kGAAkG;gBAChG,kGAAkG;AAClG,gBAAA,4DAA4D,CAC/D;QACH;AACA,QAAA,MAAM,MAAM,CAAC,KAAK,EAAE;IACtB;;;ACjJF;;;;;AAKG;AAEH;;;;;;;;;;;;;;;AAeG;AACG,SAAU,qBAAqB,CAAC,IAAY,EAAA;IAChD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE;AACzC;;ACzBA;;;;;AAKG;AAiBH;;;;;;;AAOG;AACH,MAAM,OAAO,GAAG,uBAAuB;AAEvC;AACA,MAAM,aAAa,GAAG,wBAAwB;AAE9C;AACA,eAAe,SAAS,CAAC,OAAoB,EAAA;AAC3C,IAAA,OAAO,qBAAqB,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AACxE;AAEA;;;;;;;;;;AAUG;AACH,eAAe,OAAO,CAAC,IAAiB,EAAA;AACtC,IAAA,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;AAE1E,IAAA,QAAQ,KAAK,GAAG,CAAC,CAAC;AAChB,QAAA,KAAK,OAAO;AACV,YAAA,OAAO,OAAO;AAChB,QAAA,KAAK,QAAQ;AACX,YAAA,OAAO,QAAQ;AACjB,QAAA,KAAK,KAAK;AACR,YAAA,OAAO,KAAK;AACd,QAAA;AACE,YAAA,OAAO,IAAI;;AAEjB;AAEA;;;;;;;;AAQG;AACH,MAAM,wBAAyB,SAAQ,gBAAgB,CAAA;;AAErD,IAAA,OAAO,YAAY,GAAG,UAAU;AAEhC,IAAA,MAAM,YAAY,GAAA;QAChB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC,EAAE;AAC5D,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD;;AAGF;;;;;;;;;AASG;AACH,MAAM,wBAAyB,SAAQ,gBAAgB,CAAA;AACrD,IAAA,OAAO,YAAY,GAAG,0BAA0B;AAE/B,IAAA,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,6BAA6B,CAAC;AAC7D,IAAA,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC;AAE9D,IAAA,MAAM,IAAI,GAAA;AACR,QAAA,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE;QAErC,OAAO;YACL,IAAI,EAAE,MAAM,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI;AACrC,YAAA,UAAU,EAAE,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,GAAG,IAAI;SAC9C;IACH;;AAGF;AACA,MAAM,qBAAsB,SAAQ,gBAAgB,CAAA;AAClD,IAAA,OAAO,YAAY,GAAG,0BAA0B;AAEhD,IAAA,MAAM,IAAI,GAAA;QACR,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAAE;QAChE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAAC,EAAE;QAEjE,OAAO;AACL,YAAA,OAAO,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;AACpE,YAAA,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;AAC5D,YAAA,KAAK,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;SACjE;IACH;;AAGF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCG;AACG,MAAO,iBAAkB,SAAQ,gBAAgB,CAAA;AACrD,IAAA,OAAO,YAAY,GAAG,aAAa;;AAGnC,IAAA,OAAO,IAAI,CAAC,OAAA,GAAoC,EAAE,EAAA;AAChD,QAAA,OAAO,IAAI,gBAAgB,CAAC,iBAAiB,EAAE,OAAO;aACnD,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC;AAC1G,aAAA,SAAS,CAAC,aAAa,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,OAAO,EAAE,IAAI,KAAI;YACrE,KAAK,MAAM,OAAO,IAAI,MAAM,OAAO,CAAC,WAAW,EAAE,EAAE;gBACjD,IAAI,MAAM,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC;AAAE,oBAAA,OAAO,IAAI;YAC3E;AACA,YAAA,OAAO,KAAK;AACd,QAAA,CAAC;AACA,aAAA,SAAS,CAAC,cAAc,EAAE,OAAO,CAAC,YAAY,EAAE,OAAO,OAAO,EAAE,QAAQ,KAAI;YAC3E,KAAK,MAAM,KAAK,IAAI,MAAM,OAAO,CAAC,aAAa,EAAE,EAAE;gBACjD,IAAI,MAAM,gBAAgB,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC;AAAE,oBAAA,OAAO,IAAI;YACtF;AACA,YAAA,OAAO,KAAK;AACd,QAAA,CAAC;aACA,SAAS,CACR,WAAW,EACX,OAAO,CAAC,SAAS,EACjB,OAAO,OAAO,EAAE,SAAS,KAAK,CAAC,MAAM,OAAO,CAAC,WAAW,EAAE,MAAM,SAAS,CAC1E;IACL;AAEA;;;;;;;;;;;;;;;AAeG;AACH,IAAA,MAAM,OAAO,GAAA;QACX,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACrC;AAEA;;;;;;AAMG;AACH,IAAA,MAAM,OAAO,GAAA;AACX,QAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE;QAC9B,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,CAAS,mBAAmB,CAAC,IAAI,CAAC;AAAE,YAAA,OAAO,KAAK;QAC3E,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE;IACtC;AAEA;;;;;;;;AAQG;AACH,IAAA,MAAM,WAAW,GAAA;AACf,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,wBAAwB,CAAC;IAC/D;;AAGA,IAAA,MAAM,WAAW,GAAA;QACf,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,uBAAuB,CAAC,EAAE;AAEpE,QAAA,OAAO,OAAO,CAAC,GAAG,CAChB,QAAQ,CAAC,GAAG,CAAC,OAAM,OAAO,MAAK;;YAE7B,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,OAAO,CAAC,WAAW,CAAS,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACnF,YAAA,IAAI,EAAE,MAAM,SAAS,CAAC,OAAO,CAAC;AAC9B,YAAA,EAAE,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC;SACrC,CAAC,CAAC,CACJ;IACH;AAEA;;;;;;;AAOG;AACH,IAAA,MAAM,aAAa,GAAA;QACjB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC,EAAE;AACxE,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;IACvE;AAEA;;;;;;;AAOG;AACH,IAAA,MAAM,QAAQ,GAAA;QACZ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAAE;AAE9D,QAAA,OAAO,OAAO,CAAC,GAAG,CAChB,KAAK,CAAC,GAAG,CAAC,OAAM,IAAI,MAAK;AACvB,YAAA,IAAI,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC;AAC3B,YAAA,IAAI,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;AACrC,YAAA,KAAK,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;AACvC,YAAA,MAAM,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC;AACzC,YAAA,GAAG,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;SACpC,CAAC,CAAC,CACJ;IACH;AAEA;;;;;;AAMG;AACH,IAAA,MAAM,SAAS,GAAA;QACb,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,EAAE;AAEhE,QAAA,OAAO,OAAO,CAAC,GAAG,CAChB,MAAM,CAAC,GAAG,CAAC,OAAM,KAAK,MAAK;AACzB,YAAA,GAAG,EAAE,MAAM,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC;AACpC,YAAA,GAAG,EAAE,MAAM,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC;AACpC,YAAA,KAAK,EAAE,MAAM,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC;SACzC,CAAC,CAAC,CACJ;IACH;AAEA;;;;;;;AAOG;AACH,IAAA,MAAM,aAAa,GAAA;QACjB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,2BAA2B,CAAC,EAAE;QACrE,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAM,IAAI,KAAI,CAAC,MAAM,IAAI,CAAC,WAAW,CAAgB,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC;IAC3G;AAEA;;;;;;AAMG;AACH,IAAA,MAAM,aAAa,CAAC,OAAA,GAA6C,EAAE,EAAA;AACjE,QAAA,OAAO,IAAI,CAAC,aAAa,CAAC,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE;IACvE;AAEA;;;;;;AAMG;AACH,IAAA,MAAM,YAAY,CAAC,OAAA,GAA6C,EAAE,EAAA;QAChE,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;AACjD,QAAA,IAAI,KAAK;AAAE,YAAA,OAAO,KAAK;QAEvB,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,EAAE,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;AACnG,QAAA,MAAM,OAAO,GACX,SAAS,CAAC,MAAM,GAAG;cACf,qBAAqB,SAAS,CAAC,MAAM,CAAA,eAAA,EAAkB,SAAS,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,IAAI,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAA;cACzG,8CAA8C;AAEpD,QAAA,MAAM,IAAI,KAAK,CAAC,CAAA,mDAAA,EAAsD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA,EAAA,EAAK,OAAO,CAAA,CAAE,CAAC;IAC9G;AAEA;;;;;;;;AAQG;AACH,IAAA,MAAM,YAAY,GAAA;QAChB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAAE;AAC9D,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD;AAEA;;;;;;;AAOG;AACH,IAAA,MAAM,YAAY,GAAA;QAChB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAAC,EAAE;AAClE,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACpD;;AAGA,IAAA,MAAM,SAAS,GAAA;QACb,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,EAAE;AAChE,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD;AAEA;;;;;;AAMG;AACH,IAAA,MAAM,SAAS,GAAA;QACb,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,EAAE;AAChE,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3D;AAEA;;;;;;;AAOG;AACH,IAAA,MAAM,YAAY,GAAA;AAChB,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAAE,EAAE,MAAM;IAClE;;;ACtZF;;AAEG;;"}
|