ag-studio-angular 1.1.1 → 2.0.1

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.
@@ -1,350 +0,0 @@
1
- /* eslint-disable no-duplicate-imports */
2
- // False positive lint error, ElementRef and co can't be type imports
3
- // eslint-disable-next-line @typescript-eslint/consistent-type-imports
4
- import { Component, EventEmitter, Input, Output, ViewEncapsulation, booleanAttribute, } from '@angular/core';
5
- import { _BOOLEAN_MIXED_STUDIO_PROPERTIES, _combineAttributesAndStudioProperties, _createStudio, _processPropertyChanges, } from 'ag-studio';
6
- // @END_IMPORTS@
7
- import { AngularFrameworkComponentWrapper } from './angularFrameworkComponentWrapper';
8
- import { AngularFrameworkOverrides } from './angularFrameworkOverrides';
9
- import * as i0 from "@angular/core";
10
- import * as i1 from "./angularFrameworkOverrides";
11
- import * as i2 from "./angularFrameworkComponentWrapper";
12
- export class AgStudio {
13
- constructor(elementDef, _viewContainerRef, _angularFrameworkOverrides, _frameworkCompWrapper) {
14
- this._viewContainerRef = _viewContainerRef;
15
- this._angularFrameworkOverrides = _angularFrameworkOverrides;
16
- this._frameworkCompWrapper = _frameworkCompWrapper;
17
- this._initialised = false;
18
- this._destroyed = false;
19
- // in order to ensure firing of apiReady is deterministic
20
- this._holdEvents = true;
21
- this._fullyReady = new Promise((resolve) => {
22
- this._resolveFullyReady = resolve;
23
- });
24
- // @START@
25
- /** Change this value to set the tabIndex order of Studio within your application.
26
- * @default 0
27
- * @initial
28
- */
29
- this.tabIndex = undefined;
30
- /** Set to `true` to operate Studio in RTL (Right to Left) mode.
31
- * @default false
32
- * @initial
33
- */
34
- this.enableRtl = undefined;
35
- /** DOM element to use as the popup parent for Studio popups (context menus, etc.).
36
- */
37
- this.popupParent = undefined;
38
- /** Theme to apply to Studio.
39
- *
40
- * @default studioTheme
41
- */
42
- this.theme = undefined;
43
- /** If your theme uses a font that is available on Google Fonts, pass true to load it from Google's CDN.
44
- */
45
- this.loadThemeGoogleFonts = undefined;
46
- /** The CSS layer that this theme should be rendered onto. When specified,
47
- * Studio CSS will be wrapped in a `@layer ${themeCssLayer} { ... }` block.
48
- *
49
- * NOTE: when specifying `themeCssLayer` we recommend setting
50
- * `themeStyleContainer` to `document.body` to ensure that Studio CSS
51
- * comes after your application CSS, allowing your application to set the
52
- * order of layers.
53
- *
54
- * @see https://developer.mozilla.org/en-US/docs/Web/CSS/@layer
55
- */
56
- this.themeCssLayer = undefined;
57
- /** The nonce attribute to set on style elements added to the document by
58
- * themes. If "foo" is passed to this property, Studio can use the Content
59
- * Security Policy `style-src 'nonce-foo'`, instead of the less secure
60
- * `style-src 'unsafe-inline'`.
61
- *
62
- * Note: CSP nonces are global to a page, where a page has multiple Studio components,
63
- * every one must have the same styleNonce set.
64
- */
65
- this.styleNonce = undefined;
66
- /** An element to insert style elements into when injecting styles into the
67
- * Studio. Styles are inserted at the start of the element.
68
- *
69
- * If undefined, styles will be added to the document head for Studio components
70
- * rendered in the main document fragment, or to Studio wrapper element
71
- * for other Studio components (e.g. those rendered in a shadow DOM or detached from the
72
- * document).
73
- *
74
- * @initial
75
- */
76
- this.themeStyleContainer = undefined;
77
- /** Allows overriding what `document` is used.
78
- * Use this when you want Studio to use a different `document` than the one available on the global scope.
79
- * This can happen if docking out components (something which Electron supports).
80
- */
81
- this.getDocument = undefined;
82
- /** Disables touch support (but does not remove the browser's efforts to simulate mouse events on touch).
83
- * @default false
84
- * @initial
85
- */
86
- this.suppressTouch = undefined;
87
- /** A map of key->value pairs for localising text within Studio.
88
- * @initial
89
- */
90
- this.localeText = undefined;
91
- /** A callback for localising text within Studio.
92
- * @initial
93
- */
94
- this.getLocaleText = undefined;
95
- /** Provide a custom `studioId` for this instance of Studio. Value will be set on the root DOM node using the attribute `studio-id` as well as being accessible via the `api.getStudioId()` method.
96
- * @initial
97
- */
98
- this.studioId = undefined;
99
- /** Provides a context object that is provided to different callbacks Studio uses. Used for passing additional information to the callbacks used by your application.
100
- * @initial
101
- */
102
- this.context = undefined;
103
- /** Initial state for Studio. Only read once on initialization. Can be used in conjunction with `api.getState()` to save and restore Studio state.
104
- * @initial
105
- */
106
- this.initialState = undefined;
107
- /** Defines the data sources used by Studio.
108
- *
109
- * If updated after initially being set, only changes to synchronous data will be processed.
110
- * Any other changes will be ignored (e.g. adding/removing data sources, updating fields, etc.)
111
- */
112
- this.data = undefined;
113
- /** Which mode Studio is in.
114
- * @default 'view'
115
- */
116
- this.mode = undefined;
117
- /** Default layout styling.
118
- */
119
- this.layout = undefined;
120
- /** AI Assistant configuration.
121
- *
122
- * NOTE: The **AI Assistant** is an experimental feature. Behaviour will be
123
- * slightly different depending on the LLM being used, and results can vary across queries.
124
- *
125
- * @initial
126
- */
127
- this.ai = undefined;
128
- /** Data-layer configuration. Controls behaviours such as export row limits.
129
- */
130
- this.dataOptions = undefined;
131
- /** @deprecated v1.1 Use `widgets` to customise the widget configurations and available widgets,
132
- * and `page` to customise the page setup form.
133
- *
134
- * Overrides for the layout and widget configs.
135
- */
136
- this.overrides = undefined;
137
- /** Configure which panels are displayed and on which side.
138
- */
139
- this.panels = undefined;
140
- /** Configure page (e.g. page setup form in page tab of edit panel).
141
- */
142
- this.page = undefined;
143
- this.widgets = undefined;
144
- /** Custom components (e.g. custom widget components) keyed by ID.
145
- * Used to share components which can then be referenced directly by key in the definitions.
146
- */
147
- this.components = undefined;
148
- /** State has been updated.
149
- */
150
- this.stateUpdated = new EventEmitter();
151
- /** The API has been initialised and is ready for most calls. The data engine has not been initialised yet, and the UI is not ready.
152
- */
153
- this.apiReady = new EventEmitter();
154
- /** The data engine has been initialised, and the UI has been created, but may not be fully rendered yet.
155
- */
156
- this.studioReady = new EventEmitter();
157
- /** An error has occurred within Studio.
158
- */
159
- this.errorRaised = new EventEmitter();
160
- this._nativeElement = elementDef.nativeElement;
161
- // NOSONAR
162
- this._fullyReady.then(() => {
163
- // Register the status flag reset before any events are fired
164
- // so that we can swap to synchronous event firing as soon as the studio is ready
165
- this._holdEvents = false;
166
- });
167
- }
168
- ngAfterViewInit() {
169
- // Run the setup outside of angular so all the event handlers that are created do not trigger change detection
170
- this._angularFrameworkOverrides.runOutsideAngular(() => {
171
- this._frameworkCompWrapper.setViewContainerRef(this._viewContainerRef, this._angularFrameworkOverrides);
172
- // Get all the inputs that are valid AgStudioProperties
173
- const studioPropertiesKeys = Object.keys(this).filter((key) => !(key.startsWith('_') ||
174
- key == 'studioProperties' ||
175
- key == 'modules' ||
176
- this[key] instanceof EventEmitter));
177
- const coercedStudioProperties = {};
178
- for (const key of studioPropertiesKeys) {
179
- const valueToUse = getValueOrCoercedValue(key, this[key]);
180
- coercedStudioProperties[key] = valueToUse;
181
- }
182
- const mergedStudioProperties = _combineAttributesAndStudioProperties(this.studioProperties, coercedStudioProperties, studioPropertiesKeys);
183
- const studioParams = {
184
- globalListener: this.globalListener.bind(this),
185
- frameworkOverrides: this._angularFrameworkOverrides,
186
- setThemeOnRootDiv: true,
187
- modules: this.modules,
188
- providedBeanInstances: {
189
- frameworkCompWrapper: this._frameworkCompWrapper,
190
- },
191
- };
192
- const api = _createStudio(this._nativeElement, mergedStudioProperties, studioParams);
193
- if (api) {
194
- this.api = api;
195
- }
196
- this._initialised = true;
197
- // sometimes, especially in large client apps apiReady can fire before ngAfterViewInit
198
- // this ties these together so that apiReady will always fire after agStudio's ngAfterViewInit
199
- // the actual containing component's ngAfterViewInit will fire just after agStudio's
200
- this._resolveFullyReady();
201
- });
202
- }
203
- ngOnChanges(changes) {
204
- if (this._initialised) {
205
- // Run the changes outside of angular so any event handlers that are created do not trigger change detection
206
- this._angularFrameworkOverrides.runOutsideAngular(() => {
207
- const studioProperties = {};
208
- for (const key of Object.keys(changes)) {
209
- const value = changes[key];
210
- studioProperties[key] = value.currentValue;
211
- }
212
- _processPropertyChanges(studioProperties, this.api);
213
- });
214
- }
215
- }
216
- ngOnDestroy() {
217
- if (this._initialised) {
218
- // need to do this before the destroy, so we know not to emit any events
219
- // while tearing down the studio.
220
- this._destroyed = true;
221
- // could be null if studio failed to initialise
222
- this.api?.destroy();
223
- }
224
- }
225
- // we'll emit the emit if a user is listening for a given event either on the component via normal angular binding
226
- // or via studioProperties
227
- isEmitterUsed(eventType) {
228
- const emitter = this[eventType];
229
- // For RxJs compatibility we need to check for observed v7+ or observers v6
230
- const emitterAny = emitter;
231
- const hasEmitter = emitterAny?.observed ?? emitterAny?.observers?.length > 0;
232
- // apiReady => onApiReady
233
- const asEventName = `on${eventType.charAt(0).toUpperCase()}${eventType.substring(1)}`;
234
- const hasStudioPropertyListener = !!this.studioProperties && !!this.studioProperties[asEventName];
235
- return hasEmitter || hasStudioPropertyListener;
236
- }
237
- globalListener(eventType, event) {
238
- // if we are tearing down, don't emit angular events, as this causes
239
- // problems with the angular router
240
- if (this._destroyed) {
241
- return;
242
- }
243
- // generically look up the eventType
244
- const emitter = this[eventType];
245
- if (emitter && this.isEmitterUsed(eventType)) {
246
- // Make sure we emit within the angular zone, so change detection works properly
247
- const fireEmitter = () => this._angularFrameworkOverrides.runInsideAngular(() => emitter.emit(event));
248
- if (this._holdEvents) {
249
- // if the user is listening to events, wait for ngAfterViewInit to fire first, then emit the studio events
250
- this._fullyReady.then(() => fireEmitter());
251
- }
252
- else {
253
- fireEmitter();
254
- }
255
- }
256
- }
257
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AgStudio, deps: [{ token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i1.AngularFrameworkOverrides }, { token: i2.AngularFrameworkComponentWrapper }], target: i0.ɵɵFactoryTarget.Component }); }
258
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "18.2.14", type: AgStudio, isStandalone: true, selector: "ag-studio", inputs: { studioProperties: "studioProperties", modules: "modules", tabIndex: "tabIndex", enableRtl: ["enableRtl", "enableRtl", booleanAttribute], popupParent: "popupParent", theme: "theme", loadThemeGoogleFonts: ["loadThemeGoogleFonts", "loadThemeGoogleFonts", booleanAttribute], themeCssLayer: "themeCssLayer", styleNonce: "styleNonce", themeStyleContainer: "themeStyleContainer", getDocument: "getDocument", suppressTouch: ["suppressTouch", "suppressTouch", booleanAttribute], localeText: "localeText", getLocaleText: "getLocaleText", studioId: "studioId", context: "context", initialState: "initialState", data: "data", mode: "mode", layout: "layout", ai: "ai", dataOptions: "dataOptions", overrides: "overrides", panels: "panels", page: "page", widgets: "widgets", components: "components" }, outputs: { stateUpdated: "stateUpdated", apiReady: "apiReady", studioReady: "studioReady", errorRaised: "errorRaised" }, providers: [AngularFrameworkOverrides, AngularFrameworkComponentWrapper], usesOnChanges: true, ngImport: i0, template: '', isInline: true, encapsulation: i0.ViewEncapsulation.None }); }
259
- }
260
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AgStudio, decorators: [{
261
- type: Component,
262
- args: [{
263
- selector: 'ag-studio',
264
- standalone: true,
265
- template: '',
266
- providers: [AngularFrameworkOverrides, AngularFrameworkComponentWrapper],
267
- // tell angular we don't want view encapsulation, we don't want a shadow root
268
- encapsulation: ViewEncapsulation.None,
269
- }]
270
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i1.AngularFrameworkOverrides }, { type: i2.AngularFrameworkComponentWrapper }], propDecorators: { studioProperties: [{
271
- type: Input
272
- }], modules: [{
273
- type: Input
274
- }], tabIndex: [{
275
- type: Input
276
- }], enableRtl: [{
277
- type: Input,
278
- args: [{ transform: booleanAttribute }]
279
- }], popupParent: [{
280
- type: Input
281
- }], theme: [{
282
- type: Input
283
- }], loadThemeGoogleFonts: [{
284
- type: Input,
285
- args: [{ transform: booleanAttribute }]
286
- }], themeCssLayer: [{
287
- type: Input
288
- }], styleNonce: [{
289
- type: Input
290
- }], themeStyleContainer: [{
291
- type: Input
292
- }], getDocument: [{
293
- type: Input
294
- }], suppressTouch: [{
295
- type: Input,
296
- args: [{ transform: booleanAttribute }]
297
- }], localeText: [{
298
- type: Input
299
- }], getLocaleText: [{
300
- type: Input
301
- }], studioId: [{
302
- type: Input
303
- }], context: [{
304
- type: Input
305
- }], initialState: [{
306
- type: Input
307
- }], data: [{
308
- type: Input
309
- }], mode: [{
310
- type: Input
311
- }], layout: [{
312
- type: Input
313
- }], ai: [{
314
- type: Input
315
- }], dataOptions: [{
316
- type: Input
317
- }], overrides: [{
318
- type: Input
319
- }], panels: [{
320
- type: Input
321
- }], page: [{
322
- type: Input
323
- }], widgets: [{
324
- type: Input
325
- }], components: [{
326
- type: Input
327
- }], stateUpdated: [{
328
- type: Output
329
- }], apiReady: [{
330
- type: Output
331
- }], studioReady: [{
332
- type: Output
333
- }], errorRaised: [{
334
- type: Output
335
- }] } });
336
- const booleanMixedStudioProperties = new Set(_BOOLEAN_MIXED_STUDIO_PROPERTIES);
337
- /**
338
- * Used to support the user setting combined boolean and string / object properties
339
- * as plain HTML attributes and us correctly mapping that to true.
340
- * For example cellSection can be boolean or an object
341
- */
342
- function getValueOrCoercedValue(key, valueToUse) {
343
- if (booleanMixedStudioProperties.has(key)) {
344
- // Handle plain HTML boolean attributes and convert them to boolean values
345
- // Also handle the false string case to match Angular boolean attributes
346
- return valueToUse === '' ? true : valueToUse === 'false' ? false : valueToUse;
347
- }
348
- return valueToUse;
349
- }
350
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWctc3R1ZGlvLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2FnLXN0dWRpby1hbmd1bGFyL3NyYy9saWIvYWctc3R1ZGlvLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5Q0FBeUM7QUFDekMscUVBQXFFO0FBQ3JFLHNFQUFzRTtBQUN0RSxPQUFPLEVBRUgsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUVOLGlCQUFpQixFQUNqQixnQkFBZ0IsR0FDbkIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUNILGdDQUFnQyxFQUNoQyxxQ0FBcUMsRUFDckMsYUFBYSxFQUNiLHVCQUF1QixHQUMxQixNQUFNLFdBQVcsQ0FBQztBQXVCbkIsZ0JBQWdCO0FBRWhCLE9BQU8sRUFBRSxnQ0FBZ0MsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3RGLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDOzs7O0FBV3hFLE1BQU0sT0FBTyxRQUFRO0lBaUJqQixZQUNJLFVBQXNCLEVBQ0wsaUJBQW1DLEVBQ25DLDBCQUFxRCxFQUNyRCxxQkFBdUQ7UUFGdkQsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFrQjtRQUNuQywrQkFBMEIsR0FBMUIsMEJBQTBCLENBQTJCO1FBQ3JELDBCQUFxQixHQUFyQixxQkFBcUIsQ0FBa0M7UUFqQnBFLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFFM0IseURBQXlEO1FBQ2pELGdCQUFXLEdBQUcsSUFBSSxDQUFDO1FBRVYsZ0JBQVcsR0FBa0IsSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNsRSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsT0FBTyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDO1FBNElILFVBQVU7UUFDVjs7O1dBR0c7UUFDYSxhQUFR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TSw0QkFBNEIsR0FBRyxJQUFJLEdBQUcsQ0FBUyxnQ0FBZ0MsQ0FBQyxDQUFDO0FBQ3ZGOzs7O0dBSUc7QUFDSCxTQUFTLHNCQUFzQixDQUFDLEdBQVcsRUFBRSxVQUFlO0lBQ3hELElBQUksNEJBQTRCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDeEMsMEVBQTBFO1FBQzFFLHdFQUF3RTtRQUN4RSxPQUFPLFVBQVUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7SUFDbEYsQ0FBQztJQUNELE9BQU8sVUFBVSxDQUFDO0FBQ3RCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby1kdXBsaWNhdGUtaW1wb3J0cyAqL1xuLy8gRmFsc2UgcG9zaXRpdmUgbGludCBlcnJvciwgRWxlbWVudFJlZiBhbmQgY28gY2FuJ3QgYmUgdHlwZSBpbXBvcnRzXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2NvbnNpc3RlbnQtdHlwZS1pbXBvcnRzXG5pbXBvcnQge1xuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIElucHV0LFxuICAgIE9uQ2hhbmdlcyxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT3V0cHV0LFxuICAgIFZpZXdDb250YWluZXJSZWYsXG4gICAgVmlld0VuY2Fwc3VsYXRpb24sXG4gICAgYm9vbGVhbkF0dHJpYnV0ZSxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgdHlwZSB7IEFnRGVmYXVsdFJlZ2lzdHJ5LCBBZ1N0dWRpb0FwaSwgQWdTdHVkaW9Nb2R1bGUsIEFnU3R1ZGlvUHJvcGVydGllcywgX1N0dWRpb1BhcmFtcyB9IGZyb20gJ2FnLXN0dWRpbyc7XG5pbXBvcnQge1xuICAgIF9CT09MRUFOX01JWEVEX1NUVURJT19QUk9QRVJUSUVTLFxuICAgIF9jb21iaW5lQXR0cmlidXRlc0FuZFN0dWRpb1Byb3BlcnRpZXMsXG4gICAgX2NyZWF0ZVN0dWRpbyxcbiAgICBfcHJvY2Vzc1Byb3BlcnR5Q2hhbmdlcyxcbn0gZnJvbSAnYWctc3R1ZGlvJztcbi8vIEBTVEFSVF9JTVBPUlRTQFxuaW1wb3J0IHR5cGUge1xuICAgIEFnQWlBc3Npc3RhbnQsXG4gICAgQWdEYXRhRW5naW5lLFxuICAgIEFnRGF0YU9wdGlvbnMsXG4gICAgQWdEYXRhU291cmNlc0RlZmluaXRpb24sXG4gICAgQWdQYWdlQ29uZmlnLFxuICAgIEFnUGFnZUxheW91dFN0YXRlLFxuICAgIEFnUGFuZWxDb25maWcsXG4gICAgQWdSZXBvcnRTdGF0ZSxcbiAgICBBZ1N0dWRpb0FwaVJlYWR5RXZlbnQsXG4gICAgQWdTdHVkaW9FcnJvclJhaXNlZEV2ZW50LFxuICAgIEFnU3R1ZGlvR2V0TG9jYWxlVGV4dFBhcmFtcyxcbiAgICBBZ1N0dWRpb0xvY2FsZVRleHQsXG4gICAgQWdTdHVkaW9Nb2RlLFxuICAgIEFnU3R1ZGlvT3ZlcnJpZGVzLFxuICAgIEFnU3R1ZGlvUmVhZHlFdmVudCxcbiAgICBBZ1N0dWRpb1N0YXRlVXBkYXRlZEV2ZW50LFxuICAgIEFnU3R1ZGlvVGhlbWUsXG4gICAgQWdXaWRnZXRzQ29uZmlnLFxufSBmcm9tICdhZy1zdHVkaW8nO1xuXG4vLyBARU5EX0lNUE9SVFNAXG5cbmltcG9ydCB7IEFuZ3VsYXJGcmFtZXdvcmtDb21wb25lbnRXcmFwcGVyIH0gZnJvbSAnLi9hbmd1bGFyRnJhbWV3b3JrQ29tcG9uZW50V3JhcHBlcic7XG5pbXBvcnQgeyBBbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzIH0gZnJvbSAnLi9hbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzJztcbmltcG9ydCB0eXBlIHsgQWdSZWdpc3RyeSB9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnYWctc3R1ZGlvJyxcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIHRlbXBsYXRlOiAnJyxcbiAgICBwcm92aWRlcnM6IFtBbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzLCBBbmd1bGFyRnJhbWV3b3JrQ29tcG9uZW50V3JhcHBlcl0sXG4gICAgLy8gdGVsbCBhbmd1bGFyIHdlIGRvbid0IHdhbnQgdmlldyBlbmNhcHN1bGF0aW9uLCB3ZSBkb24ndCB3YW50IGEgc2hhZG93IHJvb3RcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxufSlcbmV4cG9ydCBjbGFzcyBBZ1N0dWRpbzxUUmVnaXN0cnkgZXh0ZW5kcyBBZ1JlZ2lzdHJ5ID0gQWdEZWZhdWx0UmVnaXN0cnk+IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICAgIC8vIG5vdCBpbnRlbmRlZCBmb3IgdXNlciB0byBpbnRlcmFjdCB3aXRoLiBzbyBwdXR0aW5nIF8gaW4gc28gaWYgdXNlciBnZXRzIHJlZmVyZW5jZVxuICAgIC8vIHRvIHRoaXMgb2JqZWN0LCB0aGV5IGtpbmQnYSBrbm93IGl0J3Mgbm90IHBhcnQgb2YgdGhlIGFncmVlZCBpbnRlcmZhY2VcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9uYXRpdmVFbGVtZW50OiBhbnk7XG4gICAgcHJpdmF0ZSBfaW5pdGlhbGlzZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIF9kZXN0cm95ZWQgPSBmYWxzZTtcblxuICAgIC8vIGluIG9yZGVyIHRvIGVuc3VyZSBmaXJpbmcgb2YgYXBpUmVhZHkgaXMgZGV0ZXJtaW5pc3RpY1xuICAgIHByaXZhdGUgX2hvbGRFdmVudHMgPSB0cnVlO1xuICAgIHByaXZhdGUgX3Jlc29sdmVGdWxseVJlYWR5OiAoKSA9PiB2b2lkO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX2Z1bGx5UmVhZHk6IFByb21pc2U8dm9pZD4gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICB0aGlzLl9yZXNvbHZlRnVsbHlSZWFkeSA9IHJlc29sdmU7XG4gICAgfSk7XG5cbiAgICAvKiogU3R1ZGlvIEFwaSBhdmFpbGFibGUgYWZ0ZXIgb25BcGlSZWFkeSBldmVudCBoYXMgZmlyZWQuICovXG4gICAgYXBpOiBBZ1N0dWRpb0FwaTxUUmVnaXN0cnk+O1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIGVsZW1lbnREZWY6IEVsZW1lbnRSZWYsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgX3ZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgX2FuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXM6IEFuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgX2ZyYW1ld29ya0NvbXBXcmFwcGVyOiBBbmd1bGFyRnJhbWV3b3JrQ29tcG9uZW50V3JhcHBlclxuICAgICkge1xuICAgICAgICB0aGlzLl9uYXRpdmVFbGVtZW50ID0gZWxlbWVudERlZi5uYXRpdmVFbGVtZW50O1xuICAgICAgICAvLyBOT1NPTkFSXG4gICAgICAgIHRoaXMuX2Z1bGx5UmVhZHkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAvLyBSZWdpc3RlciB0aGUgc3RhdHVzIGZsYWcgcmVzZXQgYmVmb3JlIGFueSBldmVudHMgYXJlIGZpcmVkXG4gICAgICAgICAgICAvLyBzbyB0aGF0IHdlIGNhbiBzd2FwIHRvIHN5bmNocm9ub3VzIGV2ZW50IGZpcmluZyBhcyBzb29uIGFzIHRoZSBzdHVkaW8gaXMgcmVhZHlcbiAgICAgICAgICAgIHRoaXMuX2hvbGRFdmVudHMgPSBmYWxzZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgICAvLyBSdW4gdGhlIHNldHVwIG91dHNpZGUgb2YgYW5ndWxhciBzbyBhbGwgdGhlIGV2ZW50IGhhbmRsZXJzIHRoYXQgYXJlIGNyZWF0ZWQgZG8gbm90IHRyaWdnZXIgY2hhbmdlIGRldGVjdGlvblxuICAgICAgICB0aGlzLl9hbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1ld29ya0NvbXBXcmFwcGVyLnNldFZpZXdDb250YWluZXJSZWYodGhpcy5fdmlld0NvbnRhaW5lclJlZiwgdGhpcy5fYW5ndWxhckZyYW1ld29ya092ZXJyaWRlcyk7XG5cbiAgICAgICAgICAgIC8vIEdldCBhbGwgdGhlIGlucHV0cyB0aGF0IGFyZSB2YWxpZCBBZ1N0dWRpb1Byb3BlcnRpZXNcbiAgICAgICAgICAgIGNvbnN0IHN0dWRpb1Byb3BlcnRpZXNLZXlzID0gT2JqZWN0LmtleXModGhpcykuZmlsdGVyKFxuICAgICAgICAgICAgICAgIChrZXkpID0+XG4gICAgICAgICAgICAgICAgICAgICEoXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkuc3RhcnRzV2l0aCgnXycpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPT0gJ3N0dWRpb1Byb3BlcnRpZXMnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPT0gJ21vZHVsZXMnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2tleSBhcyBrZXlvZiBBZ1N0dWRpb10gaW5zdGFuY2VvZiBFdmVudEVtaXR0ZXJcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgY29uc3QgY29lcmNlZFN0dWRpb1Byb3BlcnRpZXMgPSB7fSBhcyBBZ1N0dWRpb1Byb3BlcnRpZXM8VFJlZ2lzdHJ5PjtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHN0dWRpb1Byb3BlcnRpZXNLZXlzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWVUb1VzZSA9IGdldFZhbHVlT3JDb2VyY2VkVmFsdWUoa2V5LCB0aGlzW2tleSBhcyBrZXlvZiBBZ1N0dWRpb10pO1xuICAgICAgICAgICAgICAgIGNvZXJjZWRTdHVkaW9Qcm9wZXJ0aWVzW2tleSBhcyBrZXlvZiBBZ1N0dWRpb1Byb3BlcnRpZXNdID0gdmFsdWVUb1VzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbWVyZ2VkU3R1ZGlvUHJvcGVydGllcyA9IF9jb21iaW5lQXR0cmlidXRlc0FuZFN0dWRpb1Byb3BlcnRpZXMoXG4gICAgICAgICAgICAgICAgdGhpcy5zdHVkaW9Qcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAgIGNvZXJjZWRTdHVkaW9Qcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAgIHN0dWRpb1Byb3BlcnRpZXNLZXlzXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBzdHVkaW9QYXJhbXM6IF9TdHVkaW9QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgZ2xvYmFsTGlzdGVuZXI6IHRoaXMuZ2xvYmFsTGlzdGVuZXIuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBmcmFtZXdvcmtPdmVycmlkZXM6IHRoaXMuX2FuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMsXG4gICAgICAgICAgICAgICAgc2V0VGhlbWVPblJvb3REaXY6IHRydWUsXG4gICAgICAgICAgICAgICAgbW9kdWxlczogdGhpcy5tb2R1bGVzLFxuICAgICAgICAgICAgICAgIHByb3ZpZGVkQmVhbkluc3RhbmNlczoge1xuICAgICAgICAgICAgICAgICAgICBmcmFtZXdvcmtDb21wV3JhcHBlcjogdGhpcy5fZnJhbWV3b3JrQ29tcFdyYXBwZXIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGFwaSA9IF9jcmVhdGVTdHVkaW8odGhpcy5fbmF0aXZlRWxlbWVudCwgbWVyZ2VkU3R1ZGlvUHJvcGVydGllcywgc3R1ZGlvUGFyYW1zKTtcbiAgICAgICAgICAgIGlmIChhcGkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFwaSA9IGFwaTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5faW5pdGlhbGlzZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICAvLyBzb21ldGltZXMsIGVzcGVjaWFsbHkgaW4gbGFyZ2UgY2xpZW50IGFwcHMgYXBpUmVhZHkgY2FuIGZpcmUgYmVmb3JlIG5nQWZ0ZXJWaWV3SW5pdFxuICAgICAgICAgICAgLy8gdGhpcyB0aWVzIHRoZXNlIHRvZ2V0aGVyIHNvIHRoYXQgYXBpUmVhZHkgd2lsbCBhbHdheXMgZmlyZSBhZnRlciBhZ1N0dWRpbydzIG5nQWZ0ZXJWaWV3SW5pdFxuICAgICAgICAgICAgLy8gdGhlIGFjdHVhbCBjb250YWluaW5nIGNvbXBvbmVudCdzIG5nQWZ0ZXJWaWV3SW5pdCB3aWxsIGZpcmUganVzdCBhZnRlciBhZ1N0dWRpbydzXG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlRnVsbHlSZWFkeSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogYW55KTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLl9pbml0aWFsaXNlZCkge1xuICAgICAgICAgICAgLy8gUnVuIHRoZSBjaGFuZ2VzIG91dHNpZGUgb2YgYW5ndWxhciBzbyBhbnkgZXZlbnQgaGFuZGxlcnMgdGhhdCBhcmUgY3JlYXRlZCBkbyBub3QgdHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uXG4gICAgICAgICAgICB0aGlzLl9hbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHVkaW9Qcm9wZXJ0aWVzOiBBZ1N0dWRpb1Byb3BlcnRpZXM8VFJlZ2lzdHJ5PiA9IHt9O1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNoYW5nZXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gY2hhbmdlc1trZXldO1xuICAgICAgICAgICAgICAgICAgICBzdHVkaW9Qcm9wZXJ0aWVzW2tleSBhcyBrZXlvZiBBZ1N0dWRpb1Byb3BlcnRpZXNdID0gdmFsdWUuY3VycmVudFZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBfcHJvY2Vzc1Byb3BlcnR5Q2hhbmdlcyhzdHVkaW9Qcm9wZXJ0aWVzLCB0aGlzLmFwaSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX2luaXRpYWxpc2VkKSB7XG4gICAgICAgICAgICAvLyBuZWVkIHRvIGRvIHRoaXMgYmVmb3JlIHRoZSBkZXN0cm95LCBzbyB3ZSBrbm93IG5vdCB0byBlbWl0IGFueSBldmVudHNcbiAgICAgICAgICAgIC8vIHdoaWxlIHRlYXJpbmcgZG93biB0aGUgc3R1ZGlvLlxuICAgICAgICAgICAgdGhpcy5fZGVzdHJveWVkID0gdHJ1ZTtcbiAgICAgICAgICAgIC8vIGNvdWxkIGJlIG51bGwgaWYgc3R1ZGlvIGZhaWxlZCB0byBpbml0aWFsaXNlXG4gICAgICAgICAgICB0aGlzLmFwaT8uZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gd2UnbGwgZW1pdCB0aGUgZW1pdCBpZiBhIHVzZXIgaXMgbGlzdGVuaW5nIGZvciBhIGdpdmVuIGV2ZW50IGVpdGhlciBvbiB0aGUgY29tcG9uZW50IHZpYSBub3JtYWwgYW5ndWxhciBiaW5kaW5nXG4gICAgLy8gb3IgdmlhIHN0dWRpb1Byb3BlcnRpZXNcbiAgICBwcm90ZWN0ZWQgaXNFbWl0dGVyVXNlZChldmVudFR5cGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBlbWl0dGVyID0gPEV2ZW50RW1pdHRlcjxhbnk+Pig8YW55PnRoaXMpW2V2ZW50VHlwZV07XG4gICAgICAgIC8vIEZvciBSeEpzIGNvbXBhdGliaWxpdHkgd2UgbmVlZCB0byBjaGVjayBmb3Igb2JzZXJ2ZWQgdjcrIG9yIG9ic2VydmVycyB2NlxuICAgICAgICBjb25zdCBlbWl0dGVyQW55ID0gZW1pdHRlciBhcyBhbnk7XG4gICAgICAgIGNvbnN0IGhhc0VtaXR0ZXIgPSBlbWl0dGVyQW55Py5vYnNlcnZlZCA/PyBlbWl0dGVyQW55Py5vYnNlcnZlcnM/Lmxlbmd0aCA+IDA7XG5cbiAgICAgICAgLy8gYXBpUmVhZHkgPT4gb25BcGlSZWFkeVxuICAgICAgICBjb25zdCBhc0V2ZW50TmFtZSA9IGBvbiR7ZXZlbnRUeXBlLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpfSR7ZXZlbnRUeXBlLnN1YnN0cmluZygxKX1gO1xuICAgICAgICBjb25zdCBoYXNTdHVkaW9Qcm9wZXJ0eUxpc3RlbmVyID0gISF0aGlzLnN0dWRpb1Byb3BlcnRpZXMgJiYgISEodGhpcy5zdHVkaW9Qcm9wZXJ0aWVzIGFzIGFueSlbYXNFdmVudE5hbWVdO1xuXG4gICAgICAgIHJldHVybiBoYXNFbWl0dGVyIHx8IGhhc1N0dWRpb1Byb3BlcnR5TGlzdGVuZXI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnbG9iYWxMaXN0ZW5lcihldmVudFR5cGU6IHN0cmluZywgZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgICAgICAvLyBpZiB3ZSBhcmUgdGVhcmluZyBkb3duLCBkb24ndCBlbWl0IGFuZ3VsYXIgZXZlbnRzLCBhcyB0aGlzIGNhdXNlc1xuICAgICAgICAvLyBwcm9ibGVtcyB3aXRoIHRoZSBhbmd1bGFyIHJvdXRlclxuICAgICAgICBpZiAodGhpcy5fZGVzdHJveWVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBnZW5lcmljYWxseSBsb29rIHVwIHRoZSBldmVudFR5cGVcbiAgICAgICAgY29uc3QgZW1pdHRlciA9IDxFdmVudEVtaXR0ZXI8YW55Pj4oPGFueT50aGlzKVtldmVudFR5cGVdO1xuICAgICAgICBpZiAoZW1pdHRlciAmJiB0aGlzLmlzRW1pdHRlclVzZWQoZXZlbnRUeXBlKSkge1xuICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHdlIGVtaXQgd2l0aGluIHRoZSBhbmd1bGFyIHpvbmUsIHNvIGNoYW5nZSBkZXRlY3Rpb24gd29ya3MgcHJvcGVybHlcbiAgICAgICAgICAgIGNvbnN0IGZpcmVFbWl0dGVyID0gKCkgPT4gdGhpcy5fYW5ndWxhckZyYW1ld29ya092ZXJyaWRlcy5ydW5JbnNpZGVBbmd1bGFyKCgpID0+IGVtaXR0ZXIuZW1pdChldmVudCkpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5faG9sZEV2ZW50cykge1xuICAgICAgICAgICAgICAgIC8vIGlmIHRoZSB1c2VyIGlzIGxpc3RlbmluZyB0byBldmVudHMsIHdhaXQgZm9yIG5nQWZ0ZXJWaWV3SW5pdCB0byBmaXJlIGZpcnN0LCB0aGVuIGVtaXQgdGhlIHN0dWRpbyBldmVudHNcbiAgICAgICAgICAgICAgICB0aGlzLl9mdWxseVJlYWR5LnRoZW4oKCkgPT4gZmlyZUVtaXR0ZXIoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZpcmVFbWl0dGVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogUHJvdmlkZWQgYW4gaW5pdGlhbCBzdHVkaW9Qcm9wZXJ0aWVzIGNvbmZpZ3VyYXRpb24gdG8gdGhlIGNvbXBvbmVudC4gSWYgYSBwcm9wZXJ0eSBpcyBzcGVjaWZpZWQgaW4gYm90aCBzdHVkaW9Qcm9wZXJ0aWVzIGFuZCB2aWEgY29tcG9uZW50IGJpbmRpbmcgdGhlIGNvbXBvbmVudCBiaW5kaW5nIHRha2VzIHByZWNlZGVuY2UuICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzdHVkaW9Qcm9wZXJ0aWVzOiBBZ1N0dWRpb1Byb3BlcnRpZXM8VFJlZ2lzdHJ5PiB8IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBVc2VkIHRvIHJlZ2lzdGVyIEFHIFN0dWRpbyBNb2R1bGVzIGRpcmVjdGx5IHdpdGggdGhpcyBpbnN0YW5jZSBvZiBTdHVkaW8uXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIG1vZHVsZXM6IEFnU3R1ZGlvTW9kdWxlW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvLyBAU1RBUlRAXG4gICAgLyoqIENoYW5nZSB0aGlzIHZhbHVlIHRvIHNldCB0aGUgdGFiSW5kZXggb3JkZXIgb2YgU3R1ZGlvIHdpdGhpbiB5b3VyIGFwcGxpY2F0aW9uLlxuICAgICAqIEBkZWZhdWx0IDBcbiAgICAgKiBAaW5pdGlhbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyB0YWJJbmRleDogbnVtYmVyIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBTZXQgdG8gYHRydWVgIHRvIG9wZXJhdGUgU3R1ZGlvIGluIFJUTCAoUmlnaHQgdG8gTGVmdCkgbW9kZS5cbiAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAqIEBpbml0aWFsXG4gICAgICovXG4gICAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pIHB1YmxpYyBlbmFibGVSdGw6IGJvb2xlYW4gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIERPTSBlbGVtZW50IHRvIHVzZSBhcyB0aGUgcG9wdXAgcGFyZW50IGZvciBTdHVkaW8gcG9wdXBzIChjb250ZXh0IG1lbnVzLCBldGMuKS5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgcG9wdXBQYXJlbnQ6IEhUTUxFbGVtZW50IHwgbnVsbCB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogVGhlbWUgdG8gYXBwbHkgdG8gU3R1ZGlvLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgc3R1ZGlvVGhlbWVcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgdGhlbWU6IEFnU3R1ZGlvVGhlbWUgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIElmIHlvdXIgdGhlbWUgdXNlcyBhIGZvbnQgdGhhdCBpcyBhdmFpbGFibGUgb24gR29vZ2xlIEZvbnRzLCBwYXNzIHRydWUgdG8gbG9hZCBpdCBmcm9tIEdvb2dsZSdzIENETi5cbiAgICAgKi9cbiAgICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgcHVibGljIGxvYWRUaGVtZUdvb2dsZUZvbnRzOiBib29sZWFuIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBUaGUgQ1NTIGxheWVyIHRoYXQgdGhpcyB0aGVtZSBzaG91bGQgYmUgcmVuZGVyZWQgb250by4gV2hlbiBzcGVjaWZpZWQsXG4gICAgICogU3R1ZGlvIENTUyB3aWxsIGJlIHdyYXBwZWQgaW4gYSBgQGxheWVyICR7dGhlbWVDc3NMYXllcn0geyAuLi4gfWAgYmxvY2suXG4gICAgICpcbiAgICAgKiBOT1RFOiB3aGVuIHNwZWNpZnlpbmcgYHRoZW1lQ3NzTGF5ZXJgIHdlIHJlY29tbWVuZCBzZXR0aW5nXG4gICAgICogYHRoZW1lU3R5bGVDb250YWluZXJgIHRvIGBkb2N1bWVudC5ib2R5YCB0byBlbnN1cmUgdGhhdCBTdHVkaW8gQ1NTXG4gICAgICogY29tZXMgYWZ0ZXIgeW91ciBhcHBsaWNhdGlvbiBDU1MsIGFsbG93aW5nIHlvdXIgYXBwbGljYXRpb24gdG8gc2V0IHRoZVxuICAgICAqIG9yZGVyIG9mIGxheWVycy5cbiAgICAgKlxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL0BsYXllclxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyB0aGVtZUNzc0xheWVyOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIFRoZSBub25jZSBhdHRyaWJ1dGUgdG8gc2V0IG9uIHN0eWxlIGVsZW1lbnRzIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBieVxuICAgICAqIHRoZW1lcy4gSWYgXCJmb29cIiBpcyBwYXNzZWQgdG8gdGhpcyBwcm9wZXJ0eSwgU3R1ZGlvIGNhbiB1c2UgdGhlIENvbnRlbnRcbiAgICAgKiBTZWN1cml0eSBQb2xpY3kgYHN0eWxlLXNyYyAnbm9uY2UtZm9vJ2AsIGluc3RlYWQgb2YgdGhlIGxlc3Mgc2VjdXJlXG4gICAgICogYHN0eWxlLXNyYyAndW5zYWZlLWlubGluZSdgLlxuICAgICAqXG4gICAgICogTm90ZTogQ1NQIG5vbmNlcyBhcmUgZ2xvYmFsIHRvIGEgcGFnZSwgd2hlcmUgYSBwYWdlIGhhcyBtdWx0aXBsZSBTdHVkaW8gY29tcG9uZW50cyxcbiAgICAgKiBldmVyeSBvbmUgbXVzdCBoYXZlIHRoZSBzYW1lIHN0eWxlTm9uY2Ugc2V0LlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzdHlsZU5vbmNlOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEFuIGVsZW1lbnQgdG8gaW5zZXJ0IHN0eWxlIGVsZW1lbnRzIGludG8gd2hlbiBpbmplY3Rpbmcgc3R5bGVzIGludG8gdGhlXG4gICAgICogU3R1ZGlvLiBTdHlsZXMgYXJlIGluc2VydGVkIGF0IHRoZSBzdGFydCBvZiB0aGUgZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIHVuZGVmaW5lZCwgc3R5bGVzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGRvY3VtZW50IGhlYWQgZm9yIFN0dWRpbyBjb21wb25lbnRzXG4gICAgICogcmVuZGVyZWQgaW4gdGhlIG1haW4gZG9jdW1lbnQgZnJhZ21lbnQsIG9yIHRvIFN0dWRpbyB3cmFwcGVyIGVsZW1lbnRcbiAgICAgKiBmb3Igb3RoZXIgU3R1ZGlvIGNvbXBvbmVudHMgKGUuZy4gdGhvc2UgcmVuZGVyZWQgaW4gYSBzaGFkb3cgRE9NIG9yIGRldGFjaGVkIGZyb20gdGhlXG4gICAgICogZG9jdW1lbnQpLlxuICAgICAqXG4gICAgICogQGluaXRpYWxcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgdGhlbWVTdHlsZUNvbnRhaW5lcjogKEhUTUxFbGVtZW50IHwgKCgpID0+IEhUTUxFbGVtZW50IHwgdm9pZCkpIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBBbGxvd3Mgb3ZlcnJpZGluZyB3aGF0IGBkb2N1bWVudGAgaXMgdXNlZC5cbiAgICAgKiBVc2UgdGhpcyB3aGVuIHlvdSB3YW50IFN0dWRpbyB0byB1c2UgYSBkaWZmZXJlbnQgYGRvY3VtZW50YCB0aGFuIHRoZSBvbmUgYXZhaWxhYmxlIG9uIHRoZSBnbG9iYWwgc2NvcGUuXG4gICAgICogVGhpcyBjYW4gaGFwcGVuIGlmIGRvY2tpbmcgb3V0IGNvbXBvbmVudHMgKHNvbWV0aGluZyB3aGljaCBFbGVjdHJvbiBzdXBwb3J0cykuXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGdldERvY3VtZW50OiAoKCkgPT4gRG9jdW1lbnQpIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBEaXNhYmxlcyB0b3VjaCBzdXBwb3J0IChidXQgZG9lcyBub3QgcmVtb3ZlIHRoZSBicm93c2VyJ3MgZWZmb3J0cyB0byBzaW11bGF0ZSBtb3VzZSBldmVudHMgb24gdG91Y2gpLlxuICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICogQGluaXRpYWxcbiAgICAgKi9cbiAgICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgcHVibGljIHN1cHByZXNzVG91Y2g6IGJvb2xlYW4gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEEgbWFwIG9mIGtleS0+dmFsdWUgcGFpcnMgZm9yIGxvY2FsaXNpbmcgdGV4dCB3aXRoaW4gU3R1ZGlvLlxuICAgICAqIEBpbml0aWFsXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGxvY2FsZVRleHQ6IEFnU3R1ZGlvTG9jYWxlVGV4dCB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQSBjYWxsYmFjayBmb3IgbG9jYWxpc2luZyB0ZXh0IHdpdGhpbiBTdHVkaW8uXG4gICAgICogQGluaXRpYWxcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgZ2V0TG9jYWxlVGV4dDogKChwYXJhbXM6IEFnU3R1ZGlvR2V0TG9jYWxlVGV4dFBhcmFtcykgPT4gc3RyaW5nKSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogUHJvdmlkZSBhIGN1c3RvbSBgc3R1ZGlvSWRgIGZvciB0aGlzIGluc3RhbmNlIG9mIFN0dWRpby4gVmFsdWUgd2lsbCBiZSBzZXQgb24gdGhlIHJvb3QgRE9NIG5vZGUgdXNpbmcgdGhlIGF0dHJpYnV0ZSBgc3R1ZGlvLWlkYCBhcyB3ZWxsIGFzIGJlaW5nIGFjY2Vzc2libGUgdmlhIHRoZSBgYXBpLmdldFN0dWRpb0lkKClgIG1ldGhvZC5cbiAgICAgKiBAaW5pdGlhbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzdHVkaW9JZDogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBQcm92aWRlcyBhIGNvbnRleHQgb2JqZWN0IHRoYXQgaXMgcHJvdmlkZWQgdG8gZGlmZmVyZW50IGNhbGxiYWNrcyBTdHVkaW8gdXNlcy4gVXNlZCBmb3IgcGFzc2luZyBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRvIHRoZSBjYWxsYmFja3MgdXNlZCBieSB5b3VyIGFwcGxpY2F0aW9uLlxuICAgICAqIEBpbml0aWFsXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGNvbnRleHQ6IGFueSA9IHVuZGVmaW5lZDtcbiAgICAvKiogSW5pdGlhbCBzdGF0ZSBmb3IgU3R1ZGlvLiBPbmx5IHJlYWQgb25jZSBvbiBpbml0aWFsaXphdGlvbi4gQ2FuIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBgYXBpLmdldFN0YXRlKClgIHRvIHNhdmUgYW5kIHJlc3RvcmUgU3R1ZGlvIHN0YXRlLlxuICAgICAqIEBpbml0aWFsXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGluaXRpYWxTdGF0ZTogQWdSZXBvcnRTdGF0ZTxUUmVnaXN0cnk+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBEZWZpbmVzIHRoZSBkYXRhIHNvdXJjZXMgdXNlZCBieSBTdHVkaW8uXG4gICAgICpcbiAgICAgKiBJZiB1cGRhdGVkIGFmdGVyIGluaXRpYWxseSBiZWluZyBzZXQsIG9ubHkgY2hhbmdlcyB0byBzeW5jaHJvbm91cyBkYXRhIHdpbGwgYmUgcHJvY2Vzc2VkLlxuICAgICAqIEFueSBvdGhlciBjaGFuZ2VzIHdpbGwgYmUgaWdub3JlZCAoZS5nLiBhZGRpbmcvcmVtb3ZpbmcgZGF0YSBzb3VyY2VzLCB1cGRhdGluZyBmaWVsZHMsIGV0Yy4pXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGRhdGE6IEFnRGF0YVNvdXJjZXNEZWZpbml0aW9uIHwgQWdEYXRhRW5naW5lIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBXaGljaCBtb2RlIFN0dWRpbyBpcyBpbi5cbiAgICAgKiBAZGVmYXVsdCAndmlldydcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgbW9kZTogQWdTdHVkaW9Nb2RlIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBEZWZhdWx0IGxheW91dCBzdHlsaW5nLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBsYXlvdXQ6IFBhcnRpYWw8QWdQYWdlTGF5b3V0U3RhdGU+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBBSSBBc3Npc3RhbnQgY29uZmlndXJhdGlvbi5cbiAgICAgKlxuICAgICAqIE5PVEU6IFRoZSAgICAgKipBSSBBc3Npc3RhbnQqKiBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZS4gQmVoYXZpb3VyIHdpbGwgYmVcbiAgICAgKiBzbGlnaHRseSBkaWZmZXJlbnQgZGVwZW5kaW5nIG9uIHRoZSBMTE0gYmVpbmcgdXNlZCwgYW5kIHJlc3VsdHMgY2FuIHZhcnkgYWNyb3NzIHF1ZXJpZXMuXG4gICAgICpcbiAgICAgKiBAaW5pdGlhbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBhaTogQWdBaUFzc2lzdGFudCB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogRGF0YS1sYXllciBjb25maWd1cmF0aW9uLiBDb250cm9scyBiZWhhdmlvdXJzIHN1Y2ggYXMgZXhwb3J0IHJvdyBsaW1pdHMuXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGRhdGFPcHRpb25zOiBBZ0RhdGFPcHRpb25zIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAZGVwcmVjYXRlZCB2MS4xIFVzZSBgd2lkZ2V0c2AgdG8gY3VzdG9taXNlIHRoZSB3aWRnZXQgY29uZmlndXJhdGlvbnMgYW5kIGF2YWlsYWJsZSB3aWRnZXRzLFxuICAgICAqIGFuZCBgcGFnZWAgdG8gY3VzdG9taXNlIHRoZSBwYWdlIHNldHVwIGZvcm0uXG4gICAgICpcbiAgICAgKiBPdmVycmlkZXMgZm9yIHRoZSBsYXlvdXQgYW5kIHdpZGdldCBjb25maWdzLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBvdmVycmlkZXM6IEFnU3R1ZGlvT3ZlcnJpZGVzIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBDb25maWd1cmUgd2hpY2ggcGFuZWxzIGFyZSBkaXNwbGF5ZWQgYW5kIG9uIHdoaWNoIHNpZGUuXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIHBhbmVsczogQWdQYW5lbENvbmZpZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQ29uZmlndXJlIHBhZ2UgKGUuZy4gcGFnZSBzZXR1cCBmb3JtIGluIHBhZ2UgdGFiIG9mIGVkaXQgcGFuZWwpLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBwYWdlOiAoQWdQYWdlQ29uZmlnIHwgKChjb25maWc6IEFnUGFnZUNvbmZpZykgPT4gQWdQYWdlQ29uZmlnKSkgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgQElucHV0KCkgcHVibGljIHdpZGdldHM6XG4gICAgICAgIHwgKEFnV2lkZ2V0c0NvbmZpZzxUUmVnaXN0cnk+IHwgKCh3aWRnZXRzOiBBZ1dpZGdldHNDb25maWc8VFJlZ2lzdHJ5PikgPT4gQWdXaWRnZXRzQ29uZmlnPFRSZWdpc3RyeT4pKVxuICAgICAgICB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQ3VzdG9tIGNvbXBvbmVudHMgKGUuZy4gY3VzdG9tIHdpZGdldCBjb21wb25lbnRzKSBrZXllZCBieSBJRC5cbiAgICAgKiBVc2VkIHRvIHNoYXJlIGNvbXBvbmVudHMgd2hpY2ggY2FuIHRoZW4gYmUgcmVmZXJlbmNlZCBkaXJlY3RseSBieSBrZXkgaW4gdGhlIGRlZmluaXRpb25zLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBjb21wb25lbnRzOiBUUmVnaXN0cnlbJ2NvbXBvbmVudHMnXSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICAgIC8qKiBTdGF0ZSBoYXMgYmVlbiB1cGRhdGVkLlxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgc3RhdGVVcGRhdGVkOiBFdmVudEVtaXR0ZXI8QWdTdHVkaW9TdGF0ZVVwZGF0ZWRFdmVudD4gPVxuICAgICAgICBuZXcgRXZlbnRFbWl0dGVyPEFnU3R1ZGlvU3RhdGVVcGRhdGVkRXZlbnQ+KCk7XG4gICAgLyoqIFRoZSBBUEkgaGFzIGJlZW4gaW5pdGlhbGlzZWQgYW5kIGlzIHJlYWR5IGZvciBtb3N0IGNhbGxzLiBUaGUgZGF0YSBlbmdpbmUgaGFzIG5vdCBiZWVuIGluaXRpYWxpc2VkIHlldCwgYW5kIHRoZSBVSSBpcyBub3QgcmVhZHkuXG4gICAgICovXG4gICAgQE91dHB1dCgpIHB1YmxpYyBhcGlSZWFkeTogRXZlbnRFbWl0dGVyPEFnU3R1ZGlvQXBpUmVhZHlFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPEFnU3R1ZGlvQXBpUmVhZHlFdmVudD4oKTtcbiAgICAvKiogVGhlIGRhdGEgZW5naW5lIGhhcyBiZWVuIGluaXRpYWxpc2VkLCBhbmQgdGhlIFVJIGhhcyBiZWVuIGNyZWF0ZWQsIGJ1dCBtYXkgbm90IGJlIGZ1bGx5IHJlbmRlcmVkIHlldC5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcHVibGljIHN0dWRpb1JlYWR5OiBFdmVudEVtaXR0ZXI8QWdTdHVkaW9SZWFkeUV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8QWdTdHVkaW9SZWFkeUV2ZW50PigpO1xuICAgIC8qKiBBbiBlcnJvciBoYXMgb2NjdXJyZWQgd2l0aGluIFN0dWRpby5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcHVibGljIGVycm9yUmFpc2VkOiBFdmVudEVtaXR0ZXI8QWdTdHVkaW9FcnJvclJhaXNlZEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8QWdTdHVkaW9FcnJvclJhaXNlZEV2ZW50PigpO1xuXG4gICAgLy8gQEVOREBcbn1cblxuY29uc3QgYm9vbGVhbk1peGVkU3R1ZGlvUHJvcGVydGllcyA9IG5ldyBTZXQ8c3RyaW5nPihfQk9PTEVBTl9NSVhFRF9TVFVESU9fUFJPUEVSVElFUyk7XG4vKipcbiAqIFVzZWQgdG8gc3VwcG9ydCB0aGUgdXNlciBzZXR0aW5nIGNvbWJpbmVkIGJvb2xlYW4gYW5kIHN0cmluZyAvIG9iamVjdCBwcm9wZXJ0aWVzXG4gKiBhcyBwbGFpbiBIVE1MIGF0dHJpYnV0ZXMgYW5kIHVzIGNvcnJlY3RseSBtYXBwaW5nIHRoYXQgdG8gdHJ1ZS5cbiAqIEZvciBleGFtcGxlIGNlbGxTZWN0aW9uIGNhbiBiZSBib29sZWFuIG9yIGFuIG9iamVjdFxuICovXG5mdW5jdGlvbiBnZXRWYWx1ZU9yQ29lcmNlZFZhbHVlKGtleTogc3RyaW5nLCB2YWx1ZVRvVXNlOiBhbnkpOiBhbnkge1xuICAgIGlmIChib29sZWFuTWl4ZWRTdHVkaW9Qcm9wZXJ0aWVzLmhhcyhrZXkpKSB7XG4gICAgICAgIC8vIEhhbmRsZSBwbGFpbiBIVE1MIGJvb2xlYW4gYXR0cmlidXRlcyBhbmQgY29udmVydCB0aGVtIHRvIGJvb2xlYW4gdmFsdWVzXG4gICAgICAgIC8vIEFsc28gaGFuZGxlIHRoZSBmYWxzZSBzdHJpbmcgY2FzZSB0byBtYXRjaCBBbmd1bGFyIGJvb2xlYW4gYXR0cmlidXRlc1xuICAgICAgICByZXR1cm4gdmFsdWVUb1VzZSA9PT0gJycgPyB0cnVlIDogdmFsdWVUb1VzZSA9PT0gJ2ZhbHNlJyA/IGZhbHNlIDogdmFsdWVUb1VzZTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlVG9Vc2U7XG59XG4iXX0=
@@ -1,16 +0,0 @@
1
- import { NgModule } from '@angular/core';
2
- import { AgStudio } from './ag-studio.component';
3
- import * as i0 from "@angular/core";
4
- export class AgStudioModule {
5
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AgStudioModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
6
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: AgStudioModule, imports: [AgStudio], exports: [AgStudio] }); }
7
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AgStudioModule }); }
8
- }
9
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AgStudioModule, decorators: [{
10
- type: NgModule,
11
- args: [{
12
- imports: [AgStudio],
13
- exports: [AgStudio],
14
- }]
15
- }] });
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWctc3R1ZGlvLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2FnLXN0dWRpby1hbmd1bGFyL3NyYy9saWIvYWctc3R1ZGlvLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXpDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7QUFNakQsTUFBTSxPQUFPLGNBQWM7K0dBQWQsY0FBYztnSEFBZCxjQUFjLFlBSGIsUUFBUSxhQUNSLFFBQVE7Z0hBRVQsY0FBYzs7NEZBQWQsY0FBYztrQkFKMUIsUUFBUTttQkFBQztvQkFDTixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUM7b0JBQ25CLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQztpQkFDdEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBBZ1N0dWRpbyB9IGZyb20gJy4vYWctc3R1ZGlvLmNvbXBvbmVudCc7XG5cbkBOZ01vZHVsZSh7XG4gICAgaW1wb3J0czogW0FnU3R1ZGlvXSxcbiAgICBleHBvcnRzOiBbQWdTdHVkaW9dLFxufSlcbmV4cG9ydCBjbGFzcyBBZ1N0dWRpb01vZHVsZSB7fVxuIl19
@@ -1,107 +0,0 @@
1
- import { Component, Injectable, ViewContainerRef, inject } from '@angular/core';
2
- import { _BaseComponentWrapper } from 'ag-studio';
3
- import { _removeFromParent } from 'ag-grid-enterprise';
4
- import * as i0 from "@angular/core";
5
- // To speed up the removal of custom components we create a number of shards to contain them.
6
- // Removing a single component calls a function within Angular called removeFromArray.
7
- // This is a lot faster if the array is smaller.
8
- export class AgComponentContainer {
9
- constructor() {
10
- this.vcr = inject(ViewContainerRef);
11
- }
12
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AgComponentContainer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
13
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AgComponentContainer, selector: "ag-component-container", ngImport: i0, template: '', isInline: true }); }
14
- }
15
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AgComponentContainer, decorators: [{
16
- type: Component,
17
- args: [{
18
- selector: 'ag-component-container',
19
- template: '',
20
- }]
21
- }] });
22
- const NUM_SHARDS = 16;
23
- let shardIdx = 0;
24
- function createComponentContainers(vcr) {
25
- const containerMap = new Map();
26
- for (let i = 0; i < NUM_SHARDS; i++) {
27
- const container = vcr.createComponent(AgComponentContainer);
28
- containerMap.set(i, container);
29
- _removeFromParent(container.location.nativeElement);
30
- }
31
- return containerMap;
32
- }
33
- export class AngularFrameworkComponentWrapper extends _BaseComponentWrapper {
34
- setViewContainerRef(viewContainerRef, angularFrameworkOverrides) {
35
- this.viewContainerRef = viewContainerRef;
36
- this.frameworkOverrides = angularFrameworkOverrides;
37
- }
38
- createWrapper(OriginalConstructor) {
39
- this.compShards ??= createComponentContainers(this.viewContainerRef);
40
- return new DynamicAgNg2Component(this.frameworkOverrides, this, OriginalConstructor);
41
- }
42
- createComponent(componentType) {
43
- shardIdx = (shardIdx + 1) % NUM_SHARDS;
44
- const container = this.compShards.get(shardIdx);
45
- return container.instance.vcr.createComponent(componentType);
46
- }
47
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularFrameworkComponentWrapper, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
48
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularFrameworkComponentWrapper }); }
49
- }
50
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularFrameworkComponentWrapper, decorators: [{
51
- type: Injectable
52
- }] });
53
- class DynamicAgNg2Component {
54
- constructor(frameworkOverrides, frameworkCompWrapper, OriginalConstructor) {
55
- this.frameworkOverrides = frameworkOverrides;
56
- this.frameworkCompWrapper = frameworkCompWrapper;
57
- this.OriginalConstructor = OriginalConstructor;
58
- }
59
- init(params) {
60
- return new Promise((resolve) => {
61
- this.frameworkOverrides.runInsideAngular(() => {
62
- this._init(params).then((result) => {
63
- this._componentRef.changeDetectorRef.detectChanges();
64
- resolve(result);
65
- });
66
- });
67
- });
68
- }
69
- async _init(params) {
70
- this._componentRef = this.frameworkCompWrapper.createComponent(this.OriginalConstructor);
71
- const instance = this._componentRef.instance;
72
- this._frameworkComponentInstance = instance;
73
- this._eGui = this._componentRef.location.nativeElement;
74
- // Angular appends the component to the DOM, so remove it
75
- _removeFromParent(this._eGui);
76
- return instance.agInit?.(params);
77
- }
78
- async refresh(params) {
79
- return this.frameworkOverrides.runInsideAngular(() => this._frameworkComponentInstance.refresh?.(params));
80
- }
81
- getGui() {
82
- return this._eGui;
83
- }
84
- /** `getGui()` returns the `ng-component` element. This returns the actual root element. */
85
- getRootElement() {
86
- return this._eGui.firstChild;
87
- }
88
- destroy() {
89
- if (typeof this._frameworkComponentInstance?.destroy === 'function') {
90
- this._frameworkComponentInstance.destroy();
91
- }
92
- this._componentRef?.destroy();
93
- }
94
- getFrameworkComponentInstance() {
95
- return this._frameworkComponentInstance;
96
- }
97
- hasMethod(name) {
98
- return this._frameworkComponentInstance[name] != null;
99
- }
100
- callMethod(name, args) {
101
- return this.frameworkOverrides.runInsideAngular(() => this._frameworkComponentInstance[name](...args));
102
- }
103
- addMethod(name, callback) {
104
- this[name] = callback;
105
- }
106
- }
107
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhckZyYW1ld29ya0NvbXBvbmVudFdyYXBwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hZy1zdHVkaW8tYW5ndWxhci9zcmMvbGliL2FuZ3VsYXJGcmFtZXdvcmtDb21wb25lbnRXcmFwcGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVoRixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFbEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7O0FBS3ZELDZGQUE2RjtBQUM3RixzRkFBc0Y7QUFDdEYsZ0RBQWdEO0FBS2hELE1BQU0sT0FBTyxvQkFBb0I7SUFKakM7UUFLVyxRQUFHLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7S0FDekM7K0dBRlksb0JBQW9CO21HQUFwQixvQkFBb0IsOERBRm5CLEVBQUU7OzRGQUVILG9CQUFvQjtrQkFKaEMsU0FBUzttQkFBQztvQkFDUCxRQUFRLEVBQUUsd0JBQXdCO29CQUNsQyxRQUFRLEVBQUUsRUFBRTtpQkFDZjs7QUFJRCxNQUFNLFVBQVUsR0FBRyxFQUFFLENBQUM7QUFDdEIsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBRWpCLFNBQVMseUJBQXlCLENBQUMsR0FBcUI7SUFDcEQsTUFBTSxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQThDLENBQUM7SUFDM0UsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFVBQVUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxlQUFlLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUM1RCxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxTQUFT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QUksQ0FBQyxLQUFLLENBQUM7SUFDdEIsQ0FBQztJQUVELDJGQUEyRjtJQUMzRixjQUFjO1FBQ1YsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQXlCLENBQUM7SUFDaEQsQ0FBQztJQUVELE9BQU87UUFDSCxJQUFJLE9BQU8sSUFBSSxDQUFDLDJCQUEyQixFQUFFLE9BQU8sS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNsRSxJQUFJLENBQUMsMkJBQTJCLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0MsQ0FBQztRQUNELElBQUksQ0FBQyxhQUFhLEVBQUUsT0FBTyxFQUFFLENBQUM7SUFDbEMsQ0FBQztJQUVELDZCQUE2QjtRQUN6QixPQUFPLElBQUksQ0FBQywyQkFBMkIsQ0FBQztJQUM1QyxDQUFDO0lBRUQsU0FBUyxDQUFDLElBQVk7UUFDbEIsT0FBTyxJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDO0lBQzFELENBQUM7SUFFRCxVQUFVLENBQUMsSUFBWSxFQUFFLElBQWdCO1FBQ3JDLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDM0csQ0FBQztJQUVELFNBQVMsQ0FBQyxJQUFZLEVBQUUsUUFBaUM7UUFDcEQsSUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLFFBQVEsQ0FBQztJQUNuQyxDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IENvbXBvbmVudFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBJbmplY3RhYmxlLCBWaWV3Q29udGFpbmVyUmVmLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB0eXBlIHsgX0ZyYW1ld29ya0NvbXBvbmVudFdyYXBwZXIsIF9XcmFwcGFibGVJbnRlcmZhY2UgfSBmcm9tICdhZy1zdHVkaW8nO1xuaW1wb3J0IHsgX0Jhc2VDb21wb25lbnRXcmFwcGVyIH0gZnJvbSAnYWctc3R1ZGlvJztcblxuaW1wb3J0IHsgX3JlbW92ZUZyb21QYXJlbnQgfSBmcm9tICdhZy1ncmlkLWVudGVycHJpc2UnO1xuXG5pbXBvcnQgdHlwZSB7IEFuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMgfSBmcm9tICcuL2FuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMnO1xuaW1wb3J0IHR5cGUgeyBBZ0N1c3RvbUNvbXBvbmVudCB9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5cbi8vIFRvIHNwZWVkIHVwIHRoZSByZW1vdmFsIG9mIGN1c3RvbSBjb21wb25lbnRzIHdlIGNyZWF0ZSBhIG51bWJlciBvZiBzaGFyZHMgdG8gY29udGFpbiB0aGVtLlxuLy8gUmVtb3ZpbmcgYSBzaW5nbGUgY29tcG9uZW50IGNhbGxzIGEgZnVuY3Rpb24gd2l0aGluIEFuZ3VsYXIgY2FsbGVkIHJlbW92ZUZyb21BcnJheS5cbi8vIFRoaXMgaXMgYSBsb3QgZmFzdGVyIGlmIHRoZSBhcnJheSBpcyBzbWFsbGVyLlxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdhZy1jb21wb25lbnQtY29udGFpbmVyJyxcbiAgICB0ZW1wbGF0ZTogJycsXG59KVxuZXhwb3J0IGNsYXNzIEFnQ29tcG9uZW50Q29udGFpbmVyIHtcbiAgICBwdWJsaWMgdmNyID0gaW5qZWN0KFZpZXdDb250YWluZXJSZWYpO1xufVxuY29uc3QgTlVNX1NIQVJEUyA9IDE2O1xubGV0IHNoYXJkSWR4ID0gMDtcblxuZnVuY3Rpb24gY3JlYXRlQ29tcG9uZW50Q29udGFpbmVycyh2Y3I6IFZpZXdDb250YWluZXJSZWYpOiBNYXA8bnVtYmVyLCBDb21wb25lbnRSZWY8QWdDb21wb25lbnRDb250YWluZXI+PiB7XG4gICAgY29uc3QgY29udGFpbmVyTWFwID0gbmV3IE1hcDxudW1iZXIsIENvbXBvbmVudFJlZjxBZ0NvbXBvbmVudENvbnRhaW5lcj4+KCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBOVU1fU0hBUkRTOyBpKyspIHtcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gdmNyLmNyZWF0ZUNvbXBvbmVudChBZ0NvbXBvbmVudENvbnRhaW5lcik7XG4gICAgICAgIGNvbnRhaW5lck1hcC5zZXQoaSwgY29udGFpbmVyKTtcbiAgICAgICAgX3JlbW92ZUZyb21QYXJlbnQoY29udGFpbmVyLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQpO1xuICAgIH1cbiAgICByZXR1cm4gY29udGFpbmVyTWFwO1xufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQW5ndWxhckZyYW1ld29ya0NvbXBvbmVudFdyYXBwZXJcbiAgICBleHRlbmRzIF9CYXNlQ29tcG9uZW50V3JhcHBlcjxfV3JhcHBhYmxlSW50ZXJmYWNlPlxuICAgIGltcGxlbWVudHMgX0ZyYW1ld29ya0NvbXBvbmVudFdyYXBwZXJcbntcbiAgICBwcml2YXRlIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWY7XG4gICAgcHJpdmF0ZSBmcmFtZXdvcmtPdmVycmlkZXM6IEFuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXM7XG4gICAgcHJpdmF0ZSBjb21wU2hhcmRzOiBNYXA8bnVtYmVyLCBDb21wb25lbnRSZWY8QWdDb21wb25lbnRDb250YWluZXI+PjtcblxuICAgIHNldFZpZXdDb250YWluZXJSZWYodmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZiwgYW5ndWxhckZyYW1ld29ya092ZXJyaWRlczogQW5ndWxhckZyYW1ld29ya092ZXJyaWRlcykge1xuICAgICAgICB0aGlzLnZpZXdDb250YWluZXJSZWYgPSB2aWV3Q29udGFpbmVyUmVmO1xuICAgICAgICB0aGlzLmZyYW1ld29ya092ZXJyaWRlcyA9IGFuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXM7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGNyZWF0ZVdyYXBwZXIoT3JpZ2luYWxDb25zdHJ1Y3RvcjogeyBuZXcgKCk6IGFueSB9KTogX1dyYXBwYWJsZUludGVyZmFjZSB7XG4gICAgICAgIHRoaXMuY29tcFNoYXJkcyA/Pz0gY3JlYXRlQ29tcG9uZW50Q29udGFpbmVycyh0aGlzLnZpZXdDb250YWluZXJSZWYpO1xuICAgICAgICByZXR1cm4gbmV3IER5bmFtaWNBZ05nMkNvbXBvbmVudCh0aGlzLmZyYW1ld29ya092ZXJyaWRlcywgdGhpcywgT3JpZ2luYWxDb25zdHJ1Y3Rvcik7XG4gICAgfVxuXG4gICAgY3JlYXRlQ29tcG9uZW50PFQ+KGNvbXBvbmVudFR5cGU6IHsgbmV3ICguLi5hcmdzOiBhbnlbXSk6IFQgfSk6IENvbXBvbmVudFJlZjxUPiB7XG4gICAgICAgIHNoYXJkSWR4ID0gKHNoYXJkSWR4ICsgMSkgJSBOVU1fU0hBUkRTO1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmNvbXBTaGFyZHMuZ2V0KHNoYXJkSWR4KSE7XG4gICAgICAgIHJldHVybiBjb250YWluZXIuaW5zdGFuY2UudmNyLmNyZWF0ZUNvbXBvbmVudChjb21wb25lbnRUeXBlKTtcbiAgICB9XG59XG5cbmNsYXNzIER5bmFtaWNBZ05nMkNvbXBvbmVudDxQPiBpbXBsZW1lbnRzIF9XcmFwcGFibGVJbnRlcmZhY2Uge1xuICAgIHByaXZhdGUgX2VHdWk6IEhUTUxFbGVtZW50O1xuICAgIHByaXZhdGUgX2NvbXBvbmVudFJlZjogQ29tcG9uZW50UmVmPEFnQ3VzdG9tQ29tcG9uZW50PFA+PjtcbiAgICBwcml2YXRlIF9mcmFtZXdvcmtDb21wb25lbnRJbnN0YW5jZTogYW55OyAvLyB0aGUgdXNlcidzIGNvbXBvbmVudCAtIGZvciBhY2Nlc3NpbmcgbWV0aG9kcyB0aGV5IGNyZWF0ZVxuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgZnJhbWV3b3JrT3ZlcnJpZGVzOiBBbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzLFxuICAgICAgICBwcml2YXRlIGZyYW1ld29ya0NvbXBXcmFwcGVyOiBBbmd1bGFyRnJhbWV3b3JrQ29tcG9uZW50V3JhcHBlcixcbiAgICAgICAgcHJpdmF0ZSBPcmlnaW5hbENvbnN0cnVjdG9yOiB7IG5ldyAoKTogYW55IH1cbiAgICApIHt9XG5cbiAgICBpbml0KHBhcmFtczogUCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5mcmFtZXdvcmtPdmVycmlkZXMucnVuSW5zaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5faW5pdChwYXJhbXMpLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jb21wb25lbnRSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfaW5pdChwYXJhbXM6IFApOiBQcm9taXNlPGFueT4ge1xuICAgICAgICB0aGlzLl9jb21wb25lbnRSZWYgPSB0aGlzLmZyYW1ld29ya0NvbXBXcmFwcGVyLmNyZWF0ZUNvbXBvbmVudCh0aGlzLk9yaWdpbmFsQ29uc3RydWN0b3IpO1xuICAgICAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMuX2NvbXBvbmVudFJlZi5pbnN0YW5jZTtcbiAgICAgICAgdGhpcy5fZnJhbWV3b3JrQ29tcG9uZW50SW5zdGFuY2UgPSBpbnN0YW5jZTtcbiAgICAgICAgdGhpcy5fZUd1aSA9IHRoaXMuX2NvbXBvbmVudFJlZi5sb2NhdGlvbi5uYXRpdmVFbGVtZW50O1xuICAgICAgICAvLyBBbmd1bGFyIGFwcGVuZHMgdGhlIGNvbXBvbmVudCB0byB0aGUgRE9NLCBzbyByZW1vdmUgaXRcbiAgICAgICAgX3JlbW92ZUZyb21QYXJlbnQodGhpcy5fZUd1aSk7XG5cbiAgICAgICAgcmV0dXJuIGluc3RhbmNlLmFnSW5pdD8uKHBhcmFtcyk7XG4gICAgfVxuXG4gICAgYXN5bmMgcmVmcmVzaChwYXJhbXM6IFApOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5mcmFtZXdvcmtPdmVycmlkZXMucnVuSW5zaWRlQW5ndWxhcigoKSA9PiB0aGlzLl9mcmFtZXdvcmtDb21wb25lbnRJbnN0YW5jZS5yZWZyZXNoPy4ocGFyYW1zKSk7XG4gICAgfVxuXG4gICAgZ2V0R3VpKCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VHdWk7XG4gICAgfVxuXG4gICAgLyoqIGBnZXRHdWkoKWAgcmV0dXJucyB0aGUgYG5nLWNvbXBvbmVudGAgZWxlbWVudC4gVGhpcyByZXR1cm5zIHRoZSBhY3R1YWwgcm9vdCBlbGVtZW50LiAqL1xuICAgIGdldFJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VHdWkuZmlyc3RDaGlsZCBhcyBIVE1MRWxlbWVudDtcbiAgICB9XG5cbiAgICBkZXN0cm95KCk6IHZvaWQge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX2ZyYW1ld29ya0NvbXBvbmVudEluc3RhbmNlPy5kZXN0cm95ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9mcmFtZXdvcmtDb21wb25lbnRJbnN0YW5jZS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY29tcG9uZW50UmVmPy5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgZ2V0RnJhbWV3b3JrQ29tcG9uZW50SW5zdGFuY2UoKTogYW55IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZyYW1ld29ya0NvbXBvbmVudEluc3RhbmNlO1xuICAgIH1cblxuICAgIGhhc01ldGhvZChuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZyYW1ld29ya0NvbXBvbmVudEluc3RhbmNlW25hbWVdICE9IG51bGw7XG4gICAgfVxuXG4gICAgY2FsbE1ldGhvZChuYW1lOiBzdHJpbmcsIGFyZ3M6IElBcmd1bWVudHMpOiBhbnkge1xuICAgICAgICByZXR1cm4gdGhpcy5mcmFtZXdvcmtPdmVycmlkZXMucnVuSW5zaWRlQW5ndWxhcigoKSA9PiB0aGlzLl9mcmFtZXdvcmtDb21wb25lbnRJbnN0YW5jZVtuYW1lXSguLi5hcmdzKSk7XG4gICAgfVxuXG4gICAgYWRkTWV0aG9kKG5hbWU6IHN0cmluZywgY2FsbGJhY2s6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55KTogdm9pZCB7XG4gICAgICAgICh0aGlzIGFzIGFueSlbbmFtZV0gPSBjYWxsYmFjaztcbiAgICB9XG59XG4iXX0=