<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">{"version":3,"sources":["webpack://WaveSurfer.[name]/webpack/universalModuleDefinition","webpack://WaveSurfer.[name]/webpack/bootstrap","webpack://WaveSurfer.[name]/./src/plugin/microphone.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","MicrophonePlugin","params","ws","this","wavesurfer","active","paused","browser","detectBrowser","reloadBufferFunction","e","reloadBuffer","undefined","navigator","mediaDevices","getUserMedia","constraints","successCallback","errorCallback","webkitGetUserMedia","mozGetUserMedia","msGetUserMedia","Promise","reject","Error","video","audio","bufferSize","numberOfInputChannels","numberOfOutputChannels","_onBackendCreated","micContext","backend","getAudioContext","deferInit","instance","on","un","stop","then","data","gotStream","catch","deviceError","pause","play","start","connect","disconnect","stopDevice","empty","stream","version","getTracks","forEach","localAudioBuffer","createBuffer","sampleRate","mediaStreamSource","createMediaStreamSource","levelChecker","createScriptProcessor","destination","onaudioprocess","event","channel","Math","min","numberOfChannels","inputBuffer","getChannelData","set","loadDecodedBuffer","fireEvent","code","uastring","expr","pos","match","length","parseInt","result","extractVersion","userAgent","minVersion","RTCPeerConnection"],"mappings":"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","file":"wavesurfer.microphone.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' &amp;&amp; typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' &amp;&amp; define.amd)\n\t\tdefine(\"microphone\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"microphone\"] = factory();\n\telse\n\t\troot[\"WaveSurfer\"] = root[\"WaveSurfer\"] || {}, root[\"WaveSurfer\"][\"microphone\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' &amp;&amp; Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode &amp; 1: value is a module id, require it\n \t// mode &amp; 2: merge all properties of value into the ns\n \t// mode &amp; 4: return value when already ns object\n \t// mode &amp; 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode &amp; 1) value = __webpack_require__(value);\n \t\tif(mode &amp; 8) return value;\n \t\tif((mode &amp; 4) &amp;&amp; typeof value === 'object' &amp;&amp; value &amp;&amp; value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode &amp; 2 &amp;&amp; typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module &amp;&amp; module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"localhost:8080/dist/plugin/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 5);\n","/**\n * @typedef {Object} MicrophonePluginParams\n * @property {MediaStreamConstraints} constraints The constraints parameter is a\n * MediaStreamConstaints object with two members: video and audio, describing\n * the media types requested. Either or both must be specified.\n * @property {number} bufferSize=4096 The buffer size in units of sample-frames.\n * If specified, the bufferSize must be one of the following values: `256`,\n * `512`, `1024`, `2048`, `4096`, `8192`, `16384`\n * @property {number} numberOfInputChannels=1 Integer specifying the number of\n * channels for this node's input. Values of up to 32 are supported.\n * @property {?boolean} deferInit Set to true to manually call\n * `initPlugin('microphone')`\n */\n\n/**\n * Visualize microphone input in a wavesurfer instance.\n *\n * @implements {PluginClass}\n * @extends {Observer}\n * @example\n * // es6\n * import MicrophonePlugin from 'wavesurfer.microphone.js';\n *\n * // commonjs\n * var MicrophonePlugin = require('wavesurfer.microphone.js');\n *\n * // if you are using &lt;script&gt; tags\n * var MicrophonePlugin = window.WaveSurfer.microphone;\n *\n * // ... initialising wavesurfer with the plugin\n * var wavesurfer = WaveSurfer.create({\n *   // wavesurfer options ...\n *   plugins: [\n *     MicrophonePlugin.create({\n *       // plugin options ...\n *     })\n *   ]\n * });\n */\nexport default class MicrophonePlugin {\n    /**\n     * Microphone plugin definition factory\n     *\n     * This function must be used to create a plugin definition which can be\n     * used by wavesurfer to correctly instantiate the plugin.\n     *\n     * @param  {MicrophonePluginParams} params parameters use to initialise the plugin\n     * @return {PluginDefinition} an object representing the plugin\n     */\n    static create(params) {\n        return {\n            name: 'microphone',\n            deferInit: params &amp;&amp; params.deferInit ? params.deferInit : false,\n            params: params,\n            instance: MicrophonePlugin\n        };\n    }\n\n    constructor(params, ws) {\n        this.params = params;\n        this.wavesurfer = ws;\n\n        this.active = false;\n        this.paused = false;\n        this.browser = this.detectBrowser();\n        this.reloadBufferFunction = e =&gt; this.reloadBuffer(e);\n\n        // cross-browser getUserMedia\n        const promisifiedOldGUM = (\n            constraints,\n            successCallback,\n            errorCallback\n        ) =&gt; {\n            // get a hold of getUserMedia, if present\n            const getUserMedia =\n                navigator.getUserMedia ||\n                navigator.webkitGetUserMedia ||\n                navigator.mozGetUserMedia ||\n                navigator.msGetUserMedia;\n            // Some browsers just don't implement it - return a rejected\n            // promise with an error to keep a consistent interface\n            if (!getUserMedia) {\n                return Promise.reject(\n                    new Error('getUserMedia is not implemented in this browser')\n                );\n            }\n            // otherwise, wrap the call to the old navigator.getUserMedia with\n            // a Promise\n            return new Promise((successCallback, errorCallback) =&gt; {\n                getUserMedia.call(\n                    navigator,\n                    constraints,\n                    successCallback,\n                    errorCallback\n                );\n            });\n        };\n        // Older browsers might not implement mediaDevices at all, so we set an\n        // empty object first\n        if (navigator.mediaDevices === undefined) {\n            navigator.mediaDevices = {};\n        }\n        // Some browsers partially implement mediaDevices. We can't just assign\n        // an object with getUserMedia as it would overwrite existing\n        // properties. Here, we will just add the getUserMedia property if it's\n        // missing.\n        if (navigator.mediaDevices.getUserMedia === undefined) {\n            navigator.mediaDevices.getUserMedia = promisifiedOldGUM;\n        }\n        this.constraints = this.params.constraints || {\n            video: false,\n            audio: true\n        };\n        this.bufferSize = this.params.bufferSize || 4096;\n        this.numberOfInputChannels = this.params.numberOfInputChannels || 1;\n        this.numberOfOutputChannels = this.params.numberOfOutputChannels || 1;\n\n        this._onBackendCreated = () =&gt; {\n            // wavesurfer's AudioContext where we'll route the mic signal to\n            this.micContext = this.wavesurfer.backend.getAudioContext();\n        };\n    }\n\n    init() {\n        this.wavesurfer.on('backend-created', this._onBackendCreated);\n        if (this.wavesurfer.backend) {\n            this._onBackendCreated();\n        }\n    }\n\n    /**\n     * Destroy the microphone plugin.\n     */\n    destroy() {\n        // make sure the buffer is not redrawn during\n        // cleanup and demolition of this plugin.\n        this.paused = true;\n\n        this.wavesurfer.un('backend-created', this._onBackendCreated);\n        this.stop();\n    }\n\n    /**\n     * Allow user to select audio input device, e.g. microphone, and\n     * start the visualization.\n     */\n    start() {\n        navigator.mediaDevices\n            .getUserMedia(this.constraints)\n            .then(data =&gt; this.gotStream(data))\n            .catch(data =&gt; this.deviceError(data));\n    }\n\n    /**\n     * Pause/resume visualization.\n     */\n    togglePlay() {\n        if (!this.active) {\n            // start it first\n            this.start();\n        } else {\n            // toggle paused\n            this.paused = !this.paused;\n\n            if (this.paused) {\n                this.pause();\n            } else {\n                this.play();\n            }\n        }\n    }\n\n    /**\n     * Play visualization.\n     */\n    play() {\n        this.paused = false;\n\n        this.connect();\n    }\n\n    /**\n     * Pause visualization.\n     */\n    pause() {\n        this.paused = true;\n\n        // disconnect sources so they can be used elsewhere\n        // (eg. during audio playback)\n        this.disconnect();\n    }\n\n    /**\n     * Stop the device stream and remove any remaining waveform drawing from\n     * the wavesurfer canvas.\n     */\n    stop() {\n        if (this.active) {\n            // stop visualization and device\n            this.stopDevice();\n\n            // empty last frame\n            this.wavesurfer.empty();\n        }\n    }\n\n    /**\n     * Stop the device and the visualization.\n     */\n    stopDevice() {\n        this.active = false;\n\n        // stop visualization\n        this.disconnect();\n\n        // stop stream from device\n        if (this.stream) {\n            // MediaStream.stop is deprecated since:\n            // - Firefox 44 (https://www.fxsitecompat.com/en-US/docs/2015/mediastream-stop-has-been-deprecated/)\n            // - Chrome 45 (https://developers.google.com/web/updates/2015/07/mediastream-deprecations)\n            if (\n                (this.browser.browser === 'chrome' &amp;&amp;\n                    this.browser.version &gt;= 45) ||\n                (this.browser.browser === 'firefox' &amp;&amp;\n                    this.browser.version &gt;= 44) ||\n                this.browser.browser === 'edge' ||\n                this.browser.browser === 'safari'\n            ) {\n                if (this.stream.getTracks) {\n                    // note that this should not be a call\n                    this.stream.getTracks().forEach(stream =&gt; stream.stop());\n                    return;\n                }\n            }\n\n            this.stream.stop();\n        }\n    }\n\n    /**\n     * Connect the media sources that feed the visualization.\n     */\n    connect() {\n        if (this.stream !== undefined) {\n            // Create a local buffer for data to be copied to the Wavesurfer buffer for Edge\n            if (this.browser.browser === 'edge') {\n                this.localAudioBuffer = this.micContext.createBuffer(\n                    this.numberOfInputChannels,\n                    this.bufferSize,\n                    this.micContext.sampleRate\n                );\n            }\n\n            // Create an AudioNode from the stream.\n            this.mediaStreamSource = this.micContext.createMediaStreamSource(\n                this.stream\n            );\n\n            this.levelChecker = this.micContext.createScriptProcessor(\n                this.bufferSize,\n                this.numberOfInputChannels,\n                this.numberOfOutputChannels\n            );\n            this.mediaStreamSource.connect(this.levelChecker);\n\n            this.levelChecker.connect(this.micContext.destination);\n            this.levelChecker.onaudioprocess = this.reloadBufferFunction;\n        }\n    }\n\n    /**\n     * Disconnect the media sources that feed the visualization.\n     */\n    disconnect() {\n        if (this.mediaStreamSource !== undefined) {\n            this.mediaStreamSource.disconnect();\n        }\n\n        if (this.levelChecker !== undefined) {\n            this.levelChecker.disconnect();\n            this.levelChecker.onaudioprocess = undefined;\n        }\n\n        if (this.localAudioBuffer !== undefined) {\n            this.localAudioBuffer = undefined;\n        }\n    }\n\n    /**\n     * Redraw the waveform.\n     */\n    reloadBuffer(event) {\n        if (!this.paused) {\n            this.wavesurfer.empty();\n\n            if (this.browser.browser === 'edge') {\n                // copy audio data to a local audio buffer,\n                // from https://github.com/audiojs/audio-buffer-utils\n                let channel, l;\n                for (\n                    channel = 0,\n                        l = Math.min(\n                            this.localAudioBuffer.numberOfChannels,\n                            event.inputBuffer.numberOfChannels\n                        );\n                    channel &lt; l;\n                    channel++\n                ) {\n                    this.localAudioBuffer\n                        .getChannelData(channel)\n                        .set(event.inputBuffer.getChannelData(channel));\n                }\n\n                this.wavesurfer.loadDecodedBuffer(this.localAudioBuffer);\n            } else {\n                this.wavesurfer.loadDecodedBuffer(event.inputBuffer);\n            }\n        }\n    }\n\n    /**\n     * Audio input device is ready.\n     *\n     * @param {LocalMediaStream} stream The microphone's media stream.\n     */\n    gotStream(stream) {\n        this.stream = stream;\n        this.active = true;\n\n        // start visualization\n        this.play();\n\n        // notify listeners\n        this.fireEvent('deviceReady', stream);\n    }\n\n    /**\n     * Device error callback.\n     */\n    deviceError(code) {\n        // notify listeners\n        this.fireEvent('deviceError', code);\n    }\n\n    /**\n     * Extract browser version out of the provided user agent string.\n     * @param {!string} uastring userAgent string.\n     * @param {!string} expr Regular expression used as match criteria.\n     * @param {!number} pos position in the version string to be returned.\n     * @return {!number} browser version.\n     */\n    extractVersion(uastring, expr, pos) {\n        const match = uastring.match(expr);\n        return match &amp;&amp; match.length &gt;= pos &amp;&amp; parseInt(match[pos], 10);\n    }\n\n    /**\n     * Browser detector.\n     * @return {object} result containing browser, version and minVersion\n     *     properties.\n     */\n    detectBrowser() {\n        // Returned result object.\n        const result = {};\n        result.browser = null;\n        result.version = null;\n        result.minVersion = null;\n\n        // Non supported browser.\n        if (typeof window === 'undefined' || !window.navigator) {\n            result.browser = 'Not a supported browser.';\n            return result;\n        }\n\n        if (navigator.mozGetUserMedia) {\n            // Firefox\n            result.browser = 'firefox';\n            result.version = this.extractVersion(\n                navigator.userAgent,\n                /Firefox\\/(\\d+)\\./,\n                1\n            );\n            result.minVersion = 31;\n            return result;\n        } else if (navigator.webkitGetUserMedia) {\n            // Chrome/Chromium/Webview/Opera\n            result.browser = 'chrome';\n            result.version = this.extractVersion(\n                navigator.userAgent,\n                /Chrom(e|ium)\\/(\\d+)\\./,\n                2\n            );\n            result.minVersion = 38;\n            return result;\n        } else if (\n            navigator.mediaDevices &amp;&amp;\n            navigator.userAgent.match(/Edge\\/(\\d+).(\\d+)$/)\n        ) {\n            // Edge\n            result.browser = 'edge';\n            result.version = this.extractVersion(\n                navigator.userAgent,\n                /Edge\\/(\\d+).(\\d+)$/,\n                2\n            );\n            result.minVersion = 10547;\n            return result;\n        } else if (\n            window.RTCPeerConnection &amp;&amp;\n            navigator.userAgent.match(/AppleWebKit\\/(\\d+)\\./)\n        ) {\n            // Safari\n            result.browser = 'safari';\n            result.minVersion = 11;\n            result.version = this.extractVersion(\n                navigator.userAgent,\n                /AppleWebKit\\/(\\d+)\\./,\n                1\n            );\n            return result;\n        }\n\n        // Non supported browser default.\n        result.browser = 'Not a supported browser.';\n        return result;\n    }\n}\n"],"sourceRoot":""}</pre></body></html>