From f1e18cbd98ec3733aedd56030e2245bf44feabd9 Mon Sep 17 00:00:00 2001 From: lone-cloud Date: Tue, 18 Oct 2016 10:19:52 -0700 Subject: [PATCH] init huegasm_mobile --- mobile/.bowerrc | 4 + mobile/.editorconfig | 20 + mobile/.ember-cli | 10 + mobile/.gitignore | 26 + mobile/.jshintrc | 37 + mobile/.travis.yml | 24 + mobile/.watchmanconfig | 3 + mobile/README.md | 44 + mobile/TODO | Bin 4544 -> 0 bytes mobile/app/app.js | 18 + mobile/app/index.html | 67 + .../components/bridge-finder/component.js | 152 + .../components/bridge-finder/template.hbs | 57 + .../pods/components/hue-controls/component.js | 260 + .../pods/components/hue-controls/template.hbs | 36 + .../pods/components/huegasm-app/component.js | 68 + .../pods/components/huegasm-app/template.hbs | 39 + .../pods/components/light-group/component.js | 157 + .../pods/components/light-group/template.hbs | 5 + .../lights-tab/color-picker/component.js | 58 + .../lights-tab/color-picker/template.hbs | 1 + .../pods/components/lights-tab/component.js | 364 ++ .../pods/components/lights-tab/template.hbs | 38 + .../add-soundcloud-sound-modal/component.js | 45 + .../add-soundcloud-sound-modal/template.hbs | 13 + .../pods/components/music-tab/component.js | 890 +++ .../components/music-tab/mixins/helpers.js | 422 ++ .../components/music-tab/mixins/visualizer.js | 94 + .../pods/components/music-tab/template.hbs | 212 + mobile/app/resolver.js | 3 + mobile/app/router.js | 12 + mobile/app/styles/app.scss | 112 + mobile/app/styles/bootstrap.scss | 56 + mobile/app/styles/bridge-finder.scss | 73 + mobile/app/styles/common.scss | 15 + mobile/app/styles/dimmer.scss | 86 + mobile/app/styles/fancy-speaker.scss | 102 + mobile/app/styles/hue-controls.scss | 115 + mobile/app/styles/huegasm-variables.scss | 10 + mobile/app/styles/introjs.scss | 22 + mobile/app/styles/light-group.scss | 59 + mobile/app/styles/music-tab.scss | 403 ++ mobile/app/styles/noui-slider.scss | 56 + mobile/app/styles/paper.scss | 62 + mobile/app/templates/application.hbs | 1 + mobile/bower.json | 19 + mobile/config/environment.js | 49 + mobile/ember-cli-build.js | 21 + mobile/ember-cordova/cordova/config.xml | 26 + mobile/ember-cordova/cordova/hooks/README.md | 23 + .../ember-cordova/cordova/platforms/.gitkeep | 0 mobile/ember-cordova/cordova/plugins/.gitkeep | 0 mobile/ember-cordova/cordova/www/.gitkeep | 0 mobile/package.json | 47 + mobile/public/android-chrome-192x192.png | Bin 0 -> 5619 bytes mobile/public/android-chrome-512x512.png | Bin 0 -> 14867 bytes mobile/public/apple-touch-icon.png | Bin 0 -> 4346 bytes mobile/public/assets/images/colormap.png | Bin 0 -> 6305 bytes mobile/public/assets/images/lights/a19.svg | 32 + mobile/public/assets/images/lights/a19w.svg | 32 + mobile/public/assets/images/lights/br30.svg | 48 + mobile/public/assets/images/lights/br30w.svg | 48 + mobile/public/assets/images/lights/gu10.svg | 18 + mobile/public/assets/images/lights/gu10w.svg | 18 + mobile/public/assets/images/lights/huego.svg | 23 + mobile/public/assets/images/lights/huegow.svg | 23 + .../public/assets/images/lights/lc_aura.svg | 32 + .../public/assets/images/lights/lc_auraw.svg | 32 + .../public/assets/images/lights/lc_bloom.svg | 30 + .../public/assets/images/lights/lc_bloomw.svg | 30 + .../public/assets/images/lights/lc_iris.svg | 29 + .../public/assets/images/lights/lc_irisw.svg | 29 + .../assets/images/lights/lightstrip.svg | 45 + .../assets/images/lights/lightstripw.svg | 45 + .../assets/images/lights/storylight.svg | 42 + .../assets/images/lights/storylightw.svg | 42 + mobile/public/assets/images/logo.png | Bin 0 -> 28287 bytes .../public/assets/images/missingArtwork.png | Bin 0 -> 1867 bytes .../assets/images/pressButtonBridge.png | Bin 0 -> 7050 bytes mobile/public/assets/images/sc-white-sm.png | Bin 0 -> 292 bytes mobile/public/assets/images/sc-white.png | Bin 0 -> 3452 bytes mobile/public/browserconfig.xml | 9 + mobile/public/crossdomain.xml | 15 + mobile/public/favicon-16x16.png | Bin 0 -> 1025 bytes mobile/public/favicon-32x32.png | Bin 0 -> 1732 bytes mobile/public/favicon-96x96.png | Bin 0 -> 3876 bytes mobile/public/favicon.ico | Bin 0 -> 15086 bytes mobile/public/humans.txt | 14 + mobile/public/manifest.json | 17 + mobile/public/mstile-150x150.png | Bin 0 -> 3929 bytes mobile/public/robots.txt | 3 + mobile/public/safari-pinned-tab.svg | 69 + mobile/testem.js | 13 + mobile/tests/.jshintrc | 52 + mobile/tests/helpers/destroy-app.js | 5 + mobile/tests/helpers/module-for-acceptance.js | 23 + mobile/tests/helpers/resolver.js | 11 + mobile/tests/helpers/start-app.js | 18 + mobile/tests/index.html | 33 + .../component-test.js | 26 + .../bridge-finder/component-test.js | 26 + .../components/color-picker/component-test.js | 26 + .../components/hue-controls/component-test.js | 26 + .../components/huegasm-app/component-test.js | 26 + .../components/light-group/component-test.js | 26 + .../components/lights-tab/component-test.js | 26 + .../components/music-tab/component-test.js | 26 + mobile/tests/test-helper.js | 6 + mobile/tests/unit/.gitkeep | 0 mobile/vendor/dancer.js | 703 +++ mobile/yarn.lock | 5069 +++++++++++++++++ 111 files changed, 11402 insertions(+) create mode 100644 mobile/.bowerrc create mode 100644 mobile/.editorconfig create mode 100644 mobile/.ember-cli create mode 100644 mobile/.gitignore create mode 100644 mobile/.jshintrc create mode 100644 mobile/.travis.yml create mode 100644 mobile/.watchmanconfig create mode 100644 mobile/README.md delete mode 100644 mobile/TODO create mode 100644 mobile/app/app.js create mode 100644 mobile/app/index.html create mode 100644 mobile/app/pods/components/bridge-finder/component.js create mode 100644 mobile/app/pods/components/bridge-finder/template.hbs create mode 100644 mobile/app/pods/components/hue-controls/component.js create mode 100644 mobile/app/pods/components/hue-controls/template.hbs create mode 100644 mobile/app/pods/components/huegasm-app/component.js create mode 100644 mobile/app/pods/components/huegasm-app/template.hbs create mode 100644 mobile/app/pods/components/light-group/component.js create mode 100644 mobile/app/pods/components/light-group/template.hbs create mode 100644 mobile/app/pods/components/lights-tab/color-picker/component.js create mode 100644 mobile/app/pods/components/lights-tab/color-picker/template.hbs create mode 100644 mobile/app/pods/components/lights-tab/component.js create mode 100644 mobile/app/pods/components/lights-tab/template.hbs create mode 100644 mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/component.js create mode 100644 mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/template.hbs create mode 100644 mobile/app/pods/components/music-tab/component.js create mode 100644 mobile/app/pods/components/music-tab/mixins/helpers.js create mode 100644 mobile/app/pods/components/music-tab/mixins/visualizer.js create mode 100644 mobile/app/pods/components/music-tab/template.hbs create mode 100644 mobile/app/resolver.js create mode 100644 mobile/app/router.js create mode 100644 mobile/app/styles/app.scss create mode 100644 mobile/app/styles/bootstrap.scss create mode 100644 mobile/app/styles/bridge-finder.scss create mode 100644 mobile/app/styles/common.scss create mode 100644 mobile/app/styles/dimmer.scss create mode 100644 mobile/app/styles/fancy-speaker.scss create mode 100644 mobile/app/styles/hue-controls.scss create mode 100644 mobile/app/styles/huegasm-variables.scss create mode 100644 mobile/app/styles/introjs.scss create mode 100644 mobile/app/styles/light-group.scss create mode 100644 mobile/app/styles/music-tab.scss create mode 100644 mobile/app/styles/noui-slider.scss create mode 100644 mobile/app/styles/paper.scss create mode 100644 mobile/app/templates/application.hbs create mode 100644 mobile/bower.json create mode 100644 mobile/config/environment.js create mode 100644 mobile/ember-cli-build.js create mode 100644 mobile/ember-cordova/cordova/config.xml create mode 100644 mobile/ember-cordova/cordova/hooks/README.md create mode 100644 mobile/ember-cordova/cordova/platforms/.gitkeep create mode 100644 mobile/ember-cordova/cordova/plugins/.gitkeep create mode 100644 mobile/ember-cordova/cordova/www/.gitkeep create mode 100644 mobile/package.json create mode 100644 mobile/public/android-chrome-192x192.png create mode 100644 mobile/public/android-chrome-512x512.png create mode 100644 mobile/public/apple-touch-icon.png create mode 100644 mobile/public/assets/images/colormap.png create mode 100644 mobile/public/assets/images/lights/a19.svg create mode 100644 mobile/public/assets/images/lights/a19w.svg create mode 100644 mobile/public/assets/images/lights/br30.svg create mode 100644 mobile/public/assets/images/lights/br30w.svg create mode 100644 mobile/public/assets/images/lights/gu10.svg create mode 100644 mobile/public/assets/images/lights/gu10w.svg create mode 100644 mobile/public/assets/images/lights/huego.svg create mode 100644 mobile/public/assets/images/lights/huegow.svg create mode 100644 mobile/public/assets/images/lights/lc_aura.svg create mode 100644 mobile/public/assets/images/lights/lc_auraw.svg create mode 100644 mobile/public/assets/images/lights/lc_bloom.svg create mode 100644 mobile/public/assets/images/lights/lc_bloomw.svg create mode 100644 mobile/public/assets/images/lights/lc_iris.svg create mode 100644 mobile/public/assets/images/lights/lc_irisw.svg create mode 100644 mobile/public/assets/images/lights/lightstrip.svg create mode 100644 mobile/public/assets/images/lights/lightstripw.svg create mode 100644 mobile/public/assets/images/lights/storylight.svg create mode 100644 mobile/public/assets/images/lights/storylightw.svg create mode 100644 mobile/public/assets/images/logo.png create mode 100644 mobile/public/assets/images/missingArtwork.png create mode 100644 mobile/public/assets/images/pressButtonBridge.png create mode 100644 mobile/public/assets/images/sc-white-sm.png create mode 100644 mobile/public/assets/images/sc-white.png create mode 100644 mobile/public/browserconfig.xml create mode 100644 mobile/public/crossdomain.xml create mode 100644 mobile/public/favicon-16x16.png create mode 100644 mobile/public/favicon-32x32.png create mode 100644 mobile/public/favicon-96x96.png create mode 100644 mobile/public/favicon.ico create mode 100644 mobile/public/humans.txt create mode 100644 mobile/public/manifest.json create mode 100644 mobile/public/mstile-150x150.png create mode 100644 mobile/public/robots.txt create mode 100644 mobile/public/safari-pinned-tab.svg create mode 100644 mobile/testem.js create mode 100644 mobile/tests/.jshintrc create mode 100644 mobile/tests/helpers/destroy-app.js create mode 100644 mobile/tests/helpers/module-for-acceptance.js create mode 100644 mobile/tests/helpers/resolver.js create mode 100644 mobile/tests/helpers/start-app.js create mode 100644 mobile/tests/index.html create mode 100644 mobile/tests/integration/pods/components/add-soundcloud-sound-modal/component-test.js create mode 100644 mobile/tests/integration/pods/components/bridge-finder/component-test.js create mode 100644 mobile/tests/integration/pods/components/color-picker/component-test.js create mode 100644 mobile/tests/integration/pods/components/hue-controls/component-test.js create mode 100644 mobile/tests/integration/pods/components/huegasm-app/component-test.js create mode 100644 mobile/tests/integration/pods/components/light-group/component-test.js create mode 100644 mobile/tests/integration/pods/components/lights-tab/component-test.js create mode 100644 mobile/tests/integration/pods/components/music-tab/component-test.js create mode 100644 mobile/tests/test-helper.js create mode 100644 mobile/tests/unit/.gitkeep create mode 100644 mobile/vendor/dancer.js create mode 100644 mobile/yarn.lock diff --git a/mobile/.bowerrc b/mobile/.bowerrc new file mode 100644 index 0000000..959e169 --- /dev/null +++ b/mobile/.bowerrc @@ -0,0 +1,4 @@ +{ + "directory": "bower_components", + "analytics": false +} diff --git a/mobile/.editorconfig b/mobile/.editorconfig new file mode 100644 index 0000000..219985c --- /dev/null +++ b/mobile/.editorconfig @@ -0,0 +1,20 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 2 + +[*.hbs] +insert_final_newline = false + +[*.{diff,md}] +trim_trailing_whitespace = false diff --git a/mobile/.ember-cli b/mobile/.ember-cli new file mode 100644 index 0000000..b4934f3 --- /dev/null +++ b/mobile/.ember-cli @@ -0,0 +1,10 @@ +{ + /** + Ember CLI sends analytics information by default. The data is completely + anonymous, but there are times when you might want to disable this behavior. + + Setting `disableAnalytics` to true will prevent any data from being sent. + */ + "disableAnalytics": true, + "usePods": true +} diff --git a/mobile/.gitignore b/mobile/.gitignore new file mode 100644 index 0000000..905f716 --- /dev/null +++ b/mobile/.gitignore @@ -0,0 +1,26 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp + +# dependencies +/node_modules +/bower_components + +# misc +/.sass-cache +/connect.lock +/coverage/* +/libpeerconnection.log +npm-debug.log +testem.log +/.idea/ + +ember-cordova/tmp-livereload +ember-cordova/cordova/www/* +!ember-cordova/cordova/www/.gitkeep +ember-cordova/cordova/plugins/* +!ember-cordova/cordova/plugins/.gitkeep +ember-cordova/cordova/platforms/* +!ember-cordova/cordova/platforms/.gitkeep diff --git a/mobile/.jshintrc b/mobile/.jshintrc new file mode 100644 index 0000000..42624ff --- /dev/null +++ b/mobile/.jshintrc @@ -0,0 +1,37 @@ +{ + "predef": [ + "document", + "window", + "-Promise", + "Dancer", + "ID3", + "FileAPIReader", + "SC", + "introJs" + ], + "browser": true, + "boss": true, + "curly": true, + "debug": false, + "devel": true, + "eqeqeq": true, + "evil": true, + "forin": false, + "immed": false, + "laxbreak": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": false, + "nomen": false, + "onevar": false, + "plusplus": false, + "regexp": false, + "undef": true, + "sub": true, + "strict": false, + "white": false, + "eqnull": true, + "esversion": 6, + "unused": true +} diff --git a/mobile/.travis.yml b/mobile/.travis.yml new file mode 100644 index 0000000..ac9eaa1 --- /dev/null +++ b/mobile/.travis.yml @@ -0,0 +1,24 @@ +--- +language: node_js +node_js: + - "4" + +sudo: false + +cache: + directories: + - node_modules + +before_install: + - npm config set spin false + - npm install -g bower + - bower --version + - npm install phantomjs-prebuilt + - node_modules/phantomjs-prebuilt/bin/phantomjs --version + +install: + - npm install + - bower install + +script: + - npm test diff --git a/mobile/.watchmanconfig b/mobile/.watchmanconfig new file mode 100644 index 0000000..e7834e3 --- /dev/null +++ b/mobile/.watchmanconfig @@ -0,0 +1,3 @@ +{ + "ignore_dirs": ["tmp", "dist"] +} diff --git a/mobile/README.md b/mobile/README.md new file mode 100644 index 0000000..c8af9d5 --- /dev/null +++ b/mobile/README.md @@ -0,0 +1,44 @@ +# Huegasm + +This README outlines the details of collaborating on this Ember application. +Music awesomeness for hue lights. + +## Prerequisites + +You will need the following things properly installed on your computer. + +* [Git](http://git-scm.com/) +* [Node.js](http://nodejs.org/) (with NPM) +* [Bower](http://bower.io/) +* [Ember CLI](http://ember-cli.com/) +* [PhantomJS](http://phantomjs.org/) + +## Installation + +* `git clone ` this repository +* `cd huegasm` +* `npm install` +* `bower install` + +## Running / Development + +* `ember serve` +* Visit your app at [http://localhost:4200](http://localhost:4200). + +### Code Generators + +Make use of the many generators for code, try `ember help generate` for more details + +### Building + +* `ember build` (development) +* `ember build --environment production` (production) + +## Further Reading / Useful Links + +* [ember.js](http://emberjs.com/) +* [ember-cli](http://ember-cli.com/) +* Development Browser Extensions + * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi) + * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/) + diff --git a/mobile/TODO b/mobile/TODO deleted file mode 100644 index e63c25323a2203faf5bc11b08eaca2f75fb6013b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4544 zcmeHJZ)j6j6hE(Nw3WIg?QD};ZNiiW>xbAsq9Pg-1x09TEkjsU>e{Z3cFk(j>GtJS z9dkNC*^mxI*@v;QQRom6r_;1$U_nsyg9vkUMf|oYaSS$RvfuCZ-udWi7P^5<`U^Mb z+;i`{=bm%#`<+)8ULwDXNWCGh97vfXVnCz;cJ~?=VmlrT4IgcI(RyPyrSIV4`KyE7M&YZ(*JqyEi25;=jHW|L2u5W!m!u@u8ZCrL42Pw2wqetAY`R0~xtKFc=?>^_ zV`7~==<{szilNDfF?VtB}Drmo2+UGF*$E4mcQ*Q zlYjG-eMSAzo9+{LBoS>tl%}70H2eAKb70P=1MrW<=iIN(-9N2E|I9Vvly%_vUNHV% z@L)44K@B)Q2##+>C8|Mf2xF`RwpxreV`e>S!xNDI@pWtEle{$*H1BI^pYtE^|6lbd z+xS^0V`>wOKaQyOApSQHUk~C7!qQ?@!M9}@#+j8`5kJq%RGV<3=EhOiI}s(nJvQMhq|N#gprr?uzYCV9BY=}<>;&u7RM2s2X`k~f z;^%p7vv1;G>J!mV{7+*ki@)dN!4O&*+D0^u$vi|Jr;U=x#6M&2olgE1ZFhZjJWnbs h&fF&dkn{LF`A>0x=~Fg)oyeAdXXa&BC!dz5KLOxACUgJ* diff --git a/mobile/app/app.js b/mobile/app/app.js new file mode 100644 index 0000000..831ad61 --- /dev/null +++ b/mobile/app/app.js @@ -0,0 +1,18 @@ +import Ember from 'ember'; +import Resolver from './resolver'; +import loadInitializers from 'ember-load-initializers'; +import config from './config/environment'; + +let App; + +Ember.MODEL_FACTORY_INJECTIONS = true; + +App = Ember.Application.extend({ + modulePrefix: config.modulePrefix, + podModulePrefix: config.podModulePrefix, + Resolver +}); + +loadInitializers(App, config.modulePrefix); + +export default App; diff --git a/mobile/app/index.html b/mobile/app/index.html new file mode 100644 index 0000000..a96fb5f --- /dev/null +++ b/mobile/app/index.html @@ -0,0 +1,67 @@ + + + + + + Huegasm + + + + + + + + + + + + + + + + + {{content-for 'head'}} + + + + + + + + + + + + + + + {{content-for 'head-footer'}} + + + + + + + {{content-for 'body'}} + + + + + {{content-for 'body-footer'}} + + diff --git a/mobile/app/pods/components/bridge-finder/component.js b/mobile/app/pods/components/bridge-finder/component.js new file mode 100644 index 0000000..551f846 --- /dev/null +++ b/mobile/app/pods/components/bridge-finder/component.js @@ -0,0 +1,152 @@ +import Ember from 'ember'; + +const { + Component, + observer, + computed, + on, + isNone, + $ +} = Ember; + +export default Component.extend({ + elementId: 'bridge-finder', + classNames: ['container'], + bridgeIp: null, + trial: false, + bridgeUsername: null, + bridgeFindStatus: null, + bridgeFindSuccess: computed.equal('bridgeFindStatus', 'success'), + bridgeFindMultiple: computed.equal('bridgeFindStatus', 'multiple'), + bridgeFindFail: computed.equal('bridgeFindStatus', 'fail'), + bridgeUsernamePingMaxTime: 30000, // 30 seconds + bridgeUsernamePingIntervalTime: 1500, + bridgeUserNamePingIntervalProgress: 0, + bridgePingIntervalHandle: null, + bridgeAuthenticateReachedStatus: null, + manualBridgeIp: null, + manualBridgeIpNotFound: false, + multipleBridgeIps: [], + error: false, + isAuthenticating: computed.notEmpty('bridgePingIntervalHandle'), + + // try to authenticate against the bridge here + onBridgeIpChange: on('init', observer('bridgeIp', function(){ + if(!this.get('trial') && !this.get('isAuthenticating')) { + this.setProperties({ + bridgePingIntervalHandle: setInterval(this.pingBridgeUser.bind(this), this.get('bridgeUsernamePingIntervalTime')), + bridgeUserNamePingIntervalProgress: 0 + }); + } + })), + + didInsertElement() { + $(document).keypress((event)=>{ + if(!isNone(this.get('manualBridgeIp')) && event.which === 13) { + this.send('findBridgeByIp'); + } + }); + }, + + // find the bridge ip here + init() { + this._super(...arguments); + + if(this.get('bridgeIp') === null) { + $.ajax('https://www.meethue.com/api/nupnp', { + timeout: 30000 + }) + .done((result, status)=> { + let bridgeFindStatus = 'fail'; + + if (status === 'success' && result.length === 1) { + this.set('bridgeIp', result[0].internalipaddress); + this.get('storage').set('huegasm.bridgeIp', result[0].internalipaddress); + bridgeFindStatus = 'success'; + } else if (result.length > 1) { + let multipleBridgeIps = this.get('multipleBridgeIps'); + + result.forEach(function (item) { + multipleBridgeIps.pushObject(item.internalipaddress); + }); + + bridgeFindStatus = 'multiple'; + } else { + bridgeFindStatus = 'fail'; + } + + this.set('bridgeFindStatus', bridgeFindStatus); + }) + .fail(()=>{ + this.set('bridgeFindStatus', 'fail'); + }); + } + }, + + pingBridgeUser() { + let bridgeIp = this.get('bridgeIp'), + bridgeUserNamePingIntervalProgress = this.get('bridgeUserNamePingIntervalProgress'), + bridgeUsernamePingMaxTime = this.get('bridgeUsernamePingMaxTime'); + + if (bridgeIp !== null && bridgeUserNamePingIntervalProgress < 100) { + $.ajax('http://' + bridgeIp + '/api', { + data: JSON.stringify({"devicetype": "huegasm"}), + contentType: 'application/json', + type: 'POST' + }).done((result, status)=>{ + if(!this.isDestroyed){ + this.set('bridgeAuthenticateReachedStatus', status); + + if (status === 'success' && !result[0].error) { + this.clearBridgePingIntervalHandle(); + this.get('storage').set('huegasm.bridgeUsername', result[0].success.username); + this.set('bridgeUsername', result[0].success.username); + } + } + }).fail(()=>{ + this.clearBridgePingIntervalHandle(); + this.set('error', true); + }); + + this.incrementProperty('bridgeUserNamePingIntervalProgress', this.get('bridgeUsernamePingIntervalTime')/bridgeUsernamePingMaxTime*100); + } else { + this.clearBridgePingIntervalHandle(); + } + }, + + clearBridgePingIntervalHandle(){ + clearInterval(this.get('bridgePingIntervalHandle')); + this.set('bridgePingIntervalHandle', null); + }, + + actions: { + retry(){ + this.onBridgeIpChange(); + }, + chooseBridge(bridge){ + this.set('bridgeIp', bridge); + }, + findBridgeByIp() { + let manualBridgeIp = this.get('manualBridgeIp'); + + if (manualBridgeIp.toLowerCase() === 'trial' || manualBridgeIp.toLowerCase() === 'offline') { + this.setProperties({ + trial: true, + bridgeIp: 'trial', + bridgeUsername: 'trial' + }); + } else { + $.ajax('http://' + manualBridgeIp + '/api', { + data: JSON.stringify({"devicetype": "huegasm"}), + contentType: 'application/json', + type: 'POST' + }).fail(() => { + this.set('manualBridgeIpNotFound', true); + setTimeout(() => { this.set('manualBridgeIpNotFound', false); }, 5000); + }).then(() => { + this.set('bridgeIp', manualBridgeIp); + }); + } + } + }, +}); diff --git a/mobile/app/pods/components/bridge-finder/template.hbs b/mobile/app/pods/components/bridge-finder/template.hbs new file mode 100644 index 0000000..b1d1e8a --- /dev/null +++ b/mobile/app/pods/components/bridge-finder/template.hbs @@ -0,0 +1,57 @@ +
Huegasm
+{{#unless bridgeUsername}} + {{#if bridgeIp}} + {{#if error}} +

Huegasm encountered a critical error while trying to connect to your bridge.

+ This likely happened because you're using an outdated browser and/or because your browser does not support CORS. Feel free to contact me through the link at the bottom of the page if you feel like this is not the case.
+ For the best browsing experience on this site ( and every other one known to man ) please switch to Google Chrome or Firefox.

+ {{else}} + + {{paper-progress-linear warn=true value=bridgeUserNamePingIntervalProgress}} + + {{#if isAuthenticating}} +

+ Your bridge IP is {{bridgeIp}} +
+ Press the button on your bridge to authenticate this application. +

+ {{else}} +

You failed to press the button in time. RETRY

+ {{/if}} + {{/if}} + {{else}} + {{#unless bridgeFindStatus}} + {{paper-progress-circular diameter=100}} +

Trying to find your bridge's IP.

+ {{/unless}} + + {{#if bridgeFindMultiple}} +

Found multiple hue bridges.
+ Please select the one you want to use for this application.

+ +
+ {{#each multipleBridgeIps as |bridge|}} + {{paper-radio value=bridge label=bridge onChange=(action "chooseBridge")}} + {{/each}} +
+ {{else}} + {{#if bridgeFindFail}} +

A hue bridge could not be automatically found on your network.
+ Enter one manually?

+ ( or type offline to look around ) +

+ + + {{paper-input label="Hue bridge IP address" value=manualBridgeIp onChange=(action (mut manualBridgeIp))}} + {{paper-button onClick=(action "findBridgeByIp") raised=true primary=true label="Find"}} + + + {{#if manualBridgeIpNotFound}} +

+ Could not find a bridge with that IP address. +

+ {{/if}} + {{/if}} + {{/if}} + {{/if}} +{{/unless}} \ No newline at end of file diff --git a/mobile/app/pods/components/hue-controls/component.js b/mobile/app/pods/components/hue-controls/component.js new file mode 100644 index 0000000..78a780b --- /dev/null +++ b/mobile/app/pods/components/hue-controls/component.js @@ -0,0 +1,260 @@ +import Ember from 'ember'; +import ENV from 'huegasm/config/environment'; + +const { + A, + Component, + computed, + isEmpty, + isNone, + run, + $ +} = Ember; + +export default Component.extend({ + classNames: ['container-fluid'], + elementId: 'hue-controls', + lightsData: null, + activeLights: A(), + tabList: ["Lights", "Music"], + selectedTab: 1, + pauseLightUpdates: false, + + lightsTabSelected: computed.equal('selectedTab', 0), + musicTabSelected: computed.equal('selectedTab', 1), + + dimmerOnClass: computed('dimmerOn', function(){ + return this.get('dimmerOn') ? 'dimmerOn md-menu-origin' : 'md-menu-origin'; + }), + + ready: computed('lightsData', 'trial', function() { + return this.get('trial') || !isNone(this.get('lightsData')); + }), + + apiURL: computed('bridgeIp', 'bridgeUsername', function(){ + return 'http://' + this.get('bridgeIp') + '/api/' + this.get('bridgeUsername'); + }), + + tabData: computed('tabList', 'selectedTab', function(){ + let tabData = [], selectedTab = this.get('selectedTab'); + + this.get('tabList').forEach(function(tab, i){ + let selected = false; + + if(i === selectedTab){ + selected = true; + } + + tabData.push({"name": tab, "selected": selected }); + }); + + return tabData; + }), + + didInsertElement(){ + // here's a weird way to automatically initialize bootstrap tooltips + let observer = new MutationObserver(function(mutations) { + let haveTooltip = !mutations.every(function(mutation) { + return isEmpty(mutation.addedNodes) || isNone(mutation.addedNodes[0].classList) || mutation.addedNodes[0].classList.contains('tooltip'); + }); + + if(haveTooltip) { + run.scheduleOnce('afterRender', function(){ + $('.bootstrap-tooltip').tooltip(); + }); + } + }); + + observer.observe($('#hue-controls')[0], {childList: true, subtree: true}); + }, + + init() { + this._super(...arguments); + + if(!this.get('trial')) { + this.updateLightData(); + this.set('lightsDataIntervalHandle', setInterval(this.updateLightData.bind(this), 2000)); + } + + if (!isNone(this.get('storage').get('huegasm.selectedTab'))) { + this.set('selectedTab', this.get('storage').get('huegasm.selectedTab')); + } + }, + + updateLightData(){ + let fail = ()=>{ + if(!ENV.ignoreFailures) { + clearInterval(this.get('lightsDataIntervalHandle')); + this.send('clearBridge'); + } + }; + + if(!this.get('pauseLightUpdates')){ + $.get(this.get('apiURL') + '/lights', (result, status)=>{ + if(!isNone(result[0]) && !isNone(result[0].error)){ + fail(); + } else if (status === 'success' && JSON.stringify(this.get('lightsData')) !== JSON.stringify(result)) { + this.set('lightsData', result); + } + }).fail(fail); + } + }, + + actions: { + changeTab(tabName){ + let index = this.get('tabList').indexOf(tabName); + this.set('selectedTab', index); + this.get('storage').set('huegasm.selectedTab', index); + }, + clearBridge() { + let storage = this.get('storage'); + storage.remove('huegasm.bridgeUsername'); + storage.remove('huegasm.bridgeIp'); + location.reload(); + }, + clearAllSettings() { + this.get('storage').clear(); + location.reload(); + }, + startIntro(){ + let INTRO = introJs, + intro = INTRO(), + playerBottom = $('#player-bottom'), + beatDetectionAreaArrowIcon = $('#beat-detection-area-arrow-icon'); + + intro.setOptions({ + steps: [ + { + intro: 'Welcome! This short tutorial will introduce you to Huegasm.' + }, + { + element: '#music-tab', + intro: 'This is the music player. You\'ll use this to play music and synchronize it with your active lights.

' + + 'TIP: Control which lights are active through the Lights tab.' + }, + { + element: '#playlist', + intro: 'You can add and select music to play from your playlist here. You may listen to local audio files, stream music from soundcloud or stream directly from a connected microphone.

' + + 'TIP: Songs added through Soundcloud will be saved for when you visit this page again.' + }, + { + element: '#player-area', + intro: 'The audio playback may be controlled with the controls here. Basic music visualization effects may be shown here by selecting them from the menu ( eyeball icon in the bottom right ).' + }, + { + element: '#beat-option-row', + intro: 'These are the settings for the music tab:
' + + 'Sensitivity - The sensitivity of the beat detector ( more sensitivity results in more registered beats )
' + + 'Hue Range - The hue range that the lights may change to on beat.
' + + 'Flashing Transitions - Quickly flash the lights on beat
' + + 'Colorloop - Slowly cycle the lights through all the colors while the music is playing
' + + 'TIP: Your sensitivity settings are saved per song as indicated by the red star icon in the top left corner. These settings they will be restored if you ever listen to the same song again.', + position: 'top' + }, + { + element: '#beat-container', + intro: 'An interactive speaker that will bump when a beat is registered.

' + + 'TIP: Click on the center of the speaker to simulate a beat.', + position: 'top' + }, + { + element: '#lights-tab', + intro: 'This is the lights tab. Here you\'ll be able to change various light properties:
' + + 'Power - Turn the selected lights on/off
' + + 'Brightness - The brightness level of the selected lights
' + + 'Color - The color of the selected lights
' + + 'Strobe - Selected lights will flash in sequential order
' + + 'Colorloop - Selected lights will slowly cycle through all the colors
' + }, + { + element: '#active-lights', + intro: 'These icons represent the hue lights in your system. Active lights will be controlled by the application while the inactive lights will have a red X over them and will not be controlled.
' + + 'You may toggle a light\'s state by clicking on it.' + }, + { + element: '#settings', + intro: 'A few miscellaneous settings can be found here.

' + + 'WARNING: clearing application settings will restore the application to its original state. This will even delete your playlist and any saved song beat preferences.', + position: 'bottom' + }, + { + element: '#dimmer', + intro: 'And that\'s it...Hope you enjoy the application. ;)

' + + 'TIP: click on the icon to switch to a darker theme.', + position: 'top' + } + ] + }); + + // it's VERY ugly but it works... the jQuery massacre :'( + intro.onchange((element) => { + if(element.id === 'music-tab' || element.id === 'playlist' || element.id === 'player-area' || element.id === 'beat-option-row' || element.id === 'beat-option-button-group' || element.id === 'beat-container' || element.id === 'using-mic-audio-tooltip'){ + $('#music-tab').removeClass('hidden'); + $('#lights-tab').addClass('hidden'); + $('.navigation-item').eq(0).removeClass('active'); + $('.navigation-item').eq(1).addClass('active'); + } else { + $('#lights-tab').removeClass('hidden'); + $('#music-tab').addClass('hidden'); + $('.navigation-item').eq(1).removeClass('active'); + $('.navigation-item').eq(0).addClass('active'); + } + + if(element.id === 'music-tab' || element.id === 'playlist' || element.id === 'player-area'){ + playerBottom.hide(); + + if(beatDetectionAreaArrowIcon.hasClass('keyboard-arrow-up')){ + beatDetectionAreaArrowIcon.removeClass('keyboard-arrow-up').addClass('keyboard-arrow-down'); + } + } else if(element.id === 'beat-option-row' || element.id === 'beat-option-button-group' || element.id === 'beat-container'){ + playerBottom.show(); + + if(beatDetectionAreaArrowIcon.hasClass('keyboard-arrow-down')){ + beatDetectionAreaArrowIcon.removeClass('keyboard-arrow-down').addClass('keyboard-arrow-up'); + } + } else if(element.id === 'dimmer'){ + $(document).click(); + } + }); + + let onFinish = ()=>{ + this.set('activeTab', 1); + $('#music-tab').removeClass('hidden'); + $('#lights-tab').addClass('hidden'); + $('.navigation-item').eq(0).removeClass('active'); + $('.navigation-item').eq(1).addClass('active'); + + if(beatDetectionAreaArrowIcon.hasClass('keyboard-arrow-up')){ + playerBottom.show(); + } else { + playerBottom.hide(); + } + }, onExit = ()=>{ + let dimmer = $('#dimmer'); + + onFinish(); + dimmer.popover({ + trigger: 'manual', + placement: 'top', + content: 'Click on this icon to toggle the dark theme.' + }).popover('show'); + + setTimeout(()=>{ + dimmer.popover('hide'); + }, 5000); + }; + + // skip hidden/missing elements + intro.onafterchange((element)=>{ + let elem = $(element); + if(elem.html() === ''){ + $('.introjs-nextbutton').click(); + } + + run.later(this, function() { + $('.introjs-tooltip').velocity('scroll'); + }, 500); + }).onexit(onExit).oncomplete(onFinish).start(); + } + } +}); diff --git a/mobile/app/pods/components/hue-controls/template.hbs b/mobile/app/pods/components/hue-controls/template.hbs new file mode 100644 index 0000000..72eaf95 --- /dev/null +++ b/mobile/app/pods/components/hue-controls/template.hbs @@ -0,0 +1,36 @@ +{{#if ready}} + + + {{light-group lightsData=lightsData activeLights=activeLights syncLight=syncLight apiURL=apiURL dimmerOn=dimmerOn storage=storage}} + + {{lights-tab apiURL=apiURL lightsData=lightsData activeLights=activeLights syncLight=syncLight trial=trial active=lightsTabSelected colorLoopOn=colorLoopOn dimmerOn=dimmerOn}} + + {{music-tab apiURL=apiURL lightsData=lightsData activeLights=activeLights active=musicTabSelected pauseLightUpdates=pauseLightUpdates dimmerOn=dimmerOn storage=storage colorLoopOn=colorLoopOn action="startIntro"}} +{{/if}} \ No newline at end of file diff --git a/mobile/app/pods/components/huegasm-app/component.js b/mobile/app/pods/components/huegasm-app/component.js new file mode 100644 index 0000000..7472972 --- /dev/null +++ b/mobile/app/pods/components/huegasm-app/component.js @@ -0,0 +1,68 @@ +import Ember from 'ember'; + +const { + Component, + computed, + isEmpty, + isNone, + $ +} = Ember; + +export default Component.extend({ + bridgeIp: null, + bridgeUsername: null, + trial: false, + storage: null, + dimmerOn: false, + ready: false, + + year: computed(function(){ + return new Date().getFullYear(); + }), + + dimmerOnClass: computed('dimmerOn', function(){ + let dimmerOn = this.get('dimmerOn'), + storage = this.get('storage'), + dimmerOnClass = null; + + if (dimmerOn) { + $('body').addClass('dimmerOn'); + $('html').addClass('dimmerOn'); + dimmerOnClass = 'active'; + } else { + $('body').removeClass('dimmerOn'); + $('html').removeClass('dimmerOn'); + } + + storage.set('huegasm.dimmerOn', dimmerOn); + + return dimmerOnClass; + }), + + init(){ + this._super(...arguments); + + let storage = new window.Locally.Store({compress: true}); + this.set('storage', storage); + + if (!isNone(storage.get('huegasm.dimmerOn'))) { + this.set('dimmerOn', storage.get('huegasm.dimmerOn')); + } + + if (!isEmpty(storage.get('huegasm.bridgeIp')) && !isEmpty(storage.get('huegasm.bridgeUsername'))) { + this.setProperties({ + bridgeIp: storage.get('huegasm.bridgeIp'), + bridgeUsername: storage.get('huegasm.bridgeUsername') + }); + } + }, + + actions: { + toggleDimmer(){ + this.toggleProperty('dimmerOn'); + }, + isReady(){ + this.set('ready', true); + } + } +}); diff --git a/mobile/app/pods/components/huegasm-app/template.hbs b/mobile/app/pods/components/huegasm-app/template.hbs new file mode 100644 index 0000000..d1723b8 --- /dev/null +++ b/mobile/app/pods/components/huegasm-app/template.hbs @@ -0,0 +1,39 @@ +{{#if bridgeUsername}} + {{hue-controls bridgeIp=bridgeIp bridgeUsername=bridgeUsername trial=trial dimmerOn=dimmerOn storage=storage}} +{{else}} + {{#if ready}} + {{bridge-finder bridgeIp=bridgeIp bridgeUsername=bridgeUsername trial=trial storage=storage}} + {{else}} +
+
+ Huegasm +
+ +

+ Your lights, meet your music. Huegasm. +

+

+ Huegasm is a free web application for managing and synchronizing your Philips Hue lights with the beat of your music. +

+ +
+
+ +
+
+ {{paper-button raised=true primary=true onClick=(action "isReady") class="go-button center-block" label="Go!"}} +
+ {{/if}} +{{/if}} + + \ No newline at end of file diff --git a/mobile/app/pods/components/light-group/component.js b/mobile/app/pods/components/light-group/component.js new file mode 100644 index 0000000..7b448bd --- /dev/null +++ b/mobile/app/pods/components/light-group/component.js @@ -0,0 +1,157 @@ +import Ember from 'ember'; + +const { + A, + Component, + computed, + isEmpty, + isNone, + observer, + $ +} = Ember; + +export default Component.extend({ + elementId: 'active-lights', + classNames: ['light-group', 'horizontal-light-group'], + isHovering: false, + activeLights: A(), + + // list of all the lights in the hue system + lightsList: computed('lightsData', 'activeLights.[]', 'dimmerOn', function(){ + let lightsData = this.get('lightsData'), + activeLights = this.get('activeLights'), + dimmerOn = this.get('dimmerOn'), + lightsList = A(), + type, + activeClass; + + for (let key in lightsData) { + activeClass = 'light-active'; + + if (lightsData.hasOwnProperty(key) && lightsData[key].state.reachable) { + switch(lightsData[key].modelid){ + case 'LCT001': + type = 'a19'; + break; + case 'LCT002': + type = 'br30'; + break; + case 'LCT003': + type = 'gu10'; + break; + case 'LST001': + type = 'lightstrip'; + break; + case 'LLC010': + type = 'lc_iris'; + break; + case 'LLC011': + type = 'lc_bloom'; + break; + case 'LLC012': + type = 'lc_bloom'; + break; + case 'LLC006': + type = 'lc_iris'; + break; + case 'LLC007': + type = 'lc_aura'; + break; + case 'LLC013': + type = 'storylight'; + break; + case 'LWB004': + type ='a19'; + break; + case 'LLC020': + type = 'huego'; + break; + default: + type = 'a19'; + } + + if(dimmerOn){ + type += 'w'; + } + + if(!activeLights.includes(key)){ + activeClass = 'light-inactive'; + } + + lightsList.push({type: type, name: lightsData[key].name, id: key, data: lightsData[key], activeClass: activeClass}); + } + } + + return lightsList; + }), + + onActiveLightsChange: observer('activeLights.[]', function(){ + this.get('storage').set('huegasm.activeLights', this.get('activeLights')); + }), + + init(){ + this._super(...arguments); + + let lightsData = this.get('lightsData'), + activeLights = this.get('activeLights'), + activeLightsCache = this.get('storage').get('huegasm.activeLights'); + + if(!isNone(activeLightsCache)){ + activeLightsCache.forEach(function(i){ + if (lightsData.hasOwnProperty(i) && lightsData[i].state.reachable) { + activeLights.pushObject(i); + } + }); + } else { + for (let key in lightsData) { + if (lightsData.hasOwnProperty(key) && lightsData[key].state.reachable) { + activeLights.pushObject(key); + } + } + } + }, + + actions: { + clickLight(id){ + let activeLights = this.get('activeLights'), + lightId = activeLights.indexOf(id); + + if(lightId !== -1){ + activeLights.removeObject(id); + } else { + activeLights.pushObject(id); + this.set('syncLight', id); + } + }, + lightStartHover(id){ + let hoveredLight = this.get('lightsList').filter(function(light){ + return light.activeClass !== 'unreachable' && light.id === id[0]; + }); + + if(!isEmpty(hoveredLight) && this.get('noHover') !== true){ + $.ajax(this.get('apiURL') + '/lights/' + id + '/state', { + data: JSON.stringify({"alert": "lselect"}), + contentType: 'application/json', + type: 'PUT' + }); + } + + this.set('isHovering', true); + }, + lightStopHover(id){ + let hoveredLight = this.get('lightsList').filter(function(light){ + return light.activeClass !== 'unreachable' && light.id === id[0]; + }); + + if(!isEmpty(hoveredLight) && this.get('noHover') !== true){ + $.ajax(this.get('apiURL') + '/lights/' + id + '/state', { + data: JSON.stringify({"alert": "none"}), + contentType: 'application/json', + type: 'PUT' + }); + } + + this.set('isHovering', false); + } + } +}); diff --git a/mobile/app/pods/components/light-group/template.hbs b/mobile/app/pods/components/light-group/template.hbs new file mode 100644 index 0000000..2b0361a --- /dev/null +++ b/mobile/app/pods/components/light-group/template.hbs @@ -0,0 +1,5 @@ +{{#each lightsList as |light|}} +
+ +
+{{/each}} \ No newline at end of file diff --git a/mobile/app/pods/components/lights-tab/color-picker/component.js b/mobile/app/pods/components/lights-tab/color-picker/component.js new file mode 100644 index 0000000..232cfb1 --- /dev/null +++ b/mobile/app/pods/components/lights-tab/color-picker/component.js @@ -0,0 +1,58 @@ +import Ember from 'ember'; + +const { + Component, + $ +} = Ember; + +export default Component.extend({ + elementId: 'color-picker', + rgb: null, + canvas: null, + canvasContext: null, + pressingDown: false, + + mouseUp(){ + this.set('pressingDown', false); + }, + + mouseMove(event){ + if (this.get('pressingDown')) { + this.mouseDown(event); + } + }, + + mouseDown(event){ + let canvasOffset = $(this.get('canvas')).offset(), + canvasX = Math.floor(event.pageX - canvasOffset.left), + canvasY = Math.floor(event.pageY - canvasOffset.top); + + // get current pixel + let imageData = this.get('canvasContext').getImageData(canvasX, canvasY, 1, 1), + pixel = imageData.data; + + this.set('pressingDown', true); + + if (!(pixel[0] === 0 && pixel[1] === 0 && pixel[2] === 0)) { + this.set('rgb', [pixel[0], pixel[1], pixel[2]]); + } + }, + + // https://dzone.com/articles/creating-your-own-html5 + didInsertElement(){ + // handle color changes + let canvas = $('#picker')[0], + canvasContext = canvas.getContext('2d'), + image = new Image(); + + image.src = 'assets/images/colormap.png'; + image.onload = function () { + canvasContext.drawImage(image, 0, 0, image.width, image.height); // draw the image on the canvas + }; + + this.setProperties({ + canvas: canvas, + canvasContext: canvasContext + }); + } +}); diff --git a/mobile/app/pods/components/lights-tab/color-picker/template.hbs b/mobile/app/pods/components/lights-tab/color-picker/template.hbs new file mode 100644 index 0000000..16508e9 --- /dev/null +++ b/mobile/app/pods/components/lights-tab/color-picker/template.hbs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile/app/pods/components/lights-tab/component.js b/mobile/app/pods/components/lights-tab/component.js new file mode 100644 index 0000000..ab57143 --- /dev/null +++ b/mobile/app/pods/components/lights-tab/component.js @@ -0,0 +1,364 @@ +import Ember from 'ember'; + +const { + Component, + observer, + computed, + on, + $ +} = Ember; + +export default Component.extend({ + classNames: ['col-sm-8', 'col-sm-offset-2', 'col-xs-12'], + classNameBindings: ['active::hidden'], + elementId: 'lights-tab', + + colorPickerDisplayed: false, + + rgb: [255, 255, 255], + + lightsOn: false, + + // COLOR LOOP related stuff + colorLoopOn: false, + + lightsOnTxt: computed('lightsOn', function(){ + return this.get('lightsOn') ? 'On' : 'Off'; + }), + + colorloopOnTxt: computed('colorLoopOn', function(){ + return this.get('colorLoopOn') ? 'On' : 'Off'; + }), + + colorRowAction: computed('strobeOn', function() { + if (this.get('trial')) { + return null; + } + + return 'toggleColorPicker'; + }), + + // determines the average brightness of the hue system for the brightness slider + lightsBrightness: computed('lightsData', function(){ + let lightsData = this.get('lightsData'), + activeLights = this.get('activeLights'), + lightsBrightness = 0; + + activeLights.forEach(function(light){ + lightsBrightness += lightsData[light].state.bri; + }); + + return lightsBrightness/activeLights.length; + }), + + brightnessControlDisabled: computed.not('lightsOn'), + + onColorLoopOnChange: observer('colorLoopOn', function(){ + let lightsData = this.get('lightsData'), + activeLights = this.get('activeLights'), + colorLoopsOn = this.get('colorLoopOn'), + effect = colorLoopsOn ? 'colorloop' : 'none'; + + let colorLoopsOnSystem = activeLights.some(function(light) { + return lightsData[light].state.effect === 'colorloop'; + }); + + // if the internal lights state is different than the one from lightsData ( user manually toggled the switch ), send the request to change the bulbs state + if(colorLoopsOn !== colorLoopsOnSystem){ + activeLights.forEach((light)=>{ + if(this.get('lightsData')[light].state.effect !== effect) { + $.ajax(this.get('apiURL') + '/lights/' + light + '/state', { + data: JSON.stringify({'effect': effect }), + contentType: 'application/json', + type: 'PUT' + }); + } + }); + } + }), + + rgbPreview: observer('rgb', function() { + let rgb = this.get('rgb'), + xy = this.rgbToXy(rgb[0], rgb[1], rgb[2]); + + this.set('colorLoopOn', false); + + this.get('activeLights').forEach((light) => { + $.ajax(this.get('apiURL') + '/lights/' + light + '/state', { + data: JSON.stringify({"xy": xy}), + contentType: 'application/json', + type: 'PUT' + }); + }); + + this.set('colorLoopOn', false); + $('.color').css('background', 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')'); + }), + + // determines whether the lights are on/off for the lights switch + lightsOnChange: on('init', observer('lightsData.@each.state.on', 'activeLights.[]', function(){ + if(!this.get('strobeOn')){ + let lightsData = this.get('lightsData'), lightsOn = this.get('activeLights').some(function(light) { + return lightsData[light].state.on === true; + }); + + this.set('lightsOn', lightsOn); + } + })), + + onLightsOnChange: observer('lightsOn', function(){ + let lightsData = this.get('lightsData'), + activeLights = this.get('activeLights'), + lightsOn = this.get('lightsOn'); + + let lightsOnSystem = activeLights.some(function(light) { + return lightsData[light].state.on === true; + }); + + // if the internal lights state is different than the one from lightsData ( user manually toggled the switch ), send the request to change the bulbs state + if(lightsOn !== lightsOnSystem){ + activeLights.forEach((light)=>{ + $.ajax(this.get('apiURL') + '/lights/' + light + '/state', { + data: JSON.stringify({"on": lightsOn}), + contentType: 'application/json', + type: 'PUT' + }); + }); + } + }), + + onBrightnessChanged: observer('lightsBrightness', function(){ + let lightsData = this.get('lightsData'), + lightsBrightnessSystem = false, + lightsBrightness = this.get('lightsBrightness'), + activeLights = this.get('activeLights'); + + activeLights.forEach(function(light){ + lightsBrightnessSystem += lightsData[light].state.bri; + }); + + lightsBrightnessSystem /= activeLights.length; + + // if the internal lights state is different than the one from lightsData ( user manually toggled the switch ), send the request to change the bulbs state + if(lightsBrightness !== lightsBrightnessSystem){ + activeLights.forEach((light)=>{ + $.ajax(this.get('apiURL') + '/lights/' + light + '/state', { + data: JSON.stringify({"bri": lightsBrightness}), + contentType: 'application/json', + type: 'PUT' + }); + }); + } + }), + + // sync the current light settings to the newly added light + onaActiveLightsChange: observer('syncLight', function(){ + let options = { + on: this.get('lightsOn'), + bri: this.get('lightsBrightness'), + effect: this.get('colorLoopOn') ? 'colorloop' : 'none' + }, rgb = this.get('rgb'), + syncLight = this.get('syncLight'); + + if(rgb[0] !== 255 && rgb[1] !== 255 && rgb[2] !== 255) { + options['xy'] = this.rgbToXy(rgb[0], rgb[1], rgb[2]); + } + + options['transitiontime'] = 0; + + $.ajax(this.get('apiURL') + '/lights/' + syncLight + '/state', { + data: JSON.stringify(options), + contentType: 'application/json', + type: 'PUT' + }); + }), + + didInsertElement() { + $(document).click((event)=>{ + if(this.get('colorPickerDisplayed') && !event.target.classList.contains('color') && !$(event.target).closest('#color-picker, #color-row').length) { + this.toggleProperty('colorPickerDisplayed'); + } + }); + + $(document).on('click', '#color-row', () => { + this.send('toggleColorPicker'); + }); + }, + + actions: { + toggleColorPicker() { + this.toggleProperty('colorPickerDisplayed'); + } + }, + + // **************** STROBE LIGHT START **************** + strobeOn: false, + + strobeOnInervalHandle: null, + strobeSat: 0, + preStrobeOnLightsDataCache: null, + lastStrobeLight: 0, + + onStrobeOnChange: observer('strobeOn', function () { + let lightsData = this.get('lightsData'); + + if (this.get('strobeOn')) { + this.set('preStrobeOnLightsDataCache', lightsData); + let stobeInitRequestData = {'sat': this.get('strobeSat'), 'transitiontime': 0}; + + for (let key in lightsData) { + if (lightsData.hasOwnProperty(key)) { + if (lightsData[key].state.on) { + stobeInitRequestData.on = false; + } + + $.ajax(this.get('apiURL') + '/lights/' + key + '/state', { + data: JSON.stringify(stobeInitRequestData), + contentType: 'application/json', + type: 'PUT' + }); + } + } + + this.set('strobeOnInervalHandle', setInterval(this.strobeStep.bind(this), 200)); + } else { // revert the light system to pre-strobe + let preStrobeOnLightsDataCache = this.get('preStrobeOnLightsDataCache'), updateLight = (lightIndex)=> { + $.ajax(this.get('apiURL') + '/lights/' + lightIndex + '/state', { + data: JSON.stringify({ + 'on': preStrobeOnLightsDataCache[lightIndex].state.on, + 'sat': preStrobeOnLightsDataCache[lightIndex].state.sat + }), + contentType: 'application/json', + type: 'PUT' + }); + }; + + for (let key in lightsData) { + if (lightsData.hasOwnProperty(key)) { + setTimeout(updateLight, 2000, key); + } + } + + setTimeout(()=>{this.onColorLoopOnChange();}, 2000); + clearInterval(this.get('strobeOnInervalHandle')); + } + }), + + strobeStep() { + let lastStrobeLight = (this.get('lastStrobeLight') + 1) % (this.get('activeLights').length + 1), + turnOnOptions = {'on': true, 'transitiontime': 0, 'alert': 'select'}; + + // random light if in cololoop mode + if(this.get('colorLoopOn')) { + turnOnOptions.hue = Math.floor(Math.random() * 65535); + } + + $.ajax(this.get('apiURL') + '/lights/' + lastStrobeLight + '/state', { + data: JSON.stringify(turnOnOptions), + contentType: 'application/json', + type: 'PUT' + }); + $.ajax(this.get('apiURL') + '/lights/' + lastStrobeLight + '/state', { + data: JSON.stringify({'on': false, 'transitiontime': 0}), + contentType: 'application/json', + type: 'PUT' + }); + + this.set('lastStrobeLight', lastStrobeLight); + }, + + strobeOnTxt: computed('strobeOn', function () { + return this.get('strobeOn') ? 'On' : 'Off'; + }), + + dimmerOnClass: computed('dimmerOn', function(){ + return this.get('dimmerOn') ? 'dimmerOn' : null; + }), + + // **************** STROBE LIGHT FINISH **************** + // http://www.developers.meethue.com/documentation/color-conversions-rgb-xy + rgbToXy(red, green, blue){ + let X, Y, Z, x, y; + + // normalize + red = Number((red/255)); + green = Number((green/255)); + blue = Number((blue/255)); + + // gamma correction + red = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92); + green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92); + blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92); + + // RGB to XYZ + X = red * 0.664511 + green * 0.154324 + blue * 0.162028; + Y = red * 0.283881 + green * 0.668433 + blue * 0.047685; + Z = red * 0.000088 + green * 0.072310 + blue * 0.986039; + + x = X / (X + Y + Z); + y = Y / (X + Y + Z); + + return [x,y]; + }, + + xyToRgb(x, y){ + let r, g, b, X, Y = 1.0, Z; + + X = (Y / y) * x; + Z = (Y / y) * (1 - x - y); + + r = X * 1.656492 - Y * 0.354851 - Z * 0.255038; + g = X * -0.707196 + Y * 1.655397 + Z * 0.036152; + b = X * 0.051713 - Y * 0.121364 + Z * 1.011530; + + if (r > b && r > g && r > 1.0) { + // red is too big + g = g / r; + b = b / r; + r = 1.0; + } else if (g > b && g > r && g > 1.0) { + // green is too big + r = r / g; + b = b / g; + g = 1.0; + } else if (b > r && b > g && b > 1.0) { + // blue is too big + r = r / b; + g = g / b; + b = 1.0; + } + + r = (r <= 0.0031308) ? 12.92 * r : 1.055 * Math.pow(r, (1.0 / 2.4)) - 0.055; + g = (g <= 0.0031308) ? 12.92 * g : 1.055 * Math.pow(g, (1.0 / 2.4)) - 0.055; + b = (b <= 0.0031308) ? 12.92 * b : 1.055 * Math.pow(b, (1.0 / 2.4)) - 0.055; + + if (r > b && r > g) { + // red is biggest + if (r > 1.0) { + g = g / r; + b = b / r; + r = 1.0; + } + } else if (g > b && g > r) { + // green is biggest + if (g > 1.0) { + r = r / g; + b = b / g; + g = 1.0; + } + } else if (b > r && b > g) { + // blue is biggest + if (b > 1.0) { + r = r / b; + g = g / b; + b = 1.0; + } + } + + r = r * 255; + g = g * 255; + b = b * 255; + + return [r, g, b]; + } +}); diff --git a/mobile/app/pods/components/lights-tab/template.hbs b/mobile/app/pods/components/lights-tab/template.hbs new file mode 100644 index 0000000..fcd5118 --- /dev/null +++ b/mobile/app/pods/components/lights-tab/template.hbs @@ -0,0 +1,38 @@ +{{#paper-list}} + {{#paper-item}} + {{paper-icon "power-settings-new" class=dimmerOnClass}} +

Power

+ {{paper-switch value=lightsOn onChange=(action (mut lightsOn)) disabled=trial skipProxy=trial label=lightsOnTxt}} + {{/paper-item}} + + {{#paper-item}} + {{paper-icon "brightness-4" class=dimmerOnClass}} +

Brightness

+ {{paper-slider flex=true min='1' max='254' value=lightsBrightness disabled=brightnessControlDisabled}} + {{/paper-item}} + + {{#paper-item elementId="color-row"}} + {{paper-icon "color-lens" class=dimmerOnClass}} +

Color

+ {{/paper-item}} + +
+ {{paper-button raised=true class="color" onClick=(action "toggleColorPicker") disabled=trial}} + + {{#if colorPickerDisplayed}} + {{lights-tab/color-picker lightsData=lightsData activeLights=activeLights rgb=rgb}} + {{/if}} +
+ + {{#paper-item}} + {{paper-icon "flare" class=dimmerOnClass}} +

Strobe

+ {{paper-switch value=strobeOn onChange=(action (mut strobeOn)) disabled=trial skipProxy=trial label=strobeOnTxt}} + {{/paper-item}} + + {{#paper-item}} + {{paper-icon "color-lens" class=dimmerOnClass}} {{paper-icon "loop" id="loop-addition" class=dimmerOnClass}} +

Colorloop

+ {{paper-switch value=colorLoopOn onChange=(action (mut colorLoopOn)) disabled=trial skipProxy=trial label=colorloopOnTxt}} + {{/paper-item}} +{{/paper-list}} \ No newline at end of file diff --git a/mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/component.js b/mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/component.js new file mode 100644 index 0000000..d95bc08 --- /dev/null +++ b/mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/component.js @@ -0,0 +1,45 @@ +import Ember from 'ember'; + +const { + Component, + observer, + computed, + isEmpty, + isNone, + $ +} = Ember; + +export default Component.extend({ + url: null, + + onIsShowingModalChange: observer('isShowingModal', function(){ + if(this.get('isShowingModal')){ + this.set('url', null); + setTimeout(()=>{ + $('md-input-container input').focus(); + }, 500); + } + + }), + + saveDisabled: computed('url', function(){ + return isNone(this.get('url')) || isEmpty(this.get('url').trim()); + }), + + didInsertElement: function() { + $(document).keypress((event)=>{ + if(!this.get('saveDisabled') && event.which === 13) { + this.send('add'); + } + }); + }, + + actions: { + close () { + this.sendAction(); + }, + add (){ + this.sendAction('action', this.get('url')); + } + } +}); diff --git a/mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/template.hbs b/mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/template.hbs new file mode 100644 index 0000000..bb6a80c --- /dev/null +++ b/mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/template.hbs @@ -0,0 +1,13 @@ +{{#if isShowingModal}} + {{#modal-dialog close="close" alignment="center" translucentOverlay=true attachment="center" targetAttachment="center"}} + +

Enter a SoundCloud track or playlist/set URL

+

( ex. https://soundcloud.com/mrsuicidesheep/tracks )

+ + {{paper-input label="SoundCloud URL" icon="search" value=url}} + + {{paper-button onClick=(action "close") label="Close"}} + {{paper-button class="pull-right" onClick=(action "add") disabled=saveDisabled primary=true label="Add Music"}} + + {{/modal-dialog}} +{{/if}} \ No newline at end of file diff --git a/mobile/app/pods/components/music-tab/component.js b/mobile/app/pods/components/music-tab/component.js new file mode 100644 index 0000000..c4cf9ef --- /dev/null +++ b/mobile/app/pods/components/music-tab/component.js @@ -0,0 +1,890 @@ +import Ember from 'ember'; +import helperMixin from './mixins/helpers'; +import visualizerMixin from './mixins/visualizer'; + +const { + Component, + observer, + isEmpty, + isNone, + $, + run +} = Ember; + +export default Component.extend(helperMixin, visualizerMixin, { + onAmbienceModeChange: observer('ambienceMode', 'playing', function(){ + if(this.get('ambienceMode') && this.get('playing')) { + this.set('ambienceModeHandle', setInterval(()=> {this.doAmbienceLightChange();}, 5000)); + this.setProperties({ + 'colorloopMode': false, + 'flashingTransitions': false + }); + } else if(this.get('ambienceModeHandle')) { + this.get('activeLights').forEach((light)=>{ + $.ajax(this.get('apiURL') + '/lights/' + light + '/state', { + data: JSON.stringify({'on': true}), + contentType: 'application/json', + type: 'PUT' + }); + }); + + clearInterval(this.get('ambienceModeHandle')); + this.set('ambienceModeHandle', null); + } + }), + + updatePageTitle: observer('playQueuePointer', function(){ + let title = 'Huegasm', + playQueuePointer = this.get('playQueuePointer'), + playQueue = this.get('playQueue'); + + if(playQueuePointer !== -1){ + let song = playQueue[playQueuePointer]; + if(song.title){ + title = song.title; + + if(song.artist){ + title += (' - ' + song.artist); + } + } else { + title = song.fileName; + } + + title += '- Huegasm'; + } + + document.title = title; + }), + + changePlayerControl(name, value, saveBeatPrefs){ + this.set(name, value); + + if(name === 'threshold'){ + this.get('kick').set({threshold: value}); + } + + if(saveBeatPrefs && this.get('usingLocalAudio') && this.get('playQueuePointer') !== -1){ + this.saveSongBeatPreferences(); + } + + this.get('storage').set('huegasm.' + name, value); + }, + + saveSongBeatPreferences() { + let song = this.get('playQueue')[this.get('playQueuePointer')]; + if(song) { + let title = isEmpty(song.artist) ? song.fileName : song.artist + '-' + song.title, + songBeatPreferences = this.get('songBeatPreferences'); + + songBeatPreferences[title] = {threshold: this.get('threshold')}; + + this.set('usingBeatPreferences', true); + this.get('storage').set('huegasm.songBeatPreferences', songBeatPreferences); + } + }, + + loadSongBeatPreferences() { + let song = this.get('playQueue')[this.get('playQueuePointer')], + title = isEmpty(song.artist) ? song.fileName : song.artist + '-' + song.title, + songBeatPreferences = this.get('songBeatPreferences'), + preference = songBeatPreferences[title], + oldBeatPrefCache = this.get('oldBeatPrefCache'), + newOldBeatPrefCache = null; + + if(!isNone(preference)) { // load existing beat prefs + newOldBeatPrefCache = {threshold: this.get('threshold')}; + + this.changePlayerControl('threshold', preference.threshold); + this.set('usingBeatPreferences', true); + } else if(!isNone(oldBeatPrefCache)) { // revert to using beat prefs before the remembered song + this.changePlayerControl('threshold', oldBeatPrefCache.threshold); + this.set('usingBeatPreferences', false); + } + + this.set('oldBeatPrefCache', newOldBeatPrefCache); + }, + + doAmbienceLightChange(justOneLight){ + let activeLights = this.get('activeLights'), + lightsData = this.get('lightsData'), + workedLights = this.get('ambienceWorkedLights'), + hueRange = this.get('hueRange'), + ambienceWorkedLightsHandles = this.get('ambienceWorkedLightsHandles'), + lightOff = (light)=>{ + if(this.get('ambienceMode') && this.get('playing')){ + $.ajax(this.get('apiURL') + '/lights/' + light + '/state', { + data: JSON.stringify({'on': false, 'transitiontime': 20}), + contentType: 'application/json', + type: 'PUT' + }); + } + }, + lights = [], + transitionTime = Math.floor(Math.random()*20), + iterations = justOneLight ? 1 : activeLights.length/2; + + // pick some random lights + for(let i=0; i < iterations; i++){ + let l = activeLights[Math.floor(Math.random()*activeLights.length)]; + + if(!lights.includes(l) && !workedLights.includes(l)){ + lights.push(l); + workedLights.push(l); + } else if(justOneLight && workedLights.length !== activeLights.length){ // work a light if we only need one + while(workedLights.includes(l)){ + l = activeLights[Math.floor(Math.random()*activeLights.length)]; + } + + lights.push(l); + workedLights.push(l); + } + } + + lights.forEach((light)=>{ + let options = {'hue': Math.floor(Math.random()*(hueRange[1] - hueRange[0] + 1)+hueRange[0]), 'bri': Math.floor(Math.random()*200) + 1, 'transitiontime': transitionTime}; + + if(lightsData[light].state.on === false){ + options.on = true; + } + + $.ajax(this.get('apiURL') + '/lights/' + light + '/state', { + data: JSON.stringify(options), + contentType: 'application/json', + type: 'PUT' + }); + + // stop the light from turning off + if(ambienceWorkedLightsHandles[light]){ + clearTimeout(ambienceWorkedLightsHandles[light]); + delete ambienceWorkedLightsHandles[light]; + } + + // turn the light off after it's been idle for a while + ambienceWorkedLightsHandles[light] = setTimeout(()=>{ + lightOff(light); + workedLights.removeObject(light); + delete ambienceWorkedLightsHandles[light]; + }, transitionTime * 100 + 1000); + }); + }, + + startUsingMic() { + navigator.getUserMedia( + {audio: true}, + (stream) => { + this.changePlayerControl('audioMode', 1); + let dancer = this.get('dancer'); + + if(dancer.audio && dancer.audio.pause) { + dancer.pause(); + } + + this.setProperties({ + volumeCache: this.get('volume'), + playing: true, + audioStream: stream + }); + + document.title = 'Listening to Mic - Huegasm'; + + dancer.load(stream, this.get('micBoost'), true); + this.set('usingBeatPreferences', false); + + // much more sensitive beat preference settings are needed for mic mode + this.setProperties({ + oldThreshold: this.get('threshold'), + threshold: 0.1 + }); + + dancer.setVolume(0); + }, + (err) => { + if(err.name === 'DevicesNotFoundError'){ + this.get('notify').alert({html: this.get('notFoundHtml')}); + } + + console.log('Error during navigator.getUserMedia: ' + err.name + ', ' + err.message + ', ' + err.constraintName); + } + ); + }, + + clearCurrentAudio(resetPointer) { + let dancer = this.get('dancer'); + + if(dancer.audio.pause) { + dancer.pause(); + } + + if(resetPointer){ + this.set('playQueuePointer', -1); + } + + this.setProperties({ + timeElapsed: 0, + timeTotal: 0, + playing: false + }); + }, + + dragOver() { + let dragLeaveTimeoutHandle = this.get('dragLeaveTimeoutHandle'); + this.set('dragging', true); + + if (dragLeaveTimeoutHandle) { + clearTimeout(dragLeaveTimeoutHandle); + } + }, + + dragLeave(){ + // need to delay the dragLeave notification to avoid flickering ( hovering over some page elements causes this event to be sent ) + this.set('dragLeaveTimeoutHandle', setTimeout(()=>{ this.set('dragging', false); }, 500)); + }, + + simulateKick(/*mag, ratioKickMag*/) { + let activeLights = this.get('activeLights'), + lightsData = this.get('lightsData'), + color = null, + transitiontime = this.get('flashingTransitions'), + stimulateLight = (light, brightness, hue) => { + let options = {'bri': brightness}; + + if(transitiontime) { + options['transitiontime'] = 0; + } else { + options['transitiontime'] = 1; + } + + if(!isNone(hue)) { + options.hue = hue; + } + + if(lightsData[light].state.on === false){ + options.on = true; + } + + $.ajax(this.get('apiURL') + '/lights/' + light + '/state', { + data: JSON.stringify(options), + contentType: 'application/json', + type: 'PUT' + }); + }, + timeToBriOff = 100; + + if(activeLights.length > 0 && !this.get('ambienceMode')){ + let lastLightBopIndex = this.get('lastLightBopIndex'), + lightBopIndex, + brightnessOnBeat = 254, + light; + + lightBopIndex = Math.floor(Math.random() * activeLights.length); + + // let's try not to select the same light twice in a row + if(activeLights.length > 1) { + while(lightBopIndex === lastLightBopIndex) { + lightBopIndex = Math.floor(Math.random() * activeLights.length); + } + } + + light = activeLights[lightBopIndex]; + this.set('lastLightBopIndex', lightBopIndex); + + if(!this.get('colorloopMode')) { + let hueRange = this.get('hueRange'); + + color = Math.floor(Math.random()*(hueRange[1] - hueRange[0] + 1)+hueRange[0]); + } + + if(transitiontime){ + timeToBriOff = 80; + } + + stimulateLight(light, brightnessOnBeat, color); + setTimeout(stimulateLight, timeToBriOff, light, 1); + } + + this.set('paused', true); + setTimeout(() => { + this.set('paused', false); + }, 150); + + if(this.get('ambienceMode') && activeLights.length > 0){ + this.doAmbienceLightChange(true); + } + + //work the music beat area - simulate the speaker vibration by running a CSS animation on it + $('#beat-speaker-center-outer').velocity({blur: 3}, 100).velocity({blur: 0}, 100); + $('#beat-speaker-center-inner').velocity({scale: 1.05}, 100).velocity({scale: 1}, 100); + }, + + init() { + this._super(...arguments); + + window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame; + window.cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.msCancelAnimationFrame; + navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; + + let dancer = new Dancer(), + storage = this.get('storage'), + kick = dancer.createKick({ + threshold: this.get('threshold'), + onKick: (mag, ratioKickMag) => { + if (this.get('paused') === false) { + this.simulateKick(mag, ratioKickMag); + } + } + }); + + kick.on(); + + this.setProperties({ + dancer: dancer, + kick: kick + }); + + if(navigator.getUserMedia === undefined){ + this.set('usingMicSupported', false); + } + + ['volume', 'shuffle', 'repeat', 'volumeMuted', 'threshold', 'playerBottomDisplayed', 'audioMode', 'songBeatPreferences', 'firstVisit', 'currentVisName', 'playQueue', 'playQueuePointer', 'micBoost', 'flashingTransitions', 'colorloopMode', 'ambienceMode', 'hueRange'].forEach((item)=>{ + if (!isNone(storage.get('huegasm.' + item))) { + let itemVal = storage.get('huegasm.' + item); + + if(isNone(this.actions[item+'Changed'])){ + this.set(item, itemVal); + } else { + this.send(item + 'Changed', itemVal); + } + } + }); + + SC.initialize({ + client_id: this.get('SC_CLIENT_ID') + }); + }, + + didInsertElement() { + let self = this; + + // file input code + $('#file-input').on('change', function() { + let files = this.files; + self.send('handleNewFiles', files); + this.value = null; // reset in case upload the second file again + }); + + $(document).on('click', '.alert', (event)=>{ + $(event.target).addClass('removed'); + }); + + // prevent space/text selection when the user repeatedly clicks on the center + $('#beat-container').on('mousedown', '#beat-speaker-center-inner', function(event) { + event.preventDefault(); + }); + + $(document).keypress((event) => { + if(event.which === 32 && event.target.type !== 'text'){ + this.send('play'); + } + }); + + this.$().on('drop', '#play-list-area', (event)=>{ + this.send('dropFiles', event.dataTransfer.files); + }); + + // control the volume by scrolling up/down + $('#player-area').on('mousewheel', (event)=>{ + if(this.get('playQueueNotEmpty') && !this.get('usingMicAudio')) { + let scrollSize = 5; + + if(event.deltaY < 0) { + scrollSize *= -1; + } + let newVolume = this.get('volume') + scrollSize; + + this.send('volumeChanged', newVolume < 0 ? 0 : newVolume); + event.preventDefault(); + } + }); + + // demo tracks + if(this.get('firstVisit')){ + this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/candyland-speechless-feat-rkcb'); + this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/vallis-alps-young-feki-remix'); + this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/andrew-luce-when-to-love-you-feat-chelsea-cutler'); + this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/ahh-ooh-carefree-with-me'); + this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/crywolf-slow-burn'); + this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/clozee-red-forest'); + this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/elo-method-subranger-solace'); + this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/90-pounds-of-pete-waited-too-long-feat-devon-baldwin'); + this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/draper-eyes-open'); + + this.get('storage').set('huegasm.firstVisit', false); + + this.sendAction(); + } + + if(!this.get('playerBottomDisplayed')) { + $('#player-bottom').hide(); + } + }, + + actions: { + clearPlaylist(){ + this.get('playQueue').clear(); + }, + setVisName(name){ + this.set('currentVisName', name); + }, + hideTooltip(){ + $('.bootstrap-tooltip').tooltip('hide'); + }, + gotoSCURL(URL){ + // need to pause the music since soundcloud is going to start playing this song anyways + if(this.get('playing')){ + this.send('play'); + } + + this.send('gotoURL', URL); + }, + gotoURL(URL){ + $('.tooltip').remove(); + window.open(URL, '_blank'); + }, + handleNewSoundCloudURL(URL){ + if(URL) { + SC.resolve(URL).then((resultObj)=>{ + let processResult = (result)=>{ + if(result.kind === 'user'){ + this.get('notify').alert({html: this.get('scUserNotSupportedHtml')}); + } else if(result.kind === 'track') { + if(result.streamable === true){ + let picture = null; + + if(result.artwork_url){ + picture = result.artwork_url.replace('large', 't67x67'); + } else if(result.user.avatar_url){ + picture = result.user.avatar_url; + } + + $.get(picture) + .done(()=>{ + this.get('playQueue').pushObject({url: result.stream_url + '?client_id=' + this.get('SC_CLIENT_ID'), fileName: result.title + ' - ' + result.user.username, artist: result.user.username, scUrl: result.permalink_url, title: result.title, picture: picture }); + }).fail(()=>{ // no picture + this.get('playQueue').pushObject({url: result.stream_url + '?client_id=' + this.get('SC_CLIENT_ID'), fileName: result.title + ' - ' + result.user.username, artist: result.user.username, scUrl: result.permalink_url, title: result.title }); + }); + } else { + failedSongs.push(result.title); + } + } else if(result.kind === 'playlist'){ + if(result.streamable === true){ + result.tracks.forEach(processResult); + } else { + failedSongs.push(result.title); + } + } + }, + failedSongs = []; + + if(resultObj instanceof Array){ + resultObj.forEach(processResult); + } else { + processResult(resultObj); + } + + if(failedSongs.length > 0) { + this.get('notify').alert({html: this.get('notStreamableHtml')(failedSongs)}); + } + + if(this.get('playQueuePointer') === -1){ + if(this.get('firstVisit')){ + this.send('goToSong', 0); + } else { + this.send('next'); + } + } + }, () => { + this.get('notify').alert({html: this.get('urlNotFoundHtml')(URL)}); + }); + } + + this.set('isShowingAddSoundCloudModal', false); + }, + toggleIsShowingAddSoundCloudModal() { + this.toggleProperty('isShowingAddSoundCloudModal'); + }, + useLocalAudio(){ + let audioStream = this.get('audioStream'); + this.changePlayerControl('audioMode', 0); + + if(!isNone(audioStream)){ + let tracks = audioStream.getVideoTracks(); + if (tracks && tracks[0] && tracks[0].stop) { + tracks[0].stop(); + } + + if (audioStream.stop) { + // deprecated, may be removed in future + audioStream.stop(); + } + + this.setProperties({ + audioStream: null, + playing: false + }); + } + + if(this.get('playQueuePointer') !== -1) { + this.send('goToSong', this.get('playQueuePointer')); + this.send('volumeChanged', this.get('volume')); + } + + // restore the old beat preferences ( before the user went into mic mode ) + if(!isNone(this.get('oldThreshold'))){ + this.set('threshold', this.get('oldThreshold')); + } + + document.title = 'Huegasm'; + }, + useMicAudio() { + if(this.get('usingMicAudio')) { + this.send('useLocalAudio'); + } else { + this.startUsingMic(); + } + }, + slideTogglePlayerBottom(){ + let elem = this.$('#player-bottom'); + + elem.velocity(elem.is(':visible') ? 'slideUp' : 'slideDown', { duration: 300 }); + this.changePlayerControl('playerBottomDisplayed', !this.get('playerBottomDisplayed')); + }, + goToSong(index, playSong, scrollToSong){ + let dancer = this.get('dancer'), playQueue = this.get('playQueue'); + + if(dancer.audio) { + this.clearCurrentAudio(true); + } + + if(!isNone(playQueue[index])) { + let audio = new Audio(); + audio.src = this.get('playQueue')[index].url; + + audio.crossOrigin = "anonymous"; + audio.oncanplay = ()=>{ + this.set('timeTotal', Math.floor(audio.duration)); + this.set('soundCloudFuckUps', 0); + }; + audio.onerror = (event)=>{ + let playQueuePointer =this.get('playQueuePointer'), + song = this.get('playQueue')[playQueuePointer]; + + if(this.get('soundCloudFuckUps') >= this.get('maxSoundCloudFuckUps')) { + this.get('notify').alert({html: this.get('tooManySoundCloudFuckUps')}); + this.send('play'); + this.set('soundCloudFuckUps', 0); + } else { + if(song.local){ + this.send('removeAudio', playQueuePointer); + } else { + this.send('next', true); + } + + if(event.target.error.code === 2){ + this.get('notify').alert({html: this.get('failedToDecodeFileHtml')(song.fileName)}); + } else { + this.get('notify').alert({html: this.get('failedToPlayFileHtml')(song.fileName)}); + } + + this.set('usingBeatPreferences', false); + this.incrementProperty('soundCloudFuckUps'); + } + }; + audio.ontimeupdate = ()=>{ + this.set('timeElapsed', Math.floor(audio.currentTime)); + }; + audio.onended = ()=> { + this.send('next'); + }; + + dancer.load(audio, 1); + + this.set('playQueuePointer', index); + + this.loadSongBeatPreferences(); + + if(playSong){ + this.send('play'); + } + + if(scrollToSong){ + // this is just a bad workaround to make sure that the track has been rendered to the playlist + run.next(this, ()=>{ + $('.track'+index).velocity('scroll', { container: $('#play-list-area'), duration: 200 }); + }); + } + } + }, + removeAudio(index){ + this.get('playQueue').removeAt(index); + + // need to manually remove the tooltip + $('body .tooltip').remove(); + + if(index === this.get('playQueuePointer')) { + this.send('goToSong', index, true, true); + } + }, + playerAreaPlay(){ + if(isEmpty($('#player-controls:hover')) && this.get('playQueuePointer') !== -1 ){ + this.send('play'); + + $('#play-notification').velocity({opacity: 0.8, scale: 1}, 0).velocity({opacity: 0, scale: 3}, 500); + } + }, + play(replayPause) { + let dancer = this.get('dancer'), + playQueuePointer = this.get('playQueuePointer'); + + if(playQueuePointer !== -1 ) { + if (this.get('playing')) { + dancer.pause(); + + if(!replayPause){ + this.set('timeElapsed', Math.floor(dancer.getTime())); + } + } else { + let timeTotal = this.get('timeTotal'); + + if(this.get('volumeMuted')) { + dancer.setVolume(0); + } else { + dancer.setVolume(this.get('volume')/100); + } + + // replay song + if(this.get('timeElapsed') === timeTotal && timeTotal !== 0){ + this.send('next', true); + return; + } + + $(window).trigger('resize'); // workaround to redraw the canvas for the vitualizer + + dancer.play(); + } + + this.onColorloopModeChange(); + this.toggleProperty('playing'); + } + }, + volumeChanged(value) { + this.changePlayerControl('volume', value); + if(this.get('playing')) { + this.get('dancer').setVolume(value/100); + } + + if(this.get('volume') > 0 && this.get('volumeMuted')){ + this.changePlayerControl('volumeMuted', false); + } + }, + next(repeatAll) { + let playQueuePointer = this.get('playQueuePointer'), + playQueue = this.get('playQueue'), + nextSong = (playQueuePointer + 1), + repeat = this.get('repeat'), + shuffle = this.get('shuffle'); + + if(repeat === 2){ // repeating one song takes precedence over shuffling + if(playQueuePointer === -1 && playQueue.length > 0) { + nextSong = 0; + } else { + nextSong = playQueuePointer; + } + } else if(shuffle){ // next shuffle song + let shufflePlayed = this.get('shufflePlayed'); + + // played all the song in shuffle mode + if(shufflePlayed.length === playQueue.length){ + shufflePlayed.clear(); + this.send('play', true); + return; + } + + // we're going to assume that the song URL is the id + do { + nextSong = Math.floor(Math.random() * playQueue.length); + } while(shufflePlayed.includes(playQueue[nextSong].url)); + + shufflePlayed.pushObject(playQueue[nextSong].url); + } else if(nextSong > playQueue.length-1){ + if(repeat === 1 || repeatAll){ + nextSong = nextSong % playQueue.length; + } else { + this.send('play', true); + return; + } + } + + this.send('goToSong', nextSong, true, true); + }, + previous() { + if(this.get('timeElapsed') > 5) { + this.send('seekChanged', 0); + } else { + let nextSong = this.get('playQueuePointer'), + playQueue = this.get('playQueue'); + + if(this.get('shuffle') && !isNone(playQueue[nextSong])) { // go to the previously shuffled song + let shufflePlayed = this.get('shufflePlayed'), + shuffledSongIndx = this.get('shufflePlayed').indexOf(playQueue[nextSong].url), + i = 0; + + if(shufflePlayed.length > 0 && shuffledSongIndx !== -1){ // only if there was one + nextSong = shuffledSongIndx - 1; + + if(nextSong < 0){ + nextSong = shufflePlayed.length - 1; + } + + playQueue.some(function(item){ // try to find the previous song id + if(item.url === shufflePlayed[nextSong]){ + nextSong = i; + return true; + } + i++; + + return false; + }); + } + } else { + nextSong--; + + if(nextSong < 0) { + nextSong = playQueue.length - 1; + } + } + + this.send('goToSong', nextSong, true, true); + } + }, + seekChanged(position) { + let dancer = this.get('dancer'); + + if(dancer.audio){ + dancer.audio.currentTime = Math.floor(this.get('timeTotal') * position / 100); + } + }, + volumeMutedChanged(value) { + let dancer = this.get('dancer'), + volumeMuted = isNone(value) ? !this.get('volumeMuted') : value; + + this.changePlayerControl('volumeMuted', volumeMuted); + + if(this.get('playing')){ + if(volumeMuted){ + dancer.setVolume(0); + } else { + dancer.setVolume(this.get('volume')/100); + } + } + }, + addLocalAudio: function () { + $('#file-input').click(); + }, + shuffleChanged(value) { + this.changePlayerControl('shuffle', isNone(value) ? !this.get('shuffle') : value); + }, + repeatChanged(value) { + this.changePlayerControl('repeat', isNone(value) ? (this.get('repeat') + 1) % 3 : value); + }, + playerBottomDisplayedChanged(value) { + this.changePlayerControl('playerBottomDisplayed', value); + }, + thresholdChanged(value) { + this.changePlayerControl('threshold', value, true); + }, + hueRangeChanged(value) { + this.changePlayerControl('hueRange', value); + }, + micBoostChanged(value) { + this.set('micBoost', value); + this.get('storage').set('huegasm.micBoost', value); + + if(this.get('usingMicAudio')) { + this.get('dancer').setBoost(value); + } + }, + audioModeChanged(value){ + if(value === 1) { + this.startUsingMic(); + } else if(value === 0) { + this.send('useLocalAudio'); + } else { + this.set('audioMode', value); + } + }, + playQueuePointerChanged(value){ + this.send('goToSong', value, false, true); + }, + clickSpeaker(){ + this.simulateKick(1); + }, + dropFiles(files){ + this.setProperties({ + dragging: false, + draggingOverPlayListArea: false + }); + this.send('handleNewFiles', files); + }, + playerListAreaDragOver(){ + this.set('draggingOverPlayListArea', true); + }, + playerListAreaDragLeave(){ + this.set('draggingOverPlayListArea', false); + }, + handleNewFiles(files){ + let self = this, + playQueue = this.get('playQueue'), + updatePlayQueue = function(){ + let tags = ID3.getAllTags("local"), + picture = null; + + if(tags.picture){ + let base64String = ""; + for (let i = 0; i < tags.picture.data.length; i++) { + base64String += String.fromCharCode(tags.picture.data[i]); + } + + picture = "data:" + tags.picture.format + ";base64," + window.btoa(base64String); + } + + playQueue.pushObject({ + fileName: this.name.replace(/\.[^/.]+$/, ""), + url: URL.createObjectURL(this), + artist: tags.artist, + title: tags.title, + picture: picture, + local: true + }); + + ID3.clearAll(); + + if(self.get('playQueuePointer') === -1){ + self.send('next'); + } + }; + + for (let key in files) { + if (files.hasOwnProperty(key)) { + let file = files[key]; + + if(file.type.startsWith('audio')) { + ID3.loadTags("local", updatePlayQueue.bind(file),{ + dataReader: new FileAPIReader(file), + tags: ['title', 'artist', 'album', 'track', 'picture'] + }); + } + } + } + } + } +}); diff --git a/mobile/app/pods/components/music-tab/mixins/helpers.js b/mobile/app/pods/components/music-tab/mixins/helpers.js new file mode 100644 index 0000000..24baa45 --- /dev/null +++ b/mobile/app/pods/components/music-tab/mixins/helpers.js @@ -0,0 +1,422 @@ +import Ember from 'ember'; + +const { + Mixin, + observer, + computed, + isNone, + $, + inject, + on, + A +} = Ember; + +export default Mixin.create({ + classNames: ['col-sm-10', 'col-sm-offset-1', 'col-xs-12'], + classNameBindings: ['active::hidden'], + elementId: 'music-tab', + + dancer: null, + + notify: inject.service('notify'), + + beatOptions: { + threshold: { + range: {min: 0, max: 0.5}, + step: 0.01, + defaultValue: 0.3, + pips: { + mode: 'values', + values: [0, 0.25, 0.5], + density: 10, + format: { + to: function ( value ) { + if(value === 0) { + value = 'More'; + } else if(value === 0.25) { + value = ''; + } else { + value = 'Less'; + } + + return value; + }, + from: function ( value ) { return value; } + } + } + }, + hueRange: { + range: {min: 0, max: 65535}, + step: 1, + defaultValue: 0.3, + pips: { + mode: 'values', + values: [0, 25500, 46920, 65535], + density: 10, + format: { + to: function ( value ) { + if(value === 0 || value === 65535) { + value = 'Red'; + } else if(value === 25500 ) { + value = 'Green'; + } else { + value = 'Blue'; + } + + return value; + }, + from: function ( value ) { return value; } + } + } + }, + micBoost: { + range: {min: 1, max: 11}, + step: 0.5, + defaultValue: 5, + pips: { + mode: 'positions', + values: [0,20,40,60,80,100], + density: 10, + format: { + to: function ( value ) {return 'x'+value;}, + from: function ( value ) { return value; } + } + } + } + }, + + threshold: 0.3, + hueRange: [0, 65535], + micBoost: 5, + oldThreshold: null, + + playQueuePointer: -1, + playQueue: A(), + timeElapsed: 0, + timeTotal: 0, + lastLightBopIndex: 0, + usingMicSupported: false, + + // 0 - local, 1 - mic, possibly more to come + audioMode: 0, + usingLocalAudio: computed.equal('audioMode', 0), + usingMicAudio: computed.equal('audioMode', 1), + + playerBottomDisplayed: false, + dragging: false, + draggingOverPlayListArea: false, + dragLeaveTimeoutHandle: null, + ambienceModeHandle: null, + audioStream: null, + dimmerOn: false, + isShowingAddSoundCloudModal: false, + + colorloopMode: false, + ambienceMode: false, + flashingTransitions: false, + + // 0 - no repeat, 1 - repeat all, 2 - repeat one + repeat: 0, + shuffle: false, + volumeMuted: false, + volume: 100, + // beat detection related pausing + paused: false, + // audio: playing or paused + playing: false, + songBeatPreferences: {}, + usingBeatPreferences: false, + oldBeatPrefCache: null, + storage: null, + firstVisit: true, + ambienceWorkedLights: [], + ambienceWorkedLightsHandles: {}, + + soundCloudFuckUps: 0, + maxSoundCloudFuckUps: 3, + + // used to insure that we don't replay the same thing multiple times in shuffle mode + shufflePlayed: [], + + // noUiSlider connection specification + filledConnect: [true, false], + hueRangeConnect: [false, true, false], + + SC_CLIENT_ID: 'aeec0034f58ecd85c2bd1deaecc41594', + notFoundHtml: '', + scUserNotSupportedHtml: '', + tooManySoundCloudFuckUps: '', + notStreamableHtml(fileNames){ + let html = ''; + + return html; + }, + urlNotFoundHtml(url){ + return ''; + }, + failedToPlayFileHtml(fileName){ + return ''; + }, + failedToDecodeFileHtml(fileName){ + return ''; + }, + + scUrl: computed('playQueuePointer', 'playQueue.[]', 'usingMicAudio', function(){ + let rtn = null, + currentSong = this.get('playQueue')[this.get('playQueuePointer')]; + + if(currentSong && currentSong.scUrl && !this.get('usingMicAudio')){ + rtn = currentSong.scUrl; + } + + return rtn; + }), + + playQueueEmpty: computed.empty('playQueue'), + playQueueNotEmpty: computed.notEmpty('playQueue'), + playQueueMultiple: computed('playQueue.[]', function(){ + return this.get('playQueue').length > 1; + }), + + seekPosition: computed('timeElapsed', 'timeTotal', function(){ + let timeTotal = this.get('timeTotal'), + timeElapsed = this.get('timeElapsed'); + + if (timeTotal === 0) { + return 0; + } + + return timeElapsed/timeTotal*100; + }), + + largeArtworkPic: computed('playQueuePointer', 'usingMicAudio', 'currentVisName', function(){ + let pic = null, + currentVisName = this.get('currentVisName'), + usingMicAudio = this.get('usingMicAudio'), + playQueuePointer = this.get('playQueuePointer'), + playQueue = this.get('playQueue'); + + if(playQueuePointer !== -1 && !usingMicAudio && currentVisName === 'None'){ + let song = playQueue[playQueuePointer]; + if(song.scUrl && !isNone(song.picture)){ + pic = song.picture.replace('67x67', '500x500'); + } else { + pic = song.picture; + } + } + + return pic; + }), + + pauseLightUpdates: computed('playing', function(){ + return this.get('playing'); + }), + + micIcon: computed('usingMicAudio', function(){ + if(this.get('usingMicAudio')) { + return 'mic'; + } + + return 'mic-off'; + }), + + repeatIcon: computed('repeat', function() { + if(this.get('repeat') === 2) { + return 'repeat-one'; + } + + return 'repeat'; + }), + + playingIcon: computed('playing', function() { + if(this.get('playing')){ + return 'pause'; + } else if(this.get('timeElapsed') === this.get('timeTotal') && this.get('timeTotal') !== 0){ + return 'replay'; + } else { + return 'play-arrow'; + } + }), + + playListAreaClass: computed('dragging', 'draggingOverPlayListArea', 'dimmerOn', function(){ + let classes = 'pointer'; + + if(this.get('dragging')){ + classes += ' drag-here-highlight'; + } + + if(this.get('draggingOverPlayListArea')){ + classes += ' dragging-over'; + } + + if(this.get('dimmerOn')){ + classes += ' dimmerOn'; + } + + return classes; + }), + + dimmerOnClass: computed('dimmerOn', function(){ + return this.get('dimmerOn') ? 'dimmerOn' : null; + }), + + volumeMutedClass: computed('volumeMuted', function(){ + let classes = 'player-control-icon volumeButton'; + + if(this.get('volumeMuted')){ + classes += ' active'; + } + + return classes; + }), + + usingLocalAudioClass: computed('usingLocalAudio', function(){ + return this.get('usingLocalAudio') ? 'player-control-icon active' : 'player-control-icon'; + }), + + usingMicAudioClass: computed('usingMicAudio', function(){ + return this.get('usingMicAudio') ? 'player-control-icon active' : 'player-control-icon'; + }), + + repeatClass: computed('repeat', function(){ + return this.get('repeat') !== 0 ? 'player-control-icon active' : 'player-control-icon'; + }), + + shuffleClass: computed('shuffle', function(){ + return this.get('shuffle') ? 'player-control-icon active' : 'player-control-icon'; + }), + + volumeIcon: computed('volumeMuted', 'volume', function() { + let volume = this.get('volume'); + + if (this.get('volumeMuted')) { + return "volume-off"; + } else if (volume >= 70) { + return "volume-up"; + } else if (volume > 10) { + return "volume-down"; + } else { + return 'volume-mute'; + } + }), + + beatDetectionAreaArrowIcon: computed('playerBottomDisplayed', function(){ + if(!this.get('playerBottomDisplayed')){ + return 'keyboard-arrow-down'; + } else { + return 'keyboard-arrow-up'; + } + }), + + timeElapsedTxt: computed('timeElapsed', function(){ + return this.formatTime(this.get('timeElapsed')); + }), + + timeTotalTxt: computed('timeTotal', function() { + return this.formatTime(this.get('timeTotal')); + }), + + onColorloopModeChange: observer('colorloopMode', 'usingMicAudio', 'playing', function(){ + let colorLoop = ((this.get('playing') || this.get('usingMicAudio')) && this.get('colorloopMode')) ? true : false; + + this.set('colorLoopOn', colorLoop); + }), + + onOptionChange: observer('flashingTransitions', 'playQueue.[]', 'playQueuePointer', 'colorloopMode', 'ambienceMode', function(self, option){ + option = option.replace('.[]', ''); + this.get('storage').set('huegasm.' + option, this.get(option)); + }), + + onRepeatChange: on('init', observer('repeat', function () { + let tooltipTxt = 'Repeat all', type = 'repeat'; + + if (this.get(type) === 1) { + tooltipTxt = 'Repeat one'; + } else if (this.get(type) === 2) { + tooltipTxt = 'Repeat off'; + } + + this.changeTooltipText(type, tooltipTxt); + })), + + onUsingMicAudioChange: on('init', observer('usingMicAudio', function(){ + let tooltipTxt = 'Listen to audio through mic', type = 'usingMicAudio'; + + if (this.get(type)) { + tooltipTxt = 'Listen to audio files'; + } + + this.changeTooltipText(type, tooltipTxt); + })), + + onShuffleChange: on('init', observer('shuffle', function () { + let tooltipTxt = 'Shuffle', type = 'shuffle'; + + if (this.get(type)) { + this.get('shufflePlayed').clear(); + tooltipTxt = 'Unshuffle'; + } + + this.changeTooltipText(type, tooltipTxt); + })), + + onVolumeMutedChange: on('init', observer('volumeMuted', function() { + let tooltipTxt = 'Mute', type = 'volumeMuted', + volumeMuted = this.get(type), dancer = this.get('dancer'), + volume=0; + + if (volumeMuted) { + tooltipTxt = 'Unmute'; + volume = 0; + } else { + volume = this.get('volume')/100; + } + + if(this.get('playing')){ + dancer.setVolume(volume); + } + + this.changeTooltipText(type, tooltipTxt); + })), + + onPrevChange: on('init', observer('timeElapsed', 'playQueueNotEmpty', 'playQueue.[]', function() { + if(this.get('playQueueNotEmpty')){ + let tooltipTxt = 'Previous', type = 'prev'; + + if(this.get('timeElapsed') > 5 || this.get('playQueue').length === 1) { + tooltipTxt = 'Replay'; + } + + this.changeTooltipText(type, tooltipTxt); + } + })), + + onPlayingChange: on('init', observer('playing', function () { + let tooltipTxt = 'Play', type = 'playing'; + + if (this.get(type)) { + tooltipTxt = 'Pause'; + } else if(this.get('timeElapsed') === this.get('timeTotal') && this.get('timeTotal') !== 0){ + tooltipTxt = 'Replay'; + } + + this.changeTooltipText(type, tooltipTxt); + })), + + changeTooltipText(type, text) { + // change the tooltip text if it's already visible + $('#' + type + 'Tooltip + .tooltip .tooltip-inner').html(text); + //change the tooltip text for hover + $('#' + type + 'Tooltip').attr('data-original-title', text); + + if(isNone(this.get(type + 'TooltipTxt'))) { + this.set(type + 'TooltipTxt', text); + } + }, + + formatTime(time){ + return this.pad(Math.floor(time/60), 2) + ':' + this.pad(time%60, 2); + }, + + pad(num, size){ return ('000000000' + num).substr(-size); } +}); diff --git a/mobile/app/pods/components/music-tab/mixins/visualizer.js b/mobile/app/pods/components/music-tab/mixins/visualizer.js new file mode 100644 index 0000000..17dcfe2 --- /dev/null +++ b/mobile/app/pods/components/music-tab/mixins/visualizer.js @@ -0,0 +1,94 @@ +import Ember from 'ember'; + +const { + Mixin, + observer, + $ +} = Ember; + +export default Mixin.create({ + currentVisName: 'None', + + visNames: ['None', 'Bars', 'Wave'], + + onCurrentVisNameChange: observer('currentVisName', function () { + let currentVisName = this.get('currentVisName'); + + if(currentVisName === 'None'){ + let canvasEl = $('#visualization')[0], + ctx = canvasEl.getContext('2d'); + + ctx.clearRect(0, 0, canvasEl.width, canvasEl.height); + } + + this.get('storage').set('huegasm.currentVisName', currentVisName); + }), + + didInsertElement(){ + let dancer = this.get('dancer'), + canvas = $('#visualization')[0], + playerArea = $('#player-area'), + ctx = canvas.getContext('2d'), + spacing = 2, + h = playerArea.height(), w; + + canvas.height = h; + + // must be done to preserver resolution so that things don't appear blurry + // note that the height is set to 400px via css so it doesn't need to be recalculated + let syncCanvasHeight = ()=>{ + w = playerArea.width(); + canvas.width = w; + }; + + syncCanvasHeight(); + + $(window).on('resize', syncCanvasHeight); + + dancer.bind('update', () => { + let currentVisName = this.get('currentVisName'), + gradient = ctx.createLinearGradient(0, 0, 0, h), + pageHidden = document.hidden || document.msHidden || document.webkitHidden || document.mozHidden; + + // dont do anything if the page is hidden or no visualization + if(currentVisName === 'None' || pageHidden || !this.get('active')){ + return; + } + + ctx.clearRect(0, 0, w, h); + + if (currentVisName === 'Wave') { + let width = 3, + count = 1024; + + gradient.addColorStop(0.6, 'white'); + gradient.addColorStop(0, '#0036FA'); + + ctx.lineWidth = 1; + ctx.strokeStyle = gradient; + let waveform = dancer.getWaveform(); + + ctx.beginPath(); + ctx.moveTo(0, h / 2); + for (let i = 0, l = waveform.length; i < l && i < count; i++) { + ctx.lineTo(i * ( spacing + width ), ( h / 2 ) + waveform[i] * ( h / 2 )); + } + ctx.stroke(); + ctx.closePath(); + } else if (currentVisName === 'Bars') { + let width = 4, + count = 128; + + gradient.addColorStop(1, '#0f0'); + gradient.addColorStop(0.6, '#ff0'); + gradient.addColorStop(0.2, '#F12B24'); + + ctx.fillStyle = gradient; + let spectrum = dancer.getSpectrum(); + for (let i = 0, l = spectrum.length; i < l && i < count; i++) { + ctx.fillRect(i * ( spacing + width ), h, width, -spectrum[i] * h - 60); + } + } + }); + } +}); diff --git a/mobile/app/pods/components/music-tab/template.hbs b/mobile/app/pods/components/music-tab/template.hbs new file mode 100644 index 0000000..6cbc9fa --- /dev/null +++ b/mobile/app/pods/components/music-tab/template.hbs @@ -0,0 +1,212 @@ +
+
+ +
+
+ +
+ {{#if usingLocalAudio}} + {{range-slider start=seekPosition min=0 max=100 connect=filledConnect id="seek-slider" on-slide="seekChanged"}} + + {{#if playQueueNotEmpty}} + {{paper-icon "skip-previous" class="player-control-icon"}}{{/if}}{{paper-icon playingIcon class="player-control-icon"}}{{#if playQueueMultiple}}{{paper-icon "skip-next" action="" class="player-control-icon"}}{{/if}}{{paper-icon icon=volumeIcon class=volumeMutedClass}}{{range-slider start=volume min=0 max=100 connect=filledConnect on-slide="volumeChanged" id="volume-bar" class="hidden-xs"}} + +
{{timeElapsedTxt}} / {{timeTotalTxt}}
+ {{/if}} + + + {{#if scUrl}} + + + + + {{/if}} + + + + {{paper-icon "remove-red-eye" class="player-control-icon"}} + + + + + + +
+
+ +
+ + +
+ {{#if usingLocalAudio}} + + + + {{/if}} + + {{#if usingMicSupported}} + {{paper-icon icon=micIcon class=usingMicAudioClass}} + {{/if}} + + {{#if usingLocalAudio}} + {{paper-icon "shuffle" class=shuffleClass}} + {{paper-icon repeatIcon class=repeatClass}} + {{paper-icon "clear-all" class="player-control-icon"}} + {{/if}} +
+ +{{#if usingMicAudio}} +
+ {{paper-icon "mic" class=dimmerOnClass}} +
+{{else}} + {{#if usingLocalAudio}} +
+ {{#if (or playQueueEmpty dragging)}} +
+ {{#if dragging}} + Drag your music files here + {{else}} + Add your music files here + {{/if}} +
+ {{paper-icon "library-music" class=dimmerOnClass}} + {{/if}} + + {{#each playQueue as |item index|}} +
+ {{#if item.picture}} + + {{else}} + + {{/if}} + +
+ {{#if item.title}} +
{{item.title}}
+
+ {{#if item.artistUrl}} + {{item.artist}} + {{else}} + {{item.artist}} + {{/if}} +
+ {{else}} + {{item.fileName}} + {{/if}} +
+ + {{paper-icon "close" classNames="close"}} +
+ {{/each}} +
+ {{/if}} +{{/if}} +
+
+ +
+
+ {{paper-icon beatDetectionAreaArrowIcon id="beat-detection-area-arrow-icon"}} +
+
+ +
+
+ {{#if usingBeatPreferences}} + + {{paper-icon "star" class=dimmerOnClass}} + + {{/if}} + +
+
+ + Sensitivity + + + {{range-slider start=threshold orientation="vertical" step=beatOptions.threshold.step range=beatOptions.threshold.range on-slide="thresholdChanged" pips=beatOptions.threshold.pips}} +
+ +
+ + Hue Range + + + {{range-slider start=hueRange orientation="vertical" step=beatOptions.hueRange.step range=beatOptions.hueRange.range connect=hueRangeConnect on-slide="hueRangeChanged" pips=beatOptions.hueRange.pips}} +
+ + {{#if usingMicAudio}} +
+ + Mic Boost + + + {{range-slider start=micBoost orientation="vertical" step=beatOptions.micBoost.step range=beatOptions.micBoost.range on-slide="micBoostChanged" pips=beatOptions.micBoost.pips}} +
+ {{/if}} + +
+ + {{paper-checkbox value=flashingTransitions onChange=(action (mut flashingTransitions)) label="Flashing Transitions"}} + + + + {{paper-checkbox value=colorloopMode onChange=(action (mut colorloopMode)) label="Colorloop"}} + + + {{!-- + {{#paper-checkbox checked=ambienceMode}}Ambience{{/paper-checkbox}} + --}} +
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +{{ember-notify messageStyle='bootstrap' closeAfter=5000}} + +{{music-tab/add-soundcloud-sound-modal action="handleNewSoundCloudURL" isShowingModal=isShowingAddSoundCloudModal}} \ No newline at end of file diff --git a/mobile/app/resolver.js b/mobile/app/resolver.js new file mode 100644 index 0000000..2fb563d --- /dev/null +++ b/mobile/app/resolver.js @@ -0,0 +1,3 @@ +import Resolver from 'ember-resolver'; + +export default Resolver; diff --git a/mobile/app/router.js b/mobile/app/router.js new file mode 100644 index 0000000..cdc2578 --- /dev/null +++ b/mobile/app/router.js @@ -0,0 +1,12 @@ +import Ember from 'ember'; +import config from './config/environment'; + +const Router = Ember.Router.extend({ + location: config.locationType, + rootURL: config.rootURL +}); + +Router.map(function() { +}); + +export default Router; diff --git a/mobile/app/styles/app.scss b/mobile/app/styles/app.scss new file mode 100644 index 0000000..acb9c25 --- /dev/null +++ b/mobile/app/styles/app.scss @@ -0,0 +1,112 @@ +@import 'ember-modal-dialog/ember-modal-structure'; +@import 'ember-modal-dialog/ember-modal-appearance'; + +@import 'huegasm-variables'; + +@import 'bootstrap'; // used to take out bootstrap scss modules that we don't need +@import 'paper'; + +@import 'bridge-finder'; +@import 'common'; +@import 'dimmer'; +@import 'fancy-speaker'; +@import 'introjs'; +@import 'hue-controls'; +@import 'light-group'; +@import 'music-tab'; +@import 'noui-slider'; + +html { + min-height: 100%; + height: auto; +} + +body { + margin-bottom: $footerHeight; + position: static; +} + +body, button { + font-family: 'Slabo 27px', serif; +} + +.ember-app { + padding-bottom: 50px; +} + +#footer { + position: absolute; + left: 0; + bottom: 0; + width: 100%; + text-align: center; + height: $footerHeight; +} + +#footer-text { + display: inline-block; + position: relative; + bottom: 10px; + a { + margin-left: 5px; + } +} + +.alert { + margin-bottom: 0; + border: none; +} + + +.title { + margin-bottom: 20px; + img { + width: 200px; + } +} + +button.md-warn { + background: $secondaryThemeColor; +} + +div.ember-modal-dialog { + padding: 20px; + color: black; + md-input-container input { + color: black !important; + } + md-input-container label { + color: rgba(0, 0, 0, 0.26); + } +} + +.dropdown-menu { + font-size: 14px; + a { + line-height: 2 !important; + } + +} +// fancy webkit scrollbars +::-webkit-scrollbar { + -webkit-appearance: none; +} + +::-webkit-scrollbar:vertical { + width: 12px; +} + +::-webkit-scrollbar:horizontal { + height: 12px; +} + +::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, .5); + border-radius: 10px; + border: 2px solid #ffffff; + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); +} + +::-webkit-scrollbar-track { + background-color: #ffffff; +} diff --git a/mobile/app/styles/bootstrap.scss b/mobile/app/styles/bootstrap.scss new file mode 100644 index 0000000..6d071e4 --- /dev/null +++ b/mobile/app/styles/bootstrap.scss @@ -0,0 +1,56 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +// Core variables and mixins +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/variables"; +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/mixins"; + +// Reset and dependencies +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/normalize"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/print"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/glyphicons"; + +// Core CSS +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/scaffolding"; +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/type"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/code"; +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/grid"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/tables"; +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/forms"; +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/buttons"; + +// Components +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/component-animations"; +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/dropdowns"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/button-groups"; +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/input-groups"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/navs"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/navbar"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/breadcrumbs"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/pagination"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/pager"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/labels"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/badges"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/jumbotron"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/thumbnails"; +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/alerts"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/progress-bars"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/media"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/list-group"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/panels"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/responsive-embed"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/wells"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/close"; + +// Components w/ JavaScript +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/modals"; +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/tooltip"; +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/popovers"; +//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/carousel"; + +// Utility classes +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/utilities"; +@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/responsive-utilities"; diff --git a/mobile/app/styles/bridge-finder.scss b/mobile/app/styles/bridge-finder.scss new file mode 100644 index 0000000..c285ea8 --- /dev/null +++ b/mobile/app/styles/bridge-finder.scss @@ -0,0 +1,73 @@ +#press-bridge-button-img { + width: 200px; + margin: 0 auto 30px auto; + display: inherit; +} + +#bridge-button-group { + width: 150px; + margin: 30px auto; + text-align: left; +} + +#bridge-input md-input-container{ + max-width: 200px; + margin: 30px auto; +} + +#intro { + font-size: 22px; +} + +#intro-paragraph { + margin-bottom: 20px; + font-size: 16px; +} + +#bridge-finder, .ready-block { + text-align: center; + padding: 10px 15px 0; + font-size: 16px; +} + +#bridge-finder .md-bar { + background-color: $secondaryThemeColor !important; +} + +// preloading image +.ready-block:after { + display: none; + content: url(images/pressButtonBridge.png); +} + +.embed-container { + position:relative; + padding-bottom:56.25%; + padding-top:30px; + height:0; + overflow:hidden; +} + +.embed-container-wrapper { + max-width: 550px; + margin: auto; +} + +.embed-container iframe, .embed-container object, .embed-container embed { + position:absolute; + top:0; + left:0; + width:100%; + height:100%; +} + +.go-button { + margin: 20px 0; + border-radius: 100% !important; + width: 100px; + height: 100px; + font-size: 28px; + &:hover { + background: darken(#3f51b5, 10%) !important; + } +} diff --git a/mobile/app/styles/common.scss b/mobile/app/styles/common.scss new file mode 100644 index 0000000..db7ef0f --- /dev/null +++ b/mobile/app/styles/common.scss @@ -0,0 +1,15 @@ +.text-left { + text-align: left !important; +} + +.relative { + position: relative !important; +} + +.no-text-decoration { + text-decoration: none !important; +} + +.pointer { + cursor: pointer; +} \ No newline at end of file diff --git a/mobile/app/styles/dimmer.scss b/mobile/app/styles/dimmer.scss new file mode 100644 index 0000000..119e4d1 --- /dev/null +++ b/mobile/app/styles/dimmer.scss @@ -0,0 +1,86 @@ +div.dimmerOn { + color: $whitish !important; + background: $blackish !important; +} + +html.dimmerOn { + color: white; + background: $blackish; +} + +body.dimmerOn { + color: $whitish; + background: $blackish; + md-input-container { + label { + color: #3f51b5 !important; + } + .md-input { + color: $whitish !important; + border-color: #3f51b5 !important; + } + } + .md-track { + background: $whitish; + } + .color { + border: 1px solid white; + } + .playlist-item, .dropdown-menu, .add-new-music { + color: $whitish; + background-color: $dimmerOnButtonColor; + } + .dropdown-menu { + a { + color: $whitish; + &:hover { + background-color: darken($dimmerOnButtonColor, 10%) !important; + } + } + } + .playlist-item { + &.active { + background: darken($dimmerOnButtonColor, 15%) !important; + } + &:hover { + background: darken($dimmerOnButtonColor, 10%); + } + .audio-remove-button .paper-icon { + color: $whitish !important; + &:hover { + color: white !important; + } + } + } + svg { + -webkit-filter: drop-shadow(0 0 5px #228DFF); + } + .md-container { + color: $whitish; + } + .add-new-music:hover { + background: darken($dimmerOnButtonColor, 5%); + } + .popover-content { + color: black !important; + } + .md-bar { + background-color: darken(white, 60%) !important; + } +} + + +.paper-icon.dimmerOn { + color: inherit !important; + text-shadow: $glowingText; + opacity: 0.9 !important; +} + +#dimmer { + display: inline-block; + cursor: pointer; + width: 40px; + height: 40px; + background: url(/favicon-96x96.png) center center no-repeat; + background-size: 40px 40px; +} diff --git a/mobile/app/styles/fancy-speaker.scss b/mobile/app/styles/fancy-speaker.scss new file mode 100644 index 0000000..8c4ccb3 --- /dev/null +++ b/mobile/app/styles/fancy-speaker.scss @@ -0,0 +1,102 @@ +/* Variables */ +$centersize: 80px; +$center1size: 205px; +$bezelsize: 240px; + +/* Extenders */ +%base { + border-radius: 100%; +} +%rivet { + position: absolute; + height: 8px; + width: 8px; + background-color: #555; + border-radius: 100%; + box-shadow: inset 0 0 3px #000, 0 0 2px #000; +} + +#beat-speaker-center-inner { + @extend %base; + height: $centersize; + width: $centersize; + position: absolute; + bottom: 47px; + right: 47px; + -webkit-filter: blur(1px); + filter: blur(1px); + background: rgb(0,0,0); + background: -moz-radial-gradient(center, ellipse cover, rgba(0,0,0,1) 0%, rgba(79,79,79,1) 0%, rgba(0,0,0,1) 100%); + background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(0,0,0,1)), color-stop(0%,rgba(79,79,79,1)), color-stop(100%,rgba(0,0,0,1))); + background: -webkit-radial-gradient(center, ellipse cover, rgba(0,0,0,1) 0%,rgba(79,79,79,1) 0%,rgba(0,0,0,1) 100%); + background: -o-radial-gradient(center, ellipse cover, rgba(0,0,0,1) 0%,rgba(79,79,79,1) 0%,rgba(0,0,0,1) 100%); + background: -ms-radial-gradient(center, ellipse cover, rgba(0,0,0,1) 0%,rgba(79,79,79,1) 0%,rgba(0,0,0,1) 100%); + background: radial-gradient(ellipse at center, rgba(0,0,0,1) 0%,rgba(79,79,79,1) 0%,rgba(0,0,0,1) 100%); + box-shadow: 0 0 10px rgba(0, 0, 0, 1); +} +#beat-speaker-center-outer { + @extend %base; + position: absolute; + top: 16px; + left: 16px; + height: $center1size; + width: $center1size; + border: 15px solid #333; + box-shadow: -3px -3px 15px rgba(0, 0, 0, 0.4), inset -3px -3px 15px rgba(0, 0, 0, 0.5); + background: -moz-linear-gradient(130deg, rgba(117, 117, 117, 1) 55%, rgba(220, 220, 220, 1) 100%); + background: -webkit-linear-gradient(130deg, rgba(117, 117, 117, 1) 55%, rgba(220, 220, 220, 1) 100%); + background: -o-linear-gradient(130deg, rgba(117, 117, 117, 1) 55%, rgba(220, 220, 220, 1) 100%); + background: -ms-linear-gradient(130deg, rgba(117, 117, 117, 1) 55%, rgba(220, 220, 220, 1) 100%); + background: linear-gradient(130deg, rgba(117, 117, 117, 1) 55%, rgba(220, 220, 220, 1) 100%); +} +.bezel { + @extend %base; + margin: 0 auto; + height: $bezelsize; + width: $bezelsize; + position: relative; + background-color: #A8A8A8; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.8), inset 3px 3px 10px rgba(0, 0, 0, 0.8), 0 0 2px rgba(0, 0, 0, 0.8), inset 0 0 30px -5px rgba(0, 0, 0, 0.8); + top: 50%; + transform: translateY(-50%); +} +.rivet1 { + @extend %rivet; + top: 6px; + left: 50%; +} +.rivet2 { + @extend %rivet; + bottom: 6px; + left: 50%; +} +.rivet3 { + @extend %rivet; + top: 50%; + left: 6px; +} +.rivet4 { + @extend %rivet; + top: 50%; + right: 6px; +} +.rivet5 { + @extend %rivet; + top: 18%; + left: 13.7%; +} +.rivet6 { + @extend %rivet; + top: 18%; + right: 13.5%; +} +.rivet7 { + @extend %rivet; + bottom: 17%; + left: 13.5%; +} +.rivet8 { + @extend %rivet; + bottom: 17%; + right: 13.5%; +} diff --git a/mobile/app/styles/hue-controls.scss b/mobile/app/styles/hue-controls.scss new file mode 100644 index 0000000..8198213 --- /dev/null +++ b/mobile/app/styles/hue-controls.scss @@ -0,0 +1,115 @@ +#lights-tab { + min-height: 350px; + .paper-icon { + line-height: 0.8 !important; + } +} + +.lights-control-tooltip + .tooltip { + left: 0 !important; +} + +#color-row { + cursor: pointer; +} + +#hue-controls { + max-width: 1200px; + position: relative; +} + +// preload images +#hue-controls:after, md-progress-circular:after { + display: none; + content: url(images/colormap.png) url(images/missingArtwork.png) url(images/sc-white.png) url(/favicon-96x96.png) url(images/lights/a19.svg) url(images/lights/a19w.svg) url(images/lights/br30.svg) url(images/lights/br30w.svg) url(images/lights/gu10.svg) url(images/lights/gu10w.svg) url(images/lights/huego.svg) url(images/lights/huegow.svg) url(images/lights/lc_aura.svg) url(images/lights/lc_auraw.svg) url(images/lights/lc_bloom.svg) url(images/lights/lc_bloomw.svg) url(images/lights/lc_iris.svg) url(images/lights/lc_irisw.svg) url(images/lights/lightstrip.svg) url(images/lights/lightstripw.svg) url(images/lights/storylight.svg) url(images/lights/storylightw.svg); +} + +#navigation { + padding: 15px 0; + text-align: center; +} + +.navigation-item { + font-size: 18px; + padding: 0 10px 0 10px; + &.active { + font-weight: bold; + cursor: default; + text-decoration: none !important; + } + &:hover { + text-decoration: underline; + } +} + +.color { + border: 1px solid rgba(0, 0, 0, 0.5); + position: absolute; + top: -53px; + right: 0; +} + +#color-picker { + padding: 5px; + background: rgba(0, 0, 0, 0.7); + box-shadow: 5px 10px 15px 5px rgba(0, 0, 0, 0.3); + color: #FFFFFF; + position: absolute; + width: 266px; + height: 266px; + right: 6px; + top: -9px; + z-index: 3; +} + +#picker { + cursor: crosshair; +} + +#loop-addition { + position: absolute; + left: 35px; + top: 15px; + font-size: 16px; +} + +#settings { + z-index: 3; + text-align: right; + cursor: pointer; + float: right; + position: relative; +} + +#settings-menu { + position: absolute; + box-shadow: 1px 10px 15px 1px rgba(0, 0, 0, 0.3); + left: -135px; + top: 25px; + border: none; + padding: 0; +} + +#settings-icon { + transition: 0.1s all ease-in-out; + &:hover { + -webkit-transform: scale(1.1); + transform: scale(1.1); + } + &:before { + transition: 0.1s all ease-in-out; + } +} + +@media(min-width:767px) { + #lights-tab { + font-size: 20px; + min-height: 450px; + .paper-icon { + font-size: 24px; + } + .md-list-item-inner { + height: 75px; + } + } +} diff --git a/mobile/app/styles/huegasm-variables.scss b/mobile/app/styles/huegasm-variables.scss new file mode 100644 index 0000000..aec128d --- /dev/null +++ b/mobile/app/styles/huegasm-variables.scss @@ -0,0 +1,10 @@ +$playerHeight: 400px; +$playerDefaultIconColor: #BBBBBB; +$footerHeight: 50px; +$playerBottomHeight: 255px; +$secondaryThemeColor: #F12B24; +$glowingText: 0 0 2px #fff, 0 0 4px #fff, 0 0 20px #228DFF; +$dimmerOnButtonColor: #404040; +$blackish: #242424; +$whitish: #e0e0e0; +$paperThemeColor: #3f51b5; diff --git a/mobile/app/styles/introjs.scss b/mobile/app/styles/introjs.scss new file mode 100644 index 0000000..6578692 --- /dev/null +++ b/mobile/app/styles/introjs.scss @@ -0,0 +1,22 @@ +.introjs-overlay { + background: black; +} + +#settings.introjs-fixParent { + position: inherit !important; +} + +.introjs-tooltip { + color: black; +} + +.introjs-skipbutton { + color: $secondaryThemeColor; +} + +.introjs-bullets ul li a.active { + position: relative; + height: 10px; + width: 10px; + top: -2px; +} diff --git a/mobile/app/styles/light-group.scss b/mobile/app/styles/light-group.scss new file mode 100644 index 0000000..f9b1256 --- /dev/null +++ b/mobile/app/styles/light-group.scss @@ -0,0 +1,59 @@ +.light-group { + margin: 0 auto; + text-align: center; + .tooltip.top { + margin-top: 4px; + margin-left: 0; + } + div { + display: inline-block; + } +} + +.light-inactive { + cursor: pointer; + position: relative; +} + +.light-inactive::before { + font-weight: bold; + position: absolute; + content: "X"; + top: -10px; + left: 5px; + font-size: 40px; + color: rgba(255, 0, 0, 0.37); + font-family: cursive; +} + +.horizontal-light-group { + .light-inactive::before { + top: -9px; + left: 6px; + } + .tooltip.top { + margin-top: 1px; + margin-left: 2px; + } +} + +.light-active { + cursor: pointer; + img { + transition-duration: 0.3s; + transition-property: transform; + box-shadow: 0 0 1px rgba(0, 0, 0, 0); + } + img:hover { + -webkit-transform: scale(1.2); + transform: scale(1.2); + } +} + +.ember-modal-overlay.translucent { + background-color: rgba(0, 0, 0, 0.50); +} + +.remove-button { + margin: 10px 0 10px 60px; +} diff --git a/mobile/app/styles/music-tab.scss b/mobile/app/styles/music-tab.scss new file mode 100644 index 0000000..754d7d0 --- /dev/null +++ b/mobile/app/styles/music-tab.scss @@ -0,0 +1,403 @@ +.row { + margin: 0; +} + +#beat-option-row { + height: 250px; +} + +#light-option { + text-align: left !important; + top: 20%; + -webkit-transform: translateY(-20%); + transform: translateY(-20%); + .tooltip { + margin-top: 5px !important; + } +} + +#music-tab { + padding: 0; + margin: 10px 0 $footerHeight + 20px; +} + +#slide-toggle { + color: $playerDefaultIconColor; + background: #730B07; + div .paper-icon { + color: inherit !important; + } +} + +#slide-toggle:hover{ + color: lighten($playerDefaultIconColor, 30%) !important;; +} + +#player-controls { + transition: all 0.2s ease-in-out; + position: absolute; + bottom: 0; + left: 0; + padding: 5px 10px; + width: 100%; + color: white !important; + z-index: 20; + background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 1)); + .tooltip.top { + margin-top: -17px; + } + .tooltip-arrow { + display: none; + } + .play-arrow, .pause, .replay { + font-size: 30px; + } +} + +#player-time-controls { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + display: inline-block; + margin-left: 1em; +} + +.player-control-icon { + color: $playerDefaultIconColor !important; + transition-duration: 0.1s; + margin-right: 5px; +} + +.player-control-icon.active { + color: $secondaryThemeColor !important; +} + +.player-control-icon:hover { + color: white !important; +} + +#play-notification { + position: relative; + color: white; + top: 50%; + left: 50%; + opacity: 0; + background: black; + border-radius: 100%; +} + +#player-area { + height: $playerHeight; + background-color: black; + display: inline-block; + padding: 0; +} + +#playlist { + height: $playerHeight; + background-color: #1E1E1E; + padding: 0 5px 0 5px; +} + +#player-area * .noUi-origin { + background-color: black; + border-radius: 5px; +} + +#player-area * .noUi-base { + background-color: black; + border-radius: 5px; +} + +#volume-bar { + width: 5em; + height: 0.4em; + display: inline-block; +} + +#player-area * .noUi-handle::after, #player-area * .noUi-handle::before { + content: none; +} + +#seek-slider { + height: 6px; + margin-bottom: 10px; + transition-duration: 0.2s; +} + +#seek-slider:hover { + height: 8px; +} + +#seek-slider:hover * .noUi-handle { + opacity: 1; +} + +#seek-slider * .noUi-handle { + border: none; + height: 13px; + width: 13px; + border-radius: 50%; + top: -4px; + left: -6px; + opacity: 0; + transition-duration: 0.1s; + background-color: $secondaryThemeColor !important; + box-shadow: none; +} + +#play-list-controls { + min-height: 30px; + margin-top: 5px; + border-bottom: 1px solid #3a3a3a; + position: relative; +} + +#play-list-area, #play-area-mic { + background-color: white; + width: 100%; + height: 350px; + margin: 10px auto 0 auto; + border-radius: 5px; + transition: 0.1s all ease-in-out; + position: relative; + overflow: auto; + #dragHere { + position: absolute; + top: 27%; + font-size: 20px; + text-align: center; + width: 100%; + } + .library-music, .mic { + position: absolute; + top: 40%; + font-size: 100px; + opacity: 0.5; + width: 100%; + text-align: center; + } +} + +.song-artist { + font-weight: bold; +} + +#play-list-area.drag-here-highlight { + background-color: white; + border: 5px dotted #5383ff; +} + +#play-list-area.dragging-over { + background-color: darken(white, 5%); + box-shadow: inset 0 0 20px 0 rgba(0, 0, 0, 1); +} + +#file-input { + width: 1px; + height: 1px; + visibility: hidden; +} + +.playlist-item { + border-bottom: 1px solid rgba(128, 128, 128, 0.3); + border-top: 1px solid rgba(128,128,128,0.3); + height: 62px; + font-family: 'Open Sans', sans-serif; + padding: 0 20px 0 5px; + position: relative; + color: black; + background: darken(white, 5%); + .close { + font-size: 18px; + } + .album-art { + height: 60px; + float: left; + margin-right: 5px; + border: 1px solid rgba(0, 0, 0, 0.5); + } + .song-info { + .song-title { + max-height: 40px; + overflow: hidden; + } + .song-artist { + max-height: 20px; + overflow: hidden; + } + } + .audio-remove-button { + position: absolute; + top: 20px; + right: 5px; + } +} + +.playlist-item.active { + background: darken(white, 15%) !important; + border-top: 1px solid $secondaryThemeColor; + border-bottom: 1px solid $secondaryThemeColor; +} + +.playlist-item:hover { + background: darken(white, 10%); + .close { + display: block; + } +} + +#beat-area { + height: $playerBottomHeight; + position: relative; + padding: 0; + margin-bottom: 10px; +} + +.star { + cursor: auto !important; +} + +#beat-option-button-group { + margin: 20px 0 10px 0; +} + +.beat-option { + padding: 5px 0; + text-align: center; + md-switch { + margin: 0; + } + .option-description { + font-size: 16px; + } + button { + margin-top: 0; + } + .tooltip { + margin: 0; + } +} + +#player-bottom { + color: black; + border: 1px solid black; + width: 100%; + background: white; +} + +#beat-container { + padding: 0; + height: $playerBottomHeight; +} + +#beat-area .light-group { + margin: 10px 20px 0 40px; + float: right; + div { + display: block; + padding: 10px; + } +} + +#add-music-choices { + min-width: initial; + right: 0; + left: initial; + width: 100px; + top: 25px; +} + +.add-new-music { + padding: 0 5px 0 10px; + font-size: 16px; + border-radius: 5px; + background: #f8f8f8; + border: none; +} + +.add-new-music:hover { + background: darken(#f8f8f8, 5%); +} + +.sound-cloud-link { + margin-right: 5px; +} + +#visualization { + position: absolute; + top: 0; + left: 0; +} + +#save-beat-preferences-star { + position: absolute; + top: 3px; + z-index: 1000; + md-icon { + color: $secondaryThemeColor !important; + font-size: 25px; + } +} + +.visualizers-menu { + left: -135px; +} + +.display-icon { + background: url(/favicon-96x96.png) center center no-repeat; + background-size: 80px 80px; +} + +#artwork { + position: absolute; + width: 100%; + overflow: hidden; + img { + display: block; + margin: 0 auto; + max-height: 400px; + } +} + +.keyboard-arrow-down { + font-size: 20px; +} + +.visualizers-menu .paper-icon { + margin-left: 10px; + position: relative; + top: -4px; +} + +.close { + font-size: 18px !important; + color: rgb(51, 51, 51); + display: none; + opacity: 1; + text-shadow: none; + &:hover { + color: darken(#333333, 5%) !important; + opacity: 1 + } +} + +.ember-notify-default.ember-notify-cn { + top: 0; + bottom: initial; +} + +// mobile overrides +@media(max-width:767px) { + #seek-slider { + height: 8px; + .noUi-handle { + opacity: 1 !important; + } + } + #seek-slider { + margin-bottom: 15px; + } + .beat-option { + text-align: center !important; + } +} diff --git a/mobile/app/styles/noui-slider.scss b/mobile/app/styles/noui-slider.scss new file mode 100644 index 0000000..06c756b --- /dev/null +++ b/mobile/app/styles/noui-slider.scss @@ -0,0 +1,56 @@ +.noUi-value-vertical { + margin-top: -10px; + transform: none; +} + +.noUi-value-vertical, .noUi-pips { + color: inherit !important; +} + +.noUi-vertical .noUi-handle { + border: 1px solid #A3A0A0; + width: 26px; +} + +.noUi-vertical .noUi-handle:after, .noUi-vertical .noUi-handle:before{ + background: grey; +} + +.noUi-base { + cursor: pointer; +} + +.noUi-connect { + background-color: $secondaryThemeColor; +} + +.noUi-handle { + cursor: pointer; +} + +.noUi-horizontal .noUi-handle { + width: 0.4em; + height: 1.3em; + left: -0.071em; + top: -0.550em; + transition-duration: 0.1s; + background: $playerDefaultIconColor !important; +} + +.noUi-horizontal .noUi-handle:hover { + background: white !important; +} + +.noUi-target { + margin: 0 auto; +} + +.noUi-base { + background-color: #ADADAD; + border: 1px solid #797979; +} + +.noUi-vertical { + height: 200px; + margin: 15px auto 10px; +} diff --git a/mobile/app/styles/paper.scss b/mobile/app/styles/paper.scss new file mode 100644 index 0000000..ac9f217 --- /dev/null +++ b/mobile/app/styles/paper.scss @@ -0,0 +1,62 @@ +@import 'ember-paper'; + +.paper-icon { + cursor: pointer; +} + +md-checkbox .md-icon, .md-off, .md-on { + border-color: inherit !important; +} + +md-checkbox.md-default-theme.md-checked .md-icon { + background: $secondaryThemeColor; +} + +md-checkbox .md-label { + width: 125px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.md-button { + flex-direction: unset; + span { + width: 100%; + } +} + +md-switch[disabled=disabled], md-switch[disabled=disabled] .md-container, md-slider[disabled=disabled] { + cursor: not-allowed; +} + +md-progress-circular { + margin: 0 auto 20px auto !important; +} + +md-progress-linear { + margin-bottom: 50px !important; +} + +md-slider { + cursor: pointer; +} + +md-slider.md-default-theme .md-thumb:after { + border-color: $secondaryThemeColor; + background-color: $secondaryThemeColor; +} + +md-icon { + color: rgba(0, 0, 0, 0.54) !important; +} + +md-switch.md-default-theme.md-checked .md-thumb { + background-color: $secondaryThemeColor; +} + +@media(max-width:500px) { + md-checkbox .md-label { + width: 100px; + } +} diff --git a/mobile/app/templates/application.hbs b/mobile/app/templates/application.hbs new file mode 100644 index 0000000..d53e9c5 --- /dev/null +++ b/mobile/app/templates/application.hbs @@ -0,0 +1 @@ +{{huegasm-app}} \ No newline at end of file diff --git a/mobile/bower.json b/mobile/bower.json new file mode 100644 index 0000000..205cf86 --- /dev/null +++ b/mobile/bower.json @@ -0,0 +1,19 @@ +{ + "name": "huegasm", + "dependencies": { + "HackTimer": "https://github.com/turuslan/HackTimer.git#~1.0.0", + "JavaScript-ID3-Reader": "https://github.com/aadsm/JavaScript-ID3-Reader.git", + "bootstrap-sass": "^3.3.5", + "ember": "beta", + "ember-cli-shims": "^0.1.0", + "ember-load-initializers": "0.5.1", + "ember-qunit-notifications": "0.1.0", + "hammer.js": "^2.0.8", + "intro.js": "^2.1.0", + "jquery-mousewheel": "^3.1.13", + "locallyjs": "^0.3.2", + "matchMedia": "^0.3.0", + "nouislider": "^9.0.0", + "velocity": "^1.3.1" + } +} diff --git a/mobile/config/environment.js b/mobile/config/environment.js new file mode 100644 index 0000000..941cd60 --- /dev/null +++ b/mobile/config/environment.js @@ -0,0 +1,49 @@ +/* jshint node: true */ + +module.exports = function(environment) { + var ENV = { + modulePrefix: 'huegasm', + podModulePrefix: 'huegasm/pods', + environment: environment, + rootURL: '/', + locationType: 'hash', + ignoreFailures: false, + EmberENV: { + FEATURES: { + // Here you can enable experimental features on an ember canary build + // e.g. 'with-controller': true + } + }, + + APP: { + // Here you can pass flags/options to your application instance + // when it is created + } + }; + + if (environment === 'development') { + ENV.ignoreFailures = true; + // ENV.APP.LOG_RESOLVER = true; + // ENV.APP.LOG_ACTIVE_GENERATION = true; + // ENV.APP.LOG_TRANSITIONS = true; + // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; + // ENV.APP.LOG_VIEW_LOOKUPS = true; + } + + if (environment === 'test') { + // Testem prefers this... + ENV.locationType = 'none'; + + // keep test console output quieter + ENV.APP.LOG_ACTIVE_GENERATION = false; + ENV.APP.LOG_VIEW_LOOKUPS = false; + + ENV.APP.rootElement = '#ember-testing'; + } + + if (environment === 'production') { + + } + + return ENV; +}; diff --git a/mobile/ember-cli-build.js b/mobile/ember-cli-build.js new file mode 100644 index 0000000..18c3ef2 --- /dev/null +++ b/mobile/ember-cli-build.js @@ -0,0 +1,21 @@ +/* global require, module */ +var EmberApp = require('ember-cli/lib/broccoli/ember-app'); + +module.exports = function(defaults) { + var app = new EmberApp(defaults); + + app.import('vendor/dancer.js'); + + app.import('bower_components/bootstrap-sass/assets/javascripts/bootstrap/tooltip.js'); + app.import('bower_components/bootstrap-sass/assets/javascripts/bootstrap/dropdown.js'); + app.import('bower_components/bootstrap-sass/assets/javascripts/bootstrap/popover.js'); + app.import('bower_components/HackTimer/HackTimer.js'); + app.import('bower_components/intro.js/intro.js'); + app.import('bower_components/intro.js/introjs.css'); + app.import('bower_components/JavaScript-ID3-Reader/dist/id3-minimized.js'); + app.import('bower_components/jquery-mousewheel/jquery.mousewheel.js'); + app.import('bower_components/locallyjs/dist/locally.min.js'); + app.import('bower_components/velocity/velocity.js'); + + return app.toTree(); +}; diff --git a/mobile/ember-cordova/cordova/config.xml b/mobile/ember-cordova/cordova/config.xml new file mode 100644 index 0000000..45e53ad --- /dev/null +++ b/mobile/ember-cordova/cordova/config.xml @@ -0,0 +1,26 @@ + + + huegasm_mobile + + A sample Apache Cordova application that responds to the deviceready event. + + + Apache Cordova Team + + + + + + + + + + + + + + + + + + diff --git a/mobile/ember-cordova/cordova/hooks/README.md b/mobile/ember-cordova/cordova/hooks/README.md new file mode 100644 index 0000000..574ad4c --- /dev/null +++ b/mobile/ember-cordova/cordova/hooks/README.md @@ -0,0 +1,23 @@ + +# Cordova Hooks + +Cordova Hooks represent special scripts which could be added by application and plugin developers or even by your own build system to customize cordova commands. See Hooks Guide for more details: http://cordova.apache.org/docs/en/edge/guide_appdev_hooks_index.md.html#Hooks%20Guide. diff --git a/mobile/ember-cordova/cordova/platforms/.gitkeep b/mobile/ember-cordova/cordova/platforms/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/mobile/ember-cordova/cordova/plugins/.gitkeep b/mobile/ember-cordova/cordova/plugins/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/mobile/ember-cordova/cordova/www/.gitkeep b/mobile/ember-cordova/cordova/www/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/mobile/package.json b/mobile/package.json new file mode 100644 index 0000000..8402460 --- /dev/null +++ b/mobile/package.json @@ -0,0 +1,47 @@ +{ + "name": "huegasm_mobile", + "version": "1.0.0", + "description": "Huegasm is a free web application for managing and synchronizing your Philips Hue lights with the beat of your music.", + "private": true, + "directories": { + "doc": "doc", + "test": "tests" + }, + "scripts": { + "start": "ember server", + "build": "ember build", + "test": "ember test" + }, + "engines": { + "node": ">= 0.10.0" + }, + "author": "Egor Philippov", + "license": "MIT", + "devDependencies": { + "broccoli-asset-rev": "^2.2.0", + "ember-ajax": "^2.0.1", + "ember-cli": "^2.8.0", + "ember-cli-app-version": "^2.0.0", + "ember-cli-babel": "^5.1.5", + "ember-cli-dependency-checker": "^1.2.0", + "ember-cli-htmlbars": "^1.0.1", + "ember-cli-htmlbars-inline-precompile": "^0.3.1", + "ember-cli-inject-live-reload": "^1.3.1", + "ember-cli-nouislider": "^0.10.0", + "ember-cli-qunit": "^1.2.1", + "ember-cli-release": "0.2.8", + "ember-cli-sass": "^5.2.1", + "ember-cli-sri": "^2.1.0", + "ember-cli-test-loader": "^1.1.0", + "ember-cli-uglify": "^1.2.0", + "ember-cordova": "0.3.5", + "ember-export-application-global": "^1.0.4", + "ember-load-initializers": "^0.5.0", + "ember-modal-dialog": "^0.9.0", + "ember-notify": "^5.0.4", + "ember-paper": "^1.0.0-alpha.5", + "ember-resolver": "^2.0.3", + "ember-truth-helpers": "^1.2.0", + "loader.js": "^4.0.7" + } +} diff --git a/mobile/public/android-chrome-192x192.png b/mobile/public/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..cc9d381368ea56579cd4baacd22313862e82c641 GIT binary patch literal 5619 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 literal 0 HcmV?d00001 diff --git a/mobile/public/android-chrome-512x512.png b/mobile/public/android-chrome-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..13e6e2661b84293f4056fff5cb4cc081b7f696ac GIT binary patch literal 14867 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 literal 0 HcmV?d00001 diff --git a/mobile/public/assets/images/colormap.png b/mobile/public/assets/images/colormap.png new file mode 100644 index 0000000000000000000000000000000000000000..53c80efa728bfb6c76c68d6ab3fc4a00159ebc30 GIT binary patch literal 6305 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 literal 0 HcmV?d00001 diff --git a/mobile/public/assets/images/lights/a19.svg b/mobile/public/assets/images/lights/a19.svg new file mode 100644 index 0000000..cf3eee3 --- /dev/null +++ b/mobile/public/assets/images/lights/a19.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/a19w.svg b/mobile/public/assets/images/lights/a19w.svg new file mode 100644 index 0000000..b05e873 --- /dev/null +++ b/mobile/public/assets/images/lights/a19w.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/br30.svg b/mobile/public/assets/images/lights/br30.svg new file mode 100644 index 0000000..7d71208 --- /dev/null +++ b/mobile/public/assets/images/lights/br30.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/br30w.svg b/mobile/public/assets/images/lights/br30w.svg new file mode 100644 index 0000000..ba1585a --- /dev/null +++ b/mobile/public/assets/images/lights/br30w.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/gu10.svg b/mobile/public/assets/images/lights/gu10.svg new file mode 100644 index 0000000..014d2f5 --- /dev/null +++ b/mobile/public/assets/images/lights/gu10.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/gu10w.svg b/mobile/public/assets/images/lights/gu10w.svg new file mode 100644 index 0000000..1ea01cb --- /dev/null +++ b/mobile/public/assets/images/lights/gu10w.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/huego.svg b/mobile/public/assets/images/lights/huego.svg new file mode 100644 index 0000000..e912e5a --- /dev/null +++ b/mobile/public/assets/images/lights/huego.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/huegow.svg b/mobile/public/assets/images/lights/huegow.svg new file mode 100644 index 0000000..b3b0b88 --- /dev/null +++ b/mobile/public/assets/images/lights/huegow.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/lc_aura.svg b/mobile/public/assets/images/lights/lc_aura.svg new file mode 100644 index 0000000..9faf3b9 --- /dev/null +++ b/mobile/public/assets/images/lights/lc_aura.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/lc_auraw.svg b/mobile/public/assets/images/lights/lc_auraw.svg new file mode 100644 index 0000000..c125947 --- /dev/null +++ b/mobile/public/assets/images/lights/lc_auraw.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/lc_bloom.svg b/mobile/public/assets/images/lights/lc_bloom.svg new file mode 100644 index 0000000..a498b9a --- /dev/null +++ b/mobile/public/assets/images/lights/lc_bloom.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/lc_bloomw.svg b/mobile/public/assets/images/lights/lc_bloomw.svg new file mode 100644 index 0000000..3dce9f7 --- /dev/null +++ b/mobile/public/assets/images/lights/lc_bloomw.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/lc_iris.svg b/mobile/public/assets/images/lights/lc_iris.svg new file mode 100644 index 0000000..876b3d2 --- /dev/null +++ b/mobile/public/assets/images/lights/lc_iris.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/lc_irisw.svg b/mobile/public/assets/images/lights/lc_irisw.svg new file mode 100644 index 0000000..cdf472b --- /dev/null +++ b/mobile/public/assets/images/lights/lc_irisw.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/lightstrip.svg b/mobile/public/assets/images/lights/lightstrip.svg new file mode 100644 index 0000000..1d55b8e --- /dev/null +++ b/mobile/public/assets/images/lights/lightstrip.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/lightstripw.svg b/mobile/public/assets/images/lights/lightstripw.svg new file mode 100644 index 0000000..fb32dab --- /dev/null +++ b/mobile/public/assets/images/lights/lightstripw.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/storylight.svg b/mobile/public/assets/images/lights/storylight.svg new file mode 100644 index 0000000..d04a5db --- /dev/null +++ b/mobile/public/assets/images/lights/storylight.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/lights/storylightw.svg b/mobile/public/assets/images/lights/storylightw.svg new file mode 100644 index 0000000..8bc66a5 --- /dev/null +++ b/mobile/public/assets/images/lights/storylightw.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/public/assets/images/logo.png b/mobile/public/assets/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e384e771737b508919b34a8452047a7a61d1b352 GIT binary patch literal 28287 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 FV1oB7oW=kE literal 0 HcmV?d00001 diff --git a/mobile/public/assets/images/pressButtonBridge.png b/mobile/public/assets/images/pressButtonBridge.png new file mode 100644 index 0000000000000000000000000000000000000000..e98ac238d3d28c04924aae8d60bbb149c955562e GIT binary patch literal 7050 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

  • d$H~fe`_16QE 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 + + + + + #da532c + + + diff --git a/mobile/public/crossdomain.xml b/mobile/public/crossdomain.xml new file mode 100644 index 0000000..0c16a7a --- /dev/null +++ b/mobile/public/crossdomain.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/mobile/public/favicon-16x16.png b/mobile/public/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..9e5a2e4617eaa21d062ad293f8dd53b14bedd097 GIT binary patch literal 1025 zcmV+c1pfPpP)Px$+E7eXMNDaN3n3r^1_l5D0{{R30SXWWA}as@00000 z000000|fv802e_-Hj9=96cI#zYybcNDQRv10024$0|*rmB~C_8i*-T<1OyTj1`!Md z000aZ4J1G@U$UV&WKbY27)lZak|+@Z0|Cf18qHD~G)X9BmuXsUFjid{000040RYW4 z8xj}?YM*YaQWK0M5LYAyQglafjz=d-KL7v#mOl{}8U%%=R15|Hev2+hY)NN~Gkuarx5FP{pw#P#N003ho2bP5mmvj!Fog15E5NA;as+SO{RTGb|RfMcA4)L<3l%#TfYcZ0M$w6Bqk0?c2bVxzU6R#V_q7!@JkI zsORh`{SJ<~z3xMXIC2vmSGc~)LcZPqkH4yXV_)QrrWjQB~aFg}BC z%+&O_$=>pC0ZrT3=@T8*;W`)?v^=8yG?c(h0Pfu}7O(vVm;e9(S9(-fbW&k=AaHVT zW@&6?Aar?fWguyAbYlPjc%0+%3K74o@~6kN@D^bMF0}yPW&G_ndowb35m#Ag3V*0DuDH z44t`;_*Mi=X&6Kzm7!A{2@*ipw*rePs5*>+?k=)ff5HD$SRdcMlCzg#%# zNs+lpSDYnNHenBX0K- zq^n2Q>6(=ju@aW%=6#|hhV<%#{p6yp zGp@wAw)9?Ijm%o+2pd;3%3ez)4(sEe{fIl)-sj)dTu)KY?c|mYMYcGp&iWD-Y2?g) zel-(acL}}vA3`ld<;U{E7b(~te{8n^)6k?N`WIm_1OM@XMo)>#K%RP7SNZ4+J@+1U z!U=zUApc`Aem;z_(@y--jUS&lvDAlKXvY0DaOz%)QrmBs$t>)**~n*DCRkL;IO3+QH=(Zu|wgF%$yR^dF<3dK}i#< zB5xpT;)c$Q#B?__xxlq0BY*1|XHydRm@@lTurcvzy zyE9vMUp>nK02a=m(>yE&1N{NW!Ho7`<)MI$2@K5TC%S*1e28c$1E0%&@j(CG?mwcI zEK+lL(to*KeP8XTEejJr8O6tRZ4?+J?V=LYTz)aWG@gk&f5iQ&AGIA54!8?dqAy<@ z+?ZUwdkC{RTGSZFnc9&yTYh0ZV$P-LDs@=I#|&i)s1VNW3B+vQ};i5Xr0CT-)E}AWQbtOQb5Mj7=jQ zBBFM$v2-4qkRe4)j#}#p@1U%aFw1*gz1J|}Z74~(EYkfbO{Y0b;+Sd@toa&nf_l2dx zGT*D>Y=Yp3Gfr4mCkl9c66!@*RL|VWRyC^X;Lc3-4++ON0#V*w1B;o}VUtg$I@hv{ zAjcaW$?T{L32(+B{)N5Pu}<+N18d0q5jv|xa=Y1b@@%!-H}-bBpSm&s?~BLoHy$bA z&^?7UucwprGE@l)?=N|65OZiK-T2YTRW8HUzx%0c%jQL=vg32oQ!lBXd4@&`^;P;y z7s4Cn?cIf%PdM|9Eq_F($Sg&V`0>1pRH;@L7@|wD_&k7ZvbGla#jyL*PbiKJQ!z0N zn7fW!mzA}HGvZe=g7WrlRk4-GPp~Mw75TiKdUH0fs5r!CZN>Y z2ZtDoOaRhG83v*-+8C!?6$nG7Upv_y1Zg*TkOyDC>hBrqA@s-&UOQ8E)(}`xSB{d{ Rn&usFFznCK>umk`{{#Al(UbrH literal 0 HcmV?d00001 diff --git a/mobile/public/favicon-96x96.png b/mobile/public/favicon-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..649034280ef5399823e8ae167c4e8e7d55c3ba4d GIT binary patch literal 3876 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 literal 0 HcmV?d00001 diff --git a/mobile/public/favicon.ico b/mobile/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..0c485bcc40208ebfde2b91f77affb37929f18122 GIT binary patch literal 15086 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 literal 0 HcmV?d00001 diff --git a/mobile/public/humans.txt b/mobile/public/humans.txt new file mode 100644 index 0000000..d5c830d --- /dev/null +++ b/mobile/public/humans.txt @@ -0,0 +1,14 @@ +/* TEAM */ +Your title: Egor Philippov +Site: https://www.linkedin.com/pub/egor-philippov/7b/220/148 +Location: Vancouver, Canada. + +/* THANKS */ +Edmond Cheung - favicons + huegasm logo +Liviu Antonescu - filming + video editing of the intro +Olamide Omorodion - business consultation + +/* SITE */ +Last update: 2015 +Standards: HTML5, CSS3 +Components: ember, jQuery, bootstrap, font-awesome, intro.js, locallyjs, nouislider, dancer.js, jquery-mousewheel, ember paper, ember notify, JavaScript-ID3-Reader diff --git a/mobile/public/manifest.json b/mobile/public/manifest.json new file mode 100644 index 0000000..e059ba3 --- /dev/null +++ b/mobile/public/manifest.json @@ -0,0 +1,17 @@ +{ + "name": "Huegasm", + "icons": [ + { + "src": "\/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image\/png" + }, + { + "src": "\/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image\/png" + } + ], + "theme_color": "#ffffff", + "display": "standalone" +} diff --git a/mobile/public/mstile-150x150.png b/mobile/public/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..c5e4b2220144e7599ed950294e6f77b733c36e48 GIT binary patch literal 3929 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 literal 0 HcmV?d00001 diff --git a/mobile/public/robots.txt b/mobile/public/robots.txt new file mode 100644 index 0000000..f591645 --- /dev/null +++ b/mobile/public/robots.txt @@ -0,0 +1,3 @@ +# http://www.robotstxt.org +User-agent: * +Disallow: diff --git a/mobile/public/safari-pinned-tab.svg b/mobile/public/safari-pinned-tab.svg new file mode 100644 index 0000000..947ed66 --- /dev/null +++ b/mobile/public/safari-pinned-tab.svg @@ -0,0 +1,69 @@ + + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + diff --git a/mobile/testem.js b/mobile/testem.js new file mode 100644 index 0000000..26044b2 --- /dev/null +++ b/mobile/testem.js @@ -0,0 +1,13 @@ +/*jshint node:true*/ +module.exports = { + "framework": "qunit", + "test_page": "tests/index.html?hidepassed", + "disable_watching": true, + "launch_in_ci": [ + "PhantomJS" + ], + "launch_in_dev": [ + "PhantomJS", + "Chrome" + ] +}; diff --git a/mobile/tests/.jshintrc b/mobile/tests/.jshintrc new file mode 100644 index 0000000..d2bd113 --- /dev/null +++ b/mobile/tests/.jshintrc @@ -0,0 +1,52 @@ +{ + "predef": [ + "document", + "window", + "location", + "setTimeout", + "$", + "-Promise", + "define", + "console", + "visit", + "exists", + "fillIn", + "click", + "keyEvent", + "triggerEvent", + "find", + "findWithAssert", + "wait", + "DS", + "andThen", + "currentURL", + "currentPath", + "currentRouteName" + ], + "node": false, + "browser": false, + "boss": true, + "curly": true, + "debug": false, + "devel": false, + "eqeqeq": true, + "evil": true, + "forin": false, + "immed": false, + "laxbreak": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": false, + "nomen": false, + "onevar": false, + "plusplus": false, + "regexp": false, + "undef": true, + "sub": true, + "strict": false, + "white": false, + "eqnull": true, + "esversion": 6, + "unused": true +} diff --git a/mobile/tests/helpers/destroy-app.js b/mobile/tests/helpers/destroy-app.js new file mode 100644 index 0000000..c3d4d1a --- /dev/null +++ b/mobile/tests/helpers/destroy-app.js @@ -0,0 +1,5 @@ +import Ember from 'ember'; + +export default function destroyApp(application) { + Ember.run(application, 'destroy'); +} diff --git a/mobile/tests/helpers/module-for-acceptance.js b/mobile/tests/helpers/module-for-acceptance.js new file mode 100644 index 0000000..76996fd --- /dev/null +++ b/mobile/tests/helpers/module-for-acceptance.js @@ -0,0 +1,23 @@ +import { module } from 'qunit'; +import Ember from 'ember'; +import startApp from '../helpers/start-app'; +import destroyApp from '../helpers/destroy-app'; + +const { RSVP: { Promise } } = Ember; + +export default function(name, options = {}) { + module(name, { + beforeEach() { + this.application = startApp(); + + if (options.beforeEach) { + return options.beforeEach.apply(this, arguments); + } + }, + + afterEach() { + let afterEach = options.afterEach && options.afterEach.apply(this, arguments); + return Promise.resolve(afterEach).then(() => destroyApp(this.application)); + } + }); +} diff --git a/mobile/tests/helpers/resolver.js b/mobile/tests/helpers/resolver.js new file mode 100644 index 0000000..b208d38 --- /dev/null +++ b/mobile/tests/helpers/resolver.js @@ -0,0 +1,11 @@ +import Resolver from '../../resolver'; +import config from '../../config/environment'; + +const resolver = Resolver.create(); + +resolver.namespace = { + modulePrefix: config.modulePrefix, + podModulePrefix: config.podModulePrefix +}; + +export default resolver; diff --git a/mobile/tests/helpers/start-app.js b/mobile/tests/helpers/start-app.js new file mode 100644 index 0000000..e098f1d --- /dev/null +++ b/mobile/tests/helpers/start-app.js @@ -0,0 +1,18 @@ +import Ember from 'ember'; +import Application from '../../app'; +import config from '../../config/environment'; + +export default function startApp(attrs) { + let application; + + let attributes = Ember.merge({}, config.APP); + attributes = Ember.merge(attributes, attrs); // use defaults, but you can override; + + Ember.run(() => { + application = Application.create(attributes); + application.setupForTesting(); + application.injectTestHelpers(); + }); + + return application; +} diff --git a/mobile/tests/index.html b/mobile/tests/index.html new file mode 100644 index 0000000..9ea9afb --- /dev/null +++ b/mobile/tests/index.html @@ -0,0 +1,33 @@ + + + + + + Huegasm Tests + + + + {{content-for "head"}} + {{content-for "test-head"}} + + + + + + {{content-for "head-footer"}} + {{content-for "test-head-footer"}} + + + {{content-for "body"}} + {{content-for "test-body"}} + + + + + + + + {{content-for "body-footer"}} + {{content-for "test-body-footer"}} + + diff --git a/mobile/tests/integration/pods/components/add-soundcloud-sound-modal/component-test.js b/mobile/tests/integration/pods/components/add-soundcloud-sound-modal/component-test.js new file mode 100644 index 0000000..2c2d873 --- /dev/null +++ b/mobile/tests/integration/pods/components/add-soundcloud-sound-modal/component-test.js @@ -0,0 +1,26 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('add-soundcloud-sound-modal', 'Integration | Component | add soundcloud sound modal', { + integration: true +}); + +test('it renders', function(assert) { + assert.expect(2); + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{add-soundcloud-sound-modal}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#add-soundcloud-sound-modal}} + template block text + {{/add-soundcloud-sound-modal}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/mobile/tests/integration/pods/components/bridge-finder/component-test.js b/mobile/tests/integration/pods/components/bridge-finder/component-test.js new file mode 100644 index 0000000..c42803d --- /dev/null +++ b/mobile/tests/integration/pods/components/bridge-finder/component-test.js @@ -0,0 +1,26 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('bridge-finder', 'Integration | Component | bridge finder', { + integration: true +}); + +test('it renders', function(assert) { + assert.expect(2); + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{bridge-finder}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#bridge-finder}} + template block text + {{/bridge-finder}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/mobile/tests/integration/pods/components/color-picker/component-test.js b/mobile/tests/integration/pods/components/color-picker/component-test.js new file mode 100644 index 0000000..fb1d925 --- /dev/null +++ b/mobile/tests/integration/pods/components/color-picker/component-test.js @@ -0,0 +1,26 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('color-picker', 'Integration | Component | color picker', { + integration: true +}); + +test('it renders', function(assert) { + assert.expect(2); + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{color-picker}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#color-picker}} + template block text + {{/color-picker}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/mobile/tests/integration/pods/components/hue-controls/component-test.js b/mobile/tests/integration/pods/components/hue-controls/component-test.js new file mode 100644 index 0000000..1d1ebc2 --- /dev/null +++ b/mobile/tests/integration/pods/components/hue-controls/component-test.js @@ -0,0 +1,26 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('hue-controls', 'Integration | Component | hue controls', { + integration: true +}); + +test('it renders', function(assert) { + assert.expect(2); + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{hue-controls}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#hue-controls}} + template block text + {{/hue-controls}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/mobile/tests/integration/pods/components/huegasm-app/component-test.js b/mobile/tests/integration/pods/components/huegasm-app/component-test.js new file mode 100644 index 0000000..53484b6 --- /dev/null +++ b/mobile/tests/integration/pods/components/huegasm-app/component-test.js @@ -0,0 +1,26 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('huegasm-app', 'Integration | Component | huegasm app', { + integration: true +}); + +test('it renders', function(assert) { + assert.expect(2); + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{huegasm-app}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#huegasm-app}} + template block text + {{/huegasm-app}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/mobile/tests/integration/pods/components/light-group/component-test.js b/mobile/tests/integration/pods/components/light-group/component-test.js new file mode 100644 index 0000000..22a66cd --- /dev/null +++ b/mobile/tests/integration/pods/components/light-group/component-test.js @@ -0,0 +1,26 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('light-group', 'Integration | Component | light group', { + integration: true +}); + +test('it renders', function(assert) { + assert.expect(2); + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{light-group}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#light-group}} + template block text + {{/light-group}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/mobile/tests/integration/pods/components/lights-tab/component-test.js b/mobile/tests/integration/pods/components/lights-tab/component-test.js new file mode 100644 index 0000000..d7af880 --- /dev/null +++ b/mobile/tests/integration/pods/components/lights-tab/component-test.js @@ -0,0 +1,26 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('lights-tab', 'Integration | Component | lights tab', { + integration: true +}); + +test('it renders', function(assert) { + assert.expect(2); + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{lights-tab}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#lights-tab}} + template block text + {{/lights-tab}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/mobile/tests/integration/pods/components/music-tab/component-test.js b/mobile/tests/integration/pods/components/music-tab/component-test.js new file mode 100644 index 0000000..d9636e1 --- /dev/null +++ b/mobile/tests/integration/pods/components/music-tab/component-test.js @@ -0,0 +1,26 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('music-tab', 'Integration | Component | music tab', { + integration: true +}); + +test('it renders', function(assert) { + assert.expect(2); + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{music-tab}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#music-tab}} + template block text + {{/music-tab}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/mobile/tests/test-helper.js b/mobile/tests/test-helper.js new file mode 100644 index 0000000..e6cfb70 --- /dev/null +++ b/mobile/tests/test-helper.js @@ -0,0 +1,6 @@ +import resolver from './helpers/resolver'; +import { + setResolver +} from 'ember-qunit'; + +setResolver(resolver); diff --git a/mobile/tests/unit/.gitkeep b/mobile/tests/unit/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/mobile/vendor/dancer.js b/mobile/vendor/dancer.js new file mode 100644 index 0000000..b928621 --- /dev/null +++ b/mobile/vendor/dancer.js @@ -0,0 +1,703 @@ +/* + * dancer - v0.4.0 - 2014-02-01 + * https://github.com/jsantell/dancer.js + * Copyright (c) 2014 Jordan Santell + * Licensed MIT + */ +(function() { + + var Dancer = function () { + this.audioAdapter = Dancer._getAdapter( this ); + this.events = {}; + this.sections = []; + this.bind( 'update', update ); + }; + + Dancer.version = 'X.X.X'; + Dancer.adapters = {}; + + Dancer.prototype = { + + load : function ( source, micBoost, useMic ) { + // Loading an Audio element + if ( source instanceof HTMLElement ) { + this.source = source; + // Loading an object with src, [codecs] + } else if(source instanceof EventTarget){ + this.source = source; + } else { + this.source = window.Audio ? new Audio() : {}; + this.source.src = Dancer._makeSupportedPath( source.src, source.codecs ); + } + + this.useMic = useMic === true; + this.boost = micBoost ? micBoost : 1; + this.audio = this.audioAdapter.load(this.source, this.useMic, this.boost); + + return this; + }, + + /* Controls */ + play : function () { + this.audioAdapter.play(); + return this; + }, + + pause : function () { + this.audioAdapter.pause(); + return this; + }, + + setVolume : function ( volume ) { + this.audioAdapter.setVolume( volume ); + return this; + }, + + setBoost : function ( boost ) { + this.audioAdapter.setBoost( boost ); + return this; + }, + + /* Actions */ + createKick : function ( options ) { + return new Dancer.Kick( this, options ); + }, + + bind : function ( name, callback ) { + if ( !this.events[ name ] ) { + this.events[ name ] = []; + } + this.events[ name ].push( callback ); + return this; + }, + + unbind : function ( name ) { + if ( this.events[ name ] ) { + delete this.events[ name ]; + } + return this; + }, + + trigger : function ( name ) { + var _this = this; + if ( this.events[ name ] ) { + this.events[ name ].forEach(function( callback ) { + callback.call( _this ); + }); + } + return this; + }, + + + /* Getters */ + + getVolume : function () { + return this.audioAdapter.getVolume(); + }, + + getProgress : function () { + return this.audioAdapter.getProgress(); + }, + + getTime : function () { + return this.audioAdapter.getTime(); + }, + + // Returns the magnitude of a frequency or average over a range of frequencies + getFrequency : function ( freq, endFreq ) { + var sum = 0; + if ( endFreq !== undefined ) { + for ( var i = freq; i <= endFreq; i++ ) { + sum += this.getSpectrum()[ i ]; + } + return sum / ( endFreq - freq + 1 ); + } else { + return this.getSpectrum()[ freq ]; + } + }, + + getWaveform : function () { + return this.audioAdapter.getWaveform(); + }, + + getSpectrum : function () { + return this.audioAdapter.getSpectrum(); + }, + + isLoaded : function () { + return this.audioAdapter.isLoaded; + }, + + isPlaying : function () { + return this.audioAdapter.isPlaying; + }, + + + /* Sections */ + + after : function ( time, callback ) { + var _this = this; + this.sections.push({ + condition : function () { + return _this.getTime() > time; + }, + callback : callback + }); + return this; + }, + + before : function ( time, callback ) { + var _this = this; + this.sections.push({ + condition : function () { + return _this.getTime() < time; + }, + callback : callback + }); + return this; + }, + + between : function ( startTime, endTime, callback ) { + var _this = this; + this.sections.push({ + condition : function () { + return _this.getTime() > startTime && _this.getTime() < endTime; + }, + callback : callback + }); + return this; + }, + + onceAt : function ( time, callback ) { + var + _this = this, + thisSection = null; + this.sections.push({ + condition : function () { + return _this.getTime() > time && !this.called; + }, + callback : function () { + callback.call( this ); + thisSection.called = true; + }, + called : false + }); + // Baking the section in the closure due to callback's this being the dancer instance + thisSection = this.sections[ this.sections.length - 1 ]; + return this; + } + }; + + function update () { + for (var i in this.sections) { + if (this.sections[i].condition && this.sections[i].condition() ) + this.sections[i].callback.call(this); + } + } + + window.Dancer = Dancer; +})(); + +(function ( Dancer ) { + + var CODECS = { + 'mp3' : 'audio/mpeg;', + 'ogg' : 'audio/ogg; codecs="vorbis"', + 'wav' : 'audio/wav; codecs="1"', + 'aac' : 'audio/mp4; codecs="mp4a.40.2"' + }, + audioEl = document.createElement( 'audio' ); + + Dancer.options = {}; + + Dancer.setOptions = function ( o ) { + for ( var option in o ) { + if ( o.hasOwnProperty( option ) ) { + Dancer.options[ option ] = o[ option ]; + } + } + }; + + Dancer.isSupported = function () { + if ( !window.Float32Array || !window.Uint32Array ) { + return null; + } else if ( !isUnsupportedSafari() && ( window.AudioContext || window.webkitAudioContext )) { + return 'webaudio'; + } else { + return ''; + } + }; + + Dancer.canPlay = function ( type ) { + var canPlay = audioEl.canPlayType; + return !!( + type.toLowerCase() === 'mp3' || + audioEl.canPlayType && + audioEl.canPlayType( CODECS[ type.toLowerCase() ] ).replace( /no/, '')); + }; + + Dancer.addPlugin = function ( name, fn ) { + if ( Dancer.prototype[ name ] === undefined ) { + Dancer.prototype[ name ] = fn; + } + }; + + Dancer._makeSupportedPath = function ( source, codecs ) { + if ( !codecs ) { return source; } + + for ( var i = 0; i < codecs.length; i++ ) { + if ( Dancer.canPlay( codecs[ i ] ) ) { + return source + '.' + codecs[ i ]; + } + } + return source; + }; + + Dancer._getAdapter = function ( instance ) { + switch ( Dancer.isSupported() ) { + case 'webaudio': + return new Dancer.adapters.webaudio( instance ); + default: + return null; + } + }; + + Dancer._getMP3SrcFromAudio = function ( audioEl ) { + var sources = audioEl.children; + if ( audioEl.src ) { return audioEl.src; } + for ( var i = sources.length; i--; ) { + if (( sources[ i ].type || '' ).match( /audio\/mpeg/ )) return sources[ i ].src; + } + return null; + }; + + // Browser detection is lame, but Safari 6 has Web Audio API, + // but does not support processing audio from a Media Element Source + // https://gist.github.com/3265344 + function isUnsupportedSafari () { + var + isApple = !!( navigator.vendor || '' ).match( /Apple/ ), + version = navigator.userAgent.match( /Version\/([^ ]*)/ ); + version = version ? parseFloat( version[ 1 ] ) : 0; + return isApple && version <= 6; + } + +})( window.Dancer ); + +(function ( undefined ) { + var Kick = function ( dancer, o ) { + o = o || {}; + this.dancer = dancer; + this.frequency = o.frequency !== undefined ? o.frequency : [ 0, 5 ]; + this.threshold = o.threshold !== undefined ? o.threshold : 0.3; + this.decay = o.decay !== undefined ? o.decay : 0.02; + this.onKick = o.onKick; + this.offKick = o.offKick; + this.isOn = false; + this.currentThreshold = this.threshold; + this.previousMag = 0; + this.canUseRatio = true; + this.canUseRatioHandle = null; + + var _this = this; + this.dancer.bind( 'update', function () { + _this.onUpdate(); + }); + }; + + Kick.prototype = { + on : function () { + this.isOn = true; + return this; + }, + off : function () { + this.isOn = false; + return this; + }, + + set : function ( o ) { + o = o || {}; + this.frequency = o.frequency !== undefined ? o.frequency : this.frequency; + this.threshold = o.threshold !== undefined ? o.threshold : this.threshold; + this.decay = o.decay !== undefined ? o.decay : this.decay; + this.onKick = o.onKick || this.onKick; + this.offKick = o.offKick || this.offKick; + }, + + onUpdate : function () { + if ( !this.isOn ) { return; } + + var magnitude = this.maxAmplitude(this.frequency); + + if (magnitude >= this.currentThreshold && magnitude >= this.threshold) { + this.currentThreshold = magnitude; + this.onKick && this.onKick.call(this.dancer, magnitude); + this.canUseRatio = false; + + if(this.canUseRatioHandle) { + clearTimeout(this.canUseRatioHandle); + this.canUseRatioHandle = null; + } + + var self = this; + this.canUseRatioHandle = setTimeout(function(){ + self.canUseRatio = true; + }, 5000); + } else { + if(magnitude/this.previousMag > this.threshold*5 && magnitude>0.1 && this.canUseRatio) { + this.onKick && this.onKick.call(this.dancer, magnitude, magnitude/this.previousMag); + } else { + this.offKick && this.offKick.call(this.dancer, magnitude); + } + + this.currentThreshold -= this.decay; + this.previousMag = (magnitude > 0) ? magnitude : 0.0001; + } + }, + maxAmplitude : function ( frequency ) { + var max = 0, fft = this.dancer.getSpectrum(); + + // Sloppy array check + if ( !frequency.length ) { + return frequency < fft.length ? + fft[ ~~frequency ] : + null; + } + + for ( var i = frequency[ 0 ], l = frequency[ 1 ]; i <= l; i++ ) { + if ( fft[ i ] > max ) { max = fft[ i ]; } + } + return max; + } + }; + + window.Dancer.Kick = Kick; +})(); + +(function() { + var + SAMPLE_SIZE = 2048, + SAMPLE_RATE = 44100; + + var adapter = function ( dancer ) { + var context = new AudioContext(); + + this.dancer = dancer; + this.audio = new Audio(); + this.context = context; + }; + + adapter.prototype = { + + load : function (_source, useMic, boost) { + var _this = this; + this.audio = _source; + this.useMic = useMic; + this.boost = boost; + + this.isLoaded = false; + this.progress = 0; + + if(this.proc){ + this.proc.onaudioprocess = null; + delete this.proc; + } + + this.proc = this.context.createScriptProcessor( SAMPLE_SIZE / 2, 1, 1 ); + + this.proc.onaudioprocess = function ( e ) { + _this.update.call( _this, e ); + }; + + this.gain = this.context.createGain(); + + this.fft = new FFT( SAMPLE_SIZE / 2, SAMPLE_RATE, this.boost ); + this.signal = new Float32Array( SAMPLE_SIZE / 2 ); + + if ( this.audio.readyState < 3 ) { + this.audio.addEventListener( 'canplay', function () { + connectContext.call( _this ); + }); + } else { + connectContext.call( _this ); + } + + this.audio.addEventListener( 'progress', function ( e ) { + if ( e.currentTarget.duration && e.currentTarget.duration !== Infinity ) { + _this.progress = e.currentTarget.seekable.end( 0 ) / e.currentTarget.duration; + } + }); + + return this.audio; + }, + + play : function () { + this.audio.play(); + this.isPlaying = true; + }, + + pause : function () { + this.audio.pause(); + this.isPlaying = false; + }, + + setVolume : function ( volume ) { + this.gain.gain.value = volume; + }, + + setBoost : function( boost ){ + if(this.fft){ + this.fft.setBoost(boost); + } + + this.boost = boost; + }, + + getVolume : function () { + return this.gain.gain.value; + }, + + getProgress : function() { + return this.progress; + }, + + getWaveform : function () { + return this.signal; + }, + + getSpectrum : function () { + return this.fft.spectrum; + }, + + getTime : function () { + return this.audio.currentTime; + }, + + update : function ( e ) { + if ((!this.isPlaying || !this.isLoaded) && this.useMic !== true ) return; + + var + buffers = [], + channels = e.inputBuffer.numberOfChannels, + resolution = SAMPLE_SIZE / channels, + sum = function ( prev, curr ) { + return prev[ i ] + curr[ i ]; + }, i; + + for ( i = channels; i--; ) { + buffers.push( e.inputBuffer.getChannelData( i ) ); + } + + for ( i = 0; i < resolution; i++ ) { + this.signal[ i ] = channels > 1 ? + buffers.reduce( sum ) / channels : + buffers[ 0 ][ i ]; + } + + this.fft.forward( this.signal ); + this.dancer.trigger( 'update' ); + } + }; + + function connectContext () { + try { + if(this.useMic){ + this.source = this.context.createMediaStreamSource(this.audio); + } else { + this.source = this.context.createMediaElementSource(this.audio); + } + } catch (err) { + console.info('Dancer: '+ err); + return; + } + + this.source.connect(this.proc); + this.source.connect(this.gain); + this.gain.connect(this.context.destination); + this.proc.connect(this.context.destination); + + this.isLoaded = true; + this.progress = 1; + this.dancer.trigger( 'loaded' ); + } + + Dancer.adapters.webaudio = adapter; + +})(); + + +/* + * DSP.js - a comprehensive digital signal processing library for javascript + * + * Created by Corban Brook on 2010-01-01. + * Copyright 2010 Corban Brook. All rights reserved. + * + */ + +// Fourier Transform Module used by DFT, FFT, RFFT +function FourierTransform(bufferSize, sampleRate, boost) { + this.bufferSize = bufferSize; + this.sampleRate = sampleRate; + this.bandwidth = 2 / bufferSize * sampleRate / 2; + this.boost = boost ? boost : 1; + + this.spectrum = new Float32Array(bufferSize/2); + this.real = new Float32Array(bufferSize); + this.imag = new Float32Array(bufferSize); + + this.peakBand = 0; + this.peak = 0; + + /** + * Calculates the *middle* frequency of an FFT band. + * + * @param {Number} index The index of the FFT band. + * + * @returns The middle frequency in Hz. + */ + this.getBandFrequency = function(index) { + return this.bandwidth * index + this.bandwidth / 2; + }; + + this.setBoost = function(boost){ + this.boost = boost; + }; + + this.calculateSpectrum = function() { + var spectrum = this.spectrum, + real = this.real, + imag = this.imag, + boost = this.boost, + bSi = 2 / this.bufferSize, + sqrt = Math.sqrt, + rval, + ival, + mag; + + for (var i = 0, N = bufferSize/2; i < N; i++) { + rval = real[i]; + ival = imag[i]; + mag = bSi * sqrt(rval * rval + ival * ival); + + if (mag > this.peak) { + this.peakBand = i; + this.peak = mag; + } + + spectrum[i] = mag * boost; + } + }; +} + +/** + * FFT is a class for calculating the Discrete Fourier Transform of a signal + * with the Fast Fourier Transform algorithm. + * + * @param {Number} bufferSize The size of the sample buffer to be computed. Must be power of 2 + * @param {Number} sampleRate The sampleRate of the buffer (eg. 44100) + * @param {Number} boost The coefficient + * + * @constructor + */ +function FFT(bufferSize, sampleRate, boost) { + FourierTransform.call(this, bufferSize, sampleRate, boost); + + this.reverseTable = new Uint32Array(bufferSize); + + var limit = 1; + var bit = bufferSize >> 1; + + var i; + + while (limit < bufferSize) { + for (i = 0; i < limit; i++) { + this.reverseTable[i + limit] = this.reverseTable[i] + bit; + } + + limit = limit << 1; + bit = bit >> 1; + } + + this.sinTable = new Float32Array(bufferSize); + this.cosTable = new Float32Array(bufferSize); + + for (i = 0; i < bufferSize; i++) { + this.sinTable[i] = Math.sin(-Math.PI/i); + this.cosTable[i] = Math.cos(-Math.PI/i); + } +} + +/** + * Performs a forward transform on the sample buffer. + * Converts a time domain signal to frequency domain spectra. + * + * @param {Array} buffer The sample buffer. Buffer Length must be power of 2 + * + * @returns The frequency spectrum array + */ +FFT.prototype.forward = function(buffer) { + // Locally scope variables for speed up + var bufferSize = this.bufferSize, + cosTable = this.cosTable, + sinTable = this.sinTable, + reverseTable = this.reverseTable, + real = this.real, + imag = this.imag, + spectrum = this.spectrum; + + var k = Math.floor(Math.log(bufferSize) / Math.LN2); + + if (Math.pow(2, k) !== bufferSize) { throw "Invalid buffer size, must be a power of 2."; } + if (bufferSize !== buffer.length) { throw "Supplied buffer is not the same size as defined FFT. FFT Size: " + bufferSize + " Buffer Size: " + buffer.length; } + + var halfSize = 1, + phaseShiftStepReal, + phaseShiftStepImag, + currentPhaseShiftReal, + currentPhaseShiftImag, + off, + tr, + ti, + tmpReal, + i; + + for (i = 0; i < bufferSize; i++) { + real[i] = buffer[reverseTable[i]]; + imag[i] = 0; + } + + while (halfSize < bufferSize) { + //phaseShiftStepReal = Math.cos(-Math.PI/halfSize); + //phaseShiftStepImag = Math.sin(-Math.PI/halfSize); + phaseShiftStepReal = cosTable[halfSize]; + phaseShiftStepImag = sinTable[halfSize]; + + currentPhaseShiftReal = 1; + currentPhaseShiftImag = 0; + + for (var fftStep = 0; fftStep < halfSize; fftStep++) { + i = fftStep; + + while (i < bufferSize) { + off = i + halfSize; + tr = (currentPhaseShiftReal * real[off]) - (currentPhaseShiftImag * imag[off]); + ti = (currentPhaseShiftReal * imag[off]) + (currentPhaseShiftImag * real[off]); + + real[off] = real[i] - tr; + imag[off] = imag[i] - ti; + real[i] += tr; + imag[i] += ti; + + i += halfSize << 1; + } + + tmpReal = currentPhaseShiftReal; + currentPhaseShiftReal = (tmpReal * phaseShiftStepReal) - (currentPhaseShiftImag * phaseShiftStepImag); + currentPhaseShiftImag = (tmpReal * phaseShiftStepImag) + (currentPhaseShiftImag * phaseShiftStepReal); + } + + halfSize = halfSize << 1; + } + + return this.calculateSpectrum(); +}; diff --git a/mobile/yarn.lock b/mobile/yarn.lock new file mode 100644 index 0000000..17aa412 --- /dev/null +++ b/mobile/yarn.lock @@ -0,0 +1,5069 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 +abbrev@~1.0.7, abbrev@1: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + +accepts@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" + dependencies: + mime-types "~2.1.11" + negotiator "0.6.1" + +accepts@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.1.4.tgz#d71c96f7d41d0feda2c38cd14e8a27c04158df4a" + dependencies: + mime-types "~2.0.4" + negotiator "0.4.9" + +acorn@^1.0.3: + version "1.2.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-1.2.2.tgz#c8ce27de0acc76d896d2b1fad3df588d9e82f014" + +after@0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.1.tgz#ab5d4fb883f596816d3515f8f791c0af486dd627" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +alter@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/alter/-/alter-0.2.0.tgz#c7588808617572034aae62480af26b1d4d1cb3cd" + dependencies: + stable "~0.1.3" + +amd-name-resolver@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/amd-name-resolver/-/amd-name-resolver-0.0.5.tgz#76962dac876ed3311b05d29c6a58c14e1ef3304b" + dependencies: + ensure-posix-path "^1.0.1" + +amdefine@>=0.0.4: + version "1.0.0" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.0.tgz#fd17474700cb5cc9c2b709f0be9d23ce3c198c33" + +angular-material-source@angular/material#v1.0.6: + version "1.0.6" + resolved "https://codeload.github.com/angular/material/tar.gz/8b886cbed0254eaefa2f85077ebf4169cb09a762" + +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + +ansi-regex@^0.2.0, ansi-regex@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9" + +ansi-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.0.0.tgz#c5061b6e0ef8a81775e50f5d66151bf6bf371107" + +ansi-styles@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" + +ansi-styles@^2.1.0, ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + +ansi@^0.3.0, ansi@~0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21" + +ansicolors@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef" + +ansicolors@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" + +ansistyles@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539" + +aproba@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.0.4.tgz#2713680775e7614c8ba186c065d4e2e52d1072c0" + +archy@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + +are-we-there-yet@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.0 || ^1.1.13" + +argparse@^1.0.7, argparse@~1.0.2: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + +array-index@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-index/-/array-index-1.0.0.tgz#ec56a749ee103e4e08c790b9c353df16055b97f9" + dependencies: + debug "^2.2.0" + es6-symbol "^3.0.2" + +array-to-error@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-to-error/-/array-to-error-1.1.1.tgz#d68812926d14097a205579a667eeaf1856a44c07" + dependencies: + array-to-sentence "^1.1.0" + +array-to-sentence@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-to-sentence/-/array-to-sentence-1.1.0.tgz#c804956dafa53232495b205a9452753a258d39fc" + +arraybuffer.slice@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca" + +asap@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +ast-traverse@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ast-traverse/-/ast-traverse-0.1.1.tgz#69cf2b8386f19dcda1bb1e05d68fe359d8897de6" + +ast-types@0.8.12: + version "0.8.12" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.12.tgz#a0d90e4351bb887716c83fd637ebf818af4adfcc" + +ast-types@0.8.15: + version "0.8.15" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.15.tgz#8eef0827f04dff0ec8857ba925abe3fea6194e52" + +ast-types@0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.0.tgz#c8721c8747ae4d5b29b929e99c5317b4e8745623" + +async-disk-cache@^1.0.0: + version "1.0.8" + resolved "https://registry.yarnpkg.com/async-disk-cache/-/async-disk-cache-1.0.8.tgz#f0b0013ad84abbac10389c60e7bac493502fb91e" + dependencies: + debug "^2.1.3" + istextorbinary "2.1.0" + mkdirp "^0.5.0" + rimraf "^2.5.3" + rsvp "^3.0.18" + +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + +async-some@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/async-some/-/async-some-1.0.2.tgz#4d8a81620d5958791b5b98f802d3207776e95509" + dependencies: + dezalgo "^1.0.2" + +async@^1.4.0, async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@^2.0.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/async/-/async-2.1.2.tgz#612a4ab45ef42a70cde806bad86ee6db047e8385" + dependencies: + lodash "^4.14.0" + +async@~0.2.6, async@~0.2.9: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +autoprefixer-core@^5.0.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/autoprefixer-core/-/autoprefixer-core-5.2.1.tgz#e640c414ae419aae21c1ad43c8ea0f3db82a566d" + dependencies: + browserslist "~0.4.0" + caniuse-db "^1.0.30000214" + num2fraction "^1.1.0" + postcss "~4.1.12" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755" + +babel-core@^5.0.0: + version "5.8.38" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-5.8.38.tgz#1fcaee79d7e61b750b00b8e54f6dfc9d0af86558" + dependencies: + babel-plugin-constant-folding "^1.0.1" + babel-plugin-dead-code-elimination "^1.0.2" + babel-plugin-eval "^1.0.1" + babel-plugin-inline-environment-variables "^1.0.1" + babel-plugin-jscript "^1.0.4" + babel-plugin-member-expression-literals "^1.0.1" + babel-plugin-property-literals "^1.0.1" + babel-plugin-proto-to-assign "^1.0.3" + babel-plugin-react-constant-elements "^1.0.3" + babel-plugin-react-display-name "^1.0.3" + babel-plugin-remove-console "^1.0.1" + babel-plugin-remove-debugger "^1.0.1" + babel-plugin-runtime "^1.0.7" + babel-plugin-undeclared-variables-check "^1.0.2" + babel-plugin-undefined-to-void "^1.1.6" + babylon "^5.8.38" + bluebird "^2.9.33" + chalk "^1.0.0" + convert-source-map "^1.1.0" + core-js "^1.0.0" + debug "^2.1.1" + detect-indent "^3.0.0" + esutils "^2.0.0" + fs-readdir-recursive "^0.1.0" + globals "^6.4.0" + home-or-tmp "^1.0.0" + is-integer "^1.0.4" + js-tokens "1.0.1" + json5 "^0.4.0" + lodash "^3.10.0" + minimatch "^2.0.3" + output-file-sync "^1.1.0" + path-exists "^1.0.0" + path-is-absolute "^1.0.0" + private "^0.1.6" + regenerator "0.8.40" + regexpu "^1.3.0" + repeating "^1.1.2" + resolve "^1.1.6" + shebang-regex "^1.0.0" + slash "^1.0.0" + source-map "^0.5.0" + source-map-support "^0.2.10" + to-fast-properties "^1.0.0" + trim-right "^1.0.0" + try-resolve "^1.0.0" + +babel-plugin-constant-folding@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-constant-folding/-/babel-plugin-constant-folding-1.0.1.tgz#8361d364c98e449c3692bdba51eff0844290aa8e" + +babel-plugin-dead-code-elimination@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-dead-code-elimination/-/babel-plugin-dead-code-elimination-1.0.2.tgz#5f7c451274dcd7cccdbfbb3e0b85dd28121f0f65" + +babel-plugin-eval@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-eval/-/babel-plugin-eval-1.0.1.tgz#a2faed25ce6be69ade4bfec263f70169195950da" + +babel-plugin-htmlbars-inline-precompile@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-0.1.0.tgz#b784723bd1f108796b56faf9f1c05eb5ca442983" + +babel-plugin-inline-environment-variables@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-inline-environment-variables/-/babel-plugin-inline-environment-variables-1.0.1.tgz#1f58ce91207ad6a826a8bf645fafe68ff5fe3ffe" + +babel-plugin-jscript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/babel-plugin-jscript/-/babel-plugin-jscript-1.0.4.tgz#8f342c38276e87a47d5fa0a8bd3d5eb6ccad8fcc" + +babel-plugin-member-expression-literals@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-member-expression-literals/-/babel-plugin-member-expression-literals-1.0.1.tgz#cc5edb0faa8dc927170e74d6d1c02440021624d3" + +babel-plugin-property-literals@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-property-literals/-/babel-plugin-property-literals-1.0.1.tgz#0252301900192980b1c118efea48ce93aab83336" + +babel-plugin-proto-to-assign@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/babel-plugin-proto-to-assign/-/babel-plugin-proto-to-assign-1.0.4.tgz#c49e7afd02f577bc4da05ea2df002250cf7cd123" + dependencies: + lodash "^3.9.3" + +babel-plugin-react-constant-elements@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/babel-plugin-react-constant-elements/-/babel-plugin-react-constant-elements-1.0.3.tgz#946736e8378429cbc349dcff62f51c143b34e35a" + +babel-plugin-react-display-name@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/babel-plugin-react-display-name/-/babel-plugin-react-display-name-1.0.3.tgz#754fe38926e8424a4e7b15ab6ea6139dee0514fc" + +babel-plugin-remove-console@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-remove-console/-/babel-plugin-remove-console-1.0.1.tgz#d8f24556c3a05005d42aaaafd27787f53ff013a7" + +babel-plugin-remove-debugger@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-remove-debugger/-/babel-plugin-remove-debugger-1.0.1.tgz#fd2ea3cd61a428ad1f3b9c89882ff4293e8c14c7" + +babel-plugin-runtime@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/babel-plugin-runtime/-/babel-plugin-runtime-1.0.7.tgz#bf7c7d966dd56ecd5c17fa1cb253c9acb7e54aaf" + +babel-plugin-undeclared-variables-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-undeclared-variables-check/-/babel-plugin-undeclared-variables-check-1.0.2.tgz#5cf1aa539d813ff64e99641290af620965f65dee" + dependencies: + leven "^1.0.2" + +babel-plugin-undefined-to-void@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/babel-plugin-undefined-to-void/-/babel-plugin-undefined-to-void-1.1.6.tgz#7f578ef8b78dfae6003385d8417a61eda06e2f81" + +babylon@^5.8.38: + version "5.8.38" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-5.8.38.tgz#ec9b120b11bf6ccd4173a18bf217e60b79859ffd" + +backbone@^1.1.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/backbone/-/backbone-1.3.3.tgz#4cc80ea7cb1631ac474889ce40f2f8bc683b2999" + dependencies: + underscore ">=1.8.3" + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + +balanced-match@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +base64-arraybuffer@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.2.tgz#474df4a9f2da24e05df3158c3b1db3c3cd46a154" + +base64id@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-0.1.0.tgz#02ce0fdeee0cef4f40080e1e73e834f0b1bfce3f" + +basic-auth@~1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.0.4.tgz#030935b01de7c9b94a824b29f3fccb750d3a5290" + +bcrypt-pbkdf@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz#3ca76b85241c7170bf7d9703e7b9aa74630040d4" + dependencies: + tweetnacl "^0.14.3" + +benchmark@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/benchmark/-/benchmark-1.0.0.tgz#2f1e2fa4c359f11122aa183082218e957e390c73" + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + dependencies: + callsite "1.0.0" + +"binaryextensions@1 || 2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.0.0.tgz#e597d1a7a6a3558a2d1c7241a16c99965e6aa40f" + +bl@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398" + dependencies: + readable-stream "~2.0.5" + +blank-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/blank-object/-/blank-object-1.0.2.tgz#f990793fbe9a8c8dd013fb3219420bec81d5f4b9" + +blob@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921" + +block-stream@*, block-stream@0.0.9: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bluebird@^2.9.33: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" + +bluebird@^3.1.1, bluebird@^3.4.6: + version "3.4.6" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f" + +body-parser@~1.14.0: + version "1.14.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.14.2.tgz#1015cb1fe2c443858259581db53332f8d0cf50f9" + dependencies: + bytes "2.2.0" + content-type "~1.0.1" + debug "~2.2.0" + depd "~1.1.0" + http-errors "~1.3.1" + iconv-lite "0.4.13" + on-finished "~2.3.0" + qs "5.2.0" + raw-body "~2.1.5" + type-is "~1.6.10" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +bower-config@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/bower-config/-/bower-config-1.4.0.tgz#16c38c1135f8071c19f25938d61b0d8cbf18d3f1" + dependencies: + graceful-fs "^4.1.3" + mout "^1.0.0" + optimist "^0.6.1" + osenv "^0.1.3" + untildify "^2.1.0" + +bower-endpoint-parser@0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz#00b565adbfab6f2d35addde977e97962acbcb3f6" + +bower@^1.3.12: + version "1.7.9" + resolved "https://registry.yarnpkg.com/bower/-/bower-1.7.9.tgz#b7296c2393e0d75edaa6ca39648132dd255812b0" + +brace-expansion@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" + dependencies: + balanced-match "^0.4.1" + concat-map "0.0.1" + +breakable@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/breakable/-/breakable-1.0.0.tgz#784a797915a38ead27bad456b5572cb4bbaa78c1" + +broccoli-asset-rev@^2.2.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/broccoli-asset-rev/-/broccoli-asset-rev-2.5.0.tgz#f5f66eac962bf9f086286921f0eaeaab6d00d819" + dependencies: + broccoli-asset-rewrite "^1.1.0" + broccoli-filter "^1.2.2" + json-stable-stringify "^1.0.0" + matcher-collection "^1.0.1" + rsvp "^3.0.6" + +broccoli-asset-rewrite@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/broccoli-asset-rewrite/-/broccoli-asset-rewrite-1.1.0.tgz#77a5da56157aa318c59113245e8bafb4617f8830" + dependencies: + broccoli-filter "^1.2.3" + +broccoli-autoprefixer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/broccoli-autoprefixer/-/broccoli-autoprefixer-3.0.0.tgz#b7c9edb7166382ab2c626261ff56566cda0d1a71" + dependencies: + autoprefixer-core "^5.0.0" + broccoli-filter "^0.1.6" + object-assign "^2.0.0" + postcss "^4.1.11" + +broccoli-babel-transpiler@^5.4.5, broccoli-babel-transpiler@^5.5.0, broccoli-babel-transpiler@^5.6.0: + version "5.6.1" + resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-5.6.1.tgz#97184dcb140b40aa57f3ff38330afccc675d0a3c" + dependencies: + babel-core "^5.0.0" + broccoli-funnel "^1.0.0" + broccoli-merge-trees "^1.0.0" + broccoli-persistent-filter "^1.0.1" + clone "^0.2.0" + hash-for-dep "^1.0.2" + json-stable-stringify "^1.0.0" + +broccoli-caching-writer@^2.0.4, broccoli-caching-writer@^2.2.0, broccoli-caching-writer@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/broccoli-caching-writer/-/broccoli-caching-writer-2.3.1.tgz#b93cf58f9264f003075868db05774f4e7f25bd07" + dependencies: + broccoli-kitchen-sink-helpers "^0.2.5" + broccoli-plugin "1.1.0" + debug "^2.1.1" + rimraf "^2.2.8" + rsvp "^3.0.17" + walk-sync "^0.2.5" + +broccoli-caching-writer@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/broccoli-caching-writer/-/broccoli-caching-writer-3.0.3.tgz#0bd2c96a9738d6a6ab590f07ba35c5157d7db476" + dependencies: + broccoli-kitchen-sink-helpers "^0.3.1" + broccoli-plugin "^1.2.1" + debug "^2.1.1" + rimraf "^2.2.8" + rsvp "^3.0.17" + walk-sync "^0.3.0" + +broccoli-clean-css@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/broccoli-clean-css/-/broccoli-clean-css-1.1.0.tgz#9db143d9af7e0ae79c26e3ac5a9bb2d720ea19fa" + dependencies: + broccoli-persistent-filter "^1.1.6" + clean-css-promise "^0.1.0" + inline-source-map-comment "^1.0.5" + json-stable-stringify "^1.0.0" + +broccoli-concat@^2.0.4, broccoli-concat@^2.2.0: + version "2.3.8" + resolved "https://registry.yarnpkg.com/broccoli-concat/-/broccoli-concat-2.3.8.tgz#590cdcc021bb905b6c121d87c2d1d57df44a2a48" + dependencies: + broccoli-caching-writer "^2.3.1" + broccoli-kitchen-sink-helpers "^0.3.1" + broccoli-stew "^1.3.3" + fast-sourcemap-concat "^1.0.1" + fs-extra "^0.30.0" + lodash.merge "^4.3.0" + lodash.omit "^4.1.0" + lodash.uniq "^4.2.0" + +broccoli-config-loader@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/broccoli-config-loader/-/broccoli-config-loader-1.0.0.tgz#c3cf5ecfaffc04338c6f1d5d38dc36baeaa131ba" + dependencies: + broccoli-caching-writer "^2.0.4" + +broccoli-config-replace@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/broccoli-config-replace/-/broccoli-config-replace-1.1.2.tgz#6ea879d92a5bad634d11329b51fc5f4aafda9c00" + dependencies: + broccoli-kitchen-sink-helpers "^0.3.1" + broccoli-plugin "^1.2.0" + debug "^2.2.0" + fs-extra "^0.24.0" + +broccoli-filter@^0.1.6: + version "0.1.14" + resolved "https://registry.yarnpkg.com/broccoli-filter/-/broccoli-filter-0.1.14.tgz#23cae3891ff9ebb7b4d7db00c6dcf03535daf7ad" + dependencies: + broccoli-kitchen-sink-helpers "^0.2.6" + broccoli-writer "^0.1.1" + mkdirp "^0.3.5" + promise-map-series "^0.2.1" + quick-temp "^0.1.2" + rsvp "^3.0.16" + symlink-or-copy "^1.0.1" + walk-sync "^0.1.3" + +broccoli-filter@^1.2.2, broccoli-filter@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/broccoli-filter/-/broccoli-filter-1.2.4.tgz#409afb94b9a3a6da9fac8134e91e205f40cc7330" + dependencies: + broccoli-kitchen-sink-helpers "^0.3.1" + broccoli-plugin "^1.0.0" + copy-dereference "^1.0.0" + debug "^2.2.0" + mkdirp "^0.5.1" + promise-map-series "^0.2.1" + rsvp "^3.0.18" + symlink-or-copy "^1.0.1" + walk-sync "^0.3.1" + +broccoli-funnel-reducer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/broccoli-funnel-reducer/-/broccoli-funnel-reducer-1.0.0.tgz#11365b2a785aec9b17972a36df87eef24c5cc0ea" + +broccoli-funnel@^1.0.0, broccoli-funnel@^1.0.1, broccoli-funnel@^1.0.3: + version "1.0.7" + resolved "https://registry.yarnpkg.com/broccoli-funnel/-/broccoli-funnel-1.0.7.tgz#d44eb55991cb365f2f6de450734ff467135953d2" + dependencies: + array-equal "^1.0.0" + blank-object "^1.0.1" + broccoli-plugin "^1.0.0" + debug "^2.2.0" + fast-ordered-set "^1.0.0" + fs-tree-diff "^0.5.3" + heimdalljs "^0.2.0" + minimatch "^3.0.0" + mkdirp "^0.5.0" + path-posix "^1.0.0" + rimraf "^2.4.3" + symlink-or-copy "^1.0.0" + walk-sync "^0.3.1" + +broccoli-jshint@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/broccoli-jshint/-/broccoli-jshint-1.2.0.tgz#8cd565d11a04bfd32cb8f85a0f7ede1e5be7a6a2" + dependencies: + broccoli-persistent-filter "^1.2.0" + chalk "~0.4.0" + findup-sync "^0.3.0" + jshint "^2.7.0" + json-stable-stringify "^1.0.0" + mkdirp "~0.4.0" + +broccoli-kitchen-sink-helpers@^0.2.5, broccoli-kitchen-sink-helpers@^0.2.6: + version "0.2.9" + resolved "https://registry.yarnpkg.com/broccoli-kitchen-sink-helpers/-/broccoli-kitchen-sink-helpers-0.2.9.tgz#a5e0986ed8d76fb5984b68c3f0450d3a96e36ecc" + dependencies: + glob "^5.0.10" + mkdirp "^0.5.1" + +broccoli-kitchen-sink-helpers@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/broccoli-kitchen-sink-helpers/-/broccoli-kitchen-sink-helpers-0.3.1.tgz#77c7c18194b9664163ec4fcee2793444926e0c06" + dependencies: + glob "^5.0.10" + mkdirp "^0.5.1" + +broccoli-merge-trees@^1.0.0, broccoli-merge-trees@^1.1.0, broccoli-merge-trees@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/broccoli-merge-trees/-/broccoli-merge-trees-1.1.4.tgz#ab9eafd30b0dd8136e882ffd8fb08f3817533ea0" + dependencies: + broccoli-plugin "^1.0.0" + can-symlink "^1.0.0" + fast-ordered-set "^1.0.2" + fs-tree-diff "^0.5.2" + heimdalljs "^0.2.1" + heimdalljs-logger "^0.1.7" + rimraf "^2.4.3" + symlink-or-copy "^1.0.0" + +broccoli-persistent-filter@^1.0.1, broccoli-persistent-filter@^1.0.3, broccoli-persistent-filter@^1.1.6, broccoli-persistent-filter@^1.2.0: + version "1.2.11" + resolved "https://registry.yarnpkg.com/broccoli-persistent-filter/-/broccoli-persistent-filter-1.2.11.tgz#95cc6b0b0eb0dcce5f8e6ae18f6a3cc45a06bf40" + dependencies: + async-disk-cache "^1.0.0" + blank-object "^1.0.1" + broccoli-plugin "^1.0.0" + fs-tree-diff "^0.5.2" + hash-for-dep "^1.0.2" + heimdalljs "^0.2.1" + heimdalljs-logger "^0.1.7" + md5-hex "^1.0.2" + mkdirp "^0.5.1" + promise-map-series "^0.2.1" + rsvp "^3.0.18" + symlink-or-copy "^1.0.1" + walk-sync "^0.3.1" + +broccoli-plugin@^1.0.0, broccoli-plugin@^1.2.0, broccoli-plugin@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/broccoli-plugin/-/broccoli-plugin-1.2.2.tgz#0ed4320c20344487d0a2afafb963d52ee5179ab0" + dependencies: + promise-map-series "^0.2.1" + quick-temp "^0.1.3" + rimraf "^2.3.4" + symlink-or-copy "^1.0.1" + +broccoli-plugin@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/broccoli-plugin/-/broccoli-plugin-1.1.0.tgz#73e2cfa05f8ea1e3fc1420c40c3d9e7dc724bf02" + dependencies: + promise-map-series "^0.2.1" + quick-temp "^0.1.3" + rimraf "^2.3.4" + symlink-or-copy "^1.0.1" + +broccoli-sane-watcher@^1.1.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/broccoli-sane-watcher/-/broccoli-sane-watcher-1.1.5.tgz#f2b0af9cf0afb74c7a49cd88eb11c6869ee8c0c0" + dependencies: + broccoli-slow-trees "^1.1.0" + debug "^2.1.0" + rsvp "^3.0.18" + sane "^1.1.1" + +broccoli-sass-source-maps@^1.8.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/broccoli-sass-source-maps/-/broccoli-sass-source-maps-1.8.1.tgz#115e32be25dc5f1686af1c8d1fa4c4c62749f0b6" + dependencies: + broccoli-caching-writer "^3.0.3" + include-path-searcher "^0.1.0" + mkdirp "^0.3.5" + node-sass "^3.8.0" + object-assign "^2.0.0" + rsvp "^3.0.6" + +broccoli-slow-trees@^1.0.0, broccoli-slow-trees@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/broccoli-slow-trees/-/broccoli-slow-trees-1.1.0.tgz#426c5724e008107e4573f73e8a9ca702916b78f7" + +broccoli-source@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/broccoli-source/-/broccoli-source-1.1.0.tgz#54f0e82c8b73f46580cbbc4f578f0b32fca8f809" + +broccoli-sri-hash@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/broccoli-sri-hash/-/broccoli-sri-hash-2.1.2.tgz#bc69905ed7a381ad325cc0d02ded071328ebf3f3" + dependencies: + broccoli-caching-writer "^2.2.0" + mkdirp "^0.5.1" + rsvp "^3.1.0" + sri-toolbox "^0.2.0" + symlink-or-copy "^1.0.1" + +broccoli-stew@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/broccoli-stew/-/broccoli-stew-1.4.0.tgz#1bdb0a1804d62a419d190abc26acb3c91878154d" + dependencies: + broccoli-funnel "^1.0.1" + broccoli-merge-trees "^1.0.0" + broccoli-persistent-filter "^1.1.6" + chalk "^1.1.3" + debug "^2.1.0" + ensure-posix-path "^1.0.1" + fs-extra "^0.30.0" + minimatch "^3.0.2" + resolve "^1.1.6" + rsvp "^3.0.16" + walk-sync "^0.3.0" + +broccoli-uglify-sourcemap@^1.0.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/broccoli-uglify-sourcemap/-/broccoli-uglify-sourcemap-1.4.2.tgz#1e280afbdfaa700b2f42155f6c4a036c37e61ca7" + dependencies: + broccoli-plugin "^1.2.1" + debug "^2.2.0" + lodash.merge "^4.5.1" + matcher-collection "^1.0.0" + mkdirp "^0.5.0" + source-map-url "^0.3.0" + symlink-or-copy "^1.0.1" + uglify-js "^2.6.0" + walk-sync "^0.1.3" + +broccoli-viz@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/broccoli-viz/-/broccoli-viz-2.0.1.tgz#3f3ed2fb83e368aa5306fae460801dea552e40db" + +broccoli-writer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/broccoli-writer/-/broccoli-writer-0.1.1.tgz#d4d71aa8f2afbc67a3866b91a2da79084b96ab2d" + dependencies: + quick-temp "^0.1.0" + rsvp "^3.0.6" + +browserslist@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-0.4.0.tgz#3bd4ab9199dc1b9150d4d6dba4d9d3aabbc86dd4" + dependencies: + caniuse-db "^1.0.30000153" + +bser@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bser/-/bser-1.0.2.tgz#381116970b2a6deea5646dd15dd7278444b56169" + dependencies: + node-int64 "^0.4.0" + +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +builtins@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-0.0.7.tgz#355219cd6cf18dbe7c01cc7fd2dce765cfdc549a" + +bytes@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.2.0.tgz#fd35464a403f6f9117c2de3609ecff9cae000588" + +bytes@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.3.0.tgz#d5b680a165b6201739acb611542aabc2d8ceb070" + +bytes@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" + +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^1.0.2, camelcase@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + +can-symlink@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/can-symlink/-/can-symlink-1.0.0.tgz#97b607d8a84bb6c6e228b902d864ecb594b9d219" + dependencies: + tmp "0.0.28" + +caniuse-db@^1.0.30000153, caniuse-db@^1.0.30000214: + version "1.0.30000559" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000559.tgz#afbd68916dd23bfd549c26520c78631fb5e2e393" + +cardinal@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-0.5.0.tgz#00d5f661dbd4aabfdf7d41ce48a5a59bca35a291" + dependencies: + ansicolors "~0.2.1" + redeyed "~0.5.0" + +cardinal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-1.0.0.tgz#50e21c1b0aa37729f9377def196b5a9cec932ee9" + dependencies: + ansicolors "~0.2.1" + redeyed "~1.0.0" + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chalk@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" + dependencies: + ansi-styles "^1.1.0" + escape-string-regexp "^1.0.0" + has-ansi "^0.1.0" + strip-ansi "^0.3.0" + supports-color "^0.2.0" + +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + +char-spinner@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/char-spinner/-/char-spinner-1.0.1.tgz#e6ea67bd247e107112983b7ab0479ed362800081" + +charm@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/charm/-/charm-1.0.1.tgz#68566a7a553d4fe91797030dd1852d0dd6efa82d" + dependencies: + inherits "^2.0.1" + +chmodr@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chmodr/-/chmodr-1.0.2.tgz#04662b932d0f02ec66deaa2b0ea42811968e3eb9" + +chownr@^1.0.1, chownr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + +clean-base-url@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clean-base-url/-/clean-base-url-1.0.0.tgz#c901cf0a20b972435b0eccd52d056824a4351b7b" + +clean-css-promise@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/clean-css-promise/-/clean-css-promise-0.1.1.tgz#43f3d2c8dfcb2bf071481252cd9b76433c08eecb" + dependencies: + array-to-error "^1.0.0" + clean-css "^3.4.5" + pinkie-promise "^2.0.0" + +clean-css@^3.4.5: + version "3.4.20" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.20.tgz#c0d8963b5448e030f0bcd3ddd0dac4dfe3dea501" + dependencies: + commander "2.8.x" + source-map "0.4.x" + +cli-cursor@^1.0.1, cli-cursor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-spinners@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" + +cli-table@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" + dependencies: + colors "1.0.3" + +cli-table2@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/cli-table2/-/cli-table2-0.2.0.tgz#2d1ef7f218a0e786e214540562d4bd177fe32d97" + dependencies: + lodash "^3.10.1" + string-width "^1.0.1" + optionalDependencies: + colors "^1.1.2" + +cli-usage@^0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/cli-usage/-/cli-usage-0.1.4.tgz#7c01e0dc706c234b39c933838c8e20b2175776e2" + dependencies: + marked "^0.3.6" + marked-terminal "^1.6.2" + +cli-width@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" + +cli@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli/-/cli-1.0.0.tgz#ee07dfc1390e3f2e6a9957cf88e1d4bfa777719d" + dependencies: + exit "0.1.2" + glob "^7.0.5" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +clone@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" + +clone@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" + +cmd-shim@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" + dependencies: + graceful-fs "^4.1.2" + mkdirp "~0.5.0" + +code-point-at@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.0.1.tgz#1104cd34f9b5b45d3eba88f1babc1924e1ce35fb" + dependencies: + number-is-nan "^1.0.0" + +colors@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + +colors@~0.6.0-1: + version "0.6.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc" + +colors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + +columnify@~1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" + dependencies: + strip-ansi "^3.0.0" + wcwidth "^1.0.0" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +commander@^2.5.0, commander@^2.6.0, commander@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + +commander@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.1.0.tgz#d121bbae860d9992a3d517ba96f56588e47c6781" + +commander@2.8.x: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + dependencies: + graceful-readlink ">= 1.0.0" + +commoner@~0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/commoner/-/commoner-0.10.4.tgz#98f3333dd3ad399596bb2d384a783bb7213d68f8" + dependencies: + commander "^2.5.0" + detective "^4.3.1" + glob "^5.0.15" + graceful-fs "^4.1.2" + iconv-lite "^0.4.5" + mkdirp "^0.5.0" + private "^0.1.6" + q "^1.1.2" + recast "^0.10.0" + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + +component-emitter@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.1.2.tgz#296594f2753daa63996d2af08d15a95116c9aec3" + +component-emitter@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.0.tgz#ccd113a86388d06482d03de3fc7df98526ba8efe" + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + +compressible@~2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.8.tgz#7162e6c46d3b9d200ffb45cb4e4a0f7832732503" + dependencies: + mime-db ">= 1.23.0 < 2" + +compression@^1.4.4: + version "1.6.2" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.6.2.tgz#cceb121ecc9d09c52d7ad0c3350ea93ddd402bc3" + dependencies: + accepts "~1.3.3" + bytes "2.3.0" + compressible "~2.0.8" + debug "~2.2.0" + on-headers "~1.0.1" + vary "~1.1.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.4.6, concat-stream@^1.4.7: + version "1.5.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" + dependencies: + inherits "~2.0.1" + readable-stream "~2.0.0" + typedarray "~0.0.5" + +config-chain@~1.1.10: + version "1.1.11" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.11.tgz#aba09747dfbe4c3e70e766a6e41586e1859fc6f2" + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +configstore@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-2.1.0.tgz#737a3a7036e9886102aa6099e47bb33ab1aba1a1" + dependencies: + dot-prop "^3.0.0" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + object-assign "^4.0.1" + os-tmpdir "^1.0.0" + osenv "^0.1.0" + uuid "^2.0.1" + write-file-atomic "^1.1.2" + xdg-basedir "^2.0.0" + +connect@^3.3.3: + version "3.5.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.5.0.tgz#b357525a0b4c1f50599cd983e1d9efeea9677198" + dependencies: + debug "~2.2.0" + finalhandler "0.5.0" + parseurl "~1.3.1" + utils-merge "1.0.0" + +console-browserify@1.1.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +consolidate@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.14.1.tgz#506d529ef7e211624d2e4a5f337df8be136ef727" + dependencies: + bluebird "^3.1.1" + +content-disposition@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.1.tgz#87476c6a67c8daa87e32e87616df883ba7fb071b" + +content-type@~1.0.1, content-type@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" + +convert-source-map@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.3.0.tgz#e9f3e9c6e2728efc2676696a70eb382f73106a67" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + +copy-dereference@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/copy-dereference/-/copy-dereference-1.0.0.tgz#6b131865420fd81b413ba994b44d3655311152b6" + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + +core-object@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/core-object/-/core-object-1.1.0.tgz#86d63918733cf9da1a5aae729e62c0a88e66ad0a" + +core-object@^2.0.2: + version "2.0.6" + resolved "https://registry.yarnpkg.com/core-object/-/core-object-2.0.6.tgz#60134b9c40ff69b27bc15e82db945e4df782961b" + dependencies: + chalk "^1.1.3" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + dependencies: + array-find-index "^1.0.1" + +d@^0.1.1, d@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309" + dependencies: + es5-ext "~0.10.2" + +dashdash@^1.12.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.0.tgz#29e486c5418bf0f356034a993d51686a33e84141" + dependencies: + assert-plus "^1.0.0" + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + +debug@^2.1.0, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@~2.2.0, debug@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +debug@0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" + +debuglog@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + dependencies: + clone "^1.0.2" + +defined@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + +defs@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/defs/-/defs-1.1.1.tgz#b22609f2c7a11ba7a3db116805c139b1caffa9d2" + dependencies: + alter "~0.2.0" + ast-traverse "~0.1.1" + breakable "~1.0.0" + esprima-fb "~15001.1001.0-dev-harmony-fb" + simple-fmt "~0.1.0" + simple-is "~0.2.0" + stringmap "~0.2.2" + stringset "~0.2.1" + tryor "~0.1.2" + yargs "~3.27.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +depd@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + +detect-indent@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-3.0.1.tgz#9dc5e5ddbceef8325764b9451b02bc6d54084f75" + dependencies: + get-stdin "^4.0.1" + minimist "^1.1.0" + repeating "^1.1.0" + +detective@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/detective/-/detective-4.3.1.tgz#9fb06dd1ee8f0ea4dbcc607cda39d9ce1d4f726f" + dependencies: + acorn "^1.0.3" + defined "^1.0.0" + +dezalgo@^1.0.0, dezalgo@^1.0.1, dezalgo@^1.0.2, dezalgo@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" + dependencies: + asap "^2.0.0" + wrappy "1" + +did_it_work@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/did_it_work/-/did_it_work-0.0.6.tgz#5180cb9e16ebf9a8753a0cc6b4af9ccdff71ec05" + +diff@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" + +dom-serializer@0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" + dependencies: + domelementtype "~1.1.1" + entities "~1.1.1" + +domelementtype@~1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" + +domelementtype@1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" + +domhandler@2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" + dependencies: + domelementtype "1" + +domutils@1.5: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + dependencies: + dom-serializer "0" + domelementtype "1" + +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + dependencies: + is-obj "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +editions@^1.1.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.1.tgz#008425f64dc1401db45ec110e06aa602562419c0" + +editor@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +ember-ajax@^2.0.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/ember-ajax/-/ember-ajax-2.5.2.tgz#aefd6f860b03ab75c97e73ed410aa9e371ea88c6" + dependencies: + ember-cli-babel "^5.1.5" + +ember-cli-app-version@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-app-version/-/ember-cli-app-version-2.0.0.tgz#18ad746c5c05e8556823fe6e779191419e967c36" + dependencies: + ember-cli-babel "^5.1.6" + ember-cli-htmlbars "^1.0.0" + git-repo-version "0.4.0" + +ember-cli-babel@^5.0.0, ember-cli-babel@^5.1.10, ember-cli-babel@^5.1.3, ember-cli-babel@^5.1.5, ember-cli-babel@^5.1.6, ember-cli-babel@5.1.10: + version "5.1.10" + resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-5.1.10.tgz#d403f178aab602e1337c403c5a58c0200a8969aa" + dependencies: + broccoli-babel-transpiler "^5.6.0" + broccoli-funnel "^1.0.0" + clone "^1.0.2" + ember-cli-version-checker "^1.0.2" + resolve "^1.1.2" + +ember-cli-broccoli@0.16.10: + version "0.16.10" + resolved "https://registry.yarnpkg.com/ember-cli-broccoli/-/ember-cli-broccoli-0.16.10.tgz#e1f6fb204fc04bba836edaf3fdd07f4bec868d1b" + dependencies: + broccoli-kitchen-sink-helpers "^0.2.5" + broccoli-slow-trees "^1.0.0" + commander "^2.5.0" + connect "^3.3.3" + copy-dereference "^1.0.0" + findup-sync "^0.2.1" + handlebars "^4.0.4" + mime "^1.2.11" + promise-map-series "^0.2.1" + quick-temp "^0.1.2" + rimraf "^2.2.8" + rsvp "^3.0.17" + +ember-cli-dependency-checker@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ember-cli-dependency-checker/-/ember-cli-dependency-checker-1.3.0.tgz#f0e8cb7f0f43c1e560494eaa9372804e7a088a2a" + dependencies: + chalk "^0.5.1" + is-git-url "0.2.0" + semver "^4.1.0" + +ember-cli-get-component-path-option@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-get-component-path-option/-/ember-cli-get-component-path-option-1.0.0.tgz#0d7b595559e2f9050abed804f1d8eff1b08bc771" + +ember-cli-get-dependency-depth@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-get-dependency-depth/-/ember-cli-get-dependency-depth-1.0.0.tgz#e0afecf82a2d52f00f28ab468295281aec368d11" + +ember-cli-htmlbars-inline-precompile@^0.3.1: + version "0.3.5" + resolved "https://registry.yarnpkg.com/ember-cli-htmlbars-inline-precompile/-/ember-cli-htmlbars-inline-precompile-0.3.5.tgz#79316c0f9bad9ae702cb4801b6c670d21b264345" + dependencies: + babel-plugin-htmlbars-inline-precompile "^0.1.0" + ember-cli-babel "^5.1.3" + ember-cli-htmlbars "^1.0.0" + hash-for-dep "^1.0.2" + +ember-cli-htmlbars@^1.0.0, ember-cli-htmlbars@^1.0.1, ember-cli-htmlbars@^1.0.3, ember-cli-htmlbars@^1.0.8: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-1.1.0.tgz#0d6bd1e8fa94d00edbe438f15dd59d1700a544d1" + dependencies: + broccoli-persistent-filter "^1.0.3" + ember-cli-version-checker "^1.0.2" + hash-for-dep "^1.0.2" + json-stable-stringify "^1.0.0" + strip-bom "^2.0.0" + +ember-cli-inject-live-reload@^1.3.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/ember-cli-inject-live-reload/-/ember-cli-inject-live-reload-1.4.1.tgz#ddadb9a346c5ed694ec0f9e11f49994eacafd277" + +ember-cli-is-package-missing@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-is-package-missing/-/ember-cli-is-package-missing-1.0.0.tgz#6e6184cafb92635dd93ca6c946b104292d4e3390" + +ember-cli-legacy-blueprints@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ember-cli-legacy-blueprints/-/ember-cli-legacy-blueprints-0.1.2.tgz#802aee80b2ef18a24533c0f05cfcb5ad009aa471" + dependencies: + chalk "^1.1.1" + ember-cli-get-component-path-option "^1.0.0" + ember-cli-get-dependency-depth "^1.0.0" + ember-cli-is-package-missing "^1.0.0" + ember-cli-lodash-subset "^1.0.7" + ember-cli-normalize-entity-name "^1.0.0" + ember-cli-path-utils "^1.0.0" + ember-cli-string-utils "^1.0.0" + ember-cli-test-info "^1.0.0" + ember-cli-valid-component-name "^1.0.0" + ember-router-generator "^1.0.0" + exists-sync "0.0.3" + fs-extra "^0.24.0" + inflection "^1.7.1" + rsvp "^3.0.17" + silent-error "^1.0.0" + +ember-cli-lodash-subset@^1.0.1, ember-cli-lodash-subset@^1.0.7: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ember-cli-lodash-subset/-/ember-cli-lodash-subset-1.0.11.tgz#0149eef9c0c3505ba44ed202f8d034ddbbfb2826" + +ember-cli-normalize-entity-name@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-normalize-entity-name/-/ember-cli-normalize-entity-name-1.0.0.tgz#0b14f7bcbc599aa117b5fddc81e4fd03c4bad5b7" + dependencies: + silent-error "^1.0.0" + +ember-cli-nouislider@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/ember-cli-nouislider/-/ember-cli-nouislider-0.10.0.tgz#94bda98cc3d8809cbceb41cdf151b715528e5570" + dependencies: + ember-cli-babel "^5.1.6" + ember-cli-htmlbars "^1.0.3" + +ember-cli-path-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-path-utils/-/ember-cli-path-utils-1.0.0.tgz#4e39af8b55301cddc5017739b77a804fba2071ed" + +ember-cli-preprocess-registry@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-preprocess-registry/-/ember-cli-preprocess-registry-2.0.0.tgz#45c8b985eba06bb443b3abce1c3c6220fdcb8094" + dependencies: + broccoli-clean-css "^1.1.0" + broccoli-funnel "^1.0.0" + broccoli-merge-trees "^1.0.0" + debug "^2.2.0" + exists-sync "0.0.3" + lodash "^3.10.0" + process-relative-require "^1.0.0" + silent-error "^1.0.0" + +ember-cli-qunit@^1.2.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/ember-cli-qunit/-/ember-cli-qunit-1.4.2.tgz#7ca25495c70ca347106d44fc00f0d7aeca027475" + dependencies: + broccoli-babel-transpiler "^5.5.0" + broccoli-concat "^2.2.0" + broccoli-jshint "^1.0.0" + broccoli-merge-trees "^1.1.0" + ember-cli-babel "^5.1.5" + ember-cli-version-checker "^1.1.4" + ember-qunit "^0.4.18" + qunitjs "^1.20.0" + resolve "^1.1.6" + +ember-cli-release@0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/ember-cli-release/-/ember-cli-release-0.2.8.tgz#e9fddd06058c0f3bc2ea57ab2667e9611f8fb205" + dependencies: + chalk "^1.0.0" + git-tools "^0.1.4" + make-array "^0.1.2" + merge "^1.2.0" + moment-timezone "^0.3.0" + nopt "^3.0.3" + rsvp "^3.0.17" + semver "^4.3.1" + silent-error "^1.0.0" + +ember-cli-sass@^5.2.1: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ember-cli-sass/-/ember-cli-sass-5.5.2.tgz#7430cb3c9cb99d0888532c1c6be56fc879c42977" + dependencies: + broccoli-merge-trees "^1.1.0" + broccoli-sass-source-maps "^1.8.0" + ember-cli-babel "5.1.10" + ember-cli-version-checker "^1.0.2" + merge "^1.2.0" + +ember-cli-sri@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ember-cli-sri/-/ember-cli-sri-2.1.1.tgz#971620934a4b9183cf7923cc03e178b83aa907fd" + dependencies: + broccoli-sri-hash "^2.1.0" + +ember-cli-string-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-string-utils/-/ember-cli-string-utils-1.0.0.tgz#d07b17d0b6223c42e09bfb835ee2b8466ec9b88e" + +ember-cli-test-info@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-test-info/-/ember-cli-test-info-1.0.0.tgz#ed4e960f249e97523cf891e4aed2072ce84577b4" + dependencies: + ember-cli-string-utils "^1.0.0" + +ember-cli-test-loader@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ember-cli-test-loader/-/ember-cli-test-loader-1.1.0.tgz#54850145b311e7ac0f990cbd461a028012700441" + +ember-cli-uglify@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ember-cli-uglify/-/ember-cli-uglify-1.2.0.tgz#3208c32b54bc2783056e8bb0d5cfe9bbaf17ffb2" + dependencies: + broccoli-uglify-sourcemap "^1.0.0" + +ember-cli-valid-component-name@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-valid-component-name/-/ember-cli-valid-component-name-1.0.0.tgz#71550ce387e0233065f30b30b1510aa2dfbe87ef" + dependencies: + silent-error "^1.0.0" + +ember-cli-version-checker@^1.0.2, ember-cli-version-checker@^1.1.4, ember-cli-version-checker@^1.1.6: + version "1.1.7" + resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-1.1.7.tgz#cbabacb5eef2635048d5208fab05b032e5313d1a" + dependencies: + semver "^4.2.2" + +ember-cli@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/ember-cli/-/ember-cli-2.8.0.tgz#7c503a49cbd8423ba58403e222056bdfb79a985a" + dependencies: + amd-name-resolver "0.0.5" + bower "^1.3.12" + bower-config "^1.3.0" + bower-endpoint-parser "0.2.2" + broccoli-babel-transpiler "^5.4.5" + broccoli-concat "^2.0.4" + broccoli-config-loader "^1.0.0" + broccoli-config-replace "^1.1.2" + broccoli-funnel "^1.0.3" + broccoli-funnel-reducer "^1.0.0" + broccoli-merge-trees "^1.1.2" + broccoli-sane-watcher "^1.1.1" + broccoli-source "^1.1.0" + broccoli-viz "^2.0.1" + chalk "^1.1.3" + clean-base-url "^1.0.0" + compression "^1.4.4" + configstore "^2.0.0" + core-object "^2.0.2" + debug "^2.1.3" + diff "^1.3.1" + ember-cli-broccoli "0.16.10" + ember-cli-get-component-path-option "^1.0.0" + ember-cli-is-package-missing "^1.0.0" + ember-cli-legacy-blueprints "^0.1.1" + ember-cli-lodash-subset "^1.0.1" + ember-cli-normalize-entity-name "^1.0.0" + ember-cli-preprocess-registry "^2.0.0" + ember-cli-string-utils "^1.0.0" + ember-try "^0.2.2" + escape-string-regexp "^1.0.3" + exists-sync "0.0.3" + exit "^0.1.2" + express "^4.12.3" + filesize "^3.1.3" + find-up "^1.1.2" + fs-extra "0.30.0" + fs-monitor-stack "^1.0.2" + fs-tree-diff "^0.5.0" + get-caller-file "^1.0.0" + git-repo-info "^1.0.4" + glob "7.0.5" + http-proxy "^1.9.0" + inflection "^1.7.0" + inquirer "^1.0.2" + is-git-url "^0.2.0" + isbinaryfile "^3.0.0" + leek "0.0.22" + lodash "^4.12.0" + lodash.template "^4.2.5" + markdown-it "7.0.0" + markdown-it-terminal "0.0.3" + minimatch "^3.0.0" + morgan "^1.5.2" + node-modules-path "^1.0.0" + node-uuid "^1.4.3" + nopt "^3.0.1" + npm "2.15.5" + npm-package-arg "^4.1.1" + ora "^0.2.0" + portfinder "^1.0.4" + promise-map-series "^0.2.1" + quick-temp "0.1.5" + resolve "^1.1.6" + rsvp "^3.0.17" + sane "^1.1.1" + semver "^5.1.1" + silent-error "^1.0.0" + symlink-or-copy "^1.0.1" + temp "0.8.3" + testem "^1.8.1" + through "^2.3.6" + tiny-lr "0.2.1" + tree-sync "^1.1.0" + walk-sync "^0.2.6" + yam "0.0.21" + +ember-css-transitions@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/ember-css-transitions/-/ember-css-transitions-0.1.5.tgz#0c57917b89e7c39d37f4435b8fb18fca0acccf73" + dependencies: + ember-cli-babel "^5.1.6" + +ember-export-application-global@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ember-export-application-global/-/ember-export-application-global-1.1.1.tgz#f257d5271268932a89d7392679ce4db89d7154af" + dependencies: + ember-cli-babel "^5.1.10" + +ember-load-initializers@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/ember-load-initializers/-/ember-load-initializers-0.5.1.tgz#76e3db23c111dbdcd3ae6f687036bf0b56be0cbe" + +ember-modal-dialog@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/ember-modal-dialog/-/ember-modal-dialog-0.9.0.tgz#e2797762f13eea5aa71524c1ec516c150980b287" + dependencies: + ember-cli-babel "^5.1.6" + ember-cli-htmlbars "^1.0.8" + ember-cli-version-checker "^1.1.6" + ember-wormhole "~0.3.6" + +ember-notify@^5.0.4: + version "5.1.6" + resolved "https://registry.yarnpkg.com/ember-notify/-/ember-notify-5.1.6.tgz#5f728d3ecc792a839cb549fe3ed0f019fed2c706" + dependencies: + ember-cli-babel "^5.1.6" + ember-cli-htmlbars "^1.0.3" + ember-string-ishtmlsafe-polyfill "1.0.1" + +ember-paper@^1.0.0-alpha.5: + version "1.0.0-alpha.5" + resolved "https://registry.yarnpkg.com/ember-paper/-/ember-paper-1.0.0-alpha.5.tgz#fc9fd3796dd9c6b2f1bb8bb87094702ef3ec07f7" + dependencies: + angular-material-source angular/material#v1.0.6 + broccoli-autoprefixer "^3.0.0" + broccoli-filter "^1.2.3" + broccoli-funnel "^1.0.1" + broccoli-merge-trees "^1.1.0" + ember-cli-babel "^5.1.6" + ember-css-transitions "0.1.5" + ember-wormhole "0.4.1" + +ember-qunit@^0.4.18: + version "0.4.22" + resolved "https://registry.yarnpkg.com/ember-qunit/-/ember-qunit-0.4.22.tgz#bc389798e1a4a933f542863025e2fb91d856da49" + dependencies: + ember-test-helpers "^0.5.32" + +ember-resolver@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ember-resolver/-/ember-resolver-2.1.0.tgz#e6d249d3b5806468c0ba2c67ccecf7aa24b754bf" + dependencies: + ember-cli-babel "^5.1.3" + ember-cli-version-checker "^1.1.4" + +ember-router-generator@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/ember-router-generator/-/ember-router-generator-1.2.2.tgz#62dac1f63e873553e6d4c7e32da6589e577bcf63" + dependencies: + recast "^0.11.3" + +ember-string-ishtmlsafe-polyfill@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ember-string-ishtmlsafe-polyfill/-/ember-string-ishtmlsafe-polyfill-1.0.1.tgz#b40a8c98663be5c16d16f31dc686102bb655abbd" + dependencies: + ember-cli-babel "^5.1.6" + +ember-test-helpers@^0.5.32: + version "0.5.34" + resolved "https://registry.yarnpkg.com/ember-test-helpers/-/ember-test-helpers-0.5.34.tgz#c8439108d1cba1d7d838c212208a5c4061471b83" + dependencies: + klassy "^0.1.3" + +ember-truth-helpers@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ember-truth-helpers/-/ember-truth-helpers-1.2.0.tgz#e63cffeaa8211882ae61a958816fded3790d065b" + dependencies: + ember-cli-babel "^5.1.5" + +ember-try-config@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ember-try-config/-/ember-try-config-2.1.0.tgz#e0e156229a542346a58ee6f6ad605104c98edfe0" + dependencies: + lodash "^4.6.1" + node-fetch "^1.3.3" + rsvp "^3.2.1" + semver "^5.1.0" + +ember-try@^0.2.2: + version "0.2.6" + resolved "https://registry.yarnpkg.com/ember-try/-/ember-try-0.2.6.tgz#10a0a694dc0178e45385077e035b1fd86f7cca03" + dependencies: + chalk "^1.0.0" + cli-table2 "^0.2.0" + core-object "^1.1.0" + debug "^2.2.0" + ember-cli-babel "^5.1.3" + ember-cli-version-checker "^1.1.6" + ember-try-config "^2.0.1" + extend "^3.0.0" + fs-extra "^0.26.0" + promise-map-series "^0.2.1" + resolve "^1.1.6" + rimraf "^2.3.2" + rsvp "^3.0.17" + semver "^5.1.0" + sync-exec "^0.6.2" + +ember-wormhole@~0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/ember-wormhole/-/ember-wormhole-0.3.6.tgz#bbe21bb5478ad254efe4fff4019ac6710f4ad85c" + dependencies: + ember-cli-babel "^5.0.0" + +ember-wormhole@0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/ember-wormhole/-/ember-wormhole-0.4.1.tgz#55fafaad20a650d21f6583a0e59c060a65338111" + dependencies: + ember-cli-babel "^5.1.6" + ember-cli-htmlbars "^1.0.3" + +encodeurl@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +engine.io-client@1.6.9: + version "1.6.9" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.6.9.tgz#1d6ad48048a5083c95096943b29d36efdb212401" + dependencies: + component-emitter "1.1.2" + component-inherit "0.0.3" + debug "2.2.0" + engine.io-parser "1.2.4" + has-cors "1.1.0" + indexof "0.0.1" + parsejson "0.0.1" + parseqs "0.0.2" + parseuri "0.0.4" + ws "1.0.1" + xmlhttprequest-ssl "1.5.1" + yeast "0.1.2" + +engine.io-parser@1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-1.2.4.tgz#e0897b0bf14e792d4cd2a5950553919c56948c42" + dependencies: + after "0.8.1" + arraybuffer.slice "0.0.6" + base64-arraybuffer "0.1.2" + blob "0.0.4" + has-binary "0.1.6" + utf8 "2.1.0" + +engine.io@1.6.10: + version "1.6.10" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.6.10.tgz#f87d84e1bd21d1a2ec7f8deef0c62054acdfb27a" + dependencies: + accepts "1.1.4" + base64id "0.1.0" + debug "2.2.0" + engine.io-parser "1.2.4" + ws "1.0.1" + +ensure-posix-path@^1.0.0, ensure-posix-path@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ensure-posix-path/-/ensure-posix-path-1.0.2.tgz#a65b3e42d0b71cfc585eb774f9943c8d9b91b0c2" + +entities@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" + +entities@1.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" + +error-ex@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.0.tgz#e67b43f3e82c96ea3a584ffee0b9fc3325d802d9" + dependencies: + is-arrayish "^0.2.1" + +es5-ext@^0.10.7, es5-ext@~0.10.11, es5-ext@~0.10.2: + version "0.10.12" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047" + dependencies: + es6-iterator "2" + es6-symbol "~3.1" + +es6-iterator@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.0.tgz#bd968567d61635e33c0b80727613c9cb4b096bac" + dependencies: + d "^0.1.1" + es5-ext "^0.10.7" + es6-symbol "3" + +es6-promise@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-2.3.0.tgz#96edb9f2fdb01995822b263dd8aadab6748181bc" + +es6-symbol@^3.0.2, es6-symbol@~3.1, es6-symbol@3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.0.tgz#94481c655e7a7cad82eba832d97d5433496d7ffa" + dependencies: + d "~0.1.1" + es5-ext "~0.10.11" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +esprima-fb@~12001.1.0-dev-harmony-fb: + version "12001.1.0-dev-harmony-fb" + resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-12001.1.0-dev-harmony-fb.tgz#d84400384ba95ce2678c617ad24a7f40808da915" + +esprima-fb@~15001.1001.0-dev-harmony-fb: + version "15001.1001.0-dev-harmony-fb" + resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz#43beb57ec26e8cf237d3dd8b33e42533577f2659" + +esprima@^2.6.0, esprima@~2.7.0: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + +esprima@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.0.0.tgz#53cf247acda77313e551c3aa2e73342d3fb4f7d9" + +esutils@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +etag@~1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.7.0.tgz#03d30b5f67dd6e632d2945d30d6652731a34d5d8" + +eventemitter3@1.x.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" + +events-to-array@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/events-to-array/-/events-to-array-1.0.2.tgz#b3484465534fe4ff66fbdd1a83b777713ba404aa" + +exec-sh@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.0.tgz#14f75de3f20d286ef933099b2ce50a90359cef10" + dependencies: + merge "^1.1.3" + +exists-sync@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/exists-sync/-/exists-sync-0.0.3.tgz#b910000bedbb113b378b82f5f5a7638107622dcf" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + +exit@^0.1.2, exit@0.1.2, exit@0.1.x: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + +express@^4.10.7, express@^4.12.3: + version "4.14.0" + resolved "https://registry.yarnpkg.com/express/-/express-4.14.0.tgz#c1ee3f42cdc891fb3dc650a8922d51ec847d0d66" + dependencies: + accepts "~1.3.3" + array-flatten "1.1.1" + content-disposition "0.5.1" + content-type "~1.0.2" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "~2.2.0" + depd "~1.1.0" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.7.0" + finalhandler "0.5.0" + fresh "0.3.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.1" + path-to-regexp "0.1.7" + proxy-addr "~1.1.2" + qs "6.2.0" + range-parser "~1.2.0" + send "0.14.1" + serve-static "~1.11.1" + type-is "~1.6.13" + utils-merge "1.0.0" + vary "~1.1.0" + +extend@^3.0.0, extend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" + +external-editor@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-1.1.0.tgz#c7fe15954b09af852b89aaec82a2707a0dc5597a" + dependencies: + extend "^3.0.0" + spawn-sync "^1.0.15" + temp "^0.8.3" + +extsprintf@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" + +fast-ordered-set@^1.0.0, fast-ordered-set@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fast-ordered-set/-/fast-ordered-set-1.0.3.tgz#3fbb36634f7be79e4f7edbdb4a357dee25d184eb" + dependencies: + blank-object "^1.0.1" + +fast-sourcemap-concat@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-sourcemap-concat/-/fast-sourcemap-concat-1.1.0.tgz#a800767abed5eda02e67238ec063a709be61f9d4" + dependencies: + chalk "^0.5.1" + debug "^2.2.0" + fs-extra "^0.30.0" + memory-streams "^0.1.0" + mkdirp "^0.5.0" + rsvp "^3.0.14" + source-map "^0.4.2" + source-map-url "^0.3.0" + +faye-websocket@~0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + dependencies: + websocket-driver ">=0.5.1" + +fb-watchman@^1.8.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-1.9.0.tgz#6f268f1f347a6b3c875d1e89da7e1ed79adfc0ec" + dependencies: + bser "^1.0.2" + +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +filesize@^3.1.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.3.0.tgz#53149ea3460e3b2e024962a51648aa572cf98122" + +finalhandler@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.5.0.tgz#e9508abece9b6dba871a6942a1d7911b91911ac7" + dependencies: + debug "~2.2.0" + escape-html "~1.0.3" + on-finished "~2.3.0" + statuses "~1.3.0" + unpipe "~1.0.0" + +find-up@^1.0.0, find-up@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +findup-sync@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.2.1.tgz#e0a90a450075c49466ee513732057514b81e878c" + dependencies: + glob "~4.3.0" + +findup-sync@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.3.0.tgz#37930aa5d816b777c03445e1966cc6790a4c0b16" + dependencies: + glob "~5.0.0" + +findup@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/findup/-/findup-0.1.5.tgz#8ad929a3393bac627957a7e5de4623b06b0e2ceb" + dependencies: + colors "~0.6.0-1" + commander "~2.1.0" + +fireworm@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/fireworm/-/fireworm-0.7.1.tgz#ccf20f7941f108883fcddb99383dbe6e1861c758" + dependencies: + async "~0.2.9" + is-type "0.0.1" + lodash.debounce "^3.1.1" + lodash.flatten "^3.0.2" + minimatch "^3.0.2" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~1.0.0-rc3: + version "1.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c" + dependencies: + async "^2.0.1" + combined-stream "^1.0.5" + mime-types "^2.1.11" + +form-data@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.0.0.tgz#6f0aebadcc5da16c13e1ecc11137d85f9b883b25" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.11" + +forwarded@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363" + +fresh@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f" + +fs-extra@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.24.0.tgz#d4e4342a96675cb7846633a6099249332b539952" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + +fs-extra@^0.26.0: + version "0.26.7" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.26.7.tgz#9ae1fdd94897798edab76d0918cf42d0c3184fa9" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + +fs-extra@^0.30.0, fs-extra@0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + +fs-monitor-stack@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fs-monitor-stack/-/fs-monitor-stack-1.1.1.tgz#c4038d5977939b6b4e38396d7e7cd0895a7ac6b3" + +fs-readdir-recursive@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz#315b4fb8c1ca5b8c47defef319d073dad3568059" + +fs-tree-diff@^0.5.0, fs-tree-diff@^0.5.2, fs-tree-diff@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/fs-tree-diff/-/fs-tree-diff-0.5.3.tgz#a7e6044bf660b49b38c484826d5a41b34ae6aa69" + dependencies: + fast-ordered-set "^1.0.2" + heimdalljs-logger "^0.1.7" + +fs-vacuum@~1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.9.tgz#4f90193ab8ea02890995bcd4e804659a5d366b2d" + dependencies: + graceful-fs "^4.1.2" + path-is-inside "^1.0.1" + rimraf "^2.5.2" + +fs-write-stream-atomic@~1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.8.tgz#e49aaddf288f87d46ff9e882f216a13abc40778b" + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fstream-ignore@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream-npm@~1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/fstream-npm/-/fstream-npm-1.0.7.tgz#7ed0d1ac13d7686dd9e1bf6ceb8be273bf6d2f86" + dependencies: + fstream-ignore "^1.0.0" + inherits "2" + +fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.10.tgz#604e8a92fe26ffd9f6fae30399d4984e1ab22822" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +gauge@~1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93" + dependencies: + ansi "^0.3.0" + has-unicode "^2.0.0" + lodash.pad "^4.1.0" + lodash.padend "^4.1.0" + lodash.padstart "^4.1.0" + +gauge@~2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.6.0.tgz#d35301ad18e96902b4751dcbbe40f4218b942a46" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-color "^0.1.7" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gaze@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.2.tgz#847224677adb8870d679257ed3388fdb61e40105" + dependencies: + globule "^1.0.0" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +get-caller-file@^1.0.0, get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + +getpass@^0.1.1: + version "0.1.6" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6" + dependencies: + assert-plus "^1.0.0" + +git-repo-info@^1.0.4: + version "1.3.0" + resolved "https://registry.yarnpkg.com/git-repo-info/-/git-repo-info-1.3.0.tgz#d49c30955cf58c0ec1acd52d26bc5b8af13afd58" + +git-repo-version@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/git-repo-version/-/git-repo-version-0.4.0.tgz#14e0ee35279a1b647bd7c28395d2c4d11e72ca2c" + dependencies: + git-repo-info "^1.0.4" + +git-tools@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/git-tools/-/git-tools-0.1.4.tgz#5e43e59443b8a5dedb39dba663da49e79f943978" + dependencies: + spawnback "~1.0.0" + +github-url-from-git@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/github-url-from-git/-/github-url-from-git-1.4.0.tgz#285e6b520819001bde128674704379e4ff03e0de" + +github-url-from-username-repo@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/github-url-from-username-repo/-/github-url-from-username-repo-1.0.2.tgz#7dd79330d2abe69c10c2cef79714c97215791dfa" + +glob@^5.0.10, glob@^5.0.15, glob@~5.0.0: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^6.0.0: + version "6.0.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@~4.3.0: + version "4.3.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-4.3.5.tgz#80fbb08ca540f238acce5d11d1e9bc41e75173d3" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "^2.0.1" + once "^1.3.0" + +glob@~7.0.3: + version "7.0.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +"glob@3 || 4": + version "4.5.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "^2.0.1" + once "^1.3.0" + +glob@7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^6.4.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/globals/-/globals-6.4.1.tgz#8498032b3b6d1cc81eebc5f79690d8fe29fabf4f" + +globule@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.0.0.tgz#f22aebaacce02be492453e979c3ae9b6983f1c6c" + dependencies: + glob "~7.0.3" + lodash "~4.9.0" + minimatch "~3.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@~4.1.4: + version "4.1.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.9.tgz#baacba37d19d11f9d146d3578bc99958c3787e29" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +growly@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + +handlebars@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.5.tgz#92c6ed6bb164110c50d4d8d0fbddc70806c6f8e7" + dependencies: + async "^1.4.0" + optimist "^0.6.1" + source-map "^0.4.4" + optionalDependencies: + uglify-js "^2.6" + +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +has-ansi@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-0.1.0.tgz#84f265aae8c0e6a88a12d7022894b7568894c62e" + dependencies: + ansi-regex "^0.2.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-binary@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.6.tgz#25326f39cfa4f616ad8787894e3af2cfbc7b6e10" + dependencies: + isarray "0.0.1" + +has-binary@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.7.tgz#68e61eb16210c9545a0a5cce06a873912fe1e68c" + dependencies: + isarray "0.0.1" + +has-color@^0.1.7, has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +hash-for-dep@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/hash-for-dep/-/hash-for-dep-1.0.3.tgz#b57f18a0ace56380951638a3b36a6b73d8619b8b" + dependencies: + broccoli-kitchen-sink-helpers "^0.3.1" + resolve "^1.1.6" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +heimdalljs-logger@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/heimdalljs-logger/-/heimdalljs-logger-0.1.7.tgz#10e340af5c22a811e34522d9b9397675ad589ca4" + dependencies: + debug "^2.2.0" + heimdalljs "^0.2.0" + +heimdalljs@^0.2.0, heimdalljs@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/heimdalljs/-/heimdalljs-0.2.1.tgz#bde5d5034bc7996f0d973f21fa2d93d6c729de19" + dependencies: + rsvp "^3.2.1" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +home-or-tmp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-1.0.0.tgz#4b9f1e40800c3e50c6c27f781676afcce71f3985" + dependencies: + os-tmpdir "^1.0.1" + user-home "^1.1.1" + +hosted-git-info@^2.1.4, hosted-git-info@^2.1.5, hosted-git-info@~2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b" + +htmlparser2@3.8.x: + version "3.8.3" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" + dependencies: + domelementtype "1" + domhandler "2.3" + domutils "1.5" + entities "1.0" + readable-stream "1.1" + +http-errors@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942" + dependencies: + inherits "~2.0.1" + statuses "1" + +http-errors@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.0.tgz#b1cb3d8260fd8e2386cad3189045943372d48211" + dependencies: + inherits "2.0.1" + setprototypeof "1.0.1" + statuses ">= 1.3.0 < 2" + +http-proxy@^1.13.1, http-proxy@^1.9.0: + version "1.15.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.15.1.tgz#91a6088172e79bc0e821d5eb04ce702f32446393" + dependencies: + eventemitter3 "1.x.x" + requires-port "1.x.x" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +iconv-lite@^0.4.5, iconv-lite@~0.4.13, iconv-lite@0.4.13: + version "0.4.13" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +in-publish@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" + +include-path-searcher@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/include-path-searcher/-/include-path-searcher-0.1.0.tgz#c0cf2ddfa164fb2eae07bc7ca43a7f191cb4d7bd" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + +inflection@^1.7.0, inflection@^1.7.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.10.0.tgz#5bffcb1197ad3e81050f8e17e21668087ee9eb2f" + +inflight@^1.0.4, inflight@~1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1, inherits@2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + +ini@^1.3.4, ini@~1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + +init-package-json@~1.9.3: + version "1.9.4" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.9.4.tgz#b4053d0b40f0cf842a41966937cb3dc0f534e856" + dependencies: + glob "^6.0.0" + npm-package-arg "^4.0.0" + promzard "^0.3.0" + read "~1.0.1" + read-package-json "1 || 2" + semver "2.x || 3.x || 4 || 5" + validate-npm-package-license "^3.0.1" + validate-npm-package-name "^2.0.1" + +inline-source-map-comment@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/inline-source-map-comment/-/inline-source-map-comment-1.0.5.tgz#50a8a44c2a790dfac441b5c94eccd5462635faf6" + dependencies: + chalk "^1.0.0" + get-stdin "^4.0.1" + minimist "^1.1.1" + sum-up "^1.0.1" + xtend "^4.0.0" + +inquirer@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-1.2.2.tgz#f725c1316f0020e7f3d538c8c5ad0c2732c1c451" + dependencies: + ansi-escapes "^1.1.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + external-editor "^1.1.0" + figures "^1.3.5" + lodash "^4.3.0" + mute-stream "0.0.6" + pinkie-promise "^2.0.0" + run-async "^2.2.0" + rx "^4.1.0" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +ipaddr.js@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.1.1.tgz#c791d95f52b29c1247d5df80ada39b8a73647230" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-buffer@^1.0.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-git-url@^0.2.0: + version "0.2.3" + resolved "https://registry.yarnpkg.com/is-git-url/-/is-git-url-0.2.3.tgz#445200d6fbd6da028fb5e01440d9afc93f3ccb64" + +is-git-url@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-git-url/-/is-git-url-0.2.0.tgz#b9ce0fb044821c88880213d602db03bdb255da1b" + +is-integer@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-integer/-/is-integer-1.0.6.tgz#5273819fada880d123e1ac00a938e7172dd8d95e" + dependencies: + is-finite "^1.0.0" + +is-my-json-valid@^2.12.4: + version "2.15.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz#936edda3ca3c211fd98f3b2d3e08da43f7b2915b" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-type@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/is-type/-/is-type-0.0.1.tgz#f651d85c365d44955d14a51d8d7061f3f6b4779c" + dependencies: + core-util-is "~1.0.0" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isbinaryfile@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.1.tgz#6e99573675372e841a0520c036b41513d783e79e" + +isexe@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +istextorbinary@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.1.0.tgz#dbed2a6f51be2f7475b68f89465811141b758874" + dependencies: + binaryextensions "1 || 2" + editions "^1.1.1" + textextensions "1 || 2" + +jju@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jju/-/jju-1.3.0.tgz#dadd9ef01924bc728b03f2f7979bdbd62f7a2aaa" + +jodid25519@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" + dependencies: + jsbn "~0.1.0" + +js-base64@~2.1.8: + version "2.1.9" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce" + +js-tokens@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-1.0.1.tgz#cc435a5c8b94ad15acb7983140fc80182c89aeae" + +js-yaml@^3.2.5, js-yaml@^3.2.7: + version "3.6.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30" + dependencies: + argparse "^1.0.7" + esprima "^2.6.0" + +jsbn@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.0.tgz#650987da0dd74f4ebf5a11377a2aa2d273e97dfd" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +jshint@^2.7.0: + version "2.9.3" + resolved "https://registry.yarnpkg.com/jshint/-/jshint-2.9.3.tgz#a2e14ff85c2d6bf8c8080e5aa55129ebc6a2d320" + dependencies: + cli "~1.0.0" + console-browserify "1.1.x" + exit "0.1.x" + htmlparser2 "3.8.x" + lodash "3.7.x" + minimatch "~3.0.2" + shelljs "0.3.x" + strip-json-comments "1.0.x" + +json-parse-helpfulerror@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz#13f14ce02eed4e981297b64eb9e3b932e2dd13dc" + dependencies: + jju "^1.1.0" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json3@3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.2.6.tgz#f6efc93c06a04de9aec53053df2559bb19e2038b" + +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + +json5@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.4.0.tgz#054352e4c4c80c86c0923877d449de176a732c8d" + +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsonpointer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.0.tgz#6661e161d2fc445f19f98430231343722e1fcbd5" + +jsprim@^1.2.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.3.1.tgz#2a7256f70412a29ee3670aaca625994c4dcff252" + dependencies: + extsprintf "1.0.2" + json-schema "0.2.3" + verror "1.3.6" + +kind-of@^3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.0.4.tgz#7b8ecf18a4e17f8269d73b501c9f232c96887a74" + dependencies: + is-buffer "^1.0.2" + +klassy@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/klassy/-/klassy-0.1.3.tgz#c31d5756d583197d75f582b6e692872be497067f" + +klaw@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.0.tgz#8857bfbc1d824badf13d3d0241d8bbe46fb12f73" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +leek@0.0.22: + version "0.0.22" + resolved "https://registry.yarnpkg.com/leek/-/leek-0.0.22.tgz#c7b8f38963874ed2f4c0fa9b501a41fb1fb5f5af" + dependencies: + debug "^2.1.0" + lodash.assign "^3.2.0" + request "^2.27.0" + rsvp "^3.0.21" + +leven@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/leven/-/leven-1.0.2.tgz#9144b6eebca5f1d0680169f1a6770dcea60b75c3" + +linkify-it@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.0.2.tgz#994629a4adfa5a7d34e08c075611575ab9b6fcfc" + dependencies: + uc.micro "^1.0.1" + +linkify-it@~1.2.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-1.2.4.tgz#0773526c317c8fd13bd534ee1d180ff88abf881a" + dependencies: + uc.micro "^1.0.1" + +livereload-js@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.2.2.tgz#6c87257e648ab475bc24ea257457edcc1f8d0bc2" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +loader.js@^4.0.7: + version "4.0.11" + resolved "https://registry.yarnpkg.com/loader.js/-/loader.js-4.0.11.tgz#457d7cdcff1badfc9837441a562957dae7eeecea" + +lockfile@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.2.tgz#97e1990174f696cbe0a3acd58a43b84aa30c7c83" + +lodash._arraycopy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1" + +lodash._arrayeach@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz#bab156b2a90d3f1bbd5c653403349e5e5933ef9e" + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._baseclone@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz#303519bf6393fe7e42f34d8b630ef7794e3542b7" + dependencies: + lodash._arraycopy "^3.0.0" + lodash._arrayeach "^3.0.0" + lodash._baseassign "^3.0.0" + lodash._basefor "^3.0.0" + lodash.isarray "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + +lodash._baseflatten@^3.0.0: + version "3.1.4" + resolved "https://registry.yarnpkg.com/lodash._baseflatten/-/lodash._baseflatten-3.1.4.tgz#0770ff80131af6e34f3b511796a7ba5214e65ff7" + dependencies: + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash._basefor@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basefor/-/lodash._basefor-3.0.3.tgz#7550b4e9218ef09fad24343b612021c79b4c20c2" + +lodash._bindcallback@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" + +lodash._createassigner@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" + dependencies: + lodash._bindcallback "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash.restparam "^3.0.0" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + +lodash._reinterpolate@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + +lodash.assign@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" + dependencies: + lodash._baseassign "^3.0.0" + lodash._createassigner "^3.0.0" + lodash.keys "^3.0.0" + +lodash.assign@^4.0.3, lodash.assign@^4.0.6, lodash.assign@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + +lodash.assignin@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" + +lodash.clonedeep@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-3.0.2.tgz#a0a1e40d82a5ea89ff5b147b8444ed63d92827db" + dependencies: + lodash._baseclone "^3.0.0" + lodash._bindcallback "^3.0.0" + +lodash.clonedeep@^4.3.2, lodash.clonedeep@^4.4.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + +lodash.debounce@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-3.1.1.tgz#812211c378a94cc29d5aa4e3346cf0bfce3a7df5" + dependencies: + lodash._getnative "^3.0.0" + +lodash.find@^4.5.1: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1" + +lodash.flatten@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-3.0.2.tgz#de1cf57758f8f4479319d35c3e9cc60c4501938c" + dependencies: + lodash._baseflatten "^3.0.0" + lodash._isiterateecall "^3.0.0" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + +lodash.isplainobject@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-3.2.0.tgz#9a8238ae16b200432960cd7346512d0123fbf4c5" + dependencies: + lodash._basefor "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.keysin "^3.0.0" + +lodash.istypedarray@^3.0.0: + version "3.0.6" + resolved "https://registry.yarnpkg.com/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz#c9a477498607501d8e8494d283b87c39281cef62" + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.keysin@^3.0.0: + version "3.0.8" + resolved "https://registry.yarnpkg.com/lodash.keysin/-/lodash.keysin-3.0.8.tgz#22c4493ebbedb1427962a54b445b2c8a767fb47f" + dependencies: + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.merge@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-3.3.2.tgz#0d90d93ed637b1878437bb3e21601260d7afe994" + dependencies: + lodash._arraycopy "^3.0.0" + lodash._arrayeach "^3.0.0" + lodash._createassigner "^3.0.0" + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + lodash.isplainobject "^3.0.0" + lodash.istypedarray "^3.0.0" + lodash.keys "^3.0.0" + lodash.keysin "^3.0.0" + lodash.toplainobject "^3.0.0" + +lodash.merge@^4.3.0, lodash.merge@^4.4.0, lodash.merge@^4.5.1: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" + +lodash.omit@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" + +lodash.pad@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70" + +lodash.padend@^4.1.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" + +lodash.padstart@^4.1.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + +lodash.template@^4.2.5: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" + dependencies: + lodash._reinterpolate "~3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" + dependencies: + lodash._reinterpolate "~3.0.0" + +lodash.toplainobject@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash.toplainobject/-/lodash.toplainobject-3.0.0.tgz#28790ad942d293d78aa663a07ecf7f52ca04198d" + dependencies: + lodash._basecopy "^3.0.0" + lodash.keysin "^3.0.0" + +lodash.uniq@^4.2.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + +lodash@^3.10.0, lodash@^3.10.1, lodash@^3.9.3: + version "3.10.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + +lodash@^4.0.0, lodash@^4.12.0, lodash@^4.14.0, lodash@^4.3.0, lodash@^4.6.1: + version "4.16.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.16.4.tgz#01ce306b9bad1319f2a5528674f88297aeb70127" + +lodash@~4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.9.0.tgz#4c20d742f03ce85dc700e0dd7ab9bcab85e6fc14" + +lodash@3.7.x: + version "3.7.0" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.7.0.tgz#3678bd8ab995057c07ade836ed2ef087da811d45" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lru-cache@^4.0.1, lru-cache@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.1.tgz#1343955edaf2e37d9b9e7ee7241e27c4b9fb72be" + dependencies: + pseudomap "^1.0.1" + yallist "^2.0.0" + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + +make-array@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/make-array/-/make-array-0.1.2.tgz#335e36ebb0c5a43154d21213a1ecaeae2a1bb3ef" + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + dependencies: + tmpl "1.0.x" + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + +markdown-it-terminal@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/markdown-it-terminal/-/markdown-it-terminal-0.0.3.tgz#c77a8533c2170b46d2a907a3c3452d4d7f4aa5db" + dependencies: + ansi-styles "^2.1.0" + cardinal "^0.5.0" + cli-table "^0.3.1" + lodash.merge "^3.3.2" + markdown-it "^4.4.0" + +markdown-it@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-4.4.0.tgz#3df373dbea587a9a7fef3e56311b68908f75c414" + dependencies: + argparse "~1.0.2" + entities "~1.1.1" + linkify-it "~1.2.0" + mdurl "~1.0.0" + uc.micro "^1.0.0" + +markdown-it@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-7.0.0.tgz#d5ae413e160c862246573b0df79025fb9795fcf2" + dependencies: + argparse "^1.0.7" + entities "~1.1.1" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.1" + +marked-terminal@^1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-1.6.2.tgz#44c128d69b5d9776c848314cdf69d4ec96322973" + dependencies: + cardinal "^1.0.0" + chalk "^1.0.0" + cli-table "^0.3.1" + lodash.assign "^4.2.0" + node-emoji "^1.3.1" + +marked@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.6.tgz#b2c6c618fccece4ef86c4fc6cb8a7cbf5aeda8d7" + +matcher-collection@^1.0.0, matcher-collection@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/matcher-collection/-/matcher-collection-1.0.4.tgz#2f66ae0869996f29e43d0b62c83dd1d43e581755" + dependencies: + minimatch "^3.0.2" + +md5-hex@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + +mdurl@^1.0.1, mdurl@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + +memory-streams@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/memory-streams/-/memory-streams-0.1.0.tgz#bec658a71e3f28b0f0c2f1b14501c2db547d5f7a" + dependencies: + readable-stream "~1.0.2" + +meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + +merge@^1.1.3, merge@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + +"mime-db@>= 1.23.0 < 2", mime-db@~1.24.0: + version "1.24.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.24.0.tgz#e2d13f939f0016c6e4e9ad25a8652f126c467f0c" + +mime-db@~1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.12.0.tgz#3d0c63180f458eb10d325aaa37d7c58ae312e9d7" + +mime-types@^2.1.11, mime-types@~2.1.11, mime-types@~2.1.7: + version "2.1.12" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.12.tgz#152ba256777020dd4663f54c2e7bc26381e71729" + dependencies: + mime-db "~1.24.0" + +mime-types@~2.0.4: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.0.14.tgz#310e159db23e077f8bb22b748dabfa4957140aa6" + dependencies: + mime-db "~1.12.0" + +mime@^1.2.11, mime@1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" + +minimatch@^2.0.1, minimatch@^2.0.3: + version "2.0.10" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" + dependencies: + brace-expansion "^1.0.0" + +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@~3.0.0, minimatch@~3.0.2, "minimatch@2 || 3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + dependencies: + brace-expansion "^1.0.0" + +minimatch@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-1.0.0.tgz#e0dd2120b49e1b724ce8d714c520822a9438576d" + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +mkdirp@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" + +mkdirp@^0.5.0, mkdirp@^0.5.1, "mkdirp@>=0.5 0", mkdirp@~0.5.0, mkdirp@~0.5.1, mkdirp@0.5.x: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mkdirp@~0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.4.2.tgz#427c8c18ece398b932f6f666f4e1e5b7740e78c8" + dependencies: + minimist "0.0.8" + +mktemp@~0.3.4: + version "0.3.5" + resolved "https://registry.yarnpkg.com/mktemp/-/mktemp-0.3.5.tgz#a1504c706d0d2b198c6a0eb645f7fdaf8181f7de" + +mktemp@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/mktemp/-/mktemp-0.4.0.tgz#6d0515611c8a8c84e484aa2000129b98e981ff0b" + +moment-timezone@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.3.1.tgz#3ef47856b02d53b718a10a5ec2023aa299e07bf5" + dependencies: + moment ">= 2.6.0" + +"moment@>= 2.6.0": + version "2.15.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.15.1.tgz#e979c2a29e22888e60f396f2220a6118f85cd94c" + +morgan@^1.5.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.7.0.tgz#eb10ca8e50d1abe0f8d3dad5c0201d052d981c62" + dependencies: + basic-auth "~1.0.3" + debug "~2.2.0" + depd "~1.1.0" + on-finished "~2.3.0" + on-headers "~1.0.1" + +mout@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mout/-/mout-1.0.0.tgz#9bdf1d4af57d66d47cb353a6335a3281098e1501" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +mustache@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.2.1.tgz#2c40ca21c278f53150682bcf9090e41a3339b876" + +mute-stream@~0.0.4, mute-stream@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db" + +nan@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.4.0.tgz#fb3c59d45fe4effe215f0b890f8adf6eb32d2232" + +negotiator@0.4.9: + version "0.4.9" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.4.9.tgz#92e46b6db53c7e421ed64a2bc94f08be7630df3f" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + +node-emoji@^1.3.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.4.1.tgz#c9fa0cf91094335bcb967a6f42b2305c15af2ebc" + dependencies: + string.prototype.codepointat "^0.2.0" + +node-fetch@^1.3.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-gyp@^3.3.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.4.0.tgz#dda558393b3ecbbe24c9e6b8703c71194c63fa36" + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + minimatch "^3.0.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3" + osenv "0" + path-array "^1.0.0" + request "2" + rimraf "2" + semver "2.x || 3.x || 4 || 5" + tar "^2.0.0" + which "1" + +node-gyp@~3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.3.1.tgz#80f7b6d7c2f9c0495ba42c518a670c99bdf6e4a0" + dependencies: + fstream "^1.0.0" + glob "3 || 4" + graceful-fs "^4.1.2" + minimatch "1" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2" + osenv "0" + path-array "^1.0.0" + request "2" + rimraf "2" + semver "2.x || 3.x || 4 || 5" + tar "^2.0.0" + which "1" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + +node-modules-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/node-modules-path/-/node-modules-path-1.0.1.tgz#40096b08ce7ad0ea14680863af449c7c75a5d1c8" + +node-notifier@^4.3.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-4.6.1.tgz#056d14244f3dcc1ceadfe68af9cff0c5473a33f3" + dependencies: + cli-usage "^0.1.1" + growly "^1.2.0" + lodash.clonedeep "^3.0.0" + minimist "^1.1.1" + semver "^5.1.0" + shellwords "^0.1.0" + which "^1.0.5" + +node-sass@^3.8.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-3.10.1.tgz#c535b2e1a5439240591e06d7308cb663820d616c" + dependencies: + async-foreach "^0.1.3" + chalk "^1.1.1" + cross-spawn "^3.0.0" + gaze "^1.0.0" + get-stdin "^4.0.1" + glob "^7.0.3" + in-publish "^2.0.0" + lodash.assign "^4.2.0" + lodash.clonedeep "^4.3.2" + meow "^3.7.0" + mkdirp "^0.5.1" + nan "^2.3.2" + node-gyp "^3.3.1" + npmlog "^4.0.0" + request "^2.61.0" + sass-graph "^2.1.1" + +node-uuid@^1.4.3, node-uuid@~1.4.7: + version "1.4.7" + resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.7.tgz#6da5a17668c4b3dd59623bda11cf7fa4c1f60a6f" + +nopt@^3.0.1, nopt@^3.0.3, nopt@~3.0.6, "nopt@2 || 3": + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +normalize-git-url@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/normalize-git-url/-/normalize-git-url-3.0.2.tgz#8e5f14be0bdaedb73e07200310aa416c27350fc4" + +normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, "normalize-package-data@~1.0.1 || ^2.0.0", normalize-package-data@~2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.5.tgz#8d924f142960e1777e7ffe170543631cc7cb02df" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +npm-cache-filename@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11" + +npm-install-checks@~1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-1.0.7.tgz#6d91aeda0ac96801f1ed7aadee116a6c0a086a57" + dependencies: + npmlog "0.1 || 1 || 2" + semver "^2.3.0 || 3.x || 4 || 5" + +"npm-package-arg@^3.0.0 || ^4.0.0", npm-package-arg@^4.0.0, npm-package-arg@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-4.2.0.tgz#809bc61cabf54bd5ff94f6165c89ba8ee88c115c" + dependencies: + hosted-git-info "^2.1.5" + semver "^5.1.0" + +npm-package-arg@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-4.1.1.tgz#86d9dca985b4c5e5d59772dfd5de6919998a495a" + dependencies: + hosted-git-info "^2.1.4" + semver "4 || 5" + +npm-registry-client@~7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/npm-registry-client/-/npm-registry-client-7.1.2.tgz#ddf243a2bd149d35172fe680aff40dfa20054bc3" + dependencies: + chownr "^1.0.1" + concat-stream "^1.4.6" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + normalize-package-data "~1.0.1 || ^2.0.0" + npm-package-arg "^3.0.0 || ^4.0.0" + once "^1.3.0" + request "^2.47.0" + retry "^0.8.0" + rimraf "2" + semver "2 >=2.2.1 || 3.x || 4 || 5" + slide "^1.1.3" + optionalDependencies: + npmlog "~2.0.0 || ~3.1.0" + +npm-user-validate@~0.1.2: + version "0.1.5" + resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-0.1.5.tgz#52465d50c2d20294a57125b996baedbf56c5004b" + +npm@2.15.5: + version "2.15.5" + resolved "https://registry.yarnpkg.com/npm/-/npm-2.15.5.tgz#5fcd71999c3d54baa0e1c27ac44f84a1b82b4559" + dependencies: + abbrev "~1.0.7" + ansi "~0.3.1" + ansicolors "~0.3.2" + ansistyles "~0.1.3" + archy "~1.0.0" + async-some "~1.0.2" + block-stream "0.0.9" + char-spinner "~1.0.1" + chmodr "~1.0.2" + chownr "~1.0.1" + cmd-shim "~2.0.2" + columnify "~1.5.4" + config-chain "~1.1.10" + dezalgo "~1.0.3" + editor "~1.0.0" + fs-vacuum "~1.2.9" + fs-write-stream-atomic "~1.0.8" + fstream "~1.0.8" + fstream-npm "~1.0.7" + github-url-from-git "~1.4.0" + github-url-from-username-repo "~1.0.2" + glob "~7.0.3" + graceful-fs "~4.1.4" + hosted-git-info "~2.1.4" + inflight "~1.0.4" + inherits "~2.0.1" + ini "~1.3.4" + init-package-json "~1.9.3" + lockfile "~1.0.1" + lru-cache "~4.0.1" + minimatch "~3.0.0" + mkdirp "~0.5.1" + node-gyp "~3.3.1" + nopt "~3.0.6" + normalize-git-url "~3.0.2" + normalize-package-data "~2.3.5" + npm-cache-filename "~1.0.2" + npm-install-checks "~1.0.7" + npm-package-arg "~4.1.0" + npm-registry-client "~7.1.0" + npm-user-validate "~0.1.2" + npmlog "~2.0.3" + once "~1.3.3" + opener "~1.4.1" + osenv "~0.1.3" + path-is-inside "~1.0.0" + read "~1.0.7" + read-installed "~4.0.3" + read-package-json "~2.0.4" + readable-stream "~2.1.2" + realize-package-specifier "~3.0.3" + request "~2.72.0" + retry "~0.9.0" + rimraf "~2.5.2" + semver "~5.1.0" + sha "~2.0.1" + slide "~1.1.6" + sorted-object "~2.0.0" + spdx-license-ids "~1.2.1" + strip-ansi "~3.0.1" + tar "~2.2.1" + text-table "~0.2.0" + uid-number "0.0.6" + umask "~1.1.0" + validate-npm-package-license "~3.0.1" + validate-npm-package-name "~2.2.2" + which "~1.2.8" + wrappy "~1.0.1" + write-file-atomic "~1.1.4" + +npmlog@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.0.tgz#e094503961c70c1774eb76692080e8d578a9f88f" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.6.0" + set-blocking "~2.0.0" + +"npmlog@~2.0.0 || ~3.1.0", "npmlog@0 || 1 || 2 || 3": + version "3.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-3.1.2.tgz#2d46fa874337af9498a2f12bb43d8d0be4a36873" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.6.0" + set-blocking "~2.0.0" + +npmlog@~2.0.3, "npmlog@0 || 1 || 2", "npmlog@0.1 || 1 || 2": + version "2.0.4" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692" + dependencies: + ansi "~0.3.1" + are-we-there-yet "~1.1.2" + gauge "~1.2.5" + +num2fraction@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +once@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +opener@~1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.2.tgz#b32582080042af8680c389a499175b4c54fff523" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +options@>=0.0.5: + version "0.0.6" + resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" + +ora@^0.2.0: + version "0.2.3" + resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" + dependencies: + chalk "^1.1.1" + cli-cursor "^1.0.2" + cli-spinners "^0.1.2" + object-assign "^4.0.1" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + dependencies: + lcid "^1.0.0" + +os-shim@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.0, osenv@^0.1.3, osenv@~0.1.3, osenv@0: + version "0.1.3" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.3.tgz#83cf05c6d6458fc4d5ac6362ea325d92f2754217" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +output-file-sync@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" + dependencies: + graceful-fs "^4.1.4" + mkdirp "^0.5.1" + object-assign "^4.1.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parsejson@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/parsejson/-/parsejson-0.0.1.tgz#9b10c6c0d825ab589e685153826de0a3ba278bcc" + dependencies: + better-assert "~1.0.0" + +parseqs@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.2.tgz#9dfe70b2cddac388bde4f35b1f240fa58adbe6c7" + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.4.tgz#806582a39887e1ea18dd5e2fe0e01902268e9350" + dependencies: + better-assert "~1.0.0" + +parseurl@~1.3.0, parseurl@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" + +path-array@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-array/-/path-array-1.0.1.tgz#7e2f0f35f07a2015122b868b7eac0eb2c4fec271" + dependencies: + array-index "^1.0.0" + +path-exists@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-1.0.0.tgz#d5a8998eb71ef37a74c34eb0d9eba6e878eea081" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1, path-is-inside@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-posix@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/path-posix/-/path-posix-1.0.0.tgz#06b26113f56beab042545a23bfa88003ccac260f" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +portfinder@^1.0.4: + version "1.0.8" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.8.tgz#b08b2ed226719d682b6f4158eb8e5b69a2561f71" + dependencies: + async "^1.5.2" + debug "^2.2.0" + mkdirp "0.5.x" + +postcss@^4.1.11, postcss@~4.1.12: + version "4.1.16" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-4.1.16.tgz#4c449b4c8af9df3caf6d37f8e1e575d0361758dc" + dependencies: + es6-promise "~2.3.0" + js-base64 "~2.1.8" + source-map "~0.4.2" + +printf@^0.2.3: + version "0.2.5" + resolved "https://registry.yarnpkg.com/printf/-/printf-0.2.5.tgz#c438ca2ca33e3927671db4ab69c0e52f936a4f0f" + +private@^0.1.6, private@~0.1.5: + version "0.1.6" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.6.tgz#55c6a976d0f9bafb9924851350fe47b9b5fbb7c1" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +process-relative-require@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/process-relative-require/-/process-relative-require-1.0.0.tgz#1590dfcf5b8f2983ba53e398446b68240b4cc68a" + dependencies: + node-modules-path "^1.0.0" + +promise-map-series@^0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/promise-map-series/-/promise-map-series-0.2.3.tgz#c2d377afc93253f6bd03dbb77755eb88ab20a847" + dependencies: + rsvp "^3.0.14" + +promzard@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" + dependencies: + read "1" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + +proxy-addr@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.2.tgz#b4cc5f22610d9535824c123aef9d3cf73c40ba37" + dependencies: + forwarded "~0.1.0" + ipaddr.js "1.1.1" + +pseudomap@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +q@^1.1.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" + +qs@~5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-5.1.0.tgz#4d932e5c7ea411cca76a312d39a606200fd50cd9" + +qs@~6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.1.0.tgz#ec1d1626b24278d99f0fdf4549e524e24eceeb26" + +qs@~6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.1.tgz#ce03c5ff0935bc1d9d69a9f14cbd18e568d67625" + +qs@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be" + +qs@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.0.tgz#3b7848c03c2dece69a9522b0fae8c4126d745f3b" + +quick-temp@^0.1.0, quick-temp@^0.1.2, quick-temp@^0.1.3, quick-temp@^0.1.5: + version "0.1.6" + resolved "https://registry.yarnpkg.com/quick-temp/-/quick-temp-0.1.6.tgz#a6242a15cba9f9cdbd341287b5c569e318eec307" + dependencies: + mktemp "~0.4.0" + rimraf "~2.2.6" + underscore.string "~2.3.3" + +quick-temp@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/quick-temp/-/quick-temp-0.1.5.tgz#0d0d67f0fb6a589a0e142f90985f76cdbaf403f7" + dependencies: + mktemp "~0.3.4" + rimraf "~2.2.6" + underscore.string "~2.3.3" + +qunitjs@^1.20.0: + version "1.23.1" + resolved "https://registry.yarnpkg.com/qunitjs/-/qunitjs-1.23.1.tgz#1971cf97ac9be01a64d2315508d2e48e6fd4e719" + +range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + +raw-body@~2.1.5: + version "2.1.7" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774" + dependencies: + bytes "2.4.0" + iconv-lite "0.4.13" + unpipe "1.0.0" + +read-installed@~4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" + dependencies: + debuglog "^1.0.1" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + semver "2 || 3 || 4 || 5" + slide "~1.1.3" + util-extend "^1.0.1" + optionalDependencies: + graceful-fs "^4.1.2" + +read-package-json@^2.0.0, read-package-json@~2.0.4, "read-package-json@1 || 2": + version "2.0.4" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.4.tgz#61ed1b2256ea438d8008895090be84b8e799c853" + dependencies: + glob "^6.0.0" + json-parse-helpfulerror "^1.0.2" + normalize-package-data "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.2" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read@~1.0.1, read@~1.0.7, read@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + dependencies: + mute-stream "~0.0.4" + +readable-stream@^2, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2, readable-stream@~2.1.2, "readable-stream@1 || 2": + version "2.1.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@~1.0.2: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~2.0.0, readable-stream@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@1.1: + version "1.1.13" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readdir-scoped-modules@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + graceful-fs "^4.1.2" + once "^1.3.0" + +realize-package-specifier@~3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/realize-package-specifier/-/realize-package-specifier-3.0.3.tgz#d0def882952b8de3f67eba5e91199661271f41f4" + dependencies: + dezalgo "^1.0.1" + npm-package-arg "^4.1.1" + +recast@^0.10.0, recast@^0.10.10: + version "0.10.43" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.43.tgz#b95d50f6d60761a5f6252e15d80678168491ce7f" + dependencies: + ast-types "0.8.15" + esprima-fb "~15001.1001.0-dev-harmony-fb" + private "~0.1.5" + source-map "~0.5.0" + +recast@^0.11.3: + version "0.11.14" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.14.tgz#3ba11420f9403c66e397c045ce4fe951a56eecb1" + dependencies: + ast-types "0.9.0" + esprima "~3.0.0" + private "~0.1.5" + source-map "~0.5.0" + +recast@0.10.33: + version "0.10.33" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.33.tgz#942808f7aa016f1fa7142c461d7e5704aaa8d697" + dependencies: + ast-types "0.8.12" + esprima-fb "~15001.1001.0-dev-harmony-fb" + private "~0.1.5" + source-map "~0.5.0" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +redeyed@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-0.5.0.tgz#7ab000e60ee3875ac115d29edb32c1403c6c25d1" + dependencies: + esprima-fb "~12001.1.0-dev-harmony-fb" + +redeyed@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-1.0.0.tgz#6ce25045c9e1f9b28c0ae73ce2960c8cb48184b1" + dependencies: + esprima "~2.7.0" + +regenerate@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.1.tgz#0300203a5d2fdcf89116dce84275d011f5903f33" + +regenerator@0.8.40: + version "0.8.40" + resolved "https://registry.yarnpkg.com/regenerator/-/regenerator-0.8.40.tgz#a0e457c58ebdbae575c9f8cd75127e93756435d8" + dependencies: + commoner "~0.10.3" + defs "~1.1.0" + esprima-fb "~15001.1001.0-dev-harmony-fb" + private "~0.1.5" + recast "0.10.33" + through "~2.3.8" + +regexpu@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/regexpu/-/regexpu-1.3.0.tgz#e534dc991a9e5846050c98de6d7dd4a55c9ea16d" + dependencies: + esprima "^2.6.0" + recast "^0.10.10" + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +repeat-string@^1.5.2: + version "1.5.4" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.5.4.tgz#64ec0c91e0f4b475f90d5b643651e3e6e5b6c2d5" + +repeating@^1.1.0, repeating@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-1.1.3.tgz#3d4114218877537494f97f77f9785fab810fa4ac" + dependencies: + is-finite "^1.0.0" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request@^2.27.0, request@^2.47.0, request@^2.61.0, request@2: + version "2.75.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.75.0.tgz#d2b8268a286da13eaa5d01adf5d18cc90f657d93" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + bl "~1.1.2" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.0.0" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + node-uuid "~1.4.7" + oauth-sign "~0.8.1" + qs "~6.2.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + +request@~2.72.0: + version "2.72.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.72.0.tgz#0ce3a179512620b10441f14c82e21c12c0ddb4e1" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + bl "~1.1.2" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~1.0.0-rc3" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + node-uuid "~1.4.7" + oauth-sign "~0.8.1" + qs "~6.1.0" + stringstream "~0.0.4" + tough-cookie "~2.2.0" + tunnel-agent "~0.4.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +requires-port@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + +resolve@^1.1.2, resolve@^1.1.6: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +retry@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.8.0.tgz#2367628dc0edb247b1eab649dc53ac8628ac2d5f" + +retry@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.9.0.tgz#6f697e50a0e4ddc8c8f7fb547a9b60dead43678d" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@^2.2.8, rimraf@^2.3.2, rimraf@^2.3.4, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@^2.5.2, rimraf@^2.5.3, rimraf@~2.5.2, rimraf@2: + version "2.5.4" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" + dependencies: + glob "^7.0.5" + +rimraf@~2.2.6: + version "2.2.8" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + +rsvp@^3.0.14, rsvp@^3.0.16, rsvp@^3.0.17, rsvp@^3.0.18, rsvp@^3.0.21, rsvp@^3.0.6, rsvp@^3.1.0, rsvp@^3.2.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.3.3.tgz#34633caaf8bc66ceff4be3c2e1dffd032538a813" + +run-async@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.2.0.tgz#8783abd83c7bb86f41ee0602fc82404b3bd6e8b9" + dependencies: + is-promise "^2.1.0" + pinkie-promise "^2.0.0" + +rx@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" + +sane@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/sane/-/sane-1.4.1.tgz#88f763d74040f5f0c256b6163db399bf110ac715" + dependencies: + exec-sh "^0.2.0" + fb-watchman "^1.8.0" + minimatch "^3.0.2" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.10.0" + +sass-graph@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.1.2.tgz#965104be23e8103cb7e5f710df65935b317da57b" + dependencies: + glob "^7.0.0" + lodash "^4.0.0" + yargs "^4.7.1" + +"semver@^2.3.0 || 3.x || 4 || 5", semver@^5.1.0, semver@^5.1.1, "semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", "semver@4 || 5": + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +semver@^4.1.0, semver@^4.2.2, semver@^4.3.1: + version "4.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" + +semver@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.1.1.tgz#a3292a373e6f3e0798da0b20641b9a9c5bc47e19" + +send@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.14.1.tgz#a954984325392f51532a7760760e459598c89f7a" + dependencies: + debug "~2.2.0" + depd "~1.1.0" + destroy "~1.0.4" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.7.0" + fresh "0.3.0" + http-errors "~1.5.0" + mime "1.3.4" + ms "0.7.1" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.3.0" + +serve-static@~1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.11.1.tgz#d6cce7693505f733c759de57befc1af76c0f0805" + dependencies: + encodeurl "~1.0.1" + escape-html "~1.0.3" + parseurl "~1.3.1" + send "0.14.1" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +setprototypeof@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.1.tgz#52009b27888c4dc48f591949c0a8275834c1ca7e" + +sha@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sha/-/sha-2.0.1.tgz#6030822fbd2c9823949f8f72ed6411ee5cf25aae" + dependencies: + graceful-fs "^4.1.2" + readable-stream "^2.0.2" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +shelljs@0.3.x: + version "0.3.0" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.3.0.tgz#3596e6307a781544f591f37da618360f31db57b1" + +shellwords@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.0.tgz#66afd47b6a12932d9071cbfd98a52e785cd0ba14" + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + +signal-exit@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.1.tgz#5a4c884992b63a7acd9badb7894c3ee9cfccad81" + +silent-error@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/silent-error/-/silent-error-1.0.1.tgz#71b7d503d1c6f94882b51b56be879b113cb4822c" + dependencies: + debug "^2.2.0" + +simple-fmt@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/simple-fmt/-/simple-fmt-0.1.0.tgz#191bf566a59e6530482cb25ab53b4a8dc85c3a6b" + +simple-is@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/simple-is/-/simple-is-0.2.0.tgz#2abb75aade39deb5cc815ce10e6191164850baf0" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slide@^1.1.3, slide@^1.1.5, slide@~1.1.3, slide@~1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +socket.io-adapter@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-0.4.0.tgz#fb9f82ab1aa65290bf72c3657955b930a991a24f" + dependencies: + debug "2.2.0" + socket.io-parser "2.2.2" + +socket.io-client@1.4.6: + version "1.4.6" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.4.6.tgz#49b0ba537efd15b8297c84016e642e1c7c752c3d" + dependencies: + backo2 "1.0.2" + component-bind "1.0.0" + component-emitter "1.2.0" + debug "2.2.0" + engine.io-client "1.6.9" + has-binary "0.1.7" + indexof "0.0.1" + object-component "0.0.3" + parseuri "0.0.4" + socket.io-parser "2.2.6" + to-array "0.1.4" + +socket.io-parser@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-2.2.2.tgz#3d7af6b64497e956b7d9fe775f999716027f9417" + dependencies: + benchmark "1.0.0" + component-emitter "1.1.2" + debug "0.7.4" + isarray "0.0.1" + json3 "3.2.6" + +socket.io-parser@2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-2.2.6.tgz#38dfd61df50dcf8ab1d9e2091322bf902ba28b99" + dependencies: + benchmark "1.0.0" + component-emitter "1.1.2" + debug "2.2.0" + isarray "0.0.1" + json3 "3.3.2" + +socket.io@1.4.7: + version "1.4.7" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.4.7.tgz#92b7f7cb88c5797d4daee279fe8075dbe6d3fa1c" + dependencies: + debug "2.2.0" + engine.io "1.6.10" + has-binary "0.1.7" + socket.io-adapter "0.4.0" + socket.io-client "1.4.6" + socket.io-parser "2.2.6" + +sorted-object@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc" + +source-map-support@^0.2.10: + version "0.2.10" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.2.10.tgz#ea5a3900a1c1cb25096a0ae8cc5c2b4b10ded3dc" + dependencies: + source-map "0.1.32" + +source-map-url@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" + +source-map@^0.4.2, source-map@^0.4.4, source-map@~0.4.2, source-map@0.4.x: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@~0.5.0, source-map@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + +source-map@0.1.32: + version "0.1.32" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.32.tgz#c8b6c167797ba4740a8ea33252162ff08591b266" + dependencies: + amdefine ">=0.0.4" + +spawn-args@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/spawn-args/-/spawn-args-0.2.0.tgz#fb7d0bd1d70fd4316bd9e3dec389e65f9d6361bb" + +spawn-sync@^1.0.15: + version "1.0.15" + resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" + dependencies: + concat-stream "^1.4.7" + os-shim "^0.1.2" + +spawnback@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/spawnback/-/spawnback-1.0.0.tgz#f73662f7e54d95367eca74d6426c677dd7ea686f" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2, spdx-license-ids@~1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sri-toolbox@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/sri-toolbox/-/sri-toolbox-0.2.0.tgz#a7fea5c3fde55e675cf1c8c06f3ebb5c2935835e" + +sshpk@^1.7.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.10.1.tgz#30e1a5d329244974a1af61511339d595af6638b0" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jodid25519 "^1.0.0" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stable@~0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.5.tgz#08232f60c732e9890784b5bed0734f8b32a887b9" + +"statuses@>= 1.3.0 < 2", statuses@~1.3.0, statuses@1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.0.tgz#8e55758cb20e7682c1f4fce8dcab30bf01d1e07a" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string.prototype.codepointat@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/string.prototype.codepointat/-/string.prototype.codepointat-0.2.0.tgz#6b26e9bd3afcaa7be3b4269b526de1b82000ac78" + +stringmap@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stringmap/-/stringmap-0.2.2.tgz#556c137b258f942b8776f5b2ef582aa069d7d1b1" + +stringset@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/stringset/-/stringset-0.2.1.tgz#ef259c4e349344377fcd1c913dd2e848c9c042b5" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.3.0.tgz#25f48ea22ca79187f3174a4db8759347bb126220" + dependencies: + ansi-regex "^0.2.1" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1, strip-ansi@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + +styled_string@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/styled_string/-/styled_string-0.0.1.tgz#d22782bd81295459bc4f1df18c4bad8e94dd124a" + +sum-up@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sum-up/-/sum-up-1.0.3.tgz#1c661f667057f63bcb7875aa1438bc162525156e" + dependencies: + chalk "^1.0.0" + +supports-color@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +symlink-or-copy@^1.0.0, symlink-or-copy@^1.0.1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/symlink-or-copy/-/symlink-or-copy-1.1.6.tgz#b5f6e8e00616210f64e6b3fa114ea0208e268f78" + +sync-exec@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/sync-exec/-/sync-exec-0.6.2.tgz#717d22cc53f0ce1def5594362f3a89a2ebb91105" + +tap-parser@^1.1.3: + version "1.3.2" + resolved "https://registry.yarnpkg.com/tap-parser/-/tap-parser-1.3.2.tgz#120c5089c88c3c8a793ef288867de321e18f8c22" + dependencies: + events-to-array "^1.0.1" + inherits "~2.0.1" + js-yaml "^3.2.7" + optionalDependencies: + readable-stream "^2" + +tar@^2.0.0, tar@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +temp@^0.8.3, temp@0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" + dependencies: + os-tmpdir "^1.0.0" + rimraf "~2.2.6" + +testem@^1.8.1: + version "1.12.0" + resolved "https://registry.yarnpkg.com/testem/-/testem-1.12.0.tgz#69c42d1c8ed6d6c5185ca270a1cb8cf617ea8fec" + dependencies: + backbone "^1.1.2" + bluebird "^3.4.6" + charm "^1.0.0" + commander "^2.6.0" + consolidate "^0.14.0" + cross-spawn "^4.0.0" + did_it_work "0.0.6" + express "^4.10.7" + fireworm "^0.7.0" + glob "^7.0.4" + http-proxy "^1.13.1" + js-yaml "^3.2.5" + lodash.assignin "^4.1.0" + lodash.clonedeep "^4.4.1" + lodash.find "^4.5.1" + mkdirp "^0.5.1" + mustache "^2.2.1" + node-notifier "^4.3.1" + npmlog "^4.0.0" + printf "^0.2.3" + rimraf "^2.4.4" + socket.io "1.4.7" + spawn-args "^0.2.0" + styled_string "0.0.1" + tap-parser "^1.1.3" + xmldom "^0.1.19" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +"textextensions@1 || 2": + version "2.0.1" + resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.0.1.tgz#be8cf22d65379c151319f88f0335ad8f667abdca" + +through@^2.3.6, through@~2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +tiny-lr@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-0.2.1.tgz#b3fdba802e5d56a33c2f6f10794b32e477ac729d" + dependencies: + body-parser "~1.14.0" + debug "~2.2.0" + faye-websocket "~0.10.0" + livereload-js "^2.2.0" + parseurl "~1.3.0" + qs "~5.1.0" + +tmp@0.0.28: + version "0.0.28" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" + dependencies: + os-tmpdir "~1.0.1" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + +to-fast-properties@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" + +tough-cookie@~2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.2.2.tgz#c83a1830f4e5ef0b93ef2a3488e724f8de016ac7" + +tough-cookie@~2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.1.tgz#99c77dfbb7d804249e8a299d4cb0fd81fef083fd" + +tree-sync@^1.1.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/tree-sync/-/tree-sync-1.1.4.tgz#6dd4f7fe5db35fcd86cac54bc844b260746b21b8" + dependencies: + debug "^2.2.0" + fs-tree-diff "^0.5.2" + mkdirp "^0.5.1" + quick-temp "^0.1.5" + walk-sync "^0.2.7" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + +trim-right@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +try-resolve@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/try-resolve/-/try-resolve-1.0.1.tgz#cfde6fabd72d63e5797cfaab873abbe8e700e912" + +tryor@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/tryor/-/tryor-0.1.2.tgz#8145e4ca7caff40acde3ccf946e8b8bb75b4172b" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.3" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.3.tgz#3da382f670f25ded78d7b3d1792119bca0b7132d" + +type-is@~1.6.10, type-is@~1.6.13: + version "1.6.13" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.13.tgz#6e83ba7bc30cd33a7bb0b7fb00737a2085bf9d08" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.11" + +typedarray@~0.0.5: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +uc.micro@^1.0.0, uc.micro@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192" + +uglify-js@^2.6, uglify-js@^2.6.0: + version "2.7.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.3.tgz#39b3a7329b89f5ec507e344c6e22568698ef4868" + dependencies: + async "~0.2.6" + source-map "~0.5.1" + uglify-to-browserify "~1.0.0" + yargs "~3.10.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +uid-number@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +ultron@1.0.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" + +umask@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" + +underscore.string@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.3.3.tgz#71c08bf6b428b1133f37e78fa3a21c82f7329b0d" + +underscore@>=1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" + +unpipe@~1.0.0, unpipe@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +untildify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" + dependencies: + os-homedir "^1.0.0" + +user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + +utf8@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.0.tgz#0cfec5c8052d44a23e3aaa908104e8075f95dfd5" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util-extend@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" + +utils-merge@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" + +uuid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + +validate-npm-package-license@^3.0.1, validate-npm-package-license@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +validate-npm-package-name@^2.0.1, validate-npm-package-name@~2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-2.2.2.tgz#f65695b22f7324442019a3c7fa39a6e7fd299085" + dependencies: + builtins "0.0.7" + +vary@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.0.tgz#e1e5affbbd16ae768dd2674394b9ad3022653140" + +verror@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" + dependencies: + extsprintf "1.0.2" + +walk-sync@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.1.3.tgz#8a07261a00bda6cfb1be25e9f100fad57546f583" + +walk-sync@^0.2.5, walk-sync@^0.2.6, walk-sync@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.2.7.tgz#b49be4ee6867657aeb736978b56a29d10fa39969" + dependencies: + ensure-posix-path "^1.0.0" + matcher-collection "^1.0.0" + +walk-sync@^0.3.0, walk-sync@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.3.1.tgz#558a16aeac8c0db59c028b73c66f397684ece465" + dependencies: + ensure-posix-path "^1.0.0" + matcher-collection "^1.0.0" + +walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + dependencies: + makeerror "1.0.x" + +watch@~0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.10.0.tgz#77798b2da0f9910d595f1ace5b0c2258521f21dc" + +wcwidth@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + dependencies: + defaults "^1.0.3" + +websocket-driver@>=0.5.1: + version "0.6.5" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" + dependencies: + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.1.tgz#76899499c184b6ef754377c2dbb0cd6cb55d29e7" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + +which@^1.0.5, which@^1.2.9, which@~1.2.8, which@1: + version "1.2.11" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.11.tgz#c8b2eeea6b8c1659fa7c1dd4fdaabe9533dc5e8b" + dependencies: + isexe "^1.1.1" + +wide-align@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad" + dependencies: + string-width "^1.0.1" + +window-size@^0.1.2: + version "0.1.4" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" + +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wrap-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.0.0.tgz#7d30f8f873f9a5bbc3a64dabc8d177e071ae426f" + dependencies: + string-width "^1.0.1" + +wrappy@~1.0.1, wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.2.0.tgz#14c66d4e4cb3ca0565c28cf3b7a6f3e4d5938fab" + dependencies: + graceful-fs "^4.1.2" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write-file-atomic@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.1.4.tgz#b1f52dc2e8dc0e3cb04d187a25f758a38a90ca3b" + dependencies: + graceful-fs "^4.1.2" + imurmurhash "^0.1.4" + slide "^1.1.5" + +ws@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-1.0.1.tgz#7d0b2a2e58cddd819039c29c9de65045e1b310e9" + dependencies: + options ">=0.0.5" + ultron "1.0.x" + +xdg-basedir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2" + dependencies: + os-homedir "^1.0.0" + +xmldom@^0.1.19: + version "0.1.22" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.22.tgz#10de4e5e964981f03c8cc72fadc08d14b6c3aa26" + +xmlhttprequest-ssl@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.1.tgz#3b7741fea4a86675976e908d296d4445961faa67" + +xtend@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.0, y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.0.0.tgz#306c543835f09ee1a4cb23b7bce9ab341c91cdd4" + +yam@0.0.21: + version "0.0.21" + resolved "https://registry.yarnpkg.com/yam/-/yam-0.0.21.tgz#2b74a3c973193d58bd13cb5018c0245f82c8c6d3" + dependencies: + findup "^0.1.5" + fs-extra "^0.30.0" + lodash.merge "^4.4.0" + +yargs-parser@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" + dependencies: + camelcase "^3.0.0" + lodash.assign "^4.0.6" + +yargs@^4.7.1: + version "4.8.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" + dependencies: + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + lodash.assign "^4.0.3" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.1" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^2.4.1" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" + +yargs@~3.27.0: + version "3.27.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.27.0.tgz#21205469316e939131d59f2da0c6d7f98221ea40" + dependencies: + camelcase "^1.2.1" + cliui "^2.1.0" + decamelize "^1.0.0" + os-locale "^1.4.0" + window-size "^0.1.2" + y18n "^3.2.0" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" +