@sumaris-net/ngx-components 18.6.10 → 18.6.11-alpha1
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/esm2022/public_api.mjs +2 -1
- package/esm2022/src/app/core/home/home.mjs +4 -1
- package/esm2022/src/app/shared/markdown/markdown.component.mjs +55 -81
- package/esm2022/src/app/shared/markdown/markdown.modal.mjs +17 -10
- package/esm2022/src/app/shared/markdown/markdown.utils.mjs +8 -1
- package/esm2022/src/app/shared/markdown/testing/markdown.test.mjs +16 -7
- package/esm2022/src/app/shared/print/print.service.mjs +257 -0
- package/esm2022/src/app/shared/toolbar/modal-toolbar.mjs +3 -3
- package/fesm2022/sumaris-net.ngx-components.mjs +339 -96
- package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +1 -0
- package/src/app/core/install/install-upgrade-card.component.d.ts +1 -1
- package/src/app/shared/markdown/markdown.component.d.ts +12 -7
- package/src/app/shared/markdown/markdown.modal.d.ts +9 -2
- package/src/app/shared/markdown/markdown.utils.d.ts +1 -0
- package/src/app/shared/markdown/testing/markdown.test.d.ts +4 -1
- package/src/app/shared/print/print.service.d.ts +60 -0
- package/src/assets/i18n/en-US.json +3 -2
- package/src/assets/i18n/en.json +2 -1
- package/src/assets/i18n/fr.json +2 -1
- package/src/assets/manifest.json +1 -1
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
1
|
+
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
|
2
2
|
import { AppMarkdownModal } from '../markdown.modal';
|
|
3
|
+
import { ENVIRONMENT } from '../../../../environments/environment.class';
|
|
3
4
|
import * as i0 from "@angular/core";
|
|
4
5
|
import * as i1 from "@ionic/angular";
|
|
5
6
|
import * as i2 from "@angular/forms";
|
|
6
7
|
import * as i3 from "../markdown.component";
|
|
7
8
|
import * as i4 from "@ngx-translate/core";
|
|
9
|
+
import * as i5 from "../../../../environments/environment.class";
|
|
8
10
|
export class MarkdownTestPage {
|
|
9
11
|
modalCtrl;
|
|
10
12
|
cd;
|
|
13
|
+
environment;
|
|
11
14
|
markdownModalTitle = 'Markdown modal';
|
|
15
|
+
debug;
|
|
12
16
|
// URL from a starting markdown
|
|
13
17
|
//protected markdownUrl = 'http://localhost:3000/user-manual/index.md';
|
|
14
18
|
markdownUrl = 'https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-doc/-/raw/master/projects/pifil/man/quick_start_guide_fr.md';
|
|
@@ -17,9 +21,11 @@ export class MarkdownTestPage {
|
|
|
17
21
|
//protected markdownUrl = 'https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-doc/-/raw/master/model/administration/index.md';
|
|
18
22
|
//protected markdownUrl ='https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-doc/-/raw/master/projects/activity-calendar/spe/collecte_de_donnees.md';
|
|
19
23
|
//protected markdownUrl ='https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-app/-/raw/develop/doc/privacy_policy.md';
|
|
20
|
-
constructor(modalCtrl, cd) {
|
|
24
|
+
constructor(modalCtrl, cd, environment) {
|
|
21
25
|
this.modalCtrl = modalCtrl;
|
|
22
26
|
this.cd = cd;
|
|
27
|
+
this.environment = environment;
|
|
28
|
+
this.debug = !environment.production;
|
|
23
29
|
}
|
|
24
30
|
onSubmit(event, newUrl) {
|
|
25
31
|
this.markdownUrl = '' + newUrl;
|
|
@@ -36,11 +42,14 @@ export class MarkdownTestPage {
|
|
|
36
42
|
canPrint: true,
|
|
37
43
|
});
|
|
38
44
|
}
|
|
39
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownTestPage, deps: [{ token: i1.ModalController }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
40
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: MarkdownTestPage, selector: "app-markdown-test", ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"primary\">\n <ion-buttons slot=\"start\">\n @if (content.canGoBack) {\n <ion-button class=\"back-button\" (click)=\"content.goBack($event)\" routerDirection=\"back\">\n <ion-icon slot=\"icon-only\" name=\"arrow-back\"></ion-icon>\n </ion-button>\n } @else {\n <ion-back-button></ion-back-button>\n }\n </ion-buttons>\n\n <ion-title>Markdown test page</ion-title>\n\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"openHelpModal($event)\">Open in modal</ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n <ion-input\n #input\n fill=\"outline\"\n [ngModel]=\"markdownUrl\"\n placeholder=\"Markdown URL\"\n label=\"URL: \"\n (keyup.enter)=\"onSubmit($event, input.value)\"\n >\n <ion-button\n slot=\"end\"\n [fill]=\"markdownUrl !== input.value ? 'solid' : 'clear'\"\n (click)=\"onSubmit($event, input.value)\"\n >\n {{ 'COMMON.BTN_OK' | translate }}\n </ion-button>\n </ion-input>\n\n <app-markdown-content\n #content\n [src]=\"markdownUrl\"\n enableNavigationHistory=\"true\"\n debug=\"
|
|
45
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownTestPage, deps: [{ token: i1.ModalController }, { token: i0.ChangeDetectorRef }, { token: ENVIRONMENT }], target: i0.ɵɵFactoryTarget.Component });
|
|
46
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: MarkdownTestPage, selector: "app-markdown-test", ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"primary\">\n <ion-buttons slot=\"start\">\n @if (content.canGoBack) {\n <ion-button class=\"back-button\" (click)=\"content.goBack($event)\" routerDirection=\"back\">\n <ion-icon slot=\"icon-only\" name=\"arrow-back\"></ion-icon>\n </ion-button>\n } @else {\n <ion-back-button></ion-back-button>\n }\n </ion-buttons>\n\n <ion-title>Markdown test page</ion-title>\n\n <ion-buttons slot=\"end\">\n <ion-button slot=\"end\" (click)=\"content.print()\">\n <ion-icon slot=\"icon-only\" name=\"print\"></ion-icon>\n </ion-button>\n\n <ion-button (click)=\"openHelpModal($event)\">Open in modal</ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n <ion-input\n #input\n fill=\"outline\"\n [ngModel]=\"markdownUrl\"\n placeholder=\"Markdown URL\"\n label=\"URL: \"\n (keyup.enter)=\"onSubmit($event, input.value)\"\n >\n <ion-button\n slot=\"end\"\n [fill]=\"markdownUrl !== input.value ? 'solid' : 'clear'\"\n (click)=\"onSubmit($event, input.value)\"\n >\n {{ 'COMMON.BTN_OK' | translate }}\n </ion-button>\n </ion-input>\n\n <app-markdown-content\n #content\n [src]=\"markdownUrl\"\n enableNavigationHistory=\"true\"\n [debug]=\"debug\"\n (markdownUrlChange)=\"updateInputUrl($event)\"\n ></app-markdown-content>\n</ion-content>\n", dependencies: [{ kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "legacy", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i1.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i1.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i1.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar,ion-range" }, { kind: "component", type: i1.IonBackButton, selector: "ion-back-button" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.AppMarkdownContent, selector: "app-markdown-content", inputs: ["data", "src", "anchor", "debug", "showError", "animated", "enableNavigationHistory", "updateRouteLocation"], outputs: ["markdownUrlChange"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
41
47
|
}
|
|
42
48
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownTestPage, decorators: [{
|
|
43
49
|
type: Component,
|
|
44
|
-
args: [{ selector: 'app-markdown-test', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-header>\n <ion-toolbar color=\"primary\">\n <ion-buttons slot=\"start\">\n @if (content.canGoBack) {\n <ion-button class=\"back-button\" (click)=\"content.goBack($event)\" routerDirection=\"back\">\n <ion-icon slot=\"icon-only\" name=\"arrow-back\"></ion-icon>\n </ion-button>\n } @else {\n <ion-back-button></ion-back-button>\n }\n </ion-buttons>\n\n <ion-title>Markdown test page</ion-title>\n\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"openHelpModal($event)\">Open in modal</ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n <ion-input\n #input\n fill=\"outline\"\n [ngModel]=\"markdownUrl\"\n placeholder=\"Markdown URL\"\n label=\"URL: \"\n (keyup.enter)=\"onSubmit($event, input.value)\"\n >\n <ion-button\n slot=\"end\"\n [fill]=\"markdownUrl !== input.value ? 'solid' : 'clear'\"\n (click)=\"onSubmit($event, input.value)\"\n >\n {{ 'COMMON.BTN_OK' | translate }}\n </ion-button>\n </ion-input>\n\n <app-markdown-content\n #content\n [src]=\"markdownUrl\"\n enableNavigationHistory=\"true\"\n debug=\"
|
|
45
|
-
}], ctorParameters: () => [{ type: i1.ModalController }, { type: i0.ChangeDetectorRef }
|
|
46
|
-
|
|
50
|
+
args: [{ selector: 'app-markdown-test', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-header>\n <ion-toolbar color=\"primary\">\n <ion-buttons slot=\"start\">\n @if (content.canGoBack) {\n <ion-button class=\"back-button\" (click)=\"content.goBack($event)\" routerDirection=\"back\">\n <ion-icon slot=\"icon-only\" name=\"arrow-back\"></ion-icon>\n </ion-button>\n } @else {\n <ion-back-button></ion-back-button>\n }\n </ion-buttons>\n\n <ion-title>Markdown test page</ion-title>\n\n <ion-buttons slot=\"end\">\n <ion-button slot=\"end\" (click)=\"content.print()\">\n <ion-icon slot=\"icon-only\" name=\"print\"></ion-icon>\n </ion-button>\n\n <ion-button (click)=\"openHelpModal($event)\">Open in modal</ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-padding\">\n <ion-input\n #input\n fill=\"outline\"\n [ngModel]=\"markdownUrl\"\n placeholder=\"Markdown URL\"\n label=\"URL: \"\n (keyup.enter)=\"onSubmit($event, input.value)\"\n >\n <ion-button\n slot=\"end\"\n [fill]=\"markdownUrl !== input.value ? 'solid' : 'clear'\"\n (click)=\"onSubmit($event, input.value)\"\n >\n {{ 'COMMON.BTN_OK' | translate }}\n </ion-button>\n </ion-input>\n\n <app-markdown-content\n #content\n [src]=\"markdownUrl\"\n enableNavigationHistory=\"true\"\n [debug]=\"debug\"\n (markdownUrlChange)=\"updateInputUrl($event)\"\n ></app-markdown-content>\n</ion-content>\n" }]
|
|
51
|
+
}], ctorParameters: () => [{ type: i1.ModalController }, { type: i0.ChangeDetectorRef }, { type: i5.Environment, decorators: [{
|
|
52
|
+
type: Inject,
|
|
53
|
+
args: [ENVIRONMENT]
|
|
54
|
+
}] }] });
|
|
55
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFya2Rvd24udGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL21hcmtkb3duL3Rlc3RpbmcvbWFya2Rvd24udGVzdC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL21hcmtkb3duL3Rlc3RpbmcvbWFya2Rvd24udGVzdC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBcUIsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM5RixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVyRCxPQUFPLEVBQWUsV0FBVyxFQUFFLE1BQU0sNENBQTRDLENBQUM7Ozs7Ozs7QUFPdEYsTUFBTSxPQUFPLGdCQUFnQjtJQWNqQjtJQUNBO0lBQ3VCO0lBZnZCLGtCQUFrQixHQUFHLGdCQUFnQixDQUFDO0lBQ3RDLEtBQUssQ0FBVTtJQUV6QiwrQkFBK0I7SUFDL0IsdUVBQXVFO0lBQzdELFdBQVcsR0FBRyxrSEFBa0gsQ0FBQztJQUMzSSw0R0FBNEc7SUFDNUcsaUhBQWlIO0lBQ2pILGdJQUFnSTtJQUNoSSx1SkFBdUo7SUFDdkosd0hBQXdIO0lBRXhILFlBQ1UsU0FBMEIsRUFDMUIsRUFBcUIsRUFDRSxXQUF3QjtRQUYvQyxjQUFTLEdBQVQsU0FBUyxDQUFpQjtRQUMxQixPQUFFLEdBQUYsRUFBRSxDQUFtQjtRQUNFLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBRXZELElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxRQUFRLENBQUMsS0FBWSxFQUFFLE1BQXVCO1FBQzVDLElBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQztRQUMvQixJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxjQUFjLENBQUMsR0FBVztRQUN4QixJQUFJLENBQUMsV0FBVyxHQUFHLEdBQUcsQ0FBQztRQUN2QixJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxhQUFhLENBQUMsS0FBWTtRQUN4QixPQUFPLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQzNDLEtBQUssRUFBRSxJQUFJLENBQUMsa0JBQWtCO1lBQzlCLEdBQUcsRUFBRSxJQUFJLENBQUMsV0FBVztZQUNyQixRQUFRLEVBQUUsSUFBSTtTQUNmLENBQUMsQ0FBQztJQUNMLENBQUM7d0dBckNVLGdCQUFnQixrRkFnQmpCLFdBQVc7NEZBaEJWLGdCQUFnQix5RENWN0IsdzdDQWtEQTs7NEZEeENhLGdCQUFnQjtrQkFMNUIsU0FBUzsrQkFDRSxtQkFBbUIsbUJBRVosdUJBQXVCLENBQUMsTUFBTTs7MEJBa0I1QyxNQUFNOzJCQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBcHBNYXJrZG93bk1vZGFsIH0gZnJvbSAnLi4vbWFya2Rvd24ubW9kYWwnO1xuaW1wb3J0IHsgTW9kYWxDb250cm9sbGVyIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXInO1xuaW1wb3J0IHsgRW52aXJvbm1lbnQsIEVOVklST05NRU5UIH0gZnJvbSAnLi4vLi4vLi4vLi4vZW52aXJvbm1lbnRzL2Vudmlyb25tZW50LmNsYXNzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLW1hcmtkb3duLXRlc3QnLFxuICB0ZW1wbGF0ZVVybDogJy4vbWFya2Rvd24udGVzdC5odG1sJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIE1hcmtkb3duVGVzdFBhZ2Uge1xuICBwcm90ZWN0ZWQgbWFya2Rvd25Nb2RhbFRpdGxlID0gJ01hcmtkb3duIG1vZGFsJztcbiAgcHJvdGVjdGVkIGRlYnVnOiBib29sZWFuO1xuXG4gIC8vIFVSTCBmcm9tIGEgc3RhcnRpbmcgbWFya2Rvd25cbiAgLy9wcm90ZWN0ZWQgbWFya2Rvd25VcmwgPSAnaHR0cDovL2xvY2FsaG9zdDozMDAwL3VzZXItbWFudWFsL2luZGV4Lm1kJztcbiAgcHJvdGVjdGVkIG1hcmtkb3duVXJsID0gJ2h0dHBzOi8vZ2l0bGFiLmlmcmVtZXIuZnIvc2loLXB1YmxpYy9zdW1hcmlzL3N1bWFyaXMtZG9jLy0vcmF3L21hc3Rlci9wcm9qZWN0cy9waWZpbC9tYW4vcXVpY2tfc3RhcnRfZ3VpZGVfZnIubWQnO1xuICAvL3Byb3RlY3RlZCBtYXJrZG93blVybCA9ICdodHRwczovL2dpdGxhYi5pZnJlbWVyLmZyL3NpaC1wdWJsaWMvc3VtYXJpcy9zdW1hcmlzLWRvYy8tL3Jhdy9tYXN0ZXIvUkVBRE1FLm1kJztcbiAgLy9wcm90ZWN0ZWQgbWFya2Rvd25VcmwgPSAnaHR0cHM6Ly9naXRsYWIuaWZyZW1lci5mci9zaWgtcHVibGljL3N1bWFyaXMvc3VtYXJpcy1kb2MvLS9yYXcvbWFzdGVyL21vZGVsL2luZGV4Lm1kJztcbiAgLy9wcm90ZWN0ZWQgbWFya2Rvd25VcmwgPSAnaHR0cHM6Ly9naXRsYWIuaWZyZW1lci5mci9zaWgtcHVibGljL3N1bWFyaXMvc3VtYXJpcy1kb2MvLS9yYXcvbWFzdGVyL21vZGVsL2FkbWluaXN0cmF0aW9uL2luZGV4Lm1kJztcbiAgLy9wcm90ZWN0ZWQgbWFya2Rvd25VcmwgPSdodHRwczovL2dpdGxhYi5pZnJlbWVyLmZyL3NpaC1wdWJsaWMvc3VtYXJpcy9zdW1hcmlzLWRvYy8tL3Jhdy9tYXN0ZXIvcHJvamVjdHMvYWN0aXZpdHktY2FsZW5kYXIvc3BlL2NvbGxlY3RlX2RlX2Rvbm5lZXMubWQnO1xuICAvL3Byb3RlY3RlZCBtYXJrZG93blVybCA9J2h0dHBzOi8vZ2l0bGFiLmlmcmVtZXIuZnIvc2loLXB1YmxpYy9zdW1hcmlzL3N1bWFyaXMtYXBwLy0vcmF3L2RldmVsb3AvZG9jL3ByaXZhY3lfcG9saWN5Lm1kJztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG1vZGFsQ3RybDogTW9kYWxDb250cm9sbGVyLFxuICAgIHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBJbmplY3QoRU5WSVJPTk1FTlQpIHByb3RlY3RlZCBlbnZpcm9ubWVudDogRW52aXJvbm1lbnRcbiAgKSB7XG4gICAgdGhpcy5kZWJ1ZyA9ICFlbnZpcm9ubWVudC5wcm9kdWN0aW9uO1xuICB9XG5cbiAgb25TdWJtaXQoZXZlbnQ6IEV2ZW50LCBuZXdVcmw6IHN0cmluZyB8IG51bWJlcikge1xuICAgIHRoaXMubWFya2Rvd25VcmwgPSAnJyArIG5ld1VybDtcbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgdXBkYXRlSW5wdXRVcmwodXJsOiBzdHJpbmcpIHtcbiAgICB0aGlzLm1hcmtkb3duVXJsID0gdXJsO1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBvcGVuSGVscE1vZGFsKGV2ZW50OiBFdmVudCkge1xuICAgIHJldHVybiBBcHBNYXJrZG93bk1vZGFsLnNob3codGhpcy5tb2RhbEN0cmwsIHtcbiAgICAgIHRpdGxlOiB0aGlzLm1hcmtkb3duTW9kYWxUaXRsZSxcbiAgICAgIHNyYzogdGhpcy5tYXJrZG93blVybCxcbiAgICAgIGNhblByaW50OiB0cnVlLFxuICAgIH0pO1xuICB9XG59XG4iLCI8aW9uLWhlYWRlcj5cbiAgPGlvbi10b29sYmFyIGNvbG9yPVwicHJpbWFyeVwiPlxuICAgIDxpb24tYnV0dG9ucyBzbG90PVwic3RhcnRcIj5cbiAgICAgIEBpZiAoY29udGVudC5jYW5Hb0JhY2spIHtcbiAgICAgICAgPGlvbi1idXR0b24gY2xhc3M9XCJiYWNrLWJ1dHRvblwiIChjbGljayk9XCJjb250ZW50LmdvQmFjaygkZXZlbnQpXCIgcm91dGVyRGlyZWN0aW9uPVwiYmFja1wiPlxuICAgICAgICAgIDxpb24taWNvbiBzbG90PVwiaWNvbi1vbmx5XCIgbmFtZT1cImFycm93LWJhY2tcIj48L2lvbi1pY29uPlxuICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICB9IEBlbHNlIHtcbiAgICAgICAgPGlvbi1iYWNrLWJ1dHRvbj48L2lvbi1iYWNrLWJ1dHRvbj5cbiAgICAgIH1cbiAgICA8L2lvbi1idXR0b25zPlxuXG4gICAgPGlvbi10aXRsZT5NYXJrZG93biB0ZXN0IHBhZ2U8L2lvbi10aXRsZT5cblxuICAgIDxpb24tYnV0dG9ucyBzbG90PVwiZW5kXCI+XG4gICAgICA8aW9uLWJ1dHRvbiBzbG90PVwiZW5kXCIgKGNsaWNrKT1cImNvbnRlbnQucHJpbnQoKVwiPlxuICAgICAgICA8aW9uLWljb24gc2xvdD1cImljb24tb25seVwiIG5hbWU9XCJwcmludFwiPjwvaW9uLWljb24+XG4gICAgICA8L2lvbi1idXR0b24+XG5cbiAgICAgIDxpb24tYnV0dG9uIChjbGljayk9XCJvcGVuSGVscE1vZGFsKCRldmVudClcIj5PcGVuIGluIG1vZGFsPC9pb24tYnV0dG9uPlxuICAgIDwvaW9uLWJ1dHRvbnM+XG4gIDwvaW9uLXRvb2xiYXI+XG48L2lvbi1oZWFkZXI+XG5cbjxpb24tY29udGVudCBjbGFzcz1cImlvbi1wYWRkaW5nXCI+XG4gIDxpb24taW5wdXRcbiAgICAjaW5wdXRcbiAgICBmaWxsPVwib3V0bGluZVwiXG4gICAgW25nTW9kZWxdPVwibWFya2Rvd25VcmxcIlxuICAgIHBsYWNlaG9sZGVyPVwiTWFya2Rvd24gVVJMXCJcbiAgICBsYWJlbD1cIlVSTDogXCJcbiAgICAoa2V5dXAuZW50ZXIpPVwib25TdWJtaXQoJGV2ZW50LCBpbnB1dC52YWx1ZSlcIlxuICA+XG4gICAgPGlvbi1idXR0b25cbiAgICAgIHNsb3Q9XCJlbmRcIlxuICAgICAgW2ZpbGxdPVwibWFya2Rvd25VcmwgIT09IGlucHV0LnZhbHVlID8gJ3NvbGlkJyA6ICdjbGVhcidcIlxuICAgICAgKGNsaWNrKT1cIm9uU3VibWl0KCRldmVudCwgaW5wdXQudmFsdWUpXCJcbiAgICA+XG4gICAgICB7eyAnQ09NTU9OLkJUTl9PSycgfCB0cmFuc2xhdGUgfX1cbiAgICA8L2lvbi1idXR0b24+XG4gIDwvaW9uLWlucHV0PlxuXG4gIDxhcHAtbWFya2Rvd24tY29udGVudFxuICAgICNjb250ZW50XG4gICAgW3NyY109XCJtYXJrZG93blVybFwiXG4gICAgZW5hYmxlTmF2aWdhdGlvbkhpc3Rvcnk9XCJ0cnVlXCJcbiAgICBbZGVidWddPVwiZGVidWdcIlxuICAgIChtYXJrZG93blVybENoYW5nZSk9XCJ1cGRhdGVJbnB1dFVybCgkZXZlbnQpXCJcbiAgPjwvYXBwLW1hcmtkb3duLWNvbnRlbnQ+XG48L2lvbi1jb250ZW50PlxuIl19
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { Toasts } from '../toast/toasts';
|
|
2
|
+
import { Inject, Injectable } from '@angular/core';
|
|
3
|
+
import { DOCUMENT } from '@angular/common';
|
|
4
|
+
import { isNil } from '../functions';
|
|
5
|
+
import { waitForTrue } from '../observables';
|
|
6
|
+
import { mergeMap, timer } from 'rxjs';
|
|
7
|
+
import { isChrome } from '../platforms';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "@ionic/angular";
|
|
10
|
+
import * as i2 from "@ngx-translate/core";
|
|
11
|
+
import * as i3 from "../storage/storage.service";
|
|
12
|
+
export const PRINT_LOADING_STORAGE_KEY_PREFIX = 'print-loading-';
|
|
13
|
+
export class PrintService {
|
|
14
|
+
toastController;
|
|
15
|
+
translate;
|
|
16
|
+
storage;
|
|
17
|
+
document;
|
|
18
|
+
printId = 0;
|
|
19
|
+
constructor(toastController, translate, storage, document) {
|
|
20
|
+
this.toastController = toastController;
|
|
21
|
+
this.translate = translate;
|
|
22
|
+
this.storage = storage;
|
|
23
|
+
this.document = document;
|
|
24
|
+
}
|
|
25
|
+
nextJobId() {
|
|
26
|
+
return ++this.printId;
|
|
27
|
+
}
|
|
28
|
+
async printElement(element, opts) {
|
|
29
|
+
if (!element)
|
|
30
|
+
throw new Error("Missing required 'element' argument");
|
|
31
|
+
return this.printHTML(element.innerHTML, opts);
|
|
32
|
+
}
|
|
33
|
+
async printHTML(html, opts) {
|
|
34
|
+
if (!html)
|
|
35
|
+
throw new Error("Missing required 'html' argument");
|
|
36
|
+
// Create iframe
|
|
37
|
+
const iframe = this.createPrintIframeByHtml(html, opts);
|
|
38
|
+
return this.printIframe(iframe, opts);
|
|
39
|
+
}
|
|
40
|
+
async printUrl(url, opts) {
|
|
41
|
+
if (!url)
|
|
42
|
+
throw new Error("Missing required 'url' argument");
|
|
43
|
+
// Create iframe
|
|
44
|
+
const iframe = this.createPrintIframeByUrl(url);
|
|
45
|
+
return this.printIframe(iframe, opts);
|
|
46
|
+
}
|
|
47
|
+
async printIframe(iframe, opts) {
|
|
48
|
+
if (!iframe)
|
|
49
|
+
throw new Error("Missing required 'iframe' argument");
|
|
50
|
+
const printId = opts?.id ?? this.printId++;
|
|
51
|
+
const toastId = `printing-${printId}`;
|
|
52
|
+
const showLoadingToast = opts?.showToast !== false;
|
|
53
|
+
if (showLoadingToast)
|
|
54
|
+
await this.showToast({
|
|
55
|
+
id: toastId,
|
|
56
|
+
message: opts?.toastMessage || 'COMMON.PLEASE_WAIT',
|
|
57
|
+
duration: 0,
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
// Wait end of iframe load
|
|
61
|
+
await this.waitIdle(iframe, { id: printId });
|
|
62
|
+
// Print (and wait end of print)
|
|
63
|
+
await this.print(iframe);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
console.error('[print-service] Failed to create hidden iframe', err);
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
iframe.remove();
|
|
70
|
+
if (showLoadingToast)
|
|
71
|
+
await this.toastController.dismiss(null, null, toastId);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async markAsLoading(id) {
|
|
75
|
+
console.debug(`[print-service] Mark print job #${id} as loading`);
|
|
76
|
+
await this.storage.set(PRINT_LOADING_STORAGE_KEY_PREFIX + id, '1');
|
|
77
|
+
}
|
|
78
|
+
async markAsLoaded(id) {
|
|
79
|
+
console.debug(`[print-service] Mark print job #${id} as loaded`);
|
|
80
|
+
await this.storage.remove(PRINT_LOADING_STORAGE_KEY_PREFIX + id);
|
|
81
|
+
}
|
|
82
|
+
async isLoaded(id) {
|
|
83
|
+
const result = await this.storage.get(PRINT_LOADING_STORAGE_KEY_PREFIX + id);
|
|
84
|
+
return isNil(result);
|
|
85
|
+
}
|
|
86
|
+
async isLoading(id) {
|
|
87
|
+
return !(await this.isLoaded(id));
|
|
88
|
+
}
|
|
89
|
+
/* -- protected functions -- */
|
|
90
|
+
createPrintIframeByUrl(url) {
|
|
91
|
+
// Create a iframe with '?print-pdf'
|
|
92
|
+
const iframe = this.document.createElement('iframe');
|
|
93
|
+
iframe.classList.add('cdk-visually-hidden');
|
|
94
|
+
iframe.style.width = '100%';
|
|
95
|
+
iframe.style.height = '100%';
|
|
96
|
+
this.document.body.appendChild(iframe);
|
|
97
|
+
iframe.src = url;
|
|
98
|
+
return iframe;
|
|
99
|
+
}
|
|
100
|
+
createPrintIframeByHtml(html, opts) {
|
|
101
|
+
if (!html)
|
|
102
|
+
throw new Error("Missing required 'html' argument");
|
|
103
|
+
const lang = this.document.documentElement?.lang || 'en';
|
|
104
|
+
// Create an empty iframe
|
|
105
|
+
const iframe = this.document.createElement('iframe');
|
|
106
|
+
iframe.classList.add('cdk-visually-hidden');
|
|
107
|
+
iframe.style.width = '100%';
|
|
108
|
+
iframe.style.height = '100%';
|
|
109
|
+
this.document.body.appendChild(iframe);
|
|
110
|
+
// Write iframe content
|
|
111
|
+
const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
|
|
112
|
+
if (iframeDocument) {
|
|
113
|
+
iframeDocument.open();
|
|
114
|
+
iframeDocument.write(`
|
|
115
|
+
<!DOCTYPE html>
|
|
116
|
+
<html lang="${lang}" class="print-pdf">
|
|
117
|
+
<head>
|
|
118
|
+
<title>${opts?.title || ''}</title>
|
|
119
|
+
<style>
|
|
120
|
+
@media print {
|
|
121
|
+
body {
|
|
122
|
+
font-family: 'Roboto', Helvetica, Arial, sans-serif;
|
|
123
|
+
margin: 0;
|
|
124
|
+
padding: 0;
|
|
125
|
+
overflow: hidden;
|
|
126
|
+
}
|
|
127
|
+
img {
|
|
128
|
+
max-width: 100%;
|
|
129
|
+
height: auto;
|
|
130
|
+
page-break-inside: avoid;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
${opts?.inlineStyle || ''}
|
|
134
|
+
</style>
|
|
135
|
+
</head>
|
|
136
|
+
<body>
|
|
137
|
+
${html}
|
|
138
|
+
</body>
|
|
139
|
+
</html>
|
|
140
|
+
`);
|
|
141
|
+
iframeDocument.close();
|
|
142
|
+
}
|
|
143
|
+
// Set iframe style
|
|
144
|
+
this.applyDocumentStyleToIframe(iframe);
|
|
145
|
+
return iframe;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Applies the styles from the provided document, including external stylesheets and inline styles,
|
|
149
|
+
* to the specified iframe's document.
|
|
150
|
+
*
|
|
151
|
+
* @param {HTMLIFrameElement} iframe - The iframe to which the styles are applied.
|
|
152
|
+
* @return {void} Does not return a value.
|
|
153
|
+
*/
|
|
154
|
+
applyDocumentStyleToIframe(iframe) {
|
|
155
|
+
// Ignore style injection, if not on Chrome
|
|
156
|
+
// (There is bug on Firefox: nothing appear in the print dialog)
|
|
157
|
+
// TODO: Should be tested on Safari
|
|
158
|
+
if (!isChrome(window))
|
|
159
|
+
return;
|
|
160
|
+
const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
|
|
161
|
+
if (iframeDocument) {
|
|
162
|
+
// Récupérer tous les styles (liens CSS)
|
|
163
|
+
const links = Array.from(this.document.querySelectorAll('style,link[rel="stylesheet"]'));
|
|
164
|
+
links.forEach((element) => {
|
|
165
|
+
// Insert inline style
|
|
166
|
+
if (element.tagName === 'STYLE') {
|
|
167
|
+
const newStyle = iframeDocument.createElement('style');
|
|
168
|
+
newStyle.innerHTML = element.innerHTML;
|
|
169
|
+
iframeDocument.head.appendChild(newStyle);
|
|
170
|
+
console.debug('[print-service] Add style to iframe', newStyle);
|
|
171
|
+
}
|
|
172
|
+
// Insert link to stylesheet file
|
|
173
|
+
else if (element.tagName === 'LINK' && element.getAttribute('href')) {
|
|
174
|
+
const newLink = iframeDocument.createElement('link');
|
|
175
|
+
newLink.rel = 'stylesheet';
|
|
176
|
+
newLink.href = element.getAttribute('href');
|
|
177
|
+
iframeDocument.head.appendChild(newLink);
|
|
178
|
+
console.debug('[print-service] Add stylesheet to iframe: ', newLink.href);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async waitIdle(iframe, opts) {
|
|
184
|
+
// Wait job finished
|
|
185
|
+
const printId = opts?.id || this.printId;
|
|
186
|
+
await waitForTrue(timer(500, 500).pipe(mergeMap(() => this.isLoaded(printId))), { timeout: opts?.timeout });
|
|
187
|
+
// Wait end of iframe load
|
|
188
|
+
await new Promise((resolve, reject) => {
|
|
189
|
+
const iframeWindow = iframe.contentWindow?.window || iframe.contentWindow;
|
|
190
|
+
if (iframeWindow.document.readyState === 'complete') {
|
|
191
|
+
resolve();
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
// Stop if timeout reached
|
|
195
|
+
if (opts?.timeout > 0) {
|
|
196
|
+
setTimeout(() => reject('timeout'), opts.timeout);
|
|
197
|
+
}
|
|
198
|
+
const readyListener = () => {
|
|
199
|
+
if (iframeWindow.document.readyState === 'complete') {
|
|
200
|
+
resolve();
|
|
201
|
+
iframeWindow.document.removeEventListener('readystatechange', readyListener);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
iframeWindow.document.addEventListener('readystatechange', readyListener);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Triggers the print functionality of the given iframe and resolves or rejects based on the print completion or timeout.
|
|
210
|
+
*
|
|
211
|
+
* @param {HTMLIFrameElement} iframe - The iframe element to be printed.
|
|
212
|
+
* @param {{timeout?: number}} [opts] - An optional configuration object.
|
|
213
|
+
* @param {number} [opts.timeout] - The maximum time in milliseconds to wait for the print to complete before rejecting the promise.
|
|
214
|
+
* @return {Promise<void>} A promise that resolves after the print is completed or rejects if a timeout occurs.
|
|
215
|
+
*/
|
|
216
|
+
print(iframe, opts) {
|
|
217
|
+
return new Promise((resolve, reject) => {
|
|
218
|
+
const iframeWindow = iframe.contentWindow?.window || iframe.contentWindow;
|
|
219
|
+
// Stop if timeout reached
|
|
220
|
+
if (opts?.timeout > 0) {
|
|
221
|
+
setTimeout(() => reject('timeout'), opts.timeout);
|
|
222
|
+
}
|
|
223
|
+
// On Chrome
|
|
224
|
+
if (isChrome(window)) {
|
|
225
|
+
// Wait after print event, to resolve the promise
|
|
226
|
+
const afterPrintListener = () => {
|
|
227
|
+
console.debug('[print-service] After print');
|
|
228
|
+
resolve();
|
|
229
|
+
// Remove the listener
|
|
230
|
+
iframeWindow.removeEventListener('afterprint', afterPrintListener);
|
|
231
|
+
};
|
|
232
|
+
iframeWindow.addEventListener('afterprint', afterPrintListener);
|
|
233
|
+
iframe.contentWindow.window.print();
|
|
234
|
+
}
|
|
235
|
+
// Otherwise (e.g. Firefox)
|
|
236
|
+
else {
|
|
237
|
+
iframe.contentWindow.window.print();
|
|
238
|
+
resolve();
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
async showToast(opts) {
|
|
243
|
+
if (!this.toastController)
|
|
244
|
+
throw new Error("Missing toastController in component's constructor");
|
|
245
|
+
return await Toasts.show(this.toastController, this.translate, opts);
|
|
246
|
+
}
|
|
247
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrintService, deps: [{ token: i1.ToastController }, { token: i2.TranslateService }, { token: i3.StorageService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
248
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrintService, providedIn: 'root' });
|
|
249
|
+
}
|
|
250
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrintService, decorators: [{
|
|
251
|
+
type: Injectable,
|
|
252
|
+
args: [{ providedIn: 'root' }]
|
|
253
|
+
}], ctorParameters: () => [{ type: i1.ToastController }, { type: i2.TranslateService }, { type: i3.StorageService }, { type: Document, decorators: [{
|
|
254
|
+
type: Inject,
|
|
255
|
+
args: [DOCUMENT]
|
|
256
|
+
}] }] });
|
|
257
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpbnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL3ByaW50L3ByaW50LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUkzRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFM0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNyQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdkMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7Ozs7QUFVeEMsTUFBTSxDQUFDLE1BQU0sZ0NBQWdDLEdBQUcsZ0JBQWdCLENBQUM7QUFHakUsTUFBTSxPQUFPLFlBQVk7SUFJWDtJQUNBO0lBQ0E7SUFDa0I7SUFOdEIsT0FBTyxHQUFHLENBQUMsQ0FBQztJQUVwQixZQUNZLGVBQWdDLEVBQ2hDLFNBQTJCLEVBQzNCLE9BQXVCLEVBQ0wsUUFBa0I7UUFIcEMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLGNBQVMsR0FBVCxTQUFTLENBQWtCO1FBQzNCLFlBQU8sR0FBUCxPQUFPLENBQWdCO1FBQ0wsYUFBUSxHQUFSLFFBQVEsQ0FBVTtJQUM3QyxDQUFDO0lBRUosU0FBUztRQUNQLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxLQUFLLENBQUMsWUFBWSxDQUFDLE9BQW9CLEVBQUUsSUFBbUI7UUFDMUQsSUFBSSxDQUFDLE9BQU87WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxD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TUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDdkUsQ0FBQzt3R0FwUVUsWUFBWSwrR0FPYixRQUFROzRHQVBQLFlBQVksY0FEQyxNQUFNOzs0RkFDbkIsWUFBWTtrQkFEeEIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUU7OzBCQVE3QixNQUFNOzJCQUFDLFFBQVEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTaG93VG9hc3RPcHRpb25zLCBUb2FzdHMgfSBmcm9tICcuLi90b2FzdC90b2FzdHMnO1xuaW1wb3J0IHsgT3ZlcmxheUV2ZW50RGV0YWlsIH0gZnJvbSAnQGlvbmljL2NvcmUnO1xuaW1wb3J0IHsgVG9hc3RDb250cm9sbGVyIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXInO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBTdG9yYWdlU2VydmljZSB9IGZyb20gJy4uL3N0b3JhZ2Uvc3RvcmFnZS5zZXJ2aWNlJztcbmltcG9ydCB7IGlzTmlsIH0gZnJvbSAnLi4vZnVuY3Rpb25zJztcbmltcG9ydCB7IHdhaXRGb3JUcnVlIH0gZnJvbSAnLi4vb2JzZXJ2YWJsZXMnO1xuaW1wb3J0IHsgbWVyZ2VNYXAsIHRpbWVyIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBpc0Nocm9tZSB9IGZyb20gJy4uL3BsYXRmb3Jtcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJpbnRPcHRpb25zIHtcbiAgaWQ/OiBzdHJpbmcgfCBudW1iZXI7XG4gIHRpdGxlPzogc3RyaW5nO1xuICBzaG93VG9hc3Q/OiBib29sZWFuO1xuICB0b2FzdE1lc3NhZ2U/OiBzdHJpbmc7XG4gIHN0eWxlPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY29uc3QgUFJJTlRfTE9BRElOR19TVE9SQUdFX0tFWV9QUkVGSVggPSAncHJpbnQtbG9hZGluZy0nO1xuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIFByaW50U2VydmljZSB7XG4gIHByaXZhdGUgcHJpbnRJZCA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIHRvYXN0Q29udHJvbGxlcjogVG9hc3RDb250cm9sbGVyLFxuICAgIHByb3RlY3RlZCB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIHN0b3JhZ2U6IFN0b3JhZ2VTZXJ2aWNlLFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIHByb3RlY3RlZCBkb2N1bWVudDogRG9jdW1lbnRcbiAgKSB7fVxuXG4gIG5leHRKb2JJZCgpIHtcbiAgICByZXR1cm4gKyt0aGlzLnByaW50SWQ7XG4gIH1cblxuICBhc3luYyBwcmludEVsZW1lbnQoZWxlbWVudDogSFRNTEVsZW1lbnQsIG9wdHM/OiBQcmludE9wdGlvbnMpIHtcbiAgICBpZiAoIWVsZW1lbnQpIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgcmVxdWlyZWQgJ2VsZW1lbnQnIGFyZ3VtZW50XCIpO1xuXG4gICAgcmV0dXJuIHRoaXMucHJpbnRIVE1MKGVsZW1lbnQuaW5uZXJIVE1MLCBvcHRzKTtcbiAgfVxuXG4gIGFzeW5jIHByaW50SFRNTChodG1sOiBzdHJpbmcsIG9wdHM/OiBQcmludE9wdGlvbnMpIHtcbiAgICBpZiAoIWh0bWwpIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgcmVxdWlyZWQgJ2h0bWwnIGFyZ3VtZW50XCIpO1xuXG4gICAgLy8gQ3JlYXRlIGlmcmFtZVxuICAgIGNvbnN0IGlmcmFtZSA9IHRoaXMuY3JlYXRlUHJpbnRJZnJhbWVCeUh0bWwoaHRtbCwgb3B0cyk7XG5cbiAgICByZXR1cm4gdGhpcy5wcmludElmcmFtZShpZnJhbWUsIG9wdHMpO1xuICB9XG5cbiAgYXN5bmMgcHJpbnRVcmwodXJsOiBzdHJpbmcsIG9wdHM/OiBPbWl0PFByaW50T3B0aW9ucywgJ3N0eWxlJz4pIHtcbiAgICBpZiAoIXVybCkgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyByZXF1aXJlZCAndXJsJyBhcmd1bWVudFwiKTtcblxuICAgIC8vIENyZWF0ZSBpZnJhbWVcbiAgICBjb25zdCBpZnJhbWUgPSB0aGlzLmNyZWF0ZVByaW50SWZyYW1lQnlVcmwodXJsKTtcblxuICAgIHJldHVybiB0aGlzLnByaW50SWZyYW1lKGlmcmFtZSwgb3B0cyk7XG4gIH1cblxuICBhc3luYyBwcmludElmcmFtZShpZnJhbWU6IEhUTUxJRnJhbWVFbGVtZW50LCBvcHRzPzogUHJpbnRPcHRpb25zKSB7XG4gICAgaWYgKCFpZnJhbWUpIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgcmVxdWlyZWQgJ2lmcmFtZScgYXJndW1lbnRcIik7XG5cbiAgICBjb25zdCBwcmludElkID0gb3B0cz8uaWQgPz8gdGhpcy5wcmludElkKys7XG4gICAgY29uc3QgdG9hc3RJZCA9IGBwcmludGluZy0ke3ByaW50SWR9YDtcbiAgICBjb25zdCBzaG93TG9hZGluZ1RvYXN0ID0gb3B0cz8uc2hvd1RvYXN0ICE9PSBmYWxzZTtcbiAgICBpZiAoc2hvd0xvYWRpbmdUb2FzdClcbiAgICAgIGF3YWl0IHRoaXMuc2hvd1RvYXN0KHtcbiAgICAgICAgaWQ6IHRvYXN0SWQsXG4gICAgICAgIG1lc3NhZ2U6IG9wdHM/LnRvYXN0TWVzc2FnZSB8fCAnQ09NTU9OLlBMRUFTRV9XQUlUJyxcbiAgICAgICAgZHVyYXRpb246IDAsXG4gICAgICB9KTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBXYWl0IGVuZCBvZiBpZnJhbWUgbG9hZFxuICAgICAgYXdhaXQgdGhpcy53YWl0SWRsZShpZnJhbWUsIHsgaWQ6IHByaW50SWQgfSk7XG5cbiAgICAgIC8vIFByaW50IChhbmQgd2FpdCBlbmQgb2YgcHJpbnQpXG4gICAgICBhd2FpdCB0aGlzLnByaW50KGlmcmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdbcHJpbnQtc2VydmljZV0gRmFpbGVkIHRvIGNyZWF0ZSBoaWRkZW4gaWZyYW1lJywgZXJyKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWZyYW1lLnJlbW92ZSgpO1xuICAgICAgaWYgKHNob3dMb2FkaW5nVG9hc3QpIGF3YWl0IHRoaXMudG9hc3RDb250cm9sbGVyLmRpc21pc3MobnVsbCwgbnVsbCwgdG9hc3RJZCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgbWFya0FzTG9hZGluZyhpZDogc3RyaW5nIHwgbnVtYmVyKSB7XG4gICAgY29uc29sZS5kZWJ1ZyhgW3ByaW50LXNlcnZpY2VdIE1hcmsgcHJpbnQgam9iICMke2lkfSBhcyBsb2FkaW5nYCk7XG4gICAgYXdhaXQgdGhpcy5zdG9yYWdlLnNldChQUklOVF9MT0FESU5HX1NUT1JBR0VfS0VZX1BSRUZJWCArIGlkLCAnMScpO1xuICB9XG5cbiAgYXN5bmMgbWFya0FzTG9hZGVkKGlkOiBzdHJpbmcgfCBudW1iZXIpIHtcbiAgICBjb25zb2xlLmRlYnVnKGBbcHJpbnQtc2VydmljZV0gTWFyayBwcmludCBqb2IgIyR7aWR9IGFzIGxvYWRlZGApO1xuICAgIGF3YWl0IHRoaXMuc3RvcmFnZS5yZW1vdmUoUFJJTlRfTE9BRElOR19TVE9SQUdFX0tFWV9QUkVGSVggKyBpZCk7XG4gIH1cblxuICBhc3luYyBpc0xvYWRlZChpZDogc3RyaW5nIHwgbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zdG9yYWdlLmdldChQUklOVF9MT0FESU5HX1NUT1JBR0VfS0VZX1BSRUZJWCArIGlkKTtcbiAgICByZXR1cm4gaXNOaWwocmVzdWx0KTtcbiAgfVxuXG4gIGFzeW5jIGlzTG9hZGluZyhpZDogc3RyaW5nIHwgbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuICEoYXdhaXQgdGhpcy5pc0xvYWRlZChpZCkpO1xuICB9XG5cbiAgLyogLS0gcHJvdGVjdGVkIGZ1bmN0aW9ucyAtLSAqL1xuXG4gIHByb3RlY3RlZCBjcmVhdGVQcmludElmcmFtZUJ5VXJsKHVybDogc3RyaW5nKTogSFRNTElGcmFtZUVsZW1lbnQge1xuICAgIC8vIENyZWF0ZSBhIGlmcmFtZSB3aXRoICc/cHJpbnQtcGRmJ1xuICAgIGNvbnN0IGlmcmFtZSA9IHRoaXMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgaWZyYW1lLmNsYXNzTGlzdC5hZGQoJ2Nkay12aXN1YWxseS1oaWRkZW4nKTtcbiAgICBpZnJhbWUuc3R5bGUud2lkdGggPSAnMTAwJSc7XG4gICAgaWZyYW1lLnN0eWxlLmhlaWdodCA9ICcxMDAlJztcbiAgICB0aGlzLmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgICBpZnJhbWUuc3JjID0gdXJsO1xuICAgIHJldHVybiBpZnJhbWU7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlUHJpbnRJZnJhbWVCeUh0bWwoaHRtbDogc3RyaW5nLCBvcHRzPzogeyB0aXRsZT86IHN0cmluZzsgaW5saW5lU3R5bGU/OiBzdHJpbmcgfSk6IEhUTUxJRnJhbWVFbGVtZW50IHtcbiAgICBpZiAoIWh0bWwpIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgcmVxdWlyZWQgJ2h0bWwnIGFyZ3VtZW50XCIpO1xuXG4gICAgY29uc3QgbGFuZyA9IHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50Py5sYW5nIHx8ICdlbic7XG5cbiAgICAvLyBDcmVhdGUgYW4gZW1wdHkgaWZyYW1lXG4gICAgY29uc3QgaWZyYW1lID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICBpZnJhbWUuY2xhc3NMaXN0LmFkZCgnY2RrLXZpc3VhbGx5LWhpZGRlbicpO1xuICAgIGlmcmFtZS5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICBpZnJhbWUuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIHRoaXMuZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuXG4gICAgLy8gV3JpdGUgaWZyYW1lIGNvbnRlbnRcbiAgICBjb25zdCBpZnJhbWVEb2N1bWVudCA9IGlmcmFtZS5jb250ZW50RG9jdW1lbnQgfHwgaWZyYW1lLmNvbnRlbnRXaW5kb3c/LmRvY3VtZW50O1xuICAgIGlmIChpZnJhbWVEb2N1bWVudCkge1xuICAgICAgaWZyYW1lRG9jdW1lbnQub3BlbigpO1xuICAgICAgaWZyYW1lRG9jdW1lbnQud3JpdGUoYFxuICAgICAgICA8IURPQ1RZUEUgaHRtbD5cbiAgICAgICAgPGh0bWwgbGFuZz1cIiR7bGFuZ31cIiBjbGFzcz1cInByaW50LXBkZlwiPlxuICAgICAgICAgIDxoZWFkPlxuICAgICAgICAgICAgPHRpdGxlPiR7b3B0cz8udGl0bGUgfHwgJyd9PC90aXRsZT5cbiAgICAgICAgICAgIDxzdHlsZT5cbiAgICAgICAgICAgIEBtZWRpYSBwcmludCB7XG4gICAgICAgICAgICAgIGJvZHkge1xuICAgICAgICAgICAgICAgIGZvbnQtZmFtaWx5OiAnUm9ib3RvJywgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZjtcbiAgICAgICAgICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgICAgICAgICAgcGFkZGluZzogMDtcbiAgICAgICAgICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGltZyB7XG4gICAgICAgICAgICAgICAgbWF4LXdpZHRoOiAxMDAlO1xuICAgICAgICAgICAgICAgIGhlaWdodDogYXV0bztcbiAgICAgICAgICAgICAgICBwYWdlLWJyZWFrLWluc2lkZTogYXZvaWQ7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICR7b3B0cz8uaW5saW5lU3R5bGUgfHwgJyd9XG4gICAgICAgICAgPC9zdHlsZT5cbiAgICAgICAgICA8L2hlYWQ+XG4gICAgICAgICAgPGJvZHk+XG4gICAgICAgICAgICAke2h0bWx9XG4gICAgICAgICAgPC9ib2R5PlxuICAgICAgICA8L2h0bWw+XG4gICAgICBgKTtcbiAgICAgIGlmcmFtZURvY3VtZW50LmNsb3NlKCk7XG4gICAgfVxuXG4gICAgLy8gU2V0IGlmcmFtZSBzdHlsZVxuICAgIHRoaXMuYXBwbHlEb2N1bWVudFN0eWxlVG9JZnJhbWUoaWZyYW1lKTtcblxuICAgIHJldHVybiBpZnJhbWU7XG4gIH1cblxuICAvKipcbiAgICogQXBwbGllcyB0aGUgc3R5bGVzIGZyb20gdGhlIHByb3ZpZGVkIGRvY3VtZW50LCBpbmNsdWRpbmcgZXh0ZXJuYWwgc3R5bGVzaGVldHMgYW5kIGlubGluZSBzdHlsZXMsXG4gICAqIHRvIHRoZSBzcGVjaWZpZWQgaWZyYW1lJ3MgZG9jdW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7SFRNTElGcmFtZUVsZW1lbnR9IGlmcmFtZSAtIFRoZSBpZnJhbWUgdG8gd2hpY2ggdGhlIHN0eWxlcyBhcmUgYXBwbGllZC5cbiAgICogQHJldHVybiB7dm9pZH0gRG9lcyBub3QgcmV0dXJuIGEgdmFsdWUuXG4gICAqL1xuICBwcm90ZWN0ZWQgYXBwbHlEb2N1bWVudFN0eWxlVG9JZnJhbWUoaWZyYW1lOiBIVE1MSUZyYW1lRWxlbWVudCk6IHZvaWQge1xuICAgIC8vIElnbm9yZSBzdHlsZSBpbmplY3Rpb24sIGlmIG5vdCBvbiBDaHJvbWVcbiAgICAvLyAoVGhlcmUgaXMgYnVnIG9uIEZpcmVmb3g6IG5vdGhpbmcgYXBwZWFyIGluIHRoZSBwcmludCBkaWFsb2cpXG4gICAgLy8gVE9ETzogU2hvdWxkIGJlIHRlc3RlZCBvbiBTYWZhcmlcbiAgICBpZiAoIWlzQ2hyb21lKHdpbmRvdykpIHJldHVybjtcblxuICAgIGNvbnN0IGlmcmFtZURvY3VtZW50ID0gaWZyYW1lLmNvbnRlbnREb2N1bWVudCB8fCBpZnJhbWUuY29udGVudFdpbmRvdz8uZG9jdW1lbnQ7XG4gICAgaWYgKGlmcmFtZURvY3VtZW50KSB7XG4gICAgICAvLyBSw6ljdXDDqXJlciB0b3VzIGxlcyBzdHlsZXMgKGxpZW5zIENTUylcbiAgICAgIGNvbnN0IGxpbmtzID0gQXJyYXkuZnJvbSh0aGlzLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ3N0eWxlLGxpbmtbcmVsPVwic3R5bGVzaGVldFwiXScpKTtcbiAgICAgIGxpbmtzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgLy8gSW5zZXJ0IGlubGluZSBzdHlsZVxuICAgICAgICBpZiAoZWxlbWVudC50YWdOYW1lID09PSAnU1RZTEUnKSB7XG4gICAgICAgICAgY29uc3QgbmV3U3R5bGUgPSBpZnJhbWVEb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuICAgICAgICAgIG5ld1N0eWxlLmlubmVySFRNTCA9IGVsZW1lbnQuaW5uZXJIVE1MO1xuICAgICAgICAgIGlmcmFtZURvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQobmV3U3R5bGUpO1xuXG4gICAgICAgICAgY29uc29sZS5kZWJ1ZygnW3ByaW50LXNlcnZpY2VdIEFkZCBzdHlsZSB0byBpZnJhbWUnLCBuZXdTdHlsZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJbnNlcnQgbGluayB0byBzdHlsZXNoZWV0IGZpbGVcbiAgICAgICAgZWxzZSBpZiAoZWxlbWVudC50YWdOYW1lID09PSAnTElOSycgJiYgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSkge1xuICAgICAgICAgIGNvbnN0IG5ld0xpbmsgPSBpZnJhbWVEb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaW5rJyk7XG4gICAgICAgICAgbmV3TGluay5yZWwgPSAnc3R5bGVzaGVldCc7XG4gICAgICAgICAgbmV3TGluay5ocmVmID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKTtcbiAgICAgICAgICBpZnJhbWVEb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG5ld0xpbmspO1xuXG4gICAgICAgICAgY29uc29sZS5kZWJ1ZygnW3ByaW50LXNlcnZpY2VdIEFkZCBzdHlsZXNoZWV0IHRvIGlmcmFtZTogJywgbmV3TGluay5ocmVmKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHdhaXRJZGxlKGlmcmFtZTogSFRNTElGcmFtZUVsZW1lbnQsIG9wdHM/OiB7IGlkPzogbnVtYmVyIHwgc3RyaW5nOyB0aW1lb3V0PzogbnVtYmVyIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBXYWl0IGpvYiBmaW5pc2hlZFxuICAgIGNvbnN0IHByaW50SWQgPSBvcHRzPy5pZCB8fCB0aGlzLnByaW50SWQ7XG4gICAgYXdhaXQgd2FpdEZvclRydWUodGltZXIoNTAwLCA1MDApLnBpcGUobWVyZ2VNYXAoKCkgPT4gdGhpcy5pc0xvYWRlZChwcmludElkKSkpLCB7IHRpbWVvdXQ6IG9wdHM/LnRpbWVvdXQgfSk7XG5cbiAgICAvLyBXYWl0IGVuZCBvZiBpZnJhbWUgbG9hZFxuICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IGlmcmFtZVdpbmRvdyA9IGlmcmFtZS5jb250ZW50V2luZG93Py53aW5kb3cgfHwgaWZyYW1lLmNvbnRlbnRXaW5kb3c7XG4gICAgICBpZiAoaWZyYW1lV2luZG93LmRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdjb21wbGV0ZScpIHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gU3RvcCBpZiB0aW1lb3V0IHJlYWNoZWRcbiAgICAgICAgaWYgKG9wdHM/LnRpbWVvdXQgPiAwKSB7XG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiByZWplY3QoJ3RpbWVvdXQnKSwgb3B0cy50aW1lb3V0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlYWR5TGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICAgICAgaWYgKGlmcmFtZVdpbmRvdy5kb2N1bWVudC5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnKSB7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgICAgIGlmcmFtZVdpbmRvdy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdyZWFkeXN0YXRlY2hhbmdlJywgcmVhZHlMaXN0ZW5lcik7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZnJhbWVXaW5kb3cuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncmVhZHlzdGF0ZWNoYW5nZScsIHJlYWR5TGlzdGVuZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyaWdnZXJzIHRoZSBwcmludCBmdW5jdGlvbmFsaXR5IG9mIHRoZSBnaXZlbiBpZnJhbWUgYW5kIHJlc29sdmVzIG9yIHJlamVjdHMgYmFzZWQgb24gdGhlIHByaW50IGNvbXBsZXRpb24gb3IgdGltZW91dC5cbiAgICpcbiAgICogQHBhcmFtIHtIVE1MSUZyYW1lRWxlbWVudH0gaWZyYW1lIC0gVGhlIGlmcmFtZSBlbGVtZW50IHRvIGJlIHByaW50ZWQuXG4gICAqIEBwYXJhbSB7e3RpbWVvdXQ/OiBudW1iZXJ9fSBbb3B0c10gLSBBbiBvcHRpb25hbCBjb25maWd1cmF0aW9uIG9iamVjdC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnRpbWVvdXRdIC0gVGhlIG1heGltdW0gdGltZSBpbiBtaWxsaXNlY29uZHMgdG8gd2FpdCBmb3IgdGhlIHByaW50IHRvIGNvbXBsZXRlIGJlZm9yZSByZWplY3RpbmcgdGhlIHByb21pc2UuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIHRoZSBwcmludCBpcyBjb21wbGV0ZWQgb3IgcmVqZWN0cyBpZiBhIHRpbWVvdXQgb2NjdXJzLlxuICAgKi9cbiAgcHJvdGVjdGVkIHByaW50KGlmcmFtZTogSFRNTElGcmFtZUVsZW1lbnQsIG9wdHM/OiB7IHRpbWVvdXQ/OiBudW1iZXIgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBpZnJhbWVXaW5kb3cgPSBpZnJhbWUuY29udGVudFdpbmRvdz8ud2luZG93IHx8IGlmcmFtZS5jb250ZW50V2luZG93O1xuXG4gICAgICAvLyBTdG9wIGlmIHRpbWVvdXQgcmVhY2hlZFxuICAgICAgaWYgKG9wdHM/LnRpbWVvdXQgPiAwKSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcmVqZWN0KCd0aW1lb3V0JyksIG9wdHMudGltZW91dCk7XG4gICAgICB9XG5cbiAgICAgIC8vIE9uIENocm9tZVxuICAgICAgaWYgKGlzQ2hyb21lKHdpbmRvdykpIHtcbiAgICAgICAgLy8gV2FpdCBhZnRlciBwcmludCBldmVudCwgdG8gcmVzb2x2ZSB0aGUgcHJvbWlzZVxuICAgICAgICBjb25zdCBhZnRlclByaW50TGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICAgICAgY29uc29sZS5kZWJ1ZygnW3ByaW50LXNlcnZpY2VdIEFmdGVyIHByaW50Jyk7XG5cbiAgICAgICAgICByZXNvbHZlKCk7XG5cbiAgICAgICAgICAvLyBSZW1vdmUgdGhlIGxpc3RlbmVyXG4gICAgICAgICAgaWZyYW1lV2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2FmdGVycHJpbnQnLCBhZnRlclByaW50TGlzdGVuZXIpO1xuICAgICAgICB9O1xuICAgICAgICBpZnJhbWVXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignYWZ0ZXJwcmludCcsIGFmdGVyUHJpbnRMaXN0ZW5lcik7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LndpbmRvdy5wcmludCgpO1xuICAgICAgfVxuXG4gICAgICAvLyBPdGhlcndpc2UgKGUuZy4gRmlyZWZveClcbiAgICAgIGVsc2Uge1xuICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy53aW5kb3cucHJpbnQoKTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzaG93VG9hc3Q8VCA9IGFueT4ob3B0czogU2hvd1RvYXN0T3B0aW9ucyk6IFByb21pc2U8T3ZlcmxheUV2ZW50RGV0YWlsPFQ+PiB7XG4gICAgaWYgKCF0aGlzLnRvYXN0Q29udHJvbGxlcikgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyB0b2FzdENvbnRyb2xsZXIgaW4gY29tcG9uZW50J3MgY29uc3RydWN0b3JcIik7XG4gICAgcmV0dXJuIGF3YWl0IFRvYXN0cy5zaG93KHRoaXMudG9hc3RDb250cm9sbGVyLCB0aGlzLnRyYW5zbGF0ZSwgb3B0cyk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -37,11 +37,11 @@ export class ModalToolbarComponent {
|
|
|
37
37
|
this._subscription.unsubscribe();
|
|
38
38
|
}
|
|
39
39
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ModalToolbarComponent, deps: [{ token: i1.Hotkeys }], target: i0.ɵɵFactoryTarget.Component });
|
|
40
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
40
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ModalToolbarComponent, selector: "app-modal-toolbar", inputs: { modalName: "modalName", title: "title", color: "color", showSpinner: "showSpinner", canValidate: "canValidate", validateIcon: "validateIcon" }, outputs: { cancel: "cancel", validate: "validate" }, ngImport: i0, template: "<ion-header>\n <ion-toolbar [color]=\"color\">\n <ion-buttons slot=\"start\">\n @if (cancel.observed) {\n <ion-button visible-xs visible-sm visible-mobile (click)=\"cancel.emit()\">\n <ion-icon slot=\"icon-only\" name=\"arrow-back\"></ion-icon>\n </ion-button>\n }\n\n <ng-content select=\"[slot=start]\"></ng-content>\n </ion-buttons>\n\n <ion-title [innerHTML]=\"title\"></ion-title>\n\n <ng-content select=\"ion-title\"></ng-content>\n\n <ng-content select=\"ion-buttons[slot=end]\"></ng-content>\n\n <ion-buttons slot=\"end\">\n <ng-content select=\"ion-button[slot=end]\"></ng-content>\n\n <ion-spinner *ngIf=\"showSpinner\"></ion-spinner>\n\n <ion-button visible-xs visible-sm visible-mobile *ngIf=\"canValidate\" (click)=\"validate.emit($event)\">\n <ion-icon slot=\"icon-only\" *ngIf=\"validateIcon?.icon\" [name]=\"validateIcon.icon\"></ion-icon>\n <mat-icon slot=\"icon-only\" *ngIf=\"validateIcon?.matIcon\">{{ validateIcon.matIcon }}</mat-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i3.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i3.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i3.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i3.IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: i3.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i3.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
41
41
|
}
|
|
42
42
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ModalToolbarComponent, decorators: [{
|
|
43
43
|
type: Component,
|
|
44
|
-
args: [{ selector: 'app-modal-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-header>\n <ion-toolbar [color]=\"color\">\n <ion-buttons slot=\"start\">\n <ion-button visible-xs visible-sm visible-mobile (click)=\"cancel.emit()\">\n
|
|
44
|
+
args: [{ selector: 'app-modal-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-header>\n <ion-toolbar [color]=\"color\">\n <ion-buttons slot=\"start\">\n @if (cancel.observed) {\n <ion-button visible-xs visible-sm visible-mobile (click)=\"cancel.emit()\">\n <ion-icon slot=\"icon-only\" name=\"arrow-back\"></ion-icon>\n </ion-button>\n }\n\n <ng-content select=\"[slot=start]\"></ng-content>\n </ion-buttons>\n\n <ion-title [innerHTML]=\"title\"></ion-title>\n\n <ng-content select=\"ion-title\"></ng-content>\n\n <ng-content select=\"ion-buttons[slot=end]\"></ng-content>\n\n <ion-buttons slot=\"end\">\n <ng-content select=\"ion-button[slot=end]\"></ng-content>\n\n <ion-spinner *ngIf=\"showSpinner\"></ion-spinner>\n\n <ion-button visible-xs visible-sm visible-mobile *ngIf=\"canValidate\" (click)=\"validate.emit($event)\">\n <ion-icon slot=\"icon-only\" *ngIf=\"validateIcon?.icon\" [name]=\"validateIcon.icon\"></ion-icon>\n <mat-icon slot=\"icon-only\" *ngIf=\"validateIcon?.matIcon\">{{ validateIcon.matIcon }}</mat-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n" }]
|
|
45
45
|
}], ctorParameters: () => [{ type: i1.Hotkeys }], propDecorators: { modalName: [{
|
|
46
46
|
type: Input
|
|
47
47
|
}], title: [{
|
|
@@ -59,4 +59,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
59
59
|
}], validate: [{
|
|
60
60
|
type: Output
|
|
61
61
|
}] } });
|
|
62
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
62
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwtdG9vbGJhci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL3Rvb2xiYXIvbW9kYWwtdG9vbGJhci50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL3Rvb2xiYXIvbW9kYWwtdG9vbGJhci5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ILE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDekMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUdwQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7OztBQVF4QyxNQUFNLE9BQU8scUJBQXFCO0lBMEJaO0lBekJaLGFBQWEsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBRzNDLFNBQVMsR0FBRyxlQUFlLENBQUM7SUFHNUIsS0FBSyxHQUFHLEVBQUUsQ0FBQztJQUdYLEtBQUssR0FBRyxTQUFTLENBQUM7SUFHbEIsV0FBVyxHQUFHLEtBQUssQ0FBQztJQUdwQixXQUFXLENBQVU7SUFFWixZQUFZLEdBQVksRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUM7SUFHdkQsTUFBTSxHQUFHLElBQUksWUFBWSxFQUFTLENBQUM7SUFHbkMsUUFBUSxHQUFHLElBQUksWUFBWSxFQUFTLENBQUM7SUFFckMsWUFBb0IsT0FBZ0I7UUFBaEIsWUFBTyxHQUFQLE9BQU8sQ0FBUztJQUFHLENBQUM7SUFFeEMsUUFBUTtRQUNOLElBQUksQ0FBQyxXQUFXLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUV2RSxTQUFTO1FBQ1QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQ3BCLElBQUksQ0FBQyxPQUFPO2FBQ1QsV0FBVyxDQUFDLEVBQUUsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsSUFBSSxFQUFFLFdBQVcsRUFBRSxxQkFBcUIsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2FBQzdILElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2FBQ3BDLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FDbkQsQ0FBQztRQUVGLFNBQVM7UUFDVCxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FDcEIsSUFBSSxDQUFDLE9BQU87YUFDVCxXQUFXLENBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxrQkFBa0IsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2FBQzdGLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FDakQsQ0FBQztJQUNKLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNuQyxDQUFDO3dHQWpEVSxxQkFBcUI7NEZBQXJCLHFCQUFxQix3UUNibEMsZ21DQThCQTs7NEZEakJhLHFCQUFxQjtrQkFOakMsU0FBUzsrQkFDRSxtQkFBbUIsbUJBR1osdUJBQXVCLENBQUMsTUFBTTs0RUFNL0MsU0FBUztzQkFEUixLQUFLO2dCQUlOLEtBQUs7c0JBREosS0FBSztnQkFJTixLQUFLO3NCQURKLEtBQUs7Z0JBSU4sV0FBVztzQkFEVixLQUFLO2dCQUlOLFdBQVc7c0JBRFYsS0FBSztnQkFHRyxZQUFZO3NCQUFwQixLQUFLO2dCQUdOLE1BQU07c0JBREwsTUFBTTtnQkFJUCxRQUFRO3NCQURQLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0b0Jvb2xlYW4gfSBmcm9tICcuLi9mdW5jdGlvbnMnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBIb3RrZXlzIH0gZnJvbSAnLi4vaG90a2V5cy9ob3RrZXlzLnNlcnZpY2UnO1xuaW1wb3J0IHsgSWNvblJlZiB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGZpbHRlciB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLW1vZGFsLXRvb2xiYXInLFxuICB0ZW1wbGF0ZVVybDogJ21vZGFsLXRvb2xiYXIuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL21vZGFsLXRvb2xiYXIuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgTW9kYWxUb29sYmFyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIF9zdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgQElucHV0KClcbiAgbW9kYWxOYW1lID0gJ21vZGFsLXRvb2xiYXInO1xuXG4gIEBJbnB1dCgpXG4gIHRpdGxlID0gJyc7XG5cbiAgQElucHV0KClcbiAgY29sb3IgPSAncHJpbWFyeSc7XG5cbiAgQElucHV0KClcbiAgc2hvd1NwaW5uZXIgPSBmYWxzZTtcblxuICBASW5wdXQoKVxuICBjYW5WYWxpZGF0ZTogYm9vbGVhbjtcblxuICBASW5wdXQoKSB2YWxpZGF0ZUljb246IEljb25SZWYgPSB7IGljb246ICdjaGVja21hcmsnIH07XG5cbiAgQE91dHB1dCgpXG4gIGNhbmNlbCA9IG5ldyBFdmVudEVtaXR0ZXI8RXZlbnQ+KCk7XG5cbiAgQE91dHB1dCgpXG4gIHZhbGlkYXRlID0gbmV3IEV2ZW50RW1pdHRlcjxFdmVudD4oKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGhvdGtleXM6IEhvdGtleXMpIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5jYW5WYWxpZGF0ZSA9IHRvQm9vbGVhbih0aGlzLmNhblZhbGlkYXRlLCB0aGlzLnZhbGlkYXRlLm9ic2VydmVkKTtcblxuICAgIC8vIEN0cmwrU1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi5hZGQoXG4gICAgICB0aGlzLmhvdGtleXNcbiAgICAgICAgLmFkZFNob3J0Y3V0KHsga2V5czogYCR7dGhpcy5ob3RrZXlzLmRlZmF1bHRDb250cm9sS2V5fS5zYCwgZGVzY3JpcHRpb246ICdDT01NT04uQlROX1ZBTElEQVRFJywgZWxlbWVudE5hbWU6IHRoaXMubW9kYWxOYW1lIH0pXG4gICAgICAgIC5waXBlKGZpbHRlcigoKSA9PiB0aGlzLmNhblZhbGlkYXRlKSlcbiAgICAgICAgLnN1YnNjcmliZSgoZXZlbnQpID0+IHRoaXMudmFsaWRhdGUuZW1pdChldmVudCkpXG4gICAgKTtcblxuICAgIC8vIEVzY2FwZVxuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi5hZGQoXG4gICAgICB0aGlzLmhvdGtleXNcbiAgICAgICAgLmFkZFNob3J0Y3V0KHsga2V5czogJ2VzY2FwZScsIGRlc2NyaXB0aW9uOiAnQ09NTU9OLkJUTl9DTE9TRScsIGVsZW1lbnROYW1lOiB0aGlzLm1vZGFsTmFtZSB9KVxuICAgICAgICAuc3Vic2NyaWJlKChldmVudCkgPT4gdGhpcy5jYW5jZWwuZW1pdChldmVudCkpXG4gICAgKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICB9XG59XG4iLCI8aW9uLWhlYWRlcj5cbiAgPGlvbi10b29sYmFyIFtjb2xvcl09XCJjb2xvclwiPlxuICAgIDxpb24tYnV0dG9ucyBzbG90PVwic3RhcnRcIj5cbiAgICAgIEBpZiAoY2FuY2VsLm9ic2VydmVkKSB7XG4gICAgICAgIDxpb24tYnV0dG9uIHZpc2libGUteHMgdmlzaWJsZS1zbSB2aXNpYmxlLW1vYmlsZSAoY2xpY2spPVwiY2FuY2VsLmVtaXQoKVwiPlxuICAgICAgICAgIDxpb24taWNvbiBzbG90PVwiaWNvbi1vbmx5XCIgbmFtZT1cImFycm93LWJhY2tcIj48L2lvbi1pY29uPlxuICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICB9XG5cbiAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltzbG90PXN0YXJ0XVwiPjwvbmctY29udGVudD5cbiAgICA8L2lvbi1idXR0b25zPlxuXG4gICAgPGlvbi10aXRsZSBbaW5uZXJIVE1MXT1cInRpdGxlXCI+PC9pb24tdGl0bGU+XG5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJpb24tdGl0bGVcIj48L25nLWNvbnRlbnQ+XG5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJpb24tYnV0dG9uc1tzbG90PWVuZF1cIj48L25nLWNvbnRlbnQ+XG5cbiAgICA8aW9uLWJ1dHRvbnMgc2xvdD1cImVuZFwiPlxuICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiaW9uLWJ1dHRvbltzbG90PWVuZF1cIj48L25nLWNvbnRlbnQ+XG5cbiAgICAgIDxpb24tc3Bpbm5lciAqbmdJZj1cInNob3dTcGlubmVyXCI+PC9pb24tc3Bpbm5lcj5cblxuICAgICAgPGlvbi1idXR0b24gdmlzaWJsZS14cyB2aXNpYmxlLXNtIHZpc2libGUtbW9iaWxlICpuZ0lmPVwiY2FuVmFsaWRhdGVcIiAoY2xpY2spPVwidmFsaWRhdGUuZW1pdCgkZXZlbnQpXCI+XG4gICAgICAgIDxpb24taWNvbiBzbG90PVwiaWNvbi1vbmx5XCIgKm5nSWY9XCJ2YWxpZGF0ZUljb24/Lmljb25cIiBbbmFtZV09XCJ2YWxpZGF0ZUljb24uaWNvblwiPjwvaW9uLWljb24+XG4gICAgICAgIDxtYXQtaWNvbiBzbG90PVwiaWNvbi1vbmx5XCIgKm5nSWY9XCJ2YWxpZGF0ZUljb24/Lm1hdEljb25cIj57eyB2YWxpZGF0ZUljb24ubWF0SWNvbiB9fTwvbWF0LWljb24+XG4gICAgICA8L2lvbi1idXR0b24+XG4gICAgPC9pb24tYnV0dG9ucz5cbiAgPC9pb24tdG9vbGJhcj5cbjwvaW9uLWhlYWRlcj5cbiJdfQ==
|