├── .eslintrc.json ├── .gitignore ├── README.md ├── config.js.example ├── index.js ├── initlangs.js ├── lang ├── en.json └── fr.json ├── package-lock.json └── package.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "env": { 4 | "node": true, 5 | "es6": true 6 | }, 7 | "parserOptions": { 8 | "ecmaVersion": 2017 9 | }, 10 | "rules": { 11 | "no-extra-parens": ["warn", "all", { 12 | "nestedBinaryExpressions": false 13 | }], 14 | "valid-jsdoc": ["warn", { 15 | "requireReturn": false, 16 | "requireReturnDescription": false, 17 | "preferType": { 18 | "String": "string", 19 | "Number": "number", 20 | "Boolean": "boolean", 21 | "Symbol": "symbol", 22 | "function": "Function", 23 | "object": "Object", 24 | "date": "Date", 25 | "error": "Error" 26 | } 27 | }], 28 | 29 | "accessor-pairs": "warn", 30 | "array-callback-return": "error", 31 | "complexity": "warn", 32 | "consistent-return": "error", 33 | "curly": ["error", "multi-line", "consistent"], 34 | "dot-location": ["error", "property"], 35 | "dot-notation": "error", 36 | "eqeqeq": "error", 37 | "no-console": ["error", { "allow": ["log", "warn", "error"] }], 38 | "no-empty-function": "error", 39 | "no-floating-decimal": "error", 40 | "no-implied-eval": "error", 41 | "no-invalid-this": "error", 42 | "no-lone-blocks": "error", 43 | "no-multi-spaces": "error", 44 | "no-new-func": "error", 45 | "no-new-wrappers": "error", 46 | "no-new": "error", 47 | "no-octal-escape": "error", 48 | "no-return-assign": "error", 49 | "no-self-compare": "error", 50 | "no-sequences": "error", 51 | "no-unmodified-loop-condition": "error", 52 | "no-unused-expressions": "error", 53 | "no-useless-call": "error", 54 | "no-useless-concat": "error", 55 | "no-useless-escape": "error", 56 | "no-void": "error", 57 | "no-warning-comments": "warn", 58 | "wrap-iife": "error", 59 | "yoda": "error", 60 | 61 | "no-label-var": "error", 62 | "no-shadow": "error", 63 | "no-undef-init": "error", 64 | 65 | "callback-return": "error", 66 | "handle-callback-err": "error", 67 | "no-mixed-requires": "error", 68 | "no-new-require": "error", 69 | "no-path-concat": "error", 70 | "no-process-env": "error", 71 | 72 | "array-bracket-spacing": "error", 73 | "block-spacing": "error", 74 | "brace-style": ["error", "1tbs", { "allowSingleLine": true }], 75 | "camelcase": "error", 76 | "comma-dangle": "error", 77 | "comma-spacing": "error", 78 | "comma-style": "error", 79 | "computed-property-spacing": "error", 80 | "consistent-this": "error", 81 | "eol-last": "error", 82 | "func-names": "error", 83 | "func-style": ["error", "declaration", { "allowArrowFunctions": true }], 84 | "id-length": ["error", { "exceptions": ["i", "j", "a", "b"] }], 85 | "indent": ["error", 2, {"SwitchCase": 1 }], 86 | "key-spacing": "error", 87 | "keyword-spacing": ["error", { 88 | "overrides": { 89 | "if": { "after": true }, 90 | "for": { "after": true }, 91 | "while": { "after": true }, 92 | "catch": { "after": true }, 93 | "switch": { "after": true } 94 | } 95 | }], 96 | "max-depth": "error", 97 | "max-len": ["error", 200, 2], 98 | "max-nested-callbacks": ["error", { "max": 4 }], 99 | "max-statements-per-line": ["error", { "max": 2 }], 100 | "new-cap": "error", 101 | "newline-per-chained-call": ["error", { "ignoreChainWithDepth": 6 }], 102 | "no-array-constructor": "error", 103 | "no-bitwise": "warn", 104 | "no-inline-comments": "error", 105 | "no-lonely-if": "error", 106 | "no-mixed-operators": "error", 107 | "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], 108 | "no-new-object": "error", 109 | "no-spaced-func": "error", 110 | "no-trailing-spaces": "error", 111 | "no-unneeded-ternary": "error", 112 | "no-whitespace-before-property": "error", 113 | "object-curly-newline": "error", 114 | "object-curly-spacing": ["error", "always"], 115 | "operator-assignment": "error", 116 | "operator-linebreak": ["error", "after"], 117 | "padded-blocks": ["error", { "classes": "always", "blocks": "never", "switches": "never" }], 118 | "quote-props": ["error", "as-needed"], 119 | "quotes": ["error", "single", { "avoidEscape": true, "allowTemplateLiterals": true }], 120 | "semi-spacing": "error", 121 | "semi": "error", 122 | "space-before-blocks": "error", 123 | "space-before-function-paren": ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always"}], 124 | "space-in-parens": "error", 125 | "space-infix-ops": "error", 126 | "space-unary-ops": "error", 127 | "spaced-comment": "error", 128 | "unicode-bom": "error", 129 | 130 | "arrow-body-style": "error", 131 | "arrow-spacing": "error", 132 | "no-duplicate-imports": "error", 133 | "no-useless-computed-key": "error", 134 | "no-useless-constructor": "error", 135 | "prefer-arrow-callback": "error", 136 | "prefer-const": "error", 137 | "prefer-destructuring": ["error", { 138 | "VariableDeclarator": { 139 | "array": false, 140 | "object": true 141 | }, 142 | "AssignmentExpression": { 143 | "array": true, 144 | "object": true 145 | } 146 | }, { 147 | "enforceForRenamedProperties": false 148 | }], 149 | "prefer-rest-params": "error", 150 | "prefer-spread": "error", 151 | "prefer-template": "error", 152 | "rest-spread-spacing": "error", 153 | "template-curly-spacing": "error", 154 | "yield-star-spacing": "error" 155 | } 156 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | config.json 6 | config.js 7 | data/ 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | *.pid.lock 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | 21 | # nyc test coverage 22 | .nyc_output 23 | 24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 25 | .grunt 26 | 27 | # Bower dependency directory (https://bower.io/) 28 | bower_components 29 | 30 | # node-waf configuration 31 | .lock-wscript 32 | 33 | # Compiled binary addons (http://nodejs.org/api/addons.html) 34 | build/Release 35 | 36 | # Dependency directories 37 | node_modules/ 38 | jspm_packages/ 39 | 40 | # Typescript v1 declaration files 41 | typings/ 42 | 43 | # Optional npm cache directory 44 | .npm 45 | 46 | # Optional eslint cache 47 | .eslintcache 48 | 49 | # Optional REPL history 50 | .node_repl_history 51 | 52 | # Output of 'npm pack' 53 | *.tgz 54 | 55 | # Yarn Integrity file 56 | .yarn-integrity 57 | 58 | # dotenv environment variables file 59 | .env 60 | 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Etiket - Dead Simple Tags 2 | 3 | Etiket is a simple tag bot that offers very few features execpt for its main one: **Tags**. 4 | 5 | What are *Tags* you ask? They're bits of text that you repeat often and want to save somewhere so that you - or anyone else on your server - can call up at any time to answer frequently asked questions. 6 | 7 | Tags can be used to provide information, contact, instructions, or on the other hand can be filled with memes and jokes and all the shitposting you want. It's up to you to determine how tags are used! 8 | 9 | ## Prerequisites 10 | 11 | > Don't want to bother installing this yourself and just want to use the bot yourself? Sure, just [invite it here](https://discordapp.com/api/oauth2/authorize?client_id=419529979768864770&permissions=2112&scope=bot)! 12 | 13 | Etiket runs on node.js and uses the Discord.js library. It uses a MongoDB database as a back-end. 14 | 15 | It requires the following: 16 | 17 | - `git` command line ([Windows](https://git-scm.com/download/win)|[Linux](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)|[MacOS](https://git-scm.com/download/mac)) installed 18 | - [Nodejs 7.6 or higher](http://nodejs.org/) 19 | - `a machine` to host it on. Want it to be online 24/7? Get a VPS. I suggest [OVH](http://ovh.com/) (no there are no good free hosts). 20 | - A MongoDB instance. If you do not have one, there are online free ones. For testing, check out [mLab](https://mlab.com/) which has a free sandbox option (not backed up). 21 | 22 | ## Installation 23 | 24 | In a command prompt in your projects folder (wherever that may be) run the following: 25 | 26 | `git clone https://github.com/eslachance/etiket.git` 27 | 28 | Once finished: 29 | 30 | - In the folder from where you ran the git command, run `cd etiket` and then run `npm i` 31 | - Rename `config.js.example` to `config.js` 32 | - Edit `config.js` and enter your token and other details as indicated. 33 | - Execute `node initlangs.js`. This will import all the language strings into the database. 34 | 35 | ## First Start 36 | 37 | To start etiket, in the command prompt, run the following command: 38 | `node .` 39 | 40 | > If at any point it says "cannot find module X" just run `npm install X` and try again. 41 | 42 | ## Commands Reference 43 | 44 | The following commands are available in the bot (`` is called a placeholder and you can replace it with actual data!): 45 | 46 | ``` 47 | ?tagname // Tags are accessed by prefix+tagname. 48 | 49 | // Modifying tags is reserved for Moderator or higher. 50 | ?tag add // Creates a new tag with the selected name. Can be multiple lines, markdown, etc. Currently does not support embeds and attachments 51 | ?tag rename // Rename existing tag 52 | ?tag edit // Edit tag contents 53 | ?tag del // Delete tag (cannot undo!) 54 | 55 | // Blacklist are Moderator or higher only 56 | ?blacklist add // Prevents user from using bot completely 57 | ?blacklist view // Displays all users currently in the blacklist. 58 | ?blacklist remove // Restores access to bot commands 59 | 60 | // Settings are Admin/Guild owner only 61 | ?settings // View settings for the server 62 | ?settings edit // Edits the value of a setting for the server. 63 | ?settings reset // Restores the global default for the settings key. 64 | ?settings add // For array settings, add a new value to the setting array (like prefixes) 65 | ?settings del // For array settings, remove the value from the settings array. 66 | 67 | ?eval // Owner only, evals arbitrary javascript. useful for debugging/custom stuff 68 | ``` 69 | 70 | ## Permanent run and Auto-restart 71 | 72 | To run the bot permanently, you'll need `pm2` 73 | 74 | For the first run: 75 | 76 | ``` 77 | npm i -g pm2 78 | pm2 start index.js --name="etiket" 79 | ``` 80 | 81 | - To start the bot after a system reboot, run `pm2 start etiket` 82 | - To view the logs, just run `pm2 logs etiket` 83 | - To restart the bot, run `pm2 restart etiket` 84 | - To stop it, run `pm2 stop etiket` 85 | - To setup auto start at boot, run `pm2 startup`, run the snip of text that it outputs, then run `pm2 save`. 86 | 87 | ## Support 88 | 89 | If you need help running this bot, check the **Issues** pane on this repository. Support is not guaranteed, -------------------------------------------------------------------------------- /config.js.example: -------------------------------------------------------------------------------- 1 | const config = { 2 | // Bot Owner, level 4. A User ID. Should never be anything else than the bot owner's ID. 3 | ownerID: "123456789123456", 4 | 5 | // Your Bot's Token. Available on https://discordapp.com/developers/applications/me 6 | token: "mfa.VkO_2G4Qv3T--NO--lWetW_tjND--TOKEN--QFTm6YGtzq9PH--4U--tG0", 7 | 8 | // Default per-server settings. New guilds have these settings. 9 | defaultSettings: { 10 | prefixes: ['+', '?'], 11 | lang: 'en', 12 | admins: [], 13 | mods: [] 14 | }, 15 | 16 | mongodb: { url: 'mongodb://user:password@localhost:27017/enmap' }, 17 | 18 | permLevels: [ 19 | { 20 | level: 0, 21 | name: 'User', 22 | check: () => true 23 | }, 24 | { 25 | level: 2, 26 | name: 'Moderator', 27 | guildOnly: true, 28 | check: (message) => message.member.roles.some(role => config.support.includes(role.id)) 29 | }, 30 | { 31 | level: 3, 32 | name: 'Administrator', 33 | guildOnly: true, 34 | check: (message) => message.member.roles.some(role => config.admins.includes(role.id)) || 35 | message.member.roles.some(role => role.hasPermission('ADMINISTRATOR')) || 36 | message.author.id === message.guild.owner.user.id 37 | }, 38 | { 39 | level: 4, 40 | name: 'Bot Owner', 41 | check: (message) => config.ownerID === message.author.id 42 | } 43 | ] 44 | }; 45 | 46 | module.exports = config; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* eslint consistent-return: 0 */ 2 | const moment = require('moment'); 3 | require('moment-duration-format'); 4 | const { inspect } = require('util'); 5 | 6 | const config = require('./config.js'); 7 | const Discord = require('discord.js'); 8 | const client = new Discord.Client({ 9 | disableEveryone: true, 10 | disabledEvents: config.disabledEvents, 11 | messageCacheMaxSize: 10, 12 | messageCacheLifetime: 10 13 | }); 14 | 15 | const Provider = require('enmap-mongo'); 16 | const Enmap = require('enmap'); 17 | const { settings, tags, blacklist, langs, testing } = Enmap.multi(['settings', 'tags', 'blacklist', 'langs', 'testing'], Provider, { url: config.mongodb.url }); 18 | 19 | const cooldown = new Set(); 20 | 21 | const commands = { 22 | tags: { 23 | run: async (message) => { 24 | const tagslist = tags.filter(tag => tag.guild === message.guild.id).map(tag => `+${tag.name}`).join(' '); 25 | const list = message.strings.taglist.replace('{tags}', tagslist); 26 | try { 27 | return [list, null]; 28 | } catch (err) { 29 | return [message.strings.enabledms, '❌']; 30 | } 31 | }, 32 | level: 0 33 | }, 34 | list: { 35 | run: () => commands.tags.run(), 36 | level: () => commands.tags.level 37 | }, 38 | test: { 39 | run: (message, args) => { 40 | const myEmbed = new Discord.MessageEmbed(); 41 | myEmbed.setDescription(args.join(" ")); 42 | message.channel.send({embed: myEmbed}); 43 | }, 44 | level: 4 45 | }, 46 | tag: { 47 | run: (message, args) => { 48 | const [action, name, ...content] = args; 49 | let answer; 50 | switch (action) { 51 | case 'add': 52 | if (tags.has(`${message.guild.id}-${name}`)) return message.channel.send(message.strings.tagexists); 53 | if (Object.keys(commands).includes(name)) return message.reply(message.strings.reservedtagname); 54 | tags.set(`${message.guild.id}-${name}`, { 55 | guild: message.guild.id, 56 | content: content.join(' '), 57 | name 58 | }); 59 | answer = [null, '☑']; 60 | break; 61 | case 'del': 62 | if (tags.has(`${message.guild.id}-${name}`)) { 63 | tags.delete(`${message.guild.id}-${name}`); 64 | answer = [null, '☑']; 65 | } else { 66 | answer = [message.strings.tagnotfound, null]; 67 | } 68 | break; 69 | case 'edit': 70 | if (tags.has(`${message.guild.id}-${name}`)) { 71 | tags.set(`${message.guild.id}-${name}`, { 72 | guild: message.guild.id, 73 | content: content.join(' '), 74 | name 75 | }); 76 | answer = [null, '☑']; 77 | } else { 78 | answer = [message.strings.tagnotfound, null]; 79 | } 80 | break; 81 | case 'rename': 82 | if (tags.has(`${message.guild.id}-${name}`)) { 83 | const newName = content[0]; 84 | const oldTag = tags.get(`${message.guild.id}-${name}`); 85 | tags.set(`${message.guild.id}-${newName}`, oldTag); 86 | tags.delete(`${message.guild.id}-${name}`); 87 | answer = [null, '☑']; 88 | } else { 89 | answer = [message.strings.tagnotfound, null]; 90 | } 91 | break; 92 | default: 93 | answer = [null, '⁉']; 94 | } 95 | return answer; 96 | }, 97 | level: 2 98 | }, 99 | blacklist: { 100 | run: (message, args) => { 101 | const action = args[0]; 102 | let user = args[1]; 103 | let answer; 104 | switch (action) { 105 | case 'add': 106 | user = client.users.get(args[1]) || message.mentions.users.first(); 107 | if (!user) return [message.strings.cantfinduser, null]; 108 | blacklist.set(`${message.guild.id}-${user.id}`, { 109 | user: user.id, 110 | guild: message.guild.id, 111 | time: message.createdTimestamp 112 | }); 113 | message.guild.channels.find('name', message.settings.modlog) 114 | .send(message.strings.addedtoblacklist 115 | .replace('{user.tag}', user.tag) 116 | .replace('{user.id}', user.id) 117 | .replace('{author.tag}', message.author.tag) 118 | .replace('{author.id}', message.author.id)) 119 | .catch(); 120 | answer = [null, '☑']; 121 | break; 122 | case 'remove': 123 | case 'del': 124 | user = client.users.get(args[1]) || message.mentions.users.first(); 125 | if (!user) return [message.strings.cantfinduser, null]; 126 | if (blacklist.has(`${message.guild.id}-${user.id}`)) { 127 | const blEntry = blacklist.get(`${message.guild.id}-${user.id}`); 128 | const duration = moment.duration(moment.createdTimestamp - blEntry.time).format(' D [days], H [hrs], m [mins], s [secs]'); 129 | blacklist.delete(`${message.guild.id}-${user.id}`); 130 | message.guild.channels.find('name', message.settings.modlog) 131 | .send(message.strings.addedtoblacklist 132 | .replace('{user.tag}', user.tag) 133 | .replace('{user.id}', user.id) 134 | .replace('{author.tag}', message.author.tag) 135 | .replace('{author.id}', message.author.id) 136 | .replace('{duration}', duration)) 137 | .catch(); 138 | answer = [null, '☑']; 139 | } else { 140 | answer = [message.strings.usernotinblacklist, null]; 141 | } 142 | break; 143 | case 'view': 144 | const blIDs = blacklist.filter(entry => entry.guild === message.guild.id); 145 | const list = blIDs.map(entry => `${entry.user} ... ${client.users.get(entry.user).tag}`); 146 | if(!list.length) { 147 | answer = ['The blacklist is empty.', null] 148 | } else { 149 | answer = [`\`\`\`${list}\`\`\``, null]; 150 | } 151 | break; 152 | default: 153 | answer = [null, '⁉']; 154 | } 155 | return answer; 156 | }, 157 | level: 2 158 | }, 159 | settings: { 160 | run: async (message, args) => { 161 | let answer; 162 | if (!message.guild.id) { 163 | return ['Uhhhh how are you seeing this?', null]; 164 | } 165 | const [action, key, ...val] = args; 166 | switch (action) { 167 | case 'set': case 'edit': 168 | if (!message.settings[key]) { 169 | return [message.strings.invalidsetting, null]; 170 | } 171 | if (message.settings[key].constructor.name.toLowerCase() === 'array') { 172 | return [message.strings.settingisarray, null]; 173 | } 174 | message.settings[key] = val.join(' '); 175 | settings.set(message.guild.id, message.settings); 176 | answer = [null, '☑']; 177 | break; 178 | case 'reset': 179 | if (!message.settings[key]) { 180 | return [message.strings.invalidsetting, null]; 181 | } 182 | delete message.settings[key]; 183 | settings.set(message.guild.id, message.settings); 184 | answer = [null, '☑']; 185 | break; 186 | case 'add': case 'append': 187 | if (!message.settings[key]) { 188 | return [message.strings.invalidsetting, null]; 189 | } 190 | if (!message.settings[key].constructor.name.toLowerCase() === 'array') { 191 | return [message.strings.settingnotarray, null]; 192 | } 193 | if (message.settings[key].indexOf(val.join(' ')) > -1) { 194 | return ['This value is already in the settings array.', null]; 195 | } 196 | message.settings[key].push(val.join(' ')); 197 | settings.set(message.guild.id, message.settings); 198 | answer = [null, '☑']; 199 | break; 200 | case 'del': case 'remove': 201 | if (!message.settings[key]) { 202 | return [message.strings.invalidsetting, null]; 203 | } 204 | if (!message.settings[key].constructor.name.toLowerCase() === 'array') { 205 | return [message.strings.settingnotarray, null]; 206 | } 207 | if (message.settings[key].indexOf(val.join(' ')) < 0) { 208 | return [message.strings.cantfindinarray, null]; 209 | } 210 | message.settings[key].slice(message.settings[key].indexOf(val.join(' ')), 1); 211 | settings.set(message.guild.id, message.settings); 212 | answer = [null, '☑']; 213 | break; 214 | case 'list': case 'view': default: 215 | answer = [JSON.stringify(message.settings), null]; 216 | break; 217 | } 218 | return answer; 219 | }, 220 | level: 3 221 | }, 222 | level: { 223 | run: async (message) => [`You are level ${message.author.level}`, null], 224 | level: 0 225 | }, 226 | eval: { 227 | run: async (message, args) => { 228 | const code = args.join(' '); 229 | try { 230 | const evaled = clean(await eval(code)); 231 | return [`\`\`\`xl\n${evaled}\n\`\`\``, null]; 232 | } catch (err) { 233 | return [`\`ERROR\` \`\`\`xl\n${clean(err)}\n\`\`\``, null]; 234 | } 235 | }, 236 | level: 4 237 | }, 238 | reboot: { 239 | run: () => process.exit(1), 240 | level: 3 241 | } 242 | }; 243 | 244 | module.exports = commands; 245 | 246 | const validateThrottle = (message, level) => { 247 | if ( (message.guild && blacklist.has(`${message.guild.id}-${message.author.id}`) ) || blacklist.has(message.author.id)) { 248 | return [false, 'blacklisted']; 249 | } 250 | 251 | if (cooldown.has(message.author.id)) { 252 | return [false, 'throttled']; 253 | } else if (level < 2) { 254 | cooldown.add(message.author.id); 255 | setTimeout(() => { 256 | cooldown.delete(message.author.id); 257 | }, config.cooldown); 258 | } 259 | return [true, null]; 260 | }; 261 | 262 | const getPrefix = (message) => message.settings.prefixes.find((prefix) => message.content.startsWith(prefix)); 263 | 264 | const getSettings = (message) => { 265 | const def = config.defaultSettings; 266 | if (!message.guild) return def; 267 | const overrides = settings.get(message.guild.id) || {}; 268 | for (const key in def) { 269 | overrides[key] = overrides[key] || def[key]; 270 | } 271 | return overrides; 272 | }; 273 | 274 | async function handleMessage(message) { 275 | if (message.author.bot) return; 276 | message.settings = getSettings(message); 277 | 278 | const prefix = getPrefix(message); 279 | if (!prefix) return; 280 | 281 | if (message.guild && !message.member) await message.guild.members.fetch(message.author); 282 | const level = permLevel(message); 283 | message.author.level = level; 284 | 285 | const args = message.content.slice(prefix.length).trim().split(/ +/g); 286 | const command = args.shift().toLowerCase(); 287 | message.strings = langs.get(message.settings.lang); 288 | 289 | const [valid, status] = validateThrottle(message, level, command); 290 | if (!valid) { 291 | switch (status) { 292 | case 'blacklisted': 293 | return message.react('🚫'); 294 | case 'throttled': 295 | if (message.guild) { 296 | return message.react('⏱'); 297 | } 298 | break; 299 | } 300 | } 301 | 302 | if (tags.has(`${message.guild.id}-${command}`)) { 303 | return message.channel.send(tags.get(`${message.guild.id}-${command}`).content); 304 | } 305 | 306 | if (commands[command]) { 307 | const thisCommand = commands[command]; 308 | if (level < thisCommand.level) { 309 | return message.react('🚫'); 310 | } else { 311 | const [answer, reaction] = await thisCommand.run(message, args); 312 | if (answer) message.channel.send(answer); 313 | if (reaction) message.react(reaction); 314 | } 315 | } 316 | } 317 | 318 | client.on('ready', () => { 319 | console.log('Ready to serve'); 320 | client.user.setActivity(`?tags`); 321 | }); 322 | 323 | client.on('message', handleMessage); 324 | 325 | client.on('error', (o_O)=>{}); 326 | 327 | client.login(config.token); 328 | 329 | const permLevel = (message) => { 330 | let permlvl = 0; 331 | 332 | const permOrder = config.permLevels.slice(0).sort((prev, curr) => prev.level < curr.level ? 1 : -1); 333 | 334 | while (permOrder.length) { 335 | const currentLevel = permOrder.shift(); 336 | if (!message.guild && currentLevel.guildOnly) continue; 337 | if (currentLevel.check(message)) { 338 | permlvl = currentLevel.level; 339 | break; 340 | } 341 | } 342 | return permlvl; 343 | }; 344 | 345 | const clean = (text) => { 346 | if (typeof text !== 'string') { 347 | text = inspect(text, { depth: 0 }); 348 | } 349 | text = text 350 | .replace(/`/g, `\`${String.fromCharCode(8203)}`) 351 | .replace(/@/g, `@${String.fromCharCode(8203)}`) 352 | .replace(client.token, 'mfa.VkO_2G4Qv3T--NO--lWetW_tjND--TOKEN--QFTm6YGtzq9PH--4U--tG0'); 353 | return text; 354 | }; 355 | 356 | 357 | // These 2 process methods will catch exceptions and give *more details* about the error and stack trace. 358 | process.on('uncaughtException', (err) => { 359 | const errorMsg = err.stack.replace(new RegExp(`${__dirname}/`, 'g'), './'); 360 | console.dir(errorMsg); 361 | process.exit(1); 362 | }); 363 | 364 | process.on('unhandledRejection', console.dir); 365 | -------------------------------------------------------------------------------- /initlangs.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable func-names */ 2 | const Enmap = require('enmap'); 3 | const Provider = require('enmap-mongo'); 4 | const { promisify } = require("util"); 5 | const readdir = promisify(require("fs").readdir); 6 | 7 | const config = require('./config.js'); 8 | 9 | const langs = new Enmap({ provider: new Provider({ name: 'langs', url: config.mongodb.url }) }); 10 | 11 | 12 | (async function () { 13 | await langs.defer; 14 | const langfiles = await readdir("./lang/"); 15 | langfiles.forEach(file => { 16 | const lang = file.split(".")[0]; 17 | const langdata = require(`./lang/${file}`).strings; 18 | langs.set(lang, langdata); 19 | }); 20 | }()); 21 | -------------------------------------------------------------------------------- /lang/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "strings": { 3 | "taglist": "**`List of Available Tags:`**\n```{tags}```", 4 | "enabledms": "Please enable direct messages on this server and run this command again to get a list of tags.", 5 | "tagexists": "That tag already exists", 6 | "reservedtagname": "Cannot use reserved tag names.", 7 | "tagnotfound": "Tag name not found", 8 | "cantfinduser": "Cannot resolve mention or ID to a user.", 9 | "usernotinblacklist": "User not in blacklist.", 10 | "addedtoblacklist": "🚷 {user.tag} (`{user.id}`) added to blacklist by {author.tag} (`{author.id}`).", 11 | "removedfromblacklist": "☑ {user.tag} (`{user.id}`) removed from the blacklist by {author.tag} (`{author.id}`). Was blacklisted: {duration}", 12 | "invalidsetting": "Invalid settings key.", 13 | "settingnotarray": "This setting is an not an array.", 14 | "settingisarray": "This setting is an array. Use the `add` and `remove` actions.", 15 | "cantfindinarray": "Cannot find this value in the settings array." 16 | } 17 | } -------------------------------------------------------------------------------- /lang/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "strings": { 3 | "taglist": "**`Liste des étiquettes disponibles.`**\n```{tags}```", 4 | "enabledms": "Veuillez activer les messages privés sur ce serveur et executer cette commande à nouveau pour voir la liste des étiquettes.", 5 | "tagexists": "Cette étiquette existe déjà.", 6 | "reservedtagname": "Ce nom d'étiquette est réservé à l'interne.", 7 | "tagnotfound": "Impossible de trouver cette étiquette.", 8 | "cantfinduser": "Impossible de trouver cet utilisateur par mention ou identifiant.", 9 | "usernotinblacklist": "Cet utilisateur n'est pas dans la liste noire.", 10 | "addedtoblacklist": "🚷 L'utilisateur {user.tag} (`{user.id}`) a été ajouté à la liste noire par {author.tag} (`{author.id}`).", 11 | "removedfromblacklist": "☑ L'utilisateur {user.tag} (`{user.id}`) a été retiré de la liste noire par {author.tag} (`{author.id}`). Durée totale: {duration}", 12 | "invalidsetting": "Clé de configuration invalide.", 13 | "settingnotarray": "Cette clé de configuration n'est pas une matrice!", 14 | "settingisarray": "Cette clé de configuration est une matrice. Utiliser les actions `add` et `remove`.", 15 | "cantfindinarray": "Impossible de trouver cette valeur dans la matrice." 16 | } 17 | } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "etiket", 3 | "version": "0.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "acorn": { 8 | "version": "5.5.0", 9 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.0.tgz", 10 | "integrity": "sha512-arn53F07VXmls4o4pUhSzBa4fvaagPRe7AVZ8l7NHxFWUie2DsuFSBMMNAkgzRlOhEhzAnxeKyaWVzOH4xqp/g==", 11 | "dev": true 12 | }, 13 | "acorn-jsx": { 14 | "version": "3.0.1", 15 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", 16 | "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", 17 | "dev": true, 18 | "requires": { 19 | "acorn": "3.3.0" 20 | }, 21 | "dependencies": { 22 | "acorn": { 23 | "version": "3.3.0", 24 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", 25 | "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", 26 | "dev": true 27 | } 28 | } 29 | }, 30 | "ajv": { 31 | "version": "5.5.2", 32 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 33 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 34 | "dev": true, 35 | "requires": { 36 | "co": "4.6.0", 37 | "fast-deep-equal": "1.1.0", 38 | "fast-json-stable-stringify": "2.0.0", 39 | "json-schema-traverse": "0.3.1" 40 | } 41 | }, 42 | "ajv-keywords": { 43 | "version": "2.1.1", 44 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", 45 | "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", 46 | "dev": true 47 | }, 48 | "ansi-escapes": { 49 | "version": "3.0.0", 50 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", 51 | "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", 52 | "dev": true 53 | }, 54 | "ansi-regex": { 55 | "version": "2.1.1", 56 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 57 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 58 | "dev": true 59 | }, 60 | "ansi-styles": { 61 | "version": "2.2.1", 62 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 63 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", 64 | "dev": true 65 | }, 66 | "argparse": { 67 | "version": "1.0.10", 68 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 69 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 70 | "dev": true, 71 | "requires": { 72 | "sprintf-js": "1.0.3" 73 | } 74 | }, 75 | "array-union": { 76 | "version": "1.0.2", 77 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", 78 | "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", 79 | "dev": true, 80 | "requires": { 81 | "array-uniq": "1.0.3" 82 | } 83 | }, 84 | "array-uniq": { 85 | "version": "1.0.3", 86 | "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", 87 | "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", 88 | "dev": true 89 | }, 90 | "arrify": { 91 | "version": "1.0.1", 92 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", 93 | "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", 94 | "dev": true 95 | }, 96 | "async-limiter": { 97 | "version": "1.0.0", 98 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", 99 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" 100 | }, 101 | "babel-code-frame": { 102 | "version": "6.26.0", 103 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", 104 | "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", 105 | "dev": true, 106 | "requires": { 107 | "chalk": "1.1.3", 108 | "esutils": "2.0.2", 109 | "js-tokens": "3.0.2" 110 | }, 111 | "dependencies": { 112 | "chalk": { 113 | "version": "1.1.3", 114 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 115 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 116 | "dev": true, 117 | "requires": { 118 | "ansi-styles": "2.2.1", 119 | "escape-string-regexp": "1.0.5", 120 | "has-ansi": "2.0.0", 121 | "strip-ansi": "3.0.1", 122 | "supports-color": "2.0.0" 123 | } 124 | }, 125 | "strip-ansi": { 126 | "version": "3.0.1", 127 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 128 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 129 | "dev": true, 130 | "requires": { 131 | "ansi-regex": "2.1.1" 132 | } 133 | } 134 | } 135 | }, 136 | "balanced-match": { 137 | "version": "1.0.0", 138 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 139 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 140 | "dev": true 141 | }, 142 | "brace-expansion": { 143 | "version": "1.1.11", 144 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 145 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 146 | "dev": true, 147 | "requires": { 148 | "balanced-match": "1.0.0", 149 | "concat-map": "0.0.1" 150 | } 151 | }, 152 | "bson": { 153 | "version": "1.0.5", 154 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.5.tgz", 155 | "integrity": "sha512-D4SCtud6mlEb48kXdTHU31DRU0bsgOJ+4St1Dcx30uYNnf/aGc+hC9gHB/z0Eth8HYYs/hr0SFdyZViht19SwA==" 156 | }, 157 | "builtin-modules": { 158 | "version": "1.1.1", 159 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 160 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", 161 | "dev": true 162 | }, 163 | "caller-path": { 164 | "version": "0.1.0", 165 | "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", 166 | "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", 167 | "dev": true, 168 | "requires": { 169 | "callsites": "0.2.0" 170 | } 171 | }, 172 | "callsites": { 173 | "version": "0.2.0", 174 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", 175 | "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", 176 | "dev": true 177 | }, 178 | "chalk": { 179 | "version": "2.3.2", 180 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", 181 | "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", 182 | "dev": true, 183 | "requires": { 184 | "ansi-styles": "3.2.1", 185 | "escape-string-regexp": "1.0.5", 186 | "supports-color": "5.3.0" 187 | }, 188 | "dependencies": { 189 | "ansi-styles": { 190 | "version": "3.2.1", 191 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 192 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 193 | "dev": true, 194 | "requires": { 195 | "color-convert": "1.9.1" 196 | } 197 | }, 198 | "supports-color": { 199 | "version": "5.3.0", 200 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", 201 | "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", 202 | "dev": true, 203 | "requires": { 204 | "has-flag": "3.0.0" 205 | } 206 | } 207 | } 208 | }, 209 | "chardet": { 210 | "version": "0.4.2", 211 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", 212 | "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", 213 | "dev": true 214 | }, 215 | "circular-json": { 216 | "version": "0.3.3", 217 | "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", 218 | "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", 219 | "dev": true 220 | }, 221 | "cli-cursor": { 222 | "version": "2.1.0", 223 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 224 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 225 | "dev": true, 226 | "requires": { 227 | "restore-cursor": "2.0.0" 228 | } 229 | }, 230 | "cli-width": { 231 | "version": "2.2.0", 232 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 233 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", 234 | "dev": true 235 | }, 236 | "co": { 237 | "version": "4.6.0", 238 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 239 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", 240 | "dev": true 241 | }, 242 | "color-convert": { 243 | "version": "1.9.1", 244 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", 245 | "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", 246 | "dev": true, 247 | "requires": { 248 | "color-name": "1.1.3" 249 | } 250 | }, 251 | "color-name": { 252 | "version": "1.1.3", 253 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 254 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 255 | "dev": true 256 | }, 257 | "concat-map": { 258 | "version": "0.0.1", 259 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 260 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 261 | "dev": true 262 | }, 263 | "concat-stream": { 264 | "version": "1.6.1", 265 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.1.tgz", 266 | "integrity": "sha512-gslSSJx03QKa59cIKqeJO9HQ/WZMotvYJCuaUULrLpjj8oG40kV2Z+gz82pVxlTkOADi4PJxQPPfhl1ELYrrXw==", 267 | "dev": true, 268 | "requires": { 269 | "inherits": "2.0.3", 270 | "readable-stream": "2.3.5", 271 | "typedarray": "0.0.6" 272 | } 273 | }, 274 | "contains-path": { 275 | "version": "0.1.0", 276 | "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", 277 | "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", 278 | "dev": true 279 | }, 280 | "core-util-is": { 281 | "version": "1.0.2", 282 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 283 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 284 | "dev": true 285 | }, 286 | "cross-spawn": { 287 | "version": "5.1.0", 288 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 289 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", 290 | "dev": true, 291 | "requires": { 292 | "lru-cache": "4.1.1", 293 | "shebang-command": "1.2.0", 294 | "which": "1.3.0" 295 | } 296 | }, 297 | "debug": { 298 | "version": "3.1.0", 299 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 300 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 301 | "dev": true, 302 | "requires": { 303 | "ms": "2.0.0" 304 | } 305 | }, 306 | "deep-is": { 307 | "version": "0.1.3", 308 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 309 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 310 | "dev": true 311 | }, 312 | "del": { 313 | "version": "2.2.2", 314 | "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", 315 | "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", 316 | "dev": true, 317 | "requires": { 318 | "globby": "5.0.0", 319 | "is-path-cwd": "1.0.0", 320 | "is-path-in-cwd": "1.0.0", 321 | "object-assign": "4.1.1", 322 | "pify": "2.3.0", 323 | "pinkie-promise": "2.0.1", 324 | "rimraf": "2.6.2" 325 | } 326 | }, 327 | "discord.js": { 328 | "version": "github:discordjs/discord.js#2dd7fd2739fb5c68832b7eafeab5a9daa2f5b331", 329 | "requires": { 330 | "pako": "1.0.6", 331 | "prism-media": "0.2.1", 332 | "snekfetch": "3.6.4", 333 | "tweetnacl": "1.0.0", 334 | "ws": "4.1.0" 335 | }, 336 | "dependencies": { 337 | "prism-media": { 338 | "version": "0.2.1", 339 | "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-0.2.1.tgz", 340 | "integrity": "sha512-Kfp1+6gzjY6X8mqKHa6D3brX+BtMUPFwzAkz4zgtVPgbkA2XxhITROdfQXVurU4fuJsylFRwqo7ciQlQCm9hAw==" 341 | } 342 | } 343 | }, 344 | "doctrine": { 345 | "version": "2.1.0", 346 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", 347 | "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", 348 | "dev": true, 349 | "requires": { 350 | "esutils": "2.0.2" 351 | } 352 | }, 353 | "enmap": { 354 | "version": "0.5.0", 355 | "resolved": "https://registry.npmjs.org/enmap/-/enmap-0.5.0.tgz", 356 | "integrity": "sha512-/RqUSYlw/61XCIeNKjjuRhtSTYx3MVhztwqgNOJ6IFsNnbUTKZSAGtpBOJwOe0wLMsELtzQliCj/Y2XdxEYd0w==" 357 | }, 358 | "enmap-mongo": { 359 | "version": "1.0.3", 360 | "resolved": "https://registry.npmjs.org/enmap-mongo/-/enmap-mongo-1.0.3.tgz", 361 | "integrity": "sha512-BNjmhgldL/Lzz8vOGvybnk+f3pP5MxJH7yS7Nb9fffXwjpzcdSD2bchHKBFafIr2bOBCIfw4zESA/ztQnKzfxQ==", 362 | "requires": { 363 | "mongodb": "3.0.3" 364 | } 365 | }, 366 | "error-ex": { 367 | "version": "1.3.1", 368 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", 369 | "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", 370 | "dev": true, 371 | "requires": { 372 | "is-arrayish": "0.2.1" 373 | } 374 | }, 375 | "escape-string-regexp": { 376 | "version": "1.0.5", 377 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 378 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 379 | "dev": true 380 | }, 381 | "eslint": { 382 | "version": "4.18.2", 383 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.2.tgz", 384 | "integrity": "sha512-qy4i3wODqKMYfz9LUI8N2qYDkHkoieTbiHpMrYUI/WbjhXJQr7lI4VngixTgaG+yHX+NBCv7nW4hA0ShbvaNKw==", 385 | "dev": true, 386 | "requires": { 387 | "ajv": "5.5.2", 388 | "babel-code-frame": "6.26.0", 389 | "chalk": "2.3.2", 390 | "concat-stream": "1.6.1", 391 | "cross-spawn": "5.1.0", 392 | "debug": "3.1.0", 393 | "doctrine": "2.1.0", 394 | "eslint-scope": "3.7.1", 395 | "eslint-visitor-keys": "1.0.0", 396 | "espree": "3.5.3", 397 | "esquery": "1.0.0", 398 | "esutils": "2.0.2", 399 | "file-entry-cache": "2.0.0", 400 | "functional-red-black-tree": "1.0.1", 401 | "glob": "7.1.2", 402 | "globals": "11.3.0", 403 | "ignore": "3.3.7", 404 | "imurmurhash": "0.1.4", 405 | "inquirer": "3.3.0", 406 | "is-resolvable": "1.1.0", 407 | "js-yaml": "3.10.0", 408 | "json-stable-stringify-without-jsonify": "1.0.1", 409 | "levn": "0.3.0", 410 | "lodash": "4.17.5", 411 | "minimatch": "3.0.4", 412 | "mkdirp": "0.5.1", 413 | "natural-compare": "1.4.0", 414 | "optionator": "0.8.2", 415 | "path-is-inside": "1.0.2", 416 | "pluralize": "7.0.0", 417 | "progress": "2.0.0", 418 | "require-uncached": "1.0.3", 419 | "semver": "5.5.0", 420 | "strip-ansi": "4.0.0", 421 | "strip-json-comments": "2.0.1", 422 | "table": "4.0.2", 423 | "text-table": "0.2.0" 424 | } 425 | }, 426 | "eslint-config-standard": { 427 | "version": "10.2.1", 428 | "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", 429 | "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", 430 | "dev": true 431 | }, 432 | "eslint-import-resolver-node": { 433 | "version": "0.3.2", 434 | "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", 435 | "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", 436 | "dev": true, 437 | "requires": { 438 | "debug": "2.6.9", 439 | "resolve": "1.5.0" 440 | }, 441 | "dependencies": { 442 | "debug": { 443 | "version": "2.6.9", 444 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 445 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 446 | "dev": true, 447 | "requires": { 448 | "ms": "2.0.0" 449 | } 450 | } 451 | } 452 | }, 453 | "eslint-module-utils": { 454 | "version": "2.1.1", 455 | "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", 456 | "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", 457 | "dev": true, 458 | "requires": { 459 | "debug": "2.6.9", 460 | "pkg-dir": "1.0.0" 461 | }, 462 | "dependencies": { 463 | "debug": { 464 | "version": "2.6.9", 465 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 466 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 467 | "dev": true, 468 | "requires": { 469 | "ms": "2.0.0" 470 | } 471 | } 472 | } 473 | }, 474 | "eslint-plugin-import": { 475 | "version": "2.9.0", 476 | "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.9.0.tgz", 477 | "integrity": "sha1-JgAu+/ylmJtyiKwEdQi9JPIXsWk=", 478 | "dev": true, 479 | "requires": { 480 | "builtin-modules": "1.1.1", 481 | "contains-path": "0.1.0", 482 | "debug": "2.6.9", 483 | "doctrine": "1.5.0", 484 | "eslint-import-resolver-node": "0.3.2", 485 | "eslint-module-utils": "2.1.1", 486 | "has": "1.0.1", 487 | "lodash": "4.17.5", 488 | "minimatch": "3.0.4", 489 | "read-pkg-up": "2.0.0" 490 | }, 491 | "dependencies": { 492 | "debug": { 493 | "version": "2.6.9", 494 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 495 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 496 | "dev": true, 497 | "requires": { 498 | "ms": "2.0.0" 499 | } 500 | }, 501 | "doctrine": { 502 | "version": "1.5.0", 503 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", 504 | "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", 505 | "dev": true, 506 | "requires": { 507 | "esutils": "2.0.2", 508 | "isarray": "1.0.0" 509 | } 510 | } 511 | } 512 | }, 513 | "eslint-plugin-node": { 514 | "version": "5.2.1", 515 | "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz", 516 | "integrity": "sha512-xhPXrh0Vl/b7870uEbaumb2Q+LxaEcOQ3kS1jtIXanBAwpMre1l5q/l2l/hESYJGEFKuI78bp6Uw50hlpr7B+g==", 517 | "dev": true, 518 | "requires": { 519 | "ignore": "3.3.7", 520 | "minimatch": "3.0.4", 521 | "resolve": "1.5.0", 522 | "semver": "5.3.0" 523 | }, 524 | "dependencies": { 525 | "semver": { 526 | "version": "5.3.0", 527 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", 528 | "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", 529 | "dev": true 530 | } 531 | } 532 | }, 533 | "eslint-plugin-promise": { 534 | "version": "3.6.0", 535 | "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.6.0.tgz", 536 | "integrity": "sha512-YQzM6TLTlApAr7Li8vWKR+K3WghjwKcYzY0d2roWap4SLK+kzuagJX/leTetIDWsFcTFnKNJXWupDCD6aZkP2Q==", 537 | "dev": true 538 | }, 539 | "eslint-plugin-standard": { 540 | "version": "3.0.1", 541 | "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", 542 | "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=", 543 | "dev": true 544 | }, 545 | "eslint-scope": { 546 | "version": "3.7.1", 547 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", 548 | "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", 549 | "dev": true, 550 | "requires": { 551 | "esrecurse": "4.2.1", 552 | "estraverse": "4.2.0" 553 | } 554 | }, 555 | "eslint-visitor-keys": { 556 | "version": "1.0.0", 557 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", 558 | "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", 559 | "dev": true 560 | }, 561 | "espree": { 562 | "version": "3.5.3", 563 | "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.3.tgz", 564 | "integrity": "sha512-Zy3tAJDORxQZLl2baguiRU1syPERAIg0L+JB2MWorORgTu/CplzvxS9WWA7Xh4+Q+eOQihNs/1o1Xep8cvCxWQ==", 565 | "dev": true, 566 | "requires": { 567 | "acorn": "5.5.0", 568 | "acorn-jsx": "3.0.1" 569 | } 570 | }, 571 | "esprima": { 572 | "version": "4.0.0", 573 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", 574 | "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", 575 | "dev": true 576 | }, 577 | "esquery": { 578 | "version": "1.0.0", 579 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", 580 | "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", 581 | "dev": true, 582 | "requires": { 583 | "estraverse": "4.2.0" 584 | } 585 | }, 586 | "esrecurse": { 587 | "version": "4.2.1", 588 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 589 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 590 | "dev": true, 591 | "requires": { 592 | "estraverse": "4.2.0" 593 | } 594 | }, 595 | "estraverse": { 596 | "version": "4.2.0", 597 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", 598 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", 599 | "dev": true 600 | }, 601 | "esutils": { 602 | "version": "2.0.2", 603 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 604 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 605 | "dev": true 606 | }, 607 | "external-editor": { 608 | "version": "2.1.0", 609 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", 610 | "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", 611 | "dev": true, 612 | "requires": { 613 | "chardet": "0.4.2", 614 | "iconv-lite": "0.4.19", 615 | "tmp": "0.0.33" 616 | } 617 | }, 618 | "fast-deep-equal": { 619 | "version": "1.1.0", 620 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 621 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", 622 | "dev": true 623 | }, 624 | "fast-json-stable-stringify": { 625 | "version": "2.0.0", 626 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 627 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", 628 | "dev": true 629 | }, 630 | "fast-levenshtein": { 631 | "version": "2.0.6", 632 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 633 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 634 | "dev": true 635 | }, 636 | "figures": { 637 | "version": "2.0.0", 638 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 639 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 640 | "dev": true, 641 | "requires": { 642 | "escape-string-regexp": "1.0.5" 643 | } 644 | }, 645 | "file-entry-cache": { 646 | "version": "2.0.0", 647 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", 648 | "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", 649 | "dev": true, 650 | "requires": { 651 | "flat-cache": "1.3.0", 652 | "object-assign": "4.1.1" 653 | } 654 | }, 655 | "find-up": { 656 | "version": "1.1.2", 657 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", 658 | "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", 659 | "dev": true, 660 | "requires": { 661 | "path-exists": "2.1.0", 662 | "pinkie-promise": "2.0.1" 663 | } 664 | }, 665 | "flat-cache": { 666 | "version": "1.3.0", 667 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", 668 | "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", 669 | "dev": true, 670 | "requires": { 671 | "circular-json": "0.3.3", 672 | "del": "2.2.2", 673 | "graceful-fs": "4.1.11", 674 | "write": "0.2.1" 675 | } 676 | }, 677 | "fs.realpath": { 678 | "version": "1.0.0", 679 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 680 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 681 | "dev": true 682 | }, 683 | "function-bind": { 684 | "version": "1.1.1", 685 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 686 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 687 | "dev": true 688 | }, 689 | "functional-red-black-tree": { 690 | "version": "1.0.1", 691 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 692 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 693 | "dev": true 694 | }, 695 | "glob": { 696 | "version": "7.1.2", 697 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 698 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 699 | "dev": true, 700 | "requires": { 701 | "fs.realpath": "1.0.0", 702 | "inflight": "1.0.6", 703 | "inherits": "2.0.3", 704 | "minimatch": "3.0.4", 705 | "once": "1.4.0", 706 | "path-is-absolute": "1.0.1" 707 | } 708 | }, 709 | "globals": { 710 | "version": "11.3.0", 711 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.3.0.tgz", 712 | "integrity": "sha512-kkpcKNlmQan9Z5ZmgqKH/SMbSmjxQ7QjyNqfXVc8VJcoBV2UEg+sxQD15GQofGRh2hfpwUb70VC31DR7Rq5Hdw==", 713 | "dev": true 714 | }, 715 | "globby": { 716 | "version": "5.0.0", 717 | "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", 718 | "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", 719 | "dev": true, 720 | "requires": { 721 | "array-union": "1.0.2", 722 | "arrify": "1.0.1", 723 | "glob": "7.1.2", 724 | "object-assign": "4.1.1", 725 | "pify": "2.3.0", 726 | "pinkie-promise": "2.0.1" 727 | } 728 | }, 729 | "graceful-fs": { 730 | "version": "4.1.11", 731 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 732 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", 733 | "dev": true 734 | }, 735 | "has": { 736 | "version": "1.0.1", 737 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", 738 | "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", 739 | "dev": true, 740 | "requires": { 741 | "function-bind": "1.1.1" 742 | } 743 | }, 744 | "has-ansi": { 745 | "version": "2.0.0", 746 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 747 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 748 | "dev": true, 749 | "requires": { 750 | "ansi-regex": "2.1.1" 751 | } 752 | }, 753 | "has-flag": { 754 | "version": "3.0.0", 755 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 756 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 757 | "dev": true 758 | }, 759 | "hosted-git-info": { 760 | "version": "2.5.0", 761 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", 762 | "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", 763 | "dev": true 764 | }, 765 | "iconv-lite": { 766 | "version": "0.4.19", 767 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 768 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", 769 | "dev": true 770 | }, 771 | "ignore": { 772 | "version": "3.3.7", 773 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", 774 | "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", 775 | "dev": true 776 | }, 777 | "imurmurhash": { 778 | "version": "0.1.4", 779 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 780 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 781 | "dev": true 782 | }, 783 | "inflight": { 784 | "version": "1.0.6", 785 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 786 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 787 | "dev": true, 788 | "requires": { 789 | "once": "1.4.0", 790 | "wrappy": "1.0.2" 791 | } 792 | }, 793 | "inherits": { 794 | "version": "2.0.3", 795 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 796 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 797 | "dev": true 798 | }, 799 | "inquirer": { 800 | "version": "3.3.0", 801 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", 802 | "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", 803 | "dev": true, 804 | "requires": { 805 | "ansi-escapes": "3.0.0", 806 | "chalk": "2.3.2", 807 | "cli-cursor": "2.1.0", 808 | "cli-width": "2.2.0", 809 | "external-editor": "2.1.0", 810 | "figures": "2.0.0", 811 | "lodash": "4.17.5", 812 | "mute-stream": "0.0.7", 813 | "run-async": "2.3.0", 814 | "rx-lite": "4.0.8", 815 | "rx-lite-aggregates": "4.0.8", 816 | "string-width": "2.1.1", 817 | "strip-ansi": "4.0.0", 818 | "through": "2.3.8" 819 | } 820 | }, 821 | "is-arrayish": { 822 | "version": "0.2.1", 823 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 824 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", 825 | "dev": true 826 | }, 827 | "is-builtin-module": { 828 | "version": "1.0.0", 829 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 830 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", 831 | "dev": true, 832 | "requires": { 833 | "builtin-modules": "1.1.1" 834 | } 835 | }, 836 | "is-fullwidth-code-point": { 837 | "version": "2.0.0", 838 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 839 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 840 | "dev": true 841 | }, 842 | "is-path-cwd": { 843 | "version": "1.0.0", 844 | "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", 845 | "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", 846 | "dev": true 847 | }, 848 | "is-path-in-cwd": { 849 | "version": "1.0.0", 850 | "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", 851 | "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", 852 | "dev": true, 853 | "requires": { 854 | "is-path-inside": "1.0.1" 855 | } 856 | }, 857 | "is-path-inside": { 858 | "version": "1.0.1", 859 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", 860 | "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", 861 | "dev": true, 862 | "requires": { 863 | "path-is-inside": "1.0.2" 864 | } 865 | }, 866 | "is-promise": { 867 | "version": "2.1.0", 868 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 869 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", 870 | "dev": true 871 | }, 872 | "is-resolvable": { 873 | "version": "1.1.0", 874 | "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", 875 | "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", 876 | "dev": true 877 | }, 878 | "isarray": { 879 | "version": "1.0.0", 880 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 881 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 882 | "dev": true 883 | }, 884 | "isexe": { 885 | "version": "2.0.0", 886 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 887 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 888 | "dev": true 889 | }, 890 | "js-tokens": { 891 | "version": "3.0.2", 892 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 893 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", 894 | "dev": true 895 | }, 896 | "js-yaml": { 897 | "version": "3.10.0", 898 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", 899 | "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", 900 | "dev": true, 901 | "requires": { 902 | "argparse": "1.0.10", 903 | "esprima": "4.0.0" 904 | } 905 | }, 906 | "json-schema-traverse": { 907 | "version": "0.3.1", 908 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 909 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", 910 | "dev": true 911 | }, 912 | "json-stable-stringify-without-jsonify": { 913 | "version": "1.0.1", 914 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 915 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 916 | "dev": true 917 | }, 918 | "levn": { 919 | "version": "0.3.0", 920 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 921 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 922 | "dev": true, 923 | "requires": { 924 | "prelude-ls": "1.1.2", 925 | "type-check": "0.3.2" 926 | } 927 | }, 928 | "load-json-file": { 929 | "version": "2.0.0", 930 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", 931 | "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", 932 | "dev": true, 933 | "requires": { 934 | "graceful-fs": "4.1.11", 935 | "parse-json": "2.2.0", 936 | "pify": "2.3.0", 937 | "strip-bom": "3.0.0" 938 | } 939 | }, 940 | "locate-path": { 941 | "version": "2.0.0", 942 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", 943 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", 944 | "dev": true, 945 | "requires": { 946 | "p-locate": "2.0.0", 947 | "path-exists": "3.0.0" 948 | }, 949 | "dependencies": { 950 | "path-exists": { 951 | "version": "3.0.0", 952 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 953 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 954 | "dev": true 955 | } 956 | } 957 | }, 958 | "lodash": { 959 | "version": "4.17.5", 960 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", 961 | "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", 962 | "dev": true 963 | }, 964 | "lru-cache": { 965 | "version": "4.1.1", 966 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", 967 | "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", 968 | "dev": true, 969 | "requires": { 970 | "pseudomap": "1.0.2", 971 | "yallist": "2.1.2" 972 | } 973 | }, 974 | "mimic-fn": { 975 | "version": "1.2.0", 976 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 977 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", 978 | "dev": true 979 | }, 980 | "minimatch": { 981 | "version": "3.0.4", 982 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 983 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 984 | "dev": true, 985 | "requires": { 986 | "brace-expansion": "1.1.11" 987 | } 988 | }, 989 | "minimist": { 990 | "version": "0.0.8", 991 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 992 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 993 | "dev": true 994 | }, 995 | "mkdirp": { 996 | "version": "0.5.1", 997 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 998 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 999 | "dev": true, 1000 | "requires": { 1001 | "minimist": "0.0.8" 1002 | } 1003 | }, 1004 | "moment": { 1005 | "version": "2.21.0", 1006 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.21.0.tgz", 1007 | "integrity": "sha512-TCZ36BjURTeFTM/CwRcViQlfkMvL1/vFISuNLO5GkcVm1+QHfbSiNqZuWeMFjj1/3+uAjXswgRk30j1kkLYJBQ==" 1008 | }, 1009 | "moment-duration-format": { 1010 | "version": "1.3.0", 1011 | "resolved": "https://registry.npmjs.org/moment-duration-format/-/moment-duration-format-1.3.0.tgz", 1012 | "integrity": "sha1-VBdxtfh6BJzGVUBHXTrZZnN9aQg=" 1013 | }, 1014 | "mongodb": { 1015 | "version": "3.0.3", 1016 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.0.3.tgz", 1017 | "integrity": "sha512-BuYbPwjrIS/Ik/AUegjnYb8ncOa4dj8tzP4eSCsaqjP9yjmIWzzKrAXBY+s8xy6xkTJxgvbuTFub6cIwpmHRXQ==", 1018 | "requires": { 1019 | "mongodb-core": "3.0.3" 1020 | } 1021 | }, 1022 | "mongodb-core": { 1023 | "version": "3.0.3", 1024 | "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.0.3.tgz", 1025 | "integrity": "sha512-AkEiYeq4PZrgoKPZ32q2nL2xFe9iswOgefMipS2YHJHX8DCFAXmYr1aFxefAWisinxI/nd57nBMSe4mrm3yV1g==", 1026 | "requires": { 1027 | "bson": "1.0.5", 1028 | "require_optional": "1.0.1" 1029 | } 1030 | }, 1031 | "ms": { 1032 | "version": "2.0.0", 1033 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1034 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 1035 | "dev": true 1036 | }, 1037 | "mute-stream": { 1038 | "version": "0.0.7", 1039 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 1040 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", 1041 | "dev": true 1042 | }, 1043 | "natural-compare": { 1044 | "version": "1.4.0", 1045 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1046 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 1047 | "dev": true 1048 | }, 1049 | "normalize-package-data": { 1050 | "version": "2.4.0", 1051 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", 1052 | "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", 1053 | "dev": true, 1054 | "requires": { 1055 | "hosted-git-info": "2.5.0", 1056 | "is-builtin-module": "1.0.0", 1057 | "semver": "5.5.0", 1058 | "validate-npm-package-license": "3.0.3" 1059 | } 1060 | }, 1061 | "object-assign": { 1062 | "version": "4.1.1", 1063 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1064 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 1065 | "dev": true 1066 | }, 1067 | "once": { 1068 | "version": "1.4.0", 1069 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1070 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1071 | "dev": true, 1072 | "requires": { 1073 | "wrappy": "1.0.2" 1074 | } 1075 | }, 1076 | "onetime": { 1077 | "version": "2.0.1", 1078 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 1079 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 1080 | "dev": true, 1081 | "requires": { 1082 | "mimic-fn": "1.2.0" 1083 | } 1084 | }, 1085 | "optionator": { 1086 | "version": "0.8.2", 1087 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 1088 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 1089 | "dev": true, 1090 | "requires": { 1091 | "deep-is": "0.1.3", 1092 | "fast-levenshtein": "2.0.6", 1093 | "levn": "0.3.0", 1094 | "prelude-ls": "1.1.2", 1095 | "type-check": "0.3.2", 1096 | "wordwrap": "1.0.0" 1097 | } 1098 | }, 1099 | "os-tmpdir": { 1100 | "version": "1.0.2", 1101 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1102 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 1103 | "dev": true 1104 | }, 1105 | "p-limit": { 1106 | "version": "1.2.0", 1107 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", 1108 | "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", 1109 | "dev": true, 1110 | "requires": { 1111 | "p-try": "1.0.0" 1112 | } 1113 | }, 1114 | "p-locate": { 1115 | "version": "2.0.0", 1116 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", 1117 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", 1118 | "dev": true, 1119 | "requires": { 1120 | "p-limit": "1.2.0" 1121 | } 1122 | }, 1123 | "p-try": { 1124 | "version": "1.0.0", 1125 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", 1126 | "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", 1127 | "dev": true 1128 | }, 1129 | "pako": { 1130 | "version": "1.0.6", 1131 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", 1132 | "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==" 1133 | }, 1134 | "parse-json": { 1135 | "version": "2.2.0", 1136 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", 1137 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", 1138 | "dev": true, 1139 | "requires": { 1140 | "error-ex": "1.3.1" 1141 | } 1142 | }, 1143 | "path-exists": { 1144 | "version": "2.1.0", 1145 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", 1146 | "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", 1147 | "dev": true, 1148 | "requires": { 1149 | "pinkie-promise": "2.0.1" 1150 | } 1151 | }, 1152 | "path-is-absolute": { 1153 | "version": "1.0.1", 1154 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1155 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1156 | "dev": true 1157 | }, 1158 | "path-is-inside": { 1159 | "version": "1.0.2", 1160 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 1161 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", 1162 | "dev": true 1163 | }, 1164 | "path-parse": { 1165 | "version": "1.0.5", 1166 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", 1167 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", 1168 | "dev": true 1169 | }, 1170 | "path-type": { 1171 | "version": "2.0.0", 1172 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", 1173 | "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", 1174 | "dev": true, 1175 | "requires": { 1176 | "pify": "2.3.0" 1177 | } 1178 | }, 1179 | "pify": { 1180 | "version": "2.3.0", 1181 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1182 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", 1183 | "dev": true 1184 | }, 1185 | "pinkie": { 1186 | "version": "2.0.4", 1187 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1188 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", 1189 | "dev": true 1190 | }, 1191 | "pinkie-promise": { 1192 | "version": "2.0.1", 1193 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1194 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 1195 | "dev": true, 1196 | "requires": { 1197 | "pinkie": "2.0.4" 1198 | } 1199 | }, 1200 | "pkg-dir": { 1201 | "version": "1.0.0", 1202 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", 1203 | "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", 1204 | "dev": true, 1205 | "requires": { 1206 | "find-up": "1.1.2" 1207 | } 1208 | }, 1209 | "pluralize": { 1210 | "version": "7.0.0", 1211 | "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", 1212 | "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", 1213 | "dev": true 1214 | }, 1215 | "prelude-ls": { 1216 | "version": "1.1.2", 1217 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1218 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 1219 | "dev": true 1220 | }, 1221 | "process-nextick-args": { 1222 | "version": "2.0.0", 1223 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 1224 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", 1225 | "dev": true 1226 | }, 1227 | "progress": { 1228 | "version": "2.0.0", 1229 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", 1230 | "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", 1231 | "dev": true 1232 | }, 1233 | "pseudomap": { 1234 | "version": "1.0.2", 1235 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 1236 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", 1237 | "dev": true 1238 | }, 1239 | "read-pkg": { 1240 | "version": "2.0.0", 1241 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", 1242 | "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", 1243 | "dev": true, 1244 | "requires": { 1245 | "load-json-file": "2.0.0", 1246 | "normalize-package-data": "2.4.0", 1247 | "path-type": "2.0.0" 1248 | } 1249 | }, 1250 | "read-pkg-up": { 1251 | "version": "2.0.0", 1252 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", 1253 | "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", 1254 | "dev": true, 1255 | "requires": { 1256 | "find-up": "2.1.0", 1257 | "read-pkg": "2.0.0" 1258 | }, 1259 | "dependencies": { 1260 | "find-up": { 1261 | "version": "2.1.0", 1262 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", 1263 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", 1264 | "dev": true, 1265 | "requires": { 1266 | "locate-path": "2.0.0" 1267 | } 1268 | } 1269 | } 1270 | }, 1271 | "readable-stream": { 1272 | "version": "2.3.5", 1273 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", 1274 | "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", 1275 | "dev": true, 1276 | "requires": { 1277 | "core-util-is": "1.0.2", 1278 | "inherits": "2.0.3", 1279 | "isarray": "1.0.0", 1280 | "process-nextick-args": "2.0.0", 1281 | "safe-buffer": "5.1.1", 1282 | "string_decoder": "1.0.3", 1283 | "util-deprecate": "1.0.2" 1284 | } 1285 | }, 1286 | "require-uncached": { 1287 | "version": "1.0.3", 1288 | "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", 1289 | "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", 1290 | "dev": true, 1291 | "requires": { 1292 | "caller-path": "0.1.0", 1293 | "resolve-from": "1.0.1" 1294 | }, 1295 | "dependencies": { 1296 | "resolve-from": { 1297 | "version": "1.0.1", 1298 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", 1299 | "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", 1300 | "dev": true 1301 | } 1302 | } 1303 | }, 1304 | "require_optional": { 1305 | "version": "1.0.1", 1306 | "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", 1307 | "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", 1308 | "requires": { 1309 | "resolve-from": "2.0.0", 1310 | "semver": "5.5.0" 1311 | } 1312 | }, 1313 | "resolve": { 1314 | "version": "1.5.0", 1315 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", 1316 | "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", 1317 | "dev": true, 1318 | "requires": { 1319 | "path-parse": "1.0.5" 1320 | } 1321 | }, 1322 | "resolve-from": { 1323 | "version": "2.0.0", 1324 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", 1325 | "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" 1326 | }, 1327 | "restore-cursor": { 1328 | "version": "2.0.0", 1329 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 1330 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 1331 | "dev": true, 1332 | "requires": { 1333 | "onetime": "2.0.1", 1334 | "signal-exit": "3.0.2" 1335 | } 1336 | }, 1337 | "rimraf": { 1338 | "version": "2.6.2", 1339 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", 1340 | "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 1341 | "dev": true, 1342 | "requires": { 1343 | "glob": "7.1.2" 1344 | } 1345 | }, 1346 | "run-async": { 1347 | "version": "2.3.0", 1348 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 1349 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 1350 | "dev": true, 1351 | "requires": { 1352 | "is-promise": "2.1.0" 1353 | } 1354 | }, 1355 | "rx-lite": { 1356 | "version": "4.0.8", 1357 | "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", 1358 | "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", 1359 | "dev": true 1360 | }, 1361 | "rx-lite-aggregates": { 1362 | "version": "4.0.8", 1363 | "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", 1364 | "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", 1365 | "dev": true, 1366 | "requires": { 1367 | "rx-lite": "4.0.8" 1368 | } 1369 | }, 1370 | "safe-buffer": { 1371 | "version": "5.1.1", 1372 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 1373 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" 1374 | }, 1375 | "semver": { 1376 | "version": "5.5.0", 1377 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", 1378 | "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" 1379 | }, 1380 | "shebang-command": { 1381 | "version": "1.2.0", 1382 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 1383 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 1384 | "dev": true, 1385 | "requires": { 1386 | "shebang-regex": "1.0.0" 1387 | } 1388 | }, 1389 | "shebang-regex": { 1390 | "version": "1.0.0", 1391 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 1392 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 1393 | "dev": true 1394 | }, 1395 | "signal-exit": { 1396 | "version": "3.0.2", 1397 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 1398 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 1399 | "dev": true 1400 | }, 1401 | "slice-ansi": { 1402 | "version": "1.0.0", 1403 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", 1404 | "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", 1405 | "dev": true, 1406 | "requires": { 1407 | "is-fullwidth-code-point": "2.0.0" 1408 | } 1409 | }, 1410 | "snekfetch": { 1411 | "version": "3.6.4", 1412 | "resolved": "https://registry.npmjs.org/snekfetch/-/snekfetch-3.6.4.tgz", 1413 | "integrity": "sha512-NjxjITIj04Ffqid5lqr7XdgwM7X61c/Dns073Ly170bPQHLm6jkmelye/eglS++1nfTWktpP6Y2bFXjdPlQqdw==" 1414 | }, 1415 | "spdx-correct": { 1416 | "version": "3.0.0", 1417 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", 1418 | "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", 1419 | "dev": true, 1420 | "requires": { 1421 | "spdx-expression-parse": "3.0.0", 1422 | "spdx-license-ids": "3.0.0" 1423 | } 1424 | }, 1425 | "spdx-exceptions": { 1426 | "version": "2.1.0", 1427 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", 1428 | "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", 1429 | "dev": true 1430 | }, 1431 | "spdx-expression-parse": { 1432 | "version": "3.0.0", 1433 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", 1434 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", 1435 | "dev": true, 1436 | "requires": { 1437 | "spdx-exceptions": "2.1.0", 1438 | "spdx-license-ids": "3.0.0" 1439 | } 1440 | }, 1441 | "spdx-license-ids": { 1442 | "version": "3.0.0", 1443 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", 1444 | "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", 1445 | "dev": true 1446 | }, 1447 | "sprintf-js": { 1448 | "version": "1.0.3", 1449 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1450 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 1451 | "dev": true 1452 | }, 1453 | "string-width": { 1454 | "version": "2.1.1", 1455 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 1456 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 1457 | "dev": true, 1458 | "requires": { 1459 | "is-fullwidth-code-point": "2.0.0", 1460 | "strip-ansi": "4.0.0" 1461 | } 1462 | }, 1463 | "string_decoder": { 1464 | "version": "1.0.3", 1465 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 1466 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", 1467 | "dev": true, 1468 | "requires": { 1469 | "safe-buffer": "5.1.1" 1470 | } 1471 | }, 1472 | "strip-ansi": { 1473 | "version": "4.0.0", 1474 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1475 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 1476 | "dev": true, 1477 | "requires": { 1478 | "ansi-regex": "3.0.0" 1479 | }, 1480 | "dependencies": { 1481 | "ansi-regex": { 1482 | "version": "3.0.0", 1483 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 1484 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 1485 | "dev": true 1486 | } 1487 | } 1488 | }, 1489 | "strip-bom": { 1490 | "version": "3.0.0", 1491 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 1492 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", 1493 | "dev": true 1494 | }, 1495 | "strip-json-comments": { 1496 | "version": "2.0.1", 1497 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1498 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 1499 | "dev": true 1500 | }, 1501 | "supports-color": { 1502 | "version": "2.0.0", 1503 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 1504 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", 1505 | "dev": true 1506 | }, 1507 | "table": { 1508 | "version": "4.0.2", 1509 | "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", 1510 | "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", 1511 | "dev": true, 1512 | "requires": { 1513 | "ajv": "5.5.2", 1514 | "ajv-keywords": "2.1.1", 1515 | "chalk": "2.3.2", 1516 | "lodash": "4.17.5", 1517 | "slice-ansi": "1.0.0", 1518 | "string-width": "2.1.1" 1519 | } 1520 | }, 1521 | "text-table": { 1522 | "version": "0.2.0", 1523 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1524 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 1525 | "dev": true 1526 | }, 1527 | "through": { 1528 | "version": "2.3.8", 1529 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1530 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 1531 | "dev": true 1532 | }, 1533 | "tmp": { 1534 | "version": "0.0.33", 1535 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 1536 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 1537 | "dev": true, 1538 | "requires": { 1539 | "os-tmpdir": "1.0.2" 1540 | } 1541 | }, 1542 | "tweetnacl": { 1543 | "version": "1.0.0", 1544 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.0.tgz", 1545 | "integrity": "sha1-cT2LgY2kIGh0C/aDhtBHnmb8ins=" 1546 | }, 1547 | "type-check": { 1548 | "version": "0.3.2", 1549 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 1550 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 1551 | "dev": true, 1552 | "requires": { 1553 | "prelude-ls": "1.1.2" 1554 | } 1555 | }, 1556 | "typedarray": { 1557 | "version": "0.0.6", 1558 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 1559 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", 1560 | "dev": true 1561 | }, 1562 | "util-deprecate": { 1563 | "version": "1.0.2", 1564 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1565 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 1566 | "dev": true 1567 | }, 1568 | "validate-npm-package-license": { 1569 | "version": "3.0.3", 1570 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", 1571 | "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", 1572 | "dev": true, 1573 | "requires": { 1574 | "spdx-correct": "3.0.0", 1575 | "spdx-expression-parse": "3.0.0" 1576 | } 1577 | }, 1578 | "which": { 1579 | "version": "1.3.0", 1580 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", 1581 | "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", 1582 | "dev": true, 1583 | "requires": { 1584 | "isexe": "2.0.0" 1585 | } 1586 | }, 1587 | "wordwrap": { 1588 | "version": "1.0.0", 1589 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 1590 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 1591 | "dev": true 1592 | }, 1593 | "wrappy": { 1594 | "version": "1.0.2", 1595 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1596 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1597 | "dev": true 1598 | }, 1599 | "write": { 1600 | "version": "0.2.1", 1601 | "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", 1602 | "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", 1603 | "dev": true, 1604 | "requires": { 1605 | "mkdirp": "0.5.1" 1606 | } 1607 | }, 1608 | "ws": { 1609 | "version": "4.1.0", 1610 | "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz", 1611 | "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==", 1612 | "requires": { 1613 | "async-limiter": "1.0.0", 1614 | "safe-buffer": "5.1.1" 1615 | } 1616 | }, 1617 | "yallist": { 1618 | "version": "2.1.2", 1619 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 1620 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", 1621 | "dev": true 1622 | } 1623 | } 1624 | } 1625 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "etiket", 3 | "version": "0.0.1", 4 | "description": "Just Another Tagbot", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Evelyne Lachance (http://evie.codes/)", 10 | "license": "MIT", 11 | "dependencies": { 12 | "discord.js": "github:discordjs/discord.js#master", 13 | "enmap": "^0.5.0", 14 | "enmap-mongo": "^1.0.3", 15 | "moment": "^2.18.1", 16 | "moment-duration-format": "^1.3.0" 17 | }, 18 | "devDependencies": { 19 | "eslint": "^4.7.1", 20 | "eslint-config-standard": "^10.2.1", 21 | "eslint-plugin-import": "^2.7.0", 22 | "eslint-plugin-node": "^5.1.1", 23 | "eslint-plugin-promise": "^3.5.0", 24 | "eslint-plugin-standard": "^3.0.1" 25 | } 26 | } 27 | --------------------------------------------------------------------------------