{"version":3,"file":"mpc.min.mjs","sources":["../node_modules/eventemitter3/index.js","../src/util.ts","../src/protocol.ts","../src/transform.ts","../src/objects/status.ts","../src/objects/statistics.ts","../src/objects/playlists.ts","../src/objects/database.ts","../src/objects/outputDevice.ts","../src/objects/mount.ts","../src/objects/decoder.ts","../src/commands/database.ts","../src/mpcCore.ts","../src/commands/status.ts","../src/commands/playback.ts","../src/commands/playbackOptions.ts","../src/commands/currentPlaylist.ts","../src/commands/storedPlaylists.ts","../src/commands/mount.ts","../src/commands/sticker.ts","../src/commands/connection.ts","../src/commands/partition.ts","../src/commands/outputDevice.ts","../src/commands/reflection.ts","../src/commands/clientToClient.ts","../src/mpc.ts"],"sourcesContent":["'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n  , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n  Events.prototype = Object.create(null);\n\n  //\n  // This hack is needed because the `__proto__` property is still inherited in\n  // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n  //\n  if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n  this.fn = fn;\n  this.context = context;\n  this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n  if (typeof fn !== 'function') {\n    throw new TypeError('The listener must be a function');\n  }\n\n  var listener = new EE(fn, context || emitter, once)\n    , evt = prefix ? prefix + event : event;\n\n  if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n  else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n  else emitter._events[evt] = [emitter._events[evt], listener];\n\n  return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n  if (--emitter._eventsCount === 0) emitter._events = new Events();\n  else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n  this._events = new Events();\n  this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n  var names = []\n    , events\n    , name;\n\n  if (this._eventsCount === 0) return names;\n\n  for (name in (events = this._events)) {\n    if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n  }\n\n  if (Object.getOwnPropertySymbols) {\n    return names.concat(Object.getOwnPropertySymbols(events));\n  }\n\n  return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n  var evt = prefix ? prefix + event : event\n    , handlers = this._events[evt];\n\n  if (!handlers) return [];\n  if (handlers.fn) return [handlers.fn];\n\n  for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n    ee[i] = handlers[i].fn;\n  }\n\n  return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n  var evt = prefix ? prefix + event : event\n    , listeners = this._events[evt];\n\n  if (!listeners) return 0;\n  if (listeners.fn) return 1;\n  return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n  var evt = prefix ? prefix + event : event;\n\n  if (!this._events[evt]) return false;\n\n  var listeners = this._events[evt]\n    , len = arguments.length\n    , args\n    , i;\n\n  if (listeners.fn) {\n    if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n    switch (len) {\n      case 1: return listeners.fn.call(listeners.context), true;\n      case 2: return listeners.fn.call(listeners.context, a1), true;\n      case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n      case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n      case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n      case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n    }\n\n    for (i = 1, args = new Array(len -1); i < len; i++) {\n      args[i - 1] = arguments[i];\n    }\n\n    listeners.fn.apply(listeners.context, args);\n  } else {\n    var length = listeners.length\n      , j;\n\n    for (i = 0; i < length; i++) {\n      if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n      switch (len) {\n        case 1: listeners[i].fn.call(listeners[i].context); break;\n        case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n        case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n        case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n        default:\n          if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n            args[j - 1] = arguments[j];\n          }\n\n          listeners[i].fn.apply(listeners[i].context, args);\n      }\n    }\n  }\n\n  return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n  return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n  return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n  var evt = prefix ? prefix + event : event;\n\n  if (!this._events[evt]) return this;\n  if (!fn) {\n    clearEvent(this, evt);\n    return this;\n  }\n\n  var listeners = this._events[evt];\n\n  if (listeners.fn) {\n    if (\n      listeners.fn === fn &&\n      (!once || listeners.once) &&\n      (!context || listeners.context === context)\n    ) {\n      clearEvent(this, evt);\n    }\n  } else {\n    for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n      if (\n        listeners[i].fn !== fn ||\n        (once && !listeners[i].once) ||\n        (context && listeners[i].context !== context)\n      ) {\n        events.push(listeners[i]);\n      }\n    }\n\n    //\n    // Reset the array, or remove it completely if we have no more listeners.\n    //\n    if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n    else clearEvent(this, evt);\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n  var evt;\n\n  if (event) {\n    evt = prefix ? prefix + event : event;\n    if (this._events[evt]) clearEvent(this, evt);\n  } else {\n    this._events = new Events();\n    this._eventsCount = 0;\n  }\n\n  return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n  module.exports = EventEmitter;\n}\n","import type { MPDError, MPDInitialResponse, MPDResponse } from \"./protocol.js\";\n\nexport function getOptionalNumber(valueMap: Map<string, string>, key: string): number | undefined {\n  return valueMap.has(key) ? Number(valueMap.get(key)) : undefined;\n}\n\nexport function getOptionalDate(valueMap: Map<string, string>, key: string): Date | undefined {\n  return valueMap.has(key) ? new Date(valueMap.get(key)!) : undefined;\n}\n\nexport function getOptionalBoolean(valueMap: Map<string, string>, key: string): boolean | undefined {\n  return valueMap.has(key) ? Boolean(Number(valueMap.get(key))) : undefined;\n}\n\nexport function parseOptionalNumber(num: string | undefined): number | undefined {\n  return (num !== undefined) ? Number(num) : undefined;\n}\n\nexport function isInitialResponse(response: MPDInitialResponse | MPDResponse | MPDError): response is MPDInitialResponse {\n  return 'version' in response;\n}\n\nexport function isError(response: MPDInitialResponse | MPDResponse | MPDError): response is MPDError {\n  return 'errorMessage' in response;\n}\n\n/**\n * Helper function for parsing a response from the daemon into an array of objects\n * @param lines    The daemon response\n * @param markers  Markers are keys denoting the start of a new object within the response\n * @param convert  Converts a key-value Map from the response into the desired target object\n */\nexport function parse<T>(lines: string[], markers: string[], convert: (valueMap: Map<string, string>) => T): T[] {\n  const result = new Array<T>();\n  let currentValueMap = new Map<string, string>();\n  let lineCount = 0;\n\n  lines.forEach(line => {\n    const colonIndex = line.indexOf(':');\n    if (colonIndex > 0) {\n      const key = line.substring(0, colonIndex);\n      const value = line.substring(colonIndex + 2);\n      if ((lineCount > 0) && markers.some(marker => (marker == key))) {\n        result.push(convert(currentValueMap));\n        currentValueMap = new Map<string, string>();\n      }\n      if (currentValueMap.has(key)) {\n        const multiValue = [currentValueMap.get(key), value].join(';');\n        currentValueMap.set(key, multiValue);\n      }\n      else {\n        currentValueMap.set(key, value);\n      }\n      lineCount++;\n    }\n  });\n  if (lineCount > 0) {\n    result.push(convert(currentValueMap));\n  }\n\n  return result;\n}\n\nexport function concatUint8Arrays(src1: Uint8Array, src2: Uint8Array): Uint8Array {\n  const result = new Uint8Array(src1.length + src2.length);\n  result.set(src1, 0);\n  result.set(src2, src1.length);\n  return result;\n}\n","import { EventEmitter } from 'eventemitter3';\nimport { decodeLines, groupResponseLines } from './transform.js';\nimport { isError, isInitialResponse } from './util.js';\n\n/**\n * Implements the [general syntax](http://www.musicpd.org/doc/protocol/syntax.html)\n * of the [Music Player Daemon protocol](http://www.musicpd.org/doc/protocol/index.html)\n */\nexport class MPDProtocol extends EventEmitter {\n\n  private readonly encoder = new TextEncoder();\n\n  private _connection?: {\n    responseStream: ReadableStream<MPDInitialResponse | MPDResponse | MPDError>;\n    responseReader: ReadableStreamDefaultReader<MPDInitialResponse | MPDResponse | MPDError>;\n    send: (msg: Uint8Array) => void;\n  }\n\n  private ready = false;\n  private idle = false;\n  private queuedRequests: MPDRequest[] = [];\n  private runningRequests: MPDRequest[] = [];\n\n  /**\n   * The version (major, minor, patch) of the connected daemon\n   */\n  mpdVersion?: [number, number, number];\n\n  get isReady() { return this.ready; }\n\n  /**\n   * Connect to the daemon\n   */\n  protected connect(\n    byteStream: ReadableStream<ArrayBufferLike>,\n    send: (msg: Uint8Array) => void\n  ): Promise<void> {\n\n    if (this._connection) {\n      throw new Error('Client is already connected');\n    }\n\n    const responseStream = byteStream\n      .pipeThrough(decodeLines())\n      .pipeThrough(groupResponseLines());\n\n    this._connection = {\n      responseStream,\n      responseReader: responseStream.getReader(),\n      send,\n    };\n\n    return new Promise<void>(resolve => this.processResponses(resolve));\n  }\n\n  private async processResponses(initialCallback: () => void) {\n    const reader = this._connection!.responseReader;\n    try {\n      while (true) {\n        const { done, value } = await reader.read();\n\n        if (done) {\n          this.emit('socket-end');\n          this.disconnect();\n          return;\n        }\n\n        if (isInitialResponse(value)) {\n          this.mpdVersion = value.version;\n          this.ready = true;\n          initialCallback();\n          this.emit('ready');\n          this.dequeueRequests();\n          continue;\n        }\n\n        if (this.runningRequests.length === 0) {\n          const message = isError(value) ? value.errorMessage : value.lines.join('\\n');\n          const errorMessage = `Received unexpected message:\\n${message}`;\n          this.emit('socket-error', errorMessage);\n          this.disconnect({ errorCode: -1, errorMessage });\n          return;\n        }\n\n        const request = this.runningRequests.shift()!;\n        if (!isError(value)) {\n          request.resolve(value);\n        } else {\n          request.reject(value);\n          this.queuedRequests.push(...this.runningRequests);\n          this.runningRequests = [];\n        }\n\n        if (this.runningRequests.length === 0) {\n          this.dequeueRequests();\n        }\n      }\n    } catch (err) {\n      this.emit('socket-error', err);\n      this.disconnect({ errorCode: -1, errorMessage: `Unknown error: ${err}`});\n    }\n  }\n\n  /**\n   * Disconnect from the daemon\n   */\n  disconnect(err = { errorCode: -1, errorMessage: 'Disconnected' }) {\n\n    this.runningRequests.forEach(request => request.reject(err));\n    this.queuedRequests.forEach(request => request.reject(err));\n\n    this.ready = false;\n    this.idle = false;\n    this.runningRequests = [];\n    this.queuedRequests = [];\n    this.mpdVersion = undefined;\n\n    const connection = this._connection;\n    if (connection) {\n      this._connection = undefined;\n      connection.responseReader.releaseLock();\n      connection.responseStream.cancel();\n    }\n  }\n\n  /**\n   * Send a command to the daemon. The returned promise will be resolved with an array\n   * containing the lines of the daemon's response.\n   */\n  sendCommand(cmd: string): Promise<MPDResponse> {\n    return new Promise<MPDResponse>((resolve, reject) => {\n      const mpdRequest = { cmd, resolve, reject };\n      this.enqueueRequest(mpdRequest);\n    });\n  }\n\n  private enqueueRequest(mpdRequest: MPDRequest) {\n\n    if (!this._connection) throw new Error('Not connected');\n\n    this.queuedRequests.push(mpdRequest);\n    if (this.idle) {\n      this.send('noidle\\n');\n      this.idle = false;\n    }\n  }\n\n  private dequeueRequests() {\n    if (this.queuedRequests.length > 0) {\n      this.runningRequests = this.queuedRequests;\n      this.queuedRequests = [];\n      this.idle = false;\n    } else {\n      this.runningRequests = [{ cmd: 'idle', resolve: response => this.idleCallback(response), reject: () => {} }];\n      this.idle = true;\n    }\n    let commandString: string;\n    if (this.runningRequests.length == 1) {\n      commandString = this.runningRequests[0]!.cmd + '\\n';\n    } else {\n      commandString = 'command_list_ok_begin\\n';\n      this.runningRequests.forEach(command => {\n        commandString += command.cmd + '\\n';\n      });\n      commandString += 'command_list_end\\n';\n    }\n    this.send(commandString);\n  }\n\n  private idleCallback(response: MPDResponse) {\n    this.idle = false;\n    const subsystems = response.lines.map(changed => changed.substring(9));\n    this.emit('changed', subsystems);\n    subsystems.forEach(subsystem => this.emit(`changed-${subsystem}`));\n  }\n\n  private send(cmd: string) {\n    this._connection!.send(this.encoder.encode(cmd));\n  }\n}\n\nexport interface MPDInitialResponse {\n  version: [number, number, number];\n}\n\nexport interface MPDResponse {\n  lines: string[];\n  binary?: ArrayBuffer;\n};\n\n/**\n * A failure response from the daemon\n */\nexport interface MPDError {\n  errorCode: number;\n  errorMessage: string;\n}\n\ninterface MPDRequest {\n  cmd: string;\n  resolve: (response: MPDResponse) => void;\n  reject: (error: MPDError) => void;\n}\n","import type { MPDError, MPDInitialResponse, MPDResponse } from \"./protocol.js\";\nimport { concatUint8Arrays } from \"./util.js\";\n\nexport function decodeLines() {\n\n  const decoder = new TextDecoder();\n\n  let buffer: Uint8Array| undefined;\n  let binaryLength: number | undefined;\n\n  return new TransformStream<ArrayBuffer, string | ArrayBuffer>({\n    transform(data, controller) {\n      const chunk = new Uint8Array(data);\n      buffer = buffer ? concatUint8Arrays(buffer, chunk) : chunk;\n\n      while (true) {\n        if (binaryLength === undefined) {\n          const lineSeparatorIndex = buffer.indexOf(10);\n          if (lineSeparatorIndex < 0) {\n            break;\n          }\n\n          const decodedLine = decoder.decode(buffer.subarray(0, lineSeparatorIndex));\n          buffer = buffer.subarray(lineSeparatorIndex + 1);\n\n          if (decodedLine.startsWith(\"binary: \")) {\n            binaryLength = parseInt(decodedLine.substring(8));\n          } else {\n            controller.enqueue(decodedLine);\n          }\n        } else {\n          if (buffer.length <= binaryLength) {\n            break;\n          }\n          controller.enqueue(buffer.slice(0, binaryLength).buffer);\n          buffer = buffer.subarray(binaryLength + 1);\n          binaryLength = undefined;\n        }\n      }\n    }\n  });\n}\n\nexport function groupResponseLines() {\n\n  const initialRegExp = /^OK MPD ([0-9]+)\\.([0-9]+)\\.([0-9]+)/;\n  const failureRegExp = /ACK \\[([0-9]+)@[0-9]+\\] \\{[^\\}]*\\} (.*)/;\n\n  let initialized = false;\n  let receivingList = false;\n  let currentResponse: MPDResponse = { lines: [] };\n\n  return new TransformStream<string | ArrayBuffer, MPDInitialResponse | MPDResponse | MPDError>({\n    transform(data, controller) {\n\n      if (!initialized) {\n\n        if (typeof data === 'string') {\n          const match = initialRegExp.exec(data);\n          if (match) {\n            initialized = true;\n            controller.enqueue({ version: [ Number(match[1]), Number(match[2]), Number(match[3]) ] });\n            return;\n          }\n        }\n\n        controller.error(`Unexpected initial message: ${data}`);\n\n      } else if (typeof data === 'string') {\n\n        if (data === 'OK') {\n\n          if (!receivingList) {\n            controller.enqueue(currentResponse);\n            currentResponse = { lines: [] };\n          }\n          receivingList = false;\n\n        } else if (data === 'list_OK') {\n\n          controller.enqueue(currentResponse);\n          currentResponse = { lines: [] };\n          receivingList = true;\n\n        } else if (data.startsWith('ACK [')) {\n\n          let mpdError: MPDError;\n          const match = failureRegExp.exec(data);\n          if (match != null) {\n            mpdError = { errorCode: Number(match[1]), errorMessage: match[2]! };\n          } else {\n            mpdError = { errorCode: -1, errorMessage: `Unknown error: ${data}` };\n          }\n          controller.enqueue(mpdError);\n          currentResponse = { lines: [] };\n\n        } else {\n          currentResponse.lines.push(data);\n        }\n\n      } else {\n        currentResponse.binary = data;\n      }\n    }\n  });\n}\n","import { getOptionalNumber, getOptionalBoolean, parseOptionalNumber } from '../util.js';\n\n/**\n * The current status of the player\n */\nexport class Status {\n\n  /**\n   * the name of the current partition\n   */\n  partition?: string;\n\n  state?: 'play' | 'stop' | 'pause';\n\n  /**\n   * index of the currently playing or stopped on song within the playlist\n   */\n  song?: number;\n\n  /**\n   * playlist songid of the currently playing or stopped on song\n   */\n  songId?: number;\n\n  /**\n   * index of the next song within the playlist\n   */\n  nextSong?: number;\n\n  /**\n   * playlist songid of the next song\n   */\n  nextSongId?: number;\n\n  /**\n   * total time elapsed within the current song in seconds\n   */\n  elapsed?: number;\n\n  /**\n   * duration of the current song in seconds\n   */\n  duration?: number;\n\n  /**\n   * current bitrate in kbps\n   */\n  bitRate?: number;\n\n  /**\n   *  The format emitted by the decoder plugin during playback, format: \"samplerate:bits:channels\".\n   */\n  audio?: string;\n\n  sampleRate?: number;\n\n  bitDepth?: number;\n\n  channels?: number;\n\n  /**\n   * 0-100\n   */\n  volume?: number;\n\n  /**\n   * crossfade in seconds\n   */\n  xfade?: number;\n\n  /**\n   * mixramp threshold in dB\n   */\n  mixrampdb?: number;\n\n  /**\n   * mixramp delay in seconds\n   */\n  mixrampDelay?: number;\n\n  /**\n   * 31-bit unsigned integer, the playlist version number\n   */\n  playlistVersion?: number;\n\n  /**\n   * integer, the length of the playlist\n   */\n  playlistLength?: number;\n\n  repeat?: boolean;\n\n  random?: boolean;\n\n  single?: boolean | 'oneshot';\n\n  consume?: boolean;\n\n  /**\n   * update job id\n   */\n  updating?: number;\n\n  error?: string;\n\n  constructor(valueMap: Map<string, string>) {\n    this.partition = valueMap.get('partition');\n    this.state = <'play' | 'stop' | 'pause'>valueMap.get('state');\n    this.song = getOptionalNumber(valueMap, 'song');\n    this.songId = getOptionalNumber(valueMap, 'songid');\n    this.nextSong = getOptionalNumber(valueMap, 'nextsong');\n    this.nextSongId = getOptionalNumber(valueMap, 'nextsongid');\n    this.elapsed = getOptionalNumber(valueMap, 'elapsed');\n    this.duration = getOptionalNumber(valueMap, 'duration');\n    this.bitRate = getOptionalNumber(valueMap, 'bitrate');\n    this.audio = valueMap.get('audio');\n    const splitAudio = this.audio ? this.audio.split(':') : [];\n    this.sampleRate = parseOptionalNumber(splitAudio[0]);\n    this.bitDepth = parseOptionalNumber(splitAudio[1]);\n    this.channels = parseOptionalNumber(splitAudio[2]);\n    this.volume = getOptionalNumber(valueMap, 'volume');\n    this.xfade = getOptionalNumber(valueMap, 'xfade');\n    this.mixrampdb = getOptionalNumber(valueMap, 'mixrampdb');\n    this.mixrampDelay = getOptionalNumber(valueMap, 'mixrampdelay');\n    this.playlistVersion = getOptionalNumber(valueMap, 'playlist');\n    this.playlistLength = getOptionalNumber(valueMap, 'playlistlength');\n    this.repeat = getOptionalBoolean(valueMap, 'repeat');\n    this.random = getOptionalBoolean(valueMap, 'random');\n    const singleString = valueMap.get('single');\n    if (singleString !== undefined) {\n      this.single = (singleString === 'oneshot') ? 'oneshot' : Boolean(Number(singleString));\n    }\n    this.consume = getOptionalBoolean(valueMap, 'consume');\n    this.updating = getOptionalNumber(valueMap, 'updating_db');\n    this.error = valueMap.get('error');\n  }\n}\n","import { getOptionalNumber } from '../util.js';\n\nexport class Statistics {\n\n  /**\n   * the number of artists in the database\n   */\n  artists?: number;\n\n  /**\n   * the number of albums in the database\n   */\n  albums?: number;\n\n  /**\n   * the number of sonds in the database\n   */\n  songs?: number;\n\n  /**\n   * daemon uptime in seconds\n   */\n  uptime?: number;\n\n  /**\n   * sum of all song lengths in the database in seconds\n   */\n  dbPlaytime?: number;\n\n  /**\n   * time of last database update\n   */\n  dbUpdate?: Date;\n\n  /**\n   * time length in seconds of music played\n   */\n  playtime?: number;\n\n  constructor(valueMap: Map<string, string>) {\n    this.artists = getOptionalNumber(valueMap, 'artists');\n    this.albums = getOptionalNumber(valueMap, 'albums');\n    this.songs = getOptionalNumber(valueMap, 'songs');\n    this.uptime = getOptionalNumber(valueMap, 'uptime');\n    this.dbPlaytime = getOptionalNumber(valueMap, 'db_playtime');\n    this.dbUpdate = valueMap.has('db_update') ? new Date(Number(valueMap.get('db_update')) * 1000) : undefined;\n    this.playtime = getOptionalNumber(valueMap, 'playtime');\n  }\n}\n","import { getOptionalDate } from '../util.js';\n\nexport class StoredPlaylist {\n\n  name: string;\n  lastModified?: Date;\n\n  constructor(valueMap: Map<string, string>) {\n\n    if (!valueMap.has('playlist')) throw new Error('Name not found for StoredPlaylist object');\n\n    this.name = valueMap.get('playlist')!;\n    this.lastModified = getOptionalDate(valueMap, 'Last-Modified');\n  }\n}\n\nexport class PlaylistItem {\n\n  id?: number;\n  position?: number;\n  title?: string;\n  name?: string;\n  artist?: string;\n  album?: string;\n  albumArtist?: string;\n  track?: string;\n  date?: string;\n  genre?: string;\n  duration?: number;\n  path?: string;\n  lastModified?: Date;\n\n  constructor(valueMap: Map<string, string>) {\n    this.id = valueMap.has('Id') ? Number(valueMap.get('Id')) : undefined;\n    this.position = valueMap.has('Pos') ? Number(valueMap.get('Pos')) : undefined;\n    this.title = valueMap.get('Title');\n    this.name = valueMap.get('Name');\n    this.artist = valueMap.get('Artist');\n    this.album = valueMap.get('Album');\n    this.albumArtist = valueMap.get('AlbumArtist');\n    this.track = valueMap.get('Track');\n    this.date = valueMap.get('Date');\n    this.genre = valueMap.get('Genre');\n    const durationString = valueMap.get('duration') || valueMap.get('Time');\n    this.duration = durationString ? Number(durationString) : undefined;\n    this.path = valueMap.get('file');\n    this.lastModified = getOptionalDate(valueMap, 'Last-Modified');\n  }\n}\n\nexport class SongIdAndPosition {\n\n  songId: number;\n  position: number;\n\n  constructor(valueMap: Map<string, string>) {\n    this.songId = Number(valueMap.get('Id'));\n    this.position = Number(valueMap.get('cpos'));\n  }\n}\n","import { getOptionalDate, parseOptionalNumber } from '../util.js';\n\n/**\n * The types of objects in the music database\n */\nexport declare type DirectoryEntryType = 'file' | 'song' | 'playlist' | 'directory';\n\n/**\n * Base class for objects in the music database.\n */\nexport class DirectoryEntry {\n\n  path: string;\n  lastModified?: Date;\n  entryType: DirectoryEntryType;\n\n  constructor(valueMap: Map<string, string>, pathKey: string, entryType: DirectoryEntryType) {\n\n    if (!valueMap.has(pathKey)) throw new Error('Path not found for DirectoryEntry object');\n\n    this.entryType = entryType;\n    this.path = valueMap.get(pathKey)!;\n    this.lastModified = getOptionalDate(valueMap,'Last-Modified');\n  }\n\n  static fromValueMap(valueMap: Map<string, string>, withMetadata = true): DirectoryEntry {\n    if (valueMap.get('file')) {\n      if (withMetadata) {\n        return new Song(valueMap);\n      } else {\n        return new File(valueMap);\n      }\n    } else if (valueMap.get('directory')) {\n      return new Directory(valueMap);\n    } else if (valueMap.get('playlist')) {\n      return new Playlist(valueMap);\n    } else {\n      const keys = [ ...valueMap.keys() ].map(key => `'${key}'`).join(', ');\n      throw new Error(`Couldn't determine type of directory entry with keys ${keys}`)\n    }\n  }\n\n  isFile(): this is File { return this.entryType === 'file'; }\n  isSong(): this is Song { return this.entryType === 'song'; }\n  isPlaylist(): this is Playlist { return this.entryType === 'playlist'; }\n  isDirectory(): this is Directory { return this.entryType === 'directory'; }\n}\n\nexport class File extends DirectoryEntry {\n\n  declare entryType: 'file';\n  size?: number;\n\n  constructor(valueMap: Map<string, string>) {\n    super(valueMap, 'file', 'file');\n    this.size = valueMap.has('size') ? Number(valueMap.get('size')) : undefined;\n  }\n}\n\nexport class Song extends DirectoryEntry {\n\n  declare entryType: 'song';\n\n  /**\n   * the song title\n   */\n  title?: string;\n\n  /**\n   * same as title, but for sorting\n   */\n  titleSort?: string;\n\n  /**\n   * a name for this song. This is not the song title. The exact meaning of this tag is not well-defined.\n   * It is often used by badly configured internet radio stations with broken tags to squeeze both\n   * the artist name and the song title in one tag\n   */\n  name?: string;\n\n  /**\n   * the artist name. Its meaning is not well-defined; see “composer” and “performer” for more specific tags\n   */\n  artist?: string;\n\n  /**\n   * same as artist, but for sorting. This usually omits prefixes such as “The”\n   */\n  artistSort?: string;\n\n  /**\n   * the artist who composed the song\n   */\n  composer?: string;\n\n  /**\n   * same as composer, but for sorting\n   */\n  composerSort?: string;\n\n  /**\n   * the artist who performed the song\n   */\n  performer?: string;\n\n  /**\n   * the conductor who conducted the song\n   */\n  conductor?: string;\n\n  /**\n   * the album name\n   */\n  album?: string;\n\n  /**\n   * same as album, but for sorting\n   */\n  albumSort?: string;\n\n  /**\n   * on multi-artist albums, this is the artist name which shall be used for the whole album.\n   * The exact meaning of this tag is not well-defined\n   */\n  albumArtist?: string;\n\n  /**\n   * same as albumArtist, but for sorting\n   */\n  albumArtistSort?: string;\n\n  /**\n   * the decimal track number within the album\n   */\n  track?: string;\n\n  /**\n   * the decimal disc number in a multi-disc album\n   */\n  disc?: string;\n\n  /**\n   * the name of the label or publisher\n   */\n  label?: string;\n\n  /**\n   * the song’s release date. This is usually a 4-digit year\n   */\n  date?: string;\n\n  /**\n   * the song’s original release date\n   */\n  originalDate?: string;\n\n  /**\n   * the music genre\n   */\n  genre?: string;\n\n  /**\n   * the mood of the audio with a few keywords\n   */\n  mood?: string;\n\n  /**\n   * “a work is a distinct intellectual or artistic creation,\n   * which can be expressed in the form of one or more audio recordings”\n   */\n  work?: string;\n\n  /**\n   * the ensemble performing this song, e.g. “Wiener Philharmoniker”\n   */\n  ensemble?: string;\n\n  /**\n   * name of the movement, e.g. “Andante con moto”\n   */\n  movement?: string;\n\n  /**\n   * movement number, e.g. “2” or “II”\n   */\n  movementNumber?: string;\n\n  /**\n   * If this is true players supporting this tag will display the work,\n   * movement, and movementnumber` instead of the track title\n   */\n  showMovement?: boolean;\n\n  /**\n   * location of the recording, e.g. “Royal Albert Hall”\n   */\n  location?: string;\n\n  /**\n   * “used if the sound belongs to a larger category of sounds/music”\n   */\n  grouping?: string;\n\n  /**\n   * a human-readable comment about this song. The exact meaning of this tag is not well-defined\n   */\n  comment?: string;\n\n  /**\n   * the artist id in the MusicBrainz database\n   */\n  musicBrainzArtistId?: string;\n\n  /**\n   * the album id in the MusicBrainz database\n   */\n  musicBrainzAlbumId?: string;\n\n  /**\n   * the album artist id in the MusicBrainz database\n   */\n  musicBrainzAlbumArtistId?: string;\n\n  /**\n   * the track id in the MusicBrainz database\n   */\n  musicBrainzTrackId?: string;\n\n  /**\n   * the release group id in the MusicBrainz database\n   */\n  musicBrainzReleaseGroupId?: string;\n\n  /**\n   * the release track id in the MusicBrainz database\n   */\n  musicBrainzReleaseTrackId?: string;\n\n  /**\n   * the work id in the MusicBrainz database\n   */\n  musicBrainzWorkId?: string;\n\n  /**\n   * the duration of the song in seconds; may contain a fractional part\n   */\n  duration?: number;\n\n  /**\n   *  The format emitted by the decoder plugin, format: \"samplerate:bits:channels\".\n   */\n  format?: string;\n\n  sampleRate?: number;\n\n  bitDepth?: number;\n\n  channels?: number;\n\n  constructor(valueMap: Map<string, string>) {\n    super(valueMap, 'file', 'song');\n    this.title = valueMap.get('Title');\n    this.titleSort = valueMap.get('TitleSort');\n    this.name =  valueMap.get('Name');\n    this.artist = valueMap.get('Artist');\n    this.artistSort = valueMap.get('ArtistSort');\n    this.composer = valueMap.get('Composer');\n    this.composerSort = valueMap.get('ComposerSort');\n    this.performer = valueMap.get('Performer');\n    this.conductor = valueMap.get('Conductor');\n    this.album = valueMap.get('Album');\n    this.albumSort = valueMap.get('AlbumSort');\n    this.albumArtist = valueMap.get('AlbumArtist');\n    this.albumArtistSort = valueMap.get('AlbumArtistSort');\n    this.track = valueMap.get('Track');\n    this.disc = valueMap.get('Disc');\n    this.label = valueMap.get('Label');\n    this.date = valueMap.get('Date');\n    this.originalDate = valueMap.get('OriginalDate');\n    this.genre = valueMap.get('Genre');\n    this.mood = valueMap.get('Mood');\n    this.work = valueMap.get('Work');\n    this.ensemble = valueMap.get('Ensemble');\n    this.movement = valueMap.get('Movement');\n    this.movementNumber = valueMap.get('MovementNumber');\n    this.showMovement = valueMap.get('ShowMovement') === '1';\n    this.location = valueMap.get('Location');\n    this.grouping = valueMap.get('Grouping');\n    this.comment = valueMap.get('Comment');\n    this.musicBrainzArtistId = valueMap.get('MUSICBRAINZ_ARTISTID');\n    this.musicBrainzAlbumId = valueMap.get('MUSICBRAINZ_ALBUMID');\n    this.musicBrainzAlbumArtistId = valueMap.get('MUSICBRAINZ_ALBUMARTISTID');\n    this.musicBrainzTrackId = valueMap.get('MUSICBRAINZ_TRACKID');\n    this.musicBrainzReleaseGroupId = valueMap.get('MUSICBRAINZ_RELEASEGROUPID');\n    this.musicBrainzReleaseTrackId = valueMap.get('MUSICBRAINZ_RELEASETRACKID');\n    this.musicBrainzWorkId = valueMap.get('MUSICBRAINZ_WORKID');\n    const durationString = valueMap.get('duration') || valueMap.get('Time');\n    this.duration = durationString ? Number(durationString) : undefined;\n    this.format = valueMap.get('format');\n    const splitFormat = this.format ? this.format.split(':') : [];\n    this.sampleRate = parseOptionalNumber(splitFormat[0]);\n    this.bitDepth = parseOptionalNumber(splitFormat[1]);\n    this.channels = parseOptionalNumber(splitFormat[2]);\n  }\n}\n\nexport class Playlist extends DirectoryEntry {\n\n  declare entryType: 'playlist';\n\n  constructor(valueMap: Map<string, string>) {\n    super(valueMap, 'playlist', 'playlist');\n  }\n}\n\nexport class Directory extends DirectoryEntry {\n\n  declare entryType: 'directory';\n\n  constructor(valueMap: Map<string, string>) {\n    super(valueMap, 'directory', 'directory');\n  }\n}\n\nexport class SongCount {\n\n  songs: number;\n  playtime: number;\n\n  constructor(valueMap: Map<string, string>) {\n\n    if (!valueMap.has('songs')) throw new Error('Number of songs not found for SongCount object');\n    if (!valueMap.has('playtime')) throw new Error('Playtime of songs not found for SongCount object');\n\n    this.songs = Number(valueMap.get('songs'));\n    this.playtime = Number(valueMap.get('playtime'));\n  }\n}\n\nexport class GroupedSongCount extends SongCount {\n\n  group: string;\n\n  constructor(valueMap: Map<string, string>, groupingTag: string) {\n    super(valueMap);\n\n    if (!valueMap.has(groupingTag)) throw new Error(`'${groupingTag}' not found for GroupedSongCount object`);\n\n    this.group = valueMap.get(groupingTag)!;\n  }\n}\n\nexport class GroupedTagList {\n  constructor(\n    public group: string[],\n    public tags: string[]\n  ) {}\n}\n\nexport class Picture {\n  constructor(\n    public data: ArrayBuffer,\n    public type: string\n  ) {}\n}\n","export class OutputDevice {\n\n  /** ID of the output. May change between executions. */\n  id: number;\n\n  /** Name of the output. It can be any. */\n  name: string;\n\n  /** Status of the output. */\n  enabled: boolean;\n\n  plugin?: string;\n\n  attributes: Map<string, string>;\n\n  constructor(valueMap: Map<string, string>) {\n\n    if (!valueMap.has('outputid')) throw new Error('ID not found for OutputDevice object');\n    if (!valueMap.has('outputname')) throw new Error('Name not found for OutputDevice object');\n    if (!valueMap.has('outputenabled')) throw new Error('Enabled flag not found for OutputDevice object');\n\n    this.id = Number(valueMap.get('outputid')!);\n    this.name = valueMap.get('outputname')!;\n    this.enabled = Boolean(Number(valueMap.get('outputenabled')!));\n    this.plugin = valueMap.get('plugin');\n\n    this.attributes = new Map<string, string>();\n    const attrsString = valueMap.get('attribute');\n    if (attrsString) {\n      const attrStrings = attrsString.split(';');\n      for (const attrString of attrStrings) {\n        const keyAndValue = attrString.split('=');\n        if (keyAndValue.length === 2) {\n          this.attributes.set(keyAndValue[0]!, keyAndValue[1]!);\n        }\n      }\n    }\n  }\n}\n","export class Mount {\n\n  path: string;\n  storage: string;\n\n  constructor(valueMap: Map<string, string>) {\n\n    if (!valueMap.has('mount')) throw new Error('Path not found for Mount object');\n    if (!valueMap.has('storage')) throw new Error('URI not found for Mount object');\n\n    this.path = valueMap.get('mount')!;\n    this.storage = valueMap.get('storage')!;\n  }\n}\n\nexport class Neighbor {\n\n  neighbor: string;\n  name: string;\n\n  constructor(valueMap: Map<string, string>) {\n\n    if (!valueMap.has('neighbor')) throw new Error('URI not found for Neighbor object');\n    if (!valueMap.has('storage')) throw new Error('Name not found for Neighbor object');\n\n    this.neighbor = valueMap.get('neighbor')!;\n    this.name = valueMap.get('name')!;\n  }\n}\n","export class Decoder {\n\n  name: string;\n  suffixes: string[];\n  mimeTypes: string[];\n\n  constructor(name: string) {\n    this.name = name;\n    this.suffixes = [];\n    this.mimeTypes = [];\n  }\n}\n","import { MPDProtocol } from '../protocol.js';\nimport { DirectoryEntry, File, GroupedTagList, Song, Playlist, Directory, SongCount, GroupedSongCount, Picture } from '../objects/database.js';\nimport { concatUint8Arrays, parse } from '../util.js';\n\nexport interface DatabaseCommands extends ReturnType<typeof createDatabaseCommands>{}\n\nexport const createDatabaseCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Counts the number of songs and their total playtime in the database that match exactly.\n   * `filter` is either a filter expression as described\n   * [here](https://www.musicpd.org/doc/html/protocol.html#filter-syntax)\n   * or an array of tuples containing a tag and the value that it should match.\n   * Note that tags are case sensitive and that the MPD documentation incorrectly lists all\n   * tags as lower-case. Use `mpc.connection.tagTypes()` to get the correct list of tags\n   * supported by MPD.\n   */\n  async count(filter: string | [string, string][] = []): Promise<SongCount> {\n    let cmd = 'count';\n    cmd = addFilter(cmd, filter);\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, [], valueMap => new SongCount(valueMap))[0]!;\n  },\n\n  /**\n   * Counts the number of songs and their total playtime in the database that match exactly.\n   * `filter` is either a filter expression as described\n   * [here](https://www.musicpd.org/doc/html/protocol.html#filter-syntax)\n   * or an array of tuples containing a tag and the value that it should match.\n   * The results are grouped by tag `groupingTag` (e.g. 'Artist', 'Album', 'Date', 'Genre')\n   * Note that tags are case sensitive and that the MPD documentation incorrectly lists all\n   * tags as lower-case. Use `mpc.connection.tagTypes()` to get the correct list of tags\n   * supported by MPD.\n   */\n  async countGrouped(groupingTag: string, filter: string | [string, string][] = []): Promise<GroupedSongCount[]> {\n    let cmd = 'count';\n    cmd = addFilter(cmd, filter);\n    cmd += ` group ${groupingTag}`;\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, [groupingTag], valueMap => new GroupedSongCount(valueMap, groupingTag));\n  },\n\n  /**\n   * Count the number of songs and their total playtime in the database matching the given filter.\n   * Parameters have the same meaning as for `count()` except the search is not case sensitive.\n   */\n  async searchCount(filter: string | [string, string][] = []): Promise<SongCount> {\n    let cmd = 'searchcount';\n    cmd = addFilter(cmd, filter);\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, [], valueMap => new SongCount(valueMap))[0]!;\n  },\n\n  /**\n   * Count the number of songs and their total playtime in the database matching the given filter.\n   * Parameters have the same meaning as for `countGrouped()` except the search is not case sensitive.\n   */\n  async searchCountGrouped(groupingTag: string, filter: string | [string, string][] = []): Promise<GroupedSongCount[]> {\n    let cmd = 'searchcount';\n    cmd = addFilter(cmd, filter);\n    cmd += ` group ${groupingTag}`;\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, [groupingTag], valueMap => new GroupedSongCount(valueMap, groupingTag));\n  },\n\n  /**\n   * Finds songs in the database that match exactly.\n   * `start` and `end` can be used to query only a portion of the real response.\n   * `sort` sorts the result by the specified tag. The sort is descending if the tag is prefixed with a\n   * minus (‘-‘). Without sort, the order is undefined. Only the first tag value will be used,\n   * if multiple of the same type exist. To sort by “Artist”, “Album” or “AlbumArtist”, you should\n   * specify “ArtistSort”, “AlbumSort” or “AlbumArtistSort” instead. These will automatically fall back\n   * to the former if “*Sort” doesn’t exist. “AlbumArtist” falls back to just “Artist”. The type\n   * “Last-Modified” can sort by file modification time.\n   * `filter` is either a filter expression as described\n   * [here](https://www.musicpd.org/doc/html/protocol.html#filter-syntax)\n   * or an array of tuples containing a tag or one of the special parameters listed below\n   * and the value that it should match. Supported special parameters are:\n   * * 'any' checks all tag values\n   * * 'file' checks the full path (relative to the music directory)\n   * * 'base' restricts the search to songs in the given directory (also relative to the music directory)\n   * * 'modified-since' compares the file's time stamp with the given value (ISO 8601 or UNIX time stamp)\n   * Note that tags are case sensitive and that the MPD documentation incorrectly lists all\n   * tags as lower-case. Use `mpc.connection.tagTypes()` to get the correct list of tags\n   * supported by MPD.\n   */\n  async find(filter: string | [string, string][], start?: number, end?: number, sort?: string): Promise<Song[]> {\n    let cmd = 'find';\n    cmd = addFilter(cmd, filter);\n    cmd = addSort(cmd, sort);\n    cmd = addWindow(cmd, start, end);\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['file'], valueMap => <Song>DirectoryEntry.fromValueMap(valueMap, true));\n  },\n\n  /**\n   * Finds songs in the database that match exactly and adds them to the current playlist.\n   * Parameters have the same meaning as for `find()` and `searchAdd()`.\n   */\n  async findAdd(filter: string | [string, string][], start?: number, end?: number, sort?: string, position?: number): Promise<void> {\n    let cmd = 'findadd';\n    cmd = addFilter(cmd, filter);\n    cmd = addSort(cmd, sort);\n    cmd = addWindow(cmd, start, end);\n    cmd = addPosition(cmd, position);\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Searches for any song that matches. Parameters have the same meaning as for `find()`,\n   * except that the search is a case insensitive substring search.\n   */\n  async search(filter: string | [string, string][], start?: number, end?: number, sort?: string): Promise<Song[]> {\n    let cmd = 'search';\n    cmd = addFilter(cmd, filter);\n    cmd = addSort(cmd, sort);\n    cmd = addWindow(cmd, start, end);\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['file'], valueMap => <Song>DirectoryEntry.fromValueMap(valueMap, true));\n  },\n\n  /**\n   * Searches for any song that matches and adds them to the current playlist.\n   * Parameters have the same meaning as for `search()`.\n   * The `position` parameter specifies where the songs will be inserted.\n   */\n  async searchAdd(filter: string | [string, string][], start?: number, end?: number, sort?: string, position?: number): Promise<void> {\n    let cmd = 'searchadd';\n    cmd = addFilter(cmd, filter);\n    cmd = addSort(cmd, sort);\n    cmd = addWindow(cmd, start, end);\n    cmd = addPosition(cmd, position);\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Searches for any song that matches and adds them to the playlist named `name`.\n   * If a playlist by that name doesn't exist it is created.\n   * Parameters have the same meaning as for `search()`.\n   * The `position` parameter specifies where the songs will be inserted.\n   */\n  async searchAddPlaylist(name: string, filter: string | [string, string][], start?: number, end?: number, sort?: string, position?: number): Promise<void> {\n    let cmd = `searchaddpl ${name}`;\n    cmd = addFilter(cmd, filter);\n    cmd = addSort(cmd, sort);\n    cmd = addWindow(cmd, start, end);\n    cmd = addPosition(cmd, position);\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Lists the contents of the directory `uri`, including files are not recognized by MPD.\n   * `uri` can be a path relative to the music directory or an URI understood by one of the\n   * storage plugins. For example, \"smb://SERVER\" returns a list of all shares on the given\n   * SMB/CIFS server; \"nfs://servername/path\" obtains a directory listing from the NFS server. \n   */\n  async listFiles(uri?: string): Promise<(File | Directory)[]> {\n    let cmd = 'listfiles';\n    if (uri) {\n      cmd += ` \"${uri}\"`;\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['file', 'directory'], valueMap => <File | Directory>DirectoryEntry.fromValueMap(valueMap, false));\n  },\n\n  /**\n   * Lists the contents of the directory `uri`. When listing the root directory, this currently\n   * returns the list of stored playlists. This behavior is deprecated; use `listPlaylists()`\n   * instead. This command may be used to list metadata of remote files (e.g. `uri` beginning\n   * with \"http://\" or \"smb://\"). Clients that are connected via UNIX domain socket may use this\n   * command to read the tags of an arbitrary local file (`uri` is an absolute path).\n   */\n  async listInfo(uri?: string): Promise<(Song | Playlist | Directory)[]> {\n    let cmd = 'lsinfo';\n    if (uri) {\n      cmd += ` \"${uri}\"`;\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['file', 'playlist', 'directory'], valueMap => <Song | Playlist | Directory>DirectoryEntry.fromValueMap(valueMap, true));\n  },\n\n  /**\n   * Lists all songs and directories in `uri` recursively. Do not use this command to manage a\n   * client-side copy of MPD's database. That is fragile and adds huge overhead.\n   * It will break with large databases. Instead, query MPD whenever you need something.\n   */\n  async listAll(uri?: string): Promise<string[]> {\n    let cmd = 'listall';\n    if (uri) {\n      cmd += ` \"${uri}\"`;\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    return lines.map(line => line.substring(line.indexOf(':') + 2));\n  },\n\n  /**\n   * Same as `listAll()`, except it also returns metadata info. Do not use this command to\n   * manage a client-side copy of MPD's database. That is fragile and adds huge overhead.\n   * It will break with large databases. Instead, query MPD whenever you need something.\n   */\n  async listAllInfo(uri?: string): Promise<(Song | Playlist | Directory)[]> {\n    let cmd = 'listallinfo';\n    if (uri) {\n      cmd += ` \"${uri}\"`;\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['file', 'playlist', 'directory'], valueMap => <Song | Playlist | Directory>DirectoryEntry.fromValueMap(valueMap, true));\n  },\n\n  /**\n   * Lists unique tags values of the specified type. `type` can be any tag supported by MPD\n   * or 'file', but 'file' is deprecated. `filter` specifies a filter like the one in `find()`.\n   * Note that tags are case sensitive and that the MPD documentation incorrectly lists all\n   * tags as lower-case. Use `mpc.connection.tagTypes()` to get the correct list of tags\n   * supported by MPD.\n   */\n  async list(type: string, filter: string | [string, string][] = []): Promise<string[]> {\n    let cmd = `list ${type}`;\n    cmd = addFilter(cmd, filter);\n    const { lines } = await protocol.sendCommand(cmd);\n    return lines.map(line => line.substring(type.length + 2));\n  },\n\n  /**\n   * Lists unique tags values of the specified type. `type` can be any tag supported by MPD\n   * or 'file', but 'file' is deprecated. `filter` specifies a filter like the one in `find()`.\n   * `groupingTags` are used to group the results by one or more tags.\n   * Note that tags are case sensitive and that the MPD documentation incorrectly lists all\n   * tags as lower-case. Use `mpc.connection.tagTypes()` to get the correct list of tags\n   * supported by MPD.\n   */\n  async listGrouped(type: string, groupingTags: [string, ...string[]], filter: string | [string, string][] = []): Promise<GroupedTagList[]> {\n    let cmd = `list ${type}`;\n    cmd = addFilter(cmd, filter);\n    groupingTags.forEach(tag => {\n      cmd += ` group ${tag}`;\n    });\n    const { lines } = await protocol.sendCommand(cmd);\n\n    const result: GroupedTagList[] = [];\n    let currentGroup = new Array(groupingTags.length).fill(\"\");\n    let currentTags: string[] = [];\n    function saveCurrentTags() {\n      if (currentTags.length > 0) {\n        result.push(new GroupedTagList(currentGroup, currentTags));\n        currentGroup = [...currentGroup];\n        currentTags = [];\n      }\n    }\n    lines.forEach(line => {\n      const colonIndex = line.indexOf(':');\n      if (colonIndex > 0) {\n        const key = line.substring(0, colonIndex);\n        const value = line.substring(colonIndex + 2);\n        if (groupingTags.includes(key)) {\n          saveCurrentTags();\n          currentGroup[groupingTags.indexOf(key)] = value;\n        } else {\n          currentTags.push(value);\n        }\n      }\n    });\n    saveCurrentTags();\n\n    return result;\n  },\n\n  /**\n   * Read \"comments\" (i.e. key-value pairs) from the file specified by `uri`. This `uri` can be\n   * a path relative to the music directory or an absolute path. This command may be used to list\n   * metadata of remote files (e.g. `uri` beginning with \"http://\" or \"smb://\").\n   * Comments with suspicious characters (e.g. newlines) are ignored silently.\n   * The meaning of these depends on the codec, and not all decoder plugins support it.\n   * For example, on Ogg files, this lists the Vorbis comments.\n   */\n  async readComments(uri: string): Promise<Map<string, string>> {\n    const cmd = `readcomments \"${uri}\"`;\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, [], valueMap => valueMap)[0]!;\n  },\n\n  /**\n   * Calculate the song’s audio fingerprint. This command is only available\n   * if MPD was built with `libchromaprint` (`-Dchromaprint=enabled`).\n   */\n  async getFingerprint(uri: string): Promise<string> {\n    const cmd = `getfingerprint \"${uri}\"`;\n    const { lines } = await protocol.sendCommand(cmd);\n    return lines[0]!.substring(13);\n  },\n\n  getAlbumArt(uri: string): Promise<Picture | undefined> {\n    return downloadPicture(protocol, `albumart \"${uri}\"`);\n  },\n\n  getPicture(uri: string): Promise<Picture | undefined> {\n    return downloadPicture(protocol, `readpicture \"${uri}\"`);\n  },\n\n  /**\n   * Updates the music database: find new files, remove deleted files, update modified files.\n   * `uri` is a particular directory or song/file to update. If you do not specify it, everything\n   * is updated. Returns a positive number identifying the update job. You can read the current\n   * job id in the status response. \n   */\n  async update(uri?: string): Promise<number> {\n    let cmd = 'update';\n    if (uri) {\n      cmd += ` \"${uri}\"`;\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    return Number(lines[0]!.substring(13));\n  },\n\n  /**\n   * Same as `update()`, but also rescans unmodified files.\n   */\n  async rescan(uri?: string): Promise<number> {\n    let cmd = 'rescan';\n    if (uri) {\n      cmd += ` \"${uri}\"`;\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    return Number(lines[0]!.substring(13));\n  },\n});\n\nexport function addFilter(cmd: string, filter: string | [string, string][]): string {\n  if (typeof filter === 'string') {\n    cmd += ` \"${filter.replace(/\\\\/g, '\\\\\\\\').replace(/\\\"/g, '\\\\\\\"')}\"`;\n  } else {\n    filter.forEach(tagAndNeedle => {\n      cmd += ` ${tagAndNeedle[0]} \"${tagAndNeedle[1]}\"`;\n    });\n  }\n  return cmd;\n}\n\nfunction addSort(cmd: string, sort?: string): string {\n  if (sort !== undefined) {\n    cmd += ` sort ${sort}`;\n  }\n  return cmd;\n}\n\nfunction addWindow(cmd: string, start?: number, end?: number): string {\n  if (start !== undefined) {\n    cmd += ` window ${start}:${(end !== undefined) ? end : ''}`;\n  }\n  return cmd;\n}\n\nfunction addPosition(cmd: string, position?: number): string {\n  if (position !== undefined) {\n    cmd += ` position ${position}`;\n  }\n  return cmd;\n}\n\nasync function downloadPicture(protocol: MPDProtocol, cmd: string): Promise<Picture | undefined> {\n  const { lines, binary } = await protocol.sendCommand(`${cmd} 0`);\n  const values = parse(lines, [], valueMap => valueMap)[0];\n  if (values && binary) {\n    const length = +values.get('size')!;\n    let buffer = new Uint8Array(binary);\n    while (buffer.byteLength < length) {\n      const { binary } = await protocol.sendCommand(`${cmd} ${buffer.byteLength}`);\n      buffer = concatUint8Arrays(buffer, new Uint8Array(binary!)) as Uint8Array<ArrayBuffer>;\n    }\n    return new Picture(buffer.buffer, values.get('type')!);\n  }\n  return undefined;\n}\n","import { MPDProtocol } from './protocol.js';\nimport { type StatusCommands, createStatusCommands } from './commands/status.js';\nimport { type PlaybackCommands, createPlaybackCommands } from './commands/playback.js';\nimport { type PlaybackOptionsCommands, createPlaybackOptionsCommands } from './commands/playbackOptions.js';\nimport { type CurrentPlaylistCommands, createCurrentPlaylistCommands } from './commands/currentPlaylist.js';\nimport { type StoredPlaylistsCommands, createStoredPlaylistsCommands } from './commands/storedPlaylists.js';\nimport { type DatabaseCommands, createDatabaseCommands } from './commands/database.js';\nimport { type MountCommands, createMountCommands } from './commands/mount.js';\nimport { type StickerCommands, createStickerCommands } from './commands/sticker.js';\nimport { type ConnectionCommands, createConnectionCommands } from './commands/connection.js';\nimport { type PartitionCommands, createPartitionCommands } from './commands/partition.js';\nimport { type OutputDeviceCommands, createOutputDeviceCommands } from './commands/outputDevice.js';\nimport { type ReflectionCommands, createReflectionCommands } from './commands/reflection.js';\nimport { type ClientToClientCommands, createClientToClientCommands } from './commands/clientToClient.js';\n\nexport class MPCCore extends MPDProtocol {\n\n  readonly status: StatusCommands;\n  readonly playback: PlaybackCommands;\n  readonly playbackOptions: PlaybackOptionsCommands;\n  readonly currentPlaylist: CurrentPlaylistCommands;\n  readonly storedPlaylists: StoredPlaylistsCommands;\n  readonly database: DatabaseCommands;\n  readonly mounts: MountCommands;\n  readonly stickers: StickerCommands;\n  readonly connection: ConnectionCommands;\n  readonly partition: PartitionCommands;\n  readonly outputDevices: OutputDeviceCommands;\n  readonly reflection: ReflectionCommands;\n  readonly clientToClient: ClientToClientCommands;\n\n  constructor() {\n    super();\n    this.status = createStatusCommands(this);\n    this.playback = createPlaybackCommands(this);\n    this.playbackOptions = createPlaybackOptionsCommands(this);\n    this.currentPlaylist = createCurrentPlaylistCommands(this);\n    this.storedPlaylists = createStoredPlaylistsCommands(this);\n    this.database = createDatabaseCommands(this);\n    this.mounts = createMountCommands(this);\n    this.stickers = createStickerCommands(this);\n    this.connection = createConnectionCommands(this);\n    this.partition = createPartitionCommands(this);\n    this.outputDevices = createOutputDeviceCommands(this);\n    this.reflection = createReflectionCommands(this);\n    this.clientToClient = createClientToClientCommands(this);\n  }\n}\n","import { MPDProtocol } from '../protocol.js';\nimport { PlaylistItem, Status, Statistics } from '../objects/index.js';\nimport { parse } from '../util.js';\n\nexport interface StatusCommands extends ReturnType<typeof createStatusCommands>{}\n\nexport const createStatusCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Displays the song info of the current song (same song that is identified in status).\n   */\n  async currentSong(): Promise<PlaylistItem> {\n    const { lines } = await protocol.sendCommand('currentsong');\n    return parse(lines, ['file'], valueMap => new PlaylistItem(valueMap))[0]!;\n  },\n\n  /**\n   * Reports the current status of the player and the volume level.\n   */\n  async status(): Promise<Status> {\n    const { lines } = await protocol.sendCommand('status');\n    return parse<Status>(lines, [], valueMap => new Status(valueMap))[0]!;\n  },\n\n  async statistics(): Promise<Statistics> {\n    const { lines } = await protocol.sendCommand('stats');\n    return parse<Statistics>(lines, [], valueMap => new Statistics(valueMap))[0]!;\n  },\n\n  /**\n   * Clears the current error message in status\n   */\n  async clearError(): Promise<void> {\n    await protocol.sendCommand('clearerror');\n  },\n});\n","import { MPDProtocol } from '../protocol.js';\n\nexport interface PlaybackCommands extends ReturnType<typeof createPlaybackCommands>{}\n\nexport const createPlaybackCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Begins playing the playlist at song number songPos.\n   */\n  async play(songPos?: number) {\n    let cmd = 'play';\n    if (songPos !== undefined) {\n      cmd += ` ${songPos}`;\n    }\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Begins playing the playlist at song with the given songId.\n   */\n  async playId(songId: number) {\n    let cmd = 'playid';\n    if (songId !== undefined) {\n      cmd += ` ${songId}`;\n    }\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Plays the previous song in the playlist.\n   */\n  async previous(): Promise<void> {\n    await protocol.sendCommand('previous');\n  },\n\n  /**\n   * Plays the next song in the playlist.\n   */\n  async next(): Promise<void> {\n    await protocol.sendCommand('next');\n  },\n\n  /**\n   * Seeks to the position time (in seconds; fractions allowed) of entry songPos in the playlist.\n   */\n  async seek(songPos: number, time: number) {\n    const cmd = `seek ${songPos} ${time}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Seeks to the position time (in seconds; fractions allowed) of song with the given songId. \n   */\n  async seekId(songId: number, time: number) {\n    const cmd = `seekid ${songId} ${time}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Seeks to the position time (in seconds; fractions allowed) within the current song.\n   * If relative is true, then the time is relative to the current playing position. \n   */\n  async seekCur(time: number, relative = false) {\n    let cmd: string; \n    if (relative && (time >= 0)) {\n      cmd = `seekcur +${time}`;\n    } else {\n      cmd = `seekcur ${time}`;\n    }\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Pauses or resumes playback.\n   */\n  async pause(pause: boolean = true): Promise<void> {\n    const cmd = `pause ${pause ? 1 : 0}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Stops playing.\n   */\n  async stop(): Promise<void> {\n    await protocol.sendCommand('stop');\n  },\n});\n","import { MPDProtocol } from '../protocol.js';\n\nexport interface PlaybackOptionsCommands extends ReturnType<typeof createPlaybackOptionsCommands>{}\n\nexport const createPlaybackOptionsCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Read the volume. The result is in the range 0-100. Returns undefined if there is no mixer.\n   */\n  async getVolume(): Promise<number | undefined> {\n    const { lines } = await protocol.sendCommand('getvol');\n    return lines[0] ? Number(lines[0].substring(8)) : undefined;\n  },\n\n  /**\n   * Sets volume, the range of volume is 0-100.\n   */\n  async setVolume(volume: number): Promise<void> {\n    const cmd = `setvol ${volume}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Changes volume by the given amount.\n   */\n  async changeVolume(change: number): Promise<void> {\n    const cmd = `volume ${change}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  async setRandom(random: boolean): Promise<void> {\n    const cmd = `random ${random ? 1 : 0}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Sets repeat state.\n   * If enabled, MPD keeps repeating the whole queue (single mode disabled) or the current song (single mode enabled).\n   * If random mode is also enabled, the playback order will be shuffled each time the queue gets repeated.\n   */\n  async setRepeat(repeat: boolean): Promise<void> {\n    const cmd = `repeat ${repeat ? 1 : 0}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Sets single state. When single is activated, playback is stopped after current song,\n   * or song is repeated if the 'repeat' mode is enabled.\n   */\n  async setSingle(single: boolean | 'oneshot'): Promise<void> {\n    const cmd = `single ${(single === 'oneshot') ? 'oneshot' : (single ? 1 : 0)}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Sets consume state. When consume is activated, each song played is removed from playlist.\n   */\n  async setConsume(consume: boolean): Promise<void> {\n    const cmd = `consume ${consume ? 1 : 0}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Sets crossfading between songs\n   */\n  async setCrossfade(seconds: number): Promise<void> {\n    const cmd = `crossfade ${seconds}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Sets the threshold at which songs will be overlapped. Like crossfading but doesn't fade the\n   * track volume, just overlaps. The songs need to have MixRamp tags added by an external tool.\n   * 0dB is the normalized maximum volume so use negative values, I prefer -17dB.\n   * In the absence of mixramp tags * crossfading will be used.\n   * See [http://sourceforge.net/projects/mixramp]\n   */\n  async setMixrampdb(decibels: number): Promise<void> {\n    const cmd = `mixrampdb ${decibels}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Additional time subtracted from the overlap calculated by mixrampdb.\n   * A value of null disables MixRamp overlapping and falls back to crossfading.\n   */\n  async setMixrampDelay(seconds: number): Promise<void> {\n    const cmd = `mixrampdelay ${seconds ? seconds : 'nan'}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Sets the replay gain mode. One of off, track, album, auto.\n   * Changing the mode during playback may take several seconds, because the new settings does\n   * not affect the buffered data. This command triggers the options idle event. \n   */\n  async setReplayGainMode(mode: 'off' | 'track' | 'album' | 'auto'): Promise<void> {\n    const cmd = `replay_gain_mode ${mode}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  async getReplayGainMode(): Promise<'off' | 'track' | 'album' | 'auto'> {\n    const { lines } = await protocol.sendCommand('replay_gain_status');\n    return <'off' | 'track' | 'album' | 'auto'>lines[0]!.substring(18);\n  },\n});\n","import { MPDProtocol } from '../protocol.js';\nimport { PlaylistItem, SongIdAndPosition } from '../objects/playlists.js';\nimport { parse } from '../util.js';\n\nexport interface CurrentPlaylistCommands extends ReturnType<typeof createCurrentPlaylistCommands>{}\n\nexport const createCurrentPlaylistCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Adds the file or directory `uri` to the playlist (directories add recursively).\n   * The position parameter is the same as in `addId()`.\n   */\n  async add(uri: string, position?: number): Promise<void> {\n    let cmd = `add \"${uri}\"`;\n    if (position !== undefined) {\n      cmd += ` ${position}`;\n    }\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Adds a song to the playlist (non-recursive) and returns the song id.\n   * `uri` is always a single file or URL.\n   * If the `position` parameter is given, then the song is inserted at the specified position.\n   */\n  async addId(uri: string, position?: number): Promise<number> {\n    let cmd = `addid \"${uri}\"`;\n    if (position !== undefined) {\n      cmd += ` ${position}`;\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    return Number(lines[0]!.substring(4));\n  },\n\n  /**\n   * Clears the current playlist.\n   */\n  async clear(): Promise<void> {\n    await protocol.sendCommand('clear');\n  },\n\n  /**\n   * Deletes a song from the playlist.\n   */\n  async delete(position: number): Promise<void> {\n    const cmd = `delete ${position}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Deletes a song range from the playlist.\n   */\n  async deleteRange(start: number, end?: number): Promise<void> {\n    let cmd = `delete ${start}:`;\n    if (end !== undefined) {\n      cmd += end;\n    }\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Deletes the song with the given songid from the playlist.\n   */\n  async deleteId(songId: number): Promise<void> {\n    const cmd = `deleteid ${songId}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Moves the song at `from` to `to` in the playlist.\n   */\n  async move(from: number, to: number): Promise<void> {\n    const cmd = `move ${from} ${to}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Moves the range of songs from `start` to `end` to `to` in the playlist.\n   */\n  async moveRange(start: number, end: number, to: number): Promise<void> {\n    const cmd = `move ${start}:${end} ${to}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Moves the song with the given songid to `to` the playlist.\n   * If `to` is negative, it is relative to the current song in the playlist (if there is one).\n   */\n  async moveId(songId: number, to: number): Promise<void> {\n    const cmd = `moveid ${songId} ${to}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Finds songs in the current playlist with strict matching.\n   */\n  async playlistFind(tag: string, needle: string): Promise<PlaylistItem[]> {\n    const cmd = `playlistfind \"${tag}\" \"${needle}\"`;\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['file'], valueMap => new PlaylistItem(valueMap));\n  },\n\n  /**\n   * Searches case-insensitively for partial matches in the current playlist.\n   */\n  async playlistSearch(tag: string, needle: string): Promise<PlaylistItem[]> {\n    const cmd = `playlistsearch \"${tag}\" \"${needle}\"`;\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['file'], valueMap => new PlaylistItem(valueMap));\n  },\n\n  /**\n   * Gets info for the song with the specified songid in the playlist.\n   */\n  async playlistId(songId: number): Promise<PlaylistItem> {\n    const cmd = `playlistid ${songId}`;\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, [], valueMap => new PlaylistItem(valueMap))[0]!;\n  },\n\n  /**\n   * Gets info for all songs or a single song in the playlist.\n   */\n  async playlistInfo(position?: number): Promise<PlaylistItem[]> {\n    let cmd = 'playlistinfo';\n    if (position !== undefined) {\n      cmd += ` ${position}`;\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['file'], valueMap => new PlaylistItem(valueMap));\n  },\n\n  /**\n   * Gets info for a range of songs in the playlist.\n   */\n  async playlistRangeInfo(start: number, end?: number): Promise<PlaylistItem[]> {\n    let cmd = `playlistinfo ${start}:`;\n    if (end !== undefined) {\n      cmd += `${end}`;\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['file'], valueMap => new PlaylistItem(valueMap));\n  },\n\n  /**\n   * Displays changed songs currently in the playlist since `version`. Start and end positions \n   * may be given to limit the output to changes in the given range. To detect songs that were \n   * deleted at the end of the playlist, use playlistlength returned by status command. \n   */\n  async playlistChanges(version: number, start?: number, end?: number): Promise<PlaylistItem[]> {\n    let cmd = `plchanges ${version}`;\n    if (start !== undefined) {\n      cmd += ` ${start}:`;\n      if (end !== undefined) {\n        cmd += end;\n      }\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['file'], valueMap => new PlaylistItem(valueMap));\n  },\n\n  /**\n   * Displays changed songs currently in the playlist since `version`. This function only returns\n   * the position and the id of the changed song, not the complete metadata. This is more\n   * bandwidth efficient. To detect songs that were deleted at the end of the playlist, use \n   * playlistlength returned by status command. \n   */\n  async playlistChangesPosId(version: number, start?: number, end?: number): Promise<SongIdAndPosition[]> {\n    let cmd = `plchangesposid ${version}`;\n    if (start !== undefined) {\n      cmd += ` ${start}:`;\n      if (end !== undefined) {\n        cmd += end;\n      }\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['cpos'], valueMap => new SongIdAndPosition(valueMap));\n  },\n\n  /**\n   * Set the priority of the specified songs. A higher priority means that it will be played \n   * first when \"random\" mode is enabled.\n   * A priority is an integer between 0 and 255. The default priority of new songs is 0.\n   */\n  async prio(priority: number, start: number, end:number): Promise<void> {\n    const cmd = `prio ${priority} ${start}:${end}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Same as prio, but address the songs with their songid.\n   */\n  async prioId(priority: number, songId: number): Promise<void> {\n    const cmd = `prioid ${priority} ${songId}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Specifies the portion of the song that shall be played. `start` and `end` are offsets \n   * in seconds (fractional seconds allowed); both are optional. Omitting both means \"remove the\n   * range, play everything\". A song that is currently playing cannot be manipulated this way.\n   */\n  async rangeId(songId: number, start?: number, end?: number): Promise<void> {\n    let cmd = `rangeid ${songId} `;\n    if (start !== undefined) {\n      cmd += start;\n    }\n    cmd += ':';\n    if (end !== undefined) {\n      cmd += end;\n    }\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Shuffles the current playlist. `start` and `end` is optional and specifies a range of songs.\n   */\n  async shuffle(start?: number, end?: number): Promise<void> {\n    let cmd = 'shuffle';\n    if (start !== undefined) {\n      cmd += ` ${start}:`;\n      if (end !== undefined) {\n        cmd += end;\n      }\n    }\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Swaps the positions of `song1` and `song2`.\n   */\n  async swap(song1: number, song2: number): Promise<void> {\n    const cmd = `swap ${song1} ${song2}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Swaps the positions of `song1` and `song2` (both songids).\n   */\n  async swapId(song1: number, song2: number): Promise<void> {\n    const cmd = `swapid ${song1} ${song2}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Adds a tag to the specified song. Editing song tags is only possible for remote songs.\n   * This change is volatile: it may be overwritten by tags received from the server, and the\n   * data is gone when the song gets removed from the queue.\n   */\n  async addTagId(songId: number, tag: string, value: string): Promise<void> {\n    const cmd = `addtagid ${songId} \"${tag}\" \"${value}\"`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Removes tags from the specified song. If `tag` is not specified, then all tag values will be\n   * removed. Editing song tags is only possible for remote songs.\n   */\n  async clearTagId(songId: number, tag?: string): Promise<void> {\n    let cmd = `cleartagid ${songId}`;\n    if (tag) {\n      cmd += ` \"${tag}\"`;\n    }\n    await protocol.sendCommand(cmd);\n  },\n});\n","import { MPDProtocol } from '../protocol.js';\nimport { SongCount } from '../objects/database.js';\nimport { StoredPlaylist, PlaylistItem } from '../objects/playlists.js';\nimport { parse } from '../util.js';\nimport { addFilter } from './database.js';\n\nexport interface StoredPlaylistsCommands extends ReturnType<typeof createStoredPlaylistsCommands>{}\n\nexport const createStoredPlaylistsCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Prints a list of the playlist directory. Each playlist name comes with its last \n   * modification time. To avoid problems due to clock differences between clients and the\n   * server, clients should not compare this value with their local clock. \n   */\n  async listPlaylists(): Promise<StoredPlaylist[]> {\n    const { lines } = await protocol.sendCommand('listplaylists');\n    return parse(lines, ['playlist'], valueMap => new StoredPlaylist(valueMap));\n  },\n\n  /**\n   * Lists the songs in the playlist. Playlist plugins are supported.\n   */\n  async listPlaylist(name: string): Promise<string[]> {\n    const cmd = `listplaylist \"${name}\"`;\n    const { lines } = await protocol.sendCommand(cmd);\n    return lines.map(line => line.substring(6));\n  },\n\n  /**\n   * Lists the songs with metadata in the playlist. Playlist plugins are supported.\n   */\n  async listPlaylistInfo(name: string): Promise<PlaylistItem[]> {\n    const cmd = `listplaylistinfo \"${name}\"`;\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['file'], valueMap => new PlaylistItem(valueMap));\n  },\n\n  /**\n   * Search the playlist for songs matching the given filter. Playlist plugins are supported.\n   */\n  async searchPlaylist(name: string, filter: string | [string, string][]): Promise<PlaylistItem[]> {\n    let cmd = `searchplaylist \"${name}\"`;\n    cmd = addFilter(cmd, filter);\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['file'], valueMap => new PlaylistItem(valueMap));\n  },\n\n  /**\n   * Count the number of songs and their total playtime (seconds) in the playlist.\n   */\n  async playlistLength(name: string): Promise<SongCount> {\n    const cmd = `playlistlength \"${name}\"`;\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, [], valueMap => new SongCount(valueMap))[0]!;\n  },\n\n  /**\n   * Loads the playlist into the current queue. Playlist plugins are supported.\n   * A range may be specified to load only a part of the playlist.\n   * The `position` parameter specifies where the songs will be inserted into the queue.\n   */\n  async load(name: string, start?: number, end?: number, position?: number): Promise<void> {\n    let cmd = `load \"${name}\"`;\n    if (start !== undefined) {\n      cmd += ` ${start}:`;\n      if (end !== undefined) {\n        cmd += end;\n      }\n    }\n    if (position !== undefined) {\n      if (start === undefined) {\n        cmd += ' 0:';\n      }\n      cmd += ` ${position}`;\n    }\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Saves the current playlist to `name`.m3u in the playlist directory.\n   */\n  async save(name: string): Promise<void> {\n    const cmd = `save \"${name}\"`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Adds `uri` to the playlist `name`.m3u. `name`.m3u will be created if it does not exist.\n   * The `position` parameter specifies where the songs will be inserted into the playlist.\n   */\n  async playlistAdd(name: string, uri: string, position?: number): Promise<void> {\n    let cmd = `playlistadd \"${name}\" \"${uri}\"`;\n    if (position !== undefined) {\n      cmd += ` ${position}`;\n    }\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Clears the playlist `name`.m3u.\n   */\n  async playlistClear(name: string): Promise<void> {\n    const cmd = `playlistclear \"${name}\"`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Deletes `position` from the playlist `name`.m3u.\n   */\n  async playlistDelete(name: string, position: number): Promise<void> {\n    const cmd = `playlistdelete \"${name}\" ${position}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Moves the song at position `from` in the playlist `name`.m3u to the position `to`.\n   */\n  async playlistMove(name: string, from: number, to: number): Promise<void> {\n    const cmd = `playlistmove \"${name}\" ${from} ${to}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Renames the playlist `name`.m3u to `newName`.m3u.\n   */\n  async rename(name: string, newName: string): Promise<void> {\n    const cmd = `rename \"${name}\" \"${newName}\"`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Removes the playlist `name`.m3u from the playlist directory.\n   */\n  async remove(name: string): Promise<void> {\n    const cmd = `rm \"${name}\"`;\n    await protocol.sendCommand(cmd);\n  },\n});\n","import { MPDProtocol } from '../protocol.js';\nimport { Mount, Neighbor } from '../objects/mount.js';\nimport { parse } from '../util.js';\n\nexport interface MountCommands extends ReturnType<typeof createMountCommands>{}\n\nexport const createMountCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Mount the specified remote storage `uri` at the given `path`.\n   */\n  async mount(path: string, uri: string): Promise<void> {\n    const cmd = `mount \"${path}\" \"${uri}\"`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Unmounts the specified `path`.\n   */\n  async unmount(path: string): Promise<void> {\n    const cmd = `unmount \"${path}\"`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Queries a list of all mounts. By default, this contains just the configured `music_directory`.\n   */\n  async listMounts(): Promise<Mount[]> {\n    const { lines } = await protocol.sendCommand('listmounts');\n    return parse(lines, ['mount'], valueMap => new Mount(valueMap));\n  },\n\n  /**\n   * Queries a list of \"neighbors\" (e.g. accessible file servers on the local net).\n   * Items on that list may be used with `mount()`.\n   */\n  async listNeighbors(): Promise<Neighbor[]> {\n    const { lines } = await protocol.sendCommand('listneighbors');\n    return parse(lines, ['neighbor'], valueMap => new Neighbor(valueMap));\n  },\n});\n","import { MPDProtocol } from '../protocol.js';\nimport { parse } from '../util.js';\n\nexport interface StickerCommands extends ReturnType<typeof createStickerCommands>{}\n\nexport const createStickerCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Reads a sticker value for the specified object.\n   */\n  async getSticker(type: string, uri: string, name: string): Promise<string> {\n    const cmd = `sticker get ${type} \"${uri}\" \"${name}\"`;\n    const { lines } = await protocol.sendCommand(cmd);\n    return lines[0]!.substring(name.length + 10);\n  },\n\n  /**\n   * Adds a sticker value to the specified object.\n   * If a sticker item with that name already exists, it is replaced.\n   */\n  async setSticker(type: string, uri: string, name: string, value: string): Promise<void> {\n    const cmd = `sticker set ${type} \"${uri}\" \"${name}\" \"${value}\"`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Adds a sticker value to the specified object. If a sticker item\n   * with that name already exists, it is incremented by supplied value.\n   */\n  async incrementSticker(type: string, uri: string, name: string, value: number): Promise<void> {\n    const cmd = `sticker inc ${type} \"${uri}\" \"${name}\" ${value}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Adds a sticker value to the specified object. If a sticker item\n   * with that name already exists, it is decremented by supplied value.\n   */\n  async decrementSticker(type: string, uri: string, name: string, value: number): Promise<void> {\n    const cmd = `sticker dec ${type} \"${uri}\" \"${name}\" ${value}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Deletes a sticker value from the specified object.\n   * If you do not specify a sticker name, all sticker values are deleted.\n   */\n  async deleteSticker(type: string, uri: string, name?: string): Promise<void> {\n    let cmd = `sticker delete ${type} \"${uri}\"`;\n    if (name) {\n      cmd += ` \"${name}\"`;\n    }\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Lists the stickers for the specified object.\n   * Returns a Map with sticker names as keys.\n   */\n  async listStickers(type: string, uri: string): Promise<Map<string, string>> {\n    const cmd = `sticker list ${type} \"${uri}\"`;\n    const { lines } = await protocol.sendCommand(cmd);\n    const stickerMap = new Map<string, string>();\n    lines.forEach(line => {\n      const separatorIndex = line.indexOf('=');\n      stickerMap.set(line.substring(9, separatorIndex), line.substring(separatorIndex + 1));\n    });\n    return stickerMap;\n  },\n\n  /**\n   * Searches the sticker database for stickers with the specified name,\n   * below the specified directory (`uri`).\n   * Returns a Map with the URIs of the matching songs as keys.\n   */\n  async findStickers(\n    type: string,\n    uri: string,\n    name: string,\n    value?: string, \n    operator: '=' | '<' | '>' = '='\n  ): Promise<Map<string, string>> {\n\n    let cmd = `sticker find ${type} \"${uri}\" \"${name}\"`;\n    if (value) {\n      cmd += ` ${operator} \"${value}\"`;\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    const fileAndStickers = parse(lines, ['file'], valueMap => valueMap);\n    const stickerMap = new Map<string, string>();\n    fileAndStickers.forEach(fileAndSticker => {\n      const fileValue = fileAndSticker.get('file');\n      let stickerValue = fileAndSticker.get('sticker');\n      if (fileValue && stickerValue) {\n        stickerValue = stickerValue.substring(name.length + 1);\n        stickerMap.set(fileValue, stickerValue);\n      }\n    });\n    return stickerMap;\n  },\n\n  /**\n   * Gets a list of uniq sticker names.\n   */\n  async getStickerNames(): Promise<string[]> {\n    const { lines } = await protocol.sendCommand('stickernames');\n    return lines.map(line => line.substring(6));\n  },\n\n  /**\n   * Gets a list of available sticker types.\n   */\n  async getStickerTypes(): Promise<string[]> {\n    const { lines } = await protocol.sendCommand('stickertypes');\n    return lines.map(line => line.substring(13));\n  },\n\n  /**\n   * Gets a list of uniq sticker names and their types.\n   */\n  async getStickerNamesTypes(type?: string): Promise<[string, string][]> {\n    let cmd = 'stickernamestypes';\n    if (type) {\n      cmd += ` ${type}`;\n    }\n    const { lines } = await protocol.sendCommand(cmd);\n    return parse(lines, ['name'], valueMap => [valueMap.get('name')!, valueMap.get('type')!]);\n  }\n});\n","import { MPDProtocol } from '../protocol.js';\n\nexport interface ConnectionCommands extends ReturnType<typeof createConnectionCommands>{}\n\nexport const createConnectionCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Closes the connection to MPD. MPD will try to send the remaining output buffer before it\n   * actually closes the connection, but that cannot be guaranteed. This command will not\n   * generate a response.\n   */\n  close(): void {\n    protocol.sendCommand('close');\n  },\n\n  /**\n   * Kills MPD.\n   */\n  kill(): void {\n    protocol.sendCommand('kill');\n  },\n\n  /**\n   * This is used for authentication with the server. `password` is simply the plaintext password.\n   */\n  async password(password: string): Promise<void> {\n    const cmd = `password \"${password}\"`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Does nothing but return \"OK\".\n   */\n  async ping(): Promise<void> {\n    await protocol.sendCommand('ping');\n  },\n\n  /**\n   * Set the maximum binary response size for the current connection to\n   * the specified number of bytes.\n   * A bigger value means less overhead for transmitting large entities,\n   * but it also means that the connection is blocked for a longer time.\n   */\n  async setBinaryLimit(size: number): Promise<void> {\n    await protocol.sendCommand(`binarylimit ${size}`);\n  },\n\n  /**\n   * Gets a list of available tag types. It is an intersection of the\n   * metadata_to_use setting and this client's tag mask.\n   * About the tag mask: each client can decide to disable any number of tag types,\n   * which will be omitted from responses to this client.\n   * That is a good idea, because it makes responses smaller.\n   */\n  async tagTypes(): Promise<string[]> {\n    const { lines } = await protocol.sendCommand('tagtypes');\n    return lines.map(line => line.substring(9));\n  },\n\n  /**\n   * Get the list of tag types configured by the `metadata_to_use` setting.\n   */\n  async getAvailableTagTypes(): Promise<string[]> {\n    const { lines } = await protocol.sendCommand('tagtypes available');\n    return lines.map(line => line.substring(9));\n  },\n\n  /**\n   * Remove one or more tags from the list of tag types the client is interested in.\n   * These will be omitted from responses to this client.\n   */\n  async disableTagTypes(names: string[]): Promise<void> {\n    if (names.length < 1) return;\n    const cmd = `tagtypes disable ${names.join(' ')}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Re-enable one or more tags from the list of tag types for this client.\n   * These will no longer be hidden from responses to this client.\n   */\n  async enableTagTypes(names: string[]): Promise<void> {\n    if (names.length < 1) return;\n    const cmd = `tagtypes enable ${names.join(' ')}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Clear the list of tag types this client is interested in.\n   * This means that MPD will not send any tags to this client.\n   */\n  async clearTagTypes(): Promise<void> {\n    await protocol.sendCommand('tagtypes clear');\n  },\n\n  /**\n   * Announce that this client is interested in all tag types.\n   * This is the default setting for new clients.\n   */\n  async allTagTypes(): Promise<void> {\n    await protocol.sendCommand('tagtypes all');\n  },\n\n  /**\n   * Set the list of enabled tag types for this client. These will no longer\n   * be hidden from responses to this client.\n   */\n  async setEnabledTagTypes(names: string[]): Promise<void> {\n    let cmd = 'tagtypes reset';\n    if (names.length > 0) {\n      cmd += ` ${names.join(' ')}`;\n    }\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Get a list of enabled protocol features. Available features:\n   * - `hide_playlists_in_root`: disables the listing of stored playlists for `listInfo()`.\n   */\n  async getEnabledProtocolFeatures(): Promise<string[]> {\n    const { lines } = await protocol.sendCommand('protocol');\n    return lines.map(line => line.substring(9));\n  },\n\n  /**\n   * Lists all available protocol features.\n   */\n  async getAvailableProtocolFeatures(): Promise<string[]> {\n    const { lines } = await protocol.sendCommand('protocol available');\n    return lines.map(line => line.substring(9));\n  },\n\n  /**\n   * Enables one or more features.\n   */\n  async enableProtocolFeatures(features: string[]): Promise<void> {\n    if (features.length < 1) return;\n    const cmd = `protocol enable ${features.join(' ')}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Disables one or more features.\n   */\n  async disableProtocolFeatures(features: string[]): Promise<void> {\n    if (features.length < 1) return;\n    const cmd = `protocol disable ${features.join(' ')}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Enables all protocol features.\n   */\n  async enableAllProtocolFeatures(): Promise<void> {\n    await protocol.sendCommand('protocol all');\n  },\n\n  /**\n   * Disables all protocol features.\n   */\n  async disableAllProtocolFeatures(): Promise<void> {\n    await protocol.sendCommand('protocol clear');\n  },\n});\n","import { MPDProtocol } from '../protocol.js';\nimport { parse } from '../util.js';\n\nexport interface PartitionCommands extends ReturnType<typeof createPartitionCommands>{}\n\nexport const createPartitionCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Switch the client to a different partition.\n   */\n  async partition(name: string): Promise<void> {\n    await protocol.sendCommand(`partition \"${name}\"`);\n  },\n\n  /**\n   * Returns a list of partitions.\n   */\n  async listPartitions(): Promise<string[]> {\n    const { lines } = await protocol.sendCommand('listpartitions');\n    return parse(lines, ['partition'], \n      valueMap => valueMap.get('partition')!);\n  },\n\n  /**\n   * Create a new partition.\n   */\n  async newPartition(name: string): Promise<void> {\n    await protocol.sendCommand(`newpartition \"${name}\"`);\n  },\n\n  /**\n   * Delete a partition. The partition must be empty (no connected clients and no outputs).\n   */\n  async deletePartition(name: string): Promise<void> {\n    await protocol.sendCommand(`delpartition \"${name}\"`);\n  },\n\n  /**\n   * Move an output to the current partition.\n   */\n  async moveOutput(outputName: string): Promise<void> {\n    await protocol.sendCommand(`moveoutput \"${outputName}\"`);\n  },\n});\n","import { MPDProtocol } from '../protocol.js';\nimport { OutputDevice } from '../objects/outputDevice.js';\nimport { parse } from '../util.js';\n\nexport interface OutputDeviceCommands extends ReturnType<typeof createOutputDeviceCommands>{}\n\nexport const createOutputDeviceCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Returns information about all outputs.\n   */\n  async outputs(): Promise<OutputDevice[]> {\n    const { lines } = await protocol.sendCommand('outputs');\n    return parse(lines, ['outputid'], valueMap => new OutputDevice(valueMap));\n  },\n\n  /**\n   * Turns an output on.\n   */\n  async enableOutput(id: number): Promise<void> {\n    const cmd = `enableoutput ${id}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Turns an output off.\n   */\n  async disableOutput(id: number): Promise<void> {\n    const cmd = `disableoutput ${id}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Turns an output on or off, depending on the current state.\n   */\n  async toggleOutput(id: number): Promise<void> {\n    const cmd = `toggleoutput ${id}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Set a runtime attribute. These are specific to the output plugin, and\n   * supported values are shown in the result of the `outputs` command.\n   */\n  async outputSet(id: number, name: string, value: string): Promise<void> {\n    const cmd = `outputset ${id} \"${name}\" \"${value}\"`;\n    await protocol.sendCommand(cmd);\n  },\n});\n","import { MPDProtocol } from '../protocol.js';\nimport { Decoder } from '../objects/decoder.js';\nimport { parse } from '../util.js';\n\nexport interface ReflectionCommands extends ReturnType<typeof createReflectionCommands>{}\n\nexport const createReflectionCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Dumps configuration values that may be interesting for the client.\n   * This command is only permitted to \"local\" clients (connected via UNIX domain socket).\n   * The following response attributes are available:\n   * * `music_directory`: The absolute path of the music directory.\n   */\n  async config(): Promise<Map<string, string>> {\n    const { lines } = await protocol.sendCommand('config');\n    return parse(lines, [], valueMap => valueMap)[0]!;\n  },\n\n  /**\n   * Shows which commands the current user has access to.\n   */\n  async commands(): Promise<string[]> {\n    const { lines } = await protocol.sendCommand('commands');\n    return lines.map(line => line.substring(9));\n  },\n\n  /**\n   * Shows which commands the current user has access to.\n   */\n  async notCommands(): Promise<string[]> {\n    const { lines } = await protocol.sendCommand('notcommands');\n    return lines.map(line => line.substring(9));\n  },\n\n  /**\n   * Gets a list of available URL handlers.\n   */\n  async urlHandlers(): Promise<string[]> {\n    const { lines } = await protocol.sendCommand('urlhandlers');\n    return lines.map(line => line.substring(9));\n  },\n\n  /**\n   * Returns a list of decoder plugins with their supported suffixes and MIME types.\n   */\n  async decoders(): Promise<Decoder[]> {\n    const { lines } = await protocol.sendCommand('decoders');\n    const decoders: Decoder[] = [];\n    let currentDecoder: Decoder;\n    lines.forEach(line => {\n      if (line.startsWith('plugin')) {\n        if (currentDecoder) {\n          decoders.push(currentDecoder);\n        }\n        currentDecoder = new Decoder(line.substring(8));\n      }\n      else if (line.startsWith('suffix')) {\n        currentDecoder.suffixes.push(line.substr(8));\n      }\n      else if (line.startsWith('mime_type')) {\n        currentDecoder.mimeTypes.push(line.substr(11));\n      }\n    });\n    return decoders;\n  },\n});\n","import { MPDProtocol } from '../protocol.js';\n\nexport interface ClientToClientCommands extends ReturnType<typeof createClientToClientCommands>{}\n\nexport const createClientToClientCommands = (protocol: MPDProtocol) => ({\n\n  /**\n   * Subscribe to a channel. The channel is created if it does not exist already.\n   * The name may consist of alphanumeric ASCII characters plus underscore, dash, dot and colon.\n   */\n  async subscribe(channel: string): Promise<void> {\n    const cmd = `subscribe ${channel}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Unsubscribe from a channel.\n   */\n  async unsubscribe(channel: string): Promise<void> {\n    const cmd = `unsubscribe ${channel}`;\n    await protocol.sendCommand(cmd);\n  },\n\n  /**\n   * Obtain a list of all channels.\n   */\n  async channels(): Promise<string[]> {\n    const { lines } = await protocol.sendCommand('channels');\n    return lines.map(line => line.substring(9));\n  },\n\n  /**\n   * Reads messages for this client. Returns a Map containing the messages grouped by channel name.\n   */\n  async readMessages(): Promise<Map<string, string[]>> {\n    const { lines } = await protocol.sendCommand('readmessages');\n    const messagesPerChannel = new Map<string, string[]>();\n    for (let i = 0; i < lines.length - 1; i += 2) {\n      const channel = lines[i]!.substring(9);\n      const message = lines[i + 1]!.substring(9);\n      if (!messagesPerChannel.has(channel)) {\n        messagesPerChannel.set(channel, []);\n      }\n      messagesPerChannel.get(channel)!.push(message);\n    }\n    return messagesPerChannel;\n  },\n\n  /**\n   * Send a message to the specified channel.\n   */\n  async sendMessage(channel: string, text: string): Promise<void> {\n    const cmd = `sendmessage ${channel} \"${text}\"`;\n    await protocol.sendCommand(cmd);\n  },\n});\n","import { MPCCore } from './mpcCore.js';\nexport type { MPDError } from './protocol.js';\nexport type * from './commands/index.js';\nexport type * from './objects/index.js';\n\nexport class MPC extends MPCCore {\n\n  public connectWebSocket(url: string): Promise<void> {\n    const webSocket = new WebSocket(url, ['binary']);\n    return this.connect(\n      webSocketReadableStream(webSocket),\n      msg => webSocket.send(msg)\n    );\n  }\n\n}\n\nfunction webSocketReadableStream(webSocket: WebSocket): ReadableStream<ArrayBuffer> {\n  const blobStream = new ReadableStream<Blob>({\n    start(controller) {\n      webSocket.onmessage = event => controller.enqueue(event.data);\n      webSocket.onclose = () => controller.close();\n      webSocket.onerror = error => controller.error(error);\n    },\n    cancel() {\n      webSocket.close();\n    },\n  });\n\n  return blobStream.pipeThrough(\n    new TransformStream<Blob, ArrayBuffer>({\n      async transform(data, controller) {\n        controller.enqueue(await data.arrayBuffer());\n      }\n    }\n  ));\n}\n"],"names":["has","Object","prototype","hasOwnProperty","prefix","Events","EE","fn","context","once","this","addListener","emitter","event","TypeError","listener","evt","_events","push","_eventsCount","clearEvent","EventEmitter","create","__proto__","eventNames","events","name","names","call","slice","getOwnPropertySymbols","concat","listeners","handlers","i","l","length","ee","Array","listenerCount","emit","a1","a2","a3","a4","a5","args","len","arguments","removeListener","undefined","apply","j","on","removeAllListeners","off","prefixed","module","getOptionalNumber","valueMap","key","Number","get","getOptionalDate","Date","getOptionalBoolean","Boolean","parseOptionalNumber","num","isInitialResponse","response","isError","parse","lines","markers","convert","result","currentValueMap","Map","lineCount","forEach","line","colonIndex","indexOf","substring","value","some","marker","multiValue","join","set","concatUint8Arrays","src1","src2","Uint8Array","MPDProtocol","encoder","TextEncoder","_connection","ready","idle","queuedRequests","runningRequests","mpdVersion","isReady","connect","byteStream","send","Error","responseStream","pipeThrough","decoder","TextDecoder","buffer","binaryLength","TransformStream","transform","data","controller","chunk","lineSeparatorIndex","decodedLine","decode","subarray","startsWith","parseInt","enqueue","decodeLines","initialRegExp","failureRegExp","initialized","receivingList","currentResponse","mpdError","match","exec","errorCode","errorMessage","binary","version","error","groupResponseLines","responseReader","getReader","Promise","resolve","processResponses","initialCallback","reader","done","read","disconnect","dequeueRequests","request","shift","reject","err","connection","releaseLock","cancel","sendCommand","cmd","mpdRequest","enqueueRequest","commandString","idleCallback","command","subsystems","map","changed","subsystem","encode","Status","partition","state","song","songId","nextSong","nextSongId","elapsed","duration","bitRate","audio","sampleRate","bitDepth","channels","volume","xfade","mixrampdb","mixrampDelay","playlistVersion","playlistLength","repeat","random","single","consume","updating","constructor","splitAudio","split","singleString","Statistics","artists","albums","songs","uptime","dbPlaytime","dbUpdate","playtime","StoredPlaylist","lastModified","PlaylistItem","id","position","title","artist","album","albumArtist","track","date","genre","path","durationString","SongIdAndPosition","DirectoryEntry","entryType","pathKey","fromValueMap","withMetadata","Song","File","Directory","Playlist","keys","isFile","isSong","isPlaylist","isDirectory","size","super","titleSort","artistSort","composer","composerSort","performer","conductor","albumSort","albumArtistSort","disc","label","originalDate","mood","work","ensemble","movement","movementNumber","showMovement","location","grouping","comment","musicBrainzArtistId","musicBrainzAlbumId","musicBrainzAlbumArtistId","musicBrainzTrackId","musicBrainzReleaseGroupId","musicBrainzReleaseTrackId","musicBrainzWorkId","format","splitFormat","SongCount","GroupedSongCount","group","groupingTag","GroupedTagList","tags","Picture","type","OutputDevice","enabled","plugin","attributes","attrsString","attrStrings","attrString","keyAndValue","Mount","storage","Neighbor","neighbor","Decoder","suffixes","mimeTypes","addFilter","filter","replace","tagAndNeedle","addSort","sort","addWindow","start","end","addPosition","async","downloadPicture","protocol","values","byteLength","MPCCore","status","playback","playbackOptions","currentPlaylist","storedPlaylists","database","mounts","stickers","outputDevices","reflection","clientToClient","currentSong","statistics","clearError","play","songPos","playId","previous","next","seek","time","seekId","seekCur","relative","pause","stop","createPlaybackCommands","getVolume","setVolume","changeVolume","change","setRandom","setRepeat","setSingle","setConsume","setCrossfade","seconds","setMixrampdb","decibels","setMixrampDelay","setReplayGainMode","mode","getReplayGainMode","createPlaybackOptionsCommands","add","uri","addId","clear","deleteRange","deleteId","move","from","to","moveRange","moveId","playlistFind","tag","needle","playlistSearch","playlistId","playlistInfo","playlistRangeInfo","playlistChanges","playlistChangesPosId","prio","priority","prioId","rangeId","shuffle","swap","song1","song2","swapId","addTagId","clearTagId","createCurrentPlaylistCommands","listPlaylists","listPlaylist","listPlaylistInfo","searchPlaylist","load","save","playlistAdd","playlistClear","playlistDelete","playlistMove","rename","newName","remove","createStoredPlaylistsCommands","count","countGrouped","searchCount","searchCountGrouped","find","findAdd","search","searchAdd","searchAddPlaylist","listFiles","listInfo","listAll","listAllInfo","list","listGrouped","groupingTags","currentGroup","fill","currentTags","saveCurrentTags","includes","readComments","getFingerprint","getAlbumArt","getPicture","update","rescan","createDatabaseCommands","mount","unmount","listMounts","listNeighbors","createMountCommands","getSticker","setSticker","incrementSticker","decrementSticker","deleteSticker","listStickers","stickerMap","separatorIndex","findStickers","operator","fileAndStickers","fileAndSticker","fileValue","stickerValue","getStickerNames","getStickerTypes","getStickerNamesTypes","createStickerCommands","close","kill","password","ping","setBinaryLimit","tagTypes","getAvailableTagTypes","disableTagTypes","enableTagTypes","clearTagTypes","allTagTypes","setEnabledTagTypes","getEnabledProtocolFeatures","getAvailableProtocolFeatures","enableProtocolFeatures","features","disableProtocolFeatures","enableAllProtocolFeatures","disableAllProtocolFeatures","createConnectionCommands","listPartitions","newPartition","deletePartition","moveOutput","outputName","createPartitionCommands","outputs","enableOutput","disableOutput","toggleOutput","outputSet","createOutputDeviceCommands","config","commands","notCommands","urlHandlers","decoders","currentDecoder","substr","createReflectionCommands","subscribe","channel","unsubscribe","readMessages","messagesPerChannel","message","sendMessage","text","createClientToClientCommands","MPC","connectWebSocket","url","webSocket","WebSocket","blobStream","ReadableStream","onmessage","onclose","onerror","arrayBuffer","webSocketReadableStream","msg"],"mappings":"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","x_google_ignoreList":[0]}