@datagrok-libraries/utils 3.3.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/package.json +1 -1
  2. package/css/file-input.css +0 -32
  3. package/css/history-input.css +0 -27
  4. package/css/history-panel.css +0 -57
  5. package/css/pipeline-view.css +0 -13
  6. package/css/rich-function-view.css +0 -4
  7. package/src/computation-view.d.ts +0 -78
  8. package/src/computation-view.d.ts.map +0 -1
  9. package/src/computation-view.js +0 -157
  10. package/src/function-view.d.ts +0 -226
  11. package/src/function-view.d.ts.map +0 -1
  12. package/src/function-view.js +0 -384
  13. package/src/history-utils.d.ts +0 -65
  14. package/src/history-utils.d.ts.map +0 -1
  15. package/src/history-utils.js +0 -212
  16. package/src/pipeline-view.d.ts +0 -40
  17. package/src/pipeline-view.d.ts.map +0 -1
  18. package/src/pipeline-view.js +0 -178
  19. package/src/rich-function-view.d.ts +0 -55
  20. package/src/rich-function-view.d.ts.map +0 -1
  21. package/src/rich-function-view.js +0 -571
  22. package/src/shared-components/file-input.d.ts +0 -23
  23. package/src/shared-components/file-input.d.ts.map +0 -1
  24. package/src/shared-components/file-input.js +0 -133
  25. package/src/shared-components/history-input.d.ts +0 -26
  26. package/src/shared-components/history-input.d.ts.map +0 -1
  27. package/src/shared-components/history-input.js +0 -192
  28. package/src/shared-components/history-panel.d.ts +0 -65
  29. package/src/shared-components/history-panel.d.ts.map +0 -1
  30. package/src/shared-components/history-panel.js +0 -502
  31. package/src/shared-components/ui-utils.d.ts +0 -10
  32. package/src/shared-components/ui-utils.d.ts.map +0 -1
  33. package/src/shared-components/ui-utils.js +0 -19
  34. package/src/validation.d.ts +0 -56
  35. package/src/validation.d.ts.map +0 -1
  36. package/src/validation.js +0 -152
@@ -1,571 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- /* eslint-disable valid-jsdoc */
11
- /* eslint-disable max-len */
12
- import * as grok from 'datagrok-api/grok';
13
- import * as ui from 'datagrok-api/ui';
14
- import * as DG from 'datagrok-api/dg';
15
- import { FunctionView } from './function-view';
16
- import ExcelJS from 'exceljs';
17
- import html2canvas from 'html2canvas';
18
- import wu from 'wu';
19
- import $ from 'cash-dom';
20
- import { Subject } from 'rxjs';
21
- import { UiUtils } from './shared-components/ui-utils';
22
- import '../css/rich-function-view.css';
23
- // mapping from internal Dart labels to JS DG.VIEWER labels
24
- const viewerTypesMapping = {
25
- ['barchart']: DG.VIEWER.BAR_CHART,
26
- ['boxplot']: DG.VIEWER.BOX_PLOT,
27
- ['calendar']: DG.VIEWER.CALENDAR,
28
- ['corrplot']: DG.VIEWER.CORR_PLOT,
29
- ['densityplot']: DG.VIEWER.DENSITY_PLOT,
30
- ['filters']: DG.VIEWER.FILTERS,
31
- ['form']: DG.VIEWER.FORM,
32
- ['globe']: DG.VIEWER.GLOBE,
33
- ['googlemap']: DG.VIEWER.GOOGLE_MAP,
34
- ['grid']: DG.VIEWER.GRID,
35
- ['heatmap']: DG.VIEWER.HEAT_MAP,
36
- ['histogram']: DG.VIEWER.HISTOGRAM,
37
- ['linechart']: DG.VIEWER.LINE_CHART,
38
- ['markup']: DG.VIEWER.MARKUP,
39
- ['matrixplot']: DG.VIEWER.MATRIX_PLOT,
40
- ['networkdiagram']: DG.VIEWER.NETWORK_DIAGRAM,
41
- ['pcplot']: DG.VIEWER.PC_PLOT,
42
- ['piechart']: DG.VIEWER.PIE_CHART,
43
- ['scatterplot']: DG.VIEWER.SCATTER_PLOT,
44
- ['scatterplot3d']: DG.VIEWER.SCATTER_PLOT_3D,
45
- ['shapemap']: DG.VIEWER.SHAPE_MAP,
46
- ['statistics']: DG.VIEWER.STATISTICS,
47
- ['tileviewer']: DG.VIEWER.TILE_VIEWER,
48
- ['timelines']: DG.VIEWER.TIMELINES,
49
- ['treemap']: DG.VIEWER.TREE_MAP,
50
- ['trellisplot']: DG.VIEWER.TRELLIS_PLOT,
51
- ['wordcloud']: DG.VIEWER.WORD_CLOUD,
52
- };
53
- const FILE_INPUT_TYPE = 'file';
54
- export class RichFunctionView extends FunctionView {
55
- static fromFuncCall(funcCall, options = { historyEnabled: true, isTabbed: false }) {
56
- return new this(funcCall.func.nqName, options);
57
- }
58
- constructor(funcName, options = { historyEnabled: true, isTabbed: false }) {
59
- super(funcName, options);
60
- this.options = options;
61
- // emitted when runButton disability should be checked
62
- this.checkDisability = new Subject();
63
- // stores the running state
64
- this.isRunning = false;
65
- // Main element of the output block. Stores all the tabs for the output and input
66
- this.tabsElem = ui.tabControl();
67
- // Stores mapping between DF and its' viewers
68
- this.dfToViewerMapping = {};
69
- /**
70
- * RichFunctionView know everything about its UI, so it exports not only data, but also viewer screenshots.
71
- * This function iterates over all of the tabs and sequentally exports all dataframes, their viewers and scalars.
72
- * @param format format needed to export. See {@link this.defaultSupportedExportFormats} for available formats.
73
- * @returns Promise<Blob> with data ready for download
74
- */
75
- this.defaultExport = (format) => __awaiter(this, void 0, void 0, function* () {
76
- const lastCall = this.lastCall;
77
- if (!lastCall)
78
- throw new Error(`Function was not called`);
79
- if (!this.exportConfig.supportedFormats.includes(format))
80
- throw new Error(`Format "${format}" is not supported.`);
81
- if (!this.func)
82
- throw new Error('The correspoding function is not specified');
83
- const BLOB_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8';
84
- const exportWorkbook = new ExcelJS.Workbook();
85
- const isScalarType = (type) => (DG.TYPES_SCALAR.has(type));
86
- const isDataFrame = (type) => (type === DG.TYPE.DATA_FRAME);
87
- const dfInputs = this.func.inputs.filter((input) => isDataFrame(input.propertyType));
88
- const scalarInputs = this.func.inputs.filter((input) => isScalarType(input.propertyType));
89
- const dfOutputs = this.func.outputs.filter((output) => isDataFrame(output.propertyType));
90
- const scalarOutputs = this.func.outputs.filter((output) => isScalarType(output.propertyType));
91
- const inputParams = [...lastCall.inputParams.values()];
92
- const outputParams = [...lastCall.outputParams.values()];
93
- dfInputs.forEach((dfInput) => {
94
- const visibleTitle = dfInput.options.caption || dfInput.name;
95
- const currentDfSheet = exportWorkbook.addWorksheet(getSheetName(visibleTitle, DIRECTION.INPUT));
96
- const currentDf = lastCall.inputs[dfInput.name];
97
- dfToSheet(currentDfSheet, currentDf);
98
- });
99
- if (scalarInputs.length) {
100
- const inputScalarsSheet = exportWorkbook.addWorksheet('Input scalars');
101
- scalarsToSheet(inputScalarsSheet, scalarInputs.map((scalarInput) => ({
102
- caption: scalarInput.options['caption'] || scalarInput.name,
103
- value: lastCall.inputs[scalarInput.name],
104
- units: scalarInput.options['units'] || '',
105
- })));
106
- }
107
- dfOutputs.forEach((dfOutput) => {
108
- const visibleTitle = dfOutput.options.caption || dfOutput.name;
109
- const currentDfSheet = exportWorkbook.addWorksheet(getSheetName(visibleTitle, DIRECTION.OUTPUT));
110
- const currentDf = lastCall.outputs[dfOutput.name];
111
- dfToSheet(currentDfSheet, currentDf);
112
- });
113
- if (scalarOutputs.length) {
114
- const outputScalarsSheet = exportWorkbook.addWorksheet('Output scalars');
115
- scalarsToSheet(outputScalarsSheet, scalarOutputs.map((scalarOutput) => ({
116
- caption: scalarOutput.options['caption'] || scalarOutput.name,
117
- value: lastCall.outputs[scalarOutput.name],
118
- units: scalarOutput.options['units'] || '',
119
- })));
120
- }
121
- const tabControl = this.tabsElem;
122
- for (const tabLabel of this.tabsLabels) {
123
- tabControl.currentPane = tabControl.getPane(tabLabel);
124
- yield new Promise((r) => setTimeout(r, 100));
125
- if (tabLabel === 'Input') {
126
- for (const inputParam of inputParams.filter((inputParam) => inputParam.property.propertyType === DG.TYPE.DATA_FRAME)) {
127
- const nonGridViewers = this.dfToViewerMapping[inputParam.name]
128
- .filter((viewer) => viewer.type !== DG.VIEWER.GRID)
129
- .filter((viewer) => Object.values(viewerTypesMapping).includes(viewer.type));
130
- const dfInput = dfInputs.find((input) => input.name === inputParam.name);
131
- const visibleTitle = dfInput.options.caption || inputParam.name;
132
- const currentDf = lastCall.inputs[dfInput.name];
133
- for (const [index, viewer] of nonGridViewers.entries()) {
134
- yield plotToSheet(exportWorkbook, exportWorkbook.getWorksheet(getSheetName(visibleTitle, DIRECTION.INPUT)), viewer.root, currentDf.columns.length + 2, (index > 0) ? Math.ceil(nonGridViewers[index - 1].root.clientHeight / 20) + 1 : 0);
135
- }
136
- ;
137
- }
138
- }
139
- else {
140
- for (const outputParam of outputParams.filter((outputParam) => outputParam.property.propertyType === DG.TYPE.DATA_FRAME &&
141
- ((tabLabel === 'Output' && outputParam.property.category === 'Misc' || outputParam.property.category === 'Output') ||
142
- (tabLabel !== 'Output' && outputParam.property.category === tabLabel)))) {
143
- const nonGridViewers = this.dfToViewerMapping[outputParam.property.name]
144
- .filter((viewer) => viewer.type !== DG.VIEWER.GRID)
145
- .filter((viewer) => Object.values(viewerTypesMapping).includes(viewer.type));
146
- const dfOutput = dfOutputs.find((output) => output.name === outputParam.property.name);
147
- const visibleTitle = dfOutput.options.caption || outputParam.property.name;
148
- const currentDf = lastCall.outputs[dfOutput.name];
149
- for (const [index, viewer] of nonGridViewers.entries()) {
150
- if (viewer.type === DG.VIEWER.STATISTICS) {
151
- const length = currentDf.columns.length;
152
- const stats = DG.DataFrame.fromColumns([
153
- DG.Column.string('Name', length).init((i) => currentDf.columns.byIndex(i).name),
154
- DG.Column.int('Values', length).init((i) => currentDf.columns.byIndex(i).stats.valueCount),
155
- DG.Column.int('Nulls', length).init((i) => currentDf.columns.byIndex(i).stats.missingValueCount),
156
- DG.Column.float('Min', length).init((i) => currentDf.columns.byIndex(i).stats.min),
157
- DG.Column.float('Max', length).init((i) => currentDf.columns.byIndex(i).stats.max),
158
- DG.Column.float('Avg', length).init((i) => currentDf.columns.byIndex(i).stats.avg),
159
- DG.Column.float('Stdev', length).init((i) => currentDf.columns.byIndex(i).stats.stdev),
160
- ]);
161
- dfToSheet(exportWorkbook.getWorksheet(getSheetName(visibleTitle, DIRECTION.OUTPUT)), stats, currentDf.columns.length + 2, (index > 0) ? Math.ceil(nonGridViewers[index - 1].root.clientHeight / 20) + 1 : 0);
162
- }
163
- else {
164
- yield plotToSheet(exportWorkbook, exportWorkbook.getWorksheet(getSheetName(visibleTitle, DIRECTION.OUTPUT)), viewer.root, currentDf.columns.length + 2, (index > 0) ? Math.ceil(nonGridViewers[index - 1].root.clientHeight / 20) + 1 : 0);
165
- }
166
- }
167
- }
168
- ;
169
- }
170
- }
171
- ;
172
- const buffer = yield exportWorkbook.xlsx.writeBuffer();
173
- return new Blob([buffer], { type: BLOB_TYPE });
174
- });
175
- this.exportConfig = {
176
- supportedExtensions: this.defaultSupportedExportExtensions(),
177
- supportedFormats: this.defaultSupportedExportFormats(),
178
- export: this.defaultExport,
179
- filename: this.defaultExportFilename,
180
- };
181
- this.subs.push(this.onFuncCallReady.subscribe({
182
- complete: () => {
183
- this.basePath = `scripts/${this.funcCall.func.id}/view`;
184
- }
185
- }));
186
- }
187
- /**
188
- * Showing UI after completion of function call.
189
- * @param runFunc
190
- */
191
- onAfterRun(runFunc) {
192
- this.tabsElem.root.style.removeProperty('display');
193
- this.tabsElem.panes.forEach((tab) => {
194
- tab.header.style.removeProperty('display');
195
- });
196
- const firstOutputTab = this.tabsElem.panes.find((tab) => tab.name !== 'Input');
197
- if (firstOutputTab)
198
- this.tabsElem.currentPane = firstOutputTab;
199
- return Promise.resolve();
200
- }
201
- /**
202
- * RichFunctionView has adavanced automatic UI builder. It takes {@link this.funcCall} as a base and constructs flexible view.
203
- * This view is updated automatically when {@link this.funcCallReplaced} is emitted or any of input/output param changes.
204
- * @returns HTMLElement attached to the root of the view
205
- */
206
- buildIO() {
207
- const inputBlock = this.buildInputBlock();
208
- ui.tools.handleResize(inputBlock, (width) => {
209
- if (width < 350)
210
- $(inputBlock.firstChild).addClass('ui-form-condensed');
211
- else
212
- $(inputBlock.firstChild).removeClass('ui-form-condensed');
213
- });
214
- const outputBlock = this.buildOutputBlock();
215
- outputBlock.style.height = '100%';
216
- outputBlock.style.width = '100%';
217
- this.tabsElem.root.style.display = 'none';
218
- if (!!this.tabsElem.getPane('Input')) {
219
- this.tabsElem.panes.forEach((tab) => {
220
- tab.header.style.display = 'none';
221
- });
222
- }
223
- const out = ui.splitH([inputBlock, ui.panel([outputBlock], { style: { 'padding-top': '0px' } })], null, true);
224
- out.style.padding = '0 12px';
225
- inputBlock.parentElement.style.maxWidth = '450px';
226
- return out;
227
- }
228
- buildInputBlock() {
229
- const formDiv = this.renderRunSection();
230
- return formDiv;
231
- }
232
- buildRibbonPanels() {
233
- super.buildRibbonPanels();
234
- const play = ui.iconFA('play', () => __awaiter(this, void 0, void 0, function* () { return yield this.doRun(); }));
235
- play.classList.add('fas');
236
- const newRibbonPanels = [
237
- ...this.getRibbonPanels(),
238
- [play],
239
- ];
240
- this.setRibbonPanels(newRibbonPanels);
241
- return newRibbonPanels;
242
- }
243
- buildOutputBlock() {
244
- this.tabsElem.root.style.width = '100%';
245
- this.tabsLabels.forEach((tabLabel) => {
246
- const tabDfProps = this.categoryToParamMap[tabLabel].filter((p) => p.propertyType === DG.TYPE.DATA_FRAME);
247
- const tabScalarProps = this.categoryToParamMap[tabLabel].filter((p) => p.propertyType !== DG.TYPE.DATA_FRAME);
248
- // dfProp.options['viewer'] could be empty, so we need to check it
249
- const parsedTabDfProps = tabDfProps.map((dfProp) => (dfProp.options['viewer'] !== undefined) ?
250
- // true and false values are retrieved as string, so we call JSON.parse on them once more
251
- JSON.parse(dfProp.options['viewer'], (_, v) => v === 'true' || v === 'false' ? JSON.parse(v) : v) :
252
- []);
253
- const dfBlocks = tabDfProps.map((dfProp, dfIndex) => {
254
- var _a;
255
- let fullBlockWidth = 0;
256
- parsedTabDfProps[dfIndex].forEach((_, viewerIndex) => {
257
- const blockSize = parsedTabDfProps[dfIndex][viewerIndex]['block'];
258
- fullBlockWidth += blockSize ? parseInt(blockSize) : 0;
259
- });
260
- const viewers = Promise.all(parsedTabDfProps[dfIndex].map((viewerDesc) => __awaiter(this, void 0, void 0, function* () {
261
- var _b, _c, _d, _e, _f;
262
- const initialValue = (_f = (_d = (_c = (_b = this.funcCall) === null || _b === void 0 ? void 0 : _b.outputs[dfProp.name]) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : (_e = this.funcCall.inputParams[dfProp.name]) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : grok.data.demo.demog(1);
263
- const viewer = viewerTypesMapping[viewerDesc['type']] ? DG.Viewer.fromType(viewerTypesMapping[viewerDesc['type']], initialValue) : yield initialValue.plot.fromType(viewerDesc['type']);
264
- viewer.setOptions(viewerDesc);
265
- if (this.dfToViewerMapping[dfProp.name])
266
- this.dfToViewerMapping[dfProp.name].push(viewer);
267
- else
268
- this.dfToViewerMapping[dfProp.name] = [viewer];
269
- return viewer;
270
- })));
271
- viewers.then((loadedViewers) => {
272
- const subscribeOnFcChanges = () => {
273
- var _a;
274
- const currentParam = (_a = this.funcCall.outputParams[dfProp.name]) !== null && _a !== void 0 ? _a : this.funcCall.inputParams[dfProp.name];
275
- const paramSub = currentParam.onChanged.subscribe(() => {
276
- loadedViewers.forEach((viewer) => __awaiter(this, void 0, void 0, function* () {
277
- if (Object.values(viewerTypesMapping).includes(viewer.type)) {
278
- viewer.dataFrame = currentParam.value;
279
- }
280
- else {
281
- // User-defined viewers (e.g. OutliersSelectionViewer) could created only asynchronously
282
- const newViewer = yield currentParam.value.plot.fromType(viewer.type);
283
- viewer.root.replaceWith(newViewer.root);
284
- viewer = newViewer;
285
- }
286
- }));
287
- });
288
- this.subs.push(paramSub);
289
- };
290
- subscribeOnFcChanges();
291
- this.subs.push(this.funcCallReplaced.subscribe(subscribeOnFcChanges));
292
- });
293
- const dfBlockTitle = (_a = dfProp.options['caption']) !== null && _a !== void 0 ? _a : dfProp.name;
294
- const dfBlock = ui.wait(() => __awaiter(this, void 0, void 0, function* () {
295
- const loadedViewers = yield viewers;
296
- return ui.divH(yield Promise.all(loadedViewers.map((viewer) => viewer.root, { style: { 'flex-wrap': 'wrap' } })));
297
- }));
298
- if (tabLabel === 'Input') {
299
- const subscribeOnFcChanges = () => {
300
- var _a;
301
- const currentParam = (_a = this.funcCall.outputParams[dfProp.name]) !== null && _a !== void 0 ? _a : this.funcCall.inputParams[dfProp.name];
302
- const paramSub = currentParam.onChanged.subscribe(() => {
303
- this.tabsElem.root.style.removeProperty('display');
304
- });
305
- this.subs.push(paramSub);
306
- };
307
- subscribeOnFcChanges();
308
- this.subs.push(this.funcCallReplaced.subscribe(subscribeOnFcChanges));
309
- }
310
- return ui.divV([
311
- // Removing title margin on top of block titles
312
- ui.h2(dfBlockTitle, Object.assign({}, (dfIndex > 0) ? { style: { 'margin-top': '0px' } } : {})),
313
- dfBlock
314
- ], { style: Object.assign({}, (fullBlockWidth > 0) ? { 'width': `${fullBlockWidth}%` } : { 'width': `100%` }) });
315
- });
316
- const generateScalarsTable = () => {
317
- const table = DG.HtmlTable.create(tabScalarProps, (scalarProp) => { var _a; return [scalarProp.name, (_a = this.funcCall) === null || _a === void 0 ? void 0 : _a.outputs[scalarProp.name], scalarProp.options['units']]; }).root;
318
- table.style.maxWidth = '400px';
319
- return table;
320
- };
321
- let scalarsTable = generateScalarsTable();
322
- tabScalarProps.forEach((tabScalarProp) => {
323
- const subscribeOnFcChanges = () => {
324
- const paramSub = this.funcCall.outputParams[tabScalarProp.name].onChanged.subscribe(() => {
325
- const newScalarsTable = generateScalarsTable();
326
- scalarsTable.replaceWith(newScalarsTable);
327
- scalarsTable = newScalarsTable;
328
- });
329
- this.subs.push(paramSub);
330
- };
331
- subscribeOnFcChanges();
332
- this.subs.push(this.funcCallReplaced.subscribe(subscribeOnFcChanges));
333
- });
334
- const dfSections = [];
335
- let currentWidth = 0;
336
- let currentSection = ui.divH([], { style: { 'margin-bottom': '25px' } }); // Adding small margin between sections
337
- dfBlocks.forEach((dfBlock, dfIndex) => {
338
- const blockWidth = parseInt(dfBlock.style.width);
339
- if (currentWidth + blockWidth === 100) {
340
- currentSection.append(dfBlock);
341
- dfSections.push(currentSection);
342
- currentSection = ui.divH([]);
343
- currentWidth = 0;
344
- }
345
- else if (currentWidth + blockWidth < 100) {
346
- currentSection.append(dfBlock);
347
- currentWidth += blockWidth;
348
- }
349
- else {
350
- dfSections.push(currentSection);
351
- currentSection = ui.divH([]);
352
- currentSection.append(dfBlock);
353
- currentWidth = blockWidth;
354
- }
355
- if (dfIndex === dfBlocks.length - 1)
356
- dfSections.push(currentSection);
357
- });
358
- this.tabsElem.addPane(tabLabel, () => {
359
- return ui.divV([...dfSections, ...tabScalarProps.length ? [ui.h2('Scalar values')] : [], scalarsTable]);
360
- });
361
- });
362
- const outputBlock = ui.box();
363
- outputBlock.append(this.tabsElem.root);
364
- return outputBlock;
365
- }
366
- onAfterLoadRun(loadedRun) {
367
- return __awaiter(this, void 0, void 0, function* () {
368
- wu(this.funcCall.outputParams.values()).forEach((out) => {
369
- this.funcCall.setParamValue(out.name, loadedRun.outputs[out.name]);
370
- });
371
- wu(this.funcCall.inputParams.values()).forEach((inp) => {
372
- this.funcCall.setParamValue(inp.name, loadedRun.inputs[inp.name]);
373
- });
374
- this.tabsElem.root.style.removeProperty('display');
375
- this.tabsElem.panes.forEach((tab) => {
376
- tab.header.style.removeProperty('display');
377
- });
378
- });
379
- }
380
- get isInputPanelRequired() {
381
- var _a;
382
- return ((_a = this.func) === null || _a === void 0 ? void 0 : _a.inputs.some((p) => p.propertyType == DG.TYPE.DATA_FRAME && p.options['viewer'] != null)) || false;
383
- }
384
- get tabsLabels() {
385
- return Object.keys(this.categoryToParamMap);
386
- }
387
- get categoryToParamMap() {
388
- const map = {};
389
- if (this.isInputPanelRequired) {
390
- this.func.inputs.
391
- filter((p) => p.propertyType == DG.TYPE.DATA_FRAME && p.options['viewer'] != null).
392
- forEach((p) => map['Input'] ? map['Input'].push(p) : map['Input'] = [p]);
393
- }
394
- this.func.outputs.forEach((p) => {
395
- const category = p.category === 'Misc' ? 'Output' : p.category;
396
- if (map[category])
397
- map[category].push(p);
398
- else
399
- map[category] = [p];
400
- });
401
- return map;
402
- }
403
- doRun() {
404
- return __awaiter(this, void 0, void 0, function* () {
405
- this.isRunning = true;
406
- this.checkDisability.next();
407
- try {
408
- yield this.run();
409
- }
410
- catch (e) {
411
- grok.shell.error(e);
412
- }
413
- finally {
414
- this.isRunning = false;
415
- this.checkDisability.next();
416
- }
417
- });
418
- }
419
- renderRunSection() {
420
- const runButton = ui.bigButton('Run', () => __awaiter(this, void 0, void 0, function* () { return yield this.doRun(); }));
421
- // REPLACE BY TYPE GUARD
422
- const isFuncScript = () => {
423
- //@ts-ignore
424
- return !!this.func.script;
425
- };
426
- // TO DO: move button somewhere
427
- const openScriptBtn = ui.button('Open script', () => __awaiter(this, void 0, void 0, function* () {
428
- window.open(`${window.location.origin}/script/${this.func.id}`, '_blank');
429
- }));
430
- // const buttonWrapper = ui.div([...this.options.isTabbed && isFuncScript() ? [openScriptBtn]: [], runButton]);
431
- const buttonWrapper = ui.div([runButton]);
432
- ui.tooltip.bind(buttonWrapper, () => runButton.disabled ? (this.isRunning ? 'Computations are in progress' : 'Some inputs are invalid') : '');
433
- const disabilitySub = this.checkDisability.subscribe(() => {
434
- const isValid = (wu(this.funcCall.inputs.values()).every((v) => v !== null && v !== undefined)) && !this.isRunning;
435
- runButton.disabled = !isValid;
436
- });
437
- this.subs.push(disabilitySub);
438
- const inputs = ui.divV([], 'ui-form');
439
- let prevCategory = 'Misc';
440
- wu(this.funcCall.inputParams.values())
441
- .filter((val) => !!val)
442
- .forEach((val) => {
443
- var _a, _b, _c;
444
- const prop = val.property;
445
- if (prop.propertyType.toString() === FILE_INPUT_TYPE) {
446
- const t = UiUtils.fileInput((_a = prop.caption) !== null && _a !== void 0 ? _a : prop.name, null, (file) => {
447
- this.funcCall.inputs[prop.name] = file;
448
- this.checkDisability.next();
449
- });
450
- if (prop.category !== prevCategory)
451
- inputs.append(ui.h2(prop.category));
452
- this.checkDisability.next();
453
- inputs.append(t.root);
454
- }
455
- else {
456
- let t = prop.propertyType === DG.TYPE.DATA_FRAME ?
457
- ui.tableInput((_b = prop.caption) !== null && _b !== void 0 ? _b : prop.name, null, grok.shell.tables) :
458
- ui.input.forProperty(prop);
459
- t.input.onkeydown = (ev) => __awaiter(this, void 0, void 0, function* () {
460
- if (ev.key == 'Enter')
461
- yield this.doRun();
462
- });
463
- t.captionLabel.firstChild.replaceWith(ui.span([(_c = prop.caption) !== null && _c !== void 0 ? _c : prop.name]));
464
- if (prop.options['units'])
465
- t.addPostfix(prop.options['units']);
466
- const subscribeOnFcChanges = () => {
467
- var _a, _b, _c, _d;
468
- t.value = (_b = (_a = this.funcCall.inputs[val.name]) !== null && _a !== void 0 ? _a : prop.defaultValue) !== null && _b !== void 0 ? _b : null;
469
- this.funcCall.inputs[val.name] = (_d = (_c = this.funcCall.inputs[val.name]) !== null && _c !== void 0 ? _c : prop.defaultValue) !== null && _d !== void 0 ? _d : null;
470
- };
471
- subscribeOnFcChanges();
472
- this.subs.push(this.funcCallReplaced.subscribe(subscribeOnFcChanges));
473
- t.onChanged(() => {
474
- // Resolving case of propertyType = DATAFRAME
475
- if (!!t.property)
476
- return;
477
- this.funcCall.inputs[val.name] = t.value;
478
- });
479
- t.onInput(() => {
480
- this.funcCall.inputs[val.name] = t.value;
481
- if (t.value === null)
482
- setTimeout(() => t.input.classList.add('d4-invalid'), 100);
483
- else
484
- t.input.classList.remove('d4-invalid');
485
- ;
486
- this.checkDisability.next();
487
- });
488
- const valChangeSub = val.onChanged.subscribe(() => {
489
- var _a;
490
- const newValue = this.funcCall.inputs[val.name];
491
- if (val.property.propertyType === DG.TYPE.DATA_FRAME) {
492
- // DEALING WITH BUG: https://reddata.atlassian.net/browse/GROK-12223
493
- const newTableInput = ui.tableInput((_a = prop.caption) !== null && _a !== void 0 ? _a : prop.name, newValue, [...grok.shell.tables, newValue]);
494
- t.root.replaceWith(newTableInput.root);
495
- t = newTableInput;
496
- t.onInput(() => {
497
- this.funcCall.inputs[val.name] = t.value;
498
- if (t.value === null)
499
- setTimeout(() => t.input.classList.add('d4-invalid'), 100);
500
- else
501
- t.input.classList.remove('d4-invalid');
502
- ;
503
- this.checkDisability.next();
504
- });
505
- }
506
- else {
507
- t.notify = false;
508
- t.value = newValue;
509
- t.notify = true;
510
- }
511
- this.checkDisability.next();
512
- });
513
- this.subs.push(valChangeSub);
514
- if (prop.category !== prevCategory)
515
- inputs.append(ui.h2(prop.category));
516
- if (t.value === null)
517
- runButton.disabled = true;
518
- inputs.append(t.root);
519
- }
520
- prevCategory = prop.category;
521
- });
522
- // @ts-ignore
523
- const buttons = ui.buttonsInput([buttonWrapper]);
524
- inputs.append(buttons);
525
- inputs.classList.remove('ui-panel');
526
- inputs.style.paddingTop = '0px';
527
- inputs.style.paddingLeft = '0px';
528
- return ui.div([inputs]);
529
- }
530
- }
531
- const getSheetName = (name, direction) => {
532
- const idealName = `${direction} - ${name}`;
533
- return (idealName.length > 31) ? name.substring(0, 32) : idealName;
534
- };
535
- var DIRECTION;
536
- (function (DIRECTION) {
537
- DIRECTION["INPUT"] = "Input";
538
- DIRECTION["OUTPUT"] = "Output";
539
- })(DIRECTION || (DIRECTION = {}));
540
- const scalarsToSheet = (sheet, scalars) => {
541
- sheet.addRow(['Parameter', 'Value', 'Units']).font = { bold: true };
542
- scalars.forEach((scalar) => {
543
- sheet.addRow([scalar.caption, scalar.value, scalar.units]);
544
- });
545
- sheet.getColumn(1).width = Math.max(...scalars.map((scalar) => scalar.caption.toString().length), 'Parameter'.length) * 1.2;
546
- sheet.getColumn(2).width = Math.max(...scalars.map((scalar) => scalar.value.toString().length), 'Value'.length) * 1.2;
547
- sheet.getColumn(3).width = Math.max(...scalars.map((scalar) => scalar.units.toString().length), 'Units'.length) * 1.2;
548
- };
549
- const dfToSheet = (sheet, df, column = 0, row = 0) => {
550
- for (let i = 0; i < df.columns.names().length; i++) {
551
- sheet.getCell(1 + row, 1 + i + column).value = df.columns.byIndex(i).name;
552
- sheet.getColumn(1 + i + column).width = Math.max(...df.columns.byIndex(i).categories.map((category) => category.toString().length), df.columns.byIndex(i).name.length) * 1.2;
553
- }
554
- for (let dfColumn = 0; dfColumn < df.columns.length; dfColumn++) {
555
- for (let i = 0; i < df.rowCount; i++)
556
- sheet.getCell(i + 2 + row, 1 + column + dfColumn).value = df.columns.byIndex(dfColumn).get(i);
557
- }
558
- };
559
- const plotToSheet = (exportWb, sheet, plot, columnForImage, rowForImage = 0) => __awaiter(void 0, void 0, void 0, function* () {
560
- const canvas = yield html2canvas(plot, { logging: false });
561
- const dataUrl = canvas.toDataURL('image/png');
562
- const imageId = exportWb.addImage({
563
- base64: dataUrl,
564
- extension: 'png',
565
- });
566
- sheet.addImage(imageId, {
567
- tl: { col: columnForImage, row: rowForImage },
568
- ext: { width: canvas.width, height: canvas.height },
569
- });
570
- });
571
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmljaC1mdW5jdGlvbi12aWV3LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmljaC1mdW5jdGlvbi12aWV3LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBLGdDQUFnQztBQUNoQyw0QkFBNEI7QUFDNUIsT0FBTyxLQUFLLElBQUksTUFBTSxtQkFBbUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3RDLE9BQU8sS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdEMsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQzdDLE9BQU8sT0FBTyxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLFdBQVcsTUFBTSxhQUFhLENBQUM7QUFDdEMsT0FBTyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3BCLE9BQU8sQ0FBQyxNQUFNLFVBQVUsQ0FBQztBQUN6QixPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUNyRCxPQUFPLCtCQUErQixDQUFDO0FBRXZDLDJEQUEyRDtBQUMzRCxNQUFNLGtCQUFrQixHQUE0QjtJQUNsRCxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUztJQUNqQyxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUTtJQUMvQixDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUTtJQUNoQyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUztJQUNqQyxDQUFDLGFBQWEsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsWUFBWTtJQUN2QyxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTztJQUM5QixDQUFDLE1BQU0s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Q0gsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUU7UUFDdEIsRUFBRSxFQUFFLEVBQUMsR0FBRyxFQUFFLGNBQWMsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFDO1FBQzNDLEdBQUcsRUFBRSxFQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFDO0tBQ2xELENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgdmFsaWQtanNkb2MgKi9cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cbmltcG9ydCAqIGFzIGdyb2sgZnJvbSAnZGF0YWdyb2stYXBpL2dyb2snO1xuaW1wb3J0ICogYXMgdWkgZnJvbSAnZGF0YWdyb2stYXBpL3VpJztcbmltcG9ydCAqIGFzIERHIGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5pbXBvcnQge0Z1bmN0aW9uVmlld30gZnJvbSAnLi9mdW5jdGlvbi12aWV3JztcbmltcG9ydCBFeGNlbEpTIGZyb20gJ2V4Y2VsanMnO1xuaW1wb3J0IGh0bWwyY2FudmFzIGZyb20gJ2h0bWwyY2FudmFzJztcbmltcG9ydCB3dSBmcm9tICd3dSc7XG5pbXBvcnQgJCBmcm9tICdjYXNoLWRvbSc7XG5pbXBvcnQge1N1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtVaVV0aWxzfSBmcm9tICcuL3NoYXJlZC1jb21wb25lbnRzL3VpLXV0aWxzJztcbmltcG9ydCAnLi4vY3NzL3JpY2gtZnVuY3Rpb24tdmlldy5jc3MnO1xuXG4vLyBtYXBwaW5nIGZyb20gaW50ZXJuYWwgRGFydCBsYWJlbHMgdG8gSlMgREcuVklFV0VSIGxhYmVsc1xuY29uc3Qgdmlld2VyVHlwZXNNYXBwaW5nOiB7W2tleTogc3RyaW5nXTogc3RyaW5nfSA9IHtcbiAgWydiYXJjaGFydCddOiBERy5WSUVXRVIuQkFSX0NIQVJULFxuICBbJ2JveHBsb3QnXTogREcuVklFV0VSLkJPWF9QTE9ULFxuICBbJ2NhbGVuZGFyJ106IERHLlZJRVdFUi5DQUxFTkRBUixcbiAgWydjb3JycGxvdCddOiBERy5WSUVXRVIuQ09SUl9QTE9ULFxuICBbJ2RlbnNpdHlwbG90J106IERHLlZJRVdFUi5ERU5TSVRZX1BMT1QsXG4gIFsnZmlsdGVycyddOiBERy5WSUVXRVIuRklMVEVSUyxcbiAgWydmb3JtJ106IERHLlZJRVdFUi5GT1JNLFxuICBbJ2dsb2JlJ106IERHLlZJRVdFUi5HTE9CRSxcbiAgWydnb29nbGVtYXAnXTogREcuVklFV0VSLkdPT0dMRV9NQVAsXG4gIFsnZ3JpZCddOiBERy5WSUVXRVIuR1JJRCxcbiAgWydoZWF0bWFwJ106IERHLlZJRVdFUi5IRUFUX01BUCxcbiAgWydoaXN0b2dyYW0nXTogREcuVklFV0VSLkhJU1RPR1JBTSxcbiAgWydsaW5lY2hhcnQnXTogREcuVklFV0VSLkxJTkVfQ0hBUlQsXG4gIFsnbWFya3VwJ106IERHLlZJRVdFUi5NQVJLVVAsXG4gIFsnbWF0cml4cGxvdCddOiBERy5WSUVXRVIuTUFUUklYX1BMT1QsXG4gIFsnbmV0d29ya2RpYWdyYW0nXTogREcuVklFV0VSLk5FVFdPUktfRElBR1JBTSxcbiAgWydwY3Bsb3QnXTogREcuVklFV0VSLlBDX1BMT1QsXG4gIFsncGllY2hhcnQnXTogREcuVklFV0VSLlBJRV9DSEFSVCxcbiAgWydzY2F0dGVycGxvdCddOiBERy5WSUVXRVIuU0NBVFRFUl9QTE9ULFxuICBbJ3NjYXR0ZXJwbG90M2QnXTogREcuVklFV0VSLlNDQVRURVJfUExPVF8zRCxcbiAgWydzaGFwZW1hcCddOiBERy5WSUVXRVIuU0hBUEVfTUFQLFxuICBbJ3N0YXRpc3RpY3MnXTogREcuVklFV0VSLlNUQVRJU1RJQ1MsXG4gIFsndGlsZXZpZXdlciddOiBERy5WSUVXRVIuVElMRV9WSUVXRVIsXG4gIFsndGltZWxpbmVzJ106IERHLlZJRVdFUi5USU1FTElORVMsXG4gIFsndHJlZW1hcCddOiBERy5WSUVXRVIuVFJFRV9NQVAsXG4gIFsndHJlbGxpc3Bsb3QnXTogREcuVklFV0VSLlRSRUxMSVNfUExPVCxcbiAgWyd3b3JkY2xvdWQnXTogREcuVklFV0VSLldPUkRfQ0xPVUQsXG59O1xuXG5jb25zdCBGSUxFX0lOUFVUX1RZUEUgPSAnZmlsZSc7XG5cbmV4cG9ydCBjbGFzcyBSaWNoRnVuY3Rpb25WaWV3IGV4dGVuZHMgRnVuY3Rpb25WaWV3IHtcbiAgLy8gZW1pdHRlZCB3aGVuIHJ1bkJ1dHRvbiBkaXNhYmlsaXR5IHNob3VsZCBiZSBjaGVja2VkXG4gIHByaXZhdGUgY2hlY2tEaXNhYmlsaXR5ID0gbmV3IFN1YmplY3QoKTtcblxuICAvLyBzdG9yZXMgdGhlIHJ1bm5pbmcgc3RhdGVcbiAgcHJpdmF0ZSBpc1J1bm5pbmcgPSBmYWxzZTtcblxuICBzdGF0aWMgZnJvbUZ1bmNDYWxsKFxuICAgIGZ1bmNDYWxsOiBERy5GdW5jQ2FsbCxcbiAgICBvcHRpb25zOiB7aGlzdG9yeUVuYWJsZWQ6IGJvb2xlYW4sIGlzVGFiYmVkOiBib29sZWFufSA9XG4gICAge2hpc3RvcnlFbmFibGVkOiB0cnVlLCBpc1RhYmJlZDogZmFsc2V9XG4gICkge1xuICAgIHJldHVybiBuZXcgdGhpcyhmdW5jQ2FsbC5mdW5jLm5xTmFtZSwgb3B0aW9ucyk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBmdW5jTmFtZTogc3RyaW5nLFxuICAgIHB1YmxpYyBvcHRpb25zOiB7IGhpc3RvcnlFbmFibGVkOiBib29sZWFuLCBpc1RhYmJlZDogYm9vbGVhbn0gPVxuICAgIHtoaXN0b3J5RW5hYmxlZDogdHJ1ZSwgaXNUYWJiZWQ6IGZhbHNlfVxuICApIHtcbiAgICBzdXBlcihmdW5jTmFtZSwgb3B0aW9ucyk7XG5cbiAgICB0aGlzLnN1YnMucHVzaChcbiAgICAgIHRoaXMub25GdW5jQ2FsbFJlYWR5LnN1YnNjcmliZSh7XG4gICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5iYXNlUGF0aCA9IGBzY3JpcHRzLyR7dGhpcy5mdW5jQ2FsbC5mdW5jLmlkfS92aWV3YDtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFNob3dpbmcgVUkgYWZ0ZXIgY29tcGxldGlvbiBvZiBmdW5jdGlvbiBjYWxsLlxuICAgKiBAcGFyYW0gcnVuRnVuY1xuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIG9uQWZ0ZXJSdW4ocnVuRnVuYzogREcuRnVuY0NhbGwpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnRhYnNFbGVtLnJvb3Quc3R5bGUucmVtb3ZlUHJvcGVydHkoJ2Rpc3BsYXknKTtcbiAgICB0aGlzLnRhYnNFbGVtLnBhbmVzLmZvckVhY2goKHRhYikgPT4ge1xuICAgICAgdGFiLmhlYWRlci5zdHlsZS5yZW1vdmVQcm9wZXJ0eSgnZGlzcGxheScpO1xuICAgIH0pO1xuICAgIGNvbnN0IGZpcnN0T3V0cHV0VGFiID0gdGhpcy50YWJzRWxlbS5wYW5lcy5maW5kKCh0YWIpID0+IHRhYi5uYW1lICE9PSAnSW5wdXQnKTtcbiAgICBpZiAoZmlyc3RPdXRwdXRUYWIpIHRoaXMudGFic0VsZW0uY3VycmVudFBhbmUgPSBmaXJzdE91dHB1dFRhYjtcblxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSaWNoRnVuY3Rpb25WaWV3IGhhcyBhZGF2YW5jZWQgYXV0b21hdGljIFVJIGJ1aWxkZXIuIEl0IHRha2VzIHtAbGluayB0aGlzLmZ1bmNDYWxsfSBhcyBhIGJhc2UgYW5kIGNvbnN0cnVjdHMgZmxleGlibGUgdmlldy5cbiAgICogVGhpcyB2aWV3IGlzIHVwZGF0ZWQgYXV0b21hdGljYWxseSB3aGVuIHtAbGluayB0aGlzLmZ1bmNDYWxsUmVwbGFjZWR9IGlzIGVtaXR0ZWQgb3IgYW55IG9mIGlucHV0L291dHB1dCBwYXJhbSBjaGFuZ2VzLlxuICAgKiBAcmV0dXJucyBIVE1MRWxlbWVudCBhdHRhY2hlZCB0byB0aGUgcm9vdCBvZiB0aGUgdmlld1xuICAgKi9cbiAgcHVibGljIGJ1aWxkSU8oKTogSFRNTEVsZW1lbnQge1xuICAgIGNvbnN0IGlucHV0QmxvY2sgPSB0aGlzLmJ1aWxkSW5wdXRCbG9jaygpO1xuXG4gICAgdWkudG9vbHMuaGFuZGxlUmVzaXplKGlucHV0QmxvY2ssICh3aWR0aCkgPT4ge1xuICAgICAgaWYgKHdpZHRoIDwgMzUwKVxuICAgICAgICAkKGlucHV0QmxvY2suZmlyc3RDaGlsZCEpLmFkZENsYXNzKCd1aS1mb3JtLWNvbmRlbnNlZCcpO1xuICAgICAgZWxzZVxuICAgICAgICAkKGlucHV0QmxvY2suZmlyc3RDaGlsZCEpLnJlbW92ZUNsYXNzKCd1aS1mb3JtLWNvbmRlbnNlZCcpO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgb3V0cHV0QmxvY2sgPSB0aGlzLmJ1aWxkT3V0cHV0QmxvY2soKTtcbiAgICBvdXRwdXRCbG9jay5zdHlsZS5oZWlnaHQgPSAnMTAwJSc7XG4gICAgb3V0cHV0QmxvY2suc3R5bGUud2lkdGggPSAnMTAwJSc7XG4gICAgdGhpcy50YWJzRWxlbS5yb290LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cbiAgICBpZiAoISF0aGlzLnRhYnNFbGVtLmdldFBhbmUoJ0lucHV0JykpIHtcbiAgICAgIHRoaXMudGFic0VsZW0ucGFuZXMuZm9yRWFjaCgodGFiKSA9PiB7XG4gICAgICAgIHRhYi5oZWFkZXIuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IG91dCA9IHVpLnNwbGl0SChbaW5wdXRCbG9jaywgdWkucGFuZWwoW291dHB1dEJsb2NrXSwge3N0eWxlOiB7J3BhZGRpbmctdG9wJzogJzBweCd9fSldLCBudWxsLCB0cnVlKTtcbiAgICBvdXQuc3R5bGUucGFkZGluZyA9ICcwIDEycHgnO1xuXG4gICAgaW5wdXRCbG9jay5wYXJlbnRFbGVtZW50IS5zdHlsZS5tYXhXaWR0aCA9ICc0NTBweCc7XG5cbiAgICByZXR1cm4gb3V0O1xuICB9XG5cbiAgcHVibGljIGJ1aWxkSW5wdXRCbG9jaygpOiBIVE1MRWxlbWVudCB7XG4gICAgY29uc3QgZm9ybURpdiA9IHRoaXMucmVuZGVyUnVuU2VjdGlvbigpO1xuXG4gICAgcmV0dXJuIGZvcm1EaXY7XG4gIH1cblxuICBidWlsZFJpYmJvblBhbmVscygpOiBIVE1MRWxlbWVudFtdW10ge1xuICAgIHN1cGVyLmJ1aWxkUmliYm9uUGFuZWxzKCk7XG5cbiAgICBjb25zdCBwbGF5ID0gdWkuaWNvbkZBKCdwbGF5JywgYXN5bmMgKCkgPT4gYXdhaXQgdGhpcy5kb1J1bigpKTtcbiAgICBwbGF5LmNsYXNzTGlzdC5hZGQoJ2ZhcycpO1xuXG4gICAgY29uc3QgbmV3UmliYm9uUGFuZWxzID0gW1xuICAgICAgLi4udGhpcy5nZXRSaWJib25QYW5lbHMoKSxcbiAgICAgIFtwbGF5XSxcbiAgICBdO1xuXG4gICAgdGhpcy5zZXRSaWJib25QYW5lbHMobmV3UmliYm9uUGFuZWxzKTtcbiAgICByZXR1cm4gbmV3UmliYm9uUGFuZWxzO1xuICB9XG5cbiAgLy8gTWFpbiBlbGVtZW50IG9mIHRoZSBvdXRwdXQgYmxvY2suIFN0b3JlcyBhbGwgdGhlIHRhYnMgZm9yIHRoZSBvdXRwdXQgYW5kIGlucHV0XG4gIHByaXZhdGUgdGFic0VsZW0gPSB1aS50YWJDb250cm9sKCk7XG5cbiAgcHVibGljIGJ1aWxkT3V0cHV0QmxvY2soKTogSFRNTEVsZW1lbnQge1xuICAgIHRoaXMudGFic0VsZW0ucm9vdC5zdHlsZS53aWR0aCA9ICcxMDAlJztcblxuICAgIHRoaXMudGFic0xhYmVscy5mb3JFYWNoKCh0YWJMYWJlbCkgPT4ge1xuICAgICAgY29uc3QgdGFiRGZQcm9wcyA9IHRoaXMuY2F0ZWdvcnlUb1BhcmFtTWFwW3RhYkxhYmVsXS5maWx0ZXIoKHApID0+IHAucHJvcGVydHlUeXBlID09PSBERy5UWVBFLkRBVEFfRlJBTUUpO1xuICAgICAgY29uc3QgdGFiU2NhbGFyUHJvcHMgPSB0aGlzLmNhdGVnb3J5VG9QYXJhbU1hcFt0YWJMYWJlbF0uZmlsdGVyKChwKSA9PiBwLnByb3BlcnR5VHlwZSAhPT0gREcuVFlQRS5EQVRBX0ZSQU1FKTtcblxuICAgICAgLy8gZGZQcm9wLm9wdGlvbnNbJ3ZpZXdlciddIGNvdWxkIGJlIGVtcHR5LCBzbyB3ZSBuZWVkIHRvIGNoZWNrIGl0XG4gICAgICBjb25zdCBwYXJzZWRUYWJEZlByb3BzID0gdGFiRGZQcm9wcy5tYXAoKGRmUHJvcCkgPT4gKGRmUHJvcC5vcHRpb25zWyd2aWV3ZXInXSAhPT0gdW5kZWZpbmVkKSA/XG4gICAgICAgIC8vIHRydWUgYW5kIGZhbHNlIHZhbHVlcyBhcmUgcmV0cmlldmVkIGFzIHN0cmluZywgc28gd2UgY2FsbCBKU09OLnBhcnNlIG9uIHRoZW0gb25jZSBtb3JlXG4gICAgICAgIEpTT04ucGFyc2UoZGZQcm9wLm9wdGlvbnNbJ3ZpZXdlciddLCAoXywgdikgPT4gdiA9PT0gJ3RydWUnIHx8IHYgPT09ICdmYWxzZScgPyBKU09OLnBhcnNlKHYpOiB2KTpcbiAgICAgICAgW10pO1xuXG4gICAgICBjb25zdCBkZkJsb2NrcyA9IHRhYkRmUHJvcHMubWFwKChkZlByb3AsIGRmSW5kZXgpID0+IHtcbiAgICAgICAgbGV0IGZ1bGxCbG9ja1dpZHRoID0gMDtcbiAgICAgICAgcGFyc2VkVGFiRGZQcm9wc1tkZkluZGV4XS5mb3JFYWNoKChfOiBhbnksIHZpZXdlckluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICBjb25zdCBibG9ja1NpemUgPSBwYXJzZWRUYWJEZlByb3BzW2RmSW5kZXhdW3ZpZXdlckluZGV4XVsnYmxvY2snXTtcblxuICAgICAgICAgIGZ1bGxCbG9ja1dpZHRoICs9IGJsb2NrU2l6ZSA/IHBhcnNlSW50KGJsb2NrU2l6ZSk6IDA7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHZpZXdlcnM6IFByb21pc2U8REcuVmlld2VyW10+ID0gUHJvbWlzZS5hbGwocGFyc2VkVGFiRGZQcm9wc1tkZkluZGV4XS5tYXAoYXN5bmMgKHZpZXdlckRlc2M6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9KSA9PiB7XG4gICAgICAgICAgY29uc3QgaW5pdGlhbFZhbHVlOiBERy5EYXRhRnJhbWUgPSB0aGlzLmZ1bmNDYWxsPy5vdXRwdXRzW2RmUHJvcC5uYW1lXT8udmFsdWUgPz8gdGhpcy5mdW5jQ2FsbCEuaW5wdXRQYXJhbXNbZGZQcm9wLm5hbWVdPy52YWx1ZSA/PyBncm9rLmRhdGEuZGVtby5kZW1vZygxKTtcblxuICAgICAgICAgIGNvbnN0IHZpZXdlciA9IHZpZXdlclR5cGVzTWFwcGluZ1t2aWV3ZXJEZXNjWyd0eXBlJ11dID8gREcuVmlld2VyLmZyb21UeXBlKHZpZXdlclR5cGVzTWFwcGluZ1t2aWV3ZXJEZXNjWyd0eXBlJ11dLCBpbml0aWFsVmFsdWUpOiBhd2FpdCBpbml0aWFsVmFsdWUucGxvdC5mcm9tVHlwZSh2aWV3ZXJEZXNjWyd0eXBlJ10pIGFzIERHLlZpZXdlcjtcbiAgICAgICAgICB2aWV3ZXIuc2V0T3B0aW9ucyh2aWV3ZXJEZXNjKTtcblxuICAgICAgICAgIGlmICh0aGlzLmRmVG9WaWV3ZXJNYXBwaW5nW2RmUHJvcC5uYW1lXSkgdGhpcy5kZlRvVmlld2VyTWFwcGluZ1tkZlByb3AubmFtZV0ucHVzaCh2aWV3ZXIpOyBlbHNlIHRoaXMuZGZUb1ZpZXdlck1hcHBpbmdbZGZQcm9wLm5hbWVdID0gW3ZpZXdlcl07XG5cbiAgICAgICAgICByZXR1cm4gdmlld2VyO1xuICAgICAgICB9KSk7XG5cbiAgICAgICAgdmlld2Vycy50aGVuKChsb2FkZWRWaWV3ZXJzKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc3Vic2NyaWJlT25GY0NoYW5nZXMgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50UGFyYW06IERHLkZ1bmNDYWxsUGFyYW0gPSB0aGlzLmZ1bmNDYWxsIS5vdXRwdXRQYXJhbXNbZGZQcm9wLm5hbWVdID8/IHRoaXMuZnVuY0NhbGwhLmlucHV0UGFyYW1zW2RmUHJvcC5uYW1lXTtcblxuICAgICAgICAgICAgY29uc3QgcGFyYW1TdWIgPSBjdXJyZW50UGFyYW0ub25DaGFuZ2VkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgIGxvYWRlZFZpZXdlcnMuZm9yRWFjaChhc3luYyAodmlld2VyKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKE9iamVjdC52YWx1ZXModmlld2VyVHlwZXNNYXBwaW5nKS5pbmNsdWRlcyh2aWV3ZXIudHlwZSkpIHtcbiAgICAgICAgICAgICAgICAgIHZpZXdlci5kYXRhRnJhbWUgPSBjdXJyZW50UGFyYW0udmFsdWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIC8vIFVzZXItZGVmaW5lZCB2aWV3ZXJzIChlLmcuIE91dGxpZXJzU2VsZWN0aW9uVmlld2VyKSBjb3VsZCBjcmVhdGVkIG9ubHkgYXN5bmNocm9ub3VzbHlcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZpZXdlciA9IGF3YWl0IGN1cnJlbnRQYXJhbS52YWx1ZS5wbG90LmZyb21UeXBlKHZpZXdlci50eXBlKSBhcyBERy5WaWV3ZXI7XG4gICAgICAgICAgICAgICAgICB2aWV3ZXIucm9vdC5yZXBsYWNlV2l0aChuZXdWaWV3ZXIucm9vdCk7XG4gICAgICAgICAgICAgICAgICB2aWV3ZXIgPSBuZXdWaWV3ZXI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLnN1YnMucHVzaChwYXJhbVN1Yik7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHN1YnNjcmliZU9uRmNDaGFuZ2VzKCk7XG4gICAgICAgICAgdGhpcy5zdWJzLnB1c2goXG4gICAgICAgICAgICB0aGlzLmZ1bmNDYWxsUmVwbGFjZWQuc3Vic2NyaWJlKHN1YnNjcmliZU9uRmNDaGFuZ2VzKVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGRmQmxvY2tUaXRsZTogc3RyaW5nID0gZGZQcm9wLm9wdGlvbnNbJ2NhcHRpb24nXSA/PyBkZlByb3AubmFtZTtcblxuICAgICAgICBjb25zdCBkZkJsb2NrID0gdWkud2FpdChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgbG9hZGVkVmlld2VycyA9IGF3YWl0IHZpZXdlcnM7XG4gICAgICAgICAgcmV0dXJuIHVpLmRpdkgoXG4gICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICAgICAgbG9hZGVkVmlld2Vycy5tYXAoKHZpZXdlcikgPT4gdmlld2VyLnJvb3QsIHtzdHlsZTogeydmbGV4LXdyYXAnOiAnd3JhcCd9fSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodGFiTGFiZWwgPT09ICdJbnB1dCcpIHtcbiAgICAgICAgICBjb25zdCBzdWJzY3JpYmVPbkZjQ2hhbmdlcyA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRQYXJhbTogREcuRnVuY0NhbGxQYXJhbSA9IHRoaXMuZnVuY0NhbGwhLm91dHB1dFBhcmFtc1tkZlByb3AubmFtZV0gPz8gdGhpcy5mdW5jQ2FsbCEuaW5wdXRQYXJhbXNbZGZQcm9wLm5hbWVdO1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbVN1YiA9IGN1cnJlbnRQYXJhbS5vbkNoYW5nZWQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy50YWJzRWxlbS5yb290LnN0eWxlLnJlbW92ZVByb3BlcnR5KCdkaXNwbGF5Jyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGhpcy5zdWJzLnB1c2gocGFyYW1TdWIpO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICBzdWJzY3JpYmVPbkZjQ2hhbmdlcygpO1xuICAgICAgICAgIHRoaXMuc3Vicy5wdXNoKFxuICAgICAgICAgICAgdGhpcy5mdW5jQ2FsbFJlcGxhY2VkLnN1YnNjcmliZShzdWJzY3JpYmVPbkZjQ2hhbmdlcylcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHVpLmRpdlYoW1xuICAgICAgICAgIC8vIFJlbW92aW5nIHRpdGxlIG1hcmdpbiBvbiB0b3Agb2YgYmxvY2sgdGl0bGVzXG4gICAgICAgICAgdWkuaDIoZGZCbG9ja1RpdGxlLCB7Li4uKGRmSW5kZXggPiAwKSA/IHtzdHlsZTogeydtYXJnaW4tdG9wJzogJzBweCd9fSA6IHt9fSksXG4gICAgICAgICAgZGZCbG9ja1xuICAgICAgICBdLCB7c3R5bGU6IHsuLi4oZnVsbEJsb2NrV2lkdGggPiAwKSA/IHsnd2lkdGgnOiBgJHtmdWxsQmxvY2tXaWR0aH0lYH06IHsnd2lkdGgnOiBgMTAwJWB9fX0pO1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGdlbmVyYXRlU2NhbGFyc1RhYmxlID0gKCkgPT4ge1xuICAgICAgICBjb25zdCB0YWJsZSA9IERHLkh0bWxUYWJsZS5jcmVhdGUoXG4gICAgICAgICAgdGFiU2NhbGFyUHJvcHMsXG4gICAgICAgICAgKHNjYWxhclByb3A6IERHLlByb3BlcnR5KSA9PiBbc2NhbGFyUHJvcC5uYW1lLCB0aGlzLmZ1bmNDYWxsPy5vdXRwdXRzW3NjYWxhclByb3AubmFtZV0sIHNjYWxhclByb3Aub3B0aW9uc1sndW5pdHMnXV1cbiAgICAgICAgKS5yb290O1xuICAgICAgICB0YWJsZS5zdHlsZS5tYXhXaWR0aCA9ICc0MDBweCc7XG4gICAgICAgIHJldHVybiB0YWJsZTtcbiAgICAgIH07XG5cbiAgICAgIGxldCBzY2FsYXJzVGFibGUgPSBnZW5lcmF0ZVNjYWxhcnNUYWJsZSgpO1xuXG4gICAgICB0YWJTY2FsYXJQcm9wcy5mb3JFYWNoKCh0YWJTY2FsYXJQcm9wKSA9PiB7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZU9uRmNDaGFuZ2VzID0gKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHBhcmFtU3ViID0gKHRoaXMuZnVuY0NhbGwhLm91dHB1dFBhcmFtc1t0YWJTY2FsYXJQcm9wLm5hbWVdIGFzIERHLkZ1bmNDYWxsUGFyYW0pLm9uQ2hhbmdlZC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbmV3U2NhbGFyc1RhYmxlID0gZ2VuZXJhdGVTY2FsYXJzVGFibGUoKTtcbiAgICAgICAgICAgIHNjYWxhcnNUYWJsZS5yZXBsYWNlV2l0aChuZXdTY2FsYXJzVGFibGUpO1xuICAgICAgICAgICAgc2NhbGFyc1RhYmxlID0gbmV3U2NhbGFyc1RhYmxlO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgdGhpcy5zdWJzLnB1c2gocGFyYW1TdWIpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHN1YnNjcmliZU9uRmNDaGFuZ2VzKCk7XG4gICAgICAgIHRoaXMuc3Vicy5wdXNoKFxuICAgICAgICAgIHRoaXMuZnVuY0NhbGxSZXBsYWNlZC5zdWJzY3JpYmUoc3Vic2NyaWJlT25GY0NoYW5nZXMpXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgZGZTZWN0aW9ucyA9IFtdIGFzIEhUTUxFbGVtZW50W107XG4gICAgICBsZXQgY3VycmVudFdpZHRoID0gMDtcbiAgICAgIGxldCBjdXJyZW50U2VjdGlvbiA9IHVpLmRpdkgoW10sIHtzdHlsZTogeydtYXJnaW4tYm90dG9tJzogJzI1cHgnfX0pOyAvLyBBZGRpbmcgc21hbGwgbWFyZ2luIGJldHdlZW4gc2VjdGlvbnNcbiAgICAgIGRmQmxvY2tzLmZvckVhY2goKGRmQmxvY2ssIGRmSW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgYmxvY2tXaWR0aCA9IHBhcnNlSW50KGRmQmxvY2suc3R5bGUud2lkdGgpO1xuXG4gICAgICAgIGlmIChjdXJyZW50V2lkdGggKyBibG9ja1dpZHRoID09PSAxMDApIHtcbiAgICAgICAgICBjdXJyZW50U2VjdGlvbi5hcHBlbmQoZGZCbG9jayk7XG4gICAgICAgICAgZGZTZWN0aW9ucy5wdXNoKGN1cnJlbnRTZWN0aW9uKTtcbiAgICAgICAgICBjdXJyZW50U2VjdGlvbiA9IHVpLmRpdkgoW10pO1xuICAgICAgICAgIGN1cnJlbnRXaWR0aCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoY3VycmVudFdpZHRoICsgYmxvY2tXaWR0aCA8IDEwMCkge1xuICAgICAgICAgIGN1cnJlbnRTZWN0aW9uLmFwcGVuZChkZkJsb2NrKTtcbiAgICAgICAgICBjdXJyZW50V2lkdGggKz0gYmxvY2tXaWR0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZlNlY3Rpb25zLnB1c2goY3VycmVudFNlY3Rpb24pO1xuICAgICAgICAgIGN1cnJlbnRTZWN0aW9uID0gdWkuZGl2SChbXSk7XG4gICAgICAgICAgY3VycmVudFNlY3Rpb24uYXBwZW5kKGRmQmxvY2spO1xuICAgICAgICAgIGN1cnJlbnRXaWR0aCA9IGJsb2NrV2lkdGg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGZJbmRleCA9PT0gZGZCbG9ja3MubGVuZ3RoIC0gMSlcbiAgICAgICAgICBkZlNlY3Rpb25zLnB1c2goY3VycmVudFNlY3Rpb24pO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMudGFic0VsZW0uYWRkUGFuZSh0YWJMYWJlbCwgKCkgPT4ge1xuICAgICAgICByZXR1cm4gdWkuZGl2VihbLi4uZGZTZWN0aW9ucywgLi4udGFiU2NhbGFyUHJvcHMubGVuZ3RoID8gW3VpLmgyKCdTY2FsYXIgdmFsdWVzJyldOiBbXSwgc2NhbGFyc1RhYmxlXSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGNvbnN0IG91dHB1dEJsb2NrID0gdWkuYm94KCk7XG4gICAgb3V0cHV0QmxvY2suYXBwZW5kKHRoaXMudGFic0VsZW0ucm9vdCk7XG5cbiAgICByZXR1cm4gb3V0cHV0QmxvY2s7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgb25BZnRlckxvYWRSdW4obG9hZGVkUnVuOiBERy5GdW5jQ2FsbCkge1xuICAgIHd1KHRoaXMuZnVuY0NhbGwhLm91dHB1dFBhcmFtcy52YWx1ZXMoKSBhcyBERy5GdW5jQ2FsbFBhcmFtW10pLmZvckVhY2goKG91dCkgPT4ge1xuICAgICAgdGhpcy5mdW5jQ2FsbCEuc2V0UGFyYW1WYWx1ZShvdXQubmFtZSwgbG9hZGVkUnVuLm91dHB1dHNbb3V0Lm5hbWVdKTtcbiAgICB9KTtcblxuICAgIHd1KHRoaXMuZnVuY0NhbGwhLmlucHV0UGFyYW1zLnZhbHVlcygpIGFzIERHLkZ1bmNDYWxsUGFyYW1bXSkuZm9yRWFjaCgoaW5wKSA9PiB7XG4gICAgICB0aGlzLmZ1bmNDYWxsIS5zZXRQYXJhbVZhbHVlKGlucC5uYW1lLCBsb2FkZWRSdW4uaW5wdXRzW2lucC5uYW1lXSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnRhYnNFbGVtLnJvb3Quc3R5bGUucmVtb3ZlUHJvcGVydHkoJ2Rpc3BsYXknKTtcbiAgICB0aGlzLnRhYnNFbGVtLnBhbmVzLmZvckVhY2goKHRhYikgPT4ge1xuICAgICAgdGFiLmhlYWRlci5zdHlsZS5yZW1vdmVQcm9wZXJ0eSgnZGlzcGxheScpO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gU3RvcmVzIG1hcHBpbmcgYmV0d2VlbiBERiBhbmQgaXRzJyB2aWV3ZXJzXG4gIHByaXZhdGUgZGZUb1ZpZXdlck1hcHBpbmc6IHtba2V5OiBzdHJpbmddOiBERy5WaWV3ZXJbXX0gPSB7fTtcblxuICBwcm90ZWN0ZWQgZ2V0IGlzSW5wdXRQYW5lbFJlcXVpcmVkKCkge1xuICAgIHJldHVybiB0aGlzLmZ1bmM/LmlucHV0cy5zb21lKChwKSA9PiBwLnByb3BlcnR5VHlwZSA9PSBERy5UWVBFLkRBVEFfRlJBTUUgJiYgcC5vcHRpb25zWyd2aWV3ZXInXSAhPSBudWxsKSB8fCBmYWxzZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXQgdGFic0xhYmVscygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5jYXRlZ29yeVRvUGFyYW1NYXApO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldCBjYXRlZ29yeVRvUGFyYW1NYXAoKSB7XG4gICAgY29uc3QgbWFwID0ge30gYXMgUmVjb3JkPHN0cmluZywgREcuUHJvcGVydHlbXT47XG5cbiAgICBpZiAodGhpcy5pc0lucHV0UGFuZWxSZXF1aXJlZCkge1xuICAgICAgdGhpcy5mdW5jIS5pbnB1dHMuXG4gICAgICAgIGZpbHRlcigocCkgPT4gcC5wcm9wZXJ0eVR5cGUgPT0gREcuVFlQRS5EQVRBX0ZSQU1FICYmIHAub3B0aW9uc1sndmlld2VyJ10gIT0gbnVsbCkuXG4gICAgICAgIGZvckVhY2goKHApID0+IG1hcFsnSW5wdXQnXSA/IG1hcFsnSW5wdXQnXS5wdXNoKHApOiBtYXBbJ0lucHV0J10gPSBbcF0pO1xuICAgIH1cblxuICAgIHRoaXMuZnVuYyEub3V0cHV0cy5mb3JFYWNoKChwKSA9PiB7XG4gICAgICBjb25zdCBjYXRlZ29yeSA9IHAuY2F0ZWdvcnkgPT09ICdNaXNjJyA/ICdPdXRwdXQnOiBwLmNhdGVnb3J5O1xuXG4gICAgICBpZiAobWFwW2NhdGVnb3J5XSlcbiAgICAgICAgbWFwW2NhdGVnb3J5XS5wdXNoKHApO1xuICAgICAgZWxzZVxuICAgICAgICBtYXBbY2F0ZWdvcnldID0gW3BdO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIG1hcDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZG9SdW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5pc1J1bm5pbmcgPSB0cnVlO1xuICAgIHRoaXMuY2hlY2tEaXNhYmlsaXR5Lm5leHQoKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5ydW4oKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGdyb2suc2hlbGwuZXJyb3IoZSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuaXNSdW5uaW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmNoZWNrRGlzYWJpbGl0eS5uZXh0KCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJSdW5TZWN0aW9uKCk6IEhUTUxFbGVtZW50IHtcbiAgICBjb25zdCBydW5CdXR0b24gPSB1aS5iaWdCdXR0b24oJ1J1bicsIGFzeW5jICgpID0+IGF3YWl0IHRoaXMuZG9SdW4oKSk7XG4gICAgLy8gUkVQTEFDRSBCWSBUWVBFIEdVQVJEXG4gICAgY29uc3QgaXNGdW5jU2NyaXB0ID0gKCkgPT4ge1xuICAgICAgLy9AdHMtaWdub3JlXG4gICAgICByZXR1cm4gISF0aGlzLmZ1bmMuc2NyaXB0O1xuICAgIH07XG4gICAgLy8gVE8gRE86IG1vdmUgYnV0dG9uIHNvbWV3aGVyZVxuICAgIGNvbnN0IG9wZW5TY3JpcHRCdG4gPSB1aS5idXR0b24oJ09wZW4gc2NyaXB0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgd2luZG93Lm9wZW4oYCR7d2luZG93LmxvY2F0aW9uLm9yaWdpbn0vc2NyaXB0LyR7KHRoaXMuZnVuYyBhcyBERy5TY3JpcHQpLmlkfWAsICdfYmxhbmsnKTtcbiAgICB9KTtcbiAgICAvLyBjb25zdCBidXR0b25XcmFwcGVyID0gdWkuZGl2KFsuLi50aGlzLm9wdGlvbnMuaXNUYWJiZWQgJiYgaXNGdW5jU2NyaXB0KCkgPyBbb3BlblNjcmlwdEJ0bl06IFtdLCBydW5CdXR0b25dKTtcbiAgICBjb25zdCBidXR0b25XcmFwcGVyID0gdWkuZGl2KFtydW5CdXR0b25dKTtcbiAgICB1aS50b29sdGlwLmJpbmQoYnV0dG9uV3JhcHBlciwgKCkgPT4gcnVuQnV0dG9uLmRpc2FibGVkID8gKHRoaXMuaXNSdW5uaW5nID8gJ0NvbXB1dGF0aW9ucyBhcmUgaW4gcHJvZ3Jlc3MnIDogJ1NvbWUgaW5wdXRzIGFyZSBpbnZhbGlkJykgOiAnJyk7XG5cbiAgICBjb25zdCBkaXNhYmlsaXR5U3ViID0gdGhpcy5jaGVja0Rpc2FiaWxpdHkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGNvbnN0IGlzVmFsaWQgPSAod3UodGhpcy5mdW5jQ2FsbCEuaW5wdXRzLnZhbHVlcygpKS5ldmVyeSgodikgPT4gdiAhPT0gbnVsbCAmJiB2ICE9PSB1bmRlZmluZWQpKSAmJiAhdGhpcy5pc1J1bm5pbmc7XG4gICAgICBydW5CdXR0b24uZGlzYWJsZWQgPSAhaXNWYWxpZDtcbiAgICB9KTtcbiAgICB0aGlzLnN1YnMucHVzaChkaXNhYmlsaXR5U3ViKTtcblxuICAgIGNvbnN0IGlucHV0cyA9IHVpLmRpdlYoW10sICd1aS1mb3JtJyk7XG4gICAgbGV0IHByZXZDYXRlZ29yeSA9ICdNaXNjJztcbiAgICB3dSh0aGlzLmZ1bmNDYWxsIS5pbnB1dFBhcmFtcy52YWx1ZXMoKSBhcyBERy5GdW5jQ2FsbFBhcmFtW10pXG4gICAgICAuZmlsdGVyKCh2YWwpID0+ICEhdmFsKVxuICAgICAgLmZvckVhY2goKHZhbCkgPT4ge1xuICAgICAgICBjb25zdCBwcm9wID0gdmFsLnByb3BlcnR5O1xuICAgICAgICBpZiAocHJvcC5wcm9wZXJ0eVR5cGUudG9TdHJpbmcoKSA9PT0gRklMRV9JTlBVVF9UWVBFKSB7XG4gICAgICAgICAgY29uc3QgdCA9IFVpVXRpbHMuZmlsZUlucHV0KHByb3AuY2FwdGlvbiA/PyBwcm9wLm5hbWUsIG51bGwsIChmaWxlOiBGaWxlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZ1bmNDYWxsIS5pbnB1dHNbcHJvcC5uYW1lXSA9IGZpbGU7XG4gICAgICAgICAgICB0aGlzLmNoZWNrRGlzYWJpbGl0eS5uZXh0KCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKHByb3AuY2F0ZWdvcnkgIT09IHByZXZDYXRlZ29yeSlcbiAgICAgICAgICAgIGlucHV0cy5hcHBlbmQodWkuaDIocHJvcC5jYXRlZ29yeSkpO1xuXG4gICAgICAgICAgdGhpcy5jaGVja0Rpc2FiaWxpdHkubmV4dCgpO1xuICAgICAgICAgIGlucHV0cy5hcHBlbmQodC5yb290KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsZXQgdCA9IHByb3AucHJvcGVydHlUeXBlID09PSBERy5UWVBFLkRBVEFfRlJBTUUgP1xuICAgICAgICAgICAgdWkudGFibGVJbnB1dChwcm9wLmNhcHRpb24gPz8gcHJvcC5uYW1lLCBudWxsLCBncm9rLnNoZWxsLnRhYmxlcyk6XG4gICAgICAgICAgICB1aS5pbnB1dC5mb3JQcm9wZXJ0eShwcm9wKTtcblxuICAgICAgICAgIHQuaW5wdXQub25rZXlkb3duID0gYXN5bmMgKGV2KSA9PiB7XG4gICAgICAgICAgICBpZiAoZXYua2V5ID09ICdFbnRlcicpXG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuZG9SdW4oKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgdC5jYXB0aW9uTGFiZWwuZmlyc3RDaGlsZCEucmVwbGFjZVdpdGgodWkuc3BhbihbcHJvcC5jYXB0aW9uID8/IHByb3AubmFtZV0pKTtcbiAgICAgICAgICBpZiAocHJvcC5vcHRpb25zWyd1bml0cyddKSB0LmFkZFBvc3RmaXgocHJvcC5vcHRpb25zWyd1bml0cyddKTtcblxuICAgICAgICAgIGNvbnN0IHN1YnNjcmliZU9uRmNDaGFuZ2VzID0gKCkgPT4ge1xuICAgICAgICAgICAgdC52YWx1ZSA9IHRoaXMuZnVuY0NhbGwhLmlucHV0c1t2YWwubmFtZV0gPz8gcHJvcC5kZWZhdWx0VmFsdWUgPz8gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuZnVuY0NhbGwhLmlucHV0c1t2YWwubmFtZV0gPSB0aGlzLmZ1bmNDYWxsIS5pbnB1dHNbdmFsLm5hbWVdID8/IHByb3AuZGVmYXVsdFZhbHVlID8/IG51bGw7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHN1YnNjcmliZU9uRmNDaGFuZ2VzKCk7XG4gICAgICAgICAgdGhpcy5zdWJzLnB1c2goXG4gICAgICAgICAgICB0aGlzLmZ1bmNDYWxsUmVwbGFjZWQuc3Vic2NyaWJlKHN1YnNjcmliZU9uRmNDaGFuZ2VzKVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICB0Lm9uQ2hhbmdlZCgoKSA9PiB7XG4gICAgICAgICAgICAvLyBSZXNvbHZpbmcgY2FzZSBvZiBwcm9wZXJ0eVR5cGUgPSBEQVRBRlJBTUVcbiAgICAgICAgICAgIGlmICghIXQucHJvcGVydHkpIHJldHVybjtcblxuICAgICAgICAgICAgdGhpcy5mdW5jQ2FsbCEuaW5wdXRzW3ZhbC5uYW1lXSA9IHQudmFsdWU7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICB0Lm9uSW5wdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5mdW5jQ2FsbCEuaW5wdXRzW3ZhbC5uYW1lXSA9IHQudmFsdWU7XG4gICAgICAgICAgICBpZiAodC52YWx1ZSA9PT0gbnVsbCkgc2V0VGltZW91dCgoKSA9PiB0LmlucHV0LmNsYXNzTGlzdC5hZGQoJ2Q0LWludmFsaWQnKSwgMTAwKTsgZWxzZSB0LmlucHV0LmNsYXNzTGlzdC5yZW1vdmUoJ2Q0LWludmFsaWQnKTsgO1xuXG4gICAgICAgICAgICB0aGlzLmNoZWNrRGlzYWJpbGl0eS5uZXh0KCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCB2YWxDaGFuZ2VTdWIgPSB2YWwub25DaGFuZ2VkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBuZXdWYWx1ZSA9IHRoaXMuZnVuY0NhbGwhLmlucHV0c1t2YWwubmFtZV07XG5cbiAgICAgICAgICAgIGlmICh2YWwucHJvcGVydHkucHJvcGVydHlUeXBlID09PSBERy5UWVBFLkRBVEFfRlJBTUUpIHtcbiAgICAgICAgICAgICAgLy8gREVBTElORyBXSVRIIEJVRzogaHR0cHM6Ly9yZWRkYXRhLmF0bGFzc2lhbi5uZXQvYnJvd3NlL0dST0stMTIyMjNcbiAgICAgICAgICAgICAgY29uc3QgbmV3VGFibGVJbnB1dCA9IHVpLnRhYmxlSW5wdXQocHJvcC5jYXB0aW9uID8/IHByb3AubmFtZSwgbmV3VmFsdWUsIFsuLi5ncm9rLnNoZWxsLnRhYmxlcywgbmV3VmFsdWVdKTtcbiAgICAgICAgICAgICAgdC5yb290LnJlcGxhY2VXaXRoKG5ld1RhYmxlSW5wdXQucm9vdCk7XG4gICAgICAgICAgICAgIHQgPSBuZXdUYWJsZUlucHV0O1xuXG4gICAgICAgICAgICAgIHQub25JbnB1dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5mdW5jQ2FsbCEuaW5wdXRzW3ZhbC5uYW1lXSA9IHQudmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKHQudmFsdWUgPT09IG51bGwpIHNldFRpbWVvdXQoKCkgPT4gdC5pbnB1dC5jbGFzc0xpc3QuYWRkKCdkNC1pbnZhbGlkJyksIDEwMCk7IGVsc2UgdC5pbnB1dC5jbGFzc0xpc3QucmVtb3ZlKCdkNC1pbnZhbGlkJyk7IDtcblxuICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tEaXNhYmlsaXR5Lm5leHQoKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0Lm5vdGlmeSA9IGZhbHNlO1xuICAgICAgICAgICAgICB0LnZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgICAgICAgIHQubm90aWZ5ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jaGVja0Rpc2FiaWxpdHkubmV4dCgpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgdGhpcy5zdWJzLnB1c2godmFsQ2hhbmdlU3ViKTtcblxuICAgICAgICAgIGlmIChwcm9wLmNhdGVnb3J5ICE9PSBwcmV2Q2F0ZWdvcnkpXG4gICAgICAgICAgICBpbnB1dHMuYXBwZW5kKHVpLmgyKHByb3AuY2F0ZWdvcnkpKTtcblxuICAgICAgICAgIGlmICh0LnZhbHVlID09PSBudWxsKSBydW5CdXR0b24uZGlzYWJsZWQgPSB0cnVlO1xuICAgICAgICAgIGlucHV0cy5hcHBlbmQodC5yb290KTtcbiAgICAgICAgfVxuICAgICAgICBwcmV2Q2F0ZWdvcnkgPSBwcm9wLmNhdGVnb3J5O1xuICAgICAgfSk7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGJ1dHRvbnMgPSB1aS5idXR0b25zSW5wdXQoW2J1dHRvbldyYXBwZXJdKTtcbiAgICBpbnB1dHMuYXBwZW5kKGJ1dHRvbnMpO1xuICAgIGlucHV0cy5jbGFzc0xpc3QucmVtb3ZlKCd1aS1wYW5lbCcpO1xuICAgIGlucHV0cy5zdHlsZS5wYWRkaW5nVG9wID0gJzBweCc7XG4gICAgaW5wdXRzLnN0eWxlLnBhZGRpbmdMZWZ0ID0gJzBweCc7XG5cbiAgICByZXR1cm4gdWkuZGl2KFtpbnB1dHNdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSaWNoRnVuY3Rpb25WaWV3IGtub3cgZXZlcnl0aGluZyBhYm91dCBpdHMgVUksIHNvIGl0IGV4cG9ydHMgbm90IG9ubHkgZGF0YSwgYnV0IGFsc28gdmlld2VyIHNjcmVlbnNob3RzLlxuICAgKiBUaGlzIGZ1bmN0aW9uIGl0ZXJhdGVzIG92ZXIgYWxsIG9mIHRoZSB0YWJzIGFuZCBzZXF1ZW50YWxseSBleHBvcnRzIGFsbCBkYXRhZnJhbWVzLCB0aGVpciB2aWV3ZXJzIGFuZCBzY2FsYXJzLlxuICAgKiBAcGFyYW0gZm9ybWF0IGZvcm1hdCBuZWVkZWQgdG8gZXhwb3J0LiBTZWUge0BsaW5rIHRoaXMuZGVmYXVsdFN1cHBvcnRlZEV4cG9ydEZvcm1hdHN9IGZvciBhdmFpbGFibGUgZm9ybWF0cy5cbiAgICogQHJldHVybnMgUHJvbWlzZTxCbG9iPiB3aXRoIGRhdGEgcmVhZHkgZm9yIGRvd25sb2FkXG4gICAqL1xuICBwcm90ZWN0ZWQgZGVmYXVsdEV4cG9ydCA9IGFzeW5jIChmb3JtYXQ6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IGxhc3RDYWxsID0gdGhpcy5sYXN0Q2FsbDtcbiAgICBpZiAoIWxhc3RDYWxsKSB0aHJvdyBuZXcgRXJyb3IoYEZ1bmN0aW9uIHdhcyBub3QgY2FsbGVkYCk7XG5cbiAgICBpZiAoIXRoaXMuZXhwb3J0Q29uZmlnIS5zdXBwb3J0ZWRGb3JtYXRzLmluY2x1ZGVzKGZvcm1hdCkpIHRocm93IG5ldyBFcnJvcihgRm9ybWF0IFwiJHtmb3JtYXR9XCIgaXMgbm90IHN1cHBvcnRlZC5gKTtcblxuICAgIGlmICghdGhpcy5mdW5jKSB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjb3JyZXNwb2RpbmcgZnVuY3Rpb24gaXMgbm90IHNwZWNpZmllZCcpO1xuXG4gICAgY29uc3QgQkxPQl9UWVBFID0gJ2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0O2NoYXJzZXQ9VVRGLTgnO1xuICAgIGNvbnN0IGV4cG9ydFdvcmtib29rID0gbmV3IEV4Y2VsSlMuV29ya2Jvb2soKTtcblxuICAgIGNvbnN0IGlzU2NhbGFyVHlwZSA9ICh0eXBlOiBERy5UWVBFKSA9PiAoREcuVFlQRVNfU0NBTEFSLmhhcyh0eXBlKSk7XG5cbiAgICBjb25zdCBpc0RhdGFGcmFtZSA9ICh0eXBlOiBERy5UWVBFKSA9PiAodHlwZSA9PT0gREcuVFlQRS5EQVRBX0ZSQU1FKTtcblxuICAgIGNvbnN0IGRmSW5wdXRzID0gdGhpcy5mdW5jLmlucHV0cy5maWx0ZXIoKGlucHV0KSA9PiBpc0RhdGFGcmFtZShpbnB1dC5wcm9wZXJ0eVR5cGUpKTtcbiAgICBjb25zdCBzY2FsYXJJbnB1dHMgPSB0aGlzLmZ1bmMuaW5wdXRzLmZpbHRlcigoaW5wdXQpID0+IGlzU2NhbGFyVHlwZShpbnB1dC5wcm9wZXJ0eVR5cGUpKTtcbiAgICBjb25zdCBkZk91dHB1dHMgPSB0aGlzLmZ1bmMub3V0cHV0cy5maWx0ZXIoKG91dHB1dCkgPT4gaXNEYXRhRnJhbWUob3V0cHV0LnByb3BlcnR5VHlwZSkpO1xuICAgIGNvbnN0IHNjYWxhck91dHB1dHMgPSB0aGlzLmZ1bmMub3V0cHV0cy5maWx0ZXIoKG91dHB1dCkgPT4gaXNTY2FsYXJUeXBlKG91dHB1dC5wcm9wZXJ0eVR5cGUpKTtcblxuICAgIGNvbnN0IGlucHV0UGFyYW1zID0gWy4uLmxhc3RDYWxsLmlucHV0UGFyYW1zLnZhbHVlcygpXSBhcyBERy5GdW5jQ2FsbFBhcmFtW107XG4gICAgY29uc3Qgb3V0cHV0UGFyYW1zID0gWy4uLmxhc3RDYWxsLm91dHB1dFBhcmFtcy52YWx1ZXMoKV0gYXMgREcuRnVuY0NhbGxQYXJhbVtdO1xuXG4gICAgZGZJbnB1dHMuZm9yRWFjaCgoZGZJbnB1dCkgPT4ge1xuICAgICAgY29uc3QgdmlzaWJsZVRpdGxlID0gZGZJbnB1dC5vcHRpb25zLmNhcHRpb24gfHwgZGZJbnB1dC5uYW1lO1xuICAgICAgY29uc3QgY3VycmVudERmU2hlZXQgPSBleHBvcnRXb3JrYm9vay5hZGRXb3Jrc2hlZXQoZ2V0U2hlZXROYW1lKHZpc2libGVUaXRsZSwgRElSRUNUSU9OLklOUFVUKSk7XG5cbiAgICAgIGNvbnN0IGN1cnJlbnREZiA9IChsYXN0Q2FsbC5pbnB1dHNbZGZJbnB1dC5uYW1lXSBhcyBERy5EYXRhRnJhbWUpO1xuICAgICAgZGZUb1NoZWV0KGN1cnJlbnREZlNoZWV0LCBjdXJyZW50RGYpO1xuICAgIH0pO1xuXG4gICAgaWYgKHNjYWxhcklucHV0cy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IGlucHV0U2NhbGFyc1NoZWV0ID0gZXhwb3J0V29ya2Jvb2suYWRkV29ya3NoZWV0KCdJbnB1dCBzY2FsYXJzJyk7XG4gICAgICBzY2FsYXJzVG9TaGVldChpbnB1dFNjYWxhcnNTaGVldCwgc2NhbGFySW5wdXRzLm1hcCgoc2NhbGFySW5wdXQpID0+ICh7XG4gICAgICAgIGNhcHRpb246IHNjYWxhcklucHV0Lm9wdGlvbnNbJ2NhcHRpb24nXSB8fCBzY2FsYXJJbnB1dC5uYW1lLFxuICAgICAgICB2YWx1ZTogbGFzdENhbGwuaW5wdXRzW3NjYWxhcklucHV0Lm5hbWVdLFxuICAgICAgICB1bml0czogc2NhbGFySW5wdXQub3B0aW9uc1sndW5pdHMnXSB8fCAnJyxcbiAgICAgIH0pKSk7XG4gICAgfVxuXG4gICAgZGZPdXRwdXRzLmZvckVhY2goKGRmT3V0cHV0KSA9PiB7XG4gICAgICBjb25zdCB2aXNpYmxlVGl0bGUgPSBkZk91dHB1dC5vcHRpb25zLmNhcHRpb24gfHwgZGZPdXRwdXQubmFtZTtcbiAgICAgIGNvbnN0IGN1cnJlbnREZlNoZWV0ID0gZXhwb3J0V29ya2Jvb2suYWRkV29ya3NoZWV0KGdldFNoZWV0TmFtZSh2aXNpYmxlVGl0bGUsIERJUkVDVElPTi5PVVRQVVQpKTtcblxuICAgICAgY29uc3QgY3VycmVudERmID0gKGxhc3RDYWxsLm91dHB1dHNbZGZPdXRwdXQubmFtZV0gYXMgREcuRGF0YUZyYW1lKTtcbiAgICAgIGRmVG9TaGVldChjdXJyZW50RGZTaGVldCwgY3VycmVudERmKTtcbiAgICB9KTtcblxuXG4gICAgaWYgKHNjYWxhck91dHB1dHMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBvdXRwdXRTY2FsYXJzU2hlZXQgPSBleHBvcnRXb3JrYm9vay5hZGRXb3Jrc2hlZXQoJ091dHB1dCBzY2FsYXJzJyk7XG4gICAgICBzY2FsYXJzVG9TaGVldChvdXRwdXRTY2FsYXJzU2hlZXQsIHNjYWxhck91dHB1dHMubWFwKChzY2FsYXJPdXRwdXQpID0+ICh7XG4gICAgICAgIGNhcHRpb246IHNjYWxhck91dHB1dC5vcHRpb25zWydjYXB0aW9uJ10gfHwgc2NhbGFyT3V0cHV0Lm5hbWUsXG4gICAgICAgIHZhbHVlOiBsYXN0Q2FsbC5vdXRwdXRzW3NjYWxhck91dHB1dC5uYW1lXSxcbiAgICAgICAgdW5pdHM6IHNjYWxhck91dHB1dC5vcHRpb25zWyd1bml0cyddIHx8ICcnLFxuICAgICAgfSkpKTtcbiAgICB9XG5cbiAgICBjb25zdCB0YWJDb250cm9sID0gdGhpcy50YWJzRWxlbTtcbiAgICBmb3IgKGNvbnN0IHRhYkxhYmVsIG9mIHRoaXMudGFic0xhYmVscykge1xuICAgICAgdGFiQ29udHJvbC5jdXJyZW50UGFuZSA9IHRhYkNvbnRyb2wuZ2V0UGFuZSh0YWJMYWJlbCk7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCAxMDApKTtcbiAgICAgIGlmICh0YWJMYWJlbCA9PT0gJ0lucHV0Jykge1xuICAgICAgICBmb3IgKGNvbnN0IGlucHV0UGFyYW0gb2YgaW5wdXRQYXJhbXMuZmlsdGVyKChpbnB1dFBhcmFtKSA9PiBpbnB1dFBhcmFtLnByb3BlcnR5LnByb3BlcnR5VHlwZSA9PT0gREcuVFlQRS5EQVRBX0ZSQU1FKSkge1xuICAgICAgICAgIGNvbnN0IG5vbkdyaWRWaWV3ZXJzID0gdGhpcy5kZlRvVmlld2VyTWFwcGluZ1tpbnB1dFBhcmFtLm5hbWVdXG4gICAgICAgICAgICAuZmlsdGVyKCh2aWV3ZXIpID0+IHZpZXdlci50eXBlICE9PSBERy5WSUVXRVIuR1JJRClcbiAgICAgICAgICAgIC5maWx0ZXIoKHZpZXdlcikgPT4gT2JqZWN0LnZhbHVlcyh2aWV3ZXJUeXBlc01hcHBpbmcpLmluY2x1ZGVzKHZpZXdlci50eXBlKSk7XG5cbiAgICAgICAgICBjb25zdCBkZklucHV0ID0gZGZJbnB1dHMuZmluZCgoaW5wdXQpID0+IGlucHV0Lm5hbWUgPT09IGlucHV0UGFyYW0ubmFtZSk7XG4gICAgICAgICAgY29uc3QgdmlzaWJsZVRpdGxlID0gZGZJbnB1dCEub3B0aW9ucy5jYXB0aW9uIHx8IGlucHV0UGFyYW0ubmFtZTtcbiAgICAgICAgICBjb25zdCBjdXJyZW50RGYgPSAobGFzdENhbGwuaW5wdXRzW2RmSW5wdXQhLm5hbWVdIGFzIERHLkRhdGFGcmFtZSk7XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IFtpbmRleCwgdmlld2VyXSBvZiBub25HcmlkVmlld2Vycy5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgIGF3YWl0IHBsb3RUb1NoZWV0KFxuICAgICAgICAgICAgICBleHBvcnRXb3JrYm9vayxcbiAgICAgICAgICAgICAgZXhwb3J0V29ya2Jvb2suZ2V0V29ya3NoZWV0KGdldFNoZWV0TmFtZSh2aXNpYmxlVGl0bGUsIERJUkVDVElPTi5JTlBVVCkpLFxuICAgICAgICAgICAgICB2aWV3ZXIucm9vdCxcbiAgICAgICAgICAgICAgY3VycmVudERmLmNvbHVtbnMubGVuZ3RoICsgMixcbiAgICAgICAgICAgICAgKGluZGV4ID4gMCkgPyBNYXRoLmNlaWwobm9uR3JpZFZpZXdlcnNbaW5kZXgtMV0ucm9vdC5jbGllbnRIZWlnaHQgLyAyMCkgKyAxIDogMFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGNvbnN0IG91dHB1dFBhcmFtIG9mIG91dHB1dFBhcmFtcy5maWx0ZXIoXG4gICAgICAgICAgKG91dHB1dFBhcmFtKSA9PiBvdXRwdXRQYXJhbS5wcm9wZXJ0eS5wcm9wZXJ0eVR5cGUgPT09IERHLlRZUEUuREFUQV9GUkFNRSAmJlxuICAgICAgICAgIChcbiAgICAgICAgICAgICh0YWJMYWJlbCA9PT0gJ091dHB1dCcgJiYgb3V0cHV0UGFyYW0ucHJvcGVydHkuY2F0ZWdvcnkgPT09ICdNaXNjJyB8fCBvdXRwdXRQYXJhbS5wcm9wZXJ0eS5jYXRlZ29yeSA9PT0gJ091dHB1dCcpIHx8XG4gICAgICAgICAgICAodGFiTGFiZWwgIT09ICdPdXRwdXQnICYmIG91dHB1dFBhcmFtLnByb3BlcnR5LmNhdGVnb3J5ID09PSB0YWJMYWJlbClcbiAgICAgICAgICApXG4gICAgICAgICkpIHtcbiAgICAgICAgICBjb25zdCBub25HcmlkVmlld2VycyA9IHRoaXMuZGZUb1ZpZXdlck1hcHBpbmdbb3V0cHV0UGFyYW0ucHJvcGVydHkubmFtZV1cbiAgICAgICAgICAgIC5maWx0ZXIoKHZpZXdlcikgPT4gdmlld2VyLnR5cGUgIT09IERHLlZJRVdFUi5HUklEKVxuICAgICAgICAgICAgLmZpbHRlcigodmlld2VyKSA9PiBPYmplY3QudmFsdWVzKHZpZXdlclR5cGVzTWFwcGluZykuaW5jbHVkZXModmlld2VyLnR5cGUpKTtcblxuICAgICAgICAgIGNvbnN0IGRmT3V0cHV0ID0gZGZPdXRwdXRzLmZpbmQoKG91dHB1dCkgPT4gb3V0cHV0Lm5hbWUgPT09IG91dHB1dFBhcmFtLnByb3BlcnR5Lm5hbWUpITtcbiAgICAgICAgICBjb25zdCB2aXNpYmxlVGl0bGUgPSBkZk91dHB1dC5vcHRpb25zLmNhcHRpb24gfHwgb3V0cHV0UGFyYW0ucHJvcGVydHkubmFtZTtcbiAgICAgICAgICBjb25zdCBjdXJyZW50RGYgPSAobGFzdENhbGwub3V0cHV0c1tkZk91dHB1dC5uYW1lXSBhcyBERy5EYXRhRnJhbWUpO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBbaW5kZXgsIHZpZXdlcl0gb2Ygbm9uR3JpZFZpZXdlcnMuZW50cmllcygpKSB7XG4gICAgICAgICAgICBpZiAodmlld2VyLnR5cGUgPT09IERHLlZJRVdFUi5TVEFUSVNUSUNTKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IGN1cnJlbnREZi5jb2x1bW5zLmxlbmd0aDtcbiAgICAgICAgICAgICAgY29uc3Qgc3RhdHMgPSBERy5EYXRhRnJhbWUuZnJvbUNvbHVtbnMoW1xuICAgICAgICAgICAgICAgIERHLkNvbHVtbi5zdHJpbmcoJ05hbWUnLCBsZW5ndGgpLmluaXQoKGk6IG51bWJlcikgPT4gY3VycmVudERmLmNvbHVtbnMuYnlJbmRleChpKS5uYW1lKSxcbiAgICAgICAgICAgICAgICBERy5Db2x1bW4uaW50KCdWYWx1ZXMnLCBsZW5ndGgpLmluaXQoKGk6IG51bWJlcikgPT4gY3VycmVudERmLmNvbHVtbnMuYnlJbmRleChpKS5zdGF0cy52YWx1ZUNvdW50KSxcbiAgICAgICAgICAgICAgICBERy5Db2x1bW4uaW50KCdOdWxscycsIGxlbmd0aCkuaW5pdCgoaTogbnVtYmVyKSA9PiBjdXJyZW50RGYuY29sdW1ucy5ieUluZGV4KGkpLnN0YXRzLm1pc3NpbmdWYWx1ZUNvdW50KSxcbiAgICAgICAgICAgICAgICBERy5Db2x1bW4uZmxvYXQoJ01pbicsIGxlbmd0aCkuaW5pdCgoaTogbnVtYmVyKSA9PiBjdXJyZW50RGYuY29sdW1ucy5ieUluZGV4KGkpLnN0YXRzLm1pbiksXG4gICAgICAgICAgICAgICAgREcuQ29sdW1uLmZsb2F0KCdNYXgnLCBsZW5ndGgpLmluaXQoKGk6IG51bWJlcikgPT4gY3VycmVudERmLmNvbHVtbnMuYnlJbmRleChpKS5zdGF0cy5tYXgpLFxuICAgICAgICAgICAgICAgIERHLkNvbHVtbi5mbG9hdCgnQXZnJywgbGVuZ3RoKS5pbml0KChpOiBudW1iZXIpID0+IGN1cnJlbnREZi5jb2x1bW5zLmJ5SW5kZXgoaSkuc3RhdHMuYXZnKSxcbiAgICAgICAgICAgICAgICBERy5Db2x1bW4uZmxvYXQoJ1N0ZGV2JywgbGVuZ3RoKS5pbml0KChpOiBudW1iZXIpID0+IGN1cnJlbnREZi5jb2x1bW5zLmJ5SW5kZXgoaSkuc3RhdHMuc3RkZXYpLFxuICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgZGZUb1NoZWV0KFxuICAgICAgICAgICAgICAgIGV4cG9ydFdvcmtib29rLmdldFdvcmtzaGVldChnZXRTaGVldE5hbWUodmlzaWJsZVRpdGxlLCBESVJFQ1RJT04uT1VUUFVUKSksXG4gICAgICAgICAgICAgICAgc3RhdHMsXG4gICAgICAgICAgICAgICAgY3VycmVudERmLmNvbHVtbnMubGVuZ3RoICsgMixcbiAgICAgICAgICAgICAgICAoaW5kZXggPiAwKSA/IE1hdGguY2VpbChub25HcmlkVmlld2Vyc1tpbmRleC0xXS5yb290LmNsaWVudEhlaWdodCAvIDIwKSArIDEgOiAwXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBhd2FpdCBwbG90VG9TaGVldChcbiAgICAgICAgICAgICAgICBleHBvcnRXb3JrYm9vayxcbiAgICAgICAgICAgICAgICBleHBvcnRXb3JrYm9vay5nZXRXb3Jrc2hlZXQoZ2V0U2hlZXROYW1lKHZpc2libGVUaXRsZSwgRElSRUNUSU9OLk9VVFBVVCkpLFxuICAgICAgICAgICAgICAgIHZpZXdlci5yb290LFxuICAgICAgICAgICAgICAgIGN1cnJlbnREZi5jb2x1bW5zLmxlbmd0aCArIDIsXG4gICAgICAgICAgICAgICAgKGluZGV4ID4gMCkgPyBNYXRoLmNlaWwobm9uR3JpZFZpZXdlcnNbaW5kZXgtMV0ucm9vdC5jbGllbnRIZWlnaHQgLyAyMCkgKyAxIDogMFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IGJ1ZmZlciA9IGF3YWl0IGV4cG9ydFdvcmtib29rLnhsc3gud3JpdGVCdWZmZXIoKTtcblxuICAgIHJldHVybiBuZXcgQmxvYihbYnVmZmVyXSwge3R5cGU6IEJMT0JfVFlQRX0pO1xuICB9O1xuXG4gIGV4cG9ydENvbmZpZyA9IHtcbiAgICBzdXBwb3J0ZWRFeHRlbnNpb25zOiB0aGlzLmRlZmF1bHRTdXBwb3J0ZWRFeHBvcnRFeHRlbnNpb25zKCksXG4gICAgc3VwcG9ydGVkRm9ybWF0czogdGhpcy5kZWZhdWx0U3VwcG9ydGVkRXhwb3J0Rm9ybWF0cygpLFxuICAgIGV4cG9ydDogdGhpcy5kZWZhdWx0RXhwb3J0LFxuICAgIGZpbGVuYW1lOiB0aGlzLmRlZmF1bHRFeHBvcnRGaWxlbmFtZSxcbiAgfTtcbn1cblxuY29uc3QgZ2V0U2hlZXROYW1lID0gKG5hbWU6IHN0cmluZywgZGlyZWN0aW9uOiBESVJFQ1RJT04pID0+IHtcbiAgY29uc3QgaWRlYWxOYW1lID0gYCR7ZGlyZWN0aW9ufSAtICR7bmFtZX1gO1xuICByZXR1cm4gKGlkZWFsTmFtZS5sZW5ndGggPiAzMSkgPyBuYW1lLnN1YnN0cmluZygwLCAzMikgOiBpZGVhbE5hbWU7XG59O1xuXG5lbnVtIERJUkVDVElPTiB7XG4gIElOUFVUID0gJ0lucHV0JyxcbiAgT1VUUFVUID0gJ091dHB1dCdcbn1cblxuY29uc3Qgc2NhbGFyc1RvU2hlZXQgPSAoc2hlZXQ6IEV4Y2VsSlMuV29ya3NoZWV0LCBzY2FsYXJzOiB7IGNhcHRpb246IHN0cmluZywgdmFsdWU6IHN0cmluZywgdW5pdHM6IHN0cmluZyB9W10pID0+IHtcbiAgc2hlZXQuYWRkUm93KFsnUGFyYW1ldGVyJywgJ1ZhbHVlJywgJ1VuaXRzJ10pLmZvbnQgPSB7Ym9sZDogdHJ1ZX07XG4gIHNjYWxhcnMuZm9yRWFjaCgoc2NhbGFyKSA9PiB7XG4gICAgc2hlZXQuYWRkUm93KFtzY2FsYXIuY2FwdGlvbiwgc2NhbGFyLnZhbHVlLCBzY2FsYXIudW5pdHNdKTtcbiAgfSk7XG5cbiAgc2hlZXQuZ2V0Q29sdW1uKDEpLndpZHRoID0gTWF0aC5tYXgoXG4gICAgLi4uc2NhbGFycy5tYXAoKHNjYWxhcikgPT4gc2NhbGFyLmNhcHRpb24udG9TdHJpbmcoKS5sZW5ndGgpLCAnUGFyYW1ldGVyJy5sZW5ndGhcbiAgKSAqIDEuMjtcbiAgc2hlZXQuZ2V0Q29sdW1uKDIpLndpZHRoID0gTWF0aC5tYXgoLi4uc2NhbGFycy5tYXAoKHNjYWxhcikgPT4gc2NhbGFyLnZhbHVlLnRvU3RyaW5nKCkubGVuZ3RoKSwgJ1ZhbHVlJy5sZW5ndGgpICogMS4yO1xuICBzaGVldC5nZXRDb2x1bW4oMykud2lkdGggPSBNYXRoLm1heCguLi5zY2FsYXJzLm1hcCgoc2NhbGFyKSA9PiBzY2FsYXIudW5pdHMudG9TdHJpbmcoKS5sZW5ndGgpLCAnVW5pdHMnLmxlbmd0aCkgKiAxLjI7XG59O1xuXG5jb25zdCBkZlRvU2hlZXQgPSAoc2hlZXQ6IEV4Y2VsSlMuV29ya3NoZWV0LCBkZjogREcuRGF0YUZyYW1lLCBjb2x1bW46IG51bWJlciA9IDAsIHJvdzogbnVtYmVyID0gMCkgPT4ge1xuICBmb3IgKGxldCBpPSAwOyBpIDwgZGYuY29sdW1ucy5uYW1lcygpLmxlbmd0aDsgaSsrKSB7XG4gICAgc2hlZXQuZ2V0Q2VsbCgxICsgcm93LCAxICsgaSArIGNvbHVtbikudmFsdWUgPSBkZi5jb2x1bW5zLmJ5SW5kZXgoaSkubmFtZTtcbiAgICBzaGVldC5nZXRDb2x1bW4oMSArIGkgKyBjb2x1bW4pLndpZHRoID0gTWF0aC5tYXgoXG4gICAgICAuLi5kZi5jb2x1bW5zLmJ5SW5kZXgoaSkuY2F0ZWdvcmllcy5tYXAoKGNhdGVnb3J5KSA9PiBjYXRlZ29yeS50b1N0cmluZygpLmxlbmd0aCksXG4gICAgICBkZi5jb2x1bW5zLmJ5SW5kZXgoaSkubmFtZS5sZW5ndGhcbiAgICApICogMS4yO1xuICB9XG4gIGZvciAobGV0IGRmQ29sdW1uID0gMDsgZGZDb2x1bW4gPCBkZi5jb2x1bW5zLmxlbmd0aDsgZGZDb2x1bW4rKykge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGYucm93Q291bnQ7IGkrKylcbiAgICAgIHNoZWV0LmdldENlbGwoaSArIDIgKyByb3csIDEgKyBjb2x1bW4rZGZDb2x1bW4pLnZhbHVlID0gZGYuY29sdW1ucy5ieUluZGV4KGRmQ29sdW1uKS5nZXQoaSk7XG4gIH1cbn07XG5cbmNvbnN0IHBsb3RUb1NoZWV0ID0gYXN5bmMgKGV4cG9ydFdiOiBFeGNlbEpTLldvcmtib29rLCBzaGVldDogRXhjZWxKUy5Xb3Jrc2hlZXQsIHBsb3Q6IEhUTUxFbGVtZW50LCBjb2x1bW5Gb3JJbWFnZTogbnVtYmVyLCByb3dGb3JJbWFnZTogbnVtYmVyID0gMCkgPT4ge1xuICBjb25zdCBjYW52YXMgPSBhd2FpdCBodG1sMmNhbnZhcyhwbG90IGFzIEhUTUxFbGVtZW50LCB7bG9nZ2luZzogZmFsc2V9KTtcbiAgY29uc3QgZGF0YVVybCA9IGNhbnZhcy50b0RhdGFVUkwoJ2ltYWdlL3BuZycpO1xuXG4gIGNvbnN0IGltYWdlSWQgPSBleHBvcnRXYi5hZGRJbWFnZSh7XG4gICAgYmFzZTY0OiBkYXRhVXJsLFxuICAgIGV4dGVuc2lvbjogJ3BuZycsXG4gIH0pO1xuICBzaGVldC5hZGRJbWFnZShpbWFnZUlkLCB7XG4gICAgdGw6IHtjb2w6IGNvbHVtbkZvckltYWdlLCByb3c6IHJvd0ZvckltYWdlfSxcbiAgICBleHQ6IHt3aWR0aDogY2FudmFzLndpZHRoLCBoZWlnaHQ6IGNhbnZhcy5oZWlnaHR9LFxuICB9KTtcbn07XG4iXX0=