@decaf-ts/for-angular 0.0.12 → 0.0.14
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/{dist/lib/components → components}/component-renderer/component-renderer.component.d.ts +0 -1
- package/{dist/lib/components → components}/crud-field/crud-field.component.d.ts +0 -1
- package/{dist/lib/components → components}/crud-form/constants.d.ts +0 -1
- package/{dist/lib/components → components}/crud-form/crud-form.component.d.ts +0 -1
- package/{dist/lib/components → components}/crud-form/types.d.ts +0 -1
- package/{dist/lib/components → components}/empty-state/empty-state.component.d.ts +0 -1
- package/{dist/lib/components → components}/fieldset/fieldset.component.d.ts +0 -1
- package/{dist/lib/components → components}/filter/filter.component.d.ts +0 -1
- package/{dist/lib/components → components}/for-angular-components.module.d.ts +0 -1
- package/{dist/lib/components → components}/index.d.ts +0 -1
- package/{dist/lib/components → components}/layout/layout.component.d.ts +0 -1
- package/{dist/lib/components → components}/list/constants.d.ts +0 -1
- package/{dist/lib/components → components}/list/list.component.d.ts +0 -1
- package/{dist/lib/components → components}/list-item/list-item.component.d.ts +0 -1
- package/{dist/lib/components → components}/model-renderer/model-renderer.component.d.ts +0 -1
- package/{dist/lib/components → components}/pagination/constants.d.ts +0 -1
- package/{dist/lib/components → components}/pagination/pagination.component.d.ts +0 -1
- package/{dist/lib/components → components}/searchbar/searchbar.component.d.ts +0 -1
- package/{dist/lib/directives → directives}/collapsable.directive.d.ts +0 -1
- package/{dist/lib/directives → directives}/index.d.ts +0 -1
- package/{dist/lib/engine → engine}/DynamicModule.d.ts +0 -1
- package/{dist/lib/engine → engine}/NgxBaseComponent.d.ts +0 -1
- package/{dist/lib/engine → engine}/NgxCrudFormField.d.ts +0 -1
- package/{dist/lib/engine → engine}/NgxFormService.d.ts +0 -1
- package/{dist/lib/engine → engine}/NgxRenderingEngine.d.ts +0 -1
- package/{dist/lib/engine → engine}/NgxRenderingEngine2.d.ts +0 -1
- package/{dist/lib/engine → engine}/ValidatorFactory.d.ts +0 -1
- package/{dist/lib/engine → engine}/constants.d.ts +0 -1
- package/{dist/lib/engine → engine}/decorators.d.ts +0 -1
- package/{dist/lib/engine → engine}/index.d.ts +0 -1
- package/{dist/lib/engine → engine}/types.d.ts +0 -1
- package/esm2022/components/component-renderer/component-renderer.component.mjs +313 -0
- package/esm2022/components/crud-field/crud-field.component.mjs +301 -0
- package/esm2022/components/crud-form/crud-form.component.mjs +139 -0
- package/esm2022/components/empty-state/empty-state.component.mjs +348 -0
- package/esm2022/components/fieldset/fieldset.component.mjs +225 -0
- package/esm2022/components/filter/filter.component.mjs +689 -0
- package/esm2022/components/for-angular-components.module.mjs +71 -0
- package/esm2022/components/layout/layout.component.mjs +176 -0
- package/esm2022/components/list/list.component.mjs +1236 -0
- package/esm2022/components/list-item/list-item.component.mjs +408 -0
- package/esm2022/components/model-renderer/model-renderer.component.mjs +138 -0
- package/esm2022/components/pagination/pagination.component.mjs +323 -0
- package/esm2022/components/searchbar/searchbar.component.mjs +493 -0
- package/esm2022/directives/collapsable.directive.mjs +28 -0
- package/esm2022/engine/NgxBaseComponent.mjs +539 -0
- package/esm2022/for-angular.module.mjs +118 -0
- package/{dist/lib/fesm2022 → fesm2022}/decaf-ts-for-angular.mjs +621 -1805
- package/fesm2022/decaf-ts-for-angular.mjs.map +1 -0
- package/{dist/lib/for-angular.module.d.ts → for-angular.module.d.ts} +0 -1
- package/{dist/lib/helpers → helpers}/index.d.ts +0 -1
- package/{dist/lib/helpers → helpers}/utils.d.ts +0 -1
- package/{dist/lib/index.d.ts → index.d.ts} +0 -1
- package/{dist/lib/interfaces.d.ts → interfaces.d.ts} +0 -1
- package/package.json +19 -95
- package/{dist/lib/public-apis.d.ts → public-apis.d.ts} +0 -1
- package/LICENSE.md +0 -659
- package/dist/for-angular/cli/cli-module.d.ts +0 -22
- package/dist/for-angular/cli/cli-module.d.ts.map +0 -1
- package/dist/for-angular/cli/cli-module.js +0 -131
- package/dist/for-angular/cli/cli-module.js.map +0 -1
- package/dist/lib/README.md +0 -92
- package/dist/lib/components/component-renderer/component-renderer.component.d.ts.map +0 -1
- package/dist/lib/components/crud-field/crud-field.component.d.ts.map +0 -1
- package/dist/lib/components/crud-form/constants.d.ts.map +0 -1
- package/dist/lib/components/crud-form/crud-form.component.d.ts.map +0 -1
- package/dist/lib/components/crud-form/types.d.ts.map +0 -1
- package/dist/lib/components/empty-state/empty-state.component.d.ts.map +0 -1
- package/dist/lib/components/fieldset/fieldset.component.d.ts.map +0 -1
- package/dist/lib/components/filter/filter.component.d.ts.map +0 -1
- package/dist/lib/components/for-angular-components.module.d.ts.map +0 -1
- package/dist/lib/components/index.d.ts.map +0 -1
- package/dist/lib/components/layout/layout.component.d.ts.map +0 -1
- package/dist/lib/components/list/constants.d.ts.map +0 -1
- package/dist/lib/components/list/list.component.d.ts.map +0 -1
- package/dist/lib/components/list-item/list-item.component.d.ts.map +0 -1
- package/dist/lib/components/model-renderer/model-renderer.component.d.ts.map +0 -1
- package/dist/lib/components/pagination/constants.d.ts.map +0 -1
- package/dist/lib/components/pagination/pagination.component.d.ts.map +0 -1
- package/dist/lib/components/searchbar/searchbar.component.d.ts.map +0 -1
- package/dist/lib/decaf-ts-for-angular.d.ts.map +0 -1
- package/dist/lib/directives/collapsable.directive.d.ts.map +0 -1
- package/dist/lib/directives/index.d.ts.map +0 -1
- package/dist/lib/engine/DynamicModule.d.ts.map +0 -1
- package/dist/lib/engine/NgxBaseComponent.d.ts.map +0 -1
- package/dist/lib/engine/NgxCrudFormField.d.ts.map +0 -1
- package/dist/lib/engine/NgxFormService.d.ts.map +0 -1
- package/dist/lib/engine/NgxRenderingEngine.d.ts.map +0 -1
- package/dist/lib/engine/NgxRenderingEngine2.d.ts.map +0 -1
- package/dist/lib/engine/ValidatorFactory.d.ts.map +0 -1
- package/dist/lib/engine/constants.d.ts.map +0 -1
- package/dist/lib/engine/decorators.d.ts.map +0 -1
- package/dist/lib/engine/index.d.ts.map +0 -1
- package/dist/lib/engine/types.d.ts.map +0 -1
- package/dist/lib/esm2022/components/component-renderer/component-renderer.component.mjs +0 -359
- package/dist/lib/esm2022/components/crud-field/crud-field.component.mjs +0 -456
- package/dist/lib/esm2022/components/crud-form/crud-form.component.mjs +0 -272
- package/dist/lib/esm2022/components/empty-state/empty-state.component.mjs +0 -410
- package/dist/lib/esm2022/components/fieldset/fieldset.component.mjs +0 -250
- package/dist/lib/esm2022/components/filter/filter.component.mjs +0 -906
- package/dist/lib/esm2022/components/for-angular-components.module.mjs +0 -72
- package/dist/lib/esm2022/components/layout/layout.component.mjs +0 -245
- package/dist/lib/esm2022/components/list/list.component.mjs +0 -1405
- package/dist/lib/esm2022/components/list-item/list-item.component.mjs +0 -612
- package/dist/lib/esm2022/components/model-renderer/model-renderer.component.mjs +0 -182
- package/dist/lib/esm2022/components/pagination/pagination.component.mjs +0 -364
- package/dist/lib/esm2022/components/searchbar/searchbar.component.mjs +0 -503
- package/dist/lib/esm2022/directives/collapsable.directive.mjs +0 -28
- package/dist/lib/esm2022/engine/NgxBaseComponent.mjs +0 -546
- package/dist/lib/esm2022/for-angular.module.mjs +0 -119
- package/dist/lib/fesm2022/decaf-ts-for-angular.mjs.map +0 -1
- package/dist/lib/for-angular.module.d.ts.map +0 -1
- package/dist/lib/helpers/index.d.ts.map +0 -1
- package/dist/lib/helpers/utils.d.ts.map +0 -1
- package/dist/lib/interfaces.d.ts.map +0 -1
- package/dist/lib/public-apis.d.ts.map +0 -1
- /package/{dist/lib/assets → assets}/i18n/en.json +0 -0
- /package/{dist/lib/assets → assets}/images/angular-logo.svg +0 -0
- /package/{dist/lib/assets → assets}/images/decaf-logo-black.svg +0 -0
- /package/{dist/lib/assets → assets}/images/decaf-logo-lw.svg +0 -0
- /package/{dist/lib/assets → assets}/images/decaf-logo-white.svg +0 -0
- /package/{dist/lib/assets → assets}/images/decaf-logo.svg +0 -0
- /package/{dist/lib/esm2022 → esm2022}/components/crud-form/constants.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/components/crud-form/types.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/components/index.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/components/list/constants.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/components/pagination/constants.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/decaf-ts-for-angular.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/directives/index.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/engine/DynamicModule.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/engine/NgxCrudFormField.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/engine/NgxFormService.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/engine/NgxRenderingEngine.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/engine/NgxRenderingEngine2.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/engine/ValidatorFactory.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/engine/constants.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/engine/decorators.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/engine/index.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/engine/types.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/helpers/index.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/helpers/utils.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/interfaces.mjs +0 -0
- /package/{dist/lib/esm2022 → esm2022}/public-apis.mjs +0 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Component, EventEmitter, inject, Injector, Input, Output, TemplateRef, ViewChild, ViewContainerRef, } from '@angular/core';
|
|
2
|
+
import { Model, sf } from '@decaf-ts/decorator-validation';
|
|
3
|
+
import { NgComponentOutlet } from '@angular/common';
|
|
4
|
+
import { AngularEngineKeys, BaseComponentProps, NgxRenderingEngine2, } from '../../engine';
|
|
5
|
+
import { ForAngularModule } from '../../for-angular.module';
|
|
6
|
+
import { ComponentRendererComponent } from '../component-renderer/component-renderer.component';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "@angular/common";
|
|
9
|
+
/**
|
|
10
|
+
* @description Component for rendering dynamic models
|
|
11
|
+
* @summary This component is responsible for dynamically rendering models,
|
|
12
|
+
* handling model changes, and managing event subscriptions for the rendered components.
|
|
13
|
+
* It uses the NgxRenderingEngine2 to render the models and supports both string and Model inputs.
|
|
14
|
+
* @class
|
|
15
|
+
* @template M - Type extending Model
|
|
16
|
+
* @param {Injector} injector - Angular Injector for dependency injection
|
|
17
|
+
* @example
|
|
18
|
+
* <ngx-decaf-model-renderer
|
|
19
|
+
* [model]="myModel"
|
|
20
|
+
* [globals]="globalVariables"
|
|
21
|
+
* (listenEvent)="handleEvent($event)">
|
|
22
|
+
* </ngx-decaf-model-renderer>
|
|
23
|
+
* @mermaid
|
|
24
|
+
* sequenceDiagram
|
|
25
|
+
* participant App
|
|
26
|
+
* participant ModelRenderer
|
|
27
|
+
* participant RenderingEngine
|
|
28
|
+
* participant Model
|
|
29
|
+
* App->>ModelRenderer: Input model
|
|
30
|
+
* ModelRenderer->>Model: Parse if string
|
|
31
|
+
* Model-->>ModelRenderer: Parsed model
|
|
32
|
+
* ModelRenderer->>RenderingEngine: Render model
|
|
33
|
+
* RenderingEngine-->>ModelRenderer: Rendered output
|
|
34
|
+
* ModelRenderer->>ModelRenderer: Subscribe to events
|
|
35
|
+
* ModelRenderer-->>App: Emit events
|
|
36
|
+
*/
|
|
37
|
+
export class ModelRendererComponent {
|
|
38
|
+
constructor() {
|
|
39
|
+
/**
|
|
40
|
+
* @description Global variables to be passed to the rendered component
|
|
41
|
+
*/
|
|
42
|
+
this.globals = {};
|
|
43
|
+
/**
|
|
44
|
+
* @description Event emitter for custom events from the rendered component
|
|
45
|
+
*/
|
|
46
|
+
this.listenEvent = new EventEmitter();
|
|
47
|
+
this.injector = inject(Injector);
|
|
48
|
+
this.JSON = JSON;
|
|
49
|
+
}
|
|
50
|
+
// constructor() {}
|
|
51
|
+
/**
|
|
52
|
+
* @description Refreshes the rendered model
|
|
53
|
+
* @param {string | M} model - The model to be rendered
|
|
54
|
+
*/
|
|
55
|
+
refresh(model) {
|
|
56
|
+
model =
|
|
57
|
+
typeof model === 'string'
|
|
58
|
+
? Model.build({}, model)
|
|
59
|
+
: model;
|
|
60
|
+
this.output = model.render(this.globals || {}, this.vcr, this.injector, this.inner);
|
|
61
|
+
if (this.output?.inputs)
|
|
62
|
+
this.rendererId = sf(AngularEngineKeys.RENDERED_ID, this.output.inputs['rendererId']);
|
|
63
|
+
this.instance = this.output?.instance;
|
|
64
|
+
this.subscribeEvents();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* @description Lifecycle hook that is called when data-bound properties of a directive change
|
|
68
|
+
* @param {SimpleChanges} changes - Object containing changes
|
|
69
|
+
*/
|
|
70
|
+
ngOnChanges(changes) {
|
|
71
|
+
if (changes[BaseComponentProps.MODEL]) {
|
|
72
|
+
const { currentValue } = changes[BaseComponentProps.MODEL];
|
|
73
|
+
this.refresh(currentValue);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* @description Lifecycle hook that is called when a directive, pipe, or service is destroyed
|
|
78
|
+
* @return {Promise<void>}
|
|
79
|
+
*/
|
|
80
|
+
async ngOnDestroy() {
|
|
81
|
+
if (this.instance) {
|
|
82
|
+
this.unsubscribeEvents();
|
|
83
|
+
await NgxRenderingEngine2.destroy();
|
|
84
|
+
}
|
|
85
|
+
this.output = undefined;
|
|
86
|
+
}
|
|
87
|
+
subscribeEvents() {
|
|
88
|
+
if (this.instance) {
|
|
89
|
+
const componentKeys = Object.keys(this.instance);
|
|
90
|
+
for (const key of componentKeys) {
|
|
91
|
+
const value = this.instance[key];
|
|
92
|
+
if (value instanceof EventEmitter)
|
|
93
|
+
this.instance[key].subscribe((event) => {
|
|
94
|
+
this.listenEvent.emit({
|
|
95
|
+
component: this.output?.component.name || '',
|
|
96
|
+
name: key,
|
|
97
|
+
...event,
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* @description Unsubscribes from events emitted by the rendered component
|
|
105
|
+
*/
|
|
106
|
+
unsubscribeEvents() {
|
|
107
|
+
if (this.instance) {
|
|
108
|
+
const componentKeys = Object.keys(this.instance);
|
|
109
|
+
for (const key of componentKeys) {
|
|
110
|
+
const value = this.instance[key];
|
|
111
|
+
if (value instanceof EventEmitter)
|
|
112
|
+
this.instance[key].unsubscribe();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ModelRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
117
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ModelRendererComponent, isStandalone: true, selector: "ngx-decaf-model-renderer", inputs: { model: "model", globals: "globals", rendererId: "rendererId" }, outputs: { listenEvent: "listenEvent" }, viewQueries: [{ propertyName: "inner", first: true, predicate: ["inner"], descendants: true, read: TemplateRef, static: true }, { propertyName: "vcr", first: true, predicate: ["componentOuter"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: " <ng-template #componentOuter></ng-template>\n <ng-template #inner>\n <div [id]=\"rendererId || null\">\n @for (child of output?.children; track child) {\n @if(child?.children?.length) {\n <ngx-decaf-component-renderer [parent]=\"child\" />\n } @else {\n <ng-container\n #childComponents\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n </div>\n </ng-template>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ForAngularModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "globals", "model", "parent"], outputs: ["listenEvent"] }] }); }
|
|
118
|
+
}
|
|
119
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ModelRendererComponent, decorators: [{
|
|
120
|
+
type: Component,
|
|
121
|
+
args: [{ standalone: true, imports: [ForAngularModule, NgComponentOutlet, ComponentRendererComponent], selector: 'ngx-decaf-model-renderer', template: " <ng-template #componentOuter></ng-template>\n <ng-template #inner>\n <div [id]=\"rendererId || null\">\n @for (child of output?.children; track child) {\n @if(child?.children?.length) {\n <ngx-decaf-component-renderer [parent]=\"child\" />\n } @else {\n <ng-container\n #childComponents\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n }\n }\n </div>\n </ng-template>\n" }]
|
|
122
|
+
}], propDecorators: { model: [{
|
|
123
|
+
type: Input,
|
|
124
|
+
args: [{ required: true }]
|
|
125
|
+
}], globals: [{
|
|
126
|
+
type: Input
|
|
127
|
+
}], inner: [{
|
|
128
|
+
type: ViewChild,
|
|
129
|
+
args: ['inner', { read: TemplateRef, static: true }]
|
|
130
|
+
}], rendererId: [{
|
|
131
|
+
type: Input
|
|
132
|
+
}], vcr: [{
|
|
133
|
+
type: ViewChild,
|
|
134
|
+
args: ['componentOuter', { static: true, read: ViewContainerRef }]
|
|
135
|
+
}], listenEvent: [{
|
|
136
|
+
type: Output
|
|
137
|
+
}] } });
|
|
138
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwtcmVuZGVyZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL21vZGVsLXJlbmRlcmVyL21vZGVsLXJlbmRlcmVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9tb2RlbC1yZW5kZXJlci9tb2RlbC1yZW5kZXJlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixNQUFNLEVBQ04sUUFBUSxFQUNSLEtBQUssRUFHTCxNQUFNLEVBRU4sV0FBVyxFQUNYLFNBQVMsRUFDVCxnQkFBZ0IsR0FDakIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBRUwsaUJBQWlCLEVBQ2pCLGtCQUFrQixFQUVsQixtQkFBbUIsR0FFcEIsTUFBTSxjQUFjLENBQUM7QUFFdEIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFNUQsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sb0RBQW9ELENBQUM7OztBQUVoRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMkJHO0FBUUgsTUFBTSxPQUFPLHNCQUFzQjtJQVBuQztRQWlCRTs7V0FFRztRQUVILFlBQU8sR0FBNEIsRUFBRSxDQUFDO1FBeUJ0Qzs7V0FFRztRQUVILGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQXVCLENBQUM7UUFZOUMsYUFBUSxHQUFhLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQWtGM0IsU0FBSSxHQUFHLElBQUksQ0FBQztLQUNoQztJQWpGQyxtQkFBbUI7SUFFbkI7OztPQUdHO0lBQ0ssT0FBTyxDQUFDLEtBQWlCO1FBQy9CLEtBQUs7WUFDSCxPQUFPLEtBQUssS0FBSyxRQUFRO2dCQUN2QixDQUFDLENBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFPO2dCQUMvQixDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ1osSUFBSSxDQUFDLE1BQU0sR0FBSSxLQUErQixDQUFDLE1BQU0sQ0FDbkQsSUFBSSxDQUFDLE9BQU8sSUFBSSxFQUFFLEVBQ2xCLElBQUksQ0FBQyxHQUFHLEVBQ1IsSUFBSSxDQUFDLFFBQVEsRUFDYixJQUFJLENBQUMsS0FBSyxDQUNYLENBQUM7UUFDRixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTTtZQUNyQixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FDbEIsaUJBQWlCLENBQUMsV0FBVyxFQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLE1BQWtDLENBQUMsWUFBWSxDQUFXLENBQ3hFLENBQUM7UUFDSixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksT0FBTyxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEMsTUFBTSxFQUFFLFlBQVksRUFBRSxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMzRCxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzdCLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLFdBQVc7UUFDZixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN6QixNQUFNLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3RDLENBQUM7UUFDRCxJQUFJLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQztJQUMxQixDQUFDO0lBRU8sZUFBZTtRQUNyQixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNsQixNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNqRCxLQUFLLE1BQU0sR0FBRyxJQUFJLGFBQWEsRUFBRSxDQUFDO2dCQUNoQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNqQyxJQUFJLEtBQUssWUFBWSxZQUFZO29CQUM5QixJQUFJLENBQUMsUUFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUErQixFQUFFLEVBQUU7d0JBQzdFLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDOzRCQUNwQixTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsSUFBSSxJQUFJLEVBQUU7NEJBQzVDLElBQUksRUFBRSxHQUFHOzRCQUNULEdBQUcsS0FBSzt5QkFDYyxDQUFDLENBQUM7b0JBQzVCLENBQUMsQ0FBQyxDQUFDO1lBQ1AsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUI7UUFDdkIsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbEIsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDakQsS0FBSyxNQUFNLEdBQUcsSUFBSSxhQUFhLEVBQUUsQ0FBQztnQkFDaEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDakMsSUFBSSxLQUFLLFlBQVksWUFBWTtvQkFDL0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7K0dBdklVLHNCQUFzQjttR0FBdEIsc0JBQXNCLGtSQW1CTCxXQUFXLDhHQWlCWSxnQkFBZ0IsZ0VDcEdyRSxnbUJBb0JBLHlERHVDWSxnQkFBZ0IsdVNBQXFCLDBCQUEwQjs7NEZBSzlELHNCQUFzQjtrQkFQbEMsU0FBUztpQ0FDSSxJQUFJLFdBQ1AsQ0FBQyxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSwwQkFBMEIsQ0FBQyxZQUNoRSwwQkFBMEI7OEJBWXBDLEtBQUs7c0JBREosS0FBSzt1QkFBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7Z0JBT3pCLE9BQU87c0JBRE4sS0FBSztnQkFPTixLQUFLO3NCQURKLFNBQVM7dUJBQUMsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQVl2RCxVQUFVO3NCQURULEtBQUs7Z0JBT04sR0FBRztzQkFERixTQUFTO3VCQUFDLGdCQUFnQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBT3JFLFdBQVc7c0JBRFYsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBpbmplY3QsXG4gIEluamVjdG9yLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0NvbnRhaW5lclJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNb2RlbCwgc2YgfSBmcm9tICdAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb24nO1xuaW1wb3J0IHsgTmdDb21wb25lbnRPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQW5ndWxhckR5bmFtaWNPdXRwdXQsXG4gIEFuZ3VsYXJFbmdpbmVLZXlzLFxuICBCYXNlQ29tcG9uZW50UHJvcHMsXG4gIEJhc2VDdXN0b21FdmVudCxcbiAgTmd4UmVuZGVyaW5nRW5naW5lMixcbiAgUmVuZGVyZWRNb2RlbCxcbn0gZnJvbSAnLi4vLi4vZW5naW5lJztcbmltcG9ydCB7IEtleVZhbHVlLCBSZW5kZXJlckN1c3RvbUV2ZW50IH0gZnJvbSAnLi4vLi4vZW5naW5lL3R5cGVzJztcbmltcG9ydCB7IEZvckFuZ3VsYXJNb2R1bGUgfSBmcm9tICcuLi8uLi9mb3ItYW5ndWxhci5tb2R1bGUnO1xuaW1wb3J0IHsgUmVuZGVyYWJsZSB9IGZyb20gJ0BkZWNhZi10cy91aS1kZWNvcmF0b3JzJztcbmltcG9ydCB7IENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50LXJlbmRlcmVyL2NvbXBvbmVudC1yZW5kZXJlci5jb21wb25lbnQnO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb21wb25lbnQgZm9yIHJlbmRlcmluZyBkeW5hbWljIG1vZGVsc1xuICogQHN1bW1hcnkgVGhpcyBjb21wb25lbnQgaXMgcmVzcG9uc2libGUgZm9yIGR5bmFtaWNhbGx5IHJlbmRlcmluZyBtb2RlbHMsXG4gKiBoYW5kbGluZyBtb2RlbCBjaGFuZ2VzLCBhbmQgbWFuYWdpbmcgZXZlbnQgc3Vic2NyaXB0aW9ucyBmb3IgdGhlIHJlbmRlcmVkIGNvbXBvbmVudHMuXG4gKiBJdCB1c2VzIHRoZSBOZ3hSZW5kZXJpbmdFbmdpbmUyIHRvIHJlbmRlciB0aGUgbW9kZWxzIGFuZCBzdXBwb3J0cyBib3RoIHN0cmluZyBhbmQgTW9kZWwgaW5wdXRzLlxuICogQGNsYXNzXG4gKiBAdGVtcGxhdGUgTSAtIFR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAcGFyYW0ge0luamVjdG9yfSBpbmplY3RvciAtIEFuZ3VsYXIgSW5qZWN0b3IgZm9yIGRlcGVuZGVuY3kgaW5qZWN0aW9uXG4gKiBAZXhhbXBsZVxuICogPG5neC1kZWNhZi1tb2RlbC1yZW5kZXJlclxuICogICBbbW9kZWxdPVwibXlNb2RlbFwiXG4gKiAgIFtnbG9iYWxzXT1cImdsb2JhbFZhcmlhYmxlc1wiXG4gKiAgIChsaXN0ZW5FdmVudCk9XCJoYW5kbGVFdmVudCgkZXZlbnQpXCI+XG4gKiA8L25neC1kZWNhZi1tb2RlbC1yZW5kZXJlcj5cbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQXBwXG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsUmVuZGVyZXJcbiAqICAgcGFydGljaXBhbnQgUmVuZGVyaW5nRW5naW5lXG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsXG4gKiAgIEFwcC0+Pk1vZGVsUmVuZGVyZXI6IElucHV0IG1vZGVsXG4gKiAgIE1vZGVsUmVuZGVyZXItPj5Nb2RlbDogUGFyc2UgaWYgc3RyaW5nXG4gKiAgIE1vZGVsLS0+Pk1vZGVsUmVuZGVyZXI6IFBhcnNlZCBtb2RlbFxuICogICBNb2RlbFJlbmRlcmVyLT4+UmVuZGVyaW5nRW5naW5lOiBSZW5kZXIgbW9kZWxcbiAqICAgUmVuZGVyaW5nRW5naW5lLS0+Pk1vZGVsUmVuZGVyZXI6IFJlbmRlcmVkIG91dHB1dFxuICogICBNb2RlbFJlbmRlcmVyLT4+TW9kZWxSZW5kZXJlcjogU3Vic2NyaWJlIHRvIGV2ZW50c1xuICogICBNb2RlbFJlbmRlcmVyLS0+PkFwcDogRW1pdCBldmVudHNcbiAqL1xuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtGb3JBbmd1bGFyTW9kdWxlLCBOZ0NvbXBvbmVudE91dGxldCwgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRdLFxuICBzZWxlY3RvcjogJ25neC1kZWNhZi1tb2RlbC1yZW5kZXJlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9tb2RlbC1yZW5kZXJlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9tb2RlbC1yZW5kZXJlci5jb21wb25lbnQuc2NzcycsXG59KVxuZXhwb3J0IGNsYXNzIE1vZGVsUmVuZGVyZXJDb21wb25lbnQ8TSBleHRlbmRzIE1vZGVsPlxuICBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25EZXN0cm95LCBSZW5kZXJlZE1vZGVsIHtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIElucHV0IG1vZGVsIHRvIGJlIHJlbmRlcmVkXG4gICAqIEBzdW1tYXJ5IENhbiBiZSBhIE1vZGVsIGluc3RhbmNlIG9yIGEgSlNPTiBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBtb2RlbFxuICAgKi9cbiAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSlcbiAgbW9kZWwhOiBNIHwgc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2xvYmFsIHZhcmlhYmxlcyB0byBiZSBwYXNzZWQgdG8gdGhlIHJlbmRlcmVkIGNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KClcbiAgZ2xvYmFsczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRlbXBsYXRlIHJlZmVyZW5jZSBmb3IgaW5uZXIgY29udGVudFxuICAgKi9cbiAgQFZpZXdDaGlsZCgnaW5uZXInLCB7IHJlYWQ6IFRlbXBsYXRlUmVmLCBzdGF0aWM6IHRydWUgfSlcbiAgaW5uZXI/OiBUZW1wbGF0ZVJlZjx1bmtub3duPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIE91dHB1dCBvZiB0aGUgcmVuZGVyZWQgbW9kZWxcbiAgICovXG4gIG91dHB1dD86IEFuZ3VsYXJEeW5hbWljT3V0cHV0O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSByZW5kZXJlclxuICAgKi9cbiAgQElucHV0KClcbiAgcmVuZGVyZXJJZD86IHN0cmluZztcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFZpZXcgY29udGFpbmVyIHJlZmVyZW5jZSBmb3IgZHluYW1pYyBjb21wb25lbnQgcmVuZGVyaW5nXG4gICAqL1xuICBAVmlld0NoaWxkKCdjb21wb25lbnRPdXRlcicsIHsgc3RhdGljOiB0cnVlLCByZWFkOiBWaWV3Q29udGFpbmVyUmVmIH0pXG4gIHZjciE6IFZpZXdDb250YWluZXJSZWY7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFdmVudCBlbWl0dGVyIGZvciBjdXN0b20gZXZlbnRzIGZyb20gdGhlIHJlbmRlcmVkIGNvbXBvbmVudFxuICAgKi9cbiAgQE91dHB1dCgpXG4gIGxpc3RlbkV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxSZW5kZXJlckN1c3RvbUV2ZW50PigpO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSW5zdGFuY2Ugb2YgdGhlIE5neFJlbmRlcmluZ0VuZ2luZTJcbiAgICovXG4gIHByaXZhdGUgcmVuZGVyITogTmd4UmVuZGVyaW5nRW5naW5lMjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEluc3RhbmNlIG9mIHRoZSByZW5kZXJlZCBjb21wb25lbnRcbiAgICovXG4gIHByaXZhdGUgaW5zdGFuY2UhOiBLZXlWYWx1ZSB8IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvciA9IGluamVjdChJbmplY3Rvcik7XG5cbiAgLy8gY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVmcmVzaGVzIHRoZSByZW5kZXJlZCBtb2RlbFxuICAgKiBAcGFyYW0ge3N0cmluZyB8IE19IG1vZGVsIC0gVGhlIG1vZGVsIHRvIGJlIHJlbmRlcmVkXG4gICAqL1xuICBwcml2YXRlIHJlZnJlc2gobW9kZWw6IHN0cmluZyB8IE0pIHtcbiAgICBtb2RlbCA9XG4gICAgICB0eXBlb2YgbW9kZWwgPT09ICdzdHJpbmcnXG4gICAgICAgID8gKE1vZGVsLmJ1aWxkKHt9LCBtb2RlbCkgYXMgTSlcbiAgICAgICAgOiBtb2RlbDtcbiAgICB0aGlzLm91dHB1dCA9IChtb2RlbCBhcyB1bmtub3duIGFzIFJlbmRlcmFibGUpLnJlbmRlcjxBbmd1bGFyRHluYW1pY091dHB1dD4oXG4gICAgICB0aGlzLmdsb2JhbHMgfHwge30sXG4gICAgICB0aGlzLnZjcixcbiAgICAgIHRoaXMuaW5qZWN0b3IsXG4gICAgICB0aGlzLmlubmVyLFxuICAgICk7XG4gICAgaWYgKHRoaXMub3V0cHV0Py5pbnB1dHMpXG4gICAgICB0aGlzLnJlbmRlcmVySWQgPSBzZihcbiAgICAgICAgQW5ndWxhckVuZ2luZUtleXMuUkVOREVSRURfSUQsXG4gICAgICAgICh0aGlzLm91dHB1dC5pbnB1dHMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pWydyZW5kZXJlcklkJ10gYXMgc3RyaW5nLFxuICAgICAgKTtcbiAgICB0aGlzLmluc3RhbmNlID0gdGhpcy5vdXRwdXQ/Lmluc3RhbmNlO1xuICAgIHRoaXMuc3Vic2NyaWJlRXZlbnRzKCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExpZmVjeWNsZSBob29rIHRoYXQgaXMgY2FsbGVkIHdoZW4gZGF0YS1ib3VuZCBwcm9wZXJ0aWVzIG9mIGEgZGlyZWN0aXZlIGNoYW5nZVxuICAgKiBAcGFyYW0ge1NpbXBsZUNoYW5nZXN9IGNoYW5nZXMgLSBPYmplY3QgY29udGFpbmluZyBjaGFuZ2VzXG4gICAqL1xuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbQmFzZUNvbXBvbmVudFByb3BzLk1PREVMXSkge1xuICAgICAgY29uc3QgeyBjdXJyZW50VmFsdWUgfSA9IGNoYW5nZXNbQmFzZUNvbXBvbmVudFByb3BzLk1PREVMXTtcbiAgICAgIHRoaXMucmVmcmVzaChjdXJyZW50VmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTGlmZWN5Y2xlIGhvb2sgdGhhdCBpcyBjYWxsZWQgd2hlbiBhIGRpcmVjdGl2ZSwgcGlwZSwgb3Igc2VydmljZSBpcyBkZXN0cm95ZWRcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIG5nT25EZXN0cm95KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmluc3RhbmNlKSB7XG4gICAgICB0aGlzLnVuc3Vic2NyaWJlRXZlbnRzKCk7XG4gICAgICBhd2FpdCBOZ3hSZW5kZXJpbmdFbmdpbmUyLmRlc3Ryb3koKTtcbiAgICB9XG4gICAgdGhpcy5vdXRwdXQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIHN1YnNjcmliZUV2ZW50cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pbnN0YW5jZSkge1xuICAgICAgY29uc3QgY29tcG9uZW50S2V5cyA9IE9iamVjdC5rZXlzKHRoaXMuaW5zdGFuY2UpO1xuICAgICAgZm9yIChjb25zdCBrZXkgb2YgY29tcG9uZW50S2V5cykge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuaW5zdGFuY2Vba2V5XTtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRXZlbnRFbWl0dGVyKVxuICAgICAgICAgICh0aGlzLmluc3RhbmNlIGFzIEtleVZhbHVlKVtrZXldLnN1YnNjcmliZSgoZXZlbnQ6IFBhcnRpYWw8QmFzZUN1c3RvbUV2ZW50PikgPT4ge1xuICAgICAgICAgICAgdGhpcy5saXN0ZW5FdmVudC5lbWl0KHtcbiAgICAgICAgICAgICAgY29tcG9uZW50OiB0aGlzLm91dHB1dD8uY29tcG9uZW50Lm5hbWUgfHwgJycsXG4gICAgICAgICAgICAgIG5hbWU6IGtleSxcbiAgICAgICAgICAgICAgLi4uZXZlbnQsXG4gICAgICAgICAgICB9IGFzIFJlbmRlcmVyQ3VzdG9tRXZlbnQpO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVW5zdWJzY3JpYmVzIGZyb20gZXZlbnRzIGVtaXR0ZWQgYnkgdGhlIHJlbmRlcmVkIGNvbXBvbmVudFxuICAgKi9cbiAgcHJpdmF0ZSB1bnN1YnNjcmliZUV2ZW50cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pbnN0YW5jZSkge1xuICAgICAgY29uc3QgY29tcG9uZW50S2V5cyA9IE9iamVjdC5rZXlzKHRoaXMuaW5zdGFuY2UpO1xuICAgICAgZm9yIChjb25zdCBrZXkgb2YgY29tcG9uZW50S2V5cykge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuaW5zdGFuY2Vba2V5XTtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRXZlbnRFbWl0dGVyKVxuICAgICAgICAgIHRoaXMuaW5zdGFuY2Vba2V5XS51bnN1YnNjcmliZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCByZWFkb25seSBKU09OID0gSlNPTjtcbn1cbiIsIiAgPG5nLXRlbXBsYXRlICNjb21wb25lbnRPdXRlcj48L25nLXRlbXBsYXRlPlxuICA8bmctdGVtcGxhdGUgI2lubmVyPlxuICAgIDxkaXYgIFtpZF09XCJyZW5kZXJlcklkIHx8IG51bGxcIj5cbiAgICAgIEBmb3IgKGNoaWxkIG9mIG91dHB1dD8uY2hpbGRyZW47IHRyYWNrIGNoaWxkKSB7XG4gICAgICAgIEBpZihjaGlsZD8uY2hpbGRyZW4/Lmxlbmd0aCkge1xuICAgICAgICAgIDxuZ3gtZGVjYWYtY29tcG9uZW50LXJlbmRlcmVyIFtwYXJlbnRdPVwiY2hpbGRcIiAvPlxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAjY2hpbGRDb21wb25lbnRzXG4gICAgICAgICAgICAqbmdDb21wb25lbnRPdXRsZXQ9XCJcbiAgICAgICAgICAgICAgY2hpbGQuY29tcG9uZW50O1xuICAgICAgICAgICAgICBpbmplY3RvcjogY2hpbGQuaW5qZWN0b3I7XG4gICAgICAgICAgICAgIGlucHV0czogY2hpbGQuaW5wdXRzO1xuICAgICAgICAgICAgICBjb250ZW50OmNoaWxkLmNvbnRlbnQ7XG4gICAgICAgICAgICBcIlxuICAgICAgICAgIC8+XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import { IonIcon } from '@ionic/angular/standalone';
|
|
3
|
+
import { addIcons } from 'ionicons';
|
|
4
|
+
import { chevronBackOutline, chevronForwardOutline } from 'ionicons/icons';
|
|
5
|
+
import { ForAngularModule } from '../../for-angular.module';
|
|
6
|
+
import { NgxBaseComponent } from '../../engine/NgxBaseComponent';
|
|
7
|
+
import { EventConstants } from '../../engine';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "@angular/common";
|
|
10
|
+
import * as i2 from "@ngx-translate/core";
|
|
11
|
+
/**
|
|
12
|
+
* @description A pagination component for navigating through multiple pages of content.
|
|
13
|
+
* @summary This component provides a user interface for paginated content navigation,
|
|
14
|
+
* displaying page numbers and navigation controls. It supports customizable page counts,
|
|
15
|
+
* current page tracking, and emits events when users navigate between pages.
|
|
16
|
+
*
|
|
17
|
+
* The component intelligently handles large numbers of pages by showing a subset of page
|
|
18
|
+
* numbers with ellipses to indicate skipped pages, ensuring the UI remains clean and usable
|
|
19
|
+
* even with many pages.
|
|
20
|
+
*
|
|
21
|
+
* @mermaid
|
|
22
|
+
* sequenceDiagram
|
|
23
|
+
* participant U as User
|
|
24
|
+
* participant P as PaginationComponent
|
|
25
|
+
* participant E as External Component
|
|
26
|
+
*
|
|
27
|
+
* U->>P: Click page number
|
|
28
|
+
* P->>P: navigate(page)
|
|
29
|
+
* P->>P: handleClick(direction, page)
|
|
30
|
+
* P->>E: Emit clickEvent with PaginationCustomEvent
|
|
31
|
+
*
|
|
32
|
+
* U->>P: Click next button
|
|
33
|
+
* P->>P: next()
|
|
34
|
+
* P->>P: handleClick('next')
|
|
35
|
+
* P->>E: Emit clickEvent with PaginationCustomEvent
|
|
36
|
+
*
|
|
37
|
+
* U->>P: Click previous button
|
|
38
|
+
* P->>P: previous()
|
|
39
|
+
* P->>P: handleClick('previous')
|
|
40
|
+
* P->>E: Emit clickEvent with PaginationCustomEvent
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* <ngx-decaf-pagination
|
|
44
|
+
* [pages]="10"
|
|
45
|
+
* [current]="3"
|
|
46
|
+
* (clickEvent)="handlePageChange($event)">
|
|
47
|
+
* </ngx-decaf-pagination>
|
|
48
|
+
*
|
|
49
|
+
* @extends {NgxBaseComponent}
|
|
50
|
+
* @implements {OnInit}
|
|
51
|
+
*/
|
|
52
|
+
export class PaginationComponent extends NgxBaseComponent {
|
|
53
|
+
/**
|
|
54
|
+
* @constructor
|
|
55
|
+
* @description Initializes a new instance of the PaginationComponent.
|
|
56
|
+
* Calls the parent constructor with the component name for generate base locale string.
|
|
57
|
+
*/
|
|
58
|
+
constructor() {
|
|
59
|
+
super("PaginationComponent");
|
|
60
|
+
/**
|
|
61
|
+
* @description Controls whether the component uses translation services.
|
|
62
|
+
* @summary When set to true, the component will attempt to use translation services
|
|
63
|
+
* for any text content. This allows for internationalization of the pagination component.
|
|
64
|
+
*
|
|
65
|
+
* @type {StringOrBoolean}
|
|
66
|
+
* @default true
|
|
67
|
+
* @memberOf PaginationComponent
|
|
68
|
+
*/
|
|
69
|
+
this.translatable = true;
|
|
70
|
+
/**
|
|
71
|
+
* @description The currently active page number.
|
|
72
|
+
* @summary Specifies which page is currently active or selected. This value is used
|
|
73
|
+
* to highlight the current page in the UI and as a reference point for navigation.
|
|
74
|
+
*
|
|
75
|
+
* @type {number}
|
|
76
|
+
* @default 1
|
|
77
|
+
* @memberOf PaginationComponent
|
|
78
|
+
*/
|
|
79
|
+
this.current = 1;
|
|
80
|
+
/**
|
|
81
|
+
* @description Event emitter for pagination navigation events.
|
|
82
|
+
* @summary Emits a custom event when users navigate between pages, either by clicking
|
|
83
|
+
* on page numbers or using the next/previous buttons. The event contains information
|
|
84
|
+
* about the navigation direction and the target page number.
|
|
85
|
+
*
|
|
86
|
+
* @type {EventEmitter<PaginationCustomEvent>}
|
|
87
|
+
* @memberOf PaginationComponent
|
|
88
|
+
*/
|
|
89
|
+
this.clickEvent = new EventEmitter();
|
|
90
|
+
addIcons({ chevronBackOutline, chevronForwardOutline });
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* @description Initializes the component after Angular sets the input properties.
|
|
94
|
+
* @summary Sets up the component by initializing the locale settings based on the
|
|
95
|
+
* translatable property, generating the page numbers based on the total pages and
|
|
96
|
+
* current page, and storing the last page number for boundary checking.
|
|
97
|
+
*
|
|
98
|
+
* @mermaid
|
|
99
|
+
* sequenceDiagram
|
|
100
|
+
* participant A as Angular Lifecycle
|
|
101
|
+
* participant P as PaginationComponent
|
|
102
|
+
*
|
|
103
|
+
* A->>P: ngOnInit()
|
|
104
|
+
* P->>P: getLocale(translatable)
|
|
105
|
+
* P->>P: Set locale
|
|
106
|
+
* P->>P: getPages(data, current)
|
|
107
|
+
* P->>P: Set pages array
|
|
108
|
+
* P->>P: Set last page number
|
|
109
|
+
*
|
|
110
|
+
* @returns {void}
|
|
111
|
+
* @memberOf PaginationComponent
|
|
112
|
+
*/
|
|
113
|
+
ngOnInit() {
|
|
114
|
+
this.locale = this.getLocale(this.translatable);
|
|
115
|
+
this.pages = this.getPages(this.totalPages, this.current);
|
|
116
|
+
this.last = this.totalPages;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* @description Handles click events on pagination controls.
|
|
120
|
+
* @summary Processes user interactions with the pagination component, updating the
|
|
121
|
+
* current page if specified and emitting an event with navigation details. This method
|
|
122
|
+
* is called when users click on page numbers or navigation buttons.
|
|
123
|
+
*
|
|
124
|
+
* @param {('next' | 'previous')} direction - The direction of navigation
|
|
125
|
+
* @param {number} [page] - Optional page number to navigate to directly
|
|
126
|
+
* @returns {void}
|
|
127
|
+
*
|
|
128
|
+
* @mermaid
|
|
129
|
+
* sequenceDiagram
|
|
130
|
+
* participant U as User
|
|
131
|
+
* participant P as PaginationComponent
|
|
132
|
+
* participant E as External Component
|
|
133
|
+
*
|
|
134
|
+
* U->>P: Click pagination control
|
|
135
|
+
* P->>P: handleClick(direction, page?)
|
|
136
|
+
* alt page is provided
|
|
137
|
+
* P->>P: Update current page
|
|
138
|
+
* end
|
|
139
|
+
* P->>E: Emit clickEvent with direction and page
|
|
140
|
+
*
|
|
141
|
+
* @memberOf PaginationComponent
|
|
142
|
+
*/
|
|
143
|
+
handleClick(direction, page) {
|
|
144
|
+
if (page)
|
|
145
|
+
this.current = page;
|
|
146
|
+
this.clickEvent.emit({
|
|
147
|
+
name: EventConstants.CLICK_EVENT,
|
|
148
|
+
data: {
|
|
149
|
+
direction,
|
|
150
|
+
page: this.current
|
|
151
|
+
},
|
|
152
|
+
component: this.componentName
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* @description Generates the array of page objects for display.
|
|
157
|
+
* @summary Creates an array of page objects based on the total number of pages and
|
|
158
|
+
* the current page. For small page counts (≤5), all pages are shown. For larger page
|
|
159
|
+
* counts, a subset is shown with ellipses to indicate skipped pages. This ensures
|
|
160
|
+
* the pagination UI remains clean and usable even with many pages.
|
|
161
|
+
*
|
|
162
|
+
* @param {number} total - The total number of pages
|
|
163
|
+
* @param {number} [current] - The current active page (defaults to this.current)
|
|
164
|
+
* @returns {KeyValue[]} Array of page objects with index and text properties
|
|
165
|
+
*
|
|
166
|
+
* @mermaid
|
|
167
|
+
* flowchart TD
|
|
168
|
+
* A[Start] --> B{total <= 5?}
|
|
169
|
+
* B -->|Yes| C[Show all pages]
|
|
170
|
+
* B -->|No| D[Show first page]
|
|
171
|
+
* D --> E[Show last pages]
|
|
172
|
+
* E --> F[Add ellipses for skipped pages]
|
|
173
|
+
* C --> G[Return pages array]
|
|
174
|
+
* F --> G
|
|
175
|
+
*
|
|
176
|
+
* @memberOf PaginationComponent
|
|
177
|
+
*/
|
|
178
|
+
getPages(total, current) {
|
|
179
|
+
if (!current)
|
|
180
|
+
current = this.current;
|
|
181
|
+
const pages = [];
|
|
182
|
+
function getPage(index, text = '') {
|
|
183
|
+
if (pages.some(item => item['index'] === index))
|
|
184
|
+
return;
|
|
185
|
+
pages.push({ index, text: index != null ? index.toString().padStart(2, '0') : text });
|
|
186
|
+
}
|
|
187
|
+
if (total <= 5) {
|
|
188
|
+
for (let i = 1; i <= total; i++)
|
|
189
|
+
getPage(i);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
// Adiciona os dois primeiros
|
|
193
|
+
getPage(1);
|
|
194
|
+
getPage(2);
|
|
195
|
+
// Adiciona "..." entre os blocos
|
|
196
|
+
if (current && current > 3)
|
|
197
|
+
getPage(null, '...');
|
|
198
|
+
// Adiciona a página atual (se estiver no meio)
|
|
199
|
+
if (current && current > 2 && current < total - 1)
|
|
200
|
+
getPage(current);
|
|
201
|
+
// Adiciona "..." entre os blocos
|
|
202
|
+
if (current && current < total - 2)
|
|
203
|
+
getPage(null, '...');
|
|
204
|
+
// Adiciona os dois últimos
|
|
205
|
+
getPage(total - 1);
|
|
206
|
+
getPage(total);
|
|
207
|
+
}
|
|
208
|
+
return pages;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* @description Gets the current active page number.
|
|
212
|
+
* @summary Returns the current page number that is active in the pagination component.
|
|
213
|
+
* This method provides a way to access the current page state from outside the component.
|
|
214
|
+
*
|
|
215
|
+
* @returns {number} The current page number
|
|
216
|
+
* @memberOf PaginationComponent
|
|
217
|
+
*/
|
|
218
|
+
getCurrent() {
|
|
219
|
+
return this.current;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* @description Navigates to the next page.
|
|
223
|
+
* @summary Increments the current page number if not at the last page and triggers
|
|
224
|
+
* the click event handler with 'next' direction. This method is typically called
|
|
225
|
+
* when the user clicks on the "next" button in the pagination UI.
|
|
226
|
+
*
|
|
227
|
+
* @returns {void}
|
|
228
|
+
*
|
|
229
|
+
* @mermaid
|
|
230
|
+
* sequenceDiagram
|
|
231
|
+
* participant U as User
|
|
232
|
+
* participant P as PaginationComponent
|
|
233
|
+
*
|
|
234
|
+
* U->>P: Click next button
|
|
235
|
+
* P->>P: next()
|
|
236
|
+
* alt page <= max pages
|
|
237
|
+
* P->>P: Increment current page
|
|
238
|
+
* P->>P: handleClick('next')
|
|
239
|
+
* end
|
|
240
|
+
*
|
|
241
|
+
* @memberOf PaginationComponent
|
|
242
|
+
*/
|
|
243
|
+
next() {
|
|
244
|
+
const page = this.current + 1;
|
|
245
|
+
if (page <= Object.keys(this.pages)?.length || 0) {
|
|
246
|
+
this.current = page;
|
|
247
|
+
this.handleClick('next');
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* @description Navigates to the previous page.
|
|
252
|
+
* @summary Decrements the current page number if not at the first page and triggers
|
|
253
|
+
* the click event handler with 'previous' direction. This method is typically called
|
|
254
|
+
* when the user clicks on the "previous" button in the pagination UI.
|
|
255
|
+
*
|
|
256
|
+
* @returns {void}
|
|
257
|
+
*
|
|
258
|
+
* @mermaid
|
|
259
|
+
* sequenceDiagram
|
|
260
|
+
* participant U as User
|
|
261
|
+
* participant P as PaginationComponent
|
|
262
|
+
*
|
|
263
|
+
* U->>P: Click previous button
|
|
264
|
+
* P->>P: previous()
|
|
265
|
+
* alt page > 0
|
|
266
|
+
* P->>P: Decrement current page
|
|
267
|
+
* P->>P: handleClick('previous')
|
|
268
|
+
* end
|
|
269
|
+
*
|
|
270
|
+
* @memberOf PaginationComponent
|
|
271
|
+
*/
|
|
272
|
+
previous() {
|
|
273
|
+
const page = this.current - 1;
|
|
274
|
+
if (page > 0) {
|
|
275
|
+
this.current = page;
|
|
276
|
+
this.handleClick('previous');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* @description Navigates to a specific page number.
|
|
281
|
+
* @summary Updates the current page to the specified page number and triggers
|
|
282
|
+
* the click event handler with the appropriate direction. This method is typically
|
|
283
|
+
* called when the user clicks directly on a page number in the pagination UI.
|
|
284
|
+
*
|
|
285
|
+
* @param {number | null} page - The page number to navigate to
|
|
286
|
+
* @returns {void}
|
|
287
|
+
*
|
|
288
|
+
* @mermaid
|
|
289
|
+
* sequenceDiagram
|
|
290
|
+
* participant U as User
|
|
291
|
+
* participant P as PaginationComponent
|
|
292
|
+
*
|
|
293
|
+
* U->>P: Click page number
|
|
294
|
+
* P->>P: navigate(page)
|
|
295
|
+
* alt page is not null and different from current
|
|
296
|
+
* P->>P: Determine direction (next/previous)
|
|
297
|
+
* P->>P: handleClick(direction, page)
|
|
298
|
+
* end
|
|
299
|
+
*
|
|
300
|
+
* @memberOf PaginationComponent
|
|
301
|
+
*/
|
|
302
|
+
navigate(page) {
|
|
303
|
+
if (page !== null && this.current !== page)
|
|
304
|
+
this.handleClick(page > this.current ? 'next' : 'previous', page);
|
|
305
|
+
}
|
|
306
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
307
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: PaginationComponent, isStandalone: true, selector: "ngx-decaf-pagination", inputs: { totalPages: "totalPages", current: "current" }, outputs: { clickEvent: "clickEvent" }, usesInheritance: true, ngImport: i0, template: " <div id=\"dcf-paginator-container\" class=\"dcf-flex dcf-flex-center\">\n <div class=\"dcf-width-1-1\">\n <div class=\"dcf-pagination-resume\" [innerHTML]=\"locale + '.resume' | translate: {value0: current, value1: last}\"></div>\n <div #paginationComponent class=\"dcf-pagination aeon-pagination dcf-flex-center\">\n <div\n aria-label=\"previous\"\n tabindex=\"0\"\n (click)=\"previous()\"\n (keydown.enter)=\"previous()\" [ngClass]=\"{'dcf-disabled': current === 1}\">\n <ion-icon name=\"chevron-back-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n @for(page of pages; track page) {\n <div tabindex=\"0\" (click)=\"navigate(page['index'])\"\n (keydown.enter)=\"navigate(page['index'])\"\n [ngClass]=\"{'dcf-active': current === page['index'], 'dcf-disabled': page['index'] === ndivl}\">\n <span class=\"page-item\">{{ page['text'] }}</span>\n </div>\n }\n <div\n tabindex=\"0\" (click)=\"next()\"\n (keydown.enter)=\"next()\"\n [ngClass]=\"{'dcf-disabled': current === last}\">\n <ion-icon name=\"chevron-forward-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n </div>\n </div>\n</div>\n", styles: ["#dcf-paginator-container{margin-bottom:1rem}.dcf-pagination{display:flex;flex-wrap:wrap;align-items:center;margin-left:0;padding:0;list-style:none}.dcf-pagination .page-item{display:flex;justify-content:center;align-items:top;color:var(--ion-color-gray-7);font-weight:600;width:36px;line-height:34px;padding:0!important;border-radius:50%;box-sizing:border-box}.dcf-pagination>*{flex:none;padding-left:0;position:relative;margin:0px .15rem}.dcf-pagination>*:not(.disabled){cursor:pointer}.dcf-pagination>*:hover .page-item{color:var(--ion-color-primary)}.dcf-pagination>* .page-item{color:var(--ion-color-gray-7);font-weight:600}.dcf-pagination>*.dcf-active .page-item{background:rgba(var(--ion-color-primary-rgb),.15)}.dcf-pagination>*>*{display:flex;align-items:center;column-gap:.25em;padding:5px 10px;color:var(--ion-color-gray-8);transition:color .1s ease-in-out}.dcf-pagination>*>:hover{color:var(--ion-color-gray-6);text-decoration:none}.dcf-pagination .dcf-disabled>*{opacity:.5;color:var(--ion-color-gray-6)}.dcf-pagination-resume{color:var(--ion-color-gray-8);margin:1rem 0px;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: ForAngularModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }] }); }
|
|
308
|
+
}
|
|
309
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PaginationComponent, decorators: [{
|
|
310
|
+
type: Component,
|
|
311
|
+
args: [{ selector: 'ngx-decaf-pagination', imports: [
|
|
312
|
+
ForAngularModule,
|
|
313
|
+
IonIcon
|
|
314
|
+
], standalone: true, template: " <div id=\"dcf-paginator-container\" class=\"dcf-flex dcf-flex-center\">\n <div class=\"dcf-width-1-1\">\n <div class=\"dcf-pagination-resume\" [innerHTML]=\"locale + '.resume' | translate: {value0: current, value1: last}\"></div>\n <div #paginationComponent class=\"dcf-pagination aeon-pagination dcf-flex-center\">\n <div\n aria-label=\"previous\"\n tabindex=\"0\"\n (click)=\"previous()\"\n (keydown.enter)=\"previous()\" [ngClass]=\"{'dcf-disabled': current === 1}\">\n <ion-icon name=\"chevron-back-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n @for(page of pages; track page) {\n <div tabindex=\"0\" (click)=\"navigate(page['index'])\"\n (keydown.enter)=\"navigate(page['index'])\"\n [ngClass]=\"{'dcf-active': current === page['index'], 'dcf-disabled': page['index'] === ndivl}\">\n <span class=\"page-item\">{{ page['text'] }}</span>\n </div>\n }\n <div\n tabindex=\"0\" (click)=\"next()\"\n (keydown.enter)=\"next()\"\n [ngClass]=\"{'dcf-disabled': current === last}\">\n <ion-icon name=\"chevron-forward-outline\" aria-hidden=\"true\"></ion-icon>\n </div>\n </div>\n </div>\n</div>\n", styles: ["#dcf-paginator-container{margin-bottom:1rem}.dcf-pagination{display:flex;flex-wrap:wrap;align-items:center;margin-left:0;padding:0;list-style:none}.dcf-pagination .page-item{display:flex;justify-content:center;align-items:top;color:var(--ion-color-gray-7);font-weight:600;width:36px;line-height:34px;padding:0!important;border-radius:50%;box-sizing:border-box}.dcf-pagination>*{flex:none;padding-left:0;position:relative;margin:0px .15rem}.dcf-pagination>*:not(.disabled){cursor:pointer}.dcf-pagination>*:hover .page-item{color:var(--ion-color-primary)}.dcf-pagination>* .page-item{color:var(--ion-color-gray-7);font-weight:600}.dcf-pagination>*.dcf-active .page-item{background:rgba(var(--ion-color-primary-rgb),.15)}.dcf-pagination>*>*{display:flex;align-items:center;column-gap:.25em;padding:5px 10px;color:var(--ion-color-gray-8);transition:color .1s ease-in-out}.dcf-pagination>*>:hover{color:var(--ion-color-gray-6);text-decoration:none}.dcf-pagination .dcf-disabled>*{opacity:.5;color:var(--ion-color-gray-6)}.dcf-pagination-resume{color:var(--ion-color-gray-8);margin:1rem 0px;text-align:center}\n"] }]
|
|
315
|
+
}], ctorParameters: () => [], propDecorators: { totalPages: [{
|
|
316
|
+
type: Input,
|
|
317
|
+
args: [{ required: true }]
|
|
318
|
+
}], current: [{
|
|
319
|
+
type: Input
|
|
320
|
+
}], clickEvent: [{
|
|
321
|
+
type: Output
|
|
322
|
+
}] } });
|
|
323
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnaW5hdGlvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvcGFnaW5hdGlvbi9wYWdpbmF0aW9uLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9wYWdpbmF0aW9uL3BhZ2luYXRpb24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDcEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNwQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNqRSxPQUFPLEVBQUUsY0FBYyxFQUE2QixNQUFNLGNBQWMsQ0FBQzs7OztBQUd6RTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdDRztBQVlILE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxnQkFBZ0I7SUFvRXZEOzs7O09BSUc7SUFDSDtRQUNFLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBeEUvQjs7Ozs7Ozs7V0FRRztRQUNNLGlCQUFZLEdBQW9CLElBQUksQ0FBQztRQWM5Qzs7Ozs7Ozs7V0FRRztRQUVILFlBQU8sR0FBRyxDQUFDLENBQUM7UUFxQlo7Ozs7Ozs7O1dBUUc7UUFFSCxlQUFVLEdBQXdDLElBQUksWUFBWSxFQUF5QixDQUFDO1FBU3pGLFFBQVEsQ0FBQyxFQUFDLGtCQUFrQixFQUFF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QUFLO3VCQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRTtnQkFhekIsT0FBTztzQkFETixLQUFLO2dCQWdDTixVQUFVO3NCQURULE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJb25JY29uIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXIvc3RhbmRhbG9uZSc7XG5pbXBvcnQgeyBhZGRJY29ucyB9IGZyb20gJ2lvbmljb25zJztcbmltcG9ydCB7IGNoZXZyb25CYWNrT3V0bGluZSwgY2hldnJvbkZvcndhcmRPdXRsaW5lIH0gZnJvbSAnaW9uaWNvbnMvaWNvbnMnO1xuaW1wb3J0IHsgRm9yQW5ndWxhck1vZHVsZSB9IGZyb20gJy4uLy4uL2Zvci1hbmd1bGFyLm1vZHVsZSc7XG5pbXBvcnQgeyBOZ3hCYXNlQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vZW5naW5lL05neEJhc2VDb21wb25lbnQnO1xuaW1wb3J0IHsgRXZlbnRDb25zdGFudHMsIEtleVZhbHVlLCBTdHJpbmdPckJvb2xlYW4gfSBmcm9tICcuLi8uLi9lbmdpbmUnO1xuaW1wb3J0IHsgUGFnaW5hdGlvbkN1c3RvbUV2ZW50IH0gZnJvbSAnLi9jb25zdGFudHMnO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBIHBhZ2luYXRpb24gY29tcG9uZW50IGZvciBuYXZpZ2F0aW5nIHRocm91Z2ggbXVsdGlwbGUgcGFnZXMgb2YgY29udGVudC5cbiAqIEBzdW1tYXJ5IFRoaXMgY29tcG9uZW50IHByb3ZpZGVzIGEgdXNlciBpbnRlcmZhY2UgZm9yIHBhZ2luYXRlZCBjb250ZW50IG5hdmlnYXRpb24sXG4gKiBkaXNwbGF5aW5nIHBhZ2UgbnVtYmVycyBhbmQgbmF2aWdhdGlvbiBjb250cm9scy4gSXQgc3VwcG9ydHMgY3VzdG9taXphYmxlIHBhZ2UgY291bnRzLFxuICogY3VycmVudCBwYWdlIHRyYWNraW5nLCBhbmQgZW1pdHMgZXZlbnRzIHdoZW4gdXNlcnMgbmF2aWdhdGUgYmV0d2VlbiBwYWdlcy5cbiAqXG4gKiBUaGUgY29tcG9uZW50IGludGVsbGlnZW50bHkgaGFuZGxlcyBsYXJnZSBudW1iZXJzIG9mIHBhZ2VzIGJ5IHNob3dpbmcgYSBzdWJzZXQgb2YgcGFnZVxuICogbnVtYmVycyB3aXRoIGVsbGlwc2VzIHRvIGluZGljYXRlIHNraXBwZWQgcGFnZXMsIGVuc3VyaW5nIHRoZSBVSSByZW1haW5zIGNsZWFuIGFuZCB1c2FibGVcbiAqIGV2ZW4gd2l0aCBtYW55IHBhZ2VzLlxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgVSBhcyBVc2VyXG4gKiAgIHBhcnRpY2lwYW50IFAgYXMgUGFnaW5hdGlvbkNvbXBvbmVudFxuICogICBwYXJ0aWNpcGFudCBFIGFzIEV4dGVybmFsIENvbXBvbmVudFxuICpcbiAqICAgVS0+PlA6IENsaWNrIHBhZ2UgbnVtYmVyXG4gKiAgIFAtPj5QOiBuYXZpZ2F0ZShwYWdlKVxuICogICBQLT4+UDogaGFuZGxlQ2xpY2soZGlyZWN0aW9uLCBwYWdlKVxuICogICBQLT4+RTogRW1pdCBjbGlja0V2ZW50IHdpdGggUGFnaW5hdGlvbkN1c3RvbUV2ZW50XG4gKlxuICogICBVLT4+UDogQ2xpY2sgbmV4dCBidXR0b25cbiAqICAgUC0+PlA6IG5leHQoKVxuICogICBQLT4+UDogaGFuZGxlQ2xpY2soJ25leHQnKVxuICogICBQLT4+RTogRW1pdCBjbGlja0V2ZW50IHdpdGggUGFnaW5hdGlvbkN1c3RvbUV2ZW50XG4gKlxuICogICBVLT4+UDogQ2xpY2sgcHJldmlvdXMgYnV0dG9uXG4gKiAgIFAtPj5QOiBwcmV2aW91cygpXG4gKiAgIFAtPj5QOiBoYW5kbGVDbGljaygncHJldmlvdXMnKVxuICogICBQLT4+RTogRW1pdCBjbGlja0V2ZW50IHdpdGggUGFnaW5hdGlvbkN1c3RvbUV2ZW50XG4gKlxuICogQGV4YW1wbGVcbiAqIDxuZ3gtZGVjYWYtcGFnaW5hdGlvblxuICogICBbcGFnZXNdPVwiMTBcIlxuICogICBbY3VycmVudF09XCIzXCJcbiAqICAgKGNsaWNrRXZlbnQpPVwiaGFuZGxlUGFnZUNoYW5nZSgkZXZlbnQpXCI+XG4gKiA8L25neC1kZWNhZi1wYWdpbmF0aW9uPlxuICpcbiAqIEBleHRlbmRzIHtOZ3hCYXNlQ29tcG9uZW50fVxuICogQGltcGxlbWVudHMge09uSW5pdH1cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWRlY2FmLXBhZ2luYXRpb24nLFxuICB0ZW1wbGF0ZVVybDogJy4vcGFnaW5hdGlvbi5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3BhZ2luYXRpb24uY29tcG9uZW50LnNjc3MnXSxcbiAgaW1wb3J0czogW1xuICAgIEZvckFuZ3VsYXJNb2R1bGUsXG4gICAgSW9uSWNvblxuICBdLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuXG59KVxuZXhwb3J0IGNsYXNzIFBhZ2luYXRpb25Db21wb25lbnQgZXh0ZW5kcyBOZ3hCYXNlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENvbnRyb2xzIHdoZXRoZXIgdGhlIGNvbXBvbmVudCB1c2VzIHRyYW5zbGF0aW9uIHNlcnZpY2VzLlxuICAgKiBAc3VtbWFyeSBXaGVuIHNldCB0byB0cnVlLCB0aGUgY29tcG9uZW50IHdpbGwgYXR0ZW1wdCB0byB1c2UgdHJhbnNsYXRpb24gc2VydmljZXNcbiAgICogZm9yIGFueSB0ZXh0IGNvbnRlbnQuIFRoaXMgYWxsb3dzIGZvciBpbnRlcm5hdGlvbmFsaXphdGlvbiBvZiB0aGUgcGFnaW5hdGlvbiBjb21wb25lbnQuXG4gICAqXG4gICAqIEB0eXBlIHtTdHJpbmdPckJvb2xlYW59XG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICogQG1lbWJlck9mIFBhZ2luYXRpb25Db21wb25lbnRcbiAgICovXG4gIG92ZXJyaWRlIHRyYW5zbGF0YWJsZTogU3RyaW5nT3JCb29sZWFuID0gdHJ1ZTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSB0b3RhbCBudW1iZXIgb2YgcGFnZXMgdG8gZGlzcGxheSBpbiB0aGUgcGFnaW5hdGlvbiBjb21wb25lbnQuXG4gICAqIEBzdW1tYXJ5IFNwZWNpZmllcyB0aGUgdG90YWwgbnVtYmVyIG9mIHBhZ2VzIGF2YWlsYWJsZSBmb3IgbmF2aWdhdGlvbi4gVGhpcyBpcyBhIHJlcXVpcmVkXG4gICAqIGlucHV0IHRoYXQgZGV0ZXJtaW5lcyBob3cgbWFueSBwYWdlIG51bWJlcnMgd2lsbCBiZSBnZW5lcmF0ZWQgYW5kIGRpc3BsYXllZC5cbiAgICpcbiAgICogQHR5cGUge251bWJlcn1cbiAgICogQHJlcXVpcmVkXG4gICAqIEBtZW1iZXJPZiBQYWdpbmF0aW9uQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KVxuICB0b3RhbFBhZ2VzITogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGN1cnJlbnRseSBhY3RpdmUgcGFnZSBudW1iZXIuXG4gICAqIEBzdW1tYXJ5IFNwZWNpZmllcyB3aGljaCBwYWdlIGlzIGN1cnJlbnRseSBhY3RpdmUgb3Igc2VsZWN0ZWQuIFRoaXMgdmFsdWUgaXMgdXNlZFxuICAgKiB0byBoaWdobGlnaHQgdGhlIGN1cnJlbnQgcGFnZSBpbiB0aGUgVUkgYW5kIGFzIGEgcmVmZXJlbmNlIHBvaW50IGZvciBuYXZpZ2F0aW9uLlxuICAgKlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKiBAZGVmYXVsdCAxXG4gICAqIEBtZW1iZXJPZiBQYWdpbmF0aW9uQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKVxuICBjdXJyZW50ID0gMTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFycmF5IG9mIHBhZ2Ugb2JqZWN0cyBmb3IgcmVuZGVyaW5nIGluIHRoZSB0ZW1wbGF0ZS5cbiAgICogQHN1bW1hcnkgQ29udGFpbnMgdGhlIHByb2Nlc3NlZCBwYWdlIGRhdGEgdXNlZCBmb3IgcmVuZGVyaW5nIHRoZSBwYWdpbmF0aW9uIFVJLlxuICAgKiBFYWNoIG9iamVjdCBpbmNsdWRlcyBhbiBpbmRleCAocGFnZSBudW1iZXIpIGFuZCB0ZXh0IHJlcHJlc2VudGF0aW9uLlxuICAgKlxuICAgKiBAdHlwZSB7S2V5VmFsdWVbXX1cbiAgICogQG1lbWJlck9mIFBhZ2luYXRpb25Db21wb25lbnRcbiAgICovXG4gIHBhZ2VzITogS2V5VmFsdWVbXTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBsYXN0IHBhZ2UgbnVtYmVyIGluIHRoZSBwYWdpbmF0aW9uLlxuICAgKiBAc3VtbWFyeSBTdG9yZXMgdGhlIG51bWJlciBvZiB0aGUgbGFzdCBwYWdlIGZvciBib3VuZGFyeSBjaGVja2luZyBkdXJpbmcgbmF2aWdhdGlvbi5cbiAgICpcbiAgICogQHR5cGUge251bWJlcn1cbiAgICogQG1lbWJlck9mIFBhZ2luYXRpb25Db21wb25lbnRcbiAgICovXG4gIGxhc3QhOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFdmVudCBlbWl0dGVyIGZvciBwYWdpbmF0aW9uIG5hdmlnYXRpb24gZXZlbnRzLlxuICAgKiBAc3VtbWFyeSBFbWl0cyBhIGN1c3RvbSBldmVudCB3aGVuIHVzZXJzIG5hdmlnYXRlIGJldHdlZW4gcGFnZXMsIGVpdGhlciBieSBjbGlja2luZ1xuICAgKiBvbiBwYWdlIG51bWJlcnMgb3IgdXNpbmcgdGhlIG5leHQvcHJldmlvdXMgYnV0dG9ucy4gVGhlIGV2ZW50IGNvbnRhaW5zIGluZm9ybWF0aW9uXG4gICAqIGFib3V0IHRoZSBuYXZpZ2F0aW9uIGRpcmVjdGlvbiBhbmQgdGhlIHRhcmdldCBwYWdlIG51bWJlci5cbiAgICpcbiAgICogQHR5cGUge0V2ZW50RW1pdHRlcjxQYWdpbmF0aW9uQ3VzdG9tRXZlbnQ+fVxuICAgKiBAbWVtYmVyT2YgUGFnaW5hdGlvbkNvbXBvbmVudFxuICAgKi9cbiAgQE91dHB1dCgpXG4gIGNsaWNrRXZlbnQ6IEV2ZW50RW1pdHRlcjxQYWdpbmF0aW9uQ3VzdG9tRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxQYWdpbmF0aW9uQ3VzdG9tRXZlbnQ+KCk7XG5cbiAgLyoqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKiBAZGVzY3JpcHRpb24gSW5pdGlhbGl6ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIFBhZ2luYXRpb25Db21wb25lbnQuXG4gICAqIENhbGxzIHRoZSBwYXJlbnQgY29uc3RydWN0b3Igd2l0aCB0aGUgY29tcG9uZW50IG5hbWUgZm9yIGdlbmVyYXRlIGJhc2UgbG9jYWxlIHN0cmluZy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKFwiUGFnaW5hdGlvbkNvbXBvbmVudFwiKTtcbiAgICAgYWRkSWNvbnMoe2NoZXZyb25CYWNrT3V0bGluZSwgY2hldnJvbkZvcndhcmRPdXRsaW5lfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEluaXRpYWxpemVzIHRoZSBjb21wb25lbnQgYWZ0ZXIgQW5ndWxhciBzZXRzIHRoZSBpbnB1dCBwcm9wZXJ0aWVzLlxuICAgKiBAc3VtbWFyeSBTZXRzIHVwIHRoZSBjb21wb25lbnQgYnkgaW5pdGlhbGl6aW5nIHRoZSBsb2NhbGUgc2V0dGluZ3MgYmFzZWQgb24gdGhlXG4gICAqIHRyYW5zbGF0YWJsZSBwcm9wZXJ0eSwgZ2VuZXJhdGluZyB0aGUgcGFnZSBudW1iZXJzIGJhc2VkIG9uIHRoZSB0b3RhbCBwYWdlcyBhbmRcbiAgICogY3VycmVudCBwYWdlLCBhbmQgc3RvcmluZyB0aGUgbGFzdCBwYWdlIG51bWJlciBmb3IgYm91bmRhcnkgY2hlY2tpbmcuXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEEgYXMgQW5ndWxhciBMaWZlY3ljbGVcbiAgICogICBwYXJ0aWNpcGFudCBQIGFzIFBhZ2luYXRpb25Db21wb25lbnRcbiAgICpcbiAgICogICBBLT4+UDogbmdPbkluaXQoKVxuICAgKiAgIFAtPj5QOiBnZXRMb2NhbGUodHJhbnNsYXRhYmxlKVxuICAgKiAgIFAtPj5QOiBTZXQgbG9jYWxlXG4gICAqICAgUC0+PlA6IGdldFBhZ2VzKGRhdGEsIGN1cnJlbnQpXG4gICAqICAgUC0+PlA6IFNldCBwYWdlcyBhcnJheVxuICAgKiAgIFAtPj5QOiBTZXQgbGFzdCBwYWdlIG51bWJlclxuICAgKlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICogQG1lbWJlck9mIFBhZ2luYXRpb25Db21wb25lbnRcbiAgICovXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMubG9jYWxlID0gdGhpcy5nZXRMb2NhbGUodGhpcy50cmFuc2xhdGFibGUpO1xuICAgIHRoaXMucGFnZXMgPSB0aGlzLmdldFBhZ2VzKHRoaXMudG90YWxQYWdlcywgdGhpcy5jdXJyZW50KSBhcyBLZXlWYWx1ZVtdO1xuICAgIHRoaXMubGFzdCA9IHRoaXMudG90YWxQYWdlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSGFuZGxlcyBjbGljayBldmVudHMgb24gcGFnaW5hdGlvbiBjb250cm9scy5cbiAgICogQHN1bW1hcnkgUHJvY2Vzc2VzIHVzZXIgaW50ZXJhY3Rpb25zIHdpdGggdGhlIHBhZ2luYXRpb24gY29tcG9uZW50LCB1cGRhdGluZyB0aGVcbiAgICogY3VycmVudCBwYWdlIGlmIHNwZWNpZmllZCBhbmQgZW1pdHRpbmcgYW4gZXZlbnQgd2l0aCBuYXZpZ2F0aW9uIGRldGFpbHMuIFRoaXMgbWV0aG9kXG4gICAqIGlzIGNhbGxlZCB3aGVuIHVzZXJzIGNsaWNrIG9uIHBhZ2UgbnVtYmVycyBvciBuYXZpZ2F0aW9uIGJ1dHRvbnMuXG4gICAqXG4gICAqIEBwYXJhbSB7KCduZXh0JyB8ICdwcmV2aW91cycpfSBkaXJlY3Rpb24gLSBUaGUgZGlyZWN0aW9uIG9mIG5hdmlnYXRpb25cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtwYWdlXSAtIE9wdGlvbmFsIHBhZ2UgbnVtYmVyIHRvIG5hdmlnYXRlIHRvIGRpcmVjdGx5XG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBVIGFzIFVzZXJcbiAgICogICBwYXJ0aWNpcGFudCBQIGFzIFBhZ2luYXRpb25Db21wb25lbnRcbiAgICogICBwYXJ0aWNpcGFudCBFIGFzIEV4dGVybmFsIENvbXBvbmVudFxuICAgKlxuICAgKiAgIFUtPj5QOiBDbGljayBwYWdpbmF0aW9uIGNvbnRyb2xcbiAgICogICBQLT4+UDogaGFuZGxlQ2xpY2soZGlyZWN0aW9uLCBwYWdlPylcbiAgICogICBhbHQgcGFnZSBpcyBwcm92aWRlZFxuICAgKiAgICAgUC0+PlA6IFVwZGF0ZSBjdXJyZW50IHBhZ2VcbiAgICogICBlbmRcbiAgICogICBQLT4+RTogRW1pdCBjbGlja0V2ZW50IHdpdGggZGlyZWN0aW9uIGFuZCBwYWdlXG4gICAqXG4gICAqIEBtZW1iZXJPZiBQYWdpbmF0aW9uQ29tcG9uZW50XG4gICAqL1xuICBoYW5kbGVDbGljayhkaXJlY3Rpb246ICduZXh0JyB8ICdwcmV2aW91cycsIHBhZ2U/OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZihwYWdlKVxuICAgICAgdGhpcy5jdXJyZW50ID0gcGFnZTtcbiAgICB0aGlzLmNsaWNrRXZlbnQuZW1pdCh7XG4gICAgICBuYW1lOiBFdmVudENvbnN0YW50cy5DTElDS19FVkVOVCxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgZGlyZWN0aW9uLFxuICAgICAgICBwYWdlOiB0aGlzLmN1cnJlbnRcbiAgICAgIH0sXG4gICAgICBjb21wb25lbnQ6IHRoaXMuY29tcG9uZW50TmFtZVxuICAgIH0gYXMgUGFnaW5hdGlvbkN1c3RvbUV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2VuZXJhdGVzIHRoZSBhcnJheSBvZiBwYWdlIG9iamVjdHMgZm9yIGRpc3BsYXkuXG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYW4gYXJyYXkgb2YgcGFnZSBvYmplY3RzIGJhc2VkIG9uIHRoZSB0b3RhbCBudW1iZXIgb2YgcGFnZXMgYW5kXG4gICAqIHRoZSBjdXJyZW50IHBhZ2UuIEZvciBzbWFsbCBwYWdlIGNvdW50cyAo4omkNSksIGFsbCBwYWdlcyBhcmUgc2hvd24uIEZvciBsYXJnZXIgcGFnZVxuICAgKiBjb3VudHMsIGEgc3Vic2V0IGlzIHNob3duIHdpdGggZWxsaXBzZXMgdG8gaW5kaWNhdGUgc2tpcHBlZCBwYWdlcy4gVGhpcyBlbnN1cmVzXG4gICAqIHRoZSBwYWdpbmF0aW9uIFVJIHJlbWFpbnMgY2xlYW4gYW5kIHVzYWJsZSBldmVuIHdpdGggbWFueSBwYWdlcy5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRvdGFsIC0gVGhlIHRvdGFsIG51bWJlciBvZiBwYWdlc1xuICAgKiBAcGFyYW0ge251bWJlcn0gW2N1cnJlbnRdIC0gVGhlIGN1cnJlbnQgYWN0aXZlIHBhZ2UgKGRlZmF1bHRzIHRvIHRoaXMuY3VycmVudClcbiAgICogQHJldHVybnMge0tleVZhbHVlW119IEFycmF5IG9mIHBhZ2Ugb2JqZWN0cyB3aXRoIGluZGV4IGFuZCB0ZXh0IHByb3BlcnRpZXNcbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogZmxvd2NoYXJ0IFREXG4gICAqICAgQVtTdGFydF0gLS0+IEJ7dG90YWwgPD0gNT99XG4gICAqICAgQiAtLT58WWVzfCBDW1Nob3cgYWxsIHBhZ2VzXVxuICAgKiAgIEIgLS0+fE5vfCBEW1Nob3cgZmlyc3QgcGFnZV1cbiAgICogICBEIC0tPiBFW1Nob3cgbGFzdCBwYWdlc11cbiAgICogICBFIC0tPiBGW0FkZCBlbGxpcHNlcyBmb3Igc2tpcHBlZCBwYWdlc11cbiAgICogICBDIC0tPiBHW1JldHVybiBwYWdlcyBhcnJheV1cbiAgICogICBGIC0tPiBHXG4gICAqXG4gICAqIEBtZW1iZXJPZiBQYWdpbmF0aW9uQ29tcG9uZW50XG4gICAqL1xuICBnZXRQYWdlcyh0b3RhbDogbnVtYmVyLCBjdXJyZW50PzogbnVtYmVyKTogS2V5VmFsdWVbXSB7XG4gICAgaWYgKCFjdXJyZW50KSBjdXJyZW50ID0gdGhpcy5jdXJyZW50O1xuXG4gICAgY29uc3QgcGFnZXM6IEtleVZhbHVlW10gPSBbXTtcblxuICAgIGZ1bmN0aW9uIGdldFBhZ2UoaW5kZXg6IG51bWJlciB8IG51bGwsIHRleHQgPSAnJykge1xuICAgICAgICBpZiAocGFnZXMuc29tZShpdGVtID0+IGl0ZW1bJ2luZGV4J10gPT09IGluZGV4KSkgcmV0dXJuO1xuICAgICAgICBwYWdlcy5wdXNoKHsgaW5kZXgsIHRleHQ6IGluZGV4ICE9IG51bGwgPyBpbmRleC50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJykgOiB0ZXh0IH0pO1xuICAgIH1cblxuICAgIGlmICh0b3RhbCA8PSA1KSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDw9IHRvdGFsOyBpKyspIGdldFBhZ2UoaSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEFkaWNpb25hIG9zIGRvaXMgcHJpbWVpcm9zXG4gICAgICBnZXRQYWdlKDEpO1xuICAgICAgZ2V0UGFnZSgyKTtcblxuICAgICAgLy8gQWRpY2lvbmEgXCIuLi5cIiBlbnRyZSBvcyBibG9jb3NcbiAgICAgIGlmIChjdXJyZW50ICYmIGN1cnJlbnQgPiAzKSBnZXRQYWdlKG51bGwsICcuLi4nKTtcblxuICAgICAgLy8gQWRpY2lvbmEgYSBww6FnaW5hIGF0dWFsIChzZSBlc3RpdmVyIG5vIG1laW8pXG4gICAgICBpZiAoY3VycmVudCAmJiBjdXJyZW50ID4gMiAmJiBjdXJyZW50IDwgdG90YWwgLSAxKSBnZXRQYWdlKGN1cnJlbnQpO1xuXG4gICAgICAvLyBBZGljaW9uYSBcIi4uLlwiIGVudHJlIG9zIGJsb2Nvc1xuICAgICAgaWYgKGN1cnJlbnQgJiYgY3VycmVudCA8IHRvdGFsIC0gMikgZ2V0UGFnZShudWxsLCAnLi4uJyk7XG5cbiAgICAgIC8vIEFkaWNpb25hIG9zIGRvaXMgw7psdGltb3NcbiAgICAgIGdldFBhZ2UodG90YWwgLSAxKTtcbiAgICAgIGdldFBhZ2UodG90YWwpO1xuICAgIH1cblxuICAgIHJldHVybiBwYWdlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgY3VycmVudCBhY3RpdmUgcGFnZSBudW1iZXIuXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGN1cnJlbnQgcGFnZSBudW1iZXIgdGhhdCBpcyBhY3RpdmUgaW4gdGhlIHBhZ2luYXRpb24gY29tcG9uZW50LlxuICAgKiBUaGlzIG1ldGhvZCBwcm92aWRlcyBhIHdheSB0byBhY2Nlc3MgdGhlIGN1cnJlbnQgcGFnZSBzdGF0ZSBmcm9tIG91dHNpZGUgdGhlIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHJldHVybnMge251bWJlcn0gVGhlIGN1cnJlbnQgcGFnZSBudW1iZXJcbiAgICogQG1lbWJlck9mIFBhZ2luYXRpb25Db21wb25lbnRcbiAgICovXG4gIGdldEN1cnJlbnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5jdXJyZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBOYXZpZ2F0ZXMgdG8gdGhlIG5leHQgcGFnZS5cbiAgICogQHN1bW1hcnkgSW5jcmVtZW50cyB0aGUgY3VycmVudCBwYWdlIG51bWJlciBpZiBub3QgYXQgdGhlIGxhc3QgcGFnZSBhbmQgdHJpZ2dlcnNcbiAgICogdGhlIGNsaWNrIGV2ZW50IGhhbmRsZXIgd2l0aCAnbmV4dCcgZGlyZWN0aW9uLiBUaGlzIG1ldGhvZCBpcyB0eXBpY2FsbHkgY2FsbGVkXG4gICAqIHdoZW4gdGhlIHVzZXIgY2xpY2tzIG9uIHRoZSBcIm5leHRcIiBidXR0b24gaW4gdGhlIHBhZ2luYXRpb24gVUkuXG4gICAqXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBVIGFzIFVzZXJcbiAgICogICBwYXJ0aWNpcGFudCBQIGFzIFBhZ2luYXRpb25Db21wb25lbnRcbiAgICpcbiAgICogICBVLT4+UDogQ2xpY2sgbmV4dCBidXR0b25cbiAgICogICBQLT4+UDogbmV4dCgpXG4gICAqICAgYWx0IHBhZ2UgPD0gbWF4IHBhZ2VzXG4gICAqICAgICBQLT4+UDogSW5jcmVtZW50IGN1cnJlbnQgcGFnZVxuICAgKiAgICAgUC0+PlA6IGhhbmRsZUNsaWNrKCduZXh0JylcbiAgICogICBlbmRcbiAgICpcbiAgICogQG1lbWJlck9mIFBhZ2luYXRpb25Db21wb25lbnRcbiAgICovXG4gIG5leHQoKTogdm9pZCB7XG4gICAgY29uc3QgcGFnZSA9IHRoaXMuY3VycmVudCArIDE7XG4gICAgaWYocGFnZSA8PSBPYmplY3Qua2V5cyh0aGlzLnBhZ2VzKT8ubGVuZ3RoIHx8IDApIHtcbiAgICAgIHRoaXMuY3VycmVudCA9IHBhZ2U7XG4gICAgICB0aGlzLmhhbmRsZUNsaWNrKCduZXh0Jyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBOYXZpZ2F0ZXMgdG8gdGhlIHByZXZpb3VzIHBhZ2UuXG4gICAqIEBzdW1tYXJ5IERlY3JlbWVudHMgdGhlIGN1cnJlbnQgcGFnZSBudW1iZXIgaWYgbm90IGF0IHRoZSBmaXJzdCBwYWdlIGFuZCB0cmlnZ2Vyc1xuICAgKiB0aGUgY2xpY2sgZXZlbnQgaGFuZGxlciB3aXRoICdwcmV2aW91cycgZGlyZWN0aW9uLiBUaGlzIG1ldGhvZCBpcyB0eXBpY2FsbHkgY2FsbGVkXG4gICAqIHdoZW4gdGhlIHVzZXIgY2xpY2tzIG9uIHRoZSBcInByZXZpb3VzXCIgYnV0dG9uIGluIHRoZSBwYWdpbmF0aW9uIFVJLlxuICAgKlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgVSBhcyBVc2VyXG4gICAqICAgcGFydGljaXBhbnQgUCBhcyBQYWdpbmF0aW9uQ29tcG9uZW50XG4gICAqXG4gICAqICAgVS0+PlA6IENsaWNrIHByZXZpb3VzIGJ1dHRvblxuICAgKiAgIFAtPj5QOiBwcmV2aW91cygpXG4gICAqICAgYWx0IHBhZ2UgPiAwXG4gICAqICAgICBQLT4+UDogRGVjcmVtZW50IGN1cnJlbnQgcGFnZVxuICAgKiAgICAgUC0+PlA6IGhhbmRsZUNsaWNrKCdwcmV2aW91cycpXG4gICAqICAgZW5kXG4gICAqXG4gICAqIEBtZW1iZXJPZiBQYWdpbmF0aW9uQ29tcG9uZW50XG4gICAqL1xuICBwcmV2aW91cygpOiB2b2lkIHtcbiAgICBjb25zdCBwYWdlID0gdGhpcy5jdXJyZW50IC0gMTtcbiAgICBpZihwYWdlID4gMCkge1xuICAgICAgdGhpcy5jdXJyZW50ID0gcGFnZTtcbiAgICAgIHRoaXMuaGFuZGxlQ2xpY2soJ3ByZXZpb3VzJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBOYXZpZ2F0ZXMgdG8gYSBzcGVjaWZpYyBwYWdlIG51bWJlci5cbiAgICogQHN1bW1hcnkgVXBkYXRlcyB0aGUgY3VycmVudCBwYWdlIHRvIHRoZSBzcGVjaWZpZWQgcGFnZSBudW1iZXIgYW5kIHRyaWdnZXJzXG4gICAqIHRoZSBjbGljayBldmVudCBoYW5kbGVyIHdpdGggdGhlIGFwcHJvcHJpYXRlIGRpcmVjdGlvbi4gVGhpcyBtZXRob2QgaXMgdHlwaWNhbGx5XG4gICAqIGNhbGxlZCB3aGVuIHRoZSB1c2VyIGNsaWNrcyBkaXJlY3RseSBvbiBhIHBhZ2UgbnVtYmVyIGluIHRoZSBwYWdpbmF0aW9uIFVJLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlciB8IG51bGx9IHBhZ2UgLSBUaGUgcGFnZSBudW1iZXIgdG8gbmF2aWdhdGUgdG9cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IFUgYXMgVXNlclxuICAgKiAgIHBhcnRpY2lwYW50IFAgYXMgUGFnaW5hdGlvbkNvbXBvbmVudFxuICAgKlxuICAgKiAgIFUtPj5QOiBDbGljayBwYWdlIG51bWJlclxuICAgKiAgIFAtPj5QOiBuYXZpZ2F0ZShwYWdlKVxuICAgKiAgIGFsdCBwYWdlIGlzIG5vdCBudWxsIGFuZCBkaWZmZXJlbnQgZnJvbSBjdXJyZW50XG4gICAqICAgICBQLT4+UDogRGV0ZXJtaW5lIGRpcmVjdGlvbiAobmV4dC9wcmV2aW91cylcbiAgICogICAgIFAtPj5QOiBoYW5kbGVDbGljayhkaXJlY3Rpb24sIHBhZ2UpXG4gICAqICAgZW5kXG4gICAqXG4gICAqIEBtZW1iZXJPZiBQYWdpbmF0aW9uQ29tcG9uZW50XG4gICAqL1xuICBuYXZpZ2F0ZShwYWdlOiBudW1iZXIgfCBudWxsKTogdm9pZCB7XG4gICAgaWYocGFnZSAhPT0gbnVsbCAmJiB0aGlzLmN1cnJlbnQgIT09IHBhZ2UgYXMgbnVtYmVyKVxuICAgICAgdGhpcy5oYW5kbGVDbGljayhwYWdlID4gdGhpcy5jdXJyZW50ID8gJ25leHQnIDogJ3ByZXZpb3VzJywgcGFnZSk7XG4gIH1cbn1cbiIsIiA8ZGl2IGlkPVwiZGNmLXBhZ2luYXRvci1jb250YWluZXJcIiBjbGFzcz1cImRjZi1mbGV4IGRjZi1mbGV4LWNlbnRlclwiPlxuICA8ZGl2IGNsYXNzPVwiZGNmLXdpZHRoLTEtMVwiPlxuICAgIDxkaXYgY2xhc3M9XCJkY2YtcGFnaW5hdGlvbi1yZXN1bWVcIiBbaW5uZXJIVE1MXT1cImxvY2FsZSArICcucmVzdW1lJyB8IHRyYW5zbGF0ZToge3ZhbHVlMDogY3VycmVudCwgdmFsdWUxOiBsYXN0fVwiPjwvZGl2PlxuICAgIDxkaXYgI3BhZ2luYXRpb25Db21wb25lbnQgY2xhc3M9XCJkY2YtcGFnaW5hdGlvbiBhZW9uLXBhZ2luYXRpb24gZGNmLWZsZXgtY2VudGVyXCI+XG4gICAgICA8ZGl2XG4gICAgICAgIGFyaWEtbGFiZWw9XCJwcmV2aW91c1wiXG4gICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgIChjbGljayk9XCJwcmV2aW91cygpXCJcbiAgICAgICAgKGtleWRvd24uZW50ZXIpPVwicHJldmlvdXMoKVwiIFtuZ0NsYXNzXT1cInsnZGNmLWRpc2FibGVkJzogY3VycmVudCA9PT0gMX1cIj5cbiAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJjaGV2cm9uLWJhY2stb3V0bGluZVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaW9uLWljb24+XG4gICAgICA8L2Rpdj5cbiAgICAgIEBmb3IocGFnZSBvZiBwYWdlczsgdHJhY2sgcGFnZSkge1xuICAgICAgICA8ZGl2IHRhYmluZGV4PVwiMFwiIChjbGljayk9XCJuYXZpZ2F0ZShwYWdlWydpbmRleCddKVwiXG4gICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwibmF2aWdhdGUocGFnZVsnaW5kZXgnXSlcIlxuICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZGNmLWFjdGl2ZSc6IGN1cnJlbnQgPT09IHBhZ2VbJ2luZGV4J10sICdkY2YtZGlzYWJsZWQnOiBwYWdlWydpbmRleCddID09PSBuZGl2bH1cIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInBhZ2UtaXRlbVwiPnt7IHBhZ2VbJ3RleHQnXSB9fTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgICA8ZGl2XG4gICAgICAgIHRhYmluZGV4PVwiMFwiIChjbGljayk9XCJuZXh0KClcIlxuICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCJuZXh0KClcIlxuICAgICAgICBbbmdDbGFzc109XCJ7J2RjZi1kaXNhYmxlZCc6IGN1cnJlbnQgPT09IGxhc3R9XCI+XG4gICAgICAgIDxpb24taWNvbiBuYW1lPVwiY2hldnJvbi1mb3J3YXJkLW91dGxpbmVcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2lvbi1pY29uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=
|