fix shadow

This commit is contained in:
Hamid Reza Mohammadi 2026-09-14 20:30:50 +03:30
parent fd609f86c5
commit e6397afae4
22 changed files with 158 additions and 123 deletions

View File

@ -14,7 +14,7 @@
<meta name="robots" content="noindex, nofollow" />
<title>پیشنهاد اضافه شدن مصرع‌های جا افتاده</title>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link href="/css/user-panel.css?version=1" rel="stylesheet" type="text/css" />
</head>
<body>

View File

@ -13,7 +13,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex, nofollow" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
</head>
<body class="bk-background">
<div id="hdr">

View File

@ -11,7 +11,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex, nofollow" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
</head>
<body class="bk-background">
<div id="hdr">

View File

@ -12,7 +12,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex, nofollow" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
</head>
<body class="bk-background">
<div id="hdr">

View File

@ -11,7 +11,7 @@
<meta name="robots" content="noindex, nofollow" />
<title>درخواست حذف حاشیه</title>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<style>
label {
width: 100px;

View File

@ -13,7 +13,7 @@
<title>
@ViewData["Title"]
</title>
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link rel="search" type="application/opensearchdescription+xml" title="گنجور" href="https://ganjoor.net/search.xml" />

View File

@ -12,7 +12,7 @@
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link href="/css/spotify.css" rel="stylesheet" type="text/css" />
<script src="/lib/jquery/dist/jquery.min.js"></script>

View File

@ -12,7 +12,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="سخنوران و نویسندگان گنجور روی نقشهٔ جغرافیایی" />
<meta charset="utf-8" />
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="/css/leaflet.css?version=2" />
<style>
.leaflet-container {
@ -23,7 +23,7 @@
font-family: 'Vazirmatn'
}
</style>
<script src="/js/bk.js?version=94"></script>
<script src="/js/bk.js?version=95"></script>
<script src="~/js/jquery-1.10.2.min.js"></script>
<script src="~/js/leaflet.js"></script>
<script src="~/js/leaflet-providers.js"></script>

View File

@ -11,11 +11,11 @@
<title>
@Html.Raw(ViewData["Title"])
</title>
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link rel="search" type="application/opensearchdescription+xml" title="گنجور" href="https://ganjoor.net/search.xml" />
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/js/bk.js?version=94"></script>
<script src="/js/bk.js?version=95"></script>
<script>
var cookieValue = getCookie("playerScrollLock");
var playerScrollLock = cookieValue === "true";

View File

@ -15,7 +15,7 @@
گنجور » نمایش خوانش
</title>
<link href="~/dist/skin/pink.flag/css/jplayer.pink.flag.min.css" rel="stylesheet" type="text/css" />
<link href="~/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="~/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link rel="search" type="application/opensearchdescription+xml" title="گنجور" href="https://ganjoor.net/search.xml" />
<script>
@ -150,7 +150,7 @@
</p>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/js/bk.js?version=94"></script>
<script src="~/js/bk.js?version=95"></script>
<script src="~/js/jplayersupport.js"></script>
<script src="~/js/vaabd.js?version=10"></script>
<script src="~/dist/jplayer/jquery.jplayer.min.js"></script>

View File

@ -12,7 +12,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex, nofollow" />
<title>اطلاعات رتبه‌بندی خوانش‌های شعر</title>
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
</head>
<body>

View File

@ -13,7 +13,7 @@
<meta name="robots" content="noindex, nofollow" />
<title>گنجور » گزارش خطا در خوانش</title>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link href="~/dist/skin/pink.flag/css/jplayer.pink.flag.min.css" rel="stylesheet" type="text/css" />
<style>
label {
@ -238,7 +238,7 @@
<script src="~/js/bk.js?version=94"></script>
<script src="~/js/bk.js?version=95"></script>
<script src="~/js/jplayersupport.js"></script>
<script src="~/js/vaabd.js?version=10"></script>
<script src="~/dist/jplayer/jquery.jplayer.min.js"></script>

View File

@ -10,7 +10,7 @@
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<link href="/dist/skin/blue.monday/css/jplayer.blue.monday.min.css" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link href="/css/user-panel.css?version=3" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link rel="search" type="application/opensearchdescription+xml" title="گنجور" href="https://ganjoor.net/search.xml" />
@ -36,7 +36,7 @@
});
</script>
<script src="/js/bk.js?version=94"></script>
<script src="/js/bk.js?version=95"></script>
<script>
function editBanner(bannerId) {
var url = '?handler=Edit';

View File

@ -30,11 +30,11 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>@Html.Raw(ViewData["Title"])</title>
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link rel="search" type="application/opensearchdescription+xml" title="گنجور" href="https://ganjoor.net/search.xml" />
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/js/bk.js?version=94"></script>
<script src="/js/bk.js?version=95"></script>
<script>
var cookieValue = getCookie("playerScrollLock");
var playerScrollLock = cookieValue === "true";

View File

@ -9,7 +9,7 @@
</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link href="/css/user-panel.css?version=3" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link rel="search" type="application/opensearchdescription+xml" title="گنجور" href="https://ganjoor.net/search.xml" />
@ -33,7 +33,7 @@
});
</script>
<script src="/lib/diff.js"></script>
<script src="/js/bk.js?version=94"></script>
<script src="/js/bk.js?version=95"></script>
<script>
function compareCorrectionBlocks(originalElemenyId, editedElementId, resultElementId) {
var a = document.getElementById(originalElemenyId);

View File

@ -12,7 +12,7 @@
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link href="/css/spotify.css" rel="stylesheet" type="text/css" />
<script src="/lib/jquery/dist/jquery.min.js"></script>
@ -20,8 +20,8 @@
<script src="/js/beeptunes.js"></script>
<script>
$(function () {
$('#musiclink').on('click', function() {
window.location.href = "@Html.Raw($"/musiclink/?p={Model.PoemId}")";
$('#spotify').on('click', function() {
window.location.href = "@Html.Raw($"/spotify/?p={Model.PoemId}")";
});
$('#golha').on('click', function () {
@ -96,8 +96,8 @@
<label for="golha"><a href="@Html.Raw($"/golha/?p={Model.PoemId}")"><img src="/image/golha.png" alt="گلها" height="32" /></a></label>
<input type="radio" id="beeptunes" name="beeptunes" value="بیپ‌تونز" checked>
<label for="beeptunes"><a href="@Html.Raw($"/bp/?p={Model.PoemId}")"><img src="/image/beeptunes.png" alt="بیپ‌تونز" height="32" /></a></label>
<input type="radio" id="musiclink" name="musiclink" value="پیوند آهنگ">
<label for="musiclink"><a href="@Html.Raw($"/musiclink/?p={Model.PoemId}")"><img src="/image/note.png" alt="پیوند آهنگ" height="32" /></a></label>
<input type="radio" id="spotify" name="spotify" value="اسپاتیفای">
<label for="spotify"><a href="@Html.Raw($"/spotify/?p={Model.PoemId}")"><img src="/image/spotify.png" alt="اسپاتیفای" height="32" /></a></label>
</div>
</div>
<p>
@ -117,14 +117,14 @@
@if (suggestedSong.Id == Model.InsertedSongId)
{
<text>
<a target="_blank" href="@suggestedSong.ArtistUrl" style="color:green">@suggestedSong.ArtistName</a> » <a target="_blank" href="@suggestedSong.AlbumUrl" style="color:green">@suggestedSong.AlbumName</a> » <a target="_blank" href="@suggestedSong.TrackUrl" style="color:green">@suggestedSong.TrackName</a>
<a target="_blank" href="@Html.Raw(suggestedSong.ArtistUrl)" style="color:green">@suggestedSong.ArtistName</a> » <a target="_blank" href="@Html.Raw(suggestedSong.AlbumUrl)" style="color:green">@suggestedSong.AlbumName</a> » <a target="_blank" href="@Html.Raw(suggestedSong.TrackUrl)" style="color:green">@suggestedSong.TrackName</a>
</text>
}
else
{
<text>
<a target="_blank" href="@suggestedSong.ArtistUrl">@suggestedSong.ArtistName</a> » <a target="_blank" href="@suggestedSong.AlbumUrl">@suggestedSong.AlbumName</a> » <a target="_blank" href="@suggestedSong.TrackUrl">@suggestedSong.TrackName</a>
<a target="_blank" href="@Html.Raw(suggestedSong.ArtistUrl)">@suggestedSong.ArtistName</a> » <a target="_blank" href="@Html.Raw(suggestedSong.AlbumUrl)">@suggestedSong.AlbumName</a> » <a target="_blank" href="@Html.Raw(suggestedSong.TrackUrl)">@suggestedSong.TrackName</a>
</text>
}

View File

@ -11,14 +11,14 @@
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link href="/css/spotify.css" rel="stylesheet" type="text/css" />
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="~/js/golha.js"></script>
<script>
$(function () {
$('#musiclink').on('click', function() {
window.location.href = "@Html.Raw($"/musiclink/?p={Model.PoemId}")";
$('#spotify').on('click', function() {
window.location.href = "@Html.Raw($"/spotify/?p={Model.PoemId}")";
});
$('#golha').on('click', function () {
@ -87,8 +87,8 @@
<label for="golha"><a href="@Html.Raw($"/golha/?p={Model.PoemId}")"><img src="/image/golha.png" alt="گلها" height="32" /></a></label>
<input type="radio" id="beeptunes" name="beeptunes" value="بیپ‌تونز">
<label for="beeptunes"><a href="@Html.Raw($"/bp/?p={Model.PoemId}")"><img src="/image/beeptunes.png" alt="بیپ‌تونز" height="32" /></a></label>
<input type="radio" id="musiclink" name="musiclink" value="پیوند آهنگ">
<label for="musiclink"><a href="@Html.Raw($"/musiclink/?p={Model.PoemId}")"><img src="/image/note.png" alt="پیوند آهنگ" height="32" /></a></label>
<input type="radio" id="spotify" name="spotify" value="اسپاتیفای">
<label for="spotify"><a href="@Html.Raw($"/spotify/?p={Model.PoemId}")"><img src="/image/spotify.png" alt="اسپاتیفای" height="32" /></a></label>
</div>
</div>
@ -109,14 +109,14 @@
@if (suggestedSong.Id == Model.InsertedSongId)
{
<text>
<a target="_blank" href="@suggestedSong.TrackUrl" style="color:green">@suggestedSong.AlbumName</a> » <a target="_blank" href="@suggestedSong.TrackUrl" style="color:green">@suggestedSong.TrackName</a>
<a target="_blank" href="@Html.Raw(suggestedSong.TrackUrl)" style="color:green">@suggestedSong.AlbumName</a> » <a target="_blank" href="@Html.Raw(suggestedSong.TrackUrl)" style="color:green">@suggestedSong.TrackName</a>
</text>
}
else
{
<text>
<a target="_blank" href="@suggestedSong.TrackUrl">@suggestedSong.AlbumName</a> » <a target="_blank" href="@suggestedSong.TrackUrl">@suggestedSong.TrackName</a>
<a target="_blank" href="@Html.Raw(suggestedSong.TrackUrl)">@suggestedSong.AlbumName</a> » <a target="_blank" href="@Html.Raw(suggestedSong.TrackUrl)">@suggestedSong.TrackName</a>
</text>
}

View File

@ -12,7 +12,7 @@
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link href="/css/spotify.css" rel="stylesheet" type="text/css" />
<script src="/lib/jquery/dist/jquery.min.js"></script>
@ -116,14 +116,14 @@
@if (suggestedSong.Id == Model.InsertedSongId)
{
<text>
<a target="_blank" href="@suggestedSong.ArtistUrl" style="color:green">@suggestedSong.ArtistName</a> » <a target="_blank" href="@suggestedSong.AlbumUrl" style="color:green">@suggestedSong.AlbumName</a> » <a target="_blank" href="@suggestedSong.TrackUrl" style="color:green">@suggestedSong.TrackName</a>
<a target="_blank" href="@Html.Raw(suggestedSong.ArtistUrl)" style="color:green">@suggestedSong.ArtistName</a> » <a target="_blank" href="@Html.Raw(suggestedSong.AlbumUrl)" style="color:green">@suggestedSong.AlbumName</a> » <a target="_blank" href="@Html.Raw(suggestedSong.TrackUrl)" style="color:green">@suggestedSong.TrackName</a>
</text>
}
else
{
<text>
<a target="_blank" href="@suggestedSong.ArtistUrl">@suggestedSong.ArtistName</a> » <a target="_blank" href="@suggestedSong.AlbumUrl">@suggestedSong.AlbumName</a> » <a target="_blank" href="@suggestedSong.TrackUrl">@suggestedSong.TrackName</a>
<a target="_blank" href="@Html.Raw(suggestedSong.ArtistUrl)">@suggestedSong.ArtistName</a> » <a target="_blank" href="@Html.Raw(suggestedSong.AlbumUrl)">@suggestedSong.AlbumName</a> » <a target="_blank" href="@Html.Raw(suggestedSong.TrackUrl)">@suggestedSong.TrackName</a>
</text>
}

View File

@ -13,7 +13,7 @@
<title>
@ViewData["Title"]
</title>
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link rel="search" type="application/opensearchdescription+xml" title="گنجور" href="https://ganjoor.net/search.xml" />

View File

@ -14,7 +14,7 @@
<title>
@ViewData["Title"]
</title>
<link href="/css/p8.css?version=94" rel="stylesheet" type="text/css" />
<link href="/css/p8.css?version=95" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link rel="search" type="application/opensearchdescription+xml" title="گنجور" href="https://ganjoor.net/search.xml" />

View File

@ -1,4 +1,4 @@
@font-face {
@font-face {
font-family: 'Vazirmatn';
src: url('/fonts/Vazirmatn-Regular.woff2') format('woff2');
font-weight: 400;
@ -676,7 +676,6 @@ div.n, div.l {
.m1 p, .m2 p, .b2 p, .n p {
color: inherit;
text-shadow: 0.3px 0.3px grey;
}
@media (max-width: 950px) {
@ -3035,83 +3034,3 @@ mark {
#after-bio {
scroll-margin-top: 50px;
}
/* ---------- sticky mini audio-player (recitation seek controls stay
reachable while scrolling the poem text) ---------- */
.up-sticky-player {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 1000;
display: flex;
align-items: center;
gap: 10px;
padding: 8px 14px;
background: var(--card-inner);
border-top: 1px solid var(--border-gold);
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.15);
}
.up-sticky-player__narrator {
font-weight: 600;
white-space: nowrap;
color: var(--lapis);
flex-shrink: 0;
}
.up-sticky-player__audio-slot {
flex: 1;
min-width: 0;
}
.up-sticky-player__audio-slot audio {
width: 100%;
display: block;
}
.up-sticky-player__lock {
display: inline-flex;
align-items: center;
cursor: pointer;
color: var(--lapis);
padding: 4px 6px;
flex-shrink: 0;
}
.up-sticky-player__lock:hover {
color: var(--brand);
}
.up-sticky-player__jump {
display: inline-flex;
align-items: center;
cursor: pointer;
color: var(--lapis);
padding: 4px 6px;
flex-shrink: 0;
}
.up-sticky-player__jump:hover {
color: var(--brand);
}
.up-sticky-player__close {
display: inline-flex;
align-items: center;
cursor: pointer;
color: var(--lapis);
padding: 4px 6px;
flex-shrink: 0;
}
.up-sticky-player__close:hover {
color: var(--brand);
}
@media (max-width: 600px) {
.up-sticky-player__narrator {
display: none;
}
}

View File

@ -11237,6 +11237,11 @@
https://open.spotify.com/
</summary>
</member>
<member name="F:RMuseum.Models.Ganjoor.PoemMusicTrackType.MusicUrl">
<summary>
user supplied link to any platform accepted by RMuseum.Utils.MusicUrlValidator
</summary>
</member>
<member name="T:RMuseum.Models.Ganjoor.PoemSectionType">
<summary>
poem section type
@ -11341,6 +11346,17 @@
not a redaction pass.
</summary>
</member>
<member name="P:RMuseum.Models.Ganjoor.PublicExport.VersePublicDto.CoupletSummary">
<summary>
AI-generated (prefixed "هوش مصنوعی:", matching PoemSummary's own convention) until a
human reviews/edits it, at which point the prefix is removed — that prefix's
presence/absence is itself the provenance signal, same as for PoemSummary, nothing
new needed here to track it. Published specifically so a human editor's curatorial
work on a couplet's interpretation — genuinely irreplaceable if the live database
were ever lost, unlike the poem text itself, which exists in many other sources —
isn't only ever stored in one place.
</summary>
</member>
<member name="T:RMuseum.Models.Ganjoor.PublicExport.MetrePublicDto">
<summary>
metres.json — shared lookup table written once at the repo root
@ -21694,6 +21710,13 @@
<param name="paging"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.Implementation.GanjoorService._PrepareTrackUrl(RMuseum.Models.Ganjoor.ViewModels.PoemMusicTrackViewModel)">
<summary>
checks a user supplied track and rewrites its url to canonical form, returns null when it is acceptable
</summary>
<param name="song"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.Implementation.GanjoorService.SuggestSong(System.Guid,RMuseum.Models.Ganjoor.ViewModels.PoemMusicTrackViewModel)">
<summary>
suggest song
@ -24383,6 +24406,99 @@
<param name="poemHtml"></param>
<returns></returns>
</member>
<member name="T:RMuseum.Utils.MusicPlatform">
<summary>
a legal music streaming/store platform accepted for poem music track links
</summary>
</member>
<member name="P:RMuseum.Utils.MusicPlatform.Key">
<summary>
stable identifier
</summary>
</member>
<member name="P:RMuseum.Utils.MusicPlatform.Name">
<summary>
display name (Persian)
</summary>
</member>
<member name="P:RMuseum.Utils.MusicPlatform.IconUrl">
<summary>
16px icon path, null when no artwork is available yet
</summary>
</member>
<member name="P:RMuseum.Utils.MusicPlatform.LargeIconUrl">
<summary>
32px icon path, null when no artwork is available yet
</summary>
</member>
<member name="P:RMuseum.Utils.MusicPlatform.OEmbedEndpoint">
<summary>
oEmbed endpoint accepting a ?url= parameter, null when the platform has none
</summary>
</member>
<member name="P:RMuseum.Utils.MusicPlatform.Hosts">
<summary>
accepted hosts, each matching itself and its subdomains
</summary>
</member>
<member name="P:RMuseum.Utils.MusicPlatform.HostPattern">
<summary>
accepted host pattern, used where the host varies by country
</summary>
</member>
<member name="M:RMuseum.Utils.MusicPlatform.MatchesHost(System.String)">
<summary>
does the given lowercased host belong to this platform?
</summary>
<param name="host"></param>
<returns></returns>
</member>
<member name="T:RMuseum.Utils.MusicUrlValidator">
<summary>
validates user supplied music links against an allow-list of legal music platforms
</summary>
</member>
<member name="F:RMuseum.Utils.MusicUrlValidator.MaxUrlLength">
<summary>
maximum accepted url length
</summary>
</member>
<member name="F:RMuseum.Utils.MusicUrlValidator.Platforms">
<summary>
accepted platforms, ordered so that more specific hosts win (YouTube Music before YouTube)
</summary>
<remarks>
IconUrl/LargeIconUrl are only set for platforms whose artwork already exists under
GanjooRazor/wwwroot/image; drop a {Key}16.png/{Key}.png pair in image/music and fill them in.
</remarks>
</member>
<member name="F:RMuseum.Utils.MusicUrlValidator._trackingParameters">
<summary>
query parameters dropped during normalization so that the same track always yields the same url
</summary>
</member>
<member name="P:RMuseum.Utils.MusicUrlValidator.PlatformNames">
<summary>
comma separated platform names, for user facing messages
</summary>
</member>
<member name="M:RMuseum.Utils.MusicUrlValidator.TryNormalize(System.String,System.String@,RMuseum.Utils.MusicPlatform@,System.String@)">
<summary>
validate a user supplied music url and rewrite it to its canonical form
</summary>
<param name="url"></param>
<param name="normalizedUrl"></param>
<param name="platform"></param>
<param name="error">Persian error message when validation fails</param>
<returns></returns>
</member>
<member name="M:RMuseum.Utils.MusicUrlValidator.Detect(System.String)">
<summary>
platform of an already stored url, null when it belongs to none of the accepted platforms
</summary>
<param name="url"></param>
<returns></returns>
</member>
<member name="T:RMuseum.Utils.PublicDataExport.DeterministicJsonWriter">
<summary>
Writes JSON in a way that is stable across runs: fixed indentation, LF line endings,