@sbb-esta/lyne-elements-dev 4.7.0-dev.1773818683 → 4.7.0-dev.1773821763
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/core/styles/core.scss +9 -0
- package/core.css +20 -0
- package/custom-elements.json +230 -230
- package/development/menu/common/menu-action-common.js +1 -1
- package/development/menu/common.js +1 -1
- package/development/menu/menu/menu.component.js +1 -1
- package/development/menu/menu.js +1 -1
- package/development/menu-action-common-CE1gySL_.js +140 -0
- package/development/menu.component-D4nt6M9b.js +620 -0
- package/development/menu.js +2 -2
- package/development/menu.pure.js +2 -2
- package/menu/common/menu-action-common.js +1 -1
- package/menu/common.js +1 -1
- package/menu/menu/menu.component.js +1 -1
- package/menu/menu.js +1 -1
- package/menu-action-common-vt9j6nkG.js +29 -0
- package/{menu.component-_ncuRAqx.js → menu.component-elxRPsQz.js} +1 -1
- package/menu.js +2 -2
- package/menu.pure.js +2 -2
- package/off-brand-theme.css +20 -0
- package/package.json +2 -2
- package/safety-theme.css +20 -0
- package/standard-theme.css +20 -0
- package/development/menu-action-common-BTOi6wCg.js +0 -148
- package/development/menu.component-Dt6ilHX4.js +0 -638
- package/menu-action-common-BCV8hNkz.js +0 -29
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
import { __esDecorate, __runInitializers } from "tslib";
|
|
2
|
+
import { css, html, isServer } from "lit";
|
|
3
|
+
import { property } from "lit/decorators.js";
|
|
4
|
+
import { SbbOpenCloseBaseElement } from "./core/base-elements.js";
|
|
5
|
+
import { idReference } from "./core/decorators.js";
|
|
6
|
+
import { SbbScrollHandler, isZeroAnimationDuration } from "./core/dom.js";
|
|
7
|
+
import { forwardEvent } from "./core/eventing.js";
|
|
8
|
+
import { ɵstateController } from "./core/mixins.js";
|
|
9
|
+
import { boxSizingStyles } from "./core/styles.js";
|
|
10
|
+
import { SbbDarkModeController, SbbEscapableOverlayController, SbbInertController, SbbLanguageController, SbbMediaMatcherController, SbbMediaQueryBreakpointSmallAndBelow } from "./core/controllers.js";
|
|
11
|
+
import "./divider.js";
|
|
12
|
+
import { ref } from "lit/directives/ref.js";
|
|
13
|
+
import { getElementPosition, getElementPositionHorizontal, isEventOnElement, removeAriaOverlayTriggerAttributes, setAriaOverlayTriggerAttributes } from "./core/overlay.js";
|
|
14
|
+
import { SbbFocusTrapController, getNextElementIndex, interactivityChecker, isArrowKeyOrPageKeysPressed } from "./core/a11y.js";
|
|
15
|
+
import { i18nGoBack } from "./core/i18n/i18n.js";
|
|
16
|
+
import { SbbMenuButtonElement } from "./menu/menu-button/menu-button.component.js";
|
|
17
|
+
//#region src/elements/menu/menu/menu.scss?lit&inline
|
|
18
|
+
var menu_default = css`:host {
|
|
19
|
+
display: contents;
|
|
20
|
+
--sbb-menu-animation-duration: var(
|
|
21
|
+
--sbb-disable-animation-duration,
|
|
22
|
+
var(--sbb-animation-duration-6x)
|
|
23
|
+
);
|
|
24
|
+
--sbb-focus-outline-color: var(--sbb-focus-outline-color-dark);
|
|
25
|
+
--_sbb-menu-inset: 0 auto auto 0;
|
|
26
|
+
--sbb-scrollbar-thumb-width: 0.125rem;
|
|
27
|
+
--sbb-scrollbar-thumb-width-hover: 0.25rem;
|
|
28
|
+
--sbb-scrollbar-width-firefox: thin;
|
|
29
|
+
--sbb-scrollbar-color: color-mix(in srgb, var(--sbb-color-white) 30%, transparent);
|
|
30
|
+
--sbb-scrollbar-color-hover: color-mix(in srgb, var(--sbb-color-white) 60%, transparent);
|
|
31
|
+
--sbb-scrollbar-track-color: transparent;
|
|
32
|
+
}
|
|
33
|
+
@media (min-width: calc(64rem)) {
|
|
34
|
+
:host {
|
|
35
|
+
--sbb-menu-back-button-display: none;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
:host(:is(:is(:state(state-opened),[state--state-opened]), :is(:state(state-opening),[state--state-opening]))) {
|
|
40
|
+
--sbb-menu-visibility: visible;
|
|
41
|
+
--sbb-menu-backdrop-color: color-mix(in srgb, var(--sbb-color-black) 20%, transparent);
|
|
42
|
+
}
|
|
43
|
+
@media (min-width: calc(64rem)) {
|
|
44
|
+
:host(:is(:is(:state(state-opened),[state--state-opened]), :is(:state(state-opening),[state--state-opening]))) {
|
|
45
|
+
--sbb-menu-backdrop-color: transparent;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
:host(:not(:is(:state(nested),[state--nested]))) {
|
|
50
|
+
--sbb-menu-back-button-display: none;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
:host(:not(:is(:state(state-closed),[state--state-closed]))) {
|
|
54
|
+
--_sbb-menu-inset: 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
:host(:is(:state(dark),[state--dark])) {
|
|
58
|
+
--sbb-focus-outline-color: var(--sbb-focus-outline-color-default);
|
|
59
|
+
--sbb-scrollbar-color: color-mix(in srgb, var(--sbb-color-black) 30%, transparent);
|
|
60
|
+
--sbb-scrollbar-color-hover: color-mix(in srgb, var(--sbb-color-black) 60%, transparent);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@media (max-width: calc(63.9375rem)) {
|
|
64
|
+
:host(:is(:state(skip-animation),[state--skip-animation])) {
|
|
65
|
+
--sbb-menu-animation-duration: 0ms;
|
|
66
|
+
}
|
|
67
|
+
:host(:is(:state(nested-child),[state--nested-child])) {
|
|
68
|
+
--sbb-menu-transform-x: -100%;
|
|
69
|
+
}
|
|
70
|
+
:host(:is(:state(nested),[state--nested]):is(:is(:state(state-opening),[state--state-opening]), :is(:state(state-opened),[state--state-opened]), :is(:state(state-closing),[state--state-closing]))) {
|
|
71
|
+
--sbb-menu-open-animation-name: open-sideways;
|
|
72
|
+
}
|
|
73
|
+
:host(:is(:state(state-closing),[state--state-closing]):is(:state(nested),[state--nested]):not(:is(:state(close-all),[state--close-all]))) {
|
|
74
|
+
--sbb-menu-close-animation-name: close-sideways;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
::slotted(:not(sbb-menu-button, sbb-menu-link, sbb-divider)) {
|
|
78
|
+
display: block;
|
|
79
|
+
padding-inline: var(--sbb-spacing-fixed-5x);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
sbb-divider,
|
|
83
|
+
::slotted(sbb-divider) {
|
|
84
|
+
--sbb-divider-color: var(--sbb-background-color-4-inverted);
|
|
85
|
+
margin-block: var(--sbb-spacing-fixed-2x);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
sbb-divider,
|
|
89
|
+
#sbb-menu__back-button {
|
|
90
|
+
display: var(--sbb-menu-back-button-display, block);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.sbb-menu__container {
|
|
94
|
+
position: fixed;
|
|
95
|
+
pointer-events: none;
|
|
96
|
+
inset: var(--_sbb-menu-inset);
|
|
97
|
+
height: var(--sbb-menu-container-height);
|
|
98
|
+
z-index: var(--sbb-menu-z-index, var(--sbb-overlay-default-z-index));
|
|
99
|
+
}
|
|
100
|
+
.sbb-menu__container::before {
|
|
101
|
+
content: "";
|
|
102
|
+
visibility: var(--sbb-menu-visibility, hidden);
|
|
103
|
+
pointer-events: all;
|
|
104
|
+
position: fixed;
|
|
105
|
+
inset: var(--_sbb-menu-inset);
|
|
106
|
+
height: var(--sbb-menu-container-height);
|
|
107
|
+
background-color: var(--sbb-menu-backdrop-color, transparent);
|
|
108
|
+
transition-duration: var(--sbb-menu-animation-duration);
|
|
109
|
+
transition-timing-function: var(--sbb-menu-animation-easing);
|
|
110
|
+
transition-property: background-color, visibility;
|
|
111
|
+
}
|
|
112
|
+
:host(:is(:state(nested),[state--nested])) .sbb-menu__container::before {
|
|
113
|
+
display: none;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.sbb-menu {
|
|
117
|
+
display: none;
|
|
118
|
+
opacity: 0;
|
|
119
|
+
pointer-events: none;
|
|
120
|
+
max-width: var(--sbb-menu-max-width);
|
|
121
|
+
min-width: var(--sbb-menu-min-width);
|
|
122
|
+
text-align: start;
|
|
123
|
+
position: absolute;
|
|
124
|
+
inset-inline-start: 0;
|
|
125
|
+
inset-block-start: unset;
|
|
126
|
+
inset-block-end: 0;
|
|
127
|
+
inset-inline-end: unset;
|
|
128
|
+
color: var(--sbb-menu-color);
|
|
129
|
+
border: none;
|
|
130
|
+
border-radius: var(--sbb-menu-border-radius) var(--sbb-menu-border-radius) 0 0;
|
|
131
|
+
background-color: var(--sbb-menu-background-color);
|
|
132
|
+
padding: 0;
|
|
133
|
+
overflow: hidden;
|
|
134
|
+
translate: var(--sbb-menu-transform-x, 0) 0;
|
|
135
|
+
transition: translate var(--sbb-menu-animation-duration);
|
|
136
|
+
}
|
|
137
|
+
:host(:is(:is(:state(state-opening),[state--state-opening]), :is(:state(state-opened),[state--state-opened]), :is(:state(state-closing),[state--state-closing]))) .sbb-menu {
|
|
138
|
+
display: block;
|
|
139
|
+
opacity: 1;
|
|
140
|
+
pointer-events: all;
|
|
141
|
+
animation-name: var(--sbb-menu-open-animation-name, open);
|
|
142
|
+
animation-duration: var(--sbb-menu-animation-duration);
|
|
143
|
+
animation-timing-function: var(--sbb-menu-animation-easing);
|
|
144
|
+
}
|
|
145
|
+
:host(:is(:state(state-closing),[state--state-closing])) .sbb-menu {
|
|
146
|
+
pointer-events: none;
|
|
147
|
+
animation-name: var(--sbb-menu-close-animation-name, close);
|
|
148
|
+
}
|
|
149
|
+
@media (forced-colors: active) {
|
|
150
|
+
.sbb-menu {
|
|
151
|
+
outline: var(--sbb-border-width-1x) solid CanvasText;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
@media (min-width: calc(64rem)) {
|
|
155
|
+
.sbb-menu {
|
|
156
|
+
top: 0;
|
|
157
|
+
bottom: unset;
|
|
158
|
+
left: 0;
|
|
159
|
+
right: unset;
|
|
160
|
+
max-height: fit-content;
|
|
161
|
+
border-radius: var(--sbb-menu-border-radius);
|
|
162
|
+
}
|
|
163
|
+
:host(:not(:is(:state(state-closed),[state--state-closed]))) .sbb-menu {
|
|
164
|
+
top: var(--sbb-menu-position-y, 0);
|
|
165
|
+
left: var(--sbb-menu-position-x, 0);
|
|
166
|
+
max-height: var(--sbb-menu-max-height);
|
|
167
|
+
min-height: var(--sbb-menu-min-height);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.sbb-menu__content {
|
|
172
|
+
--sbb-scrollbar-width: var(--sbb-spacing-fixed-3x);
|
|
173
|
+
}
|
|
174
|
+
.sbb-menu__content::-webkit-scrollbar {
|
|
175
|
+
width: var(--sbb-scrollbar-width);
|
|
176
|
+
height: var(--sbb-scrollbar-width);
|
|
177
|
+
background-color: var(--sbb-scrollbar-track-color, transparent);
|
|
178
|
+
}
|
|
179
|
+
.sbb-menu__content::-webkit-scrollbar-corner {
|
|
180
|
+
background-color: var(--sbb-scrollbar-track-color, transparent);
|
|
181
|
+
}
|
|
182
|
+
.sbb-menu__content::-webkit-scrollbar-thumb {
|
|
183
|
+
background-color: var(--sbb-scrollbar-color, currentcolor);
|
|
184
|
+
border: calc(0.5 * (var(--sbb-scrollbar-width) - var(--sbb-scrollbar-thumb-width))) solid transparent;
|
|
185
|
+
border-radius: var(--sbb-border-radius-4x);
|
|
186
|
+
background-clip: padding-box;
|
|
187
|
+
}
|
|
188
|
+
.sbb-menu__content::-webkit-scrollbar-thumb:hover {
|
|
189
|
+
background-color: var(--sbb-scrollbar-color-hover, currentcolor);
|
|
190
|
+
border-width: calc(0.5 * (var(--sbb-scrollbar-width) - var(--sbb-scrollbar-thumb-width-hover)));
|
|
191
|
+
}
|
|
192
|
+
.sbb-menu__content::-webkit-scrollbar-button, .sbb-menu__content::-webkit-scrollbar-corner {
|
|
193
|
+
display: none;
|
|
194
|
+
}
|
|
195
|
+
@supports not selector(::-webkit-scrollbar) {
|
|
196
|
+
.sbb-menu__content {
|
|
197
|
+
scrollbar-width: var(--sbb-scrollbar-width-firefox);
|
|
198
|
+
scrollbar-color: var(--sbb-scrollbar-color, currentcolor) var(--sbb-scrollbar-track-color, transparent);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
.sbb-menu__content {
|
|
202
|
+
max-height: var(--sbb-menu-max-height);
|
|
203
|
+
padding-block: var(--sbb-spacing-fixed-1x);
|
|
204
|
+
overflow: auto;
|
|
205
|
+
outline: none;
|
|
206
|
+
}
|
|
207
|
+
.sbb-menu__content::after {
|
|
208
|
+
content: "";
|
|
209
|
+
display: block;
|
|
210
|
+
height: var(--sbb-spacing-fixed-8x);
|
|
211
|
+
}
|
|
212
|
+
@media (min-width: calc(64rem)) {
|
|
213
|
+
.sbb-menu__content {
|
|
214
|
+
max-height: fit-content;
|
|
215
|
+
}
|
|
216
|
+
:host(:not(:is(:state(state-closed),[state--state-closed]))) .sbb-menu__content {
|
|
217
|
+
max-height: var(--sbb-menu-max-height);
|
|
218
|
+
min-height: var(--sbb-menu-min-height);
|
|
219
|
+
}
|
|
220
|
+
.sbb-menu__content::after {
|
|
221
|
+
display: none;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
::slotted(:is(:is(:state(sbb-link),[state--sbb-link]), :is(:state(sbb-button),[state--sbb-button]))) {
|
|
226
|
+
color-scheme: only light;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
@keyframes open {
|
|
230
|
+
from {
|
|
231
|
+
opacity: 0;
|
|
232
|
+
translate: 0 var(--sbb-menu-transform-y, 100%);
|
|
233
|
+
}
|
|
234
|
+
to {
|
|
235
|
+
opacity: 1;
|
|
236
|
+
translate: 0 0;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
@keyframes close {
|
|
240
|
+
from {
|
|
241
|
+
opacity: 1;
|
|
242
|
+
translate: 0 0;
|
|
243
|
+
}
|
|
244
|
+
to {
|
|
245
|
+
opacity: 0;
|
|
246
|
+
translate: 0 var(--sbb-menu-transform-y, 100%);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
@keyframes open-sideways {
|
|
250
|
+
from {
|
|
251
|
+
translate: 100% 0;
|
|
252
|
+
}
|
|
253
|
+
to {
|
|
254
|
+
translate: 0 0;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
@keyframes close-sideways {
|
|
258
|
+
from {
|
|
259
|
+
translate: 0 0;
|
|
260
|
+
}
|
|
261
|
+
to {
|
|
262
|
+
translate: 100% 0;
|
|
263
|
+
}
|
|
264
|
+
}`;
|
|
265
|
+
//#endregion
|
|
266
|
+
//#region src/elements/menu/menu/menu.component.ts
|
|
267
|
+
SbbMenuButtonElement.define();
|
|
268
|
+
var MENU_OFFSET = 8;
|
|
269
|
+
var NESTED_MENU_OFFSET = -4;
|
|
270
|
+
var INTERACTIVE_ELEMENTS = [
|
|
271
|
+
"A",
|
|
272
|
+
"BUTTON",
|
|
273
|
+
"SBB-BUTTON",
|
|
274
|
+
"SBB-BUTTON-LINK",
|
|
275
|
+
"SBB-LINK",
|
|
276
|
+
"SBB-BLOCK-LINK",
|
|
277
|
+
"SBB-LINK-BUTTON",
|
|
278
|
+
"SBB-BLOCK-LINK-BUTTON",
|
|
279
|
+
"SBB-MENU-BUTTON",
|
|
280
|
+
"SBB-MENU-LINK"
|
|
281
|
+
];
|
|
282
|
+
var nextId = 0;
|
|
283
|
+
/**
|
|
284
|
+
* It displays a contextual menu with one or more action element.
|
|
285
|
+
*
|
|
286
|
+
* @slot - Use the unnamed slot to add `sbb-menu-button`/`sbb-menu-link` or other elements to the menu.
|
|
287
|
+
* @cssprop [--sbb-menu-z-index=var(--sbb-overlay-default-z-index)] - To specify a custom stack order,
|
|
288
|
+
* the `z-index` can be overridden by defining this CSS variable. The default `z-index` of the
|
|
289
|
+
* component is set to `var(--sbb-overlay-default-z-index)` with a value of `1000`.
|
|
290
|
+
*/
|
|
291
|
+
var SbbMenuElement = (() => {
|
|
292
|
+
let _classSuper = SbbOpenCloseBaseElement;
|
|
293
|
+
let _trigger_decorators;
|
|
294
|
+
let _trigger_initializers = [];
|
|
295
|
+
let _trigger_extraInitializers = [];
|
|
296
|
+
return class SbbMenuElement extends _classSuper {
|
|
297
|
+
static {
|
|
298
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
299
|
+
_trigger_decorators = [idReference(), property()];
|
|
300
|
+
__esDecorate(this, null, _trigger_decorators, {
|
|
301
|
+
kind: "accessor",
|
|
302
|
+
name: "trigger",
|
|
303
|
+
static: false,
|
|
304
|
+
private: false,
|
|
305
|
+
access: {
|
|
306
|
+
has: (obj) => "trigger" in obj,
|
|
307
|
+
get: (obj) => obj.trigger,
|
|
308
|
+
set: (obj, value) => {
|
|
309
|
+
obj.trigger = value;
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
metadata: _metadata
|
|
313
|
+
}, _trigger_initializers, _trigger_extraInitializers);
|
|
314
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, {
|
|
315
|
+
enumerable: true,
|
|
316
|
+
configurable: true,
|
|
317
|
+
writable: true,
|
|
318
|
+
value: _metadata
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
static {
|
|
322
|
+
this.elementName = "sbb-menu";
|
|
323
|
+
}
|
|
324
|
+
static {
|
|
325
|
+
this.styles = [boxSizingStyles, menu_default];
|
|
326
|
+
}
|
|
327
|
+
static {
|
|
328
|
+
this.role = "menu";
|
|
329
|
+
}
|
|
330
|
+
#trigger_accessor_storage;
|
|
331
|
+
/**
|
|
332
|
+
* The element that will trigger the menu overlay.
|
|
333
|
+
*
|
|
334
|
+
* For attribute usage, provide an id reference.
|
|
335
|
+
*/
|
|
336
|
+
get trigger() {
|
|
337
|
+
return this.#trigger_accessor_storage;
|
|
338
|
+
}
|
|
339
|
+
set trigger(value) {
|
|
340
|
+
this.#trigger_accessor_storage = value;
|
|
341
|
+
}
|
|
342
|
+
constructor() {
|
|
343
|
+
super();
|
|
344
|
+
this.#trigger_accessor_storage = __runInitializers(this, _trigger_initializers, null);
|
|
345
|
+
this._menu = __runInitializers(this, _trigger_extraInitializers);
|
|
346
|
+
this._triggerElement = null;
|
|
347
|
+
this._isPointerDownEventOnMenu = false;
|
|
348
|
+
this._escapableOverlayController = new SbbEscapableOverlayController(this);
|
|
349
|
+
this._focusTrapController = new SbbFocusTrapController(this);
|
|
350
|
+
this._scrollHandler = new SbbScrollHandler();
|
|
351
|
+
this._inertController = new SbbInertController(this);
|
|
352
|
+
this._mobileBreakpoint = SbbMediaQueryBreakpointSmallAndBelow;
|
|
353
|
+
this._mediaMatcher = new SbbMediaMatcherController(this, { [this._mobileBreakpoint]: (matches) => {
|
|
354
|
+
if (matches && (this.state === "opening" || this.state === "opened")) this._scrollHandler.disableScroll();
|
|
355
|
+
else this._scrollHandler.enableScroll();
|
|
356
|
+
} });
|
|
357
|
+
this._darkModeController = new SbbDarkModeController(this, () => this._syncNegative());
|
|
358
|
+
this._language = new SbbLanguageController(this);
|
|
359
|
+
this._nestedMenu = null;
|
|
360
|
+
this._pointerDownListener = (event) => {
|
|
361
|
+
const menu = event.target.closest("sbb-menu");
|
|
362
|
+
this._isPointerDownEventOnMenu = isEventOnElement(this._menu, event) || this._nestedMenus().some((el) => menu === el);
|
|
363
|
+
};
|
|
364
|
+
this._closeOnBackdropClick = (event) => {
|
|
365
|
+
const target = event.target;
|
|
366
|
+
if (!this._isPointerDownEventOnMenu && !isEventOnElement(this._menu, event) && !this._nestedMenus().some((el) => el === target)) this.closeAll();
|
|
367
|
+
};
|
|
368
|
+
this.addEventListener?.("keydown", (e) => this._handleKeyDown(e));
|
|
369
|
+
}
|
|
370
|
+
firstUpdated(changedProperties) {
|
|
371
|
+
super.firstUpdated(changedProperties);
|
|
372
|
+
this._configureTrigger();
|
|
373
|
+
}
|
|
374
|
+
escapeStrategy() {
|
|
375
|
+
this.closeAll();
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Opens the menu on trigger click.
|
|
379
|
+
*/
|
|
380
|
+
open() {
|
|
381
|
+
if (this.state === "closing" || this.state === "opened" || !this._menu || !this.dispatchBeforeOpenEvent()) return;
|
|
382
|
+
if (this._isNested()) {
|
|
383
|
+
const parentMenu = this._parentMenu();
|
|
384
|
+
parentMenu.internals.states.add("nested-child");
|
|
385
|
+
if (parentMenu._nestedMenu !== this) parentMenu._nestedMenu?.close();
|
|
386
|
+
parentMenu._nestedMenu = this;
|
|
387
|
+
}
|
|
388
|
+
this.showPopover?.();
|
|
389
|
+
this.state = "opening";
|
|
390
|
+
this._setMenuPosition();
|
|
391
|
+
this._triggerElement?.setAttribute("aria-expanded", "true");
|
|
392
|
+
if (this._isMobile()) this._scrollHandler.disableScroll();
|
|
393
|
+
if (this._isZeroAnimationDuration()) this._handleOpening();
|
|
394
|
+
}
|
|
395
|
+
/** Closes the menu and all its nested menus. */
|
|
396
|
+
close() {
|
|
397
|
+
this._close();
|
|
398
|
+
}
|
|
399
|
+
/** Closes the menu and all related menus (nested and parent menus). */
|
|
400
|
+
closeAll() {
|
|
401
|
+
this._mainMenu()._close(true);
|
|
402
|
+
}
|
|
403
|
+
/** @param [closeAll='false'] - If true, it ensures animations are correct by toggling some states when closing all related menus at once. */
|
|
404
|
+
_close(closeAll = false) {
|
|
405
|
+
if (this.state === "opening" && !this._isNested() || !this.dispatchBeforeCloseEvent()) return;
|
|
406
|
+
this._nestedMenu?._close(closeAll);
|
|
407
|
+
if (this._isNested()) {
|
|
408
|
+
const parentMenu = this._parentMenu();
|
|
409
|
+
if (closeAll) {
|
|
410
|
+
this.internals.states.add("close-all");
|
|
411
|
+
parentMenu.internals.states.add("skip-animation");
|
|
412
|
+
} else {
|
|
413
|
+
this.internals.states.delete("close-all");
|
|
414
|
+
parentMenu.internals.states.delete("skip-animation");
|
|
415
|
+
}
|
|
416
|
+
parentMenu.internals.states.delete("nested-child");
|
|
417
|
+
parentMenu._nestedMenu = null;
|
|
418
|
+
}
|
|
419
|
+
this.state = "closing";
|
|
420
|
+
this._triggerElement?.setAttribute("aria-expanded", "false");
|
|
421
|
+
if (this._isZeroAnimationDuration()) this._handleClosing();
|
|
422
|
+
}
|
|
423
|
+
_isZeroAnimationDuration() {
|
|
424
|
+
return isZeroAnimationDuration(this, "--sbb-menu-animation-duration");
|
|
425
|
+
}
|
|
426
|
+
_handleOpening() {
|
|
427
|
+
this.state = "opened";
|
|
428
|
+
if (!this._isNested()) this._inertController.activate();
|
|
429
|
+
else this._updateNestedInert();
|
|
430
|
+
this._escapableOverlayController.connect();
|
|
431
|
+
this._focusTrapController.focusInitialElement();
|
|
432
|
+
this._focusTrapController.enabled = true;
|
|
433
|
+
this._attachWindowEvents();
|
|
434
|
+
this.dispatchOpenEvent();
|
|
435
|
+
}
|
|
436
|
+
_handleClosing() {
|
|
437
|
+
this.state = "closed";
|
|
438
|
+
this.internals.states.delete("skip-animation");
|
|
439
|
+
this.internals.states.delete("close-all");
|
|
440
|
+
this.hidePopover?.();
|
|
441
|
+
this._menu?.firstElementChild?.scrollTo(0, 0);
|
|
442
|
+
if (!this._isNested()) this._inertController.deactivate();
|
|
443
|
+
else this._updateNestedInert();
|
|
444
|
+
this._triggerElement?.focus({ preventScroll: ["sbb-header-button", "sbb-header-link"].includes(this._triggerElement.localName) });
|
|
445
|
+
this._escapableOverlayController.disconnect();
|
|
446
|
+
this.dispatchCloseEvent();
|
|
447
|
+
this._windowEventsController?.abort();
|
|
448
|
+
this._focusTrapController.enabled = false;
|
|
449
|
+
this._scrollHandler.enableScroll();
|
|
450
|
+
}
|
|
451
|
+
_handleKeyDown(evt) {
|
|
452
|
+
if (!isArrowKeyOrPageKeysPressed(evt)) return;
|
|
453
|
+
evt.preventDefault();
|
|
454
|
+
const enabledActions = Array.from(this.querySelectorAll("sbb-menu-button, sbb-menu-link")).concat(this.shadowRoot.querySelector("sbb-menu-button")).filter((el) => (!el.disabled || el.disabledInteractive) && interactivityChecker.isVisible(el));
|
|
455
|
+
const current = enabledActions.findIndex((e) => e === evt.target);
|
|
456
|
+
let nextIndex;
|
|
457
|
+
switch (evt.key) {
|
|
458
|
+
case "ArrowUp":
|
|
459
|
+
case "ArrowDown":
|
|
460
|
+
nextIndex = getNextElementIndex(evt, current, enabledActions.length);
|
|
461
|
+
break;
|
|
462
|
+
case "ArrowLeft":
|
|
463
|
+
if (this._isNested()) this.close();
|
|
464
|
+
break;
|
|
465
|
+
case "ArrowRight":
|
|
466
|
+
if (evt.target.matches(":is(:state(sbb-menu-trigger),[state--sbb-menu-trigger])")) evt.target.click();
|
|
467
|
+
break;
|
|
468
|
+
case "PageUp":
|
|
469
|
+
case "Home":
|
|
470
|
+
nextIndex = 0;
|
|
471
|
+
break;
|
|
472
|
+
case "End":
|
|
473
|
+
case "PageDown":
|
|
474
|
+
nextIndex = enabledActions.length - 1;
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
if (nextIndex !== void 0) enabledActions[nextIndex].focus();
|
|
478
|
+
}
|
|
479
|
+
createRenderRoot() {
|
|
480
|
+
const renderRoot = super.createRenderRoot();
|
|
481
|
+
this.shadowRoot?.addEventListener("slotchange", () => this._syncNegative(), { capture: true });
|
|
482
|
+
return renderRoot;
|
|
483
|
+
}
|
|
484
|
+
connectedCallback() {
|
|
485
|
+
this.popover = "manual";
|
|
486
|
+
super.connectedCallback();
|
|
487
|
+
this.id ||= `sbb-menu-${nextId++}`;
|
|
488
|
+
if (this.hasUpdated) this._configureTrigger();
|
|
489
|
+
}
|
|
490
|
+
disconnectedCallback() {
|
|
491
|
+
super.disconnectedCallback();
|
|
492
|
+
this._triggerElement = null;
|
|
493
|
+
this._triggerAbortController?.abort();
|
|
494
|
+
this._windowEventsController?.abort();
|
|
495
|
+
this._scrollHandler.enableScroll();
|
|
496
|
+
}
|
|
497
|
+
requestUpdate(name, oldValue, options) {
|
|
498
|
+
super.requestUpdate(name, oldValue, options);
|
|
499
|
+
if (!isServer && (!name || name === "trigger") && this.hasUpdated) this._configureTrigger();
|
|
500
|
+
}
|
|
501
|
+
_configureTrigger() {
|
|
502
|
+
if (this.trigger === this._triggerElement) return;
|
|
503
|
+
this._triggerAbortController?.abort();
|
|
504
|
+
removeAriaOverlayTriggerAttributes(this._triggerElement);
|
|
505
|
+
this._triggerElement = this.trigger;
|
|
506
|
+
if (!this._triggerElement) return;
|
|
507
|
+
setAriaOverlayTriggerAttributes(this._triggerElement, "menu", this.id, this.state);
|
|
508
|
+
this._triggerAbortController = new AbortController();
|
|
509
|
+
this._triggerElement.addEventListener("click", () => this.open(), { signal: this._triggerAbortController.signal });
|
|
510
|
+
this.toggleState("nested", ["sbb-menu-button", "sbb-menu-link"].includes(this._triggerElement.localName));
|
|
511
|
+
ɵstateController(this._triggerElement).add("sbb-menu-trigger");
|
|
512
|
+
}
|
|
513
|
+
_attachWindowEvents() {
|
|
514
|
+
this._windowEventsController = new AbortController();
|
|
515
|
+
document.addEventListener("scroll", () => this._setMenuPosition(), {
|
|
516
|
+
passive: true,
|
|
517
|
+
signal: this._windowEventsController.signal,
|
|
518
|
+
capture: true
|
|
519
|
+
});
|
|
520
|
+
window.addEventListener("resize", () => this._setMenuPosition(), {
|
|
521
|
+
passive: true,
|
|
522
|
+
signal: this._windowEventsController.signal
|
|
523
|
+
});
|
|
524
|
+
if (!this._isNested()) {
|
|
525
|
+
window.addEventListener("pointerdown", this._pointerDownListener, { signal: this._windowEventsController.signal });
|
|
526
|
+
window.addEventListener("pointerup", this._closeOnBackdropClick, { signal: this._windowEventsController.signal });
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
_interactiveElementClick(event) {
|
|
530
|
+
const target = event.target;
|
|
531
|
+
if (INTERACTIVE_ELEMENTS.includes(target.nodeName) && !target.hasAttribute("disabled") && !target.matches(":is(:state(sbb-menu-trigger),[state--sbb-menu-trigger])") && target.id !== "sbb-menu__back-button") this.closeAll();
|
|
532
|
+
}
|
|
533
|
+
/** Converts the linked list into an array of SbbMenuElement. */
|
|
534
|
+
_nestedMenus() {
|
|
535
|
+
const menus = [];
|
|
536
|
+
let current = this._nestedMenu;
|
|
537
|
+
while (current) {
|
|
538
|
+
menus.push(current);
|
|
539
|
+
current = current._nestedMenu;
|
|
540
|
+
}
|
|
541
|
+
return menus;
|
|
542
|
+
}
|
|
543
|
+
_parentMenu() {
|
|
544
|
+
return this._triggerElement?.closest("sbb-menu") ?? null;
|
|
545
|
+
}
|
|
546
|
+
/** The outermost menu. */
|
|
547
|
+
_mainMenu() {
|
|
548
|
+
return this._isNested() ? this._parentMenu()?._mainMenu() ?? this : this;
|
|
549
|
+
}
|
|
550
|
+
_isNested() {
|
|
551
|
+
return !!this._parentMenu();
|
|
552
|
+
}
|
|
553
|
+
_updateNestedInert() {
|
|
554
|
+
this._inertController.restoreAllExempted();
|
|
555
|
+
this._mainMenu()._nestedMenus().forEach((menu) => this._inertController.exempt(menu));
|
|
556
|
+
}
|
|
557
|
+
_handleMouseOver(event) {
|
|
558
|
+
const element = event.target;
|
|
559
|
+
const isMobile = this._isMobile();
|
|
560
|
+
if (!isMobile && this._nestedMenu && !element.classList.contains("sbb-menu__content") && !(element.getAttribute("aria-expanded") === "true")) this._nestedMenu.close();
|
|
561
|
+
if (element.matches(":is(:state(sbb-menu-trigger),[state--sbb-menu-trigger])") && !isMobile) element.click();
|
|
562
|
+
}
|
|
563
|
+
_onMenuAnimationEnd(event) {
|
|
564
|
+
if ((event.animationName === "open" || event.animationName === "open-sideways") && this.state === "opening") this._handleOpening();
|
|
565
|
+
else if ((event.animationName === "close" || event.animationName === "close-sideways") && this.state === "closing") this._handleClosing();
|
|
566
|
+
}
|
|
567
|
+
_setMenuPosition() {
|
|
568
|
+
if (this._isMobile() || !this._menu || !this._triggerElement || this.state === "closing") return;
|
|
569
|
+
const menuPosition = !this._isNested() ? getElementPosition(this.shadowRoot.querySelector(".sbb-menu__content"), this._triggerElement, this.shadowRoot.querySelector(".sbb-menu__container"), { verticalOffset: MENU_OFFSET }) : getElementPositionHorizontal(this.shadowRoot.querySelector(".sbb-menu__content"), this._triggerElement, this.shadowRoot.querySelector(".sbb-menu__container"), {
|
|
570
|
+
horizontalOffset: MENU_OFFSET,
|
|
571
|
+
verticalOffset: NESTED_MENU_OFFSET,
|
|
572
|
+
contentSelector: ".sbb-menu__content"
|
|
573
|
+
});
|
|
574
|
+
this.style.setProperty("--sbb-menu-position-x", `${menuPosition.left}px`);
|
|
575
|
+
this.style.setProperty("--sbb-menu-position-y", `${menuPosition.top}px`);
|
|
576
|
+
this.style.setProperty("--sbb-menu-max-height", menuPosition.maxHeight);
|
|
577
|
+
}
|
|
578
|
+
_syncNegative() {
|
|
579
|
+
this.querySelectorAll(":is(:state(sbb-link),[state--sbb-link]), :is(:state(sbb-button),[state--sbb-button])")?.forEach((el) => {
|
|
580
|
+
customElements.upgrade(el);
|
|
581
|
+
el.negative = !this._darkModeController.matches();
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
_isMobile() {
|
|
585
|
+
return this._mediaMatcher.matches(this._mobileBreakpoint) ?? true;
|
|
586
|
+
}
|
|
587
|
+
render() {
|
|
588
|
+
return html`
|
|
589
|
+
<div class="sbb-menu__container">
|
|
590
|
+
<div
|
|
591
|
+
@animationend=${this._onMenuAnimationEnd}
|
|
592
|
+
@mouseover=${(e) => this._handleMouseOver(e)}
|
|
593
|
+
class="sbb-menu"
|
|
594
|
+
${ref((el) => this._menu = el)}
|
|
595
|
+
>
|
|
596
|
+
<div
|
|
597
|
+
@click=${(event) => this._interactiveElementClick(event)}
|
|
598
|
+
@scroll=${(e) => forwardEvent(e, document)}
|
|
599
|
+
class="sbb-menu__content"
|
|
600
|
+
>
|
|
601
|
+
<slot></slot>
|
|
602
|
+
<sbb-divider></sbb-divider>
|
|
603
|
+
<sbb-menu-button
|
|
604
|
+
id="sbb-menu__back-button"
|
|
605
|
+
@click=${() => this.close()}
|
|
606
|
+
icon-name="chevron-small-left-small"
|
|
607
|
+
>
|
|
608
|
+
${i18nGoBack[this._language.current]}
|
|
609
|
+
</sbb-menu-button>
|
|
610
|
+
</div>
|
|
611
|
+
</div>
|
|
612
|
+
</div>
|
|
613
|
+
`;
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
})();
|
|
617
|
+
//#endregion
|
|
618
|
+
export { SbbMenuElement as t };
|
|
619
|
+
|
|
620
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudS5jb21wb25lbnQtRDRudDZNOWIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VsZW1lbnRzL21lbnUvbWVudS9tZW51LnNjc3M/bGl0JmlubGluZSIsIi4uLy4uLy4uL3NyYy9lbGVtZW50cy9tZW51L21lbnUvbWVudS5jb21wb25lbnQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiQHVzZSAnLi4vLi4vY29yZS9zdHlsZXMnIGFzIHNiYjtcblxuOmhvc3Qge1xuICAvLyBXZSB1c2UgdGhpcyBydWxlIHRvIG1ha2UgdGhlIGlubmVyIGNvbnRhaW5lciBlbGVtZW50IHRvIGFwcGVhciBhcyBpZiBpdCB3ZXJlIGFcbiAgLy8gZGlyZWN0IGNoaWxkIG9mIHRoZSBob3N0J3MgcGFyZW50IGVsZW1lbnQuIFRoaXMgaXMgdXNlZnVsIGJlY2F1c2UgdGhlIGhvc3RcbiAgLy8gc2hvdWxkIGJlIGlnbm9yZWQgd2hlbiB1c2luZyBDU1MgZ3JpZCBvciBzaW1pbGFyIGxheW91dCB0ZWNobmlxdWVzLlxuICBkaXNwbGF5OiBjb250ZW50cztcblxuICAtLXNiYi1tZW51LWFuaW1hdGlvbi1kdXJhdGlvbjogdmFyKFxuICAgIC0tc2JiLWRpc2FibGUtYW5pbWF0aW9uLWR1cmF0aW9uLFxuICAgIHZhcigtLXNiYi1hbmltYXRpb24tZHVyYXRpb24tNngpXG4gICk7XG4gIC0tc2JiLWZvY3VzLW91dGxpbmUtY29sb3I6IHZhcigtLXNiYi1mb2N1cy1vdXRsaW5lLWNvbG9yLWRhcmspO1xuICAtLV9zYmItbWVudS1pbnNldDogMCBhdXRvIGF1dG8gMDtcblxuICBAaW5jbHVkZSBzYmIuc2Nyb2xsYmFyLXZhcmlhYmxlcygkbmVnYXRpdmU6IHRydWUpO1xuXG4gIEBpbmNsdWRlIHNiYi5tcSgkZnJvbTogbGFyZ2UpIHtcbiAgICAtLXNiYi1tZW51LWJhY2stYnV0dG9uLWRpc3BsYXk6IG5vbmU7XG4gIH1cbn1cblxuOmhvc3QoOmlzKDpzdGF0ZShzdGF0ZS1vcGVuZWQpLCA6c3RhdGUoc3RhdGUtb3BlbmluZykpKSB7XG4gIC0tc2JiLW1lbnUtdmlzaWJpbGl0eTogdmlzaWJsZTtcbiAgLS1zYmItbWVudS1iYWNrZHJvcC1jb2xvcjogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLXNiYi1jb2xvci1ibGFjaykgMjAlLCB0cmFuc3BhcmVudCk7XG5cbiAgQGluY2x1ZGUgc2JiLm1xKCRmcm9tOiBsYXJnZSkge1xuICAgIC0tc2JiLW1lbnUtYmFja2Ryb3AtY29sb3I6IHRyYW5zcGFyZW50O1xuICB9XG59XG5cbjpob3N0KDpub3QoOnN0YXRlKG5lc3RlZCkpKSB7XG4gIC0tc2JiLW1lbnUtYmFjay1idXR0b24tZGlzcGxheTogbm9uZTtcbn1cblxuOmhvc3QoOm5vdCg6c3RhdGUoc3RhdGUtY2xvc2VkKSkpIHtcbiAgLS1fc2JiLW1lbnUtaW5zZXQ6IDA7XG59XG5cbjpob3N0KDpzdGF0ZShkYXJrKSkge1xuICAtLXNiYi1mb2N1cy1vdXRsaW5lLWNvbG9yOiB2YXIoLS1zYmItZm9jdXMtb3V0bGluZS1jb2xvci1kZWZhdWx0KTtcblxuICAvLyBXZSBoYXZlIHRvIGVuc3VyZSB0aGF0IHRoZSBzY3JvbGxiYXIgaXMgdmlzaWJsZSBpbiBkYXJrIG1vZGUgd2l0aCBub24tZGFyayBtb2RlIHZhbHVlcy5cbiAgLS1zYmItc2Nyb2xsYmFyLWNvbG9yOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tc2JiLWNvbG9yLWJsYWNrKSAzMCUsIHRyYW5zcGFyZW50KTtcbiAgLS1zYmItc2Nyb2xsYmFyLWNvbG9yLWhvdmVyOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tc2JiLWNvbG9yLWJsYWNrKSA2MCUsIHRyYW5zcGFyZW50KTtcbn1cblxuQGluY2x1ZGUgc2JiLm1xKCR0bzogbGFyZ2UpIHtcbiAgOmhvc3QoOnN0YXRlKHNraXAtYW5pbWF0aW9uKSkge1xuICAgIC0tc2JiLW1lbnUtYW5pbWF0aW9uLWR1cmF0aW9uOiAwbXM7XG4gIH1cblxuICA6aG9zdCg6c3RhdGUobmVzdGVkLWNoaWxkKSkge1xuICAgIC0tc2JiLW1lbnUtdHJhbnNmb3JtLXg6IC0xMDAlO1xuICB9XG5cbiAgOmhvc3QoOnN0YXRlKG5lc3RlZCk6aXMoOnN0YXRlKHN0YXRlLW9wZW5pbmcpLCA6c3RhdGUoc3RhdGUtb3BlbmVkKSwgOnN0YXRlKHN0YXRlLWNsb3NpbmcpKSkge1xuICAgIC0tc2JiLW1lbnUtb3Blbi1hbmltYXRpb24tbmFtZTogb3Blbi1zaWRld2F5cztcbiAgfVxuXG4gIDpob3N0KDpzdGF0ZShzdGF0ZS1jbG9zaW5nKTpzdGF0ZShuZXN0ZWQpOm5vdCg6c3RhdGUoY2xvc2UtYWxsKSkpIHtcbiAgICAtLXNiYi1tZW51LWNsb3NlLWFuaW1hdGlvbi1uYW1lOiBjbG9zZS1zaWRld2F5cztcbiAgfVxufVxuXG46OnNsb3R0ZWQoOm5vdChzYmItbWVudS1idXR0b24sIHNiYi1tZW51LWxpbmssIHNiYi1kaXZpZGVyKSkge1xuICBkaXNwbGF5OiBibG9jaztcbiAgcGFkZGluZy1pbmxpbmU6IHZhcigtLXNiYi1zcGFjaW5nLWZpeGVkLTV4KTtcbn1cblxuc2JiLWRpdmlkZXIsXG46OnNsb3R0ZWQoc2JiLWRpdmlkZXIpIHtcbiAgLS1zYmItZGl2aWRlci1jb2xvcjogdmFyKC0tc2JiLWJhY2tncm91bmQtY29sb3ItNC1pbnZlcnRlZCk7XG5cbiAgbWFyZ2luLWJsb2NrOiB2YXIoLS1zYmItc3BhY2luZy1maXhlZC0yeCk7XG59XG5cbnNiYi1kaXZpZGVyLFxuI3NiYi1tZW51X19iYWNrLWJ1dHRvbiB7XG4gIGRpc3BsYXk6IHZhcigtLXNiYi1tZW51LWJhY2stYnV0dG9uLWRpc3BsYXksIGJsb2NrKTtcbn1cblxuLnNiYi1tZW51X19jb250YWluZXIge1xuICBwb3NpdGlvbjogZml4ZWQ7XG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICBpbnNldDogdmFyKC0tX3NiYi1tZW51LWluc2V0KTtcbiAgaGVpZ2h0OiB2YXIoLS1zYmItbWVudS1jb250YWluZXItaGVpZ2h0KTtcbiAgei1pbmRleDogdmFyKC0tc2JiLW1lbnUtei1pbmRleCwgdmFyKC0tc2JiLW92ZXJsYXktZGVmYXVsdC16LWluZGV4KSk7XG5cbiAgLy8gTWVudSBiYWNrZHJvcCAob25seSB2aXNpYmxlIG9uIG1vYmlsZSlcbiAgJjo6YmVmb3JlIHtcbiAgICBjb250ZW50OiAnJztcbiAgICB2aXNpYmlsaXR5OiB2YXIoLS1zYmItbWVudS12aXNpYmlsaXR5LCBoaWRkZW4pO1xuICAgIHBvaW50ZXItZXZlbnRzOiBhbGw7XG4gICAgcG9zaXRpb246IGZpeGVkO1xuICAgIGluc2V0OiB2YXIoLS1fc2JiLW1lbnUtaW5zZXQpO1xuICAgIGhlaWdodDogdmFyKC0tc2JiLW1lbnUtY29udGFpbmVyLWhlaWdodCk7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tc2JiLW1lbnUtYmFja2Ryb3AtY29sb3IsIHRyYW5zcGFyZW50KTtcbiAgICB0cmFuc2l0aW9uOiB7XG4gICAgICBkdXJhdGlvbjogdmFyKC0tc2JiLW1lbnUtYW5pbWF0aW9uLWR1cmF0aW9uKTtcbiAgICAgIHRpbWluZy1mdW5jdGlvbjogdmFyKC0tc2JiLW1lbnUtYW5pbWF0aW9uLWVhc2luZyk7XG4gICAgICBwcm9wZXJ0eTogYmFja2dyb3VuZC1jb2xvciwgdmlzaWJpbGl0eTtcbiAgICB9XG5cbiAgICAvLyBIaWRlIHRoZSBiYWNrZHJvcCB3aGVuIGluIG5lc3RlZCBzdGF0ZVxuICAgIDpob3N0KDpzdGF0ZShuZXN0ZWQpKSAmIHtcbiAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgfVxuICB9XG59XG5cbi5zYmItbWVudSB7XG4gIGRpc3BsYXk6IG5vbmU7XG4gIG9wYWNpdHk6IDA7XG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICBtYXgtd2lkdGg6IHZhcigtLXNiYi1tZW51LW1heC13aWR0aCk7XG4gIG1pbi13aWR0aDogdmFyKC0tc2JiLW1lbnUtbWluLXdpZHRoKTtcbiAgdGV4dC1hbGlnbjogc3RhcnQ7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgaW5zZXQtaW5saW5lLXN0YXJ0OiAwO1xuICBpbnNldC1ibG9jay1zdGFydDogdW5zZXQ7XG4gIGluc2V0LWJsb2NrLWVuZDogMDtcbiAgaW5zZXQtaW5saW5lLWVuZDogdW5zZXQ7XG4gIGNvbG9yOiB2YXIoLS1zYmItbWVudS1jb2xvcik7XG4gIGJvcmRlcjogbm9uZTtcbiAgYm9yZGVyLXJhZGl1czogdmFyKC0tc2JiLW1lbnUtYm9yZGVyLXJhZGl1cykgdmFyKC0tc2JiLW1lbnUtYm9yZGVyLXJhZGl1cykgMCAwO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1zYmItbWVudS1iYWNrZ3JvdW5kLWNvbG9yKTtcbiAgcGFkZGluZzogMDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdHJhbnNsYXRlOiB2YXIoLS1zYmItbWVudS10cmFuc2Zvcm0teCwgMCkgMDtcblxuICAvLyBVc2VkIHdoZW4gbmF2aWdhdGluZyBiYWNrIGZyb20gbmVzdGVkIG1lbnUgaW4gbW9iaWxlIHZpZXdcbiAgdHJhbnNpdGlvbjogdHJhbnNsYXRlIHZhcigtLXNiYi1tZW51LWFuaW1hdGlvbi1kdXJhdGlvbik7XG5cbiAgOmhvc3QoOmlzKDpzdGF0ZShzdGF0ZS1vcGVuaW5nKSwgOnN0YXRlKHN0YXRlLW9wZW5lZCksIDpzdGF0ZShzdGF0ZS1jbG9zaW5nKSkpICYge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIG9wYWNpdHk6IDE7XG4gICAgcG9pbnRlci1ldmVudHM6IGFsbDtcblxuICAgIGFuaW1hdGlvbjoge1xuICAgICAgbmFtZTogdmFyKC0tc2JiLW1lbnUtb3Blbi1hbmltYXRpb24tbmFtZSwgb3Blbik7XG4gICAgICBkdXJhdGlvbjogdmFyKC0tc2JiLW1lbnUtYW5pbWF0aW9uLWR1cmF0aW9uKTtcbiAgICAgIHRpbWluZy1mdW5jdGlvbjogdmFyKC0tc2JiLW1lbnUtYW5pbWF0aW9uLWVhc2luZyk7XG4gICAgfVxuICB9XG5cbiAgOmhvc3QoOnN0YXRlKHN0YXRlLWNsb3NpbmcpKSAmIHtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICBhbmltYXRpb24tbmFtZTogdmFyKC0tc2JiLW1lbnUtY2xvc2UtYW5pbWF0aW9uLW5hbWUsIGNsb3NlKTtcbiAgfVxuXG4gIEBpbmNsdWRlIHNiYi5pZi1mb3JjZWQtY29sb3JzIHtcbiAgICBvdXRsaW5lOiB2YXIoLS1zYmItYm9yZGVyLXdpZHRoLTF4KSBzb2xpZCBDYW52YXNUZXh0O1xuICB9XG5cbiAgQGluY2x1ZGUgc2JiLm1xKCRmcm9tOiBsYXJnZSkge1xuICAgIHRvcDogMDtcbiAgICBib3R0b206IHVuc2V0O1xuICAgIGxlZnQ6IDA7XG4gICAgcmlnaHQ6IHVuc2V0O1xuICAgIG1heC1oZWlnaHQ6IGZpdC1jb250ZW50O1xuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXNiYi1tZW51LWJvcmRlci1yYWRpdXMpO1xuXG4gICAgOmhvc3QoOm5vdCg6c3RhdGUoc3RhdGUtY2xvc2VkKSkpICYge1xuICAgICAgdG9wOiB2YXIoLS1zYmItbWVudS1wb3NpdGlvbi15LCAwKTtcbiAgICAgIGxlZnQ6IHZhcigtLXNiYi1tZW51LXBvc2l0aW9uLXgsIDApO1xuICAgICAgbWF4LWhlaWdodDogdmFyKC0tc2JiLW1lbnUtbWF4LWhlaWdodCk7XG4gICAgICBtaW4taGVpZ2h0OiB2YXIoLS1zYmItbWVudS1taW4taGVpZ2h0KTtcbiAgICB9XG4gIH1cbn1cblxuLnNiYi1tZW51X19jb250ZW50IHtcbiAgQGluY2x1ZGUgc2JiLnNjcm9sbGJhci1ydWxlcztcblxuICBtYXgtaGVpZ2h0OiB2YXIoLS1zYmItbWVudS1tYXgtaGVpZ2h0KTtcbiAgcGFkZGluZy1ibG9jazogdmFyKC0tc2JiLXNwYWNpbmctZml4ZWQtMXgpO1xuICBvdmVyZmxvdzogYXV0bztcbiAgb3V0bGluZTogbm9uZTtcblxuICAvLyBNYXJnaW4gYm90dG9tIGluIG1vYmlsZSB2YXJpYW50XG4gICY6OmFmdGVyIHtcbiAgICBjb250ZW50OiAnJztcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBoZWlnaHQ6IHZhcigtLXNiYi1zcGFjaW5nLWZpeGVkLTh4KTtcbiAgfVxuXG4gIEBpbmNsdWRlIHNiYi5tcSgkZnJvbTogbGFyZ2UpIHtcbiAgICBtYXgtaGVpZ2h0OiBmaXQtY29udGVudDtcblxuICAgIDpob3N0KDpub3QoOnN0YXRlKHN0YXRlLWNsb3NlZCkpKSAmIHtcbiAgICAgIG1heC1oZWlnaHQ6IHZhcigtLXNiYi1tZW51LW1heC1oZWlnaHQpO1xuICAgICAgbWluLWhlaWdodDogdmFyKC0tc2JiLW1lbnUtbWluLWhlaWdodCk7XG4gICAgfVxuXG4gICAgJjo6YWZ0ZXIge1xuICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG4gIH1cbn1cblxuOjpzbG90dGVkKDppcyg6c3RhdGUoc2JiLWxpbmspLCA6c3RhdGUoc2JiLWJ1dHRvbikpKSB7XG4gIC8vIEFzIHRoZSBiYWNrZ3JvdW5kIHR1cm5zIHdoaXRlLCB3ZSBuZWVkIHRvIGVuc3VyZSB0aGF0IGJ1dHRvbnMgYW5kIGxpbmtzIGFyZSBkaXNwbGF5ZWQgaW4gcG9zaXRpdmUuXG4gIGNvbG9yLXNjaGVtZTogb25seSBsaWdodDtcbn1cblxuQGtleWZyYW1lcyBvcGVuIHtcbiAgZnJvbSB7XG4gICAgb3BhY2l0eTogMDtcbiAgICB0cmFuc2xhdGU6IDAgdmFyKC0tc2JiLW1lbnUtdHJhbnNmb3JtLXksIDEwMCUpO1xuICB9XG5cbiAgdG8ge1xuICAgIG9wYWNpdHk6IDE7XG4gICAgdHJhbnNsYXRlOiAwIDA7XG4gIH1cbn1cblxuQGtleWZyYW1lcyBjbG9zZSB7XG4gIGZyb20ge1xuICAgIG9wYWNpdHk6IDE7XG4gICAgdHJhbnNsYXRlOiAwIDA7XG4gIH1cblxuICB0byB7XG4gICAgb3BhY2l0eTogMDtcbiAgICB0cmFuc2xhdGU6IDAgdmFyKC0tc2JiLW1lbnUtdHJhbnNmb3JtLXksIDEwMCUpO1xuICB9XG59XG5cbkBrZXlmcmFtZXMgb3Blbi1zaWRld2F5cyB7XG4gIGZyb20ge1xuICAgIHRyYW5zbGF0ZTogMTAwJSAwO1xuICB9XG5cbiAgdG8ge1xuICAgIHRyYW5zbGF0ZTogMCAwO1xuICB9XG59XG5cbkBrZXlmcmFtZXMgY2xvc2Utc2lkZXdheXMge1xuICBmcm9tIHtcbiAgICB0cmFuc2xhdGU6IDAgMDtcbiAgfVxuXG4gIHRvIHtcbiAgICB0cmFuc2xhdGU6IDEwMCUgMDtcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgdHlwZSBDU1NSZXN1bHRHcm91cCxcbiAgaHRtbCxcbiAgaXNTZXJ2ZXIsXG4gIHR5cGUgUHJvcGVydHlEZWNsYXJhdGlvbixcbiAgdHlwZSBQcm9wZXJ0eVZhbHVlcyxcbiAgdHlwZSBUZW1wbGF0ZVJlc3VsdCxcbn0gZnJvbSAnbGl0JztcbmltcG9ydCB7IHByb3BlcnR5IH0gZnJvbSAnbGl0L2RlY29yYXRvcnMuanMnO1xuaW1wb3J0IHsgcmVmIH0gZnJvbSAnbGl0L2RpcmVjdGl2ZXMvcmVmLmpzJztcblxuaW1wb3J0IHtcbiAgZ2V0TmV4dEVsZW1lbnRJbmRleCxcbiAgaW50ZXJhY3Rpdml0eUNoZWNrZXIsXG4gIGlzQXJyb3dLZXlPclBhZ2VLZXlzUHJlc3NlZCxcbiAgU2JiRm9jdXNUcmFwQ29udHJvbGxlcixcbn0gZnJvbSAnLi4vLi4vY29yZS9hMTF5LnRzJztcbmltcG9ydCB7IFNiYk9wZW5DbG9zZUJhc2VFbGVtZW50IH0gZnJvbSAnLi4vLi4vY29yZS9iYXNlLWVsZW1lbnRzLnRzJztcbmltcG9ydCB7XG4gIFNiYkRhcmtNb2RlQ29udHJvbGxlcixcbiAgU2JiRXNjYXBhYmxlT3ZlcmxheUNvbnRyb2xsZXIsXG4gIFNiYkluZXJ0Q29udHJvbGxlcixcbiAgU2JiTGFuZ3VhZ2VDb250cm9sbGVyLFxuICBTYmJNZWRpYU1hdGNoZXJDb250cm9sbGVyLFxuICBTYmJNZWRpYVF1ZXJ5QnJlYWtwb2ludFNtYWxsQW5kQmVsb3csXG59IGZyb20gJy4uLy4uL2NvcmUvY29udHJvbGxlcnMudHMnO1xuaW1wb3J0IHsgaWRSZWZlcmVuY2UgfSBmcm9tICcuLi8uLi9jb3JlL2RlY29yYXRvcnMudHMnO1xuaW1wb3J0IHsgaXNaZXJvQW5pbWF0aW9uRHVyYXRpb24sIFNiYlNjcm9sbEhhbmRsZXIgfSBmcm9tICcuLi8uLi9jb3JlL2RvbS50cyc7XG5pbXBvcnQgeyBmb3J3YXJkRXZlbnQgfSBmcm9tICcuLi8uLi9jb3JlL2V2ZW50aW5nLnRzJztcbmltcG9ydCB7IGkxOG5Hb0JhY2sgfSBmcm9tICcuLi8uLi9jb3JlL2kxOG4vaTE4bi50cyc7XG5pbXBvcnQgeyDJtXN0YXRlQ29udHJvbGxlciwgdHlwZSBTYmJOZWdhdGl2ZU1peGluVHlwZSB9IGZyb20gJy4uLy4uL2NvcmUvbWl4aW5zLnRzJztcbmltcG9ydCB7XG4gIGdldEVsZW1lbnRQb3NpdGlvbixcbiAgZ2V0RWxlbWVudFBvc2l0aW9uSG9yaXpvbnRhbCxcbiAgaXNFdmVudE9uRWxlbWVudCxcbiAgcmVtb3ZlQXJpYU92ZXJsYXlUcmlnZ2VyQXR0cmlidXRlcyxcbiAgc2V0QXJpYU92ZXJsYXlUcmlnZ2VyQXR0cmlidXRlcyxcbn0gZnJvbSAnLi4vLi4vY29yZS9vdmVybGF5LnRzJztcbmltcG9ydCB7IGJveFNpemluZ1N0eWxlcyB9IGZyb20gJy4uLy4uL2NvcmUvc3R5bGVzLnRzJztcbmltcG9ydCB7IFNiYk1lbnVCdXR0b25FbGVtZW50IH0gZnJvbSAnLi4vbWVudS1idXR0b24vbWVudS1idXR0b24uY29tcG9uZW50LnRzJztcbmltcG9ydCB0eXBlIHsgU2JiTWVudUxpbmtFbGVtZW50IH0gZnJvbSAnLi4vbWVudS1saW5rL21lbnUtbGluay5jb21wb25lbnQudHMnO1xuXG5pbXBvcnQgc3R5bGUgZnJvbSAnLi9tZW51LnNjc3M/bGl0JmlubGluZSc7XG5cbmltcG9ydCAnLi4vLi4vZGl2aWRlci50cyc7XG5cblNiYk1lbnVCdXR0b25FbGVtZW50LmRlZmluZSgpO1xuXG5jb25zdCBNRU5VX09GRlNFVCA9IDg7XG5jb25zdCBORVNURURfTUVOVV9PRkZTRVQgPSAtNDtcbmNvbnN0IElOVEVSQUNUSVZFX0VMRU1FTlRTID0gW1xuICAnQScsXG4gICdCVVRUT04nLFxuICAnU0JCLUJVVFRPTicsXG4gICdTQkItQlVUVE9OLUxJTksnLFxuICAnU0JCLUxJTksnLFxuICAnU0JCLUJMT0NLLUxJTksnLFxuICAnU0JCLUxJTkstQlVUVE9OJyxcbiAgJ1NCQi1CTE9DSy1MSU5LLUJVVFRPTicsXG4gICdTQkItTUVOVS1CVVRUT04nLFxuICAnU0JCLU1FTlUtTElOSycsXG5dO1xuXG5sZXQgbmV4dElkID0gMDtcblxuLyoqXG4gKiBJdCBkaXNwbGF5cyBhIGNvbnRleHR1YWwgbWVudSB3aXRoIG9uZSBvciBtb3JlIGFjdGlvbiBlbGVtZW50LlxuICpcbiAqIEBzbG90IC0gVXNlIHRoZSB1bm5hbWVkIHNsb3QgdG8gYWRkIGBzYmItbWVudS1idXR0b25gL2BzYmItbWVudS1saW5rYCBvciBvdGhlciBlbGVtZW50cyB0byB0aGUgbWVudS5cbiAqIEBjc3Nwcm9wIFstLXNiYi1tZW51LXotaW5kZXg9dmFyKC0tc2JiLW92ZXJsYXktZGVmYXVsdC16LWluZGV4KV0gLSBUbyBzcGVjaWZ5IGEgY3VzdG9tIHN0YWNrIG9yZGVyLFxuICogdGhlIGB6LWluZGV4YCBjYW4gYmUgb3ZlcnJpZGRlbiBieSBkZWZpbmluZyB0aGlzIENTUyB2YXJpYWJsZS4gVGhlIGRlZmF1bHQgYHotaW5kZXhgIG9mIHRoZVxuICogY29tcG9uZW50IGlzIHNldCB0byBgdmFyKC0tc2JiLW92ZXJsYXktZGVmYXVsdC16LWluZGV4KWAgd2l0aCBhIHZhbHVlIG9mIGAxMDAwYC5cbiAqL1xuZXhwb3J0IGNsYXNzIFNiYk1lbnVFbGVtZW50IGV4dGVuZHMgU2JiT3BlbkNsb3NlQmFzZUVsZW1lbnQge1xuICBwdWJsaWMgc3RhdGljIG92ZXJyaWRlIHJlYWRvbmx5IGVsZW1lbnROYW1lOiBzdHJpbmcgPSAnc2JiLW1lbnUnO1xuICBwdWJsaWMgc3RhdGljIG92ZXJyaWRlIHN0eWxlczogQ1NTUmVzdWx0R3JvdXAgPSBbYm94U2l6aW5nU3R5bGVzLCBzdHlsZV07XG4gIHB1YmxpYyBzdGF0aWMgb3ZlcnJpZGUgcmVhZG9ubHkgcm9sZSA9ICdtZW51JztcblxuICAvKipcbiAgICogVGhlIGVsZW1lbnQgdGhhdCB3aWxsIHRyaWdnZXIgdGhlIG1lbnUgb3ZlcmxheS5cbiAgICpcbiAgICogRm9yIGF0dHJpYnV0ZSB1c2FnZSwgcHJvdmlkZSBhbiBpZCByZWZlcmVuY2UuXG4gICAqL1xuICBAaWRSZWZlcmVuY2UoKVxuICBAcHJvcGVydHkoKVxuICBwdWJsaWMgYWNjZXNzb3IgdHJpZ2dlcjogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIF9tZW51ITogSFRNTERpdkVsZW1lbnQ7XG4gIHByaXZhdGUgX3RyaWdnZXJFbGVtZW50OiBIVE1MRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF90cmlnZ2VyQWJvcnRDb250cm9sbGVyITogQWJvcnRDb250cm9sbGVyO1xuICBwcml2YXRlIF9pc1BvaW50ZXJEb3duRXZlbnRPbk1lbnU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBfd2luZG93RXZlbnRzQ29udHJvbGxlciE6IEFib3J0Q29udHJvbGxlcjtcbiAgcHJpdmF0ZSBfZXNjYXBhYmxlT3ZlcmxheUNvbnRyb2xsZXIgPSBuZXcgU2JiRXNjYXBhYmxlT3ZlcmxheUNvbnRyb2xsZXIodGhpcyk7XG4gIHByaXZhdGUgX2ZvY3VzVHJhcENvbnRyb2xsZXIgPSBuZXcgU2JiRm9jdXNUcmFwQ29udHJvbGxlcih0aGlzKTtcbiAgcHJpdmF0ZSBfc2Nyb2xsSGFuZGxlciA9IG5ldyBTYmJTY3JvbGxIYW5kbGVyKCk7XG4gIHByaXZhdGUgX2luZXJ0Q29udHJvbGxlciA9IG5ldyBTYmJJbmVydENvbnRyb2xsZXIodGhpcyk7XG4gIHByaXZhdGUgX21vYmlsZUJyZWFrcG9pbnQgPSBTYmJNZWRpYVF1ZXJ5QnJlYWtwb2ludFNtYWxsQW5kQmVsb3c7XG4gIHByaXZhdGUgX21lZGlhTWF0Y2hlciA9IG5ldyBTYmJNZWRpYU1hdGNoZXJDb250cm9sbGVyKHRoaXMsIHtcbiAgICBbdGhpcy5fbW9iaWxlQnJlYWtwb2ludF06IChtYXRjaGVzKSA9PiB7XG4gICAgICBpZiAobWF0Y2hlcyAmJiAodGhpcy5zdGF0ZSA9PT0gJ29wZW5pbmcnIHx8IHRoaXMuc3RhdGUgPT09ICdvcGVuZWQnKSkge1xuICAgICAgICB0aGlzLl9zY3JvbGxIYW5kbGVyLmRpc2FibGVTY3JvbGwoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3Njcm9sbEhhbmRsZXIuZW5hYmxlU2Nyb2xsKCk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG4gIHByaXZhdGUgX2RhcmtNb2RlQ29udHJvbGxlciA9IG5ldyBTYmJEYXJrTW9kZUNvbnRyb2xsZXIodGhpcywgKCkgPT4gdGhpcy5fc3luY05lZ2F0aXZlKCkpO1xuICBwcml2YXRlIF9sYW5ndWFnZSA9IG5ldyBTYmJMYW5ndWFnZUNvbnRyb2xsZXIodGhpcyk7XG4gIHByaXZhdGUgX25lc3RlZE1lbnU6IFNiYk1lbnVFbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyPy4oJ2tleWRvd24nLCAoZSkgPT4gdGhpcy5faGFuZGxlS2V5RG93bihlKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgZmlyc3RVcGRhdGVkKGNoYW5nZWRQcm9wZXJ0aWVzOiBQcm9wZXJ0eVZhbHVlczx0aGlzPik6IHZvaWQge1xuICAgIHN1cGVyLmZpcnN0VXBkYXRlZChjaGFuZ2VkUHJvcGVydGllcyk7XG5cbiAgICB0aGlzLl9jb25maWd1cmVUcmlnZ2VyKCk7XG4gIH1cblxuICBwdWJsaWMgb3ZlcnJpZGUgZXNjYXBlU3RyYXRlZ3koKTogdm9pZCB7XG4gICAgdGhpcy5jbG9zZUFsbCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW5zIHRoZSBtZW51IG9uIHRyaWdnZXIgY2xpY2suXG4gICAqL1xuICBwdWJsaWMgb3BlbigpOiB2b2lkIHtcbiAgICBpZiAoXG4gICAgICB0aGlzLnN0YXRlID09PSAnY2xvc2luZycgfHxcbiAgICAgIHRoaXMuc3RhdGUgPT09ICdvcGVuZWQnIHx8XG4gICAgICAhdGhpcy5fbWVudSB8fFxuICAgICAgIXRoaXMuZGlzcGF0Y2hCZWZvcmVPcGVuRXZlbnQoKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9pc05lc3RlZCgpKSB7XG4gICAgICBjb25zdCBwYXJlbnRNZW51ID0gdGhpcy5fcGFyZW50TWVudSgpITtcbiAgICAgIHBhcmVudE1lbnUuaW50ZXJuYWxzLnN0YXRlcy5hZGQoJ25lc3RlZC1jaGlsZCcpO1xuXG4gICAgICAvLyBJbiBjYXNlIHdlIGNoYW5nZSBiZXR3ZWVuIGFycm93IGtleSBuYXZpZ2F0aW9uIGFuZCBtb3VzZSBuYXZpZ2F0aW9uLCBpdCBjYW4gYmUgdGhhdCBhbm90aGVyXG4gICAgICAvLyBuZXN0ZWQgcGFyZW50IG1lbnUgaXMgc3RpbGwgb3Blbi4gV2UgaGF2ZSB0byBjbG9zZSBpdC5cbiAgICAgIGlmIChwYXJlbnRNZW51Ll9uZXN0ZWRNZW51ICE9PSB0aGlzKSB7XG4gICAgICAgIHBhcmVudE1lbnUuX25lc3RlZE1lbnU/LmNsb3NlKCk7XG4gICAgICB9XG4gICAgICBwYXJlbnRNZW51Ll9uZXN0ZWRNZW51ID0gdGhpcztcbiAgICB9XG5cbiAgICB0aGlzLnNob3dQb3BvdmVyPy4oKTtcbiAgICB0aGlzLnN0YXRlID0gJ29wZW5pbmcnO1xuICAgIHRoaXMuX3NldE1lbnVQb3NpdGlvbigpO1xuICAgIHRoaXMuX3RyaWdnZXJFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnLCAndHJ1ZScpO1xuXG4gICAgLy8gRnJvbSB6ZXJvIHRvIGxhcmdlLCBkaXNhYmxlIHNjcm9sbFxuICAgIGlmICh0aGlzLl9pc01vYmlsZSgpKSB7XG4gICAgICB0aGlzLl9zY3JvbGxIYW5kbGVyLmRpc2FibGVTY3JvbGwoKTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgYW5pbWF0aW9uIGR1cmF0aW9uIGlzIHplcm8sIHRoZSBhbmltYXRpb25lbmQgZXZlbnQgaXMgbm90IGFsd2F5cyBmaXJlZCByZWxpYWJseS5cbiAgICAvLyBJbiB0aGlzIGNhc2Ugd2UgZGlyZWN0bHkgc2V0IHRoZSBgb3BlbmVkYCBzdGF0ZS5cbiAgICBpZiAodGhpcy5faXNaZXJvQW5pbWF0aW9uRHVyYXRpb24oKSkge1xuICAgICAgdGhpcy5faGFuZGxlT3BlbmluZygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBDbG9zZXMgdGhlIG1lbnUgYW5kIGFsbCBpdHMgbmVzdGVkIG1lbnVzLiAqL1xuICBwdWJsaWMgY2xvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5fY2xvc2UoKTtcbiAgfVxuXG4gIC8qKiBDbG9zZXMgdGhlIG1lbnUgYW5kIGFsbCByZWxhdGVkIG1lbnVzIChuZXN0ZWQgYW5kIHBhcmVudCBtZW51cykuICovXG4gIHB1YmxpYyBjbG9zZUFsbCgpOiB2b2lkIHtcbiAgICB0aGlzLl9tYWluTWVudSgpLl9jbG9zZSh0cnVlKTtcbiAgfVxuXG4gIC8qKiBAcGFyYW0gW2Nsb3NlQWxsPSdmYWxzZSddIC0gSWYgdHJ1ZSwgaXQgZW5zdXJlcyBhbmltYXRpb25zIGFyZSBjb3JyZWN0IGJ5IHRvZ2dsaW5nIHNvbWUgc3RhdGVzIHdoZW4gY2xvc2luZyBhbGwgcmVsYXRlZCBtZW51cyBhdCBvbmNlLiAqL1xuICBwcml2YXRlIF9jbG9zZShjbG9zZUFsbCA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKCh0aGlzLnN0YXRlID09PSAnb3BlbmluZycgJiYgIXRoaXMuX2lzTmVzdGVkKCkpIHx8ICF0aGlzLmRpc3BhdGNoQmVmb3JlQ2xvc2VFdmVudCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2xvc2UgbmVzdGVkIG1lbnVzIGZpcnN0XG4gICAgdGhpcy5fbmVzdGVkTWVudT8uX2Nsb3NlKGNsb3NlQWxsKTtcblxuICAgIGlmICh0aGlzLl9pc05lc3RlZCgpKSB7XG4gICAgICBjb25zdCBwYXJlbnRNZW51ID0gdGhpcy5fcGFyZW50TWVudSgpITtcbiAgICAgIGlmIChjbG9zZUFsbCkge1xuICAgICAgICB0aGlzLmludGVybmFscy5zdGF0ZXMuYWRkKCdjbG9zZS1hbGwnKTtcbiAgICAgICAgcGFyZW50TWVudS5pbnRlcm5hbHMuc3RhdGVzLmFkZCgnc2tpcC1hbmltYXRpb24nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxzLnN0YXRlcy5kZWxldGUoJ2Nsb3NlLWFsbCcpO1xuICAgICAgICBwYXJlbnRNZW51LmludGVybmFscy5zdGF0ZXMuZGVsZXRlKCdza2lwLWFuaW1hdGlvbicpO1xuICAgICAgfVxuICAgICAgcGFyZW50TWVudS5pbnRlcm5hbHMuc3RhdGVzLmRlbGV0ZSgnbmVzdGVkLWNoaWxkJyk7XG4gICAgICBwYXJlbnRNZW51Ll9uZXN0ZWRNZW51ID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXRlID0gJ2Nsb3NpbmcnO1xuICAgIHRoaXMuX3RyaWdnZXJFbGVtZW50Py5zZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnLCAnZmFsc2UnKTtcblxuICAgIC8vIElmIHRoZSBhbmltYXRpb24gZHVyYXRpb24gaXMgemVybywgdGhlIGFuaW1hdGlvbmVuZCBldmVudCBpcyBub3QgYWx3YXlzIGZpcmVkIHJlbGlhYmx5LlxuICAgIC8vIEluIHRoaXMgY2FzZSB3ZSBkaXJlY3RseSBzZXQgdGhlIGBjbG9zZWRgIHN0YXRlLlxuICAgIGlmICh0aGlzLl9pc1plcm9BbmltYXRpb25EdXJhdGlvbigpKSB7XG4gICAgICB0aGlzLl9oYW5kbGVDbG9zaW5nKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfaXNaZXJvQW5pbWF0aW9uRHVyYXRpb24oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzWmVyb0FuaW1hdGlvbkR1cmF0aW9uKHRoaXMsICctLXNiYi1tZW51LWFuaW1hdGlvbi1kdXJhdGlvbicpO1xuICB9XG5cbiAgcHJpdmF0ZSBfaGFuZGxlT3BlbmluZygpOiB2b2lkIHtcbiAgICB0aGlzLnN0YXRlID0gJ29wZW5lZCc7XG5cbiAgICBpZiAoIXRoaXMuX2lzTmVzdGVkKCkpIHtcbiAgICAgIHRoaXMuX2luZXJ0Q29udHJvbGxlci5hY3RpdmF0ZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl91cGRhdGVOZXN0ZWRJbmVydCgpO1xuICAgIH1cbiAgICB0aGlzLl9lc2NhcGFibGVPdmVybGF5Q29udHJvbGxlci5jb25uZWN0KCk7XG4gICAgdGhpcy5fZm9jdXNUcmFwQ29udHJvbGxlci5mb2N1c0luaXRpYWxFbGVtZW50KCk7XG4gICAgdGhpcy5fZm9jdXNUcmFwQ29udHJvbGxlci5lbmFibGVkID0gdHJ1ZTtcbiAgICB0aGlzLl9hdHRhY2hXaW5kb3dFdmVudHMoKTtcbiAgICB0aGlzLmRpc3BhdGNoT3BlbkV2ZW50KCk7XG4gIH1cblxuICBwcml2YXRlIF9oYW5kbGVDbG9zaW5nKCk6IHZvaWQge1xuICAgIHRoaXMuc3RhdGUgPSAnY2xvc2VkJztcbiAgICB0aGlzLmludGVybmFscy5zdGF0ZXMuZGVsZXRlKCdza2lwLWFuaW1hdGlvbicpO1xuICAgIHRoaXMuaW50ZXJuYWxzLnN0YXRlcy5kZWxldGUoJ2Nsb3NlLWFsbCcpO1xuICAgIHRoaXMuaGlkZVBvcG92ZXI/LigpO1xuXG4gICAgdGhpcy5fbWVudT8uZmlyc3RFbGVtZW50Q2hpbGQ/LnNjcm9sbFRvKDAsIDApO1xuICAgIGlmICghdGhpcy5faXNOZXN0ZWQoKSkge1xuICAgICAgdGhpcy5faW5lcnRDb250cm9sbGVyLmRlYWN0aXZhdGUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fdXBkYXRlTmVzdGVkSW5lcnQoKTtcbiAgICB9XG4gICAgLy8gTWFudWFsbHkgZm9jdXMgbGFzdCBmb2N1c2VkIGVsZW1lbnRcbiAgICB0aGlzLl90cmlnZ2VyRWxlbWVudD8uZm9jdXMoe1xuICAgICAgLy8gV2hlbiBpbnNpZGUgdGhlIHNiYi1oZWFkZXIsIHdlIHByZXZlbnQgdGhlIHNjcm9sbCB0byBhdm9pZCB0aGUgc25hcHBpbmcgdG8gdGhlIHRvcCBvZiB0aGUgcGFnZVxuICAgICAgcHJldmVudFNjcm9sbDogWydzYmItaGVhZGVyLWJ1dHRvbicsICdzYmItaGVhZGVyLWxpbmsnXS5pbmNsdWRlcyhcbiAgICAgICAgdGhpcy5fdHJpZ2dlckVsZW1lbnQubG9jYWxOYW1lLFxuICAgICAgKSxcbiAgICB9KTtcbiAgICB0aGlzLl9lc2NhcGFibGVPdmVybGF5Q29udHJvbGxlci5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy5kaXNwYXRjaENsb3NlRXZlbnQoKTtcbiAgICB0aGlzLl93aW5kb3dFdmVudHNDb250cm9sbGVyPy5hYm9ydCgpO1xuICAgIHRoaXMuX2ZvY3VzVHJhcENvbnRyb2xsZXIuZW5hYmxlZCA9IGZhbHNlO1xuXG4gICAgLy8gU3RhcnRpbmcgZnJvbSBicmVha3BvaW50IGxhcmdlLCBlbmFibGUgc2Nyb2xsXG4gICAgdGhpcy5fc2Nyb2xsSGFuZGxlci5lbmFibGVTY3JvbGwoKTtcbiAgfVxuXG4gIHByaXZhdGUgX2hhbmRsZUtleURvd24oZXZ0OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCFpc0Fycm93S2V5T3JQYWdlS2V5c1ByZXNzZWQoZXZ0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBldnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGNvbnN0IGVuYWJsZWRBY3Rpb25zOiBFbGVtZW50W10gPSBBcnJheS5mcm9tKFxuICAgICAgdGhpcy5xdWVyeVNlbGVjdG9yQWxsPFNiYk1lbnVCdXR0b25FbGVtZW50IHwgU2JiTWVudUxpbmtFbGVtZW50PihcbiAgICAgICAgJ3NiYi1tZW51LWJ1dHRvbiwgc2JiLW1lbnUtbGluaycsXG4gICAgICApLFxuICAgIClcbiAgICAgIC5jb25jYXQodGhpcy5zaGFkb3dSb290IS5xdWVyeVNlbGVjdG9yKCdzYmItbWVudS1idXR0b24nKSEpXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAoZWwpID0+ICghZWwuZGlzYWJsZWQgfHwgZWwuZGlzYWJsZWRJbnRlcmFjdGl2ZSkgJiYgaW50ZXJhY3Rpdml0eUNoZWNrZXIuaXNWaXNpYmxlKGVsKSxcbiAgICAgICk7XG4gICAgY29uc3QgY3VycmVudCA9IGVuYWJsZWRBY3Rpb25zLmZpbmRJbmRleCgoZTogRWxlbWVudCkgPT4gZSA9PT0gZXZ0LnRhcmdldCk7XG5cbiAgICBsZXQgbmV4dEluZGV4O1xuICAgIHN3aXRjaCAoZXZ0LmtleSkge1xuICAgICAgY2FzZSAnQXJyb3dVcCc6XG4gICAgICBjYXNlICdBcnJvd0Rvd24nOlxuICAgICAgICBuZXh0SW5kZXggPSBnZXROZXh0RWxlbWVudEluZGV4KGV2dCwgY3VycmVudCwgZW5hYmxlZEFjdGlvbnMubGVuZ3RoKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ0Fycm93TGVmdCc6XG4gICAgICAgIGlmICh0aGlzLl9pc05lc3RlZCgpKSB7XG4gICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdBcnJvd1JpZ2h0JzpcbiAgICAgICAgaWYgKChldnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5tYXRjaGVzKCc6c3RhdGUoc2JiLW1lbnUtdHJpZ2dlciknKSkge1xuICAgICAgICAgIChldnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbGljaygpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdQYWdlVXAnOlxuICAgICAgY2FzZSAnSG9tZSc6XG4gICAgICAgIG5leHRJbmRleCA9IDA7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdFbmQnOlxuICAgICAgY2FzZSAnUGFnZURvd24nOlxuICAgICAgICBuZXh0SW5kZXggPSBlbmFibGVkQWN0aW9ucy5sZW5ndGggLSAxO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAobmV4dEluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIChlbmFibGVkQWN0aW9uc1tuZXh0SW5kZXhdIGFzIEhUTUxFbGVtZW50KS5mb2N1cygpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJlbW92ZXMgdHJpZ2dlciBjbGljayBsaXN0ZW5lciBvbiB0cmlnZ2VyIGNoYW5nZS5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGNyZWF0ZVJlbmRlclJvb3QoKTogSFRNTEVsZW1lbnQgfCBEb2N1bWVudEZyYWdtZW50IHtcbiAgICBjb25zdCByZW5kZXJSb290ID0gc3VwZXIuY3JlYXRlUmVuZGVyUm9vdCgpO1xuICAgIC8vIER1ZSB0byB0aGUgZmFjdCB0aGF0IG1lbnUgY2FuIGJvdGggYmUgYSBsaXN0IGFuZCBqdXN0IGEgY29udGFpbmVyLCB3ZSBuZWVkIHRvIGNoZWNrIGl0c1xuICAgIC8vIHN0YXRlIGJlZm9yZSB0aGUgU2JiTmFtZWRTbG90TGlzdE1peGluIGhhbmRsZXMgdGhlIHNsb3RjaGFuZ2UgZXZlbnQsIGluIG9yZGVyIHRvIGF2b2lkXG4gICAgLy8gaXQgaW50ZXJwcmV0aW5nIHRoZSBub24gbGlzdCBjYXNlIGFzIGEgbGlzdC5cbiAgICB0aGlzLnNoYWRvd1Jvb3Q/LmFkZEV2ZW50TGlzdGVuZXIoJ3Nsb3RjaGFuZ2UnLCAoKSA9PiB0aGlzLl9zeW5jTmVnYXRpdmUoKSwgeyBjYXB0dXJlOiB0cnVlIH0pO1xuICAgIHJldHVybiByZW5kZXJSb290O1xuICB9XG5cbiAgcHVibGljIG92ZXJyaWRlIGNvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIHRoaXMucG9wb3ZlciA9ICdtYW51YWwnO1xuICAgIHN1cGVyLmNvbm5lY3RlZENhbGxiYWNrKCk7XG4gICAgdGhpcy5pZCB8fD0gYHNiYi1tZW51LSR7bmV4dElkKyt9YDtcbiAgICBpZiAodGhpcy5oYXNVcGRhdGVkKSB7XG4gICAgICB0aGlzLl9jb25maWd1cmVUcmlnZ2VyKCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG92ZXJyaWRlIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xuICAgIHN1cGVyLmRpc2Nvbm5lY3RlZENhbGxiYWNrKCk7XG4gICAgdGhpcy5fdHJpZ2dlckVsZW1lbnQgPSBudWxsO1xuICAgIHRoaXMuX3RyaWdnZXJBYm9ydENvbnRyb2xsZXI/LmFib3J0KCk7XG4gICAgdGhpcy5fd2luZG93RXZlbnRzQ29udHJvbGxlcj8uYWJvcnQoKTtcbiAgICB0aGlzLl9zY3JvbGxIYW5kbGVyLmVuYWJsZVNjcm9sbCgpO1xuICB9XG5cbiAgcHVibGljIG92ZXJyaWRlIHJlcXVlc3RVcGRhdGUoXG4gICAgbmFtZT86IFByb3BlcnR5S2V5LFxuICAgIG9sZFZhbHVlPzogdW5rbm93bixcbiAgICBvcHRpb25zPzogUHJvcGVydHlEZWNsYXJhdGlvbixcbiAgKTogdm9pZCB7XG4gICAgc3VwZXIucmVxdWVzdFVwZGF0ZShuYW1lLCBvbGRWYWx1ZSwgb3B0aW9ucyk7XG5cbiAgICBpZiAoIWlzU2VydmVyICYmICghbmFtZSB8fCBuYW1lID09PSAndHJpZ2dlcicpICYmIHRoaXMuaGFzVXBkYXRlZCkge1xuICAgICAgdGhpcy5fY29uZmlndXJlVHJpZ2dlcigpO1xuICAgIH1cbiAgfVxuXG4gIC8vIENoZWNrIGlmIHRoZSB0cmlnZ2VyIGlzIHZhbGlkIGFuZCBhdHRhY2ggY2xpY2sgZXZlbnQgbGlzdGVuZXJzLlxuICBwcml2YXRlIF9jb25maWd1cmVUcmlnZ2VyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnRyaWdnZXIgPT09IHRoaXMuX3RyaWdnZXJFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fdHJpZ2dlckFib3J0Q29udHJvbGxlcj8uYWJvcnQoKTtcbiAgICByZW1vdmVBcmlhT3ZlcmxheVRyaWdnZXJBdHRyaWJ1dGVzKHRoaXMuX3RyaWdnZXJFbGVtZW50KTtcbiAgICB0aGlzLl90cmlnZ2VyRWxlbWVudCA9IHRoaXMudHJpZ2dlcjtcblxuICAgIGlmICghdGhpcy5fdHJpZ2dlckVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZXRBcmlhT3ZlcmxheVRyaWdnZXJBdHRyaWJ1dGVzKHRoaXMuX3RyaWdnZXJFbGVtZW50LCAnbWVudScsIHRoaXMuaWQsIHRoaXMuc3RhdGUpO1xuICAgIHRoaXMuX3RyaWdnZXJBYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgdGhpcy5fdHJpZ2dlckVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB0aGlzLm9wZW4oKSwge1xuICAgICAgc2lnbmFsOiB0aGlzLl90cmlnZ2VyQWJvcnRDb250cm9sbGVyLnNpZ25hbCxcbiAgICB9KTtcblxuICAgIC8vIENvbnNpZGVyIHRoZSBtZW51IGFzIG5lc3RlZCBpZiB0aGUgdHJpZ2dlciBpcyBhIG1lbnUgYnV0dG9uIG9yIG1lbnUgbGluay5cbiAgICB0aGlzLnRvZ2dsZVN0YXRlKFxuICAgICAgJ25lc3RlZCcsXG4gICAgICBbJ3NiYi1tZW51LWJ1dHRvbicsICdzYmItbWVudS1saW5rJ10uaW5jbHVkZXModGhpcy5fdHJpZ2dlckVsZW1lbnQubG9jYWxOYW1lKSxcbiAgICApO1xuICAgIMm1c3RhdGVDb250cm9sbGVyKHRoaXMuX3RyaWdnZXJFbGVtZW50KS5hZGQoJ3NiYi1tZW51LXRyaWdnZXInKTtcbiAgfVxuXG4gIHByaXZhdGUgX2F0dGFjaFdpbmRvd0V2ZW50cygpOiB2b2lkIHtcbiAgICB0aGlzLl93aW5kb3dFdmVudHNDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsICgpID0+IHRoaXMuX3NldE1lbnVQb3NpdGlvbigpLCB7XG4gICAgICBwYXNzaXZlOiB0cnVlLFxuICAgICAgc2lnbmFsOiB0aGlzLl93aW5kb3dFdmVudHNDb250cm9sbGVyLnNpZ25hbCxcbiAgICAgIC8vIFdpdGhvdXQgY2FwdHVyZSwgb3RoZXIgc2Nyb2xsIGNvbnRleHRzIHdvdWxkIG5vdCBidWJibGUgdG8gdGhpcyBldmVudCBsaXN0ZW5lci5cbiAgICAgIC8vIENhcHR1cmUgYWxsb3dzIHVzIHRvIHJlYWN0IHRvIGFsbCBzY3JvbGwgY29udGV4dHMgaW4gdGhpcyBET00uXG4gICAgICBjYXB0dXJlOiB0cnVlLFxuICAgIH0pO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCAoKSA9PiB0aGlzLl9zZXRNZW51UG9zaXRpb24oKSwge1xuICAgICAgcGFzc2l2ZTogdHJ1ZSxcbiAgICAgIHNpZ25hbDogdGhpcy5fd2luZG93RXZlbnRzQ29udHJvbGxlci5zaWduYWwsXG4gICAgfSk7XG5cbiAgICAvLyBPbmx5IHRoZSBvdXRlcm1vc3QgbWVudSBuZWVkcyB0byBsaXN0ZW4gdG8gdGhlIGJhY2tkcm9wIGNsaWNrc1xuICAgIGlmICghdGhpcy5faXNOZXN0ZWQoKSkge1xuICAgICAgLy8gQ2xvc2UgbWVudSBvbiBiYWNrZHJvcCBjbGlja1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgdGhpcy5fcG9pbnRlckRvd25MaXN0ZW5lciwge1xuICAgICAgICBzaWduYWw6IHRoaXMuX3dpbmRvd0V2ZW50c0NvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgfSk7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgdGhpcy5fY2xvc2VPbkJhY2tkcm9wQ2xpY2ssIHtcbiAgICAgICAgc2lnbmFsOiB0aGlzLl93aW5kb3dFdmVudHNDb250cm9sbGVyLnNpZ25hbCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIENsb3NlIG1lbnUgYXQgYW55IGNsaWNrIG9uIGFuIGludGVyYWN0aXZlIGVsZW1lbnQgaW5zaWRlIHRoZSA8c2JiLW1lbnU+IHRoYXQgYnViYmxlcyB0byB0aGUgY29udGFpbmVyLlxuICBwcml2YXRlIF9pbnRlcmFjdGl2ZUVsZW1lbnRDbGljayhldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICBpZiAoXG4gICAgICBJTlRFUkFDVElWRV9FTEVNRU5UUy5pbmNsdWRlcyh0YXJnZXQubm9kZU5hbWUpICYmXG4gICAgICAhdGFyZ2V0Lmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKSAmJlxuICAgICAgIXRhcmdldC5tYXRjaGVzKCc6c3RhdGUoc2JiLW1lbnUtdHJpZ2dlciknKSAmJlxuICAgICAgdGFyZ2V0LmlkICE9PSAnc2JiLW1lbnVfX2JhY2stYnV0dG9uJ1xuICAgICkge1xuICAgICAgdGhpcy5jbG9zZUFsbCgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIENoZWNrIGlmIHRoZSBwb2ludGVyZG93biBldmVudCB0YXJnZXQgaXMgdHJpZ2dlcmVkIG9uIHRoZSBtZW51LlxuICBwcml2YXRlIF9wb2ludGVyRG93bkxpc3RlbmVyID0gKGV2ZW50OiBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBjb25zdCBtZW51ID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCkuY2xvc2VzdCgnc2JiLW1lbnUnKTtcblxuICAgIC8vIFRoZSBwb2ludGVyIGRvd24gaXMgb24gdGhlIG1lbnUgb3Igb25lIG9mIGl0cyBuZXN0ZWQgbWVudXMuXG4gICAgdGhpcy5faXNQb2ludGVyRG93bkV2ZW50T25NZW51ID1cbiAgICAgIGlzRXZlbnRPbkVsZW1lbnQodGhpcy5fbWVudSwgZXZlbnQpIHx8IHRoaXMuX25lc3RlZE1lbnVzKCkuc29tZSgoZWwpID0+IG1lbnUgPT09IGVsKTtcbiAgfTtcblxuICAvLyBDbG9zZSBtZW51IG9uIGJhY2tkcm9wIGNsaWNrLlxuICBwcml2YXRlIF9jbG9zZU9uQmFja2Ryb3BDbGljayA9IChldmVudDogUG9pbnRlckV2ZW50KTogdm9pZCA9PiB7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuXG4gICAgLy8gVGhlIGJhY2tkcm9wIGlzIG9ubHkgbGlzdGVuZWQgb24gdGhlIG1haW4gbWVudSAob3V0ZXJtb3N0IG1lbnUpLlxuICAgIC8vIFRvIGNsb3NlLlxuICAgIC8vIC0gVGhlIHBvaW50ZXIgZG93biBhbmQgdXAgbmVlZCB0byBiZSBvdXRzaWRlIHRoZSBtZW51LlxuICAgIC8vIC0gVGhlIHRhcmdldCBzaG91bGQgYmUgbm90IG9uIGEgbmVzdGVkIG1lbnVcbiAgICBpZiAoXG4gICAgICAhdGhpcy5faXNQb2ludGVyRG93bkV2ZW50T25NZW51ICYmXG4gICAgICAhaXNFdmVudE9uRWxlbWVudCh0aGlzLl9tZW51LCBldmVudCkgJiZcbiAgICAgICF0aGlzLl9uZXN0ZWRNZW51cygpLnNvbWUoKGVsKSA9PiBlbCA9PT0gdGFyZ2V0KVxuICAgICkge1xuICAgICAgdGhpcy5jbG9zZUFsbCgpO1xuICAgIH1cbiAgfTtcblxuICAvKiogQ29udmVydHMgdGhlIGxpbmtlZCBsaXN0IGludG8gYW4gYXJyYXkgb2YgU2JiTWVudUVsZW1lbnQuICovXG4gIHByaXZhdGUgX25lc3RlZE1lbnVzKCk6IFNiYk1lbnVFbGVtZW50W10ge1xuICAgIGNvbnN0IG1lbnVzOiBTYmJNZW51RWxlbWVudFtdID0gW107XG4gICAgbGV0IGN1cnJlbnQgPSB0aGlzLl9uZXN0ZWRNZW51O1xuXG4gICAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICAgIG1lbnVzLnB1c2goY3VycmVudCk7XG4gICAgICBjdXJyZW50ID0gY3VycmVudC5fbmVzdGVkTWVudTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWVudXM7XG4gIH1cblxuICBwcml2YXRlIF9wYXJlbnRNZW51KCk6IFNiYk1lbnVFbGVtZW50IHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3RyaWdnZXJFbGVtZW50Py5jbG9zZXN0KCdzYmItbWVudScpID8/IG51bGw7XG4gIH1cblxuICAvKiogVGhlIG91dGVybW9zdCBtZW51LiAqL1xuICBwcml2YXRlIF9tYWluTWVudSgpOiBTYmJNZW51RWxlbWVudCB7XG4gICAgcmV0dXJuIHRoaXMuX2lzTmVzdGVkKCkgPyAodGhpcy5fcGFyZW50TWVudSgpPy5fbWFpbk1lbnUoKSA/PyB0aGlzKSA6IHRoaXM7XG4gIH1cblxuICBwcml2YXRlIF9pc05lc3RlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLl9wYXJlbnRNZW51KCk7XG4gIH1cblxuICBwcml2YXRlIF91cGRhdGVOZXN0ZWRJbmVydCgpOiB2b2lkIHtcbiAgICB0aGlzLl9pbmVydENvbnRyb2xsZXIucmVzdG9yZUFsbEV4ZW1wdGVkKCk7XG4gICAgdGhpcy5fbWFpbk1lbnUoKVxuICAgICAgLl9uZXN0ZWRNZW51cygpXG4gICAgICAuZm9yRWFjaCgobWVudSkgPT4gdGhpcy5faW5lcnRDb250cm9sbGVyLmV4ZW1wdChtZW51KSk7XG4gIH1cblxuICAvLyBDaGVjayBpZiBuZXN0ZWQgbWVudSBzaG91bGQgYmUgY2xvc2VkLlxuICBwcml2YXRlIF9oYW5kbGVNb3VzZU92ZXIoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBlbGVtZW50ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIGNvbnN0IGlzTW9iaWxlID0gdGhpcy5faXNNb2JpbGUoKTtcblxuICAgIC8vIEFsbCBuZXN0ZWQgbWVudXMgc2hvdWxkIGNsb3NlIGluIGRlc2t0b3AgbW9kZSBpZiB0aGUgY3Vyc29yIGxhbmRlZCBvblxuICAgIC8vIGFueXRoaW5nIG90aGVyIHRoYW4gdGhlIGNvbnRhaW5lciwgdGhlIGNvbnRhaW5lcidzIHNjcm9sbGJhciBvciB0aGUgdHJpZ2dlciBpdHNlbGZcbiAgICBpZiAoXG4gICAgICAhaXNNb2JpbGUgJiZcbiAgICAgIHRoaXMuX25lc3RlZE1lbnUgJiZcbiAgICAgICFlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnc2JiLW1lbnVfX2NvbnRlbnQnKSAmJlxuICAgICAgIShlbGVtZW50LmdldEF0dHJpYnV0ZSgnYXJpYS1leHBhbmRlZCcpID09PSAndHJ1ZScpXG4gICAgKSB7XG4gICAgICB0aGlzLl9uZXN0ZWRNZW51LmNsb3NlKCk7XG4gICAgfVxuXG4gICAgaWYgKGVsZW1lbnQubWF0Y2hlcygnOnN0YXRlKHNiYi1tZW51LXRyaWdnZXIpJykgJiYgIWlzTW9iaWxlKSB7XG4gICAgICBlbGVtZW50LmNsaWNrKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gU2V0IG1lbnUgcG9zaXRpb24gKHgsIHkpIHRvICcwJyBvbmNlIHRoZSBtZW51IGlzIGNsb3NlZCBhbmQgdGhlIHRyYW5zaXRpb24gZW5kZWQgdG8gcHJldmVudCB0aGVcbiAgLy8gdmlld3BvcnQgZnJvbSBvdmVyZmxvd2luZy4gQW5kIHNldCB0aGUgZm9jdXMgdG8gdGhlIGZpcnN0IGZvY3VzYWJsZSBlbGVtZW50IG9uY2UgdGhlIG1lbnUgaXMgb3Blbi5cbiAgLy8gSW4gcmFyZSBjYXNlcyBpdCBjYW4gYmUgdGhhdCB0aGUgYW5pbWF0aW9uRW5kIGV2ZW50IGlzIHRyaWdnZXJlZCB0d2ljZS5cbiAgLy8gVG8gYXZvaWQgZW50ZXJpbmcgYSBjb3JydXB0IHN0YXRlLCBleGl0IHdoZW4gc3RhdGUgaXMgbm90IGV4cGVjdGVkLlxuICBwcml2YXRlIF9vbk1lbnVBbmltYXRpb25FbmQoZXZlbnQ6IEFuaW1hdGlvbkV2ZW50KTogdm9pZCB7XG4gICAgaWYgKFxuICAgICAgKGV2ZW50LmFuaW1hdGlvbk5hbWUgPT09ICdvcGVuJyB8fCBldmVudC5hbmltYXRpb25OYW1lID09PSAnb3Blbi1zaWRld2F5cycpICYmXG4gICAgICB0aGlzLnN0YXRlID09PSAnb3BlbmluZydcbiAgICApIHtcbiAgICAgIHRoaXMuX2hhbmRsZU9wZW5pbmcoKTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgKGV2ZW50LmFuaW1hdGlvbk5hbWUgPT09ICdjbG9zZScgfHwgZXZlbnQuYW5pbWF0aW9uTmFtZSA9PT0gJ2Nsb3NlLXNpZGV3YXlzJykgJiZcbiAgICAgIHRoaXMuc3RhdGUgPT09ICdjbG9zaW5nJ1xuICAgICkge1xuICAgICAgdGhpcy5faGFuZGxlQ2xvc2luZygpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFNldCBtZW51IHBvc2l0aW9uIGFuZCBtYXggaGVpZ2h0IGlmIHRoZSBicmVha3BvaW50IGlzIGxhcmdlLXVsdHJhLlxuICBwcml2YXRlIF9zZXRNZW51UG9zaXRpb24oKTogdm9pZCB7XG4gICAgLy8gU3RhcnRpbmcgZnJvbSBicmVha3BvaW50IGxhcmdlXG4gICAgaWYgKHRoaXMuX2lzTW9iaWxlKCkgfHwgIXRoaXMuX21lbnUgfHwgIXRoaXMuX3RyaWdnZXJFbGVtZW50IHx8IHRoaXMuc3RhdGUgPT09ICdjbG9zaW5nJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG1lbnVQb3NpdGlvbiA9ICF0aGlzLl9pc05lc3RlZCgpXG4gICAgICA/IGdldEVsZW1lbnRQb3NpdGlvbihcbiAgICAgICAgICB0aGlzLnNoYWRvd1Jvb3QhLnF1ZXJ5U2VsZWN0b3IoJy5zYmItbWVudV9fY29udGVudCcpISxcbiAgICAgICAgICB0aGlzLl90cmlnZ2VyRWxlbWVudCxcbiAgICAgICAgICB0aGlzLnNoYWRvd1Jvb3QhLnF1ZXJ5U2VsZWN0b3IoJy5zYmItbWVudV9fY29udGFpbmVyJykhLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZlcnRpY2FsT2Zmc2V0OiBNRU5VX09GRlNFVCxcbiAgICAgICAgICB9LFxuICAgICAgICApXG4gICAgICA6IGdldEVsZW1lbnRQb3NpdGlvbkhvcml6b250YWwoXG4gICAgICAgICAgdGhpcy5zaGFkb3dSb290IS5xdWVyeVNlbGVjdG9yKCcuc2JiLW1lbnVfX2NvbnRlbnQnKSEsXG4gICAgICAgICAgdGhpcy5fdHJpZ2dlckVsZW1lbnQsXG4gICAgICAgICAgdGhpcy5zaGFkb3dSb290IS5xdWVyeVNlbGVjdG9yKCcuc2JiLW1lbnVfX2NvbnRhaW5lcicpISxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBob3Jpem9udGFsT2Zmc2V0OiBNRU5VX09GRlNFVCxcbiAgICAgICAgICAgIHZlcnRpY2FsT2Zmc2V0OiBORVNURURfTUVOVV9PRkZTRVQsXG4gICAgICAgICAgICBjb250ZW50U2VsZWN0b3I6ICcuc2JiLW1lbnVfX2NvbnRlbnQnLFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICB0aGlzLnN0eWxlLnNldFByb3BlcnR5KCctLXNiYi1tZW51LXBvc2l0aW9uLXgnLCBgJHttZW51UG9zaXRpb24ubGVmdH1weGApO1xuICAgIHRoaXMuc3R5bGUuc2V0UHJvcGVydHkoJy0tc2JiLW1lbnUtcG9zaXRpb24teScsIGAke21lbnVQb3NpdGlvbi50b3B9cHhgKTtcbiAgICB0aGlzLnN0eWxlLnNldFByb3BlcnR5KCctLXNiYi1tZW51LW1heC1oZWlnaHQnLCBtZW51UG9zaXRpb24ubWF4SGVpZ2h0KTtcbiAgfVxuXG4gIHByaXZhdGUgX3N5bmNOZWdhdGl2ZSgpOiB2b2lkIHtcbiAgICAvLyBMaW5rcyBhbmQgYnV0dG9ucyBhcmUgdGhlIG1vc3QgZXhwZWN0ZWQgY29udGVudHMgd2hpY2ggaGF2ZSBhIG5lZ2F0aXZlIHByb3BlcnR5XG4gICAgdGhpcy5xdWVyeVNlbGVjdG9yQWxsKCc6c3RhdGUoc2JiLWxpbmspLCA6c3RhdGUoc2JiLWJ1dHRvbiknKT8uZm9yRWFjaCgoZWw6IEVsZW1lbnQpID0+IHtcbiAgICAgIGN1c3RvbUVsZW1lbnRzLnVwZ3JhZGUoZWwpO1xuICAgICAgKGVsIGFzIEVsZW1lbnQgJiBTYmJOZWdhdGl2ZU1peGluVHlwZSkubmVnYXRpdmUgPSAhdGhpcy5fZGFya01vZGVDb250cm9sbGVyLm1hdGNoZXMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2lzTW9iaWxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9tZWRpYU1hdGNoZXIubWF0Y2hlcyh0aGlzLl9tb2JpbGVCcmVha3BvaW50KSA/PyB0cnVlO1xuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIHJlbmRlcigpOiBUZW1wbGF0ZVJlc3VsdCB7XG4gICAgcmV0dXJuIGh0bWxgXG4gICAgICA8ZGl2IGNsYXNzPVwic2JiLW1lbnVfX2NvbnRhaW5lclwiPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgQGFuaW1hdGlvbmVuZD0ke3RoaXMuX29uTWVudUFuaW1hdGlvbkVuZH1cbiAgICAgICAgICBAbW91c2VvdmVyPSR7KGU6IE1vdXNlRXZlbnQpID0+IHRoaXMuX2hhbmRsZU1vdXNlT3ZlcihlKX1cbiAgICAgICAgICBjbGFzcz1cInNiYi1tZW51XCJcbiAgICAgICAgICAke3JlZigoZWw/OiBFbGVtZW50KSA9PiAodGhpcy5fbWVudSA9IGVsIGFzIEhUTUxEaXZFbGVtZW50KSl9XG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBAY2xpY2s9JHsoZXZlbnQ6IEV2ZW50KSA9PiB0aGlzLl9pbnRlcmFjdGl2ZUVsZW1lbnRDbGljayhldmVudCl9XG4gICAgICAgICAgICBAc2Nyb2xsPSR7KGU6IEV2ZW50KSA9PiBmb3J3YXJkRXZlbnQoZSwgZG9jdW1lbnQpfVxuICAgICAgICAgICAgY2xhc3M9XCJzYmItbWVudV9fY29udGVudFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNsb3Q+PC9zbG90PlxuICAgICAgICAgICAgPHNiYi1kaXZpZGVyPjwvc2JiLWRpdmlkZXI+XG4gICAgICAgICAgICA8c2JiLW1lbnUtYnV0dG9uXG4gICAgICAgICAgICAgIGlkPVwic2JiLW1lbnVfX2JhY2stYnV0dG9uXCJcbiAgICAgICAgICAgICAgQGNsaWNrPSR7KCkgPT4gdGhpcy5jbG9zZSgpfVxuICAgICAgICAgICAgICBpY29uLW5hbWU9XCJjaGV2cm9uLXNtYWxsLWxlZnQtc21hbGxcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAke2kxOG5Hb0JhY2tbdGhpcy5fbGFuZ3VhZ2UuY3VycmVudF19XG4gICAgICAgICAgICA8L3NiYi1tZW51LWJ1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICBgO1xuICB9XG59XG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIEhUTUxFbGVtZW50VGFnTmFtZU1hcCB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuICAgICdzYmItbWVudSc6IFNiYk1lbnVFbGVtZW50O1xuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDOENBLHFCQUFxQixRQUFRO0FBRTdCLElBQU0sY0FBYztBQUNwQixJQUFNLHFCQUFxQjtBQUMzQixJQUFNLHVCQUF1QjtDQUMzQjtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNEO0FBRUQsSUFBSSxTQUFTOzs7Ozs7Ozs7SUFVQSx3QkFBYzttQkFBUzs7OztjQUF2Qix1QkFBdUIsWUFBdUI7OzswQkFVeEQsYUFBYSxFQUNiLFVBQVUsQ0FBQTtBQUNYLGdCQUFBLE1BQUEsTUFBQSxxQkFBQTtJQUFBLE1BQUE7SUFBQSxNQUFBO0lBQUEsUUFBQTtJQUFBLFNBQUE7SUFBQSxRQUFBO0tBQUEsTUFBQSxRQUFBLGFBQUE7S0FBQSxNQUFBLFFBQUEsSUFBZ0I7S0FBTyxNQUFBLEtBQUEsVUFBQTtBQUFBLFVBQVAsVUFBTzs7S0FBQTtJQUFBLFVBQUE7SUFBQSxFQUFBLHVCQUFBLDJCQUFBOzs7Ozs7Ozs7QUFYUyxRQUFBLGNBQXNCOzs7QUFD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
|