NFLmusic库文件

This commit is contained in:
2025-01-23 16:47:37 +08:00
parent 7516e1c95d
commit 9b3f1d1654
54 changed files with 3763 additions and 0 deletions

3
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
# 默认忽略的文件
/shelf/
/workspace.xml

10
.idea/NFLmusic.iml generated Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.6 (NFLmusic)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.6 (NFLmusic)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (NFLmusic)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/NFLmusic.iml" filepath="$PROJECT_DIR$/.idea/NFLmusic.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

1
NFLmusic.json Normal file
View File

@ -0,0 +1 @@
{"language": "\u7b80\u4f53\u4e2d\u6587", "theme": "darkly", "path": "./music", "repo": {"QQ": ["https://api.xingzhige.com/API/QQmusicVIP", {"\u6807\u51c6\u97f3\u8d28": 9, "\u6709\u635f\u97f3\u8d28": 4}, "\u6807\u51c6\u97f3\u8d28"], "KUWO": ["https://api.xingzhige.com/API/Kuwo_BD_new", {"SQ\u97f3\u8d28": 3, "HQ\u97f3\u8d28": 2, "\u6807\u51c6\u97f3\u8d28": 1}, "HQ\u97f3\u8d28"], "KUGOU": ["https://api.xingzhige.com/API/Kugou_GN_new", {"SQ\u97f3\u8d28": 3, "HQ\u97f3\u8d28": 2, "\u6807\u51c6\u97f3\u8d28": 1}, "HQ\u97f3\u8d28"], "WANGYIYUN": ["https://api.xingzhige.com/API/NetEase_CloudMusic_new", {"\u6807\u51c6": 1, "\u8f83\u9ad8": 2, "\u6781\u9ad8": 3, "\u65e0\u635f": 4, "Hi-Res": 5, "\u9ad8\u6e05\u73af\u7ed5\u58f0": 6, "\u6c89\u6d78\u73af\u7ed5\u58f0": 7, "\u8d85\u6e05\u6bcd\u5e26": 8}, "\u8f83\u9ad8"]}, "choice": "KUGOU", "auto_update": true}

1503
NFLmusic.py Normal file

File diff suppressed because it is too large Load Diff

BIN
icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

12
nflmusic/.idea/NFLmusic.iml generated Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
</module>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
nflmusic/.idea/misc.xml generated Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (NFLmusic)" project-jdk-type="Python SDK" />
</project>

8
nflmusic/.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/NFLmusic.iml" filepath="$PROJECT_DIR$/.idea/NFLmusic.iml" />
</modules>
</component>
</project>

6
nflmusic/.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

47
nflmusic/.idea/workspace.xml generated Normal file
View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="326a7e2c-ef08-4dc8-8291-8a313c81be55" name="更改" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
</component>
<component name="ProjectColorInfo"><![CDATA[{
"customColor": "",
"associatedIndex": 7
}]]></component>
<component name="ProjectId" id="2s1RHjAiMQKLYBT5bIRzer8mkeg" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.ShowReadmeOnStart": "true",
"git-widget-placeholder": "master",
"last_opened_file_path": "D:/pythonProject/NFLmusic"
}
}]]></component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-python-sdk-98f27166c754-ba05f1cad1b1-com.jetbrains.pycharm.community.sharedIndexes.bundled-PC-242.21829.153" />
</set>
</attachedChunks>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="默认任务">
<changelist id="326a7e2c-ef08-4dc8-8291-8a313c81be55" name="更改" comment="" />
<created>1737621010394</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1737621010394</updated>
</task>
<servers />
</component>
</project>

485
nflmusic/assets/images.py Normal file
View File

@ -0,0 +1,485 @@
buttons = {
"play_music": b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3"
b"\xffa\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05"
b"\x00\x00\x00\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x00TIDAT8O\xb5\xd21\x0e"
b"\x00 \x08CQ\xf4\xfew\xd64!. -\x89\xfe\x85\xa9o\xc2~\xb5\xfc\xd2\xa6\xdf,"
b"\t\xa9\x00D\x11\x06\xa0\x12Q\x00tET\x00\xa5H\x07@\x01\xe9\x02\xa1.0\xfc\x9e:@\x18#\x15H\xc7H\x01"
b"\xaec\xc4\x80r\\E_\xf8Qf\x1b\xeb\xd7\x08\x16\x16\x82\x8cL\x00\x00\x00\x00IEND\xaeB`\x82",
"pause_music": b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3'
b'\xffa\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05'
b'\x00\x00\x00\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x00\x1fIDAT8Oc\x18\x9e'
b'\xe0?\x14\xa3\x03\xac\xe2LP\x9al0j\xc0\xa8\x01\xc3\x0200\x00\x00\xc8\xa8\x04\x0f\xe3\xd8\x19\x19'
b'\x00\x00\x00\x00IEND\xaeB`\x82',
"stop_music": b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3"
b"\xffa\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05"
b"\x00\x00\x00\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x00'IDAT8Oc\x18p\xc0\x08"
b"\xa5A\xe0?\x94&\x16\x80\xf52\x81\x99\x14\x80Q\x03F\r\x00\x81\x817`\xa0\x01\x03\x03\x00\xb6K\x01"
b"\x18\xa7={\xee\x00\x00\x00\x00IEND\xaeB`\x82",
"refresh": b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa'
b'\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00'
b'\x00\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x00\\IDAT8O\xb5\x92Q\n\x00 '
b'\x08C\xad\xfb\xdf\xb9\x18H\x98\xac0\xab\xf73\xb0\xb5\x16(?h\xaa!\x8a\xaa\x05\x01\x98\xfb '
b'\xe6\xa5\xe0"kA\xe7\xab\x06\x16\xef\xc1y\xb8\r\x83\xb5;f\x84TU\x90J\xb6\x01)\xae\x03<\x91oL\x9e\xe7'
b'\r\x00^`M\xe8|\xb7\x10\xde|\xb5<\xbf\x10\xe9>\x97\x12\xfe\xb4g\xc6\xd3\x00\x00\x00\x00IEND\xaeB`\x82',
"delete": b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa'
b'\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00'
b'\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x00FIDAT8Oc\x18p\xc0\x08\xa5\xb1\x81'
b'\xffP\x1a\x06\xb0\xaaE\x16D\xd7@\x08`5\x90\x18CP\xd40Ail\x00Y!N\x83\xf1\x19@\x14\x185\x80\n\x06\xa0'
b'\x03\x92\xd3\x01zj"\xc6\x00\x10\xc0\x97\x05\xe8\n\x18\x18\x00k\xf8\t\x0c\xa2\xb5\x02\r\x00\x00\x00'
b'\x00IEND\xaeB`\x82',
"browse": b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa'
b'\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00'
b'\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x00?IDAT8Oc\x18\xfa\x80\x11J\x83\xc0'
b'\x7f(\r\x03\xc8rD\x01t\x03\xd0\xf9X\x01\xba\x0b\xd0m\xc5g\x08\x86\x0b\x89\xb2\x11\n\xe0j\x99\xa04\xd9'
b'`\xd4\x00\xfc\t\x89\x10 9\xa1\rJ\xc0\xc0\x00\x00u\xfe\x08\n\x08+\xacW\x00\x00\x00\x00IEND\xaeB`\x82',
}
icon = (b'\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x01\x00 '
b'\x00\x139\x00\x00\x16\x00\x00\x00\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01\x00\x00\x00\x01\x00\x08'
b'\x06\x00\x00\x00\\r\xa8f\x00\x00\x00\x01orNT\x01\xcf\xa2w\x9a\x00\x008\xcdIDATx\xda\xed\x9d\x05XT['
b'\xd7\xc77v\xb7\xa2^\x15;\xae\xd7\xbcvw\\\xbb\xbb\x0bQ\xb1\x0b\x15,\xecD\x14\xc5@\xb10\x11ll,'
b'\x90\x9a`f\x98\x19\x18\x18z\x18\xba{\xbe\xb5\x0e\xe0\x878('
b'\xdcW\xef\xfb^Y\xbf\xe7Y\xcf\x0c3\xe7\xecs\x0e\xb0\xfe{\xedZ\x9b1\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x88\x9fN\\b2g\x1f\x05\nv\xf5\xb1\x13{'
b'\xcf\xf7f\x1a\x8d\x86~1\x04\xf1+\xe3\xe0$f\xcf\xc0\x86.?\xce\xd232k\x7f\xe0\xfb\x0c\xb8\xfc\xc8i\xe0;\x9e'
b'\xbc-\x08\x80N\x89\xce\xfa\x9c\x10\\\xb0{O\xbf,'
b'\x82\xf8\x99\x8cYs\x92M\xd8`\xc1F\xaf1g\x137\x9c\xe6\xde\xffL&\xac?\xcdvX>`\xee^\xfe\xb5\x16\x9b^^\n"\xc0'
b'\xeb\xbd\xf0\xa0\xa6\xd3LSM\xc7\x19\xbbC\'o<\xf3\xe0\x82\xfd\xfbQ\xcd\xc6me\xea\xa88\x96\x9c\x92F\x7f$\x82'
b'\xf8Y\x8c[w\x8aM\xdet\xa6\x11\xbc\xf6\x84\xd7\xba`?\xedZ\xf7\x1d\xf9\xec\xc8\x95gl\xd5\xa1\x1b\xf5\xc1\xf1'
b'\x1d\x9a\x8e\xdd\xa2\xf9s\xe6n\xd1\x06\xb3;\x1f\x0eX?\xfdhx\xd0\xe6c\x9fE\x07}\xfa.:\x14nq\xfb\xf5q\x88\x02'
b'\xaa\'\xa5\xa4\xb2\xbb/\xdd\xe9\x0fE\x10?\x9a2\xdd\r8\x01\xf8m\xf8\x86#u\x87\xad\xd7\xc0\xeb\x9a\x81\xfaG'
b'\xd8\xf5\xa7\x9f~\xf8\xb5\x92S\xd3\xd8\xe3\x0f\x9e\xec\xb5\xab\xb4~\xbf\xc5\x87\x1c\x9a\x8f\xdf\xa6Y}\xf8'
b'\xe6U\xeb\x87\x1fk\x82\xa3\x97\x06+\x03V\xca\xd1]\xd6p\xd7\xb9\x87\xb7\xc7\xae=\x95x\xe0\xd2\x13\xfd\x91'
b'\xab\xcc\xe1\xec\xa6\xf4\xc7"\x88\x1fJ\x8d1\xec\xeacg\x96\x90\x94\xd2\xa6\xfb\xbc}|\xd6v\x81f\xd8\xf2\xe3'
b'\xaf\xc1\t\xf5\x1e\xbd\x17B\x98~\xff\x87^\x0e\xdb\xf4h\xdb\xcf\xdc\xdf\xdd|\xdc6\xcd\xfa\xe3\xb7\xaf\xc2'
b'\xcfU\xed!*\x88\x8eKd\x89\xc9\xa9\xec\xb9\xb3\x98Y\xdd\xff\x80\xc7\x95\xda}\xfe\xa1\xf5\xbc\xed\x17UNBE7'
b'\xbe<\x90\xc1+\xfd\xcd\x08\xe2?E\x11\xa4f\xaa\xc8X\xb6\xe7\xc2#\xf6\x8e\xe7\xddf\xd5\xe1\x1b\xee5\x07\xad'
b'\xd5\x94\xeen\xa0\xa9;l\x83f\xdd\xb1\xdb\xcfE\x8a`=\xa8\x999\x87MMK\xff!\xd7\xbd\xfd\xc2\x8d\x89|\x82kB\xc4'
b'!\x85\x08 \xee\xb9\xb3\xa4\x8d\xddk\x1e\x93\xf8\x85|%\x14(\nr\x7fU\x839&V<\xb0\x95\xac\xda(n\xa4\x80 '
b'\x88\xff\xb0\x16vp\x12\xe1kIh\x8f/\x1flp\xd4\xb3boCM\x9b);\xc2\xf4\xf7\\\xb1i4\xca('
b'\xa0\xda\x80\xd5\x9a\t\xebO?\xbf\xf7\xca\xa3=\x1cWL\x00\xb5\xaf\x99\xcd\x8b\xff\xf8\xdaC\x96\x1dc\x936\x9e'
b'\xa9\xd5h\xb4\x91\xb2\xcf\xc2\x83\x0ePv\xa5\xf8\xa4\x94\xaf\x05*9\x99\x05gf\xb0\xd1G\xae\xb35\x07m\x0c\x8cN'
b'\xdc}\xa3\xc9\xd4\x94v\xf3\xf4e\xfe))\xf4G$\x88\xc2r\x0fj\xda\'\x1fDl\xe1.k\xc6\x93\xfa\xd7\\\xb6\xff\xda'
b'\xf6N3M\xd3+\xf51\xd4\x80\x08\xc87\x9b\xdb\xf6\x05\x87,'
b'nt\xd2vt\xcf\xf9\xfbC*\xf4Z\xa1\x19\xbd\xda\\}\xf1\xfe\x07\x03<\x1f\x9b\n('
b'\x1e\xe9\x19\x19\x7f\xfb\x1e\x1a\x8e\xdc\xcc\x9a\x8d\xddZ\xab\xfa\x80\xd5\x01\x10i\x98u\x9b\xbb\x97\x0b'
b'\xfds\xf3 :\x9a\xb9&$\xe0\xb5J\x9b\xa9\xc3\x1aOw\x13\xf6:/\xf2\xde\xec\x1c\x13\xdb\x90]\xb7\xe1\xee\xe1\t'
b'\x1cC\x10D\x01\xc0\xf1\xf6G\xef=\xd9\xd6S\xf7\xb8v\xf5\xdd\x97\xee\x06\xe3\xd7['
b'\xb8W\xe9\xb7*\xb3\xf6\x90u\x99k\x8f\xde\xf2\x80\xb6u\xaf\x15\x07\xae3\x99R\xc5ZN0fvox\xa3!\x02\x90\x96\x07'
b'\x11h8js\xec\xf4-\xe7\xcc\x9c\x84>\xed0\x1ap\xf7Rr}\x079\\{\xe2\xcc\x99\x95\xfd{'
b'v\xc1\xfe\x1d7\x99\x07\x7f\xd6F\xa5\xde\x86\xacr\x1f\xc3Z\xe5{.\x0f\xa8\xff\xd7&s\x88<\xbe\xf8\xfeUl,'
b'\xfb\x14\x1f\xcf\xa2\xd3\xd3Km\t\x0c4\xed.\x91\xa8\xcb\xb8\xbb\xa9*{'
b'x\x84\x8e\xf3\xf6\x96\x1dS\xa9\x86NW@3\xc0\xdc\x9c\xfe\xb0\x04\xf1-\xb0\x03\xef\xe8\xd5\xe7\xec\xd8\xb5\xe7'
b'\xe8\xf8%\xe0\xb5\xfb\xc4\r\xa7\xadZM4\xe6j}\x08\xc1\xa3\x8f\\}v('
b'<&\xbeF\x85\xedgY9\x0f\x0f\xc6\\]\xd9uu8w\xbe\x8d\x83\xcbo3\xb7\x9d\xb7n2f\x8b\x06\x8f\x1f\xb7\xce"\xec\xc4'
b'\x8d\x97\xab\xe2\x13\x93+\xad:t\x83\xddz\xee\xca\xd5\xc6\x8e\x1e2\xb4\xd2\xd0\xac\xa8\xf7\xf4\xa3g\xfd7\xee'
b'\xd2r\x8e\xee2\xad\xf7T\xa2\x8b>+\xdeyI\xadR\xdd\x0c\xb4\n\x8081\x91+\xd3L\xa52n$\x10d\xc0\xfdhrL\x07l\xb8L'
b'\x16\xe0\x1c\x1f\xdf\xf3]\\\x1c\xfd\x81\t\x02Y\xb0\xf3\x12['
b'\xb8\xd3\x9a\xcd\xdav\x81\xcd\xdcz\xfe\xb3\x9d\xbf\xf7\x8e=|\'\xa8\x00\xa1\xfb\xe2\x11+OX5\x1f\xb7-\xb2r'
b'\xdf\x95\x1ax\x8d\x9a\xbb\xdd\xea"\xd4\xf2=\xb1\x1f\xe0\xb1\xdc\x1f\x1d\xbf2X]\xb0Z\xe0h\xc5\xce$\xc5q\xc3'
b'\x80\x19\x19\x99\xd5N\xde|e\xd4g\xd1AiE\x10\x81\xdf\x86oH\x9b\xbc\xe9\x8c#|6S '
b'\x0b\xa8\x8a\xce\ne\xb3a+\x8e\xf7\x18\xba\xfc\x98r\xe8\xb2c\xc1\xf0~\xcc\xa8\xd5\xe6,'
b'26\xe1\xeb\x9b\xfds1c\x1d\x16\xd5*\xd1e\xa9V\x01X\xe4\xe7\xc7\x02RRJ\xf4\xf5\xf2zU,'
b'\x97\xf3\xe7Xu\x1eO3\xcd\xc7\xc7\x80\x8b\x02\x08\x82`\xcc\xc8\xdc\x96m9y\xaf\xfc\xda#\xb7tW\x1f\xbe\x89V'
b'\x11\x8cu\x9d\xb3\x97u\x9b\xb3wl\xe3\xd1F\\\r^\x7f\xc4\xa6\xe8!\xcb\x8e]\xdck\xf5\x18\x1d\xbf\x04\xb4'
b'\xedYBr\nc..(\x00{\xc1B\xc1\x1c\xc1\xaac$\xf0\xf4\xa3(k\xd8Mo*\xbb\xf2\xd8\xb9\xfe\xa6\x13w\xcf\xf5^p '
b'\xb1j\xffU\x1a\xbd\x91\x9b2F\xae:a\x89\x02\x80\xb3\xf5\x1a\x8d2\x1a\xc1:.\xca\x04\xd3\xd4\x19\xba~A\xb9\x9e'
b'\xcb\xb9\x9a\xdc?4\xb2P\x02P\x05\xa2\x90f\x02A\x89r\xee\xee\xcf\x99\x16\x01@Q('
b'\xef\xee\xae\x0fF\x7fx\x82@\xdaO\xdb\t\xb6kY\x9b);\xfc\xff\x98\xbc\x1dm\'\x18\xab1p\r\xab>`\xcd\x84N3M\xd5'
b'\xd0\xe6\xbf\xb4\xc1\xec\x0e\xe7\xf8\xf0\xca\x9c=\x15\xccE\xe4\x9bU\x008;\xd4\xfa\xe7\xb3\x9d,'
b'@\'+\n\xe0\xbe\xf2\xf4\t\xe2\x1c\x19\x9a\x03\xf8Z\x16B\xfba\xdb-\xef\xdb\xe2\x10^\xcdAk\xef\xe2\xe8@\xb0'
b':\xba\xc5\x82\x9d\xd6\x1f\x8buZ\xa2A\x01\x98\xbc\xc9R$S\xaa\xba@\x94\xc0\x9d\xfb\xe0\xad\xa0\xc0\x020\xc9'
b'\xc7\x87\xbd\x8e\x8d-\xd1I,~\xa9\xa3E\x00*zxh\xfaK\xa5\x06\x03\xa4R\xfa\xc3\x13\x04\x0e\xe7AX\x0e*\xb0\xd0'
b'\x88u\\\xac\xe1\xac\xc3\xc2\x93 \x06\xac\x1d\x08C\x8fy\xfb+Z\xdc~\xdd\x14;\xff\x0c\x0f\xdap=\xf9_u\xd0\x81'
b'\xb3\x97ps\x9b\x02\xaf\xa7\x8a\xbb\xba\x1a\x97vs\xabP\xca\xcd\xed\x8bC\xa2 \x9c\xc7\x15{'
b'7\x9fq\xed\xfer\xf7^\xf3Z\x9f\xbb\xf7n\xf0\x07\x81O\xab\xa5{'
b'\xaf:U\xed\xb7J\x03\xb5~f\x85^+2*\xf4^\xa1\x99\xb7\xfd\xa2\xd8\xc1I\xdc\x05;\x16q.\xff\xe7\t<\xdf\x11\x00'
b'\'h\xdb\xa3h\x98\x06\x07\xef\xa9\xcf\xe7\x7f%\x00 \x0c\xa16\x11\x11\xfd\xaeFD\xd0\x1f\x9f('
b'\xda`\x08\x8f\xf3\xea\xc1a\xcaw\x98\xbe\xfb:\xd6\xbeh\x10\x92?\x8f\x88\x8e\xaf\x81\xdf\xa3\x10@\xc8\xcf\xbc'
b'\x03TL\xac\x08\xd6^\x10\x08@1\xac\xf1\xb3"\x01V<\xdb\xf2\x82mz\xbe,'
b'\x80\x05\x85E\xe15\x8b=\xf9\xe09~\xd8\xf2\xe3\xce8R\xa0;x\x9df\xe2\x86\xd3\x16\xb3\x8d/\xec\x83\xe6@:N('
b'\x1alpT\xbc\xd9\xfcnw<\x16G"\xb8%\xbe\xdf\x11\x00\xcb\xb00\xf6 '
b'*\x8ay\xc4\xc7\x97\xdd\x13\x12rt\xb0L\x16\x03\xed\xfe\xd4\x8a\xee\xeeI=%\x12\xe5r\xa5rLe\x08\xff\xef\xd10 '
b'QT\x89\x87\x9a\x189r\xf5\x19\x93*U\x15V\x1e\xb2\xb1h0bS&\xd4\xfcX\xfbkpF\xdf\xcc\xad\xe7oY\xd9\xbf\xaf\x81'
b'\x1dy\xe8x\xf9:\x7f\x01\xe1I\xfd\xb9r\x86.;\xc62\xa1)\xb0\xfb\xdc\xc3\r\x03\x96\x1cN)\xd1E_\xd3j\x82\xb1f'
b'\x9b\x85\xdd\x99\xf0\xe8\xb8\xf2\xd8\xa9x\xfc\xfa\x8b=\xd0\xecH\xc4\xefZO\xda\xae\xda~\xe6\xfe\x1e/\xbf'
b'\xd0J\x10\xa5\xb0:C\xd7\x7fS\x00\x90['
b'\x91\x91\xcc;9\x99\x8b4>\xc6\xc7w]\xe5\xef\xff\xba\xb1@\xb0\xe3attKfo\xcf|\xe1\xbbc*\x15\xfd#\x10E\x0flO'
b'\xa3#\xea\x0eY\xcbl\x9e~\xaa2n\xdd)\x0b\xac}\xd1\xf1\xf5Fn\xceh<\xda('
b'\r\x1cL\x833\xfbz/<`\xfb\xdcY\xdc\x1b\xcf\xc3\xa9\xbc\x7f\'\xc9\xc6\x95GN,'
b'$<\x86\xf9\x05g\x85\xdc\xd0\x84h\x0b!\xbfC\xed\xa1\xeb\x93\xb1\xcd\xff\xc7\xe4\xed\x01g\xee:\xee\x82\xb2'
b'+\xbe\xe3\xc9Q\x90\xb8\xb9\x06;\xcf>\x18\xd8{'
b'\xe1A\x01N&\xaa1pM\xfalc\xab\xf7\xe7l\xdf\xf5\xe2\n\xa9=\xbez~\x02\x10\x91\x96\x96u\x9fw\xee0\xdb\xa8\xa8'
b'\xf93\x15\n\x97\x86\x02Ade\x0f\x0f\xdf\x19\n\xc5C+\xb5\xfa\x8f; '
b'\x10\xea4Z\x1eL\x141\xd0\x8935\x99\xdcR\xda\xf7<\xefA3\xb6\x9e\xfb\x04\xe1w\x06:|\xbb\xa9;\x93\xc1\xe9\xb6l'
b'=u\xcf\xa0\xe3\x8c\xdd\xb1\x10js\xf3\xfaG\xac<\x11~\xc2\xe6\xe5d\x0c\xc3\xdf\xb8\xcb\x98\xc47\xa4\xc0B\x83'
b'\xe6*Q\xb2=\x17\x1e\xb3@UT\xb3=\x17\x1e\x99v\x9d\xb3\xd7\x0f\xcb\xad\xd4g\xa5f\xfa\x96s\x8a\xd3\xb7\xdf\x0c'
b'\x18\xbd\xe6$\x13\x04\xa8>\x0bLlJ*\xdbw\xf1\t{\xed&\xed\xb8`\xe7%\xdb\xba\xc36\xa4\xe29 '
b'\x16!F\'m\x8f\x1d\xbd\xfal0\x08\x80?\n@\xe5\xbe+\x99\xe5]\xc7\xcf\xd7\xe5\x1c\xdb\xd2\x92\xdd\x8c\x8c\x9c'
b'\xd7C"\x89-\xee\xe6\xf6\xb9\xfd_\x06\xdeO\xf2\xf1qU$\'\xb7\x12&&\xd2?\x04Q4\xc0\xf0\xdd\xfc\xe6\xab\x9cTY'
b'\x95\xce\xda\xbe\x9d;P\xff\x88_\x99\x1e\xcb4:P\x0b\xf7_r8\xc1\xfa\xe1\xc7\xcd\xe8\xe4\x8c5\xc7\t:\x8b\xc6'
b'\xaf\xb7\x88*\xd5\xcd\x80\xeb\x14\xfc}\xa2I\xf4\xb1k\xcf/\xaa"cke\xf7\x19\xb0\xb3\xb6\x8eZ\xafe~\xe3\x15'
b'\x84\xfb\x01, 4\x92M5:\x8b\x8e_n\xcd\x91\x9bcF\xad2w\x83\xf0]\x03\x8e\xab\xe92{O\xda\x86\xe3\xb7O{'
b'\xfa\x045g]\xf4\x19\xfb\xe8\xa4\x03\x0eZ\x12\xad\x18\xd8Z\x7f\xff\x12\x1a\x7f539c\xcfE\x03\x87/;\xac\xef>w'
b'\x9f\x0c;\x07\xab\xf5_\xad\xe9\xb7\xf8\x90\xaab\x1f\xc3\xb4F\xa3\x8cN\xe25?\n}\xd8\x12\xd3\xcb,'
b'#3\x93m\x0b\xe2F\x1dJ\x8c\xf3\xf6~Q"\x97\xf3\xe7X\x03\x81@\xb3+8X\x1f\x8c\xfe1\x88_\x1f\\?\x8f\xb5\xfe\x12'
b'\xd3+\xec\xc1;Ae\xa8\xe1\xcf\xfd9\xd3\x94\xeb\xec+\x0b\x02\xd0c\xde>\xe7S\xb7^\x0f\xc0\xb67v\xd2\xa5\xa4r!t'
b'\xb1\xe7\xce\x92nS6[>\xad=$\xaby\x80+\xfc\xa0\xa6\xb6\xbb\xfd\xdc\xad;\x96\xfb\xd6C\xce\xdc\xa0v\xcf\x01'
b';\xe9\xb0\xa7\xde\xf8\xb4=\xf7\xb3"P\xddr\xf5\xe1\x9b\xd3@h\x9e\xc0\xb9\xc9(4 '
b'\x00)\x137\x9c~v\xf3\x99\xebxl\x9f\xbb{\xf9\xb3\xe28\x1e\xef\xea\xda\x19\xec\x15\xd8\x1b\x10\x80\xb7 '
b'\x00gp\x1e\xbf\x08\xee\xdb\xf6\x95;\x8eD`\xf9\xed7\x9d\xb8k\xd7f\xca\x8e\x84R\xdd\x96j0B\xf9}\x92I\xf0'
b'\xfeKO\xcc 2\xe1\xa6\x18\xb3\xd6s\xd8\xfd\xb7|\xd6B ('
b'Q6\x9fy\x00%A\x14j\xf3x\xfa`\xf4\xcfA\xfc\xda`M\xfd\xcc\x99\xeb=\xafde\xff~\xd6`\x83\xa3\xef!d\xced\xed\x16'
b'\xa03j\x0c\xf6]u\xb2}\xe5\xd1\xd2\xe2\xf6k\xeeX\\K\x9f\xd3\xd6\x7f\xf2Q\x84m\xf7\xfa\xfb.>\xb6n9\xc18\x06'
b'\xdb\xeb\xa5\xba.\xd5@M\x1c>\x7f\xc7\xc5e\xd0\x14\xa8\xf5\x97\xa1\x19\x0b\x8b\x8c\x05\x8bc\x0f\xdf\tQ\x14'
b'\xcao6\xb7\xed\x0f\xa1\xbd\xe9 \x83\xa3~u\xb3k\xfc\xdf\x86o\xc0i\xc0^\xcb\x0f\\\x1f\x1f\x15\x97X\x1e\x9a'
b'\x1a\xdc5P\x9cX\xd6\xe8\xc1\xd0\xdc\x13u@\x00\xdcQ '
b'\\\xe3\xe3\xb3\x9f\xa4\x1e\xdbfa\xc7-\xee\xb9x\xff\xc3\xd0I\x1b\xcf\xdc+\xd9ui"\x8aJ\xb5\xfe\xab0\x05X\x10'
b'<\xcb\xe3]\xe7\x1e\xcc\xbe`\xff\xae\xb2\x9dFS\xbc\xadH\xa4u\x1e@)\x10\x00=\x81`)\x18\xfd\x83\x10\xbf\x1e'
b'\xd8\xc3\x8f\xce\x8554r\xef\xb5G[\xfd=W/C\x1b\x9f\x0b\xf7\x8bu^\xa2\xe94\xcb4q\xd5\xe1\x1b&Q\xb1\t\r\xce'
b'\xd9\xbee\xe8\xc8yq\x12\xfaBm\xcau\x18\xea@\xf3`\x16\x1c#\xa8\xd2o\x95\x86\xb5_\x88\x9dr\x9a\x91\x10\xd2C'
b'\xb8\xbf4=#\xa3\xd6\x94M\x96l\xe7\xb9\x07\x0c\x04\xa6y\xf3q\xdb\xd4e\xba/\xd3\x94\x86\xe6\x83\xde\xc8\xcd'
b'\xc9\xc3\r\xcd>\\\xb0{\xb7?4"\xa6%\x08\x03{\xcb\xf3\xe6\xa2\x85\xcf\xe0,'
b'B\x17\x97!`\xe9\xf9\x0b\x00\xe3f\x04\xa6\xa5g\xb0\xc9p-\xbd\x11\x9btA\x90|\x9b\x8f\xdf\xa6\xea:gol\xf9\x9e'
b'\xcb5 \x08\x1a\xdd!\xeb\x92 B\x80\x08\xa5\x023\x0f\x0b;_\x17\xe7\x01\xb8\xb8\xfc\xbf\x00\xc0\xfb\xa6Ba\xd2'
b'\xce\xe0\xe0\xb1;\xa9\t@\xfcJ\xf8\x05\x87s\x8e\x8f\x13m\x10\x81<\xb0\x9d\xc9i\xfb\x13\xdd\xe7\xed\x0b)\x07'
b'\x0e\x82a\xfco\x10\xc6C\x08\xfe\xfe\xfc\xbdwCp\xd9\xae\xdc_\xc56\x8ae\xac\x0c\x84\xe1:\xd9\xe3\xf89c\xf9'
b'\xa5\xdd\xdcX\x05\x97\xac\xc5:\x95\xfb\x18b\n\xaez;,'
b'\xef_n;uGt\xf1\xce\xfa\\\x08\x8eS\x84\xe7\x98X\xb9A\xad\xbc\x14\x8e\xab\xd1m\xce\xde&m\xa7\xee\x0c\x00\'t'
b'\xdahv\xe7\x81\x99\xcd\x8b\xf1p_\x15\xf0~\x02U\x91_\xce\xe8\xcb\xa6\x9bD\x826\xa4\xa7\x97W\x86.\x9f\xef'
b'\x89S\x89s\x9a\x00\xb9\x05\xe03\x9f\xe7\x01\xe8\xfb\xb7\x18ol\xf9\xc6M\xdas\xc6\xd6s\x9b\x87.;&\x85k\xa74'
b'\x1am\xd4c\xd8\x06\x0b\xa6LI\xd1\xdd\x1c\x18x\x0f"\x01\xae\xd6G\xfbC$J\x98\xaaP\xacL\xcd\xc8('
b'N\x13\x81\x88_\x02Ls%R\x04\xb3\xde\x0b\x0fr\xce\nm\xf7v\x10b\x9f\x18\xba\xfcX('
b'v\x98a\x8d\x8d5$\x84\xc92\x08\xa3\xb7\x86\x86\xc7\xe8\xddx\xc6M\xcb\xe5\x86\xe7\xd0\xd1A\x00\xea\x83\xd3'
b'\xf7\x04\xe7\xeb\x81\x86\xef\xe1\xf3&('
b'\x06\xe1\xd1\xf1\xec\xde+\x1e;v\xed\x05\x9eS\xfc\xf8\xf5\x17\xbd\xc7\xac9y\x1fW\xf8a?\x026\r\x9a\x8d\xdd'
b'\x8a=\xfa\xae\xe0\xf0\x1bA(\xa6\xa6\xa6\xa7\x97\xc5\xc8a\xb1\xa95\xf3\tR3G\x88Fp\xea\xb0\xd6\x0e\xca\xc4D'
b'&JL\xd4\xf5KN\x1e\xe7\x9e\x90P\x9f98\x94\xe0:\x01\xe1\xfe\xbe-\x008\x0c\xb8\xd1|\xb1\xe9e\xc6\xca\x0fe'
b'\x10a4z\xf8N0\xf6\xd0e\x87\xea\x87.=a\xd2\xa4$\xbc\xdfZ\x97\xc3\xc3G\xcf\xf3\xf5u\xaa\xcf\xe7\x1f\xb3\x08'
b'\x0b\xeb\x8d\xcfpN\xadf\xeb\x03\x02\xe8\x9f\x87\xf87\xd3\x18\xac\x0e\xab;l=:iU\xa8\xf9\xe7\xae>|\xf3\x16'
b'\xb4\xd1\x83sBu\x0c\xc3;L\xdf\x9d\xb0\xf9\xc4];\xa8\xf5\x9b\xb3b\xfd\x99/D\n\x81aQ\x9f3\xe4\xe2\x0c\xbe'
b'\xe2nn\xdb\xc0\xd9q\xe9lr\xb6e\xc0\xe7\x16,'
b'{6_N\xb3"gN?\xb4\xddk\x1d\xbf\xfe|\xd5\xf0\x15f\xc2Z\x83\xd7jp\x18\x11\x9b\x17\xe0\x90\x99}\x16\x1et:x\xf9'
b'\xe9i\xbb7\xbc\x1e\xe8l\xac\xd14(\xa1}\xbeO\xa1LN\xe6,'
b'<-\x8d\xc5\xa5g\xf5?\x80\x00\xb0\x82\t@\xd6<\x00<6&>\x89\xbdr\xf5b\xe67^2KgOf\x1f\xc5\xcd6,{&,'
b'l\xa4\xa1\xbf\xbfr\x98Lvg_HH+,\xe2Qt4.\x17\xa6\x7f!\xe2\xdf\xcb\xfac\xb7\x99\xe9\xf9G\xe5gn=\xbf\xb7\xdb'
b'\xdc\xbd\xefZN0N\xc7\xb67:#\x86\xfc\xed\xa6\xedL\xd0\xdfs\xc5\x1e\x84\xe1/\xcc\x94\x8bK}{'
b'\xce\xdb\xcf>\xf0}\xbe,(+\xec\xdf\xa1\xa5\xc7\xfc,'
b'\xd32\x9d\x17\xe7\xf4\xab\xa3\xe3X\x8b\xf1\xdb\x98\x8b\xd8\xaf\xce\xba\xa3\xb7V\xf5_rXX{'
b'\xc8zM\xceTb\\\xed\xd7~\xfa\xaeHh\x12\xd8\x1a\xec\xbb:y\x96\xf1\x85\x1f\xf7\xe0\xdf\x99\n<M\xa1`\x17\xa0'
b'\x86\x7f\x1a\x13Sa\x91\x9f\xdf\xe9\xe6Ba*\x86\xff\xa5\xb3\x9a\x00\xa1\x0b\xfc\xfc\xa6\xb0\xd3\xa7\xd9}\x9a'
b'\nL\xfc\x9b)\xd3c\x19\x03G\xafZ\xaa\x9b\x81\x0c\xdb\xe3h8d\xd7i\xa6\xa9\xeffs['
b'\xbb\xbb\xaf\xdc9\xc7?o\xf7\x8eK\x99\x85\xb5d\xce\x14`-\x02\xb0\xbd\xa0\x02\x80`BP\xd6z>&\x03e\x10e0GwY\x9d'
b'\x1d\x96\xf7WM\xdd|V\xd8z\xf2vM\xd9\x1eY}\x0e\xd8\xe1X\xba\xbb\xc1A\xb8\xc7\x7fL\x00^\xc4\xc6r\x1d\x97\xdb'
b'\x82\x82\x0e\xd5\xe2\xf1\xbe\x1a\x05\xe8*\x91\x84?\x8e\x8e\x1e\x84\xeb\x05\x08\xe2\xdf\xdb\x00\x18\xb3\x85'
b'\xe9\x8d\xdc\\\x15jb\xc9\x9f3M\x03&\xac?}g\xed\xd1['
b'\x0b!\xf4n\x82\x1dh\xb8bO\xe8\x9d\xb5\x147X\xfd\x8d\xda.K\x00vj\x11\x80\xf3\xf9\t@\x0e8\xee\x8f\x93\x8c\xa0'
b'\xdd\x0fQ\xfe"\x14\x9a\xba\xb6\xaf<\xe6\xac?~\xfb\xf2\xa8\xd5\xe6\x92\xa6c\xb7\xc64\x1b\xbb\xf5 '
b'F\x0b\xff\x94\x00\x0c\x96\xc9\x18\xb4\xf1K\xfc\xee\xe9\xa9u\x18\xb0\x92\x87\x87\x06\x8e1\x18"\x93\xd1?\x11'
b'\xf1\xef\x05{\xfb\xad\xec\xdf\x97~\xee,\x99\xf2\xf0\x9d\x80s\xfa5Go1\x9b\xa7.L\xe6\xaf*\xf8\xbc\xfd,'
b'\x010\x04S\x80\xc9\xb2MQ\xc2\xcdm\xf7\xf7\x04 \x87\xd0\x88\x18\x16\x9f\x94\xcc\xad\xfd\xcf\x1e:,'
b'\xf5\xdaMZ\xf9\xc9\x07\xcf~\xf0s\xaf\xe7\x9f$\xff\x98\x00`\xa7fU\x0f\x8f\x12p\xffZ\'\x02\xa1('
b'\xc01\xfa\xa5\xf3,W&\x88\x7f\x15\xd7\x9e|b\xe7\xee\xbde\xe0d\xec\xf2C\'\x86\x9bp\x8cY{'
b'\xb2\xf0\x05e\t@9\xb0\x1a\xd9\x99|\xaa\x83\x93\xd4('
b'\xeb\xee^\xa1\xa0\x02\x90\x1b\x1cZ\x8c\x88I\xe0V\x1ab\x16\xe1\x9cL\xc2\xff\x94\x00\x8c\x94\xcb\xd9\xed\x88'
b'\x88\x12\xedD\xa2W\xda"\x80*\x10\x01\x8c\x92\xcb\x97\x8e\x96\xcb\xe9\x9f\x88 '
b'X\xae\xf1\xff\xbc\xf3\x00\xfe\x8e\x00\xfclt:-A\x11\xd0-\xd9uiH\x83\x11\x9b,'
b'*\xf6\xf9R\x00^\xc7\xc6r\xaf\xdb\x83\x826\xd6\x17\x08R\xf3\xa6\x03\xeb\xe5\xe5\xa5\xb0\x8b\x8a\xear;2\x92'
b'\xfe\xf6\x04\xf1o\xa3L\xf7e\xactw\x83\xf2e{,[\xd5d\xcc\x96\xe1U\xfa\xae\xfc\xe2{'
b'\x1c\xfe\xc3}\x01DII%V\xf9\xfbo\xeb"\x91\x04\x95ts\x0b\x84\x9a?x\x9c\xb7\xb7\xc048\xb8\xef\xd6\xa0 '
b'&HJ\xa2_&A\xfc/\xf2\x10\x1c\xf8c\\\x1c{'
b'\x11\x13\xc3\x9e\xe7\xb1\xd7\t\xf1\xec\xd8\x1bw\xd6t\xfc6L$\xca*\xe7\x11\x00\xe4tX\x18\xb7?\x00.p\xda\x17'
b'\x12R\xaf\xa2\xbb{\xfd\xd6\x9e\x9e\xf5\xdf\xc4\xc5\xd5\xc2\x84 '
b'\xd8?\x92\x99\x99\xc9x\t\t\x0cs\x03\xdc\xfe\xc9\x06\x11\x07\xf3LLd\xcf\xe0\xfe\t\x82\xf8\x0ea\xa9\xa9,'
b'2-\xadbxjjM\xb0\x1ay-"-\xadfBzz\xf9\x98o$\xf5\xc0\x19\x868\x1bp]@\x00\xc3\x0c\xc0\xcd\x84Bf\x1d\x1e\xfeyBS'
b'\xb6U\xf3JJ\xaa\xf1\xb3M\x96\x94TS\x9d\x96V\x013\x11\x11D\x91\xe3\xa4J\xc5N\x81-\xf5\xf3c3\x15\n6\xeb;6\xd5'
b'\xc7\x87\x19\x05\x06\xee\x9b\xe3\xeb\xeb\x0b\xc7\xcbg\xe52\xfcy\x89\x9f\x9f\xdf\x8d\x88\x88\r\x10\xe2\x7f'
b'\xb7\xac\x19`\x9b\x03\x03\x99[|<\xc3$ '
b'\xea\xec\x8cA\'T\xaa\xc9\xcb\x95J\xd1$\x1f\x1fo0\xf9\xcf\xb2\x89`\xf0\x1c~\xd7""L\xd6\xd0\xf4\xe3_\x0f\xdc'
b'\xf0\x12\x13`\xe0\xf0\x1b\xa6\xbf*\x88]\x7f\xf2\x89\xdb\xa5\xb6x\xa7E\x98\xf5\x86\xbdr\x95\xb2\xdb\xcf\xdd'
b'\xd8e-\xc7^~\xf8\x91\xd9\xbf\xe1\xb1\x88\x98xn\xce?\xae\xc1\xc7\x0c8G\xafe\xed\xd8\xf3#\xec\xea\xd3O,'
b'!#\x83I\xa0\xc6\xc4\x1ds\xb4\xd9{0Y\xd6\xfc\xfa\xbf%\x00`\x7f\x80\x00,'
b'\x03\x076\x98\xf5\x1d\x9b\xeb\xeb\xab\xff\x87\xa7\xa7\xb3\xb6^|\xb4r\xee\xee\x9a)>>/\xe6('
b'\x14K\xbeW\x16\x08\x80\x01\x08\x80\x01\x08@S\x14\x00p|v9<\xbc\xf1\x00\xa9\xd4?\xbf\xf2\x7f\xb4\xe1\xdc\x03'
b'\xb8\x87\x93\xd0\x0c!\x87\xf9\xd5\x08\x08\x8d\xc0t\xd7eT\x111\x15B\xc2\xa3\x0bdxljZz\x19\xb3\xabO\xb9YzQq'
b'\x89\xc5\xc3"c\xf3=^\x1d\x15W!-=\xbd\x14&\xec\x80\x9fK\xf1\xa4\xfe\x15\\D\xbe?\xcaJI}C\xb8\xd9s\x98\x1d\x18'
b'\xac\xc27\xaclpz\xe1\xb7\xf9\xc6\xddz\x16\xfb\xf9\xad\x800\x9c\xdb\x99\xa7F\x01\xac,'
b'8y~\x0e\x85\x8e\x0b\xed\xfa\x02\x95S\x15\x9c\xaf\xb7\x97\x97\xe6Qt\xf4T\xec\x17\xe8\'\x95\xb2!2\xd9\xef\xb5'
b'\xf9\xfc\xe8\xfc\xca/\xee\xea\x9a\n\x16\xf7#\xac\x18X5\x0f\x8f\xe4-\x81\x81\x87\xda\x89D\xe40\xbf\x1a\xdd'
b'\xe7\xedc7\x1c\\v\xcc\xdbqQ8\xcd\xe8\xacGAl\x96\xf1\x05\xe1\xd1\xab\xcf\x0f0V\x93\x1d\xbc\xfc\x94\x1d\xb0'
b'~\xd2}\xc9\x9e+nS\xb5\x1c;u\xb3\xa5\xc7\x9a#7\x85>\x81asp\xa7\x1d\xdbW\x1eK\xe6\x98X\tG\xad6\xf7\x18\xbd'
b'\xe6\xe4\x7fjB\xb0\xf9\xcb\x8e\xdebA))\xd5-\xd5\xea\x87\x06J%\x7f\x99R\xe9\x91\xd7\x0c\xfd\xfd\x85\xd0\x86'
b'>\x81BQ\xd8\xdf\xd1t\x08\xe9g\xf8\xf8\x18\xd6\x04\x87\xc4\xa18\xcc\xd3W\x10+\xf1\r+h\x19\xe8\xd0\xe0x\x1a'
b'\xbb\xa8\xa8i\xd8\t\x87\xcb\x8fA\x10Z\xd5\xe2\xf1\xa2X>\tCZ\x8bD7\xca\xb8\xb9\xb5)\xeb\xe6\xd6\xbeL\x01'
b'\xadl>\x86\xdf\xe9\xf2x\x1d\xb6\x05\x05\xd5\xfbS,'
b'&\x87\xf9\xe5\xa80\x9c\x19\x9d\xb4\xbd\x84Ytq>\xbeN\xa7\xef\x18\x1c\x83\xe9\xae\xdbN\xddy\x17\x9di\xdc'
b'\xbaSl\xc4J\xb3\xa1\xdc\xaa\xba\x8e_\x1f\x8f\x8bkZ\x8c\xdf\xa6\xf9\xe4\xe9\xbb\xf1\xcc\x9d7\xec\xf0\x95g'
b'\xdb\xb3\x16\xded\x95\xf5\x03\xcc\xa8\xc5lS&HH\xa8=\xde\xdb\xdb?\xa7\x86\xcdk\xe8\x18\xd0\x96}\x92\x957'
b'\xb0pl\x8268\x84\xc0C\xa0\xf6\xb5i/\x12]\x03\xb3\xee '
b'\x16_\xea\xa8\xc5:\x88D\x97\xe0\xfb+\xf0\xfeZ\x87\xef\xdb\x95|\xcb\x01\x03\xc7\xb7\x06\xbb\x06m\xf1\xeb'
b'\xafcc\xbb;\xc5\xc7\x7fW\x00p\xd1P///s\x880X\x19\x9c\x0b\xe1\xccmi^|Opp\t\xd3\xa0\xa0/l7\xd8^\xf8\x9c-['
b'\xc6u4\xe2\xf1y\r\xe7S\xc0\xb5\xb8\\\x85$\x00\xbf\xae\x00Xa\xc2\xca\x9cE9\xdf\xb5\x0e\x0b1\xe5v\x88_px['
b'\xdct\xe3\xaf\x95fCj\x0eZ\x9b\xce\xad\xa6\xfb\xea\xd8E\xb8\x19\'\n\xc0\xfa\xd3Y\x02`\xc2\xe5\xe9\xd3v,'
b'\'@K4e\xba\x1bp\xf9\xfe\nh[\xda\xcc\xdf\x87\x02\xa0\x0b\x02\xe0\x9b_X\\2K\x00\x1e\xfe\x1d\x01\xa8\xed\xe1'
b'\xc1\xea`\x0e\xbe7o\xb8|\x83\xf3|}\x07\x81cN\x00\x1b\x9f\xdb\xda\x82\x8d\x90\xc9&\\\x8b\x88\xa8\xdb\x06\xc3'
b'\xe5\'O\x18{\xfa\xf4ksp`\xec\xd5+\xb6T\xa9l\xd6U"\xf9\xaa\x1c\xb4\x8e"\xd1Ds\x95\xaa\x0fw\x03\xef\xdf3\xb3'
b'\xd0Pf\xa5V\x17H\x00zzy\x9d\x84\xa6\x03\xfeN\xb8i\xcd\xa6\xc1\xc1g\x1b\x08\x04\x9f\xea\xf1\xf9\x1f\xf3\x9a'
b'\x9e@\xe0\xdc\xd2\xd3sDKj\xdf\x93\x00\x14F\x00\xdaM\xdb\x99jq\xebu\xaf\x95\x87l~\x9c\x00\xc0\xb1\x8dG\x1be'
b'\x98^x\xf4\xce\xfc\xc6K\xdb\x136/\xef}\xc7\x1e\x80M\xb4|\xe1\xfaS\x05 '
b'\x87\x9b\x91\x91\x9cCA9\xb7\xb0m\x0e\xb5\xa6\xa6B.\xc3\x9fu\xf9|\xcdL\x85b\x0b{'
b'\xf4\x88\xf5\xcb\xa7\xcd\x8c\xe5\xf8&\'W\x1e\xeb\xed\xfd\xa6b\xf6y\xb9\xcb\xc1N\xc2F\x02\x81\xe6\x82Z\x8d'
b'\x9b\x8f\xea\x84\xa6\xa6~>\xb70\x02\x80\xf9\x08pE\xe5\x86\x80\x80O\xd8\x9c\xc8\x1b\x15\xe1\xf1\xd8\x1c\xa9'
b'\xec\xe11\xbf2n\x8dN\x90\x00\x14\xc8\xc0y\xab\x0fX\x9d\xd2o\xc9\xa1\xde\x03\xf5\x8f\xfc@\x01X\x88M\x8bT\xeb'
b'\x07N}\x19k\x9aw\xcc;_{\x9a\x9c\xf0\xd3\x04 '
b'6=\x9d\xa5ff\xe2\x96\xdd\xdcd\x98\x1b\x11\x11\xcc\xd0\xdf\xbfo\x9dot\xc2A\xad.{'
b'\x10\x1d\xad\xe7\x02\x0e\x88\xe7\xe46\x11\xd8\x95\xf0p\x06\xb5\xfb\x8cFy\xa6\xfa\xe6\xb6ARi('
b'\x1c\xdf^\x98\xe7\xfc\xbf)\x00\x1f\x8bkI1\xce\xb2\xfb3*yx\xcc%\x01 \x01('
b'\xb8\x00\x80a\xf2\x0e\xe3\xd3\xf6G1\x9d\xd5\x8f\x14\x806Sv\xa4\x9e\xbc\xf9\xaa\x0f\xe6\xe7/(8['
b'\xedg\t@L\x96\x00\x94T\xa6\xa4\xf4\xe0%$\x0c\x06\x1b\x04\xd7\x1a1\xd9\xc7G\x92\xdf0\x1c\x8e\x14\x18\x05\x06'
b'\xee\xf7JJ\xea\x9f}Nn\x1b$IJ\x1a5\xdf\xd7\xd7\xa5D>N\x89;\x00\x1fW\xa9\\|\x92\x93\x87\xe6:O\x17g\xfe\x91'
b'\x00\x10\xff\x13\x02\x80\x9bn\xcc\xddne\xc7t\xfa\xfd\xd2\x02\x80\x8bs\x82RR\xaa\x99\x04\x05\x89{'
b'yy\xe1\x90\\z\x1f\xb0V\x9e\x9e\x99\xdf\x1a;o*\x14f\xe0q\xbd\xb5Xv\x02\xd1|\xcf-\x03M\x80\xcebqf\xaes2'
b'\xfazyM\x06#\x01 \xfe7\x04\x00\xb3\xe54\x1b\xbb\xf5n\x9da\xeb\x7fi\x01\xc0\xf6\xba<)\xa9\x1a\x94-e\x9f>e'
b'\xa5\xe9\xfe\xef\xd8\x14LA^\xc0Q\x80\x93\xec\xf5k\xc6,,'
b'\xb8\xbd\x086\x05\x04|\xf8\x96\x00\x80X\xcceo\xdf2fj\x9a\xbf\x1d9\xc2\x86b\x12\x92C\x87\xc8g\x8a\x94\x00t'
b'\\\xac\xa9\xdcw%\x97\xa03\xafc\xb7\x9f\xbeK\xe9\x1b\x14\xde|\xb0\xc1\xd1\x81?\xb2\x0f\xc0\xe2\xd6\x9b^\xfb'
b'\xac\x1e\xb3M\'\xee\xe6k\x1b\xc1\xce\xda\xbe\xe5\xb6\xeb\xfe\x99\x02\x80\x0bx\xa0\xfd_mc`\xa0\xac\x83X\xac'
b'\xf9oXG\xb0Nb\xf1T\x88\nXW\x10\x00p\xf0V5\xf3\x11\x00t\xe8v"\x91\xf7Xoo\x9b\xd1\xde\xde7&x{\xdf\x1e '
b'\x95\x86\xeb|cRR\x1b\x91\xe8\xd3\xb8\xac\xe3oj5\xb9\xfc\xe6L\x85\xe2\x8eK|\xfcb\xccYH\x14%\x01\x00\x07\xfec'
b'\xf2\x0en\xcb\xed/\x9c\x16\x9c\xb5\xf5\xe4\xed\xe9\xc7\xae=\xef9d\xd9\xd1\x01?j\x14\xa0\xd5D\x93\xb4]\xe7'
b'\x1e.\xdafa\xd7\xce\xf8\xb4\xfd\x9f\xf9\x9a\x85\xdd\x9fV\xf7\xdf\xff!\xf4\x0e,'
b'qO\xa5\xfei\x02\x10\x95\x9e\xceR23KC{'
b'|\x148\xc0L\x8f\x84\x84\xa9\x82\x7f\xd0\xdc\xe2\xe3\xa7\xc1ug@8\xaf\x87!\xfd\x14\x1f\x1f6\xd7\xd7\xb7Uc'
b'\xa10\xe6\x8bMC\xf2\xe4\r\xc0\xe7\xcd\xb1\xefM\x19.\x9e\xebXm\x86}\x15\xb5\xa1\xc9\xf20:\xfa\\u\xda\x92\xac'
b'\xa8\t\xc0BM\xaf\x05\x07\xb0\xb6\xff\xd2i\xe1}\xb5\xfe\xab\xd2\x97\xee\xb9:n\xf4\x1a\xf3\x81?j\x1e\x00f'
b'\x04n1~[\xd2\xef\x93L\xe2\xbfe \x14I\xf3\xb6_\xf4|\xf4^P\xf3\n_\xf6\xd3\x04\x00S}\xa7ef\xb2\xc0\x94\x14\xe6'
b'\x18\x1b\xcbL\x83\x83G\x8c\x95\xcb\xcfAml\xd9\xe5\'\x1a\xd4\xf4\x96K\xfc\xfc,'
b'\x9fDG\xf7}\x0b\xd7\xc5\xd5\x81h\xb8T\xf8iLLE\xa8\xd5/\xe9\xf2x\xdc\x94\xe2\xefY\xa9|\xc2\xff\xdc}\x0e\xd8'
b'\xf1\x98\xdf\xf984\xd9P \xd0<\x8e\x8e>\xfb\x1b\x9fO>S\xd4\x04`\xd0\xd2\xa3\xb8#\x0f\xe7\xcc_\x8c\x04\xf4X'
b'\xa69|\xc5\xe1\xc64\xa3\xb3C\x7f\x94\x00p\x9f\xb7_\xa0\xc1\xfd\xff\xbeim\x17h\xfa,'
b':\xa8\xb8\xf6\xc4\xb9\x96\xe5G\xe1O\x9f\x07\x80CwW\xc3\xc3\xfb\x83\xe3\xabKg\xef\xd4\x93\xd7J\xfeM+\x95\x8f'
b'\xa1S\xfe%\x93}\x84\xa8\xa3\xaag\xf6v\xe0\x96j5\xb7\'\xc0\xe1\xd0\xd0\xea\x0b|}\xe7\xf4\x94H\x16A\x93`A\xef'
b'<\x86\x9f\xe1w\xc3d\xb2ec\xe4r\x9f\xfc\xa2\x00\x8c\x16\xea\xf3\xf9\x17\xe1\x9c\xf9p\xfcW\xe5\xa0\xf5\x80'
b'\xcf\xe1>\x96\xbc\x8f\x8b\xebM\xc9H\x8b\xa0\x00\x0c['
b'q<m\xf9\x81\xebQy\x05\x00\xf7\xb3\x9b\xba\xf9\xac\xed\xf8\xf5\x16?L\x00\xb0\xaf\x01\xb7\xecj>~\xdb7\xad\xd9'
b'\xb8\xad\x9a\xd9\xc6\x17\x94\x0f\xde\nt/{'
b'x\xfdt\x01X\xa1T\xb2eJ\xa5\xbe\xae\x96T\xdd\xb9\xe7\xe1W\x06\xa7\xadR\x08\xc3\xe3\xf3\xeb\xa0\xc3\x10\x1f'
b'\xda\xf3\xe9\xafbcG}\xca\xb5\xc9\x088?\xdb\x13\x1c\xcc\x0c\xe0\x9ef)\x14\x95\xa0\x9c\xc6pl#pr\xce\xf0}yww'
b'=\xe6\xe8X\x0c\x9fwS`\xe0\xfbou\x02B\r?\x8b\x1d?\xce\xe0\xf7\xd70w99eMW('
b'\xf4pB\xd2\x87\xb886\x8c\x04\xa0\xe8\xf5\x01\xf4^xP5v\xed)\xcbRy:\x02q\xda\xee\x1f\x93\xb7?\x9d\xb7\xc3j'
b'\\\xcdAk~H\x1f\x00\x84\xf7\xe96\x0e.\xe6\xef\xf9\xde+\x1d=d\xab\xbfak\x04\xf2\xc0\xf9a\x91\xb1\xe5\x9e\x87G'
b'\xfet\x01\x80s\xd9l\x85bq\xcd|\x04\x00k\xd8n\x12\x89\xcfD\x1f\x9fuc\xbd\xbdW\x17\xc4\xc6\x81\x8d\x94\xcb7'
b'\xd7\xe0\xf1\x82\xf3\x13\x80\xf6b1\x86\xde\xe3\xdfd\xe7\n\xcc\x013\x02\xa1SB\x8d|\xa0\x9c\xbb{'
b'LqW\xd7\x88\x1c\x83Z=\xa2\x81@\xa0\x84\xdf\xc7\x1f\x98U\xe8{'
b'\xc3\x80e\xdd\xddg\xc3q\xf5\xe0\x9e\x04\xf0\x1c\x91\xb9\xcb\xc2\x9f\xfbxy\xc9\xafED4\xb1\x80\xe6\x07Q\x04'
b'\x05\xa0\xc7\xbc\xfd![N\xde3\xfb\xaa#\xb0\xfdBM\xcf\xf9\xfbc\x0eZ?5\xad6`u\xf2\x0f\x19\x05\x98\xb2#\xf5\x84'
b'\xcd\xcb\x9e7\x1c\\\x99\x83\x93(_{\n\xe6"\xf6c!\xeahv+\xf2\xe7\x0b\xc0\xdc\xef\x08\x00\x86\xd2\xa3\xe4\xf27'
b'\xe8\x94\x98\xb1wT\x01l8\xd4\xa6\x7f\x88De\xa1L\xfe\xb7\x04\xe0IL\xccxG\xa8}s\x83\x93\x82\xa2\xd3\xd2\x1aL'
b'\xf6\xf1Qj;\xaf\xbfT\x9a\xf026\xb6\x03\xdcO\x89\x82\xcc\x03`66l\x80Tz^['
b'\x7f\x81.\x9f\x1f\xad\xafTv\x82f\x05\xf9KQ\x14\x80\xee\xf3\xf6\x85^\x7f\xea\xb2Oo\xe4\xe6\xb4/\x9a\x01'
b'\x9csoM^lz\xf9`\xf5\x81?F\x00\xfe\xd7\xe6\x01\x14R\x00\x1c\xd1\xe1p\xac\xbe\x93X\xfc]\xeb '
b'\x12\xe1\xb0^\x05(SPX\x01\x80\xe6\x08\x03\xc7n\xd8V$Ri\x8bF\xa0\xcd\xfe\x017\x17\xc5\xb5\x0b\x05\x11\x80F'
b'\x02\x013\x0e\n\xda\x8bM\x12m\xa9\xc8\xf7\x87\x84\xec\xef+\x95\xb2t\x88<\x88"&\x00P\xcb\xab\xa1V\xeeWk'
b'\xd0ZI\xde\x0e\xbb\x8a}\x0c\x93G\xac4;\x05\xdf\xa5\x14u\x01\x80p\xdc\t\xda\xe4\r\xfazy\xd5.\x88\xf5\x03\xeb'
b'!\x914\x832\xc5\x85\x15\x00\x8c2\x8e\x86\x86N\x86\xe6Cb\xde\xf3pq\xd1b?\xbfsXc\x17t&`=>\x1f\xd3\x8fu\xac'
b'\xa1e~\x01\x8e\x12\x8c\x91\xcb\xcfg\']!\x9f)z\x02p '
b'\xfc\xa2\xfd\x87\xce=\xe6\xef\x17\xe4\xfd\xbed\xd7\xa5\x99+\x0f\xd9\xc4\xd4\x1d\xb6!\xb3('
b'\x0b\x00\x1af\xce\xa9\xc3\xe7+k\xf3\xf9~\x850\xff2nn\xa9\x85\x11\x00Ab"\x1b\x01\x02\xb0> '
b'\xe0H\x15-56\xd4\xe2i\xbb\x83\x83\x97\xd4\xe6\xf1\n,'
b'\x00\x98i\xe8FDD\x0bh\xefGj\x9b_0\xc9\xc7\'09#\xa3\x99\x92\x12\x83\x16\xc9\x08 '
b'\xfc\xa5\x8bW\xe7\xb9\xdb\xad>\xe5\xfd\xbexg}\xcd\xb8u\xa74u\x86\xae\xd7\x14u\x01\xf8\xe1\x96\x8f\x00\x04'
b'\xe2\xf2\xe0\xb5k\xd9\x1f\x9e\x9e\'Jjq\xec\x16\x9e\x9e\xd1\x86J\xe5\xef+\xb3\xb6)/\xb0\x00\xc0\xb15\x86'
b'\xcbdo\xb5\x1d\xf7\xa7X\x1c}8$\xa4%\x8e>\x10E/\x02\x88x\xf1\xc9\xabi\xc7\x19\xbb\xd7\xe1\xd0_\xdecZM4\xd6de'
b'\x04*\xda\x02\xa0\xcb\xe3\xa5\xb5\x06\xe7\x03\x8b*\xa8\xb5\x82\xe3!dO/\x8c\x00\xe0\xc6!n\t\tz\x03\xa5R\x1fm'
b'\xe7\x8c\x92\xcb\xd5\xfe))\xadxY\tA\n$\x00\x98A\x08\x87\xf8\xa6\xfa\xf8\x1c\xa9\xa0%\x9f!<w\xf2\x91\xd0'
b'\xd0i\xcd\x85B\xf2\x99\xa2(\x00\xb6\xaf<\x1aM\xdaxf~\x8d\x81k\xber^\x9c\xbd\x87\x86\xeb\x06\x8ar\x1f\x008'
b'\x90\xabipp;\xa3\xc0\xc0\xdf\x0bb[\xc0\x96\xf8\xf9u\xd1\xe5\xf3\xa5\x85\x11\x80\xe9\n\x05v\x00\xb6n*\x14Fj{'
b'\xce\xc1R\xe9U\xec\x8c\xc4\xa5\xcc\x85Y\r\x88Q\xc0\xae\xe0\xe0\x05\xf0>U['
b'f`\x93\xa0\xa0\xb3x\x1c\x88\x0b\xf9MQ\x13\x80+\x8f\x9c\x1b]~\xe8\xb4\xa8\xe9\xd8\xad_\xcd\x08\xfcv\xf6\xa0'
b'"5\n\x80\xc3\x80\xc51\xdf\x7fAl\xa1\x9f\x1fk\xe9\xe9Y\xbe\xb0\xc3\x80P\xf3\xb3\xf3j\xb5q\r-\xf7\x82\x8ej'
b'\x1c\x14t\x0c\x9d\xf9M\xd6\xeeB\x05\x16\x80\xb1r9\x9b\xe6\xe3\xd3\xa8\xb1@\xa0\xd2\xf6\xfb\xeb,'
b'\x16\x9fg\xeb\xd6\xb1\x0c\x1a\t(z\x02p\xd1\xfeC\x137\x89r \x84\xfb1$\x00\xda\x05`\xa4\\\xee\x18\x92\x92Rj{'
b'PP\x81\xca\xc4<|]%\x92J\x85\x19\x06\xc4\xccD\x7f\x81\xa3\xc2\xbd\x1c\xd7\x16\xaaW\xe3\xf1b\r\x94\xca\xdemE'
b'\xa2B\xe7\x03\xc0\xad\xcc\xc4II\x8d@\xc8\x82\xbf\xea\x08\xcc\x9a['
b'\xe0\'KJj\xe6\x94kV"QD\x04\xe0\xeac\xe7\xe6\x1b\x8e\xdf.\xd7a\xfa.^a\xf2\x06\xfc\x13\x02\x80\xfb\xe3\t\x13'
b'\x13\x8b\x8c\x00\xe0\xfe\x07\xdd%\x12;m\xf3\xfb\xbbI$Q\x96aa-\xa0\xbd^h\x01\x88\xcdj2\x94\x00G?\xaf\xads'
b'\xb1\x95\xa7g<D\x17\x1d\x97C\xf4B\x14\xbd&@s\xfc\xc7\xc3\x9c\xfe\xffk\x02\x80\xd9r\x1dccu\xc1\x01\x0b$\x00'
b'\xd8\xd9\xf5=\xc3E/{CBp\xb6\x1d\xb7\xa3Pa\x05\xe0^T\xd4w\xed\xef\x08\x80MD\x04n>\xda\x02\x9cT\xebp\x1d\xd4'
b'\xde<x\xc6\xbaJ\x10\x8a\xc2\n@8<+n\x82\xb290p\x7f5-\xcf\x89\xa9\xce.\xa8\xd5\xa6\xec\xe3G\xf2\x9b\xa2&\x00'
b'\xd0\xfeG\x01(\xb9\xfa\xf0M[\x1c\xfa\xfb_\x12\x80\x85\xe0\x9c\xf0O\xab\xdbN$\xfa\x9e\x00<\xc2g\xb8\x1f\x15U'
b'\xfc{f\x0f\xe6\x16\x1f_<9#\x83E\x81c\x14D\x00F\xcb\xe5oq\xf7!\xec\x07('
b'\xa0\xe1B\x9d\xaa\xba<\x9e\xb0\xa0\x020\x18\xda\xf6\'U\xaa\xbf\xea\x0b\x04\t\xda\xb6\x1c\x1b\xeb\xedm\x06'
b'\xdfq\xc9R\xa7AS\x01^\xcbmD\x01\xf8F.\x80\xdc)\xc1@,P\x9c\x96B\x19i\xda\xca\x87\xe6\x85UC('
b'?\xf6o\xec\xb0D\xfc\xcb#\x80y\xdb/\xb2\xe1+\x8e\xcf\xab\xd2oU\xfe\xcby\xff\x0b\x02\x80\xff\xb4\xc7BCu!\xfc'
b'\xf5\xfd\xd6v\\-<=\xd5\xd06~\xd6F$r\xf8\x9e\xb5\xf6\xf4|\x06\xe5\xda\x80\xf3\xebb&\xdf9Y\x9bu~s\x18\x10\xc2'
b'\xf2(C\x7f\xff\xe7`\x0e\x055}\xa5\xf2e]>?\xae\xa0\x8b\x81\xf4\xc0\xf9,\xc2\xc2,'
b'\xb4\xd5\xd0\xe0\xc4\x19\xa6\xc1\xc1kp\x06\xe0\xd3\xe8h\xdc\xa5\xb8\xf4\t\x95\xea\xd4@\xa94\xf6['
b'\xc9@*\xba\xbb\xcf\xad\x94-\x00\xb8\x01\x88\x99J\xd5\xb0\x8bD\x12\xaaM\xe4\xa0l\x14\xd1\n\xf1$\x00\xbf\x08'
b'\xe5\x87\xb1\xcd\xe6\xb6V\xe5{\xad\xc8r\xca\x8e\x8b\xbf\xb4\x0e\xdc\x82\x1fN\x00N\xddz\xcd\xccl^\xce\xc7'
b'\xe5\xba\xf8\xf9W\xc7j38\x0e\x97\xee\xe6\x08\xc0!\x10\x00\xdd\xef\t\xc0\x8d\xc2\t\x00&\xcc\x88\x00G\x85\x1a'
b'\xda/\xbf,9\xb9\x85\xa0 \x86\xc7NW(\xd4\xe1\xa9\xa9\r1\x94\x86Z\x14\xb7\xea^\x8c\x99q\xf2\xbb\x86Nv\x9e\xfd'
b'\xc2\x9a\xce7&\x02\x81\xa8i\\\x13\x12\xc6\x8bs66uu\xc5ED\x16e\xb4\x84\xf4\xbf\xf1\xf9\xeaqry\xb3\x81YQ'
b'\x02S$\'\x97\x9b\xe4\xe3\xe3\xae\xf3\x9dd \x7f\x88D\xf3\xdbf\xefa\x80b\x87k\x08\xc6y{\xbb\xe5\xb3\xc8('
b'\xfec\\\\G\xec0$~\x05j\x8ee&g\xec\xadp\xa5_\xd9\x1e\xcb?\x8f\xe9\xe7X\xe9\xee\x06\x9a\x81\xfaG"\xae?\xf9'
b'\xd4\xc2\xe1\xa3\x989\t}Gv\x98\xbe;\x01?\xcf{'
b'\xac6\xc3\xe3\xdaN\xdd\xa9q\x15\xfb\xad\xc7\x1c~G\xaf>7\xa97|\xa3\xa6x\x17}.\x9f@n\xc3D\xa3P6n8\xd2\x17\xc5'
b'\xa6\xa0\xc4eu^\x95\xdc\x19\x1cl\x0c\xed\xea\xd4\x9ct\xdbX\xbb\x95\xcb\xdeh\xa3\xb0V:\xab\xc9\x10\x02\x02'
b'\xa0\xe7\x0e\x02p)<\x9c]\x8b\x88h\t\xed|?\xcc\x92S\xe2?H\x00RP\xab\x05\xb5<4o\x9e$ed\xd4\x05\xc3\xec\xc48'
b'\x04\xd7\x00\x9cS\\F\xcb\xfd\x8e\xf6\xf6V\xbf\x8f\x8bk\x8a\xfd\x0b\x989\xc8\x17\x04`\x9aB\xe1R^\xcb\xf3\xe1'
b'\xe6\xa58d8B.O\xb8\x19\x199\x12GR\x10\x14\x19\xcc\xfa\x03\xcf\xb9;g\x93\xd3\x9cs\xf0\x9a\xcd\x85\xc2\x84'
b'\xb9\n\xc5\x9f3)7\xe0/B\xbb\x05\xec\xc8\xd5g\x9d\xdaM\xdb5\tj\xea\x89y\xad\xc9\x98-\x13\xa7n\xb6\x1cm\xf7'
b'\x9aW\xd1\xfa\xe1Gv\xc2\xe6e\xc9\xaes\xf6\x0e\x82\xef\xb4\x1e\xaf\xed\xfc!\xcb\x8eM\x12\xc8\x03\x9b['
b'?tb\x10\xde\xff\xder\x82\xf1\xa4\xaa\xfdWM\xac>`\xf5\x17\x06M\x8b\x89\xbd\x17\x1e\x18\x7f\xee\xde\xdb\x1ag'
b'\xef\xbd-\xf0#`8\n\xff\xec\xcc?9\xb9\xf4\xb6\xc0\xc0\xe1\xd5=<&\x82\x00L\x04G\x9d\xd8L(\xfc['
b'\xd6\x04l\xb5\xbf\xff\xc8\xc8\xb4\xb4r\xc2\xacZ\x91\xdbc\xefyL\xcc\xa0Nb\xf1\xa4\xaap\x8d\xea<\xdeO\xb3jP'
b'\xfexo\xef\x89\x10\xca\xff\xe6\x91\x90\xc0\xa5%\xe3\xc3\xabORR\x95\xc5~~\xe3\x1a\xe7\xb9_\xfcyc`\xe0('
b'\x0c\xcf\xd5ii\xb8\x858S&\'\x17_\xaeT\x0el\xee\xe99)\xef\xf35\x05\x83p~\x92]T\xd4 '
b'\x14\xcf\x9cE>\xd0l`\xf0\xdclOHH\xeb\xce\xf0\x9cM\xf3\x9c\x07\x91\xc2\xd8\xbe^^U\xfb\xd0\xd2\xe0_\x84\x0e'
b'\x0b\xd9\xd1k\xcfY\xc7\x19\xbbY\x8b\xf1\xdb\xc0\x8c\xbf0pb6\xcd\xe8,'
b'\xb3{\xc3c\x96w\x1d\xd9\xbc\x1dV\xac\xcb\x9c=\xac\xc5\x04\xe3\xaf\x8e\xd5fx\xfe\xd0\xe5\xc7\x19\x08\x00\xbb'
b'\xfc\x08\x04\xe0\xd6+\xd6j\xa2\t\xab6`5\xab1p\xcd\x17\x06\xa2\xc0\xfa,<\xc8@\x008+\x08Re('
b'\x93\x07\xa8\x98\xd0;\x90\x89\x03\xc2\xb8\x9e\xfbyR9\x9b,\x10\xb1y")['
b'\xe9%g+\xc42\xce\x0c%2\xb6X\xe6\xcd\x16J\xbd\xb9\xf7\x86\x129\x1b!\xf6bM<\x85l\x86\x04\x8e\x85\xcf\x96'
b'\xc0q3\xe1=\x1e\x7f) \x98y\xf9\xab\x98\x87\xd4\x9f\xf9\x85D\xb0\x000\xe7\xd0p6L\xe2\xc5zI$l\x11\x1c?\xdf'
b'\xd3\xeb\xf3\xeb\x02\x91\x17\xeb.\xf4dUx<6\x0e\xde/\x80\xcf\xe6g\xdbB\xb8\x97ab\t\xab\n\xdf\xd5('
b'\x80a\xf2\xcd\xc9>>\xcc\x01Bm\x0c\xb7\xefB\r\xed\x06\x91\x88\x14\x9a\x02\xd8S\x0f\x8e\xc9Zxz~6\xfc\x1971EGF'
b'\x01\xc0\x14f \x88\\&\xa3\x96\xb9\x8e\xcb1\x10\x05\xd6\x0f\x9c\xf8Qt4w\x0e4\xa1>\xffN\xd7@s\x07\x7f\x8f\x98'
b'\x81\xb8y\x9e\xf3\xdaCSa\x00\x9c\xd7\x8f\x04\x80\xf8_@\x06\x0e\n\x02P\x07^;F\xc6$\xd4\xc6%\xab\x01\xaa\xc8'
b'\xd6b\xdf\xe0\x0e^~\xa1\x1d\xa5JU{4\x9e,'
b'\xa0\xa3\xc0;\xb0\x83*2\xa6\x89O\xa0\xba)\x1c\xdf\x01\xc4\xa3\x83\xc47\xa4\x1a\x1c\xc7<}\x82\xeaC9xNK\xb1"X'
b'\x0f>\xef\x00\xc7q\xe7\xc3\xb1\xed\x95\xa1\x11\x1d}\x83\xc3\xd1\xda\xe2\x1a\xfb\xd8\xf8\xa4*\xf2\x80\xb0'
b'\x8ep,\x94\xa3\xea\x88\xc7xe\x95W\xd5\xd3\'\x18\xefK\x0f\xaf!\xf6\ri\x0f\x02\xd2\x11^;\xa8\xa3\xe2tC#\xa8'
b'\xedL\x10?\x8cC\x97\x1d\xd8\xe9;o\x96\xce\xddn\x15\xbf`\xe7%G\x99R\xf5\xe7\xf5\xa7\x9flf\x19_P\xef\xb5z,'
b'0<h\xa3\x9a\xb1\xf5|\xecv\xcb\xfb\x82u\xc7n\xabMN\xdb\xdb['
b'\xdc~c9\xd5\xe8l\xe2\xfc\x9d\x97\xd4G\xae<\x1b\x86\xfb\x0c\xec\xb1zl>i\xe3\x994\x83}\xd7\xdc\xb6\x9f\xb9'
b'\xbfs\x8e\x89U\x04D!\xfc\xf5\xc7oG\x8d^}2\xfa\x82\xdd{\xb7S\xb7^{'
b'\x8d_g\x11\x0be\x98\x04\xab\xa3\x87\xc1q\xe2\x85\xbb\xac\x83\x8e^}&\x9c\xb2\xc92\x0e\xde\xab '
b'\x9a\x1a\xb0\xe5\xd4=l*\xed\x81\xeb&\xe8\xef\xb9\x12\xbe\xf3\xec\x03\xde\xda\xa3\xb7\xe2\xb7Y\xd8m0:iK\x7f4'
b'\x82(p\xfb>1\x99%\xa5\xa42p"6l\xc5q6\xc2\xf0\x04\x9b\xb2\xd9\x92\x99^x\xc4v\x9f\x7f\xc8\xccl^\xb0K\x0f>4'
b'\x1a\xbd\xe6dP\xbd\xe1\x1b4\x8bw_>\xb3t\xef\xd5\xdf\xa6o9\xf7\t\x9cw\xf8\x8c\xad\xe7\\\xa0y\x93\x01\xce'
b';\xe4\xc0\xa5\'GW\x1f\xbe\xe1p\xfb\x85\xdb_\x9dg\xef\xd1\x0c]v\xcc\x15\x9a5\x15\xb1\x9c\x17.^\xe3\xba\xcd'
b'\xdd\x17\xd1s\xfe~\xe5\x0e\xcb\xfb\x07\xa0\x0c\x0f\x07\'\xf1\xef\x03\x96\x1c\xbeRg\xc8\xfa\xd8AK\x8f\xb6'
b'\xdbw\xf1\xf1\x8a\xdf\'\x99h:\xcd4M\x02\xe1\x19<n\xed\xa9\xe93\xb7\x9d\x7fp\xe5\xb1\xf3\x04\xb8\x86\xe6/C'
b'\xb3\x0fV\xf6\xef\xcbY\xdd\x7f\xcf@\x84\xbav\x9f\xb7/\t\xc4Cz\xed\xb1s\x1b\x10\x897p\xdf\x86\xb3M.p\xcf'
b'\x84a7\x1c\xcb=\xcf\xc8\x95\'\xd8\x985\'\x99\x919\x88\x83\xce\x00\xfa\xa3\x13D\x0e\xe8\xfc\xa9i\xe9\x8do>s'
b'=\x06"`\xbe\xfb\xdcCsp\xbeS\xe0\xc4\xfdn=wcvo\xf8\xcc\xd1C\xfe\x1b\xd4\xac\x82\x01\xfaG\x9cZ\x8c\xdf\x96'
b'\x08\x8ejlla\xf7\xc9\xf2\xee\xdb^\xfa{'
b'\xaf~l7m\xa7\x06\x9c\xfc\xce\xa2\xdd\x97%|y\xe0\x06\x81<\xb0O\xbf\xc5\x872\xc1!\x9dp\xa6\xdc\xb5\'\x9f\x18k'
b'>\x93A\xb4p\xa0\xf1h\xa3\xcc\xf9;.\xa5\xc2\xf56`\x9fH\x8d\x01k64\x1b\xb75f\xc4\xca\x13\x8d.=\xf8\xb8\x08jyA'
b'\x9b);\x82\xfa/9\xec~\xe2\xc6K\xd3\xcd\xe6\xb6w\\%\xca\xa1\xbd\x17\x1e\xd0@\x8d\x8f)\xc1J=x+\xc0~\x83v '
b'\x1a\xf1 \x00\x91\x1b\xcc\xee\xd8l=u\xcf\xc3\xd1C\xd6\xe0\xf1\x07O\xee\x99pV\xe5K\x17/\x13x\x9eS\xbb\xcf?2'
b'\x87h\xc5\xe2\xca#\xe7y\xd8oB\x10D6\xb1\tI,'
b'19\xb5\xde\xaaC76\xb6\x9d\xb2\xc3\xa8\xfd\xb4]F}\x17\x1d\xdc\n!u\xa75Gn2\xbb\xd7<\xf6\xcaUZ\x0f\x1c\xf1'
b'#\xd4\xf0\xb3\xc0\xb1\xfd@\x0826\x99\xdd\x8d:k\xfb\xb6\x07\xd4\xe4N\xbfO4\xc9\x84\xf0\xfb\x19\x1c\x9f\xf4I'
b'\xe4;\x80\'\x0b\xe8\xc9\t\xc0&N\x00J\xdb<u\xa9\xb1\xe5\xe4\xbd\xf2P#\xb7\x85\x9a<f\xd4j\xf3@/\xbf\xd0\x86'
b'\xc3W\x98\xb1Z\x83\xd6nl6vk\xcc\xd0\xe5\xc7\x1b^\xbc\xffA\x7f\x89\xe9\x15k\x88>\xb6\xb7\x9c`\x9c\x01b\x90'
b'\xbe\xd1\xec\xae\xad\xab\xc4o\x18\n\x00D\x1d\\N@\x10\x8a\xaa\xcf?Iz\r28\x1a\x0f\xf7\xa2\x82\x9a\xfd\xfd'
b'\xaes\x0f\x02\xa3\xe3\x13\x9b\x8a}C\xb8g\xc2\x19\x83\xc7\xaf\xbf\xd0\x87\xe7\xd9\xd2a\xfa.\xa3.\xb3\xf6l'
b']lzy,(\x11\xfd\xd1\t"\x8f\x00\xb0\xb5Gn\xb1\x8e\xd3w\xb3\xce\xb3L\xd9@\xfd#l\x83\xd9m\xb6\xfe\xd8mf\xe3\xe0'
b'\xc2\x9e~\x14\xfd\x06\xce\xed1\xdb\xf8\xc2\xef\xd0V_\x06\x0e\xa5\xe9:go\x028bwpR\xa7.\xb3\xf7d>s\x16\x0f'
b'\x90\xfa\x85\xce\x84\xf2\xf4\xc0a{\xf7YtP3\xd5\xe8\xacSrjZ\x1dp\xea\x8b\xe0|\xb3\xf9\xb2\xc0\x86\x03\x97'
b'\x1e\x89\x9e\xb4\xf1\x8c\x7fXT\xac.+\xd6\x9f\xb5\x9ahl\n\x02\x90\xb0\xe5\xa4m\x9b\x93\xb7^/\x9e\xbf\xe3'
b'\xe2mp\xdeJ @o\xea\x0e\xdb\xa0\x99\xbc\xc9\xf2\x9e\x9b\x97r(4\x1d4\xd0\x1cx\x0b\xb5{'
b'\xedE\xbb\xad\xad\xf7_|\xb2\x1f\xa2\x848\xf8^\x0c\xc7\xb7vt\x979A\x04\xb3\xfe\xe0e\x87\x1c\x01`\xe67^r\xcf'
b'\x03\xce\xcfz\xcc\xdb\xc7@\xac\xe0\x89\x7f\xa7?:A\x14\x94\xd1\xab\xcd\xd9\xf8u\x16\xfd\xba\xcd\xd9+]\xb6'
b'\xef\xaaEt\\b=h\xfb[\xf6_|X\xbe\xd1\xec\xce\xa4\xae\xb3\xf78\xd7\xffkc0\xfc\xbc\x10\xda\xe5\x0cD\x81\xcd'
b'\xdbqQ\xbf\xe9\xd8-!\xd0\x96w\x86Z\xfb\x168\x9f\x12\x1cz:\x08\xc1p\xa8\xd9};\xcf\xda\xe3\x05M\x86\x9egm\x1d'
b'\xbb\rXr\xd8\xad\xce\x90u!\xdb-\xef_\x82\x88\xc1\x02"\x0794A&\x08\xe4\x01]G\xae:!\x04\xb1\xb0\x06\x911l2'
b'\xda(\x14\x84\xe6#\x94w\x1b\xca\xf3\x05g\xbe\xdbd\xcc\x16\x05\\\x83\x0f\xf7f\x04\xf7)l3y\xfb\xaa\xf6\xd3v'
b'\xd2\x1f\x8d ~\x14\xe0\\l\xd0\xd2#U+\xf56\xd4\x1blp\xb4\xc1y\xbb\xb7\xc5!\xa4/7w\xbbU\xbd\x85\xbb.U\x03\xe7'
b'\xd5\xab\xd0k\x85\x1e8\xa8n\\"\xb7\x94\x96A\xed\xaf['
b'\xb1\xf7\n\xbd\xd2\xdd\x0c\xf4\x8auZ\xdc\xa8\xf9\xb8\xadz\xd0\x9e/\x0fBR\xbdz\xff\xd5z\xbf\r\xdb\xa0\x07'
b'\x82P\xc5\xe4\x8c}\x95\x06#65,\xd3\xcd\xa0\xc1t\xa3\xb3\x8d\xc6\xac9\xd9\xa8"\x94ex\xf0z-\x9c\x1bar\xda\xbe'
b'\x16\\\xa3\x164Ijg\x95\xb7T\xaf\xd8\x9f\x8b\x1bA\x93Co\x8e\x89UC\xb8\xa7\x06\xa5\xbb.\xd5+\xdfsy\xe3\xb2'
b'=\x965\xec9\x7f_\xa5?g\xee\xa6?\x1aA\xfc( '
b'\xf4fC\x96\x1dc\xba\x83\xd7\xb2\xbf\x0c\xcd\x98\xdd\x1b\x0ffv\xfd\x057yi\xc9\x9e\xcb\xac\xe1\xc8M\xacJ\xdf'
b'\x95\xac\xe5\xf8m9\xb3\xf9P0\x188:\xf7y\xa5>\x86\xac\xf5D\x13n8q\xd2\x863\xac\xf6\xe0u\xac\xd1\xa8\xcdl\xc3'
b'\xf1\xdbl\xe7\xd9\xfb\xac\xe9\x98-\xacB\xaf\xe5l\x8e\xf1\x056n\xed)\xee:\xab\x8f\xdc\xe0\xcaY}\xf8\x06F\x13'
b'\x0c\x84\x87U\xeb\xbf*\xab\xbc\xde\x86\xac\xed\x94\x1d\xdc\xe79\xd7@\xc3\xf3\xba\xcd\xdd\xcbH\x00\x08\xe2'
b'\'\x93\x9a\xb5m\x16\xc3\xfd\xf401\x86\x1f\xa6\xb2\xber\xe5\x87\x95\x1f\x99\x9e\xcem\x1b~B\xa5bc\xbd\xbdYv'
b'\xf2M\xfa\xc5\x13\xc4\x7f\x13L\x82\x89\xeb\xf7q\xf5\xdeQp|\\\x0b\xff&6\xb6\x12\x0e\xf5\xe1\xea8\\5\xf8'
b'<&\x86\xdbW\xaf0;\xdc(@@p\xbd\xc1K8\xff\x18\x94\xfb\x0c\xca\xc0\x19\x87\xce\xf1\xf1\x95\x0c\xfd\xfd\xb1\xfc'
b'\xb2\xa7\xc2\xc2p\xb1\x10\x970SII3\t\xe2\xe7\x92\x9e]\xcb\x07\xa7\xa62t>\\\xcd\xf60k^{'
b'\xb1\xe8\xb4\xb4*vQQ\xd3\xd6\x05\x04\xbc\x1c)\x97\x8b\xd7\xfa\xfb\xdf\x01\x01\x98\x0bb\xd0\x18E\x01\xcf7'
b'\x0e\n\xe2V\xcc=\x81sp\xa3\r,\xc7\x07#\x85\xb5k\xb9W\xcc\x02\xf4>.\x8e['
b'T\xb3\xc4\xcf\x8f1ggn\xe8\xeeRxxe\xdb\xa8\xa81k\x02\x02\xf6\x8f\xf1\xf6\x16\xfc\xee\xe9\xe9\xb9> '
b'\xe0\xa1ux\xf8(qbbE\xbc\'\\9\x88"\xd4\xdb\xcb\x8b\x81Hp\xe2\x11C\xeb\xe7\t\xe2kp\xdf{'
b'tf\xdc\xe0\xb3\x1d\xaeIwu\xfd\x7f33\xe3\xc2\xf7hp\x9e\x10pPp0nq\xcc\x19p\\C\xccK\xf7\xe2\x05\x97\xf2*6=\xbd'
b'\xec\xc5\xf0\xf0\xaaP\x03\x8f\xdd\x1a\x14tt\xbaB!l\xe5\xe9\x99\xc2mt\xe9\xe2\xc2-\x95m,'
b'\x14j:\x8a\xc5\xf2\x15J\xa5\xebr\xa5\xd2\x18\xce\x9fa\xa6R\xcd\x02g\x9e\xe5\x14\x1f?K\x9e\x9c<\x1b^\xff'
b'`\xf6\xf6\xa5\xc0y\xbb@X?\x1b\xa2\x85Yg\xd5\xeaYs}}g\xc2\xb9\x0b\xe7\xf9\xfa>\xeb$\x16\xf3\x9b\t\x85I\xb9'
b'\xf7\xd0\xc3\xb5\xf9M\x84\xc2\xf8Qr\xb9\xc7L\x85b\xa7\xb9J5\xe3ELL\xcb\x9b\x11\x11e\xb23\x04\xe9\x8c\x83'
b'\xa6\x02.\xd6Aq\xc0\xc5=\x12\x10\x18\x14\x9d\xc8\xb44L\xc4\xc9\xd8\x8d\x1b\x9f\x9f\x1b\xee\x95\x1d\x87HC'
b'\x00M\x0bl^\x10\xc4\xaf.\x00: \x00\xe5j\xf1x\xe5\xd8\xd3\xa7\xa5\xd9\xc7\x8f\xa5\xc1\x11J\xb3\xd7\xafK=\x8d'
b'\x89\xf9- %e\xb2<)i\x8aK|\xfc\x94{QQS\x8e\xa9TS\xe6\xfb\xf9M\x1e+\x97/\xde\x1e\x14\xf4z\x9aB\xf1\t\x9c\xd2'
b'\x03\x9c0\xb5|\xf6Z}\\\xc7\x0e"\x90\xdc\x1a\xac\\N\xf6\\\x10\x03\x9d\xec\xd4\xd9\xbf\xf1\xf9\xe8\xb4\x1a'
b'\xa8\xc1\xb9\xac;\x9d%\x12M]>_\t\xc7|l('
b'\x10\x84\xfc\t\x9f\xb5\x11\x894P.\xee\x8e\xcb\x95\xa7\x93+1\x06\x8aK\x03\x81 '
b'\xf9\x0fOO!\x94\x93\x88?c\xc6\x9cR\xd9b\xd3T(T\x0c\x90J\x9d '
b'RpY\xec\xe7\xb7\xbf\xaf\x97\xd7$x?\x05\xc4k\xca}x\x06\x97\x84\x84)\x10eL\x81\xe6\xc2\x84\xeb\x11\x115\x99'
b'\xa3c)\xf6\xf6mi\xf6\xf8qi\x10\x97\xf2 '
b'N\x15@\x00\x8a\x93\x00\x10EA\x00J\xde\x8c\x8c\x9c\x015\xe8\xd1\xae\x12\xc9\xeb\xaa\x1e\x1eo\xc1\xe1>\x95tss'
b'\xae\xc1\xe3yaV\x9c.`P\x0bc\xf6\x1a\xce)\xc1Y\xb9]k\xcb\xe6Jn\x01N\x97\nN\x97\x00a\xff\xb3\xb5\x01\x01'
b'&;\x83\x82\xba\x1d\t\r\xed\xbd\xca\xdf\xdf\x0c\xca\xfd\x80\xc9Br\x04"\xc7\x91\xbf\xb0<\xd9or\x1b&\x17\xc1'
b'\x9a\xbe\x9e@\x90\xd1Y,V@4ps\x7fH\xc8\x04\x88\x16\xeao\x0c\x08\xe8\xae\xef\xe7w\x10\x9c\xfc\r\\\'\x19\xee9'
b'\x15\x85\xa0tvb\x0f<\x0f\x9e\t\xcf\xc5\x84\x1a\xdc3\xa0\xc0\xe0su\x07\x83\xe3=\xe1\x19\xde\xc3\xf7\xaf\xfbK'
b'\xa5/{yy\xed\x81\x08`5\x08@C\x12\x00\xa2H4\x01\xa0V/\x06\xb5}\x9d\x1dAA\xfd\x17\xfa\xf9-\xda\x10\x10\xf0h'
b'\x84\\\xfe\x08\x1c\xe6!\xd4\x88\xf6P\xbb\xda\x83#\xdaC-l\x0f\xcen\x0f\xceb\x0f\x8eh\x0f!\xb7\xfd\x9e\x90'
b'\x90\x07{CB\x8c6\x07\x06\xf6\xf6NN\xee\xc1\xb5\xf3\x9f=c\x98\x9d\x17\xdb\xfa\x10U`r\x8c\xea\xe0\xb0}\xf7'
b'\x06\x07\x9bM\xf4\xf6\xbe\x0f"\xf2\x16D%\x15j\xef\xf4\xea<^Z\x19w\xf74\xb8F\x1a\x94\x9f\x06N\x9b\x06\xd7H'
b'\x83(!\r\x9a%\x19\x10\t\xc8\xbb\x88\xc5vP\xd6m(s\xd2\x87\xb8\xb8\x16l\xe2D\x86i\xb4\xe0=['
b'\xa9T2\xf6\xfc96G*?\x89\x8e\xee=L&\xeb\xbd> `/\xd4\xfc\x0f\xc0\x99\xed!R\xb0\x07\x07\xb7g\xd9\xcfP<\xfb\x19 '
b'\xd2\xb0\x07\x87\xb7_\xa6T>\x81\xe7=\x04\xe2\xd5\xff\x9cZ\xdd\xffQttu\x10\x95\xe2 '
b'\x00:$\x00D\x91\x00;\xe20\xe3\r\x0e\xdbe;\x93N\x8e\x810\xe8\x0c\x95\xc9tJ\xb9\xba\xeat\x14\x89t\xa0\x1d\xad'
b'\x93\xfb{4v\xf0 3\x01g\x97g\xe7\xce\xcb\xdd\xcb\x8f"\x83\xb63W\xbe~\xff\x94\x94*\x0e11\xfd\xc1\xf1\x06\x82'
b'\x13\x0e\xac\xc7\xe7\x0f\x84\x9az 8\xff@\xa8\xad\x07\x82\xe3\x0f\x04q\x19xA\xad\x1e\x04\xf7\xd5\x9c5i\xc2'
b'\xdd\x134\x19\xb8\xce\xc1\xfe2\xd9\x17\xf7\x8fmy\xcc\x94\xfb8:\x9a\xfd\x85\xdf\x8d\x1e\xfd\xc53,'
b'V(t\xaa{x\xe8\x80\xc0\xe8\xf4\xf3\xf2\xd2\xb9\x1f\x19\xf9\xe5\xfd\x0f\x1b\xc6\xa5#\xbf\x1a\x1e\xce%\xfd\xc0'
b'\xfe\x0e\x82 ~\x028T\x17\x94\x9a\xcau\xc6m\n\x08`P\xf32\x10\x00\x06\x02\xc0@\x00\x18\x08\x00\xd7!9K\xa1'
b'`\x17\xc1!1Q\xe6\xbb\\[s\x11\x04\xf1_\x00SQ\xb1;w\xb8\x0c\xbd\xf2\x1fXK\xe6\x9e84\xde\xdb\x9b+\x1f\xf3\xf0'
b'\xbd\xfd\xc1N\x8fQ\x8e\x17\xdc7D4\\\x14A\x10Da\xf8\xf0\x81\xd9EEM9\x10\x122$,'
b'5\xb56\x0e\x032GGnX\x10\xc3f\xd7\x02\xeeY\x87;\xe0DgO\xec\xc1\xbc{'
b'\xec\xdd;n\x8c\x1f\x9c\xbe\xcbDo\xef\x1e\x9b\x03\x03{'
b'\x82\xc0\xd4c\xaf_3\xf6\xe4\t\x17\t`\xee<e\xf6\xfc\x80\x82\x82\xd7H\x01qAa\x19)\x973\xf6\xea\x15\x93\'\'7x'
b'\x12\x13\xd3\xc8\x91\x04\x80 \n\xc7Hh#\xaf\xf6\xf7\xff\x0b\x9cI\xd9\xd3\xcb\xcbmu@\x80\x8d\x99J\xb5\xdc2,'
b'\xac\x93:-\xed\xb7f\xb8w\xbd\x83\x03c\x0f\x1e0fk\xcb\xd8\xed\xdb\x8c\xdd\xbc\x99\xf5z\xf7.cvv\x9cCg\xef'
b'\x9cS\x1ej\xe1NS}|:m\t\x0c\xdc\n\xaf\x8f1\xe7}]>?\r\xcaI\xfbS,\xf6\x98\xeb\xebk\xb3=('
b'h\xcd\x0c\x85\xa2\x13\x88EG\xcc\x1dP\x8d\xc7\xe3\xfa('
b'\xd8\xc3\x87Y\xe5a\xb9X\xfe\xe3\xc7\\\xd9\xec\xd6-\xc6\xee\xdd\xcb\xfa\xde\xc5\x05\xafS\x1aj\xfe\x0e;\x83'
b'\x82\x06\xc1u\xce\xaf\xf0\xf7\xe7\xdf\x8f\x8e6\xc4\xf9\x00\x04A\x14\x02\xa8\x99\xd9\x1c__6S\xa1\x18\xd1]"Q'
b'\xe1\xd0Z\r\x1e/\x13\x9c5\t\xcc\xbd\xadHt\tjkkpZk\x88\n\xacoDFZ\xdbFEY\xdbDDX[\xaa\xd5\xd6\x109X/U*\xad{'
b'yy]\xfa\xdd\xd3\xf3Q_p\xf8z\x02Ab\x99\xec\xbc\xfau\xf8\xfcT\x10\x01~k\x91H\x85Cw8\x94W\xde\xdd=C\x0f\x8e'
b'\x01\xc1\x89\xa9\xcf\xe7\xdf\xc3kL\xf4\xf1\xb1\xde\x18\x18h}$4\x94+\xf7ZD\xc4\x95\xf3j\xb5)\xbc\xdf\x81'
b'\xefA\x94\xac\xa1\x19a=F.\xbf\xd4N$\xb2\x852\xa3\x1b\n\x04\xa9\x1d\xc4b\xcd\xa6\xc0\xc0S\x92\xc4\xc4\nw\xb3'
b'\xf3\xf0\x13\x04Q@\xe6\x83\xf3sm\xe7\xb7oq\x93\xcc\x1e\xe0`\x17\xc1\xb1"K\xe5\xda\x08\xa4t\x96\xd3j*\x828'
b'\xe0l\xbd*\xd9\xaf8O\xa0B\xf6\xe6\x16\xc5s\xcd\x03\xc0M>\xc0\xa9\xd3\xa6\xf8\xf8\xbc5\t\n\x9a\xf9!.\xae'
b'\x8aEXX\xd7\xf1\xde\xde\xe7Zzz\x86\x97\xcf5\x89\x88e\xef\xfc\x83e\xe4\\\xa3Rv\xf9\x15\xb2?\xc3\xf7\xf89N'
b'>\xca\xd9a\x17\xbf\x1b,\x95\xaa\xad\xc3\xc3\x0fc\xe4\x81M\x02\x07\xdaY\x87 '
b'\n\x0f\xf6\xcas\t5\xd5jn+\xeb=\xc1\xc1=\x97)\x95\x97\x06H\xa5\x12\xdc\x1a\xab\x1e\x9f\xcf9a\xe9\xec\x99y'
b'\xb9\xb7\xecB\x07\xc5\xddv\x9a\n\x85\x1a\xa8\xe5\x03!Z\x10\xaf\x0f\x088\x06m\xf2II\x19\x19\x95q\xba.\xee'
b'\xaa\x83k\x0bp\x13\x10s\x95\xaa\xdb*\x7f\xff\xf3P\x83\xcb\x1b\x0b\x04\xe9\x95rM\xff\xfd\x9e\xa1\xf3CSC3X'
b'&\x0b\x83Z\xff\xb4cllg,\x13G <hl\x9f '
b'\xfe3\x16\xfb\xf9q\xcbq\x8fe\xad\xfa+u5"\xa2\xf2\xe5\xf0\xf0\x9e\xfbCBV\x8e\x90\xcbW4\x16\nW@\xed\xbe\x02D'
b'`\x05D\x08+j\xf3x+\xa0\xd9\xb0b\x85R\xb9\x02\x9c|\xc5\xf3\x98\x98\xb6\xa1ii\x95\xd1)_\xc5\xc6r\x91\x05\n'
b'\x0bv\xf2\xed\x0b\t\xe1\x04\xe6|\xb6\xc8<\x8d\x8e\xae\re\xcf\x19-\x97\xaf\x9b\xe7\xeb\xfba\x88L&o&\x14\xca'
b'@hd\xe0\xe82\xb8\x86\xac\xac\xbb\xbb\x0c\x04H\xd6U"\x91\xcd\xf6\xf5\x95O\xf6\xf19\x05\xe5\xac\x10%&v\xc5'
b'\x05Jx\r\x1cm\xf0\xc6\x05G\x04A\xfc\x18p\xa6\x1cn\x0b\x86\xfd\x03\xe7\xc0a!"\xe0&\xe2@\x8d\xcd@\x00\x188'
b'\'\x03\x01`\xba<\x1e\xeb&\x910\x03\xa5\x92[9\x885=\xbe&\x83S\xe2\xbe{'
b'\xda\xc0\xf1\x7f?\xa8\xb1\xcfBDp\x11\xca\x86\xb0\x9e\x9b\xed\x07\xe7\xd6\x98\xadPTo!\x14V\x87\xf0\xbez\tW'
b'\xd7\xeaP~\xf5ARi\xf5C!!\xd5#\xd3\xd2j\xa0p\x1c\x03\x81r\xca\xde\xcdGB\x13{'
b'\x08\xe2\xdf\x0b\xee\x99\x97\x01b\x81\xfb\x04\x82\x93s"\x83['
b'uC\xcd\xcf\x8a\x83\xc8T\xf3\xf0`]@`p\x95"\xe6\x1c\x88JK\xe3\x8c \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 \x08\x82 '
b'\x88\x7f\x82\xff\x03\xe2\x1d\xb6Y\xca\x8f\xc5Z\x00\x00\x00\x00IEND\xaeB`\x82')

17
nflmusic/decode_format.py Normal file
View File

@ -0,0 +1,17 @@
import re
def decode_format(value):
match = re.match(r'(\d+):(\d)', value)
if match:
minute = int(match.group(1))
second = int(match.group(2))
time = minute * 60 + second
return time
else:
return None
if __name__ == '__main__':
value = input("输入转换的时间戳:")
print(decode_format(value))

50
nflmusic/files.py Normal file
View File

@ -0,0 +1,50 @@
import os
from nflmusic.assets import images as ima
import json
def create_path():
# 父文件夹
if not os.path.exists("../.NFLmusic"):
os.makedirs("../.NFLmusic")
# 子文件夹assets
if not os.path.exists("../.NFLmusic/assets"):
os.makedirs("../.NFLmusic/assets")
# 子文件夹data
if not os.path.exists("../.NFLmusic/data"):
os.makedirs("../.NFLmusic/data")
# 子文件夹downloads
if not os.path.exists("../.NFLmusic/downloads"):
os.makedirs("../.NFLmusic/downloads")
# 子文件夹assets/buttons
if not os.path.exists("../.NFLmusic/assets/buttons"):
os.makedirs("../.NFLmusic/assets/buttons")
# 子文件夹data/settings
if not os.path.exists("../.NFLmusic/data/settings"):
os.makedirs("../.NFLmusic/data/settings")
def create_files(file, method, content=None):
if content is not None:
with open(file, method) as f:
f.write(content)
def init():
create_path()
create_files("../.NFLmusic/assets/buttons/play_music.png", "wb", ima.buttons["play_music"])
create_files("../.NFLmusic/assets/buttons/pause_music.png", "wb", ima.buttons["pause_music"])
create_files("../.NFLmusic/assets/buttons/stop_music.png", "wb", ima.buttons["stop_music"])
create_files("../.NFLmusic/assets/buttons/delete.png", "wb", ima.buttons["delete"])
create_files("../.NFLmusic/assets/buttons/refresh.png", "wb", ima.buttons["refresh"])
create_files("../.NFLmusic/assets/icon.ico", "wb", ima.icon)
data = {
"auto_update": True
}
create_files("../NFLmusic/assets/data/settings/auto_update.json", "w", json.dumps(data["auto_update"]))
if __name__ == '__main__':
init()

56
nflmusic/get_url.py Normal file
View File

@ -0,0 +1,56 @@
import requests
import re
import json
def re_domain(url):
pattern_domain = r"https?://([^/]+)"
match = re.search(pattern_domain, url)
if match:
domain = match.group(1)
return domain
else:
return None
def get_url(url):
domain = re_domain(url)
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0"
}
response = requests.get(url, headers=headers)
iframe_pattern = re.compile(r'<iframe\s+class="ifr2"\s+name="\d+"\s+src="([^"]+)"\s+frameborder="0"\s+scrolling="no"></iframe>')
matches = iframe_pattern.findall(response.text)
response2 = requests.get(f"https://{domain}{matches[1]}", headers=headers)
pattern = r"'sign'\s*:\s*'([^']+)'"
sign = re.search(pattern, response2.text).group(1)
pattern2 = r"url\s*:\s*'([^']+)'"
url2 = re.search(pattern2, response2.text).group(1)
data = {
'action': 'downprocess',
'signs': '?ctdf',
'sign': sign,
'websign': '',
'websignkey': 'bL27',
'ves': 1
}
headers = {
"Referer": matches[1],
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0"
}
response3 = requests.post(f"https://{domain}{url2}", headers=headers, data=data)
data = json.loads(response3.text)
full_url = data['dom'] + "/file/" + data['url']
headers = {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"sec-ch-ua": "\"Chromium\";v=\"122\", \"Not(A:Brand\";v=\"24\", \"Microsoft Edge\";v=\"122\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "none",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1",
"cookie": "down_ip=1"
}
response4 = requests.get(full_url, headers=headers, allow_redirects=False)
return response4.headers['Location']

BIN
nflmusic/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

285
nflmusic/ifm_json.py Normal file
View File

@ -0,0 +1,285 @@
usercache = {
"language": "简体中文",
"theme": "sandstone",
"path": "./music",
"br": {
"QQ": "HQ高音质",
"KUWO": "HQ音质",
"KUGOU": "HQ音质",
"WANGYIYUN": "较高"
},
"choice": "KUGOU",
"auto_update": True,
"playing_mode": 0,
"auto_play": False
}
api_data = {
"QQ": ["https://api.xingzhige.com/API/QQmusicVIP",
{
"SQ无损音质": 11,
"臻品2.0": 10,
"HQ高音质": 9,
"标准音质": 7,
"有损音质": 3
}
],
"KUWO": ["https://api.xingzhige.com/API/Kuwo_BD_new",
{
"SQ音质": 3,
"HQ音质": 2,
"标准音质": 1
}
],
"KUGOU": ["https://api.xingzhige.com/API/Kugou_GN_new",
{
"SQ音质": 3,
"HQ音质": 2,
"标准音质": 1
}
],
"WANGYIYUN": ["https://api.xingzhige.com/API/NetEase_CloudMusic_new",
{
"标准": 1,
"较高": 2,
"极高": 3,
"无损": 4,
"Hi-Res": 5,
"高清环绕声": 6,
"沉浸环绕声": 7,
"超清母带": 8
}
]
}
class Language:
zh_cn = {
"frame.song_list": "歌曲列表",
"frame.download": "下载音乐",
"frame.playing_settings": "歌曲设置",
"frame.treasure_chest": "百宝箱",
"frame.about": "关于",
"frame.update_log": "_version_更新日志",
"frame.base_settings": "基本设置",
"frame.thanks": "鸣谢",
"frame.version_list": "版本列表",
"menu.homepage": "首页",
"menu.settings": "设置",
"menu.about": "关于",
"menu.versions": "开发版本",
"mbox.title.search_fail": "搜索失败",
"mbox.title.delete": "删除",
"mbox.title.delete_fail": "删除失败(▼ヘ▼#)",
"mbox.title.play_fail": "播放失败(▼ヘ▼#)",
"mbox.title.network_connection_fail": "联网失败(╥╯^╰╥)",
"mbox.title.save_settings": "保存设置",
"mbox.title.position_not_exist": "无效的目录",
"mbox.title.restart": "提示",
"mbox.title.joke_warning": "安全警告√(─皿─)√",
"mbox.title.joke_fail": "你的电脑可能会爆炸!",
"mbox.title.joke0": "窗口",
"mbox.title.update_reminding": "更新提示 - v_version_",
"mbox.title.update_start": "更新 - v_version_",
"mbox.title.update_fail": "更新失败(〒︿〒)",
"mbox.title.download_web": "即将进入下载页面",
"mbox.title.copy_pwd": "密码提示",
"mbox.text.search_fail": "没有搜索到你想要的结果~(╯°Д°)╯︵┻━┻",
"mbox.text.delete": "确定删除这首歌曲吗?",
"mbox.text.delete_fail_no_target": "请先选择你要删除的歌吧(•́へ•́╬)",
"mbox.text.delete_fail_no_permission": "源文件正在使用或无权限ヽ(#`Д´)ノ",
"mbox.text.delete_fail_not_found": "源文件不存在(╯°Д°)╯",
"mbox.text.play_fail_no_target": "请先选择你要听的歌吧(•́へ•́╬)",
"mbox.text.play_fail_not_found": "源文件不存在或暂时无法播放ヽ(#`Д´)ノ",
"mbox.text.play_fail_unrecognized_format": "文件_file_已损坏或该格式不支持o(╥﹏╥)o",
"mbox.text.network_connection_fail": "服务器连接失败╮(╯﹏╰)╭\n请检查网络设置或稍后再试吧~",
"mbox.text.save_settings": "是否保存设置?",
"mbox.text.position_not_exist": "当前目录不存在,请重新设置吧┓(;´_)┏",
"mbox.text.restart": "更改设置后需要重新启动程序!",
"mbox.text.joke_warning": "NFLmusic不会受责任于任何千万别点按钮,确定继续吗?",
"mbox.text.joke_fail": "别了NFL_jiancx十分害怕把你的电脑卡炸",
"mbox.text.joke0": "这是一个窗口",
"mbox.text.update_reminding": "检测到新版本,是否更新?\n\n_update_",
"mbox.text.update_latest": "当前已是最新版本(。◕ˇ∀ˇ◕)",
"mbox.text.update_fail": "请检查网络状况或稍后再试吧╮(╯﹏╰)╭",
"mbox.text.update_start_auto": "检测到新版本,即将为您更新!\n\n_update_",
"mbox.text.download_web": "是否进入_url_",
"mbox.text.copy_pwd": "文件密码:_pwd_已帮您复制到剪贴板",
"ui.download.text.song_name": "歌名:",
"ui.download.text.sound_quality": "音质:",
"ui.download.text.file_exists": "下载失败(悲已存在名为_filename_的文件...",
"ui.download.text.download_lyrics_success": "已补充下载该歌曲的歌词!",
"ui.download.text.download_success": "_singer_的_music_下载成功~",
"ui.download.text.download_fail_no_keys": "请先输入歌名再下载吧!!!∑(゚Д゚ノ)",
"ui.download.text.download_fail_no_choice": "请先选择歌曲再下载吧!!!∑(゚Д゚ノ)",
"ui.download.text.download_fail_no_permission": "暂无权限哦罒ω罒!!!请尝试更改下载目录\n或重启程序吧",
"ui.download.text.download_fail_no_network": "连接服务器失败 (>_<)!!! 请检查网络或稍后再试吧",
"ui.download.text.download_fail_file_not_found": "下载目录不存在哦!罒ω罒!!!∑(゚Д゚ノ)",
"ui.download.text.search_fail_not_found": "抱歉暂无版权哦 (*_*)!!! 切换音质再试试吧",
"ui.download.button.search": "搜索",
"ui.download.entry.song_name": "输入你想搜的...( ̄▽ ̄)/",
"ui.download.treeview.song": "歌名",
"ui.download.treeview.artist": "歌手",
"ui.download.treeview.album": "专辑",
"ui.settings.text.theme": "主题",
"ui.settings.text.download_source": "下载源:",
"ui.settings.text.download_position": "下载目录:",
"ui.settings.text.auto_update": "自动更新:",
"ui.settings.text.language": "语言:",
"ui.settings.button.check_update": "检测更新",
"ui.settings.check_button.auto_update": "勾选后将会自动更新程序新版本",
"ui.settings.button.auto_play": "自动播放:",
"ui.settings.check_button.auto_play": "勾选后将会自动播放下一首歌",
"ui.about.text.information": "应用版本:_version_\n函数编写:NFL_jiancx\nGUI设计:AetherialCrane\n源码维护:NFL_jiancx\n问题测试与修复:AetherialCrane\n所属工作室:NFL工作室\n歌曲来源QQ,酷我,酷狗,网易云音乐\n请勿将从NFLmusic中下载的\n音频文件用于商业或盈利\n\n本应用遵循CC BY-NC-ND协议\n允许公开与传播,侵权必究!",
"ui.about.text.announcement": "公告:_announcement_",
"ui.about.text.starting_poem": [
"站在珠穆朗玛峰之巅,你未曾见过的——那最遥远的距离,并非光年之外, 而是网络未连接!",
"月亮下的对白,单纯的像小孩,你有好几次问我那是什么?这就是——没联网~",
"这个世界是什么模样?连接了网络才能揭晓~",
"原来连接了网络才能淹没了脆弱,你发誓更勇敢一生与梦相拥!",
"奔跑吧,骄傲的少年。年轻的心里面,是未联网的信念!",
"“网络是人类进步的阶梯”——NFL_jiancx",
"未知的读者,你好,当你看到这封信时,网络或许已经不在了...",
"互联网真是全世界最便捷的东西,可惜呀可惜,你没有...",
"如果你不想联网的话把NFLmusic作为一个播放器也可以~"
],
"ui.about.button.do_not_click": "千万别点",
"ui.playing.text.time_format": "正在播放_music_ %n/%a",
"ui.thanks.text.music_url": "音乐直链:",
"ui.thanks.text.random_poem": "随机诗句:",
"ui.thanks.text.file_store": "文件托管:",
"ui.thanks.text.bug_fix": "问题修复:",
"ui.thanks.text.sponsorship": "赞助我们:",
"ui.thanks.button.music_url": "星之阁API",
"ui.thanks.button.random_poem": "码云Gitee",
"ui.thanks.button.file_store": "云翼网盘",
"ui.thanks.button.bug_fix": "白鹤云中AetherialCrane",
"ui.thanks.button.sponsorship": "爱发电Afdian",
"ui.versions.text.current_version": "当前版本:_version_\nNFLmusic一路走来——\n从最初的“下载工具”到现在“功能兼备的APP”\n路上见证了无数风雨,见证了音乐界的兴衰...\nNFLmusic今后也会不断维护与开发并尽可能的提高用户体验~\n(在版本列表中,你可以选择双击版本编号以查看该版本的更新日志,右击列表以返回全版本日志)",
"ui.versions.treeview.version": "版本号",
"ui.versions.treeview.upload_time": "发布时间",
"ui.versions.treeview.update_brief": "更新简要",
"ui.update.text.download_update": "下载更新程序:",
"ui.update.text.download_app": "下载新版本:",
"ui.ads.jump_url": "访问广告主网站",
"ui.ads.close": "_time_秒后自动关闭广告"
}
#########################################################
en_us = {
"frame.song_list": "Song List",
"frame.download": "Download",
"frame.playing_settings": "Player Settings",
"frame.treasure_chest": "Treasure Chest",
"frame.about": "About",
"frame.update_log": "_version_Update Logs",
"frame.base_settings": "Settings",
"frame.thanks": "Thanks",
"frame.version_list": "Version List",
"menu.homepage": "Homepage",
"menu.settings": "Settings",
"menu.about": "About",
"menu.versions": "Version List",
"mbox.title.search_fail": "Search Failingly",
"mbox.title.delete": "Delete",
"mbox.title.delete_fail": "Delete Failingly(▼ヘ▼#)",
"mbox.title.play_fail": "Play Failingly(▼ヘ▼#)",
"mbox.title.network_connection_fail": "Network Error(╥╯^╰╥)",
"mbox.title.save_settings": "Save",
"mbox.title.position_not_exist": "Invalid Path",
"mbox.title.restart": "Tips",
"mbox.title.joke_warning": "Safety Warning!√(─皿─)√",
"mbox.title.joke_fail": "Your computer will explode!",
"mbox.title.joke0": "Window",
"mbox.title.update_reminding": "Update Reminding - v_version_",
"mbox.title.update_start": "Update - v_version_",
"mbox.title.update_fail": "Update Failed(〒︿〒)",
"mbox.title.download_web": "Approaching Download Page",
"mbox.title.copy_pwd": "Password Prompt",
"mbox.text.search_fail": "We couldn't find the results you were looking for(╯°Д°)╯︵┻━┻",
"mbox.text.delete": "Are you sure to delete this song?",
"mbox.text.delete_fail_no_target": "Please select the song you want to delete first(•́へ•́╬)",
"mbox.text.delete_fail_no_permission": "The source file is in use or does not have permissionヽ(#`Д´)ノ",
"mbox.text.delete_fail_not_found": "The source file does not exist(╯°Д°)╯",
"mbox.text.play_fail_no_target": "Please choose the song you want to listen to first(•́へ•́╬)",
"mbox.text.play_fail_not_found": "The source file does not exist or cannot be played temporarilyヽ(#`Д´)ノ",
"mbox.text.play_fail_unrecognized_format": "file _file_ is damaged or the format is not supported o(╥﹏╥)o",
"mbox.text.network_connection_fail": "Server connection failed╮(╯﹏╰)╭\nPlease check your network settings or try again later~",
"mbox.text.save_settings": "Do you want to save the settings?",
"mbox.text.position_not_exist": "The current directory does not exist, please reset it┓(;´_)┏",
"mbox.text.restart": "After changing the settings, the program needs to be restarted!",
"mbox.text.joke_warning": "NFLmusic will not take responsibility for the 'Do not click' button, are you sure to continue?",
"mbox.text.joke_fail": "Goodbye, NFL_jiancx is very afraid of blowing up your computer card",
"mbox.text.joke0": "This is a window",
"mbox.text.update_reminding": "Detected a new version, would you like to update it?\n\n_update_",
"mbox.text.update_latest": "The current version is already the latest version(。◕ˇ∀ˇ◕)",
"mbox.text.update_fail": "Please check the network status or try again later╮(╯﹏╰)╭",
"mbox.text.update_start_auto": "We have detected a new version and will update it for you soon!\n\n_update_",
"mbox.text.download_web": "Do you want to enter_url_?",
"mbox.text.copy_pwd": "File password:_pwd_, I have copied it to the clipboard for you!",
"ui.download.text.song_name": "Song Title:",
"ui.download.text.sound_quality": "Song Quality:",
"ui.download.text.file_exists": "Download failed (sadly, there is already a file named '_filename_'...",
"ui.download.text.download_lyrics_success": "The lyrics of the song have been added and downloaded!",
"ui.download.text.download_success": "_singer_'s_music_download successful~",
"ui.download.text.download_fail_no_keys": "Please enter the song name before downloading!!!∑(゚Д゚ノ)",
"ui.download.text.download_fail_no_choice": "Please select a song before downloading!!!∑(゚Д゚ノ)",
"ui.download.text.download_fail_no_permission": "No permission at the moment罒ω罒!!!Please try changing the download directory \nor restarting the program",
"ui.download.text.download_fail_no_network": "Failed to connect to server (>_<)!!! Please check the network or try again later",
"ui.download.text.download_fail_file_not_found": "The download directory does not exist!罒ω罒!!!∑(゚Д゚ノ)",
"ui.download.text.search_fail_not_found": "Sorry, there is currently no copyright available (* _ *)!!! Switch the sound quality and try again",
"ui.download.button.search": "search",
"ui.download.entry.song_name": "Enter what you want to search for...( ̄▽ ̄)/",
"ui.download.treeview.song": "Song Title",
"ui.download.treeview.artist": "Singer",
"ui.download.treeview.album": "Album",
"ui.settings.text.theme": "Theme",
"ui.settings.text.download_source": "Download Source:",
"ui.settings.text.download_position": "Download Catalog:",
"ui.settings.text.auto_update": "Automatic Update:",
"ui.settings.text.language": "language:",
"ui.settings.button.check_update": "Detect Updates",
"ui.settings.check_button.auto_update": "Once checked, the program will automatically update to a new version",
"ui.settings.button.auto_play": "Automatic Play:",
"ui.settings.check_button.auto_play": "Once checked, the next song will automatically play",
"ui.about.text.information": "Application Version:_version_\nFunction Writing:NFL_jiancx\nGUI Design:AetherialCrane\nSource code Maintenance:NFL_jiancx\nProblem testing and Repair:AetherialCrane\nBelonging Studio:NFL Studios\nThe song originates from QQ,Kuwo,Kugou,Netease_Cloud music\nDo not use audio files downloaded from\nNFLmusic for commercial or profit purposes\n\nThis application follows the CC BY-NC-ND protocol\nPublic disclosure and dissemination are allowed, and infringement will be prosecuted!",
"ui.about.text.announcement": "Announcement:_announcement_",
"ui.about.text.starting_poem": [
"Standing at the top of Mount Everest, the farthest distance you have never seen - not light years away, but an unconnected network!",
"The dialogue under the moon, pure like a child, you have asked me several times what it is? This is - no internet connection~",
"What does this world look like? Only when connected to the network can it be revealed~",
"It turns out that only by connecting to the internet can we drown out vulnerability. You swear to be braver and embrace your dreams for the rest of your life!",
"Run, proud young man. In the hearts of young people, there are beliefs that are not connected to the internet!",
"'The internet is the ladder of human progress' - NFL_jiancx",
"Hello unknown reader, by the time you read this letter, the internet may no longer be available...",
"The Internet is the most convenient thing in the world. It's a pity that you don't have...",
"If you don't want to connect to the internet, NFLmusic can also be used as a player~"
],
"ui.about.button.do_not_click": "do not click",
"ui.playing.text.time_format": "Playing _music_ %n/%a",
"ui.thanks.text.music_url": "Music Direct Link:",
"ui.thanks.text.random_poem": "Random Verses:",
"ui.thanks.text.file_store": "File Hosting:",
"ui.thanks.text.bug_fix": "Problem Fix:",
"ui.thanks.text.sponsorship": "Sponsor Us:",
"ui.thanks.button.music_url": "xingzhige API",
"ui.thanks.button.random_poem": "Code Cloud Gitee",
"ui.thanks.button.file_store": "Yunyi Cloud Drive",
"ui.thanks.button.bug_fix": "白鹤云中AetherialCrane",
"ui.thanks.button.sponsorship": "爱发电Afdian",
"ui.versions.text.current_version": "Current Version:_version_\nNFLmusic have walked all the way——\nFrom the initial 'download tool' to the current 'multi-functional app'\nWitnessed countless storms on the road, witnessed the rise and fall of the music industry\nNFLmusic will continue to maintain and develop in the future, and strive to improve user experience as much as possible~\n(In the version list, you can choose to double-click the version number to view the update logs for that version, or right-click the list to return the full version logs)",
"ui.versions.treeview.version": "Version Number",
"ui.versions.treeview.upload_time": "Release Time",
"ui.versions.treeview.update_brief": "Update Brief",
"ui.update.text.download_update": "Download the update program:",
"ui.update.text.download_app": "Download the new version:",
"ui.ads.jump_url": "Visit the advertiser's website",
"ui.ads.close": "Automatically close ads after _time_ seconds"
}

21
nflmusic/label_button.py Normal file
View File

@ -0,0 +1,21 @@
from tkinter import Label, ttk
Button = ttk.Button
Label = ttk.Label
class LabelButton:
def __init__(self, pack_box, label, button, command):
self.pack_box = pack_box
self.label_text = label
self.button_text = button
self.click_event = command
self.button = Button(self.pack_box, text=self.button_text, command=command, style='info.Link.TButton')
self.label = Label(self.pack_box, text=self.label_text)
def place(self, button, label):
self.button.place(x=button[0], y=button[1])
self.label.place(x=label[0], y=label[1])
def place_forget(self):
self.button.place_forget()
self.label.place_forget()

253
nflmusic/lang_test.py Normal file
View File

@ -0,0 +1,253 @@
import json
zh_cn = {
'frame.song_list': '歌曲列表',
'frame.download': '下载音乐',
'frame.playing_settings': '歌曲设置',
'frame.treasure_chest': '百宝箱',
'frame.about': '关于',
'frame.update_log': '_version_更新日志',
'frame.base_settings': '基本设置',
'frame.thanks': '鸣谢',
'frame.version_list': '版本列表',
'menu.homepage': '首页',
'menu.settings': '设置',
'menu.about': '关于',
'menu.versions': '开发版本',
'mbox.title.search_fail': '搜索失败',
'mbox.title.delete': '删除',
'mbox.title.delete_fail': '删除失败(▼ヘ▼#)',
'mbox.title.play_fail': '播放失败(▼ヘ▼#)',
'mbox.title.network_connection_fail': '联网失败(╥╯^╰╥)',
'mbox.title.save_settings': '保存设置',
'mbox.title.position_not_exist': '无效的目录',
'mbox.title.restart': '提示',
'mbox.title.joke_warning': '安全警告√(─皿─)√',
'mbox.title.joke_fail': '你的电脑可能会爆炸!',
'mbox.title.joke0': '窗口',
'mbox.title.update_reminding': '更新提示 - v_version_',
'mbox.title.update_start': '更新 - v_version_',
'mbox.title.download_web': '即将进入下载页面',
'mbox.title.copy_pwd': '密码提示',
'mbox.text.search_fail': '没有搜索到你想要的结果~(╯°Д°)╯︵┻━┻',
'mbox.text.delete': '确定删除这首歌曲吗?',
'mbox.text.delete_fail_no_target': '请先选择你要删除的歌吧(•́へ•́╬)',
'mbox.text.delete_fail_no_permission': '源文件正在使用或无权限ヽ(#`Д´)ノ',
'mbox.text.delete_fail_not_found': '源文件不存在(╯°Д°)╯',
'mbox.text.play_fail_no_target': '请先选择你要听的歌吧(•́へ•́╬)',
'mbox.text.play_fail_not_found': '源文件不存在或暂时无法播放ヽ(#`Д´)ノ',
'mbox.text.network_connection_fail': '服务器连接失败╮(╯﹏╰)╭\n请检查网络设置或稍后再试吧~',
'mbox.text.save_settings': '是否保存设置?',
'mbox.text.position_not_exist': '当前目录不存在,请重新设置吧┓(;´_)┏',
'mbox.text.restart': '更改设置后需要重新启动程序!',
'mbox.text.joke_warning': 'NFLmusic不会受责任于任何千万别点按钮,确定继续吗?',
'mbox.text.joke_fail': '别了NFL_jiancx十分害怕把你的电脑卡炸',
'mbox.text.joke0': '这是一个窗口',
'mbox.text.update_reminding': '检测到新版本,是否更新?\n\n_update_',
'mbox.text.update_latest': '当前已是最新版本(。◕ˇ∀ˇ◕)',
'mbox.text.update_start_auto': '检测到新版本,即将为您更新!\n\n_update_',
'mbox.text.download_web': '是否进入_url_',
'mbox.text.copy_pwd': '文件密码:_pwd_已帮您复制到剪贴板',
'ui.download.text.song_name': '歌名:',
'ui.download.text.sound_quality': '音质:',
'ui.download.text.file_exists': '下载失败(悲已存在名为_filename_的文件...',
'ui.download.text.download_lyrics_success': '已补充下载该歌曲的歌词!',
'ui.download.text.download_success': '_singer_的_music_下载成功~',
'ui.download.text.download_fail_no_keys': '请先输入歌名再下载吧!!!∑(゚Д゚ノ)',
'ui.download.text.download_fail_no_choice': '请先选择歌曲再下载吧!!!∑(゚Д゚ノ)',
'ui.download.text.download_fail_no_permission': '暂无权限哦罒ω罒!!!请尝试更改下载目录\n或重启程序吧',
'ui.download.text.download_fail_no_network': '连接服务器失败 (>_<)!!! 请检查网络或稍后再试吧',
'ui.download.text.download_fail_file_not_found': '下载目录不存在哦!罒ω罒!!!∑(゚Д゚ノ)',
'ui.download.text.search_fail_not_found': '抱歉没有找到该歌曲哦 (*_*)!!! 换一首吧',
'ui.download.button.search': '搜索',
'ui.download.entry.song_name': '输入你想搜的...( ̄▽ ̄)/',
'ui.download.treeview.song': '歌名',
'ui.download.treeview.artist': '歌手',
"ui.download.treeview.album": '专辑',
'ui.settings.text.theme': '主题',
'ui.settings.text.download_source': '下载源:',
'ui.settings.text.download_position': '下载目录:',
'ui.settings.text.auto_update': '自动更新:',
'ui.settings.text.language': '语言:',
'ui.settings.button.check_update': '检测更新',
'ui.settings.check_button.auto_update': '勾选后将会自动更新程序新版本',
'ui.about.text.information': '应用版本:_version_\n'
'函数编写:NFL_jiancx\n'
'GUI设计:AetherialCrane\n'
'源码维护:NFL_jiancx\n'
'问题测试与修复:AetherialCrane\n'
'所属工作室:NFL工作室\n'
'歌曲来源QQ,酷我,酷狗,网易云音乐\n'
'请勿将从NFLmusic中下载的\n'
'音频文件用于商业或盈利\n\n'
'本应用遵循CC BY-NC-ND协议\n'
'允许公开与传播,侵权必究!',
'ui.about.text.announcement': '公告:_announcement_',
'ui.about.text.starting_poem': [
'站在珠穆朗玛峰之巅,你未曾见过的——那最遥远的距离,并非光年之外, 而是网络未连接!',
'月亮下的对白,单纯的像小孩,你有好几次问我那是什么?这就是——没联网~',
'这个世界是什么模样?连接了网络才能揭晓~',
'原来连接了网络才能淹没了脆弱,你发誓更勇敢一生与梦相拥!',
'奔跑吧,骄傲的少年。年轻的心里面,是未联网的信念!',
'“网络是人类进步的阶梯”——NFL_jiancx',
'未知的读者,你好,当你看到这封信时,网络或许已经不在了...',
'互联网真是全世界最便捷的东西,可惜呀可惜,你没有...',
'如果你不想联网的话把NFLmusic作为一个播放器也可以~'
],
'ui.about.button.do_not_click': '千万别点',
'ui.playing.text.time_format': '正在播放_music_ %n/%a',
'ui.thanks.text.music_url': '音乐直链:',
'ui.thanks.text.random_poem': '随机诗句:',
'ui.thanks.text.file_store': '文件托管:',
'ui.thanks.text.bug_fix': '问题修复:',
'ui.thanks.text.sponsorship': '赞助我们:',
'ui.thanks.button.music_url': '星之阁API',
'ui.thanks.button.random_poem': '码云Gitee',
'ui.thanks.button.file_store': '蓝奏云LanZou',
'ui.thanks.button.bug_fix': '白鹤云中AetherialCrane',
'ui.thanks.button.sponsorship': '爱发电Afdian',
'ui.versions.text.current_version': '当前版本:_version_\n'
'NFLmusic一路走来——\n'
'从最初的“下载工具”到现在“功能兼备的APP”\n'
'路上见证了无数风雨,见证了音乐界的兴衰...\n'
'NFLmusic今后也会不断维护与开发并尽可能的提高用户体验~\n'
'(在版本列表中,你可以选择双击版本编号以查看该版本的更新日志,右击列表以返回全版本日志)',
'ui.versions.treeview.version': '版本号',
'ui.versions.treeview.upload_time': '发布时间',
'ui.versions.treeview.update_brief': '更新简要',
'ui.update.text.download_update': '下载更新程序:',
'ui.update.text.download_app': '下载新版本:'
}
en_us = {
'frame.song_list': '歌曲列表',
'frame.download': '下载音乐',
'frame.playing_settings': '歌曲设置',
'frame.treasure_chest': '百宝箱',
'frame.about': '关于',
'frame.update_log': '_version_更新日志',
'frame.base_settings': '基本设置',
'frame.thanks': '鸣谢',
'frame.version_list': '版本列表',
'menu.homepage': '首页',
'menu.settings': '设置',
'menu.about': '关于',
'menu.versions': '开发版本',
'mbox.title.search_fail': '搜索失败',
'mbox.title.delete': '删除',
'mbox.title.delete_fail': '删除失败(▼ヘ▼#)',
'mbox.title.play_fail': '播放失败(▼ヘ▼#)',
'mbox.title.network_connection_fail': '联网失败(╥╯^╰╥)',
'mbox.title.save_settings': '保存设置',
'mbox.title.position_not_exist': '无效的目录',
'mbox.title.restart': '提示',
'mbox.title.joke_warning': '安全警告√(─皿─)√',
'mbox.title.joke_fail': '你的电脑可能会爆炸!',
'mbox.title.joke0': '窗口',
'mbox.title.update_reminding': '更新提示 - v_version_',
'mbox.title.update_start': '更新 - v_version_',
'mbox.title.download_web': '即将进入下载页面',
'mbox.title.copy_pwd': '密码提示',
'mbox.text.search_fail': '没有搜索到你想要的结果~(╯°Д°)╯︵┻━┻',
'mbox.text.delete': '确定删除这首歌曲吗?',
'mbox.text.delete_fail_no_target': '请先选择你要删除的歌吧(•́へ•́╬)',
'mbox.text.delete_fail_no_permission': '源文件正在使用或无权限ヽ(#`Д´)ノ',
'mbox.text.delete_fail_not_found': '源文件不存在(╯°Д°)╯',
'mbox.text.play_fail_no_target': '请先选择你要听的歌吧(•́へ•́╬)',
'mbox.text.play_fail_not_found': '源文件不存在或暂时无法播放ヽ(#`Д´)ノ',
'mbox.text.network_connection_fail': '服务器连接失败╮(╯﹏╰)╭\n请检查网络设置或稍后再试吧~',
'mbox.text.save_settings': '是否保存设置?',
'mbox.text.position_not_exist': '当前目录不存在,请重新设置吧┓(;´_)┏',
'mbox.text.restart': '更改设置后需要重新启动程序!',
'mbox.text.joke_warning': 'NFLmusic不会受责任于任何千万别点按钮,确定继续吗?',
'mbox.text.joke_fail': '别了NFL_jiancx十分害怕把你的电脑卡炸',
'mbox.text.joke0': '这是一个窗口',
'mbox.text.update_reminding': '检测到新版本,是否更新?\n\n_update_',
'mbox.text.update_latest': '当前已是最新版本(。◕ˇ∀ˇ◕)',
'mbox.text.update_start_auto': '检测到新版本,即将为您更新!\n\n_update_',
'mbox.text.download_web': '是否进入_url_',
'mbox.text.copy_pwd': '文件密码:_pwd_已帮您复制到剪贴板',
'ui.download.text.song_name': '歌名:',
'ui.download.text.sound_quality': '音质:',
'ui.download.text.file_exists': '下载失败(悲已存在名为_filename_的文件...',
'ui.download.text.download_lyrics_success': '已补充下载该歌曲的歌词!',
'ui.download.text.download_success': '_singer_的_music_下载成功~',
'ui.download.text.download_fail_no_keys': '请先输入歌名再下载吧!!!∑(゚Д゚ノ)',
'ui.download.text.download_fail_no_choice': '请先选择歌曲再下载吧!!!∑(゚Д゚ノ)',
'ui.download.text.download_fail_no_permission': '暂无权限哦罒ω罒!!!请尝试更改下载目录\n或重启程序吧',
'ui.download.text.download_fail_no_network': '连接服务器失败 (>_<)!!! 请检查网络或稍后再试吧',
'ui.download.text.download_fail_file_not_found': '下载目录不存在哦!罒ω罒!!!∑(゚Д゚ノ)',
'ui.download.text.search_fail_not_found': '抱歉没有找到该歌曲哦 (*_*)!!! 换一首吧',
'ui.download.button.search': '搜索',
'ui.download.entry.song_name': '输入你想搜的...( ̄▽ ̄)/',
'ui.download.treeview.song': '歌名',
'ui.download.treeview.artist': '歌手',
"ui.download.treeview.album": '专辑',
'ui.settings.text.theme': '主题',
'ui.settings.text.download_source': '下载源:',
'ui.settings.text.download_position': '下载目录:',
'ui.settings.text.auto_update': '自动更新:',
'ui.settings.text.language': '语言:',
'ui.settings.button.check_update': '检测更新',
'ui.settings.check_button.auto_update': '勾选后将会自动更新程序新版本',
'ui.about.text.information': '应用版本:_version_\n'
'函数编写:NFL_jiancx\n'
'GUI设计:AetherialCrane\n'
'源码维护:NFL_jiancx\n'
'问题测试与修复:AetherialCrane\n'
'所属工作室:NFL工作室\n'
'歌曲来源QQ,酷我,酷狗,网易云音乐\n'
'请勿将从NFLmusic中下载的\n'
'音频文件用于商业或盈利\n\n'
'本应用遵循CC BY-NC-ND协议\n'
'允许公开与传播,侵权必究!',
'ui.about.text.announcement': '公告:_announcement_',
'ui.about.text.starting_poem': [
'站在珠穆朗玛峰之巅,你未曾见过的——那最遥远的距离,并非光年之外, 而是网络未连接!',
'月亮下的对白,单纯的像小孩,你有好几次问我那是什么?这就是——没联网~',
'这个世界是什么模样?连接了网络才能揭晓~',
'原来连接了网络才能淹没了脆弱,你发誓更勇敢一生与梦相拥!',
'奔跑吧,骄傲的少年。年轻的心里面,是未联网的信念!',
'“网络是人类进步的阶梯”——NFL_jiancx',
'未知的读者,你好,当你看到这封信时,网络或许已经不在了...',
'互联网真是全世界最便捷的东西,可惜呀可惜,你没有...',
'如果你不想联网的话把NFLmusic作为一个播放器也可以~'
],
'ui.about.button.do_not_click': '千万别点',
'ui.playing.text.time_format': '正在播放_music_ %n/%a',
'ui.thanks.text.music_url': '音乐直链:',
'ui.thanks.text.random_poem': '随机诗句:',
'ui.thanks.text.file_store': '文件托管:',
'ui.thanks.text.bug_fix': '问题修复:',
'ui.thanks.text.sponsorship': '赞助我们:',
'ui.thanks.button.music_url': '星之阁API',
'ui.thanks.button.random_poem': '码云Gitee',
'ui.thanks.button.file_store': '蓝奏云LanZou',
'ui.thanks.button.bug_fix': '白鹤云中AetherialCrane',
'ui.thanks.button.sponsorship': '爱发电Afdian',
'ui.versions.text.current_version': '当前版本:_version_\n'
'NFLmusic一路走来——\n'
'从最初的“下载工具”到现在“功能兼备的APP”\n'
'路上见证了无数风雨,见证了音乐界的兴衰...\n'
'NFLmusic今后也会不断维护与开发并尽可能的提高用户体验~\n'
'(在版本列表中,你可以选择双击版本编号以查看该版本的更新日志,右击列表以返回全版本日志)',
'ui.versions.treeview.version': '版本号',
'ui.versions.treeview.upload_time': '发布时间',
'ui.versions.treeview.update_brief': '更新简要',
'ui.update.text.download_update': '下载更新程序:',
'ui.update.text.download_app': '下载新版本:'
}
print(json.dumps(zh_cn))
print("===========================")
print(json.dumps(en_us))

38
nflmusic/language.py Normal file
View File

@ -0,0 +1,38 @@
import os
import json
appdata = os.getenv("APPDATA")
def read_language():
with open(appdata + "/.NFLmusic/language/zh_cn.json", "r") as f:
zh_cn = json.loads(f.read())
with open(appdata + "/.NFLmusic/language/en_us.json", "r") as f:
en_us = json.loads(f.read())
language0 = {
"简体中文": zh_cn,
"English(US)": en_us
}
return language0
def get(lang, key, replace_word=None):
language0 = read_language()
if replace_word is None:
replace_word = {}
try:
if len(replace_word) == 0:
return language0[lang][key]
else:
replaced_language = language0[lang][key]
for word in replace_word.keys():
replaced_language = replaced_language.replace(word, replace_word[word])
except:
replaced_language = key
return replaced_language
def list_languages():
return read_language().keys()

29
nflmusic/load_gif.py Normal file
View File

@ -0,0 +1,29 @@
from itertools import count
from PIL import Image, ImageTk
def load_gif(gif_file):
"""Load GIF frames from the specified file."""
frames = []
try:
with Image.open(gif_file) as img:
for frame in count(1):
frames.append(ImageTk.PhotoImage(img.copy()))
img.seek(frame)
except EOFError:
pass
return frames
def show_animation(label, frames):
"""Display the animation on the specified label."""
def update_frame(frame_index):
if not getattr(label, 'stop_animation', False):
label.configure(image=frames[frame_index])
label.after(100, update_frame, (frame_index + 1) % len(frames))
update_frame(0)
def stop_animation(label):
"""Stop the animation."""
label.stop_animation = True

13
nflmusic/loading.py Normal file
View File

@ -0,0 +1,13 @@
from tkinter import Frame, ttk
class Loading:
def __init__(self, box, length, width):
self.box = box
self.frame = Frame(self.box, length=length, width=width)
self.progressbar = ttk.Progressbar(self.box, style="success.Striped.Horizontal.TProgressbar")
self.frame.place(x=0, y=0)
self.progressbar.place(relx=0.5, rely=0.8, anchor="center")
def set_progress(self, progress):
self.progressbar["value"] = progress

BIN
nflmusic/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

401
nflmusic/logs.py Normal file
View File

@ -0,0 +1,401 @@
text = {"简体中文": '''v3.9.3 - 2024.8.13
修复了程序更新后无法自动重启的问题
优化了界面切换动画的算法
v3.9.2 - 2024.7.19
修复了部分歌曲下载完成后重命名失败的问题
修复了未联网时程序主界面无法加载的问题
修复了用户数据无法取消保存的问题
优化了广告加载算法,使广告平均加载时间更短
新增了手动播放模式
v3.9.1 - 2024.7.15
修复了播放,暂停图片更替失败的问题
修复了部分用户”关于“界面白屏的问题
修复了歌曲文件损坏导致音乐信息获取出错的问题
v3.9.0 - 2024.7.11
修复了更新不稳定导致进度卡死问题
修复了歌词部分歌词下载失败导致无法下载歌曲的问题
优化了部分界面按钮及外观样式
新增了歌曲前后切换功能
新增了语言选择功能,目前支持中英切换
v3.8.9 - 2024.6.21
修复了滚动歌词未显示完会导致下一行歌词无法显示的问题
优化了歌词显示逻辑,滚动歌词速度现在会根据时间差进行调整
优化了应用启动的位置,现在默认启动在屏幕正中央了
增加了启动应用的动画
增加了切换页面的动画
v3.8.8 - 2024.6.19
修复了在音乐时长较长时,后期歌词不同步的问题
修复了在某些版本下无法正常更新的问题
优化了歌词的显示逻辑,现在歌词过长会以滚动方式显示
v3.8.7 - 2024.6.13
修复了在顺序、随机播放下,切换歌曲后歌词不切换的问题
优化了下载音乐、更新时的算法现在不会在这2种情况下发生严重卡顿了
调整了歌词的颜色、位置与字体
现在选中“酷狗音乐”下载源后下载同名文件会自动补充歌词了
放大了应用程序图标
v3.8.6 - 2024.6.12
修复了在下载列表中双击空位置会导致下载锁定的问题
调整了播放设置中组件的位置
调整了关于页面的组件,将“千万别点”调整到了此页面内
增加了“开发版本”页面,详情请自行查看
增加了歌词下载功能,目前仅支持酷狗音乐下载源
增加了歌词显示功能
v3.8.5 - 2024.6.11
优化了更新应用的算法,修复了历史遗留问题
更换了文件托管方
v3.8.4 - 2024.6.10
修改了应用程序图标
更换了“随机一言”的API
增加了公告显示功能,目前显示在关于页面
v3.8.3 - 2024.6.6
修复了未联网状态下无法启动程序的问题
修复了连续快速点击下载列表时进度条显示异常的问题
增加了更新开始时的更新内容显示
现在在搜索成功后若再次搜索时搜索对象未变,则不会再刷新下载列表
现在点击“检测更新”按钮后会直接禁用点击了
v3.8.2 - 2024.6.5
修复了音乐播放结束后进度条会停留在末尾的问题
修复了下载框中的提示不居中的问题
增加了更新进度条的下载文字提示
增加了鸣谢中的两个项目
增加了鸣谢中的赞助者列表
删除了停止按钮,取而代之的是播放模式按钮
现在双击播放列表中的文件可以直接进行播放了
现在聚焦搜索输入框时会将提示词清除了,同时当输入框中如果为空时,会附加提示词
现在歌曲列表只会捕获.mp3文件/.flac文件/.ogg文件/.m4a文件了
现在歌曲列表中不会显示文件后缀名称了
现在自动更新也会显示更新进度条了
现在播放歌曲名称也会显示在播放进度旁边了
v3.8.1 - 2024.6.4
优化了程序的算法,修复了上个版本中开启应用时会导致严重卡顿的问题
v3.8.0 - 2024.6.4
修复了“关于”中一处文本显示错误的问题
修复了歌曲列表中滚动条溢出外框的问题
大幅度修改UI界面
修改了下载文件的文件名
增加了下载列表中歌曲专辑的显示
增加了歌曲播放的进度条
删除了歌曲播放结束后会循环播放的设定
删除了下载按钮,现在可以直接通过双击列表项目进行下载
v3.7.9 - 2024.6.2
修复了暂停或停止音乐短时间后会重新播放的问题
修复了播放状态下未选中歌曲会无法暂停的问题
修复了未选中歌曲时播放会使停止按钮变为可用状态的问题
修复了未选中歌曲时播放会使播放按钮切换为暂停图标的问题
修复了浏览下载路径点击取消时会抹除当前路径的问题
修改了应用分发协议并调整了“关于”部分的文本
增加了播放时长的显示文本
增加了随机诗句每行的允许最大字符数
现在更新日志会优先显示最近的更新内容
现在系统只有在确保未联网状态下才会显示未联网诗句
现在随机诗句不会因为过长而导致被系统截断了
v3.7.8 - 2024.6.1
修复了成功下载歌曲后提示词显示问题
修复了更新日志在某些分辨率下组件溢出屏幕的问题
修复了在非主页页面也可以看到下载进度条的问题
修复了部分数据加载问题
修复了勾选自动更新后不会同步设置的问题
修改了下载文件的文件名
增加了音乐暂停功能
增加了检测更新功能
现在设置音乐下载目录时可以进行浏览了
现在在点击“千万别点!”后不能二次点击触发了
优化了音乐加载算法
v3.6.7 - 2024.5.14
大幅度修改UI界面
修改设置项“更新方式”至“自动更新”
增加了未联网时的诗词提示
增加了五个彩蛋
翻译了主题文本
更改了窗口图标
v3.6.6 - 2024.5.1
优化图形界面
提升操作体验
更改部分外观
v3.6.5 - 2024.4.24
修复已知问题
修复部分界面无法正常显示的问题
新增更新设置
v3.6.4 - 2024.4.11
调整部分UI
优化运行性能
修复已知问题
v3.6.3 - 2024.3.31
新增文件删除功能
美化部分按钮外观
优化随机诗句加载
v3.6.2 - 2024.3.15
修复搜索函数搜索失败问题
修复主题参数读取异常
优化搜索函数
v3.6.1 - 2024.3.1
整合下载源
优化数据格式
v3.6.0 - 2023.12.31
修复音质参数错误问题
v3.5.2 - 2023.12.14
更换下载源
修复已知问题
v3.5.1 - 2023.12.2
更新下载进度条
修复搜索函数阻塞问题
v3.1.5 - 2023.11.13
修复未联网时二次弹窗问题
修复参数错误导致下载失败的问题
v3.1.0 - 2023.10.31
修复了大部分已知问题
优化搜索函数
增加了更新日志
v3.0.0 - 2023.10.4
大幅度更新了UI组件
v2.4.1 - 2023.9.16
大幅度更改函数并添加了大量组件
v2.2.3 - 2023.7.29
音质可自由选择
下载格式优化
v2.0.0 - 2023.6.29
新增播放与停止功能
v1.9.2 - 2023.5.19
更新了UI组件
v1.5.7 - 2023.3.22
歌曲可选择索引
v1.2.7 - 2023.1.8
第一个正式版出现
''',
"English(US)": '''v3.9.3 - 2024.8.13
Fixed the issue where the program could not automatically restart after being updated
Optimized the algorithm for interface switching animation
v3.9.2 - 2024.7.19
Fixed the issue of renaming failure after downloading some songs
Fixed the issue where the main interface of the program could not be loaded when not connected to the internet
Fixed the issue where user data could not be cancelled for saving
Optimized the ad loading algorithm to shorten the average ad loading time
Added manual playback mode
v3.9.1 - 2024.7.15
Fixed the issue of failed playback and pause image replacement
Fixed the issue of "white screen interface" for some users
Fixed the issue of music information retrieval errors caused by damaged song files
v3.9.0 - 2024.7.11
Fixed the issue of progress freezing caused by unstable updates
Fixed the issue where some lyrics failed to download, resulting in the inability to download songs
Optimized some interface buttons and appearance styles
Added the function of switching songs before and after
Added language selection function, currently supports switching between Chinese and English
v3.8.9 - 2024.6.21
Fixed the issue where scrolling lyrics were not fully displayed, causing the next line of lyrics to not be displayed
Optimized lyrics display logic, scrolling lyrics speed now adjusts based on time difference
Optimized the location of application startup, now it defaults to the center of the screen
Added animation for launching applications
Added animation for switching pages
v3.8.8 - 2024.6.19
Fixed the issue of unsynchronized lyrics in the later stage when the music duration is long
Fixed the issue of not being able to update properly in certain versions
Optimized the display logic of lyrics, now lyrics that are too long will be displayed in a scrolling manner
v3.8.7 - 2024.6.13
Fixed the issue where lyrics did not switch after switching songs in sequential or random playback
Optimized the algorithm for downloading music and updating, and now there will be no severe lag in these two situations
Adjusted the color, position, and font of the lyrics
After selecting the download source of 'Kugou Music', downloading the file with the same name will automatically add lyrics
Enlarged the application icon
v3.8.6 - 2024.6.12
Fixed the issue where double clicking an empty position in the download list would cause the download to lock
Adjusted the position of components in the playback settings
Adjusted the components related to the page and moved the 'Do Not Click' button to this page
Added a "Development Version" page, please check the details yourself
Added lyrics download function, currently only supports KuGou music download source
Added lyrics display function
v3.8.5 - 2024.6.11
Optimized the algorithm for updating applications and fixed historical legacy issues
Replaced the file hosting provider
v3.8.4 - 2024.6.10
Modified the application icon
Replaced the API for 'Random Word'
Added announcement display function, currently displayed on the About page
v3.8.3 - 2024.6.6
Fixed the issue of not being able to start programs when not connected to the internet
Fixed the issue where the progress bar displayed abnormally when clicking on the download list continuously and quickly
Added display of update content at the beginning of the update
If the search object remains unchanged when searching again after a successful search, the download list will not be refreshed
Now clicking the 'detect updates' button will directly disable clicking
v3.8.2 - 2024.6.5
Fixed the issue where the progress bar would stay at the end of the music playback
Fixed the issue of the prompt not being centered in the download box
Added download text prompt for update progress bar
Added two items in the acknowledgements
Added a list of sponsors in the acknowledgements section
Removed the stop button and replaced it with a play mode button
Now double clicking on a file in the playlist allows for direct playback
When focusing on the search input box now, the prompt words will be cleared, and if the input box is empty, prompt words will be attached
Now the song list only captures. mp3 files/. flac files/. ogg files/. m4a files
The file suffix names will no longer be displayed in the song list
Now automatic updates will also display an update progress bar
Now the song name will also be displayed next to the playback progress when playing
v3.8.1 - 2024.6.4
Optimized the algorithm of the program and fixed the issue of severe lag when opening the application in the previous version
v3.8.0 - 2024.6.4
Fixed an issue with a text display error in 'About'
Fixed the issue of the scrollbar overflowing the outer frame in the song list
Significantly modify the UI interface
Changed the file name of the downloaded file
Added display of song albums in the download list
Added progress bar for song playback
Removed the setting that the song will loop after playback ends
The download button has been removed, and now you can download directly by double clicking on the list item
v3.7.9 - 2024.6.2
Fixed the issue of music replaying after pausing or stopping for a short period of time
Fixed the issue where unselected songs could not pause while playing
Fixed the issue where playing an unselected song would make the stop button available
Fixed the issue where playing an unselected song would cause the play button to switch to a pause icon
Fixed the issue where clicking cancel while browsing the download path would erase the current path
Modified the application distribution protocol and adjusted the text in the "About" section
Display text with increased playback duration
Added the maximum allowed number of characters per line for random poetic lines
The update log now prioritizes displaying the latest updates
Currently, the system only displays unconnected poetry when it is ensured to be in an unconnected state
Now random poetry lines will not be truncated by the system due to being too long
v3.7.8 - 2024.6.1
Fixed the issue of displaying prompt words after successfully downloading songs
Fixed the issue of component overflow screen in update logs at certain resolutions
Fixed the issue where the download progress bar could also be seen on non home pages
Fixed some data loading issues
Fixed the issue of not synchronizing settings after selecting automatic updates
Changed the file name of the downloaded file
Added music pause function
Added detection and update function
Now you can browse when setting the music download directory
Now, after clicking 'Don't click!', it cannot be triggered by clicking again
Optimized music loading algorithm
v3.6.7 - 2024.5.14
Significantly modify the UI interface
Change the setting item 'update method' to 'automatic update'
Added poetry prompts when not connected to the internet
Added five Easter eggs
Translated the theme text
Changed the window icon
v3.6.6 - 2024.5.1
Optimize the graphical interface
Improve operational experience
Change some appearance
v3.6.5 - 2024.4.24
Fix known issues
Fix the issue of some interfaces not displaying properly
Add update settings
v3.6.4 - 2024.4.11
Adjust some UI
Optimize operational performance
Fix known issues
v3.6.3 - 2024.3.31
Add file deletion function
Beautify the appearance of some buttons
Optimize random poetry loading
v3.6.2 - 2024.3.15
Fix search function search failure issue
Fix abnormal reading of theme parameters
Optimize search function
v3.6.1 - 2024.3.1
整合下载源
优化数据格式
v3.6.0 - 2023.12.31
Fix the issue of incorrect sound quality parameters
v3.5.2 - 2023.12.14
更换下载源
修复已知问题
v3.5.1 - 2023.12.2
Update download progress bar
Fix search function blocking issue
v3.1.5 - 2023.11.13
Fix the issue of secondary pop ups when not connected to the internet
Fix the issue of download failure caused by parameter errors
v3.1.0 - 2023.10.31
Fixed most of the known issues
Optimize search function
Added update logs
v3.0.0 - 2023.10.4
Significantly updated UI components
v2.4.1 - 2023.9.16
Significant changes were made to the function and a large number of components were added
v2.2.3 - 2023.7.29
The sound quality can be freely selected
Download format optimization
v2.0.0 - 2023.6.29
Add play and stop functions
v1.9.2 - 2023.5.19
Updated UI components
v1.5.7 - 2023.3.22
Song selectable index
v1.2.7 - 2023.1.8
The first official version appears
'''
}
def get(lang):
return text[lang]

29
nflmusic/lyrics.py Normal file
View File

@ -0,0 +1,29 @@
import re
def load_lyrics(file):
with open(file, 'r', encoding='utf-8') as file:
lines = file.readlines()
lyrics = {}
for line in lines:
match = re.match(r'\[(\d+):(\d+\.\d+)\](.*)', line)
if match:
minutes = int(match.group(1))
seconds = int(float(match.group(2)))
timestamp = f'{minutes:02}:{seconds:02}'
text = match.group(3)
lyrics[timestamp] = text
return lyrics
def get_lyrics(lyrics, time):
try:
lyric = lyrics[time]
return lyric
except:
pass
if __name__ == '__main__':
print(load_lyrics("C:/Users/admin/Desktop/NFLmusic/3.8.8/music/王菲 - 匆匆那年.lrc"))

56
nflmusic/make_image.py Normal file

File diff suppressed because one or more lines are too long

25
nflmusic/obfuscation.py Normal file
View File

@ -0,0 +1,25 @@
import hashlib
import json
def hash_filename(filename):
hash_object = hashlib.sha256(filename.encode())
hex_dig = hash_object.hexdigest()
return hex_dig
if __name__ == "__main__":
hashed_files = {}
while True:
string_input = input("请输入字符串(输入'退出'退出循环):")
if string_input == "退出":
break
hashed_name = hash_filename(string_input)
hashed_files[string_input] = hashed_name
json_filename = input("请输入要保存的 JSON 文件名:")
with open(json_filename, 'w') as json_file:
json.dump(hashed_files, json_file)
print(f"JSON 文件已保存为 {json_filename}")

181
nflmusic/player.py Normal file
View File

@ -0,0 +1,181 @@
import tkinter
import pygame
import time
import re
from tkinter import ttk
class MusicPlayer:
def __init__(self, cls_root):
# 初始化变量
self.root = cls_root
self.progress_bar = None
self.play_button = None
self.pause_button = None
self.music_file = None
self.music_length = 0
self.time = None
self.time_format = "%n/%a"
self.pause = True
self.progress = []
self.length = []
self.finish = True
self.d_value = 0.0
# 初始化 Pygame
pygame.init()
# 初始化上次更新的时间
self.last_update_time = time.time()
# 开始更新进度条
self.current_position = 0.0 # 用于跟踪当前音乐播放的位置
self.update_progress()
def load_music(self, music_file):
self.music_file = music_file
self.music_length = pygame.mixer.Sound(self.music_file).get_length() # 获取音乐长度
pygame.mixer.music.load(self.music_file)
def bind(self, cls_progress_bar=None, cls_pause_button=None, cls_play_button=None, cls_time=None):
# 绑定控件
self.progress_bar = cls_progress_bar
self.pause_button = cls_pause_button
self.play_button = cls_play_button
self.time = cls_time
def play_music(self, music_file):
self.finish = False
self.load_music(music_file)
self.d_value = 0.0
pygame.mixer.music.play()
self.pause = False
self.current_position = 0.0
if self.progress_bar is not None:
self.progress_bar["from_"] = 0
self.progress_bar["to"] = float(self.music_length)
self.progress_bar.set(0)
def stop_music(self):
pygame.mixer.music.stop()
self.music_file = None
self.finish = True
self.pause = True
self.current_position = 0.0
self.music_length = 0
if self.time is not None:
self.time["text"] = ""
if self.progress_bar is not None:
self.progress_bar["from_"] = 0
self.progress_bar["to"] = 1
self.progress_bar.set(0)
def pause_music(self):
try:
if not self.finish:
if self.pause:
pygame.mixer.music.unpause()
self.pause = False
else:
pygame.mixer.music.pause()
self.pause = True
except:
self.play_music()
def set_progress(self, value):
if not self.finish:
# 检查是否距离上次更新超过0.55秒
if abs(float(value) - self.last_update_time) > 0.55:
# 将进度条的值直接设置为音乐的播放位置
self.current_position = float(value)
self.d_value = float(value) - pygame.mixer.music.get_pos() / 1000
try:
pygame.mixer.music.set_pos(float(value))
except:
self.stop_music()
def update_progress(self):
self.current_position = pygame.mixer.music.get_pos() / 1000 + self.d_value
if not self.pause:
if self.music_file is not None:
if self.progress_bar is not None:
# 更新进度条
self.progress_bar.set(self.current_position)
self.last_update_time = self.progress_bar.get()
# 更新播放时长
if self.time is not None:
self.time["text"] = self.time_format.replace("%n", self.get_progress()).replace("%a",
self.get_length())
# 每隔一段时间再次更新进度条
self.root.after(500, self.update_progress)
def get_busy(self):
return not self.pause
def get_progress(self, state="%m:%s"):
self.progress = self.get_format(int(self.current_position))
if len(self.progress[0]) == 1:
self.progress[0] = "0" + self.progress[0]
if len(self.progress[1]) == 1:
self.progress[1] = "0" + self.progress[1]
if len(self.progress[2]) == 1:
self.progress[2] = "0" + self.progress[2]
return_value = state.replace("%s", self.progress[0])
return_value = return_value.replace("%m", self.progress[1])
return_value = return_value.replace("%h", self.progress[2])
return return_value
@staticmethod
def get_format(value):
second = value % 60
minute = value // 60 % 60
hour = value // 3600
return [str(second), str(minute), str(hour)]
@staticmethod
def decode_format(value):
match = re.match(r'(\d+):(\d)', value)
if match:
minute = int(match.group(1))
second = int(match.group(2))
timestamp = minute * 60 + second
return timestamp
else:
return None
def get_length(self, state="%m:%s"):
self.length = self.get_format(int(self.music_length))
if len(self.length[0]) == 1:
self.length[0] = "0" + self.length[0]
if len(self.length[1]) == 1:
self.length[1] = "0" + self.length[1]
if len(self.length[2]) == 1:
self.length[2] = "0" + self.length[2]
return_value = state.replace("%s", self.length[0])
return_value = return_value.replace("%m", self.length[1])
return_value = return_value.replace("%h", self.length[2])
return return_value
def set_format_of_time(self, cls_format="%n/%a"):
self.time_format = cls_format
def get_finished(self):
return self.finish
if __name__ == "__main__":
root = tkinter.Tk()
player = MusicPlayer(root)
root.title("音乐播放器")
progress_bar = ttk.Scale(root, orient="horizontal", from_=0, to=player.music_length, length=2000)
progress_bar.pack()
pause_button = ttk.Button(root, text="暂停", command=player.pause_music)
play_button = ttk.Button(root, text="播放", command=lambda: player.play_music("your_music_file.mp3"))
stop_button = ttk.Button(root, text="停止", command=player.stop_music)
pause_button.pack()
play_button.pack()
stop_button.pack()
progress_time = ttk.Label(root, text="")
progress_time.pack()
progress_bar["command"] = lambda event: player.set_progress(progress_bar.get())
player.bind(progress_bar, pause_button, play_button, progress_time)
player.set_format_of_time()
root.mainloop()

39
nflmusic/test.py Normal file
View File

@ -0,0 +1,39 @@
import tkinter as tk
from itertools import count
from PIL import Image, ImageTk
class AnimatedGIF(tk.Label):
def __init__(self, root, gif_file, *args, **kwargs):
tk.Label.__init__(self, root, *args, **kwargs)
self.root = root
self.gif_file = gif_file
self.frames = []
self.load_gif()
def load_gif(self):
"""Load the GIF frames."""
try:
with Image.open(self.gif_file) as img:
for frame in count(1):
self.frames.append(ImageTk.PhotoImage(img.copy()))
img.seek(frame)
except EOFError:
pass
self.show_animation()
def show_animation(self):
"""Display the animation."""
def update_frame(frame_index):
self.configure(image=self.frames[frame_index])
self.root.after(100, update_frame, (frame_index + 1) % len(self.frames))
update_frame(0)
if __name__ == "__main__":
root = tk.Tk()
gif_label = AnimatedGIF(root, r"C:\Users\Administrator.DESKTOP-0DNOS3E\AppData\Roaming\.NFLmusic\resource\images\loading.gif")
gif_label.pack()
root.mainloop()

View File

@ -0,0 +1,60 @@
themename = {
"简体中文": {
"颗粒": "alt",
"白云": "yeti",
"冷静": "superhero",
"黑夜": "darkly",
"光泽": "xpnative",
"圆润": "vista",
"魔法": "cyborg",
"默认": "default",
"圣洁": "litera",
"宇宙": "solar",
"微醺": "journal",
"海洋": "lumen",
"直率": "flatly",
"热烈": "united",
"黯淡": "clam",
"玄幻": "pulse",
"天空": "morph",
"方块": "winnative",
"缤纷": "cosmo",
"自然": "minty",
"砂岩": "sandstone",
"经典": "classic"
},
"English(US)": {
"Alt": "alt",
"Cloud": "yeti",
"Calm": "superhero",
"Dark": "darkly",
"Xpnative": "xpnative",
"Round": "vista",
"Magic": "cyborg",
"Default": "default",
"Light": "litera",
"Universe": "solar",
"Wine": "journal",
"Ocean": "lumen",
"Direct": "flatly",
"Hot": "united",
"Dim": "clam",
"Fantasy": "pulse",
"Sky": "morph",
"Blocks": "winnative",
"Colorful": "cosmo",
"Nature": "minty",
"Sandstone": "sandstone",
"Classic": "classic"
}
}
def get(lang):
return themename[lang]
def catch(lang, key):
for find in themename[lang].keys():
if key == themename[lang][find]:
return find

Binary file not shown.

BIN
turn_images/delete.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

View File

@ -0,0 +1 @@
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x00MIDAT8Oc\x18p\xc0\x08\xa51\xc0\xce\xaa\xb0\xffP&\x18\xb8\xb7\xad\xc2\xaa\x16.\x88\xae\x81\x10\xc0j 1\x86\xa0\xaba\x82\xd2\x18\x00Y!>\x83q\x1a@,\x185\x80\n\x06\xa0\x00r\xd2\x01Jj"\xc6\x00\x10\xc0\x95\xac\x07\x0200\x00\x00\x02\x0e\x1bB\n\xf0\xe0\x01\x00\x00\x00\x00IEND\xaeB`\x82'

BIN
turn_images/former.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

View File

@ -0,0 +1 @@
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x00fIDAT8Oc\xa0:\xe0\xbb\xe8\xfa\x1f\xca\xc4\x00\xd8\xe4\x98\xa04A\x80\xcb`\xa2\x0c\xc0\xe7*\x82\x06\xe0\xd3\x0c\x02x\r \xa4\x19\x04p\x1a@\x8cf\x10\xc0j\x00\xb1\x9aA\x80\xa8@\xc4\x07\xb0\x1a\xf0I\x7f7#\x94I\x10\xe0t\x01\xb1\x86\xe0\xf5\x021\x86\x10\x0c\x03B\x86\x10\x15\x88\xf8\x0c!\xca\x00\x10 %`I\x00\x0c\x0c\x00\x1f?\x1caM\xfe\x9b\xec\x00\x00\x00\x00IEND\xaeB`\x82'

BIN
turn_images/latter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

View File

@ -0,0 +1 @@
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x00dIDAT8O\xad\xcc\xc1\r\x800\x0cC\xd1\xc0\x00\xac\xc2\x14L\xcd\x14\xac\xc2\x02 K\xb9\x14b\xc7\x87\xfeK#U~1\xbd\xed:\x9e<\x7fU\x7fk\xbeC\n\xf9V\x02\xc8E(\x80\x1cD\x02\xa8CZ\x00)\xc4\x02\x10Cl\x80e\x03\xf7~.y\x0eY\x00\x1b\xa3\x16Pc$\x81n\x8c(\xe0\x8cQ\t\xb8\xe3\tE\xbc\x1f?\x1ca\x00\x1c\xaf\x18\x00\x00\x00\x00IEND\xaeB`\x82'

BIN
turn_images/loading.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

File diff suppressed because one or more lines are too long

BIN
turn_images/pausesound.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

View File

@ -0,0 +1 @@
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x00,IDAT8Oc\xa0\x140Bi0\xe0\xbb\xe8\xfa\x1f\xcad\xf8\xa4\xbf\x9b(9&(M6\x185`\xd4\x00\x10\x185\x80b\xc0\xc0\x00\x00\xa5\xaa\x08\x1cY"\\y\x00\x00\x00\x00IEND\xaeB`\x82'

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

View File

@ -0,0 +1 @@
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x000IDAT8Oc\x18A\xc0\xde\xe3\xcc\x7f(\x93|\x80\xcd\x10F(\r\x06\xc4\xdarp\x87\t\x8a\xbe\x91\x0e\xe8\x1b\x88\x14\xa5\x05\xaa$\xa4\xc1\x08\x18\x18\x00\xb9W\x11K\x9cO\x82\xaa\x00\x00\x00\x00IEND\xaeB`\x82'

BIN
turn_images/playsound.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

View File

@ -0,0 +1 @@
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00\tpHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\xa8d\x00\x00\x00dIDAT8O\xb5\xd2\xb1\r\x800\x0cDQ\x87\x01X\x85)25S\xb0\n\x0b\x80N\xb2\xd2\xc4\xf6]$\xf8M\xdc\xdc\xabb\xbf\xb4_\xfd\xf1\x93\xb6\xf9;\xa5")\x80\x14\xa4\x04\x10C(\x80*D\x02P\x86\xc8\x00\x8a\x90% j\t\xb8\x8f\xb3\xf99\x92\x81h\x8c$ \x1b#\nTcT\x02l\x9c\xa6|\xe1\x8f2{\x01\x18\xfb\x1a\x82\xf8+\xb1(\x00\x00\x00\x00IEND\xaeB`\x82'

View File

@ -0,0 +1,6 @@
while True:
filename = input('File Name:')
with open(filename, 'rb') as f:
file_turn = f.read()
with open(filename+'.txt', 'w') as f:
f.write(str(file_turn))

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -0,0 +1,34 @@
import requests
from time import sleep
def download(name):
url = f"https://api.xingzhige.com/API/Kugou_GN_new/?name={name}&n=1"
resp = requests.get(url)
resp.close()
music_name = resp.json()["data"]["songname"]
singer = resp.json()["data"]["name"]
music_url = resp.json()["data"]["src"]
response = requests.get(music_url, stream=True)
formated = music_url.split("?")[0].rsplit(".", 1)[1]
filename_without_endswith = f"{singer} - {music_name}"
filename = f"{filename_without_endswith}.{formated}"
filename = filename.replace("\\", "#").replace("/", "#")
filename = filename.replace(":", "#").replace("*", "#")
filename = filename.replace("?", "#").replace("\"", "#")
filename = filename.replace("<", "#").replace(">", "#").replace("|", "#")
with open(filename, "wb") as f:
for data in response.iter_content(chunk_size=1024):
f.write(data)
response.close()
while True:
music = input("请输入要下载的音乐(歌名-歌手):")
print("正在下载,请稍后...")
try:
download(music)
print("下载完成!")
except Exception as e:
print(e)
sleep(2)

View File

@ -0,0 +1,51 @@
import requests
from time import sleep
def download(name, index):
url = f"https://api.xingzhige.com/API/Kugou_GN_new/?name={name}&n={index+1}"
resp = requests.get(url)
resp.close()
music_name = resp.json()["data"]["songname"]
singer = resp.json()["data"]["name"]
music_url = resp.json()["data"]["src"]
response = requests.get(music_url, stream=True)
formated = music_url.split("?")[0].rsplit(".", 1)[1]
filename_without_endswith = f"{singer} - {music_name}"
filename = f"{filename_without_endswith}.{formated}"
filename = filename.replace("\\", "#").replace("/", "#")
filename = filename.replace(":", "#").replace("*", "#")
filename = filename.replace("?", "#").replace("\"", "#")
filename = filename.replace("<", "#").replace(">", "#").replace("|", "#")
with open(filename, "wb") as f:
for data in response.iter_content(chunk_size=1024):
f.write(data)
response.close()
def get_data(name):
url = f"https://api.xingzhige.com/API/Kugou_GN_new/?name={name}"
resp = requests.get(url)
resp.close()
music_list = resp.json()["data"]
for i in range(len(music_list)):
print(f"{i+1}.{music_list[i]['songname']} - {music_list[i]['name']}")
while True:
music = input("请输入要搜索的音乐(歌名-歌手):")
get_data(music)
try:
index = int(input("请输入歌曲的编号(什么都不输默认退出):")) - 1
except:
continue
if index >= 10:
continue
try:
download(music, index)
print("下载完成!")
except Exception as e:
print(e)
sleep(2)

BIN
低版本/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB