@datagrok/helm 2.1.25 → 2.1.27

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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datagrok/helm",
3
3
  "friendlyName": "Helm",
4
- "version": "2.1.25",
4
+ "version": "2.1.27",
5
5
  "author": {
6
6
  "name": "Oleksandra Serhiienko",
7
7
  "email": "oserhiienko@datagrok.ai"
@@ -15,22 +15,23 @@
15
15
  "helm/JSDraw/Pistoia.HELM-uncompressed.js"
16
16
  ],
17
17
  "dependencies": {
18
- "@datagrok-libraries/bio": "^5.39.18",
18
+ "@datagrok-libraries/bio": "^5.39.24",
19
19
  "@datagrok-libraries/chem-meta": "^1.2.1",
20
- "@datagrok-libraries/utils": "^4.0.17",
20
+ "@datagrok-libraries/utils": "^4.1.42",
21
21
  "cash-dom": "^8.1.1",
22
- "datagrok-api": "^1.10.2",
22
+ "datagrok-api": "^1.17.0",
23
23
  "dayjs": "^1.10.6",
24
24
  "rxjs": "^6.5.5",
25
25
  "wu": "latest"
26
26
  },
27
27
  "devDependencies": {
28
+ "@types/node": "17.0.45",
28
29
  "@types/wu": "latest",
29
30
  "path": "^0.12.7",
30
31
  "source-map-loader": "^4.0.1",
31
32
  "ts-loader": "^9.2.6",
32
33
  "typescript": "^4.8.4",
33
- "webpack": "^5.59.1",
34
+ "webpack": "^5.76.3",
34
35
  "webpack-cli": "^4.9.1",
35
36
  "@typescript-eslint/eslint-plugin": "^5.11.0",
36
37
  "@typescript-eslint/parser": "^5.11.0",
@@ -144,36 +144,6 @@ function getHoveredMonomerFallback(
144
144
  return hoveredSeqMonomer;
145
145
  }
146
146
 
147
- // patch window.dojox.gfx.svg.Text.prototype.getTextWidth hangs
148
- /** get the text width in pixels */
149
- // @ts-ignore
150
- window.dojox.gfx.svg.Text.prototype.getTextWidth = function() {
151
- const rawNode = this.rawNode;
152
- const oldParent = rawNode.parentNode;
153
- const _measurementNode = rawNode.cloneNode(true);
154
- _measurementNode.style.visibility = 'hidden';
155
-
156
- // solution to the "orphan issue" in FF
157
- let _width = 0;
158
- const _text = _measurementNode.firstChild.nodeValue;
159
- oldParent.appendChild(_measurementNode);
160
-
161
- // solution to the "orphan issue" in Opera
162
- // (nodeValue == "" hangs firefox)
163
- if (_text != '') {
164
- let watchdogCounter = 100;
165
- while (!_width && --watchdogCounter > 0) { // <-- hangs
166
- //Yang: work around svgweb bug 417 -- http://code.google.com/p/svgweb/issues/detail?id=417
167
- if (_measurementNode.getBBox)
168
- _width = parseInt(_measurementNode.getBBox().width);
169
- else
170
- _width = 68;
171
- }
172
- }
173
- oldParent.removeChild(_measurementNode);
174
- return _width;
175
- };
176
-
177
147
  /** Helm cell renderer in case of no missed monomer draws with JSDraw2.Editor (webeditor),
178
148
  * in case of missed monomers presented, draws linear sequences aligned in width per monomer.
179
149
  */
@@ -0,0 +1,62 @@
1
+ import * as grok from 'datagrok-api/grok';
2
+ import * as ui from 'datagrok-api/ui';
3
+ import * as DG from 'datagrok-api/dg';
4
+
5
+ import {IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
6
+ import {IHelmWebEditor, IWebEditorApp} from '@datagrok-libraries/bio/src/helm/types';
7
+ import {HelmWebEditor} from './helm-web-editor';
8
+
9
+ type HelmHelperWindowType = Window & {
10
+ $helmHelper?: HelmHelper,
11
+ }
12
+ declare const window: HelmHelperWindowType;
13
+
14
+ export class HelmHelper implements IHelmHelper {
15
+ createHelmWebEditor(): IHelmWebEditor {
16
+ return new HelmWebEditor();
17
+ }
18
+
19
+ createWebEditorApp(host: HTMLDivElement, helm: string): IWebEditorApp {
20
+ // @ts-ignore
21
+ org.helm.webeditor.MolViewer.molscale = 0.8;
22
+ // @ts-ignore
23
+ const webEditorApp = new scil.helm.App(host, {
24
+ showabout: false,
25
+ mexfontsize: '90%',
26
+ mexrnapinontab: true,
27
+ topmargin: 20,
28
+ mexmonomerstab: true,
29
+ sequenceviewonly: false,
30
+ mexfavoritefirst: true,
31
+ mexfilter: true
32
+ }) as IWebEditorApp;
33
+ const sizes = webEditorApp.calculateSizes();
34
+ webEditorApp.canvas.resize(sizes.rightwidth - 100, sizes.topheight - 210);
35
+ let s = {width: sizes.rightwidth - 100 + 'px', height: sizes.bottomheight + 'px'};
36
+ //@ts-ignore
37
+ scil.apply(webEditorApp.sequence.style, s);
38
+ //@ts-ignore
39
+ scil.apply(webEditorApp.notation.style, s);
40
+ s = {width: sizes.rightwidth + 'px', height: (sizes.bottomheight + webEditorApp.toolbarheight) + 'px'};
41
+ //@ts-ignore
42
+ scil.apply(webEditorApp.properties.parent.style, s);
43
+ webEditorApp.structureview.resize(sizes.rightwidth, sizes.bottomheight + webEditorApp.toolbarheight);
44
+ webEditorApp.mex.resize(sizes.topheight - 80);
45
+ setTimeout(() => {
46
+ webEditorApp.canvas.helm.setSequence(helm, 'HELM');
47
+ }, 200);
48
+ return webEditorApp;
49
+ }
50
+
51
+ // -- Instance singleton --
52
+
53
+ public static async getInstance(): Promise<IHelmHelper> {
54
+ let res: HelmHelper = window.$helmHelper!;
55
+ if (!res) {
56
+ // create & init singleton
57
+ window.$helmHelper = res = new HelmHelper();
58
+ // await res.init();
59
+ }
60
+ return res;
61
+ }
62
+ }
@@ -2,7 +2,7 @@ import * as grok from 'datagrok-api/grok';
2
2
  import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
- import {IHelmWebEditor} from '@datagrok-libraries/bio/src/types/editor';
5
+ import {IHelmWebEditor} from '@datagrok-libraries/bio/src/helm/types';
6
6
 
7
7
  export class HelmWebEditor implements IHelmWebEditor {
8
8
  host: any;
@@ -18,38 +18,5 @@ export class HelmWebEditor implements IHelmWebEditor {
18
18
  resizeEditor(w: number, h: number) {
19
19
  this.editor.setSize(w, h);
20
20
  }
21
-
22
- createWebEditor(value: string) {
23
- const editorView = ui.div();
24
- // @ts-ignore
25
- org.helm.webeditor.MolViewer.molscale = 0.8;
26
- // @ts-ignore
27
- const webEditor = new scil.helm.App(editorView, {
28
- showabout: false,
29
- mexfontsize: '90%',
30
- mexrnapinontab: true,
31
- topmargin: 20,
32
- mexmonomerstab: true,
33
- sequenceviewonly: false,
34
- mexfavoritefirst: true,
35
- mexfilter: true
36
- });
37
- const sizes = webEditor.calculateSizes();
38
- webEditor.canvas.resize(sizes.rightwidth - 100, sizes.topheight - 210);
39
- let s = {width: sizes.rightwidth - 100 + 'px', height: sizes.bottomheight + 'px'};
40
- //@ts-ignore
41
- scil.apply(webEditor.sequence.style, s);
42
- //@ts-ignore
43
- scil.apply(webEditor.notation.style, s);
44
- s = {width: sizes.rightwidth + 'px', height: (sizes.bottomheight + webEditor.toolbarheight) + 'px'};
45
- //@ts-ignore
46
- scil.apply(webEditor.properties.parent.style, s);
47
- webEditor.structureview.resize(sizes.rightwidth, sizes.bottomheight + webEditor.toolbarheight);
48
- webEditor.mex.resize(sizes.topheight - 80);
49
- setTimeout(() => {
50
- webEditor.canvas.helm.setSequence(value, 'HELM');
51
- }, 200);
52
- return {editorDiv: editorView, webEditor: webEditor};
53
- }
54
21
  }
55
22
 
@@ -7,6 +7,7 @@ import './tests/helm-tests.ts';
7
7
  import './tests/findMonomers-tests';
8
8
  import './tests/renderers-tests';
9
9
  import './tests/get-molfiles';
10
+ import './tests/properties-widget-tests';
10
11
 
11
12
  export const _package = new DG.Package();
12
13
  export {tests};
package/src/package.ts CHANGED
@@ -3,14 +3,18 @@ import * as grok from 'datagrok-api/grok';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
  import * as DG from 'datagrok-api/dg';
5
5
 
6
+ import $ from 'cash-dom';
7
+
6
8
  import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
7
9
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
10
  import {GapSymbols, UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
9
11
  import {IMonomerLib, Monomer} from '@datagrok-libraries/bio/src/types';
12
+ import {IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
10
13
 
11
14
  import {findMonomers, parseHelm} from './utils';
12
- import {HelmWebEditor} from './helm-web-editor';
13
15
  import {HelmCellRenderer} from './cell-renderer';
16
+ import {HelmHelper} from './helm-helper';
17
+ import {getPropertiesWidget} from './widgets/properties-widget';
14
18
 
15
19
  let monomerLib: IMonomerLib | null = null;
16
20
 
@@ -18,6 +22,38 @@ import {WebEditorMonomer, RGROUP_CAP_GROUP_NAME, RGROUP_LABEL, SMILES} from './c
18
22
 
19
23
  export const _package = new DG.Package();
20
24
 
25
+ function initHelmPatchDojo(): void {
26
+ // patch window.dojox.gfx.svg.Text.prototype.getTextWidth hangs
27
+ /** get the text width in pixels */
28
+ // @ts-ignore
29
+ window.dojox.gfx.svg.Text.prototype.getTextWidth = function() {
30
+ const rawNode = this.rawNode;
31
+ const oldParent = rawNode.parentNode;
32
+ const _measurementNode = rawNode.cloneNode(true);
33
+ _measurementNode.style.visibility = 'hidden';
34
+
35
+ // solution to the "orphan issue" in FF
36
+ let _width = 0;
37
+ const _text = _measurementNode.firstChild.nodeValue;
38
+ oldParent.appendChild(_measurementNode);
39
+
40
+ // solution to the "orphan issue" in Opera
41
+ // (nodeValue == "" hangs firefox)
42
+ if (_text != '') {
43
+ let watchdogCounter = 100;
44
+ while (!_width && --watchdogCounter > 0) { // <-- hangs
45
+ //Yang: work around svgweb bug 417 -- http://code.google.com/p/svgweb/issues/detail?id=417
46
+ if (_measurementNode.getBBox)
47
+ _width = parseInt(_measurementNode.getBBox().width);
48
+ else
49
+ _width = 68;
50
+ }
51
+ }
52
+ oldParent.removeChild(_measurementNode);
53
+ return _width;
54
+ };
55
+ }
56
+
21
57
  //tags: init
22
58
  export async function initHelm(): Promise<void> {
23
59
  //@ts-ignore
@@ -27,6 +63,8 @@ export async function initHelm(): Promise<void> {
27
63
  new Promise((resolve, reject) => {
28
64
  // @ts-ignore
29
65
  dojo.ready(function() { resolve(null); });
66
+ }).then(() => {
67
+ initHelmPatchDojo();
30
68
  }),
31
69
  grok.functions.call('Bio:getBioLib'),
32
70
  ])
@@ -105,7 +143,7 @@ function rewriteLibraries() {
105
143
  });
106
144
 
107
145
  // Obsolete
108
- const grid: DG.Grid = grok.shell.tv.grid;
146
+ const grid: DG.Grid = grok.shell.tv?.grid;
109
147
  if (grid) grid.invalidate();
110
148
  }
111
149
 
@@ -159,29 +197,11 @@ export function openEditor(mol: string): void {
159
197
  }
160
198
 
161
199
  //name: Properties
162
- //tags: panel, widgets
163
- //input: string helmString {semType: Macromolecule}
200
+ //tags: panel, bio, helm, widgets
201
+ //input: semantic_value sequence {semType: Macromolecule}
164
202
  //output: widget result
165
- export async function propertiesPanel(helmString: string) {
166
- const grid = grok.shell.tv.grid;
167
- const parent = grid.root.parentElement!;
168
- const host = ui.div([]);
169
- parent.appendChild(host);
170
- const editor = new JSDraw2.Editor(host, {viewonly: true});
171
- host.style.width = '0px';
172
- host.style.height = '0px';
173
- editor.setHelm(helmString);
174
- const formula = editor.getFormula(true);
175
- const molWeight = Math.round(editor.getMolWeight() * 100) / 100;
176
- const coef = Math.round(editor.getExtinctionCoefficient(true) * 100) / 100;
177
- parent.lastChild!.remove();
178
- return new DG.Widget(
179
- ui.tableFromMap({
180
- 'formula': formula.replace(/<sub>/g, '').replace(/<\/sub>/g, ''),
181
- 'molecular weight': molWeight,
182
- 'extinction coefficient': coef,
183
- })
184
- );
203
+ export function propertiesWidget(sequence: DG.SemanticValue): DG.Widget {
204
+ return getPropertiesWidget(sequence);
185
205
  }
186
206
 
187
207
  function webEditor(cell?: DG.Cell, value?: string, units?: string) {
@@ -265,25 +285,28 @@ function getRS(smiles: string) {
265
285
  //input: column col {semType: Macromolecule}
266
286
  //output: column res
267
287
  export function getMolfiles(col: DG.Column): DG.Column {
268
- const grid = grok.shell.tv.grid;
269
- const parent = grid.root.parentElement!;
270
288
  const res = DG.Column.string('mols', col.length);
271
- const host = ui.div([]);
272
- parent.appendChild(host);
273
- const editor = new JSDraw2.Editor(host, {viewonly: true});
274
- host.style.width = '0px';
275
- host.style.height = '0px';
276
- res.init((i) => {
277
- editor.setHelm(col.get(i));
278
- const mol = editor.getMolfile();
279
- return mol;
280
- });
281
- parent.lastChild!.remove();
282
- return res;
289
+
290
+ const host = ui.div([], {style: {width: '0', height: '0'}});
291
+ document.documentElement.appendChild(host);
292
+ try {
293
+ const editor = new JSDraw2.Editor(host, {viewonly: true});
294
+ res.init((i) => {
295
+ editor.setHelm(col.get(i));
296
+ const mol = editor.getMolfile();
297
+ return mol;
298
+ });
299
+ return res;
300
+ } finally {
301
+ $(host).empty();
302
+ host.remove();
303
+ }
283
304
  }
284
305
 
285
- //name: helmWebEditor
306
+ // -- Utils --
307
+
308
+ //name: getHelmHelper
286
309
  //output: object result
287
- export function helmWebEditor(): HelmWebEditor {
288
- return new HelmWebEditor();
310
+ export async function getHelmHelper(): Promise<IHelmHelper> {
311
+ return HelmHelper.getInstance();
289
312
  }
@@ -0,0 +1,81 @@
1
+ import * as ui from 'datagrok-api/ui';
2
+ import * as DG from 'datagrok-api/dg';
3
+ import * as grok from 'datagrok-api/grok';
4
+
5
+ import {category, expect, expectObject, test} from '@datagrok-libraries/utils/src/test';
6
+ import {ALPHABET, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
7
+ import {UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
8
+
9
+ import {getPropertiesDict} from '../widgets/properties-widget';
10
+
11
+ const enum MolProps {
12
+ formula = 'formula',
13
+ mw = 'molecular weight',
14
+ extinctCoef = 'extinction coefficient',
15
+ }
16
+
17
+ const enum Tests {
18
+ helm = 'Helm',
19
+ separator = 'separator',
20
+ separator2 = 'separator2', // with a few gaps in a row
21
+ separatorGaps = 'separator-gaps',
22
+ fastaPt = 'fasta-PT',
23
+ fastaPtMsa = 'fasta-PT-MSA',
24
+ fastaDna = 'fasta-DNA',
25
+ }
26
+
27
+ const TestsData: {
28
+ [testName: string]: { seq: string, units: NOTATION, separator?: string, alphabet?: ALPHABET, res: {} }
29
+ } = {
30
+ [Tests.helm]: {
31
+ seq: 'PEPTIDE1{I.H.A.C.T.[Thr_PO3H2].[Aca].[D-Tyr_Et]}|PEPTIDE2{E.A.[meG]}$PEPTIDE1,PEPTIDE2,4:R3-1:R1$$$V2.0',
32
+ units: NOTATION.HELM,
33
+ res: {[MolProps.formula]: 'C58H94N13O21SP', [MolProps.mw]: 1372.48, [MolProps.extinctCoef]: 1.55}
34
+ },
35
+ [Tests.separator]: {
36
+ seq: 'I/H/A/C/T/Thr_PO3H2/Aca/D-Tyr_Et',
37
+ units: NOTATION.SEPARATOR, separator: '/', alphabet: ALPHABET.UN,
38
+ res: {[MolProps.formula]: 'C47H77N10O15SP', [MolProps.mw]: 1085.21, [MolProps.extinctCoef]: 1.55}
39
+ },
40
+ [Tests.separator2]: {
41
+ seq: 'meI/hHis/Aca/N/T/dK/Thr_PO3H2/Aca/D-Tyr_Et/Aze/dV/E/N////Phe_4Me',
42
+ units: NOTATION.SEPARATOR, separator: '/', alphabet: ALPHABET.UN,
43
+ res: {[MolProps.formula]: 'C91H146N19O25P', [MolProps.mw]: 1937.21, [MolProps.extinctCoef]: 1.49},
44
+ },
45
+ [Tests.separatorGaps]: {
46
+ seq: 'I/H/A//T/Thr_PO3H2/Aca/D-Tyr_Et',
47
+ units: NOTATION.SEPARATOR, separator: '/', alphabet: ALPHABET.UN,
48
+ res: {[MolProps.formula]: 'C44H72N9O14P', [MolProps.mw]: 982.07, [MolProps.extinctCoef]: 1.49},
49
+ },
50
+ [Tests.fastaPt]: {
51
+ seq: 'IHACTTAY',
52
+ units: NOTATION.FASTA, alphabet: ALPHABET.PT,
53
+ res: {[MolProps.formula]: 'C38H58N10O12S', [MolProps.mw]: 878.99, [MolProps.extinctCoef]: 1.55}
54
+ },
55
+ [Tests.fastaDna]: {
56
+ seq: 'ACGTATTCC',
57
+ units: NOTATION.FASTA, alphabet: ALPHABET.DNA,
58
+ res: {[MolProps.formula]: 'C87H113N30O56P9', [MolProps.mw]: 2753.76, [MolProps.extinctCoef]: 91.74}
59
+ }
60
+ };
61
+
62
+ category('properties-widget', () => {
63
+ for (const [testName, testData] of Object.entries(TestsData)) {
64
+ test(testName, async () => {
65
+ testPropertiesDict(testData.seq, testData.units, testData.separator, testData.alphabet, testData.res);
66
+ });
67
+ }
68
+ });
69
+
70
+ function testPropertiesDict(
71
+ seq: string, units: NOTATION, separator: string | undefined, alphabet: ALPHABET | undefined, expPropDict: {}
72
+ ) {
73
+ const col = DG.Column.fromList(DG.COLUMN_TYPE.STRING, 'seq', [seq]);
74
+ col.semType = DG.SEMTYPE.MACROMOLECULE;
75
+ col.setTag(DG.TAGS.UNITS, units);
76
+ if (separator) col.setTag(bioTAGS.separator, separator);
77
+ if (alphabet) col.setTag(bioTAGS.alphabet, alphabet);
78
+ const uh = UnitsHandler.getOrCreate(col);
79
+ const actPropDict = getPropertiesDict(seq, uh);
80
+ expectObject(actPropDict, expPropDict);
81
+ }
@@ -0,0 +1,43 @@
1
+ import * as grok from 'datagrok-api/grok';
2
+ import * as ui from 'datagrok-api/ui';
3
+ import * as DG from 'datagrok-api/dg';
4
+
5
+ import $ from 'cash-dom';
6
+
7
+ import {UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
8
+ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
9
+
10
+ export function getPropertiesDict(seq: string, uh: UnitsHandler): {} {
11
+ const helmString = uh.isHelm() ? seq : uh.getConverter(NOTATION.HELM)(seq);
12
+ // Remove gap symbols for compatibility with WebEditor
13
+ const helmString2 = helmString.replaceAll(/\.(\*\.)+/g, '.')
14
+ .replaceAll(/\{(\*\.)+/g, '{').replaceAll(/(\.\*)+}/g, '}');
15
+
16
+ const host = ui.div([], {style: {width: '0', height: '0'}});
17
+ document.documentElement.appendChild(host);
18
+ try {
19
+ const editor = new JSDraw2.Editor(host, {viewonly: true});
20
+ editor.setHelm(helmString2);
21
+
22
+ const formula = editor.getFormula(true);
23
+ const molWeight = Math.round(editor.getMolWeight() * 100) / 100;
24
+ const coef = Math.round(editor.getExtinctionCoefficient(true) * 100) / 100;
25
+ return {
26
+ 'formula': formula.replace(/<sub>/g, '').replace(/<\/sub>/g, ''),
27
+ 'molecular weight': molWeight,
28
+ 'extinction coefficient': coef,
29
+ };
30
+ } finally {
31
+ $(host).empty();
32
+ host.remove();
33
+ }
34
+ }
35
+
36
+
37
+ export function getPropertiesWidget(value: DG.SemanticValue): DG.Widget {
38
+ const uh = UnitsHandler.getOrCreate(value.cell.column);
39
+ const propDict = getPropertiesDict(value.value, uh);
40
+ return new DG.Widget(
41
+ ui.tableFromMap(propDict)
42
+ );
43
+ }
package/tsconfig.json CHANGED
@@ -4,9 +4,9 @@
4
4
 
5
5
  /* Basic Options */
6
6
  // "incremental": true, /* Enable incremental compilation */
7
- "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
7
+ "target": "es2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
8
8
  "module": "es2020", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
9
- "lib": ["ES2022", "dom"], /* Specify library files to be included in the compilation. */
9
+ "lib": ["ES2022", "ES2022.String", "dom"], /* Specify library files to be included in the compilation. */
10
10
  "allowJs": true, /* Allow javascript files to be compiled. */
11
11
  // "checkJs": true, /* Report errors in .js files. */
12
12
  // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
@@ -61,11 +61,12 @@
61
61
  // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
62
62
 
63
63
  /* Experimental Options */
64
- // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
65
- // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
64
+ "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
65
+ "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
66
66
 
67
67
  /* Advanced Options */
68
68
  "skipLibCheck": false, /* Skip type checking of declaration files. */
69
- "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
69
+ "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
70
+ //"jsx": "react"
70
71
  }
71
72
  }