@angular/cdk 19.0.0-next.1 → 19.0.0-next.2
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/index.d.ts +5 -1
- package/fesm2022/a11y.mjs +21 -11
- package/fesm2022/a11y.mjs.map +1 -1
- package/fesm2022/cdk.mjs +1 -1
- package/fesm2022/cdk.mjs.map +1 -1
- package/fesm2022/drag-drop.mjs +2 -1
- package/fesm2022/drag-drop.mjs.map +1 -1
- package/fesm2022/overlay.mjs +20 -1
- package/fesm2022/overlay.mjs.map +1 -1
- package/fesm2022/private.mjs +9 -7
- package/fesm2022/private.mjs.map +1 -1
- package/fesm2022/text-field.mjs +17 -2
- package/fesm2022/text-field.mjs.map +1 -1
- package/fesm2022/tree.mjs +13 -7
- package/fesm2022/tree.mjs.map +1 -1
- package/overlay/_index.scss +15 -13
- package/overlay/index.d.ts +5 -0
- package/overlay-prebuilt.css +1 -1
- package/package.json +1 -57
- package/private/index.d.ts +1 -0
- package/schematics/ng-add/index.js +1 -1
- package/schematics/ng-add/index.mjs +1 -1
- package/text-field/index.d.ts +1 -0
- package/tree/index.d.ts +3 -1
- package/esm2022/a11y/a11y-module.mjs +0 -31
- package/esm2022/a11y/a11y_public_index.mjs +0 -5
- package/esm2022/a11y/aria-describer/aria-describer.mjs +0 -232
- package/esm2022/a11y/aria-describer/aria-reference.mjs +0 -47
- package/esm2022/a11y/fake-event-detection.mjs +0 -29
- package/esm2022/a11y/focus-monitor/focus-monitor.mjs +0 -468
- package/esm2022/a11y/focus-trap/configurable-focus-trap-config.mjs +0 -9
- package/esm2022/a11y/focus-trap/configurable-focus-trap-factory.mjs +0 -54
- package/esm2022/a11y/focus-trap/configurable-focus-trap.mjs +0 -51
- package/esm2022/a11y/focus-trap/event-listener-inert-strategy.mjs +0 -61
- package/esm2022/a11y/focus-trap/focus-trap-inert-strategy.mjs +0 -11
- package/esm2022/a11y/focus-trap/focus-trap-manager.mjs +0 -53
- package/esm2022/a11y/focus-trap/focus-trap.mjs +0 -396
- package/esm2022/a11y/high-contrast-mode/high-contrast-mode-detector.mjs +0 -116
- package/esm2022/a11y/index.mjs +0 -9
- package/esm2022/a11y/input-modality/input-modality-detector.mjs +0 -176
- package/esm2022/a11y/interactivity-checker/interactivity-checker.mjs +0 -238
- package/esm2022/a11y/key-manager/activedescendant-key-manager.mjs +0 -20
- package/esm2022/a11y/key-manager/focus-key-manager.mjs +0 -29
- package/esm2022/a11y/key-manager/list-key-manager.mjs +0 -357
- package/esm2022/a11y/key-manager/noop-tree-key-manager.mjs +0 -94
- package/esm2022/a11y/key-manager/tree-key-manager-strategy.mjs +0 -9
- package/esm2022/a11y/key-manager/tree-key-manager.mjs +0 -345
- package/esm2022/a11y/key-manager/typeahead.mjs +0 -91
- package/esm2022/a11y/live-announcer/live-announcer-tokens.mjs +0 -19
- package/esm2022/a11y/live-announcer/live-announcer.mjs +0 -210
- package/esm2022/a11y/public-api.mjs +0 -30
- package/esm2022/accordion/accordion-item.mjs +0 -162
- package/esm2022/accordion/accordion-module.mjs +0 -24
- package/esm2022/accordion/accordion.mjs +0 -65
- package/esm2022/accordion/accordion_public_index.mjs +0 -5
- package/esm2022/accordion/index.mjs +0 -9
- package/esm2022/accordion/public-api.mjs +0 -11
- package/esm2022/bidi/bidi-module.mjs +0 -23
- package/esm2022/bidi/bidi_public_index.mjs +0 -5
- package/esm2022/bidi/dir-document-token.mjs +0 -33
- package/esm2022/bidi/dir.mjs +0 -70
- package/esm2022/bidi/directionality.mjs +0 -52
- package/esm2022/bidi/index.mjs +0 -9
- package/esm2022/bidi/public-api.mjs +0 -12
- package/esm2022/clipboard/clipboard-module.mjs +0 -23
- package/esm2022/clipboard/clipboard.mjs +0 -53
- package/esm2022/clipboard/clipboard_public_index.mjs +0 -5
- package/esm2022/clipboard/copy-to-clipboard.mjs +0 -100
- package/esm2022/clipboard/index.mjs +0 -9
- package/esm2022/clipboard/pending-copy.mjs +0 -71
- package/esm2022/clipboard/public-api.mjs +0 -12
- package/esm2022/coercion/array.mjs +0 -11
- package/esm2022/coercion/boolean-property.mjs +0 -12
- package/esm2022/coercion/css-pixel-value.mjs +0 -15
- package/esm2022/coercion/element.mjs +0 -16
- package/esm2022/coercion/index.mjs +0 -9
- package/esm2022/coercion/number-property.mjs +0 -24
- package/esm2022/coercion/private/index.mjs +0 -9
- package/esm2022/coercion/private/observable.mjs +0 -19
- package/esm2022/coercion/private/private_public_index.mjs +0 -5
- package/esm2022/coercion/public-api.mjs +0 -14
- package/esm2022/coercion/string-array.mjs +0 -38
- package/esm2022/collections/array-data-source.mjs +0 -21
- package/esm2022/collections/collection-viewer.mjs +0 -9
- package/esm2022/collections/collections_public_index.mjs +0 -5
- package/esm2022/collections/data-source.mjs +0 -19
- package/esm2022/collections/dispose-view-repeater-strategy.mjs +0 -48
- package/esm2022/collections/index.mjs +0 -9
- package/esm2022/collections/public-api.mjs +0 -17
- package/esm2022/collections/recycle-view-repeater-strategy.mjs +0 -129
- package/esm2022/collections/selection-model.mjs +0 -225
- package/esm2022/collections/tree-adapter.mjs +0 -9
- package/esm2022/collections/unique-selection-dispatcher.mjs +0 -55
- package/esm2022/collections/view-repeater.mjs +0 -26
- package/esm2022/dialog/dialog-config.mjs +0 -70
- package/esm2022/dialog/dialog-container.mjs +0 -308
- package/esm2022/dialog/dialog-injectors.mjs +0 -40
- package/esm2022/dialog/dialog-module.mjs +0 -40
- package/esm2022/dialog/dialog-ref.mjs +0 -85
- package/esm2022/dialog/dialog.mjs +0 -303
- package/esm2022/dialog/dialog_public_index.mjs +0 -5
- package/esm2022/dialog/index.mjs +0 -9
- package/esm2022/dialog/public-api.mjs +0 -14
- package/esm2022/drag-drop/directives/assertions.mjs +0 -18
- package/esm2022/drag-drop/directives/config.mjs +0 -14
- package/esm2022/drag-drop/directives/drag-handle.mjs +0 -68
- package/esm2022/drag-drop/directives/drag-placeholder.mjs +0 -43
- package/esm2022/drag-drop/directives/drag-preview.mjs +0 -48
- package/esm2022/drag-drop/directives/drag.mjs +0 -520
- package/esm2022/drag-drop/directives/drop-list-group.mjs +0 -47
- package/esm2022/drag-drop/directives/drop-list.mjs +0 -352
- package/esm2022/drag-drop/dom/clone-node.mjs +0 -65
- package/esm2022/drag-drop/dom/dom-rect.mjs +0 -64
- package/esm2022/drag-drop/dom/parent-position-tracker.mjs +0 -76
- package/esm2022/drag-drop/dom/root-node.mjs +0 -21
- package/esm2022/drag-drop/dom/styling.mjs +0 -89
- package/esm2022/drag-drop/dom/transition-duration.mjs +0 -36
- package/esm2022/drag-drop/drag-drop-module.mjs +0 -49
- package/esm2022/drag-drop/drag-drop-registry.mjs +0 -248
- package/esm2022/drag-drop/drag-drop.mjs +0 -57
- package/esm2022/drag-drop/drag-drop_public_index.mjs +0 -5
- package/esm2022/drag-drop/drag-events.mjs +0 -9
- package/esm2022/drag-drop/drag-parent.mjs +0 -16
- package/esm2022/drag-drop/drag-ref.mjs +0 -1097
- package/esm2022/drag-drop/drag-utils.mjs +0 -60
- package/esm2022/drag-drop/drop-list-ref.mjs +0 -672
- package/esm2022/drag-drop/index.mjs +0 -9
- package/esm2022/drag-drop/preview-ref.mjs +0 -125
- package/esm2022/drag-drop/public-api.mjs +0 -23
- package/esm2022/drag-drop/sorting/drop-list-sort-strategy.mjs +0 -9
- package/esm2022/drag-drop/sorting/mixed-sort-strategy.mjs +0 -246
- package/esm2022/drag-drop/sorting/single-axis-sort-strategy.mjs +0 -343
- package/esm2022/index.mjs +0 -9
- package/esm2022/keycodes/index.mjs +0 -9
- package/esm2022/keycodes/keycodes.mjs +0 -127
- package/esm2022/keycodes/keycodes_public_index.mjs +0 -5
- package/esm2022/keycodes/modifiers.mjs +0 -18
- package/esm2022/keycodes/public-api.mjs +0 -10
- package/esm2022/layout/breakpoints-observer.mjs +0 -105
- package/esm2022/layout/breakpoints.mjs +0 -29
- package/esm2022/layout/index.mjs +0 -9
- package/esm2022/layout/layout-module.mjs +0 -19
- package/esm2022/layout/layout_public_index.mjs +0 -5
- package/esm2022/layout/media-matcher.mjs +0 -94
- package/esm2022/layout/public-api.mjs +0 -12
- package/esm2022/listbox/index.mjs +0 -9
- package/esm2022/listbox/listbox-module.mjs +0 -24
- package/esm2022/listbox/listbox.mjs +0 -888
- package/esm2022/listbox/listbox_public_index.mjs +0 -5
- package/esm2022/listbox/public-api.mjs +0 -10
- package/esm2022/menu/context-menu-trigger.mjs +0 -221
- package/esm2022/menu/event-detection.mjs +0 -28
- package/esm2022/menu/index.mjs +0 -9
- package/esm2022/menu/menu-aim.mjs +0 -204
- package/esm2022/menu/menu-bar.mjs +0 -134
- package/esm2022/menu/menu-base.mjs +0 -192
- package/esm2022/menu/menu-errors.mjs +0 -22
- package/esm2022/menu/menu-group.mjs +0 -31
- package/esm2022/menu/menu-interface.mjs +0 -11
- package/esm2022/menu/menu-item-checkbox.mjs +0 -50
- package/esm2022/menu/menu-item-radio.mjs +0 -72
- package/esm2022/menu/menu-item-selectable.mjs +0 -36
- package/esm2022/menu/menu-item.mjs +0 -270
- package/esm2022/menu/menu-module.mjs +0 -60
- package/esm2022/menu/menu-stack.mjs +0 -163
- package/esm2022/menu/menu-trigger-base.mjs +0 -119
- package/esm2022/menu/menu-trigger.mjs +0 -313
- package/esm2022/menu/menu.mjs +0 -135
- package/esm2022/menu/menu_public_index.mjs +0 -5
- package/esm2022/menu/pointer-focus-tracker.mjs +0 -51
- package/esm2022/menu/public-api.mjs +0 -24
- package/esm2022/observers/index.mjs +0 -9
- package/esm2022/observers/observe-content.mjs +0 -216
- package/esm2022/observers/observers_public_index.mjs +0 -5
- package/esm2022/observers/private/index.mjs +0 -9
- package/esm2022/observers/private/private_public_index.mjs +0 -5
- package/esm2022/observers/private/shared-resize-observer.mjs +0 -125
- package/esm2022/observers/public-api.mjs +0 -9
- package/esm2022/overlay/dispatchers/base-overlay-dispatcher.mjs +0 -52
- package/esm2022/overlay/dispatchers/index.mjs +0 -10
- package/esm2022/overlay/dispatchers/overlay-keyboard-dispatcher.mjs +0 -81
- package/esm2022/overlay/dispatchers/overlay-outside-click-dispatcher.mjs +0 -151
- package/esm2022/overlay/fullscreen-overlay-container.mjs +0 -94
- package/esm2022/overlay/index.mjs +0 -9
- package/esm2022/overlay/overlay-config.mjs +0 -45
- package/esm2022/overlay/overlay-container.mjs +0 -81
- package/esm2022/overlay/overlay-directives.mjs +0 -432
- package/esm2022/overlay/overlay-module.mjs +0 -28
- package/esm2022/overlay/overlay-ref.mjs +0 -437
- package/esm2022/overlay/overlay.mjs +0 -126
- package/esm2022/overlay/overlay_public_index.mjs +0 -5
- package/esm2022/overlay/position/connected-position.mjs +0 -88
- package/esm2022/overlay/position/flexible-connected-position-strategy.mjs +0 -1002
- package/esm2022/overlay/position/global-position-strategy.mjs +0 -237
- package/esm2022/overlay/position/overlay-position-builder.mjs +0 -50
- package/esm2022/overlay/position/position-strategy.mjs +0 -9
- package/esm2022/overlay/position/scroll-clip.mjs +0 -40
- package/esm2022/overlay/public-api.mjs +0 -22
- package/esm2022/overlay/scroll/block-scroll-strategy.mjs +0 -80
- package/esm2022/overlay/scroll/close-scroll-strategy.mjs +0 -65
- package/esm2022/overlay/scroll/index.mjs +0 -14
- package/esm2022/overlay/scroll/noop-scroll-strategy.mjs +0 -17
- package/esm2022/overlay/scroll/reposition-scroll-strategy.mjs +0 -61
- package/esm2022/overlay/scroll/scroll-strategy-options.mjs +0 -55
- package/esm2022/overlay/scroll/scroll-strategy.mjs +0 -14
- package/esm2022/platform/features/input-types.mjs +0 -59
- package/esm2022/platform/features/passive-listeners.mjs +0 -36
- package/esm2022/platform/features/scrolling.mjs +0 -104
- package/esm2022/platform/features/shadow-dom.mjs +0 -54
- package/esm2022/platform/features/test-environment.mjs +0 -24
- package/esm2022/platform/index.mjs +0 -9
- package/esm2022/platform/platform-module.mjs +0 -19
- package/esm2022/platform/platform.mjs +0 -82
- package/esm2022/platform/platform_public_index.mjs +0 -5
- package/esm2022/platform/public-api.mjs +0 -15
- package/esm2022/portal/dom-portal-outlet.mjs +0 -158
- package/esm2022/portal/index.mjs +0 -9
- package/esm2022/portal/portal-directives.mjs +0 -251
- package/esm2022/portal/portal-errors.mjs +0 -51
- package/esm2022/portal/portal-injector.mjs +0 -28
- package/esm2022/portal/portal.mjs +0 -189
- package/esm2022/portal/portal_public_index.mjs +0 -5
- package/esm2022/portal/public-api.mjs +0 -12
- package/esm2022/private/index.mjs +0 -9
- package/esm2022/private/private_public_index.mjs +0 -5
- package/esm2022/private/public-api.mjs +0 -9
- package/esm2022/private/style-loader.mjs +0 -50
- package/esm2022/public-api.mjs +0 -9
- package/esm2022/scrolling/fixed-size-virtual-scroll.mjs +0 -218
- package/esm2022/scrolling/index.mjs +0 -9
- package/esm2022/scrolling/public-api.mjs +0 -20
- package/esm2022/scrolling/scroll-dispatcher.mjs +0 -163
- package/esm2022/scrolling/scrollable.mjs +0 -177
- package/esm2022/scrolling/scrolling-module.mjs +0 -69
- package/esm2022/scrolling/scrolling_public_index.mjs +0 -5
- package/esm2022/scrolling/viewport-ruler.mjs +0 -146
- package/esm2022/scrolling/virtual-for-of.mjs +0 -299
- package/esm2022/scrolling/virtual-scroll-repeater.mjs +0 -9
- package/esm2022/scrolling/virtual-scroll-strategy.mjs +0 -11
- package/esm2022/scrolling/virtual-scroll-viewport.mjs +0 -445
- package/esm2022/scrolling/virtual-scrollable-element.mjs +0 -42
- package/esm2022/scrolling/virtual-scrollable-window.mjs +0 -41
- package/esm2022/scrolling/virtual-scrollable.mjs +0 -40
- package/esm2022/stepper/index.mjs +0 -9
- package/esm2022/stepper/public-api.mjs +0 -13
- package/esm2022/stepper/step-header.mjs +0 -31
- package/esm2022/stepper/step-label.mjs +0 -24
- package/esm2022/stepper/stepper-button.mjs +0 -58
- package/esm2022/stepper/stepper-module.mjs +0 -41
- package/esm2022/stepper/stepper.mjs +0 -452
- package/esm2022/stepper/stepper_public_index.mjs +0 -5
- package/esm2022/table/can-stick.mjs +0 -46
- package/esm2022/table/cell.mjs +0 -245
- package/esm2022/table/coalesced-style-scheduler.mjs +0 -79
- package/esm2022/table/index.mjs +0 -9
- package/esm2022/table/public-api.mjs +0 -20
- package/esm2022/table/row.mjs +0 -317
- package/esm2022/table/sticky-position-listener.mjs +0 -11
- package/esm2022/table/sticky-styler.mjs +0 -347
- package/esm2022/table/table-errors.mjs +0 -67
- package/esm2022/table/table-module.mjs +0 -93
- package/esm2022/table/table.mjs +0 -1148
- package/esm2022/table/table_public_index.mjs +0 -5
- package/esm2022/table/text-column.mjs +0 -154
- package/esm2022/table/tokens.mjs +0 -16
- package/esm2022/testing/change-detection.mjs +0 -102
- package/esm2022/testing/component-harness.mjs +0 -328
- package/esm2022/testing/element-dimensions.mjs +0 -9
- package/esm2022/testing/harness-environment.mjs +0 -220
- package/esm2022/testing/index.mjs +0 -9
- package/esm2022/testing/public-api.mjs +0 -15
- package/esm2022/testing/selenium-webdriver/index.mjs +0 -9
- package/esm2022/testing/selenium-webdriver/public-api.mjs +0 -10
- package/esm2022/testing/selenium-webdriver/selenium-web-driver-element.mjs +0 -216
- package/esm2022/testing/selenium-webdriver/selenium-web-driver-harness-environment.mjs +0 -88
- package/esm2022/testing/selenium-webdriver/selenium-webdriver-keys.mjs +0 -64
- package/esm2022/testing/test-element-errors.mjs +0 -15
- package/esm2022/testing/test-element.mjs +0 -49
- package/esm2022/testing/testbed/fake-events/dispatch-events.mjs +0 -53
- package/esm2022/testing/testbed/fake-events/element-focus.mjs +0 -39
- package/esm2022/testing/testbed/fake-events/event-objects.mjs +0 -127
- package/esm2022/testing/testbed/fake-events/index.mjs +0 -14
- package/esm2022/testing/testbed/fake-events/type-in-element.mjs +0 -97
- package/esm2022/testing/testbed/index.mjs +0 -9
- package/esm2022/testing/testbed/public-api.mjs +0 -10
- package/esm2022/testing/testbed/task-state-zone-interceptor.mjs +0 -83
- package/esm2022/testing/testbed/testbed-harness-environment.mjs +0 -165
- package/esm2022/testing/testbed/unit-test-element.mjs +0 -258
- package/esm2022/testing/text-filtering.mjs +0 -21
- package/esm2022/text-field/autofill.mjs +0 -114
- package/esm2022/text-field/autosize.mjs +0 -309
- package/esm2022/text-field/index.mjs +0 -9
- package/esm2022/text-field/public-api.mjs +0 -11
- package/esm2022/text-field/text-field-module.mjs +0 -24
- package/esm2022/text-field/text-field_public_index.mjs +0 -5
- package/esm2022/tree/control/base-tree-control.mjs +0 -62
- package/esm2022/tree/control/flat-tree-control.mjs +0 -57
- package/esm2022/tree/control/nested-tree-control.mjs +0 -67
- package/esm2022/tree/control/tree-control.mjs +0 -2
- package/esm2022/tree/index.mjs +0 -9
- package/esm2022/tree/nested-node.mjs +0 -103
- package/esm2022/tree/node.mjs +0 -36
- package/esm2022/tree/outlet.mjs +0 -40
- package/esm2022/tree/padding.mjs +0 -129
- package/esm2022/tree/public-api.mjs +0 -20
- package/esm2022/tree/toggle.mjs +0 -51
- package/esm2022/tree/tree-errors.mjs +0 -44
- package/esm2022/tree/tree-module.mjs +0 -49
- package/esm2022/tree/tree.mjs +0 -1123
- package/esm2022/tree/tree_public_index.mjs +0 -5
- package/esm2022/version.mjs +0 -11
|
@@ -1,437 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7
|
-
*/
|
|
8
|
-
import { afterNextRender, afterRender, untracked, } from '@angular/core';
|
|
9
|
-
import { Subject, merge, Subscription } from 'rxjs';
|
|
10
|
-
import { takeUntil } from 'rxjs/operators';
|
|
11
|
-
import { coerceCssPixelValue, coerceArray } from '@angular/cdk/coercion';
|
|
12
|
-
/**
|
|
13
|
-
* Reference to an overlay that has been created with the Overlay service.
|
|
14
|
-
* Used to manipulate or dispose of said overlay.
|
|
15
|
-
*/
|
|
16
|
-
export class OverlayRef {
|
|
17
|
-
constructor(_portalOutlet, _host, _pane, _config, _ngZone, _keyboardDispatcher, _document, _location, _outsideClickDispatcher, _animationsDisabled = false, _injector) {
|
|
18
|
-
this._portalOutlet = _portalOutlet;
|
|
19
|
-
this._host = _host;
|
|
20
|
-
this._pane = _pane;
|
|
21
|
-
this._config = _config;
|
|
22
|
-
this._ngZone = _ngZone;
|
|
23
|
-
this._keyboardDispatcher = _keyboardDispatcher;
|
|
24
|
-
this._document = _document;
|
|
25
|
-
this._location = _location;
|
|
26
|
-
this._outsideClickDispatcher = _outsideClickDispatcher;
|
|
27
|
-
this._animationsDisabled = _animationsDisabled;
|
|
28
|
-
this._injector = _injector;
|
|
29
|
-
this._backdropElement = null;
|
|
30
|
-
this._backdropClick = new Subject();
|
|
31
|
-
this._attachments = new Subject();
|
|
32
|
-
this._detachments = new Subject();
|
|
33
|
-
this._locationChanges = Subscription.EMPTY;
|
|
34
|
-
this._backdropClickHandler = (event) => this._backdropClick.next(event);
|
|
35
|
-
this._backdropTransitionendHandler = (event) => {
|
|
36
|
-
this._disposeBackdrop(event.target);
|
|
37
|
-
};
|
|
38
|
-
/** Stream of keydown events dispatched to this overlay. */
|
|
39
|
-
this._keydownEvents = new Subject();
|
|
40
|
-
/** Stream of mouse outside events dispatched to this overlay. */
|
|
41
|
-
this._outsidePointerEvents = new Subject();
|
|
42
|
-
this._renders = new Subject();
|
|
43
|
-
if (_config.scrollStrategy) {
|
|
44
|
-
this._scrollStrategy = _config.scrollStrategy;
|
|
45
|
-
this._scrollStrategy.attach(this);
|
|
46
|
-
}
|
|
47
|
-
this._positionStrategy = _config.positionStrategy;
|
|
48
|
-
// Users could open the overlay from an `effect`, in which case we need to
|
|
49
|
-
// run the `afterRender` as `untracked`. We don't recommend that users do
|
|
50
|
-
// this, but we also don't want to break users who are doing it.
|
|
51
|
-
this._afterRenderRef = untracked(() => afterRender(() => {
|
|
52
|
-
this._renders.next();
|
|
53
|
-
}, { injector: this._injector }));
|
|
54
|
-
}
|
|
55
|
-
/** The overlay's HTML element */
|
|
56
|
-
get overlayElement() {
|
|
57
|
-
return this._pane;
|
|
58
|
-
}
|
|
59
|
-
/** The overlay's backdrop HTML element. */
|
|
60
|
-
get backdropElement() {
|
|
61
|
-
return this._backdropElement;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Wrapper around the panel element. Can be used for advanced
|
|
65
|
-
* positioning where a wrapper with specific styling is
|
|
66
|
-
* required around the overlay pane.
|
|
67
|
-
*/
|
|
68
|
-
get hostElement() {
|
|
69
|
-
return this._host;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Attaches content, given via a Portal, to the overlay.
|
|
73
|
-
* If the overlay is configured to have a backdrop, it will be created.
|
|
74
|
-
*
|
|
75
|
-
* @param portal Portal instance to which to attach the overlay.
|
|
76
|
-
* @returns The portal attachment result.
|
|
77
|
-
*/
|
|
78
|
-
attach(portal) {
|
|
79
|
-
// Insert the host into the DOM before attaching the portal, otherwise
|
|
80
|
-
// the animations module will skip animations on repeat attachments.
|
|
81
|
-
if (!this._host.parentElement && this._previousHostParent) {
|
|
82
|
-
this._previousHostParent.appendChild(this._host);
|
|
83
|
-
}
|
|
84
|
-
const attachResult = this._portalOutlet.attach(portal);
|
|
85
|
-
if (this._positionStrategy) {
|
|
86
|
-
this._positionStrategy.attach(this);
|
|
87
|
-
}
|
|
88
|
-
this._updateStackingOrder();
|
|
89
|
-
this._updateElementSize();
|
|
90
|
-
this._updateElementDirection();
|
|
91
|
-
if (this._scrollStrategy) {
|
|
92
|
-
this._scrollStrategy.enable();
|
|
93
|
-
}
|
|
94
|
-
// Update the position once the overlay is fully rendered before attempting to position it,
|
|
95
|
-
// as the position may depend on the size of the rendered content.
|
|
96
|
-
afterNextRender(() => {
|
|
97
|
-
// The overlay could've been detached before the callback executed.
|
|
98
|
-
if (this.hasAttached()) {
|
|
99
|
-
this.updatePosition();
|
|
100
|
-
}
|
|
101
|
-
}, { injector: this._injector });
|
|
102
|
-
// Enable pointer events for the overlay pane element.
|
|
103
|
-
this._togglePointerEvents(true);
|
|
104
|
-
if (this._config.hasBackdrop) {
|
|
105
|
-
this._attachBackdrop();
|
|
106
|
-
}
|
|
107
|
-
if (this._config.panelClass) {
|
|
108
|
-
this._toggleClasses(this._pane, this._config.panelClass, true);
|
|
109
|
-
}
|
|
110
|
-
// Only emit the `attachments` event once all other setup is done.
|
|
111
|
-
this._attachments.next();
|
|
112
|
-
// Track this overlay by the keyboard dispatcher
|
|
113
|
-
this._keyboardDispatcher.add(this);
|
|
114
|
-
if (this._config.disposeOnNavigation) {
|
|
115
|
-
this._locationChanges = this._location.subscribe(() => this.dispose());
|
|
116
|
-
}
|
|
117
|
-
this._outsideClickDispatcher.add(this);
|
|
118
|
-
// TODO(crisbeto): the null check is here, because the portal outlet returns `any`.
|
|
119
|
-
// We should be guaranteed for the result to be `ComponentRef | EmbeddedViewRef`, but
|
|
120
|
-
// `instanceof EmbeddedViewRef` doesn't appear to work at the moment.
|
|
121
|
-
if (typeof attachResult?.onDestroy === 'function') {
|
|
122
|
-
// In most cases we control the portal and we know when it is being detached so that
|
|
123
|
-
// we can finish the disposal process. The exception is if the user passes in a custom
|
|
124
|
-
// `ViewContainerRef` that isn't destroyed through the overlay API. Note that we use
|
|
125
|
-
// `detach` here instead of `dispose`, because we don't know if the user intends to
|
|
126
|
-
// reattach the overlay at a later point. It also has the advantage of waiting for animations.
|
|
127
|
-
attachResult.onDestroy(() => {
|
|
128
|
-
if (this.hasAttached()) {
|
|
129
|
-
// We have to delay the `detach` call, because detaching immediately prevents
|
|
130
|
-
// other destroy hooks from running. This is likely a framework bug similar to
|
|
131
|
-
// https://github.com/angular/angular/issues/46119
|
|
132
|
-
this._ngZone.runOutsideAngular(() => Promise.resolve().then(() => this.detach()));
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
return attachResult;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Detaches an overlay from a portal.
|
|
140
|
-
* @returns The portal detachment result.
|
|
141
|
-
*/
|
|
142
|
-
detach() {
|
|
143
|
-
if (!this.hasAttached()) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
this.detachBackdrop();
|
|
147
|
-
// When the overlay is detached, the pane element should disable pointer events.
|
|
148
|
-
// This is necessary because otherwise the pane element will cover the page and disable
|
|
149
|
-
// pointer events therefore. Depends on the position strategy and the applied pane boundaries.
|
|
150
|
-
this._togglePointerEvents(false);
|
|
151
|
-
if (this._positionStrategy && this._positionStrategy.detach) {
|
|
152
|
-
this._positionStrategy.detach();
|
|
153
|
-
}
|
|
154
|
-
if (this._scrollStrategy) {
|
|
155
|
-
this._scrollStrategy.disable();
|
|
156
|
-
}
|
|
157
|
-
const detachmentResult = this._portalOutlet.detach();
|
|
158
|
-
// Only emit after everything is detached.
|
|
159
|
-
this._detachments.next();
|
|
160
|
-
// Remove this overlay from keyboard dispatcher tracking.
|
|
161
|
-
this._keyboardDispatcher.remove(this);
|
|
162
|
-
// Keeping the host element in the DOM can cause scroll jank, because it still gets
|
|
163
|
-
// rendered, even though it's transparent and unclickable which is why we remove it.
|
|
164
|
-
this._detachContentWhenEmpty();
|
|
165
|
-
this._locationChanges.unsubscribe();
|
|
166
|
-
this._outsideClickDispatcher.remove(this);
|
|
167
|
-
return detachmentResult;
|
|
168
|
-
}
|
|
169
|
-
/** Cleans up the overlay from the DOM. */
|
|
170
|
-
dispose() {
|
|
171
|
-
const isAttached = this.hasAttached();
|
|
172
|
-
if (this._positionStrategy) {
|
|
173
|
-
this._positionStrategy.dispose();
|
|
174
|
-
}
|
|
175
|
-
this._disposeScrollStrategy();
|
|
176
|
-
this._disposeBackdrop(this._backdropElement);
|
|
177
|
-
this._locationChanges.unsubscribe();
|
|
178
|
-
this._keyboardDispatcher.remove(this);
|
|
179
|
-
this._portalOutlet.dispose();
|
|
180
|
-
this._attachments.complete();
|
|
181
|
-
this._backdropClick.complete();
|
|
182
|
-
this._keydownEvents.complete();
|
|
183
|
-
this._outsidePointerEvents.complete();
|
|
184
|
-
this._outsideClickDispatcher.remove(this);
|
|
185
|
-
this._host?.remove();
|
|
186
|
-
this._previousHostParent = this._pane = this._host = null;
|
|
187
|
-
if (isAttached) {
|
|
188
|
-
this._detachments.next();
|
|
189
|
-
}
|
|
190
|
-
this._detachments.complete();
|
|
191
|
-
this._afterRenderRef.destroy();
|
|
192
|
-
this._renders.complete();
|
|
193
|
-
}
|
|
194
|
-
/** Whether the overlay has attached content. */
|
|
195
|
-
hasAttached() {
|
|
196
|
-
return this._portalOutlet.hasAttached();
|
|
197
|
-
}
|
|
198
|
-
/** Gets an observable that emits when the backdrop has been clicked. */
|
|
199
|
-
backdropClick() {
|
|
200
|
-
return this._backdropClick;
|
|
201
|
-
}
|
|
202
|
-
/** Gets an observable that emits when the overlay has been attached. */
|
|
203
|
-
attachments() {
|
|
204
|
-
return this._attachments;
|
|
205
|
-
}
|
|
206
|
-
/** Gets an observable that emits when the overlay has been detached. */
|
|
207
|
-
detachments() {
|
|
208
|
-
return this._detachments;
|
|
209
|
-
}
|
|
210
|
-
/** Gets an observable of keydown events targeted to this overlay. */
|
|
211
|
-
keydownEvents() {
|
|
212
|
-
return this._keydownEvents;
|
|
213
|
-
}
|
|
214
|
-
/** Gets an observable of pointer events targeted outside this overlay. */
|
|
215
|
-
outsidePointerEvents() {
|
|
216
|
-
return this._outsidePointerEvents;
|
|
217
|
-
}
|
|
218
|
-
/** Gets the current overlay configuration, which is immutable. */
|
|
219
|
-
getConfig() {
|
|
220
|
-
return this._config;
|
|
221
|
-
}
|
|
222
|
-
/** Updates the position of the overlay based on the position strategy. */
|
|
223
|
-
updatePosition() {
|
|
224
|
-
if (this._positionStrategy) {
|
|
225
|
-
this._positionStrategy.apply();
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
/** Switches to a new position strategy and updates the overlay position. */
|
|
229
|
-
updatePositionStrategy(strategy) {
|
|
230
|
-
if (strategy === this._positionStrategy) {
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
if (this._positionStrategy) {
|
|
234
|
-
this._positionStrategy.dispose();
|
|
235
|
-
}
|
|
236
|
-
this._positionStrategy = strategy;
|
|
237
|
-
if (this.hasAttached()) {
|
|
238
|
-
strategy.attach(this);
|
|
239
|
-
this.updatePosition();
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
/** Update the size properties of the overlay. */
|
|
243
|
-
updateSize(sizeConfig) {
|
|
244
|
-
this._config = { ...this._config, ...sizeConfig };
|
|
245
|
-
this._updateElementSize();
|
|
246
|
-
}
|
|
247
|
-
/** Sets the LTR/RTL direction for the overlay. */
|
|
248
|
-
setDirection(dir) {
|
|
249
|
-
this._config = { ...this._config, direction: dir };
|
|
250
|
-
this._updateElementDirection();
|
|
251
|
-
}
|
|
252
|
-
/** Add a CSS class or an array of classes to the overlay pane. */
|
|
253
|
-
addPanelClass(classes) {
|
|
254
|
-
if (this._pane) {
|
|
255
|
-
this._toggleClasses(this._pane, classes, true);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
/** Remove a CSS class or an array of classes from the overlay pane. */
|
|
259
|
-
removePanelClass(classes) {
|
|
260
|
-
if (this._pane) {
|
|
261
|
-
this._toggleClasses(this._pane, classes, false);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Returns the layout direction of the overlay panel.
|
|
266
|
-
*/
|
|
267
|
-
getDirection() {
|
|
268
|
-
const direction = this._config.direction;
|
|
269
|
-
if (!direction) {
|
|
270
|
-
return 'ltr';
|
|
271
|
-
}
|
|
272
|
-
return typeof direction === 'string' ? direction : direction.value;
|
|
273
|
-
}
|
|
274
|
-
/** Switches to a new scroll strategy. */
|
|
275
|
-
updateScrollStrategy(strategy) {
|
|
276
|
-
if (strategy === this._scrollStrategy) {
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
this._disposeScrollStrategy();
|
|
280
|
-
this._scrollStrategy = strategy;
|
|
281
|
-
if (this.hasAttached()) {
|
|
282
|
-
strategy.attach(this);
|
|
283
|
-
strategy.enable();
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
/** Updates the text direction of the overlay panel. */
|
|
287
|
-
_updateElementDirection() {
|
|
288
|
-
this._host.setAttribute('dir', this.getDirection());
|
|
289
|
-
}
|
|
290
|
-
/** Updates the size of the overlay element based on the overlay config. */
|
|
291
|
-
_updateElementSize() {
|
|
292
|
-
if (!this._pane) {
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
const style = this._pane.style;
|
|
296
|
-
style.width = coerceCssPixelValue(this._config.width);
|
|
297
|
-
style.height = coerceCssPixelValue(this._config.height);
|
|
298
|
-
style.minWidth = coerceCssPixelValue(this._config.minWidth);
|
|
299
|
-
style.minHeight = coerceCssPixelValue(this._config.minHeight);
|
|
300
|
-
style.maxWidth = coerceCssPixelValue(this._config.maxWidth);
|
|
301
|
-
style.maxHeight = coerceCssPixelValue(this._config.maxHeight);
|
|
302
|
-
}
|
|
303
|
-
/** Toggles the pointer events for the overlay pane element. */
|
|
304
|
-
_togglePointerEvents(enablePointer) {
|
|
305
|
-
this._pane.style.pointerEvents = enablePointer ? '' : 'none';
|
|
306
|
-
}
|
|
307
|
-
/** Attaches a backdrop for this overlay. */
|
|
308
|
-
_attachBackdrop() {
|
|
309
|
-
const showingClass = 'cdk-overlay-backdrop-showing';
|
|
310
|
-
this._backdropElement = this._document.createElement('div');
|
|
311
|
-
this._backdropElement.classList.add('cdk-overlay-backdrop');
|
|
312
|
-
if (this._animationsDisabled) {
|
|
313
|
-
this._backdropElement.classList.add('cdk-overlay-backdrop-noop-animation');
|
|
314
|
-
}
|
|
315
|
-
if (this._config.backdropClass) {
|
|
316
|
-
this._toggleClasses(this._backdropElement, this._config.backdropClass, true);
|
|
317
|
-
}
|
|
318
|
-
// Insert the backdrop before the pane in the DOM order,
|
|
319
|
-
// in order to handle stacked overlays properly.
|
|
320
|
-
this._host.parentElement.insertBefore(this._backdropElement, this._host);
|
|
321
|
-
// Forward backdrop clicks such that the consumer of the overlay can perform whatever
|
|
322
|
-
// action desired when such a click occurs (usually closing the overlay).
|
|
323
|
-
this._backdropElement.addEventListener('click', this._backdropClickHandler);
|
|
324
|
-
// Add class to fade-in the backdrop after one frame.
|
|
325
|
-
if (!this._animationsDisabled && typeof requestAnimationFrame !== 'undefined') {
|
|
326
|
-
this._ngZone.runOutsideAngular(() => {
|
|
327
|
-
requestAnimationFrame(() => {
|
|
328
|
-
if (this._backdropElement) {
|
|
329
|
-
this._backdropElement.classList.add(showingClass);
|
|
330
|
-
}
|
|
331
|
-
});
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
this._backdropElement.classList.add(showingClass);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Updates the stacking order of the element, moving it to the top if necessary.
|
|
340
|
-
* This is required in cases where one overlay was detached, while another one,
|
|
341
|
-
* that should be behind it, was destroyed. The next time both of them are opened,
|
|
342
|
-
* the stacking will be wrong, because the detached element's pane will still be
|
|
343
|
-
* in its original DOM position.
|
|
344
|
-
*/
|
|
345
|
-
_updateStackingOrder() {
|
|
346
|
-
if (this._host.nextSibling) {
|
|
347
|
-
this._host.parentNode.appendChild(this._host);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
/** Detaches the backdrop (if any) associated with the overlay. */
|
|
351
|
-
detachBackdrop() {
|
|
352
|
-
const backdropToDetach = this._backdropElement;
|
|
353
|
-
if (!backdropToDetach) {
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
if (this._animationsDisabled) {
|
|
357
|
-
this._disposeBackdrop(backdropToDetach);
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
backdropToDetach.classList.remove('cdk-overlay-backdrop-showing');
|
|
361
|
-
this._ngZone.runOutsideAngular(() => {
|
|
362
|
-
backdropToDetach.addEventListener('transitionend', this._backdropTransitionendHandler);
|
|
363
|
-
});
|
|
364
|
-
// If the backdrop doesn't have a transition, the `transitionend` event won't fire.
|
|
365
|
-
// In this case we make it unclickable and we try to remove it after a delay.
|
|
366
|
-
backdropToDetach.style.pointerEvents = 'none';
|
|
367
|
-
// Run this outside the Angular zone because there's nothing that Angular cares about.
|
|
368
|
-
// If it were to run inside the Angular zone, every test that used Overlay would have to be
|
|
369
|
-
// either async or fakeAsync.
|
|
370
|
-
this._backdropTimeout = this._ngZone.runOutsideAngular(() => setTimeout(() => {
|
|
371
|
-
this._disposeBackdrop(backdropToDetach);
|
|
372
|
-
}, 500));
|
|
373
|
-
}
|
|
374
|
-
/** Toggles a single CSS class or an array of classes on an element. */
|
|
375
|
-
_toggleClasses(element, cssClasses, isAdd) {
|
|
376
|
-
const classes = coerceArray(cssClasses || []).filter(c => !!c);
|
|
377
|
-
if (classes.length) {
|
|
378
|
-
isAdd ? element.classList.add(...classes) : element.classList.remove(...classes);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
/** Detaches the overlay content next time the zone stabilizes. */
|
|
382
|
-
_detachContentWhenEmpty() {
|
|
383
|
-
// Normally we wouldn't have to explicitly run this outside the `NgZone`, however
|
|
384
|
-
// if the consumer is using `zone-patch-rxjs`, the `Subscription.unsubscribe` call will
|
|
385
|
-
// be patched to run inside the zone, which will throw us into an infinite loop.
|
|
386
|
-
this._ngZone.runOutsideAngular(() => {
|
|
387
|
-
// We can't remove the host here immediately, because the overlay pane's content
|
|
388
|
-
// might still be animating. This stream helps us avoid interrupting the animation
|
|
389
|
-
// by waiting for the pane to become empty.
|
|
390
|
-
const subscription = this._renders
|
|
391
|
-
.pipe(takeUntil(merge(this._attachments, this._detachments)))
|
|
392
|
-
.subscribe(() => {
|
|
393
|
-
// Needs a couple of checks for the pane and host, because
|
|
394
|
-
// they may have been removed by the time the zone stabilizes.
|
|
395
|
-
if (!this._pane || !this._host || this._pane.children.length === 0) {
|
|
396
|
-
if (this._pane && this._config.panelClass) {
|
|
397
|
-
this._toggleClasses(this._pane, this._config.panelClass, false);
|
|
398
|
-
}
|
|
399
|
-
if (this._host && this._host.parentElement) {
|
|
400
|
-
this._previousHostParent = this._host.parentElement;
|
|
401
|
-
this._host.remove();
|
|
402
|
-
}
|
|
403
|
-
subscription.unsubscribe();
|
|
404
|
-
}
|
|
405
|
-
});
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
/** Disposes of a scroll strategy. */
|
|
409
|
-
_disposeScrollStrategy() {
|
|
410
|
-
const scrollStrategy = this._scrollStrategy;
|
|
411
|
-
if (scrollStrategy) {
|
|
412
|
-
scrollStrategy.disable();
|
|
413
|
-
if (scrollStrategy.detach) {
|
|
414
|
-
scrollStrategy.detach();
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
/** Removes a backdrop element from the DOM. */
|
|
419
|
-
_disposeBackdrop(backdrop) {
|
|
420
|
-
if (backdrop) {
|
|
421
|
-
backdrop.removeEventListener('click', this._backdropClickHandler);
|
|
422
|
-
backdrop.removeEventListener('transitionend', this._backdropTransitionendHandler);
|
|
423
|
-
backdrop.remove();
|
|
424
|
-
// It is possible that a new portal has been attached to this overlay since we started
|
|
425
|
-
// removing the backdrop. If that is the case, only clear the backdrop reference if it
|
|
426
|
-
// is still the same instance that we started to remove.
|
|
427
|
-
if (this._backdropElement === backdrop) {
|
|
428
|
-
this._backdropElement = null;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
if (this._backdropTimeout) {
|
|
432
|
-
clearTimeout(this._backdropTimeout);
|
|
433
|
-
this._backdropTimeout = undefined;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcmxheS1yZWYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvY2RrL292ZXJsYXkvb3ZlcmxheS1yZWYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBSUgsT0FBTyxFQUtMLGVBQWUsRUFDZixXQUFXLEVBQ1gsU0FBUyxHQUVWLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBYSxPQUFPLEVBQUUsS0FBSyxFQUFvQixZQUFZLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDaEYsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBSXpDLE9BQU8sRUFBQyxtQkFBbUIsRUFBRSxXQUFXLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQVN2RTs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sVUFBVTtJQThCckIsWUFDVSxhQUEyQixFQUMzQixLQUFrQixFQUNsQixLQUFrQixFQUNsQixPQUF1QyxFQUN2QyxPQUFlLEVBQ2YsbUJBQThDLEVBQzlDLFNBQW1CLEVBQ25CLFNBQW1CLEVBQ25CLHVCQUFzRCxFQUN0RCxzQkFBc0IsS0FBSyxFQUMzQixTQUE4QjtRQVY5QixrQkFBYSxHQUFiLGFBQWEsQ0FBYztRQUMzQixVQUFLLEdBQUwsS0FBSyxDQUFhO1FBQ2xCLFVBQUssR0FBTCxLQUFLLENBQWE7UUFDbEIsWUFBTyxHQUFQLE9BQU8sQ0FBZ0M7UUFDdkMsWUFBTyxHQUFQLE9BQU8sQ0FBUTtRQUNmLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBMkI7UUFDOUMsY0FBUyxHQUFULFNBQVMsQ0FBVTtRQUNuQixjQUFTLEdBQVQsU0FBUyxDQUFVO1FBQ25CLDRCQUF1QixHQUF2Qix1QkFBdUIsQ0FBK0I7UUFDdEQsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFRO1FBQzNCLGNBQVMsR0FBVCxTQUFTLENBQXFCO1FBeENoQyxxQkFBZ0IsR0FBdUIsSUFBSSxDQUFDO1FBRW5DLG1CQUFjLEdBQUcsSUFBSSxPQUFPLEVBQWMsQ0FBQztRQUMzQyxpQkFBWSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDbkMsaUJBQVksR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBRzVDLHFCQUFnQixHQUFxQixZQUFZLENBQUMsS0FBSyxDQUFDO1FBQ3hELDBCQUFxQixHQUFHLENBQUMsS0FBaUIsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0Usa0NBQTZCLEdBQUcsQ0FBQyxLQUFzQixFQUFFLEVBQUU7WUFDakUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxNQUE0QixDQUFDLENBQUM7UUFDNUQsQ0FBQyxDQUFDO1FBUUYsMkRBQTJEO1FBQ2xELG1CQUFjLEdBQUcsSUFBSSxPQUFPLEVBQWlCLENBQUM7UUFFdkQsaUVBQWlFO1FBQ3hELDBCQUFxQixHQUFHLElBQUksT0FBTyxFQUFjLENBQUM7UUFFbkQsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFpQnJDLElBQUksT0FBTyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQztZQUM5QyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyxDQUFDO1FBRUQsSUFBSSxDQUFDLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztRQUVsRCwwRUFBMEU7UUFDMUUseUVBQXlFO1FBQ3pFLGdFQUFnRTtRQUNoRSxJQUFJLENBQUMsZUFBZSxHQUFHLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FDcEMsV0FBVyxDQUNULEdBQUcsRUFBRTtZQUNILElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdkIsQ0FBQyxFQUNELEVBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUMsQ0FDM0IsQ0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELGlDQUFpQztJQUNqQyxJQUFJLGNBQWM7UUFDaEIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3BCLENBQUM7SUFFRCwyQ0FBMkM7SUFDM0MsSUFBSSxlQUFlO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDO0lBQy9CLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsSUFBSSxXQUFXO1FBQ2IsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3BCLENBQUM7SUFNRDs7Ozs7O09BTUc7SUFDSCxNQUFNLENBQUMsTUFBbUI7UUFDeEIsc0VBQXNFO1FBQ3RFLG9FQUFvRTtRQUNwRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDMUQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkQsQ0FBQztRQUVELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXZELElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBRUQsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFFL0IsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNoQyxDQUFDO1FBRUQsMkZBQTJGO1FBQzNGLGtFQUFrRTtRQUNsRSxlQUFlLENBQ2IsR0FBRyxFQUFFO1lBQ0gsbUVBQW1FO1lBQ25FLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QixDQUFDO1FBQ0gsQ0FBQyxFQUNELEVBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUMsQ0FDM0IsQ0FBQztRQUVGLHNEQUFzRDtRQUN0RCxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFaEMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN6QixDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNqRSxDQUFDO1FBRUQsa0VBQWtFO1FBQ2xFLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFekIsZ0RBQWdEO1FBQ2hELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbkMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ3pFLENBQUM7UUFFRCxJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXZDLG1GQUFtRjtRQUNuRixxRkFBcUY7UUFDckYscUVBQXFFO1FBQ3JFLElBQUksT0FBTyxZQUFZLEVBQUUsU0FBUyxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQ2xELG9GQUFvRjtZQUNwRixzRkFBc0Y7WUFDdEYsb0ZBQW9GO1lBQ3BGLG1GQUFtRjtZQUNuRiw4RkFBOEY7WUFDOUYsWUFBWSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7Z0JBQzFCLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7b0JBQ3ZCLDZFQUE2RTtvQkFDN0UsOEVBQThFO29CQUM5RSxrREFBa0Q7b0JBQ2xELElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNwRixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsT0FBTyxZQUFZLENBQUM7SUFDdEIsQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU07UUFDSixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7WUFDeEIsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFFdEIsZ0ZBQWdGO1FBQ2hGLHVGQUF1RjtRQUN2Riw4RkFBOEY7UUFDOUYsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWpDLElBQUksSUFBSSxDQUFDLGlCQUFpQixJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUM1RCxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbEMsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDakMsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUVyRCwwQ0FBMEM7UUFDMUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUV6Qix5REFBeUQ7UUFDekQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV0QyxtRkFBbUY7UUFDbkYsb0ZBQW9GO1FBQ3BGLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNwQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFDLE9BQU8sZ0JBQWdCLENBQUM7SUFDMUIsQ0FBQztJQUVELDBDQUEwQztJQUMxQyxPQUFPO1FBQ0wsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRXRDLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25DLENBQUM7UUFFRCxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUM5QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDN0MsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBRXJCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSyxDQUFDO1FBRTNELElBQUksVUFBVSxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzNCLENBQUM7UUFFRCxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQsZ0RBQWdEO0lBQ2hELFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDMUMsQ0FBQztJQUVELHdFQUF3RTtJQUN4RSxhQUFhO1FBQ1gsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDO0lBQzdCLENBQUM7SUFFRCx3RUFBd0U7SUFDeEUsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUMzQixDQUFDO0lBRUQsd0VBQXdFO0lBQ3hFLFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUM7SUFDM0IsQ0FBQztJQUVELHFFQUFxRTtJQUNyRSxhQUFhO1FBQ1gsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDO0lBQzdCLENBQUM7SUFFRCwwRUFBMEU7SUFDMUUsb0JBQW9CO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLHFCQUFxQixDQUFDO0lBQ3BDLENBQUM7SUFFRCxrRUFBa0U7SUFDbEUsU0FBUztRQUNQLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBRUQsMEVBQTBFO0lBQzFFLGNBQWM7UUFDWixJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNqQyxDQUFDO0lBQ0gsQ0FBQztJQUVELDRFQUE0RTtJQUM1RSxzQkFBc0IsQ0FBQyxRQUEwQjtRQUMvQyxJQUFJLFFBQVEsS0FBSyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN4QyxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25DLENBQUM7UUFFRCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsUUFBUSxDQUFDO1FBRWxDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7WUFDdkIsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0QixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDeEIsQ0FBQztJQUNILENBQUM7SUFFRCxpREFBaUQ7SUFDakQsVUFBVSxDQUFDLFVBQTZCO1FBQ3RDLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBQyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxVQUFVLEVBQUMsQ0FBQztRQUNoRCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRUQsa0RBQWtEO0lBQ2xELFlBQVksQ0FBQyxHQUErQjtRQUMxQyxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRUQsa0VBQWtFO0lBQ2xFLGFBQWEsQ0FBQyxPQUEwQjtRQUN0QyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDakQsQ0FBQztJQUNILENBQUM7SUFFRCx1RUFBdUU7SUFDdkUsZ0JBQWdCLENBQUMsT0FBMEI7UUFDekMsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2xELENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxZQUFZO1FBQ1YsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7UUFFekMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2YsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBRUQsT0FBTyxPQUFPLFNBQVMsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztJQUNyRSxDQUFDO0lBRUQseUNBQXlDO0lBQ3pDLG9CQUFvQixDQUFDLFFBQXdCO1FBQzNDLElBQUksUUFBUSxLQUFLLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN0QyxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxlQUFlLEdBQUcsUUFBUSxDQUFDO1FBRWhDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7WUFDdkIsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0QixRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDcEIsQ0FBQztJQUNILENBQUM7SUFFRCx1REFBdUQ7SUFDL0MsdUJBQXVCO1FBQzdCLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRUQsMkVBQTJFO0lBQ25FLGtCQUFrQjtRQUN4QixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2hCLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFFL0IsS0FBSyxDQUFDLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3RELEtBQUssQ0FBQyxNQUFNLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4RCxLQUFLLENBQUMsUUFBUSxHQUFHLG1CQUFtQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDNUQsS0FBSyxDQUFDLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzlELEtBQUssQ0FBQyxRQUFRLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM1RCxLQUFLLENBQUMsU0FBUyxHQUFHLG1CQUFtQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVELCtEQUErRDtJQUN2RCxvQkFBb0IsQ0FBQyxhQUFzQjtRQUNqRCxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUMvRCxDQUFDO0lBRUQsNENBQTRDO0lBQ3BDLGVBQWU7UUFDckIsTUFBTSxZQUFZLEdBQUcsOEJBQThCLENBQUM7UUFFcEQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFFNUQsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUM3QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQzdFLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDL0UsQ0FBQztRQUVELHdEQUF3RDtRQUN4RCxnREFBZ0Q7UUFDaEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFjLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFMUUscUZBQXFGO1FBQ3JGLHlFQUF5RTtRQUN6RSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBRTVFLHFEQUFxRDtRQUNyRCxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixJQUFJLE9BQU8scUJBQXFCLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDOUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2xDLHFCQUFxQixDQUFDLEdBQUcsRUFBRTtvQkFDekIsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzt3QkFDMUIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQ3BELENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDcEQsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSyxvQkFBb0I7UUFDMUIsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakQsQ0FBQztJQUNILENBQUM7SUFFRCxrRUFBa0U7SUFDbEUsY0FBYztRQUNaLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBRS9DLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3RCLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUM3QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUN4QyxPQUFPO1FBQ1QsQ0FBQztRQUVELGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUVsRSxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtZQUNsQyxnQkFBaUIsQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUM7UUFDMUYsQ0FBQyxDQUFDLENBQUM7UUFFSCxtRkFBbUY7UUFDbkYsNkVBQTZFO1FBQzdFLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxhQUFhLEdBQUcsTUFBTSxDQUFDO1FBRTlDLHNGQUFzRjtRQUN0RiwyRkFBMkY7UUFDM0YsNkJBQTZCO1FBQzdCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxDQUMxRCxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDMUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUNSLENBQUM7SUFDSixDQUFDO0lBRUQsdUVBQXVFO0lBQy9ELGNBQWMsQ0FBQyxPQUFvQixFQUFFLFVBQTZCLEVBQUUsS0FBYztRQUN4RixNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUvRCxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNuQixLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFDbkYsQ0FBQztJQUNILENBQUM7SUFFRCxrRUFBa0U7SUFDMUQsdUJBQXVCO1FBQzdCLGlGQUFpRjtRQUNqRix1RkFBdUY7UUFDdkYsZ0ZBQWdGO1FBQ2hGLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO1lBQ2xDLGdGQUFnRjtZQUNoRixrRkFBa0Y7WUFDbEYsMkNBQTJDO1lBQzNDLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRO2lCQUMvQixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO2lCQUM1RCxTQUFTLENBQUMsR0FBRyxFQUFFO2dCQUNkLDBEQUEwRDtnQkFDMUQsOERBQThEO2dCQUM5RCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUNuRSxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQzt3QkFDMUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO29CQUNsRSxDQUFDO29CQUVELElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxDQUFDO3dCQUMzQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUM7d0JBQ3BELElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7b0JBQ3RCLENBQUM7b0JBRUQsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUM3QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxxQ0FBcUM7SUFDN0Isc0JBQXNCO1FBQzVCLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFFNUMsSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUNuQixjQUFjLENBQUMsT0FBTyxFQUFFLENBQUM7WUFFekIsSUFBSSxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQzFCLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUMxQixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCwrQ0FBK0M7SUFDdkMsZ0JBQWdCLENBQUMsUUFBNEI7UUFDbkQsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNiLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUM7WUFDbEUsUUFBUSxDQUFDLG1CQUFtQixDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsNkJBQTZCLENBQUMsQ0FBQztZQUNsRixRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7WUFFbEIsc0ZBQXNGO1lBQ3RGLHNGQUFzRjtZQUN0Rix3REFBd0Q7WUFDeEQsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ3ZDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7WUFDL0IsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzFCLFlBQVksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUNwQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsU0FBUyxDQUFDO1FBQ3BDLENBQUM7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtEaXJlY3Rpb24sIERpcmVjdGlvbmFsaXR5fSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XG5pbXBvcnQge0NvbXBvbmVudFBvcnRhbCwgUG9ydGFsLCBQb3J0YWxPdXRsZXQsIFRlbXBsYXRlUG9ydGFsfSBmcm9tICdAYW5ndWxhci9jZGsvcG9ydGFsJztcbmltcG9ydCB7XG4gIENvbXBvbmVudFJlZixcbiAgRW1iZWRkZWRWaWV3UmVmLFxuICBFbnZpcm9ubWVudEluamVjdG9yLFxuICBOZ1pvbmUsXG4gIGFmdGVyTmV4dFJlbmRlcixcbiAgYWZ0ZXJSZW5kZXIsXG4gIHVudHJhY2tlZCxcbiAgQWZ0ZXJSZW5kZXJSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtMb2NhdGlvbn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7T2JzZXJ2YWJsZSwgU3ViamVjdCwgbWVyZ2UsIFN1YnNjcmlwdGlvbkxpa2UsIFN1YnNjcmlwdGlvbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge3Rha2VVbnRpbH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtPdmVybGF5S2V5Ym9hcmREaXNwYXRjaGVyfSBmcm9tICcuL2Rpc3BhdGNoZXJzL292ZXJsYXkta2V5Ym9hcmQtZGlzcGF0Y2hlcic7XG5pbXBvcnQge092ZXJsYXlPdXRzaWRlQ2xpY2tEaXNwYXRjaGVyfSBmcm9tICcuL2Rpc3BhdGNoZXJzL292ZXJsYXktb3V0c2lkZS1jbGljay1kaXNwYXRjaGVyJztcbmltcG9ydCB7T3ZlcmxheUNvbmZpZ30gZnJvbSAnLi9vdmVybGF5LWNvbmZpZyc7XG5pbXBvcnQge2NvZXJjZUNzc1BpeGVsVmFsdWUsIGNvZXJjZUFycmF5fSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHtQb3NpdGlvblN0cmF0ZWd5fSBmcm9tICcuL3Bvc2l0aW9uL3Bvc2l0aW9uLXN0cmF0ZWd5JztcbmltcG9ydCB7U2Nyb2xsU3RyYXRlZ3l9IGZyb20gJy4vc2Nyb2xsJztcblxuLyoqIEFuIG9iamVjdCB3aGVyZSBhbGwgb2YgaXRzIHByb3BlcnRpZXMgY2Fubm90IGJlIHdyaXR0ZW4uICovXG5leHBvcnQgdHlwZSBJbW11dGFibGVPYmplY3Q8VD4gPSB7XG4gIHJlYWRvbmx5IFtQIGluIGtleW9mIFRdOiBUW1BdO1xufTtcblxuLyoqXG4gKiBSZWZlcmVuY2UgdG8gYW4gb3ZlcmxheSB0aGF0IGhhcyBiZWVuIGNyZWF0ZWQgd2l0aCB0aGUgT3ZlcmxheSBzZXJ2aWNlLlxuICogVXNlZCB0byBtYW5pcHVsYXRlIG9yIGRpc3Bvc2Ugb2Ygc2FpZCBvdmVybGF5LlxuICovXG5leHBvcnQgY2xhc3MgT3ZlcmxheVJlZiBpbXBsZW1lbnRzIFBvcnRhbE91dGxldCB7XG4gIHByaXZhdGUgX2JhY2tkcm9wRWxlbWVudDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfYmFja2Ryb3BUaW1lb3V0OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2JhY2tkcm9wQ2xpY2sgPSBuZXcgU3ViamVjdDxNb3VzZUV2ZW50PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9hdHRhY2htZW50cyA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RldGFjaG1lbnRzID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBfcG9zaXRpb25TdHJhdGVneTogUG9zaXRpb25TdHJhdGVneSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBfc2Nyb2xsU3RyYXRlZ3k6IFNjcm9sbFN0cmF0ZWd5IHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIF9sb2NhdGlvbkNoYW5nZXM6IFN1YnNjcmlwdGlvbkxpa2UgPSBTdWJzY3JpcHRpb24uRU1QVFk7XG4gIHByaXZhdGUgX2JhY2tkcm9wQ2xpY2tIYW5kbGVyID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB0aGlzLl9iYWNrZHJvcENsaWNrLm5leHQoZXZlbnQpO1xuICBwcml2YXRlIF9iYWNrZHJvcFRyYW5zaXRpb25lbmRIYW5kbGVyID0gKGV2ZW50OiBUcmFuc2l0aW9uRXZlbnQpID0+IHtcbiAgICB0aGlzLl9kaXNwb3NlQmFja2Ryb3AoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50IHwgbnVsbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlZmVyZW5jZSB0byB0aGUgcGFyZW50IG9mIHRoZSBgX2hvc3RgIGF0IHRoZSB0aW1lIGl0IHdhcyBkZXRhY2hlZC4gVXNlZCB0byByZXN0b3JlXG4gICAqIHRoZSBgX2hvc3RgIHRvIGl0cyBvcmlnaW5hbCBwb3NpdGlvbiBpbiB0aGUgRE9NIHdoZW4gaXQgZ2V0cyByZS1hdHRhY2hlZC5cbiAgICovXG4gIHByaXZhdGUgX3ByZXZpb3VzSG9zdFBhcmVudDogSFRNTEVsZW1lbnQ7XG5cbiAgLyoqIFN0cmVhbSBvZiBrZXlkb3duIGV2ZW50cyBkaXNwYXRjaGVkIHRvIHRoaXMgb3ZlcmxheS4gKi9cbiAgcmVhZG9ubHkgX2tleWRvd25FdmVudHMgPSBuZXcgU3ViamVjdDxLZXlib2FyZEV2ZW50PigpO1xuXG4gIC8qKiBTdHJlYW0gb2YgbW91c2Ugb3V0c2lkZSBldmVudHMgZGlzcGF0Y2hlZCB0byB0aGlzIG92ZXJsYXkuICovXG4gIHJlYWRvbmx5IF9vdXRzaWRlUG9pbnRlckV2ZW50cyA9IG5ldyBTdWJqZWN0PE1vdXNlRXZlbnQ+KCk7XG5cbiAgcHJpdmF0ZSBfcmVuZGVycyA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgcHJpdmF0ZSBfYWZ0ZXJSZW5kZXJSZWY6IEFmdGVyUmVuZGVyUmVmO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX3BvcnRhbE91dGxldDogUG9ydGFsT3V0bGV0LFxuICAgIHByaXZhdGUgX2hvc3Q6IEhUTUxFbGVtZW50LFxuICAgIHByaXZhdGUgX3BhbmU6IEhUTUxFbGVtZW50LFxuICAgIHByaXZhdGUgX2NvbmZpZzogSW1tdXRhYmxlT2JqZWN0PE92ZXJsYXlDb25maWc+LFxuICAgIHByaXZhdGUgX25nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgX2tleWJvYXJkRGlzcGF0Y2hlcjogT3ZlcmxheUtleWJvYXJkRGlzcGF0Y2hlcixcbiAgICBwcml2YXRlIF9kb2N1bWVudDogRG9jdW1lbnQsXG4gICAgcHJpdmF0ZSBfbG9jYXRpb246IExvY2F0aW9uLFxuICAgIHByaXZhdGUgX291dHNpZGVDbGlja0Rpc3BhdGNoZXI6IE92ZXJsYXlPdXRzaWRlQ2xpY2tEaXNwYXRjaGVyLFxuICAgIHByaXZhdGUgX2FuaW1hdGlvbnNEaXNhYmxlZCA9IGZhbHNlLFxuICAgIHByaXZhdGUgX2luamVjdG9yOiBFbnZpcm9ubWVudEluamVjdG9yLFxuICApIHtcbiAgICBpZiAoX2NvbmZpZy5zY3JvbGxTdHJhdGVneSkge1xuICAgICAgdGhpcy5fc2Nyb2xsU3RyYXRlZ3kgPSBfY29uZmlnLnNjcm9sbFN0cmF0ZWd5O1xuICAgICAgdGhpcy5fc2Nyb2xsU3RyYXRlZ3kuYXR0YWNoKHRoaXMpO1xuICAgIH1cblxuICAgIHRoaXMuX3Bvc2l0aW9uU3RyYXRlZ3kgPSBfY29uZmlnLnBvc2l0aW9uU3RyYXRlZ3k7XG5cbiAgICAvLyBVc2VycyBjb3VsZCBvcGVuIHRoZSBvdmVybGF5IGZyb20gYW4gYGVmZmVjdGAsIGluIHdoaWNoIGNhc2Ugd2UgbmVlZCB0b1xuICAgIC8vIHJ1biB0aGUgYGFmdGVyUmVuZGVyYCBhcyBgdW50cmFja2VkYC4gV2UgZG9uJ3QgcmVjb21tZW5kIHRoYXQgdXNlcnMgZG9cbiAgICAvLyB0aGlzLCBidXQgd2UgYWxzbyBkb24ndCB3YW50IHRvIGJyZWFrIHVzZXJzIHdobyBhcmUgZG9pbmcgaXQuXG4gICAgdGhpcy5fYWZ0ZXJSZW5kZXJSZWYgPSB1bnRyYWNrZWQoKCkgPT5cbiAgICAgIGFmdGVyUmVuZGVyKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5fcmVuZGVycy5uZXh0KCk7XG4gICAgICAgIH0sXG4gICAgICAgIHtpbmplY3RvcjogdGhpcy5faW5qZWN0b3J9LFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIFRoZSBvdmVybGF5J3MgSFRNTCBlbGVtZW50ICovXG4gIGdldCBvdmVybGF5RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgcmV0dXJuIHRoaXMuX3BhbmU7XG4gIH1cblxuICAvKiogVGhlIG92ZXJsYXkncyBiYWNrZHJvcCBIVE1MIGVsZW1lbnQuICovXG4gIGdldCBiYWNrZHJvcEVsZW1lbnQoKTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fYmFja2Ryb3BFbGVtZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIFdyYXBwZXIgYXJvdW5kIHRoZSBwYW5lbCBlbGVtZW50LiBDYW4gYmUgdXNlZCBmb3IgYWR2YW5jZWRcbiAgICogcG9zaXRpb25pbmcgd2hlcmUgYSB3cmFwcGVyIHdpdGggc3BlY2lmaWMgc3R5bGluZyBpc1xuICAgKiByZXF1aXJlZCBhcm91bmQgdGhlIG92ZXJsYXkgcGFuZS5cbiAgICovXG4gIGdldCBob3N0RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgcmV0dXJuIHRoaXMuX2hvc3Q7XG4gIH1cblxuICBhdHRhY2g8VD4ocG9ydGFsOiBDb21wb25lbnRQb3J0YWw8VD4pOiBDb21wb25lbnRSZWY8VD47XG4gIGF0dGFjaDxUPihwb3J0YWw6IFRlbXBsYXRlUG9ydGFsPFQ+KTogRW1iZWRkZWRWaWV3UmVmPFQ+O1xuICBhdHRhY2gocG9ydGFsOiBhbnkpOiBhbnk7XG5cbiAgLyoqXG4gICAqIEF0dGFjaGVzIGNvbnRlbnQsIGdpdmVuIHZpYSBhIFBvcnRhbCwgdG8gdGhlIG92ZXJsYXkuXG4gICAqIElmIHRoZSBvdmVybGF5IGlzIGNvbmZpZ3VyZWQgdG8gaGF2ZSBhIGJhY2tkcm9wLCBpdCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAqXG4gICAqIEBwYXJhbSBwb3J0YWwgUG9ydGFsIGluc3RhbmNlIHRvIHdoaWNoIHRvIGF0dGFjaCB0aGUgb3ZlcmxheS5cbiAgICogQHJldHVybnMgVGhlIHBvcnRhbCBhdHRhY2htZW50IHJlc3VsdC5cbiAgICovXG4gIGF0dGFjaChwb3J0YWw6IFBvcnRhbDxhbnk+KTogYW55IHtcbiAgICAvLyBJbnNlcnQgdGhlIGhvc3QgaW50byB0aGUgRE9NIGJlZm9yZSBhdHRhY2hpbmcgdGhlIHBvcnRhbCwgb3RoZXJ3aXNlXG4gICAgLy8gdGhlIGFuaW1hdGlvbnMgbW9kdWxlIHdpbGwgc2tpcCBhbmltYXRpb25zIG9uIHJlcGVhdCBhdHRhY2htZW50cy5cbiAgICBpZiAoIXRoaXMuX2hvc3QucGFyZW50RWxlbWVudCAmJiB0aGlzLl9wcmV2aW91c0hvc3RQYXJlbnQpIHtcbiAgICAgIHRoaXMuX3ByZXZpb3VzSG9zdFBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLl9ob3N0KTtcbiAgICB9XG5cbiAgICBjb25zdCBhdHRhY2hSZXN1bHQgPSB0aGlzLl9wb3J0YWxPdXRsZXQuYXR0YWNoKHBvcnRhbCk7XG5cbiAgICBpZiAodGhpcy5fcG9zaXRpb25TdHJhdGVneSkge1xuICAgICAgdGhpcy5fcG9zaXRpb25TdHJhdGVneS5hdHRhY2godGhpcyk7XG4gICAgfVxuXG4gICAgdGhpcy5fdXBkYXRlU3RhY2tpbmdPcmRlcigpO1xuICAgIHRoaXMuX3VwZGF0ZUVsZW1lbnRTaXplKCk7XG4gICAgdGhpcy5fdXBkYXRlRWxlbWVudERpcmVjdGlvbigpO1xuXG4gICAgaWYgKHRoaXMuX3Njcm9sbFN0cmF0ZWd5KSB7XG4gICAgICB0aGlzLl9zY3JvbGxTdHJhdGVneS5lbmFibGUoKTtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgdGhlIHBvc2l0aW9uIG9uY2UgdGhlIG92ZXJsYXkgaXMgZnVsbHkgcmVuZGVyZWQgYmVmb3JlIGF0dGVtcHRpbmcgdG8gcG9zaXRpb24gaXQsXG4gICAgLy8gYXMgdGhlIHBvc2l0aW9uIG1heSBkZXBlbmQgb24gdGhlIHNpemUgb2YgdGhlIHJlbmRlcmVkIGNvbnRlbnQuXG4gICAgYWZ0ZXJOZXh0UmVuZGVyKFxuICAgICAgKCkgPT4ge1xuICAgICAgICAvLyBUaGUgb3ZlcmxheSBjb3VsZCd2ZSBiZWVuIGRldGFjaGVkIGJlZm9yZSB0aGUgY2FsbGJhY2sgZXhlY3V0ZWQuXG4gICAgICAgIGlmICh0aGlzLmhhc0F0dGFjaGVkKCkpIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVBvc2l0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB7aW5qZWN0b3I6IHRoaXMuX2luamVjdG9yfSxcbiAgICApO1xuXG4gICAgLy8gRW5hYmxlIHBvaW50ZXIgZXZlbnRzIGZvciB0aGUgb3ZlcmxheSBwYW5lIGVsZW1lbnQuXG4gICAgdGhpcy5fdG9nZ2xlUG9pbnRlckV2ZW50cyh0cnVlKTtcblxuICAgIGlmICh0aGlzLl9jb25maWcuaGFzQmFja2Ryb3ApIHtcbiAgICAgIHRoaXMuX2F0dGFjaEJhY2tkcm9wKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2NvbmZpZy5wYW5lbENsYXNzKSB7XG4gICAgICB0aGlzLl90b2dnbGVDbGFzc2VzKHRoaXMuX3BhbmUsIHRoaXMuX2NvbmZpZy5wYW5lbENsYXNzLCB0cnVlKTtcbiAgICB9XG5cbiAgICAvLyBPbmx5IGVtaXQgdGhlIGBhdHRhY2htZW50c2AgZXZlbnQgb25jZSBhbGwgb3RoZXIgc2V0dXAgaXMgZG9uZS5cbiAgICB0aGlzLl9hdHRhY2htZW50cy5uZXh0KCk7XG5cbiAgICAvLyBUcmFjayB0aGlzIG92ZXJsYXkgYnkgdGhlIGtleWJvYXJkIGRpc3BhdGNoZXJcbiAgICB0aGlzLl9rZXlib2FyZERpc3BhdGNoZXIuYWRkKHRoaXMpO1xuXG4gICAgaWYgKHRoaXMuX2NvbmZpZy5kaXNwb3NlT25OYXZpZ2F0aW9uKSB7XG4gICAgICB0aGlzLl9sb2NhdGlvbkNoYW5nZXMgPSB0aGlzLl9sb2NhdGlvbi5zdWJzY3JpYmUoKCkgPT4gdGhpcy5kaXNwb3NlKCkpO1xuICAgIH1cblxuICAgIHRoaXMuX291dHNpZGVDbGlja0Rpc3BhdGNoZXIuYWRkKHRoaXMpO1xuXG4gICAgLy8gVE9ETyhjcmlzYmV0byk6IHRoZSBudWxsIGNoZWNrIGlzIGhlcmUsIGJlY2F1c2UgdGhlIHBvcnRhbCBvdXRsZXQgcmV0dXJucyBgYW55YC5cbiAgICAvLyBXZSBzaG91bGQgYmUgZ3VhcmFudGVlZCBmb3IgdGhlIHJlc3VsdCB0byBiZSBgQ29tcG9uZW50UmVmIHwgRW1iZWRkZWRWaWV3UmVmYCwgYnV0XG4gICAgLy8gYGluc3RhbmNlb2YgRW1iZWRkZWRWaWV3UmVmYCBkb2Vzbid0IGFwcGVhciB0byB3b3JrIGF0IHRoZSBtb21lbnQuXG4gICAgaWYgKHR5cGVvZiBhdHRhY2hSZXN1bHQ/Lm9uRGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gSW4gbW9zdCBjYXNlcyB3ZSBjb250cm9sIHRoZSBwb3J0YWwgYW5kIHdlIGtub3cgd2hlbiBpdCBpcyBiZWluZyBkZXRhY2hlZCBzbyB0aGF0XG4gICAgICAvLyB3ZSBjYW4gZmluaXNoIHRoZSBkaXNwb3NhbCBwcm9jZXNzLiBUaGUgZXhjZXB0aW9uIGlzIGlmIHRoZSB1c2VyIHBhc3NlcyBpbiBhIGN1c3RvbVxuICAgICAgLy8gYFZpZXdDb250YWluZXJSZWZgIHRoYXQgaXNuJ3QgZGVzdHJveWVkIHRocm91Z2ggdGhlIG92ZXJsYXkgQVBJLiBOb3RlIHRoYXQgd2UgdXNlXG4gICAgICAvLyBgZGV0YWNoYCBoZXJlIGluc3RlYWQgb2YgYGRpc3Bvc2VgLCBiZWNhdXNlIHdlIGRvbid0IGtub3cgaWYgdGhlIHVzZXIgaW50ZW5kcyB0b1xuICAgICAgLy8gcmVhdHRhY2ggdGhlIG92ZXJsYXkgYXQgYSBsYXRlciBwb2ludC4gSXQgYWxzbyBoYXMgdGhlIGFkdmFudGFnZSBvZiB3YWl0aW5nIGZvciBhbmltYXRpb25zLlxuICAgICAgYXR0YWNoUmVzdWx0Lm9uRGVzdHJveSgoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLmhhc0F0dGFjaGVkKCkpIHtcbiAgICAgICAgICAvLyBXZSBoYXZlIHRvIGRlbGF5IHRoZSBgZGV0YWNoYCBjYWxsLCBiZWNhdXNlIGRldGFjaGluZyBpbW1lZGlhdGVseSBwcmV2ZW50c1xuICAgICAgICAgIC8vIG90aGVyIGRlc3Ryb3kgaG9va3MgZnJvbSBydW5uaW5nLiBUaGlzIGlzIGxpa2VseSBhIGZyYW1ld29yayBidWcgc2ltaWxhciB0b1xuICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIvaXNzdWVzLzQ2MTE5XG4gICAgICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4gdGhpcy5kZXRhY2goKSkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXR0YWNoUmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIERldGFjaGVzIGFuIG92ZXJsYXkgZnJvbSBhIHBvcnRhbC5cbiAgICogQHJldHVybnMgVGhlIHBvcnRhbCBkZXRhY2htZW50IHJlc3VsdC5cbiAgICovXG4gIGRldGFjaCgpOiBhbnkge1xuICAgIGlmICghdGhpcy5oYXNBdHRhY2hlZCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5kZXRhY2hCYWNrZHJvcCgpO1xuXG4gICAgLy8gV2hlbiB0aGUgb3ZlcmxheSBpcyBkZXRhY2hlZCwgdGhlIHBhbmUgZWxlbWVudCBzaG91bGQgZGlzYWJsZSBwb2ludGVyIGV2ZW50cy5cbiAgICAvLyBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIG90aGVyd2lzZSB0aGUgcGFuZSBlbGVtZW50IHdpbGwgY292ZXIgdGhlIHBhZ2UgYW5kIGRpc2FibGVcbiAgICAvLyBwb2ludGVyIGV2ZW50cyB0aGVyZWZvcmUuIERlcGVuZHMgb24gdGhlIHBvc2l0aW9uIHN0cmF0ZWd5IGFuZCB0aGUgYXBwbGllZCBwYW5lIGJvdW5kYXJpZXMuXG4gICAgdGhpcy5fdG9nZ2xlUG9pbnRlckV2ZW50cyhmYWxzZSk7XG5cbiAgICBpZiAodGhpcy5fcG9zaXRpb25TdHJhdGVneSAmJiB0aGlzLl9wb3NpdGlvblN0cmF0ZWd5LmRldGFjaCkge1xuICAgICAgdGhpcy5fcG9zaXRpb25TdHJhdGVneS5kZXRhY2goKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fc2Nyb2xsU3RyYXRlZ3kpIHtcbiAgICAgIHRoaXMuX3Njcm9sbFN0cmF0ZWd5LmRpc2FibGUoKTtcbiAgICB9XG5cbiAgICBjb25zdCBkZXRhY2htZW50UmVzdWx0ID0gdGhpcy5fcG9ydGFsT3V0bGV0LmRldGFjaCgpO1xuXG4gICAgLy8gT25seSBlbWl0IGFmdGVyIGV2ZXJ5dGhpbmcgaXMgZGV0YWNoZWQuXG4gICAgdGhpcy5fZGV0YWNobWVudHMubmV4dCgpO1xuXG4gICAgLy8gUmVtb3ZlIHRoaXMgb3ZlcmxheSBmcm9tIGtleWJvYXJkIGRpc3BhdGNoZXIgdHJhY2tpbmcuXG4gICAgdGhpcy5fa2V5Ym9hcmREaXNwYXRjaGVyLnJlbW92ZSh0aGlzKTtcblxuICAgIC8vIEtlZXBpbmcgdGhlIGhvc3QgZWxlbWVudCBpbiB0aGUgRE9NIGNhbiBjYXVzZSBzY3JvbGwgamFuaywgYmVjYXVzZSBpdCBzdGlsbCBnZXRzXG4gICAgLy8gcmVuZGVyZWQsIGV2ZW4gdGhvdWdoIGl0J3MgdHJhbnNwYXJlbnQgYW5kIHVuY2xpY2thYmxlIHdoaWNoIGlzIHdoeSB3ZSByZW1vdmUgaXQuXG4gICAgdGhpcy5fZGV0YWNoQ29udGVudFdoZW5FbXB0eSgpO1xuICAgIHRoaXMuX2xvY2F0aW9uQ2hhbmdlcy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuX291dHNpZGVDbGlja0Rpc3BhdGNoZXIucmVtb3ZlKHRoaXMpO1xuICAgIHJldHVybiBkZXRhY2htZW50UmVzdWx0O1xuICB9XG5cbiAgLyoqIENsZWFucyB1cCB0aGUgb3ZlcmxheSBmcm9tIHRoZSBET00uICovXG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgY29uc3QgaXNBdHRhY2hlZCA9IHRoaXMuaGFzQXR0YWNoZWQoKTtcblxuICAgIGlmICh0aGlzLl9wb3NpdGlvblN0cmF0ZWd5KSB7XG4gICAgICB0aGlzLl9wb3NpdGlvblN0cmF0ZWd5LmRpc3Bvc2UoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kaXNwb3NlU2Nyb2xsU3RyYXRlZ3koKTtcbiAgICB0aGlzLl9kaXNwb3NlQmFja2Ryb3AodGhpcy5fYmFja2Ryb3BFbGVtZW50KTtcbiAgICB0aGlzLl9sb2NhdGlvbkNoYW5nZXMudW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLl9rZXlib2FyZERpc3BhdGNoZXIucmVtb3ZlKHRoaXMpO1xuICAgIHRoaXMuX3BvcnRhbE91dGxldC5kaXNwb3NlKCk7XG4gICAgdGhpcy5fYXR0YWNobWVudHMuY29tcGxldGUoKTtcbiAgICB0aGlzLl9iYWNrZHJvcENsaWNrLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5fa2V5ZG93bkV2ZW50cy5jb21wbGV0ZSgpO1xuICAgIHRoaXMuX291dHNpZGVQb2ludGVyRXZlbnRzLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5fb3V0c2lkZUNsaWNrRGlzcGF0Y2hlci5yZW1vdmUodGhpcyk7XG4gICAgdGhpcy5faG9zdD8ucmVtb3ZlKCk7XG5cbiAgICB0aGlzLl9wcmV2aW91c0hvc3RQYXJlbnQgPSB0aGlzLl9wYW5lID0gdGhpcy5faG9zdCA9IG51bGwhO1xuXG4gICAgaWYgKGlzQXR0YWNoZWQpIHtcbiAgICAgIHRoaXMuX2RldGFjaG1lbnRzLm5leHQoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kZXRhY2htZW50cy5jb21wbGV0ZSgpO1xuICAgIHRoaXMuX2FmdGVyUmVuZGVyUmVmLmRlc3Ryb3koKTtcbiAgICB0aGlzLl9yZW5kZXJzLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvKiogV2hldGhlciB0aGUgb3ZlcmxheSBoYXMgYXR0YWNoZWQgY29udGVudC4gKi9cbiAgaGFzQXR0YWNoZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3BvcnRhbE91dGxldC5oYXNBdHRhY2hlZCgpO1xuICB9XG5cbiAgLyoqIEdldHMgYW4gb2JzZXJ2YWJsZSB0aGF0IGVtaXRzIHdoZW4gdGhlIGJhY2tkcm9wIGhhcyBiZWVuIGNsaWNrZWQuICovXG4gIGJhY2tkcm9wQ2xpY2soKTogT2JzZXJ2YWJsZTxNb3VzZUV2ZW50PiB7XG4gICAgcmV0dXJuIHRoaXMuX2JhY2tkcm9wQ2xpY2s7XG4gIH1cblxuICAvKiogR2V0cyBhbiBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgd2hlbiB0aGUgb3ZlcmxheSBoYXMgYmVlbiBhdHRhY2hlZC4gKi9cbiAgYXR0YWNobWVudHMoKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuX2F0dGFjaG1lbnRzO1xuICB9XG5cbiAgLyoqIEdldHMgYW4gb2JzZXJ2YWJsZSB0aGF0IGVtaXRzIHdoZW4gdGhlIG92ZXJsYXkgaGFzIGJlZW4gZGV0YWNoZWQuICovXG4gIGRldGFjaG1lbnRzKCk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLl9kZXRhY2htZW50cztcbiAgfVxuXG4gIC8qKiBHZXRzIGFuIG9ic2VydmFibGUgb2Yga2V5ZG93biBldmVudHMgdGFyZ2V0ZWQgdG8gdGhpcyBvdmVybGF5LiAqL1xuICBrZXlkb3duRXZlbnRzKCk6IE9ic2VydmFibGU8S2V5Ym9hcmRFdmVudD4ge1xuICAgIHJldHVybiB0aGlzLl9rZXlkb3duRXZlbnRzO1xuICB9XG5cbiAgLyoqIEdldHMgYW4gb2JzZXJ2YWJsZSBvZiBwb2ludGVyIGV2ZW50cyB0YXJnZXRlZCBvdXRzaWRlIHRoaXMgb3ZlcmxheS4gKi9cbiAgb3V0c2lkZVBvaW50ZXJFdmVudHMoKTogT2JzZXJ2YWJsZTxNb3VzZUV2ZW50PiB7XG4gICAgcmV0dXJuIHRoaXMuX291dHNpZGVQb2ludGVyRXZlbnRzO1xuICB9XG5cbiAgLyoqIEdldHMgdGhlIGN1cnJlbnQgb3ZlcmxheSBjb25maWd1cmF0aW9uLCB3aGljaCBpcyBpbW11dGFibGUuICovXG4gIGdldENvbmZpZygpOiBPdmVybGF5Q29uZmlnIHtcbiAgICByZXR1cm4gdGhpcy5fY29uZmlnO1xuICB9XG5cbiAgLyoqIFVwZGF0ZXMgdGhlIHBvc2l0aW9uIG9mIHRoZSBvdmVybGF5IGJhc2VkIG9uIHRoZSBwb3NpdGlvbiBzdHJhdGVneS4gKi9cbiAgdXBkYXRlUG9zaXRpb24oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX3Bvc2l0aW9uU3RyYXRlZ3kpIHtcbiAgICAgIHRoaXMuX3Bvc2l0aW9uU3RyYXRlZ3kuYXBwbHkoKTtcbiAgICB9XG4gIH1cblxuICAvKiogU3dpdGNoZXMgdG8gYSBuZXcgcG9zaXRpb24gc3RyYXRlZ3kgYW5kIHVwZGF0ZXMgdGhlIG92ZXJsYXkgcG9zaXRpb24uICovXG4gIHVwZGF0ZVBvc2l0aW9uU3RyYXRlZ3koc3RyYXRlZ3k6IFBvc2l0aW9uU3RyYXRlZ3kpOiB2b2lkIHtcbiAgICBpZiAoc3RyYXRlZ3kgPT09IHRoaXMuX3Bvc2l0aW9uU3RyYXRlZ3kpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcG9zaXRpb25TdHJhdGVneSkge1xuICAgICAgdGhpcy5fcG9zaXRpb25TdHJhdGVneS5kaXNwb3NlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5fcG9zaXRpb25TdHJhdGVneSA9IHN0cmF0ZWd5O1xuXG4gICAgaWYgKHRoaXMuaGFzQXR0YWNoZWQoKSkge1xuICAgICAgc3RyYXRlZ3kuYXR0YWNoKHRoaXMpO1xuICAgICAgdGhpcy51cGRhdGVQb3NpdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBVcGRhdGUgdGhlIHNpemUgcHJvcGVydGllcyBvZiB0aGUgb3ZlcmxheS4gKi9cbiAgdXBkYXRlU2l6ZShzaXplQ29uZmlnOiBPdmVybGF5U2l6ZUNvbmZpZyk6IHZvaWQge1xuICAgIHRoaXMuX2NvbmZpZyA9IHsuLi50aGlzLl9jb25maWcsIC4uLnNpemVDb25maWd9O1xuICAgIHRoaXMuX3VwZGF0ZUVsZW1lbnRTaXplKCk7XG4gIH1cblxuICAvKiogU2V0cyB0aGUgTFRSL1JUTCBkaXJlY3Rpb24gZm9yIHRoZSBvdmVybGF5LiAqL1xuICBzZXREaXJlY3Rpb24oZGlyOiBEaXJlY3Rpb24gfCBEaXJlY3Rpb25hbGl0eSk6IHZvaWQge1xuICAgIHRoaXMuX2NvbmZpZyA9IHsuLi50aGlzLl9jb25maWcsIGRpcmVjdGlvbjogZGlyfTtcbiAgICB0aGlzLl91cGRhdGVFbGVtZW50RGlyZWN0aW9uKCk7XG4gIH1cblxuICAvKiogQWRkIGEgQ1NTIGNsYXNzIG9yIGFuIGFycmF5IG9mIGNsYXNzZXMgdG8gdGhlIG92ZXJsYXkgcGFuZS4gKi9cbiAgYWRkUGFuZWxDbGFzcyhjbGFzc2VzOiBzdHJpbmcgfCBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9wYW5lKSB7XG4gICAgICB0aGlzLl90b2dnbGVDbGFzc2VzKHRoaXMuX3BhbmUsIGNsYXNzZXMsIHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBSZW1vdmUgYSBDU1MgY2xhc3Mgb3IgYW4gYXJyYXkgb2YgY2xhc3NlcyBmcm9tIHRoZSBvdmVybGF5IHBhbmUuICovXG4gIHJlbW92ZVBhbmVsQ2xhc3MoY2xhc3Nlczogc3RyaW5nIHwgc3RyaW5nW10pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fcGFuZSkge1xuICAgICAgdGhpcy5fdG9nZ2xlQ2xhc3Nlcyh0aGlzLl9wYW5lLCBjbGFzc2VzLCBmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGxheW91dCBkaXJlY3Rpb24gb2YgdGhlIG92ZXJsYXkgcGFuZWwuXG4gICAqL1xuICBnZXREaXJlY3Rpb24oKTogRGlyZWN0aW9uIHtcbiAgICBjb25zdCBkaXJlY3Rpb24gPSB0aGlzLl9jb25maWcuZGlyZWN0aW9uO1xuXG4gICAgaWYgKCFkaXJlY3Rpb24pIHtcbiAgICAgIHJldHVybiAnbHRyJztcbiAgICB9XG5cbiAgICByZXR1cm4gdHlwZW9mIGRpcmVjdGlvbiA9PT0gJ3N0cmluZycgPyBkaXJlY3Rpb24gOiBkaXJlY3Rpb24udmFsdWU7XG4gIH1cblxuICAvKiogU3dpdGNoZXMgdG8gYSBuZXcgc2Nyb2xsIHN0cmF0ZWd5LiAqL1xuICB1cGRhdGVTY3JvbGxTdHJhdGVneShzdHJhdGVneTogU2Nyb2xsU3RyYXRlZ3kpOiB2b2lkIHtcbiAgICBpZiAoc3RyYXRlZ3kgPT09IHRoaXMuX3Njcm9sbFN0cmF0ZWd5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fZGlzcG9zZVNjcm9sbFN0cmF0ZWd5KCk7XG4gICAgdGhpcy5fc2Nyb2xsU3RyYXRlZ3kgPSBzdHJhdGVneTtcblxuICAgIGlmICh0aGlzLmhhc0F0dGFjaGVkKCkpIHtcbiAgICAgIHN0cmF0ZWd5LmF0dGFjaCh0aGlzKTtcbiAgICAgIHN0cmF0ZWd5LmVuYWJsZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBVcGRhdGVzIHRoZSB0ZXh0IGRpcmVjdGlvbiBvZiB0aGUgb3ZlcmxheSBwYW5lbC4gKi9cbiAgcHJpdmF0ZSBfdXBkYXRlRWxlbWVudERpcmVjdGlvbigpIHtcbiAgICB0aGlzLl9ob3N0LnNldEF0dHJpYnV0ZSgnZGlyJywgdGhpcy5nZXREaXJlY3Rpb24oKSk7XG4gIH1cblxuICAvKiogVXBkYXRlcyB0aGUgc2l6ZSBvZiB0aGUgb3ZlcmxheSBlbGVtZW50IGJhc2VkIG9uIHRoZSBvdmVybGF5IGNvbmZpZy4gKi9cbiAgcHJpdmF0ZSBfdXBkYXRlRWxlbWVudFNpemUoKSB7XG4gICAgaWYgKCF0aGlzLl9wYW5lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc3R5bGUgPSB0aGlzLl9wYW5lLnN0eWxlO1xuXG4gICAgc3R5bGUud2lkdGggPSBjb2VyY2VDc3NQaXhlbFZhbHVlKHRoaXMuX2NvbmZpZy53aWR0aCk7XG4gICAgc3R5bGUuaGVpZ2h0ID0gY29lcmNlQ3NzUGl4ZWxWYWx1ZSh0aGlzLl9jb25maWcuaGVpZ2h0KTtcbiAgICBzdHlsZS5taW5XaWR0aCA9IGNvZXJjZUNzc1BpeGVsVmFsdWUodGhpcy5fY29uZmlnLm1pbldpZHRoKTtcbiAgICBzdHlsZS5taW5IZWlnaHQgPSBjb2VyY2VDc3NQaXhlbFZhbHVlKHRoaXMuX2NvbmZpZy5taW5IZWlnaHQpO1xuICAgIHN0eWxlLm1heFdpZHRoID0gY29lcmNlQ3NzUGl4ZWxWYWx1ZSh0aGlzLl9jb25maWcubWF4V2lkdGgpO1xuICAgIHN0eWxlLm1heEhlaWdodCA9IGNvZXJjZUNzc1BpeGVsVmFsdWUodGhpcy5fY29uZmlnLm1heEhlaWdodCk7XG4gIH1cblxuICAvKiogVG9nZ2xlcyB0aGUgcG9pbnRlciBldmVudHMgZm9yIHRoZSBvdmVybGF5IHBhbmUgZWxlbWVudC4gKi9cbiAgcHJpdmF0ZSBfdG9nZ2xlUG9pbnRlckV2ZW50cyhlbmFibGVQb2ludGVyOiBib29sZWFuKSB7XG4gICAgdGhpcy5fcGFuZS5zdHlsZS5wb2ludGVyRXZlbnRzID0gZW5hYmxlUG9pbnRlciA/ICcnIDogJ25vbmUnO1xuICB9XG5cbiAgLyoqIEF0dGFjaGVzIGEgYmFja2Ryb3AgZm9yIHRoaXMgb3ZlcmxheS4gKi9cbiAgcHJpdmF0ZSBfYXR0YWNoQmFja2Ryb3AoKSB7XG4gICAgY29uc3Qgc2hvd2luZ0NsYXNzID0gJ2Nkay1vdmVybGF5LWJhY2tkcm9wLXNob3dpbmcnO1xuXG4gICAgdGhpcy5fYmFja2Ryb3BFbGVtZW50ID0gdGhpcy5fZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5fYmFja2Ryb3BFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2Nkay1vdmVybGF5LWJhY2tkcm9wJyk7XG5cbiAgICBpZiAodGhpcy5fYW5pbWF0aW9uc0Rpc2FibGVkKSB7XG4gICAgICB0aGlzLl9iYWNrZHJvcEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnY2RrLW92ZXJsYXktYmFja2Ryb3Atbm9vcC1hbmltYXRpb24nKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fY29uZmlnLmJhY2tkcm9wQ2xhc3MpIHtcbiAgICAgIHRoaXMuX3RvZ2dsZUNsYXNzZXModGhpcy5fYmFja2Ryb3BFbGVtZW50LCB0aGlzLl9jb25maWcuYmFja2Ryb3BDbGFzcywgdHJ1ZSk7XG4gICAgfVxuXG4gICAgLy8gSW5zZXJ0IHRoZSBiYWNrZHJvcCBiZWZvcmUgdGhlIHBhbmUgaW4gdGhlIERPTSBvcmRlcixcbiAgICAvLyBpbiBvcmRlciB0byBoYW5kbGUgc3RhY2tlZCBvdmVybGF5cyBwcm9wZXJseS5cbiAgICB0aGlzLl9ob3N0LnBhcmVudEVsZW1lbnQhLmluc2VydEJlZm9yZSh0aGlzLl9iYWNrZHJvcEVsZW1lbnQsIHRoaXMuX2hvc3QpO1xuXG4gICAgLy8gRm9yd2FyZCBiYWNrZHJvcCBjbGlja3Mgc3VjaCB0aGF0IHRoZSBjb25zdW1lciBvZiB0aGUgb3ZlcmxheSBjYW4gcGVyZm9ybSB3aGF0ZXZlclxuICAgIC8vIGFjdGlvbiBkZXNpcmVkIHdoZW4gc3VjaCBhIGNsaWNrIG9jY3VycyAodXN1YWxseSBjbG9zaW5nIHRoZSBvdmVybGF5KS5cbiAgICB0aGlzLl9iYWNrZHJvcEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9iYWNrZHJvcENsaWNrSGFuZGxlcik7XG5cbiAgICAvLyBBZGQgY2xhc3MgdG8gZmFkZS1pbiB0aGUgYmFja2Ryb3AgYWZ0ZXIgb25lIGZyYW1lLlxuICAgIGlmICghdGhpcy5fYW5pbWF0aW9uc0Rpc2FibGVkICYmIHR5cGVvZiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLl9iYWNrZHJvcEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2JhY2tkcm9wRWxlbWVudC5jbGFzc0xpc3QuYWRkKHNob3dpbmdDbGFzcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9iYWNrZHJvcEVsZW1lbnQuY2xhc3NMaXN0LmFkZChzaG93aW5nQ2xhc3MpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBzdGFja2luZyBvcmRlciBvZiB0aGUgZWxlbWVudCwgbW92aW5nIGl0IHRvIHRoZSB0b3AgaWYgbmVjZXNzYXJ5LlxuICAgKiBUaGlzIGlzIHJlcXVpcmVkIGluIGNhc2VzIHdoZXJlIG9uZSBvdmVybGF5IHdhcyBkZXRhY2hlZCwgd2hpbGUgYW5vdGhlciBvbmUsXG4gICAqIHRoYXQgc2hvdWxkIGJlIGJlaGluZCBpdCwgd2FzIGRlc3Ryb3llZC4gVGhlIG5leHQgdGltZSBib3RoIG9mIHRoZW0gYXJlIG9wZW5lZCxcbiAgICogdGhlIHN0YWNraW5nIHdpbGwgYmUgd3JvbmcsIGJlY2F1c2UgdGhlIGRldGFjaGVkIGVsZW1lbnQncyBwYW5lIHdpbGwgc3RpbGwgYmVcbiAgICogaW4gaXRzIG9yaWdpbmFsIERPTSBwb3NpdGlvbi5cbiAgICovXG4gIHByaXZhdGUgX3VwZGF0ZVN0YWNraW5nT3JkZXIoKSB7XG4gICAgaWYgKHRoaXMuX2hvc3QubmV4dFNpYmxpbmcpIHtcbiAgICAgIHRoaXMuX2hvc3QucGFyZW50Tm9kZSEuYXBwZW5kQ2hpbGQodGhpcy5faG9zdCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIERldGFjaGVzIHRoZSBiYWNrZHJvcCAoaWYgYW55KSBhc3NvY2lhdGVkIHdpdGggdGhlIG92ZXJsYXkuICovXG4gIGRldGFjaEJhY2tkcm9wKCk6IHZvaWQge1xuICAgIGNvbnN0IGJhY2tkcm9wVG9EZXRhY2ggPSB0aGlzLl9iYWNrZHJvcEVsZW1lbnQ7XG5cbiAgICBpZiAoIWJhY2tkcm9wVG9EZXRhY2gpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fYW5pbWF0aW9uc0Rpc2FibGVkKSB7XG4gICAgICB0aGlzLl9kaXNwb3NlQmFja2Ryb3AoYmFja2Ryb3BUb0RldGFjaCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYmFja2Ryb3BUb0RldGFjaC5jbGFzc0xpc3QucmVtb3ZlKCdjZGstb3ZlcmxheS1iYWNrZHJvcC1zaG93aW5nJyk7XG5cbiAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgYmFja2Ryb3BUb0RldGFjaCEuYWRkRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIHRoaXMuX2JhY2tkcm9wVHJhbnNpdGlvbmVuZEhhbmRsZXIpO1xuICAgIH0pO1xuXG4gICAgLy8gSWYgdGhlIGJhY2tkcm9wIGRvZXNuJ3QgaGF2ZSBhIHRyYW5zaXRpb24sIHRoZSBgdHJhbnNpdGlvbmVuZGAgZXZlbnQgd29uJ3QgZmlyZS5cbiAgICAvLyBJbiB0aGlzIGNhc2Ugd2UgbWFrZSBpdCB1bmNsaWNrYWJsZSBhbmQgd2UgdHJ5IHRvIHJlbW92ZSBpdCBhZnRlciBhIGRlbGF5LlxuICAgIGJhY2tkcm9wVG9EZXRhY2guc3R5bGUucG9pbnRlckV2ZW50cyA9ICdub25lJztcblxuICAgIC8vIFJ1biB0aGlzIG91dHNpZGUgdGhlIEFuZ3VsYXIgem9uZSBiZWNhdXNlIHRoZXJlJ3Mgbm90aGluZyB0aGF0IEFuZ3VsYXIgY2FyZXMgYWJvdXQuXG4gICAgLy8gSWYgaXQgd2VyZSB0byBydW4gaW5zaWRlIHRoZSBBbmd1bGFyIHpvbmUsIGV2ZXJ5IHRlc3QgdGhhdCB1c2VkIE92ZXJsYXkgd291bGQgaGF2ZSB0byBiZVxuICAgIC8vIGVpdGhlciBhc3luYyBvciBmYWtlQXN5bmMuXG4gICAgdGhpcy5fYmFja2Ryb3BUaW1lb3V0ID0gdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5fZGlzcG9zZUJhY2tkcm9wKGJhY2tkcm9wVG9EZXRhY2gpO1xuICAgICAgfSwgNTAwKSxcbiAgICApO1xuICB9XG5cbiAgLyoqIFRvZ2dsZXMgYSBzaW5nbGUgQ1NTIGNsYXNzIG9yIGFuIGFycmF5IG9mIGNsYXNzZXMgb24gYW4gZWxlbWVudC4gKi9cbiAgcHJpdmF0ZSBfdG9nZ2xlQ2xhc3NlcyhlbGVtZW50OiBIVE1MRWxlbWVudCwgY3NzQ2xhc3Nlczogc3RyaW5nIHwgc3RyaW5nW10sIGlzQWRkOiBib29sZWFuKSB7XG4gICAgY29uc3QgY2xhc3NlcyA9IGNvZXJjZUFycmF5KGNzc0NsYXNzZXMgfHwgW10pLmZpbHRlcihjID0+ICEhYyk7XG5cbiAgICBpZiAoY2xhc3Nlcy5sZW5ndGgpIHtcbiAgICAgIGlzQWRkID8gZWxlbWVudC5jbGFzc0xpc3QuYWRkKC4uLmNsYXNzZXMpIDogZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKC4uLmNsYXNzZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBEZXRhY2hlcyB0aGUgb3ZlcmxheSBjb250ZW50IG5leHQgdGltZSB0aGUgem9uZSBzdGFiaWxpemVzLiAqL1xuICBwcml2YXRlIF9kZXRhY2hDb250ZW50V2hlbkVtcHR5KCkge1xuICAgIC8vIE5vcm1hbGx5IHdlIHdvdWxkbid0IGhhdmUgdG8gZXhwbGljaXRseSBydW4gdGhpcyBvdXRzaWRlIHRoZSBgTmdab25lYCwgaG93ZXZlclxuICAgIC8vIGlmIHRoZSBjb25zdW1lciBpcyB1c2luZyBgem9uZS1wYXRjaC1yeGpzYCwgdGhlIGBTdWJzY3JpcHRpb24udW5zdWJzY3JpYmVgIGNhbGwgd2lsbFxuICAgIC8vIGJlIHBhdGNoZWQgdG8gcnVuIGluc2lkZSB0aGUgem9uZSwgd2hpY2ggd2lsbCB0aHJvdyB1cyBpbnRvIGFuIGluZmluaXRlIGxvb3AuXG4gICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIC8vIFdlIGNhbid0IHJlbW92ZSB0aGUgaG9zdCBoZXJlIGltbWVkaWF0ZWx5LCBiZWNhdXNlIHRoZSBvdmVybGF5IHBhbmUncyBjb250ZW50XG4gICAgICAvLyBtaWdodCBzdGlsbCBiZSBhbmltYXRpbmcuIFRoaXMgc3RyZWFtIGhlbHBzIHVzIGF2b2lkIGludGVycnVwdGluZyB0aGUgYW5pbWF0aW9uXG4gICAgICAvLyBieSB3YWl0aW5nIGZvciB0aGUgcGFuZSB0byBiZWNvbWUgZW1wdHkuXG4gICAgICBjb25zdCBzdWJzY3JpcHRpb24gPSB0aGlzLl9yZW5kZXJzXG4gICAgICAgIC5waXBlKHRha2VVbnRpbChtZXJnZSh0aGlzLl9hdHRhY2htZW50cywgdGhpcy5fZGV0YWNobWVudHMpKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgLy8gTmVlZHMgYSBjb3VwbGUgb2YgY2hlY2tzIGZvciB0aGUgcGFuZSBhbmQgaG9zdCwgYmVjYXVzZVxuICAgICAgICAgIC8vIHRoZXkgbWF5IGhhdmUgYmVlbiByZW1vdmVkIGJ5IHRoZSB0aW1lIHRoZSB6b25lIHN0YWJpbGl6ZXMuXG4gICAgICAgICAgaWYgKCF0aGlzLl9wYW5lIHx8ICF0aGlzLl9ob3N0IHx8IHRoaXMuX3BhbmUuY2hpbGRyZW4ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fcGFuZSAmJiB0aGlzLl9jb25maWcucGFuZWxDbGFzcykge1xuICAgICAgICAgICAgICB0aGlzLl90b2dnbGVDbGFzc2VzKHRoaXMuX3BhbmUsIHRoaXMuX2NvbmZpZy5wYW5lbENsYXNzLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLl9ob3N0ICYmIHRoaXMuX2hvc3QucGFyZW50RWxlbWVudCkge1xuICAgICAgICAgICAgICB0aGlzLl9wcmV2aW91c0hvc3RQYXJlbnQgPSB0aGlzLl9ob3N0LnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICAgIHRoaXMuX2hvc3QucmVtb3ZlKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKiogRGlzcG9zZXMgb2YgYSBzY3JvbGwgc3RyYXRlZ3kuICovXG4gIHByaXZhdGUgX2Rpc3Bvc2VTY3JvbGxTdHJhdGVneSgpIHtcbiAgICBjb25zdCBzY3JvbGxTdHJhdGVneSA9IHRoaXMuX3Njcm9sbFN0cmF0ZWd5O1xuXG4gICAgaWYgKHNjcm9sbFN0cmF0ZWd5KSB7XG4gICAgICBzY3JvbGxTdHJhdGVneS5kaXNhYmxlKCk7XG5cbiAgICAgIGlmIChzY3JvbGxTdHJhdGVneS5kZXRhY2gpIHtcbiAgICAgICAgc2Nyb2xsU3RyYXRlZ3kuZGV0YWNoKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIFJlbW92ZXMgYSBiYWNrZHJvcCBlbGVtZW50IGZyb20gdGhlIERPTS4gKi9cbiAgcHJpdmF0ZSBfZGlzcG9zZUJhY2tkcm9wKGJhY2tkcm9wOiBIVE1MRWxlbWVudCB8IG51bGwpIHtcbiAgICBpZiAoYmFja2Ryb3ApIHtcbiAgICAgIGJhY2tkcm9wLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYmFja2Ryb3BDbGlja0hhbmRsZXIpO1xuICAgICAgYmFja2Ryb3AucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIHRoaXMuX2JhY2tkcm9wVHJhbnNpdGlvbmVuZEhhbmRsZXIpO1xuICAgICAgYmFja2Ryb3AucmVtb3ZlKCk7XG5cbiAgICAgIC8vIEl0IGlzIHBvc3NpYmxlIHRoYXQgYSBuZXcgcG9ydGFsIGhhcyBiZWVuIGF0dGFjaGVkIHRvIHRoaXMgb3ZlcmxheSBzaW5jZSB3ZSBzdGFydGVkXG4gICAgICAvLyByZW1vdmluZyB0aGUgYmFja2Ryb3AuIElmIHRoYXQgaXMgdGhlIGNhc2UsIG9ubHkgY2xlYXIgdGhlIGJhY2tkcm9wIHJlZmVyZW5jZSBpZiBpdFxuICAgICAgLy8gaXMgc3RpbGwgdGhlIHNhbWUgaW5zdGFuY2UgdGhhdCB3ZSBzdGFydGVkIHRvIHJlbW92ZS5cbiAgICAgIGlmICh0aGlzLl9iYWNrZHJvcEVsZW1lbnQgPT09IGJhY2tkcm9wKSB7XG4gICAgICAgIHRoaXMuX2JhY2tkcm9wRWxlbWVudCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2JhY2tkcm9wVGltZW91dCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX2JhY2tkcm9wVGltZW91dCk7XG4gICAgICB0aGlzLl9iYWNrZHJvcFRpbWVvdXQgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG59XG5cbi8qKiBTaXplIHByb3BlcnRpZXMgZm9yIGFuIG92ZXJsYXkuICovXG5leHBvcnQgaW50ZXJmYWNlIE92ZXJsYXlTaXplQ29uZmlnIHtcbiAgd2lkdGg/OiBudW1iZXIgfCBzdHJpbmc7XG4gIGhlaWdodD86IG51bWJlciB8IHN0cmluZztcbiAgbWluV2lkdGg/OiBudW1iZXIgfCBzdHJpbmc7XG4gIG1pbkhlaWdodD86IG51bWJlciB8IHN0cmluZztcbiAgbWF4V2lkdGg/OiBudW1iZXIgfCBzdHJpbmc7XG4gIG1heEhlaWdodD86IG51bWJlciB8IHN0cmluZztcbn1cbiJdfQ==
|