mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
added a new MusicGenre entity
This commit is contained in:
parent
94e6446003
commit
b267c433c3
6 changed files with 216 additions and 8 deletions
153
ApiClient.js
153
ApiClient.js
|
@ -1152,6 +1152,27 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.getMusicGenre = function (name, userId) {
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
throw new Error("null name");
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = {};
|
||||||
|
|
||||||
|
if (userId) {
|
||||||
|
options.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = self.getUrl("MusicGenres/" + self.encodeName(name), options);
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: url,
|
||||||
|
dataType: "json"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an artist
|
* Gets an artist
|
||||||
*/
|
*/
|
||||||
|
@ -1424,6 +1445,41 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
||||||
return self.getUrl(url, options);
|
return self.getUrl(url, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a url for a genre image
|
||||||
|
* @param {String} name
|
||||||
|
* @param {Object} options
|
||||||
|
* Options supports the following properties:
|
||||||
|
* width - download the image at a fixed width
|
||||||
|
* height - download the image at a fixed height
|
||||||
|
* maxWidth - download the image at a maxWidth
|
||||||
|
* maxHeight - download the image at a maxHeight
|
||||||
|
* quality - A scale of 0-100. This should almost always be omitted as the default will suffice.
|
||||||
|
* For best results do not specify both width and height together, as aspect ratio might be altered.
|
||||||
|
*/
|
||||||
|
self.getMusicGenreImageUrl = function (name, options) {
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
throw new Error("null name");
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var url = "MusicGenres/" + self.encodeName(name) + "/Images/" + options.type;
|
||||||
|
|
||||||
|
if (options.index != null) {
|
||||||
|
url += "/" + options.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't put these on the query string
|
||||||
|
delete options.type;
|
||||||
|
delete options.index;
|
||||||
|
|
||||||
|
return self.getUrl(url, options);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a url for a artist image
|
* Constructs a url for a artist image
|
||||||
* @param {String} name
|
* @param {String} name
|
||||||
|
@ -1910,6 +1966,24 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.getMusicGenres = function (userId, options) {
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
throw new Error("null userId");
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
options.userId = userId;
|
||||||
|
|
||||||
|
var url = self.getUrl("MusicGenres", options);
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: url,
|
||||||
|
dataType: "json"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Gets people from an item
|
Gets people from an item
|
||||||
*/
|
*/
|
||||||
|
@ -2217,6 +2291,26 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.updateFavoriteMusicGenreStatus = function (userId, name, isFavorite) {
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
throw new Error("null userId");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
throw new Error("null name");
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = self.getUrl("Users/" + userId + "/Favorites/MusicGenres/" + self.encodeName(name));
|
||||||
|
|
||||||
|
var method = isFavorite ? "POST" : "DELETE";
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: method,
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a user's rating for an item by name.
|
* Updates a user's rating for an item by name.
|
||||||
* @param {String} userId
|
* @param {String} userId
|
||||||
|
@ -2303,6 +2397,26 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.updateMusicGenreRating = function (userId, name, likes) {
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
throw new Error("null userId");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
throw new Error("null name");
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = self.getUrl("Users/" + userId + "/Ratings/MusicGenres/" + self.encodeName(name), {
|
||||||
|
likes: likes
|
||||||
|
});
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears a user's rating for an item by name.
|
* Clears a user's rating for an item by name.
|
||||||
* @param {String} userId
|
* @param {String} userId
|
||||||
|
@ -2380,6 +2494,24 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.clearMusicGenreRating = function (userId, name) {
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
throw new Error("null userId");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
throw new Error("null name");
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = self.getUrl("Users/" + userId + "/Ratings/MusicGenres/" + self.encodeName(name));
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "DELETE",
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
self.getItemCounts = function (userId) {
|
self.getItemCounts = function (userId) {
|
||||||
|
|
||||||
var options = {};
|
var options = {};
|
||||||
|
@ -2445,6 +2577,27 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.getMusicGenreItemCounts = function (userId, name) {
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
throw new Error("null userId");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
throw new Error("null name");
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = self.getUrl("MusicGenres/" + self.encodeName(name) + "/Counts", {
|
||||||
|
userId: userId
|
||||||
|
});
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: url,
|
||||||
|
dataType: "json"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Gets a variety of item counts that an artist appears in
|
Gets a variety of item counts that an artist appears in
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,6 +25,12 @@
|
||||||
return ApiClient.getGenre(name, Dashboard.getCurrentUserId());
|
return ApiClient.getGenre(name, Dashboard.getCurrentUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = getParameterByName('musicgenre');
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
return ApiClient.getMusicGenre(name, Dashboard.getCurrentUserId());
|
||||||
|
}
|
||||||
|
|
||||||
name = getParameterByName('artist');
|
name = getParameterByName('artist');
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
|
@ -103,7 +109,7 @@
|
||||||
$('#tvPeopleTabs', page).show();
|
$('#tvPeopleTabs', page).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context == "music" && item.Type == "Genre") {
|
if (context == "music" && item.Type == "MusicGenre") {
|
||||||
$('#musicGenreTabs', page).show();
|
$('#musicGenreTabs', page).show();
|
||||||
}
|
}
|
||||||
if (context == "music" && item.Type == "Artist") {
|
if (context == "music" && item.Type == "Artist") {
|
||||||
|
@ -127,6 +133,9 @@
|
||||||
else if (item.Type == "Genre") {
|
else if (item.Type == "Genre") {
|
||||||
promise = ApiClient.getGenreItemCounts(Dashboard.getCurrentUserId(), item.Name);
|
promise = ApiClient.getGenreItemCounts(Dashboard.getCurrentUserId(), item.Name);
|
||||||
}
|
}
|
||||||
|
else if (item.Type == "MusicGenre") {
|
||||||
|
promise = ApiClient.getMusicGenreItemCounts(Dashboard.getCurrentUserId(), item.Name);
|
||||||
|
}
|
||||||
else if (item.Type == "Studio") {
|
else if (item.Type == "Studio") {
|
||||||
promise = ApiClient.getStudioItemCounts(Dashboard.getCurrentUserId(), item.Name);
|
promise = ApiClient.getStudioItemCounts(Dashboard.getCurrentUserId(), item.Name);
|
||||||
}
|
}
|
||||||
|
@ -361,6 +370,9 @@
|
||||||
else if (currentItem.Type == "Genre") {
|
else if (currentItem.Type == "Genre") {
|
||||||
query.Genres = currentItem.Name;
|
query.Genres = currentItem.Name;
|
||||||
}
|
}
|
||||||
|
else if (currentItem.Type == "MusicGenre") {
|
||||||
|
query.Genres = currentItem.Name;
|
||||||
|
}
|
||||||
else if (currentItem.Type == "Studio") {
|
else if (currentItem.Type == "Studio") {
|
||||||
query.Studios = currentItem.Name;
|
query.Studios = currentItem.Name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
imgUrl = "css/images/items/list/game.png";
|
imgUrl = "css/images/items/list/game.png";
|
||||||
isDefault = true;
|
isDefault = true;
|
||||||
}
|
}
|
||||||
else if (item.Type == "Studio" || item.Type == "Genre") {
|
else if (item.Type == "Studio" || item.Type == "Genre" || item.Type == "MusicGenre") {
|
||||||
|
|
||||||
if (options.context == "games") {
|
if (options.context == "games") {
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@
|
||||||
|
|
||||||
html += '<p class="itemMiscInfo">' + childText + '</p>';
|
html += '<p class="itemMiscInfo">' + childText + '</p>';
|
||||||
}
|
}
|
||||||
else if (item.Type == "Genre" || item.Type == "Studio" || item.Type == "Person" || item.Type == "Artist") {
|
else if (item.Type == "Genre" || item.Type == "Studio" || item.Type == "Person" || item.Type == "Artist" || item.Type == "MusicGenre") {
|
||||||
|
|
||||||
childText = item.ChildCount == 1 ? "1 " + options.countNameSingular : item.ChildCount + " " + options.countNamePlural;
|
childText = item.ChildCount == 1 ? "1 " + options.countNameSingular : item.ChildCount + " " + options.countNamePlural;
|
||||||
|
|
||||||
|
@ -366,6 +366,9 @@
|
||||||
if (item.Type == "Genre") {
|
if (item.Type == "Genre") {
|
||||||
return "itembynamedetails.html?genre=" + ApiClient.encodeName(item.Name) + "&context=" + itemByNameContext;
|
return "itembynamedetails.html?genre=" + ApiClient.encodeName(item.Name) + "&context=" + itemByNameContext;
|
||||||
}
|
}
|
||||||
|
if (item.Type == "MusicGenre") {
|
||||||
|
return "itembynamedetails.html?musicgenre=" + ApiClient.encodeName(item.Name) + "&context=" + itemByNameContext;
|
||||||
|
}
|
||||||
if (item.Type == "Studio") {
|
if (item.Type == "Studio") {
|
||||||
return "itembynamedetails.html?studio=" + ApiClient.encodeName(item.Name) + "&context=" + itemByNameContext;
|
return "itembynamedetails.html?studio=" + ApiClient.encodeName(item.Name) + "&context=" + itemByNameContext;
|
||||||
}
|
}
|
||||||
|
@ -411,6 +414,10 @@
|
||||||
|
|
||||||
return ApiClient.getGenreImageUrl(item.Name, options);
|
return ApiClient.getGenreImageUrl(item.Name, options);
|
||||||
}
|
}
|
||||||
|
if (item.Type == "MusicGenre") {
|
||||||
|
|
||||||
|
return ApiClient.getMusicGenreImageUrl(item.Name, options);
|
||||||
|
}
|
||||||
if (item.Type == "Artist") {
|
if (item.Type == "Artist") {
|
||||||
|
|
||||||
return ApiClient.getArtistImageUrl(item.Name, options);
|
return ApiClient.getArtistImageUrl(item.Name, options);
|
||||||
|
@ -597,7 +604,7 @@
|
||||||
return '<div class="posterRibbon">' + item.RecentlyAddedItemCount + ' New</div>';
|
return '<div class="posterRibbon">' + item.RecentlyAddedItemCount + ' New</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item.IsFolder && item.Type !== "Genre" && item.Type !== "Studio" && item.Type !== "Person" && item.Type !== "Artist") {
|
if (!item.IsFolder && item.Type !== "Genre" && item.Type !== "Studio" && item.Type !== "Person" && item.Type !== "Artist" && item.Type !== "MusicGenre") {
|
||||||
|
|
||||||
var date = item.DateCreated;
|
var date = item.DateCreated;
|
||||||
|
|
||||||
|
@ -949,6 +956,9 @@
|
||||||
else if (type == "Genre") {
|
else if (type == "Genre") {
|
||||||
itemId = item.Name;
|
itemId = item.Name;
|
||||||
}
|
}
|
||||||
|
else if (type == "MusicGenre") {
|
||||||
|
itemId = item.Name;
|
||||||
|
}
|
||||||
else if (type == "Artist") {
|
else if (type == "Artist") {
|
||||||
itemId = item.Name;
|
itemId = item.Name;
|
||||||
}
|
}
|
||||||
|
@ -1023,6 +1033,9 @@
|
||||||
else if (type == "Genre") {
|
else if (type == "Genre") {
|
||||||
ApiClient.updateFavoriteGenreStatus(Dashboard.getCurrentUserId(), id, markAsFavorite);
|
ApiClient.updateFavoriteGenreStatus(Dashboard.getCurrentUserId(), id, markAsFavorite);
|
||||||
}
|
}
|
||||||
|
else if (type == "MusicGenre") {
|
||||||
|
ApiClient.updateFavoriteMusicGenreStatus(Dashboard.getCurrentUserId(), id, markAsFavorite);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
ApiClient.updateFavoriteStatus(Dashboard.getCurrentUserId(), id, markAsFavorite);
|
ApiClient.updateFavoriteStatus(Dashboard.getCurrentUserId(), id, markAsFavorite);
|
||||||
}
|
}
|
||||||
|
@ -1104,6 +1117,9 @@
|
||||||
else if (type == "Genre") {
|
else if (type == "Genre") {
|
||||||
ApiClient.updateGenreRating(Dashboard.getCurrentUserId(), id, likes);
|
ApiClient.updateGenreRating(Dashboard.getCurrentUserId(), id, likes);
|
||||||
}
|
}
|
||||||
|
else if (type == "MusicGenre") {
|
||||||
|
ApiClient.updateMusicGenreRating(Dashboard.getCurrentUserId(), id, likes);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
ApiClient.updateUserItemRating(Dashboard.getCurrentUserId(), id, likes);
|
ApiClient.updateUserItemRating(Dashboard.getCurrentUserId(), id, likes);
|
||||||
}
|
}
|
||||||
|
@ -1123,6 +1139,9 @@
|
||||||
else if (type == "Genre") {
|
else if (type == "Genre") {
|
||||||
ApiClient.clearGenreRating(Dashboard.getCurrentUserId(), id);
|
ApiClient.clearGenreRating(Dashboard.getCurrentUserId(), id);
|
||||||
}
|
}
|
||||||
|
else if (type == "MusicGenre") {
|
||||||
|
ApiClient.clearMusicGenreRating(Dashboard.getCurrentUserId(), id);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
ApiClient.clearUserItemRating(Dashboard.getCurrentUserId(), id);
|
ApiClient.clearUserItemRating(Dashboard.getCurrentUserId(), id);
|
||||||
}
|
}
|
||||||
|
@ -1152,6 +1171,13 @@
|
||||||
type: "Primary"
|
type: "Primary"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (item.Type == "MusicGenre") {
|
||||||
|
url = ApiClient.getMusicGenreImageUrl(item.Name, {
|
||||||
|
maxheight: 480,
|
||||||
|
tag: imageTags.Primary,
|
||||||
|
type: "Primary"
|
||||||
|
});
|
||||||
|
}
|
||||||
else if (item.Type == "Studio") {
|
else if (item.Type == "Studio") {
|
||||||
url = ApiClient.getStudioImageUrl(item.Name, {
|
url = ApiClient.getStudioImageUrl(item.Name, {
|
||||||
maxheight: 480,
|
maxheight: 480,
|
||||||
|
@ -1190,6 +1216,13 @@
|
||||||
type: "Backdrop"
|
type: "Backdrop"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (item.Type == "MusicGenre") {
|
||||||
|
url = ApiClient.getMusicGenreImageUrl(item.Name, {
|
||||||
|
maxheight: 480,
|
||||||
|
tag: item.BackdropImageTags[0],
|
||||||
|
type: "Backdrop"
|
||||||
|
});
|
||||||
|
}
|
||||||
else if (item.Type == "Studio") {
|
else if (item.Type == "Studio") {
|
||||||
url = ApiClient.getStudioImageUrl(item.Name, {
|
url = ApiClient.getStudioImageUrl(item.Name, {
|
||||||
maxheight: 480,
|
maxheight: 480,
|
||||||
|
@ -1228,6 +1261,13 @@
|
||||||
type: "Thumb"
|
type: "Thumb"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (item.Type == "MusicGenre") {
|
||||||
|
url = ApiClient.getMusicGenreImageUrl(item.Name, {
|
||||||
|
maxheight: 480,
|
||||||
|
tag: imageTags.Thumb,
|
||||||
|
type: "Thumb"
|
||||||
|
});
|
||||||
|
}
|
||||||
else if (item.Type == "Studio") {
|
else if (item.Type == "Studio") {
|
||||||
url = ApiClient.getStudioImageUrl(item.Name, {
|
url = ApiClient.getStudioImageUrl(item.Name, {
|
||||||
maxheight: 480,
|
maxheight: 480,
|
||||||
|
@ -1267,7 +1307,7 @@
|
||||||
else if (item.Type == "Person") {
|
else if (item.Type == "Person") {
|
||||||
url = "css/images/items/detail/person.png";
|
url = "css/images/items/detail/person.png";
|
||||||
}
|
}
|
||||||
else if (item.Type == "Genre" || item.Type == "Studio") {
|
else if (item.Type == "Genre" || item.Type == "Studio" || item.Type == "MusicGenre") {
|
||||||
url = "css/images/items/detail/video.png";
|
url = "css/images/items/detail/video.png";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1277,7 +1317,7 @@
|
||||||
var identifierName = "id";
|
var identifierName = "id";
|
||||||
var identifierValue = item.Id;
|
var identifierValue = item.Id;
|
||||||
|
|
||||||
if (item.Type == "Person" || item.Type == "Genre" || item.Type == "Studio" || item.Type == "Artist") {
|
if (item.Type == "Person" || item.Type == "Genre" || item.Type == "Studio" || item.Type == "Artist" || item.Type == "MusicGenre") {
|
||||||
identifierName = item.Type;
|
identifierName = item.Type;
|
||||||
identifierValue = ApiClient.encodeName(item.Name);
|
identifierValue = ApiClient.encodeName(item.Name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
Dashboard.showLoadingMsg();
|
Dashboard.showLoadingMsg();
|
||||||
|
|
||||||
ApiClient.getGenres(Dashboard.getCurrentUserId(), query).done(function (result) {
|
ApiClient.getMusicGenres(Dashboard.getCurrentUserId(), query).done(function (result) {
|
||||||
|
|
||||||
// Scroll back up so they can see the results from the beginning
|
// Scroll back up so they can see the results from the beginning
|
||||||
$(document).scrollTop(0);
|
$(document).scrollTop(0);
|
||||||
|
|
|
@ -910,6 +910,9 @@ var Dashboard = {
|
||||||
if (type == "genre") {
|
if (type == "genre") {
|
||||||
url = "itembynamedetails.html?genre=" + ApiClient.encodeName(cmd.ItemName) + "&context=" + context;
|
url = "itembynamedetails.html?genre=" + ApiClient.encodeName(cmd.ItemName) + "&context=" + context;
|
||||||
}
|
}
|
||||||
|
else if (type == "musicgenre") {
|
||||||
|
url = "itembynamedetails.html?musicgenre=" + ApiClient.encodeName(cmd.ItemName) + "&context=" + (context || "music");
|
||||||
|
}
|
||||||
else if (type == "studio") {
|
else if (type == "studio") {
|
||||||
url = "itembynamedetails.html?studio=" + ApiClient.encodeName(cmd.ItemName) + "&context=" + context;
|
url = "itembynamedetails.html?studio=" + ApiClient.encodeName(cmd.ItemName) + "&context=" + context;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.122" targetFramework="net45" />
|
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.123" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Common" version="3.9.46" targetFramework="net45" />
|
<package id="ServiceStack.Common" version="3.9.46" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Text" version="3.9.45" targetFramework="net45" />
|
<package id="ServiceStack.Text" version="3.9.45" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
Loading…
Add table
Add a link
Reference in a new issue