{#snippet cover(a, size)} {#if a.art_path} {#if coverUrls[a.id]} {:else}
{/if} {:else} {@const g = genFor(a)}
{/if} {/snippet} {#snippet releaseCard(a, sectionKey)}
(hoverId = a.id)} onpointerleave={() => { if (hoverId === a.id) hoverId = null; }} onclick={() => toggleExpander(a)} onkeydown={(e) => (e.key === "Enter" || e.key === " ") && toggleExpander(a)} >
{#if chipFor(a)}{chipFor(a)}{/if} {@render cover(a, CARD_W)}
{a.title}
{subFor(a)}
{/snippet} {#snippet gapCard(r)} {@const cat = fileRelease({ title: r.title, record_type: r.record_type, track_count: r.track_count, is_live: r.is_live, is_soundtrack: r.is_soundtrack, })}
{#if r.release_date?.slice(0, 4)} {r.release_date.slice(0, 4)} {/if} {#if r.cover} {:else}
{/if}
{r.title}
{cat === "other" ? "" : CAT_ONE[cat]}
{/snippet} {#snippet expander(items, sectionKey)}
{#key openId}
{#if openAlbum?.art_path && coverUrls[openAlbum.id]} {:else if openAlbum && !openAlbum.art_path} {@const g = genFor(openAlbum)} {/if}

{#if openCatalogId != null || (openAlbum?.artist && openAlbum?.title)} {:else} {openAlbum?.title ?? ""} {/if}

{openAlbum?.year ?? "no year"}{openTracks.length ? ` · ${openTracks.length} tracks` : openAlbum?.track_count ? ` · ${openAlbum.track_count} tracks` : ""}{openAlbum?.secs ? ` · ${dur(openAlbum.secs)}` : ""}

{#if openAlbum && (openAlbum.bytes || openAlbum.avgKbps)}
{#if openAlbum.bytes} {fmtBytes(openAlbum.bytes)}on disk {/if} {#if openAlbum.bytes && openAlbum.avgKbps}{/if} {#if openAlbum.avgKbps} {openAlbum.avgKbps}kbitrate {/if} {#if openAlbum.formats[0]} {openAlbum.formats[0].toUpperCase()}{openAlbum.depth ? ` ${openAlbum.depth}` : ""} {/if}
{/if}
{#if openTracks.length} openTracks.map((t) => ({ title: t.title, artist: t.artist, album: openAlbum?.title ?? null, duration_secs: t.duration_secs, path: t.path, art_path: openAlbum?.art_path ?? null, }))} /> {/if}
{#if openInfo?.description} {#if railDesc.lede}

{railDesc.lede}

{/if} {#if railDesc.rest}

{railDesc.rest}

{/if} {#if openInfo.genre || openInfo.label}
{#if openInfo.genre}{openInfo.genre}{/if} {#if openInfo.label}{openInfo.label}{/if}
{/if} {/if}
{#if openLoading} {#if loadingVisible}
Loading tracks
{/if} {:else if openTracks.length}
# Title
{#each openDiscs as d (d.disc)} {#if multiDisc}
Disc {d.disc} · {d.rows.length} tracks
{/if} {#each d.rows as { t, i: ti } (t.id)}
playOpen(ti)} onkeydown={(e) => e.key === "Enter" && playOpen(ti)} > {isPlayingTrack(t) ? "♫" : (t.track_no ?? "·")} {t.title} {#if t.bitrate_kbps} {(t.path.split(".").pop() || "").toUpperCase()} {t.bitrate_kbps}k{t.bit_depth ? ` · ${t.bit_depth}-bit` : ""} {/if} {t.duration_secs ? dur(t.duration_secs) : "—"}
{/each} {/each} {:else}
No tracks found for this record
{/if}
{/key}
{/snippet} {#snippet cardGrid(items, sectionKey)}
{#each items as a, i (a.id)} {@render releaseCard(a, sectionKey)} {#if expanderIndex(items, sectionKey) === i} {@render expander(items, sectionKey)} {/if} {/each}
{/snippet} {#snippet gapSection(name, list)} {@const follow = followFor(name)} {#if follow} {@const key = foldKey(name)} {@const missing = gapRows[key]} {@const total = gapTotals[key]?.total} {@const count = missing ? missing.length : (total ? Math.max(0, total - list.length) : null)} {#if count !== 0} {/if} {#if gapOpen[key] && missing?.length}
{#each missing as r (r.id)} {@render gapCard(r)} {/each}
{/if} {/if} {/snippet} {#snippet artistPicker()}
(picker = null)} onkeydown={(e) => e.key === "Escape" && (picker = null)} >
{/snippet} {#snippet shelfHead(name, list)} {@const follow = followFor(name)} {@const total = group === "artist" ? gapTotals[foldKey(name)]?.total : null} {@const secs = list.reduce((n, a) => n + a.secs, 0)} {@const actionable = group === "artist"} {@const portrait = group === "artist" ? (list.find((a) => a.artist_art_path)?.artist_art_path ?? null) : null}
openShelfArtist(name) : undefined} onkeydown={actionable ? (e) => (e.key === "Enter" || e.key === " ") && openShelfArtist(name) : undefined} > {#if portrait && artistUrls[portrait]} {:else} {/if}
{name} {#if actionable} {#if resolving[name]} {:else} {/if} {/if}
{#if total}{list.length} of {total} released{:else}{list.length} {list.length === 1 ? "album" : "albums"}{/if}{#if secs} · {longDur(secs)}{/if}
{#if total} {/if}
{/snippet}
{#if picker}{@render artistPicker()}{/if} {#if ambUrl} {#key ambUrl}
{/key}
{/if}

Library

{totals.albums.toLocaleString()}{totals.albums === 1 ? "album" : "albums"} {totals.artists}{totals.artists === 1 ? "artist" : "artists"} {totals.tracks.toLocaleString()}tracks {#if totals.secs} {longDur(totals.secs)}of music {/if} {#if totals.bytes} {fmtBytes(totals.bytes)}on disk {/if} {#if totals.never} {totals.never}never played {/if}
{#each [["shelves", "Shelves"], ["grid", "Grid"], ["list", "List"]] as [k, l] (k)} {/each}
Group
{#each Object.entries(GROUPS) as [k, g] (k)} {/each}
Sort
{#if menuOpen} {/if}
{#if view === "list"}
RecordArtistTypeYear# LengthFormatRateSizeAdded
{/if}
{#if railItems.length}
{#each railItems as [l, k] (k)} {/each}
{/if} {#if corpus.length === 0}
{#if q}

Nothing matches {q}

{:else}

Your music will live here

Bring in a folder you already have, or download an album from Search — either way it lands here, tagged with art.
{/if}
{:else if view === "shelves"} {#each grouped as [name, list] (name)} {@const shown = expandedShelves[name] ? list : list.slice(0, PER_SHELF)}
{#if name}{@render shelfHead(name, list)}{/if} {#if group === "artist"} {#each splitByCategory(shown) as [label, part] (label ?? "all")} {#if label}
{label}{part.length}
{/if} {@render cardGrid(part, `${name}:${label ?? "all"}`)} {/each} {:else} {@render cardGrid(shown, name || "flat")} {/if} {#if list.length > shown.length} {/if} {#if group === "artist"} {@render gapSection(name, list)} {/if}
{/each} {:else if view === "grid"} {#each grouped as [name, list] (name)}
{#if name}
{name}{list.length}
{/if} {@render cardGrid(list, name || "flat")}
{/each} {:else}
{#each grouped as [name, list] (name)}
{#if name}
{name}{list.length}
{/if} {#each list as a (a.id)}
(hoverId = a.id)} onpointerleave={() => { if (hoverId === a.id) hoverId = null; }} onclick={() => toggleExpander(a)} onkeydown={(e) => (e.key === "Enter" || e.key === " ") && toggleExpander(a)} > {#if a.art_path && coverUrls[a.id]} {:else if !a.art_path} {@const g = genFor(a)} {:else} {/if} {a.title} {a.artist} {CAT_ONE[a.cat]} {a.year ?? "—"} {a.track_count || "—"} {a.secs ? dur(a.secs) : "—"} {#if a.formats[0]} {a.formats[0].toUpperCase()}{#if a.depth}{a.depth}{/if} {:else}—{/if} {a.avgKbps ? `${a.avgKbps}k` : "—"} {fmtBytes(a.bytes)} {since(a.added_at)}
{#if openId === a.id} {@render expander([a], "list")} {/if} {/each}
{/each}
{/if}