UNPKG

@indice/ng-components

Version:

Indice common components for Angular v18

879 lines (866 loc) 517 kB
import * as i0 from '@angular/core'; import { EventEmitter, PLATFORM_ID, Output, Input, Inject, Directive, Component, InjectionToken, Injectable, Optional, TemplateRef, ContentChild, LOCALE_ID, forwardRef, ViewChild, ContentChildren, DOCUMENT, ChangeDetectionStrategy, ViewEncapsulation, Injector, ElementRef, ViewChildren, Pipe, HostListener, NO_ERRORS_SCHEMA, NgModule } from '@angular/core'; import * as i1 from '@angular/common'; import { isPlatformBrowser, formatDate, getLocaleMonthNames, FormStyle, TranslationWidth, getLocaleDayNames, CommonModule } from '@angular/common'; import * as i1$1 from '@angular/router'; import { NavigationEnd, Router, ActivatedRoute, NavigationStart, ActivationStart, RouterModule } from '@angular/router'; import { Subject, BehaviorSubject, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1, of, fromEvent } from 'rxjs'; import { filter, distinctUntilChanged, debounceTime, share, map } from 'rxjs/operators'; import * as i2 from '@angular/forms'; import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; import * as uuid from 'uuid'; import * as i2$1 from '@indice/ng-auth'; import { AuthService, IndiceAuthModule } from '@indice/ng-auth'; // // https://github.com/arkon/ng-click-outside // the project is inactive - so imoved the directive code in our project // // tslint:disable-next-line:directive-selector class ClickOutsideDirective { constructor( // tslint:disable-next-line:variable-name _el, // tslint:disable-next-line:variable-name _ngZone, platformId) { this._el = _el; this._ngZone = _ngZone; this.platformId = platformId; this.clickOutsideEnabled = true; this.attachOutsideOnClick = false; this.delayClickOutsideInit = false; this.emitOnBlur = false; this.exclude = ''; this.excludeBeforeClick = false; this.clickOutsideEvents = ''; this.clickOutside = new EventEmitter(); // tslint:disable-next-line:variable-name this._nodesExcluded = []; // tslint:disable-next-line:variable-name this._events = ['click']; this._initOnClickBody = this._initOnClickBody.bind(this); this._onClickBody = this._onClickBody.bind(this); this._onWindowBlur = this._onWindowBlur.bind(this); } ngOnInit() { if (!isPlatformBrowser(this.platformId)) { return; } this._init(); } ngOnDestroy() { if (!isPlatformBrowser(this.platformId)) { return; } this._removeClickOutsideListener(); this._removeAttachOutsideOnClickListener(); this._removeWindowBlurListener(); } ngOnChanges(changes) { if (!isPlatformBrowser(this.platformId)) { return; } // tslint:disable-next-line:no-string-literal if (changes['attachOutsideOnClick'] || changes['exclude'] || changes['emitOnBlur']) { this._init(); } } _init() { if (this.clickOutsideEvents !== '') { this._events = this.clickOutsideEvents.split(',').map(e => e.trim()); } this._excludeCheck(); if (this.attachOutsideOnClick) { this._initAttachOutsideOnClickListener(); } else { this._initOnClickBody(); } if (this.emitOnBlur) { this._initWindowBlurListener(); } } _initOnClickBody() { if (this.delayClickOutsideInit) { setTimeout(this._initClickOutsideListener.bind(this)); } else { this._initClickOutsideListener(); } } _excludeCheck() { if (this.exclude) { try { const nodes = Array.from(document.querySelectorAll(this.exclude)); if (nodes) { this._nodesExcluded = nodes; } } catch (err) { console.error('[ng-click-outside] Check your exclude selector syntax.', err); } } } _onClickBody(ev) { if (!this.clickOutsideEnabled) { return; } if (this.excludeBeforeClick) { this._excludeCheck(); } if (!this._el.nativeElement.contains(ev.target) && !this._shouldExclude(ev.target)) { this._emit(ev); if (this.attachOutsideOnClick) { this._removeClickOutsideListener(); } } } /** * Resolves problem with outside click on iframe * @see https://github.com/arkon/ng-click-outside/issues/32 */ _onWindowBlur(ev) { setTimeout(() => { if (!document.hidden) { this._emit(ev); } }); } _emit(ev) { if (!this.clickOutsideEnabled) { return; } this._ngZone.run(() => this.clickOutside.emit(ev)); } _shouldExclude(target) { // tslint:disable-next-line:prefer-const for (let excludedNode of this._nodesExcluded) { if (excludedNode.contains(target)) { return true; } } return false; } _initClickOutsideListener() { this._ngZone.runOutsideAngular(() => { this._events.forEach(e => document.addEventListener(e, this._onClickBody)); }); } _removeClickOutsideListener() { this._ngZone.runOutsideAngular(() => { this._events.forEach(e => document.removeEventListener(e, this._onClickBody)); }); } _initAttachOutsideOnClickListener() { this._ngZone.runOutsideAngular(() => { this._events.forEach(e => this._el.nativeElement.addEventListener(e, this._initOnClickBody)); }); } _removeAttachOutsideOnClickListener() { this._ngZone.runOutsideAngular(() => { this._events.forEach(e => this._el.nativeElement.removeEventListener(e, this._initOnClickBody)); }); } _initWindowBlurListener() { this._ngZone.runOutsideAngular(() => { window.addEventListener('blur', this._onWindowBlur); }); } _removeWindowBlurListener() { this._ngZone.runOutsideAngular(() => { window.removeEventListener('blur', this._onWindowBlur); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: ClickOutsideDirective, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.1", type: ClickOutsideDirective, isStandalone: false, selector: "[clickOutside]", inputs: { clickOutsideEnabled: "clickOutsideEnabled", attachOutsideOnClick: "attachOutsideOnClick", delayClickOutsideInit: "delayClickOutsideInit", emitOnBlur: "emitOnBlur", exclude: "exclude", excludeBeforeClick: "excludeBeforeClick", clickOutsideEvents: "clickOutsideEvents" }, outputs: { clickOutside: "clickOutside" }, usesOnChanges: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: ClickOutsideDirective, decorators: [{ type: Directive, args: [{ selector: '[clickOutside]', standalone: false }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }], propDecorators: { clickOutsideEnabled: [{ type: Input }], attachOutsideOnClick: [{ type: Input }], delayClickOutsideInit: [{ type: Input }], emitOnBlur: [{ type: Input }], exclude: [{ type: Input }], excludeBeforeClick: [{ type: Input }], clickOutsideEvents: [{ type: Input }], clickOutside: [{ type: Output }] } }); class DropDownMenuComponent { get selectedOption() { return this.selectedOption$; } set selectedOption(option) { this.selectedOption$ = option; this.selectedValue = option ? option.value : null; this.expanded = false; } get expanded() { return this.expanded$; } set expanded(value) { this.expanded$ = value; } constructor() { this.options = []; // tslint:disable-next-line:no-input-rename this.selectedValue = undefined; this.multiple = false; this.placeholder = 'Παρακαλώ επιλέξτε...'; this.showIcons = true; this.selectedOption$ = null; this.selectedChange = new EventEmitter(); this.selectedChanged = new EventEmitter(); this.expanded$ = false; } ngOnChanges(changes) { if (this.options && this.options.length > 0 && this.selectedValue !== null && this.selectedValue !== undefined) { this.selectedOption$ = this.options.filter((o) => o.value === this.selectedValue)[0]; } } ngOnInit() { } isSelected(option) { return option != null && this.selectedValue != null && option.value === this.selectedValue; } onClickOutside($event) { this.expanded = false; } selectOption(option) { this.selectedOption = option; this.selectedChange.emit(option.value); this.selectedChanged.emit(option.value); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: DropDownMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.1", type: DropDownMenuComponent, isStandalone: false, selector: "lib-drop-down-menu", inputs: { options: "options", selectedValue: ["selected", "selectedValue"], multiple: "multiple", placeholder: "placeholder", showIcons: ["show-icons", "showIcons"] }, outputs: { selectedChange: "selectedChange", selectedChanged: "selectedChanged" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"dropdown-container\" (clickOutside)=\"onClickOutside($event)\">\n <button type=\"button\" (click)=\"expanded = !expanded\" class=\"dropdown-button\" aria-haspopup=\"listbox\" aria-expanded=\"true\" aria-labelledby=\"listbox-label\">\n <span class=\"dropdown-selected-text\">\n <i *ngIf=\"selectedOption?.icon && showIcons\" [class]=\"selectedOption?.icon\" \n [class.mr-2]=\"selectedOption?.icon\"></i>{{ selectedOption?.text || placeholder }}\n </span>\n <span class=\"dropdown-button-icon\">\n <!-- Heroicon name: solid/selector -->\n <svg class=\"dropdown-arrow\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </span>\n </button>\n <ul title=\"menu\" *ngIf=\"expanded && options && options.length > 0\" class=\"dropdown-ul\" tabindex=\"-1\" role=\"listbox\" aria-labelledby=\"listbox-label\">\n <ng-container *ngFor=\"let option of options\">\n <li [class]=\"isSelected(option) ? 'dropdown-li-selected' : 'dropdown-li'\" (click)=\"selectOption(option)\" id=\"listbox-option-0\" role=\"option\">\n <span [class]=\"isSelected(option) ? 'dropdown-li-selected-text' : 'dropdown-li-text'\">\n <i *ngIf=\"option.icon && showIcons\" [class]=\"option.icon\" [class.mr-2]=\"option.icon\"></i>{{ option.text }}\n </span>\n <span *ngIf=\"isSelected(option)\" class=\"dropdown-li-selected-indicator-container\">\n <!-- Heroicon name: solid/check -->\n <svg class=\"dropdown-li-selected-indicator\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\" clip-rule=\"evenodd\"/>\n </svg>\n </span>\n </li>\n </ng-container>\n </ul>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: ClickOutsideDirective, selector: "[clickOutside]", inputs: ["clickOutsideEnabled", "attachOutsideOnClick", "delayClickOutsideInit", "emitOnBlur", "exclude", "excludeBeforeClick", "clickOutsideEvents"], outputs: ["clickOutside"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: DropDownMenuComponent, decorators: [{ type: Component, args: [{ selector: 'lib-drop-down-menu', standalone: false, template: "<div class=\"dropdown-container\" (clickOutside)=\"onClickOutside($event)\">\n <button type=\"button\" (click)=\"expanded = !expanded\" class=\"dropdown-button\" aria-haspopup=\"listbox\" aria-expanded=\"true\" aria-labelledby=\"listbox-label\">\n <span class=\"dropdown-selected-text\">\n <i *ngIf=\"selectedOption?.icon && showIcons\" [class]=\"selectedOption?.icon\" \n [class.mr-2]=\"selectedOption?.icon\"></i>{{ selectedOption?.text || placeholder }}\n </span>\n <span class=\"dropdown-button-icon\">\n <!-- Heroicon name: solid/selector -->\n <svg class=\"dropdown-arrow\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\"\n d=\"M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z\"\n clip-rule=\"evenodd\"/>\n </svg>\n </span>\n </button>\n <ul title=\"menu\" *ngIf=\"expanded && options && options.length > 0\" class=\"dropdown-ul\" tabindex=\"-1\" role=\"listbox\" aria-labelledby=\"listbox-label\">\n <ng-container *ngFor=\"let option of options\">\n <li [class]=\"isSelected(option) ? 'dropdown-li-selected' : 'dropdown-li'\" (click)=\"selectOption(option)\" id=\"listbox-option-0\" role=\"option\">\n <span [class]=\"isSelected(option) ? 'dropdown-li-selected-text' : 'dropdown-li-text'\">\n <i *ngIf=\"option.icon && showIcons\" [class]=\"option.icon\" [class.mr-2]=\"option.icon\"></i>{{ option.text }}\n </span>\n <span *ngIf=\"isSelected(option)\" class=\"dropdown-li-selected-indicator-container\">\n <!-- Heroicon name: solid/check -->\n <svg class=\"dropdown-li-selected-indicator\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\" clip-rule=\"evenodd\"/>\n </svg>\n </span>\n </li>\n </ng-container>\n </ul>\n</div>\n" }] }], ctorParameters: () => [], propDecorators: { options: [{ type: Input }], selectedValue: [{ type: Input, args: ['selected'] }], multiple: [{ type: Input }], placeholder: [{ type: Input }], showIcons: [{ type: Input, args: ['show-icons'] }], selectedChange: [{ type: Output }], selectedChanged: [{ type: Output }] } }); class Icons { // https://uifabricicons.azurewebsites.net/ static { this.Dashboard = `ms-Icon ms-Icon--HomeGroup `; } static { this.Locations = `ms-Icon ms-Icon--MapPin `; } static { this.ChargePoints = `ms-Icon ms-Icon--ChatBot `; } static { this.Transations = `ms-Icon ms-Icon--LightningBolt `; } static { this.Badges = `ms-Icon ms-Icon--IDBadge `; } static { this.Information = `ms-Icon ms-Icon--Info`; } static { this.Refresh = `ms-Icon ms-Icon--Refresh`; } static { this.Search = `ms-Icon ms-Icon--Search`; } static { this.Add = `ms-Icon ms-Icon--Add`; } static { this.Delete = `ms-Icon ms-Icon--Delete`; } static { this.SendEmail = `ms-Icon ms-Icon--NewMail`; } static { this.Filter = `ms-Icon ms-Icon--Filter`; } static { this.Export = `ms-Icon ms-Icon--ExcelDocument`; } static { this.Import = `ms-Icon ms-Icon--PeopleAdd`; } static { this.TilesView = `ms-Icon ms-Icon--AppIconDefault`; } static { this.TableView = `ms-Icon ms-Icon--Table`; } static { this.MapView = `ms-Icon ms-Icon--MapPin`; } static { this.EntryView = `ms-Icon ms-Icon--EntryView`; } static { this.Separator = `ms-Icon ms-Icon--Separator text-white`; } static { this.ItemsCount = 'ms-Icon ms-Icon--Boards'; } static { this.Heart = 'ms-Icon ms-Icon--Heart'; } static { this.HeartBroken = 'ms-Icon ms-Icon--HeartBroken'; } static { this.DateTime = 'ms-Icon ms-Icon--ReminderTime'; } static { this.Expand = 'ms-Icon ms-Icon--ChevronDown'; } static { this.Collapse = 'ms-Icon ms-Icon--ChevronUp'; } static { this.SortAsc = 'ms-Icon ms-Icon--Ascending'; } static { this.SortDesc = 'ms-Icon ms-Icon--Descending'; } static { this.Details = ' ms-Icon ms-Icon--AccountActivity'; } static { this.Messages = ' ms-Icon ms-Icon--Message'; } static { this.MessagesUnread = ' ms-Icon ms-Icon--MessageFill'; } static { this.External = ' ms-Icon ms-Icon--FileSymlink'; } static { this.Statistics = ' ms-Icon ms-Icon--BIDashboard'; } } class NavLink { constructor(text, path, exact = false, external = false, icon, data, queryParams) { this.type = 'router'; this.text = text; this.path = path; this.exact = exact; this.external = external; this.icon = icon; this.data = data; this.queryParams = queryParams; } } class ExternalNavLink extends NavLink { constructor(text, path, openInNewTab, icon) { super(text, path, true, openInNewTab, icon ?? Icons.External); this.type = 'external'; } } class FragmentNavLink extends NavLink { constructor(text, path, icon) { super(text, path, true, true, icon); this.type = 'fragment'; } } class NotificationNavLink extends NavLink { constructor(text, path, isRead, creationDate) { super(text, path, true, false, undefined); this.isRead = isRead; this.creationDate = creationDate; } } class NavLinkSeparator extends NavLink { constructor(text, path, isRead, creationDate) { super('', ''); this.isRead = isRead; this.creationDate = creationDate; this.type = 'separator'; } } class ViewAction { constructor(type, key, param, icon, tooltip, text) { this.type = type; this.key = key; this.param = param; this.icon = icon; this.tooltip = tooltip; this.text = text; } } class ListViewType { static { this.Tiles = 'tiles'; } static { this.Table = 'table'; } static { this.Map = 'map'; } static { this.Gallery = 'gallery'; } } class RouterViewAction extends ViewAction { constructor(icon, link, outlet, tooltip, text) { super('router-link', null, null, icon, tooltip, text); this.outlet = null; this.link = null; this.outlet = outlet; this.link = link; } } class SwitchViewAction extends ViewAction { constructor(view, icon, tooltip) { super('switch-view', null, view, icon, tooltip); } } class HeaderMetaItem { constructor() { this.key = null; this.icon = null; this.text = null; } } class MenuOption { constructor(text, value, description, data, icon) { this.text = text; this.value = value; this.description = description; this.data = data; this.icon = icon; } } var PagerPosition; (function (PagerPosition) { PagerPosition["Top"] = "top"; PagerPosition["Bottom"] = "bottom"; PagerPosition["Both"] = "both"; })(PagerPosition || (PagerPosition = {})); var ShellLayoutType; (function (ShellLayoutType) { ShellLayoutType["Stacked"] = "Stacked"; ShellLayoutType["Sidebar"] = "Sidebar"; })(ShellLayoutType || (ShellLayoutType = {})); class DefaultShellConfig { constructor() { this.appLogo = 'https://tailwindui.com/img/logos/workflow-mark.svg?color=white'; this.appLogoAlt = 'your app name here'; this.breadcrumb = false; this.fluid = false; this.layout = ShellLayoutType.Stacked; this.showAlertsOnHeader = false; this.showFooter = true; this.showHeader = true; this.showUserNameOnHeader = false; this.showPictureOnHeader = true; } } var SCREEN_SIZE; (function (SCREEN_SIZE) { SCREEN_SIZE[SCREEN_SIZE["XS"] = 0] = "XS"; SCREEN_SIZE[SCREEN_SIZE["SM"] = 1] = "SM"; SCREEN_SIZE[SCREEN_SIZE["MD"] = 2] = "MD"; SCREEN_SIZE[SCREEN_SIZE["LG"] = 3] = "LG"; SCREEN_SIZE[SCREEN_SIZE["XL"] = 4] = "XL"; })(SCREEN_SIZE || (SCREEN_SIZE = {})); var ToastType; (function (ToastType) { ToastType["Info"] = "info"; ToastType["Success"] = "success"; ToastType["Error"] = "error"; ToastType["Warning"] = "warning"; })(ToastType || (ToastType = {})); const NULL_TOAST = { title: '_____NULL_____' }; var SidePaneSize; (function (SidePaneSize) { SidePaneSize["Default"] = ""; SidePaneSize["Small25"] = "25%"; SidePaneSize["Medium50"] = "50%"; SidePaneSize["Large75"] = "75%"; SidePaneSize["Fullscreen"] = "100%"; })(SidePaneSize || (SidePaneSize = {})); var SidePaneOverlayType; (function (SidePaneOverlayType) { SidePaneOverlayType["Default"] = ""; SidePaneOverlayType["None"] = "-opacity-0"; SidePaneOverlayType["Light"] = ""; SidePaneOverlayType["Dark"] = "-opacity-50"; })(SidePaneOverlayType || (SidePaneOverlayType = {})); class PagerComponent { constructor(router) { this.router = router; // BUSY STATE this.busy = false; // PAGING this.count = null; this.page = 1; // tslint:disable-next-line:no-input-rename this.pageSize = 20; // tslint:disable-next-line:no-input-rename this.pageSizeOptions = [ new MenuOption('10', 10), new MenuOption('20', 20), new MenuOption('30', 30), new MenuOption('50', 50), new MenuOption('100', 100) ]; this.pages = []; this.pageChanged = new EventEmitter(); this.pageSizeChanged = new EventEmitter(); this.canPreviousPage = false; this.canNextPage = false; // SORTING // tslint:disable-next-line:no-input-rename this.sortOptions = []; // tslint:disable-next-line:no-input-rename this.sort = null; // tslint:disable-next-line:no-input-rename this.sortdir = 'desc'; this.sortChanged = new EventEmitter(); this.sortdirChanged = new EventEmitter(); this.sortdirIcon = Icons.SortDesc; } ngOnChanges(changes) { this.calcPages(); } ngOnInit() { } calcPages() { this.pages = []; if (this.count && this.count > 0) { const pageCount = this.count / this.pageSize; for (let i = 0; i < pageCount; i++) { this.pages.push(new MenuOption(i + 1 + '', i + 1)); } } this.canPreviousPage = this.page > 1; this.canNextPage = this.page < this.pages.length; } nextPage() { const next = this.page + 1; this.gotoPage(next); } previousPage() { const previous = this.page - 1; this.gotoPage(previous); } gotoPage(page) { this.page = page; this.pageChanged.emit(page); this.calcPages(); } pageSizeOptionChanged(pageSize) { this.pageSizeChanged.emit(pageSize); this.calcPages(); } pageOptionChanged(page) { this.pageChanged.emit(page); this.calcPages(); } sortOptionChanged(sort) { this.sortChanged.emit(sort); } toggleSortdir() { let sortdir = 'desc'; if (this.sortdir === 'desc') { sortdir = 'asc'; this.sortdirIcon = Icons.SortAsc; } else { sortdir = 'desc'; this.sortdirIcon = Icons.SortDesc; } this.sortdirChanged.emit(sortdir); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: PagerComponent, deps: [{ token: i1$1.Router }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.1", type: PagerComponent, isStandalone: false, selector: "lib-pager", inputs: { busy: "busy", count: "count", page: "page", pageSize: ["page-size", "pageSize"], pageSizeOptions: ["page-size-options", "pageSizeOptions"], sortOptions: ["sort-options", "sortOptions"], sort: "sort", sortdir: ["sort-dir", "sortdir"] }, outputs: { pageChanged: "pageChanged", pageSizeChanged: "pageSizeChanged", sortChanged: "sortChanged", sortdirChanged: "sortdirChanged" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"pager-container\">\n <div class=\"pager-container-near\">\n <ng-content select=\"[pager-near-content]\"></ng-content>\n </div>\n <div class=\"pager-container-far\">\n <div class=\"inline-flex\" *ngIf=\"sortOptions && sortOptions.length > 0\">\n <lib-drop-down-menu [options]=\"sortOptions\" [selected]=\"sort\" (selectedChanged)=\"sortOptionChanged($event)\"></lib-drop-down-menu>\n <button (click)=\"toggleSortdir()\" [disabled]=\"!sort || busy\" class=\"pager-icon-button\">\n <span class=\"sr-only\">sort direction</span>\n <span class=\"inline-block relative\">\n <i [class]=\"sortdirIcon\"></i>\n </span>\n </button>\n </div>\n <div class=\"pager-pages-container\">\n <lib-drop-down-menu [options]=\"pageSizeOptions\" [selected]=\"pageSize\" (selectedChanged)=\"pageSizeOptionChanged($event)\"></lib-drop-down-menu>\n <div class=\"mx-1\">\n <button [disabled]=\"!canPreviousPage || busy\" (click)=\"previousPage()\"\n class=\"pager-arrow-button-left\">\n <span class=\"sr-only\">Previous</span>\n <svg class=\"h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n <button type=\"button\"\n [disabled]=\"!canNextPage || busy\" (click)=\"nextPage()\"\n class=\"pager-arrow-button-right\">\n <span class=\"sr-only\">Next</span>\n <svg class=\"h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n </div>\n <lib-drop-down-menu *ngIf=\"false && (pages && pages.length > 0)\" [options]=\"pages\" [selected]=\"page\" (selectedChanged)=\"pageOptionChanged($event)\"></lib-drop-down-menu>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DropDownMenuComponent, selector: "lib-drop-down-menu", inputs: ["options", "selected", "multiple", "placeholder", "show-icons"], outputs: ["selectedChange", "selectedChanged"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: PagerComponent, decorators: [{ type: Component, args: [{ selector: 'lib-pager', standalone: false, template: "<div class=\"pager-container\">\n <div class=\"pager-container-near\">\n <ng-content select=\"[pager-near-content]\"></ng-content>\n </div>\n <div class=\"pager-container-far\">\n <div class=\"inline-flex\" *ngIf=\"sortOptions && sortOptions.length > 0\">\n <lib-drop-down-menu [options]=\"sortOptions\" [selected]=\"sort\" (selectedChanged)=\"sortOptionChanged($event)\"></lib-drop-down-menu>\n <button (click)=\"toggleSortdir()\" [disabled]=\"!sort || busy\" class=\"pager-icon-button\">\n <span class=\"sr-only\">sort direction</span>\n <span class=\"inline-block relative\">\n <i [class]=\"sortdirIcon\"></i>\n </span>\n </button>\n </div>\n <div class=\"pager-pages-container\">\n <lib-drop-down-menu [options]=\"pageSizeOptions\" [selected]=\"pageSize\" (selectedChanged)=\"pageSizeOptionChanged($event)\"></lib-drop-down-menu>\n <div class=\"mx-1\">\n <button [disabled]=\"!canPreviousPage || busy\" (click)=\"previousPage()\"\n class=\"pager-arrow-button-left\">\n <span class=\"sr-only\">Previous</span>\n <svg class=\"h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n <button type=\"button\"\n [disabled]=\"!canNextPage || busy\" (click)=\"nextPage()\"\n class=\"pager-arrow-button-right\">\n <span class=\"sr-only\">Next</span>\n <svg class=\"h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n </div>\n <lib-drop-down-menu *ngIf=\"false && (pages && pages.length > 0)\" [options]=\"pages\" [selected]=\"page\" (selectedChanged)=\"pageOptionChanged($event)\"></lib-drop-down-menu>\n </div>\n </div>\n</div>\n" }] }], ctorParameters: () => [{ type: i1$1.Router }], propDecorators: { busy: [{ type: Input }], count: [{ type: Input }], page: [{ type: Input }], pageSize: [{ type: Input, args: ['page-size'] }], pageSizeOptions: [{ type: Input, args: ['page-size-options'] }], pageChanged: [{ type: Output }], pageSizeChanged: [{ type: Output }], sortOptions: [{ type: Input, args: ['sort-options'] }], sort: [{ type: Input, args: ['sort'] }], sortdir: [{ type: Input, args: ['sort-dir'] }], sortChanged: [{ type: Output }], sortdirChanged: [{ type: Output }] } }); class BreadcrumbItem { constructor(title, url) { this.title = title; this.url = url; this.level = 0; } get urlSegments() { if (this.url) { return this.url?.split('/').filter(x => x !== ''); } return undefined; } } const APP_LANGUAGES = new InjectionToken('APP_LANGUAGES'); const APP_LINKS = new InjectionToken('APP_LINKS'); const APP_NOTIFICATIONS = new InjectionToken('APP_NOTIFICATIONS'); const LIBSTEPPER_ACCESSOR = new InjectionToken('LibStepperAccessor'); const LIBTABGROUP_ACCESSOR = new InjectionToken('LibTabGroupAccessor'); const SHELL_CONFIG = new InjectionToken('SHELL_CONFIG'); class UtilitiesService { constructor() { } get validationErrors() { const messages = []; const errors = this.problemDetails && this.problemDetails.errors; for (const property in errors) { if (property) { const propertyMessages = errors[property]; propertyMessages.forEach((message) => { messages.push(message); }); } else { Object.values(errors || {}).forEach(message => { message.forEach(x => { messages.push(x); }); }); } } return messages; } getValidationProblemDetails(problemDetails) { this.problemDetails = problemDetails; if (this.validationErrors.length === 0 && this.problemDetails.title) { return new Array(1).fill(this.problemDetails.title); } return this.validationErrors; } getPathFromUrl(url) { if (!url) { return undefined; } return url.split(/[?#]/)[0]; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: UtilitiesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: UtilitiesService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: UtilitiesService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); class BreadcrumbService { constructor(_router, _utilities, _shellConfig) { this._router = _router; this._utilities = _utilities; this._shellConfig = _shellConfig; this._breadcrumb$ = new Subject(); this.breadcrumb = this._breadcrumb$.asObservable(); if (_shellConfig?.breadcrumb) { this._defaultHome = this._getDefaultHomeItem(); this._router .events .pipe(filter(event => event instanceof NavigationEnd), distinctUntilChanged()) .subscribe(_ => { const breadcrumb = this._buildBreadcrumb(); this._breadcrumb$.next(breadcrumb); }); } } _getDefaultHomeItem() { const routerConfig = this._router.config; const declaredHomeRoutes = routerConfig.filter((route) => route.data?.breadcrumb?.isHome === true); if (declaredHomeRoutes.length > 1) { throw new Error('You can declare only one route as home.'); } let homeRoute; if (declaredHomeRoutes.length === 1) { homeRoute = declaredHomeRoutes[0]; } else { homeRoute = routerConfig.find((route) => route.path === ''); if (!homeRoute) { return undefined; } const redirectionUrl = homeRoute.redirectTo; if (!homeRoute?.data?.breadcrumb?.title && redirectionUrl) { homeRoute = routerConfig.find((route) => route.path === redirectionUrl); if (!homeRoute) { return undefined; } } } return new BreadcrumbItem(this._getRouteTitle(homeRoute), homeRoute.path || ''); } _getRouteTitle(route) { return route?.data?.breadcrumb?.title || route.component?.name.replace('Component', ''); } _buildBreadcrumb() { const breadcrumb = []; if (this._defaultHome) { breadcrumb.push(this._defaultHome); } const url = this._router.url; const path = this._utilities.getPathFromUrl(url) || ''; const activeRoute = this._findRouteFromUrl(path); const parentRoutes = this._findParentRoutes(activeRoute); breadcrumb.push(...parentRoutes); if (activeRoute && activeRoute?.path !== this._defaultHome?.url) { const routeData = this._getBreadcrumbRouteData(activeRoute); breadcrumb.push(new BreadcrumbItem(this._getRouteTitle(activeRoute), (routeData._fullPath || activeRoute.path || ''))); } return breadcrumb.map((route) => { const routeSegments = route.url?.split('/') || []; routeSegments.forEach((segment, index) => { if (segment.startsWith(':')) { route.url = route.url?.replace(segment, url.split('/')[index + 1]); } }); return route; }); } _findRouteFromUrl(url) { let urlSegments = url.replace(/\(.+\)/, '') // remove any secondary outlet segments and focus on primary outlet that is the main route .split('/') // split the URL into segments .filter((segment) => segment !== ''); const outletRegex = new RegExp("\\(([^()]+)\\)"); var outletPart = url.match(outletRegex)?.[1]; //if (outletPart) { //urlSegments = outletPart.replace(/.+:/, '').split('/') // split the URL into segments // .filter((segment: string) => segment !== ''); //} const routerConfig = this._router.config; const flattenedRouterConfig = this._flattenRoutes(routerConfig); const filteredRouterConfig = flattenedRouterConfig.filter((route) => { const routeData = this._getBreadcrumbRouteData(route); return (routeData._fullPath || route.path)?.split('/').length === urlSegments.length; }); const route = filteredRouterConfig.find((route) => { const routeData = this._getBreadcrumbRouteData(route); const routeSegments = (routeData._fullPath || route.path)?.split('/') || []; let segmentsMatched = false; for (let i = 0; i < routeSegments.length; i++) { const currentSegment = routeSegments[i]; const isDynamicSegment = currentSegment.startsWith(':'); if (!isDynamicSegment) { segmentsMatched = currentSegment === urlSegments[i]; } } return segmentsMatched ? route : undefined; }); return route; } _findParentRoutes(activeRoute, items = []) { if (!activeRoute) { return []; } const routeData = this._getBreadcrumbRouteData(activeRoute); let urlSegments = (routeData._fullPath || activeRoute.path)?.split('/').filter((segment) => segment !== '') || []; if (urlSegments?.length <= 1) { return [...items]; } const previousUrl = urlSegments.slice(0, -1).join('/'); const route = this._findRouteFromUrl(previousUrl); if (route) { const routeData = this._getBreadcrumbRouteData(route); if (routeData._level > 0 || (!route.children || route.children.length === 0)) { items = this._findParentRoutes(route, [new BreadcrumbItem(this._getRouteTitle(route), routeData._fullPath || route.path), ...items]); } } return [...items]; } _flattenRoutes(routes, level) { let children = []; level = level || 0; return routes.map((route) => { const routeData = this._getBreadcrumbRouteData(route); routeData._level = level; if (route.children && route.children.length) { route.children.forEach((child) => { const childRouteData = this._getBreadcrumbRouteData(child); const routePath = routeData._fullPath || route.path || ''; const childPath = child.path?.endsWith('/') ? child.path.slice(0, -1) : child.path; childRouteData._fullPath = childPath?.indexOf(routePath) === -1 ? `${routePath}/${childPath}` : childPath; }); children = [...children, ...route.children]; } return route; }).concat(children.length ? this._flattenRoutes(children, level + 1) : children); } _getBreadcrumbRouteData(route) { if (!route) { throw new Error('No route was found'); } if (!route.data?.breadcrumb) { if (!route.data) { route.data = {}; } route.data.breadcrumb = new BreadcrumbRouteData(0, false, undefined); } return route.data.breadcrumb; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: BreadcrumbService, deps: [{ token: i1$1.Router }, { token: UtilitiesService }, { token: SHELL_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: BreadcrumbService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: BreadcrumbService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1$1.Router }, { type: UtilitiesService }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [SHELL_CONFIG] }] }] }); class BreadcrumbRouteData { constructor(_level, isHome, _fullPath) { this._level = _level; this.isHome = isHome; this._fullPath = _fullPath; } } class BreadcrumbComponent { constructor(_breadcrumbService) { this._breadcrumbService = _breadcrumbService; this.breadcrumb = []; } ngOnInit() { this._breadcrumbService .breadcrumb .subscribe((breadcrumb) => { this.breadcrumb = [...breadcrumb, new BreadcrumbItem('', '')]; }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: BreadcrumbComponent, deps: [{ token: BreadcrumbService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.1", type: BreadcrumbComponent, isStandalone: false, selector: "lib-breadcrumb", ngImport: i0, template: "<nav class=\"bg-white border-b border-gray-200 flex\"\n aria-label=\"Breadcrumb\">\n <ol role=\"list\"\n class=\"w-full mx-auto px-4 flex space-x-4 sm:px-6 lg:px-8\">\n <li class=\"flex\"\n *ngFor=\"let item of breadcrumb; let i = index\">\n <div class=\"flex items-center\">\n <ng-container *ngTemplateOutlet=\"i === 0 ? homeTemplate : linkTemplate; context: { value: item }\"></ng-container>\n </div>\n </li>\n </ol>\n</nav>\n<ng-template let-value=\"value\"\n #homeTemplate>\n <a [routerLink]=\"value.urlSegments\"\n [title]=\"value.title\"\n class=\"text-gray-400 hover:text-gray-500\">\n <svg class=\"flex-shrink-0 h-5 w-5\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\">\n <path d=\"M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z\" />\n </svg>\n <span class=\"sr-only\">{{ value.title }}</span>\n </a>\n</ng-template>\n<ng-template let-value=\"value\"\n #linkTemplate>\n <svg class=\"flex-shrink-0 w-6 h-full text-gray-200\"\n viewBox=\"0 0 24 44\"\n preserveAspectRatio=\"none\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\">\n <path d=\"M.293 0l22 22-22 22h1.414l22-22-22-22H.293z\" />\n </svg>\n <a [routerLink]=\"value.urlSegments\"\n class=\"ml-4 text-sm font-medium text-gray-500 hover:text-gray-700\">\n {{ value.title }}\n </a>\n</ng-template>", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: BreadcrumbComponent, decorators: [{ type: Component, args: [{ selector: 'lib-breadcrumb', standalone: false, template: "<nav class=\"bg-white border-b border-gray-200 flex\"\n aria-label=\"Breadcrumb\">\n <ol role=\"list\"\n class=\"w-full mx-auto px-4 flex space-x-4 sm:px-6 lg:px-8\">\n <li class=\"flex\"\n *ngFor=\"let item of breadcrumb; let i = index\">\n <div class=\"flex items-center\">\n <ng-container *ngTemplateOutlet=\"i === 0 ? homeTemplate : linkTemplate; context: { value: item }\"></ng-container>\n </div>\n </li>\n </ol>\n</nav>\n<ng-template let-value=\"value\"\n #homeTemplate>\n <a [routerLink]=\"value.urlSegments\"\n [title]=\"value.title\"\n class=\"text-gray-400 hover:text-gray-500\">\n <svg class=\"flex-shrink-0 h-5 w-5\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\">\n <path d=\"M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z\" />\n </svg>\n <span class=\"sr-only\">{{ value.title }}</span>\n </a>\n</ng-template>\n<ng-template let-value=\"value\"\n #linkTemplate>\n <svg class=\"flex-shrink-0 w-6 h-full text-gray-200\"\n viewBox=\"0 0 24 44\"\n preserveAspectRatio=\"none\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\">\n <path d=\"M.293 0l22 22-22 22h1.414l22-22-22-22H.293z\" />\n </svg>\n <a [routerLink]=\"value.urlSegments\"\n class=\"ml-4 text-sm font-medium text-gray-500 hover:text-gray-700\">\n {{ value.title }}\n </a>\n</ng-template>" }] }], ctorParameters: () => [{ type: BreadcrumbService }] }); class ListColumnComponent { constructor() { this.title = null; // tslint:disable-next-line:no-input-rename this.fullWidth = false; this.template = null; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: ListColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.1", type: ListColumnComponent, isStandalone: false, selector: "lib-list-column", inputs: { title: "title", fullWidth: ["full-width", "fullWidth"] }, queries: [{ propertyName: "template", first: true, predicate: TemplateRef, descendants: true }], ngImport: i0, template: '<ng-content></ng-content>', isInline: true }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: ListColumnComponent, decorators: [{ type: Component, args: [{ selector: 'lib-list-column', template: '<ng-content></ng-content>', standalone: false }] }], ctorParameters: () => [], propDecorators: { title: [{ type: Input }], fullWidth: [{ type: Input, args: ['full-width'] }], template: [{ type: ContentChild, args: [TemplateRef] }] } }); class ListTileComponent { constructor() { this.template = null; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: ListTileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.1", type: ListTileComponent, isStandalone: false, selector: "lib-list-tile", queries: [{ propertyName: "template", first: true, predicate: TemplateRef, descendants: true }], ngImport: i0, template: '<ng-content></ng-content>', isInline: true }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: ListTileComponent, decorators: [{ type: Component, args: [{ selector: 'lib-list-tile', template: '<ng-content></ng-content>', standalone: false }] }], ctorParameters: () => [], propDecorators: { template: [{ type: ContentChild, args: [TemplateRef] }] } }); class ListDetailsSectionComponent { constructor() { this.template = null; } static { this.ɵfac = i0.ɵɵngDeclareFactory(