diff --git a/README.md b/README.md
deleted file mode 100644
index 698dcb5..0000000
--- a/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# jupyter-launcher-shortcuts
-Launcher shortcuts for classic Jupyter Notebook & JupyterLab
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..6365cde
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,48 @@
+==========================
+Jupyter Launcher Shortcuts
+==========================
+
+Extensions for JupyterLab and classic Jupyter Notebook to add
+**user defined** 'launcher' shortcuts. Primarily useful in
+JupyterHub / Binder situations.
+
+For JupyterLab, they're added in the launcher interface.
+
+.. image:: labextension.png
+
+For classic Jupyter Notebook, they are added under the 'New' button
+
+.. image:: nbextension.png
+
+Installation
+============
+
+The supporting notebook server extension & classic notebook extension
+can be installed with ``pip``.
+
+.. code:: bash
+
+ pip install jupyter-launcher-shortcuts
+
+The JupyterLab extension needs to be installed separately.
+
+.. code:: bash
+
+ jupyter labextension install jupyterlab-launcher-shortcuts
+
+Configuring
+===========
+
+The extension can be configured in a ``jupyter_notebook_config.py``
+file created in any of the directories under ``config`` in the
+output of ``jupyter --paths`` command.
+
+.. code:: python
+
+ c.LauncherShortcuts.shortcuts = {
+ 'my-shiny-application': {
+ 'title': 'Human Readable Shortcut Title',
+ 'target': '{base_url}shiny/my-shiny-application-directory/',
+ 'icon_path': '/path/to/svg/file'
+ }
+ }
\ No newline at end of file
diff --git a/jupyter_launcher_shortcuts/__init__.py b/jupyter_launcher_shortcuts/__init__.py
new file mode 100644
index 0000000..ec93c0c
--- /dev/null
+++ b/jupyter_launcher_shortcuts/__init__.py
@@ -0,0 +1,72 @@
+from notebook.utils import url_path_join as ujoin
+from .api import ShortcutsHandler, IconHandler
+from traitlets import Dict
+from traitlets.config import Configurable
+from collections import namedtuple
+
+Shortcut = namedtuple('Shortcut', ['name', 'title', 'icon_path', 'target'])
+
+class LauncherShortcuts(Configurable):
+ shortcuts = Dict(
+ {},
+ help="""
+ Dictionary of shortcuts to put in launchers.
+
+ Key should be the name of the shortcut.
+
+ Value should be a dictionary with the following keys:
+
+ title
+ Human readable title for the shortcut. Defaults to the name.
+
+ target
+ URL to open when shortcut is clicked. {base_url} is replaced with
+ the notebook server's base_url
+
+ icon_path
+ Full path to an svg icon that could be used with a launcher. Currently only used by the
+ JupyterLab launcher
+ """,
+ config=True
+ )
+
+def shortcut_from_dict(name, shortcut_dict):
+ return Shortcut(
+ name,
+ title=shortcut_dict.get('title', name),
+ icon_path=shortcut_dict.get('icon_path'),
+ target=shortcut_dict['target']
+ )
+
+def load_jupyter_server_extension(nbapp):
+ # Set up handlers picked up via config
+ base_url = nbapp.web_app.settings['base_url']
+ shortcuts = [
+ shortcut_from_dict(k, v)
+ for k, v in LauncherShortcuts(parent=nbapp).shortcuts.items()
+ ]
+
+ icons = {}
+ for ls in shortcuts:
+ if ls.icon_path:
+ icons[ls.name] = ls.icon_path
+
+ nbapp.web_app.add_handlers('.*', [
+ (ujoin(base_url, 'launcher-shortcuts/shortcuts'), ShortcutsHandler, {'shortcuts': shortcuts}),
+ (ujoin(base_url, 'launcher-shortcuts/icon/(.*)'), IconHandler, {'icons': icons})
+ ])
+
+
+# Jupyter Extension points
+def _jupyter_server_extension_paths():
+ return [{
+ 'module': 'jupyter_launcher_shortcuts',
+ }]
+
+def _jupyter_nbextension_paths():
+ return [{
+ "section": "tree",
+ "dest": "jupyter_launcher_shortcuts",
+ 'src': 'static',
+ "require": "jupyter_launcher_shortcuts/tree"
+ }]
diff --git a/jupyter_launcher_shortcuts/api.py b/jupyter_launcher_shortcuts/api.py
new file mode 100644
index 0000000..97a41fc
--- /dev/null
+++ b/jupyter_launcher_shortcuts/api.py
@@ -0,0 +1,60 @@
+from tornado import web
+import mimetypes
+from notebook.base.handlers import IPythonHandler
+from notebook.utils import url_path_join as ujoin
+
+class ShortcutsHandler(IPythonHandler):
+ def initialize(self, shortcuts):
+ self.shortcuts = shortcuts
+
+ @web.authenticated
+ async def get(self):
+ data = []
+ for ls in self.shortcuts:
+ item = {
+ 'name': ls.name,
+ 'title': ls.title,
+ 'target': ls.target.format(base_url=self.base_url),
+ }
+ if ls.icon_path:
+ icon_url = ujoin(self.base_url, 'launcher-shortcuts', 'icon', sp.name)
+ data.append(item)
+
+ self.write({'shortcuts': data})
+
+
+# FIXME: Should be a StaticFileHandler subclass
+class IconHandler(IPythonHandler):
+ """
+ Serve launcher icons
+ """
+ def initialize(self, icons):
+ """
+ icons is a dict of titles to paths
+ """
+ self.icons = icons
+
+ async def get(self, name):
+ if name not in self.icons:
+ raise web.HTTPError(404)
+ path = self.icons[name]
+
+ # Guess mimetype appropriately
+ # Stolen from https://github.com/tornadoweb/tornado/blob/b399a9d19c45951e4561e6e580d7e8cf396ef9ff/tornado/web.py#L2881
+ mime_type, encoding = mimetypes.guess_type(path)
+ if encoding == "gzip":
+ content_type = "application/gzip"
+ # As of 2015-07-21 there is no bzip2 encoding defined at
+ # http://www.iana.org/assignments/media-types/media-types.xhtml
+ # So for that (and any other encoding), use octet-stream.
+ elif encoding is not None:
+ content_type = "application/octet-stream"
+ elif mime_type is not None:
+ content_type = mime_type
+ # if mime_type not detected, use application/octet-stream
+ else:
+ content_type = "application/octet-stream"
+
+ with open(self.icons[name]) as f:
+ self.write(f.read())
+ self.set_header('Content-Type', content_type)
\ No newline at end of file
diff --git a/jupyter_launcher_shortcuts/config.py b/jupyter_launcher_shortcuts/config.py
new file mode 100644
index 0000000..e4cb137
--- /dev/null
+++ b/jupyter_launcher_shortcuts/config.py
@@ -0,0 +1,8 @@
+"""
+Traitlets based configuration for jupyter_server_proxy
+"""
+from notebook.utils import url_path_join as ujoin
+from .handlers import SuperviseAndProxyHandler, AddSlashHandler
+import pkg_resources
+from collections import namedtuple
+
diff --git a/jupyter_launcher_shortcuts/etc/nbextension.json b/jupyter_launcher_shortcuts/etc/nbextension.json
new file mode 100644
index 0000000..69e3cce
--- /dev/null
+++ b/jupyter_launcher_shortcuts/etc/nbextension.json
@@ -0,0 +1,6 @@
+{
+ "load_extensions": {
+ "jupyter_launcher_extensions/tree": true
+ }
+}
+
diff --git a/jupyter_launcher_shortcuts/etc/serverextension.json b/jupyter_launcher_shortcuts/etc/serverextension.json
new file mode 100644
index 0000000..1eada14
--- /dev/null
+++ b/jupyter_launcher_shortcuts/etc/serverextension.json
@@ -0,0 +1,8 @@
+{
+ "NotebookApp": {
+ "nbserver_extensions": {
+ "jupyter_launcher_shortcuts": true
+ }
+ }
+}
+
diff --git a/jupyter_launcher_shortcuts/static/tree.js b/jupyter_launcher_shortcuts/static/tree.js
new file mode 100644
index 0000000..22f8512
--- /dev/null
+++ b/jupyter_launcher_shortcuts/static/tree.js
@@ -0,0 +1,51 @@
+define(['jquery', 'base/js/namespace', 'base/js/utils'], function($, Jupyter, utils) {
+ var $ = require('jquery');
+ var Jupyter = require('base/js/namespace');
+ var utils = require('base/js/utils');
+
+ var base_url = utils.get_body_data('baseUrl');
+
+ function load() {
+ if (!Jupyter.notebook_list) return;
+
+ var servers_info_url = base_url + 'launcher-shortcuts/shortcuts' ;
+ $.get(servers_info_url, function(data) {
+ /* locate the right-side dropdown menu of apps and notebooks */
+ var $menu = $('.tree-buttons').find('.dropdown-menu');
+
+ /* create a divider */
+ var $divider = $('
')
+ .attr('role', 'presentation')
+ .addClass('divider');
+
+
+ /* add the divider */
+ $menu.append($divider);
+
+ $.each(data.shortcuts, function(_, shortcut) {
+ /* create our list item */
+ var $entry_container = $('')
+ .attr('role', 'presentation')
+ .addClass('new-rstudio');
+
+ /* create our list item's link */
+ var $entry_link = $('')
+ .attr('role', 'menuitem')
+ .attr('tabindex', '-1')
+ .attr('href', shortcut.target)
+ .attr('target', '_blank')
+ .text(shortcut.title);
+
+ /* add the link to the item and
+ * the item to the menu */
+ $entry_container.append($entry_link);
+ $menu.append($entry_container);
+
+ });
+ });
+ }
+
+ return {
+ load_ipython_extension: load
+ };
+});
diff --git a/jupyterlab-launcher-shortcuts/.gitignore b/jupyterlab-launcher-shortcuts/.gitignore
new file mode 100644
index 0000000..6c9266e
--- /dev/null
+++ b/jupyterlab-launcher-shortcuts/.gitignore
@@ -0,0 +1,5 @@
+*.bundle.*
+lib/
+node_modules/
+*.egg-info/
+.ipynb_checkpoints
diff --git a/jupyterlab-launcher-shortcuts/README.md b/jupyterlab-launcher-shortcuts/README.md
new file mode 100644
index 0000000..8944168
--- /dev/null
+++ b/jupyterlab-launcher-shortcuts/README.md
@@ -0,0 +1,32 @@
+# jupyterlab-launcher-shortcuts
+
+Configurable launcher shortcuts for JupyterLab.
+
+
+## Prerequisites
+
+* JupyterLab
+
+## Installation
+
+```bash
+jupyter labextension install jupyterlab-launcher-shortcuts
+```
+
+## Development
+
+For a development install (requires npm version 4 or later), do the following in the repository directory:
+
+```bash
+npm install
+npm run build
+jupyter labextension link .
+```
+
+To rebuild the package and the JupyterLab app:
+
+```bash
+npm run build
+jupyter lab build
+```
+
diff --git a/jupyterlab-launcher-shortcuts/package.json b/jupyterlab-launcher-shortcuts/package.json
new file mode 100644
index 0000000..3068de4
--- /dev/null
+++ b/jupyterlab-launcher-shortcuts/package.json
@@ -0,0 +1,43 @@
+{
+ "name": "jupyterlab-launcher-shortcuts",
+ "version": "1.0.0-beta1",
+ "description": "Provide arbitrary shortcuts for apps in JupyterLab",
+ "keywords": [
+ "jupyter",
+ "jupyterlab",
+ "jupyterlab-extension"
+ ],
+ "homepage": "https://github.com/yuvipanda/jupyter-launcher-shortcuts",
+ "bugs": {
+ "url": "https://github.com/yuvipanda/jupyter-launcher-shortcuts/issues"
+ },
+ "license": "BSD-3-Clause",
+ "author": "Yuvi Panda",
+ "files": [
+ "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
+ "style/**/*.{css,eot,gif,html,jpg,json,png,svg,woff2,ttf}"
+ ],
+ "main": "lib/index.js",
+ "types": "lib/index.d.ts",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/yuvipanda/jupyter-launcher-shortcuts.git"
+ },
+ "scripts": {
+ "build": "tsc",
+ "clean": "rimraf lib",
+ "prepare": "npm run clean && npm run build",
+ "watch": "tsc -w"
+ },
+ "dependencies": {
+ "@jupyterlab/application": "^0.19.1",
+ "@jupyterlab/launcher": "^0.19.1"
+ },
+ "devDependencies": {
+ "rimraf": "^2.6.1",
+ "typescript": "~3.1.1"
+ },
+ "jupyterlab": {
+ "extension": true
+ }
+}
diff --git a/jupyterlab-launcher-shortcuts/src/index.ts b/jupyterlab-launcher-shortcuts/src/index.ts
new file mode 100644
index 0000000..55e5ec8
--- /dev/null
+++ b/jupyterlab-launcher-shortcuts/src/index.ts
@@ -0,0 +1,52 @@
+import { JupyterLab, JupyterLabPlugin } from '@jupyterlab/application';
+import { ILauncher } from '@jupyterlab/launcher';
+import { PageConfig } from '@jupyterlab/coreutils';
+
+import '../style/index.css';
+
+
+function addLauncherShortcuts(shortcutsData: any, launcher: ILauncher, app: JupyterLab) {
+ for (let shortcut of shortcutsData.shortcuts) {
+
+ let commandId = 'shortcut:' + shortcut.name;
+
+ app.commands.addCommand(commandId, {
+ label: shortcut.title,
+ execute: () => {
+ window.open(shortcut.target, '_blank');
+ }
+ });
+ let command : ILauncher.IItemOptions = {
+ command: commandId,
+ category: 'Notebook'
+ };
+ if (shortcut.icon_url) {
+ command.kernelIconUrl = shortcut.icon_url;
+ }
+ launcher.add(command);
+ }
+}
+/**
+ * Initialization data for the jupyterlab-server-proxy extension.
+ */
+const extension: JupyterLabPlugin = {
+ id: 'jupyterlab-launcher-shortcuts',
+ autoStart: true,
+ requires: [ILauncher],
+ activate: (app: JupyterLab, launcher: ILauncher) => {
+ // FIXME: What the callback hell is this
+ fetch(PageConfig.getBaseUrl() + 'launcher-shortcuts/shortcuts').then(
+ response => {
+ if (!response.ok) {
+ console.log('Fetching metadata about shortcuts failed. Make sure jupyter-launcher-shortcuts is installed');
+ console.log(response);
+ } else {
+ response.json().then(data => addLauncherShortcuts(data, launcher, app))
+ }
+
+ }
+ )
+ }
+};
+
+export default extension;
diff --git a/jupyterlab-launcher-shortcuts/style/index.css b/jupyterlab-launcher-shortcuts/style/index.css
new file mode 100644
index 0000000..e69de29
diff --git a/jupyterlab-launcher-shortcuts/tsconfig.json b/jupyterlab-launcher-shortcuts/tsconfig.json
new file mode 100644
index 0000000..4946663
--- /dev/null
+++ b/jupyterlab-launcher-shortcuts/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "compilerOptions": {
+ "declaration": true,
+ "lib": ["es2015", "dom"],
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "noEmitOnError": true,
+ "noUnusedLocals": true,
+ "outDir": "lib",
+ "rootDir": "src",
+ "strict": true,
+ "strictNullChecks": false,
+ "target": "es2015",
+ "types": []
+ },
+ "include": ["src/*"]
+}
diff --git a/jupyterlab-launcher-shortcuts/yarn.lock b/jupyterlab-launcher-shortcuts/yarn.lock
new file mode 100644
index 0000000..6194641
--- /dev/null
+++ b/jupyterlab-launcher-shortcuts/yarn.lock
@@ -0,0 +1,705 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@jupyterlab/application@^0.19.1":
+ version "0.19.1"
+ resolved "https://registry.yarnpkg.com/@jupyterlab/application/-/application-0.19.1.tgz#2f976a2e140041543f1dcf14a52eb081f7729739"
+ dependencies:
+ "@jupyterlab/apputils" "^0.19.1"
+ "@jupyterlab/coreutils" "^2.2.1"
+ "@jupyterlab/docregistry" "^0.19.1"
+ "@jupyterlab/rendermime" "^0.19.1"
+ "@jupyterlab/rendermime-interfaces" "^1.2.1"
+ "@jupyterlab/services" "^3.2.1"
+ "@phosphor/algorithm" "^1.1.2"
+ "@phosphor/application" "^1.6.0"
+ "@phosphor/commands" "^1.6.1"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/disposable" "^1.1.2"
+ "@phosphor/messaging" "^1.2.2"
+ "@phosphor/properties" "^1.1.2"
+ "@phosphor/signaling" "^1.2.2"
+ "@phosphor/widgets" "^1.6.0"
+
+"@jupyterlab/apputils@^0.19.1":
+ version "0.19.1"
+ resolved "https://registry.yarnpkg.com/@jupyterlab/apputils/-/apputils-0.19.1.tgz#673f7e8fecc01ba3a98dd75c5c0f9ca354fe0b69"
+ dependencies:
+ "@jupyterlab/coreutils" "^2.2.1"
+ "@jupyterlab/services" "^3.2.1"
+ "@phosphor/algorithm" "^1.1.2"
+ "@phosphor/commands" "^1.6.1"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/disposable" "^1.1.2"
+ "@phosphor/domutils" "^1.1.2"
+ "@phosphor/messaging" "^1.2.2"
+ "@phosphor/properties" "^1.1.2"
+ "@phosphor/signaling" "^1.2.2"
+ "@phosphor/virtualdom" "^1.1.2"
+ "@phosphor/widgets" "^1.6.0"
+ "@types/react" "~16.4.13"
+ react "~16.4.2"
+ react-dom "~16.4.2"
+ sanitize-html "~1.18.2"
+
+"@jupyterlab/codeeditor@^0.19.1":
+ version "0.19.1"
+ resolved "https://registry.yarnpkg.com/@jupyterlab/codeeditor/-/codeeditor-0.19.1.tgz#9b268ed914948bd46d93c391542b24cbaea58adc"
+ dependencies:
+ "@jupyterlab/coreutils" "^2.2.1"
+ "@jupyterlab/observables" "^2.1.1"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/disposable" "^1.1.2"
+ "@phosphor/messaging" "^1.2.2"
+ "@phosphor/signaling" "^1.2.2"
+ "@phosphor/widgets" "^1.6.0"
+ react "~16.4.2"
+ react-dom "~16.4.2"
+
+"@jupyterlab/codemirror@^0.19.1":
+ version "0.19.1"
+ resolved "https://registry.yarnpkg.com/@jupyterlab/codemirror/-/codemirror-0.19.1.tgz#7eaedcfef666feb15ede66207b4f3967c849afb5"
+ dependencies:
+ "@jupyterlab/apputils" "^0.19.1"
+ "@jupyterlab/codeeditor" "^0.19.1"
+ "@jupyterlab/coreutils" "^2.2.1"
+ "@jupyterlab/observables" "^2.1.1"
+ "@phosphor/algorithm" "^1.1.2"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/disposable" "^1.1.2"
+ "@phosphor/signaling" "^1.2.2"
+ codemirror "~5.39.0"
+
+"@jupyterlab/coreutils@^2.2.1":
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/@jupyterlab/coreutils/-/coreutils-2.2.1.tgz#c271eaf2f6e468757ba9660f24bd3c3e5d6fe583"
+ dependencies:
+ "@phosphor/algorithm" "^1.1.2"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/disposable" "^1.1.2"
+ "@phosphor/signaling" "^1.2.2"
+ ajv "~5.1.6"
+ comment-json "^1.1.3"
+ minimist "~1.2.0"
+ moment "~2.21.0"
+ path-posix "~1.0.0"
+ url-parse "~1.4.3"
+
+"@jupyterlab/docregistry@^0.19.1":
+ version "0.19.1"
+ resolved "https://registry.yarnpkg.com/@jupyterlab/docregistry/-/docregistry-0.19.1.tgz#1a8bcddc3eaf22fb25ce499a1f4c818c0c4cf1a0"
+ dependencies:
+ "@jupyterlab/apputils" "^0.19.1"
+ "@jupyterlab/codeeditor" "^0.19.1"
+ "@jupyterlab/codemirror" "^0.19.1"
+ "@jupyterlab/coreutils" "^2.2.1"
+ "@jupyterlab/observables" "^2.1.1"
+ "@jupyterlab/rendermime" "^0.19.1"
+ "@jupyterlab/rendermime-interfaces" "^1.2.1"
+ "@jupyterlab/services" "^3.2.1"
+ "@phosphor/algorithm" "^1.1.2"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/disposable" "^1.1.2"
+ "@phosphor/messaging" "^1.2.2"
+ "@phosphor/signaling" "^1.2.2"
+ "@phosphor/widgets" "^1.6.0"
+
+"@jupyterlab/launcher@^0.19.1":
+ version "0.19.1"
+ resolved "https://registry.yarnpkg.com/@jupyterlab/launcher/-/launcher-0.19.1.tgz#cab662ce42b7d0cbe65f9a0da75107677b6f01c7"
+ dependencies:
+ "@jupyterlab/apputils" "^0.19.1"
+ "@phosphor/algorithm" "^1.1.2"
+ "@phosphor/commands" "^1.6.1"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/disposable" "^1.1.2"
+ "@phosphor/properties" "^1.1.2"
+ "@phosphor/widgets" "^1.6.0"
+ react "~16.4.2"
+
+"@jupyterlab/observables@^2.1.1":
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/@jupyterlab/observables/-/observables-2.1.1.tgz#c5d8ad295c5b0bce914a607a342b0af4550b2187"
+ dependencies:
+ "@phosphor/algorithm" "^1.1.2"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/disposable" "^1.1.2"
+ "@phosphor/messaging" "^1.2.2"
+ "@phosphor/signaling" "^1.2.2"
+
+"@jupyterlab/rendermime-interfaces@^1.2.1":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@jupyterlab/rendermime-interfaces/-/rendermime-interfaces-1.2.1.tgz#702155fea6b87b58ba7025f2f267b72f6e7057f3"
+ dependencies:
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/widgets" "^1.6.0"
+
+"@jupyterlab/rendermime@^0.19.1":
+ version "0.19.1"
+ resolved "https://registry.yarnpkg.com/@jupyterlab/rendermime/-/rendermime-0.19.1.tgz#e5ca8f73cf9f6178ad5e76f18dbacb25c849bb80"
+ dependencies:
+ "@jupyterlab/apputils" "^0.19.1"
+ "@jupyterlab/codemirror" "^0.19.1"
+ "@jupyterlab/coreutils" "^2.2.1"
+ "@jupyterlab/observables" "^2.1.1"
+ "@jupyterlab/rendermime-interfaces" "^1.2.1"
+ "@jupyterlab/services" "^3.2.1"
+ "@phosphor/algorithm" "^1.1.2"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/messaging" "^1.2.2"
+ "@phosphor/signaling" "^1.2.2"
+ "@phosphor/widgets" "^1.6.0"
+ ansi_up "^3.0.0"
+ marked "~0.4.0"
+
+"@jupyterlab/services@^3.2.1":
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/@jupyterlab/services/-/services-3.2.1.tgz#e8d9329ed73f794909f786d22c5e94b07beb041b"
+ dependencies:
+ "@jupyterlab/coreutils" "^2.2.1"
+ "@jupyterlab/observables" "^2.1.1"
+ "@phosphor/algorithm" "^1.1.2"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/disposable" "^1.1.2"
+ "@phosphor/signaling" "^1.2.2"
+
+"@phosphor/algorithm@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@phosphor/algorithm/-/algorithm-1.1.2.tgz#fd1de9104c9a7f34e92864586ddf2e7f2e7779e8"
+
+"@phosphor/application@^1.6.0":
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/@phosphor/application/-/application-1.6.0.tgz#e1f1bf300680f982881d222a77b24ba8589d3fa2"
+ dependencies:
+ "@phosphor/commands" "^1.5.0"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/widgets" "^1.6.0"
+
+"@phosphor/collections@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@phosphor/collections/-/collections-1.1.2.tgz#c4c0b8b91129905fb36a9f243f2dbbde462dab8d"
+ dependencies:
+ "@phosphor/algorithm" "^1.1.2"
+
+"@phosphor/commands@^1.5.0", "@phosphor/commands@^1.6.1":
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/@phosphor/commands/-/commands-1.6.1.tgz#6f60c2a3b759316cd1363b426df3b4036bb2c7fd"
+ dependencies:
+ "@phosphor/algorithm" "^1.1.2"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/disposable" "^1.1.2"
+ "@phosphor/domutils" "^1.1.2"
+ "@phosphor/keyboard" "^1.1.2"
+ "@phosphor/signaling" "^1.2.2"
+
+"@phosphor/coreutils@^1.3.0":
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/@phosphor/coreutils/-/coreutils-1.3.0.tgz#63292d381c012c5ab0d0196e83ced829b7e04a42"
+
+"@phosphor/disposable@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@phosphor/disposable/-/disposable-1.1.2.tgz#a192dd6a2e6c69d5d09d39ecf334dab93778060e"
+ dependencies:
+ "@phosphor/algorithm" "^1.1.2"
+
+"@phosphor/domutils@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@phosphor/domutils/-/domutils-1.1.2.tgz#e2efeb052f398c42b93b89e9bab26af15cc00514"
+
+"@phosphor/dragdrop@^1.3.0":
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/@phosphor/dragdrop/-/dragdrop-1.3.0.tgz#7ce6ad39d6ca216d62a56f78104d02a77ae67307"
+ dependencies:
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/disposable" "^1.1.2"
+
+"@phosphor/keyboard@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@phosphor/keyboard/-/keyboard-1.1.2.tgz#3e32234451764240a98e148034d5a8797422dd1f"
+
+"@phosphor/messaging@^1.2.2":
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/@phosphor/messaging/-/messaging-1.2.2.tgz#7d896ddd3797b94a347708ded13da5783db75c14"
+ dependencies:
+ "@phosphor/algorithm" "^1.1.2"
+ "@phosphor/collections" "^1.1.2"
+
+"@phosphor/properties@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@phosphor/properties/-/properties-1.1.2.tgz#78cc77eff452839da02255de48e814946cc09a28"
+
+"@phosphor/signaling@^1.2.2":
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/@phosphor/signaling/-/signaling-1.2.2.tgz#3fcf97ca88e38bfb357fe8fe6bf7513347a514a9"
+ dependencies:
+ "@phosphor/algorithm" "^1.1.2"
+
+"@phosphor/virtualdom@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@phosphor/virtualdom/-/virtualdom-1.1.2.tgz#ce55c86eef31e5d0e26b1dc96ea32bd684458f41"
+ dependencies:
+ "@phosphor/algorithm" "^1.1.2"
+
+"@phosphor/widgets@^1.6.0":
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/@phosphor/widgets/-/widgets-1.6.0.tgz#ebba8008b6b13247d03e73e5f3872c90d2c9c78f"
+ dependencies:
+ "@phosphor/algorithm" "^1.1.2"
+ "@phosphor/commands" "^1.5.0"
+ "@phosphor/coreutils" "^1.3.0"
+ "@phosphor/disposable" "^1.1.2"
+ "@phosphor/domutils" "^1.1.2"
+ "@phosphor/dragdrop" "^1.3.0"
+ "@phosphor/keyboard" "^1.1.2"
+ "@phosphor/messaging" "^1.2.2"
+ "@phosphor/properties" "^1.1.2"
+ "@phosphor/signaling" "^1.2.2"
+ "@phosphor/virtualdom" "^1.1.2"
+
+"@types/prop-types@*":
+ version "15.5.8"
+ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.5.8.tgz#8ae4e0ea205fe95c3901a5a1df7f66495e3a56ce"
+
+"@types/react@~16.4.13":
+ version "16.4.18"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-16.4.18.tgz#2e28a2e7f92d3fa7d6a65f2b73275c3e3138a13d"
+ dependencies:
+ "@types/prop-types" "*"
+ csstype "^2.2.0"
+
+ajv@~5.1.6:
+ version "5.1.6"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.1.6.tgz#4b2f1a19dece93d57ac216037e3e9791c7dd1564"
+ dependencies:
+ co "^4.6.0"
+ json-schema-traverse "^0.3.0"
+ json-stable-stringify "^1.0.1"
+
+ansi-styles@^3.2.1:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
+ dependencies:
+ color-convert "^1.9.0"
+
+ansi_up@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/ansi_up/-/ansi_up-3.0.0.tgz#27f45d8f457d9ceff59e4ea03c8e6f13c1a303e8"
+
+array-uniq@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
+
+asap@~2.0.3:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
+
+balanced-match@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
+
+brace-expansion@^1.1.7:
+ version "1.1.11"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
+ dependencies:
+ balanced-match "^1.0.0"
+ concat-map "0.0.1"
+
+chalk@^2.3.0, chalk@^2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
+ dependencies:
+ ansi-styles "^3.2.1"
+ escape-string-regexp "^1.0.5"
+ supports-color "^5.3.0"
+
+co@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
+
+codemirror@~5.39.0:
+ version "5.39.2"
+ resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.39.2.tgz#778aa13b55ebf280745c309cb1b148e3fc06f698"
+
+color-convert@^1.9.0:
+ version "1.9.3"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
+ dependencies:
+ color-name "1.1.3"
+
+color-name@1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
+
+comment-json@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/comment-json/-/comment-json-1.1.3.tgz#6986c3330fee0c4c9e00c2398cd61afa5d8f239e"
+ dependencies:
+ json-parser "^1.0.0"
+
+concat-map@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+
+core-js@^1.0.0:
+ version "1.2.7"
+ resolved "http://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
+
+csstype@^2.2.0:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.0.tgz#6cf7b2fa7fc32aab3d746802c244d4eda71371a2"
+
+dom-serializer@0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
+ dependencies:
+ domelementtype "~1.1.1"
+ entities "~1.1.1"
+
+domelementtype@1, domelementtype@^1.3.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
+
+domelementtype@~1.1.1:
+ version "1.1.3"
+ resolved "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
+
+domhandler@^2.3.0:
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
+ dependencies:
+ domelementtype "1"
+
+domutils@^1.5.1:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
+ dependencies:
+ dom-serializer "0"
+ domelementtype "1"
+
+encoding@^0.1.11:
+ version "0.1.12"
+ resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
+ dependencies:
+ iconv-lite "~0.4.13"
+
+entities@^1.1.1, entities@~1.1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
+
+escape-string-regexp@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+
+esprima@^2.7.0:
+ version "2.7.3"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
+
+fbjs@^0.8.16:
+ version "0.8.17"
+ resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
+ dependencies:
+ core-js "^1.0.0"
+ isomorphic-fetch "^2.1.1"
+ loose-envify "^1.0.0"
+ object-assign "^4.1.0"
+ promise "^7.1.1"
+ setimmediate "^1.0.5"
+ ua-parser-js "^0.7.18"
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+
+glob@^7.0.5:
+ version "7.1.3"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.4"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+has-flag@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+
+htmlparser2@^3.9.0:
+ version "3.10.0"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464"
+ dependencies:
+ domelementtype "^1.3.0"
+ domhandler "^2.3.0"
+ domutils "^1.5.1"
+ entities "^1.1.1"
+ inherits "^2.0.1"
+ readable-stream "^3.0.6"
+
+iconv-lite@~0.4.13:
+ version "0.4.24"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
+ dependencies:
+ safer-buffer ">= 2.1.2 < 3"
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@2, inherits@^2.0.1, inherits@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+
+is-stream@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+
+isomorphic-fetch@^2.1.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
+ dependencies:
+ node-fetch "^1.0.1"
+ whatwg-fetch ">=0.10.0"
+
+"js-tokens@^3.0.0 || ^4.0.0":
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+
+json-parser@^1.0.0:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/json-parser/-/json-parser-1.1.5.tgz#e62ec5261d1a6a5fc20e812a320740c6d9005677"
+ dependencies:
+ esprima "^2.7.0"
+
+json-schema-traverse@^0.3.0:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
+
+json-stable-stringify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
+ dependencies:
+ jsonify "~0.0.0"
+
+jsonify@~0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
+
+lodash.clonedeep@^4.5.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
+
+lodash.escaperegexp@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347"
+
+lodash.isplainobject@^4.0.6:
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
+
+lodash.isstring@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
+
+lodash.mergewith@^4.6.0:
+ version "4.6.1"
+ resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927"
+
+loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
+ dependencies:
+ js-tokens "^3.0.0 || ^4.0.0"
+
+marked@~0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/marked/-/marked-0.4.0.tgz#9ad2c2a7a1791f10a852e0112f77b571dce10c66"
+
+minimatch@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+ dependencies:
+ brace-expansion "^1.1.7"
+
+minimist@~1.2.0:
+ version "1.2.0"
+ resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+
+moment@~2.21.0:
+ version "2.21.0"
+ resolved "http://registry.npmjs.org/moment/-/moment-2.21.0.tgz#2a114b51d2a6ec9e6d83cf803f838a878d8a023a"
+
+node-fetch@^1.0.1:
+ version "1.7.3"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
+ dependencies:
+ encoding "^0.1.11"
+ is-stream "^1.0.1"
+
+number-is-nan@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
+
+object-assign@^4.1.0, object-assign@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+
+once@^1.3.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ dependencies:
+ wrappy "1"
+
+path-is-absolute@^1.0.0:
+ version "1.0.1"
+ resolved "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+
+path-posix@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/path-posix/-/path-posix-1.0.0.tgz#06b26113f56beab042545a23bfa88003ccac260f"
+
+postcss@^6.0.14:
+ version "6.0.23"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324"
+ dependencies:
+ chalk "^2.4.1"
+ source-map "^0.6.1"
+ supports-color "^5.4.0"
+
+promise@^7.1.1:
+ version "7.3.1"
+ resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
+ dependencies:
+ asap "~2.0.3"
+
+prop-types@^15.6.0:
+ version "15.6.2"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
+ dependencies:
+ loose-envify "^1.3.1"
+ object-assign "^4.1.1"
+
+querystringify@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.0.tgz#7ded8dfbf7879dcc60d0a644ac6754b283ad17ef"
+
+react-dom@~16.4.2:
+ version "16.4.2"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.4.2.tgz#4afed569689f2c561d2b8da0b819669c38a0bda4"
+ dependencies:
+ fbjs "^0.8.16"
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.0"
+
+react@~16.4.2:
+ version "16.4.2"
+ resolved "https://registry.yarnpkg.com/react/-/react-16.4.2.tgz#2cd90154e3a9d9dd8da2991149fdca3c260e129f"
+ dependencies:
+ fbjs "^0.8.16"
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.0"
+
+readable-stream@^3.0.6:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.1.1.tgz#ed6bbc6c5ba58b090039ff18ce670515795aeb06"
+ dependencies:
+ inherits "^2.0.3"
+ string_decoder "^1.1.1"
+ util-deprecate "^1.0.1"
+
+requires-port@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
+
+rimraf@^2.6.1:
+ version "2.6.2"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
+ dependencies:
+ glob "^7.0.5"
+
+safe-buffer@~5.1.0:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
+
+"safer-buffer@>= 2.1.2 < 3":
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
+
+sanitize-html@~1.18.2:
+ version "1.18.5"
+ resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.18.5.tgz#350013d95d17f851ef8b178dfd9ca155acf2d7a0"
+ dependencies:
+ chalk "^2.3.0"
+ htmlparser2 "^3.9.0"
+ lodash.clonedeep "^4.5.0"
+ lodash.escaperegexp "^4.1.2"
+ lodash.isplainobject "^4.0.6"
+ lodash.isstring "^4.0.1"
+ lodash.mergewith "^4.6.0"
+ postcss "^6.0.14"
+ srcset "^1.0.0"
+ xtend "^4.0.0"
+
+setimmediate@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
+
+source-map@^0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+
+srcset@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/srcset/-/srcset-1.0.0.tgz#a5669de12b42f3b1d5e83ed03c71046fc48f41ef"
+ dependencies:
+ array-uniq "^1.0.2"
+ number-is-nan "^1.0.0"
+
+string_decoder@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"
+ dependencies:
+ safe-buffer "~5.1.0"
+
+supports-color@^5.3.0, supports-color@^5.4.0:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
+ dependencies:
+ has-flag "^3.0.0"
+
+typescript@~3.1.1:
+ version "3.1.6"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68"
+
+ua-parser-js@^0.7.18:
+ version "0.7.19"
+ resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.19.tgz#94151be4c0a7fb1d001af7022fdaca4642659e4b"
+
+url-parse@~1.4.3:
+ version "1.4.4"
+ resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.4.tgz#cac1556e95faa0303691fec5cf9d5a1bc34648f8"
+ dependencies:
+ querystringify "^2.0.0"
+ requires-port "^1.0.0"
+
+util-deprecate@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+
+whatwg-fetch@>=0.10.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+
+xtend@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
diff --git a/labextension.png b/labextension.png
new file mode 100644
index 0000000..abd6ddd
Binary files /dev/null and b/labextension.png differ
diff --git a/nbextension.png b/nbextension.png
new file mode 100644
index 0000000..9b6e7f8
Binary files /dev/null and b/nbextension.png differ
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..2a6d732
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,25 @@
+import setuptools
+from glob import glob
+
+setuptools.setup(
+ name="jupyter-launcher-shortcuts",
+ version='1.0dev',
+ url="https://github.com/yuvipanda/jupyter-launcher-shortcuts",
+ author="Yuvi Panda",
+ author_email="yuvipanda@gmail.com",
+ license="BSD 3-Clause",
+ description="Easily place shortcuts",
+ packages=setuptools.find_packages(),
+ install_requires=['notebook', 'simpervisor', 'aiohttp'],
+ python_requires='>=3.5',
+ classifiers=[
+ 'Framework :: Jupyter',
+ ],
+ data_files=[
+ ('share/jupyter/nbextensions/jupyter_launcher_shortcuts', glob('jupyter_launcher_shortcuts/static/*')),
+ ('etc/jupyter/jupyter_notebook_config.d', ['jupyter_launcher_shortcuts/etc/serverextension.json']),
+ ('etc/jupyter/nbconfig/tree.d', ['jupyter_launcher_shortcuts/etc/nbextension.json'])
+ ],
+ include_package_data=True,
+ zip_safe=False
+)