@libs-ui/components-scroll-measure-items-direction-vertical 0.2.356-25 → 0.2.356-27
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/direction-vertical.directive.d.ts +9 -0
- package/esm2022/direction-vertical.directive.mjs +69 -38
- package/fesm2022/libs-ui-components-scroll-measure-items-direction-vertical.mjs +68 -37
- package/fesm2022/libs-ui-components-scroll-measure-items-direction-vertical.mjs.map +1 -1
- package/package.json +1 -2
|
@@ -2,11 +2,20 @@ import { AfterViewInit } from '@angular/core';
|
|
|
2
2
|
import { IScrollMeasureItemDirectionVerticalFunctionsControl } from './interfaces/direction-vertical.interface';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
export declare class LibsUiScrollMeasureItemDirectionVerticalDirective implements AfterViewInit {
|
|
5
|
+
/** Số item buffer render thêm sau viewport để tránh trắng vùng khi scroll. */
|
|
6
|
+
private readonly bufferAhead;
|
|
5
7
|
private viewPortItems;
|
|
6
8
|
private start;
|
|
7
9
|
private end;
|
|
8
10
|
private storeItems;
|
|
9
11
|
private divVirtual;
|
|
12
|
+
private resizeObserver?;
|
|
13
|
+
/** Tham chiếu setTimeout của ngAfterViewInit để clear khi destroy — chặn ResizeObserver mồ côi. */
|
|
14
|
+
private timerAfterViewInit?;
|
|
15
|
+
/** Token nhận dạng lần effect chạy hiện tại. Async đo height xong sẽ bỏ kết quả nếu token đổi. */
|
|
16
|
+
private executionToken;
|
|
17
|
+
/** Style + DOM hook của divVirtual chỉ cần khởi tạo một lần cho cả vòng đời directive. */
|
|
18
|
+
private divVirtualInitialized;
|
|
10
19
|
readonly elementScroll: import("@angular/core").InputSignal<HTMLElement>;
|
|
11
20
|
readonly functionGetHeightItem: import("@angular/core").InputSignal<(item: any) => Promise<number>>;
|
|
12
21
|
readonly items: import("@angular/core").InputSignal<any[]>;
|
|
@@ -2,16 +2,24 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
3
|
import { DestroyRef, Directive, ElementRef, effect, inject, input, output, signal, untracked } from '@angular/core';
|
|
4
4
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
|
-
import { get } from '@libs-ui/utils';
|
|
6
5
|
import { fromEvent } from 'rxjs';
|
|
7
6
|
import * as i0 from "@angular/core";
|
|
8
7
|
export class LibsUiScrollMeasureItemDirectionVerticalDirective {
|
|
9
8
|
// #region PROPERTY
|
|
9
|
+
/** Số item buffer render thêm sau viewport để tránh trắng vùng khi scroll. */
|
|
10
|
+
bufferAhead = 3;
|
|
10
11
|
viewPortItems = signal([]);
|
|
11
12
|
start = signal(0);
|
|
12
13
|
end = signal(0);
|
|
13
14
|
storeItems = signal([]);
|
|
14
15
|
divVirtual = document.createElement('div');
|
|
16
|
+
resizeObserver;
|
|
17
|
+
/** Tham chiếu setTimeout của ngAfterViewInit để clear khi destroy — chặn ResizeObserver mồ côi. */
|
|
18
|
+
timerAfterViewInit;
|
|
19
|
+
/** Token nhận dạng lần effect chạy hiện tại. Async đo height xong sẽ bỏ kết quả nếu token đổi. */
|
|
20
|
+
executionToken = 0;
|
|
21
|
+
/** Style + DOM hook của divVirtual chỉ cần khởi tạo một lần cho cả vòng đời directive. */
|
|
22
|
+
divVirtualInitialized = false;
|
|
15
23
|
// #region INPUT
|
|
16
24
|
elementScroll = input.required();
|
|
17
25
|
functionGetHeightItem = input.required();
|
|
@@ -26,59 +34,79 @@ export class LibsUiScrollMeasureItemDirectionVerticalDirective {
|
|
|
26
34
|
destroyRef = inject(DestroyRef);
|
|
27
35
|
constructor() {
|
|
28
36
|
effect(() => {
|
|
29
|
-
const scrollEl = untracked(() => this.ScrollContainer);
|
|
30
|
-
if (!scrollEl || !untracked(() => this.functionGetHeightItem())) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
37
|
const items = this.items();
|
|
38
|
+
const myToken = ++this.executionToken;
|
|
34
39
|
untracked(async () => {
|
|
40
|
+
const scrollEl = this.ScrollContainer;
|
|
41
|
+
const functionGetHeightItem = this.functionGetHeightItem();
|
|
42
|
+
if (!scrollEl || !functionGetHeightItem) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Đo height tất cả item song song — rút ngắn thời gian cho list lớn.
|
|
46
|
+
const heights = await Promise.all(items.map((it) => functionGetHeightItem(it)));
|
|
47
|
+
// Bị huỷ vì có lượt items() mới chạy sau — bỏ kết quả cũ tránh đè state.
|
|
48
|
+
if (myToken !== this.executionToken) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
35
51
|
this.start.set(0);
|
|
36
52
|
const scrollTop = scrollEl.scrollTop;
|
|
37
53
|
const containerHeight = scrollEl.getBoundingClientRect().height;
|
|
38
54
|
let height = 0;
|
|
55
|
+
let endLocal = 0;
|
|
39
56
|
const newItems = [];
|
|
40
57
|
for (let i = 0; i < items.length; i++) {
|
|
41
|
-
const
|
|
42
|
-
const newItem = { ref:
|
|
43
|
-
const itemHeight = await this.functionGetHeightItem()(item);
|
|
44
|
-
newItem.itemHeight = itemHeight;
|
|
45
|
-
newItem.start = height;
|
|
58
|
+
const itemHeight = heights[i];
|
|
59
|
+
const newItem = { ref: items[i], itemHeight, start: height, end: 0 };
|
|
46
60
|
height += itemHeight;
|
|
47
61
|
newItem.end = height;
|
|
48
62
|
if (newItem.end <= containerHeight + scrollTop) {
|
|
49
|
-
|
|
63
|
+
endLocal = i;
|
|
50
64
|
}
|
|
51
65
|
newItems.push(newItem);
|
|
52
66
|
}
|
|
67
|
+
// Set end một lần thay vì ghi mỗi vòng lặp — tránh notify consumer N lần.
|
|
68
|
+
this.end.set(endLocal);
|
|
53
69
|
this.storeItems.set(newItems);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
70
|
+
// Khởi tạo style + DOM hook của divVirtual đúng một lần.
|
|
71
|
+
if (!this.divVirtualInitialized) {
|
|
72
|
+
this.divVirtual.style.position = 'absolute';
|
|
73
|
+
this.divVirtual.style.top = '0px';
|
|
74
|
+
this.divVirtual.style.left = '0px';
|
|
75
|
+
this.divVirtual.style.width = '1px';
|
|
76
|
+
this.divVirtual.style.visibility = 'hidden'; // Đảm bảo an toàn không hiển thị
|
|
77
|
+
this.elementRef.nativeElement.classList.add('relative');
|
|
78
|
+
this.elementRef.nativeElement.classList.remove('h-full');
|
|
79
|
+
this.elementRef.nativeElement.style.paddingTop = '0px';
|
|
80
|
+
scrollEl.append(this.divVirtual);
|
|
81
|
+
this.divVirtualInitialized = true;
|
|
82
|
+
this.outDivVirtual.emit(this.divVirtual);
|
|
83
|
+
}
|
|
84
|
+
// Height tổng thể đổi theo dataset → cần update mỗi lượt.
|
|
62
85
|
this.divVirtual.style.height = `${height}px`;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.
|
|
67
|
-
this.elementRef.nativeElement.style.paddingTop = '0px';
|
|
68
|
-
scrollEl.append(this.divVirtual);
|
|
69
|
-
this.outDivVirtual.emit(this.divVirtual);
|
|
86
|
+
// containerHeight lúc đầu có thể = 0 (DOM chưa layout), khiến end giữ
|
|
87
|
+
// nguyên 0 và chỉ render bufferAhead item đầu. Re-đo bằng handlerScroll sau khi vòng
|
|
88
|
+
// lặp await xong (layout thường đã hoàn tất) để end ra đúng giá trị.
|
|
89
|
+
this.handlerScroll();
|
|
70
90
|
});
|
|
71
91
|
});
|
|
72
92
|
this.destroyRef.onDestroy(() => {
|
|
93
|
+
clearTimeout(this.timerAfterViewInit);
|
|
73
94
|
this.divVirtual.remove();
|
|
95
|
+
this.resizeObserver?.disconnect();
|
|
74
96
|
});
|
|
75
97
|
}
|
|
76
98
|
ngAfterViewInit() {
|
|
77
|
-
setTimeout(() => {
|
|
99
|
+
this.timerAfterViewInit = setTimeout(() => {
|
|
78
100
|
fromEvent(this.ScrollContainer, 'scroll')
|
|
79
101
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
80
102
|
.subscribe(() => this.handlerScroll());
|
|
81
103
|
this.outFunctionControl.emit(this.FunctionsControl);
|
|
104
|
+
// Re-tính viewport sau khi container có kích thước thật.
|
|
105
|
+
// Lần đầu render, getBoundingClientRect().height có thể = 0 nên end giữ giá trị 0,
|
|
106
|
+
// chỉ hiển thị bufferAhead item đầu. ResizeObserver fire ngay khi observe và mỗi lần
|
|
107
|
+
// container đổi size sẽ kéo end về đúng giá trị.
|
|
108
|
+
this.resizeObserver = new ResizeObserver(() => this.handlerScroll());
|
|
109
|
+
this.resizeObserver.observe(this.ScrollContainer);
|
|
82
110
|
});
|
|
83
111
|
}
|
|
84
112
|
// #region PUBLIC API
|
|
@@ -138,18 +166,17 @@ export class LibsUiScrollMeasureItemDirectionVerticalDirective {
|
|
|
138
166
|
// Utilize Binary Search for optimal O(log N) discovery
|
|
139
167
|
const start = this.findStartIndex(store, scrollTop);
|
|
140
168
|
const end = this.findEndIndex(store, scrollTop + containerHeight);
|
|
141
|
-
this.end
|
|
169
|
+
if (end !== this.end()) {
|
|
170
|
+
this.end.set(end);
|
|
171
|
+
}
|
|
142
172
|
if (start !== this.start()) {
|
|
143
173
|
this.start.set(start);
|
|
144
|
-
//
|
|
145
|
-
const paddingTop = store[start]
|
|
174
|
+
// Binary search guarantees `start` là index hợp lệ trong store.
|
|
175
|
+
const paddingTop = store[start].start;
|
|
146
176
|
this.elementRef.nativeElement.style.paddingTop = `${paddingTop}px`;
|
|
147
177
|
this.outPaddingTop.emit(paddingTop);
|
|
148
178
|
}
|
|
149
|
-
|
|
150
|
-
this.start.set(0);
|
|
151
|
-
}
|
|
152
|
-
this.viewPortItems.set(store.slice(this.start(), this.end() + 3).map((item) => item.ref));
|
|
179
|
+
this.viewPortItems.set(store.slice(this.start(), this.end() + this.bufferAhead).map((item) => item.ref));
|
|
153
180
|
this.outViewPortItem.emit(this.viewPortItems());
|
|
154
181
|
}
|
|
155
182
|
async scrollInto(itemScroll) {
|
|
@@ -170,10 +197,14 @@ export class LibsUiScrollMeasureItemDirectionVerticalDirective {
|
|
|
170
197
|
this.ScrollContainer.scrollTop = itemOfIndex.start;
|
|
171
198
|
}
|
|
172
199
|
async reCalculatorViewPort() {
|
|
173
|
-
let height = 0;
|
|
174
200
|
const items = this.storeItems();
|
|
175
|
-
|
|
176
|
-
|
|
201
|
+
const fn = this.functionGetHeightItem();
|
|
202
|
+
// Đo song song để rút ngắn thời gian thay vì await tuần tự.
|
|
203
|
+
const heights = await Promise.all(items.map((it) => fn(it.ref)));
|
|
204
|
+
let height = 0;
|
|
205
|
+
for (let i = 0; i < items.length; i++) {
|
|
206
|
+
const item = items[i];
|
|
207
|
+
const itemHeight = heights[i];
|
|
177
208
|
item.itemHeight = itemHeight;
|
|
178
209
|
item.start = height;
|
|
179
210
|
height += itemHeight;
|
|
@@ -194,4 +225,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
194
225
|
standalone: true,
|
|
195
226
|
}]
|
|
196
227
|
}], ctorParameters: () => [] });
|
|
197
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0aW9uLXZlcnRpY2FsLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9zY3JvbGwtbWVhc3VyZS1pdGVtcy9kaXJlY3Rpb24tdmVydGljYWwvc3JjL2RpcmVjdGlvbi12ZXJ0aWNhbC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseUZBQXlGO0FBQ3pGLHVEQUF1RDtBQUN2RCxPQUFPLEVBQWlCLFVBQVUsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25JLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQVFqQyxNQUFNLE9BQU8saURBQWlEO0lBQzVELG1CQUFtQjtJQUNYLGFBQWEsR0FBRyxNQUFNLENBQWEsRUFBRSxDQUFDLENBQUM7SUFDdkMsS0FBSyxHQUFHLE1BQU0sQ0FBUyxDQUFDLENBQUMsQ0FBQztJQUMxQixHQUFHLEdBQUcsTUFBTSxDQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLFVBQVUsR0FBRyxNQUFNLENBQWdELEVBQUUsQ0FBQyxDQUFDO0lBQ3ZFLFVBQVUsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRW5ELGdCQUFnQjtJQUNQLGFBQWEsR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFlLENBQUM7SUFDOUMscUJBQXFCLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBa0MsQ0FBQztJQUN6RSxLQUFLLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBYyxDQUFDO0lBRTlDLGlCQUFpQjtJQUNSLGVBQWUsR0FBRyxNQUFNLEVBQWMsQ0FBQztJQUN2QyxrQkFBa0IsR0FBRyxNQUFNLEVBQXVELENBQUM7SUFDbkYsYUFBYSxHQUFHLE1BQU0sRUFBa0IsQ0FBQztJQUN6QyxhQUFhLEdBQUcsTUFBTSxFQUFVLENBQUM7SUFFMUMsaUJBQWlCO0lBQ0EsVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNoQyxVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRWpEO1FBQ0UsTUFBTSxDQUFDLEdBQUcsRUFBRTtZQUNWLE1BQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDdkQsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQ2hFLE9BQU87WUFDVCxDQUFDO1lBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzNCLFNBQVMsQ0FBQyxLQUFLLElBQUksRUFBRTtnQkFDbkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xCLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUM7Z0JBQ3JDLE1BQU0sZUFBZSxHQUFHLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLE1BQU0sQ0FBQztnQkFDaEUsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO2dCQUNmLE1BQU0sUUFBUSxHQUFrRCxFQUFFLENBQUM7Z0JBRW5FLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7b0JBQ3RDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDdEIsTUFBTSxPQUFPLEdBQTJDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDO29CQUN2RyxNQUFNLFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUM1RCxPQUFPLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztvQkFDaEMsT0FBTyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUM7b0JBQ3ZCLE1BQU0sSUFBSSxVQUFVLENBQUM7b0JBQ3JCLE9BQU8sQ0FBQyxHQUFHLEdBQUcsTUFBTSxDQUFDO29CQUNyQixJQUFJLE9BQU8sQ0FBQyxHQUFHLElBQUksZUFBZSxHQUFHLFNBQVMsRUFBRSxDQUFDO3dCQUMvQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDbEIsQ0FBQztvQkFDRCxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUN6QixDQUFDO2dCQUVELElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUM5QixJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FDcEIsSUFBSSxDQUFDLFVBQVUsRUFBRTtxQkFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7cUJBQ25DLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUMzQixDQUFDO2dCQUNGLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO2dCQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUFFLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFOUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQztnQkFDNUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQztnQkFDbEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQztnQkFDbkMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUM7Z0JBQzdDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxRQUFRLENBQUMsQ0FBQyxpQ0FBaUM7Z0JBQzlFLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ3hELElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3pELElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO2dCQUN2RCxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDakMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzNDLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDN0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxlQUFlO1FBQ2IsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNkLFNBQVMsQ0FBUSxJQUFJLENBQUMsZUFBZSxFQUFFLFFBQVEsQ0FBQztpQkFDN0MsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztpQkFDekMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO1lBQ3pDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDdEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQscUJBQXFCO0lBQ3JCLElBQVcsZ0JBQWdCO1FBQ3pCLE9BQU87WUFDTCxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ3RDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ2xELGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDNUMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDMUQsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRTtTQUM3QyxDQUFDO0lBQ0osQ0FBQztJQUVELDBCQUEwQjtJQUMxQixJQUFZLGVBQWU7UUFDekIsT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUM7SUFDL0QsQ0FBQztJQUVPLGNBQWMsQ0FBQyxLQUFvRCxFQUFFLFNBQWlCO1FBQzVGLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNaLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQzVCLElBQUksR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsb0VBQW9FO1FBQ2hHLE9BQU8sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ25CLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDekMsSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNoQyxHQUFHLEdBQUcsR0FBRyxDQUFDO2dCQUNWLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsc0JBQXNCO1lBQ3hDLENBQUM7aUJBQU0sQ0FBQztnQkFDTixHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztZQUNoQixDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVPLFlBQVksQ0FBQyxLQUFvRCxFQUFFLFlBQW9CO1FBQzdGLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNaLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQzVCLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLHVEQUF1RDtRQUNwRSxPQUFPLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNuQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssSUFBSSxZQUFZLEVBQUUsQ0FBQztnQkFDckMsR0FBRyxHQUFHLEdBQUcsQ0FBQztnQkFDVixHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLG9CQUFvQjtZQUNyQyxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7WUFDakIsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFFTyxhQUFhO1FBQ25CLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxDQUFDO1lBQ25CLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQztRQUN0QyxNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDO1FBQ3JDLE1BQU0sZUFBZSxHQUFHLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLE1BQU0sQ0FBQztRQUVoRSx1REFBdUQ7UUFDdkQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDcEQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsU0FBUyxHQUFHLGVBQWUsQ0FBQyxDQUFDO1FBRWxFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRWxCLElBQUksS0FBSyxLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RCLCtGQUErRjtZQUMvRixNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsVUFBVSxHQUFHLEdBQUcsVUFBVSxJQUFJLENBQUM7WUFDbkUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BCLENBQUM7UUFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMxRixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRU8sS0FBSyxDQUFDLFVBQVUsQ0FBQyxVQUFlO1FBQ3RDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEtBQUssVUFBVSxDQUFDLENBQUM7UUFDNUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2YsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDO0lBQ25ELENBQUM7SUFFTyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsUUFBZ0I7UUFDN0MsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDO0lBQzVDLENBQUM7SUFFTyxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQWE7UUFDdkMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqQixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUM7SUFDckQsQ0FBQztJQUVPLEtBQUssQ0FBQyxvQkFBb0I7UUFDaEMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2YsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBRWhDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7WUFDekIsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDaEUsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7WUFDN0IsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUM7WUFDcEIsTUFBTSxJQUFJLFVBQVUsQ0FBQztZQUNyQixJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQztRQUNwQixDQUFDO1FBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUM7UUFDN0MsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7d0dBek1VLGlEQUFpRDs0RkFBakQsaURBQWlEOzs0RkFBakQsaURBQWlEO2tCQUw3RCxTQUFTO21CQUFDO29CQUNULDhEQUE4RDtvQkFDOUQsUUFBUSxFQUFFLHFEQUFxRDtvQkFDL0QsVUFBVSxFQUFFLElBQUk7aUJBQ2pCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ09OVkVOVElPTi1FWENFUFQ6IGFueSDigJQgR2VuZXJpYyBkaXJlY3RpdmUgd29ya3Mgd2l0aCB1bmtub3duIGl0ZW0gdHlwZXMgZnJvbSBjb25zdW1lclxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqL1xuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgRGVzdHJveVJlZiwgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBlZmZlY3QsIGluamVjdCwgaW5wdXQsIG91dHB1dCwgc2lnbmFsLCB1bnRyYWNrZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IGdldCB9IGZyb20gJ0BsaWJzLXVpL3V0aWxzJztcbmltcG9ydCB7IGZyb21FdmVudCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSVNjcm9sbE1lYXN1cmVJdGVtRGlyZWN0aW9uVmVydGljYWxGdW5jdGlvbnNDb250cm9sLCBJU2Nyb2xsTWVhc3VyZVN0b3JlSXRlbVZlcnRpY2FsQ29udmVydCB9IGZyb20gJy4vaW50ZXJmYWNlcy9kaXJlY3Rpb24tdmVydGljYWwuaW50ZXJmYWNlJztcblxuQERpcmVjdGl2ZSh7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvZGlyZWN0aXZlLXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnW0xpYnNVaVNjcm9sbE1lYXN1cmVJdGVtRGlyZWN0aW9uVmVydGljYWxEaXJlY3RpdmVdJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgTGlic1VpU2Nyb2xsTWVhc3VyZUl0ZW1EaXJlY3Rpb25WZXJ0aWNhbERpcmVjdGl2ZSBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xuICAvLyAjcmVnaW9uIFBST1BFUlRZXG4gIHByaXZhdGUgdmlld1BvcnRJdGVtcyA9IHNpZ25hbDxBcnJheTxhbnk+PihbXSk7XG4gIHByaXZhdGUgc3RhcnQgPSBzaWduYWw8bnVtYmVyPigwKTtcbiAgcHJpdmF0ZSBlbmQgPSBzaWduYWw8bnVtYmVyPigwKTtcbiAgcHJpdmF0ZSBzdG9yZUl0ZW1zID0gc2lnbmFsPEFycmF5PElTY3JvbGxNZWFzdXJlU3RvcmVJdGVtVmVydGljYWxDb252ZXJ0Pj4oW10pO1xuICBwcml2YXRlIGRpdlZpcnR1YWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblxuICAvLyAjcmVnaW9uIElOUFVUXG4gIHJlYWRvbmx5IGVsZW1lbnRTY3JvbGwgPSBpbnB1dC5yZXF1aXJlZDxIVE1MRWxlbWVudD4oKTtcbiAgcmVhZG9ubHkgZnVuY3Rpb25HZXRIZWlnaHRJdGVtID0gaW5wdXQucmVxdWlyZWQ8KGl0ZW06IGFueSkgPT4gUHJvbWlzZTxudW1iZXI+PigpO1xuICByZWFkb25seSBpdGVtcyA9IGlucHV0LnJlcXVpcmVkPEFycmF5PGFueT4+KCk7XG5cbiAgLy8gI3JlZ2lvbiBPVVRQVVRcbiAgcmVhZG9ubHkgb3V0Vmlld1BvcnRJdGVtID0gb3V0cHV0PEFycmF5PGFueT4+KCk7XG4gIHJlYWRvbmx5IG91dEZ1bmN0aW9uQ29udHJvbCA9IG91dHB1dDxJU2Nyb2xsTWVhc3VyZUl0ZW1EaXJlY3Rpb25WZXJ0aWNhbEZ1bmN0aW9uc0NvbnRyb2w+KCk7XG4gIHJlYWRvbmx5IG91dERpdlZpcnR1YWwgPSBvdXRwdXQ8SFRNTERpdkVsZW1lbnQ+KCk7XG4gIHJlYWRvbmx5IG91dFBhZGRpbmdUb3AgPSBvdXRwdXQ8bnVtYmVyPigpO1xuXG4gIC8vICNyZWdpb24gSU5KRUNUXG4gIHByaXZhdGUgcmVhZG9ubHkgZWxlbWVudFJlZiA9IGluamVjdChFbGVtZW50UmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICBjb25zdCBzY3JvbGxFbCA9IHVudHJhY2tlZCgoKSA9PiB0aGlzLlNjcm9sbENvbnRhaW5lcik7XG4gICAgICBpZiAoIXNjcm9sbEVsIHx8ICF1bnRyYWNrZWQoKCkgPT4gdGhpcy5mdW5jdGlvbkdldEhlaWdodEl0ZW0oKSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgaXRlbXMgPSB0aGlzLml0ZW1zKCk7XG4gICAgICB1bnRyYWNrZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICB0aGlzLnN0YXJ0LnNldCgwKTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsVG9wID0gc2Nyb2xsRWwuc2Nyb2xsVG9wO1xuICAgICAgICBjb25zdCBjb250YWluZXJIZWlnaHQgPSBzY3JvbGxFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQ7XG4gICAgICAgIGxldCBoZWlnaHQgPSAwO1xuICAgICAgICBjb25zdCBuZXdJdGVtczogQXJyYXk8SVNjcm9sbE1lYXN1cmVTdG9yZUl0ZW1WZXJ0aWNhbENvbnZlcnQ+ID0gW107XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtc1tpXTtcbiAgICAgICAgICBjb25zdCBuZXdJdGVtOiBJU2Nyb2xsTWVhc3VyZVN0b3JlSXRlbVZlcnRpY2FsQ29udmVydCA9IHsgcmVmOiBpdGVtLCBpdGVtSGVpZ2h0OiAwLCBzdGFydDogMCwgZW5kOiAwIH07XG4gICAgICAgICAgY29uc3QgaXRlbUhlaWdodCA9IGF3YWl0IHRoaXMuZnVuY3Rpb25HZXRIZWlnaHRJdGVtKCkoaXRlbSk7XG4gICAgICAgICAgbmV3SXRlbS5pdGVtSGVpZ2h0ID0gaXRlbUhlaWdodDtcbiAgICAgICAgICBuZXdJdGVtLnN0YXJ0ID0gaGVpZ2h0O1xuICAgICAgICAgIGhlaWdodCArPSBpdGVtSGVpZ2h0O1xuICAgICAgICAgIG5ld0l0ZW0uZW5kID0gaGVpZ2h0O1xuICAgICAgICAgIGlmIChuZXdJdGVtLmVuZCA8PSBjb250YWluZXJIZWlnaHQgKyBzY3JvbGxUb3ApIHtcbiAgICAgICAgICAgIHRoaXMuZW5kLnNldChpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbmV3SXRlbXMucHVzaChuZXdJdGVtKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RvcmVJdGVtcy5zZXQobmV3SXRlbXMpO1xuICAgICAgICB0aGlzLnZpZXdQb3J0SXRlbXMuc2V0KFxuICAgICAgICAgIHRoaXMuc3RvcmVJdGVtcygpXG4gICAgICAgICAgICAuc2xpY2UodGhpcy5zdGFydCgpLCB0aGlzLmVuZCgpICsgMylcbiAgICAgICAgICAgIC5tYXAoKGl0ZW0pID0+IGl0ZW0ucmVmKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLm91dFZpZXdQb3J0SXRlbS5lbWl0KHRoaXMudmlld1BvcnRJdGVtcygpKTtcbiAgICAgICAgdGhpcy5vdXRQYWRkaW5nVG9wLmVtaXQoZ2V0KHRoaXMuc3RvcmVJdGVtcygpLCBgWyR7dGhpcy5zdGFydCgpfV0uc3RhcnRgLCAwKSk7XG5cbiAgICAgICAgdGhpcy5kaXZWaXJ0dWFsLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgICAgdGhpcy5kaXZWaXJ0dWFsLnN0eWxlLnRvcCA9ICcwcHgnO1xuICAgICAgICB0aGlzLmRpdlZpcnR1YWwuc3R5bGUubGVmdCA9ICcwcHgnO1xuICAgICAgICB0aGlzLmRpdlZpcnR1YWwuc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YDtcbiAgICAgICAgdGhpcy5kaXZWaXJ0dWFsLnN0eWxlLndpZHRoID0gJzFweCc7XG4gICAgICAgIHRoaXMuZGl2VmlydHVhbC5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7IC8vIMSQ4bqjbSBi4bqjbyBhbiB0b8OgbiBraMO0bmcgaGnhu4NuIHRo4buLXG4gICAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3JlbGF0aXZlJyk7XG4gICAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2gtZnVsbCcpO1xuICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zdHlsZS5wYWRkaW5nVG9wID0gJzBweCc7XG4gICAgICAgIHNjcm9sbEVsLmFwcGVuZCh0aGlzLmRpdlZpcnR1YWwpO1xuICAgICAgICB0aGlzLm91dERpdlZpcnR1YWwuZW1pdCh0aGlzLmRpdlZpcnR1YWwpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmRlc3Ryb3lSZWYub25EZXN0cm95KCgpID0+IHtcbiAgICAgIHRoaXMuZGl2VmlydHVhbC5yZW1vdmUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGZyb21FdmVudDxFdmVudD4odGhpcy5TY3JvbGxDb250YWluZXIsICdzY3JvbGwnKVxuICAgICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLmhhbmRsZXJTY3JvbGwoKSk7XG4gICAgICB0aGlzLm91dEZ1bmN0aW9uQ29udHJvbC5lbWl0KHRoaXMuRnVuY3Rpb25zQ29udHJvbCk7XG4gICAgfSk7XG4gIH1cblxuICAvLyAjcmVnaW9uIFBVQkxJQyBBUElcbiAgcHVibGljIGdldCBGdW5jdGlvbnNDb250cm9sKCk6IElTY3JvbGxNZWFzdXJlSXRlbURpcmVjdGlvblZlcnRpY2FsRnVuY3Rpb25zQ29udHJvbCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNjcm9sbEludG86IHRoaXMuc2Nyb2xsSW50by5iaW5kKHRoaXMpLFxuICAgICAgc2Nyb2xsVG9Qb3NpdGlvbjogdGhpcy5zY3JvbGxUb1Bvc2l0aW9uLmJpbmQodGhpcyksXG4gICAgICBzY3JvbGxUb0luZGV4OiB0aGlzLnNjcm9sbFRvSW5kZXguYmluZCh0aGlzKSxcbiAgICAgIHJlQ2FsY3VsYXRvclZpZXdQb3J0OiB0aGlzLnJlQ2FsY3VsYXRvclZpZXdQb3J0LmJpbmQodGhpcyksXG4gICAgICBnZXRWaWV3UG9ydEl0ZW1zOiAoKSA9PiB0aGlzLnZpZXdQb3J0SXRlbXMoKSxcbiAgICB9O1xuICB9XG5cbiAgLy8gI3JlZ2lvbiBQUklWQVRFIE1FVEhPRFNcbiAgcHJpdmF0ZSBnZXQgU2Nyb2xsQ29udGFpbmVyKCk6IEhUTUxFbGVtZW50IHtcbiAgICByZXR1cm4gdGhpcy5lbGVtZW50U2Nyb2xsKCkgfHwgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gIH1cblxuICBwcml2YXRlIGZpbmRTdGFydEluZGV4KHN0b3JlOiBBcnJheTxJU2Nyb2xsTWVhc3VyZVN0b3JlSXRlbVZlcnRpY2FsQ29udmVydD4sIHNjcm9sbFRvcDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgbG93ID0gMDtcbiAgICBsZXQgaGlnaCA9IHN0b3JlLmxlbmd0aCAtIDE7XG4gICAgbGV0IGFucyA9IHN0b3JlLmxlbmd0aCAtIDE7IC8vIERlZmF1bHQgdG8gbGFzdCBpdGVtIGlmIHNjcm9sbGVkIHBhc3QgYm90dG9tIChydWJiZXIgYmFuZCBlZmZlY3QpXG4gICAgd2hpbGUgKGxvdyA8PSBoaWdoKSB7XG4gICAgICBjb25zdCBtaWQgPSBNYXRoLmZsb29yKChsb3cgKyBoaWdoKSAvIDIpO1xuICAgICAgaWYgKHN0b3JlW21pZF0uZW5kID49IHNjcm9sbFRvcCkge1xuICAgICAgICBhbnMgPSBtaWQ7XG4gICAgICAgIGhpZ2ggPSBtaWQgLSAxOyAvLyBUcnkgdG8gZmluZCBlYXJsaWVyXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYW5zO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kRW5kSW5kZXgoc3RvcmU6IEFycmF5PElTY3JvbGxNZWFzdXJlU3RvcmVJdGVtVmVydGljYWxDb252ZXJ0Piwgc2Nyb2xsQm90dG9tOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBsb3cgPSAwO1xuICAgIGxldCBoaWdoID0gc3RvcmUubGVuZ3RoIC0gMTtcbiAgICBsZXQgYW5zID0gMDsgLy8gRGVmYXVsdCB0byBmaXJzdCBpdGVtIGlmIHJ1YmJlci1iYW5kZWQgYWJvdmUgdGhlIHRvcFxuICAgIHdoaWxlIChsb3cgPD0gaGlnaCkge1xuICAgICAgY29uc3QgbWlkID0gTWF0aC5mbG9vcigobG93ICsgaGlnaCkgLyAyKTtcbiAgICAgIGlmIChzdG9yZVttaWRdLnN0YXJ0IDw9IHNjcm9sbEJvdHRvbSkge1xuICAgICAgICBhbnMgPSBtaWQ7XG4gICAgICAgIGxvdyA9IG1pZCArIDE7IC8vIFRyeSB0byBmaW5kIGxhdGVyXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdoID0gbWlkIC0gMTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFucztcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlclNjcm9sbCgpIHtcbiAgICBjb25zdCBzdG9yZSA9IHRoaXMuc3RvcmVJdGVtcygpO1xuICAgIGlmICghc3RvcmU/Lmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzY3JvbGxFbCA9IHRoaXMuU2Nyb2xsQ29udGFpbmVyO1xuICAgIGNvbnN0IHNjcm9sbFRvcCA9IHNjcm9sbEVsLnNjcm9sbFRvcDtcbiAgICBjb25zdCBjb250YWluZXJIZWlnaHQgPSBzY3JvbGxFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQ7XG4gICAgXG4gICAgLy8gVXRpbGl6ZSBCaW5hcnkgU2VhcmNoIGZvciBvcHRpbWFsIE8obG9nIE4pIGRpc2NvdmVyeVxuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5maW5kU3RhcnRJbmRleChzdG9yZSwgc2Nyb2xsVG9wKTtcbiAgICBjb25zdCBlbmQgPSB0aGlzLmZpbmRFbmRJbmRleChzdG9yZSwgc2Nyb2xsVG9wICsgY29udGFpbmVySGVpZ2h0KTtcblxuICAgIHRoaXMuZW5kLnNldChlbmQpO1xuXG4gICAgaWYgKHN0YXJ0ICE9PSB0aGlzLnN0YXJ0KCkpIHtcbiAgICAgIHRoaXMuc3RhcnQuc2V0KHN0YXJ0KTtcbiAgICAgIC8vIFVzZSBsb2dpY2FsIE9SIGZvciBmYWxsYmFjayB3aGVuIHN0YXJ0IGlzIGludmFsaWQuIEJ1dCBiaW5hcnkgc2VhcmNoIGd1YXJhbnRlZXMgdmFsaWQgaW5kZXguXG4gICAgICBjb25zdCBwYWRkaW5nVG9wID0gc3RvcmVbc3RhcnRdPy5zdGFydCB8fCAwO1xuICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuc3R5bGUucGFkZGluZ1RvcCA9IGAke3BhZGRpbmdUb3B9cHhgO1xuICAgICAgdGhpcy5vdXRQYWRkaW5nVG9wLmVtaXQocGFkZGluZ1RvcCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhcnQoKSA8IDApIHtcbiAgICAgIHRoaXMuc3RhcnQuc2V0KDApO1xuICAgIH1cbiAgICB0aGlzLnZpZXdQb3J0SXRlbXMuc2V0KHN0b3JlLnNsaWNlKHRoaXMuc3RhcnQoKSwgdGhpcy5lbmQoKSArIDMpLm1hcCgoaXRlbSkgPT4gaXRlbS5yZWYpKTtcbiAgICB0aGlzLm91dFZpZXdQb3J0SXRlbS5lbWl0KHRoaXMudmlld1BvcnRJdGVtcygpKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2Nyb2xsSW50byhpdGVtU2Nyb2xsOiBhbnkpIHtcbiAgICBjb25zdCBpdGVtRm91bmQgPSB0aGlzLnN0b3JlSXRlbXMoKS5maW5kKChpdGVtKSA9PiBpdGVtLnJlZiA9PT0gaXRlbVNjcm9sbCk7XG4gICAgaWYgKCFpdGVtRm91bmQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5TY3JvbGxDb250YWluZXIuc2Nyb2xsVG9wID0gaXRlbUZvdW5kLnN0YXJ0O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzY3JvbGxUb1Bvc2l0aW9uKHBvc2l0aW9uOiBudW1iZXIpIHtcbiAgICB0aGlzLlNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBwb3NpdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2Nyb2xsVG9JbmRleChpbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3QgaXRlbU9mSW5kZXggPSB0aGlzLnN0b3JlSXRlbXMoKVtpbmRleF07XG4gICAgaWYgKCFpdGVtT2ZJbmRleCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLlNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBpdGVtT2ZJbmRleC5zdGFydDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVDYWxjdWxhdG9yVmlld1BvcnQoKSB7XG4gICAgbGV0IGhlaWdodCA9IDA7XG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLnN0b3JlSXRlbXMoKTtcblxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgY29uc3QgaXRlbUhlaWdodCA9IGF3YWl0IHRoaXMuZnVuY3Rpb25HZXRIZWlnaHRJdGVtKCkoaXRlbS5yZWYpO1xuICAgICAgaXRlbS5pdGVtSGVpZ2h0ID0gaXRlbUhlaWdodDtcbiAgICAgIGl0ZW0uc3RhcnQgPSBoZWlnaHQ7XG4gICAgICBoZWlnaHQgKz0gaXRlbUhlaWdodDtcbiAgICAgIGl0ZW0uZW5kID0gaGVpZ2h0O1xuICAgIH1cblxuICAgIHRoaXMuc3RvcmVJdGVtcy5zZXQoWy4uLml0ZW1zXSk7XG4gICAgdGhpcy5kaXZWaXJ0dWFsLnN0eWxlLmhlaWdodCA9IGAke2hlaWdodH1weGA7XG4gICAgdGhpcy5oYW5kbGVyU2Nyb2xsKCk7XG4gIH1cbn1cbiJdfQ==
|
|
228
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0aW9uLXZlcnRpY2FsLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9zY3JvbGwtbWVhc3VyZS1pdGVtcy9kaXJlY3Rpb24tdmVydGljYWwvc3JjL2RpcmVjdGlvbi12ZXJ0aWNhbC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseUZBQXlGO0FBQ3pGLHVEQUF1RDtBQUN2RCxPQUFPLEVBQWlCLFVBQVUsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25JLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7O0FBUWpDLE1BQU0sT0FBTyxpREFBaUQ7SUFDNUQsbUJBQW1CO0lBQ25CLDhFQUE4RTtJQUM3RCxXQUFXLEdBQUcsQ0FBQyxDQUFDO0lBRXpCLGFBQWEsR0FBRyxNQUFNLENBQWEsRUFBRSxDQUFDLENBQUM7SUFDdkMsS0FBSyxHQUFHLE1BQU0sQ0FBUyxDQUFDLENBQUMsQ0FBQztJQUMxQixHQUFHLEdBQUcsTUFBTSxDQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLFVBQVUsR0FBRyxNQUFNLENBQWdELEVBQUUsQ0FBQyxDQUFDO0lBQ3ZFLFVBQVUsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLGNBQWMsQ0FBa0I7SUFDeEMsbUdBQW1HO0lBQzNGLGtCQUFrQixDQUFVO0lBQ3BDLGtHQUFrRztJQUMxRixjQUFjLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLDBGQUEwRjtJQUNsRixxQkFBcUIsR0FBRyxLQUFLLENBQUM7SUFFdEMsZ0JBQWdCO0lBQ1AsYUFBYSxHQUFH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LEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQztRQUM3QyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDdkIsQ0FBQzt3R0ExT1UsaURBQWlEOzRGQUFqRCxpREFBaUQ7OzRGQUFqRCxpREFBaUQ7a0JBTDdELFNBQVM7bUJBQUM7b0JBQ1QsOERBQThEO29CQUM5RCxRQUFRLEVBQUUscURBQXFEO29CQUMvRCxVQUFVLEVBQUUsSUFBSTtpQkFDakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDT05WRU5USU9OLUVYQ0VQVDogYW55IOKAlCBHZW5lcmljIGRpcmVjdGl2ZSB3b3JrcyB3aXRoIHVua25vd24gaXRlbSB0eXBlcyBmcm9tIGNvbnN1bWVyXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55ICovXG5pbXBvcnQgeyBBZnRlclZpZXdJbml0LCBEZXN0cm95UmVmLCBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIGVmZmVjdCwgaW5qZWN0LCBpbnB1dCwgb3V0cHV0LCBzaWduYWwsIHVudHJhY2tlZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgZnJvbUV2ZW50IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBJU2Nyb2xsTWVhc3VyZUl0ZW1EaXJlY3Rpb25WZXJ0aWNhbEZ1bmN0aW9uc0NvbnRyb2wsIElTY3JvbGxNZWFzdXJlU3RvcmVJdGVtVmVydGljYWxDb252ZXJ0IH0gZnJvbSAnLi9pbnRlcmZhY2VzL2RpcmVjdGlvbi12ZXJ0aWNhbC5pbnRlcmZhY2UnO1xuXG5ARGlyZWN0aXZlKHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9kaXJlY3RpdmUtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdbTGlic1VpU2Nyb2xsTWVhc3VyZUl0ZW1EaXJlY3Rpb25WZXJ0aWNhbERpcmVjdGl2ZV0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlTY3JvbGxNZWFzdXJlSXRlbURpcmVjdGlvblZlcnRpY2FsRGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCB7XG4gIC8vICNyZWdpb24gUFJPUEVSVFlcbiAgLyoqIFPhu5EgaXRlbSBidWZmZXIgcmVuZGVyIHRow6ptIHNhdSB2aWV3cG9ydCDEkeG7gyB0csOhbmggdHLhuq9uZyB2w7luZyBraGkgc2Nyb2xsLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGJ1ZmZlckFoZWFkID0gMztcblxuICBwcml2YXRlIHZpZXdQb3J0SXRlbXMgPSBzaWduYWw8QXJyYXk8YW55Pj4oW10pO1xuICBwcml2YXRlIHN0YXJ0ID0gc2lnbmFsPG51bWJlcj4oMCk7XG4gIHByaXZhdGUgZW5kID0gc2lnbmFsPG51bWJlcj4oMCk7XG4gIHByaXZhdGUgc3RvcmVJdGVtcyA9IHNpZ25hbDxBcnJheTxJU2Nyb2xsTWVhc3VyZVN0b3JlSXRlbVZlcnRpY2FsQ29udmVydD4+KFtdKTtcbiAgcHJpdmF0ZSBkaXZWaXJ0dWFsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIHByaXZhdGUgcmVzaXplT2JzZXJ2ZXI/OiBSZXNpemVPYnNlcnZlcjtcbiAgLyoqIFRoYW0gY2hp4bq/dSBzZXRUaW1lb3V0IGPhu6dhIG5nQWZ0ZXJWaWV3SW5pdCDEkeG7gyBjbGVhciBraGkgZGVzdHJveSDigJQgY2jhurduIFJlc2l6ZU9ic2VydmVyIG3hu5MgY8O0aS4gKi9cbiAgcHJpdmF0ZSB0aW1lckFmdGVyVmlld0luaXQ/OiBudW1iZXI7XG4gIC8qKiBUb2tlbiBuaOG6rW4gZOG6oW5nIGzhuqduIGVmZmVjdCBjaOG6oXkgaGnhu4duIHThuqFpLiBBc3luYyDEkW8gaGVpZ2h0IHhvbmcgc+G6vSBi4buPIGvhur90IHF14bqjIG7hur91IHRva2VuIMSR4buVaS4gKi9cbiAgcHJpdmF0ZSBleGVjdXRpb25Ub2tlbiA9IDA7XG4gIC8qKiBTdHlsZSArIERPTSBob29rIGPhu6dhIGRpdlZpcnR1YWwgY2jhu4kgY+G6p24ga2jhu59pIHThuqFvIG3hu5l0IGzhuqduIGNobyBj4bqjIHbDsm5nIMSR4budaSBkaXJlY3RpdmUuICovXG4gIHByaXZhdGUgZGl2VmlydHVhbEluaXRpYWxpemVkID0gZmFsc2U7XG5cbiAgLy8gI3JlZ2lvbiBJTlBVVFxuICByZWFkb25seSBlbGVtZW50U2Nyb2xsID0gaW5wdXQucmVxdWlyZWQ8SFRNTEVsZW1lbnQ+KCk7XG4gIHJlYWRvbmx5IGZ1bmN0aW9uR2V0SGVpZ2h0SXRlbSA9IGlucHV0LnJlcXVpcmVkPChpdGVtOiBhbnkpID0+IFByb21pc2U8bnVtYmVyPj4oKTtcbiAgcmVhZG9ubHkgaXRlbXMgPSBpbnB1dC5yZXF1aXJlZDxBcnJheTxhbnk+PigpO1xuXG4gIC8vICNyZWdpb24gT1VUUFVUXG4gIHJlYWRvbmx5IG91dFZpZXdQb3J0SXRlbSA9IG91dHB1dDxBcnJheTxhbnk+PigpO1xuICByZWFkb25seSBvdXRGdW5jdGlvbkNvbnRyb2wgPSBvdXRwdXQ8SVNjcm9sbE1lYXN1cmVJdGVtRGlyZWN0aW9uVmVydGljYWxGdW5jdGlvbnNDb250cm9sPigpO1xuICByZWFkb25seSBvdXREaXZWaXJ0dWFsID0gb3V0cHV0PEhUTUxEaXZFbGVtZW50PigpO1xuICByZWFkb25seSBvdXRQYWRkaW5nVG9wID0gb3V0cHV0PG51bWJlcj4oKTtcblxuICAvLyAjcmVnaW9uIElOSkVDVFxuICBwcml2YXRlIHJlYWRvbmx5IGVsZW1lbnRSZWYgPSBpbmplY3QoRWxlbWVudFJlZik7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgY29uc3QgaXRlbXMgPSB0aGlzLml0ZW1zKCk7XG4gICAgICBjb25zdCBteVRva2VuID0gKyt0aGlzLmV4ZWN1dGlvblRva2VuO1xuICAgICAgdW50cmFja2VkKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2Nyb2xsRWwgPSB0aGlzLlNjcm9sbENvbnRhaW5lcjtcbiAgICAgICAgY29uc3QgZnVuY3Rpb25HZXRIZWlnaHRJdGVtID0gdGhpcy5mdW5jdGlvbkdldEhlaWdodEl0ZW0oKTtcbiAgICAgICAgaWYgKCFzY3JvbGxFbCB8fCAhZnVuY3Rpb25HZXRIZWlnaHRJdGVtKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gxJBvIGhlaWdodCB04bqldCBj4bqjIGl0ZW0gc29uZyBzb25nIOKAlCByw7p0IG5n4bqvbiB0aOG7nWkgZ2lhbiBjaG8gbGlzdCBs4bubbi5cbiAgICAgICAgY29uc3QgaGVpZ2h0cyA9IGF3YWl0IFByb21pc2UuYWxsKGl0ZW1zLm1hcCgoaXQpID0+IGZ1bmN0aW9uR2V0SGVpZ2h0SXRlbShpdCkpKTtcbiAgICAgICAgLy8gQuG7iyBodeG7tyB2w6wgY8OzIGzGsOG7o3QgaXRlbXMoKSBt4bubaSBjaOG6oXkgc2F1IOKAlCBi4buPIGvhur90IHF14bqjIGPFqSB0csOhbmggxJHDqCBzdGF0ZS5cbiAgICAgICAgaWYgKG15VG9rZW4gIT09IHRoaXMuZXhlY3V0aW9uVG9rZW4pIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0YXJ0LnNldCgwKTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsVG9wID0gc2Nyb2xsRWwuc2Nyb2xsVG9wO1xuICAgICAgICBjb25zdCBjb250YWluZXJIZWlnaHQgPSBzY3JvbGxFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQ7XG4gICAgICAgIGxldCBoZWlnaHQgPSAwO1xuICAgICAgICBsZXQgZW5kTG9jYWwgPSAwO1xuICAgICAgICBjb25zdCBuZXdJdGVtczogQXJyYXk8SVNjcm9sbE1lYXN1cmVTdG9yZUl0ZW1WZXJ0aWNhbENvbnZlcnQ+ID0gW107XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGl0ZW1IZWlnaHQgPSBoZWlnaHRzW2ldO1xuICAgICAgICAgIGNvbnN0IG5ld0l0ZW06IElTY3JvbGxNZWFzdXJlU3RvcmVJdGVtVmVydGljYWxDb252ZXJ0ID0geyByZWY6IGl0ZW1zW2ldLCBpdGVtSGVpZ2h0LCBzdGFydDogaGVpZ2h0LCBlbmQ6IDAgfTtcbiAgICAgICAgICBoZWlnaHQgKz0gaXRlbUhlaWdodDtcbiAgICAgICAgICBuZXdJdGVtLmVuZCA9IGhlaWdodDtcbiAgICAgICAgICBpZiAobmV3SXRlbS5lbmQgPD0gY29udGFpbmVySGVpZ2h0ICsgc2Nyb2xsVG9wKSB7XG4gICAgICAgICAgICBlbmRMb2NhbCA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG5ld0l0ZW1zLnB1c2gobmV3SXRlbSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2V0IGVuZCBt4buZdCBs4bqnbiB0aGF5IHbDrCBnaGkgbeG7l2kgdsOybmcgbOG6t3Ag4oCUIHRyw6FuaCBub3RpZnkgY29uc3VtZXIgTiBs4bqnbi5cbiAgICAgICAgdGhpcy5lbmQuc2V0KGVuZExvY2FsKTtcbiAgICAgICAgdGhpcy5zdG9yZUl0ZW1zLnNldChuZXdJdGVtcyk7XG5cbiAgICAgICAgLy8gS2jhu59pIHThuqFvIHN0eWxlICsgRE9NIGhvb2sgY+G7p2EgZGl2VmlydHVhbCDEkcO6bmcgbeG7mXQgbOG6p24uXG4gICAgICAgIGlmICghdGhpcy5kaXZWaXJ0dWFsSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICB0aGlzLmRpdlZpcnR1YWwuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgICAgIHRoaXMuZGl2VmlydHVhbC5zdHlsZS50b3AgPSAnMHB4JztcbiAgICAgICAgICB0aGlzLmRpdlZpcnR1YWwuc3R5bGUubGVmdCA9ICcwcHgnO1xuICAgICAgICAgIHRoaXMuZGl2VmlydHVhbC5zdHlsZS53aWR0aCA9ICcxcHgnO1xuICAgICAgICAgIHRoaXMuZGl2VmlydHVhbC5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7IC8vIMSQ4bqjbSBi4bqjbyBhbiB0b8OgbiBraMO0bmcgaGnhu4NuIHRo4buLXG4gICAgICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgncmVsYXRpdmUnKTtcbiAgICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdoLWZ1bGwnKTtcbiAgICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zdHlsZS5wYWRkaW5nVG9wID0gJzBweCc7XG4gICAgICAgICAgc2Nyb2xsRWwuYXBwZW5kKHRoaXMuZGl2VmlydHVhbCk7XG4gICAgICAgICAgdGhpcy5kaXZWaXJ0dWFsSW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgICAgIHRoaXMub3V0RGl2VmlydHVhbC5lbWl0KHRoaXMuZGl2VmlydHVhbCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSGVpZ2h0IHThu5VuZyB0aOG7gyDEkeG7lWkgdGhlbyBkYXRhc2V0IOKGkiBj4bqnbiB1cGRhdGUgbeG7l2kgbMaw4bujdC5cbiAgICAgICAgdGhpcy5kaXZWaXJ0dWFsLnN0eWxlLmhlaWdodCA9IGAke2hlaWdodH1weGA7XG5cbiAgICAgICAgLy8gY29udGFpbmVySGVpZ2h0IGzDumMgxJHhuqd1IGPDsyB0aOG7gyA9IDAgKERPTSBjaMawYSBsYXlvdXQpLCBraGnhur9uIGVuZCBnaeG7r1xuICAgICAgICAvLyBuZ3V5w6puIDAgdsOgIGNo4buJIHJlbmRlciBidWZmZXJBaGVhZCBpdGVtIMSR4bqndS4gUmUtxJFvIGLhurFuZyBoYW5kbGVyU2Nyb2xsIHNhdSBraGkgdsOybmdcbiAgICAgICAgLy8gbOG6t3AgYXdhaXQgeG9uZyAobGF5b3V0IHRoxrDhu51uZyDEkcOjIGhvw6BuIHThuqV0KSDEkeG7gyBlbmQgcmEgxJHDum5nIGdpw6EgdHLhu4suXG4gICAgICAgIHRoaXMuaGFuZGxlclNjcm9sbCgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmRlc3Ryb3lSZWYub25EZXN0cm95KCgpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyQWZ0ZXJWaWV3SW5pdCk7XG4gICAgICB0aGlzLmRpdlZpcnR1YWwucmVtb3ZlKCk7XG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgfSk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy50aW1lckFmdGVyVmlld0luaXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGZyb21FdmVudDxFdmVudD4odGhpcy5TY3JvbGxDb250YWluZXIsICdzY3JvbGwnKVxuICAgICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLmhhbmRsZXJTY3JvbGwoKSk7XG4gICAgICB0aGlzLm91dEZ1bmN0aW9uQ29udHJvbC5lbWl0KHRoaXMuRnVuY3Rpb25zQ29udHJvbCk7XG5cbiAgICAgIC8vIFJlLXTDrW5oIHZpZXdwb3J0IHNhdSBraGkgY29udGFpbmVyIGPDsyBrw61jaCB0aMaw4bubYyB0aOG6rXQuXG4gICAgICAvLyBM4bqnbiDEkeG6p3UgcmVuZGVyLCBnZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQgY8OzIHRo4buDID0gMCBuw6puIGVuZCBnaeG7ryBnacOhIHRy4buLIDAsXG4gICAgICAvLyBjaOG7iSBoaeG7g24gdGjhu4sgYnVmZmVyQWhlYWQgaXRlbSDEkeG6p3UuIFJlc2l6ZU9ic2VydmVyIGZpcmUgbmdheSBraGkgb2JzZXJ2ZSB2w6AgbeG7l2kgbOG6p25cbiAgICAgIC8vIGNvbnRhaW5lciDEkeG7lWkgc2l6ZSBz4bq9IGvDqW8gZW5kIHbhu4EgxJHDum5nIGdpw6EgdHLhu4suXG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHRoaXMuaGFuZGxlclNjcm9sbCgpKTtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLlNjcm9sbENvbnRhaW5lcik7XG4gICAgfSk7XG4gIH1cblxuICAvLyAjcmVnaW9uIFBVQkxJQyBBUElcbiAgcHVibGljIGdldCBGdW5jdGlvbnNDb250cm9sKCk6IElTY3JvbGxNZWFzdXJlSXRlbURpcmVjdGlvblZlcnRpY2FsRnVuY3Rpb25zQ29udHJvbCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNjcm9sbEludG86IHRoaXMuc2Nyb2xsSW50by5iaW5kKHRoaXMpLFxuICAgICAgc2Nyb2xsVG9Qb3NpdGlvbjogdGhpcy5zY3JvbGxUb1Bvc2l0aW9uLmJpbmQodGhpcyksXG4gICAgICBzY3JvbGxUb0luZGV4OiB0aGlzLnNjcm9sbFRvSW5kZXguYmluZCh0aGlzKSxcbiAgICAgIHJlQ2FsY3VsYXRvclZpZXdQb3J0OiB0aGlzLnJlQ2FsY3VsYXRvclZpZXdQb3J0LmJpbmQodGhpcyksXG4gICAgICBnZXRWaWV3UG9ydEl0ZW1zOiAoKSA9PiB0aGlzLnZpZXdQb3J0SXRlbXMoKSxcbiAgICB9O1xuICB9XG5cbiAgLy8gI3JlZ2lvbiBQUklWQVRFIE1FVEhPRFNcbiAgcHJpdmF0ZSBnZXQgU2Nyb2xsQ29udGFpbmVyKCk6IEhUTUxFbGVtZW50IHtcbiAgICByZXR1cm4gdGhpcy5lbGVtZW50U2Nyb2xsKCkgfHwgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gIH1cblxuICBwcml2YXRlIGZpbmRTdGFydEluZGV4KHN0b3JlOiBBcnJheTxJU2Nyb2xsTWVhc3VyZVN0b3JlSXRlbVZlcnRpY2FsQ29udmVydD4sIHNjcm9sbFRvcDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgbG93ID0gMDtcbiAgICBsZXQgaGlnaCA9IHN0b3JlLmxlbmd0aCAtIDE7XG4gICAgbGV0IGFucyA9IHN0b3JlLmxlbmd0aCAtIDE7IC8vIERlZmF1bHQgdG8gbGFzdCBpdGVtIGlmIHNjcm9sbGVkIHBhc3QgYm90dG9tIChydWJiZXIgYmFuZCBlZmZlY3QpXG4gICAgd2hpbGUgKGxvdyA8PSBoaWdoKSB7XG4gICAgICBjb25zdCBtaWQgPSBNYXRoLmZsb29yKChsb3cgKyBoaWdoKSAvIDIpO1xuICAgICAgaWYgKHN0b3JlW21pZF0uZW5kID49IHNjcm9sbFRvcCkge1xuICAgICAgICBhbnMgPSBtaWQ7XG4gICAgICAgIGhpZ2ggPSBtaWQgLSAxOyAvLyBUcnkgdG8gZmluZCBlYXJsaWVyXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYW5zO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kRW5kSW5kZXgoc3RvcmU6IEFycmF5PElTY3JvbGxNZWFzdXJlU3RvcmVJdGVtVmVydGljYWxDb252ZXJ0Piwgc2Nyb2xsQm90dG9tOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBsb3cgPSAwO1xuICAgIGxldCBoaWdoID0gc3RvcmUubGVuZ3RoIC0gMTtcbiAgICBsZXQgYW5zID0gMDsgLy8gRGVmYXVsdCB0byBmaXJzdCBpdGVtIGlmIHJ1YmJlci1iYW5kZWQgYWJvdmUgdGhlIHRvcFxuICAgIHdoaWxlIChsb3cgPD0gaGlnaCkge1xuICAgICAgY29uc3QgbWlkID0gTWF0aC5mbG9vcigobG93ICsgaGlnaCkgLyAyKTtcbiAgICAgIGlmIChzdG9yZVttaWRdLnN0YXJ0IDw9IHNjcm9sbEJvdHRvbSkge1xuICAgICAgICBhbnMgPSBtaWQ7XG4gICAgICAgIGxvdyA9IG1pZCArIDE7IC8vIFRyeSB0byBmaW5kIGxhdGVyXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdoID0gbWlkIC0gMTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFucztcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlclNjcm9sbCgpIHtcbiAgICBjb25zdCBzdG9yZSA9IHRoaXMuc3RvcmVJdGVtcygpO1xuICAgIGlmICghc3RvcmU/Lmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzY3JvbGxFbCA9IHRoaXMuU2Nyb2xsQ29udGFpbmVyO1xuICAgIGNvbnN0IHNjcm9sbFRvcCA9IHNjcm9sbEVsLnNjcm9sbFRvcDtcbiAgICBjb25zdCBjb250YWluZXJIZWlnaHQgPSBzY3JvbGxFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQ7XG5cbiAgICAvLyBVdGlsaXplIEJpbmFyeSBTZWFyY2ggZm9yIG9wdGltYWwgTyhsb2cgTikgZGlzY292ZXJ5XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmZpbmRTdGFydEluZGV4KHN0b3JlLCBzY3JvbGxUb3ApO1xuICAgIGNvbnN0IGVuZCA9IHRoaXMuZmluZEVuZEluZGV4KHN0b3JlLCBzY3JvbGxUb3AgKyBjb250YWluZXJIZWlnaHQpO1xuXG4gICAgaWYgKGVuZCAhPT0gdGhpcy5lbmQoKSkge1xuICAgICAgdGhpcy5lbmQuc2V0KGVuZCk7XG4gICAgfVxuXG4gICAgaWYgKHN0YXJ0ICE9PSB0aGlzLnN0YXJ0KCkpIHtcbiAgICAgIHRoaXMuc3RhcnQuc2V0KHN0YXJ0KTtcbiAgICAgIC8vIEJpbmFyeSBzZWFyY2ggZ3VhcmFudGVlcyBgc3RhcnRgIGzDoCBpbmRleCBo4bujcCBs4buHIHRyb25nIHN0b3JlLlxuICAgICAgY29uc3QgcGFkZGluZ1RvcCA9IHN0b3JlW3N0YXJ0XS5zdGFydDtcbiAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnN0eWxlLnBhZGRpbmdUb3AgPSBgJHtwYWRkaW5nVG9wfXB4YDtcbiAgICAgIHRoaXMub3V0UGFkZGluZ1RvcC5lbWl0KHBhZGRpbmdUb3ApO1xuICAgIH1cbiAgICB0aGlzLnZpZXdQb3J0SXRlbXMuc2V0KHN0b3JlLnNsaWNlKHRoaXMuc3RhcnQoKSwgdGhpcy5lbmQoKSArIHRoaXMuYnVmZmVyQWhlYWQpLm1hcCgoaXRlbSkgPT4gaXRlbS5yZWYpKTtcbiAgICB0aGlzLm91dFZpZXdQb3J0SXRlbS5lbWl0KHRoaXMudmlld1BvcnRJdGVtcygpKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2Nyb2xsSW50byhpdGVtU2Nyb2xsOiBhbnkpIHtcbiAgICBjb25zdCBpdGVtRm91bmQgPSB0aGlzLnN0b3JlSXRlbXMoKS5maW5kKChpdGVtKSA9PiBpdGVtLnJlZiA9PT0gaXRlbVNjcm9sbCk7XG4gICAgaWYgKCFpdGVtRm91bmQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5TY3JvbGxDb250YWluZXIuc2Nyb2xsVG9wID0gaXRlbUZvdW5kLnN0YXJ0O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzY3JvbGxUb1Bvc2l0aW9uKHBvc2l0aW9uOiBudW1iZXIpIHtcbiAgICB0aGlzLlNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBwb3NpdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2Nyb2xsVG9JbmRleChpbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3QgaXRlbU9mSW5kZXggPSB0aGlzLnN0b3JlSXRlbXMoKVtpbmRleF07XG4gICAgaWYgKCFpdGVtT2ZJbmRleCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLlNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBpdGVtT2ZJbmRleC5zdGFydDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVDYWxjdWxhdG9yVmlld1BvcnQoKSB7XG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLnN0b3JlSXRlbXMoKTtcbiAgICBjb25zdCBmbiA9IHRoaXMuZnVuY3Rpb25HZXRIZWlnaHRJdGVtKCk7XG4gICAgLy8gxJBvIHNvbmcgc29uZyDEkeG7gyByw7p0IG5n4bqvbiB0aOG7nWkgZ2lhbiB0aGF5IHbDrCBhd2FpdCB0deG6p24gdOG7sS5cbiAgICBjb25zdCBoZWlnaHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoaXRlbXMubWFwKChpdCkgPT4gZm4oaXQucmVmKSkpO1xuXG4gICAgbGV0IGhlaWdodCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zW2ldO1xuICAgICAgY29uc3QgaXRlbUhlaWdodCA9IGhlaWdodHNbaV07XG4gICAgICBpdGVtLml0ZW1IZWlnaHQgPSBpdGVtSGVpZ2h0O1xuICAgICAgaXRlbS5zdGFydCA9IGhlaWdodDtcbiAgICAgIGhlaWdodCArPSBpdGVtSGVpZ2h0O1xuICAgICAgaXRlbS5lbmQgPSBoZWlnaHQ7XG4gICAgfVxuXG4gICAgdGhpcy5zdG9yZUl0ZW1zLnNldChbLi4uaXRlbXNdKTtcbiAgICB0aGlzLmRpdlZpcnR1YWwuc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YDtcbiAgICB0aGlzLmhhbmRsZXJTY3JvbGwoKTtcbiAgfVxufVxuIl19
|
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { signal, input, output, inject, ElementRef, DestroyRef, effect, untracked, Directive } from '@angular/core';
|
|
3
3
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
|
-
import { get } from '@libs-ui/utils';
|
|
5
4
|
import { fromEvent } from 'rxjs';
|
|
6
5
|
|
|
7
6
|
// CONVENTION-EXCEPT: any — Generic directive works with unknown item types from consumer
|
|
8
7
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
9
8
|
class LibsUiScrollMeasureItemDirectionVerticalDirective {
|
|
10
9
|
// #region PROPERTY
|
|
10
|
+
/** Số item buffer render thêm sau viewport để tránh trắng vùng khi scroll. */
|
|
11
|
+
bufferAhead = 3;
|
|
11
12
|
viewPortItems = signal([]);
|
|
12
13
|
start = signal(0);
|
|
13
14
|
end = signal(0);
|
|
14
15
|
storeItems = signal([]);
|
|
15
16
|
divVirtual = document.createElement('div');
|
|
17
|
+
resizeObserver;
|
|
18
|
+
/** Tham chiếu setTimeout của ngAfterViewInit để clear khi destroy — chặn ResizeObserver mồ côi. */
|
|
19
|
+
timerAfterViewInit;
|
|
20
|
+
/** Token nhận dạng lần effect chạy hiện tại. Async đo height xong sẽ bỏ kết quả nếu token đổi. */
|
|
21
|
+
executionToken = 0;
|
|
22
|
+
/** Style + DOM hook của divVirtual chỉ cần khởi tạo một lần cho cả vòng đời directive. */
|
|
23
|
+
divVirtualInitialized = false;
|
|
16
24
|
// #region INPUT
|
|
17
25
|
elementScroll = input.required();
|
|
18
26
|
functionGetHeightItem = input.required();
|
|
@@ -27,59 +35,79 @@ class LibsUiScrollMeasureItemDirectionVerticalDirective {
|
|
|
27
35
|
destroyRef = inject(DestroyRef);
|
|
28
36
|
constructor() {
|
|
29
37
|
effect(() => {
|
|
30
|
-
const scrollEl = untracked(() => this.ScrollContainer);
|
|
31
|
-
if (!scrollEl || !untracked(() => this.functionGetHeightItem())) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
38
|
const items = this.items();
|
|
39
|
+
const myToken = ++this.executionToken;
|
|
35
40
|
untracked(async () => {
|
|
41
|
+
const scrollEl = this.ScrollContainer;
|
|
42
|
+
const functionGetHeightItem = this.functionGetHeightItem();
|
|
43
|
+
if (!scrollEl || !functionGetHeightItem) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// Đo height tất cả item song song — rút ngắn thời gian cho list lớn.
|
|
47
|
+
const heights = await Promise.all(items.map((it) => functionGetHeightItem(it)));
|
|
48
|
+
// Bị huỷ vì có lượt items() mới chạy sau — bỏ kết quả cũ tránh đè state.
|
|
49
|
+
if (myToken !== this.executionToken) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
36
52
|
this.start.set(0);
|
|
37
53
|
const scrollTop = scrollEl.scrollTop;
|
|
38
54
|
const containerHeight = scrollEl.getBoundingClientRect().height;
|
|
39
55
|
let height = 0;
|
|
56
|
+
let endLocal = 0;
|
|
40
57
|
const newItems = [];
|
|
41
58
|
for (let i = 0; i < items.length; i++) {
|
|
42
|
-
const
|
|
43
|
-
const newItem = { ref:
|
|
44
|
-
const itemHeight = await this.functionGetHeightItem()(item);
|
|
45
|
-
newItem.itemHeight = itemHeight;
|
|
46
|
-
newItem.start = height;
|
|
59
|
+
const itemHeight = heights[i];
|
|
60
|
+
const newItem = { ref: items[i], itemHeight, start: height, end: 0 };
|
|
47
61
|
height += itemHeight;
|
|
48
62
|
newItem.end = height;
|
|
49
63
|
if (newItem.end <= containerHeight + scrollTop) {
|
|
50
|
-
|
|
64
|
+
endLocal = i;
|
|
51
65
|
}
|
|
52
66
|
newItems.push(newItem);
|
|
53
67
|
}
|
|
68
|
+
// Set end một lần thay vì ghi mỗi vòng lặp — tránh notify consumer N lần.
|
|
69
|
+
this.end.set(endLocal);
|
|
54
70
|
this.storeItems.set(newItems);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
71
|
+
// Khởi tạo style + DOM hook của divVirtual đúng một lần.
|
|
72
|
+
if (!this.divVirtualInitialized) {
|
|
73
|
+
this.divVirtual.style.position = 'absolute';
|
|
74
|
+
this.divVirtual.style.top = '0px';
|
|
75
|
+
this.divVirtual.style.left = '0px';
|
|
76
|
+
this.divVirtual.style.width = '1px';
|
|
77
|
+
this.divVirtual.style.visibility = 'hidden'; // Đảm bảo an toàn không hiển thị
|
|
78
|
+
this.elementRef.nativeElement.classList.add('relative');
|
|
79
|
+
this.elementRef.nativeElement.classList.remove('h-full');
|
|
80
|
+
this.elementRef.nativeElement.style.paddingTop = '0px';
|
|
81
|
+
scrollEl.append(this.divVirtual);
|
|
82
|
+
this.divVirtualInitialized = true;
|
|
83
|
+
this.outDivVirtual.emit(this.divVirtual);
|
|
84
|
+
}
|
|
85
|
+
// Height tổng thể đổi theo dataset → cần update mỗi lượt.
|
|
63
86
|
this.divVirtual.style.height = `${height}px`;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
this.
|
|
68
|
-
this.elementRef.nativeElement.style.paddingTop = '0px';
|
|
69
|
-
scrollEl.append(this.divVirtual);
|
|
70
|
-
this.outDivVirtual.emit(this.divVirtual);
|
|
87
|
+
// containerHeight lúc đầu có thể = 0 (DOM chưa layout), khiến end giữ
|
|
88
|
+
// nguyên 0 và chỉ render bufferAhead item đầu. Re-đo bằng handlerScroll sau khi vòng
|
|
89
|
+
// lặp await xong (layout thường đã hoàn tất) để end ra đúng giá trị.
|
|
90
|
+
this.handlerScroll();
|
|
71
91
|
});
|
|
72
92
|
});
|
|
73
93
|
this.destroyRef.onDestroy(() => {
|
|
94
|
+
clearTimeout(this.timerAfterViewInit);
|
|
74
95
|
this.divVirtual.remove();
|
|
96
|
+
this.resizeObserver?.disconnect();
|
|
75
97
|
});
|
|
76
98
|
}
|
|
77
99
|
ngAfterViewInit() {
|
|
78
|
-
setTimeout(() => {
|
|
100
|
+
this.timerAfterViewInit = setTimeout(() => {
|
|
79
101
|
fromEvent(this.ScrollContainer, 'scroll')
|
|
80
102
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
81
103
|
.subscribe(() => this.handlerScroll());
|
|
82
104
|
this.outFunctionControl.emit(this.FunctionsControl);
|
|
105
|
+
// Re-tính viewport sau khi container có kích thước thật.
|
|
106
|
+
// Lần đầu render, getBoundingClientRect().height có thể = 0 nên end giữ giá trị 0,
|
|
107
|
+
// chỉ hiển thị bufferAhead item đầu. ResizeObserver fire ngay khi observe và mỗi lần
|
|
108
|
+
// container đổi size sẽ kéo end về đúng giá trị.
|
|
109
|
+
this.resizeObserver = new ResizeObserver(() => this.handlerScroll());
|
|
110
|
+
this.resizeObserver.observe(this.ScrollContainer);
|
|
83
111
|
});
|
|
84
112
|
}
|
|
85
113
|
// #region PUBLIC API
|
|
@@ -139,18 +167,17 @@ class LibsUiScrollMeasureItemDirectionVerticalDirective {
|
|
|
139
167
|
// Utilize Binary Search for optimal O(log N) discovery
|
|
140
168
|
const start = this.findStartIndex(store, scrollTop);
|
|
141
169
|
const end = this.findEndIndex(store, scrollTop + containerHeight);
|
|
142
|
-
this.end
|
|
170
|
+
if (end !== this.end()) {
|
|
171
|
+
this.end.set(end);
|
|
172
|
+
}
|
|
143
173
|
if (start !== this.start()) {
|
|
144
174
|
this.start.set(start);
|
|
145
|
-
//
|
|
146
|
-
const paddingTop = store[start]
|
|
175
|
+
// Binary search guarantees `start` là index hợp lệ trong store.
|
|
176
|
+
const paddingTop = store[start].start;
|
|
147
177
|
this.elementRef.nativeElement.style.paddingTop = `${paddingTop}px`;
|
|
148
178
|
this.outPaddingTop.emit(paddingTop);
|
|
149
179
|
}
|
|
150
|
-
|
|
151
|
-
this.start.set(0);
|
|
152
|
-
}
|
|
153
|
-
this.viewPortItems.set(store.slice(this.start(), this.end() + 3).map((item) => item.ref));
|
|
180
|
+
this.viewPortItems.set(store.slice(this.start(), this.end() + this.bufferAhead).map((item) => item.ref));
|
|
154
181
|
this.outViewPortItem.emit(this.viewPortItems());
|
|
155
182
|
}
|
|
156
183
|
async scrollInto(itemScroll) {
|
|
@@ -171,10 +198,14 @@ class LibsUiScrollMeasureItemDirectionVerticalDirective {
|
|
|
171
198
|
this.ScrollContainer.scrollTop = itemOfIndex.start;
|
|
172
199
|
}
|
|
173
200
|
async reCalculatorViewPort() {
|
|
174
|
-
let height = 0;
|
|
175
201
|
const items = this.storeItems();
|
|
176
|
-
|
|
177
|
-
|
|
202
|
+
const fn = this.functionGetHeightItem();
|
|
203
|
+
// Đo song song để rút ngắn thời gian thay vì await tuần tự.
|
|
204
|
+
const heights = await Promise.all(items.map((it) => fn(it.ref)));
|
|
205
|
+
let height = 0;
|
|
206
|
+
for (let i = 0; i < items.length; i++) {
|
|
207
|
+
const item = items[i];
|
|
208
|
+
const itemHeight = heights[i];
|
|
178
209
|
item.itemHeight = itemHeight;
|
|
179
210
|
item.start = height;
|
|
180
211
|
height += itemHeight;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libs-ui-components-scroll-measure-items-direction-vertical.mjs","sources":["../../../../../../libs-ui/components/scroll-measure-items/direction-vertical/src/direction-vertical.directive.ts","../../../../../../libs-ui/components/scroll-measure-items/direction-vertical/src/interfaces/direction-vertical.interface.ts","../../../../../../libs-ui/components/scroll-measure-items/direction-vertical/src/libs-ui-components-scroll-measure-items-direction-vertical.ts"],"sourcesContent":["// CONVENTION-EXCEPT: any — Generic directive works with unknown item types from consumer\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { AfterViewInit, DestroyRef, Directive, ElementRef, effect, inject, input, output, signal, untracked } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { get } from '@libs-ui/utils';\nimport { fromEvent } from 'rxjs';\nimport { IScrollMeasureItemDirectionVerticalFunctionsControl, IScrollMeasureStoreItemVerticalConvert } from './interfaces/direction-vertical.interface';\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[LibsUiScrollMeasureItemDirectionVerticalDirective]',\n standalone: true,\n})\nexport class LibsUiScrollMeasureItemDirectionVerticalDirective implements AfterViewInit {\n // #region PROPERTY\n private viewPortItems = signal<Array<any>>([]);\n private start = signal<number>(0);\n private end = signal<number>(0);\n private storeItems = signal<Array<IScrollMeasureStoreItemVerticalConvert>>([]);\n private divVirtual = document.createElement('div');\n\n // #region INPUT\n readonly elementScroll = input.required<HTMLElement>();\n readonly functionGetHeightItem = input.required<(item: any) => Promise<number>>();\n readonly items = input.required<Array<any>>();\n\n // #region OUTPUT\n readonly outViewPortItem = output<Array<any>>();\n readonly outFunctionControl = output<IScrollMeasureItemDirectionVerticalFunctionsControl>();\n readonly outDivVirtual = output<HTMLDivElement>();\n readonly outPaddingTop = output<number>();\n\n // #region INJECT\n private readonly elementRef = inject(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n effect(() => {\n const scrollEl = untracked(() => this.ScrollContainer);\n if (!scrollEl || !untracked(() => this.functionGetHeightItem())) {\n return;\n }\n const items = this.items();\n untracked(async () => {\n this.start.set(0);\n const scrollTop = scrollEl.scrollTop;\n const containerHeight = scrollEl.getBoundingClientRect().height;\n let height = 0;\n const newItems: Array<IScrollMeasureStoreItemVerticalConvert> = [];\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const newItem: IScrollMeasureStoreItemVerticalConvert = { ref: item, itemHeight: 0, start: 0, end: 0 };\n const itemHeight = await this.functionGetHeightItem()(item);\n newItem.itemHeight = itemHeight;\n newItem.start = height;\n height += itemHeight;\n newItem.end = height;\n if (newItem.end <= containerHeight + scrollTop) {\n this.end.set(i);\n }\n newItems.push(newItem);\n }\n\n this.storeItems.set(newItems);\n this.viewPortItems.set(\n this.storeItems()\n .slice(this.start(), this.end() + 3)\n .map((item) => item.ref)\n );\n this.outViewPortItem.emit(this.viewPortItems());\n this.outPaddingTop.emit(get(this.storeItems(), `[${this.start()}].start`, 0));\n\n this.divVirtual.style.position = 'absolute';\n this.divVirtual.style.top = '0px';\n this.divVirtual.style.left = '0px';\n this.divVirtual.style.height = `${height}px`;\n this.divVirtual.style.width = '1px';\n this.divVirtual.style.visibility = 'hidden'; // Đảm bảo an toàn không hiển thị\n this.elementRef.nativeElement.classList.add('relative');\n this.elementRef.nativeElement.classList.remove('h-full');\n this.elementRef.nativeElement.style.paddingTop = '0px';\n scrollEl.append(this.divVirtual);\n this.outDivVirtual.emit(this.divVirtual);\n });\n });\n\n this.destroyRef.onDestroy(() => {\n this.divVirtual.remove();\n });\n }\n\n ngAfterViewInit() {\n setTimeout(() => {\n fromEvent<Event>(this.ScrollContainer, 'scroll')\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.handlerScroll());\n this.outFunctionControl.emit(this.FunctionsControl);\n });\n }\n\n // #region PUBLIC API\n public get FunctionsControl(): IScrollMeasureItemDirectionVerticalFunctionsControl {\n return {\n scrollInto: this.scrollInto.bind(this),\n scrollToPosition: this.scrollToPosition.bind(this),\n scrollToIndex: this.scrollToIndex.bind(this),\n reCalculatorViewPort: this.reCalculatorViewPort.bind(this),\n getViewPortItems: () => this.viewPortItems(),\n };\n }\n\n // #region PRIVATE METHODS\n private get ScrollContainer(): HTMLElement {\n return this.elementScroll() || this.elementRef.nativeElement;\n }\n\n private findStartIndex(store: Array<IScrollMeasureStoreItemVerticalConvert>, scrollTop: number): number {\n let low = 0;\n let high = store.length - 1;\n let ans = store.length - 1; // Default to last item if scrolled past bottom (rubber band effect)\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n if (store[mid].end >= scrollTop) {\n ans = mid;\n high = mid - 1; // Try to find earlier\n } else {\n low = mid + 1;\n }\n }\n return ans;\n }\n\n private findEndIndex(store: Array<IScrollMeasureStoreItemVerticalConvert>, scrollBottom: number): number {\n let low = 0;\n let high = store.length - 1;\n let ans = 0; // Default to first item if rubber-banded above the top\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n if (store[mid].start <= scrollBottom) {\n ans = mid;\n low = mid + 1; // Try to find later\n } else {\n high = mid - 1;\n }\n }\n return ans;\n }\n\n private handlerScroll() {\n const store = this.storeItems();\n if (!store?.length) {\n return;\n }\n const scrollEl = this.ScrollContainer;\n const scrollTop = scrollEl.scrollTop;\n const containerHeight = scrollEl.getBoundingClientRect().height;\n \n // Utilize Binary Search for optimal O(log N) discovery\n const start = this.findStartIndex(store, scrollTop);\n const end = this.findEndIndex(store, scrollTop + containerHeight);\n\n this.end.set(end);\n\n if (start !== this.start()) {\n this.start.set(start);\n // Use logical OR for fallback when start is invalid. But binary search guarantees valid index.\n const paddingTop = store[start]?.start || 0;\n this.elementRef.nativeElement.style.paddingTop = `${paddingTop}px`;\n this.outPaddingTop.emit(paddingTop);\n }\n\n if (this.start() < 0) {\n this.start.set(0);\n }\n this.viewPortItems.set(store.slice(this.start(), this.end() + 3).map((item) => item.ref));\n this.outViewPortItem.emit(this.viewPortItems());\n }\n\n private async scrollInto(itemScroll: any) {\n const itemFound = this.storeItems().find((item) => item.ref === itemScroll);\n if (!itemFound) {\n return;\n }\n this.ScrollContainer.scrollTop = itemFound.start;\n }\n\n private async scrollToPosition(position: number) {\n this.ScrollContainer.scrollTop = position;\n }\n\n private async scrollToIndex(index: number) {\n const itemOfIndex = this.storeItems()[index];\n if (!itemOfIndex) {\n return;\n }\n this.ScrollContainer.scrollTop = itemOfIndex.start;\n }\n\n private async reCalculatorViewPort() {\n let height = 0;\n const items = this.storeItems();\n\n for (const item of items) {\n const itemHeight = await this.functionGetHeightItem()(item.ref);\n item.itemHeight = itemHeight;\n item.start = height;\n height += itemHeight;\n item.end = height;\n }\n\n this.storeItems.set([...items]);\n this.divVirtual.style.height = `${height}px`;\n this.handlerScroll();\n }\n}\n","// CONVENTION-EXCEPT: any — Generic data structures from consumers\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nexport interface IScrollMeasureStoreItemVerticalConvert {\n ref: any;\n itemHeight: number;\n start: number; // Tọa độ Y (px) bắt đầu của item\n end: number; // Tọa độ Y (px) kết thúc của item\n}\n\nexport interface IScrollMeasureItemDirectionVerticalFunctionsControl {\n scrollInto: (item: any) => Promise<void>;\n scrollToPosition: (position: number) => Promise<void>;\n scrollToIndex: (index: number) => Promise<void>;\n reCalculatorViewPort: () => Promise<void>;\n getViewPortItems: () => Array<any>;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"libs-ui-components-scroll-measure-items-direction-vertical.mjs","sources":["../../../../../../libs-ui/components/scroll-measure-items/direction-vertical/src/direction-vertical.directive.ts","../../../../../../libs-ui/components/scroll-measure-items/direction-vertical/src/interfaces/direction-vertical.interface.ts","../../../../../../libs-ui/components/scroll-measure-items/direction-vertical/src/libs-ui-components-scroll-measure-items-direction-vertical.ts"],"sourcesContent":["// CONVENTION-EXCEPT: any — Generic directive works with unknown item types from consumer\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { AfterViewInit, DestroyRef, Directive, ElementRef, effect, inject, input, output, signal, untracked } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { fromEvent } from 'rxjs';\nimport { IScrollMeasureItemDirectionVerticalFunctionsControl, IScrollMeasureStoreItemVerticalConvert } from './interfaces/direction-vertical.interface';\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[LibsUiScrollMeasureItemDirectionVerticalDirective]',\n standalone: true,\n})\nexport class LibsUiScrollMeasureItemDirectionVerticalDirective implements AfterViewInit {\n // #region PROPERTY\n /** Số item buffer render thêm sau viewport để tránh trắng vùng khi scroll. */\n private readonly bufferAhead = 3;\n\n private viewPortItems = signal<Array<any>>([]);\n private start = signal<number>(0);\n private end = signal<number>(0);\n private storeItems = signal<Array<IScrollMeasureStoreItemVerticalConvert>>([]);\n private divVirtual = document.createElement('div');\n private resizeObserver?: ResizeObserver;\n /** Tham chiếu setTimeout của ngAfterViewInit để clear khi destroy — chặn ResizeObserver mồ côi. */\n private timerAfterViewInit?: number;\n /** Token nhận dạng lần effect chạy hiện tại. Async đo height xong sẽ bỏ kết quả nếu token đổi. */\n private executionToken = 0;\n /** Style + DOM hook của divVirtual chỉ cần khởi tạo một lần cho cả vòng đời directive. */\n private divVirtualInitialized = false;\n\n // #region INPUT\n readonly elementScroll = input.required<HTMLElement>();\n readonly functionGetHeightItem = input.required<(item: any) => Promise<number>>();\n readonly items = input.required<Array<any>>();\n\n // #region OUTPUT\n readonly outViewPortItem = output<Array<any>>();\n readonly outFunctionControl = output<IScrollMeasureItemDirectionVerticalFunctionsControl>();\n readonly outDivVirtual = output<HTMLDivElement>();\n readonly outPaddingTop = output<number>();\n\n // #region INJECT\n private readonly elementRef = inject(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n effect(() => {\n const items = this.items();\n const myToken = ++this.executionToken;\n untracked(async () => {\n const scrollEl = this.ScrollContainer;\n const functionGetHeightItem = this.functionGetHeightItem();\n if (!scrollEl || !functionGetHeightItem) {\n return;\n }\n\n // Đo height tất cả item song song — rút ngắn thời gian cho list lớn.\n const heights = await Promise.all(items.map((it) => functionGetHeightItem(it)));\n // Bị huỷ vì có lượt items() mới chạy sau — bỏ kết quả cũ tránh đè state.\n if (myToken !== this.executionToken) {\n return;\n }\n\n this.start.set(0);\n const scrollTop = scrollEl.scrollTop;\n const containerHeight = scrollEl.getBoundingClientRect().height;\n let height = 0;\n let endLocal = 0;\n const newItems: Array<IScrollMeasureStoreItemVerticalConvert> = [];\n\n for (let i = 0; i < items.length; i++) {\n const itemHeight = heights[i];\n const newItem: IScrollMeasureStoreItemVerticalConvert = { ref: items[i], itemHeight, start: height, end: 0 };\n height += itemHeight;\n newItem.end = height;\n if (newItem.end <= containerHeight + scrollTop) {\n endLocal = i;\n }\n newItems.push(newItem);\n }\n // Set end một lần thay vì ghi mỗi vòng lặp — tránh notify consumer N lần.\n this.end.set(endLocal);\n this.storeItems.set(newItems);\n\n // Khởi tạo style + DOM hook của divVirtual đúng một lần.\n if (!this.divVirtualInitialized) {\n this.divVirtual.style.position = 'absolute';\n this.divVirtual.style.top = '0px';\n this.divVirtual.style.left = '0px';\n this.divVirtual.style.width = '1px';\n this.divVirtual.style.visibility = 'hidden'; // Đảm bảo an toàn không hiển thị\n this.elementRef.nativeElement.classList.add('relative');\n this.elementRef.nativeElement.classList.remove('h-full');\n this.elementRef.nativeElement.style.paddingTop = '0px';\n scrollEl.append(this.divVirtual);\n this.divVirtualInitialized = true;\n this.outDivVirtual.emit(this.divVirtual);\n }\n // Height tổng thể đổi theo dataset → cần update mỗi lượt.\n this.divVirtual.style.height = `${height}px`;\n\n // containerHeight lúc đầu có thể = 0 (DOM chưa layout), khiến end giữ\n // nguyên 0 và chỉ render bufferAhead item đầu. Re-đo bằng handlerScroll sau khi vòng\n // lặp await xong (layout thường đã hoàn tất) để end ra đúng giá trị.\n this.handlerScroll();\n });\n });\n\n this.destroyRef.onDestroy(() => {\n clearTimeout(this.timerAfterViewInit);\n this.divVirtual.remove();\n this.resizeObserver?.disconnect();\n });\n }\n\n ngAfterViewInit() {\n this.timerAfterViewInit = setTimeout(() => {\n fromEvent<Event>(this.ScrollContainer, 'scroll')\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.handlerScroll());\n this.outFunctionControl.emit(this.FunctionsControl);\n\n // Re-tính viewport sau khi container có kích thước thật.\n // Lần đầu render, getBoundingClientRect().height có thể = 0 nên end giữ giá trị 0,\n // chỉ hiển thị bufferAhead item đầu. ResizeObserver fire ngay khi observe và mỗi lần\n // container đổi size sẽ kéo end về đúng giá trị.\n this.resizeObserver = new ResizeObserver(() => this.handlerScroll());\n this.resizeObserver.observe(this.ScrollContainer);\n });\n }\n\n // #region PUBLIC API\n public get FunctionsControl(): IScrollMeasureItemDirectionVerticalFunctionsControl {\n return {\n scrollInto: this.scrollInto.bind(this),\n scrollToPosition: this.scrollToPosition.bind(this),\n scrollToIndex: this.scrollToIndex.bind(this),\n reCalculatorViewPort: this.reCalculatorViewPort.bind(this),\n getViewPortItems: () => this.viewPortItems(),\n };\n }\n\n // #region PRIVATE METHODS\n private get ScrollContainer(): HTMLElement {\n return this.elementScroll() || this.elementRef.nativeElement;\n }\n\n private findStartIndex(store: Array<IScrollMeasureStoreItemVerticalConvert>, scrollTop: number): number {\n let low = 0;\n let high = store.length - 1;\n let ans = store.length - 1; // Default to last item if scrolled past bottom (rubber band effect)\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n if (store[mid].end >= scrollTop) {\n ans = mid;\n high = mid - 1; // Try to find earlier\n } else {\n low = mid + 1;\n }\n }\n return ans;\n }\n\n private findEndIndex(store: Array<IScrollMeasureStoreItemVerticalConvert>, scrollBottom: number): number {\n let low = 0;\n let high = store.length - 1;\n let ans = 0; // Default to first item if rubber-banded above the top\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n if (store[mid].start <= scrollBottom) {\n ans = mid;\n low = mid + 1; // Try to find later\n } else {\n high = mid - 1;\n }\n }\n return ans;\n }\n\n private handlerScroll() {\n const store = this.storeItems();\n if (!store?.length) {\n return;\n }\n const scrollEl = this.ScrollContainer;\n const scrollTop = scrollEl.scrollTop;\n const containerHeight = scrollEl.getBoundingClientRect().height;\n\n // Utilize Binary Search for optimal O(log N) discovery\n const start = this.findStartIndex(store, scrollTop);\n const end = this.findEndIndex(store, scrollTop + containerHeight);\n\n if (end !== this.end()) {\n this.end.set(end);\n }\n\n if (start !== this.start()) {\n this.start.set(start);\n // Binary search guarantees `start` là index hợp lệ trong store.\n const paddingTop = store[start].start;\n this.elementRef.nativeElement.style.paddingTop = `${paddingTop}px`;\n this.outPaddingTop.emit(paddingTop);\n }\n this.viewPortItems.set(store.slice(this.start(), this.end() + this.bufferAhead).map((item) => item.ref));\n this.outViewPortItem.emit(this.viewPortItems());\n }\n\n private async scrollInto(itemScroll: any) {\n const itemFound = this.storeItems().find((item) => item.ref === itemScroll);\n if (!itemFound) {\n return;\n }\n this.ScrollContainer.scrollTop = itemFound.start;\n }\n\n private async scrollToPosition(position: number) {\n this.ScrollContainer.scrollTop = position;\n }\n\n private async scrollToIndex(index: number) {\n const itemOfIndex = this.storeItems()[index];\n if (!itemOfIndex) {\n return;\n }\n this.ScrollContainer.scrollTop = itemOfIndex.start;\n }\n\n private async reCalculatorViewPort() {\n const items = this.storeItems();\n const fn = this.functionGetHeightItem();\n // Đo song song để rút ngắn thời gian thay vì await tuần tự.\n const heights = await Promise.all(items.map((it) => fn(it.ref)));\n\n let height = 0;\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const itemHeight = heights[i];\n item.itemHeight = itemHeight;\n item.start = height;\n height += itemHeight;\n item.end = height;\n }\n\n this.storeItems.set([...items]);\n this.divVirtual.style.height = `${height}px`;\n this.handlerScroll();\n }\n}\n","// CONVENTION-EXCEPT: any — Generic data structures from consumers\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nexport interface IScrollMeasureStoreItemVerticalConvert {\n ref: any;\n itemHeight: number;\n start: number; // Tọa độ Y (px) bắt đầu của item\n end: number; // Tọa độ Y (px) kết thúc của item\n}\n\nexport interface IScrollMeasureItemDirectionVerticalFunctionsControl {\n scrollInto: (item: any) => Promise<void>;\n scrollToPosition: (position: number) => Promise<void>;\n scrollToIndex: (index: number) => Promise<void>;\n reCalculatorViewPort: () => Promise<void>;\n getViewPortItems: () => Array<any>;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libs-ui/components-scroll-measure-items-direction-vertical",
|
|
3
|
-
"version": "0.2.356-
|
|
3
|
+
"version": "0.2.356-27",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/core": "^18.2.0",
|
|
6
|
-
"@libs-ui/utils": "0.2.356-25",
|
|
7
6
|
"rxjs": "~7.8.0"
|
|
8
7
|
},
|
|
9
8
|
"sideEffects": false,
|