@angular/cdk 10.0.0-rc.3 → 10.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/a11y/aria-describer/aria-describer.d.ts +10 -1
- package/a11y/focus-trap/focus-trap.d.ts +4 -2
- package/a11y/index.metadata.json +1 -1
- package/a11y/interactivity-checker/interactivity-checker.d.ts +11 -1
- package/a11y/key-manager/list-key-manager.d.ts +6 -0
- package/accordion/accordion.d.ts +7 -1
- package/accordion/index.d.ts +1 -0
- package/accordion/index.metadata.json +1 -1
- package/bundles/cdk-a11y.umd.js +78 -15
- package/bundles/cdk-a11y.umd.js.map +1 -1
- package/bundles/cdk-a11y.umd.min.js +11 -11
- package/bundles/cdk-a11y.umd.min.js.map +1 -1
- package/bundles/cdk-accordion.umd.js +12 -4
- package/bundles/cdk-accordion.umd.js.map +1 -1
- package/bundles/cdk-accordion.umd.min.js +2 -2
- package/bundles/cdk-accordion.umd.min.js.map +1 -1
- package/bundles/cdk-drag-drop.umd.js +717 -641
- package/bundles/cdk-drag-drop.umd.js.map +1 -1
- package/bundles/cdk-drag-drop.umd.min.js +8 -16
- package/bundles/cdk-drag-drop.umd.min.js.map +1 -1
- package/bundles/cdk-overlay.umd.js +199 -42
- package/bundles/cdk-overlay.umd.js.map +1 -1
- package/bundles/cdk-overlay.umd.min.js +11 -18
- package/bundles/cdk-overlay.umd.min.js.map +1 -1
- package/bundles/cdk-platform.umd.js +0 -1
- package/bundles/cdk-platform.umd.js.map +1 -1
- package/bundles/cdk-platform.umd.min.js +2 -2
- package/bundles/cdk-platform.umd.min.js.map +1 -1
- package/bundles/cdk-scrolling.umd.js +26 -4
- package/bundles/cdk-scrolling.umd.js.map +1 -1
- package/bundles/cdk-scrolling.umd.min.js +11 -4
- package/bundles/cdk-scrolling.umd.min.js.map +1 -1
- package/bundles/cdk-testing-protractor.umd.min.js +1 -1
- package/bundles/cdk-testing-protractor.umd.min.js.map +1 -1
- package/bundles/cdk-testing-testbed.umd.min.js +8 -8
- package/bundles/cdk-testing-testbed.umd.min.js.map +1 -1
- package/bundles/cdk-testing.umd.js +32 -0
- package/bundles/cdk-testing.umd.js.map +1 -1
- package/bundles/cdk-testing.umd.min.js +5 -5
- package/bundles/cdk-testing.umd.min.js.map +1 -1
- package/bundles/cdk-tree.umd.js +6 -2
- package/bundles/cdk-tree.umd.js.map +1 -1
- package/bundles/cdk-tree.umd.min.js +3 -3
- package/bundles/cdk-tree.umd.min.js.map +1 -1
- package/bundles/cdk.umd.js +1 -1
- package/bundles/cdk.umd.js.map +1 -1
- package/bundles/cdk.umd.min.js +1 -1
- package/bundles/cdk.umd.min.js.map +1 -1
- package/drag-drop/directives/drag-handle.d.ts +7 -1
- package/drag-drop/directives/drag-placeholder.d.ts +7 -1
- package/drag-drop/directives/drag-preview.d.ts +7 -1
- package/drag-drop/directives/drag.d.ts +4 -14
- package/drag-drop/directives/drop-list-group.d.ts +7 -1
- package/drag-drop/directives/drop-list.d.ts +7 -1
- package/drag-drop/drag-ref.d.ts +6 -0
- package/drag-drop/drop-list-ref.d.ts +3 -2
- package/drag-drop/index.d.ts +2 -2
- package/drag-drop/index.metadata.json +1 -1
- package/esm2015/a11y/a11y-module.js +15 -19
- package/esm2015/a11y/aria-describer/aria-describer.js +177 -167
- package/esm2015/a11y/focus-monitor/focus-monitor.js +337 -345
- package/esm2015/a11y/focus-trap/configurable-focus-trap-factory.js +30 -34
- package/esm2015/a11y/focus-trap/focus-trap-manager.js +36 -40
- package/esm2015/a11y/focus-trap/focus-trap.js +85 -82
- package/esm2015/a11y/high-contrast-mode/high-contrast-mode-detector.js +56 -60
- package/esm2015/a11y/interactivity-checker/interactivity-checker.js +113 -104
- package/esm2015/a11y/key-manager/list-key-manager.js +29 -4
- package/esm2015/a11y/live-announcer/live-announcer.js +138 -146
- package/esm2015/accordion/accordion-item.js +119 -123
- package/esm2015/accordion/accordion-module.js +9 -13
- package/esm2015/accordion/accordion.js +49 -46
- package/esm2015/accordion/index.js +2 -1
- package/esm2015/bidi/bidi-module.js +9 -13
- package/esm2015/bidi/dir.js +41 -45
- package/esm2015/bidi/directionality.js +27 -31
- package/esm2015/clipboard/clipboard-module.js +9 -13
- package/esm2015/clipboard/clipboard.js +36 -40
- package/esm2015/clipboard/copy-to-clipboard.js +71 -75
- package/esm2015/collections/unique-selection-dispatcher.js +33 -37
- package/esm2015/drag-drop/directives/drag-handle.js +42 -39
- package/esm2015/drag-drop/directives/drag-placeholder.js +24 -21
- package/esm2015/drag-drop/directives/drag-preview.js +29 -26
- package/esm2015/drag-drop/directives/drag.js +313 -319
- package/esm2015/drag-drop/directives/drop-list-group.js +32 -29
- package/esm2015/drag-drop/directives/drop-list.js +251 -250
- package/esm2015/drag-drop/drag-drop-module.js +27 -31
- package/esm2015/drag-drop/drag-drop-registry.js +139 -143
- package/esm2015/drag-drop/drag-drop.js +33 -37
- package/esm2015/drag-drop/drag-ref.js +59 -25
- package/esm2015/drag-drop/drop-list-ref.js +15 -9
- package/esm2015/drag-drop/index.js +3 -2
- package/esm2015/layout/breakpoints-observer.js +81 -85
- package/esm2015/layout/layout-module.js +6 -10
- package/esm2015/layout/media-matcher.js +28 -32
- package/esm2015/observers/observe-content.js +147 -163
- package/esm2015/overlay/dispatchers/base-overlay-dispatcher.js +51 -0
- package/esm2015/overlay/dispatchers/index.js +10 -0
- package/esm2015/overlay/dispatchers/overlay-keyboard-dispatcher.js +79 -0
- package/esm2015/overlay/dispatchers/overlay-outside-click-dispatcher.js +94 -0
- package/esm2015/overlay/fullscreen-overlay-container.js +70 -74
- package/esm2015/overlay/index.js +5 -4
- package/esm2015/overlay/overlay-config.js +5 -1
- package/esm2015/overlay/overlay-container.js +69 -73
- package/esm2015/overlay/overlay-directives.js +245 -243
- package/esm2015/overlay/overlay-module.js +15 -19
- package/esm2015/overlay/overlay-ref.js +24 -2
- package/esm2015/overlay/overlay-reference.js +1 -1
- package/esm2015/overlay/overlay.js +93 -92
- package/esm2015/overlay/position/connected-position.js +14 -18
- package/esm2015/overlay/position/overlay-position-builder.js +43 -47
- package/esm2015/overlay/public-api.js +2 -2
- package/esm2015/overlay/scroll/scroll-strategy-options.js +33 -37
- package/esm2015/platform/features/scrolling.js +1 -2
- package/esm2015/platform/platform-module.js +6 -10
- package/esm2015/platform/platform.js +48 -52
- package/esm2015/portal/portal-directives.js +181 -201
- package/esm2015/scrolling/fixed-size-virtual-scroll.js +57 -47
- package/esm2015/scrolling/public-api.js +2 -1
- package/esm2015/scrolling/scroll-dispatcher.js +139 -143
- package/esm2015/scrolling/scrollable.js +135 -139
- package/esm2015/scrolling/scrolling-module.js +32 -40
- package/esm2015/scrolling/viewport-ruler.js +105 -109
- package/esm2015/scrolling/virtual-for-of.js +264 -268
- package/esm2015/scrolling/virtual-scroll-repeater.js +8 -0
- package/esm2015/scrolling/virtual-scroll-viewport.js +318 -322
- package/esm2015/stepper/step-header.js +20 -24
- package/esm2015/stepper/step-label.js +13 -17
- package/esm2015/stepper/stepper-button.js +59 -67
- package/esm2015/stepper/stepper-module.js +24 -28
- package/esm2015/stepper/stepper.js +313 -321
- package/esm2015/table/cell.js +129 -157
- package/esm2015/table/row.js +183 -219
- package/esm2015/table/table-module.js +9 -13
- package/esm2015/table/table.js +765 -785
- package/esm2015/table/text-column.js +85 -89
- package/esm2015/testing/component-harness.js +19 -1
- package/esm2015/testing/harness-environment.js +7 -1
- package/esm2015/text-field/autofill.js +89 -97
- package/esm2015/text-field/autosize.js +225 -229
- package/esm2015/text-field/text-field-module.js +10 -14
- package/esm2015/tree/control/nested-tree-control.js +7 -3
- package/esm2015/tree/nested-node.js +79 -83
- package/esm2015/tree/node.js +17 -21
- package/esm2015/tree/outlet.js +15 -19
- package/esm2015/tree/padding.js +88 -92
- package/esm2015/tree/toggle.js +32 -36
- package/esm2015/tree/tree-module.js +10 -14
- package/esm2015/tree/tree.js +266 -274
- package/esm2015/version.js +1 -1
- package/fesm2015/a11y.js +1021 -996
- package/fesm2015/a11y.js.map +1 -1
- package/fesm2015/accordion.js +173 -175
- package/fesm2015/accordion.js.map +1 -1
- package/fesm2015/bidi.js +74 -83
- package/fesm2015/bidi.js.map +1 -1
- package/fesm2015/cdk.js +1 -1
- package/fesm2015/cdk.js.map +1 -1
- package/fesm2015/clipboard.js +113 -122
- package/fesm2015/clipboard.js.map +1 -1
- package/fesm2015/collections.js +32 -35
- package/fesm2015/collections.js.map +1 -1
- package/fesm2015/drag-drop.js +1005 -961
- package/fesm2015/drag-drop.js.map +1 -1
- package/fesm2015/layout.js +111 -120
- package/fesm2015/layout.js.map +1 -1
- package/fesm2015/observers.js +146 -158
- package/fesm2015/observers.js.map +1 -1
- package/fesm2015/overlay.js +793 -659
- package/fesm2015/overlay.js.map +1 -1
- package/fesm2015/platform.js +52 -59
- package/fesm2015/platform.js.map +1 -1
- package/fesm2015/portal.js +180 -195
- package/fesm2015/portal.js.map +1 -1
- package/fesm2015/scrolling.js +1058 -1060
- package/fesm2015/scrolling.js.map +1 -1
- package/fesm2015/stepper.js +424 -445
- package/fesm2015/stepper.js.map +1 -1
- package/fesm2015/table.js +1178 -1247
- package/fesm2015/table.js.map +1 -1
- package/fesm2015/testing.js +25 -1
- package/fesm2015/testing.js.map +1 -1
- package/fesm2015/text-field.js +318 -330
- package/fesm2015/text-field.js.map +1 -1
- package/fesm2015/tree.js +517 -537
- package/fesm2015/tree.js.map +1 -1
- package/overlay/dispatchers/base-overlay-dispatcher.d.ts +28 -0
- package/overlay/dispatchers/index.d.ts +9 -0
- package/overlay/{keyboard → dispatchers}/overlay-keyboard-dispatcher.d.ts +4 -10
- package/overlay/dispatchers/overlay-outside-click-dispatcher.d.ts +27 -0
- package/overlay/index.d.ts +4 -3
- package/overlay/index.metadata.json +1 -1
- package/overlay/overlay-config.d.ts +4 -0
- package/overlay/overlay-directives.d.ts +4 -0
- package/overlay/overlay-ref.d.ts +8 -2
- package/overlay/overlay-reference.d.ts +1 -0
- package/overlay/overlay.d.ts +4 -2
- package/overlay/public-api.d.ts +1 -1
- package/package.json +3 -3
- package/schematics/index.js +1 -1
- package/schematics/migration.json +5 -0
- package/schematics/ng-add/index.js +1 -1
- package/schematics/ng-update/data/index.js +1 -1
- package/schematics/ng-update/devkit-file-system.d.ts +5 -5
- package/schematics/ng-update/devkit-file-system.js +21 -16
- package/schematics/ng-update/devkit-migration-rule.js +13 -20
- package/schematics/ng-update/devkit-migration.d.ts +0 -2
- package/schematics/ng-update/devkit-migration.js +1 -1
- package/schematics/ng-update/find-stylesheets.d.ts +10 -0
- package/schematics/ng-update/find-stylesheets.js +31 -0
- package/schematics/ng-update/index.d.ts +2 -0
- package/schematics/ng-update/index.js +7 -2
- package/schematics/ng-update/migrations/attribute-selectors.js +3 -3
- package/schematics/ng-update/migrations/css-selectors.js +3 -3
- package/schematics/ng-update/migrations/element-selectors.js +3 -3
- package/schematics/ng-update/public-api.js +1 -1
- package/schematics/update-tool/component-resource-collector.d.ts +1 -1
- package/schematics/update-tool/component-resource-collector.js +18 -14
- package/schematics/update-tool/file-system.d.ts +19 -14
- package/schematics/update-tool/file-system.js +1 -1
- package/schematics/update-tool/index.d.ts +21 -3
- package/schematics/update-tool/index.js +29 -23
- package/schematics/update-tool/public-api.js +1 -1
- package/schematics/update-tool/target-version.d.ts +2 -1
- package/schematics/update-tool/target-version.js +5 -3
- package/schematics/update-tool/utils/parse-tsconfig.d.ts +2 -1
- package/schematics/update-tool/utils/parse-tsconfig.js +6 -10
- package/schematics/update-tool/utils/virtual-host.d.ts +34 -0
- package/schematics/update-tool/utils/virtual-host.js +62 -0
- package/schematics/update-tool/version-changes.js +4 -6
- package/schematics/utils/index.js +1 -1
- package/schematics/utils/project-tsconfig-paths.d.ts +2 -1
- package/schematics/utils/project-tsconfig-paths.js +1 -1
- package/scrolling/index.metadata.json +1 -1
- package/scrolling/public-api.d.ts +1 -0
- package/scrolling/virtual-for-of.d.ts +2 -1
- package/scrolling/virtual-scroll-repeater.d.ts +16 -0
- package/scrolling/virtual-scroll-viewport.d.ts +4 -4
- package/testing/component-harness.d.ts +12 -0
- package/testing/harness-environment.d.ts +1 -0
- package/tree/control/nested-tree-control.d.ts +7 -2
- package/tree/index.metadata.json +1 -1
- package/esm2015/overlay/keyboard/overlay-keyboard-dispatcher.js +0 -100
|
@@ -24,344 +24,340 @@ function rangesEqual(r1, r2) {
|
|
|
24
24
|
*/
|
|
25
25
|
const SCROLL_SCHEDULER = typeof requestAnimationFrame !== 'undefined' ? animationFrameScheduler : asapScheduler;
|
|
26
26
|
/** A viewport that virtualizes its scrolling with the help of `CdkVirtualForOf`. */
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
export class CdkVirtualScrollViewport extends CdkScrollable {
|
|
28
|
+
constructor(elementRef, _changeDetectorRef, ngZone, _scrollStrategy, dir, scrollDispatcher,
|
|
29
|
+
/**
|
|
30
|
+
* @deprecated `viewportRuler` parameter to become required.
|
|
31
|
+
* @breaking-change 11.0.0
|
|
32
|
+
*/
|
|
33
|
+
viewportRuler) {
|
|
34
|
+
super(elementRef, scrollDispatcher, ngZone, dir);
|
|
35
|
+
this.elementRef = elementRef;
|
|
36
|
+
this._changeDetectorRef = _changeDetectorRef;
|
|
37
|
+
this._scrollStrategy = _scrollStrategy;
|
|
38
|
+
/** Emits when the viewport is detached from a CdkVirtualForOf. */
|
|
39
|
+
this._detachedSubject = new Subject();
|
|
40
|
+
/** Emits when the rendered range changes. */
|
|
41
|
+
this._renderedRangeSubject = new Subject();
|
|
42
|
+
this._orientation = 'vertical';
|
|
43
|
+
// Note: we don't use the typical EventEmitter here because we need to subscribe to the scroll
|
|
44
|
+
// strategy lazily (i.e. only if the user is actually listening to the events). We do this because
|
|
45
|
+
// depending on how the strategy calculates the scrolled index, it may come at a cost to
|
|
46
|
+
// performance.
|
|
47
|
+
/** Emits when the index of the first element visible in the viewport changes. */
|
|
48
|
+
this.scrolledIndexChange = new Observable((observer) => this._scrollStrategy.scrolledIndexChange.subscribe(index => Promise.resolve().then(() => this.ngZone.run(() => observer.next(index)))));
|
|
49
|
+
/** A stream that emits whenever the rendered range changes. */
|
|
50
|
+
this.renderedRangeStream = this._renderedRangeSubject.asObservable();
|
|
30
51
|
/**
|
|
31
|
-
*
|
|
32
|
-
* @breaking-change 11.0.0
|
|
52
|
+
* The total size of all content (in pixels), including content that is not currently rendered.
|
|
33
53
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
// performance.
|
|
48
|
-
/** Emits when the index of the first element visible in the viewport changes. */
|
|
49
|
-
this.scrolledIndexChange = new Observable((observer) => this._scrollStrategy.scrolledIndexChange.subscribe(index => Promise.resolve().then(() => this.ngZone.run(() => observer.next(index)))));
|
|
50
|
-
/** A stream that emits whenever the rendered range changes. */
|
|
51
|
-
this.renderedRangeStream = this._renderedRangeSubject.asObservable();
|
|
52
|
-
/**
|
|
53
|
-
* The total size of all content (in pixels), including content that is not currently rendered.
|
|
54
|
-
*/
|
|
55
|
-
this._totalContentSize = 0;
|
|
56
|
-
/** A string representing the `style.width` property value to be used for the spacer element. */
|
|
57
|
-
this._totalContentWidth = '';
|
|
58
|
-
/** A string representing the `style.height` property value to be used for the spacer element. */
|
|
59
|
-
this._totalContentHeight = '';
|
|
60
|
-
/** The currently rendered range of indices. */
|
|
61
|
-
this._renderedRange = { start: 0, end: 0 };
|
|
62
|
-
/** The length of the data bound to this viewport (in number of items). */
|
|
63
|
-
this._dataLength = 0;
|
|
64
|
-
/** The size of the viewport (in pixels). */
|
|
65
|
-
this._viewportSize = 0;
|
|
66
|
-
/** The last rendered content offset that was set. */
|
|
67
|
-
this._renderedContentOffset = 0;
|
|
68
|
-
/**
|
|
69
|
-
* Whether the last rendered content offset was to the end of the content (and therefore needs to
|
|
70
|
-
* be rewritten as an offset to the start of the content).
|
|
71
|
-
*/
|
|
72
|
-
this._renderedContentOffsetNeedsRewrite = false;
|
|
73
|
-
/** Whether there is a pending change detection cycle. */
|
|
74
|
-
this._isChangeDetectionPending = false;
|
|
75
|
-
/** A list of functions to run after the next change detection cycle. */
|
|
76
|
-
this._runAfterChangeDetection = [];
|
|
77
|
-
/** Subscription to changes in the viewport size. */
|
|
78
|
-
this._viewportChanges = Subscription.EMPTY;
|
|
79
|
-
if (!_scrollStrategy) {
|
|
80
|
-
throw Error('Error: cdk-virtual-scroll-viewport requires the "itemSize" property to be set.');
|
|
81
|
-
}
|
|
82
|
-
// @breaking-change 11.0.0 Remove null check for `viewportRuler`.
|
|
83
|
-
if (viewportRuler) {
|
|
84
|
-
this._viewportChanges = viewportRuler.change().subscribe(() => {
|
|
85
|
-
this.checkViewportSize();
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
/** The direction the viewport scrolls. */
|
|
90
|
-
get orientation() {
|
|
91
|
-
return this._orientation;
|
|
92
|
-
}
|
|
93
|
-
set orientation(orientation) {
|
|
94
|
-
if (this._orientation !== orientation) {
|
|
95
|
-
this._orientation = orientation;
|
|
96
|
-
this._calculateSpacerSize();
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
ngOnInit() {
|
|
100
|
-
super.ngOnInit();
|
|
101
|
-
// It's still too early to measure the viewport at this point. Deferring with a promise allows
|
|
102
|
-
// the Viewport to be rendered with the correct size before we measure. We run this outside the
|
|
103
|
-
// zone to avoid causing more change detection cycles. We handle the change detection loop
|
|
104
|
-
// ourselves instead.
|
|
105
|
-
this.ngZone.runOutsideAngular(() => Promise.resolve().then(() => {
|
|
106
|
-
this._measureViewportSize();
|
|
107
|
-
this._scrollStrategy.attach(this);
|
|
108
|
-
this.elementScrolled()
|
|
109
|
-
.pipe(
|
|
110
|
-
// Start off with a fake scroll event so we properly detect our initial position.
|
|
111
|
-
startWith(null),
|
|
112
|
-
// Collect multiple events into one until the next animation frame. This way if
|
|
113
|
-
// there are multiple scroll events in the same frame we only need to recheck
|
|
114
|
-
// our layout once.
|
|
115
|
-
auditTime(0, SCROLL_SCHEDULER))
|
|
116
|
-
.subscribe(() => this._scrollStrategy.onContentScrolled());
|
|
117
|
-
this._markChangeDetectionNeeded();
|
|
118
|
-
}));
|
|
119
|
-
}
|
|
120
|
-
ngOnDestroy() {
|
|
121
|
-
this.detach();
|
|
122
|
-
this._scrollStrategy.detach();
|
|
123
|
-
// Complete all subjects
|
|
124
|
-
this._renderedRangeSubject.complete();
|
|
125
|
-
this._detachedSubject.complete();
|
|
126
|
-
this._viewportChanges.unsubscribe();
|
|
127
|
-
super.ngOnDestroy();
|
|
128
|
-
}
|
|
129
|
-
/** Attaches a `CdkVirtualForOf` to this viewport. */
|
|
130
|
-
attach(forOf) {
|
|
131
|
-
if (this._forOf) {
|
|
132
|
-
throw Error('CdkVirtualScrollViewport is already attached.');
|
|
133
|
-
}
|
|
134
|
-
// Subscribe to the data stream of the CdkVirtualForOf to keep track of when the data length
|
|
135
|
-
// changes. Run outside the zone to avoid triggering change detection, since we're managing the
|
|
136
|
-
// change detection loop ourselves.
|
|
137
|
-
this.ngZone.runOutsideAngular(() => {
|
|
138
|
-
this._forOf = forOf;
|
|
139
|
-
this._forOf.dataStream.pipe(takeUntil(this._detachedSubject)).subscribe(data => {
|
|
140
|
-
const newLength = data.length;
|
|
141
|
-
if (newLength !== this._dataLength) {
|
|
142
|
-
this._dataLength = newLength;
|
|
143
|
-
this._scrollStrategy.onDataLengthChanged();
|
|
144
|
-
}
|
|
145
|
-
this._doChangeDetection();
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
/** Detaches the current `CdkVirtualForOf`. */
|
|
150
|
-
detach() {
|
|
151
|
-
this._forOf = null;
|
|
152
|
-
this._detachedSubject.next();
|
|
153
|
-
}
|
|
154
|
-
/** Gets the length of the data bound to this viewport (in number of items). */
|
|
155
|
-
getDataLength() {
|
|
156
|
-
return this._dataLength;
|
|
157
|
-
}
|
|
158
|
-
/** Gets the size of the viewport (in pixels). */
|
|
159
|
-
getViewportSize() {
|
|
160
|
-
return this._viewportSize;
|
|
161
|
-
}
|
|
162
|
-
// TODO(mmalerba): This is technically out of sync with what's really rendered until a render
|
|
163
|
-
// cycle happens. I'm being careful to only call it after the render cycle is complete and before
|
|
164
|
-
// setting it to something else, but its error prone and should probably be split into
|
|
165
|
-
// `pendingRange` and `renderedRange`, the latter reflecting whats actually in the DOM.
|
|
166
|
-
/** Get the current rendered range of items. */
|
|
167
|
-
getRenderedRange() {
|
|
168
|
-
return this._renderedRange;
|
|
169
|
-
}
|
|
54
|
+
this._totalContentSize = 0;
|
|
55
|
+
/** A string representing the `style.width` property value to be used for the spacer element. */
|
|
56
|
+
this._totalContentWidth = '';
|
|
57
|
+
/** A string representing the `style.height` property value to be used for the spacer element. */
|
|
58
|
+
this._totalContentHeight = '';
|
|
59
|
+
/** The currently rendered range of indices. */
|
|
60
|
+
this._renderedRange = { start: 0, end: 0 };
|
|
61
|
+
/** The length of the data bound to this viewport (in number of items). */
|
|
62
|
+
this._dataLength = 0;
|
|
63
|
+
/** The size of the viewport (in pixels). */
|
|
64
|
+
this._viewportSize = 0;
|
|
65
|
+
/** The last rendered content offset that was set. */
|
|
66
|
+
this._renderedContentOffset = 0;
|
|
170
67
|
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
68
|
+
* Whether the last rendered content offset was to the end of the content (and therefore needs to
|
|
69
|
+
* be rewritten as an offset to the start of the content).
|
|
173
70
|
*/
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
71
|
+
this._renderedContentOffsetNeedsRewrite = false;
|
|
72
|
+
/** Whether there is a pending change detection cycle. */
|
|
73
|
+
this._isChangeDetectionPending = false;
|
|
74
|
+
/** A list of functions to run after the next change detection cycle. */
|
|
75
|
+
this._runAfterChangeDetection = [];
|
|
76
|
+
/** Subscription to changes in the viewport size. */
|
|
77
|
+
this._viewportChanges = Subscription.EMPTY;
|
|
78
|
+
if (!_scrollStrategy) {
|
|
79
|
+
throw Error('Error: cdk-virtual-scroll-viewport requires the "itemSize" property to be set.');
|
|
180
80
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
this.
|
|
185
|
-
|
|
186
|
-
}
|
|
81
|
+
// @breaking-change 11.0.0 Remove null check for `viewportRuler`.
|
|
82
|
+
if (viewportRuler) {
|
|
83
|
+
this._viewportChanges = viewportRuler.change().subscribe(() => {
|
|
84
|
+
this.checkViewportSize();
|
|
85
|
+
});
|
|
187
86
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
87
|
+
}
|
|
88
|
+
/** The direction the viewport scrolls. */
|
|
89
|
+
get orientation() {
|
|
90
|
+
return this._orientation;
|
|
91
|
+
}
|
|
92
|
+
set orientation(orientation) {
|
|
93
|
+
if (this._orientation !== orientation) {
|
|
94
|
+
this._orientation = orientation;
|
|
95
|
+
this._calculateSpacerSize();
|
|
193
96
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
97
|
+
}
|
|
98
|
+
ngOnInit() {
|
|
99
|
+
super.ngOnInit();
|
|
100
|
+
// It's still too early to measure the viewport at this point. Deferring with a promise allows
|
|
101
|
+
// the Viewport to be rendered with the correct size before we measure. We run this outside the
|
|
102
|
+
// zone to avoid causing more change detection cycles. We handle the change detection loop
|
|
103
|
+
// ourselves instead.
|
|
104
|
+
this.ngZone.runOutsideAngular(() => Promise.resolve().then(() => {
|
|
105
|
+
this._measureViewportSize();
|
|
106
|
+
this._scrollStrategy.attach(this);
|
|
107
|
+
this.elementScrolled()
|
|
108
|
+
.pipe(
|
|
109
|
+
// Start off with a fake scroll event so we properly detect our initial position.
|
|
110
|
+
startWith(null),
|
|
111
|
+
// Collect multiple events into one until the next animation frame. This way if
|
|
112
|
+
// there are multiple scroll events in the same frame we only need to recheck
|
|
113
|
+
// our layout once.
|
|
114
|
+
auditTime(0, SCROLL_SCHEDULER))
|
|
115
|
+
.subscribe(() => this._scrollStrategy.onContentScrolled());
|
|
116
|
+
this._markChangeDetectionNeeded();
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
ngOnDestroy() {
|
|
120
|
+
this.detach();
|
|
121
|
+
this._scrollStrategy.detach();
|
|
122
|
+
// Complete all subjects
|
|
123
|
+
this._renderedRangeSubject.complete();
|
|
124
|
+
this._detachedSubject.complete();
|
|
125
|
+
this._viewportChanges.unsubscribe();
|
|
126
|
+
super.ngOnDestroy();
|
|
127
|
+
}
|
|
128
|
+
/** Attaches a `CdkVirtualScrollRepeater` to this viewport. */
|
|
129
|
+
attach(forOf) {
|
|
130
|
+
if (this._forOf) {
|
|
131
|
+
throw Error('CdkVirtualScrollViewport is already attached.');
|
|
229
132
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
133
|
+
// Subscribe to the data stream of the CdkVirtualForOf to keep track of when the data length
|
|
134
|
+
// changes. Run outside the zone to avoid triggering change detection, since we're managing the
|
|
135
|
+
// change detection loop ourselves.
|
|
136
|
+
this.ngZone.runOutsideAngular(() => {
|
|
137
|
+
this._forOf = forOf;
|
|
138
|
+
this._forOf.dataStream.pipe(takeUntil(this._detachedSubject)).subscribe(data => {
|
|
139
|
+
const newLength = data.length;
|
|
140
|
+
if (newLength !== this._dataLength) {
|
|
141
|
+
this._dataLength = newLength;
|
|
142
|
+
this._scrollStrategy.onDataLengthChanged();
|
|
143
|
+
}
|
|
144
|
+
this._doChangeDetection();
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
/** Detaches the current `CdkVirtualForOf`. */
|
|
149
|
+
detach() {
|
|
150
|
+
this._forOf = null;
|
|
151
|
+
this._detachedSubject.next();
|
|
152
|
+
}
|
|
153
|
+
/** Gets the length of the data bound to this viewport (in number of items). */
|
|
154
|
+
getDataLength() {
|
|
155
|
+
return this._dataLength;
|
|
156
|
+
}
|
|
157
|
+
/** Gets the size of the viewport (in pixels). */
|
|
158
|
+
getViewportSize() {
|
|
159
|
+
return this._viewportSize;
|
|
160
|
+
}
|
|
161
|
+
// TODO(mmalerba): This is technically out of sync with what's really rendered until a render
|
|
162
|
+
// cycle happens. I'm being careful to only call it after the render cycle is complete and before
|
|
163
|
+
// setting it to something else, but its error prone and should probably be split into
|
|
164
|
+
// `pendingRange` and `renderedRange`, the latter reflecting whats actually in the DOM.
|
|
165
|
+
/** Get the current rendered range of items. */
|
|
166
|
+
getRenderedRange() {
|
|
167
|
+
return this._renderedRange;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Sets the total size of all content (in pixels), including content that is not currently
|
|
171
|
+
* rendered.
|
|
172
|
+
*/
|
|
173
|
+
setTotalContentSize(size) {
|
|
174
|
+
if (this._totalContentSize !== size) {
|
|
175
|
+
this._totalContentSize = size;
|
|
176
|
+
this._calculateSpacerSize();
|
|
177
|
+
this._markChangeDetectionNeeded();
|
|
246
178
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
this._scrollStrategy.scrollToIndex(index, behavior);
|
|
179
|
+
}
|
|
180
|
+
/** Sets the currently rendered range of indices. */
|
|
181
|
+
setRenderedRange(range) {
|
|
182
|
+
if (!rangesEqual(this._renderedRange, range)) {
|
|
183
|
+
this._renderedRangeSubject.next(this._renderedRange = range);
|
|
184
|
+
this._markChangeDetectionNeeded(() => this._scrollStrategy.onContentRendered());
|
|
254
185
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Gets the offset from the start of the viewport to the start of the rendered data (in pixels).
|
|
189
|
+
*/
|
|
190
|
+
getOffsetToRenderedContentStart() {
|
|
191
|
+
return this._renderedContentOffsetNeedsRewrite ? null : this._renderedContentOffset;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Sets the offset from the start of the viewport to either the start or end of the rendered data
|
|
195
|
+
* (in pixels).
|
|
196
|
+
*/
|
|
197
|
+
setRenderedContentOffset(offset, to = 'to-start') {
|
|
198
|
+
// For a horizontal viewport in a right-to-left language we need to translate along the x-axis
|
|
199
|
+
// in the negative direction.
|
|
200
|
+
const isRtl = this.dir && this.dir.value == 'rtl';
|
|
201
|
+
const isHorizontal = this.orientation == 'horizontal';
|
|
202
|
+
const axis = isHorizontal ? 'X' : 'Y';
|
|
203
|
+
const axisDirection = isHorizontal && isRtl ? -1 : 1;
|
|
204
|
+
let transform = `translate${axis}(${Number(axisDirection * offset)}px)`;
|
|
205
|
+
this._renderedContentOffset = offset;
|
|
206
|
+
if (to === 'to-end') {
|
|
207
|
+
transform += ` translate${axis}(-100%)`;
|
|
208
|
+
// The viewport should rewrite this as a `to-start` offset on the next render cycle. Otherwise
|
|
209
|
+
// elements will appear to expand in the wrong direction (e.g. `mat-expansion-panel` would
|
|
210
|
+
// expand upward).
|
|
211
|
+
this._renderedContentOffsetNeedsRewrite = true;
|
|
264
212
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
213
|
+
if (this._renderedContentTransform != transform) {
|
|
214
|
+
// We know this value is safe because we parse `offset` with `Number()` before passing it
|
|
215
|
+
// into the string.
|
|
216
|
+
this._renderedContentTransform = transform;
|
|
217
|
+
this._markChangeDetectionNeeded(() => {
|
|
218
|
+
if (this._renderedContentOffsetNeedsRewrite) {
|
|
219
|
+
this._renderedContentOffset -= this.measureRenderedContentSize();
|
|
220
|
+
this._renderedContentOffsetNeedsRewrite = false;
|
|
221
|
+
this.setRenderedContentOffset(this._renderedContentOffset);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
this._scrollStrategy.onRenderedOffsetChanged();
|
|
225
|
+
}
|
|
226
|
+
});
|
|
269
227
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Scrolls to the given offset from the start of the viewport. Please note that this is not always
|
|
231
|
+
* the same as setting `scrollTop` or `scrollLeft`. In a horizontal viewport with right-to-left
|
|
232
|
+
* direction, this would be the equivalent of setting a fictional `scrollRight` property.
|
|
233
|
+
* @param offset The offset to scroll to.
|
|
234
|
+
* @param behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.
|
|
235
|
+
*/
|
|
236
|
+
scrollToOffset(offset, behavior = 'auto') {
|
|
237
|
+
const options = { behavior };
|
|
238
|
+
if (this.orientation === 'horizontal') {
|
|
239
|
+
options.start = offset;
|
|
279
240
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
// TODO: Cleanup later when add logic for handling content resize
|
|
283
|
-
this._measureViewportSize();
|
|
284
|
-
this._scrollStrategy.onDataLengthChanged();
|
|
241
|
+
else {
|
|
242
|
+
options.top = offset;
|
|
285
243
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
244
|
+
this.scrollTo(options);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Scrolls to the offset for the given index.
|
|
248
|
+
* @param index The index of the element to scroll to.
|
|
249
|
+
* @param behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.
|
|
250
|
+
*/
|
|
251
|
+
scrollToIndex(index, behavior = 'auto') {
|
|
252
|
+
this._scrollStrategy.scrollToIndex(index, behavior);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Gets the current scroll offset from the start of the viewport (in pixels).
|
|
256
|
+
* @param from The edge to measure the offset from. Defaults to 'top' in vertical mode and 'start'
|
|
257
|
+
* in horizontal mode.
|
|
258
|
+
*/
|
|
259
|
+
measureScrollOffset(from) {
|
|
260
|
+
return from ?
|
|
261
|
+
super.measureScrollOffset(from) :
|
|
262
|
+
super.measureScrollOffset(this.orientation === 'horizontal' ? 'start' : 'top');
|
|
263
|
+
}
|
|
264
|
+
/** Measure the combined size of all of the rendered items. */
|
|
265
|
+
measureRenderedContentSize() {
|
|
266
|
+
const contentEl = this._contentWrapper.nativeElement;
|
|
267
|
+
return this.orientation === 'horizontal' ? contentEl.offsetWidth : contentEl.offsetHeight;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Measure the total combined size of the given range. Throws if the range includes items that are
|
|
271
|
+
* not rendered.
|
|
272
|
+
*/
|
|
273
|
+
measureRangeSize(range) {
|
|
274
|
+
if (!this._forOf) {
|
|
275
|
+
return 0;
|
|
291
276
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
277
|
+
return this._forOf.measureRangeSize(range, this.orientation);
|
|
278
|
+
}
|
|
279
|
+
/** Update the viewport dimensions and re-render. */
|
|
280
|
+
checkViewportSize() {
|
|
281
|
+
// TODO: Cleanup later when add logic for handling content resize
|
|
282
|
+
this._measureViewportSize();
|
|
283
|
+
this._scrollStrategy.onDataLengthChanged();
|
|
284
|
+
}
|
|
285
|
+
/** Measure the viewport size. */
|
|
286
|
+
_measureViewportSize() {
|
|
287
|
+
const viewportEl = this.elementRef.nativeElement;
|
|
288
|
+
this._viewportSize = this.orientation === 'horizontal' ?
|
|
289
|
+
viewportEl.clientWidth : viewportEl.clientHeight;
|
|
290
|
+
}
|
|
291
|
+
/** Queue up change detection to run. */
|
|
292
|
+
_markChangeDetectionNeeded(runAfter) {
|
|
293
|
+
if (runAfter) {
|
|
294
|
+
this._runAfterChangeDetection.push(runAfter);
|
|
305
295
|
}
|
|
306
|
-
|
|
307
|
-
_doChangeDetection
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
this._contentWrapper.nativeElement.style.transform = this._renderedContentTransform;
|
|
314
|
-
// Apply changes to Angular bindings. Note: We must call `markForCheck` to run change detection
|
|
315
|
-
// from the root, since the repeated items are content projected in. Calling `detectChanges`
|
|
316
|
-
// instead does not properly check the projected content.
|
|
317
|
-
this.ngZone.run(() => this._changeDetectorRef.markForCheck());
|
|
318
|
-
const runAfterChangeDetection = this._runAfterChangeDetection;
|
|
319
|
-
this._runAfterChangeDetection = [];
|
|
320
|
-
for (const fn of runAfterChangeDetection) {
|
|
321
|
-
fn();
|
|
322
|
-
}
|
|
296
|
+
// Use a Promise to batch together calls to `_doChangeDetection`. This way if we set a bunch of
|
|
297
|
+
// properties sequentially we only have to run `_doChangeDetection` once at the end.
|
|
298
|
+
if (!this._isChangeDetectionPending) {
|
|
299
|
+
this._isChangeDetectionPending = true;
|
|
300
|
+
this.ngZone.runOutsideAngular(() => Promise.resolve().then(() => {
|
|
301
|
+
this._doChangeDetection();
|
|
302
|
+
}));
|
|
323
303
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
304
|
+
}
|
|
305
|
+
/** Run change detection. */
|
|
306
|
+
_doChangeDetection() {
|
|
307
|
+
this._isChangeDetectionPending = false;
|
|
308
|
+
// Apply the content transform. The transform can't be set via an Angular binding because
|
|
309
|
+
// bypassSecurityTrustStyle is banned in Google. However the value is safe, it's composed of
|
|
310
|
+
// string literals, a variable that can only be 'X' or 'Y', and user input that is run through
|
|
311
|
+
// the `Number` function first to coerce it to a numeric value.
|
|
312
|
+
this._contentWrapper.nativeElement.style.transform = this._renderedContentTransform;
|
|
313
|
+
// Apply changes to Angular bindings. Note: We must call `markForCheck` to run change detection
|
|
314
|
+
// from the root, since the repeated items are content projected in. Calling `detectChanges`
|
|
315
|
+
// instead does not properly check the projected content.
|
|
316
|
+
this.ngZone.run(() => this._changeDetectorRef.markForCheck());
|
|
317
|
+
const runAfterChangeDetection = this._runAfterChangeDetection;
|
|
318
|
+
this._runAfterChangeDetection = [];
|
|
319
|
+
for (const fn of runAfterChangeDetection) {
|
|
320
|
+
fn();
|
|
330
321
|
}
|
|
331
322
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
},
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlydHVhbC1zY3JvbGwtdmlld3BvcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvY2RrL3Njcm9sbGluZy92aXJ0dWFsLXNjcm9sbC12aWV3cG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFFakQsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFHTixRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFDVCxpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixhQUFhLEVBQ2IsVUFBVSxFQUNWLE9BQU8sRUFFUCxZQUFZLEdBQ2IsTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQUMsYUFBYSxFQUEwQixNQUFNLGNBQWMsQ0FBQztBQUVwRSxPQUFPLEVBQUMsdUJBQXVCLEVBQXdCLE1BQU0sMkJBQTJCLENBQUM7QUFDekYsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBRS9DLDRDQUE0QztBQUM1QyxTQUFTLFdBQVcsQ0FBQyxFQUFhLEVBQUUsRUFBYTtJQUMvQyxPQUFPLEVBQUUsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUM7QUFDbEQsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLGdCQUFnQixHQUNsQixPQUFPLHFCQUFxQixLQUFLLFdB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QyxDQUFDOztpQkFDSDs7O2dCQXhEQyxVQUFVO2dCQUZWLGlCQUFpQjtnQkFLakIsTUFBTTtnREE0SU8sUUFBUSxZQUFJLE1BQU0sU0FBQyx1QkFBdUI7Z0JBckpqRCxjQUFjLHVCQXVKUCxRQUFRO2dCQTdIZixnQkFBZ0I7Z0JBSWhCLGFBQWEsdUJBK0hOLFFBQVE7Ozs4QkF0RnBCLEtBQUs7c0NBaUJMLE1BQU07a0NBTU4sU0FBUyxTQUFDLGdCQUFnQixFQUFFLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQzs7SUFrVjdDLCtCQUFDO0tBQUE7U0FqWFksd0JBQXdCIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7RGlyZWN0aW9uYWxpdHl9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7TGlzdFJhbmdlfSBmcm9tICdAYW5ndWxhci9jZGsvY29sbGVjdGlvbnMnO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgYW5pbWF0aW9uRnJhbWVTY2hlZHVsZXIsXG4gIGFzYXBTY2hlZHVsZXIsXG4gIE9ic2VydmFibGUsXG4gIFN1YmplY3QsXG4gIE9ic2VydmVyLFxuICBTdWJzY3JpcHRpb24sXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHthdWRpdFRpbWUsIHN0YXJ0V2l0aCwgdGFrZVVudGlsfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1Njcm9sbERpc3BhdGNoZXJ9IGZyb20gJy4vc2Nyb2xsLWRpc3BhdGNoZXInO1xuaW1wb3J0IHtDZGtTY3JvbGxhYmxlLCBFeHRlbmRlZFNjcm9sbFRvT3B0aW9uc30gZnJvbSAnLi9zY3JvbGxhYmxlJztcbmltcG9ydCB7Q2RrVmlydHVhbEZvck9mfSBmcm9tICcuL3ZpcnR1YWwtZm9yLW9mJztcbmltcG9ydCB7VklSVFVBTF9TQ1JPTExfU1RSQVRFR1ksIFZpcnR1YWxTY3JvbGxTdHJhdGVneX0gZnJvbSAnLi92aXJ0dWFsLXNjcm9sbC1zdHJhdGVneSc7XG5pbXBvcnQge1ZpZXdwb3J0UnVsZXJ9IGZyb20gJy4vdmlld3BvcnQtcnVsZXInO1xuXG4vKiogQ2hlY2tzIGlmIHRoZSBnaXZlbiByYW5nZXMgYXJlIGVxdWFsLiAqL1xuZnVuY3Rpb24gcmFuZ2VzRXF1YWwocjE6IExpc3RSYW5nZSwgcjI6IExpc3RSYW5nZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gcjEuc3RhcnQgPT0gcjIuc3RhcnQgJiYgcjEuZW5kID09IHIyLmVuZDtcbn1cblxuLyoqXG4gKiBTY2hlZHVsZXIgdG8gYmUgdXNlZCBmb3Igc2Nyb2xsIGV2ZW50cy4gTmVlZHMgdG8gZmFsbCBiYWNrIHRvXG4gKiBzb21ldGhpbmcgdGhhdCBkb2Vzbid0IHJlbHkgb24gcmVxdWVzdEFuaW1hdGlvbkZyYW1lIG9uIGVudmlyb25tZW50c1xuICogdGhhdCBkb24ndCBzdXBwb3J0IGl0IChlLmcuIHNlcnZlci1zaWRlIHJlbmRlcmluZykuXG4gKi9cbmNvbnN0IFNDUk9MTF9TQ0hFRFVMRVIgPVxuICAgIHR5cGVvZiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgIT09ICd1bmRlZmluZWQnID8gYW5pbWF0aW9uRnJhbWVTY2hlZHVsZXIgOiBhc2FwU2NoZWR1bGVyO1xuXG5cbi8qKiBBIHZpZXdwb3J0IHRoYXQgdmlydHVhbGl6ZXMgaXRzIHNjcm9sbGluZyB3aXRoIHRoZSBoZWxwIG9mIGBDZGtWaXJ0dWFsRm9yT2ZgLiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY2RrLXZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0JyxcbiAgdGVtcGxhdGVVcmw6ICd2aXJ0dWFsLXNjcm9sbC12aWV3cG9ydC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJ3ZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0LmNzcyddLFxuICBob3N0OiB7XG4gICAgJ2NsYXNzJzogJ2Nkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydCcsXG4gICAgJ1tjbGFzcy5jZGstdmlydHVhbC1zY3JvbGwtb3JpZW50YXRpb24taG9yaXpvbnRhbF0nOiAnb3JpZW50YXRpb24gPT09IFwiaG9yaXpvbnRhbFwiJyxcbiAgICAnW2NsYXNzLmNkay12aXJ0dWFsLXNjcm9sbC1vcmllbnRhdGlvbi12ZXJ0aWNhbF0nOiAnb3JpZW50YXRpb24gIT09IFwiaG9yaXpvbnRhbFwiJyxcbiAgfSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHByb3ZpZGVyczogW3tcbiAgICBwcm92aWRlOiBDZGtTY3JvbGxhYmxlLFxuICAgIHVzZUV4aXN0aW5nOiBDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQsXG4gIH1dXG59KVxuZXhwb3J0IGNsYXNzIENka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydCBleHRlbmRzIENka1Njcm9sbGFibGUgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIC8qKiBFbWl0cyB3aGVuIHRoZSB2aWV3cG9ydCBpcyBkZXRhY2hlZCBmcm9tIGEgQ2RrVmlydHVhbEZvck9mLiAqL1xuICBwcml2YXRlIF9kZXRhY2hlZFN1YmplY3QgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIC8qKiBFbWl0cyB3aGVuIHRoZSByZW5kZXJlZCByYW5nZSBjaGFuZ2VzLiAqL1xuICBwcml2YXRlIF9yZW5kZXJlZFJhbmdlU3ViamVjdCA9IG5ldyBTdWJqZWN0PExpc3RSYW5nZT4oKTtcblxuICAvKiogVGhlIGRpcmVjdGlvbiB0aGUgdmlld3BvcnQgc2Nyb2xscy4gKi9cbiAgQElucHV0KClcbiAgZ2V0IG9yaWVudGF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl9vcmllbnRhdGlvbjtcbiAgfVxuICBzZXQgb3JpZW50YXRpb24ob3JpZW50YXRpb246ICdob3Jpem9udGFsJyB8ICd2ZXJ0aWNhbCcpIHtcbiAgICBpZiAodGhpcy5fb3JpZW50YXRpb24gIT09IG9yaWVudGF0aW9uKSB7XG4gICAgICB0aGlzLl9vcmllbnRhdGlvbiA9IG9yaWVudGF0aW9uO1xuICAgICAgdGhpcy5fY2FsY3VsYXRlU3BhY2VyU2l6ZSgpO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIF9vcmllbnRhdGlvbjogJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJyA9ICd2ZXJ0aWNhbCc7XG5cbiAgLy8gTm90ZTogd2UgZG9uJ3QgdXNlIHRoZSB0eXBpY2FsIEV2ZW50RW1pdHRlciBoZXJlIGJlY2F1c2Ugd2UgbmVlZCB0byBzdWJzY3JpYmUgdG8gdGhlIHNjcm9sbFxuICAvLyBzdHJhdGVneSBsYXppbHkgKGkuZS4gb25seSBpZiB0aGUgdXNlciBpcyBhY3R1YWxseSBsaXN0ZW5pbmcgdG8gdGhlIGV2ZW50cykuIFdlIGRvIHRoaXMgYmVjYXVzZVxuICAvLyBkZXBlbmRpbmcgb24gaG93IHRoZSBzdHJhdGVneSBjYWxjdWxhdGVzIHRoZSBzY3JvbGxlZCBpbmRleCwgaXQgbWF5IGNvbWUgYXQgYSBjb3N0IHRvXG4gIC8vIHBlcmZvcm1hbmNlLlxuICAvKiogRW1pdHMgd2hlbiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQgdmlzaWJsZSBpbiB0aGUgdmlld3BvcnQgY2hhbmdlcy4gKi9cbiAgQE91dHB1dCgpIHNjcm9sbGVkSW5kZXhDaGFuZ2U6IE9ic2VydmFibGU8bnVtYmVyPiA9XG4gICAgICBuZXcgT2JzZXJ2YWJsZSgob2JzZXJ2ZXI6IE9ic2VydmVyPG51bWJlcj4pID0+XG4gICAgICAgIHRoaXMuX3Njcm9sbFN0cmF0ZWd5LnNjcm9sbGVkSW5kZXhDaGFuZ2Uuc3Vic2NyaWJlKGluZGV4ID0+XG4gICAgICAgICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHRoaXMubmdab25lLnJ1bigoKSA9PiBvYnNlcnZlci5uZXh0KGluZGV4KSkpKSk7XG5cbiAgLyoqIFRoZSBlbGVtZW50IHRoYXQgd3JhcHMgdGhlIHJlbmRlcmVkIGNvbnRlbnQuICovXG4gIEBWaWV3Q2hpbGQoJ2NvbnRlbnRXcmFwcGVyJywge3N0YXRpYzogdHJ1ZX0pIF9jb250ZW50V3JhcHBlcjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cbiAgLyoqIEEgc3RyZWFtIHRoYXQgZW1pdHMgd2hlbmV2ZXIgdGhlIHJlbmRlcmVkIHJhbmdlIGNoYW5nZXMuICovXG4gIHJlbmRlcmVkUmFuZ2VTdHJlYW06IE9ic2VydmFibGU8TGlzdFJhbmdlPiA9IHRoaXMuX3JlbmRlcmVkUmFuZ2VTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIC8qKlxuICAgKiBUaGUgdG90YWwgc2l6ZSBvZiBhbGwgY29udGVudCAoaW4gcGl4ZWxzKSwgaW5jbHVkaW5nIGNvbnRlbnQgdGhhdCBpcyBub3QgY3VycmVudGx5IHJlbmRlcmVkLlxuICAgKi9cbiAgcHJpdmF0ZSBfdG90YWxDb250ZW50U2l6ZSA9IDA7XG5cbiAgLyoqIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgYHN0eWxlLndpZHRoYCBwcm9wZXJ0eSB2YWx1ZSB0byBiZSB1c2VkIGZvciB0aGUgc3BhY2VyIGVsZW1lbnQuICovXG4gIF90b3RhbENvbnRlbnRXaWR0aCA9ICcnO1xuXG4gIC8qKiBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGBzdHlsZS5oZWlnaHRgIHByb3BlcnR5IHZhbHVlIHRvIGJlIHVzZWQgZm9yIHRoZSBzcGFjZXIgZWxlbWVudC4gKi9cbiAgX3RvdGFsQ29udGVudEhlaWdodCA9ICcnO1xuXG4gIC8qKlxuICAgKiBUaGUgQ1NTIHRyYW5zZm9ybSBhcHBsaWVkIHRvIHRoZSByZW5kZXJlZCBzdWJzZXQgb2YgaXRlbXMgc28gdGhhdCB0aGV5IGFwcGVhciB3aXRoaW4gdGhlIGJvdW5kc1xuICAgKiBvZiB0aGUgdmlzaWJsZSB2aWV3cG9ydC5cbiAgICovXG4gIHByaXZhdGUgX3JlbmRlcmVkQ29udGVudFRyYW5zZm9ybTogc3RyaW5nO1xuXG4gIC8qKiBUaGUgY3VycmVudGx5IHJlbmRlcmVkIHJhbmdlIG9mIGluZGljZXMuICovXG4gIHByaXZhdGUgX3JlbmRlcmVkUmFuZ2U6IExpc3RSYW5nZSA9IHtzdGFydDogMCwgZW5kOiAwfTtcblxuICAvKiogVGhlIGxlbmd0aCBvZiB0aGUgZGF0YSBib3VuZCB0byB0aGlzIHZpZXdwb3J0IChpbiBudW1iZXIgb2YgaXRlbXMpLiAqL1xuICBwcml2YXRlIF9kYXRhTGVuZ3RoID0gMDtcblxuICAvKiogVGhlIHNpemUgb2YgdGhlIHZpZXdwb3J0IChpbiBwaXhlbHMpLiAqL1xuICBwcml2YXRlIF92aWV3cG9ydFNpemUgPSAwO1xuXG4gIC8qKiB0aGUgY3VycmVudGx5IGF0dGFjaGVkIENka1ZpcnR1YWxGb3JPZi4gKi9cbiAgcHJpdmF0ZSBfZm9yT2Y6IENka1ZpcnR1YWxGb3JPZjxhbnk+IHwgbnVsbDtcblxuICAvKiogVGhlIGxhc3QgcmVuZGVyZWQgY29udGVudCBvZmZzZXQgdGhhdCB3YXMgc2V0LiAqL1xuICBwcml2YXRlIF9yZW5kZXJlZENvbnRlbnRPZmZzZXQgPSAwO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBsYXN0IHJlbmRlcmVkIGNvbnRlbnQgb2Zmc2V0IHdhcyB0byB0aGUgZW5kIG9mIHRoZSBjb250ZW50IChhbmQgdGhlcmVmb3JlIG5lZWRzIHRvXG4gICAqIGJlIHJld3JpdHRlbiBhcyBhbiBvZmZzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBjb250ZW50KS5cbiAgICovXG4gIHByaXZhdGUgX3JlbmRlcmVkQ29udGVudE9mZnNldE5lZWRzUmV3cml0ZSA9IGZhbHNlO1xuXG4gIC8qKiBXaGV0aGVyIHRoZXJlIGlzIGEgcGVuZGluZyBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlLiAqL1xuICBwcml2YXRlIF9pc0NoYW5nZURldGVjdGlvblBlbmRpbmcgPSBmYWxzZTtcblxuICAvKiogQSBsaXN0IG9mIGZ1bmN0aW9ucyB0byBydW4gYWZ0ZXIgdGhlIG5leHQgY2hhbmdlIGRldGVjdGlvbiBjeWNsZS4gKi9cbiAgcHJpdmF0ZSBfcnVuQWZ0ZXJDaGFuZ2VEZXRlY3Rpb246IEZ1bmN0aW9uW10gPSBbXTtcblxuICAvKiogU3Vic2NyaXB0aW9uIHRvIGNoYW5nZXMgaW4gdGhlIHZpZXdwb3J0IHNpemUuICovXG4gIHByaXZhdGUgX3ZpZXdwb3J0Q2hhbmdlcyA9IFN1YnNjcmlwdGlvbi5FTVBUWTtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgZWxlbWVudFJlZjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgICAgICAgICAgIHByaXZhdGUgX2NoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICAgICAgICAgICAgbmdab25lOiBOZ1pvbmUsXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoVklSVFVBTF9TQ1JPTExfU1RSQVRFR1kpXG4gICAgICAgICAgICAgICAgICBwcml2YXRlIF9zY3JvbGxTdHJhdGVneTogVmlydHVhbFNjcm9sbFN0cmF0ZWd5LFxuICAgICAgICAgICAgICBAT3B0aW9uYWwoKSBkaXI6IERpcmVjdGlvbmFsaXR5LFxuICAgICAgICAgICAgICBzY3JvbGxEaXNwYXRjaGVyOiBTY3JvbGxEaXNwYXRjaGVyLFxuICAgICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAgICogQGRlcHJlY2F0ZWQgYHZpZXdwb3J0UnVsZXJgIHBhcmFtZXRlciB0byBiZWNvbWUgcmVxdWlyZWQuXG4gICAgICAgICAgICAgICAqIEBicmVha2luZy1jaGFuZ2UgMTEuMC4wXG4gICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICBAT3B0aW9uYWwoKSB2aWV3cG9ydFJ1bGVyPzogVmlld3BvcnRSdWxlcikge1xuICAgIHN1cGVyKGVsZW1lbnRSZWYsIHNjcm9sbERpc3BhdGNoZXIsIG5nWm9uZSwgZGlyKTtcblxuICAgIGlmICghX3Njcm9sbFN0cmF0ZWd5KSB7XG4gICAgICB0aHJvdyBFcnJvcignRXJyb3I6IGNkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydCByZXF1aXJlcyB0aGUgXCJpdGVtU2l6ZVwiIHByb3BlcnR5IHRvIGJlIHNldC4nKTtcbiAgICB9XG5cbiAgICAvLyBAYnJlYWtpbmctY2hhbmdlIDExLjAuMCBSZW1vdmUgbnVsbCBjaGVjayBmb3IgYHZpZXdwb3J0UnVsZXJgLlxuICAgIGlmICh2aWV3cG9ydFJ1bGVyKSB7XG4gICAgICB0aGlzLl92aWV3cG9ydENoYW5nZXMgPSB2aWV3cG9ydFJ1bGVyLmNoYW5nZSgpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuY2hlY2tWaWV3cG9ydFNpemUoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHN1cGVyLm5nT25Jbml0KCk7XG5cbiAgICAvLyBJdCdzIHN0aWxsIHRvbyBlYXJseSB0byBtZWFzdXJlIHRoZSB2aWV3cG9ydCBhdCB0aGlzIHBvaW50LiBEZWZlcnJpbmcgd2l0aCBhIHByb21pc2UgYWxsb3dzXG4gICAgLy8gdGhlIFZpZXdwb3J0IHRvIGJlIHJlbmRlcmVkIHdpdGggdGhlIGNvcnJlY3Qgc2l6ZSBiZWZvcmUgd2UgbWVhc3VyZS4gV2UgcnVuIHRoaXMgb3V0c2lkZSB0aGVcbiAgICAvLyB6b25lIHRvIGF2b2lkIGNhdXNpbmcgbW9yZSBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlcy4gV2UgaGFuZGxlIHRoZSBjaGFuZ2UgZGV0ZWN0aW9uIGxvb3BcbiAgICAvLyBvdXJzZWx2ZXMgaW5zdGVhZC5cbiAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMuX21lYXN1cmVWaWV3cG9ydFNpemUoKTtcbiAgICAgIHRoaXMuX3Njcm9sbFN0cmF0ZWd5LmF0dGFjaCh0aGlzKTtcblxuICAgICAgdGhpcy5lbGVtZW50U2Nyb2xsZWQoKVxuICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAvLyBTdGFydCBvZmYgd2l0aCBhIGZha2Ugc2Nyb2xsIGV2ZW50IHNvIHdlIHByb3Blcmx5IGRldGVjdCBvdXIgaW5pdGlhbCBwb3NpdGlvbi5cbiAgICAgICAgICAgICAgc3RhcnRXaXRoKG51bGwhKSxcbiAgICAgICAgICAgICAgLy8gQ29sbGVjdCBtdWx0aXBsZSBldmVudHMgaW50byBvbmUgdW50aWwgdGhlIG5leHQgYW5pbWF0aW9uIGZyYW1lLiBUaGlzIHdheSBpZlxuICAgICAgICAgICAgICAvLyB0aGVyZSBhcmUgbXVsdGlwbGUgc2Nyb2xsIGV2ZW50cyBpbiB0aGUgc2FtZSBmcmFtZSB3ZSBvbmx5IG5lZWQgdG8gcmVjaGVja1xuICAgICAgICAgICAgICAvLyBvdXIgbGF5b3V0IG9uY2UuXG4gICAgICAgICAgICAgIGF1ZGl0VGltZSgwLCBTQ1JPTExfU0NIRURVTEVSKSlcbiAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuX3Njcm9sbFN0cmF0ZWd5Lm9uQ29udGVudFNjcm9sbGVkKCkpO1xuXG4gICAgICB0aGlzLl9tYXJrQ2hhbmdlRGV0ZWN0aW9uTmVlZGVkKCk7XG4gICAgfSkpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5kZXRhY2goKTtcbiAgICB0aGlzLl9zY3JvbGxTdHJhdGVneS5kZXRhY2goKTtcblxuICAgIC8vIENvbXBsZXRlIGFsbCBzdWJqZWN0c1xuICAgIHRoaXMuX3JlbmRlcmVkUmFuZ2VTdWJqZWN0LmNvbXBsZXRlKCk7XG4gICAgdGhpcy5fZGV0YWNoZWRTdWJqZWN0LmNvbXBsZXRlKCk7XG4gICAgdGhpcy5fdmlld3BvcnRDaGFuZ2VzLnVuc3Vic2NyaWJlKCk7XG5cbiAgICBzdXBlci5uZ09uRGVzdHJveSgpO1xuICB9XG5cbiAgLyoqIEF0dGFjaGVzIGEgYENka1ZpcnR1YWxGb3JPZmAgdG8gdGhpcyB2aWV3cG9ydC4gKi9cbiAgYXR0YWNoKGZvck9mOiBDZGtWaXJ0dWFsRm9yT2Y8YW55Pikge1xuICAgIGlmICh0aGlzLl9mb3JPZikge1xuICAgICAgdGhyb3cgRXJyb3IoJ0Nka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydCBpcyBhbHJlYWR5IGF0dGFjaGVkLicpO1xuICAgIH1cblxuICAgIC8vIFN1YnNjcmliZSB0byB0aGUgZGF0YSBzdHJlYW0gb2YgdGhlIENka1ZpcnR1YWxGb3JPZiB0byBrZWVwIHRyYWNrIG9mIHdoZW4gdGhlIGRhdGEgbGVuZ3RoXG4gICAgLy8gY2hhbmdlcy4gUnVuIG91dHNpZGUgdGhlIHpvbmUgdG8gYXZvaWQgdHJpZ2dlcmluZyBjaGFuZ2UgZGV0ZWN0aW9uLCBzaW5jZSB3ZSdyZSBtYW5hZ2luZyB0aGVcbiAgICAvLyBjaGFuZ2UgZGV0ZWN0aW9uIGxvb3Agb3Vyc2VsdmVzLlxuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIHRoaXMuX2Zvck9mID0gZm9yT2Y7XG4gICAgICB0aGlzLl9mb3JPZi5kYXRhU3RyZWFtLnBpcGUodGFrZVVudGlsKHRoaXMuX2RldGFjaGVkU3ViamVjdCkpLnN1YnNjcmliZShkYXRhID0+IHtcbiAgICAgICAgY29uc3QgbmV3TGVuZ3RoID0gZGF0YS5sZW5ndGg7XG4gICAgICAgIGlmIChuZXdMZW5ndGggIT09IHRoaXMuX2RhdGFMZW5ndGgpIHtcbiAgICAgICAgICB0aGlzLl9kYXRhTGVuZ3RoID0gbmV3TGVuZ3RoO1xuICAgICAgICAgIHRoaXMuX3Njcm9sbFN0cmF0ZWd5Lm9uRGF0YUxlbmd0aENoYW5nZWQoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9kb0NoYW5nZURldGVjdGlvbigpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKiogRGV0YWNoZXMgdGhlIGN1cnJlbnQgYENka1ZpcnR1YWxGb3JPZmAuICovXG4gIGRldGFjaCgpIHtcbiAgICB0aGlzLl9mb3JPZiA9IG51bGw7XG4gICAgdGhpcy5fZGV0YWNoZWRTdWJqZWN0Lm5leHQoKTtcbiAgfVxuXG4gIC8qKiBHZXRzIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgYm91bmQgdG8gdGhpcyB2aWV3cG9ydCAoaW4gbnVtYmVyIG9mIGl0ZW1zKS4gKi9cbiAgZ2V0RGF0YUxlbmd0aCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9kYXRhTGVuZ3RoO1xuICB9XG5cbiAgLyoqIEdldHMgdGhlIHNpemUgb2YgdGhlIHZpZXdwb3J0IChpbiBwaXhlbHMpLiAqL1xuICBnZXRWaWV3cG9ydFNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fdmlld3BvcnRTaXplO1xuICB9XG5cbiAgLy8gVE9ETyhtbWFsZXJiYSk6IFRoaXMgaXMgdGVjaG5pY2FsbHkgb3V0IG9mIHN5bmMgd2l0aCB3aGF0J3MgcmVhbGx5IHJlbmRlcmVkIHVudGlsIGEgcmVuZGVyXG4gIC8vIGN5Y2xlIGhhcHBlbnMuIEknbSBiZWluZyBjYXJlZnVsIHRvIG9ubHkgY2FsbCBpdCBhZnRlciB0aGUgcmVuZGVyIGN5Y2xlIGlzIGNvbXBsZXRlIGFuZCBiZWZvcmVcbiAgLy8gc2V0dGluZyBpdCB0byBzb21ldGhpbmcgZWxzZSwgYnV0IGl0cyBlcnJvciBwcm9uZSBhbmQgc2hvdWxkIHByb2JhYmx5IGJlIHNwbGl0IGludG9cbiAgLy8gYHBlbmRpbmdSYW5nZWAgYW5kIGByZW5kZXJlZFJhbmdlYCwgdGhlIGxhdHRlciByZWZsZWN0aW5nIHdoYXRzIGFjdHVhbGx5IGluIHRoZSBET00uXG5cbiAgLyoqIEdldCB0aGUgY3VycmVudCByZW5kZXJlZCByYW5nZSBvZiBpdGVtcy4gKi9cbiAgZ2V0UmVuZGVyZWRSYW5nZSgpOiBMaXN0UmFuZ2Uge1xuICAgIHJldHVybiB0aGlzLl9yZW5kZXJlZFJhbmdlO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHRvdGFsIHNpemUgb2YgYWxsIGNvbnRlbnQgKGluIHBpeGVscyksIGluY2x1ZGluZyBjb250ZW50IHRoYXQgaXMgbm90IGN1cnJlbnRseVxuICAgKiByZW5kZXJlZC5cbiAgICovXG4gIHNldFRvdGFsQ29udGVudFNpemUoc2l6ZTogbnVtYmVyKSB7XG4gICAgaWYgKHRoaXMuX3RvdGFsQ29udGVudFNpemUgIT09IHNpemUpIHtcbiAgICAgIHRoaXMuX3RvdGFsQ29udGVudFNpemUgPSBzaXplO1xuICAgICAgdGhpcy5fY2FsY3VsYXRlU3BhY2VyU2l6ZSgpO1xuICAgICAgdGhpcy5fbWFya0NoYW5nZURldGVjdGlvbk5lZWRlZCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBTZXRzIHRoZSBjdXJyZW50bHkgcmVuZGVyZWQgcmFuZ2Ugb2YgaW5kaWNlcy4gKi9cbiAgc2V0UmVuZGVyZWRSYW5nZShyYW5nZTogTGlzdFJhbmdlKSB7XG4gICAgaWYgKCFyYW5nZXNFcXVhbCh0aGlzLl9yZW5kZXJlZFJhbmdlLCByYW5nZSkpIHtcbiAgICAgIHRoaXMuX3JlbmRlcmVkUmFuZ2VTdWJqZWN0Lm5leHQodGhpcy5fcmVuZGVyZWRSYW5nZSA9IHJhbmdlKTtcbiAgICAgIHRoaXMuX21hcmtDaGFuZ2VEZXRlY3Rpb25OZWVkZWQoKCkgPT4gdGhpcy5fc2Nyb2xsU3RyYXRlZ3kub25Db250ZW50UmVuZGVyZWQoKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmlld3BvcnQgdG8gdGhlIHN0YXJ0IG9mIHRoZSByZW5kZXJlZCBkYXRhIChpbiBwaXhlbHMpLlxuICAgKi9cbiAgZ2V0T2Zmc2V0VG9SZW5kZXJlZENvbnRlbnRTdGFydCgpOiBudW1iZXIgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fcmVuZGVyZWRDb250ZW50T2Zmc2V0TmVlZHNSZXdyaXRlID8gbnVsbCA6IHRoaXMuX3JlbmRlcmVkQ29udGVudE9mZnNldDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZpZXdwb3J0IHRvIGVpdGhlciB0aGUgc3RhcnQgb3IgZW5kIG9mIHRoZSByZW5kZXJlZCBkYXRhXG4gICAqIChpbiBwaXhlbHMpLlxuICAgKi9cbiAgc2V0UmVuZGVyZWRDb250ZW50T2Zmc2V0KG9mZnNldDogbnVtYmVyLCB0bzogJ3RvLXN0YXJ0JyB8ICd0by1lbmQnID0gJ3RvLXN0YXJ0Jykge1xuICAgIC8vIEZvciBhIGhvcml6b250YWwgdmlld3BvcnQgaW4gYSByaWdodC10by1sZWZ0IGxhbmd1YWdlIHdlIG5lZWQgdG8gdHJhbnNsYXRlIGFsb25nIHRoZSB4LWF4aXNcbiAgICAvLyBpbiB0aGUgbmVnYXRpdmUgZGlyZWN0aW9uLlxuICAgIGNvbnN0IGlzUnRsID0gdGhpcy5kaXIgJiYgdGhpcy5kaXIudmFsdWUgPT0gJ3J0bCc7XG4gICAgY29uc3QgaXNIb3Jpem9udGFsID0gdGhpcy5vcmllbnRhdGlvbiA9PSAnaG9yaXpvbnRhbCc7XG4gICAgY29uc3QgYXhpcyA9IGlzSG9yaXpvbnRhbCA/ICdYJyA6ICdZJztcbiAgICBjb25zdCBheGlzRGlyZWN0aW9uID0gaXNIb3Jpem9udGFsICYmIGlzUnRsID8gLTEgOiAxO1xuICAgIGxldCB0cmFuc2Zvcm0gPSBgdHJhbnNsYXRlJHtheGlzfSgke051bWJlcihheGlzRGlyZWN0aW9uICogb2Zmc2V0KX1weClgO1xuICAgIHRoaXMuX3JlbmRlcmVkQ29udGVudE9mZnNldCA9IG9mZnNldDtcbiAgICBpZiAodG8gPT09ICd0by1lbmQnKSB7XG4gICAgICB0cmFuc2Zvcm0gKz0gYCB0cmFuc2xhdGUke2F4aXN9KC0xMDAlKWA7XG4gICAgICAvLyBUaGUgdmlld3BvcnQgc2hvdWxkIHJld3JpdGUgdGhpcyBhcyBhIGB0by1zdGFydGAgb2Zmc2V0IG9uIHRoZSBuZXh0IHJlbmRlciBjeWNsZS4gT3RoZXJ3aXNlXG4gICAgICAvLyBlbGVtZW50cyB3aWxsIGFwcGVhciB0byBleHBhbmQgaW4gdGhlIHdyb25nIGRpcmVjdGlvbiAoZS5nLiBgbWF0LWV4cGFuc2lvbi1wYW5lbGAgd291bGRcbiAgICAgIC8vIGV4cGFuZCB1cHdhcmQpLlxuICAgICAgdGhpcy5fcmVuZGVyZWRDb250ZW50T2Zmc2V0TmVlZHNSZXdyaXRlID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX3JlbmRlcmVkQ29udGVudFRyYW5zZm9ybSAhPSB0cmFuc2Zvcm0pIHtcbiAgICAgIC8vIFdlIGtub3cgdGhpcyB2YWx1ZSBpcyBzYWZlIGJlY2F1c2Ugd2UgcGFyc2UgYG9mZnNldGAgd2l0aCBgTnVtYmVyKClgIGJlZm9yZSBwYXNzaW5nIGl0XG4gICAgICAvLyBpbnRvIHRoZSBzdHJpbmcuXG4gICAgICB0aGlzLl9yZW5kZXJlZENvbnRlbnRUcmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgICB0aGlzLl9tYXJrQ2hhbmdlRGV0ZWN0aW9uTmVlZGVkKCgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuX3JlbmRlcmVkQ29udGVudE9mZnNldE5lZWRzUmV3cml0ZSkge1xuICAgICAgICAgIHRoaXMuX3JlbmRlcmVkQ29udGVudE9mZnNldCAtPSB0aGlzLm1lYXN1cmVSZW5kZXJlZENvbnRlbnRTaXplKCk7XG4gICAgICAgICAgdGhpcy5fcmVuZGVyZWRDb250ZW50T2Zmc2V0TmVlZHNSZXdyaXRlID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5zZXRSZW5kZXJlZENvbnRlbnRPZmZzZXQodGhpcy5fcmVuZGVyZWRDb250ZW50T2Zmc2V0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9zY3JvbGxTdHJhdGVneS5vblJlbmRlcmVkT2Zmc2V0Q2hhbmdlZCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2Nyb2xscyB0byB0aGUgZ2l2ZW4gb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2aWV3cG9ydC4gUGxlYXNlIG5vdGUgdGhhdCB0aGlzIGlzIG5vdCBhbHdheXNcbiAgICogdGhlIHNhbWUgYXMgc2V0dGluZyBgc2Nyb2xsVG9wYCBvciBgc2Nyb2xsTGVmdGAuIEluIGEgaG9yaXpvbnRhbCB2aWV3cG9ydCB3aXRoIHJpZ2h0LXRvLWxlZnRcbiAgICogZGlyZWN0aW9uLCB0aGlzIHdvdWxkIGJlIHRoZSBlcXVpdmFsZW50IG9mIHNldHRpbmcgYSBmaWN0aW9uYWwgYHNjcm9sbFJpZ2h0YCBwcm9wZXJ0eS5cbiAgICogQHBhcmFtIG9mZnNldCBUaGUgb2Zmc2V0IHRvIHNjcm9sbCB0by5cbiAgICogQHBhcmFtIGJlaGF2aW9yIFRoZSBTY3JvbGxCZWhhdmlvciB0byB1c2Ugd2hlbiBzY3JvbGxpbmcuIERlZmF1bHQgaXMgYmVoYXZpb3IgaXMgYGF1dG9gLlxuICAgKi9cbiAgc2Nyb2xsVG9PZmZzZXQob2Zmc2V0OiBudW1iZXIsIGJlaGF2aW9yOiBTY3JvbGxCZWhhdmlvciA9ICdhdXRvJykge1xuICAgIGNvbnN0IG9wdGlvbnM6IEV4dGVuZGVkU2Nyb2xsVG9PcHRpb25zID0ge2JlaGF2aW9yfTtcbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICBvcHRpb25zLnN0YXJ0ID0gb2Zmc2V0O1xuICAgIH0gZWxzZSB7XG4gICAgICBvcHRpb25zLnRvcCA9IG9mZnNldDtcbiAgICB9XG4gICAgdGhpcy5zY3JvbGxUbyhvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTY3JvbGxzIHRvIHRoZSBvZmZzZXQgZm9yIHRoZSBnaXZlbiBpbmRleC5cbiAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byBzY3JvbGwgdG8uXG4gICAqIEBwYXJhbSBiZWhhdmlvciBUaGUgU2Nyb2xsQmVoYXZpb3IgdG8gdXNlIHdoZW4gc2Nyb2xsaW5nLiBEZWZhdWx0IGlzIGJlaGF2aW9yIGlzIGBhdXRvYC5cbiAgICovXG4gIHNjcm9sbFRvSW5kZXgoaW5kZXg6IG51bWJlciwgIGJlaGF2aW9yOiBTY3JvbGxCZWhhdmlvciA9ICdhdXRvJykge1xuICAgIHRoaXMuX3Njcm9sbFN0cmF0ZWd5LnNjcm9sbFRvSW5kZXgoaW5kZXgsIGJlaGF2aW9yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBjdXJyZW50IHNjcm9sbCBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZpZXdwb3J0IChpbiBwaXhlbHMpLlxuICAgKiBAcGFyYW0gZnJvbSBUaGUgZWRnZSB0byBtZWFzdXJlIHRoZSBvZmZzZXQgZnJvbS4gRGVmYXVsdHMgdG8gJ3RvcCcgaW4gdmVydGljYWwgbW9kZSBhbmQgJ3N0YXJ0J1xuICAgKiAgICAgaW4gaG9yaXpvbnRhbCBtb2RlLlxuICAgKi9cbiAgbWVhc3VyZVNjcm9sbE9mZnNldChmcm9tPzogJ3RvcCcgfCAnbGVmdCcgfCAncmlnaHQnIHwgJ2JvdHRvbScgfCAnc3RhcnQnIHwgJ2VuZCcpOiBudW1iZXIge1xuICAgIHJldHVybiBmcm9tID9cbiAgICAgIHN1cGVyLm1lYXN1cmVTY3JvbGxPZmZzZXQoZnJvbSkgOlxuICAgICAgc3VwZXIubWVhc3VyZVNjcm9sbE9mZnNldCh0aGlzLm9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCcgPyAnc3RhcnQnIDogJ3RvcCcpO1xuICB9XG5cbiAgLyoqIE1lYXN1cmUgdGhlIGNvbWJpbmVkIHNpemUgb2YgYWxsIG9mIHRoZSByZW5kZXJlZCBpdGVtcy4gKi9cbiAgbWVhc3VyZVJlbmRlcmVkQ29udGVudFNpemUoKTogbnVtYmVyIHtcbiAgICBjb25zdCBjb250ZW50RWwgPSB0aGlzLl9jb250ZW50V3JhcHBlci5uYXRpdmVFbGVtZW50O1xuICAgIHJldHVybiB0aGlzLm9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCcgPyBjb250ZW50RWwub2Zmc2V0V2lkdGggOiBjb250ZW50RWwub2Zmc2V0SGVpZ2h0O1xuICB9XG5cbiAgLyoqXG4gICAqIE1lYXN1cmUgdGhlIHRvdGFsIGNvbWJpbmVkIHNpemUgb2YgdGhlIGdpdmVuIHJhbmdlLiBUaHJvd3MgaWYgdGhlIHJhbmdlIGluY2x1ZGVzIGl0ZW1zIHRoYXQgYXJlXG4gICAqIG5vdCByZW5kZXJlZC5cbiAgICovXG4gIG1lYXN1cmVSYW5nZVNpemUocmFuZ2U6IExpc3RSYW5nZSk6IG51bWJlciB7XG4gICAgaWYgKCF0aGlzLl9mb3JPZikge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9mb3JPZi5tZWFzdXJlUmFuZ2VTaXplKHJhbmdlLCB0aGlzLm9yaWVudGF0aW9uKTtcbiAgfVxuXG4gIC8qKiBVcGRhdGUgdGhlIHZpZXdwb3J0IGRpbWVuc2lvbnMgYW5kIHJlLXJlbmRlci4gKi9cbiAgY2hlY2tWaWV3cG9ydFNpemUoKSB7XG4gICAgLy8gVE9ETzogQ2xlYW51cCBsYXRlciB3aGVuIGFkZCBsb2dpYyBmb3IgaGFuZGxpbmcgY29udGVudCByZXNpemVcbiAgICB0aGlzLl9tZWFzdXJlVmlld3BvcnRTaXplKCk7XG4gICAgdGhpcy5fc2Nyb2xsU3RyYXRlZ3kub25EYXRhTGVuZ3RoQ2hhbmdlZCgpO1xuICB9XG5cbiAgLyoqIE1lYXN1cmUgdGhlIHZpZXdwb3J0IHNpemUuICovXG4gIHByaXZhdGUgX21lYXN1cmVWaWV3cG9ydFNpemUoKSB7XG4gICAgY29uc3Qgdmlld3BvcnRFbCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICAgIHRoaXMuX3ZpZXdwb3J0U2l6ZSA9IHRoaXMub3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJyA/XG4gICAgICAgIHZpZXdwb3J0RWwuY2xpZW50V2lkdGggOiB2aWV3cG9ydEVsLmNsaWVudEhlaWdodDtcbiAgfVxuXG4gIC8qKiBRdWV1ZSB1cCBjaGFuZ2UgZGV0ZWN0aW9uIHRvIHJ1bi4gKi9cbiAgcHJpdmF0ZSBfbWFya0NoYW5nZURldGVjdGlvbk5lZWRlZChydW5BZnRlcj86IEZ1bmN0aW9uKSB7XG4gICAgaWYgKHJ1bkFmdGVyKSB7XG4gICAgICB0aGlzLl9ydW5BZnRlckNoYW5nZURldGVjdGlvbi5wdXNoKHJ1bkFmdGVyKTtcbiAgICB9XG5cbiAgICAvLyBVc2UgYSBQcm9taXNlIHRvIGJhdGNoIHRvZ2V0aGVyIGNhbGxzIHRvIGBfZG9DaGFuZ2VEZXRlY3Rpb25gLiBUaGlzIHdheSBpZiB3ZSBzZXQgYSBidW5jaCBvZlxuICAgIC8vIHByb3BlcnRpZXMgc2VxdWVudGlhbGx5IHdlIG9ubHkgaGF2ZSB0byBydW4gYF9kb0NoYW5nZURldGVjdGlvbmAgb25jZSBhdCB0aGUgZW5kLlxuICAgIGlmICghdGhpcy5faXNDaGFuZ2VEZXRlY3Rpb25QZW5kaW5nKSB7XG4gICAgICB0aGlzLl9pc0NoYW5nZURldGVjdGlvblBlbmRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuX2RvQ2hhbmdlRGV0ZWN0aW9uKCk7XG4gICAgICB9KSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFJ1biBjaGFuZ2UgZGV0ZWN0aW9uLiAqL1xuICBwcml2YXRlIF9kb0NoYW5nZURldGVjdGlvbigpIHtcbiAgICB0aGlzLl9pc0NoYW5nZURldGVjdGlvblBlbmRpbmcgPSBmYWxzZTtcblxuICAgIC8vIEFwcGx5IHRoZSBjb250ZW50IHRyYW5zZm9ybS4gVGhlIHRyYW5zZm9ybSBjYW4ndCBiZSBzZXQgdmlhIGFuIEFuZ3VsYXIgYmluZGluZyBiZWNhdXNlXG4gICAgLy8gYnlwYXNzU2VjdXJpdHlUcnVzdFN0eWxlIGlzIGJhbm5lZCBpbiBHb29nbGUuIEhvd2V2ZXIgdGhlIHZhbHVlIGlzIHNhZmUsIGl0J3MgY29tcG9zZWQgb2ZcbiAgICAvLyBzdHJpbmcgbGl0ZXJhbHMsIGEgdmFyaWFibGUgdGhhdCBjYW4gb25seSBiZSAnWCcgb3IgJ1knLCBhbmQgdXNlciBpbnB1dCB0aGF0IGlzIHJ1biB0aHJvdWdoXG4gICAgLy8gdGhlIGBOdW1iZXJgIGZ1bmN0aW9uIGZpcnN0IHRvIGNvZXJjZSBpdCB0byBhIG51bWVyaWMgdmFsdWUuXG4gICAgdGhpcy5fY29udGVudFdyYXBwZXIubmF0aXZlRWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSB0aGlzLl9yZW5kZXJlZENvbnRlbnRUcmFuc2Zvcm07XG4gICAgLy8gQXBwbHkgY2hhbmdlcyB0byBBbmd1bGFyIGJpbmRpbmdzLiBOb3RlOiBXZSBtdXN0IGNhbGwgYG1hcmtGb3JDaGVja2AgdG8gcnVuIGNoYW5nZSBkZXRlY3Rpb25cbiAgICAvLyBmcm9tIHRoZSByb290LCBzaW5jZSB0aGUgcmVwZWF0ZWQgaXRlbXMgYXJlIGNvbnRlbnQgcHJvamVjdGVkIGluLiBDYWxsaW5nIGBkZXRlY3RDaGFuZ2VzYFxuICAgIC8vIGluc3RlYWQgZG9lcyBub3QgcHJvcGVybHkgY2hlY2sgdGhlIHByb2plY3RlZCBjb250ZW50LlxuICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKSk7XG5cbiAgICBjb25zdCBydW5BZnRlckNoYW5nZURldGVjdGlvbiA9IHRoaXMuX3J1bkFmdGVyQ2hhbmdlRGV0ZWN0aW9uO1xuICAgIHRoaXMuX3J1bkFmdGVyQ2hhbmdlRGV0ZWN0aW9uID0gW107XG4gICAgZm9yIChjb25zdCBmbiBvZiBydW5BZnRlckNoYW5nZURldGVjdGlvbikge1xuICAgICAgZm4oKTtcbiAgICB9XG4gIH1cblxuICAvKiogQ2FsY3VsYXRlcyB0aGUgYHN0eWxlLndpZHRoYCBhbmQgYHN0eWxlLmhlaWdodGAgZm9yIHRoZSBzcGFjZXIgZWxlbWVudC4gKi9cbiAgcHJpdmF0ZSBfY2FsY3VsYXRlU3BhY2VyU2l6ZSgpIHtcbiAgICB0aGlzLl90b3RhbENvbnRlbnRIZWlnaHQgPVxuICAgICAgICB0aGlzLm9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCcgPyAnJyA6IGAke3RoaXMuX3RvdGFsQ29udGVudFNpemV9cHhgO1xuICAgIHRoaXMuX3RvdGFsQ29udGVudFdpZHRoID1cbiAgICAgICAgdGhpcy5vcmllbnRhdGlvbiA9PT0gJ2hvcml6b250YWwnID8gYCR7dGhpcy5fdG90YWxDb250ZW50U2l6ZX1weGAgOiAnJztcbiAgfVxufVxuIl19
|
|
323
|
+
/** Calculates the `style.width` and `style.height` for the spacer element. */
|
|
324
|
+
_calculateSpacerSize() {
|
|
325
|
+
this._totalContentHeight =
|
|
326
|
+
this.orientation === 'horizontal' ? '' : `${this._totalContentSize}px`;
|
|
327
|
+
this._totalContentWidth =
|
|
328
|
+
this.orientation === 'horizontal' ? `${this._totalContentSize}px` : '';
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
CdkVirtualScrollViewport.decorators = [
|
|
332
|
+
{ type: Component, args: [{
|
|
333
|
+
selector: 'cdk-virtual-scroll-viewport',
|
|
334
|
+
template: "<!--\n Wrap the rendered content in an element that will be used to offset it based on the scroll\n position.\n-->\n<div #contentWrapper class=\"cdk-virtual-scroll-content-wrapper\">\n <ng-content></ng-content>\n</div>\n<!--\n Spacer used to force the scrolling container to the correct size for the *total* number of items\n so that the scrollbar captures the size of the entire data set.\n-->\n<div class=\"cdk-virtual-scroll-spacer\"\n [style.width]=\"_totalContentWidth\" [style.height]=\"_totalContentHeight\"></div>\n",
|
|
335
|
+
host: {
|
|
336
|
+
'class': 'cdk-virtual-scroll-viewport',
|
|
337
|
+
'[class.cdk-virtual-scroll-orientation-horizontal]': 'orientation === "horizontal"',
|
|
338
|
+
'[class.cdk-virtual-scroll-orientation-vertical]': 'orientation !== "horizontal"',
|
|
339
|
+
},
|
|
340
|
+
encapsulation: ViewEncapsulation.None,
|
|
341
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
342
|
+
providers: [{
|
|
343
|
+
provide: CdkScrollable,
|
|
344
|
+
useExisting: CdkVirtualScrollViewport,
|
|
345
|
+
}],
|
|
346
|
+
styles: ["cdk-virtual-scroll-viewport{display:block;position:relative;overflow:auto;contain:strict;transform:translateZ(0);will-change:scroll-position;-webkit-overflow-scrolling:touch}.cdk-virtual-scroll-content-wrapper{position:absolute;top:0;left:0;contain:content}[dir=rtl] .cdk-virtual-scroll-content-wrapper{right:0;left:auto}.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper{min-height:100%}.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>dl:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>ol:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>table:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>ul:not([cdkVirtualFor]){padding-left:0;padding-right:0;margin-left:0;margin-right:0;border-left-width:0;border-right-width:0;outline:none}.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{min-width:100%}.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>dl:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>ol:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>table:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>ul:not([cdkVirtualFor]){padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;border-top-width:0;border-bottom-width:0;outline:none}.cdk-virtual-scroll-spacer{position:absolute;top:0;left:0;height:1px;width:1px;transform-origin:0 0}[dir=rtl] .cdk-virtual-scroll-spacer{right:0;left:auto;transform-origin:100% 0}\n"]
|
|
347
|
+
},] }
|
|
348
|
+
];
|
|
349
|
+
CdkVirtualScrollViewport.ctorParameters = () => [
|
|
350
|
+
{ type: ElementRef },
|
|
351
|
+
{ type: ChangeDetectorRef },
|
|
352
|
+
{ type: NgZone },
|
|
353
|
+
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [VIRTUAL_SCROLL_STRATEGY,] }] },
|
|
354
|
+
{ type: Directionality, decorators: [{ type: Optional }] },
|
|
355
|
+
{ type: ScrollDispatcher },
|
|
356
|
+
{ type: ViewportRuler, decorators: [{ type: Optional }] }
|
|
357
|
+
];
|
|
358
|
+
CdkVirtualScrollViewport.propDecorators = {
|
|
359
|
+
orientation: [{ type: Input }],
|
|
360
|
+
scrolledIndexChange: [{ type: Output }],
|
|
361
|
+
_contentWrapper: [{ type: ViewChild, args: ['contentWrapper', { static: true },] }]
|
|
362
|
+
};
|
|
363
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlydHVhbC1zY3JvbGwtdmlld3BvcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvY2RrL3Njcm9sbGluZy92aXJ0dWFsLXNjcm9sbC12aWV3cG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFFakQsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFHTixRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFDVCxpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixhQUFhLEVBQ2IsVUFBVSxFQUNWLE9BQU8sRUFFUCxZQUFZLEdBQ2IsTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQUMsYUFBYSxFQUEwQixNQUFNLGNBQWMsQ0FBQztBQUNwRSxPQUFPLEVBQUMsdUJBQXVCLEVBQXdCLE1BQU0sMkJBQTJCLENBQUM7QUFDekYsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBRy9DLDRDQUE0QztBQUM1QyxTQUFTLFdBQVcsQ0FBQyxFQUFhLEVBQUUsRUFBYTtJQUMvQyxPQUFPLEVBQUUsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUM7QUFDbEQsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLGdCQUFnQixHQUNsQixPQUFPLHFCQUFxQixLQUFLLFdB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NENBNElPLFFBQVEsWUFBSSxNQUFNLFNBQUMsdUJBQXVCO1lBckpqRCxjQUFjLHVCQXVKUCxRQUFRO1lBN0hmLGdCQUFnQjtZQUdoQixhQUFhLHVCQWdJTixRQUFROzs7MEJBdEZwQixLQUFLO2tDQWlCTCxNQUFNOzhCQU1OLFNBQVMsU0FBQyxnQkFBZ0IsRUFBRSxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtEaXJlY3Rpb25hbGl0eX0gZnJvbSAnQGFuZ3VsYXIvY2RrL2JpZGknO1xuaW1wb3J0IHtMaXN0UmFuZ2V9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBhbmltYXRpb25GcmFtZVNjaGVkdWxlcixcbiAgYXNhcFNjaGVkdWxlcixcbiAgT2JzZXJ2YWJsZSxcbiAgU3ViamVjdCxcbiAgT2JzZXJ2ZXIsXG4gIFN1YnNjcmlwdGlvbixcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge2F1ZGl0VGltZSwgc3RhcnRXaXRoLCB0YWtlVW50aWx9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7U2Nyb2xsRGlzcGF0Y2hlcn0gZnJvbSAnLi9zY3JvbGwtZGlzcGF0Y2hlcic7XG5pbXBvcnQge0Nka1Njcm9sbGFibGUsIEV4dGVuZGVkU2Nyb2xsVG9PcHRpb25zfSBmcm9tICcuL3Njcm9sbGFibGUnO1xuaW1wb3J0IHtWSVJUVUFMX1NDUk9MTF9TVFJBVEVHWSwgVmlydHVhbFNjcm9sbFN0cmF0ZWd5fSBmcm9tICcuL3ZpcnR1YWwtc2Nyb2xsLXN0cmF0ZWd5JztcbmltcG9ydCB7Vmlld3BvcnRSdWxlcn0gZnJvbSAnLi92aWV3cG9ydC1ydWxlcic7XG5pbXBvcnQge0Nka1ZpcnR1YWxTY3JvbGxSZXBlYXRlcn0gZnJvbSAnLi92aXJ0dWFsLXNjcm9sbC1yZXBlYXRlcic7XG5cbi8qKiBDaGVja3MgaWYgdGhlIGdpdmVuIHJhbmdlcyBhcmUgZXF1YWwuICovXG5mdW5jdGlvbiByYW5nZXNFcXVhbChyMTogTGlzdFJhbmdlLCByMjogTGlzdFJhbmdlKTogYm9vbGVhbiB7XG4gIHJldHVybiByMS5zdGFydCA9PSByMi5zdGFydCAmJiByMS5lbmQgPT0gcjIuZW5kO1xufVxuXG4vKipcbiAqIFNjaGVkdWxlciB0byBiZSB1c2VkIGZvciBzY3JvbGwgZXZlbnRzLiBOZWVkcyB0byBmYWxsIGJhY2sgdG9cbiAqIHNvbWV0aGluZyB0aGF0IGRvZXNuJ3QgcmVseSBvbiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgb24gZW52aXJvbm1lbnRzXG4gKiB0aGF0IGRvbid0IHN1cHBvcnQgaXQgKGUuZy4gc2VydmVyLXNpZGUgcmVuZGVyaW5nKS5cbiAqL1xuY29uc3QgU0NST0xMX1NDSEVEVUxFUiA9XG4gICAgdHlwZW9mIHJlcXVlc3RBbmltYXRpb25GcmFtZSAhPT0gJ3VuZGVmaW5lZCcgPyBhbmltYXRpb25GcmFtZVNjaGVkdWxlciA6IGFzYXBTY2hlZHVsZXI7XG5cblxuLyoqIEEgdmlld3BvcnQgdGhhdCB2aXJ0dWFsaXplcyBpdHMgc2Nyb2xsaW5nIHdpdGggdGhlIGhlbHAgb2YgYENka1ZpcnR1YWxGb3JPZmAuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjZGstdmlydHVhbC1zY3JvbGwtdmlld3BvcnQnLFxuICB0ZW1wbGF0ZVVybDogJ3ZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsndmlydHVhbC1zY3JvbGwtdmlld3BvcnQuY3NzJ10sXG4gIGhvc3Q6IHtcbiAgICAnY2xhc3MnOiAnY2RrLXZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0JyxcbiAgICAnW2NsYXNzLmNkay12aXJ0dWFsLXNjcm9sbC1vcmllbnRhdGlvbi1ob3Jpem9udGFsXSc6ICdvcmllbnRhdGlvbiA9PT0gXCJob3Jpem9udGFsXCInLFxuICAgICdbY2xhc3MuY2RrLXZpcnR1YWwtc2Nyb2xsLW9yaWVudGF0aW9uLXZlcnRpY2FsXSc6ICdvcmllbnRhdGlvbiAhPT0gXCJob3Jpem9udGFsXCInLFxuICB9LFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgcHJvdmlkZXJzOiBbe1xuICAgIHByb3ZpZGU6IENka1Njcm9sbGFibGUsXG4gICAgdXNlRXhpc3Rpbmc6IENka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydCxcbiAgfV1cbn0pXG5leHBvcnQgY2xhc3MgQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0IGV4dGVuZHMgQ2RrU2Nyb2xsYWJsZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgLyoqIEVtaXRzIHdoZW4gdGhlIHZpZXdwb3J0IGlzIGRldGFjaGVkIGZyb20gYSBDZGtWaXJ0dWFsRm9yT2YuICovXG4gIHByaXZhdGUgX2RldGFjaGVkU3ViamVjdCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLyoqIEVtaXRzIHdoZW4gdGhlIHJlbmRlcmVkIHJhbmdlIGNoYW5nZXMuICovXG4gIHByaXZhdGUgX3JlbmRlcmVkUmFuZ2VTdWJqZWN0ID0gbmV3IFN1YmplY3Q8TGlzdFJhbmdlPigpO1xuXG4gIC8qKiBUaGUgZGlyZWN0aW9uIHRoZSB2aWV3cG9ydCBzY3JvbGxzLiAqL1xuICBASW5wdXQoKVxuICBnZXQgb3JpZW50YXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uO1xuICB9XG4gIHNldCBvcmllbnRhdGlvbihvcmllbnRhdGlvbjogJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJykge1xuICAgIGlmICh0aGlzLl9vcmllbnRhdGlvbiAhPT0gb3JpZW50YXRpb24pIHtcbiAgICAgIHRoaXMuX29yaWVudGF0aW9uID0gb3JpZW50YXRpb247XG4gICAgICB0aGlzLl9jYWxjdWxhdGVTcGFjZXJTaXplKCk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgX29yaWVudGF0aW9uOiAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnID0gJ3ZlcnRpY2FsJztcblxuICAvLyBOb3RlOiB3ZSBkb24ndCB1c2UgdGhlIHR5cGljYWwgRXZlbnRFbWl0dGVyIGhlcmUgYmVjYXVzZSB3ZSBuZWVkIHRvIHN1YnNjcmliZSB0byB0aGUgc2Nyb2xsXG4gIC8vIHN0cmF0ZWd5IGxhemlseSAoaS5lLiBvbmx5IGlmIHRoZSB1c2VyIGlzIGFjdHVhbGx5IGxpc3RlbmluZyB0byB0aGUgZXZlbnRzKS4gV2UgZG8gdGhpcyBiZWNhdXNlXG4gIC8vIGRlcGVuZGluZyBvbiBob3cgdGhlIHN0cmF0ZWd5IGNhbGN1bGF0ZXMgdGhlIHNjcm9sbGVkIGluZGV4LCBpdCBtYXkgY29tZSBhdCBhIGNvc3QgdG9cbiAgLy8gcGVyZm9ybWFuY2UuXG4gIC8qKiBFbWl0cyB3aGVuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgZWxlbWVudCB2aXNpYmxlIGluIHRoZSB2aWV3cG9ydCBjaGFuZ2VzLiAqL1xuICBAT3V0cHV0KCkgc2Nyb2xsZWRJbmRleENoYW5nZTogT2JzZXJ2YWJsZTxudW1iZXI+ID1cbiAgICAgIG5ldyBPYnNlcnZhYmxlKChvYnNlcnZlcjogT2JzZXJ2ZXI8bnVtYmVyPikgPT5cbiAgICAgICAgdGhpcy5fc2Nyb2xsU3RyYXRlZ3kuc2Nyb2xsZWRJbmRleENoYW5nZS5zdWJzY3JpYmUoaW5kZXggPT5cbiAgICAgICAgICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4gdGhpcy5uZ1pvbmUucnVuKCgpID0+IG9ic2VydmVyLm5leHQoaW5kZXgpKSkpKTtcblxuICAvKiogVGhlIGVsZW1lbnQgdGhhdCB3cmFwcyB0aGUgcmVuZGVyZWQgY29udGVudC4gKi9cbiAgQFZpZXdDaGlsZCgnY29udGVudFdyYXBwZXInLCB7c3RhdGljOiB0cnVlfSkgX2NvbnRlbnRXcmFwcGVyOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcblxuICAvKiogQSBzdHJlYW0gdGhhdCBlbWl0cyB3aGVuZXZlciB0aGUgcmVuZGVyZWQgcmFuZ2UgY2hhbmdlcy4gKi9cbiAgcmVuZGVyZWRSYW5nZVN0cmVhbTogT2JzZXJ2YWJsZTxMaXN0UmFuZ2U+ID0gdGhpcy5fcmVuZGVyZWRSYW5nZVN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgLyoqXG4gICAqIFRoZSB0b3RhbCBzaXplIG9mIGFsbCBjb250ZW50IChpbiBwaXhlbHMpLCBpbmNsdWRpbmcgY29udGVudCB0aGF0IGlzIG5vdCBjdXJyZW50bHkgcmVuZGVyZWQuXG4gICAqL1xuICBwcml2YXRlIF90b3RhbENvbnRlbnRTaXplID0gMDtcblxuICAvKiogQSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBgc3R5bGUud2lkdGhgIHByb3BlcnR5IHZhbHVlIHRvIGJlIHVzZWQgZm9yIHRoZSBzcGFjZXIgZWxlbWVudC4gKi9cbiAgX3RvdGFsQ29udGVudFdpZHRoID0gJyc7XG5cbiAgLyoqIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgYHN0eWxlLmhlaWdodGAgcHJvcGVydHkgdmFsdWUgdG8gYmUgdXNlZCBmb3IgdGhlIHNwYWNlciBlbGVtZW50LiAqL1xuICBfdG90YWxDb250ZW50SGVpZ2h0ID0gJyc7XG5cbiAgLyoqXG4gICAqIFRoZSBDU1MgdHJhbnNmb3JtIGFwcGxpZWQgdG8gdGhlIHJlbmRlcmVkIHN1YnNldCBvZiBpdGVtcyBzbyB0aGF0IHRoZXkgYXBwZWFyIHdpdGhpbiB0aGUgYm91bmRzXG4gICAqIG9mIHRoZSB2aXNpYmxlIHZpZXdwb3J0LlxuICAgKi9cbiAgcHJpdmF0ZSBfcmVuZGVyZWRDb250ZW50VHJhbnNmb3JtOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSBjdXJyZW50bHkgcmVuZGVyZWQgcmFuZ2Ugb2YgaW5kaWNlcy4gKi9cbiAgcHJpdmF0ZSBfcmVuZGVyZWRSYW5nZTogTGlzdFJhbmdlID0ge3N0YXJ0OiAwLCBlbmQ6IDB9O1xuXG4gIC8qKiBUaGUgbGVuZ3RoIG9mIHRoZSBkYXRhIGJvdW5kIHRvIHRoaXMgdmlld3BvcnQgKGluIG51bWJlciBvZiBpdGVtcykuICovXG4gIHByaXZhdGUgX2RhdGFMZW5ndGggPSAwO1xuXG4gIC8qKiBUaGUgc2l6ZSBvZiB0aGUgdmlld3BvcnQgKGluIHBpeGVscykuICovXG4gIHByaXZhdGUgX3ZpZXdwb3J0U2l6ZSA9IDA7XG5cbiAgLyoqIHRoZSBjdXJyZW50bHkgYXR0YWNoZWQgQ2RrVmlydHVhbFNjcm9sbFJlcGVhdGVyLiAqL1xuICBwcml2YXRlIF9mb3JPZjogQ2RrVmlydHVhbFNjcm9sbFJlcGVhdGVyPGFueT4gfCBudWxsO1xuXG4gIC8qKiBUaGUgbGFzdCByZW5kZXJlZCBjb250ZW50IG9mZnNldCB0aGF0IHdhcyBzZXQuICovXG4gIHByaXZhdGUgX3JlbmRlcmVkQ29udGVudE9mZnNldCA9IDA7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGxhc3QgcmVuZGVyZWQgY29udGVudCBvZmZzZXQgd2FzIHRvIHRoZSBlbmQgb2YgdGhlIGNvbnRlbnQgKGFuZCB0aGVyZWZvcmUgbmVlZHMgdG9cbiAgICogYmUgcmV3cml0dGVuIGFzIGFuIG9mZnNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGNvbnRlbnQpLlxuICAgKi9cbiAgcHJpdmF0ZSBfcmVuZGVyZWRDb250ZW50T2Zmc2V0TmVlZHNSZXdyaXRlID0gZmFsc2U7XG5cbiAgLyoqIFdoZXRoZXIgdGhlcmUgaXMgYSBwZW5kaW5nIGNoYW5nZSBkZXRlY3Rpb24gY3ljbGUuICovXG4gIHByaXZhdGUgX2lzQ2hhbmdlRGV0ZWN0aW9uUGVuZGluZyA9IGZhbHNlO1xuXG4gIC8qKiBBIGxpc3Qgb2YgZnVuY3Rpb25zIHRvIHJ1biBhZnRlciB0aGUgbmV4dCBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlLiAqL1xuICBwcml2YXRlIF9ydW5BZnRlckNoYW5nZURldGVjdGlvbjogRnVuY3Rpb25bXSA9IFtdO1xuXG4gIC8qKiBTdWJzY3JpcHRpb24gdG8gY2hhbmdlcyBpbiB0aGUgdmlld3BvcnQgc2l6ZS4gKi9cbiAgcHJpdmF0ZSBfdmlld3BvcnRDaGFuZ2VzID0gU3Vic2NyaXB0aW9uLkVNUFRZO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBlbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICAgICAgICAgICBuZ1pvbmU6IE5nWm9uZSxcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChWSVJUVUFMX1NDUk9MTF9TVFJBVEVHWSlcbiAgICAgICAgICAgICAgICAgIHByaXZhdGUgX3Njcm9sbFN0cmF0ZWd5OiBWaXJ0dWFsU2Nyb2xsU3RyYXRlZ3ksXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIGRpcjogRGlyZWN0aW9uYWxpdHksXG4gICAgICAgICAgICAgIHNjcm9sbERpc3BhdGNoZXI6IFNjcm9sbERpc3BhdGNoZXIsXG4gICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgKiBAZGVwcmVjYXRlZCBgdmlld3BvcnRSdWxlcmAgcGFyYW1ldGVyIHRvIGJlY29tZSByZXF1aXJlZC5cbiAgICAgICAgICAgICAgICogQGJyZWFraW5nLWNoYW5nZSAxMS4wLjBcbiAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIHZpZXdwb3J0UnVsZXI/OiBWaWV3cG9ydFJ1bGVyKSB7XG4gICAgc3VwZXIoZWxlbWVudFJlZiwgc2Nyb2xsRGlzcGF0Y2hlciwgbmdab25lLCBkaXIpO1xuXG4gICAgaWYgKCFfc2Nyb2xsU3RyYXRlZ3kpIHtcbiAgICAgIHRocm93IEVycm9yKCdFcnJvcjogY2RrLXZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0IHJlcXVpcmVzIHRoZSBcIml0ZW1TaXplXCIgcHJvcGVydHkgdG8gYmUgc2V0LicpO1xuICAgIH1cblxuICAgIC8vIEBicmVha2luZy1jaGFuZ2UgMTEuMC4wIFJlbW92ZSBudWxsIGNoZWNrIGZvciBgdmlld3BvcnRSdWxlcmAuXG4gICAgaWYgKHZpZXdwb3J0UnVsZXIpIHtcbiAgICAgIHRoaXMuX3ZpZXdwb3J0Q2hhbmdlcyA9IHZpZXdwb3J0UnVsZXIuY2hhbmdlKCkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5jaGVja1ZpZXdwb3J0U2l6ZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgc3VwZXIubmdPbkluaXQoKTtcblxuICAgIC8vIEl0J3Mgc3RpbGwgdG9vIGVhcmx5IHRvIG1lYXN1cmUgdGhlIHZpZXdwb3J0IGF0IHRoaXMgcG9pbnQuIERlZmVycmluZyB3aXRoIGEgcHJvbWlzZSBhbGxvd3NcbiAgICAvLyB0aGUgVmlld3BvcnQgdG8gYmUgcmVuZGVyZWQgd2l0aCB0aGUgY29ycmVjdCBzaXplIGJlZm9yZSB3ZSBtZWFzdXJlLiBXZSBydW4gdGhpcyBvdXRzaWRlIHRoZVxuICAgIC8vIHpvbmUgdG8gYXZvaWQgY2F1c2luZyBtb3JlIGNoYW5nZSBkZXRlY3Rpb24gY3ljbGVzLiBXZSBoYW5kbGUgdGhlIGNoYW5nZSBkZXRlY3Rpb24gbG9vcFxuICAgIC8vIG91cnNlbHZlcyBpbnN0ZWFkLlxuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5fbWVhc3VyZVZpZXdwb3J0U2l6ZSgpO1xuICAgICAgdGhpcy5fc2Nyb2xsU3RyYXRlZ3kuYXR0YWNoKHRoaXMpO1xuXG4gICAgICB0aGlzLmVsZW1lbnRTY3JvbGxlZCgpXG4gICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgIC8vIFN0YXJ0IG9mZiB3aXRoIGEgZmFrZSBzY3JvbGwgZXZlbnQgc28gd2UgcHJvcGVybHkgZGV0ZWN0IG91ciBpbml0aWFsIHBvc2l0aW9uLlxuICAgICAgICAgICAgICBzdGFydFdpdGgobnVsbCEpLFxuICAgICAgICAgICAgICAvLyBDb2xsZWN0IG11bHRpcGxlIGV2ZW50cyBpbnRvIG9uZSB1bnRpbCB0aGUgbmV4dCBhbmltYXRpb24gZnJhbWUuIFRoaXMgd2F5IGlmXG4gICAgICAgICAgICAgIC8vIHRoZXJlIGFyZSBtdWx0aXBsZSBzY3JvbGwgZXZlbnRzIGluIHRoZSBzYW1lIGZyYW1lIHdlIG9ubHkgbmVlZCB0byByZWNoZWNrXG4gICAgICAgICAgICAgIC8vIG91ciBsYXlvdXQgb25jZS5cbiAgICAgICAgICAgICAgYXVkaXRUaW1lKDAsIFNDUk9MTF9TQ0hFRFVMRVIpKVxuICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fc2Nyb2xsU3RyYXRlZ3kub25Db250ZW50U2Nyb2xsZWQoKSk7XG5cbiAgICAgIHRoaXMuX21hcmtDaGFuZ2VEZXRlY3Rpb25OZWVkZWQoKTtcbiAgICB9KSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmRldGFjaCgpO1xuICAgIHRoaXMuX3Njcm9sbFN0cmF0ZWd5LmRldGFjaCgpO1xuXG4gICAgLy8gQ29tcGxldGUgYWxsIHN1YmplY3RzXG4gICAgdGhpcy5fcmVuZGVyZWRSYW5nZVN1YmplY3QuY29tcGxldGUoKTtcbiAgICB0aGlzLl9kZXRhY2hlZFN1YmplY3QuY29tcGxldGUoKTtcbiAgICB0aGlzLl92aWV3cG9ydENoYW5nZXMudW5zdWJzY3JpYmUoKTtcblxuICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XG4gIH1cblxuICAvKiogQXR0YWNoZXMgYSBgQ2RrVmlydHVhbFNjcm9sbFJlcGVhdGVyYCB0byB0aGlzIHZpZXdwb3J0LiAqL1xuICBhdHRhY2goZm9yT2Y6IENka1ZpcnR1YWxTY3JvbGxSZXBlYXRlcjxhbnk+KSB7XG4gICAgaWYgKHRoaXMuX2Zvck9mKSB7XG4gICAgICB0aHJvdyBFcnJvcignQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0IGlzIGFscmVhZHkgYXR0YWNoZWQuJyk7XG4gICAgfVxuXG4gICAgLy8gU3Vic2NyaWJlIHRvIHRoZSBkYXRhIHN0cmVhbSBvZiB0aGUgQ2RrVmlydHVhbEZvck9mIHRvIGtlZXAgdHJhY2sgb2Ygd2hlbiB0aGUgZGF0YSBsZW5ndGhcbiAgICAvLyBjaGFuZ2VzLiBSdW4gb3V0c2lkZSB0aGUgem9uZSB0byBhdm9pZCB0cmlnZ2VyaW5nIGNoYW5nZSBkZXRlY3Rpb24sIHNpbmNlIHdlJ3JlIG1hbmFnaW5nIHRoZVxuICAgIC8vIGNoYW5nZSBkZXRlY3Rpb24gbG9vcCBvdXJzZWx2ZXMuXG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgdGhpcy5fZm9yT2YgPSBmb3JPZjtcbiAgICAgIHRoaXMuX2Zvck9mLmRhdGFTdHJlYW0ucGlwZSh0YWtlVW50aWwodGhpcy5fZGV0YWNoZWRTdWJqZWN0KSkuc3Vic2NyaWJlKGRhdGEgPT4ge1xuICAgICAgICBjb25zdCBuZXdMZW5ndGggPSBkYXRhLmxlbmd0aDtcbiAgICAgICAgaWYgKG5ld0xlbmd0aCAhPT0gdGhpcy5fZGF0YUxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuX2RhdGFMZW5ndGggPSBuZXdMZW5ndGg7XG4gICAgICAgICAgdGhpcy5fc2Nyb2xsU3RyYXRlZ3kub25EYXRhTGVuZ3RoQ2hhbmdlZCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2RvQ2hhbmdlRGV0ZWN0aW9uKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBEZXRhY2hlcyB0aGUgY3VycmVudCBgQ2RrVmlydHVhbEZvck9mYC4gKi9cbiAgZGV0YWNoKCkge1xuICAgIHRoaXMuX2Zvck9mID0gbnVsbDtcbiAgICB0aGlzLl9kZXRhY2hlZFN1YmplY3QubmV4dCgpO1xuICB9XG5cbiAgLyoqIEdldHMgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YSBib3VuZCB0byB0aGlzIHZpZXdwb3J0IChpbiBudW1iZXIgb2YgaXRlbXMpLiAqL1xuICBnZXREYXRhTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX2RhdGFMZW5ndGg7XG4gIH1cblxuICAvKiogR2V0cyB0aGUgc2l6ZSBvZiB0aGUgdmlld3BvcnQgKGluIHBpeGVscykuICovXG4gIGdldFZpZXdwb3J0U2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl92aWV3cG9ydFNpemU7XG4gIH1cblxuICAvLyBUT0RPKG1tYWxlcmJhKTogVGhpcyBpcyB0ZWNobmljYWxseSBvdXQgb2Ygc3luYyB3aXRoIHdoYXQncyByZWFsbHkgcmVuZGVyZWQgdW50aWwgYSByZW5kZXJcbiAgLy8gY3ljbGUgaGFwcGVucy4gSSdtIGJlaW5nIGNhcmVmdWwgdG8gb25seSBjYWxsIGl0IGFmdGVyIHRoZSByZW5kZXIgY3ljbGUgaXMgY29tcGxldGUgYW5kIGJlZm9yZVxuICAvLyBzZXR0aW5nIGl0IHRvIHNvbWV0aGluZyBlbHNlLCBidXQgaXRzIGVycm9yIHByb25lIGFuZCBzaG91bGQgcHJvYmFibHkgYmUgc3BsaXQgaW50b1xuICAvLyBgcGVuZGluZ1JhbmdlYCBhbmQgYHJlbmRlcmVkUmFuZ2VgLCB0aGUgbGF0dGVyIHJlZmxlY3Rpbmcgd2hhdHMgYWN0dWFsbHkgaW4gdGhlIERPTS5cblxuICAvKiogR2V0IHRoZSBjdXJyZW50IHJlbmRlcmVkIHJhbmdlIG9mIGl0ZW1zLiAqL1xuICBnZXRSZW5kZXJlZFJhbmdlKCk6IExpc3RSYW5nZSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlbmRlcmVkUmFuZ2U7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgdG90YWwgc2l6ZSBvZiBhbGwgY29udGVudCAoaW4gcGl4ZWxzKSwgaW5jbHVkaW5nIGNvbnRlbnQgdGhhdCBpcyBub3QgY3VycmVudGx5XG4gICAqIHJlbmRlcmVkLlxuICAgKi9cbiAgc2V0VG90YWxDb250ZW50U2l6ZShzaXplOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5fdG90YWxDb250ZW50U2l6ZSAhPT0gc2l6ZSkge1xuICAgICAgdGhpcy5fdG90YWxDb250ZW50U2l6ZSA9IHNpemU7XG4gICAgICB0aGlzLl9jYWxjdWxhdGVTcGFjZXJTaXplKCk7XG4gICAgICB0aGlzLl9tYXJrQ2hhbmdlRGV0ZWN0aW9uTmVlZGVkKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFNldHMgdGhlIGN1cnJlbnRseSByZW5kZXJlZCByYW5nZSBvZiBpbmRpY2VzLiAqL1xuICBzZXRSZW5kZXJlZFJhbmdlKHJhbmdlOiBMaXN0UmFuZ2UpIHtcbiAgICBpZiAoIXJhbmdlc0VxdWFsKHRoaXMuX3JlbmRlcmVkUmFuZ2UsIHJhbmdlKSkge1xuICAgICAgdGhpcy5fcmVuZGVyZWRSYW5nZVN1YmplY3QubmV4dCh0aGlzLl9yZW5kZXJlZFJhbmdlID0gcmFuZ2UpO1xuICAgICAgdGhpcy5fbWFya0NoYW5nZURldGVjdGlvbk5lZWRlZCgoKSA9PiB0aGlzLl9zY3JvbGxTdHJhdGVneS5vbkNvbnRlbnRSZW5kZXJlZCgpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB2aWV3cG9ydCB0byB0aGUgc3RhcnQgb2YgdGhlIHJlbmRlcmVkIGRhdGEgKGluIHBpeGVscykuXG4gICAqL1xuICBnZXRPZmZzZXRUb1JlbmRlcmVkQ29udGVudFN0YXJ0KCk6IG51bWJlciB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9yZW5kZXJlZENvbnRlbnRPZmZzZXROZWVkc1Jld3JpdGUgPyBudWxsIDogdGhpcy5fcmVuZGVyZWRDb250ZW50T2Zmc2V0O1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmlld3BvcnQgdG8gZWl0aGVyIHRoZSBzdGFydCBvciBlbmQgb2YgdGhlIHJlbmRlcmVkIGRhdGFcbiAgICogKGluIHBpeGVscykuXG4gICAqL1xuICBzZXRSZW5kZXJlZENvbnRlbnRPZmZzZXQob2Zmc2V0OiBudW1iZXIsIHRvOiAndG8tc3RhcnQnIHwgJ3RvLWVuZCcgPSAndG8tc3RhcnQnKSB7XG4gICAgLy8gRm9yIGEgaG9yaXpvbnRhbCB2aWV3cG9ydCBpbiBhIHJpZ2h0LXRvLWxlZnQgbGFuZ3VhZ2Ugd2UgbmVlZCB0byB0cmFuc2xhdGUgYWxvbmcgdGhlIHgtYXhpc1xuICAgIC8vIGluIHRoZSBuZWdhdGl2ZSBkaXJlY3Rpb24uXG4gICAgY29uc3QgaXNSdGwgPSB0aGlzLmRpciAmJiB0aGlzLmRpci52YWx1ZSA9PSAncnRsJztcbiAgICBjb25zdCBpc0hvcml6b250YWwgPSB0aGlzLm9yaWVudGF0aW9uID09ICdob3Jpem9udGFsJztcbiAgICBjb25zdCBheGlzID0gaXNIb3Jpem9udGFsID8gJ1gnIDogJ1knO1xuICAgIGNvbnN0IGF4aXNEaXJlY3Rpb24gPSBpc0hvcml6b250YWwgJiYgaXNSdGwgPyAtMSA6IDE7XG4gICAgbGV0IHRyYW5zZm9ybSA9IGB0cmFuc2xhdGUke2F4aXN9KCR7TnVtYmVyKGF4aXNEaXJlY3Rpb24gKiBvZmZzZXQpfXB4KWA7XG4gICAgdGhpcy5fcmVuZGVyZWRDb250ZW50T2Zmc2V0ID0gb2Zmc2V0O1xuICAgIGlmICh0byA9PT0gJ3RvLWVuZCcpIHtcbiAgICAgIHRyYW5zZm9ybSArPSBgIHRyYW5zbGF0ZSR7YXhpc30oLTEwMCUpYDtcbiAgICAgIC8vIFRoZSB2aWV3cG9ydCBzaG91bGQgcmV3cml0ZSB0aGlzIGFzIGEgYHRvLXN0YXJ0YCBvZmZzZXQgb24gdGhlIG5leHQgcmVuZGVyIGN5Y2xlLiBPdGhlcndpc2VcbiAgICAgIC8vIGVsZW1lbnRzIHdpbGwgYXBwZWFyIHRvIGV4cGFuZCBpbiB0aGUgd3JvbmcgZGlyZWN0aW9uIChlLmcuIGBtYXQtZXhwYW5zaW9uLXBhbmVsYCB3b3VsZFxuICAgICAgLy8gZXhwYW5kIHVwd2FyZCkuXG4gICAgICB0aGlzLl9yZW5kZXJlZENvbnRlbnRPZmZzZXROZWVkc1Jld3JpdGUgPSB0cnVlO1xuICAgIH1cbiAgICBpZiAodGhpcy5fcmVuZGVyZWRDb250ZW50VHJhbnNmb3JtICE9IHRyYW5zZm9ybSkge1xuICAgICAgLy8gV2Uga25vdyB0aGlzIHZhbHVlIGlzIHNhZmUgYmVjYXVzZSB3ZSBwYXJzZSBgb2Zmc2V0YCB3aXRoIGBOdW1iZXIoKWAgYmVmb3JlIHBhc3NpbmcgaXRcbiAgICAgIC8vIGludG8gdGhlIHN0cmluZy5cbiAgICAgIHRoaXMuX3JlbmRlcmVkQ29udGVudFRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICAgIHRoaXMuX21hcmtDaGFuZ2VEZXRlY3Rpb25OZWVkZWQoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5fcmVuZGVyZWRDb250ZW50T2Zmc2V0TmVlZHNSZXdyaXRlKSB7XG4gICAgICAgICAgdGhpcy5fcmVuZGVyZWRDb250ZW50T2Zmc2V0IC09IHRoaXMubWVhc3VyZVJlbmRlcmVkQ29udGVudFNpemUoKTtcbiAgICAgICAgICB0aGlzLl9yZW5kZXJlZENvbnRlbnRPZmZzZXROZWVkc1Jld3JpdGUgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnNldFJlbmRlcmVkQ29udGVudE9mZnNldCh0aGlzLl9yZW5kZXJlZENvbnRlbnRPZmZzZXQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuX3Njcm9sbFN0cmF0ZWd5Lm9uUmVuZGVyZWRPZmZzZXRDaGFuZ2VkKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTY3JvbGxzIHRvIHRoZSBnaXZlbiBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHZpZXdwb3J0LiBQbGVhc2Ugbm90ZSB0aGF0IHRoaXMgaXMgbm90IGFsd2F5c1xuICAgKiB0aGUgc2FtZSBhcyBzZXR0aW5nIGBzY3JvbGxUb3BgIG9yIGBzY3JvbGxMZWZ0YC4gSW4gYSBob3Jpem9udGFsIHZpZXdwb3J0IHdpdGggcmlnaHQtdG8tbGVmdFxuICAgKiBkaXJlY3Rpb24sIHRoaXMgd291bGQgYmUgdGhlIGVxdWl2YWxlbnQgb2Ygc2V0dGluZyBhIGZpY3Rpb25hbCBgc2Nyb2xsUmlnaHRgIHByb3BlcnR5LlxuICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgdG8gc2Nyb2xsIHRvLlxuICAgKiBAcGFyYW0gYmVoYXZpb3IgVGhlIFNjcm9sbEJlaGF2aW9yIHRvIHVzZSB3aGVuIHNjcm9sbGluZy4gRGVmYXVsdCBpcyBiZWhhdmlvciBpcyBgYXV0b2AuXG4gICAqL1xuICBzY3JvbGxUb09mZnNldChvZmZzZXQ6IG51bWJlciwgYmVoYXZpb3I6IFNjcm9sbEJlaGF2aW9yID0gJ2F1dG8nKSB7XG4gICAgY29uc3Qgb3B0aW9uczogRXh0ZW5kZWRTY3JvbGxUb09wdGlvbnMgPSB7YmVoYXZpb3J9O1xuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgIG9wdGlvbnMuc3RhcnQgPSBvZmZzZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMudG9wID0gb2Zmc2V0O1xuICAgIH1cbiAgICB0aGlzLnNjcm9sbFRvKG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNjcm9sbHMgdG8gdGhlIG9mZnNldCBmb3IgdGhlIGdpdmVuIGluZGV4LlxuICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHNjcm9sbCB0by5cbiAgICogQHBhcmFtIGJlaGF2aW9yIFRoZSBTY3JvbGxCZWhhdmlvciB0byB1c2Ugd2hlbiBzY3JvbGxpbmcuIERlZmF1bHQgaXMgYmVoYXZpb3IgaXMgYGF1dG9gLlxuICAgKi9cbiAgc2Nyb2xsVG9JbmRleChpbmRleDogbnVtYmVyLCAgYmVoYXZpb3I6IFNjcm9sbEJlaGF2aW9yID0gJ2F1dG8nKSB7XG4gICAgdGhpcy5fc2Nyb2xsU3RyYXRlZ3kuc2Nyb2xsVG9JbmRleChpbmRleCwgYmVoYXZpb3IpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGN1cnJlbnQgc2Nyb2xsIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgdmlld3BvcnQgKGluIHBpeGVscykuXG4gICAqIEBwYXJhbSBmcm9tIFRoZSBlZGdlIHRvIG1lYXN1cmUgdGhlIG9mZnNldCBmcm9tLiBEZWZhdWx0cyB0byAndG9wJyBpbiB2ZXJ0aWNhbCBtb2RlIGFuZCAnc3RhcnQnXG4gICAqICAgICBpbiBob3Jpem9udGFsIG1vZGUuXG4gICAqL1xuICBtZWFzdXJlU2Nyb2xsT2Zmc2V0KGZyb20/OiAndG9wJyB8ICdsZWZ0JyB8ICdyaWdodCcgfCAnYm90dG9tJyB8ICdzdGFydCcgfCAnZW5kJyk6IG51bWJlciB7XG4gICAgcmV0dXJuIGZyb20gP1xuICAgICAgc3VwZXIubWVhc3VyZVNjcm9sbE9mZnNldChmcm9tKSA6XG4gICAgICBzdXBlci5tZWFzdXJlU2Nyb2xsT2Zmc2V0KHRoaXMub3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJyA/ICdzdGFydCcgOiAndG9wJyk7XG4gIH1cblxuICAvKiogTWVhc3VyZSB0aGUgY29tYmluZWQgc2l6ZSBvZiBhbGwgb2YgdGhlIHJlbmRlcmVkIGl0ZW1zLiAqL1xuICBtZWFzdXJlUmVuZGVyZWRDb250ZW50U2l6ZSgpOiBudW1iZXIge1xuICAgIGNvbnN0IGNvbnRlbnRFbCA9IHRoaXMuX2NvbnRlbnRXcmFwcGVyLm5hdGl2ZUVsZW1lbnQ7XG4gICAgcmV0dXJuIHRoaXMub3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJyA/IGNvbnRlbnRFbC5vZmZzZXRXaWR0aCA6IGNvbnRlbnRFbC5vZmZzZXRIZWlnaHQ7XG4gIH1cblxuICAvKipcbiAgICogTWVhc3VyZSB0aGUgdG90YWwgY29tYmluZWQgc2l6ZSBvZiB0aGUgZ2l2ZW4gcmFuZ2UuIFRocm93cyBpZiB0aGUgcmFuZ2UgaW5jbHVkZXMgaXRlbXMgdGhhdCBhcmVcbiAgICogbm90IHJlbmRlcmVkLlxuICAgKi9cbiAgbWVhc3VyZVJhbmdlU2l6ZShyYW5nZTogTGlzdFJhbmdlKTogbnVtYmVyIHtcbiAgICBpZiAoIXRoaXMuX2Zvck9mKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2Zvck9mLm1lYXN1cmVSYW5nZVNpemUocmFuZ2UsIHRoaXMub3JpZW50YXRpb24pO1xuICB9XG5cbiAgLyoqIFVwZGF0ZSB0aGUgdmlld3BvcnQgZGltZW5zaW9ucyBhbmQgcmUtcmVuZGVyLiAqL1xuICBjaGVja1ZpZXdwb3J0U2l6ZSgpIHtcbiAgICAvLyBUT0RPOiBDbGVhbnVwIGxhdGVyIHdoZW4gYWRkIGxvZ2ljIGZvciBoYW5kbGluZyBjb250ZW50IHJlc2l6ZVxuICAgIHRoaXMuX21lYXN1cmVWaWV3cG9ydFNpemUoKTtcbiAgICB0aGlzLl9zY3JvbGxTdHJhdGVneS5vbkRhdGFMZW5ndGhDaGFuZ2VkKCk7XG4gIH1cblxuICAvKiogTWVhc3VyZSB0aGUgdmlld3BvcnQgc2l6ZS4gKi9cbiAgcHJpdmF0ZSBfbWVhc3VyZVZpZXdwb3J0U2l6ZSgpIHtcbiAgICBjb25zdCB2aWV3cG9ydEVsID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5fdmlld3BvcnRTaXplID0gdGhpcy5vcmllbnRhdGlvbiA9PT0gJ2hvcml6b250YWwnID9cbiAgICAgICAgdmlld3BvcnRFbC5jbGllbnRXaWR0aCA6IHZpZXdwb3J0RWwuY2xpZW50SGVpZ2h0O1xuICB9XG5cbiAgLyoqIFF1ZXVlIHVwIGNoYW5nZSBkZXRlY3Rpb24gdG8gcnVuLiAqL1xuICBwcml2YXRlIF9tYXJrQ2hhbmdlRGV0ZWN0aW9uTmVlZGVkKHJ1bkFmdGVyPzogRnVuY3Rpb24pIHtcbiAgICBpZiAocnVuQWZ0ZXIpIHtcbiAgICAgIHRoaXMuX3J1bkFmdGVyQ2hhbmdlRGV0ZWN0aW9uLnB1c2gocnVuQWZ0ZXIpO1xuICAgIH1cblxuICAgIC8vIFVzZSBhIFByb21pc2UgdG8gYmF0Y2ggdG9nZXRoZXIgY2FsbHMgdG8gYF9kb0NoYW5nZURldGVjdGlvbmAuIFRoaXMgd2F5IGlmIHdlIHNldCBhIGJ1bmNoIG9mXG4gICAgLy8gcHJvcGVydGllcyBzZXF1ZW50aWFsbHkgd2Ugb25seSBoYXZlIHRvIHJ1biBgX2RvQ2hhbmdlRGV0ZWN0aW9uYCBvbmNlIGF0IHRoZSBlbmQuXG4gICAgaWYgKCF0aGlzLl9pc0NoYW5nZURldGVjdGlvblBlbmRpbmcpIHtcbiAgICAgIHRoaXMuX2lzQ2hhbmdlRGV0ZWN0aW9uUGVuZGluZyA9IHRydWU7XG4gICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5fZG9DaGFuZ2VEZXRlY3Rpb24oKTtcbiAgICAgIH0pKTtcbiAgICB9XG4gIH1cblxuICAvKiogUnVuIGNoYW5nZSBkZXRlY3Rpb24uICovXG4gIHByaXZhdGUgX2RvQ2hhbmdlRGV0ZWN0aW9uKCkge1xuICAgIHRoaXMuX2lzQ2hhbmdlRGV0ZWN0aW9uUGVuZGluZyA9IGZhbHNlO1xuXG4gICAgLy8gQXBwbHkgdGhlIGNvbnRlbnQgdHJhbnNmb3JtLiBUaGUgdHJhbnNmb3JtIGNhbid0IGJlIHNldCB2aWEgYW4gQW5ndWxhciBiaW5kaW5nIGJlY2F1c2VcbiAgICAvLyBieXBhc3NTZWN1cml0eVRydXN0U3R5bGUgaXMgYmFubmVkIGluIEdvb2dsZS4gSG93ZXZlciB0aGUgdmFsdWUgaXMgc2FmZSwgaXQncyBjb21wb3NlZCBvZlxuICAgIC8vIHN0cmluZyBsaXRlcmFscywgYSB2YXJpYWJsZSB0aGF0IGNhbiBvbmx5IGJlICdYJyBvciAnWScsIGFuZCB1c2VyIGlucHV0IHRoYXQgaXMgcnVuIHRocm91Z2hcbiAgICAvLyB0aGUgYE51bWJlcmAgZnVuY3Rpb24gZmlyc3QgdG8gY29lcmNlIGl0IHRvIGEgbnVtZXJpYyB2YWx1ZS5cbiAgICB0aGlzLl9jb250ZW50V3JhcHBlci5uYXRpdmVFbGVtZW50LnN0eWxlLnRyYW5zZm9ybSA9IHRoaXMuX3JlbmRlcmVkQ29udGVudFRyYW5zZm9ybTtcbiAgICAvLyBBcHBseSBjaGFuZ2VzIHRvIEFuZ3VsYXIgYmluZGluZ3MuIE5vdGU6IFdlIG11c3QgY2FsbCBgbWFya0ZvckNoZWNrYCB0byBydW4gY2hhbmdlIGRldGVjdGlvblxuICAgIC8vIGZyb20gdGhlIHJvb3QsIHNpbmNlIHRoZSByZXBlYXRlZCBpdGVtcyBhcmUgY29udGVudCBwcm9qZWN0ZWQgaW4uIENhbGxpbmcgYGRldGVjdENoYW5nZXNgXG4gICAgLy8gaW5zdGVhZCBkb2VzIG5vdCBwcm9wZXJseSBjaGVjayB0aGUgcHJvamVjdGVkIGNvbnRlbnQuXG4gICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuX2NoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpKTtcblxuICAgIGNvbnN0IHJ1bkFmdGVyQ2hhbmdlRGV0ZWN0aW9uID0gdGhpcy5fcnVuQWZ0ZXJDaGFuZ2VEZXRlY3Rpb247XG4gICAgdGhpcy5fcnVuQWZ0ZXJDaGFuZ2VEZXRlY3Rpb24gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGZuIG9mIHJ1bkFmdGVyQ2hhbmdlRGV0ZWN0aW9uKSB7XG4gICAgICBmbigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBDYWxjdWxhdGVzIHRoZSBgc3R5bGUud2lkdGhgIGFuZCBgc3R5bGUuaGVpZ2h0YCBmb3IgdGhlIHNwYWNlciBlbGVtZW50LiAqL1xuICBwcml2YXRlIF9jYWxjdWxhdGVTcGFjZXJTaXplKCkge1xuICAgIHRoaXMuX3RvdGFsQ29udGVudEhlaWdodCA9XG4gICAgICAgIHRoaXMub3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJyA/ICcnIDogYCR7dGhpcy5fdG90YWxDb250ZW50U2l6ZX1weGA7XG4gICAgdGhpcy5fdG90YWxDb250ZW50V2lkdGggPVxuICAgICAgICB0aGlzLm9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCcgPyBgJHt0aGlzLl90b3RhbENvbnRlbnRTaXplfXB4YCA6ICcnO1xuICB9XG59XG4iXX0=
|