diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..4ff18f1 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,31 @@ + + +version: 2 +jobs: + build: + docker: + - image: buildpack-deps:trusty + # specify the version you desire here + # - image: circleci/node:7.10 + + # Specify service dependencies here if necessary + # CircleCI maintains a library of pre-built images + # documented at https://circleci.com/docs/2.0/circleci-images/ + # - image: circleci/mongo:3.4.4 + + working_directory: ~/repo + + steps: + - checkout + - deploy: + command: | + if [ "${CIRCLE_BRANCH}" == "master" ]; then + echo -e "Host 159.89.243.114\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config + git config --global user.email "chris88@gmail.com" + git config --global user.name "Chris Hutchison" + git config --global merge.defaultToUpstream true + git remote add dokku dokku@159.89.243.114:isso + git fetch dokku master + git merge dokku/master --no-edit --commit + git push dokku master + fi diff --git a/.gitignore b/.gitignore index ae5ee37..efebafd 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,8 @@ .Python .sass-cache .vagrant - +package.json +yarn.lock /bin /include /lib @@ -17,11 +18,11 @@ /man /share /isso.egg-info/ -/isso/js/components -/isso/js/embed.min.js -/isso/js/embed.dev.js -/isso/js/count.min.js -/isso/js/count.dev.js +#/isso/js/components +#/isso/js/embed.min.js +#/isso/js/embed.dev.js +#/isso/js/count.min.js +#/isso/js/count.dev.js /docs/_build /docs/_static/css/site.css @@ -119,3 +120,5 @@ ENV/ # Rope project settings .ropeproject + +node_modules diff --git a/CHANGES.rst b/CHANGES.rst index bb055b7..291e23f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,8 +4,7 @@ Changelog for Isso 0.10.7 (unreleased) ------------------- -- Fix Chinese translation & typo in CJK -- Fix link in moderation mails if isso is setup on a sub-url (e.g. domain.tld/comments/) +- Fix Chinese translation - Add Danish translation - Add Hungarian translation - Add Persian translation @@ -13,6 +12,9 @@ Changelog for Isso - Add links highlighting in comments - Add apidoc - Add rc.d script for FreeBSD +<<<<<<< HEAD +- Some tests/travis/documentation improvements and fixes +======= - Add the possibility to set CORS Origin through ISSO_CORS_ORIGIN environ variable - Add preview button - Add Atom feed at /feed?uri={thread-id} @@ -22,6 +24,7 @@ Changelog for Isso - Upgraded to Misaka 2 - Some tests/travis/documentation improvements and fixes + pep8 - Improvement on german translation +>>>>>>> e745f326db2ec1c39a4aae9094ef4891c9687e4a 0.10.6 (2016-09-22) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 4581ef3..3b36990 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -51,14 +51,15 @@ In chronological order: * Added configuration to require email addresses (no validation) * Fix Vagrantfile -* Benoît Latinier @blatinier +* Benoît Latinier * Fix thread discovery * Added mandatory author - * Added admin interface * Ivan Pantic * Added vote levels +<<<<<<< HEAD +======= * Martin Schenck @schemar * Improvement in the german translation @@ -92,5 +93,6 @@ In chronological order: * Steffen Prince @sprin * Upgrade to Misaka 2 +>>>>>>> e745f326db2ec1c39a4aae9094ef4891c9687e4a * [Your name or handle] <[email or website]> * [Brief summary of your changes] diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 3a8203c..0000000 --- a/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -# First, compile JS stuff -FROM node -WORKDIR /src/ -COPY . . -RUN npm install -g requirejs uglify-js jade bower -RUN make init js - -# Second, create virtualenv -FROM python:3-stretch -WORKDIR /src/ -COPY --from=0 /src . -RUN apt-get -qqy update && apt-get -qqy install python3-dev sqlite3 -RUN python3 -m venv /isso \ - && . /isso/bin/activate \ - && python setup.py install \ - && pip install gunicorn - -# Third, create final repository -FROM python:3-slim-stretch -WORKDIR /isso/ -COPY --from=1 /isso . - -# Configuration -VOLUME /db /config -EXPOSE 8080 -ENV ISSO_SETTINGS /config/isso.cfg -CMD ["/isso/bin/gunicorn", "-b", "0.0.0.0:8080", "-w", "4", "--preload", "isso.run"] - -# Example of use: -# -# docker build -t isso . -# docker run -it --rm -v /opt/isso:/config -v /opt/isso:/db -v $PWD:$PWD isso /isso/bin/isso -c \$ISSO_SETTINGS import disqus.xml -# docker run -d --rm --name isso -p 8080:8080 -v /opt/isso:/config -v /opt/isso:/db isso diff --git a/Makefile b/Makefile index 2a44cb3..a101755 100644 --- a/Makefile +++ b/Makefile @@ -69,6 +69,15 @@ test: $($ISSO_PY_SRC) clean: rm -f $(DOCS_MAN_DST) $(DOCS_CSS_DST) $(ISSO_JS_DST) rm -rf $(DOCS_HTML_DST) + +web: + python setup.py develop # or `install` + # isso -c config/comments.comment.sh.cfg run + # gunicorn --pid=/app/storage/gunicorn.pid -w 4 -b 0.0.0.0:5000 isso.dispatch + uwsgi uswgi2.ini + cd isso/js; bower --allow-root install almond requirejs requirejs-text jade + make js -.PHONY: clean site man init js coverage test + +.PHONY: clean site man init js coverage test web diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..d189185 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: make web diff --git a/Vagrantfile b/Vagrantfile index 2693143..f25da5f 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -38,7 +38,7 @@ Vagrant.configure(2) do |config| # For a complete reference, please see the online documentation at # https://docs.vagrantup.com. - config.vm.box = "ubuntu/trusty32" + config.vm.box = "ubuntu/xenial32" config.vm.hostname = 'isso-dev.local' config.vm.network "private_network", type: "dhcp" diff --git a/ansible/site.retry b/ansible/site.retry new file mode 100644 index 0000000..4ad96d5 --- /dev/null +++ b/ansible/site.retry @@ -0,0 +1 @@ +default diff --git a/ansible/site.yml b/ansible/site.yml index 7304364..dc97f7b 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -5,6 +5,11 @@ sudo: true tasks: + - name: Import the NodeSource GPG key into apt + apt_key: + id: 68576280 + url: "https://keyserver.ubuntu.com/pks/lookup?op=get&fingerprint=on&search=0x1655A0AB68576280" + - name: Apt | Add nodesource keys apt_key: url=https://deb.nodesource.com/gpgkey/nodesource.gpg.key state=present diff --git a/config/comments.comment.sh.cfg b/config/comments.comment.sh.cfg new file mode 100644 index 0000000..4c98ee0 --- /dev/null +++ b/config/comments.comment.sh.cfg @@ -0,0 +1,6 @@ +[general] +name = commentssh +host = + https://comments.comment.sh/ +dbpath = /app/storage/comments.comments.sh.db + diff --git a/config/commentssh2.cfg b/config/commentssh2.cfg new file mode 100644 index 0000000..4a5e30f --- /dev/null +++ b/config/commentssh2.cfg @@ -0,0 +1,5 @@ +[general] +name = commentssh2 +host = https://chrishutchison.me/ +dbpath = /app/storage/commentssh2.sh.db + diff --git a/docs/contribute.rst b/docs/contribute.rst index c349a47..8a3886d 100644 --- a/docs/contribute.rst +++ b/docs/contribute.rst @@ -59,3 +59,5 @@ definitely need help: - delete or activate comments matching a filter (e.g. name, email, ip address) - close threads and remove threads completely + + - edit comments diff --git a/docs/docs/configuration/client.rst b/docs/docs/configuration/client.rst index 7b074b4..64d292a 100644 --- a/docs/docs/configuration/client.rst +++ b/docs/docs/configuration/client.rst @@ -7,7 +7,6 @@ preferably in the script tag which embeds the JS: .. code-block:: html Furthermore you can override the automatic title detection inside -the embed tag, as well as the thread ID, e.g.: +the embed tag, e.g.: .. code-block:: html -
+
data-isso --------- diff --git a/docs/docs/install.rst b/docs/docs/install.rst index eb2ef35..44d829f 100644 --- a/docs/docs/install.rst +++ b/docs/docs/install.rst @@ -149,18 +149,7 @@ Prebuilt Packages * Fedora: https://copr.fedoraproject.org/coprs/jujens/isso/ — copr repository. Built from Pypi, includes a systemctl unit script. -Build a Docker image --------------------- - -You can get a Docker image by running ``docker build . -t -isso``. Assuming you have your configuration in ``/opt/isso``, you can -use the following command to spawn the Docker container: - -.. code-block:: sh - - ~> docker run -d --rm --name isso -p 127.0.0.1:8080:8080 -v /opt/isso:/config -v /opt/isso:/db isso - -Then, you can use a reverse proxy to expose port 8080. +* Docker Image: https://registry.hub.docker.com/u/bl4n/isso/ Install from Source ------------------- diff --git a/docs/docs/troubleshooting.rst b/docs/docs/troubleshooting.rst index a395a0a..20ee8dd 100644 --- a/docs/docs/troubleshooting.rst +++ b/docs/docs/troubleshooting.rst @@ -1,12 +1,6 @@ Troubleshooting =============== -For uberspace users -------------------- -Some uberspace users experienced problems with isso and they solved their -issue by adding `DirectoryIndex disabled` as the first line in the `.htaccess` -file for the domain the isso server is running on. - pkg_ressources.DistributionNotFound ----------------------------------- diff --git a/isso/dispatch.py b/isso/dispatch.py index 7c8bb14..87b2b57 100644 --- a/isso/dispatch.py +++ b/isso/dispatch.py @@ -46,8 +46,9 @@ class Dispatcher(DispatcherMiddleware): return super(Dispatcher, self).__call__(environ, start_response) def default(self, environ, start_response): - resp = Response("\n".join(self.isso.keys()), - 404, content_type="text/plain") + #resp = Response("\n".join(self.sso.keys()), + # 404, content_type="text/plain") + resp = Response("Up and running", 404, content_type="text/plain") return resp(environ, start_response) diff --git a/isso/ext/notifications.py b/isso/ext/notifications.py index 2b4a81c..8855b7a 100644 --- a/isso/ext/notifications.py +++ b/isso/ext/notifications.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals +import os import sys import io import time @@ -55,7 +56,7 @@ class SMTP(object): def spooler(args): try: self._sendmail(args[b"subject"].decode("utf-8"), - args["body"].decode("utf-8")) + args["body"].decode("utf-8"), args[b"to"].decode("utf-8")) except smtplib.SMTPConnectError: return uwsgi.SPOOL_RETRY else: @@ -115,7 +116,10 @@ class SMTP(object): (local("origin") + thread["uri"] + "#isso-%i" % comment["id"])) rv.write("\n") - uri = self.general_host + "/id/%i" % comment["id"] + # uri = self.general_host + "/id/%i" % comment["id"] + name = self.isso.conf.get("general", "name") + uri = os.environ['ISSO_DOMAIN'] + "/" + name + "/id/%i" % comment["id"] + key = self.isso.sign(comment["id"]) rv.write("---\n") @@ -130,18 +134,25 @@ class SMTP(object): def notify(self, thread, comment): body = self.format(thread, comment) + + if thread["title"] is None: + thread["title"] = "New comment" + if self.conf.get("to") is not None: + to_addr = self.conf.get("to") + if uwsgi: uwsgi.spool({b"subject": thread["title"].encode("utf-8"), - b"body": body.encode("utf-8")}) + b"body": body.encode("utf-8"), b"to":to_addr.encode("utf-8")}) else: - start_new_thread(self._retry, (thread["title"], body)) + start_new_thread(self._retry, (thread["title"], body, to_addr)) - def _sendmail(self, subject, body): + def _sendmail(self, subject, body, to): from_addr = self.conf.get("from") - to_addr = self.conf.get("to") - + # to_addr = self.conf.get("to") + to_addr = to + msg = MIMEText(body, 'plain', 'utf-8') msg['From'] = from_addr msg['To'] = to_addr @@ -151,10 +162,10 @@ class SMTP(object): with self as con: con.sendmail(from_addr, to_addr, msg.as_string()) - def _retry(self, subject, body): + def _retry(self, subject, body, to): for x in range(5): try: - self._sendmail(subject, body) + self._sendmail(subject, body, to) except smtplib.SMTPConnectError: time.sleep(60) else: diff --git a/isso/ext/spooler.py b/isso/ext/spooler.py new file mode 100644 index 0000000..33fc5c5 --- /dev/null +++ b/isso/ext/spooler.py @@ -0,0 +1,10 @@ +def spooler(args): + try: + self._sendmail(args[b"subject"].decode("utf-8"), + args["body"].decode("utf-8")) + except smtplib.SMTPConnectError: + return uwsgi.SPOOL_RETRY + else: + return uwsgi.SPOOL_OK + +uwsgi.spooler = spooler diff --git a/isso/views/comments.py b/isso/views/comments.py index b76be46..e2085af 100644 --- a/isso/views/comments.py +++ b/isso/views/comments.py @@ -274,6 +274,7 @@ class API(object): else: title = data['title'] + thread = self.threads.new(uri, title) self.signal("comments.new:new-thread", thread) else: diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..ae1924b --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +uwsgi==2.0.17 diff --git a/setup.py b/setup.py index 74b1c54..5b5ec83 100644 --- a/setup.py +++ b/setup.py @@ -5,8 +5,13 @@ import sys from setuptools import setup, find_packages +<<<<<<< HEAD +requires = ['html5lib==0.9999999', 'itsdangerous', 'Jinja2', + 'misaka>=1.0,<2.0', 'werkzeug>=0.9', 'uwsgi'] +======= requires = ['itsdangerous', 'Jinja2', 'misaka>=2.0,<3.0', 'html5lib<0.9999999', 'werkzeug>=0.9'] +>>>>>>> e745f326db2ec1c39a4aae9094ef4891c9687e4a if sys.version_info < (2, 7): raise SystemExit("Python 2 versions < 2.7 are not supported.") diff --git a/test.cfg b/test.cfg new file mode 100644 index 0000000..e641c79 --- /dev/null +++ b/test.cfg @@ -0,0 +1,4 @@ +[general] +name=test +dbpath=test.db +host = https://chrishutchison.me diff --git a/test.db b/test.db new file mode 100644 index 0000000..8845e19 Binary files /dev/null and b/test.db differ diff --git a/update-settings.py b/update-settings.py new file mode 100644 index 0000000..2913f7a --- /dev/null +++ b/update-settings.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +import os +import shutil + +env = os.environ.get + +smtp_settings = [ + ('username', ''), + ('password', ''), + ('host', 'localhost'), + ('port', '25'), + ('security', 'none'), + ('to', ''), + ('from', ''), +] + +required = ['to', 'from'] + +settings = env('ISSO_SETTINGS') +if not settings: + raise Exception('No ISSO_SETTINGS defined') + +settings = settings.split(';') + + +def backup_name(setting): + return setting + '.bak' + + +def purge_backup(setting): + # if there is a backup file, delete it + backup_setting = backup_name(setting) + if os.path.exists(backup_setting): + try: + os.remove(backup_setting) + except OSError: + pass + + +def create_backup(setting): + # make a backup + shutil.copyfile(setting, backup_name(setting)) + + +def load_values(): + values = [] + for name, default in smtp_settings: + label = 'ISSO_SMTP_%s' % name.upper() + value = env(label, default) + if name in required and not value.strip(): + raise Exception('Required environment variable is not set: %s' % + label) + values.append([label, value]) + return values + + +def replace_placeholders(setting, values): + with open(setting, 'r') as _file: + content = _file.read() + + for label, value in values: + content = content.replace(label, value) + + # make a backup + create_backup(setting) + + with open(setting, 'w') as _file: + _file.write(content) + + return content + + +def main(): + values = load_values() + + for setting in settings: + print("Replacing settings %s" % setting) + replace_placeholders(setting, values) + + +if __name__ == '__main__': + main() diff --git a/uswgi2.ini b/uswgi2.ini new file mode 100644 index 0000000..d43680c --- /dev/null +++ b/uswgi2.ini @@ -0,0 +1,15 @@ +[uwsgi] +http = :5000 +master = true +; set to `nproc` +processes = 4 +cache2 = name=hash,items=1024,blocksize=32 +; you may change this +module = isso.dispatch +lazy-apps = true +spooler-import=isso.dispatch +spooler=/app/storage/spooler +touch-reload=/app/storage/kill-uwsgi.ini +touch-chain-reload = /app/storage/uwsgi-reload.ini +; uncomment if you use a virtual environment +; virtualenv = /path/to/isso diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..ab5bb34 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,276 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +acorn-globals@^1.0.3: + version "1.0.9" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-1.0.9.tgz#55bb5e98691507b74579d0513413217c380c54cf" + dependencies: + acorn "^2.1.0" + +acorn@^1.0.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-1.2.2.tgz#c8ce27de0acc76d896d2b1fad3df588d9e82f014" + +acorn@^2.1.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +almond@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/almond/-/almond-0.3.3.tgz#a0e7c95ac7624d6417b4494b1e68bff693168a20" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +asap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/asap/-/asap-1.0.0.tgz#b2a45da5fdfa20b0496fc3768cc27c12fa916a7d" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +character-parser@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-1.2.1.tgz#c0dde4ab182713b919b970959a123ecc1a30fcd6" + +clean-css@^3.1.9: + version "3.4.28" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff" + dependencies: + commander "2.8.x" + source-map "0.4.x" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +commander@2.8.x: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + dependencies: + graceful-readlink ">= 1.0.0" + +commander@~2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.6.0.tgz#9df7e52fb2a0cb0fb89058ee80c3104225f37e1d" + +constantinople@~3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-3.0.2.tgz#4b945d9937907bcd98ee575122c3817516544141" + dependencies: + acorn "^2.1.0" + +css-parse@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-1.0.4.tgz#38b0503fbf9da9f54e9c1dbda60e145c77117bdd" + +css-stringify@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/css-stringify/-/css-stringify-1.0.5.tgz#b0d042946db2953bb9d292900a6cb5f6d0122031" + +css@~1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/css/-/css-1.0.8.tgz#9386811ca82bccc9ee7fb5a732b1e2a317c8a3e7" + dependencies: + css-parse "1.0.4" + css-stringify "1.0.5" + +decamelize@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-promise@~1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-1.0.1.tgz#31573761c057e33c2e91aab9e96da08cefbe76e5" + +jade@^1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/jade/-/jade-1.11.0.tgz#9c80e538c12d3fb95c8d9bb9559fa0cc040405fd" + dependencies: + character-parser "1.2.1" + clean-css "^3.1.9" + commander "~2.6.0" + constantinople "~3.0.1" + jstransformer "0.0.2" + mkdirp "~0.5.0" + transformers "2.1.0" + uglify-js "^2.4.19" + void-elements "~2.0.1" + with "~4.0.0" + +jstransformer@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-0.0.2.tgz#7aae29a903d196cfa0973d885d3e47947ecd76ab" + dependencies: + is-promise "^2.0.0" + promise "^6.0.1" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +mkdirp@~0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +optimist@~0.3.5: + version "0.3.7" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9" + dependencies: + wordwrap "~0.0.2" + +promise@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/promise/-/promise-6.1.0.tgz#2ce729f6b94b45c26891ad0602c5c90e04c6eef6" + dependencies: + asap "~1.0.0" + +promise@~2.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/promise/-/promise-2.0.0.tgz#46648aa9d605af5d2e70c3024bf59436da02b80e" + dependencies: + is-promise "~1" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +requirejs-text@^2.0.15: + version "2.0.15" + resolved "https://registry.yarnpkg.com/requirejs-text/-/requirejs-text-2.0.15.tgz#13138733613fc4457b7e1247e8cb751df7aa5429" + +requirejs@^2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.5.tgz#617b9acbbcb336540ef4914d790323a8d4b861b0" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +source-map@0.4.x: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@~0.1.7: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + +source-map@~0.5.1: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +transformers@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/transformers/-/transformers-2.1.0.tgz#5d23cb35561dd85dc67fb8482309b47d53cce9a7" + dependencies: + css "~1.0.8" + promise "~2.0" + uglify-js "~2.2.5" + +uglify-js@^2.4.19: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-js@~2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.2.5.tgz#a6e02a70d839792b9780488b7b8b184c095c99c7" + dependencies: + optimist "~0.3.5" + source-map "~0.1.7" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +void-elements@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +with@~4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/with/-/with-4.0.3.tgz#eefd154e9e79d2c8d3417b647a8f14d9fecce14e" + dependencies: + acorn "^1.0.1" + acorn-globals "^1.0.3" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0"