├── LICENSE ├── README.md ├── decrypt.py ├── icon.py └── qmc_decrypter.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Dan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 介绍 2 | 3 | * 此工具可以将QQ音乐下载的加密的VIP歌曲🎵文件(后缀以**qmc**开头的文件),如 **qmcogg**、**qmcflac**、**qmc0**等,转换成一般播放器可以识别的**ogg**、**flac**和**mp3**格式等。 4 | 5 | * 文件解密算法在decrypt.py中,程序GUI使用tkinter构建。 6 | 7 | ## 下载使用 8 | 9 | * 可直接在[release页面]( https://github.com/ingen42/qcm_file_decrypter/releases )下载可执行文件(qq音乐VIP歌曲转换器.exe) 10 | * 也可以下载源代码,在代码路径下使用pyinstaller工具运行命令`pyinstaller -F qmc_decrypter.py -w `编译成可执行文件(在dist目录下)。 11 | * 打开工具,在操作菜单下分别添加文件和指定输出文件的路径,点击“开始转换”按钮,全部转换完成后,打开输出路径,即可找到对应的解密后的文件。 12 | * 注:腾讯电脑管家可能会报毒😓...,如果出现这样的情况请将程序文件添加到信任区。 13 | -------------------------------------------------------------------------------- /decrypt.py: -------------------------------------------------------------------------------- 1 | 2 | suffix_map = {'qmcogg': 'ogg', 'qmcflac': 'flac', 'qmc0': 'mp3'} 3 | 4 | 5 | def save_file(data, output_dir, file_name, file_suffix): 6 | path = output_dir + '/' + file_name + '.' + file_suffix 7 | with open(path, 'wb') as f: 8 | f.write(data) 9 | 10 | 11 | def qmc_file_decrypt(file_path, out_dir): 12 | file = file_path.split('/')[-1] 13 | file_name = file.split('.')[0] 14 | file_suffix = file.split('.')[-1] 15 | with open(file_path, 'rb') as f: 16 | data = bytearray(f.read()) 17 | for i in range(len(data)): 18 | data[i] ^= map_l(i) 19 | save_file(data, out_dir, file_name, suffix_map[file_suffix]) 20 | 21 | 22 | def get_i(i): 23 | maps = [0x77, 0x48, 0x32, 0x73, 0xDE, 0xF2, 0xC0, 0xC8, 0x95, 0xEC, 0x30, 0xB2, 0x51, 0xC3, 0xE1, 0xA0, 24 | 0x9E, 0xE6, 0x9D, 0xCF, 0xFA, 0x7F, 0x14, 0xD1, 0xCE, 0xB8, 0xDC, 0xC3, 0x4A, 0x67, 0x93, 0xD6, 25 | 0x28, 0xC2, 0x91, 0x70, 0xCA, 0x8D, 0xA2, 0xA4, 0xF0, 8, 0x61, 0x90, 0x7E, 0x6F, 0xA2, 0xE0, 0xEB, 26 | 0xAE, 0x3E, 0xB6, 0x67, 0xC7, 0x92, 0xF4, 0x91, 0xB5, 0xF6, 0x6C, 0x5E, 0x84, 0x40, 0xF7, 0xF3, 27 | 0x1B, 2, 0x7F, 0xD5, 0xAB, 0x41, 0x89, 0x28, 0xF4, 0x25, 0xCC, 0x52, 0x11, 0xAD, 0x43, 0x68, 0xA6, 28 | 0x41, 0x8B, 0x84, 0xB5, 0xFF, 0x2C, 0x92, 0x4A, 0x26, 0xD8, 0x47, 0x6A, 0x7C, 0x95, 0x61, 0xCC, 29 | 0xE6, 0xCB, 0xBB, 0x3F, 0x47, 0x58, 0x89, 0x75, 0xC3, 0x75, 0xA1, 0xD9, 0xAF, 0xCC, 8, 0x73, 0x17, 30 | 0xDC, 0xAA, 0x9A, 0xA2, 0x16, 0x41, 0xD8, 0xA2, 6, 0xC6, 0x8B, 0xFC, 0x66, 0x34, 0x9F, 0xCF, 0x18, 31 | 0x23, 0xA0, 0xA, 0x74, 0xE7, 0x2B, 0x27, 0x70, 0x92, 0xE9, 0xAF, 0x37, 0xE6, 0x8C, 0xA7, 0xBC, 0x62, 32 | 0x65, 0x9C, 0xC2, 8, 0xC9, 0x88, 0xB3, 0xF3, 0x43, 0xAC, 0x74, 0x2C, 0xF, 0xD4, 0xAF, 0xA1, 0xC3, 1, 33 | 0x64, 0x95, 0x4E, 0x48, 0x9F, 0xF4, 0x35, 0x78, 0x95, 0x7A, 0x39, 0xD6, 0x6A, 0xA0, 0x6D, 0x40, 34 | 0xE8, 0x4F, 0xA8, 0xEF, 0x11, 0x1D, 0xF3, 0x1B, 0x3F, 0x3F, 7, 0xDD, 0x6F, 0x5B, 0x19, 0x30, 0x19, 35 | 0xFB, 0xEF, 0xE, 0x37, 0xF0, 0xE, 0xCD, 0x16, 0x49, 0xFE, 0x53, 0x47, 0x13, 0x1A, 0xBD, 0xA4, 0xF1, 36 | 0x40, 0x19, 0x60, 0xE, 0xED, 0x68, 9, 6, 0x5F, 0x4D, 0xCF, 0x3D, 0x1A, 0xFE, 0x20, 0x77, 0xE4, 0xD9, 37 | 0xDA, 0xF9, 0xA4, 0x2B, 0x76, 0x1C, 0x71, 0xDB, 0, 0xBC, 0xFD, 0xC, 0x6C, 0xA5, 0x47, 0xF7, 0xF6, 0, 38 | 0x79, 0x4A, 0x11] 39 | return maps[(i * i + 80923) % 256] 40 | 41 | 42 | def map_l(i): 43 | if i >= 0x8000: 44 | return get_i(i % 0x7fff) 45 | else: 46 | return get_i(i) 47 | -------------------------------------------------------------------------------- /icon.py: -------------------------------------------------------------------------------- 1 | img = b'AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpEOEi6TDlQukg2dLZIOzS6TDucukw75LpMO3y6TDr8ukg1+LpQOOgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwlQ4MLpMOeC6TDesukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7JLZMNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukw4aLpMO1y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8tkw2ZJJISBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukg4sLpMN5S6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDssrjg4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtlQ0YLZIO4y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpIOkwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALZIOry6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8tkg5OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALZIOQC6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LZMO2TCYDggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6SDcMukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8tkw5kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6TDhIukw77LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMOwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkw1SLpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8wlQ4SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpMOdi6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LZMNNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2TDZEukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDlIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkw2RLpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8tkw10AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpMOdi6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMObAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2TDVIukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6SDWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukw4SLpMO+y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8tkw1eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6SDcMukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LZMNXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkg5ALpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y2TDV4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2SDq8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8tkw1eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtlQ0YLZIO4y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LZMNXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6SDiwukw3lLpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y2TDV4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpMOGi6TDtcukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8tkw1eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwlQ4MLpMOeC6TDesukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7JLZMNQi6TDv8ukw7/LpMO/y6TDv8ukw7/LZMNXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukQ4SLpMOVC6SDZ0tkg7NLpMO5y6TDvkukw7fLpMOvy6SDX4ulA46AAAAAAAAAAAukw7/LpMO/y6TDv8ukw7/LpMO/y2TDV4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpMO/y6TDv8ukw7/LpMO/y6TDv8tkw1eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6TDv8ukw7/LpMO/y6TDv8ukw7/LZMNXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukw7/LpMO/y6TDv8ukw7/LpMO/y2TDV4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpMO/y6TDv8ukw7/LpMO/y6TDv8tkw1eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6TDv8ukw7/LpMO/y6TDv8ukw7/LZMNXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukw7/LpMO/y6TDv8ukw7/LpMO/y2TDV4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpMO/y6TDv8ukw7/LpMO/y6TDv8tkw1eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6TDv8ukw7/LpMO/y6TDv8ukw7/LZMNXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukw7/LpMO/y6TDv8ukw7/LpMO/y2TDV4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpMO/y6TDv8ukw7/LpMO/y6TDv8tkw1eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukhIGLZMOOC2SDnwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6TDv8ukw7/LpMO/y6TDv8ukw7/LZMNXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALZMNJC6TDWAukg6vLpMO5y6TDv8ukw7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukw7/LpMO/y6TDv8ukw7/LpMO/y2TDV4AAAAAAAAAAAAAAAAAAAAALJQKEC6TDkoukw2VLpMO0y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpMO/y6TDv8ukw7/LpMO/y6TDv8tkw1eK5ULBi6SDjYukg16LZMOvy6TDvUukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6TDv8ukw7/LpMO/y6TDv8ukw7/LZMNzS6TDuUukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO9S6TDsEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO+y6SDdEtkw2TLZMNSC6QEBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDt8ukw6pLpMOWC2SDSIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALpMO/y6TDv8ukw7/LpMO/y6TDv8ukw7/LpMO/y6TDu8tkw63LpMObi2SDjAwjxAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6TDv8ukw7/LpMO/y6TDfcukw3HLpMOhS6SDkAtkwsKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAukw7XLZMOnS6TDk4vkwwYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////////////////////////////////////////////////////////////////////////////////A/////////wAf///////8AAf///////gAA///////8AAB///////gAAH//////+AAAP//////wAAA///////AAAB//////8AAAH//////wAAAf/////+AAAB//////4AAAH//////wAAAf//////AAAB//////8AAAH//////wAAAf//////gAAB//////+AAAH//////8AAAf//////4AAB///////wAAH///////wAQf///////wPB/////////8H/////////wf/////////B/////////8H/////////wf/////////B/////////8H/////////wf/////////B/////////8H/////////wf/D///////B/AP//////8HgA///////wAAD///////AAAP//////8AAA///////wAAD///////AAAP//////8AAA///////wAAf///////AAf///////8Af////////wP/////////P/////////////////////////////////////////////////////////////////////////////////////////8= ' 2 | -------------------------------------------------------------------------------- /qmc_decrypter.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import os 3 | import threading 4 | import time 5 | import tkinter as tk 6 | from threading import Thread 7 | from tkinter import * 8 | from tkinter import filedialog, messagebox 9 | 10 | from decrypt import qmc_file_decrypt 11 | from icon import img 12 | 13 | 14 | class HandleThread(Thread): 15 | def __init__(self, file_list_box, log_area, file_list, output_dir): 16 | super().__init__() 17 | self.file_list_box = file_list_box 18 | self.log_area = log_area 19 | self.file_list = file_list 20 | self.output_dir = output_dir 21 | 22 | def run(self): 23 | for i in list(self.file_list): 24 | start_time = time.time() 25 | self.log_area.insert(END, '正在处理 %s ...\n' % i) 26 | qmc_file_decrypt(self.file_list[i], self.output_dir) 27 | end_time = time.time() 28 | total_time = end_time - start_time 29 | self.file_list_box.delete(0) 30 | del self.file_list[i] 31 | self.log_area.insert(END, '文件处理完毕\n') 32 | self.log_area.insert(END, '共耗时 %d 秒\n' % total_time) 33 | self.log_area.insert(END, '********************************* \n') 34 | self.log_area.see(END) 35 | self.log_area.update() 36 | 37 | 38 | class App: 39 | def __init__(self, master): 40 | self.root = master 41 | self.set_app_geometry() 42 | self.root.title('qq音乐VIP歌曲转换器v1.3') 43 | with open('tmp.ico', 'wb+') as ico: 44 | ico.write(base64.b64decode(img)) 45 | self.root.iconbitmap('tmp.ico') 46 | os.remove("tmp.ico") 47 | # self.root.geometry('500x300+600+300') 48 | self.root.resizable(False, False) 49 | self.file_list = {} 50 | # self.file_name_list = [] 51 | self.file_names = StringVar() 52 | self.out_dir = StringVar() 53 | self.init_menu() 54 | self.init_input_frame() 55 | self.init_handle_frame() 56 | 57 | def set_app_geometry(self): 58 | scn_width, scn_height = self.root.maxsize() 59 | self.root.geometry('500x320+%d+%d' % (scn_width / 2 - 250, scn_height / 2 - 150)) 60 | 61 | def init_menu(self): 62 | menubar = tk.Menu(self.root) 63 | self.root.config(menu=menubar) 64 | file_menu = tk.Menu(menubar, tearoff=0) 65 | # file_menu.add_command(label='添加文件', command=self._open_file) 66 | file_menu.add_command(label='添加文件', command=self._open_directory) 67 | file_menu.add_command(label='指定输出路径', command=self._assign_output_dir) 68 | file_menu.add_command(label='清除所有文件', command=self._clear_all_file) 69 | file_menu.add_command(label='退出', command=self.root.quit) 70 | menubar.add_cascade(label='操作', menu=file_menu) 71 | 72 | about_menu = tk.Menu(menubar, tearoff=0) 73 | about_menu.add_command(label='使用说明', command=self._how_to_use) 74 | about_menu.add_command(label='关于', command=self._about) 75 | menubar.add_cascade(label='关于', menu=about_menu) 76 | 77 | def init_input_frame(self): 78 | input_frame = tk.Frame(bg='#f0e68c') 79 | input_frame.place(x=5, y=5, width=190, height=290) 80 | input_label = tk.Label(input_frame, bg='#00fa9a', text='待处理文件').pack(side='top', fill='x') 81 | list_box_scroll = tk.Scrollbar(input_frame) 82 | list_box_scroll.pack(side=RIGHT, fill=Y) 83 | self.file_list_box = tk.Listbox(input_frame, bg='#f0e68c', listvariable=self.file_names) 84 | self.file_list_box.pack(side='top', fill=BOTH, expand=YES, anchor=CENTER) 85 | list_box_scroll.config(command=self.file_list_box.yview) 86 | self.file_list_box.config(yscrollcommand=list_box_scroll.set) 87 | out_dir_label = tk.Label(input_frame, bg='#00fa9a', text='输出文件路径').pack(side=TOP, fill=X) 88 | out_dir_entry = tk.Entry(input_frame, bg='#f0e68c', textvariable=self.out_dir).pack(side=BOTTOM, fill=X) 89 | 90 | def init_handle_frame(self): 91 | handle_frame = tk.Frame(bg='#00fa9a') 92 | handle_frame.place(x=205, y=5, width=290, height=290) 93 | handle_button = tk.Button(handle_frame, text='开始转换', command=self.do_it).pack(side=TOP) 94 | scroll = tk.Scrollbar(handle_frame) 95 | scroll.pack(side=RIGHT, fill=Y) 96 | self.log_area = tk.Text(handle_frame, bg='#f0e68c', foreground='grey') 97 | self.log_area.pack(side=BOTTOM) 98 | scroll.config(command=self.log_area.yview) 99 | self.log_area.config(yscrollcommand=scroll.set) 100 | 101 | def _open_directory(self): 102 | file_opened = filedialog.askopenfilenames() 103 | for file in file_opened: 104 | file_path = file 105 | file_name = file_path.split('/')[-1] 106 | if self.is_qmc_file(file_name) and file_name not in self.file_list: 107 | file = {file_name: file_path} 108 | self.file_list.update(file) 109 | self.file_names.set(list(self.file_list)) 110 | else: 111 | pass 112 | 113 | def _assign_output_dir(self): 114 | out_dir_str = filedialog.askdirectory() 115 | self.out_dir.set(out_dir_str) 116 | 117 | def _clear_all_file(self): 118 | self.file_list_box.delete(0, len(self.file_list) - 1) 119 | self.file_list = {} 120 | 121 | def is_qmc_file(self, file_name): 122 | suffix_list = ['qmcogg', 'qmcflac'] 123 | try: 124 | file_suffix = file_name.split('.')[-1] 125 | if file_suffix not in suffix_list: 126 | return False 127 | else: 128 | return True 129 | except Exception as e: 130 | return False 131 | 132 | def do_it(self): 133 | if self.out_dir.get() == '': 134 | messagebox.showwarning(title='警告', message='请先指定输出文件夹!') 135 | pass 136 | elif len(self.file_list) == 0: 137 | messagebox.showwarning(title='提示', message='请先输入要处理的文件!') 138 | else: 139 | out_dir_str = self.out_dir.get() 140 | # file_items = self.file_list_box.get(0, len(self.file_list) - 1) 141 | 142 | if threading.activeCount() <= 1: 143 | t = HandleThread(file_list_box=self.file_list_box, log_area=self.log_area, file_list=self.file_list, 144 | output_dir=out_dir_str) 145 | t.start() 146 | else: 147 | messagebox.showinfo(title='提示', message='正在处理中,请稍后再进行其他操作!') 148 | 149 | def _how_to_use(self): 150 | messagebox.showinfo(title='使用说明', message='此工具可将QQ音乐下载下来的VIP加密歌曲文件转换成一般播放器可识别的文件格式' 151 | ', 目前支持解密的文件格式包括:.qmcogg, .qmcflac') 152 | 153 | def _about(self): 154 | messagebox.showinfo(title='关于', message='此工具仅供个人学习交流,未用于任何商业用途!') 155 | 156 | 157 | root = tk.Tk() 158 | app = App(root) 159 | root.mainloop() 160 | --------------------------------------------------------------------------------