Alex Dima 4 年 前
コミット
d089cc232d
19 ファイル変更2441 行追加2045 行削除
  1. 1 1
      .vscode/settings.json
  2. 21 21
      LICENSE.md
  3. 33 31
      README.md
  4. 786 786
      package-lock.json
  5. 39 34
      package.json
  6. 71 45
      scripts/bundle.js
  7. 4 10
      scripts/release.js
  8. 9 5
      src/fillers/vscode-nls.ts
  9. 1 1
      src/html.worker.ts
  10. 195 114
      src/htmlMode.ts
  11. 151 96
      src/htmlWorker.ts
  12. 768 576
      src/languageFeatures.ts
  13. 156 133
      src/monaco.contribution.ts
  14. 6 3
      src/monaco.d.ts
  15. 13 13
      src/tsconfig.esm.json
  16. 13 13
      src/tsconfig.json
  17. 1 1
      src/typings/refs.d.ts
  18. 92 89
      src/workerManager.ts
  19. 81 73
      test/index.html

+ 1 - 1
.vscode/settings.json

@@ -6,4 +6,4 @@
 		"**/release": true,
 		"**/out": true
 	}
-}
+}

+ 21 - 21
LICENSE.md

@@ -1,21 +1,21 @@
-The MIT License (MIT)
-
-Copyright (c) Microsoft Corporation
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 33 - 31
README.md

@@ -1,31 +1,33 @@
-# Monaco HTML
-
-HTML language plugin for the Monaco Editor. It provides the following features when editing HTML files:
-* Code completion
-* Formatting
-* Document Highlights
-* Link detection
-* Syntax highlighting
-
-Internally the HTML plugin uses the [vscode-html-languageservice](https://github.com/Microsoft/vscode-html-languageservice)
-node module, providing the implementation of the functionally listed above. The same module is also used
-in [Visual Studio Code](https://github.com/Microsoft/vscode) to power the HTML editing experience.
-
-## Issues
-
-Please file issues concering `monaco-html` in the [`monaco-editor` repository](https://github.com/Microsoft/monaco-editor/issues).
-
-## Installing
-
-This npm module is bundled and distributed in the [monaco-editor](https://www.npmjs.com/package/monaco-editor) npm module.
-
-## Development
-
-* `git clone https://github.com/Microsoft/monaco-html`
-* `cd monaco-html`
-* `npm install .`
-* `npm run watch`
-* open `$/monaco-html/test/index.html` in your favorite browser.
-
-## License
-[MIT](https://github.com/Microsoft/monaco-html/blob/master/LICENSE.md)
+# Monaco HTML
+
+HTML language plugin for the Monaco Editor. It provides the following features when editing HTML files:
+
+- Code completion
+- Formatting
+- Document Highlights
+- Link detection
+- Syntax highlighting
+
+Internally the HTML plugin uses the [vscode-html-languageservice](https://github.com/Microsoft/vscode-html-languageservice)
+node module, providing the implementation of the functionally listed above. The same module is also used
+in [Visual Studio Code](https://github.com/Microsoft/vscode) to power the HTML editing experience.
+
+## Issues
+
+Please file issues concering `monaco-html` in the [`monaco-editor` repository](https://github.com/Microsoft/monaco-editor/issues).
+
+## Installing
+
+This npm module is bundled and distributed in the [monaco-editor](https://www.npmjs.com/package/monaco-editor) npm module.
+
+## Development
+
+- `git clone https://github.com/Microsoft/monaco-html`
+- `cd monaco-html`
+- `npm install .`
+- `npm run watch`
+- open `$/monaco-html/test/index.html` in your favorite browser.
+
+## License
+
+[MIT](https://github.com/Microsoft/monaco-html/blob/master/LICENSE.md)

+ 786 - 786
package-lock.json

@@ -1,788 +1,788 @@
 {
-  "name": "monaco-html",
-  "version": "2.7.0",
-  "lockfileVersion": 1,
-  "requires": true,
-  "dependencies": {
-    "@babel/code-frame": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
-      "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
-      "dev": true,
-      "requires": {
-        "@babel/highlight": "^7.10.4"
-      }
-    },
-    "@babel/helper-validator-identifier": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
-      "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
-      "dev": true
-    },
-    "@babel/highlight": {
-      "version": "7.10.4",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
-      "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-validator-identifier": "^7.10.4",
-        "chalk": "^2.0.0",
-        "js-tokens": "^4.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "color-convert": {
-          "version": "1.9.3",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        }
-      }
-    },
-    "@types/color-name": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
-      "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
-      "dev": true
-    },
-    "@types/minimatch": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
-      "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
-      "dev": true
-    },
-    "@types/parse-json": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
-      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
-      "dev": true
-    },
-    "ansi-styles": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
-      "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
-      "dev": true,
-      "requires": {
-        "@types/color-name": "^1.1.1",
-        "color-convert": "^2.0.1"
-      }
-    },
-    "array-differ": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
-      "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
-      "dev": true
-    },
-    "array-union": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
-      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
-      "dev": true
-    },
-    "arrify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
-      "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
-      "dev": true
-    },
-    "balanced-match": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-      "dev": true
-    },
-    "brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "dev": true,
-      "requires": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "buffer-from": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
-      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
-      "dev": true
-    },
-    "callsites": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
-      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
-      "dev": true
-    },
-    "chalk": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
-      "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
-      "dev": true,
-      "requires": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      }
-    },
-    "ci-info": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
-      "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
-      "dev": true
-    },
-    "color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "requires": {
-        "color-name": "~1.1.4"
-      }
-    },
-    "color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true
-    },
-    "commander": {
-      "version": "2.20.3",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
-      "dev": true
-    },
-    "compare-versions": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz",
-      "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==",
-      "dev": true
-    },
-    "concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-      "dev": true
-    },
-    "cosmiconfig": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
-      "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==",
-      "dev": true,
-      "requires": {
-        "@types/parse-json": "^4.0.0",
-        "import-fresh": "^3.2.1",
-        "parse-json": "^5.0.0",
-        "path-type": "^4.0.0",
-        "yaml": "^1.10.0"
-      }
-    },
-    "cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-      "dev": true,
-      "requires": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
-      }
-    },
-    "end-of-stream": {
-      "version": "1.4.4",
-      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
-      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
-      "dev": true,
-      "requires": {
-        "once": "^1.4.0"
-      }
-    },
-    "error-ex": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
-      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
-      "dev": true,
-      "requires": {
-        "is-arrayish": "^0.2.1"
-      }
-    },
-    "escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-      "dev": true
-    },
-    "execa": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz",
-      "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==",
-      "dev": true,
-      "requires": {
-        "cross-spawn": "^7.0.0",
-        "get-stream": "^5.0.0",
-        "human-signals": "^1.1.1",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.0",
-        "onetime": "^5.1.0",
-        "signal-exit": "^3.0.2",
-        "strip-final-newline": "^2.0.0"
-      }
-    },
-    "find-up": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
-      "dev": true,
-      "requires": {
-        "locate-path": "^5.0.0",
-        "path-exists": "^4.0.0"
-      }
-    },
-    "find-versions": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
-      "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==",
-      "dev": true,
-      "requires": {
-        "semver-regex": "^2.0.0"
-      }
-    },
-    "get-stream": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
-      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
-      "dev": true,
-      "requires": {
-        "pump": "^3.0.0"
-      }
-    },
-    "has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true
-    },
-    "human-signals": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
-      "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
-      "dev": true
-    },
-    "husky": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.0.tgz",
-      "integrity": "sha512-tTMeLCLqSBqnflBZnlVDhpaIMucSGaYyX6855jM4AguGeWCeSzNdb1mfyWduTZ3pe3SJVvVWGL0jO1iKZVPfTA==",
-      "dev": true,
-      "requires": {
-        "chalk": "^4.0.0",
-        "ci-info": "^2.0.0",
-        "compare-versions": "^3.6.0",
-        "cosmiconfig": "^7.0.0",
-        "find-versions": "^3.2.0",
-        "opencollective-postinstall": "^2.0.2",
-        "pkg-dir": "^4.2.0",
-        "please-upgrade-node": "^3.2.0",
-        "slash": "^3.0.0",
-        "which-pm-runs": "^1.0.0"
-      }
-    },
-    "ignore": {
-      "version": "5.1.8",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
-      "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
-      "dev": true
-    },
-    "import-fresh": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
-      "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
-      "dev": true,
-      "requires": {
-        "parent-module": "^1.0.0",
-        "resolve-from": "^4.0.0"
-      }
-    },
-    "is-arrayish": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
-      "dev": true
-    },
-    "is-stream": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
-      "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
-      "dev": true
-    },
-    "isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-      "dev": true
-    },
-    "js-tokens": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true
-    },
-    "json-parse-even-better-errors": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
-      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
-      "dev": true
-    },
-    "lines-and-columns": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
-      "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
-      "dev": true
-    },
-    "locate-path": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
-      "dev": true,
-      "requires": {
-        "p-locate": "^4.1.0"
-      }
-    },
-    "merge-stream": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
-      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
-      "dev": true
-    },
-    "mimic-fn": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
-      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "dev": true
-    },
-    "minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-      "dev": true,
-      "requires": {
-        "brace-expansion": "^1.1.7"
-      }
-    },
-    "monaco-editor-core": {
-      "version": "0.20.0",
-      "resolved": "https://registry.npmjs.org/monaco-editor-core/-/monaco-editor-core-0.20.0.tgz",
-      "integrity": "sha512-4mdmfEejTvRZzrEIn70jqqNl3g15vnkRdTkJ8uMK4jiljntlwhiSc5vknZOLt1QM8za16C3tDrSl2mTL9ma2Sg==",
-      "dev": true
-    },
-    "monaco-languages": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/monaco-languages/-/monaco-languages-1.10.0.tgz",
-      "integrity": "sha512-ARAws17Xh0K4WsZYkJY6CqHn9EYdYN8CjzK6w/jgXIwU0owzCdUWxzu+FNJ/LeDLcKxL/YK3phcwGFj9IqX2yw==",
-      "dev": true
-    },
-    "monaco-plugin-helpers": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/monaco-plugin-helpers/-/monaco-plugin-helpers-1.0.2.tgz",
-      "integrity": "sha512-7kUx8dtd5qVNVgUARBRhnM8oftPglYwlINfigC4yGUiuzqtIN22u1tly8umiOCIPR0eFiBLjt6aN23oZh2QJgg==",
-      "dev": true,
-      "requires": {
-        "typescript": "^2.7.2"
-      },
-      "dependencies": {
-        "typescript": {
-          "version": "2.9.2",
-          "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
-          "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
-          "dev": true
-        }
-      }
-    },
-    "mri": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz",
-      "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==",
-      "dev": true
-    },
-    "multimatch": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
-      "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
-      "dev": true,
-      "requires": {
-        "@types/minimatch": "^3.0.3",
-        "array-differ": "^3.0.0",
-        "array-union": "^2.1.0",
-        "arrify": "^2.0.1",
-        "minimatch": "^3.0.4"
-      }
-    },
-    "npm-run-path": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
-      "dev": true,
-      "requires": {
-        "path-key": "^3.0.0"
-      }
-    },
-    "once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-      "dev": true,
-      "requires": {
-        "wrappy": "1"
-      }
-    },
-    "onetime": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
-      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
-      "dev": true,
-      "requires": {
-        "mimic-fn": "^2.1.0"
-      }
-    },
-    "opencollective-postinstall": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
-      "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
-      "dev": true
-    },
-    "p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
-      "dev": true,
-      "requires": {
-        "p-try": "^2.0.0"
-      }
-    },
-    "p-locate": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
-      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
-      "dev": true,
-      "requires": {
-        "p-limit": "^2.2.0"
-      }
-    },
-    "p-try": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
-      "dev": true
-    },
-    "parent-module": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
-      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
-      "dev": true,
-      "requires": {
-        "callsites": "^3.0.0"
-      }
-    },
-    "parse-json": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz",
-      "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.0.0",
-        "error-ex": "^1.3.1",
-        "json-parse-even-better-errors": "^2.3.0",
-        "lines-and-columns": "^1.1.6"
-      }
-    },
-    "path-exists": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
-      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-      "dev": true
-    },
-    "path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true
-    },
-    "path-type": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
-      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-      "dev": true
-    },
-    "pkg-dir": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
-      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
-      "dev": true,
-      "requires": {
-        "find-up": "^4.0.0"
-      }
-    },
-    "please-upgrade-node": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
-      "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
-      "dev": true,
-      "requires": {
-        "semver-compare": "^1.0.0"
-      }
-    },
-    "prettier": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.1.tgz",
-      "integrity": "sha512-9bY+5ZWCfqj3ghYBLxApy2zf6m+NJo5GzmLTpr9FsApsfjriNnS2dahWReHMi7qNPhhHl9SYHJs2cHZLgexNIw==",
-      "dev": true
-    },
-    "pretty-quick": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.0.0.tgz",
-      "integrity": "sha512-oIXlGQUcUxt3XpoNfQECEWvH1Q9PtKfelF2pdp6UvC1CSQ5QcB7gUYKu0kuJGlm3LMBZzJaO/vbRkxA61pWlcg==",
-      "dev": true,
-      "requires": {
-        "chalk": "^3.0.0",
-        "execa": "^4.0.0",
-        "find-up": "^4.1.0",
-        "ignore": "^5.1.4",
-        "mri": "^1.1.5",
-        "multimatch": "^4.0.0"
-      },
-      "dependencies": {
-        "chalk": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
-          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        }
-      }
-    },
-    "pump": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
-      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
-      "dev": true,
-      "requires": {
-        "end-of-stream": "^1.1.0",
-        "once": "^1.3.1"
-      }
-    },
-    "requirejs": {
-      "version": "2.3.6",
-      "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
-      "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==",
-      "dev": true
-    },
-    "resolve-from": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-      "dev": true
-    },
-    "semver-compare": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
-      "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
-      "dev": true
-    },
-    "semver-regex": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz",
-      "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==",
-      "dev": true
-    },
-    "shebang-command": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-      "dev": true,
-      "requires": {
-        "shebang-regex": "^3.0.0"
-      }
-    },
-    "shebang-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true
-    },
-    "signal-exit": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
-      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
-      "dev": true
-    },
-    "slash": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-      "dev": true
-    },
-    "source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true
-    },
-    "source-map-support": {
-      "version": "0.5.16",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz",
-      "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==",
-      "dev": true,
-      "requires": {
-        "buffer-from": "^1.0.0",
-        "source-map": "^0.6.0"
-      }
-    },
-    "strip-final-newline": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
-      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
-      "dev": true
-    },
-    "supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
-      "requires": {
-        "has-flag": "^4.0.0"
-      }
-    },
-    "terser": {
-      "version": "4.6.3",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.3.tgz",
-      "integrity": "sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ==",
-      "dev": true,
-      "requires": {
-        "commander": "^2.20.0",
-        "source-map": "~0.6.1",
-        "source-map-support": "~0.5.12"
-      }
-    },
-    "typescript": {
-      "version": "3.7.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz",
-      "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==",
-      "dev": true
-    },
-    "vscode-html-languageservice": {
-      "version": "3.0.4-next.12",
-      "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-3.0.4-next.12.tgz",
-      "integrity": "sha512-/wii3f22RildoI5M6Li2KNMeHTS3xt3ECgQmu5fGkG57rcxzIhO7XlKlozBCG+/NHzWss0lB30c0nfWvIKsn9g==",
-      "dev": true,
-      "requires": {
-        "vscode-languageserver-textdocument": "^1.0.0-next.5",
-        "vscode-languageserver-types": "^3.15.0-next.6",
-        "vscode-nls": "^4.1.1",
-        "vscode-uri": "^2.1.1"
-      },
-      "dependencies": {
-        "vscode-languageserver-types": {
-          "version": "3.15.0-next.9",
-          "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.9.tgz",
-          "integrity": "sha512-Rl/8qJ6932nrHCdPn+9y0x08uLVQaSLRG+U4JzhyKpWU4eJbVaDRoAcz1Llj7CErJGbPr6kdBvShPy5fRfR+Uw==",
-          "dev": true
-        }
-      }
-    },
-    "vscode-languageserver-textdocument": {
-      "version": "1.0.0-next.5",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.0-next.5.tgz",
-      "integrity": "sha512-1jp/zAidN/bF/sqPimhBX1orH5G4rzRw63k75TesukJDuxm8yW79ECStWbDSy41BHGOwSGN4M69QFvhancSr5A==",
-      "dev": true
-    },
-    "vscode-languageserver-types": {
-      "version": "3.15.0-next.9",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.9.tgz",
-      "integrity": "sha512-Rl/8qJ6932nrHCdPn+9y0x08uLVQaSLRG+U4JzhyKpWU4eJbVaDRoAcz1Llj7CErJGbPr6kdBvShPy5fRfR+Uw==",
-      "dev": true
-    },
-    "vscode-nls": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz",
-      "integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==",
-      "dev": true
-    },
-    "vscode-uri": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.1.tgz",
-      "integrity": "sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A==",
-      "dev": true
-    },
-    "which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
-      "requires": {
-        "isexe": "^2.0.0"
-      }
-    },
-    "which-pm-runs": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
-      "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
-      "dev": true
-    },
-    "wrappy": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-      "dev": true
-    },
-    "yaml": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
-      "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==",
-      "dev": true
-    }
-  }
+	"name": "monaco-html",
+	"version": "2.7.0",
+	"lockfileVersion": 1,
+	"requires": true,
+	"dependencies": {
+		"@babel/code-frame": {
+			"version": "7.10.4",
+			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+			"integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+			"dev": true,
+			"requires": {
+				"@babel/highlight": "^7.10.4"
+			}
+		},
+		"@babel/helper-validator-identifier": {
+			"version": "7.10.4",
+			"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+			"integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
+			"dev": true
+		},
+		"@babel/highlight": {
+			"version": "7.10.4",
+			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+			"integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+			"dev": true,
+			"requires": {
+				"@babel/helper-validator-identifier": "^7.10.4",
+				"chalk": "^2.0.0",
+				"js-tokens": "^4.0.0"
+			},
+			"dependencies": {
+				"ansi-styles": {
+					"version": "3.2.1",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+					"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+					"dev": true,
+					"requires": {
+						"color-convert": "^1.9.0"
+					}
+				},
+				"chalk": {
+					"version": "2.4.2",
+					"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+					"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+					"dev": true,
+					"requires": {
+						"ansi-styles": "^3.2.1",
+						"escape-string-regexp": "^1.0.5",
+						"supports-color": "^5.3.0"
+					}
+				},
+				"color-convert": {
+					"version": "1.9.3",
+					"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+					"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+					"dev": true,
+					"requires": {
+						"color-name": "1.1.3"
+					}
+				},
+				"color-name": {
+					"version": "1.1.3",
+					"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+					"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+					"dev": true
+				},
+				"has-flag": {
+					"version": "3.0.0",
+					"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+					"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+					"dev": true
+				},
+				"supports-color": {
+					"version": "5.5.0",
+					"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+					"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+					"dev": true,
+					"requires": {
+						"has-flag": "^3.0.0"
+					}
+				}
+			}
+		},
+		"@types/color-name": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
+			"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
+			"dev": true
+		},
+		"@types/minimatch": {
+			"version": "3.0.3",
+			"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+			"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+			"dev": true
+		},
+		"@types/parse-json": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
+			"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
+			"dev": true
+		},
+		"ansi-styles": {
+			"version": "4.2.1",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+			"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+			"dev": true,
+			"requires": {
+				"@types/color-name": "^1.1.1",
+				"color-convert": "^2.0.1"
+			}
+		},
+		"array-differ": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
+			"integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
+			"dev": true
+		},
+		"array-union": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+			"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+			"dev": true
+		},
+		"arrify": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+			"integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+			"dev": true
+		},
+		"balanced-match": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+			"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+			"dev": true
+		},
+		"brace-expansion": {
+			"version": "1.1.11",
+			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+			"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+			"dev": true,
+			"requires": {
+				"balanced-match": "^1.0.0",
+				"concat-map": "0.0.1"
+			}
+		},
+		"buffer-from": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+			"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+			"dev": true
+		},
+		"callsites": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+			"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+			"dev": true
+		},
+		"chalk": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+			"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+			"dev": true,
+			"requires": {
+				"ansi-styles": "^4.1.0",
+				"supports-color": "^7.1.0"
+			}
+		},
+		"ci-info": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+			"integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+			"dev": true
+		},
+		"color-convert": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+			"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+			"dev": true,
+			"requires": {
+				"color-name": "~1.1.4"
+			}
+		},
+		"color-name": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+			"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+			"dev": true
+		},
+		"commander": {
+			"version": "2.20.3",
+			"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+			"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+			"dev": true
+		},
+		"compare-versions": {
+			"version": "3.6.0",
+			"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz",
+			"integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==",
+			"dev": true
+		},
+		"concat-map": {
+			"version": "0.0.1",
+			"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+			"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+			"dev": true
+		},
+		"cosmiconfig": {
+			"version": "7.0.0",
+			"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
+			"integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==",
+			"dev": true,
+			"requires": {
+				"@types/parse-json": "^4.0.0",
+				"import-fresh": "^3.2.1",
+				"parse-json": "^5.0.0",
+				"path-type": "^4.0.0",
+				"yaml": "^1.10.0"
+			}
+		},
+		"cross-spawn": {
+			"version": "7.0.3",
+			"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+			"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+			"dev": true,
+			"requires": {
+				"path-key": "^3.1.0",
+				"shebang-command": "^2.0.0",
+				"which": "^2.0.1"
+			}
+		},
+		"end-of-stream": {
+			"version": "1.4.4",
+			"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+			"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+			"dev": true,
+			"requires": {
+				"once": "^1.4.0"
+			}
+		},
+		"error-ex": {
+			"version": "1.3.2",
+			"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+			"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+			"dev": true,
+			"requires": {
+				"is-arrayish": "^0.2.1"
+			}
+		},
+		"escape-string-regexp": {
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+			"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+			"dev": true
+		},
+		"execa": {
+			"version": "4.0.3",
+			"resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz",
+			"integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==",
+			"dev": true,
+			"requires": {
+				"cross-spawn": "^7.0.0",
+				"get-stream": "^5.0.0",
+				"human-signals": "^1.1.1",
+				"is-stream": "^2.0.0",
+				"merge-stream": "^2.0.0",
+				"npm-run-path": "^4.0.0",
+				"onetime": "^5.1.0",
+				"signal-exit": "^3.0.2",
+				"strip-final-newline": "^2.0.0"
+			}
+		},
+		"find-up": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+			"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+			"dev": true,
+			"requires": {
+				"locate-path": "^5.0.0",
+				"path-exists": "^4.0.0"
+			}
+		},
+		"find-versions": {
+			"version": "3.2.0",
+			"resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
+			"integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==",
+			"dev": true,
+			"requires": {
+				"semver-regex": "^2.0.0"
+			}
+		},
+		"get-stream": {
+			"version": "5.2.0",
+			"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+			"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+			"dev": true,
+			"requires": {
+				"pump": "^3.0.0"
+			}
+		},
+		"has-flag": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+			"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+			"dev": true
+		},
+		"human-signals": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
+			"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+			"dev": true
+		},
+		"husky": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/husky/-/husky-4.3.0.tgz",
+			"integrity": "sha512-tTMeLCLqSBqnflBZnlVDhpaIMucSGaYyX6855jM4AguGeWCeSzNdb1mfyWduTZ3pe3SJVvVWGL0jO1iKZVPfTA==",
+			"dev": true,
+			"requires": {
+				"chalk": "^4.0.0",
+				"ci-info": "^2.0.0",
+				"compare-versions": "^3.6.0",
+				"cosmiconfig": "^7.0.0",
+				"find-versions": "^3.2.0",
+				"opencollective-postinstall": "^2.0.2",
+				"pkg-dir": "^4.2.0",
+				"please-upgrade-node": "^3.2.0",
+				"slash": "^3.0.0",
+				"which-pm-runs": "^1.0.0"
+			}
+		},
+		"ignore": {
+			"version": "5.1.8",
+			"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+			"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+			"dev": true
+		},
+		"import-fresh": {
+			"version": "3.2.1",
+			"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
+			"integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
+			"dev": true,
+			"requires": {
+				"parent-module": "^1.0.0",
+				"resolve-from": "^4.0.0"
+			}
+		},
+		"is-arrayish": {
+			"version": "0.2.1",
+			"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+			"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+			"dev": true
+		},
+		"is-stream": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+			"integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+			"dev": true
+		},
+		"isexe": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+			"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+			"dev": true
+		},
+		"js-tokens": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+			"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+			"dev": true
+		},
+		"json-parse-even-better-errors": {
+			"version": "2.3.1",
+			"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+			"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+			"dev": true
+		},
+		"lines-and-columns": {
+			"version": "1.1.6",
+			"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
+			"integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+			"dev": true
+		},
+		"locate-path": {
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+			"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+			"dev": true,
+			"requires": {
+				"p-locate": "^4.1.0"
+			}
+		},
+		"merge-stream": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+			"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+			"dev": true
+		},
+		"mimic-fn": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+			"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+			"dev": true
+		},
+		"minimatch": {
+			"version": "3.0.4",
+			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+			"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+			"dev": true,
+			"requires": {
+				"brace-expansion": "^1.1.7"
+			}
+		},
+		"monaco-editor-core": {
+			"version": "0.20.0",
+			"resolved": "https://registry.npmjs.org/monaco-editor-core/-/monaco-editor-core-0.20.0.tgz",
+			"integrity": "sha512-4mdmfEejTvRZzrEIn70jqqNl3g15vnkRdTkJ8uMK4jiljntlwhiSc5vknZOLt1QM8za16C3tDrSl2mTL9ma2Sg==",
+			"dev": true
+		},
+		"monaco-languages": {
+			"version": "1.10.0",
+			"resolved": "https://registry.npmjs.org/monaco-languages/-/monaco-languages-1.10.0.tgz",
+			"integrity": "sha512-ARAws17Xh0K4WsZYkJY6CqHn9EYdYN8CjzK6w/jgXIwU0owzCdUWxzu+FNJ/LeDLcKxL/YK3phcwGFj9IqX2yw==",
+			"dev": true
+		},
+		"monaco-plugin-helpers": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/monaco-plugin-helpers/-/monaco-plugin-helpers-1.0.2.tgz",
+			"integrity": "sha512-7kUx8dtd5qVNVgUARBRhnM8oftPglYwlINfigC4yGUiuzqtIN22u1tly8umiOCIPR0eFiBLjt6aN23oZh2QJgg==",
+			"dev": true,
+			"requires": {
+				"typescript": "^2.7.2"
+			},
+			"dependencies": {
+				"typescript": {
+					"version": "2.9.2",
+					"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
+					"integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
+					"dev": true
+				}
+			}
+		},
+		"mri": {
+			"version": "1.1.6",
+			"resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz",
+			"integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==",
+			"dev": true
+		},
+		"multimatch": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
+			"integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
+			"dev": true,
+			"requires": {
+				"@types/minimatch": "^3.0.3",
+				"array-differ": "^3.0.0",
+				"array-union": "^2.1.0",
+				"arrify": "^2.0.1",
+				"minimatch": "^3.0.4"
+			}
+		},
+		"npm-run-path": {
+			"version": "4.0.1",
+			"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+			"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+			"dev": true,
+			"requires": {
+				"path-key": "^3.0.0"
+			}
+		},
+		"once": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+			"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+			"dev": true,
+			"requires": {
+				"wrappy": "1"
+			}
+		},
+		"onetime": {
+			"version": "5.1.2",
+			"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+			"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+			"dev": true,
+			"requires": {
+				"mimic-fn": "^2.1.0"
+			}
+		},
+		"opencollective-postinstall": {
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
+			"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
+			"dev": true
+		},
+		"p-limit": {
+			"version": "2.3.0",
+			"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+			"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+			"dev": true,
+			"requires": {
+				"p-try": "^2.0.0"
+			}
+		},
+		"p-locate": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+			"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+			"dev": true,
+			"requires": {
+				"p-limit": "^2.2.0"
+			}
+		},
+		"p-try": {
+			"version": "2.2.0",
+			"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+			"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+			"dev": true
+		},
+		"parent-module": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+			"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+			"dev": true,
+			"requires": {
+				"callsites": "^3.0.0"
+			}
+		},
+		"parse-json": {
+			"version": "5.1.0",
+			"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz",
+			"integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==",
+			"dev": true,
+			"requires": {
+				"@babel/code-frame": "^7.0.0",
+				"error-ex": "^1.3.1",
+				"json-parse-even-better-errors": "^2.3.0",
+				"lines-and-columns": "^1.1.6"
+			}
+		},
+		"path-exists": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+			"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+			"dev": true
+		},
+		"path-key": {
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+			"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+			"dev": true
+		},
+		"path-type": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+			"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+			"dev": true
+		},
+		"pkg-dir": {
+			"version": "4.2.0",
+			"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+			"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+			"dev": true,
+			"requires": {
+				"find-up": "^4.0.0"
+			}
+		},
+		"please-upgrade-node": {
+			"version": "3.2.0",
+			"resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
+			"integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
+			"dev": true,
+			"requires": {
+				"semver-compare": "^1.0.0"
+			}
+		},
+		"prettier": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.1.tgz",
+			"integrity": "sha512-9bY+5ZWCfqj3ghYBLxApy2zf6m+NJo5GzmLTpr9FsApsfjriNnS2dahWReHMi7qNPhhHl9SYHJs2cHZLgexNIw==",
+			"dev": true
+		},
+		"pretty-quick": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.0.0.tgz",
+			"integrity": "sha512-oIXlGQUcUxt3XpoNfQECEWvH1Q9PtKfelF2pdp6UvC1CSQ5QcB7gUYKu0kuJGlm3LMBZzJaO/vbRkxA61pWlcg==",
+			"dev": true,
+			"requires": {
+				"chalk": "^3.0.0",
+				"execa": "^4.0.0",
+				"find-up": "^4.1.0",
+				"ignore": "^5.1.4",
+				"mri": "^1.1.5",
+				"multimatch": "^4.0.0"
+			},
+			"dependencies": {
+				"chalk": {
+					"version": "3.0.0",
+					"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+					"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+					"dev": true,
+					"requires": {
+						"ansi-styles": "^4.1.0",
+						"supports-color": "^7.1.0"
+					}
+				}
+			}
+		},
+		"pump": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+			"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+			"dev": true,
+			"requires": {
+				"end-of-stream": "^1.1.0",
+				"once": "^1.3.1"
+			}
+		},
+		"requirejs": {
+			"version": "2.3.6",
+			"resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
+			"integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==",
+			"dev": true
+		},
+		"resolve-from": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+			"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+			"dev": true
+		},
+		"semver-compare": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+			"integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
+			"dev": true
+		},
+		"semver-regex": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz",
+			"integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==",
+			"dev": true
+		},
+		"shebang-command": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+			"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+			"dev": true,
+			"requires": {
+				"shebang-regex": "^3.0.0"
+			}
+		},
+		"shebang-regex": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+			"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+			"dev": true
+		},
+		"signal-exit": {
+			"version": "3.0.3",
+			"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+			"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+			"dev": true
+		},
+		"slash": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+			"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+			"dev": true
+		},
+		"source-map": {
+			"version": "0.6.1",
+			"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+			"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+			"dev": true
+		},
+		"source-map-support": {
+			"version": "0.5.16",
+			"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz",
+			"integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==",
+			"dev": true,
+			"requires": {
+				"buffer-from": "^1.0.0",
+				"source-map": "^0.6.0"
+			}
+		},
+		"strip-final-newline": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+			"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+			"dev": true
+		},
+		"supports-color": {
+			"version": "7.2.0",
+			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+			"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+			"dev": true,
+			"requires": {
+				"has-flag": "^4.0.0"
+			}
+		},
+		"terser": {
+			"version": "4.6.3",
+			"resolved": "https://registry.npmjs.org/terser/-/terser-4.6.3.tgz",
+			"integrity": "sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ==",
+			"dev": true,
+			"requires": {
+				"commander": "^2.20.0",
+				"source-map": "~0.6.1",
+				"source-map-support": "~0.5.12"
+			}
+		},
+		"typescript": {
+			"version": "3.7.5",
+			"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz",
+			"integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==",
+			"dev": true
+		},
+		"vscode-html-languageservice": {
+			"version": "3.0.4-next.12",
+			"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-3.0.4-next.12.tgz",
+			"integrity": "sha512-/wii3f22RildoI5M6Li2KNMeHTS3xt3ECgQmu5fGkG57rcxzIhO7XlKlozBCG+/NHzWss0lB30c0nfWvIKsn9g==",
+			"dev": true,
+			"requires": {
+				"vscode-languageserver-textdocument": "^1.0.0-next.5",
+				"vscode-languageserver-types": "^3.15.0-next.6",
+				"vscode-nls": "^4.1.1",
+				"vscode-uri": "^2.1.1"
+			},
+			"dependencies": {
+				"vscode-languageserver-types": {
+					"version": "3.15.0-next.9",
+					"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.9.tgz",
+					"integrity": "sha512-Rl/8qJ6932nrHCdPn+9y0x08uLVQaSLRG+U4JzhyKpWU4eJbVaDRoAcz1Llj7CErJGbPr6kdBvShPy5fRfR+Uw==",
+					"dev": true
+				}
+			}
+		},
+		"vscode-languageserver-textdocument": {
+			"version": "1.0.0-next.5",
+			"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.0-next.5.tgz",
+			"integrity": "sha512-1jp/zAidN/bF/sqPimhBX1orH5G4rzRw63k75TesukJDuxm8yW79ECStWbDSy41BHGOwSGN4M69QFvhancSr5A==",
+			"dev": true
+		},
+		"vscode-languageserver-types": {
+			"version": "3.15.0-next.9",
+			"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.9.tgz",
+			"integrity": "sha512-Rl/8qJ6932nrHCdPn+9y0x08uLVQaSLRG+U4JzhyKpWU4eJbVaDRoAcz1Llj7CErJGbPr6kdBvShPy5fRfR+Uw==",
+			"dev": true
+		},
+		"vscode-nls": {
+			"version": "4.1.1",
+			"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.1.tgz",
+			"integrity": "sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==",
+			"dev": true
+		},
+		"vscode-uri": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.1.tgz",
+			"integrity": "sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A==",
+			"dev": true
+		},
+		"which": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+			"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+			"dev": true,
+			"requires": {
+				"isexe": "^2.0.0"
+			}
+		},
+		"which-pm-runs": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
+			"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
+			"dev": true
+		},
+		"wrappy": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+			"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+			"dev": true
+		},
+		"yaml": {
+			"version": "1.10.0",
+			"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
+			"integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==",
+			"dev": true
+		}
+	}
 }

+ 39 - 34
package.json

@@ -1,36 +1,41 @@
 {
-  "name": "monaco-html",
-  "version": "2.7.0",
-  "description": "HTML plugin for the Monaco Editor",
-  "scripts": {
-    "compile": "mrmdir ./out && tsc -p ./src/tsconfig.json && tsc -p ./src/tsconfig.esm.json",
-    "watch": "tsc -p ./src --watch",
-    "prepublishOnly": "mrmdir ./release && npm run compile && node ./scripts/release.js && node ./scripts/bundle && mcopy ./src/monaco.d.ts ./release/monaco.d.ts",
-    "install-service-next": "npm install vscode-html-languageservice@next -f -D && npm install vscode-languageserver-types@next -f -D",
-    "install-service-local": "npm install ../vscode-html-languageservice -f -D && npm install ../vscode-languageserver-node/types -f -D",
-    "prettier": "prettier --write ."
-  },
-  "author": "Microsoft Corporation",
-  "license": "MIT",
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/Microsoft/monaco-html"
-  },
-  "bugs": {
-    "url": "https://github.com/Microsoft/monaco-editor/issues"
-  },
-  "devDependencies": {
-    "husky": "^4.2.5",
-    "monaco-editor-core": "0.20.0",
-    "monaco-languages": "^1.10.0",
-    "monaco-plugin-helpers": "^1.0.2",
-    "prettier": "^2.1.1",
-    "pretty-quick": "^3.0.0",
-    "requirejs": "^2.3.6",
-    "typescript": "^3.7.5",
-    "terser": "^4.6.3",
-    "vscode-html-languageservice": "3.0.4-next.12",
-    "vscode-languageserver-types": "3.15.0-next.9",
-    "vscode-languageserver-textdocument": "^1.0.0-next.5"
-  }
+	"name": "monaco-html",
+	"version": "2.7.0",
+	"description": "HTML plugin for the Monaco Editor",
+	"scripts": {
+		"compile": "mrmdir ./out && tsc -p ./src/tsconfig.json && tsc -p ./src/tsconfig.esm.json",
+		"watch": "tsc -p ./src --watch",
+		"prepublishOnly": "mrmdir ./release && npm run compile && node ./scripts/release.js && node ./scripts/bundle && mcopy ./src/monaco.d.ts ./release/monaco.d.ts",
+		"install-service-next": "npm install vscode-html-languageservice@next -f -D && npm install vscode-languageserver-types@next -f -D",
+		"install-service-local": "npm install ../vscode-html-languageservice -f -D && npm install ../vscode-languageserver-node/types -f -D",
+		"prettier": "prettier --write ."
+	},
+	"author": "Microsoft Corporation",
+	"license": "MIT",
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/Microsoft/monaco-html"
+	},
+	"bugs": {
+		"url": "https://github.com/Microsoft/monaco-editor/issues"
+	},
+	"devDependencies": {
+		"husky": "^4.2.5",
+		"monaco-editor-core": "0.20.0",
+		"monaco-languages": "^1.10.0",
+		"monaco-plugin-helpers": "^1.0.2",
+		"prettier": "^2.1.1",
+		"pretty-quick": "^3.0.0",
+		"requirejs": "^2.3.6",
+		"typescript": "^3.7.5",
+		"terser": "^4.6.3",
+		"vscode-html-languageservice": "3.0.4-next.12",
+		"vscode-languageserver-types": "3.15.0-next.9",
+		"vscode-languageserver-textdocument": "^1.0.0-next.5"
+	},
+	"husky": {
+		"hooks": {
+			"pre-commit": "pretty-quick --staged"
+		}
+	}
 }

+ 71 - 45
scripts/bundle.js

@@ -1,7 +1,7 @@
 const requirejs = require('requirejs');
 const path = require('path');
 const fs = require('fs');
-const terser = require("terser");
+const terser = require('terser');
 const helpers = require('monaco-plugin-helpers');
 
 const REPO_ROOT = path.resolve(__dirname, '..');
@@ -25,49 +25,75 @@ bundleOne('htmlMode');
 bundleOne('htmlWorker');
 
 function bundleOne(moduleId, exclude) {
-	requirejs.optimize({
-		baseUrl: 'out/amd/',
-		name: 'vs/language/html/' + moduleId,
-		out: 'release/dev/' + moduleId + '.js',
-		exclude: exclude,
-		paths: {
-			'vs/language/html': REPO_ROOT + '/out/amd'
+	requirejs.optimize(
+		{
+			baseUrl: 'out/amd/',
+			name: 'vs/language/html/' + moduleId,
+			out: 'release/dev/' + moduleId + '.js',
+			exclude: exclude,
+			paths: {
+				'vs/language/html': REPO_ROOT + '/out/amd'
+			},
+			optimize: 'none',
+			packages: [
+				{
+					name: 'vscode-html-languageservice',
+					location: path.join(
+						REPO_ROOT,
+						'node_modules/vscode-html-languageservice/lib/umd'
+					),
+					main: 'htmlLanguageService'
+				},
+				{
+					name: 'vscode-languageserver-types',
+					location: path.join(
+						REPO_ROOT,
+						'node_modules/vscode-languageserver-types/lib/umd'
+					),
+					main: 'main'
+				},
+				{
+					name: 'vscode-languageserver-textdocument',
+					location: path.join(
+						REPO_ROOT,
+						'node_modules/vscode-languageserver-textdocument/lib/umd'
+					),
+					main: 'main'
+				},
+				{
+					name: 'vscode-uri',
+					location: path.join(REPO_ROOT, 'node_modules/vscode-uri/lib/umd'),
+					main: 'index'
+				},
+				{
+					name: 'vscode-nls',
+					location: path.join(REPO_ROOT, '/out/amd/fillers'),
+					main: 'vscode-nls'
+				}
+			]
 		},
-		optimize: 'none',
-		packages: [{
-			name: 'vscode-html-languageservice',
-			location: path.join(REPO_ROOT, 'node_modules/vscode-html-languageservice/lib/umd'),
-			main: 'htmlLanguageService'
-		}, {
-			name: 'vscode-languageserver-types',
-			location: path.join(REPO_ROOT, 'node_modules/vscode-languageserver-types/lib/umd'),
-			main: 'main'
-		}, {
-			name: 'vscode-languageserver-textdocument',
-			location: path.join(REPO_ROOT, 'node_modules/vscode-languageserver-textdocument/lib/umd'),
-			main: 'main'
-		}, {
-			name: 'vscode-uri',
-			location: path.join(REPO_ROOT, 'node_modules/vscode-uri/lib/umd'),
-			main: 'index'
-		}, {
-			name: 'vscode-nls',
-			location: path.join(REPO_ROOT, '/out/amd/fillers'),
-			main: 'vscode-nls'
-		}]
-	}, function (buildResponse) {
-		const devFilePath = path.join(REPO_ROOT, 'release/dev/' + moduleId + '.js');
-		const minFilePath = path.join(REPO_ROOT, 'release/min/' + moduleId + '.js');
-		const fileContents = fs.readFileSync(devFilePath).toString();
-		console.log();
-		console.log(`Minifying ${devFilePath}...`);
-		const result = terser.minify(fileContents, {
-			output: {
-				comments: 'some'
-			}
-		});
-		console.log(`Done.`);
-		try { fs.mkdirSync(path.join(REPO_ROOT, 'release/min')) } catch (err) { }
-		fs.writeFileSync(minFilePath, BUNDLED_FILE_HEADER + result.code);
-	})
+		function (buildResponse) {
+			const devFilePath = path.join(
+				REPO_ROOT,
+				'release/dev/' + moduleId + '.js'
+			);
+			const minFilePath = path.join(
+				REPO_ROOT,
+				'release/min/' + moduleId + '.js'
+			);
+			const fileContents = fs.readFileSync(devFilePath).toString();
+			console.log();
+			console.log(`Minifying ${devFilePath}...`);
+			const result = terser.minify(fileContents, {
+				output: {
+					comments: 'some'
+				}
+			});
+			console.log(`Done.`);
+			try {
+				fs.mkdirSync(path.join(REPO_ROOT, 'release/min'));
+			} catch (err) {}
+			fs.writeFileSync(minFilePath, BUNDLED_FILE_HEADER + result.code);
+		}
+	);
 }

+ 4 - 10
scripts/release.js

@@ -12,19 +12,13 @@ helpers.packageESM({
 	repoRoot: REPO_ROOT,
 	esmSource: 'out/esm',
 	esmDestination: 'release/esm',
-	entryPoints: [
-		'monaco.contribution.js',
-		'htmlMode.js',
-		'html.worker.js'
-	],
+	entryPoints: ['monaco.contribution.js', 'htmlMode.js', 'html.worker.js'],
 	resolveAlias: {
-		'vscode-nls': path.join(REPO_ROOT, "out/esm/fillers/vscode-nls.js")
+		'vscode-nls': path.join(REPO_ROOT, 'out/esm/fillers/vscode-nls.js')
 	},
-	resolveSkip: [
-		'monaco-editor-core'
-	],
+	resolveSkip: ['monaco-editor-core'],
 	destinationFolderSimplification: {
-		'node_modules': '_deps',
+		node_modules: '_deps',
 		'vscode-languageserver-types/lib/esm': 'vscode-languageserver-types',
 		'vscode-uri/lib/esm': 'vscode-uri',
 		'vscode-html-languageservice/lib/esm': 'vscode-html-languageservice'

+ 9 - 5
src/fillers/vscode-nls.ts

@@ -20,7 +20,7 @@ export interface LoadFunc {
 }
 
 function format(message: string, args: any[]): string {
-	let result:string;
+	let result: string;
 
 	if (args.length === 0) {
 		result = message;
@@ -33,14 +33,18 @@ function format(message: string, args: any[]): string {
 	return result;
 }
 
-function localize(key: string | LocalizeInfo, message: string, ...args: any[]): string {
+function localize(
+	key: string | LocalizeInfo,
+	message: string,
+	...args: any[]
+): string {
 	return format(message, args);
 }
 
 export function loadMessageBundle(file?: string): LocalizeFunc {
-    return localize;
+	return localize;
 }
 
 export function config(opt?: Options | string): LoadFunc {
-    return loadMessageBundle;
-}
+	return loadMessageBundle;
+}

+ 1 - 1
src/html.worker.ts

@@ -10,6 +10,6 @@ import { HTMLWorker } from './htmlWorker';
 self.onmessage = () => {
 	// ignore the first message
 	worker.initialize((ctx, createData) => {
-		return new HTMLWorker(ctx, createData)
+		return new HTMLWorker(ctx, createData);
 	});
 };

+ 195 - 114
src/htmlMode.ts

@@ -1,114 +1,195 @@
-/*---------------------------------------------------------------------------------------------
- *  Copyright (c) Microsoft Corporation. All rights reserved.
- *  Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import { WorkerManager } from './workerManager';
-import { HTMLWorker } from './htmlWorker';
-import { LanguageServiceDefaultsImpl } from './monaco.contribution';
-import * as languageFeatures from './languageFeatures';
-
-import Uri = monaco.Uri;
-import IDisposable = monaco.IDisposable;
-
-export function setupMode1(defaults: LanguageServiceDefaultsImpl): void {
-
-	const client = new WorkerManager(defaults);
-
-	const worker: languageFeatures.WorkerAccessor = (...uris: Uri[]): Promise<HTMLWorker> => {
-		return client.getLanguageServiceWorker(...uris);
-	};
-
-	let languageId = defaults.languageId;
-
-	// all modes
-	monaco.languages.registerCompletionItemProvider(languageId, new languageFeatures.CompletionAdapter(worker));
-	monaco.languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker));
-
-	monaco.languages.registerDocumentHighlightProvider(languageId, new languageFeatures.DocumentHighlightAdapter(worker));
-	monaco.languages.registerLinkProvider(languageId, new languageFeatures.DocumentLinkAdapter(worker));
-	monaco.languages.registerFoldingRangeProvider(languageId, new languageFeatures.FoldingRangeAdapter(worker));
-	monaco.languages.registerDocumentSymbolProvider(languageId, new languageFeatures.DocumentSymbolAdapter(worker));
-	monaco.languages.registerSelectionRangeProvider(languageId, new languageFeatures.SelectionRangeAdapter(worker));
-	monaco.languages.registerRenameProvider(languageId, new languageFeatures.RenameAdapter(worker));
-
-	// only html
-	if (languageId === 'html') {
-		monaco.languages.registerDocumentFormattingEditProvider(languageId, new languageFeatures.DocumentFormattingEditProvider(worker));
-		monaco.languages.registerDocumentRangeFormattingEditProvider(languageId, new languageFeatures.DocumentRangeFormattingEditProvider(worker));
-		new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults);
-	}
-
-}
-
-export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable {
-
-	const disposables: IDisposable[] = [];
-	const providers: IDisposable[] = [];
-
-	const client = new WorkerManager(defaults);
-	disposables.push(client);
-
-	const worker: languageFeatures.WorkerAccessor = (...uris: Uri[]): Promise<HTMLWorker> => {
-		return client.getLanguageServiceWorker(...uris);
-	};
-
-
-	function registerProviders(): void {
-		const { languageId, modeConfiguration } = defaults;
-
-		disposeAll(providers);
-
-		if (modeConfiguration.completionItems) {
-			providers.push(monaco.languages.registerCompletionItemProvider(languageId, new languageFeatures.CompletionAdapter(worker)));
-		}
-		if (modeConfiguration.hovers) {
-			providers.push(monaco.languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker)));
-		}
-		if (modeConfiguration.documentHighlights) {
-			providers.push(monaco.languages.registerDocumentHighlightProvider(languageId, new languageFeatures.DocumentHighlightAdapter(worker)));
-		}
-		if (modeConfiguration.links) {
-			providers.push(monaco.languages.registerLinkProvider(languageId, new languageFeatures.DocumentLinkAdapter(worker)));
-		}
-		if (modeConfiguration.documentSymbols) {
-			providers.push(monaco.languages.registerDocumentSymbolProvider(languageId, new languageFeatures.DocumentSymbolAdapter(worker)));
-		}
-		if (modeConfiguration.rename) {
-			providers.push(monaco.languages.registerRenameProvider(languageId, new languageFeatures.RenameAdapter(worker)));
-		}
-		if (modeConfiguration.foldingRanges) {
-			providers.push(monaco.languages.registerFoldingRangeProvider(languageId, new languageFeatures.FoldingRangeAdapter(worker)));
-		}
-		if (modeConfiguration.selectionRanges) {
-			providers.push(monaco.languages.registerSelectionRangeProvider(languageId, new languageFeatures.SelectionRangeAdapter(worker)));
-		}
-		if (modeConfiguration.documentFormattingEdits) {
-			providers.push(monaco.languages.registerDocumentFormattingEditProvider(languageId, new languageFeatures.DocumentFormattingEditProvider(worker)));
-		}
-		if (modeConfiguration.documentRangeFormattingEdits) {
-			providers.push(monaco.languages.registerDocumentRangeFormattingEditProvider(languageId, new languageFeatures.DocumentRangeFormattingEditProvider(worker)));
-		}
-		if (modeConfiguration.diagnostics) {
-			providers.push(new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults));
-		}
-	}
-
-	registerProviders();
-
-
-	disposables.push(asDisposable(providers));
-
-	return asDisposable(disposables);
-}
-
-function asDisposable(disposables: IDisposable[]): IDisposable {
-	return { dispose: () => disposeAll(disposables) };
-}
-
-function disposeAll(disposables: IDisposable[]) {
-	while (disposables.length) {
-		disposables.pop().dispose();
-	}
-}
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+
+import { WorkerManager } from './workerManager';
+import { HTMLWorker } from './htmlWorker';
+import { LanguageServiceDefaultsImpl } from './monaco.contribution';
+import * as languageFeatures from './languageFeatures';
+
+import Uri = monaco.Uri;
+import IDisposable = monaco.IDisposable;
+
+export function setupMode1(defaults: LanguageServiceDefaultsImpl): void {
+	const client = new WorkerManager(defaults);
+
+	const worker: languageFeatures.WorkerAccessor = (
+		...uris: Uri[]
+	): Promise<HTMLWorker> => {
+		return client.getLanguageServiceWorker(...uris);
+	};
+
+	let languageId = defaults.languageId;
+
+	// all modes
+	monaco.languages.registerCompletionItemProvider(
+		languageId,
+		new languageFeatures.CompletionAdapter(worker)
+	);
+	monaco.languages.registerHoverProvider(
+		languageId,
+		new languageFeatures.HoverAdapter(worker)
+	);
+
+	monaco.languages.registerDocumentHighlightProvider(
+		languageId,
+		new languageFeatures.DocumentHighlightAdapter(worker)
+	);
+	monaco.languages.registerLinkProvider(
+		languageId,
+		new languageFeatures.DocumentLinkAdapter(worker)
+	);
+	monaco.languages.registerFoldingRangeProvider(
+		languageId,
+		new languageFeatures.FoldingRangeAdapter(worker)
+	);
+	monaco.languages.registerDocumentSymbolProvider(
+		languageId,
+		new languageFeatures.DocumentSymbolAdapter(worker)
+	);
+	monaco.languages.registerSelectionRangeProvider(
+		languageId,
+		new languageFeatures.SelectionRangeAdapter(worker)
+	);
+	monaco.languages.registerRenameProvider(
+		languageId,
+		new languageFeatures.RenameAdapter(worker)
+	);
+
+	// only html
+	if (languageId === 'html') {
+		monaco.languages.registerDocumentFormattingEditProvider(
+			languageId,
+			new languageFeatures.DocumentFormattingEditProvider(worker)
+		);
+		monaco.languages.registerDocumentRangeFormattingEditProvider(
+			languageId,
+			new languageFeatures.DocumentRangeFormattingEditProvider(worker)
+		);
+		new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults);
+	}
+}
+
+export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable {
+	const disposables: IDisposable[] = [];
+	const providers: IDisposable[] = [];
+
+	const client = new WorkerManager(defaults);
+	disposables.push(client);
+
+	const worker: languageFeatures.WorkerAccessor = (
+		...uris: Uri[]
+	): Promise<HTMLWorker> => {
+		return client.getLanguageServiceWorker(...uris);
+	};
+
+	function registerProviders(): void {
+		const { languageId, modeConfiguration } = defaults;
+
+		disposeAll(providers);
+
+		if (modeConfiguration.completionItems) {
+			providers.push(
+				monaco.languages.registerCompletionItemProvider(
+					languageId,
+					new languageFeatures.CompletionAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.hovers) {
+			providers.push(
+				monaco.languages.registerHoverProvider(
+					languageId,
+					new languageFeatures.HoverAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.documentHighlights) {
+			providers.push(
+				monaco.languages.registerDocumentHighlightProvider(
+					languageId,
+					new languageFeatures.DocumentHighlightAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.links) {
+			providers.push(
+				monaco.languages.registerLinkProvider(
+					languageId,
+					new languageFeatures.DocumentLinkAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.documentSymbols) {
+			providers.push(
+				monaco.languages.registerDocumentSymbolProvider(
+					languageId,
+					new languageFeatures.DocumentSymbolAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.rename) {
+			providers.push(
+				monaco.languages.registerRenameProvider(
+					languageId,
+					new languageFeatures.RenameAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.foldingRanges) {
+			providers.push(
+				monaco.languages.registerFoldingRangeProvider(
+					languageId,
+					new languageFeatures.FoldingRangeAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.selectionRanges) {
+			providers.push(
+				monaco.languages.registerSelectionRangeProvider(
+					languageId,
+					new languageFeatures.SelectionRangeAdapter(worker)
+				)
+			);
+		}
+		if (modeConfiguration.documentFormattingEdits) {
+			providers.push(
+				monaco.languages.registerDocumentFormattingEditProvider(
+					languageId,
+					new languageFeatures.DocumentFormattingEditProvider(worker)
+				)
+			);
+		}
+		if (modeConfiguration.documentRangeFormattingEdits) {
+			providers.push(
+				monaco.languages.registerDocumentRangeFormattingEditProvider(
+					languageId,
+					new languageFeatures.DocumentRangeFormattingEditProvider(worker)
+				)
+			);
+		}
+		if (modeConfiguration.diagnostics) {
+			providers.push(
+				new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults)
+			);
+		}
+	}
+
+	registerProviders();
+
+	disposables.push(asDisposable(providers));
+
+	return asDisposable(disposables);
+}
+
+function asDisposable(disposables: IDisposable[]): IDisposable {
+	return { dispose: () => disposeAll(disposables) };
+}
+
+function disposeAll(disposables: IDisposable[]) {
+	while (disposables.length) {
+		disposables.pop().dispose();
+	}
+}

+ 151 - 96
src/htmlWorker.ts

@@ -1,96 +1,151 @@
-/*---------------------------------------------------------------------------------------------
- *  Copyright (c) Microsoft Corporation. All rights reserved.
- *  Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import IWorkerContext = monaco.worker.IWorkerContext;
-
-import * as htmlService from 'vscode-html-languageservice';
-
-export class HTMLWorker {
-
-	private _ctx: IWorkerContext;
-	private _languageService: htmlService.LanguageService;
-	private _languageSettings: monaco.languages.html.Options;
-	private _languageId: string;
-
-	constructor(ctx: IWorkerContext, createData: ICreateData) {
-		this._ctx = ctx;
-		this._languageSettings = createData.languageSettings;
-		this._languageId = createData.languageId;
-		this._languageService = htmlService.getLanguageService();
-	}
-
-	async doValidation(uri: string): Promise<htmlService.Diagnostic[]> {
-		// not yet suported
-		return Promise.resolve([]);
-	}
-	async doComplete(uri: string, position: htmlService.Position): Promise<htmlService.CompletionList> {
-		let document = this._getTextDocument(uri);
-		let htmlDocument = this._languageService.parseHTMLDocument(document);
-		return Promise.resolve(this._languageService.doComplete(document, position, htmlDocument, this._languageSettings && this._languageSettings.suggest));
-	}
-	async format(uri: string, range: htmlService.Range, options: htmlService.FormattingOptions): Promise<htmlService.TextEdit[]> {
-		let document = this._getTextDocument(uri);
-		let textEdits = this._languageService.format(document, range, this._languageSettings && this._languageSettings.format);
-		return Promise.resolve(textEdits);
-	}
-	async doHover(uri: string, position: htmlService.Position): Promise<htmlService.Hover> {
-		let document = this._getTextDocument(uri);
-		let htmlDocument = this._languageService.parseHTMLDocument(document);
-		let hover = this._languageService.doHover(document, position, htmlDocument);
-		return Promise.resolve(hover);
-	}
-	async findDocumentHighlights(uri: string, position: htmlService.Position): Promise<htmlService.DocumentHighlight[]> {
-		let document = this._getTextDocument(uri);
-		let htmlDocument = this._languageService.parseHTMLDocument(document);
-		let highlights = this._languageService.findDocumentHighlights(document, position, htmlDocument);
-		return Promise.resolve(highlights);
-	}
-	async findDocumentLinks(uri: string): Promise<htmlService.DocumentLink[]> {
-		let document = this._getTextDocument(uri);
-		let links = this._languageService.findDocumentLinks(document, null);
-		return Promise.resolve(links);
-	}
-	async findDocumentSymbols(uri: string): Promise<htmlService.SymbolInformation[]> {
-		let document = this._getTextDocument(uri);
-		let htmlDocument = this._languageService.parseHTMLDocument(document);
-		let symbols = this._languageService.findDocumentSymbols(document, htmlDocument);
-		return Promise.resolve(symbols);
-	}
-	async getFoldingRanges(uri: string, context?: { rangeLimit?: number; }): Promise<htmlService.FoldingRange[]> {
-		let document = this._getTextDocument(uri);
-		let ranges = this._languageService.getFoldingRanges(document, context);
-		return Promise.resolve(ranges);
-	}
-	async getSelectionRanges(uri: string, positions: htmlService.Position[]): Promise<htmlService.SelectionRange[]> {
-		let document = this._getTextDocument(uri);
-		let ranges = this._languageService.getSelectionRanges(document, positions);
-		return Promise.resolve(ranges);
-	}
-	async doRename(uri: string, position: htmlService.Position, newName: string): Promise<htmlService.WorkspaceEdit> {
-		let document = this._getTextDocument(uri);
-		let htmlDocument = this._languageService.parseHTMLDocument(document);
-		let renames = this._languageService.doRename(document, position, newName, htmlDocument);
-		return Promise.resolve(renames);
-	}
-	private _getTextDocument(uri: string): htmlService.TextDocument {
-		let models = this._ctx.getMirrorModels();
-		for (let model of models) {
-			if (model.uri.toString() === uri) {
-				return htmlService.TextDocument.create(uri, this._languageId, model.version, model.getValue());
-			}
-		}
-		return null;
-	}
-}
-
-export interface ICreateData {
-	languageId: string;
-	languageSettings: monaco.languages.html.Options;
-}
-
-export function create(ctx: IWorkerContext, createData: ICreateData): HTMLWorker {
-	return new HTMLWorker(ctx, createData);
-}
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+
+import IWorkerContext = monaco.worker.IWorkerContext;
+
+import * as htmlService from 'vscode-html-languageservice';
+
+export class HTMLWorker {
+	private _ctx: IWorkerContext;
+	private _languageService: htmlService.LanguageService;
+	private _languageSettings: monaco.languages.html.Options;
+	private _languageId: string;
+
+	constructor(ctx: IWorkerContext, createData: ICreateData) {
+		this._ctx = ctx;
+		this._languageSettings = createData.languageSettings;
+		this._languageId = createData.languageId;
+		this._languageService = htmlService.getLanguageService();
+	}
+
+	async doValidation(uri: string): Promise<htmlService.Diagnostic[]> {
+		// not yet suported
+		return Promise.resolve([]);
+	}
+	async doComplete(
+		uri: string,
+		position: htmlService.Position
+	): Promise<htmlService.CompletionList> {
+		let document = this._getTextDocument(uri);
+		let htmlDocument = this._languageService.parseHTMLDocument(document);
+		return Promise.resolve(
+			this._languageService.doComplete(
+				document,
+				position,
+				htmlDocument,
+				this._languageSettings && this._languageSettings.suggest
+			)
+		);
+	}
+	async format(
+		uri: string,
+		range: htmlService.Range,
+		options: htmlService.FormattingOptions
+	): Promise<htmlService.TextEdit[]> {
+		let document = this._getTextDocument(uri);
+		let textEdits = this._languageService.format(
+			document,
+			range,
+			this._languageSettings && this._languageSettings.format
+		);
+		return Promise.resolve(textEdits);
+	}
+	async doHover(
+		uri: string,
+		position: htmlService.Position
+	): Promise<htmlService.Hover> {
+		let document = this._getTextDocument(uri);
+		let htmlDocument = this._languageService.parseHTMLDocument(document);
+		let hover = this._languageService.doHover(document, position, htmlDocument);
+		return Promise.resolve(hover);
+	}
+	async findDocumentHighlights(
+		uri: string,
+		position: htmlService.Position
+	): Promise<htmlService.DocumentHighlight[]> {
+		let document = this._getTextDocument(uri);
+		let htmlDocument = this._languageService.parseHTMLDocument(document);
+		let highlights = this._languageService.findDocumentHighlights(
+			document,
+			position,
+			htmlDocument
+		);
+		return Promise.resolve(highlights);
+	}
+	async findDocumentLinks(uri: string): Promise<htmlService.DocumentLink[]> {
+		let document = this._getTextDocument(uri);
+		let links = this._languageService.findDocumentLinks(document, null);
+		return Promise.resolve(links);
+	}
+	async findDocumentSymbols(
+		uri: string
+	): Promise<htmlService.SymbolInformation[]> {
+		let document = this._getTextDocument(uri);
+		let htmlDocument = this._languageService.parseHTMLDocument(document);
+		let symbols = this._languageService.findDocumentSymbols(
+			document,
+			htmlDocument
+		);
+		return Promise.resolve(symbols);
+	}
+	async getFoldingRanges(
+		uri: string,
+		context?: { rangeLimit?: number }
+	): Promise<htmlService.FoldingRange[]> {
+		let document = this._getTextDocument(uri);
+		let ranges = this._languageService.getFoldingRanges(document, context);
+		return Promise.resolve(ranges);
+	}
+	async getSelectionRanges(
+		uri: string,
+		positions: htmlService.Position[]
+	): Promise<htmlService.SelectionRange[]> {
+		let document = this._getTextDocument(uri);
+		let ranges = this._languageService.getSelectionRanges(document, positions);
+		return Promise.resolve(ranges);
+	}
+	async doRename(
+		uri: string,
+		position: htmlService.Position,
+		newName: string
+	): Promise<htmlService.WorkspaceEdit> {
+		let document = this._getTextDocument(uri);
+		let htmlDocument = this._languageService.parseHTMLDocument(document);
+		let renames = this._languageService.doRename(
+			document,
+			position,
+			newName,
+			htmlDocument
+		);
+		return Promise.resolve(renames);
+	}
+	private _getTextDocument(uri: string): htmlService.TextDocument {
+		let models = this._ctx.getMirrorModels();
+		for (let model of models) {
+			if (model.uri.toString() === uri) {
+				return htmlService.TextDocument.create(
+					uri,
+					this._languageId,
+					model.version,
+					model.getValue()
+				);
+			}
+		}
+		return null;
+	}
+}
+
+export interface ICreateData {
+	languageId: string;
+	languageSettings: monaco.languages.html.Options;
+}
+
+export function create(
+	ctx: IWorkerContext,
+	createData: ICreateData
+): HTMLWorker {
+	return new HTMLWorker(ctx, createData);
+}

+ 768 - 576
src/languageFeatures.ts

@@ -1,576 +1,768 @@
-/*---------------------------------------------------------------------------------------------
- *  Copyright (c) Microsoft Corporation. All rights reserved.
- *  Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import { LanguageServiceDefaultsImpl } from './monaco.contribution';
-import { HTMLWorker } from './htmlWorker';
-
-import * as htmlService from 'vscode-html-languageservice';
-
-import Uri = monaco.Uri;
-import Position = monaco.Position;
-import Range = monaco.Range;
-import CancellationToken = monaco.CancellationToken;
-import IDisposable = monaco.IDisposable;
-
-
-export interface WorkerAccessor {
-	(...more: Uri[]): Promise<HTMLWorker>
-}
-
-// --- diagnostics --- ---
-
-export class DiagnosticsAdapter {
-
-	private _disposables: IDisposable[] = [];
-	private _listener: { [uri: string]: IDisposable } = Object.create(null);
-
-	constructor(private _languageId: string, private _worker: WorkerAccessor, defaults: LanguageServiceDefaultsImpl) {
-		const onModelAdd = (model: monaco.editor.IModel): void => {
-			const modeId = model.getModeId();
-			if (modeId !== this._languageId) {
-				return;
-			}
-
-			let handle: number;
-			this._listener[model.uri.toString()] = model.onDidChangeContent(() => {
-				clearTimeout(handle);
-				handle = setTimeout(() => this._doValidate(model.uri, modeId), 500);
-			});
-
-			this._doValidate(model.uri, modeId);
-		};
-
-		const onModelRemoved = (model: monaco.editor.IModel): void => {
-			monaco.editor.setModelMarkers(model, this._languageId, []);
-			const uriStr = model.uri.toString();
-			const listener = this._listener[uriStr];
-			if (listener) {
-				listener.dispose();
-				delete this._listener[uriStr];
-			}
-		};
-
-		this._disposables.push(monaco.editor.onDidCreateModel(onModelAdd));
-		this._disposables.push(monaco.editor.onWillDisposeModel(model => {
-			onModelRemoved(model);
-		}));
-		this._disposables.push(monaco.editor.onDidChangeModelLanguage(event => {
-			onModelRemoved(event.model);
-			onModelAdd(event.model);
-		}));
-
-		this._disposables.push(defaults.onDidChange(_ => {
-			monaco.editor.getModels().forEach(model => {
-				if (model.getModeId() === this._languageId) {
-					onModelRemoved(model);
-					onModelAdd(model);
-				}
-			});
-		}));
-
-		this._disposables.push({
-			dispose: () => {
-				for (const key in this._listener) {
-					this._listener[key].dispose();
-				}
-			}
-		});
-
-		monaco.editor.getModels().forEach(onModelAdd);
-	}
-
-	public dispose(): void {
-		this._disposables.forEach(d => d && d.dispose());
-		this._disposables = [];
-	}
-
-	private _doValidate(resource: Uri, languageId: string): void {
-		this._worker(resource).then(worker => {
-			return worker.doValidation(resource.toString()).then(diagnostics => {
-				const markers = diagnostics.map(d => toDiagnostics(resource, d));
-				monaco.editor.setModelMarkers(monaco.editor.getModel(resource), languageId, markers);
-			});
-		}).then(undefined, err => {
-			console.error(err);
-		});
-	}
-}
-
-
-function toSeverity(lsSeverity: number): monaco.MarkerSeverity {
-	switch (lsSeverity) {
-		case htmlService.DiagnosticSeverity.Error: return monaco.MarkerSeverity.Error;
-		case htmlService.DiagnosticSeverity.Warning: return monaco.MarkerSeverity.Warning;
-		case htmlService.DiagnosticSeverity.Information: return monaco.MarkerSeverity.Info;
-		case htmlService.DiagnosticSeverity.Hint: return monaco.MarkerSeverity.Hint;
-		default:
-			return monaco.MarkerSeverity.Info;
-	}
-}
-
-function toDiagnostics(resource: Uri, diag: htmlService.Diagnostic): monaco.editor.IMarkerData {
-	const code = typeof diag.code === 'number' ? String(diag.code) : <string>diag.code;
-
-	return {
-		severity: toSeverity(diag.severity),
-		startLineNumber: diag.range.start.line + 1,
-		startColumn: diag.range.start.character + 1,
-		endLineNumber: diag.range.end.line + 1,
-		endColumn: diag.range.end.character + 1,
-		message: diag.message,
-		code: code,
-		source: diag.source
-	};
-}
-
-// --- completion ------
-
-function fromPosition(position: Position): htmlService.Position {
-	if (!position) {
-		return void 0;
-	}
-	return { character: position.column - 1, line: position.lineNumber - 1 };
-}
-
-function fromRange(range: Range): htmlService.Range {
-	if (!range) {
-		return void 0;
-	}
-	return { start: fromPosition(range.getStartPosition()), end: fromPosition(range.getEndPosition()) };
-}
-
-function toRange(range: htmlService.Range): Range {
-	if (!range) {
-		return void 0;
-	}
-	return new Range(range.start.line + 1, range.start.character + 1, range.end.line + 1, range.end.character + 1);
-}
-
-function toCompletionItemKind(kind: number): monaco.languages.CompletionItemKind {
-	const mItemKind = monaco.languages.CompletionItemKind;
-
-	switch (kind) {
-		case htmlService.CompletionItemKind.Text: return mItemKind.Text;
-		case htmlService.CompletionItemKind.Method: return mItemKind.Method;
-		case htmlService.CompletionItemKind.Function: return mItemKind.Function;
-		case htmlService.CompletionItemKind.Constructor: return mItemKind.Constructor;
-		case htmlService.CompletionItemKind.Field: return mItemKind.Field;
-		case htmlService.CompletionItemKind.Variable: return mItemKind.Variable;
-		case htmlService.CompletionItemKind.Class: return mItemKind.Class;
-		case htmlService.CompletionItemKind.Interface: return mItemKind.Interface;
-		case htmlService.CompletionItemKind.Module: return mItemKind.Module;
-		case htmlService.CompletionItemKind.Property: return mItemKind.Property;
-		case htmlService.CompletionItemKind.Unit: return mItemKind.Unit;
-		case htmlService.CompletionItemKind.Value: return mItemKind.Value;
-		case htmlService.CompletionItemKind.Enum: return mItemKind.Enum;
-		case htmlService.CompletionItemKind.Keyword: return mItemKind.Keyword;
-		case htmlService.CompletionItemKind.Snippet: return mItemKind.Snippet;
-		case htmlService.CompletionItemKind.Color: return mItemKind.Color;
-		case htmlService.CompletionItemKind.File: return mItemKind.File;
-		case htmlService.CompletionItemKind.Reference: return mItemKind.Reference;
-	}
-	return mItemKind.Property;
-}
-
-function fromCompletionItemKind(kind: monaco.languages.CompletionItemKind): htmlService.CompletionItemKind {
-	const mItemKind = monaco.languages.CompletionItemKind;
-
-	switch (kind) {
-		case mItemKind.Text: return htmlService.CompletionItemKind.Text;
-		case mItemKind.Method: return htmlService.CompletionItemKind.Method;
-		case mItemKind.Function: return htmlService.CompletionItemKind.Function;
-		case mItemKind.Constructor: return htmlService.CompletionItemKind.Constructor;
-		case mItemKind.Field: return htmlService.CompletionItemKind.Field;
-		case mItemKind.Variable: return htmlService.CompletionItemKind.Variable;
-		case mItemKind.Class: return htmlService.CompletionItemKind.Class;
-		case mItemKind.Interface: return htmlService.CompletionItemKind.Interface;
-		case mItemKind.Module: return htmlService.CompletionItemKind.Module;
-		case mItemKind.Property: return htmlService.CompletionItemKind.Property;
-		case mItemKind.Unit: return htmlService.CompletionItemKind.Unit;
-		case mItemKind.Value: return htmlService.CompletionItemKind.Value;
-		case mItemKind.Enum: return htmlService.CompletionItemKind.Enum;
-		case mItemKind.Keyword: return htmlService.CompletionItemKind.Keyword;
-		case mItemKind.Snippet: return htmlService.CompletionItemKind.Snippet;
-		case mItemKind.Color: return htmlService.CompletionItemKind.Color;
-		case mItemKind.File: return htmlService.CompletionItemKind.File;
-		case mItemKind.Reference: return htmlService.CompletionItemKind.Reference;
-	}
-	return htmlService.CompletionItemKind.Property;
-}
-
-function toTextEdit(textEdit: htmlService.TextEdit): monaco.editor.ISingleEditOperation {
-	if (!textEdit) {
-		return void 0;
-	}
-	return {
-		range: toRange(textEdit.range),
-		text: textEdit.newText
-	}
-}
-
-export class CompletionAdapter implements monaco.languages.CompletionItemProvider {
-
-	constructor(private _worker: WorkerAccessor) {
-	}
-
-	public get triggerCharacters(): string[] {
-		return ['.', ':', '<', '"', '=', '/'];
-	}
-
-	provideCompletionItems(model: monaco.editor.IReadOnlyModel, position: Position, context: monaco.languages.CompletionContext, token: CancellationToken): Promise<monaco.languages.CompletionList> {
-		const resource = model.uri;
-
-		return this._worker(resource).then(worker => {
-			return worker.doComplete(resource.toString(), fromPosition(position));
-		}).then(info => {
-			if (!info) {
-				return;
-			}
-			const wordInfo = model.getWordUntilPosition(position);
-			const wordRange = new Range(position.lineNumber, wordInfo.startColumn, position.lineNumber, wordInfo.endColumn);
-
-			const items: monaco.languages.CompletionItem[] = info.items.map(entry => {
-				const item: monaco.languages.CompletionItem = {
-					label: entry.label,
-					insertText: entry.insertText || entry.label,
-					sortText: entry.sortText,
-					filterText: entry.filterText,
-					documentation: entry.documentation,
-					detail: entry.detail,
-					range: wordRange,
-					kind: toCompletionItemKind(entry.kind),
-				};
-				if (entry.textEdit) {
-					item.range = toRange(entry.textEdit.range);
-					item.insertText = entry.textEdit.newText;
-				}
-				if (entry.additionalTextEdits) {
-					item.additionalTextEdits = entry.additionalTextEdits.map(toTextEdit)
-				}
-				if (entry.insertTextFormat === htmlService.InsertTextFormat.Snippet) {
-					item.insertTextRules = monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet;
-				}
-				return item;
-			});
-
-			return {
-				isIncomplete: info.isIncomplete,
-				suggestions: items
-			};
-		});
-	}
-}
-
-// --- hover ------
-
-function isMarkupContent(thing: any): thing is htmlService.MarkupContent {
-	return thing && typeof thing === 'object' && typeof (<htmlService.MarkupContent>thing).kind === 'string';
-}
-
-function toMarkdownString(entry: htmlService.MarkupContent | htmlService.MarkedString): monaco.IMarkdownString {
-	if (typeof entry === 'string') {
-		return {
-			value: entry
-		};
-	}
-	if (isMarkupContent(entry)) {
-		if (entry.kind === 'plaintext') {
-			return {
-				value: entry.value.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
-			};
-		}
-		return {
-			value: entry.value
-		};
-	}
-
-	return { value: '```' + entry.language + '\n' + entry.value + '\n```\n' };
-}
-
-function toMarkedStringArray(contents: htmlService.MarkupContent | htmlService.MarkedString | htmlService.MarkedString[]): monaco.IMarkdownString[] {
-	if (!contents) {
-		return void 0;
-	}
-	if (Array.isArray(contents)) {
-		return contents.map(toMarkdownString);
-	}
-	return [toMarkdownString(contents)];
-}
-
-export class HoverAdapter implements monaco.languages.HoverProvider {
-
-	constructor(private _worker: WorkerAccessor) {
-	}
-
-	provideHover(model: monaco.editor.IReadOnlyModel, position: Position, token: CancellationToken): Promise<monaco.languages.Hover> {
-		let resource = model.uri;
-
-		return this._worker(resource).then(worker => {
-			return worker.doHover(resource.toString(), fromPosition(position));
-		}).then(info => {
-			if (!info) {
-				return;
-			}
-			return <monaco.languages.Hover>{
-				range: toRange(info.range),
-				contents: toMarkedStringArray(info.contents)
-			};
-		});
-	}
-}
-
-// --- document highlights ------
-
-function toHighlighKind(kind: htmlService.DocumentHighlightKind): monaco.languages.DocumentHighlightKind {
-	const mKind = monaco.languages.DocumentHighlightKind;
-
-	switch (kind) {
-		case htmlService.DocumentHighlightKind.Read: return mKind.Read;
-		case htmlService.DocumentHighlightKind.Write: return mKind.Write;
-		case htmlService.DocumentHighlightKind.Text: return mKind.Text;
-	}
-	return mKind.Text;
-}
-
-
-export class DocumentHighlightAdapter implements monaco.languages.DocumentHighlightProvider {
-
-	constructor(private _worker: WorkerAccessor) {
-	}
-
-	public provideDocumentHighlights(model: monaco.editor.IReadOnlyModel, position: Position, token: CancellationToken): Promise<monaco.languages.DocumentHighlight[]> {
-		const resource = model.uri;
-
-		return this._worker(resource).then(worker => worker.findDocumentHighlights(resource.toString(), fromPosition(position))).then(items => {
-			if (!items) {
-				return;
-			}
-			return items.map(item => ({
-				range: toRange(item.range),
-				kind: toHighlighKind(item.kind)
-			}));
-		});
-	}
-}
-
-// --- document symbols ------
-
-function toSymbolKind(kind: htmlService.SymbolKind): monaco.languages.SymbolKind {
-	let mKind = monaco.languages.SymbolKind;
-
-	switch (kind) {
-		case htmlService.SymbolKind.File: return mKind.Array;
-		case htmlService.SymbolKind.Module: return mKind.Module;
-		case htmlService.SymbolKind.Namespace: return mKind.Namespace;
-		case htmlService.SymbolKind.Package: return mKind.Package;
-		case htmlService.SymbolKind.Class: return mKind.Class;
-		case htmlService.SymbolKind.Method: return mKind.Method;
-		case htmlService.SymbolKind.Property: return mKind.Property;
-		case htmlService.SymbolKind.Field: return mKind.Field;
-		case htmlService.SymbolKind.Constructor: return mKind.Constructor;
-		case htmlService.SymbolKind.Enum: return mKind.Enum;
-		case htmlService.SymbolKind.Interface: return mKind.Interface;
-		case htmlService.SymbolKind.Function: return mKind.Function;
-		case htmlService.SymbolKind.Variable: return mKind.Variable;
-		case htmlService.SymbolKind.Constant: return mKind.Constant;
-		case htmlService.SymbolKind.String: return mKind.String;
-		case htmlService.SymbolKind.Number: return mKind.Number;
-		case htmlService.SymbolKind.Boolean: return mKind.Boolean;
-		case htmlService.SymbolKind.Array: return mKind.Array;
-	}
-	return mKind.Function;
-}
-
-export class DocumentSymbolAdapter implements monaco.languages.DocumentSymbolProvider {
-
-	constructor(private _worker: WorkerAccessor) {
-	}
-
-	public provideDocumentSymbols(model: monaco.editor.IReadOnlyModel, token: CancellationToken): Promise<monaco.languages.DocumentSymbol[]> {
-		const resource = model.uri;
-
-		return this._worker(resource).then(worker => worker.findDocumentSymbols(resource.toString())).then(items => {
-			if (!items) {
-				return;
-			}
-			return items.map(item => ({
-				name: item.name,
-				detail: '',
-				containerName: item.containerName,
-				kind: toSymbolKind(item.kind),
-				tags: [],
-				range: toRange(item.location.range),
-				selectionRange: toRange(item.location.range)
-			}));
-		});
-	}
-}
-
-export class DocumentLinkAdapter implements monaco.languages.LinkProvider {
-
-	constructor(private _worker: WorkerAccessor) {
-	}
-
-	public provideLinks(model: monaco.editor.IReadOnlyModel, token: CancellationToken): Promise<monaco.languages.ILinksList> {
-		const resource = model.uri;
-
-		return this._worker(resource).then(worker => worker.findDocumentLinks(resource.toString())).then(items => {
-			if (!items) {
-				return;
-			}
-			return {
-				links: items.map(item => ({
-					range: toRange(item.range),
-					url: item.target
-				}))
-			};
-		});
-	}
-}
-
-
-function fromFormattingOptions(options: monaco.languages.FormattingOptions): htmlService.FormattingOptions {
-	return {
-		tabSize: options.tabSize,
-		insertSpaces: options.insertSpaces
-	};
-}
-
-export class DocumentFormattingEditProvider implements monaco.languages.DocumentFormattingEditProvider {
-
-	constructor(private _worker: WorkerAccessor) {
-	}
-
-	public provideDocumentFormattingEdits(model: monaco.editor.IReadOnlyModel, options: monaco.languages.FormattingOptions, token: CancellationToken): Promise<monaco.editor.ISingleEditOperation[]> {
-		const resource = model.uri;
-
-		return this._worker(resource).then(worker => {
-			return worker.format(resource.toString(), null, fromFormattingOptions(options)).then(edits => {
-				if (!edits || edits.length === 0) {
-					return;
-				}
-				return edits.map(toTextEdit);
-			});
-		});
-	}
-}
-
-export class DocumentRangeFormattingEditProvider implements monaco.languages.DocumentRangeFormattingEditProvider {
-
-	constructor(private _worker: WorkerAccessor) {
-	}
-
-	public provideDocumentRangeFormattingEdits(model: monaco.editor.IReadOnlyModel, range: Range, options: monaco.languages.FormattingOptions, token: CancellationToken): Promise<monaco.editor.ISingleEditOperation[]> {
-		const resource = model.uri;
-
-		return this._worker(resource).then(worker => {
-			return worker.format(resource.toString(), fromRange(range), fromFormattingOptions(options)).then(edits => {
-				if (!edits || edits.length === 0) {
-					return;
-				}
-				return edits.map(toTextEdit);
-			});
-		});
-	}
-}
-
-export class RenameAdapter implements monaco.languages.RenameProvider {
-
-	constructor(private _worker: WorkerAccessor) {
-	}
-
-	provideRenameEdits(model: monaco.editor.IReadOnlyModel, position: Position, newName: string, token: CancellationToken): Promise<monaco.languages.WorkspaceEdit> {
-		const resource = model.uri;
-
-		return this._worker(resource).then(worker => {
-			return worker.doRename(resource.toString(), fromPosition(position), newName);
-		}).then(edit => {
-			return toWorkspaceEdit(edit);
-		});
-	}
-}
-
-function toWorkspaceEdit(edit: htmlService.WorkspaceEdit): monaco.languages.WorkspaceEdit {
-	if (!edit || !edit.changes) {
-		return void 0;
-	}
-	let resourceEdits: monaco.languages.WorkspaceTextEdit[] = [];
-	for (let uri in edit.changes) {
-		const _uri = Uri.parse(uri);
-		for (let e of edit.changes[uri]) {
-			resourceEdits.push({
-				resource: _uri,
-				edit: {
-					range: toRange(e.range),
-					text: e.newText
-				}
-			});
-		}
-	}
-	return {
-		edits: resourceEdits
-	}
-}
-
-export class FoldingRangeAdapter implements monaco.languages.FoldingRangeProvider {
-
-	constructor(private _worker: WorkerAccessor) {
-	}
-
-	public provideFoldingRanges(model: monaco.editor.IReadOnlyModel, context: monaco.languages.FoldingContext, token: CancellationToken): Promise<monaco.languages.FoldingRange[]> {
-		const resource = model.uri;
-
-		return this._worker(resource).then(worker => worker.getFoldingRanges(resource.toString(), context)).then(ranges => {
-			if (!ranges) {
-				return;
-			}
-			return ranges.map(range => {
-				const result: monaco.languages.FoldingRange = {
-					start: range.startLine + 1,
-					end: range.endLine + 1
-				};
-				if (typeof range.kind !== 'undefined') {
-					result.kind = toFoldingRangeKind(<htmlService.FoldingRangeKind>range.kind);
-				}
-				return result;
-			});
-		});
-	}
-
-}
-
-function toFoldingRangeKind(kind: htmlService.FoldingRangeKind): monaco.languages.FoldingRangeKind {
-	switch (kind) {
-		case htmlService.FoldingRangeKind.Comment: return monaco.languages.FoldingRangeKind.Comment;
-		case htmlService.FoldingRangeKind.Imports: return monaco.languages.FoldingRangeKind.Imports;
-		case htmlService.FoldingRangeKind.Region: return monaco.languages.FoldingRangeKind.Region;
-	}
-}
-
-export class SelectionRangeAdapter implements monaco.languages.SelectionRangeProvider {
-
-	constructor(private _worker: WorkerAccessor) {
-	}
-
-	public provideSelectionRanges(model: monaco.editor.IReadOnlyModel, positions: Position[], token: CancellationToken): Promise<monaco.languages.SelectionRange[][]> {
-		const resource = model.uri;
-
-		return this._worker(resource).then(worker => worker.getSelectionRanges(resource.toString(), positions.map(fromPosition))).then(selectionRanges => {
-			if (!selectionRanges) {
-				return;
-			}
-			return selectionRanges.map(selectionRange => {
-				const result: monaco.languages.SelectionRange[] = [];
-				while (selectionRange) {
-					result.push({ range: toRange(selectionRange.range) });
-					selectionRange = selectionRange.parent;
-				}
-				return result;
-			});
-		});
-	}
-
-}
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+
+import { LanguageServiceDefaultsImpl } from './monaco.contribution';
+import { HTMLWorker } from './htmlWorker';
+
+import * as htmlService from 'vscode-html-languageservice';
+
+import Uri = monaco.Uri;
+import Position = monaco.Position;
+import Range = monaco.Range;
+import CancellationToken = monaco.CancellationToken;
+import IDisposable = monaco.IDisposable;
+
+export interface WorkerAccessor {
+	(...more: Uri[]): Promise<HTMLWorker>;
+}
+
+// --- diagnostics --- ---
+
+export class DiagnosticsAdapter {
+	private _disposables: IDisposable[] = [];
+	private _listener: { [uri: string]: IDisposable } = Object.create(null);
+
+	constructor(
+		private _languageId: string,
+		private _worker: WorkerAccessor,
+		defaults: LanguageServiceDefaultsImpl
+	) {
+		const onModelAdd = (model: monaco.editor.IModel): void => {
+			const modeId = model.getModeId();
+			if (modeId !== this._languageId) {
+				return;
+			}
+
+			let handle: number;
+			this._listener[model.uri.toString()] = model.onDidChangeContent(() => {
+				clearTimeout(handle);
+				handle = setTimeout(() => this._doValidate(model.uri, modeId), 500);
+			});
+
+			this._doValidate(model.uri, modeId);
+		};
+
+		const onModelRemoved = (model: monaco.editor.IModel): void => {
+			monaco.editor.setModelMarkers(model, this._languageId, []);
+			const uriStr = model.uri.toString();
+			const listener = this._listener[uriStr];
+			if (listener) {
+				listener.dispose();
+				delete this._listener[uriStr];
+			}
+		};
+
+		this._disposables.push(monaco.editor.onDidCreateModel(onModelAdd));
+		this._disposables.push(
+			monaco.editor.onWillDisposeModel((model) => {
+				onModelRemoved(model);
+			})
+		);
+		this._disposables.push(
+			monaco.editor.onDidChangeModelLanguage((event) => {
+				onModelRemoved(event.model);
+				onModelAdd(event.model);
+			})
+		);
+
+		this._disposables.push(
+			defaults.onDidChange((_) => {
+				monaco.editor.getModels().forEach((model) => {
+					if (model.getModeId() === this._languageId) {
+						onModelRemoved(model);
+						onModelAdd(model);
+					}
+				});
+			})
+		);
+
+		this._disposables.push({
+			dispose: () => {
+				for (const key in this._listener) {
+					this._listener[key].dispose();
+				}
+			}
+		});
+
+		monaco.editor.getModels().forEach(onModelAdd);
+	}
+
+	public dispose(): void {
+		this._disposables.forEach((d) => d && d.dispose());
+		this._disposables = [];
+	}
+
+	private _doValidate(resource: Uri, languageId: string): void {
+		this._worker(resource)
+			.then((worker) => {
+				return worker.doValidation(resource.toString()).then((diagnostics) => {
+					const markers = diagnostics.map((d) => toDiagnostics(resource, d));
+					monaco.editor.setModelMarkers(
+						monaco.editor.getModel(resource),
+						languageId,
+						markers
+					);
+				});
+			})
+			.then(undefined, (err) => {
+				console.error(err);
+			});
+	}
+}
+
+function toSeverity(lsSeverity: number): monaco.MarkerSeverity {
+	switch (lsSeverity) {
+		case htmlService.DiagnosticSeverity.Error:
+			return monaco.MarkerSeverity.Error;
+		case htmlService.DiagnosticSeverity.Warning:
+			return monaco.MarkerSeverity.Warning;
+		case htmlService.DiagnosticSeverity.Information:
+			return monaco.MarkerSeverity.Info;
+		case htmlService.DiagnosticSeverity.Hint:
+			return monaco.MarkerSeverity.Hint;
+		default:
+			return monaco.MarkerSeverity.Info;
+	}
+}
+
+function toDiagnostics(
+	resource: Uri,
+	diag: htmlService.Diagnostic
+): monaco.editor.IMarkerData {
+	const code =
+		typeof diag.code === 'number' ? String(diag.code) : <string>diag.code;
+
+	return {
+		severity: toSeverity(diag.severity),
+		startLineNumber: diag.range.start.line + 1,
+		startColumn: diag.range.start.character + 1,
+		endLineNumber: diag.range.end.line + 1,
+		endColumn: diag.range.end.character + 1,
+		message: diag.message,
+		code: code,
+		source: diag.source
+	};
+}
+
+// --- completion ------
+
+function fromPosition(position: Position): htmlService.Position {
+	if (!position) {
+		return void 0;
+	}
+	return { character: position.column - 1, line: position.lineNumber - 1 };
+}
+
+function fromRange(range: Range): htmlService.Range {
+	if (!range) {
+		return void 0;
+	}
+	return {
+		start: fromPosition(range.getStartPosition()),
+		end: fromPosition(range.getEndPosition())
+	};
+}
+
+function toRange(range: htmlService.Range): Range {
+	if (!range) {
+		return void 0;
+	}
+	return new Range(
+		range.start.line + 1,
+		range.start.character + 1,
+		range.end.line + 1,
+		range.end.character + 1
+	);
+}
+
+function toCompletionItemKind(
+	kind: number
+): monaco.languages.CompletionItemKind {
+	const mItemKind = monaco.languages.CompletionItemKind;
+
+	switch (kind) {
+		case htmlService.CompletionItemKind.Text:
+			return mItemKind.Text;
+		case htmlService.CompletionItemKind.Method:
+			return mItemKind.Method;
+		case htmlService.CompletionItemKind.Function:
+			return mItemKind.Function;
+		case htmlService.CompletionItemKind.Constructor:
+			return mItemKind.Constructor;
+		case htmlService.CompletionItemKind.Field:
+			return mItemKind.Field;
+		case htmlService.CompletionItemKind.Variable:
+			return mItemKind.Variable;
+		case htmlService.CompletionItemKind.Class:
+			return mItemKind.Class;
+		case htmlService.CompletionItemKind.Interface:
+			return mItemKind.Interface;
+		case htmlService.CompletionItemKind.Module:
+			return mItemKind.Module;
+		case htmlService.CompletionItemKind.Property:
+			return mItemKind.Property;
+		case htmlService.CompletionItemKind.Unit:
+			return mItemKind.Unit;
+		case htmlService.CompletionItemKind.Value:
+			return mItemKind.Value;
+		case htmlService.CompletionItemKind.Enum:
+			return mItemKind.Enum;
+		case htmlService.CompletionItemKind.Keyword:
+			return mItemKind.Keyword;
+		case htmlService.CompletionItemKind.Snippet:
+			return mItemKind.Snippet;
+		case htmlService.CompletionItemKind.Color:
+			return mItemKind.Color;
+		case htmlService.CompletionItemKind.File:
+			return mItemKind.File;
+		case htmlService.CompletionItemKind.Reference:
+			return mItemKind.Reference;
+	}
+	return mItemKind.Property;
+}
+
+function fromCompletionItemKind(
+	kind: monaco.languages.CompletionItemKind
+): htmlService.CompletionItemKind {
+	const mItemKind = monaco.languages.CompletionItemKind;
+
+	switch (kind) {
+		case mItemKind.Text:
+			return htmlService.CompletionItemKind.Text;
+		case mItemKind.Method:
+			return htmlService.CompletionItemKind.Method;
+		case mItemKind.Function:
+			return htmlService.CompletionItemKind.Function;
+		case mItemKind.Constructor:
+			return htmlService.CompletionItemKind.Constructor;
+		case mItemKind.Field:
+			return htmlService.CompletionItemKind.Field;
+		case mItemKind.Variable:
+			return htmlService.CompletionItemKind.Variable;
+		case mItemKind.Class:
+			return htmlService.CompletionItemKind.Class;
+		case mItemKind.Interface:
+			return htmlService.CompletionItemKind.Interface;
+		case mItemKind.Module:
+			return htmlService.CompletionItemKind.Module;
+		case mItemKind.Property:
+			return htmlService.CompletionItemKind.Property;
+		case mItemKind.Unit:
+			return htmlService.CompletionItemKind.Unit;
+		case mItemKind.Value:
+			return htmlService.CompletionItemKind.Value;
+		case mItemKind.Enum:
+			return htmlService.CompletionItemKind.Enum;
+		case mItemKind.Keyword:
+			return htmlService.CompletionItemKind.Keyword;
+		case mItemKind.Snippet:
+			return htmlService.CompletionItemKind.Snippet;
+		case mItemKind.Color:
+			return htmlService.CompletionItemKind.Color;
+		case mItemKind.File:
+			return htmlService.CompletionItemKind.File;
+		case mItemKind.Reference:
+			return htmlService.CompletionItemKind.Reference;
+	}
+	return htmlService.CompletionItemKind.Property;
+}
+
+function toTextEdit(
+	textEdit: htmlService.TextEdit
+): monaco.editor.ISingleEditOperation {
+	if (!textEdit) {
+		return void 0;
+	}
+	return {
+		range: toRange(textEdit.range),
+		text: textEdit.newText
+	};
+}
+
+export class CompletionAdapter
+	implements monaco.languages.CompletionItemProvider {
+	constructor(private _worker: WorkerAccessor) {}
+
+	public get triggerCharacters(): string[] {
+		return ['.', ':', '<', '"', '=', '/'];
+	}
+
+	provideCompletionItems(
+		model: monaco.editor.IReadOnlyModel,
+		position: Position,
+		context: monaco.languages.CompletionContext,
+		token: CancellationToken
+	): Promise<monaco.languages.CompletionList> {
+		const resource = model.uri;
+
+		return this._worker(resource)
+			.then((worker) => {
+				return worker.doComplete(resource.toString(), fromPosition(position));
+			})
+			.then((info) => {
+				if (!info) {
+					return;
+				}
+				const wordInfo = model.getWordUntilPosition(position);
+				const wordRange = new Range(
+					position.lineNumber,
+					wordInfo.startColumn,
+					position.lineNumber,
+					wordInfo.endColumn
+				);
+
+				const items: monaco.languages.CompletionItem[] = info.items.map(
+					(entry) => {
+						const item: monaco.languages.CompletionItem = {
+							label: entry.label,
+							insertText: entry.insertText || entry.label,
+							sortText: entry.sortText,
+							filterText: entry.filterText,
+							documentation: entry.documentation,
+							detail: entry.detail,
+							range: wordRange,
+							kind: toCompletionItemKind(entry.kind)
+						};
+						if (entry.textEdit) {
+							item.range = toRange(entry.textEdit.range);
+							item.insertText = entry.textEdit.newText;
+						}
+						if (entry.additionalTextEdits) {
+							item.additionalTextEdits = entry.additionalTextEdits.map(
+								toTextEdit
+							);
+						}
+						if (
+							entry.insertTextFormat === htmlService.InsertTextFormat.Snippet
+						) {
+							item.insertTextRules =
+								monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet;
+						}
+						return item;
+					}
+				);
+
+				return {
+					isIncomplete: info.isIncomplete,
+					suggestions: items
+				};
+			});
+	}
+}
+
+// --- hover ------
+
+function isMarkupContent(thing: any): thing is htmlService.MarkupContent {
+	return (
+		thing &&
+		typeof thing === 'object' &&
+		typeof (<htmlService.MarkupContent>thing).kind === 'string'
+	);
+}
+
+function toMarkdownString(
+	entry: htmlService.MarkupContent | htmlService.MarkedString
+): monaco.IMarkdownString {
+	if (typeof entry === 'string') {
+		return {
+			value: entry
+		};
+	}
+	if (isMarkupContent(entry)) {
+		if (entry.kind === 'plaintext') {
+			return {
+				value: entry.value.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
+			};
+		}
+		return {
+			value: entry.value
+		};
+	}
+
+	return { value: '```' + entry.language + '\n' + entry.value + '\n```\n' };
+}
+
+function toMarkedStringArray(
+	contents:
+		| htmlService.MarkupContent
+		| htmlService.MarkedString
+		| htmlService.MarkedString[]
+): monaco.IMarkdownString[] {
+	if (!contents) {
+		return void 0;
+	}
+	if (Array.isArray(contents)) {
+		return contents.map(toMarkdownString);
+	}
+	return [toMarkdownString(contents)];
+}
+
+export class HoverAdapter implements monaco.languages.HoverProvider {
+	constructor(private _worker: WorkerAccessor) {}
+
+	provideHover(
+		model: monaco.editor.IReadOnlyModel,
+		position: Position,
+		token: CancellationToken
+	): Promise<monaco.languages.Hover> {
+		let resource = model.uri;
+
+		return this._worker(resource)
+			.then((worker) => {
+				return worker.doHover(resource.toString(), fromPosition(position));
+			})
+			.then((info) => {
+				if (!info) {
+					return;
+				}
+				return <monaco.languages.Hover>{
+					range: toRange(info.range),
+					contents: toMarkedStringArray(info.contents)
+				};
+			});
+	}
+}
+
+// --- document highlights ------
+
+function toHighlighKind(
+	kind: htmlService.DocumentHighlightKind
+): monaco.languages.DocumentHighlightKind {
+	const mKind = monaco.languages.DocumentHighlightKind;
+
+	switch (kind) {
+		case htmlService.DocumentHighlightKind.Read:
+			return mKind.Read;
+		case htmlService.DocumentHighlightKind.Write:
+			return mKind.Write;
+		case htmlService.DocumentHighlightKind.Text:
+			return mKind.Text;
+	}
+	return mKind.Text;
+}
+
+export class DocumentHighlightAdapter
+	implements monaco.languages.DocumentHighlightProvider {
+	constructor(private _worker: WorkerAccessor) {}
+
+	public provideDocumentHighlights(
+		model: monaco.editor.IReadOnlyModel,
+		position: Position,
+		token: CancellationToken
+	): Promise<monaco.languages.DocumentHighlight[]> {
+		const resource = model.uri;
+
+		return this._worker(resource)
+			.then((worker) =>
+				worker.findDocumentHighlights(
+					resource.toString(),
+					fromPosition(position)
+				)
+			)
+			.then((items) => {
+				if (!items) {
+					return;
+				}
+				return items.map((item) => ({
+					range: toRange(item.range),
+					kind: toHighlighKind(item.kind)
+				}));
+			});
+	}
+}
+
+// --- document symbols ------
+
+function toSymbolKind(
+	kind: htmlService.SymbolKind
+): monaco.languages.SymbolKind {
+	let mKind = monaco.languages.SymbolKind;
+
+	switch (kind) {
+		case htmlService.SymbolKind.File:
+			return mKind.Array;
+		case htmlService.SymbolKind.Module:
+			return mKind.Module;
+		case htmlService.SymbolKind.Namespace:
+			return mKind.Namespace;
+		case htmlService.SymbolKind.Package:
+			return mKind.Package;
+		case htmlService.SymbolKind.Class:
+			return mKind.Class;
+		case htmlService.SymbolKind.Method:
+			return mKind.Method;
+		case htmlService.SymbolKind.Property:
+			return mKind.Property;
+		case htmlService.SymbolKind.Field:
+			return mKind.Field;
+		case htmlService.SymbolKind.Constructor:
+			return mKind.Constructor;
+		case htmlService.SymbolKind.Enum:
+			return mKind.Enum;
+		case htmlService.SymbolKind.Interface:
+			return mKind.Interface;
+		case htmlService.SymbolKind.Function:
+			return mKind.Function;
+		case htmlService.SymbolKind.Variable:
+			return mKind.Variable;
+		case htmlService.SymbolKind.Constant:
+			return mKind.Constant;
+		case htmlService.SymbolKind.String:
+			return mKind.String;
+		case htmlService.SymbolKind.Number:
+			return mKind.Number;
+		case htmlService.SymbolKind.Boolean:
+			return mKind.Boolean;
+		case htmlService.SymbolKind.Array:
+			return mKind.Array;
+	}
+	return mKind.Function;
+}
+
+export class DocumentSymbolAdapter
+	implements monaco.languages.DocumentSymbolProvider {
+	constructor(private _worker: WorkerAccessor) {}
+
+	public provideDocumentSymbols(
+		model: monaco.editor.IReadOnlyModel,
+		token: CancellationToken
+	): Promise<monaco.languages.DocumentSymbol[]> {
+		const resource = model.uri;
+
+		return this._worker(resource)
+			.then((worker) => worker.findDocumentSymbols(resource.toString()))
+			.then((items) => {
+				if (!items) {
+					return;
+				}
+				return items.map((item) => ({
+					name: item.name,
+					detail: '',
+					containerName: item.containerName,
+					kind: toSymbolKind(item.kind),
+					tags: [],
+					range: toRange(item.location.range),
+					selectionRange: toRange(item.location.range)
+				}));
+			});
+	}
+}
+
+export class DocumentLinkAdapter implements monaco.languages.LinkProvider {
+	constructor(private _worker: WorkerAccessor) {}
+
+	public provideLinks(
+		model: monaco.editor.IReadOnlyModel,
+		token: CancellationToken
+	): Promise<monaco.languages.ILinksList> {
+		const resource = model.uri;
+
+		return this._worker(resource)
+			.then((worker) => worker.findDocumentLinks(resource.toString()))
+			.then((items) => {
+				if (!items) {
+					return;
+				}
+				return {
+					links: items.map((item) => ({
+						range: toRange(item.range),
+						url: item.target
+					}))
+				};
+			});
+	}
+}
+
+function fromFormattingOptions(
+	options: monaco.languages.FormattingOptions
+): htmlService.FormattingOptions {
+	return {
+		tabSize: options.tabSize,
+		insertSpaces: options.insertSpaces
+	};
+}
+
+export class DocumentFormattingEditProvider
+	implements monaco.languages.DocumentFormattingEditProvider {
+	constructor(private _worker: WorkerAccessor) {}
+
+	public provideDocumentFormattingEdits(
+		model: monaco.editor.IReadOnlyModel,
+		options: monaco.languages.FormattingOptions,
+		token: CancellationToken
+	): Promise<monaco.editor.ISingleEditOperation[]> {
+		const resource = model.uri;
+
+		return this._worker(resource).then((worker) => {
+			return worker
+				.format(resource.toString(), null, fromFormattingOptions(options))
+				.then((edits) => {
+					if (!edits || edits.length === 0) {
+						return;
+					}
+					return edits.map(toTextEdit);
+				});
+		});
+	}
+}
+
+export class DocumentRangeFormattingEditProvider
+	implements monaco.languages.DocumentRangeFormattingEditProvider {
+	constructor(private _worker: WorkerAccessor) {}
+
+	public provideDocumentRangeFormattingEdits(
+		model: monaco.editor.IReadOnlyModel,
+		range: Range,
+		options: monaco.languages.FormattingOptions,
+		token: CancellationToken
+	): Promise<monaco.editor.ISingleEditOperation[]> {
+		const resource = model.uri;
+
+		return this._worker(resource).then((worker) => {
+			return worker
+				.format(
+					resource.toString(),
+					fromRange(range),
+					fromFormattingOptions(options)
+				)
+				.then((edits) => {
+					if (!edits || edits.length === 0) {
+						return;
+					}
+					return edits.map(toTextEdit);
+				});
+		});
+	}
+}
+
+export class RenameAdapter implements monaco.languages.RenameProvider {
+	constructor(private _worker: WorkerAccessor) {}
+
+	provideRenameEdits(
+		model: monaco.editor.IReadOnlyModel,
+		position: Position,
+		newName: string,
+		token: CancellationToken
+	): Promise<monaco.languages.WorkspaceEdit> {
+		const resource = model.uri;
+
+		return this._worker(resource)
+			.then((worker) => {
+				return worker.doRename(
+					resource.toString(),
+					fromPosition(position),
+					newName
+				);
+			})
+			.then((edit) => {
+				return toWorkspaceEdit(edit);
+			});
+	}
+}
+
+function toWorkspaceEdit(
+	edit: htmlService.WorkspaceEdit
+): monaco.languages.WorkspaceEdit {
+	if (!edit || !edit.changes) {
+		return void 0;
+	}
+	let resourceEdits: monaco.languages.WorkspaceTextEdit[] = [];
+	for (let uri in edit.changes) {
+		const _uri = Uri.parse(uri);
+		for (let e of edit.changes[uri]) {
+			resourceEdits.push({
+				resource: _uri,
+				edit: {
+					range: toRange(e.range),
+					text: e.newText
+				}
+			});
+		}
+	}
+	return {
+		edits: resourceEdits
+	};
+}
+
+export class FoldingRangeAdapter
+	implements monaco.languages.FoldingRangeProvider {
+	constructor(private _worker: WorkerAccessor) {}
+
+	public provideFoldingRanges(
+		model: monaco.editor.IReadOnlyModel,
+		context: monaco.languages.FoldingContext,
+		token: CancellationToken
+	): Promise<monaco.languages.FoldingRange[]> {
+		const resource = model.uri;
+
+		return this._worker(resource)
+			.then((worker) => worker.getFoldingRanges(resource.toString(), context))
+			.then((ranges) => {
+				if (!ranges) {
+					return;
+				}
+				return ranges.map((range) => {
+					const result: monaco.languages.FoldingRange = {
+						start: range.startLine + 1,
+						end: range.endLine + 1
+					};
+					if (typeof range.kind !== 'undefined') {
+						result.kind = toFoldingRangeKind(
+							<htmlService.FoldingRangeKind>range.kind
+						);
+					}
+					return result;
+				});
+			});
+	}
+}
+
+function toFoldingRangeKind(
+	kind: htmlService.FoldingRangeKind
+): monaco.languages.FoldingRangeKind {
+	switch (kind) {
+		case htmlService.FoldingRangeKind.Comment:
+			return monaco.languages.FoldingRangeKind.Comment;
+		case htmlService.FoldingRangeKind.Imports:
+			return monaco.languages.FoldingRangeKind.Imports;
+		case htmlService.FoldingRangeKind.Region:
+			return monaco.languages.FoldingRangeKind.Region;
+	}
+}
+
+export class SelectionRangeAdapter
+	implements monaco.languages.SelectionRangeProvider {
+	constructor(private _worker: WorkerAccessor) {}
+
+	public provideSelectionRanges(
+		model: monaco.editor.IReadOnlyModel,
+		positions: Position[],
+		token: CancellationToken
+	): Promise<monaco.languages.SelectionRange[][]> {
+		const resource = model.uri;
+
+		return this._worker(resource)
+			.then((worker) =>
+				worker.getSelectionRanges(
+					resource.toString(),
+					positions.map(fromPosition)
+				)
+			)
+			.then((selectionRanges) => {
+				if (!selectionRanges) {
+					return;
+				}
+				return selectionRanges.map((selectionRange) => {
+					const result: monaco.languages.SelectionRange[] = [];
+					while (selectionRange) {
+						result.push({ range: toRange(selectionRange.range) });
+						selectionRange = selectionRange.parent;
+					}
+					return result;
+				});
+			});
+	}
+}

+ 156 - 133
src/monaco.contribution.ts

@@ -1,133 +1,156 @@
-/*---------------------------------------------------------------------------------------------
- *  Copyright (c) Microsoft Corporation. All rights reserved.
- *  Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import * as mode from './htmlMode';
-
-import Emitter = monaco.Emitter;
-import IEvent = monaco.IEvent;
-
-// --- HTML configuration and defaults ---------
-
-export class LanguageServiceDefaultsImpl implements monaco.languages.html.LanguageServiceDefaults {
-
-	private _onDidChange = new Emitter<monaco.languages.html.LanguageServiceDefaults>();
-	private _options: monaco.languages.html.Options;
-	private _modeConfiguration: monaco.languages.html.ModeConfiguration;
-	private _languageId: string;
-
-	constructor(languageId: string, options: monaco.languages.html.Options, modeConfiguration: monaco.languages.html.ModeConfiguration) {
-		this._languageId = languageId;
-		this.setOptions(options);
-		this.setModeConfiguration(modeConfiguration);
-	}
-
-	get onDidChange(): IEvent<monaco.languages.html.LanguageServiceDefaults> {
-		return this._onDidChange.event;
-	}
-
-	get languageId(): string {
-		return this._languageId;
-	}
-
-	get options(): monaco.languages.html.Options {
-		return this._options;
-	}
-
-	get modeConfiguration(): monaco.languages.html.ModeConfiguration {
-		return this._modeConfiguration;
-	}
-
-	setOptions(options: monaco.languages.html.Options): void {
-		this._options = options || Object.create(null);
-		this._onDidChange.fire(this);
-	}
-
-	setModeConfiguration(modeConfiguration: monaco.languages.html.ModeConfiguration): void {
-		this._modeConfiguration = modeConfiguration || Object.create(null);
-		this._onDidChange.fire(this);
-	};
-}
-
-const formatDefaults: Required<monaco.languages.html.HTMLFormatConfiguration> = {
-	tabSize: 4,
-	insertSpaces: false,
-	wrapLineLength: 120,
-	unformatted: 'default": "a, abbr, acronym, b, bdo, big, br, button, cite, code, dfn, em, i, img, input, kbd, label, map, object, q, samp, select, small, span, strong, sub, sup, textarea, tt, var',
-	contentUnformatted: 'pre',
-	indentInnerHtml: false,
-	preserveNewLines: true,
-	maxPreserveNewLines: null,
-	indentHandlebars: false,
-	endWithNewline: false,
-	extraLiners: 'head, body, /html',
-	wrapAttributes: 'auto'
-};
-
-const htmlOptionsDefault: Required<monaco.languages.html.Options> = {
-	format: formatDefaults,
-	suggest: { html5: true, angular1: true, ionic: true }
-}
-
-const handlebarOptionsDefault: Required<monaco.languages.html.Options> = {
-	format: formatDefaults,
-	suggest: { html5: true }
-}
-
-const razorOptionsDefault: Required<monaco.languages.html.Options> = {
-	format: formatDefaults,
-	suggest: { html5: true, razor: true }
-}
-
-function getConfigurationDefault(languageId: string): Required<monaco.languages.html.ModeConfiguration> {
-	return {
-		completionItems: true,
-		hovers: true,
-		documentSymbols: true,
-		links: true,
-		documentHighlights: true,
-		rename: true,
-		colors: true,
-		foldingRanges: true,
-		selectionRanges: true,
-		diagnostics: languageId === htmlLanguageId, // turned off for Razor and Handlebar
-		documentFormattingEdits: languageId === htmlLanguageId, // turned off for Razor and Handlebar
-		documentRangeFormattingEdits: languageId === htmlLanguageId // turned off for Razor and Handlebar
-	};
-}
-
-const htmlLanguageId = 'html';
-const handlebarsLanguageId = 'handlebars';
-const razorLanguageId = 'razor';
-
-const htmlDefaults = new LanguageServiceDefaultsImpl(htmlLanguageId, htmlOptionsDefault, getConfigurationDefault(htmlLanguageId));
-const handlebarDefaults = new LanguageServiceDefaultsImpl(handlebarsLanguageId, handlebarOptionsDefault, getConfigurationDefault(handlebarsLanguageId));
-const razorDefaults = new LanguageServiceDefaultsImpl(razorLanguageId, razorOptionsDefault, getConfigurationDefault(razorLanguageId));
-
-// Export API
-function createAPI(): typeof monaco.languages.html {
-	return {
-		htmlDefaults: htmlDefaults,
-		razorDefaults: razorDefaults,
-		handlebarDefaults: handlebarDefaults
-	}
-}
-monaco.languages.html = createAPI();
-
-// --- Registration to monaco editor ---
-
-function getMode(): Promise<typeof mode> {
-	return import('./htmlMode');
-}
-
-monaco.languages.onLanguage(htmlLanguageId, () => {
-	getMode().then(mode => mode.setupMode(htmlDefaults));
-});
-monaco.languages.onLanguage(handlebarsLanguageId, () => {
-	getMode().then(mode => mode.setupMode(handlebarDefaults));
-});
-monaco.languages.onLanguage(razorLanguageId, () => {
-	getMode().then(mode => mode.setupMode(razorDefaults));
-});
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+
+import * as mode from './htmlMode';
+
+import Emitter = monaco.Emitter;
+import IEvent = monaco.IEvent;
+
+// --- HTML configuration and defaults ---------
+
+export class LanguageServiceDefaultsImpl
+	implements monaco.languages.html.LanguageServiceDefaults {
+	private _onDidChange = new Emitter<
+		monaco.languages.html.LanguageServiceDefaults
+	>();
+	private _options: monaco.languages.html.Options;
+	private _modeConfiguration: monaco.languages.html.ModeConfiguration;
+	private _languageId: string;
+
+	constructor(
+		languageId: string,
+		options: monaco.languages.html.Options,
+		modeConfiguration: monaco.languages.html.ModeConfiguration
+	) {
+		this._languageId = languageId;
+		this.setOptions(options);
+		this.setModeConfiguration(modeConfiguration);
+	}
+
+	get onDidChange(): IEvent<monaco.languages.html.LanguageServiceDefaults> {
+		return this._onDidChange.event;
+	}
+
+	get languageId(): string {
+		return this._languageId;
+	}
+
+	get options(): monaco.languages.html.Options {
+		return this._options;
+	}
+
+	get modeConfiguration(): monaco.languages.html.ModeConfiguration {
+		return this._modeConfiguration;
+	}
+
+	setOptions(options: monaco.languages.html.Options): void {
+		this._options = options || Object.create(null);
+		this._onDidChange.fire(this);
+	}
+
+	setModeConfiguration(
+		modeConfiguration: monaco.languages.html.ModeConfiguration
+	): void {
+		this._modeConfiguration = modeConfiguration || Object.create(null);
+		this._onDidChange.fire(this);
+	}
+}
+
+const formatDefaults: Required<monaco.languages.html.HTMLFormatConfiguration> = {
+	tabSize: 4,
+	insertSpaces: false,
+	wrapLineLength: 120,
+	unformatted:
+		'default": "a, abbr, acronym, b, bdo, big, br, button, cite, code, dfn, em, i, img, input, kbd, label, map, object, q, samp, select, small, span, strong, sub, sup, textarea, tt, var',
+	contentUnformatted: 'pre',
+	indentInnerHtml: false,
+	preserveNewLines: true,
+	maxPreserveNewLines: null,
+	indentHandlebars: false,
+	endWithNewline: false,
+	extraLiners: 'head, body, /html',
+	wrapAttributes: 'auto'
+};
+
+const htmlOptionsDefault: Required<monaco.languages.html.Options> = {
+	format: formatDefaults,
+	suggest: { html5: true, angular1: true, ionic: true }
+};
+
+const handlebarOptionsDefault: Required<monaco.languages.html.Options> = {
+	format: formatDefaults,
+	suggest: { html5: true }
+};
+
+const razorOptionsDefault: Required<monaco.languages.html.Options> = {
+	format: formatDefaults,
+	suggest: { html5: true, razor: true }
+};
+
+function getConfigurationDefault(
+	languageId: string
+): Required<monaco.languages.html.ModeConfiguration> {
+	return {
+		completionItems: true,
+		hovers: true,
+		documentSymbols: true,
+		links: true,
+		documentHighlights: true,
+		rename: true,
+		colors: true,
+		foldingRanges: true,
+		selectionRanges: true,
+		diagnostics: languageId === htmlLanguageId, // turned off for Razor and Handlebar
+		documentFormattingEdits: languageId === htmlLanguageId, // turned off for Razor and Handlebar
+		documentRangeFormattingEdits: languageId === htmlLanguageId // turned off for Razor and Handlebar
+	};
+}
+
+const htmlLanguageId = 'html';
+const handlebarsLanguageId = 'handlebars';
+const razorLanguageId = 'razor';
+
+const htmlDefaults = new LanguageServiceDefaultsImpl(
+	htmlLanguageId,
+	htmlOptionsDefault,
+	getConfigurationDefault(htmlLanguageId)
+);
+const handlebarDefaults = new LanguageServiceDefaultsImpl(
+	handlebarsLanguageId,
+	handlebarOptionsDefault,
+	getConfigurationDefault(handlebarsLanguageId)
+);
+const razorDefaults = new LanguageServiceDefaultsImpl(
+	razorLanguageId,
+	razorOptionsDefault,
+	getConfigurationDefault(razorLanguageId)
+);
+
+// Export API
+function createAPI(): typeof monaco.languages.html {
+	return {
+		htmlDefaults: htmlDefaults,
+		razorDefaults: razorDefaults,
+		handlebarDefaults: handlebarDefaults
+	};
+}
+monaco.languages.html = createAPI();
+
+// --- Registration to monaco editor ---
+
+function getMode(): Promise<typeof mode> {
+	return import('./htmlMode');
+}
+
+monaco.languages.onLanguage(htmlLanguageId, () => {
+	getMode().then((mode) => mode.setupMode(htmlDefaults));
+});
+monaco.languages.onLanguage(handlebarsLanguageId, () => {
+	getMode().then((mode) => mode.setupMode(handlebarDefaults));
+});
+monaco.languages.onLanguage(razorLanguageId, () => {
+	getMode().then((mode) => mode.setupMode(razorDefaults));
+});

+ 6 - 3
src/monaco.d.ts

@@ -16,7 +16,11 @@ declare module monaco.languages.html {
 		readonly indentHandlebars: boolean;
 		readonly endWithNewline: boolean;
 		readonly extraLiners: string;
-		readonly wrapAttributes: 'auto' | 'force' | 'force-aligned' | 'force-expand-multiline';
+		readonly wrapAttributes:
+			| 'auto'
+			| 'force'
+			| 'force-aligned'
+			| 'force-expand-multiline';
 	}
 
 	export interface CompletionConfiguration {
@@ -94,7 +98,6 @@ declare module monaco.languages.html {
 		 * Defines whether the built-in documentRangeFormattingEdit provider is enabled.
 		 */
 		readonly documentRangeFormattingEdits?: boolean;
-
 	}
 
 	export interface LanguageServiceDefaults {
@@ -106,4 +109,4 @@ declare module monaco.languages.html {
 	export var htmlDefaults: LanguageServiceDefaults;
 	export var handlebarDefaults: LanguageServiceDefaults;
 	export var razorDefaults: LanguageServiceDefaults;
-}
+}

+ 13 - 13
src/tsconfig.esm.json

@@ -1,15 +1,15 @@
 {
-  "compilerOptions": {
-    "module": "esnext",
-    "moduleResolution": "node",
-    "outDir": "../out/esm",
-    "target": "es5",
-    "lib": [
-      "dom",
-      "es5",
-      "es2015.collection",
-      "es2015.promise",
-      "es2015.iterable"
-    ]
-  }
+	"compilerOptions": {
+		"module": "esnext",
+		"moduleResolution": "node",
+		"outDir": "../out/esm",
+		"target": "es5",
+		"lib": [
+			"dom",
+			"es5",
+			"es2015.collection",
+			"es2015.promise",
+			"es2015.iterable"
+		]
+	}
 }

+ 13 - 13
src/tsconfig.json

@@ -1,15 +1,15 @@
 {
-  "compilerOptions": {
-    "module": "amd",
-    "moduleResolution": "node",
-    "outDir": "../out/amd",
-    "target": "es5",
-    "lib": [
-      "dom",
-      "es5",
-      "es2015.collection",
-      "es2015.promise",
-      "es2015.iterable"
-    ]
-  }
+	"compilerOptions": {
+		"module": "amd",
+		"moduleResolution": "node",
+		"outDir": "../out/amd",
+		"target": "es5",
+		"lib": [
+			"dom",
+			"es5",
+			"es2015.collection",
+			"es2015.promise",
+			"es2015.iterable"
+		]
+	}
 }

+ 1 - 1
src/typings/refs.d.ts

@@ -2,4 +2,4 @@
  *  Copyright (c) Microsoft Corporation. All rights reserved.
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
-/// <reference path='../../node_modules/monaco-editor-core/monaco.d.ts'/>
+/// <reference path='../../node_modules/monaco-editor-core/monaco.d.ts'/>

+ 92 - 89
src/workerManager.ts

@@ -1,89 +1,92 @@
-/*---------------------------------------------------------------------------------------------
- *  Copyright (c) Microsoft Corporation. All rights reserved.
- *  Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-import { LanguageServiceDefaultsImpl } from './monaco.contribution';
-import { HTMLWorker } from './htmlWorker';
-
-import IDisposable = monaco.IDisposable;
-import Uri = monaco.Uri;
-
-const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000; // 2min
-
-export class WorkerManager {
-
-	private _defaults: LanguageServiceDefaultsImpl;
-	private _idleCheckInterval: number;
-	private _lastUsedTime: number;
-	private _configChangeListener: IDisposable;
-
-	private _worker: monaco.editor.MonacoWebWorker<HTMLWorker>;
-	private _client: Promise<HTMLWorker>;
-
-	constructor(defaults: LanguageServiceDefaultsImpl) {
-		this._defaults = defaults;
-		this._worker = null;
-		this._idleCheckInterval = setInterval(() => this._checkIfIdle(), 30 * 1000);
-		this._lastUsedTime = 0;
-		this._configChangeListener = this._defaults.onDidChange(() => this._stopWorker());
-	}
-
-	private _stopWorker(): void {
-		if (this._worker) {
-			this._worker.dispose();
-			this._worker = null;
-		}
-		this._client = null;
-	}
-
-	dispose(): void {
-		clearInterval(this._idleCheckInterval);
-		this._configChangeListener.dispose();
-		this._stopWorker();
-	}
-
-	private _checkIfIdle(): void {
-		if (!this._worker) {
-			return;
-		}
-		let timePassedSinceLastUsed = Date.now() - this._lastUsedTime;
-		if (timePassedSinceLastUsed > STOP_WHEN_IDLE_FOR) {
-			this._stopWorker();
-		}
-	}
-
-	private _getClient(): Promise<HTMLWorker> {
-		this._lastUsedTime = Date.now();
-
-		if (!this._client) {
-			this._worker = monaco.editor.createWebWorker<HTMLWorker>({
-
-				// module that exports the create() method and returns a `HTMLWorker` instance
-				moduleId: 'vs/language/html/htmlWorker',
-
-				// passed in to the create() method
-				createData: {
-					languageSettings: this._defaults.options,
-					languageId: this._defaults.languageId
-				},
-
-				label: this._defaults.languageId
-			});
-
-			this._client = <Promise<HTMLWorker>>this._worker.getProxy();
-		}
-
-		return this._client;
-	}
-
-	getLanguageServiceWorker(...resources: Uri[]): Promise<HTMLWorker> {
-		let _client: HTMLWorker;
-		return this._getClient().then((client) => {
-			_client = client
-		}).then(_ => {
-			return this._worker.withSyncedResources(resources)
-		}).then(_ => _client);
-	}
-}
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+
+import { LanguageServiceDefaultsImpl } from './monaco.contribution';
+import { HTMLWorker } from './htmlWorker';
+
+import IDisposable = monaco.IDisposable;
+import Uri = monaco.Uri;
+
+const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000; // 2min
+
+export class WorkerManager {
+	private _defaults: LanguageServiceDefaultsImpl;
+	private _idleCheckInterval: number;
+	private _lastUsedTime: number;
+	private _configChangeListener: IDisposable;
+
+	private _worker: monaco.editor.MonacoWebWorker<HTMLWorker>;
+	private _client: Promise<HTMLWorker>;
+
+	constructor(defaults: LanguageServiceDefaultsImpl) {
+		this._defaults = defaults;
+		this._worker = null;
+		this._idleCheckInterval = setInterval(() => this._checkIfIdle(), 30 * 1000);
+		this._lastUsedTime = 0;
+		this._configChangeListener = this._defaults.onDidChange(() =>
+			this._stopWorker()
+		);
+	}
+
+	private _stopWorker(): void {
+		if (this._worker) {
+			this._worker.dispose();
+			this._worker = null;
+		}
+		this._client = null;
+	}
+
+	dispose(): void {
+		clearInterval(this._idleCheckInterval);
+		this._configChangeListener.dispose();
+		this._stopWorker();
+	}
+
+	private _checkIfIdle(): void {
+		if (!this._worker) {
+			return;
+		}
+		let timePassedSinceLastUsed = Date.now() - this._lastUsedTime;
+		if (timePassedSinceLastUsed > STOP_WHEN_IDLE_FOR) {
+			this._stopWorker();
+		}
+	}
+
+	private _getClient(): Promise<HTMLWorker> {
+		this._lastUsedTime = Date.now();
+
+		if (!this._client) {
+			this._worker = monaco.editor.createWebWorker<HTMLWorker>({
+				// module that exports the create() method and returns a `HTMLWorker` instance
+				moduleId: 'vs/language/html/htmlWorker',
+
+				// passed in to the create() method
+				createData: {
+					languageSettings: this._defaults.options,
+					languageId: this._defaults.languageId
+				},
+
+				label: this._defaults.languageId
+			});
+
+			this._client = <Promise<HTMLWorker>>this._worker.getProxy();
+		}
+
+		return this._client;
+	}
+
+	getLanguageServiceWorker(...resources: Uri[]): Promise<HTMLWorker> {
+		let _client: HTMLWorker;
+		return this._getClient()
+			.then((client) => {
+				_client = client;
+			})
+			.then((_) => {
+				return this._worker.withSyncedResources(resources);
+			})
+			.then((_) => _client);
+	}
+}

+ 81 - 73
test/index.html

@@ -1,73 +1,81 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
-	<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
-	<link rel="stylesheet" data-name="vs/editor/editor.main" href="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.css">
-</head>
-<body>
-
-<h2>Monaco Editor HTML test page</h2>
-<div id="container" style="width:800px;height:600px;border:1px solid grey"></div>
-
-<script>
-	// Loading basic-languages to get the html language definition
-	var paths = {
-		'vs/basic-languages': '../node_modules/monaco-languages/release/dev',
-		'vs/language/html': '../release/dev',
-		'vs': '../node_modules/monaco-editor-core/dev/vs'
-	};
-	if (document.location.protocol === 'http:') {
-		// Add support for running local http server
-		let testIndex = document.location.pathname.indexOf('/test/');
-		if (testIndex !== -1) {
-			let prefix = document.location.pathname.substr(0, testIndex);
-			paths['vs/language/html'] = prefix + '/release/dev';
-		}
-	}
-	var require = {
-		paths: paths
-	};
-</script>
-<script src="../node_modules/monaco-editor-core/dev/vs/loader.js"></script>
-<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.nls.js"></script>
-<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.js"></script>
-
-<script>
-	require([
-		'vs/basic-languages/monaco.contribution',
-		'vs/language/html/monaco.contribution'
-	], function() {
-		var editor = monaco.editor.create(document.getElementById('container'), {
-			value: [
-				'<!DOCTYPE HTML>',
-				'<!--',
-				'	Comments are overrated',
-				'-->',
-				'<html>',
-				'<head>',
-				'	<title>HTML Sample</title>',
-				'	<meta http-equiv="X-UA-Compatible" content="IE=edge">',
-				'	<style type="text/css">',
-				'		h1 {',
-				'			color: #CCA3A3;',
-				'		}',
-				'	</style>',
-				'	<script type="text/javascript">',
-				'		window.alert("I am a sample...");',
-				'		var x = 3;',
-				'	</'+'script>',
-				'</head>',
-				'<body>',
-				'	<h1>Heading No.1</h1>',
-				'	<input disabled type="button" value="Click me" />',
-				'</body>',
-				'</html>'
-			].join('\n'),
-			language: 'html'
-		});
-	});
-</script>
-
-</body>
-</html>
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
+		<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+		<link
+			rel="stylesheet"
+			data-name="vs/editor/editor.main"
+			href="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.css"
+		/>
+	</head>
+	<body>
+		<h2>Monaco Editor HTML test page</h2>
+		<div
+			id="container"
+			style="width: 800px; height: 600px; border: 1px solid grey"
+		></div>
+
+		<script>
+			// Loading basic-languages to get the html language definition
+			var paths = {
+				'vs/basic-languages': '../node_modules/monaco-languages/release/dev',
+				'vs/language/html': '../release/dev',
+				vs: '../node_modules/monaco-editor-core/dev/vs'
+			};
+			if (document.location.protocol === 'http:') {
+				// Add support for running local http server
+				let testIndex = document.location.pathname.indexOf('/test/');
+				if (testIndex !== -1) {
+					let prefix = document.location.pathname.substr(0, testIndex);
+					paths['vs/language/html'] = prefix + '/release/dev';
+				}
+			}
+			var require = {
+				paths: paths
+			};
+		</script>
+		<script src="../node_modules/monaco-editor-core/dev/vs/loader.js"></script>
+		<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.nls.js"></script>
+		<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.js"></script>
+
+		<script>
+			require([
+				'vs/basic-languages/monaco.contribution',
+				'vs/language/html/monaco.contribution'
+			], function () {
+				var editor = monaco.editor.create(
+					document.getElementById('container'),
+					{
+						value: [
+							'<!DOCTYPE HTML>',
+							'<!--',
+							'	Comments are overrated',
+							'-->',
+							'<html>',
+							'<head>',
+							'	<title>HTML Sample</title>',
+							'	<meta http-equiv="X-UA-Compatible" content="IE=edge">',
+							'	<style type="text/css">',
+							'		h1 {',
+							'			color: #CCA3A3;',
+							'		}',
+							'	</style>',
+							'	<script type="text/javascript">',
+							'		window.alert("I am a sample...");',
+							'		var x = 3;',
+							'	</' + 'script>',
+							'</head>',
+							'<body>',
+							'	<h1>Heading No.1</h1>',
+							'	<input disabled type="button" value="Click me" />',
+							'</body>',
+							'</html>'
+						].join('\n'),
+						language: 'html'
+					}
+				);
+			});
+		</script>
+	</body>
+</html>