From 0b4938d0fa729ddf0fab5dfc19b202be98cf4935 Mon Sep 17 00:00:00 2001 From: Chris Rudmin Date: Tue, 22 May 2018 12:23:55 -0400 Subject: [PATCH] Fix serial and 64bit granule pos --- dist-unminified/encoderWorker.js | 2 +- dist/encoderWorker.min.js | 2 +- package.json | 2 +- src/encoderWorker.js | 12 ++- test/encoderWorker.js | 126 +++++++++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 7 deletions(-) diff --git a/dist-unminified/encoderWorker.js b/dist-unminified/encoderWorker.js index f412b500..19eac31e 100644 --- a/dist-unminified/encoderWorker.js +++ b/dist-unminified/encoderWorker.js @@ -117,7 +117,7 @@ eval("var g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\tr /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("/* WEBPACK VAR INJECTION */(function(global) {\n\nvar encoder;\nvar mainReadyResolve;\nvar mainReady = new Promise(function(resolve){ mainReadyResolve = resolve; });\n\nglobal['onmessage'] = function( e ){\n mainReady.then(function(){\n switch( e['data']['command'] ){\n\n case 'encode':\n if (encoder){\n encoder.encode( e['data']['buffers'] );\n }\n break;\n\n case 'done':\n if (encoder) {\n encoder.encodeFinalFrame();\n }\n break;\n\n case 'init':\n encoder = new OggOpusEncoder( e['data'], Module );\n break;\n\n default:\n // Ignore any unknown commands and continue recieving commands\n }\n });\n};\n\n\nvar OggOpusEncoder = function( config, Module ){\n\n if ( !Module ) {\n throw new Error('Module with exports required to initialize an encoder instance');\n }\n\n this.config = Object.assign({ \n bufferLength: 4096, // Define size of incoming buffer\n encoderApplication: 2049, // 2048 = Voice (Lower fidelity)\n // 2049 = Full Band Audio (Highest fidelity)\n // 2051 = Restricted Low Delay (Lowest latency)\n encoderFrameSize: 20, // Specified in ms.\n encoderSampleRate: 48000, // Desired encoding sample rate. Audio will be resampled\n maxBuffersPerPage: 40, // Tradeoff latency with overhead\n numberOfChannels: 1,\n originalSampleRate: 44100,\n resampleQuality: 3, // Value between 0 and 10 inclusive. 10 being highest quality.\n serial: Math.floor( Math.random() * Math.pow(2,32) )\n }, config );\n\n this._opus_encoder_create = Module._opus_encoder_create;\n this._opus_encoder_ctl = Module._opus_encoder_ctl;\n this._speex_resampler_process_interleaved_float = Module._speex_resampler_process_interleaved_float;\n this._speex_resampler_init = Module._speex_resampler_init;\n this._opus_encode_float = Module._opus_encode_float;\n this._free = Module._free;\n this._malloc = Module._malloc;\n this.HEAPU8 = Module.HEAPU8;\n this.HEAP32 = Module.HEAP32;\n this.HEAPF32 = Module.HEAPF32;\n\n this.pageIndex = 0;\n this.granulePosition = 0;\n this.segmentData = new Uint8Array( 65025 ); // Maximum length of oggOpus data\n this.segmentDataIndex = 0;\n this.segmentTable = new Uint8Array( 255 ); // Maximum data segments\n this.segmentTableIndex = 0;\n this.buffersInPage = 0;\n\n this.initChecksumTable();\n this.initCodec();\n this.initResampler();\n this.generateIdPage();\n this.generateCommentPage();\n\n if ( this.config.numberOfChannels === 1 ) {\n this.interleave = function( buffers ) { return buffers[0]; };\n }\n else {\n this.interleavedBuffers = new Float32Array( this.config.bufferLength * this.config.numberOfChannels );\n }\n\n};\n\nOggOpusEncoder.prototype.encode = function( buffers ) {\n var samples = this.interleave( buffers );\n var sampleIndex = 0;\n\n while ( sampleIndex < samples.length ) {\n\n var lengthToCopy = Math.min( this.resampleBufferLength - this.resampleBufferIndex, samples.length - sampleIndex );\n this.resampleBuffer.set( samples.subarray( sampleIndex, sampleIndex+lengthToCopy ), this.resampleBufferIndex );\n sampleIndex += lengthToCopy;\n this.resampleBufferIndex += lengthToCopy;\n\n if ( this.resampleBufferIndex === this.resampleBufferLength ) {\n this._speex_resampler_process_interleaved_float( this.resampler, this.resampleBufferPointer, this.resampleSamplesPerChannelPointer, this.encoderBufferPointer, this.encoderSamplesPerChannelPointer );\n var packetLength = this._opus_encode_float( this.encoder, this.encoderBufferPointer, this.encoderSamplesPerChannel, this.encoderOutputPointer, this.encoderOutputMaxLength );\n this.segmentPacket( packetLength );\n this.resampleBufferIndex = 0;\n }\n }\n\n this.buffersInPage++;\n if ( this.buffersInPage >= this.config.maxBuffersPerPage ) {\n this.generatePage();\n }\n};\n\nOggOpusEncoder.prototype.encodeFinalFrame = function() {\n var finalFrameBuffers = [];\n for ( var i = 0; i < this.config.numberOfChannels; ++i ) {\n finalFrameBuffers.push( new Float32Array( this.config.bufferLength - (this.resampleBufferIndex / this.config.numberOfChannels) ));\n }\n this.encode( finalFrameBuffers );\n this.headerType += 4;\n this.generatePage();\n global['postMessage'](null);\n global['close']();\n};\n\nOggOpusEncoder.prototype.getChecksum = function( data ){\n var checksum = 0;\n for ( var i = 0; i < data.length; i++ ) {\n checksum = (checksum << 8) ^ this.checksumTable[ ((checksum>>>24) & 0xff) ^ data[i] ];\n }\n return checksum >>> 0;\n};\n\nOggOpusEncoder.prototype.generateCommentPage = function(){\n var segmentDataView = new DataView( this.segmentData.buffer );\n segmentDataView.setUint32( 0, 1937076303, true ) // Magic Signature 'Opus'\n segmentDataView.setUint32( 4, 1936154964, true ) // Magic Signature 'Tags'\n segmentDataView.setUint32( 8, 10, true ); // Vendor Length\n segmentDataView.setUint32( 12, 1868784978, true ); // Vendor name 'Reco'\n segmentDataView.setUint32( 16, 1919247474, true ); // Vendor name 'rder'\n segmentDataView.setUint16( 20, 21322, true ); // Vendor name 'JS'\n segmentDataView.setUint32( 22, 0, true ); // User Comment List Length\n this.segmentTableIndex = 1;\n this.segmentDataIndex = this.segmentTable[0] = 26;\n this.headerType = 0;\n this.generatePage();\n};\n\nOggOpusEncoder.prototype.generateIdPage = function(){\n var segmentDataView = new DataView( this.segmentData.buffer );\n segmentDataView.setUint32( 0, 1937076303, true ) // Magic Signature 'Opus'\n segmentDataView.setUint32( 4, 1684104520, true ) // Magic Signature 'Head'\n segmentDataView.setUint8( 8, 1, true ); // Version\n segmentDataView.setUint8( 9, this.config.numberOfChannels, true ); // Channel count\n segmentDataView.setUint16( 10, 3840, true ); // pre-skip (80ms)\n segmentDataView.setUint32( 12, this.config.originalSampleRateOverride || this.config.originalSampleRate, true ); // original sample rate\n segmentDataView.setUint16( 16, 0, true ); // output gain\n segmentDataView.setUint8( 18, 0, true ); // channel map 0 = mono or stereo\n this.segmentTableIndex = 1;\n this.segmentDataIndex = this.segmentTable[0] = 19;\n this.headerType = 2;\n this.generatePage();\n};\n\nOggOpusEncoder.prototype.generatePage = function(){\n var granulePosition = ( this.lastPositiveGranulePosition === this.granulePosition) ? -1 : this.granulePosition;\n var pageBuffer = new ArrayBuffer( 27 + this.segmentTableIndex + this.segmentDataIndex );\n var pageBufferView = new DataView( pageBuffer );\n var page = new Uint8Array( pageBuffer );\n\n pageBufferView.setUint32( 0, 1399285583, true); // Capture Pattern starts all page headers 'OggS'\n pageBufferView.setUint8( 4, 0, true ); // Version\n pageBufferView.setUint8( 5, this.headerType, true ); // 1 = continuation, 2 = beginning of stream, 4 = end of stream\n\n // Number of samples upto and including this page at 48000Hz, into 64 bits\n pageBufferView.setUint32( 6, granulePosition, true );\n if ( granulePosition > 4294967296 || granulePosition < 0 ) {\n pageBufferView.setUint32( 10, Math.floor( granulePosition/4294967296 ), true );\n }\n\n pageBufferView.setUint32( 14, this.config.serial, true ); // Bitstream serial number\n pageBufferView.setUint32( 18, this.pageIndex++, true ); // Page sequence number\n pageBufferView.setUint8( 26, this.segmentTableIndex, true ); // Number of segments in page.\n page.set( this.segmentTable.subarray(0, this.segmentTableIndex), 27 ); // Segment Table\n page.set( this.segmentData.subarray(0, this.segmentDataIndex), 27 + this.segmentTableIndex ); // Segment Data\n pageBufferView.setUint32( 22, this.getChecksum( page ), true ); // Checksum\n\n global['postMessage']( page, [page.buffer] );\n this.segmentTableIndex = 0;\n this.segmentDataIndex = 0;\n this.buffersInPage = 0;\n if ( granulePosition > 0 ) {\n this.lastPositiveGranulePosition = granulePosition;\n }\n};\n\nOggOpusEncoder.prototype.initChecksumTable = function(){\n this.checksumTable = [];\n for ( var i = 0; i < 256; i++ ) {\n var r = i << 24;\n for ( var j = 0; j < 8; j++ ) {\n r = ((r & 0x80000000) != 0) ? ((r << 1) ^ 0x04c11db7) : (r << 1);\n }\n this.checksumTable[i] = (r & 0xffffffff);\n }\n};\n\nOggOpusEncoder.prototype.setOpusControl = function( control, value ){\n var location = this._malloc( 4 );\n this.HEAP32[ location >> 2 ] = value;\n this._opus_encoder_ctl( this.encoder, control, location );\n this._free( location );\n};\n\nOggOpusEncoder.prototype.initCodec = function() {\n var errLocation = this._malloc( 4 );\n this.encoder = this._opus_encoder_create( this.config.encoderSampleRate, this.config.numberOfChannels, this.config.encoderApplication, errLocation );\n this._free( errLocation );\n\n if ( this.config.encoderBitRate ) {\n this.setOpusControl( 4002, this.config.encoderBitRate );\n }\n\n if ( this.config.encoderComplexity ) {\n this.setOpusControl( 4010, this.config.encoderComplexity );\n }\n\n this.encoderSamplesPerChannel = this.config.encoderSampleRate * this.config.encoderFrameSize / 1000;\n this.encoderSamplesPerChannelPointer = this._malloc( 4 );\n this.HEAP32[ this.encoderSamplesPerChannelPointer >> 2 ] = this.encoderSamplesPerChannel;\n\n this.encoderBufferLength = this.encoderSamplesPerChannel * this.config.numberOfChannels;\n this.encoderBufferPointer = this._malloc( this.encoderBufferLength * 4 ); // 4 bytes per sample\n this.encoderBuffer = this.HEAPF32.subarray( this.encoderBufferPointer >> 2, (this.encoderBufferPointer >> 2) + this.encoderBufferLength );\n\n this.encoderOutputMaxLength = 4000;\n this.encoderOutputPointer = this._malloc( this.encoderOutputMaxLength );\n this.encoderOutputBuffer = this.HEAPU8.subarray( this.encoderOutputPointer, this.encoderOutputPointer + this.encoderOutputMaxLength );\n};\n\nOggOpusEncoder.prototype.initResampler = function() {\n var errLocation = this._malloc( 4 );\n this.resampler = this._speex_resampler_init( this.config.numberOfChannels, this.config.originalSampleRate, this.config.encoderSampleRate, this.config.resampleQuality, errLocation );\n this._free( errLocation );\n\n this.resampleBufferIndex = 0;\n this.resampleSamplesPerChannel = this.config.originalSampleRate * this.config.encoderFrameSize / 1000;\n this.resampleSamplesPerChannelPointer = this._malloc( 4 );\n this.HEAP32[ this.resampleSamplesPerChannelPointer >> 2 ] = this.resampleSamplesPerChannel;\n\n this.resampleBufferLength = this.resampleSamplesPerChannel * this.config.numberOfChannels;\n this.resampleBufferPointer = this._malloc( this.resampleBufferLength * 4 ); // 4 bytes per sample\n this.resampleBuffer = this.HEAPF32.subarray( this.resampleBufferPointer >> 2, (this.resampleBufferPointer >> 2) + this.resampleBufferLength );\n};\n\nOggOpusEncoder.prototype.interleave = function( buffers ) {\n for ( var i = 0; i < this.config.bufferLength; i++ ) {\n for ( var channel = 0; channel < this.config.numberOfChannels; channel++ ) {\n this.interleavedBuffers[ i * this.config.numberOfChannels + channel ] = buffers[ channel ][ i ];\n }\n }\n\n return this.interleavedBuffers;\n};\n\nOggOpusEncoder.prototype.segmentPacket = function( packetLength ) {\n var packetIndex = 0;\n\n while ( packetLength >= 0 ) {\n\n if ( this.segmentTableIndex === 255 ) {\n this.generatePage();\n this.headerType = 1;\n }\n\n var segmentLength = Math.min( packetLength, 255 );\n this.segmentTable[ this.segmentTableIndex++ ] = segmentLength;\n this.segmentData.set( this.encoderOutputBuffer.subarray( packetIndex, packetIndex + segmentLength ), this.segmentDataIndex );\n this.segmentDataIndex += segmentLength;\n packetIndex += segmentLength;\n packetLength -= 255;\n }\n\n this.granulePosition += ( 48 * this.config.encoderFrameSize );\n if ( this.segmentTableIndex === 255 ) {\n this.generatePage();\n this.headerType = 0;\n }\n};\n\n\nif (!Module) {\n Module = {};\n}\n\nModule['mainReady'] = mainReady;\nModule['OggOpusEncoder'] = OggOpusEncoder;\nModule['onRuntimeInitialized'] = mainReadyResolve;\n\nmodule.exports = Module;\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvZW5jb2Rlcldvcmtlci5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0VuY29kZXJXb3JrZXIvLi9zcmMvZW5jb2Rlcldvcmtlci5qcz84YjNjIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG52YXIgZW5jb2RlcjtcbnZhciBtYWluUmVhZHlSZXNvbHZlO1xudmFyIG1haW5SZWFkeSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpeyBtYWluUmVhZHlSZXNvbHZlID0gcmVzb2x2ZTsgfSk7XG5cbmdsb2JhbFsnb25tZXNzYWdlJ10gPSBmdW5jdGlvbiggZSApe1xuICBtYWluUmVhZHkudGhlbihmdW5jdGlvbigpe1xuICAgIHN3aXRjaCggZVsnZGF0YSddWydjb21tYW5kJ10gKXtcblxuICAgICAgY2FzZSAnZW5jb2RlJzpcbiAgICAgICAgaWYgKGVuY29kZXIpe1xuICAgICAgICAgIGVuY29kZXIuZW5jb2RlKCBlWydkYXRhJ11bJ2J1ZmZlcnMnXSApO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdkb25lJzpcbiAgICAgICAgaWYgKGVuY29kZXIpIHtcbiAgICAgICAgICBlbmNvZGVyLmVuY29kZUZpbmFsRnJhbWUoKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnaW5pdCc6XG4gICAgICAgIGVuY29kZXIgPSBuZXcgT2dnT3B1c0VuY29kZXIoIGVbJ2RhdGEnXSwgTW9kdWxlICk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyBJZ25vcmUgYW55IHVua25vd24gY29tbWFuZHMgYW5kIGNvbnRpbnVlIHJlY2lldmluZyBjb21tYW5kc1xuICAgIH1cbiAgfSk7XG59O1xuXG5cbnZhciBPZ2dPcHVzRW5jb2RlciA9IGZ1bmN0aW9uKCBjb25maWcsIE1vZHVsZSApe1xuXG4gIGlmICggIU1vZHVsZSApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01vZHVsZSB3aXRoIGV4cG9ydHMgcmVxdWlyZWQgdG8gaW5pdGlhbGl6ZSBhbiBlbmNvZGVyIGluc3RhbmNlJyk7XG4gIH1cblxuICB0aGlzLmNvbmZpZyA9IE9iamVjdC5hc3NpZ24oeyBcbiAgICBidWZmZXJMZW5ndGg6IDQwOTYsIC8vIERlZmluZSBzaXplIG9mIGluY29taW5nIGJ1ZmZlclxuICAgIGVuY29kZXJBcHBsaWNhdGlvbjogMjA0OSwgLy8gMjA0OCA9IFZvaWNlIChMb3dlciBmaWRlbGl0eSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDIwNDkgPSBGdWxsIEJhbmQgQXVkaW8gKEhpZ2hlc3QgZmlkZWxpdHkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAyMDUxID0gUmVzdHJpY3RlZCBMb3cgRGVsYXkgKExvd2VzdCBsYXRlbmN5KVxuICAgIGVuY29kZXJGcmFtZVNpemU6IDIwLCAvLyBTcGVjaWZpZWQgaW4gbXMuXG4gICAgZW5jb2RlclNhbXBsZVJhdGU6IDQ4MDAwLCAvLyBEZXNpcmVkIGVuY29kaW5nIHNhbXBsZSByYXRlLiBBdWRpbyB3aWxsIGJlIHJlc2FtcGxlZFxuICAgIG1heEJ1ZmZlcnNQZXJQYWdlOiA0MCwgLy8gVHJhZGVvZmYgbGF0ZW5jeSB3aXRoIG92ZXJoZWFkXG4gICAgbnVtYmVyT2ZDaGFubmVsczogMSxcbiAgICBvcmlnaW5hbFNhbXBsZVJhdGU6IDQ0MTAwLFxuICAgIHJlc2FtcGxlUXVhbGl0eTogMywgLy8gVmFsdWUgYmV0d2VlbiAwIGFuZCAxMCBpbmNsdXNpdmUuIDEwIGJlaW5nIGhpZ2hlc3QgcXVhbGl0eS5cbiAgICBzZXJpYWw6IE1hdGguZmxvb3IoIE1hdGgucmFuZG9tKCkgKiBNYXRoLnBvdygyLDMyKSApXG4gIH0sIGNvbmZpZyApO1xuXG4gIHRoaXMuX29wdXNfZW5jb2Rlcl9jcmVhdGUgPSBNb2R1bGUuX29wdXNfZW5jb2Rlcl9jcmVhdGU7XG4gIHRoaXMuX29wdXNfZW5jb2Rlcl9jdGwgPSBNb2R1bGUuX29wdXNfZW5jb2Rlcl9jdGw7XG4gIHRoaXMuX3NwZWV4X3Jlc2FtcGxlcl9wcm9jZXNzX2ludGVybGVhdmVkX2Zsb2F0ID0gTW9kdWxlLl9zcGVleF9yZXNhbXBsZXJfcHJvY2Vzc19pbnRlcmxlYXZlZF9mbG9hdDtcbiAgdGhpcy5fc3BlZXhfcmVzYW1wbGVyX2luaXQgPSBNb2R1bGUuX3NwZWV4X3Jlc2FtcGxlcl9pbml0O1xuICB0aGlzLl9vcHVzX2VuY29kZV9mbG9hdCA9IE1vZHVsZS5fb3B1c19lbmNvZGVfZmxvYXQ7XG4gIHRoaXMuX2ZyZWUgPSBNb2R1bGUuX2ZyZWU7XG4gIHRoaXMuX21hbGxvYyA9IE1vZHVsZS5fbWFsbG9jO1xuICB0aGlzLkhFQVBVOCA9IE1vZHVsZS5IRUFQVTg7XG4gIHRoaXMuSEVBUDMyID0gTW9kdWxlLkhFQVAzMjtcbiAgdGhpcy5IRUFQRjMyID0gTW9kdWxlLkhFQVBGMzI7XG5cbiAgdGhpcy5wYWdlSW5kZXggPSAwO1xuICB0aGlzLmdyYW51bGVQb3NpdGlvbiA9IDA7XG4gIHRoaXMuc2VnbWVudERhdGEgPSBuZXcgVWludDhBcnJheSggNjUwMjUgKTsgLy8gTWF4aW11bSBsZW5ndGggb2Ygb2dnT3B1cyBkYXRhXG4gIHRoaXMuc2VnbWVudERhdGFJbmRleCA9IDA7XG4gIHRoaXMuc2VnbWVudFRhYmxlID0gbmV3IFVpbnQ4QXJyYXkoIDI1NSApOyAvLyBNYXhpbXVtIGRhdGEgc2VnbWVudHNcbiAgdGhpcy5zZWdtZW50VGFibGVJbmRleCA9IDA7XG4gIHRoaXMuYnVmZmVyc0luUGFnZSA9IDA7XG5cbiAgdGhpcy5pbml0Q2hlY2tzdW1UYWJsZSgpO1xuICB0aGlzLmluaXRDb2RlYygpO1xuICB0aGlzLmluaXRSZXNhbXBsZXIoKTtcbiAgdGhpcy5nZW5lcmF0ZUlkUGFnZSgpO1xuICB0aGlzLmdlbmVyYXRlQ29tbWVudFBhZ2UoKTtcblxuICBpZiAoIHRoaXMuY29uZmlnLm51bWJlck9mQ2hhbm5lbHMgPT09IDEgKSB7XG4gICAgdGhpcy5pbnRlcmxlYXZlID0gZnVuY3Rpb24oIGJ1ZmZlcnMgKSB7IHJldHVybiBidWZmZXJzWzBdOyB9O1xuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMuaW50ZXJsZWF2ZWRCdWZmZXJzID0gbmV3IEZsb2F0MzJBcnJheSggdGhpcy5jb25maWcuYnVmZmVyTGVuZ3RoICogdGhpcy5jb25maWcubnVtYmVyT2ZDaGFubmVscyApO1xuICB9XG5cbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5lbmNvZGUgPSBmdW5jdGlvbiggYnVmZmVycyApIHtcbiAgdmFyIHNhbXBsZXMgPSB0aGlzLmludGVybGVhdmUoIGJ1ZmZlcnMgKTtcbiAgdmFyIHNhbXBsZUluZGV4ID0gMDtcblxuICB3aGlsZSAoIHNhbXBsZUluZGV4IDwgc2FtcGxlcy5sZW5ndGggKSB7XG5cbiAgICB2YXIgbGVuZ3RoVG9Db3B5ID0gTWF0aC5taW4oIHRoaXMucmVzYW1wbGVCdWZmZXJMZW5ndGggLSB0aGlzLnJlc2FtcGxlQnVmZmVySW5kZXgsIHNhbXBsZXMubGVuZ3RoIC0gc2FtcGxlSW5kZXggKTtcbiAgICB0aGlzLnJlc2FtcGxlQnVmZmVyLnNldCggc2FtcGxlcy5zdWJhcnJheSggc2FtcGxlSW5kZXgsIHNhbXBsZUluZGV4K2xlbmd0aFRvQ29weSApLCB0aGlzLnJlc2FtcGxlQnVmZmVySW5kZXggKTtcbiAgICBzYW1wbGVJbmRleCArPSBsZW5ndGhUb0NvcHk7XG4gICAgdGhpcy5yZXNhbXBsZUJ1ZmZlckluZGV4ICs9IGxlbmd0aFRvQ29weTtcblxuICAgIGlmICggdGhpcy5yZXNhbXBsZUJ1ZmZlckluZGV4ID09PSB0aGlzLnJlc2FtcGxlQnVmZmVyTGVuZ3RoICkge1xuICAgICAgdGhpcy5fc3BlZXhfcmVzYW1wbGVyX3Byb2Nlc3NfaW50ZXJsZWF2ZWRfZmxvYXQoIHRoaXMucmVzYW1wbGVyLCB0aGlzLnJlc2FtcGxlQnVmZmVyUG9pbnRlciwgdGhpcy5yZXNhbXBsZVNhbXBsZXNQZXJDaGFubmVsUG9pbnRlciwgdGhpcy5lbmNvZGVyQnVmZmVyUG9pbnRlciwgdGhpcy5lbmNvZGVyU2FtcGxlc1BlckNoYW5uZWxQb2ludGVyICk7XG4gICAgICB2YXIgcGFja2V0TGVuZ3RoID0gdGhpcy5fb3B1c19lbmNvZGVfZmxvYXQoIHRoaXMuZW5jb2RlciwgdGhpcy5lbmNvZGVyQnVmZmVyUG9pbnRlciwgdGhpcy5lbmNvZGVyU2FtcGxlc1BlckNoYW5uZWwsIHRoaXMuZW5jb2Rlck91dHB1dFBvaW50ZXIsIHRoaXMuZW5jb2Rlck91dHB1dE1heExlbmd0aCApO1xuICAgICAgdGhpcy5zZWdtZW50UGFja2V0KCBwYWNrZXRMZW5ndGggKTtcbiAgICAgIHRoaXMucmVzYW1wbGVCdWZmZXJJbmRleCA9IDA7XG4gICAgfVxuICB9XG5cbiAgdGhpcy5idWZmZXJzSW5QYWdlKys7XG4gIGlmICggdGhpcy5idWZmZXJzSW5QYWdlID49IHRoaXMuY29uZmlnLm1heEJ1ZmZlcnNQZXJQYWdlICkge1xuICAgIHRoaXMuZ2VuZXJhdGVQYWdlKCk7XG4gIH1cbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5lbmNvZGVGaW5hbEZyYW1lID0gZnVuY3Rpb24oKSB7XG4gIHZhciBmaW5hbEZyYW1lQnVmZmVycyA9IFtdO1xuICBmb3IgKCB2YXIgaSA9IDA7IGkgPCB0aGlzLmNvbmZpZy5udW1iZXJPZkNoYW5uZWxzOyArK2kgKSB7XG4gICAgZmluYWxGcmFtZUJ1ZmZlcnMucHVzaCggbmV3IEZsb2F0MzJBcnJheSggdGhpcy5jb25maWcuYnVmZmVyTGVuZ3RoIC0gKHRoaXMucmVzYW1wbGVCdWZmZXJJbmRleCAvIHRoaXMuY29uZmlnLm51bWJlck9mQ2hhbm5lbHMpICkpO1xuICB9XG4gIHRoaXMuZW5jb2RlKCBmaW5hbEZyYW1lQnVmZmVycyApO1xuICB0aGlzLmhlYWRlclR5cGUgKz0gNDtcbiAgdGhpcy5nZW5lcmF0ZVBhZ2UoKTtcbiAgZ2xvYmFsWydwb3N0TWVzc2FnZSddKG51bGwpO1xuICBnbG9iYWxbJ2Nsb3NlJ10oKTtcbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5nZXRDaGVja3N1bSA9IGZ1bmN0aW9uKCBkYXRhICl7XG4gIHZhciBjaGVja3N1bSA9IDA7XG4gIGZvciAoIHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKysgKSB7XG4gICAgY2hlY2tzdW0gPSAoY2hlY2tzdW0gPDwgOCkgXiB0aGlzLmNoZWNrc3VtVGFibGVbICgoY2hlY2tzdW0+Pj4yNCkgJiAweGZmKSBeIGRhdGFbaV0gXTtcbiAgfVxuICByZXR1cm4gY2hlY2tzdW0gPj4+IDA7XG59O1xuXG5PZ2dPcHVzRW5jb2Rlci5wcm90b3R5cGUuZ2VuZXJhdGVDb21tZW50UGFnZSA9IGZ1bmN0aW9uKCl7XG4gIHZhciBzZWdtZW50RGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoIHRoaXMuc2VnbWVudERhdGEuYnVmZmVyICk7XG4gIHNlZ21lbnREYXRhVmlldy5zZXRVaW50MzIoIDAsIDE5MzcwNzYzMDMsIHRydWUgKSAvLyBNYWdpYyBTaWduYXR1cmUgJ09wdXMnXG4gIHNlZ21lbnREYXRhVmlldy5zZXRVaW50MzIoIDQsIDE5MzYxNTQ5NjQsIHRydWUgKSAvLyBNYWdpYyBTaWduYXR1cmUgJ1RhZ3MnXG4gIHNlZ21lbnREYXRhVmlldy5zZXRVaW50MzIoIDgsIDEwLCB0cnVlICk7IC8vIFZlbmRvciBMZW5ndGhcbiAgc2VnbWVudERhdGFWaWV3LnNldFVpbnQzMiggMTIsIDE4Njg3ODQ5NzgsIHRydWUgKTsgLy8gVmVuZG9yIG5hbWUgJ1JlY28nXG4gIHNlZ21lbnREYXRhVmlldy5zZXRVaW50MzIoIDE2LCAxOTE5MjQ3NDc0LCB0cnVlICk7IC8vIFZlbmRvciBuYW1lICdyZGVyJ1xuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDE2KCAyMCwgMjEzMjIsIHRydWUgKTsgLy8gVmVuZG9yIG5hbWUgJ0pTJ1xuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDMyKCAyMiwgMCwgdHJ1ZSApOyAvLyBVc2VyIENvbW1lbnQgTGlzdCBMZW5ndGhcbiAgdGhpcy5zZWdtZW50VGFibGVJbmRleCA9IDE7XG4gIHRoaXMuc2VnbWVudERhdGFJbmRleCA9IHRoaXMuc2VnbWVudFRhYmxlWzBdID0gMjY7XG4gIHRoaXMuaGVhZGVyVHlwZSA9IDA7XG4gIHRoaXMuZ2VuZXJhdGVQYWdlKCk7XG59O1xuXG5PZ2dPcHVzRW5jb2Rlci5wcm90b3R5cGUuZ2VuZXJhdGVJZFBhZ2UgPSBmdW5jdGlvbigpe1xuICB2YXIgc2VnbWVudERhdGFWaWV3ID0gbmV3IERhdGFWaWV3KCB0aGlzLnNlZ21lbnREYXRhLmJ1ZmZlciApO1xuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDMyKCAwLCAxOTM3MDc2MzAzLCB0cnVlICkgLy8gTWFnaWMgU2lnbmF0dXJlICdPcHVzJ1xuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDMyKCA0LCAxNjg0MTA0NTIwLCB0cnVlICkgLy8gTWFnaWMgU2lnbmF0dXJlICdIZWFkJ1xuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDgoIDgsIDEsIHRydWUgKTsgLy8gVmVyc2lvblxuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDgoIDksIHRoaXMuY29uZmlnLm51bWJlck9mQ2hhbm5lbHMsIHRydWUgKTsgLy8gQ2hhbm5lbCBjb3VudFxuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDE2KCAxMCwgMzg0MCwgdHJ1ZSApOyAvLyBwcmUtc2tpcCAoODBtcylcbiAgc2VnbWVudERhdGFWaWV3LnNldFVpbnQzMiggMTIsIHRoaXMuY29uZmlnLm9yaWdpbmFsU2FtcGxlUmF0ZU92ZXJyaWRlIHx8IHRoaXMuY29uZmlnLm9yaWdpbmFsU2FtcGxlUmF0ZSwgdHJ1ZSApOyAvLyBvcmlnaW5hbCBzYW1wbGUgcmF0ZVxuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDE2KCAxNiwgMCwgdHJ1ZSApOyAvLyBvdXRwdXQgZ2FpblxuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDgoIDE4LCAwLCB0cnVlICk7IC8vIGNoYW5uZWwgbWFwIDAgPSBtb25vIG9yIHN0ZXJlb1xuICB0aGlzLnNlZ21lbnRUYWJsZUluZGV4ID0gMTtcbiAgdGhpcy5zZWdtZW50RGF0YUluZGV4ID0gdGhpcy5zZWdtZW50VGFibGVbMF0gPSAxOTtcbiAgdGhpcy5oZWFkZXJUeXBlID0gMjtcbiAgdGhpcy5nZW5lcmF0ZVBhZ2UoKTtcbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5nZW5lcmF0ZVBhZ2UgPSBmdW5jdGlvbigpe1xuICB2YXIgZ3JhbnVsZVBvc2l0aW9uID0gKCB0aGlzLmxhc3RQb3NpdGl2ZUdyYW51bGVQb3NpdGlvbiA9PT0gdGhpcy5ncmFudWxlUG9zaXRpb24pID8gLTEgOiB0aGlzLmdyYW51bGVQb3NpdGlvbjtcbiAgdmFyIHBhZ2VCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoICAyNyArIHRoaXMuc2VnbWVudFRhYmxlSW5kZXggKyB0aGlzLnNlZ21lbnREYXRhSW5kZXggKTtcbiAgdmFyIHBhZ2VCdWZmZXJWaWV3ID0gbmV3IERhdGFWaWV3KCBwYWdlQnVmZmVyICk7XG4gIHZhciBwYWdlID0gbmV3IFVpbnQ4QXJyYXkoIHBhZ2VCdWZmZXIgKTtcblxuICBwYWdlQnVmZmVyVmlldy5zZXRVaW50MzIoIDAsIDEzOTkyODU1ODMsIHRydWUpOyAvLyBDYXB0dXJlIFBhdHRlcm4gc3RhcnRzIGFsbCBwYWdlIGhlYWRlcnMgJ09nZ1MnXG4gIHBhZ2VCdWZmZXJWaWV3LnNldFVpbnQ4KCA0LCAwLCB0cnVlICk7IC8vIFZlcnNpb25cbiAgcGFnZUJ1ZmZlclZpZXcuc2V0VWludDgoIDUsIHRoaXMuaGVhZGVyVHlwZSwgdHJ1ZSApOyAvLyAxID0gY29udGludWF0aW9uLCAyID0gYmVnaW5uaW5nIG9mIHN0cmVhbSwgNCA9IGVuZCBvZiBzdHJlYW1cblxuICAvLyBOdW1iZXIgb2Ygc2FtcGxlcyB1cHRvIGFuZCBpbmNsdWRpbmcgdGhpcyBwYWdlIGF0IDQ4MDAwSHosIGludG8gNjQgYml0c1xuICBwYWdlQnVmZmVyVmlldy5zZXRVaW50MzIoIDYsIGdyYW51bGVQb3NpdGlvbiwgdHJ1ZSApO1xuICBpZiAoIGdyYW51bGVQb3NpdGlvbiA+IDQyOTQ5NjcyOTYgfHwgZ3JhbnVsZVBvc2l0aW9uIDwgMCApIHtcbiAgICBwYWdlQnVmZmVyVmlldy5zZXRVaW50MzIoIDEwLCBNYXRoLmZsb29yKCBncmFudWxlUG9zaXRpb24vNDI5NDk2NzI5NiApLCB0cnVlICk7XG4gIH1cblxuICBwYWdlQnVmZmVyVmlldy5zZXRVaW50MzIoIDE0LCB0aGlzLmNvbmZpZy5zZXJpYWwsIHRydWUgKTsgLy8gQml0c3RyZWFtIHNlcmlhbCBudW1iZXJcbiAgcGFnZUJ1ZmZlclZpZXcuc2V0VWludDMyKCAxOCwgdGhpcy5wYWdlSW5kZXgrKywgdHJ1ZSApOyAvLyBQYWdlIHNlcXVlbmNlIG51bWJlclxuICBwYWdlQnVmZmVyVmlldy5zZXRVaW50OCggMjYsIHRoaXMuc2VnbWVudFRhYmxlSW5kZXgsIHRydWUgKTsgLy8gTnVtYmVyIG9mIHNlZ21lbnRzIGluIHBhZ2UuXG4gIHBhZ2Uuc2V0KCB0aGlzLnNlZ21lbnRUYWJsZS5zdWJhcnJheSgwLCB0aGlzLnNlZ21lbnRUYWJsZUluZGV4KSwgMjcgKTsgLy8gU2VnbWVudCBUYWJsZVxuICBwYWdlLnNldCggdGhpcy5zZWdtZW50RGF0YS5zdWJhcnJheSgwLCB0aGlzLnNlZ21lbnREYXRhSW5kZXgpLCAyNyArIHRoaXMuc2VnbWVudFRhYmxlSW5kZXggKTsgLy8gU2VnbWVudCBEYXRhXG4gIHBhZ2VCdWZmZXJWaWV3LnNldFVpbnQzMiggMjIsIHRoaXMuZ2V0Q2hlY2tzdW0oIHBhZ2UgKSwgdHJ1ZSApOyAvLyBDaGVja3N1bVxuXG4gIGdsb2JhbFsncG9zdE1lc3NhZ2UnXSggcGFnZSwgW3BhZ2UuYnVmZmVyXSApO1xuICB0aGlzLnNlZ21lbnRUYWJsZUluZGV4ID0gMDtcbiAgdGhpcy5zZWdtZW50RGF0YUluZGV4ID0gMDtcbiAgdGhpcy5idWZmZXJzSW5QYWdlID0gMDtcbiAgaWYgKCBncmFudWxlUG9zaXRpb24gPiAwICkge1xuICAgIHRoaXMubGFzdFBvc2l0aXZlR3JhbnVsZVBvc2l0aW9uID0gZ3JhbnVsZVBvc2l0aW9uO1xuICB9XG59O1xuXG5PZ2dPcHVzRW5jb2Rlci5wcm90b3R5cGUuaW5pdENoZWNrc3VtVGFibGUgPSBmdW5jdGlvbigpe1xuICB0aGlzLmNoZWNrc3VtVGFibGUgPSBbXTtcbiAgZm9yICggdmFyIGkgPSAwOyBpIDwgMjU2OyBpKysgKSB7XG4gICAgdmFyIHIgPSBpIDw8IDI0O1xuICAgIGZvciAoIHZhciBqID0gMDsgaiA8IDg7IGorKyApIHtcbiAgICAgIHIgPSAoKHIgJiAweDgwMDAwMDAwKSAhPSAwKSA/ICgociA8PCAxKSBeIDB4MDRjMTFkYjcpIDogKHIgPDwgMSk7XG4gICAgfVxuICAgIHRoaXMuY2hlY2tzdW1UYWJsZVtpXSA9IChyICYgMHhmZmZmZmZmZik7XG4gIH1cbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5zZXRPcHVzQ29udHJvbCA9IGZ1bmN0aW9uKCBjb250cm9sLCB2YWx1ZSApe1xuICB2YXIgbG9jYXRpb24gPSB0aGlzLl9tYWxsb2MoIDQgKTtcbiAgdGhpcy5IRUFQMzJbIGxvY2F0aW9uID4+IDIgXSA9IHZhbHVlO1xuICB0aGlzLl9vcHVzX2VuY29kZXJfY3RsKCB0aGlzLmVuY29kZXIsIGNvbnRyb2wsIGxvY2F0aW9uICk7XG4gIHRoaXMuX2ZyZWUoIGxvY2F0aW9uICk7XG59O1xuXG5PZ2dPcHVzRW5jb2Rlci5wcm90b3R5cGUuaW5pdENvZGVjID0gZnVuY3Rpb24oKSB7XG4gIHZhciBlcnJMb2NhdGlvbiA9IHRoaXMuX21hbGxvYyggNCApO1xuICB0aGlzLmVuY29kZXIgPSB0aGlzLl9vcHVzX2VuY29kZXJfY3JlYXRlKCB0aGlzLmNvbmZpZy5lbmNvZGVyU2FtcGxlUmF0ZSwgdGhpcy5jb25maWcubnVtYmVyT2ZDaGFubmVscywgdGhpcy5jb25maWcuZW5jb2RlckFwcGxpY2F0aW9uLCBlcnJMb2NhdGlvbiApO1xuICB0aGlzLl9mcmVlKCBlcnJMb2NhdGlvbiApO1xuXG4gIGlmICggdGhpcy5jb25maWcuZW5jb2RlckJpdFJhdGUgKSB7XG4gICAgdGhpcy5zZXRPcHVzQ29udHJvbCggNDAwMiwgdGhpcy5jb25maWcuZW5jb2RlckJpdFJhdGUgKTtcbiAgfVxuXG4gIGlmICggdGhpcy5jb25maWcuZW5jb2RlckNvbXBsZXhpdHkgKSB7XG4gICAgdGhpcy5zZXRPcHVzQ29udHJvbCggNDAxMCwgdGhpcy5jb25maWcuZW5jb2RlckNvbXBsZXhpdHkgKTtcbiAgfVxuXG4gIHRoaXMuZW5jb2RlclNhbXBsZXNQZXJDaGFubmVsID0gdGhpcy5jb25maWcuZW5jb2RlclNhbXBsZVJhdGUgKiB0aGlzLmNvbmZpZy5lbmNvZGVyRnJhbWVTaXplIC8gMTAwMDtcbiAgdGhpcy5lbmNvZGVyU2FtcGxlc1BlckNoYW5uZWxQb2ludGVyID0gdGhpcy5fbWFsbG9jKCA0ICk7XG4gIHRoaXMuSEVBUDMyWyB0aGlzLmVuY29kZXJTYW1wbGVzUGVyQ2hhbm5lbFBvaW50ZXIgPj4gMiBdID0gdGhpcy5lbmNvZGVyU2FtcGxlc1BlckNoYW5uZWw7XG5cbiAgdGhpcy5lbmNvZGVyQnVmZmVyTGVuZ3RoID0gdGhpcy5lbmNvZGVyU2FtcGxlc1BlckNoYW5uZWwgKiB0aGlzLmNvbmZpZy5udW1iZXJPZkNoYW5uZWxzO1xuICB0aGlzLmVuY29kZXJCdWZmZXJQb2ludGVyID0gdGhpcy5fbWFsbG9jKCB0aGlzLmVuY29kZXJCdWZmZXJMZW5ndGggKiA0ICk7IC8vIDQgYnl0ZXMgcGVyIHNhbXBsZVxuICB0aGlzLmVuY29kZXJCdWZmZXIgPSB0aGlzLkhFQVBGMzIuc3ViYXJyYXkoIHRoaXMuZW5jb2RlckJ1ZmZlclBvaW50ZXIgPj4gMiwgKHRoaXMuZW5jb2RlckJ1ZmZlclBvaW50ZXIgPj4gMikgKyB0aGlzLmVuY29kZXJCdWZmZXJMZW5ndGggKTtcblxuICB0aGlzLmVuY29kZXJPdXRwdXRNYXhMZW5ndGggPSA0MDAwO1xuICB0aGlzLmVuY29kZXJPdXRwdXRQb2ludGVyID0gdGhpcy5fbWFsbG9jKCB0aGlzLmVuY29kZXJPdXRwdXRNYXhMZW5ndGggKTtcbiAgdGhpcy5lbmNvZGVyT3V0cHV0QnVmZmVyID0gdGhpcy5IRUFQVTguc3ViYXJyYXkoIHRoaXMuZW5jb2Rlck91dHB1dFBvaW50ZXIsIHRoaXMuZW5jb2Rlck91dHB1dFBvaW50ZXIgKyB0aGlzLmVuY29kZXJPdXRwdXRNYXhMZW5ndGggKTtcbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5pbml0UmVzYW1wbGVyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBlcnJMb2NhdGlvbiA9IHRoaXMuX21hbGxvYyggNCApO1xuICB0aGlzLnJlc2FtcGxlciA9IHRoaXMuX3NwZWV4X3Jlc2FtcGxlcl9pbml0KCB0aGlzLmNvbmZpZy5udW1iZXJPZkNoYW5uZWxzLCB0aGlzLmNvbmZpZy5vcmlnaW5hbFNhbXBsZVJhdGUsIHRoaXMuY29uZmlnLmVuY29kZXJTYW1wbGVSYXRlLCB0aGlzLmNvbmZpZy5yZXNhbXBsZVF1YWxpdHksIGVyckxvY2F0aW9uICk7XG4gIHRoaXMuX2ZyZWUoIGVyckxvY2F0aW9uICk7XG5cbiAgdGhpcy5yZXNhbXBsZUJ1ZmZlckluZGV4ID0gMDtcbiAgdGhpcy5yZXNhbXBsZVNhbXBsZXNQZXJDaGFubmVsID0gdGhpcy5jb25maWcub3JpZ2luYWxTYW1wbGVSYXRlICogdGhpcy5jb25maWcuZW5jb2RlckZyYW1lU2l6ZSAvIDEwMDA7XG4gIHRoaXMucmVzYW1wbGVTYW1wbGVzUGVyQ2hhbm5lbFBvaW50ZXIgPSB0aGlzLl9tYWxsb2MoIDQgKTtcbiAgdGhpcy5IRUFQMzJbIHRoaXMucmVzYW1wbGVTYW1wbGVzUGVyQ2hhbm5lbFBvaW50ZXIgPj4gMiBdID0gdGhpcy5yZXNhbXBsZVNhbXBsZXNQZXJDaGFubmVsO1xuXG4gIHRoaXMucmVzYW1wbGVCdWZmZXJMZW5ndGggPSB0aGlzLnJlc2FtcGxlU2FtcGxlc1BlckNoYW5uZWwgKiB0aGlzLmNvbmZpZy5udW1iZXJPZkNoYW5uZWxzO1xuICB0aGlzLnJlc2FtcGxlQnVmZmVyUG9pbnRlciA9IHRoaXMuX21hbGxvYyggdGhpcy5yZXNhbXBsZUJ1ZmZlckxlbmd0aCAqIDQgKTsgLy8gNCBieXRlcyBwZXIgc2FtcGxlXG4gIHRoaXMucmVzYW1wbGVCdWZmZXIgPSB0aGlzLkhFQVBGMzIuc3ViYXJyYXkoIHRoaXMucmVzYW1wbGVCdWZmZXJQb2ludGVyID4+IDIsICh0aGlzLnJlc2FtcGxlQnVmZmVyUG9pbnRlciA+PiAyKSArIHRoaXMucmVzYW1wbGVCdWZmZXJMZW5ndGggKTtcbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5pbnRlcmxlYXZlID0gZnVuY3Rpb24oIGJ1ZmZlcnMgKSB7XG4gIGZvciAoIHZhciBpID0gMDsgaSA8IHRoaXMuY29uZmlnLmJ1ZmZlckxlbmd0aDsgaSsrICkge1xuICAgIGZvciAoIHZhciBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY29uZmlnLm51bWJlck9mQ2hhbm5lbHM7IGNoYW5uZWwrKyApIHtcbiAgICAgIHRoaXMuaW50ZXJsZWF2ZWRCdWZmZXJzWyBpICogdGhpcy5jb25maWcubnVtYmVyT2ZDaGFubmVscyArIGNoYW5uZWwgXSA9IGJ1ZmZlcnNbIGNoYW5uZWwgXVsgaSBdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzLmludGVybGVhdmVkQnVmZmVycztcbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5zZWdtZW50UGFja2V0ID0gZnVuY3Rpb24oIHBhY2tldExlbmd0aCApIHtcbiAgdmFyIHBhY2tldEluZGV4ID0gMDtcblxuICB3aGlsZSAoIHBhY2tldExlbmd0aCA+PSAwICkge1xuXG4gICAgaWYgKCB0aGlzLnNlZ21lbnRUYWJsZUluZGV4ID09PSAyNTUgKSB7XG4gICAgICB0aGlzLmdlbmVyYXRlUGFnZSgpO1xuICAgICAgdGhpcy5oZWFkZXJUeXBlID0gMTtcbiAgICB9XG5cbiAgICB2YXIgc2VnbWVudExlbmd0aCA9IE1hdGgubWluKCBwYWNrZXRMZW5ndGgsIDI1NSApO1xuICAgIHRoaXMuc2VnbWVudFRhYmxlWyB0aGlzLnNlZ21lbnRUYWJsZUluZGV4KysgXSA9IHNlZ21lbnRMZW5ndGg7XG4gICAgdGhpcy5zZWdtZW50RGF0YS5zZXQoIHRoaXMuZW5jb2Rlck91dHB1dEJ1ZmZlci5zdWJhcnJheSggcGFja2V0SW5kZXgsIHBhY2tldEluZGV4ICsgc2VnbWVudExlbmd0aCApLCB0aGlzLnNlZ21lbnREYXRhSW5kZXggKTtcbiAgICB0aGlzLnNlZ21lbnREYXRhSW5kZXggKz0gc2VnbWVudExlbmd0aDtcbiAgICBwYWNrZXRJbmRleCArPSBzZWdtZW50TGVuZ3RoO1xuICAgIHBhY2tldExlbmd0aCAtPSAyNTU7XG4gIH1cblxuICB0aGlzLmdyYW51bGVQb3NpdGlvbiArPSAoIDQ4ICogdGhpcy5jb25maWcuZW5jb2RlckZyYW1lU2l6ZSApO1xuICBpZiAoIHRoaXMuc2VnbWVudFRhYmxlSW5kZXggPT09IDI1NSApIHtcbiAgICB0aGlzLmdlbmVyYXRlUGFnZSgpO1xuICAgIHRoaXMuaGVhZGVyVHlwZSA9IDA7XG4gIH1cbn07XG5cblxuaWYgKCFNb2R1bGUpIHtcbiAgTW9kdWxlID0ge307XG59XG5cbk1vZHVsZVsnbWFpblJlYWR5J10gPSBtYWluUmVhZHk7XG5Nb2R1bGVbJ09nZ09wdXNFbmNvZGVyJ10gPSBPZ2dPcHVzRW5jb2Rlcjtcbk1vZHVsZVsnb25SdW50aW1lSW5pdGlhbGl6ZWQnXSA9IG1haW5SZWFkeVJlc29sdmU7XG5cbm1vZHVsZS5leHBvcnRzID0gTW9kdWxlO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/encoderWorker.js\n"); +eval("/* WEBPACK VAR INJECTION */(function(global) {\n\nvar encoder;\nvar mainReadyResolve;\nvar mainReady = new Promise(function(resolve){ mainReadyResolve = resolve; });\n\nglobal['onmessage'] = function( e ){\n mainReady.then(function(){\n switch( e['data']['command'] ){\n\n case 'encode':\n if (encoder){\n encoder.encode( e['data']['buffers'] );\n }\n break;\n\n case 'done':\n if (encoder) {\n encoder.encodeFinalFrame();\n }\n break;\n\n case 'init':\n encoder = new OggOpusEncoder( e['data'], Module );\n break;\n\n default:\n // Ignore any unknown commands and continue recieving commands\n }\n });\n};\n\n\nvar OggOpusEncoder = function( config, Module ){\n\n if ( !Module ) {\n throw new Error('Module with exports required to initialize an encoder instance');\n }\n\n this.config = Object.assign({ \n bufferLength: 4096, // Define size of incoming buffer\n encoderApplication: 2049, // 2048 = Voice (Lower fidelity)\n // 2049 = Full Band Audio (Highest fidelity)\n // 2051 = Restricted Low Delay (Lowest latency)\n encoderFrameSize: 20, // Specified in ms.\n encoderSampleRate: 48000, // Desired encoding sample rate. Audio will be resampled\n maxBuffersPerPage: 40, // Tradeoff latency with overhead\n numberOfChannels: 1,\n originalSampleRate: 44100,\n resampleQuality: 3, // Value between 0 and 10 inclusive. 10 being highest quality.\n serial: Math.floor( Math.random() * (Math.pow(2,32) - 1) )\n }, config );\n\n this._opus_encoder_create = Module._opus_encoder_create;\n this._opus_encoder_ctl = Module._opus_encoder_ctl;\n this._speex_resampler_process_interleaved_float = Module._speex_resampler_process_interleaved_float;\n this._speex_resampler_init = Module._speex_resampler_init;\n this._opus_encode_float = Module._opus_encode_float;\n this._free = Module._free;\n this._malloc = Module._malloc;\n this.HEAPU8 = Module.HEAPU8;\n this.HEAP32 = Module.HEAP32;\n this.HEAPF32 = Module.HEAPF32;\n\n this.pageIndex = 0;\n this.granulePosition = 0;\n this.segmentData = new Uint8Array( 65025 ); // Maximum length of oggOpus data\n this.segmentDataIndex = 0;\n this.segmentTable = new Uint8Array( 255 ); // Maximum data segments\n this.segmentTableIndex = 0;\n this.buffersInPage = 0;\n\n this.initChecksumTable();\n this.initCodec();\n this.initResampler();\n this.generateIdPage();\n this.generateCommentPage();\n\n if ( this.config.numberOfChannels === 1 ) {\n this.interleave = function( buffers ) { return buffers[0]; };\n }\n else {\n this.interleavedBuffers = new Float32Array( this.config.bufferLength * this.config.numberOfChannels );\n }\n\n};\n\nOggOpusEncoder.prototype.encode = function( buffers ) {\n var samples = this.interleave( buffers );\n var sampleIndex = 0;\n\n while ( sampleIndex < samples.length ) {\n\n var lengthToCopy = Math.min( this.resampleBufferLength - this.resampleBufferIndex, samples.length - sampleIndex );\n this.resampleBuffer.set( samples.subarray( sampleIndex, sampleIndex+lengthToCopy ), this.resampleBufferIndex );\n sampleIndex += lengthToCopy;\n this.resampleBufferIndex += lengthToCopy;\n\n if ( this.resampleBufferIndex === this.resampleBufferLength ) {\n this._speex_resampler_process_interleaved_float( this.resampler, this.resampleBufferPointer, this.resampleSamplesPerChannelPointer, this.encoderBufferPointer, this.encoderSamplesPerChannelPointer );\n var packetLength = this._opus_encode_float( this.encoder, this.encoderBufferPointer, this.encoderSamplesPerChannel, this.encoderOutputPointer, this.encoderOutputMaxLength );\n this.segmentPacket( packetLength );\n this.resampleBufferIndex = 0;\n }\n }\n\n this.buffersInPage++;\n if ( this.buffersInPage >= this.config.maxBuffersPerPage ) {\n this.generatePage();\n }\n};\n\nOggOpusEncoder.prototype.encodeFinalFrame = function() {\n var finalFrameBuffers = [];\n for ( var i = 0; i < this.config.numberOfChannels; ++i ) {\n finalFrameBuffers.push( new Float32Array( this.config.bufferLength - (this.resampleBufferIndex / this.config.numberOfChannels) ));\n }\n this.encode( finalFrameBuffers );\n this.headerType += 4;\n this.generatePage();\n global['postMessage'](null);\n global['close']();\n};\n\nOggOpusEncoder.prototype.getChecksum = function( data ){\n var checksum = 0;\n for ( var i = 0; i < data.length; i++ ) {\n checksum = (checksum << 8) ^ this.checksumTable[ ((checksum>>>24) & 0xff) ^ data[i] ];\n }\n return checksum >>> 0;\n};\n\nOggOpusEncoder.prototype.generateCommentPage = function(){\n var segmentDataView = new DataView( this.segmentData.buffer );\n segmentDataView.setUint32( 0, 1937076303, true ) // Magic Signature 'Opus'\n segmentDataView.setUint32( 4, 1936154964, true ) // Magic Signature 'Tags'\n segmentDataView.setUint32( 8, 10, true ); // Vendor Length\n segmentDataView.setUint32( 12, 1868784978, true ); // Vendor name 'Reco'\n segmentDataView.setUint32( 16, 1919247474, true ); // Vendor name 'rder'\n segmentDataView.setUint16( 20, 21322, true ); // Vendor name 'JS'\n segmentDataView.setUint32( 22, 0, true ); // User Comment List Length\n this.segmentTableIndex = 1;\n this.segmentDataIndex = this.segmentTable[0] = 26;\n this.headerType = 0;\n this.generatePage();\n};\n\nOggOpusEncoder.prototype.generateIdPage = function(){\n var segmentDataView = new DataView( this.segmentData.buffer );\n segmentDataView.setUint32( 0, 1937076303, true ) // Magic Signature 'Opus'\n segmentDataView.setUint32( 4, 1684104520, true ) // Magic Signature 'Head'\n segmentDataView.setUint8( 8, 1, true ); // Version\n segmentDataView.setUint8( 9, this.config.numberOfChannels, true ); // Channel count\n segmentDataView.setUint16( 10, 3840, true ); // pre-skip (80ms)\n segmentDataView.setUint32( 12, this.config.originalSampleRateOverride || this.config.originalSampleRate, true ); // original sample rate\n segmentDataView.setUint16( 16, 0, true ); // output gain\n segmentDataView.setUint8( 18, 0, true ); // channel map 0 = mono or stereo\n this.segmentTableIndex = 1;\n this.segmentDataIndex = this.segmentTable[0] = 19;\n this.headerType = 2;\n this.generatePage();\n};\n\nOggOpusEncoder.prototype.generatePage = function(){\n var granulePosition = ( this.lastPositiveGranulePosition === this.granulePosition) ? -1 : this.granulePosition;\n var pageBuffer = new ArrayBuffer( 27 + this.segmentTableIndex + this.segmentDataIndex );\n var pageBufferView = new DataView( pageBuffer );\n var page = new Uint8Array( pageBuffer );\n\n pageBufferView.setUint32( 0, 1399285583, true); // Capture Pattern starts all page headers 'OggS'\n pageBufferView.setUint8( 4, 0, true ); // Version\n pageBufferView.setUint8( 5, this.headerType, true ); // 1 = continuation, 2 = beginning of stream, 4 = end of stream\n\n // Number of samples upto and including this page at 48000Hz, into signed 64 bit Little Endian integer\n // Javascript Number maximum value is 53 bits or 2^53 - 1 \n pageBufferView.setUint32( 6, granulePosition, true );\n if (granulePosition < 0) {\n pageBufferView.setInt32( 10, Math.ceil(granulePosition/4294967297) - 1, true );\n }\n else {\n pageBufferView.setInt32( 10, Math.floor(granulePosition/4294967296), true );\n }\n\n pageBufferView.setUint32( 14, this.config.serial, true ); // Bitstream serial number\n pageBufferView.setUint32( 18, this.pageIndex++, true ); // Page sequence number\n pageBufferView.setUint8( 26, this.segmentTableIndex, true ); // Number of segments in page.\n page.set( this.segmentTable.subarray(0, this.segmentTableIndex), 27 ); // Segment Table\n page.set( this.segmentData.subarray(0, this.segmentDataIndex), 27 + this.segmentTableIndex ); // Segment Data\n pageBufferView.setUint32( 22, this.getChecksum( page ), true ); // Checksum\n\n global['postMessage']( page, [page.buffer] );\n this.segmentTableIndex = 0;\n this.segmentDataIndex = 0;\n this.buffersInPage = 0;\n if ( granulePosition > 0 ) {\n this.lastPositiveGranulePosition = granulePosition;\n }\n};\n\nOggOpusEncoder.prototype.initChecksumTable = function(){\n this.checksumTable = [];\n for ( var i = 0; i < 256; i++ ) {\n var r = i << 24;\n for ( var j = 0; j < 8; j++ ) {\n r = ((r & 0x80000000) != 0) ? ((r << 1) ^ 0x04c11db7) : (r << 1);\n }\n this.checksumTable[i] = (r & 0xffffffff);\n }\n};\n\nOggOpusEncoder.prototype.setOpusControl = function( control, value ){\n var location = this._malloc( 4 );\n this.HEAP32[ location >> 2 ] = value;\n this._opus_encoder_ctl( this.encoder, control, location );\n this._free( location );\n};\n\nOggOpusEncoder.prototype.initCodec = function() {\n var errLocation = this._malloc( 4 );\n this.encoder = this._opus_encoder_create( this.config.encoderSampleRate, this.config.numberOfChannels, this.config.encoderApplication, errLocation );\n this._free( errLocation );\n\n if ( this.config.encoderBitRate ) {\n this.setOpusControl( 4002, this.config.encoderBitRate );\n }\n\n if ( this.config.encoderComplexity ) {\n this.setOpusControl( 4010, this.config.encoderComplexity );\n }\n\n this.encoderSamplesPerChannel = this.config.encoderSampleRate * this.config.encoderFrameSize / 1000;\n this.encoderSamplesPerChannelPointer = this._malloc( 4 );\n this.HEAP32[ this.encoderSamplesPerChannelPointer >> 2 ] = this.encoderSamplesPerChannel;\n\n this.encoderBufferLength = this.encoderSamplesPerChannel * this.config.numberOfChannels;\n this.encoderBufferPointer = this._malloc( this.encoderBufferLength * 4 ); // 4 bytes per sample\n this.encoderBuffer = this.HEAPF32.subarray( this.encoderBufferPointer >> 2, (this.encoderBufferPointer >> 2) + this.encoderBufferLength );\n\n this.encoderOutputMaxLength = 4000;\n this.encoderOutputPointer = this._malloc( this.encoderOutputMaxLength );\n this.encoderOutputBuffer = this.HEAPU8.subarray( this.encoderOutputPointer, this.encoderOutputPointer + this.encoderOutputMaxLength );\n};\n\nOggOpusEncoder.prototype.initResampler = function() {\n var errLocation = this._malloc( 4 );\n this.resampler = this._speex_resampler_init( this.config.numberOfChannels, this.config.originalSampleRate, this.config.encoderSampleRate, this.config.resampleQuality, errLocation );\n this._free( errLocation );\n\n this.resampleBufferIndex = 0;\n this.resampleSamplesPerChannel = this.config.originalSampleRate * this.config.encoderFrameSize / 1000;\n this.resampleSamplesPerChannelPointer = this._malloc( 4 );\n this.HEAP32[ this.resampleSamplesPerChannelPointer >> 2 ] = this.resampleSamplesPerChannel;\n\n this.resampleBufferLength = this.resampleSamplesPerChannel * this.config.numberOfChannels;\n this.resampleBufferPointer = this._malloc( this.resampleBufferLength * 4 ); // 4 bytes per sample\n this.resampleBuffer = this.HEAPF32.subarray( this.resampleBufferPointer >> 2, (this.resampleBufferPointer >> 2) + this.resampleBufferLength );\n};\n\nOggOpusEncoder.prototype.interleave = function( buffers ) {\n for ( var i = 0; i < this.config.bufferLength; i++ ) {\n for ( var channel = 0; channel < this.config.numberOfChannels; channel++ ) {\n this.interleavedBuffers[ i * this.config.numberOfChannels + channel ] = buffers[ channel ][ i ];\n }\n }\n\n return this.interleavedBuffers;\n};\n\nOggOpusEncoder.prototype.segmentPacket = function( packetLength ) {\n var packetIndex = 0;\n\n while ( packetLength >= 0 ) {\n\n if ( this.segmentTableIndex === 255 ) {\n this.generatePage();\n this.headerType = 1;\n }\n\n var segmentLength = Math.min( packetLength, 255 );\n this.segmentTable[ this.segmentTableIndex++ ] = segmentLength;\n this.segmentData.set( this.encoderOutputBuffer.subarray( packetIndex, packetIndex + segmentLength ), this.segmentDataIndex );\n this.segmentDataIndex += segmentLength;\n packetIndex += segmentLength;\n packetLength -= 255;\n }\n\n this.granulePosition += ( 48 * this.config.encoderFrameSize );\n if ( this.segmentTableIndex === 255 ) {\n this.generatePage();\n this.headerType = 0;\n }\n};\n\n\nif (!Module) {\n Module = {};\n}\n\nModule['mainReady'] = mainReady;\nModule['OggOpusEncoder'] = OggOpusEncoder;\nModule['onRuntimeInitialized'] = mainReadyResolve;\n\nmodule.exports = Module;\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvZW5jb2Rlcldvcmtlci5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0VuY29kZXJXb3JrZXIvLi9zcmMvZW5jb2Rlcldvcmtlci5qcz84YjNjIl0sInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG52YXIgZW5jb2RlcjtcbnZhciBtYWluUmVhZHlSZXNvbHZlO1xudmFyIG1haW5SZWFkeSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpeyBtYWluUmVhZHlSZXNvbHZlID0gcmVzb2x2ZTsgfSk7XG5cbmdsb2JhbFsnb25tZXNzYWdlJ10gPSBmdW5jdGlvbiggZSApe1xuICBtYWluUmVhZHkudGhlbihmdW5jdGlvbigpe1xuICAgIHN3aXRjaCggZVsnZGF0YSddWydjb21tYW5kJ10gKXtcblxuICAgICAgY2FzZSAnZW5jb2RlJzpcbiAgICAgICAgaWYgKGVuY29kZXIpe1xuICAgICAgICAgIGVuY29kZXIuZW5jb2RlKCBlWydkYXRhJ11bJ2J1ZmZlcnMnXSApO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdkb25lJzpcbiAgICAgICAgaWYgKGVuY29kZXIpIHtcbiAgICAgICAgICBlbmNvZGVyLmVuY29kZUZpbmFsRnJhbWUoKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnaW5pdCc6XG4gICAgICAgIGVuY29kZXIgPSBuZXcgT2dnT3B1c0VuY29kZXIoIGVbJ2RhdGEnXSwgTW9kdWxlICk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyBJZ25vcmUgYW55IHVua25vd24gY29tbWFuZHMgYW5kIGNvbnRpbnVlIHJlY2lldmluZyBjb21tYW5kc1xuICAgIH1cbiAgfSk7XG59O1xuXG5cbnZhciBPZ2dPcHVzRW5jb2RlciA9IGZ1bmN0aW9uKCBjb25maWcsIE1vZHVsZSApe1xuXG4gIGlmICggIU1vZHVsZSApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01vZHVsZSB3aXRoIGV4cG9ydHMgcmVxdWlyZWQgdG8gaW5pdGlhbGl6ZSBhbiBlbmNvZGVyIGluc3RhbmNlJyk7XG4gIH1cblxuICB0aGlzLmNvbmZpZyA9IE9iamVjdC5hc3NpZ24oeyBcbiAgICBidWZmZXJMZW5ndGg6IDQwOTYsIC8vIERlZmluZSBzaXplIG9mIGluY29taW5nIGJ1ZmZlclxuICAgIGVuY29kZXJBcHBsaWNhdGlvbjogMjA0OSwgLy8gMjA0OCA9IFZvaWNlIChMb3dlciBmaWRlbGl0eSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDIwNDkgPSBGdWxsIEJhbmQgQXVkaW8gKEhpZ2hlc3QgZmlkZWxpdHkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAyMDUxID0gUmVzdHJpY3RlZCBMb3cgRGVsYXkgKExvd2VzdCBsYXRlbmN5KVxuICAgIGVuY29kZXJGcmFtZVNpemU6IDIwLCAvLyBTcGVjaWZpZWQgaW4gbXMuXG4gICAgZW5jb2RlclNhbXBsZVJhdGU6IDQ4MDAwLCAvLyBEZXNpcmVkIGVuY29kaW5nIHNhbXBsZSByYXRlLiBBdWRpbyB3aWxsIGJlIHJlc2FtcGxlZFxuICAgIG1heEJ1ZmZlcnNQZXJQYWdlOiA0MCwgLy8gVHJhZGVvZmYgbGF0ZW5jeSB3aXRoIG92ZXJoZWFkXG4gICAgbnVtYmVyT2ZDaGFubmVsczogMSxcbiAgICBvcmlnaW5hbFNhbXBsZVJhdGU6IDQ0MTAwLFxuICAgIHJlc2FtcGxlUXVhbGl0eTogMywgLy8gVmFsdWUgYmV0d2VlbiAwIGFuZCAxMCBpbmNsdXNpdmUuIDEwIGJlaW5nIGhpZ2hlc3QgcXVhbGl0eS5cbiAgICBzZXJpYWw6IE1hdGguZmxvb3IoIE1hdGgucmFuZG9tKCkgKiAoTWF0aC5wb3coMiwzMikgLSAxKSApXG4gIH0sIGNvbmZpZyApO1xuXG4gIHRoaXMuX29wdXNfZW5jb2Rlcl9jcmVhdGUgPSBNb2R1bGUuX29wdXNfZW5jb2Rlcl9jcmVhdGU7XG4gIHRoaXMuX29wdXNfZW5jb2Rlcl9jdGwgPSBNb2R1bGUuX29wdXNfZW5jb2Rlcl9jdGw7XG4gIHRoaXMuX3NwZWV4X3Jlc2FtcGxlcl9wcm9jZXNzX2ludGVybGVhdmVkX2Zsb2F0ID0gTW9kdWxlLl9zcGVleF9yZXNhbXBsZXJfcHJvY2Vzc19pbnRlcmxlYXZlZF9mbG9hdDtcbiAgdGhpcy5fc3BlZXhfcmVzYW1wbGVyX2luaXQgPSBNb2R1bGUuX3NwZWV4X3Jlc2FtcGxlcl9pbml0O1xuICB0aGlzLl9vcHVzX2VuY29kZV9mbG9hdCA9IE1vZHVsZS5fb3B1c19lbmNvZGVfZmxvYXQ7XG4gIHRoaXMuX2ZyZWUgPSBNb2R1bGUuX2ZyZWU7XG4gIHRoaXMuX21hbGxvYyA9IE1vZHVsZS5fbWFsbG9jO1xuICB0aGlzLkhFQVBVOCA9IE1vZHVsZS5IRUFQVTg7XG4gIHRoaXMuSEVBUDMyID0gTW9kdWxlLkhFQVAzMjtcbiAgdGhpcy5IRUFQRjMyID0gTW9kdWxlLkhFQVBGMzI7XG5cbiAgdGhpcy5wYWdlSW5kZXggPSAwO1xuICB0aGlzLmdyYW51bGVQb3NpdGlvbiA9IDA7XG4gIHRoaXMuc2VnbWVudERhdGEgPSBuZXcgVWludDhBcnJheSggNjUwMjUgKTsgLy8gTWF4aW11bSBsZW5ndGggb2Ygb2dnT3B1cyBkYXRhXG4gIHRoaXMuc2VnbWVudERhdGFJbmRleCA9IDA7XG4gIHRoaXMuc2VnbWVudFRhYmxlID0gbmV3IFVpbnQ4QXJyYXkoIDI1NSApOyAvLyBNYXhpbXVtIGRhdGEgc2VnbWVudHNcbiAgdGhpcy5zZWdtZW50VGFibGVJbmRleCA9IDA7XG4gIHRoaXMuYnVmZmVyc0luUGFnZSA9IDA7XG5cbiAgdGhpcy5pbml0Q2hlY2tzdW1UYWJsZSgpO1xuICB0aGlzLmluaXRDb2RlYygpO1xuICB0aGlzLmluaXRSZXNhbXBsZXIoKTtcbiAgdGhpcy5nZW5lcmF0ZUlkUGFnZSgpO1xuICB0aGlzLmdlbmVyYXRlQ29tbWVudFBhZ2UoKTtcblxuICBpZiAoIHRoaXMuY29uZmlnLm51bWJlck9mQ2hhbm5lbHMgPT09IDEgKSB7XG4gICAgdGhpcy5pbnRlcmxlYXZlID0gZnVuY3Rpb24oIGJ1ZmZlcnMgKSB7IHJldHVybiBidWZmZXJzWzBdOyB9O1xuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMuaW50ZXJsZWF2ZWRCdWZmZXJzID0gbmV3IEZsb2F0MzJBcnJheSggdGhpcy5jb25maWcuYnVmZmVyTGVuZ3RoICogdGhpcy5jb25maWcubnVtYmVyT2ZDaGFubmVscyApO1xuICB9XG5cbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5lbmNvZGUgPSBmdW5jdGlvbiggYnVmZmVycyApIHtcbiAgdmFyIHNhbXBsZXMgPSB0aGlzLmludGVybGVhdmUoIGJ1ZmZlcnMgKTtcbiAgdmFyIHNhbXBsZUluZGV4ID0gMDtcblxuICB3aGlsZSAoIHNhbXBsZUluZGV4IDwgc2FtcGxlcy5sZW5ndGggKSB7XG5cbiAgICB2YXIgbGVuZ3RoVG9Db3B5ID0gTWF0aC5taW4oIHRoaXMucmVzYW1wbGVCdWZmZXJMZW5ndGggLSB0aGlzLnJlc2FtcGxlQnVmZmVySW5kZXgsIHNhbXBsZXMubGVuZ3RoIC0gc2FtcGxlSW5kZXggKTtcbiAgICB0aGlzLnJlc2FtcGxlQnVmZmVyLnNldCggc2FtcGxlcy5zdWJhcnJheSggc2FtcGxlSW5kZXgsIHNhbXBsZUluZGV4K2xlbmd0aFRvQ29weSApLCB0aGlzLnJlc2FtcGxlQnVmZmVySW5kZXggKTtcbiAgICBzYW1wbGVJbmRleCArPSBsZW5ndGhUb0NvcHk7XG4gICAgdGhpcy5yZXNhbXBsZUJ1ZmZlckluZGV4ICs9IGxlbmd0aFRvQ29weTtcblxuICAgIGlmICggdGhpcy5yZXNhbXBsZUJ1ZmZlckluZGV4ID09PSB0aGlzLnJlc2FtcGxlQnVmZmVyTGVuZ3RoICkge1xuICAgICAgdGhpcy5fc3BlZXhfcmVzYW1wbGVyX3Byb2Nlc3NfaW50ZXJsZWF2ZWRfZmxvYXQoIHRoaXMucmVzYW1wbGVyLCB0aGlzLnJlc2FtcGxlQnVmZmVyUG9pbnRlciwgdGhpcy5yZXNhbXBsZVNhbXBsZXNQZXJDaGFubmVsUG9pbnRlciwgdGhpcy5lbmNvZGVyQnVmZmVyUG9pbnRlciwgdGhpcy5lbmNvZGVyU2FtcGxlc1BlckNoYW5uZWxQb2ludGVyICk7XG4gICAgICB2YXIgcGFja2V0TGVuZ3RoID0gdGhpcy5fb3B1c19lbmNvZGVfZmxvYXQoIHRoaXMuZW5jb2RlciwgdGhpcy5lbmNvZGVyQnVmZmVyUG9pbnRlciwgdGhpcy5lbmNvZGVyU2FtcGxlc1BlckNoYW5uZWwsIHRoaXMuZW5jb2Rlck91dHB1dFBvaW50ZXIsIHRoaXMuZW5jb2Rlck91dHB1dE1heExlbmd0aCApO1xuICAgICAgdGhpcy5zZWdtZW50UGFja2V0KCBwYWNrZXRMZW5ndGggKTtcbiAgICAgIHRoaXMucmVzYW1wbGVCdWZmZXJJbmRleCA9IDA7XG4gICAgfVxuICB9XG5cbiAgdGhpcy5idWZmZXJzSW5QYWdlKys7XG4gIGlmICggdGhpcy5idWZmZXJzSW5QYWdlID49IHRoaXMuY29uZmlnLm1heEJ1ZmZlcnNQZXJQYWdlICkge1xuICAgIHRoaXMuZ2VuZXJhdGVQYWdlKCk7XG4gIH1cbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5lbmNvZGVGaW5hbEZyYW1lID0gZnVuY3Rpb24oKSB7XG4gIHZhciBmaW5hbEZyYW1lQnVmZmVycyA9IFtdO1xuICBmb3IgKCB2YXIgaSA9IDA7IGkgPCB0aGlzLmNvbmZpZy5udW1iZXJPZkNoYW5uZWxzOyArK2kgKSB7XG4gICAgZmluYWxGcmFtZUJ1ZmZlcnMucHVzaCggbmV3IEZsb2F0MzJBcnJheSggdGhpcy5jb25maWcuYnVmZmVyTGVuZ3RoIC0gKHRoaXMucmVzYW1wbGVCdWZmZXJJbmRleCAvIHRoaXMuY29uZmlnLm51bWJlck9mQ2hhbm5lbHMpICkpO1xuICB9XG4gIHRoaXMuZW5jb2RlKCBmaW5hbEZyYW1lQnVmZmVycyApO1xuICB0aGlzLmhlYWRlclR5cGUgKz0gNDtcbiAgdGhpcy5nZW5lcmF0ZVBhZ2UoKTtcbiAgZ2xvYmFsWydwb3N0TWVzc2FnZSddKG51bGwpO1xuICBnbG9iYWxbJ2Nsb3NlJ10oKTtcbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5nZXRDaGVja3N1bSA9IGZ1bmN0aW9uKCBkYXRhICl7XG4gIHZhciBjaGVja3N1bSA9IDA7XG4gIGZvciAoIHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKysgKSB7XG4gICAgY2hlY2tzdW0gPSAoY2hlY2tzdW0gPDwgOCkgXiB0aGlzLmNoZWNrc3VtVGFibGVbICgoY2hlY2tzdW0+Pj4yNCkgJiAweGZmKSBeIGRhdGFbaV0gXTtcbiAgfVxuICByZXR1cm4gY2hlY2tzdW0gPj4+IDA7XG59O1xuXG5PZ2dPcHVzRW5jb2Rlci5wcm90b3R5cGUuZ2VuZXJhdGVDb21tZW50UGFnZSA9IGZ1bmN0aW9uKCl7XG4gIHZhciBzZWdtZW50RGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoIHRoaXMuc2VnbWVudERhdGEuYnVmZmVyICk7XG4gIHNlZ21lbnREYXRhVmlldy5zZXRVaW50MzIoIDAsIDE5MzcwNzYzMDMsIHRydWUgKSAvLyBNYWdpYyBTaWduYXR1cmUgJ09wdXMnXG4gIHNlZ21lbnREYXRhVmlldy5zZXRVaW50MzIoIDQsIDE5MzYxNTQ5NjQsIHRydWUgKSAvLyBNYWdpYyBTaWduYXR1cmUgJ1RhZ3MnXG4gIHNlZ21lbnREYXRhVmlldy5zZXRVaW50MzIoIDgsIDEwLCB0cnVlICk7IC8vIFZlbmRvciBMZW5ndGhcbiAgc2VnbWVudERhdGFWaWV3LnNldFVpbnQzMiggMTIsIDE4Njg3ODQ5NzgsIHRydWUgKTsgLy8gVmVuZG9yIG5hbWUgJ1JlY28nXG4gIHNlZ21lbnREYXRhVmlldy5zZXRVaW50MzIoIDE2LCAxOTE5MjQ3NDc0LCB0cnVlICk7IC8vIFZlbmRvciBuYW1lICdyZGVyJ1xuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDE2KCAyMCwgMjEzMjIsIHRydWUgKTsgLy8gVmVuZG9yIG5hbWUgJ0pTJ1xuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDMyKCAyMiwgMCwgdHJ1ZSApOyAvLyBVc2VyIENvbW1lbnQgTGlzdCBMZW5ndGhcbiAgdGhpcy5zZWdtZW50VGFibGVJbmRleCA9IDE7XG4gIHRoaXMuc2VnbWVudERhdGFJbmRleCA9IHRoaXMuc2VnbWVudFRhYmxlWzBdID0gMjY7XG4gIHRoaXMuaGVhZGVyVHlwZSA9IDA7XG4gIHRoaXMuZ2VuZXJhdGVQYWdlKCk7XG59O1xuXG5PZ2dPcHVzRW5jb2Rlci5wcm90b3R5cGUuZ2VuZXJhdGVJZFBhZ2UgPSBmdW5jdGlvbigpe1xuICB2YXIgc2VnbWVudERhdGFWaWV3ID0gbmV3IERhdGFWaWV3KCB0aGlzLnNlZ21lbnREYXRhLmJ1ZmZlciApO1xuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDMyKCAwLCAxOTM3MDc2MzAzLCB0cnVlICkgLy8gTWFnaWMgU2lnbmF0dXJlICdPcHVzJ1xuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDMyKCA0LCAxNjg0MTA0NTIwLCB0cnVlICkgLy8gTWFnaWMgU2lnbmF0dXJlICdIZWFkJ1xuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDgoIDgsIDEsIHRydWUgKTsgLy8gVmVyc2lvblxuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDgoIDksIHRoaXMuY29uZmlnLm51bWJlck9mQ2hhbm5lbHMsIHRydWUgKTsgLy8gQ2hhbm5lbCBjb3VudFxuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDE2KCAxMCwgMzg0MCwgdHJ1ZSApOyAvLyBwcmUtc2tpcCAoODBtcylcbiAgc2VnbWVudERhdGFWaWV3LnNldFVpbnQzMiggMTIsIHRoaXMuY29uZmlnLm9yaWdpbmFsU2FtcGxlUmF0ZU92ZXJyaWRlIHx8IHRoaXMuY29uZmlnLm9yaWdpbmFsU2FtcGxlUmF0ZSwgdHJ1ZSApOyAvLyBvcmlnaW5hbCBzYW1wbGUgcmF0ZVxuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDE2KCAxNiwgMCwgdHJ1ZSApOyAvLyBvdXRwdXQgZ2FpblxuICBzZWdtZW50RGF0YVZpZXcuc2V0VWludDgoIDE4LCAwLCB0cnVlICk7IC8vIGNoYW5uZWwgbWFwIDAgPSBtb25vIG9yIHN0ZXJlb1xuICB0aGlzLnNlZ21lbnRUYWJsZUluZGV4ID0gMTtcbiAgdGhpcy5zZWdtZW50RGF0YUluZGV4ID0gdGhpcy5zZWdtZW50VGFibGVbMF0gPSAxOTtcbiAgdGhpcy5oZWFkZXJUeXBlID0gMjtcbiAgdGhpcy5nZW5lcmF0ZVBhZ2UoKTtcbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5nZW5lcmF0ZVBhZ2UgPSBmdW5jdGlvbigpe1xuICB2YXIgZ3JhbnVsZVBvc2l0aW9uID0gKCB0aGlzLmxhc3RQb3NpdGl2ZUdyYW51bGVQb3NpdGlvbiA9PT0gdGhpcy5ncmFudWxlUG9zaXRpb24pID8gLTEgOiB0aGlzLmdyYW51bGVQb3NpdGlvbjtcbiAgdmFyIHBhZ2VCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoICAyNyArIHRoaXMuc2VnbWVudFRhYmxlSW5kZXggKyB0aGlzLnNlZ21lbnREYXRhSW5kZXggKTtcbiAgdmFyIHBhZ2VCdWZmZXJWaWV3ID0gbmV3IERhdGFWaWV3KCBwYWdlQnVmZmVyICk7XG4gIHZhciBwYWdlID0gbmV3IFVpbnQ4QXJyYXkoIHBhZ2VCdWZmZXIgKTtcblxuICBwYWdlQnVmZmVyVmlldy5zZXRVaW50MzIoIDAsIDEzOTkyODU1ODMsIHRydWUpOyAvLyBDYXB0dXJlIFBhdHRlcm4gc3RhcnRzIGFsbCBwYWdlIGhlYWRlcnMgJ09nZ1MnXG4gIHBhZ2VCdWZmZXJWaWV3LnNldFVpbnQ4KCA0LCAwLCB0cnVlICk7IC8vIFZlcnNpb25cbiAgcGFnZUJ1ZmZlclZpZXcuc2V0VWludDgoIDUsIHRoaXMuaGVhZGVyVHlwZSwgdHJ1ZSApOyAvLyAxID0gY29udGludWF0aW9uLCAyID0gYmVnaW5uaW5nIG9mIHN0cmVhbSwgNCA9IGVuZCBvZiBzdHJlYW1cblxuICAvLyBOdW1iZXIgb2Ygc2FtcGxlcyB1cHRvIGFuZCBpbmNsdWRpbmcgdGhpcyBwYWdlIGF0IDQ4MDAwSHosIGludG8gc2lnbmVkIDY0IGJpdCBMaXR0bGUgRW5kaWFuIGludGVnZXJcbiAgLy8gSmF2YXNjcmlwdCBOdW1iZXIgbWF4aW11bSB2YWx1ZSBpcyA1MyBiaXRzIG9yIDJeNTMgLSAxIFxuICBwYWdlQnVmZmVyVmlldy5zZXRVaW50MzIoIDYsIGdyYW51bGVQb3NpdGlvbiwgdHJ1ZSApO1xuICBpZiAoZ3JhbnVsZVBvc2l0aW9uIDwgMCkge1xuICAgIHBhZ2VCdWZmZXJWaWV3LnNldEludDMyKCAxMCwgTWF0aC5jZWlsKGdyYW51bGVQb3NpdGlvbi80Mjk0OTY3Mjk3KSAtIDEsIHRydWUgKTtcbiAgfVxuICBlbHNlIHtcbiAgICBwYWdlQnVmZmVyVmlldy5zZXRJbnQzMiggMTAsIE1hdGguZmxvb3IoZ3JhbnVsZVBvc2l0aW9uLzQyOTQ5NjcyOTYpLCB0cnVlICk7XG4gIH1cblxuICBwYWdlQnVmZmVyVmlldy5zZXRVaW50MzIoIDE0LCB0aGlzLmNvbmZpZy5zZXJpYWwsIHRydWUgKTsgLy8gQml0c3RyZWFtIHNlcmlhbCBudW1iZXJcbiAgcGFnZUJ1ZmZlclZpZXcuc2V0VWludDMyKCAxOCwgdGhpcy5wYWdlSW5kZXgrKywgdHJ1ZSApOyAvLyBQYWdlIHNlcXVlbmNlIG51bWJlclxuICBwYWdlQnVmZmVyVmlldy5zZXRVaW50OCggMjYsIHRoaXMuc2VnbWVudFRhYmxlSW5kZXgsIHRydWUgKTsgLy8gTnVtYmVyIG9mIHNlZ21lbnRzIGluIHBhZ2UuXG4gIHBhZ2Uuc2V0KCB0aGlzLnNlZ21lbnRUYWJsZS5zdWJhcnJheSgwLCB0aGlzLnNlZ21lbnRUYWJsZUluZGV4KSwgMjcgKTsgLy8gU2VnbWVudCBUYWJsZVxuICBwYWdlLnNldCggdGhpcy5zZWdtZW50RGF0YS5zdWJhcnJheSgwLCB0aGlzLnNlZ21lbnREYXRhSW5kZXgpLCAyNyArIHRoaXMuc2VnbWVudFRhYmxlSW5kZXggKTsgLy8gU2VnbWVudCBEYXRhXG4gIHBhZ2VCdWZmZXJWaWV3LnNldFVpbnQzMiggMjIsIHRoaXMuZ2V0Q2hlY2tzdW0oIHBhZ2UgKSwgdHJ1ZSApOyAvLyBDaGVja3N1bVxuXG4gIGdsb2JhbFsncG9zdE1lc3NhZ2UnXSggcGFnZSwgW3BhZ2UuYnVmZmVyXSApO1xuICB0aGlzLnNlZ21lbnRUYWJsZUluZGV4ID0gMDtcbiAgdGhpcy5zZWdtZW50RGF0YUluZGV4ID0gMDtcbiAgdGhpcy5idWZmZXJzSW5QYWdlID0gMDtcbiAgaWYgKCBncmFudWxlUG9zaXRpb24gPiAwICkge1xuICAgIHRoaXMubGFzdFBvc2l0aXZlR3JhbnVsZVBvc2l0aW9uID0gZ3JhbnVsZVBvc2l0aW9uO1xuICB9XG59O1xuXG5PZ2dPcHVzRW5jb2Rlci5wcm90b3R5cGUuaW5pdENoZWNrc3VtVGFibGUgPSBmdW5jdGlvbigpe1xuICB0aGlzLmNoZWNrc3VtVGFibGUgPSBbXTtcbiAgZm9yICggdmFyIGkgPSAwOyBpIDwgMjU2OyBpKysgKSB7XG4gICAgdmFyIHIgPSBpIDw8IDI0O1xuICAgIGZvciAoIHZhciBqID0gMDsgaiA8IDg7IGorKyApIHtcbiAgICAgIHIgPSAoKHIgJiAweDgwMDAwMDAwKSAhPSAwKSA/ICgociA8PCAxKSBeIDB4MDRjMTFkYjcpIDogKHIgPDwgMSk7XG4gICAgfVxuICAgIHRoaXMuY2hlY2tzdW1UYWJsZVtpXSA9IChyICYgMHhmZmZmZmZmZik7XG4gIH1cbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5zZXRPcHVzQ29udHJvbCA9IGZ1bmN0aW9uKCBjb250cm9sLCB2YWx1ZSApe1xuICB2YXIgbG9jYXRpb24gPSB0aGlzLl9tYWxsb2MoIDQgKTtcbiAgdGhpcy5IRUFQMzJbIGxvY2F0aW9uID4+IDIgXSA9IHZhbHVlO1xuICB0aGlzLl9vcHVzX2VuY29kZXJfY3RsKCB0aGlzLmVuY29kZXIsIGNvbnRyb2wsIGxvY2F0aW9uICk7XG4gIHRoaXMuX2ZyZWUoIGxvY2F0aW9uICk7XG59O1xuXG5PZ2dPcHVzRW5jb2Rlci5wcm90b3R5cGUuaW5pdENvZGVjID0gZnVuY3Rpb24oKSB7XG4gIHZhciBlcnJMb2NhdGlvbiA9IHRoaXMuX21hbGxvYyggNCApO1xuICB0aGlzLmVuY29kZXIgPSB0aGlzLl9vcHVzX2VuY29kZXJfY3JlYXRlKCB0aGlzLmNvbmZpZy5lbmNvZGVyU2FtcGxlUmF0ZSwgdGhpcy5jb25maWcubnVtYmVyT2ZDaGFubmVscywgdGhpcy5jb25maWcuZW5jb2RlckFwcGxpY2F0aW9uLCBlcnJMb2NhdGlvbiApO1xuICB0aGlzLl9mcmVlKCBlcnJMb2NhdGlvbiApO1xuXG4gIGlmICggdGhpcy5jb25maWcuZW5jb2RlckJpdFJhdGUgKSB7XG4gICAgdGhpcy5zZXRPcHVzQ29udHJvbCggNDAwMiwgdGhpcy5jb25maWcuZW5jb2RlckJpdFJhdGUgKTtcbiAgfVxuXG4gIGlmICggdGhpcy5jb25maWcuZW5jb2RlckNvbXBsZXhpdHkgKSB7XG4gICAgdGhpcy5zZXRPcHVzQ29udHJvbCggNDAxMCwgdGhpcy5jb25maWcuZW5jb2RlckNvbXBsZXhpdHkgKTtcbiAgfVxuXG4gIHRoaXMuZW5jb2RlclNhbXBsZXNQZXJDaGFubmVsID0gdGhpcy5jb25maWcuZW5jb2RlclNhbXBsZVJhdGUgKiB0aGlzLmNvbmZpZy5lbmNvZGVyRnJhbWVTaXplIC8gMTAwMDtcbiAgdGhpcy5lbmNvZGVyU2FtcGxlc1BlckNoYW5uZWxQb2ludGVyID0gdGhpcy5fbWFsbG9jKCA0ICk7XG4gIHRoaXMuSEVBUDMyWyB0aGlzLmVuY29kZXJTYW1wbGVzUGVyQ2hhbm5lbFBvaW50ZXIgPj4gMiBdID0gdGhpcy5lbmNvZGVyU2FtcGxlc1BlckNoYW5uZWw7XG5cbiAgdGhpcy5lbmNvZGVyQnVmZmVyTGVuZ3RoID0gdGhpcy5lbmNvZGVyU2FtcGxlc1BlckNoYW5uZWwgKiB0aGlzLmNvbmZpZy5udW1iZXJPZkNoYW5uZWxzO1xuICB0aGlzLmVuY29kZXJCdWZmZXJQb2ludGVyID0gdGhpcy5fbWFsbG9jKCB0aGlzLmVuY29kZXJCdWZmZXJMZW5ndGggKiA0ICk7IC8vIDQgYnl0ZXMgcGVyIHNhbXBsZVxuICB0aGlzLmVuY29kZXJCdWZmZXIgPSB0aGlzLkhFQVBGMzIuc3ViYXJyYXkoIHRoaXMuZW5jb2RlckJ1ZmZlclBvaW50ZXIgPj4gMiwgKHRoaXMuZW5jb2RlckJ1ZmZlclBvaW50ZXIgPj4gMikgKyB0aGlzLmVuY29kZXJCdWZmZXJMZW5ndGggKTtcblxuICB0aGlzLmVuY29kZXJPdXRwdXRNYXhMZW5ndGggPSA0MDAwO1xuICB0aGlzLmVuY29kZXJPdXRwdXRQb2ludGVyID0gdGhpcy5fbWFsbG9jKCB0aGlzLmVuY29kZXJPdXRwdXRNYXhMZW5ndGggKTtcbiAgdGhpcy5lbmNvZGVyT3V0cHV0QnVmZmVyID0gdGhpcy5IRUFQVTguc3ViYXJyYXkoIHRoaXMuZW5jb2Rlck91dHB1dFBvaW50ZXIsIHRoaXMuZW5jb2Rlck91dHB1dFBvaW50ZXIgKyB0aGlzLmVuY29kZXJPdXRwdXRNYXhMZW5ndGggKTtcbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5pbml0UmVzYW1wbGVyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBlcnJMb2NhdGlvbiA9IHRoaXMuX21hbGxvYyggNCApO1xuICB0aGlzLnJlc2FtcGxlciA9IHRoaXMuX3NwZWV4X3Jlc2FtcGxlcl9pbml0KCB0aGlzLmNvbmZpZy5udW1iZXJPZkNoYW5uZWxzLCB0aGlzLmNvbmZpZy5vcmlnaW5hbFNhbXBsZVJhdGUsIHRoaXMuY29uZmlnLmVuY29kZXJTYW1wbGVSYXRlLCB0aGlzLmNvbmZpZy5yZXNhbXBsZVF1YWxpdHksIGVyckxvY2F0aW9uICk7XG4gIHRoaXMuX2ZyZWUoIGVyckxvY2F0aW9uICk7XG5cbiAgdGhpcy5yZXNhbXBsZUJ1ZmZlckluZGV4ID0gMDtcbiAgdGhpcy5yZXNhbXBsZVNhbXBsZXNQZXJDaGFubmVsID0gdGhpcy5jb25maWcub3JpZ2luYWxTYW1wbGVSYXRlICogdGhpcy5jb25maWcuZW5jb2RlckZyYW1lU2l6ZSAvIDEwMDA7XG4gIHRoaXMucmVzYW1wbGVTYW1wbGVzUGVyQ2hhbm5lbFBvaW50ZXIgPSB0aGlzLl9tYWxsb2MoIDQgKTtcbiAgdGhpcy5IRUFQMzJbIHRoaXMucmVzYW1wbGVTYW1wbGVzUGVyQ2hhbm5lbFBvaW50ZXIgPj4gMiBdID0gdGhpcy5yZXNhbXBsZVNhbXBsZXNQZXJDaGFubmVsO1xuXG4gIHRoaXMucmVzYW1wbGVCdWZmZXJMZW5ndGggPSB0aGlzLnJlc2FtcGxlU2FtcGxlc1BlckNoYW5uZWwgKiB0aGlzLmNvbmZpZy5udW1iZXJPZkNoYW5uZWxzO1xuICB0aGlzLnJlc2FtcGxlQnVmZmVyUG9pbnRlciA9IHRoaXMuX21hbGxvYyggdGhpcy5yZXNhbXBsZUJ1ZmZlckxlbmd0aCAqIDQgKTsgLy8gNCBieXRlcyBwZXIgc2FtcGxlXG4gIHRoaXMucmVzYW1wbGVCdWZmZXIgPSB0aGlzLkhFQVBGMzIuc3ViYXJyYXkoIHRoaXMucmVzYW1wbGVCdWZmZXJQb2ludGVyID4+IDIsICh0aGlzLnJlc2FtcGxlQnVmZmVyUG9pbnRlciA+PiAyKSArIHRoaXMucmVzYW1wbGVCdWZmZXJMZW5ndGggKTtcbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5pbnRlcmxlYXZlID0gZnVuY3Rpb24oIGJ1ZmZlcnMgKSB7XG4gIGZvciAoIHZhciBpID0gMDsgaSA8IHRoaXMuY29uZmlnLmJ1ZmZlckxlbmd0aDsgaSsrICkge1xuICAgIGZvciAoIHZhciBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY29uZmlnLm51bWJlck9mQ2hhbm5lbHM7IGNoYW5uZWwrKyApIHtcbiAgICAgIHRoaXMuaW50ZXJsZWF2ZWRCdWZmZXJzWyBpICogdGhpcy5jb25maWcubnVtYmVyT2ZDaGFubmVscyArIGNoYW5uZWwgXSA9IGJ1ZmZlcnNbIGNoYW5uZWwgXVsgaSBdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzLmludGVybGVhdmVkQnVmZmVycztcbn07XG5cbk9nZ09wdXNFbmNvZGVyLnByb3RvdHlwZS5zZWdtZW50UGFja2V0ID0gZnVuY3Rpb24oIHBhY2tldExlbmd0aCApIHtcbiAgdmFyIHBhY2tldEluZGV4ID0gMDtcblxuICB3aGlsZSAoIHBhY2tldExlbmd0aCA+PSAwICkge1xuXG4gICAgaWYgKCB0aGlzLnNlZ21lbnRUYWJsZUluZGV4ID09PSAyNTUgKSB7XG4gICAgICB0aGlzLmdlbmVyYXRlUGFnZSgpO1xuICAgICAgdGhpcy5oZWFkZXJUeXBlID0gMTtcbiAgICB9XG5cbiAgICB2YXIgc2VnbWVudExlbmd0aCA9IE1hdGgubWluKCBwYWNrZXRMZW5ndGgsIDI1NSApO1xuICAgIHRoaXMuc2VnbWVudFRhYmxlWyB0aGlzLnNlZ21lbnRUYWJsZUluZGV4KysgXSA9IHNlZ21lbnRMZW5ndGg7XG4gICAgdGhpcy5zZWdtZW50RGF0YS5zZXQoIHRoaXMuZW5jb2Rlck91dHB1dEJ1ZmZlci5zdWJhcnJheSggcGFja2V0SW5kZXgsIHBhY2tldEluZGV4ICsgc2VnbWVudExlbmd0aCApLCB0aGlzLnNlZ21lbnREYXRhSW5kZXggKTtcbiAgICB0aGlzLnNlZ21lbnREYXRhSW5kZXggKz0gc2VnbWVudExlbmd0aDtcbiAgICBwYWNrZXRJbmRleCArPSBzZWdtZW50TGVuZ3RoO1xuICAgIHBhY2tldExlbmd0aCAtPSAyNTU7XG4gIH1cblxuICB0aGlzLmdyYW51bGVQb3NpdGlvbiArPSAoIDQ4ICogdGhpcy5jb25maWcuZW5jb2RlckZyYW1lU2l6ZSApO1xuICBpZiAoIHRoaXMuc2VnbWVudFRhYmxlSW5kZXggPT09IDI1NSApIHtcbiAgICB0aGlzLmdlbmVyYXRlUGFnZSgpO1xuICAgIHRoaXMuaGVhZGVyVHlwZSA9IDA7XG4gIH1cbn07XG5cblxuaWYgKCFNb2R1bGUpIHtcbiAgTW9kdWxlID0ge307XG59XG5cbk1vZHVsZVsnbWFpblJlYWR5J10gPSBtYWluUmVhZHk7XG5Nb2R1bGVbJ09nZ09wdXNFbmNvZGVyJ10gPSBPZ2dPcHVzRW5jb2Rlcjtcbk1vZHVsZVsnb25SdW50aW1lSW5pdGlhbGl6ZWQnXSA9IG1haW5SZWFkeVJlc29sdmU7XG5cbm1vZHVsZS5leHBvcnRzID0gTW9kdWxlO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/encoderWorker.js\n"); /***/ }) diff --git a/dist/encoderWorker.min.js b/dist/encoderWorker.min.js index 8a3ce428..c48e17da 100644 --- a/dist/encoderWorker.min.js +++ b/dist/encoderWorker.min.js @@ -1,4 +1,4 @@ -var Module=typeof Module!=="undefined"?Module:{};!(function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.EncoderWorker=t():e.EncoderWorker=t()})("undefined"!=typeof self?self:this,(function(){return(function(e){var t={};function n(s){if(t[s])return t[s].exports;var i=t[s]={i:s,l:!1,exports:{}};return e[s].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=(function(e,t,s){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:s})}),n.r=(function(e){Object.defineProperty(e,"__esModule",{value:!0})}),n.n=(function(e){var t=e&&e.__esModule?(function(){return e.default}):(function(){return e});return n.d(t,"a",t),t}),n.o=(function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}),n.p="",n(n.s=1)})([(function(e,t){var n;n=(function(){return this})();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n}),(function(e,t,n){"use strict";((function(t){var n,s,i=new Promise((function(e){s=e}));t.onmessage=(function(e){i.then((function(){switch(e.data.command){case"encode":n&&n.encode(e.data.buffers);break;case"done":n&&n.encodeFinalFrame();break;case"init":n=new r(e.data,Module)}}))});var r=(function(e,t){if(!t)throw new Error("Module with exports required to initialize an encoder instance");this.config=Object.assign({bufferLength:4096,encoderApplication:2049,encoderFrameSize:20,encoderSampleRate:48e3,maxBuffersPerPage:40,numberOfChannels:1,originalSampleRate:44100,resampleQuality:3,serial:Math.floor(Math.random()*Math.pow(2,32))},e),this._opus_encoder_create=t._opus_encoder_create,this._opus_encoder_ctl=t._opus_encoder_ctl,this._speex_resampler_process_interleaved_float=t._speex_resampler_process_interleaved_float,this._speex_resampler_init=t._speex_resampler_init,this._opus_encode_float=t._opus_encode_float,this._free=t._free,this._malloc=t._malloc,this.HEAPU8=t.HEAPU8,this.HEAP32=t.HEAP32,this.HEAPF32=t.HEAPF32,this.pageIndex=0,this.granulePosition=0,this.segmentData=new Uint8Array(65025),this.segmentDataIndex=0,this.segmentTable=new Uint8Array(255),this.segmentTableIndex=0,this.buffersInPage=0,this.initChecksumTable(),this.initCodec(),this.initResampler(),this.generateIdPage(),this.generateCommentPage(),1===this.config.numberOfChannels?this.interleave=(function(e){return e[0]}):this.interleavedBuffers=new Float32Array(this.config.bufferLength*this.config.numberOfChannels)});r.prototype.encode=(function(e){for(var t=this.interleave(e),n=0;n=this.config.maxBuffersPerPage&&this.generatePage()}),r.prototype.encodeFinalFrame=(function(){for(var e=[],n=0;n>>24&255^e[n]];return t>>>0}),r.prototype.generateCommentPage=(function(){var e=new DataView(this.segmentData.buffer);e.setUint32(0,1937076303,!0),e.setUint32(4,1936154964,!0),e.setUint32(8,10,!0),e.setUint32(12,1868784978,!0),e.setUint32(16,1919247474,!0),e.setUint16(20,21322,!0),e.setUint32(22,0,!0),this.segmentTableIndex=1,this.segmentDataIndex=this.segmentTable[0]=26,this.headerType=0,this.generatePage()}),r.prototype.generateIdPage=(function(){var e=new DataView(this.segmentData.buffer);e.setUint32(0,1937076303,!0),e.setUint32(4,1684104520,!0),e.setUint8(8,1,!0),e.setUint8(9,this.config.numberOfChannels,!0),e.setUint16(10,3840,!0),e.setUint32(12,this.config.originalSampleRateOverride||this.config.originalSampleRate,!0),e.setUint16(16,0,!0),e.setUint8(18,0,!0),this.segmentTableIndex=1,this.segmentDataIndex=this.segmentTable[0]=19,this.headerType=2,this.generatePage()}),r.prototype.generatePage=(function(){var e=this.lastPositiveGranulePosition===this.granulePosition?-1:this.granulePosition,n=new ArrayBuffer(27+this.segmentTableIndex+this.segmentDataIndex),s=new DataView(n),i=new Uint8Array(n);s.setUint32(0,1399285583,!0),s.setUint8(4,0,!0),s.setUint8(5,this.headerType,!0),s.setUint32(6,e,!0),(e>4294967296||e<0)&&s.setUint32(10,Math.floor(e/4294967296),!0),s.setUint32(14,this.config.serial,!0),s.setUint32(18,this.pageIndex++,!0),s.setUint8(26,this.segmentTableIndex,!0),i.set(this.segmentTable.subarray(0,this.segmentTableIndex),27),i.set(this.segmentData.subarray(0,this.segmentDataIndex),27+this.segmentTableIndex),s.setUint32(22,this.getChecksum(i),!0),t.postMessage(i,[i.buffer]),this.segmentTableIndex=0,this.segmentDataIndex=0,this.buffersInPage=0,e>0&&(this.lastPositiveGranulePosition=e)}),r.prototype.initChecksumTable=(function(){this.checksumTable=[];for(var e=0;e<256;e++){for(var t=e<<24,n=0;n<8;n++)t=0!=(2147483648&t)?t<<1^79764919:t<<1;this.checksumTable[e]=4294967295&t}}),r.prototype.setOpusControl=(function(e,t){var n=this._malloc(4);this.HEAP32[n>>2]=t,this._opus_encoder_ctl(this.encoder,e,n),this._free(n)}),r.prototype.initCodec=(function(){var e=this._malloc(4);this.encoder=this._opus_encoder_create(this.config.encoderSampleRate,this.config.numberOfChannels,this.config.encoderApplication,e),this._free(e),this.config.encoderBitRate&&this.setOpusControl(4002,this.config.encoderBitRate),this.config.encoderComplexity&&this.setOpusControl(4010,this.config.encoderComplexity),this.encoderSamplesPerChannel=this.config.encoderSampleRate*this.config.encoderFrameSize/1e3,this.encoderSamplesPerChannelPointer=this._malloc(4),this.HEAP32[this.encoderSamplesPerChannelPointer>>2]=this.encoderSamplesPerChannel,this.encoderBufferLength=this.encoderSamplesPerChannel*this.config.numberOfChannels,this.encoderBufferPointer=this._malloc(4*this.encoderBufferLength),this.encoderBuffer=this.HEAPF32.subarray(this.encoderBufferPointer>>2,(this.encoderBufferPointer>>2)+this.encoderBufferLength),this.encoderOutputMaxLength=4e3,this.encoderOutputPointer=this._malloc(this.encoderOutputMaxLength),this.encoderOutputBuffer=this.HEAPU8.subarray(this.encoderOutputPointer,this.encoderOutputPointer+this.encoderOutputMaxLength)}),r.prototype.initResampler=(function(){var e=this._malloc(4);this.resampler=this._speex_resampler_init(this.config.numberOfChannels,this.config.originalSampleRate,this.config.encoderSampleRate,this.config.resampleQuality,e),this._free(e),this.resampleBufferIndex=0,this.resampleSamplesPerChannel=this.config.originalSampleRate*this.config.encoderFrameSize/1e3,this.resampleSamplesPerChannelPointer=this._malloc(4),this.HEAP32[this.resampleSamplesPerChannelPointer>>2]=this.resampleSamplesPerChannel,this.resampleBufferLength=this.resampleSamplesPerChannel*this.config.numberOfChannels,this.resampleBufferPointer=this._malloc(4*this.resampleBufferLength),this.resampleBuffer=this.HEAPF32.subarray(this.resampleBufferPointer>>2,(this.resampleBufferPointer>>2)+this.resampleBufferLength)}),r.prototype.interleave=(function(e){for(var t=0;t=0;){255===this.segmentTableIndex&&(this.generatePage(),this.headerType=1);var n=Math.min(e,255);this.segmentTable[this.segmentTableIndex++]=n,this.segmentData.set(this.encoderOutputBuffer.subarray(t,t+n),this.segmentDataIndex),this.segmentDataIndex+=n,t+=n,e-=255}this.granulePosition+=48*this.config.encoderFrameSize,255===this.segmentTableIndex&&(this.generatePage(),this.headerType=0)}),Module||(Module={}),Module.mainReady=i,Module.OggOpusEncoder=r,Module.onRuntimeInitialized=s,e.exports=Module})).call(this,n(0))})])}));var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}Module["arguments"]=[];Module["thisProgram"]="./this.program";Module["quit"]=(function(status,toThrow){throw toThrow});Module["preRun"]=[];Module["postRun"]=[];var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;if(Module["ENVIRONMENT"]){if(Module["ENVIRONMENT"]==="WEB"){ENVIRONMENT_IS_WEB=true}else if(Module["ENVIRONMENT"]==="WORKER"){ENVIRONMENT_IS_WORKER=true}else if(Module["ENVIRONMENT"]==="NODE"){ENVIRONMENT_IS_NODE=true}else if(Module["ENVIRONMENT"]==="SHELL"){ENVIRONMENT_IS_SHELL=true}else{throw new Error("Module['ENVIRONMENT'] value is not valid. must be one of: WEB|WORKER|NODE|SHELL.")}}else{ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER}if(ENVIRONMENT_IS_NODE){var nodeFS;var nodePath;Module["read"]=function shell_read(filename,binary){var ret;if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);ret=nodeFS["readFileSync"](filename);return binary?ret:ret.toString()};Module["readBinary"]=function readBinary(filename){var ret=Module["read"](filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}Module["arguments"]=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));process["on"]("unhandledRejection",(function(reason,p){process["exit"](1)}));Module["inspect"]=(function(){return"[Emscripten Module object]"})}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){Module["read"]=function shell_read(f){return read(f)}}Module["readBinary"]=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof quit==="function"){Module["quit"]=(function(status,toThrow){quit(status)})}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){Module["read"]=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){Module["readBinary"]=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}Module["readAsync"]=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)};Module["setWindowTitle"]=(function(title){document.title=title})}Module["print"]=typeof console!=="undefined"?console.log.bind(console):typeof print!=="undefined"?print:null;Module["printErr"]=typeof printErr!=="undefined"?printErr:typeof console!=="undefined"&&console.warn.bind(console)||Module["print"];Module.print=Module["print"];Module.printErr=Module["printErr"];for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=undefined;var STACK_ALIGN=16;function staticAlloc(size){assert(!staticSealed);var ret=STATICTOP;STATICTOP=STATICTOP+size+15&-16;return ret}function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;var ret=size=Math.ceil(size/factor)*factor;return ret}var functionPointers=new Array(0);var GLOBAL_BASE=1024;var ABORT=0;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;var WASM_PAGE_SIZE=65536;var ASMJS_PAGE_SIZE=16777216;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBuffer(buf){Module["buffer"]=buffer=buf}function updateGlobalBufferViews(){Module["HEAP8"]=HEAP8=new Int8Array(buffer);Module["HEAP16"]=HEAP16=new Int16Array(buffer);Module["HEAP32"]=HEAP32=new Int32Array(buffer);Module["HEAPU8"]=HEAPU8=new Uint8Array(buffer);Module["HEAPU16"]=HEAPU16=new Uint16Array(buffer);Module["HEAPU32"]=HEAPU32=new Uint32Array(buffer);Module["HEAPF32"]=HEAPF32=new Float32Array(buffer);Module["HEAPF64"]=HEAPF64=new Float64Array(buffer)}var STATIC_BASE,STATICTOP,staticSealed;var STACK_BASE,STACKTOP,STACK_MAX;var DYNAMIC_BASE,DYNAMICTOP_PTR;STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0;staticSealed=false;function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}function enlargeMemory(){abortOnCannotGrowMemory()}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;if(TOTAL_MEMORY0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__);runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var Math_abs=Math.abs;var Math_cos=Math.cos;var Math_sin=Math.sin;var Math_tan=Math.tan;var Math_acos=Math.acos;var Math_asin=Math.asin;var Math_atan=Math.atan;var Math_atan2=Math.atan2;var Math_exp=Math.exp;var Math_log=Math.log;var Math_sqrt=Math.sqrt;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_pow=Math.pow;var Math_imul=Math.imul;var Math_fround=Math.fround;var Math_round=Math.round;var Math_min=Math.min;var Math_max=Math.max;var Math_clz32=Math.clz32;var Math_trunc=Math.trunc;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return String.prototype.startsWith?filename.startsWith(dataURIPrefix):filename.indexOf(dataURIPrefix)===0}function integrateWasmJS(){var wasmTextFile="encoderWorker.min.wast";var wasmBinaryFile="encoderWorker.min.wasm";var asmjsCodeFile="encoderWorker.min.temp.asm.js";if(typeof Module["locateFile"]==="function"){if(!isDataURI(wasmTextFile)){wasmTextFile=Module["locateFile"](wasmTextFile)}if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=Module["locateFile"](wasmBinaryFile)}if(!isDataURI(asmjsCodeFile)){asmjsCodeFile=Module["locateFile"](asmjsCodeFile)}}var wasmPageSize=64*1024;var info={"global":null,"env":null,"asm2wasm":{"f64-rem":(function(x,y){return x%y}),"debugger":(function(){debugger})},"parent":Module};var exports=null;function mergeMemory(newBuffer){var oldBuffer=Module["buffer"];if(newBuffer.byteLength>2]=value;return value}DYNAMICTOP_PTR=staticAlloc(4);STACK_BASE=STACKTOP=alignMemory(STATICTOP);STACK_MAX=STACK_BASE+TOTAL_STACK;DYNAMIC_BASE=alignMemory(STACK_MAX);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;staticSealed=true;Module["wasmTableSize"]=10;Module["wasmMaxTableSize"]=10;Module.asmGlobalArg={};Module.asmLibraryArg={"abort":abort,"enlargeMemory":enlargeMemory,"getTotalMemory":getTotalMemory,"abortOnCannotGrowMemory":abortOnCannotGrowMemory,"___setErrNo":___setErrNo,"_emscripten_memcpy_big":_emscripten_memcpy_big,"_llvm_exp2_f64":_llvm_exp2_f64,"_llvm_stackrestore":_llvm_stackrestore,"_llvm_stacksave":_llvm_stacksave,"DYNAMICTOP_PTR":DYNAMICTOP_PTR,"STACKTOP":STACKTOP};var asm=Module["asm"](Module.asmGlobalArg,Module.asmLibraryArg,buffer);Module["asm"]=asm;var _free=Module["_free"]=(function(){return Module["asm"]["_free"].apply(null,arguments)});var _malloc=Module["_malloc"]=(function(){return Module["asm"]["_malloc"].apply(null,arguments)});var _opus_encode_float=Module["_opus_encode_float"]=(function(){return Module["asm"]["_opus_encode_float"].apply(null,arguments)});var _opus_encoder_create=Module["_opus_encoder_create"]=(function(){return Module["asm"]["_opus_encoder_create"].apply(null,arguments)});var _opus_encoder_ctl=Module["_opus_encoder_ctl"]=(function(){return Module["asm"]["_opus_encoder_ctl"].apply(null,arguments)});var _speex_resampler_destroy=Module["_speex_resampler_destroy"]=(function(){return Module["asm"]["_speex_resampler_destroy"].apply(null,arguments)});var _speex_resampler_init=Module["_speex_resampler_init"]=(function(){return Module["asm"]["_speex_resampler_init"].apply(null,arguments)});var _speex_resampler_process_interleaved_float=Module["_speex_resampler_process_interleaved_float"]=(function(){return Module["asm"]["_speex_resampler_process_interleaved_float"].apply(null,arguments)});var stackRestore=Module["stackRestore"]=(function(){return Module["asm"]["stackRestore"].apply(null,arguments)});var stackSave=Module["stackSave"]=(function(){return Module["asm"]["stackSave"].apply(null,arguments)});Module["asm"]=asm;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;var initialStackTop;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"])run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};function run(args){args=args||Module["arguments"];if(runDependencies>0){return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}Module["run"]=run;function exit(status,implicit){if(implicit&&Module["noExitRuntime"]&&status===0){return}if(Module["noExitRuntime"]){}else{ABORT=true;EXITSTATUS=status;STACKTOP=initialStackTop;exitRuntime();if(Module["onExit"])Module["onExit"](status)}if(ENVIRONMENT_IS_NODE){process["exit"](status)}Module["quit"](status,new ExitStatus(status))}Module["exit"]=exit;function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}if(what!==undefined){Module.print(what);Module.printErr(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;throw"abort("+what+"). Build with -s ASSERTIONS=1 for more info."}Module["abort"]=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}Module["noExitRuntime"]=true;run() +var Module=typeof Module!=="undefined"?Module:{};!(function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.EncoderWorker=t():e.EncoderWorker=t()})("undefined"!=typeof self?self:this,(function(){return(function(e){var t={};function n(s){if(t[s])return t[s].exports;var i=t[s]={i:s,l:!1,exports:{}};return e[s].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=(function(e,t,s){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:s})}),n.r=(function(e){Object.defineProperty(e,"__esModule",{value:!0})}),n.n=(function(e){var t=e&&e.__esModule?(function(){return e.default}):(function(){return e});return n.d(t,"a",t),t}),n.o=(function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}),n.p="",n(n.s=1)})([(function(e,t){var n;n=(function(){return this})();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n}),(function(e,t,n){"use strict";((function(t){var n,s,i=new Promise((function(e){s=e}));t.onmessage=(function(e){i.then((function(){switch(e.data.command){case"encode":n&&n.encode(e.data.buffers);break;case"done":n&&n.encodeFinalFrame();break;case"init":n=new r(e.data,Module)}}))});var r=(function(e,t){if(!t)throw new Error("Module with exports required to initialize an encoder instance");this.config=Object.assign({bufferLength:4096,encoderApplication:2049,encoderFrameSize:20,encoderSampleRate:48e3,maxBuffersPerPage:40,numberOfChannels:1,originalSampleRate:44100,resampleQuality:3,serial:Math.floor(Math.random()*(Math.pow(2,32)-1))},e),this._opus_encoder_create=t._opus_encoder_create,this._opus_encoder_ctl=t._opus_encoder_ctl,this._speex_resampler_process_interleaved_float=t._speex_resampler_process_interleaved_float,this._speex_resampler_init=t._speex_resampler_init,this._opus_encode_float=t._opus_encode_float,this._free=t._free,this._malloc=t._malloc,this.HEAPU8=t.HEAPU8,this.HEAP32=t.HEAP32,this.HEAPF32=t.HEAPF32,this.pageIndex=0,this.granulePosition=0,this.segmentData=new Uint8Array(65025),this.segmentDataIndex=0,this.segmentTable=new Uint8Array(255),this.segmentTableIndex=0,this.buffersInPage=0,this.initChecksumTable(),this.initCodec(),this.initResampler(),this.generateIdPage(),this.generateCommentPage(),1===this.config.numberOfChannels?this.interleave=(function(e){return e[0]}):this.interleavedBuffers=new Float32Array(this.config.bufferLength*this.config.numberOfChannels)});r.prototype.encode=(function(e){for(var t=this.interleave(e),n=0;n=this.config.maxBuffersPerPage&&this.generatePage()}),r.prototype.encodeFinalFrame=(function(){for(var e=[],n=0;n>>24&255^e[n]];return t>>>0}),r.prototype.generateCommentPage=(function(){var e=new DataView(this.segmentData.buffer);e.setUint32(0,1937076303,!0),e.setUint32(4,1936154964,!0),e.setUint32(8,10,!0),e.setUint32(12,1868784978,!0),e.setUint32(16,1919247474,!0),e.setUint16(20,21322,!0),e.setUint32(22,0,!0),this.segmentTableIndex=1,this.segmentDataIndex=this.segmentTable[0]=26,this.headerType=0,this.generatePage()}),r.prototype.generateIdPage=(function(){var e=new DataView(this.segmentData.buffer);e.setUint32(0,1937076303,!0),e.setUint32(4,1684104520,!0),e.setUint8(8,1,!0),e.setUint8(9,this.config.numberOfChannels,!0),e.setUint16(10,3840,!0),e.setUint32(12,this.config.originalSampleRateOverride||this.config.originalSampleRate,!0),e.setUint16(16,0,!0),e.setUint8(18,0,!0),this.segmentTableIndex=1,this.segmentDataIndex=this.segmentTable[0]=19,this.headerType=2,this.generatePage()}),r.prototype.generatePage=(function(){var e=this.lastPositiveGranulePosition===this.granulePosition?-1:this.granulePosition,n=new ArrayBuffer(27+this.segmentTableIndex+this.segmentDataIndex),s=new DataView(n),i=new Uint8Array(n);s.setUint32(0,1399285583,!0),s.setUint8(4,0,!0),s.setUint8(5,this.headerType,!0),s.setUint32(6,e,!0),e<0?s.setInt32(10,Math.ceil(e/4294967297)-1,!0):s.setInt32(10,Math.floor(e/4294967296),!0),s.setUint32(14,this.config.serial,!0),s.setUint32(18,this.pageIndex++,!0),s.setUint8(26,this.segmentTableIndex,!0),i.set(this.segmentTable.subarray(0,this.segmentTableIndex),27),i.set(this.segmentData.subarray(0,this.segmentDataIndex),27+this.segmentTableIndex),s.setUint32(22,this.getChecksum(i),!0),t.postMessage(i,[i.buffer]),this.segmentTableIndex=0,this.segmentDataIndex=0,this.buffersInPage=0,e>0&&(this.lastPositiveGranulePosition=e)}),r.prototype.initChecksumTable=(function(){this.checksumTable=[];for(var e=0;e<256;e++){for(var t=e<<24,n=0;n<8;n++)t=0!=(2147483648&t)?t<<1^79764919:t<<1;this.checksumTable[e]=4294967295&t}}),r.prototype.setOpusControl=(function(e,t){var n=this._malloc(4);this.HEAP32[n>>2]=t,this._opus_encoder_ctl(this.encoder,e,n),this._free(n)}),r.prototype.initCodec=(function(){var e=this._malloc(4);this.encoder=this._opus_encoder_create(this.config.encoderSampleRate,this.config.numberOfChannels,this.config.encoderApplication,e),this._free(e),this.config.encoderBitRate&&this.setOpusControl(4002,this.config.encoderBitRate),this.config.encoderComplexity&&this.setOpusControl(4010,this.config.encoderComplexity),this.encoderSamplesPerChannel=this.config.encoderSampleRate*this.config.encoderFrameSize/1e3,this.encoderSamplesPerChannelPointer=this._malloc(4),this.HEAP32[this.encoderSamplesPerChannelPointer>>2]=this.encoderSamplesPerChannel,this.encoderBufferLength=this.encoderSamplesPerChannel*this.config.numberOfChannels,this.encoderBufferPointer=this._malloc(4*this.encoderBufferLength),this.encoderBuffer=this.HEAPF32.subarray(this.encoderBufferPointer>>2,(this.encoderBufferPointer>>2)+this.encoderBufferLength),this.encoderOutputMaxLength=4e3,this.encoderOutputPointer=this._malloc(this.encoderOutputMaxLength),this.encoderOutputBuffer=this.HEAPU8.subarray(this.encoderOutputPointer,this.encoderOutputPointer+this.encoderOutputMaxLength)}),r.prototype.initResampler=(function(){var e=this._malloc(4);this.resampler=this._speex_resampler_init(this.config.numberOfChannels,this.config.originalSampleRate,this.config.encoderSampleRate,this.config.resampleQuality,e),this._free(e),this.resampleBufferIndex=0,this.resampleSamplesPerChannel=this.config.originalSampleRate*this.config.encoderFrameSize/1e3,this.resampleSamplesPerChannelPointer=this._malloc(4),this.HEAP32[this.resampleSamplesPerChannelPointer>>2]=this.resampleSamplesPerChannel,this.resampleBufferLength=this.resampleSamplesPerChannel*this.config.numberOfChannels,this.resampleBufferPointer=this._malloc(4*this.resampleBufferLength),this.resampleBuffer=this.HEAPF32.subarray(this.resampleBufferPointer>>2,(this.resampleBufferPointer>>2)+this.resampleBufferLength)}),r.prototype.interleave=(function(e){for(var t=0;t=0;){255===this.segmentTableIndex&&(this.generatePage(),this.headerType=1);var n=Math.min(e,255);this.segmentTable[this.segmentTableIndex++]=n,this.segmentData.set(this.encoderOutputBuffer.subarray(t,t+n),this.segmentDataIndex),this.segmentDataIndex+=n,t+=n,e-=255}this.granulePosition+=48*this.config.encoderFrameSize,255===this.segmentTableIndex&&(this.generatePage(),this.headerType=0)}),Module||(Module={}),Module.mainReady=i,Module.OggOpusEncoder=r,Module.onRuntimeInitialized=s,e.exports=Module})).call(this,n(0))})])}));var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}Module["arguments"]=[];Module["thisProgram"]="./this.program";Module["quit"]=(function(status,toThrow){throw toThrow});Module["preRun"]=[];Module["postRun"]=[];var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;if(Module["ENVIRONMENT"]){if(Module["ENVIRONMENT"]==="WEB"){ENVIRONMENT_IS_WEB=true}else if(Module["ENVIRONMENT"]==="WORKER"){ENVIRONMENT_IS_WORKER=true}else if(Module["ENVIRONMENT"]==="NODE"){ENVIRONMENT_IS_NODE=true}else if(Module["ENVIRONMENT"]==="SHELL"){ENVIRONMENT_IS_SHELL=true}else{throw new Error("Module['ENVIRONMENT'] value is not valid. must be one of: WEB|WORKER|NODE|SHELL.")}}else{ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER}if(ENVIRONMENT_IS_NODE){var nodeFS;var nodePath;Module["read"]=function shell_read(filename,binary){var ret;if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);ret=nodeFS["readFileSync"](filename);return binary?ret:ret.toString()};Module["readBinary"]=function readBinary(filename){var ret=Module["read"](filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}Module["arguments"]=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));process["on"]("unhandledRejection",(function(reason,p){process["exit"](1)}));Module["inspect"]=(function(){return"[Emscripten Module object]"})}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){Module["read"]=function shell_read(f){return read(f)}}Module["readBinary"]=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof quit==="function"){Module["quit"]=(function(status,toThrow){quit(status)})}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){Module["read"]=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){Module["readBinary"]=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}Module["readAsync"]=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)};Module["setWindowTitle"]=(function(title){document.title=title})}Module["print"]=typeof console!=="undefined"?console.log.bind(console):typeof print!=="undefined"?print:null;Module["printErr"]=typeof printErr!=="undefined"?printErr:typeof console!=="undefined"&&console.warn.bind(console)||Module["print"];Module.print=Module["print"];Module.printErr=Module["printErr"];for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=undefined;var STACK_ALIGN=16;function staticAlloc(size){assert(!staticSealed);var ret=STATICTOP;STATICTOP=STATICTOP+size+15&-16;return ret}function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;var ret=size=Math.ceil(size/factor)*factor;return ret}var functionPointers=new Array(0);var GLOBAL_BASE=1024;var ABORT=0;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;var WASM_PAGE_SIZE=65536;var ASMJS_PAGE_SIZE=16777216;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBuffer(buf){Module["buffer"]=buffer=buf}function updateGlobalBufferViews(){Module["HEAP8"]=HEAP8=new Int8Array(buffer);Module["HEAP16"]=HEAP16=new Int16Array(buffer);Module["HEAP32"]=HEAP32=new Int32Array(buffer);Module["HEAPU8"]=HEAPU8=new Uint8Array(buffer);Module["HEAPU16"]=HEAPU16=new Uint16Array(buffer);Module["HEAPU32"]=HEAPU32=new Uint32Array(buffer);Module["HEAPF32"]=HEAPF32=new Float32Array(buffer);Module["HEAPF64"]=HEAPF64=new Float64Array(buffer)}var STATIC_BASE,STATICTOP,staticSealed;var STACK_BASE,STACKTOP,STACK_MAX;var DYNAMIC_BASE,DYNAMICTOP_PTR;STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0;staticSealed=false;function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}function enlargeMemory(){abortOnCannotGrowMemory()}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;if(TOTAL_MEMORY0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__);runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var Math_abs=Math.abs;var Math_cos=Math.cos;var Math_sin=Math.sin;var Math_tan=Math.tan;var Math_acos=Math.acos;var Math_asin=Math.asin;var Math_atan=Math.atan;var Math_atan2=Math.atan2;var Math_exp=Math.exp;var Math_log=Math.log;var Math_sqrt=Math.sqrt;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_pow=Math.pow;var Math_imul=Math.imul;var Math_fround=Math.fround;var Math_round=Math.round;var Math_min=Math.min;var Math_max=Math.max;var Math_clz32=Math.clz32;var Math_trunc=Math.trunc;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return String.prototype.startsWith?filename.startsWith(dataURIPrefix):filename.indexOf(dataURIPrefix)===0}function integrateWasmJS(){var wasmTextFile="encoderWorker.min.wast";var wasmBinaryFile="encoderWorker.min.wasm";var asmjsCodeFile="encoderWorker.min.temp.asm.js";if(typeof Module["locateFile"]==="function"){if(!isDataURI(wasmTextFile)){wasmTextFile=Module["locateFile"](wasmTextFile)}if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=Module["locateFile"](wasmBinaryFile)}if(!isDataURI(asmjsCodeFile)){asmjsCodeFile=Module["locateFile"](asmjsCodeFile)}}var wasmPageSize=64*1024;var info={"global":null,"env":null,"asm2wasm":{"f64-rem":(function(x,y){return x%y}),"debugger":(function(){debugger})},"parent":Module};var exports=null;function mergeMemory(newBuffer){var oldBuffer=Module["buffer"];if(newBuffer.byteLength>2]=value;return value}DYNAMICTOP_PTR=staticAlloc(4);STACK_BASE=STACKTOP=alignMemory(STATICTOP);STACK_MAX=STACK_BASE+TOTAL_STACK;DYNAMIC_BASE=alignMemory(STACK_MAX);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;staticSealed=true;Module["wasmTableSize"]=10;Module["wasmMaxTableSize"]=10;Module.asmGlobalArg={};Module.asmLibraryArg={"abort":abort,"enlargeMemory":enlargeMemory,"getTotalMemory":getTotalMemory,"abortOnCannotGrowMemory":abortOnCannotGrowMemory,"___setErrNo":___setErrNo,"_emscripten_memcpy_big":_emscripten_memcpy_big,"_llvm_exp2_f64":_llvm_exp2_f64,"_llvm_stackrestore":_llvm_stackrestore,"_llvm_stacksave":_llvm_stacksave,"DYNAMICTOP_PTR":DYNAMICTOP_PTR,"STACKTOP":STACKTOP};var asm=Module["asm"](Module.asmGlobalArg,Module.asmLibraryArg,buffer);Module["asm"]=asm;var _free=Module["_free"]=(function(){return Module["asm"]["_free"].apply(null,arguments)});var _malloc=Module["_malloc"]=(function(){return Module["asm"]["_malloc"].apply(null,arguments)});var _opus_encode_float=Module["_opus_encode_float"]=(function(){return Module["asm"]["_opus_encode_float"].apply(null,arguments)});var _opus_encoder_create=Module["_opus_encoder_create"]=(function(){return Module["asm"]["_opus_encoder_create"].apply(null,arguments)});var _opus_encoder_ctl=Module["_opus_encoder_ctl"]=(function(){return Module["asm"]["_opus_encoder_ctl"].apply(null,arguments)});var _speex_resampler_destroy=Module["_speex_resampler_destroy"]=(function(){return Module["asm"]["_speex_resampler_destroy"].apply(null,arguments)});var _speex_resampler_init=Module["_speex_resampler_init"]=(function(){return Module["asm"]["_speex_resampler_init"].apply(null,arguments)});var _speex_resampler_process_interleaved_float=Module["_speex_resampler_process_interleaved_float"]=(function(){return Module["asm"]["_speex_resampler_process_interleaved_float"].apply(null,arguments)});var stackRestore=Module["stackRestore"]=(function(){return Module["asm"]["stackRestore"].apply(null,arguments)});var stackSave=Module["stackSave"]=(function(){return Module["asm"]["stackSave"].apply(null,arguments)});Module["asm"]=asm;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;var initialStackTop;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"])run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};function run(args){args=args||Module["arguments"];if(runDependencies>0){return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}Module["run"]=run;function exit(status,implicit){if(implicit&&Module["noExitRuntime"]&&status===0){return}if(Module["noExitRuntime"]){}else{ABORT=true;EXITSTATUS=status;STACKTOP=initialStackTop;exitRuntime();if(Module["onExit"])Module["onExit"](status)}if(ENVIRONMENT_IS_NODE){process["exit"](status)}Module["quit"](status,new ExitStatus(status))}Module["exit"]=exit;function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}if(what!==undefined){Module.print(what);Module.printErr(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;throw"abort("+what+"). Build with -s ASSERTIONS=1 for more info."}Module["abort"]=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}Module["noExitRuntime"]=true;run() diff --git a/package.json b/package.json index 55ab59f6..10ec3545 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "opus-recorder", - "version": "4.1.1", + "version": "4.1.2", "description": "A library for recording opus encoded audio", "homepage": "https://github.com/chris-rudmin/opus-recorder", "author": "Chris Rudmin", diff --git a/src/encoderWorker.js b/src/encoderWorker.js index a7b8c84c..9013f8d9 100644 --- a/src/encoderWorker.js +++ b/src/encoderWorker.js @@ -48,7 +48,7 @@ var OggOpusEncoder = function( config, Module ){ numberOfChannels: 1, originalSampleRate: 44100, resampleQuality: 3, // Value between 0 and 10 inclusive. 10 being highest quality. - serial: Math.floor( Math.random() * Math.pow(2,32) ) + serial: Math.floor( Math.random() * (Math.pow(2,32) - 1) ) }, config ); this._opus_encoder_create = Module._opus_encoder_create; @@ -171,10 +171,14 @@ OggOpusEncoder.prototype.generatePage = function(){ pageBufferView.setUint8( 4, 0, true ); // Version pageBufferView.setUint8( 5, this.headerType, true ); // 1 = continuation, 2 = beginning of stream, 4 = end of stream - // Number of samples upto and including this page at 48000Hz, into 64 bits + // Number of samples upto and including this page at 48000Hz, into signed 64 bit Little Endian integer + // Javascript Number maximum value is 53 bits or 2^53 - 1 pageBufferView.setUint32( 6, granulePosition, true ); - if ( granulePosition > 4294967296 || granulePosition < 0 ) { - pageBufferView.setUint32( 10, Math.floor( granulePosition/4294967296 ), true ); + if (granulePosition < 0) { + pageBufferView.setInt32( 10, Math.ceil(granulePosition/4294967297) - 1, true ); + } + else { + pageBufferView.setInt32( 10, Math.floor(granulePosition/4294967296), true ); } pageBufferView.setUint32( 14, this.config.serial, true ); // Bitstream serial number diff --git a/test/encoderWorker.js b/test/encoderWorker.js index 79b90289..86990a12 100644 --- a/test/encoderWorker.js +++ b/test/encoderWorker.js @@ -139,4 +139,130 @@ describe('encoderWorker', function() { getEncoder(); }); + it('should set granule position to 0', function (done) { + var pageBufferCount = 0; + + global.postMessage = function(page) { + pageBufferCount++; + + if (pageBufferCount == 3) { + var dataView = new DataView(page.buffer); + expect(dataView.getUint32(6, true)).to.equal(0); + expect(dataView.getInt32(10, true)).to.equal(0); + done(); + } + }; + + getEncoder().then(function(encoder) { + encoder.lastPositiveGranulePosition = 1; + encoder.granulePosition = 0; + encoder.generatePage(); + }); + }); + + it('should set granule position to -1', function (done) { + var pageBufferCount = 0; + + global.postMessage = function(page) { + pageBufferCount++; + + if (pageBufferCount == 3) { + var dataView = new DataView(page.buffer); + expect(dataView.getUint32(6, true)).to.equal(4294967295); + expect(dataView.getInt32(10, true)).to.equal(-1); + done(); + } + }; + + getEncoder().then(function(encoder) { + encoder.lastPositiveGranulePosition = 1; + encoder.granulePosition = -1; + encoder.generatePage(); + }); + }); + + it('should set granule position to -2^32', function (done) { + var pageBufferCount = 0; + + global.postMessage = function(page) { + pageBufferCount++; + + if (pageBufferCount == 3) { + var dataView = new DataView(page.buffer); + expect(dataView.getUint32(6, true)).to.equal(0); + expect(dataView.getInt32(10, true)).to.equal(-1); + done(); + } + }; + + getEncoder().then(function(encoder) { + encoder.lastPositiveGranulePosition = 1; + encoder.granulePosition = -4294967296; + encoder.generatePage(); + }); + }); + + it('should set granule position to -2^32 - 1', function (done) { + var pageBufferCount = 0; + + global.postMessage = function(page) { + pageBufferCount++; + + if (pageBufferCount == 3) { + var dataView = new DataView(page.buffer); + expect(dataView.getUint32(6, true)).to.equal(4294967295); + expect(dataView.getInt32(10, true)).to.equal(-2); + done(); + } + }; + + getEncoder().then(function(encoder) { + encoder.lastPositiveGranulePosition = 1; + encoder.granulePosition = -4294967297; + encoder.generatePage(); + }); + }); + + it('should set granule position to 2^32 - 1', function (done) { + var pageBufferCount = 0; + + global.postMessage = function(page) { + pageBufferCount++; + + if (pageBufferCount == 3) { + var dataView = new DataView(page.buffer); + expect(dataView.getUint32(6, true)).to.equal(4294967295); + expect(dataView.getInt32(10, true)).to.equal(0); + done(); + } + }; + + getEncoder().then(function(encoder) { + encoder.lastPositiveGranulePosition = 1; + encoder.granulePosition = 4294967295; + encoder.generatePage(); + }); + }); + + it('should set granule position to 2^32', function (done) { + var pageBufferCount = 0; + + global.postMessage = function(page) { + pageBufferCount++; + + if (pageBufferCount == 3) { + var dataView = new DataView(page.buffer); + expect(dataView.getUint32(6, true)).to.equal(0); + expect(dataView.getInt32(10, true)).to.equal(1); + done(); + } + }; + + getEncoder().then(function(encoder) { + encoder.lastPositiveGranulePosition = 1; + encoder.granulePosition = 4294967296; + encoder.generatePage(); + }); + }); + });