@firestitch/report 18.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/reports/components/component-chart/component-chart.component.d.ts +16 -0
- package/app/reports/components/component-kpi/component-kpi.component.d.ts +12 -0
- package/app/reports/components/component-list/component-list.component.d.ts +27 -0
- package/app/reports/components/report-canvas/report-canvas.component.d.ts +84 -0
- package/app/reports/components/report-component/report-component.component.d.ts +71 -0
- package/app/reports/components/timezone-select/timezone-select.component.d.ts +18 -0
- package/app/reports/data/report.data.d.ts +48 -0
- package/app/reports/dialogs/component-settings/component-settings.component.d.ts +49 -0
- package/app/reports/dialogs/report-settings/report-settings.component.d.ts +25 -0
- package/app/reports/export/offscreen-chart.d.ts +2 -0
- package/app/reports/export/report-export-collector.service.d.ts +26 -0
- package/app/reports/export/report-pdf.service.d.ts +13 -0
- package/app/reports/export/report-pptx.service.d.ts +14 -0
- package/app/reports/format.d.ts +1 -0
- package/app/reports/interfaces/report.interface.d.ts +174 -0
- package/app/reports/layout.d.ts +11 -0
- package/app/reports/option-builder.d.ts +15 -0
- package/app/reports/report-filter-items.d.ts +9 -0
- package/app/reports/services/report-filter-state.service.d.ts +25 -0
- package/app/reports/services/report.service.d.ts +15 -0
- package/app/reports/theme/echarts.d.ts +2 -0
- package/app/reports/theme/palette.d.ts +2 -0
- package/app/reports/views/report/report.component.d.ts +50 -0
- package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +47 -0
- package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +33 -0
- package/esm2022/app/reports/components/component-list/component-list.component.mjs +178 -0
- package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +347 -0
- package/esm2022/app/reports/components/report-component/report-component.component.mjs +453 -0
- package/esm2022/app/reports/components/timezone-select/timezone-select.component.mjs +70 -0
- package/esm2022/app/reports/data/report.data.mjs +152 -0
- package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +221 -0
- package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +109 -0
- package/esm2022/app/reports/export/offscreen-chart.mjs +33 -0
- package/esm2022/app/reports/export/report-export-collector.service.mjs +94 -0
- package/esm2022/app/reports/export/report-pdf.service.mjs +155 -0
- package/esm2022/app/reports/export/report-pptx.service.mjs +224 -0
- package/esm2022/app/reports/format.mjs +25 -0
- package/esm2022/app/reports/interfaces/report.interface.mjs +16 -0
- package/esm2022/app/reports/layout.mjs +50 -0
- package/esm2022/app/reports/option-builder.mjs +293 -0
- package/esm2022/app/reports/report-filter-items.mjs +125 -0
- package/esm2022/app/reports/services/report-filter-state.service.mjs +177 -0
- package/esm2022/app/reports/services/report.service.mjs +56 -0
- package/esm2022/app/reports/theme/echarts.mjs +59 -0
- package/esm2022/app/reports/theme/palette.mjs +10 -0
- package/esm2022/app/reports/views/report/report.component.mjs +354 -0
- package/esm2022/firestitch-report.mjs +5 -0
- package/esm2022/public_api.mjs +13 -0
- package/fesm2022/firestitch-report-echarts-BxYnpz7n.mjs +60 -0
- package/fesm2022/firestitch-report-echarts-BxYnpz7n.mjs.map +1 -0
- package/fesm2022/firestitch-report-firestitch-report-Cnotycly.mjs +3107 -0
- package/fesm2022/firestitch-report-firestitch-report-Cnotycly.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +2 -0
- package/fesm2022/firestitch-report.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/package.json +39 -0
- package/public_api.d.ts +5 -0
- package/styles.scss +1 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, inject } from '@angular/core';
|
|
2
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
import { MatButton } from '@angular/material/button';
|
|
5
|
+
import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef, MatDialogTitle } from '@angular/material/dialog';
|
|
6
|
+
import { MatFormField, MatLabel, MatHint, MatSuffix } from '@angular/material/form-field';
|
|
7
|
+
import { MatInput } from '@angular/material/input';
|
|
8
|
+
import { MatOption, MatSelect } from '@angular/material/select';
|
|
9
|
+
import { MatTabsModule } from '@angular/material/tabs';
|
|
10
|
+
import { FsDialogModule } from '@firestitch/dialog';
|
|
11
|
+
import { FsFormModule } from '@firestitch/form';
|
|
12
|
+
import { FsMessage } from '@firestitch/message';
|
|
13
|
+
import { FsPrompt } from '@firestitch/prompt';
|
|
14
|
+
import { FsTabsModule } from '@firestitch/tabs';
|
|
15
|
+
import { TimezoneSelectComponent } from '../../components/timezone-select/timezone-select.component';
|
|
16
|
+
import { switchMap, tap } from 'rxjs/operators';
|
|
17
|
+
import { ReportData } from '../../data/report.data';
|
|
18
|
+
import { DEFAULT_HEADING_SIZE } from '../../layout';
|
|
19
|
+
import * as i0 from "@angular/core";
|
|
20
|
+
import * as i1 from "@angular/forms";
|
|
21
|
+
import * as i2 from "@firestitch/form";
|
|
22
|
+
import * as i3 from "@firestitch/dialog";
|
|
23
|
+
import * as i4 from "@firestitch/tabs";
|
|
24
|
+
import * as i5 from "@angular/material/tabs";
|
|
25
|
+
// Report settings, in two tabs:
|
|
26
|
+
// Settings — name + page setup (size, orientation, layout mode). The layout
|
|
27
|
+
// mode is the big one: Freeform (position anything anywhere) vs Flow
|
|
28
|
+
// (components flow into rows by width %).
|
|
29
|
+
// Styles — the report's typographic styles. Sizes are in POINTS so they
|
|
30
|
+
// map 1:1 to PDF/PowerPoint; we start with the Heading size.
|
|
31
|
+
export class ReportSettingsComponent {
|
|
32
|
+
selectedTab = 'settings';
|
|
33
|
+
name = '';
|
|
34
|
+
pageSize = 'widescreen';
|
|
35
|
+
pageOrientation = 'landscape';
|
|
36
|
+
layout = 'freeform';
|
|
37
|
+
// Empty until the report has one; app-timezone-select then defaults it to the
|
|
38
|
+
// viewer's browser zone (which Save persists, making the report's zone explicit).
|
|
39
|
+
timezone = '';
|
|
40
|
+
headingSize = DEFAULT_HEADING_SIZE;
|
|
41
|
+
_data = inject(MAT_DIALOG_DATA);
|
|
42
|
+
_dialogRef = inject(MatDialogRef);
|
|
43
|
+
_reportData = inject(ReportData);
|
|
44
|
+
_message = inject(FsMessage);
|
|
45
|
+
_prompt = inject(FsPrompt);
|
|
46
|
+
_destroyRef = inject(DestroyRef);
|
|
47
|
+
ngOnInit() {
|
|
48
|
+
const report = this._data.report;
|
|
49
|
+
this.name = report.name;
|
|
50
|
+
this.pageSize = report.pageSize;
|
|
51
|
+
this.pageOrientation = report.pageOrientation;
|
|
52
|
+
this.layout = report.layout ?? 'freeform';
|
|
53
|
+
this.timezone = report.timezone ?? '';
|
|
54
|
+
this.headingSize = report.config?.styles?.heading?.size ?? DEFAULT_HEADING_SIZE;
|
|
55
|
+
}
|
|
56
|
+
// Confirm and delete here, while the dialog is still open, then close with
|
|
57
|
+
// a `deleted` result. The page reacts to the result; it no longer owns the
|
|
58
|
+
// prompt or the API call.
|
|
59
|
+
delete() {
|
|
60
|
+
this._prompt.confirm({
|
|
61
|
+
title: 'Delete Report',
|
|
62
|
+
template: `Delete "${this._data.report.name}"? This cannot be undone.`,
|
|
63
|
+
})
|
|
64
|
+
.pipe(switchMap(() => this._reportData.delete(this._data.report.id)), takeUntilDestroyed(this._destroyRef))
|
|
65
|
+
.subscribe(() => {
|
|
66
|
+
this._message.success('Report deleted');
|
|
67
|
+
this._dialogRef.close({ action: 'deleted' });
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
save = () => {
|
|
71
|
+
return this._reportData.update(this._data.report.id, {
|
|
72
|
+
name: this.name,
|
|
73
|
+
pageSize: this.pageSize,
|
|
74
|
+
pageOrientation: this.pageOrientation,
|
|
75
|
+
layout: this.layout,
|
|
76
|
+
timezone: this.timezone,
|
|
77
|
+
styles: { heading: { size: this.headingSize } },
|
|
78
|
+
})
|
|
79
|
+
.pipe(tap(() => {
|
|
80
|
+
this._message.success('Report settings saved');
|
|
81
|
+
this._dialogRef.close({ action: 'saved' });
|
|
82
|
+
}));
|
|
83
|
+
};
|
|
84
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
85
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ReportSettingsComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n Report Settings\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"name\"\n name=\"name\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Page Size\n </mat-label>\n <mat-select\n [(ngModel)]=\"pageSize\"\n name=\"pageSize\">\n <mat-option value=\"widescreen\">\n Widescreen (13.33\" \u00D7 7.5\")\n </mat-option>\n <mat-option value=\"letter\">\n Letter (11\" \u00D7 8.5\")\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Orientation\n </mat-label>\n <mat-select\n [(ngModel)]=\"pageOrientation\"\n name=\"pageOrientation\">\n <mat-option value=\"landscape\">\n Landscape\n </mat-option>\n <mat-option value=\"portrait\">\n Portrait\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Layout\n </mat-label>\n <mat-select\n [(ngModel)]=\"layout\"\n name=\"layout\">\n <mat-option value=\"freeform\">\n Freeform \u2014 position components anywhere on the page\n </mat-option>\n <mat-option value=\"flow\">\n Flow \u2014 components flow into rows by width %\n </mat-option>\n </mat-select>\n <mat-hint>\n Freeform is like PowerPoint; Flow is like a responsive dashboard.\n </mat-hint>\n </mat-form-field>\n <fs-ai-report-timezone-select [(timezone)]=\"timezone\"></fs-ai-report-timezone-select>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Styles\"\n name=\"styles\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Heading Size\n </mat-label>\n <input\n matInput\n type=\"number\"\n step=\"1\"\n min=\"6\"\n max=\"96\"\n [(ngModel)]=\"headingSize\"\n name=\"headingSize\"\n [fsFormMin]=\"6\"\n [fsFormMax]=\"96\">\n <span matTextSuffix>\n pt\n </span>\n <mat-hint>\n Applies to component titles. Points map 1:1 to PDF and PowerPoint.\n </mat-hint>\n </mat-form-field>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>", styles: ["mat-form-field{width:100%}.tab-body{padding-top:16px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { kind: "directive", type: i2.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { kind: "directive", type: i2.FsFormMinDirective, selector: "[fsFormMin]", inputs: ["fsFormMin", "fsFormMinMessage"] }, { kind: "directive", type: i2.FsFormMaxDirective, selector: "[fsFormMax]", inputs: ["fsFormMax", "fsFormMaxMessage"] }, { kind: "component", type: i2.FsFormDialogActionsComponent, selector: "fs-form-dialog-actions", inputs: ["save", "create", "close", "done", "closeData", "name"] }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "directive", type: i2.FsButtonDirective, selector: "[mat-raised-button],[mat-button],[mat-flat-button],[mat-stroked-button]", inputs: ["name", "dirtySubmit"] }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i3.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "ngmodule", type: FsTabsModule }, { kind: "directive", type: i4.FsTabsHeaderTabGroupDirective, selector: "mat-tab-group, matTabGroup, [matTabGroup]", inputs: ["orientation", "selected", "selectedData"], outputs: ["selectedChange", "selectedDataChange"], exportAs: ["fsTabsHeaderTabGroup"] }, { kind: "directive", type: i4.FsTabsTabDirective, selector: "mat-tab,matTab", inputs: ["name", "data"], exportAs: ["fsTabsTab"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i5.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i5.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: TimezoneSelectComponent, selector: "fs-ai-report-timezone-select", inputs: ["placeholder", "required", "disabled", "timezone"], outputs: ["timezoneChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
86
|
+
}
|
|
87
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportSettingsComponent, decorators: [{
|
|
88
|
+
type: Component,
|
|
89
|
+
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
90
|
+
FormsModule,
|
|
91
|
+
FsFormModule,
|
|
92
|
+
FsDialogModule,
|
|
93
|
+
FsTabsModule,
|
|
94
|
+
MatTabsModule,
|
|
95
|
+
MatButton,
|
|
96
|
+
MatDialogTitle,
|
|
97
|
+
MatDialogContent,
|
|
98
|
+
MatDialogActions,
|
|
99
|
+
MatFormField,
|
|
100
|
+
MatLabel,
|
|
101
|
+
MatHint,
|
|
102
|
+
MatSuffix,
|
|
103
|
+
MatInput,
|
|
104
|
+
MatSelect,
|
|
105
|
+
MatOption,
|
|
106
|
+
TimezoneSelectComponent,
|
|
107
|
+
], template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n Report Settings\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"name\"\n name=\"name\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Page Size\n </mat-label>\n <mat-select\n [(ngModel)]=\"pageSize\"\n name=\"pageSize\">\n <mat-option value=\"widescreen\">\n Widescreen (13.33\" \u00D7 7.5\")\n </mat-option>\n <mat-option value=\"letter\">\n Letter (11\" \u00D7 8.5\")\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Orientation\n </mat-label>\n <mat-select\n [(ngModel)]=\"pageOrientation\"\n name=\"pageOrientation\">\n <mat-option value=\"landscape\">\n Landscape\n </mat-option>\n <mat-option value=\"portrait\">\n Portrait\n </mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Layout\n </mat-label>\n <mat-select\n [(ngModel)]=\"layout\"\n name=\"layout\">\n <mat-option value=\"freeform\">\n Freeform \u2014 position components anywhere on the page\n </mat-option>\n <mat-option value=\"flow\">\n Flow \u2014 components flow into rows by width %\n </mat-option>\n </mat-select>\n <mat-hint>\n Freeform is like PowerPoint; Flow is like a responsive dashboard.\n </mat-hint>\n </mat-form-field>\n <fs-ai-report-timezone-select [(timezone)]=\"timezone\"></fs-ai-report-timezone-select>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Styles\"\n name=\"styles\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Heading Size\n </mat-label>\n <input\n matInput\n type=\"number\"\n step=\"1\"\n min=\"6\"\n max=\"96\"\n [(ngModel)]=\"headingSize\"\n name=\"headingSize\"\n [fsFormMin]=\"6\"\n [fsFormMax]=\"96\">\n <span matTextSuffix>\n pt\n </span>\n <mat-hint>\n Applies to component titles. Points map 1:1 to PDF and PowerPoint.\n </mat-hint>\n </mat-form-field>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>", styles: ["mat-form-field{width:100%}.tab-body{padding-top:16px}\n"] }]
|
|
108
|
+
}] });
|
|
109
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXNldHRpbmdzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9kaWFsb2dzL3JlcG9ydC1zZXR0aW5ncy9yZXBvcnQtc2V0dGluZ3MuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvcmVwb3J0LXNldHRpbmdzL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0YsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDaEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTdDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLGdCQUFnQixFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM3SCxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDMUYsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXZELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFN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QUFjO3dCQUNkLGdCQUFnQjt3QkFDaEIsZ0JBQWdCO3dCQUNoQixZQUFZO3dCQUNaLFFBQVE7d0JBQ1IsT0FBTzt3QkFDUCxTQUFTO3dCQUNULFFBQVE7d0JBQ1IsU0FBUzt3QkFDVCxTQUFTO3dCQUNULHVCQUF1QjtxQkFDeEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBEZXN0cm95UmVmLCBPbkluaXQsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IE1hdEJ1dHRvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XG5pbXBvcnQgeyBNQVRfRElBTE9HX0RBVEEsIE1hdERpYWxvZ0FjdGlvbnMsIE1hdERpYWxvZ0NvbnRlbnQsIE1hdERpYWxvZ1JlZiwgTWF0RGlhbG9nVGl0bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkLCBNYXRMYWJlbCwgTWF0SGludCwgTWF0U3VmZml4IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcbmltcG9ydCB7IE1hdE9wdGlvbiwgTWF0U2VsZWN0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc2VsZWN0JztcbmltcG9ydCB7IE1hdFRhYnNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90YWJzJztcblxuaW1wb3J0IHsgRnNEaWFsb2dNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9kaWFsb2cnO1xuaW1wb3J0IHsgRnNGb3JtTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvZm9ybSc7XG5pbXBvcnQgeyBGc01lc3NhZ2UgfSBmcm9tICdAZmlyZXN0aXRjaC9tZXNzYWdlJztcbmltcG9ydCB7IEZzUHJvbXB0IH0gZnJvbSAnQGZpcmVzdGl0Y2gvcHJvbXB0JztcbmltcG9ydCB7IEZzVGFic01vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL3RhYnMnO1xuXG5pbXBvcnQgeyBUaW1lem9uZVNlbGVjdENvbXBvbmVudCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvdGltZXpvbmUtc2VsZWN0L3RpbWV6b25lLXNlbGVjdC5jb21wb25lbnQnO1xuXG5pbXBvcnQgeyBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHsgUmVwb3J0IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IERFRkFVTFRfSEVBRElOR19TSVpFIH0gZnJvbSAnLi4vLi4vbGF5b3V0JztcblxuXG4vLyBXaGF0IHRoZSBkaWFsb2cgaGFuZHMgYmFjayB3aGVuIGl0IGNsb3Nlcywgc28gdGhlIHBhZ2Uga25vd3Mgd2hhdCBoYXBwZW5lZFxuLy8gd2l0aG91dCBzbmlmZmluZyBtYWdpYyBzdHJpbmdzLiBBIGRpc21pc3NlZCBkaWFsb2cgY2xvc2VzIHdpdGggYHVuZGVmaW5lZGAuXG5leHBvcnQgaW50ZXJmYWNlIFJlcG9ydFNldHRpbmdzUmVzdWx0IHtcbiAgYWN0aW9uOiAnc2F2ZWQnIHwgJ2RlbGV0ZWQnO1xufVxuXG5cbi8vIFJlcG9ydCBzZXR0aW5ncywgaW4gdHdvIHRhYnM6XG4vLyAgIFNldHRpbmdzIOKAlCBuYW1lICsgcGFnZSBzZXR1cCAoc2l6ZSwgb3JpZW50YXRpb24sIGxheW91dCBtb2RlKS4gVGhlIGxheW91dFxuLy8gICBtb2RlIGlzIHRoZSBiaWcgb25lOiBGcmVlZm9ybSAocG9zaXRpb24gYW55dGhpbmcgYW55d2hlcmUpIHZzIEZsb3dcbi8vICAgKGNvbXBvbmVudHMgZmxvdyBpbnRvIHJvd3MgYnkgd2lkdGggJSkuXG4vLyAgIFN0eWxlcyAgIOKAlCB0aGUgcmVwb3J0J3MgdHlwb2dyYXBoaWMgc3R5bGVzLiBTaXplcyBhcmUgaW4gUE9JTlRTIHNvIHRoZXlcbi8vICAgbWFwIDE6MSB0byBQREYvUG93ZXJQb2ludDsgd2Ugc3RhcnQgd2l0aCB0aGUgSGVhZGluZyBzaXplLlxuQENvbXBvbmVudCh7XG4gIHRlbXBsYXRlVXJsOiAnLi9yZXBvcnQtc2V0dGluZ3MuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9yZXBvcnQtc2V0dGluZ3MuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBGc0Zvcm1Nb2R1bGUsXG4gICAgRnNEaWFsb2dNb2R1bGUsXG4gICAgRnNUYWJzTW9kdWxlLFxuICAgIE1hdFRhYnNNb2R1bGUsXG4gICAgTWF0QnV0dG9uLFxuICAgIE1hdERpYWxvZ1RpdGxlLFxuICAgIE1hdERpYWxvZ0NvbnRlbnQsXG4gICAgTWF0RGlhbG9nQWN0aW9ucyxcbiAgICBNYXRGb3JtRmllbGQsXG4gICAgTWF0TGFiZWwsXG4gICAgTWF0SGludCxcbiAgICBNYXRTdWZmaXgsXG4gICAgTWF0SW5wdXQsXG4gICAgTWF0U2VsZWN0LFxuICAgIE1hdE9wdGlvbixcbiAgICBUaW1lem9uZVNlbGVjdENvbXBvbmVudCxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgUmVwb3J0U2V0dGluZ3NDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIHB1YmxpYyBzZWxlY3RlZFRhYiA9ICdzZXR0aW5ncyc7XG5cbiAgcHVibGljIG5hbWUgPSAnJztcbiAgcHVibGljIHBhZ2VTaXplOiAnd2lkZXNjcmVlbicgfCAnbGV0dGVyJyA9ICd3aWRlc2NyZWVuJztcbiAgcHVibGljIHBhZ2VPcmllbnRhdGlvbjogJ2xhbmRzY2FwZScgfCAncG9ydHJhaXQnID0gJ2xhbmRzY2FwZSc7XG4gIHB1YmxpYyBsYXlvdXQ6ICdmcmVlZm9ybScgfCAnZmxvdycgPSAnZnJlZWZvcm0nO1xuICAvLyBFbXB0eSB1bnRpbCB0aGUgcmVwb3J0IGhhcyBvbmU7IGFwcC10aW1lem9uZS1zZWxlY3QgdGhlbiBkZWZhdWx0cyBpdCB0byB0aGVcbiAgLy8gdmlld2VyJ3MgYnJvd3NlciB6b25lICh3aGljaCBTYXZlIHBlcnNpc3RzLCBtYWtpbmcgdGhlIHJlcG9ydCdzIHpvbmUgZXhwbGljaXQpLlxuICBwdWJsaWMgdGltZXpvbmUgPSAnJztcbiAgcHVibGljIGhlYWRpbmdTaXplID0gREVGQVVMVF9IRUFESU5HX1NJWkU7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZGF0YTogeyByZXBvcnQ6IFJlcG9ydCB9ID0gaW5qZWN0KE1BVF9ESUFMT0dfREFUQSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RpYWxvZ1JlZiA9IGluamVjdDxNYXREaWFsb2dSZWY8UmVwb3J0U2V0dGluZ3NDb21wb25lbnQsIFJlcG9ydFNldHRpbmdzUmVzdWx0Pj4oTWF0RGlhbG9nUmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfcmVwb3J0RGF0YSA9IGluamVjdChSZXBvcnREYXRhKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9wcm9tcHQgPSBpbmplY3QoRnNQcm9tcHQpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9kZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBjb25zdCByZXBvcnQgPSB0aGlzLl9kYXRhLnJlcG9ydDtcbiAgICB0aGlzLm5hbWUgPSByZXBvcnQubmFtZTtcbiAgICB0aGlzLnBhZ2VTaXplID0gcmVwb3J0LnBhZ2VTaXplO1xuICAgIHRoaXMucGFnZU9yaWVudGF0aW9uID0gcmVwb3J0LnBhZ2VPcmllbnRhdGlvbjtcbiAgICB0aGlzLmxheW91dCA9IHJlcG9ydC5sYXlvdXQgPz8gJ2ZyZWVmb3JtJztcbiAgICB0aGlzLnRpbWV6b25lID0gcmVwb3J0LnRpbWV6b25lID8/ICcnO1xuICAgIHRoaXMuaGVhZGluZ1NpemUgPSByZXBvcnQuY29uZmlnPy5zdHlsZXM/LmhlYWRpbmc/LnNpemUgPz8gREVGQVVMVF9IRUFESU5HX1NJWkU7XG4gIH1cblxuICAvLyBDb25maXJtIGFuZCBkZWxldGUgaGVyZSwgd2hpbGUgdGhlIGRpYWxvZyBpcyBzdGlsbCBvcGVuLCB0aGVuIGNsb3NlIHdpdGhcbiAgLy8gYSBgZGVsZXRlZGAgcmVzdWx0LiBUaGUgcGFnZSByZWFjdHMgdG8gdGhlIHJlc3VsdDsgaXQgbm8gbG9uZ2VyIG93bnMgdGhlXG4gIC8vIHByb21wdCBvciB0aGUgQVBJIGNhbGwuXG4gIHB1YmxpYyBkZWxldGUoKTogdm9pZCB7XG4gICAgdGhpcy5fcHJvbXB0LmNvbmZpcm0oe1xuICAgICAgdGl0bGU6ICdEZWxldGUgUmVwb3J0JyxcbiAgICAgIHRlbXBsYXRlOiBgRGVsZXRlIFwiJHt0aGlzLl9kYXRhLnJlcG9ydC5uYW1lfVwiPyBUaGlzIGNhbm5vdCBiZSB1bmRvbmUuYCxcbiAgICB9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLl9yZXBvcnREYXRhLmRlbGV0ZSh0aGlzLl9kYXRhLnJlcG9ydC5pZCkpLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZiksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdSZXBvcnQgZGVsZXRlZCcpO1xuICAgICAgICB0aGlzLl9kaWFsb2dSZWYuY2xvc2UoeyBhY3Rpb246ICdkZWxldGVkJyB9KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHNhdmUgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuX3JlcG9ydERhdGEudXBkYXRlKHRoaXMuX2RhdGEucmVwb3J0LmlkLCB7XG4gICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICBwYWdlU2l6ZTogdGhpcy5wYWdlU2l6ZSxcbiAgICAgIHBhZ2VPcmllbnRhdGlvbjogdGhpcy5wYWdlT3JpZW50YXRpb24sXG4gICAgICBsYXlvdXQ6IHRoaXMubGF5b3V0LFxuICAgICAgdGltZXpvbmU6IHRoaXMudGltZXpvbmUsXG4gICAgICBzdHlsZXM6IHsgaGVhZGluZzogeyBzaXplOiB0aGlzLmhlYWRpbmdTaXplIH0gfSxcbiAgICB9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRhcCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdSZXBvcnQgc2V0dGluZ3Mgc2F2ZWQnKTtcbiAgICAgICAgICB0aGlzLl9kaWFsb2dSZWYuY2xvc2UoeyBhY3Rpb246ICdzYXZlZCcgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgfTtcbn1cbiIsIjxmb3JtXG4gICAgZnNGb3JtXG4gICAgW3N1Ym1pdF09XCJzYXZlXCI+XG4gIDxmcy1kaWFsb2c+XG4gICAgPGgxIG1hdC1kaWFsb2ctdGl0bGU+XG4gICAgICBSZXBvcnQgU2V0dGluZ3NcbiAgICA8L2gxPlxuICAgIDxtYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICA8bWF0LXRhYi1ncm91cCBbKHNlbGVjdGVkKV09XCJzZWxlY3RlZFRhYlwiPlxuICAgICAgICA8bWF0LXRhYlxuICAgICAgICAgICAgbGFiZWw9XCJTZXR0aW5nc1wiXG4gICAgICAgICAgICBuYW1lPVwic2V0dGluZ3NcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtY29sdW1uIHRhYi1ib2R5XCI+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgTmFtZVxuICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm5hbWVcIlxuICAgICAgICAgICAgICAgIG5hbWU9XCJuYW1lXCJcbiAgICAgICAgICAgICAgICBbZnNGb3JtUmVxdWlyZWRdPVwidHJ1ZVwiPlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICBQYWdlIFNpemVcbiAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInBhZ2VTaXplXCJcbiAgICAgICAgICAgICAgICAgIG5hbWU9XCJwYWdlU2l6ZVwiPlxuICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwid2lkZXNjcmVlblwiPlxuICAgICAgICAgICAgICAgICAgV2lkZXNjcmVlbiAoMTMuMzNcIiDDlyA3LjVcIilcbiAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJsZXR0ZXJcIj5cbiAgICAgICAgICAgICAgICAgIExldHRlciAoMTFcIiDDlyA4LjVcIilcbiAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgT3JpZW50YXRpb25cbiAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInBhZ2VPcmllbnRhdGlvblwiXG4gICAgICAgICAgICAgICAgICBuYW1lPVwicGFnZU9yaWVudGF0aW9uXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJsYW5kc2NhcGVcIj5cbiAgICAgICAgICAgICAgICAgIExhbmRzY2FwZVxuICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cInBvcnRyYWl0XCI+XG4gICAgICAgICAgICAgICAgICBQb3J0cmFpdFxuICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICBMYXlvdXRcbiAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImxheW91dFwiXG4gICAgICAgICAgICAgICAgICBuYW1lPVwibGF5b3V0XCI+XG4gICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJmcmVlZm9ybVwiPlxuICAgICAgICAgICAgICAgICAgRnJlZWZvcm0g4oCUIHBvc2l0aW9uIGNvbXBvbmVudHMgYW55d2hlcmUgb24gdGhlIHBhZ2VcbiAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJmbG93XCI+XG4gICAgICAgICAgICAgICAgICBGbG93IOKAlCBjb21wb25lbnRzIGZsb3cgaW50byByb3dzIGJ5IHdpZHRoICVcbiAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgIEZyZWVmb3JtIGlzIGxpa2UgUG93ZXJQb2ludDsgRmxvdyBpcyBsaWtlIGEgcmVzcG9uc2l2ZSBkYXNoYm9hcmQuXG4gICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPGZzLWFpLXJlcG9ydC10aW1lem9uZS1zZWxlY3QgWyh0aW1lem9uZSldPVwidGltZXpvbmVcIj48L2ZzLWFpLXJlcG9ydC10aW1lem9uZS1zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgPG1hdC10YWJcbiAgICAgICAgICAgIGxhYmVsPVwiU3R5bGVzXCJcbiAgICAgICAgICAgIG5hbWU9XCJzdHlsZXNcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtY29sdW1uIHRhYi1ib2R5XCI+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgSGVhZGluZyBTaXplXG4gICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgIHN0ZXA9XCIxXCJcbiAgICAgICAgICAgICAgICBtaW49XCI2XCJcbiAgICAgICAgICAgICAgICBtYXg9XCI5NlwiXG4gICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJoZWFkaW5nU2l6ZVwiXG4gICAgICAgICAgICAgICAgbmFtZT1cImhlYWRpbmdTaXplXCJcbiAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cIjZcIlxuICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwiOTZcIj5cbiAgICAgICAgICAgICAgPHNwYW4gbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICBwdFxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICBBcHBsaWVzIHRvIGNvbXBvbmVudCB0aXRsZXMuIFBvaW50cyBtYXAgMToxIHRvIFBERiBhbmQgUG93ZXJQb2ludC5cbiAgICAgICAgICAgICAgPC9tYXQtaGludD5cbiAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbWF0LXRhYj5cbiAgICAgIDwvbWF0LXRhYi1ncm91cD5cbiAgICA8L21hdC1kaWFsb2ctY29udGVudD5cbiAgICA8bWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgICAgPGZzLWZvcm0tZGlhbG9nLWFjdGlvbnM+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICAgICAgY29sb3I9XCJ3YXJuXCJcbiAgICAgICAgICAgIChjbGljayk9XCJkZWxldGUoKVwiPlxuICAgICAgICAgIERlbGV0ZVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZnMtZm9ybS1kaWFsb2ctYWN0aW9ucz5cbiAgICA8L21hdC1kaWFsb2ctYWN0aW9ucz5cbiAgPC9mcy1kaWFsb2c+XG48L2Zvcm0+Il19
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { buildChartOption } from '../option-builder';
|
|
2
|
+
// Renders a chart to a PNG data URL WITHOUT it being on screen — the PDF
|
|
3
|
+
// export needs every page's charts, but the canvas only renders the active
|
|
4
|
+
// page. ECharts happily initializes against a detached element when given
|
|
5
|
+
// explicit pixel dimensions; animations are disabled so getDataURL is
|
|
6
|
+
// complete synchronously after setOption.
|
|
7
|
+
export async function renderChartImage(component, data, width, height, pixelRatio = 3) {
|
|
8
|
+
// The same tree-shaken echarts build + 'report' theme the live canvas uses.
|
|
9
|
+
const echarts = (await import('../theme/echarts')).default;
|
|
10
|
+
const host = document.createElement('div');
|
|
11
|
+
host.style.width = `${width}px`;
|
|
12
|
+
host.style.height = `${height}px`;
|
|
13
|
+
const chart = echarts.init(host, 'report', {
|
|
14
|
+
renderer: 'canvas',
|
|
15
|
+
width,
|
|
16
|
+
height,
|
|
17
|
+
});
|
|
18
|
+
try {
|
|
19
|
+
chart.setOption({
|
|
20
|
+
...buildChartOption(component, data),
|
|
21
|
+
animation: false,
|
|
22
|
+
});
|
|
23
|
+
return chart.getDataURL({
|
|
24
|
+
type: 'png',
|
|
25
|
+
pixelRatio,
|
|
26
|
+
backgroundColor: '#ffffff',
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
chart.dispose();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2Zmc2NyZWVuLWNoYXJ0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2V4cG9ydC9vZmZzY3JlZW4tY2hhcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHckQseUVBQXlFO0FBQ3pFLDJFQUEyRTtBQUMzRSwwRUFBMEU7QUFDMUUsc0VBQXNFO0FBQ3RFLDBDQUEwQztBQUMxQyxNQUFNLENBQUMsS0FBSyxVQUFVLGdCQUFnQixDQUNwQyxTQUEwQixFQUMxQixJQUFtQixFQUNuQixLQUFhLEVBQ2IsTUFBYyxFQUNkLFVBQVUsR0FBRyxDQUFDO0lBRWQsNEVBQTRFO0lBQzVFLE1BQU0sT0FBTyxHQUFHLENBQUMsTUFBTSxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztJQUUzRCxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEdBQUcsS0FBSyxJQUFJLENBQUM7SUFDaEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQztJQUVsQyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUU7UUFDekMsUUFBUSxFQUFFLFFBQVE7UUFDbEIsS0FBSztRQUNMLE1BQU07S0FDUCxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUM7UUFDSCxLQUFLLENBQUMsU0FBUyxDQUFDO1lBQ2QsR0FBRyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDO1lBQ3BDLFNBQVMsRUFBRSxLQUFLO1NBQ2pCLENBQUMsQ0FBQztRQUVILE9BQU8sS0FBSyxDQUFDLFVBQVUsQ0FBQztZQUN0QixJQUFJLEVBQUUsS0FBSztZQUNYLFVBQVU7WUFDVixlQUFlLEVBQUUsU0FBUztTQUMzQixDQUFDLENBQUM7SUFDTCxDQUFDO1lBQVMsQ0FBQztRQUNULEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNsQixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudERhdGEsIFJlcG9ydENvbXBvbmVudCB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5pbXBvcnQgeyBidWlsZENoYXJ0T3B0aW9uIH0gZnJvbSAnLi4vb3B0aW9uLWJ1aWxkZXInO1xuXG5cbi8vIFJlbmRlcnMgYSBjaGFydCB0byBhIFBORyBkYXRhIFVSTCBXSVRIT1VUIGl0IGJlaW5nIG9uIHNjcmVlbiDigJQgdGhlIFBERlxuLy8gZXhwb3J0IG5lZWRzIGV2ZXJ5IHBhZ2UncyBjaGFydHMsIGJ1dCB0aGUgY2FudmFzIG9ubHkgcmVuZGVycyB0aGUgYWN0aXZlXG4vLyBwYWdlLiBFQ2hhcnRzIGhhcHBpbHkgaW5pdGlhbGl6ZXMgYWdhaW5zdCBhIGRldGFjaGVkIGVsZW1lbnQgd2hlbiBnaXZlblxuLy8gZXhwbGljaXQgcGl4ZWwgZGltZW5zaW9uczsgYW5pbWF0aW9ucyBhcmUgZGlzYWJsZWQgc28gZ2V0RGF0YVVSTCBpc1xuLy8gY29tcGxldGUgc3luY2hyb25vdXNseSBhZnRlciBzZXRPcHRpb24uXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVuZGVyQ2hhcnRJbWFnZShcbiAgY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsXG4gIGRhdGE6IENvbXBvbmVudERhdGEsXG4gIHdpZHRoOiBudW1iZXIsXG4gIGhlaWdodDogbnVtYmVyLFxuICBwaXhlbFJhdGlvID0gMyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIC8vIFRoZSBzYW1lIHRyZWUtc2hha2VuIGVjaGFydHMgYnVpbGQgKyAncmVwb3J0JyB0aGVtZSB0aGUgbGl2ZSBjYW52YXMgdXNlcy5cbiAgY29uc3QgZWNoYXJ0cyA9IChhd2FpdCBpbXBvcnQoJy4uL3RoZW1lL2VjaGFydHMnKSkuZGVmYXVsdDtcblxuICBjb25zdCBob3N0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIGhvc3Quc3R5bGUud2lkdGggPSBgJHt3aWR0aH1weGA7XG4gIGhvc3Quc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YDtcblxuICBjb25zdCBjaGFydCA9IGVjaGFydHMuaW5pdChob3N0LCAncmVwb3J0Jywge1xuICAgIHJlbmRlcmVyOiAnY2FudmFzJyxcbiAgICB3aWR0aCxcbiAgICBoZWlnaHQsXG4gIH0pO1xuXG4gIHRyeSB7XG4gICAgY2hhcnQuc2V0T3B0aW9uKHtcbiAgICAgIC4uLmJ1aWxkQ2hhcnRPcHRpb24oY29tcG9uZW50LCBkYXRhKSxcbiAgICAgIGFuaW1hdGlvbjogZmFsc2UsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gY2hhcnQuZ2V0RGF0YVVSTCh7XG4gICAgICB0eXBlOiAncG5nJyxcbiAgICAgIHBpeGVsUmF0aW8sXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6ICcjZmZmZmZmJyxcbiAgICB9KTtcbiAgfSBmaW5hbGx5IHtcbiAgICBjaGFydC5kaXNwb3NlKCk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Injectable, inject } from '@angular/core';
|
|
2
|
+
import { forkJoin, map, of } from 'rxjs';
|
|
3
|
+
import { catchError } from 'rxjs/operators';
|
|
4
|
+
import { format } from 'date-fns';
|
|
5
|
+
import { ReportData } from '../data/report.data';
|
|
6
|
+
import { FREQUENCY_OPTIONS, } from '../interfaces/report.interface';
|
|
7
|
+
import { ReportFilterStateService } from '../services/report-filter-state.service';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
// Rows fetched for a list component's export table — enough to fill a
|
|
10
|
+
// slide/page table; the cap note covers the rest.
|
|
11
|
+
const LIST_EXPORT_ROWS = 100;
|
|
12
|
+
// Gathers everything an export needs: every component's data across ALL pages
|
|
13
|
+
// (the canvas only renders the active page, so exports can't scrape the
|
|
14
|
+
// screen), fetched fresh with the viewer's current filter state. One failed
|
|
15
|
+
// component degrades to a note in the deck, never a failed export.
|
|
16
|
+
export class ReportExportCollectorService {
|
|
17
|
+
_reportData = inject(ReportData);
|
|
18
|
+
_filterState = inject(ReportFilterStateService);
|
|
19
|
+
collect(report) {
|
|
20
|
+
const requests = [];
|
|
21
|
+
const slots = [];
|
|
22
|
+
report.pages.forEach((page, pageIndex) => {
|
|
23
|
+
for (const component of page.components) {
|
|
24
|
+
slots.push({ pageIndex });
|
|
25
|
+
requests.push(this._componentData(report, component));
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
const all$ = requests.length ? forkJoin(requests) : of([]);
|
|
29
|
+
return all$
|
|
30
|
+
.pipe(map((collected) => {
|
|
31
|
+
const pages = report.pages.map((page) => ({ page, components: [] }));
|
|
32
|
+
collected.forEach((item, index) => {
|
|
33
|
+
pages[slots[index].pageIndex].components.push(item);
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
report,
|
|
37
|
+
pages,
|
|
38
|
+
filterSummary: this._filterSummary(report),
|
|
39
|
+
};
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
_componentData(report, component) {
|
|
43
|
+
const filters = this._filterState.resolveForComponent(component);
|
|
44
|
+
// A time-series chart carries the viewer's Frequency override so the export
|
|
45
|
+
// re-buckets exactly as the screen does; lists carry their export paging.
|
|
46
|
+
const frequency = this._filterState.frequency();
|
|
47
|
+
const isTimeSeries = component.type === 'chart' && component.config?.xAxis?.kind === 'time';
|
|
48
|
+
const state = component.type === 'list'
|
|
49
|
+
? { page: 1, pageSize: LIST_EXPORT_ROWS }
|
|
50
|
+
: (isTimeSeries && frequency ? { frequency } : {});
|
|
51
|
+
return this._reportData.componentData(report.id, component.id, filters, state)
|
|
52
|
+
.pipe(map((data) => ({ component, data })), catchError(() => of({ component, data: null })));
|
|
53
|
+
}
|
|
54
|
+
// "Report Period: Jun 12, 2025 – Jun 12, 2026", "Organization: A, B" — one
|
|
55
|
+
// line per filter group that has an active session value.
|
|
56
|
+
_filterSummary(report) {
|
|
57
|
+
const lines = [];
|
|
58
|
+
for (const group of report.filterGroups ?? []) {
|
|
59
|
+
const value = this._filterState.value(group.id);
|
|
60
|
+
if (!value) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const label = group.label || 'Filter';
|
|
64
|
+
if (value.start || value.end) {
|
|
65
|
+
lines.push(`${label}: ${this._date(value.start)} – ${this._date(value.end)}`);
|
|
66
|
+
}
|
|
67
|
+
else if (value.values?.length) {
|
|
68
|
+
lines.push(`${label}: ${value.values.map((item) => String(item)).join(', ')}`);
|
|
69
|
+
}
|
|
70
|
+
else if (value.value?.trim()) {
|
|
71
|
+
lines.push(`${label}: "${value.value.trim()}"`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const frequency = this._filterState.frequency();
|
|
75
|
+
if (frequency) {
|
|
76
|
+
const option = FREQUENCY_OPTIONS.find((item) => item.value === frequency);
|
|
77
|
+
lines.push(`Frequency: ${option?.name ?? frequency}`);
|
|
78
|
+
}
|
|
79
|
+
return lines;
|
|
80
|
+
}
|
|
81
|
+
_date(value) {
|
|
82
|
+
if (!value) {
|
|
83
|
+
return '…';
|
|
84
|
+
}
|
|
85
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
86
|
+
return Number.isNaN(date.getTime()) ? String(value) : format(date, 'MMM d, yyyy');
|
|
87
|
+
}
|
|
88
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportExportCollectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
89
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportExportCollectorService });
|
|
90
|
+
}
|
|
91
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportExportCollectorService, decorators: [{
|
|
92
|
+
type: Injectable
|
|
93
|
+
}] });
|
|
94
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWV4cG9ydC1jb2xsZWN0b3Iuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9leHBvcnQvcmVwb3J0LWV4cG9ydC1jb2xsZWN0b3Iuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRCxPQUFPLEVBQWMsUUFBUSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDckQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTVDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFbEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pELE9BQU8sRUFFTCxpQkFBaUIsR0FJbEIsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN4QyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQzs7QUFvQm5GLHNFQUFzRTtBQUN0RSxrREFBa0Q7QUFDbEQsTUFBTSxnQkFBZ0IsR0FBRyxHQUFHLENBQUM7QUFFN0IsOEVBQThFO0FBQzlFLHdFQUF3RTtBQUN4RSw0RUFBNEU7QUFDNUUsbUVBQW1FO0FBRW5FLE1BQU0sT0FBTyw0QkFBNEI7SUFFL0IsV0FBVyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNqQyxZQUFZLEdBQUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFFakQsT0FBTyxDQUFDLE1BQWM7UUFDM0IsTUFBTSxRQUFRLEdBQXFDLEVBQUUsQ0FBQztRQUN0RCxNQUFNLEtBQUssR0FBNEIsRUFBRSxDQUFDO1FBRTFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxFQUFFO1lBQ3ZDLEtBQUssTUFBTSxT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RUFBRSxJQUFJLElBQUksU0FBUyxFQUFFLENBQUMsQ0FBQztRQUN4RCxDQUFDO1FBRUQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRU8sS0FBSyxDQUFDLEtBQXVDO1FBQ25ELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sR0FBRyxDQUFDO1FBQ2IsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLEtBQUssWUFBWSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFN0QsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDcEYsQ0FBQzt3R0EzRlUsNEJBQTRCOzRHQUE1Qiw0QkFBNEI7OzRGQUE1Qiw0QkFBNEI7a0JBRHhDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgZm9ya0pvaW4sIG1hcCwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGNhdGNoRXJyb3IgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IGZvcm1hdCB9IGZyb20gJ2RhdGUtZm5zJztcblxuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50RGF0YSxcbiAgRlJFUVVFTkNZX09QVElPTlMsXG4gIFJlcG9ydCxcbiAgUmVwb3J0Q29tcG9uZW50LFxuICBSZXBvcnRQYWdlLFxufSBmcm9tICcuLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvcmVwb3J0LWZpbHRlci1zdGF0ZS5zZXJ2aWNlJztcblxuXG5leHBvcnQgaW50ZXJmYWNlIENvbGxlY3RlZENvbXBvbmVudCB7XG4gIGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50O1xuICBkYXRhOiBDb21wb25lbnREYXRhIHwgbnVsbDsgLy8gbnVsbCA9IGl0cyBxdWVyeSBmYWlsZWQ7IGV4cG9ydHMgc2hvdyBhIG5vdGVcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb2xsZWN0ZWRQYWdlIHtcbiAgcGFnZTogUmVwb3J0UGFnZTtcbiAgY29tcG9uZW50czogQ29sbGVjdGVkQ29tcG9uZW50W107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29sbGVjdGVkUmVwb3J0IHtcbiAgcmVwb3J0OiBSZXBvcnQ7XG4gIHBhZ2VzOiBDb2xsZWN0ZWRQYWdlW107XG4gIC8vIEh1bWFuLXJlYWRhYmxlIGxpbmVzIGRlc2NyaWJpbmcgdGhlIGFjdGl2ZSBmaWx0ZXJzLCBmb3IgdGhlIHRpdGxlIHNsaWRlL3BhZ2UuXG4gIGZpbHRlclN1bW1hcnk6IHN0cmluZ1tdO1xufVxuXG4vLyBSb3dzIGZldGNoZWQgZm9yIGEgbGlzdCBjb21wb25lbnQncyBleHBvcnQgdGFibGUg4oCUIGVub3VnaCB0byBmaWxsIGFcbi8vIHNsaWRlL3BhZ2UgdGFibGU7IHRoZSBjYXAgbm90ZSBjb3ZlcnMgdGhlIHJlc3QuXG5jb25zdCBMSVNUX0VYUE9SVF9ST1dTID0gMTAwO1xuXG4vLyBHYXRoZXJzIGV2ZXJ5dGhpbmcgYW4gZXhwb3J0IG5lZWRzOiBldmVyeSBjb21wb25lbnQncyBkYXRhIGFjcm9zcyBBTEwgcGFnZXNcbi8vICh0aGUgY2FudmFzIG9ubHkgcmVuZGVycyB0aGUgYWN0aXZlIHBhZ2UsIHNvIGV4cG9ydHMgY2FuJ3Qgc2NyYXBlIHRoZVxuLy8gc2NyZWVuKSwgZmV0Y2hlZCBmcmVzaCB3aXRoIHRoZSB2aWV3ZXIncyBjdXJyZW50IGZpbHRlciBzdGF0ZS4gT25lIGZhaWxlZFxuLy8gY29tcG9uZW50IGRlZ3JhZGVzIHRvIGEgbm90ZSBpbiB0aGUgZGVjaywgbmV2ZXIgYSBmYWlsZWQgZXhwb3J0LlxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFJlcG9ydEV4cG9ydENvbGxlY3RvclNlcnZpY2Uge1xuXG4gIHByaXZhdGUgX3JlcG9ydERhdGEgPSBpbmplY3QoUmVwb3J0RGF0YSk7XG4gIHByaXZhdGUgX2ZpbHRlclN0YXRlID0gaW5qZWN0KFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSk7XG5cbiAgcHVibGljIGNvbGxlY3QocmVwb3J0OiBSZXBvcnQpOiBPYnNlcnZhYmxlPENvbGxlY3RlZFJlcG9ydD4ge1xuICAgIGNvbnN0IHJlcXVlc3RzOiBPYnNlcnZhYmxlPENvbGxlY3RlZENvbXBvbmVudD5bXSA9IFtdO1xuICAgIGNvbnN0IHNsb3RzOiB7IHBhZ2VJbmRleDogbnVtYmVyIH1bXSA9IFtdO1xuXG4gICAgcmVwb3J0LnBhZ2VzLmZvckVhY2goKHBhZ2UsIHBhZ2VJbmRleCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGFnZS5jb21wb25lbnRzKSB7XG4gICAgICAgIHNsb3RzLnB1c2goeyBwYWdlSW5kZXggfSk7XG4gICAgICAgIHJlcXVlc3RzLnB1c2godGhpcy5fY29tcG9uZW50RGF0YShyZXBvcnQsIGNvbXBvbmVudCkpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgYWxsJCA9IHJlcXVlc3RzLmxlbmd0aCA/IGZvcmtKb2luKHJlcXVlc3RzKSA6IG9mKFtdIGFzIENvbGxlY3RlZENvbXBvbmVudFtdKTtcblxuICAgIHJldHVybiBhbGwkXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKChjb2xsZWN0ZWQpID0+IHtcbiAgICAgICAgICBjb25zdCBwYWdlczogQ29sbGVjdGVkUGFnZVtdID0gcmVwb3J0LnBhZ2VzLm1hcCgocGFnZSkgPT4gKHsgcGFnZSwgY29tcG9uZW50czogW10gfSkpO1xuICAgICAgICAgIGNvbGxlY3RlZC5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgcGFnZXNbc2xvdHNbaW5kZXhdLnBhZ2VJbmRleF0uY29tcG9uZW50cy5wdXNoKGl0ZW0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlcG9ydCxcbiAgICAgICAgICAgIHBhZ2VzLFxuICAgICAgICAgICAgZmlsdGVyU3VtbWFyeTogdGhpcy5fZmlsdGVyU3VtbWFyeShyZXBvcnQpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbXBvbmVudERhdGEocmVwb3J0OiBSZXBvcnQsIGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50KTogT2JzZXJ2YWJsZTxDb2xsZWN0ZWRDb21wb25lbnQ+IHtcbiAgICBjb25zdCBmaWx0ZXJzID0gdGhpcy5fZmlsdGVyU3RhdGUucmVzb2x2ZUZvckNvbXBvbmVudChjb21wb25lbnQpO1xuICAgIC8vIEEgdGltZS1zZXJpZXMgY2hhcnQgY2FycmllcyB0aGUgdmlld2VyJ3MgRnJlcXVlbmN5IG92ZXJyaWRlIHNvIHRoZSBleHBvcnRcbiAgICAvLyByZS1idWNrZXRzIGV4YWN0bHkgYXMgdGhlIHNjcmVlbiBkb2VzOyBsaXN0cyBjYXJyeSB0aGVpciBleHBvcnQgcGFnaW5nLlxuICAgIGNvbnN0IGZyZXF1ZW5jeSA9IHRoaXMuX2ZpbHRlclN0YXRlLmZyZXF1ZW5jeSgpO1xuICAgIGNvbnN0IGlzVGltZVNlcmllcyA9IGNvbXBvbmVudC50eXBlID09PSAnY2hhcnQnICYmIGNvbXBvbmVudC5jb25maWc/LnhBeGlzPy5raW5kID09PSAndGltZSc7XG4gICAgY29uc3Qgc3RhdGUgPSBjb21wb25lbnQudHlwZSA9PT0gJ2xpc3QnXG4gICAgICA/IHsgcGFnZTogMSwgcGFnZVNpemU6IExJU1RfRVhQT1JUX1JPV1MgfVxuICAgICAgOiAoaXNUaW1lU2VyaWVzICYmIGZyZXF1ZW5jeSA/IHsgZnJlcXVlbmN5IH0gOiB7fSk7XG5cbiAgICByZXR1cm4gdGhpcy5fcmVwb3J0RGF0YS5jb21wb25lbnREYXRhKHJlcG9ydC5pZCwgY29tcG9uZW50LmlkLCBmaWx0ZXJzLCBzdGF0ZSlcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAoKGRhdGE6IENvbXBvbmVudERhdGEpID0+ICh7IGNvbXBvbmVudCwgZGF0YSB9KSksXG4gICAgICAgIGNhdGNoRXJyb3IoKCkgPT4gb2YoeyBjb21wb25lbnQsIGRhdGE6IG51bGwgfSkpLFxuICAgICAgKTtcbiAgfVxuXG4gIC8vIFwiUmVwb3J0IFBlcmlvZDogSnVuIDEyLCAyMDI1IOKAkyBKdW4gMTIsIDIwMjZcIiwgXCJPcmdhbml6YXRpb246IEEsIEJcIiDigJQgb25lXG4gIC8vIGxpbmUgcGVyIGZpbHRlciBncm91cCB0aGF0IGhhcyBhbiBhY3RpdmUgc2Vzc2lvbiB2YWx1ZS5cbiAgcHJpdmF0ZSBfZmlsdGVyU3VtbWFyeShyZXBvcnQ6IFJlcG9ydCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgcmVwb3J0LmZpbHRlckdyb3VwcyA/PyBbXSkge1xuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLl9maWx0ZXJTdGF0ZS52YWx1ZShncm91cC5pZCk7XG4gICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBsYWJlbCA9IGdyb3VwLmxhYmVsIHx8ICdGaWx0ZXInO1xuXG4gICAgICBpZiAodmFsdWUuc3RhcnQgfHwgdmFsdWUuZW5kKSB7XG4gICAgICAgIGxpbmVzLnB1c2goYCR7bGFiZWx9OiAke3RoaXMuX2RhdGUodmFsdWUuc3RhcnQpfSDigJMgJHt0aGlzLl9kYXRlKHZhbHVlLmVuZCl9YCk7XG4gICAgICB9IGVsc2UgaWYgKHZhbHVlLnZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICAgIGxpbmVzLnB1c2goYCR7bGFiZWx9OiAke3ZhbHVlLnZhbHVlcy5tYXAoKGl0ZW0pID0+IFN0cmluZyhpdGVtKSkuam9pbignLCAnKX1gKTtcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUudmFsdWU/LnRyaW0oKSkge1xuICAgICAgICBsaW5lcy5wdXNoKGAke2xhYmVsfTogXCIke3ZhbHVlLnZhbHVlLnRyaW0oKX1cImApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGZyZXF1ZW5jeSA9IHRoaXMuX2ZpbHRlclN0YXRlLmZyZXF1ZW5jeSgpO1xuICAgIGlmIChmcmVxdWVuY3kpIHtcbiAgICAgIGNvbnN0IG9wdGlvbiA9IEZSRVFVRU5DWV9PUFRJT05TLmZpbmQoKGl0ZW0pID0+IGl0ZW0udmFsdWUgPT09IGZyZXF1ZW5jeSk7XG4gICAgICBsaW5lcy5wdXNoKGBGcmVxdWVuY3k6ICR7b3B0aW9uPy5uYW1lID8/IGZyZXF1ZW5jeX1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbGluZXM7XG4gIH1cblxuICBwcml2YXRlIF9kYXRlKHZhbHVlOiBEYXRlIHwgc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgcmV0dXJuICfigKYnO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGUgPSB2YWx1ZSBpbnN0YW5jZW9mIERhdGUgPyB2YWx1ZSA6IG5ldyBEYXRlKHZhbHVlKTtcblxuICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0ZS5nZXRUaW1lKCkpID8gU3RyaW5nKHZhbHVlKSA6IGZvcm1hdChkYXRlLCAnTU1NIGQsIHl5eXknKTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { format } from 'date-fns';
|
|
3
|
+
import { formatMeasureValue } from '../format';
|
|
4
|
+
import { pageGeometry } from '../layout';
|
|
5
|
+
import { renderChartImage } from './offscreen-chart';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
// Inches → points (the PDF unit).
|
|
8
|
+
const PT = 72;
|
|
9
|
+
// Component title strip height, points.
|
|
10
|
+
const TITLE_H = 18;
|
|
11
|
+
// Approximate table row height, points — drives the rows-that-fit cap.
|
|
12
|
+
const TABLE_ROW_H = 16;
|
|
13
|
+
// Builds the PDF client-side with jspdf. The report's unit is inches and PDFs
|
|
14
|
+
// are points at exactly 72/inch, so each report page becomes one PDF page of
|
|
15
|
+
// the exact physical size and components land at their precise positions.
|
|
16
|
+
// Charts are rendered through an offscreen ECharts instance at 3× pixel
|
|
17
|
+
// ratio — pixel-identical to the screen, crisp at print size — and tables are
|
|
18
|
+
// drawn with jspdf-autotable. Both libraries load lazily into their own chunks.
|
|
19
|
+
export class ReportPdfService {
|
|
20
|
+
async export(collected) {
|
|
21
|
+
const { jsPDF } = await import('jspdf');
|
|
22
|
+
const autoTable = (await import('jspdf-autotable')).default;
|
|
23
|
+
const report = collected.report;
|
|
24
|
+
const pageW = report.pageWidth * PT;
|
|
25
|
+
const pageH = report.pageHeight * PT;
|
|
26
|
+
const doc = new jsPDF({
|
|
27
|
+
orientation: pageW >= pageH ? 'landscape' : 'portrait',
|
|
28
|
+
unit: 'pt',
|
|
29
|
+
format: [pageW, pageH],
|
|
30
|
+
});
|
|
31
|
+
this._titlePage(doc, collected, pageW, pageH);
|
|
32
|
+
for (const collectedPage of collected.pages) {
|
|
33
|
+
doc.addPage([pageW, pageH], pageW >= pageH ? 'landscape' : 'portrait');
|
|
34
|
+
const geometry = pageGeometry(report, collectedPage.page);
|
|
35
|
+
for (const item of collectedPage.components) {
|
|
36
|
+
await this._renderComponent(doc, autoTable, item, geometry.get(item.component.id));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
doc.save(`${this._slug(report.name)}.pdf`);
|
|
40
|
+
}
|
|
41
|
+
_titlePage(doc, collected, pageW, pageH) {
|
|
42
|
+
doc.setFont('helvetica', 'bold');
|
|
43
|
+
doc.setFontSize(28);
|
|
44
|
+
doc.setTextColor('#1f2933');
|
|
45
|
+
doc.text(collected.report.name, 40, pageH * 0.35);
|
|
46
|
+
doc.setFont('helvetica', 'normal');
|
|
47
|
+
doc.setFontSize(11);
|
|
48
|
+
doc.setTextColor('#52606d');
|
|
49
|
+
const lines = [
|
|
50
|
+
format(new Date(), 'MMMM d, yyyy'),
|
|
51
|
+
...collected.filterSummary,
|
|
52
|
+
];
|
|
53
|
+
doc.text(lines, 40, pageH * 0.35 + 26);
|
|
54
|
+
}
|
|
55
|
+
async _renderComponent(doc, autoTable, item, geometry) {
|
|
56
|
+
const component = item.component;
|
|
57
|
+
// Geometry arrives in inches (flow layout pre-resolved); the PDF draws in
|
|
58
|
+
// points.
|
|
59
|
+
const inches = geometry ?? component;
|
|
60
|
+
const x = inches.x * PT;
|
|
61
|
+
const y = inches.y * PT;
|
|
62
|
+
const w = inches.w * PT;
|
|
63
|
+
const h = inches.h * PT;
|
|
64
|
+
if (component.title) {
|
|
65
|
+
doc.setFont('helvetica', 'bold');
|
|
66
|
+
doc.setFontSize(9);
|
|
67
|
+
doc.setTextColor('#1f2933');
|
|
68
|
+
doc.text(component.title, x, y + 10, { maxWidth: w });
|
|
69
|
+
}
|
|
70
|
+
const bodyY = y + TITLE_H;
|
|
71
|
+
const bodyH = Math.max(20, h - TITLE_H);
|
|
72
|
+
if (!item.data || !item.data.rows?.length) {
|
|
73
|
+
doc.setFont('helvetica', 'italic');
|
|
74
|
+
doc.setFontSize(9);
|
|
75
|
+
doc.setTextColor('#7b8794');
|
|
76
|
+
doc.text(item.data ? 'No data' : 'Data unavailable', x + w / 2, bodyY + bodyH / 2, { align: 'center' });
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
switch (component.type) {
|
|
80
|
+
case 'chart': {
|
|
81
|
+
const image = await renderChartImage(component, item.data, w, bodyH);
|
|
82
|
+
doc.addImage(image, 'PNG', x, bodyY, w, bodyH);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
case 'list':
|
|
86
|
+
this._renderTable(doc, autoTable, component, item.data, x, bodyY, w, bodyH);
|
|
87
|
+
break;
|
|
88
|
+
case 'kpi':
|
|
89
|
+
this._renderKpi(doc, component, item.data, x, bodyY, w, bodyH);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
_renderTable(doc, autoTable, component, data, x, y, w, h) {
|
|
94
|
+
const config = component.config;
|
|
95
|
+
const columns = config.columns?.length
|
|
96
|
+
? config.columns
|
|
97
|
+
: data.columns.map((column) => ({ column, label: column }));
|
|
98
|
+
const cap = Math.max(2, Math.floor(h / TABLE_ROW_H) - 1);
|
|
99
|
+
const rows = data.rows.slice(0, cap);
|
|
100
|
+
const remaining = (data.paging?.total ?? data.rows.length) - rows.length;
|
|
101
|
+
const body = rows.map((row) => columns.map((column) => this._cell(row[column.column], column.format)));
|
|
102
|
+
if (remaining > 0) {
|
|
103
|
+
body.push([`… ${remaining} more row(s) — use the component's CSV export for the full dataset`]);
|
|
104
|
+
}
|
|
105
|
+
autoTable(doc, {
|
|
106
|
+
head: [columns.map((column) => column.label || column.column)],
|
|
107
|
+
body,
|
|
108
|
+
startY: y,
|
|
109
|
+
margin: { left: x },
|
|
110
|
+
tableWidth: w,
|
|
111
|
+
styles: { fontSize: 8, cellPadding: 3, textColor: '#1f2933' },
|
|
112
|
+
headStyles: { fillColor: '#4e79a7', textColor: '#ffffff', fontStyle: 'bold' },
|
|
113
|
+
alternateRowStyles: { fillColor: '#f5f7fa' },
|
|
114
|
+
theme: 'grid',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
_renderKpi(doc, component, data, x, y, w, h) {
|
|
118
|
+
const config = component.config;
|
|
119
|
+
const row = data.rows[0] ?? {};
|
|
120
|
+
const column = config.measure?.column ?? Object.keys(row)[0];
|
|
121
|
+
const value = formatMeasureValue(row[column], config.measure?.format);
|
|
122
|
+
doc.setFont('helvetica', 'bold');
|
|
123
|
+
doc.setFontSize(26);
|
|
124
|
+
doc.setTextColor('#1f2933');
|
|
125
|
+
doc.text(value, x + w / 2, y + h / 2, { align: 'center' });
|
|
126
|
+
if (config.measure?.label) {
|
|
127
|
+
doc.setFont('helvetica', 'normal');
|
|
128
|
+
doc.setFontSize(9);
|
|
129
|
+
doc.setTextColor('#7b8794');
|
|
130
|
+
doc.text(config.measure.label, x + w / 2, y + h / 2 + 16, { align: 'center' });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
_cell(value, columnFormat) {
|
|
134
|
+
if (value === null || value === undefined) {
|
|
135
|
+
return '';
|
|
136
|
+
}
|
|
137
|
+
if (columnFormat === 'date') {
|
|
138
|
+
const date = new Date(String(value));
|
|
139
|
+
return Number.isNaN(date.getTime()) ? String(value) : format(date, 'MMM d, yyyy');
|
|
140
|
+
}
|
|
141
|
+
if (columnFormat === 'number') {
|
|
142
|
+
return formatMeasureValue(value, 'number');
|
|
143
|
+
}
|
|
144
|
+
return String(value);
|
|
145
|
+
}
|
|
146
|
+
_slug(name) {
|
|
147
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'report';
|
|
148
|
+
}
|
|
149
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportPdfService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
150
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportPdfService });
|
|
151
|
+
}
|
|
152
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportPdfService, decorators: [{
|
|
153
|
+
type: Injectable
|
|
154
|
+
}] });
|
|
155
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXBkZi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2V4cG9ydC9yZXBvcnQtcGRmLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRWxDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQU8vQyxPQUFPLEVBQXFCLFlBQVksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUM1RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7QUFJckQsa0NBQWtDO0FBQ2xDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUVkLHdDQUF3QztBQUN4QyxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUM7QUFDbkIsdUVBQXVFO0FBQ3ZFLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQztBQUV2Qiw4RUFBOEU7QUFDOUUsNkVBQTZFO0FBQzdFLDBFQUEwRTtBQUMxRSx3RUFBd0U7QUFDeEUsOEVBQThFO0FBQzlFLGdGQUFnRjtBQUVoRixNQUFNLE9BQU8sZ0JBQWdCO0lBRXBCLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBMEI7UUFDNUMsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sU0FBUyxHQUFHLENBQUMsTUFBTSxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUU1RCxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO1FBQ2hDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO1FBQ3BDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxVQUFVLEdBQUcs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Qjs7NEZBQWhCLGdCQUFnQjtrQkFENUIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgZm9ybWF0IH0gZnJvbSAnZGF0ZS1mbnMnO1xuXG5pbXBvcnQgeyBmb3JtYXRNZWFzdXJlVmFsdWUgfSBmcm9tICcuLi9mb3JtYXQnO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50RGF0YSxcbiAgS3BpQ29uZmlnLFxuICBMaXN0Q29uZmlnLFxuICBSZXBvcnRDb21wb25lbnQsXG59IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7IC8vIENvbXBvbmVudERhdGEgdXNlZCBpbiBtZXRob2Qgc2lnbmF0dXJlcyBiZWxvd1xuaW1wb3J0IHsgQ29tcG9uZW50R2VvbWV0cnksIHBhZ2VHZW9tZXRyeSB9IGZyb20gJy4uL2xheW91dCc7XG5pbXBvcnQgeyByZW5kZXJDaGFydEltYWdlIH0gZnJvbSAnLi9vZmZzY3JlZW4tY2hhcnQnO1xuaW1wb3J0IHsgQ29sbGVjdGVkQ29tcG9uZW50LCBDb2xsZWN0ZWRSZXBvcnQgfSBmcm9tICcuL3JlcG9ydC1leHBvcnQtY29sbGVjdG9yLnNlcnZpY2UnO1xuXG5cbi8vIEluY2hlcyDihpIgcG9pbnRzICh0aGUgUERGIHVuaXQpLlxuY29uc3QgUFQgPSA3MjtcblxuLy8gQ29tcG9uZW50IHRpdGxlIHN0cmlwIGhlaWdodCwgcG9pbnRzLlxuY29uc3QgVElUTEVfSCA9IDE4O1xuLy8gQXBwcm94aW1hdGUgdGFibGUgcm93IGhlaWdodCwgcG9pbnRzIOKAlCBkcml2ZXMgdGhlIHJvd3MtdGhhdC1maXQgY2FwLlxuY29uc3QgVEFCTEVfUk9XX0ggPSAxNjtcblxuLy8gQnVpbGRzIHRoZSBQREYgY2xpZW50LXNpZGUgd2l0aCBqc3BkZi4gVGhlIHJlcG9ydCdzIHVuaXQgaXMgaW5jaGVzIGFuZCBQREZzXG4vLyBhcmUgcG9pbnRzIGF0IGV4YWN0bHkgNzIvaW5jaCwgc28gZWFjaCByZXBvcnQgcGFnZSBiZWNvbWVzIG9uZSBQREYgcGFnZSBvZlxuLy8gdGhlIGV4YWN0IHBoeXNpY2FsIHNpemUgYW5kIGNvbXBvbmVudHMgbGFuZCBhdCB0aGVpciBwcmVjaXNlIHBvc2l0aW9ucy5cbi8vIENoYXJ0cyBhcmUgcmVuZGVyZWQgdGhyb3VnaCBhbiBvZmZzY3JlZW4gRUNoYXJ0cyBpbnN0YW5jZSBhdCAzw5cgcGl4ZWxcbi8vIHJhdGlvIOKAlCBwaXhlbC1pZGVudGljYWwgdG8gdGhlIHNjcmVlbiwgY3Jpc3AgYXQgcHJpbnQgc2l6ZSDigJQgYW5kIHRhYmxlcyBhcmVcbi8vIGRyYXduIHdpdGgganNwZGYtYXV0b3RhYmxlLiBCb3RoIGxpYnJhcmllcyBsb2FkIGxhemlseSBpbnRvIHRoZWlyIG93biBjaHVua3MuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUmVwb3J0UGRmU2VydmljZSB7XG5cbiAgcHVibGljIGFzeW5jIGV4cG9ydChjb2xsZWN0ZWQ6IENvbGxlY3RlZFJlcG9ydCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsganNQREYgfSA9IGF3YWl0IGltcG9ydCgnanNwZGYnKTtcbiAgICBjb25zdCBhdXRvVGFibGUgPSAoYXdhaXQgaW1wb3J0KCdqc3BkZi1hdXRvdGFibGUnKSkuZGVmYXVsdDtcblxuICAgIGNvbnN0IHJlcG9ydCA9IGNvbGxlY3RlZC5yZXBvcnQ7XG4gICAgY29uc3QgcGFnZVcgPSByZXBvcnQucGFnZVdpZHRoICogUFQ7XG4gICAgY29uc3QgcGFnZUggPSByZXBvcnQucGFnZUhlaWdodCAqIFBUO1xuXG4gICAgY29uc3QgZG9jID0gbmV3IGpzUERGKHtcbiAgICAgIG9yaWVudGF0aW9uOiBwYWdlVyA+PSBwYWdlSCA/ICdsYW5kc2NhcGUnIDogJ3BvcnRyYWl0JyxcbiAgICAgIHVuaXQ6ICdwdCcsXG4gICAgICBmb3JtYXQ6IFtwYWdlVywgcGFnZUhdLFxuICAgIH0pO1xuXG4gICAgdGhpcy5fdGl0bGVQYWdlKGRvYywgY29sbGVjdGVkLCBwYWdlVywgcGFnZUgpO1xuXG4gICAgZm9yIChjb25zdCBjb2xsZWN0ZWRQYWdlIG9mIGNvbGxlY3RlZC5wYWdlcykge1xuICAgICAgZG9jLmFkZFBhZ2UoW3BhZ2VXLCBwYWdlSF0sIHBhZ2VXID49IHBhZ2VIID8gJ2xhbmRzY2FwZScgOiAncG9ydHJhaXQnKTtcbiAgICAgIGNvbnN0IGdlb21ldHJ5ID0gcGFnZUdlb21ldHJ5KHJlcG9ydCwgY29sbGVjdGVkUGFnZS5wYWdlKTtcblxuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGNvbGxlY3RlZFBhZ2UuY29tcG9uZW50cykge1xuICAgICAgICBhd2FpdCB0aGlzLl9yZW5kZXJDb21wb25lbnQoZG9jLCBhdXRvVGFibGUsIGl0ZW0sIGdlb21ldHJ5LmdldChpdGVtLmNvbXBvbmVudC5pZCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGRvYy5zYXZlKGAke3RoaXMuX3NsdWcocmVwb3J0Lm5hbWUpfS5wZGZgKTtcbiAgfVxuXG4gIHByaXZhdGUgX3RpdGxlUGFnZShkb2M6IGFueSwgY29sbGVjdGVkOiBDb2xsZWN0ZWRSZXBvcnQsIHBhZ2VXOiBudW1iZXIsIHBhZ2VIOiBudW1iZXIpOiB2b2lkIHtcbiAgICBkb2Muc2V0Rm9udCgnaGVsdmV0aWNhJywgJ2JvbGQnKTtcbiAgICBkb2Muc2V0Rm9udFNpemUoMjgpO1xuICAgIGRvYy5zZXRUZXh0Q29sb3IoJyMxZjI5MzMnKTtcbiAgICBkb2MudGV4dChjb2xsZWN0ZWQucmVwb3J0Lm5hbWUsIDQwLCBwYWdlSCAqIDAuMzUpO1xuXG4gICAgZG9jLnNldEZvbnQoJ2hlbHZldGljYScsICdub3JtYWwnKTtcbiAgICBkb2Muc2V0Rm9udFNpemUoMTEpO1xuICAgIGRvYy5zZXRUZXh0Q29sb3IoJyM1MjYwNmQnKTtcblxuICAgIGNvbnN0IGxpbmVzID0gW1xuICAgICAgZm9ybWF0KG5ldyBEYXRlKCksICdNTU1NIGQsIHl5eXknKSxcbiAgICAgIC4uLmNvbGxlY3RlZC5maWx0ZXJTdW1tYXJ5LFxuICAgIF07XG4gICAgZG9jLnRleHQobGluZXMsIDQwLCBwYWdlSCAqIDAuMzUgKyAyNik7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIF9yZW5kZXJDb21wb25lbnQoZG9jOiBhbnksIGF1dG9UYWJsZTogYW55LCBpdGVtOiBDb2xsZWN0ZWRDb21wb25lbnQsIGdlb21ldHJ5PzogQ29tcG9uZW50R2VvbWV0cnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjb21wb25lbnQgPSBpdGVtLmNvbXBvbmVudDtcbiAgICAvLyBHZW9tZXRyeSBhcnJpdmVzIGluIGluY2hlcyAoZmxvdyBsYXlvdXQgcHJlLXJlc29sdmVkKTsgdGhlIFBERiBkcmF3cyBpblxuICAgIC8vIHBvaW50cy5cbiAgICBjb25zdCBpbmNoZXMgPSBnZW9tZXRyeSA/PyBjb21wb25lbnQ7XG4gICAgY29uc3QgeCA9IGluY2hlcy54ICogUFQ7XG4gICAgY29uc3QgeSA9IGluY2hlcy55ICogUFQ7XG4gICAgY29uc3QgdyA9IGluY2hlcy53ICogUFQ7XG4gICAgY29uc3QgaCA9IGluY2hlcy5oICogUFQ7XG5cbiAgICBpZiAoY29tcG9uZW50LnRpdGxlKSB7XG4gICAgICBkb2Muc2V0Rm9udCgnaGVsdmV0aWNhJywgJ2JvbGQnKTtcbiAgICAgIGRvYy5zZXRGb250U2l6ZSg5KTtcbiAgICAgIGRvYy5zZXRUZXh0Q29sb3IoJyMxZjI5MzMnKTtcbiAgICAgIGRvYy50ZXh0KGNvbXBvbmVudC50aXRsZSwgeCwgeSArIDEwLCB7IG1heFdpZHRoOiB3IH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGJvZHlZID0geSArIFRJVExFX0g7XG4gICAgY29uc3QgYm9keUggPSBNYXRoLm1heCgyMCwgaCAtIFRJVExFX0gpO1xuXG4gICAgaWYgKCFpdGVtLmRhdGEgfHwgIWl0ZW0uZGF0YS5yb3dzPy5sZW5ndGgpIHtcbiAgICAgIGRvYy5zZXRGb250KCdoZWx2ZXRpY2EnLCAnaXRhbGljJyk7XG4gICAgICBkb2Muc2V0Rm9udFNpemUoOSk7XG4gICAgICBkb2Muc2V0VGV4dENvbG9yKCcjN2I4Nzk0Jyk7XG4gICAgICBkb2MudGV4dChpdGVtLmRhdGEgPyAnTm8gZGF0YScgOiAnRGF0YSB1bmF2YWlsYWJsZScsIHggKyB3IC8gMiwgYm9keVkgKyBib2R5SCAvIDIsIHsgYWxpZ246ICdjZW50ZXInIH0pO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3dpdGNoIChjb21wb25lbnQudHlwZSkge1xuICAgICAgY2FzZSAnY2hhcnQnOiB7XG4gICAgICAgIGNvbnN0IGltYWdlID0gYXdhaXQgcmVuZGVyQ2hhcnRJbWFnZShjb21wb25lbnQsIGl0ZW0uZGF0YSwgdywgYm9keUgpO1xuICAgICAgICBkb2MuYWRkSW1hZ2UoaW1hZ2UsICdQTkcnLCB4LCBib2R5WSwgdywgYm9keUgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2xpc3QnOlxuICAgICAgICB0aGlzLl9yZW5kZXJUYWJsZShkb2MsIGF1dG9UYWJsZSwgY29tcG9uZW50LCBpdGVtLmRhdGEsIHgsIGJvZHlZLCB3LCBib2R5SCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAna3BpJzpcbiAgICAgICAgdGhpcy5fcmVuZGVyS3BpKGRvYywgY29tcG9uZW50LCBpdGVtLmRhdGEsIHgsIGJvZHlZLCB3LCBib2R5SCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3JlbmRlclRhYmxlKFxuICAgIGRvYzogYW55LFxuICAgIGF1dG9UYWJsZTogYW55LFxuICAgIGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50LFxuICAgIGRhdGE6IENvbXBvbmVudERhdGEsXG4gICAgeDogbnVtYmVyLCB5OiBudW1iZXIsIHc6IG51bWJlciwgaDogbnVtYmVyLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBjb25maWcgPSBjb21wb25lbnQuY29uZmlnIGFzIExpc3RDb25maWc7XG4gICAgY29uc3QgY29sdW1ucyA9IGNvbmZpZy5jb2x1bW5zPy5sZW5ndGhcbiAgICAgID8gY29uZmlnLmNvbHVtbnNcbiAgICAgIDogZGF0YS5jb2x1bW5zLm1hcCgoY29sdW1uKSA9PiAoeyBjb2x1bW4sIGxhYmVsOiBjb2x1bW4gfSkpO1xuXG4gICAgY29uc3QgY2FwID0gTWF0aC5tYXgoMiwgTWF0aC5mbG9vcihoIC8gVEFCTEVfUk9XX0gpIC0gMSk7XG4gICAgY29uc3Qgcm93cyA9IGRhdGEucm93cy5zbGljZSgwLCBjYXApO1xuICAgIGNvbnN0IHJlbWFpbmluZyA9IChkYXRhLnBhZ2luZz8udG90YWwgPz8gZGF0YS5yb3dzLmxlbmd0aCkgLSByb3dzLmxlbmd0aDtcblxuICAgIGNvbnN0IGJvZHkgPSByb3dzLm1hcCgocm93KSA9PiBjb2x1bW5zLm1hcCgoY29sdW1uKSA9PiB0aGlzLl9jZWxsKHJvd1tjb2x1bW4uY29sdW1uXSwgY29sdW1uLmZvcm1hdCkpKTtcblxuICAgIGlmIChyZW1haW5pbmcgPiAwKSB7XG4gICAgICBib2R5LnB1c2goW2DigKYgJHtyZW1haW5pbmd9IG1vcmUgcm93KHMpIOKAlCB1c2UgdGhlIGNvbXBvbmVudCdzIENTViBleHBvcnQgZm9yIHRoZSBmdWxsIGRhdGFzZXRgXSk7XG4gICAgfVxuXG4gICAgYXV0b1RhYmxlKGRvYywge1xuICAgICAgaGVhZDogW2NvbHVtbnMubWFwKChjb2x1bW4pID0+IGNvbHVtbi5sYWJlbCB8fCBjb2x1bW4uY29sdW1uKV0sXG4gICAgICBib2R5LFxuICAgICAgc3RhcnRZOiB5LFxuICAgICAgbWFyZ2luOiB7IGxlZnQ6IHggfSxcbiAgICAgIHRhYmxlV2lkdGg6IHcsXG4gICAgICBzdHlsZXM6IHsgZm9udFNpemU6IDgsIGNlbGxQYWRkaW5nOiAzLCB0ZXh0Q29sb3I6ICcjMWYyOTMzJyB9LFxuICAgICAgaGVhZFN0eWxlczogeyBmaWxsQ29sb3I6ICcjNGU3OWE3JywgdGV4dENvbG9yOiAnI2ZmZmZmZicsIGZvbnRTdHlsZTogJ2JvbGQnIH0sXG4gICAgICBhbHRlcm5hdGVSb3dTdHlsZXM6IHsgZmlsbENvbG9yOiAnI2Y1ZjdmYScgfSxcbiAgICAgIHRoZW1lOiAnZ3JpZCcsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9yZW5kZXJLcGkoXG4gICAgZG9jOiBhbnksXG4gICAgY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsXG4gICAgZGF0YTogQ29tcG9uZW50RGF0YSxcbiAgICB4OiBudW1iZXIsIHk6IG51bWJlciwgdzogbnVtYmVyLCBoOiBudW1iZXIsXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IGNvbXBvbmVudC5jb25maWcgYXMgS3BpQ29uZmlnO1xuICAgIGNvbnN0IHJvdyA9IGRhdGEucm93c1swXSA/PyB7fTtcbiAgICBjb25zdCBjb2x1bW4gPSBjb25maWcubWVhc3VyZT8uY29sdW1uID8/IE9iamVjdC5rZXlzKHJvdylbMF07XG4gICAgY29uc3QgdmFsdWUgPSBmb3JtYXRNZWFzdXJlVmFsdWUocm93W2NvbHVtbl0sIGNvbmZpZy5tZWFzdXJlPy5mb3JtYXQpO1xuXG4gICAgZG9jLnNldEZvbnQoJ2hlbHZldGljYScsICdib2xkJyk7XG4gICAgZG9jLnNldEZvbnRTaXplKDI2KTtcbiAgICBkb2Muc2V0VGV4dENvbG9yKCcjMWYyOTMzJyk7XG4gICAgZG9jLnRleHQodmFsdWUsIHggKyB3IC8gMiwgeSArIGggLyAyLCB7IGFsaWduOiAnY2VudGVyJyB9KTtcblxuICAgIGlmIChjb25maWcubWVhc3VyZT8ubGFiZWwpIHtcbiAgICAgIGRvYy5zZXRGb250KCdoZWx2ZXRpY2EnLCAnbm9ybWFsJyk7XG4gICAgICBkb2Muc2V0Rm9udFNpemUoOSk7XG4gICAgICBkb2Muc2V0VGV4dENvbG9yKCcjN2I4Nzk0Jyk7XG4gICAgICBkb2MudGV4dChjb25maWcubWVhc3VyZS5sYWJlbCwgeCArIHcgLyAyLCB5ICsgaCAvIDIgKyAxNiwgeyBhbGlnbjogJ2NlbnRlcicgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfY2VsbCh2YWx1ZTogdW5rbm93biwgY29sdW1uRm9ybWF0Pzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIGlmIChjb2x1bW5Gb3JtYXQgPT09ICdkYXRlJykge1xuICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKFN0cmluZyh2YWx1ZSkpO1xuXG4gICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGUuZ2V0VGltZSgpKSA/IFN0cmluZyh2YWx1ZSkgOiBmb3JtYXQoZGF0ZSwgJ01NTSBkLCB5eXl5Jyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbHVtbkZvcm1hdCA9PT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVybiBmb3JtYXRNZWFzdXJlVmFsdWUodmFsdWUsICdudW1iZXInKTtcbiAgICB9XG5cbiAgICByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgX3NsdWcobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gbmFtZS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1teYS16MC05XSsvZywgJy0nKS5yZXBsYWNlKC9eLSt8LSskL2csICcnKSB8fCAncmVwb3J0JztcbiAgfVxufVxuIl19
|