@datagrok-libraries/bio 5.3.0 → 5.4.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.
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "friendlyName": "Datagrok bio library",
7
- "version": "5.3.0",
7
+ "version": "5.4.0",
8
8
  "description": "",
9
9
  "dependencies": {
10
10
  "@datagrok-libraries/utils": "^1.10.1",
@@ -0,0 +1,2 @@
1
+ export declare function getMacroMol(monomers: any[][]): Promise<string[]>;
2
+ //# sourceMappingURL=atomic-works.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atomic-works.d.ts","sourceRoot":"","sources":["atomic-works.ts"],"names":[],"mappings":"AAuYA,wBAAsB,WAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqBtE"}
@@ -0,0 +1,354 @@
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
+ import * as grok from 'datagrok-api/grok';
11
+ function extractAtomDataV3K(v3KMolblock) {
12
+ const numbers = extractAtomAndBondCountsV3K(v3KMolblock);
13
+ let begin = v3KMolblock.indexOf('M V30 BEGIN ATOM'); // V3000 block for atom coordinates
14
+ begin = v3KMolblock.indexOf('\n', begin);
15
+ let end = begin;
16
+ const atomIndices = Array(numbers.atomCount);
17
+ const atomTypes = Array(numbers.atomCount);
18
+ const x = Array(numbers.atomCount);
19
+ const y = Array(numbers.atomCount);
20
+ for (let i = 0; i < numbers.atomCount; i++) {
21
+ begin = v3KMolblock.indexOf('V30', begin) + 4;
22
+ end = v3KMolblock.indexOf(' ', begin);
23
+ atomIndices[i] = parseInt(v3KMolblock.substring(begin, end));
24
+ begin = end + 1;
25
+ end = v3KMolblock.indexOf(' ', begin);
26
+ atomTypes[i] = v3KMolblock.substring(begin, end);
27
+ begin = end + 1;
28
+ end = v3KMolblock.indexOf(' ', begin);
29
+ x[i] = parseFloat(v3KMolblock.substring(begin, end));
30
+ begin = end + 1;
31
+ end = v3KMolblock.indexOf(' ', begin);
32
+ y[i] = parseFloat(v3KMolblock.substring(begin, end));
33
+ begin = v3KMolblock.indexOf('\n', begin) + 1;
34
+ }
35
+ return { atomIndices: atomIndices, atomTypes: atomTypes, x: x, y: y };
36
+ }
37
+ // todo: extractRgroupData
38
+ function extractAtomAndBondCountsV3K(v3KMolblock) {
39
+ v3KMolblock = v3KMolblock.replaceAll('\r', ''); // equalize old and new sdf standards
40
+ // parse atom count
41
+ let idxBegin = v3KMolblock.indexOf('COUNTS') + 7;
42
+ let idxEnd = v3KMolblock.indexOf(' ', idxBegin);
43
+ const numOfAtoms = parseInt(v3KMolblock.substring(idxBegin, idxEnd));
44
+ // parse bond count
45
+ idxBegin = idxEnd + 1;
46
+ idxEnd = v3KMolblock.indexOf(' ', idxBegin);
47
+ const numOfBonds = parseInt(v3KMolblock.substring(idxBegin, idxEnd));
48
+ return { atomCount: numOfAtoms, bondCount: numOfBonds };
49
+ }
50
+ function getIndices(v2KMolblock, v3KMolblock) {
51
+ // one should also take into account that there can be multiple M RGP lines
52
+ // with R-Groups specified
53
+ let begin = v2KMolblock.indexOf('M RGP', 0) + 8;
54
+ let end = v2KMolblock.indexOf('\n', begin);
55
+ // todo: maybe this part deserves a separate function
56
+ // there may be situation when the rgp information is distributed among
57
+ // multiple lines, this must be taken into account
58
+ const rgpStringParsed = v2KMolblock.substring(begin, end).replaceAll(' ', ' ').replaceAll(' ', ' ').split(' ');
59
+ const rgpData = rgpStringParsed.map((el) => parseInt(el));
60
+ // rgpData[0] is the number of R-groups
61
+ // the following code sets remFirst to node# to which RGP#1 is substituted
62
+ // todo: handle the exceptional case when there is not enough rgroups
63
+ // todo: handle the exceptional case when the order is different
64
+ const remFirst = rgpData[1]; // leftmost Rgroup node
65
+ const remLast = rgpData[rgpData.length - 2]; // rightmost Rgroup node
66
+ // if (remFirst === -1 || remLast === -1)
67
+ // throw new Error('RGP parsing: first and last groups have wrong format');
68
+ // const remFirst = rgpData[2] === '1' ? parseInt(rgpData[1]) : parseInt(rgpData[3]);
69
+ // const remLast = rgpData[2] === '2' ? parseInt(rgpData[1]) : parseInt(rgpData[3]);
70
+ // todo: rename 'numbers'
71
+ const numbers = extractAtomAndBondCountsV3K(v3KMolblock);
72
+ let indexBonds = v3KMolblock.indexOf('M V30 BEGIN BOND'); // V3000 bond block
73
+ indexBonds = v3KMolblock.indexOf('\n', indexBonds);
74
+ begin = indexBonds;
75
+ end = indexBonds;
76
+ let first = 0; // todo: improve notation
77
+ let last = 0;
78
+ let remBondFirst = 0;
79
+ let remBondLast = 0;
80
+ // iterate over edges of the graph and find those
81
+ for (let j = 0; j < numbers.bondCount; j++) {
82
+ if (first === 0 || last === 0) {
83
+ begin = v3KMolblock.indexOf('V30', begin) + 4;
84
+ end = v3KMolblock.indexOf('\n', begin);
85
+ const bondStringParsed = v3KMolblock.substring(begin, end).replaceAll(' ', ' ').replaceAll(' ', ' ').split(' ');
86
+ const bondData = bondStringParsed.map((el) => parseInt(el));
87
+ if (bondData[2] === remFirst) { // bondData[2] is the 1st node/atom of the bond
88
+ first = bondData[3]; // bondData[3] is the 2nd node/atom of the bond
89
+ remBondFirst = bondData[0]; // bondData[0] is the idx of the associated bond/edge
90
+ }
91
+ else if (bondData[3] === remFirst) {
92
+ first = bondData[2];
93
+ remBondFirst = bondData[0];
94
+ }
95
+ else if (bondData[2] === remLast) {
96
+ last = bondData[3];
97
+ remBondLast = bondData[0];
98
+ }
99
+ else if (bondData[3] === remLast) {
100
+ last = bondData[2];
101
+ remBondLast = bondData[0];
102
+ }
103
+ }
104
+ }
105
+ return { first, last, remFirst, remLast, remBondFirst, remBondLast };
106
+ }
107
+ /* provide description */
108
+ function rotateBackboneV3K(v3KMolblock, indices) {
109
+ return __awaiter(this, void 0, void 0, function* () {
110
+ const coordinates = extractAtomDataV3K(v3KMolblock); // naming?
111
+ const atomCount = coordinates.atomIndices.length;
112
+ const first = indices['first'];
113
+ const last = indices['last'];
114
+ const xCenter = (coordinates.x[last] + coordinates.x[first]) / 2;
115
+ const yCenter = (coordinates.y[last] + coordinates.y[first]) / 2;
116
+ //place to center
117
+ for (let i = 0; i < atomCount; i++) {
118
+ coordinates.x[i] -= xCenter;
119
+ coordinates.y[i] -= yCenter;
120
+ }
121
+ let angle = 0;
122
+ if (coordinates.x[first] === 0) { // both vertices are on OY
123
+ angle = coordinates.y[first] > coordinates.y[last] ? Math.PI / 2 : -Math.PI / 2;
124
+ }
125
+ else if (coordinates.y[first] === 0) { // both vertices are on OX
126
+ angle = coordinates.x[first] > coordinates.x[last] ? Math.PI : 0; // v
127
+ }
128
+ else {
129
+ const tangent = coordinates.y[first] / coordinates.x[first];
130
+ if (coordinates.x[first] < coordinates.x[last])
131
+ angle = tangent > 0 ? -Math.atan(tangent) : Math.atan(tangent);
132
+ else
133
+ angle = tangent > 0 ? Math.PI - Math.atan(tangent) : Math.atan(tangent) - Math.PI;
134
+ }
135
+ const cos = Math.cos(angle);
136
+ const sin = Math.sin(angle);
137
+ for (let i = 0; i < atomCount; i++) {
138
+ const xAdd = coordinates.x[i];
139
+ coordinates.x[i] = xAdd * cos - coordinates.y[i] * sin;
140
+ coordinates.y[i] = xAdd * sin + coordinates.y[i] * cos;
141
+ }
142
+ //place to right
143
+ const xShift = coordinates.x[first];
144
+ for (let i = 0; i < atomCount; i++)
145
+ coordinates.x[i] -= xShift;
146
+ //rewrite v3KMolblock
147
+ let index = v3KMolblock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates
148
+ index = v3KMolblock.indexOf('\n', index);
149
+ let indexEnd = index;
150
+ for (let i = 0; i < atomCount; i++) {
151
+ index = v3KMolblock.indexOf('V30', index) + 4;
152
+ index = v3KMolblock.indexOf(' ', index) + 1;
153
+ index = v3KMolblock.indexOf(' ', index) + 1;
154
+ indexEnd = v3KMolblock.indexOf(' ', index) + 1;
155
+ indexEnd = v3KMolblock.indexOf(' ', indexEnd);
156
+ v3KMolblock = v3KMolblock.slice(0, index) +
157
+ coordinates.x[i] + ' ' + coordinates.y[i] +
158
+ v3KMolblock.slice(indexEnd);
159
+ index = v3KMolblock.indexOf('\n', index) + 1;
160
+ }
161
+ return v3KMolblock;
162
+ });
163
+ }
164
+ /* provide description */
165
+ function linkV3K(monomers) {
166
+ let macroMolBlock = '\nDatagrok macromolecule handler\n\n';
167
+ macroMolBlock += ' 0 0 0 0 0 0 999 V3000\n';
168
+ macroMolBlock += 'M V30 BEGIN CTAB\n';
169
+ let atomBlock = '';
170
+ let bondBlock = '';
171
+ // const collectionBlock = '';
172
+ // const collection: number [] = [];
173
+ let atomCount = 0;
174
+ let bondCount = 0;
175
+ let xShift = 0; // ?
176
+ for (let i = 0; i < monomers.length; i++) {
177
+ let v3KMolfile = monomers[i]['molfile'];
178
+ const first = monomers[i]['indices']['first'];
179
+ const last = monomers[i]['indices']['last'];
180
+ const remFirst = monomers[i]['indices']['remFirst'];
181
+ const remLast = monomers[i]['indices']['remLast'];
182
+ const remBondFirst = monomers[i]['indices']['remBondFirst'];
183
+ const remBondLast = monomers[i]['indices']['remBondLast'];
184
+ // todo: handle r-groups
185
+ v3KMolfile = v3KMolfile.replaceAll('(-\nM V30 ', '(')
186
+ .replaceAll('-\nM V30 ', '').replaceAll(' )', ')');
187
+ // todo: improve naming
188
+ const numbers = extractAtomAndBondCountsV3K(v3KMolfile);
189
+ const coordinates = extractAtomDataV3K(v3KMolfile);
190
+ let indexAtoms = v3KMolfile.indexOf('M V30 BEGIN ATOM'); // V3000 atom block
191
+ indexAtoms = v3KMolfile.indexOf('\n', indexAtoms);
192
+ let index = indexAtoms;
193
+ let indexEnd = indexAtoms;
194
+ const totalShift = xShift - coordinates.x[first - 1];
195
+ for (let j = 0; j < numbers.atomCount; j++) {
196
+ if (coordinates.atomIndices[j] != remFirst && coordinates.atomIndices[j] != remLast) { //|| i === 0) {
197
+ //rewrite atom number
198
+ index = v3KMolfile.indexOf('V30', index) + 4;
199
+ indexEnd = v3KMolfile.indexOf(' ', index);
200
+ let atomNumber = parseInt(v3KMolfile.substring(index, indexEnd));
201
+ atomNumber = (atomNumber > remFirst && atomNumber > remLast) ? atomNumber - 2 :
202
+ (atomNumber > remFirst || atomNumber > remLast) ? atomNumber - 1 : atomNumber;
203
+ atomNumber += atomCount;
204
+ v3KMolfile = v3KMolfile.slice(0, index) + atomNumber + v3KMolfile.slice(indexEnd);
205
+ //rewrite coordinates
206
+ index = v3KMolfile.indexOf(' ', index) + 1;
207
+ index = v3KMolfile.indexOf(' ', index) + 1;
208
+ indexEnd = v3KMolfile.indexOf(' ', index);
209
+ let coordinate = Math.round(10000 * (parseFloat(v3KMolfile.substring(index, indexEnd)) + totalShift)) / 10000;
210
+ v3KMolfile = v3KMolfile.slice(0, index) + coordinate + v3KMolfile.slice(indexEnd);
211
+ index = v3KMolfile.indexOf(' ', index) + 1;
212
+ indexEnd = v3KMolfile.indexOf(' ', index);
213
+ coordinate = Math.round(10000 * (parseFloat(v3KMolfile.substring(index, indexEnd)))) / 10000;
214
+ v3KMolfile = v3KMolfile.slice(0, index) + coordinate + v3KMolfile.slice(indexEnd);
215
+ index = v3KMolfile.indexOf('\n', index) + 1;
216
+ }
217
+ else {
218
+ index = v3KMolfile.indexOf('M V30', index) - 1;
219
+ indexEnd = v3KMolfile.indexOf('\n', index + 1);
220
+ v3KMolfile = v3KMolfile.slice(0, index) + v3KMolfile.slice(indexEnd);
221
+ }
222
+ }
223
+ const indexAtomsEnd = v3KMolfile.indexOf('M V30 END ATOM');
224
+ atomBlock += v3KMolfile.substring(indexAtoms + 1, indexAtomsEnd);
225
+ let indexBonds = v3KMolfile.indexOf('M V30 BEGIN BOND'); // V3000 index for bonds
226
+ indexBonds = v3KMolfile.indexOf('\n', indexBonds);
227
+ index = indexBonds;
228
+ indexEnd = indexBonds;
229
+ let bondNumber = 0;
230
+ for (let j = 0; j < numbers.bondCount; j++) {
231
+ //rewrite bond number
232
+ index = v3KMolfile.indexOf('V30', index) + 4;
233
+ indexEnd = v3KMolfile.indexOf(' ', index);
234
+ bondNumber = parseInt(v3KMolfile.substring(index, indexEnd));
235
+ if (bondNumber === remBondFirst || bondNumber === remBondLast) {
236
+ indexEnd = v3KMolfile.indexOf('\n', index) + 1;
237
+ index -= 7;
238
+ v3KMolfile = v3KMolfile.slice(0, index) + v3KMolfile.slice(indexEnd);
239
+ continue;
240
+ }
241
+ bondNumber = (bondNumber > remBondFirst && bondNumber > remBondLast) ? bondNumber - 2 :
242
+ (bondNumber > remBondFirst || bondNumber > remBondLast) ? bondNumber - 1 : bondNumber;
243
+ bondNumber += bondCount;
244
+ v3KMolfile = v3KMolfile.slice(0, index) + bondNumber + v3KMolfile.slice(indexEnd);
245
+ //rewrite atom pair in bond
246
+ index = v3KMolfile.indexOf(' ', index) + 1;
247
+ index = v3KMolfile.indexOf(' ', index) + 1;
248
+ indexEnd = v3KMolfile.indexOf(' ', index);
249
+ let atomNumber = parseInt(v3KMolfile.substring(index, indexEnd));
250
+ atomNumber = (atomNumber > remFirst && atomNumber > remLast) ? atomNumber - 2 :
251
+ (atomNumber > remFirst || atomNumber > remLast) ? atomNumber - 1 : atomNumber;
252
+ atomNumber += atomCount;
253
+ v3KMolfile = v3KMolfile.slice(0, index) + atomNumber + v3KMolfile.slice(indexEnd);
254
+ index = v3KMolfile.indexOf(' ', index) + 1;
255
+ indexEnd = Math.min(v3KMolfile.indexOf('\n', index), v3KMolfile.indexOf(' ', index));
256
+ atomNumber = parseInt(v3KMolfile.substring(index, indexEnd));
257
+ atomNumber = (atomNumber > remFirst && atomNumber > remLast) ? atomNumber - 2 :
258
+ (atomNumber > remFirst || atomNumber > remLast) ? atomNumber - 1 : atomNumber;
259
+ atomNumber += atomCount;
260
+ v3KMolfile = v3KMolfile.slice(0, index) + atomNumber + v3KMolfile.slice(indexEnd);
261
+ index = v3KMolfile.indexOf('\n', index) + 1;
262
+ }
263
+ const indexBondEnd = v3KMolfile.indexOf('M V30 END BOND');
264
+ bondBlock += v3KMolfile.substring(indexBonds + 1, indexBondEnd);
265
+ //let indexCollection = v3KMolfile.indexOf('M V30 MDLV30/STEABS ATOMS=('); // V3000 index for collections
266
+ // while (indexCollection != -1) {
267
+ // indexCollection += 28;
268
+ // const collectionEnd = v3KMolfile.indexOf(')', indexCollection);
269
+ // const collectionEntries = v3KMolfile.substring(indexCollection, collectionEnd).split(' ').slice(1);
270
+ // collectionEntries.forEach((e: string) => {
271
+ // collection.push(parseInt(e) + atomCount);
272
+ // });
273
+ // indexCollection = collectionEnd;
274
+ // indexCollection = v3KMolfile.indexOf('M V30 MDLV30/STEABS ATOMS=(', indexCollection);
275
+ // }
276
+ atomCount += numbers.atomCount - 2;
277
+ bondCount += numbers.bondCount - 2;
278
+ xShift += coordinates.x[last] - coordinates.x[first] + 1;
279
+ if (i === monomers.length - 1) {
280
+ atomCount++;
281
+ const shift = xShift + 0.2;
282
+ atomBlock += 'M V30 ' + atomCount + ' O ' + shift + ' 0 0.000000 0\n';
283
+ }
284
+ bondCount++;
285
+ if (i === monomers.length - 1) {
286
+ const rightTerminal = (last > remFirst && last > remLast) ? last + atomCount - (numbers.atomCount - 2) - 3 :
287
+ (last > remFirst || last > remLast) ? last + atomCount - (numbers.atomCount - 2) - 2 :
288
+ last + atomCount - (numbers.atomCount - 2) - 1;
289
+ bondBlock += 'M V30 ' + bondCount + ' 1 ' + rightTerminal + ' ' + atomCount + '\n';
290
+ }
291
+ else {
292
+ const rightTerminal = (last > remFirst && last > remLast) ? last + atomCount - (numbers.atomCount - 2) - 2 :
293
+ (last > remFirst || last > remLast) ? last + atomCount - (numbers.atomCount - 2) - 1 :
294
+ last + atomCount - (numbers.atomCount - 2);
295
+ const next = monomers[i + 1]['indices'];
296
+ const nextFirst = next['first'];
297
+ const nextRemFirst = next['remFirst'];
298
+ const nextRemLast = next['remLast'];
299
+ const leftTerminal = (nextFirst > nextRemFirst && nextFirst > nextRemLast) ? nextFirst + atomCount - 2 :
300
+ (nextFirst > nextRemFirst || nextFirst > nextRemLast) ? nextFirst + atomCount - 1 :
301
+ nextFirst + atomCount;
302
+ bondBlock += 'M V30 ' + bondCount + ' 1 ' + rightTerminal + ' ' + leftTerminal + '\n';
303
+ }
304
+ }
305
+ // const entries = 4;
306
+ // const collNumber = Math.ceil(collection.length / entries);
307
+ // collectionBlock += 'M V30 MDLV30/STEABS ATOMS=(' + collection.length + ' -\n';
308
+ // for (let i = 0; i < collNumber; i++) {
309
+ // collectionBlock += 'M V30 ';
310
+ // const entriesCurrent = i + 1 === collNumber ? collection.length - (collNumber - 1)*entries : entries;
311
+ // for (let j = 0; j < entriesCurrent; j++) {
312
+ // collectionBlock += (j + 1 === entriesCurrent) ?
313
+ // (i === collNumber - 1 ? collection[entries*i + j] + ')\n' : collection[entries*i + j] + ' -\n') :
314
+ // collection[entries*i + j] + ' ';
315
+ // }
316
+ // }
317
+ //generate file
318
+ macroMolBlock += 'M V30 COUNTS ' + atomCount + ' ' + bondCount + ' 0 0 0\n';
319
+ macroMolBlock += 'M V30 BEGIN ATOM\n';
320
+ macroMolBlock += atomBlock;
321
+ macroMolBlock += 'M V30 END ATOM\n';
322
+ macroMolBlock += 'M V30 BEGIN BOND\n';
323
+ macroMolBlock += bondBlock;
324
+ macroMolBlock += 'M V30 END BOND\n';
325
+ //macroMolBlock += 'M V30 BEGIN COLLECTION\n';
326
+ //macroMolBlock += collectionBlock;
327
+ //macroMolBlock += 'M V30 END COLLECTION\n';
328
+ macroMolBlock += 'M V30 END CTAB\n';
329
+ macroMolBlock += 'M END\n';
330
+ return macroMolBlock;
331
+ }
332
+ export function getMacroMol(monomers) {
333
+ return __awaiter(this, void 0, void 0, function* () {
334
+ const result = [];
335
+ const moduleRdkit = yield grok.functions.call('Chem:getRdKitModule');
336
+ for (let i = 0; i < monomers.length; i++) {
337
+ for (let j = 0; j < monomers[i].length; j++) {
338
+ const molObj = moduleRdkit.get_mol(monomers[i][j]['molfile']);
339
+ const v3KMolblock = molObj.get_v3Kmolblock();
340
+ const indices = getIndices(monomers[i][j]['molfile'], v3KMolblock);
341
+ monomers[i][j]['indices'] = indices;
342
+ // a new molfile for 'rotated' is obtained in v3k format
343
+ monomers[i][j]['molfile'] = yield rotateBackboneV3K(v3KMolblock, indices);
344
+ // monomers[i][j]['molfile'] = v3KMolblock;
345
+ molObj === null || molObj === void 0 ? void 0 : molObj.delete();
346
+ }
347
+ // seemingly, at this stage the bond is reconstructed
348
+ result.push(linkV3K(monomers[i]));
349
+ // result.push(monomers[i][0]['molfile']);
350
+ }
351
+ return result;
352
+ });
353
+ }
354
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRvbWljLXdvcmtzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYXRvbWljLXdvcmtzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBLE9BQU8sS0FBSyxJQUFJLE1BQU0sbUJBQW1CLENBQUM7QUFtQjFDLFNBQVMsa0JBQWtCLENBQUMsV0FBbUI7SUFDN0MsTUFBTSxPQUFPLEdBQUcsMkJBQTJCLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDekQsSUFBSSxLQUFLLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsbUNBQW1DO0lBQ3pGLEtBQUssR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN6QyxJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUM7SUFFaEIsTUFBTSxXQUFXLEdBQWEsS0FBSyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN2RCxNQUFNLFNBQVMsR0FBYSxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3JELE1BQU0sQ0FBQyxHQUFhLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0MsTUFBTSxDQUFDLEdBQWEsS0FBSyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUU3QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUMxQyxLQUFLLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzlDLEdBQUcsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN0QyxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFF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S0FBSyxDQUFDLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBQyxDQUFDLENBQUM7U0FDN0U7YUFBTSxJQUFJLFdBQVcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsMEJBQTBCO1lBQ2pFLEtBQUssR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUk7U0FDdkU7YUFBTTtZQUNMLE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMxRCxJQUFJLFdBQVcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0JBQzVDLEtBQUssR0FBRyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7O2dCQUUvRCxLQUFLLEdBQUcsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7U0FDckY7UUFFRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzVCLE1B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LEVBQUUsS0FBSyxDQUFDLEdBQUcsVUFBVSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBRWxGLHFCQUFxQjtnQkFDckIsS0FBSyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDM0MsS0FBSyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDM0MsUUFBUSxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUUxQyxJQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLEdBQUMsS0FBSyxDQUFDO2dCQUMxRyxVQUFVLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEdBQUcsVUFBVSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBRWxGLEtBQUssR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzNDLFFBQVEsR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDMUMsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFDLEtBQUssQ0FBQztnQkFDekYsVUFBVSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxHQUFHLFVBQVUsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLFFB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MkNBQTJDO2dCQUMzQyxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsTUFBTSxFQUFFLENBQUM7YUFDbEI7WUFDRCxxREFBcUQ7WUFDckQsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsQywwQ0FBMEM7U0FDM0M7UUFFRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0NBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBncm9rIGZyb20gJ2RhdGFncm9rLWFwaS9ncm9rJztcblxudHlwZSBJbmRpY2VzID0ge1xuICBmaXJzdDogbnVtYmVyLCAvLyBub2RlIHRvIHdoaWNoIHJlbUZpcnN0IGlzIGF0dGFjaGVkXG4gIGxhc3Q6IG51bWJlciwgLy8gbm9kZSB0byB3aGljaCByZW1MYXN0IGlzIGF0dGFjaGVkXG4gIHJlbUZpcnN0OiBudW1iZXIsIC8vIFwibGVmdG1vc3RcIiByLWdyb3VwIG5vZGUgb2YgdGhlIG1vbm9tZXJcbiAgcmVtTGFzdDogbnVtYmVyLCAvLyBcInJpZ2h0bW9zdFwiIHItZ3JvdXAgbm9kZSBvZiB0aGUgbW9ub21lclxuICByZW1Cb25kRmlyc3Q6IG51bWJlciwgLy8gaWR4IG9mIHRoZSBib25kIGJldHdlZW4gZmlyc3QgYW5kIHJlbUZpcnN0XG4gIHJlbUJvbmRMYXN0OiBudW1iZXIsIC8vIGlkeCBvZiB0aGUgYm9uZCBiZXR3ZWVuIGxhc3QgYW5kIHJlbUxhc3Rcbn1cblxuLy8gdG9kbzogaW1wcm92ZVxudHlwZSBBdG9tRGF0YSA9IHtcbiAgYXRvbUluZGljZXM6IG51bWJlcltdLFxuICBhdG9tVHlwZXM6IHN0cmluZ1tdLFxuICB4OiBudW1iZXJbXSxcbiAgeTogbnVtYmVyW10sXG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RBdG9tRGF0YVYzSyh2M0tNb2xibG9jazogc3RyaW5nKTogQXRvbURhdGEge1xuICBjb25zdCBudW1iZXJzID0gZXh0cmFjdEF0b21BbmRCb25kQ291bnRzVjNLKHYzS01vbGJsb2NrKTtcbiAgbGV0IGJlZ2luID0gdjNLTW9sYmxvY2suaW5kZXhPZignTSAgVjMwIEJFR0lOIEFUT00nKTsgLy8gVjMwMDAgYmxvY2sgZm9yIGF0b20gY29vcmRpbmF0ZXNcbiAgYmVnaW4gPSB2M0tNb2xibG9jay5pbmRleE9mKCdcXG4nLCBiZWdpbik7XG4gIGxldCBlbmQgPSBiZWdpbjtcblxuICBjb25zdCBhdG9tSW5kaWNlczogbnVtYmVyW10gPSBBcnJheShudW1iZXJzLmF0b21Db3VudCk7XG4gIGNvbnN0IGF0b21UeXBlczogc3RyaW5nW10gPSBBcnJheShudW1iZXJzLmF0b21Db3VudCk7XG4gIGNvbnN0IHg6IG51bWJlcltdID0gQXJyYXkobnVtYmVycy5hdG9tQ291bnQpO1xuICBjb25zdCB5OiBudW1iZXJbXSA9IEFycmF5KG51bWJlcnMuYXRvbUNvdW50KTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlcnMuYXRvbUNvdW50OyBpKyspIHtcbiAgICBiZWdpbiA9IHYzS01vbGJsb2NrLmluZGV4T2YoJ1YzMCcsIGJlZ2luKSArIDQ7XG4gICAgZW5kID0gdjNLTW9sYmxvY2suaW5kZXhPZignICcsIGJlZ2luKTtcbiAgICBhdG9tSW5kaWNlc1tpXSA9IHBhcnNlSW50KHYzS01vbGJsb2NrLnN1YnN0cmluZyhiZWdpbiwgZW5kKSk7XG5cbiAgICBiZWdpbiA9IGVuZCArIDE7XG4gICAgZW5kID0gdjNLTW9sYmxvY2suaW5kZXhPZignICcsIGJlZ2luKTtcbiAgICBhdG9tVHlwZXNbaV0gPSB2M0tNb2xibG9jay5zdWJzdHJpbmcoYmVnaW4sIGVuZCk7XG5cbiAgICBiZWdpbiA9IGVuZCArIDE7XG4gICAgZW5kID0gdjNLTW9sYmxvY2suaW5kZXhPZignICcsIGJlZ2luKTtcbiAgICB4W2ldID0gcGFyc2VGbG9hdCh2M0tNb2xibG9jay5zdWJzdHJpbmcoYmVnaW4sIGVuZCkpO1xuXG4gICAgYmVnaW4gPSBlbmQgKyAxO1xuICAgIGVuZCA9IHYzS01vbGJsb2NrLmluZGV4T2YoJyAnLCBiZWdpbik7XG4gICAgeVtpXSA9IHBhcnNlRmxvYXQodjNLTW9sYmxvY2suc3Vic3RyaW5nKGJlZ2luLCBlbmQpKTtcblxuICAgIGJlZ2luID0gdjNLTW9sYmxvY2suaW5kZXhPZignXFxuJywgYmVnaW4pICsgMTtcbiAgfVxuXG4gIHJldHVybiB7YXRvbUluZGljZXM6IGF0b21JbmRpY2VzLCBhdG9tVHlwZXM6IGF0b21UeXBlcywgeDogeCwgeTogeX07XG59XG5cbi8vIHRvZG86IGV4dHJhY3RSZ3JvdXBEYXRhXG5cbmZ1bmN0aW9uIGV4dHJhY3RBdG9tQW5kQm9uZENvdW50c1YzSyh2M0tNb2xibG9jazogc3RyaW5nKToge2F0b21Db3VudDogbnVtYmVyLCBib25kQ291bnQ6IG51bWJlcn0ge1xuICB2M0tNb2xibG9jayA9IHYzS01vbGJsb2NrLnJlcGxhY2VBbGwoJ1xccicsICcnKTsgLy8gZXF1YWxpemUgb2xkIGFuZCBuZXcgc2RmIHN0YW5kYXJkc1xuXG4gIC8vIHBhcnNlIGF0b20gY291bnRcbiAgbGV0IGlkeEJlZ2luID0gdjNLTW9sYmxvY2suaW5kZXhPZignQ09VTlRTJykgKyA3O1xuICBsZXQgaWR4RW5kID0gdjNLTW9sYmxvY2suaW5kZXhPZignICcsIGlkeEJlZ2luKTtcbiAgY29uc3QgbnVtT2ZBdG9tcyA9IHBhcnNlSW50KHYzS01vbGJsb2NrLnN1YnN0cmluZyhpZHhCZWdpbiwgaWR4RW5kKSk7XG5cbiAgLy8gcGFyc2UgYm9uZCBjb3VudFxuICBpZHhCZWdpbiA9IGlkeEVuZCArIDE7XG4gIGlkeEVuZCA9IHYzS01vbGJsb2NrLmluZGV4T2YoJyAnLCBpZHhCZWdpbik7XG4gIGNvbnN0IG51bU9mQm9uZHMgPSBwYXJzZUludCh2M0tNb2xibG9jay5zdWJzdHJpbmcoaWR4QmVnaW4sIGlkeEVuZCkpO1xuXG4gIHJldHVybiB7YXRvbUNvdW50OiBudW1PZkF0b21zLCBib25kQ291bnQ6IG51bU9mQm9uZHN9O1xufVxuXG5mdW5jdGlvbiBnZXRJbmRpY2VzKHYyS01vbGJsb2NrOiBzdHJpbmcsIHYzS01vbGJsb2NrOiBzdHJpbmcpOiBJbmRpY2VzIHtcbiAgLy8gb25lIHNob3VsZCBhbHNvIHRha2UgaW50byBhY2NvdW50IHRoYXQgdGhlcmUgY2FuIGJlIG11bHRpcGxlIE0gUkdQIGxpbmVzXG4gIC8vIHdpdGggUi1Hcm91cHMgc3BlY2lmaWVkXG4gIGxldCBiZWdpbiA9IHYyS01vbGJsb2NrLmluZGV4T2YoJ00gIFJHUCcsIDApICsgODtcbiAgbGV0IGVuZCA9IHYyS01vbGJsb2NrLmluZGV4T2YoJ1xcbicsIGJlZ2luKTtcblxuICAvLyB0b2RvOiBtYXliZSB0aGlzIHBhcnQgZGVzZXJ2ZXMgYSBzZXBhcmF0ZSBmdW5jdGlvblxuICAvLyB0aGVyZSBtYXkgYmUgc2l0dWF0aW9uIHdoZW4gdGhlIHJncCBpbmZvcm1hdGlvbiBpcyBkaXN0cmlidXRlZCBhbW9uZ1xuICAvLyBtdWx0aXBsZSBsaW5lcywgdGhpcyBtdXN0IGJlIHRha2VuIGludG8gYWNjb3VudFxuICBjb25zdCByZ3BTdHJpbmdQYXJzZWQgPSB2MktNb2xibG9jay5zdWJzdHJpbmcoYmVnaW4sIGVuZCkucmVwbGFjZUFsbCgnICAnLCAnICcpLnJlcGxhY2VBbGwoJyAgJywgJyAnKS5zcGxpdCgnICcpO1xuICBjb25zdCByZ3BEYXRhID0gcmdwU3RyaW5nUGFyc2VkLm1hcCgoZWwpID0+IHBhcnNlSW50KGVsKSk7XG4gIC8vIHJncERhdGFbMF0gaXMgdGhlIG51bWJlciBvZiBSLWdyb3Vwc1xuICAvLyB0aGUgZm9sbG93aW5nIGNvZGUgc2V0cyByZW1GaXJzdCB0byBub2RlIyB0byB3aGljaCBSR1AjMSBpcyBzdWJzdGl0dXRlZFxuXG4gIC8vIHRvZG86IGhhbmRsZSB0aGUgZXhjZXB0aW9uYWwgY2FzZSB3aGVuIHRoZXJlIGlzIG5vdCBlbm91Z2ggcmdyb3Vwc1xuICAvLyB0b2RvOiBoYW5kbGUgdGhlIGV4Y2VwdGlvbmFsIGNhc2Ugd2hlbiB0aGUgb3JkZXIgaXMgZGlmZmVyZW50XG4gIGNvbnN0IHJlbUZpcnN0ID0gcmdwRGF0YVsxXTsgLy8gbGVmdG1vc3QgUmdyb3VwIG5vZGVcbiAgY29uc3QgcmVtTGFzdCA9IHJncERhdGFbcmdwRGF0YS5sZW5ndGggLSAyXTsgLy8gcmlnaHRtb3N0IFJncm91cCBub2RlXG4gIC8vIGlmIChyZW1GaXJzdCA9PT0gLTEgfHwgcmVtTGFzdCA9PT0gLTEpXG4gIC8vICAgdGhyb3cgbmV3IEVycm9yKCdSR1AgcGFyc2luZzogZmlyc3QgYW5kIGxhc3QgZ3JvdXBzIGhhdmUgd3JvbmcgZm9ybWF0Jyk7XG5cbiAgLy8gY29uc3QgcmVtRmlyc3QgPSByZ3BEYXRhWzJdID09PSAnMScgPyBwYXJzZUludChyZ3BEYXRhWzFdKSA6IHBhcnNlSW50KHJncERhdGFbM10pO1xuICAvLyBjb25zdCByZW1MYXN0ID0gcmdwRGF0YVsyXSA9PT0gJzInID8gcGFyc2VJbnQocmdwRGF0YVsxXSkgOiBwYXJzZUludChyZ3BEYXRhWzNdKTtcblxuICAvLyB0b2RvOiByZW5hbWUgJ251bWJlcnMnXG4gIGNvbnN0IG51bWJlcnMgPSBleHRyYWN0QXRvbUFuZEJvbmRDb3VudHNWM0sodjNLTW9sYmxvY2spO1xuICBsZXQgaW5kZXhCb25kcyA9IHYzS01vbGJsb2NrLmluZGV4T2YoJ00gIFYzMCBCRUdJTiBCT05EJyk7IC8vIFYzMDAwIGJvbmQgYmxvY2tcbiAgaW5kZXhCb25kcyA9IHYzS01vbGJsb2NrLmluZGV4T2YoJ1xcbicsIGluZGV4Qm9uZHMpO1xuICBiZWdpbiA9IGluZGV4Qm9uZHM7XG4gIGVuZCA9IGluZGV4Qm9uZHM7XG5cbiAgbGV0IGZpcnN0ID0gMDsgLy8gdG9kbzogaW1wcm92ZSBub3RhdGlvblxuICBsZXQgbGFzdCA9IDA7XG4gIGxldCByZW1Cb25kRmlyc3QgPSAwO1xuICBsZXQgcmVtQm9uZExhc3QgPSAwO1xuXG4gIC8vIGl0ZXJhdGUgb3ZlciBlZGdlcyBvZiB0aGUgZ3JhcGggYW5kIGZpbmQgdGhvc2VcbiAgZm9yIChsZXQgaiA9IDA7IGogPCBudW1iZXJzLmJvbmRDb3VudDsgaisrKSB7XG4gICAgaWYgKGZpcnN0ID09PSAwIHx8IGxhc3QgPT09IDApIHtcbiAgICAgIGJlZ2luID0gdjNLTW9sYmxvY2suaW5kZXhPZignVjMwJywgYmVnaW4pICsgNDtcbiAgICAgIGVuZCA9IHYzS01vbGJsb2NrLmluZGV4T2YoJ1xcbicsIGJlZ2luKTtcbiAgICAgIGNvbnN0IGJvbmRTdHJpbmdQYXJzZWQgPSB2M0tNb2xibG9jay5zdWJzdHJpbmcoYmVnaW4sIGVuZCkucmVwbGFjZUFsbCgnICAnLCAnICcpLnJlcGxhY2VBbGwoJyAgJywgJyAnKS5zcGxpdCgnICcpO1xuICAgICAgY29uc3QgYm9uZERhdGEgPSBib25kU3RyaW5nUGFyc2VkLm1hcCgoZWwpID0+IHBhcnNlSW50KGVsKSk7XG5cbiAgICAgIGlmIChib25kRGF0YVsyXSA9PT0gcmVtRmlyc3QpIHsgLy8gYm9uZERhdGFbMl0gaXMgdGhlIDFzdCBub2RlL2F0b20gb2YgdGhlIGJvbmRcbiAgICAgICAgZmlyc3QgPSBib25kRGF0YVszXTsgLy8gYm9uZERhdGFbM10gaXMgdGhlIDJuZCBub2RlL2F0b20gb2YgdGhlIGJvbmRcbiAgICAgICAgcmVtQm9uZEZpcnN0ID0gYm9uZERhdGFbMF07IC8vIGJvbmREYXRhWzBdIGlzIHRoZSBpZHggb2YgdGhlIGFzc29jaWF0ZWQgYm9uZC9lZGdlXG4gICAgICB9IGVsc2UgaWYgKGJvbmREYXRhWzNdID09PSByZW1GaXJzdCkge1xuICAgICAgICBmaXJzdCA9IGJvbmREYXRhWzJdO1xuICAgICAgICByZW1Cb25kRmlyc3QgPSBib25kRGF0YVswXTtcbiAgICAgIH0gZWxzZSBpZiAoYm9uZERhdGFbMl0gPT09IHJlbUxhc3QpIHtcbiAgICAgICAgbGFzdCA9IGJvbmREYXRhWzNdO1xuICAgICAgICByZW1Cb25kTGFzdCA9IGJvbmREYXRhWzBdO1xuICAgICAgfSBlbHNlIGlmIChib25kRGF0YVszXSA9PT0gcmVtTGFzdCkge1xuICAgICAgICBsYXN0ID0gYm9uZERhdGFbMl07XG4gICAgICAgIHJlbUJvbmRMYXN0ID0gYm9uZERhdGFbMF07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtmaXJzdCwgbGFzdCwgcmVtRmlyc3QsIHJlbUxhc3QsIHJlbUJvbmRGaXJzdCwgcmVtQm9uZExhc3R9O1xufVxuXG4vKiBwcm92aWRlIGRlc2NyaXB0aW9uICovXG5hc3luYyBmdW5jdGlvbiByb3RhdGVCYWNrYm9uZVYzSyh2M0tNb2xibG9jazogc3RyaW5nLCBpbmRpY2VzOmFueSk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGNvb3JkaW5hdGVzID0gZXh0cmFjdEF0b21EYXRhVjNLKHYzS01vbGJsb2NrKTsgLy8gbmFtaW5nP1xuICBjb25zdCBhdG9tQ291bnQgPSBjb29yZGluYXRlcy5hdG9tSW5kaWNlcy5sZW5ndGg7XG4gIGNvbnN0IGZpcnN0ID0gaW5kaWNlc1snZmlyc3QnXTtcbiAgY29uc3QgbGFzdCA9IGluZGljZXNbJ2xhc3QnXTtcblxuICBjb25zdCB4Q2VudGVyID0gKGNvb3JkaW5hdGVzLnhbbGFzdF0gKyBjb29yZGluYXRlcy54W2ZpcnN0XSkvMjtcbiAgY29uc3QgeUNlbnRlciA9IChjb29yZGluYXRlcy55W2xhc3RdICsgY29vcmRpbmF0ZXMueVtmaXJzdF0pLzI7XG5cbiAgLy9wbGFjZSB0byBjZW50ZXJcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdG9tQ291bnQ7IGkrKykge1xuICAgIGNvb3JkaW5hdGVzLnhbaV0gLT0geENlbnRlcjtcbiAgICBjb29yZGluYXRlcy55W2ldIC09IHlDZW50ZXI7XG4gIH1cblxuICBsZXQgYW5nbGUgPSAwO1xuICBpZiAoY29vcmRpbmF0ZXMueFtmaXJzdF0gPT09IDApIHsgLy8gYm90aCB2ZXJ0aWNlcyBhcmUgb24gT1lcbiAgICBhbmdsZSA9IGNvb3JkaW5hdGVzLnlbZmlyc3RdID4gY29vcmRpbmF0ZXMueVtsYXN0XSA/IE1hdGguUEkvMiA6IC1NYXRoLlBJLzI7XG4gIH0gZWxzZSBpZiAoY29vcmRpbmF0ZXMueVtmaXJzdF0gPT09IDApIHsgLy8gYm90aCB2ZXJ0aWNlcyBhcmUgb24gT1hcbiAgICBhbmdsZSA9IGNvb3JkaW5hdGVzLnhbZmlyc3RdID4gY29vcmRpbmF0ZXMueFtsYXN0XSA/IE1hdGguUEkgOiAwOyAvLyB2XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgdGFuZ2VudCA9IGNvb3JkaW5hdGVzLnlbZmlyc3RdL2Nvb3JkaW5hdGVzLnhbZmlyc3RdO1xuICAgIGlmIChjb29yZGluYXRlcy54W2ZpcnN0XSA8IGNvb3JkaW5hdGVzLnhbbGFzdF0pXG4gICAgICBhbmdsZSA9IHRhbmdlbnQgPiAwID8gLU1hdGguYXRhbih0YW5nZW50KSA6IE1hdGguYXRhbih0YW5nZW50KTtcbiAgICBlbHNlXG4gICAgICBhbmdsZSA9IHRhbmdlbnQgPiAwID8gTWF0aC5QSSAtIE1hdGguYXRhbih0YW5nZW50KSA6IE1hdGguYXRhbih0YW5nZW50KSAtIE1hdGguUEk7XG4gIH1cblxuICBjb25zdCBjb3MgPSBNYXRoLmNvcyhhbmdsZSk7XG4gIGNvbnN0IHNpbiA9IE1hdGguc2luKGFuZ2xlKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGF0b21Db3VudDsgaSsrKSB7XG4gICAgY29uc3QgeEFkZCA9IGNvb3JkaW5hdGVzLnhbaV07XG4gICAgY29vcmRpbmF0ZXMueFtpXSA9IHhBZGQqY29zIC0gY29vcmRpbmF0ZXMueVtpXSpzaW47XG4gICAgY29vcmRpbmF0ZXMueVtpXSA9IHhBZGQqc2luICsgY29vcmRpbmF0ZXMueVtpXSpjb3M7XG4gIH1cblxuICAvL3BsYWNlIHRvIHJpZ2h0XG4gIGNvbnN0IHhTaGlmdCA9IGNvb3JkaW5hdGVzLnhbZmlyc3RdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGF0b21Db3VudDsgaSsrKVxuICAgIGNvb3JkaW5hdGVzLnhbaV0gLT0geFNoaWZ0O1xuXG4gIC8vcmV3cml0ZSB2M0tNb2xibG9ja1xuICBsZXQgaW5kZXggPSB2M0tNb2xibG9jay5pbmRleE9mKCdNICBWMzAgQkVHSU4gQVRPTScpOyAvLyBWMzAwMCBpbmRleCBmb3IgYXRvbXMgY29vcmRpbmF0ZXNcbiAgaW5kZXggPSB2M0tNb2xibG9jay5pbmRleE9mKCdcXG4nLCBpbmRleCk7XG4gIGxldCBpbmRleEVuZCA9IGluZGV4O1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGF0b21Db3VudDsgaSsrKSB7XG4gICAgaW5kZXggPSB2M0tNb2xibG9jay5pbmRleE9mKCdWMzAnLCBpbmRleCkgKyA0O1xuICAgIGluZGV4ID0gdjNLTW9sYmxvY2suaW5kZXhPZignICcsIGluZGV4KSArIDE7XG4gICAgaW5kZXggPSB2M0tNb2xibG9jay5pbmRleE9mKCcgJywgaW5kZXgpICsgMTtcbiAgICBpbmRleEVuZCA9IHYzS01vbGJsb2NrLmluZGV4T2YoJyAnLCBpbmRleCkgKyAxO1xuICAgIGluZGV4RW5kID0gdjNLTW9sYmxvY2suaW5kZXhPZignICcsIGluZGV4RW5kKTtcblxuICAgIHYzS01vbGJsb2NrID0gdjNLTW9sYmxvY2suc2xpY2UoMCwgaW5kZXgpICtcbiAgICAgIGNvb3JkaW5hdGVzLnhbaV0gKyAnICcgKyBjb29yZGluYXRlcy55W2ldICtcbiAgICAgIHYzS01vbGJsb2NrLnNsaWNlKGluZGV4RW5kKTtcblxuICAgIGluZGV4ID0gdjNLTW9sYmxvY2suaW5kZXhPZignXFxuJywgaW5kZXgpICsgMTtcbiAgfVxuXG4gIHJldHVybiB2M0tNb2xibG9jaztcbn1cblxuLyogcHJvdmlkZSBkZXNjcmlwdGlvbiAqL1xuZnVuY3Rpb24gbGlua1YzSyhtb25vbWVyczogYW55W10pOiBzdHJpbmcge1xuICBsZXQgbWFjcm9Nb2xCbG9jayA9ICdcXG5EYXRhZ3JvayBtYWNyb21vbGVjdWxlIGhhbmRsZXJcXG5cXG4nO1xuICBtYWNyb01vbEJsb2NrICs9ICcgIDAgIDAgIDAgIDAgIDAgIDAgICAgICAgICAgICA5OTkgVjMwMDBcXG4nO1xuICBtYWNyb01vbEJsb2NrICs9ICdNICBWMzAgQkVHSU4gQ1RBQlxcbic7XG4gIGxldCBhdG9tQmxvY2sgPSAnJztcbiAgbGV0IGJvbmRCbG9jayA9ICcnO1xuICAvLyBjb25zdCBjb2xsZWN0aW9uQmxvY2sgPSAnJztcbiAgLy8gY29uc3QgY29sbGVjdGlvbjogbnVtYmVyIFtdID0gW107XG4gIGxldCBhdG9tQ291bnQgPSAwO1xuICBsZXQgYm9uZENvdW50ID0gMDtcbiAgbGV0IHhTaGlmdCA9IDA7IC8vID9cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IG1vbm9tZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IHYzS01vbGZpbGUgPSBtb25vbWVyc1tpXVsnbW9sZmlsZSddO1xuICAgIGNvbnN0IGZpcnN0ID0gbW9ub21lcnNbaV1bJ2luZGljZXMnXVsnZmlyc3QnXTtcbiAgICBjb25zdCBsYXN0ID0gbW9ub21lcnNbaV1bJ2luZGljZXMnXVsnbGFzdCddO1xuICAgIGNvbnN0IHJlbUZpcnN0ID0gbW9ub21lcnNbaV1bJ2luZGljZXMnXVsncmVtRmlyc3QnXTtcbiAgICBjb25zdCByZW1MYXN0ID0gbW9ub21lcnNbaV1bJ2luZGljZXMnXVsncmVtTGFzdCddO1xuICAgIGNvbnN0IHJlbUJvbmRGaXJzdCA9IG1vbm9tZXJzW2ldWydpbmRpY2VzJ11bJ3JlbUJvbmRGaXJzdCddO1xuICAgIGNvbnN0IHJlbUJvbmRMYXN0ID0gbW9ub21lcnNbaV1bJ2luZGljZXMnXVsncmVtQm9uZExhc3QnXTtcbiAgICAvLyB0b2RvOiBoYW5kbGUgci1ncm91cHNcbiAgICB2M0tNb2xmaWxlID0gdjNLTW9sZmlsZS5yZXBsYWNlQWxsKCcoLVxcbk0gIFYzMCAnLCAnKCcpXG4gICAgICAucmVwbGFjZUFsbCgnLVxcbk0gIFYzMCAnLCAnJykucmVwbGFjZUFsbCgnICknLCAnKScpO1xuICAgIC8vIHRvZG86IGltcHJvdmUgbmFtaW5nXG4gICAgY29uc3QgbnVtYmVycyA9IGV4dHJhY3RBdG9tQW5kQm9uZENvdW50c1YzSyh2M0tNb2xmaWxlKTtcbiAgICBjb25zdCBjb29yZGluYXRlcyA9IGV4dHJhY3RBdG9tRGF0YVYzSyh2M0tNb2xmaWxlKTtcblxuICAgIGxldCBpbmRleEF0b21zID0gdjNLTW9sZmlsZS5pbmRleE9mKCdNICBWMzAgQkVHSU4gQVRPTScpOyAvLyBWMzAwMCBhdG9tIGJsb2NrXG4gICAgaW5kZXhBdG9tcyA9IHYzS01vbGZpbGUuaW5kZXhPZignXFxuJywgaW5kZXhBdG9tcyk7XG4gICAgbGV0IGluZGV4ID0gaW5kZXhBdG9tcztcbiAgICBsZXQgaW5kZXhFbmQgPSBpbmRleEF0b21zO1xuICAgIGNvbnN0IHRvdGFsU2hpZnQgPSB4U2hpZnQgLSBjb29yZGluYXRlcy54W2ZpcnN0IC0gMV07XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IG51bWJlcnMuYXRvbUNvdW50OyBqKyspIHtcbiAgICAgIGlmIChjb29yZGluYXRlcy5hdG9tSW5kaWNlc1tqXSAhPSByZW1GaXJzdCAmJiBjb29yZGluYXRlcy5hdG9tSW5kaWNlc1tqXSAhPSByZW1MYXN0KSB7IC8vfHwgaSA9PT0gMCkge1xuICAgICAgICAvL3Jld3JpdGUgYXRvbSBudW1iZXJcbiAgICAgICAgaW5kZXggPSB2M0tNb2xmaWxlLmluZGV4T2YoJ1YzMCcsIGluZGV4KSArIDQ7XG4gICAgICAgIGluZGV4RW5kID0gdjNLTW9sZmlsZS5pbmRleE9mKCcgJywgaW5kZXgpO1xuXG4gICAgICAgIGxldCBhdG9tTnVtYmVyID0gcGFyc2VJbnQodjNLTW9sZmlsZS5zdWJzdHJpbmcoaW5kZXgsIGluZGV4RW5kKSk7XG4gICAgICAgIGF0b21OdW1iZXIgPSAoYXRvbU51bWJlciA+IHJlbUZpcnN0ICYmIGF0b21OdW1iZXIgPiByZW1MYXN0KSA/IGF0b21OdW1iZXIgLSAyIDpcbiAgICAgICAgICAoYXRvbU51bWJlciA+IHJlbUZpcnN0IHx8IGF0b21OdW1iZXIgPiByZW1MYXN0KSA/IGF0b21OdW1iZXIgLSAxIDogYXRvbU51bWJlcjtcbiAgICAgICAgYXRvbU51bWJlciArPSBhdG9tQ291bnQ7XG4gICAgICAgIHYzS01vbGZpbGUgPSB2M0tNb2xmaWxlLnNsaWNlKDAsIGluZGV4KSArIGF0b21OdW1iZXIgKyB2M0tNb2xmaWxlLnNsaWNlKGluZGV4RW5kKTtcblxuICAgICAgICAvL3Jld3JpdGUgY29vcmRpbmF0ZXNcbiAgICAgICAgaW5kZXggPSB2M0tNb2xmaWxlLmluZGV4T2YoJyAnLCBpbmRleCkgKyAxO1xuICAgICAgICBpbmRleCA9IHYzS01vbGZpbGUuaW5kZXhPZignICcsIGluZGV4KSArIDE7XG4gICAgICAgIGluZGV4RW5kID0gdjNLTW9sZmlsZS5pbmRleE9mKCcgJywgaW5kZXgpO1xuXG4gICAgICAgIGxldCBjb29yZGluYXRlID0gTWF0aC5yb3VuZCgxMDAwMCoocGFyc2VGbG9hdCh2M0tNb2xmaWxlLnN1YnN0cmluZyhpbmRleCwgaW5kZXhFbmQpKSArIHRvdGFsU2hpZnQpKS8xMDAwMDtcbiAgICAgICAgdjNLTW9sZmlsZSA9IHYzS01vbGZpbGUuc2xpY2UoMCwgaW5kZXgpICsgY29vcmRpbmF0ZSArIHYzS01vbGZpbGUuc2xpY2UoaW5kZXhFbmQpO1xuXG4gICAgICAgIGluZGV4ID0gdjNLTW9sZmlsZS5pbmRleE9mKCcgJywgaW5kZXgpICsgMTtcbiAgICAgICAgaW5kZXhFbmQgPSB2M0tNb2xmaWxlLmluZGV4T2YoJyAnLCBpbmRleCk7XG4gICAgICAgIGNvb3JkaW5hdGUgPSBNYXRoLnJvdW5kKDEwMDAwKihwYXJzZUZsb2F0KHYzS01vbGZpbGUuc3Vic3RyaW5nKGluZGV4LCBpbmRleEVuZCkpKSkvMTAwMDA7XG4gICAgICAgIHYzS01vbGZpbGUgPSB2M0tNb2xmaWxlLnNsaWNlKDAsIGluZGV4KSArIGNvb3JkaW5hdGUgKyB2M0tNb2xmaWxlLnNsaWNlKGluZGV4RW5kKTtcblxuICAgICAgICBpbmRleCA9IHYzS01vbGZpbGUuaW5kZXhPZignXFxuJywgaW5kZXgpICsgMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZGV4ID0gdjNLTW9sZmlsZS5pbmRleE9mKCdNICBWMzAnLCBpbmRleCkgLSAxO1xuICAgICAgICBpbmRleEVuZCA9IHYzS01vbGZpbGUuaW5kZXhPZignXFxuJywgaW5kZXggKyAxKTtcbiAgICAgICAgdjNLTW9sZmlsZSA9IHYzS01vbGZpbGUuc2xpY2UoMCwgaW5kZXgpICsgdjNLTW9sZmlsZS5zbGljZShpbmRleEVuZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaW5kZXhBdG9tc0VuZCA9IHYzS01vbGZpbGUuaW5kZXhPZignTSAgVjMwIEVORCBBVE9NJyk7XG4gICAgYXRvbUJsb2NrICs9IHYzS01vbGZpbGUuc3Vic3RyaW5nKGluZGV4QXRvbXMgKyAxLCBpbmRleEF0b21zRW5kKTtcblxuICAgIGxldCBpbmRleEJvbmRzID0gdjNLTW9sZmlsZS5pbmRleE9mKCdNICBWMzAgQkVHSU4gQk9ORCcpOyAvLyBWMzAwMCBpbmRleCBmb3IgYm9uZHNcbiAgICBpbmRleEJvbmRzID0gdjNLTW9sZmlsZS5pbmRleE9mKCdcXG4nLCBpbmRleEJvbmRzKTtcbiAgICBpbmRleCA9IGluZGV4Qm9uZHM7XG4gICAgaW5kZXhFbmQgPSBpbmRleEJvbmRzO1xuICAgIGxldCBib25kTnVtYmVyID0gMDtcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgbnVtYmVycy5ib25kQ291bnQ7IGorKykge1xuICAgICAgLy9yZXdyaXRlIGJvbmQgbnVtYmVyXG4gICAgICBpbmRleCA9IHYzS01vbGZpbGUuaW5kZXhPZignVjMwJywgaW5kZXgpICsgNDtcbiAgICAgIGluZGV4RW5kID0gdjNLTW9sZmlsZS5pbmRleE9mKCcgJywgaW5kZXgpO1xuICAgICAgYm9uZE51bWJlciA9IHBhcnNlSW50KHYzS01vbGZpbGUuc3Vic3RyaW5nKGluZGV4LCBpbmRleEVuZCkpO1xuXG4gICAgICBpZiAoYm9uZE51bWJlciA9PT0gcmVtQm9uZEZpcnN0IHx8IGJvbmROdW1iZXIgPT09IHJlbUJvbmRMYXN0KSB7XG4gICAgICAgIGluZGV4RW5kID0gdjNLTW9sZmlsZS5pbmRleE9mKCdcXG4nLCBpbmRleCkgKyAxO1xuICAgICAgICBpbmRleCAtPTc7XG4gICAgICAgIHYzS01vbGZpbGUgPSB2M0tNb2xmaWxlLnNsaWNlKDAsIGluZGV4KSArIHYzS01vbGZpbGUuc2xpY2UoaW5kZXhFbmQpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgYm9uZE51bWJlciA9IChib25kTnVtYmVyID4gcmVtQm9uZEZpcnN0ICYmIGJvbmROdW1iZXIgPiByZW1Cb25kTGFzdCkgPyBib25kTnVtYmVyIC0gMiA6XG4gICAgICAgIChib25kTnVtYmVyID4gcmVtQm9uZEZpcnN0IHx8IGJvbmROdW1iZXIgPiByZW1Cb25kTGFzdCkgPyBib25kTnVtYmVyIC0gMSA6IGJvbmROdW1iZXI7XG4gICAgICBib25kTnVtYmVyICs9IGJvbmRDb3VudDtcblxuICAgICAgdjNLTW9sZmlsZSA9IHYzS01vbGZpbGUuc2xpY2UoMCwgaW5kZXgpICsgYm9uZE51bWJlciArIHYzS01vbGZpbGUuc2xpY2UoaW5kZXhFbmQpO1xuXG4gICAgICAvL3Jld3JpdGUgYXRvbSBwYWlyIGluIGJvbmRcbiAgICAgIGluZGV4ID0gdjNLTW9sZmlsZS5pbmRleE9mKCcgJywgaW5kZXgpICsgMTtcbiAgICAgIGluZGV4ID0gdjNLTW9sZmlsZS5pbmRleE9mKCcgJywgaW5kZXgpICsgMTtcbiAgICAgIGluZGV4RW5kID0gdjNLTW9sZmlsZS5pbmRleE9mKCcgJywgaW5kZXgpO1xuICAgICAgbGV0IGF0b21OdW1iZXIgPSBwYXJzZUludCh2M0tNb2xmaWxlLnN1YnN0cmluZyhpbmRleCwgaW5kZXhFbmQpKTtcbiAgICAgIGF0b21OdW1iZXIgPSAoYXRvbU51bWJlciA+IHJlbUZpcnN0ICYmIGF0b21OdW1iZXIgPiByZW1MYXN0KSA/IGF0b21OdW1iZXIgLSAyIDpcbiAgICAgICAgKGF0b21OdW1iZXIgPiByZW1GaXJzdCB8fCBhdG9tTnVtYmVyID4gcmVtTGFzdCkgPyBhdG9tTnVtYmVyIC0gMSA6IGF0b21OdW1iZXI7XG4gICAgICBhdG9tTnVtYmVyICs9IGF0b21Db3VudDtcbiAgICAgIHYzS01vbGZpbGUgPSB2M0tNb2xmaWxlLnNsaWNlKDAsIGluZGV4KSArIGF0b21OdW1iZXIgKyB2M0tNb2xmaWxlLnNsaWNlKGluZGV4RW5kKTtcbiAgICAgIGluZGV4ID0gdjNLTW9sZmlsZS5pbmRleE9mKCcgJywgaW5kZXgpICsgMTtcbiAgICAgIGluZGV4RW5kID0gTWF0aC5taW4odjNLTW9sZmlsZS5pbmRleE9mKCdcXG4nLCBpbmRleCksIHYzS01vbGZpbGUuaW5kZXhPZignICcsIGluZGV4KSk7XG4gICAgICBhdG9tTnVtYmVyID0gcGFyc2VJbnQodjNLTW9sZmlsZS5zdWJzdHJpbmcoaW5kZXgsIGluZGV4RW5kKSk7XG4gICAgICBhdG9tTnVtYmVyID0gKGF0b21OdW1iZXIgPiByZW1GaXJzdCAmJiBhdG9tTnVtYmVyID4gcmVtTGFzdCkgPyBhdG9tTnVtYmVyIC0gMiA6XG4gICAgICAgIChhdG9tTnVtYmVyID4gcmVtRmlyc3QgfHwgYXRvbU51bWJlciA+IHJlbUxhc3QpID8gYXRvbU51bWJlciAtIDEgOiBhdG9tTnVtYmVyO1xuICAgICAgYXRvbU51bWJlciArPSBhdG9tQ291bnQ7XG4gICAgICB2M0tNb2xmaWxlID0gdjNLTW9sZmlsZS5zbGljZSgwLCBpbmRleCkgKyBhdG9tTnVtYmVyICsgdjNLTW9sZmlsZS5zbGljZShpbmRleEVuZCk7XG5cbiAgICAgIGluZGV4ID0gdjNLTW9sZmlsZS5pbmRleE9mKCdcXG4nLCBpbmRleCkgKyAxO1xuICAgIH1cblxuICAgIGNvbnN0IGluZGV4Qm9uZEVuZCA9IHYzS01vbGZpbGUuaW5kZXhPZignTSAgVjMwIEVORCBCT05EJyk7XG4gICAgYm9uZEJsb2NrICs9IHYzS01vbGZpbGUuc3Vic3RyaW5nKGluZGV4Qm9uZHMgKyAxLCBpbmRleEJvbmRFbmQpO1xuICAgIC8vbGV0IGluZGV4Q29sbGVjdGlvbiA9IHYzS01vbGZpbGUuaW5kZXhPZignTSAgVjMwIE1ETFYzMC9TVEVBQlMgQVRPTVM9KCcpOyAvLyBWMzAwMCBpbmRleCBmb3IgY29sbGVjdGlvbnNcblxuICAgIC8vIHdoaWxlIChpbmRleENvbGxlY3Rpb24gIT0gLTEpIHtcbiAgICAvLyAgIGluZGV4Q29sbGVjdGlvbiArPSAyODtcbiAgICAvLyAgIGNvbnN0IGNvbGxlY3Rpb25FbmQgPSB2M0tNb2xmaWxlLmluZGV4T2YoJyknLCBpbmRleENvbGxlY3Rpb24pO1xuICAgIC8vICAgY29uc3QgY29sbGVjdGlvbkVudHJpZXMgPSB2M0tNb2xmaWxlLnN1YnN0cmluZyhpbmRleENvbGxlY3Rpb24sIGNvbGxlY3Rpb25FbmQpLnNwbGl0KCcgJykuc2xpY2UoMSk7XG4gICAgLy8gICBjb2xsZWN0aW9uRW50cmllcy5mb3JFYWNoKChlOiBzdHJpbmcpID0+IHtcbiAgICAvLyAgICAgY29sbGVjdGlvbi5wdXNoKHBhcnNlSW50KGUpICsgYXRvbUNvdW50KTtcbiAgICAvLyAgIH0pO1xuICAgIC8vICAgaW5kZXhDb2xsZWN0aW9uID0gY29sbGVjdGlvbkVuZDtcbiAgICAvLyAgIGluZGV4Q29sbGVjdGlvbiA9IHYzS01vbGZpbGUuaW5kZXhPZignTSAgVjMwIE1ETFYzMC9TVEVBQlMgQVRPTVM9KCcsIGluZGV4Q29sbGVjdGlvbik7XG4gICAgLy8gfVxuXG4gICAgYXRvbUNvdW50ICs9IG51bWJlcnMuYXRvbUNvdW50IC0gMjtcbiAgICBib25kQ291bnQgKz0gbnVtYmVycy5ib25kQ291bnQgLSAyO1xuICAgIHhTaGlmdCArPSBjb29yZGluYXRlcy54W2xhc3RdIC0gY29vcmRpbmF0ZXMueFtmaXJzdF0gKyAxO1xuXG4gICAgaWYgKGkgPT09IG1vbm9tZXJzLmxlbmd0aCAtMSkge1xuICAgICAgYXRvbUNvdW50Kys7XG4gICAgICBjb25zdCBzaGlmdCA9IHhTaGlmdCArIDAuMjtcbiAgICAgIGF0b21CbG9jayArPSAnTSAgVjMwICcgKyBhdG9tQ291bnQgKyAnIE8gJyArIHNoaWZ0ICsgJyAwIDAuMDAwMDAwIDBcXG4nO1xuICAgIH1cbiAgICBib25kQ291bnQrKztcbiAgICBpZiAoaSA9PT0gbW9ub21lcnMubGVuZ3RoIC0xKSB7XG4gICAgICBjb25zdCByaWdodFRlcm1pbmFsID0gKGxhc3QgPiByZW1GaXJzdCAmJiBsYXN0ID4gcmVtTGFzdCkgPyBsYXN0ICsgYXRvbUNvdW50IC0gKG51bWJlcnMuYXRvbUNvdW50IC0gMikgLSAzOlxuICAgICAgICAobGFzdCA+IHJlbUZpcnN0IHx8IGxhc3QgPiByZW1MYXN0KSA/IGxhc3QgKyBhdG9tQ291bnQgLSAobnVtYmVycy5hdG9tQ291bnQgLSAyKSAtIDIgOlxuICAgICAgICAgIGxhc3QgKyBhdG9tQ291bnQgLSAobnVtYmVycy5hdG9tQ291bnQgLSAyKSAtIDE7XG4gICAgICBib25kQmxvY2sgKz0gJ00gIFYzMCAnICsgYm9uZENvdW50ICsgJyAxICcgKyByaWdodFRlcm1pbmFsICsgJyAnICsgYXRvbUNvdW50ICsgJ1xcbic7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHJpZ2h0VGVybWluYWwgPSAobGFzdCA+IHJlbUZpcnN0ICYmIGxhc3QgPiByZW1MYXN0KSA/IGxhc3QgKyBhdG9tQ291bnQgLSAobnVtYmVycy5hdG9tQ291bnQgLSAyKSAtIDI6XG4gICAgICAgIChsYXN0ID4gcmVtRmlyc3QgfHwgbGFzdCA+IHJlbUxhc3QpID8gbGFzdCArIGF0b21Db3VudCAtIChudW1iZXJzLmF0b21Db3VudCAtIDIpIC0gMSA6XG4gICAgICAgICAgbGFzdCArIGF0b21Db3VudCAtIChudW1iZXJzLmF0b21Db3VudCAtIDIpO1xuXG4gICAgICBjb25zdCBuZXh0ID0gbW9ub21lcnNbaSArIDFdWydpbmRpY2VzJ107XG4gICAgICBjb25zdCBuZXh0Rmlyc3QgPSBuZXh0WydmaXJzdCddO1xuICAgICAgY29uc3QgbmV4dFJlbUZpcnN0ID0gbmV4dFsncmVtRmlyc3QnXTtcbiAgICAgIGNvbnN0IG5leHRSZW1MYXN0ID0gbmV4dFsncmVtTGFzdCddO1xuXG4gICAgICBjb25zdCBsZWZ0VGVybWluYWwgPSAobmV4dEZpcnN0ID4gbmV4dFJlbUZpcnN0ICYmIG5leHRGaXJzdCA+IG5leHRSZW1MYXN0KSA/IG5leHRGaXJzdCArIGF0b21Db3VudCAtIDIgOlxuICAgICAgICAobmV4dEZpcnN0ID4gbmV4dFJlbUZpcnN0IHx8IG5leHRGaXJzdCA+IG5leHRSZW1MYXN0KSA/IG5leHRGaXJzdCArIGF0b21Db3VudCAtIDEgOlxuICAgICAgICAgIG5leHRGaXJzdCArIGF0b21Db3VudDtcblxuICAgICAgYm9uZEJsb2NrICs9ICdNICBWMzAgJyArIGJvbmRDb3VudCArICcgMSAnICsgcmlnaHRUZXJtaW5hbCArICcgJyArIGxlZnRUZXJtaW5hbCArICdcXG4nO1xuICAgIH1cbiAgfVxuXG4gIC8vIGNvbnN0IGVudHJpZXMgPSA0O1xuICAvLyBjb25zdCBjb2xsTnVtYmVyID0gTWF0aC5jZWlsKGNvbGxlY3Rpb24ubGVuZ3RoIC8gZW50cmllcyk7XG4gIC8vIGNvbGxlY3Rpb25CbG9jayArPSAnTSAgVjMwIE1ETFYzMC9TVEVBQlMgQVRPTVM9KCcgKyBjb2xsZWN0aW9uLmxlbmd0aCArICcgLVxcbic7XG4gIC8vIGZvciAobGV0IGkgPSAwOyBpIDwgY29sbE51bWJlcjsgaSsrKSB7XG4gIC8vICAgY29sbGVjdGlvbkJsb2NrICs9ICdNICBWMzAgJztcbiAgLy8gICBjb25zdCBlbnRyaWVzQ3VycmVudCA9IGkgKyAxID09PSBjb2xsTnVtYmVyID8gY29sbGVjdGlvbi5sZW5ndGggLSAoY29sbE51bWJlciAtIDEpKmVudHJpZXMgOiBlbnRyaWVzO1xuICAvLyAgIGZvciAobGV0IGogPSAwOyBqIDwgZW50cmllc0N1cnJlbnQ7IGorKykge1xuICAvLyAgICAgY29sbGVjdGlvbkJsb2NrICs9IChqICsgMSA9PT0gZW50cmllc0N1cnJlbnQpID9cbiAgLy8gICAgICAgKGkgPT09IGNvbGxOdW1iZXIgLSAxID8gY29sbGVjdGlvbltlbnRyaWVzKmkgKyBqXSArICcpXFxuJyA6IGNvbGxlY3Rpb25bZW50cmllcyppICsgal0gKyAnIC1cXG4nKSA6XG4gIC8vICAgICAgIGNvbGxlY3Rpb25bZW50cmllcyppICsgal0gKyAnICc7XG4gIC8vICAgfVxuICAvLyB9XG5cbiAgLy9nZW5lcmF0ZSBmaWxlXG4gIG1hY3JvTW9sQmxvY2sgKz0gJ00gIFYzMCBDT1VOVFMgJyArIGF0b21Db3VudCArICcgJyArIGJvbmRDb3VudCArICcgMCAwIDBcXG4nO1xuICBtYWNyb01vbEJsb2NrICs9ICdNICBWMzAgQkVHSU4gQVRPTVxcbic7XG4gIG1hY3JvTW9sQmxvY2sgKz0gYXRvbUJsb2NrO1xuICBtYWNyb01vbEJsb2NrICs9ICdNICBWMzAgRU5EIEFUT01cXG4nO1xuICBtYWNyb01vbEJsb2NrICs9ICdNICBWMzAgQkVHSU4gQk9ORFxcbic7XG4gIG1hY3JvTW9sQmxvY2sgKz0gYm9uZEJsb2NrO1xuICBtYWNyb01vbEJsb2NrICs9ICdNICBWMzAgRU5EIEJPTkRcXG4nO1xuICAvL21hY3JvTW9sQmxvY2sgKz0gJ00gIFYzMCBCRUdJTiBDT0xMRUNUSU9OXFxuJztcbiAgLy9tYWNyb01vbEJsb2NrICs9IGNvbGxlY3Rpb25CbG9jaztcbiAgLy9tYWNyb01vbEJsb2NrICs9ICdNICBWMzAgRU5EIENPTExFQ1RJT05cXG4nO1xuICBtYWNyb01vbEJsb2NrICs9ICdNICBWMzAgRU5EIENUQUJcXG4nO1xuICBtYWNyb01vbEJsb2NrICs9ICdNICBFTkRcXG4nO1xuXG4gIHJldHVybiBtYWNyb01vbEJsb2NrO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0TWFjcm9Nb2wobW9ub21lcnM6IGFueVtdW10pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gIGNvbnN0IHJlc3VsdDogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgbW9kdWxlUmRraXQgPSBhd2FpdCBncm9rLmZ1bmN0aW9ucy5jYWxsKCdDaGVtOmdldFJkS2l0TW9kdWxlJyk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbW9ub21lcnMubGVuZ3RoOyBpKyspIHtcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IG1vbm9tZXJzW2ldLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCBtb2xPYmogPSBtb2R1bGVSZGtpdC5nZXRfbW9sKG1vbm9tZXJzW2ldW2pdWydtb2xmaWxlJ10pO1xuICAgICAgY29uc3QgdjNLTW9sYmxvY2sgPSBtb2xPYmouZ2V0X3YzS21vbGJsb2NrKCk7XG4gICAgICBjb25zdCBpbmRpY2VzID0gZ2V0SW5kaWNlcyhtb25vbWVyc1tpXVtqXVsnbW9sZmlsZSddLCB2M0tNb2xibG9jayk7XG4gICAgICBtb25vbWVyc1tpXVtqXVsnaW5kaWNlcyddID0gaW5kaWNlcztcblxuICAgICAgLy8gYSBuZXcgbW9sZmlsZSBmb3IgJ3JvdGF0ZWQnIGlzIG9idGFpbmVkIGluIHYzayBmb3JtYXRcbiAgICAgIG1vbm9tZXJzW2ldW2pdWydtb2xmaWxlJ10gPSBhd2FpdCByb3RhdGVCYWNrYm9uZVYzSyh2M0tNb2xibG9jaywgaW5kaWNlcyk7XG4gICAgICAvLyBtb25vbWVyc1tpXVtqXVsnbW9sZmlsZSddID0gdjNLTW9sYmxvY2s7XG4gICAgICBtb2xPYmo/LmRlbGV0ZSgpO1xuICAgIH1cbiAgICAvLyBzZWVtaW5nbHksIGF0IHRoaXMgc3RhZ2UgdGhlIGJvbmQgaXMgcmVjb25zdHJ1Y3RlZFxuICAgIHJlc3VsdC5wdXNoKGxpbmtWM0sobW9ub21lcnNbaV0pKTtcbiAgICAvLyByZXN1bHQucHVzaChtb25vbWVyc1tpXVswXVsnbW9sZmlsZSddKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG4iXX0=
@@ -0,0 +1,48 @@
1
+ export declare const HELM_CORE_LIB_FILENAME = "/data/HELMCoreLibrary.json";
2
+ export declare const enum HELM_FIELDS {
3
+ MONOMER_TYPE = "monomerType",
4
+ SMILES = "smiles",
5
+ NAME = "name",
6
+ AUTHOR = "author",
7
+ MOLFILE = "molfile",
8
+ NATURAL_ANALOG = "naturalAnalog",
9
+ RGROUPS = "rgroups",
10
+ CREATE_DATE = "createDate",
11
+ ID = "id",
12
+ POLYMER_TYPE = "polymerType",
13
+ SYMBOL = "symbol"
14
+ }
15
+ export declare const enum RGROUP_FIELDS {
16
+ CAP_GROUP_SMILES = "capGroupSmiles",
17
+ CAP_GROUP_SMILES_UPPERCASE = "capGroupSMILES",
18
+ ALTER_ID = "alternateId",
19
+ CAP_GROUP_NAME = "capGroupName",
20
+ LABEL = "label"
21
+ }
22
+ export declare const enum HELM_POLYMER_TYPE {
23
+ PEPTIDE = "PEPTIDE",
24
+ RNA = "RNA"
25
+ }
26
+ export declare const enum HELM_MONOMER_TYPE {
27
+ BACKBONE = "Backbone",
28
+ TERMINAL = "Terminal",
29
+ BRANCH = "Branch"
30
+ }
31
+ export declare const HELM_CORE_FIELDS: HELM_FIELDS[];
32
+ export declare const SDF_MONOMER_NAME = "MonomerName";
33
+ export declare const jsonSdfMonomerLibDict: {
34
+ monomerType: null;
35
+ smiles: null;
36
+ name: string;
37
+ author: null;
38
+ molfile: string;
39
+ naturalAnalog: string;
40
+ rgroups: string;
41
+ createDate: null;
42
+ id: null;
43
+ polymerType: string;
44
+ symbol: string;
45
+ };
46
+ export declare const MONOMER_ENCODE_MIN = 256;
47
+ export declare const MONOMER_ENCODE_MAX = 1034;
48
+ //# sourceMappingURL=const.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"const.d.ts","sourceRoot":"","sources":["const.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,sBAAsB,+BAA+B,CAAC;AAEnE,0BAAkB,WAAW;IAC3B,YAAY,gBAAgB;IAC5B,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,cAAc,kBAAkB;IAChC,OAAO,YAAY;IACnB,WAAW,eAAe;IAC1B,EAAE,OAAO;IACT,YAAY,gBAAgB;IAC5B,MAAM,WAAW;CAClB;AAGD,0BAAkB,aAAa;IAC7B,gBAAgB,mBAAmB;IACnC,0BAA0B,mBAAmB;IAC7C,QAAQ,gBAAgB;IACxB,cAAc,iBAAiB;IAC/B,KAAK,UAAU;CAChB;AAGD,0BAAkB,iBAAiB;IACjC,OAAO,YAAY;IACnB,GAAG,QAAQ;CACZ;AAED,0BAAkB,iBAAiB;IACjC,QAAQ,aAAa;IACrB,QAAQ,aAAa;IACrB,MAAM,WAAW;CAClB;AAGD,eAAO,MAAM,gBAAgB,eAO5B,CAAC;AAEF,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAG9C,eAAO,MAAM,qBAAqB;;;;;;;;;;;;CAYjC,CAAC;AAGF,eAAO,MAAM,kBAAkB,MAAQ,CAAC;AACxC,eAAO,MAAM,kBAAkB,OAAQ,CAAC"}
@@ -0,0 +1,29 @@
1
+ export const HELM_CORE_LIB_FILENAME = '/data/HELMCoreLibrary.json';
2
+ // core fields of HELM library object used in toAtomicLevel function
3
+ export const HELM_CORE_FIELDS = [
4
+ "symbol" /* HELM_FIELDS.SYMBOL */,
5
+ "molfile" /* HELM_FIELDS.MOLFILE */,
6
+ "rgroups" /* HELM_FIELDS.RGROUPS */,
7
+ "name" /* HELM_FIELDS.NAME */,
8
+ // HELM_FIELDS.MONOMER_TYPE, // add if terminal monomers for PEPTIDEs to be
9
+ // supported
10
+ ];
11
+ export const SDF_MONOMER_NAME = 'MonomerName';
12
+ // todo: ideally, keys should be expressed via constants
13
+ export const jsonSdfMonomerLibDict = {
14
+ 'monomerType': null,
15
+ 'smiles': null,
16
+ 'name': 'MonomerName',
17
+ 'author': null,
18
+ 'molfile': 'molecule',
19
+ 'naturalAnalog': 'MonomerNaturalAnalogCode',
20
+ 'rgroups': 'MonomerCaps',
21
+ 'createDate': null,
22
+ 'id': null,
23
+ 'polymerType': 'MonomerType',
24
+ 'symbol': 'MonomerCode'
25
+ };
26
+ // range of hex nubers used in PepSea library to endode monomers
27
+ export const MONOMER_ENCODE_MIN = 0x100;
28
+ export const MONOMER_ENCODE_MAX = 0x40A;
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjb25zdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyw0QkFBNEIsQ0FBQztBQXFDbkUsb0VBQW9FO0FBQ3BFLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHOzs7OztJQUs5QiwyRUFBMkU7SUFDM0UsWUFBWTtDQUNiLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxhQUFhLENBQUM7QUFFOUMsd0RBQXdEO0FBQ3hELE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHO0lBQ25DLGFBQWEsRUFBRSxJQUFJO0lBQ25CLFFBQVEsRUFBRSxJQUFJO0lBQ2QsTUFBTSxFQUFFLGFBQWE7SUFDckIsUUFBUSxFQUFFLElBQUk7SUFDZCxTQUFTLEVBQUUsVUFBVTtJQUNyQixlQUFlLEVBQUUsMEJBQTBCO0lBQzNDLFNBQVMsRUFBRSxhQUFhO0lBQ3hCLFlBQVksRUFBRSxJQUFJO0lBQ2xCLElBQUksRUFBRSxJQUFJO0lBQ1YsYUFBYSxFQUFFLGFBQWE7SUFDNUIsUUFBUSxFQUFFLGFBQWE7Q0FDeEIsQ0FBQztBQUVGLGdFQUFnRTtBQUNoRSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxLQUFLLENBQUM7QUFDeEMsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsS0FBSyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgdWkgZnJvbSAnZGF0YWdyb2stYXBpL3VpJztcbmltcG9ydCAqIGFzIGdyb2sgZnJvbSAnZGF0YWdyb2stYXBpL2dyb2snO1xuaW1wb3J0ICogYXMgREcgZnJvbSAnZGF0YWdyb2stYXBpL2RnJztcblxuZXhwb3J0IGNvbnN0IEhFTE1fQ09SRV9MSUJfRklMRU5BTUUgPSAnL2RhdGEvSEVMTUNvcmVMaWJyYXJ5Lmpzb24nO1xuXG5leHBvcnQgY29uc3QgZW51bSBIRUxNX0ZJRUxEUyB7XG4gIE1PTk9NRVJfVFlQRSA9ICdtb25vbWVyVHlwZScsXG4gIFNNSUxFUyA9ICdzbWlsZXMnLFxuICBOQU1FID0gJ25hbWUnLFxuICBBVVRIT1IgPSAnYXV0aG9yJyxcbiAgTU9MRklMRSA9ICdtb2xmaWxlJyxcbiAgTkFUVVJBTF9BTkFMT0cgPSAnbmF0dXJhbEFuYWxvZycsXG4gIFJHUk9VUFMgPSAncmdyb3VwcycsXG4gIENSRUFURV9EQVRFID0gJ2NyZWF0ZURhdGUnLFxuICBJRCA9ICdpZCcsXG4gIFBPTFlNRVJfVFlQRSA9ICdwb2x5bWVyVHlwZScsXG4gIFNZTUJPTCA9ICdzeW1ib2wnXG59XG5cbi8vIGZpZWxkcyBvZiBcInJncm91cHNcIiBzdWItb2JqZWN0IGluIEhFTE0gbGlicmFyeVxuZXhwb3J0IGNvbnN0IGVudW0gUkdST1VQX0ZJRUxEUyB7XG4gIENBUF9HUk9VUF9TTUlMRVMgPSAnY2FwR3JvdXBTbWlsZXMnLFxuICBDQVBfR1JPVVBfU01JTEVTX1VQUEVSQ0FTRSA9ICdjYXBHcm91cFNNSUxFUycsIC8vIGFsYXMsIGJvdGggdmFyaWFudHMgY29leGlzdFxuICBBTFRFUl9JRCA9ICdhbHRlcm5hdGVJZCcsXG4gIENBUF9HUk9VUF9OQU1FID0gJ2NhcEdyb3VwTmFtZScsXG4gIExBQkVMID0gJ2xhYmVsJyxcbn1cblxuLy8gcG9zc2libGUgdmFsdWVzIG9mIHBvbHltZXJzXG5leHBvcnQgY29uc3QgZW51bSBIRUxNX1BPTFlNRVJfVFlQRSB7XG4gIFBFUFRJREUgPSAnUEVQVElERScsXG4gIFJOQSA9ICdSTkEnLFxufVxuXG5leHBvcnQgY29uc3QgZW51bSBIRUxNX01PTk9NRVJfVFlQRSB7XG4gIEJBQ0tCT05FID0gJ0JhY2tib25lJyxcbiAgVEVSTUlOQUwgPSAnVGVybWluYWwnLFxuICBCUkFOQ0ggPSAnQnJhbmNoJyxcbn1cblxuLy8gY29yZSBmaWVsZHMgb2YgSEVMTSBsaWJyYXJ5IG9iamVjdCB1c2VkIGluIHRvQXRvbWljTGV2ZWwgZnVuY3Rpb25cbmV4cG9ydCBjb25zdCBIRUxNX0NPUkVfRklFTERTID0gW1xuICBIRUxNX0ZJRUxEUy5TWU1CT0wsXG4gIEhFTE1fRklFTERTLk1PTEZJTEUsXG4gIEhFTE1fRklFTERTLlJHUk9VUFMsXG4gIEhFTE1fRklFTERTLk5BTUUsXG4gIC8vIEhFTE1fRklFTERTLk1PTk9NRVJfVFlQRSwgLy8gYWRkIGlmIHRlcm1pbmFsIG1vbm9tZXJzIGZvciBQRVBUSURFcyB0byBiZVxuICAvLyBzdXBwb3J0ZWRcbl07XG5cbmV4cG9ydCBjb25zdCBTREZfTU9OT01FUl9OQU1FID0gJ01vbm9tZXJOYW1lJztcblxuLy8gdG9kbzogaWRlYWxseSwga2V5cyBzaG91bGQgYmUgZXhwcmVzc2VkIHZpYSBjb25zdGFudHNcbmV4cG9ydCBjb25zdCBqc29uU2RmTW9ub21lckxpYkRpY3QgPSB7XG4gICdtb25vbWVyVHlwZSc6IG51bGwsXG4gICdzbWlsZXMnOiBudWxsLFxuICAnbmFtZSc6ICdNb25vbWVyTmFtZScsXG4gICdhdXRob3InOiBudWxsLFxuICAnbW9sZmlsZSc6ICdtb2xlY3VsZScsXG4gICduYXR1cmFsQW5hbG9nJzogJ01vbm9tZXJOYXR1cmFsQW5hbG9nQ29kZScsXG4gICdyZ3JvdXBzJzogJ01vbm9tZXJDYXBzJyxcbiAgJ2NyZWF0ZURhdGUnOiBudWxsLFxuICAnaWQnOiBudWxsLFxuICAncG9seW1lclR5cGUnOiAnTW9ub21lclR5cGUnLFxuICAnc3ltYm9sJzogJ01vbm9tZXJDb2RlJ1xufTtcblxuLy8gcmFuZ2Ugb2YgaGV4IG51YmVycyB1c2VkIGluIFBlcFNlYSBsaWJyYXJ5IHRvIGVuZG9kZSBtb25vbWVyc1xuZXhwb3J0IGNvbnN0IE1PTk9NRVJfRU5DT0RFX01JTiA9IDB4MTAwO1xuZXhwb3J0IGNvbnN0IE1PTk9NRVJfRU5DT0RFX01BWCA9IDB4NDBBO1xuIl19
@@ -0,0 +1,43 @@
1
+ export declare type MonomerEntry = {
2
+ mol: string;
3
+ type: string;
4
+ analogueCode: string;
5
+ linkages: {
6
+ [link: string]: {
7
+ atomNumber: number;
8
+ type: string;
9
+ };
10
+ };
11
+ };
12
+ export declare type MonomerEntries = {
13
+ [name: string]: MonomerEntry;
14
+ };
15
+ export declare type LinkData = {
16
+ [link: string]: {
17
+ atomNumber: number;
18
+ type: string;
19
+ };
20
+ };
21
+ /** HELM associated sdf libraries with monomer processing*/
22
+ export declare class MonomerLibrary {
23
+ static libName: string;
24
+ private monomerFields;
25
+ private library;
26
+ private monomers;
27
+ constructor(sdf: string);
28
+ /** getting full monomer information from monomer library
29
+ * @param {string} name
30
+ * @return {MonomerEntry}
31
+ */
32
+ getMonomerEntry(name: string): MonomerEntry;
33
+ /** getting mol as string for monomer
34
+ * @param {string} name
35
+ * @return {string}
36
+ */
37
+ getMonomerMol(name: string): string;
38
+ /** getting the list of the minomers available in library*/
39
+ get monomerNames(): string[];
40
+ static get id(): string;
41
+ private getLinkData;
42
+ }
43
+ //# sourceMappingURL=monomer-library.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monomer-library.d.ts","sourceRoot":"","sources":["monomer-library.ts"],"names":[],"mappings":"AAAA,oBAAY,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CACnE,CAAC;AACF,oBAAY,cAAc,GAAG;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAA;CAAE,CAAC;AAC9D,oBAAY,QAAQ,GAAG;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAEhF,2DAA2D;AAC3D,qBAAa,cAAc;IACzB,MAAM,CAAC,OAAO,SAAoB;IAElC,OAAO,CAAC,aAAa,CAEnB;IAEF,OAAO,CAAC,OAAO,CAAsB;IAErC,OAAO,CAAC,QAAQ,CAAgB;gBAEpB,GAAG,EAAE,MAAM;IA2BvB;;;OAGG;IACI,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAOlD;;;OAGG;IACI,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAiB1C,2DAA2D;IAC3D,IAAI,YAAY,IAAI,MAAM,EAAE,CAE3B;IAED,MAAM,KAAK,EAAE,IAAI,MAAM,CAEtB;IAED,OAAO,CAAC,WAAW;CAiCpB"}