@ceriousdevtech/ngx-cerious-scroll 1.0.7 → 1.0.8

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.
@@ -62,17 +62,23 @@ export class CeriousScrollDirective {
62
62
  const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);
63
63
  const countChanged = this.hostRef.scroller.totalElements !== total;
64
64
  if (countChanged) {
65
- // The dataset size changed: the ViewportRenderer stores its own copy of
66
- // totalElements (set by value at construction) so patching the engine's
67
- // public property alone leaves the renderer's internal bound stale. The
68
- // renderer would then use the old count for its viewport-fill loop and
69
- // bottom-boundary scan, producing phantom renders at out-of-bounds
70
- // indices (undefined items 0-height rows the fill loop never
71
- // satisfies its height condition hundreds of renderer callbacks).
72
- // Recreating the engine gives both the engine and the renderer a fresh,
73
- // consistent count. ensureInitialized() schedules the first render via
74
- // queueMicrotask, which runs after the current CD cycle completes.
75
- this.recreate();
65
+ // Grow/shrink the dataset IN PLACE no recreate. updateTotalElements
66
+ // propagates the new count to every subsystem, INCLUDING the
67
+ // ViewportRenderer's own copy of totalElements (it used to go stale,
68
+ // which is exactly why this recreated: the renderer kept the old count
69
+ // for its viewport-fill loop and bottom scan, producing phantom
70
+ // out-of-bounds renders). In place keeps the scroll position and an
71
+ // in-progress scrollbar drag alive, and a growing dataset keeps a stable
72
+ // bottom index (no bouncing tail). The track lengthens, so re-sync the
73
+ // thumb afterwards.
74
+ this.hostRef.scroller.updateTotalElements(total);
75
+ // A shrink can leave the position past the new end — clamp it.
76
+ if (this.hostRef.scroller.currentElement > total - 1) {
77
+ this.hostRef.scroller.jumpToElement(total - 1);
78
+ }
79
+ if (this.ceriousScrollAutoRender)
80
+ this.render();
81
+ this.hostRef.scroller.syncScrollbar();
76
82
  }
77
83
  else if (this.ceriousScrollAutoRender) {
78
84
  // Same count, new data reference (e.g. an immutable edit or a sort that
@@ -436,4 +442,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
436
442
  }], ceriousScrollReady: [{
437
443
  type: Output
438
444
  }] } });
439
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNlcmlvdXMtc2Nyb2xsL3NyYy9saWIvY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFHTCxTQUFTLEVBR1QsWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEdBR1AsTUFBTSxlQUFlLENBQUM7OztBQWF2QixTQUFTLG1CQUFtQixDQUFDLGFBQXdDLEVBQUUsUUFBbUM7SUFDeEcsTUFBTSxTQUFTLEdBQUcsT0FBTyxhQUFhLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDMUgsSUFBSSxTQUFTLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUN2RCxNQUFNLElBQUksS0FBSyxDQUFDLHVGQUF1RixDQUFDLENBQUM7SUFDM0csQ0FBQztJQUNELHdDQUF3QztJQUN4QyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ2hDLENBQUM7QUFNRCxNQUFNLE9BQU8sc0JBQXNCO0lBa0RqQyxZQUNtQixJQUE2QixFQUM3QixNQUFzQixFQUN0QixNQUFjLEVBQ2QsT0FBNkI7UUFIN0IsU0FBSSxHQUFKLElBQUksQ0FBeUI7UUFDN0IsV0FBTSxHQUFOLE1BQU0sQ0FBZ0I7UUFDdEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFlBQU8sR0FBUCxPQUFPLENBQXNCO1FBckRoRCxtRkFBbUY7UUFDMUUsK0JBQTBCLEdBQWtCLElBQUksQ0FBQztRQUUxRCxpREFBaUQ7UUFDeEMsdUJBQWtCLEdBQTRCLElBQUksQ0FB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TSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIEFwcGxpY2F0aW9uUmVmLFxuICBEaXJlY3RpdmUsXG4gIEVsZW1lbnRSZWYsXG4gIEVtYmVkZGVkVmlld1JlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7XG4gIHR5cGUgQ2VyaW91c1Njcm9sbE9wdGlvbnMsXG4gIHR5cGUgRWxlbWVudFJlbmRlcmVyLFxuICB0eXBlIE1lYXN1cmVkVmlld3BvcnRSYW5nZSxcbn0gZnJvbSAnQGNlcmlvdXNkZXZ0ZWNoL2NlcmlvdXMtc2Nyb2xsJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgdHlwZSB7IENlcmlvdXNWaWV3cG9ydENoYW5nZURldGFpbCB9IGZyb20gJy4vY2VyaW91cy1zY3JvbGwudHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlQ29udGV4dCB9IGZyb20gJy4vY2VyaW91cy1zY3JvbGwtaXRlbS10ZW1wbGF0ZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgdHlwZSBDZXJpb3VzU2Nyb2xsSG9zdFJlZiwgQ2VyaW91c1Njcm9sbFNlcnZpY2UgfSBmcm9tICcuL2NlcmlvdXMtc2Nyb2xsLnNlcnZpY2UnO1xuXG5mdW5jdGlvbiBjb2VyY2VUb3RhbEVsZW1lbnRzKGV4cGxpY2l0VG90YWw6IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQsIGl0ZW1zTGVuOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkKTogbnVtYmVyIHtcbiAgY29uc3QgY2FuZGlkYXRlID0gdHlwZW9mIGV4cGxpY2l0VG90YWwgPT09ICdudW1iZXInID8gZXhwbGljaXRUb3RhbCA6IHR5cGVvZiBpdGVtc0xlbiA9PT0gJ251bWJlcicgPyBpdGVtc0xlbiA6IHVuZGVmaW5lZDtcbiAgaWYgKGNhbmRpZGF0ZSA9PT0gdW5kZWZpbmVkIHx8IE51bWJlci5pc05hTihjYW5kaWRhdGUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDZXJpb3VzU2Nyb2xsRGlyZWN0aXZlOiBwcm92aWRlIGBjZXJpb3VzU2Nyb2xsVG90YWxFbGVtZW50c2Agb3IgYGNlcmlvdXNTY3JvbGxJdGVtc2AuJyk7XG4gIH1cbiAgLy8gQ2VyaW91c1Njcm9sbCBjdXJyZW50bHkgcmVxdWlyZXMgPj0gMVxuICByZXR1cm4gTWF0aC5tYXgoMSwgY2FuZGlkYXRlKTtcbn1cblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2NlcmlvdXNTY3JvbGxdJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgQ2VyaW91c1Njcm9sbERpcmVjdGl2ZTxUSXRlbSA9IHVua25vd24+IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICAvKiogVG90YWwgbnVtYmVyIG9mIGl0ZW1zLiBJZiBvbWl0dGVkLCBkZXJpdmVkIGZyb20gYGNlcmlvdXNTY3JvbGxJdGVtcy5sZW5ndGhgLiAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsVG90YWxFbGVtZW50czogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIE9wdGlvbmFsIGl0ZW1zIGFycmF5IChlbmFibGVzIGBsZXQtaXRlbWApLiAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsSXRlbXM6IHJlYWRvbmx5IFRJdGVtW10gfCBudWxsID0gbnVsbDtcblxuICAvKiogT3B0aW9uYWwgZ2V0dGVyIGZvciBsYXJnZSBkYXRhc2V0cyAoYWx0ZXJuYXRpdmUgdG8gcGFzc2luZyBmdWxsIGBpdGVtc2ApLiAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsR2V0SXRlbTogKChpbmRleDogbnVtYmVyKSA9PiBUSXRlbSkgfCBudWxsID0gbnVsbDtcblxuICAvKiogVGVtcGxhdGUgdXNlZCB0byByZW5kZXIgZWFjaCByb3cuICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGU6IFRlbXBsYXRlUmVmPENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVDb250ZXh0PFRJdGVtPj4gfCBudWxsID0gbnVsbDtcblxuICAvKipcbiAgICogVGFibGUgbW9kZSBvbmx5OiB0ZW1wbGF0ZSByZW5kZXJlZCBpbnRvIHRoZSBlbmdpbmUncyBgPHRoZWFkPmAgKGEgYDx0cj5gIG9mXG4gICAqIGA8dGg+YHMpLiBJdCBsaXZlcyBpbiB0aGUgc2FtZSBgPHRhYmxlPmAgYXMgdGhlIHJvd3MsIHNvIGNvbHVtbnMgYWxpZ25cbiAgICogbmF0aXZlbHkuIFVwZGF0ZXMgdmlhIGNoYW5nZSBkZXRlY3Rpb24gbGlrZSB0aGUgcm93cy5cbiAgICovXG4gIEBJbnB1dCgpIGNlcmlvdXNTY3JvbGxIZWFkZXJUZW1wbGF0ZTogVGVtcGxhdGVSZWY8dW5rbm93bj4gfCBudWxsID0gbnVsbDtcblxuICAvKiogT3B0aW9ucyBwYXNzZWQgdG8gYG5ldyBDZXJpb3VzU2Nyb2xsKC4uLilgLiAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsT3B0aW9uczogQ2VyaW91c1Njcm9sbE9wdGlvbnMgPSB7fTtcblxuICAvKiogQXV0b21hdGljYWxseSBjYWxsIHJlbmRlciBhZnRlciBlYWNoIHNjcm9sbCBldmVudC4gRGVmYXVsdDogdHJ1ZSAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsQXV0b1JlbmRlciA9IHRydWU7XG5cbiAgLyoqIEVtaXRzIGBjZXJpb3VzLXZpZXdwb3J0LWNoYW5nZWAgZGV0YWlsLiAqL1xuICBAT3V0cHV0KCkgY2VyaW91c1Njcm9sbFZpZXdwb3J0Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWw+KCk7XG5cbiAgLyoqIEVtaXRzIHRoZSBsYXN0IG1lYXN1cmVkIHZpZXdwb3J0IGFmdGVyIGVhY2ggcmVuZGVyIHBhc3MuICovXG4gIEBPdXRwdXQoKSBjZXJpb3VzU2Nyb2xsTWVhc3VyZWRWaWV3cG9ydCA9IG5ldyBFdmVudEVtaXR0ZXI8TWVhc3VyZWRWaWV3cG9ydFJhbmdlPigpO1xuXG4gIC8qKiBFbWl0cyBvbmNlIHRoZSB1bmRlcmx5aW5nIGBDZXJpb3VzU2Nyb2xsYCBpbnN0YW5jZSBpcyByZWFkeS4gKi9cbiAgQE91dHB1dCgpIGNlcmlvdXNTY3JvbGxSZWFkeSA9IG5ldyBFdmVudEVtaXR0ZXI8Q2VyaW91c1Njcm9sbEhvc3RSZWZbJ3Njcm9sbGVyJ10+KCk7XG5cbiAgcHJpdmF0ZSBob3N0UmVmOiBDZXJpb3VzU2Nyb2xsSG9zdFJlZiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHZpZXdwb3J0U3ViOiBTdWJzY3JpcHRpb24gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBzY2hlZHVsZWRSZW5kZXJGcmFtZTogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB2aWV3QnlDb250YWluZXIgPSBuZXcgTWFwPEhUTUxFbGVtZW50LCBFbWJlZGRlZFZpZXdSZWY8Q2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQ8VEl0ZW0+Pj4oKTtcbiAgLy8gUG9vbCBvZiB2aWV3cyBkZXRhY2hlZCBiZWNhdXNlIHRoZWlyIGNvbnRhaW5lciBsZWZ0IHRoZSB2aWV3cG9ydC4gUmV1c2luZ1xuICAvLyB0aGVtIG9uIHN1YnNlcXVlbnQgcmVuZGVycyBhdm9pZHMgZGVzdHJveWluZyArIHJlY3JlYXRpbmcgdGhlIGVudGlyZSByb3dcbiAgLy8gY29tcG9uZW50IHRyZWUgb24gZmFzdCBzY3JvbGxzICh3aGVyZSB0aGUgZW5naW5lJ3MgZWxlbWVudCBwb29sIHdpcGVzXG4gIC8vIHRleHRDb250ZW50IG9uIHJldXNlZCBjb250YWluZXJzLCBzbyB2aWV3IHJvb3ROb2RlcyBnZXQgb3JwaGFuZWQpLlxuICBwcml2YXRlIHJlYWRvbmx5IGZyZWVWaWV3czogRW1iZWRkZWRWaWV3UmVmPENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVDb250ZXh0PFRJdGVtPj5bXSA9IFtdO1xuXG4gIC8vIFRhYmxlIG1vZGU6IHRoZSBlbWJlZGRlZCB2aWV3IG9mIHRoZSBkZWNsYXJhdGl2ZSBoZWFkZXIsIHJlbmRlcmVkIGludG8gdGhlXG4gIC8vIGVuZ2luZSdzIDx0aGVhZD4uXG4gIHByaXZhdGUgaGVhZGVyVmlldzogRW1iZWRkZWRWaWV3UmVmPHVua25vd24+IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBob3N0OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGFwcFJlZjogQXBwbGljYXRpb25SZWYsXG4gICAgcHJpdmF0ZSByZWFkb25seSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNlcmlvdXM6IENlcmlvdXNTY3JvbGxTZXJ2aWNlXG4gICkge31cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm47XG5cbiAgICBpZiAoY2hhbmdlc1snY2VyaW91c1Njcm9sbEl0ZW1zJ10gfHwgY2hhbmdlc1snY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHMnXSkge1xuICAgICAgY29uc3QgdG90YWwgPSBjb2VyY2VUb3RhbEVsZW1lbnRzKHRoaXMuY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHMsIHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1zPy5sZW5ndGggPz8gbnVsbCk7XG4gICAgICBjb25zdCBjb3VudENoYW5nZWQgPSB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIudG90YWxFbGVtZW50cyAhPT0gdG90YWw7XG5cbiAgICAgIGlmIChjb3VudENoYW5nZWQpIHtcbiAgICAgICAgLy8gVGhlIGRhdGFzZXQgc2l6ZSBjaGFuZ2VkOiB0aGUgVmlld3BvcnRSZW5kZXJlciBzdG9yZXMgaXRzIG93biBjb3B5IG9mXG4gICAgICAgIC8vIHRvdGFsRWxlbWVudHMgKHNldCBieSB2YWx1ZSBhdCBjb25zdHJ1Y3Rpb24pIHNvIHBhdGNoaW5nIHRoZSBlbmdpbmUnc1xuICAgICAgICAvLyBwdWJsaWMgcHJvcGVydHkgYWxvbmUgbGVhdmVzIHRoZSByZW5kZXJlcidzIGludGVybmFsIGJvdW5kIHN0YWxlLiAgVGhlXG4gICAgICAgIC8vIHJlbmRlcmVyIHdvdWxkIHRoZW4gdXNlIHRoZSBvbGQgY291bnQgZm9yIGl0cyB2aWV3cG9ydC1maWxsIGxvb3AgYW5kXG4gICAgICAgIC8vIGJvdHRvbS1ib3VuZGFyeSBzY2FuLCBwcm9kdWNpbmcgcGhhbnRvbSByZW5kZXJzIGF0IG91dC1vZi1ib3VuZHNcbiAgICAgICAgLy8gaW5kaWNlcyAodW5kZWZpbmVkIGl0ZW1zIOKGkiAwLWhlaWdodCByb3dzIOKGkiB0aGUgZmlsbCBsb29wIG5ldmVyXG4gICAgICAgIC8vIHNhdGlzZmllcyBpdHMgaGVpZ2h0IGNvbmRpdGlvbiDihpIgaHVuZHJlZHMgb2YgcmVuZGVyZXIgY2FsbGJhY2tzKS5cbiAgICAgICAgLy8gUmVjcmVhdGluZyB0aGUgZW5naW5lIGdpdmVzIGJvdGggdGhlIGVuZ2luZSBhbmQgdGhlIHJlbmRlcmVyIGEgZnJlc2gsXG4gICAgICAgIC8vIGNvbnNpc3RlbnQgY291bnQuICBlbnN1cmVJbml0aWFsaXplZCgpIHNjaGVkdWxlcyB0aGUgZmlyc3QgcmVuZGVyIHZpYVxuICAgICAgICAvLyBxdWV1ZU1pY3JvdGFzaywgd2hpY2ggcnVucyBhZnRlciB0aGUgY3VycmVudCBDRCBjeWNsZSBjb21wbGV0ZXMuXG4gICAgICAgIHRoaXMucmVjcmVhdGUoKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikge1xuICAgICAgICAvLyBTYW1lIGNvdW50LCBuZXcgZGF0YSByZWZlcmVuY2UgKGUuZy4gYW4gaW1tdXRhYmxlIGVkaXQgb3IgYSBzb3J0IHRoYXRcbiAgICAgICAgLy8gaGFwcGVucyB0byBrZWVwIHRoZSBzYW1lIGxlbmd0aCkuIFRoZSBlbmdpbmUgcmV1c2VzIHRoZSBET00gZWxlbWVudCBpdFxuICAgICAgICAvLyBhbHJlYWR5IHJlbmRlcmVkIGZvciBlYWNoIG92ZXJsYXBwaW5nIGluZGV4IHdpdGhvdXQgcmUtaW52b2tpbmcgdGhlXG4gICAgICAgIC8vIHJlbmRlcmVyLCBzbyB1cGRhdGUgdGhlIGNvbnRlbnQgb2YgZXZlcnkgY3VycmVudGx5LXZpc2libGUgcm93IElOXG4gICAgICAgIC8vIFBMQUNFIGJlZm9yZSBjYWxsaW5nIHJlbmRlcigpLiAgVGhpcyBwcmVzZXJ2ZXMgZWFjaCByb3cncyBlbWJlZGRlZFxuICAgICAgICAvLyB2aWV3IChzbyBhIGZvY3VzZWQgdGV4dGJveCBrZWVwcyBmb2N1cy9jYXJldCkgYW5kIGRvZXMgTk9UIGRpc2NhcmRcbiAgICAgICAgLy8gY2FjaGVkIGhlaWdodHMuIElmIGEgcm93J3MgaGVpZ2h0IGFjdHVhbGx5IGNoYW5nZXMgdGhlIGVuZ2luZSdzXG4gICAgICAgIC8vIFJlc2l6ZU9ic2VydmVyIGtlZXBzIHRoZSBjYWNoZSBjb3JyZWN0IG9uIGl0cyBvd247IGZvciBhIHdob2xlc2FsZVxuICAgICAgICAvLyBoZWlnaHQgY2hhbmdlIGFjcm9zcyBhbGwgcm93cywgY2FsbCByZWNhbGN1bGF0ZSgpIGluc3RlYWQuXG4gICAgICAgIHRoaXMucmVmcmVzaFJlbmRlcmVkQ29udGVudCgpO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsT3B0aW9ucyddICYmICFjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsT3B0aW9ucyddLmZpcnN0Q2hhbmdlKSB7XG4gICAgICAvLyBPcHRpb25zIGFyZSBjb25zdW1lZCBwcmltYXJpbHkgYXQgY29uc3RydWN0aW9uIHRpbWUuXG4gICAgICB0aGlzLnJlY3JlYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2NoZWR1bGVkUmVuZGVyRnJhbWUgIT0gbnVsbCkge1xuICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5zY2hlZHVsZWRSZW5kZXJGcmFtZSk7XG4gICAgICB0aGlzLnNjaGVkdWxlZFJlbmRlckZyYW1lID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLnZpZXdwb3J0U3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMudmlld3BvcnRTdWIgPSBudWxsO1xuXG4gICAgdGhpcy5kZXN0cm95QWxsVmlld3MoKTtcbiAgICB0aGlzLmhlYWRlclZpZXc/LmRlc3Ryb3koKTtcbiAgICB0aGlzLmhlYWRlclZpZXcgPSBudWxsO1xuXG4gICAgdGhpcy5ob3N0UmVmPy5kZXN0cm95KCk7XG4gICAgdGhpcy5ob3N0UmVmID0gbnVsbDtcbiAgfVxuXG4gIC8qKiBJbXBlcmF0aXZlbHkgdHJpZ2dlciBhIHJlbmRlciBwYXNzICh1c2VzIGBjZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlYCkuICovXG4gIHJlbmRlcigpOiBNZWFzdXJlZFZpZXdwb3J0UmFuZ2UgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZikgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgdGVtcGxhdGUgPSB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGU7XG4gICAgaWYgKCF0ZW1wbGF0ZSkgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBob3N0Q29udGFpbmVyID0gdGhpcy5ob3N0Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgaGVpZ2h0ID0gaG9zdENvbnRhaW5lci5jbGllbnRIZWlnaHQgfHwgaG9zdENvbnRhaW5lci5vZmZzZXRIZWlnaHQ7XG4gICAgY29uc3QgY29udGVudENvbnRhaW5lciA9IHRoaXMuaG9zdFJlZi5jb250ZW50RWxlbWVudDtcblxuICAgIC8vIFRyYWNrIHdoZXRoZXIgdGhlIGVuZ2luZSBhc2tlZCB1cyB0byBiaW5kIGFueSByb3cgdGhpcyBwYXNzLiBQdXJlIHNjcm9sbFxuICAgIC8vIGZyYW1lcyB3aGVyZSB0aGUgdmlzaWJsZSByb3cgc2V0IGRvZXNuJ3QgY2hhbmdlIHN0aWxsIGRyaXZlIHJlbmRlcigpIHZpYVxuICAgIC8vIHRoZSByQUYgY29hbGVzY2VyIOKAlCB0aGVyZSdzIG5vIHBvaW50IGluIHdhbGtpbmcgdGhlIHBydW5lIG1hcCBvclxuICAgIC8vIGVtaXR0aW5nIHRoZSB2aWV3cG9ydCByYW5nZSB3aGVuIG5vdGhpbmcgd2FzIHRvdWNoZWQuXG4gICAgbGV0IHJlbmRlcmVySW52b2NhdGlvbnMgPSAwO1xuICAgIGNvbnN0IHJlbmRlcmVyOiBFbGVtZW50UmVuZGVyZXIgPSAoaW5kZXgsIGVsZW1lbnRDb250YWluZXIpID0+IHtcbiAgICAgIHJlbmRlcmVySW52b2NhdGlvbnMrKztcbiAgICAgIC8vIFJlbmRlciBlYWNoIHJvdydzIGVtYmVkZGVkIHZpZXcgd2l0aCBMT0NBTCBjaGFuZ2UgZGV0ZWN0aW9uXG4gICAgICAvLyAoYHZpZXcuZGV0ZWN0Q2hhbmdlcygpYCBpbnNpZGUgYHJlbmRlclRlbXBsYXRlSW50b0NvbnRhaW5lcmApIHNvIHRoZVxuICAgICAgLy8gZW5naW5lIGNhbiBtZWFzdXJlIGl0cyBoZWlnaHQgZHVyaW5nIHRoaXMgcGFzcy4gRG8gTk9UIHdyYXAgZWFjaCByb3cgaW5cbiAgICAgIC8vIGl0cyBvd24gYG5nWm9uZS5ydW5gIOKAlCB0aGF0IGZpcmVzIGEgZnVsbCBgQXBwbGljYXRpb25SZWZgIHRpY2sgKnBlciByb3cqXG4gICAgICAvLyAoTyhuZXdSb3dzIMOXIHZpc2libGVSb3dzKSB3b3JrLCBqYW5reSBkcmFncykuIFRoZSBzaW5nbGUgY29hbGVzY2VkIHRpY2tcbiAgICAgIC8vIGZvciB0aGUgd2hvbGUgcGFzcyBpcyBoYW5kbGVkIGJ5IHRoZSBjYWxsZXIgKGBzY2hlZHVsZVJlbmRlcmApLlxuICAgICAgdGhpcy5yZW5kZXJUZW1wbGF0ZUludG9Db250YWluZXIodGVtcGxhdGUsIGluZGV4LCBlbGVtZW50Q29udGFpbmVyKTtcbiAgICB9O1xuXG4gICAgY29uc3QgcmFuZ2UgPSB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIucmVuZGVyVmlld3BvcnQoaGVpZ2h0LCBjb250ZW50Q29udGFpbmVyLCByZW5kZXJlcik7XG5cbiAgICBpZiAocmVuZGVyZXJJbnZvY2F0aW9ucyA9PT0gMCkge1xuICAgICAgLy8gVmlld3BvcnQgZGlkbid0IGNoYW5nZSDigJQgc2tpcCB0aGUgcHJ1bmUgd2FsayBhbmQgdGhlIChwb3RlbnRpYWxseVxuICAgICAgLy8gem9uZS1lbnRlcmluZykgZW1pdC5cbiAgICAgIHJldHVybiByYW5nZTtcbiAgICB9XG5cbiAgICAvLyBEZXN0cm95IHZpZXdzIHdob3NlIGNvbnRhaW5lciB0aGUgZW5naW5lIG5vIGxvbmdlciByZW5kZXJzLiBXaXRob3V0IHRoaXMsXG4gICAgLy8gZXZlcnkgY29udGFpbmVyIHRoZSBlbmdpbmUgcmVjeWNsZXMgaW50byBpdHMgZWxlbWVudCBwb29sIGxlYXZlcyBpdHNcbiAgICAvLyBlbWJlZGRlZCB2aWV3IGF0dGFjaGVkIHRvIEFwcGxpY2F0aW9uUmVmIGZvcmV2ZXIg4oCUIHNvIHRoZSBhdHRhY2hlZC12aWV3XG4gICAgLy8gbGlzdCAoYW5kIGV2ZXJ5IE8obikgYGRldGFjaFZpZXdgKSBncm93cyB3aXRob3V0IGJvdW5kIGFuZCBzY3JvbGxpbmcgZ2V0c1xuICAgIC8vIHByb2dyZXNzaXZlbHkgc2xvd2VyLiBNaXJyb3JzIHRoZSBSZWFjdC9WdWUgd3JhcHBlcnMsIHdoaWNoIGRyb3Agcm93cyB0aGF0XG4gICAgLy8gZmFsbCBvdXQgb2YgYGdldFJlbmRlcmVkSW5kaWNlcygpYC5cbiAgICB0aGlzLnBydW5lRGV0YWNoZWRWaWV3cygpO1xuXG4gICAgLy8gT25seSByZS1lbnRlciB0aGUgem9uZSAoYSBnbG9iYWwgdGljaykgaWYgc29tZW9uZSBpcyBhY3R1YWxseSBsaXN0ZW5pbmcuXG4gICAgaWYgKHRoaXMuY2VyaW91c1Njcm9sbE1lYXN1cmVkVmlld3BvcnQub2JzZXJ2ZWQpIHtcbiAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLmNlcmlvdXNTY3JvbGxNZWFzdXJlZFZpZXdwb3J0LmVtaXQocmFuZ2UpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG5cbiAgLyoqIFRlYXIgZG93biBlbWJlZGRlZCB2aWV3cyB3aG9zZSBjb250YWluZXIgaXMgbm8gbG9uZ2VyIHBhcnQgb2YgdGhlIHZpZXdwb3J0LiAqL1xuICBwcml2YXRlIHBydW5lRGV0YWNoZWRWaWV3cygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZiB8fCB0aGlzLnZpZXdCeUNvbnRhaW5lci5zaXplID09PSAwKSByZXR1cm47XG4gICAgY29uc3Qgc2Nyb2xsZXIgPSB0aGlzLmhvc3RSZWYuc2Nyb2xsZXI7XG4gICAgY29uc3QgYWN0aXZlID0gbmV3IFNldDxIVE1MRWxlbWVudD4oKTtcbiAgICBmb3IgKGNvbnN0IGluZGV4IG9mIHNjcm9sbGVyLmdldFJlbmRlcmVkSW5kaWNlcygpKSB7XG4gICAgICBjb25zdCBlbCA9IHNjcm9sbGVyLmdldFJlbmRlcmVkRWxlbWVudChpbmRleCk7XG4gICAgICBpZiAoZWwpIGFjdGl2ZS5hZGQoZWwpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtjb250YWluZXIsIHZpZXddIG9mIHRoaXMudmlld0J5Q29udGFpbmVyKSB7XG4gICAgICBpZiAoIWFjdGl2ZS5oYXMoY29udGFpbmVyKSkge1xuICAgICAgICAvLyBEZXRhY2ggRE9NIGJ1dCBrZWVwIHRoZSB2aWV3IGFsaXZlIGluIHRoZSBwb29sIGZvciBmdXR1cmUgcmV1c2UuXG4gICAgICAgIC8vIERlc3Ryb3lpbmcgKyByZWNyZWF0aW5nIHZpZXdzIHBlciBzY3JvbGwgc3RlcCBkb21pbmF0ZXMgZnJhbWUgdGltZS5cbiAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIHZpZXcucm9vdE5vZGVzKSB7XG4gICAgICAgICAgaWYgKG5vZGUucGFyZW50Tm9kZSkgbm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudmlld0J5Q29udGFpbmVyLmRlbGV0ZShjb250YWluZXIpO1xuICAgICAgICB0aGlzLmZyZWVWaWV3cy5wdXNoKHZpZXcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKiBBdXRvLXJlbmRlciBjb2FsZXNjZWQgdG8gYXQgbW9zdCBvbmNlIHBlciBhbmltYXRpb24gZnJhbWUuICovXG4gIHByaXZhdGUgc2NoZWR1bGVSZW5kZXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2NoZWR1bGVkUmVuZGVyRnJhbWUgIT0gbnVsbCkgcmV0dXJuO1xuICAgIHRoaXMuc2NoZWR1bGVkUmVuZGVyRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgdGhpcy5zY2hlZHVsZWRSZW5kZXJGcmFtZSA9IG51bGw7XG4gICAgICAvLyBSdW4gcmVuZGVyKCkgT1VUU0lERSBBbmd1bGFyJ3Mgem9uZS4gQSBmdWxsIEFwcGxpY2F0aW9uUmVmLnRpY2soKSBvblxuICAgICAgLy8gZXZlcnkgc2Nyb2xsIGZyYW1lIGlzIHRoZSBwcmltYXJ5IEZQUyBib3R0bGVuZWNrOiBldmVuIHdoZW4gbm8gcm93c1xuICAgICAgLy8gY2hhbmdlIChwdXJlIHRyYW5zbGF0aW9uKSwgbmdab25lLnJ1bigpIGNhdXNlcyBBbmd1bGFyIHRvIHdhbGsgdGhlXG4gICAgICAvLyBlbnRpcmUgY29tcG9uZW50IHRyZWUuIEluc3RlYWQgd2UgY2FsbCB2aWV3LmRldGVjdENoYW5nZXMoKSBsb2NhbGx5XG4gICAgICAvLyBpbnNpZGUgcmVuZGVyVGVtcGxhdGVJbnRvQ29udGFpbmVyIGZvciBlYWNoIGFmZmVjdGVkIHJvdy4gWm9uZSBlbnRyeSBpc1xuICAgICAgLy8gb25seSBuZWVkZWQgd2hlbiBjcmVhdGluZyBhIGJyYW5kLW5ldyBlbWJlZGRlZCB2aWV3ICh0byB6b25lLXBhdGNoIGl0c1xuICAgICAgLy8gZXZlbnQgbGlzdGVuZXJzKSDigJQgcmVjeWNsZWQgYW5kIHBvb2xlZCB2aWV3cyB3ZXJlIGFscmVhZHkgY3JlYXRlZCBpbnNpZGVcbiAgICAgIC8vIHpvbmUgYW5kIHRoZWlyIGxpc3RlbmVycyByZW1haW4gem9uZS1hd2FyZS5cbiAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGlzY2FyZCBhbGwgY2FjaGVkIHJvdyBoZWlnaHRzIGFuZCByZS1tZWFzdXJlIHRoZSB2aWV3cG9ydC5cbiAgICpcbiAgICogQ2FsbCB0aGlzIG9ubHkgd2hlbiB0aGUgaGVpZ2h0cyBvZiByb3dzIHlvdSd2ZSAqYWxyZWFkeSByZW5kZXJlZCogbWF5IGhhdmVcbiAgICogY2hhbmdlZCB3aXRob3V0IHRoZWlyIGluZGljZXMgY2hhbmdpbmcg4oCUIGUuZy4gYSBnbG9iYWwgZm9udC9kZW5zaXR5IGNoYW5nZSxcbiAgICogb3Igc3dhcHBpbmcgZXZlcnkgcm93IHRvIGEgZGlmZmVyZW50IGxheW91dC4gVGhpcyBmb3JjZXMgYSBzeW5jaHJvbm91c1xuICAgKiByZS1tZWFzdXJlIChvbmUgYG9mZnNldEhlaWdodGAgcmVhZCBwZXIgdmlzaWJsZSByb3cpLCBzbyBkbyBOT1QgY2FsbCBpdCBvblxuICAgKiByb3V0aW5lIGVkaXRzOiBhIHNpbmdsZSBjZWxsIGVkaXQga2VlcHMgaXRzIHJvdydzIHNpemUsIGFuZCB0aGUgZW5naW5lJ3NcbiAgICogUmVzaXplT2JzZXJ2ZXIgcGlja3MgdXAgYW55IGluY2lkZW50YWwgcmVzaXplIG9uIGl0cyBvd24uXG4gICAqL1xuICByZWNhbGN1bGF0ZSgpOiBNZWFzdXJlZFZpZXdwb3J0UmFuZ2UgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZikgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgdGVtcGxhdGUgPSB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGU7XG4gICAgaWYgKHRlbXBsYXRlKSB7XG4gICAgICAvLyBSZS1pbnZva2UgdGhlIHJlbmRlcmVyIGZvciBldmVyeSBjdXJyZW50bHktcmVuZGVyZWQgcm93IHNvIHBlbmRpbmdcbiAgICAgIC8vIEFuZ3VsYXIgYmluZGluZ3MgZmx1c2ggaW50byB0aGUgRE9NIGFuZCB0aGUgZW5naW5lIHJlLW1lYXN1cmVzIGVhY2hcbiAgICAgIC8vIHJvdydzIG5ldyBoZWlnaHQgaW50byBpdHMgY2FjaGUuIFdpdGhvdXQgdGhpcywgdGhlIGVuZ2luZSdzIHJlbmRlclxuICAgICAgLy8gcGFzcyBza2lwcyB0aGUgcmVuZGVyZXIgZm9yIGFscmVhZHktcmVuZGVyZWQgaW5kaWNlcyBhbmQgZmFsbHNcbiAgICAgIC8vIHRocm91Z2ggdG8gcmVhZGluZyBzdGFsZSBvZmZzZXRIZWlnaHQuXG4gICAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIucmVmcmVzaFZpc2libGUoKGluZGV4LCBlbGVtZW50Q29udGFpbmVyKSA9PiB7XG4gICAgICAgIHRoaXMucmVuZGVyVGVtcGxhdGVJbnRvQ29udGFpbmVyKHRlbXBsYXRlLCBpbmRleCwgZWxlbWVudENvbnRhaW5lcik7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKiogSnVtcCBkaXJlY3RseSB0byBhbiBlbGVtZW50IGluZGV4LCB0aGVuIHJlbmRlci4gKi9cbiAganVtcFRvRWxlbWVudChpbmRleDogbnVtYmVyKTogTWVhc3VyZWRWaWV3cG9ydFJhbmdlIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybiBudWxsO1xuICAgIHRoaXMuaG9zdFJlZi5zY3JvbGxlci5qdW1wVG9FbGVtZW50KGluZGV4KTtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBTY3JvbGwgdG8gYSBwZXJjZW50YWdlICgwLi4xMDApLCB0aGVuIHJlbmRlci4gKi9cbiAgc2Nyb2xsVG9QZXJjZW50YWdlKHBlcmNlbnRhZ2U6IG51bWJlcik6IE1lYXN1cmVkVmlld3BvcnRSYW5nZSB8IG51bGwge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm4gbnVsbDtcbiAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIuaGFuZGxlU2Nyb2xsUGVyY2VudGFnZShwZXJjZW50YWdlKTtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBSZXNldCB0byB0aGUgdG9wLCB0aGVuIHJlbmRlci4gKi9cbiAgcmVzZXQoKTogTWVhc3VyZWRWaWV3cG9ydFJhbmdlIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybiBudWxsO1xuICAgIHRoaXMuaG9zdFJlZi5zY3JvbGxlci5yZXNldCgpO1xuICAgIHJldHVybiB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWNyZWF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLnZpZXdwb3J0U3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMudmlld3BvcnRTdWIgPSBudWxsO1xuXG4gICAgdGhpcy5kZXN0cm95QWxsVmlld3MoKTtcblxuICAgIHRoaXMuaG9zdFJlZj8uZGVzdHJveSgpO1xuICAgIHRoaXMuaG9zdFJlZiA9IG51bGw7XG5cbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZUluaXRpYWxpemVkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhvc3RSZWYpIHJldHVybjtcblxuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuaG9zdC5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IHRvdGFsID0gY29lcmNlVG90YWxFbGVtZW50cyh0aGlzLmNlcmlvdXNTY3JvbGxUb3RhbEVsZW1lbnRzLCB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtcz8ubGVuZ3RoID8/IG51bGwpO1xuXG4gICAgLy8gVGFibGUgbW9kZTogY2FwdHVyZSB0aGUgZW5naW5lLWNyZWF0ZWQgPHRoZWFkPiBzbyB3ZSBjYW4gcmVuZGVyIHRoZVxuICAgIC8vIGRlY2xhcmF0aXZlIGhlYWRlciB0ZW1wbGF0ZSBpbnRvIGl0IChhbmQgc3RpbGwgcnVuIGFueSB1c2VyIGhlYWRlciBob29rKS5cbiAgICBsZXQgb3B0aW9ucyA9IHRoaXMuY2VyaW91c1Njcm9sbE9wdGlvbnM7XG4gICAgaWYgKG9wdGlvbnMubGF5b3V0ID09PSAndGFibGUnICYmIHRoaXMuY2VyaW91c1Njcm9sbEhlYWRlclRlbXBsYXRlKSB7XG4gICAgICBjb25zdCB1c2VySGVhZGVyID0gb3B0aW9ucy50YWJsZT8uaGVhZGVyO1xuICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgdGFibGU6IHtcbiAgICAgICAgICAuLi5vcHRpb25zLnRhYmxlLFxuICAgICAgICAgIGhlYWRlcjogKHRoZWFkOiBIVE1MVGFibGVTZWN0aW9uRWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgdXNlckhlYWRlcj8uKHRoZWFkKTtcbiAgICAgICAgICAgIHRoaXMubW91bnRIZWFkZXIodGhlYWQpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMuaG9zdFJlZiA9IHRoaXMuY2VyaW91cy5jcmVhdGVIb3N0KGNvbnRhaW5lciwgdG90YWwsIG9wdGlvbnMsIHRoaXMubmdab25lLCAoKSA9PiB7XG4gICAgICAvLyBDb2FsZXNjZSBzY3JvbGwtZHJpdmVuIHJlbmRlcnMgdG8gb25lIHBlciBmcmFtZSAodGhlIG5hdGl2ZSBzY3JvbGxiYXJcbiAgICAgIC8vIGNhbiBmaXJlIG1hbnkgc2Nyb2xsIGV2ZW50cyBiZXR3ZWVuIHBhaW50cykuXG4gICAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikgdGhpcy5zY2hlZHVsZVJlbmRlcigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy52aWV3cG9ydFN1YiA9IHRoaXMuaG9zdFJlZi52aWV3cG9ydENoYW5nZXMkLnN1YnNjcmliZSgoZGV0YWlsOiBDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWwpID0+IHtcbiAgICAgIC8vIFNraXAgdGhlIGdsb2JhbCB0aWNrIHdoZW4gbm9ib2R5IGlzIGJvdW5kIHRvIHRoZSBvdXRwdXQuXG4gICAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsVmlld3BvcnRDaGFuZ2Uub2JzZXJ2ZWQpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuY2VyaW91c1Njcm9sbFZpZXdwb3J0Q2hhbmdlLmVtaXQoZGV0YWlsKSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmNlcmlvdXNTY3JvbGxSZWFkeS5lbWl0KHRoaXMuaG9zdFJlZi5zY3JvbGxlcik7XG5cbiAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikge1xuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy5yZW5kZXIoKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgZGVjbGFyYXRpdmUgaGVhZGVyIHRlbXBsYXRlIGludG8gdGhlIGVuZ2luZSdzIDx0aGVhZD4uIE9uZVxuICAgKiBlbWJlZGRlZCB2aWV3LCBjcmVhdGVkIGluc2lkZSB0aGUgem9uZSAoc28gdGhlIGhlYWRlcidzIGV2ZW50IGJpbmRpbmdzIGFyZVxuICAgKiB6b25lLXBhdGNoZWQpLCBpdHMgcm9vdCBub2RlcyBhcHBlbmRlZCBkaXJlY3RseSBpbnRvIHRoZSA8dGhlYWQ+LlxuICAgKi9cbiAgcHJpdmF0ZSBtb3VudEhlYWRlcih0aGVhZDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2VyaW91c1Njcm9sbEhlYWRlclRlbXBsYXRlKSByZXR1cm47XG4gICAgdGhpcy5oZWFkZXJWaWV3Py5kZXN0cm95KCk7XG4gICAgY29uc3QgdmlldyA9IHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICBjb25zdCB2ID0gdGhpcy5jZXJpb3VzU2Nyb2xsSGVhZGVyVGVtcGxhdGUhLmNyZWF0ZUVtYmVkZGVkVmlldyh7fSk7XG4gICAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHYpO1xuICAgICAgdi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICByZXR1cm4gdjtcbiAgICB9KTtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygdmlldy5yb290Tm9kZXMpIHRoZWFkLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgIHRoaXMuaGVhZGVyVmlldyA9IHZpZXc7XG4gIH1cblxuICBwcml2YXRlIGdldEl0ZW1Gb3JJbmRleChpbmRleDogbnVtYmVyKTogVEl0ZW0ge1xuICAgIGNvbnN0IGdldHRlciA9IHRoaXMuY2VyaW91c1Njcm9sbEdldEl0ZW07XG4gICAgaWYgKGdldHRlcikgcmV0dXJuIGdldHRlcihpbmRleCk7XG5cbiAgICBjb25zdCBpdGVtcyA9IHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1zO1xuICAgIGlmICghaXRlbXMpIHJldHVybiB1bmRlZmluZWQgYXMgVEl0ZW07XG5cbiAgICByZXR1cm4gaXRlbXNbaW5kZXhdO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJUZW1wbGF0ZUludG9Db250YWluZXIoXG4gICAgdGVtcGxhdGU6IFRlbXBsYXRlUmVmPENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVDb250ZXh0PFRJdGVtPj4sXG4gICAgaW5kZXg6IG51bWJlcixcbiAgICBlbGVtZW50Q29udGFpbmVyOiBIVE1MRWxlbWVudFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMudmlld0J5Q29udGFpbmVyLmdldChlbGVtZW50Q29udGFpbmVyKTtcbiAgICBpZiAocHJldmlvdXMpIHtcbiAgICAgIC8vIFJlY3ljbGU6IHVwZGF0ZSB0aGUgYm91bmQgY29udGV4dCBhbmQgcnVuIGxvY2FsIENEIGluc3RlYWQgb2ZcbiAgICAgIC8vIGRlc3Ryb3lpbmcgdGhlIGVtYmVkZGVkIHZpZXcgYW5kIHJlYnVpbGRpbmcgdGhlIGVudGlyZSByb3cgdHJlZS5cbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmdldEl0ZW1Gb3JJbmRleChpbmRleCk7XG4gICAgICBwcmV2aW91cy5jb250ZXh0LiRpbXBsaWNpdCA9IGl0ZW07XG4gICAgICBwcmV2aW91cy5jb250ZXh0Lml0ZW0gPSBpdGVtO1xuICAgICAgcHJldmlvdXMuY29udGV4dC5pbmRleCA9IGluZGV4O1xuICAgICAgLy8gVGhlIGNvcmUgZW5naW5lIHdpcGVzIGVsZW1lbnRDb250YWluZXIudGV4dENvbnRlbnQgd2hlbiByZXVzaW5nIGl0IGZyb21cbiAgICAgIC8vIGl0cyBwb29sLCBvcnBoYW5pbmcgdGhlIHZpZXcncyByb290IG5vZGVzLiBSZS1hcHBlbmQgdGhlbSBkZWZlbnNpdmVseS5cbiAgICAgIGlmIChwcmV2aW91cy5yb290Tm9kZXMubGVuZ3RoICYmIHByZXZpb3VzLnJvb3ROb2Rlc1swXS5wYXJlbnROb2RlICE9PSBlbGVtZW50Q29udGFpbmVyKSB7XG4gICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBwcmV2aW91cy5yb290Tm9kZXMpIHtcbiAgICAgICAgICBlbGVtZW50Q29udGFpbmVyLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBwcmV2aW91cy5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVHJ5IHRvIHJldXNlIGEgcG9vbGVkIHZpZXcgZnJvbSBhIGNvbnRhaW5lciB0aGF0IHNjcm9sbGVkIG91dCBvZiB2aWV3cG9ydC5cbiAgICBjb25zdCBwb29sZWQgPSB0aGlzLmZyZWVWaWV3cy5wb3AoKTtcbiAgICBpZiAocG9vbGVkKSB7XG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5nZXRJdGVtRm9ySW5kZXgoaW5kZXgpO1xuICAgICAgcG9vbGVkLmNvbnRleHQuJGltcGxpY2l0ID0gaXRlbTtcbiAgICAgIHBvb2xlZC5jb250ZXh0Lml0ZW0gPSBpdGVtO1xuICAgICAgcG9vbGVkLmNvbnRleHQuaW5kZXggPSBpbmRleDtcbiAgICAgIGVsZW1lbnRDb250YWluZXIudGV4dENvbnRlbnQgPSAnJztcbiAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBwb29sZWQucm9vdE5vZGVzKSB7XG4gICAgICAgIGVsZW1lbnRDb250YWluZXIuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgICB9XG4gICAgICBwb29sZWQuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgdGhpcy52aWV3QnlDb250YWluZXIuc2V0KGVsZW1lbnRDb250YWluZXIsIHBvb2xlZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gTm8gcHJpb3IgdmlldyBmb3IgdGhpcyBjb250YWluZXI6IGNyZWF0ZSBvbmUuXG4gICAgLy8gRW50ZXIgdGhlIEFuZ3VsYXIgem9uZSBzbyB0aGUgbmV3IHZpZXcncyB0ZW1wbGF0ZSBldmVudCBsaXN0ZW5lcnNcbiAgICAvLyAoKGNsaWNrKSwgKGlucHV0KSwgZXRjLikgYXJlIHpvbmUtcGF0Y2hlZC4gVGhpcyBwYXRoIHJ1bnMgYXQgbW9zdFxuICAgIC8vIG9uY2UgcGVyIHZpc2libGUgcm93IChhZnRlciB0aGF0LCB0aGUgdmlldyBpcyByZWN5Y2xlZCBmcm9tIHRoZSBwb29sKS5cbiAgICBlbGVtZW50Q29udGFpbmVyLnRleHRDb250ZW50ID0gJyc7XG5cbiAgICBjb25zdCBpdGVtID0gdGhpcy5nZXRJdGVtRm9ySW5kZXgoaW5kZXgpO1xuICAgIGNvbnN0IHZpZXcgPSB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgY29uc3QgdiA9IHRlbXBsYXRlLmNyZWF0ZUVtYmVkZGVkVmlldyh7ICRpbXBsaWNpdDogaXRlbSwgaXRlbSwgaW5kZXggfSk7XG4gICAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHYpO1xuICAgICAgdi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICByZXR1cm4gdjtcbiAgICB9KTtcblxuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB2aWV3LnJvb3ROb2Rlcykge1xuICAgICAgZWxlbWVudENvbnRhaW5lci5hcHBlbmRDaGlsZChub2RlKTtcbiAgICB9XG5cbiAgICB0aGlzLnZpZXdCeUNvbnRhaW5lci5zZXQoZWxlbWVudENvbnRhaW5lciwgdmlldyk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHRoZSBib3VuZCBpdGVtL2luZGV4IG9uIGV2ZXJ5IGN1cnJlbnRseS1yZW5kZXJlZCByb3cncyBlbWJlZGRlZCB2aWV3XG4gICAqIGFuZCBydW4gY2hhbmdlIGRldGVjdGlvbiwgd2l0aG91dCByZWNyZWF0aW5nIHRoZSB2aWV3cy4gVXNlZCB3aGVuIHRoZSBkYXRhXG4gICAqIHJlZmVyZW5jZSBjaGFuZ2VzIGJ1dCB0aGUgdmlzaWJsZSBpbmRpY2VzIChhbmQgdGhlaXIgaGVpZ2h0cykgZG8gbm90LCBzbyByb3dcbiAgICogc3RhdGUgKGZvY3VzLCBzZWxlY3Rpb24sIG9wZW4gZHJvcGRvd25zKSBzdXJ2aXZlcyB0aGUgdXBkYXRlLlxuICAgKi9cbiAgLyoqXG4gICAqIFJlLWJpbmQgZWFjaCBjdXJyZW50bHkgcmVuZGVyZWQgcm93J3MgY29udGV4dCAoZnJvbSB0aGUgY3VycmVudCBpdGVtcy9nZXR0ZXIpXG4gICAqIGFuZCBydW4gY2hhbmdlIGRldGVjdGlvbiBvbiBpdHMgZW1iZWRkZWQgdmlldy4gVXNlIHRoaXMgYWZ0ZXIgbXV0YXRpbmcgcm93XG4gICAqIHN0YXRlIGluIHBsYWNlIChlLmcuIHNlbGVjdGlvbiBmbGFncykgb3IgY29sdW1uLWxldmVsIHN0YXRlIHJlYWQgYnkgdGhlIHJvd1xuICAgKiB0ZW1wbGF0ZSwgd2hlbiByb3cgaWRlbnRpdHkgYW5kIHZpc2libGUgaW5kaWNlcyBoYXZlIG5vdCBjaGFuZ2VkLiBDaGVhcFxuICAgKiByZWxhdGl2ZSB0byBgcmVuZGVyKClgIOKAlCBkb2VzIG5vdCBpbnZva2UgdGhlIGVuZ2luZSdzIG1lYXN1cmVtZW50IHBhc3MuXG4gICAqL1xuICByZWZyZXNoUmVuZGVyZWRDb250ZW50KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm47XG4gICAgY29uc3Qgc2Nyb2xsZXIgPSB0aGlzLmhvc3RSZWYuc2Nyb2xsZXI7XG5cbiAgICBmb3IgKGNvbnN0IGluZGV4IG9mIHNjcm9sbGVyLmdldFJlbmRlcmVkSW5kaWNlcygpKSB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSBzY3JvbGxlci5nZXRSZW5kZXJlZEVsZW1lbnQoaW5kZXgpO1xuICAgICAgaWYgKCFjb250YWluZXIpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCB2aWV3ID0gdGhpcy52aWV3QnlDb250YWluZXIuZ2V0KGNvbnRhaW5lcik7XG4gICAgICBpZiAoIXZpZXcpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5nZXRJdGVtRm9ySW5kZXgoaW5kZXgpO1xuICAgICAgdmlldy5jb250ZXh0LiRpbXBsaWNpdCA9IGl0ZW07XG4gICAgICB2aWV3LmNvbnRleHQuaXRlbSA9IGl0ZW07XG4gICAgICB2aWV3LmNvbnRleHQuaW5kZXggPSBpbmRleDtcbiAgICAgIHZpZXcuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveUFsbFZpZXdzKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgdmlldyBvZiB0aGlzLnZpZXdCeUNvbnRhaW5lci52YWx1ZXMoKSkge1xuICAgICAgdGhpcy5hcHBSZWYuZGV0YWNoVmlldyh2aWV3KTtcbiAgICAgIHZpZXcuZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLnZpZXdCeUNvbnRhaW5lci5jbGVhcigpO1xuICAgIGZvciAoY29uc3QgdmlldyBvZiB0aGlzLmZyZWVWaWV3cykge1xuICAgICAgdGhpcy5hcHBSZWYuZGV0YWNoVmlldyh2aWV3KTtcbiAgICAgIHZpZXcuZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLmZyZWVWaWV3cy5sZW5ndGggPSAwO1xuICB9XG59XG4iXX0=
445
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNlcmlvdXMtc2Nyb2xsL3NyYy9saWIvY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFHTCxTQUFTLEVBR1QsWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEdBR1AsTUFBTSxlQUFlLENBQUM7OztBQWF2QixTQUFTLG1CQUFtQixDQUFDLGFBQXdDLEVBQUUsUUFBbUM7SUFDeEcsTUFBTSxTQUFTLEdBQUcsT0FBTyxhQUFhLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDMUgsSUFBSSxTQUFTLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUN2RCxNQUFNLElBQUksS0FBSyxDQUFDLHVGQUF1RixDQUFDLENBQUM7SUFDM0csQ0FBQztJQUNELHdDQUF3QztJQUN4QyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ2hDLENBQUM7QUFNRCxNQUFNLE9BQU8sc0JBQXNCO0lBa0RqQyxZQUNtQixJQUE2QixFQUM3QixNQUFzQixFQUN0QixNQUFjLEVBQ2QsT0FBNkI7UUFIN0IsU0FBSSxHQUFKLElBQUksQ0FBeUI7UUFDN0IsV0FBTSxHQUFOLE1BQU0sQ0FBZ0I7UUFDdEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFlBQU8sR0FBUCxPQUFPLENBQXNCO1FBckRoRCxtRkFBbUY7UUFDMUUsK0JBQTBCLEdBQWtCLElBQUksQ0FBQztRQUUxRCxpREFBaUQ7UUFDeEMsdUJBQWtCLEdBQTRCLElBQUksQ0FB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QUFDO29CQUNULFFBQVEsRUFBRSxpQkFBaUI7b0JBQzNCLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjtvS0FHVSwwQkFBMEI7c0JBQWxDLEtBQUs7Z0JBR0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUdHLG9CQUFvQjtzQkFBNUIsS0FBSztnQkFHRyx5QkFBeUI7c0JBQWpDLEtBQUs7Z0JBT0csMkJBQTJCO3NCQUFuQyxLQUFLO2dCQUdHLG9CQUFvQjtzQkFBNUIsS0FBSztnQkFHRyx1QkFBdUI7c0JBQS9CLEtBQUs7Z0JBR0ksMkJBQTJCO3NCQUFwQyxNQUFNO2dCQUdHLDZCQUE2QjtzQkFBdEMsTUFBTTtnQkFHRyxrQkFBa0I7c0JBQTNCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBBcHBsaWNhdGlvblJlZixcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFbWJlZGRlZFZpZXdSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVGVtcGxhdGVSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQge1xuICB0eXBlIENlcmlvdXNTY3JvbGxPcHRpb25zLFxuICB0eXBlIEVsZW1lbnRSZW5kZXJlcixcbiAgdHlwZSBNZWFzdXJlZFZpZXdwb3J0UmFuZ2UsXG59IGZyb20gJ0BjZXJpb3VzZGV2dGVjaC9jZXJpb3VzLXNjcm9sbCc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHR5cGUgeyBDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWwgfSBmcm9tICcuL2NlcmlvdXMtc2Nyb2xsLnR5cGVzJztcbmltcG9ydCB0eXBlIHsgQ2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQgfSBmcm9tICcuL2NlcmlvdXMtc2Nyb2xsLWl0ZW0tdGVtcGxhdGUuZGlyZWN0aXZlJztcbmltcG9ydCB7IHR5cGUgQ2VyaW91c1Njcm9sbEhvc3RSZWYsIENlcmlvdXNTY3JvbGxTZXJ2aWNlIH0gZnJvbSAnLi9jZXJpb3VzLXNjcm9sbC5zZXJ2aWNlJztcblxuZnVuY3Rpb24gY29lcmNlVG90YWxFbGVtZW50cyhleHBsaWNpdFRvdGFsOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkLCBpdGVtc0xlbjogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCk6IG51bWJlciB7XG4gIGNvbnN0IGNhbmRpZGF0ZSA9IHR5cGVvZiBleHBsaWNpdFRvdGFsID09PSAnbnVtYmVyJyA/IGV4cGxpY2l0VG90YWwgOiB0eXBlb2YgaXRlbXNMZW4gPT09ICdudW1iZXInID8gaXRlbXNMZW4gOiB1bmRlZmluZWQ7XG4gIGlmIChjYW5kaWRhdGUgPT09IHVuZGVmaW5lZCB8fCBOdW1iZXIuaXNOYU4oY2FuZGlkYXRlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2VyaW91c1Njcm9sbERpcmVjdGl2ZTogcHJvdmlkZSBgY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHNgIG9yIGBjZXJpb3VzU2Nyb2xsSXRlbXNgLicpO1xuICB9XG4gIC8vIENlcmlvdXNTY3JvbGwgY3VycmVudGx5IHJlcXVpcmVzID49IDFcbiAgcmV0dXJuIE1hdGgubWF4KDEsIGNhbmRpZGF0ZSk7XG59XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tjZXJpb3VzU2Nyb2xsXScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIENlcmlvdXNTY3JvbGxEaXJlY3RpdmU8VEl0ZW0gPSB1bmtub3duPiBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcbiAgLyoqIFRvdGFsIG51bWJlciBvZiBpdGVtcy4gSWYgb21pdHRlZCwgZGVyaXZlZCBmcm9tIGBjZXJpb3VzU2Nyb2xsSXRlbXMubGVuZ3RoYC4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHM6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBPcHRpb25hbCBpdGVtcyBhcnJheSAoZW5hYmxlcyBgbGV0LWl0ZW1gKS4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbEl0ZW1zOiByZWFkb25seSBUSXRlbVtdIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIE9wdGlvbmFsIGdldHRlciBmb3IgbGFyZ2UgZGF0YXNldHMgKGFsdGVybmF0aXZlIHRvIHBhc3NpbmcgZnVsbCBgaXRlbXNgKS4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbEdldEl0ZW06ICgoaW5kZXg6IG51bWJlcikgPT4gVEl0ZW0pIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIFRlbXBsYXRlIHVzZWQgdG8gcmVuZGVyIGVhY2ggcm93LiAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlQ29udGV4dDxUSXRlbT4+IHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFRhYmxlIG1vZGUgb25seTogdGVtcGxhdGUgcmVuZGVyZWQgaW50byB0aGUgZW5naW5lJ3MgYDx0aGVhZD5gIChhIGA8dHI+YCBvZlxuICAgKiBgPHRoPmBzKS4gSXQgbGl2ZXMgaW4gdGhlIHNhbWUgYDx0YWJsZT5gIGFzIHRoZSByb3dzLCBzbyBjb2x1bW5zIGFsaWduXG4gICAqIG5hdGl2ZWx5LiBVcGRhdGVzIHZpYSBjaGFuZ2UgZGV0ZWN0aW9uIGxpa2UgdGhlIHJvd3MuXG4gICAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsSGVhZGVyVGVtcGxhdGU6IFRlbXBsYXRlUmVmPHVua25vd24+IHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIE9wdGlvbnMgcGFzc2VkIHRvIGBuZXcgQ2VyaW91c1Njcm9sbCguLi4pYC4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbE9wdGlvbnM6IENlcmlvdXNTY3JvbGxPcHRpb25zID0ge307XG5cbiAgLyoqIEF1dG9tYXRpY2FsbHkgY2FsbCByZW5kZXIgYWZ0ZXIgZWFjaCBzY3JvbGwgZXZlbnQuIERlZmF1bHQ6IHRydWUgKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbEF1dG9SZW5kZXIgPSB0cnVlO1xuXG4gIC8qKiBFbWl0cyBgY2VyaW91cy12aWV3cG9ydC1jaGFuZ2VgIGRldGFpbC4gKi9cbiAgQE91dHB1dCgpIGNlcmlvdXNTY3JvbGxWaWV3cG9ydENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Q2VyaW91c1ZpZXdwb3J0Q2hhbmdlRGV0YWlsPigpO1xuXG4gIC8qKiBFbWl0cyB0aGUgbGFzdCBtZWFzdXJlZCB2aWV3cG9ydCBhZnRlciBlYWNoIHJlbmRlciBwYXNzLiAqL1xuICBAT3V0cHV0KCkgY2VyaW91c1Njcm9sbE1lYXN1cmVkVmlld3BvcnQgPSBuZXcgRXZlbnRFbWl0dGVyPE1lYXN1cmVkVmlld3BvcnRSYW5nZT4oKTtcblxuICAvKiogRW1pdHMgb25jZSB0aGUgdW5kZXJseWluZyBgQ2VyaW91c1Njcm9sbGAgaW5zdGFuY2UgaXMgcmVhZHkuICovXG4gIEBPdXRwdXQoKSBjZXJpb3VzU2Nyb2xsUmVhZHkgPSBuZXcgRXZlbnRFbWl0dGVyPENlcmlvdXNTY3JvbGxIb3N0UmVmWydzY3JvbGxlciddPigpO1xuXG4gIHByaXZhdGUgaG9zdFJlZjogQ2VyaW91c1Njcm9sbEhvc3RSZWYgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB2aWV3cG9ydFN1YjogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc2NoZWR1bGVkUmVuZGVyRnJhbWU6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgdmlld0J5Q29udGFpbmVyID0gbmV3IE1hcDxIVE1MRWxlbWVudCwgRW1iZWRkZWRWaWV3UmVmPENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVDb250ZXh0PFRJdGVtPj4+KCk7XG4gIC8vIFBvb2wgb2Ygdmlld3MgZGV0YWNoZWQgYmVjYXVzZSB0aGVpciBjb250YWluZXIgbGVmdCB0aGUgdmlld3BvcnQuIFJldXNpbmdcbiAgLy8gdGhlbSBvbiBzdWJzZXF1ZW50IHJlbmRlcnMgYXZvaWRzIGRlc3Ryb3lpbmcgKyByZWNyZWF0aW5nIHRoZSBlbnRpcmUgcm93XG4gIC8vIGNvbXBvbmVudCB0cmVlIG9uIGZhc3Qgc2Nyb2xscyAod2hlcmUgdGhlIGVuZ2luZSdzIGVsZW1lbnQgcG9vbCB3aXBlc1xuICAvLyB0ZXh0Q29udGVudCBvbiByZXVzZWQgY29udGFpbmVycywgc28gdmlldyByb290Tm9kZXMgZ2V0IG9ycGhhbmVkKS5cbiAgcHJpdmF0ZSByZWFkb25seSBmcmVlVmlld3M6IEVtYmVkZGVkVmlld1JlZjxDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlQ29udGV4dDxUSXRlbT4+W10gPSBbXTtcblxuICAvLyBUYWJsZSBtb2RlOiB0aGUgZW1iZWRkZWQgdmlldyBvZiB0aGUgZGVjbGFyYXRpdmUgaGVhZGVyLCByZW5kZXJlZCBpbnRvIHRoZVxuICAvLyBlbmdpbmUncyA8dGhlYWQ+LlxuICBwcml2YXRlIGhlYWRlclZpZXc6IEVtYmVkZGVkVmlld1JlZjx1bmtub3duPiB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaG9zdDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgcHJpdmF0ZSByZWFkb25seSBhcHBSZWY6IEFwcGxpY2F0aW9uUmVmLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbmdab25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjZXJpb3VzOiBDZXJpb3VzU2Nyb2xsU2VydmljZVxuICApIHt9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZikgcmV0dXJuO1xuXG4gICAgaWYgKGNoYW5nZXNbJ2NlcmlvdXNTY3JvbGxJdGVtcyddIHx8IGNoYW5nZXNbJ2NlcmlvdXNTY3JvbGxUb3RhbEVsZW1lbnRzJ10pIHtcbiAgICAgIGNvbnN0IHRvdGFsID0gY29lcmNlVG90YWxFbGVtZW50cyh0aGlzLmNlcmlvdXNTY3JvbGxUb3RhbEVsZW1lbnRzLCB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtcz8ubGVuZ3RoID8/IG51bGwpO1xuICAgICAgY29uc3QgY291bnRDaGFuZ2VkID0gdGhpcy5ob3N0UmVmLnNjcm9sbGVyLnRvdGFsRWxlbWVudHMgIT09IHRvdGFsO1xuXG4gICAgICBpZiAoY291bnRDaGFuZ2VkKSB7XG4gICAgICAgIC8vIEdyb3cvc2hyaW5rIHRoZSBkYXRhc2V0IElOIFBMQUNFIOKAlCBubyByZWNyZWF0ZS4gdXBkYXRlVG90YWxFbGVtZW50c1xuICAgICAgICAvLyBwcm9wYWdhdGVzIHRoZSBuZXcgY291bnQgdG8gZXZlcnkgc3Vic3lzdGVtLCBJTkNMVURJTkcgdGhlXG4gICAgICAgIC8vIFZpZXdwb3J0UmVuZGVyZXIncyBvd24gY29weSBvZiB0b3RhbEVsZW1lbnRzIChpdCB1c2VkIHRvIGdvIHN0YWxlLFxuICAgICAgICAvLyB3aGljaCBpcyBleGFjdGx5IHdoeSB0aGlzIHJlY3JlYXRlZDogdGhlIHJlbmRlcmVyIGtlcHQgdGhlIG9sZCBjb3VudFxuICAgICAgICAvLyBmb3IgaXRzIHZpZXdwb3J0LWZpbGwgbG9vcCBhbmQgYm90dG9tIHNjYW4sIHByb2R1Y2luZyBwaGFudG9tXG4gICAgICAgIC8vIG91dC1vZi1ib3VuZHMgcmVuZGVycykuIEluIHBsYWNlIGtlZXBzIHRoZSBzY3JvbGwgcG9zaXRpb24gYW5kIGFuXG4gICAgICAgIC8vIGluLXByb2dyZXNzIHNjcm9sbGJhciBkcmFnIGFsaXZlLCBhbmQgYSBncm93aW5nIGRhdGFzZXQga2VlcHMgYSBzdGFibGVcbiAgICAgICAgLy8gYm90dG9tIGluZGV4IChubyBib3VuY2luZyB0YWlsKS4gVGhlIHRyYWNrIGxlbmd0aGVucywgc28gcmUtc3luYyB0aGVcbiAgICAgICAgLy8gdGh1bWIgYWZ0ZXJ3YXJkcy5cbiAgICAgICAgdGhpcy5ob3N0UmVmLnNjcm9sbGVyLnVwZGF0ZVRvdGFsRWxlbWVudHModG90YWwpO1xuICAgICAgICAvLyBBIHNocmluayBjYW4gbGVhdmUgdGhlIHBvc2l0aW9uIHBhc3QgdGhlIG5ldyBlbmQg4oCUIGNsYW1wIGl0LlxuICAgICAgICBpZiAodGhpcy5ob3N0UmVmLnNjcm9sbGVyLmN1cnJlbnRFbGVtZW50ID4gdG90YWwgLSAxKSB7XG4gICAgICAgICAgdGhpcy5ob3N0UmVmLnNjcm9sbGVyLmp1bXBUb0VsZW1lbnQodG90YWwgLSAxKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgdGhpcy5ob3N0UmVmLnNjcm9sbGVyLnN5bmNTY3JvbGxiYXIoKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikge1xuICAgICAgICAvLyBTYW1lIGNvdW50LCBuZXcgZGF0YSByZWZlcmVuY2UgKGUuZy4gYW4gaW1tdXRhYmxlIGVkaXQgb3IgYSBzb3J0IHRoYXRcbiAgICAgICAgLy8gaGFwcGVucyB0byBrZWVwIHRoZSBzYW1lIGxlbmd0aCkuIFRoZSBlbmdpbmUgcmV1c2VzIHRoZSBET00gZWxlbWVudCBpdFxuICAgICAgICAvLyBhbHJlYWR5IHJlbmRlcmVkIGZvciBlYWNoIG92ZXJsYXBwaW5nIGluZGV4IHdpdGhvdXQgcmUtaW52b2tpbmcgdGhlXG4gICAgICAgIC8vIHJlbmRlcmVyLCBzbyB1cGRhdGUgdGhlIGNvbnRlbnQgb2YgZXZlcnkgY3VycmVudGx5LXZpc2libGUgcm93IElOXG4gICAgICAgIC8vIFBMQUNFIGJlZm9yZSBjYWxsaW5nIHJlbmRlcigpLiAgVGhpcyBwcmVzZXJ2ZXMgZWFjaCByb3cncyBlbWJlZGRlZFxuICAgICAgICAvLyB2aWV3IChzbyBhIGZvY3VzZWQgdGV4dGJveCBrZWVwcyBmb2N1cy9jYXJldCkgYW5kIGRvZXMgTk9UIGRpc2NhcmRcbiAgICAgICAgLy8gY2FjaGVkIGhlaWdodHMuIElmIGEgcm93J3MgaGVpZ2h0IGFjdHVhbGx5IGNoYW5nZXMgdGhlIGVuZ2luZSdzXG4gICAgICAgIC8vIFJlc2l6ZU9ic2VydmVyIGtlZXBzIHRoZSBjYWNoZSBjb3JyZWN0IG9uIGl0cyBvd247IGZvciBhIHdob2xlc2FsZVxuICAgICAgICAvLyBoZWlnaHQgY2hhbmdlIGFjcm9zcyBhbGwgcm93cywgY2FsbCByZWNhbGN1bGF0ZSgpIGluc3RlYWQuXG4gICAgICAgIHRoaXMucmVmcmVzaFJlbmRlcmVkQ29udGVudCgpO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsT3B0aW9ucyddICYmICFjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsT3B0aW9ucyddLmZpcnN0Q2hhbmdlKSB7XG4gICAgICAvLyBPcHRpb25zIGFyZSBjb25zdW1lZCBwcmltYXJpbHkgYXQgY29uc3RydWN0aW9uIHRpbWUuXG4gICAgICB0aGlzLnJlY3JlYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2NoZWR1bGVkUmVuZGVyRnJhbWUgIT0gbnVsbCkge1xuICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5zY2hlZHVsZWRSZW5kZXJGcmFtZSk7XG4gICAgICB0aGlzLnNjaGVkdWxlZFJlbmRlckZyYW1lID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLnZpZXdwb3J0U3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMudmlld3BvcnRTdWIgPSBudWxsO1xuXG4gICAgdGhpcy5kZXN0cm95QWxsVmlld3MoKTtcbiAgICB0aGlzLmhlYWRlclZpZXc/LmRlc3Ryb3koKTtcbiAgICB0aGlzLmhlYWRlclZpZXcgPSBudWxsO1xuXG4gICAgdGhpcy5ob3N0UmVmPy5kZXN0cm95KCk7XG4gICAgdGhpcy5ob3N0UmVmID0gbnVsbDtcbiAgfVxuXG4gIC8qKiBJbXBlcmF0aXZlbHkgdHJpZ2dlciBhIHJlbmRlciBwYXNzICh1c2VzIGBjZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlYCkuICovXG4gIHJlbmRlcigpOiBNZWFzdXJlZFZpZXdwb3J0UmFuZ2UgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZikgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgdGVtcGxhdGUgPSB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGU7XG4gICAgaWYgKCF0ZW1wbGF0ZSkgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBob3N0Q29udGFpbmVyID0gdGhpcy5ob3N0Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgaGVpZ2h0ID0gaG9zdENvbnRhaW5lci5jbGllbnRIZWlnaHQgfHwgaG9zdENvbnRhaW5lci5vZmZzZXRIZWlnaHQ7XG4gICAgY29uc3QgY29udGVudENvbnRhaW5lciA9IHRoaXMuaG9zdFJlZi5jb250ZW50RWxlbWVudDtcblxuICAgIC8vIFRyYWNrIHdoZXRoZXIgdGhlIGVuZ2luZSBhc2tlZCB1cyB0byBiaW5kIGFueSByb3cgdGhpcyBwYXNzLiBQdXJlIHNjcm9sbFxuICAgIC8vIGZyYW1lcyB3aGVyZSB0aGUgdmlzaWJsZSByb3cgc2V0IGRvZXNuJ3QgY2hhbmdlIHN0aWxsIGRyaXZlIHJlbmRlcigpIHZpYVxuICAgIC8vIHRoZSByQUYgY29hbGVzY2VyIOKAlCB0aGVyZSdzIG5vIHBvaW50IGluIHdhbGtpbmcgdGhlIHBydW5lIG1hcCBvclxuICAgIC8vIGVtaXR0aW5nIHRoZSB2aWV3cG9ydCByYW5nZSB3aGVuIG5vdGhpbmcgd2FzIHRvdWNoZWQuXG4gICAgbGV0IHJlbmRlcmVySW52b2NhdGlvbnMgPSAwO1xuICAgIGNvbnN0IHJlbmRlcmVyOiBFbGVtZW50UmVuZGVyZXIgPSAoaW5kZXgsIGVsZW1lbnRDb250YWluZXIpID0+IHtcbiAgICAgIHJlbmRlcmVySW52b2NhdGlvbnMrKztcbiAgICAgIC8vIFJlbmRlciBlYWNoIHJvdydzIGVtYmVkZGVkIHZpZXcgd2l0aCBMT0NBTCBjaGFuZ2UgZGV0ZWN0aW9uXG4gICAgICAvLyAoYHZpZXcuZGV0ZWN0Q2hhbmdlcygpYCBpbnNpZGUgYHJlbmRlclRlbXBsYXRlSW50b0NvbnRhaW5lcmApIHNvIHRoZVxuICAgICAgLy8gZW5naW5lIGNhbiBtZWFzdXJlIGl0cyBoZWlnaHQgZHVyaW5nIHRoaXMgcGFzcy4gRG8gTk9UIHdyYXAgZWFjaCByb3cgaW5cbiAgICAgIC8vIGl0cyBvd24gYG5nWm9uZS5ydW5gIOKAlCB0aGF0IGZpcmVzIGEgZnVsbCBgQXBwbGljYXRpb25SZWZgIHRpY2sgKnBlciByb3cqXG4gICAgICAvLyAoTyhuZXdSb3dzIMOXIHZpc2libGVSb3dzKSB3b3JrLCBqYW5reSBkcmFncykuIFRoZSBzaW5nbGUgY29hbGVzY2VkIHRpY2tcbiAgICAgIC8vIGZvciB0aGUgd2hvbGUgcGFzcyBpcyBoYW5kbGVkIGJ5IHRoZSBjYWxsZXIgKGBzY2hlZHVsZVJlbmRlcmApLlxuICAgICAgdGhpcy5yZW5kZXJUZW1wbGF0ZUludG9Db250YWluZXIodGVtcGxhdGUsIGluZGV4LCBlbGVtZW50Q29udGFpbmVyKTtcbiAgICB9O1xuXG4gICAgY29uc3QgcmFuZ2UgPSB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIucmVuZGVyVmlld3BvcnQoaGVpZ2h0LCBjb250ZW50Q29udGFpbmVyLCByZW5kZXJlcik7XG5cbiAgICBpZiAocmVuZGVyZXJJbnZvY2F0aW9ucyA9PT0gMCkge1xuICAgICAgLy8gVmlld3BvcnQgZGlkbid0IGNoYW5nZSDigJQgc2tpcCB0aGUgcHJ1bmUgd2FsayBhbmQgdGhlIChwb3RlbnRpYWxseVxuICAgICAgLy8gem9uZS1lbnRlcmluZykgZW1pdC5cbiAgICAgIHJldHVybiByYW5nZTtcbiAgICB9XG5cbiAgICAvLyBEZXN0cm95IHZpZXdzIHdob3NlIGNvbnRhaW5lciB0aGUgZW5naW5lIG5vIGxvbmdlciByZW5kZXJzLiBXaXRob3V0IHRoaXMsXG4gICAgLy8gZXZlcnkgY29udGFpbmVyIHRoZSBlbmdpbmUgcmVjeWNsZXMgaW50byBpdHMgZWxlbWVudCBwb29sIGxlYXZlcyBpdHNcbiAgICAvLyBlbWJlZGRlZCB2aWV3IGF0dGFjaGVkIHRvIEFwcGxpY2F0aW9uUmVmIGZvcmV2ZXIg4oCUIHNvIHRoZSBhdHRhY2hlZC12aWV3XG4gICAgLy8gbGlzdCAoYW5kIGV2ZXJ5IE8obikgYGRldGFjaFZpZXdgKSBncm93cyB3aXRob3V0IGJvdW5kIGFuZCBzY3JvbGxpbmcgZ2V0c1xuICAgIC8vIHByb2dyZXNzaXZlbHkgc2xvd2VyLiBNaXJyb3JzIHRoZSBSZWFjdC9WdWUgd3JhcHBlcnMsIHdoaWNoIGRyb3Agcm93cyB0aGF0XG4gICAgLy8gZmFsbCBvdXQgb2YgYGdldFJlbmRlcmVkSW5kaWNlcygpYC5cbiAgICB0aGlzLnBydW5lRGV0YWNoZWRWaWV3cygpO1xuXG4gICAgLy8gT25seSByZS1lbnRlciB0aGUgem9uZSAoYSBnbG9iYWwgdGljaykgaWYgc29tZW9uZSBpcyBhY3R1YWxseSBsaXN0ZW5pbmcuXG4gICAgaWYgKHRoaXMuY2VyaW91c1Njcm9sbE1lYXN1cmVkVmlld3BvcnQub2JzZXJ2ZWQpIHtcbiAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLmNlcmlvdXNTY3JvbGxNZWFzdXJlZFZpZXdwb3J0LmVtaXQocmFuZ2UpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG5cbiAgLyoqIFRlYXIgZG93biBlbWJlZGRlZCB2aWV3cyB3aG9zZSBjb250YWluZXIgaXMgbm8gbG9uZ2VyIHBhcnQgb2YgdGhlIHZpZXdwb3J0LiAqL1xuICBwcml2YXRlIHBydW5lRGV0YWNoZWRWaWV3cygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZiB8fCB0aGlzLnZpZXdCeUNvbnRhaW5lci5zaXplID09PSAwKSByZXR1cm47XG4gICAgY29uc3Qgc2Nyb2xsZXIgPSB0aGlzLmhvc3RSZWYuc2Nyb2xsZXI7XG4gICAgY29uc3QgYWN0aXZlID0gbmV3IFNldDxIVE1MRWxlbWVudD4oKTtcbiAgICBmb3IgKGNvbnN0IGluZGV4IG9mIHNjcm9sbGVyLmdldFJlbmRlcmVkSW5kaWNlcygpKSB7XG4gICAgICBjb25zdCBlbCA9IHNjcm9sbGVyLmdldFJlbmRlcmVkRWxlbWVudChpbmRleCk7XG4gICAgICBpZiAoZWwpIGFjdGl2ZS5hZGQoZWwpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtjb250YWluZXIsIHZpZXddIG9mIHRoaXMudmlld0J5Q29udGFpbmVyKSB7XG4gICAgICBpZiAoIWFjdGl2ZS5oYXMoY29udGFpbmVyKSkge1xuICAgICAgICAvLyBEZXRhY2ggRE9NIGJ1dCBrZWVwIHRoZSB2aWV3IGFsaXZlIGluIHRoZSBwb29sIGZvciBmdXR1cmUgcmV1c2UuXG4gICAgICAgIC8vIERlc3Ryb3lpbmcgKyByZWNyZWF0aW5nIHZpZXdzIHBlciBzY3JvbGwgc3RlcCBkb21pbmF0ZXMgZnJhbWUgdGltZS5cbiAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIHZpZXcucm9vdE5vZGVzKSB7XG4gICAgICAgICAgaWYgKG5vZGUucGFyZW50Tm9kZSkgbm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudmlld0J5Q29udGFpbmVyLmRlbGV0ZShjb250YWluZXIpO1xuICAgICAgICB0aGlzLmZyZWVWaWV3cy5wdXNoKHZpZXcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKiBBdXRvLXJlbmRlciBjb2FsZXNjZWQgdG8gYXQgbW9zdCBvbmNlIHBlciBhbmltYXRpb24gZnJhbWUuICovXG4gIHByaXZhdGUgc2NoZWR1bGVSZW5kZXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2NoZWR1bGVkUmVuZGVyRnJhbWUgIT0gbnVsbCkgcmV0dXJuO1xuICAgIHRoaXMuc2NoZWR1bGVkUmVuZGVyRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgdGhpcy5zY2hlZHVsZWRSZW5kZXJGcmFtZSA9IG51bGw7XG4gICAgICAvLyBSdW4gcmVuZGVyKCkgT1VUU0lERSBBbmd1bGFyJ3Mgem9uZS4gQSBmdWxsIEFwcGxpY2F0aW9uUmVmLnRpY2soKSBvblxuICAgICAgLy8gZXZlcnkgc2Nyb2xsIGZyYW1lIGlzIHRoZSBwcmltYXJ5IEZQUyBib3R0bGVuZWNrOiBldmVuIHdoZW4gbm8gcm93c1xuICAgICAgLy8gY2hhbmdlIChwdXJlIHRyYW5zbGF0aW9uKSwgbmdab25lLnJ1bigpIGNhdXNlcyBBbmd1bGFyIHRvIHdhbGsgdGhlXG4gICAgICAvLyBlbnRpcmUgY29tcG9uZW50IHRyZWUuIEluc3RlYWQgd2UgY2FsbCB2aWV3LmRldGVjdENoYW5nZXMoKSBsb2NhbGx5XG4gICAgICAvLyBpbnNpZGUgcmVuZGVyVGVtcGxhdGVJbnRvQ29udGFpbmVyIGZvciBlYWNoIGFmZmVjdGVkIHJvdy4gWm9uZSBlbnRyeSBpc1xuICAgICAgLy8gb25seSBuZWVkZWQgd2hlbiBjcmVhdGluZyBhIGJyYW5kLW5ldyBlbWJlZGRlZCB2aWV3ICh0byB6b25lLXBhdGNoIGl0c1xuICAgICAgLy8gZXZlbnQgbGlzdGVuZXJzKSDigJQgcmVjeWNsZWQgYW5kIHBvb2xlZCB2aWV3cyB3ZXJlIGFscmVhZHkgY3JlYXRlZCBpbnNpZGVcbiAgICAgIC8vIHpvbmUgYW5kIHRoZWlyIGxpc3RlbmVycyByZW1haW4gem9uZS1hd2FyZS5cbiAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGlzY2FyZCBhbGwgY2FjaGVkIHJvdyBoZWlnaHRzIGFuZCByZS1tZWFzdXJlIHRoZSB2aWV3cG9ydC5cbiAgICpcbiAgICogQ2FsbCB0aGlzIG9ubHkgd2hlbiB0aGUgaGVpZ2h0cyBvZiByb3dzIHlvdSd2ZSAqYWxyZWFkeSByZW5kZXJlZCogbWF5IGhhdmVcbiAgICogY2hhbmdlZCB3aXRob3V0IHRoZWlyIGluZGljZXMgY2hhbmdpbmcg4oCUIGUuZy4gYSBnbG9iYWwgZm9udC9kZW5zaXR5IGNoYW5nZSxcbiAgICogb3Igc3dhcHBpbmcgZXZlcnkgcm93IHRvIGEgZGlmZmVyZW50IGxheW91dC4gVGhpcyBmb3JjZXMgYSBzeW5jaHJvbm91c1xuICAgKiByZS1tZWFzdXJlIChvbmUgYG9mZnNldEhlaWdodGAgcmVhZCBwZXIgdmlzaWJsZSByb3cpLCBzbyBkbyBOT1QgY2FsbCBpdCBvblxuICAgKiByb3V0aW5lIGVkaXRzOiBhIHNpbmdsZSBjZWxsIGVkaXQga2VlcHMgaXRzIHJvdydzIHNpemUsIGFuZCB0aGUgZW5naW5lJ3NcbiAgICogUmVzaXplT2JzZXJ2ZXIgcGlja3MgdXAgYW55IGluY2lkZW50YWwgcmVzaXplIG9uIGl0cyBvd24uXG4gICAqL1xuICByZWNhbGN1bGF0ZSgpOiBNZWFzdXJlZFZpZXdwb3J0UmFuZ2UgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaG9zdFJlZikgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgdGVtcGxhdGUgPSB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGU7XG4gICAgaWYgKHRlbXBsYXRlKSB7XG4gICAgICAvLyBSZS1pbnZva2UgdGhlIHJlbmRlcmVyIGZvciBldmVyeSBjdXJyZW50bHktcmVuZGVyZWQgcm93IHNvIHBlbmRpbmdcbiAgICAgIC8vIEFuZ3VsYXIgYmluZGluZ3MgZmx1c2ggaW50byB0aGUgRE9NIGFuZCB0aGUgZW5naW5lIHJlLW1lYXN1cmVzIGVhY2hcbiAgICAgIC8vIHJvdydzIG5ldyBoZWlnaHQgaW50byBpdHMgY2FjaGUuIFdpdGhvdXQgdGhpcywgdGhlIGVuZ2luZSdzIHJlbmRlclxuICAgICAgLy8gcGFzcyBza2lwcyB0aGUgcmVuZGVyZXIgZm9yIGFscmVhZHktcmVuZGVyZWQgaW5kaWNlcyBhbmQgZmFsbHNcbiAgICAgIC8vIHRocm91Z2ggdG8gcmVhZGluZyBzdGFsZSBvZmZzZXRIZWlnaHQuXG4gICAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIucmVmcmVzaFZpc2libGUoKGluZGV4LCBlbGVtZW50Q29udGFpbmVyKSA9PiB7XG4gICAgICAgIHRoaXMucmVuZGVyVGVtcGxhdGVJbnRvQ29udGFpbmVyKHRlbXBsYXRlLCBpbmRleCwgZWxlbWVudENvbnRhaW5lcik7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKiogSnVtcCBkaXJlY3RseSB0byBhbiBlbGVtZW50IGluZGV4LCB0aGVuIHJlbmRlci4gKi9cbiAganVtcFRvRWxlbWVudChpbmRleDogbnVtYmVyKTogTWVhc3VyZWRWaWV3cG9ydFJhbmdlIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybiBudWxsO1xuICAgIHRoaXMuaG9zdFJlZi5zY3JvbGxlci5qdW1wVG9FbGVtZW50KGluZGV4KTtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBTY3JvbGwgdG8gYSBwZXJjZW50YWdlICgwLi4xMDApLCB0aGVuIHJlbmRlci4gKi9cbiAgc2Nyb2xsVG9QZXJjZW50YWdlKHBlcmNlbnRhZ2U6IG51bWJlcik6IE1lYXN1cmVkVmlld3BvcnRSYW5nZSB8IG51bGwge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm4gbnVsbDtcbiAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIuaGFuZGxlU2Nyb2xsUGVyY2VudGFnZShwZXJjZW50YWdlKTtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBSZXNldCB0byB0aGUgdG9wLCB0aGVuIHJlbmRlci4gKi9cbiAgcmVzZXQoKTogTWVhc3VyZWRWaWV3cG9ydFJhbmdlIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybiBudWxsO1xuICAgIHRoaXMuaG9zdFJlZi5zY3JvbGxlci5yZXNldCgpO1xuICAgIHJldHVybiB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWNyZWF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLnZpZXdwb3J0U3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMudmlld3BvcnRTdWIgPSBudWxsO1xuXG4gICAgdGhpcy5kZXN0cm95QWxsVmlld3MoKTtcblxuICAgIHRoaXMuaG9zdFJlZj8uZGVzdHJveSgpO1xuICAgIHRoaXMuaG9zdFJlZiA9IG51bGw7XG5cbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZUluaXRpYWxpemVkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhvc3RSZWYpIHJldHVybjtcblxuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuaG9zdC5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IHRvdGFsID0gY29lcmNlVG90YWxFbGVtZW50cyh0aGlzLmNlcmlvdXNTY3JvbGxUb3RhbEVsZW1lbnRzLCB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtcz8ubGVuZ3RoID8/IG51bGwpO1xuXG4gICAgLy8gVGFibGUgbW9kZTogY2FwdHVyZSB0aGUgZW5naW5lLWNyZWF0ZWQgPHRoZWFkPiBzbyB3ZSBjYW4gcmVuZGVyIHRoZVxuICAgIC8vIGRlY2xhcmF0aXZlIGhlYWRlciB0ZW1wbGF0ZSBpbnRvIGl0IChhbmQgc3RpbGwgcnVuIGFueSB1c2VyIGhlYWRlciBob29rKS5cbiAgICBsZXQgb3B0aW9ucyA9IHRoaXMuY2VyaW91c1Njcm9sbE9wdGlvbnM7XG4gICAgaWYgKG9wdGlvbnMubGF5b3V0ID09PSAndGFibGUnICYmIHRoaXMuY2VyaW91c1Njcm9sbEhlYWRlclRlbXBsYXRlKSB7XG4gICAgICBjb25zdCB1c2VySGVhZGVyID0gb3B0aW9ucy50YWJsZT8uaGVhZGVyO1xuICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgdGFibGU6IHtcbiAgICAgICAgICAuLi5vcHRpb25zLnRhYmxlLFxuICAgICAgICAgIGhlYWRlcjogKHRoZWFkOiBIVE1MVGFibGVTZWN0aW9uRWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgdXNlckhlYWRlcj8uKHRoZWFkKTtcbiAgICAgICAgICAgIHRoaXMubW91bnRIZWFkZXIodGhlYWQpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMuaG9zdFJlZiA9IHRoaXMuY2VyaW91cy5jcmVhdGVIb3N0KGNvbnRhaW5lciwgdG90YWwsIG9wdGlvbnMsIHRoaXMubmdab25lLCAoKSA9PiB7XG4gICAgICAvLyBDb2FsZXNjZSBzY3JvbGwtZHJpdmVuIHJlbmRlcnMgdG8gb25lIHBlciBmcmFtZSAodGhlIG5hdGl2ZSBzY3JvbGxiYXJcbiAgICAgIC8vIGNhbiBmaXJlIG1hbnkgc2Nyb2xsIGV2ZW50cyBiZXR3ZWVuIHBhaW50cykuXG4gICAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikgdGhpcy5zY2hlZHVsZVJlbmRlcigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy52aWV3cG9ydFN1YiA9IHRoaXMuaG9zdFJlZi52aWV3cG9ydENoYW5nZXMkLnN1YnNjcmliZSgoZGV0YWlsOiBDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWwpID0+IHtcbiAgICAgIC8vIFNraXAgdGhlIGdsb2JhbCB0aWNrIHdoZW4gbm9ib2R5IGlzIGJvdW5kIHRvIHRoZSBvdXRwdXQuXG4gICAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsVmlld3BvcnRDaGFuZ2Uub2JzZXJ2ZWQpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuY2VyaW91c1Njcm9sbFZpZXdwb3J0Q2hhbmdlLmVtaXQoZGV0YWlsKSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmNlcmlvdXNTY3JvbGxSZWFkeS5lbWl0KHRoaXMuaG9zdFJlZi5zY3JvbGxlcik7XG5cbiAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikge1xuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy5yZW5kZXIoKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgZGVjbGFyYXRpdmUgaGVhZGVyIHRlbXBsYXRlIGludG8gdGhlIGVuZ2luZSdzIDx0aGVhZD4uIE9uZVxuICAgKiBlbWJlZGRlZCB2aWV3LCBjcmVhdGVkIGluc2lkZSB0aGUgem9uZSAoc28gdGhlIGhlYWRlcidzIGV2ZW50IGJpbmRpbmdzIGFyZVxuICAgKiB6b25lLXBhdGNoZWQpLCBpdHMgcm9vdCBub2RlcyBhcHBlbmRlZCBkaXJlY3RseSBpbnRvIHRoZSA8dGhlYWQ+LlxuICAgKi9cbiAgcHJpdmF0ZSBtb3VudEhlYWRlcih0aGVhZDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2VyaW91c1Njcm9sbEhlYWRlclRlbXBsYXRlKSByZXR1cm47XG4gICAgdGhpcy5oZWFkZXJWaWV3Py5kZXN0cm95KCk7XG4gICAgY29uc3QgdmlldyA9IHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICBjb25zdCB2ID0gdGhpcy5jZXJpb3VzU2Nyb2xsSGVhZGVyVGVtcGxhdGUhLmNyZWF0ZUVtYmVkZGVkVmlldyh7fSk7XG4gICAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHYpO1xuICAgICAgdi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICByZXR1cm4gdjtcbiAgICB9KTtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygdmlldy5yb290Tm9kZXMpIHRoZWFkLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgIHRoaXMuaGVhZGVyVmlldyA9IHZpZXc7XG4gIH1cblxuICBwcml2YXRlIGdldEl0ZW1Gb3JJbmRleChpbmRleDogbnVtYmVyKTogVEl0ZW0ge1xuICAgIGNvbnN0IGdldHRlciA9IHRoaXMuY2VyaW91c1Njcm9sbEdldEl0ZW07XG4gICAgaWYgKGdldHRlcikgcmV0dXJuIGdldHRlcihpbmRleCk7XG5cbiAgICBjb25zdCBpdGVtcyA9IHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1zO1xuICAgIGlmICghaXRlbXMpIHJldHVybiB1bmRlZmluZWQgYXMgVEl0ZW07XG5cbiAgICByZXR1cm4gaXRlbXNbaW5kZXhdO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJUZW1wbGF0ZUludG9Db250YWluZXIoXG4gICAgdGVtcGxhdGU6IFRlbXBsYXRlUmVmPENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVDb250ZXh0PFRJdGVtPj4sXG4gICAgaW5kZXg6IG51bWJlcixcbiAgICBlbGVtZW50Q29udGFpbmVyOiBIVE1MRWxlbWVudFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMudmlld0J5Q29udGFpbmVyLmdldChlbGVtZW50Q29udGFpbmVyKTtcbiAgICBpZiAocHJldmlvdXMpIHtcbiAgICAgIC8vIFJlY3ljbGU6IHVwZGF0ZSB0aGUgYm91bmQgY29udGV4dCBhbmQgcnVuIGxvY2FsIENEIGluc3RlYWQgb2ZcbiAgICAgIC8vIGRlc3Ryb3lpbmcgdGhlIGVtYmVkZGVkIHZpZXcgYW5kIHJlYnVpbGRpbmcgdGhlIGVudGlyZSByb3cgdHJlZS5cbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmdldEl0ZW1Gb3JJbmRleChpbmRleCk7XG4gICAgICBwcmV2aW91cy5jb250ZXh0LiRpbXBsaWNpdCA9IGl0ZW07XG4gICAgICBwcmV2aW91cy5jb250ZXh0Lml0ZW0gPSBpdGVtO1xuICAgICAgcHJldmlvdXMuY29udGV4dC5pbmRleCA9IGluZGV4O1xuICAgICAgLy8gVGhlIGNvcmUgZW5naW5lIHdpcGVzIGVsZW1lbnRDb250YWluZXIudGV4dENvbnRlbnQgd2hlbiByZXVzaW5nIGl0IGZyb21cbiAgICAgIC8vIGl0cyBwb29sLCBvcnBoYW5pbmcgdGhlIHZpZXcncyByb290IG5vZGVzLiBSZS1hcHBlbmQgdGhlbSBkZWZlbnNpdmVseS5cbiAgICAgIGlmIChwcmV2aW91cy5yb290Tm9kZXMubGVuZ3RoICYmIHByZXZpb3VzLnJvb3ROb2Rlc1swXS5wYXJlbnROb2RlICE9PSBlbGVtZW50Q29udGFpbmVyKSB7XG4gICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBwcmV2aW91cy5yb290Tm9kZXMpIHtcbiAgICAgICAgICBlbGVtZW50Q29udGFpbmVyLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBwcmV2aW91cy5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVHJ5IHRvIHJldXNlIGEgcG9vbGVkIHZpZXcgZnJvbSBhIGNvbnRhaW5lciB0aGF0IHNjcm9sbGVkIG91dCBvZiB2aWV3cG9ydC5cbiAgICBjb25zdCBwb29sZWQgPSB0aGlzLmZyZWVWaWV3cy5wb3AoKTtcbiAgICBpZiAocG9vbGVkKSB7XG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5nZXRJdGVtRm9ySW5kZXgoaW5kZXgpO1xuICAgICAgcG9vbGVkLmNvbnRleHQuJGltcGxpY2l0ID0gaXRlbTtcbiAgICAgIHBvb2xlZC5jb250ZXh0Lml0ZW0gPSBpdGVtO1xuICAgICAgcG9vbGVkLmNvbnRleHQuaW5kZXggPSBpbmRleDtcbiAgICAgIGVsZW1lbnRDb250YWluZXIudGV4dENvbnRlbnQgPSAnJztcbiAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBwb29sZWQucm9vdE5vZGVzKSB7XG4gICAgICAgIGVsZW1lbnRDb250YWluZXIuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgICB9XG4gICAgICBwb29sZWQuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgdGhpcy52aWV3QnlDb250YWluZXIuc2V0KGVsZW1lbnRDb250YWluZXIsIHBvb2xlZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gTm8gcHJpb3IgdmlldyBmb3IgdGhpcyBjb250YWluZXI6IGNyZWF0ZSBvbmUuXG4gICAgLy8gRW50ZXIgdGhlIEFuZ3VsYXIgem9uZSBzbyB0aGUgbmV3IHZpZXcncyB0ZW1wbGF0ZSBldmVudCBsaXN0ZW5lcnNcbiAgICAvLyAoKGNsaWNrKSwgKGlucHV0KSwgZXRjLikgYXJlIHpvbmUtcGF0Y2hlZC4gVGhpcyBwYXRoIHJ1bnMgYXQgbW9zdFxuICAgIC8vIG9uY2UgcGVyIHZpc2libGUgcm93IChhZnRlciB0aGF0LCB0aGUgdmlldyBpcyByZWN5Y2xlZCBmcm9tIHRoZSBwb29sKS5cbiAgICBlbGVtZW50Q29udGFpbmVyLnRleHRDb250ZW50ID0gJyc7XG5cbiAgICBjb25zdCBpdGVtID0gdGhpcy5nZXRJdGVtRm9ySW5kZXgoaW5kZXgpO1xuICAgIGNvbnN0IHZpZXcgPSB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgY29uc3QgdiA9IHRlbXBsYXRlLmNyZWF0ZUVtYmVkZGVkVmlldyh7ICRpbXBsaWNpdDogaXRlbSwgaXRlbSwgaW5kZXggfSk7XG4gICAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHYpO1xuICAgICAgdi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICByZXR1cm4gdjtcbiAgICB9KTtcblxuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB2aWV3LnJvb3ROb2Rlcykge1xuICAgICAgZWxlbWVudENvbnRhaW5lci5hcHBlbmRDaGlsZChub2RlKTtcbiAgICB9XG5cbiAgICB0aGlzLnZpZXdCeUNvbnRhaW5lci5zZXQoZWxlbWVudENvbnRhaW5lciwgdmlldyk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHRoZSBib3VuZCBpdGVtL2luZGV4IG9uIGV2ZXJ5IGN1cnJlbnRseS1yZW5kZXJlZCByb3cncyBlbWJlZGRlZCB2aWV3XG4gICAqIGFuZCBydW4gY2hhbmdlIGRldGVjdGlvbiwgd2l0aG91dCByZWNyZWF0aW5nIHRoZSB2aWV3cy4gVXNlZCB3aGVuIHRoZSBkYXRhXG4gICAqIHJlZmVyZW5jZSBjaGFuZ2VzIGJ1dCB0aGUgdmlzaWJsZSBpbmRpY2VzIChhbmQgdGhlaXIgaGVpZ2h0cykgZG8gbm90LCBzbyByb3dcbiAgICogc3RhdGUgKGZvY3VzLCBzZWxlY3Rpb24sIG9wZW4gZHJvcGRvd25zKSBzdXJ2aXZlcyB0aGUgdXBkYXRlLlxuICAgKi9cbiAgLyoqXG4gICAqIFJlLWJpbmQgZWFjaCBjdXJyZW50bHkgcmVuZGVyZWQgcm93J3MgY29udGV4dCAoZnJvbSB0aGUgY3VycmVudCBpdGVtcy9nZXR0ZXIpXG4gICAqIGFuZCBydW4gY2hhbmdlIGRldGVjdGlvbiBvbiBpdHMgZW1iZWRkZWQgdmlldy4gVXNlIHRoaXMgYWZ0ZXIgbXV0YXRpbmcgcm93XG4gICAqIHN0YXRlIGluIHBsYWNlIChlLmcuIHNlbGVjdGlvbiBmbGFncykgb3IgY29sdW1uLWxldmVsIHN0YXRlIHJlYWQgYnkgdGhlIHJvd1xuICAgKiB0ZW1wbGF0ZSwgd2hlbiByb3cgaWRlbnRpdHkgYW5kIHZpc2libGUgaW5kaWNlcyBoYXZlIG5vdCBjaGFuZ2VkLiBDaGVhcFxuICAgKiByZWxhdGl2ZSB0byBgcmVuZGVyKClgIOKAlCBkb2VzIG5vdCBpbnZva2UgdGhlIGVuZ2luZSdzIG1lYXN1cmVtZW50IHBhc3MuXG4gICAqL1xuICByZWZyZXNoUmVuZGVyZWRDb250ZW50KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm47XG4gICAgY29uc3Qgc2Nyb2xsZXIgPSB0aGlzLmhvc3RSZWYuc2Nyb2xsZXI7XG5cbiAgICBmb3IgKGNvbnN0IGluZGV4IG9mIHNjcm9sbGVyLmdldFJlbmRlcmVkSW5kaWNlcygpKSB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSBzY3JvbGxlci5nZXRSZW5kZXJlZEVsZW1lbnQoaW5kZXgpO1xuICAgICAgaWYgKCFjb250YWluZXIpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCB2aWV3ID0gdGhpcy52aWV3QnlDb250YWluZXIuZ2V0KGNvbnRhaW5lcik7XG4gICAgICBpZiAoIXZpZXcpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5nZXRJdGVtRm9ySW5kZXgoaW5kZXgpO1xuICAgICAgdmlldy5jb250ZXh0LiRpbXBsaWNpdCA9IGl0ZW07XG4gICAgICB2aWV3LmNvbnRleHQuaXRlbSA9IGl0ZW07XG4gICAgICB2aWV3LmNvbnRleHQuaW5kZXggPSBpbmRleDtcbiAgICAgIHZpZXcuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveUFsbFZpZXdzKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgdmlldyBvZiB0aGlzLnZpZXdCeUNvbnRhaW5lci52YWx1ZXMoKSkge1xuICAgICAgdGhpcy5hcHBSZWYuZGV0YWNoVmlldyh2aWV3KTtcbiAgICAgIHZpZXcuZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLnZpZXdCeUNvbnRhaW5lci5jbGVhcigpO1xuICAgIGZvciAoY29uc3QgdmlldyBvZiB0aGlzLmZyZWVWaWV3cykge1xuICAgICAgdGhpcy5hcHBSZWYuZGV0YWNoVmlldyh2aWV3KTtcbiAgICAgIHZpZXcuZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLmZyZWVWaWV3cy5sZW5ndGggPSAwO1xuICB9XG59XG4iXX0=
@@ -174,17 +174,23 @@ class CeriousScrollDirective {
174
174
  const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);
175
175
  const countChanged = this.hostRef.scroller.totalElements !== total;
176
176
  if (countChanged) {
177
- // The dataset size changed: the ViewportRenderer stores its own copy of
178
- // totalElements (set by value at construction) so patching the engine's
179
- // public property alone leaves the renderer's internal bound stale. The
180
- // renderer would then use the old count for its viewport-fill loop and
181
- // bottom-boundary scan, producing phantom renders at out-of-bounds
182
- // indices (undefined items 0-height rows the fill loop never
183
- // satisfies its height condition hundreds of renderer callbacks).
184
- // Recreating the engine gives both the engine and the renderer a fresh,
185
- // consistent count. ensureInitialized() schedules the first render via
186
- // queueMicrotask, which runs after the current CD cycle completes.
187
- this.recreate();
177
+ // Grow/shrink the dataset IN PLACE no recreate. updateTotalElements
178
+ // propagates the new count to every subsystem, INCLUDING the
179
+ // ViewportRenderer's own copy of totalElements (it used to go stale,
180
+ // which is exactly why this recreated: the renderer kept the old count
181
+ // for its viewport-fill loop and bottom scan, producing phantom
182
+ // out-of-bounds renders). In place keeps the scroll position and an
183
+ // in-progress scrollbar drag alive, and a growing dataset keeps a stable
184
+ // bottom index (no bouncing tail). The track lengthens, so re-sync the
185
+ // thumb afterwards.
186
+ this.hostRef.scroller.updateTotalElements(total);
187
+ // A shrink can leave the position past the new end — clamp it.
188
+ if (this.hostRef.scroller.currentElement > total - 1) {
189
+ this.hostRef.scroller.jumpToElement(total - 1);
190
+ }
191
+ if (this.ceriousScrollAutoRender)
192
+ this.render();
193
+ this.hostRef.scroller.syncScrollbar();
188
194
  }
189
195
  else if (this.ceriousScrollAutoRender) {
190
196
  // Same count, new data reference (e.g. an immutable edit or a sort that
@@ -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 = 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 // 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 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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ceriousdevtech/ngx-cerious-scroll",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
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.7",
14
+ "@ceriousdevtech/cerious-scroll": "^1.0.8",
15
15
  "tslib": "^2.3.0"
16
16
  },
17
17
  "sideEffects": false,