@datagrok-libraries/bio 2.8.5 → 2.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  },
6
6
  "beta": true,
7
7
  "friendlyName": "Datagrok bio library",
8
- "version": "2.8.5",
8
+ "version": "2.8.6",
9
9
  "description": "",
10
10
  "dependencies": {
11
11
  "@datagrok-libraries/utils": "^1.0.0",
@@ -1,47 +1,13 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
  import { SplitterFunc } from '../viewers/web-logo';
3
- /** enum type to simplify setting "user-friendly" notation if necessary */
4
- export declare const enum NOTATION {
5
- FASTA = "FASTA",
6
- SEPARATOR = "SEPARATOR",
7
- HELM = "HELM"
8
- }
3
+ import { UnitsHandler, NOTATION } from './units-handler';
9
4
  /** Class for handling conversion of notation systems in Macromolecule columns */
10
- export declare class NotationConverter {
11
- private readonly _sourceColumn;
12
- private _sourceUnits;
13
- private _sourceNotation;
14
- private _defaultGapSymbol;
15
- private _defaultGapSymbolsDict;
5
+ export declare class NotationConverter extends UnitsHandler {
16
6
  private _splitter;
17
7
  protected get splitter(): SplitterFunc;
18
- private get sourceUnits();
19
- private get sourceColumn();
20
- get sourceNotation(): NOTATION;
21
- get defaultGapSymbol(): string;
22
- get separator(): string;
23
- isFasta(): boolean;
24
- isSeparator(): boolean;
25
- isHelm(): boolean;
26
8
  toFasta(targetNotation: NOTATION): boolean;
27
9
  toSeparator(targetNotation: NOTATION): boolean;
28
10
  toHelm(targetNotation: NOTATION): boolean;
29
- isRna(): boolean;
30
- isDna(): boolean;
31
- isPeptide(): boolean;
32
- /** Associate notation types with the corresponding units */
33
- /**
34
- * @return {NOTATION} Notation associated with the units type
35
- */
36
- private getSourceNotation;
37
- /**
38
- * Create a new empty column of the specified notation type and the same
39
- * length as sourceColumn
40
- *
41
- * @param {NOTATION} targetNotation
42
- * @return {DG.Column}
43
- */
44
- private getNewColumn;
45
11
  /**
46
12
  * Convert a Macromolecule column from FASTA to SEPARATOR notation
47
13
  *
@@ -1 +1 @@
1
- {"version":3,"file":"notation-converter.d.ts","sourceRoot":"","sources":["notation-converter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAC,YAAY,EAAU,MAAM,qBAAqB,CAAC;AAE1D,0EAA0E;AAC1E,0BAAkB,QAAQ;IACxB,KAAK,UAAU;IACf,SAAS,cAAc;IACvB,IAAI,SAAS;CACd;AAED,iFAAiF;AACjF,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAY;IAC1C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,eAAe,CAAW;IAClC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,sBAAsB,CAI5B;IAEF,OAAO,CAAC,SAAS,CAA6B;IAC9C,SAAS,KAAK,QAAQ,IAAI,YAAY,CAIrC;IAGD,OAAO,KAAK,WAAW,GAAwC;IAE/D,OAAO,KAAK,YAAY,GAA4C;IAEpE,IAAW,cAAc,IAAI,QAAQ,CAAiC;IAEtE,IAAW,gBAAgB,IAAI,MAAM,CAAmC;IAExE,IAAW,SAAS,IAAI,MAAM,CAM7B;IAEM,OAAO,IAAI,OAAO;IAElB,WAAW,IAAI,OAAO;IAEtB,MAAM,IAAI,OAAO;IAEjB,OAAO,CAAC,cAAc,EAAE,QAAQ,GAAG,OAAO;IAE1C,WAAW,CAAC,cAAc,EAAE,QAAQ,GAAG,OAAO;IAE9C,MAAM,CAAC,cAAc,EAAE,QAAQ,GAAG,OAAO;IAEzC,KAAK,IAAI,OAAO;IAEhB,KAAK,IAAI,OAAO;IAEhB,SAAS,IAAI,OAAO;IAE3B,4DAA4D;IAC5D;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IAwBpB;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;IAmB/B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,mBAAmB;IAkB3B;;;;;;;OAOG;IACI,mBAAmB,CACxB,aAAa,EAAE,MAAM,EACrB,eAAe,GAAE,MAAM,GAAG,IAAW,GACnC,MAAM;IAOV;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAerB;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IA4B/B;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;IAiDnB,OAAO,CAAC,sBAAsB;IAK9B;;;;;OAKG;IACI,OAAO,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,GAAE,MAAM,GAAG,IAAW,GAAG,EAAE,CAAC,MAAM;gBAmBjE,GAAG,EAAE,EAAE,CAAC,MAAM;CAYlC"}
1
+ {"version":3,"file":"notation-converter.d.ts","sourceRoot":"","sources":["notation-converter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAC,YAAY,EAAU,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAC,MAAM,iBAAiB,CAAC;AAEvD,iFAAiF;AACjF,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,OAAO,CAAC,SAAS,CAA6B;IAC9C,SAAS,KAAK,QAAQ,IAAI,YAAY,CAIrC;IAEM,OAAO,CAAC,cAAc,EAAE,QAAQ,GAAG,OAAO;IAE1C,WAAW,CAAC,cAAc,EAAE,QAAQ,GAAG,OAAO;IAE9C,MAAM,CAAC,cAAc,EAAE,QAAQ,GAAG,OAAO;IAEhD;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;IAmB/B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,mBAAmB;IAkB3B;;;;;;;OAOG;IACI,mBAAmB,CACxB,aAAa,EAAE,MAAM,EACrB,eAAe,GAAE,MAAM,GAAG,IAAW,GACnC,MAAM;IAOV;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAerB;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IA4B/B;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;IAiDnB,OAAO,CAAC,sBAAsB;IAK9B;;;;;OAKG;IACI,OAAO,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,GAAE,MAAM,GAAG,IAAW,GAAG,EAAE,CAAC,MAAM;gBAmBjE,GAAG,EAAE,EAAE,CAAC,MAAM;CAGlC"}
@@ -1,87 +1,20 @@
1
- import * as DG from 'datagrok-api/dg';
2
1
  import { WebLogo } from '../viewers/web-logo';
2
+ import { UnitsHandler } from './units-handler';
3
3
  /** Class for handling conversion of notation systems in Macromolecule columns */
4
- export class NotationConverter {
4
+ export class NotationConverter extends UnitsHandler {
5
5
  constructor(col) {
6
- this._defaultGapSymbolsDict = {
7
- HELM: '*',
8
- SEPARATOR: '',
9
- FASTA: '-',
10
- };
6
+ super(col);
11
7
  this._splitter = null;
12
- this._sourceColumn = col;
13
- const units = this._sourceColumn.tags[DG.TAGS.UNITS];
14
- if (units !== null)
15
- this._sourceUnits = units;
16
- else
17
- throw new Error('Units are not specified in column');
18
- this._sourceNotation = this.getSourceNotation();
19
- this._defaultGapSymbol = (this.isFasta()) ? this._defaultGapSymbolsDict.FASTA :
20
- (this.isHelm()) ? this._defaultGapSymbolsDict.HELM :
21
- this._defaultGapSymbolsDict.SEPARATOR;
22
8
  }
23
9
  get splitter() {
24
10
  if (this._splitter === null)
25
- this._splitter = WebLogo.getSplitterForColumn(this._sourceColumn);
11
+ this._splitter = WebLogo.getSplitterForColumn(this.column);
26
12
  return this._splitter;
27
13
  }
28
14
  ;
29
- get sourceUnits() { return this._sourceUnits; }
30
- get sourceColumn() { return this._sourceColumn; }
31
- get sourceNotation() { return this._sourceNotation; }
32
- get defaultGapSymbol() { return this._defaultGapSymbol; }
33
- get separator() {
34
- const separator = this.sourceColumn.getTag('separator');
35
- if (separator !== null)
36
- return separator;
37
- else
38
- throw new Error('Separator not set');
39
- }
40
- isFasta() { return this.sourceNotation === "FASTA" /* NOTATION.FASTA */; }
41
- isSeparator() { return this.sourceNotation === "SEPARATOR" /* NOTATION.SEPARATOR */; }
42
- isHelm() { return this.sourceNotation === "HELM" /* NOTATION.HELM */; }
43
15
  toFasta(targetNotation) { return targetNotation === "FASTA" /* NOTATION.FASTA */; }
44
16
  toSeparator(targetNotation) { return targetNotation === "SEPARATOR" /* NOTATION.SEPARATOR */; }
45
17
  toHelm(targetNotation) { return targetNotation === "HELM" /* NOTATION.HELM */; }
46
- isRna() { return this.sourceUnits.toLowerCase().endsWith('rna'); }
47
- isDna() { return this.sourceUnits.toLowerCase().endsWith('dna'); }
48
- isPeptide() { return this.sourceUnits.toLowerCase().endsWith('pt'); }
49
- /** Associate notation types with the corresponding units */
50
- /**
51
- * @return {NOTATION} Notation associated with the units type
52
- */
53
- getSourceNotation() {
54
- if (this.sourceUnits.toLowerCase().startsWith('fasta'))
55
- return "FASTA" /* NOTATION.FASTA */;
56
- else if (this.sourceUnits.toLowerCase().startsWith('separator'))
57
- return "SEPARATOR" /* NOTATION.SEPARATOR */;
58
- else if (this.sourceUnits.toLowerCase().startsWith('helm'))
59
- return "HELM" /* NOTATION.HELM */;
60
- else
61
- throw new Error('The column has units that do not correspond to any notation');
62
- }
63
- /**
64
- * Create a new empty column of the specified notation type and the same
65
- * length as sourceColumn
66
- *
67
- * @param {NOTATION} targetNotation
68
- * @return {DG.Column}
69
- */
70
- getNewColumn(targetNotation) {
71
- const col = this.sourceColumn;
72
- const len = col.length;
73
- const name = targetNotation.toLowerCase() + '(' + col.name + ')';
74
- const newColName = col.dataFrame.columns.getUnusedName(name);
75
- // dummy code
76
- const newColumn = DG.Column.fromList('string', newColName, new Array(len).fill(''));
77
- newColumn.semType = DG.SEMTYPE.MACROMOLECULE;
78
- newColumn.setTag(DG.TAGS.UNITS, this.sourceUnits.replace(this.sourceNotation.toLowerCase().toString(), targetNotation.toLowerCase().toString()));
79
- // TODO: specify cell renderers for all cases
80
- if (this.toFasta(targetNotation)) {
81
- newColumn.setTag(DG.TAGS.CELL_RENDERER, 'Macromolecule');
82
- }
83
- return newColumn;
84
- }
85
18
  /**
86
19
  * Convert a Macromolecule column from FASTA to SEPARATOR notation
87
20
  *
@@ -95,7 +28,7 @@ export class NotationConverter {
95
28
  const newColumn = this.getNewColumn("SEPARATOR" /* NOTATION.SEPARATOR */);
96
29
  // assign the values to the newly created empty column
97
30
  newColumn.init((idx) => {
98
- const fastaPolymer = this.sourceColumn.get(idx);
31
+ const fastaPolymer = this.column.get(idx);
99
32
  const fastaMonomersArray = this.splitter(fastaPolymer);
100
33
  for (let i = 0; i < fastaMonomersArray.length; i++) {
101
34
  if (fastaMonomersArray[i] === fastaGapSymbol)
@@ -163,7 +96,7 @@ export class NotationConverter {
163
96
  const newColumn = this.getNewColumn("HELM" /* NOTATION.HELM */);
164
97
  // assign the values to the empty column
165
98
  newColumn.init((idx) => {
166
- const sourcePolymer = this.sourceColumn.get(idx);
99
+ const sourcePolymer = this.column.get(idx);
167
100
  return this.convertToHelmHelper(sourcePolymer, sourceGapSymbol, prefix, leftWrapper, rightWrapper, postfix);
168
101
  });
169
102
  return newColumn;
@@ -180,7 +113,7 @@ export class NotationConverter {
180
113
  const newColumn = this.getNewColumn("FASTA" /* NOTATION.FASTA */);
181
114
  // assign the values to the empty column
182
115
  newColumn.init((idx) => {
183
- const separatorPolymer = this.sourceColumn.get(idx);
116
+ const separatorPolymer = this.column.get(idx);
184
117
  // items can be monomers or separators
185
118
  const separatorItemsArray = this.splitter(separatorPolymer);
186
119
  const fastaMonomersArray = [];
@@ -225,7 +158,7 @@ export class NotationConverter {
225
158
  const newColumn = this.getNewColumn(tgtNotation);
226
159
  // assign the values to the empty column
227
160
  newColumn.init((idx) => {
228
- const helmPolymer = this.sourceColumn.get(idx);
161
+ const helmPolymer = this.column.get(idx);
229
162
  // we cannot use isDna() or isRna() because source helm columns can
230
163
  // contain DNA, RNA and PT in different cells, so the corresponding
231
164
  // tags cannot be set for the whole column
@@ -265,7 +198,7 @@ export class NotationConverter {
265
198
  */
266
199
  convert(tgtNotation, tgtSeparator = null) {
267
200
  // possible exceptions
268
- if (this.sourceNotation === tgtNotation)
201
+ if (this.notation === tgtNotation)
269
202
  throw new Error('tgt notation is invalid');
270
203
  if (this.toSeparator(tgtNotation) && tgtSeparator === null)
271
204
  throw new Error('tgt separator is not specified');
@@ -281,4 +214,4 @@ export class NotationConverter {
281
214
  return this.convertHelm(tgtNotation, tgtSeparator);
282
215
  }
283
216
  }
284
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90YXRpb24tY29udmVydGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibm90YXRpb24tY29udmVydGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdEMsT0FBTyxFQUFlLE9BQU8sRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBUzFELGlGQUFpRjtBQUNqRixNQUFNLE9BQU8saUJBQWlCO0lBdVU1QixZQUFtQixHQUFjO1FBbFV6QiwyQkFBc0IsR0FBRztZQUMvQixJQUFJLEVBQUUsR0FBRztZQUNULFNBQVMsRUFBRSxFQUFFO1lBQ2IsS0FBSyxFQUFFLEdBQUc7U0FDWCxDQUFDO1FBRU0sY0FBUyxHQUF3QixJQUFJLENBQUM7UUE2VDVDLElBQUksQ0FBQyxhQUFhLEdBQUcsR0FBRyxDQUFDO1FBQ3pCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckQsSUFBSSxLQUFLLEtBQUssSUFBSTtZQUNoQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQzs7WUFFMUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDaEQsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM3RSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ2xELElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxTQUFTLENBQUM7SUFDNUMsQ0FBQztJ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LENBQUMsYUFBYSxFQUFFLENBQUM7YUFDekIsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUM7WUFDdEQsT0FBTyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQzthQUNuQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLG1CQUFtQjtZQUN0RSxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7YUFDbEMsaURBQWlEO1lBQ3BELE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsWUFBYSxDQUFDLENBQUM7SUFDeEQsQ0FBQztDQWNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgREcgZnJvbSAnZGF0YWdyb2stYXBpL2RnJztcbmltcG9ydCB7U3BsaXR0ZXJGdW5jLCBXZWJMb2dvfSBmcm9tICcuLi92aWV3ZXJzL3dlYi1sb2dvJztcblxuLyoqIGVudW0gdHlwZSB0byBzaW1wbGlmeSBzZXR0aW5nIFwidXNlci1mcmllbmRseVwiIG5vdGF0aW9uIGlmIG5lY2Vzc2FyeSAqL1xuZXhwb3J0IGNvbnN0IGVudW0gTk9UQVRJT04ge1xuICBGQVNUQSA9ICdGQVNUQScsXG4gIFNFUEFSQVRPUiA9ICdTRVBBUkFUT1InLFxuICBIRUxNID0gJ0hFTE0nXG59XG5cbi8qKiBDbGFzcyBmb3IgaGFuZGxpbmcgY29udmVyc2lvbiBvZiBub3RhdGlvbiBzeXN0ZW1zIGluIE1hY3JvbW9sZWN1bGUgY29sdW1ucyAqL1xuZXhwb3J0IGNsYXNzIE5vdGF0aW9uQ29udmVydGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBfc291cmNlQ29sdW1uOiBERy5Db2x1bW47IC8vIHRoZSBjb2x1bW4gdG8gYmUgY29udmVydGVkXG4gIHByaXZhdGUgX3NvdXJjZVVuaXRzOiBzdHJpbmc7IC8vIHVuaXRzLCBvZiB0aGUgZm9ybSBmYXN0YTpTRVE6TlQsIGV0Yy5cbiAgcHJpdmF0ZSBfc291cmNlTm90YXRpb246IE5PVEFUSU9OOyAvLyBjdXJyZW50IG5vdGF0aW9uICh3aXRob3V0IDpTRVE6TlQsIGV0Yy4pXG4gIHByaXZhdGUgX2RlZmF1bHRHYXBTeW1ib2w6IHN0cmluZztcbiAgcHJpdmF0ZSBfZGVmYXVsdEdhcFN5bWJvbHNEaWN0ID0ge1xuICAgIEhFTE06ICcqJyxcbiAgICBTRVBBUkFUT1I6ICcnLFxuICAgIEZBU1RBOiAnLScsXG4gIH07XG5cbiAgcHJpdmF0ZSBfc3BsaXR0ZXI6IFNwbGl0dGVyRnVuYyB8IG51bGwgPSBudWxsO1xuICBwcm90ZWN0ZWQgZ2V0IHNwbGl0dGVyKCk6IFNwbGl0dGVyRnVuYyB7XG4gICAgaWYgKHRoaXMuX3NwbGl0dGVyID09PSBudWxsKVxuICAgICAgdGhpcy5fc3BsaXR0ZXIgPSBXZWJMb2dvLmdldFNwbGl0dGVyRm9yQ29sdW1uKHRoaXMuX3NvdXJjZUNvbHVtbik7XG4gICAgcmV0dXJuIHRoaXMuX3NwbGl0dGVyO1xuICB9O1xuXG5cbiAgcHJpdmF0ZSBnZXQgc291cmNlVW5pdHMoKTogc3RyaW5nIHsgcmV0dXJuIHRoaXMuX3NvdXJjZVVuaXRzOyB9XG5cbiAgcHJpdmF0ZSBnZXQgc291cmNlQ29sdW1uKCk6IERHLkNvbHVtbiB7IHJldHVybiB0aGlzLl9zb3VyY2VDb2x1bW47IH1cblxuICBwdWJsaWMgZ2V0IHNvdXJjZU5vdGF0aW9uKCk6IE5PVEFUSU9OIHsgcmV0dXJuIHRoaXMuX3NvdXJjZU5vdGF0aW9uOyB9XG5cbiAgcHVibGljIGdldCBkZWZhdWx0R2FwU3ltYm9sKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLl9kZWZhdWx0R2FwU3ltYm9sOyB9XG5cbiAgcHVibGljIGdldCBzZXBhcmF0b3IoKTogc3RyaW5nIHtcbiAgICBjb25zdCBzZXBhcmF0b3IgPSB0aGlzLnNvdXJjZUNvbHVtbi5nZXRUYWcoJ3NlcGFyYXRvcicpO1xuICAgIGlmIChzZXBhcmF0b3IgIT09IG51bGwpXG4gICAgICByZXR1cm4gc2VwYXJhdG9yO1xuICAgIGVsc2VcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2VwYXJhdG9yIG5vdCBzZXQnKTtcbiAgfVxuXG4gIHB1YmxpYyBpc0Zhc3RhKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5zb3VyY2VOb3RhdGlvbiA9PT0gTk9UQVRJT04uRkFTVEE7IH1cblxuICBwdWJsaWMgaXNTZXBhcmF0b3IoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnNvdXJjZU5vdGF0aW9uID09PSBOT1RBVElPTi5TRVBBUkFUT1I7IH1cblxuICBwdWJsaWMgaXNIZWxtKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5zb3VyY2VOb3RhdGlvbiA9PT0gTk9UQVRJT04uSEVMTTsgfVxuXG4gIHB1YmxpYyB0b0Zhc3RhKHRhcmdldE5vdGF0aW9uOiBOT1RBVElPTik6IGJvb2xlYW4geyByZXR1cm4gdGFyZ2V0Tm90YXRpb24gPT09IE5PVEFUSU9OLkZBU1RBOyB9XG5cbiAgcHVibGljIHRvU2VwYXJhdG9yKHRhcmdldE5vdGF0aW9uOiBOT1RBVElPTik6IGJvb2xlYW4geyByZXR1cm4gdGFyZ2V0Tm90YXRpb24gPT09IE5PVEFUSU9OLlNFUEFSQVRPUjsgfVxuXG4gIHB1YmxpYyB0b0hlbG0odGFyZ2V0Tm90YXRpb246IE5PVEFUSU9OKTogYm9vbGVhbiB7IHJldHVybiB0YXJnZXROb3RhdGlvbiA9PT0gTk9UQVRJT04uSEVMTTsgfVxuXG4gIHB1YmxpYyBpc1JuYSgpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuc291cmNlVW5pdHMudG9Mb3dlckNhc2UoKS5lbmRzV2l0aCgncm5hJyk7IH1cblxuICBwdWJsaWMgaXNEbmEoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnNvdXJjZVVuaXRzLnRvTG93ZXJDYXNlKCkuZW5kc1dpdGgoJ2RuYScpOyB9XG5cbiAgcHVibGljIGlzUGVwdGlkZSgpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuc291cmNlVW5pdHMudG9Mb3dlckNhc2UoKS5lbmRzV2l0aCgncHQnKTsgfVxuXG4gIC8qKiBBc3NvY2lhdGUgbm90YXRpb24gdHlwZXMgd2l0aCB0aGUgY29ycmVzcG9uZGluZyB1bml0cyAqL1xuICAvKipcbiAgICogQHJldHVybiB7Tk9UQVRJT059ICAgICBOb3RhdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhlIHVuaXRzIHR5cGVcbiAgICovXG4gIHByaXZhdGUgZ2V0U291cmNlTm90YXRpb24oKTogTk9UQVRJT04ge1xuICAgIGlmICh0aGlzLnNvdXJjZVVuaXRzLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aCgnZmFzdGEnKSlcbiAgICAgIHJldHVybiBOT1RBVElPTi5GQVNUQTtcbiAgICBlbHNlIGlmICh0aGlzLnNvdXJjZVVuaXRzLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aCgnc2VwYXJhdG9yJykpXG4gICAgICByZXR1cm4gTk9UQVRJT04uU0VQQVJBVE9SO1xuICAgIGVsc2UgaWYgKHRoaXMuc291cmNlVW5pdHMudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKCdoZWxtJykpXG4gICAgICByZXR1cm4gTk9UQVRJT04uSEVMTTtcbiAgICBlbHNlXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjb2x1bW4gaGFzIHVuaXRzIHRoYXQgZG8gbm90IGNvcnJlc3BvbmQgdG8gYW55IG5vdGF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGVtcHR5IGNvbHVtbiBvZiB0aGUgc3BlY2lmaWVkIG5vdGF0aW9uIHR5cGUgYW5kIHRoZSBzYW1lXG4gICAqIGxlbmd0aCBhcyBzb3VyY2VDb2x1bW5cbiAgICpcbiAgICogQHBhcmFtIHtOT1RBVElPTn0gdGFyZ2V0Tm90YXRpb25cbiAgICogQHJldHVybiB7REcuQ29sdW1ufVxuICAgKi9cbiAgcHJpdmF0ZSBnZXROZXdDb2x1bW4odGFyZ2V0Tm90YXRpb246IE5PVEFUSU9OKTogREcuQ29sdW1uIHtcbiAgICBjb25zdCBjb2wgPSB0aGlzLnNvdXJjZUNvbHVtbjtcbiAgICBjb25zdCBsZW4gPSBjb2wubGVuZ3RoO1xuICAgIGNvbnN0IG5hbWUgPSB0YXJnZXROb3RhdGlvbi50b0xvd2VyQ2FzZSgpICsgJygnICsgY29sLm5hbWUgKyAnKSc7XG4gICAgY29uc3QgbmV3Q29sTmFtZSA9IGNvbC5kYXRhRnJhbWUuY29sdW1ucy5nZXRVbnVzZWROYW1lKG5hbWUpO1xuICAgIC8vIGR1bW15IGNvZGVcbiAgICBjb25zdCBuZXdDb2x1bW4gPSBERy5Db2x1bW4uZnJvbUxpc3QoJ3N0cmluZycsIG5ld0NvbE5hbWUsIG5ldyBBcnJheShsZW4pLmZpbGwoJycpKTtcbiAgICBuZXdDb2x1bW4uc2VtVHlwZSA9IERHLlNFTVRZUEUuTUFDUk9NT0xFQ1VMRTtcbiAgICBuZXdDb2x1bW4uc2V0VGFnKFxuICAgICAgREcuVEFHUy5VTklUUyxcbiAgICAgIHRoaXMuc291cmNlVW5pdHMucmVwbGFjZShcbiAgICAgICAgdGhpcy5zb3VyY2VOb3RhdGlvbi50b0xvd2VyQ2FzZSgpLnRvU3RyaW5nKCksXG4gICAgICAgIHRhcmdldE5vdGF0aW9uLnRvTG93ZXJDYXNlKCkudG9TdHJpbmcoKVxuICAgICAgKVxuICAgICk7XG4gICAgLy8gVE9ETzogc3BlY2lmeSBjZWxsIHJlbmRlcmVycyBmb3IgYWxsIGNhc2VzXG4gICAgaWYgKHRoaXMudG9GYXN0YSh0YXJnZXROb3RhdGlvbikpIHtcbiAgICAgIG5ld0NvbHVtbi5zZXRUYWcoXG4gICAgICAgIERHLlRBR1MuQ0VMTF9SRU5ERVJFUixcbiAgICAgICAgJ01hY3JvbW9sZWN1bGUnKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ld0NvbHVtbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgTWFjcm9tb2xlY3VsZSBjb2x1bW4gZnJvbSBGQVNUQSB0byBTRVBBUkFUT1Igbm90YXRpb25cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHNlcGFyYXRvciAgQSBzcGVjaWZpYyBzZXBhcmF0b3IgdG8gYmUgdXNlZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmFzdGFHYXBTeW1ib2wgIEdhcCBzeW1ib2wgaW4gRkFTVEEsICctJyBieSBkZWZhdWx0XG4gICAqIEByZXR1cm4ge0RHLkNvbHVtbn0gICAgICAgIEEgbmV3IGNvbHVtbiBpbiBTRVBBUkFUT1Igbm90YXRpb25cbiAgICovXG4gIHByaXZhdGUgY29udmVydEZhc3RhVG9TZXBhcmF0b3Ioc2VwYXJhdG9yOiBzdHJpbmcsIGZhc3RhR2FwU3ltYm9sOiBzdHJpbmcgfCBudWxsID0gbnVsbCk6IERHLkNvbHVtbiB7XG4gICAgaWYgKGZhc3RhR2FwU3ltYm9sID09PSBudWxsKVxuICAgICAgZmFzdGFHYXBTeW1ib2wgPSB0aGlzLmRlZmF1bHRHYXBTeW1ib2w7XG5cbiAgICBjb25zdCBuZXdDb2x1bW4gPSB0aGlzLmdldE5ld0NvbHVtbihOT1RBVElPTi5TRVBBUkFUT1IpO1xuICAgIC8vIGFzc2lnbiB0aGUgdmFsdWVzIHRvIHRoZSBuZXdseSBjcmVhdGVkIGVtcHR5IGNvbHVtblxuICAgIG5ld0NvbHVtbi5pbml0KChpZHg6IG51bWJlcikgPT4ge1xuICAgICAgY29uc3QgZmFzdGFQb2x5bWVyID0gdGhpcy5zb3VyY2VDb2x1bW4uZ2V0KGlkeCk7XG4gICAgICBjb25zdCBmYXN0YU1vbm9tZXJzQXJyYXkgPSB0aGlzLnNwbGl0dGVyKGZhc3RhUG9seW1lcik7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZhc3RhTW9ub21lcnNBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoZmFzdGFNb25vbWVyc0FycmF5W2ldID09PSBmYXN0YUdhcFN5bWJvbClcbiAgICAgICAgICBmYXN0YU1vbm9tZXJzQXJyYXlbaV0gPSB0aGlzLl9kZWZhdWx0R2FwU3ltYm9sc0RpY3QuU0VQQVJBVE9SO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhc3RhTW9ub21lcnNBcnJheS5qb2luKHNlcGFyYXRvcik7XG4gICAgfSk7XG4gICAgbmV3Q29sdW1uLnNldFRhZygnc2VwYXJhdG9yJywgc2VwYXJhdG9yKTtcbiAgICByZXR1cm4gbmV3Q29sdW1uO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgd3JhcHBlciBzdHJpbmdzIGZvciBIRUxNLCBkZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgdGhlXG4gICAqIG1hY3JvbW9sZWN1bGUgKHBlcHRpZGUsIEROQSwgUk5BKVxuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmdbXX0gQXJyYXkgb2Ygd3JhcHBlcnNcbiAgICovXG4gIHByaXZhdGUgZ2V0SGVsbVdyYXBwZXJzKCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBwcmVmaXggPSAodGhpcy5pc0RuYSgpKSA/ICdETkExeycgOlxuICAgICAgKHRoaXMuaXNSbmEoKSkgPyAnUk5BMXsnIDpcbiAgICAgICAgKHRoaXMuaXNQZXB0aWRlKCkpID8gJ1BFUFRJREUxeycgOlxuICAgICAgICAgICdVbmtub3duJzsgLy8gdGhpcyBjYXNlIHNob3VsZCBiZSBoYW5kbGVkIGFzIGV4Y2VwdGlvbmFsXG5cbiAgICBpZiAocHJlZml4ID09PSAnVW5rbm93bicpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05laXRoZXIgcGVwdGlkZSwgbm9yIG51Y2xlb3RpZGUnKTtcblxuICAgIGNvbnN0IHBvc3RmaXggPSAnfSQkJCc7XG4gICAgY29uc3QgbGVmdFdyYXBwZXIgPSAodGhpcy5pc0RuYSgpKSA/ICdEKCcgOlxuICAgICAgKHRoaXMuaXNSbmEoKSkgPyAnUignIDogJyc7IC8vIG5vIHdyYXBwZXIgZm9yIHBlcHRpZGVzXG4gICAgY29uc3QgcmlnaHRXcmFwcGVyID0gKHRoaXMuaXNEbmEoKSB8fCB0aGlzLmlzUm5hKCkpID8gJylQJyA6ICcnOyAvLyBubyB3cmFwcGVyIGZvciBwZXB0aWRlc1xuICAgIHJldHVybiBbcHJlZml4LCBsZWZ0V3JhcHBlciwgcmlnaHRXcmFwcGVyLCBwb3N0Zml4XTtcbiAgfVxuXG4gIC8vIEEgaGVscGVyIGZ1bmN0aW9uIGZvciBjb252ZXJ0aW5nIHN0cmluZ3MgdG8gSEVMTVxuICBwcml2YXRlIGNvbnZlcnRUb0hlbG1IZWxwZXIoXG4gICAgc291cmNlUG9seW1lcjogc3RyaW5nLFxuICAgIHNvdXJjZUdhcFN5bWJvbDogc3RyaW5nLFxuICAgIHByZWZpeDogc3RyaW5nLFxuICAgIGxlZnRXcmFwcGVyOiBzdHJpbmcsXG4gICAgcmlnaHRXcmFwcGVyOiBzdHJpbmcsXG4gICAgcG9zdGZpeDogc3RyaW5nXG4gICk6IHN0cmluZyB7XG4gICAgY29uc3QgbW9ub21lckFycmF5ID0gdGhpcy5zcGxpdHRlcihzb3VyY2VQb2x5bWVyKTtcbiAgICBjb25zdCBtb25vbWVySGVsbUFycmF5OiBzdHJpbmdbXSA9IG1vbm9tZXJBcnJheS5tYXAoKG1tOiBzdHJpbmcpID0+IHtcbiAgICAgIGlmIChtbSA9PT0gc291cmNlR2FwU3ltYm9sKVxuICAgICAgICByZXR1cm4gdGhpcy5fZGVmYXVsdEdhcFN5bWJvbHNEaWN0LkhFTE07XG4gICAgICBlbHNlXG4gICAgICAgIHJldHVybiBgJHtsZWZ0V3JhcHBlcn0ke21tfSR7cmlnaHRXcmFwcGVyfWA7XG4gICAgfSk7XG4gICAgcmV0dXJuIGAke3ByZWZpeH0ke21vbm9tZXJIZWxtQXJyYXkuam9pbignLicpfSR7cG9zdGZpeH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBzdHJpbmcgd2l0aCBTRVBBUkFUT1IvRkFTVEEgbm90YXRpb24gdG8gSEVMTVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc291cmNlUG9seW1lciAgQSBzdHJpbmcgdG8gYmUgY29udmVydGVkXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVsbH0gc291cmNlR2FwU3ltYm9sICBBbiBvcHRpb25hbCBnYXAgc3ltYm9sLCBzZXQgdG9cbiAgICogZGVmYXVsdCB2YWx1ZXMgKCctJyBmb3IgRkFTVEEgYW5kICcnIGZvciBTRVBBUkFUT1IpIHVubGVzcyBzcGVjaWZpZWRcbiAgICogQHJldHVybiB7c3RyaW5nfSAgVGhlIHRhcmdldCBIRUxNIHN0cmluZ1xuICAgKi9cbiAgcHVibGljIGNvbnZlcnRTdHJpbmdUb0hlbG0oXG4gICAgc291cmNlUG9seW1lcjogc3RyaW5nLFxuICAgIHNvdXJjZUdhcFN5bWJvbDogc3RyaW5nIHwgbnVsbCA9IG51bGxcbiAgKSA6IHN0cmluZyB7XG4gICAgaWYgKHNvdXJjZUdhcFN5bWJvbCA9PT0gbnVsbClcbiAgICAgIHNvdXJjZUdhcFN5bWJvbCA9IHRoaXMuZGVmYXVsdEdhcFN5bWJvbDtcbiAgICBjb25zdCBbcHJlZml4LCBsZWZ0V3JhcHBlciwgcmlnaHRXcmFwcGVyLCBwb3N0Zml4XSA9IHRoaXMuZ2V0SGVsbVdyYXBwZXJzKCk7XG4gICAgcmV0dXJuIHRoaXMuY29udmVydFRvSGVsbUhlbHBlcihzb3VyY2VQb2x5bWVyLCBzb3VyY2VHYXBTeW1ib2wsIHByZWZpeCwgbGVmdFdyYXBwZXIsIHJpZ2h0V3JhcHBlciwgcG9zdGZpeCk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCBhIGNvbHVtbiB0byBIRUxNXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVsbH0gc291cmNlR2FwU3ltYm9sXG4gICAqIEByZXR1cm4ge0RHLkNvbHVtbn1cbiAgICovXG4gIHByaXZhdGUgY29udmVydFRvSGVsbShzb3VyY2VHYXBTeW1ib2w6IHN0cmluZyB8IG51bGwgPSBudWxsKTogREcuQ29sdW1uIHtcbiAgICBpZiAoc291cmNlR2FwU3ltYm9sID09PSBudWxsKVxuICAgICAgc291cmNlR2FwU3ltYm9sID0gdGhpcy5kZWZhdWx0R2FwU3ltYm9sO1xuXG4gICAgY29uc3QgW3ByZWZpeCwgbGVmdFdyYXBwZXIsIHJpZ2h0V3JhcHBlciwgcG9zdGZpeF0gPSB0aGlzLmdldEhlbG1XcmFwcGVycygpO1xuXG4gICAgY29uc3QgbmV3Q29sdW1uID0gdGhpcy5nZXROZXdDb2x1bW4oTk9UQVRJT04uSEVMTSk7XG4gICAgLy8gYXNzaWduIHRoZSB2YWx1ZXMgdG8gdGhlIGVtcHR5IGNvbHVtblxuICAgIG5ld0NvbHVtbi5pbml0KChpZHg6IG51bWJlcikgPT4ge1xuICAgICAgY29uc3Qgc291cmNlUG9seW1lciA9IHRoaXMuc291cmNlQ29sdW1uLmdldChpZHgpO1xuICAgICAgcmV0dXJuIHRoaXMuY29udmVydFRvSGVsbUhlbHBlcihzb3VyY2VQb2x5bWVyLCBzb3VyY2VHYXBTeW1ib2whLCBwcmVmaXgsIGxlZnRXcmFwcGVyLCByaWdodFdyYXBwZXIsIHBvc3RmaXgpO1xuICAgIH0pO1xuICAgIHJldHVybiBuZXdDb2x1bW47XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCBTRVBBUkFUT1IgY29sdW1uIHRvIEZBU1RBIG5vdGF0aW9uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVsbH0gZmFzdGFHYXBTeW1ib2wgT3B0aW9uYWwgZ2FwIHN5bWJvbCBmb3IgRkFTVEFcbiAgICogQHJldHVybiB7REcuQ29sdW1ufSAgQ29udmVydGVkIGNvbHVtblxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0U2VwYXJhdG9yVG9GYXN0YShmYXN0YUdhcFN5bWJvbDogc3RyaW5nIHwgbnVsbCA9IG51bGwpOiBERy5Db2x1bW4ge1xuICAgIGlmIChmYXN0YUdhcFN5bWJvbCA9PT0gbnVsbClcbiAgICAgIGZhc3RhR2FwU3ltYm9sID0gdGhpcy5fZGVmYXVsdEdhcFN5bWJvbHNEaWN0LkZBU1RBO1xuXG4gICAgY29uc3QgbmV3Q29sdW1uID0gdGhpcy5nZXROZXdDb2x1bW4oTk9UQVRJT04uRkFTVEEpO1xuICAgIC8vIGFzc2lnbiB0aGUgdmFsdWVzIHRvIHRoZSBlbXB0eSBjb2x1bW5cbiAgICBuZXdDb2x1bW4uaW5pdCgoaWR4OiBudW1iZXIpID0+IHtcbiAgICAgIGNvbnN0IHNlcGFyYXRvclBvbHltZXIgPSB0aGlzLnNvdXJjZUNvbHVtbi5nZXQoaWR4KTtcbiAgICAgIC8vIGl0ZW1zIGNhbiBiZSBtb25vbWVycyBvciBzZXBhcmF0b3JzXG4gICAgICBjb25zdCBzZXBhcmF0b3JJdGVtc0FycmF5ID0gdGhpcy5zcGxpdHRlcihzZXBhcmF0b3JQb2x5bWVyKTtcbiAgICAgIGNvbnN0IGZhc3RhTW9ub21lcnNBcnJheTogc3RyaW5nW10gPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VwYXJhdG9ySXRlbXNBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBpdGVtID0gc2VwYXJhdG9ySXRlbXNBcnJheVtpXTtcbiAgICAgICAgaWYgKGl0ZW0ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgZmFzdGFNb25vbWVyc0FycmF5LnB1c2goZmFzdGFHYXBTeW1ib2whKTtcbiAgICAgICAgfSBlbHNlIGlmIChpdGVtLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAvLyB0aGUgY2FzZSBvZiBhIG11bHRpLWNoYXJhY3RlciBtb25vbWVyXG4gICAgICAgICAgY29uc3QgbW9ub21lciA9ICdbJyArIGl0ZW0gKyAnXSc7XG4gICAgICAgICAgZmFzdGFNb25vbWVyc0FycmF5LnB1c2gobW9ub21lcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZmFzdGFNb25vbWVyc0FycmF5LnB1c2goaXRlbSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYXN0YU1vbm9tZXJzQXJyYXkuam9pbignJyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ld0NvbHVtbjtcbiAgfVxuXG4gIC8qKlxuICAgKiAgQ29udmVydCBIRUxNIGNvbHVtbiB0byBGQVNUQS9TRVBBUkFUT1JcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRndE5vdGF0aW9uICAgIFRhcmdldCBub3RhdGlvbjogRkFTVEEgb3IgU0VQQVJBVE9SXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0Z3RTZXBhcmF0b3IgICBPcHRpb25hbCB0YXJnZXQgc2VwYXJhdG9yIChmb3IgSEVMTSAtPlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bGx9IHRndEdhcFN5bWJvbCAgIE9wdGlvbmFsIHRhcmdldCBnYXAgc3ltYm9sXG4gICAqIFNFUEFSQVRPUilcbiAgICogQHJldHVybiB7REcuQ29sdW1ufSBDb252ZXJ0ZWQgY29sdW1uXG4gICAqL1xuICBwcml2YXRlIGNvbnZlcnRIZWxtKFxuICAgIHRndE5vdGF0aW9uOiBzdHJpbmcsXG4gICAgdGd0U2VwYXJhdG9yOiBzdHJpbmcgPSAnJyxcbiAgICB0Z3RHYXBTeW1ib2w6IHN0cmluZyB8IG51bGwgPSBudWxsXG4gICk6IERHLkNvbHVtbiB7XG4gICAgLy8gVGhpcyBmdW5jdGlvbiBtdXN0IG5vdCBjb250YWluIGNhbGxzIG9mIGlzRG5hKCkgYW5kIGlzUm5hKCksIGZvclxuICAgIC8vIHNvdXJjZSBoZWxtIGNvbHVtbnMgbWF5IGNvbnRhaW4gUk5BLCBETkEgYW5kIFBUIGFjcm9zcyBkaWZmZXJlbnQgcm93c1xuICAgIGlmICh0Z3RHYXBTeW1ib2wgPT09IG51bGwpIHtcbiAgICAgIHRndEdhcFN5bWJvbCA9ICh0aGlzLnRvRmFzdGEodGd0Tm90YXRpb24gYXMgTk9UQVRJT04pKSA/XG4gICAgICAgIHRoaXMuX2RlZmF1bHRHYXBTeW1ib2xzRGljdC5GQVNUQSA6XG4gICAgICAgIHRoaXMuX2RlZmF1bHRHYXBTeW1ib2xzRGljdC5TRVBBUkFUT1I7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudG9TZXBhcmF0b3IodGd0Tm90YXRpb24gYXMgTk9UQVRJT04pICYmIHRndFNlcGFyYXRvciA9PT0gJycpXG4gICAgICB0Z3RTZXBhcmF0b3IgPSB0aGlzLnNlcGFyYXRvcjtcblxuICAgIGNvbnN0IGhlbG1XcmFwcGVyc1JlID0gLyhSXFwofERcXCh8XFwpfFApL2c7XG4gICAgY29uc3QgbmV3Q29sdW1uID0gdGhpcy5nZXROZXdDb2x1bW4odGd0Tm90YXRpb24gYXMgTk9UQVRJT04pO1xuICAgIC8vIGFzc2lnbiB0aGUgdmFsdWVzIHRvIHRoZSBlbXB0eSBjb2x1bW5cbiAgICBuZXdDb2x1bW4uaW5pdCgoaWR4OiBudW1iZXIpID0+IHtcbiAgICAgIGNvbnN0IGhlbG1Qb2x5bWVyID0gdGhpcy5zb3VyY2VDb2x1bW4uZ2V0KGlkeCk7XG5cbiAgICAgIC8vIHdlIGNhbm5vdCB1c2UgaXNEbmEoKSBvciBpc1JuYSgpIGJlY2F1c2Ugc291cmNlIGhlbG0gY29sdW1ucyBjYW5cbiAgICAgIC8vIGNvbnRhaW4gRE5BLCBSTkEgYW5kIFBUIGluIGRpZmZlcmVudCBjZWxscywgc28gdGhlIGNvcnJlc3BvbmRpbmdcbiAgICAgIC8vIHRhZ3MgY2Fubm90IGJlIHNldCBmb3IgdGhlIHdob2xlIGNvbHVtblxuICAgICAgY29uc3QgaXNOdWNsZW90aWRlID0gaGVsbVBvbHltZXIuc3RhcnRzV2l0aCgnRE5BJykgfHwgaGVsbVBvbHltZXIuc3RhcnRzV2l0aCgnUk5BJyk7XG5cbiAgICAgIC8vIGl0ZW1zIGNhbiBiZSBtb25vbWVycyBvciBoZWxtc1xuICAgICAgY29uc3QgaGVsbUl0ZW1zQXJyYXkgPSB0aGlzLnNwbGl0dGVyKGhlbG1Qb2x5bWVyKTtcbiAgICAgIGNvbnN0IHRndE1vbm9tZXJzQXJyYXk6IHN0cmluZ1tdID0gW107XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhlbG1JdGVtc0FycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBpdGVtID0gaGVsbUl0ZW1zQXJyYXlbaV07XG4gICAgICAgIGlmIChpc051Y2xlb3RpZGUpXG4gICAgICAgICAgaXRlbSA9IGl0ZW0ucmVwbGFjZShoZWxtV3JhcHBlcnNSZSwgJycpO1xuICAgICAgICBpZiAoaXRlbSA9PT0gdGhpcy5fZGVmYXVsdEdhcFN5bWJvbHNEaWN0LkhFTE0pIHtcbiAgICAgICAgICB0Z3RNb25vbWVyc0FycmF5LnB1c2godGd0R2FwU3ltYm9sISk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy50b0Zhc3RhKHRndE5vdGF0aW9uIGFzIE5PVEFUSU9OKSAmJiBpdGVtLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAvLyB0aGUgY2FzZSBvZiBhIG11bHRpLWNoYXJhY3RlciBtb25vbWVyIGNvbnZlcnRlZCB0byBGQVNUQVxuICAgICAgICAgIGNvbnN0IG1vbm9tZXIgPSAnWycgKyBpdGVtICsgJ10nO1xuICAgICAgICAgIHRndE1vbm9tZXJzQXJyYXkucHVzaChtb25vbWVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0Z3RNb25vbWVyc0FycmF5LnB1c2goaXRlbSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0Z3RNb25vbWVyc0FycmF5LmpvaW4odGd0U2VwYXJhdG9yKTtcbiAgICB9KTtcbiAgICByZXR1cm4gbmV3Q29sdW1uO1xuICB9XG5cbiAgcHJpdmF0ZSBjb252ZXJ0SGVsbVRvU2VwYXJhdG9yKCk6IERHLkNvbHVtbiB7XG4gICAgLy8gVE9ETzogaW1wbGVtZW50YXRpb3JldHVybiB0aGlzLmdldE5ld0NvbHVtbigpO1xuICAgIHJldHVybiB0aGlzLmdldE5ld0NvbHVtbihOT1RBVElPTi5TRVBBUkFUT1IpO1xuICB9XG5cbiAgLyoqIERpc3BhdGNoZXIgbWV0aG9kIGZvciBub3RhdGlvbiBjb252ZXJzaW9uXG4gICAqXG4gICAqIEBwYXJhbSB7Tk9UQVRJT059IHRndE5vdGF0aW9uICAgTm90YXRpb24gd2Ugd2FudCB0byBjb252ZXJ0IHRvXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVsbH0gdGd0U2VwYXJhdG9yICAgUG9zc2libGUgc2VwYXJhdG9yXG4gICAqIEByZXR1cm4ge0RHLkNvbHVtbn0gICAgICAgICAgICAgICAgQ29udmVydGVkIGNvbHVtblxuICAgKi9cbiAgcHVibGljIGNvbnZlcnQodGd0Tm90YXRpb246IE5PVEFUSU9OLCB0Z3RTZXBhcmF0b3I6IHN0cmluZyB8IG51bGwgPSBudWxsKTogREcuQ29sdW1uIHtcbiAgICAvLyBwb3NzaWJsZSBleGNlcHRpb25zXG4gICAgaWYgKHRoaXMuc291cmNlTm90YXRpb24gPT09IHRndE5vdGF0aW9uKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0Z3Qgbm90YXRpb24gaXMgaW52YWxpZCcpO1xuICAgIGlmICh0aGlzLnRvU2VwYXJhdG9yKHRndE5vdGF0aW9uKSAmJiB0Z3RTZXBhcmF0b3IgPT09IG51bGwpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RndCBzZXBhcmF0b3IgaXMgbm90IHNwZWNpZmllZCcpO1xuXG4gICAgaWYgKHRoaXMuaXNGYXN0YSgpICYmIHRoaXMudG9TZXBhcmF0b3IodGd0Tm90YXRpb24pICYmIHRndFNlcGFyYXRvciAhPT0gbnVsbClcbiAgICAgIHJldHVybiB0aGlzLmNvbnZlcnRGYXN0YVRvU2VwYXJhdG9yKHRndFNlcGFyYXRvcik7XG4gICAgZWxzZSBpZiAoKHRoaXMuaXNGYXN0YSgpIHx8IHRoaXMuaXNTZXBhcmF0b3IoKSkgJiYgdGhpcy50b0hlbG0odGd0Tm90YXRpb24pKVxuICAgICAgcmV0dXJuIHRoaXMuY29udmVydFRvSGVsbSgpO1xuICAgIGVsc2UgaWYgKHRoaXMuaXNTZXBhcmF0b3IoKSAmJiB0aGlzLnRvRmFzdGEodGd0Tm90YXRpb24pKVxuICAgICAgcmV0dXJuIHRoaXMuY29udmVydFNlcGFyYXRvclRvRmFzdGEoKTtcbiAgICBlbHNlIGlmICh0aGlzLmlzSGVsbSgpICYmIHRoaXMudG9GYXN0YSh0Z3ROb3RhdGlvbikpIC8vIHRoZSBjYXNlIG9mIEhFTE1cbiAgICAgIHJldHVybiB0aGlzLmNvbnZlcnRIZWxtKHRndE5vdGF0aW9uKTtcbiAgICBlbHNlIC8vIHRoaXMuaXNIZWxtKCkgJiYgdGhpcy50b1NlcGFyYXRvcih0Z3ROb3RhdGlvbilcbiAgICAgIHJldHVybiB0aGlzLmNvbnZlcnRIZWxtKHRndE5vdGF0aW9uLCB0Z3RTZXBhcmF0b3IhKTtcbiAgfVxuXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihjb2w6IERHLkNvbHVtbikge1xuICAgIHRoaXMuX3NvdXJjZUNvbHVtbiA9IGNvbDtcbiAgICBjb25zdCB1bml0cyA9IHRoaXMuX3NvdXJjZUNvbHVtbi50YWdzW0RHLlRBR1MuVU5JVFNdO1xuICAgIGlmICh1bml0cyAhPT0gbnVsbClcbiAgICAgIHRoaXMuX3NvdXJjZVVuaXRzID0gdW5pdHM7XG4gICAgZWxzZVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbml0cyBhcmUgbm90IHNwZWNpZmllZCBpbiBjb2x1bW4nKTtcbiAgICB0aGlzLl9zb3VyY2VOb3RhdGlvbiA9IHRoaXMuZ2V0U291cmNlTm90YXRpb24oKTtcbiAgICB0aGlzLl9kZWZhdWx0R2FwU3ltYm9sID0gKHRoaXMuaXNGYXN0YSgpKSA/IHRoaXMuX2RlZmF1bHRHYXBTeW1ib2xzRGljdC5GQVNUQSA6XG4gICAgICAodGhpcy5pc0hlbG0oKSkgPyB0aGlzLl9kZWZhdWx0R2FwU3ltYm9sc0RpY3QuSEVMTSA6XG4gICAgICAgIHRoaXMuX2RlZmF1bHRHYXBTeW1ib2xzRGljdC5TRVBBUkFUT1I7XG4gIH1cbn1cbiJdfQ==
217
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90YXRpb24tY29udmVydGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibm90YXRpb24tY29udmVydGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUlBLE9BQU8sRUFBZSxPQUFPLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUMxRCxPQUFPLEVBQUMsWUFBWSxFQUFXLE1BQU0saUJBQWlCLENBQUM7QUFFdkQsaUZBQWlGO0FBQ2pGLE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxZQUFZO0lBa1BqRCxZQUFtQixHQUFjO1FBQy9CLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQWxQTCxjQUFTLEdBQXdCLElBQUksQ0FBQztJQW1QOUMsQ0FBQztJQWxQRCxJQUFjLFFBQVE7UUFDcEIsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLElBQUk7WUFDekIsSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzdELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN4QixDQUFDO0lBQUEsQ0FBQztJQUVLLE9BQU8sQ0FBQyxjQUF3QixJQUFhLE9BQU8sY0FBYyxpQ0FBbUIsQ0FBQyxDQUFDLENBQUM7SUFFeEYsV0FBVyxDQUFDLGNBQXdCLElBQWEsT0FBTyxjQUFjLHlDQUF1QixDQUFDLENBQUMsQ0FBQztJQUVoRyxNQUFNLENBQUMsY0FBd0IsSUFBYSxPQUFPLGNBQWMsK0JBQWtCLENBQUMsQ0FBQyxDQUFDO0lBRTdGOzs7Ozs7T0FNRztJQUNLLHVCQUF1QixDQUFDLFNBQWlCLEVBQUUsaUJBQWdDLElBQUk7UUFDckYsSUFBSSxjQUFjLEtBQUssSUFBSTtZQUN6QixjQUFjLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBRXpDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLHNDQUFvQixDQUFDO1FBQ3hELHNEQUFzRDtRQUN0RCxTQUFTLENBQUMsSUFBSSxDQUFDLENB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QUM7YUFDL0MsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQztZQUN6RSxPQUFPLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQzthQUN6QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQztZQUN0RCxPQUFPLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO2FBQ25DLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsbUJBQW1CO1lBQ3RFLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQzthQUNsQyxpREFBaUQ7WUFDcEQsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxZQUFhLENBQUMsQ0FBQztJQUN4RCxDQUFDO0NBS0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBEbyBub3QgY2hhbmdlIHRoZXNlIGltcG9ydCBsaW5lcyB0byBtYXRjaCBleHRlcm5hbCBtb2R1bGVzIGluIHdlYnBhY2sgY29uZmlndXJhdGlvbiAqL1xuaW1wb3J0ICogYXMgZ3JvayBmcm9tICdkYXRhZ3Jvay1hcGkvZ3Jvayc7XG5pbXBvcnQgKiBhcyB1aSBmcm9tICdkYXRhZ3Jvay1hcGkvdWknO1xuaW1wb3J0ICogYXMgREcgZnJvbSAnZGF0YWdyb2stYXBpL2RnJztcbmltcG9ydCB7U3BsaXR0ZXJGdW5jLCBXZWJMb2dvfSBmcm9tICcuLi92aWV3ZXJzL3dlYi1sb2dvJztcbmltcG9ydCB7VW5pdHNIYW5kbGVyLCBOT1RBVElPTn0gZnJvbSAnLi91bml0cy1oYW5kbGVyJztcblxuLyoqIENsYXNzIGZvciBoYW5kbGluZyBjb252ZXJzaW9uIG9mIG5vdGF0aW9uIHN5c3RlbXMgaW4gTWFjcm9tb2xlY3VsZSBjb2x1bW5zICovXG5leHBvcnQgY2xhc3MgTm90YXRpb25Db252ZXJ0ZXIgZXh0ZW5kcyBVbml0c0hhbmRsZXIge1xuICBwcml2YXRlIF9zcGxpdHRlcjogU3BsaXR0ZXJGdW5jIHwgbnVsbCA9IG51bGw7XG4gIHByb3RlY3RlZCBnZXQgc3BsaXR0ZXIoKTogU3BsaXR0ZXJGdW5jIHtcbiAgICBpZiAodGhpcy5fc3BsaXR0ZXIgPT09IG51bGwpXG4gICAgICB0aGlzLl9zcGxpdHRlciA9IFdlYkxvZ28uZ2V0U3BsaXR0ZXJGb3JDb2x1bW4odGhpcy5jb2x1bW4pO1xuICAgIHJldHVybiB0aGlzLl9zcGxpdHRlcjtcbiAgfTtcblxuICBwdWJsaWMgdG9GYXN0YSh0YXJnZXROb3RhdGlvbjogTk9UQVRJT04pOiBib29sZWFuIHsgcmV0dXJuIHRhcmdldE5vdGF0aW9uID09PSBOT1RBVElPTi5GQVNUQTsgfVxuXG4gIHB1YmxpYyB0b1NlcGFyYXRvcih0YXJnZXROb3RhdGlvbjogTk9UQVRJT04pOiBib29sZWFuIHsgcmV0dXJuIHRhcmdldE5vdGF0aW9uID09PSBOT1RBVElPTi5TRVBBUkFUT1I7IH1cblxuICBwdWJsaWMgdG9IZWxtKHRhcmdldE5vdGF0aW9uOiBOT1RBVElPTik6IGJvb2xlYW4geyByZXR1cm4gdGFyZ2V0Tm90YXRpb24gPT09IE5PVEFUSU9OLkhFTE07IH1cblxuICAvKipcbiAgICogQ29udmVydCBhIE1hY3JvbW9sZWN1bGUgY29sdW1uIGZyb20gRkFTVEEgdG8gU0VQQVJBVE9SIG5vdGF0aW9uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzZXBhcmF0b3IgIEEgc3BlY2lmaWMgc2VwYXJhdG9yIHRvIGJlIHVzZWRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZhc3RhR2FwU3ltYm9sICBHYXAgc3ltYm9sIGluIEZBU1RBLCAnLScgYnkgZGVmYXVsdFxuICAgKiBAcmV0dXJuIHtERy5Db2x1bW59ICAgICAgICBBIG5ldyBjb2x1bW4gaW4gU0VQQVJBVE9SIG5vdGF0aW9uXG4gICAqL1xuICBwcml2YXRlIGNvbnZlcnRGYXN0YVRvU2VwYXJhdG9yKHNlcGFyYXRvcjogc3RyaW5nLCBmYXN0YUdhcFN5bWJvbDogc3RyaW5nIHwgbnVsbCA9IG51bGwpOiBERy5Db2x1bW4ge1xuICAgIGlmIChmYXN0YUdhcFN5bWJvbCA9PT0gbnVsbClcbiAgICAgIGZhc3RhR2FwU3ltYm9sID0gdGhpcy5kZWZhdWx0R2FwU3ltYm9sO1xuXG4gICAgY29uc3QgbmV3Q29sdW1uID0gdGhpcy5nZXROZXdDb2x1bW4oTk9UQVRJT04uU0VQQVJBVE9SKTtcbiAgICAvLyBhc3NpZ24gdGhlIHZhbHVlcyB0byB0aGUgbmV3bHkgY3JlYXRlZCBlbXB0eSBjb2x1bW5cbiAgICBuZXdDb2x1bW4uaW5pdCgoaWR4OiBudW1iZXIpID0+IHtcbiAgICAgIGNvbnN0IGZhc3RhUG9seW1lciA9IHRoaXMuY29sdW1uLmdldChpZHgpO1xuICAgICAgY29uc3QgZmFzdGFNb25vbWVyc0FycmF5ID0gdGhpcy5zcGxpdHRlcihmYXN0YVBvbHltZXIpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmYXN0YU1vbm9tZXJzQXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGZhc3RhTW9ub21lcnNBcnJheVtpXSA9PT0gZmFzdGFHYXBTeW1ib2wpXG4gICAgICAgICAgZmFzdGFNb25vbWVyc0FycmF5W2ldID0gdGhpcy5fZGVmYXVsdEdhcFN5bWJvbHNEaWN0LlNFUEFSQVRPUjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYXN0YU1vbm9tZXJzQXJyYXkuam9pbihzZXBhcmF0b3IpO1xuICAgIH0pO1xuICAgIG5ld0NvbHVtbi5zZXRUYWcoJ3NlcGFyYXRvcicsIHNlcGFyYXRvcik7XG4gICAgcmV0dXJuIG5ld0NvbHVtbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHdyYXBwZXIgc3RyaW5ncyBmb3IgSEVMTSwgZGVwZW5kaW5nIG9uIHRoZSB0eXBlIG9mIHRoZVxuICAgKiBtYWNyb21vbGVjdWxlIChwZXB0aWRlLCBETkEsIFJOQSlcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nW119IEFycmF5IG9mIHdyYXBwZXJzXG4gICAqL1xuICBwcml2YXRlIGdldEhlbG1XcmFwcGVycygpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgcHJlZml4ID0gKHRoaXMuaXNEbmEoKSkgPyAnRE5BMXsnIDpcbiAgICAgICh0aGlzLmlzUm5hKCkpID8gJ1JOQTF7JyA6XG4gICAgICAgICh0aGlzLmlzUGVwdGlkZSgpKSA/ICdQRVBUSURFMXsnIDpcbiAgICAgICAgICAnVW5rbm93bic7IC8vIHRoaXMgY2FzZSBzaG91bGQgYmUgaGFuZGxlZCBhcyBleGNlcHRpb25hbFxuXG4gICAgaWYgKHByZWZpeCA9PT0gJ1Vua25vd24nKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOZWl0aGVyIHBlcHRpZGUsIG5vciBudWNsZW90aWRlJyk7XG5cbiAgICBjb25zdCBwb3N0Zml4ID0gJ30kJCQnO1xuICAgIGNvbnN0IGxlZnRXcmFwcGVyID0gKHRoaXMuaXNEbmEoKSkgPyAnRCgnIDpcbiAgICAgICh0aGlzLmlzUm5hKCkpID8gJ1IoJyA6ICcnOyAvLyBubyB3cmFwcGVyIGZvciBwZXB0aWRlc1xuICAgIGNvbnN0IHJpZ2h0V3JhcHBlciA9ICh0aGlzLmlzRG5hKCkgfHwgdGhpcy5pc1JuYSgpKSA/ICcpUCcgOiAnJzsgLy8gbm8gd3JhcHBlciBmb3IgcGVwdGlkZXNcbiAgICByZXR1cm4gW3ByZWZpeCwgbGVmdFdyYXBwZXIsIHJpZ2h0V3JhcHBlciwgcG9zdGZpeF07XG4gIH1cblxuICAvLyBBIGhlbHBlciBmdW5jdGlvbiBmb3IgY29udmVydGluZyBzdHJpbmdzIHRvIEhFTE1cbiAgcHJpdmF0ZSBjb252ZXJ0VG9IZWxtSGVscGVyKFxuICAgIHNvdXJjZVBvbHltZXI6IHN0cmluZyxcbiAgICBzb3VyY2VHYXBTeW1ib2w6IHN0cmluZyxcbiAgICBwcmVmaXg6IHN0cmluZyxcbiAgICBsZWZ0V3JhcHBlcjogc3RyaW5nLFxuICAgIHJpZ2h0V3JhcHBlcjogc3RyaW5nLFxuICAgIHBvc3RmaXg6IHN0cmluZ1xuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IG1vbm9tZXJBcnJheSA9IHRoaXMuc3BsaXR0ZXIoc291cmNlUG9seW1lcik7XG4gICAgY29uc3QgbW9ub21lckhlbG1BcnJheTogc3RyaW5nW10gPSBtb25vbWVyQXJyYXkubWFwKChtbTogc3RyaW5nKSA9PiB7XG4gICAgICBpZiAobW0gPT09IHNvdXJjZUdhcFN5bWJvbClcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRHYXBTeW1ib2xzRGljdC5IRUxNO1xuICAgICAgZWxzZVxuICAgICAgICByZXR1cm4gYCR7bGVmdFdyYXBwZXJ9JHttbX0ke3JpZ2h0V3JhcHBlcn1gO1xuICAgIH0pO1xuICAgIHJldHVybiBgJHtwcmVmaXh9JHttb25vbWVySGVsbUFycmF5LmpvaW4oJy4nKX0ke3Bvc3RmaXh9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgc3RyaW5nIHdpdGggU0VQQVJBVE9SL0ZBU1RBIG5vdGF0aW9uIHRvIEhFTE1cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZVBvbHltZXIgIEEgc3RyaW5nIHRvIGJlIGNvbnZlcnRlZFxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bGx9IHNvdXJjZUdhcFN5bWJvbCAgQW4gb3B0aW9uYWwgZ2FwIHN5bWJvbCwgc2V0IHRvXG4gICAqIGRlZmF1bHQgdmFsdWVzICgnLScgZm9yIEZBU1RBIGFuZCAnJyBmb3IgU0VQQVJBVE9SKSB1bmxlc3Mgc3BlY2lmaWVkXG4gICAqIEByZXR1cm4ge3N0cmluZ30gIFRoZSB0YXJnZXQgSEVMTSBzdHJpbmdcbiAgICovXG4gIHB1YmxpYyBjb252ZXJ0U3RyaW5nVG9IZWxtKFxuICAgIHNvdXJjZVBvbHltZXI6IHN0cmluZyxcbiAgICBzb3VyY2VHYXBTeW1ib2w6IHN0cmluZyB8IG51bGwgPSBudWxsXG4gICkgOiBzdHJpbmcge1xuICAgIGlmIChzb3VyY2VHYXBTeW1ib2wgPT09IG51bGwpXG4gICAgICBzb3VyY2VHYXBTeW1ib2wgPSB0aGlzLmRlZmF1bHRHYXBTeW1ib2w7XG4gICAgY29uc3QgW3ByZWZpeCwgbGVmdFdyYXBwZXIsIHJpZ2h0V3JhcHBlciwgcG9zdGZpeF0gPSB0aGlzLmdldEhlbG1XcmFwcGVycygpO1xuICAgIHJldHVybiB0aGlzLmNvbnZlcnRUb0hlbG1IZWxwZXIoc291cmNlUG9seW1lciwgc291cmNlR2FwU3ltYm9sLCBwcmVmaXgsIGxlZnRXcmFwcGVyLCByaWdodFdyYXBwZXIsIHBvc3RmaXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBjb2x1bW4gdG8gSEVMTVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bGx9IHNvdXJjZUdhcFN5bWJvbFxuICAgKiBAcmV0dXJuIHtERy5Db2x1bW59XG4gICAqL1xuICBwcml2YXRlIGNvbnZlcnRUb0hlbG0oc291cmNlR2FwU3ltYm9sOiBzdHJpbmcgfCBudWxsID0gbnVsbCk6IERHLkNvbHVtbiB7XG4gICAgaWYgKHNvdXJjZUdhcFN5bWJvbCA9PT0gbnVsbClcbiAgICAgIHNvdXJjZUdhcFN5bWJvbCA9IHRoaXMuZGVmYXVsdEdhcFN5bWJvbDtcblxuICAgIGNvbnN0IFtwcmVmaXgsIGxlZnRXcmFwcGVyLCByaWdodFdyYXBwZXIsIHBvc3RmaXhdID0gdGhpcy5nZXRIZWxtV3JhcHBlcnMoKTtcblxuICAgIGNvbnN0IG5ld0NvbHVtbiA9IHRoaXMuZ2V0TmV3Q29sdW1uKE5PVEFUSU9OLkhFTE0pO1xuICAgIC8vIGFzc2lnbiB0aGUgdmFsdWVzIHRvIHRoZSBlbXB0eSBjb2x1bW5cbiAgICBuZXdDb2x1bW4uaW5pdCgoaWR4OiBudW1iZXIpID0+IHtcbiAgICAgIGNvbnN0IHNvdXJjZVBvbHltZXIgPSB0aGlzLmNvbHVtbi5nZXQoaWR4KTtcbiAgICAgIHJldHVybiB0aGlzLmNvbnZlcnRUb0hlbG1IZWxwZXIoc291cmNlUG9seW1lciwgc291cmNlR2FwU3ltYm9sISwgcHJlZml4LCBsZWZ0V3JhcHBlciwgcmlnaHRXcmFwcGVyLCBwb3N0Zml4KTtcbiAgICB9KTtcbiAgICByZXR1cm4gbmV3Q29sdW1uO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgU0VQQVJBVE9SIGNvbHVtbiB0byBGQVNUQSBub3RhdGlvblxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bGx9IGZhc3RhR2FwU3ltYm9sIE9wdGlvbmFsIGdhcCBzeW1ib2wgZm9yIEZBU1RBXG4gICAqIEByZXR1cm4ge0RHLkNvbHVtbn0gIENvbnZlcnRlZCBjb2x1bW5cbiAgICovXG4gIHByaXZhdGUgY29udmVydFNlcGFyYXRvclRvRmFzdGEoZmFzdGFHYXBTeW1ib2w6IHN0cmluZyB8IG51bGwgPSBudWxsKTogREcuQ29sdW1uIHtcbiAgICBpZiAoZmFzdGFHYXBTeW1ib2wgPT09IG51bGwpXG4gICAgICBmYXN0YUdhcFN5bWJvbCA9IHRoaXMuX2RlZmF1bHRHYXBTeW1ib2xzRGljdC5GQVNUQTtcblxuICAgIGNvbnN0IG5ld0NvbHVtbiA9IHRoaXMuZ2V0TmV3Q29sdW1uKE5PVEFUSU9OLkZBU1RBKTtcbiAgICAvLyBhc3NpZ24gdGhlIHZhbHVlcyB0byB0aGUgZW1wdHkgY29sdW1uXG4gICAgbmV3Q29sdW1uLmluaXQoKGlkeDogbnVtYmVyKSA9PiB7XG4gICAgICBjb25zdCBzZXBhcmF0b3JQb2x5bWVyID0gdGhpcy5jb2x1bW4uZ2V0KGlkeCk7XG4gICAgICAvLyBpdGVtcyBjYW4gYmUgbW9ub21lcnMgb3Igc2VwYXJhdG9yc1xuICAgICAgY29uc3Qgc2VwYXJhdG9ySXRlbXNBcnJheSA9IHRoaXMuc3BsaXR0ZXIoc2VwYXJhdG9yUG9seW1lcik7XG4gICAgICBjb25zdCBmYXN0YU1vbm9tZXJzQXJyYXk6IHN0cmluZ1tdID0gW107XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlcGFyYXRvckl0ZW1zQXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgaXRlbSA9IHNlcGFyYXRvckl0ZW1zQXJyYXlbaV07XG4gICAgICAgIGlmIChpdGVtLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGZhc3RhTW9ub21lcnNBcnJheS5wdXNoKGZhc3RhR2FwU3ltYm9sISk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXRlbS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgLy8gdGhlIGNhc2Ugb2YgYSBtdWx0aS1jaGFyYWN0ZXIgbW9ub21lclxuICAgICAgICAgIGNvbnN0IG1vbm9tZXIgPSAnWycgKyBpdGVtICsgJ10nO1xuICAgICAgICAgIGZhc3RhTW9ub21lcnNBcnJheS5wdXNoKG1vbm9tZXIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZhc3RhTW9ub21lcnNBcnJheS5wdXNoKGl0ZW0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFzdGFNb25vbWVyc0FycmF5LmpvaW4oJycpO1xuICAgIH0pO1xuICAgIHJldHVybiBuZXdDb2x1bW47XG4gIH1cblxuICAvKipcbiAgICogIENvbnZlcnQgSEVMTSBjb2x1bW4gdG8gRkFTVEEvU0VQQVJBVE9SXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0Z3ROb3RhdGlvbiAgICBUYXJnZXQgbm90YXRpb246IEZBU1RBIG9yIFNFUEFSQVRPUlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGd0U2VwYXJhdG9yICAgT3B0aW9uYWwgdGFyZ2V0IHNlcGFyYXRvciAoZm9yIEhFTE0gLT5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBudWxsfSB0Z3RHYXBTeW1ib2wgICBPcHRpb25hbCB0YXJnZXQgZ2FwIHN5bWJvbFxuICAgKiBTRVBBUkFUT1IpXG4gICAqIEByZXR1cm4ge0RHLkNvbHVtbn0gQ29udmVydGVkIGNvbHVtblxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0SGVsbShcbiAgICB0Z3ROb3RhdGlvbjogc3RyaW5nLFxuICAgIHRndFNlcGFyYXRvcjogc3RyaW5nID0gJycsXG4gICAgdGd0R2FwU3ltYm9sOiBzdHJpbmcgfCBudWxsID0gbnVsbFxuICApOiBERy5Db2x1bW4ge1xuICAgIC8vIFRoaXMgZnVuY3Rpb24gbXVzdCBub3QgY29udGFpbiBjYWxscyBvZiBpc0RuYSgpIGFuZCBpc1JuYSgpLCBmb3JcbiAgICAvLyBzb3VyY2UgaGVsbSBjb2x1bW5zIG1heSBjb250YWluIFJOQSwgRE5BIGFuZCBQVCBhY3Jvc3MgZGlmZmVyZW50IHJvd3NcbiAgICBpZiAodGd0R2FwU3ltYm9sID09PSBudWxsKSB7XG4gICAgICB0Z3RHYXBTeW1ib2wgPSAodGhpcy50b0Zhc3RhKHRndE5vdGF0aW9uIGFzIE5PVEFUSU9OKSkgP1xuICAgICAgICB0aGlzLl9kZWZhdWx0R2FwU3ltYm9sc0RpY3QuRkFTVEEgOlxuICAgICAgICB0aGlzLl9kZWZhdWx0R2FwU3ltYm9sc0RpY3QuU0VQQVJBVE9SO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRvU2VwYXJhdG9yKHRndE5vdGF0aW9uIGFzIE5PVEFUSU9OKSAmJiB0Z3RTZXBhcmF0b3IgPT09ICcnKVxuICAgICAgdGd0U2VwYXJhdG9yID0gdGhpcy5zZXBhcmF0b3I7XG5cbiAgICBjb25zdCBoZWxtV3JhcHBlcnNSZSA9IC8oUlxcKHxEXFwofFxcKXxQKS9nO1xuICAgIGNvbnN0IG5ld0NvbHVtbiA9IHRoaXMuZ2V0TmV3Q29sdW1uKHRndE5vdGF0aW9uIGFzIE5PVEFUSU9OKTtcbiAgICAvLyBhc3NpZ24gdGhlIHZhbHVlcyB0byB0aGUgZW1wdHkgY29sdW1uXG4gICAgbmV3Q29sdW1uLmluaXQoKGlkeDogbnVtYmVyKSA9PiB7XG4gICAgICBjb25zdCBoZWxtUG9seW1lciA9IHRoaXMuY29sdW1uLmdldChpZHgpO1xuXG4gICAgICAvLyB3ZSBjYW5ub3QgdXNlIGlzRG5hKCkgb3IgaXNSbmEoKSBiZWNhdXNlIHNvdXJjZSBoZWxtIGNvbHVtbnMgY2FuXG4gICAgICAvLyBjb250YWluIEROQSwgUk5BIGFuZCBQVCBpbiBkaWZmZXJlbnQgY2VsbHMsIHNvIHRoZSBjb3JyZXNwb25kaW5nXG4gICAgICAvLyB0YWdzIGNhbm5vdCBiZSBzZXQgZm9yIHRoZSB3aG9sZSBjb2x1bW5cbiAgICAgIGNvbnN0IGlzTnVjbGVvdGlkZSA9IGhlbG1Qb2x5bWVyLnN0YXJ0c1dpdGgoJ0ROQScpIHx8IGhlbG1Qb2x5bWVyLnN0YXJ0c1dpdGgoJ1JOQScpO1xuXG4gICAgICAvLyBpdGVtcyBjYW4gYmUgbW9ub21lcnMgb3IgaGVsbXNcbiAgICAgIGNvbnN0IGhlbG1JdGVtc0FycmF5ID0gdGhpcy5zcGxpdHRlcihoZWxtUG9seW1lcik7XG4gICAgICBjb25zdCB0Z3RNb25vbWVyc0FycmF5OiBzdHJpbmdbXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoZWxtSXRlbXNBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgaXRlbSA9IGhlbG1JdGVtc0FycmF5W2ldO1xuICAgICAgICBpZiAoaXNOdWNsZW90aWRlKVxuICAgICAgICAgIGl0ZW0gPSBpdGVtLnJlcGxhY2UoaGVsbVdyYXBwZXJzUmUsICcnKTtcbiAgICAgICAgaWYgKGl0ZW0gPT09IHRoaXMuX2RlZmF1bHRHYXBTeW1ib2xzRGljdC5IRUxNKSB7XG4gICAgICAgICAgdGd0TW9ub21lcnNBcnJheS5wdXNoKHRndEdhcFN5bWJvbCEpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudG9GYXN0YSh0Z3ROb3RhdGlvbiBhcyBOT1RBVElPTikgJiYgaXRlbS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgLy8gdGhlIGNhc2Ugb2YgYSBtdWx0aS1jaGFyYWN0ZXIgbW9ub21lciBjb252ZXJ0ZWQgdG8gRkFTVEFcbiAgICAgICAgICBjb25zdCBtb25vbWVyID0gJ1snICsgaXRlbSArICddJztcbiAgICAgICAgICB0Z3RNb25vbWVyc0FycmF5LnB1c2gobW9ub21lcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGd0TW9ub21lcnNBcnJheS5wdXNoKGl0ZW0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdGd0TW9ub21lcnNBcnJheS5qb2luKHRndFNlcGFyYXRvcik7XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ld0NvbHVtbjtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydEhlbG1Ub1NlcGFyYXRvcigpOiBERy5Db2x1bW4ge1xuICAgIC8vIFRPRE86IGltcGxlbWVudGF0aW9yZXR1cm4gdGhpcy5nZXROZXdDb2x1bW4oKTtcbiAgICByZXR1cm4gdGhpcy5nZXROZXdDb2x1bW4oTk9UQVRJT04uU0VQQVJBVE9SKTtcbiAgfVxuXG4gIC8qKiBEaXNwYXRjaGVyIG1ldGhvZCBmb3Igbm90YXRpb24gY29udmVyc2lvblxuICAgKlxuICAgKiBAcGFyYW0ge05PVEFUSU9OfSB0Z3ROb3RhdGlvbiAgIE5vdGF0aW9uIHdlIHdhbnQgdG8gY29udmVydCB0b1xuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bGx9IHRndFNlcGFyYXRvciAgIFBvc3NpYmxlIHNlcGFyYXRvclxuICAgKiBAcmV0dXJuIHtERy5Db2x1bW59ICAgICAgICAgICAgICAgIENvbnZlcnRlZCBjb2x1bW5cbiAgICovXG4gIHB1YmxpYyBjb252ZXJ0KHRndE5vdGF0aW9uOiBOT1RBVElPTiwgdGd0U2VwYXJhdG9yOiBzdHJpbmcgfCBudWxsID0gbnVsbCk6IERHLkNvbHVtbiB7XG4gICAgLy8gcG9zc2libGUgZXhjZXB0aW9uc1xuICAgIGlmICh0aGlzLm5vdGF0aW9uID09PSB0Z3ROb3RhdGlvbilcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGd0IG5vdGF0aW9uIGlzIGludmFsaWQnKTtcbiAgICBpZiAodGhpcy50b1NlcGFyYXRvcih0Z3ROb3RhdGlvbikgJiYgdGd0U2VwYXJhdG9yID09PSBudWxsKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0Z3Qgc2VwYXJhdG9yIGlzIG5vdCBzcGVjaWZpZWQnKTtcblxuICAgIGlmICh0aGlzLmlzRmFzdGEoKSAmJiB0aGlzLnRvU2VwYXJhdG9yKHRndE5vdGF0aW9uKSAmJiB0Z3RTZXBhcmF0b3IgIT09IG51bGwpXG4gICAgICByZXR1cm4gdGhpcy5jb252ZXJ0RmFzdGFUb1NlcGFyYXRvcih0Z3RTZXBhcmF0b3IpO1xuICAgIGVsc2UgaWYgKCh0aGlzLmlzRmFzdGEoKSB8fCB0aGlzLmlzU2VwYXJhdG9yKCkpICYmIHRoaXMudG9IZWxtKHRndE5vdGF0aW9uKSlcbiAgICAgIHJldHVybiB0aGlzLmNvbnZlcnRUb0hlbG0oKTtcbiAgICBlbHNlIGlmICh0aGlzLmlzU2VwYXJhdG9yKCkgJiYgdGhpcy50b0Zhc3RhKHRndE5vdGF0aW9uKSlcbiAgICAgIHJldHVybiB0aGlzLmNvbnZlcnRTZXBhcmF0b3JUb0Zhc3RhKCk7XG4gICAgZWxzZSBpZiAodGhpcy5pc0hlbG0oKSAmJiB0aGlzLnRvRmFzdGEodGd0Tm90YXRpb24pKSAvLyB0aGUgY2FzZSBvZiBIRUxNXG4gICAgICByZXR1cm4gdGhpcy5jb252ZXJ0SGVsbSh0Z3ROb3RhdGlvbik7XG4gICAgZWxzZSAvLyB0aGlzLmlzSGVsbSgpICYmIHRoaXMudG9TZXBhcmF0b3IodGd0Tm90YXRpb24pXG4gICAgICByZXR1cm4gdGhpcy5jb252ZXJ0SGVsbSh0Z3ROb3RhdGlvbiwgdGd0U2VwYXJhdG9yISk7XG4gIH1cblxuICBwdWJsaWMgY29uc3RydWN0b3IoY29sOiBERy5Db2x1bW4pIHtcbiAgICBzdXBlcihjb2wpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,70 @@
1
+ import * as DG from 'datagrok-api/dg';
2
+ /** enum type to simplify setting "user-friendly" notation if necessary */
3
+ export declare const enum NOTATION {
4
+ FASTA = "FASTA",
5
+ SEPARATOR = "SEPARATOR",
6
+ HELM = "HELM"
7
+ }
8
+ /** Class for handling notation units in Macromolecule columns */
9
+ export declare class UnitsHandler {
10
+ protected readonly _column: DG.Column;
11
+ protected _units: string;
12
+ protected _notation: NOTATION;
13
+ protected _defaultGapSymbol: string;
14
+ protected _defaultGapSymbolsDict: {
15
+ HELM: string;
16
+ SEPARATOR: string;
17
+ FASTA: string;
18
+ };
19
+ protected get units(): string;
20
+ protected get column(): DG.Column;
21
+ get notation(): NOTATION;
22
+ get defaultGapSymbol(): string;
23
+ get separator(): string;
24
+ isFasta(): boolean;
25
+ isSeparator(): boolean;
26
+ isHelm(): boolean;
27
+ isRna(): boolean;
28
+ isDna(): boolean;
29
+ isPeptide(): boolean;
30
+ /** Associate notation types with the corresponding units */
31
+ /**
32
+ * @return {NOTATION} Notation associated with the units type
33
+ */
34
+ protected getNotation(): NOTATION;
35
+ /**
36
+ * Create a new empty column of the specified notation type and the same
37
+ * length as column
38
+ *
39
+ * @param {NOTATION} targetNotation
40
+ * @return {DG.Column}
41
+ */
42
+ protected getNewColumn(targetNotation: NOTATION): DG.Column;
43
+ /**
44
+ * Create a new empty column using templateCol as a template
45
+ *
46
+ * @param {DG.Column} templateCol the properties and units of this column are used as a
47
+ * template to build the new one
48
+ * @return {DG.Column}
49
+ */
50
+ static getNewColumn(templateCol: DG.Column): DG.Column;
51
+ /**
52
+ * A helper function checking the validity of the 'units' string
53
+ *
54
+ * @param {string} units the string to be validated
55
+ * @return {boolean}
56
+ */
57
+ static unitsStringIsValid(units: string): boolean;
58
+ /**
59
+ * Construct a new column of semantic type MACROMOLECULE from the list of
60
+ * specified parameters
61
+ *
62
+ * @param {number} len the length of the new column
63
+ * @param {string} name the name of the new column
64
+ * @param {string} units the units of the new column
65
+ * @return {DG.Column}
66
+ */
67
+ static getNewColumnFromParams(len: number, name: string, units: string): DG.Column;
68
+ constructor(col: DG.Column);
69
+ }
70
+ //# sourceMappingURL=units-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"units-handler.d.ts","sourceRoot":"","sources":["units-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAItC,0EAA0E;AAC1E,0BAAkB,QAAQ;IACxB,KAAK,UAAU;IACf,SAAS,cAAc;IACvB,IAAI,SAAS;CACd;AAED,iEAAiE;AACjE,qBAAa,YAAY;IACvB,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC;IACtC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC;IAC9B,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACpC,SAAS,CAAC,sBAAsB;;;;MAI9B;IAEF,SAAS,KAAK,KAAK,IAAI,MAAM,CAAwB;IAErD,SAAS,KAAK,MAAM,IAAI,EAAE,CAAC,MAAM,CAAyB;IAE1D,IAAW,QAAQ,IAAI,QAAQ,CAA2B;IAE1D,IAAW,gBAAgB,IAAI,MAAM,CAAmC;IAExE,IAAW,SAAS,IAAI,MAAM,CAM7B;IAEM,OAAO,IAAI,OAAO;IAElB,WAAW,IAAI,OAAO;IAEtB,MAAM,IAAI,OAAO;IAEjB,KAAK,IAAI,OAAO;IAEhB,KAAK,IAAI,OAAO;IAEhB,SAAS,IAAI,OAAO;IAE3B,4DAA4D;IAC5D;;OAEG;IACH,SAAS,CAAC,WAAW,IAAI,QAAQ;IAWjC;;;;;;OAMG;IACH,SAAS,CAAC,YAAY,CAAC,cAAc,EAAE,QAAQ,GAAG,EAAE,CAAC,MAAM;IAmB3D;;;;;;OAMG;WACW,YAAY,CAAC,WAAW,EAAE,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM;IAM7D;;;;;OAKG;WACW,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAUxD;;;;;;;;OAQG;WACW,sBAAsB,CAClC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,EAAE,CAAC,MAAM;gBAYO,GAAG,EAAE,EAAE,CAAC,MAAM;CAYlC"}
@@ -0,0 +1,117 @@
1
+ import * as DG from 'datagrok-api/dg';
2
+ /** Class for handling notation units in Macromolecule columns */
3
+ export class UnitsHandler {
4
+ constructor(col) {
5
+ this._defaultGapSymbolsDict = {
6
+ HELM: '*',
7
+ SEPARATOR: '',
8
+ FASTA: '-',
9
+ };
10
+ this._column = col;
11
+ const units = this._column.tags[DG.TAGS.UNITS];
12
+ if (units !== null)
13
+ this._units = units;
14
+ else
15
+ throw new Error('Units are not specified in column');
16
+ this._notation = this.getNotation();
17
+ this._defaultGapSymbol = (this.isFasta()) ? this._defaultGapSymbolsDict.FASTA :
18
+ (this.isHelm()) ? this._defaultGapSymbolsDict.HELM :
19
+ this._defaultGapSymbolsDict.SEPARATOR;
20
+ }
21
+ get units() { return this._units; }
22
+ get column() { return this._column; }
23
+ get notation() { return this._notation; }
24
+ get defaultGapSymbol() { return this._defaultGapSymbol; }
25
+ get separator() {
26
+ const separator = this.column.getTag('separator');
27
+ if (separator !== null)
28
+ return separator;
29
+ else
30
+ throw new Error('Separator not set');
31
+ }
32
+ isFasta() { return this.notation === "FASTA" /* NOTATION.FASTA */; }
33
+ isSeparator() { return this.notation === "SEPARATOR" /* NOTATION.SEPARATOR */; }
34
+ isHelm() { return this.notation === "HELM" /* NOTATION.HELM */; }
35
+ isRna() { return this.units.toLowerCase().endsWith('rna'); }
36
+ isDna() { return this.units.toLowerCase().endsWith('dna'); }
37
+ isPeptide() { return this.units.toLowerCase().endsWith('pt'); }
38
+ /** Associate notation types with the corresponding units */
39
+ /**
40
+ * @return {NOTATION} Notation associated with the units type
41
+ */
42
+ getNotation() {
43
+ if (this.units.toLowerCase().startsWith('fasta'))
44
+ return "FASTA" /* NOTATION.FASTA */;
45
+ else if (this.units.toLowerCase().startsWith('separator'))
46
+ return "SEPARATOR" /* NOTATION.SEPARATOR */;
47
+ else if (this.units.toLowerCase().startsWith('helm'))
48
+ return "HELM" /* NOTATION.HELM */;
49
+ else
50
+ throw new Error('The column has units that do not correspond to any notation');
51
+ }
52
+ /**
53
+ * Create a new empty column of the specified notation type and the same
54
+ * length as column
55
+ *
56
+ * @param {NOTATION} targetNotation
57
+ * @return {DG.Column}
58
+ */
59
+ getNewColumn(targetNotation) {
60
+ const col = this.column;
61
+ const len = col.length;
62
+ const name = targetNotation.toLowerCase() + '(' + col.name + ')';
63
+ const newColName = col.dataFrame.columns.getUnusedName(name);
64
+ const newColumn = DG.Column.fromList('string', newColName, new Array(len).fill(''));
65
+ newColumn.semType = DG.SEMTYPE.MACROMOLECULE;
66
+ newColumn.setTag(DG.TAGS.UNITS, this.units.replace(this.notation.toLowerCase().toString(), targetNotation.toLowerCase().toString()));
67
+ newColumn.setTag(DG.TAGS.CELL_RENDERER, 'Macromolecule');
68
+ return newColumn;
69
+ }
70
+ /**
71
+ * Create a new empty column using templateCol as a template
72
+ *
73
+ * @param {DG.Column} templateCol the properties and units of this column are used as a
74
+ * template to build the new one
75
+ * @return {DG.Column}
76
+ */
77
+ static getNewColumn(templateCol) {
78
+ const col = new UnitsHandler(templateCol);
79
+ const targetNotation = col.notation;
80
+ return col.getNewColumn(targetNotation);
81
+ }
82
+ /**
83
+ * A helper function checking the validity of the 'units' string
84
+ *
85
+ * @param {string} units the string to be validated
86
+ * @return {boolean}
87
+ */
88
+ static unitsStringIsValid(units) {
89
+ units = units.toLowerCase();
90
+ const prefixes = ["FASTA" /* NOTATION.FASTA */, "SEPARATOR" /* NOTATION.SEPARATOR */, "HELM" /* NOTATION.HELM */];
91
+ const postfixes = ['rna', 'dna', 'pt'];
92
+ const prefixCriterion = prefixes.some((p) => units.startsWith(p.toLowerCase()));
93
+ const postfixCriterion = postfixes.some((p) => units.endsWith(p)); // already lowercase;
94
+ return prefixCriterion && postfixCriterion;
95
+ }
96
+ /**
97
+ * Construct a new column of semantic type MACROMOLECULE from the list of
98
+ * specified parameters
99
+ *
100
+ * @param {number} len the length of the new column
101
+ * @param {string} name the name of the new column
102
+ * @param {string} units the units of the new column
103
+ * @return {DG.Column}
104
+ */
105
+ static getNewColumnFromParams(len, name, units) {
106
+ // WARNING: in this implementation is is impossible to verify the uniqueness
107
+ // of the new column's name
108
+ // TODO: verify the validity of units parameter
109
+ if (!UnitsHandler.unitsStringIsValid(units))
110
+ throw new Error('Invalid format of \'units\' parameter');
111
+ const newColumn = DG.Column.fromList('string', name, new Array(len).fill(''));
112
+ newColumn.semType = DG.SEMTYPE.MACROMOLECULE;
113
+ newColumn.setTag(DG.TAGS.UNITS, units);
114
+ return newColumn;
115
+ }
116
+ }
117
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pdHMtaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInVuaXRzLWhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQVd0QyxpRUFBaUU7QUFDakUsTUFBTSxPQUFPLFlBQVk7SUFzSXZCLFlBQW1CLEdBQWM7UUFqSXZCLDJCQUFzQixHQUFHO1lBQ2pDLElBQUksRUFBRSxHQUFHO1lBQ1QsU0FBUyxFQUFFLEVBQUU7WUFDYixLQUFLLEVBQUUsR0FBRztTQUNYLENBQUM7UUE4SEEsSUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUM7UUFDbkIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMvQyxJQUFJLEtBQUssS0FBSyxJQUFJO1lBQ2hCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDOztZQUVwQixNQUFNLElBQUksS0FBSyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDcEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM3RSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ2xELElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxTQUFTLENBQUM7SUFDNUMsQ0FBQztJQXRJRCxJQUFjLEtBQUssS0FBYSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBRXJELElBQWMsTUFBTSxLQUFnQixPQUFPLElB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QUMsdUNBQXVDLENBQUMsQ0FBQztRQUMzRCxNQUFNLFNBQVMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzlFLFNBQVMsQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUM7UUFDN0MsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN2QyxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0NBY0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBERyBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuaW1wb3J0ICogYXMgdWkgZnJvbSAnZGF0YWdyb2stYXBpL3VpJztcbmltcG9ydCAqIGFzIGdyb2sgZnJvbSAnZGF0YWdyb2stYXBpL2dyb2snO1xuXG4vKiogZW51bSB0eXBlIHRvIHNpbXBsaWZ5IHNldHRpbmcgXCJ1c2VyLWZyaWVuZGx5XCIgbm90YXRpb24gaWYgbmVjZXNzYXJ5ICovXG5leHBvcnQgY29uc3QgZW51bSBOT1RBVElPTiB7XG4gIEZBU1RBID0gJ0ZBU1RBJyxcbiAgU0VQQVJBVE9SID0gJ1NFUEFSQVRPUicsXG4gIEhFTE0gPSAnSEVMTSdcbn1cblxuLyoqIENsYXNzIGZvciBoYW5kbGluZyBub3RhdGlvbiB1bml0cyBpbiBNYWNyb21vbGVjdWxlIGNvbHVtbnMgKi9cbmV4cG9ydCBjbGFzcyBVbml0c0hhbmRsZXIge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX2NvbHVtbjogREcuQ29sdW1uOyAvLyB0aGUgY29sdW1uIHRvIGJlIGNvbnZlcnRlZFxuICBwcm90ZWN0ZWQgX3VuaXRzOiBzdHJpbmc7IC8vIHVuaXRzLCBvZiB0aGUgZm9ybSBmYXN0YTpTRVE6TlQsIGV0Yy5cbiAgcHJvdGVjdGVkIF9ub3RhdGlvbjogTk9UQVRJT047IC8vIGN1cnJlbnQgbm90YXRpb24gKHdpdGhvdXQgOlNFUTpOVCwgZXRjLilcbiAgcHJvdGVjdGVkIF9kZWZhdWx0R2FwU3ltYm9sOiBzdHJpbmc7XG4gIHByb3RlY3RlZCBfZGVmYXVsdEdhcFN5bWJvbHNEaWN0ID0ge1xuICAgIEhFTE06ICcqJyxcbiAgICBTRVBBUkFUT1I6ICcnLFxuICAgIEZBU1RBOiAnLScsXG4gIH07XG5cbiAgcHJvdGVjdGVkIGdldCB1bml0cygpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy5fdW5pdHM7IH1cblxuICBwcm90ZWN0ZWQgZ2V0IGNvbHVtbigpOiBERy5Db2x1bW4geyByZXR1cm4gdGhpcy5fY29sdW1uOyB9XG5cbiAgcHVibGljIGdldCBub3RhdGlvbigpOiBOT1RBVElPTiB7IHJldHVybiB0aGlzLl9ub3RhdGlvbjsgfVxuXG4gIHB1YmxpYyBnZXQgZGVmYXVsdEdhcFN5bWJvbCgpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy5fZGVmYXVsdEdhcFN5bWJvbDsgfVxuXG4gIHB1YmxpYyBnZXQgc2VwYXJhdG9yKCk6IHN0cmluZyB7XG4gICAgY29uc3Qgc2VwYXJhdG9yID0gdGhpcy5jb2x1bW4uZ2V0VGFnKCdzZXBhcmF0b3InKTtcbiAgICBpZiAoc2VwYXJhdG9yICE9PSBudWxsKVxuICAgICAgcmV0dXJuIHNlcGFyYXRvcjtcbiAgICBlbHNlXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlcGFyYXRvciBub3Qgc2V0Jyk7XG4gIH1cblxuICBwdWJsaWMgaXNGYXN0YSgpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMubm90YXRpb24gPT09IE5PVEFUSU9OLkZBU1RBOyB9XG5cbiAgcHVibGljIGlzU2VwYXJhdG9yKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5ub3RhdGlvbiA9PT0gTk9UQVRJT04uU0VQQVJBVE9SOyB9XG5cbiAgcHVibGljIGlzSGVsbSgpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMubm90YXRpb24gPT09IE5PVEFUSU9OLkhFTE07IH1cblxuICBwdWJsaWMgaXNSbmEoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnVuaXRzLnRvTG93ZXJDYXNlKCkuZW5kc1dpdGgoJ3JuYScpOyB9XG5cbiAgcHVibGljIGlzRG5hKCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy51bml0cy50b0xvd2VyQ2FzZSgpLmVuZHNXaXRoKCdkbmEnKTsgfVxuXG4gIHB1YmxpYyBpc1BlcHRpZGUoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLnVuaXRzLnRvTG93ZXJDYXNlKCkuZW5kc1dpdGgoJ3B0Jyk7IH1cblxuICAvKiogQXNzb2NpYXRlIG5vdGF0aW9uIHR5cGVzIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgdW5pdHMgKi9cbiAgLyoqXG4gICAqIEByZXR1cm4ge05PVEFUSU9OfSAgICAgTm90YXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoZSB1bml0cyB0eXBlXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0Tm90YXRpb24oKTogTk9UQVRJT04ge1xuICAgIGlmICh0aGlzLnVuaXRzLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aCgnZmFzdGEnKSlcbiAgICAgIHJldHVybiBOT1RBVElPTi5GQVNUQTtcbiAgICBlbHNlIGlmICh0aGlzLnVuaXRzLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aCgnc2VwYXJhdG9yJykpXG4gICAgICByZXR1cm4gTk9UQVRJT04uU0VQQVJBVE9SO1xuICAgIGVsc2UgaWYgKHRoaXMudW5pdHMudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKCdoZWxtJykpXG4gICAgICByZXR1cm4gTk9UQVRJT04uSEVMTTtcbiAgICBlbHNlXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjb2x1bW4gaGFzIHVuaXRzIHRoYXQgZG8gbm90IGNvcnJlc3BvbmQgdG8gYW55IG5vdGF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGVtcHR5IGNvbHVtbiBvZiB0aGUgc3BlY2lmaWVkIG5vdGF0aW9uIHR5cGUgYW5kIHRoZSBzYW1lXG4gICAqIGxlbmd0aCBhcyBjb2x1bW5cbiAgICpcbiAgICogQHBhcmFtIHtOT1RBVElPTn0gdGFyZ2V0Tm90YXRpb25cbiAgICogQHJldHVybiB7REcuQ29sdW1ufVxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE5ld0NvbHVtbih0YXJnZXROb3RhdGlvbjogTk9UQVRJT04pOiBERy5Db2x1bW4ge1xuICAgIGNvbnN0IGNvbCA9IHRoaXMuY29sdW1uO1xuICAgIGNvbnN0IGxlbiA9IGNvbC5sZW5ndGg7XG4gICAgY29uc3QgbmFtZSA9IHRhcmdldE5vdGF0aW9uLnRvTG93ZXJDYXNlKCkgKyAnKCcgKyBjb2wubmFtZSArICcpJztcbiAgICBjb25zdCBuZXdDb2xOYW1lID0gY29sLmRhdGFGcmFtZS5jb2x1bW5zLmdldFVudXNlZE5hbWUobmFtZSk7XG4gICAgY29uc3QgbmV3Q29sdW1uID0gREcuQ29sdW1uLmZyb21MaXN0KCdzdHJpbmcnLCBuZXdDb2xOYW1lLCBuZXcgQXJyYXkobGVuKS5maWxsKCcnKSk7XG4gICAgbmV3Q29sdW1uLnNlbVR5cGUgPSBERy5TRU1UWVBFLk1BQ1JPTU9MRUNVTEU7XG4gICAgbmV3Q29sdW1uLnNldFRhZyhcbiAgICAgIERHLlRBR1MuVU5JVFMsXG4gICAgICB0aGlzLnVuaXRzLnJlcGxhY2UoXG4gICAgICAgIHRoaXMubm90YXRpb24udG9Mb3dlckNhc2UoKS50b1N0cmluZygpLFxuICAgICAgICB0YXJnZXROb3RhdGlvbi50b0xvd2VyQ2FzZSgpLnRvU3RyaW5nKClcbiAgICAgIClcbiAgICApO1xuICAgIG5ld0NvbHVtbi5zZXRUYWcoREcuVEFHUy5DRUxMX1JFTkRFUkVSLCAnTWFjcm9tb2xlY3VsZScpO1xuXG4gICAgcmV0dXJuIG5ld0NvbHVtbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgZW1wdHkgY29sdW1uIHVzaW5nIHRlbXBsYXRlQ29sIGFzIGEgdGVtcGxhdGVcbiAgICpcbiAgICogQHBhcmFtIHtERy5Db2x1bW59IHRlbXBsYXRlQ29sICB0aGUgcHJvcGVydGllcyBhbmQgdW5pdHMgb2YgdGhpcyBjb2x1bW4gYXJlIHVzZWQgYXMgYVxuICAgKiB0ZW1wbGF0ZSB0byBidWlsZCB0aGUgbmV3IG9uZVxuICAgKiBAcmV0dXJuIHtERy5Db2x1bW59XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGdldE5ld0NvbHVtbih0ZW1wbGF0ZUNvbDogREcuQ29sdW1uKTogREcuQ29sdW1uIHtcbiAgICBjb25zdCBjb2w6IFVuaXRzSGFuZGxlciA9IG5ldyBVbml0c0hhbmRsZXIodGVtcGxhdGVDb2wpO1xuICAgIGNvbnN0IHRhcmdldE5vdGF0aW9uID0gY29sLm5vdGF0aW9uO1xuICAgIHJldHVybiBjb2wuZ2V0TmV3Q29sdW1uKHRhcmdldE5vdGF0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIGhlbHBlciBmdW5jdGlvbiBjaGVja2luZyB0aGUgdmFsaWRpdHkgb2YgdGhlICd1bml0cycgc3RyaW5nXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1bml0cyAgdGhlIHN0cmluZyB0byBiZSB2YWxpZGF0ZWRcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgdW5pdHNTdHJpbmdJc1ZhbGlkKHVuaXRzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB1bml0cyA9IHVuaXRzLnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgcHJlZml4ZXMgPSBbTk9UQVRJT04uRkFTVEEsIE5PVEFUSU9OLlNFUEFSQVRPUiwgTk9UQVRJT04uSEVMTV07XG4gICAgY29uc3QgcG9zdGZpeGVzID0gWydybmEnLCAnZG5hJywgJ3B0J107XG5cbiAgICBjb25zdCBwcmVmaXhDcml0ZXJpb24gPSBwcmVmaXhlcy5zb21lKChwKSA9PiB1bml0cy5zdGFydHNXaXRoKHAudG9Mb3dlckNhc2UoKSkpO1xuICAgIGNvbnN0IHBvc3RmaXhDcml0ZXJpb24gPSBwb3N0Zml4ZXMuc29tZSgocCkgPT4gdW5pdHMuZW5kc1dpdGgocCkpOyAvLyBhbHJlYWR5IGxvd2VyY2FzZTtcbiAgICByZXR1cm4gcHJlZml4Q3JpdGVyaW9uICYmIHBvc3RmaXhDcml0ZXJpb247XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGNvbHVtbiBvZiBzZW1hbnRpYyB0eXBlIE1BQ1JPTU9MRUNVTEUgZnJvbSB0aGUgbGlzdCBvZlxuICAgKiBzcGVjaWZpZWQgcGFyYW1ldGVyc1xuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gICAgbGVuICB0aGUgbGVuZ3RoIG9mIHRoZSBuZXcgY29sdW1uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSAgICBuYW1lICB0aGUgbmFtZSBvZiB0aGUgbmV3IGNvbHVtblxuICAgKiBAcGFyYW0ge3N0cmluZ30gICAgdW5pdHMgIHRoZSB1bml0cyBvZiB0aGUgbmV3IGNvbHVtblxuICAgKiBAcmV0dXJuIHtERy5Db2x1bW59XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGdldE5ld0NvbHVtbkZyb21QYXJhbXMoXG4gICAgbGVuOiBudW1iZXIsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHVuaXRzOiBzdHJpbmdcbiAgKTogREcuQ29sdW1uIHtcbiAgICAvLyBXQVJOSU5HOiBpbiB0aGlzIGltcGxlbWVudGF0aW9uIGlzIGlzIGltcG9zc2libGUgdG8gdmVyaWZ5IHRoZSB1bmlxdWVuZXNzXG4gICAgLy8gb2YgdGhlIG5ldyBjb2x1bW4ncyBuYW1lXG4gICAgLy8gVE9ETzogdmVyaWZ5IHRoZSB2YWxpZGl0eSBvZiB1bml0cyBwYXJhbWV0ZXJcbiAgICBpZiAoIVVuaXRzSGFuZGxlci51bml0c1N0cmluZ0lzVmFsaWQodW5pdHMpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGZvcm1hdCBvZiBcXCd1bml0c1xcJyBwYXJhbWV0ZXInKTtcbiAgICBjb25zdCBuZXdDb2x1bW4gPSBERy5Db2x1bW4uZnJvbUxpc3QoJ3N0cmluZycsIG5hbWUsIG5ldyBBcnJheShsZW4pLmZpbGwoJycpKTtcbiAgICBuZXdDb2x1bW4uc2VtVHlwZSA9IERHLlNFTVRZUEUuTUFDUk9NT0xFQ1VMRTtcbiAgICBuZXdDb2x1bW4uc2V0VGFnKERHLlRBR1MuVU5JVFMsIHVuaXRzKTtcbiAgICByZXR1cm4gbmV3Q29sdW1uO1xuICB9XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKGNvbDogREcuQ29sdW1uKSB7XG4gICAgdGhpcy5fY29sdW1uID0gY29sO1xuICAgIGNvbnN0IHVuaXRzID0gdGhpcy5fY29sdW1uLnRhZ3NbREcuVEFHUy5VTklUU107XG4gICAgaWYgKHVuaXRzICE9PSBudWxsKVxuICAgICAgdGhpcy5fdW5pdHMgPSB1bml0cztcbiAgICBlbHNlXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuaXRzIGFyZSBub3Qgc3BlY2lmaWVkIGluIGNvbHVtbicpO1xuICAgIHRoaXMuX25vdGF0aW9uID0gdGhpcy5nZXROb3RhdGlvbigpO1xuICAgIHRoaXMuX2RlZmF1bHRHYXBTeW1ib2wgPSAodGhpcy5pc0Zhc3RhKCkpID8gdGhpcy5fZGVmYXVsdEdhcFN5bWJvbHNEaWN0LkZBU1RBIDpcbiAgICAgICh0aGlzLmlzSGVsbSgpKSA/IHRoaXMuX2RlZmF1bHRHYXBTeW1ib2xzRGljdC5IRUxNIDpcbiAgICAgICAgdGhpcy5fZGVmYXVsdEdhcFN5bWJvbHNEaWN0LlNFUEFSQVRPUjtcbiAgfVxufVxuIl19