summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/trace_viewer/.gitignore6
-rw-r--r--src/trace_viewer/List-add.svg56
-rw-r--r--src/trace_viewer/List-remove.svg56
-rw-r--r--src/trace_viewer/README11
-rw-r--r--src/trace_viewer/index.css86
-rw-r--r--src/trace_viewer/index.html19
-rw-r--r--src/trace_viewer/index.ts287
-rw-r--r--src/trace_viewer/main.ts12
-rw-r--r--src/trace_viewer/package.json15
-rw-r--r--src/trace_viewer/tsconfig.json18
10 files changed, 566 insertions, 0 deletions
diff --git a/src/trace_viewer/.gitignore b/src/trace_viewer/.gitignore
new file mode 100644
index 00000000..c1f9aea6
--- /dev/null
+++ b/src/trace_viewer/.gitignore
@@ -0,0 +1,6 @@
+*~
+*.js
+*.js.map
+
+# Dependencies
+node_modules/
diff --git a/src/trace_viewer/List-add.svg b/src/trace_viewer/List-add.svg
new file mode 100644
index 00000000..f8031599
--- /dev/null
+++ b/src/trace_viewer/List-add.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg id="svg6431" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" sodipodi:docname="list-add.svg" xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" height="48px" sodipodi:version="0.32" width="48px" xmlns:cc="http://web.resource.org/cc/" xmlns:xlink="http://www.w3.org/1999/xlink" sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions" xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <defs id="defs6433">
+ <linearGradient id="linearGradient4975" y2="48.548" gradientUnits="userSpaceOnUse" x2="45.919" gradientTransform="translate(-18.018 -13.571)" y1="36.423" x1="34.893">
+ <stop id="stop1324" stop-color="#729fcf" offset="0"/>
+ <stop id="stop1326" stop-color="#5187d6" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient7922" y2="34.977" gradientUnits="userSpaceOnUse" x2="27.901" y1="22.852" x1="16.875">
+ <stop id="stop7918" stop-color="#fff" offset="0"/>
+ <stop id="stop7920" stop-color="#fff" stop-opacity=".34021" offset="1"/>
+ </linearGradient>
+ <radialGradient id="radialGradient2097" gradientUnits="userSpaceOnUse" cy="35.127" cx="23.071" gradientTransform="matrix(.91481 .012650 -.0082150 .21356 2.2539 27.189)" r="10.319">
+ <stop id="stop2093" offset="0"/>
+ <stop id="stop2095" stop-opacity="0" offset="1"/>
+ </radialGradient>
+ </defs>
+ <sodipodi:namedview id="base" bordercolor="#666666" pagecolor="#ffffff" showgrid="false" borderopacity="0.15686275" showguides="true"/>
+ <metadata id="metadata6436">
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title>Add</dc:title>
+ <dc:date>2006-01-04</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Andreas Nilsson</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://tango-project.org</dc:source>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>add</rdf:li>
+ <rdf:li>plus</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/"/>
+ </cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
+ <cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
+ <cc:requires rdf:resource="http://web.resource.org/cc/Notice"/>
+ <cc:requires rdf:resource="http://web.resource.org/cc/Attribution"/>
+ <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
+ <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike"/>
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g id="layer1">
+ <path id="path1361" sodipodi:rx="10.319340" sodipodi:ry="2.3201940" sodipodi:type="arc" d="m33.278 34.941a10.319 2.3202 0 1 1 -20.638 0 10.319 2.3202 0 1 1 20.638 0z" opacity=".2" transform="matrix(1.5505 0 0 1.293 -11.597 -8.1782)" sodipodi:cy="34.940620" sodipodi:cx="22.958872" fill="url(#radialGradient2097)"/>
+ <path id="text1314" d="m27.514 37.543v-9.027l9.979-0.04v-6.996h-9.97l-0.009-9.96-7.016 0.011 0.005 9.931-9.99 0.074-0.036 6.969 10.034-0.029 0.007 9.04 6.996 0.027z" sodipodi:nodetypes="ccccccccccccc" stroke="#3465a4" stroke-width="1px" fill="#75a1d0"/>
+ <path id="path7076" opacity=".40860" d="m26.499 36.534v-9.034h10.002l-0.006-5.025h-9.987v-9.995l-4.995 0.018 0.009 9.977-10.026 0.018-0.027 4.973 10.064 0.009-0.013 9.028 4.979 0.031z" sodipodi:nodetypes="ccccccccccccc" stroke="url(#linearGradient7922)" stroke-width="1px" fill="url(#linearGradient4975)"/>
+ <path id="path7914" opacity=".31183" d="m11 25c0 1.938 25.984-0.969 25.984-0.031v-3l-9.984 0.031v-9.965h-6v9.965h-10v3z" fill-rule="evenodd" sodipodi:nodetypes="ccccccccc" fill="#fff"/>
+ </g>
+</svg>
diff --git a/src/trace_viewer/List-remove.svg b/src/trace_viewer/List-remove.svg
new file mode 100644
index 00000000..f8031599
--- /dev/null
+++ b/src/trace_viewer/List-remove.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg id="svg6431" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" sodipodi:docname="list-add.svg" xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" height="48px" sodipodi:version="0.32" width="48px" xmlns:cc="http://web.resource.org/cc/" xmlns:xlink="http://www.w3.org/1999/xlink" sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions" xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <defs id="defs6433">
+ <linearGradient id="linearGradient4975" y2="48.548" gradientUnits="userSpaceOnUse" x2="45.919" gradientTransform="translate(-18.018 -13.571)" y1="36.423" x1="34.893">
+ <stop id="stop1324" stop-color="#729fcf" offset="0"/>
+ <stop id="stop1326" stop-color="#5187d6" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient7922" y2="34.977" gradientUnits="userSpaceOnUse" x2="27.901" y1="22.852" x1="16.875">
+ <stop id="stop7918" stop-color="#fff" offset="0"/>
+ <stop id="stop7920" stop-color="#fff" stop-opacity=".34021" offset="1"/>
+ </linearGradient>
+ <radialGradient id="radialGradient2097" gradientUnits="userSpaceOnUse" cy="35.127" cx="23.071" gradientTransform="matrix(.91481 .012650 -.0082150 .21356 2.2539 27.189)" r="10.319">
+ <stop id="stop2093" offset="0"/>
+ <stop id="stop2095" stop-opacity="0" offset="1"/>
+ </radialGradient>
+ </defs>
+ <sodipodi:namedview id="base" bordercolor="#666666" pagecolor="#ffffff" showgrid="false" borderopacity="0.15686275" showguides="true"/>
+ <metadata id="metadata6436">
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title>Add</dc:title>
+ <dc:date>2006-01-04</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Andreas Nilsson</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://tango-project.org</dc:source>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>add</rdf:li>
+ <rdf:li>plus</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/"/>
+ </cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
+ <cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
+ <cc:requires rdf:resource="http://web.resource.org/cc/Notice"/>
+ <cc:requires rdf:resource="http://web.resource.org/cc/Attribution"/>
+ <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
+ <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike"/>
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g id="layer1">
+ <path id="path1361" sodipodi:rx="10.319340" sodipodi:ry="2.3201940" sodipodi:type="arc" d="m33.278 34.941a10.319 2.3202 0 1 1 -20.638 0 10.319 2.3202 0 1 1 20.638 0z" opacity=".2" transform="matrix(1.5505 0 0 1.293 -11.597 -8.1782)" sodipodi:cy="34.940620" sodipodi:cx="22.958872" fill="url(#radialGradient2097)"/>
+ <path id="text1314" d="m27.514 37.543v-9.027l9.979-0.04v-6.996h-9.97l-0.009-9.96-7.016 0.011 0.005 9.931-9.99 0.074-0.036 6.969 10.034-0.029 0.007 9.04 6.996 0.027z" sodipodi:nodetypes="ccccccccccccc" stroke="#3465a4" stroke-width="1px" fill="#75a1d0"/>
+ <path id="path7076" opacity=".40860" d="m26.499 36.534v-9.034h10.002l-0.006-5.025h-9.987v-9.995l-4.995 0.018 0.009 9.977-10.026 0.018-0.027 4.973 10.064 0.009-0.013 9.028 4.979 0.031z" sodipodi:nodetypes="ccccccccccccc" stroke="url(#linearGradient7922)" stroke-width="1px" fill="url(#linearGradient4975)"/>
+ <path id="path7914" opacity=".31183" d="m11 25c0 1.938 25.984-0.969 25.984-0.031v-3l-9.984 0.031v-9.965h-6v9.965h-10v3z" fill-rule="evenodd" sodipodi:nodetypes="ccccccccc" fill="#fff"/>
+ </g>
+</svg>
diff --git a/src/trace_viewer/README b/src/trace_viewer/README
new file mode 100644
index 00000000..547a1435
--- /dev/null
+++ b/src/trace_viewer/README
@@ -0,0 +1,11 @@
+
+To use, first make sure node.js and npm are installed (e.g. via the
+Ubuntu package manager), then run the following in this directory:
+
+> npm install
+
+> npm run tsc
+
+> ./node_modules/.bin/electron .
+
+and point the file selector at a trace produced by sail -ocaml_trace \ No newline at end of file
diff --git a/src/trace_viewer/index.css b/src/trace_viewer/index.css
new file mode 100644
index 00000000..35ebcb23
--- /dev/null
+++ b/src/trace_viewer/index.css
@@ -0,0 +1,86 @@
+
+body {
+ background-color: #202020;
+ color: #DCDCCC;
+ font-family: monospace;
+ font-size: 14pt;
+ font-weight: bold;
+}
+
+img {
+ height: 30px;
+}
+
+#control {
+ position: fixed;
+ bottom: 0px;
+ left:10%;
+ right:10%;
+ width:80%;
+}
+
+#command {
+ font-size: 16pt;
+ width: 100%;
+}
+
+.call {
+ background-color: #313131;
+ border: 1px;
+ border-left: 5px;
+ border-color: rgb(118, 173, 160);
+ border-style: solid;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ margin: 0px;
+ min-height: 32px;
+ display: flex;
+ align-items: center;
+}
+
+.write {
+ background-color: #313131;
+ border: 1px;
+ border-left: 5px;
+ border-color: rgb(255, 40, 40);
+ border-style: solid;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ margin: 0px;
+ min-height: 32px;
+ display: flex;
+ align-items: center;
+}
+
+.load {
+ background-color: #313131;
+ color: white;
+ border: 1px;
+ border-left: 5px;
+ border-color: #ff9100;
+ border-style: solid;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ margin: 0px;
+ min-height: 32px;
+ display: flex;
+ align-items: center;
+}
+
+.read {
+ background-color: #313131;
+ border: 1px;
+ border-left: 5px;
+ border-color: rgb(107, 199, 47);
+ border-style: solid;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ margin: 0px;
+ min-height: 32px;
+ display: flex;
+ align-items: center;
+}
+
+.tree {
+ padding-left: 20px;
+} \ No newline at end of file
diff --git a/src/trace_viewer/index.html b/src/trace_viewer/index.html
new file mode 100644
index 00000000..75c5e035
--- /dev/null
+++ b/src/trace_viewer/index.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <title>Sail Log Viewer</title>
+ <script type="text/javascript">
+ var exports = {}
+ </script>
+ <script type="text/javascript" src="index.js"></script>
+ <link rel="stylesheet" type="text/css" href="index.css">
+ </head>
+ <body>
+ <div id="container">
+ </div>
+ <div id="control">
+ <input type="text" id="command">
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/src/trace_viewer/index.ts b/src/trace_viewer/index.ts
new file mode 100644
index 00000000..f9b5041b
--- /dev/null
+++ b/src/trace_viewer/index.ts
@@ -0,0 +1,287 @@
+import {remote} from "electron"
+import fs = require("fs")
+const dialog = remote.dialog
+const app = remote.app
+
+let topCallDiv = document.createElement("div")
+
+const max_arg_length = 5000
+
+abstract class Event {
+ caller: Call
+
+ protected div: HTMLDivElement | null = null
+
+ public hide(): void {
+ if (this.div != null) {
+ this.div.remove()
+ this.div = null
+ }
+ }
+
+ protected abstract showText(text: HTMLParagraphElement): void
+
+ public show(): HTMLDivElement {
+ let callerDiv: HTMLDivElement = (this.caller != null) ? this.caller.show() : topCallDiv
+
+ if (this.div != null) {
+ return this.div
+ } else {
+ this.div = document.createElement("div")
+ this.div.className = "tree"
+ callerDiv.appendChild(this.div)
+ let text = document.createElement("p")
+ this.showText(text)
+ this.div.appendChild(text)
+ return this.div
+ }
+ }
+}
+
+class Load extends Event {
+ loc: string
+ val: string
+
+ constructor(loc: string, val: string) {
+ super()
+ this.loc = loc
+ this.val = val
+ }
+
+ protected showText(text: HTMLParagraphElement): void {
+ text.className = "load"
+ text.insertAdjacentText('beforeend', this.loc + " " + this.val)
+ }
+}
+
+class Read extends Event {
+ reg: string
+ value: string
+
+ constructor(reg: string, value: string) {
+ super()
+ this.reg = reg
+ this.value = value
+ }
+
+ public showText(text: HTMLParagraphElement): void {
+ text.className = "read"
+ text.insertAdjacentText('beforeend', this.reg + " " + this.value)
+ }
+}
+
+class Write extends Event {
+ reg: string
+ value: string
+
+ constructor(reg: string, value: string) {
+ super()
+ this.reg = reg
+ this.value = value
+ }
+
+ public showText(text: HTMLParagraphElement): void {
+ text.className = "write"
+ text.insertAdjacentText('beforeend', this.reg + " " + this.value)
+ }
+}
+
+class Call {
+ fn: string
+ arg: string
+ ret: string
+ callees: (Call | Event)[] = []
+ caller: Call
+
+ private div: HTMLDivElement | null = null
+
+ private toggle: boolean = false
+ private toggleImg: HTMLImageElement | null = null
+
+ constructor(fn: string, arg: string, ret: string) {
+ this.fn = fn
+ this.arg = arg
+ this.ret = ret
+ }
+
+ public expand() {
+ if (this.caller != undefined) {
+ this.caller.expand()
+ }
+ this.showChildren()
+ }
+
+ public iter(f: (call: Call) => void): void {
+ f(this)
+ this.callees.forEach((callee) => {
+ if (callee instanceof Call) { callee.iter(f) }
+ })
+
+ }
+
+ public show(): HTMLDivElement {
+ let callerDiv: HTMLDivElement = (this.caller != null) ? this.caller.show() : topCallDiv
+
+ if (this.div != null) {
+ return this.div
+ } else {
+ this.div = document.createElement("div")
+ this.div.className = "tree"
+ callerDiv.appendChild(this.div)
+ let text = document.createElement("p")
+ text.className = "call"
+ if (this.callees.length > 0) {
+ this.toggleImg = document.createElement("img")
+ this.toggleImg.src = "List-add.svg"
+ this.toggleImg.addEventListener('click', () => {
+ if (this.toggle) {
+ this.hideChildren()
+ } else {
+ this.showChildren()
+ }
+ })
+ text.appendChild(this.toggleImg)
+ }
+ this.toggle = false
+ let display_arg = this.arg
+ if (this.arg.length > max_arg_length) {
+ display_arg = this.arg.slice(0, max_arg_length)
+ }
+ let display_ret = this.ret
+ if (this.ret.length > max_arg_length) {
+ display_ret = this.ret.slice(0, max_arg_length)
+ }
+
+ text.insertAdjacentText('beforeend', this.fn + " " + display_arg + " -> " + display_ret)
+ this.div.appendChild(text)
+ return this.div
+ }
+ }
+
+ public hide(): void {
+ if (this.toggle == true) {
+ this.hideChildren()
+ }
+
+ if (this.div != null) {
+ this.div.remove()
+ this.div = null
+ }
+ if (this.toggleImg != null) {
+ this.toggleImg.remove()
+ this.toggleImg = null
+ }
+ }
+
+ public hideChildren(): void {
+ this.callees.forEach(call => {
+ call.hide()
+ })
+
+ if (this.toggleImg != null) {
+ this.toggleImg.src = "List-add.svg"
+ this.toggle = false
+ } else {
+ alert("this.toggleImg was null!")
+ }
+ }
+
+ public showChildren(): void {
+ this.callees.forEach(call => {
+ call.show()
+ });
+
+ if (this.toggleImg != null) {
+ this.toggleImg.src = "List-remove.svg"
+ this.toggle = true
+ } else {
+ alert("this.toggleImg was null!")
+ }
+ }
+
+ public appendChild(child: Call | Write | Read | Load): void {
+ child.caller = this
+
+ this.callees.push(child)
+ }
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+ let rootCall = new Call("ROOT", "", "")
+ topCallDiv.id = "root"
+ document.getElementById("container")!.appendChild(topCallDiv)
+
+ let commandInput = document.getElementById("command") as HTMLInputElement
+
+ commandInput.addEventListener("keydown", (event) => {
+ if(event.keyCode == 13) {
+ let cmd = commandInput.value.split(" ")
+ commandInput.value = ""
+
+ if (cmd[0] == "function") {
+ rootCall.iter((call) => {
+ if (call.fn == cmd[1]) { call.caller.expand() }
+ })
+ }
+ }
+ })
+
+ let files = dialog.showOpenDialog(remote.getCurrentWindow(), {title: "Select log file", defaultPath: app.getAppPath()})
+
+ if (files == [] || files == undefined) {
+ dialog.showErrorBox("Error", "No file selected")
+ app.exit(1)
+ }
+
+ fs.readFile(files[0], 'utf-8', (err, data) => {
+ if (err) {
+ dialog.showErrorBox("Error", "An error occurred when reading the log: " + err.message)
+ app.exit(1)
+ }
+
+ let lines = data.split("\n")
+ // let indents = lines.map(line => line.search(/[^\s]/) / 2)
+ lines = lines.map(line => line.trim())
+
+ let stack : Call[] = [rootCall]
+
+ lines.forEach(line => {
+ if (line.match(/^Call:/)) {
+ let words = line.slice(6).split(" ")
+ let call = new Call(words[0], words.slice(1).join(" "), "")
+ if (stack.length > 0) {
+ stack[stack.length - 1].appendChild(call)
+ }
+ stack.push(call)
+ } else if (line.match(/^Return:/)) {
+ let call = stack.pop()
+ if (call == undefined) {
+ alert("Unbalanced return")
+ app.exit(1)
+ } else {
+ call.ret = line.slice(8)
+ }
+ } else if (line.match(/^Write:/)) {
+ let words = line.slice(7).split(" ")
+ let write = new Write(words[0], words.slice(1).join(" "))
+ if (stack.length > 0) {
+ stack[stack.length - 1].appendChild(write)
+ }
+ } else if (line.match(/^Read:/)) {
+ let words = line.slice(6).split(" ")
+ let read = new Read(words[0], words.slice(1).join(" "))
+ if (stack.length > 0) {
+ stack[stack.length - 1].appendChild(read)
+ }
+ } else if (line.match(/^Load:/)) {
+ let words = line.slice(6).split(" ")
+ let load = new Load(words[0], words[1])
+ if (stack.length > 0) {
+ stack[stack.length - 1].appendChild(load)
+ }
+ }
+ })
+
+ rootCall.show()
+ })
+}) \ No newline at end of file
diff --git a/src/trace_viewer/main.ts b/src/trace_viewer/main.ts
new file mode 100644
index 00000000..5cc33452
--- /dev/null
+++ b/src/trace_viewer/main.ts
@@ -0,0 +1,12 @@
+import {app, BrowserWindow} from 'electron'
+
+let win : BrowserWindow | null = null
+
+app.on('ready', () => {
+ win = new BrowserWindow({width: 1920, height: 1200})
+ win.loadURL('file://' + __dirname + '/index.html')
+ //win.webContents.openDevTools()
+ win.on('close', () => {
+ win = null
+ })
+}) \ No newline at end of file
diff --git a/src/trace_viewer/package.json b/src/trace_viewer/package.json
new file mode 100644
index 00000000..e3a88d30
--- /dev/null
+++ b/src/trace_viewer/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "trace_viewer",
+ "version": "1.0.0",
+ "description": "",
+ "main": "main.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "tsc": "./node_modules/typescript/bin/tsc"
+ },
+ "devDependencies": {
+ "@types/node": "^8.0.46",
+ "electron": "1.7.9",
+ "typescript": "^2.5.3"
+ }
+}
diff --git a/src/trace_viewer/tsconfig.json b/src/trace_viewer/tsconfig.json
new file mode 100644
index 00000000..e66156b3
--- /dev/null
+++ b/src/trace_viewer/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "compileOnSave": true,
+ "compilerOptions": {
+ "target": "es5",
+ "moduleResolution": "node",
+ "pretty": true,
+ "newLine": "LF",
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "sourceMap": true,
+ "strictNullChecks": true,
+ "skipLibCheck": true,
+ "allowJs": true,
+ "jsx": "preserve"
+ }
+} \ No newline at end of file