{"version":3,"file":"index.modern.mjs","sources":["../src/albums.js","../src/artists.js","../node_modules/querystringify/index.js","../node_modules/unfetch/dist/unfetch.module.js","../node_modules/isomorphic-unfetch/browser.js","../node_modules/jssha/dist/sha256.mjs","../src/utils.js","../src/auth.js","../src/bookmarks.js","../src/catalogs.js","../src/genres.js","../src/labels.js","../src/licenses.js","../src/live-streams.js","../src/playlists.js","../src/podcasts.js","../src/preferences.js","../src/shares.js","../src/shouts.js","../src/songs.js","../src/system.js","../src/users.js","../src/videos.js","../src/base.js","../src/index.js"],"sourcesContent":["/**\r\n * @typedef {Object} AlbumSummary\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} name\r\n * @property {string|null} prefix\r\n * @property {string} basename\r\n */\r\n\r\n/**\r\n * @typedef {Object} AlbumResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} name\r\n * @property {string|null} prefix\r\n * @property {string} basename\r\n * @property {import(\"./artists.js\").ArtistSummary} artist\r\n * @property {import(\"./artists.js\").ArtistSummary[]} artists\r\n * @property {import(\"./artists.js\").ArtistSummary[]} songartists\r\n * @property {number} time\r\n * @property {number|string} year\r\n * @property {import(\"./songs.js\").SongResponse[]} [tracks]\r\n * @property {number} songcount\r\n * @property {number} disccount\r\n * @property {string|null} type\r\n * @property {import(\"./genres.js\").GenreSummary[]} genre\r\n * @property {string} art\r\n * @property {boolean} has_art\r\n * @property {boolean} flag\r\n * @property {number|null} rating\r\n * @property {number|null} averagerating\r\n * @property {string|null} mbid\r\n */\r\n\r\n/**\r\n * @typedef {Object} AlbumsResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {AlbumResponse[]} album\r\n */\r\n\r\nexport const albumsMethods = {\r\n  /**\r\n   * This returns albums based on the provided search filters\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} [params]\r\n   * @param {string} [params.filter] Filter results to match this string\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n   * @param {Date} [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n   * @param {Date} [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n   * @param {\"albums\"|\"songs\"} [params.include] albums, songs (include child objects in the response)\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<AlbumsResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#albums}\r\n   */\r\n  albums(params) {\r\n    return this.call(\"albums\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns a single album based on the UID provided\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @param {\"songs\"} [params.include] songs (include child objects in the response)\r\n   * @returns {Promise<AlbumResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#album}\r\n   */\r\n  album(params) {\r\n    return this.call(\"album\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns the albums of an artist\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.album_artist] 0, 1 (if true filter for album artists only)\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<AlbumsResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#artist_albums}\r\n   */\r\n  artistAlbums(params) {\r\n    return this.call(\"artist_albums\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns the albums associated with the genre in question\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} [params]\r\n   * @param {import(\"./base.js\").UID} [params.filter] UID to find\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<AlbumsResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#genre_albums}\r\n   */\r\n  genreAlbums(params) {\r\n    return this.call(\"genre_albums\", params);\r\n  },\r\n};\r\n","/**\r\n * @typedef {Object} ArtistSummary\r\n * @property {string} id\r\n * @property {string} name\r\n * @property {string|null} prefix\r\n * @property {string} basename\r\n */\r\n\r\n/**\r\n * @typedef {Object} ArtistResponse\r\n * @property {string} id\r\n * @property {string} name\r\n * @property {string|null} prefix\r\n * @property {string} basename\r\n * @property {import(\"./albums.js\").AlbumResponse[]} albums\r\n * @property {number} albumcount\r\n * @property {import(\"./songs.js\").SongsResponse[]} songs\r\n * @property {number} songcount\r\n * @property {import(\"./genres.js\").GenreResponse[]} genre\r\n * @property {string} art\r\n * @property {boolean} has_art\r\n * @property {boolean} flag\r\n * @property {number|null} rating\r\n * @property {number|null} averagerating\r\n * @property {string|null} mbid\r\n * @property {string} summary\r\n * @property {number} time\r\n * @property {number} yearformed\r\n * @property {string} placeformed\r\n */\r\n\r\n/**\r\n * @typedef {Object} ArtistsResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {ArtistResponse[]} artist\r\n */\r\n\r\nexport const artistsMethods = {\r\n  /**\r\n   * This takes a collection of inputs and returns artist objects\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} [params]\r\n   * @param {string} [params.filter] Filter results to match this string\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n   * @param {Date} [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n   * @param {Date} [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n   * @param {\"albums\"|\"songs\"} [params.include] (albums | songs) include child objects in the response\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.album_artist] 0, 1 (if true filter for album artists only)\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<ArtistsResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#artists}\r\n   */\r\n  artists(params) {\r\n    return this.call(\"artists\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns a single artist based on the UID of said artist\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @param {\"albums\"|\"songs\"} [params.include] (albums | songs) include child objects in the response\r\n   * @returns {Promise<ArtistResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#artist}\r\n   */\r\n  artist(params) {\r\n    return this.call(\"artist\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns the artists associated with the genre in question as defined by the UID\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<ArtistsResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#genre_artists}\r\n   */\r\n  genreArtists(params) {\r\n    return this.call(\"genre_artists\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns the artists associated with the label in question as defined by the UID\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID of find\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<ArtistsResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#label_artists}\r\n   */\r\n  labelArtists(params) {\r\n    return this.call(\"label_artists\", params);\r\n  },\r\n};\r\n","'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n  , undef;\n\n/**\n * Decode a URI encoded string.\n *\n * @param {String} input The URI encoded string.\n * @returns {String|Null} The decoded string.\n * @api private\n */\nfunction decode(input) {\n  try {\n    return decodeURIComponent(input.replace(/\\+/g, ' '));\n  } catch (e) {\n    return null;\n  }\n}\n\n/**\n * Attempts to encode a given input.\n *\n * @param {String} input The string that needs to be encoded.\n * @returns {String|Null} The encoded string.\n * @api private\n */\nfunction encode(input) {\n  try {\n    return encodeURIComponent(input);\n  } catch (e) {\n    return null;\n  }\n}\n\n/**\n * Simple query string parser.\n *\n * @param {String} query The query string that needs to be parsed.\n * @returns {Object}\n * @api public\n */\nfunction querystring(query) {\n  var parser = /([^=?#&]+)=?([^&]*)/g\n    , result = {}\n    , part;\n\n  while (part = parser.exec(query)) {\n    var key = decode(part[1])\n      , value = decode(part[2]);\n\n    //\n    // Prevent overriding of existing properties. This ensures that build-in\n    // methods like `toString` or __proto__ are not overriden by malicious\n    // querystrings.\n    //\n    // In the case if failed decoding, we want to omit the key/value pairs\n    // from the result.\n    //\n    if (key === null || value === null || key in result) continue;\n    result[key] = value;\n  }\n\n  return result;\n}\n\n/**\n * Transform a query string to an object.\n *\n * @param {Object} obj Object that should be transformed.\n * @param {String} prefix Optional prefix.\n * @returns {String}\n * @api public\n */\nfunction querystringify(obj, prefix) {\n  prefix = prefix || '';\n\n  var pairs = []\n    , value\n    , key;\n\n  //\n  // Optionally prefix with a '?' if needed\n  //\n  if ('string' !== typeof prefix) prefix = '?';\n\n  for (key in obj) {\n    if (has.call(obj, key)) {\n      value = obj[key];\n\n      //\n      // Edge cases where we actually want to encode the value to an empty\n      // string instead of the stringified value.\n      //\n      if (!value && (value === null || value === undef || isNaN(value))) {\n        value = '';\n      }\n\n      key = encode(key);\n      value = encode(value);\n\n      //\n      // If we failed to encode the strings, we should bail out as we don't\n      // want to add invalid strings to the query.\n      //\n      if (key === null || value === null) continue;\n      pairs.push(key +'='+ value);\n    }\n  }\n\n  return pairs.length ? prefix + pairs.join('&') : '';\n}\n\n//\n// Expose the module.\n//\nexports.stringify = querystringify;\nexports.parse = querystring;\n","export default function(e,n){return n=n||{},new Promise(function(t,r){var s=new XMLHttpRequest,o=[],u=[],i={},a=function(){return{ok:2==(s.status/100|0),statusText:s.statusText,status:s.status,url:s.responseURL,text:function(){return Promise.resolve(s.responseText)},json:function(){return Promise.resolve(s.responseText).then(JSON.parse)},blob:function(){return Promise.resolve(new Blob([s.response]))},clone:a,headers:{keys:function(){return o},entries:function(){return u},get:function(e){return i[e.toLowerCase()]},has:function(e){return e.toLowerCase()in i}}}};for(var l in s.open(n.method||\"get\",e,!0),s.onload=function(){s.getAllResponseHeaders().replace(/^(.*?):[^\\S\\n]*([\\s\\S]*?)$/gm,function(e,n,t){o.push(n=n.toLowerCase()),u.push([n,t]),i[n]=i[n]?i[n]+\",\"+t:t}),t(a())},s.onerror=r,s.withCredentials=\"include\"==n.credentials,n.headers)s.setRequestHeader(l,n.headers[l]);s.send(n.body||null)})}\n//# sourceMappingURL=unfetch.module.js.map\n","module.exports = self.fetch || (self.fetch = require('unfetch').default || require('unfetch'));\n","/**\n * A JavaScript implementation of the SHA family of hashes - defined in FIPS PUB 180-4, FIPS PUB 202,\n * and SP 800-185 - as well as the corresponding HMAC implementation as defined in FIPS PUB 198-1.\n *\n * Copyright 2008-2023 Brian Turek, 1998-2009 Paul Johnston & Contributors\n * Distributed under the BSD License\n * See http://caligatio.github.com/jsSHA/ for more information\n */\nconst t=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",r=\"ARRAYBUFFER not supported by this environment\",n=\"UINT8ARRAY not supported by this environment\";function i(t,r,n,i){let e,s,o;const h=r||[0],u=(n=n||0)>>>3,f=-1===i?3:0;for(e=0;e<t.length;e+=1)o=e+u,s=o>>>2,h.length<=s&&h.push(0),h[s]|=t[e]<<8*(f+i*(o%4));return{value:h,binLen:8*t.length+n}}function e(e,s,o){switch(s){case\"UTF8\":case\"UTF16BE\":case\"UTF16LE\":break;default:throw new Error(\"encoding must be UTF8, UTF16BE, or UTF16LE\")}switch(e){case\"HEX\":return function(t,r,n){return function(t,r,n,i){let e,s,o,h;if(0!=t.length%2)throw new Error(\"String of HEX type must be in byte increments\");const u=r||[0],f=(n=n||0)>>>3,c=-1===i?3:0;for(e=0;e<t.length;e+=2){if(s=parseInt(t.substr(e,2),16),isNaN(s))throw new Error(\"String of HEX type contains invalid characters\");for(h=(e>>>1)+f,o=h>>>2;u.length<=o;)u.push(0);u[o]|=s<<8*(c+i*(h%4))}return{value:u,binLen:4*t.length+n}}(t,r,n,o)};case\"TEXT\":return function(t,r,n){return function(t,r,n,i,e){let s,o,h,u,f,c,a,w,E=0;const l=n||[0],A=(i=i||0)>>>3;if(\"UTF8\"===r)for(a=-1===e?3:0,h=0;h<t.length;h+=1)for(s=t.charCodeAt(h),o=[],128>s?o.push(s):2048>s?(o.push(192|s>>>6),o.push(128|63&s)):55296>s||57344<=s?o.push(224|s>>>12,128|s>>>6&63,128|63&s):(h+=1,s=65536+((1023&s)<<10|1023&t.charCodeAt(h)),o.push(240|s>>>18,128|s>>>12&63,128|s>>>6&63,128|63&s)),u=0;u<o.length;u+=1){for(c=E+A,f=c>>>2;l.length<=f;)l.push(0);l[f]|=o[u]<<8*(a+e*(c%4)),E+=1}else for(a=-1===e?2:0,w=\"UTF16LE\"===r&&1!==e||\"UTF16LE\"!==r&&1===e,h=0;h<t.length;h+=1){for(s=t.charCodeAt(h),!0===w&&(u=255&s,s=u<<8|s>>>8),c=E+A,f=c>>>2;l.length<=f;)l.push(0);l[f]|=s<<8*(a+e*(c%4)),E+=2}return{value:l,binLen:8*E+i}}(t,s,r,n,o)};case\"B64\":return function(r,n,i){return function(r,n,i,e){let s,o,h,u,f,c,a,w=0;const E=n||[0],l=(i=i||0)>>>3,A=-1===e?3:0,p=r.indexOf(\"=\");if(-1===r.search(/^[a-zA-Z0-9=+/]+$/))throw new Error(\"Invalid character in base-64 string\");if(r=r.replace(/=/g,\"\"),-1!==p&&p<r.length)throw new Error(\"Invalid '=' found in base-64 string\");for(o=0;o<r.length;o+=4){for(f=r.substr(o,4),u=0,h=0;h<f.length;h+=1)s=t.indexOf(f.charAt(h)),u|=s<<18-6*h;for(h=0;h<f.length-1;h+=1){for(a=w+l,c=a>>>2;E.length<=c;)E.push(0);E[c]|=(u>>>16-8*h&255)<<8*(A+e*(a%4)),w+=1}}return{value:E,binLen:8*w+i}}(r,n,i,o)};case\"BYTES\":return function(t,r,n){return function(t,r,n,i){let e,s,o,h;const u=r||[0],f=(n=n||0)>>>3,c=-1===i?3:0;for(s=0;s<t.length;s+=1)e=t.charCodeAt(s),h=s+f,o=h>>>2,u.length<=o&&u.push(0),u[o]|=e<<8*(c+i*(h%4));return{value:u,binLen:8*t.length+n}}(t,r,n,o)};case\"ARRAYBUFFER\":try{new ArrayBuffer(0)}catch(t){throw new Error(r)}return function(t,r,n){return function(t,r,n,e){return i(new Uint8Array(t),r,n,e)}(t,r,n,o)};case\"UINT8ARRAY\":try{new Uint8Array(0)}catch(t){throw new Error(n)}return function(t,r,n){return i(t,r,n,o)};default:throw new Error(\"format must be HEX, TEXT, B64, BYTES, ARRAYBUFFER, or UINT8ARRAY\")}}function s(i,e,s,o){switch(i){case\"HEX\":return function(t){return function(t,r,n,i){const e=\"0123456789abcdef\";let s,o,h=\"\";const u=r/8,f=-1===n?3:0;for(s=0;s<u;s+=1)o=t[s>>>2]>>>8*(f+n*(s%4)),h+=e.charAt(o>>>4&15)+e.charAt(15&o);return i.outputUpper?h.toUpperCase():h}(t,e,s,o)};case\"B64\":return function(r){return function(r,n,i,e){let s,o,h,u,f,c=\"\";const a=n/8,w=-1===i?3:0;for(s=0;s<a;s+=3)for(u=s+1<a?r[s+1>>>2]:0,f=s+2<a?r[s+2>>>2]:0,h=(r[s>>>2]>>>8*(w+i*(s%4))&255)<<16|(u>>>8*(w+i*((s+1)%4))&255)<<8|f>>>8*(w+i*((s+2)%4))&255,o=0;o<4;o+=1)c+=8*s+6*o<=n?t.charAt(h>>>6*(3-o)&63):e.b64Pad;return c}(r,e,s,o)};case\"BYTES\":return function(t){return function(t,r,n){let i,e,s=\"\";const o=r/8,h=-1===n?3:0;for(i=0;i<o;i+=1)e=t[i>>>2]>>>8*(h+n*(i%4))&255,s+=String.fromCharCode(e);return s}(t,e,s)};case\"ARRAYBUFFER\":try{new ArrayBuffer(0)}catch(t){throw new Error(r)}return function(t){return function(t,r,n){let i;const e=r/8,s=new ArrayBuffer(e),o=new Uint8Array(s),h=-1===n?3:0;for(i=0;i<e;i+=1)o[i]=t[i>>>2]>>>8*(h+n*(i%4))&255;return s}(t,e,s)};case\"UINT8ARRAY\":try{new Uint8Array(0)}catch(t){throw new Error(n)}return function(t){return function(t,r,n){let i;const e=r/8,s=-1===n?3:0,o=new Uint8Array(e);for(i=0;i<e;i+=1)o[i]=t[i>>>2]>>>8*(s+n*(i%4))&255;return o}(t,e,s)};default:throw new Error(\"format must be HEX, B64, BYTES, ARRAYBUFFER, or UINT8ARRAY\")}}const o=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],h=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428],u=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];function f(t){const r={outputUpper:!1,b64Pad:\"=\",outputLen:-1},n=t||{},i=\"Output length must be a multiple of 8\";if(r.outputUpper=n.outputUpper||!1,n.b64Pad&&(r.b64Pad=n.b64Pad),n.outputLen){if(n.outputLen%8!=0)throw new Error(i);r.outputLen=n.outputLen}else if(n.shakeLen){if(n.shakeLen%8!=0)throw new Error(i);r.outputLen=n.shakeLen}if(\"boolean\"!=typeof r.outputUpper)throw new Error(\"Invalid outputUpper formatting option\");if(\"string\"!=typeof r.b64Pad)throw new Error(\"Invalid b64Pad formatting option\");return r}class c{constructor(t,r,n){const i=n||{};if(this.t=r,this.i=i.encoding||\"UTF8\",this.numRounds=i.numRounds||1,isNaN(this.numRounds)||this.numRounds!==parseInt(this.numRounds,10)||1>this.numRounds)throw new Error(\"numRounds must a integer >= 1\");this.o=t,this.h=[],this.u=0,this.l=!1,this.A=0,this.p=!1,this.U=[],this.R=[]}update(t){let r,n=0;const i=this.T>>>5,e=this.F(t,this.h,this.u),s=e.binLen,o=e.value,h=s>>>5;for(r=0;r<h;r+=i)n+this.T<=s&&(this.m=this.g(o.slice(r,r+i),this.m),n+=this.T);return this.A+=n,this.h=o.slice(n>>>5),this.u=s%this.T,this.l=!0,this}getHash(t,r){let n,i,e=this.H;const o=f(r);if(this.B){if(-1===o.outputLen)throw new Error(\"Output length must be specified in options\");e=o.outputLen}const h=s(t,e,this.v,o);if(this.p&&this.C)return h(this.C(o));for(i=this.Y(this.h.slice(),this.u,this.A,this.S(this.m),e),n=1;n<this.numRounds;n+=1)this.B&&e%32!=0&&(i[i.length-1]&=16777215>>>24-e%32),i=this.Y(i,e,0,this.I(this.o),e);return h(i)}setHMACKey(t,r,n){if(!this.L)throw new Error(\"Variant does not support HMAC\");if(this.l)throw new Error(\"Cannot set MAC key after calling update\");const i=e(r,(n||{}).encoding||\"UTF8\",this.v);this.M(i(t))}M(t){const r=this.T>>>3,n=r/4-1;let i;if(1!==this.numRounds)throw new Error(\"Cannot set numRounds with MAC\");if(this.p)throw new Error(\"MAC key already set\");for(r<t.binLen/8&&(t.value=this.Y(t.value,t.binLen,0,this.I(this.o),this.H));t.value.length<=n;)t.value.push(0);for(i=0;i<=n;i+=1)this.U[i]=909522486^t.value[i],this.R[i]=1549556828^t.value[i];this.m=this.g(this.U,this.m),this.A=this.T,this.p=!0}getHMAC(t,r){const n=f(r);return s(t,this.H,this.v,n)(this.N())}N(){let t;if(!this.p)throw new Error(\"Cannot call getHMAC without first setting MAC key\");const r=this.Y(this.h.slice(),this.u,this.A,this.S(this.m),this.H);return t=this.g(this.R,this.I(this.o)),t=this.Y(r,this.H,this.T,t,this.H),t}}function a(t,r){return t>>>r|t<<32-r}function w(t,r){return t>>>r}function E(t,r,n){return t&r^~t&n}function l(t,r,n){return t&r^t&n^r&n}function A(t){return a(t,2)^a(t,13)^a(t,22)}function p(t,r){const n=(65535&t)+(65535&r);return(65535&(t>>>16)+(r>>>16)+(n>>>16))<<16|65535&n}function U(t,r,n,i){const e=(65535&t)+(65535&r)+(65535&n)+(65535&i);return(65535&(t>>>16)+(r>>>16)+(n>>>16)+(i>>>16)+(e>>>16))<<16|65535&e}function d(t,r,n,i,e){const s=(65535&t)+(65535&r)+(65535&n)+(65535&i)+(65535&e);return(65535&(t>>>16)+(r>>>16)+(n>>>16)+(i>>>16)+(e>>>16)+(s>>>16))<<16|65535&s}function R(t){return a(t,7)^a(t,18)^w(t,3)}function y(t){return a(t,6)^a(t,11)^a(t,25)}function T(t){let r;return r=\"SHA-224\"==t?h.slice():u.slice(),r}function F(t,r){let n,i,e,s,h,u,f,c,T,F,b;const m=[];for(n=r[0],i=r[1],e=r[2],s=r[3],h=r[4],u=r[5],f=r[6],c=r[7],b=0;b<64;b+=1)m[b]=b<16?t[b]:U(a(g=m[b-2],17)^a(g,19)^w(g,10),m[b-7],R(m[b-15]),m[b-16]),T=d(c,y(h),E(h,u,f),o[b],m[b]),F=p(A(n),l(n,i,e)),c=f,f=u,u=h,h=p(s,T),s=e,e=i,i=n,n=p(T,F);var g;return r[0]=p(n,r[0]),r[1]=p(i,r[1]),r[2]=p(e,r[2]),r[3]=p(s,r[3]),r[4]=p(h,r[4]),r[5]=p(u,r[5]),r[6]=p(f,r[6]),r[7]=p(c,r[7]),r}class b extends c{constructor(t,r,n){if(\"SHA-224\"!==t&&\"SHA-256\"!==t)throw new Error(\"Chosen SHA variant is not supported\");super(t,r,n);const i=n||{};this.C=this.N,this.L=!0,this.v=-1,this.F=e(this.t,this.i,this.v),this.g=F,this.S=function(t){return t.slice()},this.I=T,this.Y=function(r,n,i,e){return function(t,r,n,i,e){let s,o;const h=15+(r+65>>>9<<4),u=r+n;for(;t.length<=h;)t.push(0);for(t[r>>>5]|=128<<24-r%32,t[h]=4294967295&u,t[h-1]=u/4294967296|0,s=0;s<t.length;s+=16)i=F(t.slice(s,s+16),i);return o=\"SHA-224\"===e?[i[0],i[1],i[2],i[3],i[4],i[5],i[6]]:i,o}(r,n,i,e,t)},this.m=T(t),this.T=512,this.H=\"SHA-224\"===t?224:256,this.B=!1,i.hmacKey&&this.M(function(t,r,n,i){const s=t+\" must include a value and format\";if(!r){if(!i)throw new Error(s);return i}if(void 0===r.value||!r.format)throw new Error(s);return e(r.format,r.encoding||\"UTF8\",n)(r.value)}(\"hmacKey\",i.hmacKey,this.v))}}export{b as default};\n","import JsSHA from \"jssha/dist/sha256\";\r\n\r\n/**\r\n * @param {string} password\r\n * @param {number} time\r\n * @returns {string}\r\n */\r\nexport function encryptPassword(password, time) {\r\n  let key = getSHA256(password);\r\n  return getSHA256(time + key);\r\n\r\n  /**\r\n   * @param {string} text\r\n   * @returns {string}\r\n   */\r\n  function getSHA256(text) {\r\n    let shaObj = new JsSHA(\"SHA-256\", \"TEXT\", { encoding: \"UTF8\" });\r\n    shaObj.update(text);\r\n\r\n    return shaObj.getHash(\"HEX\");\r\n  }\r\n}\r\n\r\n/**\r\n * @param {string} url\r\n * @param {{ useBearerToken?: boolean, sessionKey?: string|null }} config\r\n */\r\nexport function outputDebugURL(url, config) {\r\n  let label = \"javascript-ampache query URL\";\r\n\r\n  if (config.useBearerToken) {\r\n    label = \"(Using Bearer token, auth added for debugging) - \" + label;\r\n    url += \"&auth=\" + config.sessionKey;\r\n  }\r\n\r\n  console.debug(\r\n      label + \" %c\" + url,\r\n      \"color: black; font-style: italic; background-color: orange;padding: 2px\",\r\n  );\r\n}\r\n","/**\r\n * @typedef {Object} AuthResponse\r\n * @property {string} add\r\n * @property {number} albums\r\n * @property {string} api\r\n * @property {number} artists\r\n * @property {string} auth\r\n * @property {number} catalogs\r\n * @property {string} compatible\r\n * @property {string} clean\r\n * @property {number} genres\r\n * @property {number} labels\r\n * @property {number} licenses\r\n * @property {number} live_streams\r\n * @property {number} playlists\r\n * @property {number} podcasts\r\n * @property {number} podcast_episodes\r\n * @property {string} server\r\n * @property {string} session_expire\r\n * @property {string|null} [streamtoken]\r\n * @property {number} shares\r\n * @property {number} songs\r\n * @property {string} update\r\n * @property {number} user\r\n * @property {string} username\r\n * @property {string} version\r\n * @property {number} videos\r\n * @property {number} max_song\r\n * @property {number} max_album\r\n * @property {number} max_artist\r\n * @property {number} max_video\r\n * @property {number} max_podcast\r\n * @property {number} max_podcast_episode\r\n */\r\n\r\nimport qs from \"querystringify\";\r\nimport fetch from \"isomorphic-unfetch\";\r\nimport { outputDebugURL, encryptPassword as encryptPasswordUtil } from \"./utils.js\";\r\n\r\nexport const authMethods = {\r\n  /**\r\n   * Handles verifying a new handshake\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} params\r\n   * @param {string} params.auth encrypted apikey OR password if using password auth\r\n   * @param {string} [params.user] username\r\n   * @param {number} [params.timestamp] UNIXTIME()\r\n   * @param {string} [params.version] version of Ampache API to establish connection with\r\n   * @returns {Promise<AuthResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#handshake}\r\n   */\r\n  handshake(params) {\r\n    let token = params.auth;\r\n\r\n    // generate a timestamp if one wasn't provided\r\n    if (!params.timestamp) {\r\n      params.timestamp = Math.floor(new Date().getTime() / 1000);\r\n    }\r\n\r\n    // override the fallback API version with specified\r\n    if (params.version) {\r\n      this.version = params.version;\r\n    }\r\n\r\n    // drop timestamp if no user provided (i.e. logging in with API key)\r\n    if (!params.user) {\r\n      delete params.timestamp;\r\n    }\r\n\r\n    // not needed if using Bearer token\r\n    if (this.useBearerToken) {\r\n      delete params.auth;\r\n    }\r\n\r\n    let query = this.url + \"/server/json.server.php?action=handshake\";\r\n    query += qs.stringify(params, \"&\");\r\n\r\n    if (this.debug) {\r\n      outputDebugURL(query, this);\r\n    }\r\n\r\n    return fetch(query, {\r\n      method: \"GET\",\r\n      headers: this.useBearerToken ? { Authorization: \"Bearer \" + token } : {},\r\n    })\r\n      .then((response) => response.json())\r\n      .then((data) => {\r\n        if (data.auth) {\r\n          this.sessionKey = data.auth;\r\n        }\r\n        return /** @type {AuthResponse} */ (data);\r\n      });\r\n  },\r\n\r\n  /**\r\n   * This can be called without being authenticated, it is useful for determining if what the status\r\n   * of the server is, and what version it is running/compatible with\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} [params]\r\n   * @param {string} [params.auth] (Session ID) returns version information and extends the session if passed\r\n   * @param {string} [params.version] API Version that the application understands\r\n   * @returns {Promise<AuthResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#ping}\r\n   */\r\n  ping(params) {\r\n    return this.call(\"ping\", params);\r\n  },\r\n\r\n  /**\r\n   * Destroy a session using the session auth parameter\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param {Object} params\r\n   * @param {string} params.auth Session ID to destroy\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#goodbye}\r\n   */\r\n  goodbye(params) {\r\n    return this.call(\"goodbye\", params);\r\n  },\r\n\r\n  /**\r\n   * Email a new password to the user (if allowed) using a reset token.\r\n   * @remarks MINIMUM_API_VERSION=6.1.0\r\n   * @param {Object} params\r\n   * @param {string} params.auth Password reset token\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#lost_password}\r\n   */\r\n  lostPassword(params) {\r\n    return this.call(\"lost_password\", params);\r\n  },\r\n\r\n  /**\r\n   * Encrypt your password into the accepted format.\r\n   * @param {Object} params\r\n   * @param {string} params.password\r\n   * @param {number} params.time\r\n   * @returns {string}\r\n   */\r\n  encryptPassword(params) {\r\n    return encryptPasswordUtil(params.password, params.time);\r\n  },\r\n};\r\n","/**\r\n * @typedef {Object} BookmarkResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {\"song\"|\"video\"|\"podcast_episode\"} type\r\n * @property {number} position\r\n * @property {string} [client]\r\n * @property {number} [date]\r\n */\r\n\r\n/**\r\n * @typedef {Object} BookmarksResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {BookmarkResponse[]} bookmark\r\n */\r\n\r\nexport const bookmarksMethods = {\r\n  /**\r\n   * Get a single bookmark by bookmark_id\r\n   * @remarks MINIMUM_API_VERSION=6.1.0\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.include] 0,1, if true include the object in the bookmark\r\n   * @returns {Promise<BookmarkResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#bookmark}\r\n   */\r\n  bookmark(params) {\r\n    return this.call(\"bookmark\", params);\r\n  },\r\n\r\n  /**\r\n   * Get information about bookmarked media this user is allowed to manage\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @param {Object} [params]\r\n   * @param {string} [params.client] filter by the agent/client name\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.include] 0,1, if true include the object in the bookmark\r\n   * @returns {Promise<BookmarksResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#bookmarks}\r\n   */\r\n  bookmarks(params) {\r\n    return this.call(\"bookmarks\", params);\r\n  },\r\n\r\n  /**\r\n   * Get the bookmark/s from its object_id and object_type.\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @param {\"song\"|\"video\"|\"podcast_episode\"} params.type Object type\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.include] 0,1, if true include the object in the bookmark\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.all]\r\n   * @returns {Promise<BookmarkResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#get_bookmark}\r\n   */\r\n  getBookmark(params) {\r\n    return this.call(\"get_bookmark\", params);\r\n  },\r\n\r\n  /**\r\n   * Create a placeholder for the current media that you can return to later.\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @param {\"song\"|\"video\"|\"podcast_episode\"} params.type Object type\r\n   * @param {number} params.position current track time in seconds\r\n   * @param {string} [params.client] Agent string. (Default: 'AmpacheAPI')\r\n   * @param {number} [params.date] update time (Default: UNIXTIME())\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.include] 0,1, if true include the object in the bookmark\r\n   * @returns {Promise<BookmarkResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#bookmark_create}\r\n   */\r\n  bookmarkCreate(params) {\r\n    return this.call(\"bookmark_create\", params);\r\n  },\r\n\r\n  /**\r\n   * Edit a placeholder for the current media that you can return to later.\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @param {\"bookmark\"|\"song\"|\"video\"|\"podcast_episode\"} params.type Object type\r\n   * @param {number} params.position current track time in seconds\r\n   * @param {string} [params.client] Agent string. (Default: 'AmpacheAPI')\r\n   * @param {number} [params.date] update time (Default: UNIXTIME())\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.include] 0,1, if true include the object in the bookmark\r\n   * @returns {Promise<BookmarkResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#bookmark_edit}\r\n   */\r\n  bookmarkEdit(params) {\r\n    return this.call(\"bookmark_edit\", params);\r\n  },\r\n\r\n  /**\r\n   * Delete an existing bookmark. (if it exists)\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @param {\"song\"|\"video\"|\"podcast_episode\"} params.type Object type\r\n   * @param {string} [params.client] Agent string. (Default: 'AmpacheAPI')\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#bookmark_delete}\r\n   */\r\n  bookmarkDelete(params) {\r\n    return this.call(\"bookmark_delete\", params);\r\n  },\r\n};\r\n","/**\r\n * @typedef {Object} CatalogResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} name\r\n * @property {\"local\"|\"remote\"} type\r\n * @property {\"podcast\"|\"clip\"|\"tvshow\"|\"movie\"|\"personal_video\"|\"music\"} gather_types\r\n * @property {boolean} enabled\r\n * @property {number} last_add\r\n * @property {number} last_clean\r\n * @property {number} last_update\r\n * @property {string} path\r\n * @property {string} rename_pattern\r\n * @property {string} sort_pattern\r\n */\r\n\r\n/**\r\n * @typedef {Object} CatalogsResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {CatalogResponse[]} catalog\r\n */\r\n\r\nexport const catalogsMethods = {\r\n  /**\r\n   * This searches the catalogs and returns... catalogs\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} [params]\r\n   * @param {\"music\"|\"clip\"|\"tvshow\"|\"movie\"|\"personal_video\"|\"podcast\"} [params.filter] Catalog type\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<CatalogsResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#catalogs}\r\n   */\r\n  catalogs(params) {\r\n    return this.call(\"catalogs\", params);\r\n  },\r\n\r\n  /**\r\n   * Return catalog by UID\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @returns {Promise<CatalogResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#catalog}\r\n   */\r\n  catalog(params) {\r\n    return this.call(\"catalog\", params);\r\n  },\r\n\r\n  /**\r\n   * Kick off a catalog update or clean for the selected catalog\r\n   * ACCESS REQUIRED: 75 (Catalog Manager)\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param {Object} params\r\n   * @param {\"add_to_catalog\"|\"clean_catalog\"} params.task add_to_catalog, clean_catalog\r\n   * @param {import(\"./base.js\").UID} params.catalog UID of catalog\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of catalog (Ampache 7.9.0+)\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#catalog_action}\r\n   */\r\n  catalogAction(params) {\r\n    return this.call(\"catalog_action\", params);\r\n  },\r\n\r\n  /**\r\n   * Perform actions on local catalog files. Single file versions of catalog add, clean, verify and remove (delete).\r\n   * Make sure you remember to urlencode those file names!\r\n   * ACCESS REQUIRED: 50 (Content Manager)\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {string} params.file FULL path to local file\r\n   * @param {string} params.task add, clean, verify, remove, (can include comma-separated values)\r\n   * @param {import(\"./base.js\").UID} params.catalog UID of catalog\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of catalog (Ampache 7.9.0+)\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#catalog_file}\r\n   */\r\n  catalogFile(params) {\r\n    return this.call(\"catalog_file\", params);\r\n  },\r\n\r\n  /**\r\n   * Perform actions on local catalog folders. Single folder versions of catalog add, clean, verify and remove (delete).\r\n   * Make sure you remember to urlencode those folder names!\r\n   * ACCESS REQUIRED: 50 (Content Manager)\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {string} params.folder FULL path to local folder\r\n   * @param {string} params.task add, clean, verify, remove, (can include comma-separated values)\r\n   * @param {import(\"./base.js\").UID} params.catalog UID of catalog\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of catalog (Ampache 7.9.0+)\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#catalog_folder}\r\n   */\r\n  catalogFolder(params) {\r\n    return this.call(\"catalog_folder\", params);\r\n  },\r\n\r\n  /**\r\n   * Create a new catalog.\r\n   * ACCESS REQUIRED: 75 (Catalog Manager)\r\n   * @remarks MINIMUM_API_VERSION=6.0.0\r\n   * @param {Object} params\r\n   * @param {string} params.name Name for the catalog\r\n   * @param {string} params.path URL or folder path for your catalog\r\n   * @param {\"local\"|\"beets\"|\"remote\"|\"subsonic\"|\"seafile\"|\"beetsremote\"} [params.type] Default: 'local'\r\n   * @param {\"music\"|\"podcast\"|\"clip\"|\"tvshow\"|\"movie\"|\"personal_video\"} [params.media_type] Default: 'music'\r\n   * @param {string} [params.file_pattern] Pattern used identify tags from the file name. Default: '%T - %t'\r\n   * @param {string} [params.folder_pattern] Pattern used identify tags from the folder name. Default: '%a/%A'\r\n   * @param {string} [params.username] login to remote catalog\r\n   * @param {string} [params.password] password to remote catalog\r\n   * @returns {Promise<CatalogResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#catalog_add}\r\n   */\r\n  catalogAdd(params) {\r\n    return this.call(\"catalog_add\", params);\r\n  },\r\n\r\n  /**\r\n   * Delete an existing catalog. (if it exists)\r\n   * ACCESS REQUIRED: 75 (Catalog Manager)\r\n   * @remarks MINIMUM_API_VERSION=6.0.0\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter ID of the catalog\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#catalog_delete}\r\n   */\r\n  catalogDelete(params) {\r\n    return this.call(\"catalog_delete\", params);\r\n  },\r\n};\r\n","/**\r\n * @typedef {Object} GenreSummary\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} name\r\n */\r\n\r\n/**\r\n * @typedef {Object} GenreResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} name\r\n * @property {number} albums\r\n * @property {number} artists\r\n * @property {number} songs\r\n * @property {number} videos\r\n * @property {number} playlists\r\n * @property {number} live_streams\r\n * @property {boolean} is_hidden\r\n * @property {GenreSummary[]} merge\r\n */\r\n\r\n/**\r\n * @typedef {Object} GenresResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {GenreResponse[]} genre\r\n */\r\n\r\nexport const genresMethods = {\r\n  /**\r\n   * This returns the genres (Tags) based on the specified filter\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} [params]\r\n   * @param {string} [params.filter] UID to find\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<GenresResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#genres}\r\n   */\r\n  genres(params) {\r\n    return this.call(\"genres\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns a single genre based on UID\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @returns {Promise<GenreResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#genre}\r\n   */\r\n  genre(params) {\r\n    return this.call(\"genre\", params);\r\n  },\r\n};\r\n","/**\r\n * @typedef {Object} LabelResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} name\r\n * @property {number} artists\r\n * @property {string|null} summary\r\n * @property {string|null} external_link\r\n * @property {string|null} address\r\n * @property {string|null} category\r\n * @property {string|null} email\r\n * @property {string|null} website\r\n * @property {import(\"./base.js\").UID} user\r\n */\r\n\r\n/**\r\n * @typedef {Object} LabelsResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {LabelResponse[]} label\r\n */\r\n\r\nexport const labelsMethods = {\r\n  /**\r\n   * This returns labels based on the specified filter\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} [params]\r\n   * @param {string} [params.filter] Filter results to match this string\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n   * @param {Date} [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n   * @param {Date} [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<LabelsResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#labels}\r\n   */\r\n  labels(params) {\r\n    return this.call(\"labels\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns a single label\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @returns {Promise<LabelResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#label}\r\n   */\r\n  label(params) {\r\n    return this.call(\"label\", params);\r\n  },\r\n};\r\n","/**\r\n * @typedef {Object} LicenseResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} name\r\n * @property {string} description\r\n * @property {string} external_link\r\n */\r\n\r\n/**\r\n * @typedef {Object} LicensesResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {LicenseResponse[]} license\r\n */\r\n\r\nexport const licensesMethods = {\r\n  /**\r\n   * This returns licenses based on the specified filter\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} [params]\r\n   * @param {string} [params.filter] Filter results to match this string\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n   * @param {Date} [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n   * @param {Date} [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<LicensesResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#licenses}\r\n   */\r\n  licenses(params) {\r\n    return this.call(\"licenses\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns a single license\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @returns {Promise<LicenseResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#license}\r\n   */\r\n  license(params) {\r\n    return this.call(\"license\", params);\r\n  },\r\n};\r\n","/**\r\n * @typedef {Object} LiveStreamResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} name\r\n * @property {string} url\r\n * @property {string} codec\r\n * @property {import(\"./base.js\").UID} catalog\r\n * @property {string} site_url\r\n */\r\n\r\n/**\r\n * @typedef {Object} LiveStreamsResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {LiveStreamResponse[]} live_stream\r\n */\r\n\r\nexport const liveStreamsMethods = {\r\n  /**\r\n   * This returns live_streams based on the specified filter\r\n   * @remarks MINIMUM_API_VERSION=5.1.0\r\n   * @param {Object} [params]\r\n   * @param {string} [params.filter] Filter results to match this string\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n   * @param {Date} [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n   * @param {Date} [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<LiveStreamsResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#live_streams}\r\n   */\r\n  liveStreams(params) {\r\n    return this.call(\"live_streams\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns a single live_stream\r\n   * @remarks MINIMUM_API_VERSION=5.1.0\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @returns {Promise<LiveStreamResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#live_stream}\r\n   */\r\n  liveStream(params) {\r\n    return this.call(\"live_stream\", params);\r\n  },\r\n\r\n  /**\r\n   * Create a live_stream (radio station) object.\r\n   * ACCESS REQUIRED: 50 (Content Manager)\r\n   * @remarks MINIMUM_API_VERSION=6.0.0\r\n   * @param {Object} params\r\n   * @param {string} params.name Stream title\r\n   * @param {string} params.url URL of the http/s stream\r\n   * @param {\"mp3\"|\"flac\"|\"ogg\"|\"vorbis\"|\"opus\"|\"aac\"|\"alac\"} params.codec Stream codec\r\n   * @param {string} params.catalog Catalog ID to associate with this stream\r\n   * @param {string} [params.site_url] Homepage URL of the stream\r\n   * @returns {Promise<LiveStreamResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#live_stream_create}\r\n   */\r\n  liveStreamCreate(params) {\r\n    return this.call(\"live_stream_create\", params);\r\n  },\r\n\r\n  /**\r\n   * Edit a live_stream (radio station) object.\r\n   * ACCESS REQUIRED: 50 (Content Manager)\r\n   * @remarks MINIMUM_API_VERSION=6.0.0\r\n   * @param {Object} params\r\n   * @param {string} params.filter Object to find\r\n   * @param {string} [params.name] Stream title\r\n   * @param {string} [params.url] URL of the http/s stream\r\n   * @param {\"mp3\"|\"flac\"|\"ogg\"|\"vorbis\"|\"opus\"|\"aac\"|\"alac\"} [params.codec] Stream codec\r\n   * @param {string} [params.catalog] Catalog ID to associate with this stream\r\n   * @param {string} [params.site_url] Homepage URL of the stream\r\n   * @returns {Promise<LiveStreamResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#live_stream_edit}\r\n   */\r\n  liveStreamEdit(params) {\r\n    return this.call(\"live_stream_edit\", params);\r\n  },\r\n\r\n  /**\r\n   * Delete a live_stream (radio station) object (if it exists)\r\n   * ACCESS REQUIRED: 50 (Content Manager)\r\n   * @remarks MINIMUM_API_VERSION=6.0.0\r\n   * @param {Object} params\r\n   * @param {string} params.filter Object to find\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#live_stream_delete}\r\n   */\r\n  liveStreamDelete(params) {\r\n    return this.call(\"live_stream_delete\", params);\r\n  },\r\n};\r\n","/**\n * @typedef {Object} PlaylistResponse\n * @property {import(\"./base.js\").UID} id\n * @property {string} name\n * @property {string} owner\n * @property {number} items\n * @property {\"public\"|\"private\"} type\n * @property {string} art\n * @property {boolean} has_art\n * @property {boolean} flag\n * @property {number|null} rating\n * @property {number|null} averagerating\n * @property {import(\"./users.js\").UserSummary} user\n * @property {boolean} has_access\n * @property {boolean} has_collaborate\n * @property {number} last_update\n */\n\n/**\n * @typedef {Object} PlaylistsResponse\n * @property {number} total_count\n * @property {string} md5\n * @property {PlaylistResponse[]} playlist\n */\n\n/**\n * @typedef {Object} HashResponse\n * @property {string} md5\n */\n\nexport const playlistsMethods = {\n  /**\n   * This returns playlists based on the specified filter\n   * @remarks MINIMUM_API_VERSION=380001\n   * @param {Object} [params]\n   * @param {string} [params.filter] Filter results to match this string\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\n   * @param {Date} [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\n   * @param {Date} [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\n   * @param {import(\"./base.js\").BinaryBoolean} [params.hide_search] 0, 1 (if true do not include searches/smartlists in the result)\n   * @param {import(\"./base.js\").BinaryBoolean} [params.show_dupes] 0, 1 (if true ignore 'api_hide_dupe_searches' setting)\n   * @param {import(\"./base.js\").BinaryBoolean} [params.include] 0, 1 (if true include the objects in the playlist)\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @param {string} [params.cond]\n   * @param {string} [params.sort]\n   * @returns {Promise<PlaylistsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#playlists}\n   */\n  playlists(params) {\n    return this.call(\"playlists\", params);\n  },\n\n  /**\n   * This returns smartlists based on the specified filter\n   * @remarks MINIMUM_API_VERSION=6.9.1\n   * @param {Object} [params]\n   * @param {string} [params.filter] Filter results to match this string\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\n   * @param {Date} [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\n   * @param {Date} [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @param {string} [params.cond]\n   * @param {string} [params.sort]\n   * @returns {Promise<PlaylistsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#smartlists}\n   */\n  smartlists(params) {\n    return this.call(\"smartlists\", params);\n  },\n\n  /**\n   * This returns a single playlist\n   * @remarks MINIMUM_API_VERSION=380001\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID to find\n   * @returns {Promise<PlaylistResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#playlist}\n   */\n  playlist(params) {\n    return this.call(\"playlist\", params);\n  },\n\n  /**\n   * This returns a single smartlist\n   * @remarks MINIMUM_API_VERSION=6.9.1\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID to find\n   * @returns {Promise<PlaylistResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#smartlist}\n   */\n  smartlist(params) {\n    return this.call(\"smartlist\", params);\n  },\n\n  /**\n   * This returns a user's playlists based on the specified filter\n   * @remarks MINIMUM_API_VERSION=6.3.0\n   * @param {Object} [params]\n   * @param {string} [params.filter] Filter results to match this string\n   * @param {import(\"./base.js\").BinaryBoolean} [params.include] 0, 1 (include playlist items)\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\n   * @param {Date} [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\n   * @param {Date} [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @param {string} [params.cond]\n   * @param {string} [params.sort]\n   * @returns {Promise<PlaylistsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#user_playlists}\n   */\n  userPlaylists(params) {\n    return this.call(\"user_playlists\", params);\n  },\n\n  /**\n   * This returns a user's smartlists based on the specified filter\n   * @remarks MINIMUM_API_VERSION=6.3.0\n   * @param {Object} [params]\n   * @param {string} [params.filter] Filter results to match this string\n   * @param {import(\"./base.js\").BinaryBoolean} [params.include] 0, 1 (include playlist items)\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\n   * @param {Date} [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\n   * @param {Date} [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @param {string} [params.cond]\n   * @param {string} [params.sort]\n   * @returns {Promise<PlaylistsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#user_smartlists}\n   */\n  userSmartlists(params) {\n    return this.call(\"user_smartlists\", params);\n  },\n\n  /**\n   * This creates a new playlist and returns it\n   * @remarks MINIMUM_API_VERSION=380001\n   * @param {Object} params\n   * @param {string} params.name Playlist name\n   * @param {\"public\"|\"private\"} [params.type] public, private (Playlist type)\n   * @returns {Promise<PlaylistResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#playlist_create}\n   */\n  playlistCreate(params) {\n    return this.call(\"playlist_create\", params);\n  },\n\n  /**\n   * This adds an item to a playlist\n   * @remarks MINIMUM_API_VERSION=6.3.0\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID of Playlist\n   * @param {import(\"./base.js\").UID} params.id UID of the object to add to playlist\n   * @param {\"song\"|\"album\"|\"artist\"|\"playlist\"} params.type 'song', 'album', 'artist', 'playlist'\n   * @param {import(\"./base.js\").BinaryBoolean} [params.check] 0, 1 Whether to check and ignore duplicates (default = 0)\n   * @returns {Promise<import(\"./base.js\").Success>}\n   * @see {@link https://ampache.org/api/api-json-methods#playlist_add}\n   */\n  playlistAdd(params) {\n    return this.call(\"playlist_add\", params);\n  },\n\n  /**\n   * This modifies name and type of the playlist.\n   * NOTE items and tracks must be sent together and be of equal length.\n   * @remarks MINIMUM_API_VERSION=400001\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID to find\n   * @param {string} [params.name] Playlist name\n   * @param {\"public\"|\"private\"} [params.type] public, private (Playlist type)\n   * @param {string} [params.owner] Change playlist owner to the user id (-1 = System playlist)\n   * @param {string} [params.items] comma-separated song_id's (replaces existing items with a new id)\n   * @param {string} [params.tracks] comma-separated playlisttrack numbers matched to 'items' in order\n   * @returns {Promise<import(\"./base.js\").Success>}\n   * @see {@link https://ampache.org/api/api-json-methods#playlist_edit}\n   */\n  playlistEdit(params) {\n    return this.call(\"playlist_edit\", params);\n  },\n\n  /**\n   * This deletes a playlist\n   * @remarks MINIMUM_API_VERSION=380001\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID of playlist to delete\n   * @returns {Promise<import(\"./base.js\").Success>}\n   * @see {@link https://ampache.org/api/api-json-methods#playlist_delete}\n   */\n  playlistDelete(params) {\n    return this.call(\"playlist_delete\", params);\n  },\n\n  /**\n   * This deletes a smartlist\n   * @remarks MINIMUM_API_VERSION=6.9.1\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID of smartlist to delete\n   * @returns {Promise<import(\"./base.js\").Success>}\n   * @see {@link https://ampache.org/api/api-json-methods#smartlist_delete}\n   */\n  smartlistDelete(params) {\n    return this.call(\"smartlist_delete\", params);\n  },\n\n  /**\n   * This adds a song to a playlist\n   * @remarks MINIMUM_API_VERSION=380001; CHANGED_IN_API_VERSION=400003\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID of Playlist\n   * @param {import(\"./base.js\").UID} params.song UID of song to add to playlist\n   * @param {import(\"./base.js\").BinaryBoolean} [params.check] 0, 1 Whether to check and ignore duplicates (default = 0)\n   * @returns {Promise<import(\"./base.js\").Success>}\n   * @deprecated Being removed in 7.0.0. Use `playlist_add` instead.\n   * @see {@link https://ampache.org/api/api-json-methods#playlist_add_song}\n   */\n  playlistAddSong(params) {\n    return this.call(\"playlist_add_song\", params);\n  },\n\n  /**\n   * This remove a song from a playlist\n   * @remarks MINIMUM_API_VERSION=380001; CHANGED_IN_API_VERSION=400001\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID of Playlist\n   * @param {import(\"./base.js\").UID} [params.song] UID of song to remove from playlist\n   * @param {number} [params.track] Track number to remove from playlist\n   * @returns {Promise<import(\"./base.js\").Success>}\n   * @see {@link https://ampache.org/api/api-json-methods#playlist_remove_song}\n   */\n  playlistRemoveSong(params) {\n    return this.call(\"playlist_remove_song\", params);\n  },\n\n  /**\n   * Get a list of song JSON, indexes or id's based on some simple search criteria\n   * @remarks MINIMUM_API_VERSION=400001; CHANGED_IN_API_VERSION=400002; 'recent' will search for tracks played after 'Popular Threshold' days; 'forgotten' will search for tracks played before 'Popular Threshold' days; 'unplayed' added in 400002 for searching unplayed tracks\n   * @param {Object} [params]\n   * @param {\"recent\"|\"forgotten\"|\"unplayed\"|\"random\"} [params.mode] (default = 'random')\n   * @param {string} [params.filter] string LIKE matched to song title\n   * @param {number} [params.album] UID of album\n   * @param {number} [params.artist] UID of artist\n   * @param {import(\"./base.js\").BinaryBoolean} [params.flag] 0, 1 (get flagged songs only. default = 0)\n   * @param {\"song\"|\"index\"|\"id\"} [params.format] song, index, id (default = 'song')\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @returns {Promise<import(\"./songs.js\").SongsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#playlist_generate}\n   */\n  playlistGenerate(params) {\n    return this.call(\"playlist_generate\", params);\n  },\n\n  /**\n   * This returns the md5 hash for the songs in a playlist\n   * @remarks MINIMUM_API_VERSION=6.6.0\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter string UID of Playlist\n   * @returns {Promise<HashResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#playlist_hash}\n   */\n  playlistHash(params) {\n    return this.call(\"playlist_hash\", params);\n  },\n};\n","/**\r\n * @typedef {Object} PodcastEpisodeResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} title\r\n * @property {string} name\r\n * @property {string} description\r\n * @property {string} category\r\n * @property {string} author\r\n * @property {string} author_full\r\n * @property {string} website\r\n * @property {string} pubdate\r\n * @property {\"completed\"|\"pending\"} state\r\n * @property {string} filelength\r\n * @property {string} filesize\r\n * @property {string} filename\r\n * @property {string} mime\r\n * @property {number} time\r\n * @property {number} size\r\n * @property {number} bitrate\r\n * @property {number} stream_bitrate\r\n * @property {number} rate\r\n * @property {number|null} mode\r\n * @property {number|null} channels\r\n * @property {string} public_url\r\n * @property {string} url\r\n * @property {import(\"./base.js\").UID} catalog\r\n * @property {string} art\r\n * @property {boolean} has_art\r\n * @property {boolean} flag\r\n * @property {number|null} rating\r\n * @property {number|null} averagerating\r\n * @property {number} playcount\r\n * @property {number} played\r\n */\r\n\r\n/**\r\n * @typedef {Object} PodcastResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} name\r\n * @property {string} description\r\n * @property {string} language\r\n * @property {string} copyright\r\n * @property {string} feed_url\r\n * @property {string} generator\r\n * @property {string} website\r\n * @property {string} build_date\r\n * @property {string} sync_date\r\n * @property {string} public_url\r\n * @property {string} art\r\n * @property {boolean} has_art\r\n * @property {boolean} flag\r\n * @property {number|null} rating\r\n * @property {number|null} averaterating\r\n * @property {PodcastEpisodeResponse[]} podcast_episode\r\n */\r\n\r\n/**\r\n * @typedef {Object} PodcastsResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {PodcastResponse[]} podcast\r\n */\r\n\r\n/**\r\n * @typedef {Object} PodcastEpisodesResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {PodcastEpisodeResponse[]} podcast_episode\r\n */\r\n\r\n/**\r\n * @typedef {Object} DeletedPodcastEpisodeResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {number} addition_time\r\n * @property {number} delete_time\r\n * @property {string} title\r\n * @property {string} file\r\n * @property {import(\"./base.js\").UID} catalog\r\n * @property {number} total_count\r\n * @property {number} total_skip\r\n * @property {import(\"./base.js\").UID} podcast\r\n */\r\n\r\n/**\r\n * @typedef {Object} DeletedPodcastEpisodesResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {DeletedPodcastEpisodeResponse[]} deleted_podcast_episode\r\n */\r\n\r\nexport const podcastsMethods = {\r\n  /**\r\n   * Get information about podcasts\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} [params]\r\n   * @param {string} [params.filter] Value is Alpha Match for returned results, may be more than one letter/number\r\n   * @param {\"episodes\"} [params.include] episodes (include podcast_episodes in the response)\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<PodcastsResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#podcasts}\r\n   */\r\n  podcasts(params) {\r\n    return this.call(\"podcasts\", params);\r\n  },\r\n\r\n  /**\r\n   * Get the podcast from its id\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID of podcast, returns podcast JSON\r\n   * @param {\"episodes\"} [params.include] episodes (include podcast_episodes in the response)\r\n   * @returns {Promise<PodcastResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#podcast}\r\n   */\r\n  podcast(params) {\r\n    return this.call(\"podcast\", params);\r\n  },\r\n\r\n  /**\r\n   * Create a podcast that can be used by anyone to stream media.\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {string} params.url RSS url for podcast\r\n   * @param {import(\"./base.js\").UID} params.catalog UID of podcast catalog\r\n   * @returns {Promise<PodcastResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#podcast_create}\r\n   */\r\n  podcastCreate(params) {\r\n    return this.call(\"podcast_create\", params);\r\n  },\r\n\r\n  /**\r\n   * Update the description and/or expiration date for an existing podcast.\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @param {string} [params.feed] RSS url for podcast\r\n   * @param {string} [params.title] Podcast title\r\n   * @param {string} [params.website] Source website URL\r\n   * @param {string} [params.description] Podcast description\r\n   * @param {string} [params.generator] Podcast generator\r\n   * @param {string} [params.copyright] Podcast copyright\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#podcast_edit}\r\n   */\r\n  podcastEdit(params) {\r\n    return this.call(\"podcast_edit\", params);\r\n  },\r\n\r\n  /**\r\n   * Delete an existing podcast\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID of podcast to delete\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#podcast_delete}\r\n   */\r\n  podcastDelete(params) {\r\n    return this.call(\"podcast_delete\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns the episodes for a podcast\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID of podcast\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<PodcastEpisodesResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#podcast_episodes}\r\n   */\r\n  podcastEpisodes(params) {\r\n    return this.call(\"podcast_episodes\", params);\r\n  },\r\n\r\n  /**\r\n   * Get the podcast_episode from a UID\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID of podcast\r\n   * @returns {Promise<PodcastEpisodeResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#podcast_episode}\r\n   */\r\n  podcastEpisode(params) {\r\n    return this.call(\"podcast_episode\", params);\r\n  },\r\n\r\n  /**\r\n   * Delete an existing podcast_episode\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID of podcast episode to delete\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#podcast_episode_delete}\r\n   */\r\n  podcastEpisodeDelete(params) {\r\n    return this.call(\"podcast_episode_delete\", params);\r\n  },\r\n\r\n  /**\r\n   * Sync and download new podcast episodes\r\n   * ACCESS REQUIRED: 50 (Content Manager)\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID of podcast (required)\r\n   * @param {import(\"./base.js\").UID} [params.id] Alias of filter (Ampache 7.9.0+)\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#update_podcast}\r\n   */\r\n  updatePodcast(params) {\r\n    return this.call(\"update_podcast\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns the episodes for a podcast that have been deleted\r\n   * @param {Object} [params]\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @returns {Promise<DeletedPodcastEpisodesResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#deleted_podcast_episodes}\r\n   */\r\n  deletedPodcastEpisodes(params) {\r\n    return this.call(\"deleted_podcast_episodes\", params);\r\n  },\r\n};\r\n","/**\r\n * @typedef {Object} PreferenceResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} name\r\n * @property {string} level\r\n * @property {string} description\r\n * @property {string} value\r\n * @property {string} type\r\n * @property {string} category\r\n * @property {string|null} subcategory\r\n * @property {boolean} has_access\r\n * @property {string} [values]\r\n */\r\n\r\n/**\r\n * @typedef {Object} PreferencesResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {PreferenceResponse[]} preference\r\n */\r\n\r\nexport const preferencesMethods = {\r\n  /**\r\n   * Get your server preferences\r\n   * ACCESS REQUIRED: 100 (Admin)\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @returns {Promise<PreferencesResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#system_preferences}\r\n   */\r\n  systemPreferences() {\r\n    return this.call(\"system_preferences\");\r\n  },\r\n\r\n  /**\r\n   * Get your system preference by name\r\n   * ACCESS REQUIRED: 100 (Admin)\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @param {Object} params\r\n   * @param {string} params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n   * @returns {Promise<PreferenceResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#system_preference}\r\n   */\r\n  systemPreference(params) {\r\n    return this.call(\"system_preference\", params);\r\n  },\r\n\r\n  /**\r\n   * Get your user preferences\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @returns {Promise<PreferencesResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#user_preferences}\r\n   */\r\n  userPreferences() {\r\n    return this.call(\"user_preferences\");\r\n  },\r\n\r\n  /**\r\n   * Get your user preference by name\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @param {Object} params\r\n   * @param {string} params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n   * @returns {Promise<PreferenceResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#user_preference}\r\n   */\r\n  userPreference(params) {\r\n    return this.call(\"user_preference\", params);\r\n  },\r\n\r\n  /**\r\n   * Add a new preference to your server\r\n   * ACCESS REQUIRED: 100 (Admin)\r\n   * @param {Object} params\r\n   * @param {string} params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n   * @param {\"boolean\"|\"integer\"|\"string\"|\"special\"} params.type boolean, integer, string, special\r\n   * @param {string|number} params.default string or integer default value\r\n   * @param {\"interface\"|\"internal\"|\"options\"|\"playlist\"|\"plugins\"|\"streaming\"} params.category Category type\r\n   * @param {string} [params.description]\r\n   * @param {string} [params.subcategory]\r\n   * @param {number} [params.level] access level required to change the value (default 100)\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#preference_create}\r\n   */\r\n  preferenceCreate(params) {\r\n    return this.call(\"preference_create\", params);\r\n  },\r\n\r\n  /**\r\n   * Edit a preference value and apply to all users if allowed\r\n   * ACCESS REQUIRED: 100 (Admin)\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @param {Object} params\r\n   * @param {string} params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n   * @param {string|number} params.value (string/integer) Preference value\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.all] 0, 1 apply to all users\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.default] 0, 1 set as system default (New and public users). ACCESS: 100 (Admin)\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#preference_edit}\r\n   */\r\n  preferenceEdit(params) {\r\n    return this.call(\"preference_edit\", params);\r\n  },\r\n\r\n  /**\r\n   * Delete a non-system preference by name\r\n   * ACCESS REQUIRED: 100 (Admin)\r\n   * @param {Object} params\r\n   * @param {string} params.filter Preference name e.g ('notify_email', 'ajax_load')\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#preference_delete}\r\n   */\r\n  preferenceDelete(params) {\r\n    return this.call(\"preference_delete\", params);\r\n  },\r\n};\r\n","/**\r\n * @typedef {Object} ShareResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} name\r\n * @property {string} owner\r\n * @property {boolean} allow_stream\r\n * @property {boolean} allow_download\r\n * @property {number} creation_date\r\n * @property {number} lastvisit_date\r\n * @property {string} object_type\r\n * @property {import(\"./base.js\").UID} object_id\r\n * @property {number} expire_days\r\n * @property {number} max_counter\r\n * @property {number} counter\r\n * @property {string} secret\r\n * @property {string} public_url\r\n * @property {string} description\r\n */\r\n\r\n/**\r\n * @typedef {Object} SharesResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {ShareResponse[]} share\r\n */\r\n\r\nexport const sharesMethods = {\r\n  /**\r\n   * This searches the shares and returns... shares\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} [params]\r\n   * @param {string} [params.filter] UID to find\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 boolean to match the exact filter string\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<SharesResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#shares}\r\n   */\r\n  shares(params) {\r\n    return this.call(\"shares\", params);\r\n  },\r\n\r\n  /**\r\n   * Return a share from UID\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @returns {Promise<ShareResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#share}\r\n   */\r\n  share(params) {\r\n    return this.call(\"share\", params);\r\n  },\r\n\r\n  /**\r\n   * Create a public url that can be used by anyone to stream media.\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID of object you are sharing\r\n   * @param {\"song\"|\"album\"|\"artist\"|\"playlist\"|\"podcast\"|\"podcast_episode\"|\"video\"} params.type\r\n   * @param {string} [params.description] description (will be filled for you if empty)\r\n   * @param {number} [params.expires] days to keep active\r\n   * @returns {Promise<ShareResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#share_create}\r\n   */\r\n  shareCreate(params) {\r\n    return this.call(\"share_create\", params);\r\n  },\r\n\r\n  /**\r\n   * Update the description and/or expiration date for an existing share\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.stream] 0, 1\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.download] 0, 1\r\n   * @param {number} [params.expires] days to keep active\r\n   * @param {string} [params.description] description\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#share_edit}\r\n   */\r\n  shareEdit(params) {\r\n    return this.call(\"share_edit\", params);\r\n  },\r\n\r\n  /**\r\n   * Delete an existing share.\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID of share to delete\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#share_delete}\r\n   */\r\n  shareDelete(params) {\r\n    return this.call(\"share_delete\", params);\r\n  },\r\n};\r\n","/**\r\n * @typedef {Object} ShoutResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {number} date\r\n * @property {string} text\r\n * @property {import(\"./users.js\").UserSummary} user\r\n * @property {\"song\"|\"album\"|\"artist\"|\"playlist\"} object_type\r\n * @property {import(\"./base.js\").UID} object_id\r\n */\r\n\r\nexport const shoutsMethods = {\r\n  /**\r\n   * This gets the latest posted shouts\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} [params]\r\n   * @param {string} [params.username] Username to find\r\n   * @param {string} [params.filter] Alias of username (Ampache 7.9.0+)\r\n   * @param {number} [params.limit] Maximum number of results to return\r\n   * @returns {Promise<{ shout: ShoutResponse[] }>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#last_shouts}\r\n   */\r\n  last_shouts(params) {\r\n    return this.call(\"last_shouts\", params);\r\n  },\r\n};\r\n","/**\n * @typedef {Object} SongResponse\n * @property {import(\"./base.js\").UID} id\n * @property {string} title\n * @property {string} name\n * @property {import(\"./artists.js\").ArtistSummary} artist\n * @property {import(\"./albums.js\").AlbumSummary} album\n * @property {import(\"./artists.js\").ArtistSummary} albumartist\n * @property {number} disk\n * @property {number} track\n * @property {string} filename\n * @property {import(\"./genres.js\").GenreSummary[]} genre\n * @property {number} playlisttrack\n * @property {number} time\n * @property {number|string} year\n * @property {string} format\n * @property {string} stream_format\n * @property {number} rate\n * @property {string} mode\n * @property {string} mime\n * @property {string} stream_mime\n * @property {string} url\n * @property {number} size\n * @property {string|null} mbid\n * @property {string|null} album_mbid\n * @property {string|null} artist_mbid\n * @property {string} art\n * @property {boolean} has_art\n * @property {boolean} flag\n * @property {number|null} rating\n * @property {number|null} averagerating\n * @property {number} playcount\n * @property {number} catalog\n * @property {string} composer\n * @property {number|null} channels\n * @property {string} comment\n * @property {string|null} license\n * @property {string} publisher\n * @property {string} language\n * @property {string} lyrics\n * @property {number|null} replaygain_album_gain\n * @property {number|null} replaygain_album_peak\n * @property {number|null} replaygain_track_gain\n * @property {number|null} replaygain_track_peak\n * @property {number|null} r128_album_gain\n * @property {number|null} r128_track_gain\n */\n\n/**\n * @typedef {Object} SongsResponse\n * @property {number} total_count\n * @property {string} md5\n * @property {SongResponse[]} song\n */\n\n/**\n * @typedef {Object} DeletedSongResponse\n * @property {import(\"./base.js\").UID} id\n * @property {number} addition_time\n * @property {number} delete_time\n * @property {number} update_time\n * @property {string} title\n * @property {string} file\n * @property {import(\"./base.js\").UID} catalog\n * @property {number} total_count\n * @property {number} total_skip\n * @property {import(\"./base.js\").UID} album\n * @property {import(\"./base.js\").UID} artist\n */\n\n/**\n * @typedef {Object} DeletedSongsResponse\n * @property {number} total_count\n * @property {string} md5\n * @property {DeletedSongResponse[]} deleted_song\n */\n\nimport qs from \"querystringify\";\n\nexport const songsMethods = {\n  /**\n   * Returns songs based on the specified filter\n   * @remarks MINIMUM_API_VERSION=380001\n   * @param {Object} [params]\n   * @param {string} [params.filter] Filter results to match this string\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\n   * @param {Date} [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\n   * @param {Date} [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @param {string} [params.cond]\n   * @param {string} [params.sort]\n   * @returns {Promise<SongsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#songs}\n   */\n  songs(params) {\n    return this.call(\"songs\", params);\n  },\n\n  /**\n   * Returns a single song\n   * @remarks MINIMUM_API_VERSION=380001\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID to find\n   * @returns {Promise<SongResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#song}\n   */\n  song(params) {\n    return this.call(\"song\", params);\n  },\n\n  /**\n   * Songs of the specified artist\n   * @remarks MINIMUM_API_VERSION=380001\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID to find\n   * @param {import(\"./base.js\").BinaryBoolean} [params.top50] 0, 1 (if true filter to the artist top 50)\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @param {string} [params.cond]\n   * @param {string} [params.sort]\n   * @returns {Promise<SongsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#artist_songs}\n   */\n  artistSongs(params) {\n    return this.call(\"artist_songs\", params);\n  },\n\n  /**\n   * Songs of the specified album\n   * @remarks MINIMUM_API_VERSION=380001\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID to find\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @param {string} [params.cond]\n   * @param {string} [params.sort]\n   * @returns {Promise<SongsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#album_songs}\n   */\n  albumSongs(params) {\n    return this.call(\"album_songs\", params);\n  },\n\n  /**\n   * Songs of the specified genre\n   * @remarks MINIMUM_API_VERSION=380001\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID to find\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @param {string} [params.cond]\n   * @param {string} [params.sort]\n   * @returns {Promise<SongsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#genre_songs}\n   */\n  genreSongs(params) {\n    return this.call(\"genre_songs\", params);\n  },\n\n  /**\n   * This returns the songs for a playlist\n   * @remarks MINIMUM_API_VERSION=380001\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID to find\n   * @param {import(\"./base.js\").BinaryBoolean} [params.random] 0, 1 (if true get random songs using limit)\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @returns {Promise<SongsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#playlist_songs}\n   */\n  playlistSongs(params) {\n    return this.call(\"playlist_songs\", params);\n  },\n\n  /**\n   * This returns the songs for a smartlist\n   * @remarks MINIMUM_API_VERSION=6.9.1\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID to find\n   * @param {import(\"./base.js\").BinaryBoolean} [params.random] 0, 1 (if true get random songs using limit)\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @returns {Promise<SongsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#smartlist_songs}\n   */\n  smartlistSongs(params) {\n    return this.call(\"smartlist_songs\", params);\n  },\n\n  /**\n   * This returns the songs for a license\n   * @remarks MINIMUM_API_VERSION=420000\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID to find\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @param {string} [params.cond]\n   * @param {string} [params.sort]\n   * @returns {Promise<SongsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#license_songs}\n   */\n  licenseSongs(params) {\n    return this.call(\"license_songs\", params);\n  },\n\n  /**\n   * Delete an existing song. (if you are allowed to)\n   * @remarks MINIMUM_API_VERSION=5.0.0\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID of song to delete\n   * @returns {Promise<import(\"./base.js\").Success>}\n   * @see {@link https://ampache.org/api/api-json-methods#song_delete}\n   */\n  songDelete(params) {\n    return this.call(\"song_delete\", params);\n  },\n\n  /**\n   * Get the full song file tags using VaInfo\n   * This is used to get tags for remote catalogs to allow maximum data to be returned\n   * @remarks MINIMUM_API_VERSION=6.7.0\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter UID of song to fetch\n   * @returns {Promise<*>}\n   * @see {@link https://ampache.org/api/api-json-methods#song_tags}\n   */\n  songTags(params) {\n    return this.call(\"song_tags\", params);\n  },\n\n  /**\n   * Return database lyrics or search with plugins by song id\n   * @remarks MINIMUM_API_VERSION=6.7.0\n   * @param {Object} params\n   * @param {import(\"./base.js\").UID} params.filter Song id to find\n   * @param {import(\"./base.js\").BinaryBoolean} [params.plugins] 0, 1, if false disable plugin lookup (default: 1)\n   * @returns {Promise<*>}\n   * @see {@link https://ampache.org/api/api-json-methods#get_lyrics}\n   */\n  getLyrics(params) {\n    return this.call(\"get_lyrics\", params);\n  },\n\n  /**\n   * This takes a URL and returns the song object in question\n   * @remarks MINIMUM_API_VERSION=380001\n   * @param {Object} params\n   * @param {string} [params.url] Full Ampache URL from server (deprecated in 7.9.0+, use filter)\n   * @param {string} [params.filter] Alias of url (Ampache 7.9.0+)\n   * @returns {Promise<SongResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#url_to_song}\n   */\n  urlToSong(params) {\n    let query = \"url_to_song\";\n    const out = { ...params };\n    if (out.url != null) out.url = encodeURIComponent(out.url);\n    query += qs.stringify(out, \"&\");\n    return this.request(query);\n  },\n\n  /**\n   * This searches the songs and returns... songs\n   * @remarks MINIMUM_API_VERSION=380001\n   * @param {Object} params\n   * @param {string} params.filter Filter results to match this string\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @returns {Promise<SongsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#search_songs}\n   */\n  searchSongs(params) {\n    return this.call(\"search_songs\", params);\n  },\n\n  /**\n   * Returns songs that have been deleted from the server\n   * @remarks MINIMUM_API_VERSION=500000\n   * @param {Object} [params]\n   * @param {number} [params.offset]\n   * @param {number} [params.limit]\n   * @returns {Promise<DeletedSongsResponse>}\n   * @see {@link https://ampache.org/api/api-json-methods#deleted_songs}\n   */\n  deletedSongs(params) {\n    return this.call(\"deleted_songs\", params);\n  },\n};\n","/**\r\n * @typedef {import(\"./songs.js\").SongResponse|import(\"./albums.js\").AlbumResponse|import(\"./artists.js\").ArtistResponse|import(\"./playlists.js\").PlaylistResponse|import(\"./podcasts.js\").PodcastResponse|import(\"./podcasts.js\").PodcastEpisodeResponse|import(\"./live-streams.js\").LiveStreamResponse} IndexType\r\n */\r\n\r\n/**\r\n * @typedef {import(\"./songs.js\").SongResponse|import(\"./albums.js\").AlbumResponse|import(\"./artists.js\").ArtistResponse|import(\"./videos.js\").VideoResponse|import(\"./playlists.js\").PlaylistResponse|import(\"./podcasts.js\").PodcastResponse|import(\"./podcasts.js\").PodcastEpisodeResponse} StatsType\r\n */\r\n\r\n/**\r\n * @typedef {Object} IndexEntry\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} name\r\n * @property {string} prefix\r\n * @property {string} basename\r\n */\r\n\r\n/**\r\n * @typedef {Object} NowPlayingResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {\"song\"|\"podcast_episode\"|\"video\"} type\r\n * @property {string} client\r\n * @property {number} expire\r\n * @property {import(\"./users.js\").UserSummary} user\r\n */\r\n\r\n/**\r\n * @typedef {Object} RuleResponse\r\n * @property {string} name\r\n * @property {string} label\r\n * @property {string} type\r\n * @property {string} title\r\n * @property {string[]} widget\r\n */\r\n\r\nimport qs from \"querystringify\";\r\n\r\nconst GET_INDEXES_TYPES = new Set([\r\n  \"song\",\r\n  \"album\",\r\n  \"artist\",\r\n  \"album_artist\",\r\n  \"song_artist\",\r\n  \"playlist\",\r\n  \"podcast\",\r\n  \"podcast_episode\",\r\n  \"live_stream\",\r\n  \"catalog\",\r\n]);\r\nconst GET_SIMILAR_TYPES = new Set([\"song\", \"artist\"]);\r\nconst STATS_TYPES = new Set([\r\n  \"song\",\r\n  \"album\",\r\n  \"artist\",\r\n  \"video\",\r\n  \"playlist\",\r\n  \"podcast\",\r\n  \"podcast_episode\",\r\n]);\r\nconst ADVANCED_SEARCH_TYPES = new Set([\r\n  \"song\",\r\n  \"album\",\r\n  \"artist\",\r\n  \"album_artist\",\r\n  \"song_artist\",\r\n  \"label\",\r\n  \"playlist\",\r\n  \"podcast\",\r\n  \"podcast_episode\",\r\n  \"genre\",\r\n  \"user\",\r\n  \"video\",\r\n]);\r\n\r\nexport const systemMethods = {\r\n  /**\r\n   * Check Ampache for updates and run the update if there is one.\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @see {@link https://ampache.org/api/api-json-methods#system_update}\r\n   */\r\n  systemUpdate() {\r\n    return this.call(\"system_update\");\r\n  },\r\n\r\n  /**\r\n   * This takes a collection of inputs and returns ID + name for the object type\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param params.type type of object to find\r\n   * @param [params.filter] search the name of the object_type\r\n   * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n   * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n   * @param [params.include] 0, 1 (include songs in a playlist or episodes in a podcast)\r\n   * @param [params.hide_search] 0, 1 (if true do not include searches/smartlists in the result)\r\n   * @param [params.offset]\r\n   * @param [params.limit]\r\n   * @param [params.cond]\r\n   * @param [params.sort]\r\n   * @see {@link https://ampache.org/api/api-json-methods#get_indexes}\r\n   * @deprecated Being removed in 7.0.0. Use `list` instead.\r\n   */\r\n  getIndexes(params) {\r\n    if (!GET_INDEXES_TYPES.has(params.type)) {\r\n      return false;\r\n    }\r\n    const query = \"get_indexes\" + qs.stringify(params, \"&\");\r\n    return this.request(query);\r\n  },\r\n\r\n  /**\r\n   * This takes a named array of objects and returning `id`, `name`, `prefix` and `basename`\r\n   * @remarks MINIMUM_API_VERSION=6.0.0\r\n   * @param params.type type of object to find\r\n   * @param [params.filter] Value is Alpha Match for returned results, may be more than one letter/number\r\n   * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n   * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n   * @param [params.hide_search] 0, 1 (if true do not include searches/smartlists in the result)\r\n   * @param [params.offset]\r\n   * @param [params.limit]\r\n   * @param [params.cond]\r\n   * @param [params.sort]\r\n   * @see {@link https://ampache.org/api/api-json-methods#list}\r\n   */\r\n  list(params) {\r\n    return this.call(\"list\", params);\r\n  },\r\n\r\n  /**\r\n   * This takes a collection of inputs and return ID's for the object type.\r\n   * @remarks MINIMUM_API_VERSION=6.3.0\r\n   * @param params.type type of object to find\r\n   * @param [params.filter] Value is Alpha Match for returned results, may be more than one letter/number\r\n   * @param [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n   * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n   * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n   * @param [params.include] 0, 1, (include child objects)\r\n   * @param [params.hide_search] 0, 1 (if true do not include searches/smartlists in the result)\r\n   * @param [params.offset]\r\n   * @param [params.limit]\r\n   * @param [params.cond]\r\n   * @param [params.sort]\r\n   * @see {@link https://ampache.org/api/api-json-methods#index}\r\n   */\r\n  index(params) {\r\n    return this.call(\"index\", params);\r\n  },\r\n\r\n  /**\r\n   * Return children of a parent object in a folder traversal/browse style\r\n   * If you don't send any parameters you'll get a catalog list (the 'root' path)\r\n   * @remarks MINIMUM_API_VERSION=6.0.0\r\n   * @param [params.filter] object_id\r\n   * @param [params.type] type of object to find\r\n   * @param [params.catalog] catalog ID you are browsing (required on 'artist', 'album', 'podcast')\r\n   * @param [params.add] ISO 8601 Date Format (2020-09-16) Find objects with an 'add' date newer than the specified date\r\n   * @param [params.update] ISO 8601 Date Format (2020-09-16) Find objects with an 'update' time newer than the specified date\r\n   * @param [params.offset]\r\n   * @param [params.limit]\r\n   * @param [params.cond]\r\n   * @param [params.sort]\r\n   * @see {@link https://ampache.org/api/api-json-methods#browse}\r\n   */\r\n  browse(params) {\r\n    return this.call(\"browse\", params);\r\n  },\r\n\r\n  /**\r\n   * Return similar artist IDs or similar song IDs compared to the input filter\r\n   * @remarks MINIMUM_API_VERSION=420000\r\n   * @param params.type type of object to check against\r\n   * @param params.filter UID to find\r\n   * @param [params.offset]\r\n   * @param [params.limit]\r\n   * @see {@link https://ampache.org/api/api-json-methods#get_similar}\r\n   */\r\n  getSimilar(params) {\r\n    if (!GET_SIMILAR_TYPES.has(params.type)) {\r\n      return false;\r\n    }\r\n    const query = \"get_similar\" + qs.stringify(params, \"&\");\r\n    return this.request(query);\r\n  },\r\n\r\n  /**\r\n   * Get some items based on some simple search types and filters. (Random by default)\r\n   * @remarks MINIMUM_API_VERSION=380001; CHANGED_IN_API_VERSION=400001\r\n   * @param params.type Object type\r\n   * @param [params.filter] newest, highest, frequent, recent, forgotten, flagged, random\r\n   * @param [params.user_id] Filter results to a certain user by UID\r\n   * @param [params.username] Filter results to a certain user by username\r\n   * @param [params.offset]\r\n   * @param [params.limit]\r\n   * @see {@link https://ampache.org/api/api-json-methods#stats}\r\n   */\r\n  stats(params) {\r\n    if (!STATS_TYPES.has(params.type)) {\r\n      return false;\r\n    }\r\n    const query = \"stats\" + qs.stringify(params, \"&\");\r\n    return this.request(query);\r\n  },\r\n\r\n  /**\r\n   * This rates a library item\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param params.type Object type\r\n   * @param params.id UID to find\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of id (Ampache 7.9.0+)\r\n   * @param params.rating Rating to apply\r\n   * @see {@link https://ampache.org/api/api-json-methods#rate}\r\n   */\r\n  rate(params) {\r\n    return this.call(\"rate\", params);\r\n  },\r\n\r\n  /**\r\n   * This flags a library item as a favorite\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param params.type Object type\r\n   * @param params.id UID to find\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of id (Ampache 7.9.0+)\r\n   * @param params.flag 0, 1\r\n   * @see {@link https://ampache.org/api/api-json-methods#flag}\r\n   */\r\n  flag(params) {\r\n    return this.call(\"flag\", params);\r\n  },\r\n\r\n  /**\r\n   * Take a song_id and update the object_count and user_activity table with a play. This allows other sources to record play history to Ampache.\r\n   * If you don't supply a user id (optional) then just fall back to you.\r\n   * ACCESS REQUIRED: 100 (Admin) permission to change another user's play history\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param params.id UID of song\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of id (Ampache 7.9.0+)\r\n   * @param [params.user] UID of user\r\n   * @param [params.client] Client string\r\n   * @param [params.date] UNIXTIME\r\n   * @see {@link https://ampache.org/api/api-json-methods#record_play}\r\n   */\r\n  recordPlay(params) {\r\n    return this.call(\"record_play\", params);\r\n  },\r\n\r\n  /**\r\n   * Search for a song using text info and then record a play if found. This allows other sources to record play history to ampache\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param params.song HTML encoded string\r\n   * @param params.artist HTML encoded string\r\n   * @param params.album HTML encoded string\r\n   * @param [params.songmbid] Song MBID\r\n   * @param [params.artistmbid] Artist MBID\r\n   * @param [params.albummbid] Album MBID\r\n   * @param [params.song_mbid] Alias of songmbid\r\n   * @param [params.artist_mbid] Alias of artistmbid\r\n   * @param [params.album_mbid] Alias of albummbid\r\n   * @param [params.date] UNIXTIME\r\n   * @param [params.client] Client string\r\n   * @see {@link https://ampache.org/api/api-json-methods#scrobble}\r\n   */\r\n  scrobble(params) {\r\n    return this.call(\"scrobble\", params);\r\n  },\r\n\r\n  /**\r\n   * Update a single album, artist, song from the tag data\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param params.type Object type\r\n   * @param params.id UID to find\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of id (Ampache 7.9.0+)\r\n   * @see {@link https://ampache.org/api/api-json-methods#update_from_tags}\r\n   */\r\n  updateFromTags(params) {\r\n    return this.call(\"update_from_tags\", params);\r\n  },\r\n\r\n  /**\r\n   * Update artist information and fetch similar artists from last.fm\r\n   * Make sure lastfm_API_key is set in your configuration file\r\n   * ACCESS REQUIRED: 75 (Catalog Manager)\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param params.id UID to find\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of id (Ampache 7.9.0+)\r\n   * @see {@link https://ampache.org/api/api-json-methods#update_artist_info}\r\n   */\r\n  updateArtistInfo(params) {\r\n    return this.call(\"update_artist_info\", params);\r\n  },\r\n\r\n  /**\r\n   * Updates a single album, artist, song running the gather_art process.\r\n   * Doesn't overwrite existing art by default.\r\n   * ACCESS REQUIRED: 75 (Catalog Manager)\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param params.id UID to update\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of id (Ampache 7.9.0+)\r\n   * @param params.type Object type\r\n   * @param [params.overwrite]\r\n   * @see {@link https://ampache.org/api/api-json-methods#update_art}\r\n   */\r\n  updateArt(params) {\r\n    return this.call(\"update_art\", params);\r\n  },\r\n\r\n  /**\r\n   * Streams a given media file. Takes the file id in parameter with optional max bit rate, file format, time offset,\r\n   * size and estimate content length option.\r\n   * NOTE search and playlist will only stream a random object from the list.\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param params.id UID to find\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of id (Ampache 7.9.0+)\r\n   * @param params.type Object type\r\n   * @param [params.bitrate] Max bitrate for transcoding\r\n   * @param [params.format] mp3, ogg, raw, etc. (raw returns the original format)\r\n   * @param [params.offset] Time offset\r\n   * @param [params.length] 0, 1 (estimate content length)\r\n   * @param [params.stats] 0, 1 (if false disable stat recording when playing the object; default: 1)\r\n   * @see {@link https://ampache.org/api/api-json-methods#stream}\r\n   */\r\n  stream(params) {\r\n    const query = \"stream\" + (params != null ? qs.stringify(params, \"&\") : \"\");\r\n    return this.binary(query);\r\n  },\r\n\r\n  /**\r\n   * Downloads a given media file. set format=raw to download the full file\r\n   * NOTE search and playlist will only download a random object from the list\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param params.id UID to find\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of id (Ampache 7.9.0+)\r\n   * @param params.type Object type\r\n   * @param [params.format] mp3, ogg, raw, etc. (raw returns the original format)\r\n   * @param [params.bitrate] max bitrate for transcoding in bytes (e.g 192000=192Kb)\r\n   * @param [params.stats] 0, 1 (if false disable stat recording when playing the object; default: 1)\r\n   * @see {@link https://ampache.org/api/api-json-methods#download}\r\n   */\r\n  download(params) {\r\n    const query = \"download\" + (params != null ? qs.stringify(params, \"&\") : \"\");\r\n    return this.binary(query);\r\n  },\r\n\r\n  /**\r\n   * Get an art image file.\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param params.id UID to find\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of id (Ampache 7.9.0+)\r\n   * @param params.type Object type\r\n   * @param [params.size] width x height (e.g. '640x480')\r\n   * @see {@link https://ampache.org/api/api-json-methods#get_art}\r\n   */\r\n  getArt(params) {\r\n    const query = \"get_art\" + (params != null ? qs.stringify(params, \"&\") : \"\");\r\n    return this.binary(query);\r\n  },\r\n\r\n  /**\r\n   * This is for controlling localplay\r\n   * @param params.command The command to send to the localplay controller\r\n   * @param [params.oid] Object UID\r\n   * @param {import(\"./base.js\").UID} [params.filter] Alias of oid (Ampache 7.9.0+)\r\n   * @param [params.type] Object type\r\n   * @param [params.clear] 0, 1 (Clear the current playlist before adding)\r\n   * @remarks MINIMUM_API_VERSION=380001; CHANGED_IN_API_VERSION=5.0.0\r\n   * @see {@link https://ampache.org/api/api-json-methods#localplay}\r\n   */\r\n  localplay(params) {\r\n    return this.call(\"localplay\", params);\r\n  },\r\n\r\n  /**\r\n   * Get the list of songs in your localplay playlist\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @see {@link https://ampache.org/api/api-json-methods#localplay_songs}\r\n   */\r\n  localplaySongs() {\r\n    return this.call(\"localplay_songs\");\r\n  },\r\n\r\n  /**\r\n   * This is for controlling democratic play (Songs only). VOTE: +1 vote for the oid. DEVOTE: -1 vote for the oid.\r\n   * PLAYLIST: Return an array of song items with an additional VOTE COUNT element.\r\n   * PLAY: Returns the URL for playing democratic play.\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param params.oid UID of song\r\n   * @param params.method vote, devote, playlist, play\r\n   * @see {@link https://ampache.org/api/api-json-methods#democratic}\r\n   */\r\n  democratic(params) {\r\n    return this.call(\"democratic\", params);\r\n  },\r\n\r\n  /**\r\n   * Get what is currently being played by all users.\r\n   * @remarks MINIMUM_API_VERSION=6.3.1\r\n   * @see {@link https://ampache.org/api/api-json-methods#now_playing}\r\n   */\r\n  nowPlaying() {\r\n    return this.call(\"now_playing\");\r\n  },\r\n\r\n  /**\r\n   * Inform the server about the state of your client. (Song you are playing, Play/Pause state, etc.)\r\n   * @remarks MINIMUM_API_VERSION=6.4.0\r\n   * @param params.filter $object_id currently playing/stopping\r\n   * @param [params.type] song, video, podcast_episode (Default: song)\r\n   * @param [params.state] play, stop (Default: play)\r\n   * @param [params.time] current play time in whole seconds (Default: 0)\r\n   * @param [params.client] agent/client name\r\n   * @see {@link https://ampache.org/api/api-json-methods#player}\r\n   */\r\n  player(params) {\r\n    return this.call(\"player\", params);\r\n  },\r\n\r\n  /**\r\n   * Return external plugin metadata searching by object id and type\r\n   * @remarks MINIMUM_API_VERSION=6.0.0\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter Object id to find\r\n   * @param {\"song\"|\"album\"|\"artist\"|\"label\"} params.type Object type\r\n   * @returns {Promise<*>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#get_external_metadata}\r\n   */\r\n  getExternalMetadata(params) {\r\n    return this.call(\"get_external_metadata\", params);\r\n  },\r\n\r\n  /**\r\n   * Print a list of valid search rules for your search type\r\n   * @remarks MINIMUM_API_VERSION=6.8.0\r\n   * @param params.filter Object type\r\n   * @see {@link https://ampache.org/api/api-json-methods#search_rules}\r\n   */\r\n  searchRules(params) {\r\n    return this.call(\"search_rules\", params);\r\n  },\r\n\r\n  /**\r\n   * Perform an advanced search given passed rules.\r\n   * You'll want to consult the docs for this.\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param params.operator and, or (whether to match one rule or all)\r\n   * @param params.type Object type to return\r\n   * @param params.rules An array of rules\r\n   * @param [params.random] 0, 1 (random order of results; default to 0)\r\n   * @param [params.offset]\r\n   * @param [params.limit]\r\n   * @see {@link https://ampache.org/api/api-json-methods#advanced_search}\r\n   */\r\n  advancedSearch(params) {\r\n    for (let i = 0; i < params.rules.length; i++) {\r\n      const thisRule = params.rules[i];\r\n      const ruleNumber = i + 1;\r\n\r\n      params[\"rule_\" + ruleNumber] = thisRule[0];\r\n      params[\"rule_\" + ruleNumber + \"_operator\"] = thisRule[1];\r\n      params[\"rule_\" + ruleNumber + \"_input\"] = thisRule[2];\r\n\r\n      if (thisRule[0] === \"metadata\") {\r\n        params[\"rule_\" + ruleNumber + \"_subtype\"] = thisRule[3];\r\n      }\r\n    }\r\n\r\n    delete params.rules;\r\n\r\n    if (!ADVANCED_SEARCH_TYPES.has(params.type)) {\r\n      return false;\r\n    }\r\n    const query = \"advanced_search\" + qs.stringify(params, \"&\");\r\n    return this.request(query);\r\n  },\r\n\r\n  /**\r\n   * Alias of advancedSearch\r\n   * @see advancedSearch\r\n   */\r\n  search(params) {\r\n    return this.advancedSearch(params);\r\n  },\r\n\r\n  /**\r\n   * Perform a search given passed rules and return matching objects in a group.\r\n   * If the rules do not exist for the object type or would return the entire table they will not return objects\r\n   * You'll want to consult the docs for this.\r\n   * @remarks MINIMUM_API_VERSION=6.3.0\r\n   * @param params.operator and, or (whether to match one rule or all)\r\n   * @param params.rules An array of rules\r\n   * @param [params.type] Object type to return (all, music, song_artist, album_artist, podcast, video; all by default)\r\n   * @param [params.random] 0, 1 (random order of results; default to 0)\r\n   * @param [params.offset]\r\n   * @param [params.limit]\r\n   * @see {@link https://ampache.org/api/api-json-methods#search_group}\r\n   */\r\n  searchGroup(params) {\r\n    for (let i = 0; i < params.rules.length; i++) {\r\n      const thisRule = params.rules[i];\r\n      const ruleNumber = i + 1;\r\n\r\n      params[\"rule_\" + ruleNumber] = thisRule[0];\r\n      params[\"rule_\" + ruleNumber + \"_operator\"] = thisRule[1];\r\n      params[\"rule_\" + ruleNumber + \"_input\"] = thisRule[2];\r\n\r\n      if (thisRule[0] === \"metadata\") {\r\n        params[\"rule_\" + ruleNumber + \"_subtype\"] = thisRule[3];\r\n      }\r\n    }\r\n\r\n    delete params.rules;\r\n\r\n    const query = \"search_group\" + qs.stringify(params, \"&\");\r\n    return this.request(query);\r\n  },\r\n};\r\n","/**\r\n * @typedef {Object} UserSummary\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} username\r\n */\r\n\r\n/**\r\n * @typedef {Object} UserResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} username\r\n * @property {string} auth\r\n * @property {string} email\r\n * @property {number} access\r\n * @property {string|null} streamtoken\r\n * @property {number} fullname_public\r\n * @property {string|null} validation\r\n * @property {boolean} disabled\r\n * @property {number} create_date\r\n * @property {number} last_seen\r\n * @property {string|null} website\r\n * @property {string|null} state\r\n * @property {string|null} city\r\n */\r\n\r\n/**\r\n * @typedef {Object} UsersResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {UserResponse[]} user\r\n */\r\n\r\n/**\r\n * @typedef {Object} ActivityResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {number} date\r\n * @property {string} object_type\r\n * @property {import(\"./base.js\").UID} object_id\r\n * @property {string} action\r\n * @property {UserSummary} user\r\n */\r\n\r\nexport const usersMethods = {\r\n  /**\r\n   * Get ids and usernames for your site\r\n   * @remarks MINIMUM_API_VERSION=5.0.0\r\n   * @returns {Promise<{ user: UserSummary[] }>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#users}\r\n   */\r\n  users() {\r\n    return this.call(\"users\");\r\n  },\r\n\r\n  /**\r\n   * This get a user's public information (or current user if username is omitted)\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} [params]\r\n   * @param {string} [params.username] Username of the user to get details for\r\n   * @param {string} [params.filter] Alias of username (Ampache 7.9.0+)\r\n   * @returns {Promise<UserResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#user}\r\n   */\r\n  user(params) {\r\n    return this.call(\"user\", params);\r\n  },\r\n\r\n  /**\r\n   * Create a new user\r\n   * ACCESS REQUIRED: 100 (Admin)\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param {Object} params\r\n   * @param {string} params.username Username\r\n   * @param {string} params.password SHA256 hashed password\r\n   * @param {string} params.email  Email\r\n   * @param {string} [params.fullname] Full Name\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.disable] 0, 1\r\n   * @param {number} [params.group] Catalog filter group (API param: group), default = 0\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#user_create}\r\n   */\r\n  userCreate(params) {\r\n    return this.call(\"user_create\", params);\r\n  },\r\n\r\n  /**\r\n   * Register as a new user if allowed.\r\n   * @remarks MINIMUM_API_VERSION=6.0.0\r\n   * @param {Object} params\r\n   * @param {string} params.username Username\r\n   * @param {string} params.password SHA256 hashed password\r\n   * @param {string} params.email  Email\r\n   * @param {string} [params.fullname] Full Name\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods/#register}\r\n   */\r\n  register(params) {\r\n    return this.call(\"register\", params);\r\n  },\r\n\r\n  /**\r\n   * Update an existing user\r\n   * ACCESS REQUIRED: 100 (Admin)\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param {Object} params\r\n   * @param {string} params.username Username\r\n   * @param {string} [params.password] Password\r\n   * @param {string} [params.email] Email\r\n   * @param {string} [params.fullname] Full Name\r\n   * @param {string} [params.website] Website\r\n   * @param {string} [params.state] State\r\n   * @param {string} [params.city] City\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.disable] 0, 1\r\n   * @param {string} [params.maxbitrate] Max bitrate for transcoding\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @deprecated Being removed in 7.0.0. Use `user_edit` instead.\r\n   * @see {@link https://ampache.org/api/api-json-methods#user_update}\r\n   */\r\n  userUpdate(params) {\r\n    return this.call(\"user_update\", params);\r\n  },\r\n\r\n  /**\r\n   * Update an existing user\r\n   * ACCESS REQUIRED: 100 (Admin)\r\n   * @remarks MINIMUM_API_VERSION=6.0.0\r\n   * @param {Object} params\r\n   * @param {string} params.username Username\r\n   * @param {string} [params.password] Password\r\n   * @param {string} [params.email] Email\r\n   * @param {string} [params.fullname] Full Name\r\n   * @param {string} [params.website] Website\r\n   * @param {string} [params.state] State\r\n   * @param {string} [params.city] City\r\n   * @param {string} [params.maxbitrate] Max bitrate for transcoding\r\n   * @param {number} [params.group] Catalog filter group, default = 0\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.disable] 0, 1\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.fullname_public] show fullname in public display\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.reset_apikey] reset user Api Key\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.reset_streamtoken] reset user Stream Token\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.clear_stats] reset all stats for this user\r\n   * @param {string} [params.filter] Alias of username (Ampache 7.9.0+)\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#user_edit}\r\n   */\r\n  userEdit(params) {\r\n    return this.call(\"user_edit\", params);\r\n  },\r\n\r\n  /**\r\n   * Delete an existing user.\r\n   * ACCESS REQUIRED: 100 (Admin)\r\n   * @remarks MINIMUM_API_VERSION=400001\r\n   * @param {Object} params\r\n   * @param {string} params.username Username of user to delete (required by API)\r\n   * @param {string} [params.filter] Alias of username (Ampache 7.9.0+)\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#user_delete}\r\n   */\r\n  userDelete(params) {\r\n    return this.call(\"user_delete\", params);\r\n  },\r\n\r\n  /**\r\n   * This gets the followers for the requested username\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} params\r\n   * @param {string} params.username UID to find\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @param {string} [params.cond]\r\n   * @param {string} [params.sort]\r\n   * @returns {Promise<{ user: UserSummary[] }>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#followers}\r\n   */\r\n  followers(params) {\r\n    return this.call(\"followers\", params);\r\n  },\r\n\r\n  /**\r\n   * Get a list of people that this user follows\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} params\r\n   * @param {string} params.username\r\n   * @returns {Promise<{ user: UserSummary[] }>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#following}\r\n   */\r\n  following(params) {\r\n    return this.call(\"following\", params);\r\n  },\r\n\r\n  /**\r\n   * This will follow/unfollow a user\r\n   * @param {Object} params\r\n   * @param {string} params.username Username string to find\r\n   * @param {string} [params.filter] Alias of username (Ampache 7.9.0+)\r\n   * @returns {Promise<import(\"./base.js\").Success>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#toggle_follow}\r\n   */\r\n  toggleFollow(params) {\r\n    return this.call(\"toggle_follow\", params);\r\n  },\r\n\r\n  /**\r\n   * This get a user timeline\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} params\r\n   * @param {string} params.username Username to find\r\n   * @param {string} [params.filter] Alias of username (Ampache 7.9.0+)\r\n   * @param {number} [params.limit] Max results to return\r\n   * @param {number} [params.since] UNIXTIME\r\n   * @returns {Promise<{ activity: ActivityResponse[] }>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#timeline}\r\n   */\r\n  timeline(params) {\r\n    return this.call(\"timeline\", params);\r\n  },\r\n\r\n  /**\r\n   * This get current user friends timeline\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} [params]\r\n   * @param {number} [params.limit] Max results to return\r\n   * @param {number} [params.since] UNIXTIME\r\n   * @returns {Promise<{ activity: ActivityResponse[] }>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#friends_timeline}\r\n   */\r\n  friendsTimeline(params) {\r\n    return this.call(\"friends_timeline\", params);\r\n  },\r\n};\r\n","/**\r\n * @typedef {Object} VideoResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {string} title\r\n * @property {string} mime\r\n * @property {string} resolution\r\n * @property {number} size\r\n * @property {import(\"./genres.js\").GenreSummary[]} genre\r\n * @property {number} time\r\n * @property {string} url\r\n * @property {string} art\r\n * @property {boolean} has_art\r\n * @property {boolean} flag\r\n * @property {number|null} rating\r\n * @property {number|null} averagerating\r\n * @property {number} playcount\r\n */\r\n\r\n/**\r\n * @typedef {Object} VideosResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {VideoResponse[]} video\r\n */\r\n\r\n/**\r\n * @typedef {Object} DeletedVideoResponse\r\n * @property {import(\"./base.js\").UID} id\r\n * @property {number} addition_time\r\n * @property {number} delete_time\r\n * @property {string} title\r\n * @property {string} file\r\n * @property {import(\"./base.js\").UID} catalog\r\n * @property {number} total_count\r\n * @property {number} total_skip\r\n */\r\n\r\n/**\r\n * @typedef {Object} DeletedVideosResponse\r\n * @property {number} total_count\r\n * @property {string} md5\r\n * @property {DeletedVideoResponse[]} deleted_video\r\n */\r\n\r\nexport const videosMethods = {\r\n  /**\r\n   * Get videos\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} [params]\r\n   * @param {string} [params.filter] Filter results to match this string\r\n   * @param {import(\"./base.js\").BinaryBoolean} [params.exact] 0, 1 (if true filter is exact = rather than fuzzy LIKE)\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @returns {Promise<VideosResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#videos}\r\n   */\r\n  videos(params) {\r\n    return this.call(\"videos\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns a single video\r\n   * @remarks MINIMUM_API_VERSION=380001\r\n   * @param {Object} params\r\n   * @param {import(\"./base.js\").UID} params.filter UID to find\r\n   * @returns {Promise<VideoResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#video}\r\n   */\r\n  video(params) {\r\n    return this.call(\"video\", params);\r\n  },\r\n\r\n  /**\r\n   * This returns video objects that have been deleted\r\n   * @param {Object} [params]\r\n   * @param {number} [params.offset]\r\n   * @param {number} [params.limit]\r\n   * @returns {Promise<DeletedVideosResponse>}\r\n   * @see {@link https://ampache.org/api/api-json-methods#deleted_videos}\r\n   */\r\n  deletedVideos(params) {\r\n    return this.call(\"deleted_videos\", params);\r\n  },\r\n};\r\n","import fetch from \"isomorphic-unfetch\";\r\nimport qs from \"querystringify\";\r\nimport { outputDebugURL } from \"./utils.js\";\r\n\r\n/**\r\n * @typedef {Object} Config\r\n * @property {string} url\r\n * @property {string} [sessionKey]\r\n * @property {boolean} [useBearerToken]\r\n * @property {boolean} [debug]\r\n */\r\n\r\n/**\r\n * @typedef {Object} Success\r\n * @property {string} success\r\n */\r\n\r\n/**\r\n * @typedef {Object} Pagination\r\n * @property {number} [offset] Return results starting from this index position\r\n * @property {number} [limit] Maximum number of results to return\r\n */\r\n\r\n/**\r\n * @typedef {Object} ExtendedPagination\r\n * @property {number} [offset] Return results starting from this index position\r\n * @property {number} [limit] Maximum number of results to return\r\n * @property {string} [cond] Apply additional filters to the browse using ; separated comma string pairs (e.g. 'filter1,value1;filter2,value2')\r\n * @property {string} [sort] Sort name or comma-separated key pair. (e.g. 'name,order') Default order 'ASC' (e.g. 'name,ASC' == 'name')\r\n */\r\n\r\n/** @typedef {0|1} BinaryBoolean */\r\n\r\n/** @typedef {string|number} UID */\r\n\r\nexport class Base {\r\n  /**\r\n   * @param {Config} config\r\n   */\r\n  constructor(config) {\r\n    this.sessionKey = config.sessionKey || null;\r\n    this.url = config.url;\r\n    this.version = \"6.6.8\";\r\n    this.useBearerToken = config.useBearerToken || false;\r\n    this.debug = config.debug || false;\r\n  }\r\n\r\n  /**\r\n   * Build action string with optional params and call request.\r\n   * @template T\r\n   * @param {string} action API action name\r\n   * @param {Object} [params] Optional query params\r\n   * @returns {Promise<T>}\r\n   */\r\n  call(action, params) {\r\n    const query = action + (params != null ? qs.stringify(params, \"&\") : \"\");\r\n    return this.request(query);\r\n  }\r\n\r\n  /**\r\n   * @param {string} endpoint Action and optional query string\r\n   * @returns {string} Full request URL\r\n   * @private\r\n   */\r\n  _buildURL(endpoint) {\r\n    let url =\r\n      this.url +\r\n      \"/server/json.server.php?action=\" +\r\n      endpoint +\r\n      \"&version=\" +\r\n      this.version;\r\n\r\n    if (!this.useBearerToken) {\r\n      url += \"&auth=\" + this.sessionKey;\r\n    }\r\n\r\n    if (this.debug) {\r\n      outputDebugURL(url, this);\r\n    }\r\n\r\n    return url;\r\n  }\r\n\r\n  /**\r\n   * @template T\r\n   * @param {string} endpoint\r\n   * @returns {Promise<T>}\r\n   */\r\n  request(endpoint) {\r\n    const url = this._buildURL(endpoint);\r\n    return fetch(url, {\r\n      method: \"GET\",\r\n      headers: this.useBearerToken ? { Authorization: \"Bearer \" + this.sessionKey } : {},\r\n    }).then(async (r) => {\r\n      if (r.ok) {\r\n        return r.json();\r\n      }\r\n      let body = r.statusText;\r\n      const contentType = r.headers.get(\"content-type\");\r\n      try {\r\n        body = contentType && contentType.includes(\"application/json\")\r\n          ? await r.json()\r\n          : await r.text();\r\n      } catch (_) {\r\n        // keep statusText if body read fails\r\n      }\r\n      const err = new Error(r.statusText);\r\n      err.status = r.status;\r\n      err.body = body;\r\n      throw err;\r\n    });\r\n  }\r\n\r\n  /**\r\n   * @param {string} endpoint\r\n   * @returns {Promise<Blob>}\r\n   */\r\n  binary(endpoint) {\r\n    const url = this._buildURL(endpoint);\r\n    return fetch(url, {\r\n      method: \"GET\",\r\n      headers: this.useBearerToken ? { Authorization: \"Bearer \" + this.sessionKey } : {},\r\n    }).then((response) => response.blob());\r\n  }\r\n\r\n  /**\r\n   * @param {string} sessionKey\r\n   */\r\n  setSessionKey(sessionKey) {\r\n    this.sessionKey = sessionKey;\r\n  }\r\n\r\n  /**\r\n   * Construct and return a URL\r\n   * @param {string} endpoint\r\n   * @param {Object} [params]\r\n   * @returns {string}\r\n   */\r\n  rawURL(endpoint, params) {\r\n    const query = endpoint + (params != null ? qs.stringify(params, \"&\") : \"\");\r\n    return this._buildURL(query);\r\n  }\r\n}\r\n\r\nexport {};\r\n","import { albumsMethods } from \"./albums.js\";\r\nimport { artistsMethods } from \"./artists.js\";\r\nimport { authMethods } from \"./auth.js\";\r\nimport { bookmarksMethods } from \"./bookmarks.js\";\r\nimport { catalogsMethods } from \"./catalogs.js\";\r\nimport { genresMethods } from \"./genres.js\";\r\nimport { labelsMethods } from \"./labels.js\";\r\nimport { licensesMethods } from \"./licenses.js\";\r\nimport { liveStreamsMethods } from \"./live-streams.js\";\r\nimport { playlistsMethods } from \"./playlists.js\";\r\nimport { podcastsMethods } from \"./podcasts.js\";\r\nimport { preferencesMethods } from \"./preferences.js\";\r\nimport { sharesMethods } from \"./shares.js\";\r\nimport { shoutsMethods } from \"./shouts.js\";\r\nimport { songsMethods } from \"./songs.js\";\r\nimport { systemMethods } from \"./system.js\";\r\nimport { usersMethods } from \"./users.js\";\r\nimport { videosMethods } from \"./videos.js\";\r\nimport { Base } from \"./base.js\";\r\n\r\n/**\r\n * @typedef {Base} AmpacheAPI\r\n * AmpacheAPI extends Base and has all domain methods (albums, artists, auth, etc.) on its prototype.\r\n */\r\n\r\nclass AmpacheAPI extends Base {}\r\n\r\nObject.assign(AmpacheAPI.prototype, albumsMethods, artistsMethods, authMethods, bookmarksMethods, catalogsMethods, genresMethods, labelsMethods, licensesMethods, liveStreamsMethods, playlistsMethods, podcastsMethods, preferencesMethods, sharesMethods, shoutsMethods, songsMethods, systemMethods, usersMethods, videosMethods);\r\n\r\nexport default AmpacheAPI;\r\n"],"names":["albumsMethods","albums","params","this","call","album","artistAlbums","genreAlbums","artistsMethods","artists","artist","genreArtists","labelArtists","has","Object","prototype","hasOwnProperty","encode","input","encodeURIComponent","e","obj","prefix","value","key","pairs","isNaN","push","length","join","n","Promise","t","r","s","XMLHttpRequest","o","u","i","a","ok","status","statusText","url","responseURL","text","resolve","responseText","json","then","JSON","parse","blob","Blob","response","clone","headers","keys","entries","get","toLowerCase","l","open","method","onload","getAllResponseHeaders","replace","onerror","withCredentials","credentials","setRequestHeader","send","body","browser","self","fetch","require$$0","default","h","f","binLen","Error","c","parseInt","substr","w","E","A","charCodeAt","p","indexOf","search","charAt","ArrayBuffer","Uint8Array","outputUpper","toUpperCase","b64Pad","String","fromCharCode","outputLen","shakeLen","constructor","encoding","numRounds","U","R","update","T","F","m","g","slice","getHash","H","B","v","C","Y","S","I","setHMACKey","L","M","getHMAC","N","d","y","b","super","hmacKey","format","outputDebugURL","config","label","useBearerToken","sessionKey","console","debug","authMethods","handshake","token","auth","timestamp","Math","floor","Date","getTime","version","user","query","qs","Authorization","data","ping","goodbye","lostPassword","encryptPassword","password","time","getSHA256","shaObj","JsSHA","encryptPasswordUtil","bookmarksMethods","bookmark","bookmarks","getBookmark","bookmarkCreate","bookmarkEdit","bookmarkDelete","catalogsMethods","catalogs","catalog","catalogAction","catalogFile","catalogFolder","catalogAdd","catalogDelete","genresMethods","genres","genre","labelsMethods","labels","licensesMethods","licenses","license","liveStreamsMethods","liveStreams","liveStream","liveStreamCreate","liveStreamEdit","liveStreamDelete","playlistsMethods","playlists","smartlists","playlist","smartlist","userPlaylists","userSmartlists","playlistCreate","playlistAdd","playlistEdit","playlistDelete","smartlistDelete","playlistAddSong","playlistRemoveSong","playlistGenerate","playlistHash","podcastsMethods","podcasts","podcast","podcastCreate","podcastEdit","podcastDelete","podcastEpisodes","podcastEpisode","podcastEpisodeDelete","updatePodcast","deletedPodcastEpisodes","preferencesMethods","systemPreferences","systemPreference","userPreferences","userPreference","preferenceCreate","preferenceEdit","preferenceDelete","sharesMethods","shares","share","shareCreate","shareEdit","shareDelete","shoutsMethods","last_shouts","songsMethods","songs","song","artistSongs","albumSongs","genreSongs","playlistSongs","smartlistSongs","licenseSongs","songDelete","songTags","getLyrics","urlToSong","out","_extends","request","searchSongs","deletedSongs","GET_INDEXES_TYPES","Set","GET_SIMILAR_TYPES","STATS_TYPES","ADVANCED_SEARCH_TYPES","systemMethods","systemUpdate","getIndexes","type","list","index","browse","getSimilar","stats","rate","flag","recordPlay","scrobble","updateFromTags","updateArtistInfo","updateArt","stream","binary","download","getArt","localplay","localplaySongs","democratic","nowPlaying","player","getExternalMetadata","searchRules","advancedSearch","rules","thisRule","ruleNumber","searchGroup","usersMethods","users","userCreate","register","userUpdate","userEdit","userDelete","followers","following","toggleFollow","timeline","friendsTimeline","videosMethods","videos","video","deletedVideos","Base","action","_buildURL","endpoint","async","contentType","includes","_","err","setSessionKey","rawURL","AmpacheAPI","assign"],"mappings":"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"}