@ceriousdevtech/ngx-cerious-scroll 1.0.7 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/esm2022/lib/cerious-scroll.component.mjs +12 -1
- package/esm2022/lib/cerious-scroll.directive.mjs +107 -19
- package/esm2022/lib/cerious-scroll.service.mjs +6 -4
- package/esm2022/lib/cerious-scroll.types.mjs +1 -1
- package/esm2022/public-api.mjs +1 -1
- package/fesm2022/ceriousdevtech-ngx-cerious-scroll.mjs +122 -21
- package/fesm2022/ceriousdevtech-ngx-cerious-scroll.mjs.map +1 -1
- package/lib/cerious-scroll.component.d.ts +7 -0
- package/lib/cerious-scroll.directive.d.ts +9 -2
- package/lib/cerious-scroll.types.d.ts +8 -1
- package/package.json +2 -2
- package/public-api.d.ts +1 -0
package/README.md
CHANGED
|
@@ -233,6 +233,7 @@ Both the component and directive expose:
|
|
|
233
233
|
|--------|-------------|
|
|
234
234
|
| `render()` | Trigger a manual render pass. |
|
|
235
235
|
| `recalculate()` | Discard all cached row heights and re-measure the viewport. |
|
|
236
|
+
| `jumpToItem(index, screenOffset?)` | Jump to a card in Masonry mode. |
|
|
236
237
|
|
|
237
238
|
**When to call `recalculate()`:** only when the heights of rows you've *already
|
|
238
239
|
rendered* change without their indices changing — e.g. a global font/density
|
|
@@ -267,6 +268,26 @@ Usage in templates:
|
|
|
267
268
|
</ng-template>
|
|
268
269
|
```
|
|
269
270
|
|
|
271
|
+
## Masonry Layout
|
|
272
|
+
|
|
273
|
+
Use `layout: 'masonry'` with the normal Angular item template. The directive
|
|
274
|
+
supplies the core engine's DOM renderer internally:
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
readonly options: CeriousScrollOptions = {
|
|
278
|
+
layout: 'masonry',
|
|
279
|
+
masonry: {
|
|
280
|
+
getItemHeight: (_index, width) => width * 0.75 + 48,
|
|
281
|
+
targetColumnWidth: 280,
|
|
282
|
+
gap: 16,
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Supplying `getItemHeight` gives canonical, reproducible placement. Omit it for
|
|
288
|
+
dynamic DOM-measured cards. Use `jumpToItem()` rather than `jumpToElement()` for
|
|
289
|
+
card navigation.
|
|
290
|
+
|
|
270
291
|
## Table Layout
|
|
271
292
|
|
|
272
293
|
Pass `[ceriousScrollOptions]="{ layout: 'table' }"` to render **real `<table>` / `<tr>` / `<td>` rows** with a frozen header and native column alignment — while keeping O(1) virtualization. The row template returns the row's `<td>` cells; `[ceriousScrollHeaderTemplate]` provides the `<thead>` row (it updates via change detection):
|
|
@@ -7,6 +7,17 @@ export class CeriousScrollComponent {
|
|
|
7
7
|
constructor(ceriousScroll) {
|
|
8
8
|
this.ceriousScroll = ceriousScroll;
|
|
9
9
|
}
|
|
10
|
+
get scroller() { return this.ceriousScroll.scroller; }
|
|
11
|
+
render() { return this.ceriousScroll.render(); }
|
|
12
|
+
jumpToElement(index) { return this.ceriousScroll.jumpToElement(index); }
|
|
13
|
+
jumpToItem(index, screenOffset = 0) {
|
|
14
|
+
return this.ceriousScroll.jumpToItem(index, screenOffset);
|
|
15
|
+
}
|
|
16
|
+
scrollToPercentage(percentage) {
|
|
17
|
+
return this.ceriousScroll.scrollToPercentage(percentage);
|
|
18
|
+
}
|
|
19
|
+
reset() { return this.ceriousScroll.reset(); }
|
|
20
|
+
recalculate() { return this.ceriousScroll.recalculate(); }
|
|
10
21
|
ngAfterContentInit() {
|
|
11
22
|
if (this.ceriousScroll.ceriousScrollItemTemplate)
|
|
12
23
|
return;
|
|
@@ -46,4 +57,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
46
57
|
type: ContentChild,
|
|
47
58
|
args: [CeriousScrollItemTemplateDirective]
|
|
48
59
|
}] } });
|
|
49
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
60
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNlcmlvdXMtc2Nyb2xsL3NyYy9saWIvY2VyaW91cy1zY3JvbGwuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFlBQVksR0FFYixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRSxPQUFPLEVBQ0wsa0NBQWtDLEdBRW5DLE1BQU0sMENBQTBDLENBQUM7OztBQWlDbEQsTUFBTSxPQUFPLHNCQUFzQjtJQUtqQyxZQUE2QixhQUE0QztRQUE1QyxrQkFBYSxHQUFiLGFBQWEsQ0FBK0I7SUFBRyxDQUFDO0lBRTdFLElBQUksUUFBUSxLQUFLLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ3RELE1BQU0sS0FBSyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2hELGFBQWEsQ0FBQyxLQUFhLElBQUksT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEYsVUFBVSxDQUFDLEtBQWEsRUFBRSxZQUFZLEdBQUcsQ0FBQztRQUN4QyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBQ0Qsa0JBQWtCLENBQUMsVUFBa0I7UUFDbkMsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFDRCxLQUFLLEtBQUssT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM5QyxXQUFXLEtBQUssT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUUxRCxrQkFBa0I7UUFDaEIsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLHlCQUF5QjtZQUFFLE9BQU87UUFDekQsSUFBSSxDQUFDLElBQUksQ0FBQyxxQkFBcUI7WUFBRSxPQUFPO1FBRXhDLElBQUksQ0FBQyxhQUFhLENBQUMseUJBQXlCO1lBQzFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxXQUFtRSxDQUFDO1FBRWpHLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1lBQy9DLGNBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDcEQsQ0FBQztJQUNILENBQUM7K0dBN0JVLHNCQUFzQjttR0FBdEIsc0JBQXNCLDZIQUVuQixrQ0FBa0MseWlCQVZ0QyxnQkFBZ0I7OzRGQVFmLHNCQUFzQjtrQkEvQmxDLFNBQVM7K0JBQ0UsZ0JBQWdCLGNBQ2QsSUFBSSxXQUNQLEVBQUUsa0JBQ0s7d0JBQ2Q7NEJBQ0UsU0FBUyxFQUFFLHNCQUFzQjs0QkFDakMsTUFBTSxFQUFFO2dDQUNOLDJDQUEyQztnQ0FDM0MsMkJBQTJCO2dDQUMzQiwrQkFBK0I7Z0NBQy9CLHlDQUF5QztnQ0FDekMsNkNBQTZDO2dDQUM3QywrQkFBK0I7Z0NBQy9CLHFDQUFxQzs2QkFDdEM7NEJBQ0QsT0FBTyxFQUFFO2dDQUNQLDZDQUE2QztnQ0FDN0MsaURBQWlEO2dDQUNqRCxtQ0FBbUM7NkJBQ3BDO3lCQUNGO3FCQUNGLFlBQ1MsZ0JBQWdCLG1CQU1ULHVCQUF1QixDQUFDLE1BQU07MkZBSzlCLHFCQUFxQjtzQkFEckMsWUFBWTt1QkFBQyxrQ0FBa0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGQsXG4gIFRlbXBsYXRlUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgQ2VyaW91c1Njcm9sbERpcmVjdGl2ZSB9IGZyb20gJy4vY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlJztcbmltcG9ydCB7XG4gIENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVEaXJlY3RpdmUsXG4gIHR5cGUgQ2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQsXG59IGZyb20gJy4vY2VyaW91cy1zY3JvbGwtaXRlbS10ZW1wbGF0ZS5kaXJlY3RpdmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjZXJpb3VzLXNjcm9sbCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtdLFxuICBob3N0RGlyZWN0aXZlczogW1xuICAgIHtcbiAgICAgIGRpcmVjdGl2ZTogQ2VyaW91c1Njcm9sbERpcmVjdGl2ZSxcbiAgICAgIGlucHV0czogW1xuICAgICAgICAnY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHM6IHRvdGFsRWxlbWVudHMnLFxuICAgICAgICAnY2VyaW91c1Njcm9sbEl0ZW1zOiBpdGVtcycsXG4gICAgICAgICdjZXJpb3VzU2Nyb2xsR2V0SXRlbTogZ2V0SXRlbScsXG4gICAgICAgICdjZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlOiBpdGVtVGVtcGxhdGUnLFxuICAgICAgICAnY2VyaW91c1Njcm9sbEhlYWRlclRlbXBsYXRlOiBoZWFkZXJUZW1wbGF0ZScsXG4gICAgICAgICdjZXJpb3VzU2Nyb2xsT3B0aW9uczogb3B0aW9ucycsXG4gICAgICAgICdjZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcjogYXV0b1JlbmRlcicsXG4gICAgICBdLFxuICAgICAgb3V0cHV0czogW1xuICAgICAgICAnY2VyaW91c1Njcm9sbFZpZXdwb3J0Q2hhbmdlOiB2aWV3cG9ydENoYW5nZScsXG4gICAgICAgICdjZXJpb3VzU2Nyb2xsTWVhc3VyZWRWaWV3cG9ydDogbWVhc3VyZWRWaWV3cG9ydCcsXG4gICAgICAgICdjZXJpb3VzU2Nyb2xsUmVhZHk6IHNjcm9sbGVyUmVhZHknLFxuICAgICAgXSxcbiAgICB9LFxuICBdLFxuICB0ZW1wbGF0ZTogYDxuZy1jb250ZW50IC8+YCxcbiAgc3R5bGVzOiBgXG4gICAgOmhvc3Qge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgfVxuICBgLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgQ2VyaW91c1Njcm9sbENvbXBvbmVudDxUSXRlbSA9IHVua25vd24+IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCB7XG4gIC8qKiBPcHRpb25hbCBjb252ZW5pZW5jZSB0ZW1wbGF0ZSBtYXJrZXI6IDxuZy10ZW1wbGF0ZSBjZXJpb3VzU2Nyb2xsSXRlbSBsZXQtaXRlbSBsZXQtaW5kZXg9XCJpbmRleFwiPi4uLjwvbmctdGVtcGxhdGU+ICovXG4gIEBDb250ZW50Q2hpbGQoQ2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZURpcmVjdGl2ZSlcbiAgcHJpdmF0ZSByZWFkb25seSBwcm9qZWN0ZWRJdGVtVGVtcGxhdGU/OiBDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlRGlyZWN0aXZlPFRJdGVtPjtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGNlcmlvdXNTY3JvbGw6IENlcmlvdXNTY3JvbGxEaXJlY3RpdmU8VEl0ZW0+KSB7fVxuXG4gIGdldCBzY3JvbGxlcigpIHsgcmV0dXJuIHRoaXMuY2VyaW91c1Njcm9sbC5zY3JvbGxlcjsgfVxuICByZW5kZXIoKSB7IHJldHVybiB0aGlzLmNlcmlvdXNTY3JvbGwucmVuZGVyKCk7IH1cbiAganVtcFRvRWxlbWVudChpbmRleDogbnVtYmVyKSB7IHJldHVybiB0aGlzLmNlcmlvdXNTY3JvbGwuanVtcFRvRWxlbWVudChpbmRleCk7IH1cbiAganVtcFRvSXRlbShpbmRleDogbnVtYmVyLCBzY3JlZW5PZmZzZXQgPSAwKSB7XG4gICAgcmV0dXJuIHRoaXMuY2VyaW91c1Njcm9sbC5qdW1wVG9JdGVtKGluZGV4LCBzY3JlZW5PZmZzZXQpO1xuICB9XG4gIHNjcm9sbFRvUGVyY2VudGFnZShwZXJjZW50YWdlOiBudW1iZXIpIHtcbiAgICByZXR1cm4gdGhpcy5jZXJpb3VzU2Nyb2xsLnNjcm9sbFRvUGVyY2VudGFnZShwZXJjZW50YWdlKTtcbiAgfVxuICByZXNldCgpIHsgcmV0dXJuIHRoaXMuY2VyaW91c1Njcm9sbC5yZXNldCgpOyB9XG4gIHJlY2FsY3VsYXRlKCkgeyByZXR1cm4gdGhpcy5jZXJpb3VzU2Nyb2xsLnJlY2FsY3VsYXRlKCk7IH1cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2VyaW91c1Njcm9sbC5jZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlKSByZXR1cm47XG4gICAgaWYgKCF0aGlzLnByb2plY3RlZEl0ZW1UZW1wbGF0ZSkgcmV0dXJuO1xuXG4gICAgdGhpcy5jZXJpb3VzU2Nyb2xsLmNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGUgPVxuICAgICAgdGhpcy5wcm9qZWN0ZWRJdGVtVGVtcGxhdGUudGVtcGxhdGVSZWYgYXMgVGVtcGxhdGVSZWY8Q2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQ8VEl0ZW0+PjtcblxuICAgIGlmICh0aGlzLmNlcmlvdXNTY3JvbGwuY2VyaW91c1Njcm9sbEF1dG9SZW5kZXIpIHtcbiAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHRoaXMuY2VyaW91c1Njcm9sbC5yZW5kZXIoKSk7XG4gICAgfVxuICB9XG59XG4iXX0=
|
|
@@ -10,6 +10,10 @@ function coerceTotalElements(explicitTotal, itemsLen) {
|
|
|
10
10
|
return Math.max(1, candidate);
|
|
11
11
|
}
|
|
12
12
|
export class CeriousScrollDirective {
|
|
13
|
+
/** Underlying core engine instance, or null before initialization. */
|
|
14
|
+
get scroller() {
|
|
15
|
+
return this.hostRef?.scroller ?? null;
|
|
16
|
+
}
|
|
13
17
|
constructor(host, appRef, ngZone, cerious) {
|
|
14
18
|
this.host = host;
|
|
15
19
|
this.appRef = appRef;
|
|
@@ -42,6 +46,10 @@ export class CeriousScrollDirective {
|
|
|
42
46
|
this.hostRef = null;
|
|
43
47
|
this.viewportSub = null;
|
|
44
48
|
this.scheduledRenderFrame = null;
|
|
49
|
+
// Incremented by the core-owned Masonry renderer whenever it mounts a probe
|
|
50
|
+
// or visible card. Unlike row mode, those calls do not flow through the
|
|
51
|
+
// ElementRenderer passed to renderViewport().
|
|
52
|
+
this.masonryRendererEpoch = 0;
|
|
45
53
|
this.viewByContainer = new Map();
|
|
46
54
|
// Pool of views detached because their container left the viewport. Reusing
|
|
47
55
|
// them on subsequent renders avoids destroying + recreating the entire row
|
|
@@ -60,19 +68,36 @@ export class CeriousScrollDirective {
|
|
|
60
68
|
return;
|
|
61
69
|
if (changes['ceriousScrollItems'] || changes['ceriousScrollTotalElements']) {
|
|
62
70
|
const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);
|
|
63
|
-
const
|
|
71
|
+
const masonryMode = this.ceriousScrollOptions.layout === 'masonry';
|
|
72
|
+
const currentCount = masonryMode
|
|
73
|
+
? this.hostRef.scroller.itemCount
|
|
74
|
+
: this.hostRef.scroller.totalElements;
|
|
75
|
+
const countChanged = currentCount !== total;
|
|
64
76
|
if (countChanged) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
this
|
|
77
|
+
if (masonryMode) {
|
|
78
|
+
// Masonry's renderer owns card-count-derived segment state. Recreate
|
|
79
|
+
// it when the dataset size changes rather than updating segment count
|
|
80
|
+
// through the row-oriented updateTotalElements API.
|
|
81
|
+
this.recreate();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Grow/shrink the dataset IN PLACE — no recreate. updateTotalElements
|
|
85
|
+
// propagates the new count to every subsystem, INCLUDING the
|
|
86
|
+
// ViewportRenderer's own copy of totalElements (it used to go stale,
|
|
87
|
+
// which is exactly why this recreated: the renderer kept the old count
|
|
88
|
+
// for its viewport-fill loop and bottom scan, producing phantom
|
|
89
|
+
// out-of-bounds renders). In place keeps the scroll position and an
|
|
90
|
+
// in-progress scrollbar drag alive, and a growing dataset keeps a stable
|
|
91
|
+
// bottom index (no bouncing tail). The track lengthens, so re-sync the
|
|
92
|
+
// thumb afterwards.
|
|
93
|
+
this.hostRef.scroller.updateTotalElements(total);
|
|
94
|
+
// A shrink can leave the position past the new end — clamp it.
|
|
95
|
+
if (this.hostRef.scroller.currentElement > total - 1) {
|
|
96
|
+
this.hostRef.scroller.jumpToElement(total - 1);
|
|
97
|
+
}
|
|
98
|
+
if (this.ceriousScrollAutoRender)
|
|
99
|
+
this.render();
|
|
100
|
+
this.hostRef.scroller.syncScrollbar();
|
|
76
101
|
}
|
|
77
102
|
else if (this.ceriousScrollAutoRender) {
|
|
78
103
|
// Same count, new data reference (e.g. an immutable edit or a sort that
|
|
@@ -131,8 +156,11 @@ export class CeriousScrollDirective {
|
|
|
131
156
|
// for the whole pass is handled by the caller (`scheduleRender`).
|
|
132
157
|
this.renderTemplateIntoContainer(template, index, elementContainer);
|
|
133
158
|
};
|
|
159
|
+
const masonryMode = this.ceriousScrollOptions.layout === 'masonry';
|
|
160
|
+
const masonryEpochBefore = this.masonryRendererEpoch;
|
|
134
161
|
const range = this.hostRef.scroller.renderViewport(height, contentContainer, renderer);
|
|
135
|
-
|
|
162
|
+
const masonryInvocations = this.masonryRendererEpoch - masonryEpochBefore;
|
|
163
|
+
if (rendererInvocations === 0 && (!masonryMode || masonryInvocations === 0)) {
|
|
136
164
|
// Viewport didn't change — skip the prune walk and the (potentially
|
|
137
165
|
// zone-entering) emit.
|
|
138
166
|
return range;
|
|
@@ -155,11 +183,19 @@ export class CeriousScrollDirective {
|
|
|
155
183
|
if (!this.hostRef || this.viewByContainer.size === 0)
|
|
156
184
|
return;
|
|
157
185
|
const scroller = this.hostRef.scroller;
|
|
186
|
+
const masonryMode = this.ceriousScrollOptions.layout === 'masonry';
|
|
158
187
|
const active = new Set();
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
active.add(el);
|
|
188
|
+
if (masonryMode) {
|
|
189
|
+
this.host.nativeElement
|
|
190
|
+
.querySelectorAll('[data-element-index]')
|
|
191
|
+
.forEach((el) => active.add(el));
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
for (const index of scroller.getRenderedIndices()) {
|
|
195
|
+
const el = scroller.getRenderedElement(index);
|
|
196
|
+
if (el)
|
|
197
|
+
active.add(el);
|
|
198
|
+
}
|
|
163
199
|
}
|
|
164
200
|
for (const [container, view] of this.viewByContainer) {
|
|
165
201
|
if (!active.has(container)) {
|
|
@@ -224,6 +260,13 @@ export class CeriousScrollDirective {
|
|
|
224
260
|
this.hostRef.scroller.jumpToElement(index);
|
|
225
261
|
return this.render();
|
|
226
262
|
}
|
|
263
|
+
/** Masonry mode only: jump directly to a card index, then render. */
|
|
264
|
+
jumpToItem(index, screenOffset = 0) {
|
|
265
|
+
if (!this.hostRef)
|
|
266
|
+
return null;
|
|
267
|
+
this.hostRef.scroller.jumpToItem(index, screenOffset);
|
|
268
|
+
return this.render();
|
|
269
|
+
}
|
|
227
270
|
/** Scroll to a percentage (0..100), then render. */
|
|
228
271
|
scrollToPercentage(percentage) {
|
|
229
272
|
if (!this.hostRef)
|
|
@@ -253,7 +296,33 @@ export class CeriousScrollDirective {
|
|
|
253
296
|
const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);
|
|
254
297
|
// Table mode: capture the engine-created <thead> so we can render the
|
|
255
298
|
// declarative header template into it (and still run any user header hook).
|
|
256
|
-
let options
|
|
299
|
+
let options;
|
|
300
|
+
if (this.ceriousScrollOptions.layout === 'masonry') {
|
|
301
|
+
if (!this.ceriousScrollOptions.masonry) {
|
|
302
|
+
throw new Error("CeriousScrollDirective: layout 'masonry' requires `ceriousScrollOptions.masonry`.");
|
|
303
|
+
}
|
|
304
|
+
options = {
|
|
305
|
+
...this.ceriousScrollOptions,
|
|
306
|
+
masonry: {
|
|
307
|
+
...this.ceriousScrollOptions.masonry,
|
|
308
|
+
renderItem: (index, element) => {
|
|
309
|
+
this.masonryRendererEpoch++;
|
|
310
|
+
const template = this.ceriousScrollItemTemplate;
|
|
311
|
+
if (!template)
|
|
312
|
+
return;
|
|
313
|
+
if (element.dataset['ceriousMasonry'] === 'probe') {
|
|
314
|
+
this.renderProbe(template, index, element);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
this.renderTemplateIntoContainer(template, index, element);
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
options = this.ceriousScrollOptions;
|
|
325
|
+
}
|
|
257
326
|
if (options.layout === 'table' && this.ceriousScrollHeaderTemplate) {
|
|
258
327
|
const userHeader = options.table?.header;
|
|
259
328
|
options = {
|
|
@@ -312,6 +381,25 @@ export class CeriousScrollDirective {
|
|
|
312
381
|
return undefined;
|
|
313
382
|
return items[index];
|
|
314
383
|
}
|
|
384
|
+
renderProbe(template, index, container) {
|
|
385
|
+
const item = this.getItemForIndex(index);
|
|
386
|
+
const view = this.ngZone.runOutsideAngular(() => {
|
|
387
|
+
const v = template.createEmbeddedView({ $implicit: item, item, index });
|
|
388
|
+
v.detectChanges();
|
|
389
|
+
return v;
|
|
390
|
+
});
|
|
391
|
+
for (const node of view.rootNodes)
|
|
392
|
+
container.appendChild(node);
|
|
393
|
+
// Measurement probes are deliberately NOT attached to ApplicationRef:
|
|
394
|
+
// they are disposable, non-interactive markup and local detectChanges() is
|
|
395
|
+
// enough to populate their DOM synchronously. Attaching each probe inside
|
|
396
|
+
// Angular's zone turns dynamic scrolling into repeated application-wide
|
|
397
|
+
// change-detection work. The core reads offsetHeight immediately after this
|
|
398
|
+
// callback and clears the probe, so destroy the isolated view afterwards.
|
|
399
|
+
queueMicrotask(() => {
|
|
400
|
+
view.destroy();
|
|
401
|
+
});
|
|
402
|
+
}
|
|
315
403
|
renderTemplateIntoContainer(template, index, elementContainer) {
|
|
316
404
|
const previous = this.viewByContainer.get(elementContainer);
|
|
317
405
|
if (previous) {
|
|
@@ -436,4 +524,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
436
524
|
}], ceriousScrollReady: [{
|
|
437
525
|
type: Output
|
|
438
526
|
}] } });
|
|
439
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNlcmlvdXMtc2Nyb2xsL3NyYy9saWIvY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFHTCxTQUFTLEVBR1QsWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEdBR1AsTUFBTSxlQUFlLENBQUM7OztBQWF2QixTQUFTLG1CQUFtQixDQUFDLGFBQXdDLEVBQUUsUUFBbUM7SUFDeEcsTUFBTSxTQUFTLEdBQUcsT0FBTyxhQUFhLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDMUgsSUFBSSxTQUFTLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUN2RCxNQUFNLElBQUksS0FBSyxDQUFDLHVGQUF1RixDQUFDLENBQUM7SUFDM0csQ0FBQztJQUNELHdDQUF3QztJQUN4QyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ2hDLENBQUM7QUFNRCxNQUFNLE9BQU8sc0JBQXNCO0lBa0RqQyxZQUNtQixJQUE2QixFQUM3QixNQUFzQixFQUN0QixNQUFjLEVBQ2QsT0FBNkI7UUFIN0IsU0FBSSxHQUFKLElBQUksQ0FBeUI7UUFDN0IsV0FBTSxHQUFOLE1BQU0sQ0FBZ0I7UUFDdEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFlBQU8sR0FBUCxPQUFPLENBQXNCO1FBckRoRCxtRkFBbUY7UUFDMUUsK0JBQTBCLEdBQWtCLElBQUksQ0FBQztRQUUxRCxpREFBaUQ7UUFDeEMsdUJBQWtCLEdBQTRCLElBQUksQ0FB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TSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIEFwcGxpY2F0aW9uUmVmLFxuICBEaXJlY3RpdmUsXG4gIEVsZW1lbnRSZWYsXG4gIEVtYmVkZGVkVmlld1JlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7XG4gIHR5cGUgQ2VyaW91c1Njcm9sbE9wdGlvbnMsXG4gIHR5cGUgRWxlbWVudFJlbmRlcmVyLFxuICB0eXBlIE1lYXN1cmVkVmlld3BvcnRSYW5nZSxcbn0gZnJvbSAnQGNlcmlvdXNkZXZ0ZWNoL2NlcmlvdXMtc2Nyb2xsJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgdHlwZSB7IENlcmlvdXNWaWV3cG9ydENoYW5nZURldGFpbCB9IGZyb20gJy4vY2VyaW91cy1zY3JvbGwudHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlQ29udGV4dCB9IGZyb20gJy4vY2VyaW91cy1zY3JvbGwtaXRlbS10ZW1wbGF0ZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgdHlwZSBDZXJpb3VzU2Nyb2xsSG9zdFJlZiwgQ2VyaW91c1Njcm9sbFNlcnZpY2UgfSBmcm9tICcuL2NlcmlvdXMtc2Nyb2xsLnNlcnZpY2UnO1xuXG5mdW5jdGlvbiBjb2VyY2VUb3RhbEVsZW1lbnRzKGV4cGxpY2l0VG90YWw6IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQsIGl0ZW1zTGVuOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkKTogbnVtYmVyIHtcbiAgY29uc3QgY2FuZGlkYXRlID0gdHlwZW9mIGV4cGxpY2l0VG90YWwgPT09ICdudW1iZXInID8gZXhwbGljaXRUb3RhbCA6IHR5cGVvZiBpdGVtc0xlbiA9PT0gJ251bWJlcicgPyBpdGVtc0xlbiA6IHVuZGVmaW5lZDtcbiAgaWYgKGNhbmRpZGF0ZSA9PT0gdW5kZWZpbmVkIHx8IE51bWJlci5pc05hTihjYW5kaWRhdGUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDZXJpb3VzU2Nyb2xsRGlyZWN0aXZlOiBwcm92aWRlIGBjZXJpb3VzU2Nyb2xsVG90YWxFbGVtZW50c2Agb3IgYGNlcmlvdXNTY3JvbGxJdGVtc2AuJyk7XG4gIH1cbiAgLy8gQ2VyaW91c1Njcm9sbCBjdXJyZW50bHkgcmVxdWlyZXMgPj0gMVxuICByZXR1cm4gTWF0aC5tYXgoMSwgY2FuZGlkYXRlKTtcbn1cblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2NlcmlvdXNTY3JvbGxdJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgQ2VyaW91c1Njcm9sbERpcmVjdGl2ZTxUSXRlbSA9IHVua25vd24+IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICAvKiogVG90YWwgbnVtYmVyIG9mIGl0ZW1zLiBJZiBvbWl0dGVkLCBkZXJpdmVkIGZyb20gYGNlcmlvdXNTY3JvbGxJdGVtcy5sZW5ndGhgLiAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsVG90YWxFbGVtZW50czogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIE9wdGlvbmFsIGl0ZW1zIGFycmF5IChlbmFibGVzIGBsZXQtaXRlbWApLiAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsSXRlbXM6IHJlYWRvbmx5IFRJdGVtW10gfCBudWxsID0gbnVsbDtcblxuICAvKiogT3B0aW9uYWwgZ2V0dGVyIGZvciBsYXJnZSBkYXRhc2V0cyAoYWx0ZXJuYXRpdmUgdG8gcGFzc2luZyBmdWxsIGBpdGVtc2ApLiAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsR2V0SXRlbTogKChpbmRleDogbnVtYmVyKSA9PiBUSXRlbSkgfCBudWxsID0gbnVsbDtcblxuICAvKiogVGVtcGxhdGUgdXNlZCB0byByZW5kZXIgZWFjaCByb3cuICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGU6IFRlbXBsYXRlUmVmPENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVDb250ZXh0PFRJdGVtPj4gfCBudWxsID0gbnVsbDtcblxuICAvKipcbiAgICogVGFibGUgbW9kZSBvbmx5OiB0ZW1wbGF0ZSByZW5kZXJlZCBpbnRvIHRoZSBlbmdpbmUncyBgPHRoZWFkPmAgKGEgYDx0cj5gIG9mXG4gICAqIGA8dGg+YHMpLiBJdCBsaXZlcyBpbiB0aGUgc2FtZSBgPHRhYmxlPmAgYXMgdGhlIHJvd3MsIHNvIGNvbHVtbnMgYWxpZ25cbiAgICogbmF0aXZlbHkuIFVwZGF0ZXMgdmlhIGNoYW5nZSBkZXRlY3Rpb24gbGlrZSB0aGUgcm93cy5cbiAgICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxIZWFkZXJUZW1wbGF0ZTogVGVtcGxhdGVSZWY8dW5rbm93bj4gfCBudWxsID0gbnVsbDtcblxuICAvKiogT3B0aW9ucyBwYXNzZWQgdG8gYG5ldyBDZXJpb3VzU2Nyb2xsKC4uLilgLiAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsT3B0aW9uczogQ2VyaW91c1Njcm9sbE9wdGlvbnMgPSB7fTtcblxuICAvKiogQXV0b21hdGljYWxseSBjYWxsIHJlbmRlciBhZnRlciBlYWNoIHNjcm9sbCBldmVudC4gRGVmYXVsdDogdHJ1ZSAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsQXV0b1JlbmRlciA9IHRydWU7XG5cbiAgLyoqIEVtaXRzIGBjZXJpb3VzLXZpZXdwb3J0LWNoYW5nZWAgZGV0YWlsLiAqL1xuICBAT3V0cHV0KCkgY2VyaW91c1Njcm9sbFZpZXdwb3J0Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWw+KCk7XG5cbiAgLyoqIEVtaXRzIHRoZSBsYXN0IG1lYXN1cmVkIHZpZXdwb3J0IGFmdGVyIGVhY2ggcmVuZGVyIHBhc3MuICovXG4gIEBPdXRwdXQoKSBjZXJpb3VzU2Nyb2xsTWVhc3VyZWRWaWV3cG9ydCA9IG5ldyBFdmVudEVtaXR0ZXI8TWVhc3VyZWRWaWV3cG9ydFJhbmdlPigpO1xuXG4gIC8qKiBFbWl0cyBvbmNlIHRoZSB1bmRlcmx5aW5nIGBDZXJpb3VzU2Nyb2xsYCBpbnN0YW5jZSBpcyByZWFkeS4gKi9cbiAgQE91dHB1dCgpIGNlcmlvdXNTY3JvbGxSZWFkeSA9IG5ldyBFdmVudEVtaXR0ZXI8Q2VyaW91c1Njcm9sbEhvc3RSZWZbJ3Njcm9sbGVyJ10+KCk7XG5cbiAgcHJpdmF0ZSBob3N0UmVmOiBDZXJpb3VzU2Nyb2xsSG9zdFJlZiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHZpZXdwb3J0U3ViOiBTdWJzY3JpcHRpb24gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBzY2hlZHVsZWRSZW5kZXJGcmFtZTogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB2aWV3QnlDb250YWluZXIgPSBuZXcgTWFwPEhUTUxFbGVtZW50LCBFbWJlZGRlZFZpZXdSZWY8Q2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQ8VEl0ZW0+Pj4oKTtcbiAgLy8gUG9vbCBvZiB2aWV3cyBkZXRhY2hlZCBiZWNhdXNlIHRoZWlyIGNvbnRhaW5lciBsZWZ0IHRoZSB2aWV3cG9ydC4gUmV1c2luZ1xuICAvLyB0aGVtIG9uIHN1YnNlcXVlbnQgcmVuZGVycyBhdm9pZHMgZGVzdHJveWluZyArIHJlY3JlYXRpbmcgdGhlIGVudGlyZSByb3dcbiAgLy8gY29tcG9uZW50IHRyZWUgb24gZmFzdCBzY3JvbGxzICh3aGVyZSB0aGUgZW5naW5lJ3MgZWxlbWVudCBwb29sIHdpcGVzXG4gIC8vIHRleHRDb250ZW50IG9uIHJldXNlZCBjb250YWluZXJzLCBzbyB2aWV3IHJvb3ROb2RlcyBnZXQgb3JwaGFuZWQpLlxuICBwcml2YXRlIHJlYWRvbmx5IGZyZWVWaWV3czogRW1iZWRkZWRWaWV3UmVmPENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVDb250ZXh0PFRJdGVtPj5bXSA9IFtdO1xuXG4gIC8vIFRhYmxlIG1vZGU6IHRoZSBlbWJlZGRlZCB2aWV3IG9mIHRoZSBkZWNsYXJhdGl2ZSBoZWFkZXIsIHJlbmRlcmVkIGludG8gdGhlXG4gIC8vIGVuZ2luZSdzIDx0aGVhZD4uXG4gIHByaXZhdGUgaGVhZGVyVmlldzogRW1iZWRkZWRWaWV3UmVmPHVua25vd24+IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBob3N0OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGFwcFJlZjogQXBwbGljYXRpb25SZWYsXG4gICAgcHJpdmF0ZSByZWFkb25seSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNlcmlvdXM6IENlcmlvdXNTY3JvbGxTZXJ2aWNlXG4gICkge31cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm47XG5cbiAgICBpZiAoY2hhbmdlc1snY2VyaW91c1Njcm9sbEl0ZW1zJ10gfHwgY2hhbmdlc1snY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHMnXSkge1xuICAgICAgY29uc3QgdG90YWwgPSBjb2VyY2VUb3RhbEVsZW1lbnRzKHRoaXMuY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHMsIHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1zPy5sZW5ndGggPz8gbnVsbCk7XG4gICAgICBjb25zdCBjb3VudENoYW5nZWQgPSB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIudG90YWxFbGVtZW50cyAhPT0gdG90YWw7XG5cbiAgICAgIGlmIChjb3VudENoYW5nZWQpIHtcbiAgICAgICAgLy8gVGhlIGRhdGFzZXQgc2l6ZSBjaGFuZ2VkOiB0aGUgVmlld3BvcnRSZW5kZXJlciBzdG9yZXMgaXRzIG93biBjb3B5IG9mXG4gICAgICAgIC8vIHRvdGFsRWxlbWVudHMgKHNldCBieSB2YWx1ZSBhdCBjb25zdHJ1Y3Rpb24pIHNvIHBhdGNoaW5nIHRoZSBlbmdpbmUnc1xuICAgICAgICAvLyBwdWJsaWMgcHJvcGVydHkgYWxvbmUgbGVhdmVzIHRoZSByZW5kZXJlcidzIGludGVybmFsIGJvdW5kIHN0YWxlLiAgVGhlXG4gICAgICAgIC8vIHJlbmRlcmVyIHdvdWxkIHRoZW4gdXNlIHRoZSBvbGQgY291bnQgZm9yIGl0cyB2aWV3cG9ydC1maWxsIGxvb3AgYW5kXG4gICAgICAgIC8vIGJvdHRvbS1ib3VuZGFyeSBzY2FuLCBwcm9kdWNpbmcgcGhhbnRvbSByZW5kZXJzIGF0IG91dC1vZi1ib3VuZHNcbiAgICAgICAgLy8gaW5kaWNlcyAodW5kZWZpbmVkIGl0ZW1zIOKGkiAwLWhlaWdodCByb3dzIOKGkiB0aGUgZmlsbCBsb29wIG5ldmVyXG4gICAgICAgIC8vIHNhdGlzZmllcyBpdHMgaGVpZ2h0IGNvbmRpdGlvbiDihpIgaHVuZHJlZHMgb2YgcmVuZGVyZXIgY2FsbGJhY2tzKS5cbiAgICAgICAgLy8gUmVjcmVhdGluZyB0aGUgZW5naW5lIGdpdmVzIGJvdGggdGhlIGVuZ2luZSBhbmQgdGhlIHJlbmRlcmVyIGEgZnJlc2gsXG4gICAgICAgIC8vIGNvbnNpc3RlbnQgY291bnQuICBlbnN1cmVJbml0aWFsaXplZCgpIHNjaGVkdWxlcyB0aGUgZmlyc3QgcmVuZGVyIHZpYVxuICAgICAgICAvLyBxdWV1ZU1pY3JvdGFzaywgd2hpY2ggcnVucyBhZnRlciB0aGUgY3VycmVudCBDRCBjeWNsZSBjb21wbGV0ZXMuXG4gICAgICAgIHRoaXMucmVjcmVhdGUoKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikge1xuICAgICAgICAvLyBTYW1lIGNvdW50LCBuZXcgZGF0YSByZWZlcmVuY2UgKGUuZy4gYW4gaW1tdXRhYmxlIGVkaXQgb3IgYSBzb3J0IHRoYXRcbiAgICAgICAgLy8gaGFwcGVucyB0byBrZWVwIHRoZSBzYW1lIGxlbmd0aCkuIFRoZSBlbmdpbmUgcmV1c2VzIHRoZSBET00gZWxlbWVudCBpdFxuICAgICAgICAvLyBhbHJlYWR5IHJlbmRlcmVkIGZvciBlYWNoIG92ZXJsYXBwaW5nIGluZGV4IHdpdGhvdXQgcmUtaW52b2tpbmcgdGhlXG4gICAgICAgIC8vIHJlbmRlcmVyLCBzbyB1cGRhdGUgdGhlIGNvbnRlbnQgb2YgZXZlcnkgY3VycmVudGx5LXZpc2libGUgcm93IElOXG4gICAgICAgIC8vIFBMQUNFIGJlZm9yZSBjYWxsaW5nIHJlbmRlcigpLiAgVGhpcyBwcmVzZXJ2ZXMgZWFjaCByb3cncyBlbWJlZGRlZFxuICAgICAgICAvLyB2aWV3IChzbyBhIGZvY3VzZWQgdGV4dGJveCBrZWVwcyBmb2N1cy9jYXJldCkgYW5kIGRvZXMgTk9UIGRpc2NhcmRcbiAgICAgICAgLy8gY2FjaGVkIGhlaWdodHMuIElmIGEgcm93J3MgaGVpZ2h0IGFjdHVhbGx5IGNoYW5nZXMgdGhlIGVuZ2luZSdzXG4gICAgICAgIC8vIFJlc2l6ZU9ic2VydmVyIGtlZXBzIHRoZSBjYWNoZSBjb3JyZWN0IG9uIGl0cyBvd247IGZvciBhIHdob2xlc2FsZVxuICAgICAgICAvLyBoZWlnaHQgY2hhbmdlIGFjcm9zcyBhbGwgcm93cywgY2FsbCByZWNhbGN1bGF0ZSgpIGluc3RlYWQuXG4gICAgICAgIHRoaXMucmVmcmVzaFJlbmRlcmVkQ29udGVudCgpO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsT3B0aW9ucyddICYmICFjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsT3B0aW9ucyddLmZpcnN0Q2hhbmdlKSB7XG4gICAgICAvLyBPcHRpb25zIGFyZSBjb25zdW1lZCBwcmltYXJpbHkgYXQgY29uc3RydWN0aW9uIHRpbWUuXG4gICAgICB0aGlzLnJlY3JlYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2NoZWR1bGVkUmVuZGVyRnJhbWUgIT0gbnVsbCkge1xuICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5zY2hlZHVsZWRSZW5kZXJGcmFtZSk7XG4gICAgICB0aGlzLnNjaGVkdWxlZFJlbmRlckZyYW1lID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLnZpZXdwb3J0U3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMudmlld3BvcnRTdWIgPSBudWxsO1xuXG4gICAgdGhpcy5kZXN0cm95QWxsVmlld3MoKTtcbiAgICB0aGlzLmhlYWRlclZpZXc/LmRlc3Ryb3koKTtcbiAgICB0aGlzLmhlYWRlclZpZXcgPSBudWxsO1xuXG4gICAgdGhpcy5ob3N0UmVmPy5kZXN0cm95KCk7XG4gICAgdGhpcy5ob3N0UmVmID0gbnVsbDtcbiAgfVxuXG4gIC8qKiBJbXBlcmF0aXZlbHkgdHJpZ2dlciBhIHJlbmRlciBwYXNzICh1c2VzIGBjZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlYCkuICovXG4gIHJlbmRlcigpOiBNZWFzdXJlZFZpZXdwb3J0UmFuZ2UgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZikgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgdGVtcGxhdGUgPSB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGU7XG4gICAgaWYgKCF0ZW1wbGF0ZSkgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBob3N0Q29udGFpbmVyID0gdGhpcy5ob3N0Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgaGVpZ2h0ID0gaG9zdENvbnRhaW5lci5jbGllbnRIZWlnaHQgfHwgaG9zdENvbnRhaW5lci5vZmZzZXRIZWlnaHQ7XG4gICAgY29uc3QgY29udGVudENvbnRhaW5lciA9IHRoaXMuaG9zdFJlZi5jb250ZW50RWxlbWVudDtcblxuICAgIC8vIFRyYWNrIHdoZXRoZXIgdGhlIGVuZ2luZSBhc2tlZCB1cyB0byBiaW5kIGFueSByb3cgdGhpcyBwYXNzLiBQdXJlIHNjcm9sbFxuICAgIC8vIGZyYW1lcyB3aGVyZSB0aGUgdmlzaWJsZSByb3cgc2V0IGRvZXNuJ3QgY2hhbmdlIHN0aWxsIGRyaXZlIHJlbmRlcigpIHZpYVxuICAgIC8vIHRoZSByQUYgY29hbGVzY2VyIOKAlCB0aGVyZSdzIG5vIHBvaW50IGluIHdhbGtpbmcgdGhlIHBydW5lIG1hcCBvclxuICAgIC8vIGVtaXR0aW5nIHRoZSB2aWV3cG9ydCByYW5nZSB3aGVuIG5vdGhpbmcgd2FzIHRvdWNoZWQuXG4gICAgbGV0IHJlbmRlcmVySW52b2NhdGlvbnMgPSAwO1xuICAgIGNvbnN0IHJlbmRlcmVyOiBFbGVtZW50UmVuZGVyZXIgPSAoaW5kZXgsIGVsZW1lbnRDb250YWluZXIpID0+IHtcbiAgICAgIHJlbmRlcmVySW52b2NhdGlvbnMrKztcbiAgICAgIC8vIFJlbmRlciBlYWNoIHJvdydzIGVtYmVkZGVkIHZpZXcgd2l0aCBMT0NBTCBjaGFuZ2UgZGV0ZWN0aW9uXG4gICAgICAvLyAoYHZpZXcuZGV0ZWN0Q2hhbmdlcygpYCBpbnNpZGUgYHJlbmRlclRlbXBsYXRlSW50b0NvbnRhaW5lcmApIHNvIHRoZVxuICAgICAgLy8gZW5naW5lIGNhbiBtZWFzdXJlIGl0cyBoZWlnaHQgZHVyaW5nIHRoaXMgcGFzcy4gRG8gTk9UIHdyYXAgZWFjaCByb3cgaW5cbiAgICAgIC8vIGl0cyBvd24gYG5nWm9uZS5ydW5gIOKAlCB0aGF0IGZpcmVzIGEgZnVsbCBgQXBwbGljYXRpb25SZWZgIHRpY2sgKnBlciByb3cqXG4gICAgICAvLyAoTyhuZXdSb3dzIMOXIHZpc2libGVSb3dzKSB3b3JrLCBqYW5reSBkcmFncykuIFRoZSBzaW5nbGUgY29hbGVzY2VkIHRpY2tcbiAgICAgIC8vIGZvciB0aGUgd2hvbGUgcGFzcyBpcyBoYW5kbGVkIGJ5IHRoZSBjYWxsZXIgKGBzY2hlZHVsZVJlbmRlcmApLlxuICAgICAgdGhpcy5yZW5kZXJUZW1wbGF0ZUludG9Db250YWluZXIodGVtcGxhdGUsIGluZGV4LCBlbGVtZW50Q29udGFpbmVyKTtcbiAgICB9O1xuXG4gICAgY29uc3QgcmFuZ2UgPSB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIucmVuZGVyVmlld3BvcnQoaGVpZ2h0LCBjb250ZW50Q29udGFpbmVyLCByZW5kZXJlcik7XG5cbiAgICBpZiAocmVuZGVyZXJJbnZvY2F0aW9ucyA9PT0gMCkge1xuICAgICAgLy8gVmlld3BvcnQgZGlkbid0IGNoYW5nZSDigJQgc2tpcCB0aGUgcHJ1bmUgd2FsayBhbmQgdGhlIChwb3RlbnRpYWxseVxuICAgICAgLy8gem9uZS1lbnRlcmluZykgZW1pdC5cbiAgICAgIHJldHVybiByYW5nZTtcbiAgICB9XG5cbiAgICAvLyBEZXN0cm95IHZpZXdzIHdob3NlIGNvbnRhaW5lciB0aGUgZW5naW5lIG5vIGxvbmdlciByZW5kZXJzLiBXaXRob3V0IHRoaXMsXG4gICAgLy8gZXZlcnkgY29udGFpbmVyIHRoZSBlbmdpbmUgcmVjeWNsZXMgaW50byBpdHMgZWxlbWVudCBwb29sIGxlYXZlcyBpdHNcbiAgICAvLyBlbWJlZGRlZCB2aWV3IGF0dGFjaGVkIHRvIEFwcGxpY2F0aW9uUmVmIGZvcmV2ZXIg4oCUIHNvIHRoZSBhdHRhY2hlZC12aWV3XG4gICAgLy8gbGlzdCAoYW5kIGV2ZXJ5IE8obikgYGRldGFjaFZpZXdgKSBncm93cyB3aXRob3V0IGJvdW5kIGFuZCBzY3JvbGxpbmcgZ2V0c1xuICAgIC8vIHByb2dyZXNzaXZlbHkgc2xvd2VyLiBNaXJyb3JzIHRoZSBSZWFjdC9WdWUgd3JhcHBlcnMsIHdoaWNoIGRyb3Agcm93cyB0aGF0XG4gICAgLy8gZmFsbCBvdXQgb2YgYGdldFJlbmRlcmVkSW5kaWNlcygpYC5cbiAgICB0aGlzLnBydW5lRGV0YWNoZWRWaWV3cygpO1xuXG4gICAgLy8gT25seSByZS1lbnRlciB0aGUgem9uZSAoYSBnbG9iYWwgdGljaykgaWYgc29tZW9uZSBpcyBhY3R1YWxseSBsaXN0ZW5pbmcuXG4gICAgaWYgKHRoaXMuY2VyaW91c1Njcm9sbE1lYXN1cmVkVmlld3BvcnQub2JzZXJ2ZWQpIHtcbiAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLmNlcmlvdXNTY3JvbGxNZWFzdXJlZFZpZXdwb3J0LmVtaXQocmFuZ2UpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG5cbiAgLyoqIFRlYXIgZG93biBlbWJlZGRlZCB2aWV3cyB3aG9zZSBjb250YWluZXIgaXMgbm8gbG9uZ2VyIHBhcnQgb2YgdGhlIHZpZXdwb3J0LiAqL1xuICBwcml2YXRlIHBydW5lRGV0YWNoZWRWaWV3cygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZiB8fCB0aGlzLnZpZXdCeUNvbnRhaW5lci5zaXplID09PSAwKSByZXR1cm47XG4gICAgY29uc3Qgc2Nyb2xsZXIgPSB0aGlzLmhvc3RSZWYuc2Nyb2xsZXI7XG4gICAgY29uc3QgYWN0aXZlID0gbmV3IFNldDxIVE1MRWxlbWVudD4oKTtcbiAgICBmb3IgKGNvbnN0IGluZGV4IG9mIHNjcm9sbGVyLmdldFJlbmRlcmVkSW5kaWNlcygpKSB7XG4gICAgICBjb25zdCBlbCA9IHNjcm9sbGVyLmdldFJlbmRlcmVkRWxlbWVudChpbmRleCk7XG4gICAgICBpZiAoZWwpIGFjdGl2ZS5hZGQoZWwpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtjb250YWluZXIsIHZpZXddIG9mIHRoaXMudmlld0J5Q29udGFpbmVyKSB7XG4gICAgICBpZiAoIWFjdGl2ZS5oYXMoY29udGFpbmVyKSkge1xuICAgICAgICAvLyBEZXRhY2ggRE9NIGJ1dCBrZWVwIHRoZSB2aWV3IGFsaXZlIGluIHRoZSBwb29sIGZvciBmdXR1cmUgcmV1c2UuXG4gICAgICAgIC8vIERlc3Ryb3lpbmcgKyByZWNyZWF0aW5nIHZpZXdzIHBlciBzY3JvbGwgc3RlcCBkb21pbmF0ZXMgZnJhbWUgdGltZS5cbiAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIHZpZXcucm9vdE5vZGVzKSB7XG4gICAgICAgICAgaWYgKG5vZGUucGFyZW50Tm9kZSkgbm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudmlld0J5Q29udGFpbmVyLmRlbGV0ZShjb250YWluZXIpO1xuICAgICAgICB0aGlzLmZyZWVWaWV3cy5wdXNoKHZpZXcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKiBBdXRvLXJlbmRlciBjb2FsZXNjZWQgdG8gYXQgbW9zdCBvbmNlIHBlciBhbmltYXRpb24gZnJhbWUuICovXG4gIHByaXZhdGUgc2NoZWR1bGVSZW5kZXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2NoZWR1bGVkUmVuZGVyRnJhbWUgIT0gbnVsbCkgcmV0dXJuO1xuICAgIHRoaXMuc2NoZWR1bGVkUmVuZGVyRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgdGhpcy5zY2hlZHVsZWRSZW5kZXJGcmFtZSA9IG51bGw7XG4gICAgICAvLyBSdW4gcmVuZGVyKCkgT1VUU0lERSBBbmd1bGFyJ3Mgem9uZS4gQSBmdWxsIEFwcGxpY2F0aW9uUmVmLnRpY2soKSBvblxuICAgICAgLy8gZXZlcnkgc2Nyb2xsIGZyYW1lIGlzIHRoZSBwcmltYXJ5IEZQUyBib3R0bGVuZWNrOiBldmVuIHdoZW4gbm8gcm93c1xuICAgICAgLy8gY2hhbmdlIChwdXJlIHRyYW5zbGF0aW9uKSwgbmdab25lLnJ1bigpIGNhdXNlcyBBbmd1bGFyIHRvIHdhbGsgdGhlXG4gICAgICAvLyBlbnRpcmUgY29tcG9uZW50IHRyZWUuIEluc3RlYWQgd2UgY2FsbCB2aWV3LmRldGVjdENoYW5nZXMoKSBsb2NhbGx5XG4gICAgICAvLyBpbnNpZGUgcmVuZGVyVGVtcGxhdGVJbnRvQ29udGFpbmVyIGZvciBlYWNoIGFmZmVjdGVkIHJvdy4gWm9uZSBlbnRyeSBpc1xuICAgICAgLy8gb25seSBuZWVkZWQgd2hlbiBjcmVhdGluZyBhIGJyYW5kLW5ldyBlbWJlZGRlZCB2aWV3ICh0byB6b25lLXBhdGNoIGl0c1xuICAgICAgLy8gZXZlbnQgbGlzdGVuZXJzKSDigJQgcmVjeWNsZWQgYW5kIHBvb2xlZCB2aWV3cyB3ZXJlIGFscmVhZHkgY3JlYXRlZCBpbnNpZGVcbiAgICAgIC8vIHpvbmUgYW5kIHRoZWlyIGxpc3RlbmVycyByZW1haW4gem9uZS1hd2FyZS5cbiAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGlzY2FyZCBhbGwgY2FjaGVkIHJvdyBoZWlnaHRzIGFuZCByZS1tZWFzdXJlIHRoZSB2aWV3cG9ydC5cbiAgICpcbiAgICogQ2FsbCB0aGlzIG9ubHkgd2hlbiB0aGUgaGVpZ2h0cyBvZiByb3dzIHlvdSd2ZSAqYWxyZWFkeSByZW5kZXJlZCogbWF5IGhhdmVcbiAgICogY2hhbmdlZCB3aXRob3V0IHRoZWlyIGluZGljZXMgY2hhbmdpbmcg4oCUIGUuZy4gYSBnbG9iYWwgZm9udC9kZW5zaXR5IGNoYW5nZSxcbiAgICogb3Igc3dhcHBpbmcgZXZlcnkgcm93IHRvIGEgZGlmZmVyZW50IGxheW91dC4gVGhpcyBmb3JjZXMgYSBzeW5jaHJvbm91c1xuICAgKiByZS1tZWFzdXJlIChvbmUgYG9mZnNldEhlaWdodGAgcmVhZCBwZXIgdmlzaWJsZSByb3cpLCBzbyBkbyBOT1QgY2FsbCBpdCBvblxuICAgKiByb3V0aW5lIGVkaXRzOiBhIHNpbmdsZSBjZWxsIGVkaXQga2VlcHMgaXRzIHJvdydzIHNpemUsIGFuZCB0aGUgZW5naW5lJ3NcbiAgICogUmVzaXplT2JzZXJ2ZXIgcGlja3MgdXAgYW55IGluY2lkZW50YWwgcmVzaXplIG9uIGl0cyBvd24uXG4gICAqL1xuICByZWNhbGN1bGF0ZSgpOiBNZWFzdXJlZFZpZXdwb3J0UmFuZ2UgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZikgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgdGVtcGxhdGUgPSB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGU7XG4gICAgaWYgKHRlbXBsYXRlKSB7XG4gICAgICAvLyBSZS1pbnZva2UgdGhlIHJlbmRlcmVyIGZvciBldmVyeSBjdXJyZW50bHktcmVuZGVyZWQgcm93IHNvIHBlbmRpbmdcbiAgICAgIC8vIEFuZ3VsYXIgYmluZGluZ3MgZmx1c2ggaW50byB0aGUgRE9NIGFuZCB0aGUgZW5naW5lIHJlLW1lYXN1cmVzIGVhY2hcbiAgICAgIC8vIHJvdydzIG5ldyBoZWlnaHQgaW50byBpdHMgY2FjaGUuIFdpdGhvdXQgdGhpcywgdGhlIGVuZ2luZSdzIHJlbmRlclxuICAgICAgLy8gcGFzcyBza2lwcyB0aGUgcmVuZGVyZXIgZm9yIGFscmVhZHktcmVuZGVyZWQgaW5kaWNlcyBhbmQgZmFsbHNcbiAgICAgIC8vIHRocm91Z2ggdG8gcmVhZGluZyBzdGFsZSBvZmZzZXRIZWlnaHQuXG4gICAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIucmVmcmVzaFZpc2libGUoKGluZGV4LCBlbGVtZW50Q29udGFpbmVyKSA9PiB7XG4gICAgICAgIHRoaXMucmVuZGVyVGVtcGxhdGVJbnRvQ29udGFpbmVyKHRlbXBsYXRlLCBpbmRleCwgZWxlbWVudENvbnRhaW5lcik7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKiogSnVtcCBkaXJlY3RseSB0byBhbiBlbGVtZW50IGluZGV4LCB0aGVuIHJlbmRlci4gKi9cbiAganVtcFRvRWxlbWVudChpbmRleDogbnVtYmVyKTogTWVhc3VyZWRWaWV3cG9ydFJhbmdlIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybiBudWxsO1xuICAgIHRoaXMuaG9zdFJlZi5zY3JvbGxlci5qdW1wVG9FbGVtZW50KGluZGV4KTtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBTY3JvbGwgdG8gYSBwZXJjZW50YWdlICgwLi4xMDApLCB0aGVuIHJlbmRlci4gKi9cbiAgc2Nyb2xsVG9QZXJjZW50YWdlKHBlcmNlbnRhZ2U6IG51bWJlcik6IE1lYXN1cmVkVmlld3BvcnRSYW5nZSB8IG51bGwge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm4gbnVsbDtcbiAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIuaGFuZGxlU2Nyb2xsUGVyY2VudGFnZShwZXJjZW50YWdlKTtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBSZXNldCB0byB0aGUgdG9wLCB0aGVuIHJlbmRlci4gKi9cbiAgcmVzZXQoKTogTWVhc3VyZWRWaWV3cG9ydFJhbmdlIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybiBudWxsO1xuICAgIHRoaXMuaG9zdFJlZi5zY3JvbGxlci5yZXNldCgpO1xuICAgIHJldHVybiB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWNyZWF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLnZpZXdwb3J0U3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMudmlld3BvcnRTdWIgPSBudWxsO1xuXG4gICAgdGhpcy5kZXN0cm95QWxsVmlld3MoKTtcblxuICAgIHRoaXMuaG9zdFJlZj8uZGVzdHJveSgpO1xuICAgIHRoaXMuaG9zdFJlZiA9IG51bGw7XG5cbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZUluaXRpYWxpemVkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhvc3RSZWYpIHJldHVybjtcblxuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuaG9zdC5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IHRvdGFsID0gY29lcmNlVG90YWxFbGVtZW50cyh0aGlzLmNlcmlvdXNTY3JvbGxUb3RhbEVsZW1lbnRzLCB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtcz8ubGVuZ3RoID8/IG51bGwpO1xuXG4gICAgLy8gVGFibGUgbW9kZTogY2FwdHVyZSB0aGUgZW5naW5lLWNyZWF0ZWQgPHRoZWFkPiBzbyB3ZSBjYW4gcmVuZGVyIHRoZVxuICAgIC8vIGRlY2xhcmF0aXZlIGhlYWRlciB0ZW1wbGF0ZSBpbnRvIGl0IChhbmQgc3RpbGwgcnVuIGFueSB1c2VyIGhlYWRlciBob29rKS5cbiAgICBsZXQgb3B0aW9ucyA9IHRoaXMuY2VyaW91c1Njcm9sbE9wdGlvbnM7XG4gICAgaWYgKG9wdGlvbnMubGF5b3V0ID09PSAndGFibGUnICYmIHRoaXMuY2VyaW91c1Njcm9sbEhlYWRlclRlbXBsYXRlKSB7XG4gICAgICBjb25zdCB1c2VySGVhZGVyID0gb3B0aW9ucy50YWJsZT8uaGVhZGVyO1xuICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgdGFibGU6IHtcbiAgICAgICAgICAuLi5vcHRpb25zLnRhYmxlLFxuICAgICAgICAgIGhlYWRlcjogKHRoZWFkOiBIVE1MVGFibGVTZWN0aW9uRWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgdXNlckhlYWRlcj8uKHRoZWFkKTtcbiAgICAgICAgICAgIHRoaXMubW91bnRIZWFkZXIodGhlYWQpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMuaG9zdFJlZiA9IHRoaXMuY2VyaW91cy5jcmVhdGVIb3N0KGNvbnRhaW5lciwgdG90YWwsIG9wdGlvbnMsIHRoaXMubmdab25lLCAoKSA9PiB7XG4gICAgICAvLyBDb2FsZXNjZSBzY3JvbGwtZHJpdmVuIHJlbmRlcnMgdG8gb25lIHBlciBmcmFtZSAodGhlIG5hdGl2ZSBzY3JvbGxiYXJcbiAgICAgIC8vIGNhbiBmaXJlIG1hbnkgc2Nyb2xsIGV2ZW50cyBiZXR3ZWVuIHBhaW50cykuXG4gICAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikgdGhpcy5zY2hlZHVsZVJlbmRlcigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy52aWV3cG9ydFN1YiA9IHRoaXMuaG9zdFJlZi52aWV3cG9ydENoYW5nZXMkLnN1YnNjcmliZSgoZGV0YWlsOiBDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWwpID0+IHtcbiAgICAgIC8vIFNraXAgdGhlIGdsb2JhbCB0aWNrIHdoZW4gbm9ib2R5IGlzIGJvdW5kIHRvIHRoZSBvdXRwdXQuXG4gICAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsVmlld3BvcnRDaGFuZ2Uub2JzZXJ2ZWQpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuY2VyaW91c1Njcm9sbFZpZXdwb3J0Q2hhbmdlLmVtaXQoZGV0YWlsKSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmNlcmlvdXNTY3JvbGxSZWFkeS5lbWl0KHRoaXMuaG9zdFJlZi5zY3JvbGxlcik7XG5cbiAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikge1xuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy5yZW5kZXIoKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgZGVjbGFyYXRpdmUgaGVhZGVyIHRlbXBsYXRlIGludG8gdGhlIGVuZ2luZSdzIDx0aGVhZD4uIE9uZVxuICAgKiBlbWJlZGRlZCB2aWV3LCBjcmVhdGVkIGluc2lkZSB0aGUgem9uZSAoc28gdGhlIGhlYWRlcidzIGV2ZW50IGJpbmRpbmdzIGFyZVxuICAgKiB6b25lLXBhdGNoZWQpLCBpdHMgcm9vdCBub2RlcyBhcHBlbmRlZCBkaXJlY3RseSBpbnRvIHRoZSA8dGhlYWQ+LlxuICAgKi9cbiAgcHJpdmF0ZSBtb3VudEhlYWRlcih0aGVhZDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2VyaW91c1Njcm9sbEhlYWRlclRlbXBsYXRlKSByZXR1cm47XG4gICAgdGhpcy5oZWFkZXJWaWV3Py5kZXN0cm95KCk7XG4gICAgY29uc3QgdmlldyA9IHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICBjb25zdCB2ID0gdGhpcy5jZXJpb3VzU2Nyb2xsSGVhZGVyVGVtcGxhdGUhLmNyZWF0ZUVtYmVkZGVkVmlldyh7fSk7XG4gICAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHYpO1xuICAgICAgdi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICByZXR1cm4gdjtcbiAgICB9KTtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygdmlldy5yb290Tm9kZXMpIHRoZWFkLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgIHRoaXMuaGVhZGVyVmlldyA9IHZpZXc7XG4gIH1cblxuICBwcml2YXRlIGdldEl0ZW1Gb3JJbmRleChpbmRleDogbnVtYmVyKTogVEl0ZW0ge1xuICAgIGNvbnN0IGdldHRlciA9IHRoaXMuY2VyaW91c1Njcm9sbEdldEl0ZW07XG4gICAgaWYgKGdldHRlcikgcmV0dXJuIGdldHRlcihpbmRleCk7XG5cbiAgICBjb25zdCBpdGVtcyA9IHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1zO1xuICAgIGlmICghaXRlbXMpIHJldHVybiB1bmRlZmluZWQgYXMgVEl0ZW07XG5cbiAgICByZXR1cm4gaXRlbXNbaW5kZXhdO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJUZW1wbGF0ZUludG9Db250YWluZXIoXG4gICAgdGVtcGxhdGU6IFRlbXBsYXRlUmVmPENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVDb250ZXh0PFRJdGVtPj4sXG4gICAgaW5kZXg6IG51bWJlcixcbiAgICBlbGVtZW50Q29udGFpbmVyOiBIVE1MRWxlbWVudFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMudmlld0J5Q29udGFpbmVyLmdldChlbGVtZW50Q29udGFpbmVyKTtcbiAgICBpZiAocHJldmlvdXMpIHtcbiAgICAgIC8vIFJlY3ljbGU6IHVwZGF0ZSB0aGUgYm91bmQgY29udGV4dCBhbmQgcnVuIGxvY2FsIENEIGluc3RlYWQgb2ZcbiAgICAgIC8vIGRlc3Ryb3lpbmcgdGhlIGVtYmVkZGVkIHZpZXcgYW5kIHJlYnVpbGRpbmcgdGhlIGVudGlyZSByb3cgdHJlZS5cbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmdldEl0ZW1Gb3JJbmRleChpbmRleCk7XG4gICAgICBwcmV2aW91cy5jb250ZXh0LiRpbXBsaWNpdCA9IGl0ZW07XG4gICAgICBwcmV2aW91cy5jb250ZXh0Lml0ZW0gPSBpdGVtO1xuICAgICAgcHJldmlvdXMuY29udGV4dC5pbmRleCA9IGluZGV4O1xuICAgICAgLy8gVGhlIGNvcmUgZW5naW5lIHdpcGVzIGVsZW1lbnRDb250YWluZXIudGV4dENvbnRlbnQgd2hlbiByZXVzaW5nIGl0IGZyb21cbiAgICAgIC8vIGl0cyBwb29sLCBvcnBoYW5pbmcgdGhlIHZpZXcncyByb290IG5vZGVzLiBSZS1hcHBlbmQgdGhlbSBkZWZlbnNpdmVseS5cbiAgICAgIGlmIChwcmV2aW91cy5yb290Tm9kZXMubGVuZ3RoICYmIHByZXZpb3VzLnJvb3ROb2Rlc1swXS5wYXJlbnROb2RlICE9PSBlbGVtZW50Q29udGFpbmVyKSB7XG4gICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBwcmV2aW91cy5yb290Tm9kZXMpIHtcbiAgICAgICAgICBlbGVtZW50Q29udGFpbmVyLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBwcmV2aW91cy5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVHJ5IHRvIHJldXNlIGEgcG9vbGVkIHZpZXcgZnJvbSBhIGNvbnRhaW5lciB0aGF0IHNjcm9sbGVkIG91dCBvZiB2aWV3cG9ydC5cbiAgICBjb25zdCBwb29sZWQgPSB0aGlzLmZyZWVWaWV3cy5wb3AoKTtcbiAgICBpZiAocG9vbGVkKSB7XG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5nZXRJdGVtRm9ySW5kZXgoaW5kZXgpO1xuICAgICAgcG9vbGVkLmNvbnRleHQuJGltcGxpY2l0ID0gaXRlbTtcbiAgICAgIHBvb2xlZC5jb250ZXh0Lml0ZW0gPSBpdGVtO1xuICAgICAgcG9vbGVkLmNvbnRleHQuaW5kZXggPSBpbmRleDtcbiAgICAgIGVsZW1lbnRDb250YWluZXIudGV4dENvbnRlbnQgPSAnJztcbiAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBwb29sZWQucm9vdE5vZGVzKSB7XG4gICAgICAgIGVsZW1lbnRDb250YWluZXIuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgICB9XG4gICAgICBwb29sZWQuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgdGhpcy52aWV3QnlDb250YWluZXIuc2V0KGVsZW1lbnRDb250YWluZXIsIHBvb2xlZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gTm8gcHJpb3IgdmlldyBmb3IgdGhpcyBjb250YWluZXI6IGNyZWF0ZSBvbmUuXG4gICAgLy8gRW50ZXIgdGhlIEFuZ3VsYXIgem9uZSBzbyB0aGUgbmV3IHZpZXcncyB0ZW1wbGF0ZSBldmVudCBsaXN0ZW5lcnNcbiAgICAvLyAoKGNsaWNrKSwgKGlucHV0KSwgZXRjLikgYXJlIHpvbmUtcGF0Y2hlZC4gVGhpcyBwYXRoIHJ1bnMgYXQgbW9zdFxuICAgIC8vIG9uY2UgcGVyIHZpc2libGUgcm93IChhZnRlciB0aGF0LCB0aGUgdmlldyBpcyByZWN5Y2xlZCBmcm9tIHRoZSBwb29sKS5cbiAgICBlbGVtZW50Q29udGFpbmVyLnRleHRDb250ZW50ID0gJyc7XG5cbiAgICBjb25zdCBpdGVtID0gdGhpcy5nZXRJdGVtRm9ySW5kZXgoaW5kZXgpO1xuICAgIGNvbnN0IHZpZXcgPSB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgY29uc3QgdiA9IHRlbXBsYXRlLmNyZWF0ZUVtYmVkZGVkVmlldyh7ICRpbXBsaWNpdDogaXRlbSwgaXRlbSwgaW5kZXggfSk7XG4gICAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHYpO1xuICAgICAgdi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICByZXR1cm4gdjtcbiAgICB9KTtcblxuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB2aWV3LnJvb3ROb2Rlcykge1xuICAgICAgZWxlbWVudENvbnRhaW5lci5hcHBlbmRDaGlsZChub2RlKTtcbiAgICB9XG5cbiAgICB0aGlzLnZpZXdCeUNvbnRhaW5lci5zZXQoZWxlbWVudENvbnRhaW5lciwgdmlldyk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHRoZSBib3VuZCBpdGVtL2luZGV4IG9uIGV2ZXJ5IGN1cnJlbnRseS1yZW5kZXJlZCByb3cncyBlbWJlZGRlZCB2aWV3XG4gICAqIGFuZCBydW4gY2hhbmdlIGRldGVjdGlvbiwgd2l0aG91dCByZWNyZWF0aW5nIHRoZSB2aWV3cy4gVXNlZCB3aGVuIHRoZSBkYXRhXG4gICAqIHJlZmVyZW5jZSBjaGFuZ2VzIGJ1dCB0aGUgdmlzaWJsZSBpbmRpY2VzIChhbmQgdGhlaXIgaGVpZ2h0cykgZG8gbm90LCBzbyByb3dcbiAgICogc3RhdGUgKGZvY3VzLCBzZWxlY3Rpb24sIG9wZW4gZHJvcGRvd25zKSBzdXJ2aXZlcyB0aGUgdXBkYXRlLlxuICAgKi9cbiAgLyoqXG4gICAqIFJlLWJpbmQgZWFjaCBjdXJyZW50bHkgcmVuZGVyZWQgcm93J3MgY29udGV4dCAoZnJvbSB0aGUgY3VycmVudCBpdGVtcy9nZXR0ZXIpXG4gICAqIGFuZCBydW4gY2hhbmdlIGRldGVjdGlvbiBvbiBpdHMgZW1iZWRkZWQgdmlldy4gVXNlIHRoaXMgYWZ0ZXIgbXV0YXRpbmcgcm93XG4gICAqIHN0YXRlIGluIHBsYWNlIChlLmcuIHNlbGVjdGlvbiBmbGFncykgb3IgY29sdW1uLWxldmVsIHN0YXRlIHJlYWQgYnkgdGhlIHJvd1xuICAgKiB0ZW1wbGF0ZSwgd2hlbiByb3cgaWRlbnRpdHkgYW5kIHZpc2libGUgaW5kaWNlcyBoYXZlIG5vdCBjaGFuZ2VkLiBDaGVhcFxuICAgKiByZWxhdGl2ZSB0byBgcmVuZGVyKClgIOKAlCBkb2VzIG5vdCBpbnZva2UgdGhlIGVuZ2luZSdzIG1lYXN1cmVtZW50IHBhc3MuXG4gICAqL1xuICByZWZyZXNoUmVuZGVyZWRDb250ZW50KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm47XG4gICAgY29uc3Qgc2Nyb2xsZXIgPSB0aGlzLmhvc3RSZWYuc2Nyb2xsZXI7XG5cbiAgICBmb3IgKGNvbnN0IGluZGV4IG9mIHNjcm9sbGVyLmdldFJlbmRlcmVkSW5kaWNlcygpKSB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSBzY3JvbGxlci5nZXRSZW5kZXJlZEVsZW1lbnQoaW5kZXgpO1xuICAgICAgaWYgKCFjb250YWluZXIpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCB2aWV3ID0gdGhpcy52aWV3QnlDb250YWluZXIuZ2V0KGNvbnRhaW5lcik7XG4gICAgICBpZiAoIXZpZXcpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5nZXRJdGVtRm9ySW5kZXgoaW5kZXgpO1xuICAgICAgdmlldy5jb250ZXh0LiRpbXBsaWNpdCA9IGl0ZW07XG4gICAgICB2aWV3LmNvbnRleHQuaXRlbSA9IGl0ZW07XG4gICAgICB2aWV3LmNvbnRleHQuaW5kZXggPSBpbmRleDtcbiAgICAgIHZpZXcuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveUFsbFZpZXdzKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgdmlldyBvZiB0aGlzLnZpZXdCeUNvbnRhaW5lci52YWx1ZXMoKSkge1xuICAgICAgdGhpcy5hcHBSZWYuZGV0YWNoVmlldyh2aWV3KTtcbiAgICAgIHZpZXcuZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLnZpZXdCeUNvbnRhaW5lci5jbGVhcigpO1xuICAgIGZvciAoY29uc3QgdmlldyBvZiB0aGlzLmZyZWVWaWV3cykge1xuICAgICAgdGhpcy5hcHBSZWYuZGV0YWNoVmlldyh2aWV3KTtcbiAgICAgIHZpZXcuZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLmZyZWVWaWV3cy5sZW5ndGggPSAwO1xuICB9XG59XG4iXX0=
|
|
527
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNlcmlvdXMtc2Nyb2xsL3NyYy9saWIvY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFHTCxTQUFTLEVBR1QsWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEdBR1AsTUFBTSxlQUFlLENBQUM7OztBQWN2QixTQUFTLG1CQUFtQixDQUFDLGFBQXdDLEVBQUUsUUFBbUM7SUFDeEcsTUFBTSxTQUFTLEdBQUcsT0FBTyxhQUFhLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDMUgsSUFBSSxTQUFTLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUN2RCxNQUFNLElBQUksS0FBSyxDQUFDLHVGQUF1RixDQUFDLENBQUM7SUFDM0csQ0FBQztJQUNELHdDQUF3QztJQUN4QyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ2hDLENBQUM7QUFNRCxNQUFNLE9BQU8sc0JBQXNCO0lBc0RqQyxzRUFBc0U7SUFDdEUsSUFBSSxRQUFRO1FBQ1YsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLFFBQVEsSUFBSSxJQUFJLENBQUM7SUFDeEMsQ0FBQztJQUVELFlBQ21CLElBQTZCLEVBQzdCLE1BQXNCLEVBQ3RCLE1BQWMsRUFDZCxPQUE2QjtRQUg3QixTQUFJLEdBQUosSUFBSSxDQUF5QjtRQUM3QixXQUFNLEdBQU4sTUFBTSxDQUFnQjtRQUN0QixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsWUFBTyxHQUFQLE9BQU8sQ0FBc0I7UUE5RGhELG1GQUFtRjtRQUMxRSwrQkFBMEIsR0FBa0IsSUFBSSxDQUFDO1FBRTFELGlEQUFpRDtRQUN4Qyx1QkFBa0IsR0FBNEIsSUFBSSxDQUFDO1FBRTVELGdGQUFnRjtRQUN2RSx5QkFBb0IsR0FBc0MsSUFBSSxDQUFDO1FBRXhFLHdDQUF3QztRQUMvQiw4QkFBeUIsR0FBZ0UsSUFBSSxDQUFDO1FBRXZHOzs7O1dBSUc7UUFDTSxnQ0FBMkIsR0FBZ0MsSUFBSSxDQUFDO1FBRXpFLGtEQUFrRDtRQUN6Qyx5QkFBb0IsR0FBeUIsRUFBRSxDQUFDO1FBRXpELHVFQUF1RTtRQUM5RCw0QkFBdUIsR0FBRyxJQUFJLENBQUM7UUFFeEMsOENBQThDO1FBQ3BDLGdDQUEyQixHQUFHLElBQUksWUFBWSxFQUErQixDQUFDO1FBRXhGLCtEQUErRDtRQUNyRCxrQ0FBNkIsR0FBRyxJQUFJLFlBQVksRUFBeUIsQ0FBQztRQUVwRixtRUFBbUU7UUFDekQsdUJBQWtCLEdBQUcsSUFBSSxZQUFZLEVBQW9DLENBQUM7UUFFNUUsWUFBTyxHQUFnQyxJQUFJLENBQUM7UUFDNUMsZ0JBQVcsR0FBd0IsSUFBSSxDQUFDO1FBQ3hDLHlCQUFvQixHQUFrQixJQUFJLENBQUM7UUFDbkQsNEVBQTRFO1FBQzVFLHdFQUF3RTtRQUN4RSw4Q0FBOEM7UUFDdEMseUJBQW9CLEdBQUcsQ0FBQyxDQUFDO1FBRWhCLG9CQUFlLEdBQUcsSUFBSSxHQUFHLEVBQXlFLENBQUM7UUFDcEgsNEVBQTRFO1FBQzVFLDJFQUEyRTtRQUMzRSx3RUFBd0U7UUFDeEUscUVBQXFFO1FBQ3BELGNBQVMsR0FBK0QsRUFBRSxDQUFDO1FBRTVGLDZFQUE2RTtRQUM3RSxvQkFBb0I7UUFDWixlQUFVLEdBQW9DLElBQUksQ0FBQztJQVl4RCxDQUFDO0lBRUosZUFBZTtRQUNiLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDaEMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQUUsT0FBTztRQUUxQixJQUFJLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLE9BQU8sQ0FBQyw0QkFBNEIsQ0FBQyxFQUFFLENBQUM7WUFDM0UsTUFBTSxLQUFLLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxNQUFNLElBQUksSUFBSSxDQUFDLENBQUM7WUFDNUcsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sS0FBSyxTQUFTLENBQUM7WUFDbkUsTUFBTSxZQUFZLEdBQUcsV0FBVztnQkFDOUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFNBQVM7Z0JBQ2pDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUM7WUFDeEMsTUFBTSxZQUFZLEdBQUcsWUFBWSxLQUFLLEtBQUssQ0FBQztZQUU1QyxJQUFJLFlBQVksRUFBRSxDQUFDO2dCQUNqQixJQUFJLFdBQVcsRUFBRSxDQUFDO29CQUNoQixxRUFBcUU7b0JBQ3JFLHNFQUFzRTtvQkFDdEUsb0RBQW9EO29CQUNwRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQ2hCLE9BQU87Z0JBQ1QsQ0FBQztnQkFDRCxzRUFBc0U7Z0JBQ3RFLDZEQUE2RDtnQkFDN0QscUVBQXFFO2dCQUNyRSx1RUFBdUU7Z0JBQ3ZFLGdFQUFnRTtnQkFDaEUsb0VBQW9FO2dCQUNwRSx5RUFBeUU7Z0JBQ3pFLHVFQUF1RTtnQkFDdkUsb0JBQW9CO2dCQUNwQixJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDakQsK0RBQStEO2dCQUMvRCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLGNBQWMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQ3JELElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pELENBQUM7Z0JBQ0QsSUFBSSxJQUFJLENBQUMsdUJBQXVCO29CQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDaEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDeEMsQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO2dCQUN4Qyx3RUFBd0U7Z0JBQ3hFLHlFQUF5RTtnQkFDekUsc0VBQXNFO2dCQUN0RSxvRUFBb0U7Z0JBQ3BFLHFFQUFxRTtnQkFDckUscUVBQXFFO2dCQUNyRSxrRUFBa0U7Z0JBQ2xFLHFFQUFxRTtnQkFDckUsNkRBQTZEO2dCQUM3RCxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztnQkFDOUIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hCLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxPQUFPLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3BGLHVEQUF1RDtZQUN2RCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDbEIsQ0FBQztJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxJQUFJLENBQUMsb0JBQW9CLElBQUksSUFBSSxFQUFFLENBQUM7WUFDdEMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7WUFDaEQsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQztRQUNuQyxDQUFDO1FBRUQsSUFBSSxDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztRQUV4QixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFVBQVUsRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUV2QixJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO0lBQ3RCLENBQUM7SUFFRCw2RUFBNkU7SUFDN0UsTUFBTTtRQUNKLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQy9CLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQztRQUNoRCxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBRTNCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBQzlDLE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxZQUFZLElBQUksYUFBYSxDQUFDLFlBQVksQ0FBQztRQUN4RSxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDO1FBRXJELDJFQUEyRTtRQUMzRSwyRUFBMkU7UUFDM0UsbUVBQW1FO1FBQ25FLHdEQUF3RDtRQUN4RCxJQUFJLG1CQUFtQixHQUFHLENBQUMsQ0FBQztRQUM1QixNQUFNLFFBQVEsR0FBb0IsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsRUFBRTtZQUM1RCxtQkFBbUIsRUFBRSxDQUFDO1lBQ3RCLDhEQUE4RDtZQUM5RCx1RUFBdUU7WUFDdkUsMEVBQTBFO1lBQzFFLDJFQUEyRTtZQUMzRSwwRUFBMEU7WUFDMUUsa0VBQWtFO1lBQ2xFLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFDdEUsQ0FBQyxDQUFDO1FBRUYsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sS0FBSyxTQUFTLENBQUM7UUFDbkUsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUM7UUFDckQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN2RixNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxrQkFBa0IsQ0FBQztRQUUxRSxJQUFJLG1CQUFtQixLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsV0FBVyxJQUFJLGtCQUFrQixLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDNUUsb0VBQW9FO1lBQ3BFLHVCQUF1QjtZQUN2QixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFFRCw0RUFBNEU7UUFDNUUsdUVBQXVFO1FBQ3ZFLDBFQUEwRTtRQUMxRSw0RUFBNEU7UUFDNUUsNkVBQTZFO1FBQzdFLHNDQUFzQztRQUN0QyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUUxQiwyRUFBMkU7UUFDM0UsSUFBSSxJQUFJLENBQUMsNkJBQTZCLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDaEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxrRkFBa0Y7SUFDMUUsa0JBQWtCO1FBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxLQUFLLENBQUM7WUFBRSxPQUFPO1FBQzdELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQ3ZDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDO1FBQ25FLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxFQUFlLENBQUM7UUFDdEMsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWE7aUJBQ3BCLGdCQUFnQixDQUFjLHNCQUFzQixDQUFDO2lCQUNyRCxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNyQyxDQUFDO2FBQU0sQ0FBQztZQUNOLEtBQUssTUFBTSxLQUFLLElBQUksUUFBUSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBQztnQkFDbEQsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM5QyxJQUFJLEVBQUU7b0JBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN6QixDQUFDO1FBQ0gsQ0FBQztRQUNELEtBQUssTUFBTSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDckQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFDM0IsbUVBQW1FO2dCQUNuRSxzRUFBc0U7Z0JBQ3RFLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO29CQUNsQyxJQUFJLElBQUksQ0FBQyxVQUFVO3dCQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN6RCxDQUFDO2dCQUNELElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUN2QyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM1QixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxpRUFBaUU7SUFDekQsY0FBYztRQUNwQixJQUFJLElBQUksQ0FBQyxvQkFBb0IsSUFBSSxJQUFJO1lBQUUsT0FBTztRQUM5QyxJQUFJLENBQUMsb0JBQW9CLEdBQUcscUJBQXFCLENBQUMsR0FBRyxFQUFFO1lBQ3JELElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7WUFDakMsdUVBQXVFO1lBQ3ZFLHNFQUFzRTtZQUN0RSxxRUFBcUU7WUFDckUsc0VBQXNFO1lBQ3RFLDBFQUEwRTtZQUMxRSx5RUFBeUU7WUFDekUsMkVBQTJFO1lBQzNFLDhDQUE4QztZQUM5QyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0gsV0FBVztRQUNULElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQy9CLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQztRQUNoRCxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2IscUVBQXFFO1lBQ3JFLHNFQUFzRTtZQUN0RSxxRUFBcUU7WUFDckUsaUVBQWlFO1lBQ2pFLHlDQUF5QztZQUN6QyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsRUFBRTtnQkFDL0QsSUFBSSxDQUFDLDJCQUEyQixDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUN0RSxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQsc0RBQXNEO0lBQ3RELGFBQWEsQ0FBQyxLQUFhO1FBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQy9CLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQyxPQUFPLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQscUVBQXFFO0lBQ3JFLFVBQVUsQ0FBQyxLQUFhLEVBQUUsWUFBWSxHQUFHLENBQUM7UUFDeEMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDL0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FBQztRQUN0RCxPQUFPLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQsb0RBQW9EO0lBQ3BELGtCQUFrQixDQUFDLFVBQWtCO1FBQ25DLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQy9CLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLHNCQUFzQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3pELE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxxQ0FBcUM7SUFDckMsS0FBSztRQUNILElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQy9CLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzlCLE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFTyxRQUFRO1FBQ2QsSUFBSSxDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztRQUV4QixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFdkIsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUVwQixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLElBQUksSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBRXpCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBQzFDLE1BQU0sS0FBSyxHQUFHLG1CQUFtQixDQUFDLElBQUksQ0FBQywwQkFBMEIsRUFBRSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsTUFBTSxJQUFJLElBQUksQ0FBQyxDQUFDO1FBRTVHLHNFQUFzRTtRQUN0RSw0RUFBNEU7UUFDNUUsSUFBSSxPQUFpQyxDQUFDO1FBQ3RDLElBQUksSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNuRCxJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN2QyxNQUFNLElBQUksS0FBSyxDQUFDLG1GQUFtRixDQUFDLENBQUM7WUFDdkcsQ0FBQztZQUNELE9BQU8sR0FBRztnQkFDUixHQUFHLElBQUksQ0FBQyxvQkFBb0I7Z0JBQzVCLE9BQU8sRUFBRTtvQkFDUCxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPO29CQUNwQyxVQUFVLEVBQUUsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7d0JBQzdCLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO3dCQUM1QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUM7d0JBQ2hELElBQUksQ0FBQyxRQUFROzRCQUFFLE9BQU87d0JBQ3RCLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLE9BQU8sRUFBRSxDQUFDOzRCQUNsRCxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7d0JBQzdDLENBQUM7NkJBQU0sQ0FBQzs0QkFDTixJQUFJLENBQUMsMkJBQTJCLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQzt3QkFDN0QsQ0FBQztvQkFDSCxDQUFDO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxHQUFHLElBQUksQ0FBQyxvQkFBZ0QsQ0FBQztRQUNsRSxDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLE9BQU8sSUFBSSxJQUFJLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztZQUNuRSxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQztZQUN6QyxPQUFPLEdBQUc7Z0JBQ1IsR0FBRyxPQUFPO2dCQUNWLEtBQUssRUFBRTtvQkFDTCxHQUFHLE9BQU8sQ0FBQyxLQUFLO29CQUNoQixNQUFNLEVBQUUsQ0FBQyxLQUE4QixFQUFFLEVBQUU7d0JBQ3pDLFVBQVUsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO3dCQUNwQixJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUMxQixDQUFDO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFO1lBQ2xGLHdFQUF3RTtZQUN4RSwrQ0FBK0M7WUFDL0MsSUFBSSxJQUFJLENBQUMsdUJBQXVCO2dCQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUMxRCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFtQyxFQUFFLEVBQUU7WUFDakcsMkRBQTJEO1lBQzNELElBQUksSUFBSSxDQUFDLDJCQUEyQixDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUM5QyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDdkUsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRXBELElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFDakMsY0FBYyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLFdBQVcsQ0FBQyxLQUFrQjtRQUNwQyxJQUFJLENBQUMsSUFBSSxDQUFDLDJCQUEyQjtZQUFFLE9BQU87UUFDOUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUMzQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDaEMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLDJCQUE0QixDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ25FLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFCLENBQUMsQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNsQixPQUFPLENBQUMsQ0FBQztRQUNYLENBQUMsQ0FBQyxDQUFDO1FBQ0gsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsU0FBUztZQUFFLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDM0QsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDekIsQ0FBQztJQUVPLGVBQWUsQ0FBQyxLQUFhO1FBQ25DLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQztRQUN6QyxJQUFJLE1BQU07WUFBRSxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVqQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7UUFDdEMsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPLFNBQWtCLENBQUM7UUFFdEMsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdEIsQ0FBQztJQUVPLFdBQVcsQ0FDakIsUUFBOEQsRUFDOUQsS0FBYSxFQUNiLFNBQXNCO1FBRXRCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUU7WUFDOUMsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUN4RSxDQUFDLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDbEIsT0FBTyxDQUFDLENBQUM7UUFDWCxDQUFDLENBQUMsQ0FBQztRQUNILEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLFNBQVM7WUFBRSxTQUFTLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRS9ELHNFQUFzRTtRQUN0RSwyRUFBMkU7UUFDM0UsMEVBQTBFO1FBQzFFLHdFQUF3RTtRQUN4RSw0RUFBNEU7UUFDNUUsMEVBQTBFO1FBQzFFLGNBQWMsQ0FBQyxHQUFHLEVBQUU7WUFDbEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLDJCQUEyQixDQUNqQyxRQUE4RCxFQUM5RCxLQUFhLEVBQ2IsZ0JBQTZCO1FBRTdCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDNUQsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNiLGdFQUFnRTtZQUNoRSxtRUFBbUU7WUFDbkUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN6QyxRQUFRLENBQUMsT0FBTyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7WUFDbEMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQzdCLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztZQUMvQiwwRUFBMEU7WUFDMUUseUVBQXlFO1lBQ3pFLElBQUksUUFBUSxDQUFDLFNBQVMsQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLEtBQUssZ0JBQWdCLEVBQUUsQ0FBQztnQkFDdkYsS0FBSyxNQUFNLElBQUksSUFBSSxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUM7b0JBQ3RDLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDckMsQ0FBQztZQUNILENBQUM7WUFDRCxRQUFRLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDekIsT0FBTztRQUNULENBQUM7UUFFRCw2RUFBNkU7UUFDN0UsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNwQyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN6QyxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7WUFDaEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQzNCLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztZQUM3QixnQkFBZ0IsQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO1lBQ2xDLEtBQUssTUFBTSxJQUFJLElBQUksTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNwQyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDckMsQ0FBQztZQUNELE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNuRCxPQUFPO1FBQ1QsQ0FBQztRQUVELGdEQUFnRDtRQUNoRCxvRUFBb0U7UUFDcEUsb0VBQW9FO1FBQ3BFLHlFQUF5RTtRQUN6RSxnQkFBZ0IsQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO1FBRWxDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO1lBQ2hDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDeEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUIsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ2xCLE9BQU8sQ0FBQyxDQUFDO1FBQ1gsQ0FBQyxDQUFDLENBQUM7UUFFSCxLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNsQyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUVELElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNIOzs7Ozs7T0FNRztJQUNILHNCQUFzQjtRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBQzFCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBRXZDLEtBQUssTUFBTSxLQUFLLElBQUksUUFBUSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBQztZQUNsRCxNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckQsSUFBSSxDQUFDLFNBQVM7Z0JBQUUsU0FBUztZQUV6QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNqRCxJQUFJLENBQUMsSUFBSTtnQkFBRSxTQUFTO1lBRXBCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1lBQzlCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztZQUN6QixJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7WUFDM0IsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3ZCLENBQUM7SUFDSCxDQUFDO0lBRU8sZUFBZTtRQUNyQixLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztZQUNqRCxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM3QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDakIsQ0FBQztRQUNELElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDN0IsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDN0IsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUM7UUFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDNUIsQ0FBQzsrR0FqaEJVLHNCQUFzQjttR0FBdEIsc0JBQXNCOzs0RkFBdEIsc0JBQXNCO2tCQUpsQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxpQkFBaUI7b0JBQzNCLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjtvS0FHVSwwQkFBMEI7c0JBQWxDLEtBQUs7Z0JBR0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUdHLG9CQUFvQjtzQkFBNUIsS0FBSztnQkFHRyx5QkFBeUI7c0JBQWpDLEtBQUs7Z0JBT0csMkJBQTJCO3NCQUFuQyxLQUFLO2dCQUdHLG9CQUFvQjtzQkFBNUIsS0FBSztnQkFHRyx1QkFBdUI7c0JBQS9CLEtBQUs7Z0JBR0ksMkJBQTJCO3NCQUFwQyxNQUFNO2dCQUdHLDZCQUE2QjtzQkFBdEMsTUFBTTtnQkFHRyxrQkFBa0I7c0JBQTNCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBBcHBsaWNhdGlvblJlZixcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFbWJlZGRlZFZpZXdSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVGVtcGxhdGVSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQge1xuICB0eXBlIENlcmlvdXNTY3JvbGxPcHRpb25zIGFzIENvcmVDZXJpb3VzU2Nyb2xsT3B0aW9ucyxcbiAgdHlwZSBFbGVtZW50UmVuZGVyZXIsXG4gIHR5cGUgTWVhc3VyZWRWaWV3cG9ydFJhbmdlLFxufSBmcm9tICdAY2VyaW91c2RldnRlY2gvY2VyaW91cy1zY3JvbGwnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB0eXBlIHsgQ2VyaW91c1ZpZXdwb3J0Q2hhbmdlRGV0YWlsIH0gZnJvbSAnLi9jZXJpb3VzLXNjcm9sbC50eXBlcyc7XG5pbXBvcnQgdHlwZSB7IENlcmlvdXNTY3JvbGxPcHRpb25zIH0gZnJvbSAnLi9jZXJpb3VzLXNjcm9sbC50eXBlcyc7XG5pbXBvcnQgdHlwZSB7IENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVDb250ZXh0IH0gZnJvbSAnLi9jZXJpb3VzLXNjcm9sbC1pdGVtLXRlbXBsYXRlLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyB0eXBlIENlcmlvdXNTY3JvbGxIb3N0UmVmLCBDZXJpb3VzU2Nyb2xsU2VydmljZSB9IGZyb20gJy4vY2VyaW91cy1zY3JvbGwuc2VydmljZSc7XG5cbmZ1bmN0aW9uIGNvZXJjZVRvdGFsRWxlbWVudHMoZXhwbGljaXRUb3RhbDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCwgaXRlbXNMZW46IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQpOiBudW1iZXIge1xuICBjb25zdCBjYW5kaWRhdGUgPSB0eXBlb2YgZXhwbGljaXRUb3RhbCA9PT0gJ251bWJlcicgPyBleHBsaWNpdFRvdGFsIDogdHlwZW9mIGl0ZW1zTGVuID09PSAnbnVtYmVyJyA/IGl0ZW1zTGVuIDogdW5kZWZpbmVkO1xuICBpZiAoY2FuZGlkYXRlID09PSB1bmRlZmluZWQgfHwgTnVtYmVyLmlzTmFOKGNhbmRpZGF0ZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NlcmlvdXNTY3JvbGxEaXJlY3RpdmU6IHByb3ZpZGUgYGNlcmlvdXNTY3JvbGxUb3RhbEVsZW1lbnRzYCBvciBgY2VyaW91c1Njcm9sbEl0ZW1zYC4nKTtcbiAgfVxuICAvLyBDZXJpb3VzU2Nyb2xsIGN1cnJlbnRseSByZXF1aXJlcyA+PSAxXG4gIHJldHVybiBNYXRoLm1heCgxLCBjYW5kaWRhdGUpO1xufVxuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbY2VyaW91c1Njcm9sbF0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBDZXJpb3VzU2Nyb2xsRGlyZWN0aXZlPFRJdGVtID0gdW5rbm93bj4gaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIC8qKiBUb3RhbCBudW1iZXIgb2YgaXRlbXMuIElmIG9taXR0ZWQsIGRlcml2ZWQgZnJvbSBgY2VyaW91c1Njcm9sbEl0ZW1zLmxlbmd0aGAuICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxUb3RhbEVsZW1lbnRzOiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICAvKiogT3B0aW9uYWwgaXRlbXMgYXJyYXkgKGVuYWJsZXMgYGxldC1pdGVtYCkuICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxJdGVtczogcmVhZG9ubHkgVEl0ZW1bXSB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBPcHRpb25hbCBnZXR0ZXIgZm9yIGxhcmdlIGRhdGFzZXRzIChhbHRlcm5hdGl2ZSB0byBwYXNzaW5nIGZ1bGwgYGl0ZW1zYCkuICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxHZXRJdGVtOiAoKGluZGV4OiBudW1iZXIpID0+IFRJdGVtKSB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBUZW1wbGF0ZSB1c2VkIHRvIHJlbmRlciBlYWNoIHJvdy4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZTogVGVtcGxhdGVSZWY8Q2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQ8VEl0ZW0+PiB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBUYWJsZSBtb2RlIG9ubHk6IHRlbXBsYXRlIHJlbmRlcmVkIGludG8gdGhlIGVuZ2luZSdzIGA8dGhlYWQ+YCAoYSBgPHRyPmAgb2ZcbiAgICogYDx0aD5gcykuIEl0IGxpdmVzIGluIHRoZSBzYW1lIGA8dGFibGU+YCBhcyB0aGUgcm93cywgc28gY29sdW1ucyBhbGlnblxuICAgKiBuYXRpdmVseS4gVXBkYXRlcyB2aWEgY2hhbmdlIGRldGVjdGlvbiBsaWtlIHRoZSByb3dzLlxuICAgKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbEhlYWRlclRlbXBsYXRlOiBUZW1wbGF0ZVJlZjx1bmtub3duPiB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBPcHRpb25zIHBhc3NlZCB0byBgbmV3IENlcmlvdXNTY3JvbGwoLi4uKWAuICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxPcHRpb25zOiBDZXJpb3VzU2Nyb2xsT3B0aW9ucyA9IHt9O1xuXG4gIC8qKiBBdXRvbWF0aWNhbGx5IGNhbGwgcmVuZGVyIGFmdGVyIGVhY2ggc2Nyb2xsIGV2ZW50LiBEZWZhdWx0OiB0cnVlICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxBdXRvUmVuZGVyID0gdHJ1ZTtcblxuICAvKiogRW1pdHMgYGNlcmlvdXMtdmlld3BvcnQtY2hhbmdlYCBkZXRhaWwuICovXG4gIEBPdXRwdXQoKSBjZXJpb3VzU2Nyb2xsVmlld3BvcnRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPENlcmlvdXNWaWV3cG9ydENoYW5nZURldGFpbD4oKTtcblxuICAvKiogRW1pdHMgdGhlIGxhc3QgbWVhc3VyZWQgdmlld3BvcnQgYWZ0ZXIgZWFjaCByZW5kZXIgcGFzcy4gKi9cbiAgQE91dHB1dCgpIGNlcmlvdXNTY3JvbGxNZWFzdXJlZFZpZXdwb3J0ID0gbmV3IEV2ZW50RW1pdHRlcjxNZWFzdXJlZFZpZXdwb3J0UmFuZ2U+KCk7XG5cbiAgLyoqIEVtaXRzIG9uY2UgdGhlIHVuZGVybHlpbmcgYENlcmlvdXNTY3JvbGxgIGluc3RhbmNlIGlzIHJlYWR5LiAqL1xuICBAT3V0cHV0KCkgY2VyaW91c1Njcm9sbFJlYWR5ID0gbmV3IEV2ZW50RW1pdHRlcjxDZXJpb3VzU2Nyb2xsSG9zdFJlZlsnc2Nyb2xsZXInXT4oKTtcblxuICBwcml2YXRlIGhvc3RSZWY6IENlcmlvdXNTY3JvbGxIb3N0UmVmIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgdmlld3BvcnRTdWI6IFN1YnNjcmlwdGlvbiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHNjaGVkdWxlZFJlbmRlckZyYW1lOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLy8gSW5jcmVtZW50ZWQgYnkgdGhlIGNvcmUtb3duZWQgTWFzb25yeSByZW5kZXJlciB3aGVuZXZlciBpdCBtb3VudHMgYSBwcm9iZVxuICAvLyBvciB2aXNpYmxlIGNhcmQuIFVubGlrZSByb3cgbW9kZSwgdGhvc2UgY2FsbHMgZG8gbm90IGZsb3cgdGhyb3VnaCB0aGVcbiAgLy8gRWxlbWVudFJlbmRlcmVyIHBhc3NlZCB0byByZW5kZXJWaWV3cG9ydCgpLlxuICBwcml2YXRlIG1hc29ucnlSZW5kZXJlckVwb2NoID0gMDtcblxuICBwcml2YXRlIHJlYWRvbmx5IHZpZXdCeUNvbnRhaW5lciA9IG5ldyBNYXA8SFRNTEVsZW1lbnQsIEVtYmVkZGVkVmlld1JlZjxDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlQ29udGV4dDxUSXRlbT4+PigpO1xuICAvLyBQb29sIG9mIHZpZXdzIGRldGFjaGVkIGJlY2F1c2UgdGhlaXIgY29udGFpbmVyIGxlZnQgdGhlIHZpZXdwb3J0LiBSZXVzaW5nXG4gIC8vIHRoZW0gb24gc3Vic2VxdWVudCByZW5kZXJzIGF2b2lkcyBkZXN0cm95aW5nICsgcmVjcmVhdGluZyB0aGUgZW50aXJlIHJvd1xuICAvLyBjb21wb25lbnQgdHJlZSBvbiBmYXN0IHNjcm9sbHMgKHdoZXJlIHRoZSBlbmdpbmUncyBlbGVtZW50IHBvb2wgd2lwZXNcbiAgLy8gdGV4dENvbnRlbnQgb24gcmV1c2VkIGNvbnRhaW5lcnMsIHNvIHZpZXcgcm9vdE5vZGVzIGdldCBvcnBoYW5lZCkuXG4gIHByaXZhdGUgcmVhZG9ubHkgZnJlZVZpZXdzOiBFbWJlZGRlZFZpZXdSZWY8Q2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQ8VEl0ZW0+PltdID0gW107XG5cbiAgLy8gVGFibGUgbW9kZTogdGhlIGVtYmVkZGVkIHZpZXcgb2YgdGhlIGRlY2xhcmF0aXZlIGhlYWRlciwgcmVuZGVyZWQgaW50byB0aGVcbiAgLy8gZW5naW5lJ3MgPHRoZWFkPi5cbiAgcHJpdmF0ZSBoZWFkZXJWaWV3OiBFbWJlZGRlZFZpZXdSZWY8dW5rbm93bj4gfCBudWxsID0gbnVsbDtcblxuICAvKiogVW5kZXJseWluZyBjb3JlIGVuZ2luZSBpbnN0YW5jZSwgb3IgbnVsbCBiZWZvcmUgaW5pdGlhbGl6YXRpb24uICovXG4gIGdldCBzY3JvbGxlcigpOiBDZXJpb3VzU2Nyb2xsSG9zdFJlZlsnc2Nyb2xsZXInXSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmhvc3RSZWY/LnNjcm9sbGVyID8/IG51bGw7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGhvc3Q6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYXBwUmVmOiBBcHBsaWNhdGlvblJlZixcbiAgICBwcml2YXRlIHJlYWRvbmx5IG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2VyaW91czogQ2VyaW91c1Njcm9sbFNlcnZpY2VcbiAgKSB7fVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybjtcblxuICAgIGlmIChjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsSXRlbXMnXSB8fCBjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsVG90YWxFbGVtZW50cyddKSB7XG4gICAgICBjb25zdCB0b3RhbCA9IGNvZXJjZVRvdGFsRWxlbWVudHModGhpcy5jZXJpb3VzU2Nyb2xsVG90YWxFbGVtZW50cywgdGhpcy5jZXJpb3VzU2Nyb2xsSXRlbXM/Lmxlbmd0aCA/PyBudWxsKTtcbiAgICAgIGNvbnN0IG1hc29ucnlNb2RlID0gdGhpcy5jZXJpb3VzU2Nyb2xsT3B0aW9ucy5sYXlvdXQgPT09ICdtYXNvbnJ5JztcbiAgICAgIGNvbnN0IGN1cnJlbnRDb3VudCA9IG1hc29ucnlNb2RlXG4gICAgICAgID8gdGhpcy5ob3N0UmVmLnNjcm9sbGVyLml0ZW1Db3VudFxuICAgICAgICA6IHRoaXMuaG9zdFJlZi5zY3JvbGxlci50b3RhbEVsZW1lbnRzO1xuICAgICAgY29uc3QgY291bnRDaGFuZ2VkID0gY3VycmVudENvdW50ICE9PSB0b3RhbDtcblxuICAgICAgaWYgKGNvdW50Q2hhbmdlZCkge1xuICAgICAgICBpZiAobWFzb25yeU1vZGUpIHtcbiAgICAgICAgICAvLyBNYXNvbnJ5J3MgcmVuZGVyZXIgb3ducyBjYXJkLWNvdW50LWRlcml2ZWQgc2VnbWVudCBzdGF0ZS4gUmVjcmVhdGVcbiAgICAgICAgICAvLyBpdCB3aGVuIHRoZSBkYXRhc2V0IHNpemUgY2hhbmdlcyByYXRoZXIgdGhhbiB1cGRhdGluZyBzZWdtZW50IGNvdW50XG4gICAgICAgICAgLy8gdGhyb3VnaCB0aGUgcm93LW9yaWVudGVkIHVwZGF0ZVRvdGFsRWxlbWVudHMgQVBJLlxuICAgICAgICAgIHRoaXMucmVjcmVhdGUoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gR3Jvdy9zaHJpbmsgdGhlIGRhdGFzZXQgSU4gUExBQ0Ug4oCUIG5vIHJlY3JlYXRlLiB1cGRhdGVUb3RhbEVsZW1lbnRzXG4gICAgICAgIC8vIHByb3BhZ2F0ZXMgdGhlIG5ldyBjb3VudCB0byBldmVyeSBzdWJzeXN0ZW0sIElOQ0xVRElORyB0aGVcbiAgICAgICAgLy8gVmlld3BvcnRSZW5kZXJlcidzIG93biBjb3B5IG9mIHRvdGFsRWxlbWVudHMgKGl0IHVzZWQgdG8gZ28gc3RhbGUsXG4gICAgICAgIC8vIHdoaWNoIGlzIGV4YWN0bHkgd2h5IHRoaXMgcmVjcmVhdGVkOiB0aGUgcmVuZGVyZXIga2VwdCB0aGUgb2xkIGNvdW50XG4gICAgICAgIC8vIGZvciBpdHMgdmlld3BvcnQtZmlsbCBsb29wIGFuZCBib3R0b20gc2NhbiwgcHJvZHVjaW5nIHBoYW50b21cbiAgICAgICAgLy8gb3V0LW9mLWJvdW5kcyByZW5kZXJzKS4gSW4gcGxhY2Uga2VlcHMgdGhlIHNjcm9sbCBwb3NpdGlvbiBhbmQgYW5cbiAgICAgICAgLy8gaW4tcHJvZ3Jlc3Mgc2Nyb2xsYmFyIGRyYWcgYWxpdmUsIGFuZCBhIGdyb3dpbmcgZGF0YXNldCBrZWVwcyBhIHN0YWJsZVxuICAgICAgICAvLyBib3R0b20gaW5kZXggKG5vIGJvdW5jaW5nIHRhaWwpLiBUaGUgdHJhY2sgbGVuZ3RoZW5zLCBzbyByZS1zeW5jIHRoZVxuICAgICAgICAvLyB0aHVtYiBhZnRlcndhcmRzLlxuICAgICAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIudXBkYXRlVG90YWxFbGVtZW50cyh0b3RhbCk7XG4gICAgICAgIC8vIEEgc2hyaW5rIGNhbiBsZWF2ZSB0aGUgcG9zaXRpb24gcGFzdCB0aGUgbmV3IGVuZCDigJQgY2xhbXAgaXQuXG4gICAgICAgIGlmICh0aGlzLmhvc3RSZWYuc2Nyb2xsZXIuY3VycmVudEVsZW1lbnQgPiB0b3RhbCAtIDEpIHtcbiAgICAgICAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIuanVtcFRvRWxlbWVudCh0b3RhbCAtIDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmNlcmlvdXNTY3JvbGxBdXRvUmVuZGVyKSB0aGlzLnJlbmRlcigpO1xuICAgICAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIuc3luY1Njcm9sbGJhcigpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmNlcmlvdXNTY3JvbGxBdXRvUmVuZGVyKSB7XG4gICAgICAgIC8vIFNhbWUgY291bnQsIG5ldyBkYXRhIHJlZmVyZW5jZSAoZS5nLiBhbiBpbW11dGFibGUgZWRpdCBvciBhIHNvcnQgdGhhdFxuICAgICAgICAvLyBoYXBwZW5zIHRvIGtlZXAgdGhlIHNhbWUgbGVuZ3RoKS4gVGhlIGVuZ2luZSByZXVzZXMgdGhlIERPTSBlbGVtZW50IGl0XG4gICAgICAgIC8vIGFscmVhZHkgcmVuZGVyZWQgZm9yIGVhY2ggb3ZlcmxhcHBpbmcgaW5kZXggd2l0aG91dCByZS1pbnZva2luZyB0aGVcbiAgICAgICAgLy8gcmVuZGVyZXIsIHNvIHVwZGF0ZSB0aGUgY29udGVudCBvZiBldmVyeSBjdXJyZW50bHktdmlzaWJsZSByb3cgSU5cbiAgICAgICAgLy8gUExBQ0UgYmVmb3JlIGNhbGxpbmcgcmVuZGVyKCkuICBUaGlzIHByZXNlcnZlcyBlYWNoIHJvdydzIGVtYmVkZGVkXG4gICAgICAgIC8vIHZpZXcgKHNvIGEgZm9jdXNlZCB0ZXh0Ym94IGtlZXBzIGZvY3VzL2NhcmV0KSBhbmQgZG9lcyBOT1QgZGlzY2FyZFxuICAgICAgICAvLyBjYWNoZWQgaGVpZ2h0cy4gSWYgYSByb3cncyBoZWlnaHQgYWN0dWFsbHkgY2hhbmdlcyB0aGUgZW5naW5lJ3NcbiAgICAgICAgLy8gUmVzaXplT2JzZXJ2ZXIga2VlcHMgdGhlIGNhY2hlIGNvcnJlY3Qgb24gaXRzIG93bjsgZm9yIGEgd2hvbGVzYWxlXG4gICAgICAgIC8vIGhlaWdodCBjaGFuZ2UgYWNyb3NzIGFsbCByb3dzLCBjYWxsIHJlY2FsY3VsYXRlKCkgaW5zdGVhZC5cbiAgICAgICAgdGhpcy5yZWZyZXNoUmVuZGVyZWRDb250ZW50KCk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXNbJ2NlcmlvdXNTY3JvbGxPcHRpb25zJ10gJiYgIWNoYW5nZXNbJ2NlcmlvdXNTY3JvbGxPcHRpb25zJ10uZmlyc3RDaGFuZ2UpIHtcbiAgICAgIC8vIE9wdGlvbnMgYXJlIGNvbnN1bWVkIHByaW1hcmlseSBhdCBjb25zdHJ1Y3Rpb24gdGltZS5cbiAgICAgIHRoaXMucmVjcmVhdGUoKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zY2hlZHVsZWRSZW5kZXJGcmFtZSAhPSBudWxsKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLnNjaGVkdWxlZFJlbmRlckZyYW1lKTtcbiAgICAgIHRoaXMuc2NoZWR1bGVkUmVuZGVyRnJhbWUgPSBudWxsO1xuICAgIH1cblxuICAgIHRoaXMudmlld3BvcnRTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy52aWV3cG9ydFN1YiA9IG51bGw7XG5cbiAgICB0aGlzLmRlc3Ryb3lBbGxWaWV3cygpO1xuICAgIHRoaXMuaGVhZGVyVmlldz8uZGVzdHJveSgpO1xuICAgIHRoaXMuaGVhZGVyVmlldyA9IG51bGw7XG5cbiAgICB0aGlzLmhvc3RSZWY/LmRlc3Ryb3koKTtcbiAgICB0aGlzLmhvc3RSZWYgPSBudWxsO1xuICB9XG5cbiAgLyoqIEltcGVyYXRpdmVseSB0cmlnZ2VyIGEgcmVuZGVyIHBhc3MgKHVzZXMgYGNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVgKS4gKi9cbiAgcmVuZGVyKCk6IE1lYXN1cmVkVmlld3BvcnRSYW5nZSB8IG51bGwge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCB0ZW1wbGF0ZSA9IHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZTtcbiAgICBpZiAoIXRlbXBsYXRlKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IGhvc3RDb250YWluZXIgPSB0aGlzLmhvc3QubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCBoZWlnaHQgPSBob3N0Q29udGFpbmVyLmNsaWVudEhlaWdodCB8fCBob3N0Q29udGFpbmVyLm9mZnNldEhlaWdodDtcbiAgICBjb25zdCBjb250ZW50Q29udGFpbmVyID0gdGhpcy5ob3N0UmVmLmNvbnRlbnRFbGVtZW50O1xuXG4gICAgLy8gVHJhY2sgd2hldGhlciB0aGUgZW5naW5lIGFza2VkIHVzIHRvIGJpbmQgYW55IHJvdyB0aGlzIHBhc3MuIFB1cmUgc2Nyb2xsXG4gICAgLy8gZnJhbWVzIHdoZXJlIHRoZSB2aXNpYmxlIHJvdyBzZXQgZG9lc24ndCBjaGFuZ2Ugc3RpbGwgZHJpdmUgcmVuZGVyKCkgdmlhXG4gICAgLy8gdGhlIHJBRiBjb2FsZXNjZXIg4oCUIHRoZXJlJ3Mgbm8gcG9pbnQgaW4gd2Fsa2luZyB0aGUgcHJ1bmUgbWFwIG9yXG4gICAgLy8gZW1pdHRpbmcgdGhlIHZpZXdwb3J0IHJhbmdlIHdoZW4gbm90aGluZyB3YXMgdG91Y2hlZC5cbiAgICBsZXQgcmVuZGVyZXJJbnZvY2F0aW9ucyA9IDA7XG4gICAgY29uc3QgcmVuZGVyZXI6IEVsZW1lbnRSZW5kZXJlciA9IChpbmRleCwgZWxlbWVudENvbnRhaW5lcikgPT4ge1xuICAgICAgcmVuZGVyZXJJbnZvY2F0aW9ucysrO1xuICAgICAgLy8gUmVuZGVyIGVhY2ggcm93J3MgZW1iZWRkZWQgdmlldyB3aXRoIExPQ0FMIGNoYW5nZSBkZXRlY3Rpb25cbiAgICAgIC8vIChgdmlldy5kZXRlY3RDaGFuZ2VzKClgIGluc2lkZSBgcmVuZGVyVGVtcGxhdGVJbnRvQ29udGFpbmVyYCkgc28gdGhlXG4gICAgICAvLyBlbmdpbmUgY2FuIG1lYXN1cmUgaXRzIGhlaWdodCBkdXJpbmcgdGhpcyBwYXNzLiBEbyBOT1Qgd3JhcCBlYWNoIHJvdyBpblxuICAgICAgLy8gaXRzIG93biBgbmdab25lLnJ1bmAg4oCUIHRoYXQgZmlyZXMgYSBmdWxsIGBBcHBsaWNhdGlvblJlZmAgdGljayAqcGVyIHJvdypcbiAgICAgIC8vIChPKG5ld1Jvd3Mgw5cgdmlzaWJsZVJvd3MpIHdvcmssIGphbmt5IGRyYWdzKS4gVGhlIHNpbmdsZSBjb2FsZXNjZWQgdGlja1xuICAgICAgLy8gZm9yIHRoZSB3aG9sZSBwYXNzIGlzIGhhbmRsZWQgYnkgdGhlIGNhbGxlciAoYHNjaGVkdWxlUmVuZGVyYCkuXG4gICAgICB0aGlzLnJlbmRlclRlbXBsYXRlSW50b0NvbnRhaW5lcih0ZW1wbGF0ZSwgaW5kZXgsIGVsZW1lbnRDb250YWluZXIpO1xuICAgIH07XG5cbiAgICBjb25zdCBtYXNvbnJ5TW9kZSA9IHRoaXMuY2VyaW91c1Njcm9sbE9wdGlvbnMubGF5b3V0ID09PSAnbWFzb25yeSc7XG4gICAgY29uc3QgbWFzb25yeUVwb2NoQmVmb3JlID0gdGhpcy5tYXNvbnJ5UmVuZGVyZXJFcG9jaDtcbiAgICBjb25zdCByYW5nZSA9IHRoaXMuaG9zdFJlZi5zY3JvbGxlci5yZW5kZXJWaWV3cG9ydChoZWlnaHQsIGNvbnRlbnRDb250YWluZXIsIHJlbmRlcmVyKTtcbiAgICBjb25zdCBtYXNvbnJ5SW52b2NhdGlvbnMgPSB0aGlzLm1hc29ucnlSZW5kZXJlckVwb2NoIC0gbWFzb25yeUVwb2NoQmVmb3JlO1xuXG4gICAgaWYgKHJlbmRlcmVySW52b2NhdGlvbnMgPT09IDAgJiYgKCFtYXNvbnJ5TW9kZSB8fCBtYXNvbnJ5SW52b2NhdGlvbnMgPT09IDApKSB7XG4gICAgICAvLyBWaWV3cG9ydCBkaWRuJ3QgY2hhbmdlIOKAlCBza2lwIHRoZSBwcnVuZSB3YWxrIGFuZCB0aGUgKHBvdGVudGlhbGx5XG4gICAgICAvLyB6b25lLWVudGVyaW5nKSBlbWl0LlxuICAgICAgcmV0dXJuIHJhbmdlO1xuICAgIH1cblxuICAgIC8vIERlc3Ryb3kgdmlld3Mgd2hvc2UgY29udGFpbmVyIHRoZSBlbmdpbmUgbm8gbG9uZ2VyIHJlbmRlcnMuIFdpdGhvdXQgdGhpcyxcbiAgICAvLyBldmVyeSBjb250YWluZXIgdGhlIGVuZ2luZSByZWN5Y2xlcyBpbnRvIGl0cyBlbGVtZW50IHBvb2wgbGVhdmVzIGl0c1xuICAgIC8vIGVtYmVkZGVkIHZpZXcgYXR0YWNoZWQgdG8gQXBwbGljYXRpb25SZWYgZm9yZXZlciDigJQgc28gdGhlIGF0dGFjaGVkLXZpZXdcbiAgICAvLyBsaXN0IChhbmQgZXZlcnkgTyhuKSBgZGV0YWNoVmlld2ApIGdyb3dzIHdpdGhvdXQgYm91bmQgYW5kIHNjcm9sbGluZyBnZXRzXG4gICAgLy8gcHJvZ3Jlc3NpdmVseSBzbG93ZXIuIE1pcnJvcnMgdGhlIFJlYWN0L1Z1ZSB3cmFwcGVycywgd2hpY2ggZHJvcCByb3dzIHRoYXRcbiAgICAvLyBmYWxsIG91dCBvZiBgZ2V0UmVuZGVyZWRJbmRpY2VzKClgLlxuICAgIHRoaXMucHJ1bmVEZXRhY2hlZFZpZXdzKCk7XG5cbiAgICAvLyBPbmx5IHJlLWVudGVyIHRoZSB6b25lIChhIGdsb2JhbCB0aWNrKSBpZiBzb21lb25lIGlzIGFjdHVhbGx5IGxpc3RlbmluZy5cbiAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsTWVhc3VyZWRWaWV3cG9ydC5vYnNlcnZlZCkge1xuICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuY2VyaW91c1Njcm9sbE1lYXN1cmVkVmlld3BvcnQuZW1pdChyYW5nZSkpO1xuICAgIH1cbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cblxuICAvKiogVGVhciBkb3duIGVtYmVkZGVkIHZpZXdzIHdob3NlIGNvbnRhaW5lciBpcyBubyBsb25nZXIgcGFydCBvZiB0aGUgdmlld3BvcnQuICovXG4gIHByaXZhdGUgcHJ1bmVEZXRhY2hlZFZpZXdzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5ob3N0UmVmIHx8IHRoaXMudmlld0J5Q29udGFpbmVyLnNpemUgPT09IDApIHJldHVybjtcbiAgICBjb25zdCBzY3JvbGxlciA9IHRoaXMuaG9zdFJlZi5zY3JvbGxlcjtcbiAgICBjb25zdCBtYXNvbnJ5TW9kZSA9IHRoaXMuY2VyaW91c1Njcm9sbE9wdGlvbnMubGF5b3V0ID09PSAnbWFzb25yeSc7XG4gICAgY29uc3QgYWN0aXZlID0gbmV3IFNldDxIVE1MRWxlbWVudD4oKTtcbiAgICBpZiAobWFzb25yeU1vZGUpIHtcbiAgICAgIHRoaXMuaG9zdC5uYXRpdmVFbGVtZW50XG4gICAgICAgIC5xdWVyeVNlbGVjdG9yQWxsPEhUTUxFbGVtZW50PignW2RhdGEtZWxlbWVudC1pbmRleF0nKVxuICAgICAgICAuZm9yRWFjaCgoZWwpID0+IGFjdGl2ZS5hZGQoZWwpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChjb25zdCBpbmRleCBvZiBzY3JvbGxlci5nZXRSZW5kZXJlZEluZGljZXMoKSkge1xuICAgICAgICBjb25zdCBlbCA9IHNjcm9sbGVyLmdldFJlbmRlcmVkRWxlbWVudChpbmRleCk7XG4gICAgICAgIGlmIChlbCkgYWN0aXZlLmFkZChlbCk7XG4gICAgICB9XG4gICAgfVxuICAgIGZvciAoY29uc3QgW2NvbnRhaW5lciwgdmlld10gb2YgdGhpcy52aWV3QnlDb250YWluZXIpIHtcbiAgICAgIGlmICghYWN0aXZlLmhhcyhjb250YWluZXIpKSB7XG4gICAgICAgIC8vIERldGFjaCBET00gYnV0IGtlZXAgdGhlIHZpZXcgYWxpdmUgaW4gdGhlIHBvb2wgZm9yIGZ1dHVyZSByZXVzZS5cbiAgICAgICAgLy8gRGVzdHJveWluZyArIHJlY3JlYXRpbmcgdmlld3MgcGVyIHNjcm9sbCBzdGVwIGRvbWluYXRlcyBmcmFtZSB0aW1lLlxuICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygdmlldy5yb290Tm9kZXMpIHtcbiAgICAgICAgICBpZiAobm9kZS5wYXJlbnROb2RlKSBub2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy52aWV3QnlDb250YWluZXIuZGVsZXRlKGNvbnRhaW5lcik7XG4gICAgICAgIHRoaXMuZnJlZVZpZXdzLnB1c2godmlldyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIEF1dG8tcmVuZGVyIGNvYWxlc2NlZCB0byBhdCBtb3N0IG9uY2UgcGVyIGFuaW1hdGlvbiBmcmFtZS4gKi9cbiAgcHJpdmF0ZSBzY2hlZHVsZVJlbmRlcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zY2hlZHVsZWRSZW5kZXJGcmFtZSAhPSBudWxsKSByZXR1cm47XG4gICAgdGhpcy5zY2hlZHVsZWRSZW5kZXJGcmFtZSA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICB0aGlzLnNjaGVkdWxlZFJlbmRlckZyYW1lID0gbnVsbDtcbiAgICAgIC8vIFJ1biByZW5kZXIoKSBPVVRTSURFIEFuZ3VsYXIncyB6b25lLiBBIGZ1bGwgQXBwbGljYXRpb25SZWYudGljaygpIG9uXG4gICAgICAvLyBldmVyeSBzY3JvbGwgZnJhbWUgaXMgdGhlIHByaW1hcnkgRlBTIGJvdHRsZW5lY2s6IGV2ZW4gd2hlbiBubyByb3dzXG4gICAgICAvLyBjaGFuZ2UgKHB1cmUgdHJhbnNsYXRpb24pLCBuZ1pvbmUucnVuKCkgY2F1c2VzIEFuZ3VsYXIgdG8gd2FsayB0aGVcbiAgICAgIC8vIGVudGlyZSBjb21wb25lbnQgdHJlZS4gSW5zdGVhZCB3ZSBjYWxsIHZpZXcuZGV0ZWN0Q2hhbmdlcygpIGxvY2FsbHlcbiAgICAgIC8vIGluc2lkZSByZW5kZXJUZW1wbGF0ZUludG9Db250YWluZXIgZm9yIGVhY2ggYWZmZWN0ZWQgcm93LiBab25lIGVudHJ5IGlzXG4gICAgICAvLyBvbmx5IG5lZWRlZCB3aGVuIGNyZWF0aW5nIGEgYnJhbmQtbmV3IGVtYmVkZGVkIHZpZXcgKHRvIHpvbmUtcGF0Y2ggaXRzXG4gICAgICAvLyBldmVudCBsaXN0ZW5lcnMpIOKAlCByZWN5Y2xlZCBhbmQgcG9vbGVkIHZpZXdzIHdlcmUgYWxyZWFkeSBjcmVhdGVkIGluc2lkZVxuICAgICAgLy8gem9uZSBhbmQgdGhlaXIgbGlzdGVuZXJzIHJlbWFpbiB6b25lLWF3YXJlLlxuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNjYXJkIGFsbCBjYWNoZWQgcm93IGhlaWdodHMgYW5kIHJlLW1lYXN1cmUgdGhlIHZpZXdwb3J0LlxuICAgKlxuICAgKiBDYWxsIHRoaXMgb25seSB3aGVuIHRoZSBoZWlnaHRzIG9mIHJvd3MgeW91J3ZlICphbHJlYWR5IHJlbmRlcmVkKiBtYXkgaGF2ZVxuICAgKiBjaGFuZ2VkIHdpdGhvdXQgdGhlaXIgaW5kaWNlcyBjaGFuZ2luZyDigJQgZS5nLiBhIGdsb2JhbCBmb250L2RlbnNpdHkgY2hhbmdlLFxuICAgKiBvciBzd2FwcGluZyBldmVyeSByb3cgdG8gYSBkaWZmZXJlbnQgbGF5b3V0LiBUaGlzIGZvcmNlcyBhIHN5bmNocm9ub3VzXG4gICAqIHJlLW1lYXN1cmUgKG9uZSBgb2Zmc2V0SGVpZ2h0YCByZWFkIHBlciB2aXNpYmxlIHJvdyksIHNvIGRvIE5PVCBjYWxsIGl0IG9uXG4gICAqIHJvdXRpbmUgZWRpdHM6IGEgc2luZ2xlIGNlbGwgZWRpdCBrZWVwcyBpdHMgcm93J3Mgc2l6ZSwgYW5kIHRoZSBlbmdpbmUnc1xuICAgKiBSZXNpemVPYnNlcnZlciBwaWNrcyB1cCBhbnkgaW5jaWRlbnRhbCByZXNpemUgb24gaXRzIG93bi5cbiAgICovXG4gIHJlY2FsY3VsYXRlKCk6IE1lYXN1cmVkVmlld3BvcnRSYW5nZSB8IG51bGwge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCB0ZW1wbGF0ZSA9IHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZTtcbiAgICBpZiAodGVtcGxhdGUpIHtcbiAgICAgIC8vIFJlLWludm9rZSB0aGUgcmVuZGVyZXIgZm9yIGV2ZXJ5IGN1cnJlbnRseS1yZW5kZXJlZCByb3cgc28gcGVuZGluZ1xuICAgICAgLy8gQW5ndWxhciBiaW5kaW5ncyBmbHVzaCBpbnRvIHRoZSBET00gYW5kIHRoZSBlbmdpbmUgcmUtbWVhc3VyZXMgZWFjaFxuICAgICAgLy8gcm93J3MgbmV3IGhlaWdodCBpbnRvIGl0cyBjYWNoZS4gV2l0aG91dCB0aGlzLCB0aGUgZW5naW5lJ3MgcmVuZGVyXG4gICAgICAvLyBwYXNzIHNraXBzIHRoZSByZW5kZXJlciBmb3IgYWxyZWFkeS1yZW5kZXJlZCBpbmRpY2VzIGFuZCBmYWxsc1xuICAgICAgLy8gdGhyb3VnaCB0byByZWFkaW5nIHN0YWxlIG9mZnNldEhlaWdodC5cbiAgICAgIHRoaXMuaG9zdFJlZi5zY3JvbGxlci5yZWZyZXNoVmlzaWJsZSgoaW5kZXgsIGVsZW1lbnRDb250YWluZXIpID0+IHtcbiAgICAgICAgdGhpcy5yZW5kZXJUZW1wbGF0ZUludG9Db250YWluZXIodGVtcGxhdGUsIGluZGV4LCBlbGVtZW50Q29udGFpbmVyKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBKdW1wIGRpcmVjdGx5IHRvIGFuIGVsZW1lbnQgaW5kZXgsIHRoZW4gcmVuZGVyLiAqL1xuICBqdW1wVG9FbGVtZW50KGluZGV4OiBudW1iZXIpOiBNZWFzdXJlZFZpZXdwb3J0UmFuZ2UgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZikgcmV0dXJuIG51bGw7XG4gICAgdGhpcy5ob3N0UmVmLnNjcm9sbGVyLmp1bXBUb0VsZW1lbnQoaW5kZXgpO1xuICAgIHJldHVybiB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgLyoqIE1hc29ucnkgbW9kZSBvbmx5OiBqdW1wIGRpcmVjdGx5IHRvIGEgY2FyZCBpbmRleCwgdGhlbiByZW5kZXIuICovXG4gIGp1bXBUb0l0ZW0oaW5kZXg6IG51bWJlciwgc2NyZWVuT2Zmc2V0ID0gMCk6IE1lYXN1cmVkVmlld3BvcnRSYW5nZSB8IG51bGwge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm4gbnVsbDtcbiAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIuanVtcFRvSXRlbShpbmRleCwgc2NyZWVuT2Zmc2V0KTtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBTY3JvbGwgdG8gYSBwZXJjZW50YWdlICgwLi4xMDApLCB0aGVuIHJlbmRlci4gKi9cbiAgc2Nyb2xsVG9QZXJjZW50YWdlKHBlcmNlbnRhZ2U6IG51bWJlcik6IE1lYXN1cmVkVmlld3BvcnRSYW5nZSB8IG51bGwge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm4gbnVsbDtcbiAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIuaGFuZGxlU2Nyb2xsUGVyY2VudGFnZShwZXJjZW50YWdlKTtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBSZXNldCB0byB0aGUgdG9wLCB0aGVuIHJlbmRlci4gKi9cbiAgcmVzZXQoKTogTWVhc3VyZWRWaWV3cG9ydFJhbmdlIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybiBudWxsO1xuICAgIHRoaXMuaG9zdFJlZi5zY3JvbGxlci5yZXNldCgpO1xuICAgIHJldHVybiB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWNyZWF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLnZpZXdwb3J0U3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMudmlld3BvcnRTdWIgPSBudWxsO1xuXG4gICAgdGhpcy5kZXN0cm95QWxsVmlld3MoKTtcblxuICAgIHRoaXMuaG9zdFJlZj8uZGVzdHJveSgpO1xuICAgIHRoaXMuaG9zdFJlZiA9IG51bGw7XG5cbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZUluaXRpYWxpemVkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhvc3RSZWYpIHJldHVybjtcblxuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuaG9zdC5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IHRvdGFsID0gY29lcmNlVG90YWxFbGVtZW50cyh0aGlzLmNlcmlvdXNTY3JvbGxUb3RhbEVsZW1lbnRzLCB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtcz8ubGVuZ3RoID8/IG51bGwpO1xuXG4gICAgLy8gVGFibGUgbW9kZTogY2FwdHVyZSB0aGUgZW5naW5lLWNyZWF0ZWQgPHRoZWFkPiBzbyB3ZSBjYW4gcmVuZGVyIHRoZVxuICAgIC8vIGRlY2xhcmF0aXZlIGhlYWRlciB0ZW1wbGF0ZSBpbnRvIGl0IChhbmQgc3RpbGwgcnVuIGFueSB1c2VyIGhlYWRlciBob29rKS5cbiAgICBsZXQgb3B0aW9uczogQ29yZUNlcmlvdXNTY3JvbGxPcHRpb25zO1xuICAgIGlmICh0aGlzLmNlcmlvdXNTY3JvbGxPcHRpb25zLmxheW91dCA9PT0gJ21hc29ucnknKSB7XG4gICAgICBpZiAoIXRoaXMuY2VyaW91c1Njcm9sbE9wdGlvbnMubWFzb25yeSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDZXJpb3VzU2Nyb2xsRGlyZWN0aXZlOiBsYXlvdXQgJ21hc29ucnknIHJlcXVpcmVzIGBjZXJpb3VzU2Nyb2xsT3B0aW9ucy5tYXNvbnJ5YC5cIik7XG4gICAgICB9XG4gICAgICBvcHRpb25zID0ge1xuICAgICAgICAuLi50aGlzLmNlcmlvdXNTY3JvbGxPcHRpb25zLFxuICAgICAgICBtYXNvbnJ5OiB7XG4gICAgICAgICAgLi4udGhpcy5jZXJpb3VzU2Nyb2xsT3B0aW9ucy5tYXNvbnJ5LFxuICAgICAgICAgIHJlbmRlckl0ZW06IChpbmRleCwgZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5tYXNvbnJ5UmVuZGVyZXJFcG9jaCsrO1xuICAgICAgICAgICAgY29uc3QgdGVtcGxhdGUgPSB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGU7XG4gICAgICAgICAgICBpZiAoIXRlbXBsYXRlKSByZXR1cm47XG4gICAgICAgICAgICBpZiAoZWxlbWVudC5kYXRhc2V0WydjZXJpb3VzTWFzb25yeSddID09PSAncHJvYmUnKSB7XG4gICAgICAgICAgICAgIHRoaXMucmVuZGVyUHJvYmUodGVtcGxhdGUsIGluZGV4LCBlbGVtZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRoaXMucmVuZGVyVGVtcGxhdGVJbnRvQ29udGFpbmVyKHRlbXBsYXRlLCBpbmRleCwgZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMgPSB0aGlzLmNlcmlvdXNTY3JvbGxPcHRpb25zIGFzIENvcmVDZXJpb3VzU2Nyb2xsT3B0aW9ucztcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMubGF5b3V0ID09PSAndGFibGUnICYmIHRoaXMuY2VyaW91c1Njcm9sbEhlYWRlclRlbXBsYXRlKSB7XG4gICAgICBjb25zdCB1c2VySGVhZGVyID0gb3B0aW9ucy50YWJsZT8uaGVhZGVyO1xuICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgdGFibGU6IHtcbiAgICAgICAgICAuLi5vcHRpb25zLnRhYmxlLFxuICAgICAgICAgIGhlYWRlcjogKHRoZWFkOiBIVE1MVGFibGVTZWN0aW9uRWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgdXNlckhlYWRlcj8uKHRoZWFkKTtcbiAgICAgICAgICAgIHRoaXMubW91bnRIZWFkZXIodGhlYWQpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMuaG9zdFJlZiA9IHRoaXMuY2VyaW91cy5jcmVhdGVIb3N0KGNvbnRhaW5lciwgdG90YWwsIG9wdGlvbnMsIHRoaXMubmdab25lLCAoKSA9PiB7XG4gICAgICAvLyBDb2FsZXNjZSBzY3JvbGwtZHJpdmVuIHJlbmRlcnMgdG8gb25lIHBlciBmcmFtZSAodGhlIG5hdGl2ZSBzY3JvbGxiYXJcbiAgICAgIC8vIGNhbiBmaXJlIG1hbnkgc2Nyb2xsIGV2ZW50cyBiZXR3ZWVuIHBhaW50cykuXG4gICAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikgdGhpcy5zY2hlZHVsZVJlbmRlcigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy52aWV3cG9ydFN1YiA9IHRoaXMuaG9zdFJlZi52aWV3cG9ydENoYW5nZXMkLnN1YnNjcmliZSgoZGV0YWlsOiBDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWwpID0+IHtcbiAgICAgIC8vIFNraXAgdGhlIGdsb2JhbCB0aWNrIHdoZW4gbm9ib2R5IGlzIGJvdW5kIHRvIHRoZSBvdXRwdXQuXG4gICAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsVmlld3BvcnRDaGFuZ2Uub2JzZXJ2ZWQpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuY2VyaW91c1Njcm9sbFZpZXdwb3J0Q2hhbmdlLmVtaXQoZGV0YWlsKSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmNlcmlvdXNTY3JvbGxSZWFkeS5lbWl0KHRoaXMuaG9zdFJlZi5zY3JvbGxlcik7XG5cbiAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikge1xuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy5yZW5kZXIoKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgZGVjbGFyYXRpdmUgaGVhZGVyIHRlbXBsYXRlIGludG8gdGhlIGVuZ2luZSdzIDx0aGVhZD4uIE9uZVxuICAgKiBlbWJlZGRlZCB2aWV3LCBjcmVhdGVkIGluc2lkZSB0aGUgem9uZSAoc28gdGhlIGhlYWRlcidzIGV2ZW50IGJpbmRpbmdzIGFyZVxuICAgKiB6b25lLXBhdGNoZWQpLCBpdHMgcm9vdCBub2RlcyBhcHBlbmRlZCBkaXJlY3RseSBpbnRvIHRoZSA8dGhlYWQ+LlxuICAgKi9cbiAgcHJpdmF0ZSBtb3VudEhlYWRlcih0aGVhZDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2VyaW91c1Njcm9sbEhlYWRlclRlbXBsYXRlKSByZXR1cm47XG4gICAgdGhpcy5oZWFkZXJWaWV3Py5kZXN0cm95KCk7XG4gICAgY29uc3QgdmlldyA9IHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICBjb25zdCB2ID0gdGhpcy5jZXJpb3VzU2Nyb2xsSGVhZGVyVGVtcGxhdGUhLmNyZWF0ZUVtYmVkZGVkVmlldyh7fSk7XG4gICAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHYpO1xuICAgICAgdi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICByZXR1cm4gdjtcbiAgICB9KTtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygdmlldy5yb290Tm9kZXMpIHRoZWFkLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgIHRoaXMuaGVhZGVyVmlldyA9IHZpZXc7XG4gIH1cblxuICBwcml2YXRlIGdldEl0ZW1Gb3JJbmRleChpbmRleDogbnVtYmVyKTogVEl0ZW0ge1xuICAgIGNvbnN0IGdldHRlciA9IHRoaXMuY2VyaW91c1Njcm9sbEdldEl0ZW07XG4gICAgaWYgKGdldHRlcikgcmV0dXJuIGdldHRlcihpbmRleCk7XG5cbiAgICBjb25zdCBpdGVtcyA9IHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1zO1xuICAgIGlmICghaXRlbXMpIHJldHVybiB1bmRlZmluZWQgYXMgVEl0ZW07XG5cbiAgICByZXR1cm4gaXRlbXNbaW5kZXhdO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJQcm9iZShcbiAgICB0ZW1wbGF0ZTogVGVtcGxhdGVSZWY8Q2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQ8VEl0ZW0+PixcbiAgICBpbmRleDogbnVtYmVyLFxuICAgIGNvbnRhaW5lcjogSFRNTEVsZW1lbnRcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgaXRlbSA9IHRoaXMuZ2V0SXRlbUZvckluZGV4KGluZGV4KTtcbiAgICBjb25zdCB2aWV3ID0gdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgY29uc3QgdiA9IHRlbXBsYXRlLmNyZWF0ZUVtYmVkZGVkVmlldyh7ICRpbXBsaWNpdDogaXRlbSwgaXRlbSwgaW5kZXggfSk7XG4gICAgICB2LmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHJldHVybiB2O1xuICAgIH0pO1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB2aWV3LnJvb3ROb2RlcykgY29udGFpbmVyLmFwcGVuZENoaWxkKG5vZGUpO1xuXG4gICAgLy8gTWVhc3VyZW1lbnQgcHJvYmVzIGFyZSBkZWxpYmVyYXRlbHkgTk9UIGF0dGFjaGVkIHRvIEFwcGxpY2F0aW9uUmVmOlxuICAgIC8vIHRoZXkgYXJlIGRpc3Bvc2FibGUsIG5vbi1pbnRlcmFjdGl2ZSBtYXJrdXAgYW5kIGxvY2FsIGRldGVjdENoYW5nZXMoKSBpc1xuICAgIC8vIGVub3VnaCB0byBwb3B1bGF0ZSB0aGVpciBET00gc3luY2hyb25vdXNseS4gQXR0YWNoaW5nIGVhY2ggcHJvYmUgaW5zaWRlXG4gICAgLy8gQW5ndWxhcidzIHpvbmUgdHVybnMgZHluYW1pYyBzY3JvbGxpbmcgaW50byByZXBlYXRlZCBhcHBsaWNhdGlvbi13aWRlXG4gICAgLy8gY2hhbmdlLWRldGVjdGlvbiB3b3JrLiBUaGUgY29yZSByZWFkcyBvZmZzZXRIZWlnaHQgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhpc1xuICAgIC8vIGNhbGxiYWNrIGFuZCBjbGVhcnMgdGhlIHByb2JlLCBzbyBkZXN0cm95IHRoZSBpc29sYXRlZCB2aWV3IGFmdGVyd2FyZHMuXG4gICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgdmlldy5kZXN0cm95KCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlclRlbXBsYXRlSW50b0NvbnRhaW5lcihcbiAgICB0ZW1wbGF0ZTogVGVtcGxhdGVSZWY8Q2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQ8VEl0ZW0+PixcbiAgICBpbmRleDogbnVtYmVyLFxuICAgIGVsZW1lbnRDb250YWluZXI6IEhUTUxFbGVtZW50XG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHByZXZpb3VzID0gdGhpcy52aWV3QnlDb250YWluZXIuZ2V0KGVsZW1lbnRDb250YWluZXIpO1xuICAgIGlmIChwcmV2aW91cykge1xuICAgICAgLy8gUmVjeWNsZTogdXBkYXRlIHRoZSBib3VuZCBjb250ZXh0IGFuZCBydW4gbG9jYWwgQ0QgaW5zdGVhZCBvZlxuICAgICAgLy8gZGVzdHJveWluZyB0aGUgZW1iZWRkZWQgdmlldyBhbmQgcmVidWlsZGluZyB0aGUgZW50aXJlIHJvdyB0cmVlLlxuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuZ2V0SXRlbUZvckluZGV4KGluZGV4KTtcbiAgICAgIHByZXZpb3VzLmNvbnRleHQuJGltcGxpY2l0ID0gaXRlbTtcbiAgICAgIHByZXZpb3VzLmNvbnRleHQuaXRlbSA9IGl0ZW07XG4gICAgICBwcmV2aW91cy5jb250ZXh0LmluZGV4ID0gaW5kZXg7XG4gICAgICAvLyBUaGUgY29yZSBlbmdpbmUgd2lwZXMgZWxlbWVudENvbnRhaW5lci50ZXh0Q29udGVudCB3aGVuIHJldXNpbmcgaXQgZnJvbVxuICAgICAgLy8gaXRzIHBvb2wsIG9ycGhhbmluZyB0aGUgdmlldydzIHJvb3Qgbm9kZXMuIFJlLWFwcGVuZCB0aGVtIGRlZmVuc2l2ZWx5LlxuICAgICAgaWYgKHByZXZpb3VzLnJvb3ROb2Rlcy5sZW5ndGggJiYgcHJldmlvdXMucm9vdE5vZGVzWzBdLnBhcmVudE5vZGUgIT09IGVsZW1lbnRDb250YWluZXIpIHtcbiAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIHByZXZpb3VzLnJvb3ROb2Rlcykge1xuICAgICAgICAgIGVsZW1lbnRDb250YWluZXIuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHByZXZpb3VzLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBUcnkgdG8gcmV1c2UgYSBwb29sZWQgdmlldyBmcm9tIGEgY29udGFpbmVyIHRoYXQgc2Nyb2xsZWQgb3V0IG9mIHZpZXdwb3J0LlxuICAgIGNvbnN0IHBvb2xlZCA9IHRoaXMuZnJlZVZpZXdzLnBvcCgpO1xuICAgIGlmIChwb29sZWQpIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmdldEl0ZW1Gb3JJbmRleChpbmRleCk7XG4gICAgICBwb29sZWQuY29udGV4dC4kaW1wbGljaXQgPSBpdGVtO1xuICAgICAgcG9vbGVkLmNvbnRleHQuaXRlbSA9IGl0ZW07XG4gICAgICBwb29sZWQuY29udGV4dC5pbmRleCA9IGluZGV4O1xuICAgICAgZWxlbWVudENvbnRhaW5lci50ZXh0Q29udGVudCA9ICcnO1xuICAgICAgZm9yIChjb25zdCBub2RlIG9mIHBvb2xlZC5yb290Tm9kZXMpIHtcbiAgICAgICAgZWxlbWVudENvbnRhaW5lci5hcHBlbmRDaGlsZChub2RlKTtcbiAgICAgIH1cbiAgICAgIHBvb2xlZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB0aGlzLnZpZXdCeUNvbnRhaW5lci5zZXQoZWxlbWVudENvbnRhaW5lciwgcG9vbGVkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBObyBwcmlvciB2aWV3IGZvciB0aGlzIGNvbnRhaW5lcjogY3JlYXRlIG9uZS5cbiAgICAvLyBFbnRlciB0aGUgQW5ndWxhciB6b25lIHNvIHRoZSBuZXcgdmlldydzIHRlbXBsYXRlIGV2ZW50IGxpc3RlbmVyc1xuICAgIC8vICgoY2xpY2spLCAoaW5wdXQpLCBldGMuKSBhcmUgem9uZS1wYXRjaGVkLiBUaGlzIHBhdGggcnVucyBhdCBtb3N0XG4gICAgLy8gb25jZSBwZXIgdmlzaWJsZSByb3cgKGFmdGVyIHRoYXQsIHRoZSB2aWV3IGlzIHJlY3ljbGVkIGZyb20gdGhlIHBvb2wpLlxuICAgIGVsZW1lbnRDb250YWluZXIudGV4dENvbnRlbnQgPSAnJztcblxuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmdldEl0ZW1Gb3JJbmRleChpbmRleCk7XG4gICAgY29uc3QgdmlldyA9IHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICBjb25zdCB2ID0gdGVtcGxhdGUuY3JlYXRlRW1iZWRkZWRWaWV3KHsgJGltcGxpY2l0OiBpdGVtLCBpdGVtLCBpbmRleCB9KTtcbiAgICAgIHRoaXMuYXBwUmVmLmF0dGFjaFZpZXcodik7XG4gICAgICB2LmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHJldHVybiB2O1xuICAgIH0pO1xuXG4gICAgZm9yIChjb25zdCBub2RlIG9mIHZpZXcucm9vdE5vZGVzKSB7XG4gICAgICBlbGVtZW50Q29udGFpbmVyLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgIH1cblxuICAgIHRoaXMudmlld0J5Q29udGFpbmVyLnNldChlbGVtZW50Q29udGFpbmVyLCB2aWV3KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIGJvdW5kIGl0ZW0vaW5kZXggb24gZXZlcnkgY3VycmVudGx5LXJlbmRlcmVkIHJvdydzIGVtYmVkZGVkIHZpZXdcbiAgICogYW5kIHJ1biBjaGFuZ2UgZGV0ZWN0aW9uLCB3aXRob3V0IHJlY3JlYXRpbmcgdGhlIHZpZXdzLiBVc2VkIHdoZW4gdGhlIGRhdGFcbiAgICogcmVmZXJlbmNlIGNoYW5nZXMgYnV0IHRoZSB2aXNpYmxlIGluZGljZXMgKGFuZCB0aGVpciBoZWlnaHRzKSBkbyBub3QsIHNvIHJvd1xuICAgKiBzdGF0ZSAoZm9jdXMsIHNlbGVjdGlvbiwgb3BlbiBkcm9wZG93bnMpIHN1cnZpdmVzIHRoZSB1cGRhdGUuXG4gICAqL1xuICAvKipcbiAgICogUmUtYmluZCBlYWNoIGN1cnJlbnRseSByZW5kZXJlZCByb3cncyBjb250ZXh0IChmcm9tIHRoZSBjdXJyZW50IGl0ZW1zL2dldHRlcilcbiAgICogYW5kIHJ1biBjaGFuZ2UgZGV0ZWN0aW9uIG9uIGl0cyBlbWJlZGRlZCB2aWV3LiBVc2UgdGhpcyBhZnRlciBtdXRhdGluZyByb3dcbiAgICogc3RhdGUgaW4gcGxhY2UgKGUuZy4gc2VsZWN0aW9uIGZsYWdzKSBvciBjb2x1bW4tbGV2ZWwgc3RhdGUgcmVhZCBieSB0aGUgcm93XG4gICAqIHRlbXBsYXRlLCB3aGVuIHJvdyBpZGVudGl0eSBhbmQgdmlzaWJsZSBpbmRpY2VzIGhhdmUgbm90IGNoYW5nZWQuIENoZWFwXG4gICAqIHJlbGF0aXZlIHRvIGByZW5kZXIoKWAg4oCUIGRvZXMgbm90IGludm9rZSB0aGUgZW5naW5lJ3MgbWVhc3VyZW1lbnQgcGFzcy5cbiAgICovXG4gIHJlZnJlc2hSZW5kZXJlZENvbnRlbnQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybjtcbiAgICBjb25zdCBzY3JvbGxlciA9IHRoaXMuaG9zdFJlZi5zY3JvbGxlcjtcblxuICAgIGZvciAoY29uc3QgaW5kZXggb2Ygc2Nyb2xsZXIuZ2V0UmVuZGVyZWRJbmRpY2VzKCkpIHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHNjcm9sbGVyLmdldFJlbmRlcmVkRWxlbWVudChpbmRleCk7XG4gICAgICBpZiAoIWNvbnRhaW5lcikgY29udGludWU7XG5cbiAgICAgIGNvbnN0IHZpZXcgPSB0aGlzLnZpZXdCeUNvbnRhaW5lci5nZXQoY29udGFpbmVyKTtcbiAgICAgIGlmICghdmlldykgY29udGludWU7XG5cbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmdldEl0ZW1Gb3JJbmRleChpbmRleCk7XG4gICAgICB2aWV3LmNvbnRleHQuJGltcGxpY2l0ID0gaXRlbTtcbiAgICAgIHZpZXcuY29udGV4dC5pdGVtID0gaXRlbTtcbiAgICAgIHZpZXcuY29udGV4dC5pbmRleCA9IGluZGV4O1xuICAgICAgdmlldy5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZXN0cm95QWxsVmlld3MoKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCB2aWV3IG9mIHRoaXMudmlld0J5Q29udGFpbmVyLnZhbHVlcygpKSB7XG4gICAgICB0aGlzLmFwcFJlZi5kZXRhY2hWaWV3KHZpZXcpO1xuICAgICAgdmlldy5kZXN0cm95KCk7XG4gICAgfVxuICAgIHRoaXMudmlld0J5Q29udGFpbmVyLmNsZWFyKCk7XG4gICAgZm9yIChjb25zdCB2aWV3IG9mIHRoaXMuZnJlZVZpZXdzKSB7XG4gICAgICB0aGlzLmFwcFJlZi5kZXRhY2hWaWV3KHZpZXcpO1xuICAgICAgdmlldy5kZXN0cm95KCk7XG4gICAgfVxuICAgIHRoaXMuZnJlZVZpZXdzLmxlbmd0aCA9IDA7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -27,7 +27,9 @@ function ensureContentElement(container) {
|
|
|
27
27
|
}
|
|
28
28
|
export class CeriousScrollService {
|
|
29
29
|
createHost(container, totalElements, options, ngZone, onScrollHook) {
|
|
30
|
-
const contentElement =
|
|
30
|
+
const contentElement = options.layout === 'masonry'
|
|
31
|
+
? container
|
|
32
|
+
: ensureContentElement(container);
|
|
31
33
|
let scroller;
|
|
32
34
|
ngZone.runOutsideAngular(() => {
|
|
33
35
|
const userOnScroll = options?.onScroll;
|
|
@@ -46,10 +48,10 @@ export class CeriousScrollService {
|
|
|
46
48
|
contentElement,
|
|
47
49
|
viewportChanges$,
|
|
48
50
|
destroy: () => {
|
|
49
|
-
// Remove rendered rows content first; keep container stable.
|
|
50
|
-
contentElement.textContent = '';
|
|
51
51
|
scroller.detachScrollbar(container);
|
|
52
52
|
scroller.dispose();
|
|
53
|
+
// Remove rendered content after the engine has detached its own DOM.
|
|
54
|
+
contentElement.textContent = '';
|
|
53
55
|
},
|
|
54
56
|
};
|
|
55
57
|
}
|
|
@@ -62,4 +64,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
62
64
|
providedIn: 'root'
|
|
63
65
|
}]
|
|
64
66
|
}] });
|
|
65
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
67
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1jZXJpb3VzLXNjcm9sbC9zcmMvbGliL2NlcmlvdXMtc2Nyb2xsLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUVuRCxPQUFPLEVBQUUsYUFBYSxFQUE2QixNQUFNLGdDQUFnQyxDQUFDO0FBRzFGLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDOztBQUdyRSxNQUFNLFlBQVksR0FBRyw2QkFBNkIsQ0FBQztBQUVuRCxTQUFTLG9CQUFvQixDQUFDLFNBQXNCO0lBQ2xELE1BQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxhQUFhLENBQWMsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO0lBQzNFLElBQUksUUFBUTtRQUFFLE9BQU8sUUFBUSxDQUFDO0lBRTlCLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDekMsRUFBRSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDbEMsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsVUFBVSxDQUFDO0lBQy9CLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQztJQUN4QixFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDekIsMEVBQTBFO0lBQzFFLHFFQUFxRTtJQUNyRSxxRUFBcUU7SUFDckUsd0VBQXdFO0lBQ3hFLDJFQUEyRTtJQUMzRSxvRUFBb0U7SUFDcEUseUVBQXlFO0lBQ3pFLHNDQUFzQztJQUN0QyxFQUFFLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUM7SUFDNUIsRUFBRSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDO0lBQzVCLFNBQVMsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDMUIsT0FBTyxFQUFFLENBQUM7QUFDWixDQUFDO0FBS0QsTUFBTSxPQUFPLG9CQUFvQjtJQUMvQixVQUFVLENBQ1IsU0FBc0IsRUFDdEIsYUFBcUIsRUFDckIsT0FBNkIsRUFDN0IsTUFBYyxFQUNkLFlBQXlCO1FBRXpCLE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEtBQUssU0FBUztZQUNqRCxDQUFDLENBQUMsU0FBUztZQUNYLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwQyxJQUFJLFFBQXdCLENBQUM7UUFFN0IsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtZQUM1QixNQUFNLFlBQVksR0FBRyxPQUFPLEVBQUUsUUFBUSxDQUFDO1lBQ3ZDLE1BQU0sYUFBYSxHQUF5QjtnQkFDMUMsR0FBRyxPQUFPO2dCQUNWLFFBQVEsRUFBRSxHQUFHLEVBQUU7b0JBQ2IsWUFBWSxFQUFFLEVBQUUsQ0FBQztvQkFDakIsWUFBWSxFQUFFLEVBQUUsQ0FBQztnQkFDbkIsQ0FBQzthQUNGLENBQUM7WUFFRixRQUFRLEdBQUcsSUFBSSxhQUFhLENBQUMsU0FBUyxFQUFFLGFBQWEsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUN4RSxDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sZ0JBQWdCLEdBQUcsc0JBQXNCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFM0QsT0FBTztZQUNMLFFBQVE7WUFDUixjQUFjO1lBQ2QsZ0JBQWdCO1lBQ2hCLE9BQU8sRUFBRSxHQUFHLEVBQUU7Z0JBQ1osUUFBUSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDcEMsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNuQixxRUFBcUU7Z0JBQ3JFLGNBQWMsQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO1lBQ2xDLENBQUM7U0FDRixDQUFDO0lBQ0osQ0FBQzsrR0F2Q1Usb0JBQW9CO21IQUFwQixvQkFBb0IsY0FGbkIsTUFBTTs7NEZBRVAsb0JBQW9CO2tCQUhoQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIE5nWm9uZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBDZXJpb3VzU2Nyb2xsLCB0eXBlIENlcmlvdXNTY3JvbGxPcHRpb25zIH0gZnJvbSAnQGNlcmlvdXNkZXZ0ZWNoL2NlcmlvdXMtc2Nyb2xsJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgY2VyaW91c1ZpZXdwb3J0Q2hhbmdlJCB9IGZyb20gJy4vY2VyaW91cy1zY3JvbGwub2JzZXJ2YWJsZSc7XG5pbXBvcnQgdHlwZSB7IENlcmlvdXNWaWV3cG9ydENoYW5nZURldGFpbCB9IGZyb20gJy4vY2VyaW91cy1zY3JvbGwudHlwZXMnO1xuXG5jb25zdCBDT05URU5UX0FUVFIgPSAnZGF0YS1jZXJpb3VzLXNjcm9sbC1jb250ZW50JztcblxuZnVuY3Rpb24gZW5zdXJlQ29udGVudEVsZW1lbnQoY29udGFpbmVyOiBIVE1MRWxlbWVudCk6IEhUTUxFbGVtZW50IHtcbiAgY29uc3QgZXhpc3RpbmcgPSBjb250YWluZXIucXVlcnlTZWxlY3RvcjxIVE1MRWxlbWVudD4oYFske0NPTlRFTlRfQVRUUn1dYCk7XG4gIGlmIChleGlzdGluZykgcmV0dXJuIGV4aXN0aW5nO1xuXG4gIGNvbnN0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIGVsLnNldEF0dHJpYnV0ZShDT05URU5UX0FUVFIsICcnKTtcbiAgZWwuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICBlbC5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgZWwuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAvLyBvdmVyZmxvdy15OiBjbGlwICsgb3ZlcmZsb3cteDogYXV0bzogY2xpcCB2ZXJ0aWNhbCByb3cgb3ZlcmZsb3cgKGVuZ2luZVxuICAvLyBvd25zIHZlcnRpY2FsKSBhbmQgbGV0IHRoZSBpbm5lciBlbGVtZW50IG93biB0aGUgbmF0aXZlIGhvcml6b250YWxcbiAgLy8gc2Nyb2xsYmFyIHdoZW4gY29uc3VtZXIgY29udGVudCAoZS5nLiB3aWRlIHNwcmVhZHNoZWV0KSBvdmVyZmxvd3MuXG4gIC8vIEhvcml6b250YWwgc2Nyb2xsIG11c3QgTk9UIG1vdmUgdG8gdGhlIG91dGVyIGNvbnRhaW5lciBvciB0aGUgY2VyaW91c1xuICAvLyBzaWJsaW5nLWRyaXZlciB2ZXJ0aWNhbCBzY3JvbGxiYXIgKGBwb3NpdGlvbjogYWJzb2x1dGU7IHJpZ2h0OiAwYCBpbnNpZGVcbiAgLy8gdGhlIG91dGVyKSB3b3VsZCB0cmFuc2xhdGUgd2l0aCB0aGUgY29udGVudC4gVGhlIGVuZ2luZSByZWFkcyBpdHNcbiAgLy8gdmlld3BvcnQgaGVpZ2h0IGZyb20gdGhpcyBlbGVtZW50IHNvIHRoZSBib3R0b20gcm93IHN0YXlzIGNsZWFyIG9mIHRoZVxuICAvLyBoLXNjcm9sbGJhciBndXR0ZXIgd2hlbiBpdCBhcHBlYXJzLlxuICBlbC5zdHlsZS5vdmVyZmxvd1kgPSAnY2xpcCc7XG4gIGVsLnN0eWxlLm92ZXJmbG93WCA9ICdhdXRvJztcbiAgY29udGFpbmVyLmFwcGVuZENoaWxkKGVsKTtcbiAgcmV0dXJuIGVsO1xufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBDZXJpb3VzU2Nyb2xsU2VydmljZSB7XG4gIGNyZWF0ZUhvc3QoXG4gICAgY29udGFpbmVyOiBIVE1MRWxlbWVudCxcbiAgICB0b3RhbEVsZW1lbnRzOiBudW1iZXIsXG4gICAgb3B0aW9uczogQ2VyaW91c1Njcm9sbE9wdGlvbnMsXG4gICAgbmdab25lOiBOZ1pvbmUsXG4gICAgb25TY3JvbGxIb29rPzogKCkgPT4gdm9pZFxuICApOiBDZXJpb3VzU2Nyb2xsSG9zdFJlZiB7XG4gICAgY29uc3QgY29udGVudEVsZW1lbnQgPSBvcHRpb25zLmxheW91dCA9PT0gJ21hc29ucnknXG4gICAgICA/IGNvbnRhaW5lclxuICAgICAgOiBlbnN1cmVDb250ZW50RWxlbWVudChjb250YWluZXIpO1xuICAgIGxldCBzY3JvbGxlciE6IENlcmlvdXNTY3JvbGw7XG5cbiAgICBuZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgY29uc3QgdXNlck9uU2Nyb2xsID0gb3B0aW9ucz8ub25TY3JvbGw7XG4gICAgICBjb25zdCBtZXJnZWRPcHRpb25zOiBDZXJpb3VzU2Nyb2xsT3B0aW9ucyA9IHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgb25TY3JvbGw6ICgpID0+IHtcbiAgICAgICAgICB1c2VyT25TY3JvbGw/LigpO1xuICAgICAgICAgIG9uU2Nyb2xsSG9vaz8uKCk7XG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBzY3JvbGxlciA9IG5ldyBDZXJpb3VzU2Nyb2xsKGNvbnRhaW5lciwgdG90YWxFbGVtZW50cywgbWVyZ2VkT3B0aW9ucyk7XG4gICAgfSk7XG5cbiAgICBjb25zdCB2aWV3cG9ydENoYW5nZXMkID0gY2VyaW91c1ZpZXdwb3J0Q2hhbmdlJChjb250YWluZXIpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHNjcm9sbGVyLFxuICAgICAgY29udGVudEVsZW1lbnQsXG4gICAgICB2aWV3cG9ydENoYW5nZXMkLFxuICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICBzY3JvbGxlci5kZXRhY2hTY3JvbGxiYXIoY29udGFpbmVyKTtcbiAgICAgICAgc2Nyb2xsZXIuZGlzcG9zZSgpO1xuICAgICAgICAvLyBSZW1vdmUgcmVuZGVyZWQgY29udGVudCBhZnRlciB0aGUgZW5naW5lIGhhcyBkZXRhY2hlZCBpdHMgb3duIERPTS5cbiAgICAgICAgY29udGVudEVsZW1lbnQudGV4dENvbnRlbnQgPSAnJztcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENlcmlvdXNTY3JvbGxIb3N0UmVmIHtcbiAgcmVhZG9ubHkgc2Nyb2xsZXI6IENlcmlvdXNTY3JvbGw7XG4gIC8qKiBEZWRpY2F0ZWQgZWxlbWVudCB1c2VkIGZvciByb3cgcmVuZGVyaW5nIChwcmV2ZW50cyBzY3JvbGxiYXIgRE9NIGZyb20gYmVpbmcgY2xlYXJlZCkuICovXG4gIHJlYWRvbmx5IGNvbnRlbnRFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgcmVhZG9ubHkgdmlld3BvcnRDaGFuZ2VzJDogT2JzZXJ2YWJsZTxDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWw+O1xuICBkZXN0cm95KCk6IHZvaWQ7XG59XG4iXX0=
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export {};
|
|
2
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwudHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtY2VyaW91cy1zY3JvbGwvc3JjL2xpYi9jZXJpb3VzLXNjcm9sbC50eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUge1xuICBDZXJpb3VzU2Nyb2xsT3B0aW9ucyBhcyBDb3JlQ2VyaW91c1Njcm9sbE9wdGlvbnMsXG4gIE1hc29ucnlPcHRpb25zLFxuICBTY3JvbGxSZXN1bHQsXG59IGZyb20gJ0BjZXJpb3VzZGV2dGVjaC9jZXJpb3VzLXNjcm9sbCc7XG5cbi8qKiBFbmdpbmUgb3B0aW9ucyBhZGFwdGVkIGZvciBBbmd1bGFyLW93bmVkIE1hc29ucnkgcmVuZGVyaW5nLiAqL1xuZXhwb3J0IHR5cGUgQ2VyaW91c1Njcm9sbE9wdGlvbnMgPSBPbWl0PENvcmVDZXJpb3VzU2Nyb2xsT3B0aW9ucywgJ21hc29ucnknPiAmIHtcbiAgbWFzb25yeT86IE9taXQ8TWFzb25yeU9wdGlvbnMsICdyZW5kZXJJdGVtJz4gJiB7XG4gICAgLyoqIEFjY2VwdGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5OyBBbmd1bGFyIHN1cHBsaWVzIHRoZSBhY3RpdmUgcmVuZGVyZXIuICovXG4gICAgcmVuZGVySXRlbT86IE1hc29ucnlPcHRpb25zWydyZW5kZXJJdGVtJ107XG4gIH07XG59O1xuXG4vKipcbiAqIERldGFpbCBwYXlsb2FkIGZvciB0aGUgYGNlcmlvdXMtdmlld3BvcnQtY2hhbmdlYCBDdXN0b21FdmVudCBkaXNwYXRjaGVkIGJ5IGBAY2VyaW91c2RldnRlY2gvY2VyaW91cy1zY3JvbGxgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENlcmlvdXNWaWV3cG9ydENoYW5nZURldGFpbCB7XG4gIC8qKiBTY3JvbGwgcGVyY2VudGFnZSBmcm9tIDAuLjEwMCAqL1xuICBwZXJjZW50YWdlOiBudW1iZXI7XG5cbiAgLyoqIEN1cnJlbnQgdG9wLW1vc3QgZWxlbWVudCBpbmRleCAoYXMgdHJhY2tlZCBieSBDZXJpb3VzU2Nyb2xsKSAqL1xuICBjdXJyZW50RWxlbWVudDogbnVtYmVyO1xuXG4gIC8qKiBQaXhlbCBvZmZzZXQgd2l0aGluIGBjdXJyZW50RWxlbWVudGAgKi9cbiAgc2Nyb2xsT2Zmc2V0OiBudW1iZXI7XG5cbiAgLyoqIFNjcm9sbCBvcGVyYXRpb24gcmVzdWx0IChlbGVtZW50ICsgb2Zmc2V0KSAqL1xuICByZXN1bHQ6IFNjcm9sbFJlc3VsdDtcbn1cblxuZXhwb3J0IHR5cGUgQ2VyaW91c1ZpZXdwb3J0Q2hhbmdlRXZlbnQgPSBDdXN0b21FdmVudDxDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWw+O1xuXG4vKipcbiAqIFBheWxvYWQgdXNlZCBieSBDZXJpb3VzU2Nyb2xsJ3MgbmF0aXZlIHNjcm9sbGJhciBpbnRlZ3JhdGlvbi5cbiAqIChEaXNwYXRjaGVkIGFzIGB2aWV3cG9ydC1jaGFuZ2VgIGluIHRoZSB1cHN0cmVhbSBwYWNrYWdlLilcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZXJpb3VzTmF0aXZlU2Nyb2xsYmFyVmlld3BvcnRDaGFuZ2VEZXRhaWwge1xuICBwZXJjZW50YWdlOiBudW1iZXI7XG4gIGVsZW1lbnQ6IG51bWJlcjtcbiAgc2Nyb2xsT2Zmc2V0OiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIENlcmlvdXNOYXRpdmVTY3JvbGxiYXJWaWV3cG9ydENoYW5nZUV2ZW50ID0gQ3VzdG9tRXZlbnQ8Q2VyaW91c05hdGl2ZVNjcm9sbGJhclZpZXdwb3J0Q2hhbmdlRGV0YWlsPjtcbiJdfQ==
|
package/esm2022/public-api.mjs
CHANGED
|
@@ -9,4 +9,4 @@ export * from './lib/cerious-scroll.component';
|
|
|
9
9
|
export * from './lib/cerious-scroll.service';
|
|
10
10
|
// Re-export upstream types/classes for convenience
|
|
11
11
|
export * from '@ceriousdevtech/cerious-scroll';
|
|
12
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL25neC1jZXJpb3VzLXNjcm9sbC9zcmMvcHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsNEJBQTRCLENBQUM7QUFFM0MsY0FBYyxpQ0FBaUMsQ0FBQztBQUNoRCxjQUFjLDhDQUE4QyxDQUFDO0FBQzdELGNBQWMsZ0NBQWdDLENBQUM7QUFDL0MsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLDhCQUE4QixDQUFDO0FBRTdDLG1EQUFtRDtBQUNuRCxjQUFjLGdDQUFnQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIFB1YmxpYyBBUEkgU3VyZmFjZSBvZiBuZ3gtY2VyaW91cy1zY3JvbGxcbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2xpYi9jZXJpb3VzLXNjcm9sbC50eXBlcyc7XG5leHBvcnQgdHlwZSB7IENlcmlvdXNTY3JvbGxPcHRpb25zIH0gZnJvbSAnLi9saWIvY2VyaW91cy1zY3JvbGwudHlwZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY2VyaW91cy1zY3JvbGwub2JzZXJ2YWJsZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jZXJpb3VzLXNjcm9sbC1pdGVtLXRlbXBsYXRlLmRpcmVjdGl2ZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jZXJpb3VzLXNjcm9sbC5kaXJlY3RpdmUnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY2VyaW91cy1zY3JvbGwuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NlcmlvdXMtc2Nyb2xsLnNlcnZpY2UnO1xuXG4vLyBSZS1leHBvcnQgdXBzdHJlYW0gdHlwZXMvY2xhc3NlcyBmb3IgY29udmVuaWVuY2VcbmV4cG9ydCAqIGZyb20gJ0BjZXJpb3VzZGV2dGVjaC9jZXJpb3VzLXNjcm9sbCc7XG4iXX0=
|
|
@@ -77,7 +77,9 @@ function ensureContentElement(container) {
|
|
|
77
77
|
}
|
|
78
78
|
class CeriousScrollService {
|
|
79
79
|
createHost(container, totalElements, options, ngZone, onScrollHook) {
|
|
80
|
-
const contentElement =
|
|
80
|
+
const contentElement = options.layout === 'masonry'
|
|
81
|
+
? container
|
|
82
|
+
: ensureContentElement(container);
|
|
81
83
|
let scroller;
|
|
82
84
|
ngZone.runOutsideAngular(() => {
|
|
83
85
|
const userOnScroll = options?.onScroll;
|
|
@@ -96,10 +98,10 @@ class CeriousScrollService {
|
|
|
96
98
|
contentElement,
|
|
97
99
|
viewportChanges$,
|
|
98
100
|
destroy: () => {
|
|
99
|
-
// Remove rendered rows content first; keep container stable.
|
|
100
|
-
contentElement.textContent = '';
|
|
101
101
|
scroller.detachScrollbar(container);
|
|
102
102
|
scroller.dispose();
|
|
103
|
+
// Remove rendered content after the engine has detached its own DOM.
|
|
104
|
+
contentElement.textContent = '';
|
|
103
105
|
},
|
|
104
106
|
};
|
|
105
107
|
}
|
|
@@ -122,6 +124,10 @@ function coerceTotalElements(explicitTotal, itemsLen) {
|
|
|
122
124
|
return Math.max(1, candidate);
|
|
123
125
|
}
|
|
124
126
|
class CeriousScrollDirective {
|
|
127
|
+
/** Underlying core engine instance, or null before initialization. */
|
|
128
|
+
get scroller() {
|
|
129
|
+
return this.hostRef?.scroller ?? null;
|
|
130
|
+
}
|
|
125
131
|
constructor(host, appRef, ngZone, cerious) {
|
|
126
132
|
this.host = host;
|
|
127
133
|
this.appRef = appRef;
|
|
@@ -154,6 +160,10 @@ class CeriousScrollDirective {
|
|
|
154
160
|
this.hostRef = null;
|
|
155
161
|
this.viewportSub = null;
|
|
156
162
|
this.scheduledRenderFrame = null;
|
|
163
|
+
// Incremented by the core-owned Masonry renderer whenever it mounts a probe
|
|
164
|
+
// or visible card. Unlike row mode, those calls do not flow through the
|
|
165
|
+
// ElementRenderer passed to renderViewport().
|
|
166
|
+
this.masonryRendererEpoch = 0;
|
|
157
167
|
this.viewByContainer = new Map();
|
|
158
168
|
// Pool of views detached because their container left the viewport. Reusing
|
|
159
169
|
// them on subsequent renders avoids destroying + recreating the entire row
|
|
@@ -172,19 +182,36 @@ class CeriousScrollDirective {
|
|
|
172
182
|
return;
|
|
173
183
|
if (changes['ceriousScrollItems'] || changes['ceriousScrollTotalElements']) {
|
|
174
184
|
const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);
|
|
175
|
-
const
|
|
185
|
+
const masonryMode = this.ceriousScrollOptions.layout === 'masonry';
|
|
186
|
+
const currentCount = masonryMode
|
|
187
|
+
? this.hostRef.scroller.itemCount
|
|
188
|
+
: this.hostRef.scroller.totalElements;
|
|
189
|
+
const countChanged = currentCount !== total;
|
|
176
190
|
if (countChanged) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
//
|
|
185
|
-
//
|
|
186
|
-
//
|
|
187
|
-
this
|
|
191
|
+
if (masonryMode) {
|
|
192
|
+
// Masonry's renderer owns card-count-derived segment state. Recreate
|
|
193
|
+
// it when the dataset size changes rather than updating segment count
|
|
194
|
+
// through the row-oriented updateTotalElements API.
|
|
195
|
+
this.recreate();
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
// Grow/shrink the dataset IN PLACE — no recreate. updateTotalElements
|
|
199
|
+
// propagates the new count to every subsystem, INCLUDING the
|
|
200
|
+
// ViewportRenderer's own copy of totalElements (it used to go stale,
|
|
201
|
+
// which is exactly why this recreated: the renderer kept the old count
|
|
202
|
+
// for its viewport-fill loop and bottom scan, producing phantom
|
|
203
|
+
// out-of-bounds renders). In place keeps the scroll position and an
|
|
204
|
+
// in-progress scrollbar drag alive, and a growing dataset keeps a stable
|
|
205
|
+
// bottom index (no bouncing tail). The track lengthens, so re-sync the
|
|
206
|
+
// thumb afterwards.
|
|
207
|
+
this.hostRef.scroller.updateTotalElements(total);
|
|
208
|
+
// A shrink can leave the position past the new end — clamp it.
|
|
209
|
+
if (this.hostRef.scroller.currentElement > total - 1) {
|
|
210
|
+
this.hostRef.scroller.jumpToElement(total - 1);
|
|
211
|
+
}
|
|
212
|
+
if (this.ceriousScrollAutoRender)
|
|
213
|
+
this.render();
|
|
214
|
+
this.hostRef.scroller.syncScrollbar();
|
|
188
215
|
}
|
|
189
216
|
else if (this.ceriousScrollAutoRender) {
|
|
190
217
|
// Same count, new data reference (e.g. an immutable edit or a sort that
|
|
@@ -243,8 +270,11 @@ class CeriousScrollDirective {
|
|
|
243
270
|
// for the whole pass is handled by the caller (`scheduleRender`).
|
|
244
271
|
this.renderTemplateIntoContainer(template, index, elementContainer);
|
|
245
272
|
};
|
|
273
|
+
const masonryMode = this.ceriousScrollOptions.layout === 'masonry';
|
|
274
|
+
const masonryEpochBefore = this.masonryRendererEpoch;
|
|
246
275
|
const range = this.hostRef.scroller.renderViewport(height, contentContainer, renderer);
|
|
247
|
-
|
|
276
|
+
const masonryInvocations = this.masonryRendererEpoch - masonryEpochBefore;
|
|
277
|
+
if (rendererInvocations === 0 && (!masonryMode || masonryInvocations === 0)) {
|
|
248
278
|
// Viewport didn't change — skip the prune walk and the (potentially
|
|
249
279
|
// zone-entering) emit.
|
|
250
280
|
return range;
|
|
@@ -267,11 +297,19 @@ class CeriousScrollDirective {
|
|
|
267
297
|
if (!this.hostRef || this.viewByContainer.size === 0)
|
|
268
298
|
return;
|
|
269
299
|
const scroller = this.hostRef.scroller;
|
|
300
|
+
const masonryMode = this.ceriousScrollOptions.layout === 'masonry';
|
|
270
301
|
const active = new Set();
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
active.add(el);
|
|
302
|
+
if (masonryMode) {
|
|
303
|
+
this.host.nativeElement
|
|
304
|
+
.querySelectorAll('[data-element-index]')
|
|
305
|
+
.forEach((el) => active.add(el));
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
for (const index of scroller.getRenderedIndices()) {
|
|
309
|
+
const el = scroller.getRenderedElement(index);
|
|
310
|
+
if (el)
|
|
311
|
+
active.add(el);
|
|
312
|
+
}
|
|
275
313
|
}
|
|
276
314
|
for (const [container, view] of this.viewByContainer) {
|
|
277
315
|
if (!active.has(container)) {
|
|
@@ -336,6 +374,13 @@ class CeriousScrollDirective {
|
|
|
336
374
|
this.hostRef.scroller.jumpToElement(index);
|
|
337
375
|
return this.render();
|
|
338
376
|
}
|
|
377
|
+
/** Masonry mode only: jump directly to a card index, then render. */
|
|
378
|
+
jumpToItem(index, screenOffset = 0) {
|
|
379
|
+
if (!this.hostRef)
|
|
380
|
+
return null;
|
|
381
|
+
this.hostRef.scroller.jumpToItem(index, screenOffset);
|
|
382
|
+
return this.render();
|
|
383
|
+
}
|
|
339
384
|
/** Scroll to a percentage (0..100), then render. */
|
|
340
385
|
scrollToPercentage(percentage) {
|
|
341
386
|
if (!this.hostRef)
|
|
@@ -365,7 +410,33 @@ class CeriousScrollDirective {
|
|
|
365
410
|
const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);
|
|
366
411
|
// Table mode: capture the engine-created <thead> so we can render the
|
|
367
412
|
// declarative header template into it (and still run any user header hook).
|
|
368
|
-
let options
|
|
413
|
+
let options;
|
|
414
|
+
if (this.ceriousScrollOptions.layout === 'masonry') {
|
|
415
|
+
if (!this.ceriousScrollOptions.masonry) {
|
|
416
|
+
throw new Error("CeriousScrollDirective: layout 'masonry' requires `ceriousScrollOptions.masonry`.");
|
|
417
|
+
}
|
|
418
|
+
options = {
|
|
419
|
+
...this.ceriousScrollOptions,
|
|
420
|
+
masonry: {
|
|
421
|
+
...this.ceriousScrollOptions.masonry,
|
|
422
|
+
renderItem: (index, element) => {
|
|
423
|
+
this.masonryRendererEpoch++;
|
|
424
|
+
const template = this.ceriousScrollItemTemplate;
|
|
425
|
+
if (!template)
|
|
426
|
+
return;
|
|
427
|
+
if (element.dataset['ceriousMasonry'] === 'probe') {
|
|
428
|
+
this.renderProbe(template, index, element);
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
this.renderTemplateIntoContainer(template, index, element);
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
},
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
options = this.ceriousScrollOptions;
|
|
439
|
+
}
|
|
369
440
|
if (options.layout === 'table' && this.ceriousScrollHeaderTemplate) {
|
|
370
441
|
const userHeader = options.table?.header;
|
|
371
442
|
options = {
|
|
@@ -424,6 +495,25 @@ class CeriousScrollDirective {
|
|
|
424
495
|
return undefined;
|
|
425
496
|
return items[index];
|
|
426
497
|
}
|
|
498
|
+
renderProbe(template, index, container) {
|
|
499
|
+
const item = this.getItemForIndex(index);
|
|
500
|
+
const view = this.ngZone.runOutsideAngular(() => {
|
|
501
|
+
const v = template.createEmbeddedView({ $implicit: item, item, index });
|
|
502
|
+
v.detectChanges();
|
|
503
|
+
return v;
|
|
504
|
+
});
|
|
505
|
+
for (const node of view.rootNodes)
|
|
506
|
+
container.appendChild(node);
|
|
507
|
+
// Measurement probes are deliberately NOT attached to ApplicationRef:
|
|
508
|
+
// they are disposable, non-interactive markup and local detectChanges() is
|
|
509
|
+
// enough to populate their DOM synchronously. Attaching each probe inside
|
|
510
|
+
// Angular's zone turns dynamic scrolling into repeated application-wide
|
|
511
|
+
// change-detection work. The core reads offsetHeight immediately after this
|
|
512
|
+
// callback and clears the probe, so destroy the isolated view afterwards.
|
|
513
|
+
queueMicrotask(() => {
|
|
514
|
+
view.destroy();
|
|
515
|
+
});
|
|
516
|
+
}
|
|
427
517
|
renderTemplateIntoContainer(template, index, elementContainer) {
|
|
428
518
|
const previous = this.viewByContainer.get(elementContainer);
|
|
429
519
|
if (previous) {
|
|
@@ -553,6 +643,17 @@ class CeriousScrollComponent {
|
|
|
553
643
|
constructor(ceriousScroll) {
|
|
554
644
|
this.ceriousScroll = ceriousScroll;
|
|
555
645
|
}
|
|
646
|
+
get scroller() { return this.ceriousScroll.scroller; }
|
|
647
|
+
render() { return this.ceriousScroll.render(); }
|
|
648
|
+
jumpToElement(index) { return this.ceriousScroll.jumpToElement(index); }
|
|
649
|
+
jumpToItem(index, screenOffset = 0) {
|
|
650
|
+
return this.ceriousScroll.jumpToItem(index, screenOffset);
|
|
651
|
+
}
|
|
652
|
+
scrollToPercentage(percentage) {
|
|
653
|
+
return this.ceriousScroll.scrollToPercentage(percentage);
|
|
654
|
+
}
|
|
655
|
+
reset() { return this.ceriousScroll.reset(); }
|
|
656
|
+
recalculate() { return this.ceriousScroll.recalculate(); }
|
|
556
657
|
ngAfterContentInit() {
|
|
557
658
|
if (this.ceriousScroll.ceriousScrollItemTemplate)
|
|
558
659
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ceriousdevtech-ngx-cerious-scroll.mjs","sources":["../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll.observable.ts","../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll-item-template.directive.ts","../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll.service.ts","../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll.directive.ts","../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll.component.ts","../../../projects/ngx-cerious-scroll/src/public-api.ts","../../../projects/ngx-cerious-scroll/src/ceriousdevtech-ngx-cerious-scroll.ts"],"sourcesContent":["import { fromEvent, map, merge, Observable, share } from 'rxjs';\n\nimport type { ScrollResult } from '@ceriousdevtech/cerious-scroll';\n\nimport {\n CeriousNativeScrollbarViewportChangeEvent,\n CeriousViewportChangeDetail,\n CeriousViewportChangeEvent,\n} from './cerious-scroll.types';\n\n/**\n * Observable wrapper around the `cerious-viewport-change` CustomEvent emitted by `@ceriousdevtech/cerious-scroll`.\n *\n * Note: this event is emitted when wheel/touch/keyboard handlers are enabled (defaults are enabled).\n */\nexport function ceriousViewportChange$(container: HTMLElement): Observable<CeriousViewportChangeDetail> {\n const fromCerious = fromEvent<CeriousViewportChangeEvent>(container, 'cerious-viewport-change').pipe(\n map((evt) => evt.detail)\n );\n\n // Native scrollbar integration in the upstream package dispatches `viewport-change`.\n // Normalize it into the same shape as `cerious-viewport-change`.\n const fromScrollbar = fromEvent<CeriousNativeScrollbarViewportChangeEvent>(container, 'viewport-change').pipe(\n map((evt) => {\n const result: ScrollResult = { element: evt.detail.element, offset: evt.detail.scrollOffset };\n return {\n percentage: evt.detail.percentage,\n currentElement: evt.detail.element,\n scrollOffset: evt.detail.scrollOffset,\n result,\n } satisfies CeriousViewportChangeDetail;\n })\n );\n\n return merge(fromCerious, fromScrollbar).pipe(share());\n}\n","import { Directive, TemplateRef } from '@angular/core';\n\nexport interface CeriousScrollItemTemplateContext<TItem = unknown> {\n /** The item for this row (also available as `$implicit`). */\n $implicit: TItem;\n /** Row index. */\n index: number;\n /** Same as `$implicit` for named access. */\n item: TItem;\n}\n\n/**\n * Marks an `ng-template` as the row template for `CeriousScrollComponent`.\n *\n * Usage:\n * ```html\n * <cerious-scroll [items]=\"items\">\n * <ng-template ceriousScrollItem let-item let-index=\"index\">\n * {{ index }} - {{ item.name }}\n * </ng-template>\n * </cerious-scroll>\n * ```\n */\n@Directive({\n selector: 'ng-template[ceriousScrollItem]',\n standalone: true,\n})\nexport class CeriousScrollItemTemplateDirective<TItem = unknown> {\n constructor(public readonly templateRef: TemplateRef<CeriousScrollItemTemplateContext<TItem>>) {}\n}\n","import { Injectable, NgZone } from '@angular/core';\n\nimport { CeriousScroll, type CeriousScrollOptions } from '@ceriousdevtech/cerious-scroll';\nimport { Observable } from 'rxjs';\n\nimport { ceriousViewportChange$ } from './cerious-scroll.observable';\nimport type { CeriousViewportChangeDetail } from './cerious-scroll.types';\n\nconst CONTENT_ATTR = 'data-cerious-scroll-content';\n\nfunction ensureContentElement(container: HTMLElement): HTMLElement {\n const existing = container.querySelector<HTMLElement>(`[${CONTENT_ATTR}]`);\n if (existing) return existing;\n\n const el = document.createElement('div');\n el.setAttribute(CONTENT_ATTR, '');\n el.style.position = 'relative';\n el.style.width = '100%';\n el.style.height = '100%';\n // overflow-y: clip + overflow-x: auto: clip vertical row overflow (engine\n // owns vertical) and let the inner element own the native horizontal\n // scrollbar when consumer content (e.g. wide spreadsheet) overflows.\n // Horizontal scroll must NOT move to the outer container or the cerious\n // sibling-driver vertical scrollbar (`position: absolute; right: 0` inside\n // the outer) would translate with the content. The engine reads its\n // viewport height from this element so the bottom row stays clear of the\n // h-scrollbar gutter when it appears.\n el.style.overflowY = 'clip';\n el.style.overflowX = 'auto';\n container.appendChild(el);\n return el;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class CeriousScrollService {\n createHost(\n container: HTMLElement,\n totalElements: number,\n options: CeriousScrollOptions,\n ngZone: NgZone,\n onScrollHook?: () => void\n ): CeriousScrollHostRef {\n const contentElement = ensureContentElement(container);\n let scroller!: CeriousScroll;\n\n ngZone.runOutsideAngular(() => {\n const userOnScroll = options?.onScroll;\n const mergedOptions: CeriousScrollOptions = {\n ...options,\n onScroll: () => {\n userOnScroll?.();\n onScrollHook?.();\n },\n };\n\n scroller = new CeriousScroll(container, totalElements, mergedOptions);\n });\n\n const viewportChanges$ = ceriousViewportChange$(container);\n\n return {\n scroller,\n contentElement,\n viewportChanges$,\n destroy: () => {\n // Remove rendered rows content first; keep container stable.\n contentElement.textContent = '';\n scroller.detachScrollbar(container);\n scroller.dispose();\n },\n };\n }\n}\n\nexport interface CeriousScrollHostRef {\n readonly scroller: CeriousScroll;\n /** Dedicated element used for row rendering (prevents scrollbar DOM from being cleared). */\n readonly contentElement: HTMLElement;\n readonly viewportChanges$: Observable<CeriousViewportChangeDetail>;\n destroy(): void;\n}\n","import {\n AfterViewInit,\n ApplicationRef,\n Directive,\n ElementRef,\n EmbeddedViewRef,\n EventEmitter,\n Input,\n NgZone,\n OnChanges,\n OnDestroy,\n Output,\n SimpleChanges,\n TemplateRef,\n} from '@angular/core';\n\nimport {\n type CeriousScrollOptions,\n type ElementRenderer,\n type MeasuredViewportRange,\n} from '@ceriousdevtech/cerious-scroll';\nimport { Subscription } from 'rxjs';\n\nimport type { CeriousViewportChangeDetail } from './cerious-scroll.types';\nimport type { CeriousScrollItemTemplateContext } from './cerious-scroll-item-template.directive';\nimport { type CeriousScrollHostRef, CeriousScrollService } from './cerious-scroll.service';\n\nfunction coerceTotalElements(explicitTotal: number | null | undefined, itemsLen: number | null | undefined): number {\n const candidate = typeof explicitTotal === 'number' ? explicitTotal : typeof itemsLen === 'number' ? itemsLen : undefined;\n if (candidate === undefined || Number.isNaN(candidate)) {\n throw new Error('CeriousScrollDirective: provide `ceriousScrollTotalElements` or `ceriousScrollItems`.');\n }\n // CeriousScroll currently requires >= 1\n return Math.max(1, candidate);\n}\n\n@Directive({\n selector: '[ceriousScroll]',\n standalone: true,\n})\nexport class CeriousScrollDirective<TItem = unknown> implements AfterViewInit, OnChanges, OnDestroy {\n /** Total number of items. If omitted, derived from `ceriousScrollItems.length`. */\n @Input() ceriousScrollTotalElements: number | null = null;\n\n /** Optional items array (enables `let-item`). */\n @Input() ceriousScrollItems: readonly TItem[] | null = null;\n\n /** Optional getter for large datasets (alternative to passing full `items`). */\n @Input() ceriousScrollGetItem: ((index: number) => TItem) | null = null;\n\n /** Template used to render each row. */\n @Input() ceriousScrollItemTemplate: TemplateRef<CeriousScrollItemTemplateContext<TItem>> | null = null;\n\n /**\n * Table mode only: template rendered into the engine's `<thead>` (a `<tr>` of\n * `<th>`s). It lives in the same `<table>` as the rows, so columns align\n * natively. Updates via change detection like the rows.\n */\n @Input() ceriousScrollHeaderTemplate: TemplateRef<unknown> | null = null;\n\n /** Options passed to `new CeriousScroll(...)`. */\n @Input() ceriousScrollOptions: CeriousScrollOptions = {};\n\n /** Automatically call render after each scroll event. Default: true */\n @Input() ceriousScrollAutoRender = true;\n\n /** Emits `cerious-viewport-change` detail. */\n @Output() ceriousScrollViewportChange = new EventEmitter<CeriousViewportChangeDetail>();\n\n /** Emits the last measured viewport after each render pass. */\n @Output() ceriousScrollMeasuredViewport = new EventEmitter<MeasuredViewportRange>();\n\n /** Emits once the underlying `CeriousScroll` instance is ready. */\n @Output() ceriousScrollReady = new EventEmitter<CeriousScrollHostRef['scroller']>();\n\n private hostRef: CeriousScrollHostRef | null = null;\n private viewportSub: Subscription | null = null;\n private scheduledRenderFrame: number | null = null;\n\n private readonly viewByContainer = new Map<HTMLElement, EmbeddedViewRef<CeriousScrollItemTemplateContext<TItem>>>();\n // Pool of views detached because their container left the viewport. Reusing\n // them on subsequent renders avoids destroying + recreating the entire row\n // component tree on fast scrolls (where the engine's element pool wipes\n // textContent on reused containers, so view rootNodes get orphaned).\n private readonly freeViews: EmbeddedViewRef<CeriousScrollItemTemplateContext<TItem>>[] = [];\n\n // Table mode: the embedded view of the declarative header, rendered into the\n // engine's <thead>.\n private headerView: EmbeddedViewRef<unknown> | null = null;\n\n constructor(\n private readonly host: ElementRef<HTMLElement>,\n private readonly appRef: ApplicationRef,\n private readonly ngZone: NgZone,\n private readonly cerious: CeriousScrollService\n ) {}\n\n ngAfterViewInit(): void {\n this.ensureInitialized();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (!this.hostRef) return;\n\n if (changes['ceriousScrollItems'] || changes['ceriousScrollTotalElements']) {\n const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);\n const countChanged = this.hostRef.scroller.totalElements !== total;\n\n if (countChanged) {\n // The dataset size changed: the ViewportRenderer stores its own copy of\n // totalElements (set by value at construction) so patching the engine's\n // public property alone leaves the renderer's internal bound stale. The\n // renderer would then use the old count for its viewport-fill loop and\n // bottom-boundary scan, producing phantom renders at out-of-bounds\n // indices (undefined items → 0-height rows → the fill loop never\n // satisfies its height condition → hundreds of renderer callbacks).\n // Recreating the engine gives both the engine and the renderer a fresh,\n // consistent count. ensureInitialized() schedules the first render via\n // queueMicrotask, which runs after the current CD cycle completes.\n this.recreate();\n } else if (this.ceriousScrollAutoRender) {\n // Same count, new data reference (e.g. an immutable edit or a sort that\n // happens to keep the same length). The engine reuses the DOM element it\n // already rendered for each overlapping index without re-invoking the\n // renderer, so update the content of every currently-visible row IN\n // PLACE before calling render(). This preserves each row's embedded\n // view (so a focused textbox keeps focus/caret) and does NOT discard\n // cached heights. If a row's height actually changes the engine's\n // ResizeObserver keeps the cache correct on its own; for a wholesale\n // height change across all rows, call recalculate() instead.\n this.refreshRenderedContent();\n this.render();\n }\n }\n\n if (changes['ceriousScrollOptions'] && !changes['ceriousScrollOptions'].firstChange) {\n // Options are consumed primarily at construction time.\n this.recreate();\n }\n }\n\n ngOnDestroy(): void {\n if (this.scheduledRenderFrame != null) {\n cancelAnimationFrame(this.scheduledRenderFrame);\n this.scheduledRenderFrame = null;\n }\n\n this.viewportSub?.unsubscribe();\n this.viewportSub = null;\n\n this.destroyAllViews();\n this.headerView?.destroy();\n this.headerView = null;\n\n this.hostRef?.destroy();\n this.hostRef = null;\n }\n\n /** Imperatively trigger a render pass (uses `ceriousScrollItemTemplate`). */\n render(): MeasuredViewportRange | null {\n if (!this.hostRef) return null;\n const template = this.ceriousScrollItemTemplate;\n if (!template) return null;\n\n const hostContainer = this.host.nativeElement;\n const height = hostContainer.clientHeight || hostContainer.offsetHeight;\n const contentContainer = this.hostRef.contentElement;\n\n // Track whether the engine asked us to bind any row this pass. Pure scroll\n // frames where the visible row set doesn't change still drive render() via\n // the rAF coalescer — there's no point in walking the prune map or\n // emitting the viewport range when nothing was touched.\n let rendererInvocations = 0;\n const renderer: ElementRenderer = (index, elementContainer) => {\n rendererInvocations++;\n // Render each row's embedded view with LOCAL change detection\n // (`view.detectChanges()` inside `renderTemplateIntoContainer`) so the\n // engine can measure its height during this pass. Do NOT wrap each row in\n // its own `ngZone.run` — that fires a full `ApplicationRef` tick *per row*\n // (O(newRows × visibleRows) work, janky drags). The single coalesced tick\n // for the whole pass is handled by the caller (`scheduleRender`).\n this.renderTemplateIntoContainer(template, index, elementContainer);\n };\n\n const range = this.hostRef.scroller.renderViewport(height, contentContainer, renderer);\n\n if (rendererInvocations === 0) {\n // Viewport didn't change — skip the prune walk and the (potentially\n // zone-entering) emit.\n return range;\n }\n\n // Destroy views whose container the engine no longer renders. Without this,\n // every container the engine recycles into its element pool leaves its\n // embedded view attached to ApplicationRef forever — so the attached-view\n // list (and every O(n) `detachView`) grows without bound and scrolling gets\n // progressively slower. Mirrors the React/Vue wrappers, which drop rows that\n // fall out of `getRenderedIndices()`.\n this.pruneDetachedViews();\n\n // Only re-enter the zone (a global tick) if someone is actually listening.\n if (this.ceriousScrollMeasuredViewport.observed) {\n this.ngZone.run(() => this.ceriousScrollMeasuredViewport.emit(range));\n }\n return range;\n }\n\n /** Tear down embedded views whose container is no longer part of the viewport. */\n private pruneDetachedViews(): void {\n if (!this.hostRef || this.viewByContainer.size === 0) return;\n const scroller = this.hostRef.scroller;\n const active = new Set<HTMLElement>();\n for (const index of scroller.getRenderedIndices()) {\n const el = scroller.getRenderedElement(index);\n if (el) active.add(el);\n }\n for (const [container, view] of this.viewByContainer) {\n if (!active.has(container)) {\n // Detach DOM but keep the view alive in the pool for future reuse.\n // Destroying + recreating views per scroll step dominates frame time.\n for (const node of view.rootNodes) {\n if (node.parentNode) node.parentNode.removeChild(node);\n }\n this.viewByContainer.delete(container);\n this.freeViews.push(view);\n }\n }\n }\n\n /** Auto-render coalesced to at most once per animation frame. */\n private scheduleRender(): void {\n if (this.scheduledRenderFrame != null) return;\n this.scheduledRenderFrame = requestAnimationFrame(() => {\n this.scheduledRenderFrame = null;\n // Run render() OUTSIDE Angular's zone. A full ApplicationRef.tick() on\n // every scroll frame is the primary FPS bottleneck: even when no rows\n // change (pure translation), ngZone.run() causes Angular to walk the\n // entire component tree. Instead we call view.detectChanges() locally\n // inside renderTemplateIntoContainer for each affected row. Zone entry is\n // only needed when creating a brand-new embedded view (to zone-patch its\n // event listeners) — recycled and pooled views were already created inside\n // zone and their listeners remain zone-aware.\n this.render();\n });\n }\n\n /**\n * Discard all cached row heights and re-measure the viewport.\n *\n * Call this only when the heights of rows you've *already rendered* may have\n * changed without their indices changing — e.g. a global font/density change,\n * or swapping every row to a different layout. This forces a synchronous\n * re-measure (one `offsetHeight` read per visible row), so do NOT call it on\n * routine edits: a single cell edit keeps its row's size, and the engine's\n * ResizeObserver picks up any incidental resize on its own.\n */\n recalculate(): MeasuredViewportRange | null {\n if (!this.hostRef) return null;\n const template = this.ceriousScrollItemTemplate;\n if (template) {\n // Re-invoke the renderer for every currently-rendered row so pending\n // Angular bindings flush into the DOM and the engine re-measures each\n // row's new height into its cache. Without this, the engine's render\n // pass skips the renderer for already-rendered indices and falls\n // through to reading stale offsetHeight.\n this.hostRef.scroller.refreshVisible((index, elementContainer) => {\n this.renderTemplateIntoContainer(template, index, elementContainer);\n });\n }\n return this.render();\n }\n\n /** Jump directly to an element index, then render. */\n jumpToElement(index: number): MeasuredViewportRange | null {\n if (!this.hostRef) return null;\n this.hostRef.scroller.jumpToElement(index);\n return this.render();\n }\n\n /** Scroll to a percentage (0..100), then render. */\n scrollToPercentage(percentage: number): MeasuredViewportRange | null {\n if (!this.hostRef) return null;\n this.hostRef.scroller.handleScrollPercentage(percentage);\n return this.render();\n }\n\n /** Reset to the top, then render. */\n reset(): MeasuredViewportRange | null {\n if (!this.hostRef) return null;\n this.hostRef.scroller.reset();\n return this.render();\n }\n\n private recreate(): void {\n this.viewportSub?.unsubscribe();\n this.viewportSub = null;\n\n this.destroyAllViews();\n\n this.hostRef?.destroy();\n this.hostRef = null;\n\n this.ensureInitialized();\n }\n\n private ensureInitialized(): void {\n if (this.hostRef) return;\n\n const container = this.host.nativeElement;\n const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);\n\n // Table mode: capture the engine-created <thead> so we can render the\n // declarative header template into it (and still run any user header hook).\n let options = this.ceriousScrollOptions;\n if (options.layout === 'table' && this.ceriousScrollHeaderTemplate) {\n const userHeader = options.table?.header;\n options = {\n ...options,\n table: {\n ...options.table,\n header: (thead: HTMLTableSectionElement) => {\n userHeader?.(thead);\n this.mountHeader(thead);\n },\n },\n };\n }\n\n this.hostRef = this.cerious.createHost(container, total, options, this.ngZone, () => {\n // Coalesce scroll-driven renders to one per frame (the native scrollbar\n // can fire many scroll events between paints).\n if (this.ceriousScrollAutoRender) this.scheduleRender();\n });\n\n this.viewportSub = this.hostRef.viewportChanges$.subscribe((detail: CeriousViewportChangeDetail) => {\n // Skip the global tick when nobody is bound to the output.\n if (this.ceriousScrollViewportChange.observed) {\n this.ngZone.run(() => this.ceriousScrollViewportChange.emit(detail));\n }\n });\n\n this.ceriousScrollReady.emit(this.hostRef.scroller);\n\n if (this.ceriousScrollAutoRender) {\n queueMicrotask(() => this.render());\n }\n }\n\n /**\n * Render the declarative header template into the engine's <thead>. One\n * embedded view, created inside the zone (so the header's event bindings are\n * zone-patched), its root nodes appended directly into the <thead>.\n */\n private mountHeader(thead: HTMLElement): void {\n if (!this.ceriousScrollHeaderTemplate) return;\n this.headerView?.destroy();\n const view = this.ngZone.run(() => {\n const v = this.ceriousScrollHeaderTemplate!.createEmbeddedView({});\n this.appRef.attachView(v);\n v.detectChanges();\n return v;\n });\n for (const node of view.rootNodes) thead.appendChild(node);\n this.headerView = view;\n }\n\n private getItemForIndex(index: number): TItem {\n const getter = this.ceriousScrollGetItem;\n if (getter) return getter(index);\n\n const items = this.ceriousScrollItems;\n if (!items) return undefined as TItem;\n\n return items[index];\n }\n\n private renderTemplateIntoContainer(\n template: TemplateRef<CeriousScrollItemTemplateContext<TItem>>,\n index: number,\n elementContainer: HTMLElement\n ): void {\n const previous = this.viewByContainer.get(elementContainer);\n if (previous) {\n // Recycle: update the bound context and run local CD instead of\n // destroying the embedded view and rebuilding the entire row tree.\n const item = this.getItemForIndex(index);\n previous.context.$implicit = item;\n previous.context.item = item;\n previous.context.index = index;\n // The core engine wipes elementContainer.textContent when reusing it from\n // its pool, orphaning the view's root nodes. Re-append them defensively.\n if (previous.rootNodes.length && previous.rootNodes[0].parentNode !== elementContainer) {\n for (const node of previous.rootNodes) {\n elementContainer.appendChild(node);\n }\n }\n previous.detectChanges();\n return;\n }\n\n // Try to reuse a pooled view from a container that scrolled out of viewport.\n const pooled = this.freeViews.pop();\n if (pooled) {\n const item = this.getItemForIndex(index);\n pooled.context.$implicit = item;\n pooled.context.item = item;\n pooled.context.index = index;\n elementContainer.textContent = '';\n for (const node of pooled.rootNodes) {\n elementContainer.appendChild(node);\n }\n pooled.detectChanges();\n this.viewByContainer.set(elementContainer, pooled);\n return;\n }\n\n // No prior view for this container: create one.\n // Enter the Angular zone so the new view's template event listeners\n // ((click), (input), etc.) are zone-patched. This path runs at most\n // once per visible row (after that, the view is recycled from the pool).\n elementContainer.textContent = '';\n\n const item = this.getItemForIndex(index);\n const view = this.ngZone.run(() => {\n const v = template.createEmbeddedView({ $implicit: item, item, index });\n this.appRef.attachView(v);\n v.detectChanges();\n return v;\n });\n\n for (const node of view.rootNodes) {\n elementContainer.appendChild(node);\n }\n\n this.viewByContainer.set(elementContainer, view);\n }\n\n /**\n * Update the bound item/index on every currently-rendered row's embedded view\n * and run change detection, without recreating the views. Used when the data\n * reference changes but the visible indices (and their heights) do not, so row\n * state (focus, selection, open dropdowns) survives the update.\n */\n /**\n * Re-bind each currently rendered row's context (from the current items/getter)\n * and run change detection on its embedded view. Use this after mutating row\n * state in place (e.g. selection flags) or column-level state read by the row\n * template, when row identity and visible indices have not changed. Cheap\n * relative to `render()` — does not invoke the engine's measurement pass.\n */\n refreshRenderedContent(): void {\n if (!this.hostRef) return;\n const scroller = this.hostRef.scroller;\n\n for (const index of scroller.getRenderedIndices()) {\n const container = scroller.getRenderedElement(index);\n if (!container) continue;\n\n const view = this.viewByContainer.get(container);\n if (!view) continue;\n\n const item = this.getItemForIndex(index);\n view.context.$implicit = item;\n view.context.item = item;\n view.context.index = index;\n view.detectChanges();\n }\n }\n\n private destroyAllViews(): void {\n for (const view of this.viewByContainer.values()) {\n this.appRef.detachView(view);\n view.destroy();\n }\n this.viewByContainer.clear();\n for (const view of this.freeViews) {\n this.appRef.detachView(view);\n view.destroy();\n }\n this.freeViews.length = 0;\n }\n}\n","import {\n AfterContentInit,\n ChangeDetectionStrategy,\n Component,\n ContentChild,\n TemplateRef,\n} from '@angular/core';\n\nimport { CeriousScrollDirective } from './cerious-scroll.directive';\nimport {\n CeriousScrollItemTemplateDirective,\n type CeriousScrollItemTemplateContext,\n} from './cerious-scroll-item-template.directive';\n\n@Component({\n selector: 'cerious-scroll',\n standalone: true,\n imports: [],\n hostDirectives: [\n {\n directive: CeriousScrollDirective,\n inputs: [\n 'ceriousScrollTotalElements: totalElements',\n 'ceriousScrollItems: items',\n 'ceriousScrollGetItem: getItem',\n 'ceriousScrollItemTemplate: itemTemplate',\n 'ceriousScrollHeaderTemplate: headerTemplate',\n 'ceriousScrollOptions: options',\n 'ceriousScrollAutoRender: autoRender',\n ],\n outputs: [\n 'ceriousScrollViewportChange: viewportChange',\n 'ceriousScrollMeasuredViewport: measuredViewport',\n 'ceriousScrollReady: scrollerReady',\n ],\n },\n ],\n template: `<ng-content />`,\n styles: `\n :host {\n display: block;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CeriousScrollComponent<TItem = unknown> implements AfterContentInit {\n /** Optional convenience template marker: <ng-template ceriousScrollItem let-item let-index=\"index\">...</ng-template> */\n @ContentChild(CeriousScrollItemTemplateDirective)\n private readonly projectedItemTemplate?: CeriousScrollItemTemplateDirective<TItem>;\n\n constructor(private readonly ceriousScroll: CeriousScrollDirective<TItem>) {}\n\n ngAfterContentInit(): void {\n if (this.ceriousScroll.ceriousScrollItemTemplate) return;\n if (!this.projectedItemTemplate) return;\n\n this.ceriousScroll.ceriousScrollItemTemplate =\n this.projectedItemTemplate.templateRef as TemplateRef<CeriousScrollItemTemplateContext<TItem>>;\n\n if (this.ceriousScroll.ceriousScrollAutoRender) {\n queueMicrotask(() => this.ceriousScroll.render());\n }\n }\n}\n","/*\n * Public API Surface of ngx-cerious-scroll\n */\n\nexport * from './lib/cerious-scroll.types';\nexport * from './lib/cerious-scroll.observable';\nexport * from './lib/cerious-scroll-item-template.directive';\nexport * from './lib/cerious-scroll.directive';\nexport * from './lib/cerious-scroll.component';\nexport * from './lib/cerious-scroll.service';\n\n// Re-export upstream types/classes for convenience\nexport * from '@ceriousdevtech/cerious-scroll';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.CeriousScrollService","i1.CeriousScrollDirective"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ceriousdevtech-ngx-cerious-scroll.mjs","sources":["../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll.observable.ts","../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll-item-template.directive.ts","../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll.service.ts","../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll.directive.ts","../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll.component.ts","../../../projects/ngx-cerious-scroll/src/public-api.ts","../../../projects/ngx-cerious-scroll/src/ceriousdevtech-ngx-cerious-scroll.ts"],"sourcesContent":["import { fromEvent, map, merge, Observable, share } from 'rxjs';\n\nimport type { ScrollResult } from '@ceriousdevtech/cerious-scroll';\n\nimport {\n CeriousNativeScrollbarViewportChangeEvent,\n CeriousViewportChangeDetail,\n CeriousViewportChangeEvent,\n} from './cerious-scroll.types';\n\n/**\n * Observable wrapper around the `cerious-viewport-change` CustomEvent emitted by `@ceriousdevtech/cerious-scroll`.\n *\n * Note: this event is emitted when wheel/touch/keyboard handlers are enabled (defaults are enabled).\n */\nexport function ceriousViewportChange$(container: HTMLElement): Observable<CeriousViewportChangeDetail> {\n const fromCerious = fromEvent<CeriousViewportChangeEvent>(container, 'cerious-viewport-change').pipe(\n map((evt) => evt.detail)\n );\n\n // Native scrollbar integration in the upstream package dispatches `viewport-change`.\n // Normalize it into the same shape as `cerious-viewport-change`.\n const fromScrollbar = fromEvent<CeriousNativeScrollbarViewportChangeEvent>(container, 'viewport-change').pipe(\n map((evt) => {\n const result: ScrollResult = { element: evt.detail.element, offset: evt.detail.scrollOffset };\n return {\n percentage: evt.detail.percentage,\n currentElement: evt.detail.element,\n scrollOffset: evt.detail.scrollOffset,\n result,\n } satisfies CeriousViewportChangeDetail;\n })\n );\n\n return merge(fromCerious, fromScrollbar).pipe(share());\n}\n","import { Directive, TemplateRef } from '@angular/core';\n\nexport interface CeriousScrollItemTemplateContext<TItem = unknown> {\n /** The item for this row (also available as `$implicit`). */\n $implicit: TItem;\n /** Row index. */\n index: number;\n /** Same as `$implicit` for named access. */\n item: TItem;\n}\n\n/**\n * Marks an `ng-template` as the row template for `CeriousScrollComponent`.\n *\n * Usage:\n * ```html\n * <cerious-scroll [items]=\"items\">\n * <ng-template ceriousScrollItem let-item let-index=\"index\">\n * {{ index }} - {{ item.name }}\n * </ng-template>\n * </cerious-scroll>\n * ```\n */\n@Directive({\n selector: 'ng-template[ceriousScrollItem]',\n standalone: true,\n})\nexport class CeriousScrollItemTemplateDirective<TItem = unknown> {\n constructor(public readonly templateRef: TemplateRef<CeriousScrollItemTemplateContext<TItem>>) {}\n}\n","import { Injectable, NgZone } from '@angular/core';\n\nimport { CeriousScroll, type CeriousScrollOptions } from '@ceriousdevtech/cerious-scroll';\nimport { Observable } from 'rxjs';\n\nimport { ceriousViewportChange$ } from './cerious-scroll.observable';\nimport type { CeriousViewportChangeDetail } from './cerious-scroll.types';\n\nconst CONTENT_ATTR = 'data-cerious-scroll-content';\n\nfunction ensureContentElement(container: HTMLElement): HTMLElement {\n const existing = container.querySelector<HTMLElement>(`[${CONTENT_ATTR}]`);\n if (existing) return existing;\n\n const el = document.createElement('div');\n el.setAttribute(CONTENT_ATTR, '');\n el.style.position = 'relative';\n el.style.width = '100%';\n el.style.height = '100%';\n // overflow-y: clip + overflow-x: auto: clip vertical row overflow (engine\n // owns vertical) and let the inner element own the native horizontal\n // scrollbar when consumer content (e.g. wide spreadsheet) overflows.\n // Horizontal scroll must NOT move to the outer container or the cerious\n // sibling-driver vertical scrollbar (`position: absolute; right: 0` inside\n // the outer) would translate with the content. The engine reads its\n // viewport height from this element so the bottom row stays clear of the\n // h-scrollbar gutter when it appears.\n el.style.overflowY = 'clip';\n el.style.overflowX = 'auto';\n container.appendChild(el);\n return el;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class CeriousScrollService {\n createHost(\n container: HTMLElement,\n totalElements: number,\n options: CeriousScrollOptions,\n ngZone: NgZone,\n onScrollHook?: () => void\n ): CeriousScrollHostRef {\n const contentElement = options.layout === 'masonry'\n ? container\n : ensureContentElement(container);\n let scroller!: CeriousScroll;\n\n ngZone.runOutsideAngular(() => {\n const userOnScroll = options?.onScroll;\n const mergedOptions: CeriousScrollOptions = {\n ...options,\n onScroll: () => {\n userOnScroll?.();\n onScrollHook?.();\n },\n };\n\n scroller = new CeriousScroll(container, totalElements, mergedOptions);\n });\n\n const viewportChanges$ = ceriousViewportChange$(container);\n\n return {\n scroller,\n contentElement,\n viewportChanges$,\n destroy: () => {\n scroller.detachScrollbar(container);\n scroller.dispose();\n // Remove rendered content after the engine has detached its own DOM.\n contentElement.textContent = '';\n },\n };\n }\n}\n\nexport interface CeriousScrollHostRef {\n readonly scroller: CeriousScroll;\n /** Dedicated element used for row rendering (prevents scrollbar DOM from being cleared). */\n readonly contentElement: HTMLElement;\n readonly viewportChanges$: Observable<CeriousViewportChangeDetail>;\n destroy(): void;\n}\n","import {\n AfterViewInit,\n ApplicationRef,\n Directive,\n ElementRef,\n EmbeddedViewRef,\n EventEmitter,\n Input,\n NgZone,\n OnChanges,\n OnDestroy,\n Output,\n SimpleChanges,\n TemplateRef,\n} from '@angular/core';\n\nimport {\n type CeriousScrollOptions as CoreCeriousScrollOptions,\n type ElementRenderer,\n type MeasuredViewportRange,\n} from '@ceriousdevtech/cerious-scroll';\nimport { Subscription } from 'rxjs';\n\nimport type { CeriousViewportChangeDetail } from './cerious-scroll.types';\nimport type { CeriousScrollOptions } from './cerious-scroll.types';\nimport type { CeriousScrollItemTemplateContext } from './cerious-scroll-item-template.directive';\nimport { type CeriousScrollHostRef, CeriousScrollService } from './cerious-scroll.service';\n\nfunction coerceTotalElements(explicitTotal: number | null | undefined, itemsLen: number | null | undefined): number {\n const candidate = typeof explicitTotal === 'number' ? explicitTotal : typeof itemsLen === 'number' ? itemsLen : undefined;\n if (candidate === undefined || Number.isNaN(candidate)) {\n throw new Error('CeriousScrollDirective: provide `ceriousScrollTotalElements` or `ceriousScrollItems`.');\n }\n // CeriousScroll currently requires >= 1\n return Math.max(1, candidate);\n}\n\n@Directive({\n selector: '[ceriousScroll]',\n standalone: true,\n})\nexport class CeriousScrollDirective<TItem = unknown> implements AfterViewInit, OnChanges, OnDestroy {\n /** Total number of items. If omitted, derived from `ceriousScrollItems.length`. */\n @Input() ceriousScrollTotalElements: number | null = null;\n\n /** Optional items array (enables `let-item`). */\n @Input() ceriousScrollItems: readonly TItem[] | null = null;\n\n /** Optional getter for large datasets (alternative to passing full `items`). */\n @Input() ceriousScrollGetItem: ((index: number) => TItem) | null = null;\n\n /** Template used to render each row. */\n @Input() ceriousScrollItemTemplate: TemplateRef<CeriousScrollItemTemplateContext<TItem>> | null = null;\n\n /**\n * Table mode only: template rendered into the engine's `<thead>` (a `<tr>` of\n * `<th>`s). It lives in the same `<table>` as the rows, so columns align\n * natively. Updates via change detection like the rows.\n */\n @Input() ceriousScrollHeaderTemplate: TemplateRef<unknown> | null = null;\n\n /** Options passed to `new CeriousScroll(...)`. */\n @Input() ceriousScrollOptions: CeriousScrollOptions = {};\n\n /** Automatically call render after each scroll event. Default: true */\n @Input() ceriousScrollAutoRender = true;\n\n /** Emits `cerious-viewport-change` detail. */\n @Output() ceriousScrollViewportChange = new EventEmitter<CeriousViewportChangeDetail>();\n\n /** Emits the last measured viewport after each render pass. */\n @Output() ceriousScrollMeasuredViewport = new EventEmitter<MeasuredViewportRange>();\n\n /** Emits once the underlying `CeriousScroll` instance is ready. */\n @Output() ceriousScrollReady = new EventEmitter<CeriousScrollHostRef['scroller']>();\n\n private hostRef: CeriousScrollHostRef | null = null;\n private viewportSub: Subscription | null = null;\n private scheduledRenderFrame: number | null = null;\n // Incremented by the core-owned Masonry renderer whenever it mounts a probe\n // or visible card. Unlike row mode, those calls do not flow through the\n // ElementRenderer passed to renderViewport().\n private masonryRendererEpoch = 0;\n\n private readonly viewByContainer = new Map<HTMLElement, EmbeddedViewRef<CeriousScrollItemTemplateContext<TItem>>>();\n // Pool of views detached because their container left the viewport. Reusing\n // them on subsequent renders avoids destroying + recreating the entire row\n // component tree on fast scrolls (where the engine's element pool wipes\n // textContent on reused containers, so view rootNodes get orphaned).\n private readonly freeViews: EmbeddedViewRef<CeriousScrollItemTemplateContext<TItem>>[] = [];\n\n // Table mode: the embedded view of the declarative header, rendered into the\n // engine's <thead>.\n private headerView: EmbeddedViewRef<unknown> | null = null;\n\n /** Underlying core engine instance, or null before initialization. */\n get scroller(): CeriousScrollHostRef['scroller'] | null {\n return this.hostRef?.scroller ?? null;\n }\n\n constructor(\n private readonly host: ElementRef<HTMLElement>,\n private readonly appRef: ApplicationRef,\n private readonly ngZone: NgZone,\n private readonly cerious: CeriousScrollService\n ) {}\n\n ngAfterViewInit(): void {\n this.ensureInitialized();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (!this.hostRef) return;\n\n if (changes['ceriousScrollItems'] || changes['ceriousScrollTotalElements']) {\n const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);\n const masonryMode = this.ceriousScrollOptions.layout === 'masonry';\n const currentCount = masonryMode\n ? this.hostRef.scroller.itemCount\n : this.hostRef.scroller.totalElements;\n const countChanged = currentCount !== total;\n\n if (countChanged) {\n if (masonryMode) {\n // Masonry's renderer owns card-count-derived segment state. Recreate\n // it when the dataset size changes rather than updating segment count\n // through the row-oriented updateTotalElements API.\n this.recreate();\n return;\n }\n // Grow/shrink the dataset IN PLACE — no recreate. updateTotalElements\n // propagates the new count to every subsystem, INCLUDING the\n // ViewportRenderer's own copy of totalElements (it used to go stale,\n // which is exactly why this recreated: the renderer kept the old count\n // for its viewport-fill loop and bottom scan, producing phantom\n // out-of-bounds renders). In place keeps the scroll position and an\n // in-progress scrollbar drag alive, and a growing dataset keeps a stable\n // bottom index (no bouncing tail). The track lengthens, so re-sync the\n // thumb afterwards.\n this.hostRef.scroller.updateTotalElements(total);\n // A shrink can leave the position past the new end — clamp it.\n if (this.hostRef.scroller.currentElement > total - 1) {\n this.hostRef.scroller.jumpToElement(total - 1);\n }\n if (this.ceriousScrollAutoRender) this.render();\n this.hostRef.scroller.syncScrollbar();\n } else if (this.ceriousScrollAutoRender) {\n // Same count, new data reference (e.g. an immutable edit or a sort that\n // happens to keep the same length). The engine reuses the DOM element it\n // already rendered for each overlapping index without re-invoking the\n // renderer, so update the content of every currently-visible row IN\n // PLACE before calling render(). This preserves each row's embedded\n // view (so a focused textbox keeps focus/caret) and does NOT discard\n // cached heights. If a row's height actually changes the engine's\n // ResizeObserver keeps the cache correct on its own; for a wholesale\n // height change across all rows, call recalculate() instead.\n this.refreshRenderedContent();\n this.render();\n }\n }\n\n if (changes['ceriousScrollOptions'] && !changes['ceriousScrollOptions'].firstChange) {\n // Options are consumed primarily at construction time.\n this.recreate();\n }\n }\n\n ngOnDestroy(): void {\n if (this.scheduledRenderFrame != null) {\n cancelAnimationFrame(this.scheduledRenderFrame);\n this.scheduledRenderFrame = null;\n }\n\n this.viewportSub?.unsubscribe();\n this.viewportSub = null;\n\n this.destroyAllViews();\n this.headerView?.destroy();\n this.headerView = null;\n\n this.hostRef?.destroy();\n this.hostRef = null;\n }\n\n /** Imperatively trigger a render pass (uses `ceriousScrollItemTemplate`). */\n render(): MeasuredViewportRange | null {\n if (!this.hostRef) return null;\n const template = this.ceriousScrollItemTemplate;\n if (!template) return null;\n\n const hostContainer = this.host.nativeElement;\n const height = hostContainer.clientHeight || hostContainer.offsetHeight;\n const contentContainer = this.hostRef.contentElement;\n\n // Track whether the engine asked us to bind any row this pass. Pure scroll\n // frames where the visible row set doesn't change still drive render() via\n // the rAF coalescer — there's no point in walking the prune map or\n // emitting the viewport range when nothing was touched.\n let rendererInvocations = 0;\n const renderer: ElementRenderer = (index, elementContainer) => {\n rendererInvocations++;\n // Render each row's embedded view with LOCAL change detection\n // (`view.detectChanges()` inside `renderTemplateIntoContainer`) so the\n // engine can measure its height during this pass. Do NOT wrap each row in\n // its own `ngZone.run` — that fires a full `ApplicationRef` tick *per row*\n // (O(newRows × visibleRows) work, janky drags). The single coalesced tick\n // for the whole pass is handled by the caller (`scheduleRender`).\n this.renderTemplateIntoContainer(template, index, elementContainer);\n };\n\n const masonryMode = this.ceriousScrollOptions.layout === 'masonry';\n const masonryEpochBefore = this.masonryRendererEpoch;\n const range = this.hostRef.scroller.renderViewport(height, contentContainer, renderer);\n const masonryInvocations = this.masonryRendererEpoch - masonryEpochBefore;\n\n if (rendererInvocations === 0 && (!masonryMode || masonryInvocations === 0)) {\n // Viewport didn't change — skip the prune walk and the (potentially\n // zone-entering) emit.\n return range;\n }\n\n // Destroy views whose container the engine no longer renders. Without this,\n // every container the engine recycles into its element pool leaves its\n // embedded view attached to ApplicationRef forever — so the attached-view\n // list (and every O(n) `detachView`) grows without bound and scrolling gets\n // progressively slower. Mirrors the React/Vue wrappers, which drop rows that\n // fall out of `getRenderedIndices()`.\n this.pruneDetachedViews();\n\n // Only re-enter the zone (a global tick) if someone is actually listening.\n if (this.ceriousScrollMeasuredViewport.observed) {\n this.ngZone.run(() => this.ceriousScrollMeasuredViewport.emit(range));\n }\n return range;\n }\n\n /** Tear down embedded views whose container is no longer part of the viewport. */\n private pruneDetachedViews(): void {\n if (!this.hostRef || this.viewByContainer.size === 0) return;\n const scroller = this.hostRef.scroller;\n const masonryMode = this.ceriousScrollOptions.layout === 'masonry';\n const active = new Set<HTMLElement>();\n if (masonryMode) {\n this.host.nativeElement\n .querySelectorAll<HTMLElement>('[data-element-index]')\n .forEach((el) => active.add(el));\n } else {\n for (const index of scroller.getRenderedIndices()) {\n const el = scroller.getRenderedElement(index);\n if (el) active.add(el);\n }\n }\n for (const [container, view] of this.viewByContainer) {\n if (!active.has(container)) {\n // Detach DOM but keep the view alive in the pool for future reuse.\n // Destroying + recreating views per scroll step dominates frame time.\n for (const node of view.rootNodes) {\n if (node.parentNode) node.parentNode.removeChild(node);\n }\n this.viewByContainer.delete(container);\n this.freeViews.push(view);\n }\n }\n }\n\n /** Auto-render coalesced to at most once per animation frame. */\n private scheduleRender(): void {\n if (this.scheduledRenderFrame != null) return;\n this.scheduledRenderFrame = requestAnimationFrame(() => {\n this.scheduledRenderFrame = null;\n // Run render() OUTSIDE Angular's zone. A full ApplicationRef.tick() on\n // every scroll frame is the primary FPS bottleneck: even when no rows\n // change (pure translation), ngZone.run() causes Angular to walk the\n // entire component tree. Instead we call view.detectChanges() locally\n // inside renderTemplateIntoContainer for each affected row. Zone entry is\n // only needed when creating a brand-new embedded view (to zone-patch its\n // event listeners) — recycled and pooled views were already created inside\n // zone and their listeners remain zone-aware.\n this.render();\n });\n }\n\n /**\n * Discard all cached row heights and re-measure the viewport.\n *\n * Call this only when the heights of rows you've *already rendered* may have\n * changed without their indices changing — e.g. a global font/density change,\n * or swapping every row to a different layout. This forces a synchronous\n * re-measure (one `offsetHeight` read per visible row), so do NOT call it on\n * routine edits: a single cell edit keeps its row's size, and the engine's\n * ResizeObserver picks up any incidental resize on its own.\n */\n recalculate(): MeasuredViewportRange | null {\n if (!this.hostRef) return null;\n const template = this.ceriousScrollItemTemplate;\n if (template) {\n // Re-invoke the renderer for every currently-rendered row so pending\n // Angular bindings flush into the DOM and the engine re-measures each\n // row's new height into its cache. Without this, the engine's render\n // pass skips the renderer for already-rendered indices and falls\n // through to reading stale offsetHeight.\n this.hostRef.scroller.refreshVisible((index, elementContainer) => {\n this.renderTemplateIntoContainer(template, index, elementContainer);\n });\n }\n return this.render();\n }\n\n /** Jump directly to an element index, then render. */\n jumpToElement(index: number): MeasuredViewportRange | null {\n if (!this.hostRef) return null;\n this.hostRef.scroller.jumpToElement(index);\n return this.render();\n }\n\n /** Masonry mode only: jump directly to a card index, then render. */\n jumpToItem(index: number, screenOffset = 0): MeasuredViewportRange | null {\n if (!this.hostRef) return null;\n this.hostRef.scroller.jumpToItem(index, screenOffset);\n return this.render();\n }\n\n /** Scroll to a percentage (0..100), then render. */\n scrollToPercentage(percentage: number): MeasuredViewportRange | null {\n if (!this.hostRef) return null;\n this.hostRef.scroller.handleScrollPercentage(percentage);\n return this.render();\n }\n\n /** Reset to the top, then render. */\n reset(): MeasuredViewportRange | null {\n if (!this.hostRef) return null;\n this.hostRef.scroller.reset();\n return this.render();\n }\n\n private recreate(): void {\n this.viewportSub?.unsubscribe();\n this.viewportSub = null;\n\n this.destroyAllViews();\n\n this.hostRef?.destroy();\n this.hostRef = null;\n\n this.ensureInitialized();\n }\n\n private ensureInitialized(): void {\n if (this.hostRef) return;\n\n const container = this.host.nativeElement;\n const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);\n\n // Table mode: capture the engine-created <thead> so we can render the\n // declarative header template into it (and still run any user header hook).\n let options: CoreCeriousScrollOptions;\n if (this.ceriousScrollOptions.layout === 'masonry') {\n if (!this.ceriousScrollOptions.masonry) {\n throw new Error(\"CeriousScrollDirective: layout 'masonry' requires `ceriousScrollOptions.masonry`.\");\n }\n options = {\n ...this.ceriousScrollOptions,\n masonry: {\n ...this.ceriousScrollOptions.masonry,\n renderItem: (index, element) => {\n this.masonryRendererEpoch++;\n const template = this.ceriousScrollItemTemplate;\n if (!template) return;\n if (element.dataset['ceriousMasonry'] === 'probe') {\n this.renderProbe(template, index, element);\n } else {\n this.renderTemplateIntoContainer(template, index, element);\n }\n },\n },\n };\n } else {\n options = this.ceriousScrollOptions as CoreCeriousScrollOptions;\n }\n if (options.layout === 'table' && this.ceriousScrollHeaderTemplate) {\n const userHeader = options.table?.header;\n options = {\n ...options,\n table: {\n ...options.table,\n header: (thead: HTMLTableSectionElement) => {\n userHeader?.(thead);\n this.mountHeader(thead);\n },\n },\n };\n }\n\n this.hostRef = this.cerious.createHost(container, total, options, this.ngZone, () => {\n // Coalesce scroll-driven renders to one per frame (the native scrollbar\n // can fire many scroll events between paints).\n if (this.ceriousScrollAutoRender) this.scheduleRender();\n });\n\n this.viewportSub = this.hostRef.viewportChanges$.subscribe((detail: CeriousViewportChangeDetail) => {\n // Skip the global tick when nobody is bound to the output.\n if (this.ceriousScrollViewportChange.observed) {\n this.ngZone.run(() => this.ceriousScrollViewportChange.emit(detail));\n }\n });\n\n this.ceriousScrollReady.emit(this.hostRef.scroller);\n\n if (this.ceriousScrollAutoRender) {\n queueMicrotask(() => this.render());\n }\n }\n\n /**\n * Render the declarative header template into the engine's <thead>. One\n * embedded view, created inside the zone (so the header's event bindings are\n * zone-patched), its root nodes appended directly into the <thead>.\n */\n private mountHeader(thead: HTMLElement): void {\n if (!this.ceriousScrollHeaderTemplate) return;\n this.headerView?.destroy();\n const view = this.ngZone.run(() => {\n const v = this.ceriousScrollHeaderTemplate!.createEmbeddedView({});\n this.appRef.attachView(v);\n v.detectChanges();\n return v;\n });\n for (const node of view.rootNodes) thead.appendChild(node);\n this.headerView = view;\n }\n\n private getItemForIndex(index: number): TItem {\n const getter = this.ceriousScrollGetItem;\n if (getter) return getter(index);\n\n const items = this.ceriousScrollItems;\n if (!items) return undefined as TItem;\n\n return items[index];\n }\n\n private renderProbe(\n template: TemplateRef<CeriousScrollItemTemplateContext<TItem>>,\n index: number,\n container: HTMLElement\n ): void {\n const item = this.getItemForIndex(index);\n const view = this.ngZone.runOutsideAngular(() => {\n const v = template.createEmbeddedView({ $implicit: item, item, index });\n v.detectChanges();\n return v;\n });\n for (const node of view.rootNodes) container.appendChild(node);\n\n // Measurement probes are deliberately NOT attached to ApplicationRef:\n // they are disposable, non-interactive markup and local detectChanges() is\n // enough to populate their DOM synchronously. Attaching each probe inside\n // Angular's zone turns dynamic scrolling into repeated application-wide\n // change-detection work. The core reads offsetHeight immediately after this\n // callback and clears the probe, so destroy the isolated view afterwards.\n queueMicrotask(() => {\n view.destroy();\n });\n }\n\n private renderTemplateIntoContainer(\n template: TemplateRef<CeriousScrollItemTemplateContext<TItem>>,\n index: number,\n elementContainer: HTMLElement\n ): void {\n const previous = this.viewByContainer.get(elementContainer);\n if (previous) {\n // Recycle: update the bound context and run local CD instead of\n // destroying the embedded view and rebuilding the entire row tree.\n const item = this.getItemForIndex(index);\n previous.context.$implicit = item;\n previous.context.item = item;\n previous.context.index = index;\n // The core engine wipes elementContainer.textContent when reusing it from\n // its pool, orphaning the view's root nodes. Re-append them defensively.\n if (previous.rootNodes.length && previous.rootNodes[0].parentNode !== elementContainer) {\n for (const node of previous.rootNodes) {\n elementContainer.appendChild(node);\n }\n }\n previous.detectChanges();\n return;\n }\n\n // Try to reuse a pooled view from a container that scrolled out of viewport.\n const pooled = this.freeViews.pop();\n if (pooled) {\n const item = this.getItemForIndex(index);\n pooled.context.$implicit = item;\n pooled.context.item = item;\n pooled.context.index = index;\n elementContainer.textContent = '';\n for (const node of pooled.rootNodes) {\n elementContainer.appendChild(node);\n }\n pooled.detectChanges();\n this.viewByContainer.set(elementContainer, pooled);\n return;\n }\n\n // No prior view for this container: create one.\n // Enter the Angular zone so the new view's template event listeners\n // ((click), (input), etc.) are zone-patched. This path runs at most\n // once per visible row (after that, the view is recycled from the pool).\n elementContainer.textContent = '';\n\n const item = this.getItemForIndex(index);\n const view = this.ngZone.run(() => {\n const v = template.createEmbeddedView({ $implicit: item, item, index });\n this.appRef.attachView(v);\n v.detectChanges();\n return v;\n });\n\n for (const node of view.rootNodes) {\n elementContainer.appendChild(node);\n }\n\n this.viewByContainer.set(elementContainer, view);\n }\n\n /**\n * Update the bound item/index on every currently-rendered row's embedded view\n * and run change detection, without recreating the views. Used when the data\n * reference changes but the visible indices (and their heights) do not, so row\n * state (focus, selection, open dropdowns) survives the update.\n */\n /**\n * Re-bind each currently rendered row's context (from the current items/getter)\n * and run change detection on its embedded view. Use this after mutating row\n * state in place (e.g. selection flags) or column-level state read by the row\n * template, when row identity and visible indices have not changed. Cheap\n * relative to `render()` — does not invoke the engine's measurement pass.\n */\n refreshRenderedContent(): void {\n if (!this.hostRef) return;\n const scroller = this.hostRef.scroller;\n\n for (const index of scroller.getRenderedIndices()) {\n const container = scroller.getRenderedElement(index);\n if (!container) continue;\n\n const view = this.viewByContainer.get(container);\n if (!view) continue;\n\n const item = this.getItemForIndex(index);\n view.context.$implicit = item;\n view.context.item = item;\n view.context.index = index;\n view.detectChanges();\n }\n }\n\n private destroyAllViews(): void {\n for (const view of this.viewByContainer.values()) {\n this.appRef.detachView(view);\n view.destroy();\n }\n this.viewByContainer.clear();\n for (const view of this.freeViews) {\n this.appRef.detachView(view);\n view.destroy();\n }\n this.freeViews.length = 0;\n }\n}\n","import {\n AfterContentInit,\n ChangeDetectionStrategy,\n Component,\n ContentChild,\n TemplateRef,\n} from '@angular/core';\n\nimport { CeriousScrollDirective } from './cerious-scroll.directive';\nimport {\n CeriousScrollItemTemplateDirective,\n type CeriousScrollItemTemplateContext,\n} from './cerious-scroll-item-template.directive';\n\n@Component({\n selector: 'cerious-scroll',\n standalone: true,\n imports: [],\n hostDirectives: [\n {\n directive: CeriousScrollDirective,\n inputs: [\n 'ceriousScrollTotalElements: totalElements',\n 'ceriousScrollItems: items',\n 'ceriousScrollGetItem: getItem',\n 'ceriousScrollItemTemplate: itemTemplate',\n 'ceriousScrollHeaderTemplate: headerTemplate',\n 'ceriousScrollOptions: options',\n 'ceriousScrollAutoRender: autoRender',\n ],\n outputs: [\n 'ceriousScrollViewportChange: viewportChange',\n 'ceriousScrollMeasuredViewport: measuredViewport',\n 'ceriousScrollReady: scrollerReady',\n ],\n },\n ],\n template: `<ng-content />`,\n styles: `\n :host {\n display: block;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CeriousScrollComponent<TItem = unknown> implements AfterContentInit {\n /** Optional convenience template marker: <ng-template ceriousScrollItem let-item let-index=\"index\">...</ng-template> */\n @ContentChild(CeriousScrollItemTemplateDirective)\n private readonly projectedItemTemplate?: CeriousScrollItemTemplateDirective<TItem>;\n\n constructor(private readonly ceriousScroll: CeriousScrollDirective<TItem>) {}\n\n get scroller() { return this.ceriousScroll.scroller; }\n render() { return this.ceriousScroll.render(); }\n jumpToElement(index: number) { return this.ceriousScroll.jumpToElement(index); }\n jumpToItem(index: number, screenOffset = 0) {\n return this.ceriousScroll.jumpToItem(index, screenOffset);\n }\n scrollToPercentage(percentage: number) {\n return this.ceriousScroll.scrollToPercentage(percentage);\n }\n reset() { return this.ceriousScroll.reset(); }\n recalculate() { return this.ceriousScroll.recalculate(); }\n\n ngAfterContentInit(): void {\n if (this.ceriousScroll.ceriousScrollItemTemplate) return;\n if (!this.projectedItemTemplate) return;\n\n this.ceriousScroll.ceriousScrollItemTemplate =\n this.projectedItemTemplate.templateRef as TemplateRef<CeriousScrollItemTemplateContext<TItem>>;\n\n if (this.ceriousScroll.ceriousScrollAutoRender) {\n queueMicrotask(() => this.ceriousScroll.render());\n }\n }\n}\n","/*\n * Public API Surface of ngx-cerious-scroll\n */\n\nexport * from './lib/cerious-scroll.types';\nexport type { CeriousScrollOptions } from './lib/cerious-scroll.types';\nexport * from './lib/cerious-scroll.observable';\nexport * from './lib/cerious-scroll-item-template.directive';\nexport * from './lib/cerious-scroll.directive';\nexport * from './lib/cerious-scroll.component';\nexport * from './lib/cerious-scroll.service';\n\n// Re-export upstream types/classes for convenience\nexport * from '@ceriousdevtech/cerious-scroll';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.CeriousScrollService","i1.CeriousScrollDirective"],"mappings":"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"}
|
|
@@ -7,6 +7,13 @@ export declare class CeriousScrollComponent<TItem = unknown> implements AfterCon
|
|
|
7
7
|
/** Optional convenience template marker: <ng-template ceriousScrollItem let-item let-index="index">...</ng-template> */
|
|
8
8
|
private readonly projectedItemTemplate?;
|
|
9
9
|
constructor(ceriousScroll: CeriousScrollDirective<TItem>);
|
|
10
|
+
get scroller(): import("@ceriousdevtech/cerious-scroll").CeriousScroll | null;
|
|
11
|
+
render(): import("@ceriousdevtech/cerious-scroll").MeasuredViewportRange | null;
|
|
12
|
+
jumpToElement(index: number): import("@ceriousdevtech/cerious-scroll").MeasuredViewportRange | null;
|
|
13
|
+
jumpToItem(index: number, screenOffset?: number): import("@ceriousdevtech/cerious-scroll").MeasuredViewportRange | null;
|
|
14
|
+
scrollToPercentage(percentage: number): import("@ceriousdevtech/cerious-scroll").MeasuredViewportRange | null;
|
|
15
|
+
reset(): import("@ceriousdevtech/cerious-scroll").MeasuredViewportRange | null;
|
|
16
|
+
recalculate(): import("@ceriousdevtech/cerious-scroll").MeasuredViewportRange | null;
|
|
10
17
|
ngAfterContentInit(): void;
|
|
11
18
|
static ɵfac: i0.ɵɵFactoryDeclaration<CeriousScrollComponent<any>, never>;
|
|
12
19
|
static ɵcmp: i0.ɵɵComponentDeclaration<CeriousScrollComponent<any>, "cerious-scroll", never, {}, {}, ["projectedItemTemplate"], ["*"], true, [{ directive: typeof i1.CeriousScrollDirective; inputs: { "ceriousScrollTotalElements": "totalElements"; "ceriousScrollItems": "items"; "ceriousScrollGetItem": "getItem"; "ceriousScrollItemTemplate": "itemTemplate"; "ceriousScrollHeaderTemplate": "headerTemplate"; "ceriousScrollOptions": "options"; "ceriousScrollAutoRender": "autoRender"; }; outputs: { "ceriousScrollViewportChange": "viewportChange"; "ceriousScrollMeasuredViewport": "measuredViewport"; "ceriousScrollReady": "scrollerReady"; }; }]>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { AfterViewInit, ApplicationRef, ElementRef, EventEmitter, NgZone, OnChanges, OnDestroy, SimpleChanges, TemplateRef } from '@angular/core';
|
|
2
|
-
import { type
|
|
2
|
+
import { type MeasuredViewportRange } from '@ceriousdevtech/cerious-scroll';
|
|
3
3
|
import type { CeriousViewportChangeDetail } from './cerious-scroll.types';
|
|
4
|
+
import type { CeriousScrollOptions } from './cerious-scroll.types';
|
|
4
5
|
import type { CeriousScrollItemTemplateContext } from './cerious-scroll-item-template.directive';
|
|
5
|
-
import { CeriousScrollService } from './cerious-scroll.service';
|
|
6
|
+
import { type CeriousScrollHostRef, CeriousScrollService } from './cerious-scroll.service';
|
|
6
7
|
import * as i0 from "@angular/core";
|
|
7
8
|
export declare class CeriousScrollDirective<TItem = unknown> implements AfterViewInit, OnChanges, OnDestroy {
|
|
8
9
|
private readonly host;
|
|
@@ -36,9 +37,12 @@ export declare class CeriousScrollDirective<TItem = unknown> implements AfterVie
|
|
|
36
37
|
private hostRef;
|
|
37
38
|
private viewportSub;
|
|
38
39
|
private scheduledRenderFrame;
|
|
40
|
+
private masonryRendererEpoch;
|
|
39
41
|
private readonly viewByContainer;
|
|
40
42
|
private readonly freeViews;
|
|
41
43
|
private headerView;
|
|
44
|
+
/** Underlying core engine instance, or null before initialization. */
|
|
45
|
+
get scroller(): CeriousScrollHostRef['scroller'] | null;
|
|
42
46
|
constructor(host: ElementRef<HTMLElement>, appRef: ApplicationRef, ngZone: NgZone, cerious: CeriousScrollService);
|
|
43
47
|
ngAfterViewInit(): void;
|
|
44
48
|
ngOnChanges(changes: SimpleChanges): void;
|
|
@@ -62,6 +66,8 @@ export declare class CeriousScrollDirective<TItem = unknown> implements AfterVie
|
|
|
62
66
|
recalculate(): MeasuredViewportRange | null;
|
|
63
67
|
/** Jump directly to an element index, then render. */
|
|
64
68
|
jumpToElement(index: number): MeasuredViewportRange | null;
|
|
69
|
+
/** Masonry mode only: jump directly to a card index, then render. */
|
|
70
|
+
jumpToItem(index: number, screenOffset?: number): MeasuredViewportRange | null;
|
|
65
71
|
/** Scroll to a percentage (0..100), then render. */
|
|
66
72
|
scrollToPercentage(percentage: number): MeasuredViewportRange | null;
|
|
67
73
|
/** Reset to the top, then render. */
|
|
@@ -75,6 +81,7 @@ export declare class CeriousScrollDirective<TItem = unknown> implements AfterVie
|
|
|
75
81
|
*/
|
|
76
82
|
private mountHeader;
|
|
77
83
|
private getItemForIndex;
|
|
84
|
+
private renderProbe;
|
|
78
85
|
private renderTemplateIntoContainer;
|
|
79
86
|
/**
|
|
80
87
|
* Update the bound item/index on every currently-rendered row's embedded view
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import type { ScrollResult } from '@ceriousdevtech/cerious-scroll';
|
|
1
|
+
import type { CeriousScrollOptions as CoreCeriousScrollOptions, MasonryOptions, ScrollResult } from '@ceriousdevtech/cerious-scroll';
|
|
2
|
+
/** Engine options adapted for Angular-owned Masonry rendering. */
|
|
3
|
+
export type CeriousScrollOptions = Omit<CoreCeriousScrollOptions, 'masonry'> & {
|
|
4
|
+
masonry?: Omit<MasonryOptions, 'renderItem'> & {
|
|
5
|
+
/** Accepted for backward compatibility; Angular supplies the active renderer. */
|
|
6
|
+
renderItem?: MasonryOptions['renderItem'];
|
|
7
|
+
};
|
|
8
|
+
};
|
|
2
9
|
/**
|
|
3
10
|
* Detail payload for the `cerious-viewport-change` CustomEvent dispatched by `@ceriousdevtech/cerious-scroll`.
|
|
4
11
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ceriousdevtech/ngx-cerious-scroll",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"@angular/core": ">=16.0.0"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@ceriousdevtech/cerious-scroll": "^1.0
|
|
14
|
+
"@ceriousdevtech/cerious-scroll": "^1.1.0",
|
|
15
15
|
"tslib": "^2.3.0"
|
|
16
16
|
},
|
|
17
17
|
"sideEffects": false,
|
package/public-api.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './lib/cerious-scroll.types';
|
|
2
|
+
export type { CeriousScrollOptions } from './lib/cerious-scroll.types';
|
|
2
3
|
export * from './lib/cerious-scroll.observable';
|
|
3
4
|
export * from './lib/cerious-scroll-item-template.directive';
|
|
4
5
|
export * from './lib/cerious-scroll.directive';
|