@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,888 +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 { ActiveDescendantKeyManager } from '@angular/cdk/a11y';
|
|
9
|
-
import { Directionality } from '@angular/cdk/bidi';
|
|
10
|
-
import { coerceArray } from '@angular/cdk/coercion';
|
|
11
|
-
import { SelectionModel } from '@angular/cdk/collections';
|
|
12
|
-
import { A, DOWN_ARROW, END, ENTER, hasModifierKey, HOME, LEFT_ARROW, RIGHT_ARROW, SPACE, UP_ARROW, } from '@angular/cdk/keycodes';
|
|
13
|
-
import { Platform } from '@angular/cdk/platform';
|
|
14
|
-
import { booleanAttribute, ChangeDetectorRef, ContentChildren, Directive, ElementRef, forwardRef, inject, Input, NgZone, Output, QueryList, } from '@angular/core';
|
|
15
|
-
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
16
|
-
import { defer, fromEvent, merge, Subject } from 'rxjs';
|
|
17
|
-
import { filter, map, startWith, switchMap, takeUntil } from 'rxjs/operators';
|
|
18
|
-
import * as i0 from "@angular/core";
|
|
19
|
-
/** The next id to use for creating unique DOM IDs. */
|
|
20
|
-
let nextId = 0;
|
|
21
|
-
/**
|
|
22
|
-
* An implementation of SelectionModel that internally always represents the selection as a
|
|
23
|
-
* multi-selection. This is necessary so that we can recover the full selection if the user
|
|
24
|
-
* switches the listbox from single-selection to multi-selection after initialization.
|
|
25
|
-
*
|
|
26
|
-
* This selection model may report multiple selected values, even if it is in single-selection
|
|
27
|
-
* mode. It is up to the user (CdkListbox) to check for invalid selections.
|
|
28
|
-
*/
|
|
29
|
-
class ListboxSelectionModel extends SelectionModel {
|
|
30
|
-
constructor(multiple = false, initiallySelectedValues, emitChanges = true, compareWith) {
|
|
31
|
-
super(true, initiallySelectedValues, emitChanges, compareWith);
|
|
32
|
-
this.multiple = multiple;
|
|
33
|
-
}
|
|
34
|
-
isMultipleSelection() {
|
|
35
|
-
return this.multiple;
|
|
36
|
-
}
|
|
37
|
-
select(...values) {
|
|
38
|
-
// The super class is always in multi-selection mode, so we need to override the behavior if
|
|
39
|
-
// this selection model actually belongs to a single-selection listbox.
|
|
40
|
-
if (this.multiple) {
|
|
41
|
-
return super.select(...values);
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
return super.setSelection(...values);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/** A selectable option in a listbox. */
|
|
49
|
-
export class CdkOption {
|
|
50
|
-
constructor() {
|
|
51
|
-
this._generatedId = `cdk-option-${nextId++}`;
|
|
52
|
-
this._disabled = false;
|
|
53
|
-
/** The option's host element */
|
|
54
|
-
this.element = inject(ElementRef).nativeElement;
|
|
55
|
-
/** The parent listbox this option belongs to. */
|
|
56
|
-
this.listbox = inject(CdkListbox);
|
|
57
|
-
/** Emits when the option is destroyed. */
|
|
58
|
-
this.destroyed = new Subject();
|
|
59
|
-
/** Emits when the option is clicked. */
|
|
60
|
-
this._clicked = new Subject();
|
|
61
|
-
}
|
|
62
|
-
/** The id of the option's host element. */
|
|
63
|
-
get id() {
|
|
64
|
-
return this._id || this._generatedId;
|
|
65
|
-
}
|
|
66
|
-
set id(value) {
|
|
67
|
-
this._id = value;
|
|
68
|
-
}
|
|
69
|
-
/** Whether this option is disabled. */
|
|
70
|
-
get disabled() {
|
|
71
|
-
return this.listbox.disabled || this._disabled;
|
|
72
|
-
}
|
|
73
|
-
set disabled(value) {
|
|
74
|
-
this._disabled = value;
|
|
75
|
-
}
|
|
76
|
-
/** The tabindex of the option when it is enabled. */
|
|
77
|
-
get enabledTabIndex() {
|
|
78
|
-
return this._enabledTabIndex === undefined
|
|
79
|
-
? this.listbox.enabledTabIndex
|
|
80
|
-
: this._enabledTabIndex;
|
|
81
|
-
}
|
|
82
|
-
set enabledTabIndex(value) {
|
|
83
|
-
this._enabledTabIndex = value;
|
|
84
|
-
}
|
|
85
|
-
ngOnDestroy() {
|
|
86
|
-
this.destroyed.next();
|
|
87
|
-
this.destroyed.complete();
|
|
88
|
-
}
|
|
89
|
-
/** Whether this option is selected. */
|
|
90
|
-
isSelected() {
|
|
91
|
-
return this.listbox.isSelected(this);
|
|
92
|
-
}
|
|
93
|
-
/** Whether this option is active. */
|
|
94
|
-
isActive() {
|
|
95
|
-
return this.listbox.isActive(this);
|
|
96
|
-
}
|
|
97
|
-
/** Toggle the selected state of this option. */
|
|
98
|
-
toggle() {
|
|
99
|
-
this.listbox.toggle(this);
|
|
100
|
-
}
|
|
101
|
-
/** Select this option if it is not selected. */
|
|
102
|
-
select() {
|
|
103
|
-
this.listbox.select(this);
|
|
104
|
-
}
|
|
105
|
-
/** Deselect this option if it is selected. */
|
|
106
|
-
deselect() {
|
|
107
|
-
this.listbox.deselect(this);
|
|
108
|
-
}
|
|
109
|
-
/** Focus this option. */
|
|
110
|
-
focus() {
|
|
111
|
-
this.element.focus();
|
|
112
|
-
}
|
|
113
|
-
/** Get the label for this element which is required by the FocusableOption interface. */
|
|
114
|
-
getLabel() {
|
|
115
|
-
return (this.typeaheadLabel ?? this.element.textContent?.trim()) || '';
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* No-op implemented as a part of `Highlightable`.
|
|
119
|
-
* @docs-private
|
|
120
|
-
*/
|
|
121
|
-
setActiveStyles() { }
|
|
122
|
-
/**
|
|
123
|
-
* No-op implemented as a part of `Highlightable`.
|
|
124
|
-
* @docs-private
|
|
125
|
-
*/
|
|
126
|
-
setInactiveStyles() { }
|
|
127
|
-
/** Handle focus events on the option. */
|
|
128
|
-
_handleFocus() {
|
|
129
|
-
// Options can wind up getting focused in active descendant mode if the user clicks on them.
|
|
130
|
-
// In this case, we push focus back to the parent listbox to prevent an extra tab stop when
|
|
131
|
-
// the user performs a shift+tab.
|
|
132
|
-
if (this.listbox.useActiveDescendant) {
|
|
133
|
-
this.listbox._setActiveOption(this);
|
|
134
|
-
this.listbox.focus();
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
/** Get the tabindex for this option. */
|
|
138
|
-
_getTabIndex() {
|
|
139
|
-
if (this.listbox.useActiveDescendant || this.disabled) {
|
|
140
|
-
return -1;
|
|
141
|
-
}
|
|
142
|
-
return this.isActive() ? this.enabledTabIndex : -1;
|
|
143
|
-
}
|
|
144
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: CdkOption, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
145
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "18.2.0-next.2", type: CdkOption, isStandalone: true, selector: "[cdkOption]", inputs: { id: "id", value: ["cdkOption", "value"], typeaheadLabel: ["cdkOptionTypeaheadLabel", "typeaheadLabel"], disabled: ["cdkOptionDisabled", "disabled", booleanAttribute], enabledTabIndex: ["tabindex", "enabledTabIndex"] }, host: { attributes: { "role": "option" }, listeners: { "click": "_clicked.next($event)", "focus": "_handleFocus()" }, properties: { "id": "id", "attr.aria-selected": "isSelected()", "attr.tabindex": "_getTabIndex()", "attr.aria-disabled": "disabled", "class.cdk-option-active": "isActive()" }, classAttribute: "cdk-option" }, exportAs: ["cdkOption"], ngImport: i0 }); }
|
|
146
|
-
}
|
|
147
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: CdkOption, decorators: [{
|
|
148
|
-
type: Directive,
|
|
149
|
-
args: [{
|
|
150
|
-
selector: '[cdkOption]',
|
|
151
|
-
standalone: true,
|
|
152
|
-
exportAs: 'cdkOption',
|
|
153
|
-
host: {
|
|
154
|
-
'role': 'option',
|
|
155
|
-
'class': 'cdk-option',
|
|
156
|
-
'[id]': 'id',
|
|
157
|
-
'[attr.aria-selected]': 'isSelected()',
|
|
158
|
-
'[attr.tabindex]': '_getTabIndex()',
|
|
159
|
-
'[attr.aria-disabled]': 'disabled',
|
|
160
|
-
'[class.cdk-option-active]': 'isActive()',
|
|
161
|
-
'(click)': '_clicked.next($event)',
|
|
162
|
-
'(focus)': '_handleFocus()',
|
|
163
|
-
},
|
|
164
|
-
}]
|
|
165
|
-
}], propDecorators: { id: [{
|
|
166
|
-
type: Input
|
|
167
|
-
}], value: [{
|
|
168
|
-
type: Input,
|
|
169
|
-
args: ['cdkOption']
|
|
170
|
-
}], typeaheadLabel: [{
|
|
171
|
-
type: Input,
|
|
172
|
-
args: ['cdkOptionTypeaheadLabel']
|
|
173
|
-
}], disabled: [{
|
|
174
|
-
type: Input,
|
|
175
|
-
args: [{ alias: 'cdkOptionDisabled', transform: booleanAttribute }]
|
|
176
|
-
}], enabledTabIndex: [{
|
|
177
|
-
type: Input,
|
|
178
|
-
args: ['tabindex']
|
|
179
|
-
}] } });
|
|
180
|
-
export class CdkListbox {
|
|
181
|
-
/** The id of the option's host element. */
|
|
182
|
-
get id() {
|
|
183
|
-
return this._id || this._generatedId;
|
|
184
|
-
}
|
|
185
|
-
set id(value) {
|
|
186
|
-
this._id = value;
|
|
187
|
-
}
|
|
188
|
-
/** The tabindex to use when the listbox is enabled. */
|
|
189
|
-
get enabledTabIndex() {
|
|
190
|
-
return this._enabledTabIndex === undefined ? 0 : this._enabledTabIndex;
|
|
191
|
-
}
|
|
192
|
-
set enabledTabIndex(value) {
|
|
193
|
-
this._enabledTabIndex = value;
|
|
194
|
-
}
|
|
195
|
-
/** The value selected in the listbox, represented as an array of option values. */
|
|
196
|
-
get value() {
|
|
197
|
-
return this._invalid ? [] : this.selectionModel.selected;
|
|
198
|
-
}
|
|
199
|
-
set value(value) {
|
|
200
|
-
this._setSelection(value);
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Whether the listbox allows multiple options to be selected. If the value switches from `true`
|
|
204
|
-
* to `false`, and more than one option is selected, all options are deselected.
|
|
205
|
-
*/
|
|
206
|
-
get multiple() {
|
|
207
|
-
return this.selectionModel.multiple;
|
|
208
|
-
}
|
|
209
|
-
set multiple(value) {
|
|
210
|
-
this.selectionModel.multiple = value;
|
|
211
|
-
if (this.options) {
|
|
212
|
-
this._updateInternalValue();
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
/** The orientation of the listbox. Only affects keyboard interaction, not visual layout. */
|
|
216
|
-
get orientation() {
|
|
217
|
-
return this._orientation;
|
|
218
|
-
}
|
|
219
|
-
set orientation(value) {
|
|
220
|
-
this._orientation = value === 'horizontal' ? 'horizontal' : 'vertical';
|
|
221
|
-
if (value === 'horizontal') {
|
|
222
|
-
this.listKeyManager?.withHorizontalOrientation(this._dir?.value || 'ltr');
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
this.listKeyManager?.withVerticalOrientation();
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
/** The function used to compare option values. */
|
|
229
|
-
get compareWith() {
|
|
230
|
-
return this.selectionModel.compareWith;
|
|
231
|
-
}
|
|
232
|
-
set compareWith(fn) {
|
|
233
|
-
this.selectionModel.compareWith = fn;
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Whether the keyboard navigation should wrap when the user presses arrow down on the last item
|
|
237
|
-
* or arrow up on the first item.
|
|
238
|
-
*/
|
|
239
|
-
get navigationWrapDisabled() {
|
|
240
|
-
return this._navigationWrapDisabled;
|
|
241
|
-
}
|
|
242
|
-
set navigationWrapDisabled(wrap) {
|
|
243
|
-
this._navigationWrapDisabled = wrap;
|
|
244
|
-
this.listKeyManager?.withWrap(!this._navigationWrapDisabled);
|
|
245
|
-
}
|
|
246
|
-
/** Whether keyboard navigation should skip over disabled items. */
|
|
247
|
-
get navigateDisabledOptions() {
|
|
248
|
-
return this._navigateDisabledOptions;
|
|
249
|
-
}
|
|
250
|
-
set navigateDisabledOptions(skip) {
|
|
251
|
-
this._navigateDisabledOptions = skip;
|
|
252
|
-
this.listKeyManager?.skipPredicate(this._navigateDisabledOptions ? this._skipNonePredicate : this._skipDisabledPredicate);
|
|
253
|
-
}
|
|
254
|
-
constructor() {
|
|
255
|
-
this._generatedId = `cdk-listbox-${nextId++}`;
|
|
256
|
-
/** Whether the listbox is disabled. */
|
|
257
|
-
this.disabled = false;
|
|
258
|
-
/** Whether the listbox will use active descendant or will move focus onto the options. */
|
|
259
|
-
this.useActiveDescendant = false;
|
|
260
|
-
this._orientation = 'vertical';
|
|
261
|
-
this._navigationWrapDisabled = false;
|
|
262
|
-
this._navigateDisabledOptions = false;
|
|
263
|
-
/** Emits when the selected value(s) in the listbox change. */
|
|
264
|
-
this.valueChange = new Subject();
|
|
265
|
-
/** The selection model used by the listbox. */
|
|
266
|
-
this.selectionModel = new ListboxSelectionModel();
|
|
267
|
-
/** Emits when the listbox is destroyed. */
|
|
268
|
-
this.destroyed = new Subject();
|
|
269
|
-
/** The host element of the listbox. */
|
|
270
|
-
this.element = inject(ElementRef).nativeElement;
|
|
271
|
-
/** The Angular zone. */
|
|
272
|
-
this.ngZone = inject(NgZone);
|
|
273
|
-
/** The change detector for this listbox. */
|
|
274
|
-
this.changeDetectorRef = inject(ChangeDetectorRef);
|
|
275
|
-
/** Whether the currently selected value in the selection model is invalid. */
|
|
276
|
-
this._invalid = false;
|
|
277
|
-
/** The last user-triggered option. */
|
|
278
|
-
this._lastTriggered = null;
|
|
279
|
-
/** Callback called when the listbox has been touched */
|
|
280
|
-
this._onTouched = () => { };
|
|
281
|
-
/** Callback called when the listbox value changes */
|
|
282
|
-
this._onChange = () => { };
|
|
283
|
-
/** Emits when an option has been clicked. */
|
|
284
|
-
this._optionClicked = defer(() => this.options.changes.pipe(startWith(this.options), switchMap(options => merge(...options.map(option => option._clicked.pipe(map(event => ({ option, event }))))))));
|
|
285
|
-
/** The directionality of the page. */
|
|
286
|
-
this._dir = inject(Directionality, { optional: true });
|
|
287
|
-
/** Whether the component is being rendered in the browser. */
|
|
288
|
-
this._isBrowser = inject(Platform).isBrowser;
|
|
289
|
-
/** A predicate that skips disabled options. */
|
|
290
|
-
this._skipDisabledPredicate = (option) => option.disabled;
|
|
291
|
-
/** A predicate that does not skip any options. */
|
|
292
|
-
this._skipNonePredicate = () => false;
|
|
293
|
-
/** Whether the listbox currently has focus. */
|
|
294
|
-
this._hasFocus = false;
|
|
295
|
-
/** A reference to the option that was active before the listbox lost focus. */
|
|
296
|
-
this._previousActiveOption = null;
|
|
297
|
-
if (this._isBrowser) {
|
|
298
|
-
this._setPreviousActiveOptionAsActiveOptionOnWindowBlur();
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
ngAfterContentInit() {
|
|
302
|
-
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
303
|
-
this._verifyNoOptionValueCollisions();
|
|
304
|
-
this._verifyOptionValues();
|
|
305
|
-
}
|
|
306
|
-
this._initKeyManager();
|
|
307
|
-
// Update the internal value whenever the options or the model value changes.
|
|
308
|
-
merge(this.selectionModel.changed, this.options.changes)
|
|
309
|
-
.pipe(startWith(null), takeUntil(this.destroyed))
|
|
310
|
-
.subscribe(() => this._updateInternalValue());
|
|
311
|
-
this._optionClicked
|
|
312
|
-
.pipe(filter(({ option }) => !option.disabled), takeUntil(this.destroyed))
|
|
313
|
-
.subscribe(({ option, event }) => this._handleOptionClicked(option, event));
|
|
314
|
-
}
|
|
315
|
-
ngOnDestroy() {
|
|
316
|
-
this.listKeyManager?.destroy();
|
|
317
|
-
this.destroyed.next();
|
|
318
|
-
this.destroyed.complete();
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Toggle the selected state of the given option.
|
|
322
|
-
* @param option The option to toggle
|
|
323
|
-
*/
|
|
324
|
-
toggle(option) {
|
|
325
|
-
this.toggleValue(option.value);
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Toggle the selected state of the given value.
|
|
329
|
-
* @param value The value to toggle
|
|
330
|
-
*/
|
|
331
|
-
toggleValue(value) {
|
|
332
|
-
if (this._invalid) {
|
|
333
|
-
this.selectionModel.clear(false);
|
|
334
|
-
}
|
|
335
|
-
this.selectionModel.toggle(value);
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Select the given option.
|
|
339
|
-
* @param option The option to select
|
|
340
|
-
*/
|
|
341
|
-
select(option) {
|
|
342
|
-
this.selectValue(option.value);
|
|
343
|
-
}
|
|
344
|
-
/**
|
|
345
|
-
* Select the given value.
|
|
346
|
-
* @param value The value to select
|
|
347
|
-
*/
|
|
348
|
-
selectValue(value) {
|
|
349
|
-
if (this._invalid) {
|
|
350
|
-
this.selectionModel.clear(false);
|
|
351
|
-
}
|
|
352
|
-
this.selectionModel.select(value);
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Deselect the given option.
|
|
356
|
-
* @param option The option to deselect
|
|
357
|
-
*/
|
|
358
|
-
deselect(option) {
|
|
359
|
-
this.deselectValue(option.value);
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
* Deselect the given value.
|
|
363
|
-
* @param value The value to deselect
|
|
364
|
-
*/
|
|
365
|
-
deselectValue(value) {
|
|
366
|
-
if (this._invalid) {
|
|
367
|
-
this.selectionModel.clear(false);
|
|
368
|
-
}
|
|
369
|
-
this.selectionModel.deselect(value);
|
|
370
|
-
}
|
|
371
|
-
/**
|
|
372
|
-
* Set the selected state of all options.
|
|
373
|
-
* @param isSelected The new selected state to set
|
|
374
|
-
*/
|
|
375
|
-
setAllSelected(isSelected) {
|
|
376
|
-
if (!isSelected) {
|
|
377
|
-
this.selectionModel.clear();
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
380
|
-
if (this._invalid) {
|
|
381
|
-
this.selectionModel.clear(false);
|
|
382
|
-
}
|
|
383
|
-
this.selectionModel.select(...this.options.map(option => option.value));
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* Get whether the given option is selected.
|
|
388
|
-
* @param option The option to get the selected state of
|
|
389
|
-
*/
|
|
390
|
-
isSelected(option) {
|
|
391
|
-
return this.isValueSelected(option.value);
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Get whether the given option is active.
|
|
395
|
-
* @param option The option to get the active state of
|
|
396
|
-
*/
|
|
397
|
-
isActive(option) {
|
|
398
|
-
return !!(this.listKeyManager?.activeItem === option);
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Get whether the given value is selected.
|
|
402
|
-
* @param value The value to get the selected state of
|
|
403
|
-
*/
|
|
404
|
-
isValueSelected(value) {
|
|
405
|
-
if (this._invalid) {
|
|
406
|
-
return false;
|
|
407
|
-
}
|
|
408
|
-
return this.selectionModel.isSelected(value);
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* Registers a callback to be invoked when the listbox's value changes from user input.
|
|
412
|
-
* @param fn The callback to register
|
|
413
|
-
* @docs-private
|
|
414
|
-
*/
|
|
415
|
-
registerOnChange(fn) {
|
|
416
|
-
this._onChange = fn;
|
|
417
|
-
}
|
|
418
|
-
/**
|
|
419
|
-
* Registers a callback to be invoked when the listbox is blurred by the user.
|
|
420
|
-
* @param fn The callback to register
|
|
421
|
-
* @docs-private
|
|
422
|
-
*/
|
|
423
|
-
registerOnTouched(fn) {
|
|
424
|
-
this._onTouched = fn;
|
|
425
|
-
}
|
|
426
|
-
/**
|
|
427
|
-
* Sets the listbox's value.
|
|
428
|
-
* @param value The new value of the listbox
|
|
429
|
-
* @docs-private
|
|
430
|
-
*/
|
|
431
|
-
writeValue(value) {
|
|
432
|
-
this._setSelection(value);
|
|
433
|
-
this._verifyOptionValues();
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* Sets the disabled state of the listbox.
|
|
437
|
-
* @param isDisabled The new disabled state
|
|
438
|
-
* @docs-private
|
|
439
|
-
*/
|
|
440
|
-
setDisabledState(isDisabled) {
|
|
441
|
-
this.disabled = isDisabled;
|
|
442
|
-
this.changeDetectorRef.markForCheck();
|
|
443
|
-
}
|
|
444
|
-
/** Focus the listbox's host element. */
|
|
445
|
-
focus() {
|
|
446
|
-
this.element.focus();
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
* Triggers the given option in response to user interaction.
|
|
450
|
-
* - In single selection mode: selects the option and deselects any other selected option.
|
|
451
|
-
* - In multi selection mode: toggles the selected state of the option.
|
|
452
|
-
* @param option The option to trigger
|
|
453
|
-
*/
|
|
454
|
-
triggerOption(option) {
|
|
455
|
-
if (option && !option.disabled) {
|
|
456
|
-
this._lastTriggered = option;
|
|
457
|
-
const changed = this.multiple
|
|
458
|
-
? this.selectionModel.toggle(option.value)
|
|
459
|
-
: this.selectionModel.select(option.value);
|
|
460
|
-
if (changed) {
|
|
461
|
-
this._onChange(this.value);
|
|
462
|
-
this.valueChange.next({
|
|
463
|
-
value: this.value,
|
|
464
|
-
listbox: this,
|
|
465
|
-
option: option,
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Trigger the given range of options in response to user interaction.
|
|
472
|
-
* Should only be called in multi-selection mode.
|
|
473
|
-
* @param trigger The option that was triggered
|
|
474
|
-
* @param from The start index of the options to toggle
|
|
475
|
-
* @param to The end index of the options to toggle
|
|
476
|
-
* @param on Whether to toggle the option range on
|
|
477
|
-
*/
|
|
478
|
-
triggerRange(trigger, from, to, on) {
|
|
479
|
-
if (this.disabled || (trigger && trigger.disabled)) {
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
this._lastTriggered = trigger;
|
|
483
|
-
const isEqual = this.compareWith ?? Object.is;
|
|
484
|
-
const updateValues = [...this.options]
|
|
485
|
-
.slice(Math.max(0, Math.min(from, to)), Math.min(this.options.length, Math.max(from, to) + 1))
|
|
486
|
-
.filter(option => !option.disabled)
|
|
487
|
-
.map(option => option.value);
|
|
488
|
-
const selected = [...this.value];
|
|
489
|
-
for (const updateValue of updateValues) {
|
|
490
|
-
const selectedIndex = selected.findIndex(selectedValue => isEqual(selectedValue, updateValue));
|
|
491
|
-
if (on && selectedIndex === -1) {
|
|
492
|
-
selected.push(updateValue);
|
|
493
|
-
}
|
|
494
|
-
else if (!on && selectedIndex !== -1) {
|
|
495
|
-
selected.splice(selectedIndex, 1);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
let changed = this.selectionModel.setSelection(...selected);
|
|
499
|
-
if (changed) {
|
|
500
|
-
this._onChange(this.value);
|
|
501
|
-
this.valueChange.next({
|
|
502
|
-
value: this.value,
|
|
503
|
-
listbox: this,
|
|
504
|
-
option: trigger,
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
/**
|
|
509
|
-
* Sets the given option as active.
|
|
510
|
-
* @param option The option to make active
|
|
511
|
-
*/
|
|
512
|
-
_setActiveOption(option) {
|
|
513
|
-
this.listKeyManager.setActiveItem(option);
|
|
514
|
-
}
|
|
515
|
-
/** Called when the listbox receives focus. */
|
|
516
|
-
_handleFocus() {
|
|
517
|
-
if (!this.useActiveDescendant) {
|
|
518
|
-
if (this.selectionModel.selected.length > 0) {
|
|
519
|
-
this._setNextFocusToSelectedOption();
|
|
520
|
-
}
|
|
521
|
-
else {
|
|
522
|
-
this.listKeyManager.setNextItemActive();
|
|
523
|
-
}
|
|
524
|
-
this._focusActiveOption();
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
/** Called when the user presses keydown on the listbox. */
|
|
528
|
-
_handleKeydown(event) {
|
|
529
|
-
if (this.disabled) {
|
|
530
|
-
return;
|
|
531
|
-
}
|
|
532
|
-
const { keyCode } = event;
|
|
533
|
-
const previousActiveIndex = this.listKeyManager.activeItemIndex;
|
|
534
|
-
const ctrlKeys = ['ctrlKey', 'metaKey'];
|
|
535
|
-
if (this.multiple && keyCode === A && hasModifierKey(event, ...ctrlKeys)) {
|
|
536
|
-
// Toggle all options off if they're all selected, otherwise toggle them all on.
|
|
537
|
-
this.triggerRange(null, 0, this.options.length - 1, this.options.length !== this.value.length);
|
|
538
|
-
event.preventDefault();
|
|
539
|
-
return;
|
|
540
|
-
}
|
|
541
|
-
if (this.multiple &&
|
|
542
|
-
(keyCode === SPACE || keyCode === ENTER) &&
|
|
543
|
-
hasModifierKey(event, 'shiftKey')) {
|
|
544
|
-
if (this.listKeyManager.activeItem && this.listKeyManager.activeItemIndex != null) {
|
|
545
|
-
this.triggerRange(this.listKeyManager.activeItem, this._getLastTriggeredIndex() ?? this.listKeyManager.activeItemIndex, this.listKeyManager.activeItemIndex, !this.listKeyManager.activeItem.isSelected());
|
|
546
|
-
}
|
|
547
|
-
event.preventDefault();
|
|
548
|
-
return;
|
|
549
|
-
}
|
|
550
|
-
if (this.multiple &&
|
|
551
|
-
keyCode === HOME &&
|
|
552
|
-
hasModifierKey(event, ...ctrlKeys) &&
|
|
553
|
-
hasModifierKey(event, 'shiftKey')) {
|
|
554
|
-
const trigger = this.listKeyManager.activeItem;
|
|
555
|
-
if (trigger) {
|
|
556
|
-
const from = this.listKeyManager.activeItemIndex;
|
|
557
|
-
this.listKeyManager.setFirstItemActive();
|
|
558
|
-
this.triggerRange(trigger, from, this.listKeyManager.activeItemIndex, !trigger.isSelected());
|
|
559
|
-
}
|
|
560
|
-
event.preventDefault();
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
if (this.multiple &&
|
|
564
|
-
keyCode === END &&
|
|
565
|
-
hasModifierKey(event, ...ctrlKeys) &&
|
|
566
|
-
hasModifierKey(event, 'shiftKey')) {
|
|
567
|
-
const trigger = this.listKeyManager.activeItem;
|
|
568
|
-
if (trigger) {
|
|
569
|
-
const from = this.listKeyManager.activeItemIndex;
|
|
570
|
-
this.listKeyManager.setLastItemActive();
|
|
571
|
-
this.triggerRange(trigger, from, this.listKeyManager.activeItemIndex, !trigger.isSelected());
|
|
572
|
-
}
|
|
573
|
-
event.preventDefault();
|
|
574
|
-
return;
|
|
575
|
-
}
|
|
576
|
-
if (keyCode === SPACE || keyCode === ENTER) {
|
|
577
|
-
this.triggerOption(this.listKeyManager.activeItem);
|
|
578
|
-
event.preventDefault();
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
|
-
const isNavKey = keyCode === UP_ARROW ||
|
|
582
|
-
keyCode === DOWN_ARROW ||
|
|
583
|
-
keyCode === LEFT_ARROW ||
|
|
584
|
-
keyCode === RIGHT_ARROW ||
|
|
585
|
-
keyCode === HOME ||
|
|
586
|
-
keyCode === END;
|
|
587
|
-
this.listKeyManager.onKeydown(event);
|
|
588
|
-
// Will select an option if shift was pressed while navigating to the option
|
|
589
|
-
if (isNavKey && event.shiftKey && previousActiveIndex !== this.listKeyManager.activeItemIndex) {
|
|
590
|
-
this.triggerOption(this.listKeyManager.activeItem);
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
/** Called when a focus moves into the listbox. */
|
|
594
|
-
_handleFocusIn() {
|
|
595
|
-
// Note that we use a `focusin` handler for this instead of the existing `focus` handler,
|
|
596
|
-
// because focus won't land on the listbox if `useActiveDescendant` is enabled.
|
|
597
|
-
this._hasFocus = true;
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* Called when the focus leaves an element in the listbox.
|
|
601
|
-
* @param event The focusout event
|
|
602
|
-
*/
|
|
603
|
-
_handleFocusOut(event) {
|
|
604
|
-
// Some browsers (e.g. Chrome and Firefox) trigger the focusout event when the user returns back to the document.
|
|
605
|
-
// To prevent losing the active option in this case, we store it in `_previousActiveOption` and restore it on the window `blur` event
|
|
606
|
-
// This ensures that the `activeItem` matches the actual focused element when the user returns to the document.
|
|
607
|
-
this._previousActiveOption = this.listKeyManager.activeItem;
|
|
608
|
-
const otherElement = event.relatedTarget;
|
|
609
|
-
if (this.element !== otherElement && !this.element.contains(otherElement)) {
|
|
610
|
-
this._onTouched();
|
|
611
|
-
this._hasFocus = false;
|
|
612
|
-
this._setNextFocusToSelectedOption();
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
/** Get the id of the active option if active descendant is being used. */
|
|
616
|
-
_getAriaActiveDescendant() {
|
|
617
|
-
return this.useActiveDescendant ? this.listKeyManager?.activeItem?.id : null;
|
|
618
|
-
}
|
|
619
|
-
/** Get the tabindex for the listbox. */
|
|
620
|
-
_getTabIndex() {
|
|
621
|
-
if (this.disabled) {
|
|
622
|
-
return -1;
|
|
623
|
-
}
|
|
624
|
-
return this.useActiveDescendant || !this.listKeyManager.activeItem ? this.enabledTabIndex : -1;
|
|
625
|
-
}
|
|
626
|
-
/** Initialize the key manager. */
|
|
627
|
-
_initKeyManager() {
|
|
628
|
-
this.listKeyManager = new ActiveDescendantKeyManager(this.options)
|
|
629
|
-
.withWrap(!this._navigationWrapDisabled)
|
|
630
|
-
.withTypeAhead()
|
|
631
|
-
.withHomeAndEnd()
|
|
632
|
-
.withAllowedModifierKeys(['shiftKey'])
|
|
633
|
-
.skipPredicate(this._navigateDisabledOptions ? this._skipNonePredicate : this._skipDisabledPredicate);
|
|
634
|
-
if (this.orientation === 'vertical') {
|
|
635
|
-
this.listKeyManager.withVerticalOrientation();
|
|
636
|
-
}
|
|
637
|
-
else {
|
|
638
|
-
this.listKeyManager.withHorizontalOrientation(this._dir?.value || 'ltr');
|
|
639
|
-
}
|
|
640
|
-
if (this.selectionModel.selected.length) {
|
|
641
|
-
Promise.resolve().then(() => this._setNextFocusToSelectedOption());
|
|
642
|
-
}
|
|
643
|
-
this.listKeyManager.change.subscribe(() => this._focusActiveOption());
|
|
644
|
-
this.options.changes.pipe(takeUntil(this.destroyed)).subscribe(() => {
|
|
645
|
-
const activeOption = this.listKeyManager.activeItem;
|
|
646
|
-
// If the active option was deleted, we need to reset
|
|
647
|
-
// the key manager so it can allow focus back in.
|
|
648
|
-
if (activeOption && !this.options.find(option => option === activeOption)) {
|
|
649
|
-
this.listKeyManager.setActiveItem(-1);
|
|
650
|
-
this.changeDetectorRef.markForCheck();
|
|
651
|
-
}
|
|
652
|
-
});
|
|
653
|
-
}
|
|
654
|
-
/** Focus the active option. */
|
|
655
|
-
_focusActiveOption() {
|
|
656
|
-
if (!this.useActiveDescendant) {
|
|
657
|
-
this.listKeyManager.activeItem?.focus();
|
|
658
|
-
}
|
|
659
|
-
this.changeDetectorRef.markForCheck();
|
|
660
|
-
}
|
|
661
|
-
/**
|
|
662
|
-
* Set the selected values.
|
|
663
|
-
* @param value The list of new selected values.
|
|
664
|
-
*/
|
|
665
|
-
_setSelection(value) {
|
|
666
|
-
if (this._invalid) {
|
|
667
|
-
this.selectionModel.clear(false);
|
|
668
|
-
}
|
|
669
|
-
this.selectionModel.setSelection(...this._coerceValue(value));
|
|
670
|
-
if (!this._hasFocus) {
|
|
671
|
-
this._setNextFocusToSelectedOption();
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
/** Sets the first selected option as first in the keyboard focus order. */
|
|
675
|
-
_setNextFocusToSelectedOption() {
|
|
676
|
-
// Null check the options since they only get defined after `ngAfterContentInit`.
|
|
677
|
-
const selected = this.options?.find(option => option.isSelected());
|
|
678
|
-
if (selected) {
|
|
679
|
-
this.listKeyManager.updateActiveItem(selected);
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
/** Update the internal value of the listbox based on the selection model. */
|
|
683
|
-
_updateInternalValue() {
|
|
684
|
-
const indexCache = new Map();
|
|
685
|
-
this.selectionModel.sort((a, b) => {
|
|
686
|
-
const aIndex = this._getIndexForValue(indexCache, a);
|
|
687
|
-
const bIndex = this._getIndexForValue(indexCache, b);
|
|
688
|
-
return aIndex - bIndex;
|
|
689
|
-
});
|
|
690
|
-
const selected = this.selectionModel.selected;
|
|
691
|
-
this._invalid =
|
|
692
|
-
(!this.multiple && selected.length > 1) || !!this._getInvalidOptionValues(selected).length;
|
|
693
|
-
this.changeDetectorRef.markForCheck();
|
|
694
|
-
}
|
|
695
|
-
/**
|
|
696
|
-
* Gets the index of the given value in the given list of options.
|
|
697
|
-
* @param cache The cache of indices found so far
|
|
698
|
-
* @param value The value to find
|
|
699
|
-
* @return The index of the value in the options list
|
|
700
|
-
*/
|
|
701
|
-
_getIndexForValue(cache, value) {
|
|
702
|
-
const isEqual = this.compareWith || Object.is;
|
|
703
|
-
if (!cache.has(value)) {
|
|
704
|
-
let index = -1;
|
|
705
|
-
for (let i = 0; i < this.options.length; i++) {
|
|
706
|
-
if (isEqual(value, this.options.get(i).value)) {
|
|
707
|
-
index = i;
|
|
708
|
-
break;
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
cache.set(value, index);
|
|
712
|
-
}
|
|
713
|
-
return cache.get(value);
|
|
714
|
-
}
|
|
715
|
-
/**
|
|
716
|
-
* Handle the user clicking an option.
|
|
717
|
-
* @param option The option that was clicked.
|
|
718
|
-
*/
|
|
719
|
-
_handleOptionClicked(option, event) {
|
|
720
|
-
event.preventDefault();
|
|
721
|
-
this.listKeyManager.setActiveItem(option);
|
|
722
|
-
if (event.shiftKey && this.multiple) {
|
|
723
|
-
this.triggerRange(option, this._getLastTriggeredIndex() ?? this.listKeyManager.activeItemIndex, this.listKeyManager.activeItemIndex, !option.isSelected());
|
|
724
|
-
}
|
|
725
|
-
else {
|
|
726
|
-
this.triggerOption(option);
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
/** Verifies that no two options represent the same value under the compareWith function. */
|
|
730
|
-
_verifyNoOptionValueCollisions() {
|
|
731
|
-
this.options.changes.pipe(startWith(this.options), takeUntil(this.destroyed)).subscribe(() => {
|
|
732
|
-
const isEqual = this.compareWith ?? Object.is;
|
|
733
|
-
for (let i = 0; i < this.options.length; i++) {
|
|
734
|
-
const option = this.options.get(i);
|
|
735
|
-
let duplicate = null;
|
|
736
|
-
for (let j = i + 1; j < this.options.length; j++) {
|
|
737
|
-
const other = this.options.get(j);
|
|
738
|
-
if (isEqual(option.value, other.value)) {
|
|
739
|
-
duplicate = other;
|
|
740
|
-
break;
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
if (duplicate) {
|
|
744
|
-
// TODO(mmalerba): Link to docs about this.
|
|
745
|
-
if (this.compareWith) {
|
|
746
|
-
console.warn(`Found multiple CdkOption representing the same value under the given compareWith function`, {
|
|
747
|
-
option1: option.element,
|
|
748
|
-
option2: duplicate.element,
|
|
749
|
-
compareWith: this.compareWith,
|
|
750
|
-
});
|
|
751
|
-
}
|
|
752
|
-
else {
|
|
753
|
-
console.warn(`Found multiple CdkOption with the same value`, {
|
|
754
|
-
option1: option.element,
|
|
755
|
-
option2: duplicate.element,
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
return;
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
});
|
|
762
|
-
}
|
|
763
|
-
/** Verifies that the option values are valid. */
|
|
764
|
-
_verifyOptionValues() {
|
|
765
|
-
if (this.options && (typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
766
|
-
const selected = this.selectionModel.selected;
|
|
767
|
-
const invalidValues = this._getInvalidOptionValues(selected);
|
|
768
|
-
if (!this.multiple && selected.length > 1) {
|
|
769
|
-
throw Error('Listbox cannot have more than one selected value in multi-selection mode.');
|
|
770
|
-
}
|
|
771
|
-
if (invalidValues.length) {
|
|
772
|
-
throw Error('Listbox has selected values that do not match any of its options.');
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
/**
|
|
777
|
-
* Coerces a value into an array representing a listbox selection.
|
|
778
|
-
* @param value The value to coerce
|
|
779
|
-
* @return An array
|
|
780
|
-
*/
|
|
781
|
-
_coerceValue(value) {
|
|
782
|
-
return value == null ? [] : coerceArray(value);
|
|
783
|
-
}
|
|
784
|
-
/**
|
|
785
|
-
* Get the sublist of values that do not represent valid option values in this listbox.
|
|
786
|
-
* @param values The list of values
|
|
787
|
-
* @return The sublist of values that are not valid option values
|
|
788
|
-
*/
|
|
789
|
-
_getInvalidOptionValues(values) {
|
|
790
|
-
const isEqual = this.compareWith || Object.is;
|
|
791
|
-
const validValues = (this.options || []).map(option => option.value);
|
|
792
|
-
return values.filter(value => !validValues.some(validValue => isEqual(value, validValue)));
|
|
793
|
-
}
|
|
794
|
-
/** Get the index of the last triggered option. */
|
|
795
|
-
_getLastTriggeredIndex() {
|
|
796
|
-
const index = this.options.toArray().indexOf(this._lastTriggered);
|
|
797
|
-
return index === -1 ? null : index;
|
|
798
|
-
}
|
|
799
|
-
/**
|
|
800
|
-
* Set previous active option as active option on window blur.
|
|
801
|
-
* This ensures that the `activeOption` matches the actual focused element when the user returns to the document.
|
|
802
|
-
*/
|
|
803
|
-
_setPreviousActiveOptionAsActiveOptionOnWindowBlur() {
|
|
804
|
-
this.ngZone.runOutsideAngular(() => {
|
|
805
|
-
fromEvent(window, 'blur')
|
|
806
|
-
.pipe(takeUntil(this.destroyed))
|
|
807
|
-
.subscribe(() => {
|
|
808
|
-
if (this.element.contains(document.activeElement) && this._previousActiveOption) {
|
|
809
|
-
this._setActiveOption(this._previousActiveOption);
|
|
810
|
-
this._previousActiveOption = null;
|
|
811
|
-
}
|
|
812
|
-
});
|
|
813
|
-
});
|
|
814
|
-
}
|
|
815
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: CdkListbox, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
816
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "18.2.0-next.2", type: CdkListbox, isStandalone: true, selector: "[cdkListbox]", inputs: { id: "id", enabledTabIndex: ["tabindex", "enabledTabIndex"], value: ["cdkListboxValue", "value"], multiple: ["cdkListboxMultiple", "multiple", booleanAttribute], disabled: ["cdkListboxDisabled", "disabled", booleanAttribute], useActiveDescendant: ["cdkListboxUseActiveDescendant", "useActiveDescendant", booleanAttribute], orientation: ["cdkListboxOrientation", "orientation"], compareWith: ["cdkListboxCompareWith", "compareWith"], navigationWrapDisabled: ["cdkListboxNavigationWrapDisabled", "navigationWrapDisabled", booleanAttribute], navigateDisabledOptions: ["cdkListboxNavigatesDisabledOptions", "navigateDisabledOptions", booleanAttribute] }, outputs: { valueChange: "cdkListboxValueChange" }, host: { attributes: { "role": "listbox" }, listeners: { "focus": "_handleFocus()", "keydown": "_handleKeydown($event)", "focusout": "_handleFocusOut($event)", "focusin": "_handleFocusIn()" }, properties: { "id": "id", "attr.tabindex": "_getTabIndex()", "attr.aria-disabled": "disabled", "attr.aria-multiselectable": "multiple", "attr.aria-activedescendant": "_getAriaActiveDescendant()", "attr.aria-orientation": "orientation" }, classAttribute: "cdk-listbox" }, providers: [
|
|
817
|
-
{
|
|
818
|
-
provide: NG_VALUE_ACCESSOR,
|
|
819
|
-
useExisting: forwardRef(() => CdkListbox),
|
|
820
|
-
multi: true,
|
|
821
|
-
},
|
|
822
|
-
], queries: [{ propertyName: "options", predicate: CdkOption, descendants: true }], exportAs: ["cdkListbox"], ngImport: i0 }); }
|
|
823
|
-
}
|
|
824
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: CdkListbox, decorators: [{
|
|
825
|
-
type: Directive,
|
|
826
|
-
args: [{
|
|
827
|
-
selector: '[cdkListbox]',
|
|
828
|
-
standalone: true,
|
|
829
|
-
exportAs: 'cdkListbox',
|
|
830
|
-
host: {
|
|
831
|
-
'role': 'listbox',
|
|
832
|
-
'class': 'cdk-listbox',
|
|
833
|
-
'[id]': 'id',
|
|
834
|
-
'[attr.tabindex]': '_getTabIndex()',
|
|
835
|
-
'[attr.aria-disabled]': 'disabled',
|
|
836
|
-
'[attr.aria-multiselectable]': 'multiple',
|
|
837
|
-
'[attr.aria-activedescendant]': '_getAriaActiveDescendant()',
|
|
838
|
-
'[attr.aria-orientation]': 'orientation',
|
|
839
|
-
'(focus)': '_handleFocus()',
|
|
840
|
-
'(keydown)': '_handleKeydown($event)',
|
|
841
|
-
'(focusout)': '_handleFocusOut($event)',
|
|
842
|
-
'(focusin)': '_handleFocusIn()',
|
|
843
|
-
},
|
|
844
|
-
providers: [
|
|
845
|
-
{
|
|
846
|
-
provide: NG_VALUE_ACCESSOR,
|
|
847
|
-
useExisting: forwardRef(() => CdkListbox),
|
|
848
|
-
multi: true,
|
|
849
|
-
},
|
|
850
|
-
],
|
|
851
|
-
}]
|
|
852
|
-
}], ctorParameters: () => [], propDecorators: { id: [{
|
|
853
|
-
type: Input
|
|
854
|
-
}], enabledTabIndex: [{
|
|
855
|
-
type: Input,
|
|
856
|
-
args: ['tabindex']
|
|
857
|
-
}], value: [{
|
|
858
|
-
type: Input,
|
|
859
|
-
args: ['cdkListboxValue']
|
|
860
|
-
}], multiple: [{
|
|
861
|
-
type: Input,
|
|
862
|
-
args: [{ alias: 'cdkListboxMultiple', transform: booleanAttribute }]
|
|
863
|
-
}], disabled: [{
|
|
864
|
-
type: Input,
|
|
865
|
-
args: [{ alias: 'cdkListboxDisabled', transform: booleanAttribute }]
|
|
866
|
-
}], useActiveDescendant: [{
|
|
867
|
-
type: Input,
|
|
868
|
-
args: [{ alias: 'cdkListboxUseActiveDescendant', transform: booleanAttribute }]
|
|
869
|
-
}], orientation: [{
|
|
870
|
-
type: Input,
|
|
871
|
-
args: ['cdkListboxOrientation']
|
|
872
|
-
}], compareWith: [{
|
|
873
|
-
type: Input,
|
|
874
|
-
args: ['cdkListboxCompareWith']
|
|
875
|
-
}], navigationWrapDisabled: [{
|
|
876
|
-
type: Input,
|
|
877
|
-
args: [{ alias: 'cdkListboxNavigationWrapDisabled', transform: booleanAttribute }]
|
|
878
|
-
}], navigateDisabledOptions: [{
|
|
879
|
-
type: Input,
|
|
880
|
-
args: [{ alias: 'cdkListboxNavigatesDisabledOptions', transform: booleanAttribute }]
|
|
881
|
-
}], valueChange: [{
|
|
882
|
-
type: Output,
|
|
883
|
-
args: ['cdkListboxValueChange']
|
|
884
|
-
}], options: [{
|
|
885
|
-
type: ContentChildren,
|
|
886
|
-
args: [CdkOption, { descendants: true }]
|
|
887
|
-
}] } });
|
|
888
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdGJveC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jZGsvbGlzdGJveC9saXN0Ym94LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQywwQkFBMEIsRUFBc0MsTUFBTSxtQkFBbUIsQ0FBQztBQUNsRyxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQ2xELE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUN4RCxPQUFPLEVBQ0wsQ0FBQyxFQUNELFVBQVUsRUFDVixHQUFHLEVBQ0gsS0FBSyxFQUNMLGNBQWMsRUFDZCxJQUFJLEVBQ0osVUFBVSxFQUNWLFdBQVcsRUFDWCxLQUFLLEVBQ0wsUUFBUSxHQUNULE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQy9DLE9BQU8sRUFFTCxnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2pCLGVBQWUsRUFDZixTQUFTLEVBQ1QsVUFBVSxFQUNWLFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFFTixNQUFNLEVBQ04sU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBdUIsaUJBQWlCLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2RSxPQUFPLEVBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQWMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ2xFLE9BQU8sRUFBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7O0FBRTVFLHNEQUFzRDtBQUN0RCxJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFFZjs7Ozs7OztH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LEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFDO2dCQUt4RSxXQUFXO3NCQURkLEtBQUs7dUJBQUMsdUJBQXVCO2dCQWdCMUIsV0FBVztzQkFEZCxLQUFLO3VCQUFDLHVCQUF1QjtnQkFhMUIsc0JBQXNCO3NCQUR6QixLQUFLO3VCQUFDLEVBQUMsS0FBSyxFQUFFLGtDQUFrQyxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBQztnQkFZM0UsdUJBQXVCO3NCQUQxQixLQUFLO3VCQUFDLEVBQUMsS0FBSyxFQUFFLG9DQUFvQyxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBQztnQkFhdkMsV0FBVztzQkFBcEQsTUFBTTt1QkFBQyx1QkFBdUI7Z0JBRzRCLE9BQU87c0JBQWpFLGVBQWU7dUJBQUMsU0FBUyxFQUFFLEVBQUMsV0FBVyxFQUFFLElBQUksRUFBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0FjdGl2ZURlc2NlbmRhbnRLZXlNYW5hZ2VyLCBIaWdobGlnaHRhYmxlLCBMaXN0S2V5TWFuYWdlck9wdGlvbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL2ExMXknO1xuaW1wb3J0IHtEaXJlY3Rpb25hbGl0eX0gZnJvbSAnQGFuZ3VsYXIvY2RrL2JpZGknO1xuaW1wb3J0IHtjb2VyY2VBcnJheX0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvZXJjaW9uJztcbmltcG9ydCB7U2VsZWN0aW9uTW9kZWx9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XG5pbXBvcnQge1xuICBBLFxuICBET1dOX0FSUk9XLFxuICBFTkQsXG4gIEVOVEVSLFxuICBoYXNNb2RpZmllcktleSxcbiAgSE9NRSxcbiAgTEVGVF9BUlJPVyxcbiAgUklHSFRfQVJST1csXG4gIFNQQUNFLFxuICBVUF9BUlJPVyxcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7UGxhdGZvcm19IGZyb20gJ0Bhbmd1bGFyL2Nkay9wbGF0Zm9ybSc7XG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBib29sZWFuQXR0cmlidXRlLFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29udGVudENoaWxkcmVuLFxuICBEaXJlY3RpdmUsXG4gIEVsZW1lbnRSZWYsXG4gIGZvcndhcmRSZWYsXG4gIGluamVjdCxcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25EZXN0cm95LFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0NvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtkZWZlciwgZnJvbUV2ZW50LCBtZXJnZSwgT2JzZXJ2YWJsZSwgU3ViamVjdH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge2ZpbHRlciwgbWFwLCBzdGFydFdpdGgsIHN3aXRjaE1hcCwgdGFrZVVudGlsfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbi8qKiBUaGUgbmV4dCBpZCB0byB1c2UgZm9yIGNyZWF0aW5nIHVuaXF1ZSBET00gSURzLiAqL1xubGV0IG5leHRJZCA9IDA7XG5cbi8qKlxuICogQW4gaW1wbGVtZW50YXRpb24gb2YgU2VsZWN0aW9uTW9kZWwgdGhhdCBpbnRlcm5hbGx5IGFsd2F5cyByZXByZXNlbnRzIHRoZSBzZWxlY3Rpb24gYXMgYVxuICogbXVsdGktc2VsZWN0aW9uLiBUaGlzIGlzIG5lY2Vzc2FyeSBzbyB0aGF0IHdlIGNhbiByZWNvdmVyIHRoZSBmdWxsIHNlbGVjdGlvbiBpZiB0aGUgdXNlclxuICogc3dpdGNoZXMgdGhlIGxpc3Rib3ggZnJvbSBzaW5nbGUtc2VsZWN0aW9uIHRvIG11bHRpLXNlbGVjdGlvbiBhZnRlciBpbml0aWFsaXphdGlvbi5cbiAqXG4gKiBUaGlzIHNlbGVjdGlvbiBtb2RlbCBtYXkgcmVwb3J0IG11bHRpcGxlIHNlbGVjdGVkIHZhbHVlcywgZXZlbiBpZiBpdCBpcyBpbiBzaW5nbGUtc2VsZWN0aW9uXG4gKiBtb2RlLiBJdCBpcyB1cCB0byB0aGUgdXNlciAoQ2RrTGlzdGJveCkgdG8gY2hlY2sgZm9yIGludmFsaWQgc2VsZWN0aW9ucy5cbiAqL1xuY2xhc3MgTGlzdGJveFNlbGVjdGlvbk1vZGVsPFQ+IGV4dGVuZHMgU2VsZWN0aW9uTW9kZWw8VD4ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgbXVsdGlwbGUgPSBmYWxzZSxcbiAgICBpbml0aWFsbHlTZWxlY3RlZFZhbHVlcz86IFRbXSxcbiAgICBlbWl0Q2hhbmdlcyA9IHRydWUsXG4gICAgY29tcGFyZVdpdGg/OiAobzE6IFQsIG8yOiBUKSA9PiBib29sZWFuLFxuICApIHtcbiAgICBzdXBlcih0cnVlLCBpbml0aWFsbHlTZWxlY3RlZFZhbHVlcywgZW1pdENoYW5nZXMsIGNvbXBhcmVXaXRoKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGlzTXVsdGlwbGVTZWxlY3Rpb24oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubXVsdGlwbGU7XG4gIH1cblxuICBvdmVycmlkZSBzZWxlY3QoLi4udmFsdWVzOiBUW10pIHtcbiAgICAvLyBUaGUgc3VwZXIgY2xhc3MgaXMgYWx3YXlzIGluIG11bHRpLXNlbGVjdGlvbiBtb2RlLCBzbyB3ZSBuZWVkIHRvIG92ZXJyaWRlIHRoZSBiZWhhdmlvciBpZlxuICAgIC8vIHRoaXMgc2VsZWN0aW9uIG1vZGVsIGFjdHVhbGx5IGJlbG9uZ3MgdG8gYSBzaW5nbGUtc2VsZWN0aW9uIGxpc3Rib3guXG4gICAgaWYgKHRoaXMubXVsdGlwbGUpIHtcbiAgICAgIHJldHVybiBzdXBlci5zZWxlY3QoLi4udmFsdWVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHN1cGVyLnNldFNlbGVjdGlvbiguLi52YWx1ZXMpO1xuICAgIH1cbiAgfVxufVxuXG4vKiogQSBzZWxlY3RhYmxlIG9wdGlvbiBpbiBhIGxpc3Rib3guICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbY2RrT3B0aW9uXScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGV4cG9ydEFzOiAnY2RrT3B0aW9uJyxcbiAgaG9zdDoge1xuICAgICdyb2xlJzogJ29wdGlvbicsXG4gICAgJ2NsYXNzJzogJ2Nkay1vcHRpb24nLFxuICAgICdbaWRdJzogJ2lkJyxcbiAgICAnW2F0dHIuYXJpYS1zZWxlY3RlZF0nOiAnaXNTZWxlY3RlZCgpJyxcbiAgICAnW2F0dHIudGFiaW5kZXhdJzogJ19nZXRUYWJJbmRleCgpJyxcbiAgICAnW2F0dHIuYXJpYS1kaXNhYmxlZF0nOiAnZGlzYWJsZWQnLFxuICAgICdbY2xhc3MuY2RrLW9wdGlvbi1hY3RpdmVdJzogJ2lzQWN0aXZlKCknLFxuICAgICcoY2xpY2spJzogJ19jbGlja2VkLm5leHQoJGV2ZW50KScsXG4gICAgJyhmb2N1cyknOiAnX2hhbmRsZUZvY3VzKCknLFxuICB9LFxufSlcbmV4cG9ydCBjbGFzcyBDZGtPcHRpb248VCA9IHVua25vd24+IGltcGxlbWVudHMgTGlzdEtleU1hbmFnZXJPcHRpb24sIEhpZ2hsaWdodGFibGUsIE9uRGVzdHJveSB7XG4gIC8qKiBUaGUgaWQgb2YgdGhlIG9wdGlvbidzIGhvc3QgZWxlbWVudC4gKi9cbiAgQElucHV0KClcbiAgZ2V0IGlkKCkge1xuICAgIHJldHVybiB0aGlzLl9pZCB8fCB0aGlzLl9nZW5lcmF0ZWRJZDtcbiAgfVxuICBzZXQgaWQodmFsdWUpIHtcbiAgICB0aGlzLl9pZCA9IHZhbHVlO1xuICB9XG4gIHByaXZhdGUgX2lkOiBzdHJpbmc7XG4gIHByaXZhdGUgX2dlbmVyYXRlZElkID0gYGNkay1vcHRpb24tJHtuZXh0SWQrK31gO1xuXG4gIC8qKiBUaGUgdmFsdWUgb2YgdGhpcyBvcHRpb24uICovXG4gIEBJbnB1dCgnY2RrT3B0aW9uJykgdmFsdWU6IFQ7XG5cbiAgLyoqXG4gICAqIFRoZSB0ZXh0IHVzZWQgdG8gbG9jYXRlIHRoaXMgaXRlbSBkdXJpbmcgbGlzdGJveCB0eXBlYWhlYWQuIElmIG5vdCBzcGVjaWZpZWQsXG4gICAqIHRoZSBgdGV4dENvbnRlbnRgIG9mIHRoZSBpdGVtIHdpbGwgYmUgdXNlZC5cbiAgICovXG4gIEBJbnB1dCgnY2RrT3B0aW9uVHlwZWFoZWFkTGFiZWwnKSB0eXBlYWhlYWRMYWJlbDogc3RyaW5nIHwgbnVsbDtcblxuICAvKiogV2hldGhlciB0aGlzIG9wdGlvbiBpcyBkaXNhYmxlZC4gKi9cbiAgQElucHV0KHthbGlhczogJ2Nka09wdGlvbkRpc2FibGVkJywgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlfSlcbiAgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmxpc3Rib3guZGlzYWJsZWQgfHwgdGhpcy5fZGlzYWJsZWQ7XG4gIH1cbiAgc2V0IGRpc2FibGVkKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fZGlzYWJsZWQgPSB2YWx1ZTtcbiAgfVxuICBwcml2YXRlIF9kaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBUaGUgdGFiaW5kZXggb2YgdGhlIG9wdGlvbiB3aGVuIGl0IGlzIGVuYWJsZWQuICovXG4gIEBJbnB1dCgndGFiaW5kZXgnKVxuICBnZXQgZW5hYmxlZFRhYkluZGV4KCkge1xuICAgIHJldHVybiB0aGlzLl9lbmFibGVkVGFiSW5kZXggPT09IHVuZGVmaW5lZFxuICAgICAgPyB0aGlzLmxpc3Rib3guZW5hYmxlZFRhYkluZGV4XG4gICAgICA6IHRoaXMuX2VuYWJsZWRUYWJJbmRleDtcbiAgfVxuICBzZXQgZW5hYmxlZFRhYkluZGV4KHZhbHVlKSB7XG4gICAgdGhpcy5fZW5hYmxlZFRhYkluZGV4ID0gdmFsdWU7XG4gIH1cbiAgcHJpdmF0ZSBfZW5hYmxlZFRhYkluZGV4PzogbnVtYmVyIHwgbnVsbDtcblxuICAvKiogVGhlIG9wdGlvbidzIGhvc3QgZWxlbWVudCAqL1xuICByZWFkb25seSBlbGVtZW50OiBIVE1MRWxlbWVudCA9IGluamVjdChFbGVtZW50UmVmKS5uYXRpdmVFbGVtZW50O1xuXG4gIC8qKiBUaGUgcGFyZW50IGxpc3Rib3ggdGhpcyBvcHRpb24gYmVsb25ncyB0by4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGxpc3Rib3g6IENka0xpc3Rib3g8VD4gPSBpbmplY3QoQ2RrTGlzdGJveCk7XG5cbiAgLyoqIEVtaXRzIHdoZW4gdGhlIG9wdGlvbiBpcyBkZXN0cm95ZWQuICovXG4gIHByb3RlY3RlZCBkZXN0cm95ZWQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIC8qKiBFbWl0cyB3aGVuIHRoZSBvcHRpb24gaXMgY2xpY2tlZC4gKi9cbiAgcmVhZG9ubHkgX2NsaWNrZWQgPSBuZXcgU3ViamVjdDxNb3VzZUV2ZW50PigpO1xuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuZGVzdHJveWVkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3llZC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhpcyBvcHRpb24gaXMgc2VsZWN0ZWQuICovXG4gIGlzU2VsZWN0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdGJveC5pc1NlbGVjdGVkKHRoaXMpO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhpcyBvcHRpb24gaXMgYWN0aXZlLiAqL1xuICBpc0FjdGl2ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5saXN0Ym94LmlzQWN0aXZlKHRoaXMpO1xuICB9XG5cbiAgLyoqIFRvZ2dsZSB0aGUgc2VsZWN0ZWQgc3RhdGUgb2YgdGhpcyBvcHRpb24uICovXG4gIHRvZ2dsZSgpIHtcbiAgICB0aGlzLmxpc3Rib3gudG9nZ2xlKHRoaXMpO1xuICB9XG5cbiAgLyoqIFNlbGVjdCB0aGlzIG9wdGlvbiBpZiBpdCBpcyBub3Qgc2VsZWN0ZWQuICovXG4gIHNlbGVjdCgpIHtcbiAgICB0aGlzLmxpc3Rib3guc2VsZWN0KHRoaXMpO1xuICB9XG5cbiAgLyoqIERlc2VsZWN0IHRoaXMgb3B0aW9uIGlmIGl0IGlzIHNlbGVjdGVkLiAqL1xuICBkZXNlbGVjdCgpIHtcbiAgICB0aGlzLmxpc3Rib3guZGVzZWxlY3QodGhpcyk7XG4gIH1cblxuICAvKiogRm9jdXMgdGhpcyBvcHRpb24uICovXG4gIGZvY3VzKCkge1xuICAgIHRoaXMuZWxlbWVudC5mb2N1cygpO1xuICB9XG5cbiAgLyoqIEdldCB0aGUgbGFiZWwgZm9yIHRoaXMgZWxlbWVudCB3aGljaCBpcyByZXF1aXJlZCBieSB0aGUgRm9jdXNhYmxlT3B0aW9uIGludGVyZmFjZS4gKi9cbiAgZ2V0TGFiZWwoKSB7XG4gICAgcmV0dXJuICh0aGlzLnR5cGVhaGVhZExhYmVsID8/IHRoaXMuZWxlbWVudC50ZXh0Q29udGVudD8udHJpbSgpKSB8fCAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBOby1vcCBpbXBsZW1lbnRlZCBhcyBhIHBhcnQgb2YgYEhpZ2hsaWdodGFibGVgLlxuICAgKiBAZG9jcy1wcml2YXRlXG4gICAqL1xuICBzZXRBY3RpdmVTdHlsZXMoKSB7fVxuXG4gIC8qKlxuICAgKiBOby1vcCBpbXBsZW1lbnRlZCBhcyBhIHBhcnQgb2YgYEhpZ2hsaWdodGFibGVgLlxuICAgKiBAZG9jcy1wcml2YXRlXG4gICAqL1xuICBzZXRJbmFjdGl2ZVN0eWxlcygpIHt9XG5cbiAgLyoqIEhhbmRsZSBmb2N1cyBldmVudHMgb24gdGhlIG9wdGlvbi4gKi9cbiAgcHJvdGVjdGVkIF9oYW5kbGVGb2N1cygpIHtcbiAgICAvLyBPcHRpb25zIGNhbiB3aW5kIHVwIGdldHRpbmcgZm9jdXNlZCBpbiBhY3RpdmUgZGVzY2VuZGFudCBtb2RlIGlmIHRoZSB1c2VyIGNsaWNrcyBvbiB0aGVtLlxuICAgIC8vIEluIHRoaXMgY2FzZSwgd2UgcHVzaCBmb2N1cyBiYWNrIHRvIHRoZSBwYXJlbnQgbGlzdGJveCB0byBwcmV2ZW50IGFuIGV4dHJhIHRhYiBzdG9wIHdoZW5cbiAgICAvLyB0aGUgdXNlciBwZXJmb3JtcyBhIHNoaWZ0K3RhYi5cbiAgICBpZiAodGhpcy5saXN0Ym94LnVzZUFjdGl2ZURlc2NlbmRhbnQpIHtcbiAgICAgIHRoaXMubGlzdGJveC5fc2V0QWN0aXZlT3B0aW9uKHRoaXMpO1xuICAgICAgdGhpcy5saXN0Ym94LmZvY3VzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEdldCB0aGUgdGFiaW5kZXggZm9yIHRoaXMgb3B0aW9uLiAqL1xuICBwcm90ZWN0ZWQgX2dldFRhYkluZGV4KCkge1xuICAgIGlmICh0aGlzLmxpc3Rib3gudXNlQWN0aXZlRGVzY2VuZGFudCB8fCB0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzQWN0aXZlKCkgPyB0aGlzLmVuYWJsZWRUYWJJbmRleCA6IC0xO1xuICB9XG59XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tjZGtMaXN0Ym94XScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGV4cG9ydEFzOiAnY2RrTGlzdGJveCcsXG4gIGhvc3Q6IHtcbiAgICAncm9sZSc6ICdsaXN0Ym94JyxcbiAgICAnY2xhc3MnOiAnY2RrLWxpc3Rib3gnLFxuICAgICdbaWRdJzogJ2lkJyxcbiAgICAnW2F0dHIudGFiaW5kZXhdJzogJ19nZXRUYWJJbmRleCgpJyxcbiAgICAnW2F0dHIuYXJpYS1kaXNhYmxlZF0nOiAnZGlzYWJsZWQnLFxuICAgICdbYXR0ci5hcmlhLW11bHRpc2VsZWN0YWJsZV0nOiAnbXVsdGlwbGUnLFxuICAgICdbYXR0ci5hcmlhLWFjdGl2ZWRlc2NlbmRhbnRdJzogJ19nZXRBcmlhQWN0aXZlRGVzY2VuZGFudCgpJyxcbiAgICAnW2F0dHIuYXJpYS1vcmllbnRhdGlvbl0nOiAnb3JpZW50YXRpb24nLFxuICAgICcoZm9jdXMpJzogJ19oYW5kbGVGb2N1cygpJyxcbiAgICAnKGtleWRvd24pJzogJ19oYW5kbGVLZXlkb3duKCRldmVudCknLFxuICAgICcoZm9jdXNvdXQpJzogJ19oYW5kbGVGb2N1c091dCgkZXZlbnQpJyxcbiAgICAnKGZvY3VzaW4pJzogJ19oYW5kbGVGb2N1c0luKCknLFxuICB9LFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IENka0xpc3Rib3gpLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgfSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgQ2RrTGlzdGJveDxUID0gdW5rbm93bj4gaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBPbkRlc3Ryb3ksIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgLyoqIFRoZSBpZCBvZiB0aGUgb3B0aW9uJ3MgaG9zdCBlbGVtZW50LiAqL1xuICBASW5wdXQoKVxuICBnZXQgaWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lkIHx8IHRoaXMuX2dlbmVyYXRlZElkO1xuICB9XG4gIHNldCBpZCh2YWx1ZSkge1xuICAgIHRoaXMuX2lkID0gdmFsdWU7XG4gIH1cbiAgcHJpdmF0ZSBfaWQ6IHN0cmluZztcbiAgcHJpdmF0ZSBfZ2VuZXJhdGVkSWQgPSBgY2RrLWxpc3Rib3gtJHtuZXh0SWQrK31gO1xuXG4gIC8qKiBUaGUgdGFiaW5kZXggdG8gdXNlIHdoZW4gdGhlIGxpc3Rib3ggaXMgZW5hYmxlZC4gKi9cbiAgQElucHV0KCd0YWJpbmRleCcpXG4gIGdldCBlbmFibGVkVGFiSW5kZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2VuYWJsZWRUYWJJbmRleCA9PT0gdW5kZWZpbmVkID8gMCA6IHRoaXMuX2VuYWJsZWRUYWJJbmRleDtcbiAgfVxuICBzZXQgZW5hYmxlZFRhYkluZGV4KHZhbHVlKSB7XG4gICAgdGhpcy5fZW5hYmxlZFRhYkluZGV4ID0gdmFsdWU7XG4gIH1cbiAgcHJpdmF0ZSBfZW5hYmxlZFRhYkluZGV4PzogbnVtYmVyIHwgbnVsbDtcblxuICAvKiogVGhlIHZhbHVlIHNlbGVjdGVkIGluIHRoZSBsaXN0Ym94LCByZXByZXNlbnRlZCBhcyBhbiBhcnJheSBvZiBvcHRpb24gdmFsdWVzLiAqL1xuICBASW5wdXQoJ2Nka0xpc3Rib3hWYWx1ZScpXG4gIGdldCB2YWx1ZSgpOiByZWFkb25seSBUW10ge1xuICAgIHJldHVybiB0aGlzLl9pbnZhbGlkID8gW10gOiB0aGlzLnNlbGVjdGlvbk1vZGVsLnNlbGVjdGVkO1xuICB9XG4gIHNldCB2YWx1ZSh2YWx1ZTogcmVhZG9ubHkgVFtdKSB7XG4gICAgdGhpcy5fc2V0U2VsZWN0aW9uKHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBsaXN0Ym94IGFsbG93cyBtdWx0aXBsZSBvcHRpb25zIHRvIGJlIHNlbGVjdGVkLiBJZiB0aGUgdmFsdWUgc3dpdGNoZXMgZnJvbSBgdHJ1ZWBcbiAgICogdG8gYGZhbHNlYCwgYW5kIG1vcmUgdGhhbiBvbmUgb3B0aW9uIGlzIHNlbGVjdGVkLCBhbGwgb3B0aW9ucyBhcmUgZGVzZWxlY3RlZC5cbiAgICovXG4gIEBJbnB1dCh7YWxpYXM6ICdjZGtMaXN0Ym94TXVsdGlwbGUnLCB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGV9KVxuICBnZXQgbXVsdGlwbGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0aW9uTW9kZWwubXVsdGlwbGU7XG4gIH1cbiAgc2V0IG11bHRpcGxlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5zZWxlY3Rpb25Nb2RlbC5tdWx0aXBsZSA9IHZhbHVlO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucykge1xuICAgICAgdGhpcy5fdXBkYXRlSW50ZXJuYWxWYWx1ZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHRoZSBsaXN0Ym94IGlzIGRpc2FibGVkLiAqL1xuICBASW5wdXQoe2FsaWFzOiAnY2RrTGlzdGJveERpc2FibGVkJywgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlfSlcbiAgZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKiogV2hldGhlciB0aGUgbGlzdGJveCB3aWxsIHVzZSBhY3RpdmUgZGVzY2VuZGFudCBvciB3aWxsIG1vdmUgZm9jdXMgb250byB0aGUgb3B0aW9ucy4gKi9cbiAgQElucHV0KHthbGlhczogJ2Nka0xpc3Rib3hVc2VBY3RpdmVEZXNjZW5kYW50JywgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlfSlcbiAgdXNlQWN0aXZlRGVzY2VuZGFudDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBUaGUgb3JpZW50YXRpb24gb2YgdGhlIGxpc3Rib3guIE9ubHkgYWZmZWN0cyBrZXlib2FyZCBpbnRlcmFjdGlvbiwgbm90IHZpc3VhbCBsYXlvdXQuICovXG4gIEBJbnB1dCgnY2RrTGlzdGJveE9yaWVudGF0aW9uJylcbiAgZ2V0IG9yaWVudGF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl9vcmllbnRhdGlvbjtcbiAgfVxuICBzZXQgb3JpZW50YXRpb24odmFsdWU6ICdob3Jpem9udGFsJyB8ICd2ZXJ0aWNhbCcpIHtcbiAgICB0aGlzLl9vcmllbnRhdGlvbiA9IHZhbHVlID09PSAnaG9yaXpvbnRhbCcgPyAnaG9yaXpvbnRhbCcgOiAndmVydGljYWwnO1xuICAgIGlmICh2YWx1ZSA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICB0aGlzLmxpc3RLZXlNYW5hZ2VyPy53aXRoSG9yaXpvbnRhbE9yaWVudGF0aW9uKHRoaXMuX2Rpcj8udmFsdWUgfHwgJ2x0cicpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxpc3RLZXlNYW5hZ2VyPy53aXRoVmVydGljYWxPcmllbnRhdGlvbigpO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIF9vcmllbnRhdGlvbjogJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJyA9ICd2ZXJ0aWNhbCc7XG5cbiAgLyoqIFRoZSBmdW5jdGlvbiB1c2VkIHRvIGNvbXBhcmUgb3B0aW9uIHZhbHVlcy4gKi9cbiAgQElucHV0KCdjZGtMaXN0Ym94Q29tcGFyZVdpdGgnKVxuICBnZXQgY29tcGFyZVdpdGgoKTogdW5kZWZpbmVkIHwgKChvMTogVCwgbzI6IFQpID0+IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb25Nb2RlbC5jb21wYXJlV2l0aDtcbiAgfVxuICBzZXQgY29tcGFyZVdpdGgoZm46IHVuZGVmaW5lZCB8ICgobzE6IFQsIG8yOiBUKSA9PiBib29sZWFuKSkge1xuICAgIHRoaXMuc2VsZWN0aW9uTW9kZWwuY29tcGFyZVdpdGggPSBmbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBrZXlib2FyZCBuYXZpZ2F0aW9uIHNob3VsZCB3cmFwIHdoZW4gdGhlIHVzZXIgcHJlc3NlcyBhcnJvdyBkb3duIG9uIHRoZSBsYXN0IGl0ZW1cbiAgICogb3IgYXJyb3cgdXAgb24gdGhlIGZpcnN0IGl0ZW0uXG4gICAqL1xuICBASW5wdXQoe2FsaWFzOiAnY2RrTGlzdGJveE5hdmlnYXRpb25XcmFwRGlzYWJsZWQnLCB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGV9KVxuICBnZXQgbmF2aWdhdGlvbldyYXBEaXNhYmxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fbmF2aWdhdGlvbldyYXBEaXNhYmxlZDtcbiAgfVxuICBzZXQgbmF2aWdhdGlvbldyYXBEaXNhYmxlZCh3cmFwOiBib29sZWFuKSB7XG4gICAgdGhpcy5fbmF2aWdhdGlvbldyYXBEaXNhYmxlZCA9IHdyYXA7XG4gICAgdGhpcy5saXN0S2V5TWFuYWdlcj8ud2l0aFdyYXAoIXRoaXMuX25hdmlnYXRpb25XcmFwRGlzYWJsZWQpO1xuICB9XG4gIHByaXZhdGUgX25hdmlnYXRpb25XcmFwRGlzYWJsZWQgPSBmYWxzZTtcblxuICAvKiogV2hldGhlciBrZXlib2FyZCBuYXZpZ2F0aW9uIHNob3VsZCBza2lwIG92ZXIgZGlzYWJsZWQgaXRlbXMuICovXG4gIEBJbnB1dCh7YWxpYXM6ICdjZGtMaXN0Ym94TmF2aWdhdGVzRGlzYWJsZWRPcHRpb25zJywgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlfSlcbiAgZ2V0IG5hdmlnYXRlRGlzYWJsZWRPcHRpb25zKCkge1xuICAgIHJldHVybiB0aGlzLl9uYXZpZ2F0ZURpc2FibGVkT3B0aW9ucztcbiAgfVxuICBzZXQgbmF2aWdhdGVEaXNhYmxlZE9wdGlvbnMoc2tpcDogYm9vbGVhbikge1xuICAgIHRoaXMuX25hdmlnYXRlRGlzYWJsZWRPcHRpb25zID0gc2tpcDtcbiAgICB0aGlzLmxpc3RLZXlNYW5hZ2VyPy5za2lwUHJlZGljYXRlKFxuICAgICAgdGhpcy5fbmF2aWdhdGVEaXNhYmxlZE9wdGlvbnMgPyB0aGlzLl9za2lwTm9uZVByZWRpY2F0ZSA6IHRoaXMuX3NraXBEaXNhYmxlZFByZWRpY2F0ZSxcbiAgICApO1xuICB9XG4gIHByaXZhdGUgX25hdmlnYXRlRGlzYWJsZWRPcHRpb25zID0gZmFsc2U7XG5cbiAgLyoqIEVtaXRzIHdoZW4gdGhlIHNlbGVjdGVkIHZhbHVlKHMpIGluIHRoZSBsaXN0Ym94IGNoYW5nZS4gKi9cbiAgQE91dHB1dCgnY2RrTGlzdGJveFZhbHVlQ2hhbmdlJykgcmVhZG9ubHkgdmFsdWVDaGFuZ2UgPSBuZXcgU3ViamVjdDxMaXN0Ym94VmFsdWVDaGFuZ2VFdmVudDxUPj4oKTtcblxuICAvKiogVGhlIGNoaWxkIG9wdGlvbnMgaW4gdGhpcyBsaXN0Ym94LiAqL1xuICBAQ29udGVudENoaWxkcmVuKENka09wdGlvbiwge2Rlc2NlbmRhbnRzOiB0cnVlfSkgcHJvdGVjdGVkIG9wdGlvbnM6IFF1ZXJ5TGlzdDxDZGtPcHRpb248VD4+O1xuXG4gIC8qKiBUaGUgc2VsZWN0aW9uIG1vZGVsIHVzZWQgYnkgdGhlIGxpc3Rib3guICovXG4gIHByb3RlY3RlZCBzZWxlY3Rpb25Nb2RlbCA9IG5ldyBMaXN0Ym94U2VsZWN0aW9uTW9kZWw8VD4oKTtcblxuICAvKiogVGhlIGtleSBtYW5hZ2VyIHRoYXQgbWFuYWdlcyBrZXlib2FyZCBuYXZpZ2F0aW9uIGZvciB0aGlzIGxpc3Rib3guICovXG4gIHByb3RlY3RlZCBsaXN0S2V5TWFuYWdlcjogQWN0aXZlRGVzY2VuZGFudEtleU1hbmFnZXI8Q2RrT3B0aW9uPFQ+PjtcblxuICAvKiogRW1pdHMgd2hlbiB0aGUgbGlzdGJveCBpcyBkZXN0cm95ZWQuICovXG4gIHByb3RlY3RlZCByZWFkb25seSBkZXN0cm95ZWQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIC8qKiBUaGUgaG9zdCBlbGVtZW50IG9mIHRoZSBsaXN0Ym94LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZWxlbWVudDogSFRNTEVsZW1lbnQgPSBpbmplY3QoRWxlbWVudFJlZikubmF0aXZlRWxlbWVudDtcblxuICAvKiogVGhlIEFuZ3VsYXIgem9uZS4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG5nWm9uZSA9IGluamVjdChOZ1pvbmUpO1xuXG4gIC8qKiBUaGUgY2hhbmdlIGRldGVjdG9yIGZvciB0aGlzIGxpc3Rib3guICovXG4gIHByb3RlY3RlZCByZWFkb25seSBjaGFuZ2VEZXRlY3RvclJlZiA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgLyoqIFdoZXRoZXIgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCB2YWx1ZSBpbiB0aGUgc2VsZWN0aW9uIG1vZGVsIGlzIGludmFsaWQuICovXG4gIHByaXZhdGUgX2ludmFsaWQgPSBmYWxzZTtcblxuICAvKiogVGhlIGxhc3QgdXNlci10cmlnZ2VyZWQgb3B0aW9uLiAqL1xuICBwcml2YXRlIF9sYXN0VHJpZ2dlcmVkOiBDZGtPcHRpb248VD4gfCBudWxsID0gbnVsbDtcblxuICAvKiogQ2FsbGJhY2sgY2FsbGVkIHdoZW4gdGhlIGxpc3Rib3ggaGFzIGJlZW4gdG91Y2hlZCAqL1xuICBwcml2YXRlIF9vblRvdWNoZWQgPSAoKSA9PiB7fTtcblxuICAvKiogQ2FsbGJhY2sgY2FsbGVkIHdoZW4gdGhlIGxpc3Rib3ggdmFsdWUgY2hhbmdlcyAqL1xuICBwcml2YXRlIF9vbkNoYW5nZTogKHZhbHVlOiByZWFkb25seSBUW10pID0+IHZvaWQgPSAoKSA9PiB7fTtcblxuICAvKiogRW1pdHMgd2hlbiBhbiBvcHRpb24gaGFzIGJlZW4gY2xpY2tlZC4gKi9cbiAgcHJpdmF0ZSBfb3B0aW9uQ2xpY2tlZCA9IGRlZmVyKCgpID0+XG4gICAgKHRoaXMub3B0aW9ucy5jaGFuZ2VzIGFzIE9ic2VydmFibGU8Q2RrT3B0aW9uPFQ+W10+KS5waXBlKFxuICAgICAgc3RhcnRXaXRoKHRoaXMub3B0aW9ucyksXG4gICAgICBzd2l0Y2hNYXAob3B0aW9ucyA9PlxuICAgICAgICBtZXJnZSguLi5vcHRpb25zLm1hcChvcHRpb24gPT4gb3B0aW9uLl9jbGlja2VkLnBpcGUobWFwKGV2ZW50ID0+ICh7b3B0aW9uLCBldmVudH0pKSkpKSxcbiAgICAgICksXG4gICAgKSxcbiAgKTtcblxuICAvKiogVGhlIGRpcmVjdGlvbmFsaXR5IG9mIHRoZSBwYWdlLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9kaXIgPSBpbmplY3QoRGlyZWN0aW9uYWxpdHksIHtvcHRpb25hbDogdHJ1ZX0pO1xuXG4gIC8qKiBXaGV0aGVyIHRoZSBjb21wb25lbnQgaXMgYmVpbmcgcmVuZGVyZWQgaW4gdGhlIGJyb3dzZXIuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgX2lzQnJvd3NlcjogYm9vbGVhbiA9IGluamVjdChQbGF0Zm9ybSkuaXNCcm93c2VyO1xuXG4gIC8qKiBBIHByZWRpY2F0ZSB0aGF0IHNraXBzIGRpc2FibGVkIG9wdGlvbnMuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgX3NraXBEaXNhYmxlZFByZWRpY2F0ZSA9IChvcHRpb246IENka09wdGlvbjxUPikgPT4gb3B0aW9uLmRpc2FibGVkO1xuXG4gIC8qKiBBIHByZWRpY2F0ZSB0aGF0IGRvZXMgbm90IHNraXAgYW55IG9wdGlvbnMuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgX3NraXBOb25lUHJlZGljYXRlID0gKCkgPT4gZmFsc2U7XG5cbiAgLyoqIFdoZXRoZXIgdGhlIGxpc3Rib3ggY3VycmVudGx5IGhhcyBmb2N1cy4gKi9cbiAgcHJpdmF0ZSBfaGFzRm9jdXMgPSBmYWxzZTtcblxuICAvKiogQSByZWZlcmVuY2UgdG8gdGhlIG9wdGlvbiB0aGF0IHdhcyBhY3RpdmUgYmVmb3JlIHRoZSBsaXN0Ym94IGxvc3QgZm9jdXMuICovXG4gIHByaXZhdGUgX3ByZXZpb3VzQWN0aXZlT3B0aW9uOiBDZGtPcHRpb248VD4gfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBpZiAodGhpcy5faXNCcm93c2VyKSB7XG4gICAgICB0aGlzLl9zZXRQcmV2aW91c0FjdGl2ZU9wdGlvbkFzQWN0aXZlT3B0aW9uT25XaW5kb3dCbHVyKCk7XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgIGlmICh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpIHtcbiAgICAgIHRoaXMuX3ZlcmlmeU5vT3B0aW9uVmFsdWVDb2xsaXNpb25zKCk7XG4gICAgICB0aGlzLl92ZXJpZnlPcHRpb25WYWx1ZXMoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9pbml0S2V5TWFuYWdlcigpO1xuXG4gICAgLy8gVXBkYXRlIHRoZSBpbnRlcm5hbCB2YWx1ZSB3aGVuZXZlciB0aGUgb3B0aW9ucyBvciB0aGUgbW9kZWwgdmFsdWUgY2hhbmdlcy5cbiAgICBtZXJnZSh0aGlzLnNlbGVjdGlvbk1vZGVsLmNoYW5nZWQsIHRoaXMub3B0aW9ucy5jaGFuZ2VzKVxuICAgICAgLnBpcGUoc3RhcnRXaXRoKG51bGwpLCB0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLl91cGRhdGVJbnRlcm5hbFZhbHVlKCkpO1xuXG4gICAgdGhpcy5fb3B0aW9uQ2xpY2tlZFxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcigoe29wdGlvbn0pID0+ICFvcHRpb24uZGlzYWJsZWQpLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoe29wdGlvbiwgZXZlbnR9KSA9PiB0aGlzLl9oYW5kbGVPcHRpb25DbGlja2VkKG9wdGlvbiwgZXZlbnQpKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMubGlzdEtleU1hbmFnZXI/LmRlc3Ryb3koKTtcbiAgICB0aGlzLmRlc3Ryb3llZC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95ZWQuY29tcGxldGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUb2dnbGUgdGhlIHNlbGVjdGVkIHN0YXRlIG9mIHRoZSBnaXZlbiBvcHRpb24uXG4gICAqIEBwYXJhbSBvcHRpb24gVGhlIG9wdGlvbiB0byB0b2dnbGVcbiAgICovXG4gIHRvZ2dsZShvcHRpb246IENka09wdGlvbjxUPikge1xuICAgIHRoaXMudG9nZ2xlVmFsdWUob3B0aW9uLnZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUb2dnbGUgdGhlIHNlbGVjdGVkIHN0YXRlIG9mIHRoZSBnaXZlbiB2YWx1ZS5cbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byB0b2dnbGVcbiAgICovXG4gIHRvZ2dsZVZhbHVlKHZhbHVlOiBUKSB7XG4gICAgaWYgKHRoaXMuX2ludmFsaWQpIHtcbiAgICAgIHRoaXMuc2VsZWN0aW9uTW9kZWwuY2xlYXIoZmFsc2UpO1xuICAgIH1cbiAgICB0aGlzLnNlbGVjdGlvbk1vZGVsLnRvZ2dsZSh2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0IHRoZSBnaXZlbiBvcHRpb24uXG4gICAqIEBwYXJhbSBvcHRpb24gVGhlIG9wdGlvbiB0byBzZWxlY3RcbiAgICovXG4gIHNlbGVjdChvcHRpb246IENka09wdGlvbjxUPikge1xuICAgIHRoaXMuc2VsZWN0VmFsdWUob3B0aW9uLnZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3QgdGhlIGdpdmVuIHZhbHVlLlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlbGVjdFxuICAgKi9cbiAgc2VsZWN0VmFsdWUodmFsdWU6IFQpIHtcbiAgICBpZiAodGhpcy5faW52YWxpZCkge1xuICAgICAgdGhpcy5zZWxlY3Rpb25Nb2RlbC5jbGVhcihmYWxzZSk7XG4gICAgfVxuICAgIHRoaXMuc2VsZWN0aW9uTW9kZWwuc2VsZWN0KHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXNlbGVjdCB0aGUgZ2l2ZW4gb3B0aW9uLlxuICAgKiBAcGFyYW0gb3B0aW9uIFRoZSBvcHRpb24gdG8gZGVzZWxlY3RcbiAgICovXG4gIGRlc2VsZWN0KG9wdGlvbjogQ2RrT3B0aW9uPFQ+KSB7XG4gICAgdGhpcy5kZXNlbGVjdFZhbHVlKG9wdGlvbi52YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogRGVzZWxlY3QgdGhlIGdpdmVuIHZhbHVlLlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGRlc2VsZWN0XG4gICAqL1xuICBkZXNlbGVjdFZhbHVlKHZhbHVlOiBUKSB7XG4gICAgaWYgKHRoaXMuX2ludmFsaWQpIHtcbiAgICAgIHRoaXMuc2VsZWN0aW9uTW9kZWwuY2xlYXIoZmFsc2UpO1xuICAgIH1cbiAgICB0aGlzLnNlbGVjdGlvbk1vZGVsLmRlc2VsZWN0KHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHNlbGVjdGVkIHN0YXRlIG9mIGFsbCBvcHRpb25zLlxuICAgKiBAcGFyYW0gaXNTZWxlY3RlZCBUaGUgbmV3IHNlbGVjdGVkIHN0YXRlIHRvIHNldFxuICAgKi9cbiAgc2V0QWxsU2VsZWN0ZWQoaXNTZWxlY3RlZDogYm9vbGVhbikge1xuICAgIGlmICghaXNTZWxlY3RlZCkge1xuICAgICAgdGhpcy5zZWxlY3Rpb25Nb2RlbC5jbGVhcigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5faW52YWxpZCkge1xuICAgICAgICB0aGlzLnNlbGVjdGlvbk1vZGVsLmNsZWFyKGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2VsZWN0aW9uTW9kZWwuc2VsZWN0KC4uLnRoaXMub3B0aW9ucy5tYXAob3B0aW9uID0+IG9wdGlvbi52YWx1ZSkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgd2hldGhlciB0aGUgZ2l2ZW4gb3B0aW9uIGlzIHNlbGVjdGVkLlxuICAgKiBAcGFyYW0gb3B0aW9uIFRoZSBvcHRpb24gdG8gZ2V0IHRoZSBzZWxlY3RlZCBzdGF0ZSBvZlxuICAgKi9cbiAgaXNTZWxlY3RlZChvcHRpb246IENka09wdGlvbjxUPikge1xuICAgIHJldHVybiB0aGlzLmlzVmFsdWVTZWxlY3RlZChvcHRpb24udmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB3aGV0aGVyIHRoZSBnaXZlbiBvcHRpb24gaXMgYWN0aXZlLlxuICAgKiBAcGFyYW0gb3B0aW9uIFRoZSBvcHRpb24gdG8gZ2V0IHRoZSBhY3RpdmUgc3RhdGUgb2ZcbiAgICovXG4gIGlzQWN0aXZlKG9wdGlvbjogQ2RrT3B0aW9uPFQ+KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhKHRoaXMubGlzdEtleU1hbmFnZXI/LmFjdGl2ZUl0ZW0gPT09IG9wdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHdoZXRoZXIgdGhlIGdpdmVuIHZhbHVlIGlzIHNlbGVjdGVkLlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGdldCB0aGUgc2VsZWN0ZWQgc3RhdGUgb2ZcbiAgICovXG4gIGlzVmFsdWVTZWxlY3RlZCh2YWx1ZTogVCkge1xuICAgIGlmICh0aGlzLl9pbnZhbGlkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNlbGVjdGlvbk1vZGVsLmlzU2VsZWN0ZWQodmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBhIGNhbGxiYWNrIHRvIGJlIGludm9rZWQgd2hlbiB0aGUgbGlzdGJveCdzIHZhbHVlIGNoYW5nZXMgZnJvbSB1c2VyIGlucHV0LlxuICAgKiBAcGFyYW0gZm4gVGhlIGNhbGxiYWNrIHRvIHJlZ2lzdGVyXG4gICAqIEBkb2NzLXByaXZhdGVcbiAgICovXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46ICh2YWx1ZTogcmVhZG9ubHkgVFtdKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5fb25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYSBjYWxsYmFjayB0byBiZSBpbnZva2VkIHdoZW4gdGhlIGxpc3Rib3ggaXMgYmx1cnJlZCBieSB0aGUgdXNlci5cbiAgICogQHBhcmFtIGZuIFRoZSBjYWxsYmFjayB0byByZWdpc3RlclxuICAgKiBAZG9jcy1wcml2YXRlXG4gICAqL1xuICByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4ge30pOiB2b2lkIHtcbiAgICB0aGlzLl9vblRvdWNoZWQgPSBmbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBsaXN0Ym94J3MgdmFsdWUuXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgbmV3IHZhbHVlIG9mIHRoZSBsaXN0Ym94XG4gICAqIEBkb2NzLXByaXZhdGVcbiAgICovXG4gIHdyaXRlVmFsdWUodmFsdWU6IHJlYWRvbmx5IFRbXSk6IHZvaWQge1xuICAgIHRoaXMuX3NldFNlbGVjdGlvbih2YWx1ZSk7XG4gICAgdGhpcy5fdmVyaWZ5T3B0aW9uVmFsdWVzKCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgZGlzYWJsZWQgc3RhdGUgb2YgdGhlIGxpc3Rib3guXG4gICAqIEBwYXJhbSBpc0Rpc2FibGVkIFRoZSBuZXcgZGlzYWJsZWQgc3RhdGVcbiAgICogQGRvY3MtcHJpdmF0ZVxuICAgKi9cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKiBGb2N1cyB0aGUgbGlzdGJveCdzIGhvc3QgZWxlbWVudC4gKi9cbiAgZm9jdXMoKSB7XG4gICAgdGhpcy5lbGVtZW50LmZvY3VzKCk7XG4gIH1cblxuICAvKipcbiAgICogVHJpZ2dlcnMgdGhlIGdpdmVuIG9wdGlvbiBpbiByZXNwb25zZSB0byB1c2VyIGludGVyYWN0aW9uLlxuICAgKiAtIEluIHNpbmdsZSBzZWxlY3Rpb24gbW9kZTogc2VsZWN0cyB0aGUgb3B0aW9uIGFuZCBkZXNlbGVjdHMgYW55IG90aGVyIHNlbGVjdGVkIG9wdGlvbi5cbiAgICogLSBJbiBtdWx0aSBzZWxlY3Rpb24gbW9kZTogdG9nZ2xlcyB0aGUgc2VsZWN0ZWQgc3RhdGUgb2YgdGhlIG9wdGlvbi5cbiAgICogQHBhcmFtIG9wdGlvbiBUaGUgb3B0aW9uIHRvIHRyaWdnZXJcbiAgICovXG4gIHByb3RlY3RlZCB0cmlnZ2VyT3B0aW9uKG9wdGlvbjogQ2RrT3B0aW9uPFQ+IHwgbnVsbCkge1xuICAgIGlmIChvcHRpb24gJiYgIW9wdGlvbi5kaXNhYmxlZCkge1xuICAgICAgdGhpcy5fbGFzdFRyaWdnZXJlZCA9IG9wdGlvbjtcbiAgICAgIGNvbnN0IGNoYW5nZWQgPSB0aGlzLm11bHRpcGxlXG4gICAgICAgID8gdGhpcy5zZWxlY3Rpb25Nb2RlbC50b2dnbGUob3B0aW9uLnZhbHVlKVxuICAgICAgICA6IHRoaXMuc2VsZWN0aW9uTW9kZWwuc2VsZWN0KG9wdGlvbi52YWx1ZSk7XG4gICAgICBpZiAoY2hhbmdlZCkge1xuICAgICAgICB0aGlzLl9vbkNoYW5nZSh0aGlzLnZhbHVlKTtcbiAgICAgICAgdGhpcy52YWx1ZUNoYW5nZS5uZXh0KHtcbiAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZSxcbiAgICAgICAgICBsaXN0Ym94OiB0aGlzLFxuICAgICAgICAgIG9wdGlvbjogb3B0aW9uLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVHJpZ2dlciB0aGUgZ2l2ZW4gcmFuZ2Ugb2Ygb3B0aW9ucyBpbiByZXNwb25zZSB0byB1c2VyIGludGVyYWN0aW9uLlxuICAgKiBTaG91bGQgb25seSBiZSBjYWxsZWQgaW4gbXVsdGktc2VsZWN0aW9uIG1vZGUuXG4gICAqIEBwYXJhbSB0cmlnZ2VyIFRoZSBvcHRpb24gdGhhdCB3YXMgdHJpZ2dlcmVkXG4gICAqIEBwYXJhbSBmcm9tIFRoZSBzdGFydCBpbmRleCBvZiB0aGUgb3B0aW9ucyB0byB0b2dnbGVcbiAgICogQHBhcmFtIHRvIFRoZSBlbmQgaW5kZXggb2YgdGhlIG9wdGlvbnMgdG8gdG9nZ2xlXG4gICAqIEBwYXJhbSBvbiBXaGV0aGVyIHRvIHRvZ2dsZSB0aGUgb3B0aW9uIHJhbmdlIG9uXG4gICAqL1xuICBwcm90ZWN0ZWQgdHJpZ2dlclJhbmdlKHRyaWdnZXI6IENka09wdGlvbjxUPiB8IG51bGwsIGZyb206IG51bWJlciwgdG86IG51bWJlciwgb246IGJvb2xlYW4pIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCB8fCAodHJpZ2dlciAmJiB0cmlnZ2VyLmRpc2FibGVkKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9sYXN0VHJpZ2dlcmVkID0gdHJpZ2dlcjtcbiAgICBjb25zdCBpc0VxdWFsID0gdGhpcy5jb21wYXJlV2l0aCA/PyBPYmplY3QuaXM7XG4gICAgY29uc3QgdXBkYXRlVmFsdWVzID0gWy4uLnRoaXMub3B0aW9uc11cbiAgICAgIC5zbGljZShNYXRoLm1heCgwLCBNYXRoLm1pbihmcm9tLCB0bykpLCBNYXRoLm1pbih0aGlzLm9wdGlvbnMubGVuZ3RoLCBNYXRoLm1heChmcm9tLCB0bykgKyAxKSlcbiAgICAgIC5maWx0ZXIob3B0aW9uID0+ICFvcHRpb24uZGlzYWJsZWQpXG4gICAgICAubWFwKG9wdGlvbiA9PiBvcHRpb24udmFsdWUpO1xuICAgIGNvbnN0IHNlbGVjdGVkID0gWy4uLnRoaXMudmFsdWVdO1xuICAgIGZvciAoY29uc3QgdXBkYXRlVmFsdWUgb2YgdXBkYXRlVmFsdWVzKSB7XG4gICAgICBjb25zdCBzZWxlY3RlZEluZGV4ID0gc2VsZWN0ZWQuZmluZEluZGV4KHNlbGVjdGVkVmFsdWUgPT5cbiAgICAgICAgaXNFcXVhbChzZWxlY3RlZFZhbHVlLCB1cGRhdGVWYWx1ZSksXG4gICAgICApO1xuICAgICAgaWYgKG9uICYmIHNlbGVjdGVkSW5kZXggPT09IC0xKSB7XG4gICAgICAgIHNlbGVjdGVkLnB1c2godXBkYXRlVmFsdWUpO1xuICAgICAgfSBlbHNlIGlmICghb24gJiYgc2VsZWN0ZWRJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgc2VsZWN0ZWQuc3BsaWNlKHNlbGVjdGVkSW5kZXgsIDEpO1xuICAgICAgfVxuICAgIH1cbiAgICBsZXQgY2hhbmdlZCA9IHRoaXMuc2VsZWN0aW9uTW9kZWwuc2V0U2VsZWN0aW9uKC4uLnNlbGVjdGVkKTtcbiAgICBpZiAoY2hhbmdlZCkge1xuICAgICAgdGhpcy5fb25DaGFuZ2UodGhpcy52YWx1ZSk7XG4gICAgICB0aGlzLnZhbHVlQ2hhbmdlLm5leHQoe1xuICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZSxcbiAgICAgICAgbGlzdGJveDogdGhpcyxcbiAgICAgICAgb3B0aW9uOiB0cmlnZ2VyLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGdpdmVuIG9wdGlvbiBhcyBhY3RpdmUuXG4gICAqIEBwYXJhbSBvcHRpb24gVGhlIG9wdGlvbiB0byBtYWtlIGFjdGl2ZVxuICAgKi9cbiAgX3NldEFjdGl2ZU9wdGlvbihvcHRpb246IENka09wdGlvbjxUPikge1xuICAgIHRoaXMubGlzdEtleU1hbmFnZXIuc2V0QWN0aXZlSXRlbShvcHRpb24pO1xuICB9XG5cbiAgLyoqIENhbGxlZCB3aGVuIHRoZSBsaXN0Ym94IHJlY2VpdmVzIGZvY3VzLiAqL1xuICBwcm90ZWN0ZWQgX2hhbmRsZUZvY3VzKCkge1xuICAgIGlmICghdGhpcy51c2VBY3RpdmVEZXNjZW5kYW50KSB7XG4gICAgICBpZiAodGhpcy5zZWxlY3Rpb25Nb2RlbC5zZWxlY3RlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuX3NldE5leHRGb2N1c1RvU2VsZWN0ZWRPcHRpb24oKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubGlzdEtleU1hbmFnZXIuc2V0TmV4dEl0ZW1BY3RpdmUoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fZm9jdXNBY3RpdmVPcHRpb24oKTtcbiAgICB9XG4gIH1cblxuICAvKiogQ2FsbGVkIHdoZW4gdGhlIHVzZXIgcHJlc3NlcyBrZXlkb3duIG9uIHRoZSBsaXN0Ym94LiAqL1xuICBwcm90ZWN0ZWQgX2hhbmRsZUtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHtrZXlDb2RlfSA9IGV2ZW50O1xuICAgIGNvbnN0IHByZXZpb3VzQWN0aXZlSW5kZXggPSB0aGlzLmxpc3RLZXlNYW5hZ2VyLmFjdGl2ZUl0ZW1JbmRleDtcbiAgICBjb25zdCBjdHJsS2V5cyA9IFsnY3RybEtleScsICdtZXRhS2V5J10gYXMgY29uc3Q7XG5cbiAgICBpZiAodGhpcy5tdWx0aXBsZSAmJiBrZXlDb2RlID09PSBBICYmIGhhc01vZGlmaWVyS2V5KGV2ZW50LCAuLi5jdHJsS2V5cykpIHtcbiAgICAgIC8vIFRvZ2dsZSBhbGwgb3B0aW9ucyBvZmYgaWYgdGhleSdyZSBhbGwgc2VsZWN0ZWQsIG90aGVyd2lzZSB0b2dnbGUgdGhlbSBhbGwgb24uXG4gICAgICB0aGlzLnRyaWdnZXJSYW5nZShcbiAgICAgICAgbnVsbCxcbiAgICAgICAgMCxcbiAgICAgICAgdGhpcy5vcHRpb25zLmxlbmd0aCAtIDEsXG4gICAgICAgIHRoaXMub3B0aW9ucy5sZW5ndGggIT09IHRoaXMudmFsdWUubGVuZ3RoLFxuICAgICAgKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy5tdWx0aXBsZSAmJlxuICAgICAgKGtleUNvZGUgPT09IFNQQUNFIHx8IGtleUNvZGUgPT09IEVOVEVSKSAmJlxuICAgICAgaGFzTW9kaWZpZXJLZXkoZXZlbnQsICdzaGlmdEtleScpXG4gICAgKSB7XG4gICAgICBpZiAodGhpcy5saXN0S2V5TWFuYWdlci5hY3RpdmVJdGVtICYmIHRoaXMubGlzdEtleU1hbmFnZXIuYWN0aXZlSXRlbUluZGV4ICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy50cmlnZ2VyUmFuZ2UoXG4gICAgICAgICAgdGhpcy5saXN0S2V5TWFuYWdlci5hY3RpdmVJdGVtLFxuICAgICAgICAgIHRoaXMuX2dldExhc3RUcmlnZ2VyZWRJbmRleCgpID8/IHRoaXMubGlzdEtleU1hbmFnZXIuYWN0aXZlSXRlbUluZGV4LFxuICAgICAgICAgIHRoaXMubGlzdEtleU1hbmFnZXIuYWN0aXZlSXRlbUluZGV4LFxuICAgICAgICAgICF0aGlzLmxpc3RLZXlNYW5hZ2VyLmFjdGl2ZUl0ZW0uaXNTZWxlY3RlZCgpLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLm11bHRpcGxlICYmXG4gICAgICBrZXlDb2RlID09PSBIT01FICYmXG4gICAgICBoYXNNb2RpZmllcktleShldmVudCwgLi4uY3RybEtleXMpICYmXG4gICAgICBoYXNNb2RpZmllcktleShldmVudCwgJ3NoaWZ0S2V5JylcbiAgICApIHtcbiAgICAgIGNvbnN0IHRyaWdnZXIgPSB0aGlzLmxpc3RLZXlNYW5hZ2VyLmFjdGl2ZUl0ZW07XG4gICAgICBpZiAodHJpZ2dlcikge1xuICAgICAgICBjb25zdCBmcm9tID0gdGhpcy5saXN0S2V5TWFuYWdlci5hY3RpdmVJdGVtSW5kZXghO1xuICAgICAgICB0aGlzLmxpc3RLZXlNYW5hZ2VyLnNldEZpcnN0SXRlbUFjdGl2ZSgpO1xuICAgICAgICB0aGlzLnRyaWdnZXJSYW5nZShcbiAgICAgICAgICB0cmlnZ2VyLFxuICAgICAgICAgIGZyb20sXG4gICAgICAgICAgdGhpcy5saXN0S2V5TWFuYWdlci5hY3RpdmVJdGVtSW5kZXghLFxuICAgICAgICAgICF0cmlnZ2VyLmlzU2VsZWN0ZWQoKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy5tdWx0aXBsZSAmJlxuICAgICAga2V5Q29kZSA9PT0gRU5EICYmXG4gICAgICBoYXNNb2RpZmllcktleShldmVudCwgLi4uY3RybEtleXMpICYmXG4gICAgICBoYXNNb2RpZmllcktleShldmVudCwgJ3NoaWZ0S2V5JylcbiAgICApIHtcbiAgICAgIGNvbnN0IHRyaWdnZXIgPSB0aGlzLmxpc3RLZXlNYW5hZ2VyLmFjdGl2ZUl0ZW07XG4gICAgICBpZiAodHJpZ2dlcikge1xuICAgICAgICBjb25zdCBmcm9tID0gdGhpcy5saXN0S2V5TWFuYWdlci5hY3RpdmVJdGVtSW5kZXghO1xuICAgICAgICB0aGlzLmxpc3RLZXlNYW5hZ2VyLnNldExhc3RJdGVtQWN0aXZlKCk7XG4gICAgICAgIHRoaXMudHJpZ2dlclJhbmdlKFxuICAgICAgICAgIHRyaWdnZXIsXG4gICAgICAgICAgZnJvbSxcbiAgICAgICAgICB0aGlzLmxpc3RLZXlNYW5hZ2VyLmFjdGl2ZUl0ZW1JbmRleCEsXG4gICAgICAgICAgIXRyaWdnZXIuaXNTZWxlY3RlZCgpLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoa2V5Q29kZSA9PT0gU1BBQ0UgfHwga2V5Q29kZSA9PT0gRU5URVIpIHtcbiAgICAgIHRoaXMudHJpZ2dlck9wdGlvbih0aGlzLmxpc3RLZXlNYW5hZ2VyLmFjdGl2ZUl0ZW0pO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpc05hdktleSA9XG4gICAgICBrZXlDb2RlID09PSBVUF9BUlJPVyB8fFxuICAgICAga2V5Q29kZSA9PT0gRE9XTl9BUlJPVyB8fFxuICAgICAga2V5Q29kZSA9PT0gTEVGVF9BUlJPVyB8fFxuICAgICAga2V5Q29kZSA9PT0gUklHSFRfQVJST1cgfHxcbiAgICAgIGtleUNvZGUgPT09IEhPTUUgfHxcbiAgICAgIGtleUNvZGUgPT09IEVORDtcbiAgICB0aGlzLmxpc3RLZXlNYW5hZ2VyLm9uS2V5ZG93bihldmVudCk7XG4gICAgLy8gV2lsbCBzZWxlY3QgYW4gb3B0aW9uIGlmIHNoaWZ0IHdhcyBwcmVzc2VkIHdoaWxlIG5hdmlnYXRpbmcgdG8gdGhlIG9wdGlvblxuICAgIGlmIChpc05hdktleSAmJiBldmVudC5zaGlmdEtleSAmJiBwcmV2aW91c0FjdGl2ZUluZGV4ICE9PSB0aGlzLmxpc3RLZXlNYW5hZ2VyLmFjdGl2ZUl0ZW1JbmRleCkge1xuICAgICAgdGhpcy50cmlnZ2VyT3B0aW9uKHRoaXMubGlzdEtleU1hbmFnZXIuYWN0aXZlSXRlbSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIENhbGxlZCB3aGVuIGEgZm9jdXMgbW92ZXMgaW50byB0aGUgbGlzdGJveC4gKi9cbiAgcHJvdGVjdGVkIF9oYW5kbGVGb2N1c0luKCkge1xuICAgIC8vIE5vdGUgdGhhdCB3ZSB1c2UgYSBgZm9jdXNpbmAgaGFuZGxlciBmb3IgdGhpcyBpbnN0ZWFkIG9mIHRoZSBleGlzdGluZyBgZm9jdXNgIGhhbmRsZXIsXG4gICAgLy8gYmVjYXVzZSBmb2N1cyB3b24ndCBsYW5kIG9uIHRoZSBsaXN0Ym94IGlmIGB1c2VBY3RpdmVEZXNjZW5kYW50YCBpcyBlbmFibGVkLlxuICAgIHRoaXMuX2hhc0ZvY3VzID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgZm9jdXMgbGVhdmVzIGFuIGVsZW1lbnQgaW4gdGhlIGxpc3Rib3guXG4gICAqIEBwYXJhbSBldmVudCBUaGUgZm9jdXNvdXQgZXZlbnRcbiAgICovXG4gIHByb3RlY3RlZCBfaGFuZGxlRm9jdXNPdXQoZXZlbnQ6IEZvY3VzRXZlbnQpIHtcbiAgICAvLyBTb21lIGJyb3dzZXJzIChlLmcuIENocm9tZSBhbmQgRmlyZWZveCkgdHJpZ2dlciB0aGUgZm9jdXNvdXQgZXZlbnQgd2hlbiB0aGUgdXNlciByZXR1cm5zIGJhY2sgdG8gdGhlIGRvY3VtZW50LlxuICAgIC8vIFRvIHByZXZlbnQgbG9zaW5nIHRoZSBhY3RpdmUgb3B0aW9uIGluIHRoaXMgY2FzZSwgd2Ugc3RvcmUgaXQgaW4gYF9wcmV2aW91c0FjdGl2ZU9wdGlvbmAgYW5kIHJlc3RvcmUgaXQgb24gdGhlIHdpbmRvdyBgYmx1cmAgZXZlbnRcbiAgICAvLyBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgYGFjdGl2ZUl0ZW1gIG1hdGNoZXMgdGhlIGFjdHVhbCBmb2N1c2VkIGVsZW1lbnQgd2hlbiB0aGUgdXNlciByZXR1cm5zIHRvIHRoZSBkb2N1bWVudC5cbiAgICB0aGlzLl9wcmV2aW91c0FjdGl2ZU9wdGlvbiA9IHRoaXMubGlzdEtleU1hbmFnZXIuYWN0aXZlSXRlbTtcblxuICAgIGNvbnN0IG90aGVyRWxlbWVudCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXQgYXMgRWxlbWVudDtcbiAgICBpZiAodGhpcy5lbGVtZW50ICE9PSBvdGhlckVsZW1lbnQgJiYgIXRoaXMuZWxlbWVudC5jb250YWlucyhvdGhlckVsZW1lbnQpKSB7XG4gICAgICB0aGlzLl9vblRvdWNoZWQoKTtcbiAgICAgIHRoaXMuX2hhc0ZvY3VzID0gZmFsc2U7XG4gICAgICB0aGlzLl9zZXROZXh0Rm9jdXNUb1NlbGVjdGVkT3B0aW9uKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEdldCB0aGUgaWQgb2YgdGhlIGFjdGl2ZSBvcHRpb24gaWYgYWN0aXZlIGRlc2NlbmRhbnQgaXMgYmVpbmcgdXNlZC4gKi9cbiAgcHJvdGVjdGVkIF9nZXRBcmlhQWN0aXZlRGVzY2VuZGFudCgpOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy51c2VBY3RpdmVEZXNjZW5kYW50ID8gdGhpcy5saXN0S2V5TWFuYWdlcj8uYWN0aXZlSXRlbT8uaWQgOiBudWxsO1xuICB9XG5cbiAgLyoqIEdldCB0aGUgdGFiaW5kZXggZm9yIHRoZSBsaXN0Ym94LiAqL1xuICBwcm90ZWN0ZWQgX2dldFRhYkluZGV4KCkge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnVzZUFjdGl2ZURlc2NlbmRhbnQgfHwgIXRoaXMubGlzdEtleU1hbmFnZXIuYWN0aXZlSXRlbSA/IHRoaXMuZW5hYmxlZFRhYkluZGV4IDogLTE7XG4gIH1cblxuICAvKiogSW5pdGlhbGl6ZSB0aGUga2V5IG1hbmFnZXIuICovXG4gIHByaXZhdGUgX2luaXRLZXlNYW5hZ2VyKCkge1xuICAgIHRoaXMubGlzdEtleU1hbmFnZXIgPSBuZXcgQWN0aXZlRGVzY2VuZGFudEtleU1hbmFnZXIodGhpcy5vcHRpb25zKVxuICAgICAgLndpdGhXcmFwKCF0aGlzLl9uYXZpZ2F0aW9uV3JhcERpc2FibGVkKVxuICAgICAgLndpdGhUeXBlQWhlYWQoKVxuICAgICAgLndpdGhIb21lQW5kRW5kKClcbiAgICAgIC53aXRoQWxsb3dlZE1vZGlmaWVyS2V5cyhbJ3NoaWZ0S2V5J10pXG4gICAgICAuc2tpcFByZWRpY2F0ZShcbiAgICAgICAgdGhpcy5fbmF2aWdhdGVEaXNhYmxlZE9wdGlvbnMgPyB0aGlzLl9za2lwTm9uZVByZWRpY2F0ZSA6IHRoaXMuX3NraXBEaXNhYmxlZFByZWRpY2F0ZSxcbiAgICAgICk7XG5cbiAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdGhpcy5saXN0S2V5TWFuYWdlci53aXRoVmVydGljYWxPcmllbnRhdGlvbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxpc3RLZXlNYW5hZ2VyLndpdGhIb3Jpem9udGFsT3JpZW50YXRpb24odGhpcy5fZGlyPy52YWx1ZSB8fCAnbHRyJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2VsZWN0aW9uTW9kZWwuc2VsZWN0ZWQubGVuZ3RoKSB7XG4gICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHRoaXMuX3NldE5leHRGb2N1c1RvU2VsZWN0ZWRPcHRpb24oKSk7XG4gICAgfVxuXG4gICAgdGhpcy5saXN0S2V5TWFuYWdlci5jaGFuZ2Uuc3Vic2NyaWJlKCgpID0+IHRoaXMuX2ZvY3VzQWN0aXZlT3B0aW9uKCkpO1xuXG4gICAgdGhpcy5vcHRpb25zLmNoYW5nZXMucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgY29uc3QgYWN0aXZlT3B0aW9uID0gdGhpcy5saXN0S2V5TWFuYWdlci5hY3RpdmVJdGVtO1xuXG4gICAgICAvLyBJZiB0aGUgYWN0aXZlIG9wdGlvbiB3YXMgZGVsZXRlZCwgd2UgbmVlZCB0byByZXNldFxuICAgICAgLy8gdGhlIGtleSBtYW5hZ2VyIHNvIGl0IGNhbiBhbGxvdyBmb2N1cyBiYWNrIGluLlxuICAgICAgaWYgKGFjdGl2ZU9wdGlvbiAmJiAhdGhpcy5vcHRpb25zLmZpbmQob3B0aW9uID0+IG9wdGlvbiA9PT0gYWN0aXZlT3B0aW9uKSkge1xuICAgICAgICB0aGlzLmxpc3RLZXlNYW5hZ2VyLnNldEFjdGl2ZUl0ZW0oLTEpO1xuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqIEZvY3VzIHRoZSBhY3RpdmUgb3B0aW9uLiAqL1xuICBwcml2YXRlIF9mb2N1c0FjdGl2ZU9wdGlvbigpIHtcbiAgICBpZiAoIXRoaXMudXNlQWN0aXZlRGVzY2VuZGFudCkge1xuICAgICAgdGhpcy5saXN0S2V5TWFuYWdlci5hY3RpdmVJdGVtPy5mb2N1cygpO1xuICAgIH1cbiAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgc2VsZWN0ZWQgdmFsdWVzLlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxpc3Qgb2YgbmV3IHNlbGVjdGVkIHZhbHVlcy5cbiAgICovXG4gIHByaXZhdGUgX3NldFNlbGVjdGlvbih2YWx1ZTogcmVhZG9ubHkgVFtdKSB7XG4gICAgaWYgKHRoaXMuX2ludmFsaWQpIHtcbiAgICAgIHRoaXMuc2VsZWN0aW9uTW9kZWwuY2xlYXIoZmFsc2UpO1xuICAgIH1cbiAgICB0aGlzLnNlbGVjdGlvbk1vZGVsLnNldFNlbGVjdGlvbiguLi50aGlzLl9jb2VyY2VWYWx1ZSh2YWx1ZSkpO1xuXG4gICAgaWYgKCF0aGlzLl9oYXNGb2N1cykge1xuICAgICAgdGhpcy5fc2V0TmV4dEZvY3VzVG9TZWxlY3RlZE9wdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBTZXRzIHRoZSBmaXJzdCBzZWxlY3RlZCBvcHRpb24gYXMgZmlyc3QgaW4gdGhlIGtleWJvYXJkIGZvY3VzIG9yZGVyLiAqL1xuICBwcml2YXRlIF9zZXROZXh0Rm9jdXNUb1NlbGVjdGVkT3B0aW9uKCkge1xuICAgIC8vIE51bGwgY2hlY2sgdGhlIG9wdGlvbnMgc2luY2UgdGhleSBvbmx5IGdldCBkZWZpbmVkIGFmdGVyIGBuZ0FmdGVyQ29udGVudEluaXRgLlxuICAgIGNvbnN0IHNlbGVjdGVkID0gdGhpcy5vcHRpb25zPy5maW5kKG9wdGlvbiA9PiBvcHRpb24uaXNTZWxlY3RlZCgpKTtcblxuICAgIGlmIChzZWxlY3RlZCkge1xuICAgICAgdGhpcy5saXN0S2V5TWFuYWdlci51cGRhdGVBY3RpdmVJdGVtKHNlbGVjdGVkKTtcbiAgICB9XG4gIH1cblxuICAvKiogVXBkYXRlIHRoZSBpbnRlcm5hbCB2YWx1ZSBvZiB0aGUgbGlzdGJveCBiYXNlZCBvbiB0aGUgc2VsZWN0aW9uIG1vZGVsLiAqL1xuICBwcml2YXRlIF91cGRhdGVJbnRlcm5hbFZhbHVlKCkge1xuICAgIGNvbnN0IGluZGV4Q2FjaGUgPSBuZXcgTWFwPFQsIG51bWJlcj4oKTtcbiAgICB0aGlzLnNlbGVjdGlvbk1vZGVsLnNvcnQoKGE6IFQsIGI6IFQpID0+IHtcbiAgICAgIGNvbnN0IGFJbmRleCA9IHRoaXMuX2dldEluZGV4Rm9yVmFsdWUoaW5kZXhDYWNoZSwgYSk7XG4gICAgICBjb25zdCBiSW5kZXggPSB0aGlzLl9nZXRJbmRleEZvclZhbHVlKGluZGV4Q2FjaGUsIGIpO1xuICAgICAgcmV0dXJuIGFJbmRleCAtIGJJbmRleDtcbiAgICB9KTtcbiAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMuc2VsZWN0aW9uTW9kZWwuc2VsZWN0ZWQ7XG4gICAgdGhpcy5faW52YWxpZCA9XG4gICAgICAoIXRoaXMubXVsdGlwbGUgJiYgc2VsZWN0ZWQubGVuZ3RoID4gMSkgfHwgISF0aGlzLl9nZXRJbnZhbGlkT3B0aW9uVmFsdWVzKHNlbGVjdGVkKS5sZW5ndGg7XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBpbmRleCBvZiB0aGUgZ2l2ZW4gdmFsdWUgaW4gdGhlIGdpdmVuIGxpc3Qgb2Ygb3B0aW9ucy5cbiAgICogQHBhcmFtIGNhY2hlIFRoZSBjYWNoZSBvZiBpbmRpY2VzIGZvdW5kIHNvIGZhclxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGZpbmRcbiAgICogQHJldHVybiBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIGluIHRoZSBvcHRpb25zIGxpc3RcbiAgICovXG4gIHByaXZhdGUgX2dldEluZGV4Rm9yVmFsdWUoY2FjaGU6IE1hcDxULCBudW1iZXI+LCB2YWx1ZTogVCkge1xuICAgIGNvbnN0IGlzRXF1YWwgPSB0aGlzLmNvbXBhcmVXaXRoIHx8IE9iamVjdC5pcztcbiAgICBpZiAoIWNhY2hlLmhhcyh2YWx1ZSkpIHtcbiAgICAgIGxldCBpbmRleCA9IC0xO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm9wdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGlzRXF1YWwodmFsdWUsIHRoaXMub3B0aW9ucy5nZXQoaSkhLnZhbHVlKSkge1xuICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2FjaGUuc2V0KHZhbHVlLCBpbmRleCk7XG4gICAgfVxuICAgIHJldHVybiBjYWNoZS5nZXQodmFsdWUpITtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgdGhlIHVzZXIgY2xpY2tpbmcgYW4gb3B0aW9uLlxuICAgKiBAcGFyYW0gb3B0aW9uIFRoZSBvcHRpb24gdGhhdCB3YXMgY2xpY2tlZC5cbiAgICovXG4gIHByaXZhdGUgX2hhbmRsZU9wdGlvbkNsaWNrZWQob3B0aW9uOiBDZGtPcHRpb248VD4sIGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLmxpc3RLZXlNYW5hZ2VyLnNldEFjdGl2ZUl0ZW0ob3B0aW9uKTtcbiAgICBpZiAoZXZlbnQuc2hpZnRLZXkgJiYgdGhpcy5tdWx0aXBsZSkge1xuICAgICAgdGhpcy50cmlnZ2VyUmFuZ2UoXG4gICAgICAgIG9wdGlvbixcbiAgICAgICAgdGhpcy5fZ2V0TGFzdFRyaWdnZXJlZEluZGV4KCkgPz8gdGhpcy5saXN0S2V5TWFuYWdlci5hY3RpdmVJdGVtSW5kZXghLFxuICAgICAgICB0aGlzLmxpc3RLZXlNYW5hZ2VyLmFjdGl2ZUl0ZW1JbmRleCEsXG4gICAgICAgICFvcHRpb24uaXNTZWxlY3RlZCgpLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50cmlnZ2VyT3B0aW9uKG9wdGlvbik7XG4gICAgfVxuICB9XG5cbiAgLyoqIFZlcmlmaWVzIHRoYXQgbm8gdHdvIG9wdGlvbnMgcmVwcmVzZW50IHRoZSBzYW1lIHZhbHVlIHVuZGVyIHRoZSBjb21wYXJlV2l0aCBmdW5jdGlvbi4gKi9cbiAgcHJpdmF0ZSBfdmVyaWZ5Tm9PcHRpb25WYWx1ZUNvbGxpc2lvbnMoKSB7XG4gICAgdGhpcy5vcHRpb25zLmNoYW5nZXMucGlwZShzdGFydFdpdGgodGhpcy5vcHRpb25zKSwgdGFrZVVudGlsKHRoaXMuZGVzdHJveWVkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGNvbnN0IGlzRXF1YWwgPSB0aGlzLmNvbXBhcmVXaXRoID8/IE9iamVjdC5pcztcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5vcHRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMub3B0aW9ucy5nZXQoaSkhO1xuICAgICAgICBsZXQgZHVwbGljYXRlOiBDZGtPcHRpb248VD4gfCBudWxsID0gbnVsbDtcbiAgICAgICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgdGhpcy5vcHRpb25zLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgY29uc3Qgb3RoZXIgPSB0aGlzLm9wdGlvbnMuZ2V0KGopITtcbiAgICAgICAgICBpZiAoaXNFcXVhbChvcHRpb24udmFsdWUsIG90aGVyLnZhbHVlKSkge1xuICAgICAgICAgICAgZHVwbGljYXRlID0gb3RoZXI7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGR1cGxpY2F0ZSkge1xuICAgICAgICAgIC8vIFRPRE8obW1hbGVyYmEpOiBMaW5rIHRvIGRvY3MgYWJvdXQgdGhpcy5cbiAgICAgICAgICBpZiAodGhpcy5jb21wYXJlV2l0aCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICBgRm91bmQgbXVsdGlwbGUgQ2RrT3B0aW9uIHJlcHJlc2VudGluZyB0aGUgc2FtZSB2YWx1ZSB1bmRlciB0aGUgZ2l2ZW4gY29tcGFyZVdpdGggZnVuY3Rpb25gLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgb3B0aW9uMTogb3B0aW9uLmVsZW1lbnQsXG4gICAgICAgICAgICAgICAgb3B0aW9uMjogZHVwbGljYXRlLmVsZW1lbnQsXG4gICAgICAgICAgICAgICAgY29tcGFyZVdpdGg6IHRoaXMuY29tcGFyZVdpdGgsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYEZvdW5kIG11bHRpcGxlIENka09wdGlvbiB3aXRoIHRoZSBzYW1lIHZhbHVlYCwge1xuICAgICAgICAgICAgICBvcHRpb24xOiBvcHRpb24uZWxlbWVudCxcbiAgICAgICAgICAgICAgb3B0aW9uMjogZHVwbGljYXRlLmVsZW1lbnQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKiogVmVyaWZpZXMgdGhhdCB0aGUgb3B0aW9uIHZhbHVlcyBhcmUgdmFsaWQuICovXG4gIHByaXZhdGUgX3ZlcmlmeU9wdGlvblZhbHVlcygpIHtcbiAgICBpZiAodGhpcy5vcHRpb25zICYmICh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpKSB7XG4gICAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMuc2VsZWN0aW9uTW9kZWwuc2VsZWN0ZWQ7XG4gICAgICBjb25zdCBpbnZhbGlkVmFsdWVzID0gdGhpcy5fZ2V0SW52YWxpZE9wdGlvblZhbHVlcyhzZWxlY3RlZCk7XG5cbiAgICAgIGlmICghdGhpcy5tdWx0aXBsZSAmJiBzZWxlY3RlZC5sZW5ndGggPiAxKSB7XG4gICAgICAgIHRocm93IEVycm9yKCdMaXN0Ym94IGNhbm5vdCBoYXZlIG1vcmUgdGhhbiBvbmUgc2VsZWN0ZWQgdmFsdWUgaW4gbXVsdGktc2VsZWN0aW9uIG1vZGUuJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbnZhbGlkVmFsdWVzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBFcnJvcignTGlzdGJveCBoYXMgc2VsZWN0ZWQgdmFsdWVzIHRoYXQgZG8gbm90IG1hdGNoIGFueSBvZiBpdHMgb3B0aW9ucy4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29lcmNlcyBhIHZhbHVlIGludG8gYW4gYXJyYXkgcmVwcmVzZW50aW5nIGEgbGlzdGJveCBzZWxlY3Rpb24uXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29lcmNlXG4gICAqIEByZXR1cm4gQW4gYXJyYXlcbiAgICovXG4gIHByaXZhdGUgX2NvZXJjZVZhbHVlKHZhbHVlOiByZWFkb25seSBUW10pIHtcbiAgICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/IFtdIDogY29lcmNlQXJyYXkodmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgc3VibGlzdCBvZiB2YWx1ZXMgdGhhdCBkbyBub3QgcmVwcmVzZW50IHZhbGlkIG9wdGlvbiB2YWx1ZXMgaW4gdGhpcyBsaXN0Ym94LlxuICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBsaXN0IG9mIHZhbHVlc1xuICAgKiBAcmV0dXJuIFRoZSBzdWJsaXN0IG9mIHZhbHVlcyB0aGF0IGFyZSBub3QgdmFsaWQgb3B0aW9uIHZhbHVlc1xuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0SW52YWxpZE9wdGlvblZhbHVlcyh2YWx1ZXM6IHJlYWRvbmx5IFRbXSkge1xuICAgIGNvbnN0IGlzRXF1YWwgPSB0aGlzLmNvbXBhcmVXaXRoIHx8IE9iamVjdC5pcztcbiAgICBjb25zdCB2YWxpZFZhbHVlcyA9ICh0aGlzLm9wdGlvbnMgfHwgW10pLm1hcChvcHRpb24gPT4gb3B0aW9uLnZhbHVlKTtcbiAgICByZXR1cm4gdmFsdWVzLmZpbHRlcih2YWx1ZSA9PiAhdmFsaWRWYWx1ZXMuc29tZSh2YWxpZFZhbHVlID0+IGlzRXF1YWwodmFsdWUsIHZhbGlkVmFsdWUpKSk7XG4gIH1cblxuICAvKiogR2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCB0cmlnZ2VyZWQgb3B0aW9uLiAqL1xuICBwcml2YXRlIF9nZXRMYXN0VHJpZ2dlcmVkSW5kZXgoKSB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLm9wdGlvbnMudG9BcnJheSgpLmluZGV4T2YodGhpcy5fbGFzdFRyaWdnZXJlZCEpO1xuICAgIHJldHVybiBpbmRleCA9PT0gLTEgPyBudWxsIDogaW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHByZXZpb3VzIGFjdGl2ZSBvcHRpb24gYXMgYWN0aXZlIG9wdGlvbiBvbiB3aW5kb3cgYmx1ci5cbiAgICogVGhpcyBlbnN1cmVzIHRoYXQgdGhlIGBhY3RpdmVPcHRpb25gIG1hdGNoZXMgdGhlIGFjdHVhbCBmb2N1c2VkIGVsZW1lbnQgd2hlbiB0aGUgdXNlciByZXR1cm5zIHRvIHRoZSBkb2N1bWVudC5cbiAgICovXG4gIHByaXZhdGUgX3NldFByZXZpb3VzQWN0aXZlT3B0aW9uQXNBY3RpdmVPcHRpb25PbldpbmRvd0JsdXIoKSB7XG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgZnJvbUV2ZW50KHdpbmRvdywgJ2JsdXInKVxuICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQpKVxuICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5lbGVtZW50LmNvbnRhaW5zKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpICYmIHRoaXMuX3ByZXZpb3VzQWN0aXZlT3B0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLl9zZXRBY3RpdmVPcHRpb24odGhpcy5fcHJldmlvdXNBY3RpdmVPcHRpb24pO1xuICAgICAgICAgICAgdGhpcy5fcHJldmlvdXNBY3RpdmVPcHRpb24gPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbn1cblxuLyoqIENoYW5nZSBldmVudCB0aGF0IGlzIGZpcmVkIHdoZW5ldmVyIHRoZSB2YWx1ZSBvZiB0aGUgbGlzdGJveCBjaGFuZ2VzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBMaXN0Ym94VmFsdWVDaGFuZ2VFdmVudDxUPiB7XG4gIC8qKiBUaGUgbmV3IHZhbHVlIG9mIHRoZSBsaXN0Ym94LiAqL1xuICByZWFkb25seSB2YWx1ZTogcmVhZG9ubHkgVFtdO1xuXG4gIC8qKiBSZWZlcmVuY2UgdG8gdGhlIGxpc3Rib3ggdGhhdCBlbWl0dGVkIHRoZSBldmVudC4gKi9cbiAgcmVhZG9ubHkgbGlzdGJveDogQ2RrTGlzdGJveDxUPjtcblxuICAvKiogUmVmZXJlbmNlIHRvIHRoZSBvcHRpb24gdGhhdCB3YXMgdHJpZ2dlcmVkLiAqL1xuICByZWFkb25seSBvcHRpb246IENka09wdGlvbjxUPiB8IG51bGw7XG59XG4iXX0=
|