nixamp 0.77.2 → 0.78.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/backtoschool/dist/assets/{ar-Cj5WpObc.js → ar-CYu0byMf.js} +1 -1
  2. package/backtoschool/dist/assets/{cs-DOYgXvWh.js → cs-BTTM7DeB.js} +1 -1
  3. package/backtoschool/dist/assets/{da-CmgimT0P.js → da-iixezQtd.js} +1 -1
  4. package/backtoschool/dist/assets/{de-D_AUWuE3.js → de-Sx3acevR.js} +1 -1
  5. package/backtoschool/dist/assets/{es-B4QfiG7X.js → es-ByCnw8ja.js} +1 -1
  6. package/backtoschool/dist/assets/{fi-Clf9SZn5.js → fi-BCeFoeH5.js} +1 -1
  7. package/backtoschool/dist/assets/{fr-DpLIxvgd.js → fr-Nz5hMzAE.js} +1 -1
  8. package/backtoschool/dist/assets/{hi-a9HR1j7t.js → hi-x5-IG1rl.js} +1 -1
  9. package/backtoschool/dist/assets/hls-CydbS6hn.js +42 -0
  10. package/backtoschool/dist/assets/hls-OR5FY6YP-O3qhTXm4.js +1 -0
  11. package/backtoschool/dist/assets/{hu-CXw_ATKN.js → hu-QqIkGcMe.js} +1 -1
  12. package/backtoschool/dist/assets/{id-B8GHWT99.js → id-OVwO1Uoi.js} +1 -1
  13. package/backtoschool/dist/assets/index-Dgqs6yM_.js +112 -0
  14. package/backtoschool/dist/assets/{it-D8K-Cjn9.js → it-CmssY5Ut.js} +1 -1
  15. package/backtoschool/dist/assets/mpegts-RQlLEU1A.js +3 -0
  16. package/backtoschool/dist/assets/mpegts-Y2FARLFE-y49QH7a5.js +1 -0
  17. package/backtoschool/dist/assets/{nl-BTHM_tIM.js → nl-VkQxlPku.js} +1 -1
  18. package/backtoschool/dist/assets/{ru-cwqVc7z_.js → ru-Dk8FAbDx.js} +1 -1
  19. package/backtoschool/dist/assets/{sv-De7KSFg-.js → sv-CNs1UySx.js} +1 -1
  20. package/backtoschool/dist/assets/{uk-COyId2km.js → uk-BDB1YayY.js} +1 -1
  21. package/backtoschool/dist/assets/{vi-3djg7AGj.js → vi-DnEIKzy7.js} +1 -1
  22. package/backtoschool/dist/assets/{zh-DNAab67I.js → zh-B_atHA4S.js} +1 -1
  23. package/backtoschool/dist/index.html +1 -1
  24. package/dist/ai-label.js +368 -0
  25. package/dist/partyline.d.ts +41 -201
  26. package/dist/partyline.js +65 -601
  27. package/package.json +13 -12
  28. package/src/ai-label.ts +368 -0
  29. package/src/partyline.ts +88 -671
  30. package/web/dist/assets/{ar-D11SvZiO.js → ar-D7oGrIBc.js} +1 -1
  31. package/web/dist/assets/background.worker-F49brs4A.js +547 -0
  32. package/web/dist/assets/chunk-55GBNX64-BDcCEJUP.js +1 -0
  33. package/web/dist/assets/client-D7waX8NA.js +1 -0
  34. package/web/dist/assets/{cs-C9A8mi2r.js → cs-Do_NVHzs.js} +1 -1
  35. package/web/dist/assets/{da-CIp_Ajuh.js → da-BIzsUdfm.js} +1 -1
  36. package/web/dist/assets/{de-5HI3ODDg.js → de-BIvKiWjR.js} +1 -1
  37. package/web/dist/assets/{es-B7jsPXIF.js → es-DlwX4mPV.js} +1 -1
  38. package/web/dist/assets/{fi-CDifgjAY.js → fi-DSxAbrPX.js} +1 -1
  39. package/web/dist/assets/{fr-CWCMwXQf.js → fr-DlPaqVof.js} +1 -1
  40. package/web/dist/assets/{hi-D9A8GEcr.js → hi-CGj6w2rC.js} +1 -1
  41. package/web/dist/assets/hls-CydbS6hn.js +42 -0
  42. package/web/dist/assets/hls-OR5FY6YP-_WOdANsC.js +1 -0
  43. package/web/dist/assets/{hu-BQnB41QA.js → hu-C3hnXVMS.js} +1 -1
  44. package/web/dist/assets/{id-BiRd7S38.js → id-CXTixL8r.js} +1 -1
  45. package/web/dist/assets/{it-Qyw9ho6m.js → it-kiPCXGt4.js} +1 -1
  46. package/web/dist/assets/main-DFt__4mL.js +26 -0
  47. package/web/dist/assets/mpegts-CL9RC5Ls.js +3 -0
  48. package/web/dist/assets/mpegts-Y2FARLFE-C91SD8Pl.js +1 -0
  49. package/web/dist/assets/music-ByEeUk4Z.js +1 -0
  50. package/web/dist/assets/{nl-BO3ykanC.js → nl-BMVfOLOI.js} +1 -1
  51. package/web/dist/assets/radio-BnQ78a-O.js +1 -0
  52. package/web/dist/assets/{ru-EoEoXLPn.js → ru-BbFlZrrY.js} +1 -1
  53. package/web/dist/assets/{station-UibBpdBh.js → station-C_6L4CDU.js} +2 -2
  54. package/web/dist/assets/{sv-BzFjGhqA.js → sv-DSYI0dH8.js} +1 -1
  55. package/web/dist/assets/{uk-DMWjHo-5.js → uk-CgzzaOY_.js} +1 -1
  56. package/web/dist/assets/{vi-DlSMYqgm.js → vi-CLwyMANh.js} +1 -1
  57. package/web/dist/assets/{vod-CkR6hzN7.js → vod-CbSC5NFA.js} +1 -1
  58. package/web/dist/assets/{watch-BO-wMY8T.js → watch-D-ZRxfJ_.js} +1 -1
  59. package/web/dist/assets/{zh-cB0Zpdge.js → zh-8uXFdsMm.js} +1 -1
  60. package/web/dist/index.html +5 -5
  61. package/web/dist/music.html +2 -2
  62. package/web/dist/radio.html +3 -3
  63. package/web/dist/station.html +3 -3
  64. package/web/dist/sw.js +32 -32
  65. package/web/dist/vod.html +3 -3
  66. package/web/dist/watch.html +3 -3
  67. package/backtoschool/dist/assets/hls-OR5FY6YP-nOjNFW0f.js +0 -1
  68. package/backtoschool/dist/assets/hls-n74Cnh8A.js +0 -42
  69. package/backtoschool/dist/assets/index-BPJoeY65.js +0 -112
  70. package/backtoschool/dist/assets/mpegts-7CN75AI2-cUtR703j.js +0 -1
  71. package/backtoschool/dist/assets/mpegts-CixmcUbS.js +0 -3
  72. package/web/dist/assets/background.worker-Hz7oaQ8X.js +0 -547
  73. package/web/dist/assets/chunk-Q2XQMA4B-OBCD3Aev.js +0 -1
  74. package/web/dist/assets/client-B_mfdrFh.js +0 -1
  75. package/web/dist/assets/hls-OR5FY6YP-B2RNEz5K.js +0 -1
  76. package/web/dist/assets/hls-n74Cnh8A.js +0 -42
  77. package/web/dist/assets/main-D4Tyu9aM.js +0 -26
  78. package/web/dist/assets/mpegts-7CN75AI2-1Qj6py7N.js +0 -1
  79. package/web/dist/assets/mpegts-BcF3gJrf.js +0 -3
  80. package/web/dist/assets/music-Day-DtFd.js +0 -1
  81. package/web/dist/assets/radio-Dx44o-ug.js +0 -1
  82. /package/web/dist/assets/{chunk-Q2XQMA4B-DR1XNWCJ.css → chunk-55GBNX64-DR1XNWCJ.css} +0 -0
@@ -1 +0,0 @@
1
- import"./modulepreload-polyfill-P2Xu9kJm.js";import{a as e,i as t,r as n}from"./client-B_mfdrFh.js";import{i as r,n as i,r as a,t as o}from"./now-playing-DVQqWQIu.js";var s=e=>document.querySelector(e);function c(e,t={},...n){let r=document.createElement(e);for(let[e,n]of Object.entries(t))n!==!1&&(e===`class`?r.className=String(n):r.setAttribute(e,n===!0?``:n));for(let e of n)e!=null&&e!==!1&&r.append(typeof e==`string`?document.createTextNode(e):e);return r}function l(e){s(`#sr-status`).textContent=e}var u=e=>e.normalize(`NFKD`).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``),d=e=>`${Math.floor(e/60)}:${String(Math.round(e%60)).padStart(2,`0`)}`,f=(e,t)=>`/api/v1/music/file/${e}/${t}`,p=(e,t)=>t.cover?f(e.server,`${e.key}/${t.key}/cover.jpg`):``,m=(e,t)=>f(e.server,`${e.key}/members/${t.slug}.jpg`),h=e=>`/music/artist/${e.server}/${e.key}`,g=(e,t)=>`/music/album/${e.server}/${e.key}/${t.key}`,_=(e,t)=>`/music/member/${e.server}/${e.key}/${t.slug}`,v=(e,t,n=``,r=0)=>`/buy?${new URLSearchParams({server:e.server,kind:t,artist:e.key,...t===`artist`?{}:{album:n},...t===`song`?{n:String(r)}:{}})}`,y=(e,t,n,r=0)=>`/license?${new URLSearchParams({server:e.server,kind:t,artist:e.key,album:n,...t===`song`?{n:String(r)}:{}})}`;function b(e){let t=[...e.albums].find(e=>e.cover);if(t)return p(e,t);let n=e.members?.[0];return n?m(e,n):``}function x(e,t,n){let r=c(`video`,{controls:!0,preload:`none`,playsinline:!0,src:f(e.server,`${e.key}/${t.key}/${n.n}.mp4`),"aria-label":`${n.title} by ${e.name}, music video`,width:`640`,height:`360`}),i=p(e,t);return i&&(r.poster=i),r.addEventListener(`play`,()=>{for(let e of document.querySelectorAll(`video`))e!==r&&e.pause();M&&!R().paused&&s(`#player-toggle`).click()}),r}function S(e,t=``){return e?c(`img`,{src:e,alt:t,loading:`lazy`,decoding:`async`,width:`200`,height:`200`}):c(`div`,{class:`blank`,"aria-hidden":`true`})}var C=null;function w(){return C??=fetch(`/api/v1/music`).then(e=>{if(!e.ok)throw Error(`HTTP ${e.status}`);return e.json()}).catch(e=>{throw C=null,e}),C}var T=e=>e.genres.flatMap(e=>e.artists),ee=(e,t)=>e.genres.find(e=>e.genre===t)?.stations[0];function E(e){let t=c(`button`,{type:`button`,class:`card`},c(`span`,{class:`live`},e.state===`live`?`● LIVE`:`OFF THE AIR`),c(`strong`,{},e.name.replace(/^Profullstack AI · /,``)),c(`small`,{},e.nowPlaying?[e.nowPlaying.title,e.nowPlaying.artist].filter(Boolean).join(` · `):`Free, with a short break every 10 minutes`));return t.addEventListener(`click`,()=>K(e)),t}function D(e){return c(`a`,{class:`card`,href:h(e)},S(b(e)),c(`strong`,{},e.name),c(`small`,{},e.genre))}function te(e){let t=[c(`h1`,{},`AI music, live and on demand`),c(`p`,{class:`lead`},`Original bands and artists, written and sung by AI and released by ${e.holders.join(`, `)||`Profullstack, Inc.`}. Listen free on the live stations; follow the artists; buy the songs you love.`)];e.stations.length&&t.push(c(`h2`,{},`Live now`),c(`div`,{class:`row`},...e.stations.map(E)));for(let n of e.genres)n.artists.length&&t.push(c(`h2`,{},c(`a`,{href:`/music/genre/${u(n.genre)}`},n.genre)),c(`div`,{class:`row`},...n.artists.map(D)));return e.genres.length?t.push(c(`p`,{class:`lead`},`Making a game, an app or a video? `,c(`a`,{href:`/license?kind=catalog`},`License the whole catalogue for $29 a year`),`, or any song from $5. `,c(`a`,{href:`/license/terms`},`The terms`),`.`)):t.push(c(`p`,{class:`empty`},`The first albums are being recorded. Check back soon.`)),t}function ne(e,t){let n=e.genres.find(e=>u(e.genre)===t);return n?(document.title=`${n.genre} · nixamp music`,[c(`p`,{class:`crumbs`},c(`a`,{href:`/music`},`Music`),` / `,n.genre),c(`h1`,{},n.genre),...n.stations.length?[c(`h2`,{},`Live`),c(`div`,{class:`row`},...n.stations.map(E))]:[],c(`h2`,{},`Artists`),c(`div`,{class:`grid`},...n.artists.map(D))]):j()}function O(){let r=c(`p`,{class:`muted`,role:`status`}),i=c(`input`,{type:`checkbox`}),a=c(`input`,{type:`checkbox`}),o=c(`input`,{type:`checkbox`}),s=c(`input`,{type:`tel`,autocomplete:`tel`,placeholder:`+1 555 123 4567`,"aria-label":`Phone number for texts`}),l=c(`button`,{type:`button`,class:`btn ghost`},`Save number`),u=c(`fieldset`,{class:`alerts`},c(`legend`,{},`Tell me when they release something`),c(`label`,{},i,` Browser notification on this device`),c(`label`,{},a,` Email`),c(`label`,{},o,` Text message`),c(`div`,{class:`phone`},s,l),r),d=async e=>{let t=await fetch(`/api/v1/notify/prefs`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify(e)}).catch(()=>null);return t?.ok?(r.textContent=`Saved.`,!0):(r.textContent=t?.status===422?`That does not look like a phone number.`:`Could not save that.`,!1)};return fetch(`/api/v1/notify/prefs`).then(e=>e.ok?e.json():null).then(e=>{if(!e){u.hidden=!0;return}a.checked=e.wantsEmail,o.checked=e.wantsSms,s.value=e.phone,i.checked=e.wantsWeb&&`Notification`in window&&Notification.permission===`granted`}).catch(()=>{u.hidden=!0}),i.addEventListener(`change`,()=>void(async()=>{if(i.checked){let e=n();if(!e.supported){r.textContent=e.message,i.checked=!1;return}try{await t({vapidKeyUrl:`/api/v1/notify/key`,serviceWorkerUrl:`/sw.js`,saveUrl:`/api/v1/notify/subscribe`}),await d({wantsWeb:!0})}catch(e){i.checked=!1;let t=e instanceof Error?e.message:``;r.textContent=/push service/i.test(t)?`This browser has no push service of its own. In TronBrowser, turn this on from a normal window (not a private or app window), on TronBrowser 3.16 or newer (tron upgrade). Email and text work anywhere.`:t||`Could not set this device up.`}}else await e({removeUrl:`/api/v1/notify/subscribe`}).catch(()=>void 0),r.textContent=`This device will not be told.`})()),a.addEventListener(`change`,()=>void d({wantsEmail:a.checked})),o.addEventListener(`change`,()=>{if(o.checked&&!s.value.trim()){r.textContent=`Add your number, then Save number.`,o.checked=!1;return}d({wantsSms:o.checked})}),l.addEventListener(`click`,()=>void d({phone:s.value.trim(),...s.value.trim()?{wantsSms:!0}:{wantsSms:!1}}).then(e=>{e&&(o.checked=!!s.value.trim())})),u}function k(e){let t=c(`button`,{type:`button`,class:`btn ghost`,"aria-pressed":`false`},`Follow`),n=encodeURIComponent(e.follow);return fetch(`/api/v1/follows/${n}`).then(async e=>{if(e.status===401){t.dataset.out=`1`;return}e.ok&&(await e.json()).following&&(t.setAttribute(`aria-pressed`,`true`),t.textContent=`Following`)}).catch(()=>void 0),t.addEventListener(`click`,()=>{if(t.dataset.out){location.assign(`/?redirect=${encodeURIComponent(location.pathname)}#account-panel`);return}let r=t.getAttribute(`aria-pressed`)!==`true`;t.disabled=!0,fetch(`/api/v1/follows/${n}`,{method:r?`PUT`:`DELETE`}).then(n=>{if(n.status===401){location.assign(`/?redirect=${encodeURIComponent(location.pathname)}#account-panel`);return}if(!n.ok)return;t.setAttribute(`aria-pressed`,String(r)),t.textContent=r?`Following`:`Follow`;let i=t.closest(`.actions`);r&&i&&!i.parentElement?.querySelector(`.alerts`)&&i.after(O()),l(r?`Following ${e.name}. You will hear when they release something.`:`No longer following ${e.name}.`)}).finally(()=>{t.disabled=!1})}),t}function A(e,t){let n=ee(e,t.genre);if(!n)return null;let r=c(`button`,{type:`button`,class:`btn`},`▶ Listen live: ${t.genre}`);return r.addEventListener(`click`,()=>K(n)),r}function re(e,t,n){let r=T(e).find(e=>e.server===t&&e.key===n);if(!r)return j();document.title=`${r.name} · nixamp music`;let i=[...r.albums].sort((e,t)=>t.year-e.year);return[c(`p`,{class:`crumbs`},c(`a`,{href:`/music`},`Music`),` / `,c(`a`,{href:`/music/genre/${u(r.genre)}`},r.genre)),c(`div`,{class:`hero`},S(b(r),``),c(`div`,{},c(`div`,{class:`kind`},r.members&&r.members.length>1?`Band`:`Artist`),c(`h1`,{},r.name),r.bio?c(`p`,{class:`lead`},r.bio):null,c(`div`,{class:`actions`},A(e,r),k(r),c(`a`,{class:`btn ghost`,href:v(r,`artist`)},`Download everything · $2`)))),...r.members?.length?[c(`h2`,{},r.members.length>1?`The band`:`Who`),c(`ul`,{class:`members`},...r.members.map(e=>c(`li`,{},c(`a`,{href:_(r,e)},c(`img`,{src:m(r,e),alt:``,width:`64`,height:`64`,loading:`lazy`})),c(`div`,{},c(`a`,{href:_(r,e)},c(`strong`,{},e.name)),c(`span`,{},e.role)))))]:[],...(()=>{let e=i.flatMap(e=>e.songs.filter(e=>e.video).map(t=>({album:e,song:t}))).slice(0,6);return e.length?[c(`h2`,{},`Videos`),c(`div`,{class:`videos`},...e.map(({album:e,song:t})=>c(`figure`,{},x(r,e,t),c(`figcaption`,{},c(`strong`,{},t.title),` · `,c(`a`,{href:g(r,e)},e.title)))))]:[]})(),c(`h2`,{},`Discography`),i.length?c(`div`,{class:`grid`},...i.map(e=>c(`a`,{class:`card`,href:g(r,e)},S(p(r,e)),c(`strong`,{},e.title),c(`small`,{},`${e.year} · ${e.songs.length} songs${e.complete?``:` · recording`}`)))):c(`p`,{class:`empty`},`The first album is being recorded.`)]}function ie(e,t,n,r){let i=T(e).find(e=>e.server===t&&e.key===n),a=i?.albums.find(e=>e.key===r);if(!i||!a)return j();document.title=`${a.title} by ${i.name} · nixamp music`;let o=a.songs.reduce((e,t)=>e+t.seconds,0);return[c(`p`,{class:`crumbs`},c(`a`,{href:`/music`},`Music`),` / `,c(`a`,{href:h(i)},i.name)),c(`div`,{class:`hero`},S(p(i,a),`Cover of ${a.title}`),c(`div`,{},c(`div`,{class:`kind`},`Album`),c(`h1`,{},a.title),c(`p`,{class:`lead`},c(`a`,{href:h(i)},i.name),` · ${a.year} · ${a.songs.length} songs, ${d(o)}${a.complete?``:` · still recording`}`),a.concept?c(`p`,{class:`lead`},a.concept):null,c(`div`,{class:`actions`},A(e,i),c(`a`,{class:`btn ghost`,href:v(i,`album`,a.key)},`Download the album · $1`),c(`a`,{class:`btn ghost`,href:y(i,`album`,a.key),title:`Use this album in your game, app or video`},`License for your project · $100`)))),c(`ol`,{class:`tracks`},...a.songs.map(e=>c(`li`,{},c(`div`,{class:`track`},c(`span`,{class:`n`},String(e.n)),c(`span`,{},e.title),c(`span`,{class:`t`},d(e.seconds)),c(`a`,{class:`buy`,href:v(i,`song`,a.key,e.n),title:`Download the MP3`},`10¢`),c(`a`,{class:`buy`,href:y(i,`song`,a.key,e.n),title:`License this song for your game, app or video, from $5`},`License`)),e.video?c(`details`,{class:`words`},c(`summary`,{},`Watch the video`),x(i,a,e)):null,e.lyrics?c(`details`,{class:`words`},c(`summary`,{},`Lyrics`),c(`pre`,{},e.lyrics)):null))),c(`p`,{class:`muted`},`Every song plays free on the live station. A download is the MP3s with the cover art and lyrics, yours to keep and listen to. To use a song in your own game, app or video, `,c(`a`,{href:y(i,`album`,a.key)},`license it`),` (from $5 a song), or get the `,c(`a`,{href:`/license?kind=catalog`},`Catalog pass`),` for every artist, $29 a year.`)]}async function ae(){document.title=`My music · nixamp`;let e=[c(`h1`,{},`My music`)],t=await fetch(`/api/v1/store/purchases`);if(t.status===401)return e.push(c(`p`,{class:`lead`},`Sign in to see what you bought and who you follow.`),c(`div`,{class:`actions`},c(`a`,{class:`btn`,href:`/?redirect=%2Fmusic%2Fme#account-panel`},`Sign in with nixamp`),c(`a`,{class:`btn ghost`,href:`/api/v1/coinpay/oauth/start?redirect=%2Fmusic%2Fme`},`Sign in with CoinPay`))),e;let n=await t.json().catch(()=>({}));e.push(c(`h2`,{},`Bought`)),e.push(n.purchases?.length?c(`div`,{class:`list`},...n.purchases.map(e=>c(`div`,{class:`item`},c(`div`,{class:`grow`},c(`strong`,{},e.title),c(`div`,{class:`muted`},`${e.artistName} · ${e.kind} · ${new Date(e.paidAt).toLocaleDateString()}`)),e.zip?c(`a`,{class:`btn`,href:e.zip},`Download`):null,e.link?c(`a`,{class:`btn ghost`,href:e.link},`Receipt`):null))):c(`p`,{class:`empty`},`Nothing yet: every album page has a Download button.`));let r=await fetch(`/api/v1/follows`).then(e=>e.ok?e.json():{}).catch(()=>({})),i=await w().catch(()=>null),a=(r.following??[]).map(e=>typeof e==`string`?e:e.id).filter(e=>e.startsWith(`artist:`));e.push(c(`h2`,{},`Following`));let o=i?T(i).filter(e=>a.includes(e.follow)):[];return e.push(o.length?c(`div`,{class:`grid`},...o.map(D)):c(`p`,{class:`empty`},`Follow an artist to hear when they release something.`)),e.push(O()),e}async function oe(e,t,n,r){let i=T(e).find(e=>e.server===t&&e.key===n),a=i?.members?.find(e=>e.slug===r);if(!i||!a)return j();let o=`/api/v1/music/member/${t}/${n}/${r}.json`,s=await fetch(o).catch(()=>null),l=s?.ok?await s.json():null,u=l?.role||a.role||`member`;document.title=`${a.name} · ${u} in ${i.name} · nixamp music`;let d=(e,t)=>t&&!/^(none|n\/a|-+)\.?$/i.test(t.trim())?[c(`dt`,{},e),c(`dd`,{},t)]:[],p=l?[...d(`Look`,l.look),...d(i.members.length>1&&/vocal|sing/i.test(u)?`Voice`:`Sound`,l.voice),...d(`Personality`,l.personality),...d(`Influences`,l.influences)]:[],g=i.members.filter(e=>e.slug!==r);return[c(`p`,{class:`crumbs`},c(`a`,{href:`/music`},`Music`),` / `,c(`a`,{href:h(i)},i.name)),c(`div`,{class:`hero`},S(m(i,a),`${a.name}`),c(`div`,{},c(`div`,{class:`kind`},`${u.charAt(0).toUpperCase()}${u.slice(1)} · `,c(`a`,{href:h(i)},i.name)),c(`h1`,{},a.name),l?.bio||a.bio?c(`p`,{class:`lead`},l?.bio||a.bio):null,c(`div`,{class:`actions`},A(e,i),k(i),c(`a`,{class:`btn ghost`,href:o,title:`This profile as OpenProfile JSON, for apps and agents`},`JSON`),c(`a`,{class:`btn ghost`,href:f(t,`${n}/members/${r}.md`),title:`The OpenProfile page this is read from`},`OpenProfile source`)))),...p.length?[c(`h2`,{},`About`),c(`dl`,{class:`facts`},...p)]:[],...g.length?[c(`h2`,{},`Also in ${i.name}`),c(`ul`,{class:`members`},...g.map(e=>c(`li`,{},c(`a`,{href:_(i,e)},c(`img`,{src:m(i,e),alt:``,width:`64`,height:`64`,loading:`lazy`})),c(`div`,{},c(`a`,{href:_(i,e)},c(`strong`,{},e.name)),c(`span`,{},e.role)))))]:[],c(`p`,{class:`muted`},`A fictional musician, made with AI. `,l?``:`Their full profile did not load; try again in a moment.`)]}function j(){return[c(`h1`,{},`Not here`),c(`p`,{class:`lead`},`That page is not in the catalogue (yet).`),c(`a`,{href:`/music`},`Back to the music`)]}var M=null,N=``,P=null,F=0,I=``,L=null,R=()=>s(`#audio`),z=e=>`t=${encodeURIComponent(e.token)}`,B=!1,V=0,H=0,U=0;function W(){B&&M&&(V+=1,clearTimeout(H),H=window.setTimeout(()=>{B&&G()},Math.min(15e3,1e3*2**Math.min(V,4))))}function G(){if(!M)return;B=!0,U=Date.now(),N=Date.now().toString(36)+Math.random().toString(36).slice(2,8),P=null;let e=R();e.src=`${M.listen}/stream?${z(M)}&n=${N}`,e.play().catch(()=>void 0),r(`playing`),s(`#player-toggle`).textContent=`❚❚`,s(`#player-toggle`).setAttribute(`aria-label`,`Pause`)}function K(e){M=e,I=``,L=null,G(),s(`#player`).hidden=!1,s(`#player-title`).textContent=e.nowPlaying?.title||e.name,s(`#player-by`).textContent=e.nowPlaying?.artist||e.name,i({title:e.nowPlaying?.title||e.name,artist:e.nowPlaying?.artist||``,album:e.name}),l(`Playing ${e.name}`),Y()}async function q(){let e=R(),t=M,n=N;if(!t||!n||e.paused||e.readyState<2)return;F=Date.now();let r=e.currentTime;try{let e=await fetch(`${t.listen}/clock?${z(t)}&n=${encodeURIComponent(n)}&ct=${r.toFixed(3)}`,{cache:`no-store`});if(n!==N)return;if(!e.ok){P=null;return}let i=await e.json();P={nonce:n,ct:r,position:i.position,duration:i.duration,break:i.break,title:i.nowPlaying?.title??``},P.title&&P.title!==I&&Y()}catch{}}var J=e=>{let t=Math.max(0,Math.floor(e));return`${Math.floor(t/60)}:${String(t%60).padStart(2,`0`)}`};function se(){let e=R(),t=P&&P.nonce===N&&!e.paused?P:null,n=s(`#player-progress`);if(!t){n.hidden=!0,s(`#player-break`).hidden=!0,a(0,0);return}let r=t.position+(e.currentTime-t.ct);if(t.duration>0&&r>t.duration&&Date.now()-F>1e3&&q(),s(`#player-break`).hidden=!t.break,t.break||t.duration<=0){n.hidden=!0,a(0,0);return}let i=Math.min(t.duration,Math.max(0,r));a(t.duration,i);let o=s(`#player-bar`);o.max=t.duration,o.value=i,o.setAttribute(`aria-valuetext`,`${J(i)} of ${J(t.duration)}`),s(`#player-at`).textContent=J(i),s(`#player-length`).textContent=J(t.duration),n.hidden=!1,L&&(!L.title||!t.title||L.title.trim().toLowerCase()===t.title.trim().toLowerCase())&&ce(r)}function ce(e){if(!L)return;let{lines:t,els:n,words:r}=L,i=-1;for(let n=0;n<t.length;n++)t[n].start<=e+.1&&(i=n);if(i>=0&&i<L.at&&e>t[L.at].start-1&&(i=L.at),i!==L.at){n.forEach((e,t)=>{e.classList.toggle(`now`,t===i),e.classList.toggle(`past`,t<i)}),L.at=i;let e=s(`#lyrics-panel`);if(i>=0&&!e.hidden&&s(`#lyrics-follow`).checked){let t=n[i],r=t.offsetTop-e.scrollTop;(r<e.clientHeight*.2||r+t.clientHeight>e.clientHeight*.6)&&e.scrollTo({top:Math.max(0,t.offsetTop-e.clientHeight/3),behavior:`smooth`})}}i>=0&&r[i].forEach((n,r)=>n.classList.toggle(`sung`,t[i].words[r].start<=e))}async function Y(){let e=M;if(!e)return;let t=new URL(e.listen).origin,n=(await fetch(`${e.listen}/now?${z(e)}`,{cache:`no-store`}).then(e=>e.json()).catch(()=>null))?.facts;if(!n||e!==M)return;I=P?.title||n.title||``,s(`#player-title`).textContent=n.title||e.name,s(`#player-by`).textContent=[n.artist,n.album].filter(Boolean).join(` · `);let r=s(`#player-art`);n.art&&r.dataset.src!==n.art&&(r.dataset.src=n.art,r.src=t+n.art),i({title:n.title||e.name,artist:n.artist||``,album:n.album||e.name,art:n.art?t+n.art:``});let a=s(`#lyrics-panel`);n.lyrics&&a.dataset.src!==n.lyrics?(a.dataset.src=n.lyrics,X((await fetch(t+n.lyrics).then(e=>e.json()).catch(()=>null))?.lyrics??null)):n.lyrics||(delete a.dataset.src,X(null))}function X(e){s(`#lyrics-title`).textContent=e?.title?`Lyrics · ${e.title}`:`Lyrics`;let t=s(`#lyrics-text`);if(e?.synced?.length){let n=[],r=[];for(let t of e.synced){let e=t.words.map((e,t)=>c(`span`,{class:`word`},(t?` `:``)+e.text));n.push(e.length?c(`p`,{class:`line`},...e):c(`p`,{class:`line`},t.text)),r.push(e)}t.replaceChildren(...n),t.classList.add(`synced`),L={lines:e.synced,els:n,words:r,at:-1,title:e.title},s(`#lyrics-follow-box`).hidden=!1;return}L=null,t.classList.remove(`synced`),s(`#lyrics-follow-box`).hidden=!0,t.replaceChildren(...(e?.text??`No lyrics for this one.`).split(/\n{2,}/).map(e=>/^\[[^\]]+\]$/.test(e.trim())?c(`p`,{class:`section`},e.trim().slice(1,-1)):c(`p`,{},e.replace(/^\[[^\]]+\]\n/,``))))}var Z=(e,t)=>{try{localStorage.setItem(`nixamp.music.${e}`,t)}catch{}},Q=e=>{try{return localStorage.getItem(`nixamp.music.${e}`)}catch{return null}};function le(){let e=R(),t=()=>{B=!1,clearTimeout(H),e.pause(),e.removeAttribute(`src`),e.load(),P=null,r(`paused`),s(`#player-toggle`).textContent=`▶`,s(`#player-toggle`).setAttribute(`aria-label`,`Play`)};s(`#player-toggle`).addEventListener(`click`,()=>{M&&(e.paused?G():t())}),o({play:()=>{M&&e.paused&&G()},pause:()=>{M&&!e.paused&&t()},stop:()=>{M&&!e.paused&&t()},seekto:null,seekbackward:null,seekforward:null});let n=s(`#player-volume`),i=s(`#player-mute`),a=()=>{i.textContent=e.muted||e.volume===0?`🔇`:e.volume<.5?`🔉`:`🔊`,i.setAttribute(`aria-pressed`,String(e.muted)),i.setAttribute(`aria-label`,e.muted?`Unmute`:`Mute`)},c=Number(Q(`volume`)??`1`);e.volume=Number.isFinite(c)?Math.min(1,Math.max(0,c)):1,n.value=String(e.volume),e.muted=Q(`muted`)===`1`,a(),n.addEventListener(`input`,()=>{e.volume=Number(n.value),e.volume>0&&e.muted&&(e.muted=!1),Z(`volume`,n.value),Z(`muted`,e.muted?`1`:`0`),a()}),i.addEventListener(`click`,()=>{e.muted=!e.muted,Z(`muted`,e.muted?`1`:`0`),a()}),s(`#player-lyrics`).addEventListener(`click`,()=>{let e=s(`#lyrics-panel`);e.hidden=!e.hidden,s(`#player-lyrics`).setAttribute(`aria-expanded`,String(!e.hidden)),L&&(L.at=-1)});let u=s(`#lyrics-follow`);u.checked=Q(`follow`)!==`0`,u.addEventListener(`change`,()=>Z(`follow`,u.checked?`1`:`0`));for(let e of[`wheel`,`touchmove`])s(`#lyrics-panel`).addEventListener(e,()=>{u.checked&&(u.checked=!1,Z(`follow`,`0`))},{passive:!0});e.addEventListener(`playing`,()=>{V&&l(`Back on`),V=0,q()}),e.addEventListener(`error`,()=>{e.getAttribute(`src`)&&W()}),e.addEventListener(`ended`,()=>W()),e.addEventListener(`stalled`,()=>{!e.paused&&e.readyState<3&&Date.now()-U>12e3&&W()}),setInterval(()=>void q(),2e3),setInterval(se,100),setInterval(()=>{M&&!e.paused&&!P&&Y()},15e3)}async function $(){let e=s(`#view`),t=location.pathname.replace(/\/+$/,``).split(`/`).slice(2);for(let e of document.querySelectorAll(`[data-nav]`))e.dataset.nav===`me`&&t[0]===`me`||e.dataset.nav===`home`&&t[0]!==`me`?e.setAttribute(`aria-current`,`page`):e.removeAttribute(`aria-current`);document.title=`Music · nixamp`;let n;try{if(t[0]===`me`)n=await ae();else{let e=await w();n=t[0]===`genre`&&t[1]?ne(e,t[1]):t[0]===`artist`&&t[2]?re(e,t[1],t[2]):t[0]===`album`&&t[3]?ie(e,t[1],t[2],t[3]):t[0]===`member`&&t[3]?await oe(e,t[1],t[2],t[3]):t.length===0?te(e):j()}}catch{n=[c(`h1`,{},`The music did not load`),c(`p`,{class:`notice`},`Try again in a moment.`)]}e.replaceChildren(...n)}function ue(){document.addEventListener(`click`,e=>{let t=e.target.closest(`a`);if(!t||e.defaultPrevented||e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||t.target)return;let n=new URL(t.href,location.href);n.origin===location.origin&&/^\/music(\/|$)/.test(n.pathname)&&(e.preventDefault(),n.pathname+n.search!==location.pathname+location.search&&(history.pushState(null,``,n.pathname+n.search),$().then(()=>{window.scrollTo(0,0),s(`#view`).focus({preventScroll:!0})})))}),window.addEventListener(`popstate`,()=>void $())}async function de(){let e=(await fetch(`/api/v1/auth/me`).then(e=>e.ok?e.json():null).catch(()=>null))?.account?.email??``;s(`#who`).replaceChildren(...e&&!e.endsWith(`.invalid`)?[e]:e?[`Signed in`]:[c(`a`,{href:`/?redirect=${encodeURIComponent(location.pathname)}#account-panel`},`Sign in`)])}ue(),le(),de(),$(),`serviceWorker`in navigator&&globalThis.addEventListener(`load`,()=>{navigator.serviceWorker.register(`/sw.js`).catch(()=>{})});
@@ -1 +0,0 @@
1
- import"./modulepreload-polyfill-P2Xu9kJm.js";import{n as e}from"./chunk-Q2XQMA4B-OBCD3Aev.js";import{l as t}from"./remote-DJqvFdE6.js";var n=e=>document.querySelector(e);function r(e,t={},...n){let r=document.createElement(e);for(let[e,n]of Object.entries(t))n!==!1&&(e===`class`?r.className=String(n):r.setAttribute(e,n===!0?``:n));for(let e of n)e!=null&&e!==!1&&r.append(typeof e==`string`?document.createTextNode(e):e);return r}function i(e){n(`#sr-status`).textContent=e}var a;function o(e,t=`error`){let i=n(`#notice`);if(clearTimeout(a),i.classList.toggle(`ok`,t===`ok`),i.setAttribute(`role`,t===`ok`?`status`:`alert`),i.replaceChildren(),e!==``){let t=r(`button`,{type:`button`,class:`ghost notice-close`,"aria-label":`Dismiss`},`×`);t.addEventListener(`click`,()=>o(``)),i.append(r(`span`,{},e),t)}i.hidden=e===``,t===`ok`&&e&&(a=setTimeout(()=>o(``),6e3))}var s=class extends Error{status;code;constructor(e,t,n){super(n),this.status=e,this.code=t}},c={id:`here`,name:location.host,base:``,session:``,key:``},l=0;function u(e,t=!1){if(!c.base)return e;let n=new URL(c.base+e);return c.session?t&&n.searchParams.set(`session`,c.session):c.key&&n.searchParams.set(`k`,c.key),n.href}async function d(e,t,n){let r=c.base!==``,i=await fetch(u(t),{method:e,credentials:r?`omit`:`same-origin`,headers:{...n===void 0?{}:{"content-type":`application/json`},...r&&c.session?{authorization:`Bearer ${c.session}`}:{}},...n===void 0?{}:{body:JSON.stringify(n)}}),a=await i.json().catch(()=>({}));if(!i.ok)throw new s(i.status,String(a.code??i.status),String(a.error??`HTTP ${i.status}`));return a}async function f(e,t,n){if(!n?.disabled){n&&(n.disabled=!0);try{await t()}catch(t){o(`${e} failed: ${t instanceof Error?t.message:String(t)}`)}finally{n&&(n.disabled=!1)}}}function p(e){return e?`${Math.floor(e/60)}:${String(Math.floor(e%60)).padStart(2,`0`)}`:``}var m={live:`Live`,starting:`Starting`,recovering:`Coming back`,offline:`Offline`,stopped:`Off the air`},h=[],g=null;async function _(){let e=l,t=await d(`GET`,`/api/v1/stations?limit=200`);e===l&&(h=t.stations,w())}var ee=`https://backtoschool.help`,v=!1,y=new Map;function b(e){try{let t=new URL(e);return`${t.origin}${t.pathname.replace(/\/+$/,``)}?t=${t.searchParams.get(`t`)??``}`}catch{return e}}async function x(){if(!v)return;let e=await fetch(`/api/v1/events?mine=true&kind=class&status=live&limit=100`,{credentials:`same-origin`});if(!e.ok)return;let t=await e.json().catch(()=>({}));y=new Map((t.events??[]).filter(e=>e.broadcastUrl).map(e=>[b(e.broadcastUrl),e]))}async function S(e,t){let n=await fetch(e,{method:`POST`,credentials:`same-origin`,headers:{"content-type":`application/json`},body:JSON.stringify(t)}),r=await n.json().catch(()=>({}));if(!n.ok)throw Error(String(r.error??`HTTP ${n.status}`));return r}async function C(e){e.desired!==`running`&&await d(`POST`,`/api/v1/stations/${e.id}/start`,{})}async function te(e,t){if(t&&!e.rights){T(e,{visibility:`public`,listed:!0});return}await d(`POST`,`/api/v1/stations/${e.id}/access`,t?{visibility:`public`,listed:!0}:{visibility:e.visibility,listed:!1}),t&&await C(e),i(t?`${e.name} is on live.streaming`:`${e.name} is off live.streaming`),await _()}async function ne(e,t){let n=y.get(b(e.links.page));if(!t){n&&await S(`/api/v1/events/${encodeURIComponent(n.id)}/end`,{version:n.version}),i(`${e.name} is off backtoschool.help`),await x(),w();return}let r=e;e.visibility===`private`&&(r=(await d(`POST`,`/api/v1/stations/${e.id}/access`,{visibility:`unlisted`})).station),await C(r);let a=(await S(`/api/v1/events`,{kind:`class`,title:r.name,broadcastUrl:r.links.page,visibility:`public`})).event;await S(`/api/v1/events/${encodeURIComponent(a.id)}/start`,{version:a.version}),i(`${r.name} is live on backtoschool.help`),await x(),await _()}async function re(e){let t=y.get(b(e.links.page));t&&await S(`/api/v1/events/${encodeURIComponent(t.id)}/end`,{version:t.version}).catch(()=>void 0)}function ie(e){let t=r(`div`,{class:`targets`}),n=r(`input`,{type:`checkbox`});n.checked=e.visibility===`public`&&e.listed,n.addEventListener(`change`,()=>{n.disabled=!0,f(`live.streaming`,()=>te(e,n.checked)).finally(()=>{n.disabled=!1,_().catch(()=>void 0)})}),t.append(r(`label`,{title:`Public and listed in the live.streaming guide`},n,`On live.streaming`)),n.checked&&t.append(r(`a`,{href:`https://live.streaming/`,target:`_blank`,rel:`noopener`},`open`));let i=y.get(b(e.links.page)),a=r(`input`,{type:`checkbox`,disabled:!v});return a.checked=i!==void 0,a.addEventListener(`change`,()=>{a.disabled=!0,f(`backtoschool.help`,()=>ne(e,a.checked)).finally(()=>{a.disabled=!v,w()})}),t.append(r(`label`,{title:v?`A live class on backtoschool.help that plays this station`:`Open nixamp.com/radio signed in to put stations on backtoschool.help`},a,`On backtoschool.help`)),i&&t.append(r(`a`,{href:`${ee}/live/${encodeURIComponent(i.slug)}`,target:`_blank`,rel:`noopener`},`open`)),t}function w(){let e=n(`#station-list`);if(e.replaceChildren(),h.length===0){e.append(r(`p`,{class:`hint`},`No stations yet. Make one below from a folder or a playlist.`));return}for(let t of h){let n=t.desired===`running`,a=t.visibility!==`private`,o=r(`button`,{type:`button`,class:`ghost`,disabled:!a,title:a?`Copy the listening link`:`Private: make it unlisted or public to share`},`Copy link`);o.addEventListener(`click`,()=>void f(`Copy`,async()=>{await navigator.clipboard.writeText(t.links.page),i(`Link to ${t.name} copied`),o.textContent=`Copied`,setTimeout(()=>{o.textContent=`Copy link`},1500)}));let s=r(`button`,{type:`button`},n?`Stop`:`Start`);s.addEventListener(`click`,()=>void f(n?`Stop`:`Start`,async()=>{await d(`POST`,`/api/v1/stations/${t.id}/${n?`stop`:`start`}`,{}),i(`${t.name} ${n?`stopped`:`started`}`),await _()}));let c=r(`button`,{type:`button`,class:`ghost`,disabled:t.state!==`live`},`Skip`);c.addEventListener(`click`,()=>void f(`Skip`,async()=>{await d(`POST`,`/api/v1/stations/${t.id}/skip`,{}),i(`Skipped`)}));let l=r(`button`,{type:`button`,class:`ghost`},`Who can listen…`);l.addEventListener(`click`,()=>T(t));let u=r(`button`,{type:`button`,class:`ghost danger`},`Delete`);u.addEventListener(`click`,()=>void f(`Delete`,async()=>{confirm(`Delete the station "${t.name}"? Its files are not touched.`)&&(await d(`DELETE`,`/api/v1/stations/${t.id}`),i(`${t.name} deleted`),await _())}));let p=t.excluded.length?r(`button`,{type:`button`,class:`ghost`},`Retry ${t.excluded.length} left out`):null;p?.addEventListener(`click`,()=>void f(`Retry`,async()=>{await d(`POST`,`/api/v1/stations/${t.id}/retry`,{}),await _()})),e.append(r(`article`,{class:`station`,id:`station-${t.id}`,"aria-label":t.name},r(`div`,{class:`station-head`},r(`span`,{class:`state state-${t.state}`},m[t.state]??t.state),r(`h3`,{},t.name),r(`span`,{class:`muted`},`${t.visibility}${t.listed?`, listed`:``}`)),r(`p`,{class:`muted`},`${t.items.length} files · ${t.shuffle?`shuffle`:`in order`} · ${t.repeat?`repeating`:`once`} · ${t.bitrate} kbps · ${t.listeners} listening`),t.error&&t.state!==`live`?r(`p`,{class:`warn`},t.error):null,...(t.alerts??[]).map(e=>r(`p`,{class:`warn`,role:`status`},`⚠ ${e}`)),t.metrics?r(`p`,{class:`muted`},`This month: ${(t.metrics.month.bytes/1024**2).toFixed(1)} MB delivered · ${Math.round(t.metrics.month.listenerSeconds/3600*10)/10} listener-hours · peak ${t.metrics.month.peakListeners}`):null,ie(t),a?r(`p`,{class:`link`},r(`a`,{href:t.links.page,target:`_blank`,rel:`noopener`},`Open the listening page`)):null,r(`div`,{class:`actions`},s,c,o,l,p,u)))}}function T(e,t){g=e;let r=n(`#publish-form`);r.elements.namedItem(`visibility`).value=t?.visibility??e.visibility,r.elements.namedItem(`listed`).checked=t?.listed??(e.visibility!==`public`||e.listed),r.elements.namedItem(`basis`).value=e.rights?.basis??``,r.elements.namedItem(`note`).value=e.rights?.note??``,E(),n(`#publish-dialog`).showModal()}function E(){let e=n(`#publish-form`),t=e.elements.namedItem(`visibility`).value===`public`;n(`#public-only`).hidden=!t,e.elements.namedItem(`basis`).required=t}async function ae(){if(!g)return;let e=n(`#publish-form`),t=e.elements.namedItem(`visibility`).value,r=e.elements.namedItem(`basis`).value,i=e.elements.namedItem(`note`).value,a=await d(`POST`,`/api/v1/stations/${g.id}/access`,{visibility:t,listed:t===`public`&&e.elements.namedItem(`listed`).checked,...r?{rights:{basis:r,note:i}}:{}});t===`private`?await re(g):t===`public`&&e.elements.namedItem(`listed`).checked&&await C(g);let s=t===`private`?`${g.name} is private`:t===`unlisted`?`${g.name} is unlisted: anyone with the link can listen`:`${g.name} is public${e.elements.namedItem(`listed`).checked?` and on the air on live.streaming`:``}`;o(a.dropped?`${s}; ${a.dropped} listeners disconnected`:s,`ok`),await x(),await _(),D(g.id)}function D(e){let t=document.getElementById(`station-${e}`);t&&(t.scrollIntoView({block:`center`}),t.classList.add(`just-changed`),setTimeout(()=>t.classList.remove(`just-changed`),2500))}var O=[],k=new Set,A=[],j=!0;async function M(){let e=l,t=await d(`GET`,`/api/v1/library`);if(e!==l)return;let a=Object.entries(t.counts).filter(([e,t])=>t>0&&e!==`ready`).map(([e,t])=>`${t} ${e}`),o=t.sources.some(e=>e.lastScan?.status===`running`);n(`#library-summary`).textContent=`${t.counts.ready??0} ready to play${a.length?` (${a.join(`, `)})`:``}${o?` · reading new files…`:``}`;let s=n(`#sources`);s.replaceChildren();for(let e of t.sources){let t=r(`button`,{type:`button`,class:`ghost`},`Scan again`);t.addEventListener(`click`,()=>void f(`Scan`,async()=>{await d(`POST`,`/api/v1/library/sources/${String(e.id)}/scan`,{}),i(`Scanning`),setTimeout(()=>void M(),1500)}));let n=e.lastScan;s.append(r(`p`,{class:`source`},r(`code`,{},String(e.root??e.id)),` ${e.enabled?``:`(off) `}`,n?r(`span`,{class:`muted`},`last scan ${String(n.status)}: ${String(n.found)} found, ${String(n.probed)} read`):r(`span`,{class:`muted`},`never scanned`),` `,t))}}var N=0;async function P(e){let t=++N,n=await d(`GET`,`/api/v1/library/items?${new URLSearchParams({q:e,limit:`100`,sort:e?`artist`:`recent`})}`);t===N&&(O=n.items,k.clear(),F(n.total))}function F(e){let t=n(`#results`);if(t.replaceChildren(),O.length===0){t.append(r(`p`,{class:`hint`},`Nothing matches.`)),I();return}let i=r(`table`,{class:`items`},r(`caption`,{class:`sr-only`},`Library items`),r(`thead`,{},r(`tr`,{},r(`th`,{scope:`col`},r(`span`,{class:`sr-only`},`Select`)),r(`th`,{scope:`col`},`Title`),r(`th`,{scope:`col`},`Artist`),r(`th`,{scope:`col`},`Album`),r(`th`,{scope:`col`},`Time`),r(`th`,{scope:`col`},r(`span`,{class:`sr-only`},`Play`))))),a=r(`tbody`);for(let e of O){let t=r(`input`,{type:`checkbox`,"aria-label":`Select ${e.title}`});t.addEventListener(`change`,()=>{t.checked?k.add(e.id):k.delete(e.id),I()});let n=r(`button`,{type:`button`,class:`ghost`,"aria-label":`Play ${e.title}`},`▶`);n.addEventListener(`click`,()=>void W([e.id],0)),a.append(r(`tr`,{},r(`td`,{},t),r(`td`,{title:e.rel},e.title),r(`td`,{},e.artist),r(`td`,{},e.album),r(`td`,{class:`muted`},p(e.duration)),r(`td`,{},n)))}i.append(a),t.append(i),e>O.length&&t.append(r(`p`,{class:`muted`},`Showing ${O.length} of ${e}. Narrow the search to see the rest.`)),I()}function I(){n(`#selection`).hidden=k.size===0,n(`#selection-count`).textContent=`${k.size} selected`,n(`#add-to`).replaceChildren(...A.map(e=>r(`option`,{value:e.id},e.name))),n(`#add-selection`).toggleAttribute(`disabled`,A.length===0),n(`#new-playlist`).disabled=!j}async function L(e){let t=await d(`GET`,`/api/v1/library/browse/${e}?limit=500`),i=n(`#groups`);i.replaceChildren(),i.hidden=!1;for(let n of t.groups){let t=r(`button`,{type:`button`,class:`group`},`${n.name}${n.artist?` — ${n.artist}`:``} (${n.count})`);t.addEventListener(`click`,()=>void f(`Browse`,async()=>{let t={[e===`artists`?`artist`:e===`albums`?`album`:e===`genres`?`genre`:`folder`]:n.name},r=++N,i=await d(`GET`,`/api/v1/library/items?${new URLSearchParams({...t,limit:`500`,sort:`album`})}`);r===N&&(O=i.items,k.clear(),F(i.total))})),i.append(t)}}async function R(){try{A=(await d(`GET`,`/api/v1/library/playlists`)).playlists,j=!0}catch(e){if(e instanceof s&&e.code===`sign_in_required`)j=!1,A=[];else throw e}let e=n(`#playlists`);e.replaceChildren(),j?A.length===0&&e.append(r(`p`,{class:`hint`},`No playlists yet. Select some items above and choose New playlist.`)):e.append(r(`p`,{class:`hint`},`Sign in to nixamp.com (or open this server with its control link) to keep playlists and pick up where you left off on another device.`));for(let t of A){let n=r(`button`,{type:`button`,class:`ghost`},`Open`);n.addEventListener(`click`,()=>void f(`Open playlist`,()=>z(t.id)));let i=r(`button`,{type:`button`},`Play`);i.addEventListener(`click`,()=>void f(`Play`,async()=>{let e=(await d(`GET`,`/api/v1/library/playlists/${t.id}`)).playlist;await W((e.items??[]).filter(e=>e.state===`ready`).map(e=>e.id),0)}));let a=r(`button`,{type:`button`,class:`ghost`},`Publish as a station`);a.addEventListener(`click`,()=>void f(`Publish as a station`,async()=>{let e=await d(`POST`,`/api/v1/stations`,{name:t.name,playlist:t.id,idempotencyKey:`playlist:${t.id}`});await _(),D(e.station.id),o(e.created?`Station ${t.name} made. Choose who can listen to put it on the air.`:`${t.name} already has a station. Choose who can listen.`,`ok`),T(h.find(t=>t.id===e.station.id)??e.station,{visibility:`public`,listed:!0})},a));let s=r(`button`,{type:`button`,class:`ghost danger`},`Delete`);s.addEventListener(`click`,()=>void f(`Delete playlist`,async()=>{confirm(`Delete the playlist "${t.name}"?`)&&(await d(`DELETE`,`/api/v1/library/playlists/${t.id}`),await R())})),e.append(r(`div`,{class:`playlist`,id:`playlist-${t.id}`},r(`strong`,{},t.name),r(`span`,{class:`muted`},` ${t.count} items `),r(`span`,{class:`actions`},i,n,a,s)))}I(),ce()}async function z(e){let t=(await d(`GET`,`/api/v1/library/playlists/${e}`)).playlist,i=n(`#playlist-${e}`);i.querySelector(`ol`)?.remove();let a=t.items??[],o=r(`ol`,{class:`playlist-items`});a.forEach((n,i)=>{let s=n=>async()=>{let r=a.map(e=>e.id),[o]=r.splice(i,1);r.splice(Math.max(0,Math.min(r.length,i+n)),0,o),await d(`PATCH`,`/api/v1/library/playlists/${e}`,{items:r,revision:t.revision}),await z(e)},c=r(`button`,{type:`button`,class:`ghost`,disabled:i===0,"aria-label":`Move ${n.title??`item`} up`},`↑`);c.addEventListener(`click`,()=>void f(`Move`,s(-1)));let l=r(`button`,{type:`button`,class:`ghost`,disabled:i===a.length-1,"aria-label":`Move ${n.title??`item`} down`},`↓`);l.addEventListener(`click`,()=>void f(`Move`,s(1)));let u=r(`button`,{type:`button`,class:`ghost`,"aria-label":`Remove ${n.title??`item`}`},`✕`);u.addEventListener(`click`,()=>void f(`Remove`,async()=>{await d(`PATCH`,`/api/v1/library/playlists/${e}`,{items:a.filter((e,t)=>t!==i).map(e=>e.id),revision:t.revision}),await z(e),await R()})),o.append(r(`li`,{},`${n.title??n.id}${n.artist?` — ${n.artist}`:``}`,n.state===`ready`?null:r(`span`,{class:`warn`},` (${n.state})`),` `,c,l,u))}),i.append(o)}var B=[],V=0,H=0,U=/Mobi|Android|iPhone/i.test(navigator.userAgent)?`phone`:`computer`;async function W(e,t,n=0){e.length!==0&&(B=e,V=t,j&&await d(`PUT`,`/api/v1/library/queue`,{items:e,device:U}).catch(()=>void 0),await q(n))}var G=null;function K(){G?.destroy(),G=null}async function q(t=0){let r=B[V];if(!r)return;let i=n(`#audio`);K(),G=await e(i,{src:u(`/api/v1/library/items/${r}/stream`,!0),kind:`audio`}),t>0&&(i.currentTime=t);let a=O.find(e=>e.id===r)??await d(`GET`,`/api/v1/library/items/${r}`).then(e=>e.item).catch(()=>null);n(`#now`).textContent=a?`${a.title}${a.artist?` — ${a.artist}`:``}`:``,await i.play().catch(()=>void 0),j&&await d(`PATCH`,`/api/v1/library/queue`,{at:V,position:t,device:U}).catch(()=>void 0)}function oe(){let e=n(`#audio`);e.addEventListener(`ended`,()=>{V+1<B.length&&(V+=1,q())}),e.addEventListener(`timeupdate`,()=>{!j||Date.now()-H<1e4||(H=Date.now(),d(`PATCH`,`/api/v1/library/queue`,{at:V,position:e.currentTime,device:U}).catch(()=>void 0))})}async function se(){if(!j)return;let e=(await d(`GET`,`/api/v1/library/queue`).catch(()=>null))?.queue,t=e?.items[e.at];if(!e||!t||e.items.length===0)return;let i=n(`#resume`),a=r(`button`,{type:`button`},`Resume`);a.addEventListener(`click`,()=>void f(`Resume`,async()=>{B=e.items.map(e=>e.id),V=e.at,await q(e.position),i.hidden=!0})),i.replaceChildren(r(`span`,{},`Where you left off${e.device?` on your ${e.device}`:``}: ${t.title??``} at ${p(e.position)||`the start`}. `),a),i.hidden=!1}async function ce(){let e=n(`#station-from`),t=await d(`GET`,`/api/v1/library/browse/folders?limit=500`).catch(()=>({groups:[]}));e.replaceChildren(r(`option`,{value:`folder:`},`The whole library`),...A.length?[r(`optgroup`,{label:`Playlists`},...A.map(e=>r(`option`,{value:`playlist:${e.id}`},`${e.name} (${e.count})`)))]:[],r(`optgroup`,{label:`Folders`},...t.groups.map(e=>r(`option`,{value:`folder:${e.name}`},`${e.name} (${e.count})`))))}async function le(e){let t=new FormData(e),[r,i]=String(t.get(`from`)??`folder:`).split(/:(.*)/s),a=await d(`POST`,`/api/v1/stations`,{name:String(t.get(`name`)??``),...r===`playlist`?{playlist:i}:{folder:i??``},shuffle:t.get(`shuffle`)===`on`,repeat:t.get(`repeat`)===`on`,bitrate:Number(t.get(`bitrate`)??128)});e.reset(),n(`#new-station`).open=!1,await _(),D(a.station.id),o(`Station ${a.station.name} made; it is private and stopped. Use "Who can listen" to put it on the air.`,`ok`)}var J={ai:`AI Radio`,radio:`Radio`,tv:`TV`,shared:`Shared by listeners`,rooms:`Live rooms`,vod:`On demand`};async function Y(){let e=Q()?``:`https://nixamp.com`,t=((await(await fetch(`${e}/api/v1/stations/guide`)).json()).stations??[]).filter(e=>/^https:\/\//.test(e.page)),i=n(`#on-air-list`);if(t.length===0){i.replaceChildren(r(`p`,{class:`hint`},`Nothing is on the air right now.`));return}let a=[...new Set(t.map(e=>e.group??(e.kind===`video`?`tv`:`radio`)))].sort((e,t)=>Object.keys(J).indexOf(e)-Object.keys(J).indexOf(t));i.replaceChildren(...a.map(e=>r(`div`,{class:`on-air-group`},r(`h3`,{class:`radio-subtitle`},J[e]??e),r(`ul`,{class:`on-air-cards`},...t.filter(t=>(t.group??(t.kind===`video`?`tv`:`radio`))===e).map(e=>r(`li`,{class:`on-air-card`},r(`a`,{href:e.page,target:`_blank`,rel:`noopener`},r(`span`,{class:`state ${e.state===`live`?`state-live`:`state-stopped`}`},e.state===`live`?`Live`:`Off`),r(`strong`,{},e.name),r(`span`,{class:`muted`},e.nowPlaying?[e.nowPlaying.title,e.nowPlaying.artist].filter(Boolean).join(` · `):``))))))))}async function ue(e){let t=(await(await fetch(`${e.server}/api/v1/label`)).json()).genres.flatMap(e=>e.artists).find(t=>t.key===e.artist);return t?t.albums.filter(t=>e.kind===`artist`||t.key===e.album).flatMap(n=>n.songs.filter(t=>e.kind!==`song`||t.n===e.n).map(r=>({title:`${r.title} · ${t.name} · ${n.title}`,src:`${e.server}/api/v1/label/${t.key}/${n.key}/${r.n}.mp3?grant=${encodeURIComponent(e.grant??``)}`}))):[]}var X=[],de=0;function fe(e){let t=X[e];if(!t)return;de=e;let r=n(`#music-audio`);n(`#music-player`).hidden=!1,n(`#music-now`).textContent=`${e+1}/${X.length} · ${t.title}`,r.src=t.src,r.play().catch(()=>void 0),i(`Playing ${t.title}`)}async function pe(){if(!Q()){n(`#music-summary`).replaceChildren(`Your purchases are on `,r(`a`,{href:`https://nixamp.com/music/me`,target:`_blank`,rel:`noopener`},`nixamp.com/music`),`.`);return}let e=await fetch(`/api/v1/store/purchases`,{credentials:`same-origin`});if(e.status===401){n(`#music-summary`).textContent=`Sign in to nixamp.com with the email you bought with, and your music is here.`;return}let t=await e.json(),i=t.purchases??[];n(`#music-summary`).textContent=i.length?`${i.length} purchase${i.length===1?``:`s`} for ${t.email??`you`}. Play here or download the zip again.`:`Nothing bought yet. Every AI label song is 10¢, an album $1, an artist's whole catalogue $2: look for Download on a station's now playing.`,n(`#music-list`).replaceChildren(...i.map(e=>{if(e.kind===`vod`)return r(`article`,{class:`station`,"aria-label":e.title},r(`div`,{class:`station-head`},r(`span`,{class:`state state-live`},`Video`),r(`h3`,{},e.title),r(`span`,{class:`muted`},`${e.artistName} · ${new Date(e.paidAt).toLocaleDateString()}`)),r(`div`,{class:`actions`},r(`a`,{href:`${e.server}/vod/${e.artist}`,target:`_blank`,rel:`noopener`},`Watch`),e.zip?r(`a`,{href:e.zip,class:`ghost`},`Download`):null,e.link?r(`a`,{href:e.link,target:`_blank`,rel:`noopener`},`Receipt`):null));let t=r(`button`,{type:`button`},`Play`);return t.addEventListener(`click`,()=>void f(`Play`,async()=>{if(X=await ue(e),X.length===0)throw Error(`its server has no songs for it right now`);fe(0)},t)),r(`article`,{class:`station`,"aria-label":e.title},r(`div`,{class:`station-head`},r(`span`,{class:`state state-live`},e.kind===`artist`?`Artist`:e.kind===`album`?`Album`:`Song`),r(`h3`,{},e.title),r(`span`,{class:`muted`},`${e.artistName} · ${new Date(e.paidAt).toLocaleDateString()}`)),r(`div`,{class:`actions`},t,e.zip?r(`a`,{href:e.zip,class:`ghost`,download:!0},`Download zip`):null,e.link?r(`a`,{href:e.link,target:`_blank`,rel:`noopener`},`Receipt`):null))}))}function me(){n(`#music-audio`).addEventListener(`ended`,()=>fe(de+1)),pe().catch(()=>void 0)}var he=``;async function Z(){let e=l,t;try{t=await d(`GET`,`/api/v1/stations/label`)}catch(t){if(e!==l)return;n(`#label-artists`).replaceChildren(),n(`#label-summary`).textContent=t instanceof s&&t.status===404?`This server has no AI label yet: it needs nixamp 0.49 or later (nixamp update on that machine).`:`The label could not be read: ${t instanceof Error?t.message:String(t)}`;return}if(e!==l)return;let{settings:a}=t,o=a.monthlySeconds===0?`no cap`:`${Math.round(t.secondsThisMonth/60)} of ${Math.round(a.monthlySeconds/60)} min this month`,u=`${c.base}/label`;n(`#label-summary`).replaceChildren(`${a.holder} · ${t.composer??`no composer`} · ${o} · an album every ${a.everyDays} days`,t.busy?` · recording ${t.busy}`:``,t.waiting?` · waiting: ${t.waiting}`:``,` · `,r(`a`,{href:u,target:`_blank`,rel:`noopener`},`Public catalogue`));let p=n(`#label-preset`),m=p.value;if(p.replaceChildren(r(`option`,{value:``},`Choose…`),...t.roster.filter(e=>!e.signed).map(e=>r(`option`,{value:e.key},`${e.name} (${e.genre})`))),p.value=t.roster.some(e=>e.key===m&&!e.signed)?m:``,he!==c.id){he=c.id;let e=n(`#label-config`);for(let t of[`holder`,`monthlySeconds`,`everyDays`,`songsPerAlbum`,`songSeconds`])e.elements.namedItem(t).value=String(a[t])}let h=n(`#label-artists`);if(h.replaceChildren(),a.pausedReason){let e=r(`button`,{type:`button`},`Resume`);e.addEventListener(`click`,()=>void f(`Resume`,async()=>{await d(`POST`,`/api/v1/stations/label`,{resume:!0}),await Z()},e)),h.append(r(`p`,{class:`warn`,role:`status`},`Paused: ${a.pausedReason} `,e))}if(t.artists.length===0){let e=r(`button`,{type:`button`},`Sign the whole roster`);e.addEventListener(`click`,()=>void f(`Sign`,async()=>{await d(`POST`,`/api/v1/stations/label/artists`,{roster:!0}),i(`Roster signed`),await Z()},e)),h.append(r(`p`,{class:`hint`},`Nobody signed yet. `,e));return}for(let e of t.artists){let t=e.nextAlbumAt===-1?`off`:e.nextAlbumAt===0?`due now`:`next album ${new Date(e.nextAlbumAt).toLocaleDateString()}`,n=e.albums.some(e=>!e.doneAt),a=r(`button`,{type:`button`,disabled:n,title:n?`An album is still being recorded`:`Plan and record the next album now`},`New album now`);a.addEventListener(`click`,()=>void f(`New album`,async()=>{await d(`POST`,`/api/v1/stations/label/artists/${e.key}/album`,{}),i(`${e.name}: album planned`),await Z()},a));let o=r(`button`,{type:`button`,class:`ghost`},e.enabled?`Pause`:`Resume`);o.addEventListener(`click`,()=>void f(e.enabled?`Pause`:`Resume`,async()=>{await d(`PATCH`,`/api/v1/stations/label/artists/${e.key}`,{enabled:!e.enabled}),await Z()},o));let s=r(`button`,{type:`button`,class:`ghost danger`},`Drop`);s.addEventListener(`click`,()=>void f(`Drop`,async()=>{confirm(`Drop ${e.name} from the label? Their albums stay on the air; nothing new is recorded.`)&&(await d(`DELETE`,`/api/v1/stations/label/artists/${e.key}`),await Z())},s)),h.append(r(`article`,{class:`station`,"aria-label":e.name},r(`div`,{class:`station-head`},r(`span`,{class:`state ${e.enabled?`state-live`:`state-stopped`}`},e.genre),r(`h3`,{},e.name),r(`span`,{class:`muted`},t)),e.albums.length?r(`ul`,{class:`playlist-items`},...e.albums.map(e=>r(`li`,{},`${e.year} · ${e.title} · ${e.composed}/${e.songs} songs${e.doneAt?``:` (recording)`}`))):r(`p`,{class:`muted`},`No albums yet.`),e.lastError?r(`p`,{class:`warn`},e.lastError):null,r(`div`,{class:`actions`},a,o,s)))}}function ge(){n(`#label-sign`).addEventListener(`submit`,e=>{e.preventDefault();let t=e.currentTarget,n=e=>t.elements.namedItem(e).value.trim(),r=n(`preset`)?{preset:n(`preset`)}:{name:n(`name`),genre:n(`genre`),sound:n(`sound`),...n(`voice`)?{voice:n(`voice`)}:{}};f(`Sign`,async()=>{let e=await d(`POST`,`/api/v1/stations/label/artists`,r);t.reset(),o(`${e.artist.name} signed. Their first albums are being written now.`,`ok`),await Z()},t.querySelector(`button[type=submit]`)??void 0)}),n(`#label-config`).addEventListener(`submit`,e=>{e.preventDefault();let t=e.currentTarget,n=e=>t.elements.namedItem(e).value.trim();f(`Save label settings`,async()=>{await d(`POST`,`/api/v1/stations/label`,{holder:n(`holder`),monthlySeconds:Number(n(`monthlySeconds`)),everyDays:Number(n(`everyDays`)),songsPerAlbum:Number(n(`songsPerAlbum`)),songSeconds:Number(n(`songSeconds`))}),o(`Label settings saved.`,`ok`),await Z()},t.querySelector(`button[type=submit]`)??void 0)}),setInterval(()=>void Z().catch(()=>void 0),15e3)}async function _e(){oe(),ge(),me(),Y().catch(()=>void 0),setInterval(()=>void Y().catch(()=>void 0),3e4),n(`#search-form`).addEventListener(`submit`,e=>{e.preventDefault();let t=e.currentTarget,r=t.elements.namedItem(`browse`).value,i=t.elements.namedItem(`q`).value.trim();n(`#groups`).hidden=!0,f(`Search`,()=>r&&!i?L(r):P(i))}),n(`#search-form select`).addEventListener(`change`,e=>{let t=e.currentTarget.value;t&&f(`Browse`,()=>L(t))}),n(`#play-selection`).addEventListener(`click`,()=>void f(`Play`,()=>W(O.filter(e=>k.has(e.id)).map(e=>e.id),0))),n(`#new-playlist`).addEventListener(`click`,()=>void f(`New playlist`,async()=>{let e=prompt(`Name the playlist`);e&&(await d(`POST`,`/api/v1/library/playlists`,{name:e,items:O.filter(e=>k.has(e.id)).map(e=>e.id)}),i(`Playlist ${e} made`),await R())})),n(`#add-selection`).addEventListener(`click`,()=>void f(`Add to playlist`,async()=>{let e=n(`#add-to`).value;await d(`POST`,`/api/v1/library/playlists/${e}/items`,{items:O.filter(e=>k.has(e.id)).map(e=>e.id)}),i(`Added`),await R()})),n(`#station-form`).addEventListener(`submit`,e=>{e.preventDefault();let t=e.currentTarget;f(`Make station`,()=>le(t),t.querySelector(`button[type=submit]`)??void 0)}),n(`#source-form`).addEventListener(`submit`,e=>{e.preventDefault();let t=e.currentTarget,n=t.elements.namedItem(`root`).value.trim();f(`Add source`,async()=>{await d(`POST`,`/api/v1/library/sources`,{root:n}),t.reset(),i(`Added; reading its files`),setTimeout(()=>void M(),1500)})}),n(`#publish-form`).addEventListener(`change`,E),n(`#publish-dialog`).addEventListener(`close`,()=>{n(`#publish-dialog`).returnValue===`save`&&f(`Who can listen`,ae)});let e=await be(),t=n(`#server`);t.replaceChildren(...e.map(e=>r(`option`,{value:e.id},e.name))),e.length===0&&t.append(r(`option`,{value:``},`No servers`));let a=(()=>{try{return localStorage.getItem(ye)??``}catch{return``}})(),o=e.find(e=>e.id===a)??e[0];if(t.addEventListener(`change`,()=>{let n=e.find(e=>e.id===t.value);n&&$(n)}),setInterval(()=>void _().catch(()=>void 0),5e3),setInterval(()=>void M().catch(()=>void 0),15e3),setInterval(()=>void x().then(w).catch(()=>void 0),15e3),!o){let e=Q()?`Sign in to nixamp.com to manage your own stations, library and label here. A server shows up once it has run signed in to your account (nixamp login on that machine).`:`This page manages the server it is on.`;for(let e of[`#stations`,`#label`,`#library`,`#music`])n(e).hidden=!0;for(let e of document.querySelectorAll(`.radio-nav [data-tab], .server-pick`))e.hidden=!0;n(`#on-air`).before(r(`p`,{class:`hint`,id:`signed-out`},e)),Q()&&ve().then(e=>{e&&n(`#signed-out`).after(e)});return}t.value=o.id,await $(o),location.hash===`#stations`&&document.querySelector(`#stations`)?.scrollIntoView()}async function ve(){let e=[];try{let t=await fetch(`/api/v1/auth/providers`);t.ok&&(e=(await t.json()).providers??[])}catch{return null}let t=encodeURIComponent(location.pathname+location.hash);return r(`p`,{class:`actions sign-in`,id:`sign-in`},r(`a`,{class:`button`,href:`/?redirect=${t}#account-panel`},`Sign in with nixamp`),...e.map(e=>r(`a`,{class:`button ghost`,href:`/api/v1/${encodeURIComponent(e.id)}/oauth/start?redirect=${t}`},`Sign in with ${e.name}`)))}var ye=`nixamp.radio.server`;function Q(){return/^(www\.)?nixamp\.com$/i.test(location.hostname)}async function be(){let e=Q()?[]:[{id:`here`,name:`This server (${location.host})`,base:``,session:``,key:``}],n=``;try{let e=await fetch(`/api/v1/auth/token`,{credentials:`same-origin`}),t=await e.json().catch(()=>({}));n=e.ok&&typeof t.token==`string`?t.token:``}catch{n=``}if(!n)return e;try{v=(await fetch(`/api/v1/events?mine=true&kind=class&status=live&limit=1`,{credentials:`same-origin`})).ok}catch{v=!1}try{let r=await(await fetch(`/api/v1/servers`,{credentials:`same-origin`})).json().catch(()=>({}));for(let i of r.servers??[]){let{base:r,key:a}=t(i.url);/^https?:\/\//.test(r)&&r.replace(/\/+$/,``)!==location.origin&&(location.protocol===`https:`&&r.startsWith(`http://`)||e.find(e=>e.base===r.replace(/\/+$/,``))||e.push({id:i.id,name:i.name||new URL(r).host,base:r.replace(/\/+$/,``),session:n,key:i.key||a}))}}catch{}return e}async function $(e){l+=1,N+=1,c=e;try{localStorage.setItem(ye,e.id)}catch{}h=[],O=[],k.clear(),B=[];let t=n(`#audio`);t.pause(),K(),t.removeAttribute(`src`),n(`#now`).textContent=``,n(`#resume`).hidden=!0,n(`#groups`).hidden=!0,w(),o(``);try{await x().catch(()=>void 0),await xe(e)}catch(t){t instanceof s&&(t.status===401||t.status===403)?o(e.base?`${e.name} did not accept your nixamp.com sign-in. Is it running signed in as you? (on that machine: nixamp login, then nixamp daemon restart)`:`This page manages the server it is on. Open it from your server's admin link (nixamp admin prints it), or sign in as its owner.`):t instanceof s&&t.status===404?o(`${e.name} has no library or stations: it needs nixamp 0.32 or later (nixamp update on that machine).`):t instanceof TypeError?o(`Could not reach ${e.name} at ${e.base||location.origin}. Is it on?`):o(t instanceof Error?t.message:String(t));return}await Z(),await se()}async function xe(e){let t=l;try{await Promise.all([M(),_(),R(),P(``)])}catch(n){if(!(n instanceof s&&(n.status===401||n.status===403)&&e.session&&e.key)||t!==l)throw n;c={...e,session:``},await Promise.all([M(),_(),R(),P(``)])}}_e();