| 
					
				 | 
			
			
				@@ -5,7 +5,11 @@ import crypto from "crypto"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import request from "request"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import CoreClass from "../core"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let UtilsModule; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let IOModule; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let CacheModule; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class _UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// eslint-disable-next-line require-jsdoc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	constructor() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		super("utils"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -13,6 +17,8 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		this.youtubeRequestCallbacks = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		this.youtubeRequestsPending = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		this.youtubeRequestsActive = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		UtilsModule = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	/** 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -22,10 +28,8 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	initialize() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(resolve => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.io = this.moduleManager.modules.io; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.db = this.moduleManager.modules.db; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.spotify = this.moduleManager.modules.spotify; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.cache = this.moduleManager.modules.cache; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			IOModule = this.moduleManager.modules.io; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			CacheModule = this.moduleManager.modules.cache; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		}); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -79,16 +83,20 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			let cookies; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				cookies = this.runJob("PARSE_COOKIES", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					cookieString: payload.cookieString 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				cookies = UtilsModule.runJob( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					"PARSE_COOKIES", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						cookieString: payload.cookieString 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				return reject(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			delete cookies[payload.cookieName]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return resolve(this.toString(cookies)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -124,10 +132,14 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		const promises = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		for (let i = 0; i < payload.length; i += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			promises.push( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.runJob("GET_RANDOM_NUMBER", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					min: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					max: chars.length - 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				UtilsModule.runJob( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					"GET_RANDOM_NUMBER", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						min: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						max: chars.length - 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -150,7 +162,7 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	async GET_SOCKET_FROM_ID(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// socketId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const io = await this.io.runJob("IO", {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const io = await IOModule.runJob("IO", {}, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(resolve => resolve(io.sockets.sockets[payload.socketId])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -248,7 +260,7 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// eslint-disable-next-line require-jsdoc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	async SOCKET_FROM_SESSION(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// socketId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const io = await this.io.runJob("IO", {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const io = await IOModule.runJob("IO", {}, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise((resolve, reject) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const ns = io.of("/"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -268,7 +280,7 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * @returns {Promise} - returns promise (reject, resolve) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	async SOCKETS_FROM_SESSION_ID(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const io = await this.io.runJob("IO", {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const io = await IOModule.runJob("IO", {}, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(resolve => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const ns = io.of("/"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -300,7 +312,7 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * @returns {Promise} - returns promise (reject, resolve) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	async SOCKETS_FROM_USER(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const io = await this.io.runJob("IO", {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const io = await IOModule.runJob("IO", {}, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise((resolve, reject) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const ns = io.of("/"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -311,11 +323,14 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					Object.keys(ns.connected), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					(id, next) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						const { session } = ns.connected[id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						this.cache 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							.runJob("HGET", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						CacheModule.runJob( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							"HGET", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								table: "sessions", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								key: session.sessionId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							.then(session => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								if (session && session.userId === payload.userId) sockets.push(ns.connected[id]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								next(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -343,7 +358,7 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * @returns {Promise} - returns promise (reject, resolve) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	async SOCKETS_FROM_IP(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const io = await this.io.runJob("IO", {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const io = await IOModule.runJob("IO", {}, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(resolve => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const ns = io.of("/"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -353,11 +368,14 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					Object.keys(ns.connected), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					(id, next) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						const { session } = ns.connected[id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						this.cache 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							.runJob("HGET", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						CacheModule.runJob( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							"HGET", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								table: "sessions", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								key: session.sessionId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							.then(session => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								if (session && ns.connected[id].ip === payload.ip) sockets.push(ns.connected[id]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								next(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -382,7 +400,7 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * @returns {Promise} - returns promise (reject, resolve) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	async SOCKETS_FROM_USER_WITHOUT_CACHE(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const io = await this.io.runJob("IO", {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const io = await IOModule.runJob("IO", {}, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(resolve => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const ns = io.of("/"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -414,15 +432,21 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * @returns {Promise} - returns promise (reject, resolve) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	async SOCKET_LEAVE_ROOMS(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const socket = await this.runJob("SOCKET_FROM_SESSION", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			socketId: payload.socketId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const socket = await UtilsModule.runJob( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			"SOCKET_FROM_SESSION", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				socketId: payload.socketId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(resolve => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const { rooms } = socket; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			for (let room = 0, roomKeys = Object.keys(rooms); room < roomKeys.length; room += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Object.keys(rooms).forEach(roomKey => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const room = rooms[roomKey]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				socket.leave(room); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		}); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -437,15 +461,20 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * @returns {Promise} - returns promise (reject, resolve) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	async SOCKET_JOIN_ROOM(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const socket = await this.runJob("SOCKET_FROM_SESSION", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			socketId: payload.socketId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const socket = await UtilsModule.runJob( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			"SOCKET_FROM_SESSION", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				socketId: payload.socketId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(resolve => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const { rooms } = socket; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			for (let room = 0, roomKeys = Object.keys(rooms); room < roomKeys.length; room += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Object.keys(rooms).forEach(roomKey => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const room = rooms[roomKey]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				socket.leave(room); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			socket.join(payload.room); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -457,15 +486,20 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// eslint-disable-next-line require-jsdoc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	async SOCKET_JOIN_SONG_ROOM(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// socketId, room 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const socket = await this.runJob("SOCKET_FROM_SESSION", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			socketId: payload.socketId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const socket = await UtilsModule.runJob( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			"SOCKET_FROM_SESSION", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				socketId: payload.socketId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(resolve => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const { rooms } = socket; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			for (let room = 0, roomKeys = Object.keys(rooms); room < roomKeys.length; room += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (room.indexOf("song.") !== -1) socket.leave(rooms); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Object.keys(rooms).forEach(roomKey => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const room = rooms[roomKey]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if (room.indexOf("song.") !== -1) socket.leave(room); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			socket.join(payload.room); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -478,16 +512,17 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	SOCKETS_JOIN_SONG_ROOM(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// sockets, room 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(resolve => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			for (let id = 0, socketKeys = Object.keys(payload.sockets); id < socketKeys.length; id += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const socket = payload.sockets[socketKeys[id]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Object.keys(payload.sockets).forEach(socketKey => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const socket = payload.sockets[socketKey]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const { rooms } = socket; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				for (let room = 0, roomKeys = Object.keys(rooms); room < roomKeys.length; room += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Object.keys(rooms).forEach(roomKey => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					const room = rooms[roomKey]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					if (room.indexOf("song.") !== -1) socket.leave(room); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				socket.join(payload.room); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		}); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -498,13 +533,14 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	SOCKETS_LEAVE_SONG_ROOMS(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// sockets 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(resolve => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			for (let id = 0, socketKeys = Object.keys(payload.sockets); id < socketKeys.length; id += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const socket = payload.sockets[socketKeys[id]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Object.keys(payload.sockets).forEach(socketKey => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const socket = payload.sockets[socketKey]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const { rooms } = socket; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				for (let room = 0, roomKeys = Object.keys(rooms); room < roomKeys.length; room += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Object.keys(rooms).forEach(roomKey => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					const room = rooms[roomKey]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					if (room.indexOf("song.") !== -1) socket.leave(room); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -518,16 +554,16 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * @returns {Promise} - returns promise (reject, resolve) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	async EMIT_TO_ROOM(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const io = await this.io.runJob("IO", {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const io = await IOModule.runJob("IO", {}, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(resolve => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const { sockets } = io.sockets; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			for (let id = 0, socketKeys = Object.keys(sockets); id < socketKeys.length; id += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const socket = sockets[socketKeys[id]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Object.keys(sockets).forEach(socketKey => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const socket = sockets[socketKey]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if (socket.rooms[payload.room]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					socket.emit(...payload.args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		}); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -541,15 +577,15 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * @returns {Promise} - returns promise (reject, resolve) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	async GET_ROOM_SOCKETS(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const io = await this.io.runJob("IO", {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const io = await IOModule.runJob("IO", {}, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(resolve => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const { sockets } = io.sockets; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const roomSockets = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			for (let id = 0, socketKeys = Object.keys(sockets); id < socketKeys.length; id += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const socket = sockets[socketKeys[id]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Object.keys(sockets).forEach(socketKey => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const socket = sockets[socketKey]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if (socket.rooms[payload.room]) roomSockets.push(socket); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return resolve(roomSockets); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		}); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -565,9 +601,9 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	GET_SONG_FROM_YOUTUBE(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// songId, cb 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise((resolve, reject) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			this.youtubeRequestCallbacks.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			UtilsModule.youtubeRequestCallbacks.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				cb: () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					this.youtubeRequestsActive = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					UtilsModule.youtubeRequestsActive = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					const youtubeParams = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						"part=snippet,contentDetails,statistics,status", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						`id=${encodeURIComponent(payload.songId)}`, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -575,10 +611,10 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					].join("&"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					request(`https://www.googleapis.com/youtube/v3/videos?${youtubeParams}`, (err, res, body) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						this.youtubeRequestCallbacks.splice(0, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						if (this.youtubeRequestCallbacks.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							this.youtubeRequestCallbacks[0].cb(this.youtubeRequestCallbacks[0].songId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} else this.youtubeRequestsActive = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						UtilsModule.youtubeRequestCallbacks.splice(0, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						if (UtilsModule.youtubeRequestCallbacks.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							UtilsModule.youtubeRequestCallbacks[0].cb(UtilsModule.youtubeRequestCallbacks[0].songId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						} else UtilsModule.youtubeRequestsActive = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						if (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							console.error(err); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -635,8 +671,8 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				songId: payload.songId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (!this.youtubeRequestsActive) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				this.youtubeRequestCallbacks[0].cb(this.youtubeRequestCallbacks[0].songId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (!UtilsModule.youtubeRequestsActive) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				UtilsModule.youtubeRequestCallbacks[0].cb(UtilsModule.youtubeRequestCallbacks[0].songId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -763,9 +799,13 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						if (!payload.musicOnly) return resolve({ songs }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						return local 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							.runJob("FILTER_MUSIC_VIDEOS_YOUTUBE", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-								videoIds: songs.slice() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							.runJob( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								"FILTER_MUSIC_VIDEOS_YOUTUBE", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									videoIds: songs.slice() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							.then(filteredSongs => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								resolve({ filteredSongs, songs }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							}); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -777,119 +817,6 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 * Gets the details of a song from the Spotify API 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 * @param {object} payload - object that contains the payload 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 * @param {object} payload.song - the song object (song.title etc.) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 * @returns {Promise} - returns promise (reject, resolve) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	async GET_SONG_FROM_SPOTIFY(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// song 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const token = await this.spotify.runJob("GET_TOKEN", {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return new Promise((resolve, reject) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (!config.get("apis.spotify.enabled")) return reject(new Error("Spotify is not enabled.")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const song = { ...payload.song }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const spotifyParams = [`q=${encodeURIComponent(payload.song.title)}`, `type=track`].join("&"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const options = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				url: `https://api.spotify.com/v1/search?${spotifyParams}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				headers: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					Authorization: `Bearer ${token}` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return request(options, (err, res, body) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (err) console.error(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				body = JSON.parse(body); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (body.error) console.error(body.error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				for (let i = 0, bodyKeys = Object.keys(body); i < bodyKeys.length; i += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const { items } = body[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					for (let j = 0, itemKeys = Object.keys(body); j < itemKeys.length; j += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						const item = items[j]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						let hasArtist = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						for (let k = 0; k < item.artists.length; k += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							const artist = item.artists[k]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							if (song.title.indexOf(artist.name) !== -1) hasArtist = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						if (hasArtist && song.title.indexOf(item.name) !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							song.duration = item.duration_ms / 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							song.artists = item.artists.map(artist => artist.name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							song.title = item.name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							song.explicit = item.explicit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							song.thumbnail = item.album.images[1].url; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				resolve({ song }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 * Returns the details of multiple songs from the Spotify API 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 * @param {object} payload - object that contains the payload 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 * @param {object} payload.title - the query/title of a song to search the API with 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 * @returns {Promise} - returns promise (reject, resolve) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	async GET_SONGS_FROM_SPOTIFY(payload) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		// title, artist 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		const token = await this.spotify.runJob("GET_TOKEN", {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return new Promise((resolve, reject) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (!config.get("apis.spotify.enabled")) return reject(new Error("Spotify is not enabled.")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const spotifyParams = [`q=${encodeURIComponent(payload.title)}`, `type=track`].join("&"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			const options = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				url: `https://api.spotify.com/v1/search?${spotifyParams}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				headers: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					Authorization: `Bearer ${token}` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			return request(options, (err, res, body) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (err) return console.error(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				body = JSON.parse(body); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (body.error) return console.error(body.error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const songs = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				for (let i = 0, bodyKeys = Object.keys(body); i < bodyKeys.length; i += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					const { items } = body[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					for (let j = 0, itemKeys = Object.keys(body); j < itemKeys.length; j += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						const item = items[j]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						let hasArtist = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						for (let k = 0; k < item.artists.length; k += 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							const localArtist = item.artists[k]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							if (payload.artist.toLowerCase() === localArtist.name.toLowerCase()) hasArtist = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						if ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							hasArtist && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							(payload.title.indexOf(item.name) !== -1 || item.name.indexOf(payload.title) !== -1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							const song = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							song.duration = item.duration_ms / 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							song.artists = item.artists.map(artist => artist.name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							song.title = item.name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							song.explicit = item.explicit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							song.thumbnail = item.album.images[1].url; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-							songs.push(song); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				return resolve({ songs }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * Shuffles an array of songs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -966,4 +893,4 @@ class UtilsModule extends CoreClass { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-export default new UtilsModule(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+export default new _UtilsModule(); 
			 |