optimize code
@@ -26,44 +26,11 @@ from tidal_dl.lang.language import setLang, initLang, getLangChoicePrint
|
||||
from tidal_dl.printf import Printf, VERSION
|
||||
from tidal_dl.settings import Settings, TokenSettings, getLogPath
|
||||
from tidal_dl.tidal import TidalAPI
|
||||
from tidal_dl.util import API
|
||||
from tidal_dl.util import API, CONF, TOKEN, LANG, displayTime, loginByConfig, loginByWeb
|
||||
import tidal_dl.apiKey as apiKey
|
||||
|
||||
ssl._create_default_https_context = ssl._create_unverified_context
|
||||
|
||||
TOKEN = TokenSettings.read()
|
||||
CONF = Settings.read()
|
||||
LANG = initLang(CONF.language)
|
||||
API.apiKey = apiKey.getItem(CONF.apiKeyIndex)
|
||||
|
||||
logging.basicConfig(filename=getLogPath(),
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s: %(message)s')
|
||||
|
||||
|
||||
def displayTime(seconds, granularity=2):
|
||||
if seconds <= 0:
|
||||
return "unknown"
|
||||
|
||||
result = []
|
||||
intervals = (
|
||||
('weeks', 604800),
|
||||
('days', 86400),
|
||||
('hours', 3600),
|
||||
('minutes', 60),
|
||||
('seconds', 1),
|
||||
)
|
||||
|
||||
for name, count in intervals:
|
||||
value = seconds // count
|
||||
if value:
|
||||
seconds -= value * count
|
||||
if value == 1:
|
||||
name = name.rstrip('s')
|
||||
result.append("{} {}".format(value, name))
|
||||
return ', '.join(result[:granularity])
|
||||
|
||||
|
||||
def login():
|
||||
print(LANG.AUTH_START_LOGIN)
|
||||
msg, check = API.getDeviceCode()
|
||||
@@ -74,29 +41,7 @@ def login():
|
||||
# print(LANG.AUTH_LOGIN_CODE.format(green(API.key.userCode)))
|
||||
print(LANG.AUTH_NEXT_STEP.format(green("http://" + API.key.verificationUrl + "/" + API.key.userCode), yellow(displayTime(API.key.authCheckTimeout))))
|
||||
print(LANG.AUTH_WAITING)
|
||||
start = time.time()
|
||||
elapsed = 0
|
||||
while elapsed < API.key.authCheckTimeout:
|
||||
elapsed = time.time() - start
|
||||
# print("Check auth status...")
|
||||
msg, check = API.checkAuthStatus()
|
||||
if not check:
|
||||
if msg == "pending":
|
||||
time.sleep(API.key.authCheckInterval + 1)
|
||||
continue
|
||||
Printf.err(msg)
|
||||
break
|
||||
if check:
|
||||
Printf.success(LANG.MSG_VALID_ACCESSTOKEN.format(displayTime(int(API.key.expiresIn))))
|
||||
TOKEN.userid = API.key.userId
|
||||
TOKEN.countryCode = API.key.countryCode
|
||||
TOKEN.accessToken = API.key.accessToken
|
||||
TOKEN.refreshToken = API.key.refreshToken
|
||||
TOKEN.expiresAfter = time.time() + int(API.key.expiresIn)
|
||||
TokenSettings.save(TOKEN)
|
||||
break
|
||||
if elapsed >= API.key.authCheckTimeout:
|
||||
Printf.err(LANG.AUTH_TIMEOUT)
|
||||
loginByWeb()
|
||||
return
|
||||
|
||||
|
||||
@@ -139,33 +84,13 @@ def setAPIKey():
|
||||
|
||||
|
||||
def checkLogin():
|
||||
if not isNull(TOKEN.accessToken):
|
||||
# print('Checking Access Token...') #add to translations
|
||||
msg, check = API.verifyAccessToken(TOKEN.accessToken)
|
||||
if check:
|
||||
Printf.info(LANG.MSG_VALID_ACCESSTOKEN.format(displayTime(int(TOKEN.expiresAfter - time.time()))))
|
||||
return
|
||||
else:
|
||||
Printf.info(LANG.MSG_INVAILD_ACCESSTOKEN)
|
||||
msg, check = API.refreshAccessToken(TOKEN.refreshToken)
|
||||
if check:
|
||||
Printf.success(LANG.MSG_VALID_ACCESSTOKEN.format(displayTime(int(API.key.expiresIn))))
|
||||
TOKEN.userid = API.key.userId
|
||||
TOKEN.countryCode = API.key.countryCode
|
||||
TOKEN.accessToken = API.key.accessToken
|
||||
TOKEN.expiresAfter = time.time() + int(API.key.expiresIn)
|
||||
TokenSettings.save(TOKEN)
|
||||
return
|
||||
else:
|
||||
Printf.err(msg)
|
||||
tmp = TokenSettings() # clears saved tokens
|
||||
TokenSettings.save(tmp)
|
||||
if loginByConfig():
|
||||
return
|
||||
login()
|
||||
return
|
||||
|
||||
|
||||
def checkLogout():
|
||||
global LANG
|
||||
login()
|
||||
return
|
||||
|
||||
|
||||
@@ -22,396 +22,13 @@ from tidal_dl.model import Track, Video, Lyrics, Mix
|
||||
from tidal_dl.printf import Printf
|
||||
from tidal_dl.settings import Settings
|
||||
from tidal_dl.tidal import TidalAPI
|
||||
from tidal_dl.util import getVideoPath, getTrackPath, getAlbumPath, getArtistsName, convertToM4a, setMetaData, \
|
||||
isNeedDownload, API, getLyricsFromGemius
|
||||
from tidal_dl.util import convert, downloadTrack, downloadVideo, encrypted, getVideoPath, getTrackPath, getAlbumPath, API
|
||||
|
||||
|
||||
def __loadAPI__(user):
|
||||
API.key.accessToken = user.accessToken
|
||||
API.key.userId = user.userid
|
||||
API.key.countryCode = user.countryCode
|
||||
# API.key.sessionId = user.sessionid1
|
||||
|
||||
|
||||
def __loadVideoAPI__(user):
|
||||
API.key.accessToken = user.accessToken
|
||||
API.key.userId = user.userid
|
||||
API.key.countryCode = user.countryCode
|
||||
# API.key.sessionId = user.sessionid2 if not aigpy.string.isNull(user.sessionid2) else user.sessionid1
|
||||
|
||||
|
||||
# def __getIndexStr__(index):
|
||||
# pre = "0"
|
||||
# if index < 10:
|
||||
# return pre + str(index)
|
||||
# if index < 99:
|
||||
# return str(index)
|
||||
# return str(index)
|
||||
|
||||
|
||||
# def __getExtension__(url):
|
||||
# if '.flac' in url:
|
||||
# return '.flac'
|
||||
# if '.mp4' in url:
|
||||
# return '.mp4'
|
||||
# return '.m4a'
|
||||
|
||||
|
||||
# def __getArtists__(array):
|
||||
# ret = []
|
||||
# for item in array:
|
||||
# ret.append(item.name)
|
||||
# return ret
|
||||
|
||||
|
||||
# def __getArtistsString__(artists):
|
||||
# return ", ".join(map(lambda artist: artist.name, artists))
|
||||
|
||||
|
||||
# def __parseContributors__(roleType, Contributors):
|
||||
# if Contributors is None:
|
||||
# return None
|
||||
# try:
|
||||
# ret = []
|
||||
# for item in Contributors['items']:
|
||||
# if item['role'] == roleType:
|
||||
# ret.append(item['name'])
|
||||
# return ret
|
||||
# except:
|
||||
# return None
|
||||
|
||||
|
||||
# GEMIUS = lyricsgenius.Genius('vNKbAWAE3rVY_48nRaiOrDcWNLvsxS-Z8qyG5XfEzTOtZvkTfg6P3pxOVlA2BjaW')
|
||||
#
|
||||
#
|
||||
# def __getLyrics__(trackName, artistName, proxy):
|
||||
# try:
|
||||
# if not aigpy.string.isNull(proxy):
|
||||
# GEMIUS._session.proxies = {
|
||||
# 'http': f'http://{proxy}',
|
||||
# 'https': f'http://{proxy}',
|
||||
# }
|
||||
#
|
||||
# song = GEMIUS.search_song(trackName, artistName)
|
||||
# return song.lyrics
|
||||
# except:
|
||||
# return ""
|
||||
|
||||
#
|
||||
# def __setMetaData__(track, album, filepath, contributors, lyrics):
|
||||
# obj = aigpy.tag.TagTool(filepath)
|
||||
# obj.album = track.album.title
|
||||
# obj.title = track.title
|
||||
# if not aigpy.string.isNull(track.version):
|
||||
# obj.title += ' (' + track.version + ')'
|
||||
#
|
||||
# obj.artist = map(lambda artist: artist.name, track.artists) # __getArtists__(track.artists)
|
||||
# obj.copyright = track.copyRight
|
||||
# obj.tracknumber = track.trackNumber
|
||||
# obj.discnumber = track.volumeNumber
|
||||
# obj.composer = __parseContributors__('Composer', contributors)
|
||||
# obj.isrc = track.isrc
|
||||
#
|
||||
# obj.albumartist = map(lambda artist: artist.name, album.artists) #__getArtists__(album.artists)
|
||||
# obj.date = album.releaseDate
|
||||
# obj.totaldisc = album.numberOfVolumes
|
||||
# obj.lyrics = lyrics
|
||||
# if obj.totaldisc <= 1:
|
||||
# obj.totaltrack = album.numberOfTracks
|
||||
# coverpath = API.getCoverUrl(album.cover, "1280", "1280")
|
||||
# obj.save(coverpath)
|
||||
# return
|
||||
|
||||
|
||||
# def __convertToM4a__(filepath, codec):
|
||||
# if 'ac4' in codec or 'mha1' in codec:
|
||||
# return filepath
|
||||
# if '.mp4' not in filepath:
|
||||
# return filepath
|
||||
# newpath = filepath.replace('.mp4', '.m4a')
|
||||
# aigpy.path.remove(newpath)
|
||||
# os.rename(filepath, newpath)
|
||||
# return newpath
|
||||
|
||||
|
||||
# def __stripPathParts__(stripped_path, separator):
|
||||
# result = ""
|
||||
# stripped_path = stripped_path.split(separator)
|
||||
# for stripped_path_part in stripped_path:
|
||||
# result += stripped_path_part.strip()
|
||||
# if not stripped_path.index(stripped_path_part) == len(stripped_path) - 1:
|
||||
# result += separator
|
||||
# return result.strip()
|
||||
#
|
||||
#
|
||||
# def __stripPath__(path):
|
||||
# result = __stripPathParts__(path, "/")
|
||||
# result = __stripPathParts__(result, "\\")
|
||||
# return result.strip()
|
||||
|
||||
# "{ArtistName}/{Flag} [{AlbumID}] [{AlbumYear}] {AlbumTitle}"
|
||||
# def getAlbumPath(conf: Settings, album):
|
||||
# base = conf.downloadPath + '/Album/'
|
||||
# artist = aigpy.path.replaceLimitChar(__getArtistsString__(album.artists), '-')
|
||||
# # album folder pre: [ME][ID]
|
||||
# flag = API.getFlag(album, Type.Album, True, "")
|
||||
# if conf.audioQuality != AudioQuality.Master:
|
||||
# flag = flag.replace("M", "")
|
||||
# if not conf.addExplicitTag:
|
||||
# flag = flag.replace("E", "")
|
||||
# if not aigpy.string.isNull(flag):
|
||||
# flag = "[" + flag + "] "
|
||||
#
|
||||
# sid = str(album.id)
|
||||
# # album and addyear
|
||||
# albumname = aigpy.path.replaceLimitChar(album.title, '-')
|
||||
# year = ""
|
||||
# if album.releaseDate is not None:
|
||||
# year = aigpy.string.getSubOnlyEnd(album.releaseDate, '-')
|
||||
# # retpath
|
||||
# retpath = conf.albumFolderFormat
|
||||
# if retpath is None or len(retpath) <= 0:
|
||||
# retpath = Settings.getDefaultAlbumFolderFormat()
|
||||
# retpath = retpath.replace(R"{ArtistName}", artist.strip())
|
||||
# retpath = retpath.replace(R"{Flag}", flag)
|
||||
# retpath = retpath.replace(R"{AlbumID}", sid)
|
||||
# retpath = retpath.replace(R"{AlbumYear}", year)
|
||||
# retpath = retpath.replace(R"{AlbumTitle}", albumname.strip())
|
||||
# retpath = __stripPath__(retpath.strip())
|
||||
# return base + retpath
|
||||
#
|
||||
#
|
||||
# def __getAlbumPath2__(conf, album):
|
||||
# # outputdir/Album/artist/
|
||||
# artist = aigpy.path.replaceLimitChar(__getArtistsString__(album.artists), '-').strip()
|
||||
# base = conf.downloadPath + '/Album/' + artist + '/'
|
||||
#
|
||||
# # album folder pre: [ME][ID]
|
||||
# flag = API.getFlag(album, Type.Album, True, "")
|
||||
# if conf.audioQuality != AudioQuality.Master:
|
||||
# flag = flag.replace("M", "")
|
||||
# if not conf.addExplicitTag:
|
||||
# flag = flag.replace("E", "")
|
||||
# if not aigpy.string.isNull(flag):
|
||||
# flag = "[" + flag + "] "
|
||||
#
|
||||
# sid = "[" + str(album.id) + "] " if conf.addAlbumIDBeforeFolder else ""
|
||||
#
|
||||
# # album and addyear
|
||||
# albumname = aigpy.path.replaceLimitChar(album.title, '-').strip()
|
||||
# year = ""
|
||||
# if conf.addYear and album.releaseDate is not None:
|
||||
# year = "[" + aigpy.string.getSubOnlyEnd(album.releaseDate, '-') + "] "
|
||||
# return base + flag + sid + year + albumname + '/'
|
||||
#
|
||||
#
|
||||
# def getPlaylistPath(conf, playlist):
|
||||
# # outputdir/Playlist/
|
||||
# base = conf.downloadPath + '/Playlist/'
|
||||
# # name
|
||||
# name = aigpy.path.replaceLimitChar(playlist.title, '-')
|
||||
# return base + name + '/'
|
||||
#
|
||||
#
|
||||
# # "{TrackNumber} - {ArtistName} - {TrackTitle}{ExplicitFlag}"
|
||||
#
|
||||
#
|
||||
# def getTrackPath(conf: Settings, track, stream, album=None, playlist=None):
|
||||
# if album is not None:
|
||||
# base = getAlbumPath(conf, album) + '/'
|
||||
# if album.numberOfVolumes > 1:
|
||||
# base += 'CD' + str(track.volumeNumber) + '/'
|
||||
# if playlist is not None and conf.usePlaylistFolder:
|
||||
# base = getPlaylistPath(conf, playlist)
|
||||
# # number
|
||||
# number = __getIndexStr__(track.trackNumber)
|
||||
# if playlist is not None and conf.usePlaylistFolder:
|
||||
# number = __getIndexStr__(track.trackNumberOnPlaylist)
|
||||
# # artist
|
||||
# artist = aigpy.path.replaceLimitChar(__getArtistsString__(track.artists), '-')
|
||||
# # title
|
||||
# title = track.title
|
||||
# if not aigpy.string.isNull(track.version):
|
||||
# title += ' (' + track.version + ')'
|
||||
# title = aigpy.path.replaceLimitChar(title, '-')
|
||||
# # get explicit
|
||||
# explicit = "(Explicit)" if conf.addExplicitTag and track.explicit else ''
|
||||
# # album and addyear
|
||||
# albumname = aigpy.path.replaceLimitChar(album.title, '-')
|
||||
# year = ""
|
||||
# if album.releaseDate is not None:
|
||||
# year = aigpy.string.getSubOnlyEnd(album.releaseDate, '-')
|
||||
# # extension
|
||||
# extension = __getExtension__(stream.url)
|
||||
# retpath = conf.trackFileFormat
|
||||
# if retpath is None or len(retpath) <= 0:
|
||||
# retpath = Settings.getDefaultTrackFileFormat()
|
||||
# retpath = retpath.replace(R"{TrackNumber}", number)
|
||||
# retpath = retpath.replace(R"{ArtistName}", artist.strip())
|
||||
# retpath = retpath.replace(R"{TrackTitle}", title)
|
||||
# retpath = retpath.replace(R"{ExplicitFlag}", explicit)
|
||||
# retpath = retpath.replace(R"{AlbumYear}", year)
|
||||
# retpath = retpath.replace(R"{AlbumTitle}", albumname.strip())
|
||||
# retpath = retpath.strip()
|
||||
# return base + retpath + extension
|
||||
#
|
||||
#
|
||||
# def __getTrackPath2__(conf, track, stream, album=None, playlist=None):
|
||||
# if album is not None:
|
||||
# base = getAlbumPath(conf, album)
|
||||
# if album.numberOfVolumes > 1:
|
||||
# base += 'CD' + str(track.volumeNumber) + '/'
|
||||
# if playlist is not None and conf.usePlaylistFolder:
|
||||
# base = getPlaylistPath(conf, playlist)
|
||||
#
|
||||
# # hyphen
|
||||
# hyphen = ' - ' if conf.addHyphen else ' '
|
||||
# # get number
|
||||
# number = ''
|
||||
# if conf.useTrackNumber:
|
||||
# number = __getIndexStr__(track.trackNumber) + hyphen
|
||||
# if playlist is not None:
|
||||
# number = __getIndexStr__(track.trackNumberOnPlaylist) + hyphen
|
||||
# # get artist
|
||||
# artist = ''
|
||||
# if conf.artistBeforeTitle:
|
||||
# artist = aigpy.path.replaceLimitChar(__getArtistsString__(track.artists), '-') + hyphen
|
||||
# # get explicit
|
||||
# explicit = "(Explicit)" if conf.addExplicitTag and track.explicit else ''
|
||||
# # title
|
||||
# title = track.title
|
||||
# if not aigpy.string.isNull(track.version):
|
||||
# title += ' - ' + track.version
|
||||
# title = aigpy.path.replaceLimitChar(title, '-')
|
||||
# # extension
|
||||
# extension = __getExtension__(stream.url)
|
||||
# return base + number + artist.strip() + title + explicit + extension
|
||||
#
|
||||
#
|
||||
# def getVideoPath(conf, video, album=None, playlist=None):
|
||||
# if album is not None and album.title is not None:
|
||||
# base = getAlbumPath(conf, album)
|
||||
# elif playlist is not None and conf.usePlaylistFolder:
|
||||
# base = getPlaylistPath(conf, playlist)
|
||||
# else:
|
||||
# base = conf.downloadPath + '/Video/'
|
||||
#
|
||||
# # hyphen
|
||||
# hyphen = ' - ' if conf.addHyphen else ' '
|
||||
# # get number
|
||||
# number = ''
|
||||
# if conf.useTrackNumber:
|
||||
# number = __getIndexStr__(video.trackNumber) + hyphen
|
||||
# # get artist
|
||||
# artist = ''
|
||||
# if conf.artistBeforeTitle:
|
||||
# artist = aigpy.path.replaceLimitChar(__getArtistsString__(video.artists), '-') + hyphen
|
||||
# # get explicit
|
||||
# explicit = "(Explicit)" if conf.addExplicitTag and video.explicit else ''
|
||||
# # title
|
||||
# title = aigpy.path.replaceLimitChar(video.title, '-')
|
||||
# # extension
|
||||
# extension = ".mp4"
|
||||
# return base + number + artist.strip() + title + explicit + extension
|
||||
|
||||
|
||||
# def __isNeedDownload__(path, url):
|
||||
# curSize = aigpy.file.getSize(path)
|
||||
# if curSize <= 0:
|
||||
# return True
|
||||
# netSize = aigpy.net.getSize(url)
|
||||
# if curSize >= netSize:
|
||||
# return False
|
||||
# return True
|
||||
|
||||
|
||||
|
||||
def __downloadVideo__(conf, video: Video, album=None, playlist=None):
|
||||
if video.allowStreaming is False:
|
||||
Printf.err("Download failed! " + video.title + ' not allow streaming.')
|
||||
return
|
||||
|
||||
msg, stream = API.getVideoStreamUrl(video.id, conf.videoQuality)
|
||||
Printf.video(video, stream)
|
||||
if not aigpy.string.isNull(msg):
|
||||
Printf.err(video.title + "." + msg)
|
||||
return
|
||||
path = getVideoPath(conf, video, album, playlist)
|
||||
|
||||
logging.info("[DL Video] name=" + aigpy.path.getFileName(path) + "\nurl=" + stream.m3u8Url)
|
||||
m3u8content = requests.get(stream.m3u8Url).content
|
||||
if m3u8content is None:
|
||||
Printf.err(video.title + ' get m3u8 content failed.')
|
||||
return
|
||||
|
||||
urls = aigpy.m3u8.parseTsUrls(m3u8content)
|
||||
if len(urls) <= 0:
|
||||
Printf.err(video.title + ' parse ts urls failed.')
|
||||
logging.info("[DL Video] title=" + video.title + "\m3u8Content=" + str(m3u8content))
|
||||
return
|
||||
|
||||
check, msg = aigpy.m3u8.downloadByTsUrls(urls, path)
|
||||
# check, msg = aigpy.m3u8.download(stream.m3u8Url, path)
|
||||
if check is True:
|
||||
Printf.success(aigpy.path.getFileName(path))
|
||||
else:
|
||||
Printf.err("\nDownload failed!" + msg + '(' + aigpy.path.getFileName(path) + ')')
|
||||
|
||||
|
||||
def __downloadTrack__(conf: Settings, track: Track, album=None, playlist=None):
|
||||
try:
|
||||
# if track.allowStreaming is False:
|
||||
# Printf.err("Download failed! " + track.title + ' not allow streaming.')
|
||||
# return
|
||||
|
||||
msg, stream = API.getStreamUrl(track.id, conf.audioQuality)
|
||||
if conf.showTrackInfo:
|
||||
Printf.track(track, stream)
|
||||
if not aigpy.string.isNull(msg) or stream is None:
|
||||
Printf.err(track.title + "." + msg)
|
||||
return
|
||||
path = getTrackPath(conf, track, stream, album, playlist)
|
||||
|
||||
# check exist
|
||||
if conf.checkExist and isNeedDownload(path, stream.url) == False:
|
||||
Printf.success(aigpy.path.getFileName(path) + " (skip:already exists!)")
|
||||
return
|
||||
logging.info("[DL Track] name=" + aigpy.path.getFileName(path) + "\nurl=" + stream.url)
|
||||
tool = aigpy.download.DownloadTool(path + '.part', [stream.url])
|
||||
check, err = tool.start(conf.showProgress)
|
||||
|
||||
if not check:
|
||||
Printf.err("Download failed! " + aigpy.path.getFileName(path) + ' (' + str(err) + ')')
|
||||
return
|
||||
# encrypted -> decrypt and remove encrypted file
|
||||
if aigpy.string.isNull(stream.encryptionKey):
|
||||
os.replace(path + '.part', path)
|
||||
else:
|
||||
key, nonce = decrypt_security_token(stream.encryptionKey)
|
||||
decrypt_file(path + '.part', path, key, nonce)
|
||||
os.remove(path + '.part')
|
||||
|
||||
path = convertToM4a(path, stream.codec)
|
||||
|
||||
# contributors
|
||||
msg, contributors = API.getTrackContributors(track.id)
|
||||
msg, tidalLyrics = API.getLyrics(track.id)
|
||||
|
||||
lyrics = '' if tidalLyrics is None else tidalLyrics.subtitles
|
||||
if conf.addLyrics and lyrics == '':
|
||||
lyrics = getLyricsFromGemius(track.title, getArtistsName(track.artists), conf.lyricsServerProxy)
|
||||
|
||||
if conf.lyricFile:
|
||||
if tidalLyrics is None:
|
||||
Printf.info(f'Failed to get lyrics from tidal!"{track.title}"')
|
||||
else:
|
||||
lrcPath = path.rsplit(".", 1)[0] + '.lrc'
|
||||
aigpy.fileHelper.write(lrcPath, tidalLyrics.subtitles, 'w')
|
||||
|
||||
setMetaData(track, album, path, contributors, lyrics)
|
||||
Printf.success(aigpy.path.getFileName(path))
|
||||
except Exception as e:
|
||||
Printf.err("Download failed! " + track.title + ' (' + str(e) + ')')
|
||||
|
||||
|
||||
def __downloadCover__(conf, album):
|
||||
@@ -462,21 +79,21 @@ def __album__(conf, obj):
|
||||
if conf.saveCovers:
|
||||
__downloadCover__(conf, obj)
|
||||
for item in tracks:
|
||||
__downloadTrack__(conf, item, obj)
|
||||
downloadTrack(item, obj)
|
||||
for item in videos:
|
||||
__downloadVideo__(conf, item, obj)
|
||||
downloadVideo(item, obj)
|
||||
|
||||
|
||||
def __track__(conf, obj):
|
||||
msg, album = API.getAlbum(obj.album.id)
|
||||
if conf.saveCovers:
|
||||
__downloadCover__(conf, album)
|
||||
__downloadTrack__(conf, obj, album)
|
||||
downloadTrack(obj, album)
|
||||
|
||||
|
||||
def __video__(conf, obj):
|
||||
# Printf.video(obj)
|
||||
__downloadVideo__(conf, obj, obj.album)
|
||||
downloadVideo(obj, obj.album)
|
||||
|
||||
|
||||
def __artist__(conf, obj):
|
||||
@@ -499,11 +116,11 @@ def __playlist__(conf, obj):
|
||||
for index, item in enumerate(tracks):
|
||||
mag, album = API.getAlbum(item.album.id)
|
||||
item.trackNumberOnPlaylist = index + 1
|
||||
__downloadTrack__(conf, item, album, obj)
|
||||
downloadTrack(item, album, obj)
|
||||
if conf.saveCovers and not conf.usePlaylistFolder:
|
||||
__downloadCover__(conf, album)
|
||||
for item in videos:
|
||||
__downloadVideo__(conf, item, None)
|
||||
downloadVideo(item, None)
|
||||
|
||||
|
||||
def __mix__(conf, obj: Mix):
|
||||
@@ -511,11 +128,11 @@ def __mix__(conf, obj: Mix):
|
||||
for index, item in enumerate(obj.tracks):
|
||||
mag, album = API.getAlbum(item.album.id)
|
||||
item.trackNumberOnPlaylist = index + 1
|
||||
__downloadTrack__(conf, item, album)
|
||||
downloadTrack(item, album)
|
||||
if conf.saveCovers and not conf.usePlaylistFolder:
|
||||
__downloadCover__(conf, album)
|
||||
for item in obj.videos:
|
||||
__downloadVideo__(conf, item, None)
|
||||
downloadVideo(item, None)
|
||||
|
||||
|
||||
def file(user, conf, string):
|
||||
@@ -558,7 +175,6 @@ def start(user, conf, string):
|
||||
if etype == Type.Track:
|
||||
__track__(conf, obj)
|
||||
if etype == Type.Video:
|
||||
__loadVideoAPI__(user)
|
||||
__video__(conf, obj)
|
||||
if etype == Type.Artist:
|
||||
__artist__(conf, obj)
|
||||
|
||||
@@ -51,6 +51,17 @@ class Album(ModelBase):
|
||||
artists = Artist()
|
||||
|
||||
|
||||
class Playlist(ModelBase):
|
||||
uuid = None
|
||||
title = None
|
||||
numberOfTracks = 0
|
||||
numberOfVideos = 0
|
||||
description = None
|
||||
duration = 0
|
||||
image = None
|
||||
squareImage = None
|
||||
|
||||
|
||||
class Track(ModelBase):
|
||||
id = None
|
||||
title = None
|
||||
@@ -67,6 +78,7 @@ class Track(ModelBase):
|
||||
artists = Artist()
|
||||
album = Album()
|
||||
allowStreaming = False
|
||||
playlist = None
|
||||
|
||||
|
||||
class Video(ModelBase):
|
||||
@@ -83,17 +95,7 @@ class Video(ModelBase):
|
||||
artists = Artist()
|
||||
album = Album()
|
||||
allowStreaming = False
|
||||
|
||||
|
||||
class Playlist(ModelBase):
|
||||
uuid = None
|
||||
title = None
|
||||
numberOfTracks = 0
|
||||
numberOfVideos = 0
|
||||
description = None
|
||||
duration = 0
|
||||
image = None
|
||||
squareImage = None
|
||||
playlist = None
|
||||
|
||||
|
||||
class Mix(ModelBase):
|
||||
|
||||
@@ -397,6 +397,14 @@ class TidalAPI(object):
|
||||
if sid is None or sid == "":
|
||||
return None
|
||||
return "https://resources.tidal.com/images/" + sid.replace("-", "/") + "/" + width + "x" + height + ".jpg"
|
||||
|
||||
def getCoverData(self, sid, width="320", height="320"):
|
||||
url = self.getCoverUrl(sid, width, height)
|
||||
try:
|
||||
respond = requests.get(url)
|
||||
return respond.content
|
||||
except:
|
||||
return ''
|
||||
|
||||
def getArtistsName(self, artists=[]):
|
||||
array = []
|
||||
|
||||
@@ -11,19 +11,32 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
from urllib import request
|
||||
|
||||
import aigpy
|
||||
import lyricsgenius
|
||||
import datetime
|
||||
from tidal_dl import apiKey
|
||||
import tidal_dl
|
||||
from tidal_dl.decryption import decrypt_file
|
||||
from tidal_dl.decryption import decrypt_security_token
|
||||
from tidal_dl.enums import Type, AudioQuality
|
||||
from tidal_dl.lang.language import initLang
|
||||
from tidal_dl.model import Track, Video, Lyrics, Mix, Album
|
||||
from tidal_dl.printf import Printf
|
||||
from tidal_dl.settings import Settings
|
||||
from tidal_dl.settings import Settings, TokenSettings, getLogPath
|
||||
from tidal_dl.tidal import TidalAPI
|
||||
|
||||
TOKEN = TokenSettings.read()
|
||||
CONF = Settings.read()
|
||||
LANG = initLang(CONF.language)
|
||||
API = TidalAPI()
|
||||
API.apiKey = apiKey.getItem(CONF.apiKeyIndex)
|
||||
|
||||
logging.basicConfig(filename=getLogPath(),
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s: %(message)s')
|
||||
|
||||
|
||||
def __getIndexStr__(index):
|
||||
@@ -49,6 +62,7 @@ def __secondsToTimeStr__(seconds):
|
||||
time_string = time_string[2:]
|
||||
return time_string
|
||||
|
||||
|
||||
def __parseContributors__(roleType, Contributors):
|
||||
if Contributors is None:
|
||||
return None
|
||||
@@ -273,3 +287,216 @@ def isNeedDownload(path, url):
|
||||
if curSize >= netSize:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def encrypted(stream, srcPath, descPath):
|
||||
if aigpy.string.isNull(stream.encryptionKey):
|
||||
os.replace(srcPath, descPath)
|
||||
else:
|
||||
key, nonce = decrypt_security_token(stream.encryptionKey)
|
||||
decrypt_file(srcPath, descPath, key, nonce)
|
||||
os.remove(srcPath)
|
||||
|
||||
|
||||
def getAudioQualityList():
|
||||
return map(lambda quality: quality.name, tidal_dl.enums.AudioQuality)
|
||||
|
||||
|
||||
def getVideoQualityList():
|
||||
return map(lambda quality: quality.name, tidal_dl.enums.VideoQuality)
|
||||
|
||||
|
||||
def skip(path, url):
|
||||
if CONF.checkExist and isNeedDownload(path, url) is False:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def convert(srcPath, stream):
|
||||
if CONF.onlyM4a:
|
||||
return convertToM4a(srcPath, stream.codec)
|
||||
return srcPath
|
||||
|
||||
|
||||
def downloadTrack(track: Track, album=None, playlist=None, userProgress=None):
|
||||
try:
|
||||
msg, stream = API.getStreamUrl(track.id, CONF.audioQuality)
|
||||
if not aigpy.string.isNull(msg) or stream is None:
|
||||
Printf.err(track.title + "." + msg)
|
||||
return False, msg
|
||||
if CONF.showTrackInfo:
|
||||
Printf.track(track, stream)
|
||||
path = getTrackPath(CONF, track, stream, album, playlist)
|
||||
|
||||
# check exist
|
||||
if skip(path, stream.url):
|
||||
Printf.success(aigpy.path.getFileName(path) + " (skip:already exists!)")
|
||||
return True, ""
|
||||
|
||||
# download
|
||||
logging.info("[DL Track] name=" + aigpy.path.getFileName(path) + "\nurl=" + stream.url)
|
||||
tool = aigpy.download.DownloadTool(path + '.part', [stream.url])
|
||||
tool.setUserProgress(userProgress)
|
||||
check, err = tool.start(CONF.showProgress)
|
||||
if not check:
|
||||
Printf.err("Download failed! " + aigpy.path.getFileName(path) + ' (' + str(err) + ')')
|
||||
return False, str(err)
|
||||
|
||||
# encrypted -> decrypt and remove encrypted file
|
||||
encrypted(stream, path + '.part', path)
|
||||
|
||||
# convert
|
||||
path = convert(path, stream)
|
||||
|
||||
# contributors
|
||||
msg, contributors = API.getTrackContributors(track.id)
|
||||
msg, tidalLyrics = API.getLyrics(track.id)
|
||||
|
||||
lyrics = '' if tidalLyrics is None else tidalLyrics.subtitles
|
||||
if CONF.lyricFile:
|
||||
if tidalLyrics is None:
|
||||
Printf.info(f'Failed to get lyrics from tidal!"{track.title}"')
|
||||
else:
|
||||
lrcPath = path.rsplit(".", 1)[0] + '.lrc'
|
||||
aigpy.fileHelper.write(lrcPath, tidalLyrics.subtitles, 'w')
|
||||
|
||||
setMetaData(track, album, path, contributors, lyrics)
|
||||
Printf.success(aigpy.path.getFileName(path))
|
||||
return True, ""
|
||||
except Exception as e:
|
||||
Printf.err("Download failed! " + track.title + ' (' + str(e) + ')')
|
||||
return False, str(e)
|
||||
|
||||
|
||||
def downloadVideo(video: Video, album=None, playlist=None):
|
||||
msg, stream = API.getVideoStreamUrl(video.id, CONF.videoQuality)
|
||||
Printf.video(video, stream)
|
||||
if not aigpy.string.isNull(msg):
|
||||
Printf.err(video.title + "." + msg)
|
||||
return False, msg
|
||||
path = getVideoPath(CONF, video, album, playlist)
|
||||
|
||||
logging.info("[DL Video] name=" + aigpy.path.getFileName(path) + "\nurl=" + stream.m3u8Url)
|
||||
m3u8content = request.get(stream.m3u8Url).content
|
||||
if m3u8content is None:
|
||||
Printf.err(video.title + ' get m3u8 content failed.')
|
||||
return False, "Get m3u8 content failed"
|
||||
|
||||
urls = aigpy.m3u8.parseTsUrls(m3u8content)
|
||||
if len(urls) <= 0:
|
||||
Printf.err(video.title + ' parse ts urls failed.')
|
||||
logging.info("[DL Video] title=" + video.title + "\m3u8Content=" + str(m3u8content))
|
||||
return False, 'Parse ts urls failed.'
|
||||
|
||||
check, msg = aigpy.m3u8.downloadByTsUrls(urls, path)
|
||||
# check, msg = aigpy.m3u8.download(stream.m3u8Url, path)
|
||||
if check is True:
|
||||
Printf.success(aigpy.path.getFileName(path))
|
||||
return True, ''
|
||||
else:
|
||||
Printf.err("\nDownload failed!" + msg + '(' + aigpy.path.getFileName(path) + ')')
|
||||
return False, msg
|
||||
|
||||
|
||||
def displayTime(seconds, granularity=2):
|
||||
if seconds <= 0:
|
||||
return "unknown"
|
||||
|
||||
result = []
|
||||
intervals = (
|
||||
('weeks', 604800),
|
||||
('days', 86400),
|
||||
('hours', 3600),
|
||||
('minutes', 60),
|
||||
('seconds', 1),
|
||||
)
|
||||
|
||||
for name, count in intervals:
|
||||
value = seconds // count
|
||||
if value:
|
||||
seconds -= value * count
|
||||
if value == 1:
|
||||
name = name.rstrip('s')
|
||||
result.append("{} {}".format(value, name))
|
||||
return ', '.join(result[:granularity])
|
||||
|
||||
def loginByConfig():
|
||||
if aigpy.stringHelper.isNull(TOKEN.accessToken):
|
||||
return False
|
||||
|
||||
msg, check = API.verifyAccessToken(TOKEN.accessToken)
|
||||
if check:
|
||||
Printf.info(LANG.MSG_VALID_ACCESSTOKEN.format(displayTime(int(TOKEN.expiresAfter - time.time()))))
|
||||
API.key.countryCode = TOKEN.countryCode
|
||||
API.key.userId = TOKEN.userid
|
||||
API.key.accessToken = TOKEN.accessToken
|
||||
return True
|
||||
|
||||
Printf.info(LANG.MSG_INVAILD_ACCESSTOKEN)
|
||||
msg, check = API.refreshAccessToken(TOKEN.refreshToken)
|
||||
if check:
|
||||
Printf.success(LANG.MSG_VALID_ACCESSTOKEN.format(displayTime(int(API.key.expiresIn))))
|
||||
TOKEN.userid = API.key.userId
|
||||
TOKEN.countryCode = API.key.countryCode
|
||||
TOKEN.accessToken = API.key.accessToken
|
||||
TOKEN.expiresAfter = time.time() + int(API.key.expiresIn)
|
||||
TokenSettings.save(TOKEN)
|
||||
return True
|
||||
else:
|
||||
tmp = TokenSettings() # clears saved tokens
|
||||
TokenSettings.save(tmp)
|
||||
return False
|
||||
|
||||
def loginByWeb():
|
||||
start = time.time()
|
||||
elapsed = 0
|
||||
while elapsed < API.key.authCheckTimeout:
|
||||
elapsed = time.time() - start
|
||||
msg, check = API.checkAuthStatus()
|
||||
if not check:
|
||||
if msg == "pending":
|
||||
time.sleep(API.key.authCheckInterval + 1)
|
||||
continue
|
||||
return False
|
||||
if check:
|
||||
Printf.success(LANG.MSG_VALID_ACCESSTOKEN.format(displayTime(int(API.key.expiresIn))))
|
||||
TOKEN.userid = API.key.userId
|
||||
TOKEN.countryCode = API.key.countryCode
|
||||
TOKEN.accessToken = API.key.accessToken
|
||||
TOKEN.refreshToken = API.key.refreshToken
|
||||
TOKEN.expiresAfter = time.time() + int(API.key.expiresIn)
|
||||
TokenSettings.save(TOKEN)
|
||||
return True
|
||||
|
||||
Printf.err(LANG.AUTH_TIMEOUT)
|
||||
return False
|
||||
|
||||
def getArtistsNames(artists): # : list[tidal_dl.model.Artist]
|
||||
ret = []
|
||||
for item in artists:
|
||||
ret.append(item.name)
|
||||
return ','.join(ret)
|
||||
|
||||
def getDurationString(seconds: int):
|
||||
m, s = divmod(seconds, 60)
|
||||
h, m = divmod(m, 60)
|
||||
return "%02d:%02d:%02d" % (h, m, s)
|
||||
|
||||
def getBasePath(model):
|
||||
if isinstance(model, tidal_dl.model.Album):
|
||||
return getAlbumPath(CONF, model)
|
||||
if isinstance(model, tidal_dl.model.Playlist):
|
||||
return getPlaylistPath(CONF, model)
|
||||
if isinstance(model, tidal_dl.model.Track):
|
||||
return getAlbumPath(CONF, model)
|
||||
if isinstance(model, tidal_dl.model.Video):
|
||||
filePath = getVideoPath(CONF, model, model.album, model.playlist)
|
||||
return aigpy.pathHelper.getDirName(filePath)
|
||||
return './'
|
||||
|
||||
def getFilePath(model, stream=None):
|
||||
if isinstance(model, tidal_dl.model.Track):
|
||||
return getTrackPath(CONF, model, stream, model.album, model.playlist)
|
||||
if isinstance(model, tidal_dl.model.Video):
|
||||
return getVideoPath(CONF, model, model.album, model.playlist)
|
||||
return './'
|
||||
|
||||
@@ -23,11 +23,12 @@ def main():
|
||||
|
||||
mainView = MainModel()
|
||||
mainView.show()
|
||||
|
||||
|
||||
app.exec_()
|
||||
mainView.uninit()
|
||||
|
||||
sys.exit()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
from PyQt5.QtWidgets import QComboBox, QListView
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QComboBox, QListView
|
||||
|
||||
|
||||
class ComboBox(QComboBox):
|
||||
def __init__(self, items: list, width: int=200):
|
||||
def __init__(self, items: list, width: int = 200):
|
||||
super(ComboBox, self).__init__()
|
||||
self.setItems(items)
|
||||
self.setFixedWidth(width)
|
||||
|
||||
@@ -8,13 +8,7 @@
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
import ctypes.wintypes
|
||||
from ctypes.wintypes import POINT
|
||||
import typing
|
||||
|
||||
import PyQt5
|
||||
import win32api
|
||||
import win32con
|
||||
from PyQt5.QtCore import Qt, QPoint
|
||||
from PyQt5.QtGui import QMouseEvent
|
||||
from PyQt5.QtWidgets import QWidget, QGridLayout, QHBoxLayout
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
from PyQt5.QtCore import QSize
|
||||
from PyQt5.QtGui import QIcon
|
||||
from PyQt5.QtWidgets import QListWidget, QListWidgetItem, QWidget
|
||||
|
||||
|
||||
@@ -29,4 +29,3 @@ class PushButton(QPushButton):
|
||||
|
||||
if iconUrl != '':
|
||||
self.setIcon(QIcon(iconUrl))
|
||||
|
||||
|
||||
@@ -9,21 +9,19 @@
|
||||
@Desc :
|
||||
"""
|
||||
|
||||
from PyQt5.QtCore import QSize, Qt
|
||||
from PyQt5.QtGui import QIcon
|
||||
from PyQt5.QtWidgets import QListWidget, QListWidgetItem, QWidget, QScrollArea, QVBoxLayout, QPushButton, QBoxLayout
|
||||
from PyQt5.QtWidgets import QWidget, QScrollArea, QVBoxLayout
|
||||
|
||||
|
||||
class ScrollWidget(QScrollArea):
|
||||
def __init__(self):
|
||||
super(ScrollWidget, self).__init__()
|
||||
|
||||
|
||||
self._layout = QVBoxLayout()
|
||||
self._layout.addStretch(1)
|
||||
|
||||
|
||||
self._mainW = QWidget()
|
||||
self._mainW.setLayout(self._layout)
|
||||
|
||||
|
||||
self.setWidget(self._mainW)
|
||||
self.setWidgetResizable(True)
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"""
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QStandardItemModel, QStandardItem
|
||||
from PyQt5.QtWidgets import QTableView, QTableWidgetItem, QAbstractItemView
|
||||
from PyQt5.QtWidgets import QTableView, QAbstractItemView
|
||||
|
||||
|
||||
class TableView(QTableView):
|
||||
@@ -25,7 +25,7 @@ class TableView(QTableView):
|
||||
self._model.setHeaderData(index, Qt.Horizontal, name)
|
||||
|
||||
self.setModel(self._model)
|
||||
# self.setHorizontalHeaderItem(index, QTableWidgetItem(name))
|
||||
# self.setHorizontalHeaderItem(index, QTableWidgetItem(name))
|
||||
# for index in range(0, rowCount):
|
||||
# self.setRowHeight(index, 50)
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
import aigpy
|
||||
import requests
|
||||
import threading
|
||||
|
||||
from PyQt5.QtCore import Qt, QUrl
|
||||
from PyQt5.QtGui import QIcon, QPixmap
|
||||
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
||||
from PyQt5.QtWidgets import QTableWidget, QTableWidgetItem, QAbstractItemView, QLabel
|
||||
from PyQt5.QtGui import QPixmap
|
||||
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest
|
||||
from PyQt5.QtWidgets import QTableWidget, QTableWidgetItem, QAbstractItemView
|
||||
|
||||
from tidal_gui.control.label import Label, LabelStyle
|
||||
|
||||
|
||||
|
||||
@@ -8,16 +8,18 @@
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
from PyQt5.Qt import QThread
|
||||
from queue import Queue
|
||||
from tidal_gui.viewModel.taskModel import TaskModel
|
||||
import time
|
||||
|
||||
from PyQt5.Qt import QThread
|
||||
|
||||
from tidal_gui.viewModel.taskModel import TaskModel
|
||||
|
||||
|
||||
class DownloaderImp(QThread):
|
||||
def __init__(self):
|
||||
super(DownloaderImp, self).__init__()
|
||||
self._taskModel = None
|
||||
|
||||
|
||||
def run(self):
|
||||
print('DownloadImp start...')
|
||||
while not self.isInterruptionRequested():
|
||||
@@ -27,12 +29,13 @@ class DownloaderImp(QThread):
|
||||
item.download()
|
||||
time.sleep(1)
|
||||
print('DownloadImp stop...')
|
||||
|
||||
|
||||
def setTaskModel(self, model: TaskModel):
|
||||
self._taskModel = model
|
||||
|
||||
|
||||
def stop(self):
|
||||
self.requestInterruption()
|
||||
self.wait()
|
||||
|
||||
|
||||
|
||||
downloadImp = DownloaderImp()
|
||||
|
||||
@@ -1 +1,12 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1629184159878" class="icon" viewBox="0 0 1092 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="23123" xmlns:xlink="http://www.w3.org/1999/xlink" width="136.5" height="128"><defs><style type="text/css"></style></defs><path d="M538.624 1017.344L0.580267 405.162667 212.445867 0h652.356266L1076.565333 405.162667z" fill="#46F256" p-id="23124"></path><path d="M538.624 748.6464l-317.44-351.607467 67.618133-61.098666 249.787734 276.718933 249.821866-276.6848 67.618134 61.064533z" fill="#000000" p-id="23125"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1629184159878" class="icon" viewBox="0 0 1092 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="23123" width="136.5" height="128">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M538.624 1017.344L0.580267 405.162667 212.445867 0h652.356266L1076.565333 405.162667z" fill="#46F256"
|
||||
p-id="23124"></path>
|
||||
<path d="M538.624 748.6464l-317.44-351.607467 67.618133-61.098666 249.787734 276.718933 249.821866-276.6848 67.618134 61.064533z"
|
||||
fill="#000000" p-id="23125"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 673 B After Width: | Height: | Size: 694 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629268466285" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="18338" width="128" height="128"><path d="M294.314667 0L242.432 119.424H165.418667v107.648h29.653333L225.152 418.133333H178.005333l62.293334 351.146667 40.021333-0.426667 40.192 255.146667h380.501333l2.645334-17.066667 37.546666-238.08 37.888 0.426667 62.293334-351.189333h-45.056l30.08-191.018667h32.256V119.466667h-81.834667L724.906667 0H294.314667z m22.528 34.346667h385.834666l32.896 75.946666H283.818667l33.024-75.946666z m-117.333334 119.338666H824.32v39.253334H199.509333v-39.253334z m19.328 298.581334h581.76l-50.176 282.453333-241.024-2.56-240.469333 2.56-50.090667-282.453333z" p-id="18339" fill="#ffffff"></path></svg>
|
||||
<svg t="1629268466285" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="18338" width="128" height="128">
|
||||
<path d="M294.314667 0L242.432 119.424H165.418667v107.648h29.653333L225.152 418.133333H178.005333l62.293334 351.146667 40.021333-0.426667 40.192 255.146667h380.501333l2.645334-17.066667 37.546666-238.08 37.888 0.426667 62.293334-351.189333h-45.056l30.08-191.018667h32.256V119.466667h-81.834667L724.906667 0H294.314667z m22.528 34.346667h385.834666l32.896 75.946666H283.818667l33.024-75.946666z m-117.333334 119.338666H824.32v39.253334H199.509333v-39.253334z m19.328 298.581334h581.76l-50.176 282.453333-241.024-2.56-240.469333 2.56-50.090667-282.453333z"
|
||||
p-id="18339" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 743 B After Width: | Height: | Size: 764 B |
@@ -3,4 +3,8 @@
|
||||
<path d="M316.16 366.506667L512 561.92l195.84-195.413333L768 426.666667l-256 256-256-256z" fill="#cbcbcb"
|
||||
p-id="1512"></path>
|
||||
</svg> -->
|
||||
<svg t="1629251448482" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1609" width="128" height="128"><path d="M179.758545 374.008242a31.030303 31.030303 0 0 1 43.876849 0L512 662.372848l288.364606-288.364606a31.030303 31.030303 0 0 1 43.876849 43.876849l-310.303031 310.30303a31.030303 31.030303 0 0 1-43.876848 0l-310.303031-310.30303a31.030303 31.030303 0 0 1 0-43.876849z" p-id="1610" fill="#cbcbcb"></path></svg>
|
||||
<svg t="1629251448482" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1609"
|
||||
width="128" height="128">
|
||||
<path d="M179.758545 374.008242a31.030303 31.030303 0 0 1 43.876849 0L512 662.372848l288.364606-288.364606a31.030303 31.030303 0 0 1 43.876849 43.876849l-310.303031 310.30303a31.030303 31.030303 0 0 1-43.876848 0l-310.303031-310.30303a31.030303 31.030303 0 0 1 0-43.876849z"
|
||||
p-id="1610" fill="#cbcbcb"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 769 B After Width: | Height: | Size: 790 B |
@@ -3,4 +3,8 @@
|
||||
<path d="M316.16 366.506667L512 561.92l195.84-195.413333L768 426.666667l-256 256-256-256z" fill="#326cf3"
|
||||
p-id="1512"></path>
|
||||
</svg> -->
|
||||
<svg t="1629251448482" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1609" width="128" height="128"><path d="M179.758545 374.008242a31.030303 31.030303 0 0 1 43.876849 0L512 662.372848l288.364606-288.364606a31.030303 31.030303 0 0 1 43.876849 43.876849l-310.303031 310.30303a31.030303 31.030303 0 0 1-43.876848 0l-310.303031-310.30303a31.030303 31.030303 0 0 1 0-43.876849z" p-id="1610" fill="#326cf3"></path></svg>
|
||||
<svg t="1629251448482" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1609"
|
||||
width="128" height="128">
|
||||
<path d="M179.758545 374.008242a31.030303 31.030303 0 0 1 43.876849 0L512 662.372848l288.364606-288.364606a31.030303 31.030303 0 0 1 43.876849 43.876849l-310.303031 310.30303a31.030303 31.030303 0 0 1-43.876848 0l-310.303031-310.30303a31.030303 31.030303 0 0 1 0-43.876849z"
|
||||
p-id="1610" fill="#326cf3"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 769 B After Width: | Height: | Size: 790 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629268481541" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19187" width="128" height="128"><path d="M512.032 831.904c-19.168 0-38.304-9.92-58.144-29.76-7.808-7.808-7.808-20.48 0-28.288s20.48-7.808 28.288 0C494.368 786.08 504.16 792 512.032 792s17.664-5.92 29.856-18.144c7.808-7.808 20.48-7.808 28.288 0s7.808 20.48 0 28.288c-19.84 19.84-38.976 29.76-58.144 29.76z m-512-306.4c0 49.888 4.256 95.136 12.8 135.68s20.544 75.744 36 105.536 35.008 55.904 58.656 78.336 49.344 40.928 77.056 55.456c27.744 14.528 59.456 26.304 95.2 35.264S351.84 951.04 388.8 954.624 466.496 960 510.944 960c44.448 0 85.248-1.792 122.4-5.376s73.6-9.856 109.344-18.848c35.744-8.96 67.552-20.736 95.456-35.264s53.792-33.024 77.6-55.456c23.808-22.432 43.456-48.544 58.944-78.336s27.552-64.96 36.256-105.536c8.704-40.576 13.056-85.792 13.056-135.68 0-89.376-27.744-166.368-83.2-230.976 3.2-8.608 5.952-18.496 8.256-29.6s4.544-26.816 6.656-47.104c2.144-20.288 1.344-43.712-2.4-70.272S942.56 93.888 932.256 66.24l-8-1.632c-5.344-1.088-14.048-0.704-26.144 1.088s-26.208 5.024-42.4 9.696-37.056 13.92-62.656 27.744-52.608 31.328-81.056 52.512c-48.352-14.72-115.008-30.112-200-30.112s-151.808 15.392-200.544 30.112c-28.448-21.184-55.552-38.592-81.344-52.224s-46.4-22.976-61.856-28c-15.456-5.024-29.792-8.256-42.944-9.696s-21.6-1.888-25.344-1.344c-3.744 0.544-6.496 1.152-8.256 1.888-10.304 27.648-17.408 54.752-21.344 81.312s-4.8 49.888-2.656 69.984c2.144 20.096 4.448 35.904 6.944 47.392S80 286.304 83.2 294.56C27.744 358.816 0 435.808 0 525.536z m136.544 113.888c0-58.016 21.344-110.624 64-157.856 12.8-14.4 27.648-25.312 44.544-32.704s36.096-11.616 57.6-12.608 42.048-0.8 61.6 0.608 43.744 3.296 72.544 5.696 53.696 3.616 74.656 3.616c20.96 0 45.856-1.184 74.656-3.616s52.992-4.288 72.544-5.696c19.552-1.408 40.096-1.6 61.6-0.608s40.8 5.216 57.856 12.608c17.056 7.392 32 18.304 44.8 32.704 42.656 47.232 64 99.84 64 157.856 0 34.016-3.552 64.32-10.656 90.944s-16.096 48.928-26.944 66.912c-10.848 18.016-26.048 33.216-45.6 45.632s-38.496 22.016-56.8 28.8c-18.304 6.784-41.952 12.096-70.944 15.904s-54.944 6.112-77.856 6.912c-22.944 0.8-51.808 1.216-86.656 1.216s-63.648-0.416-86.4-1.216c-22.752-0.8-48.608-3.104-77.6-6.912s-52.608-9.12-70.944-15.904c-18.304-6.816-37.248-16.416-56.8-28.8s-34.752-27.616-45.6-45.632c-10.848-18.016-19.84-40.32-26.944-66.912s-10.656-56.928-10.656-90.944zM256.032 608c0-53.024 28.64-96 64-96s64 42.976 64 96-28.64 96-64 96-64-42.976-64-96z m384 0c0-53.024 28.64-96 64-96s64 42.976 64 96-28.64 96-64 96-64-42.976-64-96z" p-id="19188"></path></svg>
|
||||
<svg t="1629268481541" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="19187" width="128" height="128">
|
||||
<path d="M512.032 831.904c-19.168 0-38.304-9.92-58.144-29.76-7.808-7.808-7.808-20.48 0-28.288s20.48-7.808 28.288 0C494.368 786.08 504.16 792 512.032 792s17.664-5.92 29.856-18.144c7.808-7.808 20.48-7.808 28.288 0s7.808 20.48 0 28.288c-19.84 19.84-38.976 29.76-58.144 29.76z m-512-306.4c0 49.888 4.256 95.136 12.8 135.68s20.544 75.744 36 105.536 35.008 55.904 58.656 78.336 49.344 40.928 77.056 55.456c27.744 14.528 59.456 26.304 95.2 35.264S351.84 951.04 388.8 954.624 466.496 960 510.944 960c44.448 0 85.248-1.792 122.4-5.376s73.6-9.856 109.344-18.848c35.744-8.96 67.552-20.736 95.456-35.264s53.792-33.024 77.6-55.456c23.808-22.432 43.456-48.544 58.944-78.336s27.552-64.96 36.256-105.536c8.704-40.576 13.056-85.792 13.056-135.68 0-89.376-27.744-166.368-83.2-230.976 3.2-8.608 5.952-18.496 8.256-29.6s4.544-26.816 6.656-47.104c2.144-20.288 1.344-43.712-2.4-70.272S942.56 93.888 932.256 66.24l-8-1.632c-5.344-1.088-14.048-0.704-26.144 1.088s-26.208 5.024-42.4 9.696-37.056 13.92-62.656 27.744-52.608 31.328-81.056 52.512c-48.352-14.72-115.008-30.112-200-30.112s-151.808 15.392-200.544 30.112c-28.448-21.184-55.552-38.592-81.344-52.224s-46.4-22.976-61.856-28c-15.456-5.024-29.792-8.256-42.944-9.696s-21.6-1.888-25.344-1.344c-3.744 0.544-6.496 1.152-8.256 1.888-10.304 27.648-17.408 54.752-21.344 81.312s-4.8 49.888-2.656 69.984c2.144 20.096 4.448 35.904 6.944 47.392S80 286.304 83.2 294.56C27.744 358.816 0 435.808 0 525.536z m136.544 113.888c0-58.016 21.344-110.624 64-157.856 12.8-14.4 27.648-25.312 44.544-32.704s36.096-11.616 57.6-12.608 42.048-0.8 61.6 0.608 43.744 3.296 72.544 5.696 53.696 3.616 74.656 3.616c20.96 0 45.856-1.184 74.656-3.616s52.992-4.288 72.544-5.696c19.552-1.408 40.096-1.6 61.6-0.608s40.8 5.216 57.856 12.608c17.056 7.392 32 18.304 44.8 32.704 42.656 47.232 64 99.84 64 157.856 0 34.016-3.552 64.32-10.656 90.944s-16.096 48.928-26.944 66.912c-10.848 18.016-26.048 33.216-45.6 45.632s-38.496 22.016-56.8 28.8c-18.304 6.784-41.952 12.096-70.944 15.904s-54.944 6.112-77.856 6.912c-22.944 0.8-51.808 1.216-86.656 1.216s-63.648-0.416-86.4-1.216c-22.752-0.8-48.608-3.104-77.6-6.912s-52.608-9.12-70.944-15.904c-18.304-6.816-37.248-16.416-56.8-28.8s-34.752-27.616-45.6-45.632c-10.848-18.016-19.84-40.32-26.944-66.912s-10.656-56.928-10.656-90.944zM256.032 608c0-53.024 28.64-96 64-96s64 42.976 64 96-28.64 96-64 96-64-42.976-64-96z m384 0c0-53.024 28.64-96 64-96s64 42.976 64 96-28.64 96-64 96-64-42.976-64-96z"
|
||||
p-id="19188"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.6 KiB |
@@ -1 +1,5 @@
|
||||
<svg t="1629270772080" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1817" width="128" height="128"><path d="M658.059636 187.826424a31.030303 31.030303 0 0 1 0 43.876849l-288.364606 288.364606 288.364606 288.364606a31.030303 31.030303 0 0 1-43.876848 43.876848l-310.30303-310.30303a31.030303 31.030303 0 0 1 0-43.876848l310.30303-310.303031a31.030303 31.030303 0 0 1 43.876848 0z" p-id="1818"></path></svg>
|
||||
<svg t="1629270772080" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1817"
|
||||
width="128" height="128">
|
||||
<path d="M658.059636 187.826424a31.030303 31.030303 0 0 1 0 43.876849l-288.364606 288.364606 288.364606 288.364606a31.030303 31.030303 0 0 1-43.876848 43.876848l-310.30303-310.30303a31.030303 31.030303 0 0 1 0-43.876848l310.30303-310.303031a31.030303 31.030303 0 0 1 43.876848 0z"
|
||||
p-id="1818"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 452 B After Width: | Height: | Size: 473 B |
@@ -1 +1,10 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1629182866847" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22424" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M938.666667 682.666667v170.666666a85.333333 85.333333 0 0 1-85.333334 85.333334H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334v-170.666666h85.333334v170.666666h682.666666v-170.666666h85.333334z m-384-145.664l140.501333-140.501334 60.330667 60.330667L512 700.330667l-243.498667-243.498667 60.330667-60.330667L469.333333 537.002667V85.333333h85.333334v451.669334z" p-id="22425" fill="#ffffff"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1629182866847" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="22424" width="128" height="128">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M938.666667 682.666667v170.666666a85.333333 85.333333 0 0 1-85.333334 85.333334H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334v-170.666666h85.333334v170.666666h682.666666v-170.666666h85.333334z m-384-145.664l140.501333-140.501334 60.330667 60.330667L512 700.330667l-243.498667-243.498667 60.330667-60.330667L469.333333 537.002667V85.333333h85.333334v451.669334z"
|
||||
p-id="22425" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 792 B After Width: | Height: | Size: 798 B |
@@ -1 +1,10 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1629183863957" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22616" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M938.666667 682.666667v170.666666a85.333333 85.333333 0 0 1-85.333334 85.333334H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334v-170.666666h85.333334v170.666666h682.666666v-170.666666h85.333334z m-384-145.664l140.501333-140.501334 60.330667 60.330667L512 700.330667l-243.498667-243.498667 60.330667-60.330667L469.333333 537.002667V85.333333h85.333334v451.669334z" p-id="22617" fill="#e6e6e6"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1629183863957" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="22616" width="128" height="128">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M938.666667 682.666667v170.666666a85.333333 85.333333 0 0 1-85.333334 85.333334H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334v-170.666666h85.333334v170.666666h682.666666v-170.666666h85.333334z m-384-145.664l140.501333-140.501334 60.330667 60.330667L512 700.330667l-243.498667-243.498667 60.330667-60.330667L469.333333 537.002667V85.333333h85.333334v451.669334z"
|
||||
p-id="22617" fill="#e6e6e6"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 792 B After Width: | Height: | Size: 798 B |
@@ -1 +1,10 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1629182847499" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22040" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M512 981.333333C252.8 981.333333 42.666667 771.2 42.666667 512S252.8 42.666667 512 42.666667s469.333333 210.133333 469.333333 469.333333-210.133333 469.333333-469.333333 469.333333z m0-85.333333a384 384 0 1 0 0-768 384 384 0 0 0 0 768z m42.837333-298.752h42.624v85.333333h-170.666666v-85.333333h42.666666v-85.333333h-42.666666v-85.333334h128v170.666667z m-42.837333-213.333333a42.666667 42.666667 0 1 1 0-85.333334 42.666667 42.666667 0 0 1 0 85.333334z" p-id="22041" fill="#ffffff"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1629182847499" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="22040" width="128" height="128">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M512 981.333333C252.8 981.333333 42.666667 771.2 42.666667 512S252.8 42.666667 512 42.666667s469.333333 210.133333 469.333333 469.333333-210.133333 469.333333-469.333333 469.333333z m0-85.333333a384 384 0 1 0 0-768 384 384 0 0 0 0 768z m42.837333-298.752h42.624v85.333333h-170.666666v-85.333333h42.666666v-85.333333h-42.666666v-85.333334h128v170.666667z m-42.837333-213.333333a42.666667 42.666667 0 1 1 0-85.333334 42.666667 42.666667 0 0 1 0 85.333334z"
|
||||
p-id="22041" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 874 B After Width: | Height: | Size: 880 B |
@@ -1 +1,10 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1629181942259" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21410" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M696.32 635.989333l229.845333 229.845334-60.330666 60.330666-229.845334-229.845333a341.333333 341.333333 0 1 1 60.330667-60.330667zM426.666667 682.666667a256 256 0 1 0 0-512 256 256 0 0 0 0 512z" p-id="21411" fill="#ffffff"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1629181942259" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="21410" width="128" height="128">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M696.32 635.989333l229.845333 229.845334-60.330666 60.330666-229.845334-229.845333a341.333333 341.333333 0 1 1 60.330667-60.330667zM426.666667 682.666667a256 256 0 1 0 0-512 256 256 0 0 0 0 512z"
|
||||
p-id="21411" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 615 B After Width: | Height: | Size: 621 B |
@@ -1 +1,10 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1629182857650" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22232" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M890.581333 797.013333l-94.592 94.592-121.088-33.706666-34.602666 14.250666L578.133333 981.333333h-133.76l-61.824-109.525333-34.56-14.506667-121.088 33.322667-94.549333-94.549333 33.706667-121.088-14.250667-34.602667L42.666667 578.133333v-133.76l109.568-61.824 14.506666-34.56-33.322666-121.088 94.506666-94.506666 121.088 33.749333 34.56-14.250667L445.696 42.666667h133.802667l61.824 109.568 34.56 14.506666 121.045333-33.322666 94.72 94.506666-33.792 121.130667 14.293333 34.56L981.333333 445.738667v133.802666l-109.525333 61.781334-14.506667 34.688 33.28 121.045333z m-123.392-126.805333l37.205334-88.832L896 529.664v-34.304l-91.605333-52.053333-36.650667-88.874667 28.245333-101.333333-24.277333-24.234667-101.674667 27.946667-88.746666-37.205334L529.621333 128h-34.304l-52.053333 91.605333-88.874667 36.650667-101.376-28.288-24.149333 24.149333 27.946667 101.674667-37.205334 88.746667L128 494.208v34.346667l91.52 52.138666 36.650667 88.874667-28.245334 101.376 24.192 24.192 101.674667-27.946667 88.746667 37.205334 51.626666 91.562666h34.346667l52.138667-91.52 88.874666-36.650666 101.376 28.245333 24.234667-24.234667-27.946667-101.589333zM512 682.666667a170.666667 170.666667 0 1 1 0-341.333334 170.666667 170.666667 0 0 1 0 341.333334z m0-85.333334a85.333333 85.333333 0 1 0 0-170.666666 85.333333 85.333333 0 0 0 0 170.666666z" p-id="22233" fill="#ffffff"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1629182857650" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="22232" width="128" height="128">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M890.581333 797.013333l-94.592 94.592-121.088-33.706666-34.602666 14.250666L578.133333 981.333333h-133.76l-61.824-109.525333-34.56-14.506667-121.088 33.322667-94.549333-94.549333 33.706667-121.088-14.250667-34.602667L42.666667 578.133333v-133.76l109.568-61.824 14.506666-34.56-33.322666-121.088 94.506666-94.506666 121.088 33.749333 34.56-14.250667L445.696 42.666667h133.802667l61.824 109.568 34.56 14.506666 121.045333-33.322666 94.72 94.506666-33.792 121.130667 14.293333 34.56L981.333333 445.738667v133.802666l-109.525333 61.781334-14.506667 34.688 33.28 121.045333z m-123.392-126.805333l37.205334-88.832L896 529.664v-34.304l-91.605333-52.053333-36.650667-88.874667 28.245333-101.333333-24.277333-24.234667-101.674667 27.946667-88.746666-37.205334L529.621333 128h-34.304l-52.053333 91.605333-88.874667 36.650667-101.376-28.288-24.149333 24.149333 27.946667 101.674667-37.205334 88.746667L128 494.208v34.346667l91.52 52.138666 36.650667 88.874667-28.245334 101.376 24.192 24.192 101.674667-27.946667 88.746667 37.205334 51.626666 91.562666h34.346667l52.138667-91.52 88.874666-36.650666 101.376 28.245333 24.234667-24.234667-27.946667-101.589333zM512 682.666667a170.666667 170.666667 0 1 1 0-341.333334 170.666667 170.666667 0 0 1 0 341.333334z m0-85.333334a85.333333 85.333333 0 1 0 0-170.666666 85.333333 85.333333 0 0 0 0 170.666666z"
|
||||
p-id="22233" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -1 +1,5 @@
|
||||
<svg t="1629268420515" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16731" width="128" height="128"><path d="M350.8 591.8c-7 38.4-34.8 217.4-43 268-0.6 3.6-2 5-6 5H152.6c-15.2 0-26.2-13.2-24.2-27.8L245.6 93.2c3-19.2 20.2-33.8 40-33.8 304.6 0 330.2-7.4 408 22.8 120.2 46.6 131.2 159 88 280.6-43 125.2-145 179-280.2 180.6-86.8 1.4-139-14-150.6 48.4zM842.2 304c-3.6-2.6-5-3.6-6 2.6-4 22.8-10.2 45-17.6 67.2-79.8 227.6-301 207.8-409 207.8-12.2 0-20.2 6.6-21.8 18.8-45.2 280.8-54.2 339.4-54.2 339.4-2 14.2 7 25.8 21.2 25.8h127c17.2 0 31.4-12.6 34.8-29.8 1.4-10.8-2.2 12.2 28.8-182.6 9.2-44 28.6-39.4 58.6-39.4 142 0 252.8-57.6 285.8-224.6 13-69.6 9.2-142.8-47.6-185.2z" p-id="16732" fill="#ffffff"></path></svg>
|
||||
<svg t="1629268420515" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="16731" width="128" height="128">
|
||||
<path d="M350.8 591.8c-7 38.4-34.8 217.4-43 268-0.6 3.6-2 5-6 5H152.6c-15.2 0-26.2-13.2-24.2-27.8L245.6 93.2c3-19.2 20.2-33.8 40-33.8 304.6 0 330.2-7.4 408 22.8 120.2 46.6 131.2 159 88 280.6-43 125.2-145 179-280.2 180.6-86.8 1.4-139-14-150.6 48.4zM842.2 304c-3.6-2.6-5-3.6-6 2.6-4 22.8-10.2 45-17.6 67.2-79.8 227.6-301 207.8-409 207.8-12.2 0-20.2 6.6-21.8 18.8-45.2 280.8-54.2 339.4-54.2 339.4-2 14.2 7 25.8 21.2 25.8h127c17.2 0 31.4-12.6 34.8-29.8 1.4-10.8-2.2 12.2 28.8-182.6 9.2-44 28.6-39.4 58.6-39.4 142 0 252.8-57.6 285.8-224.6 13-69.6 9.2-142.8-47.6-185.2z"
|
||||
p-id="16732" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 753 B After Width: | Height: | Size: 774 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629270798317" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1968" width="128" height="128"><path d="M365.940364 187.826424a31.030303 31.030303 0 0 1 43.876848 0l310.30303 310.303031a31.030303 31.030303 0 0 1 0 43.876848l-310.30303 310.30303a31.030303 31.030303 0 0 1-43.876848-43.876848l288.364606-288.364606-288.364606-288.364606a31.030303 31.030303 0 0 1 0-43.876849z" p-id="1969"></path></svg>
|
||||
<svg t="1629270798317" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1968"
|
||||
width="128" height="128">
|
||||
<path d="M365.940364 187.826424a31.030303 31.030303 0 0 1 43.876848 0l310.30303 310.303031a31.030303 31.030303 0 0 1 0 43.876848l-310.30303 310.30303a31.030303 31.030303 0 0 1-43.876848-43.876848l288.364606-288.364606-288.364606-288.364606a31.030303 31.030303 0 0 1 0-43.876849z"
|
||||
p-id="1969"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 451 B After Width: | Height: | Size: 472 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629269306451" class="icon" viewBox="0 0 1057 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15526" width="128" height="128"><path d="M409.012356 811.965935c-108.676129 0.660645-213.058065-41.851871-289.924129-117.991225A401.242839 401.242839 0 0 1 0.006937 406.594065a401.242839 401.242839 0 0 1 119.015226-287.512775A408.344774 408.344774 0 0 1 409.012356 0.990968a408.344774 408.344774 0 0 1 289.924129 118.05729 401.275871 401.275871 0 0 1 119.08129 287.44671 401.275871 401.275871 0 0 1-119.048258 287.380645 408.344774 408.344774 0 0 1-289.891096 118.090322h-0.066065z m0-695.130838A290.617806 290.617806 0 0 0 201.63584 200.836129a285.563871 285.563871 0 0 0-84.69471 205.625806c0 162.221419 128.495484 289.626839 292.071226 289.626839 163.641806 0 292.13729-127.405419 292.13729-289.560774 0-162.221419-128.495484-289.725935-292.071225-289.725935h-0.066065zM957.942421 1005.799226l-173.980904-171.866839a55.130839 55.130839 0 0 1 0-80.235355c23.221677-22.990452 58.004645-22.990452 81.193291 0l173.947871 171.965936a55.130839 55.130839 0 0 1 0 80.235355 56.419097 56.419097 0 0 1-81.160258 0v-0.099097z" p-id="15527" fill="#ffffff"></path></svg>
|
||||
<svg t="1629269306451" class="icon" viewBox="0 0 1057 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="15526" width="128" height="128">
|
||||
<path d="M409.012356 811.965935c-108.676129 0.660645-213.058065-41.851871-289.924129-117.991225A401.242839 401.242839 0 0 1 0.006937 406.594065a401.242839 401.242839 0 0 1 119.015226-287.512775A408.344774 408.344774 0 0 1 409.012356 0.990968a408.344774 408.344774 0 0 1 289.924129 118.05729 401.275871 401.275871 0 0 1 119.08129 287.44671 401.275871 401.275871 0 0 1-119.048258 287.380645 408.344774 408.344774 0 0 1-289.891096 118.090322h-0.066065z m0-695.130838A290.617806 290.617806 0 0 0 201.63584 200.836129a285.563871 285.563871 0 0 0-84.69471 205.625806c0 162.221419 128.495484 289.626839 292.071226 289.626839 163.641806 0 292.13729-127.405419 292.13729-289.560774 0-162.221419-128.495484-289.725935-292.071225-289.725935h-0.066065zM957.942421 1005.799226l-173.980904-171.866839a55.130839 55.130839 0 0 1 0-80.235355c23.221677-22.990452 58.004645-22.990452 81.193291 0l173.947871 171.965936a55.130839 55.130839 0 0 1 0 80.235355 56.419097 56.419097 0 0 1-81.160258 0v-0.099097z"
|
||||
p-id="15527" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -1 +1,5 @@
|
||||
<svg t="1629269306451" class="icon" viewBox="0 0 1057 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15526" width="128" height="128"><path d="M409.012356 811.965935c-108.676129 0.660645-213.058065-41.851871-289.924129-117.991225A401.242839 401.242839 0 0 1 0.006937 406.594065a401.242839 401.242839 0 0 1 119.015226-287.512775A408.344774 408.344774 0 0 1 409.012356 0.990968a408.344774 408.344774 0 0 1 289.924129 118.05729 401.275871 401.275871 0 0 1 119.08129 287.44671 401.275871 401.275871 0 0 1-119.048258 287.380645 408.344774 408.344774 0 0 1-289.891096 118.090322h-0.066065z m0-695.130838A290.617806 290.617806 0 0 0 201.63584 200.836129a285.563871 285.563871 0 0 0-84.69471 205.625806c0 162.221419 128.495484 289.626839 292.071226 289.626839 163.641806 0 292.13729-127.405419 292.13729-289.560774 0-162.221419-128.495484-289.725935-292.071225-289.725935h-0.066065zM957.942421 1005.799226l-173.980904-171.866839a55.130839 55.130839 0 0 1 0-80.235355c23.221677-22.990452 58.004645-22.990452 81.193291 0l173.947871 171.965936a55.130839 55.130839 0 0 1 0 80.235355 56.419097 56.419097 0 0 1-81.160258 0v-0.099097z" p-id="15527" fill="#0f0f0f"></path></svg>
|
||||
<svg t="1629269306451" class="icon" viewBox="0 0 1057 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="15526" width="128" height="128">
|
||||
<path d="M409.012356 811.965935c-108.676129 0.660645-213.058065-41.851871-289.924129-117.991225A401.242839 401.242839 0 0 1 0.006937 406.594065a401.242839 401.242839 0 0 1 119.015226-287.512775A408.344774 408.344774 0 0 1 409.012356 0.990968a408.344774 408.344774 0 0 1 289.924129 118.05729 401.275871 401.275871 0 0 1 119.08129 287.44671 401.275871 401.275871 0 0 1-119.048258 287.380645 408.344774 408.344774 0 0 1-289.891096 118.090322h-0.066065z m0-695.130838A290.617806 290.617806 0 0 0 201.63584 200.836129a285.563871 285.563871 0 0 0-84.69471 205.625806c0 162.221419 128.495484 289.626839 292.071226 289.626839 163.641806 0 292.13729-127.405419 292.13729-289.560774 0-162.221419-128.495484-289.725935-292.071225-289.725935h-0.066065zM957.942421 1005.799226l-173.980904-171.866839a55.130839 55.130839 0 0 1 0-80.235355c23.221677-22.990452 58.004645-22.990452 81.193291 0l173.947871 171.965936a55.130839 55.130839 0 0 1 0 80.235355 56.419097 56.419097 0 0 1-81.160258 0v-0.099097z"
|
||||
p-id="15527" fill="#0f0f0f"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -1 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48"><path fill-opacity=".01" fill="#fff" d="M0 0h48v48H0z" data-follow-fill="#fff"/><path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="m14 14 20 20M14 34l20-20" data-follow-stroke="#333"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48">
|
||||
<path fill-opacity=".01" fill="#fff" d="M0 0h48v48H0z" data-follow-fill="#fff"/>
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="m14 14 20 20M14 34l20-20"
|
||||
data-follow-stroke="#333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 298 B After Width: | Height: | Size: 319 B |
@@ -1 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48"><path fill-opacity=".01" fill="#fff" d="M0 0h48v48H0z" data-follow-fill="#fff"/><path stroke-linejoin="round" stroke-width="4" stroke="#333" d="M8 15h32l-3 29H11L8 15z" clip-rule="evenodd" data-follow-stroke="#333"/><path stroke-linecap="round" stroke-width="4" stroke="#333" d="M20.002 25.002v10M28.002 25v9.997" data-follow-stroke="#333"/><path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M12 15 28.324 3 36 15" data-follow-stroke="#333"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48">
|
||||
<path fill-opacity=".01" fill="#fff" d="M0 0h48v48H0z" data-follow-fill="#fff"/>
|
||||
<path stroke-linejoin="round" stroke-width="4" stroke="#333" d="M8 15h32l-3 29H11L8 15z" clip-rule="evenodd"
|
||||
data-follow-stroke="#333"/>
|
||||
<path stroke-linecap="round" stroke-width="4" stroke="#333" d="M20.002 25.002v10M28.002 25v9.997"
|
||||
data-follow-stroke="#333"/>
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M12 15 28.324 3 36 15"
|
||||
data-follow-stroke="#333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 556 B After Width: | Height: | Size: 607 B |
@@ -1 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48"><path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M22 42H6V26M26 6h16v16" data-follow-stroke="#333"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48">
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M22 42H6V26M26 6h16v16"
|
||||
data-follow-stroke="#333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 216 B After Width: | Height: | Size: 232 B |
@@ -1 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48"><path stroke-linejoin="round" stroke-width="4" stroke="#333" d="M5 8a2 2 0 0 1 2-2h12l5 6h17a2 2 0 0 1 2 2v26a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V8z" data-follow-stroke="#333"/><path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="m30 28-6.007 6L18 28.013M24 20v14" data-follow-stroke="#333"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48">
|
||||
<path stroke-linejoin="round" stroke-width="4" stroke="#333"
|
||||
d="M5 8a2 2 0 0 1 2-2h12l5 6h17a2 2 0 0 1 2 2v26a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V8z" data-follow-stroke="#333"/>
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333"
|
||||
d="m30 28-6.007 6L18 28.013M24 20v14" data-follow-stroke="#333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 398 B After Width: | Height: | Size: 429 B |
@@ -1 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48"><path fill-opacity=".01" fill="#fff" d="M0 0h48v48H0z" data-follow-fill="#fff"/><path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M36.728 36.728A17.943 17.943 0 0 1 24 42c-9.941 0-18-8.059-18-18S14.059 6 24 6c4.97 0 9.47 2.015 12.728 5.272C38.386 12.93 42 17 42 17" data-follow-stroke="#333"/><path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M42 8v9h-9" data-follow-stroke="#333"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48">
|
||||
<path fill-opacity=".01" fill="#fff" d="M0 0h48v48H0z" data-follow-fill="#fff"/>
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333"
|
||||
d="M36.728 36.728A17.943 17.943 0 0 1 24 42c-9.941 0-18-8.059-18-18S14.059 6 24 6c4.97 0 9.47 2.015 12.728 5.272C38.386 12.93 42 17 42 17"
|
||||
data-follow-stroke="#333"/>
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M42 8v9h-9"
|
||||
data-follow-stroke="#333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 534 B After Width: | Height: | Size: 580 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629255942168" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8597" width="128" height="128"><path d="M512 0C229.248 0 0 229.248 0 512s229.248 512 512 512 512-229.248 512-512S794.752 0 512 0zM432.64 748.256 197.056 512.64l90.496-90.496 145.056 145.12 307.744-307.744 90.496 90.496L432.64 748.256z" p-id="8598" fill="#2DB84D"></path></svg>
|
||||
<svg t="1629255942168" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8597"
|
||||
width="128" height="128">
|
||||
<path d="M512 0C229.248 0 0 229.248 0 512s229.248 512 512 512 512-229.248 512-512S794.752 0 512 0zM432.64 748.256 197.056 512.64l90.496-90.496 145.056 145.12 307.744-307.744 90.496 90.496L432.64 748.256z"
|
||||
p-id="8598" fill="#2DB84D"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 391 B After Width: | Height: | Size: 412 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629255998157" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8792" width="128" height="128"><path d="M512 0C229.248 0 0 229.248 0 512s229.248 512 512 512 512-229.248 512-512S794.752 0 512 0zM320 768 320 256l512.256 256L320 768z" p-id="8793" fill="#00BCD4"></path></svg>
|
||||
<svg t="1629255998157" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8792"
|
||||
width="128" height="128">
|
||||
<path d="M512 0C229.248 0 0 229.248 0 512s229.248 512 512 512 512-229.248 512-512S794.752 0 512 0zM320 768 320 256l512.256 256L320 768z"
|
||||
p-id="8793" fill="#00BCD4"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 323 B After Width: | Height: | Size: 344 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629256110134" class="icon" viewBox="0 0 1185 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3025" width="128" height="128"><path d="M700.365715 60.074208l468.319709 783.01037a118.307323 118.307323 0 0 1-45.345458 164.539234 127.444603 127.444603 0 0 1-62.324434 16.297089H124.376114A122.739586 122.739586 0 0 1 0 903.567918a117.557248 117.557248 0 0 1 16.706221-60.346963L485.02593 60.210586A126.694528 126.694528 0 0 1 655.020257 16.365278a122.739586 122.739586 0 0 1 45.345458 43.845308zM592.764011 916.046443a80.803561 80.803561 0 1 0-80.80356-80.803561 80.803561 80.803561 0 0 0 80.735372 80.803561z m0-673.567572a95.464122 95.464122 0 0 0-94.373104 106.988006l34.09433 270.640786a61.369793 61.369793 0 0 0 121.103058 0l34.094329-270.640786a95.464122 95.464122 0 0 0-94.373103-106.919818z" p-id="3026" fill="#DB3340"></path></svg>
|
||||
<svg t="1629256110134" class="icon" viewBox="0 0 1185 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3025"
|
||||
width="128" height="128">
|
||||
<path d="M700.365715 60.074208l468.319709 783.01037a118.307323 118.307323 0 0 1-45.345458 164.539234 127.444603 127.444603 0 0 1-62.324434 16.297089H124.376114A122.739586 122.739586 0 0 1 0 903.567918a117.557248 117.557248 0 0 1 16.706221-60.346963L485.02593 60.210586A126.694528 126.694528 0 0 1 655.020257 16.365278a122.739586 122.739586 0 0 1 45.345458 43.845308zM592.764011 916.046443a80.803561 80.803561 0 1 0-80.80356-80.803561 80.803561 80.803561 0 0 0 80.735372 80.803561z m0-673.567572a95.464122 95.464122 0 0 0-94.373104 106.988006l34.09433 270.640786a61.369793 61.369793 0 0 0 121.103058 0l34.094329-270.640786a95.464122 95.464122 0 0 0-94.373103-106.919818z"
|
||||
p-id="3026" fill="#DB3340"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 857 B After Width: | Height: | Size: 878 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629251564375" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1864" width="128" height="128"><path d="M490.061576 311.947636a31.030303 31.030303 0 0 1 43.876848 0l310.303031 310.303031a31.030303 31.030303 0 0 1-43.876849 43.876848L512 377.762909l-288.364606 288.364606a31.030303 31.030303 0 0 1-43.876849-43.876848l310.303031-310.303031z" p-id="1865" fill="#326cf3"></path></svg>
|
||||
<svg t="1629251564375" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1864"
|
||||
width="128" height="128">
|
||||
<path d="M490.061576 311.947636a31.030303 31.030303 0 0 1 43.876848 0l310.303031 310.303031a31.030303 31.030303 0 0 1-43.876849 43.876848L512 377.762909l-288.364606 288.364606a31.030303 31.030303 0 0 1-43.876849-43.876848l310.303031-310.303031z"
|
||||
p-id="1865" fill="#326cf3"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 432 B After Width: | Height: | Size: 453 B |
@@ -1 +1,12 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1629184159878" class="icon" viewBox="0 0 1092 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="23123" xmlns:xlink="http://www.w3.org/1999/xlink" width="136.5" height="128"><defs><style type="text/css"></style></defs><path d="M538.624 1017.344L0.580267 405.162667 212.445867 0h652.356266L1076.565333 405.162667z" fill="#46F256" p-id="23124"></path><path d="M538.624 748.6464l-317.44-351.607467 67.618133-61.098666 249.787734 276.718933 249.821866-276.6848 67.618134 61.064533z" fill="#000000" p-id="23125"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1629184159878" class="icon" viewBox="0 0 1092 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="23123" width="136.5" height="128">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M538.624 1017.344L0.580267 405.162667 212.445867 0h652.356266L1076.565333 405.162667z" fill="#46F256"
|
||||
p-id="23124"></path>
|
||||
<path d="M538.624 748.6464l-317.44-351.607467 67.618133-61.098666 249.787734 276.718933 249.821866-276.6848 67.618134 61.064533z"
|
||||
fill="#000000" p-id="23125"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 673 B After Width: | Height: | Size: 694 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629268466285" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="18338" width="128" height="128"><path d="M294.314667 0L242.432 119.424H165.418667v107.648h29.653333L225.152 418.133333H178.005333l62.293334 351.146667 40.021333-0.426667 40.192 255.146667h380.501333l2.645334-17.066667 37.546666-238.08 37.888 0.426667 62.293334-351.189333h-45.056l30.08-191.018667h32.256V119.466667h-81.834667L724.906667 0H294.314667z m22.528 34.346667h385.834666l32.896 75.946666H283.818667l33.024-75.946666z m-117.333334 119.338666H824.32v39.253334H199.509333v-39.253334z m19.328 298.581334h581.76l-50.176 282.453333-241.024-2.56-240.469333 2.56-50.090667-282.453333z" p-id="18339" fill="#ffffff"></path></svg>
|
||||
<svg t="1629268466285" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="18338" width="128" height="128">
|
||||
<path d="M294.314667 0L242.432 119.424H165.418667v107.648h29.653333L225.152 418.133333H178.005333l62.293334 351.146667 40.021333-0.426667 40.192 255.146667h380.501333l2.645334-17.066667 37.546666-238.08 37.888 0.426667 62.293334-351.189333h-45.056l30.08-191.018667h32.256V119.466667h-81.834667L724.906667 0H294.314667z m22.528 34.346667h385.834666l32.896 75.946666H283.818667l33.024-75.946666z m-117.333334 119.338666H824.32v39.253334H199.509333v-39.253334z m19.328 298.581334h581.76l-50.176 282.453333-241.024-2.56-240.469333 2.56-50.090667-282.453333z"
|
||||
p-id="18339" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 743 B After Width: | Height: | Size: 764 B |
@@ -3,4 +3,8 @@
|
||||
<path d="M316.16 366.506667L512 561.92l195.84-195.413333L768 426.666667l-256 256-256-256z" fill="#cbcbcb"
|
||||
p-id="1512"></path>
|
||||
</svg> -->
|
||||
<svg t="1629251448482" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1609" width="128" height="128"><path d="M179.758545 374.008242a31.030303 31.030303 0 0 1 43.876849 0L512 662.372848l288.364606-288.364606a31.030303 31.030303 0 0 1 43.876849 43.876849l-310.303031 310.30303a31.030303 31.030303 0 0 1-43.876848 0l-310.303031-310.30303a31.030303 31.030303 0 0 1 0-43.876849z" p-id="1610" fill="#cbcbcb"></path></svg>
|
||||
<svg t="1629251448482" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1609"
|
||||
width="128" height="128">
|
||||
<path d="M179.758545 374.008242a31.030303 31.030303 0 0 1 43.876849 0L512 662.372848l288.364606-288.364606a31.030303 31.030303 0 0 1 43.876849 43.876849l-310.303031 310.30303a31.030303 31.030303 0 0 1-43.876848 0l-310.303031-310.30303a31.030303 31.030303 0 0 1 0-43.876849z"
|
||||
p-id="1610" fill="#cbcbcb"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 769 B After Width: | Height: | Size: 790 B |
@@ -3,4 +3,8 @@
|
||||
<path d="M316.16 366.506667L512 561.92l195.84-195.413333L768 426.666667l-256 256-256-256z" fill="#326cf3"
|
||||
p-id="1512"></path>
|
||||
</svg> -->
|
||||
<svg t="1629251448482" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1609" width="128" height="128"><path d="M179.758545 374.008242a31.030303 31.030303 0 0 1 43.876849 0L512 662.372848l288.364606-288.364606a31.030303 31.030303 0 0 1 43.876849 43.876849l-310.303031 310.30303a31.030303 31.030303 0 0 1-43.876848 0l-310.303031-310.30303a31.030303 31.030303 0 0 1 0-43.876849z" p-id="1610" fill="#326cf3"></path></svg>
|
||||
<svg t="1629251448482" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1609"
|
||||
width="128" height="128">
|
||||
<path d="M179.758545 374.008242a31.030303 31.030303 0 0 1 43.876849 0L512 662.372848l288.364606-288.364606a31.030303 31.030303 0 0 1 43.876849 43.876849l-310.303031 310.30303a31.030303 31.030303 0 0 1-43.876848 0l-310.303031-310.30303a31.030303 31.030303 0 0 1 0-43.876849z"
|
||||
p-id="1610" fill="#326cf3"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 769 B After Width: | Height: | Size: 790 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629268481541" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19187" width="128" height="128"><path d="M512.032 831.904c-19.168 0-38.304-9.92-58.144-29.76-7.808-7.808-7.808-20.48 0-28.288s20.48-7.808 28.288 0C494.368 786.08 504.16 792 512.032 792s17.664-5.92 29.856-18.144c7.808-7.808 20.48-7.808 28.288 0s7.808 20.48 0 28.288c-19.84 19.84-38.976 29.76-58.144 29.76z m-512-306.4c0 49.888 4.256 95.136 12.8 135.68s20.544 75.744 36 105.536 35.008 55.904 58.656 78.336 49.344 40.928 77.056 55.456c27.744 14.528 59.456 26.304 95.2 35.264S351.84 951.04 388.8 954.624 466.496 960 510.944 960c44.448 0 85.248-1.792 122.4-5.376s73.6-9.856 109.344-18.848c35.744-8.96 67.552-20.736 95.456-35.264s53.792-33.024 77.6-55.456c23.808-22.432 43.456-48.544 58.944-78.336s27.552-64.96 36.256-105.536c8.704-40.576 13.056-85.792 13.056-135.68 0-89.376-27.744-166.368-83.2-230.976 3.2-8.608 5.952-18.496 8.256-29.6s4.544-26.816 6.656-47.104c2.144-20.288 1.344-43.712-2.4-70.272S942.56 93.888 932.256 66.24l-8-1.632c-5.344-1.088-14.048-0.704-26.144 1.088s-26.208 5.024-42.4 9.696-37.056 13.92-62.656 27.744-52.608 31.328-81.056 52.512c-48.352-14.72-115.008-30.112-200-30.112s-151.808 15.392-200.544 30.112c-28.448-21.184-55.552-38.592-81.344-52.224s-46.4-22.976-61.856-28c-15.456-5.024-29.792-8.256-42.944-9.696s-21.6-1.888-25.344-1.344c-3.744 0.544-6.496 1.152-8.256 1.888-10.304 27.648-17.408 54.752-21.344 81.312s-4.8 49.888-2.656 69.984c2.144 20.096 4.448 35.904 6.944 47.392S80 286.304 83.2 294.56C27.744 358.816 0 435.808 0 525.536z m136.544 113.888c0-58.016 21.344-110.624 64-157.856 12.8-14.4 27.648-25.312 44.544-32.704s36.096-11.616 57.6-12.608 42.048-0.8 61.6 0.608 43.744 3.296 72.544 5.696 53.696 3.616 74.656 3.616c20.96 0 45.856-1.184 74.656-3.616s52.992-4.288 72.544-5.696c19.552-1.408 40.096-1.6 61.6-0.608s40.8 5.216 57.856 12.608c17.056 7.392 32 18.304 44.8 32.704 42.656 47.232 64 99.84 64 157.856 0 34.016-3.552 64.32-10.656 90.944s-16.096 48.928-26.944 66.912c-10.848 18.016-26.048 33.216-45.6 45.632s-38.496 22.016-56.8 28.8c-18.304 6.784-41.952 12.096-70.944 15.904s-54.944 6.112-77.856 6.912c-22.944 0.8-51.808 1.216-86.656 1.216s-63.648-0.416-86.4-1.216c-22.752-0.8-48.608-3.104-77.6-6.912s-52.608-9.12-70.944-15.904c-18.304-6.816-37.248-16.416-56.8-28.8s-34.752-27.616-45.6-45.632c-10.848-18.016-19.84-40.32-26.944-66.912s-10.656-56.928-10.656-90.944zM256.032 608c0-53.024 28.64-96 64-96s64 42.976 64 96-28.64 96-64 96-64-42.976-64-96z m384 0c0-53.024 28.64-96 64-96s64 42.976 64 96-28.64 96-64 96-64-42.976-64-96z" p-id="19188"></path></svg>
|
||||
<svg t="1629268481541" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="19187" width="128" height="128">
|
||||
<path d="M512.032 831.904c-19.168 0-38.304-9.92-58.144-29.76-7.808-7.808-7.808-20.48 0-28.288s20.48-7.808 28.288 0C494.368 786.08 504.16 792 512.032 792s17.664-5.92 29.856-18.144c7.808-7.808 20.48-7.808 28.288 0s7.808 20.48 0 28.288c-19.84 19.84-38.976 29.76-58.144 29.76z m-512-306.4c0 49.888 4.256 95.136 12.8 135.68s20.544 75.744 36 105.536 35.008 55.904 58.656 78.336 49.344 40.928 77.056 55.456c27.744 14.528 59.456 26.304 95.2 35.264S351.84 951.04 388.8 954.624 466.496 960 510.944 960c44.448 0 85.248-1.792 122.4-5.376s73.6-9.856 109.344-18.848c35.744-8.96 67.552-20.736 95.456-35.264s53.792-33.024 77.6-55.456c23.808-22.432 43.456-48.544 58.944-78.336s27.552-64.96 36.256-105.536c8.704-40.576 13.056-85.792 13.056-135.68 0-89.376-27.744-166.368-83.2-230.976 3.2-8.608 5.952-18.496 8.256-29.6s4.544-26.816 6.656-47.104c2.144-20.288 1.344-43.712-2.4-70.272S942.56 93.888 932.256 66.24l-8-1.632c-5.344-1.088-14.048-0.704-26.144 1.088s-26.208 5.024-42.4 9.696-37.056 13.92-62.656 27.744-52.608 31.328-81.056 52.512c-48.352-14.72-115.008-30.112-200-30.112s-151.808 15.392-200.544 30.112c-28.448-21.184-55.552-38.592-81.344-52.224s-46.4-22.976-61.856-28c-15.456-5.024-29.792-8.256-42.944-9.696s-21.6-1.888-25.344-1.344c-3.744 0.544-6.496 1.152-8.256 1.888-10.304 27.648-17.408 54.752-21.344 81.312s-4.8 49.888-2.656 69.984c2.144 20.096 4.448 35.904 6.944 47.392S80 286.304 83.2 294.56C27.744 358.816 0 435.808 0 525.536z m136.544 113.888c0-58.016 21.344-110.624 64-157.856 12.8-14.4 27.648-25.312 44.544-32.704s36.096-11.616 57.6-12.608 42.048-0.8 61.6 0.608 43.744 3.296 72.544 5.696 53.696 3.616 74.656 3.616c20.96 0 45.856-1.184 74.656-3.616s52.992-4.288 72.544-5.696c19.552-1.408 40.096-1.6 61.6-0.608s40.8 5.216 57.856 12.608c17.056 7.392 32 18.304 44.8 32.704 42.656 47.232 64 99.84 64 157.856 0 34.016-3.552 64.32-10.656 90.944s-16.096 48.928-26.944 66.912c-10.848 18.016-26.048 33.216-45.6 45.632s-38.496 22.016-56.8 28.8c-18.304 6.784-41.952 12.096-70.944 15.904s-54.944 6.112-77.856 6.912c-22.944 0.8-51.808 1.216-86.656 1.216s-63.648-0.416-86.4-1.216c-22.752-0.8-48.608-3.104-77.6-6.912s-52.608-9.12-70.944-15.904c-18.304-6.816-37.248-16.416-56.8-28.8s-34.752-27.616-45.6-45.632c-10.848-18.016-19.84-40.32-26.944-66.912s-10.656-56.928-10.656-90.944zM256.032 608c0-53.024 28.64-96 64-96s64 42.976 64 96-28.64 96-64 96-64-42.976-64-96z m384 0c0-53.024 28.64-96 64-96s64 42.976 64 96-28.64 96-64 96-64-42.976-64-96z"
|
||||
p-id="19188"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.6 KiB |
@@ -1 +1,5 @@
|
||||
<svg t="1629270772080" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1817" width="128" height="128"><path d="M658.059636 187.826424a31.030303 31.030303 0 0 1 0 43.876849l-288.364606 288.364606 288.364606 288.364606a31.030303 31.030303 0 0 1-43.876848 43.876848l-310.30303-310.30303a31.030303 31.030303 0 0 1 0-43.876848l310.30303-310.303031a31.030303 31.030303 0 0 1 43.876848 0z" p-id="1818"></path></svg>
|
||||
<svg t="1629270772080" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1817"
|
||||
width="128" height="128">
|
||||
<path d="M658.059636 187.826424a31.030303 31.030303 0 0 1 0 43.876849l-288.364606 288.364606 288.364606 288.364606a31.030303 31.030303 0 0 1-43.876848 43.876848l-310.30303-310.30303a31.030303 31.030303 0 0 1 0-43.876848l310.30303-310.303031a31.030303 31.030303 0 0 1 43.876848 0z"
|
||||
p-id="1818"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 452 B After Width: | Height: | Size: 473 B |
@@ -1 +1,10 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1629182866847" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22424" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M938.666667 682.666667v170.666666a85.333333 85.333333 0 0 1-85.333334 85.333334H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334v-170.666666h85.333334v170.666666h682.666666v-170.666666h85.333334z m-384-145.664l140.501333-140.501334 60.330667 60.330667L512 700.330667l-243.498667-243.498667 60.330667-60.330667L469.333333 537.002667V85.333333h85.333334v451.669334z" p-id="22425" fill="#ffffff"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1629182866847" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="22424" width="128" height="128">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M938.666667 682.666667v170.666666a85.333333 85.333333 0 0 1-85.333334 85.333334H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334v-170.666666h85.333334v170.666666h682.666666v-170.666666h85.333334z m-384-145.664l140.501333-140.501334 60.330667 60.330667L512 700.330667l-243.498667-243.498667 60.330667-60.330667L469.333333 537.002667V85.333333h85.333334v451.669334z"
|
||||
p-id="22425" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 792 B After Width: | Height: | Size: 798 B |
@@ -1 +1,10 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1629183863957" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22616" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M938.666667 682.666667v170.666666a85.333333 85.333333 0 0 1-85.333334 85.333334H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334v-170.666666h85.333334v170.666666h682.666666v-170.666666h85.333334z m-384-145.664l140.501333-140.501334 60.330667 60.330667L512 700.330667l-243.498667-243.498667 60.330667-60.330667L469.333333 537.002667V85.333333h85.333334v451.669334z" p-id="22617" fill="#e6e6e6"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1629183863957" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="22616" width="128" height="128">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M938.666667 682.666667v170.666666a85.333333 85.333333 0 0 1-85.333334 85.333334H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334v-170.666666h85.333334v170.666666h682.666666v-170.666666h85.333334z m-384-145.664l140.501333-140.501334 60.330667 60.330667L512 700.330667l-243.498667-243.498667 60.330667-60.330667L469.333333 537.002667V85.333333h85.333334v451.669334z"
|
||||
p-id="22617" fill="#e6e6e6"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 792 B After Width: | Height: | Size: 798 B |
@@ -1 +1,10 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1629182847499" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22040" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M512 981.333333C252.8 981.333333 42.666667 771.2 42.666667 512S252.8 42.666667 512 42.666667s469.333333 210.133333 469.333333 469.333333-210.133333 469.333333-469.333333 469.333333z m0-85.333333a384 384 0 1 0 0-768 384 384 0 0 0 0 768z m42.837333-298.752h42.624v85.333333h-170.666666v-85.333333h42.666666v-85.333333h-42.666666v-85.333334h128v170.666667z m-42.837333-213.333333a42.666667 42.666667 0 1 1 0-85.333334 42.666667 42.666667 0 0 1 0 85.333334z" p-id="22041" fill="#ffffff"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1629182847499" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="22040" width="128" height="128">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M512 981.333333C252.8 981.333333 42.666667 771.2 42.666667 512S252.8 42.666667 512 42.666667s469.333333 210.133333 469.333333 469.333333-210.133333 469.333333-469.333333 469.333333z m0-85.333333a384 384 0 1 0 0-768 384 384 0 0 0 0 768z m42.837333-298.752h42.624v85.333333h-170.666666v-85.333333h42.666666v-85.333333h-42.666666v-85.333334h128v170.666667z m-42.837333-213.333333a42.666667 42.666667 0 1 1 0-85.333334 42.666667 42.666667 0 0 1 0 85.333334z"
|
||||
p-id="22041" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 874 B After Width: | Height: | Size: 880 B |
@@ -1 +1,10 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1629181942259" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21410" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M696.32 635.989333l229.845333 229.845334-60.330666 60.330666-229.845334-229.845333a341.333333 341.333333 0 1 1 60.330667-60.330667zM426.666667 682.666667a256 256 0 1 0 0-512 256 256 0 0 0 0 512z" p-id="21411" fill="#ffffff"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1629181942259" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="21410" width="128" height="128">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M696.32 635.989333l229.845333 229.845334-60.330666 60.330666-229.845334-229.845333a341.333333 341.333333 0 1 1 60.330667-60.330667zM426.666667 682.666667a256 256 0 1 0 0-512 256 256 0 0 0 0 512z"
|
||||
p-id="21411" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 615 B After Width: | Height: | Size: 621 B |
@@ -1 +1,10 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1629182857650" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22232" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M890.581333 797.013333l-94.592 94.592-121.088-33.706666-34.602666 14.250666L578.133333 981.333333h-133.76l-61.824-109.525333-34.56-14.506667-121.088 33.322667-94.549333-94.549333 33.706667-121.088-14.250667-34.602667L42.666667 578.133333v-133.76l109.568-61.824 14.506666-34.56-33.322666-121.088 94.506666-94.506666 121.088 33.749333 34.56-14.250667L445.696 42.666667h133.802667l61.824 109.568 34.56 14.506666 121.045333-33.322666 94.72 94.506666-33.792 121.130667 14.293333 34.56L981.333333 445.738667v133.802666l-109.525333 61.781334-14.506667 34.688 33.28 121.045333z m-123.392-126.805333l37.205334-88.832L896 529.664v-34.304l-91.605333-52.053333-36.650667-88.874667 28.245333-101.333333-24.277333-24.234667-101.674667 27.946667-88.746666-37.205334L529.621333 128h-34.304l-52.053333 91.605333-88.874667 36.650667-101.376-28.288-24.149333 24.149333 27.946667 101.674667-37.205334 88.746667L128 494.208v34.346667l91.52 52.138666 36.650667 88.874667-28.245334 101.376 24.192 24.192 101.674667-27.946667 88.746667 37.205334 51.626666 91.562666h34.346667l52.138667-91.52 88.874666-36.650666 101.376 28.245333 24.234667-24.234667-27.946667-101.589333zM512 682.666667a170.666667 170.666667 0 1 1 0-341.333334 170.666667 170.666667 0 0 1 0 341.333334z m0-85.333334a85.333333 85.333333 0 1 0 0-170.666666 85.333333 85.333333 0 0 0 0 170.666666z" p-id="22233" fill="#ffffff"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1629182857650" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="22232" width="128" height="128">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M890.581333 797.013333l-94.592 94.592-121.088-33.706666-34.602666 14.250666L578.133333 981.333333h-133.76l-61.824-109.525333-34.56-14.506667-121.088 33.322667-94.549333-94.549333 33.706667-121.088-14.250667-34.602667L42.666667 578.133333v-133.76l109.568-61.824 14.506666-34.56-33.322666-121.088 94.506666-94.506666 121.088 33.749333 34.56-14.250667L445.696 42.666667h133.802667l61.824 109.568 34.56 14.506666 121.045333-33.322666 94.72 94.506666-33.792 121.130667 14.293333 34.56L981.333333 445.738667v133.802666l-109.525333 61.781334-14.506667 34.688 33.28 121.045333z m-123.392-126.805333l37.205334-88.832L896 529.664v-34.304l-91.605333-52.053333-36.650667-88.874667 28.245333-101.333333-24.277333-24.234667-101.674667 27.946667-88.746666-37.205334L529.621333 128h-34.304l-52.053333 91.605333-88.874667 36.650667-101.376-28.288-24.149333 24.149333 27.946667 101.674667-37.205334 88.746667L128 494.208v34.346667l91.52 52.138666 36.650667 88.874667-28.245334 101.376 24.192 24.192 101.674667-27.946667 88.746667 37.205334 51.626666 91.562666h34.346667l52.138667-91.52 88.874666-36.650666 101.376 28.245333 24.234667-24.234667-27.946667-101.589333zM512 682.666667a170.666667 170.666667 0 1 1 0-341.333334 170.666667 170.666667 0 0 1 0 341.333334z m0-85.333334a85.333333 85.333333 0 1 0 0-170.666666 85.333333 85.333333 0 0 0 0 170.666666z"
|
||||
p-id="22233" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -1 +1,5 @@
|
||||
<svg t="1629268420515" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16731" width="128" height="128"><path d="M350.8 591.8c-7 38.4-34.8 217.4-43 268-0.6 3.6-2 5-6 5H152.6c-15.2 0-26.2-13.2-24.2-27.8L245.6 93.2c3-19.2 20.2-33.8 40-33.8 304.6 0 330.2-7.4 408 22.8 120.2 46.6 131.2 159 88 280.6-43 125.2-145 179-280.2 180.6-86.8 1.4-139-14-150.6 48.4zM842.2 304c-3.6-2.6-5-3.6-6 2.6-4 22.8-10.2 45-17.6 67.2-79.8 227.6-301 207.8-409 207.8-12.2 0-20.2 6.6-21.8 18.8-45.2 280.8-54.2 339.4-54.2 339.4-2 14.2 7 25.8 21.2 25.8h127c17.2 0 31.4-12.6 34.8-29.8 1.4-10.8-2.2 12.2 28.8-182.6 9.2-44 28.6-39.4 58.6-39.4 142 0 252.8-57.6 285.8-224.6 13-69.6 9.2-142.8-47.6-185.2z" p-id="16732" fill="#ffffff"></path></svg>
|
||||
<svg t="1629268420515" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="16731" width="128" height="128">
|
||||
<path d="M350.8 591.8c-7 38.4-34.8 217.4-43 268-0.6 3.6-2 5-6 5H152.6c-15.2 0-26.2-13.2-24.2-27.8L245.6 93.2c3-19.2 20.2-33.8 40-33.8 304.6 0 330.2-7.4 408 22.8 120.2 46.6 131.2 159 88 280.6-43 125.2-145 179-280.2 180.6-86.8 1.4-139-14-150.6 48.4zM842.2 304c-3.6-2.6-5-3.6-6 2.6-4 22.8-10.2 45-17.6 67.2-79.8 227.6-301 207.8-409 207.8-12.2 0-20.2 6.6-21.8 18.8-45.2 280.8-54.2 339.4-54.2 339.4-2 14.2 7 25.8 21.2 25.8h127c17.2 0 31.4-12.6 34.8-29.8 1.4-10.8-2.2 12.2 28.8-182.6 9.2-44 28.6-39.4 58.6-39.4 142 0 252.8-57.6 285.8-224.6 13-69.6 9.2-142.8-47.6-185.2z"
|
||||
p-id="16732" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 753 B After Width: | Height: | Size: 774 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629270798317" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1968" width="128" height="128"><path d="M365.940364 187.826424a31.030303 31.030303 0 0 1 43.876848 0l310.30303 310.303031a31.030303 31.030303 0 0 1 0 43.876848l-310.30303 310.30303a31.030303 31.030303 0 0 1-43.876848-43.876848l288.364606-288.364606-288.364606-288.364606a31.030303 31.030303 0 0 1 0-43.876849z" p-id="1969"></path></svg>
|
||||
<svg t="1629270798317" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1968"
|
||||
width="128" height="128">
|
||||
<path d="M365.940364 187.826424a31.030303 31.030303 0 0 1 43.876848 0l310.30303 310.303031a31.030303 31.030303 0 0 1 0 43.876848l-310.30303 310.30303a31.030303 31.030303 0 0 1-43.876848-43.876848l288.364606-288.364606-288.364606-288.364606a31.030303 31.030303 0 0 1 0-43.876849z"
|
||||
p-id="1969"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 451 B After Width: | Height: | Size: 472 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629269306451" class="icon" viewBox="0 0 1057 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15526" width="128" height="128"><path d="M409.012356 811.965935c-108.676129 0.660645-213.058065-41.851871-289.924129-117.991225A401.242839 401.242839 0 0 1 0.006937 406.594065a401.242839 401.242839 0 0 1 119.015226-287.512775A408.344774 408.344774 0 0 1 409.012356 0.990968a408.344774 408.344774 0 0 1 289.924129 118.05729 401.275871 401.275871 0 0 1 119.08129 287.44671 401.275871 401.275871 0 0 1-119.048258 287.380645 408.344774 408.344774 0 0 1-289.891096 118.090322h-0.066065z m0-695.130838A290.617806 290.617806 0 0 0 201.63584 200.836129a285.563871 285.563871 0 0 0-84.69471 205.625806c0 162.221419 128.495484 289.626839 292.071226 289.626839 163.641806 0 292.13729-127.405419 292.13729-289.560774 0-162.221419-128.495484-289.725935-292.071225-289.725935h-0.066065zM957.942421 1005.799226l-173.980904-171.866839a55.130839 55.130839 0 0 1 0-80.235355c23.221677-22.990452 58.004645-22.990452 81.193291 0l173.947871 171.965936a55.130839 55.130839 0 0 1 0 80.235355 56.419097 56.419097 0 0 1-81.160258 0v-0.099097z" p-id="15527" fill="#ffffff"></path></svg>
|
||||
<svg t="1629269306451" class="icon" viewBox="0 0 1057 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="15526" width="128" height="128">
|
||||
<path d="M409.012356 811.965935c-108.676129 0.660645-213.058065-41.851871-289.924129-117.991225A401.242839 401.242839 0 0 1 0.006937 406.594065a401.242839 401.242839 0 0 1 119.015226-287.512775A408.344774 408.344774 0 0 1 409.012356 0.990968a408.344774 408.344774 0 0 1 289.924129 118.05729 401.275871 401.275871 0 0 1 119.08129 287.44671 401.275871 401.275871 0 0 1-119.048258 287.380645 408.344774 408.344774 0 0 1-289.891096 118.090322h-0.066065z m0-695.130838A290.617806 290.617806 0 0 0 201.63584 200.836129a285.563871 285.563871 0 0 0-84.69471 205.625806c0 162.221419 128.495484 289.626839 292.071226 289.626839 163.641806 0 292.13729-127.405419 292.13729-289.560774 0-162.221419-128.495484-289.725935-292.071225-289.725935h-0.066065zM957.942421 1005.799226l-173.980904-171.866839a55.130839 55.130839 0 0 1 0-80.235355c23.221677-22.990452 58.004645-22.990452 81.193291 0l173.947871 171.965936a55.130839 55.130839 0 0 1 0 80.235355 56.419097 56.419097 0 0 1-81.160258 0v-0.099097z"
|
||||
p-id="15527" fill="#ffffff"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -1 +1,5 @@
|
||||
<svg t="1629269306451" class="icon" viewBox="0 0 1057 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15526" width="128" height="128"><path d="M409.012356 811.965935c-108.676129 0.660645-213.058065-41.851871-289.924129-117.991225A401.242839 401.242839 0 0 1 0.006937 406.594065a401.242839 401.242839 0 0 1 119.015226-287.512775A408.344774 408.344774 0 0 1 409.012356 0.990968a408.344774 408.344774 0 0 1 289.924129 118.05729 401.275871 401.275871 0 0 1 119.08129 287.44671 401.275871 401.275871 0 0 1-119.048258 287.380645 408.344774 408.344774 0 0 1-289.891096 118.090322h-0.066065z m0-695.130838A290.617806 290.617806 0 0 0 201.63584 200.836129a285.563871 285.563871 0 0 0-84.69471 205.625806c0 162.221419 128.495484 289.626839 292.071226 289.626839 163.641806 0 292.13729-127.405419 292.13729-289.560774 0-162.221419-128.495484-289.725935-292.071225-289.725935h-0.066065zM957.942421 1005.799226l-173.980904-171.866839a55.130839 55.130839 0 0 1 0-80.235355c23.221677-22.990452 58.004645-22.990452 81.193291 0l173.947871 171.965936a55.130839 55.130839 0 0 1 0 80.235355 56.419097 56.419097 0 0 1-81.160258 0v-0.099097z" p-id="15527" fill="#0f0f0f"></path></svg>
|
||||
<svg t="1629269306451" class="icon" viewBox="0 0 1057 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="15526" width="128" height="128">
|
||||
<path d="M409.012356 811.965935c-108.676129 0.660645-213.058065-41.851871-289.924129-117.991225A401.242839 401.242839 0 0 1 0.006937 406.594065a401.242839 401.242839 0 0 1 119.015226-287.512775A408.344774 408.344774 0 0 1 409.012356 0.990968a408.344774 408.344774 0 0 1 289.924129 118.05729 401.275871 401.275871 0 0 1 119.08129 287.44671 401.275871 401.275871 0 0 1-119.048258 287.380645 408.344774 408.344774 0 0 1-289.891096 118.090322h-0.066065z m0-695.130838A290.617806 290.617806 0 0 0 201.63584 200.836129a285.563871 285.563871 0 0 0-84.69471 205.625806c0 162.221419 128.495484 289.626839 292.071226 289.626839 163.641806 0 292.13729-127.405419 292.13729-289.560774 0-162.221419-128.495484-289.725935-292.071225-289.725935h-0.066065zM957.942421 1005.799226l-173.980904-171.866839a55.130839 55.130839 0 0 1 0-80.235355c23.221677-22.990452 58.004645-22.990452 81.193291 0l173.947871 171.965936a55.130839 55.130839 0 0 1 0 80.235355 56.419097 56.419097 0 0 1-81.160258 0v-0.099097z"
|
||||
p-id="15527" fill="#0f0f0f"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -1 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48"><path fill-opacity=".01" fill="#fff" d="M0 0h48v48H0z" data-follow-fill="#fff"/><path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="m14 14 20 20M14 34l20-20" data-follow-stroke="#333"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48">
|
||||
<path fill-opacity=".01" fill="#fff" d="M0 0h48v48H0z" data-follow-fill="#fff"/>
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="m14 14 20 20M14 34l20-20"
|
||||
data-follow-stroke="#333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 298 B After Width: | Height: | Size: 319 B |
@@ -1 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48"><path fill-opacity=".01" fill="#fff" d="M0 0h48v48H0z" data-follow-fill="#fff"/><path stroke-linejoin="round" stroke-width="4" stroke="#333" d="M8 15h32l-3 29H11L8 15z" clip-rule="evenodd" data-follow-stroke="#333"/><path stroke-linecap="round" stroke-width="4" stroke="#333" d="M20.002 25.002v10M28.002 25v9.997" data-follow-stroke="#333"/><path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M12 15 28.324 3 36 15" data-follow-stroke="#333"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48">
|
||||
<path fill-opacity=".01" fill="#fff" d="M0 0h48v48H0z" data-follow-fill="#fff"/>
|
||||
<path stroke-linejoin="round" stroke-width="4" stroke="#333" d="M8 15h32l-3 29H11L8 15z" clip-rule="evenodd"
|
||||
data-follow-stroke="#333"/>
|
||||
<path stroke-linecap="round" stroke-width="4" stroke="#333" d="M20.002 25.002v10M28.002 25v9.997"
|
||||
data-follow-stroke="#333"/>
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M12 15 28.324 3 36 15"
|
||||
data-follow-stroke="#333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 556 B After Width: | Height: | Size: 607 B |
@@ -1 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48"><path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M22 42H6V26M26 6h16v16" data-follow-stroke="#333"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48">
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M22 42H6V26M26 6h16v16"
|
||||
data-follow-stroke="#333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 216 B After Width: | Height: | Size: 232 B |
@@ -1 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48"><path stroke-linejoin="round" stroke-width="4" stroke="#333" d="M5 8a2 2 0 0 1 2-2h12l5 6h17a2 2 0 0 1 2 2v26a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V8z" data-follow-stroke="#333"/><path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="m30 28-6.007 6L18 28.013M24 20v14" data-follow-stroke="#333"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48">
|
||||
<path stroke-linejoin="round" stroke-width="4" stroke="#333"
|
||||
d="M5 8a2 2 0 0 1 2-2h12l5 6h17a2 2 0 0 1 2 2v26a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V8z" data-follow-stroke="#333"/>
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333"
|
||||
d="m30 28-6.007 6L18 28.013M24 20v14" data-follow-stroke="#333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 398 B After Width: | Height: | Size: 429 B |
@@ -1 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48"><path fill-opacity=".01" fill="#fff" d="M0 0h48v48H0z" data-follow-fill="#fff"/><path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M36.728 36.728A17.943 17.943 0 0 1 24 42c-9.941 0-18-8.059-18-18S14.059 6 24 6c4.97 0 9.47 2.015 12.728 5.272C38.386 12.93 42 17 42 17" data-follow-stroke="#333"/><path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M42 8v9h-9" data-follow-stroke="#333"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48">
|
||||
<path fill-opacity=".01" fill="#fff" d="M0 0h48v48H0z" data-follow-fill="#fff"/>
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333"
|
||||
d="M36.728 36.728A17.943 17.943 0 0 1 24 42c-9.941 0-18-8.059-18-18S14.059 6 24 6c4.97 0 9.47 2.015 12.728 5.272C38.386 12.93 42 17 42 17"
|
||||
data-follow-stroke="#333"/>
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="4" stroke="#333" d="M42 8v9h-9"
|
||||
data-follow-stroke="#333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 534 B After Width: | Height: | Size: 580 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629255942168" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8597" width="128" height="128"><path d="M512 0C229.248 0 0 229.248 0 512s229.248 512 512 512 512-229.248 512-512S794.752 0 512 0zM432.64 748.256 197.056 512.64l90.496-90.496 145.056 145.12 307.744-307.744 90.496 90.496L432.64 748.256z" p-id="8598" fill="#2DB84D"></path></svg>
|
||||
<svg t="1629255942168" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8597"
|
||||
width="128" height="128">
|
||||
<path d="M512 0C229.248 0 0 229.248 0 512s229.248 512 512 512 512-229.248 512-512S794.752 0 512 0zM432.64 748.256 197.056 512.64l90.496-90.496 145.056 145.12 307.744-307.744 90.496 90.496L432.64 748.256z"
|
||||
p-id="8598" fill="#2DB84D"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 391 B After Width: | Height: | Size: 412 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629255998157" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8792" width="128" height="128"><path d="M512 0C229.248 0 0 229.248 0 512s229.248 512 512 512 512-229.248 512-512S794.752 0 512 0zM320 768 320 256l512.256 256L320 768z" p-id="8793" fill="#00BCD4"></path></svg>
|
||||
<svg t="1629255998157" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8792"
|
||||
width="128" height="128">
|
||||
<path d="M512 0C229.248 0 0 229.248 0 512s229.248 512 512 512 512-229.248 512-512S794.752 0 512 0zM320 768 320 256l512.256 256L320 768z"
|
||||
p-id="8793" fill="#00BCD4"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 323 B After Width: | Height: | Size: 344 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629256110134" class="icon" viewBox="0 0 1185 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3025" width="128" height="128"><path d="M700.365715 60.074208l468.319709 783.01037a118.307323 118.307323 0 0 1-45.345458 164.539234 127.444603 127.444603 0 0 1-62.324434 16.297089H124.376114A122.739586 122.739586 0 0 1 0 903.567918a117.557248 117.557248 0 0 1 16.706221-60.346963L485.02593 60.210586A126.694528 126.694528 0 0 1 655.020257 16.365278a122.739586 122.739586 0 0 1 45.345458 43.845308zM592.764011 916.046443a80.803561 80.803561 0 1 0-80.80356-80.803561 80.803561 80.803561 0 0 0 80.735372 80.803561z m0-673.567572a95.464122 95.464122 0 0 0-94.373104 106.988006l34.09433 270.640786a61.369793 61.369793 0 0 0 121.103058 0l34.094329-270.640786a95.464122 95.464122 0 0 0-94.373103-106.919818z" p-id="3026" fill="#DB3340"></path></svg>
|
||||
<svg t="1629256110134" class="icon" viewBox="0 0 1185 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3025"
|
||||
width="128" height="128">
|
||||
<path d="M700.365715 60.074208l468.319709 783.01037a118.307323 118.307323 0 0 1-45.345458 164.539234 127.444603 127.444603 0 0 1-62.324434 16.297089H124.376114A122.739586 122.739586 0 0 1 0 903.567918a117.557248 117.557248 0 0 1 16.706221-60.346963L485.02593 60.210586A126.694528 126.694528 0 0 1 655.020257 16.365278a122.739586 122.739586 0 0 1 45.345458 43.845308zM592.764011 916.046443a80.803561 80.803561 0 1 0-80.80356-80.803561 80.803561 80.803561 0 0 0 80.735372 80.803561z m0-673.567572a95.464122 95.464122 0 0 0-94.373104 106.988006l34.09433 270.640786a61.369793 61.369793 0 0 0 121.103058 0l34.094329-270.640786a95.464122 95.464122 0 0 0-94.373103-106.919818z"
|
||||
p-id="3026" fill="#DB3340"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 857 B After Width: | Height: | Size: 878 B |
@@ -1 +1,5 @@
|
||||
<svg t="1629251564375" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1864" width="128" height="128"><path d="M490.061576 311.947636a31.030303 31.030303 0 0 1 43.876848 0l310.303031 310.303031a31.030303 31.030303 0 0 1-43.876849 43.876848L512 377.762909l-288.364606 288.364606a31.030303 31.030303 0 0 1-43.876849-43.876848l310.303031-310.303031z" p-id="1865" fill="#326cf3"></path></svg>
|
||||
<svg t="1629251564375" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1864"
|
||||
width="128" height="128">
|
||||
<path d="M490.061576 311.947636a31.030303 31.030303 0 0 1 43.876848 0l310.303031 310.303031a31.030303 31.030303 0 0 1-43.876849 43.876848L512 377.762909l-288.364606 288.364606a31.030303 31.030303 0 0 1-43.876849-43.876848l310.303031-310.303031z"
|
||||
p-id="1865" fill="#326cf3"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 432 B After Width: | Height: | Size: 453 B |
@@ -94,7 +94,18 @@ QWidget#AboutWidget {
|
||||
|
||||
}
|
||||
|
||||
|
||||
QScrollBar::vertical{
|
||||
background:transparent;
|
||||
width: 4px;
|
||||
border-radius:6px;
|
||||
}
|
||||
QScrollBar::handle{
|
||||
background: lightgray;
|
||||
border-radius:6px;
|
||||
}
|
||||
QScrollBar::handle:hover{background:gray;}
|
||||
QScrollBar::sub-line{background:transparent;}
|
||||
QScrollBar::add-line{background:transparent;}
|
||||
|
||||
/* PushButton Style */
|
||||
|
||||
|
||||
@@ -33,13 +33,13 @@ class ButtonStyle(Enum):
|
||||
|
||||
PrePage = 14
|
||||
NextPage = 15
|
||||
|
||||
|
||||
TaskRetry = 16,
|
||||
TaskCancel = 17,
|
||||
TaskDelete = 18,
|
||||
TaskOpen = 19,
|
||||
TaskExpand = 20,
|
||||
|
||||
|
||||
|
||||
class LabelStyle(Enum):
|
||||
Default = 0,
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import aigpy
|
||||
|
||||
from tidal_gui.style import ThemeStyle
|
||||
|
||||
_RESOURCE_PATH = './resource'
|
||||
@@ -20,7 +22,6 @@ else:
|
||||
_RESOURCE_PATH = aigpy.path.getDirName(__file__).replace('\\', '/') + "resource"
|
||||
|
||||
|
||||
|
||||
def __getParam__(line: str):
|
||||
key = aigpy.string.getSub(line, "--", ":")
|
||||
value = aigpy.string.getSub(line, ":", ";")
|
||||
@@ -55,9 +56,11 @@ def __getQss__(filePath: str) -> str:
|
||||
qss = __parseQss__(content, params)
|
||||
return qss
|
||||
|
||||
|
||||
def getResourcePath():
|
||||
return _RESOURCE_PATH
|
||||
|
||||
|
||||
def getThemeQssContent(style: ThemeStyle = ThemeStyle.Default):
|
||||
name = "theme" + style.name + ".qss"
|
||||
return __getQss__(_RESOURCE_PATH + '/' + name)
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
@File : tidalImp.py
|
||||
@Date : 2021/9/2
|
||||
@Author : Yaronzz
|
||||
@Version : 1.0
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
import time
|
||||
|
||||
import requests
|
||||
import tidal_dl.model
|
||||
import tidal_dl.enums
|
||||
from aigpy.stringHelper import isNull
|
||||
from tidal_dl import TokenSettings, TOKEN, TidalAPI, CONF
|
||||
from tidal_dl.util import getAlbumPath, getPlaylistPath, getTrackPath
|
||||
|
||||
|
||||
class TidalImp(TidalAPI):
|
||||
def __init__(self):
|
||||
super(TidalImp, self).__init__()
|
||||
|
||||
def loginByConfig(self):
|
||||
if isNull(TOKEN.accessToken):
|
||||
return False
|
||||
|
||||
msg, check = self.verifyAccessToken(TOKEN.accessToken)
|
||||
if check:
|
||||
self.key.countryCode = TOKEN.countryCode
|
||||
self.key.userId = TOKEN.userid
|
||||
self.key.accessToken = TOKEN.accessToken
|
||||
return True
|
||||
|
||||
msg, check = self.refreshAccessToken(TOKEN.refreshToken)
|
||||
if check:
|
||||
TOKEN.userid = self.key.userId
|
||||
TOKEN.countryCode = self.key.countryCode
|
||||
TOKEN.accessToken = self.key.accessToken
|
||||
TOKEN.expiresAfter = time.time() + int(self.key.expiresIn)
|
||||
TokenSettings.save(TOKEN)
|
||||
return True
|
||||
else:
|
||||
tmp = TokenSettings() # clears saved tokens
|
||||
TokenSettings.save(tmp)
|
||||
return False
|
||||
|
||||
def loginByWeb(self):
|
||||
start = time.time()
|
||||
elapsed = 0
|
||||
while elapsed < self.key.authCheckTimeout:
|
||||
elapsed = time.time() - start
|
||||
msg, check = self.checkAuthStatus()
|
||||
if not check:
|
||||
if msg == "pending":
|
||||
time.sleep(self.key.authCheckInterval + 1)
|
||||
continue
|
||||
return False
|
||||
if check:
|
||||
TOKEN.userid = self.key.userId
|
||||
TOKEN.countryCode = self.key.countryCode
|
||||
TOKEN.accessToken = self.key.accessToken
|
||||
TOKEN.refreshToken = self.key.refreshToken
|
||||
TOKEN.expiresAfter = time.time() + int(self.key.expiresIn)
|
||||
TokenSettings.save(TOKEN)
|
||||
return True
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def getArtistsNames(artists): # : list[tidal_dl.model.Artist]
|
||||
ret = []
|
||||
for item in artists:
|
||||
ret.append(item.name)
|
||||
return ','.join(ret)
|
||||
|
||||
@staticmethod
|
||||
def getDurationString(seconds: int):
|
||||
m, s = divmod(seconds, 60)
|
||||
h, m = divmod(m, 60)
|
||||
return "%02d:%02d:%02d" % (h, m, s)
|
||||
|
||||
def getCoverData(self, sid, width="320", height="320"):
|
||||
url = self.getCoverUrl(sid, width, height)
|
||||
try:
|
||||
respond = requests.get(url)
|
||||
return respond.content
|
||||
except:
|
||||
return ''
|
||||
|
||||
@staticmethod
|
||||
def getAudioQualityList():
|
||||
return map(lambda quality: quality.name, tidal_dl.enums.AudioQuality)
|
||||
|
||||
@staticmethod
|
||||
def getVideoQualityList():
|
||||
return map(lambda quality: quality.name, tidal_dl.enums.VideoQuality)
|
||||
|
||||
def getBasePath(self, model):
|
||||
if isinstance(model, tidal_dl.model.Album):
|
||||
return getAlbumPath(CONF, model)
|
||||
if isinstance(model, tidal_dl.model.Playlist):
|
||||
return getPlaylistPath(CONF, model)
|
||||
if isinstance(model, tidal_dl.model.Track):
|
||||
return getAlbumPath(CONF, model.album)
|
||||
if isinstance(model, tidal_dl.model.Video):
|
||||
return CONF.downloadPath + '/Video/'
|
||||
return './'
|
||||
|
||||
def getConfig(self):
|
||||
return CONF
|
||||
|
||||
# def getTackPath(self, basePath, track, stream, album=None, playlist=None):
|
||||
# # number
|
||||
# number = __getIndexStr__(track.trackNumber)
|
||||
# if playlist is not None and CONF.usePlaylistFolder:
|
||||
# number = __getIndexStr__(track.trackNumberOnPlaylist)
|
||||
# # artist
|
||||
# artist = aigpy.path.replaceLimitChar(__getArtistsString__(track.artists), '-')
|
||||
# # title
|
||||
# title = track.title
|
||||
# if not aigpy.string.isNull(track.version):
|
||||
# title += ' (' + track.version + ')'
|
||||
# title = aigpy.path.replaceLimitChar(title, '-')
|
||||
# # get explicit
|
||||
# explicit = "(Explicit)" if CONF.addExplicitTag and track.explicit else ''
|
||||
# # album and addyear
|
||||
# albumname = aigpy.path.replaceLimitChar(album.title, '-')
|
||||
# year = ""
|
||||
# if album.releaseDate is not None:
|
||||
# year = aigpy.string.getSubOnlyEnd(album.releaseDate, '-')
|
||||
# # extension
|
||||
# extension = __getExtension__(stream.url)
|
||||
# retpath = CONF.trackFileFormat
|
||||
# if retpath is None or len(retpath) <= 0:
|
||||
# retpath = Settings.getDefaultTrackFileFormat()
|
||||
# retpath = retpath.replace(R"{TrackNumber}", number)
|
||||
# retpath = retpath.replace(R"{ArtistName}", artist.strip())
|
||||
# retpath = retpath.replace(R"{TrackTitle}", title)
|
||||
# retpath = retpath.replace(R"{ExplicitFlag}", explicit)
|
||||
# retpath = retpath.replace(R"{AlbumYear}", year)
|
||||
# retpath = retpath.replace(R"{AlbumTitle}", albumname.strip())
|
||||
# retpath = retpath.strip()
|
||||
# return basePath + retpath + extension
|
||||
|
||||
# def getVideoPath(self, basePath, video):
|
||||
# # hyphen
|
||||
# hyphen = ' - ' if CONF.addHyphen else ' '
|
||||
# # get number
|
||||
# number = ''
|
||||
# if CONF.useTrackNumber:
|
||||
# number = __getIndexStr__(video.trackNumber) + hyphen
|
||||
# # get artist
|
||||
# artist = ''
|
||||
# if CONF.artistBeforeTitle:
|
||||
# artist = aigpy.path.replaceLimitChar(__getArtistsString__(video.artists), '-') + hyphen
|
||||
# # get explicit
|
||||
# explicit = "(Explicit)" if CONF.addExplicitTag and video.explicit else ''
|
||||
# # title
|
||||
# title = aigpy.path.replaceLimitChar(video.title, '-')
|
||||
# # extension
|
||||
# extension = ".mp4"
|
||||
# return basePath + number + artist.strip() + title + explicit + extension
|
||||
|
||||
tidalImp = TidalImp()
|
||||
@@ -8,14 +8,11 @@
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
from PyQt5.QtGui import QPixmap
|
||||
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QTableWidget, QVBoxLayout, QGridLayout, QProgressBar
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QGridLayout, QProgressBar
|
||||
|
||||
from tidal_gui.control.label import Label
|
||||
from tidal_gui.control.layout import createHBoxLayout, createVBoxLayout
|
||||
from tidal_gui.control.pushButton import PushButton
|
||||
from tidal_gui.style import LabelStyle, ButtonStyle
|
||||
from tidal_gui.style import LabelStyle
|
||||
|
||||
|
||||
class DownloadItemView(QWidget):
|
||||
@@ -38,6 +35,7 @@ class DownloadItemView(QWidget):
|
||||
self._progress.setTextVisible(False)
|
||||
self._progress.setFixedHeight(3)
|
||||
self._progress.setFixedWidth(300)
|
||||
self._progress.setRange(0, 100)
|
||||
|
||||
grid = QGridLayout(self)
|
||||
grid.addWidget(self._indexLabel, 0, 0, Qt.AlignLeft | Qt.AlignVCenter)
|
||||
@@ -46,14 +44,14 @@ class DownloadItemView(QWidget):
|
||||
grid.addWidget(self._progress, 0, 3, Qt.AlignRight | Qt.AlignVCenter)
|
||||
grid.addWidget(self._actionLabel, 0, 4, Qt.AlignRight | Qt.AlignVCenter)
|
||||
grid.addWidget(self._errLabel, 1, 1, Qt.AlignLeft | Qt.AlignVCenter)
|
||||
|
||||
|
||||
grid.setColumnStretch(1, 1)
|
||||
|
||||
|
||||
layout = QHBoxLayout()
|
||||
layout.setSpacing(30)
|
||||
layout.addWidget(self._sizeLabel)
|
||||
layout.addWidget(self._speedLabel)
|
||||
|
||||
|
||||
grid.addLayout(layout, 1, 3, Qt.AlignLeft | Qt.AlignVCenter)
|
||||
|
||||
def setLabel(self, index, title, own):
|
||||
@@ -70,9 +68,9 @@ class DownloadItemView(QWidget):
|
||||
def setProgress(self, value):
|
||||
self._progress.setValue(value)
|
||||
pass
|
||||
|
||||
|
||||
def setSize(self, curSize: str, totalSize: str):
|
||||
self._sizeLabel.setText(f'{curSize}/{totalSize}')
|
||||
|
||||
|
||||
def setSpeed(self, speed: str):
|
||||
self._speedLabel.setText(speed)
|
||||
|
||||
@@ -87,7 +87,7 @@ class MainView(FramelessWidget):
|
||||
self._moveWidget.setFixedHeight(30)
|
||||
self._moveWidget.setObjectName("BaseWidget")
|
||||
return self._moveWidget
|
||||
|
||||
|
||||
def __initContent__(self) -> QGridLayout:
|
||||
self._searchView = None
|
||||
self._settingsView = None
|
||||
|
||||
@@ -9,21 +9,20 @@
|
||||
@Desc :
|
||||
"""
|
||||
import threading
|
||||
import tidal_dl.model
|
||||
|
||||
from PyQt5.QtCore import Qt, QUrl
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QTabWidget
|
||||
from tidal_dl import Type
|
||||
|
||||
import tidal_dl.model
|
||||
from tidal_dl import Type
|
||||
from tidal_dl.util import API, getDurationString
|
||||
from tidal_gui.control.comboBox import ComboBox
|
||||
from tidal_gui.control.label import Label
|
||||
from tidal_gui.control.layout import createHBoxLayout, createVBoxLayout
|
||||
from tidal_gui.control.lineEdit import LineEdit
|
||||
from tidal_gui.control.pushButton import PushButton
|
||||
from tidal_gui.control.tableView import TableView
|
||||
from tidal_gui.control.tableWidget import TableWidget
|
||||
from tidal_gui.style import ButtonStyle, LabelStyle
|
||||
from tidal_gui.theme import getResourcePath
|
||||
from tidal_gui.tidalImp import tidalImp
|
||||
|
||||
|
||||
class SearchView(QWidget):
|
||||
@@ -57,7 +56,7 @@ class SearchView(QWidget):
|
||||
|
||||
self._prePageBtn = PushButton('', ButtonStyle.PrePage)
|
||||
self._nextPageBtn = PushButton('', ButtonStyle.NextPage)
|
||||
|
||||
|
||||
self._pageIndexEdit = LineEdit('')
|
||||
self._pageIndexEdit.setAlignment(Qt.AlignCenter)
|
||||
self._pageIndexEdit.setEnabled(False)
|
||||
@@ -123,12 +122,12 @@ class SearchView(QWidget):
|
||||
datas = []
|
||||
for index, item in enumerate(items):
|
||||
rowData = [str(index + 1 + indexOffset),
|
||||
QUrl(tidalImp.getCoverUrl(item.cover)),
|
||||
tidalImp.getFlag(item, Type.Album, True),
|
||||
QUrl(API.getCoverUrl(item.cover)),
|
||||
API.getFlag(item, Type.Album, True),
|
||||
item.title,
|
||||
item.artists[0].name,
|
||||
str(item.releaseDate),
|
||||
tidalImp.getDurationString(item.duration)]
|
||||
API.getDurationString(item.duration)]
|
||||
datas.append(rowData)
|
||||
|
||||
elif stype == Type.Track:
|
||||
@@ -136,11 +135,11 @@ class SearchView(QWidget):
|
||||
datas = []
|
||||
for index, item in enumerate(items):
|
||||
rowData = [str(index + 1 + indexOffset),
|
||||
tidalImp.getFlag(item, Type.Track, True),
|
||||
API.getFlag(item, Type.Track, True),
|
||||
item.title,
|
||||
item.album.title,
|
||||
item.artists[0].name,
|
||||
tidalImp.getDurationString(item.duration)]
|
||||
getDurationString(item.duration)]
|
||||
datas.append(rowData)
|
||||
|
||||
elif stype == Type.Video:
|
||||
@@ -148,11 +147,11 @@ class SearchView(QWidget):
|
||||
datas = []
|
||||
for index, item in enumerate(items):
|
||||
rowData = [str(index + 1 + indexOffset),
|
||||
QUrl(tidalImp.getCoverUrl(item.imageID)),
|
||||
tidalImp.getFlag(item, Type.Video, True),
|
||||
QUrl(API.getCoverUrl(item.imageID)),
|
||||
API.getFlag(item, Type.Video, True),
|
||||
item.title,
|
||||
item.artists[0].name,
|
||||
tidalImp.getDurationString(item.duration)]
|
||||
getDurationString(item.duration)]
|
||||
datas.append(rowData)
|
||||
|
||||
elif stype == Type.Playlist:
|
||||
@@ -160,10 +159,10 @@ class SearchView(QWidget):
|
||||
datas = []
|
||||
for index, item in enumerate(items):
|
||||
rowData = [str(index + 1 + indexOffset),
|
||||
QUrl(tidalImp.getCoverUrl(item.squareImage)),
|
||||
QUrl(API.getCoverUrl(item.squareImage)),
|
||||
item.title,
|
||||
'',
|
||||
tidalImp.getDurationString(item.duration)]
|
||||
getDurationString(item.duration)]
|
||||
datas.append(rowData)
|
||||
|
||||
for index, rowData in enumerate(datas):
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QPixmap
|
||||
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QTableWidget, QVBoxLayout, QListView, QGridLayout
|
||||
from PyQt5.QtCore import Qt, QPoint
|
||||
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout
|
||||
|
||||
from tidal_gui.control.label import Label
|
||||
from tidal_gui.control.layout import createHBoxLayout, createVBoxLayout
|
||||
from tidal_gui.control.pushButton import PushButton
|
||||
from tidal_gui.control.listWidget import ListWidget
|
||||
from tidal_gui.control.pushButton import PushButton
|
||||
from tidal_gui.style import LabelStyle, ButtonStyle, ListWidgetStyle
|
||||
|
||||
|
||||
@@ -25,12 +25,12 @@ class TaskItemView(QWidget):
|
||||
self.__initView__()
|
||||
self.setObjectName('TaskItemView')
|
||||
self.setAttribute(Qt.WA_StyledBackground)
|
||||
|
||||
|
||||
def __initView__(self):
|
||||
layout = QVBoxLayout()
|
||||
layout.addLayout(self.__initHead__(), Qt.AlignTop)
|
||||
layout.addWidget(self.__initList__(), Qt.AlignTop)
|
||||
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
def __initHead__(self):
|
||||
@@ -95,4 +95,3 @@ class TaskItemView(QWidget):
|
||||
self._btnDelete.clicked.connect(func)
|
||||
elif name == 'open':
|
||||
self._btnOpen.clicked.connect(func)
|
||||
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
@Desc :
|
||||
"""
|
||||
from enum import Enum
|
||||
|
||||
from PyQt5.QtCore import Qt, QSize
|
||||
from PyQt5.QtWidgets import QWidget, QGridLayout, QListWidgetItem, QListView
|
||||
from PyQt5.QtWidgets import QWidget, QGridLayout, QListWidgetItem
|
||||
|
||||
from tidal_gui.control.label import Label
|
||||
from tidal_gui.control.line import Line
|
||||
@@ -18,7 +19,6 @@ from tidal_gui.control.listWidget import ListWidget
|
||||
from tidal_gui.control.scrollWidget import ScrollWidget
|
||||
from tidal_gui.style import LabelStyle, ListWidgetStyle
|
||||
from tidal_gui.theme import getResourcePath
|
||||
from tidal_gui.view.taskItemView import TaskItemView
|
||||
|
||||
|
||||
class TaskListType(Enum):
|
||||
|
||||
@@ -8,4 +8,3 @@
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
|
||||
|
||||
@@ -9,27 +9,42 @@
|
||||
@Desc :
|
||||
"""
|
||||
|
||||
import _thread
|
||||
import os
|
||||
import time
|
||||
from abc import ABC, ABCMeta
|
||||
from enum import Enum
|
||||
from pickle import FALSE
|
||||
from aigpy.downloadHelper import UserProgress
|
||||
import aigpy.stringHelper
|
||||
from tidal_dl import Type
|
||||
from tidal_dl.model import Album, Track, Video, Playlist
|
||||
|
||||
from tidal_gui.tidalImp import tidalImp
|
||||
from tidal_dl.model import Track
|
||||
from tidal_dl.util import downloadTrack, downloadVideo, getArtistsNames, setMetaData
|
||||
from tidal_gui.view.downloadItemView import DownloadItemView
|
||||
from tidal_gui.viewModel.viewModel import ViewModel
|
||||
|
||||
|
||||
class DownloadStatus(Enum):
|
||||
Wait = 0,
|
||||
Running = 1,
|
||||
Finish = 2,
|
||||
Error = 3,
|
||||
Cancel = 4,
|
||||
|
||||
|
||||
|
||||
_endStatus_ = [DownloadStatus.Finish, DownloadStatus.Error, DownloadStatus.Cancel]
|
||||
|
||||
|
||||
class Progress(UserProgress):
|
||||
def __init__(self, model):
|
||||
super().__init__()
|
||||
self.model = model
|
||||
|
||||
def updateCurNum(self):
|
||||
self.model.update(self.curNum, self.maxNum)
|
||||
|
||||
def updateMaxNum(self):
|
||||
pass
|
||||
|
||||
|
||||
class DownloadItemModel(ViewModel):
|
||||
def __init__(self, index, data, basePath):
|
||||
super(DownloadItemModel, self).__init__()
|
||||
@@ -37,8 +52,9 @@ class DownloadItemModel(ViewModel):
|
||||
self.data = data
|
||||
self.basePath = basePath
|
||||
self.isTrack = isinstance(data, Track)
|
||||
self.progress = Progress(self)
|
||||
self.__setStatus__(DownloadStatus.Wait)
|
||||
|
||||
|
||||
if self.isTrack:
|
||||
self.__initTrack__(index)
|
||||
else:
|
||||
@@ -50,7 +66,12 @@ class DownloadItemModel(ViewModel):
|
||||
self.view.setAction(status.name)
|
||||
else:
|
||||
self.view.setAction(status.name + '-' + desc)
|
||||
|
||||
|
||||
def __setErrStatus__(self, errmsg: str):
|
||||
self.status = DownloadStatus.Error
|
||||
self.view.setAction(self.status.name)
|
||||
self.view.setErrmsg(errmsg)
|
||||
|
||||
def __initTrack__(self, index):
|
||||
title = self.data.title
|
||||
own = self.data.album.title
|
||||
@@ -58,84 +79,36 @@ class DownloadItemModel(ViewModel):
|
||||
|
||||
def __initVideo__(self, index):
|
||||
title = self.data.title
|
||||
own = tidalImp.getArtistsNames(self.data.artists)
|
||||
own = getArtistsNames(self.data.artists)
|
||||
self.view.setLabel(index, title, own)
|
||||
|
||||
def update(self, curNum, maxNum):
|
||||
per = curNum * 100 / maxNum
|
||||
self.view.setProgress(per)
|
||||
|
||||
def isInWait(self):
|
||||
return self.status == DownloadStatus.Wait
|
||||
|
||||
|
||||
def stopDownload(self):
|
||||
if self.status not in _endStatus_:
|
||||
self.__setStatus__(DownloadStatus.Cancel)
|
||||
|
||||
def retry(self):
|
||||
self.__setStatus__(DownloadStatus.Wait)
|
||||
|
||||
|
||||
def download(self):
|
||||
self.__setStatus__(DownloadStatus.Running)
|
||||
|
||||
|
||||
if self.isTrack:
|
||||
if not self.__dlTrack__():
|
||||
return
|
||||
check, msg = downloadTrack(self.data, self.data.album, self.data.playlist, self.progress)
|
||||
else:
|
||||
if not self.__dlVideo__():
|
||||
return
|
||||
check, msg = downloadVideo(self.data)
|
||||
|
||||
if check is False:
|
||||
self.__setErrStatus__(msg)
|
||||
else:
|
||||
self.__setStatus__(DownloadStatus.Finish)
|
||||
|
||||
self.view.setProgress(100)
|
||||
self.__setStatus__(DownloadStatus.Finish)
|
||||
|
||||
def __dlTrack__(self):
|
||||
try:
|
||||
track = self.data
|
||||
conf = tidalImp.getConfig()
|
||||
|
||||
msg, stream = tidalImp.getStreamUrl(track.id, conf.audioQuality)
|
||||
if not aigpy.string.isNull(msg) or stream is None:
|
||||
self.__setStatus__(DownloadStatus.Error)
|
||||
return False
|
||||
|
||||
tidalImp.getBasePath(track)
|
||||
path = tidalImp.getTackPath(self.basePath, track, stream)
|
||||
|
||||
# # check exist
|
||||
# if conf.checkExist and tidalImp.__isNeedDownload__(path, stream.url) == False:
|
||||
# return True
|
||||
|
||||
tool = aigpy.download.DownloadTool(path + '.part', [stream.url])
|
||||
check, err = tool.start(conf.showProgress)
|
||||
|
||||
if not check:
|
||||
Printf.err("Download failed! " + aigpy.path.getFileName(path) + ' (' + str(err) + ')')
|
||||
return
|
||||
# encrypted -> decrypt and remove encrypted file
|
||||
if aigpy.string.isNull(stream.encryptionKey):
|
||||
os.replace(path + '.part', path)
|
||||
else:
|
||||
key, nonce = decrypt_security_token(stream.encryptionKey)
|
||||
decrypt_file(path + '.part', path, key, nonce)
|
||||
os.remove(path + '.part')
|
||||
|
||||
path = __convertToM4a__(path, stream.codec)
|
||||
|
||||
# contributors
|
||||
msg, contributors = API.getTrackContributors(track.id)
|
||||
msg, tidalLyrics = API.getLyrics(track.id)
|
||||
|
||||
lyrics = '' if tidalLyrics is None else tidalLyrics.subtitles
|
||||
if conf.addLyrics and lyrics == '':
|
||||
lyrics = __getLyrics__(track.title, __getArtistsString__(track.artists), conf.lyricsServerProxy)
|
||||
|
||||
if conf.lyricFile:
|
||||
if tidalLyrics is None:
|
||||
Printf.info(f'Failed to get lyrics from tidal!"{track.title}"')
|
||||
else:
|
||||
lrcPath = path.rsplit(".", 1)[0] + '.lrc'
|
||||
aigpy.fileHelper.write(lrcPath, tidalLyrics.subtitles, 'w')
|
||||
|
||||
__setMetaData__(track, album, path, contributors, lyrics)
|
||||
Printf.success(aigpy.path.getFileName(path))
|
||||
except Exception as e:
|
||||
Printf.err("Download failed! " + track.title + ' (' + str(e) + ')')
|
||||
|
||||
def __dlVideo__(self):
|
||||
pass
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
@Desc :
|
||||
"""
|
||||
import _thread
|
||||
import time
|
||||
import webbrowser
|
||||
|
||||
from PyQt5.QtCore import QTimer, pyqtSignal, QObject
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
from tidal_dl.util import API, loginByConfig, loginByWeb
|
||||
|
||||
from tidal_gui.tidalImp import tidalImp
|
||||
from tidal_gui.view.loginView import LoginView
|
||||
from tidal_gui.viewModel.viewModel import ViewModel
|
||||
|
||||
|
||||
class LoginModel(ViewModel):
|
||||
SIGNAL_LOGIN_SUCCESS = pyqtSignal()
|
||||
|
||||
@@ -26,7 +26,7 @@ class LoginModel(ViewModel):
|
||||
self.view = LoginView()
|
||||
self.view.connectConfirmButton(self.__openWeb__)
|
||||
self.SIGNAL_REFRESH_VIEW.connect(self.__refresh__)
|
||||
|
||||
|
||||
def __refresh__(self, stype: str, text: str):
|
||||
if stype == "userCode":
|
||||
self.view.setDeviceCode(text)
|
||||
@@ -37,11 +37,11 @@ class LoginModel(ViewModel):
|
||||
self.view.hideEnterView()
|
||||
self.view.setMsg(text)
|
||||
|
||||
def login(self, useConfig = True):
|
||||
def login(self, useConfig=True):
|
||||
self.SIGNAL_REFRESH_VIEW.emit('showMsg', "LOGIN...")
|
||||
|
||||
def __thread_login__(model: LoginModel, useConfig: bool):
|
||||
if useConfig and tidalImp.loginByConfig():
|
||||
if useConfig and loginByConfig():
|
||||
model.SIGNAL_LOGIN_SUCCESS.emit()
|
||||
return
|
||||
model.getDeviceCode()
|
||||
@@ -52,9 +52,9 @@ class LoginModel(ViewModel):
|
||||
self.SIGNAL_REFRESH_VIEW.emit('showMsg', "GET DEVICE-CODE...")
|
||||
|
||||
def __thread_getCode__(model: LoginModel):
|
||||
msg, check = tidalImp.getDeviceCode()
|
||||
msg, check = API.getDeviceCode()
|
||||
if check:
|
||||
model.SIGNAL_REFRESH_VIEW.emit('userCode', tidalImp.key.userCode)
|
||||
model.SIGNAL_REFRESH_VIEW.emit('userCode', API.key.userCode)
|
||||
else:
|
||||
model.SIGNAL_REFRESH_VIEW.emit('showMsg', msg)
|
||||
|
||||
@@ -62,10 +62,10 @@ class LoginModel(ViewModel):
|
||||
|
||||
def __openWeb__(self):
|
||||
self.view.enableConfirmButton(False)
|
||||
webbrowser.open('http://link.tidal.com/' + tidalImp.key.userCode, new=0, autoraise=True)
|
||||
webbrowser.open('http://link.tidal.com/' + API.key.userCode, new=0, autoraise=True)
|
||||
|
||||
def __thread_waitLogin__(model: LoginModel):
|
||||
if tidalImp.loginByWeb():
|
||||
if loginByWeb():
|
||||
model.SIGNAL_LOGIN_SUCCESS.emit()
|
||||
else:
|
||||
model.getDeviceCode()
|
||||
|
||||
@@ -37,17 +37,17 @@ class MainModel(ViewModel):
|
||||
self.view.setAboutView(self.aboutModel.view)
|
||||
|
||||
self.view.showPage()
|
||||
|
||||
|
||||
downloadImp.setTaskModel(self.taskModel)
|
||||
downloadImp.start()
|
||||
|
||||
|
||||
def uninit(self):
|
||||
self.taskModel.stopDownloadItem()
|
||||
downloadImp.stop()
|
||||
|
||||
def show(self, relogin:bool = False):
|
||||
def show(self, relogin: bool = False):
|
||||
self.view.hide()
|
||||
self.loginModel.login(bool(1-relogin))
|
||||
self.loginModel.login(bool(1 - relogin))
|
||||
self.loginModel.show()
|
||||
|
||||
def __loginSuccess__(self):
|
||||
|
||||
@@ -12,13 +12,12 @@ import _thread
|
||||
import threading
|
||||
|
||||
import aigpy.stringHelper
|
||||
import tidal_dl
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
from aigpy.modelHelper import ModelBase
|
||||
from tidal_dl import Type
|
||||
from tidal_dl.model import Album, SearchResult
|
||||
|
||||
from tidal_gui.tidalImp import tidalImp
|
||||
import tidal_dl
|
||||
from tidal_dl import Type
|
||||
from tidal_dl.util import API, getAudioQualityList, getVideoQualityList
|
||||
from tidal_gui.view.searchView import SearchView
|
||||
from tidal_gui.viewModel.viewModel import ViewModel
|
||||
|
||||
@@ -33,8 +32,8 @@ class SearchModel(ViewModel):
|
||||
|
||||
self.view = SearchView()
|
||||
self.view.setPageIndex(1, 1)
|
||||
self.view.setTrackQualityItems(tidalImp.getAudioQualityList())
|
||||
self.view.setVideoQualityItems(tidalImp.getVideoQualityList())
|
||||
self.view.setTrackQualityItems(getAudioQualityList())
|
||||
self.view.setVideoQualityItems(getVideoQualityList())
|
||||
self.view.connectButton('search', self.__search__)
|
||||
self.view.connectButton('prePage', self.__searchPre__)
|
||||
self.view.connectButton('nextPage', self.__searchNext__)
|
||||
@@ -76,7 +75,7 @@ class SearchModel(ViewModel):
|
||||
limit = 20
|
||||
offset = (index - 1) * limit
|
||||
stype = tidal_dl.Type(typeIndex)
|
||||
msg, model._resultData = tidalImp.search(searchText, stype, offset, limit)
|
||||
msg, model._resultData = API.search(searchText, stype, offset, limit)
|
||||
|
||||
if not aigpy.stringHelper.isNull(msg):
|
||||
model.SIGNAL_REFRESH_VIEW.emit('setSearchErrmsg', msg)
|
||||
|
||||
@@ -20,10 +20,10 @@ class SettingsModel(ViewModel):
|
||||
self.view.connectButton('Logout', self.__logout__)
|
||||
self.view.connectButton('Cancel', self.__cancel__)
|
||||
self.view.connectButton('OK', self.__ok__)
|
||||
|
||||
|
||||
def __logout__(self):
|
||||
self._parent.show(True)
|
||||
|
||||
|
||||
def __cancel__(self):
|
||||
pass
|
||||
|
||||
|
||||
@@ -10,17 +10,16 @@
|
||||
"""
|
||||
import _thread
|
||||
import os
|
||||
import time
|
||||
|
||||
import aigpy.stringHelper
|
||||
|
||||
from tidal_dl import Type
|
||||
from tidal_dl.model import Album, Track, Video, Playlist
|
||||
|
||||
from tidal_gui.tidalImp import tidalImp
|
||||
from tidal_dl.util import API, getArtistsNames, getBasePath, getDurationString
|
||||
from tidal_gui.view.taskItemView import TaskItemView
|
||||
from tidal_gui.viewModel.viewModel import ViewModel
|
||||
from tidal_gui.viewModel.downloadItemModel import DownloadItemModel
|
||||
from PyQt5.QtWidgets import QListWidget, QListWidgetItem, QWidget, QScrollArea, QVBoxLayout, QPushButton
|
||||
import time
|
||||
from tidal_gui.viewModel.viewModel import ViewModel
|
||||
|
||||
|
||||
class TaskItemModel(ViewModel):
|
||||
@@ -47,11 +46,11 @@ class TaskItemModel(ViewModel):
|
||||
|
||||
self.SIGNAL_REFRESH_VIEW.connect(self.__refresh__)
|
||||
|
||||
def __refresh__(self, stype: str, text: str):
|
||||
def __refresh__(self, stype: str, obj):
|
||||
if stype == "setPic":
|
||||
self.view.setPic(text)
|
||||
self.view.setPic(obj)
|
||||
elif stype == "addListItem":
|
||||
for index, item in enumerate(text):
|
||||
for index, item in enumerate(obj):
|
||||
downItem = DownloadItemModel(index + 1, item, self.path)
|
||||
self.view.addListItem(downItem.view)
|
||||
self.downloadModelList.append(downItem)
|
||||
@@ -75,24 +74,29 @@ class TaskItemModel(ViewModel):
|
||||
os.startfile(self.path)
|
||||
|
||||
def __initAlbum__(self, data: Album):
|
||||
self.path = tidalImp.getBasePath(data)
|
||||
|
||||
self.path = getBasePath(data)
|
||||
|
||||
title = data.title
|
||||
desc = f"by {tidalImp.getArtistsNames(data.artists)} " \
|
||||
f"{tidalImp.getDurationString(data.duration)} " \
|
||||
desc = f"by {getArtistsNames(data.artists)} " \
|
||||
f"{getDurationString(data.duration)} " \
|
||||
f"Track-{data.numberOfTracks} " \
|
||||
f"Video-{data.numberOfVideos}"
|
||||
self.view.setLabel(title, desc)
|
||||
|
||||
def __thread_func__(model: TaskItemModel, album: Album):
|
||||
cover = tidalImp.getCoverData(album.cover, '1280', '1280')
|
||||
cover = API.getCoverData(album.cover, '1280', '1280')
|
||||
model.SIGNAL_REFRESH_VIEW.emit('setPic', cover)
|
||||
|
||||
msg, tracks, videos = tidalImp.getItems(album.id, Type.Album)
|
||||
msg, tracks, videos = API.getItems(album.id, Type.Album)
|
||||
if not aigpy.stringHelper.isNull(msg):
|
||||
model.view.setErrmsg(msg)
|
||||
return
|
||||
|
||||
for item in tracks:
|
||||
item.album = album
|
||||
for item in videos:
|
||||
item.album = album
|
||||
|
||||
model.SIGNAL_REFRESH_VIEW.emit('addListItem', tracks + videos)
|
||||
print('__initAlbum__')
|
||||
time.sleep(1)
|
||||
|
||||
@@ -8,40 +8,36 @@
|
||||
@Contact : yaronhuang@foxmail.com
|
||||
@Desc :
|
||||
"""
|
||||
from PyQt5.QtWidgets import QPushButton, QCheckBox, QWidget
|
||||
from tidal_dl import Type
|
||||
from tidal_dl.model import Album, Artist
|
||||
|
||||
from tidal_gui.control.layout import createHBoxLayout
|
||||
from tidal_gui.view.taskView import TaskView, TaskListType
|
||||
from tidal_gui.viewModel.downloadItemModel import DownloadItemModel
|
||||
from tidal_gui.viewModel.taskItemModel import TaskItemModel
|
||||
from tidal_gui.viewModel.viewModel import ViewModel
|
||||
from tidal_gui.viewModel.downloadItemModel import DownloadItemModel
|
||||
|
||||
|
||||
class TaskModel(ViewModel):
|
||||
def __init__(self):
|
||||
super(TaskModel, self).__init__()
|
||||
self.view = TaskView()
|
||||
|
||||
|
||||
self._listMap = {}
|
||||
for item in map(lambda typeItem: typeItem.name, TaskListType):
|
||||
self._listMap[item] = []
|
||||
|
||||
|
||||
self.test()
|
||||
|
||||
|
||||
def addTaskItem(self, data):
|
||||
item = TaskItemModel(data)
|
||||
self._listMap[TaskListType.Download.name].append(item)
|
||||
self.view.addItemView(TaskListType.Download, item.view)
|
||||
|
||||
|
||||
def getWaitDownloadItem(self) -> DownloadItemModel:
|
||||
for item in self._listMap[TaskListType.Download.name]:
|
||||
for downItem in item.downloadModelList:
|
||||
if downItem.isInWait():
|
||||
return downItem
|
||||
return None
|
||||
|
||||
|
||||
def stopDownloadItem(self):
|
||||
for item in self._listMap[TaskListType.Download.name]:
|
||||
for downItem in item.downloadModelList:
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
@Desc :
|
||||
"""
|
||||
from PyQt5.QtCore import QObject
|
||||
from PyQt5.QtCore import QTimer, pyqtSignal
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
|
||||
|
||||
class ViewModel(QObject):
|
||||
SIGNAL_REFRESH_VIEW = pyqtSignal(str, object)
|
||||
|
||||
|
||||
def __init__(self):
|
||||
super(ViewModel, self).__init__()
|
||||
self.view = None
|
||||
|
||||