├── .gitignore ├── LICENSE ├── README.md ├── assets ├── avatar │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ ├── 6.jpg │ └── 7.jpg ├── document │ └── .gitkeep ├── image │ └── .gitkeep ├── match │ └── .gitkeep ├── miniprogram │ ├── gh_20c0aec9e879_258.jpg │ ├── gh_39523b4bea53_258.jpg │ └── gh_50edfc07a3c3_258.jpg ├── video │ └── .gitkeep ├── voice │ └── .gitkeep └── wallpaper │ └── .gitkeep ├── config ├── config.js ├── data.js ├── plan.js ├── remind.js └── url.js ├── feature ├── assets.js ├── avatar.js ├── bomb.js ├── cartoon.js ├── dialog.js ├── emotion.js ├── group.js ├── joke.js ├── mongodb.js ├── order.js ├── plan.js ├── playlist.js ├── poem.js ├── remind.js ├── single.js └── weather.js ├── model └── chatrecord.js ├── package-lock.json ├── package.json ├── plan.md ├── plan ├── v0.1.*.md ├── v0.2.*.md ├── v0.3.*.md └── v0.4.*.md ├── robot.js ├── test ├── baidu.test.js └── test.js ├── token └── accessToken.js ├── tools ├── assetTools.js ├── contactTools.js ├── friendShipTools.js ├── messageTools.js ├── mongo.js ├── roomTools.js ├── tools.js └── utils.js └── updatelog.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # temp 聊天记录 61 | # temp/* 62 | .DS_Store 63 | default.memory-card.json -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 康兵奎 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WeChatRobot 2 | 3 | 微信机器人,能够排忧解难,帮你处理大量的操作。也可以陪你聊天,获取想要的信息。 4 | 5 | ⚠️注意:master分支为不稳定分支,目前稳定分支为 `v0.2.6` 请优先使用稳定分支!!! 6 | 7 | ## 项目目录 8 | 9 | ``` 10 | WechatRobot 11 | |---assets // 资源目录 12 | | |---avatar // 头像资源 13 | | |---document // 文档资源 14 | | |---image // 图片资源资源 15 | | |---match // 朋友圈配图资源 16 | | |---miniprogram // 小程序码存放路径 17 | | |---video // 视频资源 18 | | |---voice // 语音资源 19 | | |---wallpaper // 壁纸资源 20 | |---config // 配置文件目录 21 | |---feature // 功能文件目录,存放各个功能的实现 22 | |---model // mongoose 数据库模型目录,存放数据库映射关系 23 | |---plan // 版本计划列表,按版本细分文件,方便查阅 24 | |---test // 存放用于临时测试的文件 25 | |---token // 百度 AI Token 存放目录,在 v0.3.0 接入百度 AI 后删除,改用数据库记录 26 | |---tools // 工具类存放目录,主要存放相关的工具类,为功能模块提供支持 27 | |---index.js // 项目主文件,是机器人的入口文件 28 | |---plan.md // 特殊功能规划文件,主要为提升机器人的智能程度 29 | |---updatelog.md // 项目更新日志 30 | |---LICENSE // 开源证书文件 31 | ``` 32 | 33 | ## 项目依赖环境 34 | 35 | node: 版本大于 `v10.0.0`,推荐使用版本:`v10.5.0` 36 | 37 | ## 运行 38 | 39 | 安装依赖: 40 | 41 | ``` 42 | npm install 43 | ``` 44 | 45 | 修改所需要的配置信息: 46 | 47 | 打开 config.js 文件,补全文件中的相应的Key,目前有: 48 | 49 | ``` 50 | // 心知天气API密钥 51 | weatherAPIKey: '', 52 | // 百度AI应用 API Key 53 | baiduApiKey: '', 54 | // 百度AI应用 Secret Key 55 | baiduSecretKey: '', 56 | // 聚合数据,获取笑话的key 57 | jokeKey: '', 58 | // 聚合数据,问答类的key 59 | qAndAKey: '' 60 | ``` 61 | 62 | 运行: 63 | 64 | ``` 65 | npm start 66 | ``` 67 | 68 | 扫描终端二维码,登录,然后完成。 69 | 70 | ## 注意 71 | 72 | 目前百度AI接口正在开发中,相应功能还未实现,可以不用填写百度AI相应的 key 。(在 v0.3.0 等后续版本中将接入百度AI中心) 73 | 74 | ## 知识库功能 75 | 76 | 此版本展示关闭知识库功能,下个版本将重构知识库功能,带来更加好用的知识库管理和整理功能。 77 | 78 | 修改 order.js 文件中的 ORDER_KEY 对象可以修改警告的关键字。 79 | 80 | ## 开源协议 81 | 82 | MIT License 83 | 84 | Copyright (c) 2018 康兵奎 85 | 86 | Permission is hereby granted, free of charge, to any person obtaining a copy 87 | of this software and associated documentation files (the "Software"), to deal 88 | in the Software without restriction, including without limitation the rights 89 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 90 | copies of the Software, and to permit persons to whom the Software is 91 | furnished to do so, subject to the following conditions: 92 | 93 | The above copyright notice and this permission notice shall be included in all 94 | copies or substantial portions of the Software. 95 | 96 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 97 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 98 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 99 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 100 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 101 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 102 | SOFTWARE. 103 | 104 | ## [更新日志](./updatelog.md) 105 | -------------------------------------------------------------------------------- /assets/avatar/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BingKui/WeChatRobot/83ff86cdd07ac62e3153b66ea0509f677bd3c78f/assets/avatar/1.jpg -------------------------------------------------------------------------------- /assets/avatar/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BingKui/WeChatRobot/83ff86cdd07ac62e3153b66ea0509f677bd3c78f/assets/avatar/2.jpg -------------------------------------------------------------------------------- /assets/avatar/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BingKui/WeChatRobot/83ff86cdd07ac62e3153b66ea0509f677bd3c78f/assets/avatar/3.jpg -------------------------------------------------------------------------------- /assets/avatar/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BingKui/WeChatRobot/83ff86cdd07ac62e3153b66ea0509f677bd3c78f/assets/avatar/4.jpg -------------------------------------------------------------------------------- /assets/avatar/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BingKui/WeChatRobot/83ff86cdd07ac62e3153b66ea0509f677bd3c78f/assets/avatar/5.jpg -------------------------------------------------------------------------------- /assets/avatar/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BingKui/WeChatRobot/83ff86cdd07ac62e3153b66ea0509f677bd3c78f/assets/avatar/6.jpg -------------------------------------------------------------------------------- /assets/avatar/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BingKui/WeChatRobot/83ff86cdd07ac62e3153b66ea0509f677bd3c78f/assets/avatar/7.jpg -------------------------------------------------------------------------------- /assets/document/.gitkeep: -------------------------------------------------------------------------------- 1 | 存放文档资源目录 -------------------------------------------------------------------------------- /assets/image/.gitkeep: -------------------------------------------------------------------------------- 1 | 存放图片资源文件 2 | -------------------------------------------------------------------------------- /assets/match/.gitkeep: -------------------------------------------------------------------------------- 1 | 存放朋友圈配图资源 -------------------------------------------------------------------------------- /assets/miniprogram/gh_20c0aec9e879_258.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BingKui/WeChatRobot/83ff86cdd07ac62e3153b66ea0509f677bd3c78f/assets/miniprogram/gh_20c0aec9e879_258.jpg -------------------------------------------------------------------------------- /assets/miniprogram/gh_39523b4bea53_258.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BingKui/WeChatRobot/83ff86cdd07ac62e3153b66ea0509f677bd3c78f/assets/miniprogram/gh_39523b4bea53_258.jpg -------------------------------------------------------------------------------- /assets/miniprogram/gh_50edfc07a3c3_258.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BingKui/WeChatRobot/83ff86cdd07ac62e3153b66ea0509f677bd3c78f/assets/miniprogram/gh_50edfc07a3c3_258.jpg -------------------------------------------------------------------------------- /assets/video/.gitkeep: -------------------------------------------------------------------------------- 1 | 存放视频资源目录 2 | -------------------------------------------------------------------------------- /assets/voice/.gitkeep: -------------------------------------------------------------------------------- 1 | 存放语音消息资源 -------------------------------------------------------------------------------- /assets/wallpaper/.gitkeep: -------------------------------------------------------------------------------- 1 | 壁纸资源目录 -------------------------------------------------------------------------------- /config/config.js: -------------------------------------------------------------------------------- 1 | // 保存项目的一些配置信息,方便修改 2 | module.exports = { 3 | // 限制群名,只在特定群内回复 4 | groupList: ["一个人的群聊", "年轻人"], 5 | // 机器人模式消息提示信息 6 | robotTipMessage: '🤖:机器人模式开启,机器人接管聊天', 7 | // 机器人回复前缀 8 | robotSuffix: '🤖', 9 | // 是否根据星期修改头像,默认关闭 10 | isAutoChangeAvatar: false, 11 | // 个人天气推送,默认关闭 12 | isAutoPushWeatherPerson: false, 13 | // 群天气推送,默认关闭 14 | isAutoPushWeatherRoom: false, 15 | // 数据库地址 16 | mongoDB: 'mongodb://127.0.0.1:27017/wechatrobot', 17 | // 是否开启聊天记录存储,默认开启 18 | isSaveChatLog: true, 19 | // 是否开启消息轰炸功能,默认关闭 20 | isOpenMsgBomb: false, 21 | // 是否开启休息提醒功能,默认关闭 22 | isOpenRemind: false, 23 | // 是否支持知识库功能,默认不支持 24 | isKnowledgeSupport: false, 25 | // log4js 配置 26 | log4js: { 27 | "appenders": [{ 28 | "type": "clustered", 29 | "appenders": [{ 30 | "type": "console" 31 | }, { 32 | "type": "dateFile", 33 | "filename": "logs/access.log", 34 | "pattern": "-yyyy-MM-dd", 35 | }, { 36 | "type": "file", 37 | "filename": "logs/app.log", 38 | "maxLogSize": 10485760, 39 | "numBackups": 3 40 | }, { 41 | "type": "logLevelFilter", 42 | "level": "ERROR", 43 | "appender": { 44 | "type": "file", 45 | "filename": "logs/errors.log" 46 | } 47 | }] 48 | }] 49 | }, 50 | // 心知天气API密钥 51 | weatherAPIKey: 'rjpchbvb5bdfx0yo', 52 | // 百度AI应用 API Key 53 | baiduApiKey: 'foOxXrjISvpgbv3zkhwstjVu', 54 | // 百度AI应用 Secret Key 55 | baiduSecretKey: 'jLFMLuZ4yZHykZgqGC8kDeHbuGcABi7x', 56 | // 聚合数据,获取笑话的key 57 | jokeKey: 'f465821c2906a83971b89619b59ff5fb', 58 | // 聚合数据,问答类的key 59 | qAndAKey: '1dde1252284a744543bb50b90b1b1f02' 60 | }; -------------------------------------------------------------------------------- /config/data.js: -------------------------------------------------------------------------------- 1 | // 配置数据公共文件,后续相应逐步替换为借口获取相应的数据 2 | // 需要配套后台管理系统,管理数据(项目待添加,规划中) 3 | module.exports = { 4 | plans: [{ 5 | startTime: { 6 | hour: 19, 7 | minute: 30, 8 | }, 9 | endTime: { 10 | hour: 21, 11 | minute: 0, 12 | }, 13 | message: '跑步中,有事电话联系~~', 14 | },], 15 | remind: { 16 | remindNoonBreakHour: [12, 13], 17 | remindNoonBreakData: ['中午休息一下吧!这样下午才能更好工作!😊 ', '你现在睡一会,下午会更有精神哟!'], 18 | remindSleepHour: [0, 1, 2, 3, 4, 5, 6], 19 | remindSleepData: ['早点睡吧!', '熬夜对身体不好,早点睡吧!', '你是不是忘了时间,现在还不睡觉??!!', '半夜三更,你不睡觉是想要上天吗?', 20 | '你要是再不睡,天就要亮了!', '天都亮了,你不会还没睡觉吧!?', '恭喜你!成功的熬了个夜!'] 21 | }, 22 | playlist: [{ 23 | name: '完了,耳朵怀孕的感觉!', 24 | address: 'https://music.163.com/#/playlist?id=2281915904', 25 | from: 'netease', 26 | }], 27 | cartoonData: [{ 28 | "name": "西行纪", 29 | "isVip": true, 30 | "address": "https://v.qq.com/x/cover/0gsf9fytppje54d.html" 31 | }, { 32 | "name": "魔道祖师", 33 | "isVip": true, 34 | "address": "https://v.qq.com/x/cover/k4mutekomtrdbux.html" 35 | }, { 36 | "name": "全职高手特别篇", 37 | "isVip": true, 38 | "address": "https://v.qq.com/x/cover/hlo45ourdy4rh3t.html" 39 | }, { 40 | "name": "我的逆天神器", 41 | "isVip": false, 42 | "address": "https://v.qq.com/x/cover/fqtckz7db8g3rtp.html" 43 | }, { 44 | "name": "刺客伍六七", 45 | "isVip": false, 46 | "address": "https://v.qq.com/x/cover/9jh7p3r7ljkxkmc.html" 47 | }], 48 | }; -------------------------------------------------------------------------------- /config/plan.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plans: [{ 3 | startTime: { 4 | hour: 19, 5 | minute: 30, 6 | }, 7 | endTime: { 8 | hour: 21, 9 | minute: 0, 10 | }, 11 | message: '跑步中,有事电话联系~~', 12 | },], 13 | }; -------------------------------------------------------------------------------- /config/remind.js: -------------------------------------------------------------------------------- 1 | // 提醒配置文件,用于配置提醒的相关时间和相应的信息 2 | 3 | module.exports = { 4 | remindNoonBreakHour: [12, 13], 5 | remindNoonBreakData: ['中午休息一下吧!这样下午才能更好工作!😊 ', '你现在睡一会,下午会更有精神哟!'], 6 | remindSleepHour: [0, 1, 2, 3, 4, 5, 6], 7 | remindSleepData: ['早点睡吧!', '熬夜对身体不好,早点睡吧!', '你是不是忘了时间,现在还不睡觉??!!', '半夜三更,你不睡觉是想要上天吗?', 8 | '你要是再不睡,天就要亮了!', '天都亮了,你不会还没睡觉吧!?', '恭喜你!成功的熬了个夜!'] 9 | }; -------------------------------------------------------------------------------- /config/url.js: -------------------------------------------------------------------------------- 1 | // 保存所有用到的地址路径 2 | module.exports = { 3 | // 百度 Access Token 获取地址 4 | accessTokenUrl: 'https://aip.baidubce.com/oauth/2.0/token', 5 | // 语法分析 6 | grammarAnalyze: 'https://aip.baidubce.com/rpc/2.0/nlp/v1/lexer', 7 | // 情感分析 8 | emotionAnalyze: 'https://aip.baidubce.com/rpc/2.0/nlp/v1/sentiment_classify', 9 | // 笑话地址 10 | jokeUrl: 'http://v.juhe.cn/joke/randJoke.php?&type=json&key=', 11 | // 问答类地址 12 | qAndAUrl: 'http://op.juhe.cn/robot/index', 13 | // 心知天气api地址 14 | weatherUrl: 'https://api.seniverse.com/v3/weather/now.json?language=zh-Hans&unit=c', 15 | } -------------------------------------------------------------------------------- /feature/assets.js: -------------------------------------------------------------------------------- 1 | // 发送图片、壁纸、头像、文件等资源 2 | const { randomFile, assetFolder } = require('../tools/assetTools.js'); 3 | const { messageText } = require('../tools/messageTools.js'); 4 | 5 | /** 6 | * @description 头像消息,弃用,使用 assetMessage 代替 7 | * @param {Message} message message 对象 8 | */ 9 | const avatarMessage = async (message) => { 10 | const msgContent = randomFile('avatar', '头像'); 11 | await message.say(msgContent); 12 | } 13 | 14 | /** 15 | * @description 图片消息,弃用,使用 assetMessage 代替 16 | * @param {Message} message message 对象 17 | */ 18 | const imageMessage = async (message) => { 19 | const msgContent = randomFile('image', '图片'); 20 | await message.say(msgContent); 21 | } 22 | 23 | /** 24 | * @description 壁纸消息,弃用,使用 assetMessage 代替 25 | * @param {Message} message message 对象 26 | */ 27 | const wallpaperMessage = async (message) => { 28 | const msgContent = randomFile('wallpaper', '壁纸'); 29 | await message.say(msgContent); 30 | } 31 | 32 | /** 33 | * @description 文档消息,弃用,使用 assetMessage 代替 34 | * @param {Message} message message 对象 35 | */ 36 | const documentMessage = async (message) => { 37 | const msgContent = randomFile('document', '文档'); 38 | await message.say(msgContent); 39 | } 40 | 41 | /** 42 | * @description 配图消息,弃用,使用 assetMessage 代替 43 | * @param {Message} message message 对象 44 | */ 45 | const matchMessage = async (message) => { 46 | const msgContent = randomFile('match', '朋友圈配图'); 47 | await message.say(msgContent); 48 | } 49 | 50 | /** 51 | * @description 视频消息,弃用,使用 assetMessage 代替 52 | * @param {Message} message message 对象 53 | */ 54 | const videoMessage = async (message) => { 55 | const msgContent = randomFile('video', '视频'); 56 | await message.say(msgContent); 57 | } 58 | 59 | /** 60 | * @description 语音消息,弃用,使用 assetMessage 代替 61 | * @param {Message} message message 对象 62 | */ 63 | const voiceMessage = async (message) => { 64 | const msgContent = randomFile('voice', '语音'); 65 | await message.say(msgContent); 66 | } 67 | 68 | /** 69 | * @description 资源类消息 70 | * @param {Message} message message 对象 71 | * @return {Boolean} 返回是否是资源消息,不是资源类消息,返回 false 72 | */ 73 | const assetsMessage = async (message) => { 74 | const text = messageText(message); 75 | const type = assetFolder(text); 76 | if (type) { 77 | const msgContent = randomFile(type); 78 | await message.say(msgContent); 79 | return true; 80 | } 81 | return false; 82 | } 83 | 84 | module.exports = assetsMessage; 85 | -------------------------------------------------------------------------------- /feature/avatar.js: -------------------------------------------------------------------------------- 1 | // 定时任务,修改用户头像 2 | const schedule = require('node-schedule'); 3 | const { avatarImg } = require('../tools/assetTools.js'); 4 | 5 | /** 6 | * @description 定时每天的 00:01:00 执行修改头像的任务 7 | * @param {Contact} contact 登录的用户对象 8 | */ 9 | const avatarAutoChange = (contact) => { 10 | schedule.scheduleJob('0 1 0 * * *', async () => { 11 | const avatarFile = avatarImg(); 12 | try { 13 | await contact.avatar(avatarFile); 14 | } catch (err) { 15 | console.log('修改头像失败'); 16 | } 17 | }); 18 | } 19 | 20 | module.exports = avatarAutoChange; -------------------------------------------------------------------------------- /feature/bomb.js: -------------------------------------------------------------------------------- 1 | // 消息轰炸功能 2 | 3 | /** 4 | * @description 消息轰炸 5 | * @param {Contact | Room | Message} obj 联系人对象、聊天室对象、消息对象 6 | * @param {Array} bomb 轰炸的消息内容 7 | * @todo 后续增加其他类型的消息轰炸,如图片、文件等。 8 | */ 9 | const bombMessage = async (obj, bomb) => { 10 | bomb.map(item => await obj.say(item)); 11 | } 12 | 13 | /** 14 | * @description 消息和房间消息轰炸,支持 @ 人员 15 | * @param {Room | Message} obj 房间对象、消息对象 16 | * @param {Array} bomb 轰炸消息内容 17 | * @param {Contact | Array} @ 对象,或数组 18 | */ 19 | const roomAndMessageBomb = async (obj, bomb, memtion) => { 20 | bomb.map(item => await obj.say(item, memtion)); 21 | } 22 | 23 | module.exports = { 24 | bombMessage, 25 | roomAndMessageBomb, 26 | }; -------------------------------------------------------------------------------- /feature/cartoon.js: -------------------------------------------------------------------------------- 1 | // 歌单推荐功能 2 | const { messageText } = require('../tools/messageTools.js'); 3 | const { randomNum } = require('../tools/tools.js'); 4 | const { cartoonData } = require('../config/data.js'); 5 | 6 | /** 7 | * 判断消息是否是歌单消息 8 | * @param {String} text 消息内容 9 | */ 10 | const cartoonState = (text) => { 11 | const reg = new RegExp(`/动漫/g`); 12 | return reg.test(text); 13 | } 14 | 15 | /** 16 | * 生成歌单内容 17 | */ 18 | const cartoonContent = () => { 19 | const index = randomNum(0, cartoonData.length - 1); 20 | const { name, address } = cartoonData[index]; 21 | return `动漫名:${name}\n地址:${address}\n`; 22 | } 23 | 24 | /** 25 | * 生成用于分享的图片,暂定 26 | */ 27 | const cartoonPicture = () => { 28 | return ''; 29 | } 30 | 31 | /** 32 | * 动漫推荐 33 | * @param {Message} message 消息对象 34 | */ 35 | const cartoonMessage = async (message) => { 36 | const text = messageText(message); 37 | if (cartoonState(text)) { 38 | await message.say(cartoonContent()); 39 | return true; 40 | } 41 | return false; 42 | } 43 | 44 | module.exports = cartoonMessage; -------------------------------------------------------------------------------- /feature/dialog.js: -------------------------------------------------------------------------------- 1 | // 正常流程对话模块 2 | // v0.2.* 先接入聚合数据的问答模式,后续大家自己的服务,改为自己的服务 3 | const Axios = require('axios'); 4 | const { qAndAUrl } = require('../config/url.js'); 5 | const { qAndAKey } = require('../config/config.js'); 6 | const { messageText } = require('../tools/messageTools.js'); 7 | 8 | /** 9 | * @description 根据问题得到答案 10 | * @param {String} question 问题内容 11 | */ 12 | const dialogAnswer = async (question) => { 13 | const url = encodeURI(`${qAndAUrl}?&info=${question}dtype=json&loc=&userid=&key=${qAndAKey}`); 14 | const result = await Axios.get(url); 15 | if (result) { 16 | return result.data.result.text; 17 | } 18 | return '这个问题有点难,难倒我了'; 19 | } 20 | 21 | /** 22 | * @description 发送消息 23 | * @param {Message} message 消息对象 24 | */ 25 | const dialogMessage = async (message) => { 26 | const question = messageText(message); 27 | const answer = await dialogAnswer(question); 28 | await message.say(answer); 29 | } 30 | 31 | module.exports = dialogMessage; -------------------------------------------------------------------------------- /feature/emotion.js: -------------------------------------------------------------------------------- 1 | // 情绪系统(规划中功能) 2 | // 模拟正常人的情绪,根据情绪回复不同的语言,规避图灵测试,更加智能 3 | // 根据不同的场景,产生不同的情绪,当情绪不同时,会增加相应的开头或者结束语。 4 | // 情绪分类 5 | // 1.正常:正常对话,答案正常 6 | // 2.沮丧 7 | // 3.愤怒 8 | // 4.开心:增加不同的表情,语气助词等,增加活跃气氛。 9 | // 5.惊恐 10 | // 6.悲哀 11 | 12 | // 通过当前语句和发送人等信息,判断当前的情绪应该是什么等级 13 | const getEmotionLevel = (m) => { 14 | 15 | } 16 | 17 | module.exports = { 18 | 19 | }; -------------------------------------------------------------------------------- /feature/group.js: -------------------------------------------------------------------------------- 1 | // 群组聊天相关功能 2 | const { Wechaty } = require('wechaty'); 3 | const { mentioned } = require('../tools/tools.js'); 4 | const { contactListInfo, contactInfo } = require('../tools/contactTools.js'); 5 | const dialogMessage = require('./dialog.js'); 6 | const { messageText, messageInfo } = require('../tools/messageTools.js'); 7 | 8 | const bot = Wechaty.instance(); 9 | 10 | /** 11 | * @description 回复群聊中的 @ 消息,并回 @ 回去 12 | * @param {Message} message 消息对象 13 | * @param {MessageInfo} info 消息内容对象 14 | * @param {ContactInfo} self 本身信息 15 | */ 16 | const groupMessage = async (message, info, self) => { 17 | // 自己发的消息,直接返回 18 | if (info.isSelf) { 19 | return; 20 | } 21 | console.log(info.mentionInfo); 22 | // 如果 @ 到自己,在进行回复 23 | if (mentioned(info.mentionInfo, self.name)) { 24 | // 处理消息进行回复 25 | await dialogMessage(message); 26 | } 27 | } 28 | 29 | /** 30 | * @description 查询群聊对象,不能存在直接创建 31 | * @param {Array} cantactList 联系人列表 32 | * @param {String} topic 群名称 33 | */ 34 | const groupObject = async (topic = '') => { 35 | // 查找是否存在 36 | let room = await bot.Room.find({topic}); 37 | const userSelf = bot.userSelf(); 38 | if (!room) { 39 | // 房间不存在,直接创建 40 | room = await bot.Room.create([contact, userSelf], topic); 41 | } 42 | return room; 43 | } 44 | 45 | /** 46 | * @description 群聊中添加一个对象 47 | * @param {String} topic 群昵称 48 | * @param {Contact} contact 联系人对象 49 | */ 50 | const groupAddOne = async (topic, contact) => { 51 | // 获取一个Room对象 52 | const room = await groupObject(topic); 53 | // 添加用户到群聊 54 | await room.add(contact); 55 | } 56 | 57 | /** 58 | * @description 群聊添加用户操作 59 | * @param {Message} message 消息对象 60 | * @return {Boolean} 消息发送成功与否 61 | */ 62 | const groupAddAction = async (message) => { 63 | const text = messageText(message); 64 | if (text.indexOf('进群') > -1) { 65 | const info = await messageInfo(message); 66 | // 目前只先添加到 “测试群聊” 67 | await groupAddOne('测试群聊', info.send); 68 | return true; 69 | } 70 | return false; 71 | } 72 | 73 | /** 74 | * @description 用户离开群聊提醒,暂时用不到 75 | * @param {Room} room 群对象 76 | * @param {Array} leaveList 离开的用户数组 77 | */ 78 | const groupLeaveMessage = async (room, leaveList) => { 79 | const infoList = contactListInfo(leaveList); 80 | const names = infoList.map(item => item.name).join('、'); 81 | await room.say(`${names}退出了群聊。`) 82 | } 83 | 84 | /** 85 | * @description 用户新加入群聊 86 | * @param {Room} room 群对象 87 | * @param {Array} joinList 加入的成员 88 | * @param {ContactInfo} inviter 邀请人 89 | * @param {ContactInfo} self 机器人自己 90 | * @TODO 如果是扫码,可能没有邀请者 91 | */ 92 | const groupJoinMessage = async (room, joinList, inviter, self) => { 93 | // 判断是否是机器人自己拉的人 94 | const isRobot = inviter.name === self.name; 95 | const infoList = contactListInfo(joinList); 96 | const names = infoList.map(item => item.name).join('、'); 97 | let msgText = ''; 98 | if (isRobot) { 99 | msgText = `欢迎${names}加入群聊!🎉 🎉 `; 100 | } else { 101 | msgText = `欢迎${names}加入群聊!🎉 感谢${inviter.name}的邀请!👍 `; 102 | } 103 | await room.say(msgText); 104 | } 105 | 106 | /** 107 | * @description 监听群昵称被修改事件 108 | * @param {Room} room 群对象 109 | * @param {String} topic 新群名 110 | * @param {String} oldTopic 旧群名 111 | * @param {Contact} contact 修改者对象 112 | * @param {ContactInfo} self 机器人信息 113 | */ 114 | const groupTopicChange = async (room, oldTopic, contact, self) => { 115 | // 判断是否是机器人自己修改的群名 116 | const isRobot = (await contactInfo(contact)).name === self.name; 117 | if (isRobot) { 118 | return; 119 | } 120 | await room.say('请不要随意修改群昵称!'); 121 | // 修改回去 122 | await room.topic(oldTopic); 123 | await room.say('为防止不必要的麻烦,我已经帮忙修改回去!'); 124 | } 125 | 126 | module.exports = { 127 | groupMessage, 128 | groupAddOne, 129 | groupLeaveMessage, 130 | groupJoinMessage, 131 | groupTopicChange, 132 | groupAddAction, 133 | } -------------------------------------------------------------------------------- /feature/joke.js: -------------------------------------------------------------------------------- 1 | // 笑话相关功能 2 | const Axios = require('axios'); 3 | const { jokeUrl } = require('../config/url'); 4 | const { jokeKey } = require('../config/config.js'); 5 | const { messageText } = require('../tools/messageTools.js'); 6 | 7 | /** 8 | * @description 获取一个笑话 9 | * @return {string} 返回一个笑话的内容 10 | */ 11 | const jokeInfo = async () => { 12 | const res = await Axios.get(`${jokeUrl}${jokeKey}`); 13 | let result = '没什么笑话!'; 14 | if (res) { 15 | result = res.data.result[2].content; 16 | } 17 | return result; 18 | } 19 | 20 | /** 21 | * @description 发送笑话信息 22 | * @param {Message} message 消息对象 23 | */ 24 | const jokeMessage = async (message) => { 25 | const text = messageText(message); 26 | if (text.indexOf('笑话') > -1) { 27 | const joke = await jokeInfo(); 28 | await message.say(joke); 29 | return true; 30 | } 31 | return false; 32 | } 33 | 34 | module.exports = jokeMessage; -------------------------------------------------------------------------------- /feature/mongodb.js: -------------------------------------------------------------------------------- 1 | // MongoDB 数据库相关操作方法 2 | const ChatRecord = require('../model/chatrecord.js'); 3 | 4 | /** 5 | * @description 保存消息到数据库 6 | * @param {MessageRecordInfo} data 需要存入数据库的数据 7 | */ 8 | const saveMessage = (data) => { 9 | console.log('保存聊天信息:', JSON.stringify(data)); 10 | const item = new ChatRecord(data); 11 | item.save((err) => { 12 | if (err) { 13 | console.log(err); 14 | throw(err); 15 | } 16 | }); 17 | } 18 | 19 | module.exports = { 20 | saveMessage, 21 | }; -------------------------------------------------------------------------------- /feature/order.js: -------------------------------------------------------------------------------- 1 | // 秩序管理功能,提醒用户文明用语 2 | const { messageText } = require('../tools/messageTools.js'); 3 | const ORDER_KEY = ['傻逼', '脑残', '我擦', '我靠', '我艹', 'wocao', '我草', '肏', '你个智障']; 4 | 5 | /** 6 | * @description 判断是否存在脏话 7 | * @param {String} text 消息文本 8 | */ 9 | const orderState = (text) => { 10 | const reg = new RegExp(`/${ORDER_KEY.join('|')}/g`); 11 | return reg.test(text); 12 | } 13 | 14 | /** 15 | * @description 判断是否消息包含脏话,并作出警告提醒 16 | * @param {Message} message 消息对象 17 | */ 18 | const orderMessage = async (message) => { 19 | const text = messageText(message); 20 | const send = message.from(); 21 | if (orderState(text)) { 22 | await message.say('请文明用语!!!', send); 23 | } 24 | } 25 | 26 | module.exports = orderMessage; -------------------------------------------------------------------------------- /feature/plan.js: -------------------------------------------------------------------------------- 1 | // 计划任务,在计划任务时间回复特定消息 2 | 3 | const { messageText, messageInfo } = require('../tools/messageTools.js'); 4 | const { robotSuffix, robotTipMessage } = require('../config/config.js'); 5 | const { plans } = require('../config/plan.js'); 6 | 7 | /** 8 | * 处理消息,返回是否在计划内和计划内的回复消息 9 | * @param {Date} date 10 | */ 11 | const planState = (date) => { 12 | let flag = false; 13 | let result = ''; 14 | for (let i = 0; i < plans.length; i++) { 15 | const { startTime, endTime, message } = plans[i]; 16 | if (dealTime(date, startTime, endTime)) { 17 | result = message; 18 | flag = true; 19 | break; 20 | } 21 | } 22 | return { 23 | flag, 24 | result, 25 | }; 26 | } 27 | 28 | const dealTime = (date, start, end) => { 29 | const time = new Date(date); 30 | const hour = time.getHours(); 31 | const minute = time.getMinutes(); 32 | const flag_one = hour >= start.hour && minute >= start.minute; 33 | const flag_two = hour <= end.hour && minute <= end.minute; 34 | if (flag_one && flag_two) { 35 | return true; 36 | } 37 | return false; 38 | } 39 | 40 | /** 41 | * 计划任务 42 | * @param {Message} message 消息对象 43 | * @return {Boolean} 返回发送是否成功 44 | */ 45 | const planMessage = async (message) => { 46 | const { date } = await messageInfo(message); 47 | const { flag, result } = planState(date); 48 | if (flag) { 49 | await message.say(robotTipMessage); 50 | await message.say(`${robotSuffix}:${result}`); 51 | return true; 52 | } 53 | return false; 54 | } 55 | 56 | module.exports = planMessage; -------------------------------------------------------------------------------- /feature/playlist.js: -------------------------------------------------------------------------------- 1 | // 歌单推荐功能 2 | const { messageText } = require('../tools/messageTools.js'); 3 | 4 | const { playlist } = require('../config/data.js'); 5 | 6 | /** 7 | * 判断消息是否是歌单消息 8 | * @param {String} text 消息内容 9 | */ 10 | const playlistState = (text) => { 11 | const reg = new RegExp(`/歌单/g`); 12 | return reg.test(text); 13 | } 14 | 15 | /** 16 | * 生成歌单内容 17 | */ 18 | const palylistContent = () => { 19 | const { name, address, from } = playlist[0]; 20 | const source = { 21 | qq: 'QQ音乐', 22 | netease: '网易云音乐', 23 | }; 24 | return `歌单名:${name}\n地址:${address}\n来源:${source[from]}`; 25 | } 26 | 27 | /** 28 | * 生成用于分享的图片,暂定 29 | */ 30 | const playlistPicture = () => { 31 | return ''; 32 | } 33 | 34 | /** 35 | * 歌单推荐 36 | * @param {Message} message 消息对象 37 | */ 38 | const playlistMessage = async (message) => { 39 | const text = messageText(message); 40 | if (playlistState(text)) { 41 | await message.say(palylistContent()); 42 | return true; 43 | } 44 | return false; 45 | } 46 | 47 | module.exports = playlistMessage; -------------------------------------------------------------------------------- /feature/poem.js: -------------------------------------------------------------------------------- 1 | // 诗词歌赋 2 | const Axios = require('axios'); 3 | const { messageText } = require('../tools/messageTools.js'); 4 | 5 | /** 6 | * @description 判断是否是需要诗句 7 | * @param {String} text 消息内容 8 | */ 9 | const poemState = (text) => { 10 | const reg = new RegExp(`/诗/g`); 11 | return reg.test(text); 12 | } 13 | 14 | /** 15 | * @description 获取一首随机的诗 16 | */ 17 | const poemOne = async () => { 18 | const poem = await Axios.get('https://wechat.uiseed.cn/poem'); 19 | let result = '没有相关的诗句'; 20 | if (poem) { 21 | result = poem.paragraphs.join('\n'); 22 | } 23 | return result; 24 | } 25 | 26 | /** 27 | * @description 获取一首诗,发送给用户 28 | * @param {Message} message 消息对象 29 | * @return {Boolean} 返回发送是否成功 30 | */ 31 | const poemMessage = async (message) => { 32 | const text = messageText(message); 33 | if (poemState(text)) { 34 | const item = await poemOne(); 35 | await message.say(item); 36 | return true; 37 | } 38 | return false; 39 | } 40 | 41 | module.exports = poemMessage; -------------------------------------------------------------------------------- /feature/remind.js: -------------------------------------------------------------------------------- 1 | // 提醒相关方法,根据当前时间,提醒用户休息 2 | const dayjs = require('dayjs'); 3 | 4 | // 配置数据 5 | const { 6 | remindNoonBreakHour, 7 | remindNoonBreakData, 8 | remindSleepHour, 9 | remindSleepData, 10 | } = require('../config/remind.js'); 11 | 12 | /** 13 | * @description 提醒用户午休,时间段 12:00-14:00 14 | */ 15 | const remindNoonBreak = (index) => { 16 | return remindNoonBreakData[index]; 17 | } 18 | 19 | /** 20 | * @description 提醒用户睡觉,时间段:00:00-7:00 21 | */ 22 | const remindSleep = (index) => { 23 | return remindSleepData[index]; 24 | } 25 | 26 | /** 27 | * @description 提醒消息判断,是否需要发送提醒 28 | * @param {Message} message message 对象 29 | */ 30 | const remindMessage = async (message) => { 31 | const hour = dayjs().hour(); 32 | const indexOne = remindNoonBreakHour.indexOf(hour); 33 | const indexTwo = remindSleepHour.indexOf(hour); 34 | if (indexOne > -1) { 35 | const msgText = remindNoonBreak(indexOne); 36 | await message.say(msgText); 37 | } 38 | if (indexTwo > -1) { 39 | const msgText = remindSleep(indexTwo) 40 | await message.say(msgText); 41 | } 42 | } 43 | 44 | module.exports = remindMessage; -------------------------------------------------------------------------------- /feature/single.js: -------------------------------------------------------------------------------- 1 | // 单聊相关功能 2 | const assetsMessage = require('./assets.js'); 3 | const jokeMessage = require('./joke.js'); 4 | const { weatherMessage } = require('./weather.js'); 5 | const dialogMessage = require('./dialog.js') 6 | const { groupAddAction } = require('./group.js'); 7 | const planMessage = require('./plan.js'); 8 | const playlistMessage = require('./playlist.js'); 9 | 10 | /** 11 | * @description 个人类消息处理 12 | * @param {Message} message Message 对象 13 | * @param {MessageInfo} info 消息信息 14 | */ 15 | const singleMessage = async (message, info) => { 16 | // 自己发的消息,直接返回 17 | if (info.isSelf) { 18 | return; 19 | } 20 | // 判断是否是资源类消息 21 | const isAssets = await assetsMessage(message); 22 | const isJoke = await jokeMessage(message); 23 | const isWeather = await weatherMessage(message); 24 | const isJoinGroup = await groupAddAction(message); 25 | const isPlan = await planMessage(message); 26 | const isPlaylist = await playlistMessage(message); 27 | if (!isAssets && !isJoke && !isWeather && !isJoinGroup && !isPlan && !isPlaylist) { 28 | // 不是特殊类型消息,转入对话模块 29 | await dialogMessage(message); 30 | } 31 | } 32 | 33 | module.exports = { 34 | singleMessage, 35 | } -------------------------------------------------------------------------------- /feature/weather.js: -------------------------------------------------------------------------------- 1 | // 天气相关功能方法 2 | const Schedule = require('node-schedule'); 3 | const Pinyin = require('pinyin'); 4 | const Axios = require('axios'); 5 | const { weatherUrl } = require('../config/url'); 6 | const { weatherAPIKey } = require('../config/config.js'); 7 | const { messageText } = require('../tools/messageTools.js'); 8 | 9 | /** 10 | * @description 定时任务,推送天气 11 | * @param {Contact} contact 开启推送的用户 12 | * @param {string} city 需要推送的城市名称 13 | */ 14 | const weatherAutoPush = (contact, city) => { 15 | Schedule.scheduleJob('0 30 9 * * *', async () => { 16 | // 推送天气 17 | const weatherInfo = await weatherInfo(city); 18 | const msg = weatherText(weatherInfo); 19 | await contact.say(msg); 20 | }); 21 | } 22 | 23 | /** 24 | * @description 生成天气消息 25 | * @param {Message} message 消息对象 26 | * @return {Boolean} 消息发送成功与否 27 | */ 28 | const weatherMessage = async (message) => { 29 | const text = messageText(message); 30 | if (text.indexOf('天气') > -1) { 31 | const city = weatherCity(text); 32 | const info = await weatherInfo(city); 33 | await message.say(weatherText(info)); 34 | return true; 35 | } 36 | return false; 37 | } 38 | 39 | const weatherText = (info) => { 40 | let msgText = ''; 41 | if (!info) { 42 | msgText = '目前还不知道天气怎样!'; 43 | } 44 | msgText = `${info.city}\n天气:${info.weather}\n气温:${info.temperature}℃\n发布时间:${info.date}`; 45 | return msgText; 46 | } 47 | 48 | /** 49 | * 50 | * @param {String} text 消息文本内容 51 | * @return {String} 返回城市名称 52 | * @TODO 增加百度的语法分析,准确获取城市 53 | */ 54 | const weatherCity = (text) => { 55 | // 默认天气城市为:杭州 56 | return text.split('的')[1] || '杭州'; 57 | } 58 | 59 | /** 60 | * @description 获取某个天气信息 61 | * @param {String} city 需要获取天气信息的城市名称 62 | * @return {Object} 基本天气信息 63 | */ 64 | const weatherInfo = async (city) => { 65 | const _city = Pinyin(city, { style: Pinyin['STYLE_NORMAL'] }).join(''); 66 | const res = await Axios.get(`${weatherUrl}&key=${weatherAPIKey}&location=${_city}`); 67 | console.log(JSON.stringify(res.data)); 68 | let result = null; 69 | if (res) { 70 | const data = res.data.results[0].now; 71 | const time = res.data.results[0].last_update; 72 | result = { 73 | city, 74 | weather: data.text, 75 | temperature: data.temperature, 76 | date: (new Date(time)).toLocaleString(), 77 | }; 78 | } else { 79 | console.log('获取天气失败'); 80 | } 81 | return result; 82 | } 83 | 84 | module.exports = { 85 | weatherInfo, 86 | weatherAutoPush, 87 | weatherMessage, 88 | }; -------------------------------------------------------------------------------- /model/chatrecord.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 消息记录数据库模型 3 | */ 4 | const mongoose = require('mongoose'); 5 | const Schema = mongoose.Schema; 6 | 7 | const ChatRecordSchema = new Schema({ 8 | send: String, 9 | accept: String, 10 | type: String, 11 | isGroupMsg: Boolean, 12 | content: String, 13 | date: Date, 14 | memtionList: [String], 15 | }); 16 | 17 | const ChatRecordModel = mongoose.model('chatrecord', ChatRecordSchema); 18 | 19 | module.exports = ChatRecordModel; -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wechatrobot", 3 | "version": "0.2.6", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.5", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", 10 | "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", 11 | "requires": { 12 | "mime-types": "~2.1.18", 13 | "negotiator": "0.6.1" 14 | } 15 | }, 16 | "addressparser": { 17 | "version": "1.0.1", 18 | "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", 19 | "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=", 20 | "optional": true 21 | }, 22 | "agent-base": { 23 | "version": "4.2.1", 24 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", 25 | "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", 26 | "requires": { 27 | "es6-promisify": "^5.0.0" 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 | "optional": true, 35 | "requires": { 36 | "co": "^4.6.0", 37 | "fast-deep-equal": "^1.0.0", 38 | "fast-json-stable-stringify": "^2.0.0", 39 | "json-schema-traverse": "^0.3.0" 40 | } 41 | }, 42 | "amqplib": { 43 | "version": "0.5.2", 44 | "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz", 45 | "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==", 46 | "optional": true, 47 | "requires": { 48 | "bitsyntax": "~0.0.4", 49 | "bluebird": "^3.4.6", 50 | "buffer-more-ints": "0.0.2", 51 | "readable-stream": "1.x >=1.1.9", 52 | "safe-buffer": "^5.0.1" 53 | } 54 | }, 55 | "ansi-regex": { 56 | "version": "2.1.1", 57 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 58 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 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 | "optional": true 65 | }, 66 | "array-flatten": { 67 | "version": "2.1.1", 68 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", 69 | "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=" 70 | }, 71 | "asn1": { 72 | "version": "0.2.3", 73 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", 74 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", 75 | "optional": true 76 | }, 77 | "assert-plus": { 78 | "version": "1.0.0", 79 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 80 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 81 | }, 82 | "ast-types": { 83 | "version": "0.11.5", 84 | "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.5.tgz", 85 | "integrity": "sha512-oJjo+5e7/vEc2FBK8gUalV0pba4L3VdBIs2EKhOLHLcOd2FgQIVQN9xb0eZ9IjEWyAL7vq6fGJxOvVvdCHNyMw==", 86 | "optional": true 87 | }, 88 | "async": { 89 | "version": "2.6.1", 90 | "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", 91 | "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", 92 | "requires": { 93 | "lodash": "^4.17.10" 94 | } 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 | "asynckit": { 102 | "version": "0.4.0", 103 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 104 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", 105 | "optional": true 106 | }, 107 | "aws-sign2": { 108 | "version": "0.7.0", 109 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 110 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", 111 | "optional": true 112 | }, 113 | "aws4": { 114 | "version": "1.7.0", 115 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", 116 | "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", 117 | "optional": true 118 | }, 119 | "axios": { 120 | "version": "0.18.0", 121 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz", 122 | "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", 123 | "requires": { 124 | "follow-redirects": "^1.3.0", 125 | "is-buffer": "^1.1.5" 126 | } 127 | }, 128 | "bcrypt-pbkdf": { 129 | "version": "1.0.2", 130 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 131 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 132 | "optional": true, 133 | "requires": { 134 | "tweetnacl": "^0.14.3" 135 | } 136 | }, 137 | "bitsyntax": { 138 | "version": "0.0.4", 139 | "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.0.4.tgz", 140 | "integrity": "sha1-6xDMb4K4xJDj6FaY8H6D1G4MuoI=", 141 | "optional": true, 142 | "requires": { 143 | "buffer-more-ints": "0.0.2" 144 | } 145 | }, 146 | "bl": { 147 | "version": "1.1.2", 148 | "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", 149 | "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=", 150 | "optional": true, 151 | "requires": { 152 | "readable-stream": "~2.0.5" 153 | }, 154 | "dependencies": { 155 | "isarray": { 156 | "version": "1.0.0", 157 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 158 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 159 | "optional": true 160 | }, 161 | "readable-stream": { 162 | "version": "2.0.6", 163 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", 164 | "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", 165 | "optional": true, 166 | "requires": { 167 | "core-util-is": "~1.0.0", 168 | "inherits": "~2.0.1", 169 | "isarray": "~1.0.0", 170 | "process-nextick-args": "~1.0.6", 171 | "string_decoder": "~0.10.x", 172 | "util-deprecate": "~1.0.1" 173 | } 174 | } 175 | } 176 | }, 177 | "bluebird": { 178 | "version": "3.5.1", 179 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", 180 | "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" 181 | }, 182 | "body-parser": { 183 | "version": "1.18.2", 184 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", 185 | "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", 186 | "requires": { 187 | "bytes": "3.0.0", 188 | "content-type": "~1.0.4", 189 | "debug": "2.6.9", 190 | "depd": "~1.1.1", 191 | "http-errors": "~1.6.2", 192 | "iconv-lite": "0.4.19", 193 | "on-finished": "~2.3.0", 194 | "qs": "6.5.1", 195 | "raw-body": "2.3.2", 196 | "type-is": "~1.6.15" 197 | }, 198 | "dependencies": { 199 | "debug": { 200 | "version": "2.6.9", 201 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 202 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 203 | "requires": { 204 | "ms": "2.0.0" 205 | } 206 | }, 207 | "iconv-lite": { 208 | "version": "0.4.19", 209 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 210 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" 211 | }, 212 | "qs": { 213 | "version": "6.5.1", 214 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", 215 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" 216 | }, 217 | "raw-body": { 218 | "version": "2.3.2", 219 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", 220 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", 221 | "requires": { 222 | "bytes": "3.0.0", 223 | "http-errors": "1.6.2", 224 | "iconv-lite": "0.4.19", 225 | "unpipe": "1.0.0" 226 | }, 227 | "dependencies": { 228 | "depd": { 229 | "version": "1.1.1", 230 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 231 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" 232 | }, 233 | "http-errors": { 234 | "version": "1.6.2", 235 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 236 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", 237 | "requires": { 238 | "depd": "1.1.1", 239 | "inherits": "2.0.3", 240 | "setprototypeof": "1.0.3", 241 | "statuses": ">= 1.3.1 < 2" 242 | } 243 | } 244 | } 245 | }, 246 | "setprototypeof": { 247 | "version": "1.0.3", 248 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", 249 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" 250 | } 251 | } 252 | }, 253 | "boom": { 254 | "version": "2.10.1", 255 | "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", 256 | "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", 257 | "requires": { 258 | "hoek": "2.x.x" 259 | } 260 | }, 261 | "brolog": { 262 | "version": "1.8.1", 263 | "resolved": "https://registry.npmjs.org/brolog/-/brolog-1.8.1.tgz", 264 | "integrity": "sha512-V5XGWTl4GGBdEC5W2kmbQlJtSFdjHVUig4BjvJUH0ZXU88098e7TwNlJaLZDsS4/KXpbWtq2m6AwNKkRMqbP5A==" 265 | }, 266 | "bson": { 267 | "version": "1.0.9", 268 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", 269 | "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==" 270 | }, 271 | "buffer-more-ints": { 272 | "version": "0.0.2", 273 | "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz", 274 | "integrity": "sha1-JrOIXRD6E9t/wBquOquHAZngEkw=" 275 | }, 276 | "buildmail": { 277 | "version": "4.0.1", 278 | "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-4.0.1.tgz", 279 | "integrity": "sha1-h393OLeHKYccmhBeO4N9K+EaenI=", 280 | "optional": true, 281 | "requires": { 282 | "addressparser": "1.0.1", 283 | "libbase64": "0.1.0", 284 | "libmime": "3.0.0", 285 | "libqp": "1.1.0", 286 | "nodemailer-fetch": "1.6.0", 287 | "nodemailer-shared": "1.1.0", 288 | "punycode": "1.4.1" 289 | } 290 | }, 291 | "builtin-modules": { 292 | "version": "1.1.1", 293 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 294 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" 295 | }, 296 | "bytes": { 297 | "version": "3.0.0", 298 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 299 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 300 | }, 301 | "callsites": { 302 | "version": "2.0.0", 303 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", 304 | "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" 305 | }, 306 | "caseless": { 307 | "version": "0.12.0", 308 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 309 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", 310 | "optional": true 311 | }, 312 | "chalk": { 313 | "version": "1.1.3", 314 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 315 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 316 | "optional": true, 317 | "requires": { 318 | "ansi-styles": "^2.2.1", 319 | "escape-string-regexp": "^1.0.2", 320 | "has-ansi": "^2.0.0", 321 | "strip-ansi": "^3.0.0", 322 | "supports-color": "^2.0.0" 323 | } 324 | }, 325 | "charenc": { 326 | "version": "0.0.2", 327 | "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", 328 | "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" 329 | }, 330 | "circular-json": { 331 | "version": "0.5.5", 332 | "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.5.tgz", 333 | "integrity": "sha512-13YaR6kiz0kBNmIVM87Io8Hp7bWOo4r61vkEANy8iH9R9bc6avud/1FT0SBpqR1RpIQADOh/Q+yHZDA1iL6ysA==" 334 | }, 335 | "clone-class": { 336 | "version": "0.6.19", 337 | "resolved": "https://registry.npmjs.org/clone-class/-/clone-class-0.6.19.tgz", 338 | "integrity": "sha512-Kp1aai587Kb7dVqYIV1nH6g/qrZZzZB1qat4CXURWQGlmK65/y8FQIwace3pD9j+ZG66TVcqggthZ0NB4sP9Xw==" 339 | }, 340 | "co": { 341 | "version": "4.6.0", 342 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 343 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", 344 | "optional": true 345 | }, 346 | "combined-stream": { 347 | "version": "1.0.6", 348 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", 349 | "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", 350 | "requires": { 351 | "delayed-stream": "~1.0.0" 352 | } 353 | }, 354 | "commander": { 355 | "version": "2.16.0", 356 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", 357 | "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==", 358 | "optional": true 359 | }, 360 | "content-disposition": { 361 | "version": "0.5.2", 362 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 363 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 364 | }, 365 | "content-type": { 366 | "version": "1.0.4", 367 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 368 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 369 | }, 370 | "cookie": { 371 | "version": "0.3.1", 372 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 373 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 374 | }, 375 | "cookie-signature": { 376 | "version": "1.0.6", 377 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 378 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 379 | }, 380 | "core-util-is": { 381 | "version": "1.0.2", 382 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 383 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 384 | }, 385 | "cron-parser": { 386 | "version": "2.5.0", 387 | "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-2.5.0.tgz", 388 | "integrity": "sha512-gzmXu16/prizIbKPPKJo+WgBpV7k8Rxxu9FgaANW+vx5DebCXavfRqbROjKkr9ETvVPqs+IO+NXj4GG/eLf8zQ==", 389 | "requires": { 390 | "is-nan": "^1.2.1", 391 | "moment-timezone": "^0.5.0" 392 | } 393 | }, 394 | "crypt": { 395 | "version": "0.0.2", 396 | "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", 397 | "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" 398 | }, 399 | "cryptiles": { 400 | "version": "2.0.5", 401 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", 402 | "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", 403 | "optional": true, 404 | "requires": { 405 | "boom": "2.x.x" 406 | } 407 | }, 408 | "cuid": { 409 | "version": "2.1.1", 410 | "resolved": "https://registry.npmjs.org/cuid/-/cuid-2.1.1.tgz", 411 | "integrity": "sha512-rF0ShwHPLQi5X1aNbQUw3IsCTtA+a0FeZsmmfJsHZxuOBgBk4BAGDDb55K+GCQSzqrSDZH0vQ7OIs38DfDlkqA==" 412 | }, 413 | "dashdash": { 414 | "version": "1.14.1", 415 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 416 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 417 | "optional": true, 418 | "requires": { 419 | "assert-plus": "^1.0.0" 420 | } 421 | }, 422 | "data-uri-to-buffer": { 423 | "version": "1.2.0", 424 | "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", 425 | "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", 426 | "optional": true 427 | }, 428 | "date-format": { 429 | "version": "1.2.0", 430 | "resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz", 431 | "integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg=" 432 | }, 433 | "dayjs": { 434 | "version": "1.7.0", 435 | "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.7.0.tgz", 436 | "integrity": "sha512-6Hz3dWjCBzDG85WYgjGe3btPlheoZC54jYfZLWaSnFn9C9h/EpYEUI2D9apDQbHVB82CSNlSZFLWwH2p9zShVQ==" 437 | }, 438 | "debug": { 439 | "version": "3.1.0", 440 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 441 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 442 | "requires": { 443 | "ms": "2.0.0" 444 | } 445 | }, 446 | "deep-is": { 447 | "version": "0.1.3", 448 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 449 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 450 | "optional": true 451 | }, 452 | "define-properties": { 453 | "version": "1.1.2", 454 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", 455 | "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", 456 | "requires": { 457 | "foreach": "^2.0.5", 458 | "object-keys": "^1.0.8" 459 | } 460 | }, 461 | "degenerator": { 462 | "version": "1.0.4", 463 | "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", 464 | "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", 465 | "optional": true, 466 | "requires": { 467 | "ast-types": "0.x.x", 468 | "escodegen": "1.x.x", 469 | "esprima": "3.x.x" 470 | } 471 | }, 472 | "delayed-stream": { 473 | "version": "1.0.0", 474 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 475 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 476 | }, 477 | "depd": { 478 | "version": "1.1.2", 479 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 480 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 481 | }, 482 | "destroy": { 483 | "version": "1.0.4", 484 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 485 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 486 | }, 487 | "double-ended-queue": { 488 | "version": "2.1.0-0", 489 | "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", 490 | "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=", 491 | "optional": true 492 | }, 493 | "ecc-jsbn": { 494 | "version": "0.1.1", 495 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", 496 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", 497 | "optional": true, 498 | "requires": { 499 | "jsbn": "~0.1.0" 500 | } 501 | }, 502 | "ee-first": { 503 | "version": "1.1.1", 504 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 505 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 506 | }, 507 | "encodeurl": { 508 | "version": "1.0.2", 509 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 510 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 511 | }, 512 | "err-code": { 513 | "version": "1.1.2", 514 | "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", 515 | "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=" 516 | }, 517 | "error-ex": { 518 | "version": "1.3.2", 519 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", 520 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", 521 | "requires": { 522 | "is-arrayish": "^0.2.1" 523 | } 524 | }, 525 | "es6-promise": { 526 | "version": "4.2.4", 527 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", 528 | "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==" 529 | }, 530 | "es6-promisify": { 531 | "version": "5.0.0", 532 | "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", 533 | "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", 534 | "requires": { 535 | "es6-promise": "^4.0.3" 536 | } 537 | }, 538 | "escape-html": { 539 | "version": "1.0.3", 540 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 541 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 542 | }, 543 | "escape-string-regexp": { 544 | "version": "1.0.5", 545 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 546 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 547 | "optional": true 548 | }, 549 | "escodegen": { 550 | "version": "1.10.0", 551 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.10.0.tgz", 552 | "integrity": "sha512-fjUOf8johsv23WuIKdNQU4P9t9jhQ4Qzx6pC2uW890OloK3Zs1ZAoCNpg/2larNF501jLl3UNy0kIRcF6VI22g==", 553 | "optional": true, 554 | "requires": { 555 | "esprima": "^3.1.3", 556 | "estraverse": "^4.2.0", 557 | "esutils": "^2.0.2", 558 | "optionator": "^0.8.1", 559 | "source-map": "~0.6.1" 560 | } 561 | }, 562 | "esprima": { 563 | "version": "3.1.3", 564 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", 565 | "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" 566 | }, 567 | "estraverse": { 568 | "version": "4.2.0", 569 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", 570 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", 571 | "optional": true 572 | }, 573 | "esutils": { 574 | "version": "2.0.2", 575 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 576 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 577 | "optional": true 578 | }, 579 | "etag": { 580 | "version": "1.8.1", 581 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 582 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 583 | }, 584 | "express": { 585 | "version": "4.16.3", 586 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", 587 | "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", 588 | "requires": { 589 | "accepts": "~1.3.5", 590 | "array-flatten": "1.1.1", 591 | "body-parser": "1.18.2", 592 | "content-disposition": "0.5.2", 593 | "content-type": "~1.0.4", 594 | "cookie": "0.3.1", 595 | "cookie-signature": "1.0.6", 596 | "debug": "2.6.9", 597 | "depd": "~1.1.2", 598 | "encodeurl": "~1.0.2", 599 | "escape-html": "~1.0.3", 600 | "etag": "~1.8.1", 601 | "finalhandler": "1.1.1", 602 | "fresh": "0.5.2", 603 | "merge-descriptors": "1.0.1", 604 | "methods": "~1.1.2", 605 | "on-finished": "~2.3.0", 606 | "parseurl": "~1.3.2", 607 | "path-to-regexp": "0.1.7", 608 | "proxy-addr": "~2.0.3", 609 | "qs": "6.5.1", 610 | "range-parser": "~1.2.0", 611 | "safe-buffer": "5.1.1", 612 | "send": "0.16.2", 613 | "serve-static": "1.13.2", 614 | "setprototypeof": "1.1.0", 615 | "statuses": "~1.4.0", 616 | "type-is": "~1.6.16", 617 | "utils-merge": "1.0.1", 618 | "vary": "~1.1.2" 619 | }, 620 | "dependencies": { 621 | "array-flatten": { 622 | "version": "1.1.1", 623 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 624 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 625 | }, 626 | "debug": { 627 | "version": "2.6.9", 628 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 629 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 630 | "requires": { 631 | "ms": "2.0.0" 632 | } 633 | }, 634 | "qs": { 635 | "version": "6.5.1", 636 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", 637 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" 638 | }, 639 | "safe-buffer": { 640 | "version": "5.1.1", 641 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 642 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" 643 | }, 644 | "statuses": { 645 | "version": "1.4.0", 646 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 647 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" 648 | } 649 | } 650 | }, 651 | "extend": { 652 | "version": "3.0.1", 653 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", 654 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" 655 | }, 656 | "extsprintf": { 657 | "version": "1.3.0", 658 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 659 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 660 | }, 661 | "fast-deep-equal": { 662 | "version": "1.1.0", 663 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 664 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", 665 | "optional": true 666 | }, 667 | "fast-json-stable-stringify": { 668 | "version": "2.0.0", 669 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 670 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", 671 | "optional": true 672 | }, 673 | "fast-levenshtein": { 674 | "version": "2.0.6", 675 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 676 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 677 | "optional": true 678 | }, 679 | "file-box": { 680 | "version": "0.8.22", 681 | "resolved": "https://registry.npmjs.org/file-box/-/file-box-0.8.22.tgz", 682 | "integrity": "sha512-PeGJP2e0vdssO2TQqAk34P8dPrF7WpbiTCiKkb+++e8ysyJ+EBnX8wNouq0yPQG/p/5dpQxDwoQ37C2f++MiuA==", 683 | "requires": { 684 | "mime": "^2.3.1" 685 | } 686 | }, 687 | "file-uri-to-path": { 688 | "version": "1.0.0", 689 | "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", 690 | "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", 691 | "optional": true 692 | }, 693 | "finalhandler": { 694 | "version": "1.1.1", 695 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", 696 | "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", 697 | "requires": { 698 | "debug": "2.6.9", 699 | "encodeurl": "~1.0.2", 700 | "escape-html": "~1.0.3", 701 | "on-finished": "~2.3.0", 702 | "parseurl": "~1.3.2", 703 | "statuses": "~1.4.0", 704 | "unpipe": "~1.0.0" 705 | }, 706 | "dependencies": { 707 | "debug": { 708 | "version": "2.6.9", 709 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 710 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 711 | "requires": { 712 | "ms": "2.0.0" 713 | } 714 | }, 715 | "statuses": { 716 | "version": "1.4.0", 717 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 718 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" 719 | } 720 | } 721 | }, 722 | "find-up": { 723 | "version": "2.1.0", 724 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", 725 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", 726 | "requires": { 727 | "locate-path": "^2.0.0" 728 | } 729 | }, 730 | "follow-redirects": { 731 | "version": "1.5.0", 732 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.0.tgz", 733 | "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==", 734 | "requires": { 735 | "debug": "^3.1.0" 736 | } 737 | }, 738 | "foreach": { 739 | "version": "2.0.5", 740 | "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", 741 | "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" 742 | }, 743 | "forever-agent": { 744 | "version": "0.6.1", 745 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 746 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", 747 | "optional": true 748 | }, 749 | "form-data": { 750 | "version": "2.3.2", 751 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", 752 | "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", 753 | "optional": true, 754 | "requires": { 755 | "asynckit": "^0.4.0", 756 | "combined-stream": "1.0.6", 757 | "mime-types": "^2.1.12" 758 | } 759 | }, 760 | "forwarded": { 761 | "version": "0.1.2", 762 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 763 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 764 | }, 765 | "fresh": { 766 | "version": "0.5.2", 767 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 768 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 769 | }, 770 | "fs-extra": { 771 | "version": "6.0.1", 772 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", 773 | "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", 774 | "requires": { 775 | "graceful-fs": "^4.1.2", 776 | "jsonfile": "^4.0.0", 777 | "universalify": "^0.1.0" 778 | } 779 | }, 780 | "ftp": { 781 | "version": "0.3.10", 782 | "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", 783 | "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", 784 | "optional": true, 785 | "requires": { 786 | "readable-stream": "1.1.x", 787 | "xregexp": "2.0.0" 788 | } 789 | }, 790 | "generate-function": { 791 | "version": "2.0.0", 792 | "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", 793 | "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", 794 | "optional": true 795 | }, 796 | "generate-object-property": { 797 | "version": "1.2.0", 798 | "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", 799 | "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", 800 | "optional": true, 801 | "requires": { 802 | "is-property": "^1.0.0" 803 | } 804 | }, 805 | "get-uri": { 806 | "version": "2.0.2", 807 | "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.2.tgz", 808 | "integrity": "sha512-ZD325dMZOgerGqF/rF6vZXyFGTAay62svjQIT+X/oU2PtxYpFxvSkbsdi+oxIrsNxlZVd4y8wUDqkaExWTI/Cw==", 809 | "optional": true, 810 | "requires": { 811 | "data-uri-to-buffer": "1", 812 | "debug": "2", 813 | "extend": "3", 814 | "file-uri-to-path": "1", 815 | "ftp": "~0.3.10", 816 | "readable-stream": "2" 817 | }, 818 | "dependencies": { 819 | "debug": { 820 | "version": "2.6.9", 821 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 822 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 823 | "optional": true, 824 | "requires": { 825 | "ms": "2.0.0" 826 | } 827 | }, 828 | "isarray": { 829 | "version": "1.0.0", 830 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 831 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 832 | "optional": true 833 | }, 834 | "process-nextick-args": { 835 | "version": "2.0.0", 836 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 837 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", 838 | "optional": true 839 | }, 840 | "readable-stream": { 841 | "version": "2.3.6", 842 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 843 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 844 | "optional": true, 845 | "requires": { 846 | "core-util-is": "~1.0.0", 847 | "inherits": "~2.0.3", 848 | "isarray": "~1.0.0", 849 | "process-nextick-args": "~2.0.0", 850 | "safe-buffer": "~5.1.1", 851 | "string_decoder": "~1.1.1", 852 | "util-deprecate": "~1.0.1" 853 | } 854 | }, 855 | "string_decoder": { 856 | "version": "1.1.1", 857 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 858 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 859 | "optional": true, 860 | "requires": { 861 | "safe-buffer": "~5.1.0" 862 | } 863 | } 864 | } 865 | }, 866 | "getpass": { 867 | "version": "0.1.7", 868 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 869 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 870 | "optional": true, 871 | "requires": { 872 | "assert-plus": "^1.0.0" 873 | } 874 | }, 875 | "graceful-fs": { 876 | "version": "4.1.11", 877 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 878 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" 879 | }, 880 | "har-schema": { 881 | "version": "2.0.0", 882 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 883 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", 884 | "optional": true 885 | }, 886 | "har-validator": { 887 | "version": "5.0.3", 888 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", 889 | "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", 890 | "optional": true, 891 | "requires": { 892 | "ajv": "^5.1.0", 893 | "har-schema": "^2.0.0" 894 | } 895 | }, 896 | "has-ansi": { 897 | "version": "2.0.0", 898 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 899 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 900 | "optional": true, 901 | "requires": { 902 | "ansi-regex": "^2.0.0" 903 | } 904 | }, 905 | "hawk": { 906 | "version": "3.1.3", 907 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", 908 | "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", 909 | "optional": true, 910 | "requires": { 911 | "boom": "2.x.x", 912 | "cryptiles": "2.x.x", 913 | "hoek": "2.x.x", 914 | "sntp": "1.x.x" 915 | } 916 | }, 917 | "hipchat-notifier": { 918 | "version": "1.1.0", 919 | "resolved": "https://registry.npmjs.org/hipchat-notifier/-/hipchat-notifier-1.1.0.tgz", 920 | "integrity": "sha1-ttJJdVQ3wZEII2d5nTupoPI7Ix4=", 921 | "optional": true, 922 | "requires": { 923 | "lodash": "^4.0.0", 924 | "request": "^2.0.0" 925 | } 926 | }, 927 | "hoek": { 928 | "version": "2.16.3", 929 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", 930 | "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" 931 | }, 932 | "hosted-git-info": { 933 | "version": "2.7.1", 934 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", 935 | "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" 936 | }, 937 | "hot-import": { 938 | "version": "0.2.1", 939 | "resolved": "https://registry.npmjs.org/hot-import/-/hot-import-0.2.1.tgz", 940 | "integrity": "sha512-MIdoLT7IQFuzcwBVCpX2gquX9k60HICiyJFgQZqhGKl7WUTdOR98C0Y8Jc6FaRKt9NnQGCOqah3HTkrftqAaIw==", 941 | "requires": { 942 | "brolog": "^1.2.6", 943 | "callsites": "^2.0.0", 944 | "read-pkg-up": "^2.0.0" 945 | }, 946 | "dependencies": { 947 | "read-pkg-up": { 948 | "version": "2.0.0", 949 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", 950 | "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", 951 | "requires": { 952 | "find-up": "^2.0.0", 953 | "read-pkg": "^2.0.0" 954 | } 955 | } 956 | } 957 | }, 958 | "http-errors": { 959 | "version": "1.6.3", 960 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", 961 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", 962 | "requires": { 963 | "depd": "~1.1.2", 964 | "inherits": "2.0.3", 965 | "setprototypeof": "1.1.0", 966 | "statuses": ">= 1.4.0 < 2" 967 | } 968 | }, 969 | "http-proxy-agent": { 970 | "version": "2.1.0", 971 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", 972 | "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", 973 | "requires": { 974 | "agent-base": "4", 975 | "debug": "3.1.0" 976 | } 977 | }, 978 | "http-signature": { 979 | "version": "1.2.0", 980 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 981 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 982 | "optional": true, 983 | "requires": { 984 | "assert-plus": "^1.0.0", 985 | "jsprim": "^1.2.2", 986 | "sshpk": "^1.7.0" 987 | } 988 | }, 989 | "httpntlm": { 990 | "version": "1.6.1", 991 | "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz", 992 | "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=", 993 | "requires": { 994 | "httpreq": ">=0.4.22", 995 | "underscore": "~1.7.0" 996 | } 997 | }, 998 | "httpreq": { 999 | "version": "0.4.24", 1000 | "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz", 1001 | "integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=" 1002 | }, 1003 | "https-proxy-agent": { 1004 | "version": "2.2.1", 1005 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", 1006 | "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", 1007 | "requires": { 1008 | "agent-base": "^4.1.0", 1009 | "debug": "^3.1.0" 1010 | } 1011 | }, 1012 | "iconv-lite": { 1013 | "version": "0.4.23", 1014 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", 1015 | "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", 1016 | "requires": { 1017 | "safer-buffer": ">= 2.1.2 < 3" 1018 | } 1019 | }, 1020 | "inflection": { 1021 | "version": "1.12.0", 1022 | "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", 1023 | "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=", 1024 | "optional": true 1025 | }, 1026 | "inherits": { 1027 | "version": "2.0.3", 1028 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 1029 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 1030 | }, 1031 | "ip": { 1032 | "version": "1.1.5", 1033 | "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", 1034 | "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" 1035 | }, 1036 | "ipaddr.js": { 1037 | "version": "1.6.0", 1038 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", 1039 | "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=" 1040 | }, 1041 | "is-arrayish": { 1042 | "version": "0.2.1", 1043 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 1044 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" 1045 | }, 1046 | "is-buffer": { 1047 | "version": "1.1.6", 1048 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 1049 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 1050 | }, 1051 | "is-builtin-module": { 1052 | "version": "1.0.0", 1053 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 1054 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", 1055 | "requires": { 1056 | "builtin-modules": "^1.0.0" 1057 | } 1058 | }, 1059 | "is-my-ip-valid": { 1060 | "version": "1.0.0", 1061 | "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", 1062 | "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", 1063 | "optional": true 1064 | }, 1065 | "is-my-json-valid": { 1066 | "version": "2.17.2", 1067 | "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz", 1068 | "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", 1069 | "optional": true, 1070 | "requires": { 1071 | "generate-function": "^2.0.0", 1072 | "generate-object-property": "^1.1.0", 1073 | "is-my-ip-valid": "^1.0.0", 1074 | "jsonpointer": "^4.0.0", 1075 | "xtend": "^4.0.0" 1076 | } 1077 | }, 1078 | "is-nan": { 1079 | "version": "1.2.1", 1080 | "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.2.1.tgz", 1081 | "integrity": "sha1-n69ltvttskt/XAYoR16nH5iEAeI=", 1082 | "requires": { 1083 | "define-properties": "^1.1.1" 1084 | } 1085 | }, 1086 | "is-property": { 1087 | "version": "1.0.2", 1088 | "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", 1089 | "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", 1090 | "optional": true 1091 | }, 1092 | "is-stream": { 1093 | "version": "1.1.0", 1094 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 1095 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", 1096 | "optional": true 1097 | }, 1098 | "is-typedarray": { 1099 | "version": "1.0.0", 1100 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 1101 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", 1102 | "optional": true 1103 | }, 1104 | "isarray": { 1105 | "version": "0.0.1", 1106 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 1107 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", 1108 | "optional": true 1109 | }, 1110 | "isstream": { 1111 | "version": "0.1.2", 1112 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 1113 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", 1114 | "optional": true 1115 | }, 1116 | "jsbn": { 1117 | "version": "0.1.1", 1118 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 1119 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 1120 | "optional": true 1121 | }, 1122 | "json-parse-better-errors": { 1123 | "version": "1.0.2", 1124 | "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", 1125 | "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" 1126 | }, 1127 | "json-schema": { 1128 | "version": "0.2.3", 1129 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 1130 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", 1131 | "optional": true 1132 | }, 1133 | "json-schema-traverse": { 1134 | "version": "0.3.1", 1135 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 1136 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", 1137 | "optional": true 1138 | }, 1139 | "json-stringify-safe": { 1140 | "version": "5.0.1", 1141 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 1142 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 1143 | }, 1144 | "jsonfile": { 1145 | "version": "4.0.0", 1146 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 1147 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", 1148 | "requires": { 1149 | "graceful-fs": "^4.1.6" 1150 | } 1151 | }, 1152 | "jsonpointer": { 1153 | "version": "4.0.1", 1154 | "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", 1155 | "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", 1156 | "optional": true 1157 | }, 1158 | "jsprim": { 1159 | "version": "1.4.1", 1160 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 1161 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 1162 | "optional": true, 1163 | "requires": { 1164 | "assert-plus": "1.0.0", 1165 | "extsprintf": "1.3.0", 1166 | "json-schema": "0.2.3", 1167 | "verror": "1.10.0" 1168 | } 1169 | }, 1170 | "kareem": { 1171 | "version": "2.2.1", 1172 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.2.1.tgz", 1173 | "integrity": "sha512-xpDFy8OxkFM+vK6pXy6JmH92ibeEFUuDWzas5M9L7MzVmHW3jzwAHxodCPV/BYkf4A31bVDLyonrMfp9RXb/oA==" 1174 | }, 1175 | "keypress": { 1176 | "version": "0.1.0", 1177 | "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz", 1178 | "integrity": "sha1-SjGI1CkbZrT2XtuZ+AaqmuKTWSo=" 1179 | }, 1180 | "levn": { 1181 | "version": "0.3.0", 1182 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 1183 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 1184 | "optional": true, 1185 | "requires": { 1186 | "prelude-ls": "~1.1.2", 1187 | "type-check": "~0.3.2" 1188 | } 1189 | }, 1190 | "libbase64": { 1191 | "version": "0.1.0", 1192 | "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz", 1193 | "integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=" 1194 | }, 1195 | "libmime": { 1196 | "version": "3.0.0", 1197 | "resolved": "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz", 1198 | "integrity": "sha1-UaGp50SOy9Ms2lRCFnW7IbwJPaY=", 1199 | "requires": { 1200 | "iconv-lite": "0.4.15", 1201 | "libbase64": "0.1.0", 1202 | "libqp": "1.1.0" 1203 | }, 1204 | "dependencies": { 1205 | "iconv-lite": { 1206 | "version": "0.4.15", 1207 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", 1208 | "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=" 1209 | } 1210 | } 1211 | }, 1212 | "libqp": { 1213 | "version": "1.1.0", 1214 | "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz", 1215 | "integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=" 1216 | }, 1217 | "load-json-file": { 1218 | "version": "2.0.0", 1219 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", 1220 | "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", 1221 | "requires": { 1222 | "graceful-fs": "^4.1.2", 1223 | "parse-json": "^2.2.0", 1224 | "pify": "^2.0.0", 1225 | "strip-bom": "^3.0.0" 1226 | } 1227 | }, 1228 | "locate-path": { 1229 | "version": "2.0.0", 1230 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", 1231 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", 1232 | "requires": { 1233 | "p-locate": "^2.0.0", 1234 | "path-exists": "^3.0.0" 1235 | } 1236 | }, 1237 | "lodash": { 1238 | "version": "4.17.10", 1239 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", 1240 | "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" 1241 | }, 1242 | "lodash.get": { 1243 | "version": "4.4.2", 1244 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 1245 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" 1246 | }, 1247 | "log4js": { 1248 | "version": "2.11.0", 1249 | "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.11.0.tgz", 1250 | "integrity": "sha512-z1XdwyGFg8/WGkOyF6DPJjivCWNLKrklGdViywdYnSKOvgtEBo2UyEMZS5sD2mZrQlU3TvO8wDWLc8mzE1ncBQ==", 1251 | "requires": { 1252 | "amqplib": "^0.5.2", 1253 | "axios": "^0.15.3", 1254 | "circular-json": "^0.5.4", 1255 | "date-format": "^1.2.0", 1256 | "debug": "^3.1.0", 1257 | "hipchat-notifier": "^1.1.0", 1258 | "loggly": "^1.1.0", 1259 | "mailgun-js": "^0.18.0", 1260 | "nodemailer": "^2.5.0", 1261 | "redis": "^2.7.1", 1262 | "semver": "^5.5.0", 1263 | "slack-node": "~0.2.0", 1264 | "streamroller": "0.7.0" 1265 | }, 1266 | "dependencies": { 1267 | "axios": { 1268 | "version": "0.15.3", 1269 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz", 1270 | "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=", 1271 | "optional": true, 1272 | "requires": { 1273 | "follow-redirects": "1.0.0" 1274 | } 1275 | }, 1276 | "follow-redirects": { 1277 | "version": "1.0.0", 1278 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", 1279 | "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=", 1280 | "optional": true, 1281 | "requires": { 1282 | "debug": "^2.2.0" 1283 | }, 1284 | "dependencies": { 1285 | "debug": { 1286 | "version": "2.6.9", 1287 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1288 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1289 | "optional": true, 1290 | "requires": { 1291 | "ms": "2.0.0" 1292 | } 1293 | } 1294 | } 1295 | } 1296 | } 1297 | }, 1298 | "loggly": { 1299 | "version": "1.1.1", 1300 | "resolved": "https://registry.npmjs.org/loggly/-/loggly-1.1.1.tgz", 1301 | "integrity": "sha1-Cg/B0/o6XsRP3HuJe+uipGlc6+4=", 1302 | "optional": true, 1303 | "requires": { 1304 | "json-stringify-safe": "5.0.x", 1305 | "request": "2.75.x", 1306 | "timespan": "2.3.x" 1307 | }, 1308 | "dependencies": { 1309 | "assert-plus": { 1310 | "version": "0.2.0", 1311 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", 1312 | "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", 1313 | "optional": true 1314 | }, 1315 | "aws-sign2": { 1316 | "version": "0.6.0", 1317 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", 1318 | "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", 1319 | "optional": true 1320 | }, 1321 | "caseless": { 1322 | "version": "0.11.0", 1323 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", 1324 | "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", 1325 | "optional": true 1326 | }, 1327 | "form-data": { 1328 | "version": "2.0.0", 1329 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz", 1330 | "integrity": "sha1-bwrrrcxdoWwT4ezBETfYX5uIOyU=", 1331 | "optional": true, 1332 | "requires": { 1333 | "asynckit": "^0.4.0", 1334 | "combined-stream": "^1.0.5", 1335 | "mime-types": "^2.1.11" 1336 | } 1337 | }, 1338 | "har-validator": { 1339 | "version": "2.0.6", 1340 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", 1341 | "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", 1342 | "optional": true, 1343 | "requires": { 1344 | "chalk": "^1.1.1", 1345 | "commander": "^2.9.0", 1346 | "is-my-json-valid": "^2.12.4", 1347 | "pinkie-promise": "^2.0.0" 1348 | } 1349 | }, 1350 | "http-signature": { 1351 | "version": "1.1.1", 1352 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", 1353 | "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", 1354 | "optional": true, 1355 | "requires": { 1356 | "assert-plus": "^0.2.0", 1357 | "jsprim": "^1.2.2", 1358 | "sshpk": "^1.7.0" 1359 | } 1360 | }, 1361 | "node-uuid": { 1362 | "version": "1.4.8", 1363 | "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", 1364 | "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", 1365 | "optional": true 1366 | }, 1367 | "qs": { 1368 | "version": "6.2.3", 1369 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", 1370 | "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", 1371 | "optional": true 1372 | }, 1373 | "request": { 1374 | "version": "2.75.0", 1375 | "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz", 1376 | "integrity": "sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM=", 1377 | "optional": true, 1378 | "requires": { 1379 | "aws-sign2": "~0.6.0", 1380 | "aws4": "^1.2.1", 1381 | "bl": "~1.1.2", 1382 | "caseless": "~0.11.0", 1383 | "combined-stream": "~1.0.5", 1384 | "extend": "~3.0.0", 1385 | "forever-agent": "~0.6.1", 1386 | "form-data": "~2.0.0", 1387 | "har-validator": "~2.0.6", 1388 | "hawk": "~3.1.3", 1389 | "http-signature": "~1.1.0", 1390 | "is-typedarray": "~1.0.0", 1391 | "isstream": "~0.1.2", 1392 | "json-stringify-safe": "~5.0.1", 1393 | "mime-types": "~2.1.7", 1394 | "node-uuid": "~1.4.7", 1395 | "oauth-sign": "~0.8.1", 1396 | "qs": "~6.2.0", 1397 | "stringstream": "~0.0.4", 1398 | "tough-cookie": "~2.3.0", 1399 | "tunnel-agent": "~0.4.1" 1400 | } 1401 | }, 1402 | "tunnel-agent": { 1403 | "version": "0.4.3", 1404 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", 1405 | "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", 1406 | "optional": true 1407 | } 1408 | } 1409 | }, 1410 | "long-timeout": { 1411 | "version": "0.1.1", 1412 | "resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz", 1413 | "integrity": "sha1-lyHXiLR+C8taJMLivuGg2lXatRQ=" 1414 | }, 1415 | "lru-cache": { 1416 | "version": "4.1.3", 1417 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", 1418 | "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", 1419 | "requires": { 1420 | "pseudomap": "^1.0.2", 1421 | "yallist": "^2.1.2" 1422 | } 1423 | }, 1424 | "mailcomposer": { 1425 | "version": "4.0.1", 1426 | "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz", 1427 | "integrity": "sha1-DhxEsqB890DuF9wUm6AJ8Zyt/rQ=", 1428 | "optional": true, 1429 | "requires": { 1430 | "buildmail": "4.0.1", 1431 | "libmime": "3.0.0" 1432 | } 1433 | }, 1434 | "mailgun-js": { 1435 | "version": "0.18.1", 1436 | "resolved": "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.18.1.tgz", 1437 | "integrity": "sha512-lvuMP14u24HS2uBsJEnzSyPMxzU2b99tQsIx1o6QNjqxjk8b3WvR+vq5oG1mjqz/IBYo+5gF+uSoDS0RkMVHmg==", 1438 | "optional": true, 1439 | "requires": { 1440 | "async": "~2.6.0", 1441 | "debug": "~3.1.0", 1442 | "form-data": "~2.3.0", 1443 | "inflection": "~1.12.0", 1444 | "is-stream": "^1.1.0", 1445 | "path-proxy": "~1.0.0", 1446 | "promisify-call": "^2.0.2", 1447 | "proxy-agent": "~3.0.0", 1448 | "tsscmp": "~1.0.0" 1449 | } 1450 | }, 1451 | "md5": { 1452 | "version": "2.2.1", 1453 | "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", 1454 | "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", 1455 | "requires": { 1456 | "charenc": "~0.0.1", 1457 | "crypt": "~0.0.1", 1458 | "is-buffer": "~1.1.1" 1459 | } 1460 | }, 1461 | "media-typer": { 1462 | "version": "0.3.0", 1463 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1464 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 1465 | }, 1466 | "memory-card": { 1467 | "version": "0.4.9", 1468 | "resolved": "https://registry.npmjs.org/memory-card/-/memory-card-0.4.9.tgz", 1469 | "integrity": "sha512-qL1BGBf8Eb4+V/MP3WgTW9LfDrPbRU4CEz1KYWddF/npNgbpi+rLdoDaJ7uEH6RDCyM12ce7I1R3SznyHnKHnw==", 1470 | "requires": { 1471 | "brolog": "^1.6.2" 1472 | } 1473 | }, 1474 | "merge-descriptors": { 1475 | "version": "1.0.1", 1476 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1477 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 1478 | }, 1479 | "methods": { 1480 | "version": "1.1.2", 1481 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1482 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 1483 | }, 1484 | "mime": { 1485 | "version": "2.3.1", 1486 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", 1487 | "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==" 1488 | }, 1489 | "mime-db": { 1490 | "version": "1.33.0", 1491 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", 1492 | "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" 1493 | }, 1494 | "mime-types": { 1495 | "version": "2.1.18", 1496 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", 1497 | "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", 1498 | "requires": { 1499 | "mime-db": "~1.33.0" 1500 | } 1501 | }, 1502 | "minimist": { 1503 | "version": "0.0.8", 1504 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1505 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 1506 | }, 1507 | "mkdirp": { 1508 | "version": "0.5.1", 1509 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1510 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1511 | "requires": { 1512 | "minimist": "0.0.8" 1513 | } 1514 | }, 1515 | "moment": { 1516 | "version": "2.22.2", 1517 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", 1518 | "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" 1519 | }, 1520 | "moment-timezone": { 1521 | "version": "0.5.21", 1522 | "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.21.tgz", 1523 | "integrity": "sha512-j96bAh4otsgj3lKydm3K7kdtA3iKf2m6MY2iSYCzCm5a1zmHo1g+aK3068dDEeocLZQIS9kU8bsdQHLqEvgW0A==", 1524 | "requires": { 1525 | "moment": ">= 2.9.0" 1526 | } 1527 | }, 1528 | "mongodb": { 1529 | "version": "3.0.10", 1530 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.0.10.tgz", 1531 | "integrity": "sha512-jy9s4FgcM4rl8sHNETYHGeWcuRh9AlwQCUuMiTj041t/HD02HwyFgmm2VZdd9/mA9YNHaUJLqj0tzBx2QFivtg==", 1532 | "requires": { 1533 | "mongodb-core": "3.0.9" 1534 | } 1535 | }, 1536 | "mongodb-core": { 1537 | "version": "3.0.9", 1538 | "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.0.9.tgz", 1539 | "integrity": "sha512-buOWjdLLBlEqjHDeHYSXqXx173wHMVp7bafhdHxSjxWdB9V6Ri4myTqxjYZwL/eGFZxvd8oRQSuhwuIDbaaB+g==", 1540 | "requires": { 1541 | "bson": "~1.0.4", 1542 | "require_optional": "^1.0.1" 1543 | } 1544 | }, 1545 | "mongoose": { 1546 | "version": "5.1.7", 1547 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.1.7.tgz", 1548 | "integrity": "sha512-9zus8yEovPqLo3S2iXz2Dg9YJAo8xG7m161abqJbUNIqZYjvpPwjmWAs6ChZnxEUpTYFOve//ljvyA5V5D9sNw==", 1549 | "requires": { 1550 | "async": "2.6.1", 1551 | "bson": "~1.0.5", 1552 | "kareem": "2.2.1", 1553 | "lodash.get": "4.4.2", 1554 | "mongodb": "3.0.10", 1555 | "mongoose-legacy-pluralize": "1.0.2", 1556 | "mpath": "0.4.1", 1557 | "mquery": "3.0.0", 1558 | "ms": "2.0.0", 1559 | "regexp-clone": "0.0.1", 1560 | "sliced": "1.0.1" 1561 | } 1562 | }, 1563 | "mongoose-legacy-pluralize": { 1564 | "version": "1.0.2", 1565 | "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", 1566 | "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" 1567 | }, 1568 | "mpath": { 1569 | "version": "0.4.1", 1570 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.4.1.tgz", 1571 | "integrity": "sha512-NNY/MpBkALb9jJmjpBlIi6GRoLveLUM0pJzgbp9vY9F7IQEb/HREC/nxrixechcQwd1NevOhJnWWV8QQQRE+OA==" 1572 | }, 1573 | "mquery": { 1574 | "version": "3.0.0", 1575 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.0.0.tgz", 1576 | "integrity": "sha512-WL1Lk8v4l8VFSSwN3yCzY9TXw+fKVYKn6f+w86TRzOLSE8k1yTgGaLBPUByJQi8VcLbOdnUneFV/y3Kv874pnQ==", 1577 | "requires": { 1578 | "bluebird": "3.5.0", 1579 | "debug": "2.6.9", 1580 | "regexp-clone": "0.0.1", 1581 | "sliced": "0.0.5" 1582 | }, 1583 | "dependencies": { 1584 | "bluebird": { 1585 | "version": "3.5.0", 1586 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", 1587 | "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" 1588 | }, 1589 | "debug": { 1590 | "version": "2.6.9", 1591 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1592 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1593 | "requires": { 1594 | "ms": "2.0.0" 1595 | } 1596 | }, 1597 | "sliced": { 1598 | "version": "0.0.5", 1599 | "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", 1600 | "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8=" 1601 | } 1602 | } 1603 | }, 1604 | "ms": { 1605 | "version": "2.0.0", 1606 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1607 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1608 | }, 1609 | "nan": { 1610 | "version": "2.10.0", 1611 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", 1612 | "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", 1613 | "optional": true 1614 | }, 1615 | "negotiator": { 1616 | "version": "0.6.1", 1617 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 1618 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 1619 | }, 1620 | "netmask": { 1621 | "version": "1.0.6", 1622 | "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", 1623 | "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=", 1624 | "optional": true 1625 | }, 1626 | "node-schedule": { 1627 | "version": "1.3.0", 1628 | "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-1.3.0.tgz", 1629 | "integrity": "sha512-NNwO9SUPjBwFmPh3vXiPVEhJLn4uqYmZYvJV358SRGM06BR4UoIqxJpeJwDDXB6atULsgQA97MfD1zMd5xsu+A==", 1630 | "requires": { 1631 | "cron-parser": "^2.4.0", 1632 | "long-timeout": "0.1.1", 1633 | "sorted-array-functions": "^1.0.0" 1634 | } 1635 | }, 1636 | "nodejieba": { 1637 | "version": "2.2.6", 1638 | "resolved": "https://registry.npmjs.org/nodejieba/-/nodejieba-2.2.6.tgz", 1639 | "integrity": "sha1-F81BZwW3sBwGLmzZ1xebMEU+tKM=", 1640 | "optional": true, 1641 | "requires": { 1642 | "nan": "~2.10.0" 1643 | } 1644 | }, 1645 | "nodemailer": { 1646 | "version": "2.7.2", 1647 | "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-2.7.2.tgz", 1648 | "integrity": "sha1-8kLmSa7q45tsftdA73sGHEBNMPk=", 1649 | "optional": true, 1650 | "requires": { 1651 | "libmime": "3.0.0", 1652 | "mailcomposer": "4.0.1", 1653 | "nodemailer-direct-transport": "3.3.2", 1654 | "nodemailer-shared": "1.1.0", 1655 | "nodemailer-smtp-pool": "2.8.2", 1656 | "nodemailer-smtp-transport": "2.7.2", 1657 | "socks": "1.1.9" 1658 | }, 1659 | "dependencies": { 1660 | "socks": { 1661 | "version": "1.1.9", 1662 | "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.9.tgz", 1663 | "integrity": "sha1-Yo1+TQSRJDVEWsC25Fk3bLPm1pE=", 1664 | "optional": true, 1665 | "requires": { 1666 | "ip": "^1.1.2", 1667 | "smart-buffer": "^1.0.4" 1668 | } 1669 | } 1670 | } 1671 | }, 1672 | "nodemailer-direct-transport": { 1673 | "version": "3.3.2", 1674 | "resolved": "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-3.3.2.tgz", 1675 | "integrity": "sha1-6W+vuQNYVglH5WkBfZfmBzilCoY=", 1676 | "optional": true, 1677 | "requires": { 1678 | "nodemailer-shared": "1.1.0", 1679 | "smtp-connection": "2.12.0" 1680 | } 1681 | }, 1682 | "nodemailer-fetch": { 1683 | "version": "1.6.0", 1684 | "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz", 1685 | "integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q=" 1686 | }, 1687 | "nodemailer-shared": { 1688 | "version": "1.1.0", 1689 | "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz", 1690 | "integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=", 1691 | "requires": { 1692 | "nodemailer-fetch": "1.6.0" 1693 | } 1694 | }, 1695 | "nodemailer-smtp-pool": { 1696 | "version": "2.8.2", 1697 | "resolved": "https://registry.npmjs.org/nodemailer-smtp-pool/-/nodemailer-smtp-pool-2.8.2.tgz", 1698 | "integrity": "sha1-LrlNbPhXgLG0clzoU7nL1ejajHI=", 1699 | "optional": true, 1700 | "requires": { 1701 | "nodemailer-shared": "1.1.0", 1702 | "nodemailer-wellknown": "0.1.10", 1703 | "smtp-connection": "2.12.0" 1704 | } 1705 | }, 1706 | "nodemailer-smtp-transport": { 1707 | "version": "2.7.2", 1708 | "resolved": "https://registry.npmjs.org/nodemailer-smtp-transport/-/nodemailer-smtp-transport-2.7.2.tgz", 1709 | "integrity": "sha1-A9ccdjFPFKx9vHvwM6am0W1n+3c=", 1710 | "optional": true, 1711 | "requires": { 1712 | "nodemailer-shared": "1.1.0", 1713 | "nodemailer-wellknown": "0.1.10", 1714 | "smtp-connection": "2.12.0" 1715 | } 1716 | }, 1717 | "nodemailer-wellknown": { 1718 | "version": "0.1.10", 1719 | "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz", 1720 | "integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=" 1721 | }, 1722 | "nop": { 1723 | "version": "1.0.0", 1724 | "resolved": "https://registry.npmjs.org/nop/-/nop-1.0.0.tgz", 1725 | "integrity": "sha1-y0bPfgFXSqY5CFgUn2aJev5Tyco=" 1726 | }, 1727 | "normalize-package-data": { 1728 | "version": "2.4.0", 1729 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", 1730 | "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", 1731 | "requires": { 1732 | "hosted-git-info": "^2.1.4", 1733 | "is-builtin-module": "^1.0.0", 1734 | "semver": "2 || 3 || 4 || 5", 1735 | "validate-npm-package-license": "^3.0.1" 1736 | } 1737 | }, 1738 | "npm-programmatic": { 1739 | "version": "0.0.10", 1740 | "resolved": "https://registry.npmjs.org/npm-programmatic/-/npm-programmatic-0.0.10.tgz", 1741 | "integrity": "sha512-SklCZ26RRGi7hLIz/oaSnHy8ZT0gh8r6N3FMuKRye3ZcRo4HI/saldc8b7OqlY/Ov8FXnA1+I+Od+WtesWEp2Q==", 1742 | "requires": { 1743 | "bluebird": "^3.4.1" 1744 | } 1745 | }, 1746 | "oauth-sign": { 1747 | "version": "0.8.2", 1748 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", 1749 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", 1750 | "optional": true 1751 | }, 1752 | "object-assign": { 1753 | "version": "4.1.1", 1754 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1755 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 1756 | }, 1757 | "object-keys": { 1758 | "version": "1.0.12", 1759 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", 1760 | "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" 1761 | }, 1762 | "on-finished": { 1763 | "version": "2.3.0", 1764 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1765 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1766 | "requires": { 1767 | "ee-first": "1.1.1" 1768 | } 1769 | }, 1770 | "optionator": { 1771 | "version": "0.8.2", 1772 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 1773 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 1774 | "optional": true, 1775 | "requires": { 1776 | "deep-is": "~0.1.3", 1777 | "fast-levenshtein": "~2.0.4", 1778 | "levn": "~0.3.0", 1779 | "prelude-ls": "~1.1.2", 1780 | "type-check": "~0.3.2", 1781 | "wordwrap": "~1.0.0" 1782 | } 1783 | }, 1784 | "p-limit": { 1785 | "version": "1.3.0", 1786 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", 1787 | "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", 1788 | "requires": { 1789 | "p-try": "^1.0.0" 1790 | } 1791 | }, 1792 | "p-locate": { 1793 | "version": "2.0.0", 1794 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", 1795 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", 1796 | "requires": { 1797 | "p-limit": "^1.1.0" 1798 | } 1799 | }, 1800 | "p-try": { 1801 | "version": "1.0.0", 1802 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", 1803 | "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" 1804 | }, 1805 | "pac-proxy-agent": { 1806 | "version": "2.0.2", 1807 | "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-2.0.2.tgz", 1808 | "integrity": "sha512-cDNAN1Ehjbf5EHkNY5qnRhGPUCp6SnpyVof5fRzN800QV1Y2OkzbH9rmjZkbBRa8igof903yOnjIl6z0SlAhxA==", 1809 | "optional": true, 1810 | "requires": { 1811 | "agent-base": "^4.2.0", 1812 | "debug": "^3.1.0", 1813 | "get-uri": "^2.0.0", 1814 | "http-proxy-agent": "^2.1.0", 1815 | "https-proxy-agent": "^2.2.1", 1816 | "pac-resolver": "^3.0.0", 1817 | "raw-body": "^2.2.0", 1818 | "socks-proxy-agent": "^3.0.0" 1819 | }, 1820 | "dependencies": { 1821 | "socks-proxy-agent": { 1822 | "version": "3.0.1", 1823 | "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz", 1824 | "integrity": "sha512-ZwEDymm204mTzvdqyUqOdovVr2YRd2NYskrYrF2LXyZ9qDiMAoFESGK8CRphiO7rtbo2Y757k2Nia3x2hGtalA==", 1825 | "optional": true, 1826 | "requires": { 1827 | "agent-base": "^4.1.0", 1828 | "socks": "^1.1.10" 1829 | } 1830 | } 1831 | } 1832 | }, 1833 | "pac-resolver": { 1834 | "version": "3.0.0", 1835 | "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", 1836 | "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", 1837 | "optional": true, 1838 | "requires": { 1839 | "co": "^4.6.0", 1840 | "degenerator": "^1.0.4", 1841 | "ip": "^1.1.5", 1842 | "netmask": "^1.0.6", 1843 | "thunkify": "^2.1.2" 1844 | } 1845 | }, 1846 | "parse-json": { 1847 | "version": "2.2.0", 1848 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", 1849 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", 1850 | "requires": { 1851 | "error-ex": "^1.2.0" 1852 | } 1853 | }, 1854 | "parseurl": { 1855 | "version": "1.3.2", 1856 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 1857 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 1858 | }, 1859 | "path-exists": { 1860 | "version": "3.0.0", 1861 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1862 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" 1863 | }, 1864 | "path-proxy": { 1865 | "version": "1.0.0", 1866 | "resolved": "https://registry.npmjs.org/path-proxy/-/path-proxy-1.0.0.tgz", 1867 | "integrity": "sha1-GOijaFn8nS8aU7SN7hOFQ8Ag3l4=", 1868 | "optional": true, 1869 | "requires": { 1870 | "inflection": "~1.3.0" 1871 | }, 1872 | "dependencies": { 1873 | "inflection": { 1874 | "version": "1.3.8", 1875 | "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.3.8.tgz", 1876 | "integrity": "sha1-y9Fg2p91sUw8xjV41POWeEvzAU4=", 1877 | "optional": true 1878 | } 1879 | } 1880 | }, 1881 | "path-to-regexp": { 1882 | "version": "0.1.7", 1883 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1884 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 1885 | }, 1886 | "path-type": { 1887 | "version": "2.0.0", 1888 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", 1889 | "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", 1890 | "requires": { 1891 | "pify": "^2.0.0" 1892 | } 1893 | }, 1894 | "performance-now": { 1895 | "version": "2.1.0", 1896 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 1897 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", 1898 | "optional": true 1899 | }, 1900 | "pify": { 1901 | "version": "2.3.0", 1902 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1903 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" 1904 | }, 1905 | "pinkie": { 1906 | "version": "2.0.4", 1907 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1908 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", 1909 | "optional": true 1910 | }, 1911 | "pinkie-promise": { 1912 | "version": "2.0.1", 1913 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1914 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 1915 | "optional": true, 1916 | "requires": { 1917 | "pinkie": "^2.0.0" 1918 | } 1919 | }, 1920 | "pinyin": { 1921 | "version": "2.8.3", 1922 | "resolved": "https://registry.npmjs.org/pinyin/-/pinyin-2.8.3.tgz", 1923 | "integrity": "sha1-MBzLQ1jM/oAlI8S9ZAphK+5NfEs=", 1924 | "requires": { 1925 | "commander": "~1.1.1", 1926 | "nodejieba": "^2.2.1", 1927 | "object-assign": "^4.0.1" 1928 | }, 1929 | "dependencies": { 1930 | "commander": { 1931 | "version": "1.1.1", 1932 | "resolved": "https://registry.npmjs.org/commander/-/commander-1.1.1.tgz", 1933 | "integrity": "sha1-UNFlGGiuYOzP8KLZ80WVN2vGsEE=", 1934 | "requires": { 1935 | "keypress": "0.1.x" 1936 | } 1937 | } 1938 | } 1939 | }, 1940 | "pkg-dir": { 1941 | "version": "3.0.0", 1942 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", 1943 | "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", 1944 | "requires": { 1945 | "find-up": "^3.0.0" 1946 | }, 1947 | "dependencies": { 1948 | "find-up": { 1949 | "version": "3.0.0", 1950 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 1951 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 1952 | "requires": { 1953 | "locate-path": "^3.0.0" 1954 | } 1955 | }, 1956 | "locate-path": { 1957 | "version": "3.0.0", 1958 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 1959 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 1960 | "requires": { 1961 | "p-locate": "^3.0.0", 1962 | "path-exists": "^3.0.0" 1963 | } 1964 | }, 1965 | "p-limit": { 1966 | "version": "2.0.0", 1967 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", 1968 | "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", 1969 | "requires": { 1970 | "p-try": "^2.0.0" 1971 | } 1972 | }, 1973 | "p-locate": { 1974 | "version": "3.0.0", 1975 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 1976 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 1977 | "requires": { 1978 | "p-limit": "^2.0.0" 1979 | } 1980 | }, 1981 | "p-try": { 1982 | "version": "2.0.0", 1983 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", 1984 | "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==" 1985 | } 1986 | } 1987 | }, 1988 | "prelude-ls": { 1989 | "version": "1.1.2", 1990 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1991 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" 1992 | }, 1993 | "process-nextick-args": { 1994 | "version": "1.0.7", 1995 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", 1996 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", 1997 | "optional": true 1998 | }, 1999 | "promise-retry": { 2000 | "version": "1.1.1", 2001 | "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", 2002 | "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", 2003 | "requires": { 2004 | "err-code": "^1.0.0", 2005 | "retry": "^0.10.0" 2006 | } 2007 | }, 2008 | "promisify-call": { 2009 | "version": "2.0.4", 2010 | "resolved": "https://registry.npmjs.org/promisify-call/-/promisify-call-2.0.4.tgz", 2011 | "integrity": "sha1-1IwtRWUszM1SgB3ey9UzptS9X7o=", 2012 | "optional": true, 2013 | "requires": { 2014 | "with-callback": "^1.0.2" 2015 | } 2016 | }, 2017 | "proxy-addr": { 2018 | "version": "2.0.3", 2019 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", 2020 | "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", 2021 | "requires": { 2022 | "forwarded": "~0.1.2", 2023 | "ipaddr.js": "1.6.0" 2024 | } 2025 | }, 2026 | "proxy-agent": { 2027 | "version": "3.0.1", 2028 | "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-3.0.1.tgz", 2029 | "integrity": "sha512-mAZexaz9ZxQhYPWfAjzlrloEjW+JHiBFryE4AJXFDTnaXfmH/FKqC1swTRKuEPbHWz02flQNXFOyDUF7zfEG6A==", 2030 | "optional": true, 2031 | "requires": { 2032 | "agent-base": "^4.2.0", 2033 | "debug": "^3.1.0", 2034 | "http-proxy-agent": "^2.1.0", 2035 | "https-proxy-agent": "^2.2.1", 2036 | "lru-cache": "^4.1.2", 2037 | "pac-proxy-agent": "^2.0.1", 2038 | "proxy-from-env": "^1.0.0", 2039 | "socks-proxy-agent": "^4.0.1" 2040 | } 2041 | }, 2042 | "proxy-from-env": { 2043 | "version": "1.0.0", 2044 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", 2045 | "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", 2046 | "optional": true 2047 | }, 2048 | "pseudomap": { 2049 | "version": "1.0.2", 2050 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 2051 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" 2052 | }, 2053 | "punycode": { 2054 | "version": "1.4.1", 2055 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 2056 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", 2057 | "optional": true 2058 | }, 2059 | "qr-image": { 2060 | "version": "3.2.0", 2061 | "resolved": "https://registry.npmjs.org/qr-image/-/qr-image-3.2.0.tgz", 2062 | "integrity": "sha1-n6gpW+rlDEoUnPn5CaHbRkqGcug=" 2063 | }, 2064 | "qrcode-terminal": { 2065 | "version": "0.12.0", 2066 | "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz", 2067 | "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==" 2068 | }, 2069 | "qs": { 2070 | "version": "6.5.2", 2071 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 2072 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", 2073 | "optional": true 2074 | }, 2075 | "range-parser": { 2076 | "version": "1.2.0", 2077 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 2078 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 2079 | }, 2080 | "raven": { 2081 | "version": "2.6.3", 2082 | "resolved": "https://registry.npmjs.org/raven/-/raven-2.6.3.tgz", 2083 | "integrity": "sha512-bKre7qlDW+y1+G2bUtCuntdDYc8o5v1T233t0vmJfbj8ttGOgLrGRlYB8saelVMW9KUAJNLrhFkAKOwFWFJonw==", 2084 | "requires": { 2085 | "cookie": "0.3.1", 2086 | "md5": "^2.2.1", 2087 | "stack-trace": "0.0.10", 2088 | "timed-out": "4.0.1", 2089 | "uuid": "3.0.0" 2090 | }, 2091 | "dependencies": { 2092 | "uuid": { 2093 | "version": "3.0.0", 2094 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz", 2095 | "integrity": "sha1-Zyj8BFnEUNeWqZwxg3VpvfZy1yg=" 2096 | } 2097 | } 2098 | }, 2099 | "raw-body": { 2100 | "version": "2.3.3", 2101 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", 2102 | "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", 2103 | "optional": true, 2104 | "requires": { 2105 | "bytes": "3.0.0", 2106 | "http-errors": "1.6.3", 2107 | "iconv-lite": "0.4.23", 2108 | "unpipe": "1.0.0" 2109 | } 2110 | }, 2111 | "read-pkg": { 2112 | "version": "2.0.0", 2113 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", 2114 | "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", 2115 | "requires": { 2116 | "load-json-file": "^2.0.0", 2117 | "normalize-package-data": "^2.3.2", 2118 | "path-type": "^2.0.0" 2119 | } 2120 | }, 2121 | "read-pkg-up": { 2122 | "version": "4.0.0", 2123 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", 2124 | "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", 2125 | "requires": { 2126 | "find-up": "^3.0.0", 2127 | "read-pkg": "^3.0.0" 2128 | }, 2129 | "dependencies": { 2130 | "find-up": { 2131 | "version": "3.0.0", 2132 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 2133 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 2134 | "requires": { 2135 | "locate-path": "^3.0.0" 2136 | } 2137 | }, 2138 | "load-json-file": { 2139 | "version": "4.0.0", 2140 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", 2141 | "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", 2142 | "requires": { 2143 | "graceful-fs": "^4.1.2", 2144 | "parse-json": "^4.0.0", 2145 | "pify": "^3.0.0", 2146 | "strip-bom": "^3.0.0" 2147 | } 2148 | }, 2149 | "locate-path": { 2150 | "version": "3.0.0", 2151 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 2152 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 2153 | "requires": { 2154 | "p-locate": "^3.0.0", 2155 | "path-exists": "^3.0.0" 2156 | } 2157 | }, 2158 | "p-limit": { 2159 | "version": "2.0.0", 2160 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", 2161 | "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", 2162 | "requires": { 2163 | "p-try": "^2.0.0" 2164 | } 2165 | }, 2166 | "p-locate": { 2167 | "version": "3.0.0", 2168 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 2169 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 2170 | "requires": { 2171 | "p-limit": "^2.0.0" 2172 | } 2173 | }, 2174 | "p-try": { 2175 | "version": "2.0.0", 2176 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", 2177 | "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==" 2178 | }, 2179 | "parse-json": { 2180 | "version": "4.0.0", 2181 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", 2182 | "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", 2183 | "requires": { 2184 | "error-ex": "^1.3.1", 2185 | "json-parse-better-errors": "^1.0.1" 2186 | } 2187 | }, 2188 | "path-type": { 2189 | "version": "3.0.0", 2190 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", 2191 | "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", 2192 | "requires": { 2193 | "pify": "^3.0.0" 2194 | } 2195 | }, 2196 | "pify": { 2197 | "version": "3.0.0", 2198 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 2199 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" 2200 | }, 2201 | "read-pkg": { 2202 | "version": "3.0.0", 2203 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", 2204 | "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", 2205 | "requires": { 2206 | "load-json-file": "^4.0.0", 2207 | "normalize-package-data": "^2.3.2", 2208 | "path-type": "^3.0.0" 2209 | } 2210 | } 2211 | } 2212 | }, 2213 | "readable-stream": { 2214 | "version": "1.1.14", 2215 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 2216 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 2217 | "optional": true, 2218 | "requires": { 2219 | "core-util-is": "~1.0.0", 2220 | "inherits": "~2.0.1", 2221 | "isarray": "0.0.1", 2222 | "string_decoder": "~0.10.x" 2223 | } 2224 | }, 2225 | "redis": { 2226 | "version": "2.8.0", 2227 | "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", 2228 | "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", 2229 | "optional": true, 2230 | "requires": { 2231 | "double-ended-queue": "^2.1.0-0", 2232 | "redis-commands": "^1.2.0", 2233 | "redis-parser": "^2.6.0" 2234 | } 2235 | }, 2236 | "redis-commands": { 2237 | "version": "1.3.5", 2238 | "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", 2239 | "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==", 2240 | "optional": true 2241 | }, 2242 | "redis-parser": { 2243 | "version": "2.6.0", 2244 | "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", 2245 | "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=", 2246 | "optional": true 2247 | }, 2248 | "regexp-clone": { 2249 | "version": "0.0.1", 2250 | "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", 2251 | "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" 2252 | }, 2253 | "request": { 2254 | "version": "2.87.0", 2255 | "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", 2256 | "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", 2257 | "optional": true, 2258 | "requires": { 2259 | "aws-sign2": "~0.7.0", 2260 | "aws4": "^1.6.0", 2261 | "caseless": "~0.12.0", 2262 | "combined-stream": "~1.0.5", 2263 | "extend": "~3.0.1", 2264 | "forever-agent": "~0.6.1", 2265 | "form-data": "~2.3.1", 2266 | "har-validator": "~5.0.3", 2267 | "http-signature": "~1.2.0", 2268 | "is-typedarray": "~1.0.0", 2269 | "isstream": "~0.1.2", 2270 | "json-stringify-safe": "~5.0.1", 2271 | "mime-types": "~2.1.17", 2272 | "oauth-sign": "~0.8.2", 2273 | "performance-now": "^2.1.0", 2274 | "qs": "~6.5.1", 2275 | "safe-buffer": "^5.1.1", 2276 | "tough-cookie": "~2.3.3", 2277 | "tunnel-agent": "^0.6.0", 2278 | "uuid": "^3.1.0" 2279 | } 2280 | }, 2281 | "requestretry": { 2282 | "version": "1.13.0", 2283 | "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz", 2284 | "integrity": "sha512-Lmh9qMvnQXADGAQxsXHP4rbgO6pffCfuR8XUBdP9aitJcLQJxhp7YZK4xAVYXnPJ5E52mwrfiKQtKonPL8xsmg==", 2285 | "optional": true, 2286 | "requires": { 2287 | "extend": "^3.0.0", 2288 | "lodash": "^4.15.0", 2289 | "request": "^2.74.0", 2290 | "when": "^3.7.7" 2291 | } 2292 | }, 2293 | "require_optional": { 2294 | "version": "1.0.1", 2295 | "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", 2296 | "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", 2297 | "requires": { 2298 | "resolve-from": "^2.0.0", 2299 | "semver": "^5.1.0" 2300 | } 2301 | }, 2302 | "resolve-from": { 2303 | "version": "2.0.0", 2304 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", 2305 | "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" 2306 | }, 2307 | "retry": { 2308 | "version": "0.10.1", 2309 | "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", 2310 | "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=" 2311 | }, 2312 | "rx-queue": { 2313 | "version": "0.4.26", 2314 | "resolved": "https://registry.npmjs.org/rx-queue/-/rx-queue-0.4.26.tgz", 2315 | "integrity": "sha512-uJtwyp4DRQwJBITyMyQxVarrjQRu31npaiMgyr3VcasRTKZ6m7pvdd6fAoZcmfpuAyfWQjp4EYco7VIxz9SpQA==" 2316 | }, 2317 | "rxjs": { 2318 | "version": "6.2.1", 2319 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.1.tgz", 2320 | "integrity": "sha512-OwMxHxmnmHTUpgO+V7dZChf3Tixf4ih95cmXjzzadULziVl/FKhHScGLj4goEw9weePVOH2Q0+GcCBUhKCZc/g==", 2321 | "requires": { 2322 | "tslib": "^1.9.0" 2323 | } 2324 | }, 2325 | "safe-buffer": { 2326 | "version": "5.1.2", 2327 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 2328 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 2329 | }, 2330 | "safer-buffer": { 2331 | "version": "2.1.2", 2332 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 2333 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 2334 | }, 2335 | "semver": { 2336 | "version": "5.5.0", 2337 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", 2338 | "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" 2339 | }, 2340 | "send": { 2341 | "version": "0.16.2", 2342 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", 2343 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", 2344 | "requires": { 2345 | "debug": "2.6.9", 2346 | "depd": "~1.1.2", 2347 | "destroy": "~1.0.4", 2348 | "encodeurl": "~1.0.2", 2349 | "escape-html": "~1.0.3", 2350 | "etag": "~1.8.1", 2351 | "fresh": "0.5.2", 2352 | "http-errors": "~1.6.2", 2353 | "mime": "1.4.1", 2354 | "ms": "2.0.0", 2355 | "on-finished": "~2.3.0", 2356 | "range-parser": "~1.2.0", 2357 | "statuses": "~1.4.0" 2358 | }, 2359 | "dependencies": { 2360 | "debug": { 2361 | "version": "2.6.9", 2362 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 2363 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 2364 | "requires": { 2365 | "ms": "2.0.0" 2366 | } 2367 | }, 2368 | "mime": { 2369 | "version": "1.4.1", 2370 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", 2371 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" 2372 | }, 2373 | "statuses": { 2374 | "version": "1.4.0", 2375 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 2376 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" 2377 | } 2378 | } 2379 | }, 2380 | "serve-static": { 2381 | "version": "1.13.2", 2382 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", 2383 | "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", 2384 | "requires": { 2385 | "encodeurl": "~1.0.2", 2386 | "escape-html": "~1.0.3", 2387 | "parseurl": "~1.3.2", 2388 | "send": "0.16.2" 2389 | } 2390 | }, 2391 | "setprototypeof": { 2392 | "version": "1.1.0", 2393 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 2394 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" 2395 | }, 2396 | "slack-node": { 2397 | "version": "0.2.0", 2398 | "resolved": "https://registry.npmjs.org/slack-node/-/slack-node-0.2.0.tgz", 2399 | "integrity": "sha1-3kuN3aqLeT9h29KTgQT9q/N9+jA=", 2400 | "optional": true, 2401 | "requires": { 2402 | "requestretry": "^1.2.2" 2403 | } 2404 | }, 2405 | "sliced": { 2406 | "version": "1.0.1", 2407 | "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", 2408 | "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" 2409 | }, 2410 | "smart-buffer": { 2411 | "version": "1.1.15", 2412 | "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", 2413 | "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=", 2414 | "optional": true 2415 | }, 2416 | "smtp-connection": { 2417 | "version": "2.12.0", 2418 | "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz", 2419 | "integrity": "sha1-1275EnyyPCJZ7bHoNJwujV4tdME=", 2420 | "requires": { 2421 | "httpntlm": "1.6.1", 2422 | "nodemailer-shared": "1.1.0" 2423 | } 2424 | }, 2425 | "sntp": { 2426 | "version": "1.0.9", 2427 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", 2428 | "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", 2429 | "optional": true, 2430 | "requires": { 2431 | "hoek": "2.x.x" 2432 | } 2433 | }, 2434 | "socks": { 2435 | "version": "1.1.10", 2436 | "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.10.tgz", 2437 | "integrity": "sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=", 2438 | "optional": true, 2439 | "requires": { 2440 | "ip": "^1.1.4", 2441 | "smart-buffer": "^1.0.13" 2442 | } 2443 | }, 2444 | "socks-proxy-agent": { 2445 | "version": "4.0.1", 2446 | "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz", 2447 | "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", 2448 | "optional": true, 2449 | "requires": { 2450 | "agent-base": "~4.2.0", 2451 | "socks": "~2.2.0" 2452 | }, 2453 | "dependencies": { 2454 | "smart-buffer": { 2455 | "version": "4.0.1", 2456 | "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.1.tgz", 2457 | "integrity": "sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg==", 2458 | "optional": true 2459 | }, 2460 | "socks": { 2461 | "version": "2.2.1", 2462 | "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.1.tgz", 2463 | "integrity": "sha512-0GabKw7n9mI46vcNrVfs0o6XzWzjVa3h6GaSo2UPxtWAROXUWavfJWh1M4PR5tnE0dcnQXZIDFP4yrAysLze/w==", 2464 | "optional": true, 2465 | "requires": { 2466 | "ip": "^1.1.5", 2467 | "smart-buffer": "^4.0.1" 2468 | } 2469 | } 2470 | } 2471 | }, 2472 | "sorted-array-functions": { 2473 | "version": "1.2.0", 2474 | "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.2.0.tgz", 2475 | "integrity": "sha512-sWpjPhIZJtqO77GN+LD8dDsDKcWZ9GCOJNqKzi1tvtjGIzwfoyuRH8S0psunmc6Z5P+qfDqztSbwYR5X/e1UTg==" 2476 | }, 2477 | "source-map": { 2478 | "version": "0.6.1", 2479 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 2480 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 2481 | "optional": true 2482 | }, 2483 | "spdx-correct": { 2484 | "version": "3.0.0", 2485 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", 2486 | "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", 2487 | "requires": { 2488 | "spdx-expression-parse": "^3.0.0", 2489 | "spdx-license-ids": "^3.0.0" 2490 | } 2491 | }, 2492 | "spdx-exceptions": { 2493 | "version": "2.1.0", 2494 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", 2495 | "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==" 2496 | }, 2497 | "spdx-expression-parse": { 2498 | "version": "3.0.0", 2499 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", 2500 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", 2501 | "requires": { 2502 | "spdx-exceptions": "^2.1.0", 2503 | "spdx-license-ids": "^3.0.0" 2504 | } 2505 | }, 2506 | "spdx-license-ids": { 2507 | "version": "3.0.0", 2508 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", 2509 | "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==" 2510 | }, 2511 | "sshpk": { 2512 | "version": "1.14.2", 2513 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", 2514 | "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", 2515 | "optional": true, 2516 | "requires": { 2517 | "asn1": "~0.2.3", 2518 | "assert-plus": "^1.0.0", 2519 | "bcrypt-pbkdf": "^1.0.0", 2520 | "dashdash": "^1.12.0", 2521 | "ecc-jsbn": "~0.1.1", 2522 | "getpass": "^0.1.1", 2523 | "jsbn": "~0.1.0", 2524 | "safer-buffer": "^2.0.2", 2525 | "tweetnacl": "~0.14.0" 2526 | } 2527 | }, 2528 | "stack-trace": { 2529 | "version": "0.0.10", 2530 | "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", 2531 | "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" 2532 | }, 2533 | "state-switch": { 2534 | "version": "0.6.2", 2535 | "resolved": "https://registry.npmjs.org/state-switch/-/state-switch-0.6.2.tgz", 2536 | "integrity": "sha512-Egnrw2tVi6xmbKMUVDAEfpe7GW1b7J4eikeTlNfmCyR+Rqe+14LNp8yv87cwPQcRNwYn7SDk0LOjywWUk4+Wfg==", 2537 | "requires": { 2538 | "nop": "^1.0.0" 2539 | } 2540 | }, 2541 | "statuses": { 2542 | "version": "1.5.0", 2543 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 2544 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 2545 | }, 2546 | "streamroller": { 2547 | "version": "0.7.0", 2548 | "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", 2549 | "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", 2550 | "requires": { 2551 | "date-format": "^1.2.0", 2552 | "debug": "^3.1.0", 2553 | "mkdirp": "^0.5.1", 2554 | "readable-stream": "^2.3.0" 2555 | }, 2556 | "dependencies": { 2557 | "isarray": { 2558 | "version": "1.0.0", 2559 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 2560 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 2561 | }, 2562 | "process-nextick-args": { 2563 | "version": "2.0.0", 2564 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 2565 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" 2566 | }, 2567 | "readable-stream": { 2568 | "version": "2.3.6", 2569 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 2570 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 2571 | "requires": { 2572 | "core-util-is": "~1.0.0", 2573 | "inherits": "~2.0.3", 2574 | "isarray": "~1.0.0", 2575 | "process-nextick-args": "~2.0.0", 2576 | "safe-buffer": "~5.1.1", 2577 | "string_decoder": "~1.1.1", 2578 | "util-deprecate": "~1.0.1" 2579 | } 2580 | }, 2581 | "string_decoder": { 2582 | "version": "1.1.1", 2583 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 2584 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 2585 | "requires": { 2586 | "safe-buffer": "~5.1.0" 2587 | } 2588 | } 2589 | } 2590 | }, 2591 | "string_decoder": { 2592 | "version": "0.10.31", 2593 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 2594 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", 2595 | "optional": true 2596 | }, 2597 | "stringstream": { 2598 | "version": "0.0.6", 2599 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", 2600 | "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", 2601 | "optional": true 2602 | }, 2603 | "strip-ansi": { 2604 | "version": "3.0.1", 2605 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 2606 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 2607 | "optional": true, 2608 | "requires": { 2609 | "ansi-regex": "^2.0.0" 2610 | } 2611 | }, 2612 | "strip-bom": { 2613 | "version": "3.0.0", 2614 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 2615 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" 2616 | }, 2617 | "supports-color": { 2618 | "version": "2.0.0", 2619 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 2620 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", 2621 | "optional": true 2622 | }, 2623 | "thunkify": { 2624 | "version": "2.1.2", 2625 | "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", 2626 | "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=", 2627 | "optional": true 2628 | }, 2629 | "timed-out": { 2630 | "version": "4.0.1", 2631 | "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", 2632 | "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" 2633 | }, 2634 | "timespan": { 2635 | "version": "2.3.0", 2636 | "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", 2637 | "integrity": "sha1-SQLOBAvRPYRcj1myfp1ZutbzmSk=", 2638 | "optional": true 2639 | }, 2640 | "tough-cookie": { 2641 | "version": "2.3.4", 2642 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", 2643 | "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", 2644 | "optional": true, 2645 | "requires": { 2646 | "punycode": "^1.4.1" 2647 | } 2648 | }, 2649 | "tslib": { 2650 | "version": "1.9.3", 2651 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", 2652 | "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" 2653 | }, 2654 | "tsscmp": { 2655 | "version": "1.0.5", 2656 | "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.5.tgz", 2657 | "integrity": "sha1-fcSjOvcVgatDN9qR2FylQn69mpc=", 2658 | "optional": true 2659 | }, 2660 | "tunnel-agent": { 2661 | "version": "0.6.0", 2662 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 2663 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 2664 | "optional": true, 2665 | "requires": { 2666 | "safe-buffer": "^5.0.1" 2667 | } 2668 | }, 2669 | "tweetnacl": { 2670 | "version": "0.14.5", 2671 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 2672 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 2673 | "optional": true 2674 | }, 2675 | "type-check": { 2676 | "version": "0.3.2", 2677 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 2678 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 2679 | "requires": { 2680 | "prelude-ls": "~1.1.2" 2681 | } 2682 | }, 2683 | "type-is": { 2684 | "version": "1.6.16", 2685 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", 2686 | "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", 2687 | "requires": { 2688 | "media-typer": "0.3.0", 2689 | "mime-types": "~2.1.18" 2690 | } 2691 | }, 2692 | "underscore": { 2693 | "version": "1.7.0", 2694 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", 2695 | "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=" 2696 | }, 2697 | "universalify": { 2698 | "version": "0.1.2", 2699 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 2700 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" 2701 | }, 2702 | "unpipe": { 2703 | "version": "1.0.0", 2704 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 2705 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 2706 | }, 2707 | "util-deprecate": { 2708 | "version": "1.0.2", 2709 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2710 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 2711 | }, 2712 | "utils-merge": { 2713 | "version": "1.0.1", 2714 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 2715 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 2716 | }, 2717 | "uuid": { 2718 | "version": "3.3.2", 2719 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", 2720 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", 2721 | "optional": true 2722 | }, 2723 | "validate-npm-package-license": { 2724 | "version": "3.0.3", 2725 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", 2726 | "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", 2727 | "requires": { 2728 | "spdx-correct": "^3.0.0", 2729 | "spdx-expression-parse": "^3.0.0" 2730 | } 2731 | }, 2732 | "vary": { 2733 | "version": "1.1.2", 2734 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 2735 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 2736 | }, 2737 | "verror": { 2738 | "version": "1.10.0", 2739 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 2740 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 2741 | "optional": true, 2742 | "requires": { 2743 | "assert-plus": "^1.0.0", 2744 | "core-util-is": "1.0.2", 2745 | "extsprintf": "^1.2.0" 2746 | } 2747 | }, 2748 | "watchdog": { 2749 | "version": "0.8.10", 2750 | "resolved": "https://registry.npmjs.org/watchdog/-/watchdog-0.8.10.tgz", 2751 | "integrity": "sha512-+R0gUqItx+iIEs3c4/q95gYyQq9cxqkD8j6bpDya4BLBgxsOP2m6n/M1rIYYLMXr5/nQLr4E3SeViXFFk9eJuA==", 2752 | "requires": { 2753 | "brolog": "^1.3.3" 2754 | } 2755 | }, 2756 | "wechaty": { 2757 | "version": "0.18.3", 2758 | "resolved": "https://registry.npmjs.org/wechaty/-/wechaty-0.18.3.tgz", 2759 | "integrity": "sha512-bODb5LNm4IiObuYnjbFQz6SsrFntCceNMNtA6hxDXBMu0hmPKSzepM7vD82cX4hQOZzel7Et4BXSumIjZRU3/Q==", 2760 | "requires": { 2761 | "array-flatten": "^2.1.1", 2762 | "brolog": "^1.8.1", 2763 | "clone-class": "^0.6.11", 2764 | "cuid": "^2.1.1", 2765 | "express": "^4.16.3", 2766 | "file-box": "^0.8.22", 2767 | "fs-extra": "^6.0.1", 2768 | "hot-import": "^0.2.1", 2769 | "memory-card": "^0.4.9", 2770 | "npm-programmatic": "0.0.10", 2771 | "pkg-dir": "^3.0.0", 2772 | "promise-retry": "^1.1.1", 2773 | "qr-image": "^3.2.0", 2774 | "raven": "^2.6.2", 2775 | "read-pkg-up": "^4.0.0", 2776 | "rx-queue": "^0.4.26", 2777 | "rxjs": "^6.1.0", 2778 | "state-switch": "^0.6.2", 2779 | "watchdog": "^0.8.1", 2780 | "wechaty-puppet": "^0.8.2", 2781 | "ws": "^5.2.0" 2782 | } 2783 | }, 2784 | "wechaty-puppet": { 2785 | "version": "0.8.2", 2786 | "resolved": "https://registry.npmjs.org/wechaty-puppet/-/wechaty-puppet-0.8.2.tgz", 2787 | "integrity": "sha512-n5C8MsPZ/cg4lXN36nAAdAxkz5MsyNmehCtCn+wu0d1zG+JfGbte2iDrAuAuA3Zb4/+sOuf8vcRB15NJeKpGmA==", 2788 | "requires": { 2789 | "brolog": "^1.6.5", 2790 | "hot-import": "^0.2.1", 2791 | "lru-cache": "^4.1.3", 2792 | "normalize-package-data": "^2.4.0", 2793 | "read-pkg-up": "^4.0.0", 2794 | "rx-queue": "^0.4.26", 2795 | "rxjs": "^6.2.1", 2796 | "semver": "^5.5.0", 2797 | "state-switch": "^0.6.2", 2798 | "watchdog": "^0.8.10" 2799 | } 2800 | }, 2801 | "when": { 2802 | "version": "3.7.8", 2803 | "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", 2804 | "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=", 2805 | "optional": true 2806 | }, 2807 | "with-callback": { 2808 | "version": "1.0.2", 2809 | "resolved": "https://registry.npmjs.org/with-callback/-/with-callback-1.0.2.tgz", 2810 | "integrity": "sha1-oJYpuakgAo1yFAT7Q1vc/1yRvCE=", 2811 | "optional": true 2812 | }, 2813 | "wordwrap": { 2814 | "version": "1.0.0", 2815 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 2816 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 2817 | "optional": true 2818 | }, 2819 | "ws": { 2820 | "version": "5.2.2", 2821 | "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", 2822 | "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", 2823 | "requires": { 2824 | "async-limiter": "~1.0.0" 2825 | } 2826 | }, 2827 | "xregexp": { 2828 | "version": "2.0.0", 2829 | "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", 2830 | "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", 2831 | "optional": true 2832 | }, 2833 | "xtend": { 2834 | "version": "4.0.1", 2835 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 2836 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", 2837 | "optional": true 2838 | }, 2839 | "yallist": { 2840 | "version": "2.1.2", 2841 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 2842 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" 2843 | } 2844 | } 2845 | } 2846 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wechatrobot", 3 | "version": "0.3.1", 4 | "description": "微信机器人,能够排忧解难,帮你处理大量的操作。也可以陪你聊天,获取想要的信息。", 5 | "main": "robot.js", 6 | "scripts": { 7 | "start": "node robot.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/BingKui/WeChatRobot.git" 12 | }, 13 | "keywords": [ 14 | "WeChat", 15 | "robot" 16 | ], 17 | "author": "康兵奎", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/BingKui/WeChatRobot/issues" 21 | }, 22 | "homepage": "https://github.com/BingKui/WeChatRobot#readme", 23 | "dependencies": { 24 | "axios": "^0.18.0", 25 | "dayjs": "^1.5.24", 26 | "file-box": "^0.8.22", 27 | "iconv-lite": "^0.4.23", 28 | "log4js": "^2.11.0", 29 | "mongoose": "^5.1.7", 30 | "node-schedule": "^1.3.0", 31 | "pinyin": "^2.8.3", 32 | "qrcode-terminal": "^0.12.0", 33 | "wechaty": "^0.18.3" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /plan.md: -------------------------------------------------------------------------------- 1 | # 高级功能规划 2 | 3 | **联动功能** 4 | 5 | - [ ] 查询天气后-询问是否开启每天天气推送-开启/不开启推送-设置推送城市(规划中) 6 | - [ ] 开启提醒功能-开启入睡提醒-其他类提醒-设置时间(规划中) 7 | - [ ] 支持联系上下文(待研究) 8 | 9 | **高级功能** 10 | 11 | - [ ] 消息轰炸: 12 | - [x] 能够预设轰炸消息队列,根据类别,设置不同的轰炸消息 13 | - [ ] 通过关键字+@用户开启,轰炸模式 14 | - [ ] 添加图灵测试反应(待研究) 15 | - [ ] 增加询问多次相同的信息时 回复不同的话语 16 | - [ ] 相同次数回答不同的话语(每个次数 根据不同的情况 根据不同的机器人状态 产生不同的回答) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /plan/v0.1.*.md: -------------------------------------------------------------------------------- 1 | # v0.1.*功能 2 | 3 | - [x] 保存聊天记录到本地文件 4 | - [x] 支持天气查询 5 | - [x] 支持讲笑话 6 | - [x] 支持问答 7 | - [x] 保存登录信息 8 | - [x] 接入 知心天气 api 9 | - [x] 支持群文明维护 10 | - [x] 支持群聊 @ 回答问题功能 11 | - [x] 支持自动添加好友 12 | - [x] 支持知识库内容回复 -------------------------------------------------------------------------------- /plan/v0.2.*.md: -------------------------------------------------------------------------------- 1 | # v0.2.*功能 2 | 3 | - [x] 项目重构,目录重构,功能拆分,工具编写 4 | - [x] 升级依赖库版本 5 | - [x] 保存聊天信息到 MongoDB 数据库 6 | - [x] 通过定时器,在每天晚上十二点换一个头像 7 | - [x] 定时每天早上9:30推送天气信息 8 | - [x] 在规定时间内,提醒用户休息 9 | - [x] 晚上00:00 - 7:00之后,收到个人发送的消息,提醒用户早点休息 10 | - [x] 中午12:30 - 14:00 收到消息,提醒中午休息 11 | - [x] 支持创建群聊 12 | - [x] 通过群名关键字,添加用户到指定群聊 13 | - [x] 支持在群聊中@一个或者多个人 14 | - [x] 添加人员到群聊 15 | - [x] 修改、获取群名称 16 | - [x] 支持被@后 回复 @ 17 | - [x] 支持发送图片等资源 18 | - [x] 给某个人发送消息、图片等 19 | - [x] 单聊,支持获取壁纸头像等消息发送 20 | - [x] 笑话功能 21 | - [x] 增加进入群聊欢迎,离开群聊提醒,修改群聊名称警告,并改回原名称 22 | - [x] 群秩序维护,@不良消息发送人,作出提醒 23 | - [x] 修改、获取群公告(规划功能场景,后续添加) 24 | - [x] 发送指定文字“进群”,拉用户进群聊“机器人测试群聊” -------------------------------------------------------------------------------- /plan/v0.3.*.md: -------------------------------------------------------------------------------- 1 | # v0.3.*功能规划 2 | 3 | - [ ] 知识库功能重构,支持多关键字匹配,回复答案(主要针对客服类群聊)- 单独项目实现相应功能、高级版功能 4 | - [x] 支持发送远程文件,生成远程文件 FileBox 5 | - [x] 支持计划任务,特定时间段回复特定的消息 6 | - [x] 每日份精品歌单推荐,网易云或者QQ音乐 7 | - [x] 最火动漫推荐 8 | - [x] 小程序推荐,推送小程序码 9 | - [ ] 删除好友:依赖 Wechaty 库的 v0.17.0 或者更高版本 10 | - [x] 实现后台爬虫,爬取需要的东西(详情见项目:[微信后台定时爬虫](https://github.com/BingKui/WeChatScheduleSpider)) 11 | - [ ] 好友信息,群聊信息保存进数据库(依赖 v0.17.0 及更高版本) 12 | - [ ] 删除群聊成员:仅限群主(规划功能场景,后续添加) 13 | - [ ] 获取、修改、删除联系人备注名称(规划功能场景,后续添加) 14 | - [ ] 增加根据天气信息,作出防晒、带伞、等操作(人性化提醒,优化项) 15 | - [ ] 群聊支持发送火热表情图片(斗图功能) 16 | - [ ] 吟诗作对,能够查询诗句,随机获取诗句,特定文字查询诗句 17 | - [ ] 批量发送消息(所有好友) 18 | - [x] 版本区分(基础版、高级版) -------------------------------------------------------------------------------- /plan/v0.4.*.md: -------------------------------------------------------------------------------- 1 | # v0.4.*功能规划 2 | 3 | - [ ] 群聊、单聊功能集合整理划分,后台控制支持哪些功能 4 | - [ ] 后台项目搭建、完成基础的数据添加和更新 5 | - [ ] 增加功能的设置,动态修改是否支持某项功能 6 | - [ ] 项目数据迁移至数据库接口获取 7 | - [ ] 消息等级划分,高级覆盖低级消息,避免消息重复 -------------------------------------------------------------------------------- /robot.js: -------------------------------------------------------------------------------- 1 | const { Wechaty } = require('wechaty'); 2 | const QrcodeTerminal = require('qrcode-terminal'); 3 | const { 4 | messageInfo, 5 | messageRecordInfo, 6 | } = require('./tools/messageTools.js'); 7 | 8 | const { contactInfo } = require('./tools/contactTools.js'); 9 | 10 | const { saveMessage } = require('./feature/mongodb.js'); 11 | 12 | const { 13 | groupMessage, 14 | groupJoinMessage, 15 | groupLeaveMessage, 16 | groupTopicChange, 17 | } = require('./feature/group.js'); 18 | 19 | const { singleMessage } = require('./feature/single.js'); 20 | 21 | const { isAutoChangeAvatar } = require('./config/config.js'); 22 | 23 | // 引入数据库链接文件 24 | require('./tools/mongo.js'); 25 | 26 | // 实例化机器人对象 27 | const bot = Wechaty.instance(); 28 | 29 | // 全局对象,保存当前登录的用户 30 | let userSelf = null; 31 | 32 | // 监听扫码登录方法 33 | bot.on('scan', (qrCode, statusCode) => { 34 | // 判断状态码 35 | if (!/201|200/.test(statusCode)) { 36 | QrcodeTerminal.generate(qrCode); 37 | console.log('扫描二维码登录~~~~'); 38 | } 39 | }); 40 | 41 | // 监听登录方法 42 | bot.on('login', async (userContact) => { 43 | userSelf = await contactInfo(userContact); 44 | console.log('登录成功,用户信息:', userSelf); 45 | // 是否开启每天自动修改头像 46 | if (isAutoChangeAvatar) { 47 | avatarAutoChange(userContact); 48 | } 49 | }) 50 | 51 | // 监听消息 52 | bot.on('message', async (message) => { 53 | console.log('有新消息~~~'); 54 | const info = await messageInfo(message); 55 | const infoRecord = messageRecordInfo(info); 56 | // 判断是否是个人类型的消息,如果不是,直接返回不做处理 57 | // 屏蔽公众号等发送过来的消息 58 | if (!info.sendInfo.isPerson) { 59 | return; 60 | } 61 | // 保存聊天消息 62 | saveMessage(infoRecord); 63 | // 判断消息来源 64 | if (info.isGroupMsg) { 65 | await groupMessage(message, info, userSelf); 66 | } else { 67 | await singleMessage(message, info); 68 | } 69 | }); 70 | 71 | // 监听添加好友 72 | bot.on('friendship', (friendship) => { 73 | // 无论什么信息,直接接受 74 | if (friendship) { 75 | friendship.accept(); 76 | } 77 | }); 78 | 79 | // 监听用户进入房间 80 | bot.on('room-join', async (room, inviterList, inviter) => { 81 | await groupJoinMessage(room, inviterList, inviter, userSelf); 82 | }); 83 | 84 | // 监听用户离开房间 85 | bot.on('room-leave', async (room, leaveList) => { 86 | await groupLeaveMessage(room, leaveList); 87 | }); 88 | 89 | // 监听房间名称修改事件 90 | bot.on('room-topic', async (room, topic, oldTopic, changer) => { 91 | await groupTopicChange(room, oldTopic, changer, userSelf); 92 | }); 93 | 94 | // 监听用户退出登录 95 | bot.on('logout', () => { 96 | userSelf = null; 97 | }); 98 | 99 | // 监听出错 100 | bot.on('error', (error) => { 101 | console.log('机器人出现错误:', error); 102 | }); 103 | 104 | // 开始运行 105 | bot.start(); -------------------------------------------------------------------------------- /test/baidu.test.js: -------------------------------------------------------------------------------- 1 | const LinkUrl = require('./url'); 2 | const { accessToken } = require('./token/accessToken'); 3 | const axios = require('axios'); 4 | const iconv = require('iconv-lite') 5 | const param = { 6 | "text": "康兵奎" 7 | }; 8 | // axios.post(`${LinkUrl.grammarAnalyze}?access_token=${accessToken}`, param).then((res) => { 9 | // console.log(res.data); 10 | // }).catch((err) => { 11 | // console.log(err); 12 | // }) 13 | 14 | // console.log(iconv.encode(JSON.stringify(param), 'GBK')); 15 | const _data = iconv.encode(JSON.stringify(param), 'GBK'); 16 | axios({ 17 | method: "post", 18 | url: `${LinkUrl.grammarAnalyze}?access_token=${accessToken}`, 19 | headers:{ 20 | 'Content-type': 'application/json' 21 | }, 22 | data: _data 23 | }).then((res) => { 24 | console.log('内容:', JSON.stringify(res.data)); 25 | const buffer = new Buffer(JSON.stringify(res.data)); 26 | // let buffer = new Buffer(res.data); 27 | let decodedBody = iconv.decode(buffer, 'GBK', { 28 | defaultEncoding: 'GBK' 29 | }); 30 | console.log(decodedBody); 31 | }).catch((err) => { 32 | console.log(err); 33 | }) 34 | 35 | // console.log(encodeGBK('康兵奎')); 36 | // console.log(decodeGBK('%BF%B5%B1%F8%BF%FC')); 37 | 38 | // const NLP = require('./aip-node-sdk-2.1.1/src/index').nlp; 39 | // console.log(NLP) 40 | // // 调用词法分析 41 | // NLP.lexer('康兵奎').then(function(result) { 42 | // console.log(JSON.stringify(result)); 43 | // }).catch(function(err) { 44 | // // 如果发生网络错误 45 | // console.log(err); 46 | // }); -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | // const qs = require('querystring'); 2 | // const axios = require('axios'); 3 | // const fs = require('fs'); 4 | // const { 5 | // baiduApiKey, 6 | // baiduSecretKey 7 | // } = require('./config.js'); 8 | 9 | // const url = 'https://aip.baidubce.com/oauth/2.0/token'; 10 | // const param = qs.stringify({ 11 | // grant_type: 'client_credentials', 12 | // client_id: baiduApiKey, 13 | // client_secret: baiduSecretKey 14 | // }); 15 | // const { accessToken } = require('./token/accessToken'); 16 | // console.log('改变之前的Accesstoken为:', accessToken); 17 | // axios.post(`${url}?${param}`).then((response) => { 18 | // // console.log(response.data); 19 | // const _res = response.data; 20 | // const days = _res.expires_in / 3600 / 24; 21 | // const now = dayjs(); 22 | // const indate = now.add(days, 'day').valueOf(); 23 | // // console.log(indate); 24 | // const content = `module.exports = { 25 | // accessToken: '${_res.access_token}', 26 | // indate: '${indate}' 27 | // }`; 28 | // // console.log('内容:', content) 29 | // fs.writeFile('token/accessToken.js', content, 'utf-8', (err) => { 30 | // if (err) throw err; 31 | // const aaa = require('./token/accessToken'); 32 | // console.log('目前的Accesstoken为:', aaa.accessToken); 33 | // }); 34 | // }).catch((err) => { 35 | // console.log(err); 36 | // }) 37 | 38 | // console.log(dayjs()); 39 | 40 | // const now = dayjs(); 41 | // console.log(now.valueOf()) 42 | // const indate = (now.add(30, 'day')).valueOf(); 43 | // console.log(indate - now.valueOf()) 44 | 45 | const schedule = require('node-schedule'); 46 | const dayjs = require('dayjs'); 47 | // 定时任务测试 48 | const testSchedule = () => { 49 | schedule.scheduleJob('* * * * * *', function() { 50 | const now = dayjs().format('YYYY-MM-DD HH:mm:ss'); 51 | console.log(now); 52 | }); 53 | schedule.scheduleJob('* * * * * *', function() { 54 | console.log('dishiqi '); 55 | }); 56 | } 57 | 58 | testSchedule(); -------------------------------------------------------------------------------- /token/accessToken.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | accessToken: '', 3 | indate: 0 4 | } -------------------------------------------------------------------------------- /tools/assetTools.js: -------------------------------------------------------------------------------- 1 | const dayjs = require('dayjs'); 2 | const { FileBox } = require('file-box'); 3 | const { readDirData, randomNum } = require('./tools.js'); 4 | 5 | /** 6 | * @description 生成发送图片的内容 7 | * @param {Wechaty} bot 机器人对象 8 | * @param {String} imgName 图片名称,包括后缀,资源存放在 “assets/img/” 文件夹下 9 | * @returns {Object} 通过机器人生成的内容发送的对象 10 | */ 11 | const imgMessage = (bot, imgName) => { 12 | return new bot.Message(`${process.cwd()}/assets/image/${imgName}`); 13 | } 14 | 15 | /** 16 | * @description 生成替换头像的文件对象,头像放在 “assets/avatar/” 文件夹下,文件命名为(星期nubmer.jpg) 17 | * @param {Date} date 机器人对象 18 | * @returns {FileBox} 通过机器人生成的内容发送的对象 19 | */ 20 | const avatarImg = () => { 21 | const num = dayjs().day(); 22 | return FileBox.fromFile(`${process.cwd()}/assets/avatar/${num}.jpg`, 'avatar'); 23 | } 24 | 25 | /** 26 | * @description 随机获取一个目录下的一个文件 27 | * @param {String} foolder 文件夹名称 28 | * @param {String} name 随机资源类型,默认为 file,用来备注 29 | */ 30 | const randomFile = (foolder) => { 31 | const path = `${process.cwd()}/assets/${foolder}`; 32 | const pathData = readDirData(path); 33 | let result = '暂时没有相关资源!'; 34 | if (pathData.length > 0) { 35 | const filename = pathData[randomNum(0, pathData.length - 1)]; 36 | result = FileBox.fromFile(`${path}/${filename}`); 37 | } 38 | return result; 39 | } 40 | 41 | /** 42 | * @description 通过 url 生成远程资源文件 43 | * @param {String} url 资源文件地址 44 | * @returns {FileBox} 返回 FileBox 文件对象,可以直接用于发送 45 | */ 46 | const remoteFile = (url) => { 47 | const result = FileBox.fromUrl(url); 48 | return result; 49 | } 50 | 51 | /** 52 | * @description 根据消息内容返回相应的资源目录,如果都不匹配返回 false 53 | * @param {String} text 消息内容 54 | */ 55 | const assetFolder = (text) => { 56 | switch (text) { 57 | case '头像': 58 | return 'avatar'; 59 | case '图片': 60 | return 'image'; 61 | case '壁纸': 62 | return 'wallpaper'; 63 | case '文档': 64 | return 'document'; 65 | case '朋友圈配图': 66 | return 'match'; 67 | case '视频': 68 | return 'video'; 69 | case '语音': 70 | return 'voice'; 71 | case '小程序': 72 | return 'miniprogram'; 73 | default: 74 | return false; 75 | } 76 | } 77 | 78 | module.exports = { 79 | imgMessage, 80 | avatarImg, 81 | randomFile, 82 | remoteFile, 83 | assetFolder, 84 | }; -------------------------------------------------------------------------------- /tools/contactTools.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description 返回联系人的信息 3 | * @param {Contact} contact 联系人对象 4 | * @returns {Object} 用户基础信息对象 5 | */ 6 | const contactInfo = async (contact) => { 7 | if (!contact) { 8 | return null; 9 | } 10 | return { 11 | name: await contact.name(), // 名字 12 | alias: await contact.alias(), // 备注名称 13 | // age: '', // 年龄 14 | gender: contactGender(contact), // 性别 15 | avatar: await contact.avatar(), // 头像 16 | star: contact.star(), // 是否是星标用户 17 | isFriend: contact.friend(), // 是否是好友关系 18 | type: contactType(contact), // 联系人类型,官方或者个人 19 | province: contact.province(), // 省份 20 | city: contact.city(), // 城市 21 | isPerson: contactIsPerson(contact), // 是否是个人的标识 22 | }; 23 | } 24 | 25 | /** 26 | * @description 处理联系人类型 27 | * @param {Contact} contact 联系人对象 28 | * @returns {String} 返回用户类型 29 | */ 30 | const contactType = (contact) => { 31 | const _type = contact.type(); 32 | let _result = '未知'; 33 | if (_type === 1) { 34 | _result = '个人'; 35 | } 36 | if (_type === 2) { 37 | _result = '官方'; 38 | } 39 | return _result; 40 | } 41 | 42 | /** 43 | * @description 判断是否是个人类型的联系人 44 | * @param {Contact} contact 联系人对象 45 | * @return {Boolean} 返回是否是个人,是的话 true,不是 false 46 | */ 47 | const contactIsPerson = (contact) => { 48 | const type = contact.type(); 49 | let result = false; 50 | if (type === 1) { 51 | result = true; 52 | } 53 | return result; 54 | } 55 | 56 | /** 57 | * @description 处理联系人性别 58 | * @param {Contact} contact 联系人对象 59 | * @returns {String} 返回用户性别 60 | */ 61 | const contactGender = (contact) => { 62 | const gender = contact.gender(); 63 | let result = '未知'; 64 | if (gender === 1) { 65 | result = '男'; 66 | } 67 | if (gender === 2) { 68 | result = '女'; 69 | } 70 | return result; 71 | } 72 | 73 | /** 74 | * @description 处理联系人列表 75 | * @param {Array} contactList 联系人对象数组 76 | * @returns {Array} 返回处理过的用户信息数组 77 | */ 78 | const contactListInfo = async (contactList = []) => { 79 | return await contactList.map(async item => await contactInfo(item)); 80 | } 81 | 82 | module.exports = { 83 | contactType, 84 | contactInfo, 85 | contactGender, 86 | contactListInfo, 87 | contactIsPerson, 88 | }; -------------------------------------------------------------------------------- /tools/friendShipTools.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description 返回好友请求的信息 3 | * @param {Friendship} friendship 好友请求对象 4 | * @return {Object} 好友请求对象内容 5 | */ 6 | const friendshipInfo = (friendship) => { 7 | return { 8 | verifyMessage: friendship.hello(), 9 | contact: friendship.contact(), 10 | type: friendshipType(friendship), 11 | }; 12 | } 13 | 14 | /** 15 | * @description 返回好友请求的信息类型 16 | * @param {Friendship} friendship 好友请求对象 17 | * @return {String} 类型 18 | */ 19 | const friendshipType = (friendship) => { 20 | let result = ''; 21 | switch (friendship.type()) { 22 | case 0: 23 | result = '未知'; 24 | break; 25 | case 1: 26 | result = '确认'; 27 | break; 28 | case 2: 29 | result = '收到'; 30 | break; 31 | case 3: 32 | result = '验证'; 33 | break; 34 | default: 35 | result = ''; 36 | } 37 | return result; 38 | } -------------------------------------------------------------------------------- /tools/messageTools.js: -------------------------------------------------------------------------------- 1 | const { formatDate } = require('./tools.js'); 2 | const { contactInfo, contactListInfo } = require('./contactTools.js'); 3 | const { roomInfo } = require('./roomTools.js'); 4 | /** 5 | * @description 处理 message 对象,返回对象的基本信息和数据 6 | * @param {Message} message 7 | */ 8 | const messageInfo = async (message) => { 9 | if (!message) { 10 | return null; 11 | } 12 | const send = message.from(); 13 | const accept = message.to(); 14 | const mention = await message.mention(); 15 | const room = message.room(); 16 | return { 17 | isSelf: message.self(), // 是否是自己发的消息 18 | send, // 发送者 19 | sendInfo: await contactInfo(send), // 发送者用户信息 20 | accept, // 接收者,在 room 中返回 null 21 | acceptInfo: await contactInfo(accept), // 接收者用户信息,在 room 中返回 null 22 | room, // 群聊房间 23 | roomInfo: await roomInfo(room), // 群聊房间信息 24 | isGroupMsg: room !== null, // 是否是群聊消息 25 | type: messageType(message), // 消息类型 26 | content: messageText(message), // 消息内容 27 | mention, // 提及用户 list 28 | mentionInfo: await contactListInfo(mention) || [], // 提及用户信息 29 | date: formatDate(message.date()), // 消息发送时间 30 | age: message.age(), // 消息的年龄,据当前时间的秒数 31 | }; 32 | } 33 | 34 | /** 35 | * @description 处理并返回消息内容 36 | * @param {Message} message message 对象 37 | * @return {String} 返回处理过的消息内容 38 | */ 39 | const messageText = (message) => { 40 | if (message) { 41 | const text = message.text(); 42 | return text ? text.replace(/\s+/g, '') : ''; 43 | } 44 | return ''; 45 | } 46 | 47 | /** 48 | * @description 返回用于保存的简要数据对象 49 | * @param {Message} message 消息对象 50 | * @return {Object} 用于保存到数据库的对象 51 | */ 52 | const messageRecord = async (message) => { 53 | const info = await messageInfo(message); 54 | return messageRecordInfo(info); 55 | } 56 | 57 | /** 58 | * @description 返回用于保存的简要数据对象 59 | * @param {MessageInfo} info 消息内容 60 | * @return {Object} 用于保存到数据库的对象 61 | */ 62 | const messageRecordInfo = (info) => { 63 | const mentionList = info.mentionInfo.map(item => item.name); 64 | const accept = info.room ? info.roomInfo.name : info.acceptInfo.name; 65 | return { 66 | send: info.sendInfo.name, //发送人名字 67 | accept, // 接收者,可能是人名或者群名 68 | type: info.type, // 消息的类型 69 | isGroupMsg: info.isGroupMsg, // 是否是群消息 70 | content: info.content, // 内容 71 | date: info.date, // 时间 72 | mentionList, // 提到的人 73 | }; 74 | } 75 | 76 | /** 77 | * @description 返回消息的类型 78 | * @param {Message} message 消息对象 79 | * @return {MessageType: String} 返回消息类型描述 80 | */ 81 | const messageType = (message) => { 82 | const msgType = message.type(); 83 | const msgTypeResult = ['未知', '附件', '语音', '联系人名片', '表情', '图片', '文本', '视频']; 84 | return msgTypeResult[msgType]; 85 | } 86 | 87 | /** 88 | * @description 获取消息的提及对象数组 89 | * @param {Message} message 消息对象 90 | * @returns {Array} 提及用户数组 91 | */ 92 | const messageMention = async (message) => { 93 | return await message.mention(); 94 | } 95 | 96 | module.exports = { 97 | messageInfo, 98 | messageType, 99 | messageRecord, 100 | messageRecordInfo, 101 | messageMention, 102 | messageText, 103 | }; 104 | -------------------------------------------------------------------------------- /tools/mongo.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const { mongoDB } = require('../config/config.js'); 3 | 4 | // 链接数据库 5 | mongoose.connect(mongoDB); 6 | 7 | // 监听数据库事件 8 | const db = mongoose.connection; 9 | 10 | /** 11 | * 连接异常 12 | */ 13 | db.on('error', function (err) { 14 | console.log('Mongoose connection error: ' + err); 15 | }); 16 | 17 | /** 18 | * 连接断开 19 | */ 20 | db.on('disconnected', function () { 21 | console.log('Mongoose connection disconnected'); 22 | }); 23 | 24 | /** 25 | * 连接成功 26 | */ 27 | db.on('connected', function () { 28 | console.log('Mongoose connection open to ' + mongoDB); 29 | }); -------------------------------------------------------------------------------- /tools/roomTools.js: -------------------------------------------------------------------------------- 1 | const { 2 | contactInfo, 3 | contactListInfo, 4 | } = require('./contactTools.js'); 5 | 6 | /** 7 | * @description 获取群聊基本信息 8 | * @param {Room} room 群对象 9 | * @returns {Object} 返回群聊的基本信息 10 | */ 11 | const roomInfo = async (room) => { 12 | if (!room) { 13 | return null; 14 | } 15 | const members = await room.memberList(); 16 | return { 17 | name: await room.topic(), // 群名字 18 | // announce: await room.announce(), // 群公告,暂不支持 19 | memberNumber: members.length, // 群成员数 20 | // avatar: await room.avatar(), // 群头像图片,暂不支持 21 | }; 22 | } 23 | 24 | /** 25 | * @description 获取单个群成员信息 26 | * @param {Room} room 群对象 27 | * @param {String | filter} query 检索条件 28 | * @returns {ContactInfo} 返回处理过的群成员信息 29 | * @example 30 | * filter = { 31 | * name: '', 32 | * roomAlias: '', 33 | * contactAlias: '' 34 | * } 35 | */ 36 | const roomMemberInfo = async (room, query) => { 37 | const member = await room.member(query); 38 | return await contactInfo(member); 39 | } 40 | 41 | /** 42 | * @description 获取所有群成员信息 43 | * @param {Room} room 群对象 44 | * @returns {Array} 返回处理过的群成员信息 45 | */ 46 | const roomMemberListInfo = async (room) => { 47 | const memberList = await room.memberAll(); 48 | return await contactListInfo(memberList); 49 | } 50 | /** 51 | * @description 通过字符串查询群聊是否存在某人 52 | * @param {Room} room 群对象 53 | * @param {Robot} bot 机器人对象 54 | * @param {String} query 需要查询的用户条件 55 | */ 56 | const roomHasPeople = async (room, bot, query) => { 57 | const contact = await bot.Contact.find(query); 58 | let result = false; 59 | if (contact) { 60 | result = await room.has(contact); 61 | } 62 | return result; 63 | } 64 | 65 | module.exports = { 66 | roomInfo, 67 | roomHasPeople, 68 | roomMemberInfo, 69 | roomMemberListInfo 70 | }; -------------------------------------------------------------------------------- /tools/tools.js: -------------------------------------------------------------------------------- 1 | const dayjs = require('dayjs'); 2 | const fs = require('fs'); 3 | 4 | /** 5 | * @description 格式化时间为字符串 6 | * @param {Date} date 需要格式化的时间 7 | * @param {String} str 格式化格式 8 | * @return {String} 返回格式化后的日期字符串 9 | */ 10 | const formatDate = (date, str = 'YYYY-MM-DD HH:mm:ss') => { 11 | return dayjs(date).format(str); 12 | } 13 | 14 | /** 15 | * @description 生成 start 到 end 的随机整数,两个都包含:[start, end] 16 | * @param {Number} start 开始 17 | * @param {Number} end 结束 18 | * @return {Number} 随机数 19 | */ 20 | const randomNum = (start, end) => { 21 | const muit = end - start; 22 | return Math.round(Math.random() * muit + start) 23 | } 24 | 25 | /** 26 | * @description 同步读取文件方法,返回读取到的数据,用于读取知识库文件下的数据文件 27 | * @param {String} fileName 文件名 28 | * @return {Object} 文件数据对象 29 | */ 30 | const readJsonFile = (fileName) => { 31 | return JSON.parse(fs.readFileSync(`${process.cwd()}/knowledge/${fileName}.json`, { encoding:'utf-8' })); 32 | } 33 | 34 | /** 35 | * @description 获取路径下的数据 36 | * @param {String} path 路径 37 | * @return {Array} 文件列表数组 38 | */ 39 | const readDirData = (path) => { 40 | return fs.readdirSync(path, { encoding:'utf-8' }); 41 | } 42 | 43 | /** 44 | * @description 判断一个用户是否在提及列表中 45 | * @param {Array} list 提及对象的信息列表 46 | * @param {String} name 需要判断的对象名字 47 | * @return {Boolean} 返回是否被提及 48 | */ 49 | const mentioned = (list, name) => { 50 | let result = false; 51 | for (let i = 0; i < list.length; i++) { 52 | if (list[i].name === name) { 53 | result = true; 54 | break; 55 | } 56 | } 57 | return result; 58 | } 59 | 60 | // 判断是否是 @ 机器人 61 | const checkAtRobot = (username, content) => { 62 | let flag = false; 63 | const isAt = /\@/g.test(content); 64 | if (isAt) { 65 | const _space = returnSpace(content); 66 | const _username = (content.split('@')[1]).split(_space)[0]; 67 | if (username === _username) { 68 | flag = true; 69 | } 70 | } 71 | return flag; 72 | } 73 | 74 | /** 75 | * 76 | * @param {*} con 77 | */ 78 | const returnSpace = (con) => { 79 | const _str = con.split('@')[1]; 80 | return _str.indexOf(' ') > -1 ? ' ' : ' '; 81 | } 82 | 83 | module.exports = { 84 | formatDate, 85 | randomNum, 86 | readJsonFile, 87 | readDirData, 88 | mentioned, 89 | }; -------------------------------------------------------------------------------- /tools/utils.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const axios = require('axios'); 3 | const pinyin = require("pinyin"); 4 | const qs = require('querystring') 5 | const { weatherAPIKey, baiduApiKey, baiduSecretKey, jokeKey, qAndAKey } = require('./config'); 6 | const LinkUrl = require('./url'); 7 | 8 | const logger = (...args) => { 9 | console.log(args); 10 | } 11 | 12 | const bindKnowledgeAnswer = (m, content, key, answer, cb) => { 13 | if (content.indexOf(key) > -1) { 14 | m.say(`${answer}`); 15 | cb && cb(); 16 | } 17 | } 18 | 19 | // 保存聊天记录 20 | const saveChatInfo = (groupName, str) => { 21 | const _date = new Date().toLocaleDateString().replace(/\//g, '-'); 22 | fs.appendFile(`temp/${groupName}-${_date}.txt`, str + '\n', 'utf8', (err) => { 23 | if (err) saveChatInfo(groupName, str); 24 | console.log('聊天记录已存储...'); 25 | }) 26 | } 27 | // 保存登录信息 28 | const saveLoginInfo = (info) => { 29 | fs.appendFile(`log/login.txt`, info + '\n', 'utf8', (err) => { 30 | if (err) saveLoginInfo(info); 31 | console.log('登录信息已记录...'); 32 | }) 33 | } 34 | 35 | // 判断是否是 @ 机器人 36 | const checkAtRobot = (username, content) => { 37 | let flag = false; 38 | const isAt = /\@/g.test(content); 39 | if (isAt) { 40 | const _space = returnSpace(content); 41 | const _username = (content.split('@')[1]).split(_space)[0]; 42 | if (username === _username) { 43 | flag = true; 44 | } 45 | } 46 | return flag; 47 | } 48 | 49 | const returnSpace = (con) => { 50 | const _str = con.split('@')[1]; 51 | return _str.indexOf(' ') > -1 ? ' ' : ' '; 52 | } 53 | 54 | const randomNum = (n) => { 55 | let _num = ''; 56 | for (let i = 0; i < n; i++) { 57 | _num += Math.floor(Math.random() * 10) + ''; 58 | } 59 | return Math.floor(_num); 60 | } 61 | 62 | const questionAndAnswer = (question, callback) => { 63 | const _url = encodeURI(`${LinkUrl.qAndAUrl}?&info=${question}dtype=json&loc=&userid=&key=${qAndAKey}`); 64 | axios.get(_url).then(function (response) { 65 | const _data = response.data.result.text; 66 | callback && callback(_data); 67 | }).catch(function (error) { 68 | console.log(error); 69 | }); 70 | 71 | } 72 | // 获取百度AI的 AccessToken,如果失效则重新获取 73 | const getBaiduAccessToken = (callback) => { 74 | const { accessToken, indate } = require('./token/accessToken'); 75 | const now = dayjs(); 76 | const _falg = now.valueOf < indate; 77 | if (accessToken && _falg) { 78 | callback && callback(accessToken); 79 | } else { 80 | const param = qs.stringify({ 81 | grant_type: 'client_credentials', 82 | client_id: baiduApiKey, 83 | client_secret: baiduSecretKey 84 | }); 85 | axios.post(`${LinkUrl.accessTokenUrl}?${param}`).then((response) => { 86 | const _res = response.data; 87 | callback && callback(_res.access_token); 88 | const _days = _res.expires_in / 3600 / 24; 89 | const _indate = now.add(_days, 'day').valueOf(); 90 | const content = `module.exports = { 91 | accessToken: '${_res.access_token}', 92 | indate: ${_indate} 93 | }`; 94 | fs.writeFile('token/accessToken.js', content, 'utf-8', (err) => { 95 | if (err) throw err; 96 | console.log('新AccessToken已保存。'); 97 | }); 98 | }).catch((err) => { 99 | console.log(err); 100 | }) 101 | } 102 | } 103 | 104 | module.exports = { 105 | logger, 106 | bindKnowledgeAnswer, 107 | saveChatInfo, 108 | randomNum, 109 | saveLoginInfo, 110 | checkAtRobot, 111 | getWeather, 112 | getJoke, 113 | questionAndAnswer, 114 | returnSpace, 115 | getBaiduAccessToken 116 | } -------------------------------------------------------------------------------- /updatelog.md: -------------------------------------------------------------------------------- 1 | # 更新记录 2 | 3 | ## 2018-05-13 4 | 5 | - 完成基本的聊天内容分析回复功能 6 | - 能够查询天气 7 | - 能够支持问答 8 | - 能够讲笑话 9 | - 能够维护群和谐文明发展 10 | 11 | ## 2018-05-14 12 | 13 | - 接入百度AI自然语言处理分析(完成30%) 14 | 15 | ## 2018-05-15 16 | 17 | - 重新整理目录结构,拆分功能模块 18 | 19 | ## 2018-06-20 20 | 21 | - 回填各项配置的参数,整理需要的新的参数,为重构做准备 22 | 23 | ## 2018-06-27 24 | 25 | - 项目开始重构,更新依赖库版本 26 | - 项目接入 MongoDB 数据库,数据保存依赖数据库 27 | - 项目接入 log4js 日志系统,记录项目运行状态 28 | - 整理依赖库提供的方法,增加思维导图文件 29 | - 版本号改为 v0.2.0 30 | 31 | ## 2018-06-28 32 | 33 | - 机器人相关模块的工具方法编写 34 | - 增加功能梳理,并评估是否能够实现 35 | - 引入 FileBox 处理消息中的文件 36 | - 引入 node-schedule 创建定时任务,定时执行操作 37 | 38 | ## 2018-06-29 39 | 40 | - 拆分天气预报和笑话为单独的功能模块 41 | - 替换 mongolass 为 mongoose 42 | - 完成聊天数据保存功能方法 43 | 44 | ## 2018-07-02 45 | 46 | - 整理目录结构 47 | - 修改版本计划表 48 | - 完成资源消息的发送功能 49 | - 删除不必要的文件 50 | - 升级依赖库到 next 版本 51 | - 修改天气、笑话等功能模块 52 | - 完成提醒模块功能开发 53 | - 修改 readme 文件,增加目录结构 54 | 55 | ## 2018-07-03 56 | 57 | - 完成群聊消息和单聊消息 58 | - 完成主要逻辑分支的判断 59 | - 完成机器人主要方法的监听 60 | 61 | 62 | ## 2018-07-04 63 | 64 | - 新增诗句功能模块 65 | - 修改部分功能计划,推迟到下版本 66 | - 完成登录和用户信息获取的调试 67 | - 依赖库版本存在问题,需要等待依赖库的升级后再进行继续开发 68 | 69 | ## 2018-07-12 70 | 71 | - 更新Wechaty到v0.18.3 72 | - 整体测试完成,基本消息能够正常发送、接收、保存 73 | 74 | ## 2018-07-13 75 | 76 | - 文档更新,拉取稳定版本分支 77 | - 修改版本到 v0.2.6 修改入口文件,删除无用的文件 78 | - 定版 v0.2.6 拉取稳定分支,可直接使用的分支 79 | - 开始 v0.3.* 版本功能开发 80 | - 增加远程文件发送功能 81 | - 功能计划,按照版本细分文件,方便查阅 82 | 83 | ## 2018-09-03 84 | 85 | - 增加计划任务 86 | 87 | ## 2018-09-07 88 | 89 | - 增加歌单推荐 90 | - 增加小程序推荐 91 | - 增加动漫推荐 --------------------------------------------------------------------------------