@foblex/m-render 4.0.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1032,13 +1032,13 @@ class FCheckboxComponent {
1032
1032
  }
1033
1033
  }
1034
1034
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FCheckboxComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1035
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "21.1.4", type: FCheckboxComponent, isStandalone: true, selector: "f-checkbox", inputs: { id: "id", checked: ["checked", "checked", booleanAttribute] }, outputs: { change: "change" }, host: { listeners: { "click": "preventBubblingFromLabel($event)" }, properties: { "class.f-checkbox-checked": "checked" } }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["input"], descendants: true }, { propertyName: "labelElement", first: true, predicate: ["label"], descendants: true }], ngImport: i0, template: "<input #input\n [id]=\"id\"\n type=\"checkbox\"\n [checked]=\"checked\"\n (click)=\"onInputClick()\"\n (change)=\"onInteractionEvent($event)\"/>\n<div class=\"f-checkbox-container\" (click)=\"onTouchTargetClick()\">\n <svg class=\"f-checkbox-checkmark\" focusable=\"false\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path class=\"f-checkbox-checkmark-path\" fill=\"none\" d=\"M1.73,12.91 8.1,19.28 22.79,4.59\"/>\n </svg>\n</div>\n<label [for]=\"id\" #label>\n <ng-content></ng-content>\n</label>\n", styles: [":host{position:relative;display:flex;align-items:center;font-weight:400;white-space:nowrap;font-size:14px;cursor:pointer;background-color:var(--checkbox-container-background);border-radius:var(--checkbox-border-radius);padding:0 8px;color:var(--checkbox-text);transition:color .25s,background-color .25s}:host input{position:absolute;inset:0;opacity:0;cursor:pointer}:host .f-checkbox-container{position:relative;display:flex;align-items:center;justify-content:center;width:var(--checkbox-size);height:var(--checkbox-size);margin-right:6px;border-radius:var(--checkbox-border-radius);background-color:var(--checkbox-background);padding:2px}:host .f-checkbox-container .f-checkbox-checkmark{position:absolute;top:calc(var(--checkbox-size) / 8);right:calc(var(--checkbox-size) / 8);bottom:calc(var(--checkbox-size) / 8);left:calc(var(--checkbox-size) / 8);opacity:0}:host .f-checkbox-container .f-checkbox-checkmark .f-checkbox-checkmark-path{stroke:currentColor;stroke-width:3}:host label{-webkit-user-select:none;user-select:none}:host.f-checkbox-checked .f-checkbox-container{background-color:var(--checkbox-checked-background)}:host.f-checkbox-checked .f-checkbox-container .f-checkbox-checkmark{color:var(--checkbox-checkmark-color);opacity:1}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1035
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "21.1.4", type: FCheckboxComponent, isStandalone: true, selector: "f-checkbox", inputs: { id: "id", checked: ["checked", "checked", booleanAttribute] }, outputs: { change: "change" }, host: { listeners: { "click": "preventBubblingFromLabel($event)" }, properties: { "class.f-checkbox-checked": "checked" } }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["input"], descendants: true }, { propertyName: "labelElement", first: true, predicate: ["label"], descendants: true }], ngImport: i0, template: "<input #input\n [id]=\"id\"\n type=\"checkbox\"\n [checked]=\"checked\"\n (click)=\"onInputClick()\"\n (change)=\"onInteractionEvent($event)\"/>\n<div class=\"f-checkbox-container\" (click)=\"onTouchTargetClick()\">\n <svg class=\"f-checkbox-checkmark\" focusable=\"false\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path class=\"f-checkbox-checkmark-path\" fill=\"none\" d=\"M1.73,12.91 8.1,19.28 22.79,4.59\"/>\n </svg>\n</div>\n<label [for]=\"id\" #label>\n <ng-content></ng-content>\n</label>\n", styles: [":host{position:relative;display:inline-flex;align-items:flex-start;gap:8px;font-weight:400;font-size:14px;line-height:20px;cursor:pointer;color:var(--checkbox-text)}:host input{position:absolute;inset:0;opacity:0;cursor:pointer;margin:0}:host:hover .f-checkbox-container{border-color:var(--checkbox-border-color-hover)}:host .f-checkbox-container{position:relative;display:flex;align-items:center;justify-content:center;width:var(--checkbox-size);height:var(--checkbox-size);flex-shrink:0;margin-top:1px;border:1px solid var(--checkbox-border-color);border-radius:var(--checkbox-border-radius);background-color:var(--checkbox-background);transition:border-color .15s ease,background-color .15s ease}:host .f-checkbox-container .f-checkbox-checkmark{position:absolute;width:10px;height:10px;opacity:0;transform:scale(.7);transition:opacity .15s ease,transform .15s ease,color .15s ease}:host .f-checkbox-container .f-checkbox-checkmark .f-checkbox-checkmark-path{stroke:var(--checkbox-checkmark-color);stroke-width:2.75;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:32;stroke-dashoffset:32}:host label{-webkit-user-select:none;user-select:none;line-height:inherit}:host.f-checkbox-checked .f-checkbox-container{border-color:var(--checkbox-checked-background);background-color:var(--checkbox-checked-background)}:host.f-checkbox-checked .f-checkbox-container .f-checkbox-checkmark{opacity:1;transform:scale(1)}:host.f-checkbox-checked .f-checkbox-container .f-checkbox-checkmark .f-checkbox-checkmark-path{animation:f-checkbox-check-draw .22s cubic-bezier(.19,1,.22,1) forwards}@keyframes f-checkbox-check-draw{0%{stroke-dashoffset:32}to{stroke-dashoffset:0}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1036
1036
  }
1037
1037
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FCheckboxComponent, decorators: [{
1038
1038
  type: Component,
1039
1039
  args: [{ selector: 'f-checkbox', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
1040
1040
  '[class.f-checkbox-checked]': 'checked',
1041
- }, template: "<input #input\n [id]=\"id\"\n type=\"checkbox\"\n [checked]=\"checked\"\n (click)=\"onInputClick()\"\n (change)=\"onInteractionEvent($event)\"/>\n<div class=\"f-checkbox-container\" (click)=\"onTouchTargetClick()\">\n <svg class=\"f-checkbox-checkmark\" focusable=\"false\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path class=\"f-checkbox-checkmark-path\" fill=\"none\" d=\"M1.73,12.91 8.1,19.28 22.79,4.59\"/>\n </svg>\n</div>\n<label [for]=\"id\" #label>\n <ng-content></ng-content>\n</label>\n", styles: [":host{position:relative;display:flex;align-items:center;font-weight:400;white-space:nowrap;font-size:14px;cursor:pointer;background-color:var(--checkbox-container-background);border-radius:var(--checkbox-border-radius);padding:0 8px;color:var(--checkbox-text);transition:color .25s,background-color .25s}:host input{position:absolute;inset:0;opacity:0;cursor:pointer}:host .f-checkbox-container{position:relative;display:flex;align-items:center;justify-content:center;width:var(--checkbox-size);height:var(--checkbox-size);margin-right:6px;border-radius:var(--checkbox-border-radius);background-color:var(--checkbox-background);padding:2px}:host .f-checkbox-container .f-checkbox-checkmark{position:absolute;top:calc(var(--checkbox-size) / 8);right:calc(var(--checkbox-size) / 8);bottom:calc(var(--checkbox-size) / 8);left:calc(var(--checkbox-size) / 8);opacity:0}:host .f-checkbox-container .f-checkbox-checkmark .f-checkbox-checkmark-path{stroke:currentColor;stroke-width:3}:host label{-webkit-user-select:none;user-select:none}:host.f-checkbox-checked .f-checkbox-container{background-color:var(--checkbox-checked-background)}:host.f-checkbox-checked .f-checkbox-container .f-checkbox-checkmark{color:var(--checkbox-checkmark-color);opacity:1}\n"] }]
1041
+ }, template: "<input #input\n [id]=\"id\"\n type=\"checkbox\"\n [checked]=\"checked\"\n (click)=\"onInputClick()\"\n (change)=\"onInteractionEvent($event)\"/>\n<div class=\"f-checkbox-container\" (click)=\"onTouchTargetClick()\">\n <svg class=\"f-checkbox-checkmark\" focusable=\"false\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path class=\"f-checkbox-checkmark-path\" fill=\"none\" d=\"M1.73,12.91 8.1,19.28 22.79,4.59\"/>\n </svg>\n</div>\n<label [for]=\"id\" #label>\n <ng-content></ng-content>\n</label>\n", styles: [":host{position:relative;display:inline-flex;align-items:flex-start;gap:8px;font-weight:400;font-size:14px;line-height:20px;cursor:pointer;color:var(--checkbox-text)}:host input{position:absolute;inset:0;opacity:0;cursor:pointer;margin:0}:host:hover .f-checkbox-container{border-color:var(--checkbox-border-color-hover)}:host .f-checkbox-container{position:relative;display:flex;align-items:center;justify-content:center;width:var(--checkbox-size);height:var(--checkbox-size);flex-shrink:0;margin-top:1px;border:1px solid var(--checkbox-border-color);border-radius:var(--checkbox-border-radius);background-color:var(--checkbox-background);transition:border-color .15s ease,background-color .15s ease}:host .f-checkbox-container .f-checkbox-checkmark{position:absolute;width:10px;height:10px;opacity:0;transform:scale(.7);transition:opacity .15s ease,transform .15s ease,color .15s ease}:host .f-checkbox-container .f-checkbox-checkmark .f-checkbox-checkmark-path{stroke:var(--checkbox-checkmark-color);stroke-width:2.75;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:32;stroke-dashoffset:32}:host label{-webkit-user-select:none;user-select:none;line-height:inherit}:host.f-checkbox-checked .f-checkbox-container{border-color:var(--checkbox-checked-background);background-color:var(--checkbox-checked-background)}:host.f-checkbox-checked .f-checkbox-container .f-checkbox-checkmark{opacity:1;transform:scale(1)}:host.f-checkbox-checked .f-checkbox-container .f-checkbox-checkmark .f-checkbox-checkmark-path{animation:f-checkbox-check-draw .22s cubic-bezier(.19,1,.22,1) forwards}@keyframes f-checkbox-check-draw{0%{stroke-dashoffset:32}to{stroke-dashoffset:0}}\n"] }]
1042
1042
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { id: [{
1043
1043
  type: Input
1044
1044
  }], change: [{
@@ -1060,6 +1060,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
1060
1060
  let uniqueId = 0;
1061
1061
  class FRadioButtonComponent {
1062
1062
  id = input(`f-radio-button-${uniqueId++}`, ...(ngDevMode ? [{ debugName: "id" }] : []));
1063
+ name = input(null, ...(ngDevMode ? [{ debugName: "name" }] : []));
1063
1064
  change = output();
1064
1065
  checked = input(false, ...(ngDevMode ? [{ debugName: "checked" }] : []));
1065
1066
  labelElement = viewChild('label', ...(ngDevMode ? [{ debugName: "labelElement" }] : []));
@@ -1084,14 +1085,14 @@ class FRadioButtonComponent {
1084
1085
  }
1085
1086
  }
1086
1087
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FRadioButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1087
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.1.4", type: FRadioButtonComponent, isStandalone: true, selector: "f-radio-button", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { change: "change" }, host: { listeners: { "click": "preventBubblingFromLabel($event)" }, properties: { "class.f-radio-button-checked": "checked()" } }, viewQueries: [{ propertyName: "labelElement", first: true, predicate: ["label"], descendants: true, isSignal: true }], ngImport: i0, template: "<input [id]=\"id()\"\n type=\"radio\"\n [checked]=\"checked()\"\n (click)=\"onInputClick()\"\n (change)=\"onInteractionEvent($event)\"/>\n<div class=\"f-radio-button-container\" (click)=\"onTouchTargetClick()\">\n <div class=\"f-radio-button-inner-circle\"></div>\n</div>\n<label [for]=\"id()\" #label>\n <ng-content></ng-content>\n</label>\n", styles: [":host{position:relative;display:flex;align-items:center;font-weight:400;white-space:nowrap;font-size:14px;cursor:pointer;background-color:var(--radio-button-container-background);border-radius:var(--radio-button-container-border-radius);padding:0 8px;color:var(--radio-button-text);transition:color .25s,background-color .25s}:host input{position:absolute;inset:0;opacity:0;cursor:pointer}:host .f-radio-button-container{position:relative;display:flex;align-items:center;justify-content:center;width:var(--radio-button-size);height:var(--radio-button-size);margin-right:6px;border-radius:50%;border:1px solid var(--radio-button-border-color);background-color:var(--radio-button-background)}:host .f-radio-button-container .f-radio-button-inner-circle{position:absolute;top:calc(var(--radio-button-size) / 4);right:calc(var(--radio-button-size) / 4);bottom:calc(var(--radio-button-size) / 4);left:calc(var(--radio-button-size) / 4);border-radius:50%}:host label{-webkit-user-select:none;user-select:none}:host.f-radio-button-checked .f-radio-button-container{background-color:var(--radio-button-checked-background)}:host.f-radio-button-checked .f-radio-button-container .f-radio-button-inner-circle{background-color:var(--radio-button-inner-circle-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1088
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.1.4", type: FRadioButtonComponent, isStandalone: true, selector: "f-radio-button", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { change: "change" }, host: { listeners: { "click": "preventBubblingFromLabel($event)" }, properties: { "class.f-radio-button-checked": "checked()" } }, viewQueries: [{ propertyName: "labelElement", first: true, predicate: ["label"], descendants: true, isSignal: true }], ngImport: i0, template: "<input [id]=\"id()\"\n [attr.name]=\"name()\"\n type=\"radio\"\n [checked]=\"checked()\"\n (click)=\"onInputClick()\"\n (change)=\"onInteractionEvent($event)\"/>\n<div class=\"f-radio-button-container\" (click)=\"onTouchTargetClick()\">\n <div class=\"f-radio-button-inner-circle\"></div>\n</div>\n<label [for]=\"id()\" #label>\n <ng-content></ng-content>\n</label>\n", styles: [":host{position:relative;display:inline-flex;align-items:flex-start;gap:6px;flex-shrink:0;font-size:14px;line-height:20px;font-weight:400;white-space:nowrap;cursor:pointer;color:var(--radio-button-text)}:host input{position:absolute;inset:0;opacity:0;cursor:pointer;margin:0}:host:hover .f-radio-button-container{border-color:var(--radio-button-border-color-hover)}:host .f-radio-button-container{position:relative;display:flex;align-items:center;justify-content:center;width:var(--radio-button-size);height:var(--radio-button-size);margin-top:2px;border-radius:50%;border:1px solid var(--radio-button-border-color);background-color:var(--radio-button-background);transition:border-color .15s ease,background-color .15s ease}:host .f-radio-button-container .f-radio-button-inner-circle{position:absolute;top:50%;left:50%;width:var(--radio-button-inner-circle-size);height:var(--radio-button-inner-circle-size);border-radius:50%;background-color:var(--radio-button-inner-circle-color);transform:translate(-50%,-50%) scale(0);transition:transform .15s ease,background-color .15s ease}:host label{-webkit-user-select:none;user-select:none;line-height:inherit}:host.f-radio-button-checked .f-radio-button-container{border-color:var(--radio-button-checked-background);background-color:var(--radio-button-checked-background)}:host.f-radio-button-checked .f-radio-button-container .f-radio-button-inner-circle{transform:translate(-50%,-50%) scale(1);animation:f-radio-button-scale-in .22s cubic-bezier(.19,1,.22,1)}@keyframes f-radio-button-scale-in{0%{transform:translate(-50%,-50%) scale(0)}to{transform:translate(-50%,-50%) scale(1)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1088
1089
  }
1089
1090
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FRadioButtonComponent, decorators: [{
1090
1091
  type: Component,
1091
1092
  args: [{ selector: 'f-radio-button', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
1092
1093
  '[class.f-radio-button-checked]': 'checked()',
1093
- }, template: "<input [id]=\"id()\"\n type=\"radio\"\n [checked]=\"checked()\"\n (click)=\"onInputClick()\"\n (change)=\"onInteractionEvent($event)\"/>\n<div class=\"f-radio-button-container\" (click)=\"onTouchTargetClick()\">\n <div class=\"f-radio-button-inner-circle\"></div>\n</div>\n<label [for]=\"id()\" #label>\n <ng-content></ng-content>\n</label>\n", styles: [":host{position:relative;display:flex;align-items:center;font-weight:400;white-space:nowrap;font-size:14px;cursor:pointer;background-color:var(--radio-button-container-background);border-radius:var(--radio-button-container-border-radius);padding:0 8px;color:var(--radio-button-text);transition:color .25s,background-color .25s}:host input{position:absolute;inset:0;opacity:0;cursor:pointer}:host .f-radio-button-container{position:relative;display:flex;align-items:center;justify-content:center;width:var(--radio-button-size);height:var(--radio-button-size);margin-right:6px;border-radius:50%;border:1px solid var(--radio-button-border-color);background-color:var(--radio-button-background)}:host .f-radio-button-container .f-radio-button-inner-circle{position:absolute;top:calc(var(--radio-button-size) / 4);right:calc(var(--radio-button-size) / 4);bottom:calc(var(--radio-button-size) / 4);left:calc(var(--radio-button-size) / 4);border-radius:50%}:host label{-webkit-user-select:none;user-select:none}:host.f-radio-button-checked .f-radio-button-container{background-color:var(--radio-button-checked-background)}:host.f-radio-button-checked .f-radio-button-container .f-radio-button-inner-circle{background-color:var(--radio-button-inner-circle-color)}\n"] }]
1094
- }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], change: [{ type: i0.Output, args: ["change"] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], labelElement: [{ type: i0.ViewChild, args: ['label', { isSignal: true }] }], preventBubblingFromLabel: [{
1094
+ }, template: "<input [id]=\"id()\"\n [attr.name]=\"name()\"\n type=\"radio\"\n [checked]=\"checked()\"\n (click)=\"onInputClick()\"\n (change)=\"onInteractionEvent($event)\"/>\n<div class=\"f-radio-button-container\" (click)=\"onTouchTargetClick()\">\n <div class=\"f-radio-button-inner-circle\"></div>\n</div>\n<label [for]=\"id()\" #label>\n <ng-content></ng-content>\n</label>\n", styles: [":host{position:relative;display:inline-flex;align-items:flex-start;gap:6px;flex-shrink:0;font-size:14px;line-height:20px;font-weight:400;white-space:nowrap;cursor:pointer;color:var(--radio-button-text)}:host input{position:absolute;inset:0;opacity:0;cursor:pointer;margin:0}:host:hover .f-radio-button-container{border-color:var(--radio-button-border-color-hover)}:host .f-radio-button-container{position:relative;display:flex;align-items:center;justify-content:center;width:var(--radio-button-size);height:var(--radio-button-size);margin-top:2px;border-radius:50%;border:1px solid var(--radio-button-border-color);background-color:var(--radio-button-background);transition:border-color .15s ease,background-color .15s ease}:host .f-radio-button-container .f-radio-button-inner-circle{position:absolute;top:50%;left:50%;width:var(--radio-button-inner-circle-size);height:var(--radio-button-inner-circle-size);border-radius:50%;background-color:var(--radio-button-inner-circle-color);transform:translate(-50%,-50%) scale(0);transition:transform .15s ease,background-color .15s ease}:host label{-webkit-user-select:none;user-select:none;line-height:inherit}:host.f-radio-button-checked .f-radio-button-container{border-color:var(--radio-button-checked-background);background-color:var(--radio-button-checked-background)}:host.f-radio-button-checked .f-radio-button-container .f-radio-button-inner-circle{transform:translate(-50%,-50%) scale(1);animation:f-radio-button-scale-in .22s cubic-bezier(.19,1,.22,1)}@keyframes f-radio-button-scale-in{0%{transform:translate(-50%,-50%) scale(0)}to{transform:translate(-50%,-50%) scale(1)}}\n"] }]
1095
+ }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], change: [{ type: i0.Output, args: ["change"] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], labelElement: [{ type: i0.ViewChild, args: ['label', { isSignal: true }] }], preventBubblingFromLabel: [{
1095
1096
  type: HostListener,
1096
1097
  args: ['click', ['$event']]
1097
1098
  }] } });
@@ -1157,7 +1158,7 @@ class HeaderComponent {
1157
1158
  cancelAnimationFrame(this._rafId);
1158
1159
  }
1159
1160
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: HeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1160
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: HeaderComponent, isStandalone: true, selector: "f-header", viewQueries: [{ propertyName: "_containerRef", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "_targetRef", first: true, predicate: ["target"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (emptyNavigation) {\n <f-brand-link class=\"empty-navigation-title\"\n [routerLink]=\"''\"\n [title]=\"title\"\n [logo]=\"image\" />\n} @else {\n <div class=\"portal-title\">\n <button hamburger-button></button>\n <div class=\"title text-ellipsis\">{{ title }}</div>\n </div>\n}\n\n@if (config.search) {\n <f-search-button [configuration]=\"config.searchConfiguration\"></f-search-button>\n <div class=\"divider search-divider\"></div>\n}\n\n<div class=\"collapsable-row\" #container>\n <div #target class=\"target\" [class.hidden]=\"initialized() && overflowed()\">\n @if (config.navigation) {\n <inline-menu />\n <div class=\"divider\"></div>\n }\n\n <button theme-button></button>\n <div class=\"divider\"></div>\n <media-links />\n </div>\n\n <div class=\"fallback\" [class.hidden]=\"!initialized() || !overflowed()\">\n <dropdown-menu />\n </div>\n</div>\n", styles: [":host{position:sticky;width:100%;top:0;display:flex;justify-content:flex-start;align-items:center;gap:12px;padding:0 20px;font-weight:600;color:var(--primary-text);height:var(--header-height);background-color:var(--surface-glass);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);border-bottom:1px solid var(--divider-color);box-shadow:0 1px 0 var(--alpha-02);z-index:var(--z-index-header)}@media(min-width:1280px){:host{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 3);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 4)}}@media(min-width:1280px){:host.empty-navigation{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2)}}.empty-navigation-title{display:flex;justify-content:flex-start;align-items:center;gap:10px;padding:0;font-weight:600;color:var(--primary-text);height:var(--header-height);width:100%;max-width:260px;margin-left:auto;cursor:pointer}.portal-title{display:flex;justify-content:flex-start;align-items:center;gap:12px}@media(min-width:960px){.portal-title{display:none}}.portal-title .title{font-weight:600;color:var(--primary-text);min-width:0}.divider{margin-right:8px;margin-left:8px;width:1px;height:18px;background-color:var(--divider-color);content:\"\"}@media(max-width:639px){.search-divider{margin-right:6px;margin-left:6px}}.collapsable-row{position:relative;width:100%;display:flex;justify-content:flex-end}.collapsable-row .target{display:flex;justify-content:flex-start;align-items:center;width:fit-content}.collapsable-row .target.hidden{position:absolute;left:-99999px;top:0;visibility:hidden;white-space:nowrap}.collapsable-row .fallback.hidden{display:none}\n"], dependencies: [{ kind: "component", type: HamburgerButton, selector: "button[hamburger-button]" }, { kind: "component", type: FBrandLinkComponent, selector: "f-brand-link", inputs: ["title", "logo", "ariaLabel", "logoAlt", "href", "routerLink"] }, { kind: "component", type: FSearchButtonComponent, selector: "f-search-button", inputs: ["configuration"] }, { kind: "component", type: ThemeButtonComponent, selector: "button[theme-button]" }, { kind: "component", type: InlineMenu, selector: "inline-menu" }, { kind: "component", type: DropdownMenu, selector: "dropdown-menu" }, { kind: "component", type: MediaLinks, selector: "media-links" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1161
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: HeaderComponent, isStandalone: true, selector: "f-header", viewQueries: [{ propertyName: "_containerRef", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "_targetRef", first: true, predicate: ["target"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (emptyNavigation) {\n <f-brand-link class=\"empty-navigation-title\"\n [routerLink]=\"''\"\n [title]=\"title\"\n [logo]=\"image\" />\n} @else {\n <div class=\"portal-title\">\n <button hamburger-button></button>\n <div class=\"title text-ellipsis\">{{ title }}</div>\n </div>\n}\n\n@if (config.search) {\n <f-search-button [configuration]=\"config.searchConfiguration\"></f-search-button>\n <div class=\"divider search-divider\"></div>\n}\n\n<div class=\"collapsable-row\" #container>\n <div #target class=\"target\" [class.hidden]=\"initialized() && overflowed()\">\n @if (config.navigation) {\n <inline-menu />\n <div class=\"divider\"></div>\n }\n\n <button theme-button></button>\n <div class=\"divider\"></div>\n <media-links />\n </div>\n\n <div class=\"fallback\" [class.hidden]=\"!initialized() || !overflowed()\">\n <dropdown-menu />\n </div>\n</div>\n", styles: [":host{position:sticky;width:100%;top:0;display:flex;justify-content:flex-start;align-items:center;gap:12px;padding:0 20px;font-weight:600;color:var(--primary-text);height:var(--header-height);background-color:var(--page-header-background);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);border-bottom:1px solid var(--page-shell-border-color);z-index:var(--z-index-header)}@media(min-width:1280px){:host{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 3);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 4)}}@media(min-width:1280px){:host.empty-navigation{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2)}}.empty-navigation-title{display:flex;justify-content:flex-start;align-items:center;gap:10px;padding:0;font-weight:600;color:var(--primary-text);height:var(--header-height);width:100%;max-width:260px;margin-left:auto;cursor:pointer}.portal-title{display:flex;justify-content:flex-start;align-items:center;gap:12px}@media(min-width:960px){.portal-title{display:none}}.portal-title .title{font-weight:600;color:var(--primary-text);min-width:0}.divider{margin-right:8px;margin-left:8px;width:1px;height:18px;background-color:var(--divider-color);content:\"\"}@media(max-width:639px){.search-divider{margin-right:6px;margin-left:6px}}.collapsable-row{position:relative;width:100%;display:flex;justify-content:flex-end}.collapsable-row .target{display:flex;justify-content:flex-start;align-items:center;width:fit-content}.collapsable-row .target.hidden{position:absolute;left:-99999px;top:0;visibility:hidden;white-space:nowrap}.collapsable-row .fallback.hidden{display:none}\n"], dependencies: [{ kind: "component", type: HamburgerButton, selector: "button[hamburger-button]" }, { kind: "component", type: FBrandLinkComponent, selector: "f-brand-link", inputs: ["title", "logo", "ariaLabel", "logoAlt", "href", "routerLink"] }, { kind: "component", type: FSearchButtonComponent, selector: "f-search-button", inputs: ["configuration"] }, { kind: "component", type: ThemeButtonComponent, selector: "button[theme-button]" }, { kind: "component", type: InlineMenu, selector: "inline-menu" }, { kind: "component", type: DropdownMenu, selector: "dropdown-menu" }, { kind: "component", type: MediaLinks, selector: "media-links" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1161
1162
  }
1162
1163
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: HeaderComponent, decorators: [{
1163
1164
  type: Component,
@@ -1169,7 +1170,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
1169
1170
  InlineMenu,
1170
1171
  DropdownMenu,
1171
1172
  MediaLinks,
1172
- ], template: "@if (emptyNavigation) {\n <f-brand-link class=\"empty-navigation-title\"\n [routerLink]=\"''\"\n [title]=\"title\"\n [logo]=\"image\" />\n} @else {\n <div class=\"portal-title\">\n <button hamburger-button></button>\n <div class=\"title text-ellipsis\">{{ title }}</div>\n </div>\n}\n\n@if (config.search) {\n <f-search-button [configuration]=\"config.searchConfiguration\"></f-search-button>\n <div class=\"divider search-divider\"></div>\n}\n\n<div class=\"collapsable-row\" #container>\n <div #target class=\"target\" [class.hidden]=\"initialized() && overflowed()\">\n @if (config.navigation) {\n <inline-menu />\n <div class=\"divider\"></div>\n }\n\n <button theme-button></button>\n <div class=\"divider\"></div>\n <media-links />\n </div>\n\n <div class=\"fallback\" [class.hidden]=\"!initialized() || !overflowed()\">\n <dropdown-menu />\n </div>\n</div>\n", styles: [":host{position:sticky;width:100%;top:0;display:flex;justify-content:flex-start;align-items:center;gap:12px;padding:0 20px;font-weight:600;color:var(--primary-text);height:var(--header-height);background-color:var(--surface-glass);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);border-bottom:1px solid var(--divider-color);box-shadow:0 1px 0 var(--alpha-02);z-index:var(--z-index-header)}@media(min-width:1280px){:host{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 3);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 4)}}@media(min-width:1280px){:host.empty-navigation{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2)}}.empty-navigation-title{display:flex;justify-content:flex-start;align-items:center;gap:10px;padding:0;font-weight:600;color:var(--primary-text);height:var(--header-height);width:100%;max-width:260px;margin-left:auto;cursor:pointer}.portal-title{display:flex;justify-content:flex-start;align-items:center;gap:12px}@media(min-width:960px){.portal-title{display:none}}.portal-title .title{font-weight:600;color:var(--primary-text);min-width:0}.divider{margin-right:8px;margin-left:8px;width:1px;height:18px;background-color:var(--divider-color);content:\"\"}@media(max-width:639px){.search-divider{margin-right:6px;margin-left:6px}}.collapsable-row{position:relative;width:100%;display:flex;justify-content:flex-end}.collapsable-row .target{display:flex;justify-content:flex-start;align-items:center;width:fit-content}.collapsable-row .target.hidden{position:absolute;left:-99999px;top:0;visibility:hidden;white-space:nowrap}.collapsable-row .fallback.hidden{display:none}\n"] }]
1173
+ ], template: "@if (emptyNavigation) {\n <f-brand-link class=\"empty-navigation-title\"\n [routerLink]=\"''\"\n [title]=\"title\"\n [logo]=\"image\" />\n} @else {\n <div class=\"portal-title\">\n <button hamburger-button></button>\n <div class=\"title text-ellipsis\">{{ title }}</div>\n </div>\n}\n\n@if (config.search) {\n <f-search-button [configuration]=\"config.searchConfiguration\"></f-search-button>\n <div class=\"divider search-divider\"></div>\n}\n\n<div class=\"collapsable-row\" #container>\n <div #target class=\"target\" [class.hidden]=\"initialized() && overflowed()\">\n @if (config.navigation) {\n <inline-menu />\n <div class=\"divider\"></div>\n }\n\n <button theme-button></button>\n <div class=\"divider\"></div>\n <media-links />\n </div>\n\n <div class=\"fallback\" [class.hidden]=\"!initialized() || !overflowed()\">\n <dropdown-menu />\n </div>\n</div>\n", styles: [":host{position:sticky;width:100%;top:0;display:flex;justify-content:flex-start;align-items:center;gap:12px;padding:0 20px;font-weight:600;color:var(--primary-text);height:var(--header-height);background-color:var(--page-header-background);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);border-bottom:1px solid var(--page-shell-border-color);z-index:var(--z-index-header)}@media(min-width:1280px){:host{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 3);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 4)}}@media(min-width:1280px){:host.empty-navigation{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2)}}.empty-navigation-title{display:flex;justify-content:flex-start;align-items:center;gap:10px;padding:0;font-weight:600;color:var(--primary-text);height:var(--header-height);width:100%;max-width:260px;margin-left:auto;cursor:pointer}.portal-title{display:flex;justify-content:flex-start;align-items:center;gap:12px}@media(min-width:960px){.portal-title{display:none}}.portal-title .title{font-weight:600;color:var(--primary-text);min-width:0}.divider{margin-right:8px;margin-left:8px;width:1px;height:18px;background-color:var(--divider-color);content:\"\"}@media(max-width:639px){.search-divider{margin-right:6px;margin-left:6px}}.collapsable-row{position:relative;width:100%;display:flex;justify-content:flex-end}.collapsable-row .target{display:flex;justify-content:flex-start;align-items:center;width:fit-content}.collapsable-row .target.hidden{position:absolute;left:-99999px;top:0;visibility:hidden;white-space:nowrap}.collapsable-row .fallback.hidden{display:none}\n"] }]
1173
1174
  }], propDecorators: { _containerRef: [{ type: i0.ViewChild, args: ['container', { isSignal: true }] }], _targetRef: [{ type: i0.ViewChild, args: ['target', { isSignal: true }] }] } });
1174
1175
 
1175
1176
  class NavigationGroupComponent {
@@ -1179,23 +1180,23 @@ class NavigationGroupComponent {
1179
1180
  this.isCollapsed.set(!this.isCollapsed());
1180
1181
  }
1181
1182
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: NavigationGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1182
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: NavigationGroupComponent, isStandalone: true, selector: "f-navigation-group", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.collapsed": "isCollapsed()", "class.no-title": "!title()" } }, ngImport: i0, template: "@if (title()) {\n <header (click)=\"toggle()\">\n <span>{{ title() }}</span>\n <div class=\"flex-space\"></div>\n <div class=\"caret\">\n <span class=\"chevron-right caret-icon\"></span>\n </div>\n </header>\n}\n@if (!isCollapsed()) {\n <ng-content></ng-content>\n}\n\n\n\n", styles: [":host{padding-top:18px;padding-bottom:18px;border-top:1px solid var(--divider-color);display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;width:100%;max-width:none;margin-left:0}:host.collapsed,:host.no-title{padding-top:12px;padding-bottom:12px}header{font-weight:700;color:var(--tertiary-text);flex-grow:1;padding:0 8px 8px;line-height:18px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;display:flex;justify-content:flex-start;align-items:center;width:100%}.caret{display:flex;justify-content:center;align-items:center;margin-right:-4px;width:28px;height:28px;border-radius:999px;color:var(--tertiary-text);cursor:pointer;transition:color .25s,background-color .25s;flex-shrink:0}:host:hover .caret{color:var(--secondary-text);background-color:var(--gray-soft)}:host:hover .caret:hover{color:var(--primary-text)}:host .caret-icon{font-size:18px;transform:rotate(90deg);transition:transform .25s;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:18px;height:18px}:host.collapsed .caret-icon{transform:rotate(0)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1183
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: NavigationGroupComponent, isStandalone: true, selector: "f-navigation-group", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.collapsed": "isCollapsed()", "class.no-title": "!title()" } }, ngImport: i0, template: "@if (title()) {\n <header (click)=\"toggle()\">\n <span>{{ title() }}</span>\n <div class=\"flex-space\"></div>\n <div class=\"caret\">\n <span class=\"chevron-right caret-icon\"></span>\n </div>\n </header>\n}\n@if (!isCollapsed()) {\n <ng-content></ng-content>\n}\n\n\n\n", styles: [":host{padding-top:18px;padding-bottom:18px;border-top:1px solid var(--divider-color);display:flex;flex-direction:column;gap:1px;justify-content:flex-start;align-items:flex-start;width:100%;max-width:none;margin-left:0}:host.collapsed,:host.no-title{padding-top:12px;padding-bottom:12px}header{font-weight:700;color:var(--tertiary-text);flex-grow:1;padding:0 8px 8px;line-height:18px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;display:flex;justify-content:flex-start;align-items:center;width:100%}.caret{display:flex;justify-content:center;align-items:center;margin-right:-4px;width:28px;height:28px;border-radius:999px;color:var(--tertiary-text);cursor:pointer;transition:color .25s,background-color .25s;flex-shrink:0}:host:hover .caret{color:var(--secondary-text);background-color:var(--gray-soft)}:host:hover .caret:hover{color:var(--primary-text)}:host .caret-icon{font-size:18px;transform:rotate(90deg);transition:transform .25s;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:18px;height:18px}:host.collapsed .caret-icon{transform:rotate(0)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1183
1184
  }
1184
1185
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: NavigationGroupComponent, decorators: [{
1185
1186
  type: Component,
1186
1187
  args: [{ selector: 'f-navigation-group', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
1187
1188
  '[class.collapsed]': 'isCollapsed()',
1188
1189
  '[class.no-title]': '!title()',
1189
- }, template: "@if (title()) {\n <header (click)=\"toggle()\">\n <span>{{ title() }}</span>\n <div class=\"flex-space\"></div>\n <div class=\"caret\">\n <span class=\"chevron-right caret-icon\"></span>\n </div>\n </header>\n}\n@if (!isCollapsed()) {\n <ng-content></ng-content>\n}\n\n\n\n", styles: [":host{padding-top:18px;padding-bottom:18px;border-top:1px solid var(--divider-color);display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;width:100%;max-width:none;margin-left:0}:host.collapsed,:host.no-title{padding-top:12px;padding-bottom:12px}header{font-weight:700;color:var(--tertiary-text);flex-grow:1;padding:0 8px 8px;line-height:18px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;display:flex;justify-content:flex-start;align-items:center;width:100%}.caret{display:flex;justify-content:center;align-items:center;margin-right:-4px;width:28px;height:28px;border-radius:999px;color:var(--tertiary-text);cursor:pointer;transition:color .25s,background-color .25s;flex-shrink:0}:host:hover .caret{color:var(--secondary-text);background-color:var(--gray-soft)}:host:hover .caret:hover{color:var(--primary-text)}:host .caret-icon{font-size:18px;transform:rotate(90deg);transition:transform .25s;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:18px;height:18px}:host.collapsed .caret-icon{transform:rotate(0)}\n"] }]
1190
+ }, template: "@if (title()) {\n <header (click)=\"toggle()\">\n <span>{{ title() }}</span>\n <div class=\"flex-space\"></div>\n <div class=\"caret\">\n <span class=\"chevron-right caret-icon\"></span>\n </div>\n </header>\n}\n@if (!isCollapsed()) {\n <ng-content></ng-content>\n}\n\n\n\n", styles: [":host{padding-top:18px;padding-bottom:18px;border-top:1px solid var(--divider-color);display:flex;flex-direction:column;gap:1px;justify-content:flex-start;align-items:flex-start;width:100%;max-width:none;margin-left:0}:host.collapsed,:host.no-title{padding-top:12px;padding-bottom:12px}header{font-weight:700;color:var(--tertiary-text);flex-grow:1;padding:0 8px 8px;line-height:18px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;display:flex;justify-content:flex-start;align-items:center;width:100%}.caret{display:flex;justify-content:center;align-items:center;margin-right:-4px;width:28px;height:28px;border-radius:999px;color:var(--tertiary-text);cursor:pointer;transition:color .25s,background-color .25s;flex-shrink:0}:host:hover .caret{color:var(--secondary-text);background-color:var(--gray-soft)}:host:hover .caret:hover{color:var(--primary-text)}:host .caret-icon{font-size:18px;transform:rotate(90deg);transition:transform .25s;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:18px;height:18px}:host.collapsed .caret-icon{transform:rotate(0)}\n"] }]
1190
1191
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }] } });
1191
1192
 
1192
1193
  class FNavigationItemComponent {
1193
1194
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FNavigationItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1194
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: FNavigationItemComponent, isStandalone: true, selector: "a[f-navigation-item]", ngImport: i0, template: "<ng-content></ng-content>\n\n\n\n", styles: [":host{font-weight:500;color:var(--secondary-text);flex-grow:1;padding:8px 10px;line-height:20px;font-size:14px;cursor:pointer;width:100%;border-radius:calc(var(--border-radius) - 2px);transition:background-color .2s ease,color .2s ease,box-shadow .2s ease;display:flex;align-items:center;justify-content:flex-start;gap:8px}:host:hover{text-decoration:none;color:var(--primary-text);background-color:var(--gray-soft)}:host.active{color:var(--primary-text);background-color:var(--soft-background);box-shadow:inset 0 0 0 1px var(--divider-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1195
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: FNavigationItemComponent, isStandalone: true, selector: "a[f-navigation-item]", ngImport: i0, template: "<ng-content></ng-content>\n\n\n\n", styles: [":host{font-weight:500;color:var(--secondary-text);flex-grow:1;padding:8px 10px;line-height:20px;font-size:14px;cursor:pointer;width:100%;border-radius:calc(var(--border-radius) - 2px);display:flex;align-items:center;justify-content:flex-start;gap:8px}:host:hover{text-decoration:none;color:var(--primary-text);background-color:var(--gray-soft)}:host.active{color:var(--primary-text);background-color:var(--soft-background)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1195
1196
  }
1196
1197
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FNavigationItemComponent, decorators: [{
1197
1198
  type: Component,
1198
- args: [{ selector: 'a[f-navigation-item]', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>\n\n\n\n", styles: [":host{font-weight:500;color:var(--secondary-text);flex-grow:1;padding:8px 10px;line-height:20px;font-size:14px;cursor:pointer;width:100%;border-radius:calc(var(--border-radius) - 2px);transition:background-color .2s ease,color .2s ease,box-shadow .2s ease;display:flex;align-items:center;justify-content:flex-start;gap:8px}:host:hover{text-decoration:none;color:var(--primary-text);background-color:var(--gray-soft)}:host.active{color:var(--primary-text);background-color:var(--soft-background);box-shadow:inset 0 0 0 1px var(--divider-color)}\n"] }]
1199
+ args: [{ selector: 'a[f-navigation-item]', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>\n\n\n\n", styles: [":host{font-weight:500;color:var(--secondary-text);flex-grow:1;padding:8px 10px;line-height:20px;font-size:14px;cursor:pointer;width:100%;border-radius:calc(var(--border-radius) - 2px);display:flex;align-items:center;justify-content:flex-start;gap:8px}:host:hover{text-decoration:none;color:var(--primary-text);background-color:var(--gray-soft)}:host.active{color:var(--primary-text);background-color:var(--soft-background)}\n"] }]
1199
1200
  }] });
1200
1201
 
1201
1202
  class NavigationPanelComponent {
@@ -1258,7 +1259,7 @@ class NavigationPanelComponent {
1258
1259
  new HandleNavigationLinksHandler().handle(new HandleNavigationLinksRequest(event, this._window, this._router));
1259
1260
  }
1260
1261
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: NavigationPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1261
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: NavigationPanelComponent, isStandalone: true, selector: "f-navigation-panel", host: { listeners: { "click": "_onDocumentClick($event)" } }, ngImport: i0, template: "<a routerLink class=\"navigation-header\">\n <img [src]=\"image\" width=\"24\" height=\"24\" alt=\"logo\" class=\"logo\"/> {{ title }}\n</a>\n\n@for (group of navigation; track group) {\n <f-navigation-group [title]=\"group.text\">\n @for (item of group.items; track item.link) {\n <a f-navigation-item [href]=\"item.link\" [class.active]=\"item.link === value\">\n <div class=\"text-ellipsis\">{{ item.text }}</div>\n @if (item.badge) {\n <span class=\"f-badge {{ item.badge.type }}\">{{ item.badge.text }}</span>\n }\n </a>\n }\n </f-navigation-group>\n}\n\n", styles: [":host{height:100%;flex-direction:column;justify-content:flex-start;align-items:flex-start;padding:0 var(--navigation-panel-padding) 40px;background-color:var(--navigation-panel-background);-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);border-right:1px solid var(--divider-color);overflow:hidden;overflow-y:auto;position:fixed;width:var(--navigation-panel-width);top:0;left:calc(-1 * var(--navigation-panel-width));transition:transform .2s ease-in-out;z-index:var(--z-index-navigation);transform:none;box-shadow:var(--shadow-4)}@media(min-width:960px){:host{position:unset;display:flex;min-width:var(--navigation-panel-width);width:var(--navigation-panel-width);box-shadow:none;transform:none!important}}@media(min-width:1440px){:host{min-width:calc((100% - (var(--layout-max-width) - 64px)) / 3 + var(--navigation-panel-width) - var(--navigation-panel-padding))}}:host.visible{transform:translate(var(--navigation-panel-width))}.navigation-header{display:flex;justify-content:flex-start;align-items:center;gap:10px;padding:0;font-weight:600;color:var(--primary-text);height:var(--header-height);width:100%;margin-left:0;cursor:pointer}.navigation-header img{margin-right:0}\n"], dependencies: [{ kind: "component", type: FNavigationItemComponent, selector: "a[f-navigation-item]" }, { kind: "component", type: NavigationGroupComponent, selector: "f-navigation-group", inputs: ["title"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1262
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: NavigationPanelComponent, isStandalone: true, selector: "f-navigation-panel", host: { listeners: { "click": "_onDocumentClick($event)" } }, ngImport: i0, template: "<a routerLink class=\"navigation-header\">\n <img [src]=\"image\" width=\"24\" height=\"24\" alt=\"logo\" class=\"logo\"/> {{ title }}\n</a>\n\n@for (group of navigation; track group) {\n <f-navigation-group [title]=\"group.text\">\n @for (item of group.items; track item.link) {\n <a f-navigation-item [href]=\"item.link\" [class.active]=\"item.link === value\">\n <div class=\"text-ellipsis\">{{ item.text }}</div>\n @if (item.badge) {\n <span class=\"f-badge {{ item.badge.type }}\">{{ item.badge.text }}</span>\n }\n </a>\n }\n </f-navigation-group>\n}\n\n", styles: [":host{height:100%;flex-direction:column;justify-content:flex-start;align-items:flex-start;padding:0 var(--navigation-panel-padding) 40px;background-color:var(--navigation-panel-background);-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);border-right:1px solid var(--page-shell-border-color);overflow:hidden;overflow-y:auto;position:fixed;width:var(--navigation-panel-width);top:0;left:calc(-1 * var(--navigation-panel-width));transition:transform .2s ease-in-out;z-index:var(--z-index-navigation);transform:none;box-shadow:var(--shadow-4)}@media(min-width:960px){:host{position:unset;display:flex;min-width:var(--navigation-panel-width);width:var(--navigation-panel-width);box-shadow:none;transform:none!important}}@media(min-width:1440px){:host{min-width:calc((100% - (var(--layout-max-width) - 64px)) / 3 + var(--navigation-panel-width) - var(--navigation-panel-padding))}}:host.visible{transform:translate(var(--navigation-panel-width))}.navigation-header{display:flex;justify-content:flex-start;align-items:center;gap:10px;padding:0;font-weight:600;color:var(--primary-text);width:100%;margin-left:0;cursor:pointer;min-height:calc(var(--header-height) - 1px)}.navigation-header img{margin-right:0}\n"], dependencies: [{ kind: "component", type: FNavigationItemComponent, selector: "a[f-navigation-item]" }, { kind: "component", type: NavigationGroupComponent, selector: "f-navigation-group", inputs: ["title"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1262
1263
  }
1263
1264
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: NavigationPanelComponent, decorators: [{
1264
1265
  type: Component,
@@ -1266,7 +1267,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
1266
1267
  FNavigationItemComponent,
1267
1268
  NavigationGroupComponent,
1268
1269
  RouterLink,
1269
- ], template: "<a routerLink class=\"navigation-header\">\n <img [src]=\"image\" width=\"24\" height=\"24\" alt=\"logo\" class=\"logo\"/> {{ title }}\n</a>\n\n@for (group of navigation; track group) {\n <f-navigation-group [title]=\"group.text\">\n @for (item of group.items; track item.link) {\n <a f-navigation-item [href]=\"item.link\" [class.active]=\"item.link === value\">\n <div class=\"text-ellipsis\">{{ item.text }}</div>\n @if (item.badge) {\n <span class=\"f-badge {{ item.badge.type }}\">{{ item.badge.text }}</span>\n }\n </a>\n }\n </f-navigation-group>\n}\n\n", styles: [":host{height:100%;flex-direction:column;justify-content:flex-start;align-items:flex-start;padding:0 var(--navigation-panel-padding) 40px;background-color:var(--navigation-panel-background);-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);border-right:1px solid var(--divider-color);overflow:hidden;overflow-y:auto;position:fixed;width:var(--navigation-panel-width);top:0;left:calc(-1 * var(--navigation-panel-width));transition:transform .2s ease-in-out;z-index:var(--z-index-navigation);transform:none;box-shadow:var(--shadow-4)}@media(min-width:960px){:host{position:unset;display:flex;min-width:var(--navigation-panel-width);width:var(--navigation-panel-width);box-shadow:none;transform:none!important}}@media(min-width:1440px){:host{min-width:calc((100% - (var(--layout-max-width) - 64px)) / 3 + var(--navigation-panel-width) - var(--navigation-panel-padding))}}:host.visible{transform:translate(var(--navigation-panel-width))}.navigation-header{display:flex;justify-content:flex-start;align-items:center;gap:10px;padding:0;font-weight:600;color:var(--primary-text);height:var(--header-height);width:100%;margin-left:0;cursor:pointer}.navigation-header img{margin-right:0}\n"] }]
1270
+ ], template: "<a routerLink class=\"navigation-header\">\n <img [src]=\"image\" width=\"24\" height=\"24\" alt=\"logo\" class=\"logo\"/> {{ title }}\n</a>\n\n@for (group of navigation; track group) {\n <f-navigation-group [title]=\"group.text\">\n @for (item of group.items; track item.link) {\n <a f-navigation-item [href]=\"item.link\" [class.active]=\"item.link === value\">\n <div class=\"text-ellipsis\">{{ item.text }}</div>\n @if (item.badge) {\n <span class=\"f-badge {{ item.badge.type }}\">{{ item.badge.text }}</span>\n }\n </a>\n }\n </f-navigation-group>\n}\n\n", styles: [":host{height:100%;flex-direction:column;justify-content:flex-start;align-items:flex-start;padding:0 var(--navigation-panel-padding) 40px;background-color:var(--navigation-panel-background);-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);border-right:1px solid var(--page-shell-border-color);overflow:hidden;overflow-y:auto;position:fixed;width:var(--navigation-panel-width);top:0;left:calc(-1 * var(--navigation-panel-width));transition:transform .2s ease-in-out;z-index:var(--z-index-navigation);transform:none;box-shadow:var(--shadow-4)}@media(min-width:960px){:host{position:unset;display:flex;min-width:var(--navigation-panel-width);width:var(--navigation-panel-width);box-shadow:none;transform:none!important}}@media(min-width:1440px){:host{min-width:calc((100% - (var(--layout-max-width) - 64px)) / 3 + var(--navigation-panel-width) - var(--navigation-panel-padding))}}:host.visible{transform:translate(var(--navigation-panel-width))}.navigation-header{display:flex;justify-content:flex-start;align-items:center;gap:10px;padding:0;font-weight:600;color:var(--primary-text);width:100%;margin-left:0;cursor:pointer;min-height:calc(var(--header-height) - 1px)}.navigation-header img{margin-right:0}\n"] }]
1270
1271
  }], propDecorators: { _onDocumentClick: [{
1271
1272
  type: HostListener,
1272
1273
  args: ['click', ['$event']]
@@ -1328,11 +1329,11 @@ class FooterNavigationButton {
1328
1329
  description;
1329
1330
  link;
1330
1331
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FooterNavigationButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
1331
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: FooterNavigationButton, isStandalone: true, selector: "a[footer-navigation-button]", inputs: { description: "description", link: "link" }, ngImport: i0, template: "<span class=\"description\">{{ description }}</span>\n<span class=\"page-title\">{{ link.text }}</span>\n", styles: [":host{display:block;border:1px solid var(--divider-color);border-radius:2px;padding:12px 16px;flex:1;max-width:50%;min-width:260px;text-decoration:none!important;cursor:pointer;pointer-events:all}:host:hover{border-color:var(--dark-divider-color)}:host:active{border-color:var(--primary-1)}:host.next{margin-left:auto;text-align:right}:host .description{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--secondary-text);pointer-events:none}:host .page-title{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--primary-1);pointer-events:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1332
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: FooterNavigationButton, isStandalone: true, selector: "a[footer-navigation-button]", inputs: { description: "description", link: "link" }, ngImport: i0, template: "<span class=\"description\">{{ description }}</span>\n<span class=\"page-title\">{{ link.text }}</span>\n", styles: [":host{display:block;border:1px solid var(--footer-navigation-button-border-color);border-radius:2px;padding:12px 16px;flex:1;max-width:50%;min-width:260px;text-decoration:none!important;cursor:pointer;pointer-events:all}:host:hover{border-color:var(--footer-navigation-button-hover-border-color)}:host:active{border-color:var(--primary-1)}:host.next{margin-left:auto;text-align:right}:host .description{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--secondary-text);pointer-events:none}:host .page-title{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--primary-1);pointer-events:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1332
1333
  }
1333
1334
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FooterNavigationButton, decorators: [{
1334
1335
  type: Component,
1335
- args: [{ selector: 'a[footer-navigation-button]', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<span class=\"description\">{{ description }}</span>\n<span class=\"page-title\">{{ link.text }}</span>\n", styles: [":host{display:block;border:1px solid var(--divider-color);border-radius:2px;padding:12px 16px;flex:1;max-width:50%;min-width:260px;text-decoration:none!important;cursor:pointer;pointer-events:all}:host:hover{border-color:var(--dark-divider-color)}:host:active{border-color:var(--primary-1)}:host.next{margin-left:auto;text-align:right}:host .description{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--secondary-text);pointer-events:none}:host .page-title{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--primary-1);pointer-events:none}\n"] }]
1336
+ args: [{ selector: 'a[footer-navigation-button]', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<span class=\"description\">{{ description }}</span>\n<span class=\"page-title\">{{ link.text }}</span>\n", styles: [":host{display:block;border:1px solid var(--footer-navigation-button-border-color);border-radius:2px;padding:12px 16px;flex:1;max-width:50%;min-width:260px;text-decoration:none!important;cursor:pointer;pointer-events:all}:host:hover{border-color:var(--footer-navigation-button-hover-border-color)}:host:active{border-color:var(--primary-1)}:host.next{margin-left:auto;text-align:right}:host .description{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--secondary-text);pointer-events:none}:host .page-title{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--primary-1);pointer-events:none}\n"] }]
1336
1337
  }], propDecorators: { description: [{
1337
1338
  type: Input,
1338
1339
  args: [{ required: true }]
@@ -1390,13 +1391,13 @@ class MarkdownFooter {
1390
1391
  new HandleNavigationLinksHandler().handle(new HandleNavigationLinksRequest(event, this._window, this._router));
1391
1392
  }
1392
1393
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: MarkdownFooter, deps: [], target: i0.ɵɵFactoryTarget.Component });
1393
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: MarkdownFooter, isStandalone: true, selector: "markdown-footer", host: { listeners: { "click": "_click($event)" } }, ngImport: i0, template: "@let eLink = editLink();\n@let pLink = previousLink();\n@let nLink = nextLink();\n\n@if (eLink) {\n <a class=\"footer-edit-link\" [href]=\"eLink\">\n <span class=\"edit-link-icon f-icon edit\"></span>\n {{ navigation.editLink?.text || 'Edit this page on GitHub' }}\n </a>\n}\n\n@if (pLink || nLink) {\n <nav class=\"footer-navigation\">\n @if (pLink) {\n <a footer-navigation-button\n [href]=\"pLink.link\"\n [description]=\"navigation.previous\"\n [link]=\"pLink\">\n </a>\n }\n @if (nLink) {\n <a footer-navigation-button class=\"next\"\n [href]=\"nLink.link\"\n [description]=\"navigation.next\"\n [link]=\"nLink\">\n </a>\n }\n </nav>\n}\n\n", styles: [":host{display:block;margin-top:64px}.footer-edit-link{display:flex;width:fit-content;align-items:center;border:0;line-height:32px;font-size:14px;font-weight:500;color:var(--primary-1);cursor:pointer;padding-bottom:18px}.footer-edit-link .edit-link-icon{margin-right:8px;width:14px;height:14px;color:inherit}.footer-edit-link:hover{color:var(--primary-2)}@media(min-width:640px){.footer-edit-link{padding-bottom:14px}}.footer-navigation{border-top:1px solid var(--divider-color);padding-top:24px;display:flex;justify-content:flex-start;align-items:flex-start;flex-wrap:wrap;gap:16px}\n"], dependencies: [{ kind: "component", type: FooterNavigationButton, selector: "a[footer-navigation-button]", inputs: ["description", "link"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1394
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: MarkdownFooter, isStandalone: true, selector: "markdown-footer", host: { listeners: { "click": "_click($event)" } }, ngImport: i0, template: "@let eLink = editLink();\n@let pLink = previousLink();\n@let nLink = nextLink();\n\n@if (eLink) {\n <a class=\"footer-edit-link f-text-link f-text-link-primary\" [href]=\"eLink\">\n <span class=\"edit-link-icon f-icon edit\"></span>\n {{ navigation.editLink?.text || 'Edit this page on GitHub' }}\n </a>\n}\n\n@if (pLink || nLink) {\n <nav class=\"footer-navigation\">\n @if (pLink) {\n <a footer-navigation-button\n [href]=\"pLink.link\"\n [description]=\"navigation.previous\"\n [link]=\"pLink\">\n </a>\n }\n @if (nLink) {\n <a footer-navigation-button class=\"next\"\n [href]=\"nLink.link\"\n [description]=\"navigation.next\"\n [link]=\"nLink\">\n </a>\n }\n </nav>\n}\n", styles: [":host{display:block;margin-top:64px}.footer-edit-link{display:flex;width:fit-content;align-items:center;border:0;line-height:32px;font-size:14px;cursor:pointer;padding-bottom:18px}.footer-edit-link .edit-link-icon{margin-right:8px;width:14px;height:14px;color:inherit}@media(min-width:640px){.footer-edit-link{padding-bottom:14px}}.footer-navigation{border-top:1px solid var(--footer-navigation-border-color);padding-top:24px;display:flex;justify-content:flex-start;align-items:flex-start;flex-wrap:wrap;gap:16px}\n"], dependencies: [{ kind: "component", type: FooterNavigationButton, selector: "a[footer-navigation-button]", inputs: ["description", "link"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1394
1395
  }
1395
1396
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: MarkdownFooter, decorators: [{
1396
1397
  type: Component,
1397
1398
  args: [{ selector: 'markdown-footer', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1398
1399
  FooterNavigationButton,
1399
- ], standalone: true, template: "@let eLink = editLink();\n@let pLink = previousLink();\n@let nLink = nextLink();\n\n@if (eLink) {\n <a class=\"footer-edit-link\" [href]=\"eLink\">\n <span class=\"edit-link-icon f-icon edit\"></span>\n {{ navigation.editLink?.text || 'Edit this page on GitHub' }}\n </a>\n}\n\n@if (pLink || nLink) {\n <nav class=\"footer-navigation\">\n @if (pLink) {\n <a footer-navigation-button\n [href]=\"pLink.link\"\n [description]=\"navigation.previous\"\n [link]=\"pLink\">\n </a>\n }\n @if (nLink) {\n <a footer-navigation-button class=\"next\"\n [href]=\"nLink.link\"\n [description]=\"navigation.next\"\n [link]=\"nLink\">\n </a>\n }\n </nav>\n}\n\n", styles: [":host{display:block;margin-top:64px}.footer-edit-link{display:flex;width:fit-content;align-items:center;border:0;line-height:32px;font-size:14px;font-weight:500;color:var(--primary-1);cursor:pointer;padding-bottom:18px}.footer-edit-link .edit-link-icon{margin-right:8px;width:14px;height:14px;color:inherit}.footer-edit-link:hover{color:var(--primary-2)}@media(min-width:640px){.footer-edit-link{padding-bottom:14px}}.footer-navigation{border-top:1px solid var(--divider-color);padding-top:24px;display:flex;justify-content:flex-start;align-items:flex-start;flex-wrap:wrap;gap:16px}\n"] }]
1400
+ ], standalone: true, template: "@let eLink = editLink();\n@let pLink = previousLink();\n@let nLink = nextLink();\n\n@if (eLink) {\n <a class=\"footer-edit-link f-text-link f-text-link-primary\" [href]=\"eLink\">\n <span class=\"edit-link-icon f-icon edit\"></span>\n {{ navigation.editLink?.text || 'Edit this page on GitHub' }}\n </a>\n}\n\n@if (pLink || nLink) {\n <nav class=\"footer-navigation\">\n @if (pLink) {\n <a footer-navigation-button\n [href]=\"pLink.link\"\n [description]=\"navigation.previous\"\n [link]=\"pLink\">\n </a>\n }\n @if (nLink) {\n <a footer-navigation-button class=\"next\"\n [href]=\"nLink.link\"\n [description]=\"navigation.next\"\n [link]=\"nLink\">\n </a>\n }\n </nav>\n}\n", styles: [":host{display:block;margin-top:64px}.footer-edit-link{display:flex;width:fit-content;align-items:center;border:0;line-height:32px;font-size:14px;cursor:pointer;padding-bottom:18px}.footer-edit-link .edit-link-icon{margin-right:8px;width:14px;height:14px;color:inherit}@media(min-width:640px){.footer-edit-link{padding-bottom:14px}}.footer-navigation{border-top:1px solid var(--footer-navigation-border-color);padding-top:24px;display:flex;justify-content:flex-start;align-items:flex-start;flex-wrap:wrap;gap:16px}\n"] }]
1400
1401
  }], propDecorators: { _click: [{
1401
1402
  type: HostListener,
1402
1403
  args: ['click', ['$event']]
@@ -2052,6 +2053,28 @@ function MExecution(requestType) {
2052
2053
  };
2053
2054
  }
2054
2055
 
2056
+ const EXAMPLE_VIEW = new InjectionToken('EXAMPLE_VIEW');
2057
+ class ExampleViewController {
2058
+ _isFullscreen = signal(false, ...(ngDevMode ? [{ debugName: "_isFullscreen" }] : []));
2059
+ _loadingCount = signal(0, ...(ngDevMode ? [{ debugName: "_loadingCount" }] : []));
2060
+ isFullscreen = this._isFullscreen.asReadonly();
2061
+ isLoading = computed(() => this._loadingCount() > 0, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
2062
+ showLoading() {
2063
+ this._loadingCount.update((value) => value + 1);
2064
+ }
2065
+ hideLoading() {
2066
+ this._loadingCount.update((value) => Math.max(0, value - 1));
2067
+ }
2068
+ setFullscreen(value) {
2069
+ this._isFullscreen.set(value);
2070
+ }
2071
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ExampleViewController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2072
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ExampleViewController });
2073
+ }
2074
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ExampleViewController, decorators: [{
2075
+ type: Injectable
2076
+ }] });
2077
+
2055
2078
  function coerceComponentHeight$1(value) {
2056
2079
  if (value === undefined || value === null) {
2057
2080
  return undefined;
@@ -2132,7 +2155,9 @@ let RenderDynamicComponent = class RenderDynamicComponent {
2132
2155
  this._logComponentResolutionError(selector);
2133
2156
  return;
2134
2157
  }
2135
- const componentRef = viewContainerRef.createComponent(extracted);
2158
+ const componentRef = viewContainerRef.createComponent(extracted, {
2159
+ injector: viewContainerRef.injector,
2160
+ });
2136
2161
  this._dynamicStore.addComponent(componentRef, element);
2137
2162
  element?.replaceWith(this._extractComponentRoot(componentRef));
2138
2163
  }).catch(error => this._logComponentLoadingError(selector, error));
@@ -2252,6 +2277,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
2252
2277
  }] });
2253
2278
 
2254
2279
  class ExternalComponent {
2280
+ _defaultLoadingTimeout = null;
2255
2281
  data = input.required({ ...(ngDevMode ? { debugName: "data" } : {}), transform: (x) => {
2256
2282
  const value = x.value?.trim() || '';
2257
2283
  return {
@@ -2276,14 +2302,19 @@ class ExternalComponent {
2276
2302
  && typeof this._document.exitFullscreen === 'function';
2277
2303
  }, ...(ngDevMode ? [{ debugName: "canToggleFullscreen" }] : []));
2278
2304
  fullscreenLabel = computed(() => this.isFullscreen() ? 'Exit full screen' : 'Full screen', ...(ngDevMode ? [{ debugName: "fullscreenLabel" }] : []));
2279
- isFullscreen = signal(false, ...(ngDevMode ? [{ debugName: "isFullscreen" }] : []));
2280
2305
  _document = inject(DOCUMENT);
2306
+ _destroyRef = inject(DestroyRef);
2307
+ _exampleViewController = inject(ExampleViewController);
2281
2308
  _hostElement = inject(ElementRef);
2282
2309
  _isBrowser = inject(IS_BROWSER_PLATFORM);
2283
2310
  _mediatr = inject(Mediatr);
2284
2311
  _viewContainerRef = viewChild.required('container', { read: ViewContainerRef });
2285
2312
  _sanitizer = inject(DomSanitizer);
2313
+ isFullscreen = this._exampleViewController.isFullscreen;
2314
+ isLoading = this._exampleViewController.isLoading;
2286
2315
  ngOnInit() {
2316
+ this._exampleViewController.setFullscreen(this._isCurrentElementInFullscreen());
2317
+ this._startDefaultLoading();
2287
2318
  const selector = this.data().selector;
2288
2319
  if (selector) {
2289
2320
  this._mediatr.execute(new RenderExternalComponentRequest(selector, this._viewContainerRef()));
@@ -2309,21 +2340,50 @@ class ExternalComponent {
2309
2340
  }
2310
2341
  }
2311
2342
  onFullscreenChange() {
2312
- this.isFullscreen.set(this._isCurrentElementInFullscreen());
2343
+ this._exampleViewController.setFullscreen(this._isCurrentElementInFullscreen());
2313
2344
  }
2314
2345
  _isCurrentElementInFullscreen() {
2315
2346
  return this._document.fullscreenElement === this._hostElement.nativeElement;
2316
2347
  }
2348
+ _startDefaultLoading() {
2349
+ if (!this.hasContent()) {
2350
+ return;
2351
+ }
2352
+ this._exampleViewController.showLoading();
2353
+ this._defaultLoadingTimeout = setTimeout(() => {
2354
+ this._exampleViewController.hideLoading();
2355
+ this._defaultLoadingTimeout = null;
2356
+ }, 1000);
2357
+ this._destroyRef.onDestroy(() => {
2358
+ if (this._defaultLoadingTimeout) {
2359
+ clearTimeout(this._defaultLoadingTimeout);
2360
+ this._defaultLoadingTimeout = null;
2361
+ }
2362
+ });
2363
+ }
2317
2364
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ExternalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2318
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: ExternalComponent, isStandalone: true, selector: "external-component", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "document:fullscreenchange": "onFullscreenChange()" }, properties: { "style.height": "data().height", "class.f-example-view-fullscreen": "isFullscreen()" }, classAttribute: "f-example-view" }, viewQueries: [{ propertyName: "_viewContainerRef", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "@if (canToggleFullscreen()) {\n <button class=\"f-fullscreen-button\"\n type=\"button\"\n [class.exit]=\"isFullscreen()\"\n [attr.aria-label]=\"fullscreenLabel()\"\n [attr.title]=\"fullscreenLabel()\"\n (click)=\"toggleFullscreen()\"></button>\n}\n\n@if (iframeResourceUrl()) {\n <iframe class=\"f-example-iframe\"\n [src]=\"iframeResourceUrl()\"\n loading=\"lazy\"\n referrerpolicy=\"no-referrer\"\n allow=\"fullscreen\"\n allowfullscreen></iframe>\n}\n\n<ng-container #container />\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
2365
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: ExternalComponent, isStandalone: true, selector: "external-component", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "document:fullscreenchange": "onFullscreenChange()" }, properties: { "style.height": "data().height", "class.f-example-view-fullscreen": "isFullscreen()", "attr.aria-busy": "isLoading()" }, classAttribute: "f-example-view" }, providers: [
2366
+ ExampleViewController,
2367
+ {
2368
+ provide: EXAMPLE_VIEW,
2369
+ useExisting: ExampleViewController,
2370
+ },
2371
+ ], viewQueries: [{ propertyName: "_viewContainerRef", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "@if (canToggleFullscreen()) {\n <button class=\"f-fullscreen-button\"\n type=\"button\"\n [class.exit]=\"isFullscreen()\"\n [attr.aria-label]=\"fullscreenLabel()\"\n [attr.title]=\"fullscreenLabel()\"\n (click)=\"toggleFullscreen()\"></button>\n}\n\n@if (iframeResourceUrl()) {\n <iframe class=\"f-example-iframe\"\n [src]=\"iframeResourceUrl()\"\n loading=\"lazy\"\n referrerpolicy=\"no-referrer\"\n allow=\"fullscreen\"\n allowfullscreen></iframe>\n}\n\n<ng-container #container />\n\n@if (isLoading()) {\n <div class=\"f-example-loading-overlay\" role=\"status\" aria-live=\"polite\" aria-label=\"Loading preview\">\n <div class=\"f-loading-dots\" aria-hidden=\"true\">\n <span class=\"f-loading-dot\"></span>\n <span class=\"f-loading-dot\"></span>\n <span class=\"f-loading-dot\"></span>\n </div>\n </div>\n}\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
2319
2372
  }
2320
2373
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ExternalComponent, decorators: [{
2321
2374
  type: Component,
2322
- args: [{ selector: 'external-component', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
2375
+ args: [{ selector: 'external-component', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
2376
+ ExampleViewController,
2377
+ {
2378
+ provide: EXAMPLE_VIEW,
2379
+ useExisting: ExampleViewController,
2380
+ },
2381
+ ], host: {
2323
2382
  class: 'f-example-view',
2324
2383
  '[style.height]': 'data().height',
2325
2384
  '[class.f-example-view-fullscreen]': 'isFullscreen()',
2326
- }, template: "@if (canToggleFullscreen()) {\n <button class=\"f-fullscreen-button\"\n type=\"button\"\n [class.exit]=\"isFullscreen()\"\n [attr.aria-label]=\"fullscreenLabel()\"\n [attr.title]=\"fullscreenLabel()\"\n (click)=\"toggleFullscreen()\"></button>\n}\n\n@if (iframeResourceUrl()) {\n <iframe class=\"f-example-iframe\"\n [src]=\"iframeResourceUrl()\"\n loading=\"lazy\"\n referrerpolicy=\"no-referrer\"\n allow=\"fullscreen\"\n allowfullscreen></iframe>\n}\n\n<ng-container #container />\n" }]
2385
+ '[attr.aria-busy]': 'isLoading()',
2386
+ }, template: "@if (canToggleFullscreen()) {\n <button class=\"f-fullscreen-button\"\n type=\"button\"\n [class.exit]=\"isFullscreen()\"\n [attr.aria-label]=\"fullscreenLabel()\"\n [attr.title]=\"fullscreenLabel()\"\n (click)=\"toggleFullscreen()\"></button>\n}\n\n@if (iframeResourceUrl()) {\n <iframe class=\"f-example-iframe\"\n [src]=\"iframeResourceUrl()\"\n loading=\"lazy\"\n referrerpolicy=\"no-referrer\"\n allow=\"fullscreen\"\n allowfullscreen></iframe>\n}\n\n<ng-container #container />\n\n@if (isLoading()) {\n <div class=\"f-example-loading-overlay\" role=\"status\" aria-live=\"polite\" aria-label=\"Loading preview\">\n <div class=\"f-loading-dots\" aria-hidden=\"true\">\n <span class=\"f-loading-dot\"></span>\n <span class=\"f-loading-dot\"></span>\n <span class=\"f-loading-dot\"></span>\n </div>\n </div>\n}\n" }]
2327
2387
  }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], _viewContainerRef: [{ type: i0.ViewChild, args: ['container', { ...{ read: ViewContainerRef }, isSignal: true }] }], onFullscreenChange: [{
2328
2388
  type: HostListener,
2329
2389
  args: ['document:fullscreenchange']
@@ -2365,7 +2425,8 @@ class CodeView {
2365
2425
  content = signal('', ...(ngDevMode ? [{ debugName: "content" }] : []));
2366
2426
  visibleLanguage = signal('', ...(ngDevMode ? [{ debugName: "visibleLanguage" }] : []));
2367
2427
  syntaxLanguage = signal('', ...(ngDevMode ? [{ debugName: "syntaxLanguage" }] : []));
2368
- copyButtonLabel = signal('Copy', ...(ngDevMode ? [{ debugName: "copyButtonLabel" }] : []));
2428
+ isCopied = signal(false, ...(ngDevMode ? [{ debugName: "isCopied" }] : []));
2429
+ copyButtonLabel = computed(() => this.isCopied() ? 'Copied' : 'Copy', ...(ngDevMode ? [{ debugName: "copyButtonLabel" }] : []));
2369
2430
  constructor() {
2370
2431
  this._destroyRef.onDestroy(() => {
2371
2432
  if (this._copyFeedbackTimeout) {
@@ -2382,7 +2443,7 @@ class CodeView {
2382
2443
  const data = this.data();
2383
2444
  const language = data?.language || parseLanguageFromFileExtension(data?.value || '');
2384
2445
  this.syntaxLanguage.set(parseSyntaxLanguage(language));
2385
- this.visibleLanguage.set(language);
2446
+ this.visibleLanguage.set(parseVisibleLanguage(language));
2386
2447
  }
2387
2448
  _updateNotExistingData(data) {
2388
2449
  if (data?.isLink) {
@@ -2400,23 +2461,26 @@ class CodeView {
2400
2461
  this._httpClient.get(link, { responseType: 'text' }).pipe(take(1), takeUntilDestroyed(this._destroyRef), catchError(() => EMPTY)).subscribe((content) => this.content.set(content));
2401
2462
  }
2402
2463
  onCopyClick() {
2464
+ if (this.isCopied()) {
2465
+ return;
2466
+ }
2403
2467
  this._copyContentToClipboard(this.content());
2404
2468
  }
2405
2469
  _copyContentToClipboard(content) {
2406
2470
  copyToClipboard(content).pipe(take(1), takeUntilDestroyed(this._destroyRef)).subscribe(() => this._setCopiedFeedback());
2407
2471
  }
2408
2472
  _setCopiedFeedback() {
2409
- this.copyButtonLabel.set('Copied');
2473
+ this.isCopied.set(true);
2410
2474
  if (this._copyFeedbackTimeout) {
2411
2475
  clearTimeout(this._copyFeedbackTimeout);
2412
2476
  }
2413
2477
  this._copyFeedbackTimeout = setTimeout(() => {
2414
- this.copyButtonLabel.set('Copy');
2478
+ this.isCopied.set(false);
2415
2479
  this._copyFeedbackTimeout = null;
2416
- }, 1500);
2480
+ }, 1300);
2417
2481
  }
2418
2482
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CodeView, deps: [], target: i0.ɵɵFactoryTarget.Component });
2419
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: CodeView, isStandalone: true, selector: "code-view", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.height": "height()" }, classAttribute: "f-code-view" }, ngImport: i0, template: "<span class=\"f-code-language\">{{ visibleLanguage() }}</span>\n<button class=\"f-copy-button\" type=\"button\" (click)=\"onCopyClick()\">{{ copyButtonLabel() }}</button>\n@if (content()) {\n <highlight [content]=\"content()\" [language]=\"syntaxLanguage()\"/>\n}\n", dependencies: [{ kind: "component", type: Highlight, selector: "highlight", inputs: ["content", "language"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2483
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: CodeView, isStandalone: true, selector: "code-view", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.height": "height()" }, classAttribute: "f-code-view" }, ngImport: i0, template: "<div class=\"f-code-controls\">\n <button class=\"f-copy-button\"\n type=\"button\"\n [attr.aria-label]=\"copyButtonLabel()\"\n [attr.title]=\"copyButtonLabel()\"\n (click)=\"onCopyClick()\">\n <span class=\"f-copy-icon\" [class.hidden]=\"isCopied()\" aria-hidden=\"true\"></span>\n <span class=\"f-copy-success-icon\" [class.visible]=\"isCopied()\" aria-hidden=\"true\"></span>\n </button>\n</div>\n@if (visibleLanguage()) {\n <span class=\"f-code-language\" [attr.title]=\"visibleLanguage()\" aria-hidden=\"true\">{{ visibleLanguage() }}</span>\n}\n@if (content()) {\n <div class=\"f-code-scroll\">\n <highlight [content]=\"content()\" [language]=\"syntaxLanguage()\"/>\n </div>\n}\n", dependencies: [{ kind: "component", type: Highlight, selector: "highlight", inputs: ["content", "language"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2420
2484
  }
2421
2485
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CodeView, decorators: [{
2422
2486
  type: Component,
@@ -2425,7 +2489,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
2425
2489
  '[style.height]': 'height()',
2426
2490
  }, imports: [
2427
2491
  Highlight,
2428
- ], template: "<span class=\"f-code-language\">{{ visibleLanguage() }}</span>\n<button class=\"f-copy-button\" type=\"button\" (click)=\"onCopyClick()\">{{ copyButtonLabel() }}</button>\n@if (content()) {\n <highlight [content]=\"content()\" [language]=\"syntaxLanguage()\"/>\n}\n" }]
2492
+ ], template: "<div class=\"f-code-controls\">\n <button class=\"f-copy-button\"\n type=\"button\"\n [attr.aria-label]=\"copyButtonLabel()\"\n [attr.title]=\"copyButtonLabel()\"\n (click)=\"onCopyClick()\">\n <span class=\"f-copy-icon\" [class.hidden]=\"isCopied()\" aria-hidden=\"true\"></span>\n <span class=\"f-copy-success-icon\" [class.visible]=\"isCopied()\" aria-hidden=\"true\"></span>\n </button>\n</div>\n@if (visibleLanguage()) {\n <span class=\"f-code-language\" [attr.title]=\"visibleLanguage()\" aria-hidden=\"true\">{{ visibleLanguage() }}</span>\n}\n@if (content()) {\n <div class=\"f-code-scroll\">\n <highlight [content]=\"content()\" [language]=\"syntaxLanguage()\"/>\n </div>\n}\n" }]
2429
2493
  }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }] } });
2430
2494
  function coerceComponentHeight(value) {
2431
2495
  if (value === undefined || value === null) {
@@ -2483,6 +2547,9 @@ function parseSyntaxLanguage(language) {
2483
2547
  }
2484
2548
  return resolveHighlightLanguage(result);
2485
2549
  }
2550
+ function parseVisibleLanguage(language) {
2551
+ return extractLanguage(language);
2552
+ }
2486
2553
  function extractLanguage(language) {
2487
2554
  const match = language.match(/^([^\s[]+)/);
2488
2555
  return match ? match[1].toLowerCase() : language;
@@ -3138,14 +3205,14 @@ class PreviewCard extends PreviewCardBase {
3138
3205
  this._fPreviewGroupService.remove(this);
3139
3206
  }
3140
3207
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: PreviewCard, deps: null, target: i0.ɵɵFactoryTarget.Component });
3141
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: PreviewCard, isStandalone: true, selector: "a[preview-card]", host: { properties: { "attr.href": "url", "attr.title": "viewModel?.text" } }, usesInheritance: true, ngImport: i0, template: "@if (viewModel) {\n <img [src]=\"src()\" [alt]=\"viewModel.description\" [title]=\"viewModel.text\">\n <div class=\"title\">\n {{ viewModel.text }}\n @if (viewModel.badge) {\n <span class=\"f-badge {{viewModel.badge.type}}\">{{ viewModel.badge.text }}</span>\n }\n </div>\n <div class=\"description\">{{ viewModel.description }}</div>\n}\n\n\n\n", styles: [":host{display:block;border-radius:4px;background-color:var(--soft-background);padding:24px;width:100%;text-decoration:none!important;color:inherit!important;line-height:24px;font-size:14px;cursor:pointer}:host:hover img{transform:scale(1.1)}:host img{display:block;margin-bottom:16px;width:100%;height:180px;border-radius:4px;object-fit:cover;transition:transform .3s}:host .title{line-height:inherit;font-weight:600;text-transform:uppercase;color:var(--primary-text);display:flex;justify-content:space-between;align-items:center}:host .description{margin:8px 0!important;line-height:inherit;color:var(--secondary-text);width:100%;word-wrap:break-word;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}@media(min-width:640px){:host{width:calc((100% - 32px)/2)}}.f-badge{padding:0 6px;line-height:14px;text-transform:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3208
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: PreviewCard, isStandalone: true, selector: "a[preview-card]", host: { properties: { "attr.href": "url", "attr.title": "viewModel?.text" } }, usesInheritance: true, ngImport: i0, template: "@if (viewModel) {\n @if (src()) {\n <div class=\"media\">\n <img\n [src]=\"src()\"\n [alt]=\"viewModel.description || viewModel.text\"\n [title]=\"viewModel.text\"\n [attr.width]=\"viewModel.image_width || null\"\n [attr.height]=\"viewModel.image_height || null\">\n </div>\n }\n\n <div class=\"content\">\n @if (viewModel.badge) {\n <div class=\"meta\">\n <span class=\"f-badge sm {{viewModel.badge.type}}\">{{ viewModel.badge.text }}</span>\n </div>\n }\n\n <div class=\"title\">{{ viewModel.text }}</div>\n <div class=\"description\">{{ viewModel.description }}</div>\n </div>\n}\n\n", styles: [":host{--f-preview-card-radius: calc(var(--border-radius) + 2px);--f-preview-card-media-radius: calc(var(--border-radius) - 2px);position:relative;display:block;box-sizing:border-box;width:100%;padding:14px;border-radius:var(--f-preview-card-radius);text-decoration:none!important;color:inherit!important;cursor:pointer;-webkit-user-select:none;user-select:none;isolation:isolate}:host:before{position:absolute;inset:0;border:1px solid var(--alpha-12);border-radius:inherit;background-color:var(--background-color);box-shadow:var(--shadow-1);content:\"\";transition:background-color .15s ease,border-color .15s ease,transform .15s ease}:host:hover:before{border-color:var(--divider-color);background-color:var(--alt-background)}:host:hover img{transform:scale(1.02)}:host:active:before{transform:scale(.985)}:host:focus-visible{outline:none}:host:focus-visible:before{border-color:var(--primary-1);box-shadow:0 0 0 3px var(--primary-soft),var(--shadow-1)}:host>*{position:relative;z-index:1}:host .media{overflow:hidden;border:1px solid var(--divider-color);border-radius:var(--f-preview-card-media-radius);background-color:var(--soft-background);aspect-ratio:16/9}:host img{display:block;width:100%;height:100%;object-fit:cover;transition:transform .2s ease}:host .content{display:flex;flex-direction:column;gap:8px;min-width:0}:host .media+.content{padding-top:14px}:host .meta{display:flex;align-items:center;min-height:var(--f-badge-compact-height);margin-bottom:2px}:host .title{margin:0;color:var(--primary-text);font-size:18px;font-weight:600;line-height:24px;letter-spacing:-.01em;text-transform:none;width:100%;word-wrap:break-word;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}:host .description{margin:0!important;font-size:15px;line-height:24px;color:var(--secondary-text);width:100%;word-wrap:break-word;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}@media(min-width:640px){:host{width:calc((100% - 24px)/2)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3142
3209
  }
3143
3210
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: PreviewCard, decorators: [{
3144
3211
  type: Component,
3145
3212
  args: [{ selector: 'a[preview-card]', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
3146
3213
  '[attr.href]': 'url',
3147
3214
  '[attr.title]': 'viewModel?.text',
3148
- }, template: "@if (viewModel) {\n <img [src]=\"src()\" [alt]=\"viewModel.description\" [title]=\"viewModel.text\">\n <div class=\"title\">\n {{ viewModel.text }}\n @if (viewModel.badge) {\n <span class=\"f-badge {{viewModel.badge.type}}\">{{ viewModel.badge.text }}</span>\n }\n </div>\n <div class=\"description\">{{ viewModel.description }}</div>\n}\n\n\n\n", styles: [":host{display:block;border-radius:4px;background-color:var(--soft-background);padding:24px;width:100%;text-decoration:none!important;color:inherit!important;line-height:24px;font-size:14px;cursor:pointer}:host:hover img{transform:scale(1.1)}:host img{display:block;margin-bottom:16px;width:100%;height:180px;border-radius:4px;object-fit:cover;transition:transform .3s}:host .title{line-height:inherit;font-weight:600;text-transform:uppercase;color:var(--primary-text);display:flex;justify-content:space-between;align-items:center}:host .description{margin:8px 0!important;line-height:inherit;color:var(--secondary-text);width:100%;word-wrap:break-word;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}@media(min-width:640px){:host{width:calc((100% - 32px)/2)}}.f-badge{padding:0 6px;line-height:14px;text-transform:none}\n"] }]
3215
+ }, template: "@if (viewModel) {\n @if (src()) {\n <div class=\"media\">\n <img\n [src]=\"src()\"\n [alt]=\"viewModel.description || viewModel.text\"\n [title]=\"viewModel.text\"\n [attr.width]=\"viewModel.image_width || null\"\n [attr.height]=\"viewModel.image_height || null\">\n </div>\n }\n\n <div class=\"content\">\n @if (viewModel.badge) {\n <div class=\"meta\">\n <span class=\"f-badge sm {{viewModel.badge.type}}\">{{ viewModel.badge.text }}</span>\n </div>\n }\n\n <div class=\"title\">{{ viewModel.text }}</div>\n <div class=\"description\">{{ viewModel.description }}</div>\n </div>\n}\n\n", styles: [":host{--f-preview-card-radius: calc(var(--border-radius) + 2px);--f-preview-card-media-radius: calc(var(--border-radius) - 2px);position:relative;display:block;box-sizing:border-box;width:100%;padding:14px;border-radius:var(--f-preview-card-radius);text-decoration:none!important;color:inherit!important;cursor:pointer;-webkit-user-select:none;user-select:none;isolation:isolate}:host:before{position:absolute;inset:0;border:1px solid var(--alpha-12);border-radius:inherit;background-color:var(--background-color);box-shadow:var(--shadow-1);content:\"\";transition:background-color .15s ease,border-color .15s ease,transform .15s ease}:host:hover:before{border-color:var(--divider-color);background-color:var(--alt-background)}:host:hover img{transform:scale(1.02)}:host:active:before{transform:scale(.985)}:host:focus-visible{outline:none}:host:focus-visible:before{border-color:var(--primary-1);box-shadow:0 0 0 3px var(--primary-soft),var(--shadow-1)}:host>*{position:relative;z-index:1}:host .media{overflow:hidden;border:1px solid var(--divider-color);border-radius:var(--f-preview-card-media-radius);background-color:var(--soft-background);aspect-ratio:16/9}:host img{display:block;width:100%;height:100%;object-fit:cover;transition:transform .2s ease}:host .content{display:flex;flex-direction:column;gap:8px;min-width:0}:host .media+.content{padding-top:14px}:host .meta{display:flex;align-items:center;min-height:var(--f-badge-compact-height);margin-bottom:2px}:host .title{margin:0;color:var(--primary-text);font-size:18px;font-weight:600;line-height:24px;letter-spacing:-.01em;text-transform:none;width:100%;word-wrap:break-word;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}:host .description{margin:0!important;font-size:15px;line-height:24px;color:var(--secondary-text);width:100%;word-wrap:break-word;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}@media(min-width:640px){:host{width:calc((100% - 24px)/2)}}\n"] }]
3149
3216
  }] });
3150
3217
 
3151
3218
  var previewCard = /*#__PURE__*/Object.freeze({
@@ -3153,10 +3220,12 @@ var previewCard = /*#__PURE__*/Object.freeze({
3153
3220
  PreviewCard: PreviewCard
3154
3221
  });
3155
3222
 
3223
+ let previewFilterGroupUniqueId = 0;
3156
3224
  class PreviewActionBar {
3157
3225
  _allKey = 'all';
3158
3226
  _fEnvironment = inject(DocumentationStore);
3159
3227
  _fPreviewGroupService = inject(PreviewGroupService);
3228
+ filterGroupName = `preview-filters-${previewFilterGroupUniqueId++}`;
3160
3229
  filters = signal([], ...(ngDevMode ? [{ debugName: "filters" }] : []));
3161
3230
  activeFilter = signal(this._allKey, ...(ngDevMode ? [{ debugName: "activeFilter" }] : []));
3162
3231
  isSortByDateChecked = signal(false, ...(ngDevMode ? [{ debugName: "isSortByDateChecked" }] : []));
@@ -3178,7 +3247,9 @@ class PreviewActionBar {
3178
3247
  if (filters.length > 0) {
3179
3248
  filters.unshift(this._allKey);
3180
3249
  }
3181
- return filters;
3250
+ return filters[0] === this._allKey
3251
+ ? [this._allKey, ...filters.slice(1).sort((a, b) => a.localeCompare(b))]
3252
+ : filters.sort((a, b) => a.localeCompare(b));
3182
3253
  }
3183
3254
  onFilterChange(key) {
3184
3255
  this.activeFilter.set(key);
@@ -3189,7 +3260,7 @@ class PreviewActionBar {
3189
3260
  this._fPreviewGroupService.sortByDate(event);
3190
3261
  }
3191
3262
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: PreviewActionBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
3192
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: PreviewActionBar, isStandalone: true, selector: "div[preview-action-bar]", ngImport: i0, template: "@if (filters().length) {\n <div class=\"filters-row\">\n @for (filter of filters(); track filter) {\n <f-radio-button [checked]=\"activeFilter() === filter\"\n (change)=\"onFilterChange(filter)\">{{ filter | titlecase }}\n </f-radio-button>\n }\n <div class=\"flex-space\"></div>\n <f-checkbox [checked]=\"isSortByDateChecked()\" (change)=\"onSortByDateChange($event)\">Sort by Newness</f-checkbox>\n </div>\n}\n\n\n\n", styles: [".filters-row{display:flex;justify-content:flex-start;align-items:center;flex-wrap:wrap;width:100%;padding-top:20px;gap:8px}\n"], dependencies: [{ kind: "component", type: FCheckboxComponent, selector: "f-checkbox", inputs: ["id", "checked"], outputs: ["change"] }, { kind: "component", type: FRadioButtonComponent, selector: "f-radio-button", inputs: ["id", "checked"], outputs: ["change"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3263
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: PreviewActionBar, isStandalone: true, selector: "div[preview-action-bar]", ngImport: i0, template: "@if (filters().length) {\n <div class=\"filters-row\">\n <div class=\"filters-group\" role=\"radiogroup\" aria-label=\"Filter preview items\">\n @for (filter of filters(); track filter) {\n <f-radio-button\n [name]=\"filterGroupName\"\n [checked]=\"activeFilter() === filter\"\n (change)=\"onFilterChange(filter)\">{{ filter | titlecase }}</f-radio-button>\n }\n </div>\n <div class=\"flex-space\"></div>\n <f-checkbox [checked]=\"isSortByDateChecked()\" (change)=\"onSortByDateChange($event)\">Sort by Newness</f-checkbox>\n </div>\n}\n", styles: [".filters-row{display:flex;justify-content:flex-start;align-items:flex-start;flex-wrap:wrap;width:100%;padding-top:20px;gap:12px}.filters-group{display:flex;flex-wrap:wrap;align-items:flex-start;column-gap:20px;row-gap:10px;min-width:0}\n"], dependencies: [{ kind: "component", type: FCheckboxComponent, selector: "f-checkbox", inputs: ["id", "checked"], outputs: ["change"] }, { kind: "component", type: FRadioButtonComponent, selector: "f-radio-button", inputs: ["id", "name", "checked"], outputs: ["change"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3193
3264
  }
3194
3265
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: PreviewActionBar, decorators: [{
3195
3266
  type: Component,
@@ -3197,7 +3268,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
3197
3268
  FCheckboxComponent,
3198
3269
  FRadioButtonComponent,
3199
3270
  TitleCasePipe,
3200
- ], template: "@if (filters().length) {\n <div class=\"filters-row\">\n @for (filter of filters(); track filter) {\n <f-radio-button [checked]=\"activeFilter() === filter\"\n (change)=\"onFilterChange(filter)\">{{ filter | titlecase }}\n </f-radio-button>\n }\n <div class=\"flex-space\"></div>\n <f-checkbox [checked]=\"isSortByDateChecked()\" (change)=\"onSortByDateChange($event)\">Sort by Newness</f-checkbox>\n </div>\n}\n\n\n\n", styles: [".filters-row{display:flex;justify-content:flex-start;align-items:center;flex-wrap:wrap;width:100%;padding-top:20px;gap:8px}\n"] }]
3271
+ ], template: "@if (filters().length) {\n <div class=\"filters-row\">\n <div class=\"filters-group\" role=\"radiogroup\" aria-label=\"Filter preview items\">\n @for (filter of filters(); track filter) {\n <f-radio-button\n [name]=\"filterGroupName\"\n [checked]=\"activeFilter() === filter\"\n (change)=\"onFilterChange(filter)\">{{ filter | titlecase }}</f-radio-button>\n }\n </div>\n <div class=\"flex-space\"></div>\n <f-checkbox [checked]=\"isSortByDateChecked()\" (change)=\"onSortByDateChange($event)\">Sort by Newness</f-checkbox>\n </div>\n}\n", styles: [".filters-row{display:flex;justify-content:flex-start;align-items:flex-start;flex-wrap:wrap;width:100%;padding-top:20px;gap:12px}.filters-group{display:flex;flex-wrap:wrap;align-items:flex-start;column-gap:20px;row-gap:10px;min-width:0}\n"] }]
3201
3272
  }] });
3202
3273
 
3203
3274
  var previewActionBar = /*#__PURE__*/Object.freeze({
@@ -3215,40 +3286,50 @@ class ShowcaseItem {
3215
3286
  return theme === 'dark' ? (model.imageUrlDark || model.imageUrl) : model.imageUrl;
3216
3287
  }, ...(ngDevMode ? [{ debugName: "src" }] : []));
3217
3288
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ShowcaseItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
3218
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: ShowcaseItem, isStandalone: true, selector: "showcase-item", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@let data = model();\n\n@if (data) {\n <img [src]=\"src()\" [alt]=\"data.description\" [title]=\"data.name\">\n <div class=\"title\">{{ data.name }}</div>\n <div class=\"description\">{{ data.description }}</div>\n <div class=\"links\">\n @for (link of (data.links || []); track link.text) {\n <a href=\"{{ link.url }}\" target=\"_blank\" rel=\"noopener\">{{ link.text }}</a>\n }\n </div>\n <div class=\"tags\">\n @for (tag of (data.tags || []); track tag) {\n <span class=\"f-badge tip\">{{ tag }}</span>\n }\n </div>\n}\n\n\n\n", styles: [":host{display:block;border-radius:4px;background-color:var(--soft-background);padding:24px;width:100%;text-decoration:none!important;color:inherit!important;line-height:24px;font-size:14px}:host img{display:block;margin-bottom:16px;width:100%;height:240px;border-radius:4px;object-fit:cover}:host .title{line-height:inherit;font-weight:600;text-transform:uppercase;color:var(--primary-text);display:flex;justify-content:space-between;align-items:center}:host .description{margin:8px 0!important;line-height:inherit;color:var(--secondary-text);width:100%;word-wrap:break-word;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}@media(min-width:640px){:host{width:calc((100% - 32px)/2)}}.links{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:16px}.links a{font-size:14px;font-weight:500;color:var(--primary-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.links a:hover,.links a.active{color:var(--primary-1)}.tags{display:flex;flex-wrap:wrap;gap:8px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3289
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: ShowcaseItem, isStandalone: true, selector: "showcase-item", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@let data = model();\n\n@if (data) {\n @if (src()) {\n <div class=\"media\">\n <img [src]=\"src()\" [alt]=\"data.description || data.name\" [title]=\"data.name\">\n </div>\n }\n\n <div class=\"content\">\n @if (data.tags?.length) {\n <div class=\"meta\">\n @for (tag of data.tags; track tag) {\n <span class=\"f-badge sm tip\">{{ tag }}</span>\n }\n </div>\n }\n\n <div class=\"title\">{{ data.name }}</div>\n <div class=\"description\">{{ data.description }}</div>\n\n @if (data.links?.length) {\n <div class=\"links\">\n @for (link of data.links; track link.text) {\n <a class=\"f-text-link f-text-link-primary\" href=\"{{ link.url }}\" target=\"_blank\" rel=\"noopener\">{{ link.text }}</a>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{--f-showcase-card-radius: calc(var(--border-radius) + 2px);--f-showcase-card-media-radius: calc(var(--border-radius) - 2px);position:relative;display:block;box-sizing:border-box;width:100%;padding:14px;border-radius:var(--f-showcase-card-radius);isolation:isolate}:host:before{position:absolute;inset:0;border:1px solid var(--alpha-12);border-radius:inherit;background-color:var(--background-color);box-shadow:var(--shadow-1);content:\"\";transition:background-color .15s ease,border-color .15s ease,transform .15s ease}:host:hover:before{border-color:var(--divider-color);background-color:var(--alt-background)}:host:hover img{transform:scale(1.02)}:host:focus-within:before{border-color:var(--primary-1);box-shadow:0 0 0 3px var(--primary-soft),var(--shadow-1)}:host>*{position:relative;z-index:1}:host .media{overflow:hidden;border:1px solid var(--divider-color);border-radius:var(--f-showcase-card-media-radius);background-color:var(--soft-background);aspect-ratio:16/9}:host img{display:block;width:100%;height:100%;object-fit:cover;transition:transform .2s ease}:host .content{display:flex;flex-direction:column;gap:8px;min-width:0}:host .media+.content{padding-top:14px}:host .meta{display:flex;align-items:center;flex-wrap:wrap;gap:8px;min-height:var(--f-badge-compact-height);margin-bottom:2px}:host .title{margin:0;color:var(--primary-text);font-size:18px;font-weight:600;line-height:24px;letter-spacing:-.01em;text-transform:none;width:100%;word-wrap:break-word;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}:host .description{margin:0!important;font-size:15px;line-height:24px;color:var(--secondary-text);width:100%;word-wrap:break-word;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}@media(min-width:640px){:host{width:calc((100% - 24px)/2)}}.links{display:flex;flex-wrap:wrap;gap:12px;margin-top:4px}.links a{font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3219
3290
  }
3220
3291
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ShowcaseItem, decorators: [{
3221
3292
  type: Component,
3222
- args: [{ selector: 'showcase-item', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let data = model();\n\n@if (data) {\n <img [src]=\"src()\" [alt]=\"data.description\" [title]=\"data.name\">\n <div class=\"title\">{{ data.name }}</div>\n <div class=\"description\">{{ data.description }}</div>\n <div class=\"links\">\n @for (link of (data.links || []); track link.text) {\n <a href=\"{{ link.url }}\" target=\"_blank\" rel=\"noopener\">{{ link.text }}</a>\n }\n </div>\n <div class=\"tags\">\n @for (tag of (data.tags || []); track tag) {\n <span class=\"f-badge tip\">{{ tag }}</span>\n }\n </div>\n}\n\n\n\n", styles: [":host{display:block;border-radius:4px;background-color:var(--soft-background);padding:24px;width:100%;text-decoration:none!important;color:inherit!important;line-height:24px;font-size:14px}:host img{display:block;margin-bottom:16px;width:100%;height:240px;border-radius:4px;object-fit:cover}:host .title{line-height:inherit;font-weight:600;text-transform:uppercase;color:var(--primary-text);display:flex;justify-content:space-between;align-items:center}:host .description{margin:8px 0!important;line-height:inherit;color:var(--secondary-text);width:100%;word-wrap:break-word;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}@media(min-width:640px){:host{width:calc((100% - 32px)/2)}}.links{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:16px}.links a{font-size:14px;font-weight:500;color:var(--primary-text);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.links a:hover,.links a.active{color:var(--primary-1)}.tags{display:flex;flex-wrap:wrap;gap:8px}\n"] }]
3293
+ args: [{ selector: 'showcase-item', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let data = model();\n\n@if (data) {\n @if (src()) {\n <div class=\"media\">\n <img [src]=\"src()\" [alt]=\"data.description || data.name\" [title]=\"data.name\">\n </div>\n }\n\n <div class=\"content\">\n @if (data.tags?.length) {\n <div class=\"meta\">\n @for (tag of data.tags; track tag) {\n <span class=\"f-badge sm tip\">{{ tag }}</span>\n }\n </div>\n }\n\n <div class=\"title\">{{ data.name }}</div>\n <div class=\"description\">{{ data.description }}</div>\n\n @if (data.links?.length) {\n <div class=\"links\">\n @for (link of data.links; track link.text) {\n <a class=\"f-text-link f-text-link-primary\" href=\"{{ link.url }}\" target=\"_blank\" rel=\"noopener\">{{ link.text }}</a>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{--f-showcase-card-radius: calc(var(--border-radius) + 2px);--f-showcase-card-media-radius: calc(var(--border-radius) - 2px);position:relative;display:block;box-sizing:border-box;width:100%;padding:14px;border-radius:var(--f-showcase-card-radius);isolation:isolate}:host:before{position:absolute;inset:0;border:1px solid var(--alpha-12);border-radius:inherit;background-color:var(--background-color);box-shadow:var(--shadow-1);content:\"\";transition:background-color .15s ease,border-color .15s ease,transform .15s ease}:host:hover:before{border-color:var(--divider-color);background-color:var(--alt-background)}:host:hover img{transform:scale(1.02)}:host:focus-within:before{border-color:var(--primary-1);box-shadow:0 0 0 3px var(--primary-soft),var(--shadow-1)}:host>*{position:relative;z-index:1}:host .media{overflow:hidden;border:1px solid var(--divider-color);border-radius:var(--f-showcase-card-media-radius);background-color:var(--soft-background);aspect-ratio:16/9}:host img{display:block;width:100%;height:100%;object-fit:cover;transition:transform .2s ease}:host .content{display:flex;flex-direction:column;gap:8px;min-width:0}:host .media+.content{padding-top:14px}:host .meta{display:flex;align-items:center;flex-wrap:wrap;gap:8px;min-height:var(--f-badge-compact-height);margin-bottom:2px}:host .title{margin:0;color:var(--primary-text);font-size:18px;font-weight:600;line-height:24px;letter-spacing:-.01em;text-transform:none;width:100%;word-wrap:break-word;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}:host .description{margin:0!important;font-size:15px;line-height:24px;color:var(--secondary-text);width:100%;word-wrap:break-word;white-space:normal;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}@media(min-width:640px){:host{width:calc((100% - 24px)/2)}}.links{display:flex;flex-wrap:wrap;gap:12px;margin-top:4px}.links a{font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"] }]
3223
3294
  }], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }] } });
3224
3295
 
3225
3296
  const SHOWCASE_DATA = new InjectionToken('SHOWCASE_DATA');
3226
3297
 
3298
+ let filterGroupUniqueId = 0;
3227
3299
  class Showcase {
3228
3300
  _data = signal(inject(SHOWCASE_DATA), ...(ngDevMode ? [{ debugName: "_data" }] : []));
3301
+ _allFilterLabel = 'All';
3302
+ filterGroupName = `showcase-filters-${filterGroupUniqueId++}`;
3229
3303
  items = computed(() => {
3230
3304
  const items = this._data();
3231
3305
  const activeTag = this.activeTag();
3232
3306
  return activeTag ? items.filter(item => item.tags?.includes(activeTag)) : items;
3233
3307
  }, ...(ngDevMode ? [{ debugName: "items" }] : []));
3234
- tags = computed(() => {
3235
- return this._data().reduce((result, item) => {
3308
+ filterOptions = computed(() => [{
3309
+ label: this._allFilterLabel,
3310
+ value: null,
3311
+ }, ...Array.from(this._data().reduce((result, item) => {
3236
3312
  item.tags?.forEach(tag => result.add(tag));
3237
3313
  return result;
3238
- }, new Set());
3239
- }, ...(ngDevMode ? [{ debugName: "tags" }] : []));
3314
+ }, new Set()))
3315
+ .sort((a, b) => a.localeCompare(b))
3316
+ .map((tag) => ({
3317
+ label: tag,
3318
+ value: tag,
3319
+ }))], ...(ngDevMode ? [{ debugName: "filterOptions" }] : []));
3240
3320
  activeTag = signal(null, ...(ngDevMode ? [{ debugName: "activeTag" }] : []));
3241
- tagClick(tag) {
3242
- this.activeTag.update((x) => x === tag ? null : tag);
3321
+ onFilterChange(tag) {
3322
+ this.activeTag.set(tag);
3243
3323
  }
3244
3324
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: Showcase, deps: [], target: i0.ɵɵFactoryTarget.Component });
3245
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: Showcase, isStandalone: true, selector: "showcase", ngImport: i0, template: "<div class=\"filters-panel\">\n @for (tag of tags(); track tag) {\n <span class=\"f-badge tip\" (click)=\"tagClick(tag)\" [class.info]=\"activeTag() === tag\">{{ tag }}</span>\n }\n</div>\n<div class=\"showcase-list\">\n @for (item of items(); track item.imageUrl) {\n <showcase-item [model]=\"item\"/>\n }\n</div>\n\n", styles: [".filters-panel{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:24px}.filters-panel .f-badge{cursor:pointer}.showcase-list{display:flex;justify-content:flex-start;align-items:normal;flex-wrap:wrap;gap:32px;pointer-events:all;overflow:hidden}\n"], dependencies: [{ kind: "component", type: ShowcaseItem, selector: "showcase-item", inputs: ["model"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3325
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: Showcase, isStandalone: true, selector: "showcase", ngImport: i0, template: "<div class=\"filters-panel\">\n <div class=\"filters-group\" role=\"radiogroup\" aria-label=\"Filter showcase items\">\n @for (filter of filterOptions(); track filter.value ?? 'all') {\n <f-radio-button\n [name]=\"filterGroupName\"\n [checked]=\"activeTag() === filter.value\"\n (change)=\"onFilterChange(filter.value)\">{{ filter.label }}</f-radio-button>\n }\n </div>\n</div>\n<div class=\"showcase-list\">\n @for (item of items(); track item.imageUrl) {\n <showcase-item [model]=\"item\"/>\n }\n</div>\n", styles: [".filters-panel{width:100%;margin-bottom:24px}.filters-group{display:flex;flex-wrap:wrap;align-items:flex-start;column-gap:20px;row-gap:10px}.showcase-list{display:flex;justify-content:flex-start;align-items:stretch;flex-wrap:wrap;gap:24px;pointer-events:all;overflow:hidden}\n"], dependencies: [{ kind: "component", type: FRadioButtonComponent, selector: "f-radio-button", inputs: ["id", "name", "checked"], outputs: ["change"] }, { kind: "component", type: ShowcaseItem, selector: "showcase-item", inputs: ["model"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3246
3326
  }
3247
3327
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: Showcase, decorators: [{
3248
3328
  type: Component,
3249
3329
  args: [{ selector: 'showcase', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3330
+ FRadioButtonComponent,
3250
3331
  ShowcaseItem,
3251
- ], template: "<div class=\"filters-panel\">\n @for (tag of tags(); track tag) {\n <span class=\"f-badge tip\" (click)=\"tagClick(tag)\" [class.info]=\"activeTag() === tag\">{{ tag }}</span>\n }\n</div>\n<div class=\"showcase-list\">\n @for (item of items(); track item.imageUrl) {\n <showcase-item [model]=\"item\"/>\n }\n</div>\n\n", styles: [".filters-panel{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:24px}.filters-panel .f-badge{cursor:pointer}.showcase-list{display:flex;justify-content:flex-start;align-items:normal;flex-wrap:wrap;gap:32px;pointer-events:all;overflow:hidden}\n"] }]
3332
+ ], template: "<div class=\"filters-panel\">\n <div class=\"filters-group\" role=\"radiogroup\" aria-label=\"Filter showcase items\">\n @for (filter of filterOptions(); track filter.value ?? 'all') {\n <f-radio-button\n [name]=\"filterGroupName\"\n [checked]=\"activeTag() === filter.value\"\n (change)=\"onFilterChange(filter.value)\">{{ filter.label }}</f-radio-button>\n }\n </div>\n</div>\n<div class=\"showcase-list\">\n @for (item of items(); track item.imageUrl) {\n <showcase-item [model]=\"item\"/>\n }\n</div>\n", styles: [".filters-panel{width:100%;margin-bottom:24px}.filters-group{display:flex;flex-wrap:wrap;align-items:flex-start;column-gap:20px;row-gap:10px}.showcase-list{display:flex;justify-content:flex-start;align-items:stretch;flex-wrap:wrap;gap:24px;pointer-events:all;overflow:hidden}\n"] }]
3252
3333
  }] });
3253
3334
 
3254
3335
  var showcase = /*#__PURE__*/Object.freeze({
@@ -3572,11 +3653,11 @@ class TableOfContent {
3572
3653
  this._mediatr.execute(new ScrollToElementInContainerRequest(hash));
3573
3654
  }
3574
3655
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: TableOfContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3575
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: TableOfContent, isStandalone: true, selector: "table-of-content", host: { listeners: { "click": "_click($event)" } }, ngImport: i0, template: "@let data = tocData();\n@if (data) {\n <div class=\"title\">{{ title || 'In this article' }}</div>\n <ul f-table-of-content-items [items]=\"data.tree\"></ul>\n <div class=\"active-marker\" [style.top]=\"activeMarkerPosition() + 'px'\"></div>\n}\n\n", styles: [":host{--on-page-navigation-item-height: 30px;display:none;padding-left:18px;border-left:1px solid var(--divider-color);font-size:13px;font-weight:500;position:relative;max-height:calc(100vh - var(--header-height) - 48px);overflow-y:auto}:host .title{line-height:20px;font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--tertiary-text);margin-bottom:12px}@media(min-width:1280px){:host{display:block;width:var(--on-page-navigation-width);position:fixed;top:calc(var(--header-height) + 32px);right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 3)}}:host .active-marker{position:absolute;top:0;left:0;width:2px;height:calc(var(--on-page-navigation-item-height) / 2);border-radius:2px;background-color:var(--primary-text);transition:top .25s cubic-bezier(0,1,.5,1),opacity .25s}\n"], dependencies: [{ kind: "component", type: TableOfContentItemsComponent, selector: "ul[f-table-of-content-items]", inputs: ["items"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3656
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: TableOfContent, isStandalone: true, selector: "table-of-content", host: { listeners: { "click": "_click($event)" } }, ngImport: i0, template: "@let data = tocData();\n@if (data) {\n <div class=\"title\">{{ title || 'In this article' }}</div>\n <ul f-table-of-content-items [items]=\"data.tree\"></ul>\n <div class=\"active-marker\" [style.top]=\"activeMarkerPosition() + 'px'\"></div>\n}\n\n", styles: [":host{--on-page-navigation-item-height: 30px;display:none;padding-left:16px;border-left:1px solid var(--divider-color);font-size:13px;font-weight:500;position:relative;max-height:calc(100vh - var(--header-height) - 48px);overflow-y:auto}:host .title{line-height:20px;font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--tertiary-text);margin-bottom:12px}@media(min-width:1280px){:host{display:block;width:var(--on-page-navigation-width);position:fixed;top:calc(var(--header-height) + 32px);right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 3 - var(--on-page-navigation-shift-desktop))}}:host .active-marker{position:absolute;top:0;left:0;width:2px;height:calc(var(--on-page-navigation-item-height) / 2);border-radius:2px;background-color:var(--primary-text);transition:top .25s cubic-bezier(0,1,.5,1),opacity .25s}\n"], dependencies: [{ kind: "component", type: TableOfContentItemsComponent, selector: "ul[f-table-of-content-items]", inputs: ["items"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3576
3657
  }
3577
3658
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: TableOfContent, decorators: [{
3578
3659
  type: Component,
3579
- args: [{ selector: 'table-of-content', standalone: true, imports: [TableOfContentItemsComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let data = tocData();\n@if (data) {\n <div class=\"title\">{{ title || 'In this article' }}</div>\n <ul f-table-of-content-items [items]=\"data.tree\"></ul>\n <div class=\"active-marker\" [style.top]=\"activeMarkerPosition() + 'px'\"></div>\n}\n\n", styles: [":host{--on-page-navigation-item-height: 30px;display:none;padding-left:18px;border-left:1px solid var(--divider-color);font-size:13px;font-weight:500;position:relative;max-height:calc(100vh - var(--header-height) - 48px);overflow-y:auto}:host .title{line-height:20px;font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--tertiary-text);margin-bottom:12px}@media(min-width:1280px){:host{display:block;width:var(--on-page-navigation-width);position:fixed;top:calc(var(--header-height) + 32px);right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 3)}}:host .active-marker{position:absolute;top:0;left:0;width:2px;height:calc(var(--on-page-navigation-item-height) / 2);border-radius:2px;background-color:var(--primary-text);transition:top .25s cubic-bezier(0,1,.5,1),opacity .25s}\n"] }]
3660
+ args: [{ selector: 'table-of-content', standalone: true, imports: [TableOfContentItemsComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let data = tocData();\n@if (data) {\n <div class=\"title\">{{ title || 'In this article' }}</div>\n <ul f-table-of-content-items [items]=\"data.tree\"></ul>\n <div class=\"active-marker\" [style.top]=\"activeMarkerPosition() + 'px'\"></div>\n}\n\n", styles: [":host{--on-page-navigation-item-height: 30px;display:none;padding-left:16px;border-left:1px solid var(--divider-color);font-size:13px;font-weight:500;position:relative;max-height:calc(100vh - var(--header-height) - 48px);overflow-y:auto}:host .title{line-height:20px;font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--tertiary-text);margin-bottom:12px}@media(min-width:1280px){:host{display:block;width:var(--on-page-navigation-width);position:fixed;top:calc(var(--header-height) + 32px);right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 3 - var(--on-page-navigation-shift-desktop))}}:host .active-marker{position:absolute;top:0;left:0;width:2px;height:calc(var(--on-page-navigation-item-height) / 2);border-radius:2px;background-color:var(--primary-text);transition:top .25s cubic-bezier(0,1,.5,1),opacity .25s}\n"] }]
3580
3661
  }], propDecorators: { _click: [{
3581
3662
  type: HostListener,
3582
3663
  args: ['click', ['$event']]
@@ -3683,13 +3764,13 @@ class MarkdownRenderer {
3683
3764
  this._dynamicComponents.dispose();
3684
3765
  }
3685
3766
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: MarkdownRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
3686
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: MarkdownRenderer, isStandalone: true, selector: "markdown-renderer", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, origin: { classPropertyName: "origin", publicName: "origin", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "_onDocumentClick($event)" }, classAttribute: "m-render" }, ngImport: i0, template: "<div [innerHTML]=\"value()\"></div>\n@if (origin(); as pageOrigin) {\n <aside class=\"origin-link\" role=\"note\">\n <span class=\"origin-link-icon\" aria-hidden=\"true\"></span>\n <div class=\"origin-link-content\">\n <span class=\"origin-link-label\">{{ pageOrigin.label }}</span>\n <a class=\"origin-link-url\"\n [href]=\"pageOrigin.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\">{{ pageOrigin.url }}</a>\n </div>\n </aside>\n}\n@if (value()) {\n <markdown-footer />\n}\n", styles: [":host{display:block;width:100%;max-width:960px}@media(min-width:1280px){:host{width:calc(100% - var(--on-page-navigation-width) - var(--page-padding))}}@media(min-width:1280px){:host.expand-no-toc{width:100%}}:host.empty-navigation{margin:auto;max-width:1040px}.origin-link{display:flex;justify-content:flex-start;align-items:flex-start;gap:12px;margin-top:28px;border:1px solid var(--divider-color);border-radius:calc(var(--border-radius) + 2px);padding:14px 16px;background:var(--surface-glass-strong);box-shadow:var(--shadow-1);line-height:20px;font-size:14px}.origin-link-icon{flex-shrink:0;display:inline-flex;justify-content:center;align-items:center;width:28px;height:28px;border-radius:999px;background-color:var(--primary-text);color:var(--neutral-inverse);font-size:10px;font-weight:700;letter-spacing:.06em}.origin-link-icon:before{content:\"SRC\"}.origin-link-content{min-width:0}.origin-link-label{display:block;color:var(--secondary-text);font-weight:600}.origin-link-url{display:inline-block;margin-top:2px;color:var(--primary-text);text-decoration:underline;text-underline-offset:3px;overflow-wrap:anywhere;transition:color .2s ease}.origin-link-url:hover{color:var(--primary-text)}@media(max-width:639px){.origin-link{margin-top:24px;border-radius:8px;padding:10px 12px;gap:10px}.origin-link-icon{width:24px;height:24px;font-size:9px}}\n"], dependencies: [{ kind: "component", type: MarkdownFooter, selector: "markdown-footer" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3767
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: MarkdownRenderer, isStandalone: true, selector: "markdown-renderer", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, origin: { classPropertyName: "origin", publicName: "origin", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "_onDocumentClick($event)" }, classAttribute: "m-render" }, ngImport: i0, template: "<div class=\"doc-content\" [innerHTML]=\"value()\"></div>\n@if (origin(); as pageOrigin) {\n <aside class=\"origin-link\" role=\"note\">\n <span class=\"origin-link-icon\" aria-hidden=\"true\"></span>\n <div class=\"origin-link-content\">\n <span class=\"origin-link-label\">{{ pageOrigin.label }}</span>\n <a class=\"origin-link-url f-text-link f-text-link-primary\"\n [href]=\"pageOrigin.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\">{{ pageOrigin.url }}</a>\n </div>\n </aside>\n}\n@if (value()) {\n <markdown-footer />\n}\n", styles: [":host{display:block;width:100%;max-width:860px}@media(min-width:1280px){:host{width:calc(100% - var(--on-page-navigation-width) - var(--page-padding) - var(--docs-content-offset-desktop));margin-left:var(--docs-content-offset-desktop)}}@media(min-width:1280px){:host.expand-no-toc{width:calc(100% - var(--docs-content-offset-desktop));max-width:1060px}}:host.empty-navigation{margin:auto;max-width:980px}@media(min-width:1280px){:host.empty-navigation{width:100%;margin-left:auto;margin-right:auto}}.origin-link{display:flex;justify-content:flex-start;align-items:flex-start;gap:12px;margin-top:28px;border:1px solid var(--divider-color);border-radius:calc(var(--border-radius) + 2px);padding:14px 16px;background:var(--surface-glass-strong);box-shadow:var(--shadow-1);line-height:20px;font-size:14px}.origin-link-icon{flex-shrink:0;display:inline-flex;justify-content:center;align-items:center;width:28px;height:28px;border-radius:999px;background-color:var(--primary-text);color:var(--neutral-inverse);font-size:10px;font-weight:700;letter-spacing:.06em}.origin-link-icon:before{content:\"SRC\"}.origin-link-content{min-width:0}.origin-link-label{display:block;color:var(--secondary-text);font-weight:600}.origin-link-url{display:inline-flex;width:fit-content;max-width:100%;margin-top:2px}@media(max-width:639px){.origin-link{margin-top:24px;border-radius:8px;padding:10px 12px;gap:10px}.origin-link-icon{width:24px;height:24px;font-size:9px}}\n"], dependencies: [{ kind: "component", type: MarkdownFooter, selector: "markdown-footer" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3687
3768
  }
3688
3769
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: MarkdownRenderer, decorators: [{
3689
3770
  type: Component,
3690
3771
  args: [{ selector: 'markdown-renderer', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MarkdownFooter], host: {
3691
3772
  class: 'm-render',
3692
- }, template: "<div [innerHTML]=\"value()\"></div>\n@if (origin(); as pageOrigin) {\n <aside class=\"origin-link\" role=\"note\">\n <span class=\"origin-link-icon\" aria-hidden=\"true\"></span>\n <div class=\"origin-link-content\">\n <span class=\"origin-link-label\">{{ pageOrigin.label }}</span>\n <a class=\"origin-link-url\"\n [href]=\"pageOrigin.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\">{{ pageOrigin.url }}</a>\n </div>\n </aside>\n}\n@if (value()) {\n <markdown-footer />\n}\n", styles: [":host{display:block;width:100%;max-width:960px}@media(min-width:1280px){:host{width:calc(100% - var(--on-page-navigation-width) - var(--page-padding))}}@media(min-width:1280px){:host.expand-no-toc{width:100%}}:host.empty-navigation{margin:auto;max-width:1040px}.origin-link{display:flex;justify-content:flex-start;align-items:flex-start;gap:12px;margin-top:28px;border:1px solid var(--divider-color);border-radius:calc(var(--border-radius) + 2px);padding:14px 16px;background:var(--surface-glass-strong);box-shadow:var(--shadow-1);line-height:20px;font-size:14px}.origin-link-icon{flex-shrink:0;display:inline-flex;justify-content:center;align-items:center;width:28px;height:28px;border-radius:999px;background-color:var(--primary-text);color:var(--neutral-inverse);font-size:10px;font-weight:700;letter-spacing:.06em}.origin-link-icon:before{content:\"SRC\"}.origin-link-content{min-width:0}.origin-link-label{display:block;color:var(--secondary-text);font-weight:600}.origin-link-url{display:inline-block;margin-top:2px;color:var(--primary-text);text-decoration:underline;text-underline-offset:3px;overflow-wrap:anywhere;transition:color .2s ease}.origin-link-url:hover{color:var(--primary-text)}@media(max-width:639px){.origin-link{margin-top:24px;border-radius:8px;padding:10px 12px;gap:10px}.origin-link-icon{width:24px;height:24px;font-size:9px}}\n"] }]
3773
+ }, template: "<div class=\"doc-content\" [innerHTML]=\"value()\"></div>\n@if (origin(); as pageOrigin) {\n <aside class=\"origin-link\" role=\"note\">\n <span class=\"origin-link-icon\" aria-hidden=\"true\"></span>\n <div class=\"origin-link-content\">\n <span class=\"origin-link-label\">{{ pageOrigin.label }}</span>\n <a class=\"origin-link-url f-text-link f-text-link-primary\"\n [href]=\"pageOrigin.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\">{{ pageOrigin.url }}</a>\n </div>\n </aside>\n}\n@if (value()) {\n <markdown-footer />\n}\n", styles: [":host{display:block;width:100%;max-width:860px}@media(min-width:1280px){:host{width:calc(100% - var(--on-page-navigation-width) - var(--page-padding) - var(--docs-content-offset-desktop));margin-left:var(--docs-content-offset-desktop)}}@media(min-width:1280px){:host.expand-no-toc{width:calc(100% - var(--docs-content-offset-desktop));max-width:1060px}}:host.empty-navigation{margin:auto;max-width:980px}@media(min-width:1280px){:host.empty-navigation{width:100%;margin-left:auto;margin-right:auto}}.origin-link{display:flex;justify-content:flex-start;align-items:flex-start;gap:12px;margin-top:28px;border:1px solid var(--divider-color);border-radius:calc(var(--border-radius) + 2px);padding:14px 16px;background:var(--surface-glass-strong);box-shadow:var(--shadow-1);line-height:20px;font-size:14px}.origin-link-icon{flex-shrink:0;display:inline-flex;justify-content:center;align-items:center;width:28px;height:28px;border-radius:999px;background-color:var(--primary-text);color:var(--neutral-inverse);font-size:10px;font-weight:700;letter-spacing:.06em}.origin-link-icon:before{content:\"SRC\"}.origin-link-content{min-width:0}.origin-link-label{display:block;color:var(--secondary-text);font-weight:600}.origin-link-url{display:inline-flex;width:fit-content;max-width:100%;margin-top:2px}@media(max-width:639px){.origin-link{margin-top:24px;border-radius:8px;padding:10px 12px;gap:10px}.origin-link-icon{width:24px;height:24px;font-size:9px}}\n"] }]
3693
3774
  }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], origin: [{ type: i0.Input, args: [{ isSignal: true, alias: "origin", required: false }] }], _onDocumentClick: [{
3694
3775
  type: HostListener,
3695
3776
  args: ['click', ['$event']]
@@ -3716,7 +3797,7 @@ class MarkdownRouter {
3716
3797
  }), tap(() => this._metaService?.applyMarkdownSeo(this._markdown.pageSeo())));
3717
3798
  })), { initialValue: undefined });
3718
3799
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: MarkdownRouter, deps: [], target: i0.ɵɵFactoryTarget.Component });
3719
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: MarkdownRouter, isStandalone: true, selector: "markdown-router", host: { attributes: { "ngSkipHydration": "" }, properties: { "class.empty-navigation": "emptyNavigation" } }, ngImport: i0, template: "<markdown-renderer [value]=\"html()\"\n [origin]=\"pageOrigin()\"\n [class.empty-navigation]=\"emptyNavigation\"\n [class.expand-no-toc]=\"shouldExpandContent()\"/>\n", styles: [":host{display:block;width:100%;padding:36px var(--page-padding) 120px}@media(min-width:1280px){:host{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 4)}}@media(min-width:1280px){:host.empty-navigation{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2)}}\n"], dependencies: [{ kind: "component", type: MarkdownRenderer, selector: "markdown-renderer", inputs: ["value", "origin"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3800
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: MarkdownRouter, isStandalone: true, selector: "markdown-router", host: { attributes: { "ngSkipHydration": "" }, properties: { "class.empty-navigation": "emptyNavigation" } }, ngImport: i0, template: "<markdown-renderer [value]=\"html()\"\n [origin]=\"pageOrigin()\"\n [class.empty-navigation]=\"emptyNavigation\"\n [class.expand-no-toc]=\"shouldExpandContent()\"/>\n", styles: [":host{display:block;width:100%;padding:48px var(--page-padding) 140px}@media(min-width:1280px){:host{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 4)}}@media(min-width:1280px){:host.empty-navigation{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2)}}\n"], dependencies: [{ kind: "component", type: MarkdownRenderer, selector: "markdown-renderer", inputs: ["value", "origin"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3720
3801
  }
3721
3802
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: MarkdownRouter, decorators: [{
3722
3803
  type: Component,
@@ -3725,7 +3806,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
3725
3806
  '[class.empty-navigation]': 'emptyNavigation',
3726
3807
  }, imports: [
3727
3808
  MarkdownRenderer,
3728
- ], template: "<markdown-renderer [value]=\"html()\"\n [origin]=\"pageOrigin()\"\n [class.empty-navigation]=\"emptyNavigation\"\n [class.expand-no-toc]=\"shouldExpandContent()\"/>\n", styles: [":host{display:block;width:100%;padding:36px var(--page-padding) 120px}@media(min-width:1280px){:host{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 4)}}@media(min-width:1280px){:host.empty-navigation{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2)}}\n"] }]
3809
+ ], template: "<markdown-renderer [value]=\"html()\"\n [origin]=\"pageOrigin()\"\n [class.empty-navigation]=\"emptyNavigation\"\n [class.expand-no-toc]=\"shouldExpandContent()\"/>\n", styles: [":host{display:block;width:100%;padding:48px var(--page-padding) 140px}@media(min-width:1280px){:host{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 4)}}@media(min-width:1280px){:host.empty-navigation{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2)}}\n"] }]
3729
3810
  }] });
3730
3811
 
3731
3812
  var index$2 = /*#__PURE__*/Object.freeze({
@@ -4030,11 +4111,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
4030
4111
  class FHomePageFooterComponent {
4031
4112
  viewModel = inject(HomeStore).getFooter();
4032
4113
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FHomePageFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4033
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: FHomePageFooterComponent, isStandalone: true, selector: "footer[f-home-page-footer]", ngImport: i0, template: "<div class=\"content\">\n <div class=\"flex-space\"></div>\n <div>\n <div class=\"item\">Created with Foblex <a href=\"https://m-render.foblex.com/\" target=\"_blank\">MRender</a></div>\n <div class=\"item\">{{ viewModel.text }}</div>\n </div>\n</div>\n\n", styles: [":host{position:relative;z-index:5;padding:0 24px}:host .content{display:flex;justify-content:flex-start;align-items:center;flex-wrap:wrap;width:100%;height:64px;max-width:1376px;margin:0 auto}:host .item{line-height:20px;font-size:12px;font-weight:500;color:var(--secondary-text);text-align:right}@media(min-width:640px){:host{padding:0 48px}}@media(min-width:960px){:host{padding:0 64px}}\n"] });
4114
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: FHomePageFooterComponent, isStandalone: true, selector: "footer[f-home-page-footer]", ngImport: i0, template: "<div class=\"content\">\n <div class=\"flex-space\"></div>\n <div>\n <div class=\"item\">Created with Foblex <a class=\"f-text-link f-text-link-primary\" href=\"https://m-render.foblex.com/\" target=\"_blank\">MRender</a></div>\n <div class=\"item\">{{ viewModel.text }}</div>\n </div>\n</div>\n", styles: [":host{position:relative;z-index:5;padding:0 24px}:host .content{display:flex;justify-content:flex-start;align-items:center;flex-wrap:wrap;width:100%;height:64px;max-width:1376px;margin:0 auto}:host .item{line-height:20px;font-size:12px;font-weight:500;color:var(--secondary-text);text-align:right}@media(min-width:640px){:host{padding:0 48px}}@media(min-width:960px){:host{padding:0 64px}}\n"] });
4034
4115
  }
4035
4116
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FHomePageFooterComponent, decorators: [{
4036
4117
  type: Component,
4037
- args: [{ selector: 'footer[f-home-page-footer]', standalone: true, template: "<div class=\"content\">\n <div class=\"flex-space\"></div>\n <div>\n <div class=\"item\">Created with Foblex <a href=\"https://m-render.foblex.com/\" target=\"_blank\">MRender</a></div>\n <div class=\"item\">{{ viewModel.text }}</div>\n </div>\n</div>\n\n", styles: [":host{position:relative;z-index:5;padding:0 24px}:host .content{display:flex;justify-content:flex-start;align-items:center;flex-wrap:wrap;width:100%;height:64px;max-width:1376px;margin:0 auto}:host .item{line-height:20px;font-size:12px;font-weight:500;color:var(--secondary-text);text-align:right}@media(min-width:640px){:host{padding:0 48px}}@media(min-width:960px){:host{padding:0 64px}}\n"] }]
4118
+ args: [{ selector: 'footer[f-home-page-footer]', standalone: true, template: "<div class=\"content\">\n <div class=\"flex-space\"></div>\n <div>\n <div class=\"item\">Created with Foblex <a class=\"f-text-link f-text-link-primary\" href=\"https://m-render.foblex.com/\" target=\"_blank\">MRender</a></div>\n <div class=\"item\">{{ viewModel.text }}</div>\n </div>\n</div>\n", styles: [":host{position:relative;z-index:5;padding:0 24px}:host .content{display:flex;justify-content:flex-start;align-items:center;flex-wrap:wrap;width:100%;height:64px;max-width:1376px;margin:0 auto}:host .item{line-height:20px;font-size:12px;font-weight:500;color:var(--secondary-text);text-align:right}@media(min-width:640px){:host{padding:0 48px}}@media(min-width:960px){:host{padding:0 64px}}\n"] }]
4038
4119
  }] });
4039
4120
 
4040
4121
  class FHomePageHeaderComponent {
@@ -4169,5 +4250,5 @@ var index = /*#__PURE__*/Object.freeze({
4169
4250
  * Generated bundle index. Do not edit.
4170
4251
  */
4171
4252
 
4172
- export { AVAILABLE_LANGUAGES, ActivateTocByHash, ActivateTocByHashRequest, CalculateAbsoluteTopToContainer, CalculateAbsoluteTopToContainerRequest, CalculateHashFromScrollPosition, CalculateTableOfContent, CalculateTableOfContentRequest, CodeGroup, CodeView, DEFAULT_MARKDOWN_PAGE_LAYOUT_OPTIONS, DOCUMENTATION_CONFIGURATION, DOCUMENTATION_ROUTES, DOCUMENT_ELEMENT, DYNAMIC_COMPONENTS_MODULE_PROVIDERS, Documentation, DocumentationStore, DropdownMenu, DynamicComponentsStore, EMarkdownContainerType, EParsedContainerType, EXTERNAL_COMPONENT_PROVIDER, ExternalComponent, FBrandLinkComponent, FCheckboxComponent, FHomePageButtonsRowComponent, FHomePageFeaturesComponent, FHomePageFooterComponent, FHomePageHeaderComponent, FHomePageHeroComponent, FHomePageMembershipsComponent, FMetaService, FNavigationItemComponent, FRadioButtonComponent, FSearchButtonComponent, F_PREVIEW_NAVIGATION_PROVIDER, FooterNavigationButton, GTAG_CONFIG, GTagService, GetPreviousNextPageNavigationHandler, GetPreviousNextPageNavigationRequest, GetPreviousNextPageNavigationResponse, HEADER_CONFIGURATION_PROVIDER, HOME_PAGE_CONFIGURATION, HOME_ROUTES, HamburgerButton, HandleNavigationLinksHandler, HandleNavigationLinksRequest, HeaderComponent, HeaderMenuBase, Highlight, HighlightService, HomeRootComponent, HomeStore, IS_BROWSER_PLATFORM, InlineMenu, LOCAL_STORAGE, LOCATION, MEDIA_LINKS_PROVIDER, MExecution, MarkCodeFocusedBlocksPostProcessor, MarkdownFooter, MarkdownRenderer, MarkdownRouter, MarkdownService, MediaLinks, Mediatr, NavigationGroupComponent, NavigationPanelComponent, ParseAlerts, ParseAngularExampleWithCodeLinks, ParseGroupedCodeItems, ParsePreviewGroup, ParseShowcase, ParseSingleCodeItem, PopoverService, PreviewActionBar, PreviewCard, PreviewCardBase, PreviewGroupService, RenderDynamicComponent, RenderDynamicComponentRequest, RenderExternalComponent, RenderExternalComponentRequest, RenderInternalComponents, RenderInternalComponentsRequest, SCROLLABLE_CONTAINER, SHOWCASE_DATA, ScrollToElementInContainer, ScrollToElementInContainerRequest, ScrollableContainer, Showcase, ShowcaseItem, TABLE_OF_CONTENT_MODULE_PROVIDERS, TOGGLE_NAVIGATION_COMPONENT, TableOfContent, TableOfContentData, TableOfContentItemsComponent, ThemeButtonComponent, ThemeService, UNIVERSAL_THEME, WINDOW, calculateMarkdownUrl, coerceComponentHeight$1 as coerceComponentHeight, copyToClipboard, defineLazyComponent, defineNavigationGroup, encodeDataAttr, extractComponent, getContent, getLanguageLoader, isClosingToken, isOpeningToken, parseComponentTag, parseFileLinkLine, parseIframeUrl, parseSingleBracketText, provide404Markdown, provideBackground, provideComponents, provideDirectory, provideDocumentation, provideFooterNavigation, provideGTag, provideHeader, provideHeaderMediaLinks, provideHeaderNavigation, provideHeaderSearch, provideHeaderSearchAlgolia, provideHero, provideHomeButtons, provideHomeFeatures, provideHomeFooter, provideHomePage, provideImage, provideLanguage, provideLogo, provideMeta, provideNavigation, provideShowcase, provideTableOfContent, provideTheme, provideTitle, resolveHighlightLanguage };
4253
+ export { AVAILABLE_LANGUAGES, ActivateTocByHash, ActivateTocByHashRequest, CalculateAbsoluteTopToContainer, CalculateAbsoluteTopToContainerRequest, CalculateHashFromScrollPosition, CalculateTableOfContent, CalculateTableOfContentRequest, CodeGroup, CodeView, DEFAULT_MARKDOWN_PAGE_LAYOUT_OPTIONS, DOCUMENTATION_CONFIGURATION, DOCUMENTATION_ROUTES, DOCUMENT_ELEMENT, DYNAMIC_COMPONENTS_MODULE_PROVIDERS, Documentation, DocumentationStore, DropdownMenu, DynamicComponentsStore, EMarkdownContainerType, EParsedContainerType, EXAMPLE_VIEW, EXTERNAL_COMPONENT_PROVIDER, ExampleViewController, ExternalComponent, FBrandLinkComponent, FCheckboxComponent, FHomePageButtonsRowComponent, FHomePageFeaturesComponent, FHomePageFooterComponent, FHomePageHeaderComponent, FHomePageHeroComponent, FHomePageMembershipsComponent, FMetaService, FNavigationItemComponent, FRadioButtonComponent, FSearchButtonComponent, F_PREVIEW_NAVIGATION_PROVIDER, FooterNavigationButton, GTAG_CONFIG, GTagService, GetPreviousNextPageNavigationHandler, GetPreviousNextPageNavigationRequest, GetPreviousNextPageNavigationResponse, HEADER_CONFIGURATION_PROVIDER, HOME_PAGE_CONFIGURATION, HOME_ROUTES, HamburgerButton, HandleNavigationLinksHandler, HandleNavigationLinksRequest, HeaderComponent, HeaderMenuBase, Highlight, HighlightService, HomeRootComponent, HomeStore, IS_BROWSER_PLATFORM, InlineMenu, LOCAL_STORAGE, LOCATION, MEDIA_LINKS_PROVIDER, MExecution, MarkCodeFocusedBlocksPostProcessor, MarkdownFooter, MarkdownRenderer, MarkdownRouter, MarkdownService, MediaLinks, Mediatr, NavigationGroupComponent, NavigationPanelComponent, ParseAlerts, ParseAngularExampleWithCodeLinks, ParseGroupedCodeItems, ParsePreviewGroup, ParseShowcase, ParseSingleCodeItem, PopoverService, PreviewActionBar, PreviewCard, PreviewCardBase, PreviewGroupService, RenderDynamicComponent, RenderDynamicComponentRequest, RenderExternalComponent, RenderExternalComponentRequest, RenderInternalComponents, RenderInternalComponentsRequest, SCROLLABLE_CONTAINER, SHOWCASE_DATA, ScrollToElementInContainer, ScrollToElementInContainerRequest, ScrollableContainer, Showcase, ShowcaseItem, TABLE_OF_CONTENT_MODULE_PROVIDERS, TOGGLE_NAVIGATION_COMPONENT, TableOfContent, TableOfContentData, TableOfContentItemsComponent, ThemeButtonComponent, ThemeService, UNIVERSAL_THEME, WINDOW, calculateMarkdownUrl, coerceComponentHeight$1 as coerceComponentHeight, copyToClipboard, defineLazyComponent, defineNavigationGroup, encodeDataAttr, extractComponent, getContent, getLanguageLoader, isClosingToken, isOpeningToken, parseComponentTag, parseFileLinkLine, parseIframeUrl, parseSingleBracketText, provide404Markdown, provideBackground, provideComponents, provideDirectory, provideDocumentation, provideFooterNavigation, provideGTag, provideHeader, provideHeaderMediaLinks, provideHeaderNavigation, provideHeaderSearch, provideHeaderSearchAlgolia, provideHero, provideHomeButtons, provideHomeFeatures, provideHomeFooter, provideHomePage, provideImage, provideLanguage, provideLogo, provideMeta, provideNavigation, provideShowcase, provideTableOfContent, provideTheme, provideTitle, resolveHighlightLanguage };
4173
4254
  //# sourceMappingURL=foblex-m-render.mjs.map