diff --git a/discord.11.1.0.js b/discord.11.1.0.js
new file mode 100644
index 00000000..1328a3cb
--- /dev/null
+++ b/discord.11.1.0.js
@@ -0,0 +1,26790 @@
+/******/ (function(modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/
+/******/ // Check if module is in cache
+/******/ if(installedModules[moduleId]) {
+/******/ return installedModules[moduleId].exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ i: moduleId,
+/******/ l: false,
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ // Flag the module as loaded
+/******/ module.l = true;
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/******/
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __webpack_require__.m = modules;
+/******/
+/******/ // expose the module cache
+/******/ __webpack_require__.c = installedModules;
+/******/
+/******/ // identity function for calling harmony imports with the correct context
+/******/ __webpack_require__.i = function(value) { return value; };
+/******/
+/******/ // define getter function for harmony exports
+/******/ __webpack_require__.d = function(exports, name, getter) {
+/******/ if(!__webpack_require__.o(exports, name)) {
+/******/ Object.defineProperty(exports, name, {
+/******/ configurable: false,
+/******/ enumerable: true,
+/******/ get: getter
+/******/ });
+/******/ }
+/******/ };
+/******/
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __webpack_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function getDefault() { return module['default']; } :
+/******/ function getModuleExports() { return module; };
+/******/ __webpack_require__.d(getter, 'a', getter);
+/******/ return getter;
+/******/ };
+/******/
+/******/ // Object.prototype.hasOwnProperty.call
+/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ // __webpack_public_path__
+/******/ __webpack_require__.p = "";
+/******/
+/******/ // Load entry module and return exports
+/******/ return __webpack_require__(__webpack_require__.s = 181);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(process) {exports.Package = __webpack_require__(41);
+
+/**
+ * Options for a client.
+ * @typedef {Object} ClientOptions
+ * @property {string} [apiRequestMethod='sequential'] One of `sequential` or `burst`. The sequential handler executes
+ * all requests in the order they are triggered, whereas the burst handler runs multiple in parallel, and doesn't
+ * provide the guarantee of any particular order. Burst mode is more likely to hit a 429 ratelimit error by its nature,
+ * and is therefore slightly riskier to use.
+ * @property {number} [shardId=0] ID of the shard to run
+ * @property {number} [shardCount=0] Total number of shards
+ * @property {number} [messageCacheMaxSize=200] Maximum number of messages to cache per channel
+ * (-1 or Infinity for unlimited - don't do this without message sweeping, otherwise memory usage will climb
+ * indefinitely)
+ * @property {number} [messageCacheLifetime=0] How long a message should stay in the cache until it is considered
+ * sweepable (in seconds, 0 for forever)
+ * @property {number} [messageSweepInterval=0] How frequently to remove messages from the cache that are older than
+ * the message cache lifetime (in seconds, 0 for never)
+ * @property {boolean} [fetchAllMembers=false] Whether to cache all guild members and users upon startup, as well as
+ * upon joining a guild (should be avoided whenever possible)
+ * @property {boolean} [disableEveryone=false] Default value for {@link MessageOptions#disableEveryone}
+ * @property {boolean} [sync=false] Whether to periodically sync guilds (for user accounts)
+ * @property {number} [restWsBridgeTimeout=5000] Maximum time permitted between REST responses and their
+ * corresponding websocket events
+ * @property {number} [restTimeOffset=500] Extra time in millseconds to wait before continuing to make REST
+ * requests (higher values will reduce rate-limiting errors on bad connections)
+ * @property {WSEventType[]} [disabledEvents] An array of disabled websocket events. Events in this array will not be
+ * processed, potentially resulting in performance improvements for larger bots. Only disable events you are
+ * 100% certain you don't need, as many are important, but not obviously so. The safest one to disable with the
+ * most impact is typically `TYPING_START`.
+ * @property {WebsocketOptions} [ws] Options for the WebSocket
+ */
+exports.DefaultOptions = {
+ apiRequestMethod: 'sequential',
+ shardId: 0,
+ shardCount: 0,
+ messageCacheMaxSize: 200,
+ messageCacheLifetime: 0,
+ messageSweepInterval: 0,
+ fetchAllMembers: false,
+ disableEveryone: false,
+ sync: false,
+ restWsBridgeTimeout: 5000,
+ disabledEvents: [],
+ restTimeOffset: 500,
+
+ /**
+ * WebSocket options (these are left as snake_case to match the API)
+ * @typedef {Object} WebsocketOptions
+ * @property {number} [large_threshold=250] Number of members in a guild to be considered large
+ * @property {boolean} [compress=true] Whether to compress data sent on the connection
+ * (defaults to `false` for browsers)
+ */
+ ws: {
+ large_threshold: 250,
+ compress: __webpack_require__(24).platform() !== 'browser',
+ properties: {
+ $os: process ? process.platform : 'discord.js',
+ $browser: 'discord.js',
+ $device: 'discord.js',
+ $referrer: '',
+ $referring_domain: '',
+ },
+ version: 6,
+ },
+ http: {
+ version: 7,
+ host: 'https://discordapp.com',
+ cdn: 'https://cdn.discordapp.com',
+ },
+};
+
+exports.WSCodes = {
+ 1000: 'Connection gracefully closed',
+ 4004: 'Tried to identify with an invalid token',
+ 4010: 'Sharding data provided was invalid',
+ 4011: 'Shard would be on too many guilds if connected',
+};
+
+exports.Errors = {
+ NO_TOKEN: 'Request to use token, but token was unavailable to the client.',
+ NO_BOT_ACCOUNT: 'Only bot accounts are able to make use of this feature.',
+ NO_USER_ACCOUNT: 'Only user accounts are able to make use of this feature.',
+ BAD_WS_MESSAGE: 'A bad message was received from the websocket; either bad compression, or not JSON.',
+ TOOK_TOO_LONG: 'Something took too long to do.',
+ NOT_A_PERMISSION: 'Invalid permission string or number.',
+ INVALID_RATE_LIMIT_METHOD: 'Unknown rate limiting method.',
+ BAD_LOGIN: 'Incorrect login details were provided.',
+ INVALID_SHARD: 'Invalid shard settings were provided.',
+ SHARDING_REQUIRED: 'This session would have handled too many guilds - Sharding is required.',
+ INVALID_TOKEN: 'An invalid token was provided.',
+};
+
+const Endpoints = exports.Endpoints = {
+ User: userID => {
+ if (userID.id) userID = userID.id;
+ const base = `/users/${userID}`;
+ return {
+ toString: () => base,
+ channels: `${base}/channels`,
+ profile: `${base}/profile`,
+ relationships: `${base}/relationships`,
+ settings: `${base}/settings`,
+ Relationship: uID => `${base}/relationships/${uID}`,
+ Guild: guildID => `${base}/guilds/${guildID}`,
+ Note: id => `${base}/notes/${id}`,
+ Mentions: (limit, roles, everyone, guildID) =>
+ `${base}/mentions?limit=${limit}&roles=${roles}&everyone=${everyone}${guildID ? `&guild_id=${guildID}` : ''}`,
+ Avatar: (root, hash) => {
+ if (userID === '1') return hash;
+ return Endpoints.CDN(root).Avatar(userID, hash);
+ },
+ };
+ },
+ guilds: '/guilds',
+ Guild: guildID => {
+ if (guildID.id) guildID = guildID.id;
+ const base = `/guilds/${guildID}`;
+ return {
+ toString: () => base,
+ prune: `${base}/prune`,
+ embed: `${base}/embed`,
+ bans: `${base}/bans`,
+ integrations: `${base}/integrations`,
+ members: `${base}/members`,
+ channels: `${base}/channels`,
+ invites: `${base}/invites`,
+ roles: `${base}/roles`,
+ emojis: `${base}/emojis`,
+ search: `${base}/messages/search`,
+ voiceRegions: `${base}/regions`,
+ webhooks: `${base}/webhooks`,
+ ack: `${base}/ack`,
+ settings: `${base}/settings`,
+ auditLogs: `${base}/audit-logs`,
+ Emoji: emojiID => Endpoints.CDN(root).Emoji(emojiID),
+ Icon: (root, hash) => Endpoints.CDN(root).Icon(guildID, hash),
+ Splash: (root, hash) => Endpoints.CDN(root).Splash(guildID, hash),
+ Role: roleID => `${base}/roles/${roleID}`,
+ Member: memberID => {
+ if (memberID.id) memberID = memberID.id;
+ const mbase = `${base}/members/${memberID}`;
+ return {
+ toString: () => mbase,
+ Role: roleID => `${mbase}/roles/${roleID}`,
+ nickname: `${base}/members/@me/nick`,
+ };
+ },
+ };
+ },
+ channels: '/channels',
+ Channel: channelID => {
+ if (channelID.id) channelID = channelID.id;
+ const base = `/channels/${channelID}`;
+ return {
+ toString: () => base,
+ messages: {
+ toString: () => `${base}/messages`,
+ bulkDelete: `${base}/messages/bulk-delete`,
+ },
+ invites: `${base}/invites`,
+ typing: `${base}/typing`,
+ permissions: `${base}/permissions`,
+ webhooks: `${base}/webhooks`,
+ search: `${base}/messages/search`,
+ pins: `${base}/pins`,
+ Pin: messageID => `${base}/pins/${messageID}`,
+ Recipient: recipientID => `${base}/recipients/${recipientID}`,
+ Message: messageID => {
+ if (messageID.id) messageID = messageID.id;
+ const mbase = `${base}/messages/${messageID}`;
+ return {
+ toString: () => mbase,
+ reactions: `${mbase}/reactions`,
+ ack: `${mbase}/ack`,
+ Reaction: (emoji, limit) => {
+ const rbase = `${mbase}/reactions/${emoji}${limit ? `?limit=${limit}` : ''}`;
+ return {
+ toString: () => rbase,
+ User: userID => `${rbase}/${userID}`,
+ };
+ },
+ };
+ },
+ };
+ },
+ Message: m => exports.Endpoints.Channel(m.channel).Message(m),
+ Member: m => exports.Endpoints.Guild(m.guild).Member(m),
+ CDN(root) {
+ return {
+ Emoji: emojiID => `${root}/emojis/${emojiID}.png`,
+ Asset: name => `${root}/assets/${name}`,
+ Avatar: (userID, hash) => `${root}/avatars/${userID}/${hash}.${hash.startsWith('a_') ? 'gif' : 'png'}?size=2048`,
+ Icon: (guildID, hash) => `${root}/icons/${guildID}/${hash}.jpg`,
+ Splash: (guildID, hash) => `${root}/splashes/${guildID}/${hash}.jpg`,
+ };
+ },
+ OAUTH2: {
+ Application: appID => {
+ const base = `/oauth2/applications/${appID}`;
+ return {
+ toString: () => base,
+ reset: `${base}/reset`,
+ };
+ },
+ App: appID => `/oauth2/authorize?client_id=${appID}`,
+ },
+ login: '/auth/login',
+ logout: '/auth/logout',
+ voiceRegions: '/voice/regions',
+ gateway: {
+ toString: () => '/gateway',
+ bot: '/gateway/bot',
+ },
+ Invite: inviteID => `/invite/${inviteID}`,
+ inviteLink: id => `https://discord.gg/${id}`,
+ Webhook: (webhookID, token) => `/webhooks/${webhookID}${token ? `/${token}` : ''}`,
+};
+
+
+/**
+ * The current status of the client. Here are the available statuses:
+ * - READY
+ * - CONNECTING
+ * - RECONNECTING
+ * - IDLE
+ * - NEARLY
+ * - DISCONNECTED
+ * @typedef {number} Status
+ */
+exports.Status = {
+ READY: 0,
+ CONNECTING: 1,
+ RECONNECTING: 2,
+ IDLE: 3,
+ NEARLY: 4,
+ DISCONNECTED: 5,
+};
+
+/**
+ * The current status of a voice connection. Here are the available statuses:
+ * - CONNECTED
+ * - CONNECTING
+ * - AUTHENTICATING
+ * - RECONNECTING
+ * - DISCONNECTED
+ * @typedef {number} VoiceStatus
+ */
+exports.VoiceStatus = {
+ CONNECTED: 0,
+ CONNECTING: 1,
+ AUTHENTICATING: 2,
+ RECONNECTING: 3,
+ DISCONNECTED: 4,
+};
+
+exports.ChannelTypes = {
+ TEXT: 0,
+ DM: 1,
+ VOICE: 2,
+ GROUP_DM: 3,
+};
+
+exports.OPCodes = {
+ DISPATCH: 0,
+ HEARTBEAT: 1,
+ IDENTIFY: 2,
+ STATUS_UPDATE: 3,
+ VOICE_STATE_UPDATE: 4,
+ VOICE_GUILD_PING: 5,
+ RESUME: 6,
+ RECONNECT: 7,
+ REQUEST_GUILD_MEMBERS: 8,
+ INVALID_SESSION: 9,
+ HELLO: 10,
+ HEARTBEAT_ACK: 11,
+};
+
+exports.VoiceOPCodes = {
+ IDENTIFY: 0,
+ SELECT_PROTOCOL: 1,
+ READY: 2,
+ HEARTBEAT: 3,
+ SESSION_DESCRIPTION: 4,
+ SPEAKING: 5,
+};
+
+exports.Events = {
+ READY: 'ready',
+ GUILD_CREATE: 'guildCreate',
+ GUILD_DELETE: 'guildDelete',
+ GUILD_UPDATE: 'guildUpdate',
+ GUILD_UNAVAILABLE: 'guildUnavailable',
+ GUILD_AVAILABLE: 'guildAvailable',
+ GUILD_MEMBER_ADD: 'guildMemberAdd',
+ GUILD_MEMBER_REMOVE: 'guildMemberRemove',
+ GUILD_MEMBER_UPDATE: 'guildMemberUpdate',
+ GUILD_MEMBER_AVAILABLE: 'guildMemberAvailable',
+ GUILD_MEMBER_SPEAKING: 'guildMemberSpeaking',
+ GUILD_MEMBERS_CHUNK: 'guildMembersChunk',
+ GUILD_ROLE_CREATE: 'roleCreate',
+ GUILD_ROLE_DELETE: 'roleDelete',
+ GUILD_ROLE_UPDATE: 'roleUpdate',
+ GUILD_EMOJI_CREATE: 'emojiCreate',
+ GUILD_EMOJI_DELETE: 'emojiDelete',
+ GUILD_EMOJI_UPDATE: 'emojiUpdate',
+ GUILD_BAN_ADD: 'guildBanAdd',
+ GUILD_BAN_REMOVE: 'guildBanRemove',
+ CHANNEL_CREATE: 'channelCreate',
+ CHANNEL_DELETE: 'channelDelete',
+ CHANNEL_UPDATE: 'channelUpdate',
+ CHANNEL_PINS_UPDATE: 'channelPinsUpdate',
+ MESSAGE_CREATE: 'message',
+ MESSAGE_DELETE: 'messageDelete',
+ MESSAGE_UPDATE: 'messageUpdate',
+ MESSAGE_BULK_DELETE: 'messageDeleteBulk',
+ MESSAGE_REACTION_ADD: 'messageReactionAdd',
+ MESSAGE_REACTION_REMOVE: 'messageReactionRemove',
+ MESSAGE_REACTION_REMOVE_ALL: 'messageReactionRemoveAll',
+ USER_UPDATE: 'userUpdate',
+ USER_NOTE_UPDATE: 'userNoteUpdate',
+ USER_SETTINGS_UPDATE: 'clientUserSettingsUpdate',
+ PRESENCE_UPDATE: 'presenceUpdate',
+ VOICE_STATE_UPDATE: 'voiceStateUpdate',
+ TYPING_START: 'typingStart',
+ TYPING_STOP: 'typingStop',
+ DISCONNECT: 'disconnect',
+ RECONNECTING: 'reconnecting',
+ ERROR: 'error',
+ WARN: 'warn',
+ DEBUG: 'debug',
+};
+
+/**
+ * The type of a websocket message event, e.g. `MESSAGE_CREATE`. Here are the available events:
+ * - READY
+ * - RESUMED
+ * - GUILD_SYNC
+ * - GUILD_CREATE
+ * - GUILD_DELETE
+ * - GUILD_UPDATE
+ * - GUILD_MEMBER_ADD
+ * - GUILD_MEMBER_REMOVE
+ * - GUILD_MEMBER_UPDATE
+ * - GUILD_MEMBERS_CHUNK
+ * - GUILD_ROLE_CREATE
+ * - GUILD_ROLE_DELETE
+ * - GUILD_ROLE_UPDATE
+ * - GUILD_BAN_ADD
+ * - GUILD_BAN_REMOVE
+ * - CHANNEL_CREATE
+ * - CHANNEL_DELETE
+ * - CHANNEL_UPDATE
+ * - CHANNEL_PINS_UPDATE
+ * - MESSAGE_CREATE
+ * - MESSAGE_DELETE
+ * - MESSAGE_UPDATE
+ * - MESSAGE_DELETE_BULK
+ * - MESSAGE_REACTION_ADD
+ * - MESSAGE_REACTION_REMOVE
+ * - MESSAGE_REACTION_REMOVE_ALL
+ * - USER_UPDATE
+ * - USER_NOTE_UPDATE
+ * - USER_SETTINGS_UPDATE
+ * - PRESENCE_UPDATE
+ * - VOICE_STATE_UPDATE
+ * - TYPING_START
+ * - VOICE_SERVER_UPDATE
+ * - RELATIONSHIP_ADD
+ * - RELATIONSHIP_REMOVE
+ * @typedef {string} WSEventType
+ */
+exports.WSEvents = {
+ READY: 'READY',
+ RESUMED: 'RESUMED',
+ GUILD_SYNC: 'GUILD_SYNC',
+ GUILD_CREATE: 'GUILD_CREATE',
+ GUILD_DELETE: 'GUILD_DELETE',
+ GUILD_UPDATE: 'GUILD_UPDATE',
+ GUILD_MEMBER_ADD: 'GUILD_MEMBER_ADD',
+ GUILD_MEMBER_REMOVE: 'GUILD_MEMBER_REMOVE',
+ GUILD_MEMBER_UPDATE: 'GUILD_MEMBER_UPDATE',
+ GUILD_MEMBERS_CHUNK: 'GUILD_MEMBERS_CHUNK',
+ GUILD_ROLE_CREATE: 'GUILD_ROLE_CREATE',
+ GUILD_ROLE_DELETE: 'GUILD_ROLE_DELETE',
+ GUILD_ROLE_UPDATE: 'GUILD_ROLE_UPDATE',
+ GUILD_BAN_ADD: 'GUILD_BAN_ADD',
+ GUILD_BAN_REMOVE: 'GUILD_BAN_REMOVE',
+ GUILD_EMOJIS_UPDATE: 'GUILD_EMOJIS_UPDATE',
+ CHANNEL_CREATE: 'CHANNEL_CREATE',
+ CHANNEL_DELETE: 'CHANNEL_DELETE',
+ CHANNEL_UPDATE: 'CHANNEL_UPDATE',
+ CHANNEL_PINS_UPDATE: 'CHANNEL_PINS_UPDATE',
+ MESSAGE_CREATE: 'MESSAGE_CREATE',
+ MESSAGE_DELETE: 'MESSAGE_DELETE',
+ MESSAGE_UPDATE: 'MESSAGE_UPDATE',
+ MESSAGE_DELETE_BULK: 'MESSAGE_DELETE_BULK',
+ MESSAGE_REACTION_ADD: 'MESSAGE_REACTION_ADD',
+ MESSAGE_REACTION_REMOVE: 'MESSAGE_REACTION_REMOVE',
+ MESSAGE_REACTION_REMOVE_ALL: 'MESSAGE_REACTION_REMOVE_ALL',
+ USER_UPDATE: 'USER_UPDATE',
+ USER_NOTE_UPDATE: 'USER_NOTE_UPDATE',
+ USER_SETTINGS_UPDATE: 'USER_SETTINGS_UPDATE',
+ PRESENCE_UPDATE: 'PRESENCE_UPDATE',
+ VOICE_STATE_UPDATE: 'VOICE_STATE_UPDATE',
+ TYPING_START: 'TYPING_START',
+ VOICE_SERVER_UPDATE: 'VOICE_SERVER_UPDATE',
+ RELATIONSHIP_ADD: 'RELATIONSHIP_ADD',
+ RELATIONSHIP_REMOVE: 'RELATIONSHIP_REMOVE',
+};
+
+exports.MessageTypes = [
+ 'DEFAULT',
+ 'RECIPIENT_ADD',
+ 'RECIPIENT_REMOVE',
+ 'CALL',
+ 'CHANNEL_NAME_CHANGE',
+ 'CHANNEL_ICON_CHANGE',
+ 'PINS_ADD',
+ 'GUILD_MEMBER_JOIN',
+];
+
+exports.DefaultAvatars = {
+ BLURPLE: '6debd47ed13483642cf09e832ed0bc1b',
+ GREY: '322c936a8c8be1b803cd94861bdfa868',
+ GREEN: 'dd4dbc0016779df1378e7812eabaa04d',
+ ORANGE: '0e291f67c9274a1abdddeb3fd919cbaa',
+ RED: '1cbd08c76f8af6dddce02c5138971129',
+};
+
+exports.ExplicitContentFilterTypes = [
+ 'DISABLED',
+ 'NON_FRIENDS',
+ 'FRIENDS_AND_NON_FRIENDS',
+];
+
+exports.UserSettingsMap = {
+ /**
+ * Automatically convert emoticons in your messages to emoji
+ * For example, when you type `:-)` Discord will convert it to 😃
+ * @name ClientUserSettings#convertEmoticons
+ * @type {boolean}
+ */
+ convert_emoticons: 'convertEmoticons',
+
+ /**
+ * If new guilds should automatically disable DMs between you and its members
+ * @name ClientUserSettings#defaultGuildsRestricted
+ * @type {boolean}
+ */
+ default_guilds_restricted: 'defaultGuildsRestricted',
+
+ /**
+ * Automatically detect accounts from services like Steam and Blizzard when you open the Discord client
+ * @name ClientUserSettings#detectPlatformAccounts
+ * @type {boolean}
+ */
+ detect_platform_accounts: 'detectPlatformAccounts',
+
+ /**
+ * Developer Mode exposes context menu items helpful for people writing bots using the Discord API
+ * @name ClientUserSettings#developerMode
+ * @type {boolean}
+ */
+ developer_mode: 'developerMode',
+
+ /**
+ * Allow playback and usage of the `/tts` command
+ * @name ClientUserSettings#enableTTSCommand
+ * @type {boolean}
+ */
+ enable_tts_command: 'enableTTSCommand',
+
+ /**
+ * The theme of the client. Either `light` or `dark`
+ * @name ClientUserSettings#theme
+ * @type {string}
+ */
+ theme: 'theme',
+
+ /**
+ * Last status set in the client
+ * @name ClientUserSettings#status
+ * @type {PresenceStatus}
+ */
+ status: 'status',
+
+ /**
+ * Display currently running game as status message
+ * @name ClientUserSettings#showCurrentGame
+ * @type {boolean}
+ */
+ show_current_game: 'showCurrentGame',
+
+ /**
+ * Display images, videos, and lolcats when uploaded directly to Discord
+ * @name ClientUserSettings#inlineAttachmentMedia
+ * @type {boolean}
+ */
+ inline_attachment_media: 'inlineAttachmentMedia',
+
+ /**
+ * Display images, videos, and lolcats when uploaded posted as links in chat
+ * @name ClientUserSettings#inlineEmbedMedia
+ * @type {boolean}
+ */
+ inline_embed_media: 'inlineEmbedMedia',
+
+ /**
+ * Language the Discord client will use, as an RFC 3066 language identifier
+ * @name ClientUserSettings#locale
+ * @type {string}
+ */
+ locale: 'locale',
+
+ /**
+ * Display messages in compact mode
+ * @name ClientUserSettings#messageDisplayCompact
+ * @type {boolean}
+ */
+ message_display_compact: 'messageDisplayCompact',
+
+ /**
+ * Show emoji reactions on messages
+ * @name ClientUserSettings#renderReactions
+ * @type {boolean}
+ */
+ render_reactions: 'renderReactions',
+
+ /**
+ * Array of snowflake IDs for guilds, in the order they appear in the Discord client
+ * @name ClientUserSettings#guildPositions
+ * @type {Snowflake[]}
+ */
+ guild_positions: 'guildPositions',
+
+ /**
+ * Array of snowflake IDs for guilds which you will not recieve DMs from
+ * @name ClientUserSettings#restrictedGuilds
+ * @type {Snowflake[]}
+ */
+ restricted_guilds: 'restrictedGuilds',
+
+ explicit_content_filter: function explicitContentFilter(type) { // eslint-disable-line func-name-matching
+ /**
+ * Safe direct messaging; force people's messages with images to be scanned before they are sent to you
+ * one of `DISABLED`, `NON_FRIENDS`, `FRIENDS_AND_NON_FRIENDS`
+ * @name ClientUserSettings#explicitContentFilter
+ * @type {string}
+ */
+ return exports.ExplicitContentFilterTypes[type];
+ },
+ friend_source_flags: function friendSources(flags) { // eslint-disable-line func-name-matching
+ /**
+ * Who can add you as a friend
+ * @name ClientUserSettings#friendSources
+ * @type {Object}
+ * @property {boolean} all Mutual friends and mutual guilds
+ * @property {boolean} mutualGuilds Only mutual guilds
+ * @property {boolean} mutualFriends Only mutual friends
+ */
+ return {
+ all: flags.all || false,
+ mutualGuilds: flags.all ? true : flags.mutual_guilds || false,
+ mutualFriends: flags.all ? true : flags.mutualFriends || false,
+ };
+ },
+};
+
+exports.Colors = {
+ DEFAULT: 0x000000,
+ AQUA: 0x1ABC9C,
+ GREEN: 0x2ECC71,
+ BLUE: 0x3498DB,
+ PURPLE: 0x9B59B6,
+ GOLD: 0xF1C40F,
+ ORANGE: 0xE67E22,
+ RED: 0xE74C3C,
+ GREY: 0x95A5A6,
+ NAVY: 0x34495E,
+ DARK_AQUA: 0x11806A,
+ DARK_GREEN: 0x1F8B4C,
+ DARK_BLUE: 0x206694,
+ DARK_PURPLE: 0x71368A,
+ DARK_GOLD: 0xC27C0E,
+ DARK_ORANGE: 0xA84300,
+ DARK_RED: 0x992D22,
+ DARK_GREY: 0x979C9F,
+ DARKER_GREY: 0x7F8C8D,
+ LIGHT_GREY: 0xBCC0C0,
+ DARK_NAVY: 0x2C3E50,
+ BLURPLE: 0x7289DA,
+ GREYPLE: 0x99AAB5,
+ DARK_BUT_NOT_BLACK: 0x2C2F33,
+ NOT_QUITE_BLACK: 0x23272A,
+};
+
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6)))
+
+/***/ }),
+/* 1 */
+/***/ (function(module, exports) {
+
+class AbstractHandler {
+ constructor(packetManager) {
+ this.packetManager = packetManager;
+ }
+
+ handle(packet) {
+ return packet;
+ }
+}
+
+module.exports = AbstractHandler;
+
+
+/***/ }),
+/* 2 */
+/***/ (function(module, exports) {
+
+/*
+
+ABOUT ACTIONS
+
+Actions are similar to WebSocket Packet Handlers, but since introducing
+the REST API methods, in order to prevent rewriting code to handle data,
+"actions" have been introduced. They're basically what Packet Handlers
+used to be but they're strictly for manipulating data and making sure
+that WebSocket events don't clash with REST methods.
+
+*/
+
+class GenericAction {
+ constructor(client) {
+ this.client = client;
+ }
+
+ handle(data) {
+ return data;
+ }
+}
+
+module.exports = GenericAction;
+
+
+/***/ }),
+/* 3 */
+/***/ (function(module, exports) {
+
+/**
+ * A Map with additional utility methods. This is used throughout discord.js rather than Arrays for anything that has
+ * an ID, for significantly improved performance and ease-of-use.
+ * @extends {Map}
+ */
+class Collection extends Map {
+ constructor(iterable) {
+ super(iterable);
+
+ /**
+ * Cached array for the `array()` method - will be reset to `null` whenever `set()` or `delete()` are called
+ * @name Collection#_array
+ * @type {?Array}
+ * @private
+ */
+ Object.defineProperty(this, '_array', { value: null, writable: true, configurable: true });
+
+ /**
+ * Cached array for the `keyArray()` method - will be reset to `null` whenever `set()` or `delete()` are called
+ * @name Collection#_keyArray
+ * @type {?Array}
+ * @private
+ */
+ Object.defineProperty(this, '_keyArray', { value: null, writable: true, configurable: true });
+ }
+
+ set(key, val) {
+ this._array = null;
+ this._keyArray = null;
+ return super.set(key, val);
+ }
+
+ delete(key) {
+ this._array = null;
+ this._keyArray = null;
+ return super.delete(key);
+ }
+
+ /**
+ * Creates an ordered array of the values of this collection, and caches it internally. The array will only be
+ * reconstructed if an item is added to or removed from the collection, or if you change the length of the array
+ * itself. If you don't want this caching behaviour, use `Array.from(collection.values())` instead.
+ * @returns {Array}
+ */
+ array() {
+ if (!this._array || this._array.length !== this.size) this._array = Array.from(this.values());
+ return this._array;
+ }
+
+ /**
+ * Creates an ordered array of the keys of this collection, and caches it internally. The array will only be
+ * reconstructed if an item is added to or removed from the collection, or if you change the length of the array
+ * itself. If you don't want this caching behaviour, use `Array.from(collection.keys())` instead.
+ * @returns {Array}
+ */
+ keyArray() {
+ if (!this._keyArray || this._keyArray.length !== this.size) this._keyArray = Array.from(this.keys());
+ return this._keyArray;
+ }
+
+ /**
+ * Obtains the first item in this collection.
+ * @returns {*}
+ */
+ first() {
+ return this.values().next().value;
+ }
+
+ /**
+ * Obtains the first key in this collection.
+ * @returns {*}
+ */
+ firstKey() {
+ return this.keys().next().value;
+ }
+
+ /**
+ * Obtains the last item in this collection. This relies on the `array()` method, and thus the caching mechanism
+ * applies here as well.
+ * @returns {*}
+ */
+ last() {
+ const arr = this.array();
+ return arr[arr.length - 1];
+ }
+
+ /**
+ * Obtains the last key in this collection. This relies on the `keyArray()` method, and thus the caching mechanism
+ * applies here as well.
+ * @returns {*}
+ */
+ lastKey() {
+ const arr = this.keyArray();
+ return arr[arr.length - 1];
+ }
+
+ /**
+ * Obtains a random item from this collection. This relies on the `array()` method, and thus the caching mechanism
+ * applies here as well.
+ * @returns {*}
+ */
+ random() {
+ const arr = this.array();
+ return arr[Math.floor(Math.random() * arr.length)];
+ }
+
+ /**
+ * Obtains a random key from this collection. This relies on the `keyArray()` method, and thus the caching mechanism
+ * applies here as well.
+ * @returns {*}
+ */
+ randomKey() {
+ const arr = this.keyArray();
+ return arr[Math.floor(Math.random() * arr.length)];
+ }
+
+ /**
+ * Searches for all items where their specified property's value is identical to the given value
+ * (`item[prop] === value`).
+ * @param {string} prop The property to test against
+ * @param {*} value The expected value
+ * @returns {Array}
+ * @example
+ * collection.findAll('username', 'Bob');
+ */
+ findAll(prop, value) {
+ if (typeof prop !== 'string') throw new TypeError('Key must be a string.');
+ if (typeof value === 'undefined') throw new Error('Value must be specified.');
+ const results = [];
+ for (const item of this.values()) {
+ if (item[prop] === value) results.push(item);
+ }
+ return results;
+ }
+
+ /**
+ * Searches for a single item where its specified property's value is identical to the given value
+ * (`item[prop] === value`), or the given function returns a truthy value. In the latter case, this is identical to
+ * [Array.find()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find).
+ * All collections used in Discord.js are mapped using their `id` property, and if you want to find by id you
+ * should use the `get` method. See
+ * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) for details.
+ * @param {string|Function} propOrFn The property to test against, or the function to test with
+ * @param {*} [value] The expected value - only applicable and required if using a property for the first argument
+ * @returns {*}
+ * @example
+ * collection.find('username', 'Bob');
+ * @example
+ * collection.find(val => val.username === 'Bob');
+ */
+ find(propOrFn, value) {
+ if (typeof propOrFn === 'string') {
+ if (typeof value === 'undefined') throw new Error('Value must be specified.');
+ for (const item of this.values()) {
+ if (item[propOrFn] === value) return item;
+ }
+ return null;
+ } else if (typeof propOrFn === 'function') {
+ for (const [key, val] of this) {
+ if (propOrFn(val, key, this)) return val;
+ }
+ return null;
+ } else {
+ throw new Error('First argument must be a property string or a function.');
+ }
+ }
+
+ /* eslint-disable max-len */
+ /**
+ * Searches for the key of a single item where its specified property's value is identical to the given value
+ * (`item[prop] === value`), or the given function returns a truthy value. In the latter case, this is identical to
+ * [Array.findIndex()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex).
+ * @param {string|Function} propOrFn The property to test against, or the function to test with
+ * @param {*} [value] The expected value - only applicable and required if using a property for the first argument
+ * @returns {*}
+ * @example
+ * collection.findKey('username', 'Bob');
+ * @example
+ * collection.findKey(val => val.username === 'Bob');
+ */
+ /* eslint-enable max-len */
+ findKey(propOrFn, value) {
+ if (typeof propOrFn === 'string') {
+ if (typeof value === 'undefined') throw new Error('Value must be specified.');
+ for (const [key, val] of this) {
+ if (val[propOrFn] === value) return key;
+ }
+ return null;
+ } else if (typeof propOrFn === 'function') {
+ for (const [key, val] of this) {
+ if (propOrFn(val, key, this)) return key;
+ }
+ return null;
+ } else {
+ throw new Error('First argument must be a property string or a function.');
+ }
+ }
+
+ /**
+ * Searches for the existence of a single item where its specified property's value is identical to the given value
+ * (`item[prop] === value`).
+ * Do not use this to check for an item by its ID. Instead, use `collection.has(id)`. See
+ * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) for details.
+ * @param {string} prop The property to test against
+ * @param {*} value The expected value
+ * @returns {boolean}
+ * @example
+ * if (collection.exists('username', 'Bob')) {
+ * console.log('user here!');
+ * }
+ */
+ exists(prop, value) {
+ return Boolean(this.find(prop, value));
+ }
+
+ /**
+ * Identical to
+ * [Array.filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter),
+ * but returns a Collection instead of an Array.
+ * @param {Function} fn Function used to test (should return a boolean)
+ * @param {Object} [thisArg] Value to use as `this` when executing function
+ * @returns {Collection}
+ */
+ filter(fn, thisArg) {
+ if (thisArg) fn = fn.bind(thisArg);
+ const results = new Collection();
+ for (const [key, val] of this) {
+ if (fn(val, key, this)) results.set(key, val);
+ }
+ return results;
+ }
+
+ /**
+ * Identical to
+ * [Array.filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter).
+ * @param {Function} fn Function used to test (should return a boolean)
+ * @param {Object} [thisArg] Value to use as `this` when executing function
+ * @returns {Array}
+ */
+ filterArray(fn, thisArg) {
+ if (thisArg) fn = fn.bind(thisArg);
+ const results = [];
+ for (const [key, val] of this) {
+ if (fn(val, key, this)) results.push(val);
+ }
+ return results;
+ }
+
+ /**
+ * Identical to
+ * [Array.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map).
+ * @param {Function} fn Function that produces an element of the new array, taking three arguments
+ * @param {*} [thisArg] Value to use as `this` when executing function
+ * @returns {Array}
+ */
+ map(fn, thisArg) {
+ if (thisArg) fn = fn.bind(thisArg);
+ const arr = new Array(this.size);
+ let i = 0;
+ for (const [key, val] of this) arr[i++] = fn(val, key, this);
+ return arr;
+ }
+
+ /**
+ * Identical to
+ * [Array.some()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some).
+ * @param {Function} fn Function used to test (should return a boolean)
+ * @param {Object} [thisArg] Value to use as `this` when executing function
+ * @returns {boolean}
+ */
+ some(fn, thisArg) {
+ if (thisArg) fn = fn.bind(thisArg);
+ for (const [key, val] of this) {
+ if (fn(val, key, this)) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Identical to
+ * [Array.every()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every).
+ * @param {Function} fn Function used to test (should return a boolean)
+ * @param {Object} [thisArg] Value to use as `this` when executing function
+ * @returns {boolean}
+ */
+ every(fn, thisArg) {
+ if (thisArg) fn = fn.bind(thisArg);
+ for (const [key, val] of this) {
+ if (!fn(val, key, this)) return false;
+ }
+ return true;
+ }
+
+ /**
+ * Identical to
+ * [Array.reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce).
+ * @param {Function} fn Function used to reduce, taking four arguments; `accumulator`, `currentValue`, `currentKey`,
+ * and `collection`
+ * @param {*} [initialValue] Starting value for the accumulator
+ * @returns {*}
+ */
+ reduce(fn, initialValue) {
+ let accumulator;
+ if (typeof initialValue !== 'undefined') {
+ accumulator = initialValue;
+ for (const [key, val] of this) accumulator = fn(accumulator, val, key, this);
+ } else {
+ let first = true;
+ for (const [key, val] of this) {
+ if (first) {
+ accumulator = val;
+ first = false;
+ continue;
+ }
+ accumulator = fn(accumulator, val, key, this);
+ }
+ }
+ return accumulator;
+ }
+
+ /**
+ * Creates an identical shallow copy of this collection.
+ * @returns {Collection}
+ * @example const newColl = someColl.clone();
+ */
+ clone() {
+ return new this.constructor(this);
+ }
+
+ /**
+ * Combines this collection with others into a new collection. None of the source collections are modified.
+ * @param {...Collection} collections Collections to merge
+ * @returns {Collection}
+ * @example const newColl = someColl.concat(someOtherColl, anotherColl, ohBoyAColl);
+ */
+ concat(...collections) {
+ const newColl = this.clone();
+ for (const coll of collections) {
+ for (const [key, val] of coll) newColl.set(key, val);
+ }
+ return newColl;
+ }
+
+ /**
+ * Calls the `delete()` method on all items that have it.
+ * @returns {Promise[]}
+ */
+ deleteAll() {
+ const returns = [];
+ for (const item of this.values()) {
+ if (item.delete) returns.push(item.delete());
+ }
+ return returns;
+ }
+
+ /**
+ * Checks if this collection shares identical key-value pairings with another.
+ * This is different to checking for equality using equal-signs, because
+ * the collections may be different objects, but contain the same data.
+ * @param {Collection} collection Collection to compare with
+ * @returns {boolean} Whether the collections have identical contents
+ */
+ equals(collection) {
+ if (!collection) return false;
+ if (this === collection) return true;
+ if (this.size !== collection.size) return false;
+ return !this.find((value, key) => {
+ const testVal = collection.get(key);
+ return testVal !== value || (testVal === undefined && !collection.has(key));
+ });
+ }
+
+ /**
+ * The sort() method sorts the elements of a collection in place and returns the collection.
+ * The sort is not necessarily stable. The default sort order is according to string Unicode code points.
+ * @param {Function} [compareFunction] Specifies a function that defines the sort order.
+ * if omitted, the collection is sorted according to each character's Unicode code point value,
+ * according to the string conversion of each element.
+ * @returns {Collection}
+ */
+ sort(compareFunction = (x, y) => +(x > y) || +(x === y) - 1) {
+ return new Collection(Array.from(this.entries()).sort((a, b) => compareFunction(a[1], b[1], a[0], b[0])));
+ }
+}
+
+module.exports = Collection;
+
+
+/***/ }),
+/* 4 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(Buffer) {const snekfetch = __webpack_require__(39);
+const Constants = __webpack_require__(0);
+const ConstantsHttp = Constants.DefaultOptions.http;
+
+/**
+ * Contains various general-purpose utility methods. These functions are also available on the base `Discord` object.
+ */
+class Util {
+ constructor() {
+ throw new Error(`The ${this.constructor.name} class may not be instantiated.`);
+ }
+
+ /**
+ * Splits a string into multiple chunks at a designated character that do not exceed a specific length.
+ * @param {string} text Content to split
+ * @param {SplitOptions} [options] Options controlling the behaviour of the split
+ * @returns {string|string[]}
+ */
+ static splitMessage(text, { maxLength = 1950, char = '\n', prepend = '', append = '' } = {}) {
+ if (text.length <= maxLength) return text;
+ const splitText = text.split(char);
+ if (splitText.length === 1) throw new Error('Message exceeds the max length and contains no split characters.');
+ const messages = [''];
+ let msg = 0;
+ for (let i = 0; i < splitText.length; i++) {
+ if (messages[msg].length + splitText[i].length + 1 > maxLength) {
+ messages[msg] += append;
+ messages.push(prepend);
+ msg++;
+ }
+ messages[msg] += (messages[msg].length > 0 && messages[msg] !== prepend ? char : '') + splitText[i];
+ }
+ return messages;
+ }
+
+ /**
+ * Escapes any Discord-flavour markdown in a string.
+ * @param {string} text Content to escape
+ * @param {boolean} [onlyCodeBlock=false] Whether to only escape codeblocks (takes priority)
+ * @param {boolean} [onlyInlineCode=false] Whether to only escape inline code
+ * @returns {string}
+ */
+ static escapeMarkdown(text, onlyCodeBlock = false, onlyInlineCode = false) {
+ if (onlyCodeBlock) return text.replace(/```/g, '`\u200b``');
+ if (onlyInlineCode) return text.replace(/\\(`|\\)/g, '$1').replace(/(`|\\)/g, '\\$1');
+ return text.replace(/\\(\*|_|`|~|\\)/g, '$1').replace(/(\*|_|`|~|\\)/g, '\\$1');
+ }
+
+ /**
+ * Gets the recommended shard count from Discord.
+ * @param {string} token Discord auth token
+ * @param {number} [guildsPerShard=1000] Number of guilds per shard
+ * @returns {Promise} The recommended number of shards
+ */
+ static fetchRecommendedShards(token, guildsPerShard = 1000) {
+ return new Promise((resolve, reject) => {
+ if (!token) throw new Error('A token must be provided.');
+ snekfetch.get(`${ConstantsHttp.host}/api/v${ConstantsHttp.version}${Constants.Endpoints.gateway.bot}`)
+ .set('Authorization', `Bot ${token.replace(/^Bot\s*/i, '')}`)
+ .end((err, res) => {
+ if (err) reject(err);
+ resolve(res.body.shards * (1000 / guildsPerShard));
+ });
+ });
+ }
+
+ /**
+ * Parses emoji info out of a string. The string must be one of:
+ * - A UTF-8 emoji (no ID)
+ * - A URL-encoded UTF-8 emoji (no ID)
+ * - A Discord custom emoji (`<:name:id>`)
+ * @param {string} text Emoji string to parse
+ * @returns {Object} Object with `name` and `id` properties
+ * @private
+ */
+ static parseEmoji(text) {
+ if (text.includes('%')) text = decodeURIComponent(text);
+ if (text.includes(':')) {
+ const [name, id] = text.split(':');
+ return { name, id };
+ } else {
+ return {
+ name: text,
+ id: null,
+ };
+ }
+ }
+
+ /**
+ * Checks whether the arrays are equal, also removes duplicated entries from b.
+ * @param {Array<*>} a Array which will not be modified.
+ * @param {Array<*>} b Array to remove duplicated entries from.
+ * @returns {boolean} Whether the arrays are equal.
+ * @private
+ */
+ static arraysEqual(a, b) {
+ if (a === b) return true;
+ if (a.length !== b.length) return false;
+
+ for (const item of a) {
+ const ind = b.indexOf(item);
+ if (ind !== -1) b.splice(ind, 1);
+ }
+
+ return b.length === 0;
+ }
+
+ /**
+ * Shallow-copies an object with its class/prototype intact.
+ * @param {Object} obj Object to clone
+ * @returns {Object}
+ * @private
+ */
+ static cloneObject(obj) {
+ return Object.assign(Object.create(obj), obj);
+ }
+
+ /**
+ * Sets default properties on an object that aren't already specified.
+ * @param {Object} def Default properties
+ * @param {Object} given Object to assign defaults to
+ * @returns {Object}
+ * @private
+ */
+ static mergeDefault(def, given) {
+ if (!given) return def;
+ for (const key in def) {
+ if (!{}.hasOwnProperty.call(given, key)) {
+ given[key] = def[key];
+ } else if (given[key] === Object(given[key])) {
+ given[key] = this.mergeDefault(def[key], given[key]);
+ }
+ }
+
+ return given;
+ }
+
+ /**
+ * Converts an ArrayBuffer or string to a Buffer.
+ * @param {ArrayBuffer|string} ab ArrayBuffer to convert
+ * @returns {Buffer}
+ * @private
+ */
+ static convertToBuffer(ab) {
+ if (typeof ab === 'string') ab = this.str2ab(ab);
+ return Buffer.from(ab);
+ }
+
+ /**
+ * Converts a string to an ArrayBuffer.
+ * @param {string} str String to convert
+ * @returns {ArrayBuffer}
+ * @private
+ */
+ static str2ab(str) {
+ const buffer = new ArrayBuffer(str.length * 2);
+ const view = new Uint16Array(buffer);
+ for (var i = 0, strLen = str.length; i < strLen; i++) view[i] = str.charCodeAt(i);
+ return buffer;
+ }
+
+ /**
+ * Makes an Error from a plain info object.
+ * @param {Object} obj Error info
+ * @param {string} obj.name Error type
+ * @param {string} obj.message Message for the error
+ * @param {string} obj.stack Stack for the error
+ * @returns {Error}
+ * @private
+ */
+ static makeError(obj) {
+ const err = new Error(obj.message);
+ err.name = obj.name;
+ err.stack = obj.stack;
+ return err;
+ }
+
+ /**
+ * Makes a plain error info object from an Error.
+ * @param {Error} err Error to get info from
+ * @returns {Object}
+ * @private
+ */
+ static makePlainError(err) {
+ const obj = {};
+ obj.name = err.name;
+ obj.message = err.message;
+ obj.stack = err.stack;
+ return obj;
+ }
+
+ /**
+ * Moves an element in an array *in place*.
+ * @param {Array<*>} array Array to modify
+ * @param {*} element Element to move
+ * @param {number} newIndex Index or offset to move the element to
+ * @param {boolean} [offset=false] Move the element by an offset amount rather than to a set index
+ * @returns {number}
+ * @private
+ */
+ static moveElementInArray(array, element, newIndex, offset = false) {
+ const index = array.indexOf(element);
+ newIndex = (offset ? index : 0) + newIndex;
+ if (newIndex > -1 && newIndex < array.length) {
+ const removedElement = array.splice(index, 1)[0];
+ array.splice(newIndex, 0, removedElement);
+ }
+ return array.indexOf(element);
+ }
+}
+
+module.exports = Util;
+
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer))
+
+/***/ }),
+/* 5 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(global) {/*!
+ * The buffer module from node.js, for the browser.
+ *
+ * @author Feross Aboukhadijeh
+ * @license MIT
+ */
+/* eslint-disable no-proto */
+
+
+
+var base64 = __webpack_require__(77)
+var ieee754 = __webpack_require__(80)
+var isArray = __webpack_require__(58)
+
+exports.Buffer = Buffer
+exports.SlowBuffer = SlowBuffer
+exports.INSPECT_MAX_BYTES = 50
+
+/**
+ * If `Buffer.TYPED_ARRAY_SUPPORT`:
+ * === true Use Uint8Array implementation (fastest)
+ * === false Use Object implementation (most compatible, even IE6)
+ *
+ * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
+ * Opera 11.6+, iOS 4.2+.
+ *
+ * Due to various browser bugs, sometimes the Object implementation will be used even
+ * when the browser supports typed arrays.
+ *
+ * Note:
+ *
+ * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
+ * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
+ *
+ * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
+ *
+ * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
+ * incorrect length in some situations.
+
+ * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
+ * get the Object implementation, which is slower but behaves correctly.
+ */
+Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
+ ? global.TYPED_ARRAY_SUPPORT
+ : typedArraySupport()
+
+/*
+ * Export kMaxLength after typed array support is determined.
+ */
+exports.kMaxLength = kMaxLength()
+
+function typedArraySupport () {
+ try {
+ var arr = new Uint8Array(1)
+ arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
+ return arr.foo() === 42 && // typed array instances can be augmented
+ typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
+ arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
+ } catch (e) {
+ return false
+ }
+}
+
+function kMaxLength () {
+ return Buffer.TYPED_ARRAY_SUPPORT
+ ? 0x7fffffff
+ : 0x3fffffff
+}
+
+function createBuffer (that, length) {
+ if (kMaxLength() < length) {
+ throw new RangeError('Invalid typed array length')
+ }
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ // Return an augmented `Uint8Array` instance, for best performance
+ that = new Uint8Array(length)
+ that.__proto__ = Buffer.prototype
+ } else {
+ // Fallback: Return an object instance of the Buffer class
+ if (that === null) {
+ that = new Buffer(length)
+ }
+ that.length = length
+ }
+
+ return that
+}
+
+/**
+ * The Buffer constructor returns instances of `Uint8Array` that have their
+ * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
+ * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
+ * and the `Uint8Array` methods. Square bracket notation works as expected -- it
+ * returns a single octet.
+ *
+ * The `Uint8Array` prototype remains unmodified.
+ */
+
+function Buffer (arg, encodingOrOffset, length) {
+ if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
+ return new Buffer(arg, encodingOrOffset, length)
+ }
+
+ // Common case.
+ if (typeof arg === 'number') {
+ if (typeof encodingOrOffset === 'string') {
+ throw new Error(
+ 'If encoding is specified then the first argument must be a string'
+ )
+ }
+ return allocUnsafe(this, arg)
+ }
+ return from(this, arg, encodingOrOffset, length)
+}
+
+Buffer.poolSize = 8192 // not used by this implementation
+
+// TODO: Legacy, not needed anymore. Remove in next major version.
+Buffer._augment = function (arr) {
+ arr.__proto__ = Buffer.prototype
+ return arr
+}
+
+function from (that, value, encodingOrOffset, length) {
+ if (typeof value === 'number') {
+ throw new TypeError('"value" argument must not be a number')
+ }
+
+ if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
+ return fromArrayBuffer(that, value, encodingOrOffset, length)
+ }
+
+ if (typeof value === 'string') {
+ return fromString(that, value, encodingOrOffset)
+ }
+
+ return fromObject(that, value)
+}
+
+/**
+ * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
+ * if value is a number.
+ * Buffer.from(str[, encoding])
+ * Buffer.from(array)
+ * Buffer.from(buffer)
+ * Buffer.from(arrayBuffer[, byteOffset[, length]])
+ **/
+Buffer.from = function (value, encodingOrOffset, length) {
+ return from(null, value, encodingOrOffset, length)
+}
+
+if (Buffer.TYPED_ARRAY_SUPPORT) {
+ Buffer.prototype.__proto__ = Uint8Array.prototype
+ Buffer.__proto__ = Uint8Array
+ if (typeof Symbol !== 'undefined' && Symbol.species &&
+ Buffer[Symbol.species] === Buffer) {
+ // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
+ Object.defineProperty(Buffer, Symbol.species, {
+ value: null,
+ configurable: true
+ })
+ }
+}
+
+function assertSize (size) {
+ if (typeof size !== 'number') {
+ throw new TypeError('"size" argument must be a number')
+ } else if (size < 0) {
+ throw new RangeError('"size" argument must not be negative')
+ }
+}
+
+function alloc (that, size, fill, encoding) {
+ assertSize(size)
+ if (size <= 0) {
+ return createBuffer(that, size)
+ }
+ if (fill !== undefined) {
+ // Only pay attention to encoding if it's a string. This
+ // prevents accidentally sending in a number that would
+ // be interpretted as a start offset.
+ return typeof encoding === 'string'
+ ? createBuffer(that, size).fill(fill, encoding)
+ : createBuffer(that, size).fill(fill)
+ }
+ return createBuffer(that, size)
+}
+
+/**
+ * Creates a new filled Buffer instance.
+ * alloc(size[, fill[, encoding]])
+ **/
+Buffer.alloc = function (size, fill, encoding) {
+ return alloc(null, size, fill, encoding)
+}
+
+function allocUnsafe (that, size) {
+ assertSize(size)
+ that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
+ if (!Buffer.TYPED_ARRAY_SUPPORT) {
+ for (var i = 0; i < size; ++i) {
+ that[i] = 0
+ }
+ }
+ return that
+}
+
+/**
+ * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
+ * */
+Buffer.allocUnsafe = function (size) {
+ return allocUnsafe(null, size)
+}
+/**
+ * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
+ */
+Buffer.allocUnsafeSlow = function (size) {
+ return allocUnsafe(null, size)
+}
+
+function fromString (that, string, encoding) {
+ if (typeof encoding !== 'string' || encoding === '') {
+ encoding = 'utf8'
+ }
+
+ if (!Buffer.isEncoding(encoding)) {
+ throw new TypeError('"encoding" must be a valid string encoding')
+ }
+
+ var length = byteLength(string, encoding) | 0
+ that = createBuffer(that, length)
+
+ var actual = that.write(string, encoding)
+
+ if (actual !== length) {
+ // Writing a hex string, for example, that contains invalid characters will
+ // cause everything after the first invalid character to be ignored. (e.g.
+ // 'abxxcd' will be treated as 'ab')
+ that = that.slice(0, actual)
+ }
+
+ return that
+}
+
+function fromArrayLike (that, array) {
+ var length = array.length < 0 ? 0 : checked(array.length) | 0
+ that = createBuffer(that, length)
+ for (var i = 0; i < length; i += 1) {
+ that[i] = array[i] & 255
+ }
+ return that
+}
+
+function fromArrayBuffer (that, array, byteOffset, length) {
+ array.byteLength // this throws if `array` is not a valid ArrayBuffer
+
+ if (byteOffset < 0 || array.byteLength < byteOffset) {
+ throw new RangeError('\'offset\' is out of bounds')
+ }
+
+ if (array.byteLength < byteOffset + (length || 0)) {
+ throw new RangeError('\'length\' is out of bounds')
+ }
+
+ if (byteOffset === undefined && length === undefined) {
+ array = new Uint8Array(array)
+ } else if (length === undefined) {
+ array = new Uint8Array(array, byteOffset)
+ } else {
+ array = new Uint8Array(array, byteOffset, length)
+ }
+
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ // Return an augmented `Uint8Array` instance, for best performance
+ that = array
+ that.__proto__ = Buffer.prototype
+ } else {
+ // Fallback: Return an object instance of the Buffer class
+ that = fromArrayLike(that, array)
+ }
+ return that
+}
+
+function fromObject (that, obj) {
+ if (Buffer.isBuffer(obj)) {
+ var len = checked(obj.length) | 0
+ that = createBuffer(that, len)
+
+ if (that.length === 0) {
+ return that
+ }
+
+ obj.copy(that, 0, 0, len)
+ return that
+ }
+
+ if (obj) {
+ if ((typeof ArrayBuffer !== 'undefined' &&
+ obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
+ if (typeof obj.length !== 'number' || isnan(obj.length)) {
+ return createBuffer(that, 0)
+ }
+ return fromArrayLike(that, obj)
+ }
+
+ if (obj.type === 'Buffer' && isArray(obj.data)) {
+ return fromArrayLike(that, obj.data)
+ }
+ }
+
+ throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
+}
+
+function checked (length) {
+ // Note: cannot use `length < kMaxLength()` here because that fails when
+ // length is NaN (which is otherwise coerced to zero.)
+ if (length >= kMaxLength()) {
+ throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
+ 'size: 0x' + kMaxLength().toString(16) + ' bytes')
+ }
+ return length | 0
+}
+
+function SlowBuffer (length) {
+ if (+length != length) { // eslint-disable-line eqeqeq
+ length = 0
+ }
+ return Buffer.alloc(+length)
+}
+
+Buffer.isBuffer = function isBuffer (b) {
+ return !!(b != null && b._isBuffer)
+}
+
+Buffer.compare = function compare (a, b) {
+ if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
+ throw new TypeError('Arguments must be Buffers')
+ }
+
+ if (a === b) return 0
+
+ var x = a.length
+ var y = b.length
+
+ for (var i = 0, len = Math.min(x, y); i < len; ++i) {
+ if (a[i] !== b[i]) {
+ x = a[i]
+ y = b[i]
+ break
+ }
+ }
+
+ if (x < y) return -1
+ if (y < x) return 1
+ return 0
+}
+
+Buffer.isEncoding = function isEncoding (encoding) {
+ switch (String(encoding).toLowerCase()) {
+ case 'hex':
+ case 'utf8':
+ case 'utf-8':
+ case 'ascii':
+ case 'latin1':
+ case 'binary':
+ case 'base64':
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return true
+ default:
+ return false
+ }
+}
+
+Buffer.concat = function concat (list, length) {
+ if (!isArray(list)) {
+ throw new TypeError('"list" argument must be an Array of Buffers')
+ }
+
+ if (list.length === 0) {
+ return Buffer.alloc(0)
+ }
+
+ var i
+ if (length === undefined) {
+ length = 0
+ for (i = 0; i < list.length; ++i) {
+ length += list[i].length
+ }
+ }
+
+ var buffer = Buffer.allocUnsafe(length)
+ var pos = 0
+ for (i = 0; i < list.length; ++i) {
+ var buf = list[i]
+ if (!Buffer.isBuffer(buf)) {
+ throw new TypeError('"list" argument must be an Array of Buffers')
+ }
+ buf.copy(buffer, pos)
+ pos += buf.length
+ }
+ return buffer
+}
+
+function byteLength (string, encoding) {
+ if (Buffer.isBuffer(string)) {
+ return string.length
+ }
+ if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
+ (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
+ return string.byteLength
+ }
+ if (typeof string !== 'string') {
+ string = '' + string
+ }
+
+ var len = string.length
+ if (len === 0) return 0
+
+ // Use a for loop to avoid recursion
+ var loweredCase = false
+ for (;;) {
+ switch (encoding) {
+ case 'ascii':
+ case 'latin1':
+ case 'binary':
+ return len
+ case 'utf8':
+ case 'utf-8':
+ case undefined:
+ return utf8ToBytes(string).length
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return len * 2
+ case 'hex':
+ return len >>> 1
+ case 'base64':
+ return base64ToBytes(string).length
+ default:
+ if (loweredCase) return utf8ToBytes(string).length // assume utf8
+ encoding = ('' + encoding).toLowerCase()
+ loweredCase = true
+ }
+ }
+}
+Buffer.byteLength = byteLength
+
+function slowToString (encoding, start, end) {
+ var loweredCase = false
+
+ // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
+ // property of a typed array.
+
+ // This behaves neither like String nor Uint8Array in that we set start/end
+ // to their upper/lower bounds if the value passed is out of range.
+ // undefined is handled specially as per ECMA-262 6th Edition,
+ // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
+ if (start === undefined || start < 0) {
+ start = 0
+ }
+ // Return early if start > this.length. Done here to prevent potential uint32
+ // coercion fail below.
+ if (start > this.length) {
+ return ''
+ }
+
+ if (end === undefined || end > this.length) {
+ end = this.length
+ }
+
+ if (end <= 0) {
+ return ''
+ }
+
+ // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
+ end >>>= 0
+ start >>>= 0
+
+ if (end <= start) {
+ return ''
+ }
+
+ if (!encoding) encoding = 'utf8'
+
+ while (true) {
+ switch (encoding) {
+ case 'hex':
+ return hexSlice(this, start, end)
+
+ case 'utf8':
+ case 'utf-8':
+ return utf8Slice(this, start, end)
+
+ case 'ascii':
+ return asciiSlice(this, start, end)
+
+ case 'latin1':
+ case 'binary':
+ return latin1Slice(this, start, end)
+
+ case 'base64':
+ return base64Slice(this, start, end)
+
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return utf16leSlice(this, start, end)
+
+ default:
+ if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+ encoding = (encoding + '').toLowerCase()
+ loweredCase = true
+ }
+ }
+}
+
+// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
+// Buffer instances.
+Buffer.prototype._isBuffer = true
+
+function swap (b, n, m) {
+ var i = b[n]
+ b[n] = b[m]
+ b[m] = i
+}
+
+Buffer.prototype.swap16 = function swap16 () {
+ var len = this.length
+ if (len % 2 !== 0) {
+ throw new RangeError('Buffer size must be a multiple of 16-bits')
+ }
+ for (var i = 0; i < len; i += 2) {
+ swap(this, i, i + 1)
+ }
+ return this
+}
+
+Buffer.prototype.swap32 = function swap32 () {
+ var len = this.length
+ if (len % 4 !== 0) {
+ throw new RangeError('Buffer size must be a multiple of 32-bits')
+ }
+ for (var i = 0; i < len; i += 4) {
+ swap(this, i, i + 3)
+ swap(this, i + 1, i + 2)
+ }
+ return this
+}
+
+Buffer.prototype.swap64 = function swap64 () {
+ var len = this.length
+ if (len % 8 !== 0) {
+ throw new RangeError('Buffer size must be a multiple of 64-bits')
+ }
+ for (var i = 0; i < len; i += 8) {
+ swap(this, i, i + 7)
+ swap(this, i + 1, i + 6)
+ swap(this, i + 2, i + 5)
+ swap(this, i + 3, i + 4)
+ }
+ return this
+}
+
+Buffer.prototype.toString = function toString () {
+ var length = this.length | 0
+ if (length === 0) return ''
+ if (arguments.length === 0) return utf8Slice(this, 0, length)
+ return slowToString.apply(this, arguments)
+}
+
+Buffer.prototype.equals = function equals (b) {
+ if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+ if (this === b) return true
+ return Buffer.compare(this, b) === 0
+}
+
+Buffer.prototype.inspect = function inspect () {
+ var str = ''
+ var max = exports.INSPECT_MAX_BYTES
+ if (this.length > 0) {
+ str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
+ if (this.length > max) str += ' ... '
+ }
+ return ''
+}
+
+Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
+ if (!Buffer.isBuffer(target)) {
+ throw new TypeError('Argument must be a Buffer')
+ }
+
+ if (start === undefined) {
+ start = 0
+ }
+ if (end === undefined) {
+ end = target ? target.length : 0
+ }
+ if (thisStart === undefined) {
+ thisStart = 0
+ }
+ if (thisEnd === undefined) {
+ thisEnd = this.length
+ }
+
+ if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
+ throw new RangeError('out of range index')
+ }
+
+ if (thisStart >= thisEnd && start >= end) {
+ return 0
+ }
+ if (thisStart >= thisEnd) {
+ return -1
+ }
+ if (start >= end) {
+ return 1
+ }
+
+ start >>>= 0
+ end >>>= 0
+ thisStart >>>= 0
+ thisEnd >>>= 0
+
+ if (this === target) return 0
+
+ var x = thisEnd - thisStart
+ var y = end - start
+ var len = Math.min(x, y)
+
+ var thisCopy = this.slice(thisStart, thisEnd)
+ var targetCopy = target.slice(start, end)
+
+ for (var i = 0; i < len; ++i) {
+ if (thisCopy[i] !== targetCopy[i]) {
+ x = thisCopy[i]
+ y = targetCopy[i]
+ break
+ }
+ }
+
+ if (x < y) return -1
+ if (y < x) return 1
+ return 0
+}
+
+// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
+// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
+//
+// Arguments:
+// - buffer - a Buffer to search
+// - val - a string, Buffer, or number
+// - byteOffset - an index into `buffer`; will be clamped to an int32
+// - encoding - an optional encoding, relevant is val is a string
+// - dir - true for indexOf, false for lastIndexOf
+function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
+ // Empty buffer means no match
+ if (buffer.length === 0) return -1
+
+ // Normalize byteOffset
+ if (typeof byteOffset === 'string') {
+ encoding = byteOffset
+ byteOffset = 0
+ } else if (byteOffset > 0x7fffffff) {
+ byteOffset = 0x7fffffff
+ } else if (byteOffset < -0x80000000) {
+ byteOffset = -0x80000000
+ }
+ byteOffset = +byteOffset // Coerce to Number.
+ if (isNaN(byteOffset)) {
+ // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
+ byteOffset = dir ? 0 : (buffer.length - 1)
+ }
+
+ // Normalize byteOffset: negative offsets start from the end of the buffer
+ if (byteOffset < 0) byteOffset = buffer.length + byteOffset
+ if (byteOffset >= buffer.length) {
+ if (dir) return -1
+ else byteOffset = buffer.length - 1
+ } else if (byteOffset < 0) {
+ if (dir) byteOffset = 0
+ else return -1
+ }
+
+ // Normalize val
+ if (typeof val === 'string') {
+ val = Buffer.from(val, encoding)
+ }
+
+ // Finally, search either indexOf (if dir is true) or lastIndexOf
+ if (Buffer.isBuffer(val)) {
+ // Special case: looking for empty string/buffer always fails
+ if (val.length === 0) {
+ return -1
+ }
+ return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
+ } else if (typeof val === 'number') {
+ val = val & 0xFF // Search for a byte value [0-255]
+ if (Buffer.TYPED_ARRAY_SUPPORT &&
+ typeof Uint8Array.prototype.indexOf === 'function') {
+ if (dir) {
+ return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
+ } else {
+ return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
+ }
+ }
+ return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
+ }
+
+ throw new TypeError('val must be string, number or Buffer')
+}
+
+function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
+ var indexSize = 1
+ var arrLength = arr.length
+ var valLength = val.length
+
+ if (encoding !== undefined) {
+ encoding = String(encoding).toLowerCase()
+ if (encoding === 'ucs2' || encoding === 'ucs-2' ||
+ encoding === 'utf16le' || encoding === 'utf-16le') {
+ if (arr.length < 2 || val.length < 2) {
+ return -1
+ }
+ indexSize = 2
+ arrLength /= 2
+ valLength /= 2
+ byteOffset /= 2
+ }
+ }
+
+ function read (buf, i) {
+ if (indexSize === 1) {
+ return buf[i]
+ } else {
+ return buf.readUInt16BE(i * indexSize)
+ }
+ }
+
+ var i
+ if (dir) {
+ var foundIndex = -1
+ for (i = byteOffset; i < arrLength; i++) {
+ if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
+ if (foundIndex === -1) foundIndex = i
+ if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
+ } else {
+ if (foundIndex !== -1) i -= i - foundIndex
+ foundIndex = -1
+ }
+ }
+ } else {
+ if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
+ for (i = byteOffset; i >= 0; i--) {
+ var found = true
+ for (var j = 0; j < valLength; j++) {
+ if (read(arr, i + j) !== read(val, j)) {
+ found = false
+ break
+ }
+ }
+ if (found) return i
+ }
+ }
+
+ return -1
+}
+
+Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
+ return this.indexOf(val, byteOffset, encoding) !== -1
+}
+
+Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
+ return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
+}
+
+Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
+ return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
+}
+
+function hexWrite (buf, string, offset, length) {
+ offset = Number(offset) || 0
+ var remaining = buf.length - offset
+ if (!length) {
+ length = remaining
+ } else {
+ length = Number(length)
+ if (length > remaining) {
+ length = remaining
+ }
+ }
+
+ // must be an even number of digits
+ var strLen = string.length
+ if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
+
+ if (length > strLen / 2) {
+ length = strLen / 2
+ }
+ for (var i = 0; i < length; ++i) {
+ var parsed = parseInt(string.substr(i * 2, 2), 16)
+ if (isNaN(parsed)) return i
+ buf[offset + i] = parsed
+ }
+ return i
+}
+
+function utf8Write (buf, string, offset, length) {
+ return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+function asciiWrite (buf, string, offset, length) {
+ return blitBuffer(asciiToBytes(string), buf, offset, length)
+}
+
+function latin1Write (buf, string, offset, length) {
+ return asciiWrite(buf, string, offset, length)
+}
+
+function base64Write (buf, string, offset, length) {
+ return blitBuffer(base64ToBytes(string), buf, offset, length)
+}
+
+function ucs2Write (buf, string, offset, length) {
+ return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+Buffer.prototype.write = function write (string, offset, length, encoding) {
+ // Buffer#write(string)
+ if (offset === undefined) {
+ encoding = 'utf8'
+ length = this.length
+ offset = 0
+ // Buffer#write(string, encoding)
+ } else if (length === undefined && typeof offset === 'string') {
+ encoding = offset
+ length = this.length
+ offset = 0
+ // Buffer#write(string, offset[, length][, encoding])
+ } else if (isFinite(offset)) {
+ offset = offset | 0
+ if (isFinite(length)) {
+ length = length | 0
+ if (encoding === undefined) encoding = 'utf8'
+ } else {
+ encoding = length
+ length = undefined
+ }
+ // legacy write(string, encoding, offset, length) - remove in v0.13
+ } else {
+ throw new Error(
+ 'Buffer.write(string, encoding, offset[, length]) is no longer supported'
+ )
+ }
+
+ var remaining = this.length - offset
+ if (length === undefined || length > remaining) length = remaining
+
+ if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
+ throw new RangeError('Attempt to write outside buffer bounds')
+ }
+
+ if (!encoding) encoding = 'utf8'
+
+ var loweredCase = false
+ for (;;) {
+ switch (encoding) {
+ case 'hex':
+ return hexWrite(this, string, offset, length)
+
+ case 'utf8':
+ case 'utf-8':
+ return utf8Write(this, string, offset, length)
+
+ case 'ascii':
+ return asciiWrite(this, string, offset, length)
+
+ case 'latin1':
+ case 'binary':
+ return latin1Write(this, string, offset, length)
+
+ case 'base64':
+ // Warning: maxLength not taken into account in base64Write
+ return base64Write(this, string, offset, length)
+
+ case 'ucs2':
+ case 'ucs-2':
+ case 'utf16le':
+ case 'utf-16le':
+ return ucs2Write(this, string, offset, length)
+
+ default:
+ if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+ encoding = ('' + encoding).toLowerCase()
+ loweredCase = true
+ }
+ }
+}
+
+Buffer.prototype.toJSON = function toJSON () {
+ return {
+ type: 'Buffer',
+ data: Array.prototype.slice.call(this._arr || this, 0)
+ }
+}
+
+function base64Slice (buf, start, end) {
+ if (start === 0 && end === buf.length) {
+ return base64.fromByteArray(buf)
+ } else {
+ return base64.fromByteArray(buf.slice(start, end))
+ }
+}
+
+function utf8Slice (buf, start, end) {
+ end = Math.min(buf.length, end)
+ var res = []
+
+ var i = start
+ while (i < end) {
+ var firstByte = buf[i]
+ var codePoint = null
+ var bytesPerSequence = (firstByte > 0xEF) ? 4
+ : (firstByte > 0xDF) ? 3
+ : (firstByte > 0xBF) ? 2
+ : 1
+
+ if (i + bytesPerSequence <= end) {
+ var secondByte, thirdByte, fourthByte, tempCodePoint
+
+ switch (bytesPerSequence) {
+ case 1:
+ if (firstByte < 0x80) {
+ codePoint = firstByte
+ }
+ break
+ case 2:
+ secondByte = buf[i + 1]
+ if ((secondByte & 0xC0) === 0x80) {
+ tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
+ if (tempCodePoint > 0x7F) {
+ codePoint = tempCodePoint
+ }
+ }
+ break
+ case 3:
+ secondByte = buf[i + 1]
+ thirdByte = buf[i + 2]
+ if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
+ tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
+ if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
+ codePoint = tempCodePoint
+ }
+ }
+ break
+ case 4:
+ secondByte = buf[i + 1]
+ thirdByte = buf[i + 2]
+ fourthByte = buf[i + 3]
+ if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
+ tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
+ if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
+ codePoint = tempCodePoint
+ }
+ }
+ }
+ }
+
+ if (codePoint === null) {
+ // we did not generate a valid codePoint so insert a
+ // replacement char (U+FFFD) and advance only 1 byte
+ codePoint = 0xFFFD
+ bytesPerSequence = 1
+ } else if (codePoint > 0xFFFF) {
+ // encode to utf16 (surrogate pair dance)
+ codePoint -= 0x10000
+ res.push(codePoint >>> 10 & 0x3FF | 0xD800)
+ codePoint = 0xDC00 | codePoint & 0x3FF
+ }
+
+ res.push(codePoint)
+ i += bytesPerSequence
+ }
+
+ return decodeCodePointsArray(res)
+}
+
+// Based on http://stackoverflow.com/a/22747272/680742, the browser with
+// the lowest limit is Chrome, with 0x10000 args.
+// We go 1 magnitude less, for safety
+var MAX_ARGUMENTS_LENGTH = 0x1000
+
+function decodeCodePointsArray (codePoints) {
+ var len = codePoints.length
+ if (len <= MAX_ARGUMENTS_LENGTH) {
+ return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
+ }
+
+ // Decode in chunks to avoid "call stack size exceeded".
+ var res = ''
+ var i = 0
+ while (i < len) {
+ res += String.fromCharCode.apply(
+ String,
+ codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
+ )
+ }
+ return res
+}
+
+function asciiSlice (buf, start, end) {
+ var ret = ''
+ end = Math.min(buf.length, end)
+
+ for (var i = start; i < end; ++i) {
+ ret += String.fromCharCode(buf[i] & 0x7F)
+ }
+ return ret
+}
+
+function latin1Slice (buf, start, end) {
+ var ret = ''
+ end = Math.min(buf.length, end)
+
+ for (var i = start; i < end; ++i) {
+ ret += String.fromCharCode(buf[i])
+ }
+ return ret
+}
+
+function hexSlice (buf, start, end) {
+ var len = buf.length
+
+ if (!start || start < 0) start = 0
+ if (!end || end < 0 || end > len) end = len
+
+ var out = ''
+ for (var i = start; i < end; ++i) {
+ out += toHex(buf[i])
+ }
+ return out
+}
+
+function utf16leSlice (buf, start, end) {
+ var bytes = buf.slice(start, end)
+ var res = ''
+ for (var i = 0; i < bytes.length; i += 2) {
+ res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
+ }
+ return res
+}
+
+Buffer.prototype.slice = function slice (start, end) {
+ var len = this.length
+ start = ~~start
+ end = end === undefined ? len : ~~end
+
+ if (start < 0) {
+ start += len
+ if (start < 0) start = 0
+ } else if (start > len) {
+ start = len
+ }
+
+ if (end < 0) {
+ end += len
+ if (end < 0) end = 0
+ } else if (end > len) {
+ end = len
+ }
+
+ if (end < start) end = start
+
+ var newBuf
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ newBuf = this.subarray(start, end)
+ newBuf.__proto__ = Buffer.prototype
+ } else {
+ var sliceLen = end - start
+ newBuf = new Buffer(sliceLen, undefined)
+ for (var i = 0; i < sliceLen; ++i) {
+ newBuf[i] = this[i + start]
+ }
+ }
+
+ return newBuf
+}
+
+/*
+ * Need to make sure that buffer isn't trying to write out of bounds.
+ */
+function checkOffset (offset, ext, length) {
+ if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
+ if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
+}
+
+Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
+ offset = offset | 0
+ byteLength = byteLength | 0
+ if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+ var val = this[offset]
+ var mul = 1
+ var i = 0
+ while (++i < byteLength && (mul *= 0x100)) {
+ val += this[offset + i] * mul
+ }
+
+ return val
+}
+
+Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
+ offset = offset | 0
+ byteLength = byteLength | 0
+ if (!noAssert) {
+ checkOffset(offset, byteLength, this.length)
+ }
+
+ var val = this[offset + --byteLength]
+ var mul = 1
+ while (byteLength > 0 && (mul *= 0x100)) {
+ val += this[offset + --byteLength] * mul
+ }
+
+ return val
+}
+
+Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 1, this.length)
+ return this[offset]
+}
+
+Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 2, this.length)
+ return this[offset] | (this[offset + 1] << 8)
+}
+
+Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 2, this.length)
+ return (this[offset] << 8) | this[offset + 1]
+}
+
+Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 4, this.length)
+
+ return ((this[offset]) |
+ (this[offset + 1] << 8) |
+ (this[offset + 2] << 16)) +
+ (this[offset + 3] * 0x1000000)
+}
+
+Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 4, this.length)
+
+ return (this[offset] * 0x1000000) +
+ ((this[offset + 1] << 16) |
+ (this[offset + 2] << 8) |
+ this[offset + 3])
+}
+
+Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
+ offset = offset | 0
+ byteLength = byteLength | 0
+ if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+ var val = this[offset]
+ var mul = 1
+ var i = 0
+ while (++i < byteLength && (mul *= 0x100)) {
+ val += this[offset + i] * mul
+ }
+ mul *= 0x80
+
+ if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+ return val
+}
+
+Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
+ offset = offset | 0
+ byteLength = byteLength | 0
+ if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+ var i = byteLength
+ var mul = 1
+ var val = this[offset + --i]
+ while (i > 0 && (mul *= 0x100)) {
+ val += this[offset + --i] * mul
+ }
+ mul *= 0x80
+
+ if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+ return val
+}
+
+Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 1, this.length)
+ if (!(this[offset] & 0x80)) return (this[offset])
+ return ((0xff - this[offset] + 1) * -1)
+}
+
+Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 2, this.length)
+ var val = this[offset] | (this[offset + 1] << 8)
+ return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 2, this.length)
+ var val = this[offset + 1] | (this[offset] << 8)
+ return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 4, this.length)
+
+ return (this[offset]) |
+ (this[offset + 1] << 8) |
+ (this[offset + 2] << 16) |
+ (this[offset + 3] << 24)
+}
+
+Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 4, this.length)
+
+ return (this[offset] << 24) |
+ (this[offset + 1] << 16) |
+ (this[offset + 2] << 8) |
+ (this[offset + 3])
+}
+
+Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 4, this.length)
+ return ieee754.read(this, offset, true, 23, 4)
+}
+
+Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 4, this.length)
+ return ieee754.read(this, offset, false, 23, 4)
+}
+
+Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 8, this.length)
+ return ieee754.read(this, offset, true, 52, 8)
+}
+
+Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
+ if (!noAssert) checkOffset(offset, 8, this.length)
+ return ieee754.read(this, offset, false, 52, 8)
+}
+
+function checkInt (buf, value, offset, ext, max, min) {
+ if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
+ if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
+ if (offset + ext > buf.length) throw new RangeError('Index out of range')
+}
+
+Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
+ value = +value
+ offset = offset | 0
+ byteLength = byteLength | 0
+ if (!noAssert) {
+ var maxBytes = Math.pow(2, 8 * byteLength) - 1
+ checkInt(this, value, offset, byteLength, maxBytes, 0)
+ }
+
+ var mul = 1
+ var i = 0
+ this[offset] = value & 0xFF
+ while (++i < byteLength && (mul *= 0x100)) {
+ this[offset + i] = (value / mul) & 0xFF
+ }
+
+ return offset + byteLength
+}
+
+Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
+ value = +value
+ offset = offset | 0
+ byteLength = byteLength | 0
+ if (!noAssert) {
+ var maxBytes = Math.pow(2, 8 * byteLength) - 1
+ checkInt(this, value, offset, byteLength, maxBytes, 0)
+ }
+
+ var i = byteLength - 1
+ var mul = 1
+ this[offset + i] = value & 0xFF
+ while (--i >= 0 && (mul *= 0x100)) {
+ this[offset + i] = (value / mul) & 0xFF
+ }
+
+ return offset + byteLength
+}
+
+Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
+ if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+ this[offset] = (value & 0xff)
+ return offset + 1
+}
+
+function objectWriteUInt16 (buf, value, offset, littleEndian) {
+ if (value < 0) value = 0xffff + value + 1
+ for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
+ buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
+ (littleEndian ? i : 1 - i) * 8
+ }
+}
+
+Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value & 0xff)
+ this[offset + 1] = (value >>> 8)
+ } else {
+ objectWriteUInt16(this, value, offset, true)
+ }
+ return offset + 2
+}
+
+Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value >>> 8)
+ this[offset + 1] = (value & 0xff)
+ } else {
+ objectWriteUInt16(this, value, offset, false)
+ }
+ return offset + 2
+}
+
+function objectWriteUInt32 (buf, value, offset, littleEndian) {
+ if (value < 0) value = 0xffffffff + value + 1
+ for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
+ buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
+ }
+}
+
+Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset + 3] = (value >>> 24)
+ this[offset + 2] = (value >>> 16)
+ this[offset + 1] = (value >>> 8)
+ this[offset] = (value & 0xff)
+ } else {
+ objectWriteUInt32(this, value, offset, true)
+ }
+ return offset + 4
+}
+
+Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value >>> 24)
+ this[offset + 1] = (value >>> 16)
+ this[offset + 2] = (value >>> 8)
+ this[offset + 3] = (value & 0xff)
+ } else {
+ objectWriteUInt32(this, value, offset, false)
+ }
+ return offset + 4
+}
+
+Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) {
+ var limit = Math.pow(2, 8 * byteLength - 1)
+
+ checkInt(this, value, offset, byteLength, limit - 1, -limit)
+ }
+
+ var i = 0
+ var mul = 1
+ var sub = 0
+ this[offset] = value & 0xFF
+ while (++i < byteLength && (mul *= 0x100)) {
+ if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
+ sub = 1
+ }
+ this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+ }
+
+ return offset + byteLength
+}
+
+Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) {
+ var limit = Math.pow(2, 8 * byteLength - 1)
+
+ checkInt(this, value, offset, byteLength, limit - 1, -limit)
+ }
+
+ var i = byteLength - 1
+ var mul = 1
+ var sub = 0
+ this[offset + i] = value & 0xFF
+ while (--i >= 0 && (mul *= 0x100)) {
+ if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
+ sub = 1
+ }
+ this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+ }
+
+ return offset + byteLength
+}
+
+Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
+ if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+ if (value < 0) value = 0xff + value + 1
+ this[offset] = (value & 0xff)
+ return offset + 1
+}
+
+Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value & 0xff)
+ this[offset + 1] = (value >>> 8)
+ } else {
+ objectWriteUInt16(this, value, offset, true)
+ }
+ return offset + 2
+}
+
+Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value >>> 8)
+ this[offset + 1] = (value & 0xff)
+ } else {
+ objectWriteUInt16(this, value, offset, false)
+ }
+ return offset + 2
+}
+
+Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value & 0xff)
+ this[offset + 1] = (value >>> 8)
+ this[offset + 2] = (value >>> 16)
+ this[offset + 3] = (value >>> 24)
+ } else {
+ objectWriteUInt32(this, value, offset, true)
+ }
+ return offset + 4
+}
+
+Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
+ value = +value
+ offset = offset | 0
+ if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+ if (value < 0) value = 0xffffffff + value + 1
+ if (Buffer.TYPED_ARRAY_SUPPORT) {
+ this[offset] = (value >>> 24)
+ this[offset + 1] = (value >>> 16)
+ this[offset + 2] = (value >>> 8)
+ this[offset + 3] = (value & 0xff)
+ } else {
+ objectWriteUInt32(this, value, offset, false)
+ }
+ return offset + 4
+}
+
+function checkIEEE754 (buf, value, offset, ext, max, min) {
+ if (offset + ext > buf.length) throw new RangeError('Index out of range')
+ if (offset < 0) throw new RangeError('Index out of range')
+}
+
+function writeFloat (buf, value, offset, littleEndian, noAssert) {
+ if (!noAssert) {
+ checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
+ }
+ ieee754.write(buf, value, offset, littleEndian, 23, 4)
+ return offset + 4
+}
+
+Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
+ return writeFloat(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
+ return writeFloat(this, value, offset, false, noAssert)
+}
+
+function writeDouble (buf, value, offset, littleEndian, noAssert) {
+ if (!noAssert) {
+ checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
+ }
+ ieee754.write(buf, value, offset, littleEndian, 52, 8)
+ return offset + 8
+}
+
+Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
+ return writeDouble(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
+ return writeDouble(this, value, offset, false, noAssert)
+}
+
+// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
+Buffer.prototype.copy = function copy (target, targetStart, start, end) {
+ if (!start) start = 0
+ if (!end && end !== 0) end = this.length
+ if (targetStart >= target.length) targetStart = target.length
+ if (!targetStart) targetStart = 0
+ if (end > 0 && end < start) end = start
+
+ // Copy 0 bytes; we're done
+ if (end === start) return 0
+ if (target.length === 0 || this.length === 0) return 0
+
+ // Fatal error conditions
+ if (targetStart < 0) {
+ throw new RangeError('targetStart out of bounds')
+ }
+ if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
+ if (end < 0) throw new RangeError('sourceEnd out of bounds')
+
+ // Are we oob?
+ if (end > this.length) end = this.length
+ if (target.length - targetStart < end - start) {
+ end = target.length - targetStart + start
+ }
+
+ var len = end - start
+ var i
+
+ if (this === target && start < targetStart && targetStart < end) {
+ // descending copy from end
+ for (i = len - 1; i >= 0; --i) {
+ target[i + targetStart] = this[i + start]
+ }
+ } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
+ // ascending copy from start
+ for (i = 0; i < len; ++i) {
+ target[i + targetStart] = this[i + start]
+ }
+ } else {
+ Uint8Array.prototype.set.call(
+ target,
+ this.subarray(start, start + len),
+ targetStart
+ )
+ }
+
+ return len
+}
+
+// Usage:
+// buffer.fill(number[, offset[, end]])
+// buffer.fill(buffer[, offset[, end]])
+// buffer.fill(string[, offset[, end]][, encoding])
+Buffer.prototype.fill = function fill (val, start, end, encoding) {
+ // Handle string cases:
+ if (typeof val === 'string') {
+ if (typeof start === 'string') {
+ encoding = start
+ start = 0
+ end = this.length
+ } else if (typeof end === 'string') {
+ encoding = end
+ end = this.length
+ }
+ if (val.length === 1) {
+ var code = val.charCodeAt(0)
+ if (code < 256) {
+ val = code
+ }
+ }
+ if (encoding !== undefined && typeof encoding !== 'string') {
+ throw new TypeError('encoding must be a string')
+ }
+ if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
+ throw new TypeError('Unknown encoding: ' + encoding)
+ }
+ } else if (typeof val === 'number') {
+ val = val & 255
+ }
+
+ // Invalid ranges are not set to a default, so can range check early.
+ if (start < 0 || this.length < start || this.length < end) {
+ throw new RangeError('Out of range index')
+ }
+
+ if (end <= start) {
+ return this
+ }
+
+ start = start >>> 0
+ end = end === undefined ? this.length : end >>> 0
+
+ if (!val) val = 0
+
+ var i
+ if (typeof val === 'number') {
+ for (i = start; i < end; ++i) {
+ this[i] = val
+ }
+ } else {
+ var bytes = Buffer.isBuffer(val)
+ ? val
+ : utf8ToBytes(new Buffer(val, encoding).toString())
+ var len = bytes.length
+ for (i = 0; i < end - start; ++i) {
+ this[i + start] = bytes[i % len]
+ }
+ }
+
+ return this
+}
+
+// HELPER FUNCTIONS
+// ================
+
+var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
+
+function base64clean (str) {
+ // Node strips out invalid characters like \n and \t from the string, base64-js does not
+ str = stringtrim(str).replace(INVALID_BASE64_RE, '')
+ // Node converts strings with length < 2 to ''
+ if (str.length < 2) return ''
+ // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
+ while (str.length % 4 !== 0) {
+ str = str + '='
+ }
+ return str
+}
+
+function stringtrim (str) {
+ if (str.trim) return str.trim()
+ return str.replace(/^\s+|\s+$/g, '')
+}
+
+function toHex (n) {
+ if (n < 16) return '0' + n.toString(16)
+ return n.toString(16)
+}
+
+function utf8ToBytes (string, units) {
+ units = units || Infinity
+ var codePoint
+ var length = string.length
+ var leadSurrogate = null
+ var bytes = []
+
+ for (var i = 0; i < length; ++i) {
+ codePoint = string.charCodeAt(i)
+
+ // is surrogate component
+ if (codePoint > 0xD7FF && codePoint < 0xE000) {
+ // last char was a lead
+ if (!leadSurrogate) {
+ // no lead yet
+ if (codePoint > 0xDBFF) {
+ // unexpected trail
+ if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+ continue
+ } else if (i + 1 === length) {
+ // unpaired lead
+ if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+ continue
+ }
+
+ // valid lead
+ leadSurrogate = codePoint
+
+ continue
+ }
+
+ // 2 leads in a row
+ if (codePoint < 0xDC00) {
+ if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+ leadSurrogate = codePoint
+ continue
+ }
+
+ // valid surrogate pair
+ codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
+ } else if (leadSurrogate) {
+ // valid bmp char, but last char was a lead
+ if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+ }
+
+ leadSurrogate = null
+
+ // encode utf8
+ if (codePoint < 0x80) {
+ if ((units -= 1) < 0) break
+ bytes.push(codePoint)
+ } else if (codePoint < 0x800) {
+ if ((units -= 2) < 0) break
+ bytes.push(
+ codePoint >> 0x6 | 0xC0,
+ codePoint & 0x3F | 0x80
+ )
+ } else if (codePoint < 0x10000) {
+ if ((units -= 3) < 0) break
+ bytes.push(
+ codePoint >> 0xC | 0xE0,
+ codePoint >> 0x6 & 0x3F | 0x80,
+ codePoint & 0x3F | 0x80
+ )
+ } else if (codePoint < 0x110000) {
+ if ((units -= 4) < 0) break
+ bytes.push(
+ codePoint >> 0x12 | 0xF0,
+ codePoint >> 0xC & 0x3F | 0x80,
+ codePoint >> 0x6 & 0x3F | 0x80,
+ codePoint & 0x3F | 0x80
+ )
+ } else {
+ throw new Error('Invalid code point')
+ }
+ }
+
+ return bytes
+}
+
+function asciiToBytes (str) {
+ var byteArray = []
+ for (var i = 0; i < str.length; ++i) {
+ // Node's code seems to be doing this and not & 0x7F..
+ byteArray.push(str.charCodeAt(i) & 0xFF)
+ }
+ return byteArray
+}
+
+function utf16leToBytes (str, units) {
+ var c, hi, lo
+ var byteArray = []
+ for (var i = 0; i < str.length; ++i) {
+ if ((units -= 2) < 0) break
+
+ c = str.charCodeAt(i)
+ hi = c >> 8
+ lo = c % 256
+ byteArray.push(lo)
+ byteArray.push(hi)
+ }
+
+ return byteArray
+}
+
+function base64ToBytes (str) {
+ return base64.toByteArray(base64clean(str))
+}
+
+function blitBuffer (src, dst, offset, length) {
+ for (var i = 0; i < length; ++i) {
+ if ((i + offset >= dst.length) || (i >= src.length)) break
+ dst[i + offset] = src[i]
+ }
+ return i
+}
+
+function isnan (val) {
+ return val !== val // eslint-disable-line no-self-compare
+}
+
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8)))
+
+/***/ }),
+/* 6 */
+/***/ (function(module, exports) {
+
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things. But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals. It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+function defaultSetTimout() {
+ throw new Error('setTimeout has not been defined');
+}
+function defaultClearTimeout () {
+ throw new Error('clearTimeout has not been defined');
+}
+(function () {
+ try {
+ if (typeof setTimeout === 'function') {
+ cachedSetTimeout = setTimeout;
+ } else {
+ cachedSetTimeout = defaultSetTimout;
+ }
+ } catch (e) {
+ cachedSetTimeout = defaultSetTimout;
+ }
+ try {
+ if (typeof clearTimeout === 'function') {
+ cachedClearTimeout = clearTimeout;
+ } else {
+ cachedClearTimeout = defaultClearTimeout;
+ }
+ } catch (e) {
+ cachedClearTimeout = defaultClearTimeout;
+ }
+} ())
+function runTimeout(fun) {
+ if (cachedSetTimeout === setTimeout) {
+ //normal enviroments in sane situations
+ return setTimeout(fun, 0);
+ }
+ // if setTimeout wasn't available but was latter defined
+ if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+ cachedSetTimeout = setTimeout;
+ return setTimeout(fun, 0);
+ }
+ try {
+ // when when somebody has screwed with setTimeout but no I.E. maddness
+ return cachedSetTimeout(fun, 0);
+ } catch(e){
+ try {
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+ return cachedSetTimeout.call(null, fun, 0);
+ } catch(e){
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+ return cachedSetTimeout.call(this, fun, 0);
+ }
+ }
+
+
+}
+function runClearTimeout(marker) {
+ if (cachedClearTimeout === clearTimeout) {
+ //normal enviroments in sane situations
+ return clearTimeout(marker);
+ }
+ // if clearTimeout wasn't available but was latter defined
+ if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+ cachedClearTimeout = clearTimeout;
+ return clearTimeout(marker);
+ }
+ try {
+ // when when somebody has screwed with setTimeout but no I.E. maddness
+ return cachedClearTimeout(marker);
+ } catch (e){
+ try {
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+ return cachedClearTimeout.call(null, marker);
+ } catch (e){
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+ // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+ return cachedClearTimeout.call(this, marker);
+ }
+ }
+
+
+
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+ if (!draining || !currentQueue) {
+ return;
+ }
+ draining = false;
+ if (currentQueue.length) {
+ queue = currentQueue.concat(queue);
+ } else {
+ queueIndex = -1;
+ }
+ if (queue.length) {
+ drainQueue();
+ }
+}
+
+function drainQueue() {
+ if (draining) {
+ return;
+ }
+ var timeout = runTimeout(cleanUpNextTick);
+ draining = true;
+
+ var len = queue.length;
+ while(len) {
+ currentQueue = queue;
+ queue = [];
+ while (++queueIndex < len) {
+ if (currentQueue) {
+ currentQueue[queueIndex].run();
+ }
+ }
+ queueIndex = -1;
+ len = queue.length;
+ }
+ currentQueue = null;
+ draining = false;
+ runClearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+ var args = new Array(arguments.length - 1);
+ if (arguments.length > 1) {
+ for (var i = 1; i < arguments.length; i++) {
+ args[i - 1] = arguments[i];
+ }
+ }
+ queue.push(new Item(fun, args));
+ if (queue.length === 1 && !draining) {
+ runTimeout(drainQueue);
+ }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+ this.fun = fun;
+ this.array = array;
+}
+Item.prototype.run = function () {
+ this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+
+process.binding = function (name) {
+ throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+ throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+
+/***/ }),
+/* 7 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Long = __webpack_require__(35);
+
+// Discord epoch (2015-01-01T00:00:00.000Z)
+const EPOCH = 1420070400000;
+let INCREMENT = 0;
+
+/**
+ * A container for useful snowflake-related methods.
+ */
+class SnowflakeUtil {
+ constructor() {
+ throw new Error(`The ${this.constructor.name} class may not be instantiated.`);
+ }
+
+ /**
+ * A Twitter snowflake, except the epoch is 2015-01-01T00:00:00.000Z
+ * ```
+ * If we have a snowflake '266241948824764416' we can represent it as binary:
+ *
+ * 64 22 17 12 0
+ * 000000111011000111100001101001000101000000 00001 00000 000000000000
+ * number of ms since Discord epoch worker pid increment
+ * ```
+ * @typedef {string} Snowflake
+ */
+
+ /**
+ * Generates a Discord snowflake.
+ * This hardcodes the worker ID as 1 and the process ID as 0.
+ * @returns {Snowflake} The generated snowflake
+ */
+ static generate() {
+ if (INCREMENT >= 4095) INCREMENT = 0;
+ const BINARY = `${pad((Date.now() - EPOCH).toString(2), 42)}0000100000${pad((INCREMENT++).toString(2), 12)}`;
+ return Long.fromString(BINARY, 2).toString();
+ }
+
+ /**
+ * A deconstructed snowflake.
+ * @typedef {Object} DeconstructedSnowflake
+ * @property {number} timestamp Timestamp the snowflake was created
+ * @property {Date} date Date the snowflake was created
+ * @property {number} workerID Worker ID in the snowflake
+ * @property {number} processID Process ID in the snowflake
+ * @property {number} increment Increment in the snowflake
+ * @property {string} binary Binary representation of the snowflake
+ */
+
+ /**
+ * Deconstructs a Discord snowflake.
+ * @param {Snowflake} snowflake Snowflake to deconstruct
+ * @returns {DeconstructedSnowflake} Deconstructed snowflake
+ */
+ static deconstruct(snowflake) {
+ const BINARY = pad(Long.fromString(snowflake).toString(2), 64);
+ const res = {
+ timestamp: parseInt(BINARY.substring(0, 42), 2) + EPOCH,
+ workerID: parseInt(BINARY.substring(42, 47), 2),
+ processID: parseInt(BINARY.substring(47, 52), 2),
+ increment: parseInt(BINARY.substring(52, 64), 2),
+ binary: BINARY,
+ };
+ Object.defineProperty(res, 'date', {
+ get: function get() { return new Date(this.timestamp); },
+ enumerable: true,
+ });
+ return res;
+ }
+}
+
+function pad(v, n, c = '0') {
+ return String(v).length >= n ? String(v) : (String(c).repeat(n) + v).slice(-n);
+}
+
+module.exports = SnowflakeUtil;
+
+
+/***/ }),
+/* 8 */
+/***/ (function(module, exports) {
+
+var g;
+
+// This works in non-strict mode
+g = (function() {
+ return this;
+})();
+
+try {
+ // This works if eval is allowed (see CSP)
+ g = g || Function("return this")() || (1,eval)("this");
+} catch(e) {
+ // This works if the window reference is available
+ if(typeof window === "object")
+ g = window;
+}
+
+// g can still be undefined, but nothing to do about it...
+// We return undefined, instead of nothing here, so it's
+// easier to handle this case. if(!global) { ...}
+
+module.exports = g;
+
+
+/***/ }),
+/* 9 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Constants = __webpack_require__(0);
+const util = __webpack_require__(22);
+
+/**
+ * Data structure that makes it easy to interact with a permission bitfield. All {@link GuildMember}s have a set of
+ * permissions in their guild, and each channel in the guild may also have {@link PermissionOverwrites} for the member
+ * that override their default permissions.
+ */
+class Permissions {
+ /**
+ * @param {GuildMember} [member] Member the permissions are for **(deprecated)**
+ * @param {number|PermissionResolvable[]} permissions Permissions or bitfield to read from
+ */
+ constructor(member, permissions) {
+ permissions = typeof member === 'object' && !(member instanceof Array) ? permissions : member;
+
+ /**
+ * Member the permissions are for
+ * @type {GuildMember}
+ * @deprecated
+ */
+ this._member = typeof member === 'object' ? member : null;
+
+ /**
+ * Bitfield of the packed permissions
+ * @type {number}
+ */
+ this.bitfield = typeof permissions === 'number' ? permissions : this.constructor.resolve(permissions);
+ }
+
+ get member() {
+ return this._member;
+ }
+
+ set member(value) {
+ this._member = value;
+ }
+
+ /**
+ * Bitfield of the packed permissions
+ * @type {number}
+ * @see {@link Permissions#bitfield}
+ * @deprecated
+ * @readonly
+ */
+ get raw() {
+ return this.bitfield;
+ }
+
+ set raw(raw) {
+ this.bitfield = raw;
+ }
+
+ /**
+ * Checks whether the bitfield has a permission, or multiple permissions.
+ * @param {PermissionResolvable|PermissionResolvable[]} permission Permission(s) to check for
+ * @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override
+ * @returns {boolean}
+ */
+ has(permission, checkAdmin = true) {
+ if (permission instanceof Array) return permission.every(p => this.has(p, checkAdmin));
+ permission = this.constructor.resolve(permission);
+ if (checkAdmin && (this.bitfield & this.constructor.FLAGS.ADMINISTRATOR) > 0) return true;
+ return (this.bitfield & permission) === permission;
+ }
+
+ /**
+ * Gets all given permissions that are missing from the bitfield.
+ * @param {PermissionResolvable[]} permissions Permissions to check for
+ * @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override
+ * @returns {PermissionResolvable[]}
+ */
+ missing(permissions, checkAdmin = true) {
+ return permissions.filter(p => !this.has(p, checkAdmin));
+ }
+
+ /**
+ * Adds permissions to this one, creating a new instance to represent the new bitfield.
+ * @param {...PermissionResolvable} permissions Permissions to add
+ * @returns {Permissions}
+ */
+ add(...permissions) {
+ let total = 0;
+ for (let p = 0; p < permissions.length; p++) {
+ const perm = this.constructor.resolve(permissions[p]);
+ if ((this.bitfield & perm) !== perm) total |= perm;
+ }
+ return new this.constructor(this.member, this.bitfield | total);
+ }
+
+ /**
+ * Removes permissions to this one, creating a new instance to represent the new bitfield.
+ * @param {...PermissionResolvable} permissions Permissions to remove
+ * @returns {Permissions}
+ */
+ remove(...permissions) {
+ let total = 0;
+ for (let p = 0; p < permissions.length; p++) {
+ const perm = this.constructor.resolve(permissions[p]);
+ if ((this.bitfield & perm) === perm) total |= perm;
+ }
+ return new this.constructor(this.member, this.bitfield & ~total);
+ }
+
+ /**
+ * Gets an object mapping permission name (like `READ_MESSAGES`) to a {@link boolean} indicating whether the
+ * permission is available.
+ * @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override
+ * @returns {Object}
+ */
+ serialize(checkAdmin = true) {
+ const serialized = {};
+ for (const perm in this.constructor.FLAGS) serialized[perm] = this.has(perm, checkAdmin);
+ return serialized;
+ }
+
+ /**
+ * Checks whether the user has a certain permission, e.g. `READ_MESSAGES`.
+ * @param {PermissionResolvable} permission The permission to check for
+ * @param {boolean} [explicit=false] Whether to require the user to explicitly have the exact permission
+ * @returns {boolean}
+ * @see {@link Permissions#has}
+ * @deprecated
+ */
+ hasPermission(permission, explicit = false) {
+ return this.has(permission, !explicit);
+ }
+
+ /**
+ * Checks whether the user has all specified permissions.
+ * @param {PermissionResolvable[]} permissions The permissions to check for
+ * @param {boolean} [explicit=false] Whether to require the user to explicitly have the exact permissions
+ * @returns {boolean}
+ * @see {@link Permissions#has}
+ * @deprecated
+ */
+ hasPermissions(permissions, explicit = false) {
+ return this.has(permissions, !explicit);
+ }
+
+ /**
+ * Checks whether the user has all specified permissions, and lists any missing permissions.
+ * @param {PermissionResolvable[]} permissions The permissions to check for
+ * @param {boolean} [explicit=false] Whether to require the user to explicitly have the exact permissions
+ * @returns {PermissionResolvable[]}
+ * @see {@link Permissions#missing}
+ * @deprecated
+ */
+ missingPermissions(permissions, explicit = false) {
+ return this.missing(permissions, !explicit);
+ }
+
+ /**
+ * Data that can be resolved to give a permission number. This can be:
+ * - A string (see {@link Permissions.flags})
+ * - A permission number
+ * @typedef {string|number} PermissionResolvable
+ */
+
+ /**
+ * Resolves permissions to their numeric form.
+ * @param {PermissionResolvable|PermissionResolvable[]} permission - Permission(s) to resolve
+ * @returns {number}
+ */
+ static resolve(permission) {
+ if (permission instanceof Array) return permission.map(p => this.resolve(p)).reduce((prev, p) => prev | p, 0);
+ if (typeof permission === 'string') permission = this.FLAGS[permission];
+ if (typeof permission !== 'number' || permission < 1) throw new RangeError(Constants.Errors.NOT_A_PERMISSION);
+ return permission;
+ }
+}
+
+/**
+ * Numeric permission flags. All available properties:
+ * - `ADMINISTRATOR` (implicitly has *all* permissions, and bypasses all channel overwrites)
+ * - `CREATE_INSTANT_INVITE` (create invitations to the guild)
+ * - `KICK_MEMBERS`
+ * - `BAN_MEMBERS`
+ * - `MANAGE_CHANNELS` (edit and reorder channels)
+ * - `MANAGE_GUILD` (edit the guild information, region, etc.)
+ * - `ADD_REACTIONS` (add new reactions to messages)
+ * - `VIEW_AUDIT_LOG`
+ * - `READ_MESSAGES`
+ * - `SEND_MESSAGES`
+ * - `SEND_TTS_MESSAGES`
+ * - `MANAGE_MESSAGES` (delete messages and reactions)
+ * - `EMBED_LINKS` (links posted will have a preview embedded)
+ * - `ATTACH_FILES`
+ * - `READ_MESSAGE_HISTORY` (view messages that were posted prior to opening Discord)
+ * - `MENTION_EVERYONE`
+ * - `USE_EXTERNAL_EMOJIS` (use emojis from different guilds)
+ * - `EXTERNAL_EMOJIS` **(deprecated)**
+ * - `CONNECT` (connect to a voice channel)
+ * - `SPEAK` (speak in a voice channel)
+ * - `MUTE_MEMBERS` (mute members across all voice channels)
+ * - `DEAFEN_MEMBERS` (deafen members across all voice channels)
+ * - `MOVE_MEMBERS` (move members between voice channels)
+ * - `USE_VAD` (use voice activity detection)
+ * - `CHANGE_NICKNAME`
+ * - `MANAGE_NICKNAMES` (change other members' nicknames)
+ * - `MANAGE_ROLES`
+ * - `MANAGE_ROLES_OR_PERMISSIONS` **(deprecated)**
+ * - `MANAGE_WEBHOOKS`
+ * - `MANAGE_EMOJIS`
+ * @type {Object}
+ * @see {@link https://discordapp.com/developers/docs/topics/permissions}
+ */
+Permissions.FLAGS = {
+ CREATE_INSTANT_INVITE: 1 << 0,
+ KICK_MEMBERS: 1 << 1,
+ BAN_MEMBERS: 1 << 2,
+ ADMINISTRATOR: 1 << 3,
+ MANAGE_CHANNELS: 1 << 4,
+ MANAGE_GUILD: 1 << 5,
+ ADD_REACTIONS: 1 << 6,
+ VIEW_AUDIT_LOG: 1 << 7,
+
+ READ_MESSAGES: 1 << 10,
+ SEND_MESSAGES: 1 << 11,
+ SEND_TTS_MESSAGES: 1 << 12,
+ MANAGE_MESSAGES: 1 << 13,
+ EMBED_LINKS: 1 << 14,
+ ATTACH_FILES: 1 << 15,
+ READ_MESSAGE_HISTORY: 1 << 16,
+ MENTION_EVERYONE: 1 << 17,
+ EXTERNAL_EMOJIS: 1 << 18,
+ USE_EXTERNAL_EMOJIS: 1 << 18,
+
+ CONNECT: 1 << 20,
+ SPEAK: 1 << 21,
+ MUTE_MEMBERS: 1 << 22,
+ DEAFEN_MEMBERS: 1 << 23,
+ MOVE_MEMBERS: 1 << 24,
+ USE_VAD: 1 << 25,
+
+ CHANGE_NICKNAME: 1 << 26,
+ MANAGE_NICKNAMES: 1 << 27,
+ MANAGE_ROLES: 1 << 28,
+ MANAGE_ROLES_OR_PERMISSIONS: 1 << 28,
+ MANAGE_WEBHOOKS: 1 << 29,
+ MANAGE_EMOJIS: 1 << 30,
+};
+
+/**
+ * Bitfield representing every permission combined
+ * @type {number}
+ */
+Permissions.ALL = Object.keys(Permissions.FLAGS).reduce((all, p) => all | Permissions.FLAGS[p], 0);
+
+/**
+ * Bitfield representing the default permissions for users
+ * @type {number}
+ */
+Permissions.DEFAULT = 104324097;
+
+/**
+ * @class EvaluatedPermissions
+ * @classdesc The final evaluated permissions for a member in a channel
+ * @see {@link Permissions}
+ * @deprecated
+ */
+
+Permissions.prototype.hasPermission = util.deprecate(Permissions.prototype.hasPermission,
+ 'EvaluatedPermissions#hasPermission is deprecated, use Permissions#has instead');
+Permissions.prototype.hasPermissions = util.deprecate(Permissions.prototype.hasPermissions,
+ 'EvaluatedPermissions#hasPermissions is deprecated, use Permissions#has instead');
+Permissions.prototype.missingPermissions = util.deprecate(Permissions.prototype.missingPermissions,
+ 'EvaluatedPermissions#missingPermissions is deprecated, use Permissions#missing instead');
+Object.defineProperty(Permissions.prototype, 'member', {
+ get: util
+ .deprecate(Object.getOwnPropertyDescriptor(Permissions.prototype, 'member').get,
+ 'EvaluatedPermissions#member is deprecated'),
+});
+
+module.exports = Permissions;
+
+
+/***/ }),
+/* 10 */
+/***/ (function(module, exports) {
+
+if (typeof Object.create === 'function') {
+ // implementation from standard node.js 'util' module
+ module.exports = function inherits(ctor, superCtor) {
+ ctor.super_ = superCtor
+ ctor.prototype = Object.create(superCtor.prototype, {
+ constructor: {
+ value: ctor,
+ enumerable: false,
+ writable: true,
+ configurable: true
+ }
+ });
+ };
+} else {
+ // old school shim for old browsers
+ module.exports = function inherits(ctor, superCtor) {
+ ctor.super_ = superCtor
+ var TempCtor = function () {}
+ TempCtor.prototype = superCtor.prototype
+ ctor.prototype = new TempCtor()
+ ctor.prototype.constructor = ctor
+ }
+}
+
+
+/***/ }),
+/* 11 */
+/***/ (function(module, exports) {
+
+/**
+ * Represents a user's presence.
+ */
+class Presence {
+ constructor(data = {}) {
+ /**
+ * The status of the presence:
+ *
+ * * **`online`** - user is online
+ * * **`offline`** - user is offline or invisible
+ * * **`idle`** - user is AFK
+ * * **`dnd`** - user is in Do not Disturb
+ * @type {string}
+ */
+ this.status = data.status || 'offline';
+
+ /**
+ * The game that the user is playing
+ * @type {?Game}
+ */
+ this.game = data.game ? new Game(data.game) : null;
+ }
+
+ update(data) {
+ this.status = data.status || this.status;
+ this.game = data.game ? new Game(data.game) : null;
+ }
+
+ /**
+ * Whether this presence is equal to another
+ * @param {Presence} presence The presence to compare with
+ * @returns {boolean}
+ */
+ equals(presence) {
+ return this === presence || (
+ presence &&
+ this.status === presence.status &&
+ this.game ? this.game.equals(presence.game) : !presence.game
+ );
+ }
+}
+
+/**
+ * Represents a game that is part of a user's presence.
+ */
+class Game {
+ constructor(data) {
+ /**
+ * The name of the game being played
+ * @type {string}
+ */
+ this.name = data.name;
+
+ /**
+ * The type of the game status
+ * @type {number}
+ */
+ this.type = data.type;
+
+ /**
+ * If the game is being streamed, a link to the stream
+ * @type {?string}
+ */
+ this.url = data.url || null;
+ }
+
+ /**
+ * Whether or not the game is being streamed
+ * @type {boolean}
+ * @readonly
+ */
+ get streaming() {
+ return this.type === 1;
+ }
+
+ /**
+ * Whether this game is equal to another game
+ * @param {Game} game The game to compare with
+ * @returns {boolean}
+ */
+ equals(game) {
+ return this === game || (
+ game &&
+ this.name === game.name &&
+ this.type === game.type &&
+ this.url === game.url
+ );
+ }
+}
+
+exports.Presence = Presence;
+exports.Game = Game;
+
+
+/***/ }),
+/* 12 */
+/***/ (function(module, exports) {
+
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+function EventEmitter() {
+ this._events = this._events || {};
+ this._maxListeners = this._maxListeners || undefined;
+}
+module.exports = EventEmitter;
+
+// Backwards-compat with node 0.10.x
+EventEmitter.EventEmitter = EventEmitter;
+
+EventEmitter.prototype._events = undefined;
+EventEmitter.prototype._maxListeners = undefined;
+
+// By default EventEmitters will print a warning if more than 10 listeners are
+// added to it. This is a useful default which helps finding memory leaks.
+EventEmitter.defaultMaxListeners = 10;
+
+// Obviously not all Emitters should be limited to 10. This function allows
+// that to be increased. Set to zero for unlimited.
+EventEmitter.prototype.setMaxListeners = function(n) {
+ if (!isNumber(n) || n < 0 || isNaN(n))
+ throw TypeError('n must be a positive number');
+ this._maxListeners = n;
+ return this;
+};
+
+EventEmitter.prototype.emit = function(type) {
+ var er, handler, len, args, i, listeners;
+
+ if (!this._events)
+ this._events = {};
+
+ // If there is no 'error' event listener then throw.
+ if (type === 'error') {
+ if (!this._events.error ||
+ (isObject(this._events.error) && !this._events.error.length)) {
+ er = arguments[1];
+ if (er instanceof Error) {
+ throw er; // Unhandled 'error' event
+ } else {
+ // At least give some kind of context to the user
+ var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
+ err.context = er;
+ throw err;
+ }
+ }
+ }
+
+ handler = this._events[type];
+
+ if (isUndefined(handler))
+ return false;
+
+ if (isFunction(handler)) {
+ switch (arguments.length) {
+ // fast cases
+ case 1:
+ handler.call(this);
+ break;
+ case 2:
+ handler.call(this, arguments[1]);
+ break;
+ case 3:
+ handler.call(this, arguments[1], arguments[2]);
+ break;
+ // slower
+ default:
+ args = Array.prototype.slice.call(arguments, 1);
+ handler.apply(this, args);
+ }
+ } else if (isObject(handler)) {
+ args = Array.prototype.slice.call(arguments, 1);
+ listeners = handler.slice();
+ len = listeners.length;
+ for (i = 0; i < len; i++)
+ listeners[i].apply(this, args);
+ }
+
+ return true;
+};
+
+EventEmitter.prototype.addListener = function(type, listener) {
+ var m;
+
+ if (!isFunction(listener))
+ throw TypeError('listener must be a function');
+
+ if (!this._events)
+ this._events = {};
+
+ // To avoid recursion in the case that type === "newListener"! Before
+ // adding it to the listeners, first emit "newListener".
+ if (this._events.newListener)
+ this.emit('newListener', type,
+ isFunction(listener.listener) ?
+ listener.listener : listener);
+
+ if (!this._events[type])
+ // Optimize the case of one listener. Don't need the extra array object.
+ this._events[type] = listener;
+ else if (isObject(this._events[type]))
+ // If we've already got an array, just append.
+ this._events[type].push(listener);
+ else
+ // Adding the second element, need to change to array.
+ this._events[type] = [this._events[type], listener];
+
+ // Check for listener leak
+ if (isObject(this._events[type]) && !this._events[type].warned) {
+ if (!isUndefined(this._maxListeners)) {
+ m = this._maxListeners;
+ } else {
+ m = EventEmitter.defaultMaxListeners;
+ }
+
+ if (m && m > 0 && this._events[type].length > m) {
+ this._events[type].warned = true;
+ console.error('(node) warning: possible EventEmitter memory ' +
+ 'leak detected. %d listeners added. ' +
+ 'Use emitter.setMaxListeners() to increase limit.',
+ this._events[type].length);
+ if (typeof console.trace === 'function') {
+ // not supported in IE 10
+ console.trace();
+ }
+ }
+ }
+
+ return this;
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.once = function(type, listener) {
+ if (!isFunction(listener))
+ throw TypeError('listener must be a function');
+
+ var fired = false;
+
+ function g() {
+ this.removeListener(type, g);
+
+ if (!fired) {
+ fired = true;
+ listener.apply(this, arguments);
+ }
+ }
+
+ g.listener = listener;
+ this.on(type, g);
+
+ return this;
+};
+
+// emits a 'removeListener' event iff the listener was removed
+EventEmitter.prototype.removeListener = function(type, listener) {
+ var list, position, length, i;
+
+ if (!isFunction(listener))
+ throw TypeError('listener must be a function');
+
+ if (!this._events || !this._events[type])
+ return this;
+
+ list = this._events[type];
+ length = list.length;
+ position = -1;
+
+ if (list === listener ||
+ (isFunction(list.listener) && list.listener === listener)) {
+ delete this._events[type];
+ if (this._events.removeListener)
+ this.emit('removeListener', type, listener);
+
+ } else if (isObject(list)) {
+ for (i = length; i-- > 0;) {
+ if (list[i] === listener ||
+ (list[i].listener && list[i].listener === listener)) {
+ position = i;
+ break;
+ }
+ }
+
+ if (position < 0)
+ return this;
+
+ if (list.length === 1) {
+ list.length = 0;
+ delete this._events[type];
+ } else {
+ list.splice(position, 1);
+ }
+
+ if (this._events.removeListener)
+ this.emit('removeListener', type, listener);
+ }
+
+ return this;
+};
+
+EventEmitter.prototype.removeAllListeners = function(type) {
+ var key, listeners;
+
+ if (!this._events)
+ return this;
+
+ // not listening for removeListener, no need to emit
+ if (!this._events.removeListener) {
+ if (arguments.length === 0)
+ this._events = {};
+ else if (this._events[type])
+ delete this._events[type];
+ return this;
+ }
+
+ // emit removeListener for all listeners on all events
+ if (arguments.length === 0) {
+ for (key in this._events) {
+ if (key === 'removeListener') continue;
+ this.removeAllListeners(key);
+ }
+ this.removeAllListeners('removeListener');
+ this._events = {};
+ return this;
+ }
+
+ listeners = this._events[type];
+
+ if (isFunction(listeners)) {
+ this.removeListener(type, listeners);
+ } else if (listeners) {
+ // LIFO order
+ while (listeners.length)
+ this.removeListener(type, listeners[listeners.length - 1]);
+ }
+ delete this._events[type];
+
+ return this;
+};
+
+EventEmitter.prototype.listeners = function(type) {
+ var ret;
+ if (!this._events || !this._events[type])
+ ret = [];
+ else if (isFunction(this._events[type]))
+ ret = [this._events[type]];
+ else
+ ret = this._events[type].slice();
+ return ret;
+};
+
+EventEmitter.prototype.listenerCount = function(type) {
+ if (this._events) {
+ var evlistener = this._events[type];
+
+ if (isFunction(evlistener))
+ return 1;
+ else if (evlistener)
+ return evlistener.length;
+ }
+ return 0;
+};
+
+EventEmitter.listenerCount = function(emitter, type) {
+ return emitter.listenerCount(type);
+};
+
+function isFunction(arg) {
+ return typeof arg === 'function';
+}
+
+function isNumber(arg) {
+ return typeof arg === 'number';
+}
+
+function isObject(arg) {
+ return typeof arg === 'object' && arg !== null;
+}
+
+function isUndefined(arg) {
+ return arg === void 0;
+}
+
+
+/***/ }),
+/* 13 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+// a duplex stream is just a stream that is both readable and writable.
+// Since JS doesn't have multiple prototypal inheritance, this class
+// prototypally inherits from Readable, and then parasitically from
+// Writable.
+
+
+
+/**/
+
+var objectKeys = Object.keys || function (obj) {
+ var keys = [];
+ for (var key in obj) {
+ keys.push(key);
+ }return keys;
+};
+/**/
+
+module.exports = Duplex;
+
+/**/
+var processNextTick = __webpack_require__(36);
+/**/
+
+/**/
+var util = __webpack_require__(20);
+util.inherits = __webpack_require__(10);
+/**/
+
+var Readable = __webpack_require__(59);
+var Writable = __webpack_require__(38);
+
+util.inherits(Duplex, Readable);
+
+var keys = objectKeys(Writable.prototype);
+for (var v = 0; v < keys.length; v++) {
+ var method = keys[v];
+ if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
+}
+
+function Duplex(options) {
+ if (!(this instanceof Duplex)) return new Duplex(options);
+
+ Readable.call(this, options);
+ Writable.call(this, options);
+
+ if (options && options.readable === false) this.readable = false;
+
+ if (options && options.writable === false) this.writable = false;
+
+ this.allowHalfOpen = true;
+ if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
+
+ this.once('end', onend);
+}
+
+// the no-half-open enforcer
+function onend() {
+ // if we allow half-open state, or if the writable side ended,
+ // then we're ok.
+ if (this.allowHalfOpen || this._writableState.ended) return;
+
+ // no more data can be written.
+ // But allow more writes to happen in this tick.
+ processNextTick(onEndNT, this);
+}
+
+function onEndNT(self) {
+ self.end();
+}
+
+function forEach(xs, f) {
+ for (var i = 0, l = xs.length; i < l; i++) {
+ f(xs[i], i);
+ }
+}
+
+/***/ }),
+/* 14 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Snowflake = __webpack_require__(7);
+
+/**
+ * Represents any channel on Discord.
+ */
+class Channel {
+ constructor(client, data) {
+ /**
+ * The client that instantiated the Channel
+ * @name Channel#client
+ * @type {Client}
+ * @readonly
+ */
+ Object.defineProperty(this, 'client', { value: client });
+
+ /**
+ * The type of the channel, either:
+ * * `dm` - a DM channel
+ * * `group` - a Group DM channel
+ * * `text` - a guild text channel
+ * * `voice` - a guild voice channel
+ * @type {string}
+ */
+ this.type = null;
+
+ if (data) this.setup(data);
+ }
+
+ setup(data) {
+ /**
+ * The unique ID of the channel
+ * @type {Snowflake}
+ */
+ this.id = data.id;
+ }
+
+ /**
+ * The timestamp the channel was created at
+ * @type {number}
+ * @readonly
+ */
+ get createdTimestamp() {
+ return Snowflake.deconstruct(this.id).timestamp;
+ }
+
+ /**
+ * The time the channel was created
+ * @type {Date}
+ * @readonly
+ */
+ get createdAt() {
+ return new Date(this.createdTimestamp);
+ }
+
+ /**
+ * Deletes the channel.
+ * @returns {Promise}
+ * @example
+ * // Delete the channel
+ * channel.delete()
+ * .then() // Success
+ * .catch(console.error); // Log error
+ */
+ delete() {
+ return this.client.rest.methods.deleteChannel(this);
+ }
+}
+
+module.exports = Channel;
+
+
+/***/ }),
+/* 15 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Snowflake = __webpack_require__(7);
+const Permissions = __webpack_require__(9);
+const util = __webpack_require__(22);
+
+/**
+ * Represents a role on Discord.
+ */
+class Role {
+ constructor(guild, data) {
+ /**
+ * The client that instantiated the role
+ * @name Role#client
+ * @type {Client}
+ * @readonly
+ */
+ Object.defineProperty(this, 'client', { value: guild.client });
+
+ /**
+ * The guild that the role belongs to
+ * @type {Guild}
+ */
+ this.guild = guild;
+
+ if (data) this.setup(data);
+ }
+
+ setup(data) {
+ /**
+ * The ID of the role (unique to the guild it is part of)
+ * @type {Snowflake}
+ */
+ this.id = data.id;
+
+ /**
+ * The name of the role
+ * @type {string}
+ */
+ this.name = data.name;
+
+ /**
+ * The base 10 color of the role
+ * @type {number}
+ */
+ this.color = data.color;
+
+ /**
+ * If true, users that are part of this role will appear in a separate category in the users list
+ * @type {boolean}
+ */
+ this.hoist = data.hoist;
+
+ /**
+ * The position of the role from the API
+ * @type {number}
+ */
+ this.position = data.position;
+
+ /**
+ * The permissions bitfield of the role
+ * @type {number}
+ */
+ this.permissions = data.permissions;
+
+ /**
+ * Whether or not the role is managed by an external service
+ * @type {boolean}
+ */
+ this.managed = data.managed;
+
+ /**
+ * Whether or not the role can be mentioned by anyone
+ * @type {boolean}
+ */
+ this.mentionable = data.mentionable;
+ }
+
+ /**
+ * The timestamp the role was created at
+ * @type {number}
+ * @readonly
+ */
+ get createdTimestamp() {
+ return Snowflake.deconstruct(this.id).timestamp;
+ }
+
+ /**
+ * The time the role was created
+ * @type {Date}
+ * @readonly
+ */
+ get createdAt() {
+ return new Date(this.createdTimestamp);
+ }
+
+ /**
+ * The hexadecimal version of the role color, with a leading hashtag
+ * @type {string}
+ * @readonly
+ */
+ get hexColor() {
+ let col = this.color.toString(16);
+ while (col.length < 6) col = `0${col}`;
+ return `#${col}`;
+ }
+
+ /**
+ * The cached guild members that have this role
+ * @type {Collection}
+ * @readonly
+ */
+ get members() {
+ return this.guild.members.filter(m => m.roles.has(this.id));
+ }
+
+ /**
+ * Whether the role is editable by the client user
+ * @type {boolean}
+ * @readonly
+ */
+ get editable() {
+ if (this.managed) return false;
+ const clientMember = this.guild.member(this.client.user);
+ if (!clientMember.permissions.has(Permissions.FLAGS.MANAGE_ROLES_OR_PERMISSIONS)) return false;
+ return clientMember.highestRole.comparePositionTo(this) > 0;
+ }
+
+ /**
+ * The position of the role in the role manager
+ * @type {number}
+ * @readonly
+ */
+ get calculatedPosition() {
+ const sorted = this.guild._sortedRoles;
+ return sorted.array().indexOf(sorted.get(this.id));
+ }
+
+ /**
+ * Get an object mapping permission names to whether or not the role enables that permission
+ * @returns {Object}
+ * @example
+ * // Print the serialized role permissions
+ * console.log(role.serialize());
+ */
+ serialize() {
+ return new Permissions(this.permissions).serialize();
+ }
+
+ /**
+ * Checks if the role has a permission.
+ * @param {PermissionResolvable|PermissionResolvable[]} permission Permission(s) to check for
+ * @param {boolean} [explicit=false] Whether to require the role to explicitly have the exact permission
+ * **(deprecated)**
+ * @param {boolean} [checkAdmin] Whether to allow the administrator permission to override
+ * (takes priority over `explicit`)
+ * @returns {boolean}
+ * @example
+ * // See if a role can ban a member
+ * if (role.hasPermission('BAN_MEMBERS')) {
+ * console.log('This role can ban members');
+ * } else {
+ * console.log('This role can\'t ban members');
+ * }
+ */
+ hasPermission(permission, explicit = false, checkAdmin) {
+ return new Permissions(this.permissions).has(
+ permission, typeof checkAdmin !== 'undefined' ? checkAdmin : !explicit
+ );
+ }
+
+ /**
+ * Checks if the role has all specified permissions.
+ * @param {PermissionResolvable[]} permissions The permissions to check for
+ * @param {boolean} [explicit=false] Whether to require the role to explicitly have the exact permissions
+ * @returns {boolean}
+ * @deprecated
+ */
+ hasPermissions(permissions, explicit = false) {
+ return new Permissions(this.permissions).has(permissions, !explicit);
+ }
+
+ /**
+ * Compares this role's position to another role's.
+ * @param {Role} role Role to compare to this one
+ * @returns {number} Negative number if the this role's position is lower (other role's is higher),
+ * positive number if the this one is higher (other's is lower), 0 if equal
+ */
+ comparePositionTo(role) {
+ return this.constructor.comparePositions(this, role);
+ }
+
+ /**
+ * The data for a role.
+ * @typedef {Object} RoleData
+ * @property {string} [name] The name of the role
+ * @property {ColorResolvable} [color] The color of the role, either a hex string or a base 10 number
+ * @property {boolean} [hoist] Whether or not the role should be hoisted
+ * @property {number} [position] The position of the role
+ * @property {string[]} [permissions] The permissions of the role
+ * @property {boolean} [mentionable] Whether or not the role should be mentionable
+ */
+
+ /**
+ * Edits the role.
+ * @param {RoleData} data The new data for the role
+ * @returns {Promise}
+ * @example
+ * // Edit a role
+ * role.edit({name: 'new role'})
+ * .then(r => console.log(`Edited role ${r}`))
+ * .catch(console.error);
+ */
+ edit(data) {
+ return this.client.rest.methods.updateGuildRole(this, data);
+ }
+
+ /**
+ * Set a new name for the role.
+ * @param {string} name The new name of the role
+ * @returns {Promise}
+ * @example
+ * // Set the name of the role
+ * role.setName('new role')
+ * .then(r => console.log(`Edited name of role ${r}`))
+ * .catch(console.error);
+ */
+ setName(name) {
+ return this.edit({ name });
+ }
+
+ /**
+ * Set a new color for the role.
+ * @param {ColorResolvable} color The color of the role
+ * @returns {Promise}
+ * @example
+ * // Set the color of a role
+ * role.setColor('#FF0000')
+ * .then(r => console.log(`Set color of role ${r}`))
+ * .catch(console.error);
+ */
+ setColor(color) {
+ return this.edit({ color });
+ }
+
+ /**
+ * Set whether or not the role should be hoisted.
+ * @param {boolean} hoist Whether or not to hoist the role
+ * @returns {Promise}
+ * @example
+ * // Set the hoist of the role
+ * role.setHoist(true)
+ * .then(r => console.log(`Role hoisted: ${r.hoist}`))
+ * .catch(console.error);
+ */
+ setHoist(hoist) {
+ return this.edit({ hoist });
+ }
+
+ /**
+ * Set the position of the role.
+ * @param {number} position The position of the role
+ * @param {boolean} [relative=false] Move the position relative to its current value
+ * @returns {Promise}
+ * @example
+ * // Set the position of the role
+ * role.setPosition(1)
+ * .then(r => console.log(`Role position: ${r.position}`))
+ * .catch(console.error);
+ */
+ setPosition(position, relative) {
+ return this.guild.setRolePosition(this, position, relative).then(() => this);
+ }
+
+ /**
+ * Set the permissions of the role.
+ * @param {string[]} permissions The permissions of the role
+ * @returns {Promise}
+ * @example
+ * // Set the permissions of the role
+ * role.setPermissions(['KICK_MEMBERS', 'BAN_MEMBERS'])
+ * .then(r => console.log(`Role updated ${r}`))
+ * .catch(console.error);
+ */
+ setPermissions(permissions) {
+ return this.edit({ permissions });
+ }
+
+ /**
+ * Set whether this role is mentionable.
+ * @param {boolean} mentionable Whether this role should be mentionable
+ * @returns {Promise}
+ * @example
+ * // Make the role mentionable
+ * role.setMentionable(true)
+ * .then(r => console.log(`Role updated ${r}`))
+ * .catch(console.error);
+ */
+ setMentionable(mentionable) {
+ return this.edit({ mentionable });
+ }
+
+ /**
+ * Deletes the role.
+ * @returns {Promise}
+ * @example
+ * // Delete a role
+ * role.delete()
+ * .then(r => console.log(`Deleted role ${r}`))
+ * .catch(console.error);
+ */
+ delete() {
+ return this.client.rest.methods.deleteGuildRole(this);
+ }
+
+ /**
+ * Whether this role equals another role. It compares all properties, so for most operations
+ * it is advisable to just compare `role.id === role2.id` as it is much faster and is often
+ * what most users need.
+ * @param {Role} role Role to compare with
+ * @returns {boolean}
+ */
+ equals(role) {
+ return role &&
+ this.id === role.id &&
+ this.name === role.name &&
+ this.color === role.color &&
+ this.hoist === role.hoist &&
+ this.position === role.position &&
+ this.permissions === role.permissions &&
+ this.managed === role.managed;
+ }
+
+ /**
+ * When concatenated with a string, this automatically concatenates the role mention rather than the Role object.
+ * @returns {string}
+ */
+ toString() {
+ if (this.id === this.guild.id) return '@everyone';
+ return `<@&${this.id}>`;
+ }
+
+ /**
+ * Compares the positions of two roles.
+ * @param {Role} role1 First role to compare
+ * @param {Role} role2 Second role to compare
+ * @returns {number} Negative number if the first role's position is lower (second role's is higher),
+ * positive number if the first's is higher (second's is lower), 0 if equal
+ */
+ static comparePositions(role1, role2) {
+ if (role1.position === role2.position) return role2.id - role1.id;
+ return role1.position - role2.position;
+ }
+}
+
+Role.prototype.hasPermissions = util
+ .deprecate(Role.prototype.hasPermissions,
+ 'Role#hasPermissions is deprecated - use Role#hasPermission instead, it now takes an array');
+
+module.exports = Role;
+
+
+/***/ }),
+/* 16 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const TextBasedChannel = __webpack_require__(23);
+const Constants = __webpack_require__(0);
+const Presence = __webpack_require__(11).Presence;
+const Snowflake = __webpack_require__(7);
+
+/**
+ * Represents a user on Discord.
+ * @implements {TextBasedChannel}
+ */
+class User {
+ constructor(client, data) {
+ /**
+ * The client that created the instance of the the user
+ * @name User#client
+ * @type {}
+ * @readonly
+ */
+ Object.defineProperty(this, 'client', { value: client });
+
+ if (data) this.setup(data);
+ }
+
+ setup(data) {
+ /**
+ * The ID of the user
+ * @type {Snowflake}
+ */
+ this.id = data.id;
+
+ /**
+ * The username of the user
+ * @type {string}
+ */
+ this.username = data.username;
+
+ /**
+ * A discriminator based on username for the user
+ * @type {string}
+ */
+ this.discriminator = data.discriminator;
+
+ /**
+ * The ID of the user's avatar
+ * @type {string}
+ */
+ this.avatar = data.avatar;
+
+ /**
+ * Whether or not the user is a bot
+ * @type {boolean}
+ */
+ this.bot = Boolean(data.bot);
+
+ /**
+ * The ID of the last message sent by the user, if one was sent
+ * @type {?Snowflake}
+ */
+ this.lastMessageID = null;
+
+ /**
+ * The Message object of the last message sent by the user, if one was sent
+ * @type {?Message}
+ */
+ this.lastMessage = null;
+ }
+
+ patch(data) {
+ for (const prop of ['id', 'username', 'discriminator', 'avatar', 'bot']) {
+ if (typeof data[prop] !== 'undefined') this[prop] = data[prop];
+ }
+ if (data.token) this.client.token = data.token;
+ }
+
+ /**
+ * The timestamp the user was created at
+ * @type {number}
+ * @readonly
+ */
+ get createdTimestamp() {
+ return Snowflake.deconstruct(this.id).timestamp;
+ }
+
+ /**
+ * The time the user was created
+ * @type {Date}
+ * @readonly
+ */
+ get createdAt() {
+ return new Date(this.createdTimestamp);
+ }
+
+ /**
+ * The presence of this user
+ * @type {Presence}
+ * @readonly
+ */
+ get presence() {
+ if (this.client.presences.has(this.id)) return this.client.presences.get(this.id);
+ for (const guild of this.client.guilds.values()) {
+ if (guild.presences.has(this.id)) return guild.presences.get(this.id);
+ }
+ return new Presence();
+ }
+
+ /**
+ * A link to the user's avatar
+ * @type {?string}
+ * @readonly
+ */
+ get avatarURL() {
+ if (!this.avatar) return null;
+ return Constants.Endpoints.User(this).Avatar(this.client.options.http.cdn, this.avatar);
+ }
+
+ /**
+ * A link to the user's default avatar
+ * @type {string}
+ * @readonly
+ */
+ get defaultAvatarURL() {
+ const avatars = Object.keys(Constants.DefaultAvatars);
+ const avatar = avatars[this.discriminator % avatars.length];
+ return Constants.Endpoints.CDN(this.client.options.http.host).Asset(`${Constants.DefaultAvatars[avatar]}.png`);
+ }
+
+ /**
+ * A link to the user's avatar if they have one. Otherwise a link to their default avatar will be returned
+ * @type {string}
+ * @readonly
+ */
+ get displayAvatarURL() {
+ return this.avatarURL || this.defaultAvatarURL;
+ }
+
+ /**
+ * The Discord "tag" for this user
+ * @type {string}
+ * @readonly
+ */
+ get tag() {
+ return `${this.username}#${this.discriminator}`;
+ }
+
+ /**
+ * The note that is set for the user
+ * This is only available when using a user account.
+ * @type {?string}
+ * @readonly
+ */
+ get note() {
+ return this.client.user.notes.get(this.id) || null;
+ }
+
+ /**
+ * Check whether the user is typing in a channel.
+ * @param {ChannelResolvable} channel The channel to check in
+ * @returns {boolean}
+ */
+ typingIn(channel) {
+ channel = this.client.resolver.resolveChannel(channel);
+ return channel._typing.has(this.id);
+ }
+
+ /**
+ * Get the time that the user started typing.
+ * @param {ChannelResolvable} channel The channel to get the time in
+ * @returns {?Date}
+ */
+ typingSinceIn(channel) {
+ channel = this.client.resolver.resolveChannel(channel);
+ return channel._typing.has(this.id) ? new Date(channel._typing.get(this.id).since) : null;
+ }
+
+ /**
+ * Get the amount of time the user has been typing in a channel for (in milliseconds), or -1 if they're not typing.
+ * @param {ChannelResolvable} channel The channel to get the time in
+ * @returns {number}
+ */
+ typingDurationIn(channel) {
+ channel = this.client.resolver.resolveChannel(channel);
+ return channel._typing.has(this.id) ? channel._typing.get(this.id).elapsedTime : -1;
+ }
+
+ /**
+ * The DM between the client's user and this user
+ * @type {?DMChannel}
+ * @readonly
+ */
+ get dmChannel() {
+ return this.client.channels.filter(c => c.type === 'dm').find(c => c.recipient.id === this.id);
+ }
+
+ /**
+ * Creates a DM channel between the client and the user.
+ * @returns {Promise}
+ */
+ createDM() {
+ return this.client.rest.methods.createDM(this);
+ }
+
+ /**
+ * Deletes a DM channel (if one exists) between the client and the user. Resolves with the channel if successful.
+ * @returns {Promise}
+ */
+ deleteDM() {
+ return this.client.rest.methods.deleteChannel(this);
+ }
+
+ /**
+ * Sends a friend request to the user.
+ * This is only available when using a user account.
+ * @returns {Promise}
+ */
+ addFriend() {
+ return this.client.rest.methods.addFriend(this);
+ }
+
+ /**
+ * Removes the user from your friends.
+ * This is only available when using a user account.
+ * @returns {Promise}
+ */
+ removeFriend() {
+ return this.client.rest.methods.removeFriend(this);
+ }
+
+ /**
+ * Blocks the user.
+ * This is only available when using a user account.
+ * @returns {Promise}
+ */
+ block() {
+ return this.client.rest.methods.blockUser(this);
+ }
+
+ /**
+ * Unblocks the user.
+ * This is only available when using a user account.
+ * @returns {Promise}
+ */
+ unblock() {
+ return this.client.rest.methods.unblockUser(this);
+ }
+
+ /**
+ * Get the profile of the user.
+ * This is only available when using a user account.
+ * @returns {Promise}
+ */
+ fetchProfile() {
+ return this.client.rest.methods.fetchUserProfile(this);
+ }
+
+ /**
+ * Sets a note for the user.
+ * This is only available when using a user account.
+ * @param {string} note The note to set for the user
+ * @returns {Promise}
+ */
+ setNote(note) {
+ return this.client.rest.methods.setNote(this, note);
+ }
+
+ /**
+ * Checks if the user is equal to another. It compares ID, username, discriminator, avatar, and bot flags.
+ * It is recommended to compare equality by using `user.id === user2.id` unless you want to compare all properties.
+ * @param {User} user User to compare with
+ * @returns {boolean}
+ */
+ equals(user) {
+ let equal = user &&
+ this.id === user.id &&
+ this.username === user.username &&
+ this.discriminator === user.discriminator &&
+ this.avatar === user.avatar &&
+ this.bot === Boolean(user.bot);
+
+ return equal;
+ }
+
+ /**
+ * When concatenated with a string, this automatically concatenates the user's mention instead of the User object.
+ * @returns {string}
+ * @example
+ * // logs: Hello from <@123456789>!
+ * console.log(`Hello from ${user}!`);
+ */
+ toString() {
+ return `<@${this.id}>`;
+ }
+
+ // These are here only for documentation purposes - they are implemented by TextBasedChannel
+ /* eslint-disable no-empty-function */
+ send() {}
+ sendMessage() {}
+ sendEmbed() {}
+ sendFile() {}
+ sendCode() {}
+}
+
+TextBasedChannel.applyToClass(User);
+
+module.exports = User;
+
+
+/***/ }),
+/* 17 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Constants = __webpack_require__(0);
+const Collection = __webpack_require__(3);
+const Snowflake = __webpack_require__(7);
+
+/**
+ * Represents a custom emoji.
+ */
+class Emoji {
+ constructor(guild, data) {
+ /**
+ * The client that instantiated this object
+ * @name Emoji#client
+ * @type {Client}
+ * @readonly
+ */
+ Object.defineProperty(this, 'client', { value: guild.client });
+
+ /**
+ * The guild this emoji is part of
+ * @type {Guild}
+ */
+ this.guild = guild;
+
+ this.setup(data);
+ }
+
+ setup(data) {
+ /**
+ * The ID of the emoji
+ * @type {Snowflake}
+ */
+ this.id = data.id;
+
+ /**
+ * The name of the emoji
+ * @type {string}
+ */
+ this.name = data.name;
+
+ /**
+ * Whether or not this emoji requires colons surrounding it
+ * @type {boolean}
+ */
+ this.requiresColons = data.require_colons;
+
+ /**
+ * Whether this emoji is managed by an external service
+ * @type {boolean}
+ */
+ this.managed = data.managed;
+
+ this._roles = data.roles;
+ }
+
+ /**
+ * The timestamp the emoji was created at
+ * @type {number}
+ * @readonly
+ */
+ get createdTimestamp() {
+ return Snowflake.deconstruct(this.id).timestamp;
+ }
+
+ /**
+ * The time the emoji was created
+ * @type {Date}
+ * @readonly
+ */
+ get createdAt() {
+ return new Date(this.createdTimestamp);
+ }
+
+ /**
+ * A collection of roles this emoji is active for (empty if all), mapped by role ID
+ * @type {Collection}
+ * @readonly
+ */
+ get roles() {
+ const roles = new Collection();
+ for (const role of this._roles) {
+ if (this.guild.roles.has(role)) roles.set(role, this.guild.roles.get(role));
+ }
+ return roles;
+ }
+
+ /**
+ * The URL to the emoji file
+ * @type {string}
+ * @readonly
+ */
+ get url() {
+ return Constants.Endpoints.CDN(this.client.options.http.cdn).Emoji(this.id);
+ }
+
+ /**
+ * The identifier of this emoji, used for message reactions
+ * @type {string}
+ * @readonly
+ */
+ get identifier() {
+ if (this.id) return `${this.name}:${this.id}`;
+ return encodeURIComponent(this.name);
+ }
+
+ /**
+ * Data for editing an emoji.
+ * @typedef {Object} EmojiEditData
+ * @property {string} [name] The name of the emoji
+ * @property {Collection|Array} [roles] Roles to restrict emoji to
+ */
+
+ /**
+ * Edits the emoji.
+ * @param {EmojiEditData} data The new data for the emoji
+ * @returns {Promise}
+ * @example
+ * // Edit a emoji
+ * emoji.edit({name: 'newemoji'})
+ * .then(e => console.log(`Edited emoji ${e}`))
+ * .catch(console.error);
+ */
+ edit(data) {
+ return this.client.rest.methods.updateEmoji(this, data);
+ }
+
+ /**
+ * Set the name of the emoji.
+ * @param {string} name The new name for the emoji
+ * @returns {Promise}
+ */
+ setName(name) {
+ return this.edit({ name });
+ }
+
+ /**
+ * Add a role to the list of roles that can use this emoji.
+ * @param {Role} role The role to add
+ * @returns {Promise}
+ */
+ addRestrictedRole(role) {
+ return this.addRestrictedRoles([role]);
+ }
+
+ /**
+ * Add multiple roles to the list of roles that can use this emoji.
+ * @param {Role[]} roles Roles to add
+ * @returns {Promise}
+ */
+ addRestrictedRoles(roles) {
+ const newRoles = new Collection(this.roles);
+ for (const role of roles) {
+ if (this.guild.roles.has(role.id)) newRoles.set(role.id, role);
+ }
+ return this.edit({ roles: newRoles });
+ }
+
+ /**
+ * Remove a role from the list of roles that can use this emoji.
+ * @param {Role} role The role to remove
+ * @returns {Promise}
+ */
+ removeRestrictedRole(role) {
+ return this.removeRestrictedRoles([role]);
+ }
+
+ /**
+ * Remove multiple roles from the list of roles that can use this emoji.
+ * @param {Role[]} roles Roles to remove
+ * @returns {Promise}
+ */
+ removeRestrictedRoles(roles) {
+ const newRoles = new Collection(this.roles);
+ for (const role of roles) {
+ if (newRoles.has(role.id)) newRoles.delete(role.id);
+ }
+ return this.edit({ roles: newRoles });
+ }
+
+ /**
+ * When concatenated with a string, this automatically returns the emoji mention rather than the object.
+ * @returns {string}
+ * @example
+ * // Send an emoji:
+ * const emoji = guild.emojis.first();
+ * msg.reply(`Hello! ${emoji}`);
+ */
+ toString() {
+ return this.requiresColons ? `<:${this.name}:${this.id}>` : this.name;
+ }
+
+ /**
+ * Whether this emoji is the same as another one.
+ * @param {Emoji|Object} other The emoji to compare it to
+ * @returns {boolean} Whether the emoji is equal to the given emoji or not
+ */
+ equals(other) {
+ if (other instanceof Emoji) {
+ return (
+ other.id === this.id &&
+ other.name === this.name &&
+ other.managed === this.managed &&
+ other.requiresColons === this.requiresColons
+ );
+ } else {
+ return (
+ other.id === this.id &&
+ other.name === this.name
+ );
+ }
+ }
+}
+
+module.exports = Emoji;
+
+
+/***/ }),
+/* 18 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const TextBasedChannel = __webpack_require__(23);
+const Role = __webpack_require__(15);
+const Permissions = __webpack_require__(9);
+const Collection = __webpack_require__(3);
+const Presence = __webpack_require__(11).Presence;
+const util = __webpack_require__(22);
+
+/**
+ * Represents a member of a guild on Discord.
+ * @implements {TextBasedChannel}
+ */
+class GuildMember {
+ constructor(guild, data) {
+ /**
+ * The client that instantiated this GuildMember
+ * @name GuildMember#client
+ * @type {Client}
+ * @readonly
+ */
+ Object.defineProperty(this, 'client', { value: guild.client });
+
+ /**
+ * The guild that this member is part of
+ * @type {Guild}
+ */
+ this.guild = guild;
+
+ /**
+ * The user that this guild member instance Represents
+ * @type {User}
+ */
+ this.user = {};
+
+ this._roles = [];
+ if (data) this.setup(data);
+
+ /**
+ * The ID of the last message sent by the member in their guild, if one was sent
+ * @type {?Snowflake}
+ */
+ this.lastMessageID = null;
+
+ /**
+ * The Message object of the last message sent by the member in their guild, if one was sent
+ * @type {?Message}
+ */
+ this.lastMessage = null;
+ }
+
+ setup(data) {
+ /**
+ * Whether this member is deafened server-wide
+ * @type {boolean}
+ */
+ this.serverDeaf = data.deaf;
+
+ /**
+ * Whether this member is muted server-wide
+ * @type {boolean}
+ */
+ this.serverMute = data.mute;
+
+ /**
+ * Whether this member is self-muted
+ * @type {boolean}
+ */
+ this.selfMute = data.self_mute;
+
+ /**
+ * Whether this member is self-deafened
+ * @type {boolean}
+ */
+ this.selfDeaf = data.self_deaf;
+
+ /**
+ * The voice session ID of this member, if any
+ * @type {?Snowflake}
+ */
+ this.voiceSessionID = data.session_id;
+
+ /**
+ * The voice channel ID of this member, if any
+ * @type {?Snowflake}
+ */
+ this.voiceChannelID = data.channel_id;
+
+ /**
+ * Whether this member is speaking
+ * @type {boolean}
+ */
+ this.speaking = false;
+
+ /**
+ * The nickname of this guild member, if they have one
+ * @type {?string}
+ */
+ this.nickname = data.nick || null;
+
+ /**
+ * The timestamp the member joined the guild at
+ * @type {number}
+ */
+ this.joinedTimestamp = new Date(data.joined_at).getTime();
+
+ this.user = data.user;
+ this._roles = data.roles;
+ }
+
+ /**
+ * The time the member joined the guild
+ * @type {Date}
+ * @readonly
+ */
+ get joinedAt() {
+ return new Date(this.joinedTimestamp);
+ }
+
+ /**
+ * The presence of this guild member
+ * @type {Presence}
+ * @readonly
+ */
+ get presence() {
+ return this.frozenPresence || this.guild.presences.get(this.id) || new Presence();
+ }
+
+ /**
+ * A list of roles that are applied to this GuildMember, mapped by the role ID
+ * @type {Collection}
+ * @readonly
+ */
+ get roles() {
+ const list = new Collection();
+ const everyoneRole = this.guild.roles.get(this.guild.id);
+
+ if (everyoneRole) list.set(everyoneRole.id, everyoneRole);
+
+ for (const roleID of this._roles) {
+ const role = this.guild.roles.get(roleID);
+ if (role) list.set(role.id, role);
+ }
+
+ return list;
+ }
+
+ /**
+ * The role of the member with the highest position
+ * @type {Role}
+ * @readonly
+ */
+ get highestRole() {
+ return this.roles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev);
+ }
+
+ /**
+ * The role of the member used to set their color
+ * @type {?Role}
+ * @readonly
+ */
+ get colorRole() {
+ const coloredRoles = this.roles.filter(role => role.color);
+ if (!coloredRoles.size) return null;
+ return coloredRoles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev);
+ }
+
+ /**
+ * The displayed color of the member in base 10
+ * @type {number}
+ * @readonly
+ */
+ get displayColor() {
+ const role = this.colorRole;
+ return (role && role.color) || 0;
+ }
+
+ /**
+ * The displayed color of the member in hexadecimal
+ * @type {string}
+ * @readonly
+ */
+ get displayHexColor() {
+ const role = this.colorRole;
+ return (role && role.hexColor) || '#000000';
+ }
+
+ /**
+ * The role of the member used to hoist them in a separate category in the users list
+ * @type {?Role}
+ * @readonly
+ */
+ get hoistRole() {
+ const hoistedRoles = this.roles.filter(role => role.hoist);
+ if (!hoistedRoles.size) return null;
+ return hoistedRoles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev);
+ }
+
+ /**
+ * Whether this member is muted in any way
+ * @type {boolean}
+ * @readonly
+ */
+ get mute() {
+ return this.selfMute || this.serverMute;
+ }
+
+ /**
+ * Whether this member is deafened in any way
+ * @type {boolean}
+ * @readonly
+ */
+ get deaf() {
+ return this.selfDeaf || this.serverDeaf;
+ }
+
+ /**
+ * The voice channel this member is in, if any
+ * @type {?VoiceChannel}
+ * @readonly
+ */
+ get voiceChannel() {
+ return this.guild.channels.get(this.voiceChannelID);
+ }
+
+ /**
+ * The ID of this user
+ * @type {Snowflake}
+ * @readonly
+ */
+ get id() {
+ return this.user.id;
+ }
+
+ /**
+ * The nickname of the member, or their username if they don't have one
+ * @type {string}
+ * @readonly
+ */
+ get displayName() {
+ return this.nickname || this.user.username;
+ }
+
+ /**
+ * The overall set of permissions for the guild member, taking only roles into account
+ * @type {Permissions}
+ * @readonly
+ */
+ get permissions() {
+ if (this.user.id === this.guild.ownerID) return new Permissions(this, Permissions.ALL);
+
+ let permissions = 0;
+ const roles = this.roles;
+ for (const role of roles.values()) permissions |= role.permissions;
+
+ return new Permissions(this, permissions);
+ }
+
+ /**
+ * Whether the member is kickable by the client user
+ * @type {boolean}
+ * @readonly
+ */
+ get kickable() {
+ if (this.user.id === this.guild.ownerID) return false;
+ if (this.user.id === this.client.user.id) return false;
+ const clientMember = this.guild.member(this.client.user);
+ if (!clientMember.permissions.has(Permissions.FLAGS.KICK_MEMBERS)) return false;
+ return clientMember.highestRole.comparePositionTo(this.highestRole) > 0;
+ }
+
+ /**
+ * Whether the member is bannable by the client user
+ * @type {boolean}
+ * @readonly
+ */
+ get bannable() {
+ if (this.user.id === this.guild.ownerID) return false;
+ if (this.user.id === this.client.user.id) return false;
+ const clientMember = this.guild.member(this.client.user);
+ if (!clientMember.permissions.has(Permissions.FLAGS.BAN_MEMBERS)) return false;
+ return clientMember.highestRole.comparePositionTo(this.highestRole) > 0;
+ }
+
+ /**
+ * Returns `channel.permissionsFor(guildMember)`. Returns permissions for a member in a guild channel,
+ * taking into account roles and permission overwrites.
+ * @param {ChannelResolvable} channel The guild channel to use as context
+ * @returns {?Permissions}
+ */
+ permissionsIn(channel) {
+ channel = this.client.resolver.resolveChannel(channel);
+ if (!channel || !channel.guild) throw new Error('Could not resolve channel to a guild channel.');
+ return channel.permissionsFor(this);
+ }
+
+ /**
+ * Checks if any of the member's roles have a permission.
+ * @param {PermissionResolvable|PermissionResolvable[]} permission Permission(s) to check for
+ * @param {boolean} [explicit=false] Whether to require the role to explicitly have the exact permission
+ * **(deprecated)**
+ * @param {boolean} [checkAdmin] Whether to allow the administrator permission to override
+ * (takes priority over `explicit`)
+ * @param {boolean} [checkOwner] Whether to allow being the guild's owner to override
+ * (takes priority over `explicit`)
+ * @returns {boolean}
+ */
+ hasPermission(permission, explicit = false, checkAdmin, checkOwner) {
+ if (typeof checkAdmin === 'undefined') checkAdmin = !explicit;
+ if (typeof checkOwner === 'undefined') checkOwner = !explicit;
+ if (checkOwner && this.user.id === this.guild.ownerID) return true;
+ return this.roles.some(r => r.hasPermission(permission, undefined, checkAdmin));
+ }
+
+ /**
+ * Checks whether the roles of the member allows them to perform specific actions.
+ * @param {PermissionResolvable[]} permissions The permissions to check for
+ * @param {boolean} [explicit=false] Whether to require the member to explicitly have the exact permissions
+ * @returns {boolean}
+ * @deprecated
+ */
+ hasPermissions(permissions, explicit = false) {
+ if (!explicit && this.user.id === this.guild.ownerID) return true;
+ return this.hasPermission(permissions, explicit);
+ }
+
+ /**
+ * Checks whether the roles of the member allows them to perform specific actions, and lists any missing permissions.
+ * @param {PermissionResolvable[]} permissions The permissions to check for
+ * @param {boolean} [explicit=false] Whether to require the member to explicitly have the exact permissions
+ * @returns {PermissionResolvable[]}
+ */
+ missingPermissions(permissions, explicit = false) {
+ return permissions.missing(permissions, explicit);
+ }
+
+ /**
+ * The data for editing a guild member.
+ * @typedef {Object} GuildMemberEditData
+ * @property {string} [nick] The nickname to set for the member
+ * @property {Collection|Role[]|Snowflake[]} [roles] The roles or role IDs to apply
+ * @property {boolean} [mute] Whether or not the member should be muted
+ * @property {boolean} [deaf] Whether or not the member should be deafened
+ * @property {ChannelResolvable} [channel] Channel to move member to (if they are connected to voice)
+ */
+
+ /**
+ * Edit a guild member.
+ * @param {GuildMemberEditData} data The data to edit the member with
+ * @returns {Promise}
+ */
+ edit(data) {
+ return this.client.rest.methods.updateGuildMember(this, data);
+ }
+
+ /**
+ * Mute/unmute a user.
+ * @param {boolean} mute Whether or not the member should be muted
+ * @returns {Promise}
+ */
+ setMute(mute) {
+ return this.edit({ mute });
+ }
+
+ /**
+ * Deafen/undeafen a user.
+ * @param {boolean} deaf Whether or not the member should be deafened
+ * @returns {Promise}
+ */
+ setDeaf(deaf) {
+ return this.edit({ deaf });
+ }
+
+ /**
+ * Moves the guild member to the given channel.
+ * @param {ChannelResolvable} channel The channel to move the member to
+ * @returns {Promise}
+ */
+ setVoiceChannel(channel) {
+ return this.edit({ channel });
+ }
+
+ /**
+ * Sets the roles applied to the member.
+ * @param {Collection|Role[]|Snowflake[]} roles The roles or role IDs to apply
+ * @returns {Promise}
+ */
+ setRoles(roles) {
+ return this.edit({ roles });
+ }
+
+ /**
+ * Adds a single role to the member.
+ * @param {Role|Snowflake} role The role or ID of the role to add
+ * @returns {Promise}
+ */
+ addRole(role) {
+ if (!(role instanceof Role)) role = this.guild.roles.get(role);
+ if (!role) throw new TypeError('Supplied parameter was neither a Role nor a Snowflake.');
+ return this.client.rest.methods.addMemberRole(this, role);
+ }
+
+ /**
+ * Adds multiple roles to the member.
+ * @param {Collection|Role[]|Snowflake[]} roles The roles or role IDs to add
+ * @returns {Promise}
+ */
+ addRoles(roles) {
+ let allRoles;
+ if (roles instanceof Collection) {
+ allRoles = this._roles.slice();
+ for (const role of roles.values()) allRoles.push(role.id);
+ } else {
+ allRoles = this._roles.concat(roles);
+ }
+ return this.edit({ roles: allRoles });
+ }
+
+ /**
+ * Removes a single role from the member.
+ * @param {Role|Snowflake} role The role or ID of the role to remove
+ * @returns {Promise}
+ */
+ removeRole(role) {
+ if (!(role instanceof Role)) role = this.guild.roles.get(role);
+ if (!role) throw new TypeError('Supplied parameter was neither a Role nor a Snowflake.');
+ return this.client.rest.methods.removeMemberRole(this, role);
+ }
+
+ /**
+ * Removes multiple roles from the member.
+ * @param {Collection|Role[]|Snowflake[]} roles The roles or role IDs to remove
+ * @returns {Promise}
+ */
+ removeRoles(roles) {
+ const allRoles = this._roles.slice();
+ if (roles instanceof Collection) {
+ for (const role of roles.values()) {
+ const index = allRoles.indexOf(role.id);
+ if (index >= 0) allRoles.splice(index, 1);
+ }
+ } else {
+ for (const role of roles) {
+ const index = allRoles.indexOf(role instanceof Role ? role.id : role);
+ if (index >= 0) allRoles.splice(index, 1);
+ }
+ }
+ return this.edit({ roles: allRoles });
+ }
+
+ /**
+ * Set the nickname for the guild member.
+ * @param {string} nick The nickname for the guild member
+ * @returns {Promise}
+ */
+ setNickname(nick) {
+ return this.edit({ nick });
+ }
+
+ /**
+ * Creates a DM channel between the client and the member.
+ * @returns {Promise}
+ */
+ createDM() {
+ return this.user.createDM();
+ }
+
+ /**
+ * Deletes any DMs with this guild member.
+ * @returns {Promise}
+ */
+ deleteDM() {
+ return this.user.deleteDM();
+ }
+
+ /**
+ * Kick this member from the guild.
+ * @param {string} [reason] Reason for kicking user
+ * @returns {Promise}
+ */
+ kick(reason) {
+ return this.client.rest.methods.kickGuildMember(this.guild, this, reason);
+ }
+
+ /**
+ * Ban this guild member
+ * @param {Object|number|string} [options] Ban options. If a number, the number of days to delete messages for, if a
+ * string, the ban reason. Supplying an object allows you to do both.
+ * @param {number} [options.days=0] Number of days of messages to delete
+ * @param {string} [options.reason] Reason for banning
+ * @returns {Promise}
+ * @example
+ * // ban a guild member
+ * guildMember.ban(7);
+ */
+ ban(options) {
+ return this.guild.ban(this, options);
+ }
+
+ /**
+ * When concatenated with a string, this automatically concatenates the user's mention instead of the Member object.
+ * @returns {string}
+ * @example
+ * // Logs: Hello from <@123456789>!
+ * console.log(`Hello from ${member}!`);
+ */
+ toString() {
+ return `<@${this.nickname ? '!' : ''}${this.user.id}>`;
+ }
+
+ // These are here only for documentation purposes - they are implemented by TextBasedChannel
+ /* eslint-disable no-empty-function */
+ send() {}
+ sendMessage() {}
+ sendEmbed() {}
+ sendFile() {}
+ sendCode() {}
+}
+
+TextBasedChannel.applyToClass(GuildMember);
+
+GuildMember.prototype.hasPermissions = util.deprecate(GuildMember.prototype.hasPermissions,
+ 'GuildMember#hasPermissions is deprecated - use GuildMember#hasPermission, it now takes an array');
+
+module.exports = GuildMember;
+
+
+/***/ }),
+/* 19 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Mentions = __webpack_require__(50);
+const Attachment = __webpack_require__(47);
+const Embed = __webpack_require__(49);
+const MessageReaction = __webpack_require__(51);
+const ReactionCollector = __webpack_require__(55);
+const Util = __webpack_require__(4);
+const Collection = __webpack_require__(3);
+const Constants = __webpack_require__(0);
+const Permissions = __webpack_require__(9);
+let GuildMember;
+
+/**
+ * Represents a message on Discord.
+ */
+class Message {
+ constructor(channel, data, client) {
+ /**
+ * The client that instantiated the Message
+ * @name Message#client
+ * @type {Client}
+ * @readonly
+ */
+ Object.defineProperty(this, 'client', { value: client });
+
+ /**
+ * The channel that the message was sent in
+ * @type {TextChannel|DMChannel|GroupDMChannel}
+ */
+ this.channel = channel;
+
+ if (data) this.setup(data);
+ }
+
+ setup(data) { // eslint-disable-line complexity
+ /**
+ * The ID of the message (unique in the channel it was sent)
+ * @type {Snowflake}
+ */
+ this.id = data.id;
+
+ /**
+ * The type of the message
+ * @type {string}
+ */
+ this.type = Constants.MessageTypes[data.type];
+
+ /**
+ * The content of the message
+ * @type {string}
+ */
+ this.content = data.content;
+
+ /**
+ * The author of the message
+ * @type {User}
+ */
+ this.author = this.client.dataManager.newUser(data.author);
+
+ /**
+ * Represents the author of the message as a guild member. Only available if the message comes from a guild
+ * where the author is still a member.
+ * @type {?GuildMember}
+ */
+ this.member = this.guild ? this.guild.member(this.author) || null : null;
+
+ /**
+ * Whether or not this message is pinned
+ * @type {boolean}
+ */
+ this.pinned = data.pinned;
+
+ /**
+ * Whether or not the message was Text-To-Speech
+ * @type {boolean}
+ */
+ this.tts = data.tts;
+
+ /**
+ * A random number or string used for checking message delivery
+ * @type {string}
+ */
+ this.nonce = data.nonce;
+
+ /**
+ * Whether or not this message was sent by Discord, not actually a user (e.g. pin notifications)
+ * @type {boolean}
+ */
+ this.system = data.type === 6;
+
+ /**
+ * A list of embeds in the message - e.g. YouTube Player
+ * @type {MessageEmbed[]}
+ */
+ this.embeds = data.embeds.map(e => new Embed(this, e));
+
+ /**
+ * A collection of attachments in the message - e.g. Pictures - mapped by their ID
+ * @type {Collection}
+ */
+ this.attachments = new Collection();
+ for (const attachment of data.attachments) this.attachments.set(attachment.id, new Attachment(this, attachment));
+
+ /**
+ * The timestamp the message was sent at
+ * @type {number}
+ */
+ this.createdTimestamp = new Date(data.timestamp).getTime();
+
+ /**
+ * The timestamp the message was last edited at (if applicable)
+ * @type {?number}
+ */
+ this.editedTimestamp = data.edited_timestamp ? new Date(data.edited_timestamp).getTime() : null;
+
+ /**
+ * A collection of reactions to this message, mapped by the reaction ID
+ * @type {Collection}
+ */
+ this.reactions = new Collection();
+ if (data.reactions && data.reactions.length > 0) {
+ for (const reaction of data.reactions) {
+ const id = reaction.emoji.id ? `${reaction.emoji.name}:${reaction.emoji.id}` : reaction.emoji.name;
+ this.reactions.set(id, new MessageReaction(this, reaction.emoji, reaction.count, reaction.me));
+ }
+ }
+
+ /**
+ * All valid mentions that the message contains
+ * @type {MessageMentions}
+ */
+ this.mentions = new Mentions(this, data.mentions, data.mention_roles, data.mention_everyone);
+
+ /**
+ * ID of the webhook that sent the message, if applicable
+ * @type {?Snowflake}
+ */
+ this.webhookID = data.webhook_id || null;
+
+ /**
+ * Whether this message is a hit in a search
+ * @type {?boolean}
+ */
+ this.hit = typeof data.hit === 'boolean' ? data.hit : null;
+
+ /**
+ * The previous versions of the message, sorted with the most recent first
+ * @type {Message[]}
+ * @private
+ */
+ this._edits = [];
+ }
+
+ /**
+ * Updates the message.
+ * @param {Object} data Raw Discord message update data
+ * @private
+ */
+ patch(data) {
+ const clone = Util.cloneObject(this);
+ this._edits.unshift(clone);
+
+ this.editedTimestamp = new Date(data.edited_timestamp).getTime();
+ if ('content' in data) this.content = data.content;
+ if ('pinned' in data) this.pinned = data.pinned;
+ if ('tts' in data) this.tts = data.tts;
+ if ('embeds' in data) this.embeds = data.embeds.map(e => new Embed(this, e));
+ else this.embeds = this.embeds.slice();
+
+ if ('attachments' in data) {
+ this.attachments = new Collection();
+ for (const attachment of data.attachments) this.attachments.set(attachment.id, new Attachment(this, attachment));
+ } else {
+ this.attachments = new Collection(this.attachments);
+ }
+
+ this.mentions = new Mentions(
+ this,
+ 'mentions' in data ? data.mentions : this.mentions.users,
+ 'mentions_roles' in data ? data.mentions_roles : this.mentions.roles,
+ 'mention_everyone' in data ? data.mention_everyone : this.mentions.everyone
+ );
+ }
+
+ /**
+ * The time the message was sent
+ * @type {Date}
+ * @readonly
+ */
+ get createdAt() {
+ return new Date(this.createdTimestamp);
+ }
+
+ /**
+ * The time the message was last edited at (if applicable)
+ * @type {?Date}
+ * @readonly
+ */
+ get editedAt() {
+ return this.editedTimestamp ? new Date(this.editedTimestamp) : null;
+ }
+
+ /**
+ * The guild the message was sent in (if in a guild channel)
+ * @type {?Guild}
+ * @readonly
+ */
+ get guild() {
+ return this.channel.guild || null;
+ }
+
+ /**
+ * The message contents with all mentions replaced by the equivalent text. If mentions cannot be resolved to a name,
+ * the relevant mention in the message content will not be converted
+ * @type {string}
+ * @readonly
+ */
+ get cleanContent() {
+ return this.content
+ .replace(/@(everyone|here)/g, '@\u200b$1')
+ .replace(/<@!?[0-9]+>/g, input => {
+ const id = input.replace(/<|!|>|@/g, '');
+ if (this.channel.type === 'dm' || this.channel.type === 'group') {
+ return this.client.users.has(id) ? `@${this.client.users.get(id).username}` : input;
+ }
+
+ const member = this.channel.guild.members.get(id);
+ if (member) {
+ if (member.nickname) return `@${member.nickname}`;
+ return `@${member.user.username}`;
+ } else {
+ const user = this.client.users.get(id);
+ if (user) return `@${user.username}`;
+ return input;
+ }
+ })
+ .replace(/<#[0-9]+>/g, input => {
+ const channel = this.client.channels.get(input.replace(/<|#|>/g, ''));
+ if (channel) return `#${channel.name}`;
+ return input;
+ })
+ .replace(/<@&[0-9]+>/g, input => {
+ if (this.channel.type === 'dm' || this.channel.type === 'group') return input;
+ const role = this.guild.roles.get(input.replace(/<|@|>|&/g, ''));
+ if (role) return `@${role.name}`;
+ return input;
+ });
+ }
+
+ /**
+ * Creates a reaction collector.
+ * @param {CollectorFilter} filter The filter to apply
+ * @param {ReactionCollectorOptions} [options={}] Options to send to the collector
+ * @returns {ReactionCollector}
+ * @example
+ * // Create a reaction collector
+ * const collector = message.createReactionCollector(
+ * (reaction, user) => reaction.emoji.id === '👌' && user.id === 'someID',
+ * { time: 15000 }
+ * );
+ * collector.on('collect', r => console.log(`Collected ${r.emoji.name}`));
+ * collector.on('end', collected => console.log(`Collected ${collected.size} items`));
+ */
+ createReactionCollector(filter, options = {}) {
+ return new ReactionCollector(this, filter, options);
+ }
+
+ /**
+ * An object containing the same properties as CollectorOptions, but a few more:
+ * @typedef {ReactionCollectorOptions} AwaitReactionsOptions
+ * @property {string[]} [errors] Stop/end reasons that cause the promise to reject
+ */
+
+ /**
+ * Similar to createCollector but in promise form. Resolves with a collection of reactions that pass the specified
+ * filter.
+ * @param {CollectorFilter} filter The filter function to use
+ * @param {AwaitReactionsOptions} [options={}] Optional options to pass to the internal collector
+ * @returns {Promise>}
+ */
+ awaitReactions(filter, options = {}) {
+ return new Promise((resolve, reject) => {
+ const collector = this.createReactionCollector(filter, options);
+ collector.once('end', (reactions, reason) => {
+ if (options.errors && options.errors.includes(reason)) reject(reactions);
+ else resolve(reactions);
+ });
+ });
+ }
+
+ /**
+ * An array of cached versions of the message, including the current version
+ * Sorted from latest (first) to oldest (last)
+ * @type {Message[]}
+ * @readonly
+ */
+ get edits() {
+ const copy = this._edits.slice();
+ copy.unshift(this);
+ return copy;
+ }
+
+ /**
+ * Whether the message is editable by the client user
+ * @type {boolean}
+ * @readonly
+ */
+ get editable() {
+ return this.author.id === this.client.user.id;
+ }
+
+ /**
+ * Whether the message is deletable by the client user
+ * @type {boolean}
+ * @readonly
+ */
+ get deletable() {
+ return this.author.id === this.client.user.id || (this.guild &&
+ this.channel.permissionsFor(this.client.user).has(Permissions.FLAGS.MANAGE_MESSAGES)
+ );
+ }
+
+ /**
+ * Whether the message is pinnable by the client user
+ * @type {boolean}
+ * @readonly
+ */
+ get pinnable() {
+ return !this.guild ||
+ this.channel.permissionsFor(this.client.user).has(Permissions.FLAGS.MANAGE_MESSAGES);
+ }
+
+ /**
+ * Whether or not a user, channel or role is mentioned in this message.
+ * @param {GuildChannel|User|Role|string} data Either a guild channel, user or a role object, or a string representing
+ * the ID of any of these
+ * @returns {boolean}
+ */
+ isMentioned(data) {
+ data = data && data.id ? data.id : data;
+ return this.mentions.users.has(data) || this.mentions.channels.has(data) || this.mentions.roles.has(data);
+ }
+
+ /**
+ * Whether or not a guild member is mentioned in this message. Takes into account
+ * user mentions, role mentions, and @everyone/@here mentions.
+ * @param {GuildMember|User} member The member/user to check for a mention of
+ * @returns {boolean}
+ */
+ isMemberMentioned(member) {
+ // Lazy-loading is used here to get around a circular dependency that breaks things
+ if (!GuildMember) GuildMember = __webpack_require__(18);
+ if (this.mentions.everyone) return true;
+ if (this.mentions.users.has(member.id)) return true;
+ if (member instanceof GuildMember && member.roles.some(r => this.mentions.roles.has(r.id))) return true;
+ return false;
+ }
+
+ /**
+ * Options that can be passed into editMessage.
+ * @typedef {Object} MessageEditOptions
+ * @property {Object} [embed] An embed to be added/edited
+ * @property {string|boolean} [code] Language for optional codeblock formatting to apply
+ */
+
+ /**
+ * Edit the content of the message.
+ * @param {StringResolvable} [content] The new content for the message
+ * @param {MessageEditOptions} [options] The options to provide
+ * @returns {Promise}
+ * @example
+ * // Update the content of a message
+ * message.edit('This is my new content!')
+ * .then(msg => console.log(`Updated the content of a message from ${msg.author}`))
+ * .catch(console.error);
+ */
+ edit(content, options) {
+ if (!options && typeof content === 'object' && !(content instanceof Array)) {
+ options = content;
+ content = '';
+ } else if (!options) {
+ options = {};
+ }
+ return this.client.rest.methods.updateMessage(this, content, options);
+ }
+
+ /**
+ * Edit the content of the message, with a code block.
+ * @param {string} lang The language for the code block
+ * @param {StringResolvable} content The new content for the message
+ * @returns {Promise}
+ */
+ editCode(lang, content) {
+ content = Util.escapeMarkdown(this.client.resolver.resolveString(content), true);
+ return this.edit(`\`\`\`${lang || ''}\n${content}\n\`\`\``);
+ }
+
+ /**
+ * Pins this message to the channel's pinned messages.
+ * @returns {Promise}
+ */
+ pin() {
+ return this.client.rest.methods.pinMessage(this);
+ }
+
+ /**
+ * Unpins this message from the channel's pinned messages.
+ * @returns {Promise}
+ */
+ unpin() {
+ return this.client.rest.methods.unpinMessage(this);
+ }
+
+ /**
+ * Add a reaction to the message.
+ * @param {string|Emoji|ReactionEmoji} emoji The emoji to react with
+ * @returns {Promise}
+ */
+ react(emoji) {
+ emoji = this.client.resolver.resolveEmojiIdentifier(emoji);
+ if (!emoji) throw new TypeError('Emoji must be a string or Emoji/ReactionEmoji');
+
+ return this.client.rest.methods.addMessageReaction(this, emoji);
+ }
+
+ /**
+ * Remove all reactions from a message.
+ * @returns {Promise}
+ */
+ clearReactions() {
+ return this.client.rest.methods.removeMessageReactions(this);
+ }
+
+ /**
+ * Deletes the message.
+ * @param {number} [timeout=0] How long to wait to delete the message in milliseconds
+ * @returns {Promise}
+ * @example
+ * // Delete a message
+ * message.delete()
+ * .then(msg => console.log(`Deleted message from ${msg.author}`))
+ * .catch(console.error);
+ */
+ delete(timeout = 0) {
+ if (timeout <= 0) {
+ return this.client.rest.methods.deleteMessage(this);
+ } else {
+ return new Promise(resolve => {
+ this.client.setTimeout(() => {
+ resolve(this.delete());
+ }, timeout);
+ });
+ }
+ }
+
+ /**
+ * Reply to the message.
+ * @param {StringResolvable} [content] The content for the message
+ * @param {MessageOptions} [options] The options to provide
+ * @returns {Promise}
+ * @example
+ * // Reply to a message
+ * message.reply('Hey, I\'m a reply!')
+ * .then(msg => console.log(`Sent a reply to ${msg.author}`))
+ * .catch(console.error);
+ */
+ reply(content, options) {
+ if (!options && typeof content === 'object' && !(content instanceof Array)) {
+ options = content;
+ content = '';
+ } else if (!options) {
+ options = {};
+ }
+ return this.channel.send(content, Object.assign(options, { reply: this.member || this.author }));
+ }
+
+ /**
+ * Marks the message as read.
+ * This is only available when using a user account.
+ * @returns {Promise}
+ */
+ acknowledge() {
+ return this.client.rest.methods.ackMessage(this);
+ }
+
+ /**
+ * Fetches the webhook used to create this message.
+ * @returns {Promise}
+ */
+ fetchWebhook() {
+ if (!this.webhookID) return Promise.reject(new Error('The message was not sent by a webhook.'));
+ return this.client.fetchWebhook(this.webhookID);
+ }
+
+ /**
+ * Used mainly internally. Whether two messages are identical in properties. If you want to compare messages
+ * without checking all the properties, use `message.id === message2.id`, which is much more efficient. This
+ * method allows you to see if there are differences in content, embeds, attachments, nonce and tts properties.
+ * @param {Message} message The message to compare it to
+ * @param {Object} rawData Raw data passed through the WebSocket about this message
+ * @returns {boolean}
+ */
+ equals(message, rawData) {
+ if (!message) return false;
+ const embedUpdate = !message.author && !message.attachments;
+ if (embedUpdate) return this.id === message.id && this.embeds.length === message.embeds.length;
+
+ let equal = this.id === message.id &&
+ this.author.id === message.author.id &&
+ this.content === message.content &&
+ this.tts === message.tts &&
+ this.nonce === message.nonce &&
+ this.embeds.length === message.embeds.length &&
+ this.attachments.length === message.attachments.length;
+
+ if (equal && rawData) {
+ equal = this.mentions.everyone === message.mentions.everyone &&
+ this.createdTimestamp === new Date(rawData.timestamp).getTime() &&
+ this.editedTimestamp === new Date(rawData.edited_timestamp).getTime();
+ }
+
+ return equal;
+ }
+
+ /**
+ * When concatenated with a string, this automatically concatenates the message's content instead of the object.
+ * @returns {string}
+ * @example
+ * // Logs: Message: This is a message!
+ * console.log(`Message: ${message}`);
+ */
+ toString() {
+ return this.content;
+ }
+
+ _addReaction(emoji, user) {
+ const emojiID = emoji.id ? `${emoji.name}:${emoji.id}` : encodeURIComponent(emoji.name);
+ let reaction;
+ if (this.reactions.has(emojiID)) {
+ reaction = this.reactions.get(emojiID);
+ if (!reaction.me) reaction.me = user.id === this.client.user.id;
+ } else {
+ reaction = new MessageReaction(this, emoji, 0, user.id === this.client.user.id);
+ this.reactions.set(emojiID, reaction);
+ }
+ if (!reaction.users.has(user.id)) reaction.users.set(user.id, user);
+ reaction.count++;
+ return reaction;
+ }
+
+ _removeReaction(emoji, user) {
+ const emojiID = emoji.id ? `${emoji.name}:${emoji.id}` : encodeURIComponent(emoji.name);
+ if (this.reactions.has(emojiID)) {
+ const reaction = this.reactions.get(emojiID);
+ if (reaction.users.has(user.id)) {
+ reaction.users.delete(user.id);
+ reaction.count--;
+ if (user.id === this.client.user.id) reaction.me = false;
+ if (reaction.count <= 0) this.reactions.delete(emojiID);
+ return reaction;
+ }
+ }
+ return null;
+ }
+
+ _clearReactions() {
+ this.reactions.clear();
+ }
+}
+
+module.exports = Message;
+
+
+/***/ }),
+/* 20 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+
+function isArray(arg) {
+ if (Array.isArray) {
+ return Array.isArray(arg);
+ }
+ return objectToString(arg) === '[object Array]';
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+ return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+ return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+ return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+ return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+ return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+ return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+ return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+ return objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+ return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+ return objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+ return (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+ return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+ return arg === null ||
+ typeof arg === 'boolean' ||
+ typeof arg === 'number' ||
+ typeof arg === 'string' ||
+ typeof arg === 'symbol' || // ES6 symbol
+ typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = Buffer.isBuffer;
+
+function objectToString(o) {
+ return Object.prototype.toString.call(o);
+}
+
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer))
+
+/***/ }),
+/* 21 */
+/***/ (function(module, exports, __webpack_require__) {
+
+exports = module.exports = __webpack_require__(59);
+exports.Stream = exports;
+exports.Readable = exports;
+exports.Writable = __webpack_require__(38);
+exports.Duplex = __webpack_require__(13);
+exports.Transform = __webpack_require__(60);
+exports.PassThrough = __webpack_require__(85);
+
+
+/***/ }),
+/* 22 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var formatRegExp = /%[sdj%]/g;
+exports.format = function(f) {
+ if (!isString(f)) {
+ var objects = [];
+ for (var i = 0; i < arguments.length; i++) {
+ objects.push(inspect(arguments[i]));
+ }
+ return objects.join(' ');
+ }
+
+ var i = 1;
+ var args = arguments;
+ var len = args.length;
+ var str = String(f).replace(formatRegExp, function(x) {
+ if (x === '%%') return '%';
+ if (i >= len) return x;
+ switch (x) {
+ case '%s': return String(args[i++]);
+ case '%d': return Number(args[i++]);
+ case '%j':
+ try {
+ return JSON.stringify(args[i++]);
+ } catch (_) {
+ return '[Circular]';
+ }
+ default:
+ return x;
+ }
+ });
+ for (var x = args[i]; i < len; x = args[++i]) {
+ if (isNull(x) || !isObject(x)) {
+ str += ' ' + x;
+ } else {
+ str += ' ' + inspect(x);
+ }
+ }
+ return str;
+};
+
+
+// Mark that a method should not be used.
+// Returns a modified function which warns once by default.
+// If --no-deprecation is set, then it is a no-op.
+exports.deprecate = function(fn, msg) {
+ // Allow for deprecating things in the process of starting up.
+ if (isUndefined(global.process)) {
+ return function() {
+ return exports.deprecate(fn, msg).apply(this, arguments);
+ };
+ }
+
+ if (process.noDeprecation === true) {
+ return fn;
+ }
+
+ var warned = false;
+ function deprecated() {
+ if (!warned) {
+ if (process.throwDeprecation) {
+ throw new Error(msg);
+ } else if (process.traceDeprecation) {
+ console.trace(msg);
+ } else {
+ console.error(msg);
+ }
+ warned = true;
+ }
+ return fn.apply(this, arguments);
+ }
+
+ return deprecated;
+};
+
+
+var debugs = {};
+var debugEnviron;
+exports.debuglog = function(set) {
+ if (isUndefined(debugEnviron))
+ debugEnviron = process.env.NODE_DEBUG || '';
+ set = set.toUpperCase();
+ if (!debugs[set]) {
+ if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
+ var pid = process.pid;
+ debugs[set] = function() {
+ var msg = exports.format.apply(exports, arguments);
+ console.error('%s %d: %s', set, pid, msg);
+ };
+ } else {
+ debugs[set] = function() {};
+ }
+ }
+ return debugs[set];
+};
+
+
+/**
+ * Echos the value of a value. Trys to print the value out
+ * in the best way possible given the different types.
+ *
+ * @param {Object} obj The object to print out.
+ * @param {Object} opts Optional options object that alters the output.
+ */
+/* legacy: obj, showHidden, depth, colors*/
+function inspect(obj, opts) {
+ // default options
+ var ctx = {
+ seen: [],
+ stylize: stylizeNoColor
+ };
+ // legacy...
+ if (arguments.length >= 3) ctx.depth = arguments[2];
+ if (arguments.length >= 4) ctx.colors = arguments[3];
+ if (isBoolean(opts)) {
+ // legacy...
+ ctx.showHidden = opts;
+ } else if (opts) {
+ // got an "options" object
+ exports._extend(ctx, opts);
+ }
+ // set default options
+ if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
+ if (isUndefined(ctx.depth)) ctx.depth = 2;
+ if (isUndefined(ctx.colors)) ctx.colors = false;
+ if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
+ if (ctx.colors) ctx.stylize = stylizeWithColor;
+ return formatValue(ctx, obj, ctx.depth);
+}
+exports.inspect = inspect;
+
+
+// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
+inspect.colors = {
+ 'bold' : [1, 22],
+ 'italic' : [3, 23],
+ 'underline' : [4, 24],
+ 'inverse' : [7, 27],
+ 'white' : [37, 39],
+ 'grey' : [90, 39],
+ 'black' : [30, 39],
+ 'blue' : [34, 39],
+ 'cyan' : [36, 39],
+ 'green' : [32, 39],
+ 'magenta' : [35, 39],
+ 'red' : [31, 39],
+ 'yellow' : [33, 39]
+};
+
+// Don't use 'blue' not visible on cmd.exe
+inspect.styles = {
+ 'special': 'cyan',
+ 'number': 'yellow',
+ 'boolean': 'yellow',
+ 'undefined': 'grey',
+ 'null': 'bold',
+ 'string': 'green',
+ 'date': 'magenta',
+ // "name": intentionally not styling
+ 'regexp': 'red'
+};
+
+
+function stylizeWithColor(str, styleType) {
+ var style = inspect.styles[styleType];
+
+ if (style) {
+ return '\u001b[' + inspect.colors[style][0] + 'm' + str +
+ '\u001b[' + inspect.colors[style][1] + 'm';
+ } else {
+ return str;
+ }
+}
+
+
+function stylizeNoColor(str, styleType) {
+ return str;
+}
+
+
+function arrayToHash(array) {
+ var hash = {};
+
+ array.forEach(function(val, idx) {
+ hash[val] = true;
+ });
+
+ return hash;
+}
+
+
+function formatValue(ctx, value, recurseTimes) {
+ // Provide a hook for user-specified inspect functions.
+ // Check that value is an object with an inspect function on it
+ if (ctx.customInspect &&
+ value &&
+ isFunction(value.inspect) &&
+ // Filter out the util module, it's inspect function is special
+ value.inspect !== exports.inspect &&
+ // Also filter out any prototype objects using the circular check.
+ !(value.constructor && value.constructor.prototype === value)) {
+ var ret = value.inspect(recurseTimes, ctx);
+ if (!isString(ret)) {
+ ret = formatValue(ctx, ret, recurseTimes);
+ }
+ return ret;
+ }
+
+ // Primitive types cannot have properties
+ var primitive = formatPrimitive(ctx, value);
+ if (primitive) {
+ return primitive;
+ }
+
+ // Look up the keys of the object.
+ var keys = Object.keys(value);
+ var visibleKeys = arrayToHash(keys);
+
+ if (ctx.showHidden) {
+ keys = Object.getOwnPropertyNames(value);
+ }
+
+ // IE doesn't make error fields non-enumerable
+ // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
+ if (isError(value)
+ && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
+ return formatError(value);
+ }
+
+ // Some type of object without properties can be shortcutted.
+ if (keys.length === 0) {
+ if (isFunction(value)) {
+ var name = value.name ? ': ' + value.name : '';
+ return ctx.stylize('[Function' + name + ']', 'special');
+ }
+ if (isRegExp(value)) {
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+ }
+ if (isDate(value)) {
+ return ctx.stylize(Date.prototype.toString.call(value), 'date');
+ }
+ if (isError(value)) {
+ return formatError(value);
+ }
+ }
+
+ var base = '', array = false, braces = ['{', '}'];
+
+ // Make Array say that they are Array
+ if (isArray(value)) {
+ array = true;
+ braces = ['[', ']'];
+ }
+
+ // Make functions say that they are functions
+ if (isFunction(value)) {
+ var n = value.name ? ': ' + value.name : '';
+ base = ' [Function' + n + ']';
+ }
+
+ // Make RegExps say that they are RegExps
+ if (isRegExp(value)) {
+ base = ' ' + RegExp.prototype.toString.call(value);
+ }
+
+ // Make dates with properties first say the date
+ if (isDate(value)) {
+ base = ' ' + Date.prototype.toUTCString.call(value);
+ }
+
+ // Make error with message first say the error
+ if (isError(value)) {
+ base = ' ' + formatError(value);
+ }
+
+ if (keys.length === 0 && (!array || value.length == 0)) {
+ return braces[0] + base + braces[1];
+ }
+
+ if (recurseTimes < 0) {
+ if (isRegExp(value)) {
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+ } else {
+ return ctx.stylize('[Object]', 'special');
+ }
+ }
+
+ ctx.seen.push(value);
+
+ var output;
+ if (array) {
+ output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
+ } else {
+ output = keys.map(function(key) {
+ return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
+ });
+ }
+
+ ctx.seen.pop();
+
+ return reduceToSingleString(output, base, braces);
+}
+
+
+function formatPrimitive(ctx, value) {
+ if (isUndefined(value))
+ return ctx.stylize('undefined', 'undefined');
+ if (isString(value)) {
+ var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
+ .replace(/'/g, "\\'")
+ .replace(/\\"/g, '"') + '\'';
+ return ctx.stylize(simple, 'string');
+ }
+ if (isNumber(value))
+ return ctx.stylize('' + value, 'number');
+ if (isBoolean(value))
+ return ctx.stylize('' + value, 'boolean');
+ // For some reason typeof null is "object", so special case here.
+ if (isNull(value))
+ return ctx.stylize('null', 'null');
+}
+
+
+function formatError(value) {
+ return '[' + Error.prototype.toString.call(value) + ']';
+}
+
+
+function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
+ var output = [];
+ for (var i = 0, l = value.length; i < l; ++i) {
+ if (hasOwnProperty(value, String(i))) {
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+ String(i), true));
+ } else {
+ output.push('');
+ }
+ }
+ keys.forEach(function(key) {
+ if (!key.match(/^\d+$/)) {
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+ key, true));
+ }
+ });
+ return output;
+}
+
+
+function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
+ var name, str, desc;
+ desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
+ if (desc.get) {
+ if (desc.set) {
+ str = ctx.stylize('[Getter/Setter]', 'special');
+ } else {
+ str = ctx.stylize('[Getter]', 'special');
+ }
+ } else {
+ if (desc.set) {
+ str = ctx.stylize('[Setter]', 'special');
+ }
+ }
+ if (!hasOwnProperty(visibleKeys, key)) {
+ name = '[' + key + ']';
+ }
+ if (!str) {
+ if (ctx.seen.indexOf(desc.value) < 0) {
+ if (isNull(recurseTimes)) {
+ str = formatValue(ctx, desc.value, null);
+ } else {
+ str = formatValue(ctx, desc.value, recurseTimes - 1);
+ }
+ if (str.indexOf('\n') > -1) {
+ if (array) {
+ str = str.split('\n').map(function(line) {
+ return ' ' + line;
+ }).join('\n').substr(2);
+ } else {
+ str = '\n' + str.split('\n').map(function(line) {
+ return ' ' + line;
+ }).join('\n');
+ }
+ }
+ } else {
+ str = ctx.stylize('[Circular]', 'special');
+ }
+ }
+ if (isUndefined(name)) {
+ if (array && key.match(/^\d+$/)) {
+ return str;
+ }
+ name = JSON.stringify('' + key);
+ if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
+ name = name.substr(1, name.length - 2);
+ name = ctx.stylize(name, 'name');
+ } else {
+ name = name.replace(/'/g, "\\'")
+ .replace(/\\"/g, '"')
+ .replace(/(^"|"$)/g, "'");
+ name = ctx.stylize(name, 'string');
+ }
+ }
+
+ return name + ': ' + str;
+}
+
+
+function reduceToSingleString(output, base, braces) {
+ var numLinesEst = 0;
+ var length = output.reduce(function(prev, cur) {
+ numLinesEst++;
+ if (cur.indexOf('\n') >= 0) numLinesEst++;
+ return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
+ }, 0);
+
+ if (length > 60) {
+ return braces[0] +
+ (base === '' ? '' : base + '\n ') +
+ ' ' +
+ output.join(',\n ') +
+ ' ' +
+ braces[1];
+ }
+
+ return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
+}
+
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+function isArray(ar) {
+ return Array.isArray(ar);
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+ return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+ return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+ return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+ return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+ return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+ return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+ return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+ return isObject(re) && objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+ return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+ return isObject(d) && objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+ return isObject(e) &&
+ (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+ return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+ return arg === null ||
+ typeof arg === 'boolean' ||
+ typeof arg === 'number' ||
+ typeof arg === 'string' ||
+ typeof arg === 'symbol' || // ES6 symbol
+ typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = __webpack_require__(104);
+
+function objectToString(o) {
+ return Object.prototype.toString.call(o);
+}
+
+
+function pad(n) {
+ return n < 10 ? '0' + n.toString(10) : n.toString(10);
+}
+
+
+var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
+ 'Oct', 'Nov', 'Dec'];
+
+// 26 Feb 16:19:34
+function timestamp() {
+ var d = new Date();
+ var time = [pad(d.getHours()),
+ pad(d.getMinutes()),
+ pad(d.getSeconds())].join(':');
+ return [d.getDate(), months[d.getMonth()], time].join(' ');
+}
+
+
+// log is just a thin wrapper to console.log that prepends a timestamp
+exports.log = function() {
+ console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
+};
+
+
+/**
+ * Inherit the prototype methods from one constructor into another.
+ *
+ * The Function.prototype.inherits from lang.js rewritten as a standalone
+ * function (not on Function.prototype). NOTE: If this file is to be loaded
+ * during bootstrapping this function needs to be rewritten using some native
+ * functions as prototype setup using normal JavaScript does not work as
+ * expected during bootstrapping (see mirror.js in r114903).
+ *
+ * @param {function} ctor Constructor function which needs to inherit the
+ * prototype.
+ * @param {function} superCtor Constructor function to inherit prototype from.
+ */
+exports.inherits = __webpack_require__(103);
+
+exports._extend = function(origin, add) {
+ // Don't do anything if add isn't an object
+ if (!add || !isObject(add)) return origin;
+
+ var keys = Object.keys(add);
+ var i = keys.length;
+ while (i--) {
+ origin[keys[i]] = add[keys[i]];
+ }
+ return origin;
+};
+
+function hasOwnProperty(obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop);
+}
+
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8), __webpack_require__(6)))
+
+/***/ }),
+/* 23 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const path = __webpack_require__(28);
+const Message = __webpack_require__(19);
+const MessageCollector = __webpack_require__(48);
+const Collection = __webpack_require__(3);
+const util = __webpack_require__(22);
+
+/**
+ * Interface for classes that have text-channel-like features.
+ * @interface
+ */
+class TextBasedChannel {
+ constructor() {
+ /**
+ * A collection containing the messages sent to this channel
+ * @type {Collection}
+ */
+ this.messages = new Collection();
+
+ /**
+ * The ID of the last message in the channel, if one was sent
+ * @type {?Snowflake}
+ */
+ this.lastMessageID = null;
+
+ /**
+ * The Message object of the last message in the channel, if one was sent
+ * @type {?Message}
+ */
+ this.lastMessage = null;
+ }
+
+ /**
+ * Options provided when sending or editing a message.
+ * @typedef {Object} MessageOptions
+ * @property {boolean} [tts=false] Whether or not the message should be spoken aloud
+ * @property {string} [nonce=''] The nonce for the message
+ * @property {RichEmbed|Object} [embed] An embed for the message
+ * (see [here](https://discordapp.com/developers/docs/resources/channel#embed-object) for more details)
+ * @property {boolean} [disableEveryone=this.client.options.disableEveryone] Whether or not @everyone and @here
+ * should be replaced with plain-text
+ * @property {FileOptions|string} [file] A file to send with the message **(deprecated)**
+ * @property {FileOptions[]|string[]} [files] Files to send with the message
+ * @property {string|boolean} [code] Language for optional codeblock formatting to apply
+ * @property {boolean|SplitOptions} [split=false] Whether or not the message should be split into multiple messages if
+ * it exceeds the character limit. If an object is provided, these are the options for splitting the message
+ * @property {UserResolvable} [reply] User to reply to (prefixes the message with a mention, except in DMs)
+ */
+
+ /**
+ * @typedef {Object} FileOptions
+ * @property {BufferResolvable} attachment File to attach
+ * @property {string} [name='file.jpg'] Filename of the attachment
+ */
+
+ /**
+ * Options for splitting a message.
+ * @typedef {Object} SplitOptions
+ * @property {number} [maxLength=1950] Maximum character length per message piece
+ * @property {string} [char='\n'] Character to split the message with
+ * @property {string} [prepend=''] Text to prepend to every piece except the first
+ * @property {string} [append=''] Text to append to every piece except the last
+ */
+
+ /**
+ * Send a message to this channel.
+ * @param {StringResolvable} [content] Text for the message
+ * @param {MessageOptions} [options={}] Options for the message
+ * @returns {Promise}
+ * @example
+ * // Send a message
+ * channel.send('hello!')
+ * .then(message => console.log(`Sent message: ${message.content}`))
+ * .catch(console.error);
+ */
+ send(content, options) {
+ if (!options && typeof content === 'object' && !(content instanceof Array)) {
+ options = content;
+ content = '';
+ } else if (!options) {
+ options = {};
+ }
+
+ if (options.embed && options.embed.file) options.file = options.embed.file;
+
+ if (options.file) {
+ if (options.files) options.files.push(options.file);
+ else options.files = [options.file];
+ }
+
+ if (options.files) {
+ for (const i in options.files) {
+ let file = options.files[i];
+ if (typeof file === 'string') file = { attachment: file };
+ if (!file.name) {
+ if (typeof file.attachment === 'string') {
+ file.name = path.basename(file.attachment);
+ } else if (file.attachment && file.attachment.path) {
+ file.name = path.basename(file.attachment.path);
+ } else {
+ file.name = 'file.jpg';
+ }
+ }
+ options.files[i] = file;
+ }
+
+ return Promise.all(options.files.map(file =>
+ this.client.resolver.resolveBuffer(file.attachment).then(buffer => {
+ file.file = buffer;
+ return file;
+ })
+ )).then(files => this.client.rest.methods.sendMessage(this, content, options, files));
+ }
+
+ return this.client.rest.methods.sendMessage(this, content, options);
+ }
+
+ /**
+ * Gets a single message from this channel, regardless of it being cached or not. Since the single message fetching
+ * endpoint is reserved for bot accounts, this abstracts the `fetchMessages` method to obtain the single message when
+ * using a user account.
+ * @param {Snowflake} messageID ID of the message to get
+ * @returns {Promise}
+ * @example
+ * // Get message
+ * channel.fetchMessage('99539446449315840')
+ * .then(message => console.log(message.content))
+ * .catch(console.error);
+ */
+ fetchMessage(messageID) {
+ if (!this.client.user.bot) {
+ return this.fetchMessages({ limit: 1, around: messageID }).then(messages => {
+ const msg = messages.get(messageID);
+ if (!msg) throw new Error('Message not found.');
+ return msg;
+ });
+ }
+ return this.client.rest.methods.getChannelMessage(this, messageID).then(data => {
+ const msg = data instanceof Message ? data : new Message(this, data, this.client);
+ this._cacheMessage(msg);
+ return msg;
+ });
+ }
+
+ /**
+ * The parameters to pass in when requesting previous messages from a channel. `around`, `before` and
+ * `after` are mutually exclusive. All the parameters are optional.
+ * @typedef {Object} ChannelLogsQueryOptions
+ * @property {number} [limit=50] Number of messages to acquire
+ * @property {Snowflake} [before] ID of a message to get the messages that were posted before it
+ * @property {Snowflake} [after] ID of a message to get the messages that were posted after it
+ * @property {Snowflake} [around] ID of a message to get the messages that were posted around it
+ */
+
+ /**
+ * Gets the past messages sent in this channel. Resolves with a collection mapping message ID's to Message objects.
+ * @param {ChannelLogsQueryOptions} [options={}] Query parameters to pass in
+ * @returns {Promise>}
+ * @example
+ * // Get messages
+ * channel.fetchMessages({limit: 10})
+ * .then(messages => console.log(`Received ${messages.size} messages`))
+ * .catch(console.error);
+ */
+ fetchMessages(options = {}) {
+ return this.client.rest.methods.getChannelMessages(this, options).then(data => {
+ const messages = new Collection();
+ for (const message of data) {
+ const msg = new Message(this, message, this.client);
+ messages.set(message.id, msg);
+ this._cacheMessage(msg);
+ }
+ return messages;
+ });
+ }
+
+ /**
+ * Fetches the pinned messages of this channel and returns a collection of them.
+ * @returns {Promise>}
+ */
+ fetchPinnedMessages() {
+ return this.client.rest.methods.getChannelPinnedMessages(this).then(data => {
+ const messages = new Collection();
+ for (const message of data) {
+ const msg = new Message(this, message, this.client);
+ messages.set(message.id, msg);
+ this._cacheMessage(msg);
+ }
+ return messages;
+ });
+ }
+
+ /**
+ * @typedef {Object} MessageSearchOptions
+ * @property {string} [content] Message content
+ * @property {Snowflake} [maxID] Maximum ID for the filter
+ * @property {Snowflake} [minID] Minimum ID for the filter
+ * @property {string} [has] One of `link`, `embed`, `file`, `video`, `image`, or `sound`,
+ * or add `-` to negate (e.g. `-file`)
+ * @property {ChannelResolvable} [channel] Channel to limit search to (only for guild search endpoint)
+ * @property {UserResolvable} [author] Author to limit search
+ * @property {string} [authorType] One of `user`, `bot`, `webhook`, or add `-` to negate (e.g. `-webhook`)
+ * @property {string} [sortBy='recent'] `recent` or `relevant`
+ * @property {string} [sortOrder='desc'] `asc` or `desc`
+ * @property {number} [contextSize=2] How many messages to get around the matched message (0 to 2)
+ * @property {number} [limit=25] Maximum number of results to get (1 to 25)
+ * @property {number} [offset=0] Offset the "pages" of results (since you can only see 25 at a time)
+ * @property {UserResolvable} [mentions] Mentioned user filter
+ * @property {boolean} [mentionsEveryone] If everyone is mentioned
+ * @property {string} [linkHostname] Filter links by hostname
+ * @property {string} [embedProvider] The name of an embed provider
+ * @property {string} [embedType] one of `image`, `video`, `url`, `rich`
+ * @property {string} [attachmentFilename] The name of an attachment
+ * @property {string} [attachmentExtension] The extension of an attachment
+ * @property {Date} [before] Date to find messages before
+ * @property {Date} [after] Date to find messages before
+ * @property {Date} [during] Date to find messages during (range of date to date + 24 hours)
+ */
+
+ /**
+ * Performs a search within the channel.
+ * This is only available when using a user account.
+ * @param {MessageSearchOptions} [options={}] Options to pass to the search
+ * @returns {Promise>}
+ * An array containing arrays of messages. Each inner array is a search context cluster
+ * The message which has triggered the result will have the `hit` property set to `true`
+ * @example
+ * channel.search({
+ * content: 'discord.js',
+ * before: '2016-11-17'
+ * }).then(res => {
+ * const hit = res.messages[0].find(m => m.hit).content;
+ * console.log(`I found: **${hit}**, total results: ${res.totalResults}`);
+ * }).catch(console.error);
+ */
+ search(options = {}) {
+ return this.client.rest.methods.search(this, options);
+ }
+
+ /**
+ * Starts a typing indicator in the channel.
+ * @param {number} [count] The number of times startTyping should be considered to have been called
+ * @example
+ * // Start typing in a channel
+ * channel.startTyping();
+ */
+ startTyping(count) {
+ if (typeof count !== 'undefined' && count < 1) throw new RangeError('Count must be at least 1.');
+ if (!this.client.user._typing.has(this.id)) {
+ this.client.user._typing.set(this.id, {
+ count: count || 1,
+ interval: this.client.setInterval(() => {
+ this.client.rest.methods.sendTyping(this.id);
+ }, 9000),
+ });
+ this.client.rest.methods.sendTyping(this.id);
+ } else {
+ const entry = this.client.user._typing.get(this.id);
+ entry.count = count || entry.count + 1;
+ }
+ }
+
+ /**
+ * Stops the typing indicator in the channel.
+ * The indicator will only stop if this is called as many times as startTyping().
+ * It can take a few seconds for the client user to stop typing.
+ * @param {boolean} [force=false] Whether or not to reset the call count and force the indicator to stop
+ * @example
+ * // Stop typing in a channel
+ * channel.stopTyping();
+ * @example
+ * // Force typing to fully stop in a channel
+ * channel.stopTyping(true);
+ */
+ stopTyping(force = false) {
+ if (this.client.user._typing.has(this.id)) {
+ const entry = this.client.user._typing.get(this.id);
+ entry.count--;
+ if (entry.count <= 0 || force) {
+ this.client.clearInterval(entry.interval);
+ this.client.user._typing.delete(this.id);
+ }
+ }
+ }
+
+ /**
+ * Whether or not the typing indicator is being shown in the channel
+ * @type {boolean}
+ * @readonly
+ */
+ get typing() {
+ return this.client.user._typing.has(this.id);
+ }
+
+ /**
+ * Number of times `startTyping` has been called
+ * @type {number}
+ * @readonly
+ */
+ get typingCount() {
+ if (this.client.user._typing.has(this.id)) return this.client.user._typing.get(this.id).count;
+ return 0;
+ }
+
+ /**
+ * Creates a Message Collector
+ * @param {CollectorFilter} filter The filter to create the collector with
+ * @param {MessageCollectorOptions} [options={}] The options to pass to the collector
+ * @returns {MessageCollector}
+ * @deprecated
+ */
+ createCollector(filter, options) {
+ return this.createMessageCollector(filter, options);
+ }
+
+ /**
+ * Creates a Message Collector.
+ * @param {CollectorFilter} filter The filter to create the collector with
+ * @param {MessageCollectorOptions} [options={}] The options to pass to the collector
+ * @returns {MessageCollector}
+ * @example
+ * // Create a message collector
+ * const collector = channel.createCollector(
+ * m => m.content.includes('discord'),
+ * { time: 15000 }
+ * );
+ * collector.on('message', m => console.log(`Collected ${m.content}`));
+ * collector.on('end', collected => console.log(`Collected ${collected.size} items`));
+ */
+ createMessageCollector(filter, options = {}) {
+ return new MessageCollector(this, filter, options);
+ }
+
+ /**
+ * An object containing the same properties as CollectorOptions, but a few more:
+ * @typedef {MessageCollectorOptions} AwaitMessagesOptions
+ * @property {string[]} [errors] Stop/end reasons that cause the promise to reject
+ */
+
+ /**
+ * Similar to createCollector but in promise form. Resolves with a collection of messages that pass the specified
+ * filter.
+ * @param {CollectorFilter} filter The filter function to use
+ * @param {AwaitMessagesOptions} [options={}] Optional options to pass to the internal collector
+ * @returns {Promise>}
+ * @example
+ * // Await !vote messages
+ * const filter = m => m.content.startsWith('!vote');
+ * // Errors: ['time'] treats ending because of the time limit as an error
+ * channel.awaitMessages(filter, { max: 4, time: 60000, errors: ['time'] })
+ * .then(collected => console.log(collected.size))
+ * .catch(collected => console.log(`After a minute, only ${collected.size} out of 4 voted.`));
+ */
+ awaitMessages(filter, options = {}) {
+ return new Promise((resolve, reject) => {
+ const collector = this.createCollector(filter, options);
+ collector.once('end', (collection, reason) => {
+ if (options.errors && options.errors.includes(reason)) {
+ reject(collection);
+ } else {
+ resolve(collection);
+ }
+ });
+ });
+ }
+
+ /**
+ * Bulk delete given messages that are newer than two weeks.
+ * This is only available when using a bot account.
+ * @param {Collection|Message[]|number} messages Messages or number of messages to delete
+ * @param {boolean} [filterOld=false] Filter messages to remove those which are older than two weeks automatically
+ * @returns {Promise>} Deleted messages
+ */
+ bulkDelete(messages, filterOld = false) {
+ if (!isNaN(messages)) return this.fetchMessages({ limit: messages }).then(msgs => this.bulkDelete(msgs, filterOld));
+ if (messages instanceof Array || messages instanceof Collection) {
+ const messageIDs = messages instanceof Collection ? messages.keyArray() : messages.map(m => m.id);
+ return this.client.rest.methods.bulkDeleteMessages(this, messageIDs, filterOld);
+ }
+ throw new TypeError('The messages must be an Array, Collection, or number.');
+ }
+
+ /**
+ * Marks all messages in this channel as read.
+ * This is only available when using a user account.
+ * @returns {Promise}
+ */
+ acknowledge() {
+ if (!this.lastMessageID) return Promise.resolve(this);
+ return this.client.rest.methods.ackTextChannel(this);
+ }
+
+ _cacheMessage(message) {
+ const maxSize = this.client.options.messageCacheMaxSize;
+ if (maxSize === 0) return null;
+ if (this.messages.size >= maxSize && maxSize > 0) this.messages.delete(this.messages.firstKey());
+ this.messages.set(message.id, message);
+ return message;
+ }
+}
+
+/** @lends TextBasedChannel.prototype */
+const Deprecated = {
+ /**
+ * Send a message to this channel.
+ * @param {StringResolvable} [content] Text for the message
+ * @param {MessageOptions} [options={}] Options for the message
+ * @returns {Promise}
+ * @deprecated
+ * @example
+ * // Send a message
+ * channel.sendMessage('hello!')
+ * .then(message => console.log(`Sent message: ${message.content}`))
+ * .catch(console.error);
+ */
+ sendMessage(content, options) {
+ return this.send(content, options);
+ },
+
+ /**
+ * Send an embed to this channel.
+ * @param {RichEmbed|Object} embed Embed for the message
+ * @param {string} [content] Text for the message
+ * @param {MessageOptions} [options] Options for the message
+ * @returns {Promise}
+ * @deprecated
+ */
+ sendEmbed(embed, content, options) {
+ if (!options && typeof content === 'object' && !(content instanceof Array)) {
+ options = content;
+ content = '';
+ } else if (!options) {
+ options = {};
+ }
+ return this.send(content, Object.assign(options, { embed }));
+ },
+
+ /**
+ * Send files to this channel.
+ * @param {FileOptions[]|string[]} files Files to send with the message
+ * @param {StringResolvable} [content] Text for the message
+ * @param {MessageOptions} [options] Options for the message
+ * @returns {Promise}
+ * @deprecated
+ */
+ sendFiles(files, content, options = {}) {
+ return this.send(content, Object.assign(options, { files }));
+ },
+
+ /**
+ * Send a file to this channel.
+ * @param {BufferResolvable} attachment File to send
+ * @param {string} [name='file.jpg'] Name and extension of the file
+ * @param {StringResolvable} [content] Text for the message
+ * @param {MessageOptions} [options] Options for the message
+ * @returns {Promise}
+ * @deprecated
+ */
+ sendFile(attachment, name, content, options = {}) {
+ return this.send({ files: [{ attachment, name }], content, options });
+ },
+
+ /**
+ * Send a code block to this channel.
+ * @param {string} lang Language for the code block
+ * @param {StringResolvable} content Content of the code block
+ * @param {MessageOptions} [options] Options for the message
+ * @returns {Promise}
+ * @deprecated
+ */
+ sendCode(lang, content, options = {}) {
+ return this.send(content, Object.assign(options, { code: lang }));
+ },
+};
+
+for (const key of Object.keys(Deprecated)) {
+ TextBasedChannel.prototype[key] = util.deprecate(Deprecated[key], `TextChannel#${key}: use TextChannel#send instead`);
+}
+
+exports.applyToClass = (structure, full = false, ignore = []) => {
+ const props = ['send', 'sendMessage', 'sendEmbed', 'sendFile', 'sendFiles', 'sendCode'];
+ if (full) {
+ props.push(
+ '_cacheMessage',
+ 'acknowledge',
+ 'fetchMessages',
+ 'fetchMessage',
+ 'search',
+ 'bulkDelete',
+ 'startTyping',
+ 'stopTyping',
+ 'typing',
+ 'typingCount',
+ 'fetchPinnedMessages',
+ 'createCollector',
+ 'createMessageCollector',
+ 'awaitMessages'
+ );
+ }
+ for (const prop of props) {
+ if (ignore.includes(prop)) continue;
+ Object.defineProperty(structure.prototype, prop, Object.getOwnPropertyDescriptor(TextBasedChannel.prototype, prop));
+ }
+};
+
+
+/***/ }),
+/* 24 */
+/***/ (function(module, exports) {
+
+exports.endianness = function () { return 'LE' };
+
+exports.hostname = function () {
+ if (typeof location !== 'undefined') {
+ return location.hostname
+ }
+ else return '';
+};
+
+exports.loadavg = function () { return [] };
+
+exports.uptime = function () { return 0 };
+
+exports.freemem = function () {
+ return Number.MAX_VALUE;
+};
+
+exports.totalmem = function () {
+ return Number.MAX_VALUE;
+};
+
+exports.cpus = function () { return [] };
+
+exports.type = function () { return 'Browser' };
+
+exports.release = function () {
+ if (typeof navigator !== 'undefined') {
+ return navigator.appVersion;
+ }
+ return '';
+};
+
+exports.networkInterfaces
+= exports.getNetworkInterfaces
+= function () { return {} };
+
+exports.arch = function () { return 'javascript' };
+
+exports.platform = function () { return 'browser' };
+
+exports.tmpdir = exports.tmpDir = function () {
+ return '/tmp';
+};
+
+exports.EOL = '\n';
+
+
+/***/ }),
+/* 25 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Long = __webpack_require__(35);
+const User = __webpack_require__(16);
+const Role = __webpack_require__(15);
+const Emoji = __webpack_require__(17);
+const Presence = __webpack_require__(11).Presence;
+const GuildMember = __webpack_require__(18);
+const Constants = __webpack_require__(0);
+const Collection = __webpack_require__(3);
+const Util = __webpack_require__(4);
+const Snowflake = __webpack_require__(7);
+
+/**
+ * Represents a guild (or a server) on Discord.
+ * It's recommended to see if a guild is available before performing operations or reading data from it. You can
+ * check this with `guild.available`.
+ */
+class Guild {
+ constructor(client, data) {
+ /**
+ * The client that created the instance of the the guild
+ * @name Guild#client
+ * @type {Client}
+ * @readonly
+ */
+ Object.defineProperty(this, 'client', { value: client });
+
+ /**
+ * A collection of members that are in this guild. The key is the member's ID, the value is the member
+ * @type {Collection}
+ */
+ this.members = new Collection();
+
+ /**
+ * A collection of channels that are in this guild. The key is the channel's ID, the value is the channel
+ * @type {Collection}
+ */
+ this.channels = new Collection();
+
+ /**
+ * A collection of roles that are in this guild. The key is the role's ID, the value is the role
+ * @type {Collection}
+ */
+ this.roles = new Collection();
+
+ /**
+ * A collection of presences in this guild
+ * @type {Collection}
+ */
+ this.presences = new Collection();
+
+ if (!data) return;
+ if (data.unavailable) {
+ /**
+ * Whether the guild is available to access. If it is not available, it indicates a server outage
+ * @type {boolean}
+ */
+ this.available = false;
+
+ /**
+ * The Unique ID of the guild, useful for comparisons
+ * @type {Snowflake}
+ */
+ this.id = data.id;
+ } else {
+ this.available = true;
+ this.setup(data);
+ }
+ }
+
+ /**
+ * Sets up the guild.
+ * @param {*} data The raw data of the guild
+ * @private
+ */
+ setup(data) {
+ /**
+ * The name of the guild
+ * @type {string}
+ */
+ this.name = data.name;
+
+ /**
+ * The hash of the guild icon
+ * @type {?string}
+ */
+ this.icon = data.icon;
+
+ /**
+ * The hash of the guild splash image (VIP only)
+ * @type {?string}
+ */
+ this.splash = data.splash;
+
+ /**
+ * The region the guild is located in
+ * @type {string}
+ */
+ this.region = data.region;
+
+ /**
+ * The full amount of members in this guild as of `READY`
+ * @type {number}
+ */
+ this.memberCount = data.member_count || this.memberCount;
+
+ /**
+ * Whether the guild is "large" (has more than 250 members)
+ * @type {boolean}
+ */
+ this.large = Boolean('large' in data ? data.large : this.large);
+
+ /**
+ * An array of guild features
+ * @type {Object[]}
+ */
+ this.features = data.features;
+
+ /**
+ * The ID of the application that created this guild (if applicable)
+ * @type {?Snowflake}
+ */
+ this.applicationID = data.application_id;
+
+ /**
+ * The time in seconds before a user is counted as "away from keyboard"
+ * @type {?number}
+ */
+ this.afkTimeout = data.afk_timeout;
+
+ /**
+ * The ID of the voice channel where AFK members are moved
+ * @type {?string}
+ */
+ this.afkChannelID = data.afk_channel_id;
+
+ /**
+ * Whether embedded images are enabled on this guild
+ * @type {boolean}
+ */
+ this.embedEnabled = data.embed_enabled;
+
+ /**
+ * The verification level of the guild
+ * @type {number}
+ */
+ this.verificationLevel = data.verification_level;
+
+ /**
+ * The explicit content filter level of the guild
+ * @type {number}
+ */
+ this.explicitContentFilter = data.explicit_content_filter;
+
+ /**
+ * The timestamp the client user joined the guild at
+ * @type {number}
+ */
+ this.joinedTimestamp = data.joined_at ? new Date(data.joined_at).getTime() : this.joinedTimestamp;
+
+ this.id = data.id;
+ this.available = !data.unavailable;
+ this.features = data.features || this.features || [];
+
+ if (data.members) {
+ this.members.clear();
+ for (const guildUser of data.members) this._addMember(guildUser, false);
+ }
+
+ if (data.owner_id) {
+ /**
+ * The user ID of this guild's owner
+ * @type {Snowflake}
+ */
+ this.ownerID = data.owner_id;
+ }
+
+ if (data.channels) {
+ this.channels.clear();
+ for (const channel of data.channels) this.client.dataManager.newChannel(channel, this);
+ }
+
+ if (data.roles) {
+ this.roles.clear();
+ for (const role of data.roles) {
+ const newRole = new Role(this, role);
+ this.roles.set(newRole.id, newRole);
+ }
+ }
+
+ if (data.presences) {
+ for (const presence of data.presences) {
+ this._setPresence(presence.user.id, presence);
+ }
+ }
+
+ this._rawVoiceStates = new Collection();
+ if (data.voice_states) {
+ for (const voiceState of data.voice_states) {
+ this._rawVoiceStates.set(voiceState.user_id, voiceState);
+ const member = this.members.get(voiceState.user_id);
+ if (member) {
+ member.serverMute = voiceState.mute;
+ member.serverDeaf = voiceState.deaf;
+ member.selfMute = voiceState.self_mute;
+ member.selfDeaf = voiceState.self_deaf;
+ member.voiceSessionID = voiceState.session_id;
+ member.voiceChannelID = voiceState.channel_id;
+ this.channels.get(voiceState.channel_id).members.set(member.user.id, member);
+ }
+ }
+ }
+
+ if (!this.emojis) {
+ /**
+ * A collection of emojis that are in this guild. The key is the emoji's ID, the value is the emoji.
+ * @type {Collection}
+ */
+ this.emojis = new Collection();
+ for (const emoji of data.emojis) this.emojis.set(emoji.id, new Emoji(this, emoji));
+ } else {
+ this.client.actions.GuildEmojisUpdate.handle({
+ guild_id: this.id,
+ emojis: data.emojis,
+ });
+ }
+ }
+
+ /**
+ * The timestamp the guild was created at
+ * @type {number}
+ * @readonly
+ */
+ get createdTimestamp() {
+ return Snowflake.deconstruct(this.id).timestamp;
+ }
+
+ /**
+ * The time the guild was created
+ * @type {Date}
+ * @readonly
+ */
+ get createdAt() {
+ return new Date(this.createdTimestamp);
+ }
+
+ /**
+ * The time the client user joined the guild
+ * @type {Date}
+ * @readonly
+ */
+ get joinedAt() {
+ return new Date(this.joinedTimestamp);
+ }
+
+ /**
+ * The URL to this guild's icon
+ * @type {?string}
+ * @readonly
+ */
+ get iconURL() {
+ if (!this.icon) return null;
+ return Constants.Endpoints.Guild(this).Icon(this.client.options.http.cdn, this.icon);
+ }
+
+ /**
+ * The URL to this guild's splash
+ * @type {?string}
+ * @readonly
+ */
+ get splashURL() {
+ if (!this.splash) return null;
+ return Constants.Endpoints.Guild(this).Splash(this.client.options.http.cdn, this.splash);
+ }
+
+ /**
+ * The owner of the guild
+ * @type {GuildMember}
+ * @readonly
+ */
+ get owner() {
+ return this.members.get(this.ownerID);
+ }
+
+ /**
+ * If the client is connected to any voice channel in this guild, this will be the relevant VoiceConnection
+ * @type {?VoiceConnection}
+ * @readonly
+ */
+ get voiceConnection() {
+ if (this.client.browser) return null;
+ return this.client.voice.connections.get(this.id) || null;
+ }
+
+ /**
+ * The `#general` TextChannel of the guild
+ * @type {TextChannel}
+ * @readonly
+ */
+ get defaultChannel() {
+ return this.channels.get(this.id);
+ }
+
+ /**
+ * The position of this guild
+ * This is only available when using a user account.
+ * @type {?number}
+ */
+ get position() {
+ if (this.client.user.bot) return null;
+ if (!this.client.user.settings.guildPositions) return null;
+ return this.client.user.settings.guildPositions.indexOf(this.id);
+ }
+
+ /**
+ * The `@everyone` role of the guild
+ * @type {Role}
+ * @readonly
+ */
+ get defaultRole() {
+ return this.roles.get(this.id);
+ }
+
+ /**
+ * The client user as a GuildMember of this guild
+ * @type {?GuildMember}
+ * @readonly
+ */
+ get me() {
+ return this.members.get(this.client.user.id);
+ }
+
+ /**
+ * Fetches a collection of roles in the current guild sorted by position
+ * @type {Collection}
+ * @readonly
+ * @private
+ */
+ get _sortedRoles() {
+ return this._sortPositionWithID(this.roles);
+ }
+
+ /**
+ * Returns the GuildMember form of a User object, if the user is present in the guild.
+ * @param {UserResolvable} user The user that you want to obtain the GuildMember of
+ * @returns {?GuildMember}
+ * @example
+ * // Get the guild member of a user
+ * const member = guild.member(message.author);
+ */
+ member(user) {
+ return this.client.resolver.resolveGuildMember(this, user);
+ }
+
+ /**
+ * Fetch a collection of banned users in this guild.
+ * @returns {Promise>}
+ */
+ fetchBans() {
+ return this.client.rest.methods.getGuildBans(this)
+ // This entire re-mapping can be removed in the next major release
+ .then(bans => {
+ const users = new Collection();
+ for (const ban of bans.values()) users.set(ban.user.id, ban.user);
+ return users;
+ });
+ }
+
+ /**
+ * Fetch a collection of invites to this guild. Resolves with a collection mapping invites by their codes.
+ * @returns {Promise>}
+ */
+ fetchInvites() {
+ return this.client.rest.methods.getGuildInvites(this);
+ }
+
+ /**
+ * Fetch all webhooks for the guild.
+ * @returns {Collection}
+ */
+ fetchWebhooks() {
+ return this.client.rest.methods.getGuildWebhooks(this);
+ }
+
+ /**
+ * Fetch available voice regions.
+ * @returns {Collection}
+ */
+ fetchVoiceRegions() {
+ return this.client.rest.methods.fetchVoiceRegions(this.id);
+ }
+
+ /**
+ * Fetch audit logs for this guild.
+ * @param {Object} [options={}] Options for fetching audit logs
+ * @param {Snowflake|GuildAuditLogsEntry} [options.before] Limit to entries from before specified entry
+ * @param {Snowflake|GuildAuditLogsEntry} [options.after] Limit to entries from after specified entry
+ * @param {number} [options.limit] Limit number of entries
+ * @param {UserResolvable} [options.user] Only show entries involving this user
+ * @param {string|number} [options.type] Only show entries involving this action type
+ * @returns {Promise}
+ */
+ fetchAuditLogs(options) {
+ return this.client.rest.methods.getGuildAuditLogs(this, options);
+ }
+
+ /**
+ * Adds a user to the guild using OAuth2. Requires the `CREATE_INSTANT_INVITE` permission.
+ * @param {UserResolvable} user User to add to the guild
+ * @param {Object} options Options for the addition
+ * @param {string} options.accessToken An OAuth2 access token for the user with the `guilds.join` scope granted to the
+ * bot's application
+ * @param {string} [options.nick] Nickname to give the member (requires `MANAGE_NICKNAMES`)
+ * @param {Collection|Role[]|Snowflake[]} [options.roles] Roles to add to the member
+ * (requires `MANAGE_ROLES`)
+ * @param {boolean} [options.mute] Whether the member should be muted (requires `MUTE_MEMBERS`)
+ * @param {boolean} [options.deaf] Whether the member should be deafened (requires `DEAFEN_MEMBERS`)
+ * @returns {Promise}
+ */
+ addMember(user, options) {
+ if (this.members.has(user.id)) return Promise.resolve(this.members.get(user.id));
+ return this.client.rest.methods.putGuildMember(this, user, options);
+ }
+
+ /**
+ * Fetch a single guild member from a user.
+ * @param {UserResolvable} user The user to fetch the member for
+ * @param {boolean} [cache=true] Insert the user into the users cache
+ * @returns {Promise}
+ */
+ fetchMember(user, cache = true) {
+ user = this.client.resolver.resolveUser(user);
+ if (!user) return Promise.reject(new Error('User is not cached. Use Client.fetchUser first.'));
+ if (this.members.has(user.id)) return Promise.resolve(this.members.get(user.id));
+ return this.client.rest.methods.getGuildMember(this, user, cache);
+ }
+
+ /**
+ * Fetches all the members in the guild, even if they are offline. If the guild has less than 250 members,
+ * this should not be necessary.
+ * @param {string} [query=''] Limit fetch to members with similar usernames
+ * @param {number} [limit=0] Maximum number of members to request
+ * @returns {Promise}
+ */
+ fetchMembers(query = '', limit = 0) {
+ return new Promise((resolve, reject) => {
+ if (this.memberCount === this.members.size) {
+ // Uncomment in v12
+ // resolve(this.members)
+ resolve(this);
+ return;
+ }
+ this.client.ws.send({
+ op: Constants.OPCodes.REQUEST_GUILD_MEMBERS,
+ d: {
+ guild_id: this.id,
+ query,
+ limit,
+ },
+ });
+ const handler = (members, guild) => {
+ if (guild.id !== this.id) return;
+ if (this.memberCount === this.members.size || members.length < 1000) {
+ this.client.removeListener(Constants.Events.GUILD_MEMBERS_CHUNK, handler);
+ // Uncomment in v12
+ // resolve(this.members)
+ resolve(this);
+ }
+ };
+ this.client.on(Constants.Events.GUILD_MEMBERS_CHUNK, handler);
+ this.client.setTimeout(() => reject(new Error('Members didn\'t arrive in time.')), 120 * 1000);
+ });
+ }
+
+ /**
+ * Performs a search within the entire guild.
+ * This is only available when using a user account.
+ * @param {MessageSearchOptions} [options={}] Options to pass to the search
+ * @returns {Promise>}
+ * An array containing arrays of messages. Each inner array is a search context cluster.
+ * The message which has triggered the result will have the `hit` property set to `true`.
+ * @example
+ * guild.search({
+ * content: 'discord.js',
+ * before: '2016-11-17'
+ * }).then(res => {
+ * const hit = res.messages[0].find(m => m.hit).content;
+ * console.log(`I found: **${hit}**, total results: ${res.totalResults}`);
+ * }).catch(console.error);
+ */
+ search(options = {}) {
+ return this.client.rest.methods.search(this, options);
+ }
+
+ /**
+ * The data for editing a guild.
+ * @typedef {Object} GuildEditData
+ * @property {string} [name] The name of the guild
+ * @property {string} [region] The region of the guild
+ * @property {number} [verificationLevel] The verification level of the guild
+ * @property {ChannelResolvable} [afkChannel] The AFK channel of the guild
+ * @property {number} [afkTimeout] The AFK timeout of the guild
+ * @property {Base64Resolvable} [icon] The icon of the guild
+ * @property {GuildMemberResolvable} [owner] The owner of the guild
+ * @property {Base64Resolvable} [splash] The splash screen of the guild
+ */
+
+ /**
+ * Updates the guild with new information - e.g. a new name.
+ * @param {GuildEditData} data The data to update the guild with
+ * @returns {Promise}
+ * @example
+ * // Set the guild name and region
+ * guild.edit({
+ * name: 'Discord Guild',
+ * region: 'london',
+ * })
+ * .then(updated => console.log(`New guild name ${updated.name} in region ${updated.region}`))
+ * .catch(console.error);
+ */
+ edit(data) {
+ return this.client.rest.methods.updateGuild(this, data);
+ }
+
+ /**
+ * Edit the name of the guild.
+ * @param {string} name The new name of the guild
+ * @returns {Promise}
+ * @example
+ * // Edit the guild name
+ * guild.setName('Discord Guild')
+ * .then(updated => console.log(`Updated guild name to ${guild.name}`))
+ * .catch(console.error);
+ */
+ setName(name) {
+ return this.edit({ name });
+ }
+
+ /**
+ * Edit the region of the guild.
+ * @param {string} region The new region of the guild
+ * @returns {Promise}
+ * @example
+ * // Edit the guild region
+ * guild.setRegion('london')
+ * .then(updated => console.log(`Updated guild region to ${guild.region}`))
+ * .catch(console.error);
+ */
+ setRegion(region) {
+ return this.edit({ region });
+ }
+
+ /**
+ * Edit the verification level of the guild.
+ * @param {number} verificationLevel The new verification level of the guild
+ * @returns {Promise}
+ * @example
+ * // Edit the guild verification level
+ * guild.setVerificationLevel(1)
+ * .then(updated => console.log(`Updated guild verification level to ${guild.verificationLevel}`))
+ * .catch(console.error);
+ */
+ setVerificationLevel(verificationLevel) {
+ return this.edit({ verificationLevel });
+ }
+
+ /**
+ * Edit the AFK channel of the guild.
+ * @param {ChannelResolvable} afkChannel The new AFK channel
+ * @returns {Promise}
+ * @example
+ * // Edit the guild AFK channel
+ * guild.setAFKChannel(channel)
+ * .then(updated => console.log(`Updated guild AFK channel to ${guild.afkChannel}`))
+ * .catch(console.error);
+ */
+ setAFKChannel(afkChannel) {
+ return this.edit({ afkChannel });
+ }
+
+ /**
+ * Edit the AFK timeout of the guild.
+ * @param {number} afkTimeout The time in seconds that a user must be idle to be considered AFK
+ * @returns {Promise}
+ * @example
+ * // Edit the guild AFK channel
+ * guild.setAFKTimeout(60)
+ * .then(updated => console.log(`Updated guild AFK timeout to ${guild.afkTimeout}`))
+ * .catch(console.error);
+ */
+ setAFKTimeout(afkTimeout) {
+ return this.edit({ afkTimeout });
+ }
+
+ /**
+ * Set a new guild icon.
+ * @param {Base64Resolvable} icon The new icon of the guild
+ * @returns {Promise}
+ * @example
+ * // Edit the guild icon
+ * guild.setIcon(fs.readFileSync('./icon.png'))
+ * .then(updated => console.log('Updated the guild icon'))
+ * .catch(console.error);
+ */
+ setIcon(icon) {
+ return this.edit({ icon });
+ }
+
+ /**
+ * Sets a new owner of the guild.
+ * @param {GuildMemberResolvable} owner The new owner of the guild
+ * @returns {Promise}
+ * @example
+ * // Edit the guild owner
+ * guild.setOwner(guild.members.first())
+ * .then(updated => console.log(`Updated the guild owner to ${updated.owner.username}`))
+ * .catch(console.error);
+ */
+ setOwner(owner) {
+ return this.edit({ owner });
+ }
+
+ /**
+ * Set a new guild splash screen.
+ * @param {Base64Resolvable} splash The new splash screen of the guild
+ * @returns {Promise}
+ * @example
+ * // Edit the guild splash
+ * guild.setIcon(fs.readFileSync('./splash.png'))
+ * .then(updated => console.log('Updated the guild splash'))
+ * .catch(console.error);
+ */
+ setSplash(splash) {
+ return this.edit({ splash });
+ }
+
+ /**
+ * @param {number} position Absolute or relative position
+ * @param {boolean} [relative=false] Whether to position relatively or absolutely
+ * @returns {Promise}
+ */
+ setPosition(position, relative) {
+ if (this.client.user.bot) {
+ return Promise.reject(new Error('Setting guild position is only available for user accounts'));
+ }
+ return this.client.user.settings.setGuildPosition(this, position, relative);
+ }
+
+ /**
+ * Marks all messages in this guild as read.
+ * This is only available when using a user account.
+ * @returns {Promise} This guild
+ */
+ acknowledge() {
+ return this.client.rest.methods.ackGuild(this);
+ }
+
+ /**
+ * Allow direct messages from guild members.
+ * @param {boolean} allow Whether to allow direct messages
+ * @returns {Promise}
+ */
+ allowDMs(allow) {
+ const settings = this.client.user.settings;
+ if (allow) return settings.removeRestrictedGuild(this);
+ else return settings.addRestrictedGuild(this);
+ }
+
+ /**
+ * Bans a user from the guild.
+ * @param {UserResolvable} user The user to ban
+ * @param {Object|number|string} [options] Ban options. If a number, the number of days to delete messages for, if a
+ * string, the ban reason. Supplying an object allows you to do both.
+ * @param {number} [options.days=0] Number of days of messages to delete
+ * @param {string} [options.reason] Reason for banning
+ * @returns {Promise} Result object will be resolved as specifically as possible.
+ * If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot
+ * be resolved, the user ID will be the result.
+ * @example
+ * // Ban a user by ID (or with a user/guild member object)
+ * guild.ban('some user ID')
+ * .then(user => console.log(`Banned ${user.username || user.id || user} from ${guild.name}`))
+ * .catch(console.error);
+ */
+ ban(user, options = {}) {
+ if (typeof options === 'number') {
+ options = { reason: null, 'delete-message-days': options };
+ } else if (typeof options === 'string') {
+ options = { reason: options, 'delete-message-days': 0 };
+ }
+ if (options.days) options['delete-message-days'] = options.days;
+ return this.client.rest.methods.banGuildMember(this, user, options);
+ }
+
+ /**
+ * Unbans a user from the guild.
+ * @param {UserResolvable} user The user to unban
+ * @returns {Promise}
+ * @example
+ * // Unban a user by ID (or with a user/guild member object)
+ * guild.unban('some user ID')
+ * .then(user => console.log(`Unbanned ${user.username} from ${guild.name}`))
+ * .catch(console.error);
+ */
+ unban(user) {
+ return this.client.rest.methods.unbanGuildMember(this, user);
+ }
+
+ /**
+ * Prunes members from the guild based on how long they have been inactive.
+ * @param {number} days Number of days of inactivity required to kick
+ * @param {boolean} [dry=false] If true, will return number of users that will be kicked, without actually doing it
+ * @returns {Promise} The number of members that were/will be kicked
+ * @example
+ * // See how many members will be pruned
+ * guild.pruneMembers(12, true)
+ * .then(pruned => console.log(`This will prune ${pruned} people!`))
+ * .catch(console.error);
+ * @example
+ * // Actually prune the members
+ * guild.pruneMembers(12)
+ * .then(pruned => console.log(`I just pruned ${pruned} people!`))
+ * .catch(console.error);
+ */
+ pruneMembers(days, dry = false) {
+ if (typeof days !== 'number') throw new TypeError('Days must be a number.');
+ return this.client.rest.methods.pruneGuildMembers(this, days, dry);
+ }
+
+ /**
+ * Syncs this guild (already done automatically every 30 seconds).
+ * This is only available when using a user account.
+ */
+ sync() {
+ if (!this.client.user.bot) this.client.syncGuilds([this]);
+ }
+
+ /**
+ * Creates a new channel in the guild.
+ * @param {string} name The name of the new channel
+ * @param {string} type The type of the new channel, either `text` or `voice`
+ * @param {Array} overwrites Permission overwrites to apply to the new channel
+ * @returns {Promise}
+ * @example
+ * // Create a new text channel
+ * guild.createChannel('new-general', 'text')
+ * .then(channel => console.log(`Created new channel ${channel}`))
+ * .catch(console.error);
+ */
+ createChannel(name, type, overwrites) {
+ return this.client.rest.methods.createChannel(this, name, type, overwrites);
+ }
+
+ /**
+ * The data needed for updating a channel's position.
+ * @typedef {Object} ChannelPosition
+ * @property {ChannelResolvable} channel Channel to update
+ * @property {number} position New position for the channel
+ */
+
+ /**
+ * Batch-updates the guild's channels' positions.
+ * @param {ChannelPosition[]} channelPositions Channel positions to update
+ * @returns {Promise}
+ * @example
+ * guild.updateChannels([{ channel: channelID, position: newChannelIndex }])
+ * .then(guild => console.log(`Updated channel positions for ${guild.id}`))
+ * .catch(console.error);
+ */
+ setChannelPositions(channelPositions) {
+ return this.client.rest.methods.updateChannelPositions(this.id, channelPositions);
+ }
+
+ /**
+ * Creates a new role in the guild with given information
+ * @param {RoleData} [data] The data to update the role with
+ * @returns {Promise}
+ * @example
+ * // Create a new role
+ * guild.createRole()
+ * .then(role => console.log(`Created role ${role}`))
+ * .catch(console.error);
+ * @example
+ * // Create a new role with data
+ * guild.createRole({
+ * name: 'Super Cool People',
+ * color: 'BLUE',
+ * })
+ * .then(role => console.log(`Created role ${role}`))
+ * .catch(console.error)
+ */
+ createRole(data = {}) {
+ return this.client.rest.methods.createGuildRole(this, data);
+ }
+
+ /**
+ * Creates a new custom emoji in the guild.
+ * @param {BufferResolvable|Base64Resolvable} attachment The image for the emoji
+ * @param {string} name The name for the emoji
+ * @param {Collection|Role[]} [roles] Roles to limit the emoji to
+ * @returns {Promise} The created emoji
+ * @example
+ * // Create a new emoji from a url
+ * guild.createEmoji('https://i.imgur.com/w3duR07.png', 'rip')
+ * .then(emoji => console.log(`Created new emoji with name ${emoji.name}!`))
+ * .catch(console.error);
+ * @example
+ * // Create a new emoji from a file on your computer
+ * guild.createEmoji('./memes/banana.png', 'banana')
+ * .then(emoji => console.log(`Created new emoji with name ${emoji.name}!`))
+ * .catch(console.error);
+ */
+ createEmoji(attachment, name, roles) {
+ return new Promise(resolve => {
+ if (typeof attachment === 'string' && attachment.startsWith('data:')) {
+ resolve(this.client.rest.methods.createEmoji(this, attachment, name, roles));
+ } else {
+ this.client.resolver.resolveBuffer(attachment).then(data => {
+ const dataURI = this.client.resolver.resolveBase64(data);
+ resolve(this.client.rest.methods.createEmoji(this, dataURI, name, roles));
+ });
+ }
+ });
+ }
+
+ /**
+ * Delete an emoji.
+ * @param {Emoji|string} emoji The emoji to delete
+ * @returns {Promise}
+ */
+ deleteEmoji(emoji) {
+ if (!(emoji instanceof Emoji)) emoji = this.emojis.get(emoji);
+ return this.client.rest.methods.deleteEmoji(emoji);
+ }
+
+ /**
+ * Causes the client to leave the guild.
+ * @returns {Promise}
+ * @example
+ * // Leave a guild
+ * guild.leave()
+ * .then(g => console.log(`Left the guild ${g}`))
+ * .catch(console.error);
+ */
+ leave() {
+ return this.client.rest.methods.leaveGuild(this);
+ }
+
+ /**
+ * Causes the client to delete the guild.
+ * @returns {Promise}
+ * @example
+ * // Delete a guild
+ * guild.delete()
+ * .then(g => console.log(`Deleted the guild ${g}`))
+ * .catch(console.error);
+ */
+ delete() {
+ return this.client.rest.methods.deleteGuild(this);
+ }
+
+ /**
+ * Whether this guild equals another guild. It compares all properties, so for most operations
+ * it is advisable to just compare `guild.id === guild2.id` as it is much faster and is often
+ * what most users need.
+ * @param {Guild} guild The guild to compare with
+ * @returns {boolean}
+ */
+ equals(guild) {
+ let equal =
+ guild &&
+ this.id === guild.id &&
+ this.available === !guild.unavailable &&
+ this.splash === guild.splash &&
+ this.region === guild.region &&
+ this.name === guild.name &&
+ this.memberCount === guild.member_count &&
+ this.large === guild.large &&
+ this.icon === guild.icon &&
+ Util.arraysEqual(this.features, guild.features) &&
+ this.ownerID === guild.owner_id &&
+ this.verificationLevel === guild.verification_level &&
+ this.embedEnabled === guild.embed_enabled;
+
+ if (equal) {
+ if (this.embedChannel) {
+ if (this.embedChannel.id !== guild.embed_channel_id) equal = false;
+ } else if (guild.embed_channel_id) {
+ equal = false;
+ }
+ }
+
+ return equal;
+ }
+
+ /**
+ * When concatenated with a string, this automatically concatenates the guild's name instead of the guild object.
+ * @returns {string}
+ * @example
+ * // Logs: Hello from My Guild!
+ * console.log(`Hello from ${guild}!`);
+ * @example
+ * // Logs: Hello from My Guild!
+ * console.log('Hello from ' + guild + '!');
+ */
+ toString() {
+ return this.name;
+ }
+
+ _addMember(guildUser, emitEvent = true) {
+ const existing = this.members.has(guildUser.user.id);
+ if (!(guildUser.user instanceof User)) guildUser.user = this.client.dataManager.newUser(guildUser.user);
+
+ guildUser.joined_at = guildUser.joined_at || 0;
+ const member = new GuildMember(this, guildUser);
+ this.members.set(member.id, member);
+
+ if (this._rawVoiceStates && this._rawVoiceStates.has(member.user.id)) {
+ const voiceState = this._rawVoiceStates.get(member.user.id);
+ member.serverMute = voiceState.mute;
+ member.serverDeaf = voiceState.deaf;
+ member.selfMute = voiceState.self_mute;
+ member.selfDeaf = voiceState.self_deaf;
+ member.voiceSessionID = voiceState.session_id;
+ member.voiceChannelID = voiceState.channel_id;
+ if (this.client.channels.has(voiceState.channel_id)) {
+ this.client.channels.get(voiceState.channel_id).members.set(member.user.id, member);
+ } else {
+ this.client.emit('warn', `Member ${member.id} added in guild ${this.id} with an uncached voice channel`);
+ }
+ }
+
+ /**
+ * Emitted whenever a user joins a guild.
+ * @event Client#guildMemberAdd
+ * @param {GuildMember} member The member that has joined a guild
+ */
+ if (this.client.ws.connection.status === Constants.Status.READY && emitEvent && !existing) {
+ this.client.emit(Constants.Events.GUILD_MEMBER_ADD, member);
+ }
+
+ return member;
+ }
+
+ _updateMember(member, data) {
+ const oldMember = Util.cloneObject(member);
+
+ if (data.roles) member._roles = data.roles;
+ if (typeof data.nick !== 'undefined') member.nickname = data.nick;
+
+ const notSame = member.nickname !== oldMember.nickname || !Util.arraysEqual(member._roles, oldMember._roles);
+
+ if (this.client.ws.connection.status === Constants.Status.READY && notSame) {
+ /**
+ * Emitted whenever a guild member changes - i.e. new role, removed role, nickname.
+ * @event Client#guildMemberUpdate
+ * @param {GuildMember} oldMember The member before the update
+ * @param {GuildMember} newMember The member after the update
+ */
+ this.client.emit(Constants.Events.GUILD_MEMBER_UPDATE, oldMember, member);
+ }
+
+ return {
+ old: oldMember,
+ mem: member,
+ };
+ }
+
+ _removeMember(guildMember) {
+ this.members.delete(guildMember.id);
+ }
+
+ _memberSpeakUpdate(user, speaking) {
+ const member = this.members.get(user);
+ if (member && member.speaking !== speaking) {
+ member.speaking = speaking;
+ /**
+ * Emitted once a guild member starts/stops speaking.
+ * @event Client#guildMemberSpeaking
+ * @param {GuildMember} member The member that started/stopped speaking
+ * @param {boolean} speaking Whether or not the member is speaking
+ */
+ this.client.emit(Constants.Events.GUILD_MEMBER_SPEAKING, member, speaking);
+ }
+ }
+
+ _setPresence(id, presence) {
+ if (this.presences.get(id)) {
+ this.presences.get(id).update(presence);
+ return;
+ }
+ this.presences.set(id, new Presence(presence));
+ }
+
+ /**
+ * Set the position of a role in this guild.
+ * @param {string|Role} role The role to edit, can be a role object or a role ID
+ * @param {number} position The new position of the role
+ * @param {boolean} [relative=false] Position Moves the role relative to its current position
+ * @returns {Promise}
+ */
+ setRolePosition(role, position, relative = false) {
+ if (typeof role === 'string') {
+ role = this.roles.get(role);
+ if (!role) return Promise.reject(new Error('Supplied role is not a role or snowflake.'));
+ }
+
+ position = Number(position);
+ if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.'));
+
+ let updatedRoles = this._sortedRoles.array();
+
+ Util.moveElementInArray(updatedRoles, role, position, relative);
+
+ updatedRoles = updatedRoles.map((r, i) => ({ id: r.id, position: i }));
+ return this.client.rest.methods.setRolePositions(this.id, updatedRoles);
+ }
+
+ /**
+ * Set the position of a channel in this guild.
+ * @param {string|GuildChannel} channel The channel to edit, can be a channel object or a channel ID
+ * @param {number} position The new position of the channel
+ * @param {boolean} [relative=false] Position Moves the channel relative to its current position
+ * @returns {Promise}
+ */
+ setChannelPosition(channel, position, relative = false) {
+ if (typeof channel === 'string') {
+ channel = this.channels.get(channel);
+ if (!channel) return Promise.reject(new Error('Supplied channel is not a channel or snowflake.'));
+ }
+
+ position = Number(position);
+ if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.'));
+
+ let updatedChannels = this._sortedChannels(channel.type).array();
+
+ Util.moveElementInArray(updatedChannels, channel, position, relative);
+
+ updatedChannels = updatedChannels.map((r, i) => ({ id: r.id, position: i }));
+ return this.client.rest.methods.setChannelPositions(this.id, updatedChannels);
+ }
+
+ /**
+ * Fetches a collection of channels in the current guild sorted by position.
+ * @param {string} type The channel type
+ * @returns {Collection}
+ * @private
+ */
+ _sortedChannels(type) {
+ return this._sortPositionWithID(this.channels.filter(c => {
+ if (type === 'voice' && c.type === 'voice') return true;
+ else if (type !== 'voice' && c.type !== 'voice') return true;
+ else return type === c.type;
+ }));
+ }
+
+ /**
+ * Sorts a collection by object position or ID if the positions are equivalent.
+ * Intended to be identical to Discord's sorting method.
+ * @param {Collection} collection The collection to sort
+ * @returns {Collection}
+ * @private
+ */
+ _sortPositionWithID(collection) {
+ return collection.sort((a, b) =>
+ a.position !== b.position ?
+ a.position - b.position :
+ Long.fromString(a.id).sub(Long.fromString(b.id)).toNumber()
+ );
+ }
+}
+
+module.exports = Guild;
+
+
+/***/ }),
+/* 26 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Channel = __webpack_require__(14);
+const Role = __webpack_require__(15);
+const PermissionOverwrites = __webpack_require__(54);
+const Permissions = __webpack_require__(9);
+const Collection = __webpack_require__(3);
+
+/**
+ * Represents a guild channel (i.e. text channels and voice channels).
+ * @extends {Channel}
+ */
+class GuildChannel extends Channel {
+ constructor(guild, data) {
+ super(guild.client, data);
+
+ /**
+ * The guild the channel is in
+ * @type {Guild}
+ */
+ this.guild = guild;
+ }
+
+ setup(data) {
+ super.setup(data);
+
+ /**
+ * The name of the guild channel
+ * @type {string}
+ */
+ this.name = data.name;
+
+ /**
+ * The position of the channel in the list
+ * @type {number}
+ */
+ this.position = data.position;
+
+ /**
+ * A map of permission overwrites in this channel for roles and users
+ * @type {Collection}
+ */
+ this.permissionOverwrites = new Collection();
+ if (data.permission_overwrites) {
+ for (const overwrite of data.permission_overwrites) {
+ this.permissionOverwrites.set(overwrite.id, new PermissionOverwrites(this, overwrite));
+ }
+ }
+ }
+
+ /**
+ * The position of the channel
+ * @type {number}
+ * @readonly
+ */
+ get calculatedPosition() {
+ const sorted = this.guild._sortedChannels(this.type);
+ return sorted.array().indexOf(sorted.get(this.id));
+ }
+
+ /**
+ * Gets the overall set of permissions for a user in this channel, taking into account roles and permission
+ * overwrites.
+ * @param {GuildMemberResolvable} member The user that you want to obtain the overall permissions for
+ * @returns {?Permissions}
+ */
+ permissionsFor(member) {
+ member = this.client.resolver.resolveGuildMember(this.guild, member);
+ if (!member) return null;
+ if (member.id === this.guild.ownerID) return new Permissions(member, Permissions.ALL);
+
+ let permissions = 0;
+
+ const roles = member.roles;
+ for (const role of roles.values()) permissions |= role.permissions;
+
+ const overwrites = this.overwritesFor(member, true, roles);
+
+ if (overwrites.everyone) {
+ permissions &= ~overwrites.everyone.deny;
+ permissions |= overwrites.everyone.allow;
+ }
+
+ let allow = 0;
+ for (const overwrite of overwrites.roles) {
+ permissions &= ~overwrite.deny;
+ allow |= overwrite.allow;
+ }
+ permissions |= allow;
+
+ if (overwrites.member) {
+ permissions &= ~overwrites.member.deny;
+ permissions |= overwrites.member.allow;
+ }
+
+ const admin = Boolean(permissions & Permissions.FLAGS.ADMINISTRATOR);
+ if (admin) permissions = Permissions.ALL;
+
+ return new Permissions(member, permissions);
+ }
+
+ overwritesFor(member, verified = false, roles = null) {
+ if (!verified) member = this.client.resolver.resolveGuildMember(this.guild, member);
+ if (!member) return [];
+
+ roles = roles || member.roles;
+ const roleOverwrites = [];
+ let memberOverwrites;
+ let everyoneOverwrites;
+
+ for (const overwrite of this.permissionOverwrites.values()) {
+ if (overwrite.id === this.guild.id) {
+ everyoneOverwrites = overwrite;
+ } else if (roles.has(overwrite.id)) {
+ roleOverwrites.push(overwrite);
+ } else if (overwrite.id === member.id) {
+ memberOverwrites = overwrite;
+ }
+ }
+
+ return {
+ everyone: everyoneOverwrites,
+ roles: roleOverwrites,
+ member: memberOverwrites,
+ };
+ }
+
+ /**
+ * An object mapping permission flags to `true` (enabled) or `false` (disabled).
+ * ```js
+ * {
+ * 'SEND_MESSAGES': true,
+ * 'ATTACH_FILES': false,
+ * }
+ * ```
+ * @typedef {Object} PermissionOverwriteOptions
+ */
+
+ /**
+ * Overwrites the permissions for a user or role in this channel.
+ * @param {RoleResolvable|UserResolvable} userOrRole The user or role to update
+ * @param {PermissionOverwriteOptions} options The configuration for the update
+ * @returns {Promise}
+ * @example
+ * // Overwrite permissions for a message author
+ * message.channel.overwritePermissions(message.author, {
+ * SEND_MESSAGES: false
+ * })
+ * .then(() => console.log('Done!'))
+ * .catch(console.error);
+ */
+ overwritePermissions(userOrRole, options) {
+ const payload = {
+ allow: 0,
+ deny: 0,
+ };
+
+ if (userOrRole instanceof Role) {
+ payload.type = 'role';
+ } else if (this.guild.roles.has(userOrRole)) {
+ userOrRole = this.guild.roles.get(userOrRole);
+ payload.type = 'role';
+ } else {
+ userOrRole = this.client.resolver.resolveUser(userOrRole);
+ payload.type = 'member';
+ if (!userOrRole) return Promise.reject(new TypeError('Supplied parameter was neither a User nor a Role.'));
+ }
+
+ payload.id = userOrRole.id;
+
+ const prevOverwrite = this.permissionOverwrites.get(userOrRole.id);
+
+ if (prevOverwrite) {
+ payload.allow = prevOverwrite.allow;
+ payload.deny = prevOverwrite.deny;
+ }
+
+ for (const perm in options) {
+ if (options[perm] === true) {
+ payload.allow |= Permissions.FLAGS[perm] || 0;
+ payload.deny &= ~(Permissions.FLAGS[perm] || 0);
+ } else if (options[perm] === false) {
+ payload.allow &= ~(Permissions.FLAGS[perm] || 0);
+ payload.deny |= Permissions.FLAGS[perm] || 0;
+ } else if (options[perm] === null) {
+ payload.allow &= ~(Permissions.FLAGS[perm] || 0);
+ payload.deny &= ~(Permissions.FLAGS[perm] || 0);
+ }
+ }
+
+ return this.client.rest.methods.setChannelOverwrite(this, payload);
+ }
+
+ /**
+ * The data for a guild channel.
+ * @typedef {Object} ChannelData
+ * @property {string} [name] The name of the channel
+ * @property {number} [position] The position of the channel
+ * @property {string} [topic] The topic of the text channel
+ * @property {number} [bitrate] The bitrate of the voice channel
+ * @property {number} [userLimit] The user limit of the channel
+ */
+
+ /**
+ * Edits the channel.
+ * @param {ChannelData} data The new data for the channel
+ * @returns {Promise}
+ * @example
+ * // Edit a channel
+ * channel.edit({name: 'new-channel'})
+ * .then(c => console.log(`Edited channel ${c}`))
+ * .catch(console.error);
+ */
+ edit(data) {
+ return this.client.rest.methods.updateChannel(this, data);
+ }
+
+ /**
+ * Set a new name for the guild channel.
+ * @param {string} name The new name for the guild channel
+ * @returns {Promise}
+ * @example
+ * // Set a new channel name
+ * channel.setName('not_general')
+ * .then(newChannel => console.log(`Channel's new name is ${newChannel.name}`))
+ * .catch(console.error);
+ */
+ setName(name) {
+ return this.edit({ name });
+ }
+
+ /**
+ * Set a new position for the guild channel.
+ * @param {number} position The new position for the guild channel
+ * @param {boolean} [relative=false] Move the position relative to its current value
+ * @returns {Promise}
+ * @example
+ * // Set a new channel position
+ * channel.setPosition(2)
+ * .then(newChannel => console.log(`Channel's new position is ${newChannel.position}`))
+ * .catch(console.error);
+ */
+ setPosition(position, relative) {
+ return this.guild.setChannelPosition(this, position, relative).then(() => this);
+ }
+
+ /**
+ * Set a new topic for the guild channel.
+ * @param {string} topic The new topic for the guild channel
+ * @returns {Promise}
+ * @example
+ * // Set a new channel topic
+ * channel.setTopic('needs more rate limiting')
+ * .then(newChannel => console.log(`Channel's new topic is ${newChannel.topic}`))
+ * .catch(console.error);
+ */
+ setTopic(topic) {
+ return this.client.rest.methods.updateChannel(this, { topic });
+ }
+
+ /**
+ * Options given when creating a guild channel invite.
+ * @typedef {Object} InviteOptions
+
+ */
+
+ /**
+ * Create an invite to this guild channel.
+ * @param {InviteOptions} [options={}] Options for the invite
+ * @param {boolean} [options.temporary=false] Whether members that joined via the invite should be automatically
+ * kicked after 24 hours if they have not yet received a role
+ * @param {number} [options.maxAge=86400] How long the invite should last (in seconds, 0 for forever)
+ * @param {number} [options.maxUses=0] Maximum number of uses
+ * @returns {Promise}
+ */
+ createInvite(options = {}) {
+ return this.client.rest.methods.createChannelInvite(this, options);
+ }
+
+ /**
+ * Clone this channel.
+ * @param {string} [name=this.name] Optional name for the new channel, otherwise it has the name of this channel
+ * @param {boolean} [withPermissions=true] Whether to clone the channel with this channel's permission overwrites
+ * @param {boolean} [withTopic=true] Whether to clone the channel with this channel's topic
+ * @returns {Promise}
+ */
+ clone(name = this.name, withPermissions = true, withTopic = true) {
+ return this.guild.createChannel(name, this.type, withPermissions ? this.permissionOverwrites : [])
+ .then(channel => withTopic ? channel.setTopic(this.topic) : channel);
+ }
+
+ /**
+ * Checks if this channel has the same type, topic, position, name, overwrites and ID as another channel.
+ * In most cases, a simple `channel.id === channel2.id` will do, and is much faster too.
+ * @param {GuildChannel} channel Channel to compare with
+ * @returns {boolean}
+ */
+ equals(channel) {
+ let equal = channel &&
+ this.id === channel.id &&
+ this.type === channel.type &&
+ this.topic === channel.topic &&
+ this.position === channel.position &&
+ this.name === channel.name;
+
+ if (equal) {
+ if (this.permissionOverwrites && channel.permissionOverwrites) {
+ equal = this.permissionOverwrites.equals(channel.permissionOverwrites);
+ } else {
+ equal = !this.permissionOverwrites && !channel.permissionOverwrites;
+ }
+ }
+
+ return equal;
+ }
+
+ /**
+ * Whether the channel is deletable by the client user
+ * @type {boolean}
+ * @readonly
+ */
+ get deletable() {
+ return this.id !== this.guild.id &&
+ this.permissionsFor(this.client.user).has(Permissions.FLAGS.MANAGE_CHANNELS);
+ }
+
+ /**
+ * When concatenated with a string, this automatically returns the channel's mention instead of the Channel object.
+ * @returns {string}
+ * @example
+ * // Outputs: Hello from #general
+ * console.log(`Hello from ${channel}`);
+ * @example
+ * // Outputs: Hello from #general
+ * console.log('Hello from ' + channel);
+ */
+ toString() {
+ return `<#${this.id}>`;
+ }
+}
+
+module.exports = GuildChannel;
+
+
+/***/ }),
+/* 27 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Snowflake = __webpack_require__(7);
+
+/**
+ * Represents an OAuth2 Application.
+ */
+class OAuth2Application {
+ constructor(client, data) {
+ /**
+ * The client that instantiated the application
+ * @name OAuth2Application#client
+ * @type {Client}
+ * @readonly
+ */
+ Object.defineProperty(this, 'client', { value: client });
+
+ this.setup(data);
+ }
+
+ setup(data) {
+ /**
+ * The ID of the app
+ * @type {Snowflake}
+ */
+ this.id = data.id;
+
+ /**
+ * The name of the app
+ * @type {string}
+ */
+ this.name = data.name;
+
+ /**
+ * The app's description
+ * @type {string}
+ */
+ this.description = data.description;
+
+ /**
+ * The app's icon hash
+ * @type {string}
+ */
+ this.icon = data.icon;
+
+ /**
+ * The app's icon URL
+ * @type {string}
+ */
+ this.iconURL = `https://cdn.discordapp.com/app-icons/${this.id}/${this.icon}.jpg`;
+
+ /**
+ * The app's RPC origins
+ * @type {?string[]}
+ */
+ this.rpcOrigins = data.rpc_origins;
+
+ /**
+ * The app's redirect URIs
+ * @type {string[]}
+ */
+ this.redirectURIs = data.redirect_uris;
+
+ /**
+ * If this app's bot requires a code grant when using the OAuth2 flow
+ * @type {boolean}
+ */
+ this.botRequireCodeGrant = data.bot_require_code_grant;
+
+ /**
+ * If this app's bot is public
+ * @type {boolean}
+ */
+ this.botPublic = data.bot_public;
+
+ /**
+ * If this app can use rpc
+ * @type {boolean}
+ */
+ this.rpcApplicationState = data.rpc_application_state;
+
+ /**
+ * Object containing basic info about this app's bot
+ * @type {Object}
+ */
+ this.bot = data.bot;
+
+ /**
+ * The flags for the app
+ * @type {number}
+ */
+ this.flags = data.flags;
+
+ /**
+ * OAuth2 secret for the application
+ * @type {boolean}
+ */
+ this.secret = data.secret;
+
+ if (data.owner) {
+ /**
+ * The owner of this OAuth application
+ * @type {?User}
+ */
+ this.owner = this.client.dataManager.newUser(data.owner);
+ }
+ }
+
+ /**
+ * The timestamp the app was created at
+ * @type {number}
+ * @readonly
+ */
+ get createdTimestamp() {
+ return Snowflake.deconstruct(this.id).timestamp;
+ }
+
+ /**
+ * The time the app was created
+ * @type {Date}
+ * @readonly
+ */
+ get createdAt() {
+ return new Date(this.createdTimestamp);
+ }
+
+ /**
+ * Reset the app's secret and bot token.
+ * @returns {OAuth2Application}
+ */
+ reset() {
+ return this.client.rest.methods.resetApplication(this.id);
+ }
+
+ /**
+ * When concatenated with a string, this automatically concatenates the app name rather than the app object.
+ * @returns {string}
+ */
+ toString() {
+ return this.name;
+ }
+}
+
+module.exports = OAuth2Application;
+
+
+/***/ }),
+/* 28 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// resolves . and .. elements in a path array with directory names there
+// must be no slashes, empty elements, or device names (c:\) in the array
+// (so also no leading and trailing slashes - it does not distinguish
+// relative and absolute paths)
+function normalizeArray(parts, allowAboveRoot) {
+ // if the path tries to go above the root, `up` ends up > 0
+ var up = 0;
+ for (var i = parts.length - 1; i >= 0; i--) {
+ var last = parts[i];
+ if (last === '.') {
+ parts.splice(i, 1);
+ } else if (last === '..') {
+ parts.splice(i, 1);
+ up++;
+ } else if (up) {
+ parts.splice(i, 1);
+ up--;
+ }
+ }
+
+ // if the path is allowed to go above the root, restore leading ..s
+ if (allowAboveRoot) {
+ for (; up--; up) {
+ parts.unshift('..');
+ }
+ }
+
+ return parts;
+}
+
+// Split a filename into [root, dir, basename, ext], unix version
+// 'root' is just a slash, or nothing.
+var splitPathRe =
+ /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+var splitPath = function(filename) {
+ return splitPathRe.exec(filename).slice(1);
+};
+
+// path.resolve([from ...], to)
+// posix version
+exports.resolve = function() {
+ var resolvedPath = '',
+ resolvedAbsolute = false;
+
+ for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+ var path = (i >= 0) ? arguments[i] : process.cwd();
+
+ // Skip empty and invalid entries
+ if (typeof path !== 'string') {
+ throw new TypeError('Arguments to path.resolve must be strings');
+ } else if (!path) {
+ continue;
+ }
+
+ resolvedPath = path + '/' + resolvedPath;
+ resolvedAbsolute = path.charAt(0) === '/';
+ }
+
+ // At this point the path should be resolved to a full absolute path, but
+ // handle relative paths to be safe (might happen when process.cwd() fails)
+
+ // Normalize the path
+ resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
+ return !!p;
+ }), !resolvedAbsolute).join('/');
+
+ return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+};
+
+// path.normalize(path)
+// posix version
+exports.normalize = function(path) {
+ var isAbsolute = exports.isAbsolute(path),
+ trailingSlash = substr(path, -1) === '/';
+
+ // Normalize the path
+ path = normalizeArray(filter(path.split('/'), function(p) {
+ return !!p;
+ }), !isAbsolute).join('/');
+
+ if (!path && !isAbsolute) {
+ path = '.';
+ }
+ if (path && trailingSlash) {
+ path += '/';
+ }
+
+ return (isAbsolute ? '/' : '') + path;
+};
+
+// posix version
+exports.isAbsolute = function(path) {
+ return path.charAt(0) === '/';
+};
+
+// posix version
+exports.join = function() {
+ var paths = Array.prototype.slice.call(arguments, 0);
+ return exports.normalize(filter(paths, function(p, index) {
+ if (typeof p !== 'string') {
+ throw new TypeError('Arguments to path.join must be strings');
+ }
+ return p;
+ }).join('/'));
+};
+
+
+// path.relative(from, to)
+// posix version
+exports.relative = function(from, to) {
+ from = exports.resolve(from).substr(1);
+ to = exports.resolve(to).substr(1);
+
+ function trim(arr) {
+ var start = 0;
+ for (; start < arr.length; start++) {
+ if (arr[start] !== '') break;
+ }
+
+ var end = arr.length - 1;
+ for (; end >= 0; end--) {
+ if (arr[end] !== '') break;
+ }
+
+ if (start > end) return [];
+ return arr.slice(start, end - start + 1);
+ }
+
+ var fromParts = trim(from.split('/'));
+ var toParts = trim(to.split('/'));
+
+ var length = Math.min(fromParts.length, toParts.length);
+ var samePartsLength = length;
+ for (var i = 0; i < length; i++) {
+ if (fromParts[i] !== toParts[i]) {
+ samePartsLength = i;
+ break;
+ }
+ }
+
+ var outputParts = [];
+ for (var i = samePartsLength; i < fromParts.length; i++) {
+ outputParts.push('..');
+ }
+
+ outputParts = outputParts.concat(toParts.slice(samePartsLength));
+
+ return outputParts.join('/');
+};
+
+exports.sep = '/';
+exports.delimiter = ':';
+
+exports.dirname = function(path) {
+ var result = splitPath(path),
+ root = result[0],
+ dir = result[1];
+
+ if (!root && !dir) {
+ // No dirname whatsoever
+ return '.';
+ }
+
+ if (dir) {
+ // It has a dirname, strip trailing slash
+ dir = dir.substr(0, dir.length - 1);
+ }
+
+ return root + dir;
+};
+
+
+exports.basename = function(path, ext) {
+ var f = splitPath(path)[2];
+ // TODO: make this comparison case-insensitive on windows?
+ if (ext && f.substr(-1 * ext.length) === ext) {
+ f = f.substr(0, f.length - ext.length);
+ }
+ return f;
+};
+
+
+exports.extname = function(path) {
+ return splitPath(path)[3];
+};
+
+function filter (xs, f) {
+ if (xs.filter) return xs.filter(f);
+ var res = [];
+ for (var i = 0; i < xs.length; i++) {
+ if (f(xs[i], i, xs)) res.push(xs[i]);
+ }
+ return res;
+}
+
+// String.prototype.substr - negative index don't work in IE8
+var substr = 'ab'.substr(-1) === 'b'
+ ? function (str, start, len) { return str.substr(start, len) }
+ : function (str, start, len) {
+ if (start < 0) start = str.length + start;
+ return str.substr(start, len);
+ }
+;
+
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6)))
+
+/***/ }),
+/* 29 */
+/***/ (function(module, exports) {
+
+
+
+/***/ }),
+/* 30 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Channel = __webpack_require__(14);
+const TextBasedChannel = __webpack_require__(23);
+const Collection = __webpack_require__(3);
+
+/*
+{ type: 3,
+ recipients:
+ [ { username: 'Charlie',
+ id: '123',
+ discriminator: '6631',
+ avatar: '123' },
+ { username: 'Ben',
+ id: '123',
+ discriminator: '2055',
+ avatar: '123' },
+ { username: 'Adam',
+ id: '123',
+ discriminator: '2406',
+ avatar: '123' } ],
+ owner_id: '123',
+ name: null,
+ last_message_id: '123',
+ id: '123',
+ icon: null }
+*/
+
+/**
+ * Represents a Group DM on Discord.
+ * @extends {Channel}
+ * @implements {TextBasedChannel}
+ */
+class GroupDMChannel extends Channel {
+ constructor(client, data) {
+ super(client, data);
+ this.type = 'group';
+ this.messages = new Collection();
+ this._typing = new Map();
+ }
+
+ setup(data) {
+ super.setup(data);
+
+ /**
+ * The name of this Group DM, can be null if one isn't set
+ * @type {string}
+ */
+ this.name = data.name;
+
+ /**
+ * A hash of the Group DM icon.
+ * @type {string}
+ */
+ this.icon = data.icon;
+
+ /**
+ * The user ID of this Group DM's owner
+ * @type {string}
+ */
+ this.ownerID = data.owner_id;
+
+ /**
+ * If the DM is managed by an application
+ * @type {boolean}
+ */
+ this.managed = data.managed;
+
+ /**
+ * Application ID of the application that made this Group DM, if applicable
+ * @type {?string}
+ */
+ this.applicationID = data.application_id;
+
+ /**
+ * Nicknames for group members
+ * @type {?Collection}
+ */
+ if (data.nicks) this.nicks = new Collection(data.nicks.map(n => [n.id, n.nick]));
+
+ if (!this.recipients) {
+ /**
+ * A collection of the recipients of this DM, mapped by their ID
+ * @type {Collection}
+ */
+ this.recipients = new Collection();
+ }
+
+ if (data.recipients) {
+ for (const recipient of data.recipients) {
+ const user = this.client.dataManager.newUser(recipient);
+ this.recipients.set(user.id, user);
+ }
+ }
+
+ this.lastMessageID = data.last_message_id;
+ }
+
+ /**
+ * The owner of this Group DM
+ * @type {User}
+ * @readonly
+ */
+ get owner() {
+ return this.client.users.get(this.ownerID);
+ }
+
+ /**
+ * Whether this channel equals another channel. It compares all properties, so for most operations
+ * it is advisable to just compare `channel.id === channel2.id` as it is much faster and is often
+ * what most users need.
+ * @param {GroupDMChannel} channel Channel to compare with
+ * @returns {boolean}
+ */
+ equals(channel) {
+ const equal = channel &&
+ this.id === channel.id &&
+ this.name === channel.name &&
+ this.icon === channel.icon &&
+ this.ownerID === channel.ownerID;
+
+ if (equal) {
+ return this.recipients.equals(channel.recipients);
+ }
+
+ return equal;
+ }
+
+ /**
+ * Add a user to the DM
+ * @param {UserResolvable|string} accessTokenOrID Access token or user resolvable
+ * @param {string} [nick] Permanent nickname to give the user (only available if a bot is creating the DM)
+ */
+
+ addUser(accessTokenOrID, nick) {
+ return this.client.rest.methods.addUserToGroupDM(this, {
+ nick,
+ id: this.client.resolver.resolveUserID(accessTokenOrID),
+ accessToken: accessTokenOrID,
+ });
+ }
+
+ /**
+ * When concatenated with a string, this automatically concatenates the channel's name instead of the Channel object.
+ * @returns {string}
+ * @example
+ * // Logs: Hello from My Group DM!
+ * console.log(`Hello from ${channel}!`);
+ * @example
+ * // Logs: Hello from My Group DM!
+ * console.log(`Hello from ' + channel + '!');
+ */
+ toString() {
+ return this.name;
+ }
+
+ // These are here only for documentation purposes - they are implemented by TextBasedChannel
+ /* eslint-disable no-empty-function */
+ send() {}
+ sendMessage() {}
+ sendEmbed() {}
+ sendFile() {}
+ sendFiles() {}
+ sendCode() {}
+ fetchMessage() {}
+ fetchMessages() {}
+ fetchPinnedMessages() {}
+ search() {}
+ startTyping() {}
+ stopTyping() {}
+ get typing() {}
+ get typingCount() {}
+ createCollector() {}
+ awaitMessages() {}
+ // Doesn't work on Group DMs; bulkDelete() {}
+ acknowledge() {}
+ _cacheMessage() {}
+}
+
+TextBasedChannel.applyToClass(GroupDMChannel, true, ['bulkDelete']);
+
+module.exports = GroupDMChannel;
+
+
+/***/ }),
+/* 31 */
+/***/ (function(module, exports) {
+
+/**
+ * Represents a limited emoji set used for both custom and unicode emojis. Custom emojis
+ * will use this class opposed to the Emoji class when the client doesn't know enough
+ * information about them.
+ */
+class ReactionEmoji {
+ constructor(reaction, name, id) {
+ /**
+ * The message reaction this emoji refers to
+ * @type {MessageReaction}
+ */
+ this.reaction = reaction;
+
+ /**
+ * The name of this reaction emoji
+ * @type {string}
+ */
+ this.name = name;
+
+ /**
+ * The ID of this reaction emoji
+ * @type {?Snowflake}
+ */
+ this.id = id;
+ }
+
+ /**
+ * The identifier of this emoji, used for message reactions
+ * @type {string}
+ * @readonly
+ */
+ get identifier() {
+ if (this.id) return `${this.name}:${this.id}`;
+ return encodeURIComponent(this.name);
+ }
+
+ /**
+ * Creates the text required to form a graphical emoji on Discord.
+ * @example
+ * // Send the emoji used in a reaction to the channel the reaction is part of
+ * reaction.message.channel.sendMessage(`The emoji used is ${reaction.emoji}`);
+ * @returns {string}
+ */
+ toString() {
+ return this.id ? `<:${this.name}:${this.id}>` : this.name;
+ }
+}
+
+module.exports = ReactionEmoji;
+
+
+/***/ }),
+/* 32 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const path = __webpack_require__(28);
+
+/**
+ * Represents a webhook.
+ */
+class Webhook {
+ constructor(client, dataOrID, token) {
+ if (client) {
+ /**
+ * The client that instantiated the webhook
+ * @name Webhook#client
+ * @type {Client}
+ * @readonly
+ */
+ Object.defineProperty(this, 'client', { value: client });
+ if (dataOrID) this.setup(dataOrID);
+ } else {
+ this.id = dataOrID;
+ this.token = token;
+ Object.defineProperty(this, 'client', { value: this });
+ }
+ }
+
+ setup(data) {
+ /**
+ * The name of the webhook
+ * @type {string}
+ */
+ this.name = data.name;
+
+ /**
+ * The token for the webhook
+ * @type {string}
+ */
+ this.token = data.token;
+
+ /**
+ * The avatar for the webhook
+ * @type {string}
+ */
+ this.avatar = data.avatar;
+
+ /**
+ * The ID of the webhook
+ * @type {Snowflake}
+ */
+ this.id = data.id;
+
+ /**
+ * The guild the webhook belongs to
+ * @type {Snowflake}
+ */
+ this.guildID = data.guild_id;
+
+ /**
+ * The channel the webhook belongs to
+ * @type {Snowflake}
+ */
+ this.channelID = data.channel_id;
+
+ if (data.user) {
+ /**
+ * The owner of the webhook
+ * @type {?User|Object}
+ */
+ this.owner = this.client.users ? this.client.users.get(data.user.id) : data.user;
+ } else {
+ this.owner = null;
+ }
+ }
+
+ /**
+ * Options that can be passed into send, sendMessage, sendFile, sendEmbed, and sendCode.
+ * @typedef {Object} WebhookMessageOptions
+ * @property {string} [username=this.name] Username override for the message
+ * @property {string} [avatarURL] Avatar URL override for the message
+ * @property {boolean} [tts=false] Whether or not the message should be spoken aloud
+ * @property {string} [nonce=''] The nonce for the message
+ * @property {Object[]} [embeds] An array of embeds for the message
+ * (see [here](https://discordapp.com/developers/docs/resources/channel#embed-object) for more details)
+ * @property {boolean} [disableEveryone=this.client.options.disableEveryone] Whether or not @everyone and @here
+ * should be replaced with plain-text
+ * @property {FileOptions|string} [file] A file to send with the message
+ * @property {string|boolean} [code] Language for optional codeblock formatting to apply
+ * @property {boolean|SplitOptions} [split=false] Whether or not the message should be split into multiple messages if
+ * it exceeds the character limit. If an object is provided, these are the options for splitting the message.
+ */
+
+ /**
+ * Send a message with this webhook.
+ * @param {StringResolvable} content The content to send
+ * @param {WebhookMessageOptions} [options={}] The options to provide
+ * @returns {Promise}
+ * @example
+ * // Send a message
+ * webhook.send('hello!')
+ * .then(message => console.log(`Sent message: ${message.content}`))
+ * .catch(console.error);
+ */
+ send(content, options) {
+ if (!options && typeof content === 'object' && !(content instanceof Array)) {
+ options = content;
+ content = '';
+ } else if (!options) {
+ options = {};
+ }
+ if (options.file) {
+ if (typeof options.file === 'string') options.file = { attachment: options.file };
+ if (!options.file.name) {
+ if (typeof options.file.attachment === 'string') {
+ options.file.name = path.basename(options.file.attachment);
+ } else if (options.file.attachment && options.file.attachment.path) {
+ options.file.name = path.basename(options.file.attachment.path);
+ } else {
+ options.file.name = 'file.jpg';
+ }
+ }
+ return this.client.resolver.resolveBuffer(options.file.attachment).then(file =>
+ this.client.rest.methods.sendWebhookMessage(this, content, options, {
+ file,
+ name: options.file.name,
+ })
+ );
+ }
+ return this.client.rest.methods.sendWebhookMessage(this, content, options);
+ }
+
+ /**
+ * Send a message with this webhook
+ * @param {StringResolvable} content The content to send
+ * @param {WebhookMessageOptions} [options={}] The options to provide
+ * @returns {Promise}
+ * @example
+ * // Send a message
+ * webhook.sendMessage('hello!')
+ * .then(message => console.log(`Sent message: ${message.content}`))
+ * .catch(console.error);
+ */
+ sendMessage(content, options = {}) {
+ return this.send(content, options);
+ }
+
+ /**
+ * Send a file with this webhook.
+ * @param {BufferResolvable} attachment The file to send
+ * @param {string} [name='file.jpg'] The name and extension of the file
+ * @param {StringResolvable} [content] Text message to send with the attachment
+ * @param {WebhookMessageOptions} [options] The options to provide
+ * @returns {Promise}
+ */
+ sendFile(attachment, name, content, options = {}) {
+ return this.send(content, Object.assign(options, { file: { attachment, name } }));
+ }
+
+ /**
+ * Send a code block with this webhook.
+ * @param {string} lang Language for the code block
+ * @param {StringResolvable} content Content of the code block
+ * @param {WebhookMessageOptions} options The options to provide
+ * @returns {Promise}
+ */
+ sendCode(lang, content, options = {}) {
+ return this.send(content, Object.assign(options, { code: lang }));
+ }
+
+ /**
+ * Send a raw slack message with this webhook.
+ * @param {Object} body The raw body to send
+ * @returns {Promise}
+ * @example
+ * // Send a slack message
+ * webhook.sendSlackMessage({
+ * 'username': 'Wumpus',
+ * 'attachments': [{
+ * 'pretext': 'this looks pretty cool',
+ * 'color': '#F0F',
+ * 'footer_icon': 'http://snek.s3.amazonaws.com/topSnek.png',
+ * 'footer': 'Powered by sneks',
+ * 'ts': Date.now() / 1000
+ * }]
+ * }).catch(console.error);
+ */
+ sendSlackMessage(body) {
+ return this.client.rest.methods.sendSlackWebhookMessage(this, body);
+ }
+
+ /**
+ * Edit the webhook.
+ * @param {string} name The new name for the webhook
+ * @param {BufferResolvable} avatar The new avatar for the webhook
+ * @returns {Promise}
+ */
+ edit(name = this.name, avatar) {
+ if (avatar) {
+ return this.client.resolver.resolveBuffer(avatar).then(file => {
+ const dataURI = this.client.resolver.resolveBase64(file);
+ return this.client.rest.methods.editWebhook(this, name, dataURI);
+ });
+ }
+ return this.client.rest.methods.editWebhook(this, name).then(data => {
+ this.setup(data);
+ return this;
+ });
+ }
+
+ /**
+ * Delete the webhook.
+ * @returns {Promise}
+ */
+ delete() {
+ return this.client.rest.methods.deleteWebhook(this);
+ }
+}
+
+module.exports = Webhook;
+
+
+/***/ }),
+/* 33 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Collection = __webpack_require__(3);
+const EventEmitter = __webpack_require__(12).EventEmitter;
+
+/**
+ * Filter to be applied to the collector.
+ * @typedef {Function} CollectorFilter
+ * @param {...*} args Any arguments received by the listener
+ * @returns {boolean} To collect or not collect
+ */
+
+/**
+ * Options to be applied to the collector.
+ * @typedef {Object} CollectorOptions
+ * @property {number} [time] How long to run the collector for
+ */
+
+/**
+ * Abstract class for defining a new Collector.
+ * @abstract
+ */
+class Collector extends EventEmitter {
+ constructor(client, filter, options = {}) {
+ super();
+
+ /**
+ * The client
+ * @name Collector#client
+ * @type {Client}
+ * @readonly
+ */
+ Object.defineProperty(this, 'client', { value: client });
+
+ /**
+ * The filter applied to this collector
+ * @type {CollectorFilter}
+ */
+ this.filter = filter;
+
+ /**
+ * The options of this collector
+ * @type {CollectorOptions}
+ */
+ this.options = options;
+
+ /**
+ * The items collected by this collector
+ * @type {Collection}
+ */
+ this.collected = new Collection();
+
+ /**
+ * Whether this collector has finished collecting
+ * @type {boolean}
+ */
+ this.ended = false;
+
+ /**
+ * Timeout for cleanup
+ * @type {?Timeout}
+ * @private
+ */
+ this._timeout = null;
+
+ /**
+ * Call this to handle an event as a collectable element
+ * Accepts any event data as parameters
+ * @type {Function}
+ * @private
+ */
+ this.listener = this._handle.bind(this);
+ if (options.time) this._timeout = this.client.setTimeout(() => this.stop('time'), options.time);
+ }
+
+ /**
+ * @param {...*} args The arguments emitted by the listener
+ * @emits Collector#collect
+ * @private
+ */
+ _handle(...args) {
+ const collect = this.handle(...args);
+ if (!collect || !this.filter(...args)) return;
+
+ this.collected.set(collect.key, collect.value);
+
+ /**
+ * Emitted whenever an element is collected.
+ * @event Collector#collect
+ * @param {*} element The element that got collected
+ * @param {Collector} collector The collector
+ */
+ this.emit('collect', collect.value, this);
+
+ const post = this.postCheck(...args);
+ if (post) this.stop(post);
+ }
+
+ /**
+ * Return a promise that resolves with the next collected element;
+ * rejects with collected elements if the collector finishes without receving a next element
+ * @type {Promise}
+ * @readonly
+ */
+ get next() {
+ return new Promise((resolve, reject) => {
+ if (this.ended) {
+ reject(this.collected);
+ return;
+ }
+
+ const cleanup = () => {
+ this.removeListener('collect', onCollect);
+ this.removeListener('end', onEnd);
+ };
+
+ const onCollect = item => {
+ cleanup();
+ resolve(item);
+ };
+
+ const onEnd = () => {
+ cleanup();
+ reject(this.collected); // eslint-disable-line prefer-promise-reject-errors
+ };
+
+ this.on('collect', onCollect);
+ this.on('end', onEnd);
+ });
+ }
+
+ /**
+ * Stop this collector and emit the `end` event.
+ * @param {string} [reason='user'] The reason this collector is ending
+ * @emits Collector#end
+ */
+ stop(reason = 'user') {
+ if (this.ended) return;
+
+ if (this._timeout) this.client.clearTimeout(this._timeout);
+ this.ended = true;
+ this.cleanup();
+
+ /**
+ * Emitted when the collector is finished collecting.
+ * @event Collector#end
+ * @param {Collection} collected The elements collected by the collector
+ * @param {string} reason The reason the collector ended
+ */
+ this.emit('end', this.collected, reason);
+ }
+
+ /* eslint-disable no-empty-function, valid-jsdoc */
+ /**
+ * Handles incoming events from the `listener` function. Returns null if the event should not be collected,
+ * or returns an object describing the data that should be stored.
+ * @see Collector#listener
+ * @param {...*} args Any args the event listener emits
+ * @returns {?{key: string, value}} Data to insert into collection, if any
+ * @abstract
+ */
+ handle() {}
+
+ /**
+ * This method runs after collection to see if the collector should finish.
+ * @param {...*} args Any args the event listener emits
+ * @returns {?string} Reason to end the collector, if any
+ * @abstract
+ */
+ postCheck() {}
+
+ /**
+ * Called when the collector is ending.
+ * @abstract
+ */
+ cleanup() {}
+ /* eslint-enable no-empty-function, valid-jsdoc */
+}
+
+module.exports = Collector;
+
+
+/***/ }),
+/* 34 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(global) {
+
+var buffer = __webpack_require__(5);
+var Buffer = buffer.Buffer;
+var SlowBuffer = buffer.SlowBuffer;
+var MAX_LEN = buffer.kMaxLength || 2147483647;
+exports.alloc = function alloc(size, fill, encoding) {
+ if (typeof Buffer.alloc === 'function') {
+ return Buffer.alloc(size, fill, encoding);
+ }
+ if (typeof encoding === 'number') {
+ throw new TypeError('encoding must not be number');
+ }
+ if (typeof size !== 'number') {
+ throw new TypeError('size must be a number');
+ }
+ if (size > MAX_LEN) {
+ throw new RangeError('size is too large');
+ }
+ var enc = encoding;
+ var _fill = fill;
+ if (_fill === undefined) {
+ enc = undefined;
+ _fill = 0;
+ }
+ var buf = new Buffer(size);
+ if (typeof _fill === 'string') {
+ var fillBuf = new Buffer(_fill, enc);
+ var flen = fillBuf.length;
+ var i = -1;
+ while (++i < size) {
+ buf[i] = fillBuf[i % flen];
+ }
+ } else {
+ buf.fill(_fill);
+ }
+ return buf;
+}
+exports.allocUnsafe = function allocUnsafe(size) {
+ if (typeof Buffer.allocUnsafe === 'function') {
+ return Buffer.allocUnsafe(size);
+ }
+ if (typeof size !== 'number') {
+ throw new TypeError('size must be a number');
+ }
+ if (size > MAX_LEN) {
+ throw new RangeError('size is too large');
+ }
+ return new Buffer(size);
+}
+exports.from = function from(value, encodingOrOffset, length) {
+ if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) {
+ return Buffer.from(value, encodingOrOffset, length);
+ }
+ if (typeof value === 'number') {
+ throw new TypeError('"value" argument must not be a number');
+ }
+ if (typeof value === 'string') {
+ return new Buffer(value, encodingOrOffset);
+ }
+ if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
+ var offset = encodingOrOffset;
+ if (arguments.length === 1) {
+ return new Buffer(value);
+ }
+ if (typeof offset === 'undefined') {
+ offset = 0;
+ }
+ var len = length;
+ if (typeof len === 'undefined') {
+ len = value.byteLength - offset;
+ }
+ if (offset >= value.byteLength) {
+ throw new RangeError('\'offset\' is out of bounds');
+ }
+ if (len > value.byteLength - offset) {
+ throw new RangeError('\'length\' is out of bounds');
+ }
+ return new Buffer(value.slice(offset, offset + len));
+ }
+ if (Buffer.isBuffer(value)) {
+ var out = new Buffer(value.length);
+ value.copy(out, 0, 0, value.length);
+ return out;
+ }
+ if (value) {
+ if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) {
+ return new Buffer(value);
+ }
+ if (value.type === 'Buffer' && Array.isArray(value.data)) {
+ return new Buffer(value.data);
+ }
+ }
+
+ throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.');
+}
+exports.allocUnsafeSlow = function allocUnsafeSlow(size) {
+ if (typeof Buffer.allocUnsafeSlow === 'function') {
+ return Buffer.allocUnsafeSlow(size);
+ }
+ if (typeof size !== 'number') {
+ throw new TypeError('size must be a number');
+ }
+ if (size >= MAX_LEN) {
+ throw new RangeError('size is too large');
+ }
+ return new SlowBuffer(size);
+}
+
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8)))
+
+/***/ }),
+/* 35 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*
+ Copyright 2013 Daniel Wirtz
+ Copyright 2009 The Closure Library Authors. All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS-IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+/**
+ * @license long.js (c) 2013 Daniel Wirtz
+ * Released under the Apache License, Version 2.0
+ * see: https://github.com/dcodeIO/long.js for details
+ */
+(function(global, factory) {
+
+ /* AMD */ if (true)
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
+ __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
+ (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
+ __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+ /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"])
+ module["exports"] = factory();
+ /* Global */ else
+ (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = factory();
+
+})(this, function() {
+ "use strict";
+
+ /**
+ * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
+ * See the from* functions below for more convenient ways of constructing Longs.
+ * @exports Long
+ * @class A Long class for representing a 64 bit two's-complement integer value.
+ * @param {number} low The low (signed) 32 bits of the long
+ * @param {number} high The high (signed) 32 bits of the long
+ * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
+ * @constructor
+ */
+ function Long(low, high, unsigned) {
+
+ /**
+ * The low 32 bits as a signed value.
+ * @type {number}
+ */
+ this.low = low | 0;
+
+ /**
+ * The high 32 bits as a signed value.
+ * @type {number}
+ */
+ this.high = high | 0;
+
+ /**
+ * Whether unsigned or not.
+ * @type {boolean}
+ */
+ this.unsigned = !!unsigned;
+ }
+
+ // The internal representation of a long is the two given signed, 32-bit values.
+ // We use 32-bit pieces because these are the size of integers on which
+ // Javascript performs bit-operations. For operations like addition and
+ // multiplication, we split each number into 16 bit pieces, which can easily be
+ // multiplied within Javascript's floating-point representation without overflow
+ // or change in sign.
+ //
+ // In the algorithms below, we frequently reduce the negative case to the
+ // positive case by negating the input(s) and then post-processing the result.
+ // Note that we must ALWAYS check specially whether those values are MIN_VALUE
+ // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
+ // a positive number, it overflows back into a negative). Not handling this
+ // case would often result in infinite recursion.
+ //
+ // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
+ // methods on which they depend.
+
+ /**
+ * An indicator used to reliably determine if an object is a Long or not.
+ * @type {boolean}
+ * @const
+ * @private
+ */
+ Long.prototype.__isLong__;
+
+ Object.defineProperty(Long.prototype, "__isLong__", {
+ value: true,
+ enumerable: false,
+ configurable: false
+ });
+
+ /**
+ * @function
+ * @param {*} obj Object
+ * @returns {boolean}
+ * @inner
+ */
+ function isLong(obj) {
+ return (obj && obj["__isLong__"]) === true;
+ }
+
+ /**
+ * Tests if the specified object is a Long.
+ * @function
+ * @param {*} obj Object
+ * @returns {boolean}
+ */
+ Long.isLong = isLong;
+
+ /**
+ * A cache of the Long representations of small integer values.
+ * @type {!Object}
+ * @inner
+ */
+ var INT_CACHE = {};
+
+ /**
+ * A cache of the Long representations of small unsigned integer values.
+ * @type {!Object}
+ * @inner
+ */
+ var UINT_CACHE = {};
+
+ /**
+ * @param {number} value
+ * @param {boolean=} unsigned
+ * @returns {!Long}
+ * @inner
+ */
+ function fromInt(value, unsigned) {
+ var obj, cachedObj, cache;
+ if (unsigned) {
+ value >>>= 0;
+ if (cache = (0 <= value && value < 256)) {
+ cachedObj = UINT_CACHE[value];
+ if (cachedObj)
+ return cachedObj;
+ }
+ obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);
+ if (cache)
+ UINT_CACHE[value] = obj;
+ return obj;
+ } else {
+ value |= 0;
+ if (cache = (-128 <= value && value < 128)) {
+ cachedObj = INT_CACHE[value];
+ if (cachedObj)
+ return cachedObj;
+ }
+ obj = fromBits(value, value < 0 ? -1 : 0, false);
+ if (cache)
+ INT_CACHE[value] = obj;
+ return obj;
+ }
+ }
+
+ /**
+ * Returns a Long representing the given 32 bit integer value.
+ * @function
+ * @param {number} value The 32 bit integer in question
+ * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
+ * @returns {!Long} The corresponding Long value
+ */
+ Long.fromInt = fromInt;
+
+ /**
+ * @param {number} value
+ * @param {boolean=} unsigned
+ * @returns {!Long}
+ * @inner
+ */
+ function fromNumber(value, unsigned) {
+ if (isNaN(value) || !isFinite(value))
+ return unsigned ? UZERO : ZERO;
+ if (unsigned) {
+ if (value < 0)
+ return UZERO;
+ if (value >= TWO_PWR_64_DBL)
+ return MAX_UNSIGNED_VALUE;
+ } else {
+ if (value <= -TWO_PWR_63_DBL)
+ return MIN_VALUE;
+ if (value + 1 >= TWO_PWR_63_DBL)
+ return MAX_VALUE;
+ }
+ if (value < 0)
+ return fromNumber(-value, unsigned).neg();
+ return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
+ }
+
+ /**
+ * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
+ * @function
+ * @param {number} value The number in question
+ * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
+ * @returns {!Long} The corresponding Long value
+ */
+ Long.fromNumber = fromNumber;
+
+ /**
+ * @param {number} lowBits
+ * @param {number} highBits
+ * @param {boolean=} unsigned
+ * @returns {!Long}
+ * @inner
+ */
+ function fromBits(lowBits, highBits, unsigned) {
+ return new Long(lowBits, highBits, unsigned);
+ }
+
+ /**
+ * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
+ * assumed to use 32 bits.
+ * @function
+ * @param {number} lowBits The low 32 bits
+ * @param {number} highBits The high 32 bits
+ * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
+ * @returns {!Long} The corresponding Long value
+ */
+ Long.fromBits = fromBits;
+
+ /**
+ * @function
+ * @param {number} base
+ * @param {number} exponent
+ * @returns {number}
+ * @inner
+ */
+ var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)
+
+ /**
+ * @param {string} str
+ * @param {(boolean|number)=} unsigned
+ * @param {number=} radix
+ * @returns {!Long}
+ * @inner
+ */
+ function fromString(str, unsigned, radix) {
+ if (str.length === 0)
+ throw Error('empty string');
+ if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")
+ return ZERO;
+ if (typeof unsigned === 'number') {
+ // For goog.math.long compatibility
+ radix = unsigned,
+ unsigned = false;
+ } else {
+ unsigned = !! unsigned;
+ }
+ radix = radix || 10;
+ if (radix < 2 || 36 < radix)
+ throw RangeError('radix');
+
+ var p;
+ if ((p = str.indexOf('-')) > 0)
+ throw Error('interior hyphen');
+ else if (p === 0) {
+ return fromString(str.substring(1), unsigned, radix).neg();
+ }
+
+ // Do several (8) digits each time through the loop, so as to
+ // minimize the calls to the very expensive emulated div.
+ var radixToPower = fromNumber(pow_dbl(radix, 8));
+
+ var result = ZERO;
+ for (var i = 0; i < str.length; i += 8) {
+ var size = Math.min(8, str.length - i),
+ value = parseInt(str.substring(i, i + size), radix);
+ if (size < 8) {
+ var power = fromNumber(pow_dbl(radix, size));
+ result = result.mul(power).add(fromNumber(value));
+ } else {
+ result = result.mul(radixToPower);
+ result = result.add(fromNumber(value));
+ }
+ }
+ result.unsigned = unsigned;
+ return result;
+ }
+
+ /**
+ * Returns a Long representation of the given string, written using the specified radix.
+ * @function
+ * @param {string} str The textual representation of the Long
+ * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed
+ * @param {number=} radix The radix in which the text is written (2-36), defaults to 10
+ * @returns {!Long} The corresponding Long value
+ */
+ Long.fromString = fromString;
+
+ /**
+ * @function
+ * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val
+ * @returns {!Long}
+ * @inner
+ */
+ function fromValue(val) {
+ if (val /* is compatible */ instanceof Long)
+ return val;
+ if (typeof val === 'number')
+ return fromNumber(val);
+ if (typeof val === 'string')
+ return fromString(val);
+ // Throws for non-objects, converts non-instanceof Long:
+ return fromBits(val.low, val.high, val.unsigned);
+ }
+
+ /**
+ * Converts the specified value to a Long.
+ * @function
+ * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
+ * @returns {!Long}
+ */
+ Long.fromValue = fromValue;
+
+ // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
+ // no runtime penalty for these.
+
+ /**
+ * @type {number}
+ * @const
+ * @inner
+ */
+ var TWO_PWR_16_DBL = 1 << 16;
+
+ /**
+ * @type {number}
+ * @const
+ * @inner
+ */
+ var TWO_PWR_24_DBL = 1 << 24;
+
+ /**
+ * @type {number}
+ * @const
+ * @inner
+ */
+ var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
+
+ /**
+ * @type {number}
+ * @const
+ * @inner
+ */
+ var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
+
+ /**
+ * @type {number}
+ * @const
+ * @inner
+ */
+ var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
+
+ /**
+ * @type {!Long}
+ * @const
+ * @inner
+ */
+ var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);
+
+ /**
+ * @type {!Long}
+ * @inner
+ */
+ var ZERO = fromInt(0);
+
+ /**
+ * Signed zero.
+ * @type {!Long}
+ */
+ Long.ZERO = ZERO;
+
+ /**
+ * @type {!Long}
+ * @inner
+ */
+ var UZERO = fromInt(0, true);
+
+ /**
+ * Unsigned zero.
+ * @type {!Long}
+ */
+ Long.UZERO = UZERO;
+
+ /**
+ * @type {!Long}
+ * @inner
+ */
+ var ONE = fromInt(1);
+
+ /**
+ * Signed one.
+ * @type {!Long}
+ */
+ Long.ONE = ONE;
+
+ /**
+ * @type {!Long}
+ * @inner
+ */
+ var UONE = fromInt(1, true);
+
+ /**
+ * Unsigned one.
+ * @type {!Long}
+ */
+ Long.UONE = UONE;
+
+ /**
+ * @type {!Long}
+ * @inner
+ */
+ var NEG_ONE = fromInt(-1);
+
+ /**
+ * Signed negative one.
+ * @type {!Long}
+ */
+ Long.NEG_ONE = NEG_ONE;
+
+ /**
+ * @type {!Long}
+ * @inner
+ */
+ var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
+
+ /**
+ * Maximum signed value.
+ * @type {!Long}
+ */
+ Long.MAX_VALUE = MAX_VALUE;
+
+ /**
+ * @type {!Long}
+ * @inner
+ */
+ var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);
+
+ /**
+ * Maximum unsigned value.
+ * @type {!Long}
+ */
+ Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;
+
+ /**
+ * @type {!Long}
+ * @inner
+ */
+ var MIN_VALUE = fromBits(0, 0x80000000|0, false);
+
+ /**
+ * Minimum signed value.
+ * @type {!Long}
+ */
+ Long.MIN_VALUE = MIN_VALUE;
+
+ /**
+ * @alias Long.prototype
+ * @inner
+ */
+ var LongPrototype = Long.prototype;
+
+ /**
+ * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
+ * @returns {number}
+ */
+ LongPrototype.toInt = function toInt() {
+ return this.unsigned ? this.low >>> 0 : this.low;
+ };
+
+ /**
+ * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
+ * @returns {number}
+ */
+ LongPrototype.toNumber = function toNumber() {
+ if (this.unsigned)
+ return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);
+ return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
+ };
+
+ /**
+ * Converts the Long to a string written in the specified radix.
+ * @param {number=} radix Radix (2-36), defaults to 10
+ * @returns {string}
+ * @override
+ * @throws {RangeError} If `radix` is out of range
+ */
+ LongPrototype.toString = function toString(radix) {
+ radix = radix || 10;
+ if (radix < 2 || 36 < radix)
+ throw RangeError('radix');
+ if (this.isZero())
+ return '0';
+ if (this.isNegative()) { // Unsigned Longs are never negative
+ if (this.eq(MIN_VALUE)) {
+ // We need to change the Long value before it can be negated, so we remove
+ // the bottom-most digit in this base and then recurse to do the rest.
+ var radixLong = fromNumber(radix),
+ div = this.div(radixLong),
+ rem1 = div.mul(radixLong).sub(this);
+ return div.toString(radix) + rem1.toInt().toString(radix);
+ } else
+ return '-' + this.neg().toString(radix);
+ }
+
+ // Do several (6) digits each time through the loop, so as to
+ // minimize the calls to the very expensive emulated div.
+ var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),
+ rem = this;
+ var result = '';
+ while (true) {
+ var remDiv = rem.div(radixToPower),
+ intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,
+ digits = intval.toString(radix);
+ rem = remDiv;
+ if (rem.isZero())
+ return digits + result;
+ else {
+ while (digits.length < 6)
+ digits = '0' + digits;
+ result = '' + digits + result;
+ }
+ }
+ };
+
+ /**
+ * Gets the high 32 bits as a signed integer.
+ * @returns {number} Signed high bits
+ */
+ LongPrototype.getHighBits = function getHighBits() {
+ return this.high;
+ };
+
+ /**
+ * Gets the high 32 bits as an unsigned integer.
+ * @returns {number} Unsigned high bits
+ */
+ LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
+ return this.high >>> 0;
+ };
+
+ /**
+ * Gets the low 32 bits as a signed integer.
+ * @returns {number} Signed low bits
+ */
+ LongPrototype.getLowBits = function getLowBits() {
+ return this.low;
+ };
+
+ /**
+ * Gets the low 32 bits as an unsigned integer.
+ * @returns {number} Unsigned low bits
+ */
+ LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
+ return this.low >>> 0;
+ };
+
+ /**
+ * Gets the number of bits needed to represent the absolute value of this Long.
+ * @returns {number}
+ */
+ LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
+ if (this.isNegative()) // Unsigned Longs are never negative
+ return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
+ var val = this.high != 0 ? this.high : this.low;
+ for (var bit = 31; bit > 0; bit--)
+ if ((val & (1 << bit)) != 0)
+ break;
+ return this.high != 0 ? bit + 33 : bit + 1;
+ };
+
+ /**
+ * Tests if this Long's value equals zero.
+ * @returns {boolean}
+ */
+ LongPrototype.isZero = function isZero() {
+ return this.high === 0 && this.low === 0;
+ };
+
+ /**
+ * Tests if this Long's value is negative.
+ * @returns {boolean}
+ */
+ LongPrototype.isNegative = function isNegative() {
+ return !this.unsigned && this.high < 0;
+ };
+
+ /**
+ * Tests if this Long's value is positive.
+ * @returns {boolean}
+ */
+ LongPrototype.isPositive = function isPositive() {
+ return this.unsigned || this.high >= 0;
+ };
+
+ /**
+ * Tests if this Long's value is odd.
+ * @returns {boolean}
+ */
+ LongPrototype.isOdd = function isOdd() {
+ return (this.low & 1) === 1;
+ };
+
+ /**
+ * Tests if this Long's value is even.
+ * @returns {boolean}
+ */
+ LongPrototype.isEven = function isEven() {
+ return (this.low & 1) === 0;
+ };
+
+ /**
+ * Tests if this Long's value equals the specified's.
+ * @param {!Long|number|string} other Other value
+ * @returns {boolean}
+ */
+ LongPrototype.equals = function equals(other) {
+ if (!isLong(other))
+ other = fromValue(other);
+ if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)
+ return false;
+ return this.high === other.high && this.low === other.low;
+ };
+
+ /**
+ * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.
+ * @function
+ * @param {!Long|number|string} other Other value
+ * @returns {boolean}
+ */
+ LongPrototype.eq = LongPrototype.equals;
+
+ /**
+ * Tests if this Long's value differs from the specified's.
+ * @param {!Long|number|string} other Other value
+ * @returns {boolean}
+ */
+ LongPrototype.notEquals = function notEquals(other) {
+ return !this.eq(/* validates */ other);
+ };
+
+ /**
+ * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
+ * @function
+ * @param {!Long|number|string} other Other value
+ * @returns {boolean}
+ */
+ LongPrototype.neq = LongPrototype.notEquals;
+
+ /**
+ * Tests if this Long's value is less than the specified's.
+ * @param {!Long|number|string} other Other value
+ * @returns {boolean}
+ */
+ LongPrototype.lessThan = function lessThan(other) {
+ return this.comp(/* validates */ other) < 0;
+ };
+
+ /**
+ * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
+ * @function
+ * @param {!Long|number|string} other Other value
+ * @returns {boolean}
+ */
+ LongPrototype.lt = LongPrototype.lessThan;
+
+ /**
+ * Tests if this Long's value is less than or equal the specified's.
+ * @param {!Long|number|string} other Other value
+ * @returns {boolean}
+ */
+ LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
+ return this.comp(/* validates */ other) <= 0;
+ };
+
+ /**
+ * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
+ * @function
+ * @param {!Long|number|string} other Other value
+ * @returns {boolean}
+ */
+ LongPrototype.lte = LongPrototype.lessThanOrEqual;
+
+ /**
+ * Tests if this Long's value is greater than the specified's.
+ * @param {!Long|number|string} other Other value
+ * @returns {boolean}
+ */
+ LongPrototype.greaterThan = function greaterThan(other) {
+ return this.comp(/* validates */ other) > 0;
+ };
+
+ /**
+ * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
+ * @function
+ * @param {!Long|number|string} other Other value
+ * @returns {boolean}
+ */
+ LongPrototype.gt = LongPrototype.greaterThan;
+
+ /**
+ * Tests if this Long's value is greater than or equal the specified's.
+ * @param {!Long|number|string} other Other value
+ * @returns {boolean}
+ */
+ LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
+ return this.comp(/* validates */ other) >= 0;
+ };
+
+ /**
+ * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
+ * @function
+ * @param {!Long|number|string} other Other value
+ * @returns {boolean}
+ */
+ LongPrototype.gte = LongPrototype.greaterThanOrEqual;
+
+ /**
+ * Compares this Long's value with the specified's.
+ * @param {!Long|number|string} other Other value
+ * @returns {number} 0 if they are the same, 1 if the this is greater and -1
+ * if the given one is greater
+ */
+ LongPrototype.compare = function compare(other) {
+ if (!isLong(other))
+ other = fromValue(other);
+ if (this.eq(other))
+ return 0;
+ var thisNeg = this.isNegative(),
+ otherNeg = other.isNegative();
+ if (thisNeg && !otherNeg)
+ return -1;
+ if (!thisNeg && otherNeg)
+ return 1;
+ // At this point the sign bits are the same
+ if (!this.unsigned)
+ return this.sub(other).isNegative() ? -1 : 1;
+ // Both are positive if at least one is unsigned
+ return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
+ };
+
+ /**
+ * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
+ * @function
+ * @param {!Long|number|string} other Other value
+ * @returns {number} 0 if they are the same, 1 if the this is greater and -1
+ * if the given one is greater
+ */
+ LongPrototype.comp = LongPrototype.compare;
+
+ /**
+ * Negates this Long's value.
+ * @returns {!Long} Negated Long
+ */
+ LongPrototype.negate = function negate() {
+ if (!this.unsigned && this.eq(MIN_VALUE))
+ return MIN_VALUE;
+ return this.not().add(ONE);
+ };
+
+ /**
+ * Negates this Long's value. This is an alias of {@link Long#negate}.
+ * @function
+ * @returns {!Long} Negated Long
+ */
+ LongPrototype.neg = LongPrototype.negate;
+
+ /**
+ * Returns the sum of this and the specified Long.
+ * @param {!Long|number|string} addend Addend
+ * @returns {!Long} Sum
+ */
+ LongPrototype.add = function add(addend) {
+ if (!isLong(addend))
+ addend = fromValue(addend);
+
+ // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
+
+ var a48 = this.high >>> 16;
+ var a32 = this.high & 0xFFFF;
+ var a16 = this.low >>> 16;
+ var a00 = this.low & 0xFFFF;
+
+ var b48 = addend.high >>> 16;
+ var b32 = addend.high & 0xFFFF;
+ var b16 = addend.low >>> 16;
+ var b00 = addend.low & 0xFFFF;
+
+ var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
+ c00 += a00 + b00;
+ c16 += c00 >>> 16;
+ c00 &= 0xFFFF;
+ c16 += a16 + b16;
+ c32 += c16 >>> 16;
+ c16 &= 0xFFFF;
+ c32 += a32 + b32;
+ c48 += c32 >>> 16;
+ c32 &= 0xFFFF;
+ c48 += a48 + b48;
+ c48 &= 0xFFFF;
+ return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
+ };
+
+ /**
+ * Returns the difference of this and the specified Long.
+ * @param {!Long|number|string} subtrahend Subtrahend
+ * @returns {!Long} Difference
+ */
+ LongPrototype.subtract = function subtract(subtrahend) {
+ if (!isLong(subtrahend))
+ subtrahend = fromValue(subtrahend);
+ return this.add(subtrahend.neg());
+ };
+
+ /**
+ * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
+ * @function
+ * @param {!Long|number|string} subtrahend Subtrahend
+ * @returns {!Long} Difference
+ */
+ LongPrototype.sub = LongPrototype.subtract;
+
+ /**
+ * Returns the product of this and the specified Long.
+ * @param {!Long|number|string} multiplier Multiplier
+ * @returns {!Long} Product
+ */
+ LongPrototype.multiply = function multiply(multiplier) {
+ if (this.isZero())
+ return ZERO;
+ if (!isLong(multiplier))
+ multiplier = fromValue(multiplier);
+ if (multiplier.isZero())
+ return ZERO;
+ if (this.eq(MIN_VALUE))
+ return multiplier.isOdd() ? MIN_VALUE : ZERO;
+ if (multiplier.eq(MIN_VALUE))
+ return this.isOdd() ? MIN_VALUE : ZERO;
+
+ if (this.isNegative()) {
+ if (multiplier.isNegative())
+ return this.neg().mul(multiplier.neg());
+ else
+ return this.neg().mul(multiplier).neg();
+ } else if (multiplier.isNegative())
+ return this.mul(multiplier.neg()).neg();
+
+ // If both longs are small, use float multiplication
+ if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24))
+ return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
+
+ // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
+ // We can skip products that would overflow.
+
+ var a48 = this.high >>> 16;
+ var a32 = this.high & 0xFFFF;
+ var a16 = this.low >>> 16;
+ var a00 = this.low & 0xFFFF;
+
+ var b48 = multiplier.high >>> 16;
+ var b32 = multiplier.high & 0xFFFF;
+ var b16 = multiplier.low >>> 16;
+ var b00 = multiplier.low & 0xFFFF;
+
+ var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
+ c00 += a00 * b00;
+ c16 += c00 >>> 16;
+ c00 &= 0xFFFF;
+ c16 += a16 * b00;
+ c32 += c16 >>> 16;
+ c16 &= 0xFFFF;
+ c16 += a00 * b16;
+ c32 += c16 >>> 16;
+ c16 &= 0xFFFF;
+ c32 += a32 * b00;
+ c48 += c32 >>> 16;
+ c32 &= 0xFFFF;
+ c32 += a16 * b16;
+ c48 += c32 >>> 16;
+ c32 &= 0xFFFF;
+ c32 += a00 * b32;
+ c48 += c32 >>> 16;
+ c32 &= 0xFFFF;
+ c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
+ c48 &= 0xFFFF;
+ return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
+ };
+
+ /**
+ * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
+ * @function
+ * @param {!Long|number|string} multiplier Multiplier
+ * @returns {!Long} Product
+ */
+ LongPrototype.mul = LongPrototype.multiply;
+
+ /**
+ * Returns this Long divided by the specified. The result is signed if this Long is signed or
+ * unsigned if this Long is unsigned.
+ * @param {!Long|number|string} divisor Divisor
+ * @returns {!Long} Quotient
+ */
+ LongPrototype.divide = function divide(divisor) {
+ if (!isLong(divisor))
+ divisor = fromValue(divisor);
+ if (divisor.isZero())
+ throw Error('division by zero');
+ if (this.isZero())
+ return this.unsigned ? UZERO : ZERO;
+ var approx, rem, res;
+ if (!this.unsigned) {
+ // This section is only relevant for signed longs and is derived from the
+ // closure library as a whole.
+ if (this.eq(MIN_VALUE)) {
+ if (divisor.eq(ONE) || divisor.eq(NEG_ONE))
+ return MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE
+ else if (divisor.eq(MIN_VALUE))
+ return ONE;
+ else {
+ // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
+ var halfThis = this.shr(1);
+ approx = halfThis.div(divisor).shl(1);
+ if (approx.eq(ZERO)) {
+ return divisor.isNegative() ? ONE : NEG_ONE;
+ } else {
+ rem = this.sub(divisor.mul(approx));
+ res = approx.add(rem.div(divisor));
+ return res;
+ }
+ }
+ } else if (divisor.eq(MIN_VALUE))
+ return this.unsigned ? UZERO : ZERO;
+ if (this.isNegative()) {
+ if (divisor.isNegative())
+ return this.neg().div(divisor.neg());
+ return this.neg().div(divisor).neg();
+ } else if (divisor.isNegative())
+ return this.div(divisor.neg()).neg();
+ res = ZERO;
+ } else {
+ // The algorithm below has not been made for unsigned longs. It's therefore
+ // required to take special care of the MSB prior to running it.
+ if (!divisor.unsigned)
+ divisor = divisor.toUnsigned();
+ if (divisor.gt(this))
+ return UZERO;
+ if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true
+ return UONE;
+ res = UZERO;
+ }
+
+ // Repeat the following until the remainder is less than other: find a
+ // floating-point that approximates remainder / other *from below*, add this
+ // into the result, and subtract it from the remainder. It is critical that
+ // the approximate value is less than or equal to the real value so that the
+ // remainder never becomes negative.
+ rem = this;
+ while (rem.gte(divisor)) {
+ // Approximate the result of division. This may be a little greater or
+ // smaller than the actual value.
+ approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
+
+ // We will tweak the approximate result by changing it in the 48-th digit or
+ // the smallest non-fractional digit, whichever is larger.
+ var log2 = Math.ceil(Math.log(approx) / Math.LN2),
+ delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48),
+
+ // Decrease the approximation until it is smaller than the remainder. Note
+ // that if it is too large, the product overflows and is negative.
+ approxRes = fromNumber(approx),
+ approxRem = approxRes.mul(divisor);
+ while (approxRem.isNegative() || approxRem.gt(rem)) {
+ approx -= delta;
+ approxRes = fromNumber(approx, this.unsigned);
+ approxRem = approxRes.mul(divisor);
+ }
+
+ // We know the answer can't be zero... and actually, zero would cause
+ // infinite recursion since we would make no progress.
+ if (approxRes.isZero())
+ approxRes = ONE;
+
+ res = res.add(approxRes);
+ rem = rem.sub(approxRem);
+ }
+ return res;
+ };
+
+ /**
+ * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
+ * @function
+ * @param {!Long|number|string} divisor Divisor
+ * @returns {!Long} Quotient
+ */
+ LongPrototype.div = LongPrototype.divide;
+
+ /**
+ * Returns this Long modulo the specified.
+ * @param {!Long|number|string} divisor Divisor
+ * @returns {!Long} Remainder
+ */
+ LongPrototype.modulo = function modulo(divisor) {
+ if (!isLong(divisor))
+ divisor = fromValue(divisor);
+ return this.sub(this.div(divisor).mul(divisor));
+ };
+
+ /**
+ * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
+ * @function
+ * @param {!Long|number|string} divisor Divisor
+ * @returns {!Long} Remainder
+ */
+ LongPrototype.mod = LongPrototype.modulo;
+
+ /**
+ * Returns the bitwise NOT of this Long.
+ * @returns {!Long}
+ */
+ LongPrototype.not = function not() {
+ return fromBits(~this.low, ~this.high, this.unsigned);
+ };
+
+ /**
+ * Returns the bitwise AND of this Long and the specified.
+ * @param {!Long|number|string} other Other Long
+ * @returns {!Long}
+ */
+ LongPrototype.and = function and(other) {
+ if (!isLong(other))
+ other = fromValue(other);
+ return fromBits(this.low & other.low, this.high & other.high, this.unsigned);
+ };
+
+ /**
+ * Returns the bitwise OR of this Long and the specified.
+ * @param {!Long|number|string} other Other Long
+ * @returns {!Long}
+ */
+ LongPrototype.or = function or(other) {
+ if (!isLong(other))
+ other = fromValue(other);
+ return fromBits(this.low | other.low, this.high | other.high, this.unsigned);
+ };
+
+ /**
+ * Returns the bitwise XOR of this Long and the given one.
+ * @param {!Long|number|string} other Other Long
+ * @returns {!Long}
+ */
+ LongPrototype.xor = function xor(other) {
+ if (!isLong(other))
+ other = fromValue(other);
+ return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
+ };
+
+ /**
+ * Returns this Long with bits shifted to the left by the given amount.
+ * @param {number|!Long} numBits Number of bits
+ * @returns {!Long} Shifted Long
+ */
+ LongPrototype.shiftLeft = function shiftLeft(numBits) {
+ if (isLong(numBits))
+ numBits = numBits.toInt();
+ if ((numBits &= 63) === 0)
+ return this;
+ else if (numBits < 32)
+ return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
+ else
+ return fromBits(0, this.low << (numBits - 32), this.unsigned);
+ };
+
+ /**
+ * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
+ * @function
+ * @param {number|!Long} numBits Number of bits
+ * @returns {!Long} Shifted Long
+ */
+ LongPrototype.shl = LongPrototype.shiftLeft;
+
+ /**
+ * Returns this Long with bits arithmetically shifted to the right by the given amount.
+ * @param {number|!Long} numBits Number of bits
+ * @returns {!Long} Shifted Long
+ */
+ LongPrototype.shiftRight = function shiftRight(numBits) {
+ if (isLong(numBits))
+ numBits = numBits.toInt();
+ if ((numBits &= 63) === 0)
+ return this;
+ else if (numBits < 32)
+ return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
+ else
+ return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
+ };
+
+ /**
+ * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
+ * @function
+ * @param {number|!Long} numBits Number of bits
+ * @returns {!Long} Shifted Long
+ */
+ LongPrototype.shr = LongPrototype.shiftRight;
+
+ /**
+ * Returns this Long with bits logically shifted to the right by the given amount.
+ * @param {number|!Long} numBits Number of bits
+ * @returns {!Long} Shifted Long
+ */
+ LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
+ if (isLong(numBits))
+ numBits = numBits.toInt();
+ numBits &= 63;
+ if (numBits === 0)
+ return this;
+ else {
+ var high = this.high;
+ if (numBits < 32) {
+ var low = this.low;
+ return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
+ } else if (numBits === 32)
+ return fromBits(high, 0, this.unsigned);
+ else
+ return fromBits(high >>> (numBits - 32), 0, this.unsigned);
+ }
+ };
+
+ /**
+ * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
+ * @function
+ * @param {number|!Long} numBits Number of bits
+ * @returns {!Long} Shifted Long
+ */
+ LongPrototype.shru = LongPrototype.shiftRightUnsigned;
+
+ /**
+ * Converts this Long to signed.
+ * @returns {!Long} Signed long
+ */
+ LongPrototype.toSigned = function toSigned() {
+ if (!this.unsigned)
+ return this;
+ return fromBits(this.low, this.high, false);
+ };
+
+ /**
+ * Converts this Long to unsigned.
+ * @returns {!Long} Unsigned long
+ */
+ LongPrototype.toUnsigned = function toUnsigned() {
+ if (this.unsigned)
+ return this;
+ return fromBits(this.low, this.high, true);
+ };
+
+ /**
+ * Converts this Long to its byte representation.
+ * @param {boolean=} le Whether little or big endian, defaults to big endian
+ * @returns {!Array.} Byte representation
+ */
+ LongPrototype.toBytes = function(le) {
+ return le ? this.toBytesLE() : this.toBytesBE();
+ }
+
+ /**
+ * Converts this Long to its little endian byte representation.
+ * @returns {!Array.} Little endian byte representation
+ */
+ LongPrototype.toBytesLE = function() {
+ var hi = this.high,
+ lo = this.low;
+ return [
+ lo & 0xff,
+ (lo >>> 8) & 0xff,
+ (lo >>> 16) & 0xff,
+ (lo >>> 24) & 0xff,
+ hi & 0xff,
+ (hi >>> 8) & 0xff,
+ (hi >>> 16) & 0xff,
+ (hi >>> 24) & 0xff
+ ];
+ }
+
+ /**
+ * Converts this Long to its big endian byte representation.
+ * @returns {!Array.} Big endian byte representation
+ */
+ LongPrototype.toBytesBE = function() {
+ var hi = this.high,
+ lo = this.low;
+ return [
+ (hi >>> 24) & 0xff,
+ (hi >>> 16) & 0xff,
+ (hi >>> 8) & 0xff,
+ hi & 0xff,
+ (lo >>> 24) & 0xff,
+ (lo >>> 16) & 0xff,
+ (lo >>> 8) & 0xff,
+ lo & 0xff
+ ];
+ }
+
+ return Long;
+});
+
+
+/***/ }),
+/* 36 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(process) {
+
+if (!process.version ||
+ process.version.indexOf('v0.') === 0 ||
+ process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
+ module.exports = nextTick;
+} else {
+ module.exports = process.nextTick;
+}
+
+function nextTick(fn, arg1, arg2, arg3) {
+ if (typeof fn !== 'function') {
+ throw new TypeError('"callback" argument must be a function');
+ }
+ var len = arguments.length;
+ var args, i;
+ switch (len) {
+ case 0:
+ case 1:
+ return process.nextTick(fn);
+ case 2:
+ return process.nextTick(function afterTickOne() {
+ fn.call(null, arg1);
+ });
+ case 3:
+ return process.nextTick(function afterTickTwo() {
+ fn.call(null, arg1, arg2);
+ });
+ case 4:
+ return process.nextTick(function afterTickThree() {
+ fn.call(null, arg1, arg2, arg3);
+ });
+ default:
+ args = new Array(len - 1);
+ i = 0;
+ while (i < args.length) {
+ args[i++] = arguments[i];
+ }
+ return process.nextTick(function afterTick() {
+ fn.apply(null, args);
+ });
+ }
+}
+
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6)))
+
+/***/ }),
+/* 37 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+exports.decode = exports.parse = __webpack_require__(82);
+exports.encode = exports.stringify = __webpack_require__(83);
+
+
+/***/ }),
+/* 38 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(process, setImmediate) {// A bit simpler than readable streams.
+// Implement an async ._write(chunk, encoding, cb), and it'll handle all
+// the drain event emission and buffering.
+
+
+
+module.exports = Writable;
+
+/**/
+var processNextTick = __webpack_require__(36);
+/**/
+
+/**/
+var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;
+/**/
+
+/**/
+var Duplex;
+/**/
+
+Writable.WritableState = WritableState;
+
+/**/
+var util = __webpack_require__(20);
+util.inherits = __webpack_require__(10);
+/**/
+
+/**/
+var internalUtil = {
+ deprecate: __webpack_require__(102)
+};
+/**/
+
+/**/
+var Stream = __webpack_require__(61);
+/**/
+
+var Buffer = __webpack_require__(5).Buffer;
+/**/
+var bufferShim = __webpack_require__(34);
+/**/
+
+util.inherits(Writable, Stream);
+
+function nop() {}
+
+function WriteReq(chunk, encoding, cb) {
+ this.chunk = chunk;
+ this.encoding = encoding;
+ this.callback = cb;
+ this.next = null;
+}
+
+function WritableState(options, stream) {
+ Duplex = Duplex || __webpack_require__(13);
+
+ options = options || {};
+
+ // object stream flag to indicate whether or not this stream
+ // contains buffers or objects.
+ this.objectMode = !!options.objectMode;
+
+ if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
+
+ // the point at which write() starts returning false
+ // Note: 0 is a valid value, means that we always return false if
+ // the entire buffer is not flushed immediately on write()
+ var hwm = options.highWaterMark;
+ var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+ this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+ // cast to ints.
+ this.highWaterMark = ~~this.highWaterMark;
+
+ // drain event flag.
+ this.needDrain = false;
+ // at the start of calling end()
+ this.ending = false;
+ // when end() has been called, and returned
+ this.ended = false;
+ // when 'finish' is emitted
+ this.finished = false;
+
+ // should we decode strings into buffers before passing to _write?
+ // this is here so that some node-core streams can optimize string
+ // handling at a lower level.
+ var noDecode = options.decodeStrings === false;
+ this.decodeStrings = !noDecode;
+
+ // Crypto is kind of old and crusty. Historically, its default string
+ // encoding is 'binary' so we have to make this configurable.
+ // Everything else in the universe uses 'utf8', though.
+ this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+ // not an actual buffer we keep track of, but a measurement
+ // of how much we're waiting to get pushed to some underlying
+ // socket or file.
+ this.length = 0;
+
+ // a flag to see when we're in the middle of a write.
+ this.writing = false;
+
+ // when true all writes will be buffered until .uncork() call
+ this.corked = 0;
+
+ // a flag to be able to tell if the onwrite cb is called immediately,
+ // or on a later tick. We set this to true at first, because any
+ // actions that shouldn't happen until "later" should generally also
+ // not happen before the first write call.
+ this.sync = true;
+
+ // a flag to know if we're processing previously buffered items, which
+ // may call the _write() callback in the same tick, so that we don't
+ // end up in an overlapped onwrite situation.
+ this.bufferProcessing = false;
+
+ // the callback that's passed to _write(chunk,cb)
+ this.onwrite = function (er) {
+ onwrite(stream, er);
+ };
+
+ // the callback that the user supplies to write(chunk,encoding,cb)
+ this.writecb = null;
+
+ // the amount that is being written when _write is called.
+ this.writelen = 0;
+
+ this.bufferedRequest = null;
+ this.lastBufferedRequest = null;
+
+ // number of pending user-supplied write callbacks
+ // this must be 0 before 'finish' can be emitted
+ this.pendingcb = 0;
+
+ // emit prefinish if the only thing we're waiting for is _write cbs
+ // This is relevant for synchronous Transform streams
+ this.prefinished = false;
+
+ // True if the error was already emitted and should not be thrown again
+ this.errorEmitted = false;
+
+ // count buffered requests
+ this.bufferedRequestCount = 0;
+
+ // allocate the first CorkedRequest, there is always
+ // one allocated and free to use, and we maintain at most two
+ this.corkedRequestsFree = new CorkedRequest(this);
+}
+
+WritableState.prototype.getBuffer = function getBuffer() {
+ var current = this.bufferedRequest;
+ var out = [];
+ while (current) {
+ out.push(current);
+ current = current.next;
+ }
+ return out;
+};
+
+(function () {
+ try {
+ Object.defineProperty(WritableState.prototype, 'buffer', {
+ get: internalUtil.deprecate(function () {
+ return this.getBuffer();
+ }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')
+ });
+ } catch (_) {}
+})();
+
+// Test _writableState for inheritance to account for Duplex streams,
+// whose prototype chain only points to Readable.
+var realHasInstance;
+if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
+ realHasInstance = Function.prototype[Symbol.hasInstance];
+ Object.defineProperty(Writable, Symbol.hasInstance, {
+ value: function (object) {
+ if (realHasInstance.call(this, object)) return true;
+
+ return object && object._writableState instanceof WritableState;
+ }
+ });
+} else {
+ realHasInstance = function (object) {
+ return object instanceof this;
+ };
+}
+
+function Writable(options) {
+ Duplex = Duplex || __webpack_require__(13);
+
+ // Writable ctor is applied to Duplexes, too.
+ // `realHasInstance` is necessary because using plain `instanceof`
+ // would return false, as no `_writableState` property is attached.
+
+ // Trying to use the custom `instanceof` for Writable here will also break the
+ // Node.js LazyTransform implementation, which has a non-trivial getter for
+ // `_writableState` that would lead to infinite recursion.
+ if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) {
+ return new Writable(options);
+ }
+
+ this._writableState = new WritableState(options, this);
+
+ // legacy.
+ this.writable = true;
+
+ if (options) {
+ if (typeof options.write === 'function') this._write = options.write;
+
+ if (typeof options.writev === 'function') this._writev = options.writev;
+ }
+
+ Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function () {
+ this.emit('error', new Error('Cannot pipe, not readable'));
+};
+
+function writeAfterEnd(stream, cb) {
+ var er = new Error('write after end');
+ // TODO: defer error events consistently everywhere, not just the cb
+ stream.emit('error', er);
+ processNextTick(cb, er);
+}
+
+// Checks that a user-supplied chunk is valid, especially for the particular
+// mode the stream is in. Currently this means that `null` is never accepted
+// and undefined/non-string values are only allowed in object mode.
+function validChunk(stream, state, chunk, cb) {
+ var valid = true;
+ var er = false;
+
+ if (chunk === null) {
+ er = new TypeError('May not write null values to stream');
+ } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
+ er = new TypeError('Invalid non-string/buffer chunk');
+ }
+ if (er) {
+ stream.emit('error', er);
+ processNextTick(cb, er);
+ valid = false;
+ }
+ return valid;
+}
+
+Writable.prototype.write = function (chunk, encoding, cb) {
+ var state = this._writableState;
+ var ret = false;
+ var isBuf = Buffer.isBuffer(chunk);
+
+ if (typeof encoding === 'function') {
+ cb = encoding;
+ encoding = null;
+ }
+
+ if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
+
+ if (typeof cb !== 'function') cb = nop;
+
+ if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
+ state.pendingcb++;
+ ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
+ }
+
+ return ret;
+};
+
+Writable.prototype.cork = function () {
+ var state = this._writableState;
+
+ state.corked++;
+};
+
+Writable.prototype.uncork = function () {
+ var state = this._writableState;
+
+ if (state.corked) {
+ state.corked--;
+
+ if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
+ }
+};
+
+Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
+ // node::ParseEncoding() requires lower case.
+ if (typeof encoding === 'string') encoding = encoding.toLowerCase();
+ if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
+ this._writableState.defaultEncoding = encoding;
+ return this;
+};
+
+function decodeChunk(state, chunk, encoding) {
+ if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
+ chunk = bufferShim.from(chunk, encoding);
+ }
+ return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn. Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
+ if (!isBuf) {
+ chunk = decodeChunk(state, chunk, encoding);
+ if (Buffer.isBuffer(chunk)) encoding = 'buffer';
+ }
+ var len = state.objectMode ? 1 : chunk.length;
+
+ state.length += len;
+
+ var ret = state.length < state.highWaterMark;
+ // we must ensure that previous needDrain will not be reset to false.
+ if (!ret) state.needDrain = true;
+
+ if (state.writing || state.corked) {
+ var last = state.lastBufferedRequest;
+ state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
+ if (last) {
+ last.next = state.lastBufferedRequest;
+ } else {
+ state.bufferedRequest = state.lastBufferedRequest;
+ }
+ state.bufferedRequestCount += 1;
+ } else {
+ doWrite(stream, state, false, len, chunk, encoding, cb);
+ }
+
+ return ret;
+}
+
+function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+ state.writelen = len;
+ state.writecb = cb;
+ state.writing = true;
+ state.sync = true;
+ if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
+ state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+ --state.pendingcb;
+ if (sync) processNextTick(cb, er);else cb(er);
+
+ stream._writableState.errorEmitted = true;
+ stream.emit('error', er);
+}
+
+function onwriteStateUpdate(state) {
+ state.writing = false;
+ state.writecb = null;
+ state.length -= state.writelen;
+ state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+ var state = stream._writableState;
+ var sync = state.sync;
+ var cb = state.writecb;
+
+ onwriteStateUpdate(state);
+
+ if (er) onwriteError(stream, state, sync, er, cb);else {
+ // Check if we're actually ready to finish, but don't emit yet
+ var finished = needFinish(state);
+
+ if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
+ clearBuffer(stream, state);
+ }
+
+ if (sync) {
+ /**/
+ asyncWrite(afterWrite, stream, state, finished, cb);
+ /**/
+ } else {
+ afterWrite(stream, state, finished, cb);
+ }
+ }
+}
+
+function afterWrite(stream, state, finished, cb) {
+ if (!finished) onwriteDrain(stream, state);
+ state.pendingcb--;
+ cb();
+ finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+ if (state.length === 0 && state.needDrain) {
+ state.needDrain = false;
+ stream.emit('drain');
+ }
+}
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+ state.bufferProcessing = true;
+ var entry = state.bufferedRequest;
+
+ if (stream._writev && entry && entry.next) {
+ // Fast case, write everything using _writev()
+ var l = state.bufferedRequestCount;
+ var buffer = new Array(l);
+ var holder = state.corkedRequestsFree;
+ holder.entry = entry;
+
+ var count = 0;
+ while (entry) {
+ buffer[count] = entry;
+ entry = entry.next;
+ count += 1;
+ }
+
+ doWrite(stream, state, true, state.length, buffer, '', holder.finish);
+
+ // doWrite is almost always async, defer these to save a bit of time
+ // as the hot path ends with doWrite
+ state.pendingcb++;
+ state.lastBufferedRequest = null;
+ if (holder.next) {
+ state.corkedRequestsFree = holder.next;
+ holder.next = null;
+ } else {
+ state.corkedRequestsFree = new CorkedRequest(state);
+ }
+ } else {
+ // Slow case, write chunks one-by-one
+ while (entry) {
+ var chunk = entry.chunk;
+ var encoding = entry.encoding;
+ var cb = entry.callback;
+ var len = state.objectMode ? 1 : chunk.length;
+
+ doWrite(stream, state, false, len, chunk, encoding, cb);
+ entry = entry.next;
+ // if we didn't call the onwrite immediately, then
+ // it means that we need to wait until it does.
+ // also, that means that the chunk and cb are currently
+ // being processed, so move the buffer counter past them.
+ if (state.writing) {
+ break;
+ }
+ }
+
+ if (entry === null) state.lastBufferedRequest = null;
+ }
+
+ state.bufferedRequestCount = 0;
+ state.bufferedRequest = entry;
+ state.bufferProcessing = false;
+}
+
+Writable.prototype._write = function (chunk, encoding, cb) {
+ cb(new Error('_write() is not implemented'));
+};
+
+Writable.prototype._writev = null;
+
+Writable.prototype.end = function (chunk, encoding, cb) {
+ var state = this._writableState;
+
+ if (typeof chunk === 'function') {
+ cb = chunk;
+ chunk = null;
+ encoding = null;
+ } else if (typeof encoding === 'function') {
+ cb = encoding;
+ encoding = null;
+ }
+
+ if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
+
+ // .end() fully uncorks
+ if (state.corked) {
+ state.corked = 1;
+ this.uncork();
+ }
+
+ // ignore unnecessary end() calls.
+ if (!state.ending && !state.finished) endWritable(this, state, cb);
+};
+
+function needFinish(state) {
+ return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
+}
+
+function prefinish(stream, state) {
+ if (!state.prefinished) {
+ state.prefinished = true;
+ stream.emit('prefinish');
+ }
+}
+
+function finishMaybe(stream, state) {
+ var need = needFinish(state);
+ if (need) {
+ if (state.pendingcb === 0) {
+ prefinish(stream, state);
+ state.finished = true;
+ stream.emit('finish');
+ } else {
+ prefinish(stream, state);
+ }
+ }
+ return need;
+}
+
+function endWritable(stream, state, cb) {
+ state.ending = true;
+ finishMaybe(stream, state);
+ if (cb) {
+ if (state.finished) processNextTick(cb);else stream.once('finish', cb);
+ }
+ state.ended = true;
+ stream.writable = false;
+}
+
+// It seems a linked list but it is not
+// there will be only 2 of these for each stream
+function CorkedRequest(state) {
+ var _this = this;
+
+ this.next = null;
+ this.entry = null;
+ this.finish = function (err) {
+ var entry = _this.entry;
+ _this.entry = null;
+ while (entry) {
+ var cb = entry.callback;
+ state.pendingcb--;
+ cb(err);
+ entry = entry.next;
+ }
+ if (state.corkedRequestsFree) {
+ state.corkedRequestsFree.next = _this;
+ } else {
+ state.corkedRequestsFree = _this;
+ }
+ };
+}
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6), __webpack_require__(99).setImmediate))
+
+/***/ }),
+/* 39 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(__dirname, Buffer, process) {const Snekfetch = __webpack_require__(93);
+
+const ENV_VAR = '__SNEKFETCH_SYNC_REQUEST';
+let first = true;
+
+for (let method of Snekfetch.METHODS) {
+ method = method === 'M-SEARCH' ? 'msearch' : method.toLowerCase();
+ Snekfetch[`${method}Sync`] = (url, options = {}) => {
+ if (first) {
+ first = false;
+ console.error(
+ 'Performing sync requests is a really stupid thing to do. ' +
+ 'https://www.google.com/search?q=why+sync+requests+are+bad+nodejs'
+ );
+ }
+ options.url = url;
+ options.method = method;
+ const cp = __webpack_require__(29);
+ const result = JSON.parse(
+ cp.execSync(`node ${__dirname}/index.js`, {
+ env: { [ENV_VAR]: JSON.stringify(options) },
+ }).toString(),
+ (k, v) => {
+ if (v === null) return v;
+ if (v.type === 'Buffer' && Array.isArray(v.data)) return new Buffer(v.data);
+ if (v.__CONVERT_TO_ERROR) {
+ const e = new Error();
+ for (const key of Object.keys(v)) {
+ if (key === '__CONVERT_TO_ERROR') continue;
+ e[key] = v[key];
+ }
+ return e;
+ }
+ return v;
+ }
+ );
+ if (result.error) throw result.error;
+ return result;
+ };
+}
+
+if (process.env[ENV_VAR]) {
+ const options = JSON.parse(process.env[ENV_VAR]);
+ const request = Snekfetch[options.method](options.url);
+ if (options.headers) request.set(options.headers);
+ if (options.body) request.send(options.body);
+ request.end((err, res = {}) => {
+ if (err) {
+ const alt = {};
+ for (const name of Object.getOwnPropertyNames(err)) alt[name] = err[name];
+ res.error = alt;
+ res.error.__CONVERT_TO_ERROR = true;
+ }
+ // circulars
+ res.request = null;
+ process.stdout.write(JSON.stringify(res));
+ });
+}
+
+module.exports = Snekfetch;
+
+/* WEBPACK VAR INJECTION */}.call(exports, "node_modules/snekfetch", __webpack_require__(5).Buffer, __webpack_require__(6)))
+
+/***/ }),
+/* 40 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(Buffer) {const path = __webpack_require__(28);
+const fs = __webpack_require__(29);
+const snekfetch = __webpack_require__(39);
+
+const Constants = __webpack_require__(0);
+const convertToBuffer = __webpack_require__(4).convertToBuffer;
+const User = __webpack_require__(16);
+const Message = __webpack_require__(19);
+const Guild = __webpack_require__(25);
+const Channel = __webpack_require__(14);
+const GuildMember = __webpack_require__(18);
+const Emoji = __webpack_require__(17);
+const ReactionEmoji = __webpack_require__(31);
+
+/**
+ * The DataResolver identifies different objects and tries to resolve a specific piece of information from them, e.g.
+ * extracting a User from a Message object.
+ * @private
+ */
+class ClientDataResolver {
+ /**
+ * @param {Client} client The client the resolver is for
+ */
+ constructor(client) {
+ this.client = client;
+ }
+
+ /**
+ * Data that resolves to give a User object. This can be:
+ * * A User object
+ * * A user ID
+ * * A Message object (resolves to the message author)
+ * * A Guild object (owner of the guild)
+ * * A GuildMember object
+ * @typedef {User|Snowflake|Message|Guild|GuildMember} UserResolvable
+ */
+
+ /**
+ * Resolves a UserResolvable to a User object.
+ * @param {UserResolvable} user The UserResolvable to identify
+ * @returns {?User}
+ */
+ resolveUser(user) {
+ if (user instanceof User) return user;
+ if (typeof user === 'string') return this.client.users.get(user) || null;
+ if (user instanceof GuildMember) return user.user;
+ if (user instanceof Message) return user.author;
+ if (user instanceof Guild) return user.owner;
+ return null;
+ }
+
+ /**
+ * Resolves a UserResolvable to a user ID string.
+ * @param {UserResolvable} user The UserResolvable to identify
+ * @returns {?Snowflake}
+ */
+ resolveUserID(user) {
+ if (user instanceof User || user instanceof GuildMember) return user.id;
+ if (typeof user === 'string') return user || null;
+ if (user instanceof Message) return user.author.id;
+ if (user instanceof Guild) return user.ownerID;
+ return null;
+ }
+
+ /**
+ * Data that resolves to give a Guild object. This can be:
+ * * A Guild object
+ * * A Guild ID
+ * @typedef {Guild|Snowflake} GuildResolvable
+ */
+
+ /**
+ * Resolves a GuildResolvable to a Guild object.
+ * @param {GuildResolvable} guild The GuildResolvable to identify
+ * @returns {?Guild}
+ */
+ resolveGuild(guild) {
+ if (guild instanceof Guild) return guild;
+ if (typeof guild === 'string') return this.client.guilds.get(guild) || null;
+ return null;
+ }
+
+ /**
+ * Data that resolves to give a GuildMember object. This can be:
+ * * A GuildMember object
+ * * A User object
+ * @typedef {GuildMember|User} GuildMemberResolvable
+ */
+
+ /**
+ * Resolves a GuildMemberResolvable to a GuildMember object.
+ * @param {GuildResolvable} guild The guild that the member is part of
+ * @param {UserResolvable} user The user that is part of the guild
+ * @returns {?GuildMember}
+ */
+ resolveGuildMember(guild, user) {
+ if (user instanceof GuildMember) return user;
+ guild = this.resolveGuild(guild);
+ user = this.resolveUser(user);
+ if (!guild || !user) return null;
+ return guild.members.get(user.id) || null;
+ }
+
+ /**
+ * Data that can be resolved to give a Channel object. This can be:
+ * * A Channel object
+ * * A Message object (the channel the message was sent in)
+ * * A Guild object (the #general channel)
+ * * A channel ID
+ * @typedef {Channel|Guild|Message|Snowflake} ChannelResolvable
+ */
+
+ /**
+ * Resolves a ChannelResolvable to a Channel object.
+ * @param {ChannelResolvable} channel The channel resolvable to resolve
+ * @returns {?Channel}
+ */
+ resolveChannel(channel) {
+ if (channel instanceof Channel) return channel;
+ if (typeof channel === 'string') return this.client.channels.get(channel) || null;
+ if (channel instanceof Message) return channel.channel;
+ if (channel instanceof Guild) return channel.channels.get(channel.id) || null;
+ return null;
+ }
+
+ /**
+ * Resolves a ChannelResolvable to a channel ID.
+ * @param {ChannelResolvable} channel The channel resolvable to resolve
+ * @returns {?Snowflake}
+ */
+ resolveChannelID(channel) {
+ if (channel instanceof Channel) return channel.id;
+ if (typeof channel === 'string') return channel;
+ if (channel instanceof Message) return channel.channel.id;
+ if (channel instanceof Guild) return channel.defaultChannel.id;
+ return null;
+ }
+
+ /**
+ * Data that can be resolved to give an invite code. This can be:
+ * * An invite code
+ * * An invite URL
+ * @typedef {string} InviteResolvable
+ */
+
+ /**
+ * Resolves InviteResolvable to an invite code.
+ * @param {InviteResolvable} data The invite resolvable to resolve
+ * @returns {string}
+ */
+ resolveInviteCode(data) {
+ const inviteRegex = /discord(?:app\.com\/invite|\.gg)\/([\w-]{2,255})/i;
+ const match = inviteRegex.exec(data);
+ if (match && match[1]) return match[1];
+ return data;
+ }
+
+ /**
+ * Data that can be resolved to give a string. This can be:
+ * * A string
+ * * An array (joined with a new line delimiter to give a string)
+ * * Any value
+ * @typedef {string|Array|*} StringResolvable
+ */
+
+ /**
+ * Resolves a StringResolvable to a string.
+ * @param {StringResolvable} data The string resolvable to resolve
+ * @returns {string}
+ */
+ resolveString(data) {
+ if (typeof data === 'string') return data;
+ if (data instanceof Array) return data.join('\n');
+ return String(data);
+ }
+
+ /**
+ * Data that resolves to give a Base64 string, typically for image uploading. This can be:
+ * * A Buffer
+ * * A base64 string
+ * @typedef {Buffer|string} Base64Resolvable
+ */
+
+ /**
+ * Resolves a Base64Resolvable to a Base 64 image.
+ * @param {Base64Resolvable} data The base 64 resolvable you want to resolve
+ * @returns {?string}
+ */
+ resolveBase64(data) {
+ if (data instanceof Buffer) return `data:image/jpg;base64,${data.toString('base64')}`;
+ return data;
+ }
+
+ /**
+ * Data that can be resolved to give a Buffer. This can be:
+ * * A Buffer
+ * * The path to a local file
+ * * A URL
+ * @typedef {string|Buffer} BufferResolvable
+ */
+
+ /**
+ * Resolves a BufferResolvable to a Buffer.
+ * @param {BufferResolvable} resource The buffer resolvable to resolve
+ * @returns {Promise}
+ */
+ resolveBuffer(resource) {
+ if (resource instanceof Buffer) return Promise.resolve(resource);
+ if (this.client.browser && resource instanceof ArrayBuffer) return Promise.resolve(convertToBuffer(resource));
+
+ if (typeof resource === 'string') {
+ return new Promise((resolve, reject) => {
+ if (/^https?:\/\//.test(resource)) {
+ snekfetch.get(resource)
+ .end((err, res) => {
+ if (err) return reject(err);
+ if (!(res.body instanceof Buffer)) return reject(new TypeError('The response body isn\'t a Buffer.'));
+ return resolve(res.body);
+ });
+ } else {
+ const file = path.resolve(resource);
+ fs.stat(file, (err, stats) => {
+ if (err) return reject(err);
+ if (!stats || !stats.isFile()) return reject(new Error(`The file could not be found: ${file}`));
+ fs.readFile(file, (err2, data) => {
+ if (err2) reject(err2); else resolve(data);
+ });
+ return null;
+ });
+ }
+ });
+ }
+
+ return Promise.reject(new TypeError('The resource must be a string or Buffer.'));
+ }
+
+ /**
+ * Data that can be resolved to give an emoji identifier. This can be:
+ * * The unicode representation of an emoji
+ * * A custom emoji ID
+ * * An Emoji object
+ * * A ReactionEmoji object
+ * @typedef {string|Emoji|ReactionEmoji} EmojiIdentifierResolvable
+ */
+
+ /**
+ * Resolves an EmojiResolvable to an emoji identifier.
+ * @param {EmojiIdentifierResolvable} emoji The emoji resolvable to resolve
+ * @returns {?string}
+ */
+ resolveEmojiIdentifier(emoji) {
+ if (emoji instanceof Emoji || emoji instanceof ReactionEmoji) return emoji.identifier;
+ if (typeof emoji === 'string') {
+ if (this.client.emojis.has(emoji)) return this.client.emojis.get(emoji).identifier;
+ else if (!emoji.includes('%')) return encodeURIComponent(emoji);
+ else return emoji;
+ }
+ return null;
+ }
+
+ /**
+ * Can be a Hex Literal, Hex String, Number, RGB Array, or one of the following
+ * ```
+ * [
+ * 'DEFAULT',
+ * 'AQUA',
+ * 'GREEN',
+ * 'BLUE',
+ * 'PURPLE',
+ * 'GOLD',
+ * 'ORANGE',
+ * 'RED',
+ * 'GREY',
+ * 'DARKER_GREY',
+ * 'NAVY',
+ * 'DARK_AQUA',
+ * 'DARK_GREEN',
+ * 'DARK_BLUE',
+ * 'DARK_PURPLE',
+ * 'DARK_GOLD',
+ * 'DARK_ORANGE',
+ * 'DARK_RED',
+ * 'DARK_GREY',
+ * 'LIGHT_GREY',
+ * 'DARK_NAVY',
+ * 'RANDOM',
+ * ]
+ * ```
+ * or something like
+ * ```
+ * [255, 0, 255]
+ * ```
+ * for purple
+ * @typedef {string|number|Array} ColorResolvable
+ */
+
+ /**
+ * Resolves a ColorResolvable into a color number.
+ * @param {ColorResolvable} color Color to resolve
+ * @returns {number} A color
+ */
+ static resolveColor(color) {
+ if (typeof color === 'string') {
+ if (color === 'RANDOM') return Math.floor(Math.random() * (0xFFFFFF + 1));
+ color = Constants.Colors[color] || parseInt(color.replace('#', ''), 16);
+ } else if (color instanceof Array) {
+ color = (color[0] << 16) + (color[1] << 8) + color[2];
+ }
+
+ if (color < 0 || color > 0xFFFFFF) {
+ throw new RangeError('Color must be within the range 0 - 16777215 (0xFFFFFF).');
+ } else if (color && isNaN(color)) {
+ throw new TypeError('Unable to convert color to a number.');
+ }
+
+ return color;
+ }
+
+ /**
+ * @param {ColorResolvable} color Color to resolve
+ * @returns {number} A color
+ */
+ resolveColor(color) {
+ return this.constructor.resolveColor(color);
+ }
+}
+
+module.exports = ClientDataResolver;
+
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer))
+
+/***/ }),
+/* 41 */
+/***/ (function(module, exports) {
+
+module.exports = {
+ "name": "discord.js",
+ "version": "11.1.0",
+ "description": "A powerful library for interacting with the Discord API",
+ "main": "./src/index",
+ "types": "./typings/index.d.ts",
+ "scripts": {
+ "test": "npm run lint && npm run docs:test",
+ "docs": "docgen --source src --custom docs/index.yml --output docs/docs.json",
+ "docs:test": "docgen --source src --custom docs/index.yml",
+ "lint": "eslint src",
+ "lint:fix": "eslint --fix src",
+ "webpack": "parallel-webpack"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/hydrabolt/discord.js.git"
+ },
+ "keywords": [
+ "discord",
+ "api",
+ "bot",
+ "client",
+ "node",
+ "discordapp"
+ ],
+ "author": "Amish Shah ",
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://github.com/hydrabolt/discord.js/issues"
+ },
+ "homepage": "https://github.com/hydrabolt/discord.js#readme",
+ "runkitExampleFilename": "./docs/examples/ping.js",
+ "dependencies": {
+ "long": "^3.2.0",
+ "prism-media": "^0.0.1",
+ "snekfetch": "^3.1.0",
+ "tweetnacl": "^0.14.0",
+ "ws": "^2.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^3.0.0",
+ "erlpack": "hammerandchisel/erlpack",
+ "node-opus": "^0.2.5",
+ "opusscript": "^0.0.3",
+ "sodium": "^2.0.1",
+ "libsodium-wrappers": "^0.5.1",
+ "uws": "^0.14.1"
+ },
+ "devDependencies": {
+ "@types/node": "^7.0.0",
+ "discord.js-docgen": "hydrabolt/discord.js-docgen",
+ "eslint": "^3.19.0",
+ "parallel-webpack": "^1.6.0",
+ "uglify-js": "mishoo/UglifyJS2#harmony",
+ "webpack": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ },
+ "browser": {
+ "ws": false,
+ "uws": false,
+ "erlpack": false,
+ "prism-media": false,
+ "opusscript": false,
+ "node-opus": false,
+ "tweetnacl": false,
+ "sodium": false,
+ "src/sharding/Shard.js": false,
+ "src/sharding/ShardClientUtil.js": false,
+ "src/sharding/ShardingManager.js": false,
+ "src/client/voice/dispatcher/StreamDispatcher.js": false,
+ "src/client/voice/opus/BaseOpusEngine.js": false,
+ "src/client/voice/opus/NodeOpusEngine.js": false,
+ "src/client/voice/opus/OpusEngineList.js": false,
+ "src/client/voice/opus/OpusScriptEngine.js": false,
+ "src/client/voice/pcm/ConverterEngine.js": false,
+ "src/client/voice/pcm/ConverterEngineList.js": false,
+ "src/client/voice/pcm/FfmpegConverterEngine.js": false,
+ "src/client/voice/player/AudioPlayer.js": false,
+ "src/client/voice/receiver/VoiceReadable.js": false,
+ "src/client/voice/receiver/VoiceReceiver.js": false,
+ "src/client/voice/util/Secretbox.js": false,
+ "src/client/voice/util/SecretKey.js": false,
+ "src/client/voice/util/VolumeInterface.js": false,
+ "src/client/voice/ClientVoiceManager.js": false,
+ "src/client/voice/VoiceBroadcast.js": false,
+ "src/client/voice/VoiceConnection.js": false,
+ "src/client/voice/VoiceUDPClient.js": false,
+ "src/client/voice/VoiceWebSocket.js": false
+ }
+};
+
+/***/ }),
+/* 42 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const User = __webpack_require__(16);
+const Collection = __webpack_require__(3);
+const ClientUserSettings = __webpack_require__(43);
+const Constants = __webpack_require__(0);
+
+/**
+ * Represents the logged in client's Discord user.
+ * @extends {User}
+ */
+class ClientUser extends User {
+ setup(data) {
+ super.setup(data);
+
+ /**
+ * Whether or not this account has been verified
+ * @type {boolean}
+ */
+ this.verified = data.verified;
+
+ /**
+ * The email of this account
+ * @type {string}
+ */
+ this.email = data.email;
+ this.localPresence = {};
+ this._typing = new Map();
+
+ /**
+ * A Collection of friends for the logged in user
+ * This is only filled when using a user account.
+ * @type {Collection}
+ */
+ this.friends = new Collection();
+
+ /**
+ * A Collection of blocked users for the logged in user
+ * This is only filled when using a user account.
+ * @type {Collection}
+ */
+ this.blocked = new Collection();
+
+ /**
+ * A Collection of notes for the logged in user
+ * This is only filled when using a user account.
+ * @type {Collection}
+ */
+ this.notes = new Collection();
+
+ /**
+ * If the user has Discord premium (nitro)
+ * This is only filled when using a user account.
+ * @type {?boolean}
+ */
+ this.premium = typeof data.premium === 'boolean' ? data.premium : null;
+
+ /**
+ * If the user has MFA enabled on their account
+ * This is only filled when using a user account.
+ * @type {?boolean}
+ */
+ this.mfaEnabled = typeof data.mfa_enabled === 'boolean' ? data.mfa_enabled : null;
+
+ /**
+ * If the user has ever used a mobile device on Discord
+ * This is only filled when using a user account.
+ * @type {?boolean}
+ */
+ this.mobile = typeof data.mobile === 'boolean' ? data.mobile : null;
+
+ /**
+ * Various settings for this user
+ * This is only filled when using a user account.
+ * @type {?ClientUserSettings}
+ */
+ if (data.user_settings) this.settings = new ClientUserSettings(this, data.user_settings);
+ }
+
+ edit(data) {
+ return this.client.rest.methods.updateCurrentUser(data);
+ }
+
+ /**
+ * Set the username of the logged in client.
+ * Changing usernames in Discord is heavily rate limited, with only 2 requests
+ * every hour. Use this sparingly!
+ * @param {string} username The new username
+ * @param {string} [password] Current password (only for user accounts)
+ * @returns {Promise}
+ * @example
+ * // Set username
+ * client.user.setUsername('discordjs')
+ * .then(user => console.log(`My new username is ${user.username}`))
+ * .catch(console.error);
+ */
+ setUsername(username, password) {
+ return this.client.rest.methods.updateCurrentUser({ username }, password);
+ }
+
+ /**
+ * Changes the email for the client user's account.
+ * This is only available when using a user account.
+ * @param {string} email New email to change to
+ * @param {string} password Current password
+ * @returns {Promise}
+ * @example
+ * // Set email
+ * client.user.setEmail('bob@gmail.com', 'some amazing password 123')
+ * .then(user => console.log(`My new email is ${user.email}`))
+ * .catch(console.error);
+ */
+ setEmail(email, password) {
+ return this.client.rest.methods.updateCurrentUser({ email }, password);
+ }
+
+ /**
+ * Changes the password for the client user's account.
+ * This is only available when using a user account.
+ * @param {string} newPassword New password to change to
+ * @param {string} oldPassword Current password
+ * @returns {Promise}
+ * @example
+ * // Set password
+ * client.user.setPassword('some new amazing password 456', 'some amazing password 123')
+ * .then(user => console.log('New password set!'))
+ * .catch(console.error);
+ */
+ setPassword(newPassword, oldPassword) {
+ return this.client.rest.methods.updateCurrentUser({ password: newPassword }, oldPassword);
+ }
+
+ /**
+ * Set the avatar of the logged in client.
+ * @param {BufferResolvable|Base64Resolvable} avatar The new avatar
+ * @returns {Promise}
+ * @example
+ * // Set avatar
+ * client.user.setAvatar('./avatar.png')
+ * .then(user => console.log(`New avatar set!`))
+ * .catch(console.error);
+ */
+ setAvatar(avatar) {
+ if (typeof avatar === 'string' && avatar.startsWith('data:')) {
+ return this.client.rest.methods.updateCurrentUser({ avatar });
+ } else {
+ return this.client.resolver.resolveBuffer(avatar).then(data =>
+ this.client.rest.methods.updateCurrentUser({ avatar: data })
+ );
+ }
+ }
+
+ /**
+ * Data resembling a raw Discord presence.
+ * @typedef {Object} PresenceData
+ * @property {PresenceStatus} [status] Status of the user
+ * @property {boolean} [afk] Whether the user is AFK
+ * @property {Object} [game] Game the user is playing
+ * @property {string} [game.name] Name of the game
+ * @property {string} [game.url] Twitch stream URL
+ */
+
+ /**
+ * Sets the full presence of the client user.
+ * @param {PresenceData} data Data for the presence
+ * @returns {Promise}
+ */
+ setPresence(data) {
+ // {"op":3,"d":{"status":"dnd","since":0,"game":null,"afk":false}}
+ return new Promise(resolve => {
+ let status = this.localPresence.status || this.presence.status;
+ let game = this.localPresence.game;
+ let afk = this.localPresence.afk || this.presence.afk;
+
+ if (!game && this.presence.game) {
+ game = {
+ name: this.presence.game.name,
+ type: this.presence.game.type,
+ url: this.presence.game.url,
+ };
+ }
+
+ if (data.status) {
+ if (typeof data.status !== 'string') throw new TypeError('Status must be a string');
+ if (this.bot) {
+ status = data.status;
+ } else {
+ this.settings.update(Constants.UserSettingsMap.status, data.status);
+ status = 'invisible';
+ }
+ }
+
+ if (data.game) {
+ game = data.game;
+ if (game.url) game.type = 1;
+ } else if (typeof data.game !== 'undefined') {
+ game = null;
+ }
+
+ if (typeof data.afk !== 'undefined') afk = data.afk;
+ afk = Boolean(afk);
+
+ this.localPresence = { status, game, afk };
+ this.localPresence.since = 0;
+ this.localPresence.game = this.localPresence.game || null;
+
+ this.client.ws.send({
+ op: 3,
+ d: this.localPresence,
+ });
+
+ this.client._setPresence(this.id, this.localPresence);
+
+ resolve(this);
+ });
+ }
+
+ /**
+ * A user's status. Must be one of:
+ * - `online`
+ * - `idle`
+ * - `invisible`
+ * - `dnd` (do not disturb)
+ * @typedef {string} PresenceStatus
+ */
+
+ /**
+ * Sets the status of the client user.
+ * @param {PresenceStatus} status Status to change to
+ * @returns {Promise}
+ */
+ setStatus(status) {
+ return this.setPresence({ status });
+ }
+
+ /**
+ * Sets the game the client user is playing.
+ * @param {?string} game Game being played
+ * @param {string} [streamingURL] Twitch stream URL
+ * @returns {Promise}
+ */
+ setGame(game, streamingURL) {
+ if (!game) return this.setPresence({ game: null });
+ return this.setPresence({
+ game: {
+ name: game,
+ url: streamingURL,
+ },
+ });
+ }
+
+ /**
+ * Sets/removes the AFK flag for the client user.
+ * @param {boolean} afk Whether or not the user is AFK
+ * @returns {Promise}
+ */
+ setAFK(afk) {
+ return this.setPresence({ afk });
+ }
+
+ /**
+ * Fetches messages that mentioned the client's user.
+ * @param {Object} [options] Options for the fetch
+ * @param {number} [options.limit=25] Maximum number of mentions to retrieve
+ * @param {boolean} [options.roles=true] Whether to include role mentions
+ * @param {boolean} [options.everyone=true] Whether to include everyone/here mentions
+ * @param {Guild|Snowflake} [options.guild] Limit the search to a specific guild
+ * @returns {Promise}
+ */
+ fetchMentions(options = { limit: 25, roles: true, everyone: true, guild: null }) {
+ return this.client.rest.methods.fetchMentions(options);
+ }
+
+ /**
+ * Send a friend request.
+ * This is only available when using a user account.
+ * @param {UserResolvable} user The user to send the friend request to
+ * @returns {Promise} The user the friend request was sent to
+ */
+ addFriend(user) {
+ user = this.client.resolver.resolveUser(user);
+ return this.client.rest.methods.addFriend(user);
+ }
+
+ /**
+ * Remove a friend.
+ * This is only available when using a user account.
+ * @param {UserResolvable} user The user to remove from your friends
+ * @returns {Promise} The user that was removed
+ */
+ removeFriend(user) {
+ user = this.client.resolver.resolveUser(user);
+ return this.client.rest.methods.removeFriend(user);
+ }
+
+ /**
+ * Creates a guild.
+ * This is only available when using a user account.
+ * @param {string} name The name of the guild
+ * @param {string} region The region for the server
+ * @param {BufferResolvable|Base64Resolvable} [icon=null] The icon for the guild
+ * @returns {Promise} The guild that was created
+ */
+ createGuild(name, region, icon = null) {
+ if (!icon) return this.client.rest.methods.createGuild({ name, icon, region });
+ if (typeof icon === 'string' && icon.startsWith('data:')) {
+ return this.client.rest.methods.createGuild({ name, icon, region });
+ } else {
+ return this.client.resolver.resolveBuffer(icon).then(data =>
+ this.client.rest.methods.createGuild({ name, icon: data, region })
+ );
+ }
+ }
+
+ /**
+ * An object containing either a user or access token, and an optional nickname.
+ * @typedef {Object} GroupDMRecipientOptions
+ * @property {UserResolvable|Snowflake} [user] User to add to the Group DM
+ * (only available if a user is creating the DM)
+ * @property {string} [accessToken] Access token to use to add a user to the Group DM
+ * (only available if a bot is creating the DM)
+ * @property {string} [nick] Permanent nickname (only available if a bot is creating the DM)
+ */
+
+ /**
+ * Creates a Group DM.
+ * @param {GroupDMRecipientOptions[]} recipients The recipients
+ * @returns {Promise}
+ */
+ createGroupDM(recipients) {
+ return this.client.rest.methods.createGroupDM({
+ recipients: recipients.map(u => this.client.resolver.resolveUserID(u.user)),
+ accessTokens: recipients.map(u => u.accessToken),
+ nicks: recipients.map(u => u.nick),
+ });
+ }
+
+ /**
+ * Accepts an invite to join a guild.
+ * This is only available when using a user account.
+ * @param {Invite|string} invite Invite or code to accept
+ * @returns {Promise} Joined guild
+ */
+ acceptInvite(invite) {
+ return this.client.rest.methods.acceptInvite(invite);
+ }
+}
+
+module.exports = ClientUser;
+
+
+/***/ }),
+/* 43 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Constants = __webpack_require__(0);
+const Util = __webpack_require__(4);
+
+/**
+ * A wrapper around the ClientUser's settings.
+ */
+class ClientUserSettings {
+ constructor(user, data) {
+ this.user = user;
+ this.patch(data);
+ }
+
+ /**
+ * Patch the data contained in this class with new partial data.
+ * @param {Object} data Data to patch this with
+ */
+ patch(data) {
+ for (const key of Object.keys(Constants.UserSettingsMap)) {
+ const value = Constants.UserSettingsMap[key];
+ if (!data.hasOwnProperty(key)) continue;
+ if (typeof value === 'function') {
+ this[value.name] = value(data[key]);
+ } else {
+ this[value] = data[key];
+ }
+ }
+ }
+
+ /**
+ * Update a specific property of of user settings.
+ * @param {string} name Name of property
+ * @param {value} value Value to patch
+ * @returns {Promise