├── .gitignore
├── LICENSE.md
├── README.md
├── browser
├── index.html
└── mock
│ ├── electron.js
│ ├── fs.js
│ └── require.js
├── desktop
├── icon.icns
├── icon.ico
├── icon.png
├── icon.svg
├── main.js
├── package-lock.json
├── package.json
└── sources
│ ├── index.html
│ ├── links
│ ├── fonts.css
│ ├── main.css
│ ├── reset.css
│ ├── style.css
│ └── theme.css
│ ├── media
│ └── fonts
│ │ ├── input_mono_medium.ttf
│ │ └── input_mono_regular.ttf
│ └── scripts
│ ├── commander.js
│ ├── interface.channel.js
│ ├── interface.effect.js
│ ├── interface.js
│ ├── lib
│ ├── controller.js
│ └── theme.js
│ ├── listener.js
│ ├── mixer.js
│ ├── pilot.js
│ ├── recorder.js
│ └── transpose.js
└── resources
├── device.jpg
└── preview.jpg
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | builds/
3 | .DS_Store
4 | */.DS_Store
5 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Hundredrabbits
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Pilot
2 |
3 | [Pilot](http://wiki.xxiivv.com/Pilot) is a **UDP synthesizer** designed to be controlled externally. It was created as a companion application to the livecoding environment [ORCA](https://hundredrabbits.itch.io/orca).
4 |
5 | ## Install & Run
6 |
7 | You can download [builds](https://hundredrabbits.itch.io/pilot) for **OSX, Windows and Linux**, or if you wish to build it yourself, follow these steps:
8 |
9 | ```
10 | git clone https://github.com/hundredrabbits/Pilot.git
11 | cd Pilot/desktop/
12 | npm install
13 | npm start
14 | ```
15 |
16 |
17 |
18 | ## Commands
19 |
20 | Pilot has 16 voices, and 8 effects. Commands can be entered directly with the input bar, or through UDP via the port `49161`. You can send multiple commands at once by using the `;` character. For example, `03C;13E` will play a `C3` and `E3` chord.
21 |
22 | ### Channel
23 |
24 | #### Play
25 |
26 | The Play commands allows you to play synth notes.
27 |
28 | | Command | Channel | Octave | Note | Velocity | Length |
29 | | :- | :-: | :-: | :-: | :-: | :-: |
30 | | `04C` | 0 | 4 | C | _64_ | _1/16_ |
31 | | `04Cf` | 0 | 4 | C | 127 | _1/16_ |
32 | | `04Cff` | 0 | 4 | C | 127 | 1bar |
33 |
34 | #### Settings
35 |
36 | The Settings commands allow you to change the sound of the synth. The settings command format is a **channel** value between `0-G`, a 3 characters long **name**, followed by four values between `0-G`. The possible waveforms are `si`, `2i`, `4i`, `8i`, `tr`, `2r`, `4r`, `8r`, `sq`, `2q`, `4q` `8q`, `sw`, `2w`, `4w` and `8w`.
37 |
38 | | Command | Channel | Name | Info |
39 | | :- | :- | :- | :- |
40 | | `0ENV056f` | 0 | Envelope | Set **Attack**:0.00, **Decay**:0.33, **Sustain**:0.40 and **Release**:1.00 |
41 | | `1OSCsisq` | 1 | Oscilloscope | Set **Osc1**:Sine, **Osc2**:Square |
42 |
43 | ### Global
44 |
45 | #### Effects
46 |
47 | The Effects are applied to all channels. The effect command format is a 3 characters long **name**, followed by one value between `0-G` for **wet** and **depth**.
48 |
49 | | Command | Channel | Operation | Info |
50 | | :- | :- | :- | :- |
51 | | `BITff` | All | Bitcrusher | .. |
52 | | `DISff` | All | Distortion | .. |
53 | | `WAHff` | All | AutoWah | .. |
54 | | `CHEff` | All | Chebyshev | .. |
55 | | `FEEff` | All | Feedback | .. |
56 | | `DELff` | All | Ping Pong Delay | .. |
57 | | `TREff` | All | Tremolo | .. |
58 | | `REVff` | All | Reverb | .. |
59 | | `PHAff` | All | Pashor | .. |
60 | | `VIBff` | All | Vibrato | .. |
61 | | `CHOff` | All | Chorus | .. |
62 | | `STEff` | All | StereoWidener | .. |
63 | | `EQUff` | All | EQ3 | .. |
64 | | `COMff` | All | Compressor | .. |
65 | | `VOLff` | All | Volume | .. |
66 | | `LIMff` | All | Limiter | .. |
67 |
68 | #### Masters
69 |
70 | `TODO` Add the ability to change the mastering effects like compressor and volume. Coming soon!
71 |
72 | #### Special
73 |
74 | - `bpm140`, sets the BPM to `140`. This command is designed to apply to effects like feedback.
75 | - `renv`, randomizes envelopes.
76 | - `rosc`, randomizes oscillators.
77 | - `refx`, randomizes effects.
78 | - `reset`, reset all.
79 |
80 | ## Record
81 |
82 | Press **cmd/ctrl+r** to record, and press it again to stop.
83 |
84 | ## Convert OGG to MP3
85 |
86 | Just use ffmpeg.
87 |
88 | ```
89 | ~/Documents/ffmpeg -i last.{ogg,mp3}
90 | ```
91 |
92 |
93 |
94 | ## Extras
95 |
96 | - This application supports the [Ecosystem Theme](https://github.com/hundredrabbits/Themes).
97 | - Support this project through [Patreon](https://www.patreon.com/hundredrabbits).
98 | - See the [License](LICENSE.md) file for license rights and limitations (MIT).
99 | - Pull Requests are welcome!
100 |
--------------------------------------------------------------------------------
/browser/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Pilot — Web
9 |
10 |
11 |
12 |
13 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/browser/mock/electron.js:
--------------------------------------------------------------------------------
1 | export let remote = {};
2 |
--------------------------------------------------------------------------------
/browser/mock/fs.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hundredrabbits/Pilot/a77a4e059147d02fbbfb676e2417974a587dbaed/browser/mock/fs.js
--------------------------------------------------------------------------------
/browser/mock/require.js:
--------------------------------------------------------------------------------
1 | import * as dgram from "https://unpkg.com/browser-dgram@latest/index.js";
2 | import * as electron from "./electron.js";
3 | import * as fs from "./fs.js";
4 |
5 | window.require = function(what) {
6 | switch (what) {
7 | case "dgram": return dgram; break;
8 | case "electron": return electron; break;
9 | case "tone": return Tone; break;
10 | case "fs": return fs; break;
11 |
12 | default: console.log(what); break;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/desktop/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hundredrabbits/Pilot/a77a4e059147d02fbbfb676e2417974a587dbaed/desktop/icon.icns
--------------------------------------------------------------------------------
/desktop/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hundredrabbits/Pilot/a77a4e059147d02fbbfb676e2417974a587dbaed/desktop/icon.ico
--------------------------------------------------------------------------------
/desktop/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hundredrabbits/Pilot/a77a4e059147d02fbbfb676e2417974a587dbaed/desktop/icon.png
--------------------------------------------------------------------------------
/desktop/icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/desktop/main.js:
--------------------------------------------------------------------------------
1 | const { app, BrowserWindow, webFrame, Menu, dialog } = require('electron')
2 | const path = require('path')
3 | const url = require('url')
4 | const shell = require('electron').shell
5 |
6 | let isShown = true
7 |
8 | require('electron').protocol.registerSchemesAsPrivileged([
9 | { scheme: 'js', privileges: { standard: true, secure: true } }
10 | ])
11 |
12 | function protocolHandler (request, respond) {
13 | try {
14 | let pathname = request.url.replace(/^js:\/*/, '')
15 | let filename = path.resolve(app.getAppPath(), pathname)
16 | respond({ mimeType: 'text/javascript', data: require('fs').readFileSync(filename) })
17 | } catch (e) {
18 | console.error(e, request)
19 | }
20 | }
21 |
22 | app.on('ready', () => {
23 | require('electron').protocol.registerBufferProtocol('js', protocolHandler)
24 |
25 | app.win = new BrowserWindow({
26 | width: 445,
27 | height: 210,
28 | minWidth: 200,
29 | minHeight: 190,
30 | backgroundColor: '#000',
31 | icon: __dirname + '/' + { darwin: 'icon.icns', linux: 'icon.png', win32: 'icon.ico' }[process.platform] || 'icon.ico',
32 | resizable: true,
33 | frame: process.platform !== 'darwin',
34 | skipTaskbar: process.platform === 'darwin',
35 | autoHideMenuBar: process.platform === 'darwin',
36 | webPreferences: { zoomFactor: 1.0, nodeIntegration: true, backgroundThrottling: false }
37 | })
38 |
39 | app.win.loadURL(`file://${__dirname}/sources/index.html`)
40 | // app.inspect()
41 |
42 | app.win.on('closed', () => {
43 | win = null
44 | app.quit()
45 | })
46 |
47 | app.win.on('hide', function () {
48 | isShown = false
49 | })
50 |
51 | app.win.on('show', function () {
52 | isShown = true
53 | })
54 |
55 | app.on('window-all-closed', () => {
56 | app.quit()
57 | })
58 |
59 | app.on('activate', () => {
60 | if (app.win === null) {
61 | createWindow()
62 | } else {
63 | app.win.show()
64 | }
65 | })
66 | })
67 |
68 | app.inspect = function () {
69 | app.win.toggleDevTools()
70 | }
71 |
72 | app.toggleFullscreen = function () {
73 | app.win.setFullScreen(!app.win.isFullScreen())
74 | }
75 |
76 | app.toggleVisible = function () {
77 | if (process.platform === 'darwin') {
78 | if (isShown && !app.win.isFullScreen()) { app.win.hide() } else { app.win.show() }
79 | } else {
80 | if (!app.win.isMinimized()) { app.win.minimize() } else { app.win.restore() }
81 | }
82 | }
83 |
84 | app.injectMenu = function (menu) {
85 | try {
86 | Menu.setApplicationMenu(Menu.buildFromTemplate(menu))
87 | } catch (err) {
88 | console.warn('Cannot inject menu.')
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/desktop/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Pilot",
3 | "version": "0.1.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@types/node": {
8 | "version": "10.14.6",
9 | "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.6.tgz",
10 | "integrity": "sha512-Fvm24+u85lGmV4hT5G++aht2C5I4Z4dYlWZIh62FAfFO/TfzXtPpoLI6I7AuBWkIFqZCnhFOoTT7RjjaIL5Fjg==",
11 | "dev": true
12 | },
13 | "ajv": {
14 | "version": "6.10.0",
15 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
16 | "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
17 | "dev": true,
18 | "requires": {
19 | "fast-deep-equal": "^2.0.1",
20 | "fast-json-stable-stringify": "^2.0.0",
21 | "json-schema-traverse": "^0.4.1",
22 | "uri-js": "^4.2.2"
23 | }
24 | },
25 | "ansi-regex": {
26 | "version": "2.1.1",
27 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
28 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
29 | "dev": true
30 | },
31 | "array-find-index": {
32 | "version": "1.0.2",
33 | "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
34 | "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
35 | "dev": true
36 | },
37 | "asar": {
38 | "version": "1.0.0",
39 | "resolved": "https://registry.npmjs.org/asar/-/asar-1.0.0.tgz",
40 | "integrity": "sha512-MBiDU5cDr9UWuY2F0zq2fZlnyRq1aOPmJGMas22Qa14K1odpRXL3xkMHPN3uw2hAK5mD89Q+/KidOUtpi4V0Cg==",
41 | "dev": true,
42 | "requires": {
43 | "chromium-pickle-js": "^0.2.0",
44 | "commander": "^2.19.0",
45 | "cuint": "^0.2.2",
46 | "glob": "^7.1.3",
47 | "minimatch": "^3.0.4",
48 | "mkdirp": "^0.5.1",
49 | "pify": "^4.0.1",
50 | "tmp-promise": "^1.0.5"
51 | },
52 | "dependencies": {
53 | "pify": {
54 | "version": "4.0.1",
55 | "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
56 | "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
57 | "dev": true
58 | }
59 | }
60 | },
61 | "asn1": {
62 | "version": "0.2.4",
63 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
64 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
65 | "dev": true,
66 | "requires": {
67 | "safer-buffer": "~2.1.0"
68 | }
69 | },
70 | "assert-plus": {
71 | "version": "1.0.0",
72 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
73 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
74 | "dev": true
75 | },
76 | "asynckit": {
77 | "version": "0.4.0",
78 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
79 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
80 | "dev": true
81 | },
82 | "author-regex": {
83 | "version": "1.0.0",
84 | "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz",
85 | "integrity": "sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA=",
86 | "dev": true
87 | },
88 | "aws-sign2": {
89 | "version": "0.7.0",
90 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
91 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
92 | "dev": true
93 | },
94 | "aws4": {
95 | "version": "1.8.0",
96 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
97 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
98 | "dev": true
99 | },
100 | "balanced-match": {
101 | "version": "1.0.0",
102 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
103 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
104 | "dev": true
105 | },
106 | "base64-js": {
107 | "version": "1.3.0",
108 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
109 | "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==",
110 | "dev": true
111 | },
112 | "bcrypt-pbkdf": {
113 | "version": "1.0.2",
114 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
115 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
116 | "dev": true,
117 | "requires": {
118 | "tweetnacl": "^0.14.3"
119 | }
120 | },
121 | "bluebird": {
122 | "version": "3.5.4",
123 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz",
124 | "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==",
125 | "dev": true
126 | },
127 | "brace-expansion": {
128 | "version": "1.1.11",
129 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
130 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
131 | "dev": true,
132 | "requires": {
133 | "balanced-match": "^1.0.0",
134 | "concat-map": "0.0.1"
135 | }
136 | },
137 | "buffer-alloc": {
138 | "version": "1.2.0",
139 | "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
140 | "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
141 | "dev": true,
142 | "requires": {
143 | "buffer-alloc-unsafe": "^1.1.0",
144 | "buffer-fill": "^1.0.0"
145 | }
146 | },
147 | "buffer-alloc-unsafe": {
148 | "version": "1.1.0",
149 | "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
150 | "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
151 | "dev": true
152 | },
153 | "buffer-fill": {
154 | "version": "1.0.0",
155 | "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
156 | "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
157 | "dev": true
158 | },
159 | "buffer-from": {
160 | "version": "1.1.1",
161 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
162 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
163 | "dev": true
164 | },
165 | "camelcase": {
166 | "version": "2.1.1",
167 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
168 | "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
169 | "dev": true
170 | },
171 | "camelcase-keys": {
172 | "version": "2.1.0",
173 | "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
174 | "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
175 | "dev": true,
176 | "requires": {
177 | "camelcase": "^2.0.0",
178 | "map-obj": "^1.0.0"
179 | }
180 | },
181 | "caseless": {
182 | "version": "0.12.0",
183 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
184 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
185 | "dev": true
186 | },
187 | "chromium-pickle-js": {
188 | "version": "0.2.0",
189 | "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
190 | "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=",
191 | "dev": true
192 | },
193 | "code-point-at": {
194 | "version": "1.1.0",
195 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
196 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
197 | "dev": true
198 | },
199 | "combined-stream": {
200 | "version": "1.0.7",
201 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
202 | "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
203 | "dev": true,
204 | "requires": {
205 | "delayed-stream": "~1.0.0"
206 | }
207 | },
208 | "commander": {
209 | "version": "2.20.0",
210 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
211 | "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
212 | "dev": true
213 | },
214 | "compare-version": {
215 | "version": "0.1.2",
216 | "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz",
217 | "integrity": "sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA=",
218 | "dev": true
219 | },
220 | "concat-map": {
221 | "version": "0.0.1",
222 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
223 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
224 | "dev": true
225 | },
226 | "concat-stream": {
227 | "version": "1.6.2",
228 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
229 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
230 | "dev": true,
231 | "requires": {
232 | "buffer-from": "^1.0.0",
233 | "inherits": "^2.0.3",
234 | "readable-stream": "^2.2.2",
235 | "typedarray": "^0.0.6"
236 | },
237 | "dependencies": {
238 | "isarray": {
239 | "version": "1.0.0",
240 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
241 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
242 | "dev": true
243 | },
244 | "readable-stream": {
245 | "version": "2.3.6",
246 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
247 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
248 | "dev": true,
249 | "requires": {
250 | "core-util-is": "~1.0.0",
251 | "inherits": "~2.0.3",
252 | "isarray": "~1.0.0",
253 | "process-nextick-args": "~2.0.0",
254 | "safe-buffer": "~5.1.1",
255 | "string_decoder": "~1.1.1",
256 | "util-deprecate": "~1.0.1"
257 | }
258 | },
259 | "string_decoder": {
260 | "version": "1.1.1",
261 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
262 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
263 | "dev": true,
264 | "requires": {
265 | "safe-buffer": "~5.1.0"
266 | }
267 | }
268 | }
269 | },
270 | "core-util-is": {
271 | "version": "1.0.2",
272 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
273 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
274 | "dev": true
275 | },
276 | "cuint": {
277 | "version": "0.2.2",
278 | "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz",
279 | "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=",
280 | "dev": true
281 | },
282 | "currently-unhandled": {
283 | "version": "0.4.1",
284 | "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
285 | "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
286 | "dev": true,
287 | "requires": {
288 | "array-find-index": "^1.0.1"
289 | }
290 | },
291 | "dashdash": {
292 | "version": "1.14.1",
293 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
294 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
295 | "dev": true,
296 | "requires": {
297 | "assert-plus": "^1.0.0"
298 | }
299 | },
300 | "debug": {
301 | "version": "3.2.6",
302 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
303 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
304 | "dev": true,
305 | "requires": {
306 | "ms": "^2.1.1"
307 | }
308 | },
309 | "decamelize": {
310 | "version": "1.2.0",
311 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
312 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
313 | "dev": true
314 | },
315 | "deep-extend": {
316 | "version": "0.6.0",
317 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
318 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
319 | "dev": true
320 | },
321 | "delayed-stream": {
322 | "version": "1.0.0",
323 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
324 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
325 | "dev": true
326 | },
327 | "ecc-jsbn": {
328 | "version": "0.1.2",
329 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
330 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
331 | "dev": true,
332 | "requires": {
333 | "jsbn": "~0.1.0",
334 | "safer-buffer": "^2.1.0"
335 | }
336 | },
337 | "electron": {
338 | "version": "5.0.1",
339 | "resolved": "https://registry.npmjs.org/electron/-/electron-5.0.1.tgz",
340 | "integrity": "sha512-8KksyhAPcpXVeO8ViVGxfZAuf8yEVBCtV0h/lMBD8VFbCQ9icej1K5csCFAGirbZbqOz5IdsBZX9Gpb9n4RCag==",
341 | "dev": true,
342 | "requires": {
343 | "@types/node": "^10.12.18",
344 | "electron-download": "^4.1.0",
345 | "extract-zip": "^1.0.3"
346 | }
347 | },
348 | "electron-download": {
349 | "version": "4.1.1",
350 | "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-4.1.1.tgz",
351 | "integrity": "sha512-FjEWG9Jb/ppK/2zToP+U5dds114fM1ZOJqMAR4aXXL5CvyPE9fiqBK/9YcwC9poIFQTEJk/EM/zyRwziziRZrg==",
352 | "dev": true,
353 | "requires": {
354 | "debug": "^3.0.0",
355 | "env-paths": "^1.0.0",
356 | "fs-extra": "^4.0.1",
357 | "minimist": "^1.2.0",
358 | "nugget": "^2.0.1",
359 | "path-exists": "^3.0.0",
360 | "rc": "^1.2.1",
361 | "semver": "^5.4.1",
362 | "sumchecker": "^2.0.2"
363 | }
364 | },
365 | "electron-notarize": {
366 | "version": "0.0.5",
367 | "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-0.0.5.tgz",
368 | "integrity": "sha512-YzrqZ6RDQ7Wt2RWlxzRoQUuxnTeXrfp7laH7XKcmQqrZ6GaAr50DMPvFMpqDKdrZSHSbcgZgB7ktIQbjvITmCQ==",
369 | "dev": true,
370 | "requires": {
371 | "debug": "^4.1.0",
372 | "fs-extra": "^7.0.0"
373 | },
374 | "dependencies": {
375 | "debug": {
376 | "version": "4.1.1",
377 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
378 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
379 | "dev": true,
380 | "requires": {
381 | "ms": "^2.1.1"
382 | }
383 | },
384 | "fs-extra": {
385 | "version": "7.0.1",
386 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
387 | "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
388 | "dev": true,
389 | "requires": {
390 | "graceful-fs": "^4.1.2",
391 | "jsonfile": "^4.0.0",
392 | "universalify": "^0.1.0"
393 | }
394 | }
395 | }
396 | },
397 | "electron-osx-sign": {
398 | "version": "0.4.11",
399 | "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.11.tgz",
400 | "integrity": "sha512-VVd40nrnVqymvFrY9ZkOYgHJOvexHHYTR3di/SN+mjJ0OWhR1I8BRVj3U+Yamw6hnkZZNKZp52rqL5EFAAPFkQ==",
401 | "dev": true,
402 | "requires": {
403 | "bluebird": "^3.5.0",
404 | "compare-version": "^0.1.2",
405 | "debug": "^2.6.8",
406 | "isbinaryfile": "^3.0.2",
407 | "minimist": "^1.2.0",
408 | "plist": "^3.0.1"
409 | },
410 | "dependencies": {
411 | "debug": {
412 | "version": "2.6.9",
413 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
414 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
415 | "dev": true,
416 | "requires": {
417 | "ms": "2.0.0"
418 | }
419 | },
420 | "ms": {
421 | "version": "2.0.0",
422 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
423 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
424 | "dev": true
425 | }
426 | }
427 | },
428 | "electron-packager": {
429 | "version": "13.1.1",
430 | "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-13.1.1.tgz",
431 | "integrity": "sha512-3Drgcw8OEOP3Psw/PprloAFJSkSUSQgjUq3AmWffJGB3Kj5WXmZl6A3GOUs8aT7bP/8GWg4oYqSiCSnA5PQkdQ==",
432 | "dev": true,
433 | "requires": {
434 | "asar": "^1.0.0",
435 | "debug": "^4.0.1",
436 | "electron-download": "^4.1.1",
437 | "electron-notarize": "^0.0.5",
438 | "electron-osx-sign": "^0.4.11",
439 | "extract-zip": "^1.0.3",
440 | "fs-extra": "^7.0.0",
441 | "galactus": "^0.2.1",
442 | "get-package-info": "^1.0.0",
443 | "parse-author": "^2.0.0",
444 | "pify": "^4.0.0",
445 | "plist": "^3.0.0",
446 | "rcedit": "^1.0.0",
447 | "resolve": "^1.1.6",
448 | "sanitize-filename": "^1.6.0",
449 | "semver": "^5.3.0",
450 | "yargs-parser": "^13.0.0"
451 | },
452 | "dependencies": {
453 | "debug": {
454 | "version": "4.1.1",
455 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
456 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
457 | "dev": true,
458 | "requires": {
459 | "ms": "^2.1.1"
460 | }
461 | },
462 | "fs-extra": {
463 | "version": "7.0.1",
464 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
465 | "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
466 | "dev": true,
467 | "requires": {
468 | "graceful-fs": "^4.1.2",
469 | "jsonfile": "^4.0.0",
470 | "universalify": "^0.1.0"
471 | }
472 | },
473 | "pify": {
474 | "version": "4.0.1",
475 | "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
476 | "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
477 | "dev": true
478 | }
479 | }
480 | },
481 | "env-paths": {
482 | "version": "1.0.0",
483 | "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz",
484 | "integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=",
485 | "dev": true
486 | },
487 | "error-ex": {
488 | "version": "1.3.2",
489 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
490 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
491 | "dev": true,
492 | "requires": {
493 | "is-arrayish": "^0.2.1"
494 | }
495 | },
496 | "extend": {
497 | "version": "3.0.2",
498 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
499 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
500 | "dev": true
501 | },
502 | "extract-zip": {
503 | "version": "1.6.7",
504 | "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
505 | "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
506 | "dev": true,
507 | "requires": {
508 | "concat-stream": "1.6.2",
509 | "debug": "2.6.9",
510 | "mkdirp": "0.5.1",
511 | "yauzl": "2.4.1"
512 | },
513 | "dependencies": {
514 | "debug": {
515 | "version": "2.6.9",
516 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
517 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
518 | "dev": true,
519 | "requires": {
520 | "ms": "2.0.0"
521 | }
522 | },
523 | "ms": {
524 | "version": "2.0.0",
525 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
526 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
527 | "dev": true
528 | }
529 | }
530 | },
531 | "extsprintf": {
532 | "version": "1.3.0",
533 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
534 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
535 | "dev": true
536 | },
537 | "fast-deep-equal": {
538 | "version": "2.0.1",
539 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
540 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
541 | "dev": true
542 | },
543 | "fast-json-stable-stringify": {
544 | "version": "2.0.0",
545 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
546 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
547 | "dev": true
548 | },
549 | "fd-slicer": {
550 | "version": "1.0.1",
551 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
552 | "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
553 | "dev": true,
554 | "requires": {
555 | "pend": "~1.2.0"
556 | }
557 | },
558 | "find-up": {
559 | "version": "1.1.2",
560 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
561 | "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
562 | "dev": true,
563 | "requires": {
564 | "path-exists": "^2.0.0",
565 | "pinkie-promise": "^2.0.0"
566 | },
567 | "dependencies": {
568 | "path-exists": {
569 | "version": "2.1.0",
570 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
571 | "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
572 | "dev": true,
573 | "requires": {
574 | "pinkie-promise": "^2.0.0"
575 | }
576 | }
577 | }
578 | },
579 | "flora-colossus": {
580 | "version": "1.0.0",
581 | "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-1.0.0.tgz",
582 | "integrity": "sha1-VHKcNh7ezuAU3UQWeeGjfB13OkU=",
583 | "dev": true,
584 | "requires": {
585 | "debug": "^3.1.0",
586 | "fs-extra": "^4.0.0"
587 | }
588 | },
589 | "forever-agent": {
590 | "version": "0.6.1",
591 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
592 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
593 | "dev": true
594 | },
595 | "form-data": {
596 | "version": "2.3.3",
597 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
598 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
599 | "dev": true,
600 | "requires": {
601 | "asynckit": "^0.4.0",
602 | "combined-stream": "^1.0.6",
603 | "mime-types": "^2.1.12"
604 | }
605 | },
606 | "fs-extra": {
607 | "version": "4.0.3",
608 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
609 | "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
610 | "dev": true,
611 | "requires": {
612 | "graceful-fs": "^4.1.2",
613 | "jsonfile": "^4.0.0",
614 | "universalify": "^0.1.0"
615 | }
616 | },
617 | "fs.realpath": {
618 | "version": "1.0.0",
619 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
620 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
621 | "dev": true
622 | },
623 | "galactus": {
624 | "version": "0.2.1",
625 | "resolved": "https://registry.npmjs.org/galactus/-/galactus-0.2.1.tgz",
626 | "integrity": "sha1-y+0tIKQMH1Z5o1kI4rlBVzPnjbk=",
627 | "dev": true,
628 | "requires": {
629 | "debug": "^3.1.0",
630 | "flora-colossus": "^1.0.0",
631 | "fs-extra": "^4.0.0"
632 | }
633 | },
634 | "get-package-info": {
635 | "version": "1.0.0",
636 | "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz",
637 | "integrity": "sha1-ZDJ5ZWPigRPNlHTbvQAFKYWkmZw=",
638 | "dev": true,
639 | "requires": {
640 | "bluebird": "^3.1.1",
641 | "debug": "^2.2.0",
642 | "lodash.get": "^4.0.0",
643 | "read-pkg-up": "^2.0.0"
644 | },
645 | "dependencies": {
646 | "debug": {
647 | "version": "2.6.9",
648 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
649 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
650 | "dev": true,
651 | "requires": {
652 | "ms": "2.0.0"
653 | }
654 | },
655 | "find-up": {
656 | "version": "2.1.0",
657 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
658 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
659 | "dev": true,
660 | "requires": {
661 | "locate-path": "^2.0.0"
662 | }
663 | },
664 | "load-json-file": {
665 | "version": "2.0.0",
666 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
667 | "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
668 | "dev": true,
669 | "requires": {
670 | "graceful-fs": "^4.1.2",
671 | "parse-json": "^2.2.0",
672 | "pify": "^2.0.0",
673 | "strip-bom": "^3.0.0"
674 | }
675 | },
676 | "ms": {
677 | "version": "2.0.0",
678 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
679 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
680 | "dev": true
681 | },
682 | "path-type": {
683 | "version": "2.0.0",
684 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
685 | "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
686 | "dev": true,
687 | "requires": {
688 | "pify": "^2.0.0"
689 | }
690 | },
691 | "read-pkg": {
692 | "version": "2.0.0",
693 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
694 | "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
695 | "dev": true,
696 | "requires": {
697 | "load-json-file": "^2.0.0",
698 | "normalize-package-data": "^2.3.2",
699 | "path-type": "^2.0.0"
700 | }
701 | },
702 | "read-pkg-up": {
703 | "version": "2.0.0",
704 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
705 | "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
706 | "dev": true,
707 | "requires": {
708 | "find-up": "^2.0.0",
709 | "read-pkg": "^2.0.0"
710 | }
711 | },
712 | "strip-bom": {
713 | "version": "3.0.0",
714 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
715 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
716 | "dev": true
717 | }
718 | }
719 | },
720 | "get-stdin": {
721 | "version": "4.0.1",
722 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
723 | "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
724 | "dev": true
725 | },
726 | "getpass": {
727 | "version": "0.1.7",
728 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
729 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
730 | "dev": true,
731 | "requires": {
732 | "assert-plus": "^1.0.0"
733 | }
734 | },
735 | "glob": {
736 | "version": "7.1.3",
737 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
738 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
739 | "dev": true,
740 | "requires": {
741 | "fs.realpath": "^1.0.0",
742 | "inflight": "^1.0.4",
743 | "inherits": "2",
744 | "minimatch": "^3.0.4",
745 | "once": "^1.3.0",
746 | "path-is-absolute": "^1.0.0"
747 | }
748 | },
749 | "graceful-fs": {
750 | "version": "4.1.15",
751 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
752 | "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
753 | "dev": true
754 | },
755 | "har-schema": {
756 | "version": "2.0.0",
757 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
758 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
759 | "dev": true
760 | },
761 | "har-validator": {
762 | "version": "5.1.3",
763 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
764 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
765 | "dev": true,
766 | "requires": {
767 | "ajv": "^6.5.5",
768 | "har-schema": "^2.0.0"
769 | }
770 | },
771 | "hosted-git-info": {
772 | "version": "2.7.1",
773 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
774 | "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
775 | "dev": true
776 | },
777 | "http-signature": {
778 | "version": "1.2.0",
779 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
780 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
781 | "dev": true,
782 | "requires": {
783 | "assert-plus": "^1.0.0",
784 | "jsprim": "^1.2.2",
785 | "sshpk": "^1.7.0"
786 | }
787 | },
788 | "indent-string": {
789 | "version": "2.1.0",
790 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
791 | "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
792 | "dev": true,
793 | "requires": {
794 | "repeating": "^2.0.0"
795 | }
796 | },
797 | "inflight": {
798 | "version": "1.0.6",
799 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
800 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
801 | "dev": true,
802 | "requires": {
803 | "once": "^1.3.0",
804 | "wrappy": "1"
805 | }
806 | },
807 | "inherits": {
808 | "version": "2.0.3",
809 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
810 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
811 | "dev": true
812 | },
813 | "ini": {
814 | "version": "1.3.5",
815 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
816 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
817 | "dev": true
818 | },
819 | "is-arrayish": {
820 | "version": "0.2.1",
821 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
822 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
823 | "dev": true
824 | },
825 | "is-finite": {
826 | "version": "1.0.2",
827 | "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
828 | "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
829 | "dev": true,
830 | "requires": {
831 | "number-is-nan": "^1.0.0"
832 | }
833 | },
834 | "is-fullwidth-code-point": {
835 | "version": "1.0.0",
836 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
837 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
838 | "dev": true,
839 | "requires": {
840 | "number-is-nan": "^1.0.0"
841 | }
842 | },
843 | "is-typedarray": {
844 | "version": "1.0.0",
845 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
846 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
847 | "dev": true
848 | },
849 | "is-utf8": {
850 | "version": "0.2.1",
851 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
852 | "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
853 | "dev": true
854 | },
855 | "isarray": {
856 | "version": "0.0.1",
857 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
858 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
859 | "dev": true
860 | },
861 | "isbinaryfile": {
862 | "version": "3.0.3",
863 | "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz",
864 | "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==",
865 | "dev": true,
866 | "requires": {
867 | "buffer-alloc": "^1.2.0"
868 | }
869 | },
870 | "isstream": {
871 | "version": "0.1.2",
872 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
873 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
874 | "dev": true
875 | },
876 | "jsbn": {
877 | "version": "0.1.1",
878 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
879 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
880 | "dev": true
881 | },
882 | "json-schema": {
883 | "version": "0.2.3",
884 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
885 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
886 | "dev": true
887 | },
888 | "json-schema-traverse": {
889 | "version": "0.4.1",
890 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
891 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
892 | "dev": true
893 | },
894 | "json-stringify-safe": {
895 | "version": "5.0.1",
896 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
897 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
898 | "dev": true
899 | },
900 | "jsonfile": {
901 | "version": "4.0.0",
902 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
903 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
904 | "dev": true,
905 | "requires": {
906 | "graceful-fs": "^4.1.6"
907 | }
908 | },
909 | "jsprim": {
910 | "version": "1.4.1",
911 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
912 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
913 | "dev": true,
914 | "requires": {
915 | "assert-plus": "1.0.0",
916 | "extsprintf": "1.3.0",
917 | "json-schema": "0.2.3",
918 | "verror": "1.10.0"
919 | }
920 | },
921 | "load-json-file": {
922 | "version": "1.1.0",
923 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
924 | "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
925 | "dev": true,
926 | "requires": {
927 | "graceful-fs": "^4.1.2",
928 | "parse-json": "^2.2.0",
929 | "pify": "^2.0.0",
930 | "pinkie-promise": "^2.0.0",
931 | "strip-bom": "^2.0.0"
932 | }
933 | },
934 | "locate-path": {
935 | "version": "2.0.0",
936 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
937 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
938 | "dev": true,
939 | "requires": {
940 | "p-locate": "^2.0.0",
941 | "path-exists": "^3.0.0"
942 | }
943 | },
944 | "lodash.get": {
945 | "version": "4.4.2",
946 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
947 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
948 | "dev": true
949 | },
950 | "loud-rejection": {
951 | "version": "1.6.0",
952 | "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
953 | "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
954 | "dev": true,
955 | "requires": {
956 | "currently-unhandled": "^0.4.1",
957 | "signal-exit": "^3.0.0"
958 | }
959 | },
960 | "map-obj": {
961 | "version": "1.0.1",
962 | "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
963 | "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
964 | "dev": true
965 | },
966 | "meow": {
967 | "version": "3.7.0",
968 | "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
969 | "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
970 | "dev": true,
971 | "requires": {
972 | "camelcase-keys": "^2.0.0",
973 | "decamelize": "^1.1.2",
974 | "loud-rejection": "^1.0.0",
975 | "map-obj": "^1.0.1",
976 | "minimist": "^1.1.3",
977 | "normalize-package-data": "^2.3.4",
978 | "object-assign": "^4.0.1",
979 | "read-pkg-up": "^1.0.1",
980 | "redent": "^1.0.0",
981 | "trim-newlines": "^1.0.0"
982 | }
983 | },
984 | "mime-db": {
985 | "version": "1.40.0",
986 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
987 | "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
988 | "dev": true
989 | },
990 | "mime-types": {
991 | "version": "2.1.24",
992 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
993 | "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
994 | "dev": true,
995 | "requires": {
996 | "mime-db": "1.40.0"
997 | }
998 | },
999 | "minimatch": {
1000 | "version": "3.0.4",
1001 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
1002 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
1003 | "dev": true,
1004 | "requires": {
1005 | "brace-expansion": "^1.1.7"
1006 | }
1007 | },
1008 | "minimist": {
1009 | "version": "1.2.0",
1010 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
1011 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
1012 | "dev": true
1013 | },
1014 | "mkdirp": {
1015 | "version": "0.5.1",
1016 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
1017 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
1018 | "dev": true,
1019 | "requires": {
1020 | "minimist": "0.0.8"
1021 | },
1022 | "dependencies": {
1023 | "minimist": {
1024 | "version": "0.0.8",
1025 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
1026 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
1027 | "dev": true
1028 | }
1029 | }
1030 | },
1031 | "ms": {
1032 | "version": "2.1.1",
1033 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
1034 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
1035 | "dev": true
1036 | },
1037 | "normalize-package-data": {
1038 | "version": "2.5.0",
1039 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
1040 | "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
1041 | "dev": true,
1042 | "requires": {
1043 | "hosted-git-info": "^2.1.4",
1044 | "resolve": "^1.10.0",
1045 | "semver": "2 || 3 || 4 || 5",
1046 | "validate-npm-package-license": "^3.0.1"
1047 | }
1048 | },
1049 | "nugget": {
1050 | "version": "2.0.1",
1051 | "resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz",
1052 | "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=",
1053 | "dev": true,
1054 | "requires": {
1055 | "debug": "^2.1.3",
1056 | "minimist": "^1.1.0",
1057 | "pretty-bytes": "^1.0.2",
1058 | "progress-stream": "^1.1.0",
1059 | "request": "^2.45.0",
1060 | "single-line-log": "^1.1.2",
1061 | "throttleit": "0.0.2"
1062 | },
1063 | "dependencies": {
1064 | "debug": {
1065 | "version": "2.6.9",
1066 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1067 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1068 | "dev": true,
1069 | "requires": {
1070 | "ms": "2.0.0"
1071 | }
1072 | },
1073 | "ms": {
1074 | "version": "2.0.0",
1075 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1076 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
1077 | "dev": true
1078 | }
1079 | }
1080 | },
1081 | "number-is-nan": {
1082 | "version": "1.0.1",
1083 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
1084 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
1085 | "dev": true
1086 | },
1087 | "oauth-sign": {
1088 | "version": "0.9.0",
1089 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
1090 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
1091 | "dev": true
1092 | },
1093 | "object-assign": {
1094 | "version": "4.1.1",
1095 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1096 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
1097 | "dev": true
1098 | },
1099 | "object-keys": {
1100 | "version": "0.4.0",
1101 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
1102 | "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
1103 | "dev": true
1104 | },
1105 | "once": {
1106 | "version": "1.4.0",
1107 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1108 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1109 | "dev": true,
1110 | "requires": {
1111 | "wrappy": "1"
1112 | }
1113 | },
1114 | "os-tmpdir": {
1115 | "version": "1.0.2",
1116 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
1117 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
1118 | "dev": true
1119 | },
1120 | "p-limit": {
1121 | "version": "1.3.0",
1122 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
1123 | "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
1124 | "dev": true,
1125 | "requires": {
1126 | "p-try": "^1.0.0"
1127 | }
1128 | },
1129 | "p-locate": {
1130 | "version": "2.0.0",
1131 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
1132 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
1133 | "dev": true,
1134 | "requires": {
1135 | "p-limit": "^1.1.0"
1136 | }
1137 | },
1138 | "p-try": {
1139 | "version": "1.0.0",
1140 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
1141 | "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
1142 | "dev": true
1143 | },
1144 | "parse-author": {
1145 | "version": "2.0.0",
1146 | "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz",
1147 | "integrity": "sha1-00YL8d3Q367tQtp1QkLmX7aEqB8=",
1148 | "dev": true,
1149 | "requires": {
1150 | "author-regex": "^1.0.0"
1151 | }
1152 | },
1153 | "parse-json": {
1154 | "version": "2.2.0",
1155 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
1156 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
1157 | "dev": true,
1158 | "requires": {
1159 | "error-ex": "^1.2.0"
1160 | }
1161 | },
1162 | "path-exists": {
1163 | "version": "3.0.0",
1164 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
1165 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
1166 | "dev": true
1167 | },
1168 | "path-is-absolute": {
1169 | "version": "1.0.1",
1170 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1171 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
1172 | "dev": true
1173 | },
1174 | "path-parse": {
1175 | "version": "1.0.6",
1176 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
1177 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
1178 | "dev": true
1179 | },
1180 | "path-type": {
1181 | "version": "1.1.0",
1182 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
1183 | "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
1184 | "dev": true,
1185 | "requires": {
1186 | "graceful-fs": "^4.1.2",
1187 | "pify": "^2.0.0",
1188 | "pinkie-promise": "^2.0.0"
1189 | }
1190 | },
1191 | "pend": {
1192 | "version": "1.2.0",
1193 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
1194 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
1195 | "dev": true
1196 | },
1197 | "performance-now": {
1198 | "version": "2.1.0",
1199 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
1200 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
1201 | "dev": true
1202 | },
1203 | "pify": {
1204 | "version": "2.3.0",
1205 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
1206 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
1207 | "dev": true
1208 | },
1209 | "pinkie": {
1210 | "version": "2.0.4",
1211 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
1212 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
1213 | "dev": true
1214 | },
1215 | "pinkie-promise": {
1216 | "version": "2.0.1",
1217 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
1218 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
1219 | "dev": true,
1220 | "requires": {
1221 | "pinkie": "^2.0.0"
1222 | }
1223 | },
1224 | "plist": {
1225 | "version": "3.0.1",
1226 | "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz",
1227 | "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==",
1228 | "dev": true,
1229 | "requires": {
1230 | "base64-js": "^1.2.3",
1231 | "xmlbuilder": "^9.0.7",
1232 | "xmldom": "0.1.x"
1233 | }
1234 | },
1235 | "pretty-bytes": {
1236 | "version": "1.0.4",
1237 | "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
1238 | "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=",
1239 | "dev": true,
1240 | "requires": {
1241 | "get-stdin": "^4.0.1",
1242 | "meow": "^3.1.0"
1243 | }
1244 | },
1245 | "process-nextick-args": {
1246 | "version": "2.0.0",
1247 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
1248 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
1249 | "dev": true
1250 | },
1251 | "progress-stream": {
1252 | "version": "1.2.0",
1253 | "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz",
1254 | "integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=",
1255 | "dev": true,
1256 | "requires": {
1257 | "speedometer": "~0.1.2",
1258 | "through2": "~0.2.3"
1259 | }
1260 | },
1261 | "psl": {
1262 | "version": "1.1.31",
1263 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz",
1264 | "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==",
1265 | "dev": true
1266 | },
1267 | "punycode": {
1268 | "version": "2.1.1",
1269 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
1270 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
1271 | "dev": true
1272 | },
1273 | "qs": {
1274 | "version": "6.5.2",
1275 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
1276 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
1277 | "dev": true
1278 | },
1279 | "rc": {
1280 | "version": "1.2.8",
1281 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
1282 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
1283 | "dev": true,
1284 | "requires": {
1285 | "deep-extend": "^0.6.0",
1286 | "ini": "~1.3.0",
1287 | "minimist": "^1.2.0",
1288 | "strip-json-comments": "~2.0.1"
1289 | }
1290 | },
1291 | "rcedit": {
1292 | "version": "1.1.2",
1293 | "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-1.1.2.tgz",
1294 | "integrity": "sha512-z2ypB4gbINhI6wVe0JJMmdpmOpmNc4g90sE6/6JSuch5kYnjfz9CxvVPqqhShgR6GIkmtW3W2UlfiXhWljA0Fw==",
1295 | "dev": true
1296 | },
1297 | "read-pkg": {
1298 | "version": "1.1.0",
1299 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
1300 | "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
1301 | "dev": true,
1302 | "requires": {
1303 | "load-json-file": "^1.0.0",
1304 | "normalize-package-data": "^2.3.2",
1305 | "path-type": "^1.0.0"
1306 | }
1307 | },
1308 | "read-pkg-up": {
1309 | "version": "1.0.1",
1310 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
1311 | "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
1312 | "dev": true,
1313 | "requires": {
1314 | "find-up": "^1.0.0",
1315 | "read-pkg": "^1.0.0"
1316 | }
1317 | },
1318 | "readable-stream": {
1319 | "version": "1.1.14",
1320 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
1321 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
1322 | "dev": true,
1323 | "requires": {
1324 | "core-util-is": "~1.0.0",
1325 | "inherits": "~2.0.1",
1326 | "isarray": "0.0.1",
1327 | "string_decoder": "~0.10.x"
1328 | }
1329 | },
1330 | "redent": {
1331 | "version": "1.0.0",
1332 | "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
1333 | "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
1334 | "dev": true,
1335 | "requires": {
1336 | "indent-string": "^2.1.0",
1337 | "strip-indent": "^1.0.1"
1338 | }
1339 | },
1340 | "repeating": {
1341 | "version": "2.0.1",
1342 | "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
1343 | "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
1344 | "dev": true,
1345 | "requires": {
1346 | "is-finite": "^1.0.0"
1347 | }
1348 | },
1349 | "request": {
1350 | "version": "2.88.0",
1351 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
1352 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
1353 | "dev": true,
1354 | "requires": {
1355 | "aws-sign2": "~0.7.0",
1356 | "aws4": "^1.8.0",
1357 | "caseless": "~0.12.0",
1358 | "combined-stream": "~1.0.6",
1359 | "extend": "~3.0.2",
1360 | "forever-agent": "~0.6.1",
1361 | "form-data": "~2.3.2",
1362 | "har-validator": "~5.1.0",
1363 | "http-signature": "~1.2.0",
1364 | "is-typedarray": "~1.0.0",
1365 | "isstream": "~0.1.2",
1366 | "json-stringify-safe": "~5.0.1",
1367 | "mime-types": "~2.1.19",
1368 | "oauth-sign": "~0.9.0",
1369 | "performance-now": "^2.1.0",
1370 | "qs": "~6.5.2",
1371 | "safe-buffer": "^5.1.2",
1372 | "tough-cookie": "~2.4.3",
1373 | "tunnel-agent": "^0.6.0",
1374 | "uuid": "^3.3.2"
1375 | }
1376 | },
1377 | "resolve": {
1378 | "version": "1.10.1",
1379 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz",
1380 | "integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==",
1381 | "dev": true,
1382 | "requires": {
1383 | "path-parse": "^1.0.6"
1384 | }
1385 | },
1386 | "safe-buffer": {
1387 | "version": "5.1.2",
1388 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
1389 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
1390 | "dev": true
1391 | },
1392 | "safer-buffer": {
1393 | "version": "2.1.2",
1394 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1395 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1396 | "dev": true
1397 | },
1398 | "sanitize-filename": {
1399 | "version": "1.6.1",
1400 | "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.1.tgz",
1401 | "integrity": "sha1-YS2hyWRz+gLczaktzVtKsWSmdyo=",
1402 | "dev": true,
1403 | "requires": {
1404 | "truncate-utf8-bytes": "^1.0.0"
1405 | }
1406 | },
1407 | "semver": {
1408 | "version": "5.7.0",
1409 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
1410 | "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
1411 | "dev": true
1412 | },
1413 | "signal-exit": {
1414 | "version": "3.0.2",
1415 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
1416 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
1417 | "dev": true
1418 | },
1419 | "single-line-log": {
1420 | "version": "1.1.2",
1421 | "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz",
1422 | "integrity": "sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q=",
1423 | "dev": true,
1424 | "requires": {
1425 | "string-width": "^1.0.1"
1426 | }
1427 | },
1428 | "spdx-correct": {
1429 | "version": "3.1.0",
1430 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
1431 | "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
1432 | "dev": true,
1433 | "requires": {
1434 | "spdx-expression-parse": "^3.0.0",
1435 | "spdx-license-ids": "^3.0.0"
1436 | }
1437 | },
1438 | "spdx-exceptions": {
1439 | "version": "2.2.0",
1440 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
1441 | "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
1442 | "dev": true
1443 | },
1444 | "spdx-expression-parse": {
1445 | "version": "3.0.0",
1446 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
1447 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
1448 | "dev": true,
1449 | "requires": {
1450 | "spdx-exceptions": "^2.1.0",
1451 | "spdx-license-ids": "^3.0.0"
1452 | }
1453 | },
1454 | "spdx-license-ids": {
1455 | "version": "3.0.4",
1456 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz",
1457 | "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==",
1458 | "dev": true
1459 | },
1460 | "speedometer": {
1461 | "version": "0.1.4",
1462 | "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-0.1.4.tgz",
1463 | "integrity": "sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0=",
1464 | "dev": true
1465 | },
1466 | "sshpk": {
1467 | "version": "1.16.1",
1468 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
1469 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
1470 | "dev": true,
1471 | "requires": {
1472 | "asn1": "~0.2.3",
1473 | "assert-plus": "^1.0.0",
1474 | "bcrypt-pbkdf": "^1.0.0",
1475 | "dashdash": "^1.12.0",
1476 | "ecc-jsbn": "~0.1.1",
1477 | "getpass": "^0.1.1",
1478 | "jsbn": "~0.1.0",
1479 | "safer-buffer": "^2.0.2",
1480 | "tweetnacl": "~0.14.0"
1481 | }
1482 | },
1483 | "string-width": {
1484 | "version": "1.0.2",
1485 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
1486 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
1487 | "dev": true,
1488 | "requires": {
1489 | "code-point-at": "^1.0.0",
1490 | "is-fullwidth-code-point": "^1.0.0",
1491 | "strip-ansi": "^3.0.0"
1492 | }
1493 | },
1494 | "string_decoder": {
1495 | "version": "0.10.31",
1496 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
1497 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
1498 | "dev": true
1499 | },
1500 | "strip-ansi": {
1501 | "version": "3.0.1",
1502 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
1503 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
1504 | "dev": true,
1505 | "requires": {
1506 | "ansi-regex": "^2.0.0"
1507 | }
1508 | },
1509 | "strip-bom": {
1510 | "version": "2.0.0",
1511 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
1512 | "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
1513 | "dev": true,
1514 | "requires": {
1515 | "is-utf8": "^0.2.0"
1516 | }
1517 | },
1518 | "strip-indent": {
1519 | "version": "1.0.1",
1520 | "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
1521 | "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
1522 | "dev": true,
1523 | "requires": {
1524 | "get-stdin": "^4.0.1"
1525 | }
1526 | },
1527 | "strip-json-comments": {
1528 | "version": "2.0.1",
1529 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
1530 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
1531 | "dev": true
1532 | },
1533 | "sumchecker": {
1534 | "version": "2.0.2",
1535 | "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-2.0.2.tgz",
1536 | "integrity": "sha1-D0LBDl0F2l1C7qPlbDOZo31sWz4=",
1537 | "dev": true,
1538 | "requires": {
1539 | "debug": "^2.2.0"
1540 | },
1541 | "dependencies": {
1542 | "debug": {
1543 | "version": "2.6.9",
1544 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1545 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1546 | "dev": true,
1547 | "requires": {
1548 | "ms": "2.0.0"
1549 | }
1550 | },
1551 | "ms": {
1552 | "version": "2.0.0",
1553 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1554 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
1555 | "dev": true
1556 | }
1557 | }
1558 | },
1559 | "throttleit": {
1560 | "version": "0.0.2",
1561 | "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz",
1562 | "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=",
1563 | "dev": true
1564 | },
1565 | "through2": {
1566 | "version": "0.2.3",
1567 | "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
1568 | "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
1569 | "dev": true,
1570 | "requires": {
1571 | "readable-stream": "~1.1.9",
1572 | "xtend": "~2.1.1"
1573 | }
1574 | },
1575 | "tmp": {
1576 | "version": "0.0.33",
1577 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
1578 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
1579 | "dev": true,
1580 | "requires": {
1581 | "os-tmpdir": "~1.0.2"
1582 | }
1583 | },
1584 | "tmp-promise": {
1585 | "version": "1.0.5",
1586 | "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-1.0.5.tgz",
1587 | "integrity": "sha512-hOabTz9Tp49wCozFwuJe5ISrOqkECm6kzw66XTP23DuzNU7QS/KiZq5LC9Y7QSy8f1rPSLy4bKaViP0OwGI1cA==",
1588 | "dev": true,
1589 | "requires": {
1590 | "bluebird": "^3.5.0",
1591 | "tmp": "0.0.33"
1592 | }
1593 | },
1594 | "tone": {
1595 | "version": "13.4.9",
1596 | "resolved": "https://registry.npmjs.org/tone/-/tone-13.4.9.tgz",
1597 | "integrity": "sha512-jU3MJOzt9wcGbo57TIzgAQe13EgwvdC7N6N/cA6ZkGYHH8gop+L6a87NRP3LIBCcJxVps6I6i/39ZUJI2aCWUA=="
1598 | },
1599 | "tough-cookie": {
1600 | "version": "2.4.3",
1601 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
1602 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
1603 | "dev": true,
1604 | "requires": {
1605 | "psl": "^1.1.24",
1606 | "punycode": "^1.4.1"
1607 | },
1608 | "dependencies": {
1609 | "punycode": {
1610 | "version": "1.4.1",
1611 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
1612 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
1613 | "dev": true
1614 | }
1615 | }
1616 | },
1617 | "trim-newlines": {
1618 | "version": "1.0.0",
1619 | "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
1620 | "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
1621 | "dev": true
1622 | },
1623 | "truncate-utf8-bytes": {
1624 | "version": "1.0.2",
1625 | "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
1626 | "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=",
1627 | "dev": true,
1628 | "requires": {
1629 | "utf8-byte-length": "^1.0.1"
1630 | }
1631 | },
1632 | "tunnel-agent": {
1633 | "version": "0.6.0",
1634 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
1635 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
1636 | "dev": true,
1637 | "requires": {
1638 | "safe-buffer": "^5.0.1"
1639 | }
1640 | },
1641 | "tweetnacl": {
1642 | "version": "0.14.5",
1643 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
1644 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
1645 | "dev": true
1646 | },
1647 | "typedarray": {
1648 | "version": "0.0.6",
1649 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
1650 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
1651 | "dev": true
1652 | },
1653 | "universalify": {
1654 | "version": "0.1.2",
1655 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
1656 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
1657 | "dev": true
1658 | },
1659 | "uri-js": {
1660 | "version": "4.2.2",
1661 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
1662 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
1663 | "dev": true,
1664 | "requires": {
1665 | "punycode": "^2.1.0"
1666 | }
1667 | },
1668 | "utf8-byte-length": {
1669 | "version": "1.0.4",
1670 | "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
1671 | "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=",
1672 | "dev": true
1673 | },
1674 | "util-deprecate": {
1675 | "version": "1.0.2",
1676 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1677 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
1678 | "dev": true
1679 | },
1680 | "uuid": {
1681 | "version": "3.3.2",
1682 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
1683 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
1684 | "dev": true
1685 | },
1686 | "validate-npm-package-license": {
1687 | "version": "3.0.4",
1688 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
1689 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
1690 | "dev": true,
1691 | "requires": {
1692 | "spdx-correct": "^3.0.0",
1693 | "spdx-expression-parse": "^3.0.0"
1694 | }
1695 | },
1696 | "verror": {
1697 | "version": "1.10.0",
1698 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
1699 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
1700 | "dev": true,
1701 | "requires": {
1702 | "assert-plus": "^1.0.0",
1703 | "core-util-is": "1.0.2",
1704 | "extsprintf": "^1.2.0"
1705 | }
1706 | },
1707 | "wrappy": {
1708 | "version": "1.0.2",
1709 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1710 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
1711 | "dev": true
1712 | },
1713 | "xmlbuilder": {
1714 | "version": "9.0.7",
1715 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
1716 | "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
1717 | "dev": true
1718 | },
1719 | "xmldom": {
1720 | "version": "0.1.27",
1721 | "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",
1722 | "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=",
1723 | "dev": true
1724 | },
1725 | "xtend": {
1726 | "version": "2.1.2",
1727 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
1728 | "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
1729 | "dev": true,
1730 | "requires": {
1731 | "object-keys": "~0.4.0"
1732 | }
1733 | },
1734 | "yargs-parser": {
1735 | "version": "13.0.0",
1736 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz",
1737 | "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==",
1738 | "dev": true,
1739 | "requires": {
1740 | "camelcase": "^5.0.0",
1741 | "decamelize": "^1.2.0"
1742 | },
1743 | "dependencies": {
1744 | "camelcase": {
1745 | "version": "5.3.1",
1746 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
1747 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
1748 | "dev": true
1749 | }
1750 | }
1751 | },
1752 | "yauzl": {
1753 | "version": "2.4.1",
1754 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
1755 | "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
1756 | "dev": true,
1757 | "requires": {
1758 | "fd-slicer": "~1.0.1"
1759 | }
1760 | }
1761 | }
1762 | }
1763 |
--------------------------------------------------------------------------------
/desktop/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Pilot",
3 | "version": "0.1.0",
4 | "main": "main.js",
5 | "scripts": {
6 | "start": "electron .",
7 | "time": "node time.js",
8 | "docs": "node ../docs.js",
9 | "fix": "standard --fix",
10 | "clean": "rm -r ~/Desktop/Pilot-darwin-x64/ ; rm -r ~/Desktop/Pilot-linux-x64/ ; rm -r ~/Desktop/Pilot-win32-x64/ ; echo 'cleaned build location'",
11 | "build_osx": "electron-packager . Pilot --platform=darwin --arch=x64 --out ~/Desktop/ --overwrite --icon=icon.icns ; echo 'Built for OSX'",
12 | "build_linux": "electron-packager . Pilot --platform=linux --arch=x64 --out ~/Desktop/ --overwrite --icon=icon.ico ; echo 'Built for LINUX'",
13 | "build_win": "electron-packager . Pilot --platform=win32 --arch=x64 --out ~/Desktop/ --overwrite --icon=icon.ico ; echo 'Built for WIN'",
14 | "build": "npm run clean ; npm run build_osx ; npm run build_linux ; npm run build_win",
15 | "push_osx": "~/butler push ~/Desktop/Pilot-darwin-x64/ hundredrabbits/pilot:osx-64",
16 | "push_linux": "~/butler push ~/Desktop/Pilot-linux-x64/ hundredrabbits/pilot:linux-64",
17 | "push_win": "~/butler push ~/Desktop/Pilot-win32-x64/ hundredrabbits/pilot:windows-64",
18 | "push_status": "~/butler status hundredrabbits/pilot",
19 | "push": "npm run build ; npm run push_osx ; npm run push_linux ; npm run push_win ; npm run clean ; npm run push_status"
20 | },
21 | "devDependencies": {
22 | "electron": "^5.0.1",
23 | "electron-packager": "^13.1.1"
24 | },
25 | "dependencies": {
26 | "tone": "^13.4.9"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/desktop/sources/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Pilot
9 |
10 |
11 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/desktop/sources/links/fonts.css:
--------------------------------------------------------------------------------
1 | /* Input */
2 |
3 | @font-face {
4 | font-family: 'input_mono_regular';
5 | src: url('../media/fonts/input_mono_regular.ttf') format('truetype');
6 | font-weight: normal;
7 | font-style: normal;
8 | }
9 |
10 | @font-face {
11 | font-family: 'input_mono_medium';
12 | src: url('../media/fonts/input_mono_medium.ttf') format('truetype');
13 | font-weight: normal;
14 | font-style: normal;
15 | }
--------------------------------------------------------------------------------
/desktop/sources/links/main.css:
--------------------------------------------------------------------------------
1 | body { background:black; padding: 30px; font-family: 'input_mono_regular'; font-size: 11px; line-height: 15px; -webkit-app-region: drag; transition: background-color 500ms; overflow: hidden;}
2 |
3 | /* Mixer */
4 |
5 | #mixer { line-height: 15px; color:#666; position: relative; text-transform: uppercase; min-width: 420px}
6 | #mixer > div { position: absolute; width: 95px}
7 | #mixer > div.channel { position: absolute; }
8 | #mixer > div.effect { width:65px; }
9 | #mixer > div .cid { font-family: 'input_mono_medium'; font-weight: normal; }
10 | #mixer > div canvas { position: absolute; right: -10px;top: 0.5px;}
11 | #mixer span { padding: 0px 2.55px; }
12 |
13 | #mixer #ch0 { top:calc(0 * 15px); left:0px; }
14 | #mixer #ch1 { top:calc(1 * 15px); left:0px; }
15 | #mixer #ch2 { top:calc(2 * 15px); left:0px; }
16 | #mixer #ch3 { top:calc(3 * 15px); left:0px; }
17 | #mixer #ch4 { top:calc(4 * 15px); left:0px; }
18 | #mixer #ch5 { top:calc(5 * 15px); left:0px; }
19 | #mixer #ch6 { top:calc(6 * 15px); left:0px; }
20 | #mixer #ch7 { top:calc(7 * 15px); left:0px; }
21 |
22 | #mixer #ch8 { top:calc(0 * 15px); left:calc(1 * 110px); }
23 | #mixer #ch9 { top:calc(1 * 15px); left:calc(1 * 110px); }
24 | #mixer #cha { top:calc(2 * 15px); left:calc(1 * 110px); }
25 | #mixer #chb { top:calc(3 * 15px); left:calc(1 * 110px); }
26 | #mixer #chc { top:calc(4 * 15px); left:calc(1 * 110px); }
27 | #mixer #chd { top:calc(5 * 15px); left:calc(1 * 110px); }
28 | #mixer #che { top:calc(6 * 15px); left:calc(1 * 110px); }
29 | #mixer #chf { top:calc(7 * 15px); left:calc(1 * 110px); }
30 |
31 | #mixer #chbit { top:calc(0 * 15px); left:calc(2 * 110px); }
32 | #mixer #chdis { top:calc(1 * 15px); left:calc(2 * 110px); }
33 | #mixer #chwah { top:calc(2 * 15px); left:calc(2 * 110px); }
34 | #mixer #chche { top:calc(3 * 15px); left:calc(2 * 110px); }
35 | #mixer #chfee { top:calc(4 * 15px); left:calc(2 * 110px); }
36 | #mixer #chdel { top:calc(5 * 15px); left:calc(2 * 110px); }
37 | #mixer #chtre { top:calc(6 * 15px); left:calc(2 * 110px); }
38 | #mixer #chrev { top:calc(7 * 15px); left:calc(2 * 110px); }
39 |
40 | #mixer #chpha { top:calc(0 * 15px); left:calc(2 * 150px); }
41 | #mixer #chvib { top:calc(1 * 15px); left:calc(2 * 150px); }
42 | #mixer #chcho { top:calc(2 * 15px); left:calc(2 * 150px); }
43 | #mixer #chste { top:calc(3 * 15px); left:calc(2 * 150px); }
44 | #mixer #chequ { top:calc(4 * 15px); left:calc(2 * 150px); }
45 | #mixer #chcom { top:calc(5 * 15px); left:calc(2 * 150px); }
46 | #mixer #chvol { top:calc(6 * 15px); left:calc(2 * 150px); }
47 | #mixer #chlim { top:calc(7 * 15px); left:calc(2 * 150px); }
48 |
49 | /* Commander */
50 |
51 | #commander input { padding: 0px 5px 0px 2.5px; width: calc(100vw - 70px); background: transparent; }
52 |
53 | /* Recorder */
54 |
55 | #pilot.recording #recorder { animation: blink 500ms linear infinite; }
56 | #recorder { position: absolute; top: calc(11 * 15px); color: #333; left: 30px; font-family: 'input_mono_medium'; font-weight: normal;}
57 |
58 | #commander { top: calc(11 * 15px); left: 55px; position: absolute; line-height: 11px; }
59 |
60 | @media (max-width: 420px) {
61 | #pilot #mixer { columns:1 !important; min-width: 0px }
62 | #pilot #mixer > div { max-width: 100%}
63 |
64 | #mixer #ch0 { top:calc(0 * 15px); left:0px; }
65 | #mixer #ch1 { top:calc(1 * 15px); left:0px; }
66 | #mixer #ch2 { top:calc(2 * 15px); left:0px; }
67 | #mixer #ch3 { top:calc(3 * 15px); left:0px; }
68 | #mixer #ch4 { top:calc(4 * 15px); left:0px; }
69 | #mixer #ch5 { top:calc(5 * 15px); left:0px; }
70 | #mixer #ch6 { top:calc(6 * 15px); left:0px; }
71 | #mixer #ch7 { top:calc(7 * 15px); left:0px; }
72 | #mixer #ch8 { top:calc(8 * 15px); left:0px; }
73 | #mixer #ch9 { top:calc(9 * 15px); left:0px; }
74 | #mixer #cha { top:calc(10 * 15px); left:0px; }
75 | #mixer #chb { top:calc(11 * 15px); left:0px; }
76 | #mixer #chc { top:calc(12 * 15px); left:0px; }
77 | #mixer #chd { top:calc(13 * 15px); left:0px; }
78 | #mixer #che { top:calc(14 * 15px); left:0px; }
79 | #mixer #chf { top:calc(15 * 15px); left:0px; }
80 |
81 | #mixer #chbit { top:calc(0 * 15px); left:calc(1 * 110px) }
82 | #mixer #chdis { top:calc(1 * 15px); left:calc(1 * 110px) }
83 | #mixer #chwah { top:calc(2 * 15px); left:calc(1 * 110px) }
84 | #mixer #chche { top:calc(3 * 15px); left:calc(1 * 110px) }
85 | #mixer #chfee { top:calc(4 * 15px); left:calc(1 * 110px) }
86 | #mixer #chdel { top:calc(5 * 15px); left:calc(1 * 110px) }
87 | #mixer #chtre { top:calc(6 * 15px); left:calc(1 * 110px) }
88 | #mixer #chrev { top:calc(7 * 15px); left:calc(1 * 110px) }
89 | #mixer #chpha { top:calc(8 * 15px); left:calc(1 * 110px) }
90 | #mixer #chvib { top:calc(9 * 15px); left:calc(1 * 110px) }
91 | #mixer #chcho { top:calc(10 * 15px); left:calc(1 * 110px) }
92 | #mixer #chste { top:calc(11 * 15px); left:calc(1 * 110px) }
93 | #mixer #chequ { top:calc(12 * 15px); left:calc(1 * 110px) }
94 | #mixer #chcom { top:calc(13 * 15px); left:calc(1 * 110px) }
95 | #mixer #chvol { top:calc(14 * 15px); left:calc(1 * 110px) }
96 | #mixer #chlim { top:calc(15 * 15px); left:calc(1 * 110px) }
97 |
98 | #commander {top:calc(17 * 16px); }
99 | #recorder {top:calc(17 * 16px); }
100 | }
--------------------------------------------------------------------------------
/desktop/sources/links/reset.css:
--------------------------------------------------------------------------------
1 | * { margin:0;padding:0;border:0;outline:0;text-decoration:none;font-weight:inherit;font-style:inherit;color:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;list-style:none;border-collapse:collapse;border-spacing:0; -webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}
--------------------------------------------------------------------------------
/desktop/sources/links/style.css:
--------------------------------------------------------------------------------
1 | @import url(reset.css);
2 | @import url(fonts.css);
3 | @import url(main.css);
4 | @import url(theme.css);
5 |
--------------------------------------------------------------------------------
/desktop/sources/links/theme.css:
--------------------------------------------------------------------------------
1 | body { background:var(--background) !important; color:var(--f_high) !important; }
2 |
3 | #mixer > div span { color:var(--f_high) !important; }
4 | #mixer > div span.cid { color:var(--f_low) !important; }
5 | #mixer > div .oct { background-color: var(--background) !important; -webkit-transition: background-color 250ms linear; }
6 | #mixer > div .env { background-color: var(--background) !important; -webkit-transition: background-color 250ms linear; }
7 | #mixer > div .osc { background-color: var(--background) !important; -webkit-transition: background-color 250ms linear; }
8 | #mixer > div .val { background-color: var(--background) !important; -webkit-transition: background-color 250ms linear; }
9 |
10 | #mixer > div .oct.active { background-color: var(--b_med) !important; -webkit-transition: background-color 1ms linear; color:var(--background) !important; }
11 | #mixer > div .env.active { background-color: var(--b_inv) !important; -webkit-transition: background-color 1ms linear; color:var(--background) !important; }
12 | #mixer > div .osc.active { background-color: var(--b_inv) !important; -webkit-transition: background-color 1ms linear; color:var(--background) !important; }
13 | #mixer > div .val.active { background-color: var(--b_inv) !important; -webkit-transition: background-color 1ms linear; color:var(--background) !important; }
14 |
15 | #commander input { color:var(--f_high) !important; }
16 |
17 | #pilot.recording #recorder { color:var(--b_inv) !important; }
18 |
19 | @keyframes blink {
20 | 0% { color: var(--b_inv) !important; }
21 | 100% { color: black; }
22 | }
23 |
24 | @-webkit-keyframes blink {
25 | 0% { color: var(--b_inv) !important; }
26 | 100% { color: black; }
27 | }
--------------------------------------------------------------------------------
/desktop/sources/media/fonts/input_mono_medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hundredrabbits/Pilot/a77a4e059147d02fbbfb676e2417974a587dbaed/desktop/sources/media/fonts/input_mono_medium.ttf
--------------------------------------------------------------------------------
/desktop/sources/media/fonts/input_mono_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hundredrabbits/Pilot/a77a4e059147d02fbbfb676e2417974a587dbaed/desktop/sources/media/fonts/input_mono_regular.ttf
--------------------------------------------------------------------------------
/desktop/sources/scripts/commander.js:
--------------------------------------------------------------------------------
1 | export default function Commander (pilot) {
2 | this.el = document.createElement('div')
3 | this.el.id = 'commander'
4 |
5 | this.input = document.createElement('input')
6 |
7 | // History of commands entered.
8 | this.history = []
9 |
10 | // Index of history command to show in input.
11 | this.historyIndex = 0
12 |
13 | // Holds whether the user is browsing the history or not.
14 | this.isBrowsingHistory = false
15 |
16 | this.install = function (host) {
17 | this.el.appendChild(this.input)
18 | host.appendChild(this.el)
19 | }
20 |
21 | this.start = function () {
22 | this.input.focus()
23 | }
24 |
25 | this.input.oninput = (e) => {
26 |
27 | }
28 |
29 | this.input.onkeydown = (e) => {
30 | switch (e.keyCode) {
31 | case 40: // Down
32 | e.preventDefault()
33 | if (!this.isBrowsingHistory) {
34 | return
35 | }
36 |
37 | if (this.history.length) {
38 | if (this.historyIndex === this.history.length - 1) {
39 | this.isBrowsingHistory = false
40 | this.input.value = ''
41 | return
42 | }
43 |
44 | this.historyIndex += 1
45 | this.input.value = this.history[this.historyIndex]
46 | }
47 | break
48 | case 38: // Up
49 | e.preventDefault()
50 | if (!this.isBrowsingHistory) {
51 | this.historyIndex = this.history.length
52 | }
53 |
54 | this.isBrowsingHistory = true
55 | if (this.history.length && this.historyIndex > 0) {
56 | this.historyIndex -= 1
57 | this.input.value = this.history[this.historyIndex]
58 | }
59 |
60 | break
61 | }
62 | }
63 |
64 | this.input.onkeypress = (e) => {
65 | if (e.keyCode !== 13) { return }
66 | e.preventDefault()
67 | this.isBrowsingHistory = false
68 | this.history.push(this.input.value)
69 | pilot.mixer.run(this.input.value)
70 | this.input.value = ''
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/desktop/sources/scripts/interface.channel.js:
--------------------------------------------------------------------------------
1 | import Interface from './interface.js'
2 | import transposeTable from './transpose.js'
3 | 'use strict'
4 |
5 | const Tone = require('tone')
6 |
7 | const OCTAVE = ['C', 'c', 'D', 'd', 'E', 'F', 'f', 'G', 'g', 'A', 'a', 'B']
8 | const MAJOR = ['C', 'D', 'E', 'F', 'G', 'A', 'B']
9 | const MINOR = ['c', 'd', 'F', 'f', 'g', 'a', 'C']
10 | const WAVCODES = ['si', 'tr', 'sq', 'sw', '2i', '2r', '2q', '2w', '4i', '4r', '4q', '4w', '8i', '8r', '8q', '8w']
11 | const WAVNAMES = ['sine', 'triangle', 'square', 'sawtooth', 'sine2', 'triangle2', 'square2', 'sawtooth2', 'sine4', 'triangle4', 'square4', 'sawtooth4', 'sine8', 'triangle8', 'square8', 'sawtooth8']
12 |
13 | export default function ChannelInterface (pilot, id, node) {
14 | Interface.call(this, pilot, id, node, true)
15 |
16 | this.node = node
17 |
18 | this.el = document.createElement('div')
19 | this.el.id = `ch${id.toString(16)}`
20 | this.el.className = 'channel'
21 | this.cid_el = document.createElement('span')
22 | this.cid_el.className = `cid`
23 | this.env_el = document.createElement('span')
24 | this.env_el.className = `env`
25 | this.osc_el = document.createElement('span')
26 | this.osc_el.className = `osc`
27 |
28 | this.cid_el.innerHTML = `${str36(id)}`
29 |
30 | this.el.appendChild(this.cid_el)
31 | this.el.appendChild(this.env_el)
32 | this.el.appendChild(this.osc_el)
33 | this.el.appendChild(this.canvas)
34 |
35 | // Run
36 |
37 | this.run = function (msg) {
38 | const channel = `${msg}`.substr(0, 1)
39 | if (int36(channel) === id) {
40 | this.operate(`${msg}`.substr(1))
41 | }
42 | }
43 |
44 | this.operate = function (msg) {
45 | const data = parse(`${msg}`)
46 | if (!data) { console.warn(`Unknown data`); return }
47 | if (data.isEnv) {
48 | this.setEnv(data)
49 | } else if (data.isOsc) {
50 | this.setOsc(data)
51 | } else if (data.isNote) {
52 | this.playNote(data)
53 | } else if (data.isRen) {
54 | this.randEnv()
55 | } else if (data.isRos) {
56 | this.randOsc()
57 | }
58 | }
59 |
60 | this.playNote = function (data) {
61 | if (isNaN(data.octave)) { return }
62 | if (OCTAVE.indexOf(data.note) < 0) { console.warn(`Unknown Note`); return }
63 | if (this.lastNote && performance.now() - this.lastNote < 100) { return }
64 | const name = `${data.note}${data.sharp}${data.octave}`
65 | const length = clamp(data.length, 0.1, 0.9)
66 | this.node.triggerAttackRelease(name, length, '+0', data.velocity)
67 | this.lastNote = performance.now()
68 | }
69 |
70 | this.setEnv = function (data) {
71 | if (this.lastEnv && performance.now() - this.lastEnv < 100) { return }
72 | if (!this.node.envelope) { return }
73 | if (id > 11) { return }
74 | if (!isNaN(data.attack)) { this.node.envelope.attack = clamp(data.attack, 0.01, 1.0) }
75 | if (!isNaN(data.decay)) { this.node.envelope.decay = clamp(data.decay, 0.01, 1.0) }
76 | if (!isNaN(data.sustain)) { this.node.envelope.sustain = clamp(data.sustain, 0.01, 1.0) }
77 | if (!isNaN(data.release)) { this.node.envelope.release = clamp(data.release, 0.01, 1.0) }
78 | this.lastEnv = performance.now()
79 | this.updateEnv(data)
80 | }
81 |
82 | this.setOsc = function (data) {
83 | if (this.lastOsc && performance.now() - this.lastOsc < 100) { return }
84 | if (data.wav && this.node.oscillator) {
85 | this.node.oscillator._oscillator.set('type', data.wav)
86 | }
87 | if (data.mod && this.node.modulation) {
88 | this.node.modulation._oscillator.set('type', data.mod)
89 | }
90 | this.lastOsc = performance.now()
91 | this.updateOsc(data)
92 | }
93 |
94 | // Updates
95 |
96 | this.updateAll = function (data, force = false) {
97 | this.updateEnv(data, force)
98 | this.updateOsc(data, force)
99 | }
100 |
101 | this.updateEnv = function (data, force = false) {
102 | if (pilot.animate !== true) { return }
103 | if (force !== true && (!data || !data.isEnv)) { return }
104 | if (!this.node.envelope) { return }
105 | setContent(this.env_el, `${to16(this.node.envelope.attack)}${to16(this.node.envelope.decay)}${to16(this.node.envelope.sustain)}${to16(this.node.envelope.release)}`)
106 | }
107 |
108 | this.updateOsc = function (data, force = false) {
109 | if (pilot.animate !== true) { return }
110 | if (force !== true && (!data || !data.isOsc)) { return }
111 | setContent(this.osc_el, `${this.node.oscillator ? wavCode(this.node.oscillator._oscillator.type) : '--'}${this.node.modulation ? wavCode(this.node.modulation._oscillator.type) : '--'}`)
112 | }
113 |
114 | this.randEnv = function () {
115 | const a = to16(Math.random() * 0.25)
116 | const s = to16(Math.random() * 0.5)
117 | const d = to16(Math.random() * 0.75)
118 | const r = to16(Math.random() * 1)
119 | this.operate(`env${a}${s}${d}${r}`)
120 | }
121 |
122 | this.randOsc = function () {
123 | const a = WAVCODES[parseInt(Math.random() * WAVCODES.length)]
124 | const b = WAVCODES[parseInt(Math.random() * WAVCODES.length)]
125 | this.operate(`osc${a}${b}`)
126 | }
127 |
128 | // Parsers
129 |
130 | function parse (msg) {
131 | const cmd = msg.substr(0, 3).toLowerCase()
132 | const val = msg.substr(3)
133 | if (cmd === 'osc') {
134 | return parseOsc(val)
135 | } else if (cmd === 'env') {
136 | return parseEnv(val)
137 | } else if (cmd === 'ren') {
138 | return { isRen: true }
139 | } else if (cmd === 'ros') {
140 | return { isRos: true }
141 | }
142 | return parseNote(msg)
143 | }
144 |
145 | function parseNote (msg) {
146 | if (msg.length < 2) { console.warn(`Misformatted note`); return }
147 | const octave = clamp(parseInt(msg.substr(0, 1)), 0, 8)
148 | const note = msg.substr(1, 1)
149 | const velocity = msg.length >= 3 ? from16(msg.substr(2, 1)) : 0.66
150 | const length = msg.length === 4 ? from16(msg.substr(3, 1)) : 0.1
151 | const transposed = transpose(note, octave)
152 | console.log(transposed)
153 | return { isNote: true, octave: transposed.octave, note: transposed.note, sharp: isUpperCase(transposed.note) === false ? '#' : '', string: `${octave}${note}`, length: length, velocity: velocity }
154 | }
155 |
156 | function parseEnv (msg) {
157 | if (msg.length < 1) { console.warn(`Misformatted env`); return }
158 | const attack = int36(msg.substr(0, 1)) / 15
159 | const decay = msg.length > 1 ? int36(msg.substr(1, 1)) / 15 : null
160 | const sustain = msg.length > 2 ? int36(msg.substr(2, 1)) / 15 : null
161 | const release = msg.length > 3 ? int36(msg.substr(3, 1)) / 15 : null
162 | return { isEnv: true, attack: attack, decay: decay, sustain: sustain, release: release, string: 'env' }
163 | }
164 |
165 | function parseOsc (msg) {
166 | if (msg.length < 2) { console.warn(`Misformatted osc`); return }
167 | return { isOsc: true, wav: (msg.length > 1 ? wavName(msg.substr(0, 2)) : null), mod: (msg.length > 3 ? wavName(msg.substr(2, 2)) : null), string: 'osc' }
168 | }
169 |
170 | // Tools
171 |
172 | function transpose (n, o = 3) {
173 | if (!transposeTable[n]) { console.log('Unknown transpose: ', n); return null }
174 | const octave = clamp(parseInt(o) + parseInt(transposeTable[n].charAt(1)), 0, 8)
175 | const note = transposeTable[n].charAt(0)
176 | const value = ['C', 'c', 'D', 'd', 'E', 'F', 'f', 'G', 'g', 'A', 'a', 'B'].indexOf(note)
177 | const id = clamp((octave * 12) + value + 24, 0, 127)
178 | return { id, value, note, octave }
179 | }
180 |
181 | // Wave Codes
182 |
183 | function wavCode (n) {
184 | const name = n.toLowerCase()
185 | const index = WAVNAMES.indexOf(name)
186 | return index > -1 ? WAVCODES[index] : '??'
187 | }
188 |
189 | function wavName (c) {
190 | const code = c.toLowerCase()
191 | const index = WAVCODES.indexOf(code)
192 | return index > -1 ? WAVNAMES[index] : 'sine'
193 | }
194 |
195 | // Helpers
196 | function letterValue (c) { return c.toLowerCase().charCodeAt(0) - 97 }
197 | function isUpperCase (s) { return `${s}`.toUpperCase() === `${s}` }
198 | function from16 (str) { return (int36(str) / 15) }
199 | function to16 (float) { return str36(Math.floor(float * 15)) }
200 | function str36 (int) { return ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'][parseInt(int)] }
201 | function int36 (str) { return ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'].indexOf(`${str.toLowerCase()}`) }
202 | function clamp (v, min, max) { return v < min ? min : v > max ? max : v }
203 |
204 | // Dom Tools
205 | function setClass (el, cl) { if (el.className !== cl) { el.className = cl } }
206 | function setContent (el, ct) { if (el.innerHTML !== ct) { el.innerHTML = ct } }
207 | }
208 |
--------------------------------------------------------------------------------
/desktop/sources/scripts/interface.effect.js:
--------------------------------------------------------------------------------
1 | import Interface from './interface.js'
2 | const Tone = require('tone')
3 |
4 | export default function EffectInterface (pilot, id, node) {
5 | Interface.call(this, pilot, id, node, true)
6 |
7 | this.node = node
8 | if (this.node.wet) {
9 | this.node.wet.value = 0
10 | }
11 |
12 | this.el = document.createElement('div')
13 | this.el.id = `ch${id}`
14 | this.el.className = 'effect'
15 | this.cid_el = document.createElement('span')
16 | this.cid_el.className = `cid`
17 | this.val_el = document.createElement('span')
18 | this.val_el.className = `val`
19 |
20 | this.cid_el.innerHTML = `${id}`
21 |
22 | this.el.appendChild(this.cid_el)
23 | this.el.appendChild(this.val_el)
24 |
25 | // Run
26 |
27 | this.run = function (msg) {
28 | if (!msg || msg.substr(0, 3).toLowerCase() !== id) { return }
29 |
30 | if (msg.substr(0, 3).toLowerCase() === id) {
31 | this.operate(`${msg}`.substr(3))
32 | }
33 | }
34 |
35 | this.operate = function (msg) {
36 | const data = parse(`${msg}`)
37 | if (!data) { console.warn(`Unknown data`); return }
38 | this.setEffect(data)
39 | }
40 |
41 | this.setEffect = function (data) {
42 | if (this.lastEffect && performance.now() - this.lastEffect < 100) { return }
43 |
44 | if (this.node.wet) {
45 | this.node.wet.value = data.wet
46 | }
47 |
48 | if (!isNaN(data.value)) {
49 | if (data.code === 'rev') {
50 | this.node.roomSize.value = data.value
51 | } else if (data.code === 'dis') {
52 | this.node.distortion = data.value
53 | } else if (data.code === 'bit') {
54 | this.node.bits = clamp(parseInt(data.value * 8), 1, 8)
55 | } else if (data.code === 'cho') {
56 | this.node.depth = data.value
57 | } else if (data.code === 'fee') {
58 | this.node.delayTime.value = data.value
59 | } else if (data.code === 'tre') {
60 | this.node.depth.value = data.value
61 | } else if (data.code === 'vib') {
62 | this.node.depth.value = data.value
63 | } else if (data.code === 'aut') {
64 | this.node.depth.value = data.value
65 | } else if (data.code === 'pha') {
66 | this.node.octaves = clamp(parseInt(data.value * 3), 0, 8)
67 | } else if (data.code === 'wah') {
68 | this.node.octaves = clamp(parseInt(data.value * 6), 0, 8)
69 | } else if (data.code === 'che') {
70 | this.node.order = clamp(parseInt(data.value * 100), 0, 8)
71 | } else {
72 | console.warn('Unknown value', this.node)
73 | }
74 | }
75 | this.lastEffect = performance.now()
76 | this.updateEffect(data, true)
77 | }
78 |
79 | this.rand = function () {
80 | this.operate(`${to16(Math.random() * 0.5)}${to16(Math.random() * 1)}`)
81 | }
82 |
83 | // Updates
84 |
85 | this.updateAll = function (data, force = false) {
86 | this.updateEffect(data, force)
87 | }
88 |
89 | this.updateEffect = function (data, force = false) {
90 | if (pilot.animate !== true) { return }
91 | if (force !== true && (!data || !data.isEffect)) { return }
92 |
93 | let value = 0
94 | if (id === 'rev') {
95 | value = this.node.roomSize.value
96 | } else if (id === 'dis') {
97 | value = this.node.distortion
98 | } else if (id === 'cho') {
99 | value = this.node.depth
100 | } else if (id === 'bit') {
101 | value = this.node.bits / 8
102 | } else if (id === 'fee') {
103 | value = this.node.delayTime.value
104 | } else if (id === 'tre') {
105 | value = this.node.depth.value
106 | } else if (id === 'vib') {
107 | value = this.node.depth.value
108 | } else if (id === 'aut') {
109 | value = this.node.depth.value
110 | } else if (id === 'pha') {
111 | value = this.node.octaves / 3
112 | } else if (id === 'wah') {
113 | value = this.node.octaves / 6
114 | } else if (id === 'che') {
115 | value = this.node.order / 100
116 | }
117 |
118 | if (this.node.wet) {
119 | setContent(this.val_el, `${to16(this.node.wet.value)}${to16(value)}`)
120 | }
121 | }
122 |
123 | // Parsers
124 |
125 | function parse (msg) {
126 | if (msg.length !== 2 && msg.length !== 1) { console.warn(`Misformatted effect`, msg); return }
127 | const wet = int36(msg.substr(0, 1)) / 15
128 | const value = int36(msg.substr(1, 1)) / 15
129 | return { isEffect: true, code: id, wet: wet, value: value }
130 | }
131 |
132 | // Helpers
133 | function from16 (str) { return (int36(str) / 15) }
134 | function to16 (float) { return str36(Math.floor(float * 15)) }
135 | function str36 (int) { return ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'][parseInt(int)] }
136 | function int36 (str) { return ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'].indexOf(`${str}`) }
137 | function clamp (v, min, max) { return v < min ? min : v > max ? max : v }
138 |
139 | // Dom Tools
140 | function setContent (el, ct) { if (el.innerHTML !== ct) { el.innerHTML = ct } }
141 | }
142 |
--------------------------------------------------------------------------------
/desktop/sources/scripts/interface.js:
--------------------------------------------------------------------------------
1 | const Tone = require('tone')
2 |
3 | export default function Interface (pilot, id, node) {
4 | this.node = node
5 | this.meter = new Tone.Meter(0.95)
6 | this.waveform = new Tone.Waveform(256)
7 |
8 | this.el = document.createElement('div')
9 | this.el.id = `ch${id}`
10 | this.canvas = document.createElement('canvas')
11 |
12 | const self = this
13 |
14 | const waveform = this.waveform
15 | const meter = this.meter
16 | const canvasWidth = 13 * 4
17 | const canvasHeight = 13 * 2
18 | const context = this.canvas.getContext('2d')
19 |
20 | let lastUpdate = null
21 |
22 | this.install = function (host) {
23 | this.canvas.width = canvasWidth
24 | this.canvas.height = canvasHeight
25 | this.canvas.style.width = (canvasWidth / 2) + 'px'
26 | this.canvas.style.height = (canvasHeight / 2) + 'px'
27 |
28 | context.lineJoin = 'round'
29 | context.lineWidth = 2
30 | context.strokeStyle = pilot.theme.active.f_high
31 |
32 | this.node.connect(this.meter)
33 | this.node.fan(this.waveform)
34 | this.el.appendChild(this.canvas)
35 | host.appendChild(this.el)
36 | }
37 |
38 | this.start = function () {
39 | this.updateAll({}, true)
40 | loop()
41 | }
42 |
43 | this.connect = function (node) {
44 | this.node.connect(node)
45 | }
46 |
47 | function draw (level) {
48 | if (pilot.animate !== true) { return }
49 | if (lastUpdate && performance.now() - lastUpdate < 30) { return }
50 |
51 | context.clearRect(0, 0, canvasWidth, canvasHeight)
52 |
53 | drawActivity()
54 | drawWaveform()
55 |
56 | lastUpdate = performance.now()
57 | }
58 |
59 | function drawWaveform () {
60 | const values = waveform.getValue()
61 | const level = meter.getLevel()
62 | const gain = Tone.dbToGain(level)
63 |
64 | context.beginPath()
65 | context.moveTo(0, parseInt(((values[0] + 1) / 2) * canvasHeight))
66 |
67 | if (gain > 0.01) {
68 | for (let i = 1, len = values.length; i < len; i++) {
69 | if (i % 17 !== 0) { continue }
70 | const x = parseInt(canvasWidth * (i / len))
71 | const y = parseInt(((values[i] + 1) / 2) * canvasHeight)
72 | context.lineTo(clamp(x, 2, canvasWidth - 2), clamp(y, 2, canvasHeight - 2))
73 | }
74 | }
75 |
76 | context.lineTo(canvasWidth, parseInt(((values[0] + 1) / 2) * canvasHeight))
77 |
78 | context.stroke()
79 | context.closePath()
80 | }
81 |
82 | function drawActivity () {
83 | if (!self) { return }
84 | if (!self.lastNote) { return }
85 |
86 | const elapsed = performance.now() - self.lastNote
87 | const max = 500
88 |
89 | context.beginPath()
90 | context.arc(2, 4, 2, 0, 2 * Math.PI, false)
91 | context.fillStyle = `rgba(255,255,255,${(1 - (elapsed / max))})`
92 | context.fill()
93 | context.closePath()
94 | }
95 |
96 | function loop () {
97 | requestAnimationFrame(loop)
98 | draw()
99 | }
100 |
101 | function clamp (v, min, max) { return v < min ? min : v > max ? max : v }
102 | }
103 |
--------------------------------------------------------------------------------
/desktop/sources/scripts/lib/controller.js:
--------------------------------------------------------------------------------
1 | export default function Controller () {
2 | const fs = require('fs')
3 | const { dialog, app } = require('electron').remote
4 |
5 | this.menu = { default: {} }
6 | this.mode = 'default'
7 |
8 | this.app = require('electron').remote.app
9 |
10 | this.start = function () {
11 | }
12 |
13 | this.add = function (mode, cat, label, fn, accelerator) {
14 | if (!this.menu[mode]) { this.menu[mode] = {} }
15 | if (!this.menu[mode][cat]) { this.menu[mode][cat] = {} }
16 | this.menu[mode][cat][label] = { fn: fn, accelerator: accelerator }
17 | }
18 |
19 | this.addRole = function (mode, cat, label) {
20 | if (!this.menu[mode]) { this.menu[mode] = {} }
21 | if (!this.menu[mode][cat]) { this.menu[mode][cat] = {} }
22 | this.menu[mode][cat][label] = { role: label }
23 | }
24 |
25 | this.format = function () {
26 | const f = []
27 | const m = this.menu[this.mode]
28 | for (const cat in m) {
29 | const submenu = []
30 | for (const name in m[cat]) {
31 | const option = m[cat][name]
32 | if (option.role) {
33 | submenu.push({ role: option.role })
34 | } else {
35 | submenu.push({ label: name, accelerator: option.accelerator, click: option.fn })
36 | }
37 | }
38 | f.push({ label: cat, submenu: submenu })
39 | }
40 | return f
41 | }
42 |
43 | this.commit = function () {
44 | this.app.injectMenu(this.format())
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/desktop/sources/scripts/lib/theme.js:
--------------------------------------------------------------------------------
1 | export default function Theme (_default) {
2 | const themer = this
3 |
4 | this.active = _default
5 |
6 | this.el = document.createElement('style')
7 | this.el.type = 'text/css'
8 |
9 | this.install = function (host = document.body, callback) {
10 | console.log('Theme', 'Installing..')
11 | host.appendChild(this.el)
12 | this.callback = callback
13 | }
14 |
15 | this.start = function () {
16 | console.log('Theme', 'Starting..')
17 | if (isJson(localStorage.theme)) {
18 | const storage = JSON.parse(localStorage.theme)
19 | if (validate(storage)) {
20 | console.log('Theme', 'Found theme in localStorage!')
21 | this.load(storage)
22 | return
23 | }
24 | }
25 | this.load(_default)
26 | }
27 |
28 | this.load = function (data) {
29 | const theme = parse(data)
30 | if (!validate(theme)) { console.warn('Theme', 'Not a theme', theme); return }
31 | console.log('Theme', `Loading theme with background ${theme.background}.`)
32 | this.el.innerHTML = `:root { --background: ${theme.background}; --f_high: ${theme.f_high}; --f_med: ${theme.f_med}; --f_low: ${theme.f_low}; --f_inv: ${theme.f_inv}; --b_high: ${theme.b_high}; --b_med: ${theme.b_med}; --b_low: ${theme.b_low}; --b_inv: ${theme.b_inv}; }`
33 | localStorage.setItem('theme', JSON.stringify(theme))
34 | this.active = theme
35 | if (this.callback) {
36 | this.callback()
37 | }
38 | }
39 |
40 | this.reset = function () {
41 | this.load(_default)
42 | }
43 |
44 | function parse (any) {
45 | if (any && any.background) { return any } else if (any && any.data) { return any.data } else if (any && isJson(any)) { return JSON.parse(any) } else if (any && isHtml(any)) { return extract(any) }
46 | return null
47 | }
48 |
49 | // Drag
50 |
51 | this.drag = function (e) {
52 | e.stopPropagation()
53 | e.preventDefault()
54 | e.dataTransfer.dropEffect = 'copy'
55 | }
56 |
57 | this.drop = function (e) {
58 | e.preventDefault()
59 | e.stopPropagation()
60 | const file = e.dataTransfer.files[0]
61 | if (!file || !file.name) { console.warn('Theme', 'Unnamed file.'); return }
62 | if (file.name.indexOf('.thm') < 0 && file.name.indexOf('.svg') < 0) { console.warn('Theme', 'Skipped, not a theme'); return }
63 | const reader = new FileReader()
64 | reader.onload = function (e) {
65 | themer.load(e.target.result)
66 | }
67 | reader.readAsText(file)
68 | }
69 |
70 | this.open = function () {
71 | const fs = require('fs')
72 | const { dialog, app } = require('electron').remote
73 | let paths = dialog.showOpenDialog(app.win, { properties: ['openFile'], filters: [{ name: 'Themes', extensions: ['svg'] }] })
74 | if (!paths) { console.log('Nothing to load') }
75 | fs.readFile(paths[0], 'utf8', function (err, data) {
76 | if (err) throw err
77 | themer.load(data)
78 | })
79 | }
80 |
81 | window.addEventListener('dragover', this.drag)
82 | window.addEventListener('drop', this.drop)
83 |
84 | // Helpers
85 |
86 | function validate (json) {
87 | if (!json) { return false }
88 | if (!json.background) { return false }
89 | if (!json.f_high) { return false }
90 | if (!json.f_med) { return false }
91 | if (!json.f_low) { return false }
92 | if (!json.f_inv) { return false }
93 | if (!json.b_high) { return false }
94 | if (!json.b_med) { return false }
95 | if (!json.b_low) { return false }
96 | if (!json.b_inv) { return false }
97 | return true
98 | }
99 |
100 | function extract (text) {
101 | const svg = new DOMParser().parseFromString(text, 'text/xml')
102 | try {
103 | return {
104 | 'background': svg.getElementById('background').getAttribute('fill'),
105 | 'f_high': svg.getElementById('f_high').getAttribute('fill'),
106 | 'f_med': svg.getElementById('f_med').getAttribute('fill'),
107 | 'f_low': svg.getElementById('f_low').getAttribute('fill'),
108 | 'f_inv': svg.getElementById('f_inv').getAttribute('fill'),
109 | 'b_high': svg.getElementById('b_high').getAttribute('fill'),
110 | 'b_med': svg.getElementById('b_med').getAttribute('fill'),
111 | 'b_low': svg.getElementById('b_low').getAttribute('fill'),
112 | 'b_inv': svg.getElementById('b_inv').getAttribute('fill')
113 | }
114 | } catch (err) {
115 | console.warn('Theme', 'Incomplete SVG Theme', err)
116 | }
117 | }
118 |
119 | function isJson (text) {
120 | try { JSON.parse(text); return true } catch (error) { return false }
121 | }
122 |
123 | function isHtml (text) {
124 | try { new DOMParser().parseFromString(text, 'text/xml'); return true } catch (error) { return false }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/desktop/sources/scripts/listener.js:
--------------------------------------------------------------------------------
1 | const dgram = require('dgram')
2 |
3 | export default function Listener (pilot) {
4 | this.server = dgram.createSocket('udp4')
5 |
6 | this.server.on('message', (msg, rinfo) => {
7 | pilot.mixer.run(`${msg}`)
8 | })
9 |
10 | this.server.on('listening', () => {
11 | const address = this.server.address()
12 | console.log(`Server listening for UDP:\n ${address.address}:${address.port}`)
13 | })
14 |
15 | this.server.on('error', (err) => {
16 | console.log(`Server error:\n ${err.stack}`)
17 | server.close()
18 | })
19 |
20 | this.server.bind(49161) // TODO - make this configurable
21 | }
22 |
--------------------------------------------------------------------------------
/desktop/sources/scripts/mixer.js:
--------------------------------------------------------------------------------
1 | import ChannelInterface from './interface.channel.js'
2 | import EffectInterface from './interface.effect.js'
3 |
4 | const Tone = require('tone')
5 |
6 | export default function Mixer (pilot) {
7 | this.el = document.createElement('div')
8 | this.el.id = 'mixer'
9 |
10 | this.channels = []
11 | this.effects = {}
12 |
13 | this.install = function (host) {
14 | console.log('Mixer', 'Installing..')
15 |
16 | Tone.start()
17 | Tone.Transport.start()
18 |
19 | // AM
20 | this.channels[0] = new ChannelInterface(pilot, 0, new Tone.AMSynth({ 'harmonicity': 1.25, 'oscillator': { 'type': 'sine8' }, 'modulation': { 'type': 'sine' } }))
21 | this.channels[1] = new ChannelInterface(pilot, 1, new Tone.AMSynth({ 'harmonicity': 1.5, 'oscillator': { 'type': 'triangle8' }, 'modulation': { 'type': 'sawtooth' } }))
22 | this.channels[2] = new ChannelInterface(pilot, 2, new Tone.AMSynth({ 'harmonicity': 1.75, 'oscillator': { 'type': 'sawtooth8' }, 'modulation': { 'type': 'triangle' } }))
23 | this.channels[3] = new ChannelInterface(pilot, 3, new Tone.AMSynth({ 'harmonicity': 2, 'oscillator': { 'type': 'square8' }, 'modulation': { 'type': 'square' } }))
24 | // AM
25 | this.channels[4] = new ChannelInterface(pilot, 4, new Tone.AMSynth({ 'harmonicity': 1.25, 'oscillator': { 'type': 'sine4' }, 'modulation': { 'type': 'square8' } }))
26 | this.channels[5] = new ChannelInterface(pilot, 5, new Tone.AMSynth({ 'harmonicity': 1.5, 'oscillator': { 'type': 'triangle4' }, 'modulation': { 'type': 'sawtooth8' } }))
27 | this.channels[6] = new ChannelInterface(pilot, 6, new Tone.FMSynth({ 'harmonicity': 1.75, 'modulationIndex': 10, 'oscillator': { 'type': 'sawtooth4' }, 'modulation': { 'type': 'triangle8' } }))
28 | this.channels[7] = new ChannelInterface(pilot, 7, new Tone.FMSynth({ 'harmonicity': 2, 'modulationIndex': 20, 'oscillator': { 'type': 'square4' }, 'modulation': { 'type': 'sine8' } }))
29 | // FM
30 | this.channels[8] = new ChannelInterface(pilot, 8, new Tone.FMSynth({ 'harmonicity': 0.5, 'modulationIndex': 30, 'oscillator': { 'type': 'sine' }, 'modulation': { 'type': 'sawtooth4' } }))
31 | this.channels[9] = new ChannelInterface(pilot, 9, new Tone.FMSynth({ 'harmonicity': 2.5, 'modulationIndex': 40, 'oscillator': { 'type': 'sine' }, 'modulation': { 'type': 'triangle8' } }))
32 | this.channels[10] = new ChannelInterface(pilot, 10, new Tone.MonoSynth({ 'volume': -20, oscillator: { 'type': 'sawtooth4' } }))
33 | this.channels[11] = new ChannelInterface(pilot, 11, new Tone.MonoSynth({ 'volume': -20, oscillator: { 'type': 'sine4' } }))
34 | // Membrane
35 | this.channels[12] = new ChannelInterface(pilot, 12, new Tone.MembraneSynth({ 'octaves': 5, 'oscillator': { 'type': 'sine' } }))
36 | this.channels[13] = new ChannelInterface(pilot, 13, new Tone.MembraneSynth({ 'octaves': 10, 'oscillator': { 'type': 'sawtooth' } }))
37 | this.channels[14] = new ChannelInterface(pilot, 14, new Tone.MembraneSynth({ 'octaves': 15, 'oscillator': { 'type': 'triangle' } }))
38 | this.channels[15] = new ChannelInterface(pilot, 15, new Tone.MembraneSynth({ 'octaves': 20, 'oscillator': { 'type': 'square' } }))
39 |
40 | // I
41 | this.effects.bitcrusher = new EffectInterface(pilot, 'bit', new Tone.BitCrusher(4))
42 | this.effects.distortion = new EffectInterface(pilot, 'dis', new Tone.Distortion(0.05))
43 | this.effects.autowah = new EffectInterface(pilot, 'wah', new Tone.AutoWah(100, 6, 0))
44 | this.effects.chebyshev = new EffectInterface(pilot, 'che', new Tone.Chebyshev(50))
45 | // II
46 | this.effects.feedback = new EffectInterface(pilot, 'fee', new Tone.FeedbackDelay(0))
47 | this.effects.delay = new EffectInterface(pilot, 'del', new Tone.PingPongDelay('4n', 0.2))
48 | this.effects.tremolo = new EffectInterface(pilot, 'tre', new Tone.Tremolo())
49 | this.effects.reverb = new EffectInterface(pilot, 'rev', new Tone.JCReverb(0))
50 | // III
51 | this.effects.phaser = new EffectInterface(pilot, 'pha', new Tone.Phaser(0.5, 3, 350))
52 | this.effects.vibrato = new EffectInterface(pilot, 'vib', new Tone.Vibrato())
53 | this.effects.chorus = new EffectInterface(pilot, 'cho', new Tone.Chorus(4, 2.5, 0.5))
54 | this.effects.widener = new EffectInterface(pilot, 'ste', new Tone.StereoWidener(0.5, 3, 350))
55 | // Mastering
56 | this.effects.equalizer = new EffectInterface(pilot, 'equ', new Tone.EQ3(5, 0, 5))
57 | this.effects.compressor = new EffectInterface(pilot, 'com', new Tone.Compressor(-6, 4))
58 | this.effects.volume = new EffectInterface(pilot, 'vol', new Tone.Volume(6))
59 | this.effects.limiter = new EffectInterface(pilot, 'lim', new Tone.Limiter(-2))
60 |
61 | // Connect
62 | for (const id in this.channels) {
63 | this.channels[id].connect(this.effects.bitcrusher.node)
64 | }
65 |
66 | this.effects.bitcrusher.connect(this.effects.distortion.node)
67 | this.effects.distortion.connect(this.effects.autowah.node)
68 | this.effects.autowah.connect(this.effects.chebyshev.node)
69 | this.effects.chebyshev.connect(this.effects.feedback.node)
70 |
71 | this.effects.feedback.connect(this.effects.delay.node)
72 | this.effects.delay.connect(this.effects.tremolo.node)
73 | this.effects.tremolo.connect(this.effects.reverb.node)
74 | this.effects.reverb.connect(this.effects.phaser.node)
75 |
76 | this.effects.phaser.connect(this.effects.vibrato.node)
77 | this.effects.vibrato.connect(this.effects.chorus.node)
78 | this.effects.chorus.connect(this.effects.widener.node)
79 | this.effects.widener.connect(this.effects.equalizer.node)
80 |
81 | this.effects.equalizer.connect(this.effects.compressor.node)
82 | this.effects.compressor.connect(this.effects.volume.node)
83 | this.effects.volume.connect(this.effects.limiter.node)
84 |
85 | // Add all instruments to dom
86 | for (const id in this.channels) {
87 | this.channels[id].install(this.el)
88 | }
89 |
90 | // Add all effects to dom
91 | for (const id in this.effects) {
92 | this.effects[id].install(this.el)
93 | }
94 |
95 | host.appendChild(this.el)
96 | }
97 |
98 | this.start = function () {
99 | console.log('Synthetiser', 'Starting..')
100 | for (const id in this.channels) {
101 | this.channels[id].start()
102 | }
103 | for (const id in this.effects) {
104 | this.effects[id].start()
105 | }
106 |
107 | // Set to Presets
108 | this.reset()
109 |
110 | this.setSpeed(120)
111 | setTimeout(() => { this.effects.limiter.node.toMaster() }, 2000)
112 | this.run()
113 | }
114 |
115 | this.run = function (msg) {
116 | // Multi
117 | if (`${msg}`.indexOf(';') > -1) {
118 | const parts = `${msg}`.split(';')
119 | for (const id in parts) {
120 | this.run(parts[id])
121 | }
122 | return
123 | }
124 | // Single
125 | for (const id in this.channels) {
126 | this.channels[id].run(msg)
127 | }
128 | for (const id in this.effects) {
129 | this.effects[id].run(msg)
130 | }
131 | // Special
132 | if (msg && `${msg}`.substr(0, 3).toLowerCase() === 'bpm') {
133 | this.setSpeed(msg.substr(3))
134 | }
135 | // Special
136 | if (msg && `${msg}`.substr(0, 4).toLowerCase() === 'renv') {
137 | for (const id in this.channels) {
138 | this.channels[id].randEnv()
139 | }
140 | }
141 | if (msg && `${msg}`.substr(0, 4).toLowerCase() === 'rosc') {
142 | for (const id in this.channels) {
143 | this.channels[id].randOsc()
144 | }
145 | }
146 | if (msg && `${msg}`.substr(0, 4).toLowerCase() === 'refx') {
147 | for (const id in this.effects) {
148 | this.effects[id].rand(msg)
149 | }
150 | }
151 | if (msg && `${msg}`.substr(0, 5).toLowerCase() === 'reset') {
152 | this.reset()
153 | }
154 | }
155 |
156 | this.setSpeed = function (bpm) {
157 | if (parseInt(bpm) < 30) { return }
158 | Tone.Transport.bpm.rampTo(parseInt(bpm), 4)
159 | console.log(`Changed BPM to ${bpm}.`)
160 | pilot.recorder.el.innerHTML = `${bpm}`
161 | }
162 |
163 | this.reset = function () {
164 | // Return to Env Presets
165 | for (const id in this.channels) {
166 | this.channels[id].setEnv({ isEnv: true,
167 | attack: 0.001,
168 | decay: clamp(((8 - (id % 8)) / 8), 0.01, 0.9),
169 | sustain: clamp(((id % 4) / 4), 0.01, 0.9),
170 | release: clamp(((id % 6) / 6), 0.01, 0.9)
171 | })
172 | }
173 | // Return to Osc Presets
174 | this.run('0OSC8ISI;1OSC8RSW;2OSC8WTR;3OSC8QSQ;4OSC4I8Q;5OSC4R8W;6OSCTR8R;7OSCTR8I;8OSCTR4W;9OSCTR8R;AOSC4W--;BOSC4I--;COSCSI--;DOSCSW--;EOSCTR--;FOSCSQ--')
175 | // Return to Effects Presets
176 | this.run('BIT07;DIS00;WAH0F;CHE07;FEE00;TRE07;REV00;PHA0F;VIB01;CHO07')
177 | }
178 |
179 | function clamp (v, min, max) { return v < min ? min : v > max ? max : v }
180 | }
181 |
--------------------------------------------------------------------------------
/desktop/sources/scripts/pilot.js:
--------------------------------------------------------------------------------
1 | import Listener from './listener.js'
2 | import Mixer from './mixer.js'
3 | import Recorder from './recorder.js'
4 | import Commander from './commander.js'
5 | import Theme from './lib/theme.js'
6 |
7 | const { webFrame } = require('electron')
8 |
9 | export default function Pilot () {
10 | this.listener = null
11 | this.mixer = null
12 | this.recorder = null
13 | this.commander = null
14 | this.theme = new Theme({ background: '#000000', f_high: '#ffffff', f_med: '#777777', f_low: '#444444', f_inv: '#000000', b_high: '#eeeeee', b_med: '#333', b_low: '#444444', b_inv: '#fff' })
15 |
16 | this.el = document.createElement('div')
17 | this.el.id = 'pilot'
18 |
19 | this.animate = true
20 |
21 | this.install = function (host) {
22 | console.info('Pilot is installing..')
23 |
24 | this.mixer = new Mixer(this)
25 | this.listener = new Listener(this)
26 | this.recorder = new Recorder(this)
27 | this.commander = new Commander(this)
28 |
29 | host.appendChild(this.el)
30 |
31 | this.theme.install()
32 | this.mixer.install(this.el)
33 | this.recorder.install(this.el)
34 | this.commander.install(this.el)
35 | }
36 |
37 | this.start = function () {
38 | console.info('Pilot is starting..')
39 | this.mixer.start()
40 | this.commander.start()
41 | this.theme.start()
42 |
43 | const zoomFactor = Number(localStorage.getItem('zoomFactor'))
44 | webFrame.setZoomFactor(zoomFactor)
45 | }
46 |
47 | this.toggleAnimations = function (mod, set = false) {
48 | this.animate = this.animate !== true
49 | }
50 |
51 | this.modZoom = function (mod = 0, set = false) {
52 | const currentZoomFactor = webFrame.getZoomFactor()
53 | const newZoomFactor = set ? mod : currentZoomFactor + mod
54 | webFrame.setZoomFactor(newZoomFactor)
55 | localStorage.setItem('zoomFactor', newZoomFactor)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/desktop/sources/scripts/recorder.js:
--------------------------------------------------------------------------------
1 | const { dialog, app } = require('electron').remote
2 | const Tone = require('tone')
3 | const fs = require('fs')
4 |
5 | export default function Recorder (pilot) {
6 | this.el = document.createElement('div')
7 | this.el.id = 'recorder'
8 | this.el.className = 'blink'
9 | this.el.textContent = '•'
10 | this.isRecording = false
11 |
12 | let chunks = []
13 |
14 | this.install = function (host) {
15 | console.log('Recorder', 'Installing..')
16 |
17 | pilot.mixer.hook = Tone.context.createMediaStreamDestination()
18 | pilot.mixer.recorder = new MediaRecorder(pilot.mixer.hook.stream)
19 | pilot.mixer.effects.limiter.connect(pilot.mixer.hook)
20 |
21 | pilot.mixer.recorder.onstop = evt => {
22 | const blob = new Blob(chunks, { type: 'audio/opus; codecs=opus' })
23 | pilot.recorder.save(blob)
24 | }
25 |
26 | pilot.mixer.recorder.ondataavailable = evt => {
27 | chunks.push(evt.data)
28 | }
29 |
30 | host.appendChild(this.el)
31 | }
32 |
33 | this.start = function () {
34 | console.log('Recorder', 'Starting..')
35 | this.isRecording = true
36 | chunks = []
37 | pilot.mixer.recorder.start()
38 | pilot.el.className = 'recording'
39 | }
40 |
41 | this.stop = function () {
42 | if (!this.isRecording) { return }
43 |
44 | console.log('Recorder', 'Stopping..')
45 | this.isRecording = false
46 | pilot.mixer.recorder.stop()
47 | pilot.el.className = ''
48 | }
49 |
50 | this.toggle = function () {
51 | if (this.isRecording !== true) {
52 | this.start()
53 | } else {
54 | this.stop()
55 | }
56 | }
57 |
58 | this.save = function (blob) {
59 | dialog.showSaveDialog({ filters: [{ name: 'Audio File', extensions: ['opus'] }] }, (path) => {
60 | if (path === undefined) { return }
61 | pilot.recorder.write(path, blob)
62 | })
63 | }
64 |
65 | this.write = function (path, blob) {
66 | const reader = new FileReader()
67 | reader.onload = function () {
68 | const buffer = new Buffer.from(reader.result)
69 | fs.writeFile(path, buffer, {}, (err, res) => {
70 | if (err) { console.error(err); return }
71 | console.log('Recorder', 'Export complete.')
72 | })
73 | }
74 | reader.readAsArrayBuffer(blob)
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/desktop/sources/scripts/transpose.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | export default {
4 | 'A': 'A0',
5 | 'a': 'a0',
6 | 'B': 'B0',
7 | 'C': 'C0',
8 | 'c': 'c0',
9 | 'D': 'D0',
10 | 'd': 'd0',
11 | 'E': 'E0',
12 | 'F': 'F0',
13 | 'f': 'f0',
14 | 'G': 'G0',
15 | 'g': 'g0',
16 | 'H': 'A0',
17 | 'h': 'a0',
18 | 'I': 'B0',
19 | 'J': 'C1',
20 | 'j': 'c1',
21 | 'K': 'D1',
22 | 'k': 'd1',
23 | 'L': 'E1',
24 | 'M': 'F1',
25 | 'm': 'f1',
26 | 'N': 'G1',
27 | 'n': 'g1',
28 | 'O': 'A1',
29 | 'o': 'a1',
30 | 'P': 'B1',
31 | 'Q': 'C2',
32 | 'q': 'c2',
33 | 'R': 'D2',
34 | 'r': 'd2',
35 | 'S': 'E2',
36 | 'T': 'F2',
37 | 't': 'f2',
38 | 'U': 'G2',
39 | 'u': 'g2',
40 | 'V': 'A2',
41 | 'v': 'a2',
42 | 'W': 'B2',
43 | 'X': 'C3',
44 | 'x': 'c3',
45 | 'Y': 'D3',
46 | 'y': 'd3',
47 | 'Z': 'E3',
48 | // Catch e
49 | 'e': 'F0',
50 | 'l': 'F1',
51 | 's': 'F2',
52 | 'z': 'F3',
53 | // Catch b
54 | 'b': 'C1',
55 | 'i': 'C1',
56 | 'p': 'C2',
57 | 'w': 'C3'
58 | }
59 |
--------------------------------------------------------------------------------
/resources/device.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hundredrabbits/Pilot/a77a4e059147d02fbbfb676e2417974a587dbaed/resources/device.jpg
--------------------------------------------------------------------------------
/resources/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hundredrabbits/Pilot/a77a4e059147d02fbbfb676e2417974a587dbaed/resources/preview.jpg
--------------------------------------------------------------------------------