From 7aaabe146561a5d780b1961a30abf3812d4d89f0 Mon Sep 17 00:00:00 2001 From: Joseph Coffland Date: Thu, 8 Feb 2018 19:35:00 -0800 Subject: [PATCH] Improved error handling and reporting, Check for firmware updates, Password control on firmware updates, lint --- Makefile | 10 +- jshint.json | 14 + package-lock.json | 1794 +++++++++++++++++++++++ package.json | 10 +- src/jade/index.jade | 35 +- src/jade/templates/admin-view.jade | 15 +- src/jade/templates/console.jade | 20 + src/jade/templates/control-view.jade | 21 +- src/js/admin-view.js | 35 +- src/js/app.js | 94 +- src/js/console.js | 59 + src/js/control-view.js | 32 +- src/js/gauge.js | 3 + src/js/io-view.js | 4 +- src/js/main.js | 6 +- src/js/motor-view.js | 2 +- src/js/slider.js | 25 - src/js/tool-view.js | 2 +- src/py/bbctrl/APIHandler.py | 10 +- src/py/bbctrl/AVR.py | 12 +- src/py/bbctrl/Cmd.py | 5 - src/py/bbctrl/Config.py | 1 + src/py/bbctrl/Ctrl.py | 1 + src/py/bbctrl/Jog.py | 2 +- src/py/bbctrl/LCD.py | 6 +- src/py/bbctrl/Messages.py | 34 + src/py/bbctrl/Planner.py | 32 +- src/py/bbctrl/Pwr.py | 13 +- src/py/bbctrl/State.py | 20 +- src/py/bbctrl/Web.py | 150 +- src/py/bbctrl/__init__.py | 8 +- src/py/inevent/Event.py | 4 +- src/py/inevent/EventStream.py | 2 +- src/py/inevent/FindDevices.py | 20 +- src/resources/config-template.json | 7 + src/resources/css/fd-slider-tooltip.css | 109 -- src/resources/css/fd-slider.css | 1004 ------------- src/resources/js/fd-slider.min.js | 2 - src/stylus/style.styl | 101 +- 39 files changed, 2307 insertions(+), 1417 deletions(-) create mode 100644 jshint.json create mode 100644 package-lock.json create mode 100644 src/jade/templates/console.jade create mode 100644 src/js/console.js delete mode 100644 src/js/slider.js create mode 100644 src/py/bbctrl/Messages.py delete mode 100644 src/resources/css/fd-slider-tooltip.css delete mode 100644 src/resources/css/fd-slider.css delete mode 100644 src/resources/js/fd-slider.min.js diff --git a/Makefile b/Makefile index aaaf44b..8b15435 100644 --- a/Makefile +++ b/Makefile @@ -136,6 +136,14 @@ build/css/%.css: src/stylus/%.styl node_modules mkdir -p $(shell dirname $@) $(STYLUS) < $< > $@ || (rm -f $@; exit 1) +pylint: + pylint3 -E $(shell find src/py -name \*.py) + +jshint: + ./node_modules/jshint/bin/jshint --config jshint.json src/js/*.js + +lint: pylint jshint + watch: @clear $(MAKE) @@ -159,4 +167,4 @@ dist-clean: clean rm -rf node_modules .PHONY: all install html css static templates clean tidy copy mount umount pkg -.PHONY: gplan +.PHONY: gplan lint pylint jshint diff --git a/jshint.json b/jshint.json new file mode 100644 index 0000000..4a7add2 --- /dev/null +++ b/jshint.json @@ -0,0 +1,14 @@ +{ + "asi": true, + "browser": true, + "devel": true, + "strict": "global", + "globals": { + "$": false, + "require": false, + "module": false, + "Vue": false, + "SockJS": false, + "Gauge": false + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..9e7bec2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1794 @@ +{ + "name": "bbctrl", + "version": "0.3.4", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@browserify/acorn5-object-spread": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@browserify/acorn5-object-spread/-/acorn5-object-spread-5.0.1.tgz", + "integrity": "sha512-sFCUPzgeEjdq3rinwy4TFXtak2YZdhqpj6MdNusxkdTFr9TXAUEYK4YQSamR8Joqt/yii1drgl5hk8q/AtJDKA==", + "requires": { + "acorn": "5.3.0" + }, + "dependencies": { + "acorn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==" + } + } + }, + "JSONStream": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", + "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", + "requires": { + "jsonparse": "1.3.1", + "through": "2.3.8" + } + }, + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + }, + "acorn-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz", + "integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=", + "requires": { + "acorn": "2.7.0" + }, + "dependencies": { + "acorn": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", + "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=" + } + } + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "requires": { + "color-convert": "1.9.1" + } + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=" + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=" + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=" + }, + "asap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz", + "integrity": "sha1-sqRdpf36ILBJb8N2jMJ8EvqRan0=" + }, + "asn1.js": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz", + "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==", + "requires": { + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "requires": { + "util": "0.10.3" + } + }, + "astw": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz", + "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=", + "requires": { + "acorn": "4.0.13" + } + }, + "autoprefixer": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.5.tgz", + "integrity": "sha512-XqHfo8Ht0VU+T5P+eWEVoXza456KJ4l62BPewu3vpNf3LP9s2+zYXkXBznzYby4XeECXgG3N4i+hGvOhXErZmA==", + "requires": { + "browserslist": "2.11.1", + "caniuse-lite": "1.0.30000791", + "normalize-range": "0.1.2", + "num2fraction": "1.2.2", + "postcss": "6.0.16", + "postcss-value-parser": "3.3.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", + "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==" + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browser-pack": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.2.tgz", + "integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=", + "requires": { + "JSONStream": "1.3.2", + "combine-source-map": "0.7.2", + "defined": "1.0.0", + "through2": "2.0.3", + "umd": "3.0.1" + } + }, + "browser-resolve": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", + "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" + } + } + }, + "browserify": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-15.1.0.tgz", + "integrity": "sha512-CulQKBiROFN+EssphwJEY4wWBACqWR1Iv+wxgO0GvOiweLb1Rwja4J/XbTCxx1ixTDK6llgUB3iG8fFxLBbJDA==", + "requires": { + "JSONStream": "1.3.2", + "assert": "1.4.1", + "browser-pack": "6.0.2", + "browser-resolve": "1.11.2", + "browserify-zlib": "0.2.0", + "buffer": "5.0.8", + "cached-path-relative": "1.0.1", + "concat-stream": "1.5.2", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "defined": "1.0.0", + "deps-sort": "2.0.0", + "domain-browser": "1.1.7", + "duplexer2": "0.1.4", + "events": "1.1.1", + "glob": "7.1.2", + "has": "1.0.1", + "htmlescape": "1.1.1", + "https-browserify": "1.0.0", + "inherits": "2.0.3", + "insert-module-globals": "7.0.1", + "labeled-stream-splicer": "2.0.0", + "module-deps": "5.0.1", + "os-browserify": "0.3.0", + "parents": "1.0.1", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "read-only-stream": "2.0.0", + "readable-stream": "2.3.3", + "resolve": "1.5.0", + "shasum": "1.0.2", + "shell-quote": "1.6.1", + "stream-browserify": "2.0.1", + "stream-http": "2.7.2", + "string_decoder": "1.0.3", + "subarg": "1.0.0", + "syntax-error": "1.3.0", + "through2": "2.0.3", + "timers-browserify": "1.4.2", + "tty-browserify": "0.0.0", + "url": "0.11.0", + "util": "0.10.3", + "vm-browserify": "0.0.4", + "xtend": "4.0.1" + } + }, + "browserify-aes": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", + "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", + "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "requires": { + "browserify-aes": "1.1.1", + "browserify-des": "1.0.0", + "evp_bytestokey": "1.0.3" + } + }, + "browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "requires": { + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "requires": { + "bn.js": "4.11.8", + "randombytes": "2.0.6" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "requires": { + "pako": "1.0.6" + } + }, + "browserslist": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.1.tgz", + "integrity": "sha512-Gp4oJOQOby5TpOJJuUtCrGE0KSJOUYVa/I+/3eD/TRWEK8jqZuJPAK1t+VuG6jp0keudrqtxlH4MbYbmylun9g==", + "requires": { + "caniuse-lite": "1.0.30000791", + "electron-to-chromium": "1.3.30" + } + }, + "buffer": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.0.8.tgz", + "integrity": "sha512-xXvjQhVNz50v2nPeoOsNqWCLGfiv4ji/gXZM28jnVwdLJxH4mFyqgqCKfaK9zf1KUbG6zTkjLOy7ou+jSMarGA==", + "requires": { + "base64-js": "1.2.1", + "ieee754": "1.1.8" + } + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + }, + "cached-path-relative": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", + "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=" + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "caniuse-lite": { + "version": "1.0.30000791", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000791.tgz", + "integrity": "sha1-jjV0Xv1IOj4ju301CZAybSMZ/BY=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + }, + "dependencies": { + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "character-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-1.2.1.tgz", + "integrity": "sha1-wN3kqxgnE7kZuXCVmhI+zBow/NY=" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "clean-css": { + "version": "3.4.28", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", + "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", + "requires": { + "commander": "2.8.1", + "source-map": "0.4.4" + }, + "dependencies": { + "commander": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", + "requires": { + "graceful-readlink": "1.0.1" + } + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "cli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", + "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", + "requires": { + "exit": "0.1.2", + "glob": "7.1.2" + } + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + } + } + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "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=" + }, + "combine-source-map": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", + "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", + "requires": { + "convert-source-map": "1.1.3", + "inline-source-map": "0.6.2", + "lodash.memoize": "3.0.4", + "source-map": "0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "commander": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz", + "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.0.6", + "typedarray": "0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "requires": { + "date-now": "0.1.4" + } + }, + "constantinople": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.0.2.tgz", + "integrity": "sha1-S5RdmTeQe82Y7ldRIsOBdRZUQUE=", + "requires": { + "acorn": "2.7.0" + }, + "dependencies": { + "acorn": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", + "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=" + } + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" + }, + "convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "requires": { + "bn.js": "4.11.8", + "elliptic": "6.4.0" + } + }, + "create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "sha.js": "2.4.9" + } + }, + "create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "requires": { + "browserify-cipher": "1.0.0", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.0", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "diffie-hellman": "5.0.2", + "inherits": "2.0.3", + "pbkdf2": "3.0.14", + "public-encrypt": "4.0.0", + "randombytes": "2.0.6", + "randomfill": "1.0.3" + } + }, + "css": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/css/-/css-1.0.8.tgz", + "integrity": "sha1-k4aBHKgrzMnuf7WnMrHioxfIo+c=", + "requires": { + "css-parse": "1.0.4", + "css-stringify": "1.0.5" + } + }, + "css-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.0.4.tgz", + "integrity": "sha1-OLBQP7+dqfVOnB29pg4UXHcRe90=" + }, + "css-stringify": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/css-stringify/-/css-stringify-1.0.5.tgz", + "integrity": "sha1-sNBClG2ylTu50pKQCmy19tASIDE=" + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "requires": { + "JSONStream": "1.3.2", + "shasum": "1.0.2", + "subarg": "1.0.0", + "through2": "2.0.3" + } + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "detective": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.0.2.tgz", + "integrity": "sha512-NUsLoezj4wb9o7vpxS9F3L5vcO87ceyRBcl48op06YFNwkyIEY997JpSCA5lDlDuDc6JxOtaL5qfK3muoWxpMA==", + "requires": { + "@browserify/acorn5-object-spread": "5.0.1", + "acorn": "5.3.0", + "defined": "1.0.0" + }, + "dependencies": { + "acorn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==" + } + } + }, + "diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "requires": { + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.6" + } + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "requires": { + "domelementtype": "1.1.3", + "entities": "1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" + } + } + }, + "domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=" + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" + }, + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "requires": { + "domelementtype": "1.3.0" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" + } + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "requires": { + "readable-stream": "2.3.3" + } + }, + "electron-releases": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/electron-releases/-/electron-releases-2.1.0.tgz", + "integrity": "sha512-cyKFD1bTE/UgULXfaueIN1k5EPFzs+FRc/rvCY5tIynefAPqopQEgjr0EzY+U3Dqrk/G4m9tXSPuZ77v6dL/Rw==" + }, + "electron-to-chromium": { + "version": "1.3.30", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz", + "integrity": "sha512-zx1Prv7kYLfc4OA60FhxGbSo4qrEjgSzpo1/37i7l9ltXPYOoQBtjQxY9KmsgfHnBxHlBGXwLlsbt/gub1w5lw==", + "requires": { + "electron-releases": "2.1.0" + } + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=" + }, + "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=" + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "5.1.1" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "requires": { + "function-bind": "1.1.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + }, + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "requires": { + "inherits": "2.0.3" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=" + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.3.0", + "domutils": "1.5.1", + "entities": "1.0.0", + "readable-stream": "1.1.14" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" + }, + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "requires": { + "source-map": "0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "insert-module-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.1.tgz", + "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", + "requires": { + "JSONStream": "1.3.2", + "combine-source-map": "0.7.2", + "concat-stream": "1.5.2", + "is-buffer": "1.1.6", + "lexical-scope": "1.2.0", + "process": "0.11.10", + "through2": "2.0.3", + "xtend": "4.0.1" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "jade": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/jade/-/jade-1.11.0.tgz", + "integrity": "sha1-nIDlOMEtP7lcjZu5VZ+gzAQEBf0=", + "requires": { + "character-parser": "1.2.1", + "clean-css": "3.4.28", + "commander": "2.6.0", + "constantinople": "3.0.2", + "jstransformer": "0.0.2", + "mkdirp": "0.5.1", + "transformers": "2.1.0", + "uglify-js": "2.8.29", + "void-elements": "2.0.1", + "with": "4.0.3" + } + }, + "jshint": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz", + "integrity": "sha1-HnJSkVzmgbQIJ+4UJIxG006apiw=", + "requires": { + "cli": "1.0.1", + "console-browserify": "1.1.0", + "exit": "0.1.2", + "htmlparser2": "3.8.3", + "lodash": "3.7.0", + "minimatch": "3.0.4", + "shelljs": "0.3.0", + "strip-json-comments": "1.0.4" + } + }, + "json-stable-stringify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "requires": { + "jsonify": "0.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" + }, + "jstransformer": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-0.0.2.tgz", + "integrity": "sha1-eq4pqQPRls+glz2IXT5HlH7Ndqs=", + "requires": { + "is-promise": "2.1.0", + "promise": "6.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "1.1.6" + } + }, + "labeled-stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", + "integrity": "sha1-pS4dE4AkwAuGscDJH2d5GLiuClk=", + "requires": { + "inherits": "2.0.3", + "isarray": "0.0.1", + "stream-splicer": "2.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + } + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "lexical-scope": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", + "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", + "requires": { + "astw": "2.2.0" + } + }, + "lodash": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz", + "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=" + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=" + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + } + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0" + } + }, + "minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "module-deps": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-5.0.1.tgz", + "integrity": "sha512-sigq/hm/L+Z5IGi1DDl0x2ptkw7S86aFh213QhPLD8v9Opv90IHzKIuWJrRa5bJ77DVKHco2CfIEuThcT/vDJA==", + "requires": { + "JSONStream": "1.3.2", + "browser-resolve": "1.11.2", + "cached-path-relative": "1.0.1", + "concat-stream": "1.6.0", + "defined": "1.0.0", + "detective": "5.0.2", + "duplexer2": "0.1.4", + "inherits": "2.0.3", + "parents": "1.0.1", + "readable-stream": "2.3.3", + "resolve": "1.5.0", + "stream-combiner2": "1.1.1", + "subarg": "1.0.0", + "through2": "2.0.3", + "xtend": "4.0.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "optimist": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", + "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=", + "requires": { + "wordwrap": "0.0.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==" + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "requires": { + "path-platform": "0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "requires": { + "asn1.js": "4.9.2", + "browserify-aes": "1.1.1", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.14" + } + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=" + }, + "pbkdf2": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", + "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "requires": { + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, + "postcss": { + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz", + "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==", + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "5.1.0" + } + }, + "postcss-value-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "promise": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-6.1.0.tgz", + "integrity": "sha1-LOcp9rlLRcJoka0GAsXJDgTG7vY=", + "requires": { + "asap": "1.0.0" + } + }, + "public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "parse-asn1": "5.1.0", + "randombytes": "2.0.6" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "randomfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", + "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", + "requires": { + "randombytes": "2.0.6", + "safe-buffer": "5.1.1" + } + }, + "read-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "requires": { + "readable-stream": "2.3.3" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "requires": { + "path-parse": "1.0.5" + } + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "requires": { + "align-text": "0.1.4" + } + }, + "ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "requires": { + "hash-base": "2.0.2", + "inherits": "2.0.3" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "sax": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" + }, + "sha.js": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", + "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "requires": { + "json-stable-stringify": "0.0.1", + "sha.js": "2.4.9" + } + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "requires": { + "array-filter": "0.0.1", + "array-map": "0.0.0", + "array-reduce": "0.0.0", + "jsonify": "0.0.0" + } + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "requires": { + "duplexer2": "0.1.4", + "readable-stream": "2.3.3" + } + }, + "stream-http": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", + "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "requires": { + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=" + }, + "stylus": { + "version": "0.54.5", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", + "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", + "requires": { + "css-parse": "1.7.0", + "debug": "3.1.0", + "glob": "7.0.6", + "mkdirp": "0.5.1", + "sax": "0.5.8", + "source-map": "0.1.43" + }, + "dependencies": { + "css-parse": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", + "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=" + }, + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "subarg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", + "requires": { + "minimist": "1.2.0" + } + }, + "supports-color": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", + "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", + "requires": { + "has-flag": "2.0.0" + } + }, + "syntax-error": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.3.0.tgz", + "integrity": "sha1-HtkmbE1AvnXcVb+bsct3Biu5bKE=", + "requires": { + "acorn": "4.0.13" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "requires": { + "process": "0.11.10" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" + }, + "transformers": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/transformers/-/transformers-2.1.0.tgz", + "integrity": "sha1-XSPLNVYd2F3Gf7hIIwm0fVPM6ac=", + "requires": { + "css": "1.0.8", + "promise": "2.0.0", + "uglify-js": "2.2.5" + }, + "dependencies": { + "is-promise": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz", + "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU=" + }, + "promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-2.0.0.tgz", + "integrity": "sha1-RmSKqdYFr10ucMMCS/WUNtoCuA4=", + "requires": { + "is-promise": "1.0.1" + } + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "requires": { + "amdefine": "1.0.1" + } + }, + "uglify-js": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.2.5.tgz", + "integrity": "sha1-puAqcNg5eSuXgEiLe4sYTAlcmcc=", + "requires": { + "optimist": "0.3.7", + "source-map": "0.1.43" + } + } + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "optional": true + }, + "umd": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz", + "integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4=" + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + } + } + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "requires": { + "indexof": "0.0.1" + } + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=" + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "with": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/with/-/with-4.0.3.tgz", + "integrity": "sha1-7v0VTp550sjTQXtkeo8U2f7M4U4=", + "requires": { + "acorn": "1.2.2", + "acorn-globals": "1.0.9" + }, + "dependencies": { + "acorn": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz", + "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ=" + } + } + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } +} diff --git a/package.json b/package.json index c7ca019..214a07f 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,14 @@ { "name": "bbctrl", - "version": "0.3.4", - "homepage": "https://github.com/buildbotics/bbctrl-firmware", - "license": "GPL 3+", + "version": "0.3.3", + "homepage": "http://buildbotics.com/", + "repository": "https://github.com/buildbotics/bbctrl-firmware", + "license": "GPL-3.0+", "dependencies": { "autoprefixer": ">=3.0.0", "jade": ">=1.3.0", "stylus": ">=0.42.3", - "browserify": ">=8.1.1" + "browserify": ">=8.1.1", + "jshint": "" } } diff --git a/src/jade/index.jade b/src/jade/index.jade index de30069..fc38c53 100644 --- a/src/jade/index.jade +++ b/src/jade/index.jade @@ -66,12 +66,45 @@ html(lang="en") .title span.left Build span.right botics - .subtitle Machine Controller + .subtitle + | Machine Controller v{{config.version}} + a.upgrade-version(v-if="show_upgrade()", href="#admin") + | Upgrade to v{{latestVersion}} + .fa.fa-check(v-if="!show_upgrade() && latestVersion", + title="Firmware up to date") .content(class="{{currentView}}-view") component(:is="currentView + '-view'", :index="index", :config="config", :template="template", :state="state", keep-alive) + message.error-message(:show.sync="errorShow") + div(slot="header") + .estop(:class="{active: state.es}"): estop(@click="estop") + h3 ERROR: {{errorMessage}} + + div(slot="body") + console + + message(:show.sync="confirmUpgrade") + h3(slot="header") Upgrade Firmware? + div(slot="body") + p + | Are you sure you want to upgrade the firmware to version + | {{latestVersion}}? + + p.pure-control-group + label(for="pass") Password + input(name="pass", v-model="password", type="password") + + div(slot="footer") + button.pure-button(@click="confirmUpgrade=false") Cancel + button.pure-button.pure-button-primary(@click="upgrade_confirmed") + | Upgrade + + message(:show.sync="firmwareUpgrading") + h3(slot="header") Firmware upgrading + p(slot="body") Please wait... + #templates include ../../build/templates.jade diff --git a/src/jade/templates/admin-view.jade b/src/jade/templates/admin-view.jade index 2687583..42b48fe 100644 --- a/src/jade/templates/admin-view.jade +++ b/src/jade/templates/admin-view.jade @@ -54,18 +54,9 @@ script#admin-view-template(type="text/x-template") button.pure-button.pure-button-primary(@click="upgrade") Upgrade p - table.pure-table - tr - th Current version - td {{config.version}} - - tr(v-if="latest") - th Latest version - td {{latest}} - - message(:show.sync="firmwareUpgrading") - h3(slot="header") Firmware upgrading - p(slot="body") Please wait... + input(type="checkbox", v-model="autoCheckUpgrade", + @change="change_auto_check_upgrade") + label(for="auto-check-upgrade")   Automatically check for upgrades message(:show.sync="hostnameSet") h3(slot="header") Hostname Set diff --git a/src/jade/templates/console.jade b/src/jade/templates/console.jade new file mode 100644 index 0000000..ec86cba --- /dev/null +++ b/src/jade/templates/console.jade @@ -0,0 +1,20 @@ +script#console-template(type="text/x-template") + .console + .toolbar + button.pure-button(title="Clear console.", @click="clear") + .fa.fa-trash + + table + tr + th Level + th Source + th Location + th Repeat + th Message + + tr(v-for="msg in messages.reverse()", :class="msg.level || 'info'") + td {{msg.level || 'info'}} + td {{msg.source || ''}} + td {{msg.where || ''}} + td {{msg.repeat}} + td {{msg.msg}} diff --git a/src/jade/templates/control-view.jade b/src/jade/templates/control-view.jade index 7a808ad..8d741ff 100644 --- a/src/jade/templates/control-view.jade +++ b/src/jade/templates/control-view.jade @@ -241,27 +241,10 @@ script#control-view-template(type="text/x-template") center Jogging speed is set by the ring that is clicked. section#content4.tab-content - .toolbar - button.pure-button(title="Clear console.", @click="clear_console") - .fa.fa-trash - - table.console - tr - th Level - th Location - th Code - th Repeat - th Message - - tr(v-for="msg in console", :class="msg.level || 'info'") - td {{msg.level || 'info'}} - td {{msg.where || ''}} - td {{msg.code || '0'}} - td {{msg.repeat}} - td {{msg.msg}} + console section#content5.tab-content - component(is="indicators", :state="state") + indicators(:state="state") section#content6.tab-content .video diff --git a/src/js/admin-view.js b/src/js/admin-view.js index 83dd874..658c511 100644 --- a/src/js/admin-view.js +++ b/src/js/admin-view.js @@ -6,7 +6,7 @@ var api = require('./api'); module.exports = { template: '#admin-view-template', - props: ['config'], + props: ['config', 'state'], data: function () { @@ -14,7 +14,6 @@ module.exports = { configRestored: false, confirmReset: false, configReset: false, - firmwareUpgrading: false, hostnameSet: false, usernameSet: false, passwordSet: false, @@ -24,7 +23,8 @@ module.exports = { username: '', current: '', password: '', - password2: '' + password2: '', + autoCheckUpgrade: true, } }, @@ -32,11 +32,15 @@ module.exports = { events: { connected: function () { if (this.firmwareUpgrading) location.reload(true); - } + }, + + latest_version: function (version) {this.latest = version} }, ready: function () { + this.autoCheckUpgrade = this.config.admin['auto-check-upgrade'] + api.get('hostname').done(function (hostname) { this.hostname = hostname; }.bind(this)); @@ -124,7 +128,7 @@ module.exports = { try { config = JSON.parse(e.target.result); - } catch (e) { + } catch (ex) { alert("Invalid config file"); return; } @@ -154,24 +158,13 @@ module.exports = { }, - check: function () { - $.ajax({ - type: 'GET', - url: 'https://buildbotics.com/bbctrl/latest.txt', - cache: false - - }).done(function (data) { - this.latest = data; - - }.bind(this)).fail(function (error) { - alert('Failed to get latest version information'); - }); - }, + check: function () {this.$dispatch('check')}, + upgrade: function () {this.$dispatch('upgrade')}, - upgrade: function () { - this.firmwareUpgrading = true; - api.put('upgrade'); + change_auto_check_upgrade: function () { + this.config.admin['auto-check-upgrade'] = this.autoCheckUpgrade; + this.$dispatch('config-changed'); } } } diff --git a/src/js/app.js b/src/js/app.js index 0690840..228db44 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -4,6 +4,21 @@ var api = require('./api'); var Sock = require('./sock'); +function compare_versions(a, b) { + var reStripTrailingZeros = /(\.0+)+$/; + var segsA = a.replace(reStripTrailingZeros, '').split('.'); + var segsB = b.replace(reStripTrailingZeros, '').split('.'); + var l = Math.min(segsA.length, segsB.length); + + for (var i = 0; i < l; i++) { + var diff = parseInt(segsA[i], 10) - parseInt(segsB[i], 10); + if (diff) return diff; + } + + return segsA.length - segsB.length; +} + + module.exports = new Vue({ el: 'body', @@ -16,7 +31,15 @@ module.exports = new Vue({ modified: false, template: {motors: {}, axes: {}}, config: {motors: [{}]}, - state: {} + state: {}, + messages: [], + errorShow: false, + errorMessage: '', + confirmUpgrade: false, + firmwareUpgrading: false, + checkedUpgrade: false, + latestVersion: '', + password: '' } }, @@ -46,7 +69,35 @@ module.exports = new Vue({ connected: function () {this.update()}, - update: function () {this.update()} + update: function () {this.update()}, + + + check: function () { + this.latestVersion = ''; + + $.ajax({ + type: 'GET', + url: 'https://buildbotics.com/bbctrl/latest.txt', + data: {hid: this.state.hid}, + cache: false + + }).done(function (data) { + this.latestVersion = data; + this.$broadcast('latest_version', data); + }.bind(this)) + }, + + + upgrade: function () { + this.password = ''; + this.confirmUpgrade = true; + }, + + + error: function (msg) { + this.errorShow = true; + this.errorMessage = msg.msg; + } }, @@ -63,6 +114,24 @@ module.exports = new Vue({ }, + upgrade_confirmed: function () { + this.confirmUpgrade = false; + + api.put('upgrade', {password: this.password}).done(function () { + this.firmwareUpgrading = true; + + }.bind(this)).fail(function () { + alert('Invalid password'); + }.bind(this)); + }, + + + show_upgrade: function () { + if (!this.latestVersion) return false; + return compare_versions(this.config.version, this.latestVersion) < 0; + }, + + update: function () { $.ajax({type: 'GET', url: '/config-template.json', cache: false}) .success(function (data, status, xhr) { @@ -71,6 +140,14 @@ module.exports = new Vue({ api.get('config/load').done(function (data) { this.config = data; this.parse_hash(); + + if (!this.checkedUpgrade) { + this.checkedUpgrade = true; + + var check = this.config.admin['auto-check-upgrade']; + if (typeof check == 'undefined' || check) + this.$emit('check'); + } }.bind(this)) }.bind(this)) }, @@ -82,12 +159,11 @@ module.exports = new Vue({ this.sock.onmessage = function (e) { var msg = e.data; - if (typeof msg == 'object') { - for (var key in msg) - Vue.set(this.state, key, msg[key]); - - if ('msg' in msg) this.$broadcast('message', msg); - } + if (typeof msg == 'object') + for (var key in msg) { + if (key == 'msg') this.$broadcast('message', msg.msg); + else Vue.set(this.state, key, msg[key]); + } }.bind(this); this.sock.onopen = function (e) { @@ -100,8 +176,6 @@ module.exports = new Vue({ this.status = 'disconnected'; this.$broadcast(this.status); }.bind(this); - - console.debug('Hello'); }, diff --git a/src/js/console.js b/src/js/console.js new file mode 100644 index 0000000..d8cb148 --- /dev/null +++ b/src/js/console.js @@ -0,0 +1,59 @@ +'use strict' + + +function _msg_equal(a, b) { + return a.level == b.level && a.location == b.location && a.code == b.code && + a.msg == b.msg; +} + + +// Shared among all instances +var messages = []; + + +module.exports = { + template: '#console-template', + + + data: function () { + return {messages: messages} + }, + + + events: { + message: function (msg) { + // There may be multiple instances of this module so ignore messages + // that have already been processed. + if (msg.logged) return; + msg.logged = true; + + // Make sure we have a message level + msg.level = msg.level || 'info'; + + // Add to message log and count and collapse repeats + if (messages.length && _msg_equal(msg, messages[messages.length - 1])) + messages[messages.length - 1].repeat++; + + else { + msg.repeat = 1; + messages.push(msg); + } + + // Write message to browser console for debugging + var text = JSON.stringify(msg); + if (msg.level == 'error' || msg.level == 'critical') console.error(text); + else if (msg.level == 'warning') console.warn(text); + else if (msg.level == 'debug' && console.debug) console.debug(text); + else console.log(text); + + // Event on errors + if (msg.level == 'error' || msg.level == 'critical') + this.$dispatch('error', msg); + } + }, + + + methods: { + clear: function () {messages.length = 0;}, + } +} diff --git a/src/js/control-view.js b/src/js/control-view.js index 3e4eb6f..32a647d 100644 --- a/src/js/control-view.js +++ b/src/js/control-view.js @@ -8,12 +8,6 @@ function _is_array(x) { } -function _msg_equal(a, b) { - return a.level == b.level && a.location == b.location && a.code == b.code && - a.msg == b.msg; -} - - function escapeHTML(s) { var entityMap = {'&': '&', '<': '<', '>': '>'}; return String(s).replace(/[&<>]/g, function (s) {return entityMap[s];}); @@ -34,7 +28,6 @@ module.exports = { axes: 'xyzabc', gcode: [], history: [], - console: [], speed_override: 1, feed_override: 1, manual_home: {x: false, y: false, z: false, a: false, b: false, c: false}, @@ -62,25 +55,11 @@ module.exports = { var data = {}; data[axis] = power; api.put('jog', data); - }, - - - message: function (msg) { - if (this.console.length && - _msg_equal(msg, this.console[this.console.length - 1])) - this.console[this.console.length - 1].repeat++; - - else { - msg.repeat = 1; - this.console.push(msg); - } } }, - ready: function () { - this.update(); - }, + ready: function () {this.update()}, methods: { @@ -99,7 +78,7 @@ module.exports = { get_axis_motor_id: function (axis) { - var axis = axis.toLowerCase(); + axis = axis.toLowerCase(); for (var i = 0; i < this.config.motors.length; i++) { var motor = this.config.motors[i]; @@ -121,8 +100,8 @@ module.exports = { if (typeof motor == 'undefined') return; if (typeof motor[name] != 'undefined') return motor[name]; - for (var section in this.template['motors']) { - var sec = this.template['motors'][section]; + for (var section in this.template.motors) { + var sec = this.template.motors[section]; if (typeof sec[name] != 'undefined') return sec[name]['default']; } }, @@ -310,9 +289,6 @@ module.exports = { }, - clear_console: function () {this.console = [];}, - - load_video: function () { this.video_url = '//' + document.location.hostname + ':8000/stream/0?=' + Math.random(); diff --git a/src/js/gauge.js b/src/js/gauge.js index dda1b4b..0b7cf7f 100644 --- a/src/js/gauge.js +++ b/src/js/gauge.js @@ -1,3 +1,6 @@ +'use strict'; + + module.exports = Vue.extend({ template: '
', diff --git a/src/js/io-view.js b/src/js/io-view.js index 1430f10..1b9cc47 100644 --- a/src/js/io-view.js +++ b/src/js/io-view.js @@ -43,8 +43,8 @@ module.exports = { this.outputs = this.config.outputs; else this.outputs = {}; - var template = this.template.outputs; - for (var key in template) + template = this.template.outputs; + for (key in template) if (!this.outputs.hasOwnProperty(key)) this.$set('outputs["' + key + '"]', template[key].default); }.bind(this)); diff --git a/src/js/main.js b/src/js/main.js index eca6d06..d36eb09 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -1,12 +1,16 @@ +'use strict'; + + $(function() { // Vue debugging Vue.config.debug = true; - Vue.util.warn = function (msg) {console.debug('[Vue warn]: ' + msg)} + //Vue.util.warn = function (msg) {console.debug('[Vue warn]: ' + msg)} // Register global components Vue.component('templated-input', require('./templated-input')); Vue.component('message', require('./message')); Vue.component('indicators', require('./indicators')); + Vue.component('console', require('./console')); Vue.filter('percent', function (value, precision) { if (typeof precision == 'undefined') precision = 2; diff --git a/src/js/motor-view.js b/src/js/motor-view.js index adc7d11..71ca620 100644 --- a/src/js/motor-view.js +++ b/src/js/motor-view.js @@ -36,7 +36,7 @@ module.exports = { slave_update: function () { var slave = false; for (var i = 0; i < this.index; i++) - if (this.motor['axis'] == this.config.motors[i]['axis']) + if (this.motor.axis == this.config.motors[i].axis) slave = true; var el = $(this.$el); diff --git a/src/js/slider.js b/src/js/slider.js deleted file mode 100644 index f25f873..0000000 --- a/src/js/slider.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = new Vue({ - template: '', - replace: true, - - - props: { - value: Number, - min: Number, - max: Number, - step: Number - }, - - - data: function () { - return { - } - }, - - - compiled: function () { - this.$el.attributes.min = this.min; - this.$el.attributes.max = this.max; - this.$el.attributes.step = this.step; - } -} diff --git a/src/js/tool-view.js b/src/js/tool-view.js index 00fe6fe..5a00006 100644 --- a/src/js/tool-view.js +++ b/src/js/tool-view.js @@ -1,4 +1,4 @@ -'use strict' +'use strict'; module.exports = { diff --git a/src/py/bbctrl/APIHandler.py b/src/py/bbctrl/APIHandler.py index 53e1eb1..77c2081 100644 --- a/src/py/bbctrl/APIHandler.py +++ b/src/py/bbctrl/APIHandler.py @@ -1,9 +1,9 @@ import json -import tornado.web +from tornado.web import RequestHandler, HTTPError import tornado.httpclient -class APIHandler(tornado.web.RequestHandler): +class APIHandler(RequestHandler): def __init__(self, app, request, **kwargs): super(APIHandler, self).__init__(app, request, **kwargs) self.ctrl = app.ctrl @@ -14,7 +14,7 @@ class APIHandler(tornado.web.RequestHandler): self.write_json('ok') - def delete_ok(self): raise tornado.httpclient.HTTPError(405) + def delete_ok(self): raise HTTPError(405) def put(self, *args, **kwargs): @@ -22,7 +22,7 @@ class APIHandler(tornado.web.RequestHandler): self.write_json('ok') - def put_ok(self): raise tornado.httpclient.HTTPError(405) + def put_ok(self): raise HTTPError(405) def prepare(self): @@ -32,7 +32,7 @@ class APIHandler(tornado.web.RequestHandler): try: self.json = tornado.escape.json_decode(self.request.body) except ValueError: - self.send_error(400, message = 'Unable to parse JSON.') + raise HTTPError(400, 'Unable to parse JSON.') def set_default_headers(self): diff --git a/src/py/bbctrl/AVR.py b/src/py/bbctrl/AVR.py index 96b1a80..b9ccdfd 100644 --- a/src/py/bbctrl/AVR.py +++ b/src/py/bbctrl/AVR.py @@ -43,7 +43,7 @@ class AVR(): self.lcd_page = ctrl.lcd.add_new_page() self.install_page = True - ctrl.state.add_listener(lambda x: self._update_state(x)) + ctrl.state.add_listener(self._update_state) try: self.sp = serial.Serial(ctrl.args.serial, ctrl.args.baud, @@ -78,12 +78,12 @@ class AVR(): retry -= 1 if retry: - log.error('AVR I2C communication failed, retrying: %s' % e) + log.warning('AVR I2C failed, retrying: %s' % e) time.sleep(0.1) continue else: - log.error('AVR I2C communication failed: %s' % e) + log.error('AVR I2C failed: %s' % e) raise @@ -118,7 +118,7 @@ class AVR(): if self.ctrl.ioloop.READ & events: self._serial_read() if self.ctrl.ioloop.WRITE & events: self._serial_write() except Exception as e: - log.error('Serial handler error: %s', traceback.format_exc()) + log.warning('Serial handler error: %s', traceback.format_exc()) def _serial_write(self): @@ -173,7 +173,7 @@ class AVR(): msg = json.loads(line) except Exception as e: - log.error('%s, data: %s', e, line) + log.warning('%s, data: %s', e, line) continue if 'variables' in msg: @@ -192,7 +192,7 @@ class AVR(): if update: if 'firmware' in update: - log.error('AVR rebooted') + log.warning('firmware rebooted') self.connect() self.ctrl.state.update(update) diff --git a/src/py/bbctrl/Cmd.py b/src/py/bbctrl/Cmd.py index e4d5fb6..c35f740 100755 --- a/src/py/bbctrl/Cmd.py +++ b/src/py/bbctrl/Cmd.py @@ -45,11 +45,6 @@ def encode_axes(axes): return data -def seek(switch, open, error): - flags = (SEEK_OPEN if open else 0) | (SEEK_ERROR if error else 0) - return '%c%x%x' % (SEEK, switch, flags) - - def line_number(line): return '#ln=%d' % line diff --git a/src/py/bbctrl/Config.py b/src/py/bbctrl/Config.py index 2e63861..d66ecbe 100644 --- a/src/py/bbctrl/Config.py +++ b/src/py/bbctrl/Config.py @@ -19,6 +19,7 @@ default_config = { "outputs": {}, "tool": {}, "gcode": {}, + "admin": {}, } diff --git a/src/py/bbctrl/Ctrl.py b/src/py/bbctrl/Ctrl.py index bb2cbf9..039e4da 100644 --- a/src/py/bbctrl/Ctrl.py +++ b/src/py/bbctrl/Ctrl.py @@ -31,6 +31,7 @@ class Ctrl(object): self.args = args self.ioloop = ioloop + self.msgs = bbctrl.Messages(self) self.state = bbctrl.State(self) self.planner = bbctrl.Planner(self) self.i2c = bbctrl.I2C(args.i2c_port) diff --git a/src/py/bbctrl/Jog.py b/src/py/bbctrl/Jog.py index 222abb6..6740b4d 100644 --- a/src/py/bbctrl/Jog.py +++ b/src/py/bbctrl/Jog.py @@ -53,7 +53,7 @@ class Jog(inevent.JogHandler): axes = {} for i in range(len(self.v)): axes["xyzabc"[i]] = self.v[i] self.ctrl.avr.jog(axes) - except Exception as e: log.error('Jog: %s', e) + except Exception as e: log.warning('Jog: %s', e) self.ctrl.ioloop.call_later(0.25, self.callback) diff --git a/src/py/bbctrl/LCD.py b/src/py/bbctrl/LCD.py index e9d36fb..7c86305 100644 --- a/src/py/bbctrl/LCD.py +++ b/src/py/bbctrl/LCD.py @@ -79,7 +79,7 @@ class LCD: self.load_page(LCDPage(self, msg)) self._update() except IOError as e: - log.error('LCD communication failed: %s' % e) + log.warning('LCD communication failed: %s' % e) def new_screen(self): @@ -164,8 +164,8 @@ class LCD: self.addr = self.addrs[self.addr_num] self.lcd = None - log.error('LCD communication failed, ' + - 'retrying on address 0x%02x: %s' % (self.addr, e)) + log.warning('LCD communication failed, ' + + 'retrying on address 0x%02x: %s' % (self.addr, e)) self.reset = True self.timeout = self.ctrl.ioloop.call_later(1, self._update) diff --git a/src/py/bbctrl/Messages.py b/src/py/bbctrl/Messages.py new file mode 100644 index 0000000..4ce5e64 --- /dev/null +++ b/src/py/bbctrl/Messages.py @@ -0,0 +1,34 @@ +import os +import logging +import bbctrl + + +log = logging.getLogger('Msgs') + + +class Messages(logging.Handler): + def __init__(self, ctrl): + logging.Handler.__init__(self, logging.WARNING) + + self.ctrl = ctrl + self.listeners = [] + + logging.getLogger().addHandler(self) + + + def add_listener(self, listener): self.listeners.append(listener) + def remove_listener(self, listener): self.listeners.remove(listener) + + + # From logging.Handler + def emit(self, record): + msg = dict( + level = record.levelname.lower(), + source = record.name, + msg = record.getMessage()) + + if hasattr(record, 'where'): msg['where'] = record.where + else: msg['where'] = '%s:%d' % (record.filename, record.lineno) + + for listener in self.listeners: + listener(msg) diff --git a/src/py/bbctrl/Planner.py b/src/py/bbctrl/Planner.py index 6b737e4..ee25cb6 100644 --- a/src/py/bbctrl/Planner.py +++ b/src/py/bbctrl/Planner.py @@ -1,10 +1,13 @@ import json +import re import logging -import camotics.gplan as gplan +import camotics.gplan as gplan # pylint: disable=no-name-in-module,import-error import bbctrl.Cmd as Cmd log = logging.getLogger('Planner') +reLogLine = re.compile( + r'^(?P[A-Z])[0-9 ]:((?P[^:]+:\d+:\d+):)?(?P.*)$') class Planner(): @@ -13,7 +16,7 @@ class Planner(): self.lastID = -1 self.mode = 'idle' - ctrl.state.add_listener(lambda x: self.update(x)) + ctrl.state.add_listener(self.update) self.reset() @@ -90,15 +93,22 @@ class Planner(): def log(self, line): line = line.strip() - if len(line) < 3: return - - if line[0] == 'I': log.info(line[3:]) - elif line[0] == 'D': log.debug(line[3:]) - # TODO send these to the LCD and Web - elif line[0] == 'W': log.warning(line[3:]) - elif line[0] == 'E': log.error(line[3:]) - elif line[0] == 'C': log.critical(line[3:]) - else: raise Exception('Could not parse planner log line: ' + line) + m = reLogLine.match(line) + if not m: return + + level = m.group('level') + msg = m.group('msg') + where = m.group('where') + + if where is not None: extra = dict(where = where) + else: extra = None + + if level == 'I': log.info (msg, extra = extra) + elif level == 'D': log.debug (msg, extra = extra) + elif level == 'W': log.warning (msg, extra = extra) + elif level == 'E': log.error (msg, extra = extra) + elif level == 'C': log.critical(msg, extra = extra) + else: log.error('Could not parse planner log line: ' + line) def mdi(self, cmd): diff --git a/src/py/bbctrl/Pwr.py b/src/py/bbctrl/Pwr.py index 50847b0..35927ad 100644 --- a/src/py/bbctrl/Pwr.py +++ b/src/py/bbctrl/Pwr.py @@ -42,14 +42,15 @@ class Pwr(): flags = self.regs[FLAGS_REG] errors = [] - if flags & UNDER_VOLTAGE_FLAG: errors.push('under voltage') - if flags & OVER_VOLTAGE_FLAG: errors.push('over voltage') - if flags & OVER_CURRENT_FLAG: errors.push('over current') - if flags & MEASUREMENT_ERROR_FLAG: errors.push('measurement error') - if flags & SHUNT_OVERLOAD_FLAG: errors.push('shunt overload') + # Decode error flags + if flags & UNDER_VOLTAGE_FLAG: errors.append('under voltage') + if flags & OVER_VOLTAGE_FLAG: errors.append('over voltage') + if flags & OVER_CURRENT_FLAG: errors.append('over current') + if flags & MEASUREMENT_ERROR_FLAG: errors.append('measurement error') + if flags & SHUNT_OVERLOAD_FLAG: errors.append('shunt overload') # Report errors - self.ctrl.state.set('pwr_errors', errors) + if errors: log.error('Power fault: ' + ', '.join(errors)) def _update(self): diff --git a/src/py/bbctrl/State.py b/src/py/bbctrl/State.py index d4e1f45..d98e0fd 100644 --- a/src/py/bbctrl/State.py +++ b/src/py/bbctrl/State.py @@ -1,4 +1,5 @@ import logging +import traceback import bbctrl @@ -14,8 +15,7 @@ class State(object): self.vars = {} self.callbacks = {} self.changes = {} - self.next_id = 1 - self.listeners = {} + self.listeners = [] self.timeout = None self.machine_vars = {} self.machine_var_set = set() @@ -37,12 +37,13 @@ class State(object): def _notify(self): if not self.changes: return - for listener in self.listeners.values(): + for listener in self.listeners: try: listener(self.changes) except Exception as e: - log.error('Updating listener: %s', traceback.format_exc()) + log.warning('Updating state listener: %s', + traceback.format_exc()) self.changes = {} self.timeout = None @@ -83,7 +84,7 @@ class State(object): if name in self.vars: return self.vars[name] if name in self.callbacks: return self.callbacks[name](name) - if default is None: log.error('State variable "%s" not found' % name) + if default is None: log.warning('State variable "%s" not found' % name) return default @@ -93,16 +94,11 @@ class State(object): def add_listener(self, listener): - sid = self.next_id - self.next_id += 1 - - self.listeners[sid] = listener + self.listeners.append(listener) if self.vars: listener(self.vars) - return sid - - def remove_listener(self, sid): del self.listeners[sid] + def remove_listener(self, listener): self.listeners.remove(listener) def machine_cmds_and_vars(self, data): diff --git a/src/py/bbctrl/Web.py b/src/py/bbctrl/Web.py index 5e57a9d..201cf25 100644 --- a/src/py/bbctrl/Web.py +++ b/src/py/bbctrl/Web.py @@ -9,6 +9,7 @@ import shutil import tarfile import subprocess import socket +from tornado.web import HTTPError import bbctrl @@ -19,10 +20,36 @@ log = logging.getLogger('Web') def call_get_output(cmd): p = subprocess.Popen(cmd, stdout = subprocess.PIPE) s = p.communicate()[0].decode('utf-8') - if p.returncode: raise Exception('Command failed') + if p.returncode: raise HTTPError(400, 'Command failed') return s +def get_username(): + return call_get_output(['getent', 'passwd', '1001']).split(':')[0] + + +def set_username(username): + if subprocess.call(['usermod', '-l', username, get_username()]): + raise HTTPError(400, 'Failed to set username to "%s"' % username) + + +def check_password(password): + # Get current password + s = call_get_output(['getent', 'shadow', get_username()]) + current = s.split(':')[1].split('$') + + # Check password type + if current[1] != '1': + raise HTTPError(400, "Don't know how to update non-MD5 password") + + # Check current password + cmd = ['openssl', 'passwd', '-salt', current[2], '-1', password] + s = call_get_output(cmd).strip() + + if s.split('$') != current: raise HTTPError(401, 'Wrong password') + + + class RebootHandler(bbctrl.APIHandler): def put_ok(self): subprocess.Popen('reboot') @@ -37,53 +64,22 @@ class HostnameHandler(bbctrl.APIHandler): self.write_json('ok') return - self.send_error(400, message = 'Failed to set hostname: %s' % self.json) - - -def get_username(): - return call_get_output(['getent', 'passwd', '1001']).split(':')[0] + raise HTTPError(400, 'Failed to set hostname') class UsernameHandler(bbctrl.APIHandler): def get(self): self.write_json(get_username()) - def put(self): - if 'username' in self.json: - username = get_username() - - if subprocess.call(['usermod', '-l', self.json['username'], - username]) == 0: - self.write_json('ok') - return - - self.send_error(400, message = 'Failed to set username: %s' % self.json) + def put_ok(self): + if 'username' in self.json: set_username(self.json['username']) + else: raise HTTPError(400, 'Missing "username"') class PasswordHandler(bbctrl.APIHandler): def put(self): if 'current' in self.json and 'password' in self.json: - # Get current user name - username = get_username() - - # Get current password - s = call_get_output(['getent', 'shadow', username]) - password = s.split(':')[1].split('$') - - # Check password type - if password[1] != '1': - self.send_error(400, message = - "Don't know how to update non-MD5 password") - return - - # Check current password - cmd = ['openssl', 'passwd', '-salt', password[2], '-1', - self.json['current']] - s = call_get_output(cmd).strip() - if s.split('$') != password: - print('%s != %s' % (s.split('$'), password)) - self.send_error(401, message = 'Wrong password') - return + check_password(self.json['current']) # Set password s = '%s:%s' % (username, self.json['password']) @@ -97,7 +93,7 @@ class PasswordHandler(bbctrl.APIHandler): self.write_json('ok') return - self.send_error(400, message = 'Failed to set password') + raise HTTPError(401, 'Failed to set password') class ConfigLoadHandler(bbctrl.APIHandler): @@ -128,11 +124,10 @@ class FirmwareUpdateHandler(bbctrl.APIHandler): def prepare(self): pass - def put(self): + def put_ok(self): # Only allow this function in dev mode if not os.path.exists('/etc/bbctrl-dev-mode'): - self.send_error(403, message = 'Not in dev mode') - return + raise HTTPError(403, 'Not in dev mode') firmware = self.request.files['firmware'][0] @@ -143,11 +138,11 @@ class FirmwareUpdateHandler(bbctrl.APIHandler): subprocess.Popen(['/usr/local/bin/update-bbctrl']) - self.write_json('ok') - class UpgradeHandler(bbctrl.APIHandler): - def put_ok(self): subprocess.Popen(['/usr/local/bin/upgrade-bbctrl']) + def put_ok(self): + check_password(self.json['password']) + subprocess.Popen(['/usr/local/bin/upgrade-bbctrl']) class HomeHandler(bbctrl.APIHandler): @@ -156,7 +151,7 @@ class HomeHandler(bbctrl.APIHandler): if set_home: if not 'position' in self.json: - raise Exception('Missing "position"') + raise HTTPError(400, 'Missing "position"') self.ctrl.avr.home(axis, self.json['position']) @@ -212,58 +207,59 @@ class JogHandler(bbctrl.APIHandler): def put_ok(self): self.ctrl.avr.jog(self.json) -# Used by CAMotics -class WSConnection(tornado.websocket.WebSocketHandler): - def __init__(self, app, request, **kwargs): - super(WSConnection, self).__init__(app, request, **kwargs) - self.ctrl = app.ctrl - self.timer = None +# Base class for Web Socket connections +class ClientConnection(object): + def __init__(self, ctrl): + self.ctrl = ctrl + self.count = 0 def heartbeat(self): - self.timer = self.ctrl.ioloop.call_later(3, self.heartbeat) - self.write_message({'heartbeat': self.count}) + self.ctrl.ioloop.call_later(3, self.heartbeat) + self.send({'heartbeat': self.count}) self.count += 1 - def open(self): - self.timer = self.ctrl.ioloop.call_later(3, self.heartbeat) - self.count = 0; - self.sid = self.ctrl.state.add_listener(lambda x: self.write_message(x)) + def notify(self, msg): self.send(dict(msg = msg)) + def send(self, msg): raise HTTPError(400, 'Not implemented') - def on_close(self): - if self.timer is not None: self.ctrl.ioloop.remove_timeout(self.timer) - self.ctrl.state.remove_listener(self.sid) + def on_open(self, *args, **kwargs): + self.timer = self.ctrl.ioloop.call_later(3, self.heartbeat) + self.ctrl.state.add_listener(self.send) + self.ctrl.msgs.add_listener(self.notify) + self.is_open = True - def on_message(self, msg): pass + def on_close(self): + self.ctrl.ioloop.remove_timeout(self.timer) + self.ctrl.state.remove_listener(self.send) + self.ctrl.msgs.remove_listener(self.notify) -# Used by Web frontend -class SockJSConnection(sockjs.tornado.SockJSConnection): - def heartbeat(self): - self.timer = self.ctrl.ioloop.call_later(3, self.heartbeat) - self.send({'heartbeat': self.count}) - self.count += 1 + def on_message(self, data): self.ctrl.avr.mdi(data) - def on_open(self, info): - self.ctrl = self.session.server.ctrl +# Used by CAMotics +class WSConnection(ClientConnection, tornado.websocket.WebSocketHandler): + def __init__(self, app, request, **kwargs): + ClientConnection.__init__(self, app.ctrl) + tornado.websocket.WebSocketHandler.__init__( + self, app, request, **kwargs) - self.timer = self.ctrl.ioloop.call_later(3, self.heartbeat) - self.count = 0; - self.sid = self.ctrl.state.add_listener(lambda x: self.send(x)) + def send(self, msg): self.write_message(msg) + def open(self): self.on_open() - def on_close(self): - self.ctrl.ioloop.remove_timeout(self.timer) - self.ctrl.state.remove_listener(self.sid) +# Used by Web frontend +class SockJSConnection(ClientConnection, sockjs.tornado.SockJSConnection): + def __init__(self, session): + ClientConnection.__init__(self, session.server.ctrl) + sockjs.tornado.SockJSConnection.__init__(self, session) - def on_message(self, data): - self.ctrl.avr.mdi(data) + def send(self, msg): sockjs.tornado.SockJSConnection.send(self, msg) class StaticFileHandler(tornado.web.StaticFileHandler): diff --git a/src/py/bbctrl/__init__.py b/src/py/bbctrl/__init__.py index e152283..d33cb1c 100755 --- a/src/py/bbctrl/__init__.py +++ b/src/py/bbctrl/__init__.py @@ -22,6 +22,7 @@ from bbctrl.Pwr import Pwr from bbctrl.I2C import I2C from bbctrl.Planner import Planner from bbctrl.State import State +from bbctrl.Messages import Messages import bbctrl.Cmd as Cmd @@ -90,10 +91,9 @@ def run(): try: ioloop.start() - except KeyboardInterrupt: - on_exit() - - except: log.exception('') + except KeyboardInterrupt: on_exit() + except SystemExit: raise + except: logging.getLogger().exception('') if __name__ == "__main__": run() diff --git a/src/py/inevent/Event.py b/src/py/inevent/Event.py index 336ceb4..5603185 100644 --- a/src/py/inevent/Event.py +++ b/src/py/inevent/Event.py @@ -96,8 +96,8 @@ class Event(object): The output is packed into a string. It is unlikely that this function will be required, but it might as well be here. """ - tint = long(self.time) - tfrac = long((self.time - tint) * 1000000) + tsec = int(self.time) + tfrac = int((self.time - tsec) * 1000000) return struct.pack(_format, tsec, tfrac, self.type, self.code, self.value) diff --git a/src/py/inevent/EventStream.py b/src/py/inevent/EventStream.py index ba2709c..ac68222 100644 --- a/src/py/inevent/EventStream.py +++ b/src/py/inevent/EventStream.py @@ -143,7 +143,7 @@ class EventStream(object): return self - def next(self): + def __next__(self): """ Returns the next waiting event. diff --git a/src/py/inevent/FindDevices.py b/src/py/inevent/FindDevices.py index bfcbd4e..90cce2e 100644 --- a/src/py/inevent/FindDevices.py +++ b/src/py/inevent/FindDevices.py @@ -77,7 +77,7 @@ class DeviceCapabilities(object): firstLine) if not match: - log.warning("Do not understand device ID:", line) + log.warning("Do not understand device ID: %s", firstLine) self.bus = 0 self.vendor = 0 self.product = 0 @@ -173,15 +173,15 @@ class DeviceCapabilities(object): def __str__(self): return ( - "%s\n" - "Bus: %s Vendor: %s Product: %s Version: %s\n" - "Phys: %s\n" - "Sysfs: %s\n" - "Uniq: %s\n" - "Handlers: %s Event Index: %s\n" - "Keyboard: %s Mouse: %s Joystick: %s\n" - "Events: %s" % ( - self.name, self.bus. self.vendor, self.product, self.version, self.phys, + ("%s\n" + "Bus: %s Vendor: %s Product: %s Version: %s\n" + "Phys: %s\n" + "Sysfs: %s\n" + "Uniq: %s\n" + "Handlers: %s Event Index: %s\n" + "Keyboard: %s Mouse: %s Joystick: %s\n" + "Events: %s") % ( + self.name, self.bus, self.vendor, self.product, self.version, self.phys, self.sysfs, self.uniq, self.handlers, self.eventIndex, self.isKeyboard, self.isMouse, self.isJoystick, EvToStr(self.eventTypes))) diff --git a/src/resources/config-template.json b/src/resources/config-template.json index 15f3d7e..a1638bb 100644 --- a/src/resources/config-template.json +++ b/src/resources/config-template.json @@ -287,5 +287,12 @@ "type": "text", "default": "M2 (End program)\n" } + }, + + "admin": { + "auto-check-upgrade": { + "type": "bool", + "default": true + } } } diff --git a/src/resources/css/fd-slider-tooltip.css b/src/resources/css/fd-slider-tooltip.css deleted file mode 100644 index bbdd5b4..0000000 --- a/src/resources/css/fd-slider-tooltip.css +++ /dev/null @@ -1,109 +0,0 @@ -/* - Sample tooltip code. Only works on grade A browsers (so no IE6, 7 or 8). - - See: http://nicolasgallagher.com/multiple-backgrounds-and-borders-with-css2/ - for full info on how to style generated content & the associated pitfalls. -*/ - -.fd-slider-handle:before, -.fd-slider-handle:after - { - content:""; - /* Remove from screen */ - opacity:0; - -webkit-transition-property: all; - -moz-transition-property: all; - -ms-transition-property: all; - -o-transition-property: all; - transition-property: all; - -webkit-transition-duration: 0.3s; - -moz-transition-duration: 0.3s; - -ms-transition-duration: 0.3s; - -o-transition-duration: 0.3s; - transition-duration: 0.3s; - -webkit-transition-delay: 0.2s; - -moz-transition-delay: 0.2s; - -ms-transition-delay: 0.2s; - -o-transition-delay: 0.2s; - transition-delay: 0.2s; - } -/* - The tooltip body - as we position it above the slider and position the - tooltip arrow below it, we need to know the height of the body. This means - that multi-line tooltips are not supported. - - To support multi-line tooltips, you will need to position the tooltip below - the slider and the tooltip pointer above the tooltip body. Additionally, you - will have to set the tooltip body "height" to auto -*/ -.fd-slider-handle:before - { - display:block; - position:absolute; - top:-30px; - left:-25px; - margin:0; - width:60px; - padding:5px; - height:14px; - line-height:12px; - font-size:10px; - text-shadow:0 1px 0 #000; - color:#fff; - background:#222; - z-index:1; - /* Use the ARIA valuetext property, set by the script, to generate the - tooltip content */ - content:attr(aria-valuetext); - -webkit-border-radius:3px; - -moz-border-radius:3px; - border-radius:3px; - -webkit-box-shadow: 0 0 4px #aaa; - -moz-box-shadow: 0 0 4px #aaa; - box-shadow: 0 0 4px #aaa; - } -.fd-slider-handle:after - { - outline:none; - content:""; - display:block; - position:absolute; - top:-14px; - left:50%; - margin:0 0 0 -5px; - background:#222; - z-index:2; - width:10px; - height:10px; - overflow:hidden; - /* Rotate element by 45 degress to get the "\/" pointer effect */ - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -ms-transform: rotate(45deg); - -o-transform: rotate(45deg); - -webkit-box-shadow: 0 0 4px #aaa; - -moz-box-shadow: 0 0 4px #aaa; - box-shadow: 0 0 4px #aaa; - clip:rect(4px, 14px, 14px, 4px); - } -/* Change opacity and position to kick in the transitions */ -.fd-slider-focused .fd-slider-handle:before, -.fd-slider-hover .fd-slider-handle:before, -.fd-slider-active .fd-slider-handle:before - { - top:-25px; - opacity:1; - } -.fd-slider-focused .fd-slider-handle:after, -.fd-slider-hover .fd-slider-handle:after, -.fd-slider-active .fd-slider-handle:after - { - top:-9px; - opacity:1; - } -/* Remove completely for IE 6, 7 and 8 */ -.oldie .fd-slider-handle:before, -.oldie .fd-slider-handle:after - { - display:none; - } \ No newline at end of file diff --git a/src/resources/css/fd-slider.css b/src/resources/css/fd-slider.css deleted file mode 100644 index 84d5def..0000000 --- a/src/resources/css/fd-slider.css +++ /dev/null @@ -1,1004 +0,0 @@ -/* - - Don't use this version of the file in a production environment. A minified - version tailored specifically to your needs can be generated in-browser by - using the /css-generator/index.html file. - - Notes for the adventurous: - - 1. The script automagically adds the classname "oldie" to IE6, 7 & 8. - - 2. A combination of the .oldie class and "safe css hacks" are used to target - specific IE versions. See: http://mathiasbynens.be/notes/safe-css-hacks - - 3. MSHTML has been used to base64 encode the various png images used for the - drag handle in IE6 and 7. IE7 gets served one base64 encoded image sprite - whereas IE6 gets served individual base64 encoded images. - - See: http://www.phpied.com/the-proper-mhtml-syntax/ for more info on MHTML - - The base64 encoded images have been placed into their own .mht file. This - means only IE6 and 7 will ever be burdened with downloading the file. - - A Microsoft security update in July 2011 means that .mht files now have to - be delivered with the mimetype "message/rfc822". If using IIS, there is - nothing to do as IIS appears to default to using the required - "message/rfc822" mimetype, if using Apache, there are two ways in which to - configure this behaviour: - - A. You have Admin rights and can restart the Apache server - - Update the apache_root/httpd/conf/Srm.conf file and add the following - line: - - AddType message/rfc822 mht - - This method requires that you restart Apache. - - B. You can simply use an htaccess directive - - You can add the following to an .htaccess file that sits in the same - directory as the .mht file (or to an htaccess file at the root of your - website if one exists already): - - AddType message/rfc822 mht - - You do not need to restart Apache for the change to take effect. - - Yikes - I cant do either of the above! - - Don't worry, using the .mht file isn't compulsory - just replace the - various mhtml: references (found within the .oldie classes) to point to - the correct image file on your server (not forgetting to actually upload - the image files to your server of course). - - All of the relevant rules have further instructions embedded within them. - - 4. All browsers but IE6 get one "normal" base64 encoded image sprite. IE6 has - to use separate images for each animation state. - - 5. The drag handle is only 20px in width & height, most probably not suitable - for touch screen devices. - - 6. It's painless to base64 encode your own images, use an online encoder. - See: http://www.google.com/search?q=base+64+encoder - the only problem is - that IE6 needs each frame of the handle sprite to be encoded individually. - - 7. If you want to use a different image for vertical slider drag handles, - uncomment the relevant classes below (easy to spot as they all have the - classname ".fd-slider-vertical" somewhere within the declaration). - - 8. As a reminder, the following HTML is being targetted by the CSS: - - - - - - -   - - - -*/ - -/* - Element: Form element associated with the slider - Notes: The styles given to the associated form element in order to hide - it within the display -*/ -.fd-form-element-hidden - { - display:none; - } -/* - Element: Outer wrapper - Orientation: Horizontal -*/ -.fd-slider - { - width:100%; - height:20px; - margin:0 0 10px 0; - } -/* - Element: Outer wrapper - Orientation: Vertical - Notes: You may wish to float the vertical sliders left or use - display:inline-block (inline-block should work even in IE6 as the slider - is constructed from span elements but don't quote me on that) -*/ -.fd-slider-vertical - { - width:20px; - height:100%; - margin:0 10px 10px 0; - } -/* - Element: Outer wrapper - Orientation: Both horizontal & vertical -*/ -.fd-slider, -.fd-slider-vertical - { - text-align:center; - display:block; - position:relative; - cursor:pointer; - text-decoration:none; - border:0 none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; - } -/* - Element: Outer Wrapper - Orientation: Both horizontal & vertical - Notes: IE6 & 7 need a transparent gif as a background in order for - hover events to work. This has been base64 encoded within the .mht file. - As it's not a png, no AlphaImageLoader filter is required for IE6. -*/ -.oldie .fd-slider, -.oldie .fd-slider-vertical - { - /* - If using the .mht file then uncomment the following rule and edit the - filepath to match the absolute path to the fd-slider.mht file on your - server (replace "www.your-domain.com/the/path/to/") - */ - - /* - - *background:transparent url(mhtml:http://www.your-domain.com/the/path/to/fd-slider.mht!blank) repeat; - - */ - - /* - If not using the .mht file then uncomment the following rule and edit - the filepath to match the absolute path to the blank.gif file on your - server (replace "www.your-domain.com/the/path/to/") - */ - - /* - - *background:transparent url(http://www.your-domain.com/the/path/to/blank.gif) repeat; - - */ - } -/* - Element: Inner wrapper - Notes: All other DOM elements added as children to this element. -*/ -.fd-slider-wrapper - { - position:absolute; - top:0; - left:0; - width:100%; - height:100%; - } -/* - Element: Inner wrapper - Notes: IE6 needs an expression as it cannot do a height:100% on - absolutely positioned elements and it also can't position on four - corners - so we are left with a "one time evaluated" self-deleting - expression to do the dirty work. -*/ - -.oldie .fd-slider-vertical .fd-slider-wrapper - { - *clear:expression(style.height=parentNode.offsetHeight+'px',style.clear='none', 0); - } -/* - Element: ieBlur shiv - Notes: Used only by IE for the onfocus "Blur" effect -*/ -.fd-slider-inner - { - display:none; - } -/* - Element: ieBlur shiv - Orientation: Horizontal - Notes: IE6, 7 & 8 only. - Use the "Blur" filter to simulate the box-shadow - not brilliant but the - best we can do for IE. IE6 can't absolutely position on 4 sides so we - reset the right to "auto" and use a nasty expression to calculate the - width dynamically. -*/ -.oldie .fd-slider-inner - { - position:absolute; - height:2px; - border:1px solid #bbf; - background:#bbf; - top:4px; - bottom:auto; - left:4px; - right:12px; - z-index:2; - margin:0; - padding:0; - overflow:hidden; - line-height:4px; - _right:auto; - _width:expression((this.parentNode.offsetWidth - 12) + "px"); - filter:progid:DXImageTransform.Microsoft.Blur(pixelradius=3.5); - } -/* - Element: ieBlur shiv - Orientation: Vertical - Notes: Reposition the "Blur" filter for the vertical slider for IE6, - 7 & 8. The "Blur" filter rule cascades from the rule above so no need to - redeclare here, we just reposition. -*/ -.oldie .fd-slider-vertical .fd-slider-inner - { - width:2px; - height:auto; - bottom:12px; - right:auto; - _bottom:auto; - *clear:expression(style.height=(parentNode.offsetHeight - 8)+'px',style.clear='none', 0); - } -/* - Element: ieBlur shiv - Orientation: Horizontal & Vertical - Notes: Display the "Blurred" inner div for IE6, 7 & 8 when the slider - gains focus -*/ -.oldie .fd-slider-focused .fd-slider-inner - { - display:block; - } -/* - Element: Inner track bar - Orientation: Horizontal -*/ -.fd-slider-bar - { - display:block; - position:absolute; - top:8px; - right:10px; - left:10px; - z-index:2; - height:2px; - margin:0; - padding:0; - overflow:hidden; - border:1px solid #bbb; - border-bottom:1px solid #aaa; - border-right:1px solid #aaa; - border:1px solid rgba(187, 187, 187, .8); - border-bottom:1px solid rgba(170, 170, 170, .8); - border-right:1px solid rgba(170, 170, 170, .8); - line-height:4px; - background-color:#ddd; - background-image: -webkit-gradient(linear, left top, left bottom, from(#ececec), to(#ccc)); - background-image: -webkit-linear-gradient(top, #ececec, #ccc); - background-image: -moz-linear-gradient(top, #ececec, #ccc); - background-image: -ms-linear-gradient(top, #ececec, #ccc); - background-image: -o-linear-gradient(top, #ececec, #ccc); - background-image: linear-gradient(to bottom, #ececec, #ccc); - border-radius:2px; - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; - } -/* - Element: Inner track bar - Orientation: Horizontal - Notes: For IE6 & 7 & 8. IE6 does not recognise absolute positioning on - four sides (top, right, bottom & left) so we use an expression to - dynamically calculate the track bar size. Yes, it is horrible - you - don't need to remind me. -*/ -.oldie .fd-slider-bar - { - _right:auto; - _width:expression((this.parentNode.offsetWidth - 20) + "px"); - filter:progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ffececec',endColorstr='#ffcccccc'); - } -/* - Element: Inner track bar - Orientation: Vertical -*/ -.fd-slider-vertical .fd-slider-bar - { - width:2px; - top:10px; - right:auto; - bottom:10px; - left:8px; - height:auto; - background-color:#ddd; - background-image: -webkit-gradient(linear, left top, right top, from(#ececec), to(#ccc)); - background-image: -webkit-linear-gradient(left, #ececec, #ccc); - background-image: -moz-linear-gradient(left, #ececec, #ccc); - background-image: -ms-linear-gradient(left, #ececec, #ccc); - background-image: -o-linear-gradient(left, #ececec, #ccc); - background-image: linear-gradient(to right, #ececec, #ccc); - } -/* - Element: Inner track bar - Orientation: Vertical - Notes: For IE6 & 7 & 8. The gradient filter colour strings in AARRGGBB - format (to save you one less google). IE6 gets repositioned and alas, - an expression to calculate the height. -*/ -.oldie .fd-slider-vertical .fd-slider-bar - { - _bottom:auto; - *clear:expression(style.height=(parentNode.offsetHeight - 20)+'px',style.clear='none', 0); - filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#ffececec',endColorstr='#ffcccccc'); - } -/* - Element: Inner track bar - Orientation: Horizontal & Vertical - State: Focused - Notes: Drop shadow on the inner bar when focused - newer browsers get - an animation. IE6, 7 & 8 get a "Blur" filter on an inner SPAN - .fd-slider-inner instead -*/ -.fd-slider-focused .fd-slider-bar - { - box-shadow: 0 0 6px rgba(10, 130, 170, 0.7); - -webkit-animation:fd-pulse 2s infinite; - -moz-animation:fd-pulse 2s infinite; - -o-animation:fd-pulse 2s infinite; - animation:fd-pulse 2s infinite; - } -/* - Element: Inner animated range bar - Orientation: Horizontal -*/ -.fd-slider-range - { - display:block; - position:absolute; - top:9px; - left:11px; - z-index:3; - height:2px; - margin:0; - padding:0; - overflow:hidden; - line-height:2px; - background-color:#4cc; - background-image: -webkit-gradient(linear, left top, right top, from(#6cc), to(#3cf)); - background-image: -webkit-linear-gradient(left, #6cc, #3cf); - background-image: -moz-linear-gradient(left, #6cc, #3cf); - background-image: -ms-linear-gradient(left, #6cc, #3cf); - background-image: -o-linear-gradient(left, #6cc, #3cf); - background-image: linear-gradient(to right, #6cc, #3cf); - border-radius:2px; - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; - } -/* - Element: Inner range bar - Orientation: Horizontal - Notes: IE6, 7 & 8 -*/ -.oldie .fd-slider-range - { - /* IE6 - is this needed? To test. */ - _left:10px; - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ff66cccc',endColorstr='#ff33ccff'); - } -/* - Element: Inner range bar - Orientation: Vertical -*/ -.fd-slider-vertical .fd-slider-range - { - height:auto; - width:2px; - top:auto; - right:auto; - bottom:11px; - left:9px; - background-image: -webkit-gradient(linear, left top, left bottom, from(#3cf), to(#6cc)); - background-image: -webkit-linear-gradient(top, #3cf, #6cc); - background-image: -moz-linear-gradient(top, #3cf, #6cc); - background-image: -ms-linear-gradient(top, #3cf, #6cc); - background-image: -o-linear-gradient(top, #3cf, #6cc); - background-image: linear-gradient(to bottom, #3cf, #6cc); - } -/* - Element: Inner range bar - Orientation: Vertical - Notes: IE6, 7 & 8 -*/ -.oldie .fd-slider-vertical .fd-slider-range - { - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#ff66cccc',endColorstr='#ff33ccff'); - } -/* - Element: Drag handle - Orientation: Horizontal - State: Default. - Notes: The image sprite used for the handle is base64 encoded below. IE7 - gets its own version within the .mht file, IE6 does not use an image - sprite and it is necessary to base64 encode individual animation frames - within the .mht file. -*/ -.fd-slider-handle - { - position:absolute; - display:block; - padding:0; - border:0 none; - margin:0; - z-index:3; - top:0; - left:0; - width:20px; - height:20px; - outline:0 none; - background-color:transparent; - background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAABQCAYAAAAZQFV3AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjFFRDg4NEVDNENDODExRTFCMTZDREIyQTZDMjlDNTQ2IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjFFRDg4NEVENENDODExRTFCMTZDREIyQTZDMjlDNTQ2Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MUVEODg0RUE0Q0M4MTFFMUIxNkNEQjJBNkMyOUM1NDYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MUVEODg0RUI0Q0M4MTFFMUIxNkNEQjJBNkMyOUM1NDYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz68iMNZAAAIQElEQVR42uxYW28b1xGes7tckiIp3iRboi6mbollya5DF4VsVWpaw42ABCmaogWSFH3oDyjQoijQP2AUyFOLFshbn4SqsYFabowmdaW4NhDJiKXaUuwotm6UKJK6kKIkipfl7p7OWR3aa5kiVdQoEjQLDM7u2TPfnss3MztDKKXwPC8BnvP1xQeUSnUSvGBwshl8R18Fq70PZOtx44WSn4F89hYkV6/B26ElWuIAyP4+xBKd70311tXV/bzb7+oLOcDaYiWSTSAkR0EfT9P8UDj1j8Rq/Lfw1ukx1NcOnKExs4tDbT6f75e9tc6+c05q90gEtwWRdAoyblG/k4jeVvcr76qKZePi0K9Q5ZF5pvuXLENj6xv1Pvc5n6DJyQJAQgGdjWZCuFQRwTLQ7P/W6PaLb0YBfoNd+YMAq8BR/TIpFCzhDECEgK5SeGafJAJEA0FqO+L7LgL+rhygEwE7FrMFWMqAVvY4CX6I2hoMHYDNg5es60I8Z9xXNiHd2A25PG3WInFPY9BfLRFiwePQS8AKuJEFHWA3Fl1PVOChArPT96Gp5YRDJMSFoExZ1Z8cisQ/sqOBroRnZgydMoBpGLk8mm9uDemdJzs8kkA8FgZKQMSXbFN1ZEiqQGl26eFS4cbwiKFTxvQyMPbhZPb9weHl6bsL4ZymZzRKXSKBADKbtew5+vDB8vKVwb8kPrh029A5yFIMYgO4UNrh1Nl+6H/9PBwPtUMg6DcGRBcTMDM5CzevjsDU2E3smUXZMRO7pOlh40AJoAR56+KvdxgsyiJvd/ebHinlYPlMZYPoezyTHx/a3p6xZSqHcg5fCn9ITC0xPRcvapJnLEoqASQUOczvRdM7WqQjisqfdTOwtA9M5GLhByHzMSJ/r3EghUuB92kcg5pnKHJlK4qdSxV/Lo5Tuatip5zlkjd9zBhITEtjyg5FUdx/iuVeuJQi35lTxZc2QGpkg2tAjbRJ2r9+6KGjb9bbHsqyLOzbV53RhnAwG+NcMpn0vxPVvz2pWn/sc9i6TlcRyzErCDbkZhY94CdpWhhPZO72yvnBXzeI/8RwkeDcZE5Pk0wHIOfz+ao/r6RP3M67ftLhtXb3OInFKyFXGV9xAnZ0qn0ukL2iPfS3mCri2PWfOhwTVqtV4duhC6Yly/F43H0lBa8QW1WnX6TSlqqTRQx1KHRhT/BeJw6BSl0+58mPdoXXmA4/PAOrOEPjQGKxmHtRD4aaqS5G8wRWC0B1YFvyhDXovigOpgWKftZq/0Ys9sh97Nix9SK9zLQRNzY2XEnP8QDJaSReIFTECIpbR83cZaaqUZ1q6GUF3eJnOmauPmUpu7u7FnDrwpqigygKCMimAcRMazZDjYmGY3R1T6eEpRgWUCgUVM/uZlLx1Lp8shFTCC6YFBHZwRi+hAqQ1yhYt7ZSTIdz8LGlFM1JxeXt1iUjC2FPbbMVuzFQ4SzxJX0SU9g3VJzdFm7u0VQszHT4CWtFSynao+JwOBKdCzMfp1w1L6iB5oATQ4nXQowoZwDrBMEpwSCsy4n4Wmv8848dDd4EN0N9b+57gIZ9NjU1JTvU7YmWR7dv5FcWV8NZVUurGrXjXtYiH1mbVnWajUc2XA/GP2rKbNxmOhxQNdsyAy20tbVtz8/Pz21PTV1zfBLfnm/s6rlzpKVxq7q2mg1yb69v16wtRFoj98fbIXsreOrUHNPhTuKpPWTT1TweT66rq2sdN3oaPvts2zf19xm0ngAeqpOHhjRaRRTNba6zszOMYxNMx+TSaDEEPOW+kFvyxMSEc2VlpZqRXVVVm/F1ScrV19dvNTQ0bJ85cyZdU1OjmNwXmAGfu4M1u3Ld1P5XIWA/MP1CRL0vcZ5y4cKFZuTcq6Io9qEYeYqmaTMot5Cb165fv374PGVgYOAckvdntbW1fdjKaOMicpABUuSoMjs7O5pKpX6PoJXzlJ6enrbq6upfIIG/iYA2FtlYIEMww9lin4h9F6anpy04dq1inoKzeQMBe1HJiksTstnsfgrhDy2Rg8FgP5roj/D5nbJ5isVieRk/aNnZ2SHpdFo/4HePNRa/338e2z+UzVMQsAPBBASrRGzCf0jL5yk4o1LLLHnx2ZfPUxAs7na7fThT/iN7MBiuZK0SD5Wtra37CNiJ3COMKgx034+98YwujSLgg4p5SiQSGXW5XCGkTTueNEF5Csj4qqIA8nB+aWnpmTxlP2AGfy0m7Xb7MN7/AEGDgiAQm80GbAuQJjSXywGOCSO5h8Ph8J1D5ylIif5AIHDe6/W2V1VVGXlKJpNJbG5uzkaj0ZFEIvFVnvJ/67H/p6WqWvAd/TpY7V0gWxt5qSoC+ex9SK7egbdD64cNAYLzvakTdXV13+v2u7pCDrC0WInAS1V0HNOKoXDqbmI1fhXeOj2D+nqlUlU9xpHv99Y6u845qeyRGCcfl6pIv5NYva3u0LuqIm1cHPojqkTLhQAJGlvP1vvcnT5Bk3ipipYoVYkDzf7u0e0X+9FcLvPfuZKAVnBUn0QvIPJSFS1TqhLbjvheQsC/lgO0IWCAl6r0Q5Sq/DylSx8EaPkPS1XAU+GypapNT2PQdchS1ValUlUBZqeXoKmliZeqoEypiirhmYh5/0oB5mDk8r18c2ub3nkyUKFUtVa4MXyPp7UHml4exj6cy74/OL48fTcezmnUVKoCU6lqY/nK4Fjig0ufm4P8QSGAlQbq4dTZbuh//WtwPFQPgaCLl6p2YGYyBjev3oOpsU+xJ8Yib6UQIHAq+FCO8tZeDNsoLNFZ5W1uv+mVCwHFgobNRI0C3zO2TPWrEGBc/xZgAJyadcoLu6zuAAAAAElFTkSuQmCC); - background-position:0 0; - cursor:W-resize; - line-height:20px; - font-size:10px; - -moz-outline:0 none; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; - } -/* - Element: Drag handle - Orientation: Horizontal - State: Default - Notes: IE6, 7 & 8 use a nasty expression in order to not draw focus - outline on drag handle. -*/ -.oldie .fd-slider-handle - { - /* IE6 & 7 - set the handle sprite as the background image */ - - /* - If using the .mht file then uncomment the following rule and edit the - filepath to match the absolute path to the fd-slider.mht file on your - server (replace "www.your-domain.com/the/path/to/") - */ - - /* - - *background-image:url(mhtml:http://www.your-domain.com/the/path/to/fd-slider.mht!fullsprite); - - */ - - /* - If not using the .mht file then uncomment the following rule and edit - the filepath to match the absolute path to the fd-slider-sprite.png - file on your server (replace "www.your-domain.com/the/path/to/") - */ - - /* - - *background-image:url(http://www.your-domain.com/the/path/to/fd-slider-sprite.png); - - */ - - /**********************************************************************/ - - /* IE6 - reset the background image sprite stipulated above. */ - _background-image:none; - - /* - IE6 - use the AlphaImageLoader to either load a base64 encoded image - from the .mht file or a normal png image from the server - */ - - /* - If using the .mht file then uncomment the following rule and edit the - filepath to match the absolute path to the fd-slider.mht file on your - server (replace "www.your-domain.com/the/path/to/") - */ - - /* - - _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='mhtml:http://www.your-domain.com/the/path/to/fd-slider.mht!handlenormal'); - - */ - - /* - If not using the .mht file then uncomment the following rule and edit - the filepath to match the absolute path to the fd-handle-normal.png - file on your server (replace "www.your-domain.com/the/path/to/") - */ - - /* - - _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='http://www.your-domain.com/the/path/to/fd-handle-normal.png'); - - */ - - /* IE6, 7 & 8 */ - outline:expression(hideFocus='true'); - } -/* - Element: Drag handle - Orientation: Horizontal & Vertical - State: Focused - Notes: Attempts to remove the focus outline, remove the rule if it - offends your sensibilities. -*/ -.fd-slider-handle:focus - { - outline:0 none; - border:0 none; - -moz-user-focus:normal; - } -.fd-slider-handle:focus::-moz-focus-inner - { - border-color: transparent; - } -/* - Element: Drag handle - Orientation: Horizontal - State: Focused and Hovered and also while handle is animating into - position or being dragged. - Notes: I'm using the same image for focused, hover and active states - but you can, of course, go wild. -*/ -.fd-slider-focused .fd-slider-handle, -.fd-slider-hover .fd-slider-handle, -.fd-slider-active .fd-slider-handle - { - background-position:0 -20px; - } -/* - Element: Drag handle - Orientation: Horizontal - State: Focused and Hovered and also while handle is animating into - position or being dragged. - Notes: IE6 only. -*/ -.oldie .fd-slider-focused .fd-slider-handle, -.oldie .fd-slider-hover .fd-slider-handle, -.oldie .fd-slider-active .fd-slider-handle - { - /* - IE6 - use the AlphaImageLoader to either load a base64 encoded image - from the .mht file or a normal png image from the server - */ - - /* - If using the .mht file then uncomment the following rule and edit the - filepath to match the absolute path to the fd-slider.mht file on your - server (replace "www.your-domain.com/the/path/to/") - */ - - /* - - _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='mhtml:http://www.your-domain.com/the/path/to/fd-slider.mht!handleglow'); - - */ - - /* - If not using the .mht file then uncomment the following rule and edit - the filepath to match the absolute path to the fd-handle-glow.png - file on your server (replace "www.your-domain.com/the/path/to/") - */ - - /* - - _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='http://www.your-domain.com/the/path/to/fd-handle-glow.png'); - - */ - } -/* - Element: Drag handle - Orientation: Vertical - Notes: Change the cursor to the correct icon. -*/ -.fd-slider-vertical .fd-slider-handle - { - cursor:N-resize; - } -/* - Element: Drag handle - Orientation: Vertical - Notes: IE6, 7 & 8 - -.oldie .fd-slider-vertical .fd-slider-handle - { - } -*/ -/* - Element: Drag handle - Orientation: Vertical - State: Focused and Hovered and also while handle is animating into - position or being dragged. - -.fd-slider-vertical .fd-slider-focused .fd-slider-handle, -.fd-slider-vertical .fd-slider-hover .fd-slider-handle, -.fd-slider-vertical .fd-slider-active .fd-slider-handle - { - } -*/ -/* - Element: Drag handle - Orientation: Vertical - State: Focused and Hovered and also while handle is animating into - position or being dragged. - Notes: IE6, 7 & 8 - -.oldie .fd-slider-vertical .fd-slider-focused .fd-slider-handle, -.oldie .fd-slider-vertical .fd-slider-hover .fd-slider-handle, -.oldie .fd-slider-vertical .fd-slider-active .fd-slider-handle - { - } -*/ -/* - Element: Drag handle - Orientation: Horizontal & Vertical - State: User has not yet used the slider to set a value - Notes: I screwed the positioning of the image sprite by 1px which is why - it's -59px and not -60px. Yeah - I suck at Photoshop. -*/ -.fd-slider-no-value .fd-slider-handle - { - background-position:0 -59px; - } -/* - Element: Drag handle - Orientation: Horizontal - State: User has not yet used the slider to set a value - Notes: IE6 only -*/ -.oldie .fd-slider-no-value .fd-slider-handle - { - /* - IE6 - use the AlphaImageLoader to either load a base64 encoded image - from the .mht file or a normal png image from the server - */ - - /* - If using the .mht file then uncomment the following rule and edit the - filepath to match the absolute path to the fd-slider.mht file on your - server (replace "www.your-domain.com/the/path/to/") - */ - - /* - - _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='mhtml:http://www.your-domain.com/the/path/to/fd-slider.mht!handlenovalue'); - - */ - - /* - If not using the .mht file then uncomment the following rule and edit - the filepath to match the absolute path to the fd-handle-no-value.png - file on your server (replace "www.your-domain.com/the/path/to/") - */ - - /* - - _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='http://www.your-domain.com/the/path/to/fd-handle-no-value.png'); - - */ - } -/* - Element: Drag handle - Orientation: Vertical - State: User has not yet used the slider to set a value - Notes: IE6, 7 & 8. Only required should you use a different image for - vertical sliders. - -.oldie .fd-slider-vertical .fd-slider-no-value .fd-slider-handle - { - } -*/ -/* - Element: document.body - Orientation: Horizontal and Vertical - Notes: Class given to body to change cursor style when dragging. It also - attempts to stop text selection while dragging. -*/ -body.fd-slider-drag-horizontal, -body.fd-slider-drag-horizontal *, -body.fd-slider-drag-vertical, -body.fd-slider-drag-vertical * - { - cursor:N-resize !important; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; - } -/* - Element: document.body - Orientation: Horizontal - Notes: Class given to body to change cursor style when dragging -*/ -body.fd-slider-drag-horizontal, -body.fd-slider-drag-horizontal * - { - cursor:W-resize !important; - } -/* - Element: Inner wrapper - Orientation: Horizontal & Vertical - State: disabled - Notes: Class given to slider when disabled -*/ -.fd-slider-disabled - { - opacity:.8; - cursor:default; - } -/* - Element: Drag handle - Orientation: Horizontal - State: disabled - Notes: Class given to slider when disabled -*/ -.fd-slider-disabled .fd-slider-handle - { - cursor:default !important; - background-position:0 -40px; - opacity:1; - } -/* - Element: Drag handle - Orientation: Horizontal - State: disabled - Notes: IE6 only -*/ -.oldie .fd-slider-disabled .fd-slider-handle - { - /* - IE6 - use the AlphaImageLoader to either load a base64 encoded image - from the .mht file or a normal png image from the server - */ - - /* - If using the .mht file then uncomment the following rule and edit the - filepath to match the absolute path to the fd-slider.mht file on your - server (replace "www.your-domain.com/the/path/to/") - */ - - /* - - _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='mhtml:http://www.your-domain.com/the/path/to/fd-slider.mht!handledisabled'); - - */ - - /* - If not using the .mht file then uncomment the following rule and edit - the filepath to match the absolute path to the fd-handle-disabled.png - file on your server (replace "www.your-domain.com/the/path/to/") - */ - - /* - - _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='http://www.your-domain.com/the/path/to/fd-handle-disabled.png'); - - */ - } -/* - Element: Drag handle - Orientation: Vertical - State: disabled - -.fd-slider-vertical .fd-slider-disabled .fd-slider-handle - { - } -.oldie .fd-slider-vertical .fd-slider-disabled .fd-slider-handle - { - } -*/ -/* - Element: Inner track bar - Orientation: Horizontal - State: disabled -*/ -.fd-slider-disabled .fd-slider-bar - { - cursor:auto !important; - border:1px solid #888; - border-bottom:1px solid #999; - border-right:1px solid #999; - border:1px solid rgba(136,136,136,.8); - border-bottom:1px solid rgba(153,153,153,.8); - border-right:1px solid rgba(153,153,153,.8); - background-color:#555; - background-image: -webkit-gradient(linear, left top, right top, from(#666), to(#333)); - background-image: -webkit-linear-gradient(left, #666, #333); - background-image: -moz-linear-gradient(left, #666, #333); - background-image: -ms-linear-gradient(left, #666, #333); - background-image: -o-linear-gradient(left, #666, #333); - background-image: linear-gradient(to right, #666, #333); - } -/* - Element: Inner track bar - Orientation: Vertical - State: disabled -*/ -.fd-slider-vertical .fd-slider-disabled .fd-slider-bar - { - background-image: -webkit-gradient(linear, left top, right bottom, from(#333), to(#666)); - background-image: -webkit-linear-gradient(top, #333, #666); - background-image: -moz-linear-gradient(top, #333, #666); - background-image: -ms-linear-gradient(top, #333, #666); - background-image: -o-linear-gradient(top, #333, #666); - background-image: linear-gradient(to bottom, #333, #666); - } -/* - Element: Inner track bar - Orientation: Horizontal - State: disabled - Notes: IE6, 7 & 8 -*/ -.oldie .fd-slider-disabled .fd-slider-bar - { - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#ff666666',endColorstr='#ff333333'); - } -/* - Element: Inner track bar - Orientation: Vertical - State: disabled - Notes: IE6, 7 & 8 -*/ -.oldie .fd-slider-vertical .fd-slider-disabled .fd-slider-bar - { - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ff666666',endColorstr='#ff333333'); - } -/* - Element: Range bar - Orientation: Horizontal - State: disabled -*/ -.fd-slider-disabled .fd-slider-range - { - cursor:auto !important; - background-color:#222; - background-image: -webkit-gradient(linear, left top, right top, from(#222), to(#000)); - background-image: -webkit-linear-gradient(left, #222, #000); - background-image: -moz-linear-gradient(left, #222, #000); - background-image: -ms-linear-gradient(left, #222, #000); - background-image: -o-linear-gradient(left, #222, #000); - background-image: linear-gradient(to right, #222, #000); - } -/* - Element: Range bar - Orientation: Horizontal - State: disabled - Notes: IE6, 7 & 8 -*/ -.oldie .fd-slider-disabled .fd-slider-range - { - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#ff222222',endColorstr='#ff000000'); - } -/* - Element: Range bar - Orientation: Vertical - State: disabled -*/ -.fd-slider-vertical .fd-slider-disabled .fd-slider-range - { - background-image: -webkit-gradient(linear, left top, right bottom, from(#000), to(#222)); - background-image: -webkit-linear-gradient(top, #000, #222); - background-image: -moz-linear-gradient(top, #000, #222); - background-image: -ms-linear-gradient(top, #000, #222); - background-image: -o-linear-gradient(top, #000, #222); - background-image: linear-gradient(to bottom, #000, #222); - } -/* - Element: Range bar - Orientation: Vertical - State: disabled - Notes: IE6, 7 & 8 -*/ -.oldie .fd-slider-vertical .fd-slider-disabled .fd-slider-range - { - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ff222222',endColorstr='#ff000000'); - } -/* - The various prefixed keyframe rules for the glow effect used whenever - the slider gains keyboard focus -*/ -@-webkit-keyframes fd-pulse { -0% { - box-shadow:0 0 3px rgba(100, 130, 170, 0.55); - } -20% { - box-shadow:0 0 4px rgba(70, 130, 170, 0.6); - } -40% { - box-shadow:0 0 5px rgba(40, 130, 170, 0.65); - } -60% { - box-shadow:0 0 6px rgba(10, 130, 170, 0.7); - } -80% { - box-shadow:0 0 5px rgba(40, 130, 170, 0.65); - } -100% { - box-shadow:0 0 4px rgba(70, 130, 170, 0.6); - } -} -@-moz-keyframes fd-pulse { -0% { - box-shadow:0 0 3px rgba(100, 130, 170, 0.55); - } -20% { - box-shadow:0 0 4px rgba(70, 130, 170, 0.6); - } -40% { - box-shadow:0 0 5px rgba(40, 130, 170, 0.65); - } -60% { - box-shadow:0 0 6px rgba(10, 130, 170, 0.7); - } -80% { - box-shadow:0 0 5px rgba(40, 130, 170, 0.65); - } -100% { - box-shadow:0 0 4px rgba(70, 130, 170, 0.6); - } -} -@-o-keyframes fd-pulse { -0% { - box-shadow:0 0 3px rgba(100, 130, 170, 0.55); - } -20% { - box-shadow:0 0 4px rgba(70, 130, 170, 0.6); - } -40% { - box-shadow:0 0 5px rgba(40, 130, 170, 0.65); - } -60% { - box-shadow:0 0 6px rgba(10, 130, 170, 0.7); - } -80% { - box-shadow:0 0 5px rgba(40, 130, 170, 0.65); - } -100% { - box-shadow:0 0 4px rgba(70, 130, 170, 0.6); - } -} -@keyframes fd-pulse { -0% { - box-shadow:0 0 3px rgba(100, 130, 170, 0.55); - } -20% { - box-shadow:0 0 4px rgba(70, 130, 170, 0.6); - } -40% { - box-shadow:0 0 5px rgba(40, 130, 170, 0.65); - } -60% { - box-shadow:0 0 6px rgba(10, 130, 170, 0.7); - } -80% { - box-shadow:0 0 5px rgba(40, 130, 170, 0.65); - } -100% { - box-shadow:0 0 4px rgba(70, 130, 170, 0.6); - } -} diff --git a/src/resources/js/fd-slider.min.js b/src/resources/js/fd-slider.min.js deleted file mode 100644 index 264cae7..0000000 --- a/src/resources/js/fd-slider.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! Unobtrusive Slider Control / HTML5 Input Range polyfill - MIT/GPL2 @freqdec */ -var fdSlider=function(){function ut(n){function nf(n){n=!!n,n!=ft&&(ft=n,pt(kt()))}function nu(){if(!p||d=="select")return;var n=g(e);if(n.min==tt&&n.max==st&&n.step==nt)return;tt=+n.min,st=+n.max,ut=tt,it=st,nt=+n.step,ir=Math.abs(st-tt),li=nt*2,bi=Math.ceil(ir/nt),ft=!1,ar(tt,st)}function gr(n){if(oi&&!n)return;try{di(l,-1),i(l,"focus",fu),i(l,"blur",su),o?i(l,"keypress",yi):(i(l,"keydown",yi),i(l,"keypress",ou)),i(a,"mouseover",br),i(a,"mouseout",sr),i(a,"mousedown",fi),i(a,"touchstart",fi),c&&(window.addEventListener&&!window.devicePixelRatio?window.removeEventListener("DOMMouseScroll",at,!1):(i(document,"mousewheel",at),i(window,"mousewheel",at)))}catch(t){}u(v,"fd-slider-focused"),u(v,"fd-slider-active"),f(v,"fd-slider-disabled"),a.setAttribute("aria-disabled",!0),e.disabled=oi=!0,clearTimeout(ht),n||ot("disable")}function hu(n){if(!oi&&!n)return;di(l,0),t(l,"focus",fu),t(l,"blur",su),o?t(l,"keypress",yi):(t(l,"keydown",yi),t(l,"keypress",ou)),t(a,"touchstart",fi),t(a,"mousedown",fi),t(a,"mouseover",br),t(a,"mouseout",sr),u(v,"fd-slider-disabled"),a.setAttribute("aria-disabled",!1),e.disabled=oi=gt=!1,n||ot("enable")}function ku(){clearTimeout(ht),ri=vt=l=a=v=ht=null,ot("destroy"),ki=null}function ii(){wr();try{var t=a.offsetWidth,n=a.offsetHeight,r=l.offsetWidth,i=l.offsetHeight,o=vt.offsetHeight,s=vt.offsetWidth,u=b?n-i:t-r;ct=u/bi,ni=Math.max(et?er(tr(ut)):Math.abs((ut-tt)/nt)*ct,0),bt=Math.min(et?er(tr(it)):Math.abs((it-tt)/nt)*ct,Math.floor(b?n-i:t-r)),ru=t,dr=n,pt(nr?kt():d=="select"?e.selectedIndex:parseFloat(e.value),!1)}catch(f){}ot("redraw")}function ot(n){var r,i,u,t;if(wt){if(n.match(/^(blur|focus|change)$/i))if(typeof document.createEvent!="undefined")t=document.createEvent("HTMLEvents"),t.initEvent(n,!0,!0),e.dispatchEvent(t);else if(typeof document.createEventObject!="undefined")try{t=document.createEventObject(),e.fireEvent("on"+n.toLowerCase(),t)}catch(f){}}else if(ki.hasOwnProperty(n))for(r={userSet:ft,disabled:oi,elem:e,value:d=="select"?e.options[e.selectedIndex].value:e.value},i=0;u=ki[n][i];i++)u.call(e,r)}function fu(){return f(v,"fd-slider-focused"),h.onfocus&&(ft=!0,pt(kt())),c&&(t(window,"DOMMouseScroll",at),t(document,"mousewheel",at),o||t(window,"mousewheel",at)),ot("focus"),!0}function su(){u(v,"fd-slider-focused"),c&&(i(document,"mousewheel",at),i(window,"DOMMouseScroll",at),o||i(window,"mousewheel",at)),lt=!0,ot("blur")}function at(n){if(!lt)return;n=n||window.event;var t=0,i;n.wheelDelta?(t=n.wheelDelta/120,o&&window.opera.version()<9.2&&(t=-t)):n.detail&&(t=-n.detail/3),b&&(t=-t),t&&(i=kt(),i+=t<0?-nt:nt,ft=!0,pt(hi(i))),s(n)}function ou(n){return n=n||window.event,n.keyCode>=33&&n.keyCode<=40||!lt||n.keyCode==45||n.keyCode==46?k(n):!0}function yi(n){if(!lt)return!0;n=n||window.event;var t=n.keyCode!==null?n.keyCode:n.charCode,i;if(t<33||t>40&&t!=45&&t!=46)return!0;i=kt(),t==37||t==40||t==46||t==34?i-=n.ctrlKey||t==34?+li:+nt:t==39||t==38||t==45||t==33?i+=n.ctrlKey||t==33?+li:+nt:t==35?i=it:t==36&&(i=ut),ft=!0,pt(hi(i)),ot("update"),s(n)}function br(){f(v,"fd-slider-hover")}function sr(){u(v,"fd-slider-hover")}function fi(n){var u,r;n=n||window.event,s(n),n.target?u=n.target:n.srcElement&&(u=n.srcElement),u&&u.nodeType==3&&(u=u.parentNode);if(n.touches){if(n.targetTouches&&n.targetTouches.length!=1)return!1;n=n.touches[0],gt=!0}return clearTimeout(ht),ht=null,lt=!1,ft=!0,u.className.search("fd-slider-handle")!=-1?(rr=b?n.clientY:n.clientX,tu=parseInt(b?l.offsetTop:l.offsetLeft)||0,ci(n),gt?(t(document,"touchmove",ci),t(document,"touchend",vi),i(a,"mousedown",fi)):(t(document,"mousemove",ci),t(document,"mouseup",vi)),f(v,"fd-slider-active"),f(document.body,"fd-slider-drag-"+(b?"vertical":"horizontal")),ot("dragstart")):(wr(),r=0,n.pageX||n.pageY?r=b?n.pageY:n.pageX:(n.clientX||n.clientY)&&(r=b?n.clientY+document.body.scrollTop+document.documentElement.scrollTop:n.clientX+document.body.scrollLeft+document.documentElement.scrollLeft),r-=b?hr+Math.round(l.offsetHeight/2):iu+Math.round(l.offsetWidth/2),r=pi(r),pr=="tween"?(f(v,"fd-slider-active"),bu(r)):pr=="timed"?(f(v,"fd-slider-active"),t(document,gt?"touchend":"mouseup",cr),ui=r,yr()):ai(r)),!1}function cr(n){return n=n||window.event,s(n),i(document,gt?"touchend":"mouseup",cr),u(v,"fd-slider-active"),clearTimeout(ht),ht=null,lt=!0,!1}function vi(n){return n=n||window.event,s(n),gt?(i(document,"touchmove",ci),i(document,"touchend",vi)):(i(document,"mousemove",ci),i(document,"mouseup",vi)),lt=!0,u(document.body,"fd-slider-drag-"+(b?"vertical":"horizontal")),u(v,"fd-slider-active"),ot("dragend"),!1}function ci(n){n=n||window.event,s(n);if(n.touches){if(n.targetTouches&&n.targetTouches.length!=1)return!1;n=n.touches[0]}return ai(pi(tu+(b?n.clientY-rr:n.clientX-rr))),!1}function ei(n){var t=kt();ft=!0,t+=n*nt,pt(hi(t))}function wr(){var i=0,t=0,n=a;try{do i+=n.offsetLeft,t+=n.offsetTop;while(n=n.offsetParent)}catch(r){}iu=i,hr=t}function yr(){var n=parseInt(b?l.offsetTop:l.offsetLeft,10);n=Math.round(ui20?50:100):(lt=!0,u(v,"fd-slider-active"),ot("finalise"))}function bu(n){lt=!1,or=parseInt(n,10),fr=parseInt(b?l.offsetTop:l.offsetLeft,10),uu=or-fr,lu=20,ur=0,ht||(ht=setTimeout(gi,20))}function si(n){return isNaN(n)||n===""||typeof n=="undefined"?(ft=!1,yt):nMath.max(ut,it)?(ft=!1,Math.max(ut,it)):(ft=!0,n)}function kt(){return hi(d=="input"?parseFloat(e.value):e.selectedIndex)}function hi(n){return isNaN(n)||n===""||typeof n=="undefined"?yt:Math.min(Math.max(n,Math.min(ut,it)),Math.max(ut,it))}function ai(n){var t=hi(et?du(tf(n)):b?st-Math.round(n/ct)*nt:tt+Math.round(n/ct)*nt);l.style[b?"top":"left"]=(n||0)+"px",lr(),vr(d=="select"||nt==1?Math.round(t):t)}function pt(n,t){var r=!1,i;(typeof n=="undefined"||isNaN(n)||n==="")&&d=="input"&&!nr?(i=yt,r=!0,ft=!1):i=si(n),l.style[b?"top":"left"]=(et?er(tr(i)):b?Math.round((st-i)/nt*ct):Math.round((i-tt)/nt*ct))+"px",lr(),!0&&vr(r?"":i)}function pi(n){if(et)return Math.max(Math.min(bt,n),ni);var t=n%ct;return t&&t>=ct/2?n+=ct-t:n-=t,nMath.max(Math.abs(ni),Math.abs(bt))&&(n=Math.max(Math.abs(ni),Math.abs(bt))),Math.min(Math.max(n,0),bt)}function du(n){var i=0,r=tt,u,t;for(t in et){if(!et.hasOwnProperty(t))continue;n+t||(u=r+(n-i)*(+et[t]-r)/(+t-i)),i=+t,r=+et[t]}return u}function tr(n){var r=0,i=tt,u=0,t;for(t in et){if(!et.hasOwnProperty(t))continue;n+et[t]||(u=r+(n-i)*(+t-r)/(+et[t]-i)),r=+t,i=+et[t]}return u}function er(n){return(a[b?"offsetHeight":"offsetWidth"]-l[b?"offsetHeight":"offsetWidth"])/100*n}function tf(n){return n/((a[b?"offsetHeight":"offsetWidth"]-a[l?"offsetHeight":"offsetWidth"])/100)}function vr(n){ot("update"),ft?u(v,"fd-slider-no-value"):f(v,"fd-slider-no-value");if(d=="select")try{n=parseInt(n,10);if(e.selectedIndex===n){dt();return}e.options[n].selected=!0}catch(t){}else{n===""||wi||(n=(tt+Math.round((+n-tt)/nt)*nt).toFixed(yu));if(e.value===n){dt();return}e.value=n}dt(),ot("change")}function ar(n,t){ut>it?(n=Math.min(tt,Math.max(n,t)),t=Math.max(st,Math.min(n,t)),ut=Math.max(n,t),it=Math.min(n,t)):(n=Math.max(tt,Math.min(n,t)),t=Math.min(st,Math.max(n,t)),ut=Math.min(n,t),it=Math.max(n,t)),ytMath.max(ut,it)&&(yt=Math.max(ut,it)),l.setAttribute("aria-valuemin",ut),l.setAttribute("aria-valuemax",it),si(d=="input"?parseFloat(e.value):e.selectedIndex),ii()}function lr(){if(y)return;b?ti.style.height=Math.max(1,vt.offsetHeight-l.offsetTop)+"px":ti.style.width=Math.max(1,l.offsetLeft)+"px"}function cu(){for(var t=!1,r=document.getElementsByTagName("label"),n,i=0;n=r[i];i++)if(n.htmlFor&&n.htmlFor==e.id||n.getAttribute("for")==e.id){t=n;break}return t&&!t.id&&(t.id=e.id+"_label"),t}function dt(){var n=d=="select"?e.options[e.selectedIndex].value:e.value,t=kr?kr(n):d=="select"?e.options[e.selectedIndex].text?e.options[e.selectedIndex].text:n:n;l.setAttribute("aria-valuenow",n),l.setAttribute("aria-valuetext",t)}function wu(){ft=!0,wi=gu,pt(d=="input"?parseFloat(e.value):e.selectedIndex),dt(),wi=!1}function pu(){d=="input"?e.value=e.defaultValue:e.selectedIndex=au,si(d=="select"?e.options[e.selectedIndex].value:e.value),ii(),dt()}function di(n,t){n.setAttribute("tabIndex",t),n.tabIndex=t}var e=n.inp,oi=!1,d=e.tagName.toLowerCase(),tt=+n.min,st=+n.max,ut=+n.min,it=+n.max,ir=Math.abs(st-tt),nt=d=="select"?1:+n.step,li=n.maxStep?+n.maxStep:nt*2,yu=n.precision||0,bi=Math.ceil(ir/nt),et=n.scale||!1,rf=!!n.hideInput,pr=n.animation||"",b=!!n.vertical,ki=n.callbacks||{},vu=n.classNames||"",wt=!!n.html5Shim,yt=st/gim,"").replace(/\bfunction\b/g,"function-"),");"].join(""));return t()}}catch(i){}return{err:"Could not parse the JSON object"}},it=function(n){if(typeof n!="object")return;for(var t in n){value=n[t];switch(t.toLowerCase()){case"mousewheelenabled":c=!!value;break;case"fullaria":rt=!!value;break;case"describedby":w=String(value);break;case"norangebar":y=!!value;break;case"html5animation":ft=String(value).search(/^(jump|tween|timed)$/i)!=-1?String(value).toLowerCase():"jump";break;case"watchattributes":p=!!value;break;case"varsetrules":"onfocus"in value&&(h.onfocus=!!value.onfocus),"onvalue"in value&&(h.onvalue=!!value.onvalue)}}},t=function(n,t,i){n.addEventListener?n.addEventListener(t,i,!0):n.attachEvent&&n.attachEvent("on"+t,i)},i=function(n,t,i){try{n.removeEventListener?n.removeEventListener(t,i,!0):n.detachEvent&&n.detachEvent("on"+t,i)}catch(r){}},k=function(n){n=n||window.event,n.stopPropagation&&(n.stopPropagation(),n.preventDefault());/*@cc_on@if(@_win32)n.cancelBubble=!0,n.returnValue=!1;@end@*/return!1},s=function(n){n=n||window.event;if(n.preventDefault){n.preventDefault();return}n.returnValue=!1},f=function(n,t){if(new RegExp("(^|\\s)"+t+"(\\s|$)").test(n.className))return;n.className+=(n.className?" ":"")+t},u=function(n,t){n.className=t?n.className.replace(new RegExp("(^|\\s)"+t+"(\\s|$)")," ").replace(/^\s\s*/,"").replace(/\s\s*$/,""):""},ct=function(){var i={},t;for(t in n)i[t]=n[t].getValueSet();return i},st=function(t,i){n[t].setValueSet(!!i)},e=function(t){return!!(t in n&&n.hasOwnProperty(t))},vt=function(t){if(!t||!t.inp||!t.inp.tagName||t.inp.tagName.search(/^input|select/i)==-1)return!1;t.html5Shim=!1;if(t.inp.tagName.toLowerCase()=="select"){if(t.inp.options.length<2)return!1;t.min=0,t.max=t.inp.options.length-1,t.step=1,t.precision=0,t.scale=!1,t.forceValue=!0}else{if(String(t.inp.type).search(/^(text|range)$/i)==-1)return!1;t.min=t.min&&String(t.min).search(v)!=-1?+t.min:0,t.max=t.max&&String(t.max).search(v)!=-1?+t.max:100,t.step=t.step&&String(t.step).search(b)!=-1?t.step:1,t.precision=t.precision&&String(t.precision).search(/^[0-9]+$/)!=-1?t.precision:String(t.step).search(/\.([0-9]+)$/)!=-1?String(t.step).match(/\.([0-9]+)$/)[1].length:0,t.scale=t.scale||!1,t.forceValue="forceValue"in t?!!t.forceValue:!1,t.userSnap="userSnap"in t?!!t.userSnap:!1}return t.ariaFormat="ariaFormat"in t&&typeof t.ariaFormat=="function"?t.ariaFormat:!1,t.maxStep=t.maxStep&&String(t.maxStep).search(b)!=-1?+t.maxStep:+t.step*2,t.classNames=t.classNames||"",t.callbacks=t.callbacks||!1,a(t.inp.id),n[t.inp.id]=new ut(t),!0},r=function(n,t){return n.getAttribute(t)||""},l=function(){for(var e=document.getElementsByTagName("input"),i,u,t,f=0;t=e[f];f++)if(t.tagName.toLowerCase()=="input"&&r(t,"type")&&r(t,"type").toLowerCase()=="range"&&(r(t,"min")&&r(t,"min").search(v)!=-1||r(t,"max")&&r(t,"max").search(v)!=-1||r(t,"step")&&r(t,"step").search(/^(any|([0-9]+(\.[0-9]+){0,1}))$/i)!=-1)){if(t.id&&document.getElementById("fd-slider-"+t.id))continue;else t.id&&!document.getElementById("fd-slider-"+t.id)&&a(t.id);t.id||(t.id="fd-slider-form-elem-"+lt++),i={inp:t,callbacks:[],animation:ft,vertical:r(t,"data-fd-slider-vertical")?!0:t.offsetHeight>t.offsetWidth,classNames:r(t,"data-fd-slider-vertical"),html5Shim:!0},i.vertical&&!r(t,"data-fd-slider-vertical")&&(i.inpHeight=t.offsetHeight),u=g(t),i.min=u.min,i.max=u.max,i.step=u.step,i.precision=String(i.step).search(/\.([0-9]+)$/)!=-1?String(i.step).match(/\.([0-9]+)$/)[1].length:0,i.maxStep=i.step*2,a(i.inp.id),n[i.inp.id]=new ut(i)}return!0},g=function(n){return{min:+(r(n,"min")||0),max:+(r(n,"max")||100),step:+(r(n,"step").search(b)!=-1?n.getAttribute("step"):1)}},a=function(t){return t in n&&n.hasOwnProperty(t)?(n[t].destroy(),delete n[t],!0):!1},tt=function(){for(var i in n)n.hasOwnProperty(i)&&n[i].destroy();n=[]},at=function(){tt(),n=null},d=function(){for(var i in n)n.hasOwnProperty(i)&&n[i].onResize()},et=function(){for(var t in n)n.hasOwnProperty(t)&&n[t].rescan()},ht=function(){nt(),l()},nt=function(){i(window,"load",l)};t(window,"load",l),t(window,"load",function(){setTimeout(function(){var t;for(t in n)n[t].checkValue()},0)}),t(window,"resize",d),t(window,"unload",at),(function(){var t=document.getElementsByTagName("script"),n=ot(String(t[t.length-1].innerHTML).replace(/[\n\r\s\t]+/g," ").replace(/^\s+/,"").replace(/\s+$/,""));typeof n!="object"||"err"in n||it(n)})();/*@if(@_jscript_version<9)f(document.documentElement,"oldie");@end@*/return{rescanDocument:l,createSlider:function(n){return vt(n)},onDomReady:function(){ht()},destroyAll:function(){tt()},destroySlider:function(n){return a(n)},redrawAll:function(){d()},addEvent:t,removeEvent:i,stopEvent:k,increment:function(t,i){if(!e(t))return!1;n[t].increment(i)},stepUp:function(t,i){if(!e(t))return!1;n[t].stepUp(Math.abs(i)||1)},stepDown:function(t,i){if(!e(t))return!1;n[t].stepDown(-Math.abs(i)||-1)},setRange:function(t,i,r){if(!e(t))return!1;n[t].setRange(i,r)},updateSlider:function(t){if(!e(t))return!1;n[t].onResize(),n[t].reset()},disable:function(t){if(!e(t))return!1;n[t].disable()},enable:function(t){if(!e(t))return!1;n[t].enable()},getValueSet:function(){return ct()},setValueSet:function(n,t){if(!e(id))return!1;st(n,t)},setGlobalVariables:function(n){it(n)},removeOnload:function(){nt()},rescanAttributes:et}}() \ No newline at end of file diff --git a/src/stylus/style.styl b/src/stylus/style.styl index 9644e6f..289060d 100644 --- a/src/stylus/style.styl +++ b/src/stylus/style.styl @@ -144,7 +144,7 @@ body 50% fill #ff9d00 -.header-content .estop +.estop width 130px transition 250ms @@ -369,8 +369,14 @@ body > svg margin 1em - .console +.console + table width 100% + margin 0.5em 0 + border-collapse collapse + + td, th + border 1px solid #ddd tr > td @@ -386,48 +392,48 @@ body &.debug td color green - .indicators - table - display inline-block - vertical-align top - margin 0.5em - empty-cells show +.indicators + table + display inline-block + vertical-align top + margin 0.5em + empty-cells show - td, th - padding 4px + td, th + padding 4px - tr:nth-child(odd) - background #f7f7f7 + tr:nth-child(odd) + background #f7f7f7 - td:nth-child(1), td:nth-child(3) - text-align center + td:nth-child(1), td:nth-child(3) + text-align center - th:nth-child(2), th:nth-child(4) - text-align left + th:nth-child(2), th:nth-child(4) + text-align left - &.inputs, &.outputs - td:nth-child(1), td:nth-child(4) - text-align center + &.inputs, &.outputs + td:nth-child(1), td:nth-child(4) + text-align center - th:nth-child(2), th:nth-child(5) - text-align right + th:nth-child(2), th:nth-child(5) + text-align right - th:nth-child(3), th:nth-child(6) - text-align left + th:nth-child(3), th:nth-child(6) + text-align left - .logic-lo - color black + .logic-lo + color black - .logic-hi - color green + .logic-hi + color green - .warn - background-color transparent - color orange + .warn + background-color transparent + color orange - .video - text-align center - line-height 0 +.video + text-align center + line-height 0 .tabs @@ -479,6 +485,19 @@ body border 1px solid #ddd padding 0.5em + +.upgrade-version + display inline-block + border-radius 4px + padding 2px + margin-left 0.5em + color #555 + background-color #e5aa3d + text-decoration none + + &:hover + color #fff + .modal-mask position fixed z-index 9998 @@ -527,6 +546,22 @@ label.file-upload position fixed top -1000px +.error-message + &.modal-mask .modal-wrapper .modal-container + width auto + max-width 800px + + .modal-header h3 + white-space nowrap + overflow hidden + text-overflow ellipsis + + .estop + float right + transform scale(0.75) + margin-top -30px + + @media only screen and (max-width 48em) .header height auto -- 2.27.0