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 = - '' + - ' ' + - ' ' + - ' FFT256' + - ' FFT512' + - ' FFT1024' + - ' FFT2048' + - ' FFT4096' + - ' FFT8192' + - ' FFT16384' + - ' Freq/TimeDomain' + - ' Freeze' + - ' ' + - '
' + - '' - ; - - 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;i0?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; +}