@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.
@@ -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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