diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..a8c26d5
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,13 @@
+#root = true
+
+[*]
+indent_style = space
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+max_line_length = 120
+indent_size = 2
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/.gitignore b/.gitignore
index 82a4493..a7d6cf0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.idea/
+.vscode/
+coverage/
+dist/
node_modules/
-an.wav
-an100ms.wav
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..e59a3c1
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,7 @@
+language: node_js
+node_js: '8'
+cache: yarn
+script:
+ - npm run build
+after_success:
+ - npm run report-coverage
diff --git a/INTERNET-SOURCES.md b/INTERNET-SOURCES.md
index 0c4072f..a5331a3 100644
--- a/INTERNET-SOURCES.md
+++ b/INTERNET-SOURCES.md
@@ -28,7 +28,7 @@ Freq domain time resolution:
http://electronics.stackexchange.com/questions/12407/what-is-the-relation-between-fft-length-and-frequency-resolution
IQ sampling explanation (complex signal):
- http://whiteboard.ping.se/SDR/IQ GREAT GREAT GREAT !!!
+ http://whiteboard.ping.se/SDR/IQ GREAT GREAT GREAT !!!!
https://www.youtube.com/watch?v=h_7d-m1ehoY
Very nice project about DSP and Software Defined Radio
@@ -120,11 +120,11 @@ Another great example
Nice articles about OFDM
http://www.skydsp.com/publications/index.htm
-
+
OFDM Symbols synchronization
https://dsp.stackexchange.com/questions/7724/how-is-symbol-synchronization-with-ofdm-done
https://dsp.stackexchange.com/questions/360/how-to-demodulate-an-ofdm-signal/368#368
-
+
OFDM pilot tones
https://dsp.stackexchange.com/questions/15164/using-pilot-tones-to-estimate-carrier-frequency-offset-in-ofdm
```
@@ -147,15 +147,15 @@ FFT FAQ
FFT explained (Decimation In Time) - REALLY GREAT!
https://jakevdp.github.io/blog/2013/08/28/understanding-the-fft/
-
+
FFT explained (Decimation In Time and Decimation In Frequency) - REALLY GREAT!
https://cnx.org/contents/JqoGchv3@3/Overview-of-Fast-Fourier-Trans FFT Overview
https://cnx.org/contents/zmcmahhR@7/Decimation-in-time-DIT-Radix-2 DIT
https://cnx.org/contents/XaYDVUAS@6/Decimation-in-Frequency-DIF-Ra DIF
-
+
FFT explained (Decimation In Time and Decimation In Frequency) - REALLY GREAT!!
http://www.cmlab.csie.ntu.edu.tw/cml/dsp/training/coding/transform/fft.html
-
+
FFT very clean implementation in Java (FFT Decimation In Time)
http://stackoverflow.com/questions/7821473/fft-in-javascript
http://introcs.cs.princeton.edu/java/97data/FFT.java.html < link from stackoverflow answer
diff --git a/README.md b/README.md
index 6c70fea..dc979b0 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,8 @@
-Audio Network
-=============
+# Audio Network
+
+[![npm version](https://badge.fury.io/js/audio-network.svg)](https://badge.fury.io/js/audio-network)
+[![Build Status](https://travis-ci.org/robertrypula/AudioNetwork.svg?branch=typescript-webpack-jest)](https://travis-ci.org/robertrypula/AudioNetwork)
+[![Coverage Status](https://coveralls.io/repos/github/robertrypula/AudioNetwork/badge.svg?branch=typescript-webpack-jest)](https://coveralls.io/github/robertrypula/AudioNetwork?branch=typescript-webpack-jest)
Data transmission over sound waves written in JavaScript without any dependencies. All you need is just
microphone, speakers and the browser!
diff --git a/build/audio-network-v1.3.0.js b/build/audio-network-v1.3.0.js
deleted file mode 100644
index 0a3b7a8..0000000
--- a/build/audio-network-v1.3.0.js
+++ /dev/null
@@ -1,10683 +0,0 @@
-/*
-The MIT License (MIT)
-
-Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-var
- AudioNetwork = {}, // namespace visible to the global JavaScript scope
- AudioNetworkBootConfig = AudioNetworkBootConfig || {}; // injects boot config
-
-AudioNetwork.version = '1.3.0';
-
-// conditions from: http://stackoverflow.com/a/33697246
-AudioNetwork.isNode = typeof module !== 'undefined' && module.exports ? true : false;
-AudioNetwork.isWebWorker = !AudioNetwork.isNode && typeof WorkerGlobalScope !== 'undefined' && typeof importScripts == 'function' && navigator instanceof WorkerNavigator;
-AudioNetwork.isBrowser = !AudioNetwork.isNode && !AudioNetwork.isWebWorker && typeof navigator !== 'undefined' && typeof document !== 'undefined';
-
-/*
-console.log(AudioNetwork.isNode);
-console.log(AudioNetwork.isWebWorker);
-console.log(AudioNetwork.isBrowser);
-*/
-
-AudioNetwork.MULTICORE_STATE = {
- DISABLED: 'DISABLED',
- ENABLED_USE_PROD_SCRIPT: 'ENABLED_USE_PROD_SCRIPT',
- ENABLED_USE_DEV_SCRIPT: 'ENABLED_USE_DEV_SCRIPT'
-};
-
-AudioNetwork.bootConfig = {
- devScriptBaseUrl: typeof AudioNetworkBootConfig.devScriptBaseUrl === 'string'
- ? AudioNetworkBootConfig.devScriptBaseUrl
- : (AudioNetwork.isBrowser ? window.location.origin + '/src/' : ''),
- prodScriptBaseUrl: typeof AudioNetworkBootConfig.prodScriptBaseUrl === 'string'
- ? AudioNetworkBootConfig.prodScriptBaseUrl
- : (AudioNetwork.isBrowser ? window.location.origin + '/build/' : ''),
- prodScriptName: typeof AudioNetworkBootConfig.prodScriptName === 'string'
- ? AudioNetworkBootConfig.prodScriptName
- : 'audio-network-v' + AudioNetwork.version + '.min.js',
- devScriptLoad: typeof AudioNetworkBootConfig.devScriptLoad !== 'undefined'
- ? !!AudioNetworkBootConfig.devScriptLoad
- : false,
- createAlias: typeof AudioNetworkBootConfig.createAlias !== 'undefined'
- ? !!AudioNetworkBootConfig.createAlias
- : true,
- multicoreState: Object.keys(AudioNetwork.MULTICORE_STATE).indexOf(AudioNetworkBootConfig.multicoreState) !== -1
- ? AudioNetworkBootConfig.multicoreState
- : AudioNetwork.MULTICORE_STATE.DISABLED
-};
-
-AudioNetwork.Injector = (function () {
- var Injector;
-
- Injector = function () {
- this.$$injectRepository = {};
- };
-
- Injector.RESOLVE_RECURSION_LIMIT = 20;
- Injector.RESOLVE_RECURSION_LIMIT_EXCEED_EXCEPTION = 'Injector - resolve recursion limit exceed';
- Injector.MULTIPLE_REGISTER_EXCEPTION = 'Injector - multiple register calls for the same name';
- Injector.UNABLE_TO_FIND_ITEM_EXCEPTION = 'Injector - unable to find factory/service for given name: ';
- Injector.TYPE = {
- SERVICE: 'SERVICE',
- FACTORY: 'FACTORY'
- };
-
- Injector.$$resolveRecursionCounter = 0;
-
- Injector.prototype.$$register = function (name, item, type) {
- if (typeof this.$$injectRepository[name] === 'undefined') {
- this.$$injectRepository[name] = {
- type: type,
- item: item,
- resolveCache: null
- };
- } else {
- throw Injector.MULTIPLE_REGISTER_EXCEPTION;
- }
- };
-
- Injector.prototype.registerService = function (name, service) {
- this.$$register(name, service, Injector.TYPE.SERVICE);
- };
-
- Injector.prototype.registerFactory = function (name, factory) {
- this.$$register(name, factory, Injector.TYPE.FACTORY);
- };
-
- Injector.prototype.resolve = function (name) {
- var i, findResult, injectList = [];
-
- findResult = this.$$find(name);
- if (findResult.resolveCache) {
- return findResult.resolveCache;
- }
-
- this.$$resolveRecursionInc();
- for (i = 0; i < findResult.item.$inject.length; i++) {
- injectList.push(
- this.resolve(findResult.item.$inject[i])
- );
- }
- switch (findResult.type) {
- case Injector.TYPE.SERVICE:
- findResult.resolveCache = this.$$injectDependenciesAndInstantiate(findResult, injectList);
- break;
- case Injector.TYPE.FACTORY:
- findResult.resolveCache = this.$$injectDependencies(findResult, injectList);
- break;
- }
- this.$$resolveRecursionDec();
-
- return findResult.resolveCache;
- };
-
- Injector.prototype.$$resolveRecursionInc = function () {
- Injector.$$resolveRecursionCounter++;
- if (Injector.$$resolveRecursionCounter >= Injector.RESOLVE_RECURSION_LIMIT) {
- throw Injector.RESOLVE_RECURSION_LIMIT_EXCEED_EXCEPTION;
- }
- };
-
- Injector.prototype.$$resolveRecursionDec = function () {
- Injector.$$resolveRecursionCounter--;
- };
-
- Injector.prototype.$$injectDependenciesAndInstantiate = function (findResult, injectList) {
- var
- f = findResult,
- i = injectList,
- r
- ;
-
- switch (injectList.length) {
- case 0: r = new f.item(); break;
- case 1: r = new f.item(i[0]); break;
- case 2: r = new f.item(i[0], i[1]); break;
- case 3: r = new f.item(i[0], i[1], i[2]); break;
- case 4: r = new f.item(i[0], i[1], i[2], i[3]); break;
- case 5: r = new f.item(i[0], i[1], i[2], i[3], i[4]); break;
- case 6: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5]); break;
- case 7: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6]); break;
- case 8: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]); break;
- case 9: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]); break;
- case 10: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9]); break;
- case 11: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9], i[10]); break;
- case 12: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9], i[10], i[11]); break;
- }
-
- return r;
- };
-
- Injector.prototype.$$injectDependencies = function (findResult, injectList) {
- var
- f = findResult,
- i = injectList,
- r
- ;
-
- switch (injectList.length) {
- case 0: r = f.item(); break;
- case 1: r = f.item(i[0]); break;
- case 2: r = f.item(i[0], i[1]); break;
- case 3: r = f.item(i[0], i[1], i[2]); break;
- case 4: r = f.item(i[0], i[1], i[2], i[3]); break;
- case 5: r = f.item(i[0], i[1], i[2], i[3], i[4]); break;
- case 6: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5]); break;
- case 7: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6]); break;
- case 8: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]); break;
- case 9: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]); break;
- case 10: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9]); break;
- case 11: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9], i[10]); break;
- case 12: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9], i[10], i[11]); break;
- }
-
- return r;
- };
-
- Injector.prototype.$$find = function (name) {
- var key;
-
- for (key in this.$$injectRepository) {
- if (this.$$injectRepository.hasOwnProperty(key) && key === name) {
- return this.$$injectRepository[key];
- }
- }
- throw Injector.UNABLE_TO_FIND_ITEM_EXCEPTION + name;
- };
-
- return new Injector(); // instantiate service
-})();
-
-AudioNetwork.DynamicScriptLoader = (function () {
- var DynamicScriptLoader;
-
- DynamicScriptLoader = function () {
- };
-
- DynamicScriptLoader.prototype.loadList = function (urlList, startingIndex) {
- var i;
-
- if (typeof startingIndex === 'undefined') {
- startingIndex = 0;
- }
-
- for (i = startingIndex; i < urlList.length; i++) {
- this.loadOne(urlList[i]);
- }
- };
-
- DynamicScriptLoader.prototype.loadOne = function (url) {
- /*
- var
- anRoot = document.getElementById('an-root'),
- scriptTag = document.createElement('script'),
- whereToAppend = anRoot ? anRoot : document.body;
-
- scriptTag.src = AudioNetwork.bootConfig.devScriptBaseUrl + url;
- whereToAppend.appendChild(scriptTag);
- */
- // block page loading - this is the best approach so far... :)
- document.write('')
- };
-
- return new DynamicScriptLoader(); // instantiate service
-})();
-
-AudioNetwork.devScriptList = [
- 'audio-network-boot.js',
- '-deprecated-probably/common/math-util/math-util.service.js',
- '-deprecated-probably/common/simple-promise/simple-promise-builder.service.js',
- '-deprecated-probably/common/simple-promise/simple-promise.factory.js',
- '-deprecated-probably/common/stopwatch/stopwatch-builder.service.js',
- '-deprecated-probably/common/stopwatch/stopwatch.factory.js',
- '-deprecated-probably/common/window-function/window-function.service.js',
- '-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker-thread.service.js',
- '-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker.factory.js',
- '-deprecated-probably/physical-layer-core/receive-worker/receive-worker.factory.js',
- '-deprecated/audio/active-audio-context/active-audio-context.service.js',
- '-deprecated/audio/simple-audio-context/simple-audio-context-builder.service.js',
- '-deprecated/audio/simple-audio-context/simple-audio-context.factory.js',
- '-deprecated/common/abstract-value-collector/abstract-value-collector.factory.js',
- '-deprecated/common/average-value-collector/average-value-collector-builder.service.js',
- '-deprecated/common/average-value-collector/average-value-collector.factory.js',
- '-deprecated/common/carrier-generate/carrier-generate-builder.service.js',
- '-deprecated/common/carrier-generate/carrier-generate.factory.js',
- '-deprecated/common/carrier-recovery/carrier-recovery-builder.service.js',
- '-deprecated/common/carrier-recovery/carrier-recovery.factory.js',
- '-deprecated/common/complex/complex-builder.service.js',
- '-deprecated/common/complex/complex.factory.js',
- '-deprecated/common/queue/queue-builder.service.js',
- '-deprecated/common/queue/queue.factory.js',
- '-deprecated/common/util/util.service.js',
- '-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector-builder.service.js',
- '-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector.factory.js',
- '-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector-builder.service.js',
- '-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector.factory.js',
- '-deprecated/physical-layer-adapter/receive-adapter-state.service.js',
- '-deprecated/physical-layer-adapter/receive-adapter.factory.js',
- '-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager-builder.service.js',
- '-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager.factory.js',
- '-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine-builder.service.js',
- '-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine.factory.js',
- '-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector-builder.service.js',
- '-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector.factory.js',
- '-deprecated/physical-layer-adapter/transmit-adapter.factory.js',
- '-deprecated/physical-layer/abstract-channel-manager/abstract-channel-manager.factory.js',
- '-deprecated/physical-layer/channel-receive-manager/channel-receive-manager-builder.service.js',
- '-deprecated/physical-layer/channel-receive-manager/channel-receive-manager.factory.js',
- '-deprecated/physical-layer/channel-receive/channel-receive-builder.service.js',
- '-deprecated/physical-layer/channel-receive/channel-receive.factory.js',
- '-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager-builder.service.js',
- '-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager.factory.js',
- '-deprecated/physical-layer/channel-transmit/channel-transmit-builder.service.js',
- '-deprecated/physical-layer/channel-transmit/channel-transmit.factory.js',
- '-deprecated/physical-layer/configuration-parser.service.js',
- '-deprecated/physical-layer/default-config.service.js',
- '-deprecated/physical-layer/physical-layer.factory.js',
- '-deprecated/physical-layer/rx-handler/rx-handler-builder.service.js',
- '-deprecated/physical-layer/rx-handler/rx-handler.factory.js',
- '-deprecated/physical-layer/rx-input.service.js',
- 'data-link-layer/checksum-service.js',
- 'data-link-layer/data-link-layer-builder.js',
- 'data-link-layer/data-link-layer.js',
- 'data-link-layer/frame.js',
- 'data-link-layer/tx-frame-manager.js',
- 'data-link-layer/tx-frame.js',
- 'dsp/complex.js',
- 'dsp/correlator.js',
- 'dsp/fft-result.js',
- 'dsp/wave-analyser.js',
- 'dsp/wave-generator.js',
- 'physical-layer/physical-layer-builder.js',
- 'physical-layer/physical-layer.js',
- 'physical-layer/rx-sync-detector.js',
- 'physical-layer/tx-symbol-manager.js',
- 'physical-layer/tx-symbol.js',
- 'util/buffer.js',
- 'util/frequency-calculator.js',
- 'util/music-calculator.js',
- 'util/smart-timer.js',
- 'util/wav-audio-file.js',
- 'visualizer/abstract-2d-visualizer/abstract-2d-visualizer.factory.js',
- 'visualizer/abstract-visualizer/abstract-visualizer.factory.js',
- 'visualizer/analyser-chart/analyser-chart-builder.service.js',
- 'visualizer/analyser-chart/analyser-chart-template-axis-x.service.js',
- 'visualizer/analyser-chart/analyser-chart-template-main.service.js',
- 'visualizer/analyser-chart/analyser-chart.factory.js',
- 'visualizer/complex-plane-chart/complex-plane-chart-builder.service.js',
- 'visualizer/complex-plane-chart/complex-plane-chart-template-main.service.js',
- 'visualizer/complex-plane-chart/complex-plane-chart.factory.js',
- 'visualizer/constellation-diagram/constellation-diagram-builder.service.js',
- 'visualizer/constellation-diagram/constellation-diagram-template-main.service.js',
- 'visualizer/constellation-diagram/constellation-diagram.factory.js',
- 'visualizer/frequency-domain-chart/frequency-domain-chart-builder.service.js',
- 'visualizer/frequency-domain-chart/frequency-domain-chart-template-main.service.js',
- 'visualizer/frequency-domain-chart/frequency-domain-chart.factory.js',
- 'visualizer/power-chart/power-chart-builder.service.js',
- 'visualizer/power-chart/power-chart-template-main.service.js',
- 'visualizer/power-chart/power-chart.factory.js',
- 'visualizer/sample-chart/sample-chart-builder.service.js',
- 'visualizer/sample-chart/sample-chart-template-main.service.js',
- 'visualizer/sample-chart/sample-chart.factory.js',
- 'web-audio/audio-mono-io-lite.js',
- 'web-audio/audio-mono-io.js',
- 'audio-network-end.js'
-];
-
-if (AudioNetwork.isBrowser && AudioNetwork.bootConfig.devScriptLoad) {
- // start from index 1 because audio-network-boot.js was already loaded
- AudioNetwork.DynamicScriptLoader.loadList(AudioNetwork.devScriptList, 1);
-}
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.DataLinkLayer.ChecksumService', ChecksumService);
-
- ChecksumService.$inject = [];
-
- function ChecksumService() {
- var ChecksumService;
-
- ChecksumService = function () {
- };
-
- ChecksumService.fletcher8 = function (data) {
- var sum0, sum1, i, isLeftHalfOfByte, byteNumber, byte, halfOfByte;
-
- sum0 = 0;
- sum1 = 0;
- for (i = 0; i < 2 * data.length; i++) {
- isLeftHalfOfByte = i % 2 === 0;
- byteNumber = i >>> 1;
- byte = data[byteNumber];
- halfOfByte = isLeftHalfOfByte
- ? (byte & 0xF0) >>> 4
- : byte & 0x0F;
- sum0 = (sum0 + halfOfByte) % 0x0F;
- sum1 = (sum1 + sum0) % 0x0F;
- }
-
- return (sum1 << 4) | sum0;
- };
-
- return ChecksumService;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.DataLinkLayer.DataLinkLayerBuilder', DataLinkLayerBuilder);
-
- DataLinkLayerBuilder.$inject = [
- 'Rewrite.DataLinkLayer.DataLinkLayer'
- ];
-
- function DataLinkLayerBuilder(
- DataLinkLayer
- ) {
- var DataLinkLayerBuilder;
-
- DataLinkLayerBuilder = function () {
- this._framePayloadLengthLimit = 7;
-
- // data link layer listeners
- this._rxFrameListener = undefined;
- this._rxFrameCandidateListener = undefined;
- this._txFrameListener = undefined;
- this._txFrameProgressListener = undefined;
-
- // physical layer listeners
- this._rxSymbolListener = undefined;
- this._rxSampleDspDetailsListener = undefined;
- this._rxSyncDspDetailsListener = undefined;
- this._rxDspConfigListener = undefined;
- this._dspConfigListener = undefined;
- this._txSymbolProgressListener = undefined;
- this._txDspConfigListener = undefined;
- };
-
- DataLinkLayerBuilder.prototype.framePayloadLengthLimit = function (framePayloadLengthLimit) {
- this._framePayloadLengthLimit = framePayloadLengthLimit;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.rxFrameListener = function (listener) {
- this._rxFrameListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.txFrameListener = function (listener) {
- this._txFrameListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.txFrameProgressListener = function (listener) {
- this._txFrameProgressListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.rxFrameCandidateListener = function (listener) {
- this._rxFrameCandidateListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.rxSymbolListener = function (listener) {
- this._rxSymbolListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.rxSampleDspDetailsListener = function (listener) {
- this._rxSampleDspDetailsListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.rxSyncStatusListener = function (listener) {
- this._rxSyncStatusListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.rxSyncDspDetailsListener = function (listener) {
- this._rxSyncDspDetailsListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.rxDspConfigListener = function (listener) {
- this._rxDspConfigListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.dspConfigListener = function (listener) {
- this._dspConfigListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.txSymbolListener = function (listener) {
- this._txSymbolListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.txSymbolProgressListener = function (listener) {
- this._txSymbolProgressListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.txDspConfigListener = function (listener) {
- this._txDspConfigListener = listener;
- return this;
- };
-
- DataLinkLayerBuilder.prototype.build = function () {
- return new DataLinkLayer(this);
- };
-
- return DataLinkLayerBuilder;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-// TODO move and refactor RX code (dedicated classes like in TX part)
-// TODO implement solution what will not require PhysicalLayer synchronization (looking for frames in two FSK symbol streams)
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.DataLinkLayer.DataLinkLayer', DataLinkLayer);
-
- DataLinkLayer.$inject = [
- 'Rewrite.PhysicalLayer.PhysicalLayerBuilder',
- 'Rewrite.DataLinkLayer.TxFrameManager',
- 'Rewrite.DataLinkLayer.TxFrame',
- 'Rewrite.DataLinkLayer.ChecksumService'
- ];
-
- function DataLinkLayer(
- PhysicalLayerBuilder,
- TxFrameManager,
- TxFrame,
- ChecksumService
- ) {
- var DataLinkLayer;
-
- DataLinkLayer = function (builder) {
- // let's create network stack!
- // Data Link Layer hides Physical Layer inside
- this.$$physicalLayer = (new PhysicalLayerBuilder())
- .rxSymbolListener(this.$$rxSymbolListener.bind(this))
- .rxSampleDspDetailsListener(builder._rxSampleDspDetailsListener)
- .rxSyncStatusListener(builder._rxSyncStatusListener)
- .rxSyncDspDetailsListener(builder._rxSyncDspDetailsListener)
- .rxDspConfigListener(builder._rxDspConfigListener)
- .dspConfigListener(builder._dspConfigListener)
- .txSymbolListener(this.$$txSymbolListener.bind(this))
- .txSymbolProgressListener(builder._txSymbolProgressListener)
- .txDspConfigListener(builder._txDspConfigListener)
- .build();
-
- // general config
- this.$$framePayloadLengthLimit = builder._framePayloadLengthLimit;
-
- // state variables
- this.$$frame = undefined;
- this.$$frameId = DataLinkLayer.$$_INITIAL_ID;
- this.$$frameCandidateId = DataLinkLayer.$$_INITIAL_ID;
- this.$$frameCandidateList = [];
- this.$$txFrameManager = new TxFrameManager();
-
- // setup listeners - data link layer
- this.$$rxFrameListener = DataLinkLayer.$$isFunction(builder._rxFrameListener) ? builder._rxFrameListener : null;
- this.$$rxFrameCandidateListener = DataLinkLayer.$$isFunction(builder._rxFrameCandidateListener) ? builder._rxFrameCandidateListener : null;
- this.$$txFrameListener = DataLinkLayer.$$isFunction(builder._txFrameListener) ? builder._txFrameListener : null;
- this.$$txFrameProgressListener = DataLinkLayer.$$isFunction(builder._txFrameProgressListener) ? builder._txFrameProgressListener : null;
-
- // setup listeners - physical layer
- this.$$externalRxSymbolListener = DataLinkLayer.$$isFunction(builder._rxSymbolListener) ? builder._rxSymbolListener : null;
- this.$$externalTxSymbolListener = DataLinkLayer.$$isFunction(builder._txSymbolListener) ? builder._txSymbolListener : null;
- };
-
- DataLinkLayer.PAYLOAD_TO_BIG_EXCEPTION = 'Payload is too big!';
-
- DataLinkLayer.COMMAND_TWO_WAY_SYNC_44100 = 0;
- DataLinkLayer.COMMAND_TWO_WAY_SYNC_48000 = 1;
-
- DataLinkLayer.$$_HEADER_FRAME_START_MARKER = 0xE0;
- DataLinkLayer.$$_HEADER_RESERVED_BIT = 0x08;
- DataLinkLayer.$$_HEADER_COMMAND_BIT_SET = 0x10;
- DataLinkLayer.$$_HEADER_COMMAND_BIT_NOT_SET = 0x00;
- DataLinkLayer.$$_HEADER_PAYLOAD_LENGTH_MASK = 0x0F;
- DataLinkLayer.$$_ONE_BYTE_MASK = 0xFF;
-
- DataLinkLayer.$$_PAYLOAD_TYPE_COMMAND = 'PAYLOAD_TYPE_COMMAND';
- DataLinkLayer.$$_PAYLOAD_TYPE_DATA = 'PAYLOAD_TYPE_DATA';
-
- DataLinkLayer.$$_INITIAL_ID = 1;
- DataLinkLayer.$$_HEADER_AND_CHECKSUM_BYTE_OVERHEAD = 2;
-
- DataLinkLayer.prototype.getPhysicalLayer = function () {
- return this.$$physicalLayer;
- };
-
- DataLinkLayer.prototype.getRxSampleRate = function () {
- var rxDspConfig = this.$$physicalLayer.getRxDspConfig();
-
- return rxDspConfig.rxSampleRate;
- };
-
- DataLinkLayer.prototype.setTxSampleRate = function (txSampleRate) {
- this.$$physicalLayer.setTxSampleRate(txSampleRate); // alias for easier access
- };
-
- DataLinkLayer.prototype.txSync = function () {
- this.$$physicalLayer.txSync(); // alias for easier access
- };
-
- DataLinkLayer.prototype.txTwoWaySync = function () {
- var isCommand = true;
-
- this.txSync();
- switch (this.getRxSampleRate()) {
- case 44100:
- this.txFrame([DataLinkLayer.COMMAND_TWO_WAY_SYNC_44100], isCommand);
- break;
- case 48000:
- this.txFrame([DataLinkLayer.COMMAND_TWO_WAY_SYNC_48000], isCommand);
- break;
- }
- };
-
- DataLinkLayer.prototype.setLoopback = function (state) {
- this.$$physicalLayer.setLoopback(state); // alias for easier access
- };
-
- DataLinkLayer.prototype.getFramePayloadLengthLimit = function () {
- return this.$$framePayloadLengthLimit;
- };
-
- DataLinkLayer.prototype.txFrame = function (txFramePayload, isTxFrameCommand) {
- var txFrame, txDspConfig, txSymbolMin, i, txByte, txSymbol, txSymbolId;
-
- if (txFramePayload.length > this.$$framePayloadLengthLimit) {
- throw DataLinkLayer.PAYLOAD_TO_BIG_EXCEPTION;
- }
-
- txFrame = new TxFrame(
- this.$$txFrameManager.getNextTxFrameId(),
- txFramePayload,
- isTxFrameCommand
- );
-
- txDspConfig = this.$$physicalLayer.getTxDspConfig();
- txSymbolMin = txDspConfig.txSymbolMin;
- for (i = 0; i < txFrame.getTxByteLength(); i++) {
- txByte = txFrame.getTxByte(i);
- txSymbol = txSymbolMin + txByte;
- txSymbolId = this.$$physicalLayer.txSymbol(txSymbol);
- txFrame.addTxSymbolId(txSymbolId);
- }
-
- this.$$txFrameManager.addTxFrame(txFrame);
-
- this.$$txFrameProgressListener ? this.$$txFrameProgressListener(this.getTxFrameProgress()) : undefined;
-
- return txFrame.getId();
- };
-
- DataLinkLayer.prototype.getTxFrame = function () {
- return this.$$txFrameManager.getTxFrameCloned();
- };
-
- DataLinkLayer.prototype.getTxFrameProgress = function () {
- return this.$$txFrameManager.getTxFrameProgressCloned();
- };
-
- DataLinkLayer.prototype.getRxFrame = function () {
- var
- frame = this.$$frame,
- frameCopy;
-
- if (!frame) {
- return null;
- }
-
- frameCopy = {
- id: frame.id,
- header: frame.rxFrameHeader,
- pyload: frame.rxFramePayload.slice(0),
- checksum: frame.rxFrameChecksum,
- isCommand: frame.isRxFrameCommand,
- rxFrameCandidateId: frame.rxFrameCandidateId
- };
-
- return frameCopy;
- };
-
- DataLinkLayer.prototype.getRxFrameCandidate = function () {
- var i, frameCandidate, frameCandidateCopy, result = [];
-
- for (i = 0; i < this.$$frameCandidateList.length; i++) {
- frameCandidate = this.$$frameCandidateList[i];
- frameCandidateCopy = {
- id: frameCandidate.id,
- byteReceived: frameCandidate.rxByteReceived.slice(0),
- byteExpected: frameCandidate.rxByteExpected,
- unitProgress: frameCandidate.rxByteReceived.length / frameCandidate.rxByteExpected,
- isFullyReceived: frameCandidate.rxByteReceived.length === frameCandidate.rxByteExpected,
- isValid: frameCandidate.isRxFrameCandidateValid,
- rxSampleDspDetailsId: frameCandidate.rxSampleDspDetailsId.slice(0)
- };
- result.push(frameCandidateCopy);
- }
-
- return result;
- };
-
- // -----------------------------------------------------
-
- DataLinkLayer.prototype.$$handleRxSymbol = function (data) {
- var
- rxSampleDspDetails = this.$$physicalLayer.getRxSampleDspDetails(),
- rxDspConfig = this.$$physicalLayer.getRxDspConfig(),
- rxSymbolMin = rxDspConfig.rxSymbolMin,
- byte = (rxSampleDspDetails.rxSymbolRaw - rxSymbolMin) & DataLinkLayer.$$_ONE_BYTE_MASK,
- rxSampleDspDetailsId = rxSampleDspDetails.id,
- isNewFrameAvailable,
- command;
-
- this.$$cleanUpFrameCandidateList();
- this.$$addNewByteToFrameCandidateList(byte, rxSampleDspDetailsId);
- this.$$tryToCreateNewFrameCandidate(byte, rxSampleDspDetailsId);
- isNewFrameAvailable = this.$$tryToFindNewFrame();
-
- // call listeners
- this.$$rxFrameCandidateListener ? this.$$rxFrameCandidateListener(this.getRxFrameCandidate()) : undefined;
- if (isNewFrameAvailable) {
- if (this.$$frame.isRxFrameCommand) {
- command = this.$$frame.rxFramePayload[0];
- this.$$handleReceivedCommand(command);
- }
- this.$$rxFrameListener ? this.$$rxFrameListener(this.getRxFrame()) : undefined;
- }
- };
-
- DataLinkLayer.prototype.$$handleTxSymbol = function (data) {
- var txSymbolId, txFrameCloned;
-
- txSymbolId = data.id;
- this.$$txFrameManager.handleTxSymbolId(txSymbolId);
-
- txFrameCloned = this.$$txFrameManager.getTxFrameCloned();
- if (txFrameCloned) {
- this.$$txFrameListener ? this.$$txFrameListener(txFrameCloned) : undefined;
- }
- this.$$txFrameProgressListener ? this.$$txFrameProgressListener(this.getTxFrameProgress()) : undefined;
- };
-
- DataLinkLayer.prototype.$$cleanUpFrameCandidateList = function () {
- var i, frameCandidate, receivedFully;
-
- for (i = this.$$frameCandidateList.length - 1; i >= 0; i--) {
- frameCandidate = this.$$frameCandidateList[i];
- receivedFully = frameCandidate.rxByteReceived.length === frameCandidate.rxByteExpected;
- if (receivedFully) {
- this.$$frameCandidateList.splice(i, 1);
- }
- }
- };
-
- DataLinkLayer.prototype.$$addNewByteToFrameCandidateList = function (byte, rxSampleDspDetailsId) {
- var i, frameCandidate, readyToComputeChecksum, fullyReceived, notFullyReceived, frameWithoutChecksum, rxChecksum;
-
- for (i = 0; i < this.$$frameCandidateList.length; i++) {
- frameCandidate = this.$$frameCandidateList[i];
- notFullyReceived = frameCandidate.rxByteReceived.length < frameCandidate.rxByteExpected;
- if (notFullyReceived) {
- frameCandidate.rxByteReceived.push(byte);
- frameCandidate.rxSampleDspDetailsId.push(rxSampleDspDetailsId);
- }
-
- readyToComputeChecksum = frameCandidate.rxByteReceived.length === (frameCandidate.rxByteExpected - 1);
- if (readyToComputeChecksum) {
- frameWithoutChecksum = frameCandidate.rxByteReceived;
- frameCandidate.rxChecksumExpected = ChecksumService.fletcher8(frameWithoutChecksum);
- }
-
- fullyReceived = frameCandidate.rxByteReceived.length === frameCandidate.rxByteExpected;
- if (fullyReceived) {
- rxChecksum = frameCandidate.rxByteReceived[frameCandidate.rxByteReceived.length - 1];
- frameCandidate.isRxFrameCandidateValid = frameCandidate.rxChecksumExpected === rxChecksum;
- }
- }
- };
-
- DataLinkLayer.prototype.$$tryToCreateNewFrameCandidate = function (byte, rxSampleDspDetailsId) {
- var frameCandidate, header, payloadLength;
-
- if (!DataLinkLayer.$$isValidHeader(byte)) {
- return;
- }
- header = byte;
- payloadLength = DataLinkLayer.$$getPayloadLength(header);
-
- frameCandidate = {
- id: this.$$frameCandidateId++,
- rxByteReceived: [header],
- rxByteExpected: payloadLength + DataLinkLayer.$$_HEADER_AND_CHECKSUM_BYTE_OVERHEAD,
- isRxFrameCandidateValid: false,
- rxChecksumExpected: null,
- rxSampleDspDetailsId: [rxSampleDspDetailsId]
- };
- this.$$frameCandidateList.push(frameCandidate);
- };
-
- DataLinkLayer.prototype.$$tryToFindNewFrame = function () {
- var i, frameCandidate;
-
- for (i = 0; i < this.$$frameCandidateList.length; i++) {
- frameCandidate = this.$$frameCandidateList[i];
- if (frameCandidate.isRxFrameCandidateValid) {
- this.$$frame = DataLinkLayer.$$getRxFrameFromFrameCandidate(frameCandidate, this.$$frameId++);
- // there is possibility that there are more valid frames
- // but the assumption is that we are picking the biggest one only
- return true;
- }
- }
-
- return false;
- };
-
- DataLinkLayer.prototype.$$handleReceivedCommand = function (command) {
- switch (command) {
- case DataLinkLayer.COMMAND_TWO_WAY_SYNC_44100:
- this.setTxSampleRate(44100);
- this.txSync();
- break;
- case DataLinkLayer.COMMAND_TWO_WAY_SYNC_48000:
- this.setTxSampleRate(48000);
- this.txSync();
- break;
- }
- };
-
- // -----------------------------------------------------
-
- DataLinkLayer.prototype.$$txSymbolListener = function (data) {
- this.$$externalTxSymbolListener ? this.$$externalTxSymbolListener(data) : undefined;
- this.$$handleTxSymbol(data);
- };
-
- DataLinkLayer.prototype.$$rxSymbolListener = function (data) {
- this.$$externalRxSymbolListener ? this.$$externalRxSymbolListener(data) : undefined;
- this.$$handleRxSymbol(data);
- };
-
- // -----------------------------------------------------
-
- DataLinkLayer.$$getRxFrameFromFrameCandidate = function (frameCandidate, frameId) {
- var frame, rxFrameHeader;
-
- rxFrameHeader = frameCandidate.rxByteReceived[0];
- frame = {
- id: frameId,
- rxFrameHeader: rxFrameHeader,
- rxFramePayload: frameCandidate.rxByteReceived.slice(1, frameCandidate.rxByteReceived.length - 1),
- rxFrameChecksum: frameCandidate.rxByteReceived[frameCandidate.rxByteReceived.length - 1],
- isRxFrameCommand: DataLinkLayer.$$getIsCommand(rxFrameHeader),
- rxFrameCandidateId: frameCandidate.id
- };
-
- return frame;
- };
-
- DataLinkLayer.$$buildFrame = function (payloadType, payload) { // TODO refactor needed as we have dedicated Frame class
- var frame, isCommand, header, checksum, i, byte;
-
- frame = [];
- isCommand = payloadType === DataLinkLayer.$$_PAYLOAD_TYPE_COMMAND;
- header = DataLinkLayer.$$getHeader(isCommand, payload.length);
- frame.push(header);
- for (i = 0; i < payload.length; i++) {
- byte = payload[i] & DataLinkLayer.$$_ONE_BYTE_MASK;
- frame.push(byte);
- }
- checksum = ChecksumService.fletcher8(frame);
- frame.push(checksum);
-
- return frame;
- };
-
- DataLinkLayer.$$getHeader = function (isCommand, payloadLength) { // TODO refactor needed as we have dedicated Frame class
- var header, frameStartMarker, commandBit;
-
- frameStartMarker = DataLinkLayer.$$_HEADER_FRAME_START_MARKER;
- commandBit = isCommand
- ? DataLinkLayer.$$_HEADER_COMMAND_BIT_SET
- : DataLinkLayer.$$_HEADER_COMMAND_BIT_NOT_SET;
- payloadLength = DataLinkLayer.$$_HEADER_PAYLOAD_LENGTH_MASK & payloadLength;
-
- header = frameStartMarker | commandBit | payloadLength;
-
- return header;
- };
-
- DataLinkLayer.$$isValidHeader = function (byte) { // TODO refactor needed as we have dedicated Frame class
- var frameStartMarkerAvailable, reservedBitNotSet;
-
- frameStartMarkerAvailable = (DataLinkLayer.$$_HEADER_FRAME_START_MARKER & byte) === DataLinkLayer.$$_HEADER_FRAME_START_MARKER;
- reservedBitNotSet = !(DataLinkLayer.$$_HEADER_RESERVED_BIT & byte);
-
- return frameStartMarkerAvailable && reservedBitNotSet;
- };
-
- DataLinkLayer.$$getPayloadLength = function (header) { // TODO refactor needed as we have dedicated Frame class
- return header & DataLinkLayer.$$_HEADER_PAYLOAD_LENGTH_MASK;
- };
-
- DataLinkLayer.$$getIsCommand = function (header) { // TODO refactor needed as we have dedicated Frame class
- return !!(header & DataLinkLayer.$$_HEADER_COMMAND_BIT_SET);
- };
-
- DataLinkLayer.$$isFunction = function (variable) {
- return typeof variable === 'function';
- };
-
- return DataLinkLayer;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.DataLinkLayer.Frame', Frame);
-
- Frame.$inject = [
- 'Rewrite.DataLinkLayer.ChecksumService'
- ];
-
- function Frame(
- ChecksumService
- ) {
- var Frame;
-
- Frame = function (id, payload, isCommand) {
- this.$$id = id;
- this.$$header = undefined;
- this.$$payload = [];
- this.$$checksum = undefined;
-
- this.setPayload(payload, isCommand);
- };
-
- Frame.$$_HEADER_FRAME_START_MARKER = 0xE0;
- Frame.$$_HEADER_COMMAND_BIT_SET = 0x10;
- Frame.$$_HEADER_COMMAND_BIT_NOT_SET = 0x00;
- Frame.$$_HEADER_PAYLOAD_LENGTH_MASK = 0x0F;
- Frame.$$_ONE_BYTE_MASK = 0xFF;
-
- Frame.prototype.getId = function () {
- return this.$$id;
- };
-
- Frame.prototype.getHeader = function () {
- return this.$$header;
- };
-
- Frame.prototype.getPayload = function () {
- return this.$$payload;
- };
-
- Frame.prototype.getChecksum = function () {
- return this.$$checksum;
- };
-
- Frame.prototype.setPayload = function (payload, isCommand) {
- var frameWithoutChecksum, i, byte;
-
- frameWithoutChecksum = [];
- this.$$header = Frame.$$generateHeader(isCommand, payload.length);
- frameWithoutChecksum.push(this.$$header);
- this.$$payload.length = 0;
- for (i = 0; i < payload.length; i++) {
- byte = payload[i] & Frame.$$_ONE_BYTE_MASK;
- this.$$payload.push(byte);
- frameWithoutChecksum.push(byte);
- }
- this.$$checksum = Frame.$$computeChecksum(frameWithoutChecksum);
- };
-
- Frame.$$computeChecksum = function (frameWithoutChecksum) {
- return ChecksumService.fletcher8(frameWithoutChecksum);
- };
-
- Frame.$$generateHeader = function (isCommand, payloadLength) {
- var frameStartMarker, commandBit, header;
-
- frameStartMarker = Frame.$$_HEADER_FRAME_START_MARKER;
- commandBit = isCommand
- ? Frame.$$_HEADER_COMMAND_BIT_SET
- : Frame.$$_HEADER_COMMAND_BIT_NOT_SET;
- payloadLength = Frame.$$_HEADER_PAYLOAD_LENGTH_MASK & payloadLength;
-
- header = frameStartMarker | commandBit | payloadLength;
-
- return header;
- };
-
- return Frame;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.DataLinkLayer.TxFrameManager', TxFrameManager);
-
- TxFrameManager.$inject = [];
-
- function TxFrameManager() {
- var TxFrameManager;
-
- TxFrameManager = function () {
- this.$$txFrameId = TxFrameManager.$$_INITIAL_TX_FRAME_ID;
- this.$$txFrame = null;
- this.$$txFrameCurrent = null;
- this.$$txFrameQueue = [];
- };
-
- TxFrameManager.$$_INITIAL_TX_FRAME_ID = 1;
-
- TxFrameManager.prototype.getNextTxFrameId = function () {
- return this.$$txFrameId++;
- };
-
- TxFrameManager.prototype.getTxFrameCloned = function () {
- return this.$$txFrame
- ? this.$$txFrame.cloneClean()
- : null;
- };
-
- TxFrameManager.prototype.getTxFrameProgressCloned = function () {
- var
- result = {},
- i;
-
- result.txFrame = this.getTxFrameCloned();
-
- result.txFrameCurrent = this.$$txFrameCurrent
- ? this.$$txFrameCurrent.cloneClean()
- : null;
-
- result.txFrameQueue = [];
- for (i = 0; i < this.$$txFrameQueue.length; i++) {
- result.txFrameQueue.push(
- this.$$txFrameQueue[i].cloneClean()
- );
- }
-
- result.isTxFrameInProgress = this.isTxFrameInProgress();
-
- return result;
- };
-
- TxFrameManager.prototype.isTxFrameInProgress = function () {
- return this.$$txFrameQueue.length > 0 ||
- !!this.$$txFrameCurrent;
- };
-
- TxFrameManager.prototype.addTxFrame = function (txFrame) {
- this.$$txFrameQueue.push(txFrame);
- };
-
- TxFrameManager.prototype.handleTxSymbolId = function (txSymbolId) {
- var isQueueNotEmpty, confirmed;
-
- isQueueNotEmpty = this.$$txFrameQueue.length > 0;
-
- if (this.$$txFrameCurrent) {
- confirmed = this.$$txFrameCurrent.tryToConfirmTxSymbolId(txSymbolId);
- if (this.$$txFrameCurrent.isFullyTransmitted()) {
- this.$$txFrame = this.$$txFrameCurrent;
- this.$$txFrameCurrent = isQueueNotEmpty ? this.$$txFrameQueue.shift() : null;
- }
- } else {
- this.$$txFrame = null;
- this.$$txFrameCurrent = isQueueNotEmpty ? this.$$txFrameQueue.shift() : null;
- }
-
- if (this.$$txFrameCurrent && !confirmed) {
- this.$$txFrameCurrent.tryToConfirmTxSymbolId(txSymbolId);
- }
- };
-
- return TxFrameManager;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.DataLinkLayer.TxFrame', TxFrame);
-
- TxFrame.$inject = [
- 'Rewrite.DataLinkLayer.Frame'
- ];
-
- function TxFrame(
- Frame
- ) {
- var TxFrame;
-
- TxFrame = function (txFrameId, txFramePayload, isTxFrameCommand) {
- Frame.call(this, txFrameId, txFramePayload, isTxFrameCommand);
-
- this.$$txSymbolId = [];
- this.$$txSymbolTransmitted = 0;
- };
-
- TxFrame.prototype = Object.create(Frame.prototype);
- TxFrame.prototype.constructor = TxFrame;
-
- TxFrame.TX_BYTE_INDEX_OUT_OF_RANGE_EXCEPTION = 'TX_BYTE_INDEX_OUT_OF_RANGE_EXCEPTION';
-
- TxFrame.prototype.cloneClean = function () {
- return {
- id: this.$$id,
- header: this.$$header,
- payload: this.$$payload.slice(0),
- checksum: this.$$checksum,
- isFullyTransmitted: this.isFullyTransmitted(),
- unitProgress: this.getUnitProgress(),
- txSymbolId: this.$$txSymbolId.slice(0),
- txSymbolTransmitted: this.$$txSymbolTransmitted
- };
- };
-
- TxFrame.prototype.getTxByteLength = function () {
- return this.$$payload.length + 2; // payload + header + checksum
- };
-
- TxFrame.prototype.addTxSymbolId = function (txSymbolId) {
- this.$$txSymbolId.push(txSymbolId);
- };
-
- TxFrame.prototype.tryToConfirmTxSymbolId = function (txSymbolId) {
- var isTxSymbolIdPartOfThisFrame = TxFrame.$$inArray(this.$$txSymbolId, txSymbolId);
-
- if (isTxSymbolIdPartOfThisFrame) {
- this.$$txSymbolTransmitted++;
- return true;
- }
-
- return false;
- };
-
- TxFrame.prototype.isFullyTransmitted = function () {
- return this.$$txSymbolId.length === this.$$txSymbolTransmitted;
- };
-
- TxFrame.prototype.getUnitProgress = function () {
- return this.$$txSymbolTransmitted / this.$$txSymbolId.length;
- };
-
- TxFrame.prototype.getTxByte = function (index) {
- var txByteLength = this.getTxByteLength();
-
- if (index < 0 || index >= txByteLength) {
- throw TxFrame.TX_BYTE_INDEX_OUT_OF_RANGE_EXCEPTION;
- }
-
- if (index === 0) {
- return this.$$header;
- }
-
- if (index === txByteLength - 1) {
- return this.$$checksum;
- }
-
- return this.$$payload[index - 1];
- };
-
- TxFrame.$$inArray = function (array, value) {
- var i;
-
- for (i = 0; i < array.length; i++) {
- if (array[i] === value) {
- return true;
- }
- }
-
- return false;
- };
-
- return TxFrame;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.Dsp.Complex', Complex);
-
- Complex.$inject = [];
-
- function Complex() {
- var Complex;
-
- Complex = function (real, imag) {
- this.$$real = real;
- this.$$imag = imag;
- };
-
- Complex.$$_EPSILON = 0.000001;
- Complex.$$_UNIT_RADIUS = 1;
-
- Complex.prototype.clone = function () {
- return new Complex(
- this.$$real,
- this.$$imag
- );
- };
-
- Complex.polar = function (unitAngle, magnitude) {
- var radian;
-
- magnitude = typeof magnitude === 'undefined'
- ? Complex.$$_UNIT_RADIUS
- : magnitude;
-
- radian = 2 * Math.PI * unitAngle;
-
- return new Complex(
- magnitude * Math.cos(radian),
- magnitude * Math.sin(radian)
- );
- };
-
- Complex.zero = function () {
- return new Complex(0, 0);
- };
-
- Complex.prototype.add = function (b) {
- this.$$real += b.$$real;
- this.$$imag += b.$$imag;
- };
-
- Complex.prototype.subtract = function (b) {
- this.$$real -= b.$$real;
- this.$$imag -= b.$$imag;
- };
-
- Complex.prototype.multiply = function (b) {
- var
- real = this.$$real * b.$$real - this.$$imag * b.$$imag,
- imag = this.$$real * b.$$imag + this.$$imag * b.$$real;
-
- this.$$real = real;
- this.$$imag = imag;
- };
-
- Complex.prototype.conjugate = function () {
- this.$$imag *= -1;
- };
-
- Complex.prototype.multiplyScalar = function (b) {
- this.$$real *= b;
- this.$$imag *= b;
- };
-
- Complex.prototype.divideScalar = function (b) {
- this.$$real /= b;
- this.$$imag /= b;
- };
-
- Complex.prototype.getReal = function () {
- return this.$$real;
- };
-
- Complex.prototype.getImaginary = function () {
- return this.$$imag;
- };
-
- Complex.prototype.getMagnitude = function () {
- return Math.sqrt(
- this.$$real * this.$$real +
- this.$$imag * this.$$imag
- );
- };
-
- Complex.prototype.getUnitAngle = function () {
- var x, y, magnitude, quarter, angle, unitAngle;
-
- x = this.$$real;
- y = this.$$imag;
- magnitude = this.getMagnitude();
- magnitude = magnitude < Complex.$$_EPSILON // prevents from dividing by zero
- ? Complex.$$_EPSILON
- : magnitude;
-
- // ^ Legend:
- // II * I '!' = 0 degrees
- // | '*' = 90 degrees
- // ----@--+--!----> '@' = 180 degrees
- // | '%' = 270 degrees
- // III % IV
-
- quarter = (y >= 0)
- ? (x >= 0 ? 1 : 2)
- : (x <= 0 ? 3 : 4);
-
- switch (quarter) {
- case 1:
- angle = Math.asin(y / magnitude);
- break;
- case 2:
- angle = Math.asin(-x / magnitude) + 0.5 * Math.PI;
- break;
- case 3:
- angle = Math.asin(-y / magnitude) + Math.PI;
- break;
- case 4:
- angle = Math.asin(x / magnitude) + 1.5 * Math.PI;
- break;
- }
-
- unitAngle = angle / (2 * Math.PI);
-
- return unitAngle;
- };
-
- Complex.prototype.normalize = function () {
- this.divideScalar(
- this.getMagnitude()
- );
- };
-
- return Complex;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.Dsp.Correlator', Correlator);
-
- Correlator.$inject = [
- 'Rewrite.Util.Buffer'
- ];
-
- function Correlator(
- Buffer
- ) {
- var Correlator;
-
- Correlator = function (skipFactor, correlationCode) {
- this.$$correlationCode = correlationCode
- ? correlationCode.slice(0)
- : Correlator.DEFAULT_CORRELATION_CODE.slice(0);
-
- this.$$skipFactor = undefined;
- this.$$dataBuffer = undefined;
- this.$$signalDecibelBuffer = undefined;
- this.$$noiseDecibelBuffer = undefined;
- this.$$cacheCorrelactionValue = undefined;
- this.$$cacheSignalDecibelAverage = undefined;
- this.$$cacheNoiseDecibelAverage = undefined;
-
- this.$$setSkipFactor(skipFactor);
- };
-
- Correlator.DEFAULT_CORRELATION_CODE = [1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1]; // Barker Code 11
-
- Correlator.CORRELATION_POSITIVE = 'CORRELATION_POSITIVE';
- Correlator.CORRELATION_NONE = 'CORRELATION_NONE';
- Correlator.CORRELATION_NEGATIVE = 'CORRELATION_NEGATIVE';
-
- Correlator.THRESHOLD_UNIT = 0.9;
- Correlator.NO_DECIBEL = null;
- Correlator.NO_DATA = 0;
-
- Correlator.POSITION_OUT_OF_RANGE_EXCEPTION = 'Position out of range';
-
- Correlator.prototype.reset = function () {
- this.$$setSkipFactor(this.$$skipFactor); // setting skip factor is like reset
- };
-
- Correlator.prototype.handle = function (correlationCodeValue, signalDecibel, noiseDecibel) {
- var data, isValidDecibel;
-
- data = Correlator.NO_DATA;
- switch (correlationCodeValue) {
- case -1:
- case 1:
- data = correlationCodeValue;
- }
- this.$$dataBuffer.pushEvenIfFull(data);
-
- isValidDecibel = data && (signalDecibel || signalDecibel === 0);
- this.$$signalDecibelBuffer.pushEvenIfFull(
- isValidDecibel ? signalDecibel : Correlator.NO_DECIBEL
- );
-
- isValidDecibel = data && (noiseDecibel || noiseDecibel === 0);
- this.$$noiseDecibelBuffer.pushEvenIfFull(
- isValidDecibel ? noiseDecibel : Correlator.NO_DECIBEL
- );
-
- this.$$clearCache();
- };
-
- Correlator.prototype.isCorrelated = function () {
- var correlation = this.getCorrelation();
-
- return (
- correlation === Correlator.CORRELATION_NEGATIVE ||
- correlation === Correlator.CORRELATION_POSITIVE
- );
- };
-
- Correlator.prototype.getCorrelation = function () {
- var
- correlationValue = this.getCorrelationValue(),
- threshold = Math.floor(Correlator.THRESHOLD_UNIT * this.$$correlationCode.length);
-
- if (correlationValue >= threshold) {
- return Correlator.CORRELATION_POSITIVE;
- }
- if (correlationValue > -threshold) {
- return Correlator.CORRELATION_NONE;
- }
-
- return Correlator.CORRELATION_NEGATIVE;
- };
-
- Correlator.prototype.getCorrelationValue = function () {
- var i, lastIndexInSkipBlock, bufferIndex, data, correlationCode, result;
-
- if (this.$$cacheCorrelactionValue !== undefined) {
- return this.$$cacheCorrelactionValue;
- }
-
- result = 0;
- lastIndexInSkipBlock = this.$$skipFactor - 1;
- for (i = 0; i < this.$$correlationCode.length; i++) {
- bufferIndex = lastIndexInSkipBlock + i * this.$$skipFactor;
- data = this.$$dataBuffer.getItem(bufferIndex);
- if (data !== Correlator.NO_DATA) {
- correlationCode = this.$$correlationCode[i];
- result += data * correlationCode;
- }
- }
-
- this.$$cacheCorrelactionValue = result;
-
- return result;
- };
-
- Correlator.prototype.getSignalDecibelAverage = function () {
- if (this.$$cacheSignalDecibelAverage === undefined) {
- this.$$cacheSignalDecibelAverage = this.$$getDecibelAverage(this.$$signalDecibelBuffer);
- }
-
- return this.$$cacheSignalDecibelAverage;
- };
-
- Correlator.prototype.getNoiseDecibelAverage = function () {
- if (this.$$cacheNoiseDecibelAverage === undefined) {
- this.$$cacheNoiseDecibelAverage = this.$$getDecibelAverage(this.$$noiseDecibelBuffer);
- }
-
- return this.$$cacheNoiseDecibelAverage;
- };
-
- Correlator.prototype.getSignalToNoiseRatio = function () {
- var
- signalDecibelAverage = this.getSignalDecibelAverage(),
- noiseDecibelAverage = this.getNoiseDecibelAverage(),
- signalToNoiseRatio = 0,
- isAbleToCompute;
-
- isAbleToCompute =
- signalDecibelAverage !== Correlator.NO_DECIBEL &&
- noiseDecibelAverage !== Correlator.NO_DECIBEL;
-
- if (isAbleToCompute) {
- signalToNoiseRatio = signalDecibelAverage - noiseDecibelAverage;
- }
-
- return signalToNoiseRatio;
- };
-
- Correlator.prototype.getCorrelationCodeLength = function () {
- return this.$$correlationCode.length;
- };
-
- Correlator.prototype.$$clearCache = function () {
- this.$$cacheCorrelactionValue = undefined;
- this.$$cacheSignalDecibelAverage = undefined;
- this.$$cacheNoiseDecibelAverage = undefined;
- };
-
- Correlator.prototype.$$getDecibelAverage = function (buffer) {
- var i, lastIndexInSkipBlock, bufferIndex, value, sum, sumLength, average;
-
- sum = 0;
- sumLength = 0;
- lastIndexInSkipBlock = this.$$skipFactor - 1;
- for (i = 0; i < this.$$correlationCode.length; i++) {
- bufferIndex = lastIndexInSkipBlock + i * this.$$skipFactor;
- value = buffer.getItem(bufferIndex);
- if (value !== Correlator.NO_DECIBEL) {
- sum += value;
- sumLength++;
- }
- }
-
- average = (sumLength > 0)
- ? sum / sumLength
- : Correlator.NO_DECIBEL;
-
- return average;
- };
-
- Correlator.prototype.$$setSkipFactor = function (skipFactor) {
- var i, bufferMaxSize;
-
- skipFactor = skipFactor || 1;
- bufferMaxSize = this.$$correlationCode.length * skipFactor;
-
- this.$$skipFactor = skipFactor;
- this.$$dataBuffer = new Buffer(bufferMaxSize);
- this.$$signalDecibelBuffer = new Buffer(bufferMaxSize);
- this.$$noiseDecibelBuffer = new Buffer(bufferMaxSize);
- this.$$cacheCorrelactionValue = undefined;
- this.$$cacheSignalDecibelAverage = undefined;
- this.$$cacheNoiseDecibelAverage = undefined;
-
- for (i = 0; i < bufferMaxSize; i++) {
- this.$$dataBuffer.pushEvenIfFull(Correlator.NO_DATA);
- this.$$signalDecibelBuffer.pushEvenIfFull(Correlator.NO_DECIBEL);
- this.$$noiseDecibelBuffer.pushEvenIfFull(Correlator.NO_DECIBEL);
- }
- };
-
- return Correlator;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-// TODO add ranges check
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.Dsp.FFTResult', FFTResult);
-
- FFTResult.$inject = [];
-
- function FFTResult() {
- var FFTResult;
-
- FFTResult = function (fftData, sampleRate) {
- this.$$fftData = fftData;
- this.$$sampleRate = sampleRate;
- };
-
- FFTResult.$$_FREQUENCY_BIN_INDEX_ZERO = 0;
- FFTResult.$$_FREQUENCY_BIN_INDEX_FIRST = 1;
- FFTResult.$$_EQUAL_EPSILON = 0.001;
- FFTResult.$$_HALF = 0.5;
-
- FFTResult.VALUES_OUT_OF_RANGE = 'Values out of range';
-
- FFTResult.prototype.downconvert = function (skipFactor) {
- var
- newFftData = [],
- factorHalf = Math.floor(skipFactor / 2),
- sampleRateCorrection,
- max,
- i,
- j;
-
- for (i = 0; i < this.$$fftData.length; i += skipFactor) {
- max = this.$$fftData[i];
- for (j = Math.max(0, i - factorHalf); j < Math.min(i - factorHalf + skipFactor, this.$$fftData.length); j++) {
- max = this.$$fftData[j] > max ? this.$$fftData[j] : max;
- }
- newFftData.push(max);
- }
-
- sampleRateCorrection = skipFactor * newFftData.length / this.$$fftData.length;
- this.$$sampleRate *= sampleRateCorrection;
-
- this.$$fftData = newFftData;
- };
-
- FFTResult.prototype.getLoudestBinIndex = function (frequencyStart, frequencyEnd) {
- return this.$$getLoudestBinIndexInRange(
- frequencyStart,
- frequencyEnd
- );
- };
-
- FFTResult.prototype.getLoudestBinIndexInBinRange = function (binIndexStart, binIndexEnd) {
- var frequencyBinCount = FFTResult.$$_HALF * this.getFFTSize();
-
- if (binIndexStart < 0 || binIndexEnd >= frequencyBinCount) {
- throw FFTResult.VALUES_OUT_OF_RANGE;
- }
-
- return FFTResult.$$findMaxIndexInRange(
- this.$$fftData,
- binIndexStart,
- binIndexEnd
- );
- };
-
- FFTResult.prototype.getLoudestFrequency = function (frequencyStart, frequencyEnd) {
- var
- loudestBinIndex = this.$$getLoudestBinIndexInRange(
- frequencyStart,
- frequencyEnd
- );
-
- return FFTResult.getFrequency(
- loudestBinIndex,
- this.$$sampleRate,
- this.getFFTSize()
- );
- };
-
- FFTResult.prototype.getLoudestDecibel = function (frequencyStart, frequencyEnd) {
- var
- loudestBinIndex = this.$$getLoudestBinIndexInRange(
- frequencyStart,
- frequencyEnd
- );
-
- return this.$$fftData[loudestBinIndex];
- };
-
- FFTResult.prototype.getDecibelAverage = function (binIndexStart, binIndexEnd, binIndexExcluded) {
- var
- frequencyBinCount = FFTResult.$$_HALF * this.getFFTSize(),
- itemNumber,
- sum,
- average,
- i;
-
- if (binIndexStart < 0 || binIndexEnd >= frequencyBinCount) {
- throw FFTResult.VALUES_OUT_OF_RANGE;
- }
-
- itemNumber = 0;
- sum = 0;
- for (i = binIndexStart; i <= binIndexEnd; i++) {
- if (typeof binIndexExcluded === 'undefined' || i !== binIndexExcluded) {
- sum += this.getDecibel(i);
- itemNumber++;
- }
- }
-
- average = 0;
- if (itemNumber > 0) {
- average = sum / itemNumber;
- }
-
- return average;
- };
-
- FFTResult.prototype.getDecibelRange = function (binIndexStart, binIndexEnd) {
- var
- frequencyBinCount = FFTResult.$$_HALF * this.getFFTSize(),
- result = [],
- i;
-
- if (binIndexStart < 0 || binIndexEnd >= frequencyBinCount) {
- throw FFTResult.VALUES_OUT_OF_RANGE;
- }
-
- for (i = binIndexStart; i <= binIndexEnd; i++) {
- result.push(
- this.getDecibel(i)
- );
- }
-
- return result;
- };
-
- FFTResult.prototype.getDecibel = function (frequencyBinIndex) {
- return this.$$fftData[frequencyBinIndex];
- };
-
- FFTResult.prototype.getDecibelFromFrequency = function (frequency) {
- var binIndex = this.getBinIndex(frequency);
-
- return this.$$fftData[binIndex];
- };
-
- FFTResult.prototype.getFrequencyData = function () {
- return this.$$fftData;
- };
-
- FFTResult.prototype.getFrequency = function (frequencyBinIndex) {
- return FFTResult.getFrequency(
- frequencyBinIndex,
- this.$$sampleRate,
- this.getFFTSize()
- );
- };
-
- FFTResult.prototype.getFrequencyOfClosestBin = function (frequency) {
- return FFTResult.getFrequencyOfClosestBin(
- frequency,
- this.$$sampleRate,
- this.getFFTSize()
- );
- };
-
- FFTResult.prototype.getBinIndex = function (frequency) {
- return FFTResult.getBinIndex(
- frequency,
- this.$$sampleRate,
- this.getFFTSize()
- );
- };
-
- FFTResult.prototype.getResolution = function () {
- return FFTResult.getResolution(
- this.$$sampleRate,
- this.getFFTSize()
- );
- };
-
- FFTResult.prototype.getLastBinIndex = function () {
- return this.$$fftData.length - 1;
- };
-
- FFTResult.prototype.getLastFrequency = function () {
- return this.getFrequency(
- this.getLastBinIndex()
- );
- };
-
- FFTResult.prototype.getNyquistFrequency = function () {
- return FFTResult.$$_HALF * this.$$sampleRate;
- };
-
- FFTResult.prototype.getSampleRate = function () {
- return this.$$sampleRate;
- };
-
- FFTResult.prototype.getFFTSize = function () {
- return this.$$fftData.length * 2;
- };
-
- FFTResult.prototype.equal = function (fftResult) {
- var
- i,
- absDiff,
- isFrequencyEqual,
- isFFTSizeEqual,
- isAllDecibelEqual;
-
- isFrequencyEqual = FFTResult.$$isEqual(
- this.getNyquistFrequency(),
- fftResult.getNyquistFrequency()
- );
- isFFTSizeEqual = FFTResult.$$isEqual(
- this.getFFTSize(),
- fftResult.getFFTSize()
- );
-
- if (!isFrequencyEqual || !isFFTSizeEqual) {
- return false;
- }
-
- isAllDecibelEqual = true;
- for (i = 0; i < this.$$fftData.length; i++) {
- absDiff = Math.abs(
- this.$$fftData[i] - fftResult.getDecibel(i)
- );
- if (absDiff > FFTResult.$$_EQUAL_EPSILON) {
- isAllDecibelEqual = false;
- break;
- }
- }
-
- return isAllDecibelEqual;
- };
-
- FFTResult.prototype.$$getLoudestBinIndexInRange = function (frequencyStart, frequencyEnd) {
- var
- frequencyBinIndexStart,
- frequencyBinIndexEnd,
- loudestBinIndex;
-
- frequencyStart = FFTResult.$$getValueOrDefault(
- frequencyStart,
- FFTResult.$$_FREQUENCY_BIN_INDEX_ZERO
- );
- frequencyEnd = FFTResult.$$getValueOrDefault(
- frequencyEnd,
- this.getLastFrequency()
- );
-
- frequencyBinIndexStart = this.getBinIndex(frequencyStart);
- frequencyBinIndexEnd = this.getBinIndex(frequencyEnd);
-
- loudestBinIndex = FFTResult.$$findMaxIndexInRange(
- this.$$fftData,
- frequencyBinIndexStart,
- frequencyBinIndexEnd
- );
-
- return loudestBinIndex;
- };
-
- FFTResult.$$isEqual = function (a, b) {
- return a === b;
- };
-
- FFTResult.$$getValueOrDefault = function (value, defaultValue) {
- return typeof value !== 'undefined' ? value : defaultValue;
- };
-
- FFTResult.$$findMaxIndexInRange = function (data, indexMin, indexMax) {
- var maxIndex, max, i;
-
- maxIndex = -1;
- max = undefined;
- for (i = indexMin; i <= indexMax; i++) {
- if (maxIndex === -1 || data[i] > max) {
- max = data[i];
- maxIndex = i;
- }
- }
-
- return maxIndex;
- };
-
- FFTResult.getResolution = function (sampleRate, fftSize) {
- return FFTResult.getFrequency(
- FFTResult.$$_FREQUENCY_BIN_INDEX_FIRST,
- sampleRate,
- fftSize
- );
- };
-
- FFTResult.getFrequency = function (frequencyBinIndex, sampleRate, fftSize) {
- var frequencyBinCount = FFTResult.$$_HALF * fftSize;
-
- if (frequencyBinIndex < 0 || frequencyBinIndex >= frequencyBinCount) {
- throw FFTResult.VALUES_OUT_OF_RANGE;
- }
-
- return frequencyBinIndex * sampleRate / fftSize;
- };
-
- FFTResult.getBinIndex = function (frequency, sampleRate, fftSize) {
- var
- frequencyBinIndex = Math.round(frequency * fftSize / sampleRate),
- frequencyBinCount = FFTResult.$$_HALF * fftSize;
-
- if (frequencyBinIndex < 0 || frequencyBinIndex >= frequencyBinCount) {
- throw FFTResult.VALUES_OUT_OF_RANGE;
- }
-
- return frequencyBinIndex;
- };
-
- FFTResult.getFrequencyOfClosestBin = function (frequency, sampleRate, fftSize) {
- var binIndex = FFTResult.getBinIndex(frequency, sampleRate, fftSize);
-
- return FFTResult.getFrequency(
- binIndex,
- sampleRate,
- fftSize
- );
- };
-
- return FFTResult;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.Dsp.WaveAnalyser', WaveAnalyser);
-
- WaveAnalyser.$inject = [
- 'Rewrite.Dsp.Complex',
- 'Rewrite.Util.Buffer'
- ];
-
- function WaveAnalyser(
- Complex,
- Buffer
- ) {
- var WaveAnalyser;
-
- WaveAnalyser = function (samplePerPeriod, windowSize, applyWindowFunction) {
- samplePerPeriod = samplePerPeriod || WaveAnalyser.$$_DEFAULT_SAMPLE_PER_PERIOD;
- windowSize = windowSize || WaveAnalyser.$$_DEFAULT_WINDOW_SIZE;
-
- this.$$cyclePerSample = null;
- this.$$firstSampleOfBufferNumber = null;
- this.setSamplePerPeriod(samplePerPeriod);
- this.$$sampleBuffer = new Buffer(windowSize);
- this.$$applyWindowFunction = !!applyWindowFunction;
- this.$$frequencyBin = null;
- };
-
- WaveAnalyser.$$_UNIT_PHASE = 1;
- WaveAnalyser.$$_NEGATIVE_FREQUENCIES_AMPLITUDE_FIX = 2;
- WaveAnalyser.$$_PHASE_CORRECTION = 0.75;
- WaveAnalyser.$$_DECIBEL_POWER_FROM_AMPLITUDE_FACTOR = 20;
- WaveAnalyser.$$_DEFAULT_SAMPLE_PER_PERIOD = 32;
- WaveAnalyser.$$_DEFAULT_WINDOW_SIZE = 1024;
-
- WaveAnalyser.prototype.$$computeFrequencyBin = function () {
- var
- size,
- i,
- n,
- unitAngle,
- complex,
- sampleValue,
- windowFunctionValue;
-
- this.$$frequencyBin = Complex.zero();
-
- size = this.$$sampleBuffer.getSize();
- for (i = 0; i < size; i++) {
- n = this.$$firstSampleOfBufferNumber + i;
- unitAngle = this.$$cyclePerSample * n;
- complex = Complex.polar(-unitAngle);
-
- sampleValue = this.$$sampleBuffer.getItem(i);
- complex.multiplyScalar(sampleValue);
-
- if (this.$$applyWindowFunction) {
- windowFunctionValue = WaveAnalyser.blackman(i, size);
- complex.multiplyScalar(windowFunctionValue);
- }
-
- this.$$frequencyBin.add(complex);
- }
- };
-
- WaveAnalyser.prototype.setSamplePerPeriod = function (samplePerPeriod) {
- this.$$cyclePerSample = 1 / samplePerPeriod;
- this.$$firstSampleOfBufferNumber = 0;
- this.$$frequencyBin = null;
- };
-
- WaveAnalyser.prototype.setWindowSize = function (windowSize) {
- this.$$sampleBuffer.setSizeMax(windowSize); // this call clears the buffer too
- this.$$firstSampleOfBufferNumber = 0;
- this.$$frequencyBin = null;
- };
-
- WaveAnalyser.prototype.enableWindowFunction = function () {
- this.$$applyWindowFunction = true;
- this.$$frequencyBin = null;
- };
-
- WaveAnalyser.prototype.disableWindowFunction = function () {
- this.$$applyWindowFunction = false;
- this.$$frequencyBin = null;
- };
-
- WaveAnalyser.prototype.handle = function (sample) {
- if (this.$$sampleBuffer.isFull()) {
- this.$$firstSampleOfBufferNumber++;
- }
- this.$$sampleBuffer.pushEvenIfFull(sample);
- this.$$frequencyBin = null;
- };
-
- WaveAnalyser.prototype.getAmplitude = function () {
- var magnitude, tmp, amplitude;
-
- if (!this.$$frequencyBin) {
- this.$$computeFrequencyBin();
- }
-
- magnitude = this.$$frequencyBin.getMagnitude();
- tmp = magnitude / this.$$sampleBuffer.getSize();
-
- // for real samples half of the energy is in negative frequency
- amplitude = tmp * WaveAnalyser.$$_NEGATIVE_FREQUENCIES_AMPLITUDE_FIX;
-
- // amplitude is valid only when window function is disabled and
- // you have pure sine waves in the signal with integer number of
- // cycles in the window size (no 'leakage')
-
- return amplitude;
- };
-
- WaveAnalyser.prototype.getUnitPhase = function () {
- var unitAngle, tmp, unitPhase;
-
- if (!this.$$frequencyBin) {
- this.$$computeFrequencyBin();
- }
-
- unitAngle = this.$$frequencyBin.getUnitAngle();
- // sine wave without any phase offset is a complex number with real part equal zero
- // and imaginary part on the negative side (vector pointing downwards -> 270 degrees)
- tmp = unitAngle - WaveAnalyser.$$_PHASE_CORRECTION;
- // correction from line above may produce negative phase so we need to fix it
- tmp = tmp < 0
- ? tmp + WaveAnalyser.$$_UNIT_PHASE
- : tmp;
- // fix direction - when sine wave is moving to the right in time domain
- // then phase angle should increase counter-clockwise
- tmp = WaveAnalyser.$$_UNIT_PHASE - tmp;
-
- unitPhase = tmp % WaveAnalyser.$$_UNIT_PHASE; // keep phase in <0, 1) range
-
- return unitPhase;
- };
-
- WaveAnalyser.prototype.getDecibel = function () {
- var decibel, amplitude;
-
- if (!this.$$frequencyBin) {
- this.$$computeFrequencyBin();
- }
-
- amplitude = this.getAmplitude();
- decibel = WaveAnalyser.$$_DECIBEL_POWER_FROM_AMPLITUDE_FACTOR *
- Math.log(amplitude) / Math.LN10;
-
- return decibel;
- };
-
- WaveAnalyser.prototype.getFrequencyBin = function () {
- if (!this.$$frequencyBin) {
- this.$$computeFrequencyBin();
- }
-
- return this.$$frequencyBin.clone();
- };
-
- WaveAnalyser.blackmanNuttall = function (n, N) {
- return 0.3635819
- - 0.4891775 * Math.cos(2 * Math.PI * n / (N - 1))
- + 0.1365995 * Math.cos(4 * Math.PI * n / (N - 1))
- - 0.0106411 * Math.cos(6 * Math.PI * n / (N - 1));
- };
-
- // https://www.w3.org/TR/webaudio/#fft-windowing-and-smoothing-over-time
- WaveAnalyser.blackman = function (n, N) {
- var
- alpha = 0.16,
- a0 = 0.5 * (1 - alpha),
- a1 = 0.5,
- a2 = 0.5 * alpha;
-
- return a0
- - a1 * Math.cos(2 * Math.PI * n / (N - 1))
- + a2 * Math.cos(4 * Math.PI * n / (N - 1));
- };
-
- return WaveAnalyser;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.Dsp.WaveGenerator', WaveGenerator);
-
- WaveGenerator.$inject = [];
-
- function WaveGenerator() {
- var WaveGenerator;
-
- WaveGenerator = function (samplePerPeriod) {
- samplePerPeriod = samplePerPeriod || WaveGenerator.$$_DEFAULT_SAMPLE_PER_PERIOD;
-
- this.$$omega = null;
- this.$$sampleNumber = null;
- this.setSamplePerPeriod(samplePerPeriod);
- this.$$phase = WaveGenerator.NO_PHASE_SHIFT;
- this.$$amplitude = WaveGenerator.UNIT_AMPLITUDE;
- this.$$sample = null;
- };
-
- WaveGenerator.UNIT_AMPLITUDE = 1;
- WaveGenerator.NO_PHASE_SHIFT = 0;
- WaveGenerator.$$_DEFAULT_SAMPLE_PER_PERIOD = 32;
-
- WaveGenerator.prototype.$$computeSample = function () {
- var x;
-
- x = this.$$omega * this.$$sampleNumber;
- this.$$sample = this.$$amplitude * Math.sin(x - this.$$phase);
- };
-
- WaveGenerator.prototype.setSamplePerPeriod = function (samplePerPeriod) {
- this.$$omega = 2 * Math.PI / samplePerPeriod;
- this.$$sampleNumber = 0;
- };
-
- WaveGenerator.prototype.setUnitPhase = function (unitPhase) {
- this.$$phase = 2 * Math.PI * unitPhase; // convert to radians
- };
-
- WaveGenerator.prototype.setAmplitude = function (amplitude) {
- this.$$amplitude = amplitude;
- };
-
- WaveGenerator.prototype.nextSample = function () {
- this.$$sampleNumber++;
- this.$$sample = null; // clear cache
- };
-
- WaveGenerator.prototype.getSample = function () {
- if (this.$$sample === null) {
- this.$$computeSample();
- }
-
- return this.$$sample;
- };
-
- return WaveGenerator;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.PhysicalLayer.PhysicalLayerBuilder', PhysicalLayerBuilder);
-
- PhysicalLayerBuilder.$inject = [
- 'Rewrite.PhysicalLayer.PhysicalLayer'
- ];
-
- function PhysicalLayerBuilder(
- PhysicalLayer
- ) {
- var PhysicalLayerBuilder;
-
- PhysicalLayerBuilder = function () {
- this._fftSize = 8192;
- this._unitTime = 0.25;
- this._fftSkipFactor = 3;
- this._microphoneMode = PhysicalLayer.MICROPHONE_MODE_ALWAYS_ON;
- this._samplePerSymbol = 2;
- this._symbolMin44100 = 114;
- this._symbolMin48000 = 82;
- this._symbolMinDefault = 1;
- this._symbolRange = 256 + 2; // 256 for data, 2 for "sync"
- this._correlationCode = [1, -1, 1, -1];
-
- this._txSampleRate = 44100;
- this._txAmplitude = 0.2;
-
- this._rxSignalDecibelThresholdFactor = 0.6;
-
- this._rxSymbolListener = undefined;
- this._rxSyncStatusListener = undefined;
- this._rxSampleDspDetailsListener = undefined;
- this._rxSyncDspDetailsListener = undefined;
- this._rxDspConfigListener = undefined;
-
- this._dspConfigListener = undefined;
-
- this._txSymbolListener = undefined;
- this._txSymbolProgressListener = undefined;
- this._txDspConfigListener = undefined;
- };
-
- PhysicalLayerBuilder.prototype.fftSize = function (fftSize) {
- this._fftSize = fftSize;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.unitTime = function (unitTime) {
- this._unitTime = unitTime;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.fftSkipFactor = function (fftSkipFactor) {
- this._fftSkipFactor = fftSkipFactor;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.microphoneMode = function (microphoneMode) {
- this._microphoneMode = microphoneMode;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.samplePerSymbol = function (samplePerSymbol) {
- this._samplePerSymbol = samplePerSymbol;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.symbolMin44100 = function (symbolMin44100) {
- this._symbolMin44100 = symbolMin44100;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.symbolMin48000 = function (symbolMin48000) {
- this._symbolMin48000 = symbolMin48000;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.symbolMinDefault = function (symbolMinDefault) {
- this._symbolMinDefault = symbolMinDefault;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.symbolRange = function (symbolRange) {
- this._symbolRange = symbolRange;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.txAmplitude = function (txAmplitude) {
- this._txAmplitude = txAmplitude;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.rxSymbolListener = function (listener) {
- this._rxSymbolListener = listener;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.rxSyncStatusListener = function (listener) {
- this._rxSyncStatusListener = listener;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.rxSampleDspDetailsListener = function (listener) {
- this._rxSampleDspDetailsListener = listener;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.rxSyncDspDetailsListener = function (listener) {
- this._rxSyncDspDetailsListener = listener;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.rxDspConfigListener = function (listener) {
- this._rxDspConfigListener = listener;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.dspConfigListener = function (listener) {
- this._dspConfigListener = listener;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.txSymbolListener = function (listener) {
- this._txSymbolListener = listener;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.txSymbolProgressListener = function (listener) {
- this._txSymbolProgressListener = listener;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.txDspConfigListener = function (listener) {
- this._txDspConfigListener = listener;
- return this;
- };
-
- PhysicalLayerBuilder.prototype.build = function () {
- return new PhysicalLayer(this);
- };
-
- return PhysicalLayerBuilder;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-// TODO refactor needed - move data returned by listeners to separate classes
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.PhysicalLayer.PhysicalLayer', PhysicalLayer);
-
- PhysicalLayer.$inject = [
- 'Rewrite.WebAudio.AudioMonoIO',
- 'Rewrite.Util.SmartTimer',
- 'Rewrite.PhysicalLayer.RxSyncDetector',
- 'Rewrite.Dsp.FFTResult',
- 'Rewrite.PhysicalLayer.TxSymbolManager'
- ];
-
- function PhysicalLayer(
- AudioMonoIO,
- SmartTimer,
- RxSyncDetector,
- FFTResult,
- TxSymbolManager
- ) {
- var PhysicalLayer;
-
- PhysicalLayer = function (builder) {
- // general config
- this.$$fftSize = builder._fftSize;
- this.$$audioMonoIO = new AudioMonoIO(this.$$fftSize);
- this.$$unitTime = builder._unitTime;
- this.$$smartTimer = new SmartTimer(this.$$unitTime);
- this.$$smartTimer.setListener(this.$$smartTimerListener.bind(this));
- this.$$fftSkipFactor = builder._fftSkipFactor;
- this.$$samplePerSymbol = builder._samplePerSymbol;
- this.$$symbolMin44100 = builder._symbolMin44100;
- this.$$symbolMin48000 = builder._symbolMin48000;
- this.$$symbolMinDefault = builder._symbolMinDefault;
- this.$$symbolRange = builder._symbolRange;
- this.$$rxSampleRate = this.$$audioMonoIO.getSampleRate();
- this.$$txAmplitude = builder._txAmplitude;
- this.$$correlationCode = builder._correlationCode.slice(0);
- this.$$rxSyncDetector = new RxSyncDetector(this.$$samplePerSymbol, this.$$correlationCode);
- this.$$rxSignalDecibelThresholdFactor = builder._rxSignalDecibelThresholdFactor;
-
- // state variables
- this.$$sampleNumber = PhysicalLayer.$$_INITIAL_SAMPLE_NUMER;
- this.$$sampleOffset = undefined;
- this.$$rxSymbolId = PhysicalLayer.$$_INITIAL_ID;
- this.$$rxSampleDspDetailsId = PhysicalLayer.$$_INITIAL_ID;
- this.$$rxSyncStatusId = PhysicalLayer.$$_INITIAL_ID;
- this.$$rxSymbol = undefined;
- this.$$rxSymbolRaw = undefined;
- this.$$rxSignalDecibel = undefined;
- this.$$rxSignalDecibelNextCandidate = undefined;
- this.$$rxNoiseDecibel = undefined;
- this.$$rxFrequencyData = undefined;
- this.$$isRxSyncInProgress = undefined;
- this.$$isRxSymbolSamplingPoint = undefined;
- this.$$rxSignalDecibelThreshold = PhysicalLayer.$$_INITIAL_RX_SIGNAL_DECIBEL_THRESHOLD;
- this.$$rxSyncDspDetailsLastId = undefined;
- this.$$txSymbolManager = new TxSymbolManager();
-
- // symbol ranges depends on sampleRate
- this.$$rxSymbolMin = this.$$getSymbolMin(this.$$rxSampleRate);
- this.$$rxSymbolMax = this.$$getSymbolMax(this.$$rxSampleRate);
- this.$$txSampleRate = undefined;
- this.$$txSymbolMin = undefined;
- this.$$txSymbolMax = undefined;
- this.setTxSampleRate(builder._txSampleRate);
-
- // setup listeners
- this.$$rxSymbolListener = PhysicalLayer.$$isFunction(builder._rxSymbolListener) ? builder._rxSymbolListener : null;
- this.$$rxSyncStatusListener = PhysicalLayer.$$isFunction(builder._rxSyncStatusListener) ? builder._rxSyncStatusListener : null;
- this.$$rxSampleDspDetailsListener = PhysicalLayer.$$isFunction(builder._rxSampleDspDetailsListener) ? builder._rxSampleDspDetailsListener : null;
- this.$$rxSyncDspDetailsListener = PhysicalLayer.$$isFunction(builder._rxSyncDspDetailsListener) ? builder._rxSyncDspDetailsListener : null;
- this.$$rxDspConfigListener = PhysicalLayer.$$isFunction(builder._rxDspConfigListener) ? builder._rxDspConfigListener : null;
- this.$$dspConfigListener = PhysicalLayer.$$isFunction(builder._dspConfigListener) ? builder._dspConfigListener : null;
- this.$$txSymbolListener = PhysicalLayer.$$isFunction(builder._txSymbolListener) ? builder._txSymbolListener : null;
- this.$$txSymbolProgressListener = PhysicalLayer.$$isFunction(builder._txSymbolProgressListener) ? builder._txSymbolProgressListener : null;
- this.$$txDspConfigListener = PhysicalLayer.$$isFunction(builder._txDspConfigListener) ? builder._txDspConfigListener : null;
-
- this.$$firstSmartTimerCall = true;
- };
-
- PhysicalLayer.MICROPHONE_MODE_ALWAYS_ON = 0;
- PhysicalLayer.MICROPHONE_MODE_AUTO_ON_OFF_WITH_GAP = 1;
- PhysicalLayer.$$_INITIAL_SAMPLE_NUMER = 0;
- PhysicalLayer.$$_INITIAL_ID = 0; // will be incremented BEFORE first use
- PhysicalLayer.$$_INITIAL_RX_SIGNAL_DECIBEL_THRESHOLD = +Infinity;
- PhysicalLayer.$$_TX_AMPLITUDE_SILENT = 0;
- PhysicalLayer.$$_TX_FREQUENCY_ZERO = 0;
- PhysicalLayer.$$_FIRST_SYMBOL = 1;
- PhysicalLayer.$$_SYMBOL_SYNC_A_OFFSET = 1;
- PhysicalLayer.$$_SYMBOL_SYNC_B_OFFSET = 0;
- PhysicalLayer.$$_RX_SYMBOL_IDLE = null;
- PhysicalLayer.SYMBOL_IS_NOT_VALID_EXCEPTION = 'Symbol is not valid. Please pass number that is inside symbol range.';
-
- // -----------------------------------------
-
- PhysicalLayer.prototype.getRxSampleRate = function () {
- var rxDspConfig = this.getRxDspConfig();
-
- return rxDspConfig.rxSampleRate;
- };
-
- PhysicalLayer.prototype.txSync = function () {
- var i, correlationCodeValue, txFskSymbol, halfPlusOne;
-
- this.$$txSymbolManager.handleGapLogicAtStart();
-
- for (i = 0; i < this.$$correlationCode.length; i++) {
- correlationCodeValue = this.$$correlationCode[i];
- txFskSymbol = correlationCodeValue === -1
- ? this.$$txSymbolMax - PhysicalLayer.$$_SYMBOL_SYNC_A_OFFSET
- : this.$$txSymbolMax - PhysicalLayer.$$_SYMBOL_SYNC_B_OFFSET;
- this.$$txSymbolManager.addTxFskSymbol(txFskSymbol);
- }
-
- // TODO actually it should take into account the Correlator.THRESHOLD_UNIT value
- halfPlusOne = Math.ceil(this.$$correlationCode.length / 2) + 1;
- this.$$txSymbolManager.handleGapLogicAtEndOfSync(halfPlusOne);
-
- this.$$txSymbolProgressListener ? this.$$txSymbolProgressListener(this.getTxSymbolProgress()) : undefined;
- };
-
- PhysicalLayer.prototype.txSymbol = function (txSymbol) {
- var isNumber, txFskSymbolParsed, inRange, isValid, id;
-
- this.$$txSymbolManager.handleGapLogicAtStart();
-
- txFskSymbolParsed = parseInt(txSymbol);
- isNumber = typeof txFskSymbolParsed === 'number';
- inRange = this.$$txSymbolMin <= txFskSymbolParsed && txFskSymbolParsed <= this.$$txSymbolMax;
- isValid = isNumber && inRange;
-
- if (!isValid) {
- throw PhysicalLayer.SYMBOL_IS_NOT_VALID_EXCEPTION;
- }
-
- id = this.$$txSymbolManager.addTxFskSymbol(txFskSymbolParsed);
-
- this.$$txSymbolManager.handleGapLogicAtEnd();
-
- this.$$txSymbolProgressListener ? this.$$txSymbolProgressListener(this.getTxSymbolProgress()) : undefined;
-
- return id;
- };
-
- PhysicalLayer.prototype.setTxSampleRate = function (txSampleRate) {
- this.$$txSampleRate = txSampleRate;
- this.$$txSymbolMin = this.$$getSymbolMin(this.$$txSampleRate);
- this.$$txSymbolMax = this.$$getSymbolMax(this.$$txSampleRate);
- this.$$txSymbolManager.clearTxSymbolQueue();
- this.$$txSymbolProgressListener ? this.$$txSymbolProgressListener(this.getTxSymbolProgress()) : undefined;
- this.$$txDspConfigListener ? this.$$txDspConfigListener(this.getTxDspConfig()) : undefined;
- };
-
- PhysicalLayer.prototype.setLoopback = function (state) {
- this.$$audioMonoIO.setLoopback(state);
- this.$$dspConfigListener ? this.$$dspConfigListener(this.getDspConfig()) : undefined;
- };
-
- PhysicalLayer.prototype.setUnitTime = function (unitTime) {
- this.$$unitTime = unitTime;
- this.$$smartTimer.setInterval(unitTime);
- this.$$dspConfigListener ? this.$$dspConfigListener(this.getDspConfig()) : undefined;
- };
-
- PhysicalLayer.prototype.setTxAmplitude = function (txAmplitude) {
- this.$$txAmplitude = txAmplitude;
- this.$$txDspConfigListener ? this.$$txDspConfigListener(this.getTxDspConfig()) : undefined;
- };
-
- // -----------------------------------------
-
- PhysicalLayer.prototype.getRxSymbol = function () {
- return {
- id: this.$$rxSymbolId,
- rxSymbol: this.$$rxSymbol,
- rxSampleDspDetailsId: this.$$rxSampleDspDetailsId
- };
- };
-
- PhysicalLayer.prototype.getRxSyncStatus = function () {
- var rxSyncDspDetails = this.$$rxSyncDetector.getRxSyncDspDetails();
-
- return {
- id: this.$$rxSyncStatusId,
- isRxSyncInProgress: this.$$isRxSyncInProgress,
- isRxSyncOk: !!rxSyncDspDetails.id,
- rxSyncDspDetailsId: rxSyncDspDetails.id,
- rxSampleDspDetailsId: this.$$rxSampleDspDetailsId
- };
- };
-
- PhysicalLayer.prototype.getRxSampleDspDetails = function () {
- return {
- id: this.$$rxSampleDspDetailsId,
- rxSymbolRaw: this.$$rxSymbolRaw,
- rxSignalDecibel: this.$$rxSignalDecibel,
- // rxSignalDecibelNextCandidate: this.$$rxSignalDecibelNextCandidate, // TODO add this at some point
- rxNoiseDecibel: this.$$rxNoiseDecibel,
- rxFrequencyData: this.$$rxFrequencyData.slice(0),
- isRxSymbolSamplingPoint: this.$$isRxSymbolSamplingPoint,
- rxSampleNumber: this.$$sampleNumber,
- rxSampleOffset: this.$$sampleOffset
- };
- };
-
- PhysicalLayer.prototype.getRxSyncDspDetails = function () {
- var rxSyncDspDetails = this.$$rxSyncDetector.getRxSyncDspDetails();
-
- return {
- id: rxSyncDspDetails.id,
- rxSymbolSamplingPointOffset: rxSyncDspDetails.rxSymbolSamplingPointOffset,
- rxCorrelationValue: rxSyncDspDetails.rxCorrelationValue,
- rxCorrelationCodeLength: rxSyncDspDetails.rxCorrelationCodeLength,
- rxSignalDecibelAverage: rxSyncDspDetails.rxSignalDecibelAverage,
- rxNoiseDecibelAverage: rxSyncDspDetails.rxNoiseDecibelAverage,
- rxSignalToNoiseRatio: rxSyncDspDetails.rxSignalToNoiseRatio
- };
- };
-
- PhysicalLayer.prototype.getRxDspConfig = function () {
- var rxSymbolFrequencySpacing = this.$$getFrequency(
- PhysicalLayer.$$_FIRST_SYMBOL,
- this.$$rxSampleRate
- );
-
- return {
- rxSampleRate: this.$$rxSampleRate,
- rxSymbolFrequencySpacing: rxSymbolFrequencySpacing,
- rxSymbolMin: this.$$rxSymbolMin,
- rxSymbolMax: this.$$rxSymbolMax,
- rxSignalDecibelThreshold: this.$$rxSignalDecibelThreshold,
- rxSignalDecibelThresholdFactor: this.$$rxSignalDecibelThresholdFactor
- };
- };
-
- PhysicalLayer.prototype.getDspConfig = function () {
- return {
- fftSkipFactor: this.$$fftSkipFactor,
- fftSize: this.$$fftSize,
- samplePerSymbol: this.$$samplePerSymbol,
- unitTime: this.$$unitTime,
- isLoopbackEnabled: this.$$audioMonoIO.isLoopbackEnabled()
- };
- };
-
- PhysicalLayer.prototype.getTxSymbol = function () {
- return this.$$txSymbolManager.getTxSymbol();
- };
-
- PhysicalLayer.prototype.getTxSymbolProgress = function () {
- return this.$$txSymbolManager.getTxSymbolProgress();
- };
-
- PhysicalLayer.prototype.getTxDspConfig = function () {
- var txSymbolFrequencySpacing = this.$$getFrequency(
- PhysicalLayer.$$_FIRST_SYMBOL,
- this.$$txSampleRate
- );
-
- return {
- txSampleRate: this.$$txSampleRate,
- txSymbolFrequencySpacing: txSymbolFrequencySpacing,
- txSymbolMin: this.$$txSymbolMin,
- txSymbolMax: this.$$txSymbolMax,
- txAmplitude: this.$$txAmplitude
- }
- };
-
- // -----------------------------------------
-
- PhysicalLayer.prototype.$$smartTimerListener = function () {
- if (this.$$firstSmartTimerCall) {
- this.$$rxDspConfigListener ? this.$$rxDspConfigListener(this.getRxDspConfig()) : undefined;
- this.$$dspConfigListener ? this.$$dspConfigListener(this.getDspConfig()) : undefined;
- this.$$txDspConfigListener ? this.$$txDspConfigListener(this.getTxDspConfig()) : undefined;
- }
-
- this.$$sampleOffset = this.$$sampleNumber % this.$$samplePerSymbol;
- this.$$rx();
- this.$$tx();
-
- this.$$sampleNumber++;
-
- this.$$firstSmartTimerCall = false;
- };
-
- PhysicalLayer.prototype.$$rx = function () {
- var
- isAllowedToListen,
- fftResult,
- rxSyncDspDetails,
- isNewSyncAvailable = false,
- isNewSymbolReadyToTake,
- fakeFrequencyData,
- i;
-
- this.$$rxSampleDspDetailsId++;
- this.$$rxSyncStatusId++;
-
- isAllowedToListen =
- this.$$txSymbolManager.getTxSymbolCurrent().isIdle() ||
- this.$$audioMonoIO.isLoopbackEnabled();
-
- if (isAllowedToListen) {
- fftResult = new FFTResult(this.$$audioMonoIO.getFrequencyData(), this.$$rxSampleRate);
- fftResult.downconvert(this.$$fftSkipFactor);
- this.$$rxFrequencyData = fftResult.getFrequencyData();
- this.$$rxSymbolRaw = fftResult.getLoudestBinIndexInBinRange(this.$$rxSymbolMin, this.$$rxSymbolMax);
- this.$$rxSignalDecibel = fftResult.getDecibel(this.$$rxSymbolRaw);
- this.$$rxSignalDecibelNextCandidate = -Infinity; // TODO add this at some point
- this.$$rxNoiseDecibel = fftResult.getDecibelAverage(this.$$rxSymbolMin, this.$$rxSymbolMax, this.$$rxSymbolRaw);
- } else {
- // TODO experiments - refactor this
- fakeFrequencyData = [];
- for (i = 0; i < this.$$fftSize * 0.5; i++) {
- fakeFrequencyData.push(-160);
- }
- fftResult = new FFTResult(fakeFrequencyData, this.$$rxSampleRate);
- fftResult.downconvert(this.$$fftSkipFactor);
- this.$$rxFrequencyData = fftResult.getFrequencyData();
- this.$$rxSymbolRaw = this.$$rxSymbolMin;
- this.$$rxSignalDecibel = -Infinity;
- this.$$rxSignalDecibelNextCandidate = -Infinity;
- this.$$rxNoiseDecibel = -Infinity;
- }
-
- this.$$handleRxSync();
-
- this.$$isRxSyncInProgress = this.$$rxSyncDetector.isRxSyncInProgress();
- rxSyncDspDetails = this.$$rxSyncDetector.getRxSyncDspDetails();
- if (rxSyncDspDetails.id && rxSyncDspDetails.id !== this.$$rxSyncDspDetailsLastId) {
- this.$$rxSignalDecibelThreshold = rxSyncDspDetails.rxNoiseDecibelAverage +
- this.$$rxSignalDecibelThresholdFactor * rxSyncDspDetails.rxSignalToNoiseRatio;
- this.$$rxSyncDspDetailsLastId = rxSyncDspDetails.id;
- isNewSyncAvailable = true;
- }
-
- this.$$isRxSymbolSamplingPoint = rxSyncDspDetails.id > 0 && this.$$sampleOffset === rxSyncDspDetails.rxSymbolSamplingPointOffset;
- isNewSymbolReadyToTake = this.$$isRxSymbolSamplingPoint && this.$$rxSignalDecibel > this.$$rxSignalDecibelThreshold;
- this.$$rxSymbol = isNewSymbolReadyToTake ? this.$$rxSymbolRaw : PhysicalLayer.$$_RX_SYMBOL_IDLE;
-
- // call listeners
- if (isNewSyncAvailable) {
- this.$$rxSyncDspDetailsListener ? this.$$rxSyncDspDetailsListener(this.getRxSyncDspDetails()) : undefined;
- this.$$rxDspConfigListener ? this.$$rxDspConfigListener(this.getRxDspConfig()) : undefined;
- }
- this.$$rxSampleDspDetailsListener ? this.$$rxSampleDspDetailsListener(this.getRxSampleDspDetails()) : undefined;
- this.$$rxSyncStatusListener ? this.$$rxSyncStatusListener(this.getRxSyncStatus()) : undefined;
- if (this.$$isRxSymbolSamplingPoint) {
- this.$$rxSymbolId++;
- this.$$rxSymbolListener ? this.$$rxSymbolListener(this.getRxSymbol()) : undefined;
- }
- };
-
- PhysicalLayer.prototype.$$tx = function () {
- var
- isFirstSampleOfBlock = this.$$sampleOffset === 0,
- isTxAboutToStart,
- isTxAboutToEnd;
-
- if (!isFirstSampleOfBlock) {
- return;
- }
-
- isTxAboutToStart = this.$$txSymbolManager.isTxAboutToStart();
- isTxAboutToEnd = this.$$txSymbolManager.isTxAboutToEnd();
- this.$$txSymbolManager.tick();
-
- if (isTxAboutToStart) {
- this.$$audioMonoIO.microphoneDisable(); // TODO experimental feature, this solves volume control problem on mobile browsers
- // console.log('microphone disable');
- }
- if (isTxAboutToEnd) {
- this.$$audioMonoIO.microphoneEnable(); // TODO experimental feature, this solves volume control problem on mobile browsers
- // console.log('microphone enable');
- }
-
- this.$$updateOscillator();
-
- this.$$txSymbolListener ? this.$$txSymbolListener(this.getTxSymbol()) : undefined;
- this.$$txSymbolProgressListener ? this.$$txSymbolProgressListener(this.getTxSymbolProgress()) : undefined;
- };
-
- // -------
-
- PhysicalLayer.prototype.$$handleRxSync = function () {
- var correlationCodeValue = null;
-
- switch (this.$$rxSymbolRaw) {
- case this.$$rxSymbolMax - PhysicalLayer.$$_SYMBOL_SYNC_A_OFFSET:
- correlationCodeValue = -1;
- break;
- case this.$$rxSymbolMax - PhysicalLayer.$$_SYMBOL_SYNC_B_OFFSET:
- correlationCodeValue = 1;
- break;
- }
- this.$$rxSyncDetector.handle(
- correlationCodeValue, this.$$rxSignalDecibel, this.$$rxNoiseDecibel
- );
- };
-
- PhysicalLayer.prototype.$$getSymbolMin = function (sampleRate) {
- switch (sampleRate) {
- case 44100:
- return this.$$symbolMin44100;
- case 48000:
- return this.$$symbolMin48000;
- default:
- return this.$$symbolMinDefault;
- }
- };
-
- PhysicalLayer.prototype.$$getSymbolMax = function (sampleRate) {
- var symbolMin = this.$$getSymbolMin(sampleRate);
-
- return symbolMin + this.$$symbolRange - 1;
- };
-
- PhysicalLayer.prototype.$$updateOscillator = function () {
- var frequency, amplitude, isFsk, txSymbolCurrent;
-
- txSymbolCurrent = this.$$txSymbolManager.getTxSymbolCurrent();
- isFsk = txSymbolCurrent.isFsk();
- if (isFsk) {
- frequency = this.$$getFrequency(txSymbolCurrent.getTxFskSymbol(), this.$$txSampleRate);
- amplitude = this.$$txAmplitude;
- } else {
- frequency = PhysicalLayer.$$_TX_FREQUENCY_ZERO;
- amplitude = PhysicalLayer.$$_TX_AMPLITUDE_SILENT;
- }
-
- this.$$audioMonoIO.setPeriodicWave(frequency, amplitude);
- };
-
- PhysicalLayer.prototype.$$getFrequency = function (symbol, sampleRate) {
- var nativeFrequency = FFTResult.getFrequency(symbol, sampleRate, this.$$fftSize);
-
- return this.$$fftSkipFactor * nativeFrequency;
- };
-
- PhysicalLayer.$$isFunction = function (variable) {
- return typeof variable === 'function';
- };
-
- return PhysicalLayer;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.PhysicalLayer.RxSyncDetector', RxSyncDetector);
-
- RxSyncDetector.$inject = [
- 'Rewrite.Dsp.Correlator'
- ];
-
- function RxSyncDetector(
- Correlator
- ) {
- var RxSyncDetector;
-
- RxSyncDetector = function (samplePerSymbol, correlationCode) {
- this.$$samplePerSymbol = samplePerSymbol;
- this.$$rxSyncInProgress = false;
- this.$$rxSyncDspDetails = RxSyncDetector.$$getEmpty();
- this.$$id = RxSyncDetector.$$_INITIAL_ID;
- this.$$correlator = new Correlator(samplePerSymbol, correlationCode);
- this.$$blockHistory = undefined;
- this.$$rxSampleNumber = RxSyncDetector.$$_INITIAL_RX_SAMPLE_NUMBER;
-
- this.$$initializeBlockHistory();
- };
-
- RxSyncDetector.$$_FIRST_ELEMENT = 0;
- RxSyncDetector.$$_INITIAL_ID = 1;
- RxSyncDetector.$$_INITIAL_RX_SAMPLE_NUMBER = 0;
-
- RxSyncDetector.prototype.isRxSyncInProgress = function () {
- return this.$$rxSyncInProgress;
- };
-
- RxSyncDetector.prototype.getRxSyncDspDetails = function () {
- return this.$$rxSyncDspDetails;
- };
-
- RxSyncDetector.prototype.handle = function (correlationCodeValue, signalDecibel, noiseDecibel) {
- var
- offset,
- blockHistoryEntry,
- isLastOffsetInSamplingBlock,
- syncDetected,
- syncJustUpdated,
- lastSyncDetected,
- syncCandidate;
-
- offset = this.$$rxSampleNumber % this.$$samplePerSymbol;
- blockHistoryEntry = this.$$blockHistory[offset];
- isLastOffsetInSamplingBlock = offset === (this.$$samplePerSymbol - 1);
-
- this.$$correlator.handle(correlationCodeValue, signalDecibel, noiseDecibel);
- syncDetected = this.$$correlator.isCorrelated();
-
- if (syncDetected) {
- syncCandidate = RxSyncDetector.$$getEmpty(); // TODO create dedicated class
- syncCandidate.rxSymbolSamplingPointOffset = offset;
- syncCandidate.rxCorrelationValue = this.$$correlator.getCorrelationValue();
- syncCandidate.rxCorrelationCodeLength = this.$$correlator.getCorrelationCodeLength();
- syncCandidate.rxSignalDecibelAverage = this.$$correlator.getSignalDecibelAverage();
- syncCandidate.rxNoiseDecibelAverage = this.$$correlator.getNoiseDecibelAverage();
- syncCandidate.rxSignalToNoiseRatio = this.$$correlator.getSignalToNoiseRatio();
-
- blockHistoryEntry.decisionList.push(syncCandidate);
- }
- lastSyncDetected = blockHistoryEntry.syncDetected;
- blockHistoryEntry.syncJustLost = lastSyncDetected && !syncDetected;
- blockHistoryEntry.syncDetected = syncDetected;
-
- if (isLastOffsetInSamplingBlock) {
- syncJustUpdated = this.$$tryToUpdateSync();
- }
-
- this.$$rxSyncInProgress =
- !syncJustUpdated &&
- this.$$isRxSyncInProgressInHistoryBlock();
-
- this.$$rxSampleNumber++;
- };
-
- RxSyncDetector.prototype.$$sortByCorrelationValue = function (a, b) {
- return a.rxCorrelationValue < b.rxCorrelationValue
- ? 1
- : (a.rxCorrelationValue > b.rxCorrelationValue ? -1 : 0);
- };
-
- RxSyncDetector.prototype.$$sortBySignalDecibel = function (a, b) {
- return a.rxSignalDecibelAverage < b.rxSignalDecibelAverage
- ? 1
- : (a.rxSignalDecibelAverage > b.rxSignalDecibelAverage ? -1 : 0);
- };
-
- RxSyncDetector.prototype.$$sortDecisionList = function (data) {
- var self = this;
-
- data.sort(function (a, b) {
- return 0 ||
- self.$$sortByCorrelationValue(a, b) ||
- self.$$sortBySignalDecibel(a, b);
- });
- };
-
- RxSyncDetector.prototype.$$initializeBlockHistory = function () {
- var offset;
-
- this.$$blockHistory = [];
- for (offset = 0; offset < this.$$samplePerSymbol; offset++) {
- this.$$blockHistory.push({
- decisionList: [],
- syncJustLost: undefined,
- syncDetected: undefined
- });
- }
- };
-
- RxSyncDetector.prototype.$$resetBlockHistory = function () {
- var offset, blockHistoryEntry;
-
- for (offset = 0; offset < this.$$samplePerSymbol; offset++) {
- blockHistoryEntry = this.$$blockHistory[offset];
- blockHistoryEntry.decisionList.length = 0;
- blockHistoryEntry.syncJustLost = undefined;
- blockHistoryEntry.syncDetected = undefined;
- }
- };
-
- RxSyncDetector.prototype.$$getTheBestRxSyncDspDetails = function () {
- var offset, decisionList, innerDecisionList, strongestSync;
-
- decisionList = [];
- for (offset = 0; offset < this.$$samplePerSymbol; offset++) {
- innerDecisionList = this.$$blockHistory[offset].decisionList;
- if (innerDecisionList.length > 0) {
- this.$$sortDecisionList(innerDecisionList);
- decisionList.push(innerDecisionList[RxSyncDetector.$$_FIRST_ELEMENT]);
- }
- }
- this.$$sortDecisionList(decisionList);
- strongestSync = decisionList[RxSyncDetector.$$_FIRST_ELEMENT];
-
- return strongestSync;
- };
-
- RxSyncDetector.prototype.$$updateSync = function () {
- this.$$rxSyncDspDetails = this.$$getTheBestRxSyncDspDetails();
- this.$$rxSyncDspDetails.id = this.$$id++;
- this.$$resetBlockHistory();
- this.$$correlator.reset();
- };
-
- RxSyncDetector.prototype.$$tryToUpdateSync = function () {
- var offset;
-
- for (offset = 0; offset < this.$$samplePerSymbol; offset++) {
- if (this.$$blockHistory[offset].syncJustLost) {
- this.$$updateSync();
- return true;
- }
- }
-
- return false;
- };
-
- RxSyncDetector.prototype.$$isRxSyncInProgressInHistoryBlock = function () {
- var offset, blockHistoryEntry;
-
- for (offset = 0; offset < this.$$samplePerSymbol; offset++) {
- blockHistoryEntry = this.$$blockHistory[offset];
- if (blockHistoryEntry.syncDetected || blockHistoryEntry.syncJustLost) {
- return true;
- }
- }
-
- return false;
- };
-
- RxSyncDetector.$$getEmpty = function () {
- return {
- id: null,
- rxSymbolSamplingPointOffset: undefined,
- rxCorrelationValue: undefined,
- rxCorrelationCodeLength: undefined,
- rxSignalDecibelAverage: undefined,
- rxNoiseDecibelAverage: undefined,
- rxSignalToNoiseRatio: undefined
- };
- };
-
- return RxSyncDetector;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.PhysicalLayer.TxSymbolManager', TxSymbolManager);
-
- TxSymbolManager.$inject = [
- 'Rewrite.PhysicalLayer.TxSymbol'
- ];
-
- function TxSymbolManager(
- TxSymbol
- ) {
- var TxSymbolManager;
-
- TxSymbolManager = function () {
- this.$$txSymbolId = 1;
- this.$$txSymbol = null;
- this.$$txSymbolCurrent = this.$$getTxSymbolIdle();
- this.$$txSymbolQueue = [];
- };
-
- TxSymbolManager.prototype.clearTxSymbolQueue = function () {
- this.$$txSymbolQueue.length = 0;
- };
-
- TxSymbolManager.prototype.getTxSymbol = function () {
- return this.$$txSymbol.cloneClean();
- };
-
- TxSymbolManager.prototype.getTxSymbolCurrent = function () {
- return this.$$txSymbolCurrent;
- };
-
- TxSymbolManager.prototype.getTxSymbolProgress = function () {
- var
- result = {},
- i;
-
- result.txSymbol = this.getTxSymbol();
-
- result.txSymbolCurrent = this.$$txSymbolCurrent.cloneClean();
-
- result.txSymbolQueue = [];
- for (i = 0; i < this.$$txSymbolQueue.length; i++) {
- result.txSymbolQueue.push(
- this.$$txSymbolQueue[i].cloneClean()
- );
- }
-
- result.isTxInProgress = this.isTxInProgress();
-
- return result;
- };
-
- TxSymbolManager.prototype.isTxInProgress = function () {
- return this.$$txSymbolQueue.length > 0 ||
- this.$$txSymbolCurrent.isNotIdle();
- };
-
- TxSymbolManager.prototype.addTxFskSymbol = function (txFskSymbol) {
- var txSymbol = new TxSymbol(
- this.$$txSymbolId++,
- TxSymbol.TX_SYMBOL_FSK
- );
-
- txSymbol.setTxFskSymbol(txFskSymbol);
- this.$$txSymbolQueue.push(txSymbol);
-
- return txSymbol.getId();
- };
-
- TxSymbolManager.prototype.addTxSymbolGapImportant = function () {
- var txSymbolGapImportant = new TxSymbol(
- this.$$txSymbolId++,
- TxSymbol.TX_SYMBOL_GAP_IMPORTANT
- );
- this.$$txSymbolQueue.push(txSymbolGapImportant);
- };
-
- TxSymbolManager.prototype.addTxSymbolGapDeletable = function () {
- var txSymbolGapDeletable = new TxSymbol(
- this.$$txSymbolId++,
- TxSymbol.TX_SYMBOL_GAP_DELETABLE
- );
- this.$$txSymbolQueue.push(txSymbolGapDeletable);
- };
-
- TxSymbolManager.prototype.$$getTxSymbolIdle = function () {
- return new TxSymbol(
- this.$$txSymbolId++,
- TxSymbol.TX_SYMBOL_IDLE
- );
- };
-
- TxSymbolManager.prototype.isTxAboutToStart = function () {
- var isQueueNotEmpty = this.$$txSymbolQueue.length !== 0;
-
- return this.$$txSymbolCurrent.isIdle() && isQueueNotEmpty;
- };
-
- TxSymbolManager.prototype.isTxAboutToEnd = function () {
- var isQueueEmpty = this.$$txSymbolQueue.length === 0;
-
- return isQueueEmpty && this.$$txSymbolCurrent.isNotIdle();
- };
-
- TxSymbolManager.prototype.tick = function () {
- var txSymbolIdle, isQueueEmpty;
-
- isQueueEmpty = this.$$txSymbolQueue.length === 0;
- this.$$txSymbol = this.$$txSymbolCurrent;
-
- if (isQueueEmpty) {
- txSymbolIdle = this.$$getTxSymbolIdle();
- this.$$txSymbolCurrent = txSymbolIdle;
- } else {
- this.$$txSymbolCurrent = this.$$txSymbolQueue.shift();
- }
- };
-
- TxSymbolManager.prototype.handleGapLogicAtStart = function () {
- // When device A sends some data to device B
- // then device B cannot respond immediately. We
- // need make sure that device A will have some time
- // to reinitialize microphone again. This is solved
- // by adding two 'gap' symbols in the beginning
- // Similar problem we have at the end. If we enable
- // microphone at the same time as last symbol stops
- // then we have a glitch. We need to add one 'gap'
- // symbol after the last symbol.
- // If symbol is not last we need to remove that
- // unnecessary gap.
- if (this.isTxInProgress()) {
- this.$$clearAllDeletableGapFromTheEndOfTheQueue();
- } else {
- this.addTxSymbolGapDeletable(); // #1
- this.addTxSymbolGapDeletable(); // #2
- }
- };
-
- TxSymbolManager.prototype.handleGapLogicAtEnd = function () {
- // will be removed if subsequent symbol will arrive
- this.addTxSymbolGapDeletable();
- };
-
- TxSymbolManager.prototype.handleGapLogicAtEndOfSync = function (gapImportantNumber) {
- var i;
-
- for (i = 0; i < gapImportantNumber; i++) {
- this.addTxSymbolGapImportant();
- }
- };
-
- TxSymbolManager.prototype.$$clearAllDeletableGapFromTheEndOfTheQueue = function () {
- var i;
-
- for (i = this.$$txSymbolQueue.length - 1; i >= 0; i--) {
- if (this.$$txSymbolQueue[i].isNotGapDeletable()) {
- this.$$txSymbolQueue.length = i + 1;
- break;
- }
- }
- };
-
- return TxSymbolManager;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.PhysicalLayer.TxSymbol', TxSymbol);
-
- TxSymbol.$inject = [];
-
- function TxSymbol() {
- var TxSymbol;
-
- TxSymbol = function (id, type) {
- this.$$id = id;
- this.$$txSymbolType = type;
- this.$$txFskSymbol = null;
- };
-
- TxSymbol.TX_SYMBOL_IDLE = 'TX_SYMBOL_IDLE';
- TxSymbol.TX_SYMBOL_GAP_IMPORTANT = 'TX_SYMBOL_GAP_IMPORTANT';
- TxSymbol.TX_SYMBOL_GAP_DELETABLE = 'TX_SYMBOL_GAP_DELETABLE';
- TxSymbol.TX_SYMBOL_FSK = 'TX_SYMBOL_FSK';
-
- TxSymbol.prototype.setTxFskSymbol = function (txFskSymbol) {
- this.$$txFskSymbol = txFskSymbol;
- };
-
- TxSymbol.prototype.cloneClean = function () {
- return {
- id: this.$$id,
- txSymbolType: this.$$txSymbolType,
- txFskSymbol: this.$$txFskSymbol
- };
- };
-
- TxSymbol.prototype.isNotIdle = function () {
- return this.$$txSymbolType !== TxSymbol.TX_SYMBOL_IDLE;
- };
-
- TxSymbol.prototype.isIdle = function () {
- return this.$$txSymbolType === TxSymbol.TX_SYMBOL_IDLE;
- };
-
- TxSymbol.prototype.isFsk = function () {
- return this.$$txSymbolType === TxSymbol.TX_SYMBOL_FSK;
- };
-
- TxSymbol.prototype.isNotGapDeletable = function () {
- return this.$$txSymbolType !== TxSymbol.TX_SYMBOL_GAP_DELETABLE;
- };
-
- TxSymbol.prototype.getId = function () {
- return this.$$id;
- };
-
- TxSymbol.prototype.getTxFskSymbol = function () {
- return this.$$txFskSymbol;
- };
-
- return TxSymbol;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.Util.Buffer', Buffer);
-
- Buffer.$inject = [];
-
- function Buffer() {
- var Buffer;
-
- Buffer = function (sizeMax) {
- this.$$data = [];
- this.$$positionStart = null;
- this.$$positionEnd = null;
- this.$$size = null;
- this.$$sizeMax = null;
- this.setSizeMax(sizeMax);
- };
-
- Buffer.prototype.clone = function () {
- var
- buffer = new Buffer(this.$$sizeMax),
- dataLength = this.$$data.length,
- i;
-
- buffer.$$positionStart = this.$$positionStart;
- buffer.$$positionEnd = this.$$positionEnd;
- buffer.$$size = this.$$size;
-
- for (i = 0; i < dataLength; i++) {
- buffer[i] = this.$$data[i];
- }
-
- return buffer;
- };
-
- Buffer.prototype.setSizeMax = function (sizeMax) {
- this.$$positionStart = 0;
- this.$$positionEnd = 0;
- this.$$size = 0;
- this.$$sizeMax = sizeMax;
- this.$$data.length = 0; // drop all data
- this.$$data.length = sizeMax;
- };
-
- Buffer.prototype.push = function (value) {
- if (this.$$size === this.$$sizeMax) {
- return false;
- }
-
- this.$$data[this.$$positionEnd] = value;
- this.$$positionEnd = (this.$$positionEnd + 1) % this.$$sizeMax;
- this.$$size++;
-
- return true;
- };
-
- Buffer.prototype.pushEvenIfFull = function (value) {
- if (this.isFull()) {
- this.pop();
- }
- this.push(value);
- };
-
- Buffer.prototype.pop = function () {
- var result;
-
- if (this.$$size === 0) {
- return null;
- }
- result = this.$$data[this.$$positionStart];
- this.$$positionStart = (this.$$positionStart + 1) % this.$$sizeMax;
- this.$$size--;
-
- return result;
- };
-
- Buffer.prototype.getItem = function (index) {
- if (index >= this.$$size || index < 0) {
- return null;
- }
-
- return this.$$data[(this.$$positionStart + index) % this.$$sizeMax];
- };
-
- Buffer.prototype.getSize = function () {
- return this.$$size;
- };
-
- Buffer.prototype.getSizeMax = function () {
- return this.$$sizeMax;
- };
-
- Buffer.prototype.isFull = function () {
- return this.$$size === this.$$sizeMax;
- };
-
- Buffer.prototype.getAll = function () {
- var i, result = [];
-
- for (i = 0; i < this.getSize(); i++) {
- result.push(
- this.getItem(i)
- );
- }
-
- return result;
- };
-
- Buffer.prototype.fillWith = function (value) {
- var i;
-
- for (i = 0; i < this.getSizeMax(); i++) {
- this.pushEvenIfFull(value);
- }
- };
-
- return Buffer;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.Util.FrequencyCalculator', FrequencyCalculator);
-
- FrequencyCalculator.$inject = [];
-
- function FrequencyCalculator() {
- var FrequencyCalculator;
-
- FrequencyCalculator = function (sampleRateProvider, windowSizeProvider) {
- this.$$sampleRateProvider = sampleRateProvider ? sampleRateProvider : null;
- this.$$windowSizeProvider = windowSizeProvider ? windowSizeProvider : null;
-
- if (!this.$$sampleRateProvider || !this.$$windowSizeProvider) {
- throw FrequencyCalculator.PLEASE_SET_BOTH_PROVIDERS;
- }
- };
-
- FrequencyCalculator.PLEASE_SET_BOTH_PROVIDERS = 'Please set both providers';
-
- FrequencyCalculator.$$isFunction = function (variable) {
- return typeof variable === 'function';
- };
-
- FrequencyCalculator.prototype.getSamplePerPeriodFromHertz = function (hertz) {
- var sampleRate;
-
- sampleRate = FrequencyCalculator.$$isFunction(this.$$sampleRateProvider)
- ? this.$$sampleRateProvider()
- : this.$$sampleRateProvider;
-
- return sampleRate / hertz;
- };
-
- FrequencyCalculator.prototype.getHertzFromSamplePerPeriod = function (samplePerPeriod) {
- var sampleRate;
-
- sampleRate = FrequencyCalculator.$$isFunction(this.$$sampleRateProvider)
- ? this.$$sampleRateProvider()
- : this.$$sampleRateProvider;
-
- return sampleRate / samplePerPeriod;
- };
-
- FrequencyCalculator.prototype.getCyclePerWindowFromHertz = function (hertz) {
- var windowSize, sampleRate;
-
- windowSize = FrequencyCalculator.$$isFunction(this.$$windowSizeProvider)
- ? this.$$windowSizeProvider()
- : this.$$windowSizeProvider;
- sampleRate = FrequencyCalculator.$$isFunction(this.$$sampleRateProvider)
- ? this.$$sampleRateProvider()
- : this.$$sampleRateProvider;
-
- return hertz * windowSize / sampleRate;
- };
-
- FrequencyCalculator.prototype.getHertzFromCyclePerWindow = function (cyclePerWindow) {
- var windowSize, sampleRate;
-
- windowSize = FrequencyCalculator.$$isFunction(this.$$windowSizeProvider)
- ? this.$$windowSizeProvider()
- : this.$$windowSizeProvider;
- sampleRate = FrequencyCalculator.$$isFunction(this.$$sampleRateProvider)
- ? this.$$sampleRateProvider()
- : this.$$sampleRateProvider;
-
- return cyclePerWindow * sampleRate / windowSize;
- };
-
- FrequencyCalculator.prototype.getSamplePerPeriodFromCyclePerWindow = function (cyclePerWindow) {
- var windowSize;
-
- windowSize = FrequencyCalculator.$$isFunction(this.$$windowSizeProvider)
- ? this.$$windowSizeProvider()
- : this.$$windowSizeProvider;
-
- return windowSize / cyclePerWindow;
- };
-
- FrequencyCalculator.prototype.getCyclePerWindowFromSamplePerPeriod = function (samplePerPeriod) {
- var windowSize;
-
- windowSize = FrequencyCalculator.$$isFunction(this.$$windowSizeProvider)
- ? this.$$windowSizeProvider()
- : this.$$windowSizeProvider;
-
- return windowSize / samplePerPeriod;
- };
-
- return FrequencyCalculator;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-// MusicCalculator class implements Scientific Pitch Notation:
-// https://en.wikipedia.org/wiki/Scientific_pitch_notation
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.Util.MusicCalculator', MusicCalculator);
-
- MusicCalculator.$inject = [];
-
- function MusicCalculator() {
- var MusicCalculator;
-
- MusicCalculator = function (a4Frequency) {
- this.$$a4Frequency = a4Frequency
- ? a4Frequency
- : MusicCalculator.A4_FREQUENCY_DEFAULT;
- };
-
- MusicCalculator.C4_A4_DELTA = 9; // semitoneNumber = 0 means middle C (C4)
- MusicCalculator.A4_FREQUENCY_DEFAULT = 440;
- MusicCalculator.SEMITONE_PER_OCTAVE = 12;
- MusicCalculator.OCTAVE_MIN = 0;
- MusicCalculator.OCTAVE_HOLDING_A4 = 4;
- MusicCalculator.OCTAVE_MAX = 10;
- MusicCalculator.NOTE_NAME_LIST = [
- 'C', // white key
- 'C#', // black key
- 'D', // white key
- 'D#', // black key
- 'E', // white key
- 'F', // white key
- 'F#', // black key
- 'G', // white key
- 'G#', // black key
- 'A', // white key
- 'A#', // black key
- 'B' // white key
- ];
-
- MusicCalculator.prototype.getSemitoneNumber = function (frequency) {
- var
- logBase2,
- semitoneNumber;
-
- if (frequency <= 0) {
- return null; // TODO throw exception
- }
-
- logBase2 = Math.log(frequency / this.$$a4Frequency) / Math.log(2);
- semitoneNumber = Math.round(
- MusicCalculator.SEMITONE_PER_OCTAVE * logBase2 + MusicCalculator.C4_A4_DELTA
- );
-
- MusicCalculator.$$checkSemitoneNumberRange(semitoneNumber);
-
- return semitoneNumber;
- };
-
- MusicCalculator.prototype.getFrequency = function (semitoneNumber) {
- var
- semitoneNumberA4based,
- exponent;
-
- MusicCalculator.$$checkSemitoneNumberRange(semitoneNumber);
-
- semitoneNumberA4based = semitoneNumber - MusicCalculator.C4_A4_DELTA;
- exponent = semitoneNumberA4based / MusicCalculator.SEMITONE_PER_OCTAVE;
-
- return this.$$a4Frequency * Math.pow(2, exponent);
- };
-
- MusicCalculator.prototype.getNoteName = function (semitoneNumber) {
- // alias of static method
- return MusicCalculator.getNoteName(semitoneNumber);
- };
-
- MusicCalculator.getNoteName = function (semitoneNumber) {
- var
- semitoneNumberC4,
- semitoneNumberC0Based,
- octaveNumber,
- semitoneIndexInOctave;
-
- MusicCalculator.$$checkSemitoneNumberRange(semitoneNumber);
-
- semitoneNumberC4 = MusicCalculator.OCTAVE_HOLDING_A4 * MusicCalculator.SEMITONE_PER_OCTAVE;
- semitoneNumberC0Based = semitoneNumberC4 + semitoneNumber;
- octaveNumber = Math.floor(semitoneNumberC0Based / MusicCalculator.SEMITONE_PER_OCTAVE);
- semitoneIndexInOctave = semitoneNumberC0Based % MusicCalculator.SEMITONE_PER_OCTAVE;
-
- return MusicCalculator.NOTE_NAME_LIST[semitoneIndexInOctave] + octaveNumber;
- };
-
- MusicCalculator.prototype.getFirstSemitoneNumber = function (semitoneNumber) {
- // alias of static method
- return MusicCalculator.getFirstSemitoneNumber(semitoneNumber);
- };
-
- MusicCalculator.getFirstSemitoneNumber = function (octaveNumber) {
- var octaveNumber4Based;
-
- if (octaveNumber < 0) {
- return null; // TODO throw exception
- }
-
- octaveNumber4Based = octaveNumber - MusicCalculator.OCTAVE_HOLDING_A4;
-
- return octaveNumber4Based * MusicCalculator.SEMITONE_PER_OCTAVE;
- };
-
- MusicCalculator.$$checkSemitoneNumberRange = function (semitoneNumber) {
- // TODO check range and throw exception if needed
- };
-
- return MusicCalculator;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.Util.SmartTimer', SmartTimer);
-
- SmartTimer.$inject = [];
-
- function SmartTimer() {
- var SmartTimer;
-
- SmartTimer = function (interval) {
- this.$$interval = null;
- this.$$intervalCounter = null;
- this.$$timeRefference = null;
- this.$$timeoutId = null;
- this.$$listener = undefined;
-
- this.setInterval(interval);
- };
-
- SmartTimer.$$_MILISECOND_IN_SECOND = 1000;
-
- SmartTimer.$$isFunction = function (variable) {
- return typeof variable === 'function';
- };
-
- SmartTimer.prototype.setInterval = function (interval) {
- if (this.$$timeoutId !== null) {
- clearTimeout(this.$$timeoutId);
- }
- this.$$interval = interval;
- this.$$intervalCounter = 0;
- this.$$timeRefference = new Date();
- this.$$scheduleNext();
- };
-
- SmartTimer.prototype.setListener = function (listener) {
- if (SmartTimer.$$isFunction(listener)) {
- this.$$listener = listener.bind(listener);
- } else {
- this.$$listener = null;
- }
- };
-
- SmartTimer.prototype.$$scheduleNext = function () {
- var
- scheduleDate = new Date(this.$$timeRefference),
- now = new Date(),
- millisecondsToAdd,
- difference;
-
- this.$$intervalCounter++;
- millisecondsToAdd = SmartTimer.$$_MILISECOND_IN_SECOND * this.$$interval * this.$$intervalCounter;
- scheduleDate.setMilliseconds(
- scheduleDate.getMilliseconds() + millisecondsToAdd
- );
- difference = scheduleDate.getTime() - now.getTime();
-
- this.$$timeoutId = setTimeout(
- this.$$notifyListener.bind(this),
- difference
- );
- };
-
- SmartTimer.prototype.$$notifyListener = function () {
- if (this.$$listener) {
- this.$$listener();
- }
- this.$$scheduleNext();
- };
-
- return SmartTimer;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-// This file is inspirated by 'Recorderjs' developed by Matt Diamond
-// https://github.com/mattdiamond/Recorderjs
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.Util.WavAudioFile', WavAudioFile);
-
- WavAudioFile.$inject = [];
-
- function WavAudioFile() {
- var WavAudioFile;
-
- WavAudioFile = function () {
- };
-
- WavAudioFile.$$_MONO_CHANNEL_COUNT = 1;
-
- WavAudioFile.$$writeString = function (dataView, offset, string) {
- var i;
-
- for (i = 0; i < string.length; i++) {
- dataView.setUint8(offset + i, string.charCodeAt(i));
- }
- };
-
- WavAudioFile.$$clipToUnit = function (value) {
- value = value < -1 ? -1 : value;
- value = value > 1 ? 1 : value;
-
- return value;
- };
-
- WavAudioFile.$$floatTo16BitPCM = function (output, offset, input) {
- var i, sample, sampleInt16;
-
- for (i = 0; i < input.length; i++) {
- sample = WavAudioFile.$$clipToUnit(input[i]);
- sampleInt16 = sample < 0
- ? sample * 0x8000
- : sample * 0x7FFF;
- output.setInt16(offset, sampleInt16, true);
- offset += 2;
- }
- };
-
- WavAudioFile.$$getObjectUrl = function (blob) {
- return (window.URL || window.webkitURL).createObjectURL(blob);
- };
-
- WavAudioFile.$$pad = function (number, size) {
- var s = '000000' + number;
-
- return s.substr(s.length - size);
- };
-
- WavAudioFile.getFilename = function () {
- var
- now = new Date(),
- filename;
-
- filename = '' +
- now.getFullYear() + '' +
- WavAudioFile.$$pad(now.getMonth() + 1, 2) + '' +
- WavAudioFile.$$pad(now.getDate(), 2) + '_' +
- WavAudioFile.$$pad(now.getHours(), 2) + '' +
- WavAudioFile.$$pad(now.getMinutes(), 2) + '' +
- WavAudioFile.$$pad(now.getSeconds(), 2) + '_' +
- WavAudioFile.$$pad(now.getMilliseconds(), 3) + '.wav';
-
- return filename;
- };
-
- WavAudioFile.getBlobUrl = function (buffer, sampleRate) {
- var
- arrayBuffer = new ArrayBuffer(44 + buffer.length * 2),
- dataView = new DataView(arrayBuffer),
- audioBlob;
-
- // RIFF identifier
- WavAudioFile.$$writeString(dataView, 0, 'RIFF');
- // RIFF chunk length
- dataView.setUint32(4, 36 + buffer.length * 2, true);
- // RIFF type
- WavAudioFile.$$writeString(dataView, 8, 'WAVE');
- // format chunk identifier
- WavAudioFile.$$writeString(dataView, 12, 'fmt ');
- // format chunk length
- dataView.setUint32(16, 16, true);
- // sample format (raw)
- dataView.setUint16(20, 1, true);
- // channel count
- dataView.setUint16(22, WavAudioFile.$$_MONO_CHANNEL_COUNT, true);
- // sample rate
- dataView.setUint32(24, sampleRate, true);
- // byte rate (sample rate * block align)
- dataView.setUint32(28, sampleRate * 4, true);
- // block align (channel count * bytes per sample)
- dataView.setUint16(32, WavAudioFile.$$_MONO_CHANNEL_COUNT * 2, true);
- // bits per sample
- dataView.setUint16(34, 16, true);
- // data chunk identifier
- WavAudioFile.$$writeString(dataView, 36, 'data');
- // data chunk length
- dataView.setUint32(40, buffer.length * 2, true);
-
- WavAudioFile.$$floatTo16BitPCM(dataView, 44, buffer);
-
- audioBlob = new Blob(
- [dataView],
- {type: 'audio/wav'}
- );
-
- return WavAudioFile.$$getObjectUrl(audioBlob);
- };
-
- return WavAudioFile;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-/**
- * Lite version of AudioMonoIO class. It wraps ScriptProcessorNode
- * only in order to provide RAW samples. So far only for mobile
- * device testing purposes.
- */
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.WebAudio.AudioMonoIOLite', AudioMonoIOLite);
-
- AudioMonoIOLite.$inject = [];
-
- function AudioMonoIOLite() {
- var AudioMonoIOLite;
-
- AudioMonoIOLite = function (bufferSize) {
- this.$$audioContext = null;
- this.$$microphone = null;
- this.$$microphoneVirtual = null;
- this.$$sampleInProcessor = null; // loopback was not working when we had one ScriptProcessor for IN and OUT
- this.$$sampleOutProcessor = null;
- this.$$volume = null;
-
- this.$$bufferSize = AudioMonoIOLite.$$getValueOrDefault(
- bufferSize,
- AudioMonoIOLite.BUFFER_SIZE
- );
- this.$$loopback = false;
- this.$$sampleInHandler = null;
- this.$$sampleOutHandler = null;
-
- this.$$initialize();
- };
-
- AudioMonoIOLite.$$firstInstance = true;
-
- AudioMonoIOLite.$$_MONO = 1;
- AudioMonoIOLite.$$_MONO_INDEX = 0;
- AudioMonoIOLite.$$_NO_CHANNEL = 0;
-
- AudioMonoIOLite.BUFFER_SIZE = 4 * 1024;
-
- AudioMonoIOLite.prototype.$$initialize = function () {
- this.$$normalizeBrowserApi();
- this.$$audioContext = this.$$createAudioContext();
- this.$$microphoneVirtual = this.$$audioContext.createGain();
- this.$$volume = this.$$audioContext.createGain();
- this.$$volume.connect(this.$$audioContext.destination);
- };
-
- AudioMonoIOLite.prototype.$$normalizeBrowserApi = function () {
- if (AudioMonoIOLite.$$firstInstance) {
- this.$$crossBrowserAudioContext();
- this.$$crossBrowserMediaDevices();
- AudioMonoIOLite.$$firstInstance = false;
- }
- };
-
- AudioMonoIOLite.prototype.$$crossBrowserAudioContext = function () {
- window.AudioContext =
- window.AudioContext ||
- window.webkitAudioContext ||
- window.mozAudioContext;
- };
-
- AudioMonoIOLite.prototype.$$crossBrowserMediaDevices = function () {
- var getUserMedia;
-
- // Code based on:
- // https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
-
- if (navigator.mediaDevices === undefined) {
- navigator.mediaDevices = {};
- }
- if (navigator.mediaDevices.getUserMedia === undefined) {
- navigator.mediaDevices.getUserMedia = function (constraints) {
- getUserMedia =
- navigator.getUserMedia ||
- navigator.webkitGetUserMedia ||
- navigator.mozGetUserMedia;
-
- if (!getUserMedia) {
- return Promise.reject(
- new Error('getUserMedia is not implemented in this browser')
- );
- }
-
- return new Promise(function (resolve, reject) {
- getUserMedia.call(navigator, constraints, resolve, reject);
- });
- }
- }
- };
-
- AudioMonoIOLite.prototype.$$logAndRethrow = function (error, message) {
- alert(message);
- console.log(error);
- throw error;
- };
-
- AudioMonoIOLite.prototype.$$createAudioContext = function () {
- var audioContext;
-
- try {
- audioContext = new window.AudioContext();
- } catch (error) {
- this.$$logAndRethrow(error, 'AudioContext creation failed');
- }
-
- return audioContext;
- };
-
- AudioMonoIOLite.prototype.$$connectMicrophoneTo = function (node) {
- var
- self = this,
- constraints = { // TODO investigate more on this
- video: false,
- audio: true
- };
-
- navigator.mediaDevices.getUserMedia(constraints)
- .then(function (stream) {
- self.$$microphone = self.$$audioContext.createMediaStreamSource(stream);
- self.$$microphone.connect(node);
- })
- .catch(function (error) {
- self.$$logAndRethrow(error, 'Microphone initialization failed');
- });
- };
-
- AudioMonoIOLite.prototype.$$onAudioProcessInHandler = function (audioProcessingEvent) {
- var monoDataIn;
-
- if (AudioMonoIOLite.$$isFunction(this.$$sampleInHandler)) {
- monoDataIn = audioProcessingEvent
- .inputBuffer
- .getChannelData(AudioMonoIOLite.$$_MONO_INDEX);
- this.$$sampleInHandler(monoDataIn);
- }
- };
-
- AudioMonoIOLite.prototype.$$onAudioProcessOutHandler = function (audioProcessingEvent) {
- var monoDataOut;
-
- if (AudioMonoIOLite.$$isFunction(this.$$sampleOutHandler)) {
- monoDataOut = audioProcessingEvent
- .outputBuffer
- .getChannelData(AudioMonoIOLite.$$_MONO_INDEX);
- this.$$sampleOutHandler(monoDataOut);
- }
- };
-
- AudioMonoIOLite.$$isFunction = function (variable) {
- return typeof variable === 'function';
- };
-
- AudioMonoIOLite.$$getValueOrDefault = function (value, defaultValue) {
- return typeof value !== 'undefined' ? value : defaultValue;
- };
-
- AudioMonoIOLite.prototype.$$setImmediately = function (audioParam, value) {
- var now = this.$$audioContext.currentTime;
-
- audioParam.value = value;
- audioParam.setValueAtTime(value, now);
- };
-
- AudioMonoIOLite.prototype.setLoopback = function (state) {
- if (this.$$loopback === !!state) {
- return;
- }
-
- this.$$lazyLoadSampleInProcessor();
-
- if (this.$$loopback) {
- this.$$volume.disconnect(this.$$sampleInProcessor);
- this.$$volume.connect(this.$$audioContext.destination);
- this.$$microphoneVirtual.connect(this.$$sampleInProcessor);
- } else {
- this.$$microphoneVirtual.disconnect(this.$$sampleInProcessor);
- this.$$volume.disconnect(this.$$audioContext.destination);
- this.$$volume.connect(this.$$sampleInProcessor);
- }
-
- this.$$loopback = !!state;
- };
-
- AudioMonoIOLite.prototype.setVolume = function (volume) {
- this.$$setImmediately(this.$$volume.gain, volume);
- };
-
- AudioMonoIOLite.prototype.$$lazyLoadSampleInProcessor = function () {
- if (this.$$sampleInProcessor) {
- return;
- }
-
- this.$$sampleInProcessor = this.$$audioContext.createScriptProcessor(
- this.$$bufferSize,
- AudioMonoIOLite.$$_MONO,
- AudioMonoIOLite.$$_MONO // required because of Chrome bug - should be set to zero
- );
- this.$$sampleInProcessor.onaudioprocess = this.$$onAudioProcessInHandler.bind(this);
- this.$$sampleInProcessor.connect(this.$$audioContext.destination); // required in Chrome
- this.$$microphoneVirtual.connect(this.$$sampleInProcessor);
- this.$$connectMicrophoneTo(this.$$microphoneVirtual);
- };
-
- AudioMonoIOLite.prototype.$$lazyLoadSampleOutProcessor = function () {
- if (this.$$sampleOutProcessor) {
- return;
- }
-
- this.$$sampleOutProcessor = this.$$audioContext.createScriptProcessor(
- this.$$bufferSize,
- AudioMonoIOLite.$$_NO_CHANNEL,
- AudioMonoIOLite.$$_MONO
- );
- this.$$sampleOutProcessor.onaudioprocess = this.$$onAudioProcessOutHandler.bind(this);
- this.$$sampleOutProcessor.connect(this.$$volume);
- };
-
- AudioMonoIOLite.prototype.setSampleInHandler = function (callback) {
- if (AudioMonoIOLite.$$isFunction(callback)) {
- this.$$lazyLoadSampleInProcessor();
- this.$$sampleInHandler = callback.bind(callback);
- } else {
- this.$$sampleInHandler = null;
- }
- };
-
- AudioMonoIOLite.prototype.setSampleOutHandler = function (callback) {
- if (AudioMonoIOLite.$$isFunction(callback)) {
- this.$$lazyLoadSampleOutProcessor();
- this.$$sampleOutHandler = callback.bind(callback);
- } else {
- this.$$sampleOutHandler = null;
- }
- };
-
- AudioMonoIOLite.prototype.getSampleRate = function () {
- return this.$$audioContext.sampleRate;
- };
-
- return AudioMonoIOLite;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-// TODO: [bug] loopback is not working on Firefox
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.WebAudio.AudioMonoIO', AudioMonoIO);
-
- AudioMonoIO.$inject = [];
-
- function AudioMonoIO() {
- var AudioMonoIO;
-
- AudioMonoIO = function (fftSize, bufferSize, smoothingTimeConstant) {
- this.$$audioContext = null;
- this.$$microphoneStream = null;
- this.$$microphone = null;
- this.$$microphoneVirtual = null;
- this.$$masterIn = null;
- this.$$masterOut = null;
- this.$$masterOutVolume = null;
-
- this.$$sampleProcessor = null; // TODO fix it: loopback is not working when we have one ScriptProcessor for IN and OUT
-
- this.$$inAnalyzer = null;
- this.$$outOscillator = null;
- this.$$outOscillatorGain = null;
-
- this.$$fftSize = AudioMonoIO.$$getValueOrDefault(
- fftSize,
- AudioMonoIO.FFT_SIZE
- );
- this.$$bufferSize = AudioMonoIO.$$getValueOrDefault(
- bufferSize,
- AudioMonoIO.BUFFER_SIZE
- );
- this.$$smoothingTimeConstant = AudioMonoIO.$$getValueOrDefault(
- smoothingTimeConstant,
- AudioMonoIO.SMOOTHING_TIME_CONSTANT
- );
-
- this.$$sampleInHandler = null;
- this.$$sampleOutHandler = null;
-
- this.$$loopbackEnabled = false;
-
- this.$$initialize();
- };
-
- AudioMonoIO.$$firstInstance = true;
-
- AudioMonoIO.$$_MONO = 1;
- AudioMonoIO.$$_MONO_INDEX = 0;
-
- // default values for setPeriodicWave method
- AudioMonoIO.$$_OUTPUT_WAVE_FREQUENCY = 0;
- AudioMonoIO.$$_OUTPUT_WAVE_VOLUME = 1;
- AudioMonoIO.$$_OUTPUT_WAVE_PHASE = 0;
- AudioMonoIO.$$_OUTPUT_WAVE_HARMONIC_AMPLITUDE = [ 1 ];
- AudioMonoIO.$$_OUTPUT_WAVE_HARMONIC_PHASE = [ 0 ];
-
- // default values for AudioMonoIO class constructor
- AudioMonoIO.FFT_SIZE = 2 * 1024;
- AudioMonoIO.BUFFER_SIZE = 4 * 1024;
- AudioMonoIO.SMOOTHING_TIME_CONSTANT = 0;
-
- AudioMonoIO.START_TIME_NEEDS_TO_GREATER_THAN_END_TIME_EXCEPTION = 'Start time needs to greater than end time';
-
- AudioMonoIO.prototype.$$normalizeBrowserApi = function () {
- if (AudioMonoIO.$$firstInstance) {
- this.$$crossBrowserAudioContext();
- this.$$crossBrowserMediaDevices();
- AudioMonoIO.$$firstInstance = false;
- }
- };
-
- AudioMonoIO.prototype.$$initialize = function () {
- this.$$normalizeBrowserApi();
- this.$$audioContext = this.$$createAudioContext();
-
- this.$$initializeCommon();
- this.$$initializeInput();
- this.$$initializeOutput();
-
- this.$$sourceAttach();
- this.$$masterOutVolume.connect(this.$$audioContext.destination);
- };
-
- AudioMonoIO.prototype.$$sourceDetach = function () {
- if (!this.$$loopbackEnabled) {
- this.$$microphoneVirtual.disconnect(this.$$masterIn);
- } else {
- this.$$masterOut.disconnect(this.$$masterIn);
- }
- };
-
- AudioMonoIO.prototype.$$sourceAttach = function () {
- if (!this.$$loopbackEnabled) {
- this.$$microphoneVirtual.connect(this.$$masterIn);
- } else {
- this.$$masterOut.connect(this.$$masterIn);
- }
- };
-
- AudioMonoIO.prototype.$$initializeCommon = function () {
- this.$$microphoneVirtual = this.$$audioContext.createGain();
- this.$$connectMicrophoneTo(this.$$microphoneVirtual);
-
- this.$$masterIn = this.$$audioContext.createGain();
- this.$$masterOut = this.$$audioContext.createGain();
- this.$$masterOutVolume = this.$$audioContext.createGain();
-
- this.$$sampleProcessor = this.$$audioContext.createScriptProcessor(
- this.$$bufferSize,
- AudioMonoIO.$$_MONO,
- AudioMonoIO.$$_MONO
- );
- this.$$sampleProcessor.onaudioprocess = this.$$onAudioProcessHandler.bind(this);
-
- this.$$masterIn.connect(this.$$sampleProcessor);
- this.$$sampleProcessor.connect(this.$$masterOut);
- this.$$masterOut.connect(this.$$masterOutVolume);
- };
-
- AudioMonoIO.prototype.$$initializeInput = function () {
- this.$$inAnalyzer = this.$$audioContext.createAnalyser();
-
- this.setFFTSize(this.$$fftSize);
- this.setSmoothingTimeConstant(this.$$smoothingTimeConstant);
-
- this.$$masterIn.connect(this.$$inAnalyzer);
- };
-
- AudioMonoIO.prototype.$$initializeOutput = function () {
- this.$$outOscillator = this.$$audioContext.createOscillator();
- this.$$outOscillatorGain = this.$$audioContext.createGain();
-
- this.setPeriodicWave(
- AudioMonoIO.$$_OUTPUT_WAVE_FREQUENCY,
- AudioMonoIO.$$_OUTPUT_WAVE_VOLUME,
- AudioMonoIO.$$_OUTPUT_WAVE_PHASE,
- AudioMonoIO.$$_OUTPUT_WAVE_HARMONIC_AMPLITUDE,
- AudioMonoIO.$$_OUTPUT_WAVE_HARMONIC_PHASE
- );
- this.$$outOscillator.start();
-
- this.$$outOscillator.connect(this.$$outOscillatorGain);
- this.$$outOscillatorGain.connect(this.$$masterOut);
- };
-
- AudioMonoIO.prototype.$$crossBrowserAudioContext = function () {
- window.AudioContext =
- window.AudioContext ||
- window.webkitAudioContext ||
- window.mozAudioContext;
- };
-
- AudioMonoIO.prototype.$$crossBrowserMediaDevices = function () {
- var getUserMedia;
-
- // Code based on:
- // https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
-
- if (navigator.mediaDevices === undefined) {
- navigator.mediaDevices = {};
- }
- if (navigator.mediaDevices.getUserMedia === undefined) {
- navigator.mediaDevices.getUserMedia = function (constraints) {
- getUserMedia =
- navigator.getUserMedia ||
- navigator.webkitGetUserMedia ||
- navigator.mozGetUserMedia;
-
- if (!getUserMedia) {
- return Promise.reject(
- new Error('getUserMedia is not implemented in this browser')
- );
- }
-
- return new Promise(function (resolve, reject) {
- getUserMedia.call(navigator, constraints, resolve, reject);
- });
- }
- }
- };
-
- AudioMonoIO.prototype.$$logAndRethrow = function (error, message) {
- alert(message);
- console.log(error);
- throw error;
- };
-
- AudioMonoIO.prototype.$$createAudioContext = function () {
- var audioContext;
-
- try {
- audioContext = new window.AudioContext();
- } catch (error) {
- this.$$logAndRethrow(error, 'AudioContext creation failed');
- }
-
- return audioContext;
- };
-
- AudioMonoIO.prototype.$$connectMicrophoneTo = function (node) {
- var
- self = this,
- constraints = { // TODO investigate more on this
- video: false,
- audio: true/*{
- // channelCount: 1,
- // sampleRate: 44100,
- echoCancellation: true
-
- // mandatory: {},
- optional: {
- googEchoCancellation: false, // disabling audio processing
- googAutoGainControl: false,
- googNoiseSuppression: false,
- googHighpassFilter: false
- }
-
- }*/
- };
-
- /*
- console.log(
- navigator.mediaDevices.getSupportedConstraints()
- );
- */
-
- navigator.mediaDevices.getUserMedia(constraints)
- .then(function (stream) {
- self.$$microphoneStream = stream;
- self.$$microphone = self.$$audioContext.createMediaStreamSource(stream);
- self.$$microphone.connect(node);
- })
- .catch(function (error) {
- self.$$logAndRethrow(error, 'Microphone initialization failed');
- });
- };
-
- AudioMonoIO.prototype.$$onAudioProcessHandler = function (audioProcessingEvent) {
- var monoDataIn, monoDataOut;
-
- monoDataIn = audioProcessingEvent.inputBuffer.getChannelData(AudioMonoIO.$$_MONO_INDEX);
- monoDataOut = audioProcessingEvent.outputBuffer.getChannelData(AudioMonoIO.$$_MONO_INDEX);
-
- if (AudioMonoIO.$$isFunction(this.$$sampleInHandler)) {
- this.$$sampleInHandler(monoDataIn);
- }
-
- if (AudioMonoIO.$$isFunction(this.$$sampleOutHandler)) {
- this.$$sampleOutHandler(monoDataOut, monoDataIn);
- }
- };
-
- AudioMonoIO.prototype.$$setLinearly = function (audioParam, value, relativeStartTime, relativeEndTime) {
- var now = this.$$audioContext.currentTime;
-
- if (relativeStartTime >= relativeEndTime) {
- throw AudioMonoIO.START_TIME_NEEDS_TO_GREATER_THAN_END_TIME_EXCEPTION;
- }
-
- audioParam.setValueAtTime(audioParam.value, now + relativeStartTime);
- audioParam.linearRampToValueAtTime(
- value,
- now + relativeEndTime
- );
- };
-
- AudioMonoIO.prototype.$$setImmediately = function (audioParam, value) {
- var now = this.$$audioContext.currentTime;
-
- audioParam.value = value;
- audioParam.setValueAtTime(value, now);
- };
-
- AudioMonoIO.$$isFunction = function (variable) {
- return typeof variable === 'function';
- };
-
- AudioMonoIO.$$getValueOrDefault = function (value, defaultValue) {
- return typeof value !== 'undefined' ? value : defaultValue;
- };
-
- AudioMonoIO.prototype.microphoneDisable = function () {
- var tracks;
-
- // NOTE: experimental feature
- if (this.$$microphone) {
- this.$$microphone.disconnect(this.$$microphoneVirtual);
- this.$$microphone = null;
- if (this.$$microphoneStream && (typeof this.$$microphoneStream.getTracks === 'function')) {
- tracks = this.$$microphoneStream.getTracks();
- if (tracks && tracks.length > 0) {
- if (typeof tracks[0].stop === 'function') {
- tracks[0].stop();
- this.$$microphoneStream = null;
- }
- }
- }
- }
- };
-
- AudioMonoIO.prototype.microphoneEnable = function () {
- // NOTE: experimental feature
- this.$$connectMicrophoneTo(this.$$microphoneVirtual);
- };
-
- AudioMonoIO.prototype.setVolume = function (volume) {
- this.$$setImmediately(this.$$masterOutVolume.gain, volume);
- };
-
- AudioMonoIO.prototype.isLoopbackEnabled = function () {
- return this.$$loopbackEnabled;
- };
-
- AudioMonoIO.prototype.setLoopback = function (state) {
- state = !!state;
-
- if (this.$$loopbackEnabled === state) {
- return false;
- }
-
- this.$$sourceDetach();
- this.$$loopbackEnabled = state;
- this.$$sourceAttach();
-
- return true;
- };
-
- AudioMonoIO.prototype.setPeriodicWaveFading = function (value, relativeStartTime, relativeEndTime) {
- this.$$setLinearly(this.$$outOscillatorGain.gain, value, relativeStartTime, relativeEndTime);
- };
-
- AudioMonoIO.prototype.setPeriodicWave = function (frequency, volume, phase, harmonicAmplitude, harmonicPhase) {
- var periodicWave, isPureSine;
-
- isPureSine = typeof phase === 'undefined' &&
- typeof harmonicAmplitude === 'undefined' &&
- typeof harmonicPhase === 'undefined';
-
- frequency = AudioMonoIO.$$getValueOrDefault(
- frequency, AudioMonoIO.$$_OUTPUT_WAVE_FREQUENCY
- );
- volume = AudioMonoIO.$$getValueOrDefault(
- volume, AudioMonoIO.$$_OUTPUT_WAVE_VOLUME
- );
-
- if (volume || volume === 0) {
- this.$$setImmediately(this.$$outOscillatorGain.gain, volume);
- }
- if (frequency || frequency === 0) {
- this.$$setImmediately(this.$$outOscillator.frequency, frequency);
- }
-
- if (isPureSine) {
- this.$$outOscillator.type = 'sine';
- } else {
- phase = AudioMonoIO.$$getValueOrDefault(
- phase, AudioMonoIO.$$_OUTPUT_WAVE_PHASE
- );
- harmonicAmplitude = AudioMonoIO.$$getValueOrDefault(
- harmonicAmplitude, AudioMonoIO.$$_OUTPUT_WAVE_HARMONIC_AMPLITUDE
- );
- harmonicPhase = AudioMonoIO.$$getValueOrDefault(
- harmonicPhase, AudioMonoIO.$$_OUTPUT_WAVE_HARMONIC_PHASE
- );
-
- periodicWave = this.$$getPeriodicWave(
- phase,
- harmonicAmplitude,
- harmonicPhase
- );
- this.$$outOscillator.setPeriodicWave(periodicWave);
- }
- };
-
- AudioMonoIO.prototype.$$getPeriodicWave = function (phase, harmonicAmplitude, harmonicPhase) {
- var
- real,
- imag,
- harmonicNumber,
- i,
- phaseRadianGlobal,
- phaseRadianLocal,
- finalRadian;
-
- if (harmonicAmplitude.length !== harmonicPhase.length) {
- throw 'Length of amplitude and phase arrays should match';
- }
- if (harmonicAmplitude.length < 1) {
- throw 'Amplitude and phase arrays should have at least one item';
- }
-
- real = new Float32Array(1 + harmonicAmplitude.length);
- imag = new Float32Array(1 + harmonicAmplitude.length);
- phaseRadianGlobal = 2 * Math.PI * (-phase);
- real[0] = 0; // DC-offset is always zero
- imag[0] = 0;
- for (i = 0; i < harmonicAmplitude.length; i++) {
- harmonicNumber = 1 + i;
- phaseRadianLocal = 2 * Math.PI * (-harmonicPhase[i]);
- finalRadian = phaseRadianGlobal * harmonicNumber + phaseRadianLocal;
- real[harmonicNumber] = harmonicAmplitude[i] * Math.sin(finalRadian);
- imag[harmonicNumber] = harmonicAmplitude[i] * Math.cos(finalRadian);
- }
-
- return this.$$audioContext.createPeriodicWave(real, imag);
- };
-
- AudioMonoIO.prototype.setSampleInHandler = function (callback) {
- if (AudioMonoIO.$$isFunction(callback)) {
- this.$$sampleInHandler = callback.bind(callback);
- } else {
- this.$$sampleInHandler = null;
- }
- };
-
- AudioMonoIO.prototype.setSampleOutHandler = function (callback) {
- if (AudioMonoIO.$$isFunction(callback)) {
- this.$$sampleOutHandler = callback.bind(callback);
- } else {
- this.$$sampleOutHandler = null;
- }
- };
-
- AudioMonoIO.prototype.setFFTSize = function (fftSize) {
- this.$$fftSize = fftSize;
- if (this.$$inAnalyzer.fftSize !== this.$$fftSize) {
- this.$$inAnalyzer.fftSize = this.$$fftSize;
- }
- };
-
- AudioMonoIO.prototype.getFFTSize = function () {
- return this.$$fftSize;
- };
-
- AudioMonoIO.prototype.setSmoothingTimeConstant = function (smoothingTimeConstant) {
- this.$$smoothingTimeConstant = smoothingTimeConstant;
- if (this.$$inAnalyzer.smoothingTimeConstant !== this.$$smoothingTimeConstant) {
- this.$$inAnalyzer.smoothingTimeConstant = this.$$smoothingTimeConstant;
- }
- };
-
- AudioMonoIO.prototype.getFrequencyData = function () {
- var data;
-
- data = new Float32Array(this.$$inAnalyzer.frequencyBinCount); // same as: 0.5 * fftSize
- this.$$inAnalyzer.getFloatFrequencyData(data);
-
- return data;
- };
-
- AudioMonoIO.prototype.getTimeDomainData = function () {
- var data;
-
- data = new Float32Array(this.$$inAnalyzer.fftSize);
- this.$$inAnalyzer.getFloatTimeDomainData(data);
-
- return data;
- };
-
- AudioMonoIO.prototype.getSampleRate = function () {
- return this.$$audioContext.sampleRate;
- };
-
- AudioMonoIO.prototype.getFFTResolution = function () {
- return this.getSampleRate() / audioMonoIO.getFFTSize()
- };
-
- return AudioMonoIO;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayer.ConfigurationParser', _ConfigurationParser);
-
- _ConfigurationParser.$inject = [
- 'Common.MathUtil',
- 'Common.Util',
- 'PhysicalLayer.DefaultConfig'
- ];
-
- function _ConfigurationParser(
- MathUtil,
- Util,
- DefaultConfig
- ) {
-
- function parseChannel(configuration, txRx) {
- var i, txChannel, result, channelDataExists, channelListSize;
-
- result = [];
- txChannel = Util.accessor(configuration, txRx + '.channel');
- channelDataExists = txChannel ? true : false;
- txChannel = txChannel ? txChannel : [];
- channelListSize = txChannel.length;
-
- for (i = 0; i < (channelDataExists ? channelListSize : 2); i++) {
- result.push({
- baseFrequency: (
- Util.accessor(txChannel[i], 'baseFrequency') ||
- (i % 2 === 0 ? DefaultConfig.CHANNEL_1_FREQUENCY : DefaultConfig.CHANNEL_2_FREQUENCY)
- ),
- ofdmSize: Util.accessor(txChannel[i], 'ofdmSize') || DefaultConfig.OFDM_SIZE,
- ofdmFrequencySpacing: (
- Util.accessor(txChannel[i], 'ofdmFrequencySpacing') || DefaultConfig.OFDM_FREQUENCY_SPACING
- )
- });
- }
-
- return result;
- }
-
- function parse(configuration) {
- var
- c = configuration,
- a = Util.accessor,
- finalConfiguration
- ;
-
- finalConfiguration = {
- tx: {
- bufferSize: c && c.tx && (typeof c.tx.bufferSize !== 'undefined') ? c.tx.bufferSize : 0,
- channel: parseChannel(c, 'tx')
- },
- rx: {
- bufferSize: c && c.rx && (typeof c.rx.bufferSize !== 'undefined') ? c.rx.bufferSize : 0,
- channel: parseChannel(c, 'rx'),
- input: a(c, 'rx.input') || DefaultConfig.RX_INPUT,
- notificationPerSecond: a(c, 'rx.notificationPerSecond') || DefaultConfig.RX_NOTIFICATION_PER_SECOND,
- dftWindowTime: a(c, 'rx.dftWindowTime') || DefaultConfig.RX_DFT_WINDOW_TIME,
- spectrum: {
- elementId: a(c, 'rx.spectrum.elementId') || null,
- color: {
- axis: a(c, 'rx.spectrum.color.axis') || '#444',
- data: a(c, 'rx.spectrum.color.data') || '#888888'
- },
- fftSize: a(c, 'rx.spectrum.fftSize') || DefaultConfig.RX_SPECTRUM_FFT_SIZE,
- height: a(c, 'rx.spectrum.height') || 200
- },
- constellationDiagram: {
- elementId: (
- a(c, 'rx.constellationDiagram.elementId') || null
- ),
- color: {
- historyPoint: {
- red: {
- newest: a(c, 'rx.constellationDiagram.color.historyPoint.red.newest') || 0,
- tailNewest: a(c, 'rx.constellationDiagram.color.historyPoint.red.tailNewest') || 100,
- tailOldest: a(c, 'rx.constellationDiagram.color.historyPoint.red.tailOldest') || 180
- },
- green: {
- newest: a(c, 'rx.constellationDiagram.color.historyPoint.green.newest') || 0,
- tailNewest: a(c, 'rx.constellationDiagram.color.historyPoint.green.tailNewest') || 100,
- tailOldest: a(c, 'rx.constellationDiagram.color.historyPoint.green.tailOldest') || 200
- },
- blue: {
- newest: a(c, 'rx.constellationDiagram.color.historyPoint.blue.newest') || 0,
- tailNewest: a(c, 'rx.constellationDiagram.color.historyPoint.blue.tailNewest') || 100,
- tailOldest: a(c, 'rx.constellationDiagram.color.historyPoint.blue.tailOldest') || 150
- }
- },
- axis: a(c, 'rx.constellationDiagram.color.axis') || 'green'
- },
- historyPointSize: MathUtil.round(a(c, 'rx.constellationDiagram.historyPointSize') || DefaultConfig.RX_HISTORY_POINT_SIZE),
- width: a(c, 'rx.constellationDiagram.width') || 200,
- height: a(c, 'rx.constellationDiagram.height') || 200
- }
- }
- };
-
- return finalConfiguration;
- }
-
- return {
- parse: parse
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayer.DefaultConfig', _DefaultConfig);
-
- _DefaultConfig.$inject = [
- 'PhysicalLayer.RxInput',
- 'Common.MathUtil'
- ];
-
- function _DefaultConfig(
- RxInput,
- MathUtil
- ) {
- var
- baud = 4,
- baudMultiplicativeInverse = 1 / baud,
- factorSymbol = 0.26,
- factorGuard = 0.74,
- factorInterpacketGap = 5,
- symbolDuration = baudMultiplicativeInverse * factorSymbol,
- rxDftWindowTime = symbolDuration,
- guardInterval = baudMultiplicativeInverse * factorGuard,
- interpacketGap = guardInterval * factorInterpacketGap,
- ofdmFrequencySpacingPositiveInteger = 2,
- ofdmFrequencySpacing = ofdmFrequencySpacingPositiveInteger / symbolDuration,
- symbolFrequency = 1 / symbolDuration,
- symbolFrequencyFactor = 2.5,
- rxNotificationPerSecond = MathUtil.round(symbolFrequencyFactor * symbolFrequency),
- rxHistoryPointSize = rxNotificationPerSecond
- ;
-
- /*
- OFDM Frequency Spacing explanation [Wikipedia]:
- "The orthogonality requires that the sub-carrier spacing is k/TU Hertz, where TU seconds
- is the useful symbol duration (the receiver side window size), and k is a positive integer,
- typically equal to 1"
-
- Channel frequencies explanation [Wikipedia]:
- "In the Bell 103 system, the originating modem sends 0s by playing a 1,070 Hz tone,
- and 1s at 1,270 Hz, with the answering modem transmitting its 0s on 2,025 Hz and
- 1s on 2,225 Hz. These frequencies were chosen carefully; they are in the range that
- suffers minimum distortion on the phone system and are not harmonics of each other."
- */
-
- return {
- CONSTELLATION_DIAGRAM_DECIBEL_LIMIT: -40,
- MINIMUM_POWER_DECIBEL: -99,
- FAKE_NOISE_MAX_AMPLITUDE: 0.001,
- CHANNEL_1_FREQUENCY: 1070,
- CHANNEL_2_FREQUENCY: 2025,
- OFDM_SIZE: 1,
- OFDM_FREQUENCY_SPACING_POSITIVE_INTEGER: ofdmFrequencySpacingPositiveInteger,
- OFDM_FREQUENCY_SPACING: ofdmFrequencySpacing,
- SYMBOL_FREQUENCY: symbolFrequency,
- SYMBOL_FREQUENCY_FACTOR: symbolFrequencyFactor,
- RX_INPUT: RxInput.MICROPHONE,
- RX_NOTIFICATION_PER_SECOND: rxNotificationPerSecond,
- RX_HISTORY_POINT_SIZE: rxHistoryPointSize,
- RX_DFT_WINDOW_TIME: rxDftWindowTime,
- RX_SPECTRUM_FFT_SIZE: 1024,
- BAUD: baud,
- BAUD_MULTIPLICATIVE_INVERSE: baudMultiplicativeInverse,
- FACTOR_SYMBOL: factorSymbol,
- FACTOR_GUARD: factorGuard,
- SYNC_DURATION: 2.0,
- SYMBOL_DURATION: symbolDuration,
- GUARD_INTERVAL: guardInterval,
- FACTOR_INTERPACKET_GAP: factorInterpacketGap,
- INTERPACKET_GAP: interpacketGap,
- PSK_SIZE: 2,
- SYNC_PREAMBLE: true
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayer.PhysicalLayer', _PhysicalLayer);
-
- _PhysicalLayer.$inject = [
- 'Common.QueueBuilder',
- 'Common.MathUtil',
- 'PhysicalLayer.DefaultConfig',
- 'PhysicalLayer.ConfigurationParser',
- 'PhysicalLayer.RxInput',
- 'PhysicalLayer.RxHandlerBuilder',
- 'PhysicalLayer.ChannelTransmitManagerBuilder',
- 'PhysicalLayer.ChannelReceiveManagerBuilder',
- 'Visualizer.ConstellationDiagramBuilder',
- 'Visualizer.AnalyserChartBuilder',
- 'Audio.ActiveAudioContext',
- 'Common.SimplePromiseBuilder'
- ];
-
- function _PhysicalLayer(
- QueueBuilder,
- MathUtil,
- DefaultConfig,
- ConfigurationParser,
- RxInput,
- RxHandlerBuilder,
- ChannelTransmitManagerBuilder,
- ChannelReceiveManagerBuilder,
- ConstellationDiagramBuilder,
- AnalyserChartBuilder,
- ActiveAudioContext,
- SimplePromiseBuilder
- ) {
- var PhysicalLayer;
-
- PhysicalLayer = function (configuration) {
- this.$$configuration = ConfigurationParser.parse(configuration);
- this.$$channelTransmitManager = null;
- this.$$channelReceiveManager = null;
- this.$$currentInput = null;
- this.$$rxAnalyser = null;
- this.$$rxAnalyserChart = null;
- this.$$rxConstellationDiagram = [];
-
- this.$$outputTx = undefined;
- this.$$outputMicrophone = undefined;
- this.$$outputRecordedAudio = undefined;
- this.$$rxExternalHandler = {
- callback: null
- };
- this.$$rxHandler = RxHandlerBuilder.build(
- this.$$rxConstellationDiagram,
- this.$$rxExternalHandler
- );
-
- this.$$initTx();
- this.$$initRx();
- this.setRxInput(this.$$configuration.rx.input);
- };
-
- PhysicalLayer.prototype.$$initTx = function () {
- this.$$channelTransmitManager = ChannelTransmitManagerBuilder.build(
- this.$$configuration.tx.channel,
- this.$$configuration.tx.bufferSize
- );
-
- this.outputTxEnable();
- this.outputMicrophoneDisable();
- this.outputRecordedAudioDisable();
- };
-
- PhysicalLayer.prototype.$$initConstellationDiagram = function (channelIndex, channel) {
- var ofdmIndex, queue, constellationDiagram, elementId;
-
- queue = [];
- constellationDiagram = [];
- for (ofdmIndex = 0; ofdmIndex < channel.ofdmSize; ofdmIndex++) {
- elementId = this.$$configuration.rx.constellationDiagram.elementId;
- elementId = elementId.replace('{{ channelIndex }}', channelIndex + '');
- elementId = elementId.replace('{{ ofdmIndex }}', ofdmIndex + '');
- if (!document.getElementById(elementId)) {
- throw 'Constellation diagram DOM element not found';
- }
-
- queue.push(
- QueueBuilder.build(this.$$configuration.rx.constellationDiagram.historyPointSize)
- );
- constellationDiagram.push(
- ConstellationDiagramBuilder.build(
- document.getElementById(elementId),
- this.$$configuration.rx.constellationDiagram.width,
- this.$$configuration.rx.constellationDiagram.height,
- queue[queue.length - 1],
- DefaultConfig.CONSTELLATION_DIAGRAM_DECIBEL_LIMIT,
- this.$$configuration.rx.constellationDiagram.color.axis,
- this.$$configuration.rx.constellationDiagram.color.historyPoint
- )
- );
- }
- this.$$rxConstellationDiagram.push({
- constellationDiagram: constellationDiagram,
- queue: queue
- });
- };
-
- PhysicalLayer.prototype.$$initRx = function () {
- var
- dftWindowSize = MathUtil.round(ActiveAudioContext.getSampleRate() * this.$$configuration.rx.dftWindowTime),
- notifyInterval = MathUtil.round(ActiveAudioContext.getSampleRate() / this.$$configuration.rx.notificationPerSecond),
- channel, i
- ;
-
- for (i = 0; i < this.$$configuration.rx.channel.length; i++) {
- channel = this.$$configuration.rx.channel[i];
-
- // attach additional fields to channel object
- channel.dftWindowSize = dftWindowSize;
- channel.notifyInterval = notifyInterval;
- channel.notifyHandler = this.$$rxHandler.handle.bind(this.$$rxHandler);
-
- if (this.$$configuration.rx.constellationDiagram.elementId) {
- this.$$initConstellationDiagram(i, channel);
- }
- }
- this.$$channelReceiveManager = ChannelReceiveManagerBuilder.build(
- this.$$configuration.rx.channel,
- this.$$configuration.rx.bufferSize
- );
-
- this.$$rxAnalyser = ActiveAudioContext.createAnalyser();
- this.$$rxAnalyser.fftSize = this.$$configuration.rx.spectrum.fftSize;
- this.$$rxAnalyser.connect(this.$$channelReceiveManager.getInputNode());
- if (this.$$configuration.rx.spectrum.elementId) {
- if (!document.getElementById(this.$$configuration.rx.spectrum.elementId)) {
- throw 'Spectrum DOM element not found';
- }
- this.$$rxAnalyserChart = AnalyserChartBuilder.build(
- document.getElementById(this.$$configuration.rx.spectrum.elementId),
- this.$$rxAnalyser,
- this.$$configuration.rx.spectrum.height,
- this.$$configuration.rx.spectrum.color.data,
- this.$$configuration.rx.spectrum.color.axis
- );
- }
- };
-
- PhysicalLayer.prototype.$$getTxInputNode = function (input) {
- var node = null;
-
- switch (input) {
- case RxInput.MICROPHONE:
- node = ActiveAudioContext.getMicrophoneNode();
- break;
- case RxInput.LOOPBACK:
- node = this.$$channelTransmitManager.getOutputNode();
- break;
- case RxInput.RECORDED_AUDIO:
- node = ActiveAudioContext.getRecordedAudioNode();
- break;
- }
-
- return node;
- };
-
- PhysicalLayer.prototype.getRxInput = function () {
- return this.$$currentInput;
- };
-
- PhysicalLayer.prototype.setRxInput = function (input) {
- var node;
-
- if (this.$$currentInput) {
- this.$$getTxInputNode(this.$$currentInput).disconnect(this.$$rxAnalyser);
- }
-
- node = this.$$getTxInputNode(input);
- if (node) {
- node.connect(this.$$rxAnalyser);
- this.$$currentInput = input;
- if (this.$$currentInput === RxInput.LOOPBACK) {
- this.$$channelTransmitManager.enableFakeNoise();
- } else {
- this.$$channelTransmitManager.disableFakeNoise();
- }
- } else {
- this.$$currentInput = null;
- }
- };
-
- PhysicalLayer.prototype.getTxBufferSize = function () {
- return this.$$channelTransmitManager.getBufferSize();
- };
-
- PhysicalLayer.prototype.getRxBufferSize = function () {
- return this.$$channelReceiveManager.getBufferSize();
- };
-
- PhysicalLayer.prototype.loadRecordedAudio = function (url) {
- return ActiveAudioContext.loadRecordedAudio(url);
- };
-
- PhysicalLayer.prototype.tx = function (channelIndex, data) {
- var
- channelTx = this.$$channelTransmitManager.getChannel(channelIndex),
- d, i, dataParsed = []
- ;
-
- if (!data) {
- throw 'Please specify data to send';
- }
-
- for (i = 0; i < data.length; i++) {
- d = data[i];
- if (!d.duration) {
- throw 'Tx - duration of all data items should be > 0';
- }
-
- dataParsed.push({
- amplitude: (typeof d.amplitude !== 'undefined') ? d.amplitude : 1,
- duration: MathUtil.round(ActiveAudioContext.getSampleRate() * d.duration),
- phase: (typeof d.phase !== 'undefined') ? d.phase : 0
- });
- }
-
- channelTx.addToQueue(dataParsed);
- };
-
- PhysicalLayer.prototype.rx = function (rxHandler) {
- this.$$rxExternalHandler.callback = (typeof rxHandler === 'function') ? rxHandler : null;
- };
-
- PhysicalLayer.prototype.getSampleRate = function () {
- return ActiveAudioContext.getSampleRate();
- };
-
- PhysicalLayer.prototype.destroy = function () {
- var i, j, promiseList = [];
-
- this.setRxInput(null);
-
- // rx
- if (this.$$rxAnalyserChart) {
- promiseList.push(this.$$rxAnalyserChart.destroy());
- this.$$rxAnalyserChart = null;
- }
- this.$$rxAnalyser.disconnect(this.$$channelReceiveManager.getInputNode());
- if (this.$$rxConstellationDiagram) {
- for (i = 0; i < this.$$rxConstellationDiagram.length; i++) {
- for (j = 0; j < this.$$rxConstellationDiagram[i].constellationDiagram.length; j++) {
- promiseList.push(
- this.$$rxConstellationDiagram[i].constellationDiagram[j].destroy()
- );
- }
- }
- }
- this.$$channelReceiveManager.destroy();
- this.$$channelReceiveManager = null;
-
- // tx
- this.outputTxDisable();
- this.outputRecordedAudioDisable();
- this.outputMicrophoneDisable();
- this.$$channelTransmitManager.destroy();
- this.$$channelTransmitManager = null;
-
- this.$$rxHandler.destroy();
-
- return SimplePromiseBuilder.buildFromList(promiseList);
- };
-
- PhysicalLayer.prototype.getOutputTxState = function () {
- return this.$$outputTx;
- };
-
- PhysicalLayer.prototype.getOutputMicrophoneState = function () {
- return this.$$outputMicrophone;
- };
-
- PhysicalLayer.prototype.getOutputRecordedAudioState = function () {
- return this.$$outputRecordedAudio;
- };
-
- PhysicalLayer.prototype.outputTxEnable = function () {
- if (!this.$$outputTx) {
- this.$$channelTransmitManager.getOutputNode().connect(ActiveAudioContext.getDestination());
- }
- this.$$outputTx = true;
- };
-
- PhysicalLayer.prototype.outputTxDisable = function () {
- if (this.$$outputTx) {
- this.$$channelTransmitManager.getOutputNode().disconnect(ActiveAudioContext.getDestination());
- }
- this.$$outputTx = false;
- };
-
- PhysicalLayer.prototype.outputMicrophoneEnable = function () {
- if (!this.$$outputMicrophone) {
- ActiveAudioContext.getMicrophoneNode().connect(ActiveAudioContext.getDestination());
- }
- this.$$outputMicrophone = true;
- };
-
- PhysicalLayer.prototype.outputMicrophoneDisable = function () {
- if (this.$$outputMicrophone) {
- ActiveAudioContext.getMicrophoneNode().disconnect(ActiveAudioContext.getDestination());
- }
- this.$$outputMicrophone = false;
- };
-
- PhysicalLayer.prototype.outputRecordedAudioEnable = function () {
- if (!this.$$outputRecordedAudio) {
- ActiveAudioContext.getRecordedAudioNode().connect(ActiveAudioContext.getDestination());
- }
- this.$$outputRecordedAudio = true;
- };
-
- PhysicalLayer.prototype.outputRecordedAudioDisable = function () {
- if (this.$$outputRecordedAudio) {
- ActiveAudioContext.getRecordedAudioNode().disconnect(ActiveAudioContext.getDestination());
- }
- this.$$outputRecordedAudio = false;
- };
-
- PhysicalLayer.prototype.getRxCpuLoadData = function () {
- return this.$$channelReceiveManager.getCpuLoadData();
- };
-
- PhysicalLayer.prototype.getTxCpuLoadData = function () {
- return this.$$channelTransmitManager.getCpuLoadData();
- };
-
- PhysicalLayer.prototype.getRxFrequency = function (channelIndex, ofdmIndex) {
- return (
- this.$$channelReceiveManager
- .getChannel(channelIndex)
- .getFrequency(ofdmIndex)
- );
- };
-
- PhysicalLayer.prototype.getTxFrequency = function (channelIndex, ofdmIndex) {
- return (
- this.$$channelTransmitManager
- .getChannel(channelIndex)
- .getFrequency(ofdmIndex)
- );
- };
-
- PhysicalLayer.prototype.setRxFrequency = function (channelIndex, ofdmIndex, frequency) {
- this.$$channelReceiveManager
- .getChannel(channelIndex)
- .setFrequency(ofdmIndex, frequency)
- ;
- };
-
- PhysicalLayer.prototype.setTxFrequency = function (channelIndex, ofdmIndex, frequency) {
- this.$$channelTransmitManager
- .getChannel(channelIndex)
- .setFrequency(ofdmIndex, frequency)
- ;
- };
-
-
- PhysicalLayer.prototype.getRxPhaseCorrection = function (channelIndex, ofdmIndex) {
- return (
- this.$$channelReceiveManager
- .getChannel(channelIndex)
- .getRxPhaseCorrection(ofdmIndex)
- );
- };
-
- PhysicalLayer.prototype.getTxPhaseCorrection = function (channelIndex, ofdmIndex) {
- return (
- this.$$channelTransmitManager
- .getChannel(channelIndex)
- .getTxPhaseCorrection(ofdmIndex)
- );
- };
-
- PhysicalLayer.prototype.setRxPhaseCorrection = function (channelIndex, ofdmIndex, phaseCorrection) {
- this.$$channelReceiveManager
- .getChannel(channelIndex)
- .setRxPhaseCorrection(ofdmIndex, phaseCorrection)
- ;
- };
-
- PhysicalLayer.prototype.setTxPhaseCorrection = function (channelIndex, ofdmIndex, phaseCorrection) {
- this.$$channelTransmitManager
- .getChannel(channelIndex)
- .setTxPhaseCorrection(ofdmIndex, phaseCorrection)
- ;
- };
-
- PhysicalLayer.prototype.getTxChannelSize = function () {
- return this.$$channelTransmitManager.getChannelSize();
- };
-
- PhysicalLayer.prototype.getRxChannelSize = function () {
- return this.$$channelReceiveManager.getChannelSize();
- };
-
- PhysicalLayer.prototype.getTxChannelOfdmSize = function (channelIndex) {
- return this.$$channelTransmitManager.getChannel(channelIndex).getOfdmSize();
- };
-
- PhysicalLayer.prototype.getRxChannelOfdmSize = function (channelIndex) {
- return this.$$channelReceiveManager.getChannel(channelIndex).getOfdmSize();
- };
-
- return PhysicalLayer;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayer.RxInput', _RxInput);
-
- _RxInput.$inject = [];
-
- function _RxInput() {
- return {
- MICROPHONE: 'MICROPHONE',
- LOOPBACK: 'LOOPBACK',
- RECORDED_AUDIO: 'RECORDED_AUDIO'
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayerAdapter.ReceiveAdapterState', _ReceiveAdapterState);
-
- _ReceiveAdapterState.$inject = [];
-
- function _ReceiveAdapterState() {
- return {
- NO_INPUT: 'NO_INPUT',
- IDLE_INIT: 'IDLE_INIT',
- FIRST_SYNC_WAIT: 'FIRST_SYNC_WAIT',
- FIRST_SYNC: 'FIRST_SYNC',
- FATAL_ERROR: 'FATAL_ERROR',
- IDLE: 'IDLE',
- SYMBOL: 'SYMBOL',
- SYNC: 'SYNC',
- GUARD: 'GUARD',
- ERROR: 'ERROR'
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayerAdapter.ReceiveAdapter', _ReceiveAdapter);
-
- _ReceiveAdapter.$inject = [
- 'PhysicalLayer.DefaultConfig',
- 'PhysicalLayerAdapter.RxStateMachineManagerBuilder',
- 'Common.MathUtil'
- ];
-
- function _ReceiveAdapter(
- DefaultConfig,
- RxStateMachineManagerBuilder,
- MathUtil
- ) {
- var ReceiveAdapter;
-
- ReceiveAdapter = function (physicalLayer) {
- var channelIndex, channelSize, stateMachineManager;
-
- this.$$physicalLayer = physicalLayer;
- this.$$stateMachineManager = [];
- this.$$packetReceiveHandler = null;
- this.$$frequencyUpdateHandler = null;
- this.$$phaseCorrectionUpdateHandler = null;
-
- channelSize = this.$$physicalLayer.getRxChannelSize();
- for (channelIndex = 0; channelIndex < channelSize; channelIndex++) {
- stateMachineManager = RxStateMachineManagerBuilder.build(
- channelIndex,
- this.$$packetReceiveInternalHandler.bind(this),
- this.$$frequencyUpdateInternalHandler.bind(this),
- this.$$phaseCorrectionUpdateInternalHandler.bind(this)
- );
- this.$$stateMachineManager.push(stateMachineManager);
- }
- this.setSymbolDuration(DefaultConfig.SYMBOL_DURATION);
- this.setGuardInterval(DefaultConfig.GUARD_INTERVAL);
- this.setSyncDuration(DefaultConfig.SYNC_DURATION);
- this.setSampleCollectionTimeIdleInitState(ReceiveAdapter.$$_SAMPLE_COLLECTION_TIME_IDLE_INIT_STATE);
- this.setSampleCollectionTimeFirstSyncState(ReceiveAdapter.$$_SAMPLE_COLLECTION_TIME_FIRST_SYNC_STATE);
- this.setSyncPreamble(DefaultConfig.SYNC_PREAMBLE);
- this.setPskSize(ReceiveAdapter.$$_ALL_CHANNEL, DefaultConfig.PSK_SIZE);
- };
-
- ReceiveAdapter.$$_SAMPLE_COLLECTION_TIME_IDLE_INIT_STATE = DefaultConfig.SYNC_DURATION;
- ReceiveAdapter.$$_SAMPLE_COLLECTION_TIME_FIRST_SYNC_STATE = DefaultConfig.SYNC_DURATION * 0.85; // little less than 'Sync Duration' in order to finish signal collection before sync transmission ends
- ReceiveAdapter.$$_TIME_TOLERANCE_SYMBOL_DURATION_FACTOR = 2.2; // how much state times can be longer
- ReceiveAdapter.$$_TIME_TOLERANCE_GUARD_INTERVAL_FACTOR = 1.1; // how much state times can be longer
- ReceiveAdapter.$$_TIME_TOLERANCE_SYNC_DURATION_FACTOR = 1.1; // how much state times can be longer
- ReceiveAdapter.$$_ALL_CHANNEL = null;
-
- ReceiveAdapter.prototype.reset = function (channelIndex) {
- this.$$checkChannelIndexRange(channelIndex);
- return this.$$stateMachineManager[channelIndex].reset();
- };
-
- ReceiveAdapter.prototype.setSymbolDuration = function (value) {
- var channelSize, i;
-
- channelSize = this.$$physicalLayer.getRxChannelSize();
- for (i = 0; i < channelSize; i++) {
- this.$$stateMachineManager[i].setSymbolStateMaxDurationTime(
- value * ReceiveAdapter.$$_TIME_TOLERANCE_SYMBOL_DURATION_FACTOR
- );
- }
- };
-
- ReceiveAdapter.prototype.setGuardInterval = function (value) {
- var channelSize, i;
-
- channelSize = this.$$physicalLayer.getRxChannelSize();
- for (i = 0; i < channelSize; i++) {
- this.$$stateMachineManager[i].setGuardStateMaxDurationTime(
- value * ReceiveAdapter.$$_TIME_TOLERANCE_GUARD_INTERVAL_FACTOR
- );
- }
- };
-
- ReceiveAdapter.prototype.setSyncDuration = function (value) {
- var channelSize, i;
-
- channelSize = this.$$physicalLayer.getRxChannelSize();
- for (i = 0; i < channelSize; i++) {
- this.$$stateMachineManager[i].setSyncStateMaxDurationTime(
- value * ReceiveAdapter.$$_TIME_TOLERANCE_SYNC_DURATION_FACTOR
- );
- }
- };
-
- ReceiveAdapter.prototype.setSampleCollectionTimeIdleInitState = function (value) {
- var channelSize, i;
-
- channelSize = this.$$physicalLayer.getRxChannelSize();
- for (i = 0; i < channelSize; i++) {
- this.$$stateMachineManager[i].setSampleCollectionTimeIdleInitState(value);
- }
- };
-
- ReceiveAdapter.prototype.setSampleCollectionTimeFirstSyncState = function (value) {
- var channelSize, i;
-
- channelSize = this.$$physicalLayer.getRxChannelSize();
- for (i = 0; i < channelSize; i++) {
- this.$$stateMachineManager[i].setSampleCollectionTimeFirstSyncState(value);
- }
- };
-
- ReceiveAdapter.prototype.setSyncPreamble = function (value) {
- var channelSize, i;
-
- value = !!value;
- channelSize = this.$$physicalLayer.getRxChannelSize();
- for (i = 0; i < channelSize; i++) {
- this.$$stateMachineManager[i].setSyncPreamble(value);
- }
- };
-
- ReceiveAdapter.prototype.setPskSize = function (channelIndex, value) {
- var channelSize, i;
-
- if (channelIndex === ReceiveAdapter.$$_ALL_CHANNEL) {
- channelSize = this.$$physicalLayer.getRxChannelSize();
- for (i = 0; i < channelSize; i++) {
- this.$$stateMachineManager[i].setPskSize(value);
- }
- } else {
- this.$$checkChannelIndexRange(channelIndex);
- this.$$stateMachineManager[channelIndex].setPskSize(value);
- }
- };
-
- ReceiveAdapter.prototype.$$packetReceiveInternalHandler = function (channelIndex, data) {
- var i;
-
- for (i = 0; i < data.length; i++) {
- if (data[i].length === 1) {
- data[i] = data[i][0]; // flatten data structure when only one ofdm is used for this channel
- }
- }
-
- if (this.$$packetReceiveHandler) {
- this.$$packetReceiveHandler(channelIndex, data);
- }
- };
-
- ReceiveAdapter.prototype.$$frequencyUpdateInternalHandler = function (channelIndex, drift) {
- var current;
-
- if (drift === null) {
- return;
- }
-
- // TODO pass drift as array
- if (MathUtil.abs(drift) > 0.005) {
- current = this.$$physicalLayer.getRxFrequency(channelIndex, 0);
- console.log('phase history current', current);
- this.$$physicalLayer.setRxFrequency(channelIndex, 0, current + drift);
- console.log('Frequency corrected for channel ' + channelIndex + ' at ofdm ' + 0 + ': ' + (current + drift));
- }
- if (this.$$frequencyUpdateHandler) {
- this.$$frequencyUpdateHandler(channelIndex, drift);
- }
- };
-
- ReceiveAdapter.prototype.$$phaseCorrectionUpdateInternalHandler = function (channelIndex, carrierDetail) {
- var current, i;
-
- // TODO pass only phase array not full carrierDetail object
- for (i = 0; i < carrierDetail.length; i++) {
- current = this.$$physicalLayer.getRxPhaseCorrection(channelIndex, i);
- this.$$physicalLayer.setRxPhaseCorrection(channelIndex, i, current + carrierDetail[i].phase);
- console.log('Phase corrected for channel ' + channelIndex + ' at ofdm ' + i + ': ' + (current + carrierDetail[i].phase));
- }
-
- if (this.$$phaseCorrectionUpdateHandler) {
- this.$$phaseCorrectionUpdateHandler(channelIndex, carrierDetail);
- }
- };
-
- ReceiveAdapter.prototype.$$checkChannelIndexRange = function (channelIndex) {
- if (channelIndex < 0 || channelIndex >= this.$$physicalLayer.getRxChannelSize()) {
- throw 'Given channelIndex is outside range: ' + channelIndex;
- }
- };
-
- ReceiveAdapter.prototype.setPacketReceiveHandler = function (cb) {
- if (typeof cb === 'function') {
- this.$$packetReceiveHandler = cb;
- } else {
- this.$$packetReceiveHandler = null;
- }
- };
-
- ReceiveAdapter.prototype.setFrequencyUpdateHandler = function (cb) {
- if (typeof cb === 'function') {
- this.$$frequencyUpdateHandler = cb;
- } else {
- this.$$frequencyUpdateHandler = null;
- }
- };
-
- ReceiveAdapter.prototype.setPhaseCorrectionUpdateHandler = function (cb) {
- if (typeof cb === 'function') {
- this.$$phaseCorrectionUpdateHandler = cb;
- } else {
- this.$$phaseCorrectionUpdateHandler = null;
- }
- };
-
- ReceiveAdapter.prototype.receive = function (channelIndex, carrierDetail, time) {
- this.$$checkChannelIndexRange(channelIndex);
- return this.$$stateMachineManager[channelIndex].receive(carrierDetail, time);
- };
-
- return ReceiveAdapter;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayerAdapter.TransmitAdapter', _TransmitAdapter);
-
- _TransmitAdapter.$inject = [
- 'Common.MathUtil',
- 'Common.Util',
- 'PhysicalLayer.DefaultConfig'
- ];
-
- function _TransmitAdapter(
- MathUtil,
- Util,
- DefaultConfig
- ) {
- var TransmitAdapter;
-
- /**
- * This works as an wrapper for raw API that PhysicalLayer provides.
- * It's much easier to send data using Adapter API. In case of really fancy sound
- * generation cases you can use PhysicalLayer API directly.
- *
- */
- TransmitAdapter = function (physicalLayer) {
- this.$$physicalLayer = physicalLayer;
- };
-
- TransmitAdapter.AMPLITUDE_DATA_LENGTH_DOES_NOT_MATCH_SYMBOL_LIST_LENGTH_EXCEPTION = 'Amplitude data length does not match symbol list length';
- TransmitAdapter.$$_SYNCHRONIZATION_SYMBOL = 0;
- TransmitAdapter.$$_LOWEST_PSK_SIZE = 1;
- TransmitAdapter.$$_ZERO_GUARD_INTERVAL = 0;
- TransmitAdapter.$$_ZERO_INTERPACKET_GAP = 0;
- TransmitAdapter.$$_NO_SYNC_PREAMBLE = false;
- TransmitAdapter.$$_UNDEFINED_AMPLITUDE = undefined;
-
- TransmitAdapter.prototype.symbol = function (channelIndex, ofdmIndex, symbol, pskSize, symbolDuration) {
- var
- ofdmSize = this.$$physicalLayer.getTxChannelOfdmSize(channelIndex),
- data = [],
- i
- ;
-
- for (i = 0; i < ofdmSize; i++) {
- data.push(i === ofdmIndex ? symbol : null);
- }
- data = [ data.length === 1 ? data[0] : data ];
-
- this.packet(
- channelIndex,
- data,
- TransmitAdapter.$$_NO_SYNC_PREAMBLE,
- pskSize,
- Util.valueOrDefault(symbolDuration, DefaultConfig.SYMBOL_DURATION),
- TransmitAdapter.$$_ZERO_GUARD_INTERVAL,
- TransmitAdapter.$$_ZERO_INTERPACKET_GAP,
- TransmitAdapter.$$_UNDEFINED_AMPLITUDE
- );
- };
-
- TransmitAdapter.prototype.packet = function (channelIndex, data, syncPreamble, pskSize, symbolDuration, guardInterval, interpacketGap, amplitude) {
- var
- ofdmSize = this.$$physicalLayer.getTxChannelOfdmSize(channelIndex),
- syncData,
- i
- ;
-
- syncPreamble = Util.valueOrDefault(syncPreamble, DefaultConfig.SYNC_PREAMBLE);
- if (syncPreamble) {
- syncData = [];
- for (i = 0; i < ofdmSize; i++) {
- syncData.push(TransmitAdapter.$$_SYNCHRONIZATION_SYMBOL);
- }
- syncData = syncData.length === 1 ? syncData[0] : syncData;
- data.unshift(syncData);
- }
-
- if (typeof amplitude === 'undefined') {
- amplitude = [];
- for (i = 0; i < ofdmSize; i++) {
- amplitude.push(
- MathUtil.floor(1000 / ofdmSize) / 1000
- );
- }
- }
-
- this.$$transmit(
- channelIndex,
- data,
- Util.valueOrDefault(pskSize, DefaultConfig.PSK_SIZE),
- Util.valueOrDefault(symbolDuration, DefaultConfig.SYMBOL_DURATION),
- Util.valueOrDefault(guardInterval, DefaultConfig.GUARD_INTERVAL),
- Util.valueOrDefault(interpacketGap, DefaultConfig.INTERPACKET_GAP),
- amplitude
- );
- };
-
- TransmitAdapter.prototype.synchronization = function (channelIndex) {
- var
- ofdmSize = this.$$physicalLayer.getTxChannelOfdmSize(channelIndex),
- data = [],
- amplitude = [],
- i
- ;
-
- for (i = 0; i < ofdmSize; i++) {
- data.push(TransmitAdapter.$$_SYNCHRONIZATION_SYMBOL);
- amplitude.push(
- MathUtil.floor(1000 / ofdmSize) / 1000
- );
- }
- data = [ data.length === 1 ? data[0] : data ];
-
- this.$$transmit(
- channelIndex,
- data,
- TransmitAdapter.$$_LOWEST_PSK_SIZE,
- DefaultConfig.SYNC_DURATION,
- TransmitAdapter.$$_ZERO_GUARD_INTERVAL,
- DefaultConfig.INTERPACKET_GAP,
- amplitude
- );
- };
-
- TransmitAdapter.prototype.$$transmit = function (channelIndex, data, pskSize, symbolDuration, guardInterval, interpacketGap, amplitude) {
- var
- ofdmSize = this.$$physicalLayer.getTxChannelOfdmSize(channelIndex),
- symbolList, symbol,
- txData, txDataTmp,
- mute,
- i, j
- ;
-
- txData = [];
- for (i = 0; i < data.length; i++) {
- // allow simpler data structure for ofdm-1 (nested arrays are not needed in this case)
- if (ofdmSize === 1 && typeof data[i] === 'number') {
- symbolList = [ data[i] ];
- } else {
- symbolList = data[i];
- }
-
- if (symbolList.length !== amplitude.length) {
- throw TransmitAdapter.AMPLITUDE_DATA_LENGTH_DOES_NOT_MATCH_SYMBOL_LIST_LENGTH_EXCEPTION;
- }
-
- txDataTmp = [];
- for (j = 0; j < symbolList.length; j++) {
- mute = symbolList[j] === null;
- symbol = mute ? 0 : parseInt(symbolList[j]) % pskSize;
-
- txDataTmp.push({
- amplitude: mute ? 0 : amplitude[j],
- duration: symbolDuration,
- phase: symbol / pskSize
- });
- }
- txData.push(txDataTmp);
-
- if (guardInterval > 0) {
- txDataTmp = [];
- for (j = 0; j < symbolList.length; j++) {
- txDataTmp.push({
- amplitude: 0,
- duration: guardInterval
- });
- }
- txData.push(txDataTmp);
- }
- }
-
- // add interpacket gap only when data loop above actually added something
- if (interpacketGap > 0 && symbolList) {
- txDataTmp = [];
- for (j = 0; j < symbolList.length; j++) {
- txDataTmp.push({
- amplitude: 0,
- duration: interpacketGap
- });
- }
- txData.push(txDataTmp);
- }
-
- for (i = 0; i < txData.length; i++) {
- this.$$physicalLayer.tx(channelIndex, txData[i]);
- }
- };
-
- return TransmitAdapter;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Visualizer.Abstract2DVisualizer', _Abstract2DVisualizer);
-
- _Abstract2DVisualizer.$inject = [
- 'Visualizer.AbstractVisualizer',
- 'Common.Util'
- ];
-
- function _Abstract2DVisualizer(
- AbstractVisualizer,
- Util
- ) {
- var Abstract2DVisualizer;
-
- Abstract2DVisualizer = function (parentElement, width, height, colorAxis, colorCenteredCircle) {
- AbstractVisualizer.call(this, parentElement, width, height);
-
- this.$$colorAxis = Util.valueOrDefault(colorAxis, 'green');
- this.$$colorCenteredCircle = Util.valueOrDefault(colorCenteredCircle, '#DDD');
- };
-
- Abstract2DVisualizer.prototype = Object.create(AbstractVisualizer.prototype);
- Abstract2DVisualizer.prototype.constructor = Abstract2DVisualizer;
-
- Abstract2DVisualizer.prototype.$$drawCenteredCircle = function (radius) {
- var
- ctx = this.$$canvasContext,
- halfW = 0.5 * this.$$width,
- halfH = 0.5 * this.$$height;
-
- ctx.strokeStyle = this.$$colorCenteredCircle;
- ctx.beginPath();
- ctx.arc(
- halfW, halfH,
- radius,
- 0, 2 * Math.PI, false
- );
- ctx.stroke();
- };
-
- Abstract2DVisualizer.prototype.$$drawAxis = function () {
- var
- ctx = this.$$canvasContext,
- w = this.$$width,
- h = this.$$height,
- halfW = 0.5 * w,
- halfH = 0.5 * h;
-
- ctx.strokeStyle = this.$$colorAxis;
- ctx.beginPath();
- ctx.moveTo(0, halfH);
- ctx.lineTo(w, halfH);
- ctx.closePath();
- ctx.stroke();
-
- ctx.beginPath();
- ctx.moveTo(halfW, 0);
- ctx.lineTo(halfW, h);
- ctx.closePath();
- ctx.stroke();
- };
-
- Abstract2DVisualizer.prototype.$$dropXYCache = function () {
- var i;
-
- for (i = 0; i < this.$$queue.getSize(); i++) {
- delete this.$$queue.getItem(i).$$cache;
- }
- };
-
- return Abstract2DVisualizer;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Visualizer.AbstractVisualizer', _AbstractVisualizer);
-
- _AbstractVisualizer.$inject = [
- 'Common.SimplePromiseBuilder'
- ];
-
- function _AbstractVisualizer(
- SimplePromiseBuilder
- ) {
- var AbstractVisualizer;
-
- AbstractVisualizer = function (parentElement, width, height) {
- this.$$parentElement = parentElement;
- this.$$width = width;
- this.$$height = height;
- this.$$canvasContext = null;
- this.$$destroyPromise = null;
-
- this.$$parentElement.innerHTML = this.$$renderTemplate();
- this.$$initCanvas();
- requestAnimationFrame(this.$$animationFrameHandler.bind(this)); // TODO wrap requestAnimationFrame
- };
-
- AbstractVisualizer.ABSTRACT_METHOD_CALLED_EXCEPTION = 'Abstract method called!';
-
- AbstractVisualizer.prototype.destroy = function () {
- if (this.$$destroyPromise) {
- return this.$$destroyPromise;
- }
- this.$$destroyPromise = SimplePromiseBuilder.build();
-
- return this.$$destroyPromise;
- };
-
-
- // TODO move it to dedicated service
- AbstractVisualizer.prototype.$$find = function (selector) {
- var jsObject = this.$$parentElement.querySelectorAll(selector);
-
- if (jsObject.length === 0) {
- throw 'Cannot $$find given selector';
- }
-
- return jsObject[0];
- };
-
- AbstractVisualizer.prototype.$$initCanvas = function () {
- var canvasElement = this.$$find('canvas');
-
- this.$$canvasContext = canvasElement.getContext("2d");
- this.$$canvasContext.lineWidth = 1;
- };
-
- AbstractVisualizer.prototype.$$animationFrameHandler = function () {
- if (this.$$destroyPromise) {
- this.$$parentElement.innerHTML = '';
- this.$$destroyPromise.resolve();
- } else {
- if (this.$$canvasContext) {
- this.$$draw();
- }
- requestAnimationFrame(this.$$animationFrameHandler.bind(this));
- }
- };
-
- AbstractVisualizer.prototype.$$draw = function () {
- throw AbstractVisualizer.ABSTRACT_METHOD_CALLED_EXCEPTION;
- };
-
- AbstractVisualizer.prototype.$$renderTemplate = function () {
- throw AbstractVisualizer.ABSTRACT_METHOD_CALLED_EXCEPTION;
- };
-
- return AbstractVisualizer;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.ComplexPlaneChartBuilder', _ComplexPlaneChartBuilder);
-
- _ComplexPlaneChartBuilder.$inject = [
- 'Visualizer.ComplexPlaneChart'
- ];
-
- function _ComplexPlaneChartBuilder(
- ComplexPlaneChart
- ) {
-
- function build(parentElement, width, height, queue, maxValue, colorAxis, colorPowerLine) {
- return new ComplexPlaneChart(parentElement, width, height, queue, maxValue, colorAxis, colorPowerLine);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.ComplexPlaneChartTemplateMain', _ComplexPlaneChartTemplateMain);
-
- _ComplexPlaneChartTemplateMain.$inject = [];
-
- function _ComplexPlaneChartTemplateMain() {
- var html =
- '
' +
- ' ' +
- '
'
- ;
-
- return {
- html: html
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Visualizer.ComplexPlaneChart', _ComplexPlaneChart);
-
- _ComplexPlaneChart.$inject = [
- 'Visualizer.Abstract2DVisualizer',
- 'Common.Util',
- 'Visualizer.ComplexPlaneChartTemplateMain'
- ];
-
- function _ComplexPlaneChart(
- Abstract2DVisualizer,
- Util,
- ComplexPlaneChartTemplateMain
- ) {
- var ComplexPlaneChart;
-
- ComplexPlaneChart = function (parentElement, width, height, queue, maxValue, colorAxis, colorPowerLine) {
- Abstract2DVisualizer.call(this, parentElement, width, height, colorAxis, colorPowerLine);
-
- this.$$queue = queue;
- this.$$maxValue = Util.valueOrDefault(maxValue, 1);
-
- this.$$hashOnCanvas = null;
- };
-
- ComplexPlaneChart.prototype = Object.create(Abstract2DVisualizer.prototype);
- ComplexPlaneChart.prototype.constructor = ComplexPlaneChart;
-
- ComplexPlaneChart.$$_VALUE_CIRCLE_STEP = 1;
-
- ComplexPlaneChart.prototype.setMaxValue = function (maxValue) {
- if (this.$$maxValue === maxValue) {
- return false;
- }
- this.$$maxValue = maxValue;
- this.$$hashOnCanvas = null;
- this.$$dropXYCache();
-
- return true;
- };
-
- ComplexPlaneChart.prototype.$$renderTemplate = function () {
- var tpl = ComplexPlaneChartTemplateMain.html;
-
- tpl = tpl.replace(/\{\{ width \}\}/g, (this.$$width).toString());
- tpl = tpl.replace(/\{\{ height \}\}/g, (this.$$height).toString());
-
- return tpl;
- };
-
- ComplexPlaneChart.prototype.$$draw = function () {
- var
- ctx = this.$$canvasContext,
- w = this.$$width,
- h = this.$$height,
- halfW = 0.5 * w,
- halfH = 0.5 * h,
- q = this.$$queue,
- item,
- valueCircle,
- radius, x, y, i,
- lineWidth
- ;
-
- if (this.$$hashOnCanvas === q.getHash()) {
- return;
- }
-
- ctx.clearRect(0, 0, w, h);
-
- valueCircle = 0;
- while (valueCircle <= this.$$maxValue) {
- radius = halfH * this.$$getNormalizedValue(valueCircle);
- this.$$drawCenteredCircle(radius);
- valueCircle += ComplexPlaneChart.$$_VALUE_CIRCLE_STEP;
- }
-
- this.$$drawAxis();
-
- lineWidth = ctx.lineWidth;
- for (i = 0; i < q.getSize(); i++) {
- item = q.getItem(i);
- this.$$setItemXYCache(item);
-
- x = halfW + halfW * item.$$cache.x;
- y = halfH - halfH * item.$$cache.y;
-
- if (item.point) {
- ctx.fillStyle = item.pointColor;
- ctx.beginPath();
- ctx.arc(x, y, item.pointRadius, 0, 2 * Math.PI, false);
- ctx.fill();
- }
-
- if (item.line) {
- ctx.lineWidth = item.lineWidth;
- ctx.strokeStyle = item.lineColor;
- ctx.beginPath();
- ctx.moveTo(halfW, halfH);
- ctx.lineTo(x, y);
- ctx.closePath();
- ctx.stroke();
- }
- }
- ctx.lineWidth = lineWidth;
-
- this.$$hashOnCanvas = q.getHash();
- };
-
- ComplexPlaneChart.prototype.$$setItemXYCache = function (item) {
- if (item.$$cache) {
- return;
- }
-
- item.$$cache = {
- x: this.$$getNormalizedValue(item.real),
- y: this.$$getNormalizedValue(item.imm)
- };
- };
-
- ComplexPlaneChart.prototype.$$getNormalizedValue = function (value) {
- return value / this.$$maxValue;
- };
-
- return ComplexPlaneChart;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.AnalyserChartBuilder', _AnalyserChartBuilder);
-
- _AnalyserChartBuilder.$inject = [
- 'Visualizer.AnalyserChart'
- ];
-
- function _AnalyserChartBuilder(
- AnalyserChart
- ) {
-
- function build(parentElement, analyser, height, colorData, colorAxis) {
- return new AnalyserChart(parentElement, analyser, height, colorData, colorAxis);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.AnalyserChartTemplateAxisX', _AnalyserChartTemplateAxisX);
-
- _AnalyserChartTemplateAxisX.$inject = [];
-
- function _AnalyserChartTemplateAxisX() {
- var html =
- '' +
- ' {{ label }}' +
- ''
- ;
-
- return {
- html: html
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.AnalyserChartTemplateMain', _AnalyserChartTemplateMain);
-
- _AnalyserChartTemplateMain.$inject = [];
-
- function _AnalyserChartTemplateMain() {
- var html =
- '' +
- '
' +
- '
' +
- '
' +
- '
'
- ;
-
- return {
- html: html
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Visualizer.AnalyserChart', _AnalyserChart);
-
- _AnalyserChart.$inject = [
- 'Visualizer.AnalyserChartTemplateAxisX',
- 'Visualizer.AnalyserChartTemplateMain',
- 'Common.SimplePromiseBuilder',
- 'Audio.ActiveAudioContext',
- 'Common.MathUtil'
- ];
-
- function _AnalyserChart(
- AnalyserChartTemplateAxisX,
- AnalyserChartTemplateMain,
- SimplePromiseBuilder,
- ActiveAudioContext,
- MathUtil
- ) {
- var AnalyserChart;
-
- AnalyserChart = function (parentElement, analyser, height, colorData, colorAxis) {
- this.$$parentElement = parentElement;
- this.$$analyser = analyser;
- this.$$canvas = null;
- this.$$canvasContext = null;
- this.$$canvasWidth = null;
- this.$$canvasHeight = height;
- this.$$colorData = colorData;
- this.$$colorAxis = colorAxis;
- this.$$data = null;
- this.$$freezeChart = false;
- this.$$analyserMethod = 'getByteFrequencyData';
- this.$$destroyPromise = null;
-
- this.$$initAnimationFrame();
- this.$$init();
- };
-
- AnalyserChart.$$_AXIS_LABEL_X_ONE_ITEM_WITH = 40;
-
- AnalyserChart.prototype.destroy = function () {
- if (this.$$destroyPromise) {
- return this.$$destroyPromise;
- }
- this.$$destroyPromise = SimplePromiseBuilder.build();
-
- return this.$$destroyPromise;
- };
-
- AnalyserChart.prototype.$$init = function () {
- this.$$canvasContext = null;
- this.$$parentElement.innerHTML = this.$$renderTemplate();
- this.$$connectTemplate();
- this.$$initCanvasContext();
- };
-
- // TODO move it to dedicated service
- AnalyserChart.prototype.$$find = function (selector) {
- var jsObject = this.$$parentElement.querySelectorAll(selector);
-
- if (jsObject.length === 0) {
- throw 'Cannot $$find given selector';
- }
-
- return jsObject[0];
- };
-
- AnalyserChart.prototype.$$connectTemplate = function () {
- var self = this;
-
- this.$$canvas = this.$$find('.analyser-chart');
- this.$$canvasContext = this.$$canvas.getContext("2d");
- this.$$canvasWidth = this.$$analyser.fftSize;
-
- this.$$find('.analyser-action-freq-timedomain').addEventListener('click', function () {
- self.actionFrequencyTimeDomainToggle();
- });
- this.$$find('.analyser-action-freeze').addEventListener('click', function () {
- self.actionFreezeChart();
- });
- this.$$find('.analyser-action-fft256').addEventListener('click', function () {
- self.actionChangeFFTSize(256);
- });
- this.$$find('.analyser-action-fft512').addEventListener('click', function () {
- self.actionChangeFFTSize(512);
- });
- this.$$find('.analyser-action-fft1024').addEventListener('click', function () {
- self.actionChangeFFTSize(1024);
- });
- this.$$find('.analyser-action-fft2048').addEventListener('click', function () {
- self.actionChangeFFTSize(2048);
- });
- this.$$find('.analyser-action-fft4096').addEventListener('click', function () {
- self.actionChangeFFTSize(4096);
- });
- this.$$find('.analyser-action-fft8192').addEventListener('click', function () {
- self.actionChangeFFTSize(8192);
- });
- this.$$find('.analyser-action-fft16384').addEventListener('click', function () {
- self.actionChangeFFTSize(16384);
- });
- };
-
- AnalyserChart.prototype.actionFrequencyTimeDomainToggle = function () {
- if (this.$$analyserMethod === 'getByteFrequencyData') {
- this.$$analyserMethod = 'getByteTimeDomainData';
- } else {
- this.$$analyserMethod = 'getByteFrequencyData';
- }
-
- this.$$generateAxisX();
- };
-
- AnalyserChart.prototype.actionFreezeChart = function () {
- this.$$freezeChart = !this.$$freezeChart;
- };
-
- AnalyserChart.prototype.actionChangeFFTSize = function (newFFTSize) {
- this.$$analyser.fftSize = newFFTSize;
- this.$$init();
- };
-
- AnalyserChart.prototype.$$renderTemplate = function () {
- var tpl = AnalyserChartTemplateMain.html;
-
- tpl = tpl.replace(/\{\{ width \}\}/g, (this.$$analyser.frequencyBinCount).toString());
- tpl = tpl.replace(/\{\{ height \}\}/g, (this.$$canvasHeight).toString());
-
- return tpl;
- };
-
- AnalyserChart.prototype.$$renderTemplateAxisXLabel = function (width, left, label) {
- var tpl = AnalyserChartTemplateAxisX.html;
-
- tpl = tpl.replace(/\{\{ width \}\}/g, width);
- tpl = tpl.replace(/\{\{ left \}\}/g, left);
- tpl = tpl.replace(/\{\{ label \}\}/g, label);
- tpl = tpl.replace(/\{\{ colorAxis \}\}/g, this.$$colorAxis);
-
- return tpl;
- };
-
- AnalyserChart.prototype.$$generateAxisXForTimeDomain = function () {
- var
- availableStep = [0.0005, 0.001, 0.002, 0.005, 0.010, 0.025, 0.050, 0.100, 0.250, 0.500],
- resolution = ActiveAudioContext.getSampleRate(), // [pix/sec]
- step = AnalyserChart.$$_AXIS_LABEL_X_ONE_ITEM_WITH / resolution,
- time = 0,
- left,
- i,
- divContent = '';
-
- for (i = 0; i < availableStep.length; i++) {
- if (availableStep[i] >= step || i == availableStep.length - 1) {
- step = availableStep[i];
- break;
- }
- }
-
- while (time < (this.$$analyser.frequencyBinCount / ActiveAudioContext.getSampleRate())) {
- left = MathUtil.round(time * resolution);
- divContent += this.$$renderTemplateAxisXLabel(
- AnalyserChart.$$_AXIS_LABEL_X_ONE_ITEM_WITH,
- left,
- MathUtil.round(time * 1000) + 'ms'
- );
- time += step;
- }
-
- return divContent;
- };
-
- AnalyserChart.prototype.$$generateAxisXForFrequency = function () {
- var
- availableStep = [50, 100, 125, 200, 250, 500, 1000, 2000, 2500, 5000, 10000, 20000],
- resolution = this.$$analyser.fftSize / ActiveAudioContext.getSampleRate(), // [pix/Hz]
- step = AnalyserChart.$$_AXIS_LABEL_X_ONE_ITEM_WITH / resolution,
- frequency = 0,
- left,
- i,
- divContent = '';
-
- for (i = 0; i < availableStep.length; i++) {
- if (availableStep[i] >= step || i == availableStep.length - 1) {
- step = availableStep[i];
- break;
- }
- }
-
- while (frequency < 0.5 * ActiveAudioContext.getSampleRate()) {
- left = MathUtil.round(frequency * resolution);
- divContent += this.$$renderTemplateAxisXLabel(
- AnalyserChart.$$_AXIS_LABEL_X_ONE_ITEM_WITH,
- left,
- frequency + 'Hz'
- );
- frequency += step;
- }
-
- return divContent;
- };
-
- AnalyserChart.prototype.$$generateAxisX = function () {
- var axisX = this.$$find('.analyser-axis-x');
-
- if (this.$$analyserMethod == 'getByteFrequencyData') {
- axisX.innerHTML = ' ' + this.$$generateAxisXForFrequency();
- } else {
- axisX.innerHTML = ' ' + this.$$generateAxisXForTimeDomain();
- }
- };
-
- AnalyserChart.prototype.$$updateChart = function () {
- var
- length = this.$$data.length,
- ctx = this.$$canvasContext,
- i
- ;
-
- if (ctx === null || this.$$freezeChart) {
- return;
- }
- ctx.clearRect(0, 0, this.$$canvasWidth, this.$$canvasHeight);
- this.$$analyser[this.$$analyserMethod](this.$$data);
- for (i = 0; i < length; i++) {
- ctx.beginPath();
- ctx.moveTo(i, this.$$canvasHeight);
- ctx.lineTo(
- i,
- this.$$canvasHeight - MathUtil.round(this.$$canvasHeight * this.$$data[i] / 255)
- );
- ctx.closePath();
- ctx.stroke();
- }
- };
-
- AnalyserChart.prototype.$$initCanvasContext = function () {
- this.$$data = new Uint8Array(this.$$analyser.frequencyBinCount);
- this.$$generateAxisX();
- this.$$canvasContext.lineWidth = 1;
- this.$$canvasContext.strokeStyle = this.$$colorData;
- };
-
- AnalyserChart.prototype.$$initAnimationFrame = function () {
- var self = this;
-
- function drawAgain() {
- if (self.$$destroyPromise) {
- self.$$parentElement.innerHTML = '';
- self.$$destroyPromise.resolve();
- } else {
- self.$$updateChart();
- requestAnimationFrame(drawAgain);
- }
- }
- requestAnimationFrame(drawAgain);
- };
-
- return AnalyserChart;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.FrequencyDomainChartBuilder', _FrequencyDomainChartBuilder);
-
- _FrequencyDomainChartBuilder.$inject = [
- 'Visualizer.FrequencyDomainChart'
- ];
-
- function _FrequencyDomainChartBuilder(
- FrequencyDomainChart
- ) {
-
- function build(parentElement, width, height, frequencyDomain, powerDecibelMin, radius, barWidth, barSpacingWidth, colorAxis, colorSample) {
- return new FrequencyDomainChart(parentElement, width, height, frequencyDomain, powerDecibelMin, radius, barWidth, barSpacingWidth, colorAxis, colorSample);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.FrequencyDomainChartTemplateMain', _FrequencyDomainChartTemplateMain);
-
- _FrequencyDomainChartTemplateMain.$inject = [];
-
- function _FrequencyDomainChartTemplateMain() {
- var html =
- '' +
- ' ' +
- '
'
- ;
-
- return {
- html: html
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Visualizer.FrequencyDomainChart', _FrequencyDomainChart);
-
- _FrequencyDomainChart.$inject = [
- 'Visualizer.AbstractVisualizer',
- 'Visualizer.FrequencyDomainChartTemplateMain',
- 'Common.Util'
- ];
-
- function _FrequencyDomainChart(
- AbstractVisualizer,
- FrequencyDomainChartTemplateMain,
- Util
- ) {
- var FrequencyDomainChart;
-
- FrequencyDomainChart = function (parentElement, width, height, frequencyDomainQueue, powerDecibelMin, radius, barWidth, barSpacingWidth, colorAxis, colorSample) {
- AbstractVisualizer.call(this, parentElement, width, height);
-
- this.$$frequencyDomainQueue = frequencyDomainQueue;
- this.$$powerDecibelMin = Util.valueOrDefault(powerDecibelMin, -40);
- this.$$radius = Util.valueOrDefault(radius, 1.1);
- this.$$barWidth = Util.valueOrDefault(barWidth, 1);
- this.$$barSpacingWidth = Util.valueOrDefault(barSpacingWidth, 0);
- this.$$colorAxis = Util.valueOrDefault(colorAxis, '#EEE');
- this.$$colorSample = Util.valueOrDefault(colorSample, '#738BD7');
-
- this.$$checkWidth();
-
- this.$$hashOnCanvas = null;
- };
-
- FrequencyDomainChart.prototype = Object.create(AbstractVisualizer.prototype);
- FrequencyDomainChart.prototype.constructor = FrequencyDomainChart;
-
- FrequencyDomainChart.QUEUE_SIZE_NOT_MATCH_CHART_WIDTH = 'Queue size not match chart width';
- FrequencyDomainChart.$$_POWER_DECIBEL_AXIS_LINE_STEP = 10;
-
- FrequencyDomainChart.prototype.setWidth = function (width) {
- var element;
-
- if (this.$$width === width) {
- return false;
- }
-
- this.$$width = width;
- this.$$checkWidth();
-
- element = this.$$find('.frequency-domain-chart-container');
- element.style.width = width + 'px';
- element = this.$$find('.frequency-domain-chart');
- element.style.width = width + 'px';
- element.setAttribute("width", width);
-
- this.$$hashOnCanvas = null;
-
- return true;
- };
-
- FrequencyDomainChart.prototype.$$checkWidth = function () {
- if (this.$$frequencyDomainQueue.getSizeMax() * (this.$$barWidth + this.$$barSpacingWidth) !== this.$$width) {
- throw FrequencyDomainChart.QUEUE_SIZE_NOT_MATCH_CHART_WIDTH;
- }
- };
-
- FrequencyDomainChart.prototype.$$renderTemplate = function () {
- var tpl = FrequencyDomainChartTemplateMain.html;
-
- tpl = tpl.replace(/\{\{ width \}\}/g, (this.$$width).toString());
- tpl = tpl.replace(/\{\{ height \}\}/g, (this.$$height).toString());
-
- return tpl;
- };
-
- FrequencyDomainChart.prototype.setPowerDecibelMin = function (powerDecibelMin) {
- if (this.$$powerDecibelMin === powerDecibelMin) {
- return false;
- }
- this.$$powerDecibelMin = powerDecibelMin;
- this.$$hashOnCanvas = null;
-
- return true;
- };
-
- FrequencyDomainChart.prototype.$$draw = function () {
- var
- ctx = this.$$canvasContext,
- fdq = this.$$frequencyDomainQueue,
- w = this.$$width,
- h = this.$$height,
- frequencyBinPowerDecibel, i, x, y,
- barMiddle
- ;
-
- if (this.$$hashOnCanvas === fdq.getHash()) {
- return;
- }
-
- ctx.clearRect(0, 0, w, h);
-
- ctx.strokeStyle = this.$$colorAxis;
- for (i = 0; i <= -this.$$powerDecibelMin; i += FrequencyDomainChart.$$_POWER_DECIBEL_AXIS_LINE_STEP) {
- y = i * h / -this.$$powerDecibelMin;
- ctx.beginPath();
- ctx.moveTo(0, y);
- ctx.lineTo(w, y);
- ctx.closePath();
- ctx.stroke();
- }
-
- ctx.fillStyle = this.$$colorSample;
- barMiddle = 0.5 * (this.$$barWidth - 1);
- for (i = 0; i < fdq.getSize(); i++) {
- frequencyBinPowerDecibel = fdq.getItem(i);
-
- x = i * (this.$$barWidth + this.$$barSpacingWidth);
- y = ((frequencyBinPowerDecibel / this.$$powerDecibelMin)) * h;
-
- if (this.$$barSpacingWidth >= 1) {
- ctx.beginPath();
- ctx.moveTo(x, 0);
- ctx.lineTo(x, h);
- ctx.closePath();
- ctx.stroke();
- }
-
- if (y >= h) {
- continue;
- }
-
- ctx.beginPath();
- ctx.arc(
- x + this.$$barSpacingWidth + barMiddle, y,
- this.$$radius, 0, 2 * Math.PI, false
- );
- ctx.fill();
- // ctx.fillRect(x - 1, y - 1, 3, 3);
- }
-
- this.$$hashOnCanvas = fdq.getHash();
- };
-
- FrequencyDomainChart.prototype.$$initCanvasContext = function () {
- this.$$canvasContext.lineWidth = 1;
- };
-
- return FrequencyDomainChart;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.ConstellationDiagramBuilder', _ConstellationDiagramBuilder);
-
- _ConstellationDiagramBuilder.$inject = [
- 'Visualizer.ConstellationDiagram'
- ];
-
- function _ConstellationDiagramBuilder(
- ConstellationDiagram
- ) {
-
- function build(parentElement, width, height, queue, powerDecibelMin, colorAxis, colorHistoryPoint, colorPowerLine, radius, radiusMain) {
- return new ConstellationDiagram(parentElement, width, height, queue, powerDecibelMin, colorAxis, colorHistoryPoint, colorPowerLine, radius, radiusMain);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.ConstellationDiagramTemplateMain', _ConstellationDiagramTemplateMain);
-
- _ConstellationDiagramTemplateMain.$inject = [];
-
- function _ConstellationDiagramTemplateMain() {
- var html =
- '' +
- ' ' +
- '
'
- ;
-
- return {
- html: html
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Visualizer.ConstellationDiagram', _ConstellationDiagram);
-
- _ConstellationDiagram.$inject = [
- 'Visualizer.Abstract2DVisualizer',
- 'Common.MathUtil',
- 'Common.Util',
- 'Visualizer.ConstellationDiagramTemplateMain'
- ];
-
- function _ConstellationDiagram(
- Abstract2DVisualizer,
- MathUtil,
- Util,
- ConstellationDiagramTemplateMain
- ) {
- var ConstellationDiagram;
-
- ConstellationDiagram = function (parentElement, width, height, queue, powerDecibelMin, colorAxis, colorHistoryPoint, colorPowerLine, radius, radiusMain) {
- Abstract2DVisualizer.call(this, parentElement, width, height, colorAxis, colorPowerLine);
-
- this.$$queue = queue;
- this.$$colorHistoryPoint = Util.valueOrDefault(
- colorHistoryPoint,
- {
- red: {
- newest: 0,
- tailNewest: 100,
- tailOldest: 180
- },
- green: {
- newest: 0,
- tailNewest: 100,
- tailOldest: 200
- },
- blue: {
- newest: 0,
- tailNewest: 100,
- tailOldest: 150
- }
- }
- );
- this.$$radius = Util.valueOrDefault(radius, 2);
- this.$$radiusMain = Util.valueOrDefault(radiusMain, 3);
- this.$$powerDecibelMin = Util.valueOrDefault(powerDecibelMin, -40);
-
- this.$$hashOnCanvas = null;
- };
-
- ConstellationDiagram.prototype = Object.create(Abstract2DVisualizer.prototype);
- ConstellationDiagram.prototype.constructor = ConstellationDiagram;
-
- ConstellationDiagram.$$_POWER_DECIBEL_AXIS_LINE_STEP = 10;
-
- ConstellationDiagram.prototype.setPowerDecibelMin = function (powerDecibelMin) {
- if (this.$$powerDecibelMin === powerDecibelMin) {
- return false;
- }
- this.$$powerDecibelMin = powerDecibelMin;
- this.$$hashOnCanvas = null;
- this.$$dropXYCache();
-
- return true;
- };
-
- ConstellationDiagram.prototype.$$renderTemplate = function () {
- var tpl = ConstellationDiagramTemplateMain.html;
-
- tpl = tpl.replace(/\{\{ width \}\}/g, (this.$$width).toString());
- tpl = tpl.replace(/\{\{ height \}\}/g, (this.$$height).toString());
-
- return tpl;
- };
-
- ConstellationDiagram.prototype.$$draw = function () {
- var
- chp = this.$$colorHistoryPoint,
- ctx = this.$$canvasContext,
- w = this.$$width,
- h = this.$$height,
- halfW = 0.5 * w,
- halfH = 0.5 * h,
- q = this.$$queue,
- item,
- powerDecibel,
- tailUnitPosition, color, radius, x, y, i, isNewest
- ;
-
- if (this.$$hashOnCanvas === q.getHash()) {
- return;
- }
-
- ctx.clearRect(0, 0, w, h);
-
- powerDecibel = 0;
- while (powerDecibel >= this.$$powerDecibelMin) {
- radius = halfH * this.$$getNormalizedPowerDecibel(powerDecibel);
- this.$$drawCenteredCircle(radius);
- powerDecibel -= ConstellationDiagram.$$_POWER_DECIBEL_AXIS_LINE_STEP;
- }
-
- this.$$drawAxis();
-
- // from oldest to newest
- for (i = 0; i < q.getSize(); i++) {
- item = q.getItem(i);
- this.$$setItemXYCache(item);
-
- //if (item.$$cache.outOfRange) {
- // continue;
- //}
-
- x = halfW + halfW * item.$$cache.x;
- y = halfH - halfH * item.$$cache.y;
- tailUnitPosition = 1 - (i / (q.getSize() - 2));
- isNewest = (i === q.getSize() - 1);
-
- if (isNewest) {
- color = (
- 'rgba(' + chp.red.newest + ', ' + chp.green.newest + ', ' + chp.blue.newest + ', ' + '1)'
- );
- } else {
- color = (
- 'rgba(' +
- this.$$colorInterpolate(chp.red.tailNewest, chp.red.tailOldest, tailUnitPosition) + ', ' +
- this.$$colorInterpolate(chp.green.tailNewest, chp.green.tailOldest, tailUnitPosition) + ', ' +
- this.$$colorInterpolate(chp.blue.tailNewest, chp.blue.tailOldest, tailUnitPosition) + ', ' +
- '1)'
- );
- }
-
- ctx.fillStyle = color;
- ctx.beginPath();
- ctx.arc(
- x, y,
- isNewest ? this.$$radiusMain : this.$$radius,
- 0, 2 * Math.PI, false
- );
- ctx.fill();
- /*
- ctx.fillRect(
- x - (isNewest ? 2 : 1),
- y - (isNewest ? 2 : 1),
- (isNewest ? 5 : 3),
- (isNewest ? 5 : 3)
- );
- */
- }
-
- this.$$hashOnCanvas = q.getHash();
- };
-
- ConstellationDiagram.prototype.$$getNormalizedPowerDecibel = function (powerDecibel) {
- var normalizedPowerDecibel;
-
- normalizedPowerDecibel = powerDecibel / this.$$powerDecibelMin;
- normalizedPowerDecibel = 1 - normalizedPowerDecibel;
- normalizedPowerDecibel = normalizedPowerDecibel < 0 ? null : normalizedPowerDecibel;
-
- return normalizedPowerDecibel;
- };
-
- ConstellationDiagram.prototype.$$setItemXYCache = function (item) {
- var normalizedPowerDecibel;
-
- if (item.$$cache) {
- return;
- }
-
- normalizedPowerDecibel = this.$$getNormalizedPowerDecibel(item.powerDecibel);
- item.$$cache = {
- x: normalizedPowerDecibel === null
- ? 0
- : (normalizedPowerDecibel * MathUtil.sin(MathUtil.TWO_PI * item.phase)),
- y: normalizedPowerDecibel === null
- ? 0
- : (normalizedPowerDecibel * MathUtil.cos(MathUtil.TWO_PI * item.phase)),
- outOfRange: normalizedPowerDecibel === null ? true : false
- };
- };
-
- ConstellationDiagram.prototype.$$colorInterpolate = function (start, end, unitPosition) {
- return MathUtil.round(start + ((end - start) * unitPosition));
- };
-
- return ConstellationDiagram;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.PowerChartBuilder', _PowerChartBuilder);
-
- _PowerChartBuilder.$inject = [
- 'Visualizer.PowerChart'
- ];
-
- function _PowerChartBuilder(
- PowerChart
- ) {
-
- function build(parentElement, width, height) {
- return new PowerChart(parentElement, width, height);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.PowerChartTemplateMain', _PowerChartTemplateMain);
-
- _PowerChartTemplateMain.$inject = [];
-
- function _PowerChartTemplateMain() {
- var html =
- '' +
- ' ' +
- '
'
- ;
-
- return {
- html: html
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Visualizer.PowerChart', _PowerChart);
-
- _PowerChart.$inject = [
- 'Visualizer.PowerChartTemplateMain',
- 'Common.SimplePromiseBuilder'
- ];
-
- function _PowerChart(
- PowerChartTemplateMain,
- SimplePromiseBuilder
- ) {
- var PowerChart;
-
- PowerChart = function (parentElement, width, height, queue) {
- this.$$parentElement = parentElement;
- this.$$canvas = null;
- this.$$canvasContext = null;
- this.$$canvasWidth = width;
- this.$$canvasHeight = height;
- this.$$queue = queue;
- this.$$destroyPromise = null;
-
- this.$$initAnimationFrame();
- this.$$init();
- };
-
- PowerChart.prototype.destroy = function () {
- if (this.$$destroyPromise) {
- return this.$$destroyPromise;
- }
- this.$$destroyPromise = SimplePromiseBuilder.build();
-
- return this.$$destroyPromise;
- };
-
- PowerChart.prototype.$$init = function () {
- this.$$canvasContext = null;
- this.$$parentElement.innerHTML = this.$$renderTemplate();
- this.$$connectTemplate();
- this.$$initCanvasContext();
- };
-
- // TODO move it to dedicated service
- PowerChart.prototype.$$find = function (selector) {
- var jsObject = this.$$parentElement.querySelectorAll(selector);
-
- if (jsObject.length === 0) {
- throw 'Cannot $$find given selector';
- }
-
- return jsObject[0];
- };
-
- PowerChart.prototype.$$connectTemplate = function () {
- this.$$canvas = this.$$find('.power-chart');
- this.$$canvasContext = this.$$canvas.getContext("2d");
- };
-
- PowerChart.prototype.$$renderTemplate = function () {
- var tpl = PowerChartTemplateMain.html;
-
- tpl = tpl.replace(/\{\{ width \}\}/g, (this.$$canvasWidth).toString());
- tpl = tpl.replace(/\{\{ height \}\}/g, (this.$$canvasHeight).toString());
-
- return tpl;
- };
-
- PowerChart.prototype.$$updateChart = function () {
- var
- ctx = this.$$canvasContext,
- q = this.$$queue,
- w = this.$$canvasWidth,
- h = this.$$canvasHeight,
- power, i, x, y
- ;
-
- if (ctx === null) {
- return;
- }
-
- ctx.clearRect(0, 0, w, h);
-
- for (y = 0; y < h; y += 10) {
- ctx.strokeStyle = '#EEE'; // TODO add ability to set colors via configuration object
- ctx.beginPath();
- ctx.moveTo(0, 2 * y);
- ctx.lineTo(w, 2 * y);
- ctx.closePath();
- ctx.stroke();
- }
-
- for (i = 0; i < q.getSize(); i++) {
- power = q.getItem(i);
-
- x = i;
- y = -power;
-
- ctx.fillStyle = '#738BD7'; // TODO add ability to set colors via configuration object
- ctx.fillRect(
- x - 1,
- 2 * y - 1,
- 3,
- 3
- );
- }
- };
-
- PowerChart.prototype.$$initCanvasContext = function () {
- this.$$canvasContext.lineWidth = 1;
- };
-
- PowerChart.prototype.$$initAnimationFrame = function () {
- var self = this;
-
- function drawAgain() {
- if (self.$$destroyPromise) {
- self.$$parentElement.innerHTML = '';
- self.$$destroyPromise.resolve();
- } else {
- self.$$updateChart();
- requestAnimationFrame(drawAgain);
- }
- }
- requestAnimationFrame(drawAgain);
- };
-
- return PowerChart;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.SampleChartBuilder', _SampleChartBuilder);
-
- _SampleChartBuilder.$inject = [
- 'Visualizer.SampleChart'
- ];
-
- function _SampleChartBuilder(
- SampleChart
- ) {
-
- function build(parentElement, width, height, queue, radius, barWidth, barSpacingWidth, colorAxis, colorSample, colorBar) {
- return new SampleChart(parentElement, width, height, queue, radius, barWidth, barSpacingWidth, colorAxis, colorSample, colorBar);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Visualizer.SampleChartTemplateMain', _SampleChartTemplateMain);
-
- _SampleChartTemplateMain.$inject = [];
-
- function _SampleChartTemplateMain() {
- var html =
- '' +
- ' ' +
- '
'
- ;
-
- return {
- html: html
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Visualizer.SampleChart', _SampleChart);
-
- _SampleChart.$inject = [
- 'Visualizer.AbstractVisualizer',
- 'Visualizer.SampleChartTemplateMain',
- 'Common.Util'
- ];
-
- function _SampleChart(
- AbstractVisualizer,
- SampleChartTemplateMain,
- Util
- ) {
- var SampleChart;
-
- SampleChart = function (parentElement, width, height, queue, radius, barWidth, barSpacingWidth, colorAxis, colorSample, colorBar) {
- AbstractVisualizer.call(this, parentElement, width, height);
-
- this.$$queue = queue;
- this.$$radius = Util.valueOrDefault(radius, 1.1);
- this.$$barWidth = Util.valueOrDefault(barWidth, 1);
- this.$$barSpacingWidth = Util.valueOrDefault(barSpacingWidth, 0);
- this.$$colorAxis = Util.valueOrDefault(colorAxis, '#EEE');
- this.$$colorSample = Util.valueOrDefault(colorSample, 'rgba(115, 139, 215, 1.0');
- this.$$colorBar = Util.valueOrDefault(colorBar, 'rgba(115, 139, 215, 0.9)');
-
- this.$$sampleBackgroundActive = false;
-
- this.$$checkWidth();
-
- this.$$hashOnCanvas = null;
- };
-
- SampleChart.prototype = Object.create(AbstractVisualizer.prototype);
- SampleChart.prototype.constructor = SampleChart;
-
- SampleChart.QUEUE_SIZE_NOT_MATCH_CHART_WIDTH = 'Queue size not match chart width';
-
- SampleChart.prototype.setWidth = function (width) {
- var element;
-
- if (this.$$width === width) {
- return false;
- }
-
- this.$$width = width;
- this.$$checkWidth();
-
- element = this.$$find('.sample-chart-container');
- element.style.width = width + 'px';
- element = this.$$find('.sample-chart');
- element.style.width = width + 'px';
- element.setAttribute("width", width);
-
- this.$$hashOnCanvas = null;
-
- return true;
- };
-
- SampleChart.prototype.enableSampleBackground = function () {
- if (this.$$sampleBackgroundActive) {
- return false;
- }
-
- this.$$sampleBackgroundActive = true;
- this.$$hashOnCanvas = null;
-
- return true;
- };
-
- SampleChart.prototype.$$checkWidth = function () {
- if (this.$$queue.getSizeMax() * (this.$$barWidth + this.$$barSpacingWidth) !== this.$$width) {
- throw SampleChart.QUEUE_SIZE_NOT_MATCH_CHART_WIDTH;
- }
- };
-
- SampleChart.prototype.$$renderTemplate = function () {
- var tpl = SampleChartTemplateMain.html;
-
- tpl = tpl.replace(/\{\{ width \}\}/g, (this.$$width).toString());
- tpl = tpl.replace(/\{\{ height \}\}/g, (this.$$height).toString());
-
- return tpl;
- };
-
- SampleChart.prototype.$$draw = function () {
- var
- ctx = this.$$canvasContext,
- q = this.$$queue,
- w = this.$$width,
- h = this.$$height,
- hHalf = this.$$height * 0.5,
- sample, i, x, y, barMiddle
- ;
-
- if (this.$$hashOnCanvas === q.getHash()) {
- return;
- }
-
- ctx.clearRect(0, 0, w, h);
-
- // draw horizontal axis
- ctx.strokeStyle = this.$$colorAxis;
- ctx.beginPath();
- ctx.moveTo(0, hHalf);
- ctx.lineTo(w, hHalf);
- ctx.closePath();
- ctx.stroke();
-
- barMiddle = 0.5 * (this.$$barWidth - 1);
- for (i = 0; i < q.getSize(); i++) {
- sample = q.getItem(i);
-
- x = i * (this.$$barWidth + this.$$barSpacingWidth);
- y = (0.5 - 0.5 * sample) * h;
-
- if (this.$$barSpacingWidth > 0) {
- // draw bar spacing
- if (this.$$barSpacingWidth === 1) {
- ctx.strokeStyle = this.$$colorAxis;
- ctx.beginPath();
- ctx.moveTo(x, 0);
- ctx.lineTo(x, h);
- ctx.closePath();
- ctx.stroke();
- } else {
- ctx.fillStyle = this.$$colorAxis;
- ctx.fillRect(
- x, 0,
- this.$$barSpacingWidth, h
- );
- }
- }
-
- if (this.$$sampleBackgroundActive) {
- // draw sample-origin background
- if (this.$$barWidth === 1) {
- ctx.strokeStyle = this.$$colorBar;
- ctx.beginPath();
- ctx.moveTo(x + this.$$barSpacingWidth, hHalf);
- ctx.lineTo(x + this.$$barSpacingWidth, y);
- ctx.closePath();
- ctx.stroke();
- } else {
- ctx.fillStyle = this.$$colorBar;
- ctx.fillRect(
- x + this.$$barSpacingWidth,
- hHalf < y ? hHalf : y,
- this.$$barWidth,
- hHalf < y ? (y - hHalf) : (hHalf - y)
- );
- }
- }
-
- // draw sample circle
- ctx.fillStyle = this.$$colorSample;
- ctx.beginPath();
- ctx.arc(
- x + this.$$barSpacingWidth + barMiddle, y,
- this.$$radius, 0, 2 * Math.PI, false
- );
- ctx.fill();
- }
-
- this.$$hashOnCanvas = q.getHash();
- };
-
- SampleChart.prototype.$$initCanvasContext = function () {
- this.$$canvasContext.lineWidth = 1;
- };
-
- return SampleChart;
- }
-
-})();
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Audio.ActiveAudioContext', _ActiveAudioContext);
-
- _ActiveAudioContext.$inject = [
- 'Audio.SimpleAudioContextBuilder'
- ];
-
- function _ActiveAudioContext(
- SimpleAudioContextBuilder
- ) {
- var simpleAudioContext = null;
-
- function $$init() {
- simpleAudioContext = SimpleAudioContextBuilder.build();
- }
-
- function initializeCheck() {
- if (simpleAudioContext === null) {
- $$init();
- }
- }
-
- function loadRecordedAudio(url) {
- initializeCheck();
- return simpleAudioContext.loadRecordedAudio(url);
- }
-
- function getMicrophoneNode() {
- initializeCheck();
- return simpleAudioContext.getMicrophoneNode();
- }
-
- function getRecordedAudioNode() {
- initializeCheck();
- return simpleAudioContext.getRecordedAudioNode();
- }
-
- function getSampleRate() {
- initializeCheck();
- return simpleAudioContext.getSampleRate();
- }
-
- function getDestination() {
- initializeCheck();
- return simpleAudioContext.getDestination();
- }
-
- function getCurrentTime() {
- initializeCheck();
- return simpleAudioContext.getCurrentTime();
- }
-
- function createAnalyser() {
- initializeCheck();
- return simpleAudioContext.createAnalyser();
- }
-
- function createGain() {
- initializeCheck();
- return simpleAudioContext.createGain();
- }
-
- function createScriptProcessor() {
- initializeCheck();
- return simpleAudioContext.createScriptProcessor();
- }
-
- return {
- loadRecordedAudio: loadRecordedAudio,
- getMicrophoneNode: getMicrophoneNode,
- getRecordedAudioNode: getRecordedAudioNode,
- getSampleRate: getSampleRate,
- getDestination: getDestination,
- getCurrentTime: getCurrentTime,
- createAnalyser: createAnalyser,
- createGain: createGain,
- createScriptProcessor: createScriptProcessor
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Audio.SimpleAudioContextBuilder', _SimpleAudioContextBuilder);
-
- _SimpleAudioContextBuilder.$inject = [
- 'Audio.SimpleAudioContext'
- ];
-
- function _SimpleAudioContextBuilder(
- SimpleAudioContext
- ) {
-
- function build() {
- return new SimpleAudioContext();
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Audio.SimpleAudioContext', _SimpleAudioContext);
-
- _SimpleAudioContext.$inject = [
- 'Common.SimplePromiseBuilder'
- ];
-
- function _SimpleAudioContext(
- SimplePromiseBuilder
- ) {
- var SimpleAudioContext;
-
- SimpleAudioContext = function () {
- this.$$context = null;
- this.$$rawMicrophoneNode = null;
- this.$$microphoneNode = null;
- this.$$recordedNode = null;
- this.$$recordedRawNode = null;
- this.$$init();
- };
-
- SimpleAudioContext.prototype.getCurrentTime = function () {
- return this.$$context.currentTime;
- };
-
- SimpleAudioContext.prototype.createAnalyser = function () {
- return this.$$context.createAnalyser();
- };
-
- SimpleAudioContext.prototype.createGain = function () {
- return this.$$context.createGain();
- };
-
- SimpleAudioContext.prototype.createScriptProcessor = function (bufferSize, numberOfInputChannels, numberOfOutputChannels) {
- return this.$$context.createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels);
- };
-
- SimpleAudioContext.prototype.getSampleRate = function () {
- return this.$$context.sampleRate;
- };
-
- SimpleAudioContext.prototype.getDestination = function () {
- return this.$$context.destination;
- };
-
- SimpleAudioContext.prototype.getMicrophoneNode = function () {
- return this.$$microphoneNode;
- };
-
- SimpleAudioContext.prototype.getRecordedAudioNode = function () {
- return this.$$recordedNode;
- };
-
- SimpleAudioContext.prototype.loadRecordedAudio = function (url) {
- var
- self = this,
- request = new XMLHttpRequest(),
- promise = SimplePromiseBuilder.build();
-
- request.open('GET', url, true);
- request.responseType = 'arraybuffer';
-
- request.onload = function() {
- self.$$context.decodeAudioData(
- request.response,
- function (buffer) {
- if (self.$$recordedRawNode) {
- self.$$recordedRawNode.disconnect(self.$$recordedNode);
- }
-
- self.$$recordedRawNode = self.$$context.createBufferSource();
- self.$$recordedRawNode.buffer = buffer;
- self.$$recordedRawNode.connect(self.$$recordedNode);
- self.$$recordedRawNode.loop = true;
- self.$$recordedRawNode.start(0);
-
- promise.resolve();
- },
- function (e) {
- promise.reject(e);
- }
- );
- };
- request.send();
-
- return promise;
- };
-
- SimpleAudioContext.prototype.$$getConstraints = function () {
- return {
- video: false,
- audio: {
- mandatory: {
- googEchoCancellation: false, // disabling audio processing
- googAutoGainControl: false,
- googNoiseSuppression: false,
- googHighpassFilter: false
- },
- optional: []
- }
- };
- };
-
- SimpleAudioContext.prototype.$$normalizeGlobalVariable = function () {
- window.AudioContext =
- window.AudioContext ||
- window.webkitAudioContext ||
- window.mozAudioContext;
- navigator.getUserMedia =
- navigator.getUserMedia ||
- navigator.webkitGetUserMedia ||
- navigator.mozGetUserMedia ||
- navigator.msGetUserMedia;
- };
-
- SimpleAudioContext.prototype.$$init = function () {
- var self = this;
-
- this.$$normalizeGlobalVariable();
-
- try {
- this.$$context = new window.AudioContext();
- } catch (e) {
- alert('Web Audio API is not supported in this browser');
- console.log(e);
- }
-
- this.$$microphoneNode = this.$$context.createGain();
- this.$$recordedNode = this.$$context.createGain();
- try {
- navigator.getUserMedia(
- this.$$getConstraints(),
- function (stream) {
- self.$$rawMicrophoneNode = self.$$context.createMediaStreamSource(stream);
- self.$$rawMicrophoneNode.connect(self.$$microphoneNode);
- },
- function (e) {
- alert('Microphone initialization failed');
- console.log(e);
- }
- );
- } catch (e) {
- alert('Microphone initialization failed');
- console.log(e);
- }
- };
-
- return SimpleAudioContext;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Common.AbstractValueCollector', _AbstractValueCollector);
-
- _AbstractValueCollector.$inject = [];
-
- function _AbstractValueCollector() {
- var AbstractValueCollector;
-
- AbstractValueCollector = function () {
- this.$$valueList = [];
- this.$$lastFinalizedSize = undefined;
- this.$$lastFinalizedResult = undefined;
- };
-
- AbstractValueCollector.ABSTRACT_METHOD_CALLED_EXCEPTION = 'Abstract method called!';
-
- AbstractValueCollector.prototype.collect = function (value) {
- this.$$valueList.push(value);
- };
-
- AbstractValueCollector.prototype.hasAtLeastItem = function () {
- return this.getSize() > 0;
- };
-
- AbstractValueCollector.prototype.getSize = function () {
- return this.$$valueList.length;
- };
-
- AbstractValueCollector.prototype.clearAll = function () {
- this.clearList();
- this.$$lastFinalizedSize = undefined;
- this.$$lastFinalizedResult = undefined;
- };
-
- AbstractValueCollector.prototype.clearList = function () {
- this.$$valueList.length = 0;
- };
-
- AbstractValueCollector.prototype.finalize = function () {
- this.$$lastFinalizedResult = this.$$finalize(); // $$finalize() method may throw error BEFORE assignment
- this.$$lastFinalizedSize = this.getSize();
- this.clearList();
-
- return this.$$lastFinalizedResult;
- };
-
- /**
- * Returns list size that was used to compute last successful result from finalize method.
- */
- AbstractValueCollector.prototype.getLastFinalizedSize = function () {
- return this.$$lastFinalizedSize;
- };
-
- /**
- * Returns last successful result from finalize method.
- */
- AbstractValueCollector.prototype.getLastFinalizedResult = function () {
- return this.$$lastFinalizedResult;
- };
-
- AbstractValueCollector.prototype.$$finalize = function () {
- throw AbstractValueCollector.ABSTRACT_METHOD_CALLED_EXCEPTION;
- };
-
- return AbstractValueCollector;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Common.AverageValueCollectorBuilder', _AverageValueCollectorBuilder);
-
- _AverageValueCollectorBuilder.$inject = [
- 'Common.AverageValueCollector'
- ];
-
- function _AverageValueCollectorBuilder(
- AverageValueCollector
- ) {
-
- function build() {
- return new AverageValueCollector();
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Common.AverageValueCollector', _AverageValueCollector);
-
- _AverageValueCollector.$inject = [
- 'Common.AbstractValueCollector',
- 'Common.Util'
- ];
-
- function _AverageValueCollector(
- AbstractValueCollector,
- Util
- ) {
- var AverageValueCollector;
-
- AverageValueCollector = function () {
- AbstractValueCollector.apply(this, arguments);
- };
-
- AverageValueCollector.prototype = Object.create(AbstractValueCollector.prototype);
- AverageValueCollector.prototype.constructor = AverageValueCollector;
-
- AverageValueCollector.EMPTY_LIST_EXCEPTION = 'Cannot finalize AverageValueCollector without any samples collected';
-
- AverageValueCollector.prototype.$$finalize = function () {
- if (this.$$valueList.length === 0) {
- throw AverageValueCollector.EMPTY_LIST_EXCEPTION;
- }
-
- return Util.computeAverage(this.$$valueList);
- };
-
- return AverageValueCollector;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Common.CarrierGenerateBuilder', _CarrierGenerateBuilder);
-
- _CarrierGenerateBuilder.$inject = [
- 'Common.CarrierGenerate'
- ];
-
- function _CarrierGenerateBuilder(
- CarrierGenerate
- ) {
-
- function build(samplePerPeriod) {
- return new CarrierGenerate(samplePerPeriod);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Common.CarrierGenerate', _CarrierGenerate);
-
- _CarrierGenerate.$inject = [
- 'Common.MathUtil',
- 'Common.Util'
- ];
-
- function _CarrierGenerate(
- MathUtil,
- Util
- ) {
- var CarrierGenerate;
-
- CarrierGenerate = function (samplePerPeriod, samplePerFade) {
- this.$$samplePerFade = samplePerFade;
- this.$$queue = [];
- this.$$sampleComputed = null;
- this.$$currentCarrier = {
- data: null,
- sampleNumberStart: null,
- sampleNumberEnd: null
- };
-
- this.$$samplePerPeriod = null;
- this.$$omega = null;
- this.$$sampleNumber = 0;
- this.$$phaseCorrection = 0;
- this.setSamplePerPeriod(samplePerPeriod);
- };
-
- CarrierGenerate.prototype.$$sampleCompute = function () {
- var
- currentCarrierData = this.$$currentCarrier.data,
- fadeFactor,
- fadePositionStart,
- fadePositionEnd
- ;
-
- if (!currentCarrierData) {
- this.$$sampleComputed = 0;
- return;
- }
-
- fadeFactor = 1.0;
- if (this.$$samplePerFade > 0) {
- fadePositionStart = (this.$$sampleNumber - this.$$currentCarrier.sampleNumberStart) / this.$$samplePerFade;
- fadePositionEnd = (this.$$currentCarrier.sampleNumberEnd - this.$$sampleNumber) / this.$$samplePerFade;
-
- if (fadePositionStart >= 0 && fadePositionStart <= 1) {
- fadeFactor = Util.unitFade(fadePositionStart);
- } else {
- if (fadePositionEnd >= 0 && fadePositionEnd <= 1) {
- fadeFactor = Util.unitFade(fadePositionEnd);
- }
- }
- }
-
- this.$$sampleComputed = (
- fadeFactor *
- currentCarrierData.amplitude *
- MathUtil.sin( // TODO: consider changing to cosine
- this.$$omega * this.$$sampleNumber
- - MathUtil.TWO_PI * (currentCarrierData.phase - this.$$phaseCorrection)
- )
- );
- };
-
- CarrierGenerate.prototype.$$grabCurrentCarrier = function () {
- var fromQueue, isSameAsBefore;
-
- fromQueue = Util.queuePop(this.$$queue);
- if (fromQueue) {
- isSameAsBefore = (fromQueue === this.$$currentCarrier.data);
- if (!isSameAsBefore) {
- this.$$currentCarrier.data = fromQueue;
- this.$$currentCarrier.sampleNumberStart = this.$$sampleNumber;
- this.$$currentCarrier.sampleNumberEnd = (
- this.$$currentCarrier.sampleNumberStart + fromQueue.duration
- );
- }
- } else {
- this.$$currentCarrier.data = null;
- this.$$currentCarrier.sampleNumberStart = null;
- this.$$currentCarrier.sampleNumberEnd = null;
- }
- };
-
- CarrierGenerate.prototype.setPhaseCorrection = function (phaseCorrection) {
- this.$$phaseCorrection = phaseCorrection;
- };
-
- CarrierGenerate.prototype.nextSample = function () {
- this.$$sampleNumber++;
- this.$$sampleComputed = null;
- };
-
- CarrierGenerate.prototype.getSample = function () {
- if (this.$$sampleComputed) { // TODO fix me, 0 will not pass but this is valid sample!!!
- return this.$$sampleComputed;
- }
-
- this.$$grabCurrentCarrier();
- this.$$sampleCompute();
-
- return this.$$sampleComputed;
- };
-
- CarrierGenerate.prototype.addToQueue = function (carrierData) {
- Util.queueAdd(
- this.$$queue,
- carrierData,
- function (queueItem, item) {
- queueItem.amplitude = item.amplitude;
- queueItem.phase = item.phase;
- }
- );
- };
-
- CarrierGenerate.prototype.reset = function () {
- this.$$sampleNumber = 0;
- };
-
- CarrierGenerate.prototype.setSamplePerPeriod = function (samplePerPeriod) {
- if (samplePerPeriod === this.$$samplePerPeriod) {
- return false;
- }
- this.$$samplePerPeriod = samplePerPeriod;
- this.$$omega = MathUtil.TWO_PI / this.$$samplePerPeriod; // revolutions per sample
- this.$$sampleNumber = 0;
-
- return true;
- };
-
- return CarrierGenerate;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Common.CarrierRecoveryBuilder', _CarrierRecoveryBuilder);
-
- _CarrierRecoveryBuilder.$inject = [
- 'Common.CarrierRecovery'
- ];
-
- function _CarrierRecoveryBuilder(
- CarrierRecovery
- ) {
-
- function build(samplePerPeriod, samplePerDftWindow) {
- return new CarrierRecovery(samplePerPeriod, samplePerDftWindow);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Common.CarrierRecovery', _CarrierRecovery);
-
- _CarrierRecovery.$inject = [
- 'Common.QueueBuilder',
- 'Common.MathUtil',
- 'Common.Util',
- 'Common.ComplexBuilder'
- ];
-
- function _CarrierRecovery(
- QueueBuilder,
- MathUtil,
- Util,
- ComplexBuilder
- ) {
- var CarrierRecovery;
-
- CarrierRecovery = function (samplePerPeriod, samplePerDftWindow) {
- this.$$samplePerDftWindow = undefined;
- this.$$complexQueue = undefined;
- this.$$complexQueueSum = undefined;
- this.setSamplePerDftWindow(samplePerDftWindow);
-
- this.$$samplePerPeriod = undefined;
- this.$$omega = undefined;
- this.$$sampleNumber = undefined;
- this.setSamplePerPeriod(samplePerPeriod);
- };
-
- CarrierRecovery.prototype.$$getUnitComplex = function () {
- var r = this.$$omega * this.$$sampleNumber;
-
- return ComplexBuilder.build(
- -MathUtil.cos(r),
- MathUtil.sin(r)
- );
- };
-
- CarrierRecovery.prototype.handleSample = function (sample) {
- var oldComplex, newComplex;
-
- if (this.$$complexQueue.isFull()) {
- oldComplex = this.$$complexQueue.pop();
- this.$$complexQueueSum.sub(oldComplex);
- }
- newComplex = this.$$getUnitComplex();
- newComplex.mulScalar(sample);
- this.$$complexQueue.push(newComplex);
- this.$$complexQueueSum.add(newComplex);
- this.$$sampleNumber++;
- };
-
- CarrierRecovery.prototype.getCarrierDetail = function () {
- var complex = ComplexBuilder.copy(this.$$complexQueueSum);
-
- complex.divScalar(this.$$complexQueue.getSize());
-
- return {
- phase: complex.findUnitAngle(),
- powerDecibel: Util.convertToDecibel(complex.getAbsoluteValue())
- };
- };
-
- CarrierRecovery.prototype.setSamplePerDftWindow = function (samplePerDftWindow) {
- if (samplePerDftWindow === this.$$samplePerDftWindow) {
- return false;
- }
- this.$$samplePerDftWindow = samplePerDftWindow;
- this.$$complexQueue = QueueBuilder.build(samplePerDftWindow);
- this.$$complexQueueSum = ComplexBuilder.build(0, 0);
-
- return true;
- };
-
- CarrierRecovery.prototype.setSamplePerPeriod = function (samplePerPeriod) {
- if (samplePerPeriod === this.$$samplePerPeriod) {
- return false;
- }
- this.$$samplePerPeriod = samplePerPeriod;
- this.$$omega = MathUtil.TWO_PI / this.$$samplePerPeriod; // revolutions per sample
- this.$$sampleNumber = 0;
-
- return true;
- };
-
- return CarrierRecovery;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Common.ComplexBuilder', _ComplexBuilder);
-
- _ComplexBuilder.$inject = [
- 'Common.Complex'
- ];
-
- function _ComplexBuilder(
- Complex
- ) {
-
- function build(real, imm) {
- return new Complex(real, imm);
- }
-
- function copy(complex) {
- return new Complex(complex.real, complex.imm);
- }
-
- return {
- build: build,
- copy: copy
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Common.Complex', _Complex);
-
- _Complex.$inject = [
- 'Common.Util',
- 'Common.MathUtil'
- ];
-
- function _Complex(
- Util,
- MathUtil
- ) {
- var Complex;
-
- Complex = function (real, imm) {
- this.real = real;
- this.imm = imm;
- };
-
- Complex.prototype.add = function (complex) {
- this.real += complex.real;
- this.imm += complex.imm;
- };
-
- Complex.prototype.sub = function (complex) {
- this.real -= complex.real;
- this.imm -= complex.imm;
- };
-
- Complex.prototype.mulScalar = function (n) {
- this.real *= n;
- this.imm *= n;
- };
-
- Complex.prototype.divScalar = function (n) {
- this.real /= n;
- this.imm /= n;
- };
-
- Complex.prototype.getAbsoluteValue = function () {
- return MathUtil.sqrt(
- this.real * this.real +
- this.imm * this.imm
- );
- };
-
- Complex.prototype.findUnitAngle = function () {
- return Util.findUnitAngle(this.real, this.imm);
- };
-
- return Complex;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Common.QueueBuilder', _QueueBuilder);
-
- _QueueBuilder.$inject = [
- 'Common.Queue'
- ];
-
- function _QueueBuilder(
- Queue
- ) {
-
- function build(size) {
- return new Queue(size);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Common.Queue', _Queue);
-
- _Queue.$inject = [
- 'Common.MathUtil'
- ];
-
- function _Queue(
- MathUtil
- ) {
- var Queue;
-
- Queue = function (sizeMax) {
- this.$$data = [];
- this.$$positionStart = null;
- this.$$positionEnd = null;
- this.$$size = null;
- this.$$hash = null;
- this.$$sizeMax = null;
- this.setSizeMax(sizeMax);
- };
-
- Queue.prototype.$$generateNewHash = function () {
- this.$$hash = MathUtil.random() * 1000000;
- };
-
- Queue.prototype.setSizeMax = function (sizeMax) {
- this.$$positionStart = 0;
- this.$$positionEnd = 0;
- this.$$size = 0;
- this.$$hash = 0;
- this.$$sizeMax = sizeMax;
- this.$$data.length = 0; // drop all data
- this.$$data.length = sizeMax;
- };
-
- Queue.prototype.getHash = function () {
- return this.$$hash;
- };
-
- Queue.prototype.push = function (value) {
- if (this.$$size === this.$$sizeMax) {
- return false;
- }
-
- this.$$data[this.$$positionEnd] = value;
- this.$$positionEnd = (this.$$positionEnd + 1) % this.$$sizeMax;
- this.$$size++;
-
- this.$$generateNewHash();
-
- return true;
- };
-
- Queue.prototype.pushEvenIfFull = function (value) {
- if (this.isFull()) {
- this.pop();
- }
- this.push(value);
- };
-
- Queue.prototype.pop = function () {
- var result;
-
- if (this.$$size === 0) {
- return null;
- }
- result = this.$$data[this.$$positionStart];
- this.$$positionStart = (this.$$positionStart + 1) % this.$$sizeMax;
- this.$$size--;
-
- this.$$generateNewHash();
-
- return result;
- };
-
- Queue.prototype.getItem = function (index) {
- if (index >= this.$$size) {
- return null;
- }
-
- return this.$$data[(this.$$positionStart + index) % this.$$sizeMax];
- };
-
- Queue.prototype.getSize = function () {
- return this.$$size;
- };
-
- Queue.prototype.getSizeMax = function () {
- return this.$$sizeMax;
- };
-
- Queue.prototype.isFull = function () {
- return this.$$size === this.$$sizeMax;
- };
-
- return Queue;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Common.Util', _Util);
-
- _Util.$inject = [
- 'Common.MathUtil'
- ];
-
- function _Util(
- MathUtil
- ) {
-
- function valueOrDefault(value, defaultValue) {
- return typeof value !== 'undefined' ? value : defaultValue;
- }
-
- function accessor(element, path) {
- var
- pathList = path.split('.'),
- result = element,
- i
- ;
-
- if (!element) {
- return undefined;
- }
-
- for (i = 0; i < pathList.length; i++) {
- result = result[pathList[i]];
- if (!result) {
- break;
- }
- }
-
- return result;
- }
-
- function computeAverage(list) {
- var i, sum;
-
- if (!list || list.length === 0) {
- return 0;
- }
- sum = 0;
- for (i = 0; i < list.length; i++) {
- sum += list[i];
- }
-
- return sum / list.length;
- }
-
- function convertToDecibel(value) {
- return 10 * MathUtil.log(value) / MathUtil.LN10; // TODO it should be (20 * ...) because decibels describes power levels
- }
-
- function findUnitAngle(x, y) {
- var length, quarter, angle;
-
- length = MathUtil.sqrt(x * x + y * y);
- length = (length < 0.000001) ? 0.000001 : length; // prevents from dividing by zero
- quarter = (x >= 0) ? (y >= 0 ? 0 : 1) : (y < 0 ? 2 : 3);
- switch (quarter) {
- case 0:
- angle = MathUtil.asin(x / length);
- break;
- case 1:
- angle = MathUtil.asin(-y / length) + MathUtil.HALF_PI;
- break;
- case 2:
- angle = MathUtil.asin(-x / length) + MathUtil.PI;
- break;
- case 3:
- angle = MathUtil.asin(y / length) + 1.5 * MathUtil.PI;
- break;
- }
-
- return angle / MathUtil.TWO_PI;
- }
-
- function unitFade(x) {
- x = x < 0 ? 0 : x;
- x = x > 1 ? 1 : x;
-
- return 0.5 * (MathUtil.sin((x - 0.5) * MathUtil.PI) + 1);
- }
-
- function queueAdd(queue, item, copyCallback, amountFieldName) {
- var queueItem;
-
- amountFieldName = amountFieldName === undefined ? 'duration' : amountFieldName;
- if (item[amountFieldName] > 0) {
- queueItem = {};
- queueItem[amountFieldName] = item[amountFieldName];
- copyCallback(queueItem, item);
- queue.push(queueItem);
- }
- }
-
- function queuePop(queue, amountFieldName) {
- var queueItem;
-
- amountFieldName = amountFieldName === undefined ? 'duration' : amountFieldName;
-
- if (queue.length === 0) {
- return null;
- }
-
- queue[0][amountFieldName]--;
- queueItem = queue[0];
- if (queue[0][amountFieldName] === 0) {
- // TODO check performance, maybe it's better to just keep track
- // of used elements and delete array at the end
- queue.splice(0, 1);
- }
-
- return queueItem;
- }
-
- function findMaxValueIndex(list, accessorString) {
- var
- maxValue = null,
- index = null,
- i, value
- ;
-
- if (!list) {
- return null;
- }
-
- for (i = 0; i < list.length; i++) {
- value = accessor(list[i], accessorString);
- if (index === null || value > maxValue) {
- maxValue = value;
- index = i;
- }
- }
-
- return index;
- }
-
- return {
- valueOrDefault: valueOrDefault,
- accessor: accessor,
- computeAverage: computeAverage,
- convertToDecibel: convertToDecibel,
- findUnitAngle: findUnitAngle,
- unitFade: unitFade,
- queueAdd: queueAdd,
- queuePop: queuePop,
- findMaxValueIndex: findMaxValueIndex
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayer.AbstractChannelManager', _AbstractChannelManager);
-
- _AbstractChannelManager.$inject = [
- 'Audio.ActiveAudioContext'
- ];
-
- function _AbstractChannelManager(
- ActiveAudioContext
- ) {
- var AbstractChannelManager;
-
- AbstractChannelManager = function () {
- this.$$cpuLoadData = {
- blockSampleSize: null,
- blockTime: null,
- blockRealTime: null,
- load: null
- };
- };
-
- AbstractChannelManager.prototype.getCpuLoadData = function () {
- var c = this.$$cpuLoadData;
-
- return {
- blockSampleSize: c.blockSampleSize,
- blockTime: c.blockTime,
- blockRealTime: c.blockRealTime,
- load: c.load
- };
- };
-
- AbstractChannelManager.prototype.$$computeCpuLoadData = function (beginTime, endTime, blockSampleSize) {
- var
- c = this.$$cpuLoadData,
- blockRealTime,
- blockTime;
-
- blockRealTime = endTime - beginTime;
- blockTime = blockSampleSize / ActiveAudioContext.getSampleRate();
-
- c.blockSampleSize = blockSampleSize;
- c.blockTime = blockTime;
- c.blockRealTime = blockRealTime;
- c.load = blockRealTime / blockTime;
- };
-
- return AbstractChannelManager;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayer.ChannelReceiveBuilder', _ChannelReceiveBuilder);
-
- _ChannelReceiveBuilder.$inject = [
- 'PhysicalLayer.ChannelReceive'
- ];
-
- function _ChannelReceiveBuilder(
- ChannelReceive
- ) {
-
- function build(index, configuration) {
- return new ChannelReceive(index, configuration);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayer.ChannelReceive', _ChannelReceive);
-
- _ChannelReceive.$inject = [
- 'Audio.ActiveAudioContext',
- 'Common.CarrierRecoveryBuilder',
- 'Common.MathUtil'
- ];
-
- function _ChannelReceive(
- ActiveAudioContext, // TODO remove that depencency - it's here only for sample rate
- CarrierRecoveryBuilder,
- MathUtil
- ) {
- var ChannelReceive;
-
- ChannelReceive = function (index, configuration) {
- this.$$carrierRecovery = [];
- this.$$carrierFrequency = [];
- this.$$carrierPhaseCorrection = [];
- this.$$notifyInterval = null;
- this.$$notifyHandler = null;
- this.$$index = index;
-
- this.configure(configuration);
- };
-
- ChannelReceive.OFDM_INDEX_OUT_OF_RANGE_EXCEPTION = 'OFDM index out of range: ';
-
- ChannelReceive.prototype.configure = function (configuration) {
- var i, cr, samplePerPeriod, frequency;
-
- for (i = 0; i < configuration.ofdmSize; i++) {
- frequency = configuration.baseFrequency + i * configuration.ofdmFrequencySpacing;
- samplePerPeriod = ActiveAudioContext.getSampleRate() / frequency;
- cr = CarrierRecoveryBuilder.build(samplePerPeriod, configuration.dftWindowSize);
- this.$$carrierRecovery.push(cr);
- this.$$carrierFrequency.push(frequency);
- this.$$carrierPhaseCorrection.push(0);
- }
-
- this.$$notifyInterval = configuration.notifyInterval;
- this.$$notifyHandler = configuration.notifyHandler;
- };
-
- ChannelReceive.prototype.$$checkOfdmIndex = function (ofdmIndex) {
- if (ofdmIndex < 0 || ofdmIndex >= this.$$carrierRecovery.length) {
- throw ChannelReceive.OFDM_INDEX_OUT_OF_RANGE_EXCEPTION + ofdmIndex;
- }
- };
-
- ChannelReceive.prototype.getOfdmSize = function () {
- return this.$$carrierRecovery.length;
- };
-
- ChannelReceive.prototype.getRxPhaseCorrection = function (ofdmIndex) {
- this.$$checkOfdmIndex(ofdmIndex);
-
- return this.$$carrierPhaseCorrection[ofdmIndex];
- };
-
- ChannelReceive.prototype.getFrequency = function (ofdmIndex) {
- this.$$checkOfdmIndex(ofdmIndex);
-
- return this.$$carrierFrequency[ofdmIndex];
- };
-
- ChannelReceive.prototype.setRxPhaseCorrection = function (ofdmIndex, phaseCorrection) {
- this.$$checkOfdmIndex(ofdmIndex);
-
- this.$$carrierPhaseCorrection[ofdmIndex] = phaseCorrection - MathUtil.floor(phaseCorrection);
- };
-
- ChannelReceive.prototype.setFrequency = function (ofdmIndex, frequency) {
- var samplePerPeriod;
-
- this.$$checkOfdmIndex(ofdmIndex);
-
- samplePerPeriod = ActiveAudioContext.getSampleRate() / frequency;
- this.$$carrierRecovery[ofdmIndex].setSamplePerPeriod(samplePerPeriod);
- this.$$carrierFrequency[ofdmIndex] = frequency;
- };
-
- ChannelReceive.prototype.handleSample = function (sample, sampleNumberGlobal, blockBeginTime, sampleNumberInBlock) {
- var notifyIteration, cr, cd, i, carrierDetail, sampleTimeOffsetInBlock;
-
- notifyIteration = (sampleNumberGlobal % this.$$notifyInterval === 0);
-
- if (notifyIteration) {
- carrierDetail = [];
- }
-
- for (i = 0; i < this.$$carrierRecovery.length; i++) {
- cr = this.$$carrierRecovery[i];
- cr.handleSample(sample);
- if (notifyIteration) {
- cd = cr.getCarrierDetail();
- cd.phase = cd.phase - this.$$carrierPhaseCorrection[i];
- cd.phase = cd.phase - MathUtil.floor(cd.phase);
- carrierDetail.push(cd);
- }
- }
-
- if (notifyIteration) {
- sampleTimeOffsetInBlock = sampleNumberInBlock / ActiveAudioContext.getSampleRate();
-
- this.$$notifyHandler(
- this.$$index,
- carrierDetail,
- blockBeginTime + sampleTimeOffsetInBlock
- );
- }
- };
-
- ChannelReceive.prototype.destroy = function () {
- this.$$carrierRecovery.length = 0;
- this.$$carrierFrequency.length = 0;
- this.$$carrierPhaseCorrection.length = 0;
- };
-
- return ChannelReceive;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayer.ChannelReceiveManagerBuilder', _ChannelReceiveManagerBuilder);
-
- _ChannelReceiveManagerBuilder.$inject = [
- 'PhysicalLayer.ChannelReceiveManager'
- ];
-
- function _ChannelReceiveManagerBuilder(
- ChannelReceiveManager
- ) {
-
- function build(configuration, bufferSize) {
- return new ChannelReceiveManager(configuration, bufferSize);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayer.ChannelReceiveManager', _ChannelReceiveManager);
-
- _ChannelReceiveManager.$inject = [
- 'PhysicalLayer.AbstractChannelManager',
- 'Audio.ActiveAudioContext',
- 'PhysicalLayer.ChannelReceiveBuilder'
- ];
-
- function _ChannelReceiveManager(
- AbstractChannelManager,
- ActiveAudioContext,
- ChannelReceiveBuilder
- ) {
- var ChannelReceiveManager;
-
- ChannelReceiveManager = function (configuration, bufferSize) {
- AbstractChannelManager.apply(this, arguments);
-
- this.$$channelReceive = [];
- this.$$scriptNode = null;
- this.$$analyserNode = null; // empty analyser needs to be connected to script node
- this.$$configuration = configuration;
- this.$$bufferSize = bufferSize;
- this.$$sampleNumberGlobal = 0;
-
- this.$$init();
- };
-
- ChannelReceiveManager.prototype = Object.create(AbstractChannelManager.prototype);
- ChannelReceiveManager.prototype.constructor = ChannelReceiveManager;
-
- ChannelReceiveManager.CHANNEL_INDEX_OUT_OF_RANGE_EXCEPTION = 'Channel index out of range: ';
- ChannelReceiveManager.$$_LOWEST_FFT_SIZE = 256;
-
- ChannelReceiveManager.prototype.destroy = function () {
- var i, cr;
-
- for (i = 0; i < this.$$channelReceive.length; i++) {
- cr = this.$$channelReceive[i];
- cr.destroy();
- }
- this.$$channelReceive.length = 0;
- };
-
- ChannelReceiveManager.prototype.getInputNode = function () {
- return this.$$scriptNode;
- };
-
- ChannelReceiveManager.prototype.getChannelSize = function () {
- return this.$$channelReceive.length;
- };
-
- ChannelReceiveManager.prototype.getChannel = function (channelIndex) {
- if (channelIndex < 0 || channelIndex >= this.$$channelReceive.length) {
- throw ChannelReceiveManager.CHANNEL_INDEX_OUT_OF_RANGE_EXCEPTION + channelIndex;
- }
-
- return this.$$channelReceive[channelIndex];
- };
-
- ChannelReceiveManager.prototype.getBufferSize = function () {
- return this.$$scriptNode.bufferSize;
- };
-
- ChannelReceiveManager.prototype.$$init = function () {
- var i, cr;
-
- this.$$scriptNode = ActiveAudioContext.createScriptProcessor(this.$$bufferSize, 1, 1);
- this.$$scriptNode.onaudioprocess = this.onAudioProcess.bind(this);
-
- this.$$analyserNode = ActiveAudioContext.createAnalyser();
- this.$$analyserNode.fftSize = ChannelReceiveManager.$$_LOWEST_FFT_SIZE;
-
- this.$$scriptNode.connect(this.$$analyserNode);
-
- for (i = 0; i < this.$$configuration.length; i++) {
- cr = ChannelReceiveBuilder.build(i, this.$$configuration[i]);
- this.$$channelReceive.push(cr);
- }
- };
-
- ChannelReceiveManager.prototype.onAudioProcess = function (audioProcessingEvent) {
- var
- inputBuffer = audioProcessingEvent.inputBuffer,
- inputData = inputBuffer.getChannelData(0),
- blockBeginTime = ActiveAudioContext.getCurrentTime(),
- sample, sampleNumberInBlock, j
- ;
-
- for (sampleNumberInBlock = 0; sampleNumberInBlock < inputBuffer.length; sampleNumberInBlock++) {
- sample = inputData[sampleNumberInBlock];
-
- for (j = 0; j < this.$$channelReceive.length; j++) {
- this.$$channelReceive[j].handleSample(
- sample,
- this.$$sampleNumberGlobal,
- blockBeginTime,
- sampleNumberInBlock
- );
- }
-
- this.$$sampleNumberGlobal++;
- }
-
- this.$$computeCpuLoadData(blockBeginTime, ActiveAudioContext.getCurrentTime(), inputBuffer.length);
- };
-
- return ChannelReceiveManager;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayer.ChannelTransmitBuilder', _ChannelTransmitBuilder);
-
- _ChannelTransmitBuilder.$inject = [
- 'PhysicalLayer.ChannelTransmit'
- ];
-
- function _ChannelTransmitBuilder(
- ChannelTransmit
- ) {
-
- function build(index, configuration) {
- return new ChannelTransmit(index, configuration);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayer.ChannelTransmit', _ChannelTransmit);
-
- _ChannelTransmit.$inject = [
- 'Common.MathUtil',
- 'Audio.ActiveAudioContext',
- 'Common.CarrierGenerateBuilder'
- ];
-
- function _ChannelTransmit(
- MathUtil,
- ActiveAudioContext, // TODO remove that depencency - it's here only for sample rate
- CarrierGenerateBuilder
- ) {
- var ChannelTransmit;
-
- ChannelTransmit = function (index, configuration) {
- this.$$carrierGenerate = [];
- this.$$carrierFrequency = [];
- this.$$carrierPhaseCorrection = [];
- this.$$index = index;
-
- this.configure(configuration);
- };
-
- ChannelTransmit.DATA_LENGTH_DOES_NOT_MATCH_OFDM_SIZE_EXCEPTION = 'Data array length does not match configured OFDM size';
- ChannelTransmit.OFDM_INDEX_OUT_OF_RANGE_EXCEPTION = 'OFDM index out of range: ';
-
- ChannelTransmit.prototype.addToQueue = function (data) {
- var i;
-
- if (data.length !== this.$$carrierGenerate.length) {
- throw ChannelTransmit.DATA_LENGTH_DOES_NOT_MATCH_OFDM_SIZE_EXCEPTION;
- }
-
- for (i = 0; i < this.$$carrierGenerate.length; i++) {
- this.$$carrierGenerate[i].addToQueue(data[i]);
- }
- };
-
- ChannelTransmit.prototype.getOfdmSize = function () {
- return this.$$carrierGenerate.length;
- };
-
- ChannelTransmit.prototype.$$checkOfdmIndex = function (ofdmIndex) {
- if (ofdmIndex < 0 || ofdmIndex >= this.$$carrierGenerate.length) {
- throw ChannelTransmit.OFDM_INDEX_OUT_OF_RANGE_EXCEPTION + ofdmIndex;
- }
- };
-
- ChannelTransmit.prototype.getTxPhaseCorrection = function (ofdmIndex) {
- this.$$checkOfdmIndex(ofdmIndex);
-
- return this.$$carrierPhaseCorrection[ofdmIndex];
- };
-
- ChannelTransmit.prototype.getFrequency = function (ofdmIndex) {
- this.$$checkOfdmIndex(ofdmIndex);
-
- return this.$$carrierFrequency[ofdmIndex];
- };
-
- ChannelTransmit.prototype.setTxPhaseCorrection = function (ofdmIndex, phaseCorrection) {
- this.$$checkOfdmIndex(ofdmIndex);
-
- this.$$carrierPhaseCorrection[ofdmIndex] = phaseCorrection - MathUtil.floor(phaseCorrection);
- this.$$carrierGenerate[ofdmIndex].setPhaseCorrection(this.$$carrierPhaseCorrection[ofdmIndex]);
- };
-
- ChannelTransmit.prototype.setFrequency = function (ofdmIndex, frequency) {
- var samplePerPeriod;
-
- this.$$checkOfdmIndex(ofdmIndex);
-
- samplePerPeriod = ActiveAudioContext.getSampleRate() / frequency;
- this.$$carrierGenerate[ofdmIndex].setSamplePerPeriod(samplePerPeriod);
- this.$$carrierFrequency[ofdmIndex] = frequency;
- };
-
- ChannelTransmit.prototype.configure = function (configuration) {
- var i, cg, samplePerPeriod, frequency;
-
- for (i = 0; i < configuration.ofdmSize; i++) {
- frequency = configuration.baseFrequency + i * configuration.ofdmFrequencySpacing;
- samplePerPeriod = ActiveAudioContext.getSampleRate() / frequency;
- cg = CarrierGenerateBuilder.build(samplePerPeriod);
- this.$$carrierGenerate.push(cg);
- this.$$carrierFrequency.push(frequency);
- this.$$carrierPhaseCorrection.push(0);
- }
- };
-
- ChannelTransmit.prototype.getSample = function () {
- var sample, cg, i;
-
- sample = 0;
- for (i = 0; i < this.$$carrierGenerate.length; i++) {
- cg = this.$$carrierGenerate[i];
- sample += cg.getSample();
- cg.nextSample();
- }
-
- return sample;
- };
-
- ChannelTransmit.prototype.destroy = function () {
- this.$$carrierGenerate.length = 0;
- this.$$carrierFrequency.length = 0;
- this.$$carrierPhaseCorrection.length = 0;
- };
-
- return ChannelTransmit;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayer.ChannelTransmitManagerBuilder', _ChannelTransmitManagerBuilder);
-
- _ChannelTransmitManagerBuilder.$inject = [
- 'PhysicalLayer.ChannelTransmitManager'
- ];
-
- function _ChannelTransmitManagerBuilder(
- ChannelTransmitManager
- ) {
-
- function build(configuration, bufferSize) {
- return new ChannelTransmitManager(configuration, bufferSize);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayer.ChannelTransmitManager', _ChannelTransmitManager);
-
- _ChannelTransmitManager.$inject = [
- 'PhysicalLayer.AbstractChannelManager',
- 'Common.MathUtil',
- 'Audio.ActiveAudioContext',
- 'PhysicalLayer.DefaultConfig',
- 'PhysicalLayer.ChannelTransmitBuilder'
- ];
-
- function _ChannelTransmitManager(
- AbstractChannelManager,
- MathUtil,
- ActiveAudioContext,
- DefaultConfig,
- ChannelTransmitBuilder
- ) {
- var ChannelTransmitManager;
-
- ChannelTransmitManager = function (configuration, bufferSize) {
- AbstractChannelManager.apply(this, arguments);
-
- this.$$channelTransmit = [];
- this.$$scriptNode = null;
- this.$$configuration = configuration;
- this.$$bufferSize = bufferSize;
- this.$$fakeNoise = false;
-
- this.$$init();
- };
-
- ChannelTransmitManager.prototype = Object.create(AbstractChannelManager.prototype);
- ChannelTransmitManager.prototype.constructor = ChannelTransmitManager;
-
- ChannelTransmitManager.CHANNEL_INDEX_OUT_OF_RANGE_EXCEPTION = 'Channel index out of range: ';
-
- ChannelTransmitManager.prototype.destroy = function () {
- var i, ct;
-
- for (i = 0; i < this.$$channelTransmit.length; i++) {
- ct = this.$$channelTransmit[i];
- ct.destroy();
- }
- this.$$channelTransmit.length = 0;
- };
-
- ChannelTransmitManager.prototype.getOutputNode = function () {
- return this.$$scriptNode;
- };
-
- ChannelTransmitManager.prototype.getChannelSize = function () {
- return this.$$channelTransmit.length;
- };
-
- ChannelTransmitManager.prototype.getChannel = function (channelIndex) {
- if (channelIndex < 0 || channelIndex >= this.$$channelTransmit.length) {
- throw ChannelTransmitManager.CHANNEL_INDEX_OUT_OF_RANGE_EXCEPTION + channelIndex;
- }
-
- return this.$$channelTransmit[channelIndex];
- };
-
- ChannelTransmitManager.prototype.getBufferSize = function () {
- return this.$$scriptNode.bufferSize;
- };
-
- ChannelTransmitManager.prototype.$$init = function () {
- var i, ct;
-
- this.$$scriptNode = ActiveAudioContext.createScriptProcessor(this.$$bufferSize, 1, 1);
- this.$$scriptNode.onaudioprocess = this.onAudioProcess.bind(this);
-
- for (i = 0; i < this.$$configuration.length; i++) {
- ct = ChannelTransmitBuilder.build(i, this.$$configuration[i]);
- this.$$channelTransmit.push(ct);
- }
- };
-
- ChannelTransmitManager.prototype.enableFakeNoise = function () {
- this.$$fakeNoise = true;
- };
-
- ChannelTransmitManager.prototype.disableFakeNoise = function () {
- this.$$fakeNoise = false;
- };
-
- ChannelTransmitManager.prototype.onAudioProcess = function (audioProcessingEvent) {
- var
- outputBuffer = audioProcessingEvent.outputBuffer,
- outputData = outputBuffer.getChannelData(0),
- blockBeginTime = ActiveAudioContext.getCurrentTime(),
- sample, i, j
- ;
-
- for (i = 0; i < outputBuffer.length; i++) {
- sample = 0;
- for (j = 0; j < this.$$channelTransmit.length; j++) {
- sample += this.$$channelTransmit[j].getSample();
- }
-
- if (this.$$fakeNoise) {
- sample += ((MathUtil.random() * 2) - 1) * DefaultConfig.FAKE_NOISE_MAX_AMPLITUDE;
- }
-
- outputData[i] = sample;
- }
-
- this.$$computeCpuLoadData(blockBeginTime, ActiveAudioContext.getCurrentTime(), outputBuffer.length);
- };
-
- return ChannelTransmitManager;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayer.RxHandlerBuilder', _RxHandlerBuilder);
-
- _RxHandlerBuilder.$inject = [
- 'PhysicalLayer.RxHandler'
- ];
-
- function _RxHandlerBuilder(
- RxHandler
- ) {
-
- function build(rxConstellationDiagram, rxExternalHandler) {
- return new RxHandler(rxConstellationDiagram, rxExternalHandler);
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayer.RxHandler', _RxHandler);
-
- _RxHandler.$inject = [
- 'PhysicalLayer.DefaultConfig',
- 'Audio.ActiveAudioContext',
- 'Common.MathUtil'
- ];
-
- function _RxHandler(
- DefaultConfig,
- ActiveAudioContext,
- MathUtil
- ) {
- var RxHandler;
-
- RxHandler = function (rxConstellationDiagram, rxExternalHandler) {
- this.$$delayedData = [];
- this.$$rxConstellationDiagram = rxConstellationDiagram;
- this.$$rxExternalHandler = rxExternalHandler;
- this.$$intervalId = setInterval(this.$$intervalHandler.bind(this), RxHandler.$$_DELAY_LOOP_RESOLUTION);
- };
-
- RxHandler.$$_RX_EXTRA_DELAY = 0.05; // [sec]
- RxHandler.$$_DELAY_LOOP_RESOLUTION = 8; // [ms]
-
- RxHandler.prototype.$$intervalHandler = function () {
- var
- currentTime = ActiveAudioContext.getCurrentTime(),
- removedCount = 0,
- item, i
- ;
-
- for (i = 0; i < this.$$delayedData.length; i++) {
- item = this.$$delayedData[i];
-
- if (item.time < (currentTime - RxHandler.$$_RX_EXTRA_DELAY)) {
- this.$$handle(
- item.channelIndex,
- item.carrierDetail,
- item.time
- );
- removedCount++;
- } else {
- break;
- }
- }
-
- /*
- // TODO enable if needed
- if (console && removedCount > 1) {
- console.log('Delay loop warning - processed more than one rx item: ' + removedCount);
- }
- */
-
- if (removedCount > 0) {
- this.$$delayedData.splice(0, removedCount);
- }
- };
-
- RxHandler.prototype.handle = function (channelIndex, carrierDetail, time) {
- this.$$delayedData.push({
- channelIndex: channelIndex,
- carrierDetail: carrierDetail,
- time: time
- });
- };
-
- RxHandler.prototype.$$handle = function (channelIndex, carrierDetail, time) {
- var i, cd, queue;
-
- for (i = 0; i < carrierDetail.length; i++) {
- cd = carrierDetail[i];
- if (cd.powerDecibel === -Infinity) {
- cd.powerDecibel = DefaultConfig.MINIMUM_POWER_DECIBEL;
- }
- cd.powerDecibel = cd.powerDecibel < DefaultConfig.MINIMUM_POWER_DECIBEL ? DefaultConfig.MINIMUM_POWER_DECIBEL : cd.powerDecibel;
-
- if (this.$$rxConstellationDiagram.length === 0) {
- continue;
- }
-
- queue = this.$$rxConstellationDiagram[channelIndex].queue[i];
- queue.pushEvenIfFull({
- powerDecibel: cd.powerDecibel,
- phase: cd.phase
- });
- }
-
- if (this.$$rxExternalHandler.callback) {
- this.$$rxExternalHandler.callback(channelIndex, carrierDetail, ActiveAudioContext.getCurrentTime());
- }
- };
-
- RxHandler.prototype.destroy = function () {
- clearInterval(this.$$intervalId);
- };
-
- return RxHandler;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayerAdapter.GuardPowerCollectorBuilder', _GuardPowerCollectorBuilder);
-
- _GuardPowerCollectorBuilder.$inject = [
- 'PhysicalLayerAdapter.GuardPowerCollector'
- ];
-
- function _GuardPowerCollectorBuilder(
- GuardPowerCollector
- ) {
-
- function build() {
- return new GuardPowerCollector();
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayerAdapter.GuardPowerCollector', _GuardPowerCollector);
-
- _GuardPowerCollector.$inject = [
- 'Common.AbstractValueCollector',
- 'Common.MathUtil'
- ];
-
- function _GuardPowerCollector(
- AbstractValueCollector,
- MathUtil
- ) {
- var GuardPowerCollector;
-
- GuardPowerCollector = function () {
- AbstractValueCollector.apply(this, arguments);
- };
-
- GuardPowerCollector.prototype = Object.create(AbstractValueCollector.prototype);
- GuardPowerCollector.prototype.constructor = GuardPowerCollector;
-
- GuardPowerCollector.EMPTY_LIST_EXCEPTION = 'Cannot finalize GuardPowerCollector without any samples collected';
-
- GuardPowerCollector.prototype.$$finalize = function () {
- if (this.$$valueList.length === 0) {
- throw GuardPowerCollector.EMPTY_LIST_EXCEPTION;
- }
-
- return MathUtil.minInArray(this.$$valueList);
- };
-
- return GuardPowerCollector;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayerAdapter.PhaseOffsetCollectorBuilder', _PhaseOffsetCollectorBuilder);
-
- _PhaseOffsetCollectorBuilder.$inject = [
- 'PhysicalLayerAdapter.PhaseOffsetCollector'
- ];
-
- function _PhaseOffsetCollectorBuilder(
- PhaseOffsetCollector
- ) {
-
- function build() {
- return new PhaseOffsetCollector();
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayerAdapter.PhaseOffsetCollector', _PhaseOffsetCollector);
-
- _PhaseOffsetCollector.$inject = [
- 'Common.AbstractValueCollector',
- 'Common.MathUtil'
- ];
-
- function _PhaseOffsetCollector(
- AbstractValueCollector,
- MathUtil
- ) {
- var PhaseOffsetCollector;
-
- PhaseOffsetCollector = function () {
- AbstractValueCollector.apply(this, arguments);
- };
-
- PhaseOffsetCollector.prototype = Object.create(AbstractValueCollector.prototype);
- PhaseOffsetCollector.prototype.constructor = PhaseOffsetCollector;
-
- PhaseOffsetCollector.prototype.$$finalize = function () {
- var
- i, indexA, indexB, drift,
- str = '';
-
- if (this.$$valueList.length === 0) {
- return null;
- }
-
- // TODO rewrite this temporary code
- for (i = 0; i < this.$$valueList.length; i++) {
- str += (
- (MathUtil.round(this.$$valueList[i].time * 1000) / 1000) + ' ' +
- (MathUtil.round(this.$$valueList[i].phase * 1000) / 1000) + ' | '
- );
- }
-
- indexA = MathUtil.round(0.43 * this.$$valueList.length);
- indexB = MathUtil.round(0.57 * this.$$valueList.length);
- indexB = indexB >= this.$$valueList.length ? this.$$valueList.length - 1 : indexB;
- drift = 0;
- if (indexA !== indexB && indexA < indexB) {
- console.log('phase history indexA', this.$$valueList[indexA].time, this.$$valueList[indexA].phase);
- console.log('phase history indexB', this.$$valueList[indexB].time, this.$$valueList[indexB].phase);
- drift = -(this.$$valueList[indexB].phase - this.$$valueList[indexA].phase) / (this.$$valueList[indexB].time - this.$$valueList[indexA].time);
- console.log('phase history drift', drift);
- }
-
- return drift;
- };
-
- PhaseOffsetCollector.prototype.collect = function (value) {
- // TODO rewrite this temporary code
- this.$$valueList.push({
- time: value.stateDurationTime,
- phase: value.carrierDetail[0].phase // TODO pass all ofdm phases here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- }); // TODO check also powerThreshold to avoid fine-tune on null OFDMs
- };
-
- return PhaseOffsetCollector;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayerAdapter.RxStateMachineBuilder', _RxStateMachineBuilder);
-
- _RxStateMachineBuilder.$inject = [
- 'PhysicalLayerAdapter.RxStateMachine'
- ];
-
- function _RxStateMachineBuilder(
- RxStateMachine
- ) {
-
- function build(handlerIdleInit, handlerFirstSyncWait, handlerFirstSync, handlerFatalError, handlerIdle, handlerSymbol, handlerSync, handlerGuard, handlerError) {
- return new RxStateMachine(
- handlerIdleInit,
- handlerFirstSyncWait,
- handlerFirstSync,
- handlerFatalError,
- handlerIdle,
- handlerSymbol,
- handlerSync,
- handlerGuard,
- handlerError
- );
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayerAdapter.RxStateMachine', _RxStateMachine);
-
- _RxStateMachine.$inject = [
- 'PhysicalLayerAdapter.ReceiveAdapterState'
- ];
-
- function _RxStateMachine(
- ReceiveAdapterState
- ) {
- var RxStateMachine;
-
- RxStateMachine = function (handlerIdleInit, handlerFirstSyncWait, handlerFirstSync, handlerFatalError, handlerIdle, handlerSymbol, handlerSync, handlerGuard, handlerError) {
- this.$$stateHandler = {};
- this.$$stateHandler[ReceiveAdapterState.IDLE_INIT] = handlerIdleInit;
- this.$$stateHandler[ReceiveAdapterState.FIRST_SYNC_WAIT] = handlerFirstSyncWait;
- this.$$stateHandler[ReceiveAdapterState.FIRST_SYNC] = handlerFirstSync;
- this.$$stateHandler[ReceiveAdapterState.FATAL_ERROR] = handlerFatalError;
- this.$$stateHandler[ReceiveAdapterState.IDLE] = handlerIdle;
- this.$$stateHandler[ReceiveAdapterState.SYMBOL] = handlerSymbol;
- this.$$stateHandler[ReceiveAdapterState.SYNC] = handlerSync;
- this.$$stateHandler[ReceiveAdapterState.GUARD] = handlerGuard;
- this.$$stateHandler[ReceiveAdapterState.ERROR] = handlerError;
- this.$$symbolStateMaxDurationTime = null;
- this.$$guardStateMaxDurationTime = null;
- this.$$syncStateMaxDurationTime = null;
-
- this.$$state = null;
- this.$$stateDurationTime = null;
- this.$$stateBeginTime = null;
- this.$$resetFlag = true;
- };
-
- RxStateMachine.SET_ALL_MAX_DURATION_TIMES_FIRST_EXCEPTION = 'Please set all max duration times first';
-
- RxStateMachine.prototype.scheduleReset = function () {
- this.$$resetFlag = true;
- };
-
- RxStateMachine.prototype.$$changeState = function (newState, time) {
- if (newState !== null) {
- this.$$state = newState;
- this.$$stateBeginTime = time;
- } else {
- this.$$stateDurationTime = time - this.$$stateBeginTime;
- }
- };
-
- RxStateMachine.prototype.$$handlerIdleInit = function (pilotSignalPresent, time) {
- var newState;
-
- this.$$changeState(null, time);
-
- // run external handler
- newState = this.$$stateHandler[ReceiveAdapterState.IDLE_INIT](this.$$stateDurationTime);
-
- if (newState) {
- this.$$changeState(newState, time);
- return false;
- }
-
- return true;
- };
-
- RxStateMachine.prototype.$$handlerFirstSyncWait = function (pilotSignalPresent, time) {
- if (pilotSignalPresent) {
- this.$$changeState(ReceiveAdapterState.FIRST_SYNC, time);
- return false;
- } else {
- this.$$changeState(null, time);
-
- // run external handler
- this.$$stateHandler[ReceiveAdapterState.FIRST_SYNC_WAIT](this.$$stateDurationTime);
- }
-
- return true;
- };
-
- RxStateMachine.prototype.$$handlerFirstSync = function (pilotSignalPresent, time) {
- var newState;
-
- this.$$changeState(null, time);
-
- // run external handler
- newState = this.$$stateHandler[ReceiveAdapterState.FIRST_SYNC](this.$$stateDurationTime);
-
- if (newState) {
- this.$$changeState(newState, time);
- return false;
- }
-
- return true;
- };
-
- RxStateMachine.prototype.$$handlerFatalError = function (pilotSignalPresent, time) {
- var newState;
-
- this.$$changeState(null, time);
-
- // run external handler
- newState = this.$$stateHandler[ReceiveAdapterState.FATAL_ERROR](this.$$stateDurationTime);
-
- if (newState) {
- this.$$changeState(newState, time);
- return false;
- }
-
- return true;
- };
-
- RxStateMachine.prototype.$$handlerIdle = function (pilotSignalPresent, time) {
- if (pilotSignalPresent) {
- this.$$changeState(ReceiveAdapterState.SYMBOL, time);
- return false;
- } else {
- this.$$changeState(null, time);
-
- // run external handler
- this.$$stateHandler[ReceiveAdapterState.IDLE](this.$$stateDurationTime);
- }
-
- return true;
- };
-
- RxStateMachine.prototype.$$handlerSymbol = function (pilotSignalPresent, time) {
- if (!pilotSignalPresent) {
- this.$$changeState(ReceiveAdapterState.GUARD, time);
- return false;
- } else {
- this.$$changeState(null, time);
-
- // run external handler
- this.$$stateHandler[ReceiveAdapterState.SYMBOL](this.$$stateDurationTime);
-
- if (this.$$stateDurationTime > this.$$symbolStateMaxDurationTime) {
- this.$$changeState(ReceiveAdapterState.SYNC, time);
- return false;
- }
- }
-
- return true;
- };
-
- RxStateMachine.prototype.$$handlerSync = function (pilotSignalPresent, time) {
- if (!pilotSignalPresent) {
- this.$$changeState(ReceiveAdapterState.IDLE, time);
- return false;
- } else {
- this.$$changeState(null, time);
-
- // run external handler
- this.$$stateHandler[ReceiveAdapterState.SYNC](this.$$stateDurationTime);
-
- if (this.$$stateDurationTime > this.$$syncStateMaxDurationTime) {
- this.$$changeState(ReceiveAdapterState.ERROR, time);
- return false;
- }
- }
-
- return true;
- };
-
- RxStateMachine.prototype.$$handlerGuard = function (pilotSignalPresent, time) {
- if (pilotSignalPresent) {
- this.$$changeState(ReceiveAdapterState.SYMBOL, time);
- return false;
- } else {
- this.$$changeState(null, time);
-
- // run external handler
- this.$$stateHandler[ReceiveAdapterState.GUARD](this.$$stateDurationTime);
-
- if (this.$$stateDurationTime > this.$$guardStateMaxDurationTime) {
- this.$$changeState(ReceiveAdapterState.IDLE, time);
- return false;
- }
- }
-
- return true;
- };
-
- RxStateMachine.prototype.$$handlerError = function (pilotSignalPresent, time) {
- if (!pilotSignalPresent) {
- this.$$changeState(ReceiveAdapterState.IDLE, time);
- return false;
- } else {
- this.$$changeState(null, time);
-
- // run external handler
- this.$$stateHandler[ReceiveAdapterState.ERROR](this.$$stateDurationTime);
- }
-
- return true;
- };
-
- RxStateMachine.prototype.setGuardStateMaxDurationTime = function (time) {
- this.$$guardStateMaxDurationTime = time;
- };
-
- RxStateMachine.prototype.setSymbolStateMaxDurationTime = function (time) {
- this.$$symbolStateMaxDurationTime = time;
- };
-
- RxStateMachine.prototype.setSyncStateMaxDurationTime = function (time) {
- this.$$syncStateMaxDurationTime = time;
- };
-
- RxStateMachine.prototype.getState = function (pilotSignalPresent, time) {
- var
- S = ReceiveAdapterState,
- finished
- ;
-
- if (this.$$resetFlag) {
- this.$$changeState(S.IDLE_INIT, time);
- this.$$resetFlag = false;
- }
-
- if (
- this.$$guardStateMaxDurationTime === null ||
- this.$$symbolStateMaxDurationTime === null ||
- this.$$syncStateMaxDurationTime === null
- ) {
- throw RxStateMachine.SET_ALL_MAX_DURATION_TIMES_FIRST_EXCEPTION;
- }
-
- while (true) {
- switch (this.$$state) {
- case S.IDLE_INIT:
- finished = this.$$handlerIdleInit(pilotSignalPresent, time);
- break;
- case S.FIRST_SYNC_WAIT:
- finished = this.$$handlerFirstSyncWait(pilotSignalPresent, time);
- break;
- case S.FIRST_SYNC:
- finished = this.$$handlerFirstSync(pilotSignalPresent, time);
- break;
- case S.FATAL_ERROR:
- finished = this.$$handlerFatalError(pilotSignalPresent, time);
- break;
- case S.IDLE:
- finished = this.$$handlerIdle(pilotSignalPresent, time);
- break;
- case S.SYMBOL:
- finished = this.$$handlerSymbol(pilotSignalPresent, time);
- break;
- case S.SYNC:
- finished = this.$$handlerSync(pilotSignalPresent, time);
- break;
- case S.GUARD:
- finished = this.$$handlerGuard(pilotSignalPresent, time);
- break;
- case S.ERROR:
- finished = this.$$handlerError(pilotSignalPresent, time);
- break;
- }
-
- if (finished) {
- break;
- }
- }
- return this.$$state;
- };
-
- return RxStateMachine;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayerAdapter.RxStateMachineManagerBuilder', _RxStateMachineManagerBuilder);
-
- _RxStateMachineManagerBuilder.$inject = [
- 'PhysicalLayerAdapter.RxStateMachineManager'
- ];
-
- function _RxStateMachineManagerBuilder(
- RxStateMachineManager
- ) {
-
- function build(channelIndex, packetReceiveHandler, frequencyUpdateHandler, phaseCorrectionUpdateHandler) {
- return new RxStateMachineManager(
- channelIndex,
- packetReceiveHandler,
- frequencyUpdateHandler,
- phaseCorrectionUpdateHandler
- );
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayerAdapter.RxStateMachineManager', _RxStateMachineManager);
-
- _RxStateMachineManager.$inject = [
- 'Common.MathUtil',
- 'Common.Util',
- 'Common.AverageValueCollectorBuilder',
- 'PhysicalLayer.DefaultConfig',
- 'PhysicalLayerAdapter.SignalPowerCollectorBuilder',
- 'PhysicalLayerAdapter.GuardPowerCollectorBuilder',
- 'PhysicalLayerAdapter.PhaseOffsetCollectorBuilder',
- 'PhysicalLayerAdapter.RxStateMachineBuilder',
- 'PhysicalLayerAdapter.ReceiveAdapterState'
- ];
-
- function _RxStateMachineManager(
- MathUtil,
- Util,
- AverageValueCollectorBuilder,
- DefaultConfig,
- SignalPowerCollectorBuilder,
- GuardPowerCollectorBuilder,
- PhaseOffsetCollectorBuilder,
- RxStateMachineBuilder,
- ReceiveAdapterState
- ) {
- var RxStateMachineManager;
-
- RxStateMachineManager = function (channelIndex, packetReceiveHandler, frequencyUpdateHandler, phaseCorrectionUpdateHandler) {
- this.$$channelIndex = channelIndex;
-
- this.$$packetReceiveHandler = packetReceiveHandler;
- this.$$frequencyUpdateHandler = frequencyUpdateHandler;
- this.$$phaseCorrectionUpdateHandler = phaseCorrectionUpdateHandler;
-
- this.$$stateMachine = RxStateMachineBuilder.build(
- this.$$handlerIdleInit.bind(this),
- this.$$handlerFirstSyncWait.bind(this),
- this.$$handlerFirstSync.bind(this),
- this.$$handlerFatalError.bind(this),
- this.$$handlerIdle.bind(this),
- this.$$handlerSymbol.bind(this),
- this.$$handlerSync.bind(this),
- this.$$handlerGuard.bind(this),
- this.$$handlerError.bind(this)
- );
-
- this.$$sampleCollectionTimeIdleInitState = null;
- this.$$sampleCollectionTimeFirstSyncState = null;
- this.$$syncPreamble = null;
- this.$$pskSize = null;
-
- this.$$averageIdlePowerCollector = AverageValueCollectorBuilder.build();
- this.$$averageFirstSyncPowerCollector = AverageValueCollectorBuilder.build();
- this.$$signalPowerCollector = SignalPowerCollectorBuilder.build();
- this.$$guardPowerCollector = GuardPowerCollectorBuilder.build();
- this.$$phaseOffsetCollector = PhaseOffsetCollectorBuilder.build();
-
- this.$$resetInternal();
- };
-
- RxStateMachineManager.$$_INITIAL_POWER_THRESHOLD = 0; // after init we need to listen to noise so this threshold should prevent catching all possible signals
- RxStateMachineManager.$$_DECIBLES_ABOVE_AVERAGE_IDLE = 10; // decibels above average idle power (ambient noise) in order to catch first, even weak, signal - it means that you should keep this value low
- RxStateMachineManager.$$_OFDM_PILOT_SIGNAL_INDEX = 0;
- RxStateMachineManager.$$_AVERAGE_POWER_UNIT_FACTOR = 0.5; // 0.0 -> closer to average 'idle' power, 1.0 -> closer to average 'first sync' power
-
- RxStateMachineManager.prototype.$$resetInternal = function () {
- this.$$averageIdlePowerCollector.clearAll();
- this.$$averageFirstSyncPowerCollector.clearAll();
- this.$$signalPowerCollector.clearAll();
- this.$$guardPowerCollector.clearAll();
- this.$$phaseOffsetCollector.clearAll();
-
- this.$$powerThreshold = RxStateMachineManager.$$_INITIAL_POWER_THRESHOLD;
-
- this.$$currentData = null;
- this.$$dataPacket = [];
- this.$$dataSymbol = [];
- };
-
- RxStateMachineManager.prototype.reset = function () {
- this.$$resetInternal();
- this.$$stateMachine.scheduleReset();
- };
-
- RxStateMachineManager.prototype.setSymbolStateMaxDurationTime = function (value) {
- this.$$stateMachine.setSymbolStateMaxDurationTime(value);
- };
-
- RxStateMachineManager.prototype.setGuardStateMaxDurationTime = function (value) {
- this.$$stateMachine.setGuardStateMaxDurationTime(value);
- };
-
- RxStateMachineManager.prototype.setSyncStateMaxDurationTime = function (value) {
- this.$$stateMachine.setSyncStateMaxDurationTime(value);
- };
-
- RxStateMachineManager.prototype.setSampleCollectionTimeIdleInitState = function (value) {
- this.$$sampleCollectionTimeIdleInitState = value;
- };
-
- RxStateMachineManager.prototype.setSampleCollectionTimeFirstSyncState = function (value) {
- this.$$sampleCollectionTimeFirstSyncState = value;
- };
-
- RxStateMachineManager.prototype.setSyncPreamble = function (value) {
- this.$$syncPreamble = value;
- };
-
- RxStateMachineManager.prototype.setPskSize = function (value) {
- this.$$pskSize = value;
- };
-
- RxStateMachineManager.prototype.$$handlerIdleInit = function (stateDurationTime) {
- var
- powerDecibel = this.$$currentData.pilotSignal.powerDecibel,
- handlerResult = null
- ;
-
- if (stateDurationTime < this.$$sampleCollectionTimeIdleInitState) {
- this.$$averageIdlePowerCollector.collect(powerDecibel);
- } else {
- try {
- // put first power threshold slightly above collected noise power to detect even weak signals
- this.$$powerThreshold = this.$$averageIdlePowerCollector.finalize() + RxStateMachineManager.$$_DECIBLES_ABOVE_AVERAGE_IDLE;
- handlerResult = ReceiveAdapterState.FIRST_SYNC_WAIT;
- } catch (e) {
- handlerResult = ReceiveAdapterState.FATAL_ERROR;
- }
- }
-
- return handlerResult;
- };
-
- RxStateMachineManager.prototype.$$handlerFirstSyncWait = function (stateDurationTime) {
- // nothing much here - user needs to send 'Sync' signal on the other device, we can just wait...
- return null;
- };
-
- RxStateMachineManager.prototype.$$handlerFirstSync = function (stateDurationTime) {
- var
- powerDecibel = this.$$currentData.pilotSignal.powerDecibel,
- averageFirstSyncPower, averageIdlePower, powerDifference
- ;
-
- // TODO refactor code block order - condition below happens actually at FIRST_SYNC state end
- if (this.$$averageFirstSyncPowerCollector.getLastFinalizedResult()) {
- // wait until signal will drop below threshold
- if (powerDecibel < this.$$powerThreshold) {
- return ReceiveAdapterState.IDLE;
- } else {
- return null;
- }
- }
-
- // signal cannot be weaker than previously stored average idle noise... :)
- if (powerDecibel <= this.$$averageIdlePowerCollector.getLastFinalizedResult()) {
- return ReceiveAdapterState.FATAL_ERROR;
- }
-
- if (stateDurationTime < this.$$sampleCollectionTimeFirstSyncState) {
- // collect phase history for all OFDM subcarriers - it will be later used for fine-tune frequency offsets
- this.$$phaseOffsetCollector.collect({
- stateDurationTime: stateDurationTime,
- carrierDetail: this.$$currentData.carrierDetail
- });
-
- // collect desired signal power history and later compute average signal power and power threshold
- this.$$averageFirstSyncPowerCollector.collect(powerDecibel);
- } else {
- try {
- averageFirstSyncPower = this.$$averageFirstSyncPowerCollector.finalize(); // this line may trow error
- averageIdlePower = this.$$averageIdlePowerCollector.getLastFinalizedResult();
- powerDifference = averageFirstSyncPower - averageIdlePower;
-
- // put threshold somewhere (depending on unit factor) between average idle power and average first sync power
- this.$$powerThreshold = averageIdlePower + RxStateMachineManager.$$_AVERAGE_POWER_UNIT_FACTOR * powerDifference;
- } catch (e) {
- return ReceiveAdapterState.FATAL_ERROR;
- }
- }
- };
-
- RxStateMachineManager.prototype.$$handlerFatalError = function (stateDurationTime) {
- // nothing much here - only way to escape from this state is to reset Receive Adapter
- };
-
- RxStateMachineManager.prototype.$$handlerIdle = function (stateDurationTime) {
- // share collected packet with rest of the world
- if (this.$$dataPacket.length > 0) {
- this.$$packetReceiveHandler(this.$$channelIndex, this.$$preparePacket(this.$$dataPacket));
- this.$$dataPacket.length = 0;
- }
-
- // fine-tune frequency offsets basing on phase history if any
- if (this.$$phaseOffsetCollector.hasAtLeastItem()) {
- this.$$frequencyUpdateHandler(this.$$channelIndex, this.$$phaseOffsetCollector.finalize());
- }
-
- // clear collected guard history from last 'GUARD' state because it was followed
- // directly by IDLE state so technically it wasn't GUARD state at all
- this.$$guardPowerCollector.clearList();
- };
-
- RxStateMachineManager.prototype.$$handlerSymbol = function (stateDurationTime) {
- var powerDecibel = this.$$currentData.pilotSignal.powerDecibel;
-
- // code below stores information about quality of incoming packets in the real time
- this.$$signalPowerCollector.collect(powerDecibel);
- if (this.$$guardPowerCollector.hasAtLeastItem()) {
- this.$$guardPowerCollector.finalize();
- }
-
- // add current signal sample to list
- this.$$dataSymbol.push(this.$$currentData);
- };
-
- RxStateMachineManager.prototype.$$handlerSync = function (stateDurationTime) {
- // collect phase history for all OFDM subcarriers - it will be later used for fine-tune frequency offsets
- this.$$phaseOffsetCollector.collect({
- stateDurationTime: stateDurationTime,
- carrierDetail: this.$$currentData.carrierDetail
- });
- };
-
- RxStateMachineManager.prototype.$$handlerGuard = function (stateDurationTime) {
- var
- powerDecibel = this.$$currentData.pilotSignal.powerDecibel,
- bestQualityIndex
- ;
-
- // code below stores information about quality of incoming packets in the real time
- this.$$guardPowerCollector.collect(powerDecibel);
- if (this.$$signalPowerCollector.hasAtLeastItem()) {
- this.$$signalPowerCollector.finalize();
- }
-
- // find best signal sample and add to current packet
- if (this.$$dataSymbol.length > 0) {
- bestQualityIndex = Util.findMaxValueIndex(this.$$dataSymbol, 'pilotSignal.powerDecibel');
- this.$$dataPacket.push(
- this.$$dataSymbol[bestQualityIndex].carrierDetail
- );
- if (this.$$isCurrentSymbolSyncPreamble()) {
- this.$$phaseCorrectionUpdateHandler(this.$$channelIndex, this.$$dataSymbol[bestQualityIndex].carrierDetail);
- }
- this.$$dataSymbol = [];
- }
- };
-
- RxStateMachineManager.prototype.$$handlerError = function (stateDurationTime) {
- // nothing much here - this state will automatically transit to idle when pilot signal will be gone
- };
-
- RxStateMachineManager.prototype.$$preparePacket = function (dataPacket) {
- var i, j, result, ofdmList, carrierDetail;
-
- result = [];
- for (i = 0; i < dataPacket.length; i++) {
- if (i === 0 && this.$$syncPreamble) {
- // when syncPreamble is true then first burst is used only for phase
- // alignment - we can simply omit it in the final packet
- continue;
- }
- carrierDetail = dataPacket[i];
- ofdmList = [];
- for (j = 0; j < carrierDetail.length; j++) {
- ofdmList.push(
- MathUtil.round(carrierDetail[j].phase * this.$$pskSize) % this.$$pskSize
- );
- }
- result.push(ofdmList);
- }
-
- return result;
- };
-
- RxStateMachineManager.prototype.$$isCurrentSymbolSyncPreamble = function () {
- return this.$$syncPreamble && this.$$dataPacket.length === 1;
- };
-
- RxStateMachineManager.prototype.$$isInputReallyConnected = function () {
- return this.$$currentData.pilotSignal.powerDecibel !== DefaultConfig.MINIMUM_POWER_DECIBEL;
- };
-
- RxStateMachineManager.prototype.$$isPilotSignalPresent = function () {
- return this.$$currentData.pilotSignal.powerDecibel > this.$$powerThreshold;
- };
-
- RxStateMachineManager.prototype.receive = function (carrierDetail, time) {
- var state;
-
- // grab current data, this will be available at all handlers that will be called back by $$stateMachine
- this.$$currentData = {
- pilotSignal: carrierDetail[RxStateMachineManager.$$_OFDM_PILOT_SIGNAL_INDEX], // alias for pilot
- carrierDetail: carrierDetail
- };
-
- if (this.$$isInputReallyConnected()) {
- state = this.$$stateMachine.getState(this.$$isPilotSignalPresent(), time);
- } else {
- state = ReceiveAdapterState.NO_INPUT;
- this.reset();
- }
-
- return {
- state: state,
- // TODO clean that mess below, move data to some dedicated fields in return object
- power: (
- '
' +
- 'averageIdlePower: ' + MathUtil.round(this.$$averageIdlePowerCollector.getLastFinalizedResult() * 100) / 100 + '
' +
- 'averageFirstSyncPower: ' + MathUtil.round(this.$$averageFirstSyncPowerCollector.getLastFinalizedResult() * 100) / 100 + '
' +
- ' delta: ' + MathUtil.round((this.$$averageFirstSyncPowerCollector.getLastFinalizedResult() - this.$$averageIdlePowerCollector.getLastFinalizedResult()) * 100) / 100 + '
' +
- ' powerThreshold: ' + MathUtil.round(this.$$powerThreshold * 100) / 100 + '
' +
- 'minGuardPower: ' + MathUtil.round(this.$$guardPowerCollector.getLastFinalizedResult() * 100) / 100 + ' sampleSize: ' + this.$$guardPowerCollector.getLastFinalizedSize() + '
' +
- 'maxSignalPower: ' + MathUtil.round(this.$$signalPowerCollector.getLastFinalizedResult() * 100) / 100 + ' sampleSize: ' + this.$$signalPowerCollector.getLastFinalizedSize() + '
' +
- ' delta: ' + MathUtil.round((this.$$signalPowerCollector.getLastFinalizedResult() - this.$$guardPowerCollector.getLastFinalizedResult()) * 100) / 100 + '
' +
- ' idealPowerThreshold: ' + MathUtil.round(0.5 * (this.$$signalPowerCollector.getLastFinalizedResult() + this.$$guardPowerCollector.getLastFinalizedResult()) * 100) / 100 + '
'
- )
- };
- };
-
- return RxStateMachineManager;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayerAdapter.SignalPowerCollectorBuilder', _SignalPowerCollectorBuilder);
-
- _SignalPowerCollectorBuilder.$inject = [
- 'PhysicalLayerAdapter.SignalPowerCollector'
- ];
-
- function _SignalPowerCollectorBuilder(
- SignalPowerCollector
- ) {
-
- function build() {
- return new SignalPowerCollector();
- }
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayerAdapter.SignalPowerCollector', _SignalPowerCollector);
-
- _SignalPowerCollector.$inject = [
- 'Common.AbstractValueCollector',
- 'Common.MathUtil'
- ];
-
- function _SignalPowerCollector(
- AbstractValueCollector,
- MathUtil
- ) {
- var SignalPowerCollector;
-
- SignalPowerCollector = function () {
- AbstractValueCollector.apply(this, arguments);
- };
-
- SignalPowerCollector.prototype = Object.create(AbstractValueCollector.prototype);
- SignalPowerCollector.prototype.constructor = SignalPowerCollector;
-
- SignalPowerCollector.EMPTY_LIST_EXCEPTION = 'Cannot finalize SignalPowerCollector without any samples collected';
-
- SignalPowerCollector.prototype.$$finalize = function () {
- if (this.$$valueList.length === 0) {
- throw SignalPowerCollector.EMPTY_LIST_EXCEPTION;
- }
-
- return MathUtil.maxInArray(this.$$valueList);
- };
-
- return SignalPowerCollector;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Common.MathUtil', _MathUtil);
-
- _MathUtil.$inject = [];
-
- function _MathUtil() {
-
- function abs(v) {
- return Math.abs(v);
- }
-
- function asin(v) {
- return Math.asin(v);
- }
-
- function sqrt(v) {
- return Math.sqrt(v);
- }
-
- function round(v) {
- return Math.round(v);
- }
-
- function random() {
- return Math.random();
- }
-
- function floor(v) {
- return Math.floor(v);
- }
-
- function sin(v) {
- return Math.sin(v);
- }
-
- function cos(v) {
- return Math.cos(v);
- }
-
- function log(v) {
- return Math.log(v);
- }
-
- function minInArray(v) {
- return Math.min.apply(null, v);
- }
-
- function maxInArray(v) {
- return Math.max.apply(null, v);
- }
-
- return {
- LN10: Math.LN10,
- HALF_PI: 0.5 * Math.PI,
- TWO_PI: 2 * Math.PI,
- PI: Math.PI,
- abs: abs,
- floor: floor,
- asin: asin,
- sqrt: sqrt,
- round: round,
- random: random,
- sin: sin,
- cos: cos,
- log: log,
- minInArray: minInArray,
- maxInArray: maxInArray
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Common.SimplePromiseBuilder', _SimplePromiseBuilder);
-
- _SimplePromiseBuilder.$inject = [
- 'Common.SimplePromise'
- ];
-
- function _SimplePromiseBuilder(
- SimplePromise
- ) {
-
- function build() {
- return new SimplePromise();
- }
-
- function buildFromList(list) {
- var i, promise, thenCount, catchCount;
-
- promise = build();
- thenCount = 0;
- catchCount = 0;
- for (i = 0; i < list.length; i++) {
- list[i]
- .then(function () {
- thenCount++;
- })
- .catch(function () {
- catchCount++;
- })
- .finally(function () {
- if (thenCount + catchCount === list.length) {
- if (catchCount === 0) {
- promise.resolve();
- } else {
- promise.reject();
- }
- }
- });
- }
-
- return promise;
- }
-
- return {
- build: build,
- buildFromList: buildFromList
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Common.SimplePromise', _SimplePromise);
-
- _SimplePromise.$inject = [];
-
- function _SimplePromise() {
- var SimplePromise;
-
- SimplePromise = function () {
- this.$$state = null;
- this.$$value = undefined;
- this.$$then = null;
- this.$$catch = null;
- this.$$finally = null;
- };
-
- SimplePromise.$$STATE_RESOLVE = 0;
- SimplePromise.$$STATE_REJECT = 1;
-
- SimplePromise.prototype.$$callbackInvoke = function () {
- switch (this.$$state) {
- case SimplePromise.$$STATE_RESOLVE:
- if (this.$$then) {
- this.$$then(this.$$value);
- this.$$then = null;
- }
- if (this.$$finally) {
- this.$$finally(this.$$value);
- this.$$finally = null;
- }
- break;
- case SimplePromise.$$STATE_REJECT:
- if (this.$$catch) {
- this.$$catch(this.$$value);
- this.$$catch = null;
- }
- if (this.$$finally) {
- this.$$finally(this.$$value);
- this.$$finally = null;
- }
- break;
- }
- };
-
- SimplePromise.prototype.resolve = function (value) {
- if (this.$$state !== null) {
- return;
- }
-
- this.$$state = SimplePromise.$$STATE_RESOLVE;
- this.$$value = value;
- this.$$callbackInvoke();
- };
-
- SimplePromise.prototype.reject = function (value) {
- if (this.$$state !== null) {
- return;
- }
-
- this.$$state = SimplePromise.$$STATE_REJECT;
- this.$$value = value;
- this.$$callbackInvoke();
- };
-
- SimplePromise.prototype.then = function (callback) {
- if (typeof callback === 'function') {
- this.$$then = callback;
- }
- this.$$callbackInvoke();
- return this;
- };
-
- SimplePromise.prototype.catch = function (callback) {
- if (typeof callback === 'function') {
- this.$$catch = callback;
- }
- this.$$callbackInvoke();
- return this;
- };
-
- SimplePromise.prototype.finally = function (callback) {
- if (typeof callback === 'function') {
- this.$$finally = callback;
- }
- this.$$callbackInvoke();
- return this;
- };
-
- return SimplePromise;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Common.StopwatchBuilder', _StopwatchBuilder);
-
- _StopwatchBuilder.$inject = [
- 'Common.Stopwatch'
- ];
-
- function _StopwatchBuilder(
- Stopwatch
- ) {
-
- function build() {
- return new Stopwatch();
- }
-
-
- return {
- build: build
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('Common.Stopwatch', _Stopwatch);
-
- _Stopwatch.$inject = [
- ];
-
- function _Stopwatch(
- ) {
- var Stopwatch;
-
- Stopwatch = function () {
- this.$$running = false;
- this.$$timeStart = undefined;
- this.$$timeEnd = undefined;
- };
-
- Stopwatch.STOPWATCH_ALREADY_STARTED_EXCEPTION = 'Stopwatch already started';
- Stopwatch.STOPWATCH_ALREADY_STOPPED_EXCEPTION = 'Stopwatch already stopped';
- Stopwatch.RESET_BEFORE_CALLING_START_EXCEPTION = 'Reset stopwatch before calling start() again';
- Stopwatch.STOPWATCH_WAS_NOT_STARTED_EXCEPTION = 'stopwatch was not started';
-
- Stopwatch.$$_MILLISECOND_IN_SECOND = 1000;
-
- Stopwatch.prototype.reset = function () {
- this.$$running = false;
- this.$$timeStart = undefined;
- this.$$timeEnd = undefined;
-
- return this;
- };
-
- Stopwatch.prototype.start = function () {
- if (this.$$running) {
- throw Stopwatch.STOPWATCH_ALREADY_STARTED_EXCEPTION;
- }
-
- if (this.$$timeStart && this.$$timeEnd) {
- throw Stopwatch.RESET_BEFORE_CALLING_START_EXCEPTION;
- }
-
- this.$$timeStart = new Date();
- this.$$running = true;
-
- return this;
- };
-
- Stopwatch.prototype.stop = function () {
- if (!this.$$timeStart) {
- throw Stopwatch.STOPWATCH_WAS_NOT_STARTED_EXCEPTION;
- }
-
- if (!this.$$running) {
- throw Stopwatch.STOPWATCH_ALREADY_STOPPED_EXCEPTION;
- }
-
- this.$$timeEnd = new Date();
- this.$$running = false;
-
- return this;
- };
-
- Stopwatch.prototype.getDuration = function (inSeconds) {
- var
- millisecondDifference,
- now = new Date();
-
- if (!this.$$timeStart) {
- throw Stopwatch.STOPWATCH_WAS_NOT_STARTED_EXCEPTION;
- }
-
- if (this.$$running) {
- millisecondDifference = now.getTime() - this.$$timeStart.getTime();
- } else {
- millisecondDifference = this.$$timeEnd.getTime() - this.$$timeStart.getTime();
- }
-
- return inSeconds ? millisecondDifference / Stopwatch.$$_MILLISECOND_IN_SECOND : millisecondDifference;
- };
-
- return Stopwatch;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('Common.WindowFunction', _WindowFunction);
-
- _WindowFunction.$inject = [
- 'Common.MathUtil'
- ];
-
- function _WindowFunction(
- MathUtil
- ) {
-
- function blackmanNuttall(n, N) {
- return 0.3635819
- - 0.4891775 * MathUtil.cos(2 * MathUtil.PI * n / (N - 1))
- + 0.1365995 * MathUtil.cos(4 * MathUtil.PI * n / (N - 1))
- - 0.0106411 * MathUtil.cos(6 * MathUtil.PI * n / (N - 1));
- }
-
- return {
- blackmanNuttall: blackmanNuttall
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerService('PhysicalLayerCore.ReceiveMulticoreWorkerThread', _ReceiveMulticoreWorkerThread);
-
- _ReceiveMulticoreWorkerThread.$inject = [];
-
- function _ReceiveMulticoreWorkerThread() {
-
- function $$getFormattedDevScriptList() {
- var i, src, isLast, scriptList = [];
-
- for (i = 0; i < AudioNetwork.devScriptList.length; i++) {
- src = AudioNetwork.bootConfig.devScriptBaseUrl + AudioNetwork.devScriptList[i];
- isLast = i === AudioNetwork.devScriptList.length - 1;
- scriptList.push(' \'' + src + '\'' + (isLast ? '' : ',') + '\n');
- }
-
- return scriptList;
- }
-
- function $$getFormattedProdScriptList() {
- var src, scriptList = [];
-
- src = AudioNetwork.bootConfig.prodScriptBaseUrl + AudioNetwork.bootConfig.prodScriptName;
- scriptList.push(' \'' + src + '\'' + '\n');
-
- return scriptList;
- }
-
- function getJavaScriptCode() {
- var js = '', scriptList;
-
- switch (AudioNetwork.bootConfig.multicoreState) {
- case AudioNetwork.MULTICORE_STATE.ENABLED_USE_DEV_SCRIPT:
- scriptList = $$getFormattedDevScriptList();
- break;
- case AudioNetwork.MULTICORE_STATE.ENABLED_USE_PROD_SCRIPT:
- scriptList = $$getFormattedProdScriptList();
- break;
- }
-
- js += 'self.importScripts( ' + '\n';
- js += scriptList.join('');
- js += '); ' + '\n';
- js += ' ' + '\n';
- js += 'var ' + '\n';
- js += ' iAlias = AudioNetwork.Injector, ' + '\n';
- js += ' ReceiveWorker = iAlias.resolve("PhysicalLayerCore.ReceiveWorker"), ' + '\n';
- js += ' ReceiveMulticoreWorker = iAlias.resolve("PhysicalLayerCore.ReceiveMulticoreWorker"), ' + '\n';
- js += ' receiveWorker = undefined; ' + '\n';
- js += ' ' + '\n';
- js += '// eval("console.log(\'eval inside thread test\');") ' + '\n';
- js += ' ' + '\n';
- js += 'self.onmessage = function(event) { ' + '\n';
- js += ' var ' + '\n';
- js += ' data = event.data, ' + '\n';
- js += ' messageIndex = data.length > 0 ? data[0] : null, ' + '\n';
- js += ' param = data.length > 0 ? data[1] : null, ' + '\n';
- js += ' promise; ' + '\n';
- js += ' ' + '\n';
- js += ' switch (messageIndex) { ' + '\n';
- js += ' case ReceiveMulticoreWorker.INITIALIZATION: ' + '\n';
- js += ' receiveWorker = new ReceiveWorker(param); ' + '\n';
- js += ' self.postMessage([ ' + '\n';
- js += ' ReceiveMulticoreWorker.INITIALIZATION_SUCCESS ' + '\n';
- js += ' ]); ' + '\n';
- js += ' break; ' + '\n';
- js += ' case ReceiveMulticoreWorker.HANDLE_SAMPLE_BLOCK: ' + '\n';
- js += ' promise = receiveWorker.handleSampleBlock(param); ' + '\n';
- js += ' break; ' + '\n';
- js += ' case ReceiveMulticoreWorker.COMPUTE_CRAZY_SINE_SUM: ' + '\n';
- js += ' promise = receiveWorker.computeCrazySineSum(param); ' + '\n';
- js += ' break; ' + '\n';
- js += ' } ' + '\n';
- js += ' ' + '\n';
- js += ' if (!promise) { ' + '\n';
- js += ' return; ' + '\n';
- js += ' } ' + '\n';
- js += ' ' + '\n';
- js += ' promise ' + '\n';
- js += ' .then(function (result) { ' + '\n';
- js += ' self.postMessage([ ' + '\n';
- js += ' messageIndex + ReceiveMulticoreWorker.MESSAGE_INDEX_OFFSET_SUCCESS, ' + '\n';
- js += ' result ' + '\n';
- js += ' ]); ' + '\n';
- js += ' }) ' + '\n';
- js += ' .catch(function () { ' + '\n';
- js += ' self.postMessage([ ' + '\n';
- js += ' messageIndex + ReceiveMulticoreWorker.MESSAGE_INDEX_OFFSET_FAIL, ' + '\n';
- js += ' result ' + '\n';
- js += ' ]); ' + '\n';
- js += ' }); ' + '\n';
- js += '} ' + '\n';
- js += ' ' + '\n';
-
- return js;
- }
-
- return {
- getJavaScriptCode: getJavaScriptCode
- };
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayerCore.ReceiveMulticoreWorker', _ReceiveMulticoreWorker);
-
- _ReceiveMulticoreWorker.$inject = [
- 'PhysicalLayerCore.ReceiveMulticoreWorkerThread',
- 'Common.SimplePromiseBuilder'
- ];
-
- function _ReceiveMulticoreWorker(
- ReceiveMulticoreWorkerThread,
- SimplePromiseBuilder
- ) {
- var ReceiveMulticoreWorker;
-
- ReceiveMulticoreWorker = function (key) {
- var threadCode, blob, objectUrl;
-
- if (AudioNetwork.bootConfig.multicoreState === AudioNetwork.MULTICORE_STATE.DISABLED) {
- throw ReceiveMulticoreWorker.MULTICORE_SUPPORT_IS_NOT_ENABLED_EXCEPTION;
- }
-
- threadCode = ReceiveMulticoreWorkerThread.getJavaScriptCode();
- blob = new Blob(
- [ threadCode ],
- { type: 'application/javascript' }
- );
- objectUrl = URL.createObjectURL(blob);
-
- this.$$key = key;
- this.$$worker = new Worker(objectUrl);
- this.$$worker.onmessage = this.$$onMessage.bind(this);
-
- this.$$promise = [];
- this.$$promise.length = ReceiveMulticoreWorker.MESSAGE_TOTAL;
-
- this.$$sendToThread(ReceiveMulticoreWorker.INITIALIZATION, this.$$key);
- };
-
- ReceiveMulticoreWorker.MULTICORE_SUPPORT_IS_NOT_ENABLED_EXCEPTION = 'Multicore support is not enabled';
- ReceiveMulticoreWorker.PREVIOUS_PROMISE_NOT_RESOLVED_YET_EXCEPTION = 'Previous promise not resolved yet';
-
- ReceiveMulticoreWorker.INITIALIZATION = 0;
- ReceiveMulticoreWorker.INITIALIZATION_SUCCESS = 1;
- ReceiveMulticoreWorker.INITIALIZATION_FAIL = 2;
- ReceiveMulticoreWorker.HANDLE_SAMPLE_BLOCK = 3;
- ReceiveMulticoreWorker.HANDLE_SAMPLE_BLOCK_SUCCESS = 4;
- ReceiveMulticoreWorker.HANDLE_SAMPLE_BLOCK_FAIL = 5;
- ReceiveMulticoreWorker.COMPUTE_CRAZY_SINE_SUM = 6;
- ReceiveMulticoreWorker.COMPUTE_CRAZY_SINE_SUM_SUCCESS = 7;
- ReceiveMulticoreWorker.COMPUTE_CRAZY_SINE_SUM_FAIL = 8;
-
- ReceiveMulticoreWorker.MESSAGE_TOTAL = 9;
- ReceiveMulticoreWorker.MESSAGE_INDEX_SPACING = 3;
- ReceiveMulticoreWorker.MESSAGE_INDEX_OFFSET_SUCCESS = 1;
- ReceiveMulticoreWorker.MESSAGE_INDEX_OFFSET_FAIL = 2;
-
- ReceiveMulticoreWorker.prototype.destroy = function() {
- if (this.$$worker) {
- this.$$worker.terminate();
- this.$$worker = undefined;
- }
- };
-
- ReceiveMulticoreWorker.prototype.getInitialization = function() {
- return this.$$promise[ReceiveMulticoreWorker.INITIALIZATION];
- };
-
- ReceiveMulticoreWorker.prototype.$$onMessage = function(event) {
- var
- data = event.data,
- messageIndex = data.length > 0 ? data[0] : null,
- result = data.length > 1 ? data[1] : null,
- promise,
- i;
-
- for (i = 0; i < this.$$promise.length; i++) {
- promise = this.$$promise[i];
- if (promise) {
- switch (messageIndex % ReceiveMulticoreWorker.MESSAGE_INDEX_SPACING) {
- case ReceiveMulticoreWorker.MESSAGE_INDEX_OFFSET_SUCCESS:
- promise.resolve(result);
- break;
- case ReceiveMulticoreWorker.MESSAGE_INDEX_OFFSET_FAIL:
- promise.reject(result);
- break;
- }
- this.$$promise[i] = undefined;
- break;
- }
- }
- };
-
- ReceiveMulticoreWorker.prototype.$$sendToThread = function (messageIndex, value) {
- if (this.$$promise[messageIndex]) {
- throw ReceiveWorker.PREVIOUS_PROMISE_NOT_RESOLVED_YET_EXCEPTION;
- }
- this.$$promise[messageIndex] = SimplePromiseBuilder.build();
- this.$$worker.postMessage([
- messageIndex,
- value
- ]);
-
- return this.$$promise[messageIndex];
- };
-
- ReceiveMulticoreWorker.prototype.computeCrazySineSum = function (value) {
- return this.$$sendToThread(ReceiveMulticoreWorker.COMPUTE_CRAZY_SINE_SUM, value);
- };
-
- ReceiveMulticoreWorker.prototype.handleSampleBlock = function (value) {
- return this.$$sendToThread(ReceiveMulticoreWorker.HANDLE_SAMPLE_BLOCK, value);
- };
-
- return ReceiveMulticoreWorker;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-(function () {
- 'use strict';
-
- AudioNetwork.Injector
- .registerFactory('PhysicalLayerCore.ReceiveWorker', _ReceiveWorker);
-
- _ReceiveWorker.$inject = [
- 'Common.CarrierRecoveryBuilder',
- 'Common.MathUtil',
- 'Common.SimplePromiseBuilder'
- ];
-
- function _ReceiveWorker(
- CarrierRecoveryBuilder,
- MathUtil,
- SimplePromiseBuilder
- ) {
- var ReceiveWorker;
-
- ReceiveWorker = function (key) {
- this.$$key = key;
- this.$$carrierRecovery = CarrierRecoveryBuilder.build(16, 16 * 1024);
- };
-
- ReceiveWorker.prototype.computeCrazySineSum = function (addValue) {
- var
- promise = SimplePromiseBuilder.build(),
- result = 0;
-
- for (var i = 0; i < 9000111; i++) {
- result += MathUtil.sin(i);
- }
- result = addValue + MathUtil.abs(result);
- promise.resolve({
- key: this.$$key,
- result: result
- });
-
- return promise;
- };
-
- ReceiveWorker.prototype.handleSampleBlock = function (sampleBlock) {
- var
- promise = SimplePromiseBuilder.build(),
- result,
- i;
-
- for (i = 0; i < 16 * 1024; i++) {
- this.$$carrierRecovery.handleSample(
- Math.sin(2 * Math.PI * (i / 16 - 0.25))
- );
- }
- result = this.$$carrierRecovery.getCarrierDetail();
-
- promise.resolve({
- key: this.$$key,
- result: result
- });
-
- return promise;
- };
-
- return ReceiveWorker;
- }
-
-})();
-
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-if (AudioNetwork.bootConfig.createAlias) {
-
- AudioNetwork.Rewrite = {};
- AudioNetwork.Rewrite.Dsp = {};
- AudioNetwork.Rewrite.PhysicalLayer = {};
- AudioNetwork.Rewrite.DataLinkLayer = {};
- AudioNetwork.Rewrite.Util = {};
- AudioNetwork.Rewrite.WebAudio = {};
- AudioNetwork.Visualizer = {};
-
- AudioNetwork.Rewrite.Dsp.Complex = AudioNetwork.Injector.resolve('Rewrite.Dsp.Complex');
- AudioNetwork.Rewrite.Dsp.Correlator = AudioNetwork.Injector.resolve('Rewrite.Dsp.Correlator');
- AudioNetwork.Rewrite.Dsp.FFTResult = AudioNetwork.Injector.resolve('Rewrite.Dsp.FFTResult');
- AudioNetwork.Rewrite.Dsp.WaveAnalyser = AudioNetwork.Injector.resolve('Rewrite.Dsp.WaveAnalyser');
- AudioNetwork.Rewrite.Dsp.WaveGenerator = AudioNetwork.Injector.resolve('Rewrite.Dsp.WaveGenerator');
- AudioNetwork.Rewrite.PhysicalLayer.PhysicalLayerBuilder = AudioNetwork.Injector.resolve('Rewrite.PhysicalLayer.PhysicalLayerBuilder');
- AudioNetwork.Rewrite.DataLinkLayer.DataLinkLayerBuilder = AudioNetwork.Injector.resolve('Rewrite.DataLinkLayer.DataLinkLayerBuilder');
- AudioNetwork.Rewrite.Util.Buffer = AudioNetwork.Injector.resolve('Rewrite.Util.Buffer');
- AudioNetwork.Rewrite.Util.FrequencyCalculator = AudioNetwork.Injector.resolve('Rewrite.Util.FrequencyCalculator');
- AudioNetwork.Rewrite.Util.MusicCalculator = AudioNetwork.Injector.resolve('Rewrite.Util.MusicCalculator');
- AudioNetwork.Rewrite.Util.SmartTimer = AudioNetwork.Injector.resolve('Rewrite.Util.SmartTimer');
- AudioNetwork.Rewrite.Util.WavAudioFile = AudioNetwork.Injector.resolve('Rewrite.Util.WavAudioFile');
- AudioNetwork.Rewrite.WebAudio.AudioMonoIO = AudioNetwork.Injector.resolve('Rewrite.WebAudio.AudioMonoIO');
- AudioNetwork.Rewrite.WebAudio.AudioMonoIOLite = AudioNetwork.Injector.resolve('Rewrite.WebAudio.AudioMonoIOLite');
- AudioNetwork.Visualizer.AnalyserChart = AudioNetwork.Injector.resolve('Visualizer.AnalyserChart');
- AudioNetwork.Visualizer.ConstellationDiagram = AudioNetwork.Injector.resolve('Visualizer.ConstellationDiagram');
- AudioNetwork.Visualizer.PowerChart = AudioNetwork.Injector.resolve('Visualizer.PowerChart');
- AudioNetwork.Visualizer.SampleChart = AudioNetwork.Injector.resolve('Visualizer.SampleChart');
- AudioNetwork.Visualizer.FrequencyDomainChart = AudioNetwork.Injector.resolve('Visualizer.FrequencyDomainChart');
- AudioNetwork.Visualizer.ComplexPlaneChart = AudioNetwork.Injector.resolve('Visualizer.ComplexPlaneChart');
-
- // components listed below are mostly deprecated
- AudioNetwork.PhysicalLayer = {};
- AudioNetwork.PhysicalLayerAdapter = {};
- AudioNetwork.Audio = {};
- AudioNetwork.Common = {};
-
- AudioNetwork.PhysicalLayer.PhysicalLayer = AudioNetwork.Injector.resolve('PhysicalLayer.PhysicalLayer'); // deprecated
- AudioNetwork.PhysicalLayer.DefaultConfig = AudioNetwork.Injector.resolve('PhysicalLayer.DefaultConfig'); // deprecated
- AudioNetwork.PhysicalLayer.RxInput = AudioNetwork.Injector.resolve('PhysicalLayer.RxInput'); // deprecated
- AudioNetwork.PhysicalLayerAdapter.TransmitAdapter = AudioNetwork.Injector.resolve('PhysicalLayerAdapter.TransmitAdapter'); // deprecated
- AudioNetwork.PhysicalLayerAdapter.ReceiveAdapter = AudioNetwork.Injector.resolve('PhysicalLayerAdapter.ReceiveAdapter'); // deprecated
- AudioNetwork.Audio.ActiveAudioContext = AudioNetwork.Injector.resolve('Audio.ActiveAudioContext'); // deprecated
- AudioNetwork.Audio.SimpleAudioContext = AudioNetwork.Injector.resolve('Audio.SimpleAudioContext'); // deprecated
- AudioNetwork.Common.Queue = AudioNetwork.Injector.resolve('Common.Queue'); // deprecated
- AudioNetwork.Common.CarrierRecovery = AudioNetwork.Injector.resolve('Common.CarrierRecovery'); // deprecated
- AudioNetwork.Common.CarrierGenerate = AudioNetwork.Injector.resolve('Common.CarrierGenerate'); // deprecated
- AudioNetwork.Common.WindowFunction = AudioNetwork.Injector.resolve('Common.WindowFunction'); // probably deprecated
- AudioNetwork.Common.Util = AudioNetwork.Injector.resolve('Common.Util'); // deprecated
-}
-
-if (AudioNetwork.isNode) {
- module.exports = AudioNetwork;
-}
diff --git a/build/audio-network-v1.3.0.min.js b/build/audio-network-v1.3.0.min.js
deleted file mode 100644
index 3622646..0000000
--- a/build/audio-network-v1.3.0.min.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-The MIT License (MIT)
-
-Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-"use strict";var AudioNetwork={},AudioNetworkBootConfig=AudioNetworkBootConfig||{};AudioNetwork.version="1.3.0",AudioNetwork.isNode=!("undefined"==typeof module||!module.exports),AudioNetwork.isWebWorker=!AudioNetwork.isNode&&"undefined"!=typeof WorkerGlobalScope&&"function"==typeof importScripts&&navigator instanceof WorkerNavigator,AudioNetwork.isBrowser=!AudioNetwork.isNode&&!AudioNetwork.isWebWorker&&"undefined"!=typeof navigator&&"undefined"!=typeof document,AudioNetwork.MULTICORE_STATE={DISABLED:"DISABLED",ENABLED_USE_PROD_SCRIPT:"ENABLED_USE_PROD_SCRIPT",ENABLED_USE_DEV_SCRIPT:"ENABLED_USE_DEV_SCRIPT"},AudioNetwork.bootConfig={devScriptBaseUrl:"string"==typeof AudioNetworkBootConfig.devScriptBaseUrl?AudioNetworkBootConfig.devScriptBaseUrl:AudioNetwork.isBrowser?window.location.origin+"/src/":"",prodScriptBaseUrl:"string"==typeof AudioNetworkBootConfig.prodScriptBaseUrl?AudioNetworkBootConfig.prodScriptBaseUrl:AudioNetwork.isBrowser?window.location.origin+"/build/":"",prodScriptName:"string"==typeof AudioNetworkBootConfig.prodScriptName?AudioNetworkBootConfig.prodScriptName:"audio-network-v"+AudioNetwork.version+".min.js",devScriptLoad:void 0!==AudioNetworkBootConfig.devScriptLoad&&!!AudioNetworkBootConfig.devScriptLoad,createAlias:void 0===AudioNetworkBootConfig.createAlias||!!AudioNetworkBootConfig.createAlias,multicoreState:-1!==Object.keys(AudioNetwork.MULTICORE_STATE).indexOf(AudioNetworkBootConfig.multicoreState)?AudioNetworkBootConfig.multicoreState:AudioNetwork.MULTICORE_STATE.DISABLED},AudioNetwork.Injector=function(){var e;return(e=function(){this.$$injectRepository={}}).RESOLVE_RECURSION_LIMIT=20,e.RESOLVE_RECURSION_LIMIT_EXCEED_EXCEPTION="Injector - resolve recursion limit exceed",e.MULTIPLE_REGISTER_EXCEPTION="Injector - multiple register calls for the same name",e.UNABLE_TO_FIND_ITEM_EXCEPTION="Injector - unable to find factory/service for given name: ",e.TYPE={SERVICE:"SERVICE",FACTORY:"FACTORY"},e.$$resolveRecursionCounter=0,e.prototype.$$register=function(t,i,r){if(void 0!==this.$$injectRepository[t])throw e.MULTIPLE_REGISTER_EXCEPTION;this.$$injectRepository[t]={type:r,item:i,resolveCache:null}},e.prototype.registerService=function(t,i){this.$$register(t,i,e.TYPE.SERVICE)},e.prototype.registerFactory=function(t,i){this.$$register(t,i,e.TYPE.FACTORY)},e.prototype.resolve=function(t){var i,r,n=[];if((r=this.$$find(t)).resolveCache)return r.resolveCache;for(this.$$resolveRecursionInc(),i=0;i=e.RESOLVE_RECURSION_LIMIT)throw e.RESOLVE_RECURSION_LIMIT_EXCEED_EXCEPTION},e.prototype.$$resolveRecursionDec=function(){e.$$resolveRecursionCounter--},e.prototype.$$injectDependenciesAndInstantiate=function(e,t){var i,r=e,n=t;switch(t.length){case 0:i=new r.item;break;case 1:i=new r.item(n[0]);break;case 2:i=new r.item(n[0],n[1]);break;case 3:i=new r.item(n[0],n[1],n[2]);break;case 4:i=new r.item(n[0],n[1],n[2],n[3]);break;case 5:i=new r.item(n[0],n[1],n[2],n[3],n[4]);break;case 6:i=new r.item(n[0],n[1],n[2],n[3],n[4],n[5]);break;case 7:i=new r.item(n[0],n[1],n[2],n[3],n[4],n[5],n[6]);break;case 8:i=new r.item(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]);break;case 9:i=new r.item(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8]);break;case 10:i=new r.item(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],n[9]);break;case 11:i=new r.item(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],n[9],n[10]);break;case 12:i=new r.item(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],n[9],n[10],n[11])}return i},e.prototype.$$injectDependencies=function(e,t){var i,r=e,n=t;switch(t.length){case 0:i=r.item();break;case 1:i=r.item(n[0]);break;case 2:i=r.item(n[0],n[1]);break;case 3:i=r.item(n[0],n[1],n[2]);break;case 4:i=r.item(n[0],n[1],n[2],n[3]);break;case 5:i=r.item(n[0],n[1],n[2],n[3],n[4]);break;case 6:i=r.item(n[0],n[1],n[2],n[3],n[4],n[5]);break;case 7:i=r.item(n[0],n[1],n[2],n[3],n[4],n[5],n[6]);break;case 8:i=r.item(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]);break;case 9:i=r.item(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8]);break;case 10:i=r.item(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],n[9]);break;case 11:i=r.item(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],n[9],n[10]);break;case 12:i=r.item(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],n[9],n[10],n[11])}return i},e.prototype.$$find=function(t){var i;for(i in this.$$injectRepository)if(this.$$injectRepository.hasOwnProperty(i)&&i===t)return this.$$injectRepository[i];throw e.UNABLE_TO_FIND_ITEM_EXCEPTION+t},new e}(),AudioNetwork.DynamicScriptLoader=function(){var e;return(e=function(){}).prototype.loadList=function(e,t){var i;for(void 0===t&&(t=0),i=t;i<\/script>')},new e}(),AudioNetwork.devScriptList=["audio-network-boot.js","-deprecated-probably/common/math-util/math-util.service.js","-deprecated-probably/common/simple-promise/simple-promise-builder.service.js","-deprecated-probably/common/simple-promise/simple-promise.factory.js","-deprecated-probably/common/stopwatch/stopwatch-builder.service.js","-deprecated-probably/common/stopwatch/stopwatch.factory.js","-deprecated-probably/common/window-function/window-function.service.js","-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker-thread.service.js","-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker.factory.js","-deprecated-probably/physical-layer-core/receive-worker/receive-worker.factory.js","-deprecated/audio/active-audio-context/active-audio-context.service.js","-deprecated/audio/simple-audio-context/simple-audio-context-builder.service.js","-deprecated/audio/simple-audio-context/simple-audio-context.factory.js","-deprecated/common/abstract-value-collector/abstract-value-collector.factory.js","-deprecated/common/average-value-collector/average-value-collector-builder.service.js","-deprecated/common/average-value-collector/average-value-collector.factory.js","-deprecated/common/carrier-generate/carrier-generate-builder.service.js","-deprecated/common/carrier-generate/carrier-generate.factory.js","-deprecated/common/carrier-recovery/carrier-recovery-builder.service.js","-deprecated/common/carrier-recovery/carrier-recovery.factory.js","-deprecated/common/complex/complex-builder.service.js","-deprecated/common/complex/complex.factory.js","-deprecated/common/queue/queue-builder.service.js","-deprecated/common/queue/queue.factory.js","-deprecated/common/util/util.service.js","-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector-builder.service.js","-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector.factory.js","-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector-builder.service.js","-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector.factory.js","-deprecated/physical-layer-adapter/receive-adapter-state.service.js","-deprecated/physical-layer-adapter/receive-adapter.factory.js","-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager-builder.service.js","-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager.factory.js","-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine-builder.service.js","-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine.factory.js","-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector-builder.service.js","-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector.factory.js","-deprecated/physical-layer-adapter/transmit-adapter.factory.js","-deprecated/physical-layer/abstract-channel-manager/abstract-channel-manager.factory.js","-deprecated/physical-layer/channel-receive-manager/channel-receive-manager-builder.service.js","-deprecated/physical-layer/channel-receive-manager/channel-receive-manager.factory.js","-deprecated/physical-layer/channel-receive/channel-receive-builder.service.js","-deprecated/physical-layer/channel-receive/channel-receive.factory.js","-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager-builder.service.js","-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager.factory.js","-deprecated/physical-layer/channel-transmit/channel-transmit-builder.service.js","-deprecated/physical-layer/channel-transmit/channel-transmit.factory.js","-deprecated/physical-layer/configuration-parser.service.js","-deprecated/physical-layer/default-config.service.js","-deprecated/physical-layer/physical-layer.factory.js","-deprecated/physical-layer/rx-handler/rx-handler-builder.service.js","-deprecated/physical-layer/rx-handler/rx-handler.factory.js","-deprecated/physical-layer/rx-input.service.js","data-link-layer/checksum-service.js","data-link-layer/data-link-layer-builder.js","data-link-layer/data-link-layer.js","data-link-layer/frame.js","data-link-layer/tx-frame-manager.js","data-link-layer/tx-frame.js","dsp/complex.js","dsp/correlator.js","dsp/fft-result.js","dsp/wave-analyser.js","dsp/wave-generator.js","physical-layer/physical-layer-builder.js","physical-layer/physical-layer.js","physical-layer/rx-sync-detector.js","physical-layer/tx-symbol-manager.js","physical-layer/tx-symbol.js","util/buffer.js","util/frequency-calculator.js","util/music-calculator.js","util/smart-timer.js","util/wav-audio-file.js","visualizer/abstract-2d-visualizer/abstract-2d-visualizer.factory.js","visualizer/abstract-visualizer/abstract-visualizer.factory.js","visualizer/analyser-chart/analyser-chart-builder.service.js","visualizer/analyser-chart/analyser-chart-template-axis-x.service.js","visualizer/analyser-chart/analyser-chart-template-main.service.js","visualizer/analyser-chart/analyser-chart.factory.js","visualizer/complex-plane-chart/complex-plane-chart-builder.service.js","visualizer/complex-plane-chart/complex-plane-chart-template-main.service.js","visualizer/complex-plane-chart/complex-plane-chart.factory.js","visualizer/constellation-diagram/constellation-diagram-builder.service.js","visualizer/constellation-diagram/constellation-diagram-template-main.service.js","visualizer/constellation-diagram/constellation-diagram.factory.js","visualizer/frequency-domain-chart/frequency-domain-chart-builder.service.js","visualizer/frequency-domain-chart/frequency-domain-chart-template-main.service.js","visualizer/frequency-domain-chart/frequency-domain-chart.factory.js","visualizer/power-chart/power-chart-builder.service.js","visualizer/power-chart/power-chart-template-main.service.js","visualizer/power-chart/power-chart.factory.js","visualizer/sample-chart/sample-chart-builder.service.js","visualizer/sample-chart/sample-chart-template-main.service.js","visualizer/sample-chart/sample-chart.factory.js","web-audio/audio-mono-io-lite.js","web-audio/audio-mono-io.js","audio-network-end.js"],AudioNetwork.isBrowser&&AudioNetwork.bootConfig.devScriptLoad&&AudioNetwork.DynamicScriptLoader.loadList(AudioNetwork.devScriptList,1),function(){AudioNetwork.Injector.registerFactory("Rewrite.DataLinkLayer.ChecksumService",e),e.$inject=[];function e(){var e;return(e=function(){}).fletcher8=function(e){var t,i,r,n,o;for(t=0,i=0,r=0;r<2*e.length;r++)n=r%2==0,o=e[r>>>1],i=(i+(t=(t+(n?(240&o)>>>4:15&o))%15))%15;return i<<4|t},e}}(),function(){AudioNetwork.Injector.registerFactory("Rewrite.DataLinkLayer.DataLinkLayerBuilder",e),e.$inject=["Rewrite.DataLinkLayer.DataLinkLayer"];function e(e){var t;return(t=function(){this._framePayloadLengthLimit=7,this._rxFrameListener=void 0,this._rxFrameCandidateListener=void 0,this._txFrameListener=void 0,this._txFrameProgressListener=void 0,this._rxSymbolListener=void 0,this._rxSampleDspDetailsListener=void 0,this._rxSyncDspDetailsListener=void 0,this._rxDspConfigListener=void 0,this._dspConfigListener=void 0,this._txSymbolProgressListener=void 0,this._txDspConfigListener=void 0}).prototype.framePayloadLengthLimit=function(e){return this._framePayloadLengthLimit=e,this},t.prototype.rxFrameListener=function(e){return this._rxFrameListener=e,this},t.prototype.txFrameListener=function(e){return this._txFrameListener=e,this},t.prototype.txFrameProgressListener=function(e){return this._txFrameProgressListener=e,this},t.prototype.rxFrameCandidateListener=function(e){return this._rxFrameCandidateListener=e,this},t.prototype.rxSymbolListener=function(e){return this._rxSymbolListener=e,this},t.prototype.rxSampleDspDetailsListener=function(e){return this._rxSampleDspDetailsListener=e,this},t.prototype.rxSyncStatusListener=function(e){return this._rxSyncStatusListener=e,this},t.prototype.rxSyncDspDetailsListener=function(e){return this._rxSyncDspDetailsListener=e,this},t.prototype.rxDspConfigListener=function(e){return this._rxDspConfigListener=e,this},t.prototype.dspConfigListener=function(e){return this._dspConfigListener=e,this},t.prototype.txSymbolListener=function(e){return this._txSymbolListener=e,this},t.prototype.txSymbolProgressListener=function(e){return this._txSymbolProgressListener=e,this},t.prototype.txDspConfigListener=function(e){return this._txDspConfigListener=e,this},t.prototype.build=function(){return new e(this)},t}}(),function(){AudioNetwork.Injector.registerFactory("Rewrite.DataLinkLayer.DataLinkLayer",e),e.$inject=["Rewrite.PhysicalLayer.PhysicalLayerBuilder","Rewrite.DataLinkLayer.TxFrameManager","Rewrite.DataLinkLayer.TxFrame","Rewrite.DataLinkLayer.ChecksumService"];function e(e,t,i,r){var n;return(n=function(i){this.$$physicalLayer=(new e).rxSymbolListener(this.$$rxSymbolListener.bind(this)).rxSampleDspDetailsListener(i._rxSampleDspDetailsListener).rxSyncStatusListener(i._rxSyncStatusListener).rxSyncDspDetailsListener(i._rxSyncDspDetailsListener).rxDspConfigListener(i._rxDspConfigListener).dspConfigListener(i._dspConfigListener).txSymbolListener(this.$$txSymbolListener.bind(this)).txSymbolProgressListener(i._txSymbolProgressListener).txDspConfigListener(i._txDspConfigListener).build(),this.$$framePayloadLengthLimit=i._framePayloadLengthLimit,this.$$frame=void 0,this.$$frameId=n.$$_INITIAL_ID,this.$$frameCandidateId=n.$$_INITIAL_ID,this.$$frameCandidateList=[],this.$$txFrameManager=new t,this.$$rxFrameListener=n.$$isFunction(i._rxFrameListener)?i._rxFrameListener:null,this.$$rxFrameCandidateListener=n.$$isFunction(i._rxFrameCandidateListener)?i._rxFrameCandidateListener:null,this.$$txFrameListener=n.$$isFunction(i._txFrameListener)?i._txFrameListener:null,this.$$txFrameProgressListener=n.$$isFunction(i._txFrameProgressListener)?i._txFrameProgressListener:null,this.$$externalRxSymbolListener=n.$$isFunction(i._rxSymbolListener)?i._rxSymbolListener:null,this.$$externalTxSymbolListener=n.$$isFunction(i._txSymbolListener)?i._txSymbolListener:null}).PAYLOAD_TO_BIG_EXCEPTION="Payload is too big!",n.COMMAND_TWO_WAY_SYNC_44100=0,n.COMMAND_TWO_WAY_SYNC_48000=1,n.$$_HEADER_FRAME_START_MARKER=224,n.$$_HEADER_RESERVED_BIT=8,n.$$_HEADER_COMMAND_BIT_SET=16,n.$$_HEADER_COMMAND_BIT_NOT_SET=0,n.$$_HEADER_PAYLOAD_LENGTH_MASK=15,n.$$_ONE_BYTE_MASK=255,n.$$_PAYLOAD_TYPE_COMMAND="PAYLOAD_TYPE_COMMAND",n.$$_PAYLOAD_TYPE_DATA="PAYLOAD_TYPE_DATA",n.$$_INITIAL_ID=1,n.$$_HEADER_AND_CHECKSUM_BYTE_OVERHEAD=2,n.prototype.getPhysicalLayer=function(){return this.$$physicalLayer},n.prototype.getRxSampleRate=function(){return this.$$physicalLayer.getRxDspConfig().rxSampleRate},n.prototype.setTxSampleRate=function(e){this.$$physicalLayer.setTxSampleRate(e)},n.prototype.txSync=function(){this.$$physicalLayer.txSync()},n.prototype.txTwoWaySync=function(){switch(this.txSync(),this.getRxSampleRate()){case 44100:this.txFrame([n.COMMAND_TWO_WAY_SYNC_44100],!0);break;case 48e3:this.txFrame([n.COMMAND_TWO_WAY_SYNC_48000],!0)}},n.prototype.setLoopback=function(e){this.$$physicalLayer.setLoopback(e)},n.prototype.getFramePayloadLengthLimit=function(){return this.$$framePayloadLengthLimit},n.prototype.txFrame=function(e,t){var r,o,a,s,$;if(e.length>this.$$framePayloadLengthLimit)throw n.PAYLOAD_TO_BIG_EXCEPTION;for(r=new i(this.$$txFrameManager.getNextTxFrameId(),e,t),o=this.$$physicalLayer.getTxDspConfig().txSymbolMin,a=0;a=0;e--)(t=this.$$frameCandidateList[e]).rxByteReceived.length===t.rxByteExpected&&this.$$frameCandidateList.splice(e,1)},n.prototype.$$addNewByteToFrameCandidateList=function(e,t){var i,n,o,a;for(i=0;i0||!!this.$$txFrameCurrent},e.prototype.addTxFrame=function(e){this.$$txFrameQueue.push(e)},e.prototype.handleTxSymbolId=function(e){var t,i;t=this.$$txFrameQueue.length>0,this.$$txFrameCurrent?(i=this.$$txFrameCurrent.tryToConfirmTxSymbolId(e),this.$$txFrameCurrent.isFullyTransmitted()&&(this.$$txFrame=this.$$txFrameCurrent,this.$$txFrameCurrent=t?this.$$txFrameQueue.shift():null)):(this.$$txFrame=null,this.$$txFrameCurrent=t?this.$$txFrameQueue.shift():null),this.$$txFrameCurrent&&!i&&this.$$txFrameCurrent.tryToConfirmTxSymbolId(e)},e}}(),function(){AudioNetwork.Injector.registerFactory("Rewrite.DataLinkLayer.TxFrame",e),e.$inject=["Rewrite.DataLinkLayer.Frame"];function e(e){var t;return((t=function(t,i,r){e.call(this,t,i,r),this.$$txSymbolId=[],this.$$txSymbolTransmitted=0}).prototype=Object.create(e.prototype)).constructor=t,t.TX_BYTE_INDEX_OUT_OF_RANGE_EXCEPTION="TX_BYTE_INDEX_OUT_OF_RANGE_EXCEPTION",t.prototype.cloneClean=function(){return{id:this.$$id,header:this.$$header,payload:this.$$payload.slice(0),checksum:this.$$checksum,isFullyTransmitted:this.isFullyTransmitted(),unitProgress:this.getUnitProgress(),txSymbolId:this.$$txSymbolId.slice(0),txSymbolTransmitted:this.$$txSymbolTransmitted}},t.prototype.getTxByteLength=function(){return this.$$payload.length+2},t.prototype.addTxSymbolId=function(e){this.$$txSymbolId.push(e)},t.prototype.tryToConfirmTxSymbolId=function(e){return!!t.$$inArray(this.$$txSymbolId,e)&&(this.$$txSymbolTransmitted++,!0)},t.prototype.isFullyTransmitted=function(){return this.$$txSymbolId.length===this.$$txSymbolTransmitted},t.prototype.getUnitProgress=function(){return this.$$txSymbolTransmitted/this.$$txSymbolId.length},t.prototype.getTxByte=function(e){var i=this.getTxByteLength();if(e<0||e>=i)throw t.TX_BYTE_INDEX_OUT_OF_RANGE_EXCEPTION;return 0===e?this.$$header:e===i-1?this.$$checksum:this.$$payload[e-1]},t.$$inArray=function(e,t){var i;for(i=0;i=0?t>=0?1:2:t<=0?3:4){case 1:n=Math.asin(i/r);break;case 2:n=Math.asin(-t/r)+.5*Math.PI;break;case 3:n=Math.asin(-i/r)+Math.PI;break;case 4:n=Math.asin(t/r)+1.5*Math.PI}return n/(2*Math.PI)},e.prototype.normalize=function(){this.divideScalar(this.getMagnitude())},e}}(),function(){AudioNetwork.Injector.registerFactory("Rewrite.Dsp.Correlator",e),e.$inject=["Rewrite.Util.Buffer"];function e(e){var t;return(t=function(e,i){this.$$correlationCode=i?i.slice(0):t.DEFAULT_CORRELATION_CODE.slice(0),this.$$skipFactor=void 0,this.$$dataBuffer=void 0,this.$$signalDecibelBuffer=void 0,this.$$noiseDecibelBuffer=void 0,this.$$cacheCorrelactionValue=void 0,this.$$cacheSignalDecibelAverage=void 0,this.$$cacheNoiseDecibelAverage=void 0,this.$$setSkipFactor(e)}).DEFAULT_CORRELATION_CODE=[1,1,1,-1,-1,-1,1,-1,-1,1,-1],t.CORRELATION_POSITIVE="CORRELATION_POSITIVE",t.CORRELATION_NONE="CORRELATION_NONE",t.CORRELATION_NEGATIVE="CORRELATION_NEGATIVE",t.THRESHOLD_UNIT=.9,t.NO_DECIBEL=null,t.NO_DATA=0,t.POSITION_OUT_OF_RANGE_EXCEPTION="Position out of range",t.prototype.reset=function(){this.$$setSkipFactor(this.$$skipFactor)},t.prototype.handle=function(e,i,r){var n,o;switch(n=t.NO_DATA,e){case-1:case 1:n=e}this.$$dataBuffer.pushEvenIfFull(n),o=n&&(i||0===i),this.$$signalDecibelBuffer.pushEvenIfFull(o?i:t.NO_DECIBEL),o=n&&(r||0===r),this.$$noiseDecibelBuffer.pushEvenIfFull(o?r:t.NO_DECIBEL),this.$$clearCache()},t.prototype.isCorrelated=function(){var e=this.getCorrelation();return e===t.CORRELATION_NEGATIVE||e===t.CORRELATION_POSITIVE},t.prototype.getCorrelation=function(){var e=this.getCorrelationValue(),i=Math.floor(t.THRESHOLD_UNIT*this.$$correlationCode.length);return e>=i?t.CORRELATION_POSITIVE:e>-i?t.CORRELATION_NONE:t.CORRELATION_NEGATIVE},t.prototype.getCorrelationValue=function(){var e,i,r,n,o;if(void 0!==this.$$cacheCorrelactionValue)return this.$$cacheCorrelactionValue;for(o=0,i=this.$$skipFactor-1,e=0;e0?a/s:t.NO_DECIBEL},t.prototype.$$setSkipFactor=function(i){var r,n;for(i=i||1,n=this.$$correlationCode.length*i,this.$$skipFactor=i,this.$$dataBuffer=new e(n),this.$$signalDecibelBuffer=new e(n),this.$$noiseDecibelBuffer=new e(n),this.$$cacheCorrelactionValue=void 0,this.$$cacheSignalDecibelAverage=void 0,this.$$cacheNoiseDecibelAverage=void 0,r=0;ri?this.$$fftData[n]:i;o.push(i)}t=e*o.length/this.$$fftData.length,this.$$sampleRate*=t,this.$$fftData=o},e.prototype.getLoudestBinIndex=function(e,t){return this.$$getLoudestBinIndexInRange(e,t)},e.prototype.getLoudestBinIndexInBinRange=function(t,i){var r=e.$$_HALF*this.getFFTSize();if(t<0||i>=r)throw e.VALUES_OUT_OF_RANGE;return e.$$findMaxIndexInRange(this.$$fftData,t,i)},e.prototype.getLoudestFrequency=function(t,i){var r=this.$$getLoudestBinIndexInRange(t,i);return e.getFrequency(r,this.$$sampleRate,this.getFFTSize())},e.prototype.getLoudestDecibel=function(e,t){var i=this.$$getLoudestBinIndexInRange(e,t);return this.$$fftData[i]},e.prototype.getDecibelAverage=function(t,i,r){var n,o,a,s,$=e.$$_HALF*this.getFFTSize();if(t<0||i>=$)throw e.VALUES_OUT_OF_RANGE;for(n=0,o=0,s=t;s<=i;s++)void 0!==r&&s===r||(o+=this.getDecibel(s),n++);return a=0,n>0&&(a=o/n),a},e.prototype.getDecibelRange=function(t,i){var r,n=e.$$_HALF*this.getFFTSize(),o=[];if(t<0||i>=n)throw e.VALUES_OUT_OF_RANGE;for(r=t;r<=i;r++)o.push(this.getDecibel(r));return o},e.prototype.getDecibel=function(e){return this.$$fftData[e]},e.prototype.getDecibelFromFrequency=function(e){var t=this.getBinIndex(e);return this.$$fftData[t]},e.prototype.getFrequencyData=function(){return this.$$fftData},e.prototype.getFrequency=function(t){return e.getFrequency(t,this.$$sampleRate,this.getFFTSize())},e.prototype.getFrequencyOfClosestBin=function(t){return e.getFrequencyOfClosestBin(t,this.$$sampleRate,this.getFFTSize())},e.prototype.getBinIndex=function(t){return e.getBinIndex(t,this.$$sampleRate,this.getFFTSize())},e.prototype.getResolution=function(){return e.getResolution(this.$$sampleRate,this.getFFTSize())},e.prototype.getLastBinIndex=function(){return this.$$fftData.length-1},e.prototype.getLastFrequency=function(){return this.getFrequency(this.getLastBinIndex())},e.prototype.getNyquistFrequency=function(){return e.$$_HALF*this.$$sampleRate},e.prototype.getSampleRate=function(){return this.$$sampleRate},e.prototype.getFFTSize=function(){return 2*this.$$fftData.length},e.prototype.equal=function(t){var i,r,n,o;if(r=e.$$isEqual(this.getNyquistFrequency(),t.getNyquistFrequency()),n=e.$$isEqual(this.getFFTSize(),t.getFFTSize()),!r||!n)return!1;for(o=!0,i=0;ie.$$_EQUAL_EPSILON){o=!1;break}return o},e.prototype.$$getLoudestBinIndexInRange=function(t,i){var r,n;return t=e.$$getValueOrDefault(t,e.$$_FREQUENCY_BIN_INDEX_ZERO),i=e.$$getValueOrDefault(i,this.getLastFrequency()),r=this.getBinIndex(t),n=this.getBinIndex(i),e.$$findMaxIndexInRange(this.$$fftData,r,n)},e.$$isEqual=function(e,t){return e===t},e.$$getValueOrDefault=function(e,t){return void 0!==e?e:t},e.$$findMaxIndexInRange=function(e,t,i){var r,n,o;for(r=-1,n=void 0,o=t;o<=i;o++)(-1===r||e[o]>n)&&(n=e[o],r=o);return r},e.getResolution=function(t,i){return e.getFrequency(e.$$_FREQUENCY_BIN_INDEX_FIRST,t,i)},e.getFrequency=function(t,i,r){if(t<0||t>=e.$$_HALF*r)throw e.VALUES_OUT_OF_RANGE;return t*i/r},e.getBinIndex=function(t,i,r){var n=Math.round(t*r/i);if(n<0||n>=e.$$_HALF*r)throw e.VALUES_OUT_OF_RANGE;return n},e.getFrequencyOfClosestBin=function(t,i,r){var n=e.getBinIndex(t,i,r);return e.getFrequency(n,i,r)},e}}(),function(){AudioNetwork.Injector.registerFactory("Rewrite.Dsp.WaveAnalyser",e),e.$inject=["Rewrite.Dsp.Complex","Rewrite.Util.Buffer"];function e(e,t){var i;return(i=function(e,r,n){e=e||i.$$_DEFAULT_SAMPLE_PER_PERIOD,r=r||i.$$_DEFAULT_WINDOW_SIZE,this.$$cyclePerSample=null,this.$$firstSampleOfBufferNumber=null,this.setSamplePerPeriod(e),this.$$sampleBuffer=new t(r),this.$$applyWindowFunction=!!n,this.$$frequencyBin=null}).$$_UNIT_PHASE=1,i.$$_NEGATIVE_FREQUENCIES_AMPLITUDE_FIX=2,i.$$_PHASE_CORRECTION=.75,i.$$_DECIBEL_POWER_FROM_AMPLITUDE_FACTOR=20,i.$$_DEFAULT_SAMPLE_PER_PERIOD=32,i.$$_DEFAULT_WINDOW_SIZE=1024,i.prototype.$$computeFrequencyBin=function(){var t,r,n,o,a,s,$;for(this.$$frequencyBin=e.zero(),t=this.$$sampleBuffer.getSize(),r=0;r0&&this.$$sampleOffset===t.rxSymbolSamplingPointOffset,i=this.$$isRxSymbolSamplingPoint&&this.$$rxSignalDecibel>this.$$rxSignalDecibelThreshold,this.$$rxSymbol=i?this.$$rxSymbolRaw:o.$$_RX_SYMBOL_IDLE,s&&(this.$$rxSyncDspDetailsListener&&this.$$rxSyncDspDetailsListener(this.getRxSyncDspDetails()),this.$$rxDspConfigListener&&this.$$rxDspConfigListener(this.getRxDspConfig())),this.$$rxSampleDspDetailsListener&&this.$$rxSampleDspDetailsListener(this.getRxSampleDspDetails()),this.$$rxSyncStatusListener&&this.$$rxSyncStatusListener(this.getRxSyncStatus()),this.$$isRxSymbolSamplingPoint&&(this.$$rxSymbolId++,this.$$rxSymbolListener&&this.$$rxSymbolListener(this.getRxSymbol()))},o.prototype.$$tx=function(){var e,t;0===this.$$sampleOffset&&(e=this.$$txSymbolManager.isTxAboutToStart(),t=this.$$txSymbolManager.isTxAboutToEnd(),this.$$txSymbolManager.tick(),e&&this.$$audioMonoIO.microphoneDisable(),t&&this.$$audioMonoIO.microphoneEnable(),this.$$updateOscillator(),this.$$txSymbolListener&&this.$$txSymbolListener(this.getTxSymbol()),this.$$txSymbolProgressListener&&this.$$txSymbolProgressListener(this.getTxSymbolProgress()))},o.prototype.$$handleRxSync=function(){var e=null;switch(this.$$rxSymbolRaw){case this.$$rxSymbolMax-o.$$_SYMBOL_SYNC_A_OFFSET:e=-1;break;case this.$$rxSymbolMax-o.$$_SYMBOL_SYNC_B_OFFSET:e=1}this.$$rxSyncDetector.handle(e,this.$$rxSignalDecibel,this.$$rxNoiseDecibel)},o.prototype.$$getSymbolMin=function(e){switch(e){case 44100:return this.$$symbolMin44100;case 48e3:return this.$$symbolMin48000;default:return this.$$symbolMinDefault}},o.prototype.$$getSymbolMax=function(e){return this.$$getSymbolMin(e)+this.$$symbolRange-1},o.prototype.$$updateOscillator=function(){var e,t,i;(i=this.$$txSymbolManager.getTxSymbolCurrent()).isFsk()?(e=this.$$getFrequency(i.getTxFskSymbol(),this.$$txSampleRate),t=this.$$txAmplitude):(e=o.$$_TX_FREQUENCY_ZERO,t=o.$$_TX_AMPLITUDE_SILENT),this.$$audioMonoIO.setPeriodicWave(e,t)},o.prototype.$$getFrequency=function(e,t){var i=r.getFrequency(e,t,this.$$fftSize);return this.$$fftSkipFactor*i},o.$$isFunction=function(e){return"function"==typeof e},o}}(),function(){AudioNetwork.Injector.registerFactory("Rewrite.PhysicalLayer.RxSyncDetector",e),e.$inject=["Rewrite.Dsp.Correlator"];function e(e){var t;return(t=function(i,r){this.$$samplePerSymbol=i,this.$$rxSyncInProgress=!1,this.$$rxSyncDspDetails=t.$$getEmpty(),this.$$id=t.$$_INITIAL_ID,this.$$correlator=new e(i,r),this.$$blockHistory=void 0,this.$$rxSampleNumber=t.$$_INITIAL_RX_SAMPLE_NUMBER,this.$$initializeBlockHistory()}).$$_FIRST_ELEMENT=0,t.$$_INITIAL_ID=1,t.$$_INITIAL_RX_SAMPLE_NUMBER=0,t.prototype.isRxSyncInProgress=function(){return this.$$rxSyncInProgress},t.prototype.getRxSyncDspDetails=function(){return this.$$rxSyncDspDetails},t.prototype.handle=function(e,i,r){var n,o,a,s,$,l,c;n=this.$$rxSampleNumber%this.$$samplePerSymbol,o=this.$$blockHistory[n],a=n===this.$$samplePerSymbol-1,this.$$correlator.handle(e,i,r),(s=this.$$correlator.isCorrelated())&&((c=t.$$getEmpty()).rxSymbolSamplingPointOffset=n,c.rxCorrelationValue=this.$$correlator.getCorrelationValue(),c.rxCorrelationCodeLength=this.$$correlator.getCorrelationCodeLength(),c.rxSignalDecibelAverage=this.$$correlator.getSignalDecibelAverage(),c.rxNoiseDecibelAverage=this.$$correlator.getNoiseDecibelAverage(),c.rxSignalToNoiseRatio=this.$$correlator.getSignalToNoiseRatio(),o.decisionList.push(c)),l=o.syncDetected,o.syncJustLost=l&&!s,o.syncDetected=s,a&&($=this.$$tryToUpdateSync()),this.$$rxSyncInProgress=!$&&this.$$isRxSyncInProgressInHistoryBlock(),this.$$rxSampleNumber++},t.prototype.$$sortByCorrelationValue=function(e,t){return e.rxCorrelationValuet.rxCorrelationValue?-1:0},t.prototype.$$sortBySignalDecibel=function(e,t){return e.rxSignalDecibelAveraget.rxSignalDecibelAverage?-1:0},t.prototype.$$sortDecisionList=function(e){var t=this;e.sort(function(e,i){return t.$$sortByCorrelationValue(e,i)||t.$$sortBySignalDecibel(e,i)})},t.prototype.$$initializeBlockHistory=function(){var e;for(this.$$blockHistory=[],e=0;e0&&(this.$$sortDecisionList(r),i.push(r[t.$$_FIRST_ELEMENT]));return this.$$sortDecisionList(i),i[t.$$_FIRST_ELEMENT]},t.prototype.$$updateSync=function(){this.$$rxSyncDspDetails=this.$$getTheBestRxSyncDspDetails(),this.$$rxSyncDspDetails.id=this.$$id++,this.$$resetBlockHistory(),this.$$correlator.reset()},t.prototype.$$tryToUpdateSync=function(){var e;for(e=0;e0||this.$$txSymbolCurrent.isNotIdle()},t.prototype.addTxFskSymbol=function(t){var i=new e(this.$$txSymbolId++,e.TX_SYMBOL_FSK);return i.setTxFskSymbol(t),this.$$txSymbolQueue.push(i),i.getId()},t.prototype.addTxSymbolGapImportant=function(){var t=new e(this.$$txSymbolId++,e.TX_SYMBOL_GAP_IMPORTANT);this.$$txSymbolQueue.push(t)},t.prototype.addTxSymbolGapDeletable=function(){var t=new e(this.$$txSymbolId++,e.TX_SYMBOL_GAP_DELETABLE);this.$$txSymbolQueue.push(t)},t.prototype.$$getTxSymbolIdle=function(){return new e(this.$$txSymbolId++,e.TX_SYMBOL_IDLE)},t.prototype.isTxAboutToStart=function(){var e=0!==this.$$txSymbolQueue.length;return this.$$txSymbolCurrent.isIdle()&&e},t.prototype.isTxAboutToEnd=function(){return 0===this.$$txSymbolQueue.length&&this.$$txSymbolCurrent.isNotIdle()},t.prototype.tick=function(){var e,t;t=0===this.$$txSymbolQueue.length,this.$$txSymbol=this.$$txSymbolCurrent,t?(e=this.$$getTxSymbolIdle(),this.$$txSymbolCurrent=e):this.$$txSymbolCurrent=this.$$txSymbolQueue.shift()},t.prototype.handleGapLogicAtStart=function(){this.isTxInProgress()?this.$$clearAllDeletableGapFromTheEndOfTheQueue():(this.addTxSymbolGapDeletable(),this.addTxSymbolGapDeletable())},t.prototype.handleGapLogicAtEnd=function(){this.addTxSymbolGapDeletable()},t.prototype.handleGapLogicAtEndOfSync=function(e){var t;for(t=0;t=0;e--)if(this.$$txSymbolQueue[e].isNotGapDeletable()){this.$$txSymbolQueue.length=e+1;break}},t}}(),function(){AudioNetwork.Injector.registerFactory("Rewrite.PhysicalLayer.TxSymbol",e),e.$inject=[];function e(){var e;return(e=function(e,t){this.$$id=e,this.$$txSymbolType=t,this.$$txFskSymbol=null}).TX_SYMBOL_IDLE="TX_SYMBOL_IDLE",e.TX_SYMBOL_GAP_IMPORTANT="TX_SYMBOL_GAP_IMPORTANT",e.TX_SYMBOL_GAP_DELETABLE="TX_SYMBOL_GAP_DELETABLE",e.TX_SYMBOL_FSK="TX_SYMBOL_FSK",e.prototype.setTxFskSymbol=function(e){this.$$txFskSymbol=e},e.prototype.cloneClean=function(){return{id:this.$$id,txSymbolType:this.$$txSymbolType,txFskSymbol:this.$$txFskSymbol}},e.prototype.isNotIdle=function(){return this.$$txSymbolType!==e.TX_SYMBOL_IDLE},e.prototype.isIdle=function(){return this.$$txSymbolType===e.TX_SYMBOL_IDLE},e.prototype.isFsk=function(){return this.$$txSymbolType===e.TX_SYMBOL_FSK},e.prototype.isNotGapDeletable=function(){return this.$$txSymbolType!==e.TX_SYMBOL_GAP_DELETABLE},e.prototype.getId=function(){return this.$$id},e.prototype.getTxFskSymbol=function(){return this.$$txFskSymbol},e}}(),function(){AudioNetwork.Injector.registerFactory("Rewrite.Util.Buffer",e),e.$inject=[];function e(){var e;return(e=function(e){this.$$data=[],this.$$positionStart=null,this.$$positionEnd=null,this.$$size=null,this.$$sizeMax=null,this.setSizeMax(e)}).prototype.clone=function(){var t,i=new e(this.$$sizeMax),r=this.$$data.length;for(i.$$positionStart=this.$$positionStart,i.$$positionEnd=this.$$positionEnd,i.$$size=this.$$size,t=0;t=this.$$size||e<0?null:this.$$data[(this.$$positionStart+e)%this.$$sizeMax]},e.prototype.getSize=function(){return this.$$size},e.prototype.getSizeMax=function(){return this.$$sizeMax},e.prototype.isFull=function(){return this.$$size===this.$$sizeMax},e.prototype.getAll=function(){var e,t=[];for(e=0;e1?1:e},e.$$floatTo16BitPCM=function(t,i,r){var n,o,a;for(n=0;n=n)throw e.START_TIME_NEEDS_TO_GREATER_THAN_END_TIME_EXCEPTION;t.setValueAtTime(t.value,o+r),t.linearRampToValueAtTime(i,o+n)},e.prototype.$$setImmediately=function(e,t){var i=this.$$audioContext.currentTime;e.value=t,e.setValueAtTime(t,i)},e.$$isFunction=function(e){return"function"==typeof e},e.$$getValueOrDefault=function(e,t){return void 0!==e?e:t},e.prototype.microphoneDisable=function(){var e;this.$$microphone&&(this.$$microphone.disconnect(this.$$microphoneVirtual),this.$$microphone=null,this.$$microphoneStream&&"function"==typeof this.$$microphoneStream.getTracks&&(e=this.$$microphoneStream.getTracks())&&e.length>0&&"function"==typeof e[0].stop&&(e[0].stop(),this.$$microphoneStream=null))},e.prototype.microphoneEnable=function(){this.$$connectMicrophoneTo(this.$$microphoneVirtual)},e.prototype.setVolume=function(e){this.$$setImmediately(this.$$masterOutVolume.gain,e)},e.prototype.isLoopbackEnabled=function(){return this.$$loopbackEnabled},e.prototype.setLoopback=function(e){return e=!!e,this.$$loopbackEnabled!==e&&(this.$$sourceDetach(),this.$$loopbackEnabled=e,this.$$sourceAttach(),!0)},e.prototype.setPeriodicWaveFading=function(e,t,i){this.$$setLinearly(this.$$outOscillatorGain.gain,e,t,i)},e.prototype.setPeriodicWave=function(t,i,r,n,o){var a,s;s=void 0===r&&void 0===n&&void 0===o,t=e.$$getValueOrDefault(t,e.$$_OUTPUT_WAVE_FREQUENCY),((i=e.$$getValueOrDefault(i,e.$$_OUTPUT_WAVE_VOLUME))||0===i)&&this.$$setImmediately(this.$$outOscillatorGain.gain,i),(t||0===t)&&this.$$setImmediately(this.$$outOscillator.frequency,t),s?this.$$outOscillator.type="sine":(r=e.$$getValueOrDefault(r,e.$$_OUTPUT_WAVE_PHASE),n=e.$$getValueOrDefault(n,e.$$_OUTPUT_WAVE_HARMONIC_AMPLITUDE),o=e.$$getValueOrDefault(o,e.$$_OUTPUT_WAVE_HARMONIC_PHASE),a=this.$$getPeriodicWave(r,n,o),this.$$outOscillator.setPeriodicWave(a))},e.prototype.$$getPeriodicWave=function(e,t,i){var r,n,o,a,s,$;if(t.length!==i.length)throw"Length of amplitude and phase arrays should match";if(t.length<1)throw"Amplitude and phase arrays should have at least one item";for(r=new Float32Array(1+t.length),n=new Float32Array(1+t.length),s=2*Math.PI*-e,r[0]=0,n[0]=0,a=0;a 0";a.push({amplitude:void 0!==r.amplitude?r.amplitude:1,duration:t.round(c.getSampleRate()*r.duration),phase:void 0!==r.phase?r.phase:0})}o.addToQueue(a)},u.prototype.rx=function(e){this.$$rxExternalHandler.callback="function"==typeof e?e:null},u.prototype.getSampleRate=function(){return c.getSampleRate()},u.prototype.destroy=function(){var e,t,i=[];if(this.setRxInput(null),this.$$rxAnalyserChart&&(i.push(this.$$rxAnalyserChart.destroy()),this.$$rxAnalyserChart=null),this.$$rxAnalyser.disconnect(this.$$channelReceiveManager.getInputNode()),this.$$rxConstellationDiagram)for(e=0;e.005&&(r=this.$$physicalLayer.getRxFrequency(e,0),console.log("phase history current",r),this.$$physicalLayer.setRxFrequency(e,0,r+t),console.log("Frequency corrected for channel "+e+" at ofdm 0: "+(r+t))),this.$$frequencyUpdateHandler&&this.$$frequencyUpdateHandler(e,t))},r.prototype.$$phaseCorrectionUpdateInternalHandler=function(e,t){var i,r;for(r=0;r=this.$$physicalLayer.getRxChannelSize())throw"Given channelIndex is outside range: "+e},r.prototype.setPacketReceiveHandler=function(e){this.$$packetReceiveHandler="function"==typeof e?e:null},r.prototype.setFrequencyUpdateHandler=function(e){this.$$frequencyUpdateHandler="function"==typeof e?e:null},r.prototype.setPhaseCorrectionUpdateHandler=function(e){this.$$phaseCorrectionUpdateHandler="function"==typeof e?e:null},r.prototype.receive=function(e,t,i){return this.$$checkChannelIndexRange(e),this.$$stateMachineManager[e].receive(t,i)},r}}(),function(){AudioNetwork.Injector.registerFactory("PhysicalLayerAdapter.TransmitAdapter",e),e.$inject=["Common.MathUtil","Common.Util","PhysicalLayer.DefaultConfig"];function e(e,t,i){var r;return(r=function(e){this.$$physicalLayer=e}).AMPLITUDE_DATA_LENGTH_DOES_NOT_MATCH_SYMBOL_LIST_LENGTH_EXCEPTION="Amplitude data length does not match symbol list length",r.$$_SYNCHRONIZATION_SYMBOL=0,r.$$_LOWEST_PSK_SIZE=1,r.$$_ZERO_GUARD_INTERVAL=0,r.$$_ZERO_INTERPACKET_GAP=0,r.$$_NO_SYNC_PREAMBLE=!1,r.$$_UNDEFINED_AMPLITUDE=void 0,r.prototype.symbol=function(e,n,o,a,s){var $,l=this.$$physicalLayer.getTxChannelOfdmSize(e),c=[];for($=0;$0){for(h=[],d=0;d<$.length;d++)h.push({amplitude:0,duration:o});c.push(h)}}if(a>0&&$){for(h=[],d=0;d<$.length;d++)h.push({amplitude:0,duration:a});c.push(h)}for(p=0;p '}}}(),function(){AudioNetwork.Injector.registerFactory("Visualizer.ComplexPlaneChart",e),e.$inject=["Visualizer.Abstract2DVisualizer","Common.Util","Visualizer.ComplexPlaneChartTemplateMain"];function e(e,t,i){var r;return((r=function(i,r,n,o,a,s,$){e.call(this,i,r,n,s,$),this.$$queue=o,this.$$maxValue=t.valueOrDefault(a,1),this.$$hashOnCanvas=null}).prototype=Object.create(e.prototype)).constructor=r,r.$$_VALUE_CIRCLE_STEP=1,r.prototype.setMaxValue=function(e){return this.$$maxValue!==e&&(this.$$maxValue=e,this.$$hashOnCanvas=null,this.$$dropXYCache(),!0)},r.prototype.$$renderTemplate=function(){var e=i.html;return e=(e=e.replace(/\{\{ width \}\}/g,this.$$width.toString())).replace(/\{\{ height \}\}/g,this.$$height.toString())},r.prototype.$$draw=function(){var e,t,i,n,o,a,s,$=this.$$canvasContext,l=this.$$width,c=this.$$height,h=.5*l,u=.5*c,p=this.$$queue;if(this.$$hashOnCanvas!==p.getHash()){for($.clearRect(0,0,l,c),t=0;t<=this.$$maxValue;)i=u*this.$$getNormalizedValue(t),this.$$drawCenteredCircle(i),t+=r.$$_VALUE_CIRCLE_STEP;for(this.$$drawAxis(),s=$.lineWidth,a=0;a {{ label }}'}}}(),function(){AudioNetwork.Injector.registerService("Visualizer.AnalyserChartTemplateMain",e),e.$inject=[];function e(){return{html:''}}}(),function(){AudioNetwork.Injector.registerFactory("Visualizer.AnalyserChart",e),e.$inject=["Visualizer.AnalyserChartTemplateAxisX","Visualizer.AnalyserChartTemplateMain","Common.SimplePromiseBuilder","Audio.ActiveAudioContext","Common.MathUtil"];function e(e,t,i,r,n){var o;return(o=function(e,t,i,r,n){this.$$parentElement=e,this.$$analyser=t,this.$$canvas=null,this.$$canvasContext=null,this.$$canvasWidth=null,this.$$canvasHeight=i,this.$$colorData=r,this.$$colorAxis=n,this.$$data=null,this.$$freezeChart=!1,this.$$analyserMethod="getByteFrequencyData",this.$$destroyPromise=null,this.$$initAnimationFrame(),this.$$init()}).$$_AXIS_LABEL_X_ONE_ITEM_WITH=40,o.prototype.destroy=function(){return this.$$destroyPromise?this.$$destroyPromise:(this.$$destroyPromise=i.build(),this.$$destroyPromise)},o.prototype.$$init=function(){this.$$canvasContext=null,this.$$parentElement.innerHTML=this.$$renderTemplate(),this.$$connectTemplate(),this.$$initCanvasContext()},o.prototype.$$find=function(e){var t=this.$$parentElement.querySelectorAll(e);if(0===t.length)throw"Cannot $$find given selector";return t[0]},o.prototype.$$connectTemplate=function(){var e=this;this.$$canvas=this.$$find(".analyser-chart"),this.$$canvasContext=this.$$canvas.getContext("2d"),this.$$canvasWidth=this.$$analyser.fftSize,this.$$find(".analyser-action-freq-timedomain").addEventListener("click",function(){e.actionFrequencyTimeDomainToggle()}),this.$$find(".analyser-action-freeze").addEventListener("click",function(){e.actionFreezeChart()}),this.$$find(".analyser-action-fft256").addEventListener("click",function(){e.actionChangeFFTSize(256)}),this.$$find(".analyser-action-fft512").addEventListener("click",function(){e.actionChangeFFTSize(512)}),this.$$find(".analyser-action-fft1024").addEventListener("click",function(){e.actionChangeFFTSize(1024)}),this.$$find(".analyser-action-fft2048").addEventListener("click",function(){e.actionChangeFFTSize(2048)}),this.$$find(".analyser-action-fft4096").addEventListener("click",function(){e.actionChangeFFTSize(4096)}),this.$$find(".analyser-action-fft8192").addEventListener("click",function(){e.actionChangeFFTSize(8192)}),this.$$find(".analyser-action-fft16384").addEventListener("click",function(){e.actionChangeFFTSize(16384)})},o.prototype.actionFrequencyTimeDomainToggle=function(){"getByteFrequencyData"===this.$$analyserMethod?this.$$analyserMethod="getByteTimeDomainData":this.$$analyserMethod="getByteFrequencyData",this.$$generateAxisX()},o.prototype.actionFreezeChart=function(){this.$$freezeChart=!this.$$freezeChart},o.prototype.actionChangeFFTSize=function(e){this.$$analyser.fftSize=e,this.$$init()},o.prototype.$$renderTemplate=function(){var e=t.html;return e=(e=e.replace(/\{\{ width \}\}/g,this.$$analyser.frequencyBinCount.toString())).replace(/\{\{ height \}\}/g,this.$$canvasHeight.toString())},o.prototype.$$renderTemplateAxisXLabel=function(t,i,r){var n=e.html;return n=(n=(n=(n=n.replace(/\{\{ width \}\}/g,t)).replace(/\{\{ left \}\}/g,i)).replace(/\{\{ label \}\}/g,r)).replace(/\{\{ colorAxis \}\}/g,this.$$colorAxis)},o.prototype.$$generateAxisXForTimeDomain=function(){var e,t,i=[5e-4,.001,.002,.005,.01,.025,.05,.1,.25,.5],a=r.getSampleRate(),s=o.$$_AXIS_LABEL_X_ONE_ITEM_WITH/a,$=0,l="";for(t=0;t=s||t==i.length-1){s=i[t];break}for(;$=s||t==i.length-1){s=i[t];break}for(;$<.5*r.getSampleRate();)e=n.round($*a),l+=this.$$renderTemplateAxisXLabel(o.$$_AXIS_LABEL_X_ONE_ITEM_WITH,e,$+"Hz"),$+=s;return l},o.prototype.$$generateAxisX=function(){var e=this.$$find(".analyser-axis-x");"getByteFrequencyData"==this.$$analyserMethod?e.innerHTML=" "+this.$$generateAxisXForFrequency():e.innerHTML=" "+this.$$generateAxisXForTimeDomain()},o.prototype.$$updateChart=function(){var e,t=this.$$data.length,i=this.$$canvasContext;if(null!==i&&!this.$$freezeChart)for(i.clearRect(0,0,this.$$canvasWidth,this.$$canvasHeight),this.$$analyser[this.$$analyserMethod](this.$$data),e=0;e '}}}(),function(){AudioNetwork.Injector.registerFactory("Visualizer.FrequencyDomainChart",e),e.$inject=["Visualizer.AbstractVisualizer","Visualizer.FrequencyDomainChartTemplateMain","Common.Util"];function e(e,t,i){var r;return((r=function(t,r,n,o,a,s,$,l,c,h){e.call(this,t,r,n),this.$$frequencyDomainQueue=o,this.$$powerDecibelMin=i.valueOrDefault(a,-40),this.$$radius=i.valueOrDefault(s,1.1),this.$$barWidth=i.valueOrDefault($,1),this.$$barSpacingWidth=i.valueOrDefault(l,0),this.$$colorAxis=i.valueOrDefault(c,"#EEE"),this.$$colorSample=i.valueOrDefault(h,"#738BD7"),this.$$checkWidth(),this.$$hashOnCanvas=null}).prototype=Object.create(e.prototype)).constructor=r,r.QUEUE_SIZE_NOT_MATCH_CHART_WIDTH="Queue size not match chart width",r.$$_POWER_DECIBEL_AXIS_LINE_STEP=10,r.prototype.setWidth=function(e){var t;return this.$$width!==e&&(this.$$width=e,this.$$checkWidth(),(t=this.$$find(".frequency-domain-chart-container")).style.width=e+"px",(t=this.$$find(".frequency-domain-chart")).style.width=e+"px",t.setAttribute("width",e),this.$$hashOnCanvas=null,!0)},r.prototype.$$checkWidth=function(){if(this.$$frequencyDomainQueue.getSizeMax()*(this.$$barWidth+this.$$barSpacingWidth)!==this.$$width)throw r.QUEUE_SIZE_NOT_MATCH_CHART_WIDTH},r.prototype.$$renderTemplate=function(){var e=t.html;return e=(e=e.replace(/\{\{ width \}\}/g,this.$$width.toString())).replace(/\{\{ height \}\}/g,this.$$height.toString())},r.prototype.setPowerDecibelMin=function(e){return this.$$powerDecibelMin!==e&&(this.$$powerDecibelMin=e,this.$$hashOnCanvas=null,!0)},r.prototype.$$draw=function(){var e,t,i,n,o,a=this.$$canvasContext,s=this.$$frequencyDomainQueue,$=this.$$width,l=this.$$height;if(this.$$hashOnCanvas!==s.getHash()){for(a.clearRect(0,0,$,l),a.strokeStyle=this.$$colorAxis,t=0;t<=-this.$$powerDecibelMin;t+=r.$$_POWER_DECIBEL_AXIS_LINE_STEP)n=t*l/-this.$$powerDecibelMin,a.beginPath(),a.moveTo(0,n),a.lineTo($,n),a.closePath(),a.stroke();for(a.fillStyle=this.$$colorSample,o=.5*(this.$$barWidth-1),t=0;t=1&&(a.beginPath(),a.moveTo(i,0),a.lineTo(i,l),a.closePath(),a.stroke()),n>=l||(a.beginPath(),a.arc(i+this.$$barSpacingWidth+o,n,this.$$radius,0,2*Math.PI,!1),a.fill());this.$$hashOnCanvas=s.getHash()}},r.prototype.$$initCanvasContext=function(){this.$$canvasContext.lineWidth=1},r}}(),function(){AudioNetwork.Injector.registerService("Visualizer.ConstellationDiagramBuilder",e),e.$inject=["Visualizer.ConstellationDiagram"];function e(e){return{build:function(t,i,r,n,o,a,s,$,l,c){return new e(t,i,r,n,o,a,s,$,l,c)}}}}(),function(){AudioNetwork.Injector.registerService("Visualizer.ConstellationDiagramTemplateMain",e),e.$inject=[];function e(){return{html:'
'}}}(),function(){AudioNetwork.Injector.registerFactory("Visualizer.ConstellationDiagram",e),e.$inject=["Visualizer.Abstract2DVisualizer","Common.MathUtil","Common.Util","Visualizer.ConstellationDiagramTemplateMain"];function e(e,t,i,r){var n;return((n=function(t,r,n,o,a,s,$,l,c,h){e.call(this,t,r,n,s,l),this.$$queue=o,this.$$colorHistoryPoint=i.valueOrDefault($,{red:{newest:0,tailNewest:100,tailOldest:180},green:{newest:0,tailNewest:100,tailOldest:200},blue:{newest:0,tailNewest:100,tailOldest:150}}),this.$$radius=i.valueOrDefault(c,2),this.$$radiusMain=i.valueOrDefault(h,3),this.$$powerDecibelMin=i.valueOrDefault(a,-40),this.$$hashOnCanvas=null}).prototype=Object.create(e.prototype)).constructor=n,n.$$_POWER_DECIBEL_AXIS_LINE_STEP=10,n.prototype.setPowerDecibelMin=function(e){return this.$$powerDecibelMin!==e&&(this.$$powerDecibelMin=e,this.$$hashOnCanvas=null,this.$$dropXYCache(),!0)},n.prototype.$$renderTemplate=function(){var e=r.html;return e=(e=e.replace(/\{\{ width \}\}/g,this.$$width.toString())).replace(/\{\{ height \}\}/g,this.$$height.toString())},n.prototype.$$draw=function(){var e,t,i,r,o,a,s,$,l,c=this.$$colorHistoryPoint,h=this.$$canvasContext,u=this.$$width,p=this.$$height,d=.5*u,m=.5*p,y=this.$$queue;if(this.$$hashOnCanvas!==y.getHash()){for(h.clearRect(0,0,u,p),t=0;t>=this.$$powerDecibelMin;)o=m*this.$$getNormalizedPowerDecibel(t),this.$$drawCenteredCircle(o),t-=n.$$_POWER_DECIBEL_AXIS_LINE_STEP;for(this.$$drawAxis(),$=0;$ '}}}(),function(){AudioNetwork.Injector.registerFactory("Visualizer.PowerChart",e),e.$inject=["Visualizer.PowerChartTemplateMain","Common.SimplePromiseBuilder"];function e(e,t){var i;return(i=function(e,t,i,r){this.$$parentElement=e,this.$$canvas=null,this.$$canvasContext=null,this.$$canvasWidth=t,this.$$canvasHeight=i,this.$$queue=r,this.$$destroyPromise=null,this.$$initAnimationFrame(),this.$$init()}).prototype.destroy=function(){return this.$$destroyPromise?this.$$destroyPromise:(this.$$destroyPromise=t.build(),this.$$destroyPromise)},i.prototype.$$init=function(){this.$$canvasContext=null,this.$$parentElement.innerHTML=this.$$renderTemplate(),this.$$connectTemplate(),this.$$initCanvasContext()},i.prototype.$$find=function(e){var t=this.$$parentElement.querySelectorAll(e);if(0===t.length)throw"Cannot $$find given selector";return t[0]},i.prototype.$$connectTemplate=function(){this.$$canvas=this.$$find(".power-chart"),this.$$canvasContext=this.$$canvas.getContext("2d")},i.prototype.$$renderTemplate=function(){var t=e.html;return t=(t=t.replace(/\{\{ width \}\}/g,this.$$canvasWidth.toString())).replace(/\{\{ height \}\}/g,this.$$canvasHeight.toString())},i.prototype.$$updateChart=function(){var e,t,i,r=this.$$canvasContext,n=this.$$queue,o=this.$$canvasWidth,a=this.$$canvasHeight;if(null!==r){for(r.clearRect(0,0,o,a),i=0;i '}}}(),function(){AudioNetwork.Injector.registerFactory("Visualizer.SampleChart",e),e.$inject=["Visualizer.AbstractVisualizer","Visualizer.SampleChartTemplateMain","Common.Util"];function e(e,t,i){var r;return((r=function(t,r,n,o,a,s,$,l,c,h){e.call(this,t,r,n),this.$$queue=o,this.$$radius=i.valueOrDefault(a,1.1),this.$$barWidth=i.valueOrDefault(s,1),this.$$barSpacingWidth=i.valueOrDefault($,0),this.$$colorAxis=i.valueOrDefault(l,"#EEE"),this.$$colorSample=i.valueOrDefault(c,"rgba(115, 139, 215, 1.0"),this.$$colorBar=i.valueOrDefault(h,"rgba(115, 139, 215, 0.9)"),this.$$sampleBackgroundActive=!1,this.$$checkWidth(),this.$$hashOnCanvas=null}).prototype=Object.create(e.prototype)).constructor=r,r.QUEUE_SIZE_NOT_MATCH_CHART_WIDTH="Queue size not match chart width",r.prototype.setWidth=function(e){var t;return this.$$width!==e&&(this.$$width=e,this.$$checkWidth(),(t=this.$$find(".sample-chart-container")).style.width=e+"px",(t=this.$$find(".sample-chart")).style.width=e+"px",t.setAttribute("width",e),this.$$hashOnCanvas=null,!0)},r.prototype.enableSampleBackground=function(){return!this.$$sampleBackgroundActive&&(this.$$sampleBackgroundActive=!0,this.$$hashOnCanvas=null,!0)},r.prototype.$$checkWidth=function(){if(this.$$queue.getSizeMax()*(this.$$barWidth+this.$$barSpacingWidth)!==this.$$width)throw r.QUEUE_SIZE_NOT_MATCH_CHART_WIDTH},r.prototype.$$renderTemplate=function(){var e=t.html;return e=(e=e.replace(/\{\{ width \}\}/g,this.$$width.toString())).replace(/\{\{ height \}\}/g,this.$$height.toString())},r.prototype.$$draw=function(){var e,t,i,r,n,o=this.$$canvasContext,a=this.$$queue,s=this.$$width,$=this.$$height,l=.5*this.$$height;if(this.$$hashOnCanvas!==a.getHash()){for(o.clearRect(0,0,s,$),o.strokeStyle=this.$$colorAxis,o.beginPath(),o.moveTo(0,l),o.lineTo(s,l),o.closePath(),o.stroke(),n=.5*(this.$$barWidth-1),t=0;t0&&(1===this.$$barSpacingWidth?(o.strokeStyle=this.$$colorAxis,o.beginPath(),o.moveTo(i,0),o.lineTo(i,$),o.closePath(),o.stroke()):(o.fillStyle=this.$$colorAxis,o.fillRect(i,0,this.$$barSpacingWidth,$))),this.$$sampleBackgroundActive&&(1===this.$$barWidth?(o.strokeStyle=this.$$colorBar,o.beginPath(),o.moveTo(i+this.$$barSpacingWidth,l),o.lineTo(i+this.$$barSpacingWidth,r),o.closePath(),o.stroke()):(o.fillStyle=this.$$colorBar,o.fillRect(i+this.$$barSpacingWidth,l0},e.prototype.getSize=function(){return this.$$valueList.length},e.prototype.clearAll=function(){this.clearList(),this.$$lastFinalizedSize=void 0,this.$$lastFinalizedResult=void 0},e.prototype.clearList=function(){this.$$valueList.length=0},e.prototype.finalize=function(){return this.$$lastFinalizedResult=this.$$finalize(),this.$$lastFinalizedSize=this.getSize(),this.clearList(),this.$$lastFinalizedResult},e.prototype.getLastFinalizedSize=function(){return this.$$lastFinalizedSize},e.prototype.getLastFinalizedResult=function(){return this.$$lastFinalizedResult},e.prototype.$$finalize=function(){throw e.ABSTRACT_METHOD_CALLED_EXCEPTION},e}}(),function(){AudioNetwork.Injector.registerService("Common.AverageValueCollectorBuilder",e),e.$inject=["Common.AverageValueCollector"];function e(e){return{build:function(){return new e}}}}(),function(){AudioNetwork.Injector.registerFactory("Common.AverageValueCollector",e),e.$inject=["Common.AbstractValueCollector","Common.Util"];function e(e,t){var i;return((i=function(){e.apply(this,arguments)}).prototype=Object.create(e.prototype)).constructor=i,i.EMPTY_LIST_EXCEPTION="Cannot finalize AverageValueCollector without any samples collected",i.prototype.$$finalize=function(){if(0===this.$$valueList.length)throw i.EMPTY_LIST_EXCEPTION;return t.computeAverage(this.$$valueList)},i}}(),function(){AudioNetwork.Injector.registerService("Common.CarrierGenerateBuilder",e),e.$inject=["Common.CarrierGenerate"];function e(e){return{build:function(t){return new e(t)}}}}(),function(){AudioNetwork.Injector.registerFactory("Common.CarrierGenerate",e),e.$inject=["Common.MathUtil","Common.Util"];function e(e,t){var i;return(i=function(e,t){this.$$samplePerFade=t,this.$$queue=[],this.$$sampleComputed=null,this.$$currentCarrier={data:null,sampleNumberStart:null,sampleNumberEnd:null},this.$$samplePerPeriod=null,this.$$omega=null,this.$$sampleNumber=0,this.$$phaseCorrection=0,this.setSamplePerPeriod(e)}).prototype.$$sampleCompute=function(){var i,r,n,o=this.$$currentCarrier.data;o?(i=1,this.$$samplePerFade>0&&(r=(this.$$sampleNumber-this.$$currentCarrier.sampleNumberStart)/this.$$samplePerFade,n=(this.$$currentCarrier.sampleNumberEnd-this.$$sampleNumber)/this.$$samplePerFade,r>=0&&r<=1?i=t.unitFade(r):n>=0&&n<=1&&(i=t.unitFade(n))),this.$$sampleComputed=i*o.amplitude*e.sin(this.$$omega*this.$$sampleNumber-e.TWO_PI*(o.phase-this.$$phaseCorrection))):this.$$sampleComputed=0},i.prototype.$$grabCurrentCarrier=function(){var e;(e=t.queuePop(this.$$queue))?e===this.$$currentCarrier.data||(this.$$currentCarrier.data=e,this.$$currentCarrier.sampleNumberStart=this.$$sampleNumber,this.$$currentCarrier.sampleNumberEnd=this.$$currentCarrier.sampleNumberStart+e.duration):(this.$$currentCarrier.data=null,this.$$currentCarrier.sampleNumberStart=null,this.$$currentCarrier.sampleNumberEnd=null)},i.prototype.setPhaseCorrection=function(e){this.$$phaseCorrection=e},i.prototype.nextSample=function(){this.$$sampleNumber++,this.$$sampleComputed=null},i.prototype.getSample=function(){return this.$$sampleComputed?this.$$sampleComputed:(this.$$grabCurrentCarrier(),this.$$sampleCompute(),this.$$sampleComputed)},i.prototype.addToQueue=function(e){t.queueAdd(this.$$queue,e,function(e,t){e.amplitude=t.amplitude,e.phase=t.phase})},i.prototype.reset=function(){this.$$sampleNumber=0},i.prototype.setSamplePerPeriod=function(t){return t!==this.$$samplePerPeriod&&(this.$$samplePerPeriod=t,this.$$omega=e.TWO_PI/this.$$samplePerPeriod,this.$$sampleNumber=0,!0)},i}}(),function(){AudioNetwork.Injector.registerService("Common.CarrierRecoveryBuilder",e),e.$inject=["Common.CarrierRecovery"];function e(e){return{build:function(t,i){return new e(t,i)}}}}(),function(){AudioNetwork.Injector.registerFactory("Common.CarrierRecovery",e),e.$inject=["Common.QueueBuilder","Common.MathUtil","Common.Util","Common.ComplexBuilder"];function e(e,t,i,r){var n;return(n=function(e,t){this.$$samplePerDftWindow=void 0,this.$$complexQueue=void 0,this.$$complexQueueSum=void 0,this.setSamplePerDftWindow(t),this.$$samplePerPeriod=void 0,this.$$omega=void 0,this.$$sampleNumber=void 0,this.setSamplePerPeriod(e)}).prototype.$$getUnitComplex=function(){var e=this.$$omega*this.$$sampleNumber;return r.build(-t.cos(e),t.sin(e))},n.prototype.handleSample=function(e){var t,i;this.$$complexQueue.isFull()&&(t=this.$$complexQueue.pop(),this.$$complexQueueSum.sub(t)),(i=this.$$getUnitComplex()).mulScalar(e),this.$$complexQueue.push(i),this.$$complexQueueSum.add(i),this.$$sampleNumber++},n.prototype.getCarrierDetail=function(){var e=r.copy(this.$$complexQueueSum);return e.divScalar(this.$$complexQueue.getSize()),{phase:e.findUnitAngle(),powerDecibel:i.convertToDecibel(e.getAbsoluteValue())}},n.prototype.setSamplePerDftWindow=function(t){return t!==this.$$samplePerDftWindow&&(this.$$samplePerDftWindow=t,this.$$complexQueue=e.build(t),this.$$complexQueueSum=r.build(0,0),!0)},n.prototype.setSamplePerPeriod=function(e){return e!==this.$$samplePerPeriod&&(this.$$samplePerPeriod=e,this.$$omega=t.TWO_PI/this.$$samplePerPeriod,this.$$sampleNumber=0,!0)},n}}(),function(){AudioNetwork.Injector.registerService("Common.ComplexBuilder",e),e.$inject=["Common.Complex"];function e(e){return{build:function(t,i){return new e(t,i)},copy:function(t){return new e(t.real,t.imm)}}}}(),function(){AudioNetwork.Injector.registerFactory("Common.Complex",e),e.$inject=["Common.Util","Common.MathUtil"];function e(e,t){var i;return(i=function(e,t){this.real=e,this.imm=t}).prototype.add=function(e){this.real+=e.real,this.imm+=e.imm},i.prototype.sub=function(e){this.real-=e.real,this.imm-=e.imm},i.prototype.mulScalar=function(e){this.real*=e,this.imm*=e},i.prototype.divScalar=function(e){this.real/=e,this.imm/=e},i.prototype.getAbsoluteValue=function(){return t.sqrt(this.real*this.real+this.imm*this.imm)},i.prototype.findUnitAngle=function(){return e.findUnitAngle(this.real,this.imm)},i}}(),function(){AudioNetwork.Injector.registerService("Common.QueueBuilder",e),e.$inject=["Common.Queue"];function e(e){return{build:function(t){return new e(t)}}}}(),function(){AudioNetwork.Injector.registerFactory("Common.Queue",e),e.$inject=["Common.MathUtil"];function e(e){var t;return(t=function(e){this.$$data=[],this.$$positionStart=null,this.$$positionEnd=null,this.$$size=null,this.$$hash=null,this.$$sizeMax=null,this.setSizeMax(e)}).prototype.$$generateNewHash=function(){this.$$hash=1e6*e.random()},t.prototype.setSizeMax=function(e){this.$$positionStart=0,this.$$positionEnd=0,this.$$size=0,this.$$hash=0,this.$$sizeMax=e,this.$$data.length=0,this.$$data.length=e},t.prototype.getHash=function(){return this.$$hash},t.prototype.push=function(e){return this.$$size!==this.$$sizeMax&&(this.$$data[this.$$positionEnd]=e,this.$$positionEnd=(this.$$positionEnd+1)%this.$$sizeMax,this.$$size++,this.$$generateNewHash(),!0)},t.prototype.pushEvenIfFull=function(e){this.isFull()&&this.pop(),this.push(e)},t.prototype.pop=function(){var e;return 0===this.$$size?null:(e=this.$$data[this.$$positionStart],this.$$positionStart=(this.$$positionStart+1)%this.$$sizeMax,this.$$size--,this.$$generateNewHash(),e)},t.prototype.getItem=function(e){return e>=this.$$size?null:this.$$data[(this.$$positionStart+e)%this.$$sizeMax]},t.prototype.getSize=function(){return this.$$size},t.prototype.getSizeMax=function(){return this.$$sizeMax},t.prototype.isFull=function(){return this.$$size===this.$$sizeMax},t}}(),function(){AudioNetwork.Injector.registerService("Common.Util",e),e.$inject=["Common.MathUtil"];function e(e){function t(e,t){var i,r=t.split("."),n=e;if(e){for(i=0;i=0?i>=0?0:1:i<0?2:3){case 0:n=e.asin(t/r);break;case 1:n=e.asin(-i/r)+e.HALF_PI;break;case 2:n=e.asin(-t/r)+e.PI;break;case 3:n=e.asin(i/r)+1.5*e.PI}return n/e.TWO_PI},unitFade:function(t){return t=(t=t<0?0:t)>1?1:t,.5*(e.sin((t-.5)*e.PI)+1)},queueAdd:function(e,t,i,r){var n;t[r=void 0===r?"duration":r]>0&&((n={})[r]=t[r],i(n,t),e.push(n))},queuePop:function(e,t){var i;return t=void 0===t?"duration":t,0===e.length?null:(e[0][t]--,i=e[0],0===e[0][t]&&e.splice(0,1),i)},findMaxValueIndex:function(e,i){var r,n,o=null,a=null;if(!e)return null;for(r=0;ro)&&(o=n,a=r);return a}}}}(),function(){AudioNetwork.Injector.registerFactory("PhysicalLayer.AbstractChannelManager",e),e.$inject=["Audio.ActiveAudioContext"];function e(e){var t;return(t=function(){this.$$cpuLoadData={blockSampleSize:null,blockTime:null,blockRealTime:null,load:null}}).prototype.getCpuLoadData=function(){var e=this.$$cpuLoadData;return{blockSampleSize:e.blockSampleSize,blockTime:e.blockTime,blockRealTime:e.blockRealTime,load:e.load}},t.prototype.$$computeCpuLoadData=function(t,i,r){var n,o,a=this.$$cpuLoadData;n=i-t,o=r/e.getSampleRate(),a.blockSampleSize=r,a.blockTime=o,a.blockRealTime=n,a.load=n/o},t}}(),function(){AudioNetwork.Injector.registerService("PhysicalLayer.ChannelReceiveBuilder",e),e.$inject=["PhysicalLayer.ChannelReceive"];function e(e){return{build:function(t,i){return new e(t,i)}}}}(),function(){AudioNetwork.Injector.registerFactory("PhysicalLayer.ChannelReceive",e),e.$inject=["Audio.ActiveAudioContext","Common.CarrierRecoveryBuilder","Common.MathUtil"];function e(e,t,i){var r;return(r=function(e,t){this.$$carrierRecovery=[],this.$$carrierFrequency=[],this.$$carrierPhaseCorrection=[],this.$$notifyInterval=null,this.$$notifyHandler=null,this.$$index=e,this.configure(t)}).OFDM_INDEX_OUT_OF_RANGE_EXCEPTION="OFDM index out of range: ",r.prototype.configure=function(i){var r,n,o,a;for(r=0;r=this.$$carrierRecovery.length)throw r.OFDM_INDEX_OUT_OF_RANGE_EXCEPTION+e},r.prototype.getOfdmSize=function(){return this.$$carrierRecovery.length},r.prototype.getRxPhaseCorrection=function(e){return this.$$checkOfdmIndex(e),this.$$carrierPhaseCorrection[e]},r.prototype.getFrequency=function(e){return this.$$checkOfdmIndex(e),this.$$carrierFrequency[e]},r.prototype.setRxPhaseCorrection=function(e,t){this.$$checkOfdmIndex(e),this.$$carrierPhaseCorrection[e]=t-i.floor(t)},r.prototype.setFrequency=function(t,i){var r;this.$$checkOfdmIndex(t),r=e.getSampleRate()/i,this.$$carrierRecovery[t].setSamplePerPeriod(r),this.$$carrierFrequency[t]=i},r.prototype.handleSample=function(t,r,n,o){var a,s,$,l,c,h;for((a=r%this.$$notifyInterval==0)&&(c=[]),l=0;l=this.$$channelReceive.length)throw r.CHANNEL_INDEX_OUT_OF_RANGE_EXCEPTION+e;return this.$$channelReceive[e]},r.prototype.getBufferSize=function(){return this.$$scriptNode.bufferSize},r.prototype.$$init=function(){var e,n;for(this.$$scriptNode=t.createScriptProcessor(this.$$bufferSize,1,1),this.$$scriptNode.onaudioprocess=this.onAudioProcess.bind(this),this.$$analyserNode=t.createAnalyser(),this.$$analyserNode.fftSize=r.$$_LOWEST_FFT_SIZE,this.$$scriptNode.connect(this.$$analyserNode),e=0;e=this.$$carrierGenerate.length)throw r.OFDM_INDEX_OUT_OF_RANGE_EXCEPTION+e},r.prototype.getTxPhaseCorrection=function(e){return this.$$checkOfdmIndex(e),this.$$carrierPhaseCorrection[e]},r.prototype.getFrequency=function(e){return this.$$checkOfdmIndex(e),this.$$carrierFrequency[e]},r.prototype.setTxPhaseCorrection=function(t,i){this.$$checkOfdmIndex(t),this.$$carrierPhaseCorrection[t]=i-e.floor(i),this.$$carrierGenerate[t].setPhaseCorrection(this.$$carrierPhaseCorrection[t])},r.prototype.setFrequency=function(e,i){var r;this.$$checkOfdmIndex(e),r=t.getSampleRate()/i,this.$$carrierGenerate[e].setSamplePerPeriod(r),this.$$carrierFrequency[e]=i},r.prototype.configure=function(e){var r,n,o,a;for(r=0;r=this.$$channelTransmit.length)throw o.CHANNEL_INDEX_OUT_OF_RANGE_EXCEPTION+e;return this.$$channelTransmit[e]},o.prototype.getBufferSize=function(){return this.$$scriptNode.bufferSize},o.prototype.$$init=function(){var e,t;for(this.$$scriptNode=i.createScriptProcessor(this.$$bufferSize,1,1),this.$$scriptNode.onaudioprocess=this.onAudioProcess.bind(this),e=0;e0&&this.$$delayedData.splice(0,o)},r.prototype.handle=function(e,t,i){this.$$delayedData.push({channelIndex:e,carrierDetail:t,time:i})},r.prototype.$$handle=function(i,r,n){var o,a;for(o=0;o=this.$$valueList.length?this.$$valueList.length-1:r)&&ithis.$$symbolStateMaxDurationTime)||(this.$$changeState(e.SYNC,i),!1)):(this.$$changeState(e.GUARD,i),!1)},t.prototype.$$handlerSync=function(t,i){return t?(this.$$changeState(null,i),this.$$stateHandler[e.SYNC](this.$$stateDurationTime),!(this.$$stateDurationTime>this.$$syncStateMaxDurationTime)||(this.$$changeState(e.ERROR,i),!1)):(this.$$changeState(e.IDLE,i),!1)},t.prototype.$$handlerGuard=function(t,i){return t?(this.$$changeState(e.SYMBOL,i),!1):(this.$$changeState(null,i),this.$$stateHandler[e.GUARD](this.$$stateDurationTime),!(this.$$stateDurationTime>this.$$guardStateMaxDurationTime)||(this.$$changeState(e.IDLE,i),!1))},t.prototype.$$handlerError=function(t,i){return t?(this.$$changeState(null,i),this.$$stateHandler[e.ERROR](this.$$stateDurationTime),!0):(this.$$changeState(e.IDLE,i),!1)},t.prototype.setGuardStateMaxDurationTime=function(e){this.$$guardStateMaxDurationTime=e},t.prototype.setSymbolStateMaxDurationTime=function(e){this.$$symbolStateMaxDurationTime=e},t.prototype.setSyncStateMaxDurationTime=function(e){this.$$syncStateMaxDurationTime=e},t.prototype.getState=function(i,r){var n,o=e;if(this.$$resetFlag&&(this.$$changeState(o.IDLE_INIT,r),this.$$resetFlag=!1),null===this.$$guardStateMaxDurationTime||null===this.$$symbolStateMaxDurationTime||null===this.$$syncStateMaxDurationTime)throw t.SET_ALL_MAX_DURATION_TIMES_FIRST_EXCEPTION;for(;;){switch(this.$$state){case o.IDLE_INIT:n=this.$$handlerIdleInit(i,r);break;case o.FIRST_SYNC_WAIT:n=this.$$handlerFirstSyncWait(i,r);break;case o.FIRST_SYNC:n=this.$$handlerFirstSync(i,r);break;case o.FATAL_ERROR:n=this.$$handlerFatalError(i,r);break;case o.IDLE:n=this.$$handlerIdle(i,r);break;case o.SYMBOL:n=this.$$handlerSymbol(i,r);break;case o.SYNC:n=this.$$handlerSync(i,r);break;case o.GUARD:n=this.$$handlerGuard(i,r);break;case o.ERROR:n=this.$$handlerError(i,r)}if(n)break}return this.$$state},t}}(),function(){AudioNetwork.Injector.registerService("PhysicalLayerAdapter.RxStateMachineManagerBuilder",e),e.$inject=["PhysicalLayerAdapter.RxStateMachineManager"];function e(e){return{build:function(t,i,r,n){return new e(t,i,r,n)}}}}(),function(){AudioNetwork.Injector.registerFactory("PhysicalLayerAdapter.RxStateMachineManager",e),e.$inject=["Common.MathUtil","Common.Util","Common.AverageValueCollectorBuilder","PhysicalLayer.DefaultConfig","PhysicalLayerAdapter.SignalPowerCollectorBuilder","PhysicalLayerAdapter.GuardPowerCollectorBuilder","PhysicalLayerAdapter.PhaseOffsetCollectorBuilder","PhysicalLayerAdapter.RxStateMachineBuilder","PhysicalLayerAdapter.ReceiveAdapterState"];function e(e,t,i,r,n,o,a,s,$){var l;return(l=function(e,t,r,$){this.$$channelIndex=e,this.$$packetReceiveHandler=t,this.$$frequencyUpdateHandler=r,this.$$phaseCorrectionUpdateHandler=$,this.$$stateMachine=s.build(this.$$handlerIdleInit.bind(this),this.$$handlerFirstSyncWait.bind(this),this.$$handlerFirstSync.bind(this),this.$$handlerFatalError.bind(this),this.$$handlerIdle.bind(this),this.$$handlerSymbol.bind(this),this.$$handlerSync.bind(this),this.$$handlerGuard.bind(this),this.$$handlerError.bind(this)),this.$$sampleCollectionTimeIdleInitState=null,this.$$sampleCollectionTimeFirstSyncState=null,this.$$syncPreamble=null,this.$$pskSize=null,this.$$averageIdlePowerCollector=i.build(),this.$$averageFirstSyncPowerCollector=i.build(),this.$$signalPowerCollector=n.build(),this.$$guardPowerCollector=o.build(),this.$$phaseOffsetCollector=a.build(),this.$$resetInternal()}).$$_INITIAL_POWER_THRESHOLD=0,l.$$_DECIBLES_ABOVE_AVERAGE_IDLE=10,l.$$_OFDM_PILOT_SIGNAL_INDEX=0,l.$$_AVERAGE_POWER_UNIT_FACTOR=.5,l.prototype.$$resetInternal=function(){this.$$averageIdlePowerCollector.clearAll(),this.$$averageFirstSyncPowerCollector.clearAll(),this.$$signalPowerCollector.clearAll(),this.$$guardPowerCollector.clearAll(),this.$$phaseOffsetCollector.clearAll(),this.$$powerThreshold=l.$$_INITIAL_POWER_THRESHOLD,this.$$currentData=null,this.$$dataPacket=[],this.$$dataSymbol=[]},l.prototype.reset=function(){this.$$resetInternal(),this.$$stateMachine.scheduleReset()},l.prototype.setSymbolStateMaxDurationTime=function(e){this.$$stateMachine.setSymbolStateMaxDurationTime(e)},l.prototype.setGuardStateMaxDurationTime=function(e){this.$$stateMachine.setGuardStateMaxDurationTime(e)},l.prototype.setSyncStateMaxDurationTime=function(e){this.$$stateMachine.setSyncStateMaxDurationTime(e)},l.prototype.setSampleCollectionTimeIdleInitState=function(e){this.$$sampleCollectionTimeIdleInitState=e},l.prototype.setSampleCollectionTimeFirstSyncState=function(e){this.$$sampleCollectionTimeFirstSyncState=e},l.prototype.setSyncPreamble=function(e){this.$$syncPreamble=e},l.prototype.setPskSize=function(e){this.$$pskSize=e},l.prototype.$$handlerIdleInit=function(e){var t=this.$$currentData.pilotSignal.powerDecibel,i=null;if(e0&&(this.$$packetReceiveHandler(this.$$channelIndex,this.$$preparePacket(this.$$dataPacket)),this.$$dataPacket.length=0),this.$$phaseOffsetCollector.hasAtLeastItem()&&this.$$frequencyUpdateHandler(this.$$channelIndex,this.$$phaseOffsetCollector.finalize()),this.$$guardPowerCollector.clearList()},l.prototype.$$handlerSymbol=function(e){var t=this.$$currentData.pilotSignal.powerDecibel;this.$$signalPowerCollector.collect(t),this.$$guardPowerCollector.hasAtLeastItem()&&this.$$guardPowerCollector.finalize(),this.$$dataSymbol.push(this.$$currentData)},l.prototype.$$handlerSync=function(e){this.$$phaseOffsetCollector.collect({stateDurationTime:e,carrierDetail:this.$$currentData.carrierDetail})},l.prototype.$$handlerGuard=function(e){var i,r=this.$$currentData.pilotSignal.powerDecibel;this.$$guardPowerCollector.collect(r),this.$$signalPowerCollector.hasAtLeastItem()&&this.$$signalPowerCollector.finalize(),this.$$dataSymbol.length>0&&(i=t.findMaxValueIndex(this.$$dataSymbol,"pilotSignal.powerDecibel"),this.$$dataPacket.push(this.$$dataSymbol[i].carrierDetail),this.$$isCurrentSymbolSyncPreamble()&&this.$$phaseCorrectionUpdateHandler(this.$$channelIndex,this.$$dataSymbol[i].carrierDetail),this.$$dataSymbol=[])},l.prototype.$$handlerError=function(e){},l.prototype.$$preparePacket=function(t){var i,r,n,o,a;for(n=[],i=0;ithis.$$powerThreshold},l.prototype.receive=function(t,i){var r;return this.$$currentData={pilotSignal:t[l.$$_OFDM_PILOT_SIGNAL_INDEX],carrierDetail:t},this.$$isInputReallyConnected()?r=this.$$stateMachine.getState(this.$$isPilotSignalPresent(),i):(r=$.NO_INPUT,this.reset()),{state:r,power:"
averageIdlePower: "+e.round(100*this.$$averageIdlePowerCollector.getLastFinalizedResult())/100+"
averageFirstSyncPower: "+e.round(100*this.$$averageFirstSyncPowerCollector.getLastFinalizedResult())/100+"
delta: "+e.round(100*(this.$$averageFirstSyncPowerCollector.getLastFinalizedResult()-this.$$averageIdlePowerCollector.getLastFinalizedResult()))/100+"
powerThreshold: "+e.round(100*this.$$powerThreshold)/100+"
minGuardPower: "+e.round(100*this.$$guardPowerCollector.getLastFinalizedResult())/100+" sampleSize: "+this.$$guardPowerCollector.getLastFinalizedSize()+"
maxSignalPower: "+e.round(100*this.$$signalPowerCollector.getLastFinalizedResult())/100+" sampleSize: "+this.$$signalPowerCollector.getLastFinalizedSize()+"
delta: "+e.round(100*(this.$$signalPowerCollector.getLastFinalizedResult()-this.$$guardPowerCollector.getLastFinalizedResult()))/100+"
idealPowerThreshold: "+e.round(.5*(this.$$signalPowerCollector.getLastFinalizedResult()+this.$$guardPowerCollector.getLastFinalizedResult())*100)/100+"
"}},l}}(),function(){AudioNetwork.Injector.registerService("PhysicalLayerAdapter.SignalPowerCollectorBuilder",e),e.$inject=["PhysicalLayerAdapter.SignalPowerCollector"];function e(e){return{build:function(){return new e}}}}(),function(){AudioNetwork.Injector.registerFactory("PhysicalLayerAdapter.SignalPowerCollector",e),e.$inject=["Common.AbstractValueCollector","Common.MathUtil"];function e(e,t){var i;return((i=function(){e.apply(this,arguments)}).prototype=Object.create(e.prototype)).constructor=i,i.EMPTY_LIST_EXCEPTION="Cannot finalize SignalPowerCollector without any samples collected",i.prototype.$$finalize=function(){if(0===this.$$valueList.length)throw i.EMPTY_LIST_EXCEPTION;return t.maxInArray(this.$$valueList)},i}}(),function(){AudioNetwork.Injector.registerService("Common.MathUtil",e),e.$inject=[];function e(){return{LN10:Math.LN10,HALF_PI:.5*Math.PI,TWO_PI:2*Math.PI,PI:Math.PI,abs:function(e){return Math.abs(e)},floor:function(e){return Math.floor(e)},asin:function(e){return Math.asin(e)},sqrt:function(e){return Math.sqrt(e)},round:function(e){return Math.round(e)},random:function(){return Math.random()},sin:function(e){return Math.sin(e)},cos:function(e){return Math.cos(e)},log:function(e){return Math.log(e)},minInArray:function(e){return Math.min.apply(null,e)},maxInArray:function(e){return Math.max.apply(null,e)}}}}(),function(){AudioNetwork.Injector.registerService("Common.SimplePromiseBuilder",e),e.$inject=["Common.SimplePromise"];function e(e){function t(){return new e}return{build:t,buildFromList:function(e){var i,r,n,o;for(r=t(),n=0,o=0,i=0;i 0 ? data[0] : null, \n",t+=" param = data.length > 0 ? data[1] : null, \n",t+=" promise; \n",t+=" \n",t+=" switch (messageIndex) { \n",t+=" case ReceiveMulticoreWorker.INITIALIZATION: \n",t+=" receiveWorker = new ReceiveWorker(param); \n",t+=" self.postMessage([ \n",t+=" ReceiveMulticoreWorker.INITIALIZATION_SUCCESS \n",t+=" ]); \n",t+=" break; \n",t+=" case ReceiveMulticoreWorker.HANDLE_SAMPLE_BLOCK: \n",t+=" promise = receiveWorker.handleSampleBlock(param); \n",t+=" break; \n",t+=" case ReceiveMulticoreWorker.COMPUTE_CRAZY_SINE_SUM: \n",t+=" promise = receiveWorker.computeCrazySineSum(param); \n",t+=" break; \n",t+=" } \n",t+=" \n",t+=" if (!promise) { \n",t+=" return; \n",t+=" } \n",t+=" \n",t+=" promise \n",t+=" .then(function (result) { \n",t+=" self.postMessage([ \n",t+=" messageIndex + ReceiveMulticoreWorker.MESSAGE_INDEX_OFFSET_SUCCESS, \n",t+=" result \n",t+=" ]); \n",t+=" }) \n",t+=" .catch(function () { \n",t+=" self.postMessage([ \n",t+=" messageIndex + ReceiveMulticoreWorker.MESSAGE_INDEX_OFFSET_FAIL, \n",t+=" result \n",t+=" ]); \n",t+=" }); \n",t+="} \n",t+=" \n"}}}}(),function(){AudioNetwork.Injector.registerFactory("PhysicalLayerCore.ReceiveMulticoreWorker",e),e.$inject=["PhysicalLayerCore.ReceiveMulticoreWorkerThread","Common.SimplePromiseBuilder"];function e(e,t){var i;return(i=function(t){var r,n,o;if(AudioNetwork.bootConfig.multicoreState===AudioNetwork.MULTICORE_STATE.DISABLED)throw i.MULTICORE_SUPPORT_IS_NOT_ENABLED_EXCEPTION;r=e.getJavaScriptCode(),n=new Blob([r],{type:"application/javascript"}),o=URL.createObjectURL(n),this.$$key=t,this.$$worker=new Worker(o),this.$$worker.onmessage=this.$$onMessage.bind(this),this.$$promise=[],this.$$promise.length=i.MESSAGE_TOTAL,this.$$sendToThread(i.INITIALIZATION,this.$$key)}).MULTICORE_SUPPORT_IS_NOT_ENABLED_EXCEPTION="Multicore support is not enabled",i.PREVIOUS_PROMISE_NOT_RESOLVED_YET_EXCEPTION="Previous promise not resolved yet",i.INITIALIZATION=0,i.INITIALIZATION_SUCCESS=1,i.INITIALIZATION_FAIL=2,i.HANDLE_SAMPLE_BLOCK=3,i.HANDLE_SAMPLE_BLOCK_SUCCESS=4,i.HANDLE_SAMPLE_BLOCK_FAIL=5,i.COMPUTE_CRAZY_SINE_SUM=6,i.COMPUTE_CRAZY_SINE_SUM_SUCCESS=7,i.COMPUTE_CRAZY_SINE_SUM_FAIL=8,i.MESSAGE_TOTAL=9,i.MESSAGE_INDEX_SPACING=3,i.MESSAGE_INDEX_OFFSET_SUCCESS=1,i.MESSAGE_INDEX_OFFSET_FAIL=2,i.prototype.destroy=function(){this.$$worker&&(this.$$worker.terminate(),this.$$worker=void 0)},i.prototype.getInitialization=function(){return this.$$promise[i.INITIALIZATION]},i.prototype.$$onMessage=function(e){var t,r,n=e.data,o=n.length>0?n[0]:null,a=n.length>1?n[1]:null;for(r=0;r
+
+
+
+ AudioNetwork - example
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
deleted file mode 100644
index fb32e66..0000000
--- a/gulpfile.js
+++ /dev/null
@@ -1,92 +0,0 @@
-'use strict';
-
-var gulp = require('gulp');
-var header = require('gulp-header');
-var rename = require('gulp-rename');
-var concat = require('gulp-concat');
-var uglify = require('gulp-uglify');
-var debug = require('gulp-debug');
-var fs = require('fs');
-
-var DEST = 'build/';
-
-gulp.task('default', function() {
- // var pattern = "./src/**/!(*.test).js";
- return gulp.src([
- './src/audio-network-boot.js',
- './src/**/!(audio-network-boot|audio-network-end|*.test).js',
- './src/audio-network-end.js'
- ])
- .pipe(debug())
- .pipe(concat('audio-network-v1.3.0.js'))
- .pipe(header('/*\n' + fs.readFileSync('./LICENCE', 'utf8') + '*/\n\n'))
- .pipe(gulp.dest(DEST))
- .pipe(uglify())
- .pipe(rename({ extname: '.min.js' }))
- .pipe(header('/*\n' + fs.readFileSync('./LICENCE', 'utf8') + '*/\n\n'))
- .pipe(gulp.dest(DEST));
-});
-
-var markdown = require('gulp-markdown');
-
-gulp.task('md-readme', function () {
- return gulp.src('README.md')
- .pipe(markdown())
- .pipe(gulp.dest(DEST));
-});
-
-gulp.task('md-changelog', function () {
- return gulp.src('CHANGELOG.md')
- .pipe(markdown())
- .pipe(gulp.dest(DEST));
-});
-
-gulp.task('md-article02', function () {
- return gulp.src('article_02.md')
- .pipe(markdown())
- .pipe(gulp.dest(DEST));
-});
-
-
-
-var webserver = require('gulp-webserver');
-
-gulp.task('serve', function() {
- gulp.src('.')
- .pipe(webserver({
- fallback: 'index.html',
- // livereload: true,
- directoryListing: true,
- open: 'http://localhost:8000/index.html'
- }));
-});
-
-var Glob = require("glob").Glob;
-
-gulp.task('script-list', function() {
- var pattern = "./src/**/!(audio-network-boot|audio-network-end|*.test).js";
- var mg = new Glob(pattern, {mark: true}, function (er, matches) {
- console.log('\'audio-network-boot.js\',');
- for (var i = 0; i < matches.length; i++) {
- matches[i] = matches[i]
- .replace('./src/', '\'')
- .replace('.js', '.js\',');
-
- console.log(matches[i]);
- }
- console.log('\'audio-network-end.js\'');
- });
-});
-
-gulp.task('script-tag-unit-test', function() {
- var pattern = "./src/**/*.test.js";
- var mg = new Glob(pattern, {mark: true}, function (er, matches) {
- for (var i = 0; i < matches.length; i++) {
- matches[i] = matches[i]
- .replace('./src/', '');
-
- console.log(matches[i]);
- }
- });
-});
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..e433336
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,8141 @@
+{
+ "name": "audio-network",
+ "version": "1.3.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.0.0-beta.39",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.39.tgz",
+ "integrity": "sha512-PConL+YIK9BgNUWWC2q4fbltj1g475TofpNVNivSypcAAKElfpSS1cv7MrpLYRG8TzZvwcVu9M30hLA/WAp1HQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.3.0",
+ "esutils": "2.0.2",
+ "js-tokens": "3.0.2"
+ }
+ },
+ "@types/commander": {
+ "version": "2.12.2",
+ "resolved": "https://registry.npmjs.org/@types/commander/-/commander-2.12.2.tgz",
+ "integrity": "sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q==",
+ "dev": true,
+ "requires": {
+ "commander": "2.14.1"
+ }
+ },
+ "@types/jest": {
+ "version": "22.1.1",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-22.1.1.tgz",
+ "integrity": "sha512-JSh6yk+GkeSkucPa3DllFtpDXe0BMxDTFqCxoryzGKvZiusdb97Sb7X5gnMiKdFGkHbTMjSH+HbE9wrBIzrUTA==",
+ "dev": true
+ },
+ "@types/semver": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz",
+ "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==",
+ "dev": true
+ },
+ "abab": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
+ "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=",
+ "dev": true
+ },
+ "accepts": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
+ "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
+ "dev": true,
+ "requires": {
+ "mime-types": "2.1.17",
+ "negotiator": "0.6.1"
+ }
+ },
+ "acorn": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.4.1.tgz",
+ "integrity": "sha512-XLmq3H/BVvW6/GbxKryGxWORz1ebilSsUDlyC27bXhWGWAZWkGwS6FLHjOlwFXNFoWFQEO/Df4u0YYd0K3BQgQ==",
+ "dev": true
+ },
+ "acorn-dynamic-import": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz",
+ "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=",
+ "dev": true,
+ "requires": {
+ "acorn": "4.0.13"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+ "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
+ "dev": true
+ }
+ }
+ },
+ "acorn-globals": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz",
+ "integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==",
+ "dev": true,
+ "requires": {
+ "acorn": "5.4.1"
+ }
+ },
+ "ajv": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+ "dev": true,
+ "requires": {
+ "co": "4.6.0",
+ "fast-deep-equal": "1.0.0",
+ "fast-json-stable-stringify": "2.0.0",
+ "json-schema-traverse": "0.3.1"
+ }
+ },
+ "ajv-keywords": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
+ "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
+ "dev": true
+ },
+ "align-text": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2",
+ "longest": "1.0.1",
+ "repeat-string": "1.6.1"
+ }
+ },
+ "amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz",
+ "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==",
+ "dev": true
+ },
+ "ansi-html": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
+ "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.1"
+ }
+ },
+ "anymatch": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+ "dev": true,
+ "requires": {
+ "micromatch": "2.3.11",
+ "normalize-path": "2.1.1"
+ }
+ },
+ "append-transform": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz",
+ "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=",
+ "dev": true,
+ "requires": {
+ "default-require-extensions": "1.0.0"
+ }
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+ "dev": true
+ },
+ "argparse": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
+ "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "1.0.3"
+ }
+ },
+ "arr-diff": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "1.1.0"
+ }
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
+ "array-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+ "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
+ "dev": true
+ },
+ "array-filter": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
+ "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
+ "dev": true
+ },
+ "array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+ "dev": true
+ },
+ "array-flatten": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz",
+ "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=",
+ "dev": true
+ },
+ "array-includes": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
+ "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
+ "dev": true,
+ "requires": {
+ "define-properties": "1.1.2",
+ "es-abstract": "1.10.0"
+ }
+ },
+ "array-map": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
+ "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=",
+ "dev": true
+ },
+ "array-reduce": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz",
+ "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=",
+ "dev": true
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "1.0.3"
+ }
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+ "dev": true
+ },
+ "arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+ "dev": true
+ },
+ "asn1.js": {
+ "version": "4.9.2",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz",
+ "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==",
+ "dev": true,
+ "requires": {
+ "bn.js": "4.11.8",
+ "inherits": "2.0.3",
+ "minimalistic-assert": "1.0.0"
+ }
+ },
+ "assert": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+ "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+ "dev": true,
+ "requires": {
+ "util": "0.10.3"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "dev": true
+ },
+ "astral-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+ "dev": true
+ },
+ "async": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
+ "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
+ "dev": true,
+ "requires": {
+ "lodash": "4.17.5"
+ }
+ },
+ "async-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+ "dev": true
+ },
+ "async-limiter": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
+ "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "atob": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz",
+ "integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+ "dev": true
+ },
+ "babel-code-frame": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "esutils": "2.0.2",
+ "js-tokens": "3.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "babel-core": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
+ "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "6.26.0",
+ "babel-generator": "6.26.1",
+ "babel-helpers": "6.24.1",
+ "babel-messages": "6.23.0",
+ "babel-register": "6.26.0",
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0",
+ "babylon": "6.18.0",
+ "convert-source-map": "1.5.1",
+ "debug": "2.6.9",
+ "json5": "0.5.1",
+ "lodash": "4.17.5",
+ "minimatch": "3.0.4",
+ "path-is-absolute": "1.0.1",
+ "private": "0.1.8",
+ "slash": "1.0.0",
+ "source-map": "0.5.7"
+ }
+ },
+ "babel-generator": {
+ "version": "6.26.1",
+ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+ "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
+ "dev": true,
+ "requires": {
+ "babel-messages": "6.23.0",
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0",
+ "detect-indent": "4.0.0",
+ "jsesc": "1.3.0",
+ "lodash": "4.17.5",
+ "source-map": "0.5.7",
+ "trim-right": "1.0.1"
+ }
+ },
+ "babel-helpers": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
+ "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0"
+ }
+ },
+ "babel-jest": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-22.2.0.tgz",
+ "integrity": "sha512-Uh26WMQOxa7Xa2zu1Wrds+q5NcYPVYIUmaSDKF2vfAkTkpsa7wt8BE13YnTXVhlhaO6dD/blJYnLKy7sqKf/0w==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-istanbul": "4.1.5",
+ "babel-preset-jest": "22.2.0"
+ }
+ },
+ "babel-messages": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-istanbul": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.5.tgz",
+ "integrity": "sha1-Z2DN2Xf0EdPhdbsGTyvDJ9mbK24=",
+ "dev": true,
+ "requires": {
+ "find-up": "2.1.0",
+ "istanbul-lib-instrument": "1.9.1",
+ "test-exclude": "4.1.1"
+ }
+ },
+ "babel-plugin-jest-hoist": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.2.0.tgz",
+ "integrity": "sha512-NwicD5n1YQaj6sM3PVULdPBDk1XdlWvh8xBeUJg3nqZwp79Vofb8Q7GOVeWoZZ/RMlMuJMMrEAgSQl/p392nLA==",
+ "dev": true
+ },
+ "babel-plugin-syntax-object-rest-spread": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+ "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
+ "dev": true
+ },
+ "babel-plugin-transform-es2015-modules-commonjs": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz",
+ "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-strict-mode": "6.24.1",
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-strict-mode": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
+ "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-preset-jest": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-22.2.0.tgz",
+ "integrity": "sha512-p61cPMGYlSgfNScn1yQuVnLguWE4bjhB/br4KQDMbYZG+v6ryE5Ch7TKukjA6mRuIQj1zhyou7Sbpqrh4/N6Pg==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-jest-hoist": "22.2.0",
+ "babel-plugin-syntax-object-rest-spread": "6.13.0"
+ }
+ },
+ "babel-register": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
+ "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
+ "dev": true,
+ "requires": {
+ "babel-core": "6.26.0",
+ "babel-runtime": "6.26.0",
+ "core-js": "2.5.3",
+ "home-or-tmp": "2.0.0",
+ "lodash": "4.17.5",
+ "mkdirp": "0.5.1",
+ "source-map-support": "0.4.18"
+ },
+ "dependencies": {
+ "source-map-support": {
+ "version": "0.4.18",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+ "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
+ "dev": true,
+ "requires": {
+ "source-map": "0.5.7"
+ }
+ }
+ }
+ },
+ "babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+ "dev": true,
+ "requires": {
+ "core-js": "2.5.3",
+ "regenerator-runtime": "0.11.1"
+ }
+ },
+ "babel-template": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0",
+ "babylon": "6.18.0",
+ "lodash": "4.17.5"
+ }
+ },
+ "babel-traverse": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "6.26.0",
+ "babel-messages": "6.23.0",
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0",
+ "babylon": "6.18.0",
+ "debug": "2.6.9",
+ "globals": "9.18.0",
+ "invariant": "2.2.2",
+ "lodash": "4.17.5"
+ }
+ },
+ "babel-types": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "esutils": "2.0.2",
+ "lodash": "4.17.5",
+ "to-fast-properties": "1.0.3"
+ }
+ },
+ "babylon": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "requires": {
+ "cache-base": "1.0.1",
+ "class-utils": "0.3.6",
+ "component-emitter": "1.2.1",
+ "define-property": "1.0.0",
+ "isobject": "3.0.1",
+ "mixin-deep": "1.3.1",
+ "pascalcase": "0.1.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "base64-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
+ "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==",
+ "dev": true
+ },
+ "batch": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+ "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "big.js": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
+ "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
+ "dev": true
+ },
+ "binary-extensions": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
+ "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
+ "dev": true
+ },
+ "bluebird": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+ "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
+ "dev": true
+ },
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+ "dev": true
+ },
+ "body-parser": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+ "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
+ "dev": true,
+ "requires": {
+ "bytes": "3.0.0",
+ "content-type": "1.0.4",
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
+ "on-finished": "2.3.0",
+ "qs": "6.5.1",
+ "raw-body": "2.3.2",
+ "type-is": "1.6.15"
+ }
+ },
+ "bonjour": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
+ "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+ "dev": true,
+ "requires": {
+ "array-flatten": "2.1.1",
+ "deep-equal": "1.0.1",
+ "dns-equal": "1.0.0",
+ "dns-txt": "2.0.2",
+ "multicast-dns": "6.2.3",
+ "multicast-dns-service-types": "1.1.0"
+ }
+ },
+ "boom": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
+ "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
+ "dev": true,
+ "requires": {
+ "hoek": "4.2.0"
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "1.8.5",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+ "dev": true,
+ "requires": {
+ "expand-range": "1.8.2",
+ "preserve": "0.2.0",
+ "repeat-element": "1.1.2"
+ }
+ },
+ "brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+ "dev": true
+ },
+ "browser-process-hrtime": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz",
+ "integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=",
+ "dev": true
+ },
+ "browser-resolve": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz",
+ "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=",
+ "dev": true,
+ "requires": {
+ "resolve": "1.1.7"
+ }
+ },
+ "browserify-aes": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz",
+ "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==",
+ "dev": true,
+ "requires": {
+ "buffer-xor": "1.0.3",
+ "cipher-base": "1.0.4",
+ "create-hash": "1.1.3",
+ "evp_bytestokey": "1.0.3",
+ "inherits": "2.0.3",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "browserify-cipher": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
+ "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
+ "dev": true,
+ "requires": {
+ "browserify-aes": "1.1.1",
+ "browserify-des": "1.0.0",
+ "evp_bytestokey": "1.0.3"
+ }
+ },
+ "browserify-des": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
+ "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
+ "dev": true,
+ "requires": {
+ "cipher-base": "1.0.4",
+ "des.js": "1.0.0",
+ "inherits": "2.0.3"
+ }
+ },
+ "browserify-rsa": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+ "dev": true,
+ "requires": {
+ "bn.js": "4.11.8",
+ "randombytes": "2.0.6"
+ }
+ },
+ "browserify-sign": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
+ "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+ "dev": true,
+ "requires": {
+ "bn.js": "4.11.8",
+ "browserify-rsa": "4.0.1",
+ "create-hash": "1.1.3",
+ "create-hmac": "1.1.6",
+ "elliptic": "6.4.0",
+ "inherits": "2.0.3",
+ "parse-asn1": "5.1.0"
+ }
+ },
+ "browserify-zlib": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+ "dev": true,
+ "requires": {
+ "pako": "1.0.6"
+ }
+ },
+ "bser": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz",
+ "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=",
+ "dev": true,
+ "requires": {
+ "node-int64": "0.4.0"
+ }
+ },
+ "buffer": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+ "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
+ "dev": true,
+ "requires": {
+ "base64-js": "1.2.1",
+ "ieee754": "1.1.8",
+ "isarray": "1.0.0"
+ }
+ },
+ "buffer-indexof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
+ "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
+ "dev": true
+ },
+ "buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+ "dev": true
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+ "dev": true
+ },
+ "builtin-status-codes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+ "dev": true
+ },
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+ "dev": true
+ },
+ "cacache": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.2.tgz",
+ "integrity": "sha512-dljb7dk1jqO5ogE+dRpoR9tpHYv5xz9vPSNunh1+0wRuNdYxmzp9WmsyokgW/DUF1FDRVA/TMsmxt027R8djbQ==",
+ "dev": true,
+ "requires": {
+ "bluebird": "3.5.1",
+ "chownr": "1.0.1",
+ "glob": "7.1.2",
+ "graceful-fs": "4.1.11",
+ "lru-cache": "4.1.1",
+ "mississippi": "1.3.1",
+ "mkdirp": "0.5.1",
+ "move-concurrently": "1.0.1",
+ "promise-inflight": "1.0.1",
+ "rimraf": "2.6.2",
+ "ssri": "5.2.1",
+ "unique-filename": "1.1.0",
+ "y18n": "3.2.1"
+ }
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "requires": {
+ "collection-visit": "1.0.0",
+ "component-emitter": "1.2.1",
+ "get-value": "2.0.6",
+ "has-value": "1.0.0",
+ "isobject": "3.0.1",
+ "set-value": "2.0.0",
+ "to-object-path": "0.3.0",
+ "union-value": "1.0.0",
+ "unset-value": "1.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "callsites": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+ "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+ "dev": true
+ },
+ "camelcase-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+ "dev": true,
+ "requires": {
+ "camelcase": "2.1.1",
+ "map-obj": "1.0.1"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+ "dev": true
+ }
+ }
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+ "dev": true
+ },
+ "center-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+ "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+ "dev": true,
+ "requires": {
+ "align-text": "0.1.4",
+ "lazy-cache": "1.0.4"
+ }
+ },
+ "chalk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.5.0"
+ }
+ },
+ "chokidar": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+ "dev": true,
+ "requires": {
+ "anymatch": "1.3.2",
+ "async-each": "1.0.1",
+ "glob-parent": "2.0.0",
+ "inherits": "2.0.3",
+ "is-binary-path": "1.0.1",
+ "is-glob": "2.0.1",
+ "path-is-absolute": "1.0.1",
+ "readdirp": "2.1.0"
+ }
+ },
+ "chownr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
+ "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
+ "dev": true
+ },
+ "ci-info": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz",
+ "integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==",
+ "dev": true
+ },
+ "cipher-base": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "3.1.0",
+ "define-property": "0.2.5",
+ "isobject": "3.0.1",
+ "static-extend": "0.1.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "cliui": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+ "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+ "dev": true,
+ "requires": {
+ "center-align": "0.1.3",
+ "right-align": "0.1.3",
+ "wordwrap": "0.0.2"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+ "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
+ "dev": true
+ }
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+ "dev": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "dev": true
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "requires": {
+ "map-visit": "1.0.0",
+ "object-visit": "1.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
+ "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "1.0.0"
+ }
+ },
+ "commander": {
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
+ "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==",
+ "dev": true
+ },
+ "commandpost": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/commandpost/-/commandpost-1.3.0.tgz",
+ "integrity": "sha512-T62tyrmYTkaRDbV2z1k2yXTyxk0cFptXYwo1cUbnfHtp7ThLgQ9/90jG1Ym5WLZgFhvOTaHA5VSARWJ9URpLDw==",
+ "dev": true
+ },
+ "commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+ "dev": true
+ },
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "dev": true
+ },
+ "compressible": {
+ "version": "2.0.12",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.12.tgz",
+ "integrity": "sha1-xZpcmdt2dn6YdlAOJx72OzSTvWY=",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.30.0"
+ }
+ },
+ "compression": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.1.tgz",
+ "integrity": "sha1-7/JgPvwuIs+G810uuTWJ+YdTc9s=",
+ "dev": true,
+ "requires": {
+ "accepts": "1.3.4",
+ "bytes": "3.0.0",
+ "compressible": "2.0.12",
+ "debug": "2.6.9",
+ "on-headers": "1.0.1",
+ "safe-buffer": "5.1.1",
+ "vary": "1.1.2"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "concat-stream": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
+ "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3",
+ "typedarray": "0.0.6"
+ }
+ },
+ "connect-history-api-fallback": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz",
+ "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=",
+ "dev": true
+ },
+ "console-browserify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+ "dev": true,
+ "requires": {
+ "date-now": "0.1.4"
+ }
+ },
+ "constants-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+ "dev": true
+ },
+ "content-disposition": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+ "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
+ "dev": true
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "dev": true
+ },
+ "content-type-parser": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz",
+ "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
+ "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
+ "dev": true
+ },
+ "cookie": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+ "dev": true
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+ "dev": true
+ },
+ "copy-concurrently": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
+ "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
+ "dev": true,
+ "requires": {
+ "aproba": "1.2.0",
+ "fs-write-stream-atomic": "1.0.10",
+ "iferr": "0.1.5",
+ "mkdirp": "0.5.1",
+ "rimraf": "2.6.2",
+ "run-queue": "1.0.3"
+ }
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "dev": true
+ },
+ "core-js": {
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz",
+ "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "coveralls": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.0.tgz",
+ "integrity": "sha512-ZppXR9y5PraUOrf/DzHJY6gzNUhXYE3b9D43xEXs4QYZ7/Oe0Gy0CS+IPKWFfvQFXB3RG9QduaQUFehzSpGAFw==",
+ "dev": true,
+ "requires": {
+ "js-yaml": "3.10.0",
+ "lcov-parse": "0.0.10",
+ "log-driver": "1.2.5",
+ "minimist": "1.2.0",
+ "request": "2.83.0"
+ }
+ },
+ "cpx": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz",
+ "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "chokidar": "1.7.0",
+ "duplexer": "0.1.1",
+ "glob": "7.1.2",
+ "glob2base": "0.0.12",
+ "minimatch": "3.0.4",
+ "mkdirp": "0.5.1",
+ "resolve": "1.1.7",
+ "safe-buffer": "5.1.1",
+ "shell-quote": "1.6.1",
+ "subarg": "1.0.0"
+ }
+ },
+ "create-ecdh": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
+ "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
+ "dev": true,
+ "requires": {
+ "bn.js": "4.11.8",
+ "elliptic": "6.4.0"
+ }
+ },
+ "create-hash": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
+ "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
+ "dev": true,
+ "requires": {
+ "cipher-base": "1.0.4",
+ "inherits": "2.0.3",
+ "ripemd160": "2.0.1",
+ "sha.js": "2.4.10"
+ }
+ },
+ "create-hmac": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
+ "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
+ "dev": true,
+ "requires": {
+ "cipher-base": "1.0.4",
+ "create-hash": "1.1.3",
+ "inherits": "2.0.3",
+ "ripemd160": "2.0.1",
+ "safe-buffer": "5.1.1",
+ "sha.js": "2.4.10"
+ }
+ },
+ "cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "4.1.1",
+ "shebang-command": "1.2.0",
+ "which": "1.3.0"
+ }
+ },
+ "cryptiles": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
+ "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
+ "dev": true,
+ "requires": {
+ "boom": "5.2.0"
+ },
+ "dependencies": {
+ "boom": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
+ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
+ "dev": true,
+ "requires": {
+ "hoek": "4.2.0"
+ }
+ }
+ }
+ },
+ "crypto-browserify": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+ "dev": true,
+ "requires": {
+ "browserify-cipher": "1.0.0",
+ "browserify-sign": "4.0.4",
+ "create-ecdh": "4.0.0",
+ "create-hash": "1.1.3",
+ "create-hmac": "1.1.6",
+ "diffie-hellman": "5.0.2",
+ "inherits": "2.0.3",
+ "pbkdf2": "3.0.14",
+ "public-encrypt": "4.0.0",
+ "randombytes": "2.0.6",
+ "randomfill": "1.0.3"
+ }
+ },
+ "cssom": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz",
+ "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=",
+ "dev": true
+ },
+ "cssstyle": {
+ "version": "0.2.37",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz",
+ "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=",
+ "dev": true,
+ "requires": {
+ "cssom": "0.3.2"
+ }
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+ "dev": true,
+ "requires": {
+ "array-find-index": "1.0.2"
+ }
+ },
+ "cyclist": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
+ "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=",
+ "dev": true
+ },
+ "d": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
+ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "0.10.38"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ }
+ },
+ "date-now": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "dev": true
+ },
+ "deep-equal": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
+ "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
+ "dev": true
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "default-require-extensions": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz",
+ "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=",
+ "dev": true,
+ "requires": {
+ "strip-bom": "2.0.0"
+ }
+ },
+ "define-properties": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
+ "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
+ "dev": true,
+ "requires": {
+ "foreach": "2.0.5",
+ "object-keys": "1.0.11"
+ }
+ },
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "del": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz",
+ "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=",
+ "dev": true,
+ "requires": {
+ "globby": "6.1.0",
+ "is-path-cwd": "1.0.0",
+ "is-path-in-cwd": "1.0.0",
+ "p-map": "1.2.0",
+ "pify": "3.0.0",
+ "rimraf": "2.6.2"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "dev": true
+ },
+ "des.js": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
+ "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "minimalistic-assert": "1.0.0"
+ }
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+ "dev": true
+ },
+ "detect-indent": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+ "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+ "dev": true,
+ "requires": {
+ "repeating": "2.0.1"
+ }
+ },
+ "detect-newline": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
+ "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=",
+ "dev": true
+ },
+ "detect-node": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz",
+ "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=",
+ "dev": true
+ },
+ "diff": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz",
+ "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==",
+ "dev": true
+ },
+ "diffie-hellman": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
+ "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
+ "dev": true,
+ "requires": {
+ "bn.js": "4.11.8",
+ "miller-rabin": "4.0.1",
+ "randombytes": "2.0.6"
+ }
+ },
+ "dns-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
+ "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
+ "dev": true
+ },
+ "dns-packet": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
+ "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
+ "dev": true,
+ "requires": {
+ "ip": "1.1.5",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "dns-txt": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
+ "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
+ "dev": true,
+ "requires": {
+ "buffer-indexof": "1.1.1"
+ }
+ },
+ "domain-browser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+ "dev": true
+ },
+ "domexception": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
+ "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+ "dev": true,
+ "requires": {
+ "webidl-conversions": "4.0.2"
+ }
+ },
+ "duplexer": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+ "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+ "dev": true
+ },
+ "duplexify": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.3.tgz",
+ "integrity": "sha512-g8ID9OroF9hKt2POf8YLayy+9594PzmM3scI00/uBXocX3TWNgoB67hjzkFe9ITAbQOne/lLdBxHXvYUM4ZgGA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "1.4.1",
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3",
+ "stream-shift": "1.0.0"
+ }
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsbn": "0.1.1"
+ }
+ },
+ "editorconfig": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.0.tgz",
+ "integrity": "sha512-j7JBoj/bpNzvoTQylfRZSc85MlLNKWQiq5y6gwKhmqD2h1eZ+tH4AXbkhEJD468gjDna/XMx2YtSkCxBRX9OGg==",
+ "dev": true,
+ "requires": {
+ "@types/commander": "2.12.2",
+ "@types/semver": "5.5.0",
+ "commander": "2.14.1",
+ "lru-cache": "4.1.1",
+ "semver": "5.5.0",
+ "sigmund": "1.0.1"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+ "dev": true
+ },
+ "elliptic": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
+ "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
+ "dev": true,
+ "requires": {
+ "bn.js": "4.11.8",
+ "brorand": "1.1.0",
+ "hash.js": "1.1.3",
+ "hmac-drbg": "1.0.1",
+ "inherits": "2.0.3",
+ "minimalistic-assert": "1.0.0",
+ "minimalistic-crypto-utils": "1.0.1"
+ }
+ },
+ "emojis-list": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+ "dev": true
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "dev": true
+ },
+ "end-of-stream": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+ "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+ "dev": true,
+ "requires": {
+ "once": "1.4.0"
+ }
+ },
+ "enhanced-resolve": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz",
+ "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "memory-fs": "0.4.1",
+ "object-assign": "4.1.1",
+ "tapable": "0.2.8"
+ }
+ },
+ "errno": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz",
+ "integrity": "sha512-IsORQDpaaSwcDP4ZZnHxgE85werpo34VYn1Ud3mq+eUsF593faR8oCZNXrROVkpFu2TsbrNhHin0aUrTsQ9vNw==",
+ "dev": true,
+ "requires": {
+ "prr": "1.0.1"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+ "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "0.2.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz",
+ "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "1.1.1",
+ "function-bind": "1.1.1",
+ "has": "1.0.1",
+ "is-callable": "1.1.3",
+ "is-regex": "1.0.4"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
+ "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
+ "dev": true,
+ "requires": {
+ "is-callable": "1.1.3",
+ "is-date-object": "1.0.1",
+ "is-symbol": "1.0.1"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.38",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.38.tgz",
+ "integrity": "sha512-jCMyePo7AXbUESwbl8Qi01VSH2piY9s/a3rSU/5w/MlTIx8HPL1xn2InGN8ejt/xulcJgnTO7vqNtOAxzYd2Kg==",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "2.0.3",
+ "es6-symbol": "3.1.1"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.38",
+ "es6-symbol": "3.1.1"
+ }
+ },
+ "es6-map": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
+ "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.38",
+ "es6-iterator": "2.0.3",
+ "es6-set": "0.1.5",
+ "es6-symbol": "3.1.1",
+ "event-emitter": "0.3.5"
+ }
+ },
+ "es6-set": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
+ "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.38",
+ "es6-iterator": "2.0.3",
+ "es6-symbol": "3.1.1",
+ "event-emitter": "0.3.5"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+ "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.38"
+ }
+ },
+ "es6-weak-map": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
+ "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.38",
+ "es6-iterator": "2.0.3",
+ "es6-symbol": "3.1.1"
+ }
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "escodegen": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz",
+ "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==",
+ "dev": true,
+ "requires": {
+ "esprima": "3.1.3",
+ "estraverse": "4.2.0",
+ "esutils": "2.0.2",
+ "optionator": "0.8.2",
+ "source-map": "0.5.7"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
+ "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
+ "dev": true
+ }
+ }
+ },
+ "escope": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
+ "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
+ "dev": true,
+ "requires": {
+ "es6-map": "0.1.5",
+ "es6-weak-map": "2.0.2",
+ "esrecurse": "4.2.0",
+ "estraverse": "4.2.0"
+ }
+ },
+ "esprima": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+ "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+ "dev": true
+ },
+ "esrecurse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
+ "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
+ "dev": true,
+ "requires": {
+ "estraverse": "4.2.0",
+ "object-assign": "4.1.1"
+ }
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+ "dev": true
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+ "dev": true
+ },
+ "event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.0",
+ "es5-ext": "0.10.38"
+ }
+ },
+ "eventemitter3": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
+ "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=",
+ "dev": true
+ },
+ "events": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+ "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
+ "dev": true
+ },
+ "eventsource": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz",
+ "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=",
+ "dev": true,
+ "requires": {
+ "original": "1.0.0"
+ }
+ },
+ "evp_bytestokey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+ "dev": true,
+ "requires": {
+ "md5.js": "1.3.4",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "exec-sh": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.1.tgz",
+ "integrity": "sha512-aLt95pexaugVtQerpmE51+4QfWrNc304uez7jvj6fWnN8GeEHpttB8F36n8N7uVhUMbH/1enbxQ9HImZ4w/9qg==",
+ "dev": true,
+ "requires": {
+ "merge": "1.2.0"
+ }
+ },
+ "execa": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "5.1.0",
+ "get-stream": "3.0.0",
+ "is-stream": "1.1.0",
+ "npm-run-path": "2.0.2",
+ "p-finally": "1.0.0",
+ "signal-exit": "3.0.2",
+ "strip-eof": "1.0.0"
+ }
+ },
+ "exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+ "dev": true
+ },
+ "expand-brackets": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+ "dev": true,
+ "requires": {
+ "is-posix-bracket": "0.1.1"
+ }
+ },
+ "expand-range": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+ "dev": true,
+ "requires": {
+ "fill-range": "2.2.3"
+ }
+ },
+ "expect": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-22.2.0.tgz",
+ "integrity": "sha512-eqFxBnAeedkNLMGjNoYW4ZPbPQf2JJtVg6Yf6Fm3yVwHbMSNAMQJggxqI/PUrR+Bzb3QHF4O9tUdPyTTKicDUw==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "jest-diff": "22.1.0",
+ "jest-get-type": "22.1.0",
+ "jest-matcher-utils": "22.2.0",
+ "jest-message-util": "22.2.0",
+ "jest-regex-util": "22.1.0"
+ }
+ },
+ "express": {
+ "version": "4.16.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz",
+ "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=",
+ "dev": true,
+ "requires": {
+ "accepts": "1.3.4",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.18.2",
+ "content-disposition": "0.5.2",
+ "content-type": "1.0.4",
+ "cookie": "0.3.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "etag": "1.8.1",
+ "finalhandler": "1.1.0",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "1.1.2",
+ "on-finished": "2.3.0",
+ "parseurl": "1.3.2",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "2.0.2",
+ "qs": "6.5.1",
+ "range-parser": "1.2.0",
+ "safe-buffer": "5.1.1",
+ "send": "0.16.1",
+ "serve-static": "1.13.1",
+ "setprototypeof": "1.1.0",
+ "statuses": "1.3.1",
+ "type-is": "1.6.15",
+ "utils-merge": "1.0.1",
+ "vary": "1.1.2"
+ },
+ "dependencies": {
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+ "dev": true
+ }
+ }
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "dev": true
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "extglob": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "dev": true
+ },
+ "fast-deep-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
+ "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "faye-websocket": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
+ "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
+ "dev": true,
+ "requires": {
+ "websocket-driver": "0.7.0"
+ }
+ },
+ "fb-watchman": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz",
+ "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=",
+ "dev": true,
+ "requires": {
+ "bser": "2.0.0"
+ }
+ },
+ "filename-regex": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+ "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
+ "dev": true
+ },
+ "fileset": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz",
+ "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=",
+ "dev": true,
+ "requires": {
+ "glob": "7.1.2",
+ "minimatch": "3.0.4"
+ }
+ },
+ "fill-range": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
+ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
+ "dev": true,
+ "requires": {
+ "is-number": "2.1.0",
+ "isobject": "2.1.0",
+ "randomatic": "1.1.7",
+ "repeat-element": "1.1.2",
+ "repeat-string": "1.6.1"
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+ "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "on-finished": "2.3.0",
+ "parseurl": "1.3.2",
+ "statuses": "1.3.1",
+ "unpipe": "1.0.0"
+ }
+ },
+ "find-cache-dir": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
+ "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
+ "dev": true,
+ "requires": {
+ "commondir": "1.0.1",
+ "make-dir": "1.1.0",
+ "pkg-dir": "2.0.0"
+ }
+ },
+ "find-index": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz",
+ "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=",
+ "dev": true
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "2.0.0"
+ }
+ },
+ "flush-write-stream": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.2.tgz",
+ "integrity": "sha1-yBuQ2HRnZvGmCaRoCZRsRd2K5Bc=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3"
+ }
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "dev": true
+ },
+ "for-own": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+ "dev": true,
+ "requires": {
+ "for-in": "1.0.2"
+ }
+ },
+ "foreach": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
+ "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
+ "dev": true,
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.5",
+ "mime-types": "2.1.17"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+ "dev": true
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "dev": true,
+ "requires": {
+ "map-cache": "0.2.2"
+ }
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+ "dev": true
+ },
+ "from2": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+ "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3"
+ }
+ },
+ "fs-extra": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
+ "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "jsonfile": "4.0.0",
+ "universalify": "0.1.1"
+ }
+ },
+ "fs-write-stream-atomic": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+ "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "iferr": "0.1.5",
+ "imurmurhash": "0.1.4",
+ "readable-stream": "2.3.3"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
+ "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+ "dev": true
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "glob-base": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
+ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
+ "dev": true,
+ "requires": {
+ "glob-parent": "2.0.0",
+ "is-glob": "2.0.1"
+ }
+ },
+ "glob-parent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+ "dev": true,
+ "requires": {
+ "is-glob": "2.0.1"
+ }
+ },
+ "glob2base": {
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz",
+ "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=",
+ "dev": true,
+ "requires": {
+ "find-index": "0.1.1"
+ }
+ },
+ "globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true
+ },
+ "globby": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+ "dev": true,
+ "requires": {
+ "array-union": "1.0.2",
+ "glob": "7.1.2",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ },
+ "growly": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
+ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
+ "dev": true
+ },
+ "handle-thing": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz",
+ "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=",
+ "dev": true
+ },
+ "handlebars": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz",
+ "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=",
+ "dev": true,
+ "requires": {
+ "async": "1.5.2",
+ "optimist": "0.6.1",
+ "source-map": "0.4.4",
+ "uglify-js": "2.8.29"
+ },
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "dev": true,
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ }
+ }
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+ "dev": true,
+ "requires": {
+ "ajv": "5.5.2",
+ "har-schema": "2.0.0"
+ }
+ },
+ "has": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
+ "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
+ "dev": true,
+ "requires": {
+ "function-bind": "1.1.1"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "dev": true,
+ "requires": {
+ "get-value": "2.0.6",
+ "has-values": "1.0.0",
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "dev": true,
+ "requires": {
+ "is-number": "3.0.0",
+ "kind-of": "4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "hash-base": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
+ "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3"
+ }
+ },
+ "hash.js": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
+ "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "minimalistic-assert": "1.0.0"
+ }
+ },
+ "hawk": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+ "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+ "dev": true,
+ "requires": {
+ "boom": "4.3.1",
+ "cryptiles": "3.1.2",
+ "hoek": "4.2.0",
+ "sntp": "2.1.0"
+ }
+ },
+ "hmac-drbg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "dev": true,
+ "requires": {
+ "hash.js": "1.1.3",
+ "minimalistic-assert": "1.0.0",
+ "minimalistic-crypto-utils": "1.0.1"
+ }
+ },
+ "hoek": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
+ "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==",
+ "dev": true
+ },
+ "home-or-tmp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
+ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "1.0.2",
+ "os-tmpdir": "1.0.2"
+ }
+ },
+ "hosted-git-info": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
+ "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==",
+ "dev": true
+ },
+ "hpack.js": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+ "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "obuf": "1.1.1",
+ "readable-stream": "2.3.3",
+ "wbuf": "1.7.2"
+ }
+ },
+ "html-encoding-sniffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
+ "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
+ "dev": true,
+ "requires": {
+ "whatwg-encoding": "1.0.3"
+ }
+ },
+ "html-entities": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz",
+ "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
+ "dev": true
+ },
+ "http-deceiver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+ "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+ "dev": true,
+ "requires": {
+ "depd": "1.1.1",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.0.3",
+ "statuses": "1.3.1"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=",
+ "dev": true
+ },
+ "setprototypeof": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+ "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=",
+ "dev": true
+ }
+ }
+ },
+ "http-parser-js": {
+ "version": "0.4.10",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz",
+ "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=",
+ "dev": true
+ },
+ "http-proxy": {
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz",
+ "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=",
+ "dev": true,
+ "requires": {
+ "eventemitter3": "1.2.0",
+ "requires-port": "1.0.0"
+ }
+ },
+ "http-proxy-middleware": {
+ "version": "0.17.4",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz",
+ "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=",
+ "dev": true,
+ "requires": {
+ "http-proxy": "1.16.2",
+ "is-glob": "3.1.0",
+ "lodash": "4.17.5",
+ "micromatch": "2.3.11"
+ },
+ "dependencies": {
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "2.1.1"
+ }
+ }
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "jsprim": "1.4.1",
+ "sshpk": "1.13.1"
+ }
+ },
+ "https-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==",
+ "dev": true
+ },
+ "ieee754": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
+ "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=",
+ "dev": true
+ },
+ "iferr": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+ "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+ "dev": true
+ },
+ "import-local": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz",
+ "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "2.0.0",
+ "resolve-cwd": "2.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+ "dev": true,
+ "requires": {
+ "repeating": "2.0.1"
+ }
+ },
+ "indexof": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+ "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ },
+ "internal-ip": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz",
+ "integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=",
+ "dev": true,
+ "requires": {
+ "meow": "3.7.0"
+ }
+ },
+ "interpret": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
+ "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
+ "dev": true
+ },
+ "invariant": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
+ "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
+ "dev": true,
+ "requires": {
+ "loose-envify": "1.3.1"
+ }
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
+ "dev": true
+ },
+ "ip": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
+ "dev": true
+ },
+ "ipaddr.js": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
+ "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=",
+ "dev": true
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "1.11.0"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "is-builtin-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+ "dev": true,
+ "requires": {
+ "builtin-modules": "1.1.1"
+ }
+ },
+ "is-callable": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
+ "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz",
+ "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==",
+ "dev": true,
+ "requires": {
+ "ci-info": "1.1.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
+ "is-date-object": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
+ "dev": true
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "1.0.0",
+ "is-data-descriptor": "1.0.0",
+ "kind-of": "6.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
+ "is-dotfile": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+ "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
+ "dev": true
+ },
+ "is-equal-shallow": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
+ "dev": true,
+ "requires": {
+ "is-primitive": "2.0.0"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+ "dev": true
+ },
+ "is-finite": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "is-generator-fn": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz",
+ "integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "is-number": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-odd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-1.0.0.tgz",
+ "integrity": "sha1-O4qTLrAos3dcObsJ6RdnrM22kIg=",
+ "dev": true,
+ "requires": {
+ "is-number": "3.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ }
+ }
+ },
+ "is-path-cwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+ "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
+ "dev": true
+ },
+ "is-path-in-cwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
+ "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
+ "dev": true,
+ "requires": {
+ "is-path-inside": "1.0.1"
+ }
+ },
+ "is-path-inside": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
+ "dev": true,
+ "requires": {
+ "path-is-inside": "1.0.2"
+ }
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "is-posix-bracket": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+ "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
+ "dev": true
+ },
+ "is-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
+ "dev": true
+ },
+ "is-regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "dev": true,
+ "requires": {
+ "has": "1.0.1"
+ }
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "is-symbol": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
+ "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
+ "dev": true
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true
+ },
+ "istanbul-api": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.2.1.tgz",
+ "integrity": "sha512-oFCwXvd65amgaPCzqrR+a2XjanS1MvpXN6l/MlMUTv6uiA1NOgGX+I0uyq8Lg3GDxsxPsaP1049krz3hIJ5+KA==",
+ "dev": true,
+ "requires": {
+ "async": "2.6.0",
+ "fileset": "2.0.3",
+ "istanbul-lib-coverage": "1.1.1",
+ "istanbul-lib-hook": "1.1.0",
+ "istanbul-lib-instrument": "1.9.1",
+ "istanbul-lib-report": "1.1.2",
+ "istanbul-lib-source-maps": "1.2.2",
+ "istanbul-reports": "1.1.3",
+ "js-yaml": "3.10.0",
+ "mkdirp": "0.5.1",
+ "once": "1.4.0"
+ }
+ },
+ "istanbul-lib-coverage": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz",
+ "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==",
+ "dev": true
+ },
+ "istanbul-lib-hook": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz",
+ "integrity": "sha512-U3qEgwVDUerZ0bt8cfl3dSP3S6opBoOtk3ROO5f2EfBr/SRiD9FQqzwaZBqFORu8W7O0EXpai+k7kxHK13beRg==",
+ "dev": true,
+ "requires": {
+ "append-transform": "0.4.0"
+ }
+ },
+ "istanbul-lib-instrument": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz",
+ "integrity": "sha512-RQmXeQ7sphar7k7O1wTNzVczF9igKpaeGQAG9qR2L+BS4DCJNTI9nytRmIVYevwO0bbq+2CXvJmYDuz0gMrywA==",
+ "dev": true,
+ "requires": {
+ "babel-generator": "6.26.1",
+ "babel-template": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0",
+ "babylon": "6.18.0",
+ "istanbul-lib-coverage": "1.1.1",
+ "semver": "5.5.0"
+ }
+ },
+ "istanbul-lib-report": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz",
+ "integrity": "sha512-UTv4VGx+HZivJQwAo1wnRwe1KTvFpfi/NYwN7DcsrdzMXwpRT/Yb6r4SBPoHWj4VuQPakR32g4PUUeyKkdDkBA==",
+ "dev": true,
+ "requires": {
+ "istanbul-lib-coverage": "1.1.1",
+ "mkdirp": "0.5.1",
+ "path-parse": "1.0.5",
+ "supports-color": "3.2.3"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "dev": true,
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "istanbul-lib-source-maps": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz",
+ "integrity": "sha512-8BfdqSfEdtip7/wo1RnrvLpHVEd8zMZEDmOFEnpC6dg0vXflHt9nvoAyQUzig2uMSXfF2OBEYBV3CVjIL9JvaQ==",
+ "dev": true,
+ "requires": {
+ "debug": "3.1.0",
+ "istanbul-lib-coverage": "1.1.1",
+ "mkdirp": "0.5.1",
+ "rimraf": "2.6.2",
+ "source-map": "0.5.7"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "istanbul-reports": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.3.tgz",
+ "integrity": "sha512-ZEelkHh8hrZNI5xDaKwPMFwDsUf5wIEI2bXAFGp1e6deR2mnEKBPhLJEgr4ZBt8Gi6Mj38E/C8kcy9XLggVO2Q==",
+ "dev": true,
+ "requires": {
+ "handlebars": "4.0.11"
+ }
+ },
+ "jest": {
+ "version": "22.2.1",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-22.2.1.tgz",
+ "integrity": "sha512-RXFH79Wdi1MiIC9jchU9iGvflSGI/FEKrccp279UirxjK/DJ3X62/iPXPahknPya+QU49ccUt7LKg+Lsmu/bFw==",
+ "dev": true,
+ "requires": {
+ "import-local": "1.0.0",
+ "jest-cli": "22.2.1"
+ },
+ "dependencies": {
+ "jest-cli": {
+ "version": "22.2.1",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-22.2.1.tgz",
+ "integrity": "sha512-4ZvaStLTNFgiIIiNrTRmPrfpZVKWYlHOZuyfkiTDdVWiciFtAbtJhCpYsK+1mMx5NOdPCr72vxeodP6U0WlzfA==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "3.0.0",
+ "chalk": "2.3.0",
+ "exit": "0.1.2",
+ "glob": "7.1.2",
+ "graceful-fs": "4.1.11",
+ "import-local": "1.0.0",
+ "is-ci": "1.1.0",
+ "istanbul-api": "1.2.1",
+ "istanbul-lib-coverage": "1.1.1",
+ "istanbul-lib-instrument": "1.9.1",
+ "istanbul-lib-source-maps": "1.2.2",
+ "jest-changed-files": "22.2.0",
+ "jest-config": "22.2.1",
+ "jest-environment-jsdom": "22.2.0",
+ "jest-get-type": "22.1.0",
+ "jest-haste-map": "22.2.0",
+ "jest-message-util": "22.2.0",
+ "jest-regex-util": "22.1.0",
+ "jest-resolve-dependencies": "22.1.0",
+ "jest-runner": "22.2.1",
+ "jest-runtime": "22.2.1",
+ "jest-snapshot": "22.2.0",
+ "jest-util": "22.2.0",
+ "jest-worker": "22.2.0",
+ "micromatch": "2.3.11",
+ "node-notifier": "5.2.1",
+ "realpath-native": "1.0.0",
+ "rimraf": "2.6.2",
+ "slash": "1.0.0",
+ "string-length": "2.0.0",
+ "strip-ansi": "4.0.0",
+ "which": "1.3.0",
+ "yargs": "10.1.2"
+ }
+ }
+ }
+ },
+ "jest-changed-files": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-22.2.0.tgz",
+ "integrity": "sha512-SzqOvoPMrXB0NPvDrSPeKETpoUNCtNDOsFbCzAGWxqWVvNyrIMLpUjVExT3u3LfdVrENlrNGCfh5YoFd8+ZeXg==",
+ "dev": true,
+ "requires": {
+ "throat": "4.1.0"
+ }
+ },
+ "jest-config": {
+ "version": "22.2.1",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-22.2.1.tgz",
+ "integrity": "sha512-1vqJDHuF35ScbIsnGU3psDS7L89dhGRmgS1ybiMGFoyuxoNeJ+Hhu25o7vbCWdwI/Gplh0ePibGS4srCfwhtiw==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.3.0",
+ "glob": "7.1.2",
+ "jest-environment-jsdom": "22.2.0",
+ "jest-environment-node": "22.2.0",
+ "jest-get-type": "22.1.0",
+ "jest-jasmine2": "22.2.1",
+ "jest-regex-util": "22.1.0",
+ "jest-resolve": "22.2.0",
+ "jest-util": "22.2.0",
+ "jest-validate": "22.2.0",
+ "pretty-format": "22.1.0"
+ }
+ },
+ "jest-diff": {
+ "version": "22.1.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-22.1.0.tgz",
+ "integrity": "sha512-lowdbU/dzXh+2/MR5QcvU5KPNkO4JdAEYw0PkQCbIQIuy5+g3QZBuVhWh8179Fmpg4CQrz1WgoK/yQHDCHbqqw==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.3.0",
+ "diff": "3.4.0",
+ "jest-get-type": "22.1.0",
+ "pretty-format": "22.1.0"
+ }
+ },
+ "jest-docblock": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-22.2.0.tgz",
+ "integrity": "sha512-Hh/JRuhIcKL+o4aOTE/kXsz3e6LCdaZoYmkSvuElp+WCt9hdhhRTErX8v6j8O4sNndhhMhYCOjNZgzHI4n51Hg==",
+ "dev": true,
+ "requires": {
+ "detect-newline": "2.1.0"
+ }
+ },
+ "jest-environment-jsdom": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-22.2.0.tgz",
+ "integrity": "sha512-OV9EGbS3uJxFJdvI98s031Ie0ejLasuNelKFRWY/G4nAvFQB4QnHjNWxoNv911mj5Qd1KrUdiUPHc1qzCXR+CQ==",
+ "dev": true,
+ "requires": {
+ "jest-mock": "22.2.0",
+ "jest-util": "22.2.0",
+ "jsdom": "11.6.2"
+ }
+ },
+ "jest-environment-node": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-22.2.0.tgz",
+ "integrity": "sha512-bP4p75KOHsRoTHn8UCxkLRfd4EsbO9e1zwiRCMv+lzECtXs6jEUXgVzm1Wx0xzRbpXOrB90z7O0eu7VXeYMKng==",
+ "dev": true,
+ "requires": {
+ "jest-mock": "22.2.0",
+ "jest-util": "22.2.0"
+ }
+ },
+ "jest-get-type": {
+ "version": "22.1.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.1.0.tgz",
+ "integrity": "sha512-nD97IVOlNP6fjIN5i7j5XRH+hFsHL7VlauBbzRvueaaUe70uohrkz7pL/N8lx/IAwZRTJ//wOdVgh85OgM7g3w==",
+ "dev": true
+ },
+ "jest-haste-map": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-22.2.0.tgz",
+ "integrity": "sha512-JjAVy+faan8qmB6sERUx+6aI2eDmKpdCA2RQ7VprjvxqP+y+uHWIbRFzzoiOKB1o6bfJrv3YmdHnVJ3a6sPVaA==",
+ "dev": true,
+ "requires": {
+ "fb-watchman": "2.0.0",
+ "graceful-fs": "4.1.11",
+ "jest-docblock": "22.2.0",
+ "jest-worker": "22.2.0",
+ "micromatch": "2.3.11",
+ "sane": "2.4.1"
+ }
+ },
+ "jest-jasmine2": {
+ "version": "22.2.1",
+ "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-22.2.1.tgz",
+ "integrity": "sha512-+XpH9wxS4fz3uAUUDKjo9HKCnaaPXgrqMjdPoQX55e7WvLDy0CcpgBNmU69cy3ZqJkLPYqtjSQLOnqlAMjtzNA==",
+ "dev": true,
+ "requires": {
+ "callsites": "2.0.0",
+ "chalk": "2.3.0",
+ "co": "4.6.0",
+ "expect": "22.2.0",
+ "graceful-fs": "4.1.11",
+ "is-generator-fn": "1.0.0",
+ "jest-diff": "22.1.0",
+ "jest-matcher-utils": "22.2.0",
+ "jest-message-util": "22.2.0",
+ "jest-snapshot": "22.2.0",
+ "source-map-support": "0.5.3"
+ }
+ },
+ "jest-leak-detector": {
+ "version": "22.1.0",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-22.1.0.tgz",
+ "integrity": "sha512-8QsCWkncWAqdvrXN4yXQp9vgWF6CT3RkRey+d06SIHX913uXzAJhJdZyo6eE+uHVYMxUbxqW93npbUFhAR0YxA==",
+ "dev": true,
+ "requires": {
+ "pretty-format": "22.1.0"
+ }
+ },
+ "jest-matcher-utils": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.2.0.tgz",
+ "integrity": "sha512-jO0cnQ93mR4on+nbmEeK4bChCvLeMFN1bP2qjRjwFv5KzQt34y5SmUq9FgzKjZQZG8zUmaQN+/pHJMUQ0xAcgQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.3.0",
+ "jest-get-type": "22.1.0",
+ "pretty-format": "22.1.0"
+ }
+ },
+ "jest-message-util": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-22.2.0.tgz",
+ "integrity": "sha512-LHPYu5kyA07FZK2CpvJ0xBE+gqy+dW30sFU3oep78lmscyc27mVOWDVwzmROhUeY8LlYpW3mcpRB/w5ibD6ZkA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "7.0.0-beta.39",
+ "chalk": "2.3.0",
+ "micromatch": "2.3.11",
+ "slash": "1.0.0",
+ "stack-utils": "1.0.1"
+ }
+ },
+ "jest-mock": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-22.2.0.tgz",
+ "integrity": "sha512-eOfoUYLOB/JlxChOFkh/bzpWGqUXb9I+oOpkprHHs9L7nUNfL8Rk28h1ycWrqzWCEQ/jZBg/xIv7VdQkfAkOhw==",
+ "dev": true
+ },
+ "jest-regex-util": {
+ "version": "22.1.0",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.1.0.tgz",
+ "integrity": "sha512-on0LqVS6Xeh69sw3d1RukVnur+lVOl3zkmb0Q54FHj9wHoq6dbtWqb3TSlnVUyx36hqjJhjgs/QLqs07Bzu72Q==",
+ "dev": true
+ },
+ "jest-resolve": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-22.2.0.tgz",
+ "integrity": "sha512-Ta9c+uZdF9KaEiTdB0drql1cUlYStF0All1uhgYgbjw4AGP2jatkGsDHOSY4gs9zhkXe9u2wHw0N9if3KgCtIA==",
+ "dev": true,
+ "requires": {
+ "browser-resolve": "1.11.2",
+ "chalk": "2.3.0"
+ }
+ },
+ "jest-resolve-dependencies": {
+ "version": "22.1.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-22.1.0.tgz",
+ "integrity": "sha512-76Ll61bD/Sus8wK8d+lw891EtiBJGJkWG8OuVDTEX0z3z2+jPujvQqSB2eQ+kCHyCsRwJ2PSjhn3UHqae/oEtA==",
+ "dev": true,
+ "requires": {
+ "jest-regex-util": "22.1.0"
+ }
+ },
+ "jest-runner": {
+ "version": "22.2.1",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-22.2.1.tgz",
+ "integrity": "sha512-oTbyozpPKBBTdJxqPBOyUr3S0eVi/Rvx2CvwGCTCvmVkwrkoMCqG4w3WJmMbKARVv892Zy/l7rxYzEdzo24yNA==",
+ "dev": true,
+ "requires": {
+ "exit": "0.1.2",
+ "jest-config": "22.2.1",
+ "jest-docblock": "22.2.0",
+ "jest-haste-map": "22.2.0",
+ "jest-jasmine2": "22.2.1",
+ "jest-leak-detector": "22.1.0",
+ "jest-message-util": "22.2.0",
+ "jest-runtime": "22.2.1",
+ "jest-util": "22.2.0",
+ "jest-worker": "22.2.0",
+ "throat": "4.1.0"
+ }
+ },
+ "jest-runtime": {
+ "version": "22.2.1",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-22.2.1.tgz",
+ "integrity": "sha512-5GQ0U6gFQyr3O6BaisL6C00+/Bxs/3WCmv51c6BQ53cKKn0J/jdWsfnVk6uzETEJv9vaLdxIukvOQuv7O+23hA==",
+ "dev": true,
+ "requires": {
+ "babel-core": "6.26.0",
+ "babel-jest": "22.2.0",
+ "babel-plugin-istanbul": "4.1.5",
+ "chalk": "2.3.0",
+ "convert-source-map": "1.5.1",
+ "exit": "0.1.2",
+ "graceful-fs": "4.1.11",
+ "jest-config": "22.2.1",
+ "jest-haste-map": "22.2.0",
+ "jest-regex-util": "22.1.0",
+ "jest-resolve": "22.2.0",
+ "jest-util": "22.2.0",
+ "json-stable-stringify": "1.0.1",
+ "micromatch": "2.3.11",
+ "realpath-native": "1.0.0",
+ "slash": "1.0.0",
+ "strip-bom": "3.0.0",
+ "write-file-atomic": "2.3.0",
+ "yargs": "10.1.2"
+ },
+ "dependencies": {
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ }
+ }
+ },
+ "jest-snapshot": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-22.2.0.tgz",
+ "integrity": "sha512-nc4hOfENTO/09NWJDz6ojf5zdAGPutQ4ZKmidWuEirTyBwhndxBlckO8ZaiQk9NDfDUeoVNptd6zJW84GWPRKw==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.3.0",
+ "jest-diff": "22.1.0",
+ "jest-matcher-utils": "22.2.0",
+ "mkdirp": "0.5.1",
+ "natural-compare": "1.4.0",
+ "pretty-format": "22.1.0"
+ }
+ },
+ "jest-util": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-22.2.0.tgz",
+ "integrity": "sha512-k8oLZA6EMStGriZdg75CBcg8eGls7/WwVhzPi7W3ghu7j5TiAOu8Jy9Gm4Zn+M9a5QhCI0Rh5QxSs8PVhw3tnw==",
+ "dev": true,
+ "requires": {
+ "callsites": "2.0.0",
+ "chalk": "2.3.0",
+ "graceful-fs": "4.1.11",
+ "is-ci": "1.1.0",
+ "jest-message-util": "22.2.0",
+ "jest-validate": "22.2.0",
+ "mkdirp": "0.5.1"
+ }
+ },
+ "jest-validate": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-22.2.0.tgz",
+ "integrity": "sha512-wQVZaNUMdY/OJMd9cMe1UEU1lgvrPwvQW2z3WrGtBPfXqDSZ+Ze5dOsKnC6y6c19NQ3FEQKR0c04ZtyNPRpDBg==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.3.0",
+ "jest-get-type": "22.1.0",
+ "leven": "2.1.0",
+ "pretty-format": "22.1.0"
+ }
+ },
+ "jest-worker": {
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-22.2.0.tgz",
+ "integrity": "sha512-RKXSCsSSn5cPpJASHs1bOAnunpgcTo+DnLEcaCvVcf5yx/4ks5TEuTTCJMQasjJwwYpHW2MJX20i2tYHfrInEw==",
+ "dev": true,
+ "requires": {
+ "merge-stream": "1.0.1"
+ }
+ },
+ "js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
+ "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
+ "dev": true,
+ "requires": {
+ "argparse": "1.0.9",
+ "esprima": "4.0.0"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true,
+ "optional": true
+ },
+ "jsdom": {
+ "version": "11.6.2",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.6.2.tgz",
+ "integrity": "sha512-pAeZhpbSlUp5yQcS6cBQJwkbzmv4tWFaYxHbFVSxzXefqjvtRA851Z5N2P+TguVG9YeUDcgb8pdeVQRJh0XR3Q==",
+ "dev": true,
+ "requires": {
+ "abab": "1.0.4",
+ "acorn": "5.4.1",
+ "acorn-globals": "4.1.0",
+ "array-equal": "1.0.0",
+ "browser-process-hrtime": "0.1.2",
+ "content-type-parser": "1.0.2",
+ "cssom": "0.3.2",
+ "cssstyle": "0.2.37",
+ "domexception": "1.0.1",
+ "escodegen": "1.9.0",
+ "html-encoding-sniffer": "1.0.2",
+ "left-pad": "1.2.0",
+ "nwmatcher": "1.4.3",
+ "parse5": "4.0.0",
+ "pn": "1.1.0",
+ "request": "2.83.0",
+ "request-promise-native": "1.0.5",
+ "sax": "1.2.4",
+ "symbol-tree": "3.2.2",
+ "tough-cookie": "2.3.3",
+ "w3c-hr-time": "1.0.1",
+ "webidl-conversions": "4.0.2",
+ "whatwg-encoding": "1.0.3",
+ "whatwg-url": "6.4.0",
+ "ws": "4.0.0",
+ "xml-name-validator": "3.0.0"
+ }
+ },
+ "jsesc": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+ "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
+ "dev": true
+ },
+ "json-loader": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
+ "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==",
+ "dev": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+ "dev": true
+ },
+ "json-stable-stringify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+ "dev": true,
+ "requires": {
+ "jsonify": "0.0.0"
+ }
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true
+ },
+ "json3": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
+ "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=",
+ "dev": true
+ },
+ "json5": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11"
+ }
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "killable": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz",
+ "integrity": "sha1-2ouEvUfeU5WHj5XWTQLyRJ/gXms=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ },
+ "lazy-cache": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+ "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
+ "dev": true
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "dev": true,
+ "requires": {
+ "invert-kv": "1.0.0"
+ }
+ },
+ "lcov-parse": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz",
+ "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=",
+ "dev": true
+ },
+ "left-pad": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.2.0.tgz",
+ "integrity": "sha1-0wpzxrggHY99jnlWupYWCHpo4O4=",
+ "dev": true
+ },
+ "leven": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
+ "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "1.1.2",
+ "type-check": "0.3.2"
+ }
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "parse-json": "2.2.0",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1",
+ "strip-bom": "2.0.0"
+ }
+ },
+ "loader-runner": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz",
+ "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=",
+ "dev": true
+ },
+ "loader-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+ "dev": true,
+ "requires": {
+ "big.js": "3.2.0",
+ "emojis-list": "2.1.0",
+ "json5": "0.5.1"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "requires": {
+ "p-locate": "2.0.0",
+ "path-exists": "3.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.5",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
+ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
+ "dev": true
+ },
+ "lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
+ "dev": true
+ },
+ "log-driver": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz",
+ "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=",
+ "dev": true
+ },
+ "loglevel": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz",
+ "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=",
+ "dev": true
+ },
+ "longest": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
+ "dev": true
+ },
+ "loose-envify": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
+ "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
+ "dev": true,
+ "requires": {
+ "js-tokens": "3.0.2"
+ }
+ },
+ "loud-rejection": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+ "dev": true,
+ "requires": {
+ "currently-unhandled": "0.4.1",
+ "signal-exit": "3.0.2"
+ }
+ },
+ "lru-cache": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
+ "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "1.0.2",
+ "yallist": "2.1.2"
+ }
+ },
+ "make-dir": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz",
+ "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==",
+ "dev": true,
+ "requires": {
+ "pify": "3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "makeerror": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz",
+ "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=",
+ "dev": true,
+ "requires": {
+ "tmpl": "1.0.4"
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "dev": true
+ },
+ "map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+ "dev": true
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "dev": true,
+ "requires": {
+ "object-visit": "1.0.1"
+ }
+ },
+ "md5.js": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
+ "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
+ "dev": true,
+ "requires": {
+ "hash-base": "3.0.4",
+ "inherits": "2.0.3"
+ },
+ "dependencies": {
+ "hash-base": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "safe-buffer": "5.1.1"
+ }
+ }
+ }
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+ "dev": true
+ },
+ "mem": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
+ "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "1.2.0"
+ }
+ },
+ "memory-fs": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
+ "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
+ "dev": true,
+ "requires": {
+ "errno": "0.1.6",
+ "readable-stream": "2.3.3"
+ }
+ },
+ "meow": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+ "dev": true,
+ "requires": {
+ "camelcase-keys": "2.1.0",
+ "decamelize": "1.2.0",
+ "loud-rejection": "1.6.0",
+ "map-obj": "1.0.1",
+ "minimist": "1.2.0",
+ "normalize-package-data": "2.4.0",
+ "object-assign": "4.1.1",
+ "read-pkg-up": "1.0.1",
+ "redent": "1.0.0",
+ "trim-newlines": "1.0.0"
+ }
+ },
+ "merge": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz",
+ "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=",
+ "dev": true
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+ "dev": true
+ },
+ "merge-stream": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz",
+ "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "2.3.3"
+ }
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "2.3.11",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+ "dev": true,
+ "requires": {
+ "arr-diff": "2.0.0",
+ "array-unique": "0.2.1",
+ "braces": "1.8.5",
+ "expand-brackets": "0.1.5",
+ "extglob": "0.3.2",
+ "filename-regex": "2.0.1",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1",
+ "kind-of": "3.2.2",
+ "normalize-path": "2.1.1",
+ "object.omit": "2.0.1",
+ "parse-glob": "3.0.4",
+ "regex-cache": "0.4.4"
+ }
+ },
+ "miller-rabin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+ "dev": true,
+ "requires": {
+ "bn.js": "4.11.8",
+ "brorand": "1.1.0"
+ }
+ },
+ "mime": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
+ "dev": true
+ },
+ "mime-db": {
+ "version": "1.30.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+ "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.17",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+ "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.30.0"
+ }
+ },
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "dev": true
+ },
+ "minimalistic-assert": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
+ "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=",
+ "dev": true
+ },
+ "minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "1.1.8"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
+ "mississippi": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-1.3.1.tgz",
+ "integrity": "sha512-/6rB8YXFbAtsUVRphIRQqB0+9c7VaPHCjVtvto+JqwVxgz8Zz+I+f68/JgQ+Pb4VlZb2svA9OtdXnHHsZz7ltg==",
+ "dev": true,
+ "requires": {
+ "concat-stream": "1.6.0",
+ "duplexify": "3.5.3",
+ "end-of-stream": "1.4.1",
+ "flush-write-stream": "1.0.2",
+ "from2": "2.3.0",
+ "parallel-transform": "1.1.0",
+ "pump": "1.0.3",
+ "pumpify": "1.4.0",
+ "stream-each": "1.2.2",
+ "through2": "2.0.3"
+ }
+ },
+ "mixin-deep": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+ "dev": true,
+ "requires": {
+ "for-in": "1.0.2",
+ "is-extendable": "1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ }
+ }
+ },
+ "move-concurrently": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+ "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
+ "dev": true,
+ "requires": {
+ "aproba": "1.2.0",
+ "copy-concurrently": "1.0.5",
+ "fs-write-stream-atomic": "1.0.10",
+ "mkdirp": "0.5.1",
+ "rimraf": "2.6.2",
+ "run-queue": "1.0.3"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "multicast-dns": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
+ "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
+ "dev": true,
+ "requires": {
+ "dns-packet": "1.3.1",
+ "thunky": "1.0.2"
+ }
+ },
+ "multicast-dns-service-types": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
+ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
+ "dev": true
+ },
+ "nanomatch": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.7.tgz",
+ "integrity": "sha512-/5ldsnyurvEw7wNpxLFgjVvBLMta43niEYOy0CJ4ntcYSbx6bugRUTQeFb4BR/WanEL1o3aQgHuVLHQaB6tOqg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "extend-shallow": "2.0.1",
+ "fragment-cache": "0.2.1",
+ "is-odd": "1.0.0",
+ "kind-of": "5.1.0",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.0",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.1"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "negotiator": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
+ "dev": true
+ },
+ "node-forge": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz",
+ "integrity": "sha1-naYR6giYL0uUIGs760zJZl8gwwA=",
+ "dev": true
+ },
+ "node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=",
+ "dev": true
+ },
+ "node-libs-browser": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz",
+ "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==",
+ "dev": true,
+ "requires": {
+ "assert": "1.4.1",
+ "browserify-zlib": "0.2.0",
+ "buffer": "4.9.1",
+ "console-browserify": "1.1.0",
+ "constants-browserify": "1.0.0",
+ "crypto-browserify": "3.12.0",
+ "domain-browser": "1.2.0",
+ "events": "1.1.1",
+ "https-browserify": "1.0.0",
+ "os-browserify": "0.3.0",
+ "path-browserify": "0.0.0",
+ "process": "0.11.10",
+ "punycode": "1.4.1",
+ "querystring-es3": "0.2.1",
+ "readable-stream": "2.3.3",
+ "stream-browserify": "2.0.1",
+ "stream-http": "2.8.0",
+ "string_decoder": "1.0.3",
+ "timers-browserify": "2.0.6",
+ "tty-browserify": "0.0.0",
+ "url": "0.11.0",
+ "util": "0.10.3",
+ "vm-browserify": "0.0.4"
+ }
+ },
+ "node-notifier": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.2.1.tgz",
+ "integrity": "sha512-MIBs+AAd6dJ2SklbbE8RUDRlIVhU8MaNLh1A9SUZDUHPiZkWLFde6UNwG41yQHZEToHgJMXqyVZ9UcS/ReOVTg==",
+ "dev": true,
+ "requires": {
+ "growly": "1.3.0",
+ "semver": "5.5.0",
+ "shellwords": "0.1.1",
+ "which": "1.3.0"
+ }
+ },
+ "normalize-package-data": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "2.5.0",
+ "is-builtin-module": "1.0.0",
+ "semver": "5.5.0",
+ "validate-npm-package-license": "3.0.1"
+ }
+ },
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "1.1.0"
+ }
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "dev": true,
+ "requires": {
+ "path-key": "2.0.1"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
+ "nwmatcher": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz",
+ "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "dev": true,
+ "requires": {
+ "copy-descriptor": "0.1.1",
+ "define-property": "0.2.5",
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "object-keys": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
+ "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=",
+ "dev": true
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "requires": {
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "object.getownpropertydescriptors": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
+ "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
+ "dev": true,
+ "requires": {
+ "define-properties": "1.1.2",
+ "es-abstract": "1.10.0"
+ }
+ },
+ "object.omit": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
+ "dev": true,
+ "requires": {
+ "for-own": "0.1.5",
+ "is-extendable": "0.1.1"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "obuf": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz",
+ "integrity": "sha1-EEEktsYCxnlogaBCVB0220OlJk4=",
+ "dev": true
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "dev": true,
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "on-headers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+ "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "opn": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-5.2.0.tgz",
+ "integrity": "sha512-Jd/GpzPyHF4P2/aNOVmS3lfMSWV9J7cOhCG1s08XCEAsPkB7lp6ddiU0J7XzyQRDUh8BqJ7PchfINjR8jyofRQ==",
+ "dev": true,
+ "requires": {
+ "is-wsl": "1.1.0"
+ }
+ },
+ "optimist": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.10",
+ "wordwrap": "0.0.3"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+ "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
+ "dev": true
+ }
+ }
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "dev": true,
+ "requires": {
+ "deep-is": "0.1.3",
+ "fast-levenshtein": "2.0.6",
+ "levn": "0.3.0",
+ "prelude-ls": "1.1.2",
+ "type-check": "0.3.2",
+ "wordwrap": "1.0.0"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ }
+ }
+ },
+ "original": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz",
+ "integrity": "sha1-kUf5P6FpbQS+YeAb1QuurKZWvTs=",
+ "dev": true,
+ "requires": {
+ "url-parse": "1.0.5"
+ },
+ "dependencies": {
+ "url-parse": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz",
+ "integrity": "sha1-CFSGBCKv3P7+tsllxmLUgAFpkns=",
+ "dev": true,
+ "requires": {
+ "querystringify": "0.0.4",
+ "requires-port": "1.0.0"
+ }
+ }
+ }
+ },
+ "os-browserify": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+ "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+ "dev": true
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "dev": true
+ },
+ "os-locale": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+ "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
+ "dev": true,
+ "requires": {
+ "execa": "0.7.0",
+ "lcid": "1.0.0",
+ "mem": "1.1.0"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz",
+ "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==",
+ "dev": true,
+ "requires": {
+ "p-try": "1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "requires": {
+ "p-limit": "1.2.0"
+ }
+ },
+ "p-map": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
+ "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
+ "dev": true
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true
+ },
+ "pako": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
+ "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==",
+ "dev": true
+ },
+ "parallel-transform": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz",
+ "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
+ "dev": true,
+ "requires": {
+ "cyclist": "0.2.2",
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3"
+ }
+ },
+ "parse-asn1": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
+ "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
+ "dev": true,
+ "requires": {
+ "asn1.js": "4.9.2",
+ "browserify-aes": "1.1.1",
+ "create-hash": "1.1.3",
+ "evp_bytestokey": "1.0.3",
+ "pbkdf2": "3.0.14"
+ }
+ },
+ "parse-glob": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
+ "dev": true,
+ "requires": {
+ "glob-base": "0.3.0",
+ "is-dotfile": "1.0.3",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1"
+ }
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "dev": true,
+ "requires": {
+ "error-ex": "1.3.1"
+ }
+ },
+ "parse5": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
+ "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
+ "dev": true
+ },
+ "parseurl": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
+ "dev": true
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+ "dev": true
+ },
+ "path-browserify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
+ "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
+ "dev": true
+ },
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
+ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
+ "dev": true
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+ "dev": true
+ },
+ "path-type": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "pbkdf2": {
+ "version": "3.0.14",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
+ "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
+ "dev": true,
+ "requires": {
+ "create-hash": "1.1.3",
+ "create-hmac": "1.1.6",
+ "ripemd160": "2.0.1",
+ "safe-buffer": "5.1.1",
+ "sha.js": "2.4.10"
+ }
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+ "dev": true
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "requires": {
+ "pinkie": "2.0.4"
+ }
+ },
+ "pkg-dir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+ "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+ "dev": true,
+ "requires": {
+ "find-up": "2.1.0"
+ }
+ },
+ "pn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
+ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
+ "dev": true
+ },
+ "portfinder": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz",
+ "integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=",
+ "dev": true,
+ "requires": {
+ "async": "1.5.2",
+ "debug": "2.6.9",
+ "mkdirp": "0.5.1"
+ },
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+ "dev": true
+ }
+ }
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "preserve": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "22.1.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-22.1.0.tgz",
+ "integrity": "sha512-0HHR5hCmjDGU4sez3w5zRDAAwn7V0vT4SgPiYPZ1XDm5sT3Icb+Bh+fsOP3+Y3UwPjMr7TbRj+L7eQyMkPAxAw==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "3.0.0",
+ "ansi-styles": "3.2.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ }
+ }
+ },
+ "private": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
+ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
+ "dev": true
+ },
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+ "dev": true
+ },
+ "promise-inflight": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+ "dev": true
+ },
+ "proxy-addr": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
+ "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=",
+ "dev": true,
+ "requires": {
+ "forwarded": "0.1.2",
+ "ipaddr.js": "1.5.2"
+ }
+ },
+ "prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+ "dev": true
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+ "dev": true
+ },
+ "public-encrypt": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
+ "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=",
+ "dev": true,
+ "requires": {
+ "bn.js": "4.11.8",
+ "browserify-rsa": "4.0.1",
+ "create-hash": "1.1.3",
+ "parse-asn1": "5.1.0",
+ "randombytes": "2.0.6"
+ }
+ },
+ "pump": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
+ "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "1.4.1",
+ "once": "1.4.0"
+ }
+ },
+ "pumpify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.4.0.tgz",
+ "integrity": "sha512-2kmNR9ry+Pf45opRVirpNuIFotsxUGLaYqxIwuR77AYrYRMuFCz9eryHBS52L360O+NcR383CL4QYlMKPq4zYA==",
+ "dev": true,
+ "requires": {
+ "duplexify": "3.5.3",
+ "inherits": "2.0.3",
+ "pump": "2.0.1"
+ },
+ "dependencies": {
+ "pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "1.4.1",
+ "once": "1.4.0"
+ }
+ }
+ }
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
+ "dev": true
+ },
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+ "dev": true
+ },
+ "querystring-es3": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+ "dev": true
+ },
+ "querystringify": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz",
+ "integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=",
+ "dev": true
+ },
+ "randomatic": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
+ "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==",
+ "dev": true,
+ "requires": {
+ "is-number": "3.0.0",
+ "kind-of": "4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "randombytes": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
+ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "randomfill": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz",
+ "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==",
+ "dev": true,
+ "requires": {
+ "randombytes": "2.0.6",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "range-parser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
+ "dev": true
+ },
+ "raw-body": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+ "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
+ "dev": true,
+ "requires": {
+ "bytes": "3.0.0",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
+ "unpipe": "1.0.0"
+ }
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "1.1.0",
+ "normalize-package-data": "2.4.0",
+ "path-type": "1.1.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "dev": true,
+ "requires": {
+ "find-up": "1.1.2",
+ "read-pkg": "1.1.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "dev": true,
+ "requires": {
+ "path-exists": "2.1.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+ "dev": true,
+ "requires": {
+ "pinkie-promise": "2.0.1"
+ }
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+ "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "1.0.7",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "readdirp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
+ "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "minimatch": "3.0.4",
+ "readable-stream": "2.3.3",
+ "set-immediate-shim": "1.0.1"
+ }
+ },
+ "realpath-native": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.0.0.tgz",
+ "integrity": "sha512-XJtlRJ9jf0E1H1SLeJyQ9PGzQD7S65h1pRXEcAeK48doKOnKxcgPeNohJvD5u/2sI9J1oke6E8bZHS/fmW1UiQ==",
+ "dev": true,
+ "requires": {
+ "util.promisify": "1.0.0"
+ }
+ },
+ "redent": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+ "dev": true,
+ "requires": {
+ "indent-string": "2.1.0",
+ "strip-indent": "1.0.1"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+ "dev": true
+ },
+ "regex-cache": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
+ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
+ "dev": true,
+ "requires": {
+ "is-equal-shallow": "0.1.3"
+ }
+ },
+ "regex-not": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.0.tgz",
+ "integrity": "sha1-Qvg+OXcWIt+CawKvF2Ul1qXxV/k=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "2.0.1"
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+ "dev": true
+ },
+ "repeat-element": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
+ "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
+ },
+ "repeating": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+ "dev": true,
+ "requires": {
+ "is-finite": "1.0.2"
+ }
+ },
+ "request": {
+ "version": "2.83.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
+ "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "0.7.0",
+ "aws4": "1.6.0",
+ "caseless": "0.12.0",
+ "combined-stream": "1.0.5",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.3.1",
+ "har-validator": "5.0.3",
+ "hawk": "6.0.2",
+ "http-signature": "1.2.0",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.17",
+ "oauth-sign": "0.8.2",
+ "performance-now": "2.1.0",
+ "qs": "6.5.1",
+ "safe-buffer": "5.1.1",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.3",
+ "tunnel-agent": "0.6.0",
+ "uuid": "3.2.1"
+ }
+ },
+ "request-promise-core": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
+ "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
+ "dev": true,
+ "requires": {
+ "lodash": "4.17.5"
+ }
+ },
+ "request-promise-native": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz",
+ "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=",
+ "dev": true,
+ "requires": {
+ "request-promise-core": "1.1.1",
+ "stealthy-require": "1.1.1",
+ "tough-cookie": "2.3.3"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+ "dev": true
+ },
+ "requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+ "dev": true
+ },
+ "resolve-cwd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
+ "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
+ "dev": true,
+ "requires": {
+ "resolve-from": "3.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "dev": true
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+ "dev": true
+ },
+ "right-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+ "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+ "dev": true,
+ "requires": {
+ "align-text": "0.1.4"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "dev": true,
+ "requires": {
+ "glob": "7.1.2"
+ }
+ },
+ "ripemd160": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
+ "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
+ "dev": true,
+ "requires": {
+ "hash-base": "2.0.2",
+ "inherits": "2.0.3"
+ }
+ },
+ "rr-tsdi": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/rr-tsdi/-/rr-tsdi-1.0.3.tgz",
+ "integrity": "sha512-+oWrmlqME6rutO/esnw1zrrtk99R2htJ2Fk2uQ77Xv9xbKc748Ro29L4OyHEt2SPmJNzgDuDggGiX4ugmUOMDQ==",
+ "dev": true
+ },
+ "run-queue": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
+ "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
+ "dev": true,
+ "requires": {
+ "aproba": "1.2.0"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
+ "dev": true
+ },
+ "sane": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/sane/-/sane-2.4.1.tgz",
+ "integrity": "sha512-fW9svvNd81XzHDZyis9/tEY1bZikDGryy8Hi1BErPyNPYv47CdLseUN+tI5FBHWXEENRtj1SWtX/jBnggLaP0w==",
+ "dev": true,
+ "requires": {
+ "anymatch": "1.3.2",
+ "exec-sh": "0.2.1",
+ "fb-watchman": "2.0.0",
+ "minimatch": "3.0.4",
+ "minimist": "1.2.0",
+ "walker": "1.0.7",
+ "watch": "0.18.0"
+ }
+ },
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+ "dev": true
+ },
+ "schema-utils": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.3.tgz",
+ "integrity": "sha512-sgv/iF/T4/SewJkaVpldKC4WjSkz0JsOh2eKtxCPpCO1oR05+7MOF+H476HVRbLArkgA7j5TRJJ4p2jdFkUGQQ==",
+ "dev": true,
+ "requires": {
+ "ajv": "5.5.2",
+ "ajv-keywords": "2.1.1"
+ }
+ },
+ "select-hose": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
+ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
+ "dev": true
+ },
+ "selfsigned": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.2.tgz",
+ "integrity": "sha1-tESVgNmZKbZbEKSDiTAaZZIIh1g=",
+ "dev": true,
+ "requires": {
+ "node-forge": "0.7.1"
+ }
+ },
+ "semver": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
+ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
+ "dev": true
+ },
+ "send": {
+ "version": "0.16.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
+ "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "destroy": "1.0.4",
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "etag": "1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "1.6.2",
+ "mime": "1.4.1",
+ "ms": "2.0.0",
+ "on-finished": "2.3.0",
+ "range-parser": "1.2.0",
+ "statuses": "1.3.1"
+ }
+ },
+ "serialize-javascript": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.4.0.tgz",
+ "integrity": "sha1-fJWFFNtqwkQ6irwGLcn3iGp/YAU=",
+ "dev": true
+ },
+ "serve-index": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
+ "dev": true,
+ "requires": {
+ "accepts": "1.3.4",
+ "batch": "0.6.1",
+ "debug": "2.6.9",
+ "escape-html": "1.0.3",
+ "http-errors": "1.6.2",
+ "mime-types": "2.1.17",
+ "parseurl": "1.3.2"
+ }
+ },
+ "serve-static": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
+ "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==",
+ "dev": true,
+ "requires": {
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "parseurl": "1.3.2",
+ "send": "0.16.1"
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ },
+ "set-getter": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz",
+ "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=",
+ "dev": true,
+ "requires": {
+ "to-object-path": "0.3.0"
+ }
+ },
+ "set-immediate-shim": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+ "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+ "dev": true
+ },
+ "set-value": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "split-string": "3.1.0"
+ }
+ },
+ "setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+ "dev": true
+ },
+ "setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "dev": true
+ },
+ "sha.js": {
+ "version": "2.4.10",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.10.tgz",
+ "integrity": "sha512-vnwmrFDlOExK4Nm16J2KMWHLrp14lBrjxMxBJpu++EnsuBmpiYaM/MEs46Vxxm/4FvdP5yTwuCTO9it5FSjrqA==",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "shell-quote": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz",
+ "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=",
+ "dev": true,
+ "requires": {
+ "array-filter": "0.0.1",
+ "array-map": "0.0.0",
+ "array-reduce": "0.0.0",
+ "jsonify": "0.0.0"
+ }
+ },
+ "shellwords": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
+ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
+ "dev": true
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true
+ },
+ "slash": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+ "dev": true
+ },
+ "snapdragon": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz",
+ "integrity": "sha1-4StUh/re0+PeoKyR6UAL91tAE3A=",
+ "dev": true,
+ "requires": {
+ "base": "0.11.2",
+ "debug": "2.6.9",
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "map-cache": "0.2.2",
+ "source-map": "0.5.7",
+ "source-map-resolve": "0.5.1",
+ "use": "2.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "requires": {
+ "define-property": "1.0.0",
+ "isobject": "3.0.1",
+ "snapdragon-util": "3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "sntp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
+ "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
+ "dev": true,
+ "requires": {
+ "hoek": "4.2.0"
+ }
+ },
+ "sockjs": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
+ "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
+ "dev": true,
+ "requires": {
+ "faye-websocket": "0.10.0",
+ "uuid": "3.2.1"
+ }
+ },
+ "sockjs-client": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz",
+ "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "eventsource": "0.1.6",
+ "faye-websocket": "0.11.1",
+ "inherits": "2.0.3",
+ "json3": "3.3.2",
+ "url-parse": "1.2.0"
+ },
+ "dependencies": {
+ "faye-websocket": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz",
+ "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=",
+ "dev": true,
+ "requires": {
+ "websocket-driver": "0.7.0"
+ }
+ }
+ }
+ },
+ "source-list-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
+ "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
+ "source-map-resolve": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz",
+ "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==",
+ "dev": true,
+ "requires": {
+ "atob": "2.0.3",
+ "decode-uri-component": "0.2.0",
+ "resolve-url": "0.2.1",
+ "source-map-url": "0.4.0",
+ "urix": "0.1.0"
+ }
+ },
+ "source-map-support": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.3.tgz",
+ "integrity": "sha512-eKkTgWYeBOQqFGXRfKabMFdnWepo51vWqEdoeikaEPFiJC7MCU5j2h4+6Q8npkZTeLGbSyecZvRxiSoWl3rh+w==",
+ "dev": true,
+ "requires": {
+ "source-map": "0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+ "dev": true
+ },
+ "spdx-correct": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
+ "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
+ "dev": true,
+ "requires": {
+ "spdx-license-ids": "1.2.2"
+ }
+ },
+ "spdx-expression-parse": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
+ "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=",
+ "dev": true
+ },
+ "spdx-license-ids": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
+ "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=",
+ "dev": true
+ },
+ "spdy": {
+ "version": "3.4.7",
+ "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz",
+ "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "handle-thing": "1.2.5",
+ "http-deceiver": "1.2.7",
+ "safe-buffer": "5.1.1",
+ "select-hose": "2.0.0",
+ "spdy-transport": "2.0.20"
+ }
+ },
+ "spdy-transport": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.0.20.tgz",
+ "integrity": "sha1-c15yBUxIayNU/onnAiVgBKOazk0=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "detect-node": "2.0.3",
+ "hpack.js": "2.1.6",
+ "obuf": "1.1.1",
+ "readable-stream": "2.3.3",
+ "safe-buffer": "5.1.1",
+ "wbuf": "1.7.2"
+ }
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "3.0.2"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "1.0.0",
+ "is-extendable": "1.0.1"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ }
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+ "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+ "dev": true,
+ "requires": {
+ "asn1": "0.2.3",
+ "assert-plus": "1.0.0",
+ "bcrypt-pbkdf": "1.0.1",
+ "dashdash": "1.14.1",
+ "ecc-jsbn": "0.1.1",
+ "getpass": "0.1.7",
+ "jsbn": "0.1.1",
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "ssri": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.2.1.tgz",
+ "integrity": "sha512-y4PjOWlAuxt+yAcXitQYOnOzZpKaH3+f/qGV3OWxbyC2noC9FA9GNC9uILnVdV7jruA1aDKr4OKz3ZDBcVZwFQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "stack-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz",
+ "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=",
+ "dev": true
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "dev": true,
+ "requires": {
+ "define-property": "0.2.5",
+ "object-copy": "0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "statuses": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+ "dev": true
+ },
+ "stealthy-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+ "dev": true
+ },
+ "stream-browserify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
+ "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3"
+ }
+ },
+ "stream-each": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz",
+ "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "1.4.1",
+ "stream-shift": "1.0.0"
+ }
+ },
+ "stream-http": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.0.tgz",
+ "integrity": "sha512-sZOFxI/5xw058XIRHl4dU3dZ+TTOIGJR78Dvo0oEAejIt4ou27k+3ne1zYmCV+v7UucbxIFQuOgnkTVHh8YPnw==",
+ "dev": true,
+ "requires": {
+ "builtin-status-codes": "3.0.0",
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3",
+ "to-arraybuffer": "1.0.1",
+ "xtend": "4.0.1"
+ }
+ },
+ "stream-shift": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
+ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
+ "dev": true
+ },
+ "string-length": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz",
+ "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=",
+ "dev": true,
+ "requires": {
+ "astral-regex": "1.0.0",
+ "strip-ansi": "4.0.0"
+ }
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "2.0.0",
+ "strip-ansi": "4.0.0"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "3.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ }
+ }
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+ "dev": true,
+ "requires": {
+ "is-utf8": "0.2.1"
+ }
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+ "dev": true
+ },
+ "strip-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+ "dev": true,
+ "requires": {
+ "get-stdin": "4.0.1"
+ }
+ },
+ "subarg": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
+ "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=",
+ "dev": true,
+ "requires": {
+ "minimist": "1.2.0"
+ }
+ },
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ },
+ "symbol-tree": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz",
+ "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=",
+ "dev": true
+ },
+ "tapable": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz",
+ "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=",
+ "dev": true
+ },
+ "test-exclude": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.1.tgz",
+ "integrity": "sha512-35+Asrsk3XHJDBgf/VRFexPgh3UyETv8IAn/LRTiZjVy6rjPVqdEk8dJcJYBzl1w0XCJM48lvTy8SfEsCWS4nA==",
+ "dev": true,
+ "requires": {
+ "arrify": "1.0.1",
+ "micromatch": "2.3.11",
+ "object-assign": "4.1.1",
+ "read-pkg-up": "1.0.1",
+ "require-main-filename": "1.0.1"
+ }
+ },
+ "throat": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz",
+ "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=",
+ "dev": true
+ },
+ "through2": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "2.3.3",
+ "xtend": "4.0.1"
+ }
+ },
+ "thunky": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.2.tgz",
+ "integrity": "sha1-qGLgGOP7HqLsP85dVWBc9X8kc3E=",
+ "dev": true
+ },
+ "time-stamp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.0.0.tgz",
+ "integrity": "sha1-lcakRTDhW6jW9KPsuMOj+sRto1c=",
+ "dev": true
+ },
+ "timers-browserify": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.6.tgz",
+ "integrity": "sha512-HQ3nbYRAowdVd0ckGFvmJPPCOH/CHleFN/Y0YQCX1DVaB7t+KFvisuyN09fuP8Jtp1CpfSh8O8bMkHbdbPe6Pw==",
+ "dev": true,
+ "requires": {
+ "setimmediate": "1.0.5"
+ }
+ },
+ "tmpl": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
+ "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=",
+ "dev": true
+ },
+ "to-arraybuffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+ "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+ "dev": true
+ },
+ "to-fast-properties": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+ "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
+ "dev": true
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "to-regex": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.1.tgz",
+ "integrity": "sha1-FTWL7kosg712N3uh3ASdDxiDeq4=",
+ "dev": true,
+ "requires": {
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "regex-not": "1.0.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "requires": {
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ }
+ }
+ },
+ "tough-cookie": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
+ "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.4.1"
+ }
+ },
+ "tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
+ "dev": true,
+ "requires": {
+ "punycode": "2.1.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
+ "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=",
+ "dev": true
+ }
+ }
+ },
+ "trim-newlines": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+ "dev": true
+ },
+ "trim-right": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
+ "dev": true
+ },
+ "ts-jest": {
+ "version": "22.0.3",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-22.0.3.tgz",
+ "integrity": "sha512-6XSJpBUQwXOBgPnpKIZylx2Q4MOvSpngOj+iTevr0N4RpUT1iWBhdpMJkyjciQexlVkuMJNNOL1iZYBpLBkL4g==",
+ "dev": true,
+ "requires": {
+ "babel-core": "6.26.0",
+ "babel-plugin-istanbul": "4.1.5",
+ "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
+ "babel-preset-jest": "22.2.0",
+ "cpx": "1.5.0",
+ "fs-extra": "4.0.3",
+ "jest-config": "22.2.1",
+ "pkg-dir": "2.0.0",
+ "source-map-support": "0.5.3",
+ "yargs": "11.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "cliui": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz",
+ "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==",
+ "dev": true,
+ "requires": {
+ "string-width": "2.1.1",
+ "strip-ansi": "4.0.0",
+ "wrap-ansi": "2.1.0"
+ }
+ },
+ "yargs": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz",
+ "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==",
+ "dev": true,
+ "requires": {
+ "cliui": "4.0.0",
+ "decamelize": "1.2.0",
+ "find-up": "2.1.0",
+ "get-caller-file": "1.0.2",
+ "os-locale": "2.1.0",
+ "require-directory": "2.1.1",
+ "require-main-filename": "1.0.1",
+ "set-blocking": "2.0.0",
+ "string-width": "2.1.1",
+ "which-module": "2.0.0",
+ "y18n": "3.2.1",
+ "yargs-parser": "9.0.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz",
+ "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=",
+ "dev": true,
+ "requires": {
+ "camelcase": "4.1.0"
+ }
+ }
+ }
+ },
+ "ts-loader": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-3.5.0.tgz",
+ "integrity": "sha512-JTia3kObhTk36wPFgy0RnkZReiusYx7Le9IhcUWRrCTcFcr6Dy1zGsFd3x8DG4gevlbN65knI8W50FfoykXcng==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.3.0",
+ "enhanced-resolve": "3.4.1",
+ "loader-utils": "1.1.0",
+ "micromatch": "3.1.5",
+ "semver": "5.5.0"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.0.tgz",
+ "integrity": "sha512-P4O8UQRdGiMLWSizsApmXVQDBS6KCt7dSexgLKBmH5Hr1CZq7vsnscFh8oR1sP1ab1Zj0uCHCEzZeV6SfUf3rA==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "1.1.0",
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "extend-shallow": "2.0.1",
+ "fill-range": "4.0.0",
+ "isobject": "3.0.1",
+ "repeat-element": "1.1.2",
+ "snapdragon": "0.8.1",
+ "snapdragon-node": "2.1.1",
+ "split-string": "3.1.0",
+ "to-regex": "3.0.1"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "posix-character-classes": "0.1.1",
+ "regex-not": "1.0.0",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "expand-brackets": "2.1.4",
+ "extend-shallow": "2.0.1",
+ "fragment-cache": "0.2.1",
+ "regex-not": "1.0.0",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1",
+ "to-regex-range": "2.1.1"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.5.tgz",
+ "integrity": "sha512-ykttrLPQrz1PUJcXjwsTUjGoPJ64StIGNE2lGVD1c9CuguJ+L7/navsE8IcDNndOoCMvYV0qc/exfVbMHkUhvA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "braces": "2.3.0",
+ "define-property": "1.0.0",
+ "extend-shallow": "2.0.1",
+ "extglob": "2.0.4",
+ "fragment-cache": "0.2.1",
+ "kind-of": "6.0.2",
+ "nanomatch": "1.2.7",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.0",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.1"
+ }
+ }
+ }
+ },
+ "tslib": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
+ "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==",
+ "dev": true
+ },
+ "tslint": {
+ "version": "5.9.1",
+ "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.9.1.tgz",
+ "integrity": "sha1-ElX4ej/1frCw4fDmEKi0dIBGya4=",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "6.26.0",
+ "builtin-modules": "1.1.1",
+ "chalk": "2.3.0",
+ "commander": "2.14.1",
+ "diff": "3.4.0",
+ "glob": "7.1.2",
+ "js-yaml": "3.10.0",
+ "minimatch": "3.0.4",
+ "resolve": "1.5.0",
+ "semver": "5.5.0",
+ "tslib": "1.9.0",
+ "tsutils": "2.21.0"
+ },
+ "dependencies": {
+ "resolve": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz",
+ "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==",
+ "dev": true,
+ "requires": {
+ "path-parse": "1.0.5"
+ }
+ }
+ }
+ },
+ "tsutils": {
+ "version": "2.21.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.21.0.tgz",
+ "integrity": "sha512-zlOHTYtTwvTiKxUyAU8wiKzPpAgwZrGjb7AY18VUlxuCgBiTMVorIl5HjrCT8V64Hm34RI1BZITJMVQpBLMxVg==",
+ "dev": true,
+ "requires": {
+ "tslib": "1.9.0"
+ }
+ },
+ "tty-browserify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+ "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
+ "dev": true
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true,
+ "optional": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "1.1.2"
+ }
+ },
+ "type-is": {
+ "version": "1.6.15",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
+ "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
+ "dev": true,
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "2.1.17"
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ },
+ "typescript": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.1.tgz",
+ "integrity": "sha512-bqB1yS6o9TNA9ZC/MJxM0FZzPnZdtHj0xWK/IZ5khzVqdpGul/R/EIiHRgFXlwTD7PSIaYVnGKq1QgMCu2mnqw==",
+ "dev": true
+ },
+ "typescript-formatter": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/typescript-formatter/-/typescript-formatter-7.0.1.tgz",
+ "integrity": "sha512-OIp8HfBsjFT/gS5JHlMBn1BNh9cRH66/07lzYjtAApjhN5Utwcjq3EB0zIQvNhQfQmOWlJvPGFZTXIunYy+btg==",
+ "dev": true,
+ "requires": {
+ "commandpost": "1.3.0",
+ "editorconfig": "0.15.0"
+ }
+ },
+ "uglify-js": {
+ "version": "2.8.29",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
+ "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
+ "dev": true,
+ "requires": {
+ "source-map": "0.5.7",
+ "uglify-to-browserify": "1.0.2",
+ "yargs": "3.10.0"
+ },
+ "dependencies": {
+ "yargs": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+ "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+ "dev": true,
+ "requires": {
+ "camelcase": "1.2.1",
+ "cliui": "2.1.0",
+ "decamelize": "1.2.0",
+ "window-size": "0.1.0"
+ }
+ }
+ }
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+ "dev": true,
+ "optional": true
+ },
+ "uglifyjs-webpack-plugin": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.1.8.tgz",
+ "integrity": "sha512-XG8/QmR1pyPeE1kj2aigo5kos8umefB31zW+PMvAAytHSB0T/vQvN6sqt8+Sh+y0b0A7zlmxNi2dzRnj0wcqGA==",
+ "dev": true,
+ "requires": {
+ "cacache": "10.0.2",
+ "find-cache-dir": "1.0.0",
+ "schema-utils": "0.4.3",
+ "serialize-javascript": "1.4.0",
+ "source-map": "0.6.1",
+ "uglify-es": "3.3.10",
+ "webpack-sources": "1.1.0",
+ "worker-farm": "1.5.2"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "uglify-es": {
+ "version": "3.3.10",
+ "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.10.tgz",
+ "integrity": "sha512-rPzPisCzW68Okj1zNrfa2dR9uEm43SevDmpR6FChoZABFk9dANGnzzBMgHYUXI3609//63fnVkyQ1SQmAMyjww==",
+ "dev": true,
+ "requires": {
+ "commander": "2.14.1",
+ "source-map": "0.6.1"
+ }
+ }
+ }
+ },
+ "ultron": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+ "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
+ "dev": true
+ },
+ "underscore.string": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
+ "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=",
+ "dev": true
+ },
+ "union-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+ "dev": true,
+ "requires": {
+ "arr-union": "3.1.0",
+ "get-value": "2.0.6",
+ "is-extendable": "0.1.1",
+ "set-value": "0.4.3"
+ },
+ "dependencies": {
+ "set-value": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "to-object-path": "0.3.0"
+ }
+ }
+ }
+ },
+ "unique-filename": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz",
+ "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=",
+ "dev": true,
+ "requires": {
+ "unique-slug": "2.0.0"
+ }
+ },
+ "unique-slug": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz",
+ "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "0.1.4"
+ }
+ },
+ "universalify": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
+ "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=",
+ "dev": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "dev": true
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "dev": true,
+ "requires": {
+ "has-value": "0.3.1",
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "dev": true,
+ "requires": {
+ "get-value": "2.0.6",
+ "has-values": "0.1.4",
+ "isobject": "2.1.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "upath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.0.tgz",
+ "integrity": "sha1-tHBrlGHKhHOt+JEz0jVonKF/NlY=",
+ "dev": true,
+ "requires": {
+ "lodash": "3.10.1",
+ "underscore.string": "2.3.3"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+ "dev": true
+ }
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+ "dev": true
+ },
+ "url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+ "dev": true
+ }
+ }
+ },
+ "url-parse": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.2.0.tgz",
+ "integrity": "sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw==",
+ "dev": true,
+ "requires": {
+ "querystringify": "1.0.0",
+ "requires-port": "1.0.0"
+ },
+ "dependencies": {
+ "querystringify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz",
+ "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=",
+ "dev": true
+ }
+ }
+ },
+ "use": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz",
+ "integrity": "sha1-riig1y+TvyJCKhii43mZMRLeyOg=",
+ "dev": true,
+ "requires": {
+ "define-property": "0.2.5",
+ "isobject": "3.0.1",
+ "lazy-cache": "2.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ },
+ "lazy-cache": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
+ "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
+ "dev": true,
+ "requires": {
+ "set-getter": "0.1.0"
+ }
+ }
+ }
+ },
+ "util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.1"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+ "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+ "dev": true
+ }
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "util.promisify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
+ "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
+ "dev": true,
+ "requires": {
+ "define-properties": "1.1.2",
+ "object.getownpropertydescriptors": "2.0.3"
+ }
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
+ "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==",
+ "dev": true
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
+ "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "1.0.2",
+ "spdx-expression-parse": "1.0.4"
+ }
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+ "dev": true
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "1.3.0"
+ }
+ },
+ "vm-browserify": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
+ "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
+ "dev": true,
+ "requires": {
+ "indexof": "0.0.1"
+ }
+ },
+ "w3c-hr-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
+ "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
+ "dev": true,
+ "requires": {
+ "browser-process-hrtime": "0.1.2"
+ }
+ },
+ "walker": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
+ "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=",
+ "dev": true,
+ "requires": {
+ "makeerror": "1.0.11"
+ }
+ },
+ "watch": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz",
+ "integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=",
+ "dev": true,
+ "requires": {
+ "exec-sh": "0.2.1",
+ "minimist": "1.2.0"
+ }
+ },
+ "watchpack": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz",
+ "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=",
+ "dev": true,
+ "requires": {
+ "async": "2.6.0",
+ "chokidar": "1.7.0",
+ "graceful-fs": "4.1.11"
+ }
+ },
+ "wbuf": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.2.tgz",
+ "integrity": "sha1-1pe5nx9ZUS3ydRvkJ2nBWAtYAf4=",
+ "dev": true,
+ "requires": {
+ "minimalistic-assert": "1.0.0"
+ }
+ },
+ "webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true
+ },
+ "webpack": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz",
+ "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==",
+ "dev": true,
+ "requires": {
+ "acorn": "5.4.1",
+ "acorn-dynamic-import": "2.0.2",
+ "ajv": "5.5.2",
+ "ajv-keywords": "2.1.1",
+ "async": "2.6.0",
+ "enhanced-resolve": "3.4.1",
+ "escope": "3.6.0",
+ "interpret": "1.1.0",
+ "json-loader": "0.5.7",
+ "json5": "0.5.1",
+ "loader-runner": "2.3.0",
+ "loader-utils": "1.1.0",
+ "memory-fs": "0.4.1",
+ "mkdirp": "0.5.1",
+ "node-libs-browser": "2.1.0",
+ "source-map": "0.5.7",
+ "supports-color": "4.5.0",
+ "tapable": "0.2.8",
+ "uglifyjs-webpack-plugin": "0.4.6",
+ "watchpack": "1.4.0",
+ "webpack-sources": "1.1.0",
+ "yargs": "8.0.2"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "dev": true,
+ "requires": {
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1",
+ "wrap-ansi": "2.1.0"
+ },
+ "dependencies": {
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ }
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "load-json-file": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "parse-json": "2.2.0",
+ "pify": "2.3.0",
+ "strip-bom": "3.0.0"
+ }
+ },
+ "path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "dev": true,
+ "requires": {
+ "pify": "2.3.0"
+ }
+ },
+ "read-pkg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "2.0.0",
+ "normalize-package-data": "2.4.0",
+ "path-type": "2.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+ "dev": true,
+ "requires": {
+ "find-up": "2.1.0",
+ "read-pkg": "2.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "uglifyjs-webpack-plugin": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz",
+ "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=",
+ "dev": true,
+ "requires": {
+ "source-map": "0.5.7",
+ "uglify-js": "2.8.29",
+ "webpack-sources": "1.1.0"
+ }
+ },
+ "yargs": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz",
+ "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=",
+ "dev": true,
+ "requires": {
+ "camelcase": "4.1.0",
+ "cliui": "3.2.0",
+ "decamelize": "1.2.0",
+ "get-caller-file": "1.0.2",
+ "os-locale": "2.1.0",
+ "read-pkg-up": "2.0.0",
+ "require-directory": "2.1.1",
+ "require-main-filename": "1.0.1",
+ "set-blocking": "2.0.0",
+ "string-width": "2.1.1",
+ "which-module": "2.0.0",
+ "y18n": "3.2.1",
+ "yargs-parser": "7.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
+ "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
+ "dev": true,
+ "requires": {
+ "camelcase": "4.1.0"
+ }
+ }
+ }
+ },
+ "webpack-dev-middleware": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz",
+ "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==",
+ "dev": true,
+ "requires": {
+ "memory-fs": "0.4.1",
+ "mime": "1.6.0",
+ "path-is-absolute": "1.0.1",
+ "range-parser": "1.2.0",
+ "time-stamp": "2.0.0"
+ },
+ "dependencies": {
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true
+ }
+ }
+ },
+ "webpack-dev-server": {
+ "version": "2.11.1",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.11.1.tgz",
+ "integrity": "sha512-ombhu5KsO/85sVshIDTyQ5HF3xjZR3N0sf5Ao6h3vFwpNyzInEzA1GV3QPVjTMLTNckp8PjfG1PFGznzBwS5lg==",
+ "dev": true,
+ "requires": {
+ "ansi-html": "0.0.7",
+ "array-includes": "3.0.3",
+ "bonjour": "3.5.0",
+ "chokidar": "2.0.1",
+ "compression": "1.7.1",
+ "connect-history-api-fallback": "1.5.0",
+ "debug": "3.1.0",
+ "del": "3.0.0",
+ "express": "4.16.2",
+ "html-entities": "1.2.1",
+ "http-proxy-middleware": "0.17.4",
+ "import-local": "1.0.0",
+ "internal-ip": "1.2.0",
+ "ip": "1.1.5",
+ "killable": "1.0.0",
+ "loglevel": "1.6.1",
+ "opn": "5.2.0",
+ "portfinder": "1.0.13",
+ "selfsigned": "1.10.2",
+ "serve-index": "1.9.1",
+ "sockjs": "0.3.19",
+ "sockjs-client": "1.1.4",
+ "spdy": "3.4.7",
+ "strip-ansi": "3.0.1",
+ "supports-color": "5.1.0",
+ "webpack-dev-middleware": "1.12.2",
+ "yargs": "6.6.0"
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "requires": {
+ "micromatch": "3.1.5",
+ "normalize-path": "2.1.1"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.0.tgz",
+ "integrity": "sha512-P4O8UQRdGiMLWSizsApmXVQDBS6KCt7dSexgLKBmH5Hr1CZq7vsnscFh8oR1sP1ab1Zj0uCHCEzZeV6SfUf3rA==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "1.1.0",
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "extend-shallow": "2.0.1",
+ "fill-range": "4.0.0",
+ "isobject": "3.0.1",
+ "repeat-element": "1.1.2",
+ "snapdragon": "0.8.1",
+ "snapdragon-node": "2.1.1",
+ "split-string": "3.1.0",
+ "to-regex": "3.0.1"
+ }
+ },
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+ "dev": true
+ },
+ "chokidar": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.1.tgz",
+ "integrity": "sha512-rv5iP8ENhpqvDWr677rAXcB+SMoPQ1urd4ch79+PhM4lQwbATdJUQK69t0lJIKNB+VXpqxt5V1gvqs59XEPKnw==",
+ "dev": true,
+ "requires": {
+ "anymatch": "2.0.0",
+ "async-each": "1.0.1",
+ "braces": "2.3.0",
+ "glob-parent": "3.1.0",
+ "inherits": "2.0.3",
+ "is-binary-path": "1.0.1",
+ "is-glob": "4.0.0",
+ "normalize-path": "2.1.1",
+ "path-is-absolute": "1.0.1",
+ "readdirp": "2.1.0",
+ "upath": "1.0.0"
+ }
+ },
+ "cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "dev": true,
+ "requires": {
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1",
+ "wrap-ansi": "2.1.0"
+ }
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "posix-character-classes": "0.1.1",
+ "regex-not": "1.0.0",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "expand-brackets": "2.1.4",
+ "extend-shallow": "2.0.1",
+ "fragment-cache": "0.2.1",
+ "regex-not": "1.0.0",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1",
+ "to-regex-range": "2.1.1"
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "3.1.0",
+ "path-dirname": "1.0.2"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "2.1.1"
+ }
+ }
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "is-glob": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.5.tgz",
+ "integrity": "sha512-ykttrLPQrz1PUJcXjwsTUjGoPJ64StIGNE2lGVD1c9CuguJ+L7/navsE8IcDNndOoCMvYV0qc/exfVbMHkUhvA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "braces": "2.3.0",
+ "define-property": "1.0.0",
+ "extend-shallow": "2.0.1",
+ "extglob": "2.0.4",
+ "fragment-cache": "0.2.1",
+ "kind-of": "6.0.2",
+ "nanomatch": "1.2.7",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.0",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.1"
+ }
+ },
+ "os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "dev": true,
+ "requires": {
+ "lcid": "1.0.0"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "supports-color": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz",
+ "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
+ "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=",
+ "dev": true,
+ "requires": {
+ "camelcase": "3.0.0",
+ "cliui": "3.2.0",
+ "decamelize": "1.2.0",
+ "get-caller-file": "1.0.2",
+ "os-locale": "1.4.0",
+ "read-pkg-up": "1.0.1",
+ "require-directory": "2.1.1",
+ "require-main-filename": "1.0.1",
+ "set-blocking": "2.0.0",
+ "string-width": "1.0.2",
+ "which-module": "1.0.0",
+ "y18n": "3.2.1",
+ "yargs-parser": "4.2.1"
+ }
+ },
+ "yargs-parser": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz",
+ "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=",
+ "dev": true,
+ "requires": {
+ "camelcase": "3.0.0"
+ }
+ }
+ }
+ },
+ "webpack-sources": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz",
+ "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==",
+ "dev": true,
+ "requires": {
+ "source-list-map": "2.0.0",
+ "source-map": "0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "websocket-driver": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz",
+ "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=",
+ "dev": true,
+ "requires": {
+ "http-parser-js": "0.4.10",
+ "websocket-extensions": "0.1.3"
+ }
+ },
+ "websocket-extensions": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
+ "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
+ "dev": true
+ },
+ "whatwg-encoding": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz",
+ "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==",
+ "dev": true,
+ "requires": {
+ "iconv-lite": "0.4.19"
+ }
+ },
+ "whatwg-url": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.4.0.tgz",
+ "integrity": "sha512-Z0CVh/YE217Foyb488eo+iBv+r7eAQ0wSTyApi9n06jhcA3z6Nidg/EGvl0UFkg7kMdKxfBzzr+o9JF+cevgMg==",
+ "dev": true,
+ "requires": {
+ "lodash.sortby": "4.7.0",
+ "tr46": "1.0.1",
+ "webidl-conversions": "4.0.2"
+ }
+ },
+ "which": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
+ "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+ "dev": true,
+ "requires": {
+ "isexe": "2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+ "dev": true
+ },
+ "window-size": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+ "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
+ "dev": true
+ },
+ "wordwrap": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+ "dev": true
+ },
+ "worker-farm": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.5.2.tgz",
+ "integrity": "sha512-XxiQ9kZN5n6mmnW+mFJ+wXjNNI/Nx4DIdaAKLX1Bn6LYBWlN/zaBhu34DQYPZ1AJobQuu67S2OfDdNSVULvXkQ==",
+ "dev": true,
+ "requires": {
+ "errno": "0.1.6",
+ "xtend": "4.0.1"
+ }
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
+ "requires": {
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1"
+ },
+ "dependencies": {
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ }
+ }
+ },
+ "wrapper-webpack-plugin": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wrapper-webpack-plugin/-/wrapper-webpack-plugin-1.0.0.tgz",
+ "integrity": "sha1-VcEWR/jKmQ/28EtB2PpK8JbDG7s=",
+ "dev": true,
+ "requires": {
+ "webpack-sources": "1.1.0"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "write-file-atomic": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz",
+ "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "imurmurhash": "0.1.4",
+ "signal-exit": "3.0.2"
+ }
+ },
+ "ws": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-4.0.0.tgz",
+ "integrity": "sha512-QYslsH44bH8O7/W2815u5DpnCpXWpEK44FmaHffNwgJI4JMaSZONgPBTOfrxJ29mXKbXak+LsJ2uAkDTYq2ptQ==",
+ "dev": true,
+ "requires": {
+ "async-limiter": "1.0.0",
+ "safe-buffer": "5.1.1",
+ "ultron": "1.1.1"
+ }
+ },
+ "xml-name-validator": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+ "dev": true
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+ "dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "10.1.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz",
+ "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==",
+ "dev": true,
+ "requires": {
+ "cliui": "4.0.0",
+ "decamelize": "1.2.0",
+ "find-up": "2.1.0",
+ "get-caller-file": "1.0.2",
+ "os-locale": "2.1.0",
+ "require-directory": "2.1.1",
+ "require-main-filename": "1.0.1",
+ "set-blocking": "2.0.0",
+ "string-width": "2.1.1",
+ "which-module": "2.0.0",
+ "y18n": "3.2.1",
+ "yargs-parser": "8.1.0"
+ },
+ "dependencies": {
+ "cliui": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz",
+ "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==",
+ "dev": true,
+ "requires": {
+ "string-width": "2.1.1",
+ "strip-ansi": "4.0.0",
+ "wrap-ansi": "2.1.0"
+ }
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz",
+ "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "4.1.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ }
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index 88cca3a..5c51b11 100644
--- a/package.json
+++ b/package.json
@@ -1,28 +1,8 @@
{
"name": "audio-network",
"version": "1.3.0",
+ "homepage": "https://audio-network.rypula.pl",
"description": "Data transmission over sound waves written in JavaScript without any dependencies. All you need is just microphone, speakers and the browser!",
- "main": "build/audio-network-v1.3.0.js",
- "dependencies": {},
- "devDependencies": {
- "glob": "7.1.2",
- "gulp": "3.9.1",
- "gulp-concat": "2.6.1",
- "gulp-debug": "3.1.0",
- "gulp-header": "1.8.9",
- "gulp-markdown": "1.2.0",
- "gulp-rename": "1.2.2",
- "gulp-uglify": "3.0.0",
- "gulp-webserver": "0.9.1",
- "jasmine": "2.8.0"
- },
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/robertrypula/AudioNetwork.git"
- },
"keywords": [
"transmission over sound",
"Web Audio API",
@@ -45,8 +25,58 @@
],
"author": "Robert Rypuła",
"license": "MIT",
+ "scripts": {
+ "dev": "npm run clean && webpack-dev-server --env.DEVELOPMENT --open",
+ "build": "npm run clean && npm run test && npm run lint && npm run lint:tsfmt:verify && webpack --env.PRODUCTION",
+ "test": "jest --coverage",
+ "test:watch": "jest --watch",
+ "lint": "tslint -c tslint.json 'src/**/*.ts'",
+ "lint:tsfmt:verify": "tsfmt --verify --no-tsfmt --no-tslint --no-tsconfig --no-vscode",
+ "lint:tsfmt:replace": "tsfmt --replace --no-tsfmt --no-tslint --no-tsconfig --no-vscode",
+ "report-coverage": "cat ./coverage/lcov.info | coveralls",
+ "clean": "rimraf dist && rimraf coverage"
+ },
+ "main": "dist/audio-network-v2.0.0-rc.js",
+ "types": "dist/index.d.ts",
+ "files": [
+ "dist/"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/robertrypula/AudioNetwork.git"
+ },
"bugs": {
"url": "https://github.com/robertrypula/AudioNetwork/issues"
},
- "homepage": "https://audio-network.rypula.pl"
+ "jest": {
+ "transform": {
+ "^.+\\.tsx?$": "ts-jest"
+ },
+ "testRegex": "(/__tests__/.*|(\\.|/)(spec))\\.(jsx?|tsx?)$",
+ "moduleFileExtensions": [
+ "ts",
+ "tsx",
+ "js",
+ "jsx",
+ "json",
+ "node"
+ ],
+ "testEnvironment": "node"
+ },
+ "devDependencies": {
+ "@types/jest": "^22.1.0",
+ "coveralls": "^3.0.0",
+ "jest": "^22.1.4",
+ "rimraf": "^2.6.2",
+ "rr-tsdi": "^1.0.3",
+ "ts-jest": "^22.0.1",
+ "ts-loader": "^3.2.0",
+ "tslint": "^5.9.1",
+ "typescript": "^2.6.2",
+ "typescript-formatter": "^7.0.1",
+ "uglifyjs-webpack-plugin": "^1.1.6",
+ "webpack": "^3.10.0",
+ "webpack-dev-server": "^2.11.1",
+ "wrapper-webpack-plugin": "^1.0.0"
+ }
}
diff --git a/src/-deprecated-probably/common/math-util/math-util.service.js b/src/-still-es5/-deprecated-probably/common/math-util/math-util.service.js
similarity index 100%
rename from src/-deprecated-probably/common/math-util/math-util.service.js
rename to src/-still-es5/-deprecated-probably/common/math-util/math-util.service.js
diff --git a/src/-deprecated-probably/common/simple-promise/simple-promise-builder.service.js b/src/-still-es5/-deprecated-probably/common/simple-promise/simple-promise-builder.service.js
similarity index 100%
rename from src/-deprecated-probably/common/simple-promise/simple-promise-builder.service.js
rename to src/-still-es5/-deprecated-probably/common/simple-promise/simple-promise-builder.service.js
diff --git a/src/-deprecated-probably/common/simple-promise/simple-promise.factory.js b/src/-still-es5/-deprecated-probably/common/simple-promise/simple-promise.factory.js
similarity index 100%
rename from src/-deprecated-probably/common/simple-promise/simple-promise.factory.js
rename to src/-still-es5/-deprecated-probably/common/simple-promise/simple-promise.factory.js
diff --git a/src/-deprecated-probably/common/stopwatch/stopwatch-builder.service.js b/src/-still-es5/-deprecated-probably/common/stopwatch/stopwatch-builder.service.js
similarity index 100%
rename from src/-deprecated-probably/common/stopwatch/stopwatch-builder.service.js
rename to src/-still-es5/-deprecated-probably/common/stopwatch/stopwatch-builder.service.js
diff --git a/src/-deprecated-probably/common/stopwatch/stopwatch.factory.js b/src/-still-es5/-deprecated-probably/common/stopwatch/stopwatch.factory.js
similarity index 100%
rename from src/-deprecated-probably/common/stopwatch/stopwatch.factory.js
rename to src/-still-es5/-deprecated-probably/common/stopwatch/stopwatch.factory.js
diff --git a/src/-deprecated-probably/common/window-function/window-function.service.js b/src/-still-es5/-deprecated-probably/common/window-function/window-function.service.js
similarity index 100%
rename from src/-deprecated-probably/common/window-function/window-function.service.js
rename to src/-still-es5/-deprecated-probably/common/window-function/window-function.service.js
diff --git a/src/-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker-thread.service.js b/src/-still-es5/-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker-thread.service.js
similarity index 100%
rename from src/-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker-thread.service.js
rename to src/-still-es5/-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker-thread.service.js
diff --git a/src/-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker.factory.js b/src/-still-es5/-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker.factory.js
similarity index 100%
rename from src/-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker.factory.js
rename to src/-still-es5/-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker.factory.js
diff --git a/src/-deprecated-probably/physical-layer-core/receive-worker/receive-worker.factory.js b/src/-still-es5/-deprecated-probably/physical-layer-core/receive-worker/receive-worker.factory.js
similarity index 100%
rename from src/-deprecated-probably/physical-layer-core/receive-worker/receive-worker.factory.js
rename to src/-still-es5/-deprecated-probably/physical-layer-core/receive-worker/receive-worker.factory.js
diff --git a/src/-deprecated/audio/active-audio-context/active-audio-context.service.js b/src/-still-es5/-deprecated/audio/active-audio-context/active-audio-context.service.js
similarity index 100%
rename from src/-deprecated/audio/active-audio-context/active-audio-context.service.js
rename to src/-still-es5/-deprecated/audio/active-audio-context/active-audio-context.service.js
diff --git a/src/-deprecated/audio/simple-audio-context/simple-audio-context-builder.service.js b/src/-still-es5/-deprecated/audio/simple-audio-context/simple-audio-context-builder.service.js
similarity index 100%
rename from src/-deprecated/audio/simple-audio-context/simple-audio-context-builder.service.js
rename to src/-still-es5/-deprecated/audio/simple-audio-context/simple-audio-context-builder.service.js
diff --git a/src/-deprecated/audio/simple-audio-context/simple-audio-context.factory.js b/src/-still-es5/-deprecated/audio/simple-audio-context/simple-audio-context.factory.js
similarity index 100%
rename from src/-deprecated/audio/simple-audio-context/simple-audio-context.factory.js
rename to src/-still-es5/-deprecated/audio/simple-audio-context/simple-audio-context.factory.js
diff --git a/src/-deprecated/common/abstract-value-collector/abstract-value-collector.factory.js b/src/-still-es5/-deprecated/common/abstract-value-collector/abstract-value-collector.factory.js
similarity index 100%
rename from src/-deprecated/common/abstract-value-collector/abstract-value-collector.factory.js
rename to src/-still-es5/-deprecated/common/abstract-value-collector/abstract-value-collector.factory.js
diff --git a/src/-deprecated/common/average-value-collector/average-value-collector-builder.service.js b/src/-still-es5/-deprecated/common/average-value-collector/average-value-collector-builder.service.js
similarity index 100%
rename from src/-deprecated/common/average-value-collector/average-value-collector-builder.service.js
rename to src/-still-es5/-deprecated/common/average-value-collector/average-value-collector-builder.service.js
diff --git a/src/-deprecated/common/average-value-collector/average-value-collector.factory.js b/src/-still-es5/-deprecated/common/average-value-collector/average-value-collector.factory.js
similarity index 100%
rename from src/-deprecated/common/average-value-collector/average-value-collector.factory.js
rename to src/-still-es5/-deprecated/common/average-value-collector/average-value-collector.factory.js
diff --git a/src/-deprecated/common/carrier-generate/carrier-generate-builder.service.js b/src/-still-es5/-deprecated/common/carrier-generate/carrier-generate-builder.service.js
similarity index 100%
rename from src/-deprecated/common/carrier-generate/carrier-generate-builder.service.js
rename to src/-still-es5/-deprecated/common/carrier-generate/carrier-generate-builder.service.js
diff --git a/src/-deprecated/common/carrier-generate/carrier-generate.factory.js b/src/-still-es5/-deprecated/common/carrier-generate/carrier-generate.factory.js
similarity index 100%
rename from src/-deprecated/common/carrier-generate/carrier-generate.factory.js
rename to src/-still-es5/-deprecated/common/carrier-generate/carrier-generate.factory.js
diff --git a/src/-deprecated/common/carrier-recovery/carrier-recovery-builder.service.js b/src/-still-es5/-deprecated/common/carrier-recovery/carrier-recovery-builder.service.js
similarity index 100%
rename from src/-deprecated/common/carrier-recovery/carrier-recovery-builder.service.js
rename to src/-still-es5/-deprecated/common/carrier-recovery/carrier-recovery-builder.service.js
diff --git a/src/-deprecated/common/carrier-recovery/carrier-recovery.factory.js b/src/-still-es5/-deprecated/common/carrier-recovery/carrier-recovery.factory.js
similarity index 100%
rename from src/-deprecated/common/carrier-recovery/carrier-recovery.factory.js
rename to src/-still-es5/-deprecated/common/carrier-recovery/carrier-recovery.factory.js
diff --git a/src/-deprecated/common/complex/complex-builder.service.js b/src/-still-es5/-deprecated/common/complex/complex-builder.service.js
similarity index 100%
rename from src/-deprecated/common/complex/complex-builder.service.js
rename to src/-still-es5/-deprecated/common/complex/complex-builder.service.js
diff --git a/src/-deprecated/common/complex/complex.factory.js b/src/-still-es5/-deprecated/common/complex/complex.factory.js
similarity index 100%
rename from src/-deprecated/common/complex/complex.factory.js
rename to src/-still-es5/-deprecated/common/complex/complex.factory.js
diff --git a/src/-deprecated/common/queue/queue-builder.service.js b/src/-still-es5/-deprecated/common/queue/queue-builder.service.js
similarity index 100%
rename from src/-deprecated/common/queue/queue-builder.service.js
rename to src/-still-es5/-deprecated/common/queue/queue-builder.service.js
diff --git a/src/-deprecated/common/queue/queue.factory.js b/src/-still-es5/-deprecated/common/queue/queue.factory.js
similarity index 100%
rename from src/-deprecated/common/queue/queue.factory.js
rename to src/-still-es5/-deprecated/common/queue/queue.factory.js
diff --git a/src/-deprecated/common/util/util.service.js b/src/-still-es5/-deprecated/common/util/util.service.js
similarity index 100%
rename from src/-deprecated/common/util/util.service.js
rename to src/-still-es5/-deprecated/common/util/util.service.js
diff --git a/src/-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector-builder.service.js b/src/-still-es5/-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector-builder.service.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector-builder.service.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector-builder.service.js
diff --git a/src/-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector.factory.js b/src/-still-es5/-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector.factory.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector.factory.js
diff --git a/src/-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector-builder.service.js b/src/-still-es5/-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector-builder.service.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector-builder.service.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector-builder.service.js
diff --git a/src/-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector.factory.js b/src/-still-es5/-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector.factory.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector.factory.js
diff --git a/src/-deprecated/physical-layer-adapter/receive-adapter-state.service.js b/src/-still-es5/-deprecated/physical-layer-adapter/receive-adapter-state.service.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/receive-adapter-state.service.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/receive-adapter-state.service.js
diff --git a/src/-deprecated/physical-layer-adapter/receive-adapter.factory.js b/src/-still-es5/-deprecated/physical-layer-adapter/receive-adapter.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/receive-adapter.factory.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/receive-adapter.factory.js
diff --git a/src/-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager-builder.service.js b/src/-still-es5/-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager-builder.service.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager-builder.service.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager-builder.service.js
diff --git a/src/-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager.factory.js b/src/-still-es5/-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager.factory.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager.factory.js
diff --git a/src/-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine-builder.service.js b/src/-still-es5/-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine-builder.service.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine-builder.service.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine-builder.service.js
diff --git a/src/-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine.factory.js b/src/-still-es5/-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine.factory.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine.factory.js
diff --git a/src/-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector-builder.service.js b/src/-still-es5/-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector-builder.service.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector-builder.service.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector-builder.service.js
diff --git a/src/-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector.factory.js b/src/-still-es5/-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector.factory.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector.factory.js
diff --git a/src/-deprecated/physical-layer-adapter/transmit-adapter.factory.js b/src/-still-es5/-deprecated/physical-layer-adapter/transmit-adapter.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer-adapter/transmit-adapter.factory.js
rename to src/-still-es5/-deprecated/physical-layer-adapter/transmit-adapter.factory.js
diff --git a/src/-deprecated/physical-layer/abstract-channel-manager/abstract-channel-manager.factory.js b/src/-still-es5/-deprecated/physical-layer/abstract-channel-manager/abstract-channel-manager.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer/abstract-channel-manager/abstract-channel-manager.factory.js
rename to src/-still-es5/-deprecated/physical-layer/abstract-channel-manager/abstract-channel-manager.factory.js
diff --git a/src/-deprecated/physical-layer/channel-receive-manager/channel-receive-manager-builder.service.js b/src/-still-es5/-deprecated/physical-layer/channel-receive-manager/channel-receive-manager-builder.service.js
similarity index 100%
rename from src/-deprecated/physical-layer/channel-receive-manager/channel-receive-manager-builder.service.js
rename to src/-still-es5/-deprecated/physical-layer/channel-receive-manager/channel-receive-manager-builder.service.js
diff --git a/src/-deprecated/physical-layer/channel-receive-manager/channel-receive-manager.factory.js b/src/-still-es5/-deprecated/physical-layer/channel-receive-manager/channel-receive-manager.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer/channel-receive-manager/channel-receive-manager.factory.js
rename to src/-still-es5/-deprecated/physical-layer/channel-receive-manager/channel-receive-manager.factory.js
diff --git a/src/-deprecated/physical-layer/channel-receive/channel-receive-builder.service.js b/src/-still-es5/-deprecated/physical-layer/channel-receive/channel-receive-builder.service.js
similarity index 100%
rename from src/-deprecated/physical-layer/channel-receive/channel-receive-builder.service.js
rename to src/-still-es5/-deprecated/physical-layer/channel-receive/channel-receive-builder.service.js
diff --git a/src/-deprecated/physical-layer/channel-receive/channel-receive.factory.js b/src/-still-es5/-deprecated/physical-layer/channel-receive/channel-receive.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer/channel-receive/channel-receive.factory.js
rename to src/-still-es5/-deprecated/physical-layer/channel-receive/channel-receive.factory.js
diff --git a/src/-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager-builder.service.js b/src/-still-es5/-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager-builder.service.js
similarity index 100%
rename from src/-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager-builder.service.js
rename to src/-still-es5/-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager-builder.service.js
diff --git a/src/-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager.factory.js b/src/-still-es5/-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager.factory.js
rename to src/-still-es5/-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager.factory.js
diff --git a/src/-deprecated/physical-layer/channel-transmit/channel-transmit-builder.service.js b/src/-still-es5/-deprecated/physical-layer/channel-transmit/channel-transmit-builder.service.js
similarity index 100%
rename from src/-deprecated/physical-layer/channel-transmit/channel-transmit-builder.service.js
rename to src/-still-es5/-deprecated/physical-layer/channel-transmit/channel-transmit-builder.service.js
diff --git a/src/-deprecated/physical-layer/channel-transmit/channel-transmit.factory.js b/src/-still-es5/-deprecated/physical-layer/channel-transmit/channel-transmit.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer/channel-transmit/channel-transmit.factory.js
rename to src/-still-es5/-deprecated/physical-layer/channel-transmit/channel-transmit.factory.js
diff --git a/src/-deprecated/physical-layer/configuration-parser.service.js b/src/-still-es5/-deprecated/physical-layer/configuration-parser.service.js
similarity index 100%
rename from src/-deprecated/physical-layer/configuration-parser.service.js
rename to src/-still-es5/-deprecated/physical-layer/configuration-parser.service.js
diff --git a/src/-deprecated/physical-layer/default-config.service.js b/src/-still-es5/-deprecated/physical-layer/default-config.service.js
similarity index 100%
rename from src/-deprecated/physical-layer/default-config.service.js
rename to src/-still-es5/-deprecated/physical-layer/default-config.service.js
diff --git a/src/-deprecated/physical-layer/physical-layer.factory.js b/src/-still-es5/-deprecated/physical-layer/physical-layer.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer/physical-layer.factory.js
rename to src/-still-es5/-deprecated/physical-layer/physical-layer.factory.js
diff --git a/src/-deprecated/physical-layer/rx-handler/rx-handler-builder.service.js b/src/-still-es5/-deprecated/physical-layer/rx-handler/rx-handler-builder.service.js
similarity index 100%
rename from src/-deprecated/physical-layer/rx-handler/rx-handler-builder.service.js
rename to src/-still-es5/-deprecated/physical-layer/rx-handler/rx-handler-builder.service.js
diff --git a/src/-deprecated/physical-layer/rx-handler/rx-handler.factory.js b/src/-still-es5/-deprecated/physical-layer/rx-handler/rx-handler.factory.js
similarity index 100%
rename from src/-deprecated/physical-layer/rx-handler/rx-handler.factory.js
rename to src/-still-es5/-deprecated/physical-layer/rx-handler/rx-handler.factory.js
diff --git a/src/-deprecated/physical-layer/rx-input.service.js b/src/-still-es5/-deprecated/physical-layer/rx-input.service.js
similarity index 100%
rename from src/-deprecated/physical-layer/rx-input.service.js
rename to src/-still-es5/-deprecated/physical-layer/rx-input.service.js
diff --git a/src/-still-es5/audio-network-boot.js b/src/-still-es5/audio-network-boot.js
new file mode 100644
index 0000000..d01eb4c
--- /dev/null
+++ b/src/-still-es5/audio-network-boot.js
@@ -0,0 +1,48 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+'use strict';
+
+// TODO extract only important parts of this file - it will no longer be need when after introducing WebPack/TypeScript
+
+var
+ AudioNetwork = {}, // namespace visible to the global JavaScript scope
+ AudioNetworkBootConfig = AudioNetworkBootConfig || {}; // injects boot config
+
+AudioNetwork.version = '1.3.0';
+
+// conditions from: http://stackoverflow.com/a/33697246
+AudioNetwork.isNode = typeof module !== 'undefined' && module.exports ? true : false;
+AudioNetwork.isWebWorker = !AudioNetwork.isNode && typeof WorkerGlobalScope !== 'undefined' && typeof importScripts == 'function' && navigator instanceof WorkerNavigator;
+AudioNetwork.isBrowser = !AudioNetwork.isNode && !AudioNetwork.isWebWorker && typeof navigator !== 'undefined' && typeof document !== 'undefined';
+
+/*
+console.log(AudioNetwork.isNode);
+console.log(AudioNetwork.isWebWorker);
+console.log(AudioNetwork.isBrowser);
+*/
+
+AudioNetwork.MULTICORE_STATE = {
+ DISABLED: 'DISABLED',
+ ENABLED_USE_PROD_SCRIPT: 'ENABLED_USE_PROD_SCRIPT',
+ ENABLED_USE_DEV_SCRIPT: 'ENABLED_USE_DEV_SCRIPT'
+};
+
+AudioNetwork.bootConfig = {
+ devScriptBaseUrl: typeof AudioNetworkBootConfig.devScriptBaseUrl === 'string'
+ ? AudioNetworkBootConfig.devScriptBaseUrl
+ : (AudioNetwork.isBrowser ? window.location.origin + '/src/' : ''),
+ prodScriptBaseUrl: typeof AudioNetworkBootConfig.prodScriptBaseUrl === 'string'
+ ? AudioNetworkBootConfig.prodScriptBaseUrl
+ : (AudioNetwork.isBrowser ? window.location.origin + '/build/' : ''),
+ prodScriptName: typeof AudioNetworkBootConfig.prodScriptName === 'string'
+ ? AudioNetworkBootConfig.prodScriptName
+ : 'audio-network-v' + AudioNetwork.version + '.min.js',
+ devScriptLoad: typeof AudioNetworkBootConfig.devScriptLoad !== 'undefined'
+ ? !!AudioNetworkBootConfig.devScriptLoad
+ : false,
+ createAlias: typeof AudioNetworkBootConfig.createAlias !== 'undefined'
+ ? !!AudioNetworkBootConfig.createAlias
+ : true,
+ multicoreState: Object.keys(AudioNetwork.MULTICORE_STATE).indexOf(AudioNetworkBootConfig.multicoreState) !== -1
+ ? AudioNetworkBootConfig.multicoreState
+ : AudioNetwork.MULTICORE_STATE.DISABLED
+};
diff --git a/src/audio-network-end.js b/src/-still-es5/audio-network-end.js
similarity index 97%
rename from src/audio-network-end.js
rename to src/-still-es5/audio-network-end.js
index 73e03c1..9eb018b 100644
--- a/src/audio-network-end.js
+++ b/src/-still-es5/audio-network-end.js
@@ -1,6 +1,8 @@
// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
'use strict';
+// TODO extract only important parts of this file - it will no longer be need when after introducing WebPack/TypeScript
+
if (AudioNetwork.bootConfig.createAlias) {
AudioNetwork.Rewrite = {};
@@ -52,7 +54,3 @@ if (AudioNetwork.bootConfig.createAlias) {
AudioNetwork.Common.WindowFunction = AudioNetwork.Injector.resolve('Common.WindowFunction'); // probably deprecated
AudioNetwork.Common.Util = AudioNetwork.Injector.resolve('Common.Util'); // deprecated
}
-
-if (AudioNetwork.isNode) {
- module.exports = AudioNetwork;
-}
diff --git a/src/data-link-layer/checksum-service.js b/src/-still-es5/data-link-layer/checksum-service.js
similarity index 100%
rename from src/data-link-layer/checksum-service.js
rename to src/-still-es5/data-link-layer/checksum-service.js
diff --git a/src/data-link-layer/data-link-layer-builder.js b/src/-still-es5/data-link-layer/data-link-layer-builder.js
similarity index 100%
rename from src/data-link-layer/data-link-layer-builder.js
rename to src/-still-es5/data-link-layer/data-link-layer-builder.js
diff --git a/src/data-link-layer/data-link-layer.js b/src/-still-es5/data-link-layer/data-link-layer.js
similarity index 100%
rename from src/data-link-layer/data-link-layer.js
rename to src/-still-es5/data-link-layer/data-link-layer.js
diff --git a/src/data-link-layer/frame.js b/src/-still-es5/data-link-layer/frame.js
similarity index 100%
rename from src/data-link-layer/frame.js
rename to src/-still-es5/data-link-layer/frame.js
diff --git a/src/data-link-layer/tx-frame-manager.js b/src/-still-es5/data-link-layer/tx-frame-manager.js
similarity index 100%
rename from src/data-link-layer/tx-frame-manager.js
rename to src/-still-es5/data-link-layer/tx-frame-manager.js
diff --git a/src/data-link-layer/tx-frame.js b/src/-still-es5/data-link-layer/tx-frame.js
similarity index 100%
rename from src/data-link-layer/tx-frame.js
rename to src/-still-es5/data-link-layer/tx-frame.js
diff --git a/src/dsp/correlator.js b/src/-still-es5/dsp/correlator.js
similarity index 100%
rename from src/dsp/correlator.js
rename to src/-still-es5/dsp/correlator.js
diff --git a/src/dsp/fft-result.js b/src/-still-es5/dsp/fft-result.js
similarity index 100%
rename from src/dsp/fft-result.js
rename to src/-still-es5/dsp/fft-result.js
diff --git a/src/dsp/fft.test.js b/src/-still-es5/dsp/fft.test.js
similarity index 100%
rename from src/dsp/fft.test.js
rename to src/-still-es5/dsp/fft.test.js
diff --git a/src/dsp/wave-analyser.js b/src/-still-es5/dsp/wave-analyser.js
similarity index 100%
rename from src/dsp/wave-analyser.js
rename to src/-still-es5/dsp/wave-analyser.js
diff --git a/src/dsp/wave-generator.js b/src/-still-es5/dsp/wave-generator.js
similarity index 100%
rename from src/dsp/wave-generator.js
rename to src/-still-es5/dsp/wave-generator.js
diff --git a/src/physical-layer/physical-layer-builder.js b/src/-still-es5/physical-layer/physical-layer-builder.js
similarity index 100%
rename from src/physical-layer/physical-layer-builder.js
rename to src/-still-es5/physical-layer/physical-layer-builder.js
diff --git a/src/physical-layer/physical-layer.js b/src/-still-es5/physical-layer/physical-layer.js
similarity index 100%
rename from src/physical-layer/physical-layer.js
rename to src/-still-es5/physical-layer/physical-layer.js
diff --git a/src/physical-layer/rx-sync-detector.js b/src/-still-es5/physical-layer/rx-sync-detector.js
similarity index 100%
rename from src/physical-layer/rx-sync-detector.js
rename to src/-still-es5/physical-layer/rx-sync-detector.js
diff --git a/src/physical-layer/tx-symbol-manager.js b/src/-still-es5/physical-layer/tx-symbol-manager.js
similarity index 100%
rename from src/physical-layer/tx-symbol-manager.js
rename to src/-still-es5/physical-layer/tx-symbol-manager.js
diff --git a/src/physical-layer/tx-symbol.js b/src/-still-es5/physical-layer/tx-symbol.js
similarity index 100%
rename from src/physical-layer/tx-symbol.js
rename to src/-still-es5/physical-layer/tx-symbol.js
diff --git a/src/util/buffer.js b/src/-still-es5/util/buffer.js
similarity index 100%
rename from src/util/buffer.js
rename to src/-still-es5/util/buffer.js
diff --git a/src/util/frequency-calculator.js b/src/-still-es5/util/frequency-calculator.js
similarity index 100%
rename from src/util/frequency-calculator.js
rename to src/-still-es5/util/frequency-calculator.js
diff --git a/src/util/music-calculator.js b/src/-still-es5/util/music-calculator.js
similarity index 100%
rename from src/util/music-calculator.js
rename to src/-still-es5/util/music-calculator.js
diff --git a/src/util/smart-timer.js b/src/-still-es5/util/smart-timer.js
similarity index 100%
rename from src/util/smart-timer.js
rename to src/-still-es5/util/smart-timer.js
diff --git a/src/util/wav-audio-file.js b/src/-still-es5/util/wav-audio-file.js
similarity index 100%
rename from src/util/wav-audio-file.js
rename to src/-still-es5/util/wav-audio-file.js
diff --git a/src/visualizer/abstract-2d-visualizer/abstract-2d-visualizer.factory.js b/src/-still-es5/visualizer/abstract-2d-visualizer/abstract-2d-visualizer.factory.js
similarity index 100%
rename from src/visualizer/abstract-2d-visualizer/abstract-2d-visualizer.factory.js
rename to src/-still-es5/visualizer/abstract-2d-visualizer/abstract-2d-visualizer.factory.js
diff --git a/src/visualizer/abstract-visualizer/abstract-visualizer.factory.js b/src/-still-es5/visualizer/abstract-visualizer/abstract-visualizer.factory.js
similarity index 100%
rename from src/visualizer/abstract-visualizer/abstract-visualizer.factory.js
rename to src/-still-es5/visualizer/abstract-visualizer/abstract-visualizer.factory.js
diff --git a/src/visualizer/analyser-chart/analyser-chart-builder.service.js b/src/-still-es5/visualizer/analyser-chart/analyser-chart-builder.service.js
similarity index 100%
rename from src/visualizer/analyser-chart/analyser-chart-builder.service.js
rename to src/-still-es5/visualizer/analyser-chart/analyser-chart-builder.service.js
diff --git a/src/visualizer/analyser-chart/analyser-chart-template-axis-x.service.js b/src/-still-es5/visualizer/analyser-chart/analyser-chart-template-axis-x.service.js
similarity index 100%
rename from src/visualizer/analyser-chart/analyser-chart-template-axis-x.service.js
rename to src/-still-es5/visualizer/analyser-chart/analyser-chart-template-axis-x.service.js
diff --git a/src/visualizer/analyser-chart/analyser-chart-template-main.service.js b/src/-still-es5/visualizer/analyser-chart/analyser-chart-template-main.service.js
similarity index 100%
rename from src/visualizer/analyser-chart/analyser-chart-template-main.service.js
rename to src/-still-es5/visualizer/analyser-chart/analyser-chart-template-main.service.js
diff --git a/src/visualizer/analyser-chart/analyser-chart.factory.js b/src/-still-es5/visualizer/analyser-chart/analyser-chart.factory.js
similarity index 100%
rename from src/visualizer/analyser-chart/analyser-chart.factory.js
rename to src/-still-es5/visualizer/analyser-chart/analyser-chart.factory.js
diff --git a/src/visualizer/complex-plane-chart/complex-plane-chart-builder.service.js b/src/-still-es5/visualizer/complex-plane-chart/complex-plane-chart-builder.service.js
similarity index 100%
rename from src/visualizer/complex-plane-chart/complex-plane-chart-builder.service.js
rename to src/-still-es5/visualizer/complex-plane-chart/complex-plane-chart-builder.service.js
diff --git a/src/visualizer/complex-plane-chart/complex-plane-chart-template-main.service.js b/src/-still-es5/visualizer/complex-plane-chart/complex-plane-chart-template-main.service.js
similarity index 100%
rename from src/visualizer/complex-plane-chart/complex-plane-chart-template-main.service.js
rename to src/-still-es5/visualizer/complex-plane-chart/complex-plane-chart-template-main.service.js
diff --git a/src/visualizer/complex-plane-chart/complex-plane-chart.factory.js b/src/-still-es5/visualizer/complex-plane-chart/complex-plane-chart.factory.js
similarity index 100%
rename from src/visualizer/complex-plane-chart/complex-plane-chart.factory.js
rename to src/-still-es5/visualizer/complex-plane-chart/complex-plane-chart.factory.js
diff --git a/src/visualizer/constellation-diagram/constellation-diagram-builder.service.js b/src/-still-es5/visualizer/constellation-diagram/constellation-diagram-builder.service.js
similarity index 100%
rename from src/visualizer/constellation-diagram/constellation-diagram-builder.service.js
rename to src/-still-es5/visualizer/constellation-diagram/constellation-diagram-builder.service.js
diff --git a/src/visualizer/constellation-diagram/constellation-diagram-template-main.service.js b/src/-still-es5/visualizer/constellation-diagram/constellation-diagram-template-main.service.js
similarity index 100%
rename from src/visualizer/constellation-diagram/constellation-diagram-template-main.service.js
rename to src/-still-es5/visualizer/constellation-diagram/constellation-diagram-template-main.service.js
diff --git a/src/visualizer/constellation-diagram/constellation-diagram.factory.js b/src/-still-es5/visualizer/constellation-diagram/constellation-diagram.factory.js
similarity index 100%
rename from src/visualizer/constellation-diagram/constellation-diagram.factory.js
rename to src/-still-es5/visualizer/constellation-diagram/constellation-diagram.factory.js
diff --git a/src/visualizer/frequency-domain-chart/frequency-domain-chart-builder.service.js b/src/-still-es5/visualizer/frequency-domain-chart/frequency-domain-chart-builder.service.js
similarity index 100%
rename from src/visualizer/frequency-domain-chart/frequency-domain-chart-builder.service.js
rename to src/-still-es5/visualizer/frequency-domain-chart/frequency-domain-chart-builder.service.js
diff --git a/src/visualizer/frequency-domain-chart/frequency-domain-chart-template-main.service.js b/src/-still-es5/visualizer/frequency-domain-chart/frequency-domain-chart-template-main.service.js
similarity index 100%
rename from src/visualizer/frequency-domain-chart/frequency-domain-chart-template-main.service.js
rename to src/-still-es5/visualizer/frequency-domain-chart/frequency-domain-chart-template-main.service.js
diff --git a/src/visualizer/frequency-domain-chart/frequency-domain-chart.factory.js b/src/-still-es5/visualizer/frequency-domain-chart/frequency-domain-chart.factory.js
similarity index 100%
rename from src/visualizer/frequency-domain-chart/frequency-domain-chart.factory.js
rename to src/-still-es5/visualizer/frequency-domain-chart/frequency-domain-chart.factory.js
diff --git a/src/visualizer/power-chart/power-chart-builder.service.js b/src/-still-es5/visualizer/power-chart/power-chart-builder.service.js
similarity index 100%
rename from src/visualizer/power-chart/power-chart-builder.service.js
rename to src/-still-es5/visualizer/power-chart/power-chart-builder.service.js
diff --git a/src/visualizer/power-chart/power-chart-template-main.service.js b/src/-still-es5/visualizer/power-chart/power-chart-template-main.service.js
similarity index 100%
rename from src/visualizer/power-chart/power-chart-template-main.service.js
rename to src/-still-es5/visualizer/power-chart/power-chart-template-main.service.js
diff --git a/src/visualizer/power-chart/power-chart.factory.js b/src/-still-es5/visualizer/power-chart/power-chart.factory.js
similarity index 100%
rename from src/visualizer/power-chart/power-chart.factory.js
rename to src/-still-es5/visualizer/power-chart/power-chart.factory.js
diff --git a/src/visualizer/sample-chart/sample-chart-builder.service.js b/src/-still-es5/visualizer/sample-chart/sample-chart-builder.service.js
similarity index 100%
rename from src/visualizer/sample-chart/sample-chart-builder.service.js
rename to src/-still-es5/visualizer/sample-chart/sample-chart-builder.service.js
diff --git a/src/visualizer/sample-chart/sample-chart-template-main.service.js b/src/-still-es5/visualizer/sample-chart/sample-chart-template-main.service.js
similarity index 100%
rename from src/visualizer/sample-chart/sample-chart-template-main.service.js
rename to src/-still-es5/visualizer/sample-chart/sample-chart-template-main.service.js
diff --git a/src/visualizer/sample-chart/sample-chart.factory.js b/src/-still-es5/visualizer/sample-chart/sample-chart.factory.js
similarity index 100%
rename from src/visualizer/sample-chart/sample-chart.factory.js
rename to src/-still-es5/visualizer/sample-chart/sample-chart.factory.js
diff --git a/src/web-audio/audio-mono-io-lite.js b/src/-still-es5/web-audio/audio-mono-io-lite.js
similarity index 100%
rename from src/web-audio/audio-mono-io-lite.js
rename to src/-still-es5/web-audio/audio-mono-io-lite.js
diff --git a/src/web-audio/audio-mono-io.js b/src/-still-es5/web-audio/audio-mono-io.js
similarity index 100%
rename from src/web-audio/audio-mono-io.js
rename to src/-still-es5/web-audio/audio-mono-io.js
diff --git a/src/audio-network-boot.js b/src/audio-network-boot.js
deleted file mode 100644
index a059d33..0000000
--- a/src/audio-network-boot.js
+++ /dev/null
@@ -1,320 +0,0 @@
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-var
- AudioNetwork = {}, // namespace visible to the global JavaScript scope
- AudioNetworkBootConfig = AudioNetworkBootConfig || {}; // injects boot config
-
-AudioNetwork.version = '1.3.0';
-
-// conditions from: http://stackoverflow.com/a/33697246
-AudioNetwork.isNode = typeof module !== 'undefined' && module.exports ? true : false;
-AudioNetwork.isWebWorker = !AudioNetwork.isNode && typeof WorkerGlobalScope !== 'undefined' && typeof importScripts == 'function' && navigator instanceof WorkerNavigator;
-AudioNetwork.isBrowser = !AudioNetwork.isNode && !AudioNetwork.isWebWorker && typeof navigator !== 'undefined' && typeof document !== 'undefined';
-
-/*
-console.log(AudioNetwork.isNode);
-console.log(AudioNetwork.isWebWorker);
-console.log(AudioNetwork.isBrowser);
-*/
-
-AudioNetwork.MULTICORE_STATE = {
- DISABLED: 'DISABLED',
- ENABLED_USE_PROD_SCRIPT: 'ENABLED_USE_PROD_SCRIPT',
- ENABLED_USE_DEV_SCRIPT: 'ENABLED_USE_DEV_SCRIPT'
-};
-
-AudioNetwork.bootConfig = {
- devScriptBaseUrl: typeof AudioNetworkBootConfig.devScriptBaseUrl === 'string'
- ? AudioNetworkBootConfig.devScriptBaseUrl
- : (AudioNetwork.isBrowser ? window.location.origin + '/src/' : ''),
- prodScriptBaseUrl: typeof AudioNetworkBootConfig.prodScriptBaseUrl === 'string'
- ? AudioNetworkBootConfig.prodScriptBaseUrl
- : (AudioNetwork.isBrowser ? window.location.origin + '/build/' : ''),
- prodScriptName: typeof AudioNetworkBootConfig.prodScriptName === 'string'
- ? AudioNetworkBootConfig.prodScriptName
- : 'audio-network-v' + AudioNetwork.version + '.min.js',
- devScriptLoad: typeof AudioNetworkBootConfig.devScriptLoad !== 'undefined'
- ? !!AudioNetworkBootConfig.devScriptLoad
- : false,
- createAlias: typeof AudioNetworkBootConfig.createAlias !== 'undefined'
- ? !!AudioNetworkBootConfig.createAlias
- : true,
- multicoreState: Object.keys(AudioNetwork.MULTICORE_STATE).indexOf(AudioNetworkBootConfig.multicoreState) !== -1
- ? AudioNetworkBootConfig.multicoreState
- : AudioNetwork.MULTICORE_STATE.DISABLED
-};
-
-AudioNetwork.Injector = (function () {
- var Injector;
-
- Injector = function () {
- this.$$injectRepository = {};
- };
-
- Injector.RESOLVE_RECURSION_LIMIT = 20;
- Injector.RESOLVE_RECURSION_LIMIT_EXCEED_EXCEPTION = 'Injector - resolve recursion limit exceed';
- Injector.MULTIPLE_REGISTER_EXCEPTION = 'Injector - multiple register calls for the same name';
- Injector.UNABLE_TO_FIND_ITEM_EXCEPTION = 'Injector - unable to find factory/service for given name: ';
- Injector.TYPE = {
- SERVICE: 'SERVICE',
- FACTORY: 'FACTORY'
- };
-
- Injector.$$resolveRecursionCounter = 0;
-
- Injector.prototype.$$register = function (name, item, type) {
- if (typeof this.$$injectRepository[name] === 'undefined') {
- this.$$injectRepository[name] = {
- type: type,
- item: item,
- resolveCache: null
- };
- } else {
- throw Injector.MULTIPLE_REGISTER_EXCEPTION;
- }
- };
-
- Injector.prototype.registerService = function (name, service) {
- this.$$register(name, service, Injector.TYPE.SERVICE);
- };
-
- Injector.prototype.registerFactory = function (name, factory) {
- this.$$register(name, factory, Injector.TYPE.FACTORY);
- };
-
- Injector.prototype.resolve = function (name) {
- var i, findResult, injectList = [];
-
- findResult = this.$$find(name);
- if (findResult.resolveCache) {
- return findResult.resolveCache;
- }
-
- this.$$resolveRecursionInc();
- for (i = 0; i < findResult.item.$inject.length; i++) {
- injectList.push(
- this.resolve(findResult.item.$inject[i])
- );
- }
- switch (findResult.type) {
- case Injector.TYPE.SERVICE:
- findResult.resolveCache = this.$$injectDependenciesAndInstantiate(findResult, injectList);
- break;
- case Injector.TYPE.FACTORY:
- findResult.resolveCache = this.$$injectDependencies(findResult, injectList);
- break;
- }
- this.$$resolveRecursionDec();
-
- return findResult.resolveCache;
- };
-
- Injector.prototype.$$resolveRecursionInc = function () {
- Injector.$$resolveRecursionCounter++;
- if (Injector.$$resolveRecursionCounter >= Injector.RESOLVE_RECURSION_LIMIT) {
- throw Injector.RESOLVE_RECURSION_LIMIT_EXCEED_EXCEPTION;
- }
- };
-
- Injector.prototype.$$resolveRecursionDec = function () {
- Injector.$$resolveRecursionCounter--;
- };
-
- Injector.prototype.$$injectDependenciesAndInstantiate = function (findResult, injectList) {
- var
- f = findResult,
- i = injectList,
- r
- ;
-
- switch (injectList.length) {
- case 0: r = new f.item(); break;
- case 1: r = new f.item(i[0]); break;
- case 2: r = new f.item(i[0], i[1]); break;
- case 3: r = new f.item(i[0], i[1], i[2]); break;
- case 4: r = new f.item(i[0], i[1], i[2], i[3]); break;
- case 5: r = new f.item(i[0], i[1], i[2], i[3], i[4]); break;
- case 6: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5]); break;
- case 7: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6]); break;
- case 8: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]); break;
- case 9: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]); break;
- case 10: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9]); break;
- case 11: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9], i[10]); break;
- case 12: r = new f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9], i[10], i[11]); break;
- }
-
- return r;
- };
-
- Injector.prototype.$$injectDependencies = function (findResult, injectList) {
- var
- f = findResult,
- i = injectList,
- r
- ;
-
- switch (injectList.length) {
- case 0: r = f.item(); break;
- case 1: r = f.item(i[0]); break;
- case 2: r = f.item(i[0], i[1]); break;
- case 3: r = f.item(i[0], i[1], i[2]); break;
- case 4: r = f.item(i[0], i[1], i[2], i[3]); break;
- case 5: r = f.item(i[0], i[1], i[2], i[3], i[4]); break;
- case 6: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5]); break;
- case 7: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6]); break;
- case 8: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]); break;
- case 9: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]); break;
- case 10: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9]); break;
- case 11: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9], i[10]); break;
- case 12: r = f.item(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8], i[9], i[10], i[11]); break;
- }
-
- return r;
- };
-
- Injector.prototype.$$find = function (name) {
- var key;
-
- for (key in this.$$injectRepository) {
- if (this.$$injectRepository.hasOwnProperty(key) && key === name) {
- return this.$$injectRepository[key];
- }
- }
- throw Injector.UNABLE_TO_FIND_ITEM_EXCEPTION + name;
- };
-
- return new Injector(); // instantiate service
-})();
-
-AudioNetwork.DynamicScriptLoader = (function () {
- var DynamicScriptLoader;
-
- DynamicScriptLoader = function () {
- };
-
- DynamicScriptLoader.prototype.loadList = function (urlList, startingIndex) {
- var i;
-
- if (typeof startingIndex === 'undefined') {
- startingIndex = 0;
- }
-
- for (i = startingIndex; i < urlList.length; i++) {
- this.loadOne(urlList[i]);
- }
- };
-
- DynamicScriptLoader.prototype.loadOne = function (url) {
- document.write('')
- };
-
- return new DynamicScriptLoader(); // instantiate service
-})();
-
-AudioNetwork.devScriptList = [
- 'audio-network-boot.js',
- '-deprecated-probably/common/math-util/math-util.service.js',
- '-deprecated-probably/common/simple-promise/simple-promise-builder.service.js',
- '-deprecated-probably/common/simple-promise/simple-promise.factory.js',
- '-deprecated-probably/common/stopwatch/stopwatch-builder.service.js',
- '-deprecated-probably/common/stopwatch/stopwatch.factory.js',
- '-deprecated-probably/common/window-function/window-function.service.js',
- '-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker-thread.service.js',
- '-deprecated-probably/physical-layer-core/receive-multicore-worker/receive-multicore-worker.factory.js',
- '-deprecated-probably/physical-layer-core/receive-worker/receive-worker.factory.js',
- '-deprecated/audio/active-audio-context/active-audio-context.service.js',
- '-deprecated/audio/simple-audio-context/simple-audio-context-builder.service.js',
- '-deprecated/audio/simple-audio-context/simple-audio-context.factory.js',
- '-deprecated/common/abstract-value-collector/abstract-value-collector.factory.js',
- '-deprecated/common/average-value-collector/average-value-collector-builder.service.js',
- '-deprecated/common/average-value-collector/average-value-collector.factory.js',
- '-deprecated/common/carrier-generate/carrier-generate-builder.service.js',
- '-deprecated/common/carrier-generate/carrier-generate.factory.js',
- '-deprecated/common/carrier-recovery/carrier-recovery-builder.service.js',
- '-deprecated/common/carrier-recovery/carrier-recovery.factory.js',
- '-deprecated/common/complex/complex-builder.service.js',
- '-deprecated/common/complex/complex.factory.js',
- '-deprecated/common/queue/queue-builder.service.js',
- '-deprecated/common/queue/queue.factory.js',
- '-deprecated/common/util/util.service.js',
- '-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector-builder.service.js',
- '-deprecated/physical-layer-adapter/guard-power-collector/guard-power-collector.factory.js',
- '-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector-builder.service.js',
- '-deprecated/physical-layer-adapter/phase-offset-collector/phase-offset-collector.factory.js',
- '-deprecated/physical-layer-adapter/receive-adapter-state.service.js',
- '-deprecated/physical-layer-adapter/receive-adapter.factory.js',
- '-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager-builder.service.js',
- '-deprecated/physical-layer-adapter/rx-state-machine-manager/rx-state-machine-manager.factory.js',
- '-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine-builder.service.js',
- '-deprecated/physical-layer-adapter/rx-state-machine/rx-state-machine.factory.js',
- '-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector-builder.service.js',
- '-deprecated/physical-layer-adapter/signal-power-collector/signal-power-collector.factory.js',
- '-deprecated/physical-layer-adapter/transmit-adapter.factory.js',
- '-deprecated/physical-layer/abstract-channel-manager/abstract-channel-manager.factory.js',
- '-deprecated/physical-layer/channel-receive-manager/channel-receive-manager-builder.service.js',
- '-deprecated/physical-layer/channel-receive-manager/channel-receive-manager.factory.js',
- '-deprecated/physical-layer/channel-receive/channel-receive-builder.service.js',
- '-deprecated/physical-layer/channel-receive/channel-receive.factory.js',
- '-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager-builder.service.js',
- '-deprecated/physical-layer/channel-transmit-manager/channel-transmit-manager.factory.js',
- '-deprecated/physical-layer/channel-transmit/channel-transmit-builder.service.js',
- '-deprecated/physical-layer/channel-transmit/channel-transmit.factory.js',
- '-deprecated/physical-layer/configuration-parser.service.js',
- '-deprecated/physical-layer/default-config.service.js',
- '-deprecated/physical-layer/physical-layer.factory.js',
- '-deprecated/physical-layer/rx-handler/rx-handler-builder.service.js',
- '-deprecated/physical-layer/rx-handler/rx-handler.factory.js',
- '-deprecated/physical-layer/rx-input.service.js',
- 'data-link-layer/checksum-service.js',
- 'data-link-layer/data-link-layer-builder.js',
- 'data-link-layer/data-link-layer.js',
- 'data-link-layer/frame.js',
- 'data-link-layer/tx-frame-manager.js',
- 'data-link-layer/tx-frame.js',
- 'dsp/complex.js',
- 'dsp/correlator.js',
- 'dsp/fft-result.js',
- 'dsp/fft.js',
- 'dsp/wave-analyser.js',
- 'dsp/wave-generator.js',
- 'physical-layer/physical-layer-builder.js',
- 'physical-layer/physical-layer.js',
- 'physical-layer/rx-sync-detector.js',
- 'physical-layer/tx-symbol-manager.js',
- 'physical-layer/tx-symbol.js',
- 'util/buffer.js',
- 'util/frequency-calculator.js',
- 'util/music-calculator.js',
- 'util/smart-timer.js',
- 'util/wav-audio-file.js',
- 'visualizer/abstract-2d-visualizer/abstract-2d-visualizer.factory.js',
- 'visualizer/abstract-visualizer/abstract-visualizer.factory.js',
- 'visualizer/analyser-chart/analyser-chart-builder.service.js',
- 'visualizer/analyser-chart/analyser-chart-template-axis-x.service.js',
- 'visualizer/analyser-chart/analyser-chart-template-main.service.js',
- 'visualizer/analyser-chart/analyser-chart.factory.js',
- 'visualizer/complex-plane-chart/complex-plane-chart-builder.service.js',
- 'visualizer/complex-plane-chart/complex-plane-chart-template-main.service.js',
- 'visualizer/complex-plane-chart/complex-plane-chart.factory.js',
- 'visualizer/constellation-diagram/constellation-diagram-builder.service.js',
- 'visualizer/constellation-diagram/constellation-diagram-template-main.service.js',
- 'visualizer/constellation-diagram/constellation-diagram.factory.js',
- 'visualizer/frequency-domain-chart/frequency-domain-chart-builder.service.js',
- 'visualizer/frequency-domain-chart/frequency-domain-chart-template-main.service.js',
- 'visualizer/frequency-domain-chart/frequency-domain-chart.factory.js',
- 'visualizer/power-chart/power-chart-builder.service.js',
- 'visualizer/power-chart/power-chart-template-main.service.js',
- 'visualizer/power-chart/power-chart.factory.js',
- 'visualizer/sample-chart/sample-chart-builder.service.js',
- 'visualizer/sample-chart/sample-chart-template-main.service.js',
- 'visualizer/sample-chart/sample-chart.factory.js',
- 'web-audio/audio-mono-io-lite.js',
- 'web-audio/audio-mono-io.js',
- 'audio-network-end.js'
-];
-
-if (AudioNetwork.isBrowser && AudioNetwork.bootConfig.devScriptLoad) {
- // start from index 1 because audio-network-boot.js was already loaded
- AudioNetwork.DynamicScriptLoader.loadList(AudioNetwork.devScriptList, 1);
-}
diff --git a/src/common/common-module.ts b/src/common/common-module.ts
new file mode 100644
index 0000000..954e8d3
--- /dev/null
+++ b/src/common/common-module.ts
@@ -0,0 +1,17 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { SIMPLE_MATH } from './simple-math/di-token';
+import { ISimpleMath } from './simple-math/simple-math.interface';
+
+class CommonModule {
+ public static $inject: string[] = [
+ SIMPLE_MATH
+ ];
+
+ constructor(
+ public simpleMath: ISimpleMath
+ ) {
+ }
+}
+
+export default CommonModule;
diff --git a/src/common/di-token.ts b/src/common/di-token.ts
new file mode 100644
index 0000000..0a86c8a
--- /dev/null
+++ b/src/common/di-token.ts
@@ -0,0 +1,3 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+export const COMMON_MODULE = 'COMMON_MODULE';
diff --git a/src/common/simple-math/di-token.ts b/src/common/simple-math/di-token.ts
new file mode 100644
index 0000000..85f9f9c
--- /dev/null
+++ b/src/common/simple-math/di-token.ts
@@ -0,0 +1,3 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+export const SIMPLE_MATH = 'SIMPLE_MATH';
diff --git a/src/common/simple-math/simple-math.interface.ts b/src/common/simple-math/simple-math.interface.ts
new file mode 100644
index 0000000..67ebc73
--- /dev/null
+++ b/src/common/simple-math/simple-math.interface.ts
@@ -0,0 +1,20 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+interface ISimpleMath {
+ getPi(): number;
+ sin(x: number): number;
+ cos(x: number): number;
+ asin(x: number): number;
+ pow(x: number, exponent: number): number;
+ sqrt(x: number): number;
+ random(): number;
+}
+
+interface ISimpleMathStatic {
+ new(): ISimpleMath;
+}
+
+export {
+ ISimpleMath,
+ ISimpleMathStatic
+};
diff --git a/src/common/simple-math/simple-math.ts b/src/common/simple-math/simple-math.ts
new file mode 100644
index 0000000..4590c67
--- /dev/null
+++ b/src/common/simple-math/simple-math.ts
@@ -0,0 +1,38 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { staticImplements } from 'rr-tsdi';
+
+import { ISimpleMath, ISimpleMathStatic } from './simple-math.interface';
+
+@staticImplements()
+class SimpleMath implements ISimpleMath {
+ public getPi(): number {
+ return Math.PI;
+ }
+
+ public sin(x: number): number {
+ return Math.sin(x);
+ }
+
+ public cos(x: number): number {
+ return Math.cos(x);
+ }
+
+ public asin(x: number): number {
+ return Math.asin(x);
+ }
+
+ public pow(x: number, exponent: number): number {
+ return Math.pow(x, exponent);
+ }
+
+ public sqrt(x: number): number {
+ return Math.sqrt(x);
+ }
+
+ public random(): number {
+ return Math.random();
+ }
+}
+
+export default SimpleMath;
diff --git a/src/di.ts b/src/di.ts
new file mode 100644
index 0000000..7086653
--- /dev/null
+++ b/src/di.ts
@@ -0,0 +1,25 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { Injector } from 'rr-tsdi';
+
+import CommonModule from './common/common-module';
+import { COMMON_MODULE } from './common/di-token';
+import { SIMPLE_MATH } from './common/simple-math/di-token';
+import SimpleMath from './common/simple-math/simple-math';
+import ComplexFactory from './dsp/complex/complex-factory';
+import { COMPLEX_FACTORY } from './dsp/complex/di-token';
+import { DSP_MODULE } from './dsp/di-token';
+import DspModule from './dsp/dsp-module';
+import { FFT } from './dsp/fft/di-token';
+import Fft from './dsp/fft/fft';
+
+const injector = new Injector();
+
+injector.registerService(SIMPLE_MATH, SimpleMath);
+injector.registerService(COMMON_MODULE, CommonModule);
+
+injector.registerService(COMPLEX_FACTORY, ComplexFactory);
+injector.registerService(FFT, Fft);
+injector.registerService(DSP_MODULE, DspModule);
+
+export default injector;
diff --git a/src/dsp/complex.js b/src/dsp/complex.js
deleted file mode 100644
index a74a52d..0000000
--- a/src/dsp/complex.js
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.Dsp.Complex', Complex);
-
- Complex.$inject = [];
-
- function Complex() {
- var Complex;
-
- Complex = function (real, imag) {
- this.$$real = real;
- this.$$imag = imag;
- };
-
- Complex.$$_EPSILON = 0.000001;
- Complex.$$_UNIT_RADIUS = 1;
-
- Complex.prototype.clone = function () {
- return new Complex(
- this.$$real,
- this.$$imag
- );
- };
-
- Complex.polar = function (unitAngle, magnitude) {
- var radian;
-
- magnitude = typeof magnitude === 'undefined'
- ? Complex.$$_UNIT_RADIUS
- : magnitude;
-
- radian = 2 * Math.PI * unitAngle;
-
- return new Complex(
- magnitude * Math.cos(radian),
- magnitude * Math.sin(radian)
- );
- };
-
- Complex.zero = function () {
- return new Complex(0, 0);
- };
-
- Complex.prototype.swap = function () {
- var tmp = this.$$real;
-
- this.$$real = this.$$imag;
- this.$$imag = tmp;
-
- return this;
- };
-
- Complex.prototype.add = function (b) {
- this.$$real += b.$$real;
- this.$$imag += b.$$imag;
-
- return this;
- };
-
- Complex.prototype.subtract = function (b) {
- this.$$real -= b.$$real;
- this.$$imag -= b.$$imag;
-
- return this;
- };
-
- Complex.prototype.multiply = function (b) {
- var
- real = this.$$real * b.$$real - this.$$imag * b.$$imag,
- imag = this.$$real * b.$$imag + this.$$imag * b.$$real;
-
- this.$$real = real;
- this.$$imag = imag;
-
- return this;
- };
-
- Complex.prototype.conjugate = function () {
- this.$$imag *= -1;
-
- return this;
- };
-
- Complex.prototype.multiplyScalar = function (b) {
- this.$$real *= b;
- this.$$imag *= b;
-
- return this;
- };
-
- Complex.prototype.divideScalar = function (b) {
- this.$$real /= b;
- this.$$imag /= b;
-
- return this;
- };
-
- Complex.prototype.getReal = function () {
- return this.$$real;
- };
-
- Complex.prototype.getImaginary = function () {
- return this.$$imag;
- };
-
- Complex.prototype.getMagnitude = function () {
- return Math.sqrt(
- this.$$real * this.$$real +
- this.$$imag * this.$$imag
- );
- };
-
- Complex.prototype.getUnitAngle = function () {
- var x, y, magnitude, quarter, angle, unitAngle;
-
- x = this.$$real;
- y = this.$$imag;
- magnitude = this.getMagnitude();
- magnitude = magnitude < Complex.$$_EPSILON // prevents from dividing by zero
- ? Complex.$$_EPSILON
- : magnitude;
-
- // ^ Legend:
- // II * I '!' = 0 degrees
- // | '*' = 90 degrees
- // ----@--+--!----> '@' = 180 degrees
- // | '%' = 270 degrees
- // III % IV
-
- quarter = (y >= 0)
- ? (x >= 0 ? 1 : 2)
- : (x <= 0 ? 3 : 4);
-
- switch (quarter) {
- case 1:
- angle = Math.asin(y / magnitude);
- break;
- case 2:
- angle = Math.asin(-x / magnitude) + 0.5 * Math.PI;
- break;
- case 3:
- angle = Math.asin(-y / magnitude) + Math.PI;
- break;
- case 4:
- angle = Math.asin(x / magnitude) + 1.5 * Math.PI;
- break;
- }
-
- unitAngle = angle / (2 * Math.PI);
-
- return unitAngle;
- };
-
- Complex.prototype.normalize = function () {
- this.divideScalar(
- this.getMagnitude()
- );
-
- return this;
- };
-
- return Complex;
- }
-
-})();
diff --git a/src/dsp/complex/complex-factory.interface.ts b/src/dsp/complex/complex-factory.interface.ts
new file mode 100644
index 0000000..bc0cb71
--- /dev/null
+++ b/src/dsp/complex/complex-factory.interface.ts
@@ -0,0 +1,18 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { ISimpleMath } from '../../common/simple-math/simple-math.interface';
+import { IComplex } from './complex.interface';
+
+interface IComplexFactory {
+ create(real?: number, imaginary?: number): IComplex;
+ createPolar(unitAngle?: number, magnitude?: number): IComplex;
+}
+
+interface IComplexFactoryStatic {
+ new(simpleMath: ISimpleMath): IComplexFactory;
+}
+
+export {
+ IComplexFactory,
+ IComplexFactoryStatic
+};
diff --git a/src/dsp/complex/complex-factory.spec.ts b/src/dsp/complex/complex-factory.spec.ts
new file mode 100644
index 0000000..2d0ff00
--- /dev/null
+++ b/src/dsp/complex/complex-factory.spec.ts
@@ -0,0 +1,55 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { Injector } from 'rr-tsdi';
+
+import { SIMPLE_MATH } from '../../common/simple-math/di-token';
+import SimpleMath from '../../common/simple-math/simple-math';
+import Complex from './complex';
+import ComplexFactory from './complex-factory';
+
+import { COMPLEX_FACTORY } from './di-token';
+
+describe('ComplexFactory', () => {
+ const NUMBER_OF_DIGITS = 6;
+ let complexFactory: ComplexFactory;
+
+ beforeEach(() => {
+ const injector = new Injector();
+
+ injector.registerService(SIMPLE_MATH, SimpleMath);
+ injector.registerService(COMPLEX_FACTORY, ComplexFactory);
+ complexFactory = injector.get(COMPLEX_FACTORY);
+ });
+
+ it('should create proper instance', () => {
+ expect(complexFactory).toBeInstanceOf(ComplexFactory);
+ });
+
+ it('should create instance of Complex class with default parameters', () => {
+ const complex: Complex = complexFactory.create();
+
+ expect(complex).toBeInstanceOf(Complex);
+ expect(complex.getReal()).toBe(0);
+ expect(complex.getImaginary()).toBe(0);
+ });
+
+ it('should create instance of Complex class basing on real/imaginary parameters', () => {
+ const REAL = 12;
+ const IMAGINARY = -32;
+ const complex: Complex = complexFactory.create(REAL, IMAGINARY);
+
+ expect(complex).toBeInstanceOf(Complex);
+ expect(complex.getReal()).toBe(REAL);
+ expect(complex.getImaginary()).toBe(IMAGINARY);
+ });
+
+ it('should create instance of Complex class basing on polar parameters', () => {
+ let complex: Complex;
+
+ complex = complexFactory.createPolar(0.125, 2);
+ expect(complex).toBeInstanceOf(Complex);
+ expect(complex.getReal()).toBeCloseTo(1.414214, NUMBER_OF_DIGITS);
+ expect(complex.getImaginary()).toBeCloseTo(1.414214, NUMBER_OF_DIGITS);
+ });
+
+});
diff --git a/src/dsp/complex/complex-factory.ts b/src/dsp/complex/complex-factory.ts
new file mode 100644
index 0000000..4802ef3
--- /dev/null
+++ b/src/dsp/complex/complex-factory.ts
@@ -0,0 +1,35 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { staticImplements } from 'rr-tsdi';
+
+import { SIMPLE_MATH } from '../../common/simple-math/di-token';
+import { ISimpleMath } from './../../common/simple-math/simple-math.interface';
+import Complex from './complex';
+import { IComplexFactory, IComplexFactoryStatic } from './complex-factory.interface';
+
+@staticImplements()
+class ComplexFactory implements IComplexFactory {
+ public static $inject: string[] = [
+ SIMPLE_MATH
+ ];
+
+ constructor(
+ private simpleMath: ISimpleMath
+ ) {
+ }
+
+ public create(real: number = 0, imaginary: number = 0): Complex {
+ return new Complex(this.simpleMath, real, imaginary);
+ }
+
+ public createPolar(unitAngle: number = 0, magnitude: number = 1): Complex {
+ const radian: number = 2 * this.simpleMath.getPi() * unitAngle;
+
+ return this.create(
+ magnitude * this.simpleMath.cos(radian),
+ magnitude * this.simpleMath.sin(radian)
+ );
+ }
+}
+
+export default ComplexFactory;
diff --git a/src/dsp/complex/complex.interface.ts b/src/dsp/complex/complex.interface.ts
new file mode 100644
index 0000000..e396cc4
--- /dev/null
+++ b/src/dsp/complex/complex.interface.ts
@@ -0,0 +1,28 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { ISimpleMath } from './../../common/simple-math/simple-math.interface';
+
+interface IComplex {
+ clone(): IComplex;
+ swap(): IComplex;
+ add(x: IComplex): IComplex;
+ subtract(x: IComplex): IComplex;
+ multiply(x: IComplex): IComplex;
+ conjugate(): IComplex;
+ multiplyScalar(x: number): IComplex;
+ divideScalar(x: number): IComplex;
+ getReal(): number;
+ getImaginary(): number;
+ getMagnitude(): number;
+ getUnitAngle(): number;
+ normalize(): IComplex;
+}
+
+interface IComplexStatic {
+ new(simpleMath: ISimpleMath, real: number, imaginary: number): IComplex;
+}
+
+export {
+ IComplex,
+ IComplexStatic
+};
diff --git a/src/dsp/complex/complex.spec.ts b/src/dsp/complex/complex.spec.ts
new file mode 100644
index 0000000..01557a2
--- /dev/null
+++ b/src/dsp/complex/complex.spec.ts
@@ -0,0 +1,157 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import SimpleMath from './../../common/simple-math/simple-math';
+import Complex from './complex';
+
+describe('Complex', () => {
+ const NUMBER_OF_DIGITS = 6;
+ const REAL = 5;
+ const IMAGINARY = -9;
+ const REAL_NORMALIZED = 0.485643;
+ const IMAGINARY_NORMALIZED = -0.874157;
+ const EXPCTED_MAGNITUDE = 10.295630;
+ let simpleMath: SimpleMath;
+ let complex: Complex;
+
+ beforeEach(() => {
+ simpleMath = new SimpleMath();
+ complex = new Complex(simpleMath, REAL, IMAGINARY);
+ });
+
+ it('should create proper instance', () => {
+ expect(complex).toBeInstanceOf(Complex);
+ });
+
+ it('should properly clone', () => {
+ const complexCopy: Complex = complex.clone();
+
+ expect(complex).not.toBe(complexCopy);
+ expect(complex.getReal()).toBe(complexCopy.getReal());
+ expect(complex.getImaginary()).toBe(complexCopy.getImaginary());
+ });
+
+ it('should swap the real and imaginary components and return the same instance', () => {
+ const realPrevious: number = complex.getReal();
+ const imaginaryPrevious: number = complex.getImaginary();
+ const complexSwaped: Complex = complex.swap();
+
+ expect(complexSwaped.getReal()).toBe(imaginaryPrevious);
+ expect(complexSwaped.getImaginary()).toBe(realPrevious);
+ expect(complex).toBe(complexSwaped);
+ });
+
+ it('should properly add two complex numers and return the same instance', () => {
+ const REAL_TO_ADD: number = 32;
+ const IMAGINARY_TO_ADD: number = -3;
+ const complexB: Complex = new Complex(simpleMath, REAL_TO_ADD, IMAGINARY_TO_ADD);
+ const complexSummed: Complex = complex.add(complexB);
+
+ expect(complexSummed.getReal()).toBeCloseTo(REAL + REAL_TO_ADD, NUMBER_OF_DIGITS);
+ expect(complexSummed.getImaginary()).toBeCloseTo(IMAGINARY + IMAGINARY_TO_ADD, NUMBER_OF_DIGITS);
+ expect(complexSummed).toBe(complex);
+ });
+
+ it('should properly subtract two complex numers and return the same instance', () => {
+ const REAL_TO_SUBTRACT: number = 32;
+ const IMAGINARY_TO_SUBTRACT: number = -3;
+ const complexB: Complex = new Complex(simpleMath, REAL_TO_SUBTRACT, IMAGINARY_TO_SUBTRACT);
+ const complexSubtracted: Complex = complex.subtract(complexB);
+
+ expect(complexSubtracted.getReal()).toBeCloseTo(REAL - REAL_TO_SUBTRACT, NUMBER_OF_DIGITS);
+ expect(complexSubtracted.getImaginary()).toBeCloseTo(IMAGINARY - IMAGINARY_TO_SUBTRACT, NUMBER_OF_DIGITS);
+ expect(complexSubtracted).toBe(complex);
+ });
+
+ it('should properly multiply two complex numers and return the same instance', () => {
+ const REAL_TO_MULTIPLY: number = 32;
+ const IMAGINARY_TO_MULTIPLY: number = -3;
+ const complexB: Complex = new Complex(simpleMath, REAL_TO_MULTIPLY, IMAGINARY_TO_MULTIPLY);
+ const complexMultiplied: Complex = complex.multiply(complexB);
+ const REAL_EXPECTATION = REAL * REAL_TO_MULTIPLY - IMAGINARY * IMAGINARY_TO_MULTIPLY;
+ const IMAGINARY_EXPECTATION = REAL * IMAGINARY_TO_MULTIPLY + IMAGINARY * REAL_TO_MULTIPLY;
+
+ expect(complexMultiplied.getReal()).toBeCloseTo(REAL_EXPECTATION, NUMBER_OF_DIGITS);
+ expect(complexMultiplied.getImaginary()).toBeCloseTo(IMAGINARY_EXPECTATION, NUMBER_OF_DIGITS);
+ expect(complexMultiplied).toBe(complex);
+ });
+
+ it('should change the sign of imaginary component (conjugate) and return the same instance', () => {
+ const realPrevious: number = complex.getReal();
+ const imaginaryPrevious: number = complex.getImaginary();
+ const complexConjugate: Complex = complex.conjugate();
+
+ expect(complexConjugate.getReal()).toBe(realPrevious);
+ expect(complexConjugate.getImaginary()).toBe(-imaginaryPrevious);
+ expect(complex).toBe(complexConjugate);
+ });
+
+ it('should properly multiply by scalar and return the same instance', () => {
+ const MULTIPLY_SCALAR: number = 5;
+ const complexMultiplied: Complex = complex.multiplyScalar(MULTIPLY_SCALAR);
+
+ expect(complexMultiplied.getReal()).toBeCloseTo(REAL * MULTIPLY_SCALAR, NUMBER_OF_DIGITS);
+ expect(complexMultiplied.getImaginary()).toBeCloseTo(IMAGINARY * MULTIPLY_SCALAR, NUMBER_OF_DIGITS);
+ expect(complex).toBe(complexMultiplied);
+ });
+
+ it('should properly divide by scalar and return the same instance', () => {
+ const DIVIDE_SCALAR: number = 5;
+ const complexDivided: Complex = complex.divideScalar(DIVIDE_SCALAR);
+
+ expect(complexDivided.getReal()).toBeCloseTo(REAL / DIVIDE_SCALAR, NUMBER_OF_DIGITS);
+ expect(complexDivided.getImaginary()).toBeCloseTo(IMAGINARY / DIVIDE_SCALAR, NUMBER_OF_DIGITS);
+ expect(complex).toBe(complexDivided);
+ });
+
+ it('should return real and imaginary part', () => {
+ expect(complex.getReal()).toBe(REAL);
+ expect(complex.getImaginary()).toBe(IMAGINARY);
+ });
+
+ it('should return proper magnitude', () => {
+ const complexMagnitude: number = complex.getMagnitude();
+
+ expect(complexMagnitude).toBeCloseTo(EXPCTED_MAGNITUDE, NUMBER_OF_DIGITS);
+ });
+
+ it('should return unit angle between positive side of X axis and complex number point (counter-clockwise)', () => {
+ let x: Complex;
+
+ x = new Complex(simpleMath, 0.707107, 0.707106);
+ expect(x.getUnitAngle()).toBeCloseTo(0.125, NUMBER_OF_DIGITS);
+
+ x = new Complex(simpleMath, -0.707107, 0.707106);
+ expect(x.getUnitAngle()).toBeCloseTo(0.25 + 0.125, NUMBER_OF_DIGITS);
+
+ x = new Complex(simpleMath, -0.707107, -0.707106);
+ expect(x.getUnitAngle()).toBeCloseTo(0.5 + 0.125, NUMBER_OF_DIGITS);
+
+ x = new Complex(simpleMath, 0.707107, -0.707106);
+ expect(x.getUnitAngle()).toBeCloseTo(0.75 + 0.125, NUMBER_OF_DIGITS);
+
+ x = new Complex(simpleMath, 0.809017, 0.587785);
+ expect(x.getUnitAngle()).toBeCloseTo(0.1, NUMBER_OF_DIGITS);
+
+ x = new Complex(simpleMath, 0.999980, 0.006283);
+ expect(x.getUnitAngle()).toBeCloseTo(0.001, NUMBER_OF_DIGITS);
+
+ x = new Complex(simpleMath, -0.006283, 0.999980);
+ expect(x.getUnitAngle()).toBeCloseTo(0.25 + 0.001, NUMBER_OF_DIGITS);
+
+ x = new Complex(simpleMath, -0.999980, -0.006283);
+ expect(x.getUnitAngle()).toBeCloseTo(0.5 + 0.001, NUMBER_OF_DIGITS);
+
+ x = new Complex(simpleMath, 0.006283, -0.999980);
+ expect(x.getUnitAngle()).toBeCloseTo(0.75 + 0.001, NUMBER_OF_DIGITS);
+ });
+
+ it('should normalize complex number and return the same instance', () => {
+ const complexNormalized: Complex = complex.normalize();
+ const UNIT = 1;
+
+ expect(complexNormalized.getReal()).toBeCloseTo(REAL_NORMALIZED, NUMBER_OF_DIGITS);
+ expect(complexNormalized.getImaginary()).toBeCloseTo(IMAGINARY_NORMALIZED, NUMBER_OF_DIGITS);
+ expect(complexNormalized.getMagnitude()).toBeCloseTo(UNIT, NUMBER_OF_DIGITS);
+ expect(complex).toBe(complexNormalized);
+ });
+});
diff --git a/src/dsp/complex/complex.ts b/src/dsp/complex/complex.ts
new file mode 100644
index 0000000..2a39300
--- /dev/null
+++ b/src/dsp/complex/complex.ts
@@ -0,0 +1,142 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { staticImplements } from 'rr-tsdi';
+
+import { ISimpleMath } from './../../common/simple-math/simple-math.interface';
+import { IComplex, IComplexStatic } from './complex.interface';
+
+@staticImplements()
+class Complex implements IComplex {
+ // TODO probably it's bad to have reference to 'simpleMath'
+ // in each Complex object but it's how DI works...
+ constructor(
+ private simpleMath: ISimpleMath,
+ private real: number,
+ private imaginary: number
+ ) {
+ }
+
+ public clone(): Complex {
+ return new Complex(this.simpleMath, this.real, this.imaginary);
+ }
+
+ public swap(): Complex {
+ const tmp: number = this.real;
+
+ this.real = this.imaginary;
+ this.imaginary = tmp;
+
+ return this;
+ }
+
+ public add(x: Complex): Complex {
+ this.real += x.real;
+ this.imaginary += x.imaginary;
+
+ return this;
+ }
+
+ public subtract(x: Complex): Complex {
+ this.real -= x.real;
+ this.imaginary -= x.imaginary;
+
+ return this;
+ }
+
+ public multiply(x: Complex): Complex {
+ const real = this.real * x.real - this.imaginary * x.imaginary;
+ const imaginary = this.real * x.imaginary + this.imaginary * x.real;
+
+ this.real = real;
+ this.imaginary = imaginary;
+
+ return this;
+ }
+
+ public conjugate(): Complex {
+ this.imaginary *= -1;
+
+ return this;
+ }
+
+ public multiplyScalar(x: number): Complex {
+ this.real *= x;
+ this.imaginary *= x;
+
+ return this;
+ }
+
+ public divideScalar(x: number): Complex {
+ this.real /= x;
+ this.imaginary /= x;
+
+ return this;
+ }
+
+ public getReal(): number {
+ return this.real;
+ }
+
+ public getImaginary(): number {
+ return this.imaginary;
+ }
+
+ public getMagnitude(): number {
+ return this.simpleMath.sqrt(
+ this.simpleMath.pow(this.real, 2) + this.simpleMath.pow(this.imaginary, 2)
+ );
+ }
+
+ public getUnitAngle(): number {
+ const MAGNITUDE_LIMIT = 0.0000001;
+ const x = this.real;
+ const y = this.imaginary;
+ const quarter = (y >= 0)
+ ? (x >= 0 ? 1 : 2)
+ : (x <= 0 ? 3 : 4);
+ let magnitude = this.getMagnitude();
+ let angle;
+ let unitAngle;
+
+ // prevents from dividing by zero
+ magnitude = magnitude < MAGNITUDE_LIMIT
+ ? MAGNITUDE_LIMIT
+ : magnitude;
+
+ // ^ Legend:
+ // II * I '!' = 0 degrees
+ // | '*' = 90 degrees
+ // ----@--+--!----> '@' = 180 degrees
+ // | '%' = 270 degrees
+ // III % IV
+
+ switch (quarter) {
+ case 1:
+ angle = this.simpleMath.asin(y / magnitude);
+ break;
+ case 2:
+ angle = this.simpleMath.asin(-x / magnitude) + 0.5 * this.simpleMath.getPi();
+ break;
+ case 3:
+ angle = this.simpleMath.asin(-y / magnitude) + this.simpleMath.getPi();
+ break;
+ case 4:
+ angle = this.simpleMath.asin(x / magnitude) + 1.5 * this.simpleMath.getPi();
+ break;
+ }
+
+ unitAngle = angle / (2 * this.simpleMath.getPi());
+
+ return unitAngle;
+ }
+
+ public normalize(): Complex {
+ this.divideScalar(
+ this.getMagnitude()
+ );
+
+ return this;
+ }
+}
+
+export default Complex;
diff --git a/src/dsp/complex/di-token.ts b/src/dsp/complex/di-token.ts
new file mode 100644
index 0000000..25b1b8e
--- /dev/null
+++ b/src/dsp/complex/di-token.ts
@@ -0,0 +1,4 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+export const COMPLEX = 'COMPLEX';
+export const COMPLEX_FACTORY = 'COMPLEX_FACTORY';
diff --git a/src/dsp/di-token.ts b/src/dsp/di-token.ts
new file mode 100644
index 0000000..eb94741
--- /dev/null
+++ b/src/dsp/di-token.ts
@@ -0,0 +1,3 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+export const DSP_MODULE = 'DSP_MODULE';
diff --git a/src/dsp/dsp-module.ts b/src/dsp/dsp-module.ts
new file mode 100644
index 0000000..450e89e
--- /dev/null
+++ b/src/dsp/dsp-module.ts
@@ -0,0 +1,21 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { IComplexFactory } from './complex/complex-factory.interface';
+import { COMPLEX_FACTORY } from './complex/di-token';
+import { FFT } from './fft/di-token';
+import { IFft } from './fft/fft.interface';
+
+class DspModule {
+ public static $inject: string[] = [
+ COMPLEX_FACTORY,
+ FFT
+ ];
+
+ constructor(
+ public complexFactory: IComplexFactory,
+ public fft: IFft
+ ) {
+ }
+}
+
+export default DspModule;
diff --git a/src/dsp/fft.js b/src/dsp/fft.js
deleted file mode 100644
index 1e2a00f..0000000
--- a/src/dsp/fft.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
-'use strict';
-
-(function () {
- AudioNetwork.Injector
- .registerFactory('Rewrite.Dsp.Fft', Fft);
-
- Fft.$inject = [
- 'Rewrite.Dsp.Complex'
- ];
-
- function Fft(
- Complex
- ) {
- var Fft;
-
- Fft = function () {
- };
-
- Fft.forward = function (input) {
- var
- n = input.length,
- nHalf,
- even,
- odd,
- output = [],
- wnkMultiplied,
- wnk,
- k,
- unitAngle;
-
- if (n === 1) {
- return input;
- }
-
- // even and odd parts
- even = Fft.forward(Fft.$$getHalf(input, 0));
- odd = Fft.forward(Fft.$$getHalf(input, 1));
-
- // combine
- output.length = n;
- nHalf = n / 2;
- for (k = 0; k < nHalf; k++) {
- unitAngle = -k / n;
- wnk = Complex.polar(unitAngle);
- wnkMultiplied = wnk.clone().multiply(odd[k]);
- output[k] = even[k].clone().add(wnkMultiplied);
- output[nHalf + k] = even[k].clone().subtract(wnkMultiplied);
- }
-
- return output;
- };
-
- Fft.inverse = function (input) {
- var
- output = [],
- i;
-
- for (i = 0; i < input.length; i++) {
- output.push(input[i].clone().swap());
- }
- output = Fft.forward(output);
- for (i = 0; i < output.length; i++) {
- output[i].swap().divideScalar(output.length);
- }
-
- return output;
- };
-
- Fft.$$getHalf = function (list, offset) {
- var i, listHalf, item, lengthHalf;
-
- listHalf = [];
- lengthHalf = list.length / 2;
- for (i = 0; i < lengthHalf; i++) {
- item = list[i * 2 + offset];
- listHalf.push(item);
- }
-
- return listHalf;
- };
-
- return Fft;
- }
-
-})();
diff --git a/src/dsp/fft/di-token.ts b/src/dsp/fft/di-token.ts
new file mode 100644
index 0000000..af00945
--- /dev/null
+++ b/src/dsp/fft/di-token.ts
@@ -0,0 +1,3 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+export const FFT = 'FFT';
diff --git a/src/dsp/fft/fft.interface.ts b/src/dsp/fft/fft.interface.ts
new file mode 100644
index 0000000..a19c420
--- /dev/null
+++ b/src/dsp/fft/fft.interface.ts
@@ -0,0 +1,18 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { IComplexFactory } from '../complex/complex-factory.interface';
+import { IComplex } from '../complex/complex.interface';
+
+interface IFft {
+ forward(input: IComplex[]): IComplex[];
+ inverse(input: IComplex[]): IComplex[];
+}
+
+interface IFftStatic {
+ new(complexFactory: IComplexFactory): IFft;
+}
+
+export {
+ IFft,
+ IFftStatic
+};
diff --git a/src/dsp/fft/fft.spec.ts b/src/dsp/fft/fft.spec.ts
new file mode 100644
index 0000000..00cfd72
--- /dev/null
+++ b/src/dsp/fft/fft.spec.ts
@@ -0,0 +1,66 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { Injector } from 'rr-tsdi';
+
+import { SIMPLE_MATH } from '../../common/simple-math/di-token';
+import SimpleMath from '../../common/simple-math/simple-math';
+import ComplexFactory from '../complex/complex-factory';
+import { IComplexFactory } from '../complex/complex-factory.interface';
+import { IComplex } from '../complex/complex.interface';
+import { COMPLEX_FACTORY } from '../complex/di-token';
+import { FFT } from './di-token';
+import Fft from './fft';
+import { IFft } from './fft.interface';
+
+describe('Complex', () => {
+ let fft: IFft;
+ let complexFactory: IComplexFactory;
+
+ beforeEach(() => {
+ const injector = new Injector();
+
+ injector.registerService(SIMPLE_MATH, SimpleMath);
+ injector.registerService(COMPLEX_FACTORY, ComplexFactory);
+ injector.registerService(FFT, Fft);
+ fft = injector.get(FFT);
+ complexFactory = injector.get(COMPLEX_FACTORY);
+ });
+
+ // TODO refactor it
+ xit('should', () => {
+ const input = [
+ complexFactory.createPolar(0.00, 1),
+ complexFactory.createPolar(0.25, 1),
+ complexFactory.createPolar(0.50, 1),
+ complexFactory.createPolar(0.75, 1)
+ ];
+ const output = fft
+ .forward(input)
+ .map((item: IComplex) => {
+ return {
+ imaginary: item.getImaginary(),
+ real: item.getReal()
+ };
+ });
+
+ expect(output).toEqual([
+ {
+ imaginary: 0,
+ real: 0
+ },
+ {
+ imaginary: 0,
+ real: 0
+ },
+ {
+ imaginary: 0,
+ real: 0
+ },
+ {
+ imaginary: 0,
+ real: 0
+ }
+ ]);
+ });
+
+});
diff --git a/src/dsp/fft/fft.ts b/src/dsp/fft/fft.ts
new file mode 100644
index 0000000..a9fdcd3
--- /dev/null
+++ b/src/dsp/fft/fft.ts
@@ -0,0 +1,85 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { staticImplements } from 'rr-tsdi';
+
+import { IComplexFactory } from '../complex/complex-factory.interface';
+import { IComplex } from '../complex/complex.interface';
+import { COMPLEX_FACTORY } from '../complex/di-token';
+import { IFft, IFftStatic } from './fft.interface';
+
+@staticImplements()
+class Fft implements IFft {
+ public static $inject: string[] = [
+ COMPLEX_FACTORY
+ ];
+
+ constructor(
+ private complexFactory: IComplexFactory
+ ) {
+ }
+
+ public forward(input: IComplex[]): IComplex[] {
+ const n = input.length;
+ let nHalf: number;
+ let even: IComplex[];
+ let odd: IComplex[];
+ const output: IComplex[] = [];
+ let wnkMultiplied: IComplex;
+ let wnk: IComplex;
+ let k: number;
+ let unitAngle: number;
+
+ if (n === 1) {
+ return input;
+ }
+
+ // even and odd parts
+ even = this.forward(this.getHalf(input, 0));
+ odd = this.forward(this.getHalf(input, 1));
+
+ // combine
+ output.length = n;
+ nHalf = n / 2;
+ for (k = 0; k < nHalf; k++) {
+ unitAngle = -k / n;
+ wnk = this.complexFactory.createPolar(unitAngle);
+ wnkMultiplied = wnk.clone().multiply(odd[k]);
+ output[k] = even[k].clone().add(wnkMultiplied);
+ output[nHalf + k] = even[k].clone().subtract(wnkMultiplied);
+ }
+
+ return output;
+ }
+
+ public inverse(input: IComplex[]): IComplex[] {
+ let output: IComplex[] = [];
+ let i: number;
+
+ for (i = 0; i < input.length; i++) {
+ output.push(input[i].clone().swap());
+ }
+ output = this.forward(output);
+ for (i = 0; i < output.length; i++) {
+ output[i].swap().divideScalar(output.length);
+ }
+
+ return output;
+ }
+
+ private getHalf(list: IComplex[], offset: number): IComplex[] {
+ const listHalf: IComplex[] = [];
+ const lengthHalf: number = list.length / 2;
+ let item: IComplex;
+ let i: number;
+
+ for (i = 0; i < lengthHalf; i++) {
+ item = list[i * 2 + offset];
+ listHalf.push(item);
+ }
+
+ return listHalf;
+ }
+
+}
+
+export default Fft;
diff --git a/src/index.spec.ts b/src/index.spec.ts
new file mode 100644
index 0000000..73571e2
--- /dev/null
+++ b/src/index.spec.ts
@@ -0,0 +1,9 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import { version } from './index';
+
+describe('index', () => {
+ it('should give proper version', () => {
+ expect(version).toBe('2.0.0-rc');
+ });
+});
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..7ee6920
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,16 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+import CommonModule from './common/common-module';
+import { COMMON_MODULE } from './common/di-token';
+import injector from './di';
+import { DSP_MODULE } from './dsp/di-token';
+import DspModule from './dsp/dsp-module';
+
+const common: CommonModule = injector.get(COMMON_MODULE);
+const dsp: DspModule = injector.get(DSP_MODULE);
+
+export { version } from './version';
+export {
+ dsp,
+ common
+};
diff --git a/src/version.ts b/src/version.ts
new file mode 100644
index 0000000..caf81c4
--- /dev/null
+++ b/src/version.ts
@@ -0,0 +1,3 @@
+// Copyright (c) 2015-2018 Robert Rypuła - https://audio-network.rypula.pl
+
+export const version = '2.0.0-rc';
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..a0ae5e4
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "outDir": "./",
+ "sourceMap": true,
+ "noImplicitAny": true,
+ "module": "commonjs",
+ "target": "es5",
+ "jsx": "react",
+ "declaration": true,
+ "experimentalDecorators": true
+ },
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": []
+}
\ No newline at end of file
diff --git a/tslint.json b/tslint.json
new file mode 100644
index 0000000..9130f93
--- /dev/null
+++ b/tslint.json
@@ -0,0 +1,20 @@
+{
+ "defaultSeverity": "error",
+ "extends": [
+ "tslint:recommended"
+ ],
+ "jsRules": {},
+ "rules": {
+ "indent": [true, "spaces", 2],
+ "trailing-comma": [
+ true,
+ {
+ "multiline": "never",
+ "singleline": "never"
+ }
+ ],
+ "quotemark": [true, "single"],
+ "prefer-for-of": false
+ },
+ "rulesDirectory": []
+}
\ No newline at end of file
diff --git a/unit-test-web-runner/test-all/test-all.css b/unit-test-web-runner/test-all/test-all.css
deleted file mode 100644
index 8a48d66..0000000
--- a/unit-test-web-runner/test-all/test-all.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.jasmine_html-reporter, .jasmine-run-options {
- display: none;
-}
-
-.jasmine-results a {
- cursor: default;
-}
-
-.jasmine-results a:hover {
- text-decoration: none !important;
-}
-
-.jasmine_html-reporter ul, .jasmine_html-reporter li {
- margin: 0;
- padding: 0;
-}
-
-.jasmine-symbol-summary {
- display: none;
-}
-
-.jasmine-summary li:before {
- display: none;
-}
-
-.jasmine-banner {
- height: 40px;
-}
-
-#unit-test-output .jasmine_html-reporter {
- display: block !important;
- line-height: 1em;
-}
diff --git a/unit-test-web-runner/test-all/test-all.html b/unit-test-web-runner/test-all/test-all.html
deleted file mode 100644
index 36befe3..0000000
--- a/unit-test-web-runner/test-all/test-all.html
+++ /dev/null
@@ -1,109 +0,0 @@
-
-
-
-
-
- Audio Network - data transmission over sound waves - unit test web runner
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Audio Network - send data over sound in JavaScript
-
-
-
- Return to main page
-
-
- THIS PROJECT IS STILL UNDER DEVELOPMENT
- Source code available at GitHub
-
-
- On this page you can run all AudioNetwork unit tests directly in your browser.
-
-
-
-
-
Jasmine output
-
-
-
-
-
- Running unit tests...
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/unit-test-web-runner/test-all/test-all.js b/unit-test-web-runner/test-all/test-all.js
deleted file mode 100644
index 7e3e692..0000000
--- a/unit-test-web-runner/test-all/test-all.js
+++ /dev/null
@@ -1,23 +0,0 @@
-function onLoad() {
- setTimeout(moveJasmineOutput, 2000);
-}
-
-function moveJasmineOutput() {
- var
- unitTestOutputElement = document.getElementById('unit-test-output'),
- jasmineElement = document.getElementsByClassName('jasmine_html-reporter')[0];
-
- unitTestOutputElement.innerHTML = '';
- unitTestOutputElement.appendChild(jasmineElement);
- disableJasmineResultHref();
-}
-
-function disableJasmineResultHref() {
- var
- allJasmineResultLink = document.querySelectorAll('.jasmine-results a'),
- i;
-
- for (i = 0; i < allJasmineResultLink.length; i++) {
- allJasmineResultLink[i].href = 'javascript:void(0)';
- }
-}
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 0000000..ea66790
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1,111 @@
+const webpack = require('webpack');
+const path = require('path');
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
+const WrapperPlugin = require('wrapper-webpack-plugin');
+const { readFileSync } = require('fs');
+const packageJson = require('./package.json');
+const packageName = packageJson.name;
+const libraryName = getLibraryName(packageName);
+const versionFileContent = readFileSync(path.resolve(__dirname) + '/src/version.ts', 'utf8');
+const version = getVersion(versionFileContent);
+const licence = readFileSync(path.resolve(__dirname) + '/LICENCE');
+
+function getLibraryName(packageName) {
+ return packageName
+ .toLowerCase()
+ .split('-')
+ .map(chunk => chunk.charAt(0).toUpperCase() + chunk.slice(1))
+ .join('');
+}
+
+function getVersion(versionFileContent) {
+ const patternStart = '= \'';
+
+ return versionFileContent.substring(
+ versionFileContent.indexOf(patternStart) + patternStart.length,
+ versionFileContent.indexOf('\';')
+ );
+}
+
+function getConfig(env) {
+ return {
+ module: {
+ rules: [
+ {
+ test: /\.tsx?$/,
+ use: 'ts-loader',
+ exclude: /node_modules/
+ }
+ ]
+ },
+ resolve: {
+ extensions: ['.ts','.js']
+ },
+ output: {
+ filename: '[name].js',
+ library: libraryName,
+ libraryTarget: 'umd',
+ path: path.resolve(__dirname, 'dist')
+ },
+ plugins: [
+ new webpack.DefinePlugin({
+ DEVELOPMENT: JSON.stringify(env.DEVELOPMENT === true),
+ PRODUCTION: JSON.stringify(env.PRODUCTION === true)
+ }),
+ new WrapperPlugin({
+ header: '/*\n' + licence + '*/\n\n'
+ })
+ ]
+ };
+}
+
+function fillDev(config) {
+ config.entry = {
+ [`${packageName}-v${version}`]: './src/index.ts'
+ };
+
+ config.devtool = 'inline-source-map';
+
+ config.devServer = {
+ contentBase: path.resolve(__dirname),
+ publicPath: '/dist/',
+ compress: true,
+ port: 8000,
+ hot: false,
+ openPage: 'example/index.html',
+ overlay: {
+ warnings: true,
+ errors: true
+ }
+ };
+}
+
+function fillProd(config) {
+ config.entry = {
+ [`${packageName}-v${version}`]: './src/index.ts',
+ [`${packageName}-v${version}.min`]: './src/index.ts',
+ };
+
+ config.devtool = 'source-map';
+
+ config.plugins.unshift(
+ new UglifyJsPlugin({
+ include: /\.min\.js$/,
+ sourceMap: true
+ })
+ );
+}
+
+module.exports = (env) => {
+ const config = getConfig(env);
+
+ if (env.DEVELOPMENT === true) {
+ fillDev(config);
+ } else if (env.PRODUCTION === true) {
+ fillProd(config);
+ } else {
+ throw 'Please set the environment!';
+ }
+
+ return config;
+}