@sbb-esta/lyne-elements 4.10.0 → 4.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/breadcrumb/breadcrumb-group/breadcrumb-group.component.js +1 -1
  2. package/breadcrumb/breadcrumb-group.js +1 -1
  3. package/{breadcrumb-group.component-Cc6CHbVy.js → breadcrumb-group.component-F3-JZkfO.js} +1 -1
  4. package/breadcrumb.js +1 -1
  5. package/breadcrumb.pure.js +1 -1
  6. package/calendar/calendar/calendar.component.js +1 -1
  7. package/calendar/calendar.js +1 -1
  8. package/{calendar.component-DhmaJt2k.js → calendar.component-DjQOyRGl.js} +2 -2
  9. package/calendar.js +1 -1
  10. package/calendar.pure.js +1 -1
  11. package/core/base-elements/element.js +1 -1
  12. package/core/styles/mixins/table.scss +18 -19
  13. package/core/styles/theme.scss +3 -1
  14. package/custom-elements.json +986 -959
  15. package/development/breadcrumb/breadcrumb-group/breadcrumb-group.component.js +1 -1
  16. package/development/breadcrumb/breadcrumb-group.js +1 -1
  17. package/development/breadcrumb-group.component-HBWRdDpS.js +195 -0
  18. package/development/breadcrumb.js +1 -1
  19. package/development/breadcrumb.pure.js +1 -1
  20. package/development/core/base-elements/element.d.ts.map +1 -1
  21. package/development/core/base-elements/element.js +2 -5
  22. package/development/dialog/dialog/dialog.component.js +1 -1
  23. package/development/dialog/dialog.js +1 -1
  24. package/development/{dialog.component-TBiL0Sdq.js → dialog.component-DKuR4u-y.js} +2 -2
  25. package/development/dialog.js +1 -1
  26. package/development/dialog.pure.js +1 -1
  27. package/development/expansion-panel/expansion-panel/expansion-panel.component.js +1 -1
  28. package/development/expansion-panel/expansion-panel.js +1 -1
  29. package/development/{expansion-panel.component-PDUmZe7w.js → expansion-panel.component-CV_IuWZA.js} +2 -2
  30. package/development/expansion-panel.js +1 -1
  31. package/development/expansion-panel.pure.js +1 -1
  32. package/development/form-field/form-field/form-field.component.d.ts +6 -0
  33. package/development/form-field/form-field/form-field.component.d.ts.map +1 -1
  34. package/development/form-field/form-field/form-field.component.js +1 -1
  35. package/development/form-field/form-field.js +1 -1
  36. package/development/form-field.component-DfMO_ihX.js +706 -0
  37. package/development/form-field.js +1 -1
  38. package/development/form-field.pure.js +1 -1
  39. package/development/sidebar/sidebar/sidebar.component.d.ts +1 -0
  40. package/development/sidebar/sidebar/sidebar.component.d.ts.map +1 -1
  41. package/development/sidebar/sidebar/sidebar.component.js +1 -1
  42. package/development/sidebar/sidebar.js +1 -1
  43. package/development/{sidebar.component-DvRTyNry.js → sidebar.component-BLqO52nH.js} +8 -1
  44. package/development/sidebar.js +1 -1
  45. package/development/sidebar.pure.js +1 -1
  46. package/dialog/dialog/dialog.component.js +1 -1
  47. package/dialog/dialog.js +1 -1
  48. package/{dialog.component-B3oQbMki.js → dialog.component-Dv5ch5mh.js} +1 -1
  49. package/dialog.js +1 -1
  50. package/dialog.pure.js +1 -1
  51. package/expansion-panel/expansion-panel/expansion-panel.component.js +1 -1
  52. package/expansion-panel/expansion-panel.js +1 -1
  53. package/{expansion-panel.component-BJCjwcoj.js → expansion-panel.component-DBnZ6IgB.js} +1 -1
  54. package/expansion-panel.js +1 -1
  55. package/expansion-panel.pure.js +1 -1
  56. package/form-field/form-field/form-field.component.js +1 -1
  57. package/form-field/form-field.js +1 -1
  58. package/{form-field.component-D50q1wC0.js → form-field.component-Cx5Keg_p.js} +15 -15
  59. package/form-field.js +1 -1
  60. package/form-field.pure.js +1 -1
  61. package/off-brand-theme.css +32 -37
  62. package/package.json +1 -1
  63. package/safety-theme.css +32 -37
  64. package/sidebar/sidebar/sidebar.component.js +1 -1
  65. package/sidebar/sidebar.js +1 -1
  66. package/{sidebar.component-DxOx02l6.js → sidebar.component-Dsx1FAg0.js} +5 -3
  67. package/sidebar.js +1 -1
  68. package/sidebar.pure.js +1 -1
  69. package/standard-theme.css +32 -37
  70. package/table.css +32 -37
  71. package/core/styles/table.scss +0 -156
  72. package/development/breadcrumb-group.component-B3Shlng3.js +0 -195
  73. package/development/form-field.component-BEXX0OcL.js +0 -702
@@ -1,156 +0,0 @@
1
- @use './mixins/table';
2
-
3
- .sbb-table,
4
- .sbb-table-m,
5
- .sbb-table-s,
6
- .sbb-table-xs {
7
- @include table.table;
8
- }
9
-
10
- .sbb-table-m {
11
- @include table.table--m;
12
- }
13
-
14
- .sbb-table-s {
15
- @include table.table--s;
16
- }
17
-
18
- .sbb-table-xs {
19
- @include table.table--xs;
20
- }
21
-
22
- sbb-table-wrapper[negative] .sbb-table,
23
- .sbb-table--negative {
24
- @include table.table--negative;
25
- }
26
-
27
- .sbb-table--striped {
28
- @include table.table--striped;
29
- }
30
-
31
- .sbb-table--unstriped {
32
- @include table.table--unstriped;
33
- }
34
-
35
- .sbb-table--theme-iron {
36
- @include table.table--theme-iron;
37
-
38
- &.sbb-table--negative {
39
- @include table.table--theme-iron-negative;
40
- }
41
- }
42
-
43
- // @deprecated
44
- .sbb-table-header-row {
45
- @include table.table-header-row;
46
- }
47
-
48
- // @deprecated
49
- .sbb-table-header-cell {
50
- @include table.table-header-cell;
51
- }
52
-
53
- .sbb-table-row--striped {
54
- @include table.table-row--striped;
55
- }
56
-
57
- // @deprecated
58
- .sbb-table-data-cell {
59
- @include table.table-data-cell;
60
- }
61
-
62
- // @deprecated
63
- .sbb-table-caption {
64
- @include table.table-caption;
65
- }
66
-
67
- .sbb-table-filter {
68
- @include table.table-filter;
69
- }
70
-
71
- .sbb-table-sticky {
72
- // Note that the table can either set this class or an inline style to make something sticky.
73
- // We set the style as `!important` so that we get an identical specificity in both cases
74
- // and to avoid cases where user styles have a higher specificity.
75
- position: sticky !important;
76
- }
77
-
78
- // The `sbb-table-sticky-*` css classes are used by the Angular wrapper and CDK.
79
- // Do not rename them, pls.
80
- :is(.sbb-table-sticky-border-elem-left, .sbb-table-sticky-border-elem-right)::after {
81
- content: '';
82
- transition: {
83
- timing-function: var(--sbb-table-sticky-shadow-transition-easing);
84
- duration: var(--sbb-table-sticky-shadow-transition-duration);
85
- property: visibility, opacity;
86
- }
87
-
88
- visibility: hidden;
89
- opacity: 0;
90
- position: absolute;
91
- width: var(--sbb-table-sticky-shadow-width);
92
- inset: 0;
93
- }
94
-
95
- .sbb-table-sticky-border-elem-left {
96
- :is(.sbb-table-wrapper-offset-left, .sbb-table-wrapper-offset-both) & {
97
- border-inline-end: var(--sbb-table-border);
98
-
99
- &::after {
100
- visibility: visible;
101
- opacity: 1;
102
- background-image: linear-gradient(-270deg, rgb(0 0 0 / 10%) 0%, transparent 100%);
103
- inset-inline-start: unset;
104
- inset-inline-end: calc(var(--sbb-table-sticky-shadow-width) * -1 - 1px);
105
- }
106
- }
107
- }
108
-
109
- .sbb-table-sticky-border-elem-right {
110
- :is(.sbb-table-wrapper-offset-right, .sbb-table-wrapper-offset-both) & {
111
- border-inline-start: var(--sbb-table-border);
112
-
113
- &::after {
114
- visibility: visible;
115
- opacity: 1;
116
- background-image: linear-gradient(270deg, rgb(0 0 0 / 10%) 0%, transparent 100%);
117
- inset-inline-start: calc(var(--sbb-table-sticky-shadow-width) * -1 - 1px);
118
- inset-inline-end: unset;
119
- }
120
- }
121
- }
122
-
123
- // TODO: In future, move to the 'sbb-lean' theme
124
- html.sbb-lean .sbb-table:not(.sbb-table-xs, .sbb-table-m) {
125
- @include table.table--s;
126
- }
127
-
128
- .sbb-table-align-start {
129
- text-align: start;
130
- }
131
-
132
- .sbb-table-align-center {
133
- text-align: center;
134
- }
135
-
136
- .sbb-table-align-end {
137
- text-align: end;
138
- }
139
-
140
- .sbb-table-align-justify {
141
- text-align: justify;
142
- }
143
-
144
- // Backwards compatibility for sbb-angular
145
- .sbb-table-align-left {
146
- text-align: left;
147
- }
148
-
149
- // Backwards compatibility for sbb-angular
150
- .sbb-table-align-right {
151
- text-align: right;
152
- }
153
-
154
- .sbb-table-header-subtitle {
155
- font-weight: normal;
156
- }
@@ -1,195 +0,0 @@
1
- import { __esDecorate, __runInitializers } from "tslib";
2
- import { html, nothing, unsafeCSS } from "lit";
3
- import { state } from "lit/decorators.js";
4
- import { SbbElement } from "./core/base-elements.js";
5
- import { SbbNamedSlotListMixin } from "./core/mixins.js";
6
- import { boxSizingStyles } from "./core/styles.js";
7
- import { SbbLanguageController } from "./core/controllers.js";
8
- import { i18nBreadcrumbEllipsisButtonLabel } from "./core/i18n.js";
9
- import "./icon.js";
10
- import { ResizeController } from "@lit-labs/observers/resize-controller.js";
11
- import { getNextElementIndex, isArrowKeyPressed, sbbInputModalityDetector } from "./core/a11y.js";
12
- //#region src/elements/breadcrumb/breadcrumb-group/breadcrumb-group.scss?inline
13
- var breadcrumb_group_default = ":host {\n display: block;\n min-width: 0;\n}\n\n:host(:is(:state(loaded),[state--loaded])) {\n --sbb-breadcrumb-group-visibility: visible;\n}\n\n:host(:is(:is(:state(state-collapsed),[state--state-collapsed]), :is(:state(state-manually-expanded),[state--state-manually-expanded]))) {\n --sbb-breadcrumb-group-wrap: wrap;\n}\n\n.sbb-breadcrumb-group {\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: inherit;\n display: flex;\n flex-wrap: var(--sbb-breadcrumb-group-wrap);\n column-gap: var(--sbb-spacing-fixed-1x);\n visibility: var(--sbb-breadcrumb-group-visibility);\n}\n\n.sbb-breadcrumb-group__item {\n flex: 0 0 auto;\n display: flex;\n column-gap: var(--sbb-spacing-fixed-1x);\n}\n\n.sbb-breadcrumb-group__divider-icon {\n color: var(--sbb-breadcrumb-group-ellipsis-color);\n}\n\n#sbb-breadcrumb-ellipsis {\n appearance: none;\n box-sizing: border-box;\n margin: 0;\n outline: none;\n border: none;\n border-radius: 0;\n padding: 0;\n background: none;\n -webkit-tap-highlight-color: transparent;\n color: inherit;\n --sbb-text-font-size: var(--sbb-text-font-size-xxs);\n font-family: var(--sbb-typo-font-family);\n font-weight: normal;\n line-height: var(--sbb-typo-line-height-text);\n letter-spacing: var(--sbb-typo-letter-spacing-text);\n font-size: var(--sbb-text-font-size);\n line-height: 0;\n letter-spacing: 0.01em;\n font-size: var(--sbb-text-font-size-xxs);\n width: var(--sbb-size-icon-ui-small);\n height: var(--sbb-size-icon-ui-small);\n border: var(--sbb-breadcrumb-group-ellipsis-border-width) solid var(--sbb-breadcrumb-group-ellipsis-border-color);\n border-radius: 50%;\n padding-block-end: 0.5em;\n cursor: var(--sbb-cursor-pointer);\n color: var(--sbb-breadcrumb-group-ellipsis-color);\n background-color: var(--sbb-breadcrumb-group-ellipsis-background-color);\n overflow: hidden;\n}\n@media (forced-colors: active) {\n #sbb-breadcrumb-ellipsis {\n --sbb-breadcrumb-group-ellipsis-border-width: var(--sbb-border-width-2x);\n --sbb-breadcrumb-group-ellipsis-border-color: CanvasText;\n }\n}\n@media (any-hover: hover) {\n #sbb-breadcrumb-ellipsis:hover {\n --sbb-breadcrumb-group-ellipsis-color: var(--sbb-color-2);\n --sbb-breadcrumb-group-ellipsis-background-color: var(--sbb-background-color-3);\n }\n}\n@media (any-hover: hover) and (forced-colors: active) {\n #sbb-breadcrumb-ellipsis:hover {\n --sbb-breadcrumb-group-ellipsis-border-color: Highlight;\n }\n}\n#sbb-breadcrumb-ellipsis:focus-visible {\n outline-offset: var(--sbb-focus-outline-offset);\n outline: var(--sbb-focus-outline-color) var(--sbb-focus-outline-style, solid) var(--sbb-focus-outline-width);\n}";
14
- //#endregion
15
- //#region src/elements/breadcrumb/breadcrumb-group/breadcrumb-group.component.ts
16
- var MIN_BREADCRUMBS_TO_COLLAPSE = 3;
17
- /**
18
- * It can be used as a container for one or more `sbb-breadcrumb` component.
19
- *
20
- * @slot - Use the unnamed slot to add `sbb-breadcrumb` elements.
21
- */
22
- var SbbBreadcrumbGroupElement = (() => {
23
- let _classSuper = SbbNamedSlotListMixin(SbbElement);
24
- let _instanceExtraInitializers = [];
25
- let _set__state_decorators;
26
- return class SbbBreadcrumbGroupElement extends _classSuper {
27
- static {
28
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
29
- _set__state_decorators = [state()];
30
- __esDecorate(this, null, _set__state_decorators, {
31
- kind: "setter",
32
- name: "_state",
33
- static: false,
34
- private: false,
35
- access: {
36
- has: (obj) => "_state" in obj,
37
- set: (obj, value) => {
38
- obj._state = value;
39
- }
40
- },
41
- metadata: _metadata
42
- }, null, _instanceExtraInitializers);
43
- if (_metadata) Object.defineProperty(this, Symbol.metadata, {
44
- enumerable: true,
45
- configurable: true,
46
- writable: true,
47
- value: _metadata
48
- });
49
- }
50
- static {
51
- this.elementName = "sbb-breadcrumb-group";
52
- }
53
- static {
54
- this.role = "navigation";
55
- }
56
- static {
57
- this.styles = [boxSizingStyles, unsafeCSS(breadcrumb_group_default)];
58
- }
59
- /** The state of the breadcrumb group. */
60
- set _state(state) {
61
- if (this._stateInternal) this.internals.states.delete(`state-${this._stateInternal}`);
62
- this._stateInternal = state;
63
- if (this._stateInternal) this.internals.states.add(`state-${this._stateInternal}`);
64
- }
65
- get _state() {
66
- return this._stateInternal;
67
- }
68
- constructor() {
69
- super();
70
- this.listChildLocalNames = (__runInitializers(this, _instanceExtraInitializers), ["sbb-breadcrumb"]);
71
- this._stateInternal = null;
72
- this._resizeObserver = new ResizeController(this, {
73
- target: null,
74
- skipInitial: true,
75
- callback: () => this._evaluateCollapsedState()
76
- });
77
- this._language = new SbbLanguageController(this);
78
- this._markForFocus = false;
79
- this.addEventListener?.("keydown", (e) => this._handleKeyDown(e));
80
- }
81
- _handleKeyDown(evt) {
82
- if (!this.listChildren.length || evt.target !== this && evt.target.parentElement !== this) return;
83
- if (isArrowKeyPressed(evt)) {
84
- if (this._state === "collapsed") return this._focusNextCollapsed(evt);
85
- this._focusNext(evt);
86
- }
87
- }
88
- firstUpdated(changedProperties) {
89
- super.firstUpdated(changedProperties);
90
- this._resizeObserver.observe(this);
91
- this.internals.states.add("loaded");
92
- }
93
- willUpdate(changedProperties) {
94
- super.willUpdate(changedProperties);
95
- if (changedProperties.has("listChildren")) this._syncBreadcrumbs();
96
- }
97
- updated(changedProperties) {
98
- super.updated(changedProperties);
99
- if (changedProperties.has("listChildren")) Promise.resolve().then(() => this._evaluateCollapsedState());
100
- if (this._markForFocus && sbbInputModalityDetector.mostRecentModality === "keyboard") {
101
- this.listChildren[1]?.focus();
102
- this._markForFocus = false;
103
- }
104
- }
105
- /** Apply the aria-current attribute to the last sbb-breadcrumb element. */
106
- _syncBreadcrumbs() {
107
- this.listChildren.slice(0, -1).filter((c) => c.hasAttribute("accessibility-current")).forEach((c) => c.removeAttribute("accessibility-current"));
108
- this.listChildren[this.listChildren.length - 1]?.setAttribute("accessibility-current", "page");
109
- if (this.listChildren.length < MIN_BREADCRUMBS_TO_COLLAPSE) this._state = null;
110
- }
111
- /**
112
- * Sets the focus on the correct element when the ellipsis breadcrumb is displayed and the user is navigating with keyboard's arrows.
113
- */
114
- _focusNextCollapsed(evt) {
115
- const arrayCollapsed = [
116
- this.listChildren[0],
117
- this.shadowRoot.querySelector("#sbb-breadcrumb-ellipsis"),
118
- this.listChildren[this.listChildren.length - 1]
119
- ];
120
- this._focusNext(evt, arrayCollapsed);
121
- }
122
- _focusNext(evt, breadcrumbs = this.listChildren) {
123
- breadcrumbs[getNextElementIndex(evt, breadcrumbs.findIndex((e) => e === document.activeElement || e === this.shadowRoot.activeElement), breadcrumbs.length)]?.focus();
124
- evt.preventDefault();
125
- }
126
- /**
127
- * Note: due to @State annotation on _state, this method triggers a new render; as a consequence, the focus is moved
128
- * to the `body`, so if the ellipsis element has focus, it's asynchronously forced to the first element.
129
- */
130
- _expandBreadcrumbs() {
131
- this._state = "manually-expanded";
132
- this._markForFocus = true;
133
- }
134
- /** Evaluate if the expanded breadcrumb element fits in page width, otherwise it needs ellipsis */
135
- _evaluateCollapsedState() {
136
- if (!this._state && this.scrollWidth > this.offsetWidth && this.listChildren.length >= MIN_BREADCRUMBS_TO_COLLAPSE) {
137
- this._state = "collapsed";
138
- this._resizeObserver.hostDisconnected();
139
- this.removeController(this._resizeObserver);
140
- }
141
- }
142
- _renderCollapsed() {
143
- return html`
144
- <li class="sbb-breadcrumb-group__item">
145
- <slot name="li-0"></slot>
146
- </li>
147
- <li class="sbb-breadcrumb-group__item" id="sbb-breadcrumb-group-ellipsis">
148
- <sbb-icon
149
- name="chevron-small-right-small"
150
- class="sbb-breadcrumb-group__divider-icon"
151
- ></sbb-icon>
152
- <button
153
- type="button"
154
- id="sbb-breadcrumb-ellipsis"
155
- aria-label=${i18nBreadcrumbEllipsisButtonLabel[this._language.current]}
156
- aria-expanded="false"
157
- @click=${() => this._expandBreadcrumbs()}
158
- >
159
- ...
160
- </button>
161
- </li>
162
- <li class="sbb-breadcrumb-group__item">
163
- <sbb-icon
164
- name="chevron-small-right-small"
165
- class="sbb-breadcrumb-group__divider-icon"
166
- ></sbb-icon>
167
- <slot name=${`li-${this.listChildren.length - 1}`}></slot>
168
- </li>
169
- `;
170
- }
171
- _renderExpanded() {
172
- return this.listSlotEntries().map((slot, index, array) => html`
173
- <li class="sbb-breadcrumb-group__item">
174
- <slot name=${slot.name}></slot>
175
- ${index !== array.length - 1 ? html`<sbb-icon
176
- name="chevron-small-right-small"
177
- class="sbb-breadcrumb-group__divider-icon"
178
- ></sbb-icon>` : nothing}
179
- </li>
180
- `);
181
- }
182
- render() {
183
- return html`
184
- <ol class="sbb-breadcrumb-group">
185
- ${this._state === "collapsed" ? this._renderCollapsed() : this._renderExpanded()}
186
- </ol>
187
- ${this.renderHiddenSlot()}
188
- `;
189
- }
190
- };
191
- })();
192
- //#endregion
193
- export { SbbBreadcrumbGroupElement as t };
194
-
195
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJlYWRjcnVtYi1ncm91cC5jb21wb25lbnQtQjNTaGxuZzMuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VsZW1lbnRzL2JyZWFkY3J1bWIvYnJlYWRjcnVtYi1ncm91cC9icmVhZGNydW1iLWdyb3VwLnNjc3M/aW5saW5lIiwiLi4vLi4vLi4vc3JjL2VsZW1lbnRzL2JyZWFkY3J1bWIvYnJlYWRjcnVtYi1ncm91cC9icmVhZGNydW1iLWdyb3VwLmNvbXBvbmVudC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJAdXNlICcuLi8uLi9jb3JlL3N0eWxlcycgYXMgc2JiO1xuXG46aG9zdCB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuXG4gIC8vIEFsbG93cyBzaXplIGNhbGN1bGF0aW9uIGV2ZW4gaWYgaW4gZ3JpZCBvciBmbGV4IGNvbnRleHQuXG4gIG1pbi13aWR0aDogMDtcbn1cblxuOmhvc3QoOnN0YXRlKGxvYWRlZCkpIHtcbiAgLS1zYmItYnJlYWRjcnVtYi1ncm91cC12aXNpYmlsaXR5OiB2aXNpYmxlO1xufVxuXG46aG9zdCg6aXMoOnN0YXRlKHN0YXRlLWNvbGxhcHNlZCksIDpzdGF0ZShzdGF0ZS1tYW51YWxseS1leHBhbmRlZCkpKSB7XG4gIC0tc2JiLWJyZWFkY3J1bWItZ3JvdXAtd3JhcDogd3JhcDtcbn1cblxuLnNiYi1icmVhZGNydW1iLWdyb3VwIHtcbiAgQGluY2x1ZGUgc2JiLmxpc3QtcmVzZXQ7XG5cbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC13cmFwOiB2YXIoLS1zYmItYnJlYWRjcnVtYi1ncm91cC13cmFwKTtcbiAgY29sdW1uLWdhcDogdmFyKC0tc2JiLXNwYWNpbmctZml4ZWQtMXgpO1xuICB2aXNpYmlsaXR5OiB2YXIoLS1zYmItYnJlYWRjcnVtYi1ncm91cC12aXNpYmlsaXR5KTtcbn1cblxuLnNiYi1icmVhZGNydW1iLWdyb3VwX19pdGVtIHtcbiAgZmxleDogMCAwIGF1dG87XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGNvbHVtbi1nYXA6IHZhcigtLXNiYi1zcGFjaW5nLWZpeGVkLTF4KTtcbn1cblxuLnNiYi1icmVhZGNydW1iLWdyb3VwX19kaXZpZGVyLWljb24ge1xuICBjb2xvcjogdmFyKC0tc2JiLWJyZWFkY3J1bWItZ3JvdXAtZWxsaXBzaXMtY29sb3IpO1xufVxuXG4jc2JiLWJyZWFkY3J1bWItZWxsaXBzaXMge1xuICBAaW5jbHVkZSBzYmIuYnV0dG9uLXJlc2V0O1xuICBAaW5jbHVkZSBzYmIudGV4dC14eHMtLXJlZ3VsYXI7XG5cbiAgLy8gbGluZSBoZWlnaHQgYW5kIGxldHRlci1zcGFjaW5nIG5lZWRlZCB0byBtYXRjaCBzcXVhcmVzIGRyYXduIGluIEZpZ21hLlxuICBsaW5lLWhlaWdodDogMDtcbiAgbGV0dGVyLXNwYWNpbmc6IDAuMDFlbTtcbiAgZm9udC1zaXplOiB2YXIoLS1zYmItdGV4dC1mb250LXNpemUteHhzKTtcbiAgd2lkdGg6IHZhcigtLXNiYi1zaXplLWljb24tdWktc21hbGwpO1xuICBoZWlnaHQ6IHZhcigtLXNiYi1zaXplLWljb24tdWktc21hbGwpO1xuICBib3JkZXI6IHZhcigtLXNiYi1icmVhZGNydW1iLWdyb3VwLWVsbGlwc2lzLWJvcmRlci13aWR0aCkgc29saWRcbiAgICB2YXIoLS1zYmItYnJlYWRjcnVtYi1ncm91cC1lbGxpcHNpcy1ib3JkZXItY29sb3IpO1xuICBib3JkZXItcmFkaXVzOiA1MCU7XG5cbiAgLy8gSW4gb3JkZXIgdG8gdmVydGljYWxseSBjZW50ZXIgLi4uLCB3ZSB1c2UgcGFkZGluZyB3aXRoIGhhbGYgdGhlIGZvbnQgc2l6ZS5cbiAgcGFkZGluZy1ibG9jay1lbmQ6IDAuNWVtO1xuICBjdXJzb3I6IHZhcigtLXNiYi1jdXJzb3ItcG9pbnRlcik7XG4gIGNvbG9yOiB2YXIoLS1zYmItYnJlYWRjcnVtYi1ncm91cC1lbGxpcHNpcy1jb2xvcik7XG4gIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXNiYi1icmVhZGNydW1iLWdyb3VwLWVsbGlwc2lzLWJhY2tncm91bmQtY29sb3IpO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuXG4gIEBpbmNsdWRlIHNiYi5pZi1mb3JjZWQtY29sb3JzIHtcbiAgICAtLXNiYi1icmVhZGNydW1iLWdyb3VwLWVsbGlwc2lzLWJvcmRlci13aWR0aDogdmFyKC0tc2JiLWJvcmRlci13aWR0aC0yeCk7XG4gICAgLS1zYmItYnJlYWRjcnVtYi1ncm91cC1lbGxpcHNpcy1ib3JkZXItY29sb3I6IENhbnZhc1RleHQ7XG4gIH1cblxuICBAaW5jbHVkZSBzYmIuaG92ZXItbXEoJGhvdmVyOiB0cnVlKSB7XG4gICAgJjpob3ZlciB7XG4gICAgICAtLXNiYi1icmVhZGNydW1iLWdyb3VwLWVsbGlwc2lzLWNvbG9yOiB2YXIoLS1zYmItY29sb3ItMik7XG4gICAgICAtLXNiYi1icmVhZGNydW1iLWdyb3VwLWVsbGlwc2lzLWJhY2tncm91bmQtY29sb3I6IHZhcigtLXNiYi1iYWNrZ3JvdW5kLWNvbG9yLTMpO1xuXG4gICAgICBAaW5jbHVkZSBzYmIuaWYtZm9yY2VkLWNvbG9ycyB7XG4gICAgICAgIC0tc2JiLWJyZWFkY3J1bWItZ3JvdXAtZWxsaXBzaXMtYm9yZGVyLWNvbG9yOiBIaWdobGlnaHQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgJjpmb2N1cy12aXNpYmxlIHtcbiAgICBAaW5jbHVkZSBzYmIuZm9jdXMtb3V0bGluZTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgUmVzaXplQ29udHJvbGxlciB9IGZyb20gJ0BsaXQtbGFicy9vYnNlcnZlcnMvcmVzaXplLWNvbnRyb2xsZXIuanMnO1xuaW1wb3J0IHtcbiAgdHlwZSBDU1NSZXN1bHRHcm91cCxcbiAgaHRtbCxcbiAgbm90aGluZyxcbiAgdHlwZSBQcm9wZXJ0eVZhbHVlcyxcbiAgdHlwZSBUZW1wbGF0ZVJlc3VsdCxcbiAgdW5zYWZlQ1NTLFxufSBmcm9tICdsaXQnO1xuaW1wb3J0IHsgc3RhdGUgfSBmcm9tICdsaXQvZGVjb3JhdG9ycy5qcyc7XG5cbmltcG9ydCB7XG4gIGdldE5leHRFbGVtZW50SW5kZXgsXG4gIGlzQXJyb3dLZXlQcmVzc2VkLFxuICBzYmJJbnB1dE1vZGFsaXR5RGV0ZWN0b3IsXG59IGZyb20gJy4uLy4uL2NvcmUvYTExeS50cyc7XG5pbXBvcnQgeyBTYmJFbGVtZW50IH0gZnJvbSAnLi4vLi4vY29yZS9iYXNlLWVsZW1lbnRzLnRzJztcbmltcG9ydCB7IFNiYkxhbmd1YWdlQ29udHJvbGxlciB9IGZyb20gJy4uLy4uL2NvcmUvY29udHJvbGxlcnMudHMnO1xuaW1wb3J0IHsgaTE4bkJyZWFkY3J1bWJFbGxpcHNpc0J1dHRvbkxhYmVsIH0gZnJvbSAnLi4vLi4vY29yZS9pMThuLnRzJztcbmltcG9ydCB7IFNiYk5hbWVkU2xvdExpc3RNaXhpbiwgdHlwZSBXaXRoTGlzdENoaWxkcmVuIH0gZnJvbSAnLi4vLi4vY29yZS9taXhpbnMudHMnO1xuaW1wb3J0IHsgYm94U2l6aW5nU3R5bGVzIH0gZnJvbSAnLi4vLi4vY29yZS9zdHlsZXMudHMnO1xuaW1wb3J0IHR5cGUgeyBTYmJCcmVhZGNydW1iRWxlbWVudCB9IGZyb20gJy4uL2JyZWFkY3J1bWIvYnJlYWRjcnVtYi5jb21wb25lbnQudHMnO1xuXG5pbXBvcnQgc3R5bGUgZnJvbSAnLi9icmVhZGNydW1iLWdyb3VwLnNjc3M/aW5saW5lJztcblxuaW1wb3J0ICcuLi8uLi9pY29uLnRzJztcblxuY29uc3QgTUlOX0JSRUFEQ1JVTUJTX1RPX0NPTExBUFNFID0gMztcblxuLyoqXG4gKiBJdCBjYW4gYmUgdXNlZCBhcyBhIGNvbnRhaW5lciBmb3Igb25lIG9yIG1vcmUgYHNiYi1icmVhZGNydW1iYCBjb21wb25lbnQuXG4gKlxuICogQHNsb3QgLSBVc2UgdGhlIHVubmFtZWQgc2xvdCB0byBhZGQgYHNiYi1icmVhZGNydW1iYCBlbGVtZW50cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFNiYkJyZWFkY3J1bWJHcm91cEVsZW1lbnQgZXh0ZW5kcyBTYmJOYW1lZFNsb3RMaXN0TWl4aW48XG4gIFNiYkJyZWFkY3J1bWJFbGVtZW50LFxuICB0eXBlb2YgU2JiRWxlbWVudFxuPihTYmJFbGVtZW50KSB7XG4gIHB1YmxpYyBzdGF0aWMgb3ZlcnJpZGUgcmVhZG9ubHkgZWxlbWVudE5hbWU6IHN0cmluZyA9ICdzYmItYnJlYWRjcnVtYi1ncm91cCc7XG4gIHB1YmxpYyBzdGF0aWMgb3ZlcnJpZGUgcmVhZG9ubHkgcm9sZSA9ICduYXZpZ2F0aW9uJztcbiAgcHVibGljIHN0YXRpYyBvdmVycmlkZSBzdHlsZXM6IENTU1Jlc3VsdEdyb3VwID0gW2JveFNpemluZ1N0eWxlcywgdW5zYWZlQ1NTKHN0eWxlKV07XG4gIHByb3RlY3RlZCBvdmVycmlkZSByZWFkb25seSBsaXN0Q2hpbGRMb2NhbE5hbWVzID0gWydzYmItYnJlYWRjcnVtYiddO1xuXG4gIC8qKiBUaGUgc3RhdGUgb2YgdGhlIGJyZWFkY3J1bWIgZ3JvdXAuICovXG4gIEBzdGF0ZSgpXG4gIHByaXZhdGUgc2V0IF9zdGF0ZShzdGF0ZTogJ2NvbGxhcHNlZCcgfCAnbWFudWFsbHktZXhwYW5kZWQnIHwgbnVsbCkge1xuICAgIGlmICh0aGlzLl9zdGF0ZUludGVybmFsKSB7XG4gICAgICB0aGlzLmludGVybmFscy5zdGF0ZXMuZGVsZXRlKGBzdGF0ZS0ke3RoaXMuX3N0YXRlSW50ZXJuYWx9YCk7XG4gICAgfVxuICAgIHRoaXMuX3N0YXRlSW50ZXJuYWwgPSBzdGF0ZTtcbiAgICBpZiAodGhpcy5fc3RhdGVJbnRlcm5hbCkge1xuICAgICAgdGhpcy5pbnRlcm5hbHMuc3RhdGVzLmFkZChgc3RhdGUtJHt0aGlzLl9zdGF0ZUludGVybmFsfWApO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIGdldCBfc3RhdGUoKTogJ2NvbGxhcHNlZCcgfCAnbWFudWFsbHktZXhwYW5kZWQnIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlSW50ZXJuYWw7XG4gIH1cbiAgcHJpdmF0ZSBfc3RhdGVJbnRlcm5hbDogJ2NvbGxhcHNlZCcgfCAnbWFudWFsbHktZXhwYW5kZWQnIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBfcmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplQ29udHJvbGxlcih0aGlzLCB7XG4gICAgdGFyZ2V0OiBudWxsLFxuICAgIHNraXBJbml0aWFsOiB0cnVlLFxuICAgIGNhbGxiYWNrOiAoKSA9PiB0aGlzLl9ldmFsdWF0ZUNvbGxhcHNlZFN0YXRlKCksXG4gIH0pO1xuICBwcml2YXRlIF9sYW5ndWFnZSA9IG5ldyBTYmJMYW5ndWFnZUNvbnRyb2xsZXIodGhpcyk7XG4gIHByaXZhdGUgX21hcmtGb3JGb2N1cyA9IGZhbHNlO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcj8uKCdrZXlkb3duJywgKGUpID0+IHRoaXMuX2hhbmRsZUtleURvd24oZSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBfaGFuZGxlS2V5RG93bihldnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoXG4gICAgICAhdGhpcy5saXN0Q2hpbGRyZW4ubGVuZ3RoIHx8XG4gICAgICAvLyBkb24ndCB0cmFwIG5lc3RlZCBoYW5kbGluZ1xuICAgICAgKChldnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KSAhPT0gdGhpcyAmJiAoZXZ0LnRhcmdldCBhcyBIVE1MRWxlbWVudCkucGFyZW50RWxlbWVudCAhPT0gdGhpcylcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJvd0tleVByZXNzZWQoZXZ0KSkge1xuICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnY29sbGFwc2VkJykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZm9jdXNOZXh0Q29sbGFwc2VkKGV2dCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9mb2N1c05leHQoZXZ0KTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgZmlyc3RVcGRhdGVkKGNoYW5nZWRQcm9wZXJ0aWVzOiBQcm9wZXJ0eVZhbHVlczx0aGlzPik6IHZvaWQge1xuICAgIHN1cGVyLmZpcnN0VXBkYXRlZChjaGFuZ2VkUHJvcGVydGllcyk7XG5cbiAgICB0aGlzLl9yZXNpemVPYnNlcnZlci5vYnNlcnZlKHRoaXMpO1xuICAgIHRoaXMuaW50ZXJuYWxzLnN0YXRlcy5hZGQoJ2xvYWRlZCcpO1xuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIHdpbGxVcGRhdGUoY2hhbmdlZFByb3BlcnRpZXM6IFByb3BlcnR5VmFsdWVzPFdpdGhMaXN0Q2hpbGRyZW48dGhpcz4+KTogdm9pZCB7XG4gICAgc3VwZXIud2lsbFVwZGF0ZShjaGFuZ2VkUHJvcGVydGllcyk7XG5cbiAgICBpZiAoY2hhbmdlZFByb3BlcnRpZXMuaGFzKCdsaXN0Q2hpbGRyZW4nKSkge1xuICAgICAgdGhpcy5fc3luY0JyZWFkY3J1bWJzKCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIHVwZGF0ZWQoY2hhbmdlZFByb3BlcnRpZXM6IFByb3BlcnR5VmFsdWVzPFdpdGhMaXN0Q2hpbGRyZW48dGhpcz4+KTogdm9pZCB7XG4gICAgc3VwZXIudXBkYXRlZChjaGFuZ2VkUHJvcGVydGllcyk7XG4gICAgaWYgKGNoYW5nZWRQcm9wZXJ0aWVzLmhhcygnbGlzdENoaWxkcmVuJykpIHtcbiAgICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4gdGhpcy5fZXZhbHVhdGVDb2xsYXBzZWRTdGF0ZSgpKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX21hcmtGb3JGb2N1cyAmJiBzYmJJbnB1dE1vZGFsaXR5RGV0ZWN0b3IubW9zdFJlY2VudE1vZGFsaXR5ID09PSAna2V5Ym9hcmQnKSB7XG4gICAgICB0aGlzLmxpc3RDaGlsZHJlblsxXT8uZm9jdXMoKTtcblxuICAgICAgLy8gUmVzZXQgbWFyayBmb3IgZm9jdXNcbiAgICAgIHRoaXMuX21hcmtGb3JGb2N1cyA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBBcHBseSB0aGUgYXJpYS1jdXJyZW50IGF0dHJpYnV0ZSB0byB0aGUgbGFzdCBzYmItYnJlYWRjcnVtYiBlbGVtZW50LiAqL1xuICBwcml2YXRlIF9zeW5jQnJlYWRjcnVtYnMoKTogdm9pZCB7XG4gICAgdGhpcy5saXN0Q2hpbGRyZW5cbiAgICAgIC5zbGljZSgwLCAtMSlcbiAgICAgIC5maWx0ZXIoKGMpID0+IGMuaGFzQXR0cmlidXRlKCdhY2Nlc3NpYmlsaXR5LWN1cnJlbnQnKSlcbiAgICAgIC5mb3JFYWNoKChjKSA9PiBjLnJlbW92ZUF0dHJpYnV0ZSgnYWNjZXNzaWJpbGl0eS1jdXJyZW50JykpO1xuICAgIHRoaXMubGlzdENoaWxkcmVuW3RoaXMubGlzdENoaWxkcmVuLmxlbmd0aCAtIDFdPy5zZXRBdHRyaWJ1dGUoJ2FjY2Vzc2liaWxpdHktY3VycmVudCcsICdwYWdlJyk7XG5cbiAgICAvLyBJZiBpdCBpcyBub3QgZXhwYW5kYWJsZSwgcmVzZXQgc3RhdGVcbiAgICBpZiAodGhpcy5saXN0Q2hpbGRyZW4ubGVuZ3RoIDwgTUlOX0JSRUFEQ1JVTUJTX1RPX0NPTExBUFNFKSB7XG4gICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGZvY3VzIG9uIHRoZSBjb3JyZWN0IGVsZW1lbnQgd2hlbiB0aGUgZWxsaXBzaXMgYnJlYWRjcnVtYiBpcyBkaXNwbGF5ZWQgYW5kIHRoZSB1c2VyIGlzIG5hdmlnYXRpbmcgd2l0aCBrZXlib2FyZCdzIGFycm93cy5cbiAgICovXG4gIHByaXZhdGUgX2ZvY3VzTmV4dENvbGxhcHNlZChldnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBhcnJheUNvbGxhcHNlZDogU2JiQnJlYWRjcnVtYkVsZW1lbnRbXSA9IFtcbiAgICAgIHRoaXMubGlzdENoaWxkcmVuWzBdLFxuICAgICAgdGhpcy5zaGFkb3dSb290IS5xdWVyeVNlbGVjdG9yKCcjc2JiLWJyZWFkY3J1bWItZWxsaXBzaXMnKSBhcyBTYmJCcmVhZGNydW1iRWxlbWVudCxcbiAgICAgIHRoaXMubGlzdENoaWxkcmVuW3RoaXMubGlzdENoaWxkcmVuLmxlbmd0aCAtIDFdLFxuICAgIF07XG4gICAgdGhpcy5fZm9jdXNOZXh0KGV2dCwgYXJyYXlDb2xsYXBzZWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZm9jdXNOZXh0KFxuICAgIGV2dDogS2V5Ym9hcmRFdmVudCxcbiAgICBicmVhZGNydW1iczogU2JiQnJlYWRjcnVtYkVsZW1lbnRbXSA9IHRoaXMubGlzdENoaWxkcmVuLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50OiBudW1iZXIgPSBicmVhZGNydW1icy5maW5kSW5kZXgoXG4gICAgICAoZSkgPT4gZSA9PT0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCB8fCBlID09PSB0aGlzLnNoYWRvd1Jvb3QhLmFjdGl2ZUVsZW1lbnQsXG4gICAgKTtcbiAgICBjb25zdCBuZXh0SW5kZXg6IG51bWJlciA9IGdldE5leHRFbGVtZW50SW5kZXgoZXZ0LCBjdXJyZW50LCBicmVhZGNydW1icy5sZW5ndGgpO1xuICAgIGJyZWFkY3J1bWJzW25leHRJbmRleF0/LmZvY3VzKCk7XG4gICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cblxuICAvKipcbiAgICogTm90ZTogZHVlIHRvIEBTdGF0ZSBhbm5vdGF0aW9uIG9uIF9zdGF0ZSwgdGhpcyBtZXRob2QgdHJpZ2dlcnMgYSBuZXcgcmVuZGVyOyBhcyBhIGNvbnNlcXVlbmNlLCB0aGUgZm9jdXMgaXMgbW92ZWRcbiAgICogdG8gdGhlIGBib2R5YCwgc28gaWYgdGhlIGVsbGlwc2lzIGVsZW1lbnQgaGFzIGZvY3VzLCBpdCdzIGFzeW5jaHJvbm91c2x5IGZvcmNlZCB0byB0aGUgZmlyc3QgZWxlbWVudC5cbiAgICovXG4gIHByaXZhdGUgX2V4cGFuZEJyZWFkY3J1bWJzKCk6IHZvaWQge1xuICAgIHRoaXMuX3N0YXRlID0gJ21hbnVhbGx5LWV4cGFuZGVkJztcbiAgICB0aGlzLl9tYXJrRm9yRm9jdXMgPSB0cnVlO1xuICB9XG5cbiAgLyoqIEV2YWx1YXRlIGlmIHRoZSBleHBhbmRlZCBicmVhZGNydW1iIGVsZW1lbnQgZml0cyBpbiBwYWdlIHdpZHRoLCBvdGhlcndpc2UgaXQgbmVlZHMgZWxsaXBzaXMgKi9cbiAgcHJpdmF0ZSBfZXZhbHVhdGVDb2xsYXBzZWRTdGF0ZSgpOiB2b2lkIHtcbiAgICBpZiAoXG4gICAgICAhdGhpcy5fc3RhdGUgJiZcbiAgICAgIHRoaXMuc2Nyb2xsV2lkdGggPiB0aGlzLm9mZnNldFdpZHRoICYmXG4gICAgICB0aGlzLmxpc3RDaGlsZHJlbi5sZW5ndGggPj0gTUlOX0JSRUFEQ1JVTUJTX1RPX0NPTExBUFNFXG4gICAgKSB7XG4gICAgICB0aGlzLl9zdGF0ZSA9ICdjb2xsYXBzZWQnO1xuICAgICAgdGhpcy5fcmVzaXplT2JzZXJ2ZXIuaG9zdERpc2Nvbm5lY3RlZCgpO1xuICAgICAgdGhpcy5yZW1vdmVDb250cm9sbGVyKHRoaXMuX3Jlc2l6ZU9ic2VydmVyKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9yZW5kZXJDb2xsYXBzZWQoKTogVGVtcGxhdGVSZXN1bHQge1xuICAgIHJldHVybiBodG1sYFxuICAgICAgPGxpIGNsYXNzPVwic2JiLWJyZWFkY3J1bWItZ3JvdXBfX2l0ZW1cIj5cbiAgICAgICAgPHNsb3QgbmFtZT1cImxpLTBcIj48L3Nsb3Q+XG4gICAgICA8L2xpPlxuICAgICAgPGxpIGNsYXNzPVwic2JiLWJyZWFkY3J1bWItZ3JvdXBfX2l0ZW1cIiBpZD1cInNiYi1icmVhZGNydW1iLWdyb3VwLWVsbGlwc2lzXCI+XG4gICAgICAgIDxzYmItaWNvblxuICAgICAgICAgIG5hbWU9XCJjaGV2cm9uLXNtYWxsLXJpZ2h0LXNtYWxsXCJcbiAgICAgICAgICBjbGFzcz1cInNiYi1icmVhZGNydW1iLWdyb3VwX19kaXZpZGVyLWljb25cIlxuICAgICAgICA+PC9zYmItaWNvbj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGlkPVwic2JiLWJyZWFkY3J1bWItZWxsaXBzaXNcIlxuICAgICAgICAgIGFyaWEtbGFiZWw9JHtpMThuQnJlYWRjcnVtYkVsbGlwc2lzQnV0dG9uTGFiZWxbdGhpcy5fbGFuZ3VhZ2UuY3VycmVudF19XG4gICAgICAgICAgYXJpYS1leHBhbmRlZD1cImZhbHNlXCJcbiAgICAgICAgICBAY2xpY2s9JHsoKSA9PiB0aGlzLl9leHBhbmRCcmVhZGNydW1icygpfVxuICAgICAgICA+XG4gICAgICAgICAgLi4uXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9saT5cbiAgICAgIDxsaSBjbGFzcz1cInNiYi1icmVhZGNydW1iLWdyb3VwX19pdGVtXCI+XG4gICAgICAgIDxzYmItaWNvblxuICAgICAgICAgIG5hbWU9XCJjaGV2cm9uLXNtYWxsLXJpZ2h0LXNtYWxsXCJcbiAgICAgICAgICBjbGFzcz1cInNiYi1icmVhZGNydW1iLWdyb3VwX19kaXZpZGVyLWljb25cIlxuICAgICAgICA+PC9zYmItaWNvbj5cbiAgICAgICAgPHNsb3QgbmFtZT0ke2BsaS0ke3RoaXMubGlzdENoaWxkcmVuLmxlbmd0aCAtIDF9YH0+PC9zbG90PlxuICAgICAgPC9saT5cbiAgICBgO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVuZGVyRXhwYW5kZWQoKTogVGVtcGxhdGVSZXN1bHRbXSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdFNsb3RFbnRyaWVzKCkubWFwKFxuICAgICAgKHNsb3QsIGluZGV4LCBhcnJheSkgPT4gaHRtbGBcbiAgICAgICAgPGxpIGNsYXNzPVwic2JiLWJyZWFkY3J1bWItZ3JvdXBfX2l0ZW1cIj5cbiAgICAgICAgICA8c2xvdCBuYW1lPSR7c2xvdC5uYW1lfT48L3Nsb3Q+XG4gICAgICAgICAgJHtpbmRleCAhPT0gYXJyYXkubGVuZ3RoIC0gMVxuICAgICAgICAgICAgPyBodG1sYDxzYmItaWNvblxuICAgICAgICAgICAgICAgIG5hbWU9XCJjaGV2cm9uLXNtYWxsLXJpZ2h0LXNtYWxsXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInNiYi1icmVhZGNydW1iLWdyb3VwX19kaXZpZGVyLWljb25cIlxuICAgICAgICAgICAgICA+PC9zYmItaWNvbj5gXG4gICAgICAgICAgICA6IG5vdGhpbmd9XG4gICAgICAgIDwvbGk+XG4gICAgICBgLFxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgcmVuZGVyKCk6IFRlbXBsYXRlUmVzdWx0IHtcbiAgICByZXR1cm4gaHRtbGBcbiAgICAgIDxvbCBjbGFzcz1cInNiYi1icmVhZGNydW1iLWdyb3VwXCI+XG4gICAgICAgICR7dGhpcy5fc3RhdGUgPT09ICdjb2xsYXBzZWQnID8gdGhpcy5fcmVuZGVyQ29sbGFwc2VkKCkgOiB0aGlzLl9yZW5kZXJFeHBhbmRlZCgpfVxuICAgICAgPC9vbD5cbiAgICAgICR7dGhpcy5yZW5kZXJIaWRkZW5TbG90KCl9XG4gICAgYDtcbiAgfVxufVxuXG5kZWNsYXJlIGdsb2JhbCB7XG4gIGludGVyZmFjZSBIVE1MRWxlbWVudFRhZ05hbWVNYXAge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbiAgICAnc2JiLWJyZWFkY3J1bWItZ3JvdXAnOiBTYmJCcmVhZGNydW1iR3JvdXBFbGVtZW50O1xuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQzJCQSxJQUFNLDhCQUE4Qjs7Ozs7O0lBT3ZCLG1DQUF5QjttQkFBUyxzQkFHN0MsV0FBVzs7O2NBSEEsa0NBQWtDLFlBR2xDOzs7NkJBT1YsT0FBTyxDQUFBO0FBQ1IsZ0JBQUEsTUFBQSxNQUFBLHdCQUFBO0lBQUEsTUFBQTtJQUFBLE1BQUE7SUFBQSxRQUFBO0lBQUEsU0FBQTtJQUFBLFFBQUE7S0FBQSxNQUFBLFFBQUEsWUFBQTtLQUFBLE1BQUEsS0FBQSxVQUFBO0FBQUEsVUFBWSxTQUFNOztLQUFBO0lBQUEsVUFBQTtJQUFBLEVBQUEsTUFBQSwyQkFBQTs7Ozs7Ozs7O0FBUGMs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