├── .gitignore ├── Icon.png ├── Makefile ├── README.md ├── bass ├── bass.go ├── bass.h ├── const.go ├── meta.go └── player.go ├── dark.png ├── go.mod ├── go.sum ├── libs └── libbass.dylib ├── light.png ├── main.go ├── music.png ├── res ├── appIcon.go ├── logo.go ├── repeatIconDark.go └── repeatIconLight.go ├── ui ├── extended │ └── doubleTapLabel.go ├── file-search.go ├── main-window.go ├── playlist-view.go └── rotate │ └── rotate.go └── utils └── utils.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | build/go_build_main_go 5 | build/gotune 6 | 7 | # Test binary, built with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Dependency directories (remove the comment below to include it) 14 | vendor/ 15 | 16 | # IDE 17 | .idea/ 18 | .vscode/ 19 | .idea/* 20 | /gotune 21 | /GoTune.app/ 22 | *.gtp 23 | -------------------------------------------------------------------------------- /Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejashwikalptaru/gotune/5f2adf5c5bdcf7c32196ca3937c13a7a30ca79da/Icon.png -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build create-package prepare-lib bundle-lib clean package 2 | 3 | build: 4 | go build -o build/gotune cmd/main.go 5 | 6 | execute: 7 | ./build/gotune 8 | 9 | run: build execute 10 | 11 | create-package: 12 | fyne package -name GoTune -icon Icon.png appVersion 0.0.1 13 | 14 | prepare-lib: 15 | install_name_tool -id "@loader_path/../libs/libbass.dylib" ./libs/libbass.dylib 16 | 17 | bundle-lib: 18 | cp -r ./libs GoTune.app/Contents/libs 19 | 20 | clean: 21 | rm ./gotune 22 | 23 | package: prepare-lib create-package bundle-lib clean -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go Tune 2 | A music player written in golang under development, was created as a part to learn [Fyne](https://fyne.io/) 3 | 4 | Uses [Bass library](http://www.un4seen.com/bass.html) as audio engine 5 | 6 | ### Features 7 | - Playlist 8 | - Save history and reload 9 | - Audio + Tracker modules support 10 | 11 | #### Bundle resource 12 | ```bash 13 | fyne bundle --package=res --prefix=Resource music.png >> res/logo.go 14 | ``` 15 | 16 | #### Build 17 | ```bash 18 | make build 19 | ``` 20 | 21 | #### Create app for Mac 22 | ```bash 23 | make package 24 | ``` 25 | 26 | ![Dark Theme](dark.png) 27 | ![Light Theme](light.png) 28 | 29 | ### Contribution 30 | Please feel free to fork the repository and submit your changes as a PR with description of changes/features -------------------------------------------------------------------------------- /bass/bass.go: -------------------------------------------------------------------------------- 1 | package bass 2 | 3 | /* 4 | #cgo CFLAGS: -I/usr/include -I. 5 | #cgo darwin LDFLAGS: -L${SRCDIR}/../libs -lbass 6 | #include "bass.h" 7 | */ 8 | import "C" 9 | import ( 10 | "errors" 11 | "unsafe" 12 | ) 13 | 14 | func initBass(device int, freq int, flags InitFlags) (bool, *Error) { 15 | if C.BASS_Init(C.int(device), C.DWORD(freq), C.DWORD(flags), nil, nil) != 0 { 16 | return true, nil 17 | } else { 18 | return false, errMsg(int(C.BASS_ErrorGetCode())) 19 | } 20 | } 21 | 22 | func freeBass() (bool, *Error) { 23 | if C.BASS_Free() != 0 { 24 | return true, nil 25 | } else { 26 | return false, errMsg(int(C.BASS_ErrorGetCode())) 27 | } 28 | } 29 | 30 | func musicLoad(file string, flags int) (int64, *Error) { 31 | ch := C.BASS_MusicLoad(0, unsafe.Pointer(C.CString(file)), 0, 0, C.DWORD(flags), 1) 32 | if ch != 0 { 33 | return int64(ch), nil 34 | } else { 35 | return 0, errMsg(int(C.BASS_ErrorGetCode())) 36 | } 37 | } 38 | 39 | func musicFree(ch int64) bool { 40 | if free := C.BASS_MusicFree(C.DWORD(ch)); free != 0 { 41 | return true 42 | } 43 | return false 44 | } 45 | 46 | func streamCreateFile(file string, flags int) (int64, *Error) { 47 | ch := C.BASS_StreamCreateFile(0, unsafe.Pointer(C.CString(file)), 0, 0, C.DWORD(flags)) 48 | if ch != 0 { 49 | return int64(ch), nil 50 | } else { 51 | return 0, errMsg(int(C.BASS_ErrorGetCode())) 52 | } 53 | } 54 | 55 | func streamFree(ch int64) bool { 56 | if free := C.BASS_StreamFree(C.DWORD(ch)); free != 0 { 57 | return true 58 | } 59 | return false 60 | } 61 | 62 | func channelPlay(ch int64, restart bool) (bool, *Error) { 63 | restartIntVal := 0 64 | if restart { 65 | restartIntVal = 1 66 | } 67 | if C.BASS_ChannelPlay(C.DWORD(ch), C.int(restartIntVal)) != 0 { 68 | return true, nil 69 | } else { 70 | return false, errMsg(int(C.BASS_ErrorGetCode())) 71 | } 72 | } 73 | 74 | func channelPause(ch int64) (bool, *Error) { 75 | if C.BASS_ChannelPause(C.DWORD(ch)) != 0 { 76 | return true, nil 77 | } else { 78 | return false, errMsg(int(C.BASS_ErrorGetCode())) 79 | } 80 | } 81 | 82 | func channelStop(ch int64) (bool, *Error) { 83 | if C.BASS_ChannelStop(C.DWORD(ch)) != 0 { 84 | return true, nil 85 | } else { 86 | return false, errMsg(int(C.BASS_ErrorGetCode())) 87 | } 88 | } 89 | 90 | func channelSetAttribute(ch int64, attrib int, value float64) (bool, *Error) { 91 | if C.BASS_ChannelSetAttribute(C.DWORD(ch), C.DWORD(attrib), C.float(value)) != 0 { 92 | return true, nil 93 | } else { 94 | return false, errMsg(int(C.BASS_ErrorGetCode())) 95 | } 96 | } 97 | 98 | func channelSetVolume(ch int64, value float64) (bool, *Error) { 99 | return channelSetAttribute(ch, C.BASS_ATTRIB_VOL, value/100) 100 | } 101 | 102 | func channelStatus(ch int64) ChannelStatus { 103 | status := C.BASS_ChannelIsActive(C.DWORD(ch)) 104 | return ChannelStatus(status) 105 | } 106 | 107 | func channelLength(ch int64) float64 { 108 | QWord := C.BASS_ChannelGetLength(C.DWORD(ch), C.BASS_POS_BYTE) 109 | return float64(QWord) 110 | } 111 | 112 | func channelGetPosition(ch int64) float64 { 113 | QWord := C.BASS_ChannelGetPosition(C.DWORD(ch), C.BASS_POS_BYTE) 114 | return float64(QWord) 115 | } 116 | 117 | func channelSetPosition(ch int64, pos float64) { 118 | C.BASS_ChannelSetPosition(C.DWORD(ch), C.QWORD(pos), C.BASS_POS_BYTE) 119 | } 120 | 121 | func channelBytes2Seconds(ch int64, pos float64) float64 { 122 | seconds := C.BASS_ChannelBytes2Seconds(C.DWORD(ch), C.QWORD(pos)) 123 | return float64(seconds) 124 | } 125 | 126 | func channelSeconds2Bytes(ch int64, pos float64) float64 { 127 | bytes := C.BASS_ChannelSeconds2Bytes(C.DWORD(ch), C.double(pos)) 128 | return float64(bytes) 129 | } 130 | 131 | func channelGetMODTags(ch int64, flags Tag) string { 132 | musicName := C.BASS_ChannelGetTags(C.DWORD(ch), C.DWORD(flags)) 133 | return C.GoString(musicName) 134 | } 135 | 136 | func channelSlideAttribute(ch int64, flags ChannelAttributes, value float32, time int) bool { 137 | if done := C.BASS_ChannelSlideAttribute(C.DWORD(ch), C.DWORD(flags), C.float(value), C.DWORD(time)); done != 0 { 138 | return true 139 | } 140 | return false 141 | } 142 | 143 | 144 | func errMsg(c int) *Error { 145 | if c == 0 { 146 | return nil 147 | } 148 | codes := make(map[int]string) 149 | codes[1] = "memory error" 150 | codes[2] = "can't open the file" 151 | codes[3] = "can't find a free/valid driver" 152 | codes[4] = "the sample buffer was lost" 153 | codes[5] = "invalid handle" 154 | codes[6] = "unsupported sample format" 155 | codes[7] = "invalid position" 156 | codes[8] = "BASS_Init has not been successfully called" 157 | codes[9] = "BASS_Start has not been successfully called" 158 | codes[10] = "SSL/HTTPS support isn't available" 159 | codes[14] = "already initialized/paused/whatever" 160 | codes[18] = "can't get a free channel" 161 | codes[19] = "an illegal type was specified" 162 | codes[20] = "an illegal parameter was specified" 163 | codes[21] = "no 3D support" 164 | codes[22] = "no EAX support" 165 | codes[23] = "illegal device number" 166 | codes[24] = "not playing" 167 | codes[25] = "illegal sample rate" 168 | codes[27] = "the stream is not a file stream" 169 | codes[29] = "no hardware voices available" 170 | codes[31] = "the MOD music has no sequence data" 171 | codes[32] = "no internet connection could be opened" 172 | codes[33] = "couldn't create the file" 173 | codes[34] = "effects are not available" 174 | codes[37] = "requested data is not available" 175 | codes[38] = "the channel is/isn't a 'decoding channel'" 176 | codes[39] = "a sufficient DirectX version is not installed" 177 | codes[40] = "connection timed out" 178 | codes[41] = "unsupported file format" 179 | codes[42] = "unavailable speaker" 180 | codes[43] = "invalid BASS version (used by add-ons)" 181 | codes[44] = "codec is not available/supported" 182 | codes[45] = "the channel/file has ended" 183 | codes[46] = "the device is busy" 184 | codes[-1] = "some other mystery problem" 185 | return &Error{ 186 | Err: errors.New(codes[c]), 187 | Code: ErrorCode(c), 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /bass/bass.h: -------------------------------------------------------------------------------- 1 | /* 2 | BASS 2.4 C/C++ header file 3 | Copyright (c) 1999-2019 Un4seen Developments Ltd. 4 | 5 | See the BASS.CHM file for more detailed documentation 6 | */ 7 | 8 | #ifndef BASS_H 9 | #define BASS_H 10 | 11 | #ifdef _WIN32 12 | #include 13 | typedef unsigned __int64 QWORD; 14 | #else 15 | #include 16 | #define WINAPI 17 | #define CALLBACK 18 | typedef uint8_t BYTE; 19 | typedef uint16_t WORD; 20 | typedef uint32_t DWORD; 21 | typedef uint64_t QWORD; 22 | #ifdef __OBJC__ 23 | #include 24 | #else 25 | typedef int BOOL; 26 | #endif 27 | #ifndef TRUE 28 | #define TRUE 1 29 | #define FALSE 0 30 | #endif 31 | #define LOBYTE(a) (BYTE)(a) 32 | #define HIBYTE(a) (BYTE)((a)>>8) 33 | #define LOWORD(a) (WORD)(a) 34 | #define HIWORD(a) (WORD)((a)>>16) 35 | #define MAKEWORD(a,b) (WORD)(((a)&0xff)|((b)<<8)) 36 | #define MAKELONG(a,b) (DWORD)(((a)&0xffff)|((b)<<16)) 37 | #endif 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | #define BASSVERSION 0x204 // API version 44 | #define BASSVERSIONTEXT "2.4" 45 | 46 | #ifndef BASSDEF 47 | #define BASSDEF(f) WINAPI f 48 | #else 49 | #define NOBASSOVERLOADS 50 | #endif 51 | 52 | typedef DWORD HMUSIC; // MOD music handle 53 | typedef DWORD HSAMPLE; // sample handle 54 | typedef DWORD HCHANNEL; // playing sample's channel handle 55 | typedef DWORD HSTREAM; // sample stream handle 56 | typedef DWORD HRECORD; // recording handle 57 | typedef DWORD HSYNC; // synchronizer handle 58 | typedef DWORD HDSP; // DSP handle 59 | typedef DWORD HFX; // DX8 effect handle 60 | typedef DWORD HPLUGIN; // Plugin handle 61 | 62 | // Error codes returned by BASS_ErrorGetCode 63 | #define BASS_OK 0 // all is OK 64 | #define BASS_ERROR_MEM 1 // memory error 65 | #define BASS_ERROR_FILEOPEN 2 // can't open the file 66 | #define BASS_ERROR_DRIVER 3 // can't find a free/valid driver 67 | #define BASS_ERROR_BUFLOST 4 // the sample buffer was lost 68 | #define BASS_ERROR_HANDLE 5 // invalid handle 69 | #define BASS_ERROR_FORMAT 6 // unsupported sample format 70 | #define BASS_ERROR_POSITION 7 // invalid position 71 | #define BASS_ERROR_INIT 8 // BASS_Init has not been successfully called 72 | #define BASS_ERROR_START 9 // BASS_Start has not been successfully called 73 | #define BASS_ERROR_SSL 10 // SSL/HTTPS support isn't available 74 | #define BASS_ERROR_ALREADY 14 // already initialized/paused/whatever 75 | #define BASS_ERROR_NOTAUDIO 17 // file does not contain audio 76 | #define BASS_ERROR_NOCHAN 18 // can't get a free channel 77 | #define BASS_ERROR_ILLTYPE 19 // an illegal type was specified 78 | #define BASS_ERROR_ILLPARAM 20 // an illegal parameter was specified 79 | #define BASS_ERROR_NO3D 21 // no 3D support 80 | #define BASS_ERROR_NOEAX 22 // no EAX support 81 | #define BASS_ERROR_DEVICE 23 // illegal device number 82 | #define BASS_ERROR_NOPLAY 24 // not playing 83 | #define BASS_ERROR_FREQ 25 // illegal sample rate 84 | #define BASS_ERROR_NOTFILE 27 // the stream is not a file stream 85 | #define BASS_ERROR_NOHW 29 // no hardware voices available 86 | #define BASS_ERROR_EMPTY 31 // the MOD music has no sequence data 87 | #define BASS_ERROR_NONET 32 // no internet connection could be opened 88 | #define BASS_ERROR_CREATE 33 // couldn't create the file 89 | #define BASS_ERROR_NOFX 34 // effects are not available 90 | #define BASS_ERROR_NOTAVAIL 37 // requested data/action is not available 91 | #define BASS_ERROR_DECODE 38 // the channel is/isn't a "decoding channel" 92 | #define BASS_ERROR_DX 39 // a sufficient DirectX version is not installed 93 | #define BASS_ERROR_TIMEOUT 40 // connection timedout 94 | #define BASS_ERROR_FILEFORM 41 // unsupported file format 95 | #define BASS_ERROR_SPEAKER 42 // unavailable speaker 96 | #define BASS_ERROR_VERSION 43 // invalid BASS version (used by add-ons) 97 | #define BASS_ERROR_CODEC 44 // codec is not available/supported 98 | #define BASS_ERROR_ENDED 45 // the channel/file has ended 99 | #define BASS_ERROR_BUSY 46 // the device is busy 100 | #define BASS_ERROR_UNSTREAMABLE 47 // unstreamable file 101 | #define BASS_ERROR_UNKNOWN -1 // some other mystery problem 102 | 103 | // BASS_SetConfig options 104 | #define BASS_CONFIG_BUFFER 0 105 | #define BASS_CONFIG_UPDATEPERIOD 1 106 | #define BASS_CONFIG_GVOL_SAMPLE 4 107 | #define BASS_CONFIG_GVOL_STREAM 5 108 | #define BASS_CONFIG_GVOL_MUSIC 6 109 | #define BASS_CONFIG_CURVE_VOL 7 110 | #define BASS_CONFIG_CURVE_PAN 8 111 | #define BASS_CONFIG_FLOATDSP 9 112 | #define BASS_CONFIG_3DALGORITHM 10 113 | #define BASS_CONFIG_NET_TIMEOUT 11 114 | #define BASS_CONFIG_NET_BUFFER 12 115 | #define BASS_CONFIG_PAUSE_NOPLAY 13 116 | #define BASS_CONFIG_NET_PREBUF 15 117 | #define BASS_CONFIG_NET_PASSIVE 18 118 | #define BASS_CONFIG_REC_BUFFER 19 119 | #define BASS_CONFIG_NET_PLAYLIST 21 120 | #define BASS_CONFIG_MUSIC_VIRTUAL 22 121 | #define BASS_CONFIG_VERIFY 23 122 | #define BASS_CONFIG_UPDATETHREADS 24 123 | #define BASS_CONFIG_DEV_BUFFER 27 124 | #define BASS_CONFIG_REC_LOOPBACK 28 125 | #define BASS_CONFIG_VISTA_TRUEPOS 30 126 | #define BASS_CONFIG_IOS_SESSION 34 127 | #define BASS_CONFIG_IOS_MIXAUDIO 34 128 | #define BASS_CONFIG_DEV_DEFAULT 36 129 | #define BASS_CONFIG_NET_READTIMEOUT 37 130 | #define BASS_CONFIG_VISTA_SPEAKERS 38 131 | #define BASS_CONFIG_IOS_SPEAKER 39 132 | #define BASS_CONFIG_MF_DISABLE 40 133 | #define BASS_CONFIG_HANDLES 41 134 | #define BASS_CONFIG_UNICODE 42 135 | #define BASS_CONFIG_SRC 43 136 | #define BASS_CONFIG_SRC_SAMPLE 44 137 | #define BASS_CONFIG_ASYNCFILE_BUFFER 45 138 | #define BASS_CONFIG_OGG_PRESCAN 47 139 | #define BASS_CONFIG_MF_VIDEO 48 140 | #define BASS_CONFIG_AIRPLAY 49 141 | #define BASS_CONFIG_DEV_NONSTOP 50 142 | #define BASS_CONFIG_IOS_NOCATEGORY 51 143 | #define BASS_CONFIG_VERIFY_NET 52 144 | #define BASS_CONFIG_DEV_PERIOD 53 145 | #define BASS_CONFIG_FLOAT 54 146 | #define BASS_CONFIG_NET_SEEK 56 147 | #define BASS_CONFIG_AM_DISABLE 58 148 | #define BASS_CONFIG_NET_PLAYLIST_DEPTH 59 149 | #define BASS_CONFIG_NET_PREBUF_WAIT 60 150 | #define BASS_CONFIG_ANDROID_SESSIONID 62 151 | #define BASS_CONFIG_WASAPI_PERSIST 65 152 | #define BASS_CONFIG_REC_WASAPI 66 153 | #define BASS_CONFIG_ANDROID_AAUDIO 67 154 | 155 | // BASS_SetConfigPtr options 156 | #define BASS_CONFIG_NET_AGENT 16 157 | #define BASS_CONFIG_NET_PROXY 17 158 | #define BASS_CONFIG_IOS_NOTIFY 46 159 | #define BASS_CONFIG_LIBSSL 64 160 | 161 | // BASS_CONFIG_IOS_SESSION flags 162 | #define BASS_IOS_SESSION_MIX 1 163 | #define BASS_IOS_SESSION_DUCK 2 164 | #define BASS_IOS_SESSION_AMBIENT 4 165 | #define BASS_IOS_SESSION_SPEAKER 8 166 | #define BASS_IOS_SESSION_DISABLE 16 167 | 168 | // BASS_Init flags 169 | #define BASS_DEVICE_8BITS 1 // 8 bit 170 | #define BASS_DEVICE_MONO 2 // mono 171 | #define BASS_DEVICE_3D 4 // enable 3D functionality 172 | #define BASS_DEVICE_16BITS 8 // limit output to 16 bit 173 | #define BASS_DEVICE_LATENCY 0x100 // calculate device latency (BASS_INFO struct) 174 | #define BASS_DEVICE_CPSPEAKERS 0x400 // detect speakers via Windows control panel 175 | #define BASS_DEVICE_SPEAKERS 0x800 // force enabling of speaker assignment 176 | #define BASS_DEVICE_NOSPEAKER 0x1000 // ignore speaker arrangement 177 | #define BASS_DEVICE_DMIX 0x2000 // use ALSA "dmix" plugin 178 | #define BASS_DEVICE_FREQ 0x4000 // set device sample rate 179 | #define BASS_DEVICE_STEREO 0x8000 // limit output to stereo 180 | #define BASS_DEVICE_HOG 0x10000 // hog/exclusive mode 181 | #define BASS_DEVICE_AUDIOTRACK 0x20000 // use AudioTrack output 182 | #define BASS_DEVICE_DSOUND 0x40000 // use DirectSound output 183 | 184 | // DirectSound interfaces (for use with BASS_GetDSoundObject) 185 | #define BASS_OBJECT_DS 1 // IDirectSound 186 | #define BASS_OBJECT_DS3DL 2 // IDirectSound3DListener 187 | 188 | // Device info structure 189 | typedef struct { 190 | #if defined(_WIN32_WCE) || (WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) 191 | const wchar_t *name; // description 192 | const wchar_t *driver; // driver 193 | #else 194 | const char *name; // description 195 | const char *driver; // driver 196 | #endif 197 | DWORD flags; 198 | } BASS_DEVICEINFO; 199 | 200 | // BASS_DEVICEINFO flags 201 | #define BASS_DEVICE_ENABLED 1 202 | #define BASS_DEVICE_DEFAULT 2 203 | #define BASS_DEVICE_INIT 4 204 | #define BASS_DEVICE_LOOPBACK 8 205 | 206 | #define BASS_DEVICE_TYPE_MASK 0xff000000 207 | #define BASS_DEVICE_TYPE_NETWORK 0x01000000 208 | #define BASS_DEVICE_TYPE_SPEAKERS 0x02000000 209 | #define BASS_DEVICE_TYPE_LINE 0x03000000 210 | #define BASS_DEVICE_TYPE_HEADPHONES 0x04000000 211 | #define BASS_DEVICE_TYPE_MICROPHONE 0x05000000 212 | #define BASS_DEVICE_TYPE_HEADSET 0x06000000 213 | #define BASS_DEVICE_TYPE_HANDSET 0x07000000 214 | #define BASS_DEVICE_TYPE_DIGITAL 0x08000000 215 | #define BASS_DEVICE_TYPE_SPDIF 0x09000000 216 | #define BASS_DEVICE_TYPE_HDMI 0x0a000000 217 | #define BASS_DEVICE_TYPE_DISPLAYPORT 0x40000000 218 | 219 | // BASS_GetDeviceInfo flags 220 | #define BASS_DEVICES_AIRPLAY 0x1000000 221 | 222 | typedef struct { 223 | DWORD flags; // device capabilities (DSCAPS_xxx flags) 224 | DWORD hwsize; // size of total device hardware memory 225 | DWORD hwfree; // size of free device hardware memory 226 | DWORD freesam; // number of free sample slots in the hardware 227 | DWORD free3d; // number of free 3D sample slots in the hardware 228 | DWORD minrate; // min sample rate supported by the hardware 229 | DWORD maxrate; // max sample rate supported by the hardware 230 | BOOL eax; // device supports EAX? (always FALSE if BASS_DEVICE_3D was not used) 231 | DWORD minbuf; // recommended minimum buffer length in ms (requires BASS_DEVICE_LATENCY) 232 | DWORD dsver; // DirectSound version 233 | DWORD latency; // delay (in ms) before start of playback (requires BASS_DEVICE_LATENCY) 234 | DWORD initflags; // BASS_Init "flags" parameter 235 | DWORD speakers; // number of speakers available 236 | DWORD freq; // current output rate 237 | } BASS_INFO; 238 | 239 | // BASS_INFO flags (from DSOUND.H) 240 | #define DSCAPS_CONTINUOUSRATE 0x00000010 // supports all sample rates between min/maxrate 241 | #define DSCAPS_EMULDRIVER 0x00000020 // device does NOT have hardware DirectSound support 242 | #define DSCAPS_CERTIFIED 0x00000040 // device driver has been certified by Microsoft 243 | #define DSCAPS_SECONDARYMONO 0x00000100 // mono 244 | #define DSCAPS_SECONDARYSTEREO 0x00000200 // stereo 245 | #define DSCAPS_SECONDARY8BIT 0x00000400 // 8 bit 246 | #define DSCAPS_SECONDARY16BIT 0x00000800 // 16 bit 247 | 248 | // Recording device info structure 249 | typedef struct { 250 | DWORD flags; // device capabilities (DSCCAPS_xxx flags) 251 | DWORD formats; // supported standard formats (WAVE_FORMAT_xxx flags) 252 | DWORD inputs; // number of inputs 253 | BOOL singlein; // TRUE = only 1 input can be set at a time 254 | DWORD freq; // current input rate 255 | } BASS_RECORDINFO; 256 | 257 | // BASS_RECORDINFO flags (from DSOUND.H) 258 | #define DSCCAPS_EMULDRIVER DSCAPS_EMULDRIVER // device does NOT have hardware DirectSound recording support 259 | #define DSCCAPS_CERTIFIED DSCAPS_CERTIFIED // device driver has been certified by Microsoft 260 | 261 | // defines for formats field of BASS_RECORDINFO (from MMSYSTEM.H) 262 | #ifndef WAVE_FORMAT_1M08 263 | #define WAVE_FORMAT_1M08 0x00000001 /* 11.025 kHz, Mono, 8-bit */ 264 | #define WAVE_FORMAT_1S08 0x00000002 /* 11.025 kHz, Stereo, 8-bit */ 265 | #define WAVE_FORMAT_1M16 0x00000004 /* 11.025 kHz, Mono, 16-bit */ 266 | #define WAVE_FORMAT_1S16 0x00000008 /* 11.025 kHz, Stereo, 16-bit */ 267 | #define WAVE_FORMAT_2M08 0x00000010 /* 22.05 kHz, Mono, 8-bit */ 268 | #define WAVE_FORMAT_2S08 0x00000020 /* 22.05 kHz, Stereo, 8-bit */ 269 | #define WAVE_FORMAT_2M16 0x00000040 /* 22.05 kHz, Mono, 16-bit */ 270 | #define WAVE_FORMAT_2S16 0x00000080 /* 22.05 kHz, Stereo, 16-bit */ 271 | #define WAVE_FORMAT_4M08 0x00000100 /* 44.1 kHz, Mono, 8-bit */ 272 | #define WAVE_FORMAT_4S08 0x00000200 /* 44.1 kHz, Stereo, 8-bit */ 273 | #define WAVE_FORMAT_4M16 0x00000400 /* 44.1 kHz, Mono, 16-bit */ 274 | #define WAVE_FORMAT_4S16 0x00000800 /* 44.1 kHz, Stereo, 16-bit */ 275 | #endif 276 | 277 | // Sample info structure 278 | typedef struct { 279 | DWORD freq; // default playback rate 280 | float volume; // default volume (0-1) 281 | float pan; // default pan (-1=left, 0=middle, 1=right) 282 | DWORD flags; // BASS_SAMPLE_xxx flags 283 | DWORD length; // length (in bytes) 284 | DWORD max; // maximum simultaneous playbacks 285 | DWORD origres; // original resolution 286 | DWORD chans; // number of channels 287 | DWORD mingap; // minimum gap (ms) between creating channels 288 | DWORD mode3d; // BASS_3DMODE_xxx mode 289 | float mindist; // minimum distance 290 | float maxdist; // maximum distance 291 | DWORD iangle; // angle of inside projection cone 292 | DWORD oangle; // angle of outside projection cone 293 | float outvol; // delta-volume outside the projection cone 294 | DWORD vam; // voice allocation/management flags (BASS_VAM_xxx) 295 | DWORD priority; // priority (0=lowest, 0xffffffff=highest) 296 | } BASS_SAMPLE; 297 | 298 | #define BASS_SAMPLE_8BITS 1 // 8 bit 299 | #define BASS_SAMPLE_FLOAT 256 // 32 bit floating-point 300 | #define BASS_SAMPLE_MONO 2 // mono 301 | #define BASS_SAMPLE_LOOP 4 // looped 302 | #define BASS_SAMPLE_3D 8 // 3D functionality 303 | #define BASS_SAMPLE_SOFTWARE 16 // not using hardware mixing 304 | #define BASS_SAMPLE_MUTEMAX 32 // mute at max distance (3D only) 305 | #define BASS_SAMPLE_VAM 64 // DX7 voice allocation & management 306 | #define BASS_SAMPLE_FX 128 // old implementation of DX8 effects 307 | #define BASS_SAMPLE_OVER_VOL 0x10000 // override lowest volume 308 | #define BASS_SAMPLE_OVER_POS 0x20000 // override longest playing 309 | #define BASS_SAMPLE_OVER_DIST 0x30000 // override furthest from listener (3D only) 310 | 311 | #define BASS_STREAM_PRESCAN 0x20000 // enable pin-point seeking/length (MP3/MP2/MP1) 312 | #define BASS_STREAM_AUTOFREE 0x40000 // automatically free the stream when it stop/ends 313 | #define BASS_STREAM_RESTRATE 0x80000 // restrict the download rate of internet file streams 314 | #define BASS_STREAM_BLOCK 0x100000 // download/play internet file stream in small blocks 315 | #define BASS_STREAM_DECODE 0x200000 // don't play the stream, only decode (BASS_ChannelGetData) 316 | #define BASS_STREAM_STATUS 0x800000 // give server status info (HTTP/ICY tags) in DOWNLOADPROC 317 | 318 | #define BASS_MP3_IGNOREDELAY 0x200 // ignore LAME/Xing/VBRI/iTunes delay & padding info 319 | #define BASS_MP3_SETPOS BASS_STREAM_PRESCAN 320 | 321 | #define BASS_MUSIC_FLOAT BASS_SAMPLE_FLOAT 322 | #define BASS_MUSIC_MONO BASS_SAMPLE_MONO 323 | #define BASS_MUSIC_LOOP BASS_SAMPLE_LOOP 324 | #define BASS_MUSIC_3D BASS_SAMPLE_3D 325 | #define BASS_MUSIC_FX BASS_SAMPLE_FX 326 | #define BASS_MUSIC_AUTOFREE BASS_STREAM_AUTOFREE 327 | #define BASS_MUSIC_DECODE BASS_STREAM_DECODE 328 | #define BASS_MUSIC_PRESCAN BASS_STREAM_PRESCAN // calculate playback length 329 | #define BASS_MUSIC_CALCLEN BASS_MUSIC_PRESCAN 330 | #define BASS_MUSIC_RAMP 0x200 // normal ramping 331 | #define BASS_MUSIC_RAMPS 0x400 // sensitive ramping 332 | #define BASS_MUSIC_SURROUND 0x800 // surround sound 333 | #define BASS_MUSIC_SURROUND2 0x1000 // surround sound (mode 2) 334 | #define BASS_MUSIC_FT2PAN 0x2000 // apply FastTracker 2 panning to XM files 335 | #define BASS_MUSIC_FT2MOD 0x2000 // play .MOD as FastTracker 2 does 336 | #define BASS_MUSIC_PT1MOD 0x4000 // play .MOD as ProTracker 1 does 337 | #define BASS_MUSIC_NONINTER 0x10000 // non-interpolated sample mixing 338 | #define BASS_MUSIC_SINCINTER 0x800000 // sinc interpolated sample mixing 339 | #define BASS_MUSIC_POSRESET 0x8000 // stop all notes when moving position 340 | #define BASS_MUSIC_POSRESETEX 0x400000 // stop all notes and reset bmp/etc when moving position 341 | #define BASS_MUSIC_STOPBACK 0x80000 // stop the music on a backwards jump effect 342 | #define BASS_MUSIC_NOSAMPLE 0x100000 // don't load the samples 343 | 344 | // Speaker assignment flags 345 | #define BASS_SPEAKER_FRONT 0x1000000 // front speakers 346 | #define BASS_SPEAKER_REAR 0x2000000 // rear/side speakers 347 | #define BASS_SPEAKER_CENLFE 0x3000000 // center & LFE speakers (5.1) 348 | #define BASS_SPEAKER_REAR2 0x4000000 // rear center speakers (7.1) 349 | #define BASS_SPEAKER_N(n) ((n)<<24) // n'th pair of speakers (max 15) 350 | #define BASS_SPEAKER_LEFT 0x10000000 // modifier: left 351 | #define BASS_SPEAKER_RIGHT 0x20000000 // modifier: right 352 | #define BASS_SPEAKER_FRONTLEFT BASS_SPEAKER_FRONT|BASS_SPEAKER_LEFT 353 | #define BASS_SPEAKER_FRONTRIGHT BASS_SPEAKER_FRONT|BASS_SPEAKER_RIGHT 354 | #define BASS_SPEAKER_REARLEFT BASS_SPEAKER_REAR|BASS_SPEAKER_LEFT 355 | #define BASS_SPEAKER_REARRIGHT BASS_SPEAKER_REAR|BASS_SPEAKER_RIGHT 356 | #define BASS_SPEAKER_CENTER BASS_SPEAKER_CENLFE|BASS_SPEAKER_LEFT 357 | #define BASS_SPEAKER_LFE BASS_SPEAKER_CENLFE|BASS_SPEAKER_RIGHT 358 | #define BASS_SPEAKER_REAR2LEFT BASS_SPEAKER_REAR2|BASS_SPEAKER_LEFT 359 | #define BASS_SPEAKER_REAR2RIGHT BASS_SPEAKER_REAR2|BASS_SPEAKER_RIGHT 360 | 361 | #define BASS_ASYNCFILE 0x40000000 362 | #define BASS_UNICODE 0x80000000 363 | 364 | #define BASS_RECORD_PAUSE 0x8000 // start recording paused 365 | #define BASS_RECORD_ECHOCANCEL 0x2000 366 | #define BASS_RECORD_AGC 0x4000 367 | 368 | // DX7 voice allocation & management flags 369 | #define BASS_VAM_HARDWARE 1 370 | #define BASS_VAM_SOFTWARE 2 371 | #define BASS_VAM_TERM_TIME 4 372 | #define BASS_VAM_TERM_DIST 8 373 | #define BASS_VAM_TERM_PRIO 16 374 | 375 | // Channel info structure 376 | typedef struct { 377 | DWORD freq; // default playback rate 378 | DWORD chans; // channels 379 | DWORD flags; // BASS_SAMPLE/STREAM/MUSIC/SPEAKER flags 380 | DWORD ctype; // type of channel 381 | DWORD origres; // original resolution 382 | HPLUGIN plugin; // plugin 383 | HSAMPLE sample; // sample 384 | const char *filename; // filename 385 | } BASS_CHANNELINFO; 386 | 387 | #define BASS_ORIGRES_FLOAT 0x10000 388 | 389 | // BASS_CHANNELINFO types 390 | #define BASS_CTYPE_SAMPLE 1 391 | #define BASS_CTYPE_RECORD 2 392 | #define BASS_CTYPE_STREAM 0x10000 393 | #define BASS_CTYPE_STREAM_VORBIS 0x10002 394 | #define BASS_CTYPE_STREAM_OGG 0x10002 395 | #define BASS_CTYPE_STREAM_MP1 0x10003 396 | #define BASS_CTYPE_STREAM_MP2 0x10004 397 | #define BASS_CTYPE_STREAM_MP3 0x10005 398 | #define BASS_CTYPE_STREAM_AIFF 0x10006 399 | #define BASS_CTYPE_STREAM_CA 0x10007 400 | #define BASS_CTYPE_STREAM_MF 0x10008 401 | #define BASS_CTYPE_STREAM_AM 0x10009 402 | #define BASS_CTYPE_STREAM_DUMMY 0x18000 403 | #define BASS_CTYPE_STREAM_DEVICE 0x18001 404 | #define BASS_CTYPE_STREAM_WAV 0x40000 // WAVE flag, LOWORD=codec 405 | #define BASS_CTYPE_STREAM_WAV_PCM 0x50001 406 | #define BASS_CTYPE_STREAM_WAV_FLOAT 0x50003 407 | #define BASS_CTYPE_MUSIC_MOD 0x20000 408 | #define BASS_CTYPE_MUSIC_MTM 0x20001 409 | #define BASS_CTYPE_MUSIC_S3M 0x20002 410 | #define BASS_CTYPE_MUSIC_XM 0x20003 411 | #define BASS_CTYPE_MUSIC_IT 0x20004 412 | #define BASS_CTYPE_MUSIC_MO3 0x00100 // MO3 flag 413 | 414 | typedef struct { 415 | DWORD ctype; // channel type 416 | #if defined(_WIN32_WCE) || (WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) 417 | const wchar_t *name; // format description 418 | const wchar_t *exts; // file extension filter (*.ext1;*.ext2;etc...) 419 | #else 420 | const char *name; // format description 421 | const char *exts; // file extension filter (*.ext1;*.ext2;etc...) 422 | #endif 423 | } BASS_PLUGINFORM; 424 | 425 | typedef struct { 426 | DWORD version; // version (same form as BASS_GetVersion) 427 | DWORD formatc; // number of formats 428 | const BASS_PLUGINFORM *formats; // the array of formats 429 | } BASS_PLUGININFO; 430 | 431 | // 3D vector (for 3D positions/velocities/orientations) 432 | typedef struct BASS_3DVECTOR { 433 | #ifdef __cplusplus 434 | BASS_3DVECTOR() {}; 435 | BASS_3DVECTOR(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}; 436 | #endif 437 | float x; // +=right, -=left 438 | float y; // +=up, -=down 439 | float z; // +=front, -=behind 440 | } BASS_3DVECTOR; 441 | 442 | // 3D channel modes 443 | #define BASS_3DMODE_NORMAL 0 // normal 3D processing 444 | #define BASS_3DMODE_RELATIVE 1 // position is relative to the listener 445 | #define BASS_3DMODE_OFF 2 // no 3D processing 446 | 447 | // software 3D mixing algorithms (used with BASS_CONFIG_3DALGORITHM) 448 | #define BASS_3DALG_DEFAULT 0 449 | #define BASS_3DALG_OFF 1 450 | #define BASS_3DALG_FULL 2 451 | #define BASS_3DALG_LIGHT 3 452 | 453 | // EAX environments, use with BASS_SetEAXParameters 454 | enum 455 | { 456 | EAX_ENVIRONMENT_GENERIC, 457 | EAX_ENVIRONMENT_PADDEDCELL, 458 | EAX_ENVIRONMENT_ROOM, 459 | EAX_ENVIRONMENT_BATHROOM, 460 | EAX_ENVIRONMENT_LIVINGROOM, 461 | EAX_ENVIRONMENT_STONEROOM, 462 | EAX_ENVIRONMENT_AUDITORIUM, 463 | EAX_ENVIRONMENT_CONCERTHALL, 464 | EAX_ENVIRONMENT_CAVE, 465 | EAX_ENVIRONMENT_ARENA, 466 | EAX_ENVIRONMENT_HANGAR, 467 | EAX_ENVIRONMENT_CARPETEDHALLWAY, 468 | EAX_ENVIRONMENT_HALLWAY, 469 | EAX_ENVIRONMENT_STONECORRIDOR, 470 | EAX_ENVIRONMENT_ALLEY, 471 | EAX_ENVIRONMENT_FOREST, 472 | EAX_ENVIRONMENT_CITY, 473 | EAX_ENVIRONMENT_MOUNTAINS, 474 | EAX_ENVIRONMENT_QUARRY, 475 | EAX_ENVIRONMENT_PLAIN, 476 | EAX_ENVIRONMENT_PARKINGLOT, 477 | EAX_ENVIRONMENT_SEWERPIPE, 478 | EAX_ENVIRONMENT_UNDERWATER, 479 | EAX_ENVIRONMENT_DRUGGED, 480 | EAX_ENVIRONMENT_DIZZY, 481 | EAX_ENVIRONMENT_PSYCHOTIC, 482 | 483 | EAX_ENVIRONMENT_COUNT // total number of environments 484 | }; 485 | 486 | // EAX presets, usage: BASS_SetEAXParameters(EAX_PRESET_xxx) 487 | #define EAX_PRESET_GENERIC EAX_ENVIRONMENT_GENERIC,0.5F,1.493F,0.5F 488 | #define EAX_PRESET_PADDEDCELL EAX_ENVIRONMENT_PADDEDCELL,0.25F,0.1F,0.0F 489 | #define EAX_PRESET_ROOM EAX_ENVIRONMENT_ROOM,0.417F,0.4F,0.666F 490 | #define EAX_PRESET_BATHROOM EAX_ENVIRONMENT_BATHROOM,0.653F,1.499F,0.166F 491 | #define EAX_PRESET_LIVINGROOM EAX_ENVIRONMENT_LIVINGROOM,0.208F,0.478F,0.0F 492 | #define EAX_PRESET_STONEROOM EAX_ENVIRONMENT_STONEROOM,0.5F,2.309F,0.888F 493 | #define EAX_PRESET_AUDITORIUM EAX_ENVIRONMENT_AUDITORIUM,0.403F,4.279F,0.5F 494 | #define EAX_PRESET_CONCERTHALL EAX_ENVIRONMENT_CONCERTHALL,0.5F,3.961F,0.5F 495 | #define EAX_PRESET_CAVE EAX_ENVIRONMENT_CAVE,0.5F,2.886F,1.304F 496 | #define EAX_PRESET_ARENA EAX_ENVIRONMENT_ARENA,0.361F,7.284F,0.332F 497 | #define EAX_PRESET_HANGAR EAX_ENVIRONMENT_HANGAR,0.5F,10.0F,0.3F 498 | #define EAX_PRESET_CARPETEDHALLWAY EAX_ENVIRONMENT_CARPETEDHALLWAY,0.153F,0.259F,2.0F 499 | #define EAX_PRESET_HALLWAY EAX_ENVIRONMENT_HALLWAY,0.361F,1.493F,0.0F 500 | #define EAX_PRESET_STONECORRIDOR EAX_ENVIRONMENT_STONECORRIDOR,0.444F,2.697F,0.638F 501 | #define EAX_PRESET_ALLEY EAX_ENVIRONMENT_ALLEY,0.25F,1.752F,0.776F 502 | #define EAX_PRESET_FOREST EAX_ENVIRONMENT_FOREST,0.111F,3.145F,0.472F 503 | #define EAX_PRESET_CITY EAX_ENVIRONMENT_CITY,0.111F,2.767F,0.224F 504 | #define EAX_PRESET_MOUNTAINS EAX_ENVIRONMENT_MOUNTAINS,0.194F,7.841F,0.472F 505 | #define EAX_PRESET_QUARRY EAX_ENVIRONMENT_QUARRY,1.0F,1.499F,0.5F 506 | #define EAX_PRESET_PLAIN EAX_ENVIRONMENT_PLAIN,0.097F,2.767F,0.224F 507 | #define EAX_PRESET_PARKINGLOT EAX_ENVIRONMENT_PARKINGLOT,0.208F,1.652F,1.5F 508 | #define EAX_PRESET_SEWERPIPE EAX_ENVIRONMENT_SEWERPIPE,0.652F,2.886F,0.25F 509 | #define EAX_PRESET_UNDERWATER EAX_ENVIRONMENT_UNDERWATER,1.0F,1.499F,0.0F 510 | #define EAX_PRESET_DRUGGED EAX_ENVIRONMENT_DRUGGED,0.875F,8.392F,1.388F 511 | #define EAX_PRESET_DIZZY EAX_ENVIRONMENT_DIZZY,0.139F,17.234F,0.666F 512 | #define EAX_PRESET_PSYCHOTIC EAX_ENVIRONMENT_PSYCHOTIC,0.486F,7.563F,0.806F 513 | 514 | typedef DWORD (CALLBACK STREAMPROC)(HSTREAM handle, void *buffer, DWORD length, void *user); 515 | /* User stream callback function. 516 | handle : The stream that needs writing 517 | buffer : Buffer to write the samples in 518 | length : Number of bytes to write 519 | user : The 'user' parameter value given when calling BASS_StreamCreate 520 | RETURN : Number of bytes written. Set the BASS_STREAMPROC_END flag to end the stream. */ 521 | 522 | #define BASS_STREAMPROC_END 0x80000000 // end of user stream flag 523 | 524 | // special STREAMPROCs 525 | #define STREAMPROC_DUMMY (STREAMPROC*)0 // "dummy" stream 526 | #define STREAMPROC_PUSH (STREAMPROC*)-1 // push stream 527 | #define STREAMPROC_DEVICE (STREAMPROC*)-2 // device mix stream 528 | #define STREAMPROC_DEVICE_3D (STREAMPROC*)-3 // device 3D mix stream 529 | 530 | // BASS_StreamCreateFileUser file systems 531 | #define STREAMFILE_NOBUFFER 0 532 | #define STREAMFILE_BUFFER 1 533 | #define STREAMFILE_BUFFERPUSH 2 534 | 535 | // User file stream callback functions 536 | typedef void (CALLBACK FILECLOSEPROC)(void *user); 537 | typedef QWORD (CALLBACK FILELENPROC)(void *user); 538 | typedef DWORD (CALLBACK FILEREADPROC)(void *buffer, DWORD length, void *user); 539 | typedef BOOL (CALLBACK FILESEEKPROC)(QWORD offset, void *user); 540 | 541 | typedef struct { 542 | FILECLOSEPROC *close; 543 | FILELENPROC *length; 544 | FILEREADPROC *read; 545 | FILESEEKPROC *seek; 546 | } BASS_FILEPROCS; 547 | 548 | // BASS_StreamPutFileData options 549 | #define BASS_FILEDATA_END 0 // end & close the file 550 | 551 | // BASS_StreamGetFilePosition modes 552 | #define BASS_FILEPOS_CURRENT 0 553 | #define BASS_FILEPOS_DECODE BASS_FILEPOS_CURRENT 554 | #define BASS_FILEPOS_DOWNLOAD 1 555 | #define BASS_FILEPOS_END 2 556 | #define BASS_FILEPOS_START 3 557 | #define BASS_FILEPOS_CONNECTED 4 558 | #define BASS_FILEPOS_BUFFER 5 559 | #define BASS_FILEPOS_SOCKET 6 560 | #define BASS_FILEPOS_ASYNCBUF 7 561 | #define BASS_FILEPOS_SIZE 8 562 | #define BASS_FILEPOS_BUFFERING 9 563 | 564 | typedef void (CALLBACK DOWNLOADPROC)(const void *buffer, DWORD length, void *user); 565 | /* Internet stream download callback function. 566 | buffer : Buffer containing the downloaded data... NULL=end of download 567 | length : Number of bytes in the buffer 568 | user : The 'user' parameter value given when calling BASS_StreamCreateURL */ 569 | 570 | // BASS_ChannelSetSync types 571 | #define BASS_SYNC_POS 0 572 | #define BASS_SYNC_END 2 573 | #define BASS_SYNC_META 4 574 | #define BASS_SYNC_SLIDE 5 575 | #define BASS_SYNC_STALL 6 576 | #define BASS_SYNC_DOWNLOAD 7 577 | #define BASS_SYNC_FREE 8 578 | #define BASS_SYNC_SETPOS 11 579 | #define BASS_SYNC_MUSICPOS 10 580 | #define BASS_SYNC_MUSICINST 1 581 | #define BASS_SYNC_MUSICFX 3 582 | #define BASS_SYNC_OGG_CHANGE 12 583 | #define BASS_SYNC_DEV_FAIL 14 584 | #define BASS_SYNC_DEV_FORMAT 15 585 | #define BASS_SYNC_THREAD 0x20000000 // flag: call sync in other thread 586 | #define BASS_SYNC_MIXTIME 0x40000000 // flag: sync at mixtime, else at playtime 587 | #define BASS_SYNC_ONETIME 0x80000000 // flag: sync only once, else continuously 588 | 589 | typedef void (CALLBACK SYNCPROC)(HSYNC handle, DWORD channel, DWORD data, void *user); 590 | /* Sync callback function. 591 | handle : The sync that has occured 592 | channel: Channel that the sync occured in 593 | data : Additional data associated with the sync's occurance 594 | user : The 'user' parameter given when calling BASS_ChannelSetSync */ 595 | 596 | typedef void (CALLBACK DSPPROC)(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user); 597 | /* DSP callback function. 598 | handle : The DSP handle 599 | channel: Channel that the DSP is being applied to 600 | buffer : Buffer to apply the DSP to 601 | length : Number of bytes in the buffer 602 | user : The 'user' parameter given when calling BASS_ChannelSetDSP */ 603 | 604 | typedef BOOL (CALLBACK RECORDPROC)(HRECORD handle, const void *buffer, DWORD length, void *user); 605 | /* Recording callback function. 606 | handle : The recording handle 607 | buffer : Buffer containing the recorded sample data 608 | length : Number of bytes 609 | user : The 'user' parameter value given when calling BASS_RecordStart 610 | RETURN : TRUE = continue recording, FALSE = stop */ 611 | 612 | // BASS_ChannelIsActive return values 613 | #define BASS_ACTIVE_STOPPED 0 614 | #define BASS_ACTIVE_PLAYING 1 615 | #define BASS_ACTIVE_STALLED 2 616 | #define BASS_ACTIVE_PAUSED 3 617 | #define BASS_ACTIVE_PAUSED_DEVICE 4 618 | 619 | // Channel attributes 620 | #define BASS_ATTRIB_FREQ 1 621 | #define BASS_ATTRIB_VOL 2 622 | #define BASS_ATTRIB_PAN 3 623 | #define BASS_ATTRIB_EAXMIX 4 624 | #define BASS_ATTRIB_NOBUFFER 5 625 | #define BASS_ATTRIB_VBR 6 626 | #define BASS_ATTRIB_CPU 7 627 | #define BASS_ATTRIB_SRC 8 628 | #define BASS_ATTRIB_NET_RESUME 9 629 | #define BASS_ATTRIB_SCANINFO 10 630 | #define BASS_ATTRIB_NORAMP 11 631 | #define BASS_ATTRIB_BITRATE 12 632 | #define BASS_ATTRIB_BUFFER 13 633 | #define BASS_ATTRIB_GRANULE 14 634 | #define BASS_ATTRIB_MUSIC_AMPLIFY 0x100 635 | #define BASS_ATTRIB_MUSIC_PANSEP 0x101 636 | #define BASS_ATTRIB_MUSIC_PSCALER 0x102 637 | #define BASS_ATTRIB_MUSIC_BPM 0x103 638 | #define BASS_ATTRIB_MUSIC_SPEED 0x104 639 | #define BASS_ATTRIB_MUSIC_VOL_GLOBAL 0x105 640 | #define BASS_ATTRIB_MUSIC_ACTIVE 0x106 641 | #define BASS_ATTRIB_MUSIC_VOL_CHAN 0x200 // + channel # 642 | #define BASS_ATTRIB_MUSIC_VOL_INST 0x300 // + instrument # 643 | 644 | // BASS_ChannelSlideAttribute flags 645 | #define BASS_SLIDE_LOG 0x1000000 646 | 647 | // BASS_ChannelGetData flags 648 | #define BASS_DATA_AVAILABLE 0 // query how much data is buffered 649 | #define BASS_DATA_FIXED 0x20000000 // flag: return 8.24 fixed-point data 650 | #define BASS_DATA_FLOAT 0x40000000 // flag: return floating-point sample data 651 | #define BASS_DATA_FFT256 0x80000000 // 256 sample FFT 652 | #define BASS_DATA_FFT512 0x80000001 // 512 FFT 653 | #define BASS_DATA_FFT1024 0x80000002 // 1024 FFT 654 | #define BASS_DATA_FFT2048 0x80000003 // 2048 FFT 655 | #define BASS_DATA_FFT4096 0x80000004 // 4096 FFT 656 | #define BASS_DATA_FFT8192 0x80000005 // 8192 FFT 657 | #define BASS_DATA_FFT16384 0x80000006 // 16384 FFT 658 | #define BASS_DATA_FFT32768 0x80000007 // 32768 FFT 659 | #define BASS_DATA_FFT_INDIVIDUAL 0x10 // FFT flag: FFT for each channel, else all combined 660 | #define BASS_DATA_FFT_NOWINDOW 0x20 // FFT flag: no Hanning window 661 | #define BASS_DATA_FFT_REMOVEDC 0x40 // FFT flag: pre-remove DC bias 662 | #define BASS_DATA_FFT_COMPLEX 0x80 // FFT flag: return complex data 663 | #define BASS_DATA_FFT_NYQUIST 0x100 // FFT flag: return extra Nyquist value 664 | 665 | // BASS_ChannelGetLevelEx flags 666 | #define BASS_LEVEL_MONO 1 667 | #define BASS_LEVEL_STEREO 2 668 | #define BASS_LEVEL_RMS 4 669 | #define BASS_LEVEL_VOLPAN 8 670 | 671 | // BASS_ChannelGetTags types : what's returned 672 | #define BASS_TAG_ID3 0 // ID3v1 tags : TAG_ID3 structure 673 | #define BASS_TAG_ID3V2 1 // ID3v2 tags : variable length block 674 | #define BASS_TAG_OGG 2 // OGG comments : series of null-terminated UTF-8 strings 675 | #define BASS_TAG_HTTP 3 // HTTP headers : series of null-terminated ANSI strings 676 | #define BASS_TAG_ICY 4 // ICY headers : series of null-terminated ANSI strings 677 | #define BASS_TAG_META 5 // ICY metadata : ANSI string 678 | #define BASS_TAG_APE 6 // APE tags : series of null-terminated UTF-8 strings 679 | #define BASS_TAG_MP4 7 // MP4/iTunes metadata : series of null-terminated UTF-8 strings 680 | #define BASS_TAG_WMA 8 // WMA tags : series of null-terminated UTF-8 strings 681 | #define BASS_TAG_VENDOR 9 // OGG encoder : UTF-8 string 682 | #define BASS_TAG_LYRICS3 10 // Lyric3v2 tag : ASCII string 683 | #define BASS_TAG_CA_CODEC 11 // CoreAudio codec info : TAG_CA_CODEC structure 684 | #define BASS_TAG_MF 13 // Media Foundation tags : series of null-terminated UTF-8 strings 685 | #define BASS_TAG_WAVEFORMAT 14 // WAVE format : WAVEFORMATEEX structure 686 | #define BASS_TAG_AM_MIME 15 // Android Media MIME type : ASCII string 687 | #define BASS_TAG_AM_NAME 16 // Android Media codec name : ASCII string 688 | #define BASS_TAG_RIFF_INFO 0x100 // RIFF "INFO" tags : series of null-terminated ANSI strings 689 | #define BASS_TAG_RIFF_BEXT 0x101 // RIFF/BWF "bext" tags : TAG_BEXT structure 690 | #define BASS_TAG_RIFF_CART 0x102 // RIFF/BWF "cart" tags : TAG_CART structure 691 | #define BASS_TAG_RIFF_DISP 0x103 // RIFF "DISP" text tag : ANSI string 692 | #define BASS_TAG_RIFF_CUE 0x104 // RIFF "cue " chunk : TAG_CUE structure 693 | #define BASS_TAG_RIFF_SMPL 0x105 // RIFF "smpl" chunk : TAG_SMPL structure 694 | #define BASS_TAG_APE_BINARY 0x1000 // + index #, binary APE tag : TAG_APE_BINARY structure 695 | #define BASS_TAG_MUSIC_NAME 0x10000 // MOD music name : ANSI string 696 | #define BASS_TAG_MUSIC_MESSAGE 0x10001 // MOD message : ANSI string 697 | #define BASS_TAG_MUSIC_ORDERS 0x10002 // MOD order list : BYTE array of pattern numbers 698 | #define BASS_TAG_MUSIC_AUTH 0x10003 // MOD author : UTF-8 string 699 | #define BASS_TAG_MUSIC_INST 0x10100 // + instrument #, MOD instrument name : ANSI string 700 | #define BASS_TAG_MUSIC_SAMPLE 0x10300 // + sample #, MOD sample name : ANSI string 701 | 702 | // ID3v1 tag structure 703 | typedef struct { 704 | char id[3]; 705 | char title[30]; 706 | char artist[30]; 707 | char album[30]; 708 | char year[4]; 709 | char comment[30]; 710 | BYTE genre; 711 | } TAG_ID3; 712 | 713 | // Binary APE tag structure 714 | typedef struct { 715 | const char *key; 716 | const void *data; 717 | DWORD length; 718 | } TAG_APE_BINARY; 719 | 720 | // BWF "bext" tag structure 721 | #ifdef _MSC_VER 722 | #pragma warning(push) 723 | #pragma warning(disable:4200) 724 | #endif 725 | #pragma pack(push,1) 726 | typedef struct { 727 | char Description[256]; // description 728 | char Originator[32]; // name of the originator 729 | char OriginatorReference[32]; // reference of the originator 730 | char OriginationDate[10]; // date of creation (yyyy-mm-dd) 731 | char OriginationTime[8]; // time of creation (hh-mm-ss) 732 | QWORD TimeReference; // first sample count since midnight (little-endian) 733 | WORD Version; // BWF version (little-endian) 734 | BYTE UMID[64]; // SMPTE UMID 735 | BYTE Reserved[190]; 736 | #if defined(__GNUC__) && __GNUC__<3 737 | char CodingHistory[0]; // history 738 | #elif 1 // change to 0 if compiler fails the following line 739 | char CodingHistory[]; // history 740 | #else 741 | char CodingHistory[1]; // history 742 | #endif 743 | } TAG_BEXT; 744 | #pragma pack(pop) 745 | 746 | // BWF "cart" tag structures 747 | typedef struct 748 | { 749 | DWORD dwUsage; // FOURCC timer usage ID 750 | DWORD dwValue; // timer value in samples from head 751 | } TAG_CART_TIMER; 752 | 753 | typedef struct 754 | { 755 | char Version[4]; // version of the data structure 756 | char Title[64]; // title of cart audio sequence 757 | char Artist[64]; // artist or creator name 758 | char CutID[64]; // cut number identification 759 | char ClientID[64]; // client identification 760 | char Category[64]; // category ID, PSA, NEWS, etc 761 | char Classification[64]; // classification or auxiliary key 762 | char OutCue[64]; // out cue text 763 | char StartDate[10]; // yyyy-mm-dd 764 | char StartTime[8]; // hh:mm:ss 765 | char EndDate[10]; // yyyy-mm-dd 766 | char EndTime[8]; // hh:mm:ss 767 | char ProducerAppID[64]; // name of vendor or application 768 | char ProducerAppVersion[64]; // version of producer application 769 | char UserDef[64]; // user defined text 770 | DWORD dwLevelReference; // sample value for 0 dB reference 771 | TAG_CART_TIMER PostTimer[8]; // 8 time markers after head 772 | char Reserved[276]; 773 | char URL[1024]; // uniform resource locator 774 | #if defined(__GNUC__) && __GNUC__<3 775 | char TagText[0]; // free form text for scripts or tags 776 | #elif 1 // change to 0 if compiler fails the following line 777 | char TagText[]; // free form text for scripts or tags 778 | #else 779 | char TagText[1]; // free form text for scripts or tags 780 | #endif 781 | } TAG_CART; 782 | 783 | // RIFF "cue " tag structures 784 | typedef struct 785 | { 786 | DWORD dwName; 787 | DWORD dwPosition; 788 | DWORD fccChunk; 789 | DWORD dwChunkStart; 790 | DWORD dwBlockStart; 791 | DWORD dwSampleOffset; 792 | } TAG_CUE_POINT; 793 | 794 | typedef struct 795 | { 796 | DWORD dwCuePoints; 797 | #if defined(__GNUC__) && __GNUC__<3 798 | TAG_CUE_POINT CuePoints[0]; 799 | #elif 1 // change to 0 if compiler fails the following line 800 | TAG_CUE_POINT CuePoints[]; 801 | #else 802 | TAG_CUE_POINT CuePoints[1]; 803 | #endif 804 | } TAG_CUE; 805 | 806 | // RIFF "smpl" tag structures 807 | typedef struct 808 | { 809 | DWORD dwIdentifier; 810 | DWORD dwType; 811 | DWORD dwStart; 812 | DWORD dwEnd; 813 | DWORD dwFraction; 814 | DWORD dwPlayCount; 815 | } TAG_SMPL_LOOP; 816 | 817 | typedef struct 818 | { 819 | DWORD dwManufacturer; 820 | DWORD dwProduct; 821 | DWORD dwSamplePeriod; 822 | DWORD dwMIDIUnityNote; 823 | DWORD dwMIDIPitchFraction; 824 | DWORD dwSMPTEFormat; 825 | DWORD dwSMPTEOffset; 826 | DWORD cSampleLoops; 827 | DWORD cbSamplerData; 828 | #if defined(__GNUC__) && __GNUC__<3 829 | TAG_SMPL_LOOP SampleLoops[0]; 830 | #elif 1 // change to 0 if compiler fails the following line 831 | TAG_SMPL_LOOP SampleLoops[]; 832 | #else 833 | TAG_SMPL_LOOP SampleLoops[1]; 834 | #endif 835 | } TAG_SMPL; 836 | #ifdef _MSC_VER 837 | #pragma warning(pop) 838 | #endif 839 | 840 | // CoreAudio codec info structure 841 | typedef struct { 842 | DWORD ftype; // file format 843 | DWORD atype; // audio format 844 | const char *name; // description 845 | } TAG_CA_CODEC; 846 | 847 | #ifndef _WAVEFORMATEX_ 848 | #define _WAVEFORMATEX_ 849 | #pragma pack(push,1) 850 | typedef struct tWAVEFORMATEX 851 | { 852 | WORD wFormatTag; 853 | WORD nChannels; 854 | DWORD nSamplesPerSec; 855 | DWORD nAvgBytesPerSec; 856 | WORD nBlockAlign; 857 | WORD wBitsPerSample; 858 | WORD cbSize; 859 | } WAVEFORMATEX, *PWAVEFORMATEX, *LPWAVEFORMATEX; 860 | typedef const WAVEFORMATEX *LPCWAVEFORMATEX; 861 | #pragma pack(pop) 862 | #endif 863 | 864 | // BASS_ChannelGetLength/GetPosition/SetPosition modes 865 | #define BASS_POS_BYTE 0 // byte position 866 | #define BASS_POS_MUSIC_ORDER 1 // order.row position, MAKELONG(order,row) 867 | #define BASS_POS_OGG 3 // OGG bitstream number 868 | #define BASS_POS_RESET 0x2000000 // flag: reset user file buffers 869 | #define BASS_POS_RELATIVE 0x4000000 // flag: seek relative to the current position 870 | #define BASS_POS_INEXACT 0x8000000 // flag: allow seeking to inexact position 871 | #define BASS_POS_DECODE 0x10000000 // flag: get the decoding (not playing) position 872 | #define BASS_POS_DECODETO 0x20000000 // flag: decode to the position instead of seeking 873 | #define BASS_POS_SCAN 0x40000000 // flag: scan to the position 874 | 875 | // BASS_ChannelSetDevice/GetDevice option 876 | #define BASS_NODEVICE 0x20000 877 | 878 | // BASS_RecordSetInput flags 879 | #define BASS_INPUT_OFF 0x10000 880 | #define BASS_INPUT_ON 0x20000 881 | 882 | #define BASS_INPUT_TYPE_MASK 0xff000000 883 | #define BASS_INPUT_TYPE_UNDEF 0x00000000 884 | #define BASS_INPUT_TYPE_DIGITAL 0x01000000 885 | #define BASS_INPUT_TYPE_LINE 0x02000000 886 | #define BASS_INPUT_TYPE_MIC 0x03000000 887 | #define BASS_INPUT_TYPE_SYNTH 0x04000000 888 | #define BASS_INPUT_TYPE_CD 0x05000000 889 | #define BASS_INPUT_TYPE_PHONE 0x06000000 890 | #define BASS_INPUT_TYPE_SPEAKER 0x07000000 891 | #define BASS_INPUT_TYPE_WAVE 0x08000000 892 | #define BASS_INPUT_TYPE_AUX 0x09000000 893 | #define BASS_INPUT_TYPE_ANALOG 0x0a000000 894 | 895 | // BASS_ChannelSetFX effect types 896 | #define BASS_FX_DX8_CHORUS 0 897 | #define BASS_FX_DX8_COMPRESSOR 1 898 | #define BASS_FX_DX8_DISTORTION 2 899 | #define BASS_FX_DX8_ECHO 3 900 | #define BASS_FX_DX8_FLANGER 4 901 | #define BASS_FX_DX8_GARGLE 5 902 | #define BASS_FX_DX8_I3DL2REVERB 6 903 | #define BASS_FX_DX8_PARAMEQ 7 904 | #define BASS_FX_DX8_REVERB 8 905 | #define BASS_FX_VOLUME 9 906 | 907 | typedef struct { 908 | float fWetDryMix; 909 | float fDepth; 910 | float fFeedback; 911 | float fFrequency; 912 | DWORD lWaveform; // 0=triangle, 1=sine 913 | float fDelay; 914 | DWORD lPhase; // BASS_DX8_PHASE_xxx 915 | } BASS_DX8_CHORUS; 916 | 917 | typedef struct { 918 | float fGain; 919 | float fAttack; 920 | float fRelease; 921 | float fThreshold; 922 | float fRatio; 923 | float fPredelay; 924 | } BASS_DX8_COMPRESSOR; 925 | 926 | typedef struct { 927 | float fGain; 928 | float fEdge; 929 | float fPostEQCenterFrequency; 930 | float fPostEQBandwidth; 931 | float fPreLowpassCutoff; 932 | } BASS_DX8_DISTORTION; 933 | 934 | typedef struct { 935 | float fWetDryMix; 936 | float fFeedback; 937 | float fLeftDelay; 938 | float fRightDelay; 939 | BOOL lPanDelay; 940 | } BASS_DX8_ECHO; 941 | 942 | typedef struct { 943 | float fWetDryMix; 944 | float fDepth; 945 | float fFeedback; 946 | float fFrequency; 947 | DWORD lWaveform; // 0=triangle, 1=sine 948 | float fDelay; 949 | DWORD lPhase; // BASS_DX8_PHASE_xxx 950 | } BASS_DX8_FLANGER; 951 | 952 | typedef struct { 953 | DWORD dwRateHz; // Rate of modulation in hz 954 | DWORD dwWaveShape; // 0=triangle, 1=square 955 | } BASS_DX8_GARGLE; 956 | 957 | typedef struct { 958 | int lRoom; // [-10000, 0] default: -1000 mB 959 | int lRoomHF; // [-10000, 0] default: 0 mB 960 | float flRoomRolloffFactor; // [0.0, 10.0] default: 0.0 961 | float flDecayTime; // [0.1, 20.0] default: 1.49s 962 | float flDecayHFRatio; // [0.1, 2.0] default: 0.83 963 | int lReflections; // [-10000, 1000] default: -2602 mB 964 | float flReflectionsDelay; // [0.0, 0.3] default: 0.007 s 965 | int lReverb; // [-10000, 2000] default: 200 mB 966 | float flReverbDelay; // [0.0, 0.1] default: 0.011 s 967 | float flDiffusion; // [0.0, 100.0] default: 100.0 % 968 | float flDensity; // [0.0, 100.0] default: 100.0 % 969 | float flHFReference; // [20.0, 20000.0] default: 5000.0 Hz 970 | } BASS_DX8_I3DL2REVERB; 971 | 972 | typedef struct { 973 | float fCenter; 974 | float fBandwidth; 975 | float fGain; 976 | } BASS_DX8_PARAMEQ; 977 | 978 | typedef struct { 979 | float fInGain; // [-96.0,0.0] default: 0.0 dB 980 | float fReverbMix; // [-96.0,0.0] default: 0.0 db 981 | float fReverbTime; // [0.001,3000.0] default: 1000.0 ms 982 | float fHighFreqRTRatio; // [0.001,0.999] default: 0.001 983 | } BASS_DX8_REVERB; 984 | 985 | #define BASS_DX8_PHASE_NEG_180 0 986 | #define BASS_DX8_PHASE_NEG_90 1 987 | #define BASS_DX8_PHASE_ZERO 2 988 | #define BASS_DX8_PHASE_90 3 989 | #define BASS_DX8_PHASE_180 4 990 | 991 | typedef struct { 992 | float fTarget; 993 | float fCurrent; 994 | float fTime; 995 | DWORD lCurve; 996 | } BASS_FX_VOLUME_PARAM; 997 | 998 | typedef void (CALLBACK IOSNOTIFYPROC)(DWORD status); 999 | /* iOS notification callback function. 1000 | status : The notification (BASS_IOSNOTIFY_xxx) */ 1001 | 1002 | #define BASS_IOSNOTIFY_INTERRUPT 1 // interruption started 1003 | #define BASS_IOSNOTIFY_INTERRUPT_END 2 // interruption ended 1004 | 1005 | BOOL BASSDEF(BASS_SetConfig)(DWORD option, DWORD value); 1006 | DWORD BASSDEF(BASS_GetConfig)(DWORD option); 1007 | BOOL BASSDEF(BASS_SetConfigPtr)(DWORD option, const void *value); 1008 | void *BASSDEF(BASS_GetConfigPtr)(DWORD option); 1009 | DWORD BASSDEF(BASS_GetVersion)(); 1010 | int BASSDEF(BASS_ErrorGetCode)(); 1011 | BOOL BASSDEF(BASS_GetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info); 1012 | #if defined(_WIN32) && !defined(_WIN32_WCE) && !(WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) 1013 | BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, HWND win, const GUID *dsguid); 1014 | #else 1015 | BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, void *win, void *dsguid); 1016 | #endif 1017 | BOOL BASSDEF(BASS_SetDevice)(DWORD device); 1018 | DWORD BASSDEF(BASS_GetDevice)(); 1019 | BOOL BASSDEF(BASS_Free)(); 1020 | #if defined(_WIN32) && !defined(_WIN32_WCE) && !(WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) 1021 | void *BASSDEF(BASS_GetDSoundObject)(DWORD object); 1022 | #endif 1023 | BOOL BASSDEF(BASS_GetInfo)(BASS_INFO *info); 1024 | BOOL BASSDEF(BASS_Update)(DWORD length); 1025 | float BASSDEF(BASS_GetCPU)(); 1026 | BOOL BASSDEF(BASS_Start)(); 1027 | BOOL BASSDEF(BASS_Stop)(); 1028 | BOOL BASSDEF(BASS_Pause)(); 1029 | BOOL BASSDEF(BASS_IsStarted)(); 1030 | BOOL BASSDEF(BASS_SetVolume)(float volume); 1031 | float BASSDEF(BASS_GetVolume)(); 1032 | 1033 | HPLUGIN BASSDEF(BASS_PluginLoad)(const char *file, DWORD flags); 1034 | BOOL BASSDEF(BASS_PluginFree)(HPLUGIN handle); 1035 | const BASS_PLUGININFO *BASSDEF(BASS_PluginGetInfo)(HPLUGIN handle); 1036 | 1037 | BOOL BASSDEF(BASS_Set3DFactors)(float distf, float rollf, float doppf); 1038 | BOOL BASSDEF(BASS_Get3DFactors)(float *distf, float *rollf, float *doppf); 1039 | BOOL BASSDEF(BASS_Set3DPosition)(const BASS_3DVECTOR *pos, const BASS_3DVECTOR *vel, const BASS_3DVECTOR *front, const BASS_3DVECTOR *top); 1040 | BOOL BASSDEF(BASS_Get3DPosition)(BASS_3DVECTOR *pos, BASS_3DVECTOR *vel, BASS_3DVECTOR *front, BASS_3DVECTOR *top); 1041 | void BASSDEF(BASS_Apply3D)(); 1042 | #if defined(_WIN32) && !defined(_WIN32_WCE) && !(WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) 1043 | BOOL BASSDEF(BASS_SetEAXParameters)(int env, float vol, float decay, float damp); 1044 | BOOL BASSDEF(BASS_GetEAXParameters)(DWORD *env, float *vol, float *decay, float *damp); 1045 | #endif 1046 | 1047 | HMUSIC BASSDEF(BASS_MusicLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD flags, DWORD freq); 1048 | BOOL BASSDEF(BASS_MusicFree)(HMUSIC handle); 1049 | 1050 | HSAMPLE BASSDEF(BASS_SampleLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD max, DWORD flags); 1051 | HSAMPLE BASSDEF(BASS_SampleCreate)(DWORD length, DWORD freq, DWORD chans, DWORD max, DWORD flags); 1052 | BOOL BASSDEF(BASS_SampleFree)(HSAMPLE handle); 1053 | BOOL BASSDEF(BASS_SampleSetData)(HSAMPLE handle, const void *buffer); 1054 | BOOL BASSDEF(BASS_SampleGetData)(HSAMPLE handle, void *buffer); 1055 | BOOL BASSDEF(BASS_SampleGetInfo)(HSAMPLE handle, BASS_SAMPLE *info); 1056 | BOOL BASSDEF(BASS_SampleSetInfo)(HSAMPLE handle, const BASS_SAMPLE *info); 1057 | HCHANNEL BASSDEF(BASS_SampleGetChannel)(HSAMPLE handle, BOOL onlynew); 1058 | DWORD BASSDEF(BASS_SampleGetChannels)(HSAMPLE handle, HCHANNEL *channels); 1059 | BOOL BASSDEF(BASS_SampleStop)(HSAMPLE handle); 1060 | 1061 | HSTREAM BASSDEF(BASS_StreamCreate)(DWORD freq, DWORD chans, DWORD flags, STREAMPROC *proc, void *user); 1062 | HSTREAM BASSDEF(BASS_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags); 1063 | HSTREAM BASSDEF(BASS_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user); 1064 | HSTREAM BASSDEF(BASS_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *proc, void *user); 1065 | BOOL BASSDEF(BASS_StreamFree)(HSTREAM handle); 1066 | QWORD BASSDEF(BASS_StreamGetFilePosition)(HSTREAM handle, DWORD mode); 1067 | DWORD BASSDEF(BASS_StreamPutData)(HSTREAM handle, const void *buffer, DWORD length); 1068 | DWORD BASSDEF(BASS_StreamPutFileData)(HSTREAM handle, const void *buffer, DWORD length); 1069 | 1070 | BOOL BASSDEF(BASS_RecordGetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info); 1071 | BOOL BASSDEF(BASS_RecordInit)(int device); 1072 | BOOL BASSDEF(BASS_RecordSetDevice)(DWORD device); 1073 | DWORD BASSDEF(BASS_RecordGetDevice)(); 1074 | BOOL BASSDEF(BASS_RecordFree)(); 1075 | BOOL BASSDEF(BASS_RecordGetInfo)(BASS_RECORDINFO *info); 1076 | const char *BASSDEF(BASS_RecordGetInputName)(int input); 1077 | BOOL BASSDEF(BASS_RecordSetInput)(int input, DWORD flags, float volume); 1078 | DWORD BASSDEF(BASS_RecordGetInput)(int input, float *volume); 1079 | HRECORD BASSDEF(BASS_RecordStart)(DWORD freq, DWORD chans, DWORD flags, RECORDPROC *proc, void *user); 1080 | 1081 | double BASSDEF(BASS_ChannelBytes2Seconds)(DWORD handle, QWORD pos); 1082 | QWORD BASSDEF(BASS_ChannelSeconds2Bytes)(DWORD handle, double pos); 1083 | DWORD BASSDEF(BASS_ChannelGetDevice)(DWORD handle); 1084 | BOOL BASSDEF(BASS_ChannelSetDevice)(DWORD handle, DWORD device); 1085 | DWORD BASSDEF(BASS_ChannelIsActive)(DWORD handle); 1086 | BOOL BASSDEF(BASS_ChannelGetInfo)(DWORD handle, BASS_CHANNELINFO *info); 1087 | const char *BASSDEF(BASS_ChannelGetTags)(DWORD handle, DWORD tags); 1088 | DWORD BASSDEF(BASS_ChannelFlags)(DWORD handle, DWORD flags, DWORD mask); 1089 | BOOL BASSDEF(BASS_ChannelUpdate)(DWORD handle, DWORD length); 1090 | BOOL BASSDEF(BASS_ChannelLock)(DWORD handle, BOOL lock); 1091 | BOOL BASSDEF(BASS_ChannelPlay)(DWORD handle, BOOL restart); 1092 | BOOL BASSDEF(BASS_ChannelStop)(DWORD handle); 1093 | BOOL BASSDEF(BASS_ChannelPause)(DWORD handle); 1094 | BOOL BASSDEF(BASS_ChannelSetAttribute)(DWORD handle, DWORD attrib, float value); 1095 | BOOL BASSDEF(BASS_ChannelGetAttribute)(DWORD handle, DWORD attrib, float *value); 1096 | BOOL BASSDEF(BASS_ChannelSlideAttribute)(DWORD handle, DWORD attrib, float value, DWORD time); 1097 | BOOL BASSDEF(BASS_ChannelIsSliding)(DWORD handle, DWORD attrib); 1098 | BOOL BASSDEF(BASS_ChannelSetAttributeEx)(DWORD handle, DWORD attrib, void *value, DWORD size); 1099 | DWORD BASSDEF(BASS_ChannelGetAttributeEx)(DWORD handle, DWORD attrib, void *value, DWORD size); 1100 | BOOL BASSDEF(BASS_ChannelSet3DAttributes)(DWORD handle, int mode, float min, float max, int iangle, int oangle, float outvol); 1101 | BOOL BASSDEF(BASS_ChannelGet3DAttributes)(DWORD handle, DWORD *mode, float *min, float *max, DWORD *iangle, DWORD *oangle, float *outvol); 1102 | BOOL BASSDEF(BASS_ChannelSet3DPosition)(DWORD handle, const BASS_3DVECTOR *pos, const BASS_3DVECTOR *orient, const BASS_3DVECTOR *vel); 1103 | BOOL BASSDEF(BASS_ChannelGet3DPosition)(DWORD handle, BASS_3DVECTOR *pos, BASS_3DVECTOR *orient, BASS_3DVECTOR *vel); 1104 | QWORD BASSDEF(BASS_ChannelGetLength)(DWORD handle, DWORD mode); 1105 | BOOL BASSDEF(BASS_ChannelSetPosition)(DWORD handle, QWORD pos, DWORD mode); 1106 | QWORD BASSDEF(BASS_ChannelGetPosition)(DWORD handle, DWORD mode); 1107 | DWORD BASSDEF(BASS_ChannelGetLevel)(DWORD handle); 1108 | BOOL BASSDEF(BASS_ChannelGetLevelEx)(DWORD handle, float *levels, float length, DWORD flags); 1109 | DWORD BASSDEF(BASS_ChannelGetData)(DWORD handle, void *buffer, DWORD length); 1110 | HSYNC BASSDEF(BASS_ChannelSetSync)(DWORD handle, DWORD type, QWORD param, SYNCPROC *proc, void *user); 1111 | BOOL BASSDEF(BASS_ChannelRemoveSync)(DWORD handle, HSYNC sync); 1112 | HDSP BASSDEF(BASS_ChannelSetDSP)(DWORD handle, DSPPROC *proc, void *user, int priority); 1113 | BOOL BASSDEF(BASS_ChannelRemoveDSP)(DWORD handle, HDSP dsp); 1114 | BOOL BASSDEF(BASS_ChannelSetLink)(DWORD handle, DWORD chan); 1115 | BOOL BASSDEF(BASS_ChannelRemoveLink)(DWORD handle, DWORD chan); 1116 | HFX BASSDEF(BASS_ChannelSetFX)(DWORD handle, DWORD type, int priority); 1117 | BOOL BASSDEF(BASS_ChannelRemoveFX)(DWORD handle, HFX fx); 1118 | 1119 | BOOL BASSDEF(BASS_FXSetParameters)(HFX handle, const void *params); 1120 | BOOL BASSDEF(BASS_FXGetParameters)(HFX handle, void *params); 1121 | BOOL BASSDEF(BASS_FXReset)(HFX handle); 1122 | BOOL BASSDEF(BASS_FXSetPriority)(HFX handle, int priority); 1123 | 1124 | #ifdef __cplusplus 1125 | } 1126 | 1127 | #if defined(_WIN32) && !defined(NOBASSOVERLOADS) 1128 | static inline HPLUGIN BASS_PluginLoad(const WCHAR *file, DWORD flags) 1129 | { 1130 | return BASS_PluginLoad((const char*)file, flags|BASS_UNICODE); 1131 | } 1132 | 1133 | static inline HMUSIC BASS_MusicLoad(BOOL mem, const WCHAR *file, QWORD offset, DWORD length, DWORD flags, DWORD freq) 1134 | { 1135 | return BASS_MusicLoad(mem, (const void*)file, offset, length, flags|BASS_UNICODE, freq); 1136 | } 1137 | 1138 | static inline HSAMPLE BASS_SampleLoad(BOOL mem, const WCHAR *file, QWORD offset, DWORD length, DWORD max, DWORD flags) 1139 | { 1140 | return BASS_SampleLoad(mem, (const void*)file, offset, length, max, flags|BASS_UNICODE); 1141 | } 1142 | 1143 | static inline HSTREAM BASS_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags) 1144 | { 1145 | return BASS_StreamCreateFile(mem, (const void*)file, offset, length, flags|BASS_UNICODE); 1146 | } 1147 | 1148 | static inline HSTREAM BASS_StreamCreateURL(const WCHAR *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user) 1149 | { 1150 | return BASS_StreamCreateURL((const char*)url, offset, flags|BASS_UNICODE, proc, user); 1151 | } 1152 | 1153 | static inline BOOL BASS_SetConfigPtr(DWORD option, const WCHAR *value) 1154 | { 1155 | return BASS_SetConfigPtr(option|BASS_UNICODE, (const void*)value); 1156 | } 1157 | #endif 1158 | #endif 1159 | 1160 | #endif 1161 | -------------------------------------------------------------------------------- /bass/const.go: -------------------------------------------------------------------------------- 1 | package bass 2 | 3 | /* 4 | #cgo CFLAGS: -I/usr/include -I. 5 | #cgo darwin LDFLAGS: -L${SRCDIR}/../libs -lbass 6 | #include "bass.h" 7 | */ 8 | import "C" 9 | 10 | type Error struct { 11 | Err error 12 | Code ErrorCode 13 | } 14 | 15 | const musicRamps int = C.BASS_MUSIC_RAMPS 16 | const musicPreScan int = C.BASS_MUSIC_PRESCAN 17 | const streamAutoFree int = C.BASS_STREAM_AUTOFREE 18 | const streamGetData int = C.BASS_STREAM_DECODE 19 | const posReset int = C.BASS_MUSIC_POSRESET 20 | const posResetEx int = C.BASS_MUSIC_POSRESETEX 21 | 22 | type ChannelStatus int 23 | 24 | const ( 25 | ChannelStatusStopped ChannelStatus = C.BASS_ACTIVE_STOPPED 26 | ChannelStatusPlaying ChannelStatus = C.BASS_ACTIVE_PLAYING 27 | ChannelStatusStalled ChannelStatus = C.BASS_ACTIVE_STALLED 28 | ChannelStatusPaused ChannelStatus = C.BASS_ACTIVE_PAUSED 29 | ) 30 | 31 | type ErrorCode int 32 | 33 | const ( 34 | ErrorOK ErrorCode = C.BASS_OK // all is OK 35 | ErrorMEM ErrorCode = C.BASS_ERROR_MEM // memory error 36 | ErrorFILEOPEN ErrorCode = C.BASS_ERROR_FILEOPEN // can't open the file 37 | ErrorDRIVER ErrorCode = C.BASS_ERROR_DRIVER // can't find a free/valid driver 38 | ErrorBUFLOST ErrorCode = C.BASS_ERROR_BUFLOST // the sample buffer was lost 39 | ErrorHANDLE ErrorCode = C.BASS_ERROR_HANDLE // invalid handle 40 | ErrorFORMAT ErrorCode = C.BASS_ERROR_FORMAT // unsupported sample format 41 | ErrorPOSITION ErrorCode = C.BASS_ERROR_POSITION // invalid position 42 | ErrorINIT ErrorCode = C.BASS_ERROR_INIT // BASS_Init has not been successfully called 43 | ErrorSTART ErrorCode = C.BASS_ERROR_START // BASS_Start has not been successfully called 44 | ErrorSSL ErrorCode = C.BASS_ERROR_SSL // SSL/HTTPS support isn't available 45 | ErrorALREADY ErrorCode = C.BASS_ERROR_ALREADY // already initialized/paused/whatever 46 | ErrorNOCHAN ErrorCode = C.BASS_ERROR_NOCHAN // can't get a free channel 47 | ErrorILLTYPE ErrorCode = C.BASS_ERROR_ILLTYPE // an illegal type was specified 48 | ErrorILLPARAM ErrorCode = C.BASS_ERROR_ILLPARAM // an illegal parameter was specified 49 | ErrorNO3D ErrorCode = C.BASS_ERROR_NO3D // no 3D support 50 | ErrorNOEAX ErrorCode = C.BASS_ERROR_NOEAX // no EAX support 51 | ErrorDEVICE ErrorCode = C.BASS_ERROR_DEVICE // illegal device number 52 | ErrorNOPLAY ErrorCode = C.BASS_ERROR_NOPLAY // not playing 53 | ErrorFREQ ErrorCode = C.BASS_ERROR_FREQ // illegal sample rate 54 | ErrorNOTFILE ErrorCode = C.BASS_ERROR_NOTFILE // the stream is not a file stream 55 | ErrorNOHW ErrorCode = C.BASS_ERROR_NOHW // no hardware voices available 56 | ErrorEMPTY ErrorCode = C.BASS_ERROR_EMPTY // the MOD music has no sequence data 57 | ErrorNONET ErrorCode = C.BASS_ERROR_NONET // no internet connection could be opened 58 | ErrorCREATE ErrorCode = C.BASS_ERROR_CREATE // couldn't create the file 59 | ErrorNOFX ErrorCode = C.BASS_ERROR_NOFX // effects are not available 60 | ErrorNOTAVAIL ErrorCode = C.BASS_ERROR_NOTAVAIL // requested data is not available 61 | ErrorDECODE ErrorCode = C.BASS_ERROR_DECODE // the channel is/isn't a "decoding channel" 62 | ErrorDX ErrorCode = C.BASS_ERROR_DX // a sufficient DirectX version is not installed 63 | ErrorTIMEOUT ErrorCode = C.BASS_ERROR_TIMEOUT // connection timed out 64 | ErrorFILEFORM ErrorCode = C.BASS_ERROR_FILEFORM // unsupported file format 65 | ErrorSPEAKER ErrorCode = C.BASS_ERROR_SPEAKER // unavailable speaker 66 | ErrorVERSION ErrorCode = C.BASS_ERROR_VERSION // invalid BASS version (used by add-ons) 67 | ErrorCODEC ErrorCode = C.BASS_ERROR_CODEC // codec is not available/supported 68 | ErrorENDED ErrorCode = C.BASS_ERROR_ENDED // the channel/file has ended 69 | ErrorBUSY ErrorCode = C.BASS_ERROR_BUSY // the device is busy 70 | ErrorUNKNOWN ErrorCode = C.BASS_ERROR_UNKNOWN // some other mystery problem 71 | ) 72 | 73 | type InitFlags int 74 | 75 | const ( 76 | InitFlag8BITS InitFlags = C.BASS_DEVICE_8BITS // 8 bit 77 | InitFlagMONO InitFlags = C.BASS_DEVICE_MONO // mono 78 | InitFlag3D InitFlags = C.BASS_DEVICE_3D // enable 3D functionality 79 | InitFlag16BITS InitFlags = C.BASS_DEVICE_16BITS // limit output to 16 bit 80 | InitFlagLATENCY InitFlags = C.BASS_DEVICE_LATENCY // calculate device latency (BASS_INFO struct) 81 | InitFlagCPSPEAKERS InitFlags = C.BASS_DEVICE_CPSPEAKERS // detect speakers via Windows control panel 82 | InitFlagSPEAKERS InitFlags = C.BASS_DEVICE_SPEAKERS // force enabling of speaker assignment 83 | InitFlagNOSPEAKER InitFlags = C.BASS_DEVICE_NOSPEAKER // ignore speaker arrangement 84 | InitFlagDMIX InitFlags = C.BASS_DEVICE_DMIX // use ALSA "dmix" plugin 85 | InitFlagFREQ InitFlags = C.BASS_DEVICE_FREQ // set device sample rate 86 | InitFlagSTEREO InitFlags = C.BASS_DEVICE_STEREO // limit output to stereo 87 | ) 88 | 89 | type Tag int 90 | 91 | const ( 92 | TagID3 Tag = C.BASS_TAG_ID3 // ID3v1 tags : TAG_ID3 structure 93 | TagID3V2 Tag = C.BASS_TAG_ID3V2 // ID3v2 tags : variable length block 94 | TagOGG Tag = C.BASS_TAG_OGG // OGG comments : series of null-terminated UTF-8 strings 95 | TagHTTP Tag = C.BASS_TAG_HTTP // HTTP headers : series of null-terminated ANSI strings 96 | TagICY Tag = C.BASS_TAG_ICY // ICY headers : series of null-terminated ANSI strings 97 | TagMETA Tag = C.BASS_TAG_META // ICY metadata : ANSI string 98 | TagAPE Tag = C.BASS_TAG_APE // APE tags : series of null-terminated UTF-8 strings 99 | TagMP4 Tag = C.BASS_TAG_MP4 // MP4/iTunes metadata : series of null-terminated UTF-8 strings 100 | TagWMA Tag = C.BASS_TAG_WMA // WMA tags : series of null-terminated UTF-8 strings 101 | TagVENDOR Tag = C.BASS_TAG_VENDOR // OGG encoder : UTF-8 string 102 | TagLYRICS3 Tag = C.BASS_TAG_LYRICS3 // Lyric3v2 tag : ASCII string 103 | TagCaCODEC Tag = C.BASS_TAG_CA_CODEC // CoreAudio codec info : TAG_CA_CODEC structure 104 | TagMF Tag = C.BASS_TAG_MF // Media Foundation tags : series of null-terminated UTF-8 strings 105 | TagWaveFORMAT Tag = C.BASS_TAG_WAVEFORMAT // WAVE format : WAVEFORMATEEX structure 106 | TagRiffINFO Tag = C.BASS_TAG_RIFF_INFO // RIFF "INFO" tags : series of null-terminated ANSI strings 107 | TagRiffBEXT Tag = C.BASS_TAG_RIFF_BEXT // RIFF/BWF "bext" tags : TAG_BEXT structure 108 | TagRiffCART Tag = C.BASS_TAG_RIFF_CART // RIFF/BWF "cart" tags : TAG_CART structure 109 | TagRiffDISP Tag = C.BASS_TAG_RIFF_DISP // RIFF "DISP" text tag : ANSI string 110 | TagApeBINARY Tag = C.BASS_TAG_APE_BINARY // + index #, binary APE tag : TAG_APE_BINARY structure 111 | TagMusicNAME Tag = C.BASS_TAG_MUSIC_NAME // MOD music name : ANSI string 112 | TagMusicMESSAGE Tag = C.BASS_TAG_MUSIC_MESSAGE // MOD message : ANSI string 113 | TagMusicORDERS Tag = C.BASS_TAG_MUSIC_ORDERS // MOD order list : BYTE array of pattern numbers 114 | TagMusicAUTH Tag = C.BASS_TAG_MUSIC_AUTH // MOD author : UTF-8 string 115 | TagMusicINST Tag = C.BASS_TAG_MUSIC_INST // + instrument #, MOD instrument name : ANSI string 116 | TagMusicSAMPLE Tag = C.BASS_TAG_MUSIC_SAMPLE // + sample #, MOD sample name : ANSI string 117 | ) 118 | 119 | type ChannelAttributes int 120 | 121 | const ( 122 | ChannelAttribFREQ ChannelAttributes = C.BASS_ATTRIB_FREQ 123 | ChannelAttribVOL ChannelAttributes = C.BASS_ATTRIB_VOL 124 | ChannelAttribPAN ChannelAttributes = C.BASS_ATTRIB_PAN 125 | ChannelAttribEAXMIX ChannelAttributes = C.BASS_ATTRIB_EAXMIX 126 | ChannelAttribNOBUFFER ChannelAttributes = C.BASS_ATTRIB_NOBUFFER 127 | ChannelAttribVBR ChannelAttributes = C.BASS_ATTRIB_VBR 128 | ChannelAttribCPU ChannelAttributes = C.BASS_ATTRIB_CPU 129 | ChannelAttribSRC ChannelAttributes = C.BASS_ATTRIB_SRC 130 | ChannelAttribNetResume ChannelAttributes = C.BASS_ATTRIB_NET_RESUME 131 | ChannelAttribSCANINFO ChannelAttributes = C.BASS_ATTRIB_SCANINFO 132 | ChannelAttribNORAMP ChannelAttributes = C.BASS_ATTRIB_NORAMP 133 | ChannelAttribBITRATE ChannelAttributes = C.BASS_ATTRIB_BITRATE 134 | ChannelAttribBUFFER ChannelAttributes = C.BASS_ATTRIB_BUFFER 135 | ChannelAttribGRANULE ChannelAttributes = C.BASS_ATTRIB_GRANULE 136 | ChannelAttribMusicAmplify ChannelAttributes = C.BASS_ATTRIB_MUSIC_AMPLIFY 137 | ChannelAttribMusicPANSEP ChannelAttributes = C.BASS_ATTRIB_MUSIC_PANSEP 138 | ChannelAttribMusicPSCALER ChannelAttributes = C.BASS_ATTRIB_MUSIC_PSCALER 139 | ChannelAttribMusicBPM ChannelAttributes = C.BASS_ATTRIB_MUSIC_BPM 140 | ChannelAttribMusicSPEED ChannelAttributes = C.BASS_ATTRIB_MUSIC_SPEED 141 | ChannelAttribMusicVOLGLOBAL ChannelAttributes = C.BASS_ATTRIB_MUSIC_VOL_GLOBAL 142 | ChannelAttribMusicACTIVE ChannelAttributes = C.BASS_ATTRIB_MUSIC_ACTIVE 143 | ChannelAttribMusicVOLCHAN ChannelAttributes = C.BASS_ATTRIB_MUSIC_VOL_CHAN // + channel # 144 | ChannelAttribMusicVOLINST ChannelAttributes = C.BASS_ATTRIB_MUSIC_VOL_INST // + instrument # 145 | ChannelAttribSLIDELOG ChannelAttributes = C.BASS_SLIDE_LOG // BASS_ChannelSlideAttribute flags 146 | ) 147 | -------------------------------------------------------------------------------- /bass/meta.go: -------------------------------------------------------------------------------- 1 | package bass 2 | 3 | import ( 4 | "github.com/dhowden/tag" 5 | "github.com/tejashwikalptaru/gotune/utils" 6 | "log" 7 | "os" 8 | "path/filepath" 9 | "strings" 10 | ) 11 | 12 | type BasicMeta struct { 13 | Name string `json:"name"` 14 | Message string `json:"message"` 15 | Author string `json:"author"` 16 | Instrument string `json:"instrument"` 17 | Album string `json:"album"` 18 | Artist string `json:"artist"` 19 | } 20 | 21 | type MusicMetaInfo struct { 22 | IsMOD bool `json:"isMod"` 23 | Path string `json:"path"` 24 | Info BasicMeta `json:"modInfo"` 25 | AdditionalMeta tag.Metadata `json:"-"` 26 | } 27 | 28 | func ParseFile(path string) MusicMetaInfo { 29 | mod := utils.IsMod(path) 30 | if mod { 31 | channel, err := musicLoad(path, streamGetData|streamAutoFree) 32 | if err != nil { 33 | return MusicMetaInfo{ 34 | IsMOD: true, 35 | Path: path, 36 | Info: BasicMeta{ 37 | Name: filepath.Base(path), 38 | }, 39 | } 40 | } 41 | meta := findMeta(channel, true, path) 42 | musicFree(channel) 43 | return meta 44 | } 45 | return findMeta(0, false, path) 46 | } 47 | 48 | func findMeta(ch int64, isMod bool, path string) MusicMetaInfo { 49 | meta := MusicMetaInfo{IsMOD: isMod, Path: path} 50 | 51 | if isMod { 52 | meta.Info.Name = strings.TrimSpace(channelGetMODTags(ch, TagMusicNAME)) 53 | meta.Info.Message = strings.TrimSpace(channelGetMODTags(ch, TagMusicMESSAGE)) 54 | meta.Info.Author = strings.TrimSpace(channelGetMODTags(ch, TagMusicAUTH)) 55 | meta.Info.Instrument = strings.TrimSpace(channelGetMODTags(ch, TagMusicINST)) 56 | if meta.Info.Name == "" { 57 | meta.Info.Name = filepath.Base(path) 58 | } 59 | return meta 60 | } 61 | // get audio meta data 62 | meta.Info.Name = filepath.Base(path) 63 | currentFile, err := os.Open(path) 64 | if err != nil { 65 | log.Fatalln(err) 66 | return meta 67 | } 68 | defer func(currentFile *os.File) { 69 | err := currentFile.Close() 70 | if err != nil { 71 | log.Fatalln(err) 72 | } 73 | }(currentFile) 74 | 75 | metadata, _ := tag.ReadFrom(currentFile) 76 | if metadata == nil { 77 | return meta 78 | } 79 | if strings.TrimSpace(metadata.Title()) != "" { 80 | meta.Info.Name = strings.TrimSpace(metadata.Title()) 81 | } 82 | meta.Info.Album = strings.TrimSpace(metadata.Album()) 83 | meta.Info.Artist = strings.TrimSpace(metadata.Artist()) 84 | meta.Info.Message = strings.TrimSpace(metadata.Composer()) 85 | meta.AdditionalMeta = metadata 86 | return meta 87 | } 88 | -------------------------------------------------------------------------------- /bass/player.go: -------------------------------------------------------------------------------- 1 | package bass 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/pkg/errors" 6 | "github.com/tejashwikalptaru/gotune/utils" 7 | "io/ioutil" 8 | "time" 9 | ) 10 | 11 | type StatusCallBack func(status ChannelStatus, elapsed float64, mute bool) 12 | type ChannelLoadedCallBack func(status ChannelStatus, totalTime float64, channel int64, meta MusicMetaInfo, queueIndex int) 13 | 14 | type Player struct { 15 | initialized bool 16 | currentChannel int64 17 | currentVolume float64 18 | mute bool 19 | killUpdateRoutine chan bool 20 | isManualStop bool 21 | loop bool 22 | 23 | // callbacks 24 | statusCallBackFunc StatusCallBack 25 | channelLoadedCallBack ChannelLoadedCallBack 26 | newFileAdded func(info MusicMetaInfo) 27 | 28 | // queue files 29 | queue []MusicMetaInfo 30 | currentQueueIndex int 31 | } 32 | 33 | func New(device, frequency int, flag InitFlags) (*Player, error) { 34 | init, err := initBass(device, frequency, flag) 35 | if err != nil { 36 | return nil, errors.Wrapf(err.Err, "Failed to initialize lib bass with error: %+v", err) 37 | } 38 | player := Player{ 39 | initialized: init, 40 | currentChannel: 0, 41 | killUpdateRoutine: make(chan bool, 1), 42 | mute: false, 43 | currentVolume: 0, 44 | isManualStop: true, 45 | currentQueueIndex: -1, 46 | } 47 | player.updateRoutine() 48 | return &player, nil 49 | } 50 | 51 | func (p *Player) Free() error { 52 | if p.initialized { 53 | p.initialized = false 54 | p.killUpdateRoutine <- true 55 | p.Stop() 56 | if _, err := freeBass(); err != nil { 57 | return errors.Wrapf(err.Err, "Failed to free lib bass with error: %+v", err) 58 | } 59 | } 60 | return nil 61 | } 62 | 63 | func (p *Player) StatusCallBack(f StatusCallBack) { 64 | p.statusCallBackFunc = f 65 | } 66 | 67 | func (p *Player) ChannelLoadedCallBack(f ChannelLoadedCallBack) { 68 | p.channelLoadedCallBack = f 69 | } 70 | 71 | func (p *Player) FileAddedCallBack(f func(info MusicMetaInfo)) { 72 | p.newFileAdded = f 73 | } 74 | 75 | func (p *Player) AddToQueue(path string, play bool) *Error { 76 | if !p.initialized { 77 | return errMsg(8) 78 | } 79 | meta := ParseFile(path) 80 | p.queue = append(p.queue, meta) 81 | if play { 82 | p.currentQueueIndex = len(p.queue) - 1 83 | p.loadFromPath(path) 84 | p.Play() 85 | } 86 | if p.newFileAdded != nil { 87 | p.newFileAdded(meta) 88 | } 89 | return nil 90 | } 91 | 92 | func (p *Player) PlayFromQueue(path string) int { 93 | if !p.initialized { 94 | return -1 95 | } 96 | indexFound := -1 97 | for i, v := range p.queue { 98 | if v.Path == path { 99 | indexFound = i 100 | break 101 | } 102 | } 103 | if indexFound == -1 { 104 | return indexFound 105 | } 106 | p.currentQueueIndex = indexFound 107 | p.loadFromPath(path) 108 | p.Play() 109 | return indexFound 110 | } 111 | 112 | func (p *Player) loadFromPath(path string) *Error { 113 | if !p.initialized { 114 | return errMsg(8) 115 | } 116 | p.Stop() 117 | 118 | isMOD := false 119 | // try to load tracker modules 120 | channel, err := musicLoad(path, musicPreScan|musicRamps|streamAutoFree|posReset|posResetEx) 121 | if err != nil { 122 | // then try to load audio files 123 | channel, err = streamCreateFile(path, streamAutoFree|posReset|posResetEx) 124 | if err != nil { 125 | // give up! 126 | return err 127 | } 128 | } else { 129 | isMOD = true 130 | } 131 | p.currentChannel = channel 132 | p.SetVolume(p.currentVolume) 133 | if p.channelLoadedCallBack != nil { 134 | status, _ := p.Status() 135 | total := channelBytes2Seconds(p.currentChannel, channelLength(p.currentChannel)) 136 | meta := findMeta(p.currentChannel, isMOD, path) 137 | p.channelLoadedCallBack(status, total, p.currentChannel, meta, p.currentQueueIndex) 138 | } 139 | return err 140 | } 141 | 142 | func (p *Player) Play() (bool, *Error) { 143 | if !p.initialized { 144 | return false, errMsg(8) 145 | } 146 | p.isManualStop = false 147 | status, _ := p.Status() 148 | if status == ChannelStatusPlaying { 149 | return true, nil 150 | } 151 | if status == ChannelStatusStopped || status == ChannelStatusStalled { 152 | channelPlay(p.currentChannel, true) 153 | } 154 | // it should be paused then, resume play 155 | return channelPlay(p.currentChannel, false) 156 | } 157 | 158 | func (p *Player) Pause() (bool, *Error) { 159 | if !p.initialized { 160 | return false, errMsg(8) 161 | } 162 | return channelPause(p.currentChannel) 163 | } 164 | 165 | func (p *Player) Stop() *Error { 166 | if !p.initialized { 167 | return errMsg(8) 168 | } 169 | p.isManualStop = true 170 | channelSlideAttribute(p.currentChannel, ChannelAttribFREQ, 1000, 500) 171 | channelSlideAttribute(p.currentChannel, ChannelAttribVOL|ChannelAttribSLIDELOG, -1, 100) 172 | channelStop(p.currentChannel) 173 | if !streamFree(p.currentChannel) { 174 | musicFree(p.currentChannel) 175 | } 176 | return nil 177 | } 178 | 179 | func (p *Player) Status() (ChannelStatus, *Error) { 180 | if !p.initialized { 181 | return ChannelStatusStopped, errMsg(8) 182 | } 183 | return channelStatus(p.currentChannel), nil 184 | } 185 | 186 | func (p *Player) SetVolume(vol float64) *Error { 187 | if !p.initialized { 188 | return errMsg(8) 189 | } 190 | p.currentVolume = vol 191 | if _, err := channelSetVolume(p.currentChannel, vol); err != nil { 192 | return err 193 | } 194 | return nil 195 | } 196 | 197 | func (p *Player) Mute(mute bool) *Error { 198 | if !p.initialized { 199 | return errMsg(8) 200 | } 201 | if mute { 202 | p.mute = true 203 | temp := p.currentVolume 204 | err := p.SetVolume(0) 205 | p.currentVolume = temp 206 | return err 207 | } 208 | p.mute = false 209 | return p.SetVolume(p.currentVolume) 210 | } 211 | 212 | func (p *Player) IsMute() bool { 213 | return p.mute 214 | } 215 | 216 | func (p *Player) IsLoop() bool { 217 | return p.loop 218 | } 219 | 220 | func (p *Player) Loop(enable bool) { 221 | p.loop = enable 222 | } 223 | 224 | func (p *Player) updateRoutine() { 225 | go func() { 226 | var elapsed float64 227 | for { 228 | select { 229 | case <-p.killUpdateRoutine: 230 | close(p.killUpdateRoutine) 231 | return 232 | default: 233 | status, _ := p.Status() 234 | if status == ChannelStatusPlaying { 235 | elapsed = channelBytes2Seconds(p.currentChannel, channelGetPosition(p.currentChannel)) 236 | } 237 | if p.statusCallBackFunc != nil { 238 | p.statusCallBackFunc(status, elapsed, p.IsMute()) 239 | } 240 | if status == ChannelStatusStopped && !p.isManualStop && len(p.queue) > 0 && p.currentQueueIndex < len(p.queue)-1 { 241 | if p.loop { 242 | p.loadFromPath(p.queue[p.currentQueueIndex].Path) 243 | p.Play() 244 | } else { 245 | p.PlayNext() 246 | } 247 | } 248 | // very important to give some rest to CPU 249 | time.Sleep(time.Second / 3) 250 | } 251 | } 252 | }() 253 | } 254 | 255 | func (p *Player) PlayNext() { 256 | if !p.initialized { 257 | return 258 | } 259 | if len(p.queue) == 0 { 260 | return 261 | } 262 | if p.currentQueueIndex < len(p.queue)-1 { 263 | p.currentQueueIndex++ 264 | p.loadFromPath(p.queue[p.currentQueueIndex].Path) 265 | p.Play() 266 | } 267 | } 268 | 269 | func (p *Player) PlayPrevious() { 270 | if !p.initialized { 271 | return 272 | } 273 | if len(p.queue) == 0 { 274 | return 275 | } 276 | if p.currentQueueIndex > 0 { 277 | p.currentQueueIndex-- 278 | p.loadFromPath(p.queue[p.currentQueueIndex].Path) 279 | p.Play() 280 | } 281 | } 282 | 283 | func (p *Player) SetChannelPosition(val float64) { 284 | if !p.initialized { 285 | return 286 | } 287 | bytes := channelSeconds2Bytes(p.currentChannel, val) 288 | channelSetPosition(p.currentChannel, bytes) 289 | } 290 | 291 | func (p *Player) GetPlayList() []MusicMetaInfo { 292 | return p.queue 293 | } 294 | 295 | func (p *Player) GetPlaylistIndex() int { 296 | return p.currentQueueIndex 297 | } 298 | 299 | func (p *Player) GetHistory() string { 300 | jsonByte, err := json.Marshal(p.queue) 301 | if err != nil { 302 | utils.ShowError(true, "Failed", err.Error()) 303 | return "" 304 | } 305 | return string(jsonByte) 306 | } 307 | 308 | func (p *Player) LoadHistory(data string) { 309 | playlist := make([]MusicMetaInfo, 0) 310 | err := json.Unmarshal([]byte(data), &playlist) 311 | if err != nil { 312 | return 313 | } 314 | if len(playlist) > 0 { 315 | p.queue = playlist 316 | p.currentQueueIndex = -1 //reset 317 | } 318 | } 319 | 320 | func (p *Player) WriteToPlaylist() { 321 | if len(p.queue) == 0 { 322 | return 323 | } 324 | jsonByte, err := json.Marshal(p.queue) 325 | if err != nil { 326 | utils.ShowError(true, "Failed", err.Error()) 327 | return 328 | } 329 | err = ioutil.WriteFile("/Users/tejashwi/projects/personal/gotune/queue.gtp", jsonByte, 0644) 330 | if err != nil { 331 | utils.ShowError(true, "Failed", err.Error()) 332 | } 333 | } 334 | 335 | func (p *Player) OpenPlayList(clearQueue bool) { 336 | file, err := ioutil.ReadFile("/Users/tejashwi/projects/personal/gotune/queue.gtp") 337 | if err != nil { 338 | return 339 | } 340 | playlist := make([]MusicMetaInfo, 0) 341 | err = json.Unmarshal(file, &playlist) 342 | if err != nil { 343 | return 344 | } 345 | if len(playlist) > 0 { 346 | p.queue = playlist 347 | p.currentQueueIndex = -1 //reset 348 | } 349 | } 350 | -------------------------------------------------------------------------------- /dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejashwikalptaru/gotune/5f2adf5c5bdcf7c32196ca3937c13a7a30ca79da/dark.png -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tejashwikalptaru/gotune 2 | 3 | go 1.16 4 | 5 | require ( 6 | fyne.io/fyne v1.4.3 7 | fyne.io/fyne/v2 v2.0.3 8 | github.com/dhowden/tag v0.0.0-20201120070457-d52dcb253c63 // indirect 9 | github.com/gen2brain/beeep v0.0.0-20200526185328-e9c15c258e28 // indirect 10 | github.com/pkg/errors v0.9.1 11 | github.com/sqweek/dialog v0.0.0-20200911184034-8a3d98e8211d // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | fyne.io/fyne v1.4.3 h1:356CnXCiYrrfaLGsB7qLK3c6ktzyh8WR05v/2RBu51I= 2 | fyne.io/fyne v1.4.3/go.mod h1:8kiPBNSDmuplxs9WnKCkaWYqbcXFy0DeAzwa6PBO9Z8= 3 | fyne.io/fyne/v2 v2.0.3 h1:qzd2uLLrAVrNeqnLY44QZCsMxZwjoo1my+lMzHicMXY= 4 | fyne.io/fyne/v2 v2.0.3/go.mod h1:nNpgL7sZkDVLraGtQII2ArNRnnl6kHup/KfQRxIhbvs= 5 | github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9 h1:1ltqoej5GtaWF8jaiA49HwsZD459jqm9YFz9ZtMFpQA= 6 | github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I= 7 | github.com/TheTitanrain/w32 v0.0.0-20180517000239-4f5cfb03fabf h1:FPsprx82rdrX2jiKyS17BH6IrTmUBYqZa/CXT4uvb+I= 8 | github.com/TheTitanrain/w32 v0.0.0-20180517000239-4f5cfb03fabf/go.mod h1:peYoMncQljjNS6tZwI9WVyQB3qZS6u79/N3mBOcnd3I= 9 | github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= 10 | github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= 11 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 12 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 13 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 14 | github.com/dhowden/tag v0.0.0-20201120070457-d52dcb253c63 h1:/u5RVRk3Nh7Zw1QQnPtUH5kzcc8JmSSRpHSlGU/zGTE= 15 | github.com/dhowden/tag v0.0.0-20201120070457-d52dcb253c63/go.mod h1:SniNVYuaD1jmdEEvi+7ywb1QFR7agjeTdGKyFb0p7Rw= 16 | github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 h1:FDqhDm7pcsLhhWl1QtD8vlzI4mm59llRvNzrFg6/LAA= 17 | github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3/go.mod h1:CzM2G82Q9BDUvMTGHnXf/6OExw/Dz2ivDj48nVg7Lg8= 18 | github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= 19 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 20 | github.com/fyne-io/mobile v0.1.2/go.mod h1:/kOrWrZB6sasLbEy2JIvr4arEzQTXBTZGb3Y96yWbHY= 21 | github.com/fyne-io/mobile v0.1.3-0.20210412090810-650a3139866a h1:3TAJhl8vXyli0tooKB0vd6gLCyBdWL4QEYbDoJpHEZk= 22 | github.com/fyne-io/mobile v0.1.3-0.20210412090810-650a3139866a/go.mod h1:/kOrWrZB6sasLbEy2JIvr4arEzQTXBTZGb3Y96yWbHY= 23 | github.com/gen2brain/beeep v0.0.0-20200526185328-e9c15c258e28 h1:M2Zt3G2w6Q57GZndOYk42p7RvMeO8izO8yKTfIxGqxA= 24 | github.com/gen2brain/beeep v0.0.0-20200526185328-e9c15c258e28/go.mod h1:ElSskYZe3oM8kThaHGJ+kiN2yyUMVXMZ7WxF9QqLDS8= 25 | github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 h1:SCYMcCJ89LjRGwEa0tRluNRiMjZHalQZrVrvTbPh+qw= 26 | github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= 27 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200625191551-73d3c3675aa3/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 28 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb h1:T6gaWBvRzJjuOrdCtg8fXXjKai2xSDqWTcKFUPuw8Tw= 29 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 30 | github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 h1:qZNfIGkIANxGv/OqtnntR4DfOY2+BgwR60cAcu/i3SE= 31 | github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4/go.mod h1:kW3HQ4UdaAyrUCSSDR4xUzBKW6O2iA4uHhk7AtyYp10= 32 | github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 33 | github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= 34 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 35 | github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff h1:W71vTCKoxtdXgnm1ECDFkfQnpdqAO00zzGXLA5yaEX8= 36 | github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw= 37 | github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c h1:16eHWuMGvCjSfgRJKqIzapE78onvvTbdi1rMkU00lZw= 38 | github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 39 | github.com/gopherjs/gopherwasm v1.1.0 h1:fA2uLoctU5+T3OhOn2vYP0DVT6pxc7xhTlBB1paATqQ= 40 | github.com/gopherjs/gopherwasm v1.1.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI= 41 | github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526 h1:NfuKjkj/Xc2z1xZIj+EmNCm5p1nKJPyw3F4E20usXvg= 42 | github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc= 43 | github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca h1:ozPUX9TKQZVek4lZWYRsQo7uS8vJ+q4OOHvRhHiCLfU= 44 | github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE= 45 | github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= 46 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 47 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 48 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 49 | github.com/lucor/goinfo v0.0.0-20200401173949-526b5363a13a h1:4djPngMU3ttoFCf6DOgPNQYmxyNmRRmpLg4/uz2TTEg= 50 | github.com/lucor/goinfo v0.0.0-20200401173949-526b5363a13a/go.mod h1:ORP3/rB5IsulLEBwQZCJyyV6niqmI7P4EWSmkug+1Ng= 51 | github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= 52 | github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= 53 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= 54 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 55 | github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ= 56 | github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= 57 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 58 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 59 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 60 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 61 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 62 | github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= 63 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= 64 | github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= 65 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 66 | github.com/sqweek/dialog v0.0.0-20200911184034-8a3d98e8211d h1:Chay1rwJnXxI27H+pzu7P81BKf647un9GOoRPTdXN18= 67 | github.com/sqweek/dialog v0.0.0-20200911184034-8a3d98e8211d/go.mod h1:/qNPSY91qTz/8TgHEMioAUc6q7+3SOybeKczHMXFcXw= 68 | github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564 h1:HunZiaEKNGVdhTRQOVpMmj5MQnGnv+e8uZNu3xFLgyM= 69 | github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564/go.mod h1:afMbS0qvv1m5tfENCwnOdZGOF8RGR/FsZ7bvBxQGZG4= 70 | github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9 h1:m59mIOBO4kfcNCEzJNy71UkeF4XIx2EVmL9KLwDQdmM= 71 | github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU= 72 | github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= 73 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 74 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 75 | github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= 76 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 77 | github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG04SN9W+iWHCRyHqlVYILiSXziwk= 78 | github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af/go.mod h1:4F09kP5F+am0jAwlQLddpoMDM+iewkxxt6nxUQ5nq5o= 79 | github.com/yuin/goldmark v1.1.25 h1:isv+Q6HQAmmL2Ofcmg8QauBmDPlUUnSoNhEcC940Rds= 80 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 81 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 82 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= 83 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 84 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 85 | golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw= 86 | golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 87 | golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= 88 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 89 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 90 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 91 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 92 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= 93 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 94 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 95 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= 96 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 97 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 98 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 99 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 100 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 101 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 102 | golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666 h1:gVCS+QOncANNPlmlO1AhlU3oxs4V9z+gTtPwIk3p2N8= 103 | golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 104 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 105 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= 106 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 107 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 108 | golang.org/x/tools v0.0.0-20190808195139-e713427fea3f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 109 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 110 | golang.org/x/tools v0.0.0-20200328031815-3db5fc6bac03 h1:XpToik3MpT5iW3iHgNwnh3a8QwugfomvxOlyDnaOils= 111 | golang.org/x/tools v0.0.0-20200328031815-3db5fc6bac03/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= 112 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 113 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 114 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 115 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 116 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 117 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= 118 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 119 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 120 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= 121 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 122 | -------------------------------------------------------------------------------- /libs/libbass.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejashwikalptaru/gotune/5f2adf5c5bdcf7c32196ca3937c13a7a30ca79da/libs/libbass.dylib -------------------------------------------------------------------------------- /light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejashwikalptaru/gotune/5f2adf5c5bdcf7c32196ca3937c13a7a30ca79da/light.png -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/tejashwikalptaru/gotune/bass" 5 | "github.com/tejashwikalptaru/gotune/ui" 6 | "log" 7 | ) 8 | 9 | var plView *ui.PlayListView 10 | 11 | func handleMainWindowButtonClicks(app *ui.Main, player *bass.Player) { 12 | app.OnPlay(func() { 13 | status, _ := player.Status() 14 | if status == bass.ChannelStatusPlaying { 15 | _, _ = player.Pause() 16 | return 17 | } 18 | _ ,_ = player.Play() 19 | }) 20 | app.OnMute(func() { 21 | mute := !player.IsMute() 22 | player.Mute(mute) 23 | }) 24 | app.OnStop(func() { 25 | player.Stop() 26 | }) 27 | app.OnNext(func() { 28 | player.PlayNext() 29 | }) 30 | app.OnPrev(func() { 31 | player.PlayPrevious() 32 | }) 33 | app.OnLoop(func() { 34 | loop := !player.IsLoop() 35 | player.Loop(loop) 36 | app.SetLoopState(loop) 37 | }) 38 | } 39 | 40 | func handleMainWindowCallBacks(app *ui.Main, player *bass.Player) { 41 | app.VolumeUpdateCallBack(func(vol float64) { 42 | player.SetVolume(vol) 43 | }) 44 | app.SetPlayListUpdater(func(path string) { 45 | player.AddToQueue(path, false) 46 | }) 47 | app.ProgressChanged(func(val float64) { 48 | player.SetChannelPosition(val) 49 | }) 50 | app.SetOpenPlayListCallBack(func() { 51 | if plView != nil { 52 | plView.Show() 53 | return 54 | } 55 | plView = ui.NewPlayListView(app.GetApp(), player.GetPlayList(), player.GetPlaylistIndex(), func() { 56 | plView = nil 57 | }, func(path string) { 58 | index := player.PlayFromQueue(path) 59 | if index > -1 { 60 | plView.SetSelected(path) 61 | } 62 | }) 63 | plView.Show() 64 | }) 65 | app.SetFileOpenCallBack(func(filePath string) { 66 | err := player.AddToQueue(filePath, false) 67 | if err != nil { 68 | log.Fatal(err) 69 | return 70 | } 71 | }) 72 | app.OnAppClose(func() { 73 | app.QuitApp() 74 | }) 75 | } 76 | 77 | func handlePlayerCallbacks(app *ui.Main, player *bass.Player) { 78 | player.ChannelLoadedCallBack(func(status bass.ChannelStatus, totalTime float64, channel int64, meta bass.MusicMetaInfo, currentQueueIndex int) { 79 | app.SetTotalTime(totalTime) 80 | app.SetSongName(meta.Info.Name) 81 | if plView != nil { 82 | plView.SetSelected(meta.Path) 83 | } 84 | if meta.IsMOD { 85 | return 86 | } 87 | if meta.AdditionalMeta != nil && meta.AdditionalMeta.Picture() != nil { 88 | app.SetAlbumArt(meta.AdditionalMeta.Picture().Data) 89 | } else { 90 | app.ClearAlbumArt() 91 | } 92 | }) 93 | player.StatusCallBack(func(status bass.ChannelStatus, elapsed float64, mute bool) { 94 | app.SetMuteState(mute) 95 | if status == bass.ChannelStatusPlaying { 96 | app.SetPlayState(true) 97 | app.SetCurrentTime(elapsed) 98 | return 99 | } 100 | app.SetPlayState(false) 101 | }) 102 | player.FileAddedCallBack(func(info bass.MusicMetaInfo) { 103 | if plView != nil { 104 | plView.FileAdded(info) 105 | } 106 | // save history 107 | app.SaveHistory(player.GetHistory()) 108 | }) 109 | } 110 | 111 | func createPlayer() *bass.Player { 112 | player, err := bass.New(-1, 44100, bass.InitFlag3D | bass.InitFlagSTEREO) 113 | if err != nil { 114 | log.Fatal(err) 115 | } 116 | player.SetVolume(100) 117 | return player 118 | } 119 | 120 | func createMainWindow() *ui.Main { 121 | app := ui.NewMainWindow() 122 | app.SetVolume(100) 123 | return app 124 | } 125 | 126 | func main() { 127 | // audio player instance 128 | player := createPlayer() 129 | defer func(player *bass.Player) { 130 | //player.SaveHistory() 131 | err := player.Free() 132 | if err != nil { 133 | log.Fatal(err) 134 | } 135 | }(player) 136 | 137 | // main window instance 138 | app := createMainWindow() 139 | defer func(app *ui.Main) { 140 | app.Free() 141 | }(app) 142 | 143 | // load history 144 | player.LoadHistory(app.GetHistory()) 145 | 146 | // main window button clicks callback 147 | handleMainWindowButtonClicks(app, player) 148 | 149 | // main window callbacks 150 | handleMainWindowCallBacks(app, player) 151 | 152 | // player callbacks 153 | handlePlayerCallbacks(app, player) 154 | 155 | // add app shortcuts 156 | app.AddShortCuts() 157 | 158 | // finally run 159 | app.ShowAndRun() 160 | } 161 | -------------------------------------------------------------------------------- /music.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejashwikalptaru/gotune/5f2adf5c5bdcf7c32196ca3937c13a7a30ca79da/music.png -------------------------------------------------------------------------------- /res/appIcon.go: -------------------------------------------------------------------------------- 1 | // auto-generated 2 | 3 | package res 4 | 5 | import "fyne.io/fyne" 6 | 7 | var ResourceIconPng = &fyne.StaticResource{ 8 | StaticName: "Icon.png", 9 | StaticContent: []byte{ 10 | 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 0, 0, 0, 2, 0, 8, 6, 0, 0, 0, 244, 120, 212, 250, 0, 0, 0, 4, 115, 66, 73, 84, 8, 8, 8, 8, 124, 8, 100, 136, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 14, 196, 0, 0, 14, 196, 1, 149, 43, 14, 27, 0, 0, 0, 25, 116, 69, 88, 116, 83, 111, 102, 116, 119, 97, 114, 101, 0, 119, 119, 119, 46, 105, 110, 107, 115, 99, 97, 112, 101, 46, 111, 114, 103, 155, 238, 60, 26, 0, 0, 32, 0, 73, 68, 65, 84, 120, 156, 236, 221, 119, 156, 92, 101, 161, 255, 241, 207, 115, 102, 118, 102, 182, 239, 38, 155, 222, 73, 32, 36, 161, 165, 208, 139, 70, 186, 128, 1, 4, 4, 188, 32, 194, 85, 175, 88, 176, 123, 175, 63, 187, 247, 218, 5, 245, 170, 87, 5, 17, 80, 64, 66, 17, 144, 162, 162, 4, 48, 244, 236, 38, 148, 208, 2, 73, 8, 233, 61, 217, 205, 238, 206, 238, 206, 60, 191, 63, 38, 129, 148, 45, 83, 206, 204, 115, 102, 230, 251, 126, 189, 226, 146, 221, 153, 231, 124, 17, 194, 249, 206, 115, 158, 243, 28, 131, 136, 4, 154, 93, 64, 5, 30, 67, 48, 12, 197, 48, 148, 4, 13, 64, 3, 134, 70, 216, 249, 215, 80, 15, 84, 3, 85, 59, 191, 70, 118, 126, 47, 188, 243, 235, 238, 106, 128, 138, 189, 190, 215, 13, 180, 237, 245, 189, 173, 64, 2, 216, 6, 116, 1, 59, 128, 246, 157, 95, 183, 2, 91, 177, 59, 191, 122, 108, 217, 249, 251, 245, 192, 6, 182, 177, 222, 204, 166, 199, 135, 191, 125, 17, 201, 19, 227, 58, 128, 72, 57, 179, 45, 12, 193, 99, 52, 73, 198, 96, 25, 139, 97, 52, 150, 209, 24, 70, 1, 67, 129, 33, 59, 127, 21, 163, 13, 176, 179, 16, 24, 86, 98, 89, 133, 101, 37, 240, 38, 30, 111, 145, 96, 165, 153, 197, 70, 199, 25, 69, 202, 150, 10, 128, 72, 30, 217, 185, 132, 152, 204, 88, 146, 76, 194, 50, 17, 118, 251, 106, 152, 8, 84, 58, 142, 232, 90, 7, 240, 58, 150, 55, 128, 215, 129, 215, 49, 188, 129, 225, 117, 14, 99, 133, 49, 36, 29, 231, 19, 41, 89, 42, 0, 34, 62, 177, 45, 140, 4, 166, 98, 152, 6, 76, 197, 50, 13, 56, 140, 212, 148, 188, 100, 174, 139, 84, 41, 88, 140, 229, 37, 60, 22, 99, 120, 137, 215, 120, 197, 92, 64, 194, 117, 56, 145, 98, 167, 2, 32, 146, 33, 187, 128, 10, 194, 28, 64, 146, 153, 240, 246, 175, 233, 164, 174, 191, 75, 254, 117, 3, 75, 128, 102, 12, 205, 36, 104, 6, 90, 204, 44, 218, 29, 231, 18, 41, 42, 42, 0, 34, 253, 176, 115, 9, 177, 31, 83, 9, 113, 36, 150, 163, 128, 35, 128, 41, 164, 22, 215, 73, 112, 244, 0, 47, 1, 207, 0, 79, 17, 226, 105, 14, 225, 37, 93, 66, 16, 233, 155, 10, 128, 200, 110, 236, 83, 212, 17, 229, 56, 146, 28, 11, 28, 13, 204, 194, 80, 235, 58, 151, 100, 101, 59, 240, 44, 134, 167, 176, 60, 78, 59, 243, 205, 113, 180, 186, 14, 37, 18, 20, 42, 0, 82, 214, 236, 124, 106, 169, 226, 72, 224, 36, 224, 56, 82, 159, 240, 247, 190, 69, 78, 74, 67, 2, 120, 21, 195, 124, 224, 31, 36, 152, 167, 187, 16, 164, 156, 169, 0, 72, 89, 177, 79, 80, 73, 37, 199, 145, 228, 100, 12, 39, 3, 135, 162, 63, 7, 229, 42, 137, 229, 57, 60, 30, 194, 242, 16, 219, 152, 111, 102, 211, 233, 58, 148, 72, 161, 232, 63, 124, 82, 242, 108, 11, 135, 98, 57, 117, 231, 9, 255, 56, 32, 230, 58, 147, 4, 82, 7, 150, 127, 225, 241, 16, 9, 254, 102, 102, 241, 130, 235, 64, 34, 249, 164, 2, 32, 37, 199, 206, 35, 70, 61, 199, 1, 103, 1, 103, 3, 99, 29, 71, 146, 226, 244, 38, 134, 191, 145, 228, 62, 182, 243, 144, 102, 7, 164, 212, 168, 0, 72, 73, 176, 79, 51, 152, 10, 230, 0, 239, 35, 117, 61, 95, 247, 222, 139, 159, 118, 96, 248, 59, 112, 47, 17, 238, 53, 211, 216, 236, 58, 144, 72, 174, 84, 0, 164, 104, 217, 5, 52, 225, 241, 94, 12, 231, 99, 57, 21, 45, 222, 147, 194, 72, 0, 79, 97, 184, 157, 4, 115, 205, 44, 214, 184, 14, 36, 146, 13, 21, 0, 41, 42, 246, 5, 134, 209, 205, 5, 24, 46, 192, 114, 12, 224, 185, 206, 36, 101, 45, 1, 60, 142, 101, 46, 134, 185, 102, 6, 27, 92, 7, 18, 73, 151, 10, 128, 4, 222, 206, 149, 251, 103, 2, 151, 234, 147, 190, 4, 88, 106, 102, 192, 114, 19, 29, 220, 170, 61, 7, 36, 232, 84, 0, 36, 144, 236, 60, 194, 212, 113, 26, 30, 151, 96, 57, 11, 61, 52, 71, 138, 75, 59, 112, 47, 134, 63, 178, 132, 191, 234, 217, 5, 18, 68, 42, 0, 18, 40, 246, 57, 38, 211, 195, 69, 24, 62, 140, 86, 239, 75, 105, 88, 3, 220, 142, 229, 119, 102, 38, 207, 187, 14, 35, 178, 139, 10, 128, 56, 103, 231, 83, 75, 53, 23, 98, 249, 48, 169, 237, 119, 69, 74, 213, 227, 192, 239, 137, 114, 155, 153, 70, 155, 235, 48, 82, 222, 84, 0, 196, 25, 187, 128, 3, 241, 184, 12, 248, 40, 208, 232, 56, 142, 72, 225, 88, 90, 241, 184, 21, 203, 175, 204, 12, 158, 115, 29, 71, 202, 147, 10, 128, 20, 148, 93, 76, 132, 46, 230, 96, 249, 40, 169, 251, 245, 69, 202, 93, 51, 150, 223, 18, 231, 15, 230, 24, 58, 92, 135, 145, 242, 161, 2, 32, 5, 97, 91, 24, 137, 225, 202, 157, 39, 254, 33, 174, 243, 136, 4, 208, 122, 224, 183, 36, 249, 149, 246, 22, 144, 66, 80, 1, 144, 188, 178, 11, 152, 65, 136, 143, 97, 185, 20, 237, 193, 47, 146, 142, 46, 224, 30, 224, 26, 51, 131, 39, 93, 135, 145, 210, 165, 2, 32, 190, 179, 22, 143, 133, 156, 11, 124, 22, 56, 198, 117, 30, 145, 162, 101, 152, 79, 146, 107, 152, 193, 221, 198, 144, 116, 29, 71, 74, 139, 10, 128, 248, 198, 46, 38, 66, 156, 11, 129, 255, 2, 14, 116, 157, 71, 164, 100, 24, 150, 2, 63, 103, 43, 191, 209, 67, 137, 196, 47, 42, 0, 146, 179, 157, 183, 241, 93, 142, 229, 139, 192, 40, 215, 121, 68, 74, 216, 58, 44, 191, 198, 227, 167, 102, 58, 91, 93, 135, 145, 226, 166, 2, 32, 89, 179, 139, 25, 68, 156, 207, 2, 159, 2, 234, 93, 231, 17, 41, 35, 91, 129, 159, 19, 230, 167, 230, 16, 182, 184, 14, 35, 197, 73, 5, 64, 50, 102, 159, 102, 48, 97, 62, 133, 225, 42, 160, 193, 117, 30, 145, 50, 214, 6, 252, 146, 40, 63, 212, 35, 138, 37, 83, 42, 0, 146, 54, 187, 128, 38, 12, 159, 196, 240, 25, 244, 137, 95, 36, 72, 218, 128, 235, 169, 224, 187, 230, 96, 214, 185, 14, 35, 197, 65, 5, 64, 6, 100, 23, 83, 67, 156, 79, 144, 90, 220, 167, 19, 191, 72, 112, 165, 102, 4, 146, 124, 207, 204, 98, 155, 235, 48, 18, 108, 42, 0, 210, 39, 187, 152, 8, 157, 92, 134, 225, 219, 192, 48, 215, 121, 68, 36, 109, 155, 128, 31, 177, 141, 159, 233, 174, 1, 233, 139, 10, 128, 236, 195, 206, 35, 76, 3, 31, 198, 242, 117, 96, 180, 235, 60, 34, 146, 181, 21, 192, 183, 120, 157, 27, 245, 72, 98, 217, 155, 10, 128, 236, 193, 182, 112, 18, 112, 53, 112, 176, 235, 44, 34, 226, 155, 87, 128, 207, 153, 25, 60, 232, 58, 136, 4, 135, 10, 128, 0, 96, 91, 152, 10, 252, 8, 120, 175, 235, 44, 34, 146, 39, 134, 251, 72, 240, 25, 51, 139, 55, 92, 71, 17, 247, 84, 0, 202, 156, 93, 196, 40, 18, 252, 55, 134, 75, 1, 207, 117, 30, 17, 201, 187, 56, 134, 159, 17, 231, 127, 204, 81, 108, 119, 29, 70, 220, 81, 1, 40, 83, 118, 1, 21, 132, 184, 146, 36, 223, 193, 80, 235, 58, 143, 136, 20, 220, 38, 12, 223, 97, 9, 191, 208, 250, 128, 242, 164, 2, 80, 134, 108, 11, 39, 2, 63, 7, 166, 186, 206, 34, 34, 142, 89, 22, 98, 248, 140, 153, 193, 99, 174, 163, 72, 97, 169, 0, 148, 17, 187, 128, 137, 120, 124, 15, 56, 223, 117, 22, 17, 9, 24, 195, 125, 120, 124, 218, 28, 202, 50, 215, 81, 164, 48, 84, 0, 202, 192, 206, 233, 254, 47, 98, 249, 26, 16, 115, 157, 71, 68, 2, 171, 3, 203, 55, 217, 206, 213, 102, 54, 61, 174, 195, 72, 126, 169, 0, 148, 56, 187, 144, 195, 176, 92, 7, 204, 116, 157, 69, 68, 138, 198, 243, 24, 254, 221, 76, 231, 89, 215, 65, 36, 127, 84, 0, 74, 148, 125, 130, 74, 98, 124, 3, 248, 2, 16, 114, 157, 71, 68, 138, 78, 15, 240, 43, 66, 124, 197, 28, 202, 14, 215, 97, 196, 127, 42, 0, 37, 200, 182, 112, 2, 112, 45, 112, 128, 235, 44, 34, 82, 228, 12, 75, 177, 124, 204, 204, 224, 31, 174, 163, 136, 191, 84, 0, 74, 136, 93, 72, 3, 240, 3, 44, 31, 65, 255, 108, 69, 196, 95, 183, 211, 205, 199, 205, 145, 108, 114, 29, 68, 252, 161, 147, 68, 137, 176, 205, 156, 133, 225, 255, 128, 81, 174, 179, 136, 72, 201, 90, 7, 124, 201, 204, 224, 38, 215, 65, 36, 119, 42, 0, 69, 206, 46, 98, 20, 150, 95, 99, 57, 211, 117, 22, 17, 41, 27, 247, 144, 228, 227, 102, 22, 107, 92, 7, 145, 236, 169, 0, 20, 49, 219, 204, 57, 24, 174, 5, 6, 187, 206, 34, 34, 101, 103, 43, 240, 113, 51, 131, 63, 185, 14, 34, 217, 81, 1, 40, 66, 59, 87, 248, 127, 31, 248, 180, 235, 44, 34, 82, 246, 254, 64, 148, 43, 205, 52, 218, 92, 7, 145, 204, 168, 0, 20, 25, 219, 194, 44, 224, 102, 180, 194, 95, 68, 130, 99, 25, 240, 65, 51, 131, 39, 93, 7, 145, 244, 233, 233, 111, 69, 194, 90, 140, 93, 200, 85, 192, 227, 232, 228, 47, 34, 193, 50, 1, 120, 204, 54, 243, 77, 59, 87, 251, 142, 20, 11, 205, 0, 20, 1, 187, 128, 177, 120, 220, 4, 188, 203, 117, 22, 17, 145, 1, 60, 73, 136, 15, 234, 153, 2, 193, 167, 25, 128, 128, 179, 45, 156, 135, 199, 66, 116, 242, 23, 145, 226, 112, 52, 9, 22, 218, 133, 124, 208, 117, 16, 233, 159, 102, 0, 2, 202, 62, 69, 29, 17, 126, 1, 92, 226, 58, 139, 136, 72, 86, 44, 55, 16, 227, 83, 90, 32, 24, 76, 42, 0, 1, 100, 159, 99, 50, 9, 238, 2, 166, 186, 206, 34, 34, 146, 163, 215, 240, 56, 215, 28, 198, 98, 215, 65, 100, 79, 186, 4, 16, 48, 182, 133, 247, 145, 224, 105, 116, 242, 23, 145, 210, 112, 0, 9, 158, 180, 45, 156, 231, 58, 136, 236, 73, 51, 0, 1, 97, 231, 18, 98, 18, 255, 3, 124, 9, 253, 115, 17, 145, 210, 99, 129, 255, 101, 27, 159, 55, 179, 233, 113, 29, 70, 116, 162, 9, 4, 187, 128, 38, 60, 110, 1, 78, 118, 157, 69, 68, 36, 207, 30, 165, 130, 15, 152, 131, 89, 231, 58, 72, 185, 83, 1, 112, 204, 46, 96, 6, 30, 119, 2, 227, 93, 103, 17, 17, 41, 144, 149, 36, 57, 207, 204, 226, 105, 215, 65, 202, 153, 214, 0, 56, 100, 91, 184, 20, 143, 249, 232, 228, 47, 34, 229, 101, 52, 30, 143, 218, 133, 124, 196, 117, 144, 114, 166, 25, 0, 7, 236, 18, 162, 108, 231, 127, 49, 250, 151, 95, 68, 202, 222, 31, 232, 228, 99, 230, 24, 58, 92, 7, 41, 55, 42, 0, 5, 102, 91, 24, 9, 220, 13, 28, 238, 58, 139, 136, 72, 32, 24, 158, 166, 155, 179, 205, 17, 172, 117, 29, 165, 156, 168, 0, 20, 144, 125, 142, 131, 72, 112, 63, 48, 214, 117, 22, 17, 145, 128, 89, 133, 225, 76, 51, 157, 69, 174, 131, 148, 11, 173, 1, 40, 16, 219, 194, 73, 36, 152, 143, 78, 254, 34, 34, 189, 25, 69, 146, 199, 108, 11, 167, 187, 14, 82, 46, 84, 0, 10, 192, 54, 243, 97, 224, 1, 160, 222, 117, 22, 17, 145, 192, 50, 212, 2, 247, 218, 102, 62, 230, 58, 74, 57, 80, 1, 200, 35, 107, 49, 182, 153, 111, 98, 184, 30, 168, 112, 157, 71, 68, 164, 8, 132, 49, 252, 218, 182, 240, 51, 107, 117, 153, 58, 159, 244, 127, 110, 158, 236, 92, 233, 255, 59, 140, 158, 136, 37, 34, 146, 165, 219, 217, 198, 165, 102, 54, 157, 174, 131, 148, 34, 21, 128, 60, 176, 139, 25, 68, 156, 187, 208, 35, 124, 69, 68, 114, 245, 4, 73, 230, 152, 89, 108, 116, 29, 164, 212, 168, 0, 248, 204, 62, 203, 126, 132, 184, 31, 56, 208, 117, 22, 17, 145, 18, 241, 58, 134, 247, 154, 233, 44, 113, 29, 164, 148, 104, 13, 128, 143, 236, 34, 142, 32, 196, 83, 232, 228, 47, 34, 226, 167, 73, 88, 254, 101, 155, 153, 233, 58, 72, 41, 81, 1, 240, 137, 93, 200, 187, 73, 242, 16, 48, 196, 117, 22, 17, 145, 18, 52, 12, 195, 35, 118, 17, 179, 93, 7, 41, 21, 42, 0, 62, 176, 205, 156, 133, 229, 65, 160, 206, 117, 22, 17, 145, 18, 86, 67, 146, 251, 236, 34, 78, 113, 29, 164, 20, 168, 0, 228, 200, 54, 243, 111, 24, 238, 2, 98, 174, 179, 136, 136, 148, 129, 42, 146, 252, 197, 54, 115, 142, 235, 32, 197, 78, 5, 32, 7, 182, 153, 207, 98, 184, 9, 8, 187, 206, 34, 34, 82, 70, 34, 24, 110, 179, 205, 124, 192, 117, 144, 98, 166, 2, 144, 37, 187, 144, 47, 98, 184, 26, 221, 73, 33, 34, 226, 66, 5, 134, 155, 109, 11, 87, 184, 14, 82, 172, 84, 0, 178, 96, 91, 248, 50, 150, 31, 186, 206, 33, 34, 82, 230, 66, 192, 181, 182, 153, 207, 184, 14, 82, 140, 84, 0, 50, 100, 155, 249, 38, 240, 125, 215, 57, 68, 68, 4, 0, 131, 225, 26, 187, 144, 111, 184, 14, 82, 108, 52, 125, 157, 1, 219, 194, 119, 128, 175, 186, 206, 33, 34, 34, 189, 250, 129, 153, 193, 127, 186, 14, 81, 44, 52, 3, 144, 38, 219, 204, 255, 160, 147, 191, 136, 72, 144, 125, 217, 182, 240, 109, 215, 33, 138, 133, 102, 0, 210, 160, 79, 254, 34, 34, 69, 229, 191, 204, 12, 93, 170, 29, 136, 10, 192, 0, 108, 11, 95, 7, 190, 229, 58, 135, 248, 47, 105, 61, 190, 123, 255, 23, 125, 27, 111, 253, 198, 78, 54, 111, 139, 251, 54, 158, 192, 193, 35, 54, 242, 229, 115, 238, 208, 195, 180, 37, 27, 159, 55, 51, 184, 218, 117, 136, 32, 211, 253, 235, 253, 176, 45, 124, 30, 157, 252, 75, 218, 166, 29, 131, 124, 27, 171, 45, 190, 137, 174, 238, 14, 223, 198, 19, 104, 235, 136, 194, 114, 96, 60, 42, 1, 146, 169, 31, 219, 133, 180, 154, 233, 92, 235, 58, 72, 80, 105, 13, 64, 31, 118, 222, 86, 242, 99, 215, 57, 68, 202, 94, 23, 169, 18, 208, 237, 56, 135, 20, 27, 131, 229, 255, 180, 89, 80, 223, 84, 0, 122, 97, 91, 184, 100, 231, 38, 63, 34, 18, 4, 42, 1, 146, 157, 16, 134, 63, 216, 102, 206, 114, 29, 36, 136, 84, 0, 246, 98, 23, 50, 7, 184, 30, 173, 143, 16, 9, 22, 149, 0, 201, 78, 5, 134, 59, 108, 11, 167, 187, 14, 18, 52, 42, 0, 187, 177, 205, 188, 7, 203, 159, 208, 218, 8, 145, 96, 82, 9, 144, 236, 68, 128, 59, 108, 11, 39, 184, 14, 18, 36, 42, 0, 59, 217, 69, 28, 129, 225, 30, 244, 84, 63, 145, 96, 83, 9, 144, 236, 84, 1, 247, 218, 102, 102, 186, 14, 18, 20, 42, 0, 128, 125, 142, 9, 36, 249, 11, 80, 227, 58, 139, 136, 164, 65, 37, 64, 178, 83, 143, 225, 175, 182, 153, 73, 174, 131, 4, 65, 217, 23, 0, 187, 152, 65, 244, 240, 32, 48, 212, 117, 22, 17, 201, 128, 74, 128, 100, 167, 9, 195, 95, 236, 243, 52, 186, 14, 226, 90, 89, 23, 0, 187, 152, 8, 113, 110, 199, 48, 217, 117, 22, 17, 201, 130, 74, 128, 100, 231, 64, 122, 184, 219, 46, 33, 234, 58, 136, 75, 101, 91, 0, 172, 197, 16, 231, 58, 224, 61, 174, 179, 136, 72, 14, 84, 2, 36, 59, 39, 208, 202, 13, 214, 150, 239, 29, 95, 101, 91, 0, 104, 225, 191, 129, 75, 92, 199, 16, 17, 31, 168, 4, 72, 118, 46, 164, 165, 124, 31, 35, 92, 150, 5, 192, 182, 112, 57, 134, 175, 184, 206, 33, 34, 62, 82, 9, 144, 108, 24, 190, 110, 23, 242, 33, 215, 49, 92, 40, 187, 2, 96, 23, 242, 110, 224, 255, 92, 231, 16, 145, 60, 80, 9, 144, 204, 25, 44, 215, 218, 22, 78, 114, 29, 164, 208, 202, 170, 0, 216, 22, 166, 98, 249, 51, 169, 77, 33, 68, 164, 20, 169, 4, 72, 230, 42, 128, 59, 237, 2, 14, 118, 29, 164, 144, 202, 166, 0, 216, 5, 140, 0, 30, 4, 26, 92, 103, 17, 145, 60, 83, 9, 144, 204, 213, 225, 113, 175, 125, 134, 225, 174, 131, 20, 74, 89, 20, 0, 59, 143, 24, 30, 247, 0, 99, 93, 103, 17, 145, 2, 81, 9, 144, 204, 141, 39, 204, 159, 203, 229, 246, 192, 178, 40, 0, 212, 243, 11, 224, 112, 215, 49, 68, 164, 192, 84, 2, 36, 115, 71, 209, 202, 207, 92, 135, 40, 132, 146, 47, 0, 182, 153, 143, 2, 87, 184, 206, 33, 34, 142, 168, 4, 72, 230, 62, 102, 91, 74, 255, 188, 81, 210, 5, 96, 231, 3, 126, 126, 238, 58, 135, 136, 56, 166, 18, 32, 153, 251, 133, 109, 97, 150, 235, 16, 249, 84, 178, 5, 192, 62, 205, 96, 146, 220, 6, 229, 113, 45, 71, 68, 6, 160, 18, 32, 153, 137, 145, 186, 51, 160, 201, 117, 144, 124, 41, 201, 2, 96, 231, 18, 34, 204, 45, 192, 120, 215, 89, 68, 36, 64, 84, 2, 36, 51, 99, 241, 248, 147, 157, 75, 200, 117, 144, 124, 40, 201, 2, 192, 68, 190, 143, 225, 20, 215, 49, 68, 36, 128, 84, 2, 36, 51, 39, 50, 145, 111, 187, 14, 145, 15, 37, 87, 0, 236, 66, 206, 198, 240, 121, 215, 57, 68, 36, 192, 84, 2, 36, 19, 134, 255, 178, 45, 156, 231, 58, 134, 223, 74, 170, 0, 216, 231, 152, 140, 229, 70, 40, 223, 167, 59, 137, 72, 154, 84, 2, 36, 125, 6, 203, 245, 182, 133, 169, 174, 131, 248, 169, 100, 10, 128, 125, 138, 58, 122, 184, 7, 168, 115, 157, 69, 68, 138, 132, 74, 128, 164, 203, 80, 11, 220, 110, 23, 83, 227, 58, 138, 95, 74, 166, 0, 16, 225, 23, 24, 38, 187, 142, 33, 34, 69, 70, 37, 64, 210, 55, 149, 56, 63, 117, 29, 194, 47, 37, 81, 0, 118, 94, 155, 185, 196, 117, 14, 17, 41, 82, 42, 1, 146, 190, 43, 108, 51, 31, 112, 29, 194, 15, 69, 95, 0, 236, 115, 140, 6, 126, 227, 58, 135, 136, 20, 57, 149, 0, 73, 151, 225, 215, 118, 65, 241, 63, 91, 166, 168, 11, 128, 181, 120, 244, 112, 19, 48, 200, 117, 22, 17, 41, 1, 42, 1, 146, 158, 6, 60, 254, 80, 236, 251, 3, 20, 117, 1, 160, 133, 255, 194, 48, 219, 117, 12, 17, 41, 33, 42, 1, 146, 158, 19, 152, 88, 220, 183, 156, 23, 109, 1, 176, 205, 204, 196, 240, 117, 215, 57, 68, 164, 4, 169, 4, 72, 58, 12, 255, 109, 23, 113, 132, 235, 24, 217, 42, 202, 2, 96, 159, 163, 26, 184, 25, 136, 184, 206, 34, 34, 37, 170, 140, 74, 64, 34, 49, 201, 117, 132, 98, 85, 65, 146, 155, 139, 245, 214, 192, 162, 44, 0, 36, 248, 153, 110, 249, 19, 145, 188, 43, 131, 18, 208, 29, 61, 130, 246, 170, 207, 194, 54, 215, 73, 138, 214, 36, 226, 252, 200, 117, 136, 108, 20, 93, 1, 176, 205, 156, 3, 165, 255, 156, 102, 17, 9, 136, 18, 47, 1, 157, 213, 23, 210, 217, 116, 46, 118, 117, 165, 74, 64, 246, 254, 195, 46, 100, 142, 235, 16, 153, 42, 170, 2, 96, 23, 49, 10, 195, 181, 174, 115, 136, 72, 153, 41, 213, 18, 96, 194, 196, 171, 207, 197, 134, 235, 232, 26, 118, 58, 172, 68, 37, 32, 91, 150, 235, 236, 2, 70, 184, 142, 145, 137, 162, 42, 0, 36, 249, 37, 48, 216, 117, 12, 17, 41, 67, 37, 88, 2, 186, 98, 39, 145, 244, 134, 0, 208, 57, 242, 252, 212, 55, 85, 2, 178, 213, 84, 108, 31, 80, 139, 166, 0, 216, 22, 46, 132, 226, 155, 98, 17, 145, 18, 82, 98, 37, 160, 179, 250, 130, 183, 255, 186, 107, 200, 105, 36, 43, 26, 83, 191, 81, 9, 200, 142, 225, 12, 187, 144, 139, 93, 199, 72, 87, 81, 20, 0, 187, 152, 65, 80, 58, 251, 47, 139, 72, 17, 43, 145, 18, 96, 77, 21, 241, 170, 51, 222, 249, 189, 23, 33, 62, 252, 125, 239, 188, 64, 37, 32, 59, 150, 159, 219, 23, 24, 230, 58, 70, 58, 138, 162, 0, 16, 231, 106, 40, 142, 255, 67, 69, 164, 12, 148, 64, 9, 136, 87, 157, 137, 53, 123, 222, 189, 22, 31, 121, 193, 158, 47, 82, 9, 200, 198, 96, 186, 139, 99, 123, 250, 192, 23, 0, 187, 136, 217, 192, 165, 174, 115, 136, 136, 236, 161, 200, 75, 64, 188, 234, 252, 125, 190, 215, 53, 232, 4, 146, 177, 145, 123, 126, 83, 37, 32, 27, 115, 118, 62, 164, 46, 208, 2, 93, 0, 236, 2, 170, 72, 114, 45, 96, 92, 103, 17, 17, 217, 71, 145, 150, 0, 235, 53, 208, 85, 121, 226, 190, 63, 48, 30, 157, 35, 222, 191, 239, 247, 85, 2, 178, 241, 11, 251, 60, 141, 174, 67, 244, 39, 208, 5, 0, 143, 239, 0, 19, 93, 199, 16, 17, 233, 83, 17, 150, 128, 206, 234, 115, 177, 38, 218, 235, 207, 226, 35, 247, 157, 25, 0, 84, 2, 50, 55, 140, 30, 190, 235, 58, 68, 127, 2, 91, 0, 236, 66, 14, 7, 174, 114, 157, 67, 68, 100, 64, 69, 86, 2, 226, 213, 23, 244, 249, 179, 238, 250, 153, 36, 170, 247, 239, 253, 135, 42, 1, 153, 250, 168, 93, 200, 49, 174, 67, 244, 37, 144, 5, 192, 206, 35, 76, 146, 223, 64, 113, 63, 106, 81, 68, 202, 72, 145, 148, 128, 100, 104, 4, 93, 145, 254, 207, 73, 157, 35, 250, 185, 124, 173, 18, 144, 9, 143, 36, 191, 177, 11, 168, 112, 29, 164, 55, 129, 44, 0, 52, 240, 37, 12, 211, 93, 199, 16, 17, 201, 72, 17, 148, 128, 206, 234, 11, 192, 244, 255, 217, 170, 115, 84, 223, 51, 4, 128, 74, 64, 38, 12, 7, 225, 241, 57, 215, 49, 122, 19, 184, 2, 96, 23, 48, 17, 203, 215, 92, 231, 16, 17, 201, 74, 192, 75, 64, 103, 63, 211, 255, 187, 36, 170, 15, 160, 167, 238, 176, 254, 95, 164, 18, 144, 137, 175, 219, 22, 198, 185, 14, 177, 183, 192, 21, 0, 60, 174, 1, 98, 174, 99, 136, 136, 100, 45, 160, 37, 32, 81, 113, 0, 61, 145, 1, 78, 236, 59, 117, 238, 189, 39, 64, 111, 84, 2, 210, 85, 5, 252, 216, 117, 136, 189, 5, 170, 0, 216, 69, 156, 2, 156, 229, 58, 135, 136, 72, 206, 2, 88, 2, 210, 249, 244, 255, 246, 107, 71, 13, 124, 169, 0, 80, 9, 72, 223, 121, 182, 153, 83, 93, 135, 216, 93, 96, 10, 128, 93, 76, 132, 4, 63, 119, 157, 67, 68, 196, 55, 1, 43, 1, 157, 213, 233, 239, 77, 147, 140, 142, 160, 171, 49, 205, 5, 236, 42, 1, 233, 49, 92, 19, 164, 5, 129, 129, 41, 0, 116, 241, 121, 12, 147, 93, 199, 16, 17, 241, 85, 64, 74, 64, 79, 100, 6, 137, 112, 31, 183, 247, 245, 161, 207, 61, 1, 122, 163, 18, 144, 142, 41, 120, 124, 202, 117, 136, 93, 194, 174, 3, 0, 216, 69, 140, 34, 201, 87, 92, 231, 16, 9, 34, 99, 12, 198, 148, 231, 102, 152, 17, 47, 233, 58, 130, 63, 118, 149, 128, 241, 224, 234, 243, 95, 103, 117, 6, 39, 243, 157, 226, 35, 206, 165, 230, 165, 47, 96, 146, 93, 233, 189, 97, 229, 206, 175, 245, 25, 31, 170, 156, 124, 195, 190, 192, 205, 230, 96, 214, 185, 14, 18, 136, 2, 64, 146, 255, 1, 106, 6, 124, 157, 72, 25, 154, 58, 116, 59, 223, 152, 113, 171, 235, 24, 146, 43, 167, 37, 192, 203, 104, 250, 127, 151, 100, 69, 35, 221, 77, 179, 137, 172, 255, 91, 250, 111, 82, 9, 24, 72, 29, 61, 124, 27, 248, 152, 235, 32, 206, 47, 1, 216, 22, 14, 5, 46, 113, 157, 67, 68, 36, 239, 28, 93, 14, 232, 138, 30, 75, 50, 52, 114, 224, 23, 246, 162, 115, 68, 250, 11, 7, 223, 166, 203, 1, 253, 179, 92, 97, 23, 112, 176, 235, 24, 206, 11, 0, 169, 91, 35, 130, 144, 67, 68, 36, 255, 28, 148, 128, 254, 182, 254, 29, 240, 189, 195, 206, 196, 122, 149, 153, 191, 81, 37, 160, 63, 33, 60, 126, 234, 58, 132, 211, 19, 175, 109, 230, 76, 224, 36, 151, 25, 68, 68, 10, 174, 144, 37, 192, 84, 16, 175, 58, 59, 235, 183, 219, 112, 13, 93, 67, 79, 203, 238, 205, 42, 1, 253, 121, 143, 235, 219, 2, 157, 21, 0, 59, 143, 48, 134, 31, 186, 58, 190, 136, 136, 83, 5, 42, 1, 241, 202, 147, 72, 134, 6, 229, 52, 70, 103, 38, 119, 3, 236, 77, 37, 160, 63, 63, 182, 115, 221, 61, 243, 198, 221, 12, 64, 29, 151, 3, 83, 156, 29, 95, 68, 196, 181, 2, 148, 128, 206, 170, 139, 114, 30, 163, 107, 232, 233, 36, 35, 131, 179, 31, 64, 37, 160, 119, 134, 131, 216, 223, 221, 26, 56, 39, 5, 192, 206, 35, 134, 225, 171, 46, 142, 45, 34, 18, 40, 121, 44, 1, 201, 208, 32, 186, 170, 206, 204, 121, 28, 235, 69, 232, 28, 121, 97, 110, 131, 168, 4, 244, 206, 242, 77, 187, 132, 168, 139, 67, 187, 153, 1, 104, 224, 147, 192, 24, 39, 199, 22, 17, 9, 154, 60, 149, 128, 206, 234, 15, 98, 141, 63, 231, 150, 206, 49, 151, 229, 62, 136, 74, 64, 111, 198, 209, 234, 230, 150, 192, 130, 23, 0, 59, 159, 90, 44, 95, 44, 244, 113, 69, 68, 2, 45, 15, 37, 160, 179, 250, 223, 124, 27, 171, 167, 118, 42, 221, 245, 179, 114, 31, 72, 37, 160, 55, 95, 181, 243, 169, 45, 244, 65, 11, 63, 3, 80, 197, 151, 128, 161, 5, 63, 174, 136, 72, 208, 249, 88, 2, 186, 163, 71, 210, 19, 57, 40, 247, 129, 118, 211, 57, 230, 67, 254, 12, 164, 18, 176, 183, 33, 84, 113, 85, 161, 15, 90, 208, 2, 96, 23, 208, 132, 45, 252, 223, 164, 136, 72, 209, 240, 169, 4, 116, 212, 94, 238, 67, 152, 61, 117, 142, 60, 31, 27, 246, 233, 131, 170, 74, 192, 222, 190, 96, 159, 167, 177, 144, 7, 44, 236, 12, 128, 199, 23, 48, 133, 159, 230, 16, 17, 41, 42, 57, 150, 128, 100, 104, 20, 241, 170, 236, 55, 255, 233, 139, 13, 215, 210, 49, 238, 35, 254, 13, 168, 18, 176, 187, 122, 122, 248, 76, 33, 15, 88, 176, 2, 96, 159, 102, 48, 150, 43, 11, 117, 60, 17, 145, 162, 150, 67, 9, 216, 81, 255, 25, 172, 137, 248, 28, 40, 165, 125, 252, 39, 177, 161, 42, 255, 6, 84, 9, 216, 221, 103, 10, 57, 11, 80, 184, 25, 128, 10, 62, 175, 79, 255, 34, 34, 25, 200, 162, 4, 36, 42, 38, 208, 89, 115, 69, 158, 2, 65, 50, 58, 140, 246, 9, 159, 246, 119, 80, 149, 128, 93, 234, 232, 46, 220, 101, 242, 130, 20, 0, 187, 152, 65, 88, 62, 89, 136, 99, 137, 136, 148, 148, 12, 75, 64, 91, 227, 15, 124, 187, 245, 175, 47, 237, 19, 63, 75, 162, 210, 231, 59, 185, 85, 2, 82, 76, 225, 102, 1, 10, 51, 3, 208, 197, 231, 244, 233, 95, 68, 36, 75, 105, 150, 128, 206, 154, 75, 137, 87, 158, 145, 247, 56, 54, 84, 195, 246, 67, 127, 7, 198, 231, 93, 108, 85, 2, 0, 234, 73, 224, 243, 20, 75, 239, 242, 94, 0, 236, 83, 212, 97, 249, 68, 190, 143, 35, 34, 82, 210, 6, 40, 1, 61, 145, 67, 105, 29, 244, 163, 130, 197, 233, 30, 116, 44, 59, 14, 200, 195, 134, 174, 42, 1, 96, 185, 202, 46, 166, 38, 223, 135, 201, 255, 12, 64, 132, 43, 129, 134, 188, 31, 71, 68, 164, 212, 245, 81, 2, 18, 21, 251, 177, 117, 232, 157, 88, 147, 247, 115, 198, 30, 118, 76, 252, 18, 29, 227, 62, 234, 255, 192, 42, 1, 141, 196, 249, 112, 190, 15, 146, 215, 2, 176, 115, 127, 227, 130, 76, 101, 136, 136, 148, 133, 189, 74, 64, 119, 244, 112, 182, 12, 127, 152, 100, 104, 132, 147, 56, 173, 211, 174, 97, 199, 254, 255, 15, 48, 254, 14, 172, 18, 240, 89, 59, 143, 112, 62, 15, 144, 223, 25, 128, 237, 92, 6, 184, 249, 183, 82, 68, 164, 84, 117, 1, 203, 13, 237, 213, 159, 96, 235, 176, 191, 145, 244, 134, 56, 141, 179, 99, 255, 175, 176, 245, 136, 191, 144, 140, 141, 244, 119, 224, 242, 46, 1, 19, 104, 224, 156, 124, 30, 32, 111, 5, 192, 206, 37, 132, 225, 243, 249, 26, 95, 68, 164, 92, 117, 55, 28, 193, 150, 153, 255, 160, 173, 233, 135, 121, 95, 241, 159, 174, 174, 166, 217, 108, 58, 126, 1, 237, 19, 63, 135, 245, 98, 254, 13, 92, 206, 37, 32, 207, 207, 205, 201, 223, 12, 192, 36, 206, 1, 246, 207, 219, 248, 34, 34, 101, 166, 123, 208, 113, 108, 61, 252, 110, 182, 28, 51, 143, 238, 198, 163, 92, 199, 217, 135, 173, 168, 167, 109, 242, 119, 216, 124, 66, 11, 29, 227, 62, 134, 245, 42, 253, 25, 184, 124, 75, 192, 225, 118, 1, 199, 229, 107, 240, 124, 94, 95, 248, 92, 30, 199, 22, 17, 41, 11, 54, 92, 75, 231, 200, 243, 233, 28, 115, 25, 221, 245, 51, 93, 199, 73, 75, 162, 106, 28, 173, 211, 174, 102, 199, 164, 175, 16, 91, 117, 51, 149, 111, 221, 64, 104, 199, 107, 185, 13, 186, 114, 231, 215, 250, 156, 227, 21, 151, 212, 76, 250, 252, 124, 12, 157, 151, 2, 96, 155, 153, 9, 28, 157, 143, 177, 69, 68, 202, 65, 79, 221, 116, 58, 198, 94, 78, 231, 168, 11, 176, 161, 194, 174, 238, 247, 75, 50, 218, 68, 251, 126, 87, 209, 190, 223, 85, 132, 183, 47, 164, 114, 197, 245, 196, 86, 205, 197, 36, 218, 178, 27, 176, 28, 75, 128, 97, 142, 109, 102, 138, 153, 201, 203, 126, 15, 157, 159, 25, 0, 163, 79, 255, 34, 34, 153, 74, 84, 239, 71, 231, 240, 243, 136, 143, 186, 144, 158, 154, 201, 174, 227, 248, 170, 167, 110, 58, 173, 7, 253, 47, 109, 7, 126, 151, 232, 218, 63, 19, 91, 61, 151, 200, 166, 199, 192, 38, 50, 27, 168, 252, 74, 128, 193, 240, 105, 224, 227, 126, 15, 236, 123, 1, 176, 45, 140, 4, 206, 243, 123, 92, 17, 145, 82, 148, 140, 12, 34, 62, 252, 108, 58, 71, 93, 188, 243, 186, 190, 207, 183, 211, 5, 140, 13, 215, 210, 57, 250, 82, 58, 71, 95, 138, 215, 181, 153, 232, 218, 187, 137, 173, 190, 149, 138, 205, 79, 2, 54, 189, 65, 202, 175, 4, 92, 102, 95, 224, 155, 230, 96, 214, 249, 57, 168, 255, 51, 0, 150, 79, 96, 200, 207, 99, 168, 68, 68, 74, 128, 173, 104, 160, 115, 248, 217, 196, 71, 94, 64, 215, 160, 227, 252, 223, 82, 183, 72, 36, 35, 131, 232, 24, 123, 57, 29, 99, 47, 39, 212, 190, 156, 232, 154, 59, 136, 173, 158, 75, 184, 117, 241, 192, 111, 46, 175, 18, 16, 163, 135, 255, 0, 190, 229, 231, 160, 190, 22, 0, 187, 132, 40, 173, 248, 248, 176, 104, 17, 145, 210, 96, 189, 24, 93, 67, 222, 67, 231, 200, 139, 232, 26, 118, 38, 214, 211, 231, 164, 221, 37, 170, 198, 211, 62, 241, 11, 180, 79, 252, 2, 225, 182, 87, 136, 174, 185, 139, 216, 170, 63, 17, 106, 127, 163, 239, 55, 149, 83, 9, 176, 92, 105, 151, 240, 125, 179, 63, 113, 191, 134, 244, 119, 6, 96, 59, 231, 99, 112, 187, 35, 133, 136, 72, 80, 152, 16, 221, 141, 71, 210, 57, 242, 34, 58, 71, 94, 128, 13, 23, 231, 98, 190, 66, 235, 169, 57, 144, 158, 253, 191, 194, 142, 253, 191, 66, 120, 251, 66, 98, 43, 111, 37, 182, 230, 14, 188, 120, 47, 51, 224, 229, 83, 2, 134, 210, 202, 185, 192, 173, 126, 13, 232, 111, 1, 48, 254, 47, 82, 16, 17, 41, 54, 61, 117, 211, 233, 24, 125, 49, 241, 145, 231, 145, 140, 12, 117, 29, 167, 168, 245, 212, 77, 167, 109, 234, 116, 218, 166, 124, 143, 138, 173, 207, 16, 91, 117, 11, 177, 213, 183, 99, 122, 90, 223, 121, 81, 249, 148, 128, 255, 32, 136, 5, 192, 54, 115, 8, 112, 140, 95, 227, 137, 136, 20, 147, 158, 218, 41, 196, 135, 159, 75, 231, 168, 15, 144, 168, 154, 232, 58, 78, 233, 49, 33, 186, 27, 143, 166, 187, 241, 104, 218, 166, 254, 136, 200, 198, 121, 68, 215, 220, 69, 116, 237, 221, 152, 68, 123, 185, 148, 128, 19, 236, 115, 28, 100, 14, 229, 69, 63, 6, 243, 111, 6, 64, 159, 254, 69, 164, 204, 36, 98, 163, 137, 15, 159, 67, 231, 232, 139, 233, 169, 59, 204, 117, 156, 178, 97, 189, 24, 241, 161, 167, 19, 31, 122, 58, 102, 218, 79, 136, 174, 187, 159, 232, 218, 187, 136, 174, 250, 59, 208, 83, 218, 37, 32, 193, 71, 128, 171, 252, 24, 202, 151, 2, 96, 23, 83, 67, 156, 139, 253, 24, 75, 68, 36, 200, 108, 168, 154, 206, 81, 31, 160, 115, 228, 69, 116, 15, 58, 154, 82, 191, 109, 47, 232, 108, 184, 142, 206, 81, 23, 209, 57, 234, 34, 188, 248, 26, 98, 171, 230, 82, 217, 121, 3, 161, 88, 142, 59, 15, 6, 215, 135, 236, 115, 124, 197, 28, 202, 142, 92, 7, 242, 231, 89, 0, 93, 92, 4, 212, 249, 50, 150, 136, 72, 128, 153, 196, 14, 194, 219, 95, 32, 220, 250, 2, 94, 215, 102, 215, 113, 100, 23, 155, 32, 220, 250, 18, 225, 214, 231, 241, 150, 175, 42, 229, 103, 7, 212, 147, 228, 124, 63, 6, 242, 231, 18, 128, 229, 114, 95, 198, 17, 17, 41, 2, 21, 91, 159, 165, 98, 235, 179, 212, 190, 244, 69, 186, 6, 159, 64, 231, 168, 15, 18, 31, 118, 150, 86, 249, 59, 16, 110, 123, 133, 216, 170, 155, 137, 173, 188, 5, 47, 190, 246, 157, 31, 148, 242, 154, 0, 203, 135, 129, 27, 114, 29, 38, 231, 2, 96, 159, 99, 50, 9, 142, 204, 117, 28, 17, 145, 162, 99, 19, 68, 54, 206, 35, 178, 113, 158, 238, 243, 47, 160, 112, 219, 171, 68, 215, 220, 73, 108, 245, 92, 66, 59, 150, 244, 253, 194, 210, 45, 1, 199, 219, 102, 38, 153, 153, 188, 158, 203, 32, 185, 207, 0, 244, 112, 5, 70, 23, 193, 68, 164, 188, 153, 100, 39, 209, 117, 15, 16, 93, 247, 0, 182, 162, 158, 248, 208, 51, 136, 143, 56, 151, 248, 144, 147, 193, 228, 243, 193, 171, 229, 193, 235, 92, 69, 116, 237, 61, 196, 214, 254, 153, 138, 205, 79, 164, 255, 198, 210, 44, 1, 6, 143, 203, 128, 175, 230, 50, 72, 78, 255, 86, 218, 121, 132, 49, 252, 91, 46, 99, 136, 136, 148, 26, 211, 189, 45, 117, 191, 250, 170, 91, 72, 198, 70, 210, 57, 252, 28, 226, 35, 206, 161, 187, 81, 15, 73, 205, 132, 233, 222, 74, 116, 253, 131, 196, 86, 221, 76, 100, 211, 163, 96, 147, 217, 13, 84, 138, 37, 192, 114, 153, 157, 203, 55, 204, 5, 100, 248, 52, 165, 119, 228, 86, 75, 235, 56, 29, 24, 145, 211, 24, 34, 34, 37, 204, 235, 92, 77, 213, 242, 95, 82, 181, 252, 151, 36, 170, 198, 17, 31, 241, 126, 58, 70, 95, 74, 162, 122, 127, 215, 209, 2, 201, 36, 59, 136, 108, 124, 132, 216, 170, 91, 136, 172, 187, 15, 147, 236, 242, 103, 224, 210, 43, 1, 163, 152, 200, 73, 192, 223, 178, 29, 32, 183, 2, 96, 184, 36, 167, 247, 139, 136, 148, 145, 80, 251, 155, 84, 189, 113, 53, 85, 111, 92, 77, 119, 253, 76, 226, 35, 207, 163, 115, 196, 251, 73, 198, 70, 185, 142, 230, 148, 73, 196, 137, 108, 124, 136, 232, 154, 59, 136, 174, 123, 0, 147, 200, 249, 14, 183, 222, 149, 94, 9, 184, 4, 23, 5, 192, 206, 167, 22, 56, 51, 219, 247, 139, 136, 148, 179, 138, 109, 205, 84, 108, 107, 166, 230, 149, 255, 71, 119, 227, 81, 169, 203, 4, 229, 180, 117, 176, 77, 82, 177, 245, 105, 162, 107, 254, 76, 108, 245, 159, 240, 186, 54, 21, 230, 184, 165, 84, 2, 12, 103, 219, 197, 212, 152, 105, 180, 101, 243, 246, 236, 103, 0, 170, 57, 23, 75, 101, 214, 239, 23, 17, 145, 212, 137, 112, 243, 19, 84, 108, 126, 130, 218, 87, 190, 66, 215, 224, 217, 116, 142, 188, 144, 248, 136, 57, 88, 47, 230, 58, 157, 239, 42, 182, 53, 19, 91, 121, 51, 209, 53, 127, 198, 235, 90, 239, 38, 68, 233, 148, 128, 106, 226, 156, 69, 150, 207, 7, 200, 190, 0, 36, 185, 88, 107, 255, 69, 68, 124, 148, 236, 38, 178, 225, 239, 68, 54, 252, 29, 187, 184, 142, 206, 145, 231, 209, 49, 246, 138, 162, 223, 102, 216, 244, 108, 39, 182, 250, 14, 42, 223, 186, 142, 240, 182, 231, 92, 199, 73, 41, 157, 18, 112, 17, 133, 44, 0, 246, 57, 134, 146, 224, 61, 217, 188, 87, 68, 68, 6, 102, 122, 182, 83, 185, 226, 122, 42, 87, 92, 159, 122, 186, 224, 152, 203, 232, 28, 125, 49, 54, 84, 229, 58, 90, 218, 42, 54, 63, 78, 229, 138, 235, 136, 174, 189, 23, 147, 236, 116, 29, 103, 95, 165, 81, 2, 78, 179, 79, 51, 216, 28, 73, 198, 215, 80, 178, 219, 10, 56, 193, 133, 248, 253, 40, 97, 17, 17, 233, 85, 120, 251, 66, 106, 23, 95, 197, 224, 71, 166, 80, 253, 250, 247, 49, 61, 89, 93, 242, 45, 152, 232, 250, 7, 105, 124, 242, 61, 52, 62, 117, 10, 177, 213, 115, 131, 121, 242, 223, 101, 37, 197, 190, 109, 112, 5, 21, 217, 109, 13, 156, 237, 179, 0, 46, 200, 242, 125, 34, 34, 146, 37, 47, 190, 145, 234, 215, 190, 195, 224, 71, 14, 166, 242, 173, 223, 3, 214, 117, 164, 61, 132, 183, 191, 72, 195, 83, 167, 83, 191, 224, 60, 42, 182, 60, 237, 58, 78, 250, 138, 191, 4, 20, 166, 0, 216, 103, 24, 14, 104, 55, 11, 17, 17, 71, 188, 174, 245, 212, 190, 240, 73, 26, 158, 57, 11, 175, 115, 149, 235, 56, 96, 147, 84, 189, 241, 19, 26, 159, 56, 158, 200, 230, 199, 92, 167, 201, 78, 113, 151, 128, 119, 217, 231, 200, 248, 246, 145, 204, 103, 0, 42, 56, 55, 171, 247, 137, 136, 136, 175, 34, 27, 231, 49, 232, 241, 227, 9, 111, 95, 232, 44, 131, 73, 196, 169, 95, 116, 25, 53, 175, 126, 221, 191, 77, 123, 92, 41, 222, 18, 16, 34, 201, 251, 50, 125, 83, 230, 39, 114, 203, 251, 51, 126, 143, 136, 136, 228, 133, 23, 95, 71, 227, 83, 167, 17, 222, 214, 82, 240, 99, 155, 100, 23, 245, 11, 206, 37, 186, 230, 206, 130, 31, 59, 111, 138, 181, 4, 100, 113, 110, 206, 168, 0, 216, 167, 25, 12, 156, 144, 233, 65, 68, 68, 36, 127, 76, 79, 27, 13, 207, 190, 159, 80, 199, 138, 130, 30, 183, 246, 249, 143, 17, 217, 244, 72, 65, 143, 89, 16, 197, 89, 2, 78, 180, 207, 211, 152, 201, 27, 50, 155, 1, 8, 243, 62, 180, 250, 95, 68, 36, 112, 188, 174, 245, 212, 45, 186, 28, 108, 214, 207, 134, 201, 72, 229, 91, 55, 18, 91, 61, 183, 32, 199, 114, 162, 248, 74, 64, 5, 61, 153, 237, 206, 155, 89, 1, 48, 156, 157, 209, 235, 69, 68, 164, 96, 42, 182, 60, 73, 213, 155, 191, 206, 251, 113, 188, 248, 26, 106, 94, 254, 82, 222, 143, 227, 92, 241, 149, 128, 140, 214, 1, 164, 93, 0, 236, 18, 162, 160, 205, 127, 68, 68, 130, 172, 122, 201, 119, 241, 186, 54, 231, 245, 24, 53, 175, 126, 51, 240, 123, 17, 248, 166, 184, 74, 192, 105, 59, 207, 213, 105, 73, 127, 6, 160, 141, 19, 129, 154, 108, 18, 137, 136, 72, 97, 152, 238, 173, 84, 45, 187, 38, 111, 227, 135, 219, 94, 37, 182, 234, 150, 188, 141, 31, 72, 197, 83, 2, 106, 104, 229, 248, 116, 95, 156, 126, 1, 176, 122, 242, 159, 136, 72, 49, 168, 124, 243, 90, 76, 119, 126, 206, 88, 85, 75, 175, 6, 155, 204, 203, 216, 129, 86, 44, 37, 192, 112, 70, 186, 47, 205, 100, 13, 192, 123, 179, 136, 34, 34, 34, 5, 102, 122, 90, 169, 92, 113, 189, 239, 227, 122, 241, 181, 68, 75, 121, 225, 223, 64, 138, 163, 4, 164, 189, 14, 32, 173, 2, 96, 155, 57, 4, 24, 151, 117, 28, 17, 17, 41, 168, 202, 183, 126, 135, 223, 91, 5, 199, 86, 254, 177, 248, 55, 251, 201, 85, 208, 75, 128, 101, 63, 187, 128, 3, 211, 121, 105, 186, 51, 0, 167, 229, 16, 71, 68, 68, 10, 44, 212, 190, 140, 138, 77, 243, 125, 28, 209, 82, 249, 214, 31, 124, 28, 175, 136, 5, 189, 4, 152, 244, 206, 217, 233, 21, 0, 195, 201, 57, 133, 17, 17, 145, 130, 171, 92, 121, 163, 111, 99, 69, 54, 255, 139, 80, 251, 235, 190, 141, 87, 244, 130, 92, 2, 210, 60, 103, 15, 88, 0, 236, 60, 98, 192, 177, 57, 7, 18, 17, 145, 130, 138, 174, 185, 27, 211, 189, 213, 151, 177, 98, 111, 221, 224, 203, 56, 37, 37, 184, 37, 224, 93, 233, 220, 14, 56, 240, 12, 64, 35, 39, 0, 149, 126, 36, 18, 17, 145, 194, 49, 201, 14, 95, 118, 235, 51, 221, 219, 136, 174, 185, 215, 135, 68, 37, 40, 152, 37, 160, 154, 182, 129, 159, 218, 59, 112, 1, 72, 104, 250, 95, 68, 164, 88, 197, 86, 255, 41, 247, 49, 214, 254, 25, 147, 236, 240, 33, 77, 137, 10, 98, 9, 72, 14, 124, 238, 30, 184, 0, 232, 250, 191, 136, 72, 209, 170, 216, 242, 12, 161, 246, 229, 57, 141, 81, 214, 183, 254, 165, 43, 104, 37, 32, 141, 115, 119, 191, 5, 192, 46, 102, 16, 112, 176, 111, 129, 68, 68, 164, 192, 108, 78, 143, 235, 245, 226, 235, 136, 108, 246, 243, 110, 130, 18, 22, 172, 18, 48, 211, 46, 164, 161, 191, 23, 244, 63, 3, 208, 197, 9, 3, 190, 70, 68, 68, 2, 45, 182, 38, 251, 79, 240, 209, 53, 119, 22, 236, 9, 131, 37, 33, 56, 37, 192, 99, 128, 5, 252, 3, 157, 220, 79, 240, 47, 139, 136, 136, 184, 16, 222, 254, 34, 225, 214, 151, 179, 122, 111, 108, 245, 237, 62, 167, 41, 3, 193, 41, 1, 253, 158, 195, 251, 47, 0, 150, 119, 249, 26, 69, 68, 68, 156, 136, 174, 201, 252, 68, 30, 234, 120, 139, 138, 173, 207, 230, 33, 77, 25, 8, 70, 9, 232, 247, 28, 222, 103, 1, 176, 79, 81, 7, 28, 234, 123, 28, 17, 17, 41, 184, 216, 234, 59, 50, 126, 79, 116, 245, 237, 248, 189, 157, 112, 89, 113, 93, 2, 44, 51, 237, 124, 106, 251, 250, 113, 223, 51, 0, 81, 142, 3, 66, 249, 200, 36, 34, 34, 133, 21, 106, 127, 131, 138, 109, 11, 50, 122, 79, 108, 205, 109, 121, 74, 83, 70, 220, 150, 128, 48, 213, 28, 213, 215, 15, 251, 46, 0, 150, 227, 242, 18, 71, 68, 68, 156, 136, 174, 74, 255, 50, 64, 184, 237, 85, 194, 219, 95, 204, 99, 154, 50, 226, 178, 4, 88, 142, 239, 235, 71, 253, 21, 128, 62, 91, 131, 136, 136, 20, 159, 216, 154, 219, 211, 94, 209, 31, 93, 117, 107, 158, 211, 148, 25, 87, 37, 192, 114, 100, 95, 63, 234, 181, 0, 88, 139, 135, 97, 102, 254, 18, 137, 136, 72, 161, 121, 241, 117, 68, 54, 61, 150, 198, 43, 109, 170, 44, 136, 191, 92, 148, 0, 195, 145, 214, 246, 126, 174, 239, 125, 6, 160, 133, 131, 128, 186, 124, 102, 18, 17, 145, 194, 75, 231, 217, 0, 21, 91, 158, 206, 121, 247, 64, 233, 67, 225, 75, 64, 61, 11, 57, 176, 183, 31, 244, 94, 0, 188, 190, 167, 12, 68, 68, 164, 120, 69, 215, 254, 25, 147, 236, 236, 247, 53, 186, 247, 63, 207, 10, 95, 2, 122, 189, 164, 223, 123, 1, 232, 231, 154, 129, 136, 136, 20, 47, 211, 211, 74, 100, 195, 223, 251, 126, 129, 77, 16, 93, 115, 87, 225, 2, 149, 171, 66, 150, 0, 211, 251, 57, 189, 175, 69, 128, 71, 228, 49, 138, 136, 136, 56, 212, 223, 39, 252, 200, 198, 121, 120, 93, 235, 11, 152, 166, 140, 21, 170, 4, 244, 241, 161, 126, 159, 2, 96, 231, 17, 3, 166, 228, 61, 144, 136, 136, 56, 17, 89, 247, 0, 166, 103, 123, 175, 63, 75, 103, 141, 128, 248, 168, 48, 37, 96, 234, 206, 115, 251, 30, 246, 157, 1, 104, 228, 16, 32, 156, 247, 56, 34, 34, 226, 132, 73, 118, 18, 93, 247, 151, 180, 191, 47, 121, 150, 255, 18, 80, 65, 45, 83, 247, 254, 230, 190, 5, 32, 193, 244, 188, 198, 16, 17, 17, 231, 122, 251, 164, 223, 223, 204, 128, 228, 89, 190, 75, 128, 183, 239, 185, 125, 223, 2, 96, 84, 0, 68, 68, 74, 93, 111, 215, 250, 181, 250, 223, 177, 124, 150, 128, 94, 206, 237, 189, 45, 2, 156, 145, 167, 195, 139, 136, 72, 80, 216, 4, 209, 53, 119, 190, 253, 219, 1, 239, 14, 144, 194, 200, 87, 9, 176, 3, 20, 0, 59, 151, 16, 112, 80, 30, 14, 45, 34, 34, 1, 179, 251, 39, 254, 116, 246, 7, 144, 2, 201, 79, 9, 56, 100, 239, 29, 1, 247, 156, 1, 56, 128, 137, 64, 165, 239, 135, 21, 17, 145, 172, 162, 71, 118, 0, 0, 32, 0, 73, 68, 65, 84, 192, 169, 216, 242, 204, 219, 59, 254, 105, 250, 63, 96, 252, 47, 1, 53, 60, 207, 184, 221, 191, 177, 103, 1, 72, 48, 205, 215, 195, 137, 136, 72, 128, 89, 98, 171, 111, 195, 139, 175, 33, 178, 233, 81, 215, 97, 100, 111, 126, 151, 128, 158, 61, 207, 241, 123, 223, 238, 183, 207, 109, 2, 34, 65, 208, 149, 168, 160, 61, 94, 69, 123, 87, 21, 237, 93, 149, 180, 119, 85, 145, 180, 239, 244, 215, 104, 56, 78, 200, 75, 2, 80, 29, 217, 65, 77, 172, 141, 154, 232, 14, 66, 94, 122, 79, 62, 19, 41, 87, 177, 149, 183, 96, 189, 104, 218, 79, 9, 148, 2, 91, 185, 243, 107, 189, 47, 163, 77, 5, 238, 219, 245, 155, 61, 11, 128, 81, 1, 16, 55, 18, 201, 16, 155, 119, 52, 178, 161, 181, 137, 245, 173, 67, 216, 208, 218, 196, 134, 214, 33, 108, 104, 29, 76, 91, 188, 134, 158, 100, 118, 91, 83, 212, 68, 83, 101, 160, 190, 114, 27, 35, 234, 215, 49, 162, 126, 45, 35, 26, 214, 48, 188, 110, 189, 202, 129, 8, 16, 106, 127, 157, 170, 165, 63, 113, 29, 67, 250, 227, 87, 9, 216, 235, 28, 175, 25, 0, 113, 98, 71, 188, 154, 101, 27, 199, 177, 108, 227, 120, 150, 111, 28, 199, 138, 205, 163, 179, 62, 201, 247, 167, 45, 94, 77, 91, 188, 154, 181, 219, 134, 241, 234, 218, 3, 222, 254, 190, 103, 146, 12, 170, 222, 226, 251, 241, 68, 138, 145, 215, 181, 217, 117, 4, 25, 136, 63, 37, 160, 247, 2, 96, 45, 30, 11, 153, 156, 211, 208, 34, 125, 232, 78, 84, 240, 234, 218, 253, 89, 188, 122, 10, 75, 55, 76, 96, 125, 235, 16, 167, 121, 146, 214, 99, 99, 219, 96, 167, 25, 68, 68, 50, 146, 123, 9, 152, 98, 45, 198, 24, 44, 236, 62, 3, 144, 90, 29, 168, 59, 0, 196, 55, 237, 241, 42, 94, 91, 63, 137, 197, 171, 167, 240, 194, 202, 105, 196, 123, 162, 174, 35, 137, 136, 20, 183, 220, 74, 64, 13, 207, 51, 106, 215, 40, 239, 20, 128, 36, 147, 114, 205, 37, 210, 147, 12, 179, 104, 197, 33, 60, 189, 124, 22, 75, 215, 79, 216, 99, 161, 158, 136, 136, 248, 32, 151, 18, 144, 58, 215, 239, 85, 0, 172, 10, 128, 100, 111, 253, 246, 33, 60, 179, 108, 22, 79, 45, 59, 156, 29, 241, 106, 215, 113, 68, 68, 74, 91, 246, 37, 96, 18, 240, 8, 236, 185, 8, 112, 98, 206, 129, 164, 172, 36, 146, 33, 22, 174, 56, 148, 39, 222, 56, 146, 101, 27, 199, 187, 142, 35, 34, 82, 94, 178, 41, 1, 246, 157, 115, 253, 238, 5, 64, 51, 0, 146, 150, 68, 50, 68, 203, 138, 67, 249, 251, 226, 147, 180, 144, 78, 68, 196, 165, 204, 75, 192, 219, 231, 122, 21, 0, 73, 91, 34, 25, 226, 153, 229, 179, 248, 251, 139, 239, 97, 107, 71, 131, 235, 56, 34, 34, 2, 153, 150, 128, 61, 11, 128, 181, 24, 22, 50, 193, 255, 84, 82, 10, 122, 146, 97, 158, 120, 253, 40, 30, 126, 229, 93, 108, 235, 168, 115, 29, 71, 68, 68, 246, 150, 110, 9, 216, 231, 18, 192, 66, 154, 128, 170, 252, 164, 146, 98, 246, 218, 186, 73, 220, 217, 124, 182, 243, 251, 246, 69, 68, 100, 0, 233, 148, 0, 67, 173, 125, 158, 70, 115, 8, 91, 82, 5, 32, 201, 24, 116, 183, 150, 236, 102, 107, 123, 61, 247, 191, 112, 26, 11, 150, 207, 112, 29, 69, 68, 68, 210, 149, 78, 9, 232, 102, 12, 236, 42, 0, 33, 198, 164, 246, 5, 146, 114, 151, 72, 134, 120, 252, 245, 163, 121, 224, 133, 83, 137, 247, 68, 92, 199, 17, 17, 145, 76, 13, 84, 2, 60, 198, 0, 207, 191, 51, 3, 96, 10, 145, 74, 130, 108, 217, 198, 113, 220, 250, 204, 5, 108, 104, 109, 114, 29, 69, 68, 68, 114, 209, 95, 9, 176, 140, 133, 93, 107, 0, 60, 205, 0, 148, 179, 164, 245, 152, 247, 234, 9, 60, 248, 194, 41, 36, 146, 33, 215, 113, 68, 68, 196, 15, 125, 151, 128, 49, 176, 171, 0, 88, 70, 23, 44, 144, 4, 202, 150, 246, 6, 110, 126, 234, 66, 222, 216, 160, 155, 64, 164, 244, 189, 222, 54, 145, 182, 100, 110, 59, 85, 38, 173, 225, 213, 77, 131, 124, 74, 84, 154, 38, 55, 172, 98, 198, 160, 215, 92, 199, 16, 232, 189, 4, 152, 221, 11, 0, 140, 44, 104, 32, 9, 132, 231, 86, 30, 204, 220, 5, 231, 210, 30, 215, 13, 32, 82, 30, 30, 88, 127, 10, 203, 218, 199, 231, 52, 70, 50, 153, 100, 205, 170, 101, 254, 4, 42, 81, 135, 140, 24, 170, 2, 16, 36, 123, 151, 0, 203, 8, 120, 167, 0, 12, 43, 120, 32, 113, 38, 105, 61, 238, 108, 158, 195, 19, 111, 28, 229, 58, 138, 136, 136, 20, 194, 238, 37, 192, 166, 206, 249, 42, 0, 101, 38, 222, 29, 229, 198, 39, 47, 230, 229, 53, 7, 186, 142, 34, 34, 34, 133, 244, 78, 9, 24, 10, 16, 182, 11, 168, 0, 26, 221, 37, 146, 66, 217, 218, 94, 207, 117, 243, 47, 99, 213, 22, 93, 241, 17, 17, 41, 75, 169, 18, 48, 196, 206, 35, 28, 38, 204, 80, 146, 186, 9, 176, 212, 173, 216, 52, 134, 235, 230, 95, 70, 107, 103, 141, 235, 40, 34, 34, 226, 210, 74, 12, 67, 152, 28, 134, 212, 84, 128, 148, 174, 23, 87, 77, 229, 166, 39, 47, 166, 59, 81, 225, 58, 138, 136, 136, 4, 129, 229, 128, 48, 160, 77, 222, 75, 216, 75, 107, 14, 228, 198, 39, 63, 72, 79, 34, 60, 240, 139, 69, 68, 164, 60, 120, 140, 241, 72, 232, 250, 127, 169, 122, 121, 205, 100, 126, 255, 248, 37, 58, 249, 139, 136, 200, 158, 122, 24, 30, 6, 244, 96, 247, 18, 244, 202, 218, 201, 92, 63, 255, 82, 122, 146, 58, 249, 139, 136, 200, 62, 134, 120, 24, 205, 0, 148, 154, 87, 214, 30, 192, 239, 254, 165, 147, 191, 136, 136, 244, 193, 50, 216, 163, 255, 135, 6, 74, 145, 89, 190, 105, 28, 191, 251, 215, 135, 116, 242, 23, 17, 145, 190, 89, 26, 61, 116, 9, 160, 100, 108, 235, 168, 227, 134, 199, 63, 168, 147, 191, 136, 136, 244, 47, 73, 189, 102, 0, 74, 68, 119, 162, 130, 235, 231, 127, 136, 109, 29, 250, 199, 41, 34, 34, 3, 176, 212, 122, 128, 118, 134, 41, 114, 214, 26, 110, 125, 250, 124, 86, 108, 214, 67, 29, 69, 68, 36, 13, 9, 170, 60, 64, 143, 130, 43, 114, 127, 125, 241, 100, 22, 190, 117, 168, 235, 24, 34, 34, 82, 60, 162, 30, 80, 233, 58, 133, 100, 239, 213, 181, 251, 243, 208, 203, 239, 113, 29, 67, 68, 68, 138, 73, 146, 10, 205, 0, 20, 177, 142, 174, 74, 254, 244, 204, 121, 88, 171, 71, 57, 136, 136, 72, 70, 194, 42, 0, 69, 236, 246, 5, 231, 176, 181, 67, 55, 113, 136, 136, 72, 134, 44, 33, 93, 2, 40, 82, 205, 203, 167, 235, 186, 191, 136, 136, 100, 199, 226, 121, 64, 204, 117, 14, 201, 204, 182, 142, 122, 238, 90, 244, 62, 215, 49, 68, 68, 164, 120, 121, 30, 160, 93, 99, 138, 204, 157, 45, 115, 104, 143, 235, 202, 141, 136, 136, 100, 41, 137, 241, 176, 42, 0, 197, 228, 245, 245, 251, 241, 194, 202, 105, 174, 99, 136, 136, 72, 145, 243, 48, 132, 92, 135, 144, 244, 88, 107, 184, 119, 209, 153, 174, 99, 136, 136, 72, 241, 51, 30, 168, 0, 20, 139, 103, 150, 207, 226, 173, 45, 163, 92, 199, 16, 17, 145, 98, 151, 84, 1, 40, 26, 241, 158, 8, 15, 60, 127, 170, 235, 24, 34, 34, 82, 10, 44, 168, 0, 20, 137, 71, 95, 59, 158, 237, 157, 181, 174, 99, 136, 136, 72, 41, 216, 89, 0, 36, 224, 122, 18, 97, 230, 47, 57, 218, 117, 12, 17, 17, 41, 21, 38, 85, 0, 18, 174, 115, 72, 255, 158, 125, 115, 38, 173, 250, 244, 47, 34, 34, 62, 82, 1, 8, 56, 107, 13, 143, 190, 122, 156, 235, 24, 34, 34, 82, 98, 84, 0, 2, 238, 165, 53, 7, 178, 110, 251, 80, 215, 49, 68, 68, 164, 148, 24, 172, 135, 85, 1, 8, 178, 71, 95, 61, 222, 117, 4, 17, 17, 41, 53, 38, 181, 17, 80, 143, 235, 28, 210, 187, 173, 29, 13, 188, 190, 97, 63, 215, 49, 68, 68, 164, 4, 121, 160, 2, 16, 84, 139, 86, 28, 140, 181, 198, 117, 12, 17, 17, 41, 61, 214, 3, 58, 93, 167, 144, 222, 233, 113, 191, 2, 16, 246, 116, 149, 78, 68, 124, 22, 34, 233, 1, 29, 174, 115, 200, 190, 182, 180, 55, 240, 214, 230, 209, 174, 99, 72, 0, 68, 60, 77, 210, 137, 136, 207, 12, 9, 15, 104, 119, 157, 67, 246, 181, 112, 197, 161, 154, 254, 23, 0, 162, 42, 0, 34, 226, 63, 21, 128, 160, 90, 188, 106, 170, 235, 8, 18, 16, 53, 145, 184, 235, 8, 34, 82, 106, 60, 186, 117, 9, 32, 128, 122, 18, 97, 86, 104, 250, 95, 118, 106, 136, 236, 112, 29, 65, 68, 74, 79, 143, 102, 0, 2, 232, 173, 45, 163, 232, 73, 134, 93, 199, 144, 128, 24, 89, 181, 201, 117, 4, 17, 41, 53, 134, 46, 15, 104, 115, 157, 67, 246, 180, 124, 227, 56, 215, 17, 36, 64, 246, 171, 93, 227, 58, 130, 136, 148, 26, 67, 220, 3, 182, 186, 206, 33, 123, 90, 166, 2, 32, 59, 133, 60, 143, 161, 149, 250, 35, 42, 34, 62, 51, 108, 83, 1, 8, 160, 229, 155, 84, 0, 36, 165, 42, 234, 58, 129, 136, 148, 36, 195, 118, 15, 171, 2, 16, 36, 109, 241, 106, 61, 250, 87, 222, 214, 84, 169, 5, 128, 34, 146, 7, 33, 182, 106, 6, 32, 96, 54, 180, 14, 113, 29, 65, 2, 100, 255, 134, 13, 174, 35, 136, 72, 41, 242, 216, 24, 70, 5, 32, 80, 54, 182, 14, 118, 29, 65, 2, 100, 122, 211, 82, 215, 17, 36, 143, 142, 26, 179, 129, 154, 138, 210, 219, 231, 97, 90, 227, 155, 174, 35, 200, 64, 146, 108, 12, 227, 177, 5, 235, 58, 137, 236, 178, 173, 163, 222, 117, 4, 9, 8, 207, 243, 56, 180, 241, 13, 215, 49, 36, 143, 222, 63, 225, 73, 198, 85, 175, 117, 29, 67, 202, 81, 136, 245, 30, 160, 57, 198, 0, 105, 139, 87, 187, 142, 32, 1, 209, 84, 211, 163, 7, 1, 137, 72, 126, 132, 120, 221, 35, 193, 58, 215, 57, 228, 29, 59, 84, 0, 100, 167, 131, 6, 173, 118, 29, 65, 68, 74, 85, 130, 215, 60, 90, 217, 0, 36, 93, 103, 145, 148, 120, 34, 226, 58, 130, 4, 130, 225, 180, 209, 45, 174, 67, 136, 72, 169, 106, 227, 117, 207, 204, 166, 7, 216, 236, 58, 139, 164, 116, 247, 84, 184, 142, 32, 1, 80, 19, 131, 241, 181, 186, 54, 44, 34, 121, 16, 34, 105, 46, 72, 109, 5, 12, 176, 222, 105, 24, 121, 91, 34, 25, 114, 29, 65, 2, 96, 106, 147, 150, 230, 136, 72, 158, 132, 232, 2, 72, 21, 0, 171, 117, 0, 65, 17, 210, 162, 47, 1, 206, 25, 255, 148, 235, 8, 34, 82, 170, 66, 169, 135, 0, 166, 10, 128, 65, 79, 27, 9, 8, 21, 0, 25, 92, 99, 153, 88, 171, 5, 128, 34, 146, 39, 161, 212, 254, 63, 187, 46, 1, 188, 229, 48, 138, 236, 38, 90, 130, 155, 130, 72, 102, 102, 143, 126, 205, 117, 4, 17, 41, 101, 94, 234, 67, 255, 174, 75, 0, 42, 0, 1, 81, 19, 213, 211, 153, 203, 89, 56, 228, 113, 246, 216, 199, 93, 199, 16, 145, 82, 230, 177, 60, 245, 5, 192, 168, 0, 4, 69, 77, 84, 15, 127, 41, 103, 51, 71, 172, 39, 18, 234, 113, 29, 67, 68, 74, 153, 199, 146, 212, 151, 212, 255, 170, 0, 4, 68, 99, 149, 30, 205, 80, 174, 140, 241, 248, 208, 254, 255, 116, 29, 67, 68, 74, 93, 152, 231, 96, 87, 1, 136, 179, 194, 105, 24, 121, 91, 83, 237, 38, 215, 17, 196, 145, 105, 67, 183, 208, 20, 219, 230, 58, 134, 136, 148, 190, 102, 216, 89, 0, 204, 145, 108, 130, 212, 109, 1, 226, 214, 144, 90, 221, 255, 93, 142, 60, 207, 240, 145, 41, 15, 185, 142, 33, 34, 165, 46, 132, 53, 167, 166, 102, 253, 189, 183, 191, 105, 209, 115, 71, 3, 160, 58, 210, 78, 67, 165, 46, 3, 148, 155, 67, 134, 111, 97, 68, 165, 54, 228, 20, 145, 60, 11, 211, 185, 235, 47, 189, 221, 190, 253, 186, 131, 40, 210, 139, 49, 131, 86, 186, 142, 32, 5, 20, 10, 121, 92, 57, 229, 1, 215, 49, 68, 164, 28, 132, 121, 251, 58, 179, 10, 64, 0, 141, 27, 172, 53, 153, 229, 228, 212, 9, 111, 208, 16, 209, 237, 159, 34, 82, 0, 187, 45, 250, 127, 167, 0, 24, 222, 112, 18, 70, 246, 177, 255, 48, 117, 177, 114, 81, 19, 51, 92, 58, 73, 43, 255, 69, 164, 64, 66, 188, 189, 211, 152, 10, 64, 0, 141, 105, 92, 69, 117, 68, 107, 50, 75, 157, 49, 240, 209, 131, 254, 133, 103, 244, 52, 110, 17, 41, 144, 16, 139, 118, 253, 229, 59, 5, 192, 211, 37, 128, 160, 48, 198, 114, 224, 200, 87, 93, 199, 144, 60, 59, 120, 216, 86, 142, 26, 242, 146, 235, 24, 34, 82, 78, 12, 111, 111, 53, 250, 78, 1, 56, 132, 55, 129, 14, 23, 121, 100, 95, 135, 141, 126, 222, 117, 4, 201, 163, 202, 136, 199, 23, 14, 185, 219, 117, 12, 17, 41, 39, 30, 150, 211, 82, 123, 0, 164, 126, 187, 147, 49, 36, 177, 188, 226, 38, 149, 236, 237, 192, 225, 175, 17, 171, 232, 28, 248, 133, 82, 132, 12, 255, 113, 240, 99, 196, 66, 93, 174, 131, 136, 72, 57, 9, 211, 110, 12, 111, 95, 115, 244, 246, 250, 177, 230, 35, 3, 34, 28, 234, 97, 198, 216, 69, 3, 191, 80, 138, 206, 209, 99, 215, 115, 244, 80, 253, 81, 19, 145, 2, 139, 164, 158, 2, 184, 203, 158, 5, 192, 83, 1, 8, 146, 99, 39, 61, 229, 58, 130, 248, 172, 169, 54, 201, 85, 83, 52, 245, 47, 34, 14, 132, 217, 99, 113, 153, 102, 0, 2, 108, 100, 195, 26, 38, 52, 45, 119, 29, 67, 124, 18, 169, 240, 248, 246, 225, 183, 227, 121, 214, 117, 20, 17, 41, 71, 30, 11, 246, 252, 237, 238, 140, 10, 64, 208, 156, 56, 229, 17, 215, 17, 196, 7, 158, 103, 248, 220, 140, 135, 105, 138, 234, 97, 63, 34, 226, 72, 152, 135, 119, 255, 237, 158, 5, 224, 53, 222, 64, 15, 5, 10, 148, 169, 35, 94, 97, 116, 227, 42, 215, 49, 36, 39, 134, 247, 79, 126, 153, 25, 131, 94, 27, 248, 165, 34, 34, 249, 224, 97, 137, 240, 196, 158, 223, 218, 141, 185, 128, 4, 134, 23, 10, 155, 74, 250, 99, 140, 229, 212, 105, 255, 112, 29, 67, 114, 240, 238, 241, 171, 56, 127, 252, 99, 174, 99, 136, 72, 57, 139, 208, 106, 102, 211, 179, 251, 183, 246, 94, 3, 0, 150, 133, 5, 11, 36, 105, 57, 104, 212, 75, 28, 160, 237, 129, 139, 210, 65, 195, 182, 115, 229, 148, 251, 92, 199, 16, 145, 114, 23, 102, 217, 222, 223, 82, 1, 40, 18, 103, 29, 250, 128, 182, 140, 45, 50, 227, 6, 197, 249, 234, 97, 183, 185, 142, 33, 34, 2, 17, 90, 246, 254, 214, 190, 5, 192, 236, 251, 34, 113, 111, 116, 227, 42, 142, 223, 255, 137, 129, 95, 40, 129, 48, 178, 190, 135, 239, 29, 254, 71, 173, 248, 23, 145, 160, 120, 104, 239, 111, 236, 91, 0, 106, 121, 1, 232, 46, 68, 26, 201, 204, 123, 15, 249, 43, 131, 171, 55, 187, 142, 33, 3, 24, 219, 216, 197, 143, 143, 186, 145, 176, 151, 112, 29, 69, 68, 4, 12, 96, 184, 127, 239, 111, 239, 83, 0, 204, 254, 196, 129, 151, 11, 145, 73, 50, 19, 9, 117, 115, 241, 145, 115, 117, 41, 32, 192, 38, 12, 138, 243, 195, 163, 110, 210, 201, 95, 68, 130, 163, 130, 14, 243, 94, 182, 239, 253, 237, 125, 103, 0, 0, 44, 79, 231, 61, 144, 100, 101, 191, 33, 203, 56, 101, 154, 158, 31, 31, 68, 239, 26, 245, 42, 223, 59, 252, 38, 60, 84, 208, 68, 36, 64, 162, 251, 46, 0, 132, 190, 10, 128, 81, 1, 8, 178, 147, 167, 62, 204, 129, 195, 117, 79, 121, 80, 120, 38, 201, 249, 35, 239, 226, 67, 19, 238, 209, 53, 127, 17, 9, 158, 48, 79, 246, 246, 237, 222, 11, 64, 72, 5, 32, 200, 60, 147, 228, 67, 199, 222, 204, 240, 250, 117, 174, 163, 148, 189, 168, 215, 197, 21, 99, 111, 228, 152, 65, 250, 35, 35, 34, 1, 21, 226, 174, 222, 190, 221, 123, 1, 56, 132, 151, 0, 237, 89, 26, 96, 177, 112, 39, 151, 31, 123, 19, 53, 177, 54, 215, 81, 202, 86, 99, 100, 11, 159, 222, 239, 87, 76, 173, 213, 83, 180, 69, 36, 160, 66, 88, 98, 252, 189, 183, 31, 245, 90, 0, 118, 62, 47, 120, 65, 111, 63, 147, 224, 24, 82, 187, 145, 143, 191, 235, 58, 170, 34, 29, 174, 163, 148, 157, 105, 181, 47, 243, 133, 253, 126, 206, 200, 216, 154, 129, 95, 44, 34, 226, 74, 148, 77, 123, 239, 0, 184, 75, 239, 51, 0, 0, 6, 61, 139, 182, 8, 140, 108, 88, 195, 191, 31, 127, 3, 177, 112, 167, 235, 40, 101, 33, 100, 18, 204, 25, 126, 31, 87, 140, 189, 145, 170, 176, 30, 155, 33, 34, 1, 23, 102, 113, 95, 63, 234, 187, 0, 88, 30, 207, 75, 24, 241, 221, 132, 166, 229, 124, 124, 246, 181, 84, 69, 117, 66, 202, 167, 198, 200, 22, 62, 53, 225, 215, 188, 187, 233, 95, 24, 163, 197, 126, 34, 82, 4, 60, 30, 232, 251, 71, 125, 105, 103, 62, 244, 62, 109, 32, 193, 51, 118, 208, 74, 62, 57, 251, 55, 52, 84, 110, 117, 29, 165, 228, 24, 99, 57, 118, 208, 83, 124, 121, 210, 53, 140, 171, 90, 225, 58, 142, 136, 72, 122, 12, 16, 225, 134, 190, 126, 220, 103, 1, 48, 199, 209, 10, 44, 202, 67, 36, 201, 147, 17, 245, 107, 249, 236, 41, 191, 96, 236, 160, 149, 174, 163, 148, 140, 193, 145, 205, 252, 199, 184, 235, 56, 111, 228, 159, 137, 122, 113, 215, 113, 68, 68, 210, 23, 163, 213, 156, 202, 250, 190, 126, 220, 247, 12, 64, 138, 158, 97, 90, 100, 234, 98, 173, 124, 226, 61, 191, 230, 240, 241, 205, 174, 163, 20, 53, 207, 36, 121, 119, 211, 191, 248, 210, 254, 87, 115, 64, 141, 158, 196, 40, 34, 69, 168, 162, 239, 235, 255, 0, 225, 126, 223, 108, 120, 12, 203, 231, 124, 13, 36, 121, 183, 107, 203, 224, 137, 67, 151, 113, 103, 243, 28, 186, 19, 21, 174, 35, 21, 149, 41, 53, 175, 48, 103, 196, 253, 12, 139, 246, 89, 156, 69, 68, 130, 47, 204, 95, 251, 255, 113, 127, 34, 252, 139, 56, 73, 6, 158, 41, 144, 0, 58, 114, 194, 179, 76, 26, 250, 6, 183, 62, 125, 1, 111, 108, 152, 224, 58, 78, 224, 13, 141, 110, 96, 206, 240, 251, 116, 95, 191, 136, 148, 138, 27, 250, 251, 97, 191, 5, 192, 76, 99, 179, 109, 230, 57, 12, 211, 125, 141, 36, 5, 51, 184, 122, 51, 87, 206, 254, 45, 143, 62, 127, 28, 127, 125, 237, 100, 186, 146, 17, 215, 145, 2, 103, 80, 197, 22, 78, 26, 242, 48, 71, 54, 46, 208, 131, 150, 68, 164, 52, 68, 217, 97, 206, 224, 205, 254, 94, 210, 255, 12, 0, 128, 199, 67, 88, 21, 128, 98, 230, 153, 36, 179, 15, 125, 140, 25, 131, 22, 113, 223, 75, 167, 179, 96, 235, 12, 215, 145, 2, 97, 112, 100, 51, 39, 14, 121, 132, 35, 26, 22, 16, 50, 122, 122, 159, 136, 148, 144, 232, 192, 139, 248, 7, 46, 0, 150, 135, 128, 47, 249, 145, 71, 220, 170, 31, 179, 157, 15, 70, 111, 227, 152, 55, 159, 230, 190, 117, 167, 177, 116, 71, 121, 94, 22, 24, 25, 91, 195, 73, 67, 230, 113, 88, 253, 243, 24, 116, 63, 191, 136, 148, 160, 48, 115, 7, 126, 201, 64, 182, 49, 159, 122, 58, 128, 74, 63, 50, 137, 99, 67, 97, 2, 203, 249, 84, 213, 175, 121, 165, 109, 50, 243, 54, 28, 207, 146, 246, 73, 88, 107, 92, 39, 203, 171, 168, 215, 197, 97, 245, 207, 113, 116, 227, 51, 186, 151, 95, 68, 74, 155, 1, 76, 255, 215, 255, 33, 141, 2, 96, 102, 211, 105, 91, 152, 15, 156, 236, 67, 44, 9, 130, 161, 169, 47, 7, 242, 42, 7, 214, 188, 202, 134, 174, 38, 230, 111, 58, 134, 167, 54, 31, 65, 151, 45, 173, 59, 6, 198, 84, 174, 98, 86, 67, 11, 179, 234, 91, 180, 117, 175, 136, 148, 135, 74, 214, 153, 247, 178, 125, 160, 151, 13, 60, 3, 0, 96, 120, 8, 171, 2, 80, 82, 118, 150, 0, 54, 192, 144, 200, 70, 206, 25, 113, 47, 167, 12, 249, 39, 79, 110, 57, 130, 103, 182, 204, 98, 67, 87, 147, 211, 120, 185, 24, 22, 93, 207, 180, 218, 151, 153, 209, 176, 136, 81, 177, 213, 174, 227, 136, 136, 20, 86, 69, 122, 91, 249, 167, 87, 0, 60, 30, 36, 193, 15, 115, 10, 36, 193, 179, 91, 9, 0, 168, 14, 239, 224, 164, 33, 243, 56, 105, 200, 60, 214, 198, 135, 177, 184, 117, 10, 139, 183, 79, 97, 89, 251, 120, 87, 9, 211, 226, 153, 36, 227, 42, 87, 48, 173, 238, 101, 14, 170, 125, 73, 247, 239, 139, 72, 121, 139, 112, 109, 58, 47, 75, 171, 0, 152, 67, 121, 209, 182, 176, 12, 40, 207, 85, 99, 165, 108, 175, 18, 176, 203, 240, 232, 58, 134, 71, 215, 113, 98, 211, 35, 108, 232, 106, 226, 249, 237, 7, 241, 70, 219, 4, 222, 236, 28, 75, 123, 79, 85, 193, 99, 238, 46, 108, 122, 24, 21, 91, 205, 216, 170, 183, 152, 80, 245, 38, 147, 107, 94, 163, 42, 164, 71, 34, 139, 136, 80, 65, 183, 57, 173, 255, 13, 128, 118, 73, 111, 6, 32, 229, 126, 224, 147, 217, 37, 146, 64, 235, 163, 4, 236, 50, 36, 178, 145, 19, 155, 30, 225, 196, 166, 71, 176, 214, 176, 161, 171, 137, 229, 29, 227, 88, 190, 99, 44, 43, 58, 199, 176, 33, 222, 148, 183, 253, 5, 162, 94, 156, 193, 145, 205, 140, 140, 173, 101, 108, 229, 91, 140, 173, 122, 139, 209, 177, 85, 186, 109, 79, 68, 164, 55, 49, 158, 79, 247, 165, 233, 23, 0, 203, 253, 24, 21, 128, 146, 53, 64, 9, 216, 197, 24, 203, 208, 232, 6, 134, 70, 55, 112, 68, 195, 130, 183, 191, 223, 214, 83, 195, 166, 238, 65, 108, 238, 106, 100, 83, 215, 32, 182, 116, 55, 210, 222, 83, 73, 55, 21, 116, 39, 194, 116, 36, 43, 233, 177, 225, 183, 139, 66, 44, 212, 73, 216, 244, 16, 53, 113, 162, 161, 46, 194, 166, 135, 234, 80, 59, 141, 145, 45, 12, 170, 216, 194, 160, 200, 102, 6, 87, 108, 161, 58, 188, 35, 79, 127, 195, 34, 34, 37, 40, 204, 173, 233, 191, 52, 93, 117, 204, 99, 59, 173, 24, 106, 179, 10, 37, 193, 151, 102, 9, 232, 77, 77, 184, 141, 154, 112, 27, 227, 42, 117, 139, 157, 136, 136, 19, 33, 44, 213, 252, 38, 221, 151, 167, 189, 199, 191, 217, 159, 56, 30, 255, 200, 46, 149, 20, 141, 161, 192, 16, 215, 33, 68, 68, 36, 99, 49, 86, 154, 217, 180, 165, 251, 242, 76, 31, 242, 115, 111, 134, 175, 151, 98, 164, 18, 32, 34, 82, 124, 42, 184, 63, 147, 151, 103, 90, 0, 238, 6, 186, 50, 124, 143, 20, 35, 149, 0, 17, 145, 226, 97, 128, 72, 102, 183, 235, 103, 84, 0, 204, 116, 182, 2, 143, 102, 242, 30, 41, 98, 42, 1, 34, 34, 197, 161, 146, 245, 230, 84, 150, 101, 242, 150, 76, 103, 0, 192, 114, 103, 198, 239, 145, 226, 165, 18, 32, 34, 18, 124, 17, 238, 203, 244, 45, 153, 23, 128, 8, 119, 3, 186, 9, 187, 156, 12, 229, 157, 59, 4, 68, 68, 36, 120, 42, 249, 65, 166, 111, 201, 184, 0, 152, 131, 89, 7, 233, 237, 51, 44, 37, 100, 8, 42, 1, 34, 34, 65, 84, 197, 38, 115, 18, 175, 101, 250, 182, 204, 103, 0, 0, 44, 183, 103, 245, 62, 41, 110, 67, 200, 252, 114, 64, 40, 154, 143, 36, 34, 34, 178, 75, 5, 15, 102, 243, 182, 236, 10, 128, 225, 54, 160, 39, 171, 247, 74, 113, 203, 244, 114, 192, 148, 47, 64, 229, 240, 124, 165, 17, 17, 41, 111, 6, 48, 124, 59, 155, 183, 102, 85, 0, 204, 12, 54, 128, 54, 5, 42, 91, 153, 92, 14, 216, 239, 82, 24, 247, 129, 124, 166, 17, 17, 41, 95, 49, 214, 154, 179, 88, 146, 205, 91, 179, 155, 1, 72, 185, 37, 135, 247, 74, 177, 75, 167, 4, 12, 57, 26, 234, 14, 128, 253, 46, 41, 68, 34, 17, 145, 242, 83, 201, 109, 217, 190, 53, 251, 2, 16, 226, 46, 64, 79, 106, 41, 103, 3, 149, 128, 241, 23, 167, 190, 14, 154, 9, 245, 83, 10, 145, 72, 68, 164, 124, 24, 32, 204, 119, 179, 125, 123, 214, 5, 192, 28, 202, 14, 200, 252, 190, 67, 41, 49, 125, 149, 0, 19, 130, 113, 231, 191, 243, 123, 93, 6, 16, 17, 241, 87, 53, 75, 205, 169, 172, 207, 246, 237, 185, 92, 2, 0, 195, 31, 114, 122, 191, 148, 134, 222, 74, 192, 136, 147, 32, 54, 236, 157, 223, 79, 248, 96, 33, 19, 137, 136, 148, 190, 40, 191, 205, 229, 237, 185, 21, 128, 37, 252, 21, 88, 153, 211, 24, 82, 26, 246, 46, 1, 227, 47, 218, 243, 231, 181, 147, 96, 240, 172, 66, 38, 18, 17, 41, 93, 97, 18, 180, 113, 77, 46, 67, 228, 84, 0, 204, 5, 36, 128, 155, 115, 25, 67, 74, 200, 174, 18, 16, 138, 193, 152, 179, 247, 253, 249, 222, 165, 64, 68, 68, 178, 83, 201, 19, 230, 130, 220, 30, 206, 23, 206, 57, 132, 199, 245, 36, 249, 18, 169, 229, 8, 82, 238, 134, 0, 195, 206, 130, 138, 250, 125, 127, 54, 254, 34, 104, 249, 18, 88, 237, 36, 45, 3, 179, 24, 218, 122, 170, 233, 72, 84, 178, 35, 81, 69, 123, 79, 21, 237, 201, 74, 122, 108, 197, 62, 175, 173, 48, 93, 212, 134, 219, 168, 11, 183, 82, 19, 110, 163, 38, 188, 3, 131, 117, 144, 90, 164, 64, 194, 124, 35, 247, 33, 114, 100, 14, 227, 53, 219, 194, 147, 192, 49, 185, 142, 37, 37, 98, 92, 31, 159, 244, 43, 71, 192, 176, 119, 193, 218, 135, 11, 155, 71, 2, 45, 105, 61, 86, 118, 142, 100, 77, 231, 8, 54, 116, 53, 177, 33, 222, 244, 246, 215, 30, 155, 221, 127, 162, 60, 147, 164, 46, 220, 202, 240, 232, 58, 70, 198, 214, 48, 60, 182, 150, 17, 209, 117, 36, 8, 249, 156, 94, 196, 129, 74, 182, 154, 51, 153, 151, 235, 48, 185, 207, 0, 164, 92, 143, 10, 128, 0, 132, 234, 160, 238, 244, 190, 127, 62, 254, 34, 21, 128, 50, 215, 153, 136, 177, 180, 99, 60, 111, 238, 24, 203, 210, 246, 9, 172, 104, 31, 67, 87, 47, 159, 234, 115, 145, 180, 30, 91, 187, 235, 217, 218, 93, 207, 43, 109, 7, 248, 58, 182, 136, 115, 49, 230, 250, 49, 140, 63, 5, 32, 202, 109, 196, 185, 26, 168, 243, 101, 60, 41, 94, 13, 231, 131, 23, 235, 251, 231, 99, 207, 131, 103, 63, 9, 137, 120, 225, 50, 137, 115, 91, 186, 27, 120, 165, 109, 50, 139, 91, 167, 240, 74, 235, 1, 36, 172, 62, 137, 139, 100, 37, 132, 197, 242, 255, 252, 24, 202, 151, 2, 96, 166, 209, 102, 155, 249, 35, 134, 43, 253, 24, 79, 138, 88, 227, 0, 11, 253, 34, 13, 48, 226, 52, 88, 121, 79, 97, 242, 136, 51, 155, 187, 27, 121, 118, 203, 76, 94, 216, 62, 141, 85, 157, 35, 93, 199, 17, 41, 13, 149, 60, 103, 206, 98, 163, 31, 67, 249, 117, 9, 0, 12, 191, 4, 62, 142, 22, 3, 150, 175, 138, 17, 80, 243, 238, 129, 95, 55, 225, 34, 21, 128, 18, 101, 49, 44, 217, 49, 137, 39, 55, 29, 193, 243, 173, 7, 145, 180, 185, 221, 105, 44, 34, 123, 137, 240, 77, 191, 134, 242, 173, 0, 152, 25, 188, 100, 23, 242, 56, 150, 227, 252, 26, 83, 138, 76, 227, 133, 169, 29, 0, 7, 50, 122, 14, 84, 212, 65, 247, 246, 252, 103, 146, 130, 216, 214, 93, 199, 227, 91, 142, 230, 233, 205, 135, 179, 189, 167, 214, 117, 28, 145, 210, 84, 201, 86, 115, 6, 190, 125, 122, 242, 111, 6, 32, 229, 215, 160, 2, 80, 182, 6, 154, 254, 223, 37, 20, 131, 49, 115, 96, 169, 54, 146, 44, 118, 173, 61, 53, 60, 186, 241, 120, 30, 219, 124, 44, 221, 73, 127, 23, 242, 137, 200, 94, 42, 185, 209, 207, 225, 252, 45, 0, 53, 220, 65, 43, 215, 144, 186, 27, 92, 202, 73, 116, 34, 84, 101, 176, 211, 223, 248, 139, 84, 0, 138, 216, 150, 238, 6, 30, 217, 120, 2, 79, 108, 62, 50, 235, 91, 245, 68, 36, 3, 33, 146, 84, 241, 85, 63, 135, 244, 245, 79, 174, 217, 159, 184, 109, 225, 215, 192, 215, 252, 28, 87, 138, 64, 227, 197, 100, 180, 252, 99, 196, 201, 16, 27, 2, 157, 27, 242, 22, 73, 252, 215, 222, 83, 197, 3, 27, 78, 225, 169, 205, 71, 104, 37, 191, 72, 33, 213, 240, 152, 153, 77, 155, 159, 67, 250, 191, 66, 39, 201, 255, 65, 110, 219, 19, 74, 17, 106, 188, 48, 179, 215, 155, 112, 234, 150, 64, 41, 10, 214, 26, 158, 221, 58, 131, 239, 189, 254, 121, 30, 223, 116, 180, 78, 254, 34, 133, 100, 0, 203, 85, 126, 15, 235, 123, 1, 48, 179, 88, 131, 241, 103, 147, 2, 41, 18, 149, 135, 65, 108, 106, 230, 239, 211, 179, 1, 138, 194, 170, 206, 145, 252, 239, 178, 143, 115, 203, 202, 15, 208, 214, 83, 227, 58, 142, 72, 249, 169, 102, 137, 153, 195, 243, 126, 15, 155, 159, 139, 119, 9, 174, 193, 227, 223, 242, 50, 182, 4, 79, 186, 139, 255, 246, 54, 244, 56, 168, 30, 7, 59, 222, 244, 55, 143, 248, 162, 59, 89, 193, 95, 214, 157, 206, 227, 155, 143, 214, 237, 124, 34, 46, 85, 229, 231, 178, 122, 94, 254, 84, 155, 89, 180, 96, 152, 159, 143, 177, 37, 104, 12, 52, 94, 144, 253, 123, 117, 25, 32, 144, 214, 198, 135, 241, 211, 165, 159, 224, 95, 155, 142, 213, 201, 95, 196, 165, 42, 182, 152, 83, 185, 45, 31, 67, 231, 239, 79, 118, 50, 183, 231, 20, 75, 145, 168, 62, 6, 34, 227, 179, 127, 255, 4, 93, 6, 8, 18, 107, 13, 79, 110, 57, 146, 107, 94, 255, 20, 171, 59, 71, 184, 142, 35, 34, 17, 126, 153, 175, 161, 243, 87, 0, 102, 112, 55, 240, 82, 222, 198, 151, 96, 200, 118, 250, 127, 151, 65, 51, 161, 78, 15, 107, 9, 130, 182, 68, 53, 215, 173, 184, 140, 185, 171, 206, 245, 253, 225, 60, 34, 146, 133, 40, 113, 106, 248, 86, 190, 134, 207, 91, 1, 48, 134, 36, 112, 117, 190, 198, 151, 0, 48, 21, 208, 120, 126, 238, 227, 140, 191, 56, 247, 49, 36, 39, 27, 187, 6, 243, 243, 55, 174, 228, 165, 214, 3, 93, 71, 17, 145, 93, 170, 184, 209, 204, 166, 39, 95, 195, 231, 247, 226, 94, 146, 155, 128, 183, 242, 122, 12, 113, 167, 254, 44, 8, 15, 205, 125, 156, 73, 151, 167, 183, 133, 176, 228, 197, 210, 246, 241, 252, 116, 233, 39, 216, 208, 213, 228, 58, 138, 136, 236, 18, 38, 65, 53, 159, 207, 231, 33, 242, 90, 0, 204, 44, 186, 49, 252, 60, 159, 199, 16, 135, 6, 95, 225, 207, 56, 85, 99, 96, 196, 73, 254, 140, 37, 25, 121, 102, 235, 44, 126, 181, 236, 163, 236, 232, 169, 118, 29, 69, 68, 118, 87, 195, 189, 126, 111, 252, 179, 183, 252, 47, 239, 221, 193, 111, 128, 45, 121, 63, 142, 20, 86, 197, 104, 168, 61, 213, 191, 241, 38, 250, 84, 38, 36, 109, 127, 93, 127, 50, 183, 174, 60, 95, 155, 250, 136, 4, 141, 135, 101, 8, 31, 207, 255, 97, 242, 204, 28, 71, 43, 240, 191, 249, 62, 142, 20, 216, 224, 15, 251, 59, 109, 63, 102, 78, 106, 107, 96, 41, 136, 7, 215, 159, 194, 223, 214, 107, 214, 69, 36, 144, 106, 152, 103, 142, 98, 93, 190, 15, 83, 152, 27, 124, 147, 92, 13, 108, 45, 200, 177, 164, 0, 188, 84, 1, 240, 117, 200, 8, 76, 184, 212, 223, 49, 165, 87, 127, 93, 127, 50, 127, 95, 127, 162, 235, 24, 34, 210, 27, 15, 75, 152, 203, 11, 115, 168, 2, 48, 179, 216, 6, 252, 162, 16, 199, 146, 2, 104, 56, 23, 34, 19, 252, 31, 119, 202, 85, 224, 233, 246, 179, 124, 122, 120, 227, 187, 244, 201, 95, 36, 200, 234, 120, 196, 156, 65, 65, 182, 71, 45, 220, 22, 95, 134, 159, 160, 89, 128, 210, 48, 236, 203, 249, 25, 183, 106, 12, 140, 207, 240, 161, 66, 146, 182, 135, 55, 190, 139, 191, 172, 125, 175, 235, 24, 34, 210, 23, 15, 139, 135, 207, 211, 171, 253, 29, 174, 64, 204, 116, 182, 98, 249, 85, 161, 142, 39, 121, 210, 240, 126, 168, 154, 149, 191, 241, 15, 249, 38, 132, 162, 249, 27, 191, 76, 189, 220, 58, 153, 251, 215, 157, 230, 58, 134, 136, 244, 167, 150, 71, 11, 245, 233, 31, 10, 57, 3, 0, 208, 195, 213, 192, 246, 130, 30, 83, 252, 99, 162, 48, 242, 7, 249, 61, 70, 205, 126, 112, 192, 39, 243, 123, 140, 50, 179, 54, 62, 140, 155, 222, 186, 88, 123, 250, 139, 4, 89, 8, 75, 136, 203, 10, 121, 200, 130, 254, 23, 193, 28, 201, 38, 140, 118, 7, 44, 90, 35, 190, 13, 209, 137, 249, 63, 206, 161, 223, 210, 246, 192, 62, 217, 145, 168, 226, 186, 55, 47, 163, 51, 25, 115, 29, 69, 68, 250, 83, 197, 67, 133, 252, 244, 15, 133, 158, 1, 0, 136, 240, 19, 200, 255, 237, 13, 226, 179, 218, 147, 96, 216, 23, 10, 115, 172, 112, 53, 28, 251, 7, 8, 233, 164, 149, 139, 164, 245, 184, 254, 205, 15, 177, 169, 107, 144, 235, 40, 34, 210, 159, 16, 73, 18, 133, 253, 244, 15, 14, 10, 128, 153, 70, 27, 150, 239, 23, 250, 184, 146, 131, 216, 65, 48, 225, 14, 10, 250, 175, 203, 224, 35, 82, 37, 192, 104, 218, 58, 91, 127, 223, 112, 34, 75, 219, 199, 187, 142, 33, 34, 3, 169, 225, 14, 243, 126, 214, 20, 250, 176, 110, 254, 235, 26, 227, 87, 192, 50, 39, 199, 150, 204, 84, 29, 1, 251, 255, 19, 66, 245, 133, 63, 246, 216, 243, 224, 132, 59, 32, 84, 89, 248, 99, 23, 185, 183, 58, 70, 241, 143, 13, 179, 93, 199, 16, 145, 129, 68, 232, 33, 204, 71, 92, 28, 218, 73, 1, 48, 211, 232, 2, 254, 219, 197, 177, 37, 3, 131, 255, 29, 246, 159, 231, 207, 3, 127, 178, 53, 230, 28, 56, 249, 97, 168, 45, 192, 218, 131, 18, 209, 101, 43, 248, 227, 202, 139, 180, 197, 175, 72, 49, 168, 230, 122, 243, 94, 55, 139, 227, 221, 205, 175, 190, 206, 141, 192, 243, 206, 142, 47, 125, 139, 78, 130, 253, 254, 2, 99, 175, 5, 175, 202, 117, 26, 104, 58, 10, 222, 187, 16, 14, 212, 70, 65, 233, 184, 119, 237, 25, 172, 143, 107, 91, 101, 145, 192, 139, 208, 65, 59, 159, 114, 117, 120, 103, 5, 192, 92, 64, 2, 143, 207, 184, 58, 190, 244, 162, 98, 20, 140, 254, 41, 76, 89, 12, 245, 103, 186, 78, 179, 167, 138, 90, 152, 245, 83, 56, 243, 69, 24, 127, 145, 30, 31, 220, 135, 55, 59, 198, 242, 196, 230, 163, 92, 199, 16, 145, 116, 212, 240, 159, 230, 2, 186, 92, 29, 222, 233, 10, 43, 115, 24, 243, 176, 220, 237, 50, 131, 0, 85, 51, 97, 236, 117, 48, 109, 41, 12, 185, 10, 76, 196, 117, 162, 190, 213, 29, 0, 199, 221, 2, 239, 123, 21, 38, 127, 10, 34, 141, 174, 19, 5, 134, 181, 134, 123, 214, 156, 129, 181, 198, 117, 20, 17, 25, 72, 53, 111, 153, 51, 248, 185, 203, 8, 238, 151, 88, 39, 249, 60, 16, 119, 29, 163, 236, 132, 234, 161, 233, 163, 48, 185, 25, 38, 47, 128, 193, 87, 4, 251, 196, 191, 183, 218, 137, 112, 248, 207, 225, 253, 107, 224, 248, 185, 48, 226, 36, 160, 188, 79, 124, 139, 182, 31, 194, 50, 173, 250, 23, 9, 62, 3, 84, 114, 177, 235, 24, 206, 11, 128, 57, 156, 165, 24, 126, 230, 58, 71, 89, 48, 33, 168, 61, 5, 198, 223, 12, 7, 173, 133, 49, 191, 129, 170, 25, 174, 83, 229, 38, 20, 133, 113, 231, 195, 137, 15, 193, 156, 37, 112, 208, 87, 160, 102, 188, 235, 84, 5, 215, 99, 195, 220, 183, 246, 116, 215, 49, 68, 36, 29, 117, 204, 55, 167, 51, 223, 117, 12, 231, 5, 0, 128, 29, 252, 55, 20, 254, 30, 200, 178, 81, 53, 19, 70, 255, 12, 166, 173, 132, 73, 127, 131, 198, 139, 193, 43, 193, 77, 118, 106, 39, 194, 97, 255, 3, 103, 47, 131, 179, 22, 195, 180, 47, 67, 229, 8, 215, 169, 10, 226, 177, 77, 199, 178, 185, 91, 151, 67, 68, 2, 47, 76, 130, 161, 156, 231, 58, 6, 4, 164, 0, 152, 227, 104, 5, 190, 230, 58, 71, 73, 137, 77, 131, 17, 223, 132, 169, 75, 82, 83, 252, 67, 62, 13, 21, 195, 93, 167, 42, 156, 250, 169, 48, 253, 251, 112, 238, 74, 56, 117, 126, 234, 14, 130, 104, 147, 235, 84, 121, 209, 99, 195, 60, 186, 241, 120, 215, 49, 68, 36, 29, 53, 92, 107, 142, 10, 198, 110, 184, 97, 215, 1, 222, 54, 157, 223, 179, 144, 143, 1, 135, 187, 142, 82, 180, 162, 251, 65, 227, 69, 169, 79, 248, 177, 169, 174, 211, 4, 131, 241, 96, 200, 177, 169, 95, 211, 127, 0, 171, 31, 132, 229, 183, 192, 202, 251, 32, 209, 225, 58, 157, 47, 154, 183, 78, 103, 123, 79, 173, 235, 24, 34, 50, 144, 24, 109, 156, 201, 39, 92, 199, 216, 37, 48, 5, 192, 24, 146, 118, 33, 159, 193, 50, 159, 114, 95, 205, 149, 137, 240, 224, 212, 35, 122, 7, 93, 10, 213, 199, 160, 255, 235, 250, 17, 138, 194, 152, 179, 83, 191, 18, 29, 169, 18, 176, 236, 15, 176, 250, 175, 144, 236, 118, 157, 46, 107, 143, 109, 58, 214, 117, 4, 17, 73, 71, 37, 95, 54, 134, 164, 235, 24, 187, 4, 166, 0, 0, 152, 233, 60, 97, 23, 114, 59, 150, 11, 92, 103, 9, 180, 80, 61, 212, 207, 129, 134, 243, 161, 238, 84, 48, 218, 28, 39, 99, 161, 202, 212, 226, 193, 113, 231, 67, 215, 102, 88, 121, 63, 44, 187, 9, 214, 252, 19, 176, 174, 211, 165, 237, 229, 214, 201, 172, 238, 44, 143, 117, 14, 34, 69, 173, 134, 165, 230, 76, 126, 229, 58, 198, 238, 2, 85, 0, 0, 176, 124, 9, 56, 11, 208, 6, 240, 187, 51, 81, 168, 59, 37, 117, 210, 111, 56, 23, 188, 106, 215, 137, 74, 71, 100, 16, 236, 119, 73, 234, 87, 251, 91, 176, 226, 207, 176, 244, 38, 216, 220, 236, 58, 217, 128, 30, 223, 124, 180, 235, 8, 34, 50, 16, 15, 75, 85, 240, 62, 216, 6, 174, 0, 152, 25, 188, 105, 91, 248, 22, 232, 137, 129, 224, 65, 205, 49, 169, 147, 126, 227, 197, 16, 46, 205, 69, 108, 129, 82, 53, 6, 14, 252, 116, 234, 215, 182, 151, 224, 205, 219, 97, 217, 31, 161, 245, 117, 215, 201, 246, 209, 145, 168, 228, 149, 182, 3, 92, 199, 16, 145, 129, 212, 114, 143, 57, 149, 192, 125, 162, 8, 92, 1, 0, 96, 27, 63, 161, 158, 243, 129, 153, 174, 163, 56, 81, 53, 3, 26, 47, 129, 198, 11, 203, 107, 229, 126, 208, 212, 79, 133, 67, 190, 1, 135, 124, 29, 54, 60, 145, 42, 2, 203, 111, 131, 174, 45, 174, 147, 1, 240, 66, 235, 52, 61, 240, 167, 200, 133, 73, 184, 142, 32, 249, 22, 101, 7, 157, 124, 192, 117, 140, 222, 4, 178, 0, 152, 217, 244, 216, 22, 174, 0, 158, 5, 202, 235, 2, 183, 57, 28, 26, 190, 13, 67, 78, 214, 126, 247, 129, 97, 82, 119, 17, 212, 238, 15, 213, 19, 224, 133, 111, 65, 79, 187, 235, 80, 44, 218, 118, 136, 235, 8, 146, 163, 234, 10, 247, 255, 30, 73, 30, 25, 160, 129, 15, 155, 83, 220, 237, 247, 223, 159, 64, 22, 0, 0, 51, 131, 231, 236, 66, 174, 217, 185, 38, 160, 124, 216, 103, 225, 249, 211, 97, 251, 8, 24, 247, 1, 152, 112, 17, 12, 62, 194, 117, 170, 242, 213, 211, 6, 111, 221, 13, 203, 111, 133, 213, 127, 7, 219, 227, 58, 17, 0, 237, 137, 74, 94, 107, 155, 228, 58, 134, 228, 168, 42, 164, 93, 208, 75, 90, 29, 243, 205, 41, 220, 238, 58, 70, 95, 2, 91, 0, 0, 232, 224, 155, 196, 56, 23, 40, 175, 255, 210, 53, 1, 172, 129, 87, 126, 154, 250, 85, 61, 14, 198, 95, 8, 19, 47, 131, 186, 3, 221, 102, 43, 7, 54, 1, 107, 231, 165, 110, 17, 92, 113, 87, 170, 4, 4, 204, 146, 182, 73, 154, 254, 47, 114, 158, 241, 136, 132, 130, 81, 40, 37, 15, 34, 116, 145, 224, 44, 215, 49, 250, 19, 232, 2, 96, 142, 161, 195, 46, 228, 35, 88, 30, 166, 220, 110, 112, 223, 181, 222, 111, 29, 176, 227, 77, 88, 252, 131, 212, 175, 134, 105, 48, 246, 252, 212, 138, 245, 154, 253, 92, 38, 44, 45, 54, 9, 27, 159, 76, 45, 250, 91, 126, 11, 116, 110, 112, 157, 168, 95, 203, 58, 198, 187, 142, 32, 57, 10, 7, 250, 191, 190, 146, 179, 106, 190, 98, 206, 100, 171, 235, 24, 253, 9, 252, 191, 130, 102, 58, 143, 216, 22, 126, 15, 92, 238, 58, 75, 193, 237, 94, 2, 118, 217, 186, 56, 245, 235, 133, 111, 195, 144, 99, 82, 101, 96, 252, 133, 16, 27, 234, 34, 97, 241, 219, 181, 210, 127, 233, 141, 208, 182, 204, 117, 154, 180, 45, 107, 31, 231, 58, 130, 228, 168, 186, 66, 11, 0, 75, 86, 45, 47, 153, 51, 249, 137, 235, 24, 3, 9, 124, 1, 0, 32, 201, 231, 240, 56, 21, 24, 229, 58, 74, 193, 245, 86, 2, 32, 245, 137, 117, 253, 252, 212, 175, 230, 207, 193, 240, 217, 48, 225, 210, 212, 46, 119, 21, 218, 22, 182, 95, 59, 222, 132, 229, 127, 130, 55, 110, 128, 237, 175, 184, 78, 147, 177, 238, 100, 5, 171, 58, 70, 186, 142, 33, 57, 106, 170, 238, 116, 29, 65, 242, 33, 68, 146, 10, 222, 235, 58, 70, 58, 138, 162, 0, 152, 89, 108, 179, 11, 249, 44, 150, 185, 174, 179, 56, 209, 87, 9, 216, 197, 38, 96, 205, 63, 82, 191, 194, 213, 48, 122, 78, 106, 241, 224, 136, 83, 192, 139, 20, 42, 101, 176, 181, 175, 130, 55, 231, 166, 22, 243, 109, 122, 214, 117, 154, 156, 188, 213, 49, 90, 215, 255, 75, 192, 136, 234, 237, 174, 35, 72, 62, 212, 241, 35, 115, 6, 111, 186, 142, 145, 142, 162, 40, 0, 0, 102, 58, 183, 219, 102, 238, 198, 112, 182, 235, 44, 78, 12, 84, 2, 118, 233, 217, 145, 186, 134, 189, 252, 22, 136, 52, 192, 232, 247, 165, 182, 187, 29, 121, 26, 152, 162, 249, 199, 237, 143, 174, 45, 169, 253, 254, 87, 220, 14, 171, 30, 12, 204, 10, 254, 92, 173, 235, 210, 229, 158, 82, 112, 96, 253, 74, 215, 17, 196, 111, 85, 172, 52, 103, 242, 159, 174, 99, 164, 171, 184, 206, 8, 150, 43, 49, 28, 199, 59, 167, 195, 242, 210, 68, 106, 155, 250, 245, 105, 190, 190, 107, 107, 106, 75, 219, 165, 55, 65, 229, 8, 24, 119, 1, 140, 191, 8, 154, 142, 204, 99, 72, 199, 186, 91, 83, 183, 237, 189, 249, 39, 88, 243, 80, 81, 63, 228, 167, 47, 91, 187, 234, 93, 71, 144, 156, 25, 102, 54, 45, 113, 29, 66, 252, 20, 34, 73, 13, 167, 187, 142, 145, 137, 162, 42, 0, 102, 22, 107, 236, 66, 254, 29, 203, 221, 174, 179, 56, 51, 132, 212, 253, 16, 153, 62, 77, 186, 99, 13, 188, 242, 179, 212, 175, 186, 3, 96, 226, 229, 169, 219, 10, 99, 195, 124, 143, 232, 196, 230, 102, 88, 242, 91, 88, 118, 75, 32, 111, 219, 243, 211, 150, 158, 6, 215, 17, 36, 71, 177, 10, 104, 140, 232, 18, 64, 73, 169, 229, 187, 230, 84, 94, 116, 29, 35, 19, 158, 235, 0, 153, 50, 211, 185, 7, 195, 111, 93, 231, 112, 170, 9, 200, 229, 188, 189, 253, 53, 88, 248, 159, 112, 231, 40, 248, 231, 201, 169, 85, 240, 197, 56, 61, 222, 181, 37, 117, 210, 191, 255, 80, 120, 96, 86, 234, 175, 75, 252, 228, 15, 176, 181, 75, 5, 160, 216, 141, 169, 215, 14, 128, 37, 165, 150, 23, 204, 89, 124, 205, 117, 140, 76, 21, 213, 12, 192, 219, 18, 124, 22, 143, 19, 128, 242, 221, 21, 39, 221, 53, 1, 253, 217, 125, 241, 96, 205, 126, 48, 245, 11, 48, 241, 195, 16, 138, 249, 145, 48, 127, 182, 191, 10, 139, 127, 152, 218, 155, 63, 25, 200, 29, 54, 243, 106, 107, 143, 46, 1, 20, 187, 35, 135, 45, 117, 29, 65, 252, 18, 37, 78, 136, 247, 184, 142, 145, 141, 162, 155, 1, 0, 48, 179, 104, 39, 201, 7, 33, 152, 251, 43, 23, 76, 174, 51, 1, 187, 107, 91, 10, 207, 92, 9, 247, 76, 74, 221, 46, 177, 151, 91, 0, 0, 20, 235, 73, 68, 65, 84, 30, 103, 147, 62, 13, 236, 163, 142, 213, 240, 228, 229, 240, 151, 169, 240, 198, 245, 101, 121, 242, 135, 212, 109, 128, 82, 188, 140, 103, 120, 207, 200, 22, 215, 49, 196, 15, 6, 168, 231, 67, 230, 44, 54, 186, 142, 146, 141, 162, 44, 0, 0, 102, 22, 45, 192, 55, 92, 231, 112, 206, 207, 18, 0, 169, 219, 229, 158, 252, 48, 252, 237, 88, 104, 13, 208, 34, 165, 37, 191, 133, 123, 38, 195, 27, 191, 15, 102, 57, 41, 32, 107, 93, 39, 144, 92, 12, 169, 78, 82, 19, 238, 112, 29, 67, 252, 80, 207, 189, 230, 84, 110, 115, 29, 35, 91, 69, 91, 0, 0, 152, 206, 15, 129, 135, 93, 199, 112, 206, 239, 18, 0, 176, 241, 41, 184, 127, 70, 106, 47, 124, 151, 18, 29, 240, 216, 121, 240, 244, 199, 202, 226, 250, 126, 90, 76, 121, 237, 138, 93, 106, 102, 12, 91, 225, 58, 130, 248, 161, 138, 77, 212, 240, 126, 215, 49, 114, 81, 212, 5, 192, 24, 146, 120, 92, 10, 108, 118, 157, 197, 185, 124, 148, 128, 158, 54, 248, 215, 249, 240, 218, 175, 125, 30, 56, 77, 221, 173, 240, 143, 147, 96, 197, 157, 110, 142, 31, 80, 73, 171, 2, 80, 172, 60, 207, 227, 188, 241, 243, 93, 199, 144, 92, 133, 176, 196, 56, 195, 204, 166, 8, 87, 79, 191, 163, 168, 11, 0, 128, 57, 140, 85, 88, 62, 226, 58, 71, 32, 228, 163, 4, 216, 36, 60, 251, 9, 88, 113, 135, 207, 3, 15, 32, 217, 157, 42, 31, 27, 158, 40, 236, 113, 139, 128, 71, 121, 95, 2, 41, 102, 19, 7, 183, 83, 87, 177, 195, 117, 12, 201, 85, 29, 63, 53, 103, 240, 180, 235, 24, 185, 42, 250, 2, 0, 96, 102, 114, 23, 150, 27, 92, 231, 8, 132, 124, 149, 128, 39, 62, 148, 90, 125, 95, 40, 139, 190, 2, 171, 255, 86, 184, 227, 21, 145, 186, 10, 93, 10, 41, 86, 115, 198, 21, 247, 54, 212, 2, 212, 242, 178, 57, 147, 207, 185, 142, 225, 135, 146, 40, 0, 0, 196, 248, 20, 240, 146, 235, 24, 129, 208, 4, 248, 189, 91, 108, 79, 59, 60, 126, 73, 234, 214, 193, 124, 91, 255, 24, 188, 124, 117, 254, 143, 83, 164, 26, 42, 2, 253, 132, 81, 233, 67, 125, 165, 225, 136, 33, 47, 187, 142, 33, 185, 136, 208, 73, 37, 239, 118, 29, 195, 47, 37, 83, 0, 204, 52, 218, 240, 56, 7, 216, 230, 58, 75, 32, 12, 193, 255, 153, 128, 77, 207, 166, 86, 225, 231, 147, 77, 194, 130, 207, 150, 253, 74, 255, 254, 168, 0, 20, 167, 211, 198, 47, 118, 29, 65, 114, 17, 194, 82, 199, 153, 230, 212, 180, 55, 99, 15, 188, 146, 41, 0, 0, 230, 48, 94, 3, 46, 37, 181, 99, 190, 228, 227, 114, 192, 115, 95, 75, 205, 6, 228, 203, 210, 27, 97, 179, 238, 145, 238, 79, 67, 133, 58, 110, 177, 169, 142, 121, 156, 51, 246, 113, 215, 49, 36, 23, 117, 252, 208, 156, 206, 63, 93, 199, 240, 83, 73, 21, 0, 0, 51, 131, 123, 129, 239, 187, 206, 17, 24, 126, 151, 128, 142, 181, 240, 198, 239, 124, 28, 112, 55, 54, 1, 47, 126, 47, 63, 99, 151, 144, 193, 21, 186, 233, 165, 216, 204, 153, 248, 34, 158, 167, 207, 37, 69, 171, 150, 199, 138, 233, 41, 127, 233, 42, 185, 2, 0, 192, 116, 190, 10, 252, 213, 117, 140, 192, 240, 187, 4, 188, 244, 227, 252, 60, 59, 96, 197, 93, 193, 218, 124, 40, 160, 70, 87, 174, 114, 29, 65, 50, 208, 80, 109, 152, 51, 70, 159, 254, 139, 86, 21, 155, 232, 226, 100, 215, 49, 242, 161, 36, 11, 128, 49, 36, 137, 242, 65, 96, 153, 235, 44, 129, 225, 103, 9, 216, 241, 255, 219, 187, 247, 32, 43, 235, 251, 142, 227, 239, 223, 185, 236, 57, 187, 103, 47, 103, 23, 88, 16, 69, 69, 171, 34, 222, 178, 96, 20, 208, 212, 1, 209, 133, 133, 69, 99, 133, 54, 38, 70, 141, 214, 36, 53, 94, 38, 181, 234, 164, 105, 172, 102, 198, 68, 39, 153, 36, 53, 182, 74, 91, 53, 137, 173, 119, 137, 83, 209, 120, 47, 90, 141, 34, 187, 11, 169, 40, 33, 40, 34, 108, 69, 46, 11, 2, 2, 187, 123, 206, 249, 245, 143, 93, 18, 144, 219, 158, 61, 151, 223, 115, 249, 188, 102, 24, 113, 102, 121, 246, 51, 176, 231, 60, 159, 243, 123, 126, 207, 247, 249, 16, 214, 204, 47, 210, 193, 118, 179, 252, 95, 138, 127, 204, 0, 106, 136, 111, 34, 21, 213, 195, 100, 252, 193, 112, 233, 152, 87, 49, 70, 159, 254, 125, 41, 78, 134, 58, 38, 153, 57, 193, 28, 59, 31, 200, 2, 0, 96, 78, 160, 11, 195, 5, 128, 102, 110, 238, 82, 204, 18, 80, 236, 203, 0, 219, 86, 194, 186, 5, 197, 61, 102, 64, 25, 99, 57, 58, 165, 135, 201, 248, 193, 225, 245, 59, 153, 212, 168, 155, 147, 124, 169, 111, 206, 255, 101, 102, 42, 203, 93, 71, 41, 149, 192, 22, 0, 0, 211, 196, 98, 224, 235, 174, 115, 120, 74, 177, 74, 64, 231, 211, 176, 125, 117, 17, 14, 212, 111, 197, 191, 105, 231, 127, 30, 142, 171, 209, 165, 18, 175, 139, 198, 34, 92, 127, 202, 83, 174, 99, 200, 96, 213, 113, 175, 153, 206, 3, 174, 99, 148, 82, 160, 11, 0, 128, 25, 199, 175, 128, 123, 92, 231, 240, 148, 98, 148, 0, 155, 133, 247, 127, 89, 140, 52, 125, 251, 9, 222, 187, 191, 56, 199, 10, 137, 177, 213, 203, 180, 172, 236, 113, 173, 71, 47, 103, 68, 229, 70, 215, 49, 100, 48, 106, 248, 157, 105, 229, 114, 215, 49, 74, 45, 240, 5, 0, 128, 26, 174, 197, 248, 127, 108, 99, 81, 21, 99, 88, 208, 138, 127, 47, 206, 167, 246, 206, 103, 250, 30, 245, 43, 3, 150, 142, 111, 230, 200, 74, 61, 84, 198, 171, 14, 169, 203, 113, 209, 81, 122, 78, 153, 47, 37, 217, 74, 29, 103, 184, 142, 81, 14, 161, 40, 0, 230, 24, 186, 233, 229, 124, 96, 149, 235, 44, 158, 82, 232, 176, 160, 109, 43, 97, 125, 17, 30, 108, 242, 254, 47, 10, 63, 70, 8, 53, 213, 45, 113, 29, 65, 246, 33, 26, 141, 112, 195, 231, 158, 116, 29, 67, 6, 35, 78, 134, 90, 38, 153, 201, 132, 98, 222, 118, 40, 10, 0, 128, 57, 141, 181, 88, 166, 3, 155, 92, 103, 241, 148, 66, 47, 7, 124, 240, 96, 97, 223, 191, 119, 75, 223, 126, 2, 201, 219, 169, 233, 118, 42, 76, 175, 235, 24, 178, 7, 195, 151, 142, 95, 204, 161, 85, 235, 93, 7, 145, 124, 69, 176, 212, 51, 219, 52, 243, 182, 235, 40, 229, 18, 154, 2, 0, 96, 198, 243, 46, 240, 69, 160, 219, 117, 22, 79, 41, 164, 4, 124, 240, 8, 228, 10, 184, 67, 102, 245, 60, 200, 234, 70, 141, 193, 168, 140, 238, 160, 41, 189, 216, 117, 12, 217, 205, 196, 81, 235, 153, 53, 234, 13, 215, 49, 36, 95, 6, 168, 231, 6, 211, 204, 175, 93, 71, 41, 167, 80, 21, 0, 0, 51, 142, 5, 192, 101, 104, 92, 240, 158, 6, 91, 2, 122, 186, 224, 163, 23, 6, 255, 125, 63, 120, 104, 240, 127, 86, 152, 50, 116, 1, 70, 63, 202, 158, 112, 72, 58, 199, 117, 39, 204, 115, 29, 67, 6, 35, 205, 92, 211, 194, 143, 92, 199, 40, 183, 208, 21, 0, 0, 51, 142, 7, 129, 239, 187, 206, 225, 57, 131, 45, 1, 131, 189, 12, 208, 189, 1, 214, 6, 106, 180, 118, 217, 53, 38, 214, 115, 114, 109, 104, 86, 44, 61, 171, 42, 17, 225, 150, 83, 31, 214, 157, 25, 126, 84, 203, 75, 102, 102, 56, 111, 23, 15, 101, 1, 0, 160, 137, 127, 4, 138, 116, 31, 91, 128, 12, 166, 4, 172, 121, 114, 112, 15, 8, 90, 245, 40, 228, 116, 13, 187, 80, 211, 135, 63, 71, 196, 104, 134, 130, 43, 241, 88, 132, 155, 63, 255, 36, 233, 248, 86, 215, 81, 36, 95, 41, 86, 49, 43, 152, 99, 126, 7, 34, 180, 5, 192, 24, 44, 57, 174, 128, 96, 61, 221, 169, 40, 242, 45, 1, 189, 91, 161, 115, 16, 163, 129, 181, 252, 95, 20, 195, 19, 235, 152, 88, 191, 208, 117, 140, 80, 138, 69, 35, 220, 52, 254, 57, 70, 215, 124, 228, 58, 138, 228, 171, 146, 205, 36, 57, 217, 24, 66, 219, 158, 67, 91, 0, 0, 204, 169, 244, 146, 227, 47, 176, 225, 217, 245, 57, 96, 249, 150, 128, 124, 47, 3, 108, 95, 83, 156, 91, 8, 5, 128, 233, 195, 159, 165, 38, 166, 79, 160, 229, 20, 141, 70, 185, 174, 105, 1, 39, 53, 104, 44, 179, 239, 84, 208, 77, 13, 227, 76, 11, 91, 92, 71, 113, 41, 212, 5, 0, 192, 156, 202, 39, 68, 104, 5, 62, 118, 157, 197, 115, 242, 41, 1, 255, 247, 52, 244, 108, 30, 248, 177, 63, 120, 72, 163, 127, 139, 40, 21, 221, 206, 151, 15, 123, 68, 215, 160, 203, 36, 26, 137, 112, 245, 41, 175, 112, 218, 176, 119, 93, 71, 145, 124, 197, 200, 145, 102, 138, 105, 214, 195, 226, 66, 95, 0, 0, 76, 19, 31, 96, 153, 1, 124, 226, 58, 139, 231, 12, 116, 98, 96, 182, 27, 86, 63, 49, 240, 227, 22, 58, 63, 64, 246, 114, 92, 245, 114, 38, 212, 191, 229, 58, 70, 224, 85, 197, 118, 242, 173, 166, 87, 153, 52, 124, 169, 235, 40, 146, 175, 40, 150, 6, 46, 50, 205, 188, 238, 58, 138, 23, 168, 0, 244, 51, 227, 105, 3, 166, 67, 56, 38, 64, 229, 101, 160, 19, 3, 7, 122, 82, 223, 178, 12, 186, 218, 11, 73, 36, 251, 113, 222, 136, 167, 24, 82, 209, 229, 58, 70, 96, 165, 227, 155, 185, 230, 232, 123, 56, 163, 81, 39, 127, 223, 137, 0, 117, 92, 109, 154, 121, 216, 117, 20, 175, 80, 1, 216, 141, 25, 199, 111, 129, 243, 129, 157, 174, 179, 120, 206, 64, 46, 7, 172, 125, 9, 182, 119, 30, 252, 88, 43, 245, 233, 191, 84, 18, 145, 110, 46, 25, 245, 0, 137, 72, 32, 31, 95, 238, 212, 97, 149, 157, 92, 119, 212, 93, 28, 146, 88, 235, 58, 138, 228, 203, 0, 13, 124, 219, 204, 224, 46, 215, 81, 188, 68, 5, 224, 51, 204, 56, 94, 196, 114, 62, 154, 22, 184, 183, 131, 149, 0, 155, 131, 15, 31, 61, 248, 113, 86, 105, 247, 127, 41, 141, 170, 236, 228, 146, 81, 15, 232, 214, 192, 34, 26, 83, 189, 156, 171, 70, 207, 165, 46, 30, 234, 61, 99, 254, 212, 119, 242, 191, 213, 76, 231, 39, 174, 163, 120, 141, 10, 192, 62, 152, 241, 60, 139, 229, 34, 32, 227, 58, 139, 231, 28, 172, 4, 28, 236, 211, 253, 198, 133, 176, 101, 121, 49, 19, 201, 62, 28, 95, 243, 123, 102, 143, 212, 84, 186, 66, 25, 99, 153, 58, 236, 101, 254, 250, 136, 251, 72, 70, 180, 48, 232, 75, 181, 220, 105, 90, 184, 217, 117, 12, 47, 82, 1, 216, 15, 51, 158, 39, 48, 92, 1, 225, 189, 71, 116, 191, 14, 84, 2, 14, 118, 130, 215, 242, 127, 217, 76, 168, 95, 72, 115, 99, 1, 99, 154, 67, 174, 58, 250, 41, 87, 30, 113, 31, 51, 134, 255, 70, 171, 41, 126, 149, 230, 151, 102, 22, 215, 184, 142, 225, 85, 42, 0, 7, 96, 154, 248, 5, 86, 63, 60, 251, 116, 160, 18, 176, 106, 63, 123, 108, 6, 122, 137, 64, 138, 102, 90, 227, 243, 180, 142, 120, 90, 183, 7, 230, 233, 168, 212, 74, 174, 63, 230, 103, 140, 169, 254, 189, 235, 40, 50, 88, 105, 30, 54, 173, 92, 226, 58, 134, 151, 25, 215, 1, 252, 192, 182, 113, 29, 70, 215, 143, 246, 105, 3, 123, 79, 80, 168, 29, 3, 179, 246, 113, 127, 244, 71, 47, 192, 139, 161, 157, 186, 233, 212, 162, 205, 77, 60, 212, 57, 155, 172, 141, 186, 142, 226, 105, 241, 72, 47, 205, 141, 47, 48, 121, 200, 43, 250, 212, 239, 103, 117, 60, 99, 102, 209, 226, 58, 134, 215, 197, 92, 7, 240, 3, 51, 158, 159, 218, 118, 134, 0, 223, 117, 157, 197, 115, 134, 246, 255, 119, 247, 18, 176, 101, 25, 116, 117, 64, 67, 211, 158, 95, 171, 123, 255, 157, 57, 53, 221, 65, 93, 124, 11, 247, 174, 250, 42, 59, 115, 73, 215, 113, 60, 105, 116, 213, 7, 252, 213, 161, 143, 209, 152, 88, 239, 58, 138, 20, 162, 150, 5, 58, 249, 15, 140, 86, 0, 242, 96, 219, 185, 17, 248, 161, 235, 28, 158, 244, 217, 149, 128, 177, 127, 7, 227, 238, 248, 211, 255, 103, 187, 225, 241, 17, 249, 77, 11, 148, 162, 251, 184, 187, 145, 95, 173, 254, 18, 157, 59, 71, 186, 142, 226, 25, 169, 216, 167, 180, 52, 62, 203, 196, 250, 133, 186, 84, 226, 119, 181, 188, 97, 206, 99, 162, 235, 24, 126, 161, 2, 144, 39, 219, 198, 13, 24, 110, 119, 157, 195, 147, 118, 47, 1, 149, 35, 225, 130, 213, 96, 250, 183, 153, 172, 158, 7, 11, 46, 112, 149, 76, 118, 147, 181, 81, 158, 95, 63, 133, 231, 214, 157, 141, 13, 241, 91, 64, 212, 100, 57, 163, 225, 13, 166, 53, 62, 79, 101, 116, 135, 235, 56, 82, 168, 90, 94, 50, 231, 113, 182, 235, 24, 126, 18, 222, 87, 127, 1, 108, 59, 223, 0, 238, 66, 155, 40, 247, 182, 123, 9, 56, 231, 191, 97, 248, 89, 125, 191, 127, 117, 78, 223, 227, 127, 197, 51, 150, 111, 251, 51, 30, 236, 156, 195, 230, 222, 58, 215, 81, 202, 202, 24, 203, 201, 53, 111, 51, 115, 196, 51, 12, 173, 216, 232, 58, 142, 20, 67, 154, 121, 166, 21, 125, 194, 200, 147, 10, 192, 32, 217, 14, 190, 140, 229, 126, 180, 143, 98, 111, 187, 74, 192, 49, 95, 135, 211, 239, 238, 123, 92, 240, 99, 195, 33, 171, 79, 89, 94, 211, 99, 227, 188, 186, 241, 12, 158, 95, 55, 133, 238, 92, 194, 117, 156, 146, 50, 88, 198, 214, 46, 163, 121, 216, 243, 140, 170, 28, 192, 196, 74, 241, 135, 52, 247, 154, 86, 46, 119, 29, 195, 143, 84, 0, 10, 96, 219, 152, 131, 225, 1, 32, 238, 58, 139, 231, 108, 0, 54, 53, 192, 133, 31, 245, 109, 254, 123, 253, 82, 215, 137, 228, 0, 54, 247, 214, 241, 244, 199, 205, 44, 218, 60, 46, 112, 151, 5, 98, 38, 195, 184, 186, 197, 76, 109, 124, 153, 97, 21, 27, 92, 199, 145, 98, 233, 155, 240, 247, 99, 211, 194, 245, 174, 163, 248, 85, 176, 94, 233, 14, 216, 14, 102, 96, 121, 20, 168, 116, 157, 197, 115, 54, 0, 99, 230, 193, 239, 127, 14, 107, 95, 116, 157, 70, 6, 160, 115, 231, 72, 94, 218, 112, 22, 75, 62, 57, 201, 247, 183, 12, 14, 79, 172, 99, 66, 253, 66, 62, 159, 110, 39, 21, 251, 212, 117, 28, 41, 38, 3, 212, 241, 3, 211, 202, 119, 92, 71, 241, 51, 21, 128, 34, 176, 237, 156, 133, 229, 191, 48, 212, 184, 206, 226, 57, 153, 73, 176, 252, 141, 190, 33, 64, 226, 27, 91, 51, 53, 188, 214, 53, 129, 215, 54, 78, 100, 91, 54, 229, 58, 206, 128, 197, 76, 134, 19, 107, 222, 97, 226, 144, 133, 28, 83, 181, 66, 187, 250, 131, 168, 239, 228, 127, 163, 105, 229, 142, 131, 126, 173, 28, 144, 10, 64, 145, 216, 14, 62, 143, 229, 55, 64, 131, 235, 44, 158, 179, 175, 97, 65, 226, 11, 25, 27, 99, 201, 39, 39, 177, 100, 203, 73, 44, 219, 118, 44, 189, 57, 239, 93, 237, 74, 197, 62, 101, 108, 245, 50, 78, 168, 121, 151, 49, 53, 203, 73, 68, 244, 28, 175, 192, 138, 98, 169, 227, 155, 102, 6, 247, 184, 142, 18, 4, 42, 0, 69, 100, 219, 24, 143, 97, 62, 7, 127, 112, 110, 248, 172, 7, 214, 185, 14, 33, 133, 232, 201, 85, 240, 206, 214, 49, 127, 44, 3, 59, 179, 110, 6, 10, 69, 76, 142, 67, 146, 107, 57, 46, 245, 7, 78, 168, 125, 135, 35, 43, 63, 212, 212, 190, 48, 136, 145, 163, 150, 175, 152, 25, 104, 162, 88, 145, 168, 0, 20, 153, 93, 194, 104, 178, 204, 7, 142, 119, 157, 197, 115, 180, 18, 16, 24, 22, 195, 218, 238, 225, 172, 218, 126, 56, 43, 183, 31, 193, 170, 237, 135, 179, 174, 103, 24, 214, 22, 255, 45, 165, 190, 98, 19, 71, 36, 87, 115, 68, 213, 106, 14, 175, 92, 205, 97, 85, 107, 168, 48, 189, 69, 255, 62, 226, 97, 9, 186, 169, 99, 138, 105, 230, 117, 215, 81, 130, 68, 5, 160, 4, 236, 239, 168, 167, 151, 199, 49, 76, 118, 157, 197, 115, 84, 2, 2, 171, 199, 198, 233, 234, 105, 96, 99, 255, 175, 174, 222, 6, 186, 122, 234, 233, 206, 86, 208, 109, 19, 100, 114, 49, 118, 230, 146, 100, 108, 12, 172, 37, 30, 201, 80, 25, 221, 73, 204, 244, 18, 55, 189, 84, 197, 118, 80, 23, 251, 132, 33, 21, 155, 104, 136, 119, 49, 36, 209, 197, 144, 120, 23, 241, 136, 78, 246, 161, 86, 197, 38, 146, 52, 153, 25, 172, 114, 29, 37, 104, 84, 0, 74, 196, 46, 165, 130, 110, 254, 21, 248, 170, 235, 44, 158, 163, 18, 32, 34, 3, 81, 205, 10, 210, 52, 153, 201, 108, 115, 29, 37, 136, 84, 0, 74, 200, 90, 12, 237, 220, 140, 225, 123, 232, 239, 122, 79, 42, 1, 34, 114, 32, 181, 44, 96, 22, 83, 140, 65, 27, 60, 74, 68, 39, 165, 50, 176, 29, 92, 130, 101, 46, 80, 225, 58, 139, 167, 168, 4, 136, 200, 103, 25, 32, 205, 61, 102, 38, 223, 112, 29, 37, 232, 84, 0, 202, 196, 182, 49, 5, 195, 227, 64, 218, 117, 22, 79, 81, 9, 16, 145, 93, 162, 88, 210, 124, 219, 180, 240, 83, 215, 81, 194, 64, 5, 160, 140, 108, 59, 99, 129, 249, 192, 145, 142, 163, 120, 139, 74, 128, 136, 196, 201, 144, 230, 124, 51, 141, 249, 174, 163, 132, 133, 10, 64, 153, 217, 133, 140, 32, 198, 60, 96, 130, 235, 44, 158, 162, 57, 1, 34, 225, 149, 100, 43, 41, 38, 152, 22, 222, 113, 29, 37, 76, 244, 56, 219, 50, 51, 167, 177, 150, 79, 248, 2, 112, 187, 235, 44, 158, 50, 12, 141, 79, 18, 9, 163, 26, 222, 101, 40, 35, 117, 242, 47, 63, 173, 0, 56, 100, 219, 248, 10, 134, 123, 128, 42, 215, 89, 60, 67, 151, 3, 68, 194, 193, 0, 245, 220, 103, 102, 240, 53, 215, 81, 194, 74, 5, 192, 49, 219, 193, 231, 176, 60, 1, 140, 118, 157, 197, 51, 84, 2, 68, 130, 45, 78, 134, 58, 174, 48, 211, 249, 133, 235, 40, 97, 166, 2, 224, 1, 246, 77, 134, 16, 231, 63, 128, 102, 215, 89, 60, 67, 37, 64, 36, 152, 42, 89, 79, 61, 19, 205, 217, 188, 231, 58, 74, 216, 169, 0, 120, 132, 181, 24, 58, 184, 1, 184, 13, 237, 205, 232, 163, 18, 32, 18, 44, 181, 188, 65, 45, 95, 48, 147, 201, 184, 142, 34, 42, 0, 158, 99, 219, 152, 137, 225, 87, 104, 94, 64, 31, 149, 0, 17, 255, 139, 98, 169, 229, 14, 51, 147, 155, 92, 71, 145, 63, 81, 1, 240, 32, 219, 193, 49, 228, 120, 2, 195, 137, 174, 179, 120, 130, 74, 128, 136, 127, 197, 233, 33, 205, 5, 186, 191, 223, 123, 84, 0, 60, 202, 46, 165, 154, 110, 126, 6, 218, 33, 11, 104, 78, 128, 136, 31, 165, 88, 70, 138, 179, 76, 179, 94, 189, 94, 164, 2, 224, 113, 182, 141, 11, 48, 204, 5, 134, 184, 206, 226, 156, 86, 2, 68, 252, 33, 138, 165, 154, 159, 155, 89, 92, 227, 58, 138, 236, 159, 10, 128, 15, 244, 79, 15, 188, 15, 152, 230, 58, 139, 115, 42, 1, 34, 222, 86, 73, 23, 53, 156, 107, 154, 105, 115, 29, 69, 14, 76, 5, 192, 39, 172, 197, 176, 152, 107, 176, 220, 14, 36, 92, 231, 113, 74, 37, 64, 196, 123, 12, 80, 195, 2, 106, 153, 170, 93, 254, 254, 160, 2, 224, 51, 118, 9, 39, 146, 229, 63, 129, 147, 92, 103, 113, 74, 37, 64, 196, 59, 18, 116, 147, 226, 50, 51, 131, 7, 93, 71, 145, 129, 83, 1, 240, 33, 251, 58, 149, 36, 249, 33, 112, 53, 97, 254, 55, 84, 9, 16, 113, 175, 154, 247, 169, 98, 162, 54, 250, 249, 79, 120, 79, 30, 1, 96, 219, 104, 198, 112, 63, 48, 194, 117, 22, 103, 84, 2, 68, 220, 136, 145, 163, 154, 219, 76, 43, 255, 224, 58, 138, 12, 142, 10, 128, 207, 217, 69, 28, 66, 132, 187, 129, 89, 174, 179, 56, 163, 91, 4, 69, 202, 171, 138, 78, 170, 153, 102, 154, 121, 219, 117, 20, 25, 60, 21, 128, 128, 176, 29, 204, 198, 242, 207, 192, 80, 215, 89, 156, 208, 74, 128, 72, 233, 197, 200, 81, 199, 79, 76, 11, 215, 187, 142, 34, 133, 83, 1, 8, 16, 187, 132, 70, 178, 252, 8, 184, 216, 117, 22, 39, 84, 2, 68, 74, 167, 154, 247, 169, 229, 92, 61, 196, 39, 56, 84, 0, 2, 200, 182, 115, 33, 112, 39, 97, 220, 27, 160, 18, 32, 82, 92, 113, 122, 169, 230, 6, 51, 147, 159, 186, 142, 34, 197, 165, 2, 16, 80, 118, 17, 117, 68, 184, 21, 184, 10, 136, 186, 206, 83, 86, 42, 1, 34, 197, 81, 203, 27, 228, 152, 110, 190, 200, 102, 215, 81, 164, 248, 84, 0, 2, 206, 46, 98, 28, 17, 230, 2, 227, 93, 103, 41, 43, 149, 0, 145, 193, 75, 176, 131, 26, 174, 52, 211, 121, 192, 117, 20, 41, 29, 61, 119, 62, 224, 204, 169, 180, 147, 99, 34, 112, 19, 176, 221, 117, 158, 178, 25, 10, 52, 186, 14, 33, 226, 51, 6, 168, 227, 215, 64, 90, 39, 255, 224, 211, 10, 64, 136, 216, 197, 28, 74, 142, 31, 16, 166, 77, 130, 90, 9, 16, 25, 152, 20, 107, 72, 241, 151, 166, 153, 215, 93, 71, 145, 242, 80, 1, 8, 33, 187, 152, 201, 100, 249, 39, 12, 39, 186, 206, 82, 22, 42, 1, 34, 251, 151, 224, 83, 106, 185, 222, 76, 227, 110, 215, 81, 164, 188, 84, 0, 66, 202, 190, 76, 140, 52, 87, 97, 185, 5, 168, 115, 157, 167, 228, 84, 2, 68, 246, 20, 35, 75, 138, 7, 169, 225, 50, 61, 188, 39, 156, 84, 0, 66, 206, 254, 47, 195, 201, 112, 43, 150, 203, 9, 250, 221, 2, 42, 1, 34, 125, 239, 250, 41, 222, 162, 134, 86, 51, 85, 175, 136, 48, 83, 1, 16, 0, 236, 34, 198, 244, 223, 54, 56, 219, 117, 150, 146, 82, 9, 144, 48, 171, 226, 99, 170, 153, 99, 154, 121, 197, 117, 20, 113, 79, 5, 64, 246, 96, 219, 153, 10, 252, 8, 56, 197, 117, 150, 146, 81, 9, 144, 176, 73, 176, 131, 106, 110, 52, 45, 220, 233, 58, 138, 120, 135, 110, 3, 148, 61, 152, 113, 188, 192, 10, 198, 99, 249, 26, 176, 202, 117, 158, 146, 208, 45, 130, 18, 22, 113, 50, 212, 51, 151, 97, 212, 234, 228, 47, 159, 165, 21, 0, 217, 47, 187, 148, 10, 118, 114, 41, 134, 91, 8, 226, 88, 97, 173, 4, 72, 80, 69, 201, 81, 205, 179, 100, 185, 72, 83, 252, 100, 127, 84, 0, 228, 160, 236, 18, 82, 100, 249, 22, 125, 195, 132, 210, 174, 243, 20, 149, 74, 128, 4, 73, 20, 75, 138, 55, 137, 112, 161, 105, 165, 211, 117, 28, 241, 54, 21, 0, 25, 48, 251, 63, 212, 80, 197, 223, 16, 180, 34, 160, 18, 32, 126, 183, 235, 196, 159, 228, 34, 211, 204, 74, 215, 113, 196, 31, 84, 0, 36, 111, 187, 21, 129, 27, 129, 122, 215, 121, 138, 66, 37, 64, 252, 72, 39, 126, 41, 128, 10, 128, 12, 154, 237, 32, 13, 92, 139, 229, 26, 160, 193, 117, 158, 130, 173, 7, 214, 185, 14, 33, 50, 0, 125, 39, 254, 151, 73, 114, 169, 105, 102, 181, 235, 56, 226, 79, 42, 0, 82, 48, 251, 50, 73, 234, 152, 131, 229, 59, 24, 142, 115, 157, 167, 32, 90, 9, 16, 47, 139, 145, 163, 138, 87, 73, 114, 177, 78, 252, 82, 40, 21, 0, 41, 26, 107, 137, 208, 206, 12, 12, 55, 1, 147, 92, 231, 25, 52, 149, 0, 241, 154, 56, 189, 164, 120, 138, 40, 151, 154, 22, 182, 184, 142, 35, 193, 160, 2, 32, 37, 97, 23, 113, 38, 134, 191, 197, 48, 11, 63, 206, 155, 208, 229, 0, 241, 130, 36, 155, 72, 114, 23, 51, 185, 217, 24, 114, 174, 227, 72, 176, 168, 0, 72, 73, 217, 183, 56, 138, 40, 215, 2, 87, 0, 85, 174, 243, 228, 69, 43, 1, 226, 130, 1, 170, 88, 67, 146, 155, 77, 11, 247, 186, 142, 35, 193, 165, 2, 32, 101, 97, 219, 25, 6, 124, 19, 184, 10, 63, 205, 225, 211, 74, 128, 148, 75, 148, 28, 41, 94, 37, 201, 183, 76, 51, 111, 187, 142, 35, 193, 167, 2, 32, 101, 101, 151, 82, 65, 15, 231, 97, 185, 18, 56, 27, 63, 252, 12, 106, 37, 64, 74, 41, 193, 118, 146, 60, 65, 5, 215, 154, 105, 116, 185, 142, 35, 225, 225, 253, 55, 95, 9, 44, 187, 132, 227, 200, 114, 25, 125, 151, 7, 134, 184, 206, 115, 64, 42, 1, 82, 76, 17, 44, 41, 150, 145, 224, 187, 102, 58, 79, 184, 142, 35, 225, 164, 2, 32, 206, 217, 37, 164, 200, 49, 187, 255, 1, 68, 103, 226, 213, 159, 75, 93, 14, 144, 66, 85, 178, 153, 36, 143, 96, 249, 123, 211, 202, 6, 215, 113, 36, 220, 188, 249, 70, 43, 161, 101, 23, 50, 138, 24, 23, 1, 95, 7, 70, 187, 206, 179, 23, 173, 4, 72, 190, 98, 100, 169, 226, 45, 42, 248, 174, 153, 206, 139, 174, 227, 136, 236, 162, 2, 32, 158, 212, 63, 83, 224, 28, 224, 98, 12, 231, 3, 41, 215, 153, 254, 72, 43, 1, 114, 48, 81, 44, 149, 172, 36, 193, 92, 42, 249, 177, 153, 76, 198, 117, 36, 145, 207, 82, 1, 16, 207, 179, 47, 147, 164, 150, 115, 48, 92, 12, 156, 7, 84, 184, 206, 164, 149, 0, 217, 167, 74, 186, 72, 242, 24, 67, 249, 158, 153, 160, 159, 16, 241, 54, 21, 0, 241, 21, 251, 38, 67, 136, 113, 33, 134, 57, 192, 89, 64, 212, 89, 24, 173, 4, 8, 244, 157, 244, 43, 153, 79, 146, 91, 204, 217, 188, 231, 58, 142, 200, 64, 169, 0, 136, 111, 217, 165, 52, 208, 205, 76, 12, 179, 177, 156, 139, 139, 149, 1, 173, 4, 132, 83, 146, 45, 36, 121, 145, 10, 190, 167, 123, 246, 197, 175, 84, 0, 36, 16, 108, 7, 105, 44, 173, 192, 121, 88, 206, 197, 80, 83, 182, 111, 174, 149, 128, 224, 139, 98, 73, 210, 73, 156, 167, 168, 224, 54, 61, 136, 71, 130, 64, 5, 64, 2, 199, 62, 66, 148, 163, 152, 72, 132, 153, 192, 44, 224, 248, 146, 127, 83, 173, 4, 4, 79, 156, 94, 146, 172, 32, 202, 227, 84, 115, 187, 153, 204, 54, 215, 145, 68, 138, 73, 5, 64, 2, 207, 46, 98, 12, 134, 105, 24, 206, 161, 111, 223, 64, 105, 238, 40, 208, 74, 128, 191, 69, 176, 36, 89, 79, 5, 175, 17, 229, 110, 211, 194, 115, 174, 35, 137, 148, 146, 10, 128, 132, 74, 255, 40, 226, 73, 253, 123, 6, 206, 1, 154, 40, 230, 70, 66, 149, 0, 127, 73, 240, 41, 9, 22, 19, 227, 17, 170, 184, 87, 159, 242, 37, 76, 84, 0, 36, 212, 236, 82, 170, 233, 102, 2, 150, 51, 49, 156, 1, 252, 57, 133, 110, 38, 212, 229, 0, 239, 74, 176, 157, 56, 127, 32, 206, 75, 84, 114, 151, 118, 237, 75, 152, 169, 0, 136, 236, 198, 46, 165, 154, 94, 38, 145, 227, 76, 44, 167, 99, 56, 29, 168, 203, 251, 64, 90, 9, 112, 47, 138, 37, 193, 70, 98, 44, 37, 194, 211, 84, 112, 191, 105, 214, 191, 138, 200, 46, 42, 0, 34, 7, 96, 45, 17, 58, 24, 131, 229, 116, 34, 76, 192, 114, 58, 48, 22, 136, 31, 244, 15, 171, 4, 148, 143, 1, 226, 236, 32, 193, 74, 98, 252, 150, 24, 243, 104, 230, 25, 99, 200, 185, 142, 38, 226, 85, 42, 0, 34, 121, 178, 139, 136, 19, 227, 88, 114, 140, 135, 63, 254, 58, 5, 168, 222, 235, 139, 117, 57, 160, 248, 34, 88, 226, 236, 32, 206, 90, 98, 44, 193, 240, 2, 49, 30, 210, 163, 116, 69, 242, 163, 2, 32, 82, 36, 182, 157, 145, 192, 88, 12, 39, 0, 99, 177, 156, 128, 229, 100, 54, 82, 163, 18, 48, 8, 125, 159, 234, 187, 137, 179, 158, 40, 239, 17, 165, 29, 195, 2, 170, 152, 175, 217, 250, 34, 133, 83, 1, 16, 41, 33, 107, 49, 188, 197, 97, 116, 113, 1, 89, 198, 145, 225, 88, 114, 28, 74, 134, 6, 50, 84, 145, 9, 249, 107, 48, 138, 37, 202, 78, 98, 108, 36, 202, 26, 162, 44, 39, 74, 7, 134, 215, 152, 70, 155, 150, 240, 69, 74, 39, 220, 111, 62, 34, 142, 217, 231, 24, 73, 134, 211, 128, 38, 114, 140, 33, 203, 161, 228, 24, 78, 142, 52, 89, 82, 228, 168, 32, 67, 20, 235, 58, 105, 158, 12, 16, 33, 71, 148, 30, 162, 108, 39, 202, 102, 12, 107, 137, 176, 138, 24, 127, 192, 176, 132, 28, 109, 102, 6, 171, 92, 71, 21, 9, 43, 21, 0, 17, 143, 179, 143, 16, 165, 158, 99, 233, 229, 56, 12, 163, 201, 112, 24, 134, 33, 64, 61, 57, 210, 64, 13, 57, 106, 200, 81, 137, 37, 73, 142, 56, 150, 88, 255, 175, 190, 83, 177, 197, 244, 255, 190, 79, 246, 51, 175, 253, 93, 95, 181, 187, 8, 25, 192, 18, 33, 67, 132, 94, 32, 75, 132, 157, 64, 15, 17, 182, 98, 216, 130, 97, 19, 134, 141, 24, 214, 3, 107, 137, 178, 146, 30, 86, 80, 203, 59, 90, 166, 23, 241, 182, 255, 7, 185, 132, 124, 151, 9, 57, 191, 10, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130}} 11 | -------------------------------------------------------------------------------- /res/repeatIconDark.go: -------------------------------------------------------------------------------- 1 | // auto-generated 2 | 3 | package res 4 | 5 | import "fyne.io/fyne/v2" 6 | 7 | var ResourceRepeatDarkPng = &fyne.StaticResource{ 8 | StaticName: "repeat.png", 9 | StaticContent: []byte{ 10 | 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 48, 0, 0, 0, 48, 8, 6, 0, 0, 0, 87, 2, 249, 135, 0, 0, 0, 6, 98, 75, 71, 68, 0, 255, 0, 255, 0, 255, 160, 189, 167, 147, 0, 0, 1, 199, 73, 68, 65, 84, 104, 129, 237, 152, 205, 74, 195, 64, 20, 70, 79, 93, 216, 7, 112, 169, 62, 146, 182, 150, 74, 55, 46, 93, 21, 169, 160, 15, 32, 46, 125, 32, 17, 247, 34, 186, 80, 124, 2, 5, 139, 85, 169, 32, 88, 177, 96, 165, 113, 49, 41, 214, 155, 180, 185, 201, 132, 102, 2, 115, 96, 160, 139, 123, 239, 124, 223, 100, 58, 127, 224, 241, 120, 92, 97, 27, 120, 3, 158, 128, 122, 193, 90, 82, 83, 1, 250, 64, 16, 182, 17, 208, 42, 84, 81, 6, 94, 249, 51, 80, 74, 19, 13, 140, 232, 82, 155, 104, 18, 53, 241, 3, 236, 20, 41, 42, 45, 185, 153, 168, 2, 29, 224, 10, 248, 20, 5, 139, 104, 35, 82, 172, 78, 171, 192, 157, 3, 162, 101, 235, 106, 196, 87, 29, 21, 31, 0, 143, 26, 3, 29, 7, 132, 90, 77, 161, 107, 145, 120, 10, 172, 105, 18, 115, 162, 133, 229, 114, 58, 16, 201, 165, 18, 15, 209, 79, 183, 40, 106, 228, 180, 145, 229, 97, 96, 5, 216, 5, 206, 129, 119, 224, 72, 145, 211, 37, 89, 252, 158, 166, 115, 91, 3, 199, 68, 71, 114, 168, 200, 235, 145, 44, 126, 172, 17, 96, 107, 64, 254, 135, 180, 117, 106, 152, 101, 242, 62, 252, 61, 205, 68, 188, 74, 143, 173, 129, 19, 204, 136, 95, 88, 214, 153, 48, 45, 62, 82, 167, 18, 147, 32, 131, 226, 98, 180, 76, 215, 202, 90, 103, 44, 114, 255, 213, 89, 202, 88, 116, 145, 204, 53, 94, 6, 3, 115, 241, 6, 138, 38, 201, 192, 34, 119, 226, 76, 204, 51, 16, 0, 251, 139, 18, 146, 39, 1, 102, 233, 146, 219, 246, 22, 240, 140, 121, 254, 104, 166, 168, 101, 187, 15, 164, 222, 151, 226, 196, 203, 83, 98, 95, 217, 249, 48, 140, 255, 82, 198, 199, 145, 218, 64, 146, 248, 0, 120, 81, 118, 126, 136, 57, 26, 28, 40, 227, 227, 176, 58, 25, 204, 58, 159, 55, 44, 4, 165, 37, 179, 129, 92, 46, 23, 150, 172, 139, 254, 63, 180, 137, 174, 136, 63, 19, 26, 46, 53, 137, 117, 162, 226, 93, 105, 109, 141, 1, 121, 51, 114, 165, 221, 0, 203, 82, 108, 89, 142, 18, 183, 192, 6, 240, 173, 9, 118, 101, 10, 13, 48, 115, 190, 77, 204, 200, 39, 225, 95, 137, 93, 97, 214, 114, 42, 47, 221, 78, 19, 103, 66, 245, 200, 234, 18, 210, 68, 175, 88, 57, 217, 168, 1, 15, 152, 209, 223, 44, 88, 139, 199, 227, 9, 249, 5, 127, 211, 221, 18, 169, 172, 165, 204, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130}} 11 | -------------------------------------------------------------------------------- /res/repeatIconLight.go: -------------------------------------------------------------------------------- 1 | // auto-generated 2 | 3 | package res 4 | 5 | import "fyne.io/fyne/v2" 6 | 7 | var ResourceRepeatLightPng = &fyne.StaticResource{ 8 | StaticName: "repeat-light.png", 9 | StaticContent: []byte{ 10 | 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 48, 0, 0, 0, 48, 8, 6, 0, 0, 0, 87, 2, 249, 135, 0, 0, 2, 233, 73, 68, 65, 84, 104, 67, 237, 152, 203, 106, 21, 65, 16, 134, 191, 95, 5, 175, 184, 241, 130, 183, 248, 4, 130, 59, 65, 125, 1, 55, 226, 133, 132, 128, 184, 112, 39, 162, 68, 196, 157, 59, 151, 110, 36, 106, 80, 16, 151, 130, 136, 34, 42, 232, 43, 136, 11, 221, 248, 6, 38, 40, 17, 119, 17, 162, 162, 150, 148, 204, 9, 125, 38, 115, 235, 201, 204, 57, 115, 48, 189, 157, 238, 158, 255, 171, 170, 174, 174, 46, 49, 226, 67, 35, 174, 159, 85, 128, 97, 123, 176, 51, 30, 48, 179, 9, 224, 30, 240, 3, 184, 40, 233, 121, 21, 227, 116, 2, 192, 204, 92, 199, 23, 96, 123, 34, 250, 23, 112, 86, 210, 227, 50, 136, 78, 0, 184, 72, 51, 155, 7, 118, 6, 130, 43, 65, 116, 9, 224, 52, 224, 22, 95, 23, 3, 209, 25, 128, 196, 11, 227, 192, 163, 20, 196, 111, 224, 156, 164, 135, 89, 225, 212, 41, 128, 58, 16, 185, 0, 102, 182, 30, 56, 15, 156, 1, 14, 0, 155, 203, 14, 84, 203, 223, 253, 76, 76, 164, 179, 83, 38, 128, 153, 237, 5, 94, 1, 7, 91, 22, 21, 187, 253, 156, 164, 177, 112, 209, 50, 128, 196, 242, 111, 59, 40, 222, 117, 207, 74, 218, 95, 6, 48, 5, 220, 138, 53, 205, 0, 230, 87, 11, 33, 51, 115, 235, 31, 10, 4, 189, 246, 179, 32, 105, 110, 0, 34, 253, 62, 152, 4, 60, 227, 84, 74, 167, 89, 33, 180, 0, 108, 9, 196, 142, 117, 85, 188, 107, 204, 2, 176, 190, 24, 147, 6, 146, 106, 205, 236, 4, 240, 180, 170, 229, 123, 26, 91, 1, 48, 179, 109, 192, 41, 79, 123, 73, 56, 78, 75, 186, 94, 20, 130, 102, 54, 11, 236, 43, 186, 133, 205, 236, 146, 164, 153, 178, 67, 188, 34, 15, 152, 153, 11, 189, 150, 178, 228, 119, 73, 27, 75, 0, 62, 1, 187, 243, 138, 57, 23, 15, 220, 150, 180, 166, 109, 128, 244, 25, 250, 247, 63, 149, 132, 98, 18, 66, 119, 0, 207, 54, 87, 36, 189, 232, 9, 237, 137, 79, 182, 233, 139, 154, 198, 67, 200, 204, 110, 0, 158, 138, 223, 1, 71, 151, 98, 181, 230, 89, 10, 197, 103, 25, 162, 113, 128, 208, 189, 102, 182, 20, 142, 101, 30, 200, 11, 47, 51, 251, 19, 38, 155, 244, 62, 163, 0, 80, 120, 38, 87, 1, 74, 50, 75, 19, 33, 244, 127, 123, 192, 210, 121, 55, 166, 30, 106, 232, 16, 215, 246, 128, 47, 188, 44, 201, 115, 115, 173, 49, 76, 0, 23, 63, 21, 94, 219, 102, 230, 165, 193, 221, 228, 134, 189, 32, 201, 235, 150, 194, 49, 44, 0, 207, 187, 105, 241, 233, 18, 247, 171, 164, 29, 21, 0, 22, 129, 13, 192, 162, 164, 77, 101, 243, 179, 190, 135, 70, 168, 122, 145, 245, 21, 76, 57, 245, 249, 188, 164, 93, 101, 130, 204, 236, 170, 119, 217, 128, 25, 73, 55, 203, 230, 55, 2, 144, 186, 73, 243, 30, 23, 147, 146, 158, 213, 17, 20, 187, 38, 218, 3, 65, 1, 21, 245, 50, 138, 21, 86, 101, 190, 153, 249, 3, 254, 99, 48, 119, 65, 210, 214, 194, 106, 212, 63, 198, 62, 235, 170, 136, 137, 157, 147, 136, 191, 15, 28, 11, 214, 190, 145, 116, 164, 16, 192, 204, 78, 2, 79, 82, 245, 124, 236, 255, 219, 154, 239, 93, 107, 207, 132, 75, 35, 171, 22, 74, 191, 140, 218, 18, 19, 187, 239, 123, 224, 176, 164, 159, 163, 8, 224, 226, 143, 75, 242, 87, 91, 223, 200, 242, 64, 87, 66, 232, 27, 240, 33, 105, 177, 60, 72, 91, 190, 71, 145, 215, 90, 140, 238, 18, 199, 198, 67, 83, 243, 139, 154, 187, 35, 1, 81, 216, 243, 41, 72, 167, 227, 225, 163, 187, 41, 107, 214, 217, 167, 180, 105, 149, 3, 177, 172, 201, 90, 231, 231, 77, 172, 41, 5, 200, 185, 216, 62, 75, 218, 211, 132, 128, 149, 238, 81, 9, 32, 129, 240, 214, 223, 52, 176, 22, 240, 130, 239, 229, 74, 127, 222, 196, 250, 202, 0, 77, 252, 172, 141, 61, 86, 1, 218, 176, 106, 204, 158, 35, 239, 129, 191, 104, 250, 137, 64, 112, 59, 51, 234, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130}} 11 | -------------------------------------------------------------------------------- /ui/extended/doubleTapLabel.go: -------------------------------------------------------------------------------- 1 | package extended 2 | 3 | import ( 4 | "fyne.io/fyne/v2" 5 | "fyne.io/fyne/v2/widget" 6 | ) 7 | 8 | type DoubleTapLabel struct { 9 | widget.Label 10 | doubleTapped func(index int) 11 | index int 12 | } 13 | 14 | func NewDoubleTapLabel(f func(int)) *DoubleTapLabel { 15 | label := &DoubleTapLabel{doubleTapped: f} 16 | label.ExtendBaseWidget(label) 17 | return label 18 | } 19 | 20 | func (label *DoubleTapLabel) DoubleTapped(_ *fyne.PointEvent) { 21 | if label.doubleTapped != nil { 22 | label.doubleTapped(label.index) 23 | } 24 | } 25 | 26 | func (label *DoubleTapLabel) Set(text string, index int) { 27 | label.SetText(text) 28 | label.index = index 29 | } 30 | -------------------------------------------------------------------------------- /ui/file-search.go: -------------------------------------------------------------------------------- 1 | package ui 2 | 3 | import ( 4 | "fyne.io/fyne/v2" 5 | "fyne.io/fyne/v2/container" 6 | "fyne.io/fyne/v2/widget" 7 | "github.com/tejashwikalptaru/gotune/utils" 8 | ) 9 | 10 | type FileSearchWindow struct { 11 | win fyne.Window 12 | progress *widget.ProgressBarInfinite 13 | progressParsing *widget.ProgressBar 14 | label *widget.Label 15 | } 16 | 17 | func NewFileSearchWindow(app fyne.App) *FileSearchWindow { 18 | fsw := FileSearchWindow{} 19 | fsw.win = app.NewWindow("Please wait") 20 | fsw.win.Resize(fyne.Size{ 21 | Width: utils.WIDTH - 100, 22 | Height: utils.HEIGHT / 4, 23 | }) 24 | fsw.win.SetFixedSize(true) 25 | 26 | fsw.progress = widget.NewProgressBarInfinite() 27 | fsw.progress.Start() 28 | fsw.progressParsing = widget.NewProgressBar() 29 | fsw.progressParsing.Hide() 30 | fsw.label = widget.NewLabel("Processing ....") 31 | 32 | fsw.win.SetContent(container.NewVBox(fsw.label, fsw.progress, fsw.progressParsing)) 33 | return &fsw 34 | } 35 | 36 | func (fsw *FileSearchWindow) Show() { 37 | fsw.win.Show() 38 | } 39 | 40 | func (fsw *FileSearchWindow) Close() { 41 | fsw.win.Close() 42 | } 43 | 44 | func (fsw *FileSearchWindow) UpdateLabel(label string) { 45 | fsw.label.SetText(label) 46 | } 47 | 48 | func (fsw *FileSearchWindow) OnClosed(f func()) { 49 | fsw.win.SetOnClosed(f) 50 | } 51 | -------------------------------------------------------------------------------- /ui/main-window.go: -------------------------------------------------------------------------------- 1 | package ui 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "fyne.io/fyne/v2" 7 | "fyne.io/fyne/v2/app" 8 | "fyne.io/fyne/v2/canvas" 9 | "fyne.io/fyne/v2/container" 10 | "fyne.io/fyne/v2/driver/desktop" 11 | "fyne.io/fyne/v2/theme" 12 | "fyne.io/fyne/v2/widget" 13 | "github.com/tejashwikalptaru/gotune/res" 14 | "github.com/tejashwikalptaru/gotune/ui/rotate" 15 | "github.com/tejashwikalptaru/gotune/utils" 16 | "image" 17 | "math" 18 | "path/filepath" 19 | "time" 20 | ) 21 | 22 | type FileOpenCallBack func(filePath string) 23 | 24 | type Main struct { 25 | app fyne.App 26 | window fyne.Window 27 | 28 | prevButton *widget.Button 29 | playButton *widget.Button 30 | stopButton *widget.Button 31 | nextButton *widget.Button 32 | muteButton *widget.Button 33 | loopButton *widget.Button 34 | songInfo *widget.Label 35 | currentTime *widget.Label 36 | endTime *widget.Label 37 | progressSlider *widget.Slider 38 | volumeSlider *widget.Slider 39 | albumArt *canvas.Image 40 | 41 | isDarkTheme bool 42 | fileSearchStatus utils.ScanStatus 43 | changeListener chan fyne.Settings 44 | 45 | // callbacks 46 | fileOpenCallBack FileOpenCallBack 47 | addToPlayListFunc func(path string) 48 | openPlaylistCallBack func() 49 | 50 | // rotator chan 51 | killRotate chan bool 52 | rotator *rotate.Rotator 53 | } 54 | 55 | func NewMainWindow() *Main { 56 | var main Main 57 | 58 | a := app.NewWithID(utils.PACKAGE) 59 | w := a.NewWindow(utils.APPNAME) 60 | splitContainer := container.NewBorder(nil, main.controls(), nil, nil, main.display()) 61 | w.SetContent(container.NewPadded(splitContainer)) 62 | w.SetMainMenu(fyne.NewMainMenu(main.createMainMenu()...)) 63 | main.app = a 64 | main.window = w 65 | w.Resize(fyne.Size{ 66 | Width: utils.WIDTH, 67 | Height: utils.HEIGHT, 68 | }) 69 | w.SetFixedSize(true) 70 | 71 | main.killRotate = make(chan bool, 1) 72 | main.changeListener = make(chan fyne.Settings, 1) 73 | main.rotator = rotate.NewRotator(utils.APPNAME, 15) 74 | main.scrollInfoRoutine() 75 | return &main 76 | } 77 | 78 | func (main *Main) Free() { 79 | main.killRotate <- true 80 | close(main.killRotate) 81 | close(main.changeListener) 82 | } 83 | 84 | func (main *Main) createMainMenu() []*fyne.Menu { 85 | menus := make([]*fyne.Menu, 0) 86 | separator := fyne.NewMenuItemSeparator() 87 | 88 | openFile := fyne.NewMenuItem("Open", func() { 89 | main.handleOpenFile() 90 | }) 91 | openFolder := fyne.NewMenuItem("Open Folder", func() { 92 | main.handleOpenFolder() 93 | }) 94 | viewPL := fyne.NewMenuItem("View Playlist", func() { 95 | if main.openPlaylistCallBack != nil { 96 | main.openPlaylistCallBack() 97 | } 98 | }) 99 | exitMenu := fyne.NewMenuItem("Exit", func() { 100 | main.window.Close() 101 | }) 102 | 103 | fileMenuItems := fyne.NewMenu("File", openFile, openFolder, separator, viewPL, separator, exitMenu) 104 | menus = append(menus, fileMenuItems) 105 | return menus 106 | } 107 | 108 | func (main *Main) display() fyne.CanvasObject { 109 | main.albumArt = canvas.NewImageFromResource(res.ResourceMusicPng) 110 | main.albumArt.FillMode = canvas.ImageFillContain 111 | return main.albumArt 112 | } 113 | func (main *Main) controls() fyne.CanvasObject { 114 | main.prevButton = widget.NewButtonWithIcon("", theme.MediaSkipPreviousIcon(), func() {}) 115 | main.playButton = widget.NewButtonWithIcon("", theme.MediaPlayIcon(), func() {}) 116 | main.stopButton = widget.NewButtonWithIcon("", theme.MediaStopIcon(), func() {}) 117 | main.nextButton = widget.NewButtonWithIcon("", theme.MediaSkipNextIcon(), func() {}) 118 | main.muteButton = widget.NewButtonWithIcon("", theme.VolumeUpIcon(), func() {}) 119 | main.loopButton = widget.NewButtonWithIcon("", theme.MediaReplayIcon(), func() {}) 120 | main.songInfo = widget.NewLabel("") 121 | main.songInfo.Wrapping = fyne.TextTruncate 122 | main.songInfo.TextStyle = fyne.TextStyle{ 123 | Bold: true, 124 | Italic: true, 125 | Monospace: false, 126 | } 127 | main.volumeSlider = widget.NewSlider(0, 100) 128 | main.volumeSlider.Orientation = widget.Horizontal 129 | 130 | volIcon := canvas.NewImageFromResource(theme.VolumeUpIcon()) 131 | volumeHolder := container.NewHBox(volIcon, main.volumeSlider) 132 | 133 | buttonsHBox := container.NewHBox(main.prevButton, main.playButton, main.stopButton, main.nextButton, main.muteButton, main.loopButton) 134 | buttonsHolder := container.NewBorder(nil, nil, buttonsHBox, volumeHolder, main.songInfo) 135 | 136 | main.progressSlider = widget.NewSlider(0, 100) 137 | main.currentTime = widget.NewLabel("00:00") 138 | main.endTime = widget.NewLabel("00:00") 139 | 140 | sliderHolder := container.NewBorder(nil, nil, main.currentTime, main.endTime, main.progressSlider) 141 | 142 | return container.NewVBox(buttonsHolder, sliderHolder) 143 | } 144 | 145 | func (main *Main) ShowAndRun() { 146 | main.app.SetIcon(res.ResourceIconPng) 147 | if main.app.Settings().ThemeVariant() == 0 { 148 | main.isDarkTheme = true 149 | } else { 150 | main.isDarkTheme = false 151 | } 152 | 153 | go func() { 154 | for { 155 | settings := <- main.changeListener 156 | if settings == nil { 157 | return 158 | } 159 | if settings.ThemeVariant() == 0 { 160 | main.isDarkTheme = true 161 | main.loopButton.SetIcon(res.ResourceRepeatLightPng) 162 | } else { 163 | main.isDarkTheme = false 164 | main.loopButton.SetIcon(res.ResourceRepeatDarkPng) 165 | } 166 | } 167 | }() 168 | main.app.Settings().AddChangeListener(main.changeListener) 169 | main.window.ShowAndRun() 170 | } 171 | 172 | func (main *Main) ShowNotification(title, message string) { 173 | main.app.SendNotification(fyne.NewNotification(title, message)) 174 | } 175 | 176 | func (main *Main) OnMute(f func()) { 177 | main.muteButton.OnTapped = f 178 | } 179 | 180 | func (main *Main) SetMuteState(mute bool) { 181 | if mute { 182 | main.muteButton.SetIcon(theme.VolumeMuteIcon()) 183 | } else { 184 | main.muteButton.SetIcon(theme.VolumeUpIcon()) 185 | } 186 | } 187 | 188 | func (main *Main) SetLoopState(loop bool) { 189 | var icon *fyne.StaticResource 190 | if main.isDarkTheme { 191 | icon = res.ResourceRepeatLightPng 192 | } else { 193 | icon = res.ResourceRepeatDarkPng 194 | } 195 | 196 | if loop { 197 | main.loopButton.SetIcon(icon) 198 | } else { 199 | main.loopButton.SetIcon(theme.MediaReplayIcon()) 200 | } 201 | } 202 | 203 | func (main *Main) OnPlay(f func()) { 204 | main.playButton.OnTapped = f 205 | } 206 | 207 | func (main *Main) OnStop(f func()) { 208 | main.stopButton.OnTapped = f 209 | } 210 | 211 | func (main *Main) SetPlayState(playing bool) { 212 | if playing { 213 | main.playButton.SetIcon(theme.MediaPauseIcon()) 214 | } else { 215 | main.playButton.SetIcon(theme.MediaPlayIcon()) 216 | } 217 | } 218 | 219 | func (main *Main) SetAlbumArt(imgByte []byte) { 220 | img, _, err := image.Decode(bytes.NewReader(imgByte)) 221 | if err != nil { 222 | //fmt.Print(err) 223 | return 224 | } 225 | main.albumArt.Resource = nil 226 | main.albumArt.Image = img 227 | canvas.Refresh(main.albumArt) 228 | } 229 | 230 | func (main *Main) ClearAlbumArt() { 231 | main.albumArt.Image = nil 232 | main.albumArt.Resource = res.ResourceMusicPng 233 | main.albumArt.Refresh() 234 | } 235 | 236 | func (main *Main) SetCurrentTime(timeElapsed float64) { 237 | format := fmt.Sprintf("%.2d:%.2d", int(timeElapsed/60), int(math.Mod(timeElapsed, 60))) 238 | main.progressSlider.Value = timeElapsed 239 | main.progressSlider.Refresh() 240 | main.currentTime.SetText(format) 241 | } 242 | 243 | func (main *Main) SetTotalTime(endTime float64) { 244 | format := fmt.Sprintf("%.2d:%.2d", int(endTime/60), int(math.Mod(endTime, 60))) 245 | main.progressSlider.Max = endTime 246 | main.endTime.SetText(format) 247 | } 248 | 249 | func (main *Main) SetSongName(name string) { 250 | main.rotator = rotate.NewRotator(name, 15) 251 | } 252 | 253 | func (main *Main) scrollInfoRoutine() { 254 | go func() { 255 | for { 256 | select { 257 | case <-main.killRotate: 258 | return 259 | default: 260 | time.Sleep(time.Millisecond * 400) 261 | main.songInfo.SetText(main.rotator.Rotate()) 262 | } 263 | } 264 | }() 265 | } 266 | 267 | func (main *Main) AddShortCuts() { 268 | volUp := desktop.CustomShortcut{ 269 | KeyName: fyne.KeyUp, 270 | Modifier: desktop.AltModifier, 271 | } 272 | main.window.Canvas().AddShortcut(&volUp, func(shortcut fyne.Shortcut) { 273 | main.volumeSlider.SetValue(main.volumeSlider.Value + 1) 274 | }) 275 | volDown := desktop.CustomShortcut{ 276 | KeyName: fyne.KeyDown, 277 | Modifier: desktop.AltModifier, 278 | } 279 | main.window.Canvas().AddShortcut(&volDown, func(shortcut fyne.Shortcut) { 280 | main.volumeSlider.SetValue(main.volumeSlider.Value - 1) 281 | }) 282 | } 283 | 284 | func (main *Main) SetPlayListUpdater(f func(p string)) { 285 | main.addToPlayListFunc = f 286 | } 287 | 288 | func (main *Main) handleOpenFolder() { 289 | if main.fileSearchStatus == utils.ScanRunning { 290 | utils.ShowError(true, "Please wait", "Scanning is already running, please wait for that to finish%s", "") 291 | return 292 | } 293 | main.fileSearchStatus = utils.ScanRunning 294 | path, err := utils.OpenFolder("Select folder to search for files...") 295 | if err != nil { 296 | fyne.LogError("failed to open folder browser", err) 297 | main.fileSearchStatus = utils.ScanStopped 298 | return 299 | } 300 | fsw := NewFileSearchWindow(main.app) 301 | fsw.OnClosed(func() { 302 | main.fileSearchStatus = utils.ScanStopped 303 | }) 304 | fsw.Show() 305 | go func() { 306 | files, err := utils.ScanFolder(path, func(s string) { 307 | fsw.UpdateLabel(filepath.Base(s)) 308 | }, &main.fileSearchStatus) 309 | if err != nil { 310 | fyne.LogError("failed to scan for files in folder", err) 311 | fsw.Close() 312 | } 313 | if main.addToPlayListFunc != nil { 314 | fsw.progress.Hide() 315 | fsw.progressParsing.Min = 0 316 | fsw.progressParsing.Max = float64(len(files)) 317 | fsw.progressParsing.Show() 318 | for i, f := range files { 319 | fsw.UpdateLabel(fmt.Sprintf("Found: %d items, processing: %d", len(files), i+1)) 320 | fsw.progressParsing.SetValue(float64(i + 1)) 321 | main.addToPlayListFunc(f) 322 | } 323 | } 324 | fsw.Close() 325 | }() 326 | } 327 | 328 | func (main *Main) SetOpenPlayListCallBack(f func()) { 329 | main.openPlaylistCallBack = f 330 | } 331 | 332 | func (main *Main) SetFileOpenCallBack(f FileOpenCallBack) { 333 | main.fileOpenCallBack = f 334 | } 335 | 336 | func (main *Main) handleOpenFile() { 337 | path, err := utils.OpenFile("Select a file to play") 338 | if err != nil { 339 | fyne.LogError("failed to select file", err) 340 | return 341 | } 342 | if main.fileOpenCallBack == nil { 343 | return 344 | } 345 | main.fileOpenCallBack(path) 346 | } 347 | 348 | func (main *Main) SetVolume(vol float64) { 349 | main.volumeSlider.Value = vol 350 | } 351 | 352 | func (main *Main) VolumeUpdateCallBack(f func(float64)) { 353 | main.volumeSlider.OnChanged = f 354 | } 355 | 356 | func (main *Main) OnNext(f func()) { 357 | main.nextButton.OnTapped = f 358 | } 359 | 360 | func (main *Main) OnPrev(f func()) { 361 | main.prevButton.OnTapped = f 362 | } 363 | 364 | func (main *Main) ProgressChanged(f func(val float64)) { 365 | main.progressSlider.OnChanged = f 366 | } 367 | 368 | func (main *Main) GetApp() fyne.App { 369 | return main.app 370 | } 371 | 372 | func (main *Main) OnAppClose(f func()) { 373 | main.window.SetOnClosed(f) 374 | } 375 | 376 | func (main *Main) QuitApp() { 377 | main.app.Quit() 378 | } 379 | 380 | func (main *Main) OnLoop(f func()) { 381 | main.loopButton.OnTapped = f 382 | } 383 | 384 | func (main *Main) SaveHistory(data string) { 385 | main.app.Preferences().SetString(utils.HISTORY, data) 386 | } 387 | 388 | func (main *Main) GetHistory() string { 389 | return main.app.Preferences().String(utils.HISTORY) 390 | } 391 | -------------------------------------------------------------------------------- /ui/playlist-view.go: -------------------------------------------------------------------------------- 1 | package ui 2 | 3 | import ( 4 | "fmt" 5 | "fyne.io/fyne/v2" 6 | "fyne.io/fyne/v2/container" 7 | "fyne.io/fyne/v2/widget" 8 | "github.com/tejashwikalptaru/gotune/bass" 9 | "github.com/tejashwikalptaru/gotune/ui/extended" 10 | "strings" 11 | ) 12 | 13 | type PlayListView struct { 14 | win fyne.Window 15 | list *widget.List 16 | searchText *widget.Entry 17 | data []bass.MusicMetaInfo 18 | mainCollection []bass.MusicMetaInfo 19 | selectedPath string 20 | 21 | onClose func() 22 | onItemSelected func(path string) 23 | } 24 | 25 | func NewPlayListView(app fyne.App, data []bass.MusicMetaInfo, currentIndex int, onClose func(), onSelected func(path string)) *PlayListView { 26 | plView := PlayListView{data: data, mainCollection: data, onClose: onClose, onItemSelected: onSelected} 27 | plView.win = app.NewWindow(fmt.Sprintf("Playlist (%d items)", len(data))) 28 | plView.win.SetOnClosed(plView.onClose) 29 | plView.list = widget.NewList(plView.getDataLength, plView.createListCell, plView.updateCell) 30 | plView.win.Resize(fyne.Size{ 31 | Width: 500, 32 | Height: 600, 33 | }) 34 | if len(data) > currentIndex && currentIndex > -1 { 35 | plView.selectedPath = data[currentIndex].Path 36 | } 37 | plView.searchText = widget.NewEntry() 38 | plView.searchText.PlaceHolder = "Search..." 39 | plView.searchText.OnChanged = plView.searchCollection 40 | plView.win.SetContent(container.NewBorder(plView.searchText, nil, nil, nil, container.NewVScroll(plView.list))) 41 | return &plView 42 | } 43 | 44 | func (plView *PlayListView) getDataLength() int { 45 | return len(plView.data) 46 | } 47 | 48 | func (plView *PlayListView) createListCell() fyne.CanvasObject { 49 | return extended.NewDoubleTapLabel(func(index int) { 50 | if plView.onItemSelected != nil { 51 | plView.onItemSelected(plView.data[index].Path) 52 | } 53 | }) 54 | } 55 | 56 | func (plView *PlayListView) updateCell(i widget.ListItemID, o fyne.CanvasObject) { 57 | o.(*extended.DoubleTapLabel).Set(plView.data[i].Info.Name, i) 58 | } 59 | 60 | func (plView *PlayListView) searchCollection(query string) { 61 | query = strings.TrimSpace(query) 62 | if query == "" { 63 | // restore main collection 64 | plView.data = plView.mainCollection 65 | // highlight currently selected 66 | for _, v := range plView.data { 67 | if v.Path == plView.selectedPath { 68 | plView.SetSelected(v.Path) 69 | } 70 | } 71 | plView.list.Refresh() 72 | plView.win.SetTitle(fmt.Sprintf("Playlist (%d items)", len(plView.data))) 73 | return 74 | } 75 | if len(plView.data) == 0 { 76 | plView.win.SetTitle(fmt.Sprintf("Playlist (%d items)", len(plView.data))) 77 | plView.list.Refresh() 78 | return 79 | } 80 | temp := make([]bass.MusicMetaInfo, 0) 81 | for _, item := range plView.mainCollection { 82 | if strings.Contains(strings.ToLower(item.Path), strings.ToLower(query)) { 83 | temp = plView.addIfNotExists(temp, item) 84 | } 85 | if strings.Contains(strings.ToLower(item.Info.Name), strings.ToLower(query)) { 86 | temp = plView.addIfNotExists(temp, item) 87 | } 88 | if strings.Contains(strings.ToLower(item.Info.Author), strings.ToLower(query)) { 89 | temp = plView.addIfNotExists(temp, item) 90 | } 91 | if strings.Contains(strings.ToLower(item.Info.Artist), strings.ToLower(query)) { 92 | temp = plView.addIfNotExists(temp, item) 93 | } 94 | } 95 | plView.data = temp 96 | plView.win.SetTitle(fmt.Sprintf("Playlist (%d items)", len(plView.data))) 97 | plView.list.Refresh() 98 | } 99 | 100 | func (plView *PlayListView) addIfNotExists(array []bass.MusicMetaInfo, item bass.MusicMetaInfo) []bass.MusicMetaInfo { 101 | found := false 102 | for _, v := range array { 103 | if strings.EqualFold(v.Path, item.Path) { 104 | found = true 105 | break 106 | } 107 | } 108 | if found { 109 | return array 110 | } 111 | return append(array, item) 112 | } 113 | 114 | func (plView *PlayListView) Show() { 115 | plView.win.Show() 116 | plView.SetSelected(plView.selectedPath) 117 | } 118 | 119 | func (plView *PlayListView) SetSelected(path string) { 120 | if path == "" { 121 | return 122 | } 123 | for i, v := range plView.data { 124 | if v.Path == path { 125 | plView.list.Select(i) 126 | plView.selectedPath = path 127 | plView.list.Refresh() 128 | break 129 | } 130 | } 131 | } 132 | 133 | func (plView *PlayListView) FileAdded(info bass.MusicMetaInfo) { 134 | plView.data = append(plView.data, info) 135 | plView.mainCollection = append(plView.mainCollection, info) 136 | plView.list.Refresh() 137 | plView.win.SetTitle(fmt.Sprintf("Playlist (%d items)", len(plView.data))) 138 | } 139 | -------------------------------------------------------------------------------- /ui/rotate/rotate.go: -------------------------------------------------------------------------------- 1 | package rotate 2 | 3 | import "fmt" 4 | 5 | type Rotator struct { 6 | text string 7 | len int 8 | } 9 | 10 | func NewRotator(text string, maxLength int) *Rotator { 11 | return &Rotator{text: fmt.Sprintf(" %s", text), len: maxLength} 12 | } 13 | 14 | func (r *Rotator) Rotate() string { 15 | if len(r.text) < r.len { 16 | // do not rotate 17 | return r.text 18 | } 19 | runes := []rune(r.text) 20 | var newRune []rune 21 | var temp int32 22 | for i, v := range runes { 23 | if i == 0 { 24 | temp = v 25 | continue 26 | } 27 | newRune = append(newRune, v) 28 | } 29 | 30 | newRune = append(newRune, temp) 31 | r.text = string(newRune) 32 | return r.text 33 | } 34 | -------------------------------------------------------------------------------- /utils/utils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "errors" 5 | "github.com/sqweek/dialog" 6 | "os" 7 | "path/filepath" 8 | "strings" 9 | ) 10 | 11 | const ( 12 | APPNAME string = "Go Tune" 13 | HISTORY string = "Go Tune History" 14 | HEIGHT float32 = 300 15 | WIDTH float32 = 450 16 | PACKAGE string = "com.tejashwi.gotune.preferences" 17 | ) 18 | 19 | var supportedFormats = []string{ 20 | ".mp3", 21 | ".mp2", 22 | ".mp1", 23 | ".ogg", 24 | ".wav", 25 | ".aif", 26 | ".mo3", 27 | ".it", 28 | ".xm", 29 | ".s3m", 30 | ".mtm", 31 | ".mod", 32 | ".umx", 33 | ".cda", 34 | ".fla", 35 | ".flac", 36 | ".oga", 37 | ".wma", 38 | ".wv", 39 | ".aac", 40 | ".m4a", 41 | ".m4b", 42 | ".mp4", 43 | ".ac3", 44 | ".adx", 45 | ".aix", 46 | ".ape", 47 | ".mac", 48 | ".mpc", 49 | ".mp+", 50 | ".mpp", 51 | ".ofr", 52 | ".ofs", 53 | ".tta", 54 | } 55 | type ScanFolderCallBack func(string) 56 | var ScanCancelled = errors.New("scanning cancelled by user") 57 | type ScanStatus int 58 | const ( 59 | ScanStopped ScanStatus = 0 60 | ScanRunning ScanStatus = 1 61 | ) 62 | 63 | func ScanFolder(folderPath string, callback ScanFolderCallBack, status *ScanStatus) ([]string, error) { 64 | result := make([]string, 0) 65 | addPath := func(path string, info os.FileInfo, err error) error { 66 | if *status == ScanStopped { 67 | return ScanCancelled 68 | } 69 | if err != nil { 70 | return err 71 | } 72 | if !info.IsDir() && Contains(supportedFormats, filepath.Ext(path)) { 73 | if callback != nil { 74 | callback(path) 75 | } 76 | result = append(result, path) 77 | } 78 | return nil 79 | } 80 | err := filepath.Walk(folderPath, addPath) 81 | return result, err 82 | } 83 | 84 | func Contains(arr []string, input string) bool { 85 | for _, v := range arr { 86 | if strings.EqualFold(v, input) { 87 | return true 88 | } 89 | } 90 | return false 91 | } 92 | 93 | func ShowError(err bool, title, format string, args ...interface{}) { 94 | builder := dialog.Message(format, args).Title(title) 95 | if err { 96 | builder.Error() 97 | return 98 | } 99 | builder.Info() 100 | } 101 | 102 | func ShowInfo(title, format string, args ...interface{}) bool { 103 | return dialog.Message(format, args).Title(title).YesNo() 104 | } 105 | 106 | func removeDot(input []string) []string { 107 | removed := make([]string, 0) 108 | for _, val := range input { 109 | removed = append(removed, strings.Replace(val,".", "", -1)) 110 | } 111 | return removed 112 | } 113 | 114 | func OpenFile(title string) (string, error) { 115 | return dialog.File().Title(title).Filter("Audio Files", removeDot(supportedFormats)...).Load() 116 | } 117 | 118 | func OpenFolder(title string) (string, error) { 119 | return dialog.Directory().Title(title).Browse() 120 | } 121 | 122 | func IsMod(path string) bool { 123 | var mod = []string{ 124 | ".it", 125 | ".xm", 126 | ".s3m", 127 | ".mtm", 128 | ".mod", 129 | ".umx", 130 | } 131 | return Contains(mod, filepath.Ext(path)) 132 | } 133 | --------------------------------------------------------------------------------