@xaendar/core 0.4.5 → 0.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,247 @@
1
+ # @xaendar/core
2
+
3
+ Core primitives for building Web Components with the **Xaendar** framework — including base classes, decorators, and reactive input signals.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@xaendar/core)](https://www.npmjs.com/package/@xaendar/core)
6
+ [![license](https://img.shields.io/npm/l/@xaendar/core)](https://opensource.org/licenses/MIT)
7
+
8
+ ---
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @xaendar/core
14
+ ```
15
+
16
+ > **Peer requirements** — This package targets the browser and relies on the native [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) APIs (`customElements`, `ShadowRoot`, `CustomEvent`) and the TC39 [Signals proposal](https://github.com/tc39/proposal-signals) (`Signal.State`).
17
+
18
+ ---
19
+
20
+ ## Overview
21
+
22
+ `@xaendar/core` gives you everything you need to author reactive, encapsulated Web Components:
23
+
24
+ | Primitive | Description |
25
+ |-----------|-------------|
26
+ | `BaseWebComponent` | Base class for every component — attaches a Shadow DOM and wires up lifecycle hooks |
27
+ | `@WebComponent` | Class decorator that registers the element with the browser and binds observed attributes |
28
+ | `@Property` | Accessor decorator that exposes a reactive `InputSignal` as an HTML attribute |
29
+ | `@Event` | Accessor decorator that creates a typed `CustomEvent` emitter |
30
+ | `InputSignal` | A `Signal.State` specialised for attribute-driven input, with optional value transformation |
31
+
32
+ > **Granular, signal-driven rendering** — the view is never re-rendered as a whole. Every DOM node (element, attribute, or text node) is independently subscribed to the signal(s) it depends on. When a signal value changes, **only the exact nodes that read that signal are updated** — nothing else is touched.
33
+
34
+ ---
35
+
36
+ ## Usage
37
+
38
+ ### 1. Define a component
39
+
40
+ ```ts
41
+ import { BaseWebComponent, WebComponent, Property, Event } from '@xaendar/core';
42
+ import type { InputSignal, Output } from '@xaendar/core';
43
+
44
+ @WebComponent({
45
+ selector: 'my-button',
46
+ templateUrl: './my-button.template.html',
47
+ styleUrl: './my-button.styles.css', // optional
48
+ })
49
+ class MyButton extends BaseWebComponent {
50
+
51
+ /** Reactive label — set via HTML attribute or programmatically */
52
+ @Property('Click me')
53
+ public accessor label!: InputSignal<string>;
54
+
55
+ /** Disabled state, transformed from the string attribute to a boolean */
56
+ @Property(false, {
57
+ transform: (v: string) => v !== 'false'
58
+ })
59
+ public accessor disabled!: InputSignal<boolean, string>;
60
+
61
+ /** Emits when the button is clicked */
62
+ @Event({ bubbles: true, composed: true })
63
+ public accessor clicked!: Output<void>;
64
+ }
65
+ ```
66
+
67
+ ```html
68
+ <!-- Use it anywhere in your HTML -->
69
+ <my-button label="Submit"></my-button>
70
+ ```
71
+
72
+ ---
73
+
74
+ ### 2. `BaseWebComponent`
75
+
76
+ All Xaendar components must extend `BaseWebComponent`. It:
77
+
78
+ - Attaches a `ShadowRoot` in **open** mode on construction.
79
+ - Implements `attributeChangedCallback` to propagate attribute changes into the corresponding `InputSignal`.
80
+ - Implements `connectedCallback` / `disconnectedCallback` to manage the component lifecycle.
81
+
82
+ ```ts
83
+ import { BaseWebComponent } from '@xaendar/core';
84
+
85
+ class MyComponent extends BaseWebComponent {
86
+ // your component logic
87
+ }
88
+ ```
89
+
90
+ ---
91
+
92
+ ### 3. `@WebComponent(options)`
93
+
94
+ Registers the class as a Custom Element.
95
+
96
+ | Option | Type | Required | Description |
97
+ |--------|------|----------|-------------|
98
+ | `selector` | `string \| string[]` | ✅ | The custom element tag name(s) |
99
+ | `templateUrl` | `string` | ✅ | Path to the HTML template |
100
+ | `styleUrl` | `string` | — | Path to the component stylesheet |
101
+
102
+ ```ts
103
+ @WebComponent({
104
+ selector: ['x-card', 'xaendar-card'],
105
+ templateUrl: './card.xd.component.html'
106
+ })
107
+ class Card extends BaseWebComponent { }
108
+ ```
109
+
110
+ ---
111
+
112
+ ### 4. `@Property(initialValue?, options?)`
113
+
114
+ Marks an `accessor` field as a reactive attribute-bound property.
115
+
116
+ - Registers the property key in the element's `observedAttributes` list.
117
+ - Wraps the value in an `InputSignal` — read it like a signal via `.get()`.
118
+ - Supports an optional `transform` function to coerce the raw attribute string into a typed value.
119
+
120
+ ```ts
121
+ // Optional property with a default value
122
+ @Property('hello')
123
+ accessor title: InputSignal<string>;
124
+
125
+ // Required-style with transform (string → number)
126
+ @Property(0, { transform: Number })
127
+ accessor count: InputSignal<number, string>;
128
+ ```
129
+
130
+ Reading the value inside the component:
131
+
132
+ ```ts
133
+ const current = this.count.get(); // number
134
+ ```
135
+
136
+ ---
137
+
138
+ ### 5. `@Event(options?)`
139
+
140
+ Creates a typed `CustomEvent` emitter bound to the property name.
141
+
142
+ ```ts
143
+ @Event({
144
+ bubbles: true,
145
+ composed: true
146
+ })
147
+ accessor valueChange: Output<string>;
148
+
149
+ // Emit from inside the component
150
+ this.valueChange.emit('new value');
151
+
152
+ // Override options per-emit
153
+ this.valueChange.emit('new value', { bubbles: false });
154
+ ```
155
+
156
+ Listen from outside in pure HTML:
157
+
158
+ ```html
159
+ <my-input id="inp"></my-input>
160
+ <script>
161
+ document.getElementById('inp').addEventListener('valueChange', e => {
162
+ console.log(e.detail); // 'new value'
163
+ });
164
+ </script>
165
+ ```
166
+
167
+ ---
168
+
169
+ ### 6. `InputSignal`
170
+
171
+ A `Signal.State` extended with attribute-pipeline support. You rarely construct it directly — `@Property` handles that — but the type is exported for annotations.
172
+
173
+ ```ts
174
+ import type { InputSignal } from '@xaendar/core';
175
+
176
+ // Type-only annotation
177
+ declare accessor name: InputSignal<string>;
178
+
179
+ // Reading the current value (Signal API)
180
+ this.name.get();
181
+ ```
182
+
183
+ ---
184
+
185
+ ## Granular DOM updates
186
+
187
+ Xaendar does **not** use a virtual DOM or component-level re-render cycles. The compiler analyses the template at build time and creates a **direct subscription** between each signal and every DOM node that consumes it:
188
+
189
+ - **Text nodes** — only the text node whose content depends on a signal is updated.
190
+ - **Element attributes** — only the specific attribute bound to a signal is written.
191
+ - **Structural nodes** — only the nodes involved in a conditional or iteration driven by a signal are added/removed.
192
+
193
+ When a signal value changes, the update is **surgical**: no diff, no component subtree walk, no unnecessary repaints.
194
+
195
+ ```
196
+ signal.set('new value')
197
+
198
+
199
+ ┌──────────────────────────────────┐
200
+ │ DOM nodes subscribed to signal │
201
+ │ ┌─────────────────────────────┐ │
202
+ │ │ <span> text node ← updated │ │
203
+ │ └─────────────────────────────┘ │
204
+ │ ┌─────────────────────────────┐ │
205
+ │ │ [aria-label] attr ← updated │ │
206
+ │ └─────────────────────────────┘ │
207
+ └──────────────────────────────────┘
208
+
209
+ everything else → untouched
210
+ ```
211
+
212
+ This makes updates **O(1) per signal change** regardless of the size of the component tree.
213
+
214
+ ---
215
+
216
+ ## TypeScript configuration
217
+
218
+ Xaendar components rely on **TC39 decorator metadata** and **accessor** syntax.
219
+ Make sure your `tsconfig.json` has at least:
220
+
221
+ ```json
222
+ {
223
+ "compilerOptions": {
224
+ "target": "ES2022",
225
+ "experimentalDecorators": false,
226
+ "useDefineForClassFields": true
227
+ }
228
+ }
229
+ ```
230
+
231
+ > Standard (stage-3) decorators are used — **not** the legacy `experimentalDecorators` variant.
232
+
233
+ ---
234
+
235
+ ## Related packages
236
+
237
+ | Package | Description |
238
+ |---------|-------------|
239
+ | [`@xaendar/signals`](https://www.npmjs.com/package/@xaendar/signals) | Reactive signal primitives |
240
+ | [`@xaendar/types`](https://www.npmjs.com/package/@xaendar/types) | Shared TypeScript utility types |
241
+ | [`@xaendar/compiler`](https://www.npmjs.com/package/@xaendar/compiler) | Template compiler |
242
+
243
+ ---
244
+
245
+ ## License
246
+
247
+ MIT © [Kaitenjo](https://github.com/kaitenjo)
@@ -2,6 +2,7 @@ import { AccessorDecorator } from '@xaendar/types';
2
2
  import { Beautify } from '@xaendar/types';
3
3
  import { ClassDecorator as ClassDecorator_2 } from '@xaendar/types';
4
4
  import { Constructor } from '@xaendar/types';
5
+ import { NoArgsVoidFunction } from '@xaendar/types';
5
6
  import { RequireOne } from '@xaendar/types';
6
7
  import { SignalOptions } from '@xaendar/signals';
7
8
  import { SignalOptions as SignalOptions_2 } from '@xaendar/signals';
@@ -15,6 +16,10 @@ import { VoidFunction as VoidFunction_2 } from '@xaendar/types';
15
16
  * It won't appear by intellisense but it's there.
16
17
  */
17
18
  export declare class BaseWebComponent extends HTMLElement {
19
+ /**
20
+ * Array of functions to unwatch all the signals used in the component
21
+ */
22
+ protected unwatchFns: NoArgsVoidFunction[];
18
23
  /**
19
24
  * The root of the Web Component, where the content is rendered
20
25
  */
@@ -1,122 +1,272 @@
1
1
  //#region ../packages/core/src/decorators/event.decorator.ts
2
- function e(e) {
3
- return !!e && typeof e == "object" && ("bubbles" in e || "cancelable" in e || "composed" in e);
2
+ function isEventOptions(value) {
3
+ return !!value && typeof value === "object" && ("bubbles" in value || "cancelable" in value || "composed" in value);
4
4
  }
5
- function t(t) {
6
- return (n, r) => {
7
- let i = r.name, a;
8
- if (r.addInitializer(function() {
9
- a = this.dispatchEvent.bind(this);
10
- }), typeof i == "symbol") throw Error("Symbol properties are not supported as event names");
11
- let o = { emit: (e, t) => {} };
5
+ function Event(options) {
6
+ return (_value, context) => {
7
+ const name = context.name;
8
+ let dispatchEvent;
9
+ context.addInitializer(function() {
10
+ dispatchEvent = this.dispatchEvent.bind(this);
11
+ });
12
+ if (typeof name === "symbol") throw new Error("Symbol properties are not supported as event names");
13
+ const output = { emit: (_valueOrOverrideOptions, _overrideOptions) => {} };
12
14
  return { get() {
13
- return o.emit = function(n, r) {
14
- let o = {};
15
- o = e(n) ? {
16
- ...t,
17
- ...n
15
+ output.emit = function(valueOrOverrideOptions, overrideOptions) {
16
+ let eventOptions = {};
17
+ eventOptions = isEventOptions(valueOrOverrideOptions) ? {
18
+ ...options,
19
+ ...valueOrOverrideOptions
18
20
  } : {
19
- ...t,
20
- ...r,
21
- detail: n
21
+ ...options,
22
+ ...overrideOptions,
23
+ detail: valueOrOverrideOptions
22
24
  };
23
- let s = new CustomEvent(i, o);
24
- a(s);
25
- }, o;
25
+ const event = new CustomEvent(name, eventOptions);
26
+ dispatchEvent(event);
27
+ };
28
+ return output;
26
29
  } };
27
30
  };
28
31
  }
29
32
  //#endregion
30
33
  //#region ../packages/core/src/costants.ts
31
- var n = "observedAttributes", r = Symbol("InputSignalSet");
32
- function i(e) {
33
- if (e !== r) throw Error("Invalid symbol for InputSignal set method");
34
+ var INTERNAL_OBSERVED_ATTRIBUTES = `observedAttributes`;
35
+ //#endregion
36
+ //#region ../packages/core/src/signals/input/input-set.symbol.ts
37
+ /**
38
+ * This symbol is used to call the set method of the InputSignal
39
+ * Normally the set method is permitted internally and should not be called
40
+ * by the User
41
+ */
42
+ var INPUT_SIGNAL_SET_SYMBOL = Symbol(`InputSignalSet`);
43
+ /**
44
+ * Asserts that the provided symbol matches the internal {@link INPUT_SIGNAL_SET_SYMBOL} symbol,
45
+ * ensuring the caller has access to internal APIs.
46
+ *
47
+ * Throws if the symbol does not match, preventing external code from
48
+ * invoking methods intended for internal use only.
49
+ *
50
+ * @param symbol - The symbol to validate against {@link INPUT_SIGNAL_SET_SYMBOL}.
51
+ * @throws {Error} If `symbol` does not match {@link INPUT_SIGNAL_SET_SYMBOL}.
52
+ * @internal
53
+ */
54
+ function assertPrivateContext(symbol) {
55
+ if (symbol !== INPUT_SIGNAL_SET_SYMBOL) throw new Error("Invalid symbol for InputSignal set method");
34
56
  }
35
57
  //#endregion
36
58
  //#region ../packages/core/src/signals/input/input.model.ts
37
- var a = class extends Signal.State {
59
+ /**
60
+ * An `InputSignal` is a specialized `Signal.State` designed for use as a property signal in web components.
61
+ * It extends the base `State` signal with additional functionality to handle incoming values, such as those from HTML attributes or external sources,
62
+ * and allows for optional transformation of these values before they are stored in the signal.
63
+ */
64
+ var InputSignal = class extends Signal.State {
65
+ /**
66
+ * Optional transform function to convert incoming values to the actual type stored in the signal.
67
+ */
38
68
  _transform;
39
- constructor(e, t) {
40
- let n = t?.transform;
41
- delete t?.transform, super(e, t), this._transform = n;
69
+ /**
70
+ * Creates a new `InputSignal` instance.
71
+ *
72
+ * @param initialValue - The initial value of the signal.
73
+ * @param options - Optional configuration:
74
+ * - `equals` — custom equality function; defaults to `Object.is`.
75
+ * - `watched` — called when the signal gains its first sink.
76
+ * - `unwatched` — called when the signal loses its last sink.
77
+ * - `transform` — function to transform incoming values before setting the signal's value.
78
+ */
79
+ constructor(value, options) {
80
+ const transform = options?.transform;
81
+ delete options?.transform;
82
+ super(value, options);
83
+ this._transform = transform;
42
84
  }
43
- set(e, t) {
44
- i(t);
45
- let n = this._transform ? this._transform(e) : e;
46
- super.set(n);
85
+ /**
86
+ * Set a new value to the signal, applying the transform function if provided.
87
+ * @param newValue - The new value to set.
88
+ * @throws If `frozen` is `true` — writes are forbidden while a protected
89
+ * callback is executing.
90
+ */
91
+ set(newValue, symbol) {
92
+ assertPrivateContext(symbol);
93
+ const transformedValue = this._transform ? this._transform(newValue) : newValue;
94
+ super.set(transformedValue);
47
95
  }
48
- }, o = Symbol("PropertyDecoratorOptionsWithRequiredBrand");
49
- function s(e, t) {
50
- return function(r, i) {
51
- let s = i.name;
52
- if (typeof s == "symbol") throw Error("Symbol properties are not supported");
53
- let c = i.metadata;
54
- c[n] ??= [], c[n].push(s);
55
- let l, u;
56
- !e || typeof e != "object" || !(o in e) ? (l = e, u = t) : u = e;
57
- let d = new a(l, {
58
- equals: u?.equals,
59
- watched: u?.watched,
60
- unwatched: u?.unwatched,
61
- transform: u?.transform
96
+ };
97
+ //#endregion
98
+ //#region ../packages/core/src/decorators/property.decorator.ts
99
+ var propertyDecoratorOptionsWithRequiredBrand = Symbol("PropertyDecoratorOptionsWithRequiredBrand");
100
+ function createPropertyDecorator(value, options) {
101
+ return function(_target, context) {
102
+ const propertyKey = context.name;
103
+ if (typeof propertyKey === "symbol") throw new Error("Symbol properties are not supported");
104
+ const metadata = context.metadata;
105
+ metadata[INTERNAL_OBSERVED_ATTRIBUTES] ??= [];
106
+ metadata[INTERNAL_OBSERVED_ATTRIBUTES].push(propertyKey);
107
+ let actualValue;
108
+ let actualOptions;
109
+ if (!value || typeof value !== "object" || !(propertyDecoratorOptionsWithRequiredBrand in value)) {
110
+ actualValue = value;
111
+ actualOptions = options;
112
+ } else actualOptions = value;
113
+ const signal = new InputSignal(actualValue, {
114
+ equals: actualOptions?.equals,
115
+ watched: actualOptions?.watched,
116
+ unwatched: actualOptions?.unwatched,
117
+ transform: actualOptions?.transform
62
118
  });
63
119
  return {
64
120
  get() {
65
- return d;
121
+ return signal;
66
122
  },
67
- init(e) {
68
- return d;
123
+ init(_) {
124
+ return signal;
69
125
  }
70
126
  };
71
127
  };
72
128
  }
73
- function c(e, t) {
74
- return s(e, t);
129
+ /**
130
+ * Decoratore per proprietà opzionale.
131
+ *
132
+ * @example
133
+ * @Property()
134
+ * accessor label: InputSignal<string>;
135
+ *
136
+ * @Property({ value: 0 })
137
+ * accessor count: InputSignal<number>;
138
+ *
139
+ * @Property({ value: { required: true, foo: 'bar' }, alias: 'cfg' })
140
+ * accessor config: InputSignal<Config>;
141
+ */
142
+ function Property(value, options) {
143
+ return createPropertyDecorator(value, options);
75
144
  }
76
- c.required = function(e) {
77
- return s({
78
- ...e,
79
- [o]: "PropertyDecoratorOptionsWithRequired",
80
- required: !0
145
+ /**
146
+ * Decoratore per proprietà obbligatoria.
147
+ * Il consumer deve fornire il valore; non accetta un valore di default.
148
+ *
149
+ * @example
150
+ * @Property.required()
151
+ * accessor userId: InputSignal<string>;
152
+ *
153
+ * @Property.required({ alias: 'user-id' })
154
+ * accessor userId: InputSignal<string>;
155
+ */
156
+ Property.required = function required(options) {
157
+ return createPropertyDecorator({
158
+ ...options,
159
+ [propertyDecoratorOptionsWithRequiredBrand]: "PropertyDecoratorOptionsWithRequired",
160
+ required: true
81
161
  });
82
162
  };
83
163
  //#endregion
84
164
  //#region ../packages/core/src/decorators/web-component/web-component.decorator.ts
85
- function l(e) {
86
- return function(t, n) {
87
- u(t, n), d(t, e.selector);
165
+ /**
166
+ * Decorator to define a web component
167
+ * @param selector Name or names of the custom element
168
+ */
169
+ function WebComponent(options) {
170
+ return function(klass, context) {
171
+ defineObservedAttributes(klass, context);
172
+ setSelectors(klass, options.selector);
88
173
  };
89
174
  }
90
- function u(e, t) {
91
- Object.defineProperty(e, "observedAttributes", {
92
- get: () => t.metadata[n],
93
- configurable: !1,
94
- enumerable: !1
175
+ /**
176
+ * Function to define the observedAttributes static property on the class.
177
+ * We define static get observedAttributes programmatically
178
+ * to abstract the manual definition from the user.
179
+ *
180
+ * We could not define the property in the base class due to the fact
181
+ * that is static and each derived class would override the value of the others
182
+ * @param klass The class to set the observedAttributes on
183
+ * @param attributes The attributes to observe
184
+ */
185
+ function defineObservedAttributes(klass, context) {
186
+ Object.defineProperty(klass, "observedAttributes", {
187
+ get: () => context.metadata[INTERNAL_OBSERVED_ATTRIBUTES],
188
+ configurable: false,
189
+ enumerable: false
95
190
  });
96
191
  }
97
- function d(e, t) {
98
- Array.isArray(t) ? t.forEach((t) => customElements.define(t, e)) : customElements.define(t, e);
192
+ /**
193
+ * Function to add the custom element definition to the browser using the passed selectors.
194
+ * @param klass The class to define as a web component
195
+ * @param selectors The selector or selectors to reference the web component in HTML
196
+ */
197
+ function setSelectors(klass, selectors) {
198
+ Array.isArray(selectors) ? selectors.forEach((selector) => customElements.define(selector, klass)) : customElements.define(selectors, klass);
99
199
  }
100
200
  //#endregion
101
201
  //#region ../packages/core/src/directives/base-web-component.ts
102
- var f = class extends HTMLElement {
202
+ /**
203
+ * Base class for all Web Components in the framework
204
+ *
205
+ * This class internally has an `observedAttributes` property
206
+ * add programmaticaly by the @WebComponent decorator.
207
+ * It won't appear by intellisense but it's there.
208
+ */
209
+ var BaseWebComponent = class extends HTMLElement {
210
+ /**
211
+ * Array of functions to unwatch all the signals used in the component
212
+ */
213
+ unwatchFns = new Array();
214
+ /**
215
+ * The root of the Web Component, where the content is rendered
216
+ */
103
217
  _root;
104
218
  constructor() {
105
- super(), this._root = this.attachShadow({ mode: "open" });
219
+ super();
220
+ this._root = this.attachShadow({ mode: "open" });
221
+ }
222
+ /**
223
+ * Method called by the @Property decorator to
224
+ * update the rendering of the component
225
+ * @internal
226
+ */
227
+ _render() {
228
+ return [];
106
229
  }
107
- _render() {}
108
- attributeChangedCallback(e, t, n) {
109
- let i = this;
110
- if (!(e in i)) throw Error(`Attribute ${e} is not associated to any property`);
111
- if (!(i[e] instanceof a)) throw Error(`Property ${e} is not an InputSignal`);
112
- i[e].set(n, r);
230
+ /**
231
+ * Method automatically called by the JavascriptEngine when an attribute
232
+ * on the host element is changed
233
+ *
234
+ * This method runs before the connectedCallback method if any observed attribute
235
+ * is specified on the CustomElement tag in the HTML
236
+ *
237
+ * @param name Name of the attribute changed
238
+ * @param _oldValue Old value of the attribute
239
+ * @param newValue New value of the attribute
240
+ */
241
+ attributeChangedCallback(name, _oldValue, newValue) {
242
+ const context = this;
243
+ if (!(name in context)) throw new Error(`Attribute ${name} is not associated to any property`);
244
+ if (!(context[name] instanceof InputSignal)) throw new Error(`Property ${name} is not an InputSignal`);
245
+ context[name].set(newValue, INPUT_SIGNAL_SET_SYMBOL);
113
246
  }
247
+ /**
248
+ * Method automatically called by the JavascriptEngine when a CustomElement
249
+ * is added to the DOM
250
+ *
251
+ * This method is called EVERY time the element is added
252
+ */
114
253
  connectedCallback() {
115
- this._render();
254
+ this.unwatchFns = this._render();
255
+ }
256
+ /**
257
+ * Method automatically called by the JavascriptEngine when a CustomElement
258
+ * is removed from the DOM
259
+ *
260
+ * This method is called EVERY time the element is removed
261
+ *
262
+ * We use this method to reset the _initialized flag
263
+ * so that if the element is re-added to the DOM
264
+ * the properties initialization won't call the render method
265
+ */
266
+ disconnectedCallback() {
267
+ this.unwatchFns.forEach((unwatch) => unwatch());
268
+ this.unwatchFns = [];
116
269
  }
117
- disconnectedCallback() {}
118
270
  };
119
271
  //#endregion
120
- export { f as BaseWebComponent, t as Event, a as InputSignal, c as Property, l as WebComponent };
121
-
122
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieGFlbmRhci1jb3JlLmVzLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL2RlY29yYXRvcnMvZXZlbnQuZGVjb3JhdG9yLnRzIiwiLi4vLi4vLi4vLi4vcGFja2FnZXMvY29yZS9zcmMvY29zdGFudHMudHMiLCIuLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9zaWduYWxzL2lucHV0L2lucHV0LXNldC5zeW1ib2wudHMiLCIuLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9zaWduYWxzL2lucHV0L2lucHV0Lm1vZGVsLnRzIiwiLi4vLi4vLi4vLi4vcGFja2FnZXMvY29yZS9zcmMvZGVjb3JhdG9ycy9wcm9wZXJ0eS5kZWNvcmF0b3IudHMiLCIuLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9kZWNvcmF0b3JzL3dlYi1jb21wb25lbnQvd2ViLWNvbXBvbmVudC5kZWNvcmF0b3IudHMiLCIuLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9kaXJlY3RpdmVzL2Jhc2Utd2ViLWNvbXBvbmVudC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY2Nlc3NvckRlY29yYXRvciwgQ2xhc3NBY2Nlc3NvckRlY29yYXRvclZhbHVlIH0gZnJvbSAnQHhhZW5kYXIvdHlwZXMnO1xyXG5pbXBvcnQgeyBCYXNlV2ViQ29tcG9uZW50IH0gZnJvbSAnLi4vZGlyZWN0aXZlcy9iYXNlLXdlYi1jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBFdmVudE9wdGlvbnMgfSBmcm9tICcuLi90eXBlcy9ldmVudC9ldmVudC1vcHRpb25zLnR5cGUnO1xyXG5pbXBvcnQgeyBPdXRwdXQgfSBmcm9tICcuLi90eXBlcy9ldmVudC9vdXRwdXQudHlwZSc7XHJcblxyXG5mdW5jdGlvbiBpc0V2ZW50T3B0aW9ucyh2YWx1ZTogRXZlbnRPcHRpb25zIHwgdW5rbm93bik6IHZhbHVlIGlzIEV2ZW50T3B0aW9ucyB7XHJcbiAgcmV0dXJuICEhdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiAoJ2J1YmJsZXMnIGluIHZhbHVlIHx8ICdjYW5jZWxhYmxlJyBpbiB2YWx1ZSB8fCAnY29tcG9zZWQnIGluIHZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIEV2ZW50PFxyXG4gIENsYXNzIGV4dGVuZHMgQmFzZVdlYkNvbXBvbmVudCxcclxuICBEYXRhID0gdm9pZCxcclxuPihvcHRpb25zPzogRXZlbnRPcHRpb25zKTogQWNjZXNzb3JEZWNvcmF0b3I8Q2xhc3MsIE91dHB1dDxEYXRhPj4ge1xyXG4gIHJldHVybiAoX3ZhbHVlOiBDbGFzc0FjY2Vzc29yRGVjb3JhdG9yVmFsdWU8T3V0cHV0PERhdGE+PiwgY29udGV4dDogQ2xhc3NBY2Nlc3NvckRlY29yYXRvckNvbnRleHQ8Q2xhc3MsIE91dHB1dDxEYXRhPj4pOiBSZXR1cm5UeXBlPEFjY2Vzc29yRGVjb3JhdG9yPENsYXNzLCBPdXRwdXQ8RGF0YT4+PiA9PiB7XHJcbiAgICBjb25zdCBuYW1lID0gY29udGV4dC5uYW1lO1xyXG4gICAgbGV0IGRpc3BhdGNoRXZlbnQ6IEV2ZW50VGFyZ2V0WydkaXNwYXRjaEV2ZW50J107XHJcblxyXG4gICAgY29udGV4dC5hZGRJbml0aWFsaXplcihmdW5jdGlvbiAodGhpczogQ2xhc3MpIHtcclxuICAgICAgZGlzcGF0Y2hFdmVudCA9IHRoaXMuZGlzcGF0Y2hFdmVudC5iaW5kKHRoaXMpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSAnc3ltYm9sJykge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N5bWJvbCBwcm9wZXJ0aWVzIGFyZSBub3Qgc3VwcG9ydGVkIGFzIGV2ZW50IG5hbWVzJyk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3Qgb3V0cHV0OiBPdXRwdXQ8RGF0YT4gPSB7XHJcbiAgICAgIGVtaXQ6IChfdmFsdWVPck92ZXJyaWRlT3B0aW9ucz86IERhdGEgfCBFdmVudE9wdGlvbnMsIF9vdmVycmlkZU9wdGlvbnM/OiBFdmVudE9wdGlvbnMpID0+IHsgfVxyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBnZXQoKTogT3V0cHV0PERhdGE+IHtcclxuICAgICAgICBvdXRwdXQuZW1pdCA9IGZ1bmN0aW9uICh0aGlzOiBDbGFzcywgdmFsdWVPck92ZXJyaWRlT3B0aW9ucz86IERhdGEgfCBFdmVudE9wdGlvbnMsIG92ZXJyaWRlT3B0aW9ucz86IEV2ZW50T3B0aW9ucykge1xyXG4gICAgICAgICAgbGV0IGV2ZW50T3B0aW9uczogQ3VzdG9tRXZlbnRJbml0PERhdGE+ID0ge307XHJcblxyXG4gICAgICAgICAgZXZlbnRPcHRpb25zID0gaXNFdmVudE9wdGlvbnModmFsdWVPck92ZXJyaWRlT3B0aW9ucylcclxuICAgICAgICAgICAgPyB7IC4uLm9wdGlvbnMsIC4uLnZhbHVlT3JPdmVycmlkZU9wdGlvbnMgfVxyXG4gICAgICAgICAgICA6IHsgLi4ub3B0aW9ucywgLi4ub3ZlcnJpZGVPcHRpb25zLCBkZXRhaWw6IHZhbHVlT3JPdmVycmlkZU9wdGlvbnMgfVxyXG5cclxuICAgICAgICAgIGNvbnN0IGV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KG5hbWUsIGV2ZW50T3B0aW9ucyk7XHJcbiAgICAgICAgICBkaXNwYXRjaEV2ZW50KGV2ZW50KTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiBvdXRwdXQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiZXhwb3J0IGNvbnN0IElOVEVSTkFMX09CU0VSVkVEX0FUVFJJQlVURVMgPSBgb2JzZXJ2ZWRBdHRyaWJ1dGVzYDsiLCIvKipcclxuICogVGhpcyBzeW1ib2wgaXMgdXNlZCB0byBjYWxsIHRoZSBzZXQgbWV0aG9kIG9mIHRoZSBJbnB1dFNpZ25hbFxyXG4gKiBOb3JtYWxseSB0aGUgc2V0IG1ldGhvZCBpcyBwZXJtaXR0ZWQgaW50ZXJuYWxseSBhbmQgc2hvdWxkIG5vdCBiZSBjYWxsZWRcclxuICogYnkgdGhlIFVzZXJcclxuICovXHJcbmV4cG9ydCBjb25zdCBJTlBVVF9TSUdOQUxfU0VUX1NZTUJPTCA9IFN5bWJvbChgSW5wdXRTaWduYWxTZXRgKTtcclxuXHJcbi8qKlxyXG4gKiBBc3NlcnRzIHRoYXQgdGhlIHByb3ZpZGVkIHN5bWJvbCBtYXRjaGVzIHRoZSBpbnRlcm5hbCB7QGxpbmsgSU5QVVRfU0lHTkFMX1NFVF9TWU1CT0x9IHN5bWJvbCxcclxuICogZW5zdXJpbmcgdGhlIGNhbGxlciBoYXMgYWNjZXNzIHRvIGludGVybmFsIEFQSXMuXHJcbiAqXHJcbiAqIFRocm93cyBpZiB0aGUgc3ltYm9sIGRvZXMgbm90IG1hdGNoLCBwcmV2ZW50aW5nIGV4dGVybmFsIGNvZGUgZnJvbVxyXG4gKiBpbnZva2luZyBtZXRob2RzIGludGVuZGVkIGZvciBpbnRlcm5hbCB1c2Ugb25seS5cclxuICpcclxuICogQHBhcmFtIHN5bWJvbCAtIFRoZSBzeW1ib2wgdG8gdmFsaWRhdGUgYWdhaW5zdCB7QGxpbmsgSU5QVVRfU0lHTkFMX1NFVF9TWU1CT0x9LlxyXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgYHN5bWJvbGAgZG9lcyBub3QgbWF0Y2gge0BsaW5rIElOUFVUX1NJR05BTF9TRVRfU1lNQk9MfS5cclxuICogQGludGVybmFsXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0UHJpdmF0ZUNvbnRleHQoc3ltYm9sOiBzeW1ib2wpOiB2b2lkIHtcclxuICBpZiAoc3ltYm9sICE9PSBJTlBVVF9TSUdOQUxfU0VUX1NZTUJPTCkge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN5bWJvbCBmb3IgSW5wdXRTaWduYWwgc2V0IG1ldGhvZCcpO1xyXG4gIH1cclxufSIsImltcG9ydCB7IFNpZ25hbE9wdGlvbnMgfSBmcm9tICdAeGFlbmRhci9zaWduYWxzJztcclxuaW1wb3J0IHsgYXNzZXJ0UHJpdmF0ZUNvbnRleHQgfSBmcm9tICcuL2lucHV0LXNldC5zeW1ib2wnO1xyXG5cclxuLyoqXHJcbiAqIEFuIGBJbnB1dFNpZ25hbGAgaXMgYSBzcGVjaWFsaXplZCBgU2lnbmFsLlN0YXRlYCBkZXNpZ25lZCBmb3IgdXNlIGFzIGEgcHJvcGVydHkgc2lnbmFsIGluIHdlYiBjb21wb25lbnRzLiBcclxuICogSXQgZXh0ZW5kcyB0aGUgYmFzZSBgU3RhdGVgIHNpZ25hbCB3aXRoIGFkZGl0aW9uYWwgZnVuY3Rpb25hbGl0eSB0byBoYW5kbGUgaW5jb21pbmcgdmFsdWVzLCBzdWNoIGFzIHRob3NlIGZyb20gSFRNTCBhdHRyaWJ1dGVzIG9yIGV4dGVybmFsIHNvdXJjZXMsIFxyXG4gKiBhbmQgYWxsb3dzIGZvciBvcHRpb25hbCB0cmFuc2Zvcm1hdGlvbiBvZiB0aGVzZSB2YWx1ZXMgYmVmb3JlIHRoZXkgYXJlIHN0b3JlZCBpbiB0aGUgc2lnbmFsLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIElucHV0U2lnbmFsPEFjdHVhbFZhbHVlID0gdW5rbm93biwgSW5jb21pbmdWYWx1ZSA9IEFjdHVhbFZhbHVlPiBleHRlbmRzIFNpZ25hbC5TdGF0ZTxBY3R1YWxWYWx1ZT57XHJcbiAgLyoqXHJcbiAgICogT3B0aW9uYWwgdHJhbnNmb3JtIGZ1bmN0aW9uIHRvIGNvbnZlcnQgaW5jb21pbmcgdmFsdWVzIHRvIHRoZSBhY3R1YWwgdHlwZSBzdG9yZWQgaW4gdGhlIHNpZ25hbC5cclxuICAgKi9cclxuICBwcml2YXRlIF90cmFuc2Zvcm0/OiAodmFsdWU6IEluY29taW5nVmFsdWUpID0+IEFjdHVhbFZhbHVlO1xyXG5cclxuICAvKipcclxuICAgKiBDcmVhdGVzIGEgbmV3IGBJbnB1dFNpZ25hbGAgaW5zdGFuY2UuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gaW5pdGlhbFZhbHVlIC0gVGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIHNpZ25hbC5cclxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb246XHJcbiAgICogICAtIGBlcXVhbHNgIOKAlCBjdXN0b20gZXF1YWxpdHkgZnVuY3Rpb247IGRlZmF1bHRzIHRvIGBPYmplY3QuaXNgLlxyXG4gICAqICAgLSBgd2F0Y2hlZGAg4oCUIGNhbGxlZCB3aGVuIHRoZSBzaWduYWwgZ2FpbnMgaXRzIGZpcnN0IHNpbmsuXHJcbiAgICogICAtIGB1bndhdGNoZWRgIOKAlCBjYWxsZWQgd2hlbiB0aGUgc2lnbmFsIGxvc2VzIGl0cyBsYXN0IHNpbmsuXHJcbiAgICogICAtIGB0cmFuc2Zvcm1gIOKAlCBmdW5jdGlvbiB0byB0cmFuc2Zvcm0gaW5jb21pbmcgdmFsdWVzIGJlZm9yZSBzZXR0aW5nIHRoZSBzaWduYWwncyB2YWx1ZS5cclxuICAgKi9cclxuICBjb25zdHJ1Y3Rvcih2YWx1ZT86IEFjdHVhbFZhbHVlLCBvcHRpb25zPzogU2lnbmFsT3B0aW9uczxBY3R1YWxWYWx1ZT4gJiB7IHRyYW5zZm9ybT86ICh2YWx1ZTogSW5jb21pbmdWYWx1ZSkgPT4gQWN0dWFsVmFsdWUgfSkge1xyXG4gICAgY29uc3QgdHJhbnNmb3JtID0gb3B0aW9ucz8udHJhbnNmb3JtO1xyXG4gICAgLyogXHJcbiAgICAgIEVuc3VyZSB0cmFuc2Zvcm0gZmllbGQgaXMgbm90IHBhc3NlZCB0byBzdXBlciBjb25zdHJ1Y3RvclxyXG4gICAgICBzaW5jZSBpdCdzIG5vdCBwYXJ0IG9mIFNpZ25hbE9wdGlvbnMgYW5kIHdvdWxkIGNhdXNlIGFuIGVycm9yXHJcbiAgICAqL1xyXG4gICAgZGVsZXRlIG9wdGlvbnM/LnRyYW5zZm9ybTtcclxuXHJcbiAgICBzdXBlcih2YWx1ZSBhcyBBY3R1YWxWYWx1ZSwgb3B0aW9ucyk7XHJcbiAgICB0aGlzLl90cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXQgYSBuZXcgdmFsdWUgdG8gdGhlIHNpZ25hbCwgYXBwbHlpbmcgdGhlIHRyYW5zZm9ybSBmdW5jdGlvbiBpZiBwcm92aWRlZC5cclxuICAgKiBAcGFyYW0gbmV3VmFsdWUgLSBUaGUgbmV3IHZhbHVlIHRvIHNldC5cclxuICAgKiBAdGhyb3dzIElmIGBmcm96ZW5gIGlzIGB0cnVlYCDigJQgd3JpdGVzIGFyZSBmb3JiaWRkZW4gd2hpbGUgYSBwcm90ZWN0ZWRcclxuICAgKiBjYWxsYmFjayBpcyBleGVjdXRpbmcuXHJcbiAgICovXHJcbiAgLy8gQHRzLWV4cGVjdC1lcnJvclxyXG4gIHB1YmxpYyBvdmVycmlkZSBzZXQobmV3VmFsdWU6IEluY29taW5nVmFsdWUsIHN5bWJvbDogc3ltYm9sKTogdm9pZCB7XHJcbiAgICBhc3NlcnRQcml2YXRlQ29udGV4dChzeW1ib2wpO1xyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX3RyYW5zZm9ybSA/IHRoaXMuX3RyYW5zZm9ybShuZXdWYWx1ZSkgOiBuZXdWYWx1ZTtcclxuICAgIHN1cGVyLnNldCh0cmFuc2Zvcm1lZFZhbHVlIGFzIEFjdHVhbFZhbHVlKTtcclxuICB9XHJcbn1cclxuIiwiaW1wb3J0IHsgQWNjZXNzb3JEZWNvcmF0b3IsIENsYXNzQWNjZXNzb3JEZWNvcmF0b3JWYWx1ZSB9IGZyb20gJ0B4YWVuZGFyL3R5cGVzJztcclxuaW1wb3J0IHsgSU5URVJOQUxfT0JTRVJWRURfQVRUUklCVVRFUyB9IGZyb20gJy4uL2Nvc3RhbnRzJztcclxuaW1wb3J0IHsgQmFzZVdlYkNvbXBvbmVudCB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvYmFzZS13ZWItY29tcG9uZW50JztcclxuaW1wb3J0IHsgSW5wdXRTaWduYWwgfSBmcm9tICcuLi9zaWduYWxzL2lucHV0L2lucHV0Lm1vZGVsJztcclxuaW1wb3J0IHsgUHJvcGVydHlEZWNvcmF0b3JPcHRpb25zLCBQcm9wZXJ0eURlY29yYXRvck9wdGlvbnNXaXRoUmVxdWlyZWQsIH0gZnJvbSAnLi4vdHlwZXMvcHJvcGVydHktZGVjb3JhdG9yLW9wdGlvbnMudHlwZSc7XHJcblxyXG5jb25zdCBwcm9wZXJ0eURlY29yYXRvck9wdGlvbnNXaXRoUmVxdWlyZWRCcmFuZCA9IFN5bWJvbCgnUHJvcGVydHlEZWNvcmF0b3JPcHRpb25zV2l0aFJlcXVpcmVkQnJhbmQnKTtcclxudHlwZSBQcm9wZXJ0eURlY29yYXRvcHJPcHRpb25zV2l0aFJlcXVpcmVkQnJhbmRUeXBlPEFjdHVhbFZhbHVlID0gdW5rbm93biwgSW5jb21pbmdWYWx1ZSA9IEFjdHVhbFZhbHVlPiA9IFByb3BlcnR5RGVjb3JhdG9yT3B0aW9uc1dpdGhSZXF1aXJlZDxBY3R1YWxWYWx1ZSwgSW5jb21pbmdWYWx1ZT4gJiB7IFxyXG4gIFtwcm9wZXJ0eURlY29yYXRvck9wdGlvbnNXaXRoUmVxdWlyZWRCcmFuZF06ICdQcm9wZXJ0eURlY29yYXRvck9wdGlvbnNXaXRoUmVxdWlyZWQnIFxyXG59O1xyXG5cclxuZnVuY3Rpb24gY3JlYXRlUHJvcGVydHlEZWNvcmF0b3I8XHJcbiAgQ2xhc3MgZXh0ZW5kcyBCYXNlV2ViQ29tcG9uZW50LFxyXG4gIFZhbHVlIGV4dGVuZHMgSW5wdXRTaWduYWw8QWN0dWFsVmFsdWUsIEluY29taW5nVmFsdWU+LFxyXG4gIEFjdHVhbFZhbHVlID0gdW5rbm93bixcclxuICBJbmNvbWluZ1ZhbHVlID0gQWN0dWFsVmFsdWVcclxuPih2YWx1ZT86IEFjdHVhbFZhbHVlIHwgUHJvcGVydHlEZWNvcmF0b3ByT3B0aW9uc1dpdGhSZXF1aXJlZEJyYW5kVHlwZTxBY3R1YWxWYWx1ZSwgSW5jb21pbmdWYWx1ZT4sIG9wdGlvbnM/OiBQcm9wZXJ0eURlY29yYXRvck9wdGlvbnM8QWN0dWFsVmFsdWUsIEluY29taW5nVmFsdWU+KTogQWNjZXNzb3JEZWNvcmF0b3I8Q2xhc3MsIFZhbHVlPiB7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uIChcclxuICAgIF90YXJnZXQ6IENsYXNzQWNjZXNzb3JEZWNvcmF0b3JWYWx1ZTxWYWx1ZT4sXHJcbiAgICBjb250ZXh0OiBDbGFzc0FjY2Vzc29yRGVjb3JhdG9yQ29udGV4dDxDbGFzcywgVmFsdWU+XHJcbiAgKTogUmV0dXJuVHlwZTxBY2Nlc3NvckRlY29yYXRvcjxDbGFzcywgVmFsdWU+PiB7XHJcbiAgICBjb25zdCBwcm9wZXJ0eUtleSA9IGNvbnRleHQubmFtZTtcclxuXHJcbiAgICBpZiAodHlwZW9mIHByb3BlcnR5S2V5ID09PSAnc3ltYm9sJykge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N5bWJvbCBwcm9wZXJ0aWVzIGFyZSBub3Qgc3VwcG9ydGVkJyk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgbWV0YWRhdGEgPSBjb250ZXh0Lm1ldGFkYXRhIGFzIHsgW0lOVEVSTkFMX09CU0VSVkVEX0FUVFJJQlVURVNdPzogc3RyaW5nW10gfTtcclxuICAgIG1ldGFkYXRhW0lOVEVSTkFMX09CU0VSVkVEX0FUVFJJQlVURVNdID8/PSBbXTtcclxuICAgIG1ldGFkYXRhW0lOVEVSTkFMX09CU0VSVkVEX0FUVFJJQlVURVNdLnB1c2gocHJvcGVydHlLZXkpO1xyXG5cclxuICAgIGxldCBhY3R1YWxWYWx1ZTogQWN0dWFsVmFsdWUgfCB1bmRlZmluZWQ7XHJcbiAgICBsZXQgYWN0dWFsT3B0aW9uczogUHJvcGVydHlEZWNvcmF0b3JPcHRpb25zPEFjdHVhbFZhbHVlLCBJbmNvbWluZ1ZhbHVlPiB8IHVuZGVmaW5lZCB8IFByb3BlcnR5RGVjb3JhdG9wck9wdGlvbnNXaXRoUmVxdWlyZWRCcmFuZFR5cGU8QWN0dWFsVmFsdWUsIEluY29taW5nVmFsdWU+IHwgdW5kZWZpbmVkO1xyXG4gICAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnIHx8ICEocHJvcGVydHlEZWNvcmF0b3JPcHRpb25zV2l0aFJlcXVpcmVkQnJhbmQgaW4gdmFsdWUpKSB7XHJcbiAgICAgIGFjdHVhbFZhbHVlID0gdmFsdWU7XHJcbiAgICAgIGFjdHVhbE9wdGlvbnMgPSBvcHRpb25zO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgYWN0dWFsT3B0aW9ucyA9IHZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHNpZ25hbCA9IG5ldyBJbnB1dFNpZ25hbDxBY3R1YWxWYWx1ZSwgSW5jb21pbmdWYWx1ZT4oYWN0dWFsVmFsdWUsIHtcclxuICAgICAgZXF1YWxzOiBhY3R1YWxPcHRpb25zPy5lcXVhbHMsXHJcbiAgICAgIHdhdGNoZWQ6IGFjdHVhbE9wdGlvbnM/LndhdGNoZWQsXHJcbiAgICAgIHVud2F0Y2hlZDogYWN0dWFsT3B0aW9ucz8udW53YXRjaGVkLFxyXG4gICAgICB0cmFuc2Zvcm06IGFjdHVhbE9wdGlvbnM/LnRyYW5zZm9ybVxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgZ2V0KCkge1xyXG4gICAgICAgIHJldHVybiBzaWduYWwgYXMgVmFsdWU7XHJcbiAgICAgIH0sXHJcbiAgICAgIGluaXQoXz86IElucHV0U2lnbmFsPEFjdHVhbFZhbHVlLCBJbmNvbWluZ1ZhbHVlPikge1xyXG4gICAgICAgIHJldHVybiBzaWduYWwgYXMgVmFsdWU7XHJcbiAgICAgIH0sXHJcbiAgICB9O1xyXG4gIH07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBEZWNvcmF0b3JlIHBlciBwcm9wcmlldMOgIG9wemlvbmFsZS5cclxuICpcclxuICogQGV4YW1wbGVcclxuICogQFByb3BlcnR5KClcclxuICogYWNjZXNzb3IgbGFiZWw6IElucHV0U2lnbmFsPHN0cmluZz47XHJcbiAqXHJcbiAqIEBQcm9wZXJ0eSh7IHZhbHVlOiAwIH0pXHJcbiAqIGFjY2Vzc29yIGNvdW50OiBJbnB1dFNpZ25hbDxudW1iZXI+O1xyXG4gKlxyXG4gKiBAUHJvcGVydHkoeyB2YWx1ZTogeyByZXF1aXJlZDogdHJ1ZSwgZm9vOiAnYmFyJyB9LCBhbGlhczogJ2NmZycgfSlcclxuICogYWNjZXNzb3IgY29uZmlnOiBJbnB1dFNpZ25hbDxDb25maWc+O1xyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIFByb3BlcnR5PFxyXG4gIENsYXNzIGV4dGVuZHMgQmFzZVdlYkNvbXBvbmVudCxcclxuICBWYWx1ZSBleHRlbmRzIElucHV0U2lnbmFsPEFjdHVhbFZhbHVlLCBJbmNvbWluZ1ZhbHVlPixcclxuICBBY3R1YWxWYWx1ZSA9IFZhbHVlIGV4dGVuZHMgSW5wdXRTaWduYWw8aW5mZXIgVSwgYW55PiA/IFUgOiB1bmtub3duLFxyXG4gIEluY29taW5nVmFsdWUgPSBWYWx1ZSBleHRlbmRzIElucHV0U2lnbmFsPGFueSwgaW5mZXIgVj4gPyBWIDogQWN0dWFsVmFsdWVcclxuPihcclxuICB2YWx1ZT86IEFjdHVhbFZhbHVlLFxyXG4gIG9wdGlvbnM/OiBQcm9wZXJ0eURlY29yYXRvck9wdGlvbnM8QWN0dWFsVmFsdWUsIEluY29taW5nVmFsdWU+XHJcbik6IEFjY2Vzc29yRGVjb3JhdG9yPENsYXNzLCBJbnB1dFNpZ25hbDxBY3R1YWxWYWx1ZSwgSW5jb21pbmdWYWx1ZT4+IHtcclxuICByZXR1cm4gY3JlYXRlUHJvcGVydHlEZWNvcmF0b3I8Q2xhc3MsIElucHV0U2lnbmFsPEFjdHVhbFZhbHVlLCBJbmNvbWluZ1ZhbHVlPiwgQWN0dWFsVmFsdWUsIEluY29taW5nVmFsdWU+KHZhbHVlLCBvcHRpb25zKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIERlY29yYXRvcmUgcGVyIHByb3ByaWV0w6Agb2JibGlnYXRvcmlhLlxyXG4gKiBJbCBjb25zdW1lciBkZXZlIGZvcm5pcmUgaWwgdmFsb3JlOyBub24gYWNjZXR0YSB1biB2YWxvcmUgZGkgZGVmYXVsdC5cclxuICpcclxuICogQGV4YW1wbGVcclxuICogQFByb3BlcnR5LnJlcXVpcmVkKClcclxuICogYWNjZXNzb3IgdXNlcklkOiBJbnB1dFNpZ25hbDxzdHJpbmc+O1xyXG4gKlxyXG4gKiBAUHJvcGVydHkucmVxdWlyZWQoeyBhbGlhczogJ3VzZXItaWQnIH0pXHJcbiAqIGFjY2Vzc29yIHVzZXJJZDogSW5wdXRTaWduYWw8c3RyaW5nPjtcclxuICovXHJcblByb3BlcnR5LnJlcXVpcmVkID0gZnVuY3Rpb24gcmVxdWlyZWQ8XHJcbiAgQ2xhc3MgZXh0ZW5kcyBCYXNlV2ViQ29tcG9uZW50LFxyXG4gIEFjdHVhbFZhbHVlID0gdW5rbm93bixcclxuICBJbmNvbWluZ1ZhbHVlID0gQWN0dWFsVmFsdWVcclxuPihcclxuICBvcHRpb25zPzogT21pdDxQcm9wZXJ0eURlY29yYXRvck9wdGlvbnNXaXRoUmVxdWlyZWQ8QWN0dWFsVmFsdWUsIEluY29taW5nVmFsdWU+LCAncmVxdWlyZWQnPlxyXG4pOiBBY2Nlc3NvckRlY29yYXRvcjxDbGFzcywgSW5wdXRTaWduYWw8QWN0dWFsVmFsdWUsIEluY29taW5nVmFsdWU+PiB7XHJcbiAgcmV0dXJuIGNyZWF0ZVByb3BlcnR5RGVjb3JhdG9yPENsYXNzLCBJbnB1dFNpZ25hbDxBY3R1YWxWYWx1ZSwgSW5jb21pbmdWYWx1ZT4sIEFjdHVhbFZhbHVlLCBJbmNvbWluZ1ZhbHVlPih7XHJcbiAgICAuLi5vcHRpb25zLFxyXG4gICAgW3Byb3BlcnR5RGVjb3JhdG9yT3B0aW9uc1dpdGhSZXF1aXJlZEJyYW5kXTogJ1Byb3BlcnR5RGVjb3JhdG9yT3B0aW9uc1dpdGhSZXF1aXJlZCcsXHJcbiAgICByZXF1aXJlZDogdHJ1ZSxcclxuICB9KTtcclxufTsiLCJpbXBvcnQgeyBDbGFzc0RlY29yYXRvciwgQ29uc3RydWN0b3IgfSBmcm9tICdAeGFlbmRhci90eXBlcyc7XHJcbmltcG9ydCB7IElOVEVSTkFMX09CU0VSVkVEX0FUVFJJQlVURVMgfSBmcm9tICcuLi8uLi9jb3N0YW50cyc7XHJcbmltcG9ydCB7IEJhc2VXZWJDb21wb25lbnQgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL2Jhc2Utd2ViLWNvbXBvbmVudCc7XHJcbmltcG9ydCB7IFdlYkNvbXBvbmVudERlY29yYXRvclBhcmFtcyB9IGZyb20gJy4uLy4uL3R5cGVzL3dlYi1jb21wb25lbnQvd2ViLWNvbXBvbmVudC1kZWNvcmF0b3ItcGFyYW1zLnR5cGUnO1xyXG5cclxuLyoqXHJcbiAqIERlY29yYXRvciB0byBkZWZpbmUgYSB3ZWIgY29tcG9uZW50XHJcbiAqIEBwYXJhbSBzZWxlY3RvciBOYW1lIG9yIG5hbWVzIG9mIHRoZSBjdXN0b20gZWxlbWVudFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIFdlYkNvbXBvbmVudDxUIGV4dGVuZHMgQmFzZVdlYkNvbXBvbmVudD4ob3B0aW9uczogV2ViQ29tcG9uZW50RGVjb3JhdG9yUGFyYW1zKTogQ2xhc3NEZWNvcmF0b3I8VD4ge1xyXG4gIHJldHVybiBmdW5jdGlvbiAoa2xhc3M6IENvbnN0cnVjdG9yPFQ+LCBjb250ZXh0OiBDbGFzc0RlY29yYXRvckNvbnRleHQ8Q29uc3RydWN0b3I8VD4+KTogdm9pZCB7XHJcbiAgICBkZWZpbmVPYnNlcnZlZEF0dHJpYnV0ZXMoa2xhc3MsIGNvbnRleHQpO1xyXG4gICAgc2V0U2VsZWN0b3JzKGtsYXNzLCBvcHRpb25zLnNlbGVjdG9yKTtcclxuICB9O1xyXG59XHJcblxyXG4vKipcclxuICogRnVuY3Rpb24gdG8gZGVmaW5lIHRoZSBvYnNlcnZlZEF0dHJpYnV0ZXMgc3RhdGljIHByb3BlcnR5IG9uIHRoZSBjbGFzcy5cclxuICogV2UgZGVmaW5lIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzIHByb2dyYW1tYXRpY2FsbHlcclxuICogdG8gYWJzdHJhY3QgdGhlIG1hbnVhbCBkZWZpbml0aW9uIGZyb20gdGhlIHVzZXIuXHJcbiAqXHJcbiAqIFdlIGNvdWxkIG5vdCBkZWZpbmUgdGhlIHByb3BlcnR5IGluIHRoZSBiYXNlIGNsYXNzIGR1ZSB0byB0aGUgZmFjdFxyXG4gKiB0aGF0IGlzIHN0YXRpYyBhbmQgZWFjaCBkZXJpdmVkIGNsYXNzIHdvdWxkIG92ZXJyaWRlIHRoZSB2YWx1ZSBvZiB0aGUgb3RoZXJzXHJcbiAqIEBwYXJhbSBrbGFzcyBUaGUgY2xhc3MgdG8gc2V0IHRoZSBvYnNlcnZlZEF0dHJpYnV0ZXMgb25cclxuICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgdG8gb2JzZXJ2ZVxyXG4gKi9cclxuZnVuY3Rpb24gZGVmaW5lT2JzZXJ2ZWRBdHRyaWJ1dGVzPFQgZXh0ZW5kcyBCYXNlV2ViQ29tcG9uZW50PihrbGFzczogQ29uc3RydWN0b3I8VD4sIGNvbnRleHQ6IENsYXNzRGVjb3JhdG9yQ29udGV4dDxDb25zdHJ1Y3RvcjxUPj4pOiB2b2lkIHtcclxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoa2xhc3MsICdvYnNlcnZlZEF0dHJpYnV0ZXMnLCB7XHJcbiAgICBnZXQ6ICgpID0+IGNvbnRleHQubWV0YWRhdGEhW0lOVEVSTkFMX09CU0VSVkVEX0FUVFJJQlVURVNdLFxyXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZSxcclxuICAgIGVudW1lcmFibGU6IGZhbHNlXHJcbiAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGdW5jdGlvbiB0byBhZGQgdGhlIGN1c3RvbSBlbGVtZW50IGRlZmluaXRpb24gdG8gdGhlIGJyb3dzZXIgdXNpbmcgdGhlIHBhc3NlZCBzZWxlY3RvcnMuXHJcbiAqIEBwYXJhbSBrbGFzcyBUaGUgY2xhc3MgdG8gZGVmaW5lIGFzIGEgd2ViIGNvbXBvbmVudFxyXG4gKiBAcGFyYW0gc2VsZWN0b3JzIFRoZSBzZWxlY3RvciBvciBzZWxlY3RvcnMgdG8gcmVmZXJlbmNlIHRoZSB3ZWIgY29tcG9uZW50IGluIEhUTUxcclxuICovXHJcbmZ1bmN0aW9uIHNldFNlbGVjdG9yczxUIGV4dGVuZHMgQmFzZVdlYkNvbXBvbmVudD4oa2xhc3M6IENvbnN0cnVjdG9yPFQ+LCBzZWxlY3RvcnM6IHN0cmluZyB8IHN0cmluZ1tdKTogdm9pZCB7XHJcbiAgQXJyYXkuaXNBcnJheShzZWxlY3RvcnMpXHJcbiAgICA/IHNlbGVjdG9ycy5mb3JFYWNoKHNlbGVjdG9yID0+IGN1c3RvbUVsZW1lbnRzLmRlZmluZShzZWxlY3Rvciwga2xhc3MpKVxyXG4gICAgOiBjdXN0b21FbGVtZW50cy5kZWZpbmUoc2VsZWN0b3JzLCBrbGFzcyk7XHJcbn0iLCJpbXBvcnQgeyBJTlBVVF9TSUdOQUxfU0VUX1NZTUJPTCB9IGZyb20gXCIuLi9zaWduYWxzL2lucHV0L2lucHV0LXNldC5zeW1ib2xcIjtcclxuaW1wb3J0IHsgSW5wdXRTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFscy9pbnB1dC9pbnB1dC5tb2RlbFwiO1xyXG5cclxuLyoqXHJcbiAqIEJhc2UgY2xhc3MgZm9yIGFsbCBXZWIgQ29tcG9uZW50cyBpbiB0aGUgZnJhbWV3b3JrXHJcbiAqIFxyXG4gKiBUaGlzIGNsYXNzIGludGVybmFsbHkgaGFzIGFuIGBvYnNlcnZlZEF0dHJpYnV0ZXNgIHByb3BlcnR5XHJcbiAqIGFkZCBwcm9ncmFtbWF0aWNhbHkgYnkgdGhlIEBXZWJDb21wb25lbnQgZGVjb3JhdG9yLiBcclxuICogSXQgd29uJ3QgYXBwZWFyIGJ5IGludGVsbGlzZW5zZSBidXQgaXQncyB0aGVyZS5cclxuICovXHJcbmV4cG9ydCBjbGFzcyBCYXNlV2ViQ29tcG9uZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQge1xyXG4gIC8qKlxyXG4gICAqIFRoZSByb290IG9mIHRoZSBXZWIgQ29tcG9uZW50LCB3aGVyZSB0aGUgY29udGVudCBpcyByZW5kZXJlZFxyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgX3Jvb3Q6IFNoYWRvd1Jvb3Q7XHJcblxyXG4gIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgc3VwZXIoKTtcclxuICAgIHRoaXMuX3Jvb3QgPSB0aGlzLmF0dGFjaFNoYWRvdyh7IG1vZGU6ICdvcGVuJyB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldGhvZCBjYWxsZWQgYnkgdGhlIEBQcm9wZXJ0eSBkZWNvcmF0b3IgdG9cclxuICAgKiB1cGRhdGUgdGhlIHJlbmRlcmluZyBvZiB0aGUgY29tcG9uZW50XHJcbiAgICogQGludGVybmFsIFxyXG4gICAqL1xyXG4gIHByaXZhdGUgX3JlbmRlcigpOiB2b2lkIHsgfVxyXG5cclxuICAvKipcclxuICAgKiBNZXRob2QgYXV0b21hdGljYWxseSBjYWxsZWQgYnkgdGhlIEphdmFzY3JpcHRFbmdpbmUgd2hlbiBhbiBhdHRyaWJ1dGVcclxuICAgKiBvbiB0aGUgaG9zdCBlbGVtZW50IGlzIGNoYW5nZWRcclxuICAgKiBcclxuICAgKiBUaGlzIG1ldGhvZCBydW5zIGJlZm9yZSB0aGUgY29ubmVjdGVkQ2FsbGJhY2sgbWV0aG9kIGlmIGFueSBvYnNlcnZlZCBhdHRyaWJ1dGVcclxuICAgKiBpcyBzcGVjaWZpZWQgb24gdGhlIEN1c3RvbUVsZW1lbnQgdGFnIGluIHRoZSBIVE1MXHJcbiAgICogXHJcbiAgICogQHBhcmFtIG5hbWUgTmFtZSBvZiB0aGUgYXR0cmlidXRlIGNoYW5nZWRcclxuICAgKiBAcGFyYW0gX29sZFZhbHVlIE9sZCB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlXHJcbiAgICogQHBhcmFtIG5ld1ZhbHVlIE5ldyB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZTogc3RyaW5nLCBfb2xkVmFsdWU6IHVua25vd24sIG5ld1ZhbHVlOiB1bmtub3duKTogdm9pZCB7XHJcbiAgICAvKlxyXG4gICAgICBTaW5jZSB0aGUgJ1Byb3BlcnR5IERlY29yYXRvciBhZGQgdGhlIHByb3BlcnR5IGtleSB0byB0aGUgT2JzZXJ2ZWRBdHRyaWJ1dGVzXHJcbiAgICAgIFdlIGFyZSBzdXJlIHRoYXQgdGhlIHByb3BlcnR5IHdpdGggdGhlIGdpdmVuIG5hbWUgZXhpc3RzIG9uIHRoZSBpbnN0YW5jZSBvZiB0aGUgc3ViY2xhc3NcclxuICAgICovXHJcbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcyBhcyBCYXNlV2ViQ29tcG9uZW50ICYgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XHJcbiAgICBpZiAoIShuYW1lIGluIGNvbnRleHQpKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQXR0cmlidXRlICR7bmFtZX0gaXMgbm90IGFzc29jaWF0ZWQgdG8gYW55IHByb3BlcnR5YCk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qXHJcbiAgICAgIEBQcm9wZXJ0eSBkZWNvcmF0b3IgdHlwZXMgZW5zdXJlIHRoYXQgdGhlIHByb3BlcnR5IGFzc29jaWF0ZWQgdG8gdGhlIGF0dHJpYnV0ZSBpcyBhbiBJbnB1dFNpZ25hbFxyXG4gICAgICBidXQgaSBwcmVmZXIgdG8gY2hlY2sgaXQgYXQgcnVudGltZSBhbnl3YXkgdG8gYXZvaWQgYW55IHBvc3NpYmxlIGVycm9yIGluIHRoZSBmdXR1cmUgXHJcbiAgICAgIGlmIHRoZSBkZWNvcmF0b3IgaXMgdXNlZCB3cm9uZyBvciBpZiB0aGUgdHlwZXMgYXJlIG5vdCByZXNwZWN0ZWQgZm9yIHNvbWUgcmVhc29uIFxyXG4gICAgICovXHJcbiAgICBpZiAoIShjb250ZXh0W25hbWVdIGluc3RhbmNlb2YgSW5wdXRTaWduYWwpKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUHJvcGVydHkgJHtuYW1lfSBpcyBub3QgYW4gSW5wdXRTaWduYWxgKTtcclxuICAgIH1cclxuXHJcbiAgICBjb250ZXh0W25hbWVdLnNldChuZXdWYWx1ZSwgSU5QVVRfU0lHTkFMX1NFVF9TWU1CT0wpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0aG9kIGF1dG9tYXRpY2FsbHkgY2FsbGVkIGJ5IHRoZSBKYXZhc2NyaXB0RW5naW5lIHdoZW4gYSBDdXN0b21FbGVtZW50XHJcbiAgICogaXMgYWRkZWQgdG8gdGhlIERPTVxyXG4gICAqIFxyXG4gICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBFVkVSWSB0aW1lIHRoZSBlbGVtZW50IGlzIGFkZGVkXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBjb25uZWN0ZWRDYWxsYmFjaygpOiB2b2lkIHtcclxuICAgIHRoaXMuX3JlbmRlcigpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0aG9kIGF1dG9tYXRpY2FsbHkgY2FsbGVkIGJ5IHRoZSBKYXZhc2NyaXB0RW5naW5lIHdoZW4gYSBDdXN0b21FbGVtZW50XHJcbiAgICogaXMgcmVtb3ZlZCBmcm9tIHRoZSBET01cclxuICAgKiBcclxuICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgRVZFUlkgdGltZSB0aGUgZWxlbWVudCBpcyByZW1vdmVkXHJcbiAgICogXHJcbiAgICogV2UgdXNlIHRoaXMgbWV0aG9kIHRvIHJlc2V0IHRoZSBfaW5pdGlhbGl6ZWQgZmxhZ1xyXG4gICAqIHNvIHRoYXQgaWYgdGhlIGVsZW1lbnQgaXMgcmUtYWRkZWQgdG8gdGhlIERPTVxyXG4gICAqIHRoZSBwcm9wZXJ0aWVzIGluaXRpYWxpemF0aW9uIHdvbid0IGNhbGwgdGhlIHJlbmRlciBtZXRob2RcclxuICAgKi9cclxuICBwcml2YXRlIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCk6IHZvaWQge1xyXG4gIH1cclxufSJdLCJtYXBwaW5ncyI6IjtBQUtBLFNBQVMsRUFBZSxHQUFzRDtDQUM1RSxPQUFPLENBQUMsQ0FBQyxLQUFTLE9BQU8sS0FBVSxhQUFhLGFBQWEsS0FBUyxnQkFBZ0IsS0FBUyxjQUFjO0FBQy9HO0FBRUEsU0FBZ0IsRUFHZCxHQUFnRTtDQUNoRSxRQUFRLEdBQW1ELE1BQW9IO0VBQzdLLElBQU0sSUFBTyxFQUFRLE1BQ2pCO0VBTUosSUFKQSxFQUFRLGVBQWUsV0FBdUI7R0FDNUMsSUFBZ0IsS0FBSyxjQUFjLEtBQUssSUFBSTtFQUM5QyxDQUFDLEdBRUcsT0FBTyxLQUFTLFVBQ2xCLE1BQVUsTUFBTSxvREFBb0Q7RUFHdEUsSUFBTSxJQUF1QixFQUMzQixPQUFPLEdBQStDLE1BQW9DLENBQUUsRUFDOUY7RUFFQSxPQUFPLEVBQ0wsTUFBb0I7R0FXbEIsT0FWQSxFQUFPLE9BQU8sU0FBdUIsR0FBOEMsR0FBZ0M7SUFDakgsSUFBSSxJQUFzQyxDQUFDO0lBRTNDLElBQWUsRUFBZSxDQUFzQixJQUNoRDtLQUFFLEdBQUc7S0FBUyxHQUFHO0lBQXVCLElBQ3hDO0tBQUUsR0FBRztLQUFTLEdBQUc7S0FBaUIsUUFBUTtJQUF1QjtJQUVyRSxJQUFNLElBQVEsSUFBSSxZQUFZLEdBQU0sQ0FBWTtJQUNoRCxFQUFjLENBQUs7R0FDckIsR0FDTztFQUNULEVBQ0Y7Q0FDRjtBQUNGOzs7QUM3Q0EsSUFBYSxJQUErQixzQkNLL0Is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
272
+ export { BaseWebComponent, Event, InputSignal, Property, WebComponent };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xaendar/core",
3
- "version": "0.4.5",
3
+ "version": "0.4.9",
4
4
  "description": "A library containing core utils such as webcomponent base classes and theming support",
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -16,7 +16,7 @@
16
16
  }
17
17
  },
18
18
  "dependencies": {
19
- "@xaendar/signals": "0.4.5",
20
- "@xaendar/types": "0.4.5"
19
+ "@xaendar/signals": "0.4.9",
20
+ "@xaendar/types": "0.4.9"
21
21
  }
22
22
  }