├── .eslintrc ├── .gitignore ├── README.md ├── cli.js ├── config.js ├── database ├── GeoLite2-Country.mmdb └── effective_tld_names.dat ├── dictionaries ├── english.dict └── polish.dict ├── docs └── screenshots │ └── demo.gif ├── lib ├── banner.txt ├── index.js └── utils.js ├── package.json └── yarn.lock /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint-config-airbnb", 3 | "env": { 4 | "node": true 5 | }, 6 | "rules": { 7 | "object-property-newline": "off", 8 | "no-underscore-dangle": "off", 9 | "camelcase": "off" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | logs/ 4 | test.js 5 | .vscode/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DomainFuzz 2 | 3 | Find similar-looking domain names that adversaries can use to attack you. Can detect typosquatters, phishing attacks, fraud and corporate espionage. Useful as an additional source of targeted threat intelligence. 4 | 5 | ![Demo](/docs/screenshots/demo.gif) 6 | 7 | ## Usage 8 | 9 | TODO. 10 | 11 | ## Command util 12 | 13 | This project provides a cli tool. 14 | 15 | For example, use qq.com as a target: 16 | 17 | ```bash 18 | node cli.js --target qq.com --format csv --out-put qq.csv -c 10 --modules whois,banners,mxcheck,geoip 19 | ``` 20 | 21 | ### Options 22 | 23 | * `--target ` target domain name or URL to check 24 | * `-o --out-put ` Output filename 25 | * `-f --format ` Output format (JSON|CSV) [JSON] 26 | * `-c --concurrency ` start specified NUMBER of concurrency 27 | * `--modules ` Enable modules (whois|banners|mxcheck|ssdeep|geoip) 28 | * `--nameservers ` comma separated list of nameservers to query 29 | * `--dictionary ` generate additional domains using dictionary FILE 30 | * `--registered` show only registered domain names (TODO) 31 | * `--can-register` show only can register domain names (TODO) 32 | 33 | ## Dependencies 34 | 35 | * http://ssdeep.sourceforge.net/ 36 | * http://dev.maxmind.com/geoip/geoip2/geolite2/ 37 | 38 | ## Reference 39 | 40 | * https://github.com/elceef/dnstwist/ 41 | -------------------------------------------------------------------------------- /cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const fs = require('fs'); 3 | const debug = require('debug')('fuzz:main'); 4 | const Promise = require('bluebird'); 5 | const program = require('commander'); 6 | const request = require('request'); 7 | const libssdeep = require('ssdeep'); 8 | const csv = require('csv'); 9 | const ProgressBar = require('progress'); 10 | const CONF = require('./config'); 11 | const { printError, printInfo, printResult, printBanner, parseTarget, bye } = require('./lib/utils'); 12 | const { DomainFuzz, DomainDict, DomainThread } = require('./lib'); 13 | 14 | const fuzz = (opts, domains, worker) => { 15 | const total = domains.length; 16 | const bar = new ProgressBar('Running [:bar] :percent :etas', { 17 | complete: '=', 18 | incomplete: ' ', 19 | width: 50, 20 | total, 21 | }); 22 | Promise 23 | .map(domains, (domain) => { 24 | bar.tick(1); 25 | return worker.run(domain); 26 | }, { concurrency: opts.concurrency }) 27 | .then((result) => { 28 | if (opts.option_output) { 29 | let data; 30 | if (opts.option_format === 'JSON') { 31 | data = JSON.stringify(result, null, 4); 32 | fs.appendFile(opts.option_output, data, 'utf8', (err) => { 33 | if (err) printError(err.message); 34 | }); 35 | } else if (opts.option_format === 'CSV') { 36 | data = []; 37 | const columns = 'fuzzer,domain-name,dns-a,dns-aaaa,dns-mx,dns-ns,geoip-country,whois-created,whois-updated,ssdeep-score'; 38 | data.push(columns.split(',')); 39 | for (const domain of result) { 40 | data.push(columns.split(',').map(_ => domain[_])); 41 | } 42 | csv.stringify(data, (parseErr, res) => { 43 | fs.appendFile(this.option_output, res, 'utf8', (err) => { 44 | if (err) printError(err.message); 45 | }); 46 | }); 47 | } 48 | } 49 | for (const domain of result) { 50 | printResult(domain); 51 | } 52 | }) 53 | .catch(err => printError(err.message)); 54 | }; 55 | 56 | const main = () => { 57 | const opts = program 58 | .version(CONF.version) 59 | .usage('[options] DOMAIN') 60 | .description(`Find similar-looking domain names that adversaries can use to attack you. Can 61 | detect typosquatters, phishing attacks, fraud and corporate espionage. Useful 62 | as an additional source of targeted threat intelligence.`) 63 | .option('--target ', 'target domain name or URL to check', parseTarget) 64 | .option('-o --out-put ', 'Output filename') 65 | .option('-f --format ', 'Output format (JSON|CSV) [JSON]', val => val.toUpperCase(), 'JSON') 66 | .option('-c --concurrency ', 'start specified NUMBER of concurrency', Math.abs, CONF.CONCURRENCY_COUNT_DEFAULT) 67 | .option('--modules ', 'Enable modules (whois|banners|mxcheck|ssdeep|geoip)', val => val.split(/\W/), []) 68 | .option('--nameservers ', 'comma separated list of nameservers to query', val => val.split(',')) 69 | .option('--dictionary ', 'generate additional domains using dictionary FILE') 70 | .option('--registered', 'show only registered domain names (TODO)')// TODO. 71 | .option('--can-register', 'show only can register domain names (TODO)')// TODO. 72 | .parse(process.argv); 73 | 74 | if (!process.argv.slice(2).length) { 75 | printInfo(` ${CONF.name} ${CONF.version} by ${CONF.author}`); 76 | opts.outputHelp(); 77 | bye(0); 78 | } 79 | 80 | if (!opts.target) { 81 | printError('The target is required'); 82 | bye(-1); 83 | } 84 | 85 | if (opts.format) { 86 | if (!['JSON', 'CSV'].includes(opts.format)) { 87 | printError('Format must be JSON or CSV'); 88 | bye(-1); 89 | } 90 | } 91 | 92 | if (opts.concurrency < 1) { 93 | opts.concurrency = CONF.CONCURRENCY_COUNT_DEFAULT; 94 | } 95 | 96 | printBanner(); 97 | 98 | const domainFuzz = new DomainFuzz(opts.target.host); 99 | domainFuzz.generate(); 100 | let { domains } = domainFuzz; 101 | 102 | if (opts.dictionary) { 103 | if (!fs.existsSync(opts.dictionary)) { 104 | printError(`dictionary not found: ${opts.dictionary}`); 105 | return false; 106 | } 107 | 108 | const domainDict = new DomainDict(opts.target.host); 109 | domainDict.load_dict(opts.dictionary); 110 | domainDict.generate(); 111 | domains = domains.concat(domainDict.domains); 112 | } 113 | 114 | debug(`Domains: ${JSON.stringify(domains)}`); 115 | printInfo(`Processing ${domains.length} domain variants`); 116 | printInfo(`Enable modules: ${opts.modules.length ? opts.modules.join(', ') : '-'}`); 117 | 118 | const worker = new DomainThread(domains); 119 | 120 | // Modules 121 | if (opts.modules) { 122 | const modules = opts.modules; 123 | if (modules.includes('whois')) worker.option_whois = true; 124 | if (modules.includes('banners')) worker.option_banners = true; 125 | if (modules.includes('ssdeep')) worker.option_ssdeep = true; 126 | if (modules.includes('mxcheck')) worker.option_mxcheck = true; 127 | if (modules.includes('geoip')) worker.option_geoip = true; 128 | } 129 | 130 | worker.target = opts.target; 131 | worker.option_output = opts.outPut; 132 | worker.option_format = opts.format; 133 | worker.concurrency = opts.concurrency; 134 | worker.nameservers = opts.nameservers; 135 | 136 | // console.log(opts.modules, opts.modules.includes('ssdeep')) 137 | if (opts.modules && opts.modules.includes('ssdeep')) { 138 | printInfo(`Fetching content from: ${opts.target.href} ...`); 139 | const options = { url: opts.target.href, method: 'GET', timeout: CONF.REQUEST_BANNER_TIMEOUT }; 140 | const headers = { 'User-Agent': `Mozilla/5.0 ${CONF.name}/${CONF.version}` }; 141 | options.headers = headers; 142 | debug(`request: ${JSON.stringify(options)}`); 143 | return new Promise((resolve) => { 144 | request(options, (err, res, body) => { 145 | if (err) { 146 | printError(`fetch ssdeep orig failed. ${err.message}`); 147 | return resolve(false); 148 | } 149 | printInfo(`${res.statusCode} ${res.statusMessage} (${body.length / 1000} Kbytes)`); 150 | if (res.statusCode === 200) { 151 | const ssdeep_orig = libssdeep.hash(body); 152 | debug(`ssdeep_orig: ${ssdeep_orig}`); 153 | return resolve(ssdeep_orig); 154 | } 155 | return resolve(false); 156 | }); 157 | }) 158 | .then((ssdeep_orig) => { 159 | if (ssdeep_orig) { 160 | worker.ssdeep_orig = ssdeep_orig; 161 | } 162 | fuzz(opts, domains, worker); 163 | }); 164 | } 165 | 166 | fuzz(opts, domains, worker); 167 | }; 168 | 169 | if (require.main) main(); 170 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const PKG = require('./package'); 3 | 4 | const config = {}; 5 | config.name = PKG.name; 6 | config.version = PKG.version; 7 | config.author = PKG.author; 8 | config.BASE_DIR = path.resolve(__dirname); 9 | config.DB_DIR = path.join(config.BASE_DIR, 'database'); 10 | config.LIB_DIR = path.join(config.BASE_DIR, 'lib'); 11 | config.TLD_FILE = path.join(config.DB_DIR, 'effective_tld_names.dat'); 12 | config.GEOIP_FILE = path.join(config.DB_DIR, 'GeoLite2-Country.mmdb'); 13 | config.banner = path.join(config.LIB_DIR, 'banner.txt'); 14 | 15 | config.REQUEST_BANNER_TIMEOUT = 2000; 16 | config.CONCURRENCY_COUNT_DEFAULT = 10; 17 | 18 | module.exports = config; 19 | -------------------------------------------------------------------------------- /database/GeoLite2-Country.mmdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/monkeym4ster/DomainFuzz/a83a95998ab5e867b993e106f8f290c9db64778b/database/GeoLite2-Country.mmdb -------------------------------------------------------------------------------- /dictionaries/english.dict: -------------------------------------------------------------------------------- 1 | // This dictionary (should) contain the most common words used in targeted 2 | // phishing campaigns. Feel free to adapt it to your needs. 3 | 4 | auth 5 | access 6 | account 7 | agree 8 | cdn 9 | confirm 10 | confirmation 11 | download 12 | find 13 | install 14 | login 15 | my 16 | online 17 | payment 18 | payments 19 | recovery 20 | register 21 | ssl 22 | safe 23 | secure 24 | security 25 | service 26 | services 27 | signin 28 | support 29 | summary 30 | update 31 | verify 32 | verification 33 | -------------------------------------------------------------------------------- /dictionaries/polish.dict: -------------------------------------------------------------------------------- 1 | // Ten słownik powinien zawierać najczęściej wykorzystywane słowa podczas 2 | // kampanii phishing-owych. Można go dopasować do swoich potrzeb. 3 | 4 | autoryzacja 5 | konto 6 | logowanie 7 | ssl 8 | -------------------------------------------------------------------------------- /docs/screenshots/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/monkeym4ster/DomainFuzz/a83a95998ab5e867b993e106f8f290c9db64778b/docs/screenshots/demo.gif -------------------------------------------------------------------------------- /lib/banner.txt: -------------------------------------------------------------------------------- 1 | _____ _ ______ 2 | | __ \ (_) | ____| 3 | | | | | ___ _ __ ___ __ _ _ _ __ | |__ _ _ ________ 4 | | | | |/ _ \| '_ ` _ \ / _` | | '_ \| __| | | |_ /_ / 5 | | |__| | (_) | | | | | | (_| | | | | | | | |_| |/ / / / 6 | |_____/ \___/|_| |_| |_|\__,_|_|_| |_|_| \__,_/___/___| 7 | 8 | 9 | 10 | 11 | 12 | ______ _ ______ 13 | | _ \ (_) | ___| 14 | | | | |___ _ __ ___ __ _ _ _ __ | |_ _ _ ________ 15 | | | | / _ \| '_ ` _ \ / _` | | '_ \| _| | | |_ /_ / 16 | | |/ / (_) | | | | | | (_| | | | | | | | |_| |/ / / / 17 | |___/ \___/|_| |_| |_|\__,_|_|_| |_\_| \__,_/___/___| 18 | 19 | 20 | 21 | 22 | 23 | '||'''|. '||''''| 24 | || || '' || . 25 | || || .|''|, '||),,(|, '''|. || `||''|, ||''| '|| ||` '''/ '''/ 26 | || || || || || || || .|''|| || || || || || || // // 27 | .||...|' `|..|' .|| ||. `|..||. .||. .|| ||. .||. `|..'|. /... /... 28 | 29 | 30 | 31 | 32 | 33 | .---. _ .---. 34 | : . : :_; : .--' 35 | : :: : .--. ,-.,-.,-. .--. .-.,-.,-.: `;.-..-..---. .---. 36 | : :; :' .; :: ,. ,. :' .; ; : :: ,. :: : : :; :`-'_.'`-'_.' 37 | :___.'`.__.':_;:_;:_;`.__,_;:_;:_;:_;:_; `.__.'`.___;`.___; 38 | 39 | 40 | 41 | 42 | 43 | ooo. o ooooo 44 | 8 `8. 8 45 | 8 `8 .oPYo. ooYoYo. .oPYo. o8 odYo. o8oo o o .oooo. .oooo. 46 | 8 8 8 8 8' 8 8 .oooo8 8 8' `8 8 8 8 .dP .dP 47 | 8 .P 8 8 8 8 8 8 8 8 8 8 8 8 8 oP' oP' 48 | 8ooo' `YooP' 8 8 8 `YooP8 8 8 8 8 `YooP' `Yooo' `Yooo' 49 | .....:::.....:..:..:..:.....::....::..:..:::::.....::.....::.....: 50 | :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 51 | :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 52 | 53 | 54 | 55 | 56 | 57 | o.OOOo. OOooOoO 58 | O `o o o 59 | o O O 60 | O o oOooO 61 | o O .oOo. `oOOoOO. .oOoO' O 'OoOo. O O o ooOO ooOO 62 | O o O o O o o O o o o O o o O o o 63 | o .O' o O o O O o O O O o o O o O O 64 | OooOO' `OoO' O o o `OoO'o o' o O O' `OoO'o OooO OooO 65 | 66 | 67 | 68 | 69 | 70 | ============================================================================== 71 | = ====================================== ======================== 72 | = ==== ===================================== ============================== 73 | = ==== ===================================== ============================== 74 | = ==== === === = = ==== === == = === ======== = == == = 75 | = ==== == == == = ====== == ==== = ====== ====== = 76 | = ==== == = == = = ===== == == = == ======== = ===== ====== == 77 | = ==== == = == = = === == == = == ======== = ==== ====== === 78 | = ==== == = == = = == = == == = == ======== = === ====== ==== 79 | = ==== === = = === == == = == ========= == == = 80 | ============================================================================== 81 | 82 | 83 | 84 | 85 | 86 | ______ _ _______ 87 | (______) (_) (_______) 88 | _ _ ___ ____ _____ _ ____ _____ _ _ _____ _____ 89 | | | | / _ \| \(____ | | _ \| ___) | | (___ |___ ) 90 | | |__/ / |_| | | | / ___ | | | | | | | |_| |/ __/ / __/ 91 | |_____/ \___/|_|_|_\_____|_|_| |_|_| |____/(_____|_____) 92 | 93 | 94 | 95 | 96 | 97 | ____ _ ______ 98 | / __ \____ ____ ___ ____ _(_)___ / ____/_ __________ 99 | / / / / __ \/ __ `__ \/ __ `/ / __ \/ /_ / / / /_ /_ / 100 | / /_/ / /_/ / / / / / / /_/ / / / / / __/ / /_/ / / /_/ /_ 101 | /_____/\____/_/ /_/ /_/\__,_/_/_/ /_/_/ \__,_/ /___/___/ 102 | 103 | 104 | 105 | 106 | 107 | ___ _ ____ 108 | / _ \___ __ _ ___ _(_)__ / __/_ ________ 109 | / // / _ \/ ' \/ _ `/ / _ \/ _// // /_ /_ / 110 | /____/\___/_/_/_/\_,_/_/_//_/_/ \_,_//__/__/ 111 | 112 | 113 | 114 | 115 | 116 | ________ _____ __________ 117 | ___ __ \____________ _________ ___(_)_________ ____/___ ____________ 118 | __ / / / __ \_ __ `__ \ __ `/_ /__ __ \_ /_ _ / / /__ /__ / 119 | _ /_/ // /_/ / / / / / / /_/ /_ / _ / / / __/ / /_/ /__ /__ /_ 120 | /_____/ \____//_/ /_/ /_/\__,_/ /_/ /_/ /_//_/ \__,_/ _____/____/ 121 | 122 | 123 | 124 | 125 | 126 | ____ _ _____ 127 | | _ \ ___ _ __ ___ __ _(_)_ __ | ___| _ ________ 128 | | | | |/ _ \| '_ ` _ \ / _` | | '_ \| |_ | | | |_ /_ / 129 | | |_| | (_) | | | | | | (_| | | | | | _|| |_| |/ / / / 130 | |____/ \___/|_| |_| |_|\__,_|_|_| |_|_| \__,_/___/___| 131 | 132 | 133 | 134 | 135 | 136 | _____ _ _______ 137 | (____ \ (_) (_______) 138 | _ \ \ ___ ____ ____ _ ____ _____ _ _ _____ _____ 139 | | | | / _ \| \ / _ | | _ \| ___) | | (___ |___ ) 140 | | |__/ / |_| | | | ( ( | | | | | | | | |_| |/ __/ / __/ 141 | |_____/ \___/|_|_|_|\_||_|_|_| |_|_| \____(_____|_____) 142 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | const url = require('url'); 2 | const fs = require('fs'); 3 | const net = require('net'); 4 | const dns = require('dns'); 5 | const Promise = require('bluebird'); 6 | const debug = require('debug')('fuzz:fuzz'); 7 | const request = require('request'); 8 | const libssdeep = require('ssdeep'); 9 | const libwhois = require('whois-json'); 10 | const nodemailer = require('nodemailer'); 11 | const { printError, bye, rsplit } = require('./utils'); 12 | const CONF = require('../config'); 13 | const geoip2 = require('geoip2'); 14 | 15 | geoip2.init(CONF.GEOIP_FILE); 16 | 17 | class DomainFuzz { 18 | constructor(domain) { 19 | [this.domain, this.tld] = this.__domain_tld(domain); 20 | if (!this.tld) { 21 | printError('Target invalid.'); 22 | bye(-1); 23 | } 24 | this.domains = []; 25 | 26 | this.qwerty = { 27 | 1: '2q', 2: '3wq1', 3: '4ew2', 4: '5re3', 5: '6tr4', 6: '7yt5', 7: '8uy6', 8: '9iu7', 9: '0oi8', 0: 'po9', 28 | q: '12wa', w: '3esaq2', e: '4rdsw3', r: '5tfde4', t: '6ygfr5', y: '7uhgt6', u: '8ijhy7', i: '9okju8', o: '0plki9', p: 'lo0', 29 | a: 'qwsz', s: 'edxzaw', d: 'rfcxse', f: 'tgvcdr', g: 'yhbvft', h: 'ujnbgy', j: 'ikmnhu', k: 'olmji', l: 'kop', 30 | z: 'asx', x: 'zsdc', c: 'xdfv', v: 'cfgb', b: 'vghn', n: 'bhjm', m: 'njk', 31 | }; 32 | this.qwertz = { 33 | 1: '2q', 2: '3wq1', 3: '4ew2', 4: '5re3', 5: '6tr4', 6: '7zt5', 7: '8uz6', 8: '9iu7', 9: '0oi8', 0: 'po9', 34 | q: '12wa', w: '3esaq2', e: '4rdsw3', r: '5tfde4', t: '6zgfr5', z: '7uhgt6', u: '8ijhz7', i: '9okju8', o: '0plki9', p: 'lo0', 35 | a: 'qwsy', s: 'edxyaw', d: 'rfcxse', f: 'tgvcdr', g: 'zhbvft', h: 'ujnbgz', j: 'ikmnhu', k: 'olmji', l: 'kop', 36 | y: 'asx', x: 'ysdc', c: 'xdfv', v: 'cfgb', b: 'vghn', n: 'bhjm', m: 'njk', 37 | }; 38 | this.azerty = { 39 | 1: '2a', 2: '3za1', 3: '4ez2', 4: '5re3', 5: '6tr4', 6: '7yt5', 7: '8uy6', 8: '9iu7', 9: '0oi8', 0: 'po9', 40 | a: '2zq1', z: '3esqa2', e: '4rdsz3', r: '5tfde4', t: '6ygfr5', y: '7uhgt6', u: '8ijhy7', i: '9okju8', o: '0plki9', p: 'lo0m', 41 | q: 'zswa', s: 'edxwqz', d: 'rfcxse', f: 'tgvcdr', g: 'yhbvft', h: 'ujnbgy', j: 'iknhu', k: 'olji', l: 'kopm', m: 'lp', 42 | w: 'sxq', x: 'zsdc', c: 'xdfv', v: 'cfgb', b: 'vghn', n: 'bhj', 43 | }; 44 | 45 | this.keyboards = [this.qwerty, this.qwertz, this.azerty]; 46 | } 47 | 48 | __domain_tld(domain) { 49 | domain = rsplit(domain, '.', 2); 50 | if (domain.length === 2) { 51 | return [domain[0], domain[1]]; 52 | } 53 | const cc_tld = {}; 54 | const re_tld = /^[a-z]{2,4}\.[a-z]{2}$/i; 55 | 56 | const data = fs.readFileSync(CONF.TLD_FILE); 57 | const lines = data.toString().split('\n'); 58 | for (const line of lines) { 59 | if (re_tld.test(line)) { 60 | const [sld, tld] = line.split('.'); 61 | if (!Reflect.has(cc_tld, tld)) { 62 | cc_tld[tld] = []; 63 | } 64 | cc_tld[tld].push(sld); 65 | } 66 | } 67 | const sld_tld = Reflect.get(cc_tld, domain[2]); 68 | if (sld_tld) { 69 | if (sld_tld.includes(domain[1])) { 70 | return [domain[0], domain[1] + '.' + domain[2]]; 71 | } 72 | } 73 | return [`${domain[0]}.${domain[1]}`, domain[2]]; 74 | } 75 | 76 | __validate_domain() { 77 | let domain = this.domain; 78 | if (domain.endsWith('.')) { 79 | domain = domain.substr(0, domain.length - 1); 80 | } 81 | if (domain.length > 255) { 82 | return false; 83 | } 84 | return true; 85 | } 86 | 87 | __filter_domains() { 88 | const domains = this.domains; 89 | const seen = new Set(); 90 | const filtered = []; 91 | for (const domain of domains) { 92 | if (this.__validate_domain(domain['domain-name']) && !seen.has(domain['domain-name'])) { 93 | seen.add(domain['domain-name']); 94 | filtered.push(domain); 95 | } 96 | } 97 | return filtered; 98 | } 99 | 100 | __bitsquatting() { 101 | const domain = this.domain; 102 | const result = []; 103 | const masks = [1, 2, 4, 8, 16, 32, 64, 128]; 104 | for (let i = 0; i < domain.length; i++) { 105 | const c = domain[i]; 106 | for (let j = 0; j < masks.length; j++) { 107 | const b = String.fromCharCode(c.charCodeAt() ^ masks[j]); 108 | const o = b.charCodeAt(); 109 | if ((o >= 48 && o <= 57) || (o >= 97 && o <= 122) || o === 45) { 110 | result.push(domain.substr(0, i) + b + domain.substr(i + 1)); 111 | } 112 | } 113 | } 114 | return result; 115 | } 116 | 117 | 118 | __homoglyph() { 119 | const domain = this.domain; 120 | const glyphs = { 121 | a: ['à', 'á', 'â', 'ã', 'ä', 'å', 'ɑ', 'а', 'ạ'], 122 | b: ['d', 'lb', 'ib', 'ʙ', 'Ь', 'b'], 123 | c: ['ϲ', 'с', 'ⅽ', 'ƈ', 'ċ', 'ć'], 124 | d: ['b', 'cl', 'dl', 'di', 'ԁ', 'ժ', 'ⅾ', 'd', 'ɗ'], 125 | e: ['é', 'ê', 'ë', 'ē', 'ĕ', 'ė', 'e', 'е', 'ẹ', 'ę'], 126 | f: ['Ϝ', 'F', 'f'], 127 | g: ['q', 'ɢ', 'ɡ', 'Ԍ', 'Ԍ', 'g', 'ġ'], 128 | h: ['lh', 'ih', 'һ', 'h'], 129 | i: ['1', 'l', 'Ꭵ', 'ⅰ', 'i', 'í', 'ï'], 130 | j: ['ј', 'j', 'ʝ'], 131 | k: ['lk', 'ik', 'lc', 'κ', 'k'], 132 | l: ['1', 'i', 'ⅼ', 'l'], 133 | m: ['n', 'nn', 'rn', 'rr', 'ṃ', 'ⅿ', 'm'], 134 | n: ['m', 'r', 'n', 'ń'], 135 | o: ['0', 'Ο', 'ο', 'О', 'о', 'Օ', 'O', 'o', 'ȯ', 'ọ', 'ỏ', 'ơ', 'ó'], 136 | p: ['ρ', 'р', 'p'], 137 | q: ['g', 'q', 'զ'], 138 | r: ['ʀ', 'r'], 139 | s: ['Ⴝ', 'Ꮪ', 'S', 's', 'ʂ', 'ś'], 140 | t: ['τ', 't'], 141 | u: ['μ', 'υ', 'Ս', 'U', 'u', 'ս'], 142 | v: ['v', 'ѵ', 'ⅴ', 'ν'], 143 | w: ['vv', 'ѡ', 'w'], 144 | x: ['ⅹ', 'x', 'х', 'ҳ'], 145 | y: ['ʏ', 'γ', 'у', 'Ү', 'y', 'ý'], 146 | z: ['z', 'ʐ', 'ż', 'ź', 'ʐ'], 147 | }; 148 | const result = []; 149 | for (let ws = 0; ws < domain.length; ws++) { 150 | for (let i = 0; i < (domain.length - ws + 1); i++) { 151 | let win = domain.substr(i, ws); 152 | let j = 0; 153 | while (j < ws) { 154 | const c = win[j]; 155 | if (Reflect.has(glyphs, c)) { 156 | const win_copy = win; 157 | for (const _ in glyphs[c]) { 158 | const g = glyphs[c][_]; 159 | win = win.replace(c, g); 160 | result.push(`${domain.substr(0, i)}${win}${domain.substr(i + ws)}`); 161 | win = win_copy; 162 | } 163 | } 164 | j += 1; 165 | } 166 | } 167 | } 168 | return Array.from(new Set(result)); 169 | } 170 | 171 | __hyphenation() { 172 | const domain = this.domain; 173 | const result = []; 174 | for (let i = 1; i < domain.length; i++) { 175 | const _ = `${domain.substr(0, i)}-${domain.substr(i)}`; 176 | result.push(_); 177 | } 178 | return result; 179 | } 180 | 181 | __insertion() { 182 | const domain = this.domain; 183 | const keyboards = this.keyboards; 184 | 185 | const result = []; 186 | for (let i = 1; i < domain.length - 1; i++) { 187 | for (const keys of keyboards) { 188 | if (Reflect.has(keys, (domain.substr(i, 1)))) { 189 | for (const c of keys[domain.substr(i, 1)]) { 190 | result.push(domain.substr(0, i) + c + domain.substr(i, 1) + domain.substr(i + 1)); 191 | result.push(domain.substr(0, i) + domain.substr(i, 1) + c + domain.substr(i + 1)); 192 | } 193 | } 194 | } 195 | } 196 | return Array.from(new Set(result)); 197 | } 198 | 199 | __omission() { 200 | const domain = this.domain; 201 | const result = []; 202 | if (domain.length > 1) { 203 | for (let i = 0; i < domain.length; i++) { 204 | result.push(domain.substr(0, i) + domain.substr(i + 1)); 205 | } 206 | } 207 | return Array.from(new Set(result)); 208 | } 209 | 210 | __repetition() { 211 | const domain = this.domain; 212 | const result = []; 213 | for (let i = 0; i < domain.length; i++) { 214 | result.push(domain.substr(0, i) + domain.substr(i, 1) + domain.substr(i, 1) + domain.substr(i + 1)); 215 | } 216 | return Array.from(new Set(result)); 217 | } 218 | 219 | __replacement() { 220 | const domain = this.domain; 221 | const keyboards = this.keyboards; 222 | const result = []; 223 | for (let i = 0; i < domain.length; i++) { 224 | for (const keys of keyboards) { 225 | if (Reflect.has(keys, (domain.substr(i, 1)))) { 226 | for (const c of keys[domain.substr(i, 1)]) { 227 | result.push(domain.substr(0, i) + c + domain.substr(i + 1)); 228 | } 229 | } 230 | } 231 | } 232 | return Array.from(new Set(result)); 233 | } 234 | 235 | __subdomain() { 236 | const domain = this.domain; 237 | const result = []; 238 | for (let i = 1; i < domain.length; i++) { 239 | if (!['-', '.'].includes(domain.substr(i, 1)) && !['-', '.'].includes(domain.substr(i + 1, 1))) { 240 | result.push(`${domain.substr(0, i)}.${domain.substr(i)}`); 241 | } 242 | } 243 | return Array.from(new Set(result)); 244 | } 245 | 246 | __transposition() { 247 | const domain = this.domain; 248 | const result = []; 249 | for (let i = 0; i < domain.length - 1; i++) { 250 | if (domain.substr(i + 1, 1) !== domain.substr(i, 1)) { 251 | result.push(domain.substr(0, i) + domain.substr(i + 1, 1) + domain.substr(i, 1) + domain.substr(i + 2)); 252 | } 253 | } 254 | return Array.from(new Set(result)); 255 | } 256 | 257 | __vowel_swap() { 258 | const domain = this.domain; 259 | const vowels = 'aeiou'; 260 | const result = []; 261 | for (let i = 0; i < domain.length; i++) { 262 | for (const vowel of vowels) { 263 | if (vowels.includes(domain.substr(i, 1))) { 264 | result.push(domain.substr(0, i) + vowel + domain.substr(i + 1)); 265 | } 266 | } 267 | } 268 | return Array.from(new Set(result)); 269 | } 270 | 271 | __addition() { 272 | const domain = this.domain; 273 | const result = []; 274 | for (let i = 97; i < 123; i++) { 275 | result.push(domain + String.fromCharCode(i)); 276 | } 277 | return Array.from(new Set(result)); 278 | } 279 | 280 | __various() { 281 | const domain = this.domain; 282 | const prefixs = ['ww', 'www', 'www-']; 283 | const result = []; 284 | for (const prefix of prefixs) { 285 | result.push(prefix + domain); 286 | } 287 | return result; 288 | } 289 | 290 | generate() { 291 | this.domains.push({ fuzzer: 'Original*', 'domain-name': this.domain + '.' + this.tld }); 292 | for (const domain of this.__addition()) { 293 | this.domains.push({ fuzzer: 'Addition', 'domain-name': `${domain}.${this.tld}` }); 294 | } 295 | for (const domain of this.__bitsquatting()) { 296 | this.domains.push({ fuzzer: 'Bitsquatting', 'domain-name': `${domain}.${this.tld}` }); 297 | } 298 | for (const domain of this.__homoglyph()) { 299 | this.domains.push({ fuzzer: 'Homoglyph', 'domain-name': `${domain}.${this.tld}` }); 300 | } 301 | for (const domain of this.__hyphenation()) { 302 | this.domains.push({ fuzzer: 'Hyphenation', 'domain-name': `${domain}.${this.tld}` }); 303 | } 304 | for (const domain of this.__insertion()) { 305 | this.domains.push({ fuzzer: 'Insertion', 'domain-name': `${domain}.${this.tld}` }); 306 | } 307 | for (const domain of this.__omission()) { 308 | this.domains.push({ fuzzer: 'Omission', 'domain-name': `${domain}.${this.tld}` }); 309 | } 310 | for (const domain of this.__repetition()) { 311 | this.domains.push({ fuzzer: 'Repetition', 'domain-name': `${domain}.${this.tld}` }); 312 | } 313 | for (const domain of this.__replacement()) { 314 | this.domains.push({ fuzzer: 'Replacement', 'domain-name': `${domain}.${this.tld}` }); 315 | } 316 | for (const domain of this.__subdomain()) { 317 | this.domains.push({ fuzzer: 'Subdomain', 'domain-name': `${domain}.${this.tld}` }); 318 | } 319 | for (const domain of this.__transposition()) { 320 | this.domains.push({ fuzzer: 'Transposition', 'domain-name': `${domain}.${this.tld}` }); 321 | } 322 | for (const domain of this.__vowel_swap()) { 323 | this.domains.push({ fuzzer: 'Vowel-swap', 'domain-name': `${domain}.${this.tld}` }); 324 | } 325 | if (!this.domain.startsWith('www.')) { 326 | for (const domain of this.__various()) { 327 | this.domains.push({ fuzzer: 'Various', 'domain-name': `${domain}.${this.tld}` }); 328 | } 329 | } 330 | if (this.tld.includes('.')) { 331 | this.domains.push({ fuzzer: 'Various', 'domain-name': `${this.domain}.${this.tld.split('.')[this.tld.split('.').length - 1]}` }); 332 | this.domains.push({ fuzzer: 'Various', 'domain-name': this.domain + this.tld }); 333 | } else { 334 | this.domains.push({ fuzzer: 'Various', 'domain-name': `${this.domain + this.tld}.${this.tld}` }); 335 | } 336 | if (this.tld !== 'com' && !this.tld.includes('.')) { 337 | this.domains.push({ fuzzer: 'Various', 'domain-name': `${this.domain}-${this.tld}.com` }); 338 | } 339 | 340 | this.__filter_domains(); 341 | } 342 | } 343 | 344 | class DomainDict extends DomainFuzz { 345 | constructor(domain) { 346 | super(domain); 347 | this.dictionary = []; 348 | } 349 | load_dict(file) { 350 | if (fs.existsSync(file)) { 351 | const data = fs.readFileSync(file); 352 | for (let word of data.toString().split('\n')) { 353 | word = word.trim(); 354 | if (word && !word.startsWith('//')) { 355 | this.dictionary.push(word); 356 | } 357 | } 358 | } 359 | } 360 | 361 | __dirtionary() { 362 | const result = []; 363 | const domain = rsplit(this.domain, '.', 1); 364 | let prefix; 365 | let name; 366 | if (domain.length > 1) { 367 | prefix = `${domain[0]}.`; 368 | name = domain[1]; 369 | } else { 370 | prefix = ''; 371 | name = domain[0]; 372 | } 373 | for (const word of this.dictionary) { 374 | result.push(`${prefix + name}-${word}`); 375 | result.push(prefix + name + word); 376 | result.push(`${prefix + word}-${name}`); 377 | result.push(prefix + word + name); 378 | } 379 | return result; 380 | } 381 | 382 | generate() { 383 | for (const domain of this.__dirtionary()) { 384 | this.domains.push({ fuzzer: 'Dictionary', 'domain-name': `${domain}.${this.tld}` }); 385 | } 386 | } 387 | } 388 | 389 | class DomainThread { 390 | constructor(domain) { 391 | this.domain = domain; 392 | this.ssdeep_orig = ''; 393 | this.domain_orig = ''; 394 | this.target = ''; 395 | 396 | this.option_output = ''; 397 | this.option_format = ''; 398 | this.concurrency = 0; 399 | 400 | this.nameservers = false; 401 | this.option_geoip = false; 402 | this.option_whois = false; 403 | this.option_ssdeep = false; 404 | this.option_banners = false; 405 | this.option_mxcheck = false; 406 | } 407 | 408 | __banner_http(ip, vhost, callback) { 409 | const port = 80; 410 | const socket = net.createConnection({ port, host: ip }); 411 | socket.write(`HEAD / HTTP/1.1\r\nHost: ${vhost}\r\nUser-agent: Mozilla/5.0\r\n\r\n`); 412 | let data = Buffer(''); 413 | socket 414 | .setTimeout(CONF.REQUEST_BANNER_TIMEOUT) 415 | .on('data', (chunk) => { 416 | data = Buffer.concat([data, chunk]); 417 | socket.end(); 418 | }) 419 | .on('error', () => null) 420 | .on('end', () => { 421 | const response = data.toString('utf8'); 422 | const sep = response.includes('\r\n') ? '\r\n' : '\n'; 423 | const headers = response.split(sep); 424 | for (const field of headers) { 425 | if (field.startsWith('Server: ')) { 426 | return callback(null, field.substr(8)); 427 | } 428 | } 429 | const banner = headers[0].split(' '); 430 | if (banner.length > 1) { 431 | return callback(null, `HTTP ${banner[1]}`); 432 | } 433 | }); 434 | } 435 | 436 | __banner_smtp(ip, callback) { 437 | const port = 25; 438 | const socket = net.createConnection({ port, host: ip }); 439 | let data = Buffer(''); 440 | socket 441 | .setTimeout(CONF.REQUEST_BANNER_TIMEOUT) 442 | .on('data', (chunk) => { 443 | data = Buffer.concat([data, chunk]); 444 | socket.end(); 445 | }) 446 | .on('error', () => null) 447 | .on('end', () => { 448 | const response = data.toString('utf8'); 449 | const sep = response.includes('\r\n') ? '\r\n' : '\n'; 450 | const hello = response.split(sep)[0]; 451 | if (hello.startsWith('220')) { 452 | return callback(null, hello.substr(4).trim()); 453 | } 454 | return callback(null, hello.substr(0, 40)); 455 | }); 456 | } 457 | 458 | __mxcheck(mx, from_domain, to_domain, callback) { 459 | const from_addr = `randomgenius${Math.floor(Math.random() * 10)}@${from_domain}`; 460 | const to_addr = `randommaster${Math.floor(Math.random() * 10)}@${to_domain}`; 461 | const transportOptions = { 462 | host: mx, 463 | port: 25, 464 | greetingTimeout: CONF.REQUEST_BANNER_TIMEOUT, 465 | connectionTimeout: CONF.REQUEST_BANNER_TIMEOUT, 466 | socketTimeout: CONF.REQUEST_BANNER_TIMEOUT, 467 | }; 468 | debug(`Transport Options: ${JSON.stringify(transportOptions)}`); 469 | const transporter = nodemailer.createTransport(); 470 | const mailOptions = { 471 | from: from_addr, 472 | to: to_addr, 473 | text: `${CONF.name} MX Check.`, 474 | }; 475 | transporter.sendMail(mailOptions, (err, info) => { 476 | debug(`Send Mail: ${err ? err.message : info.message + info.response}`); 477 | callback(!err); 478 | }); 479 | } 480 | 481 | run(domain) { 482 | const domainName = url.domainToASCII(domain['domain-name']); 483 | const names = `${domainName}(${domain['domain-name']})`; 484 | if (domain['domain-name'] !== domainName) { 485 | domain['domain-name-ascii'] = domainName; 486 | } 487 | // Fetch NS Resolve 488 | if (this.nameservers && this.nameservers.length) { 489 | try { 490 | dns.setServers(this.nameservers); 491 | } catch (err) { 492 | printError('Set nameserver failed.'); 493 | } 494 | } 495 | return new Promise((callback) => { 496 | new Promise((resolve) => { 497 | dns.resolve(domainName, 'NS', (err, res) => { 498 | if (err) { 499 | debug(`${names} DNS NS query NS error: ${res}`); 500 | return resolve(false); 501 | } 502 | debug(`${names} DNS NS query: ${res}`); 503 | resolve(res); 504 | }); 505 | }) 506 | .then((ns) => { 507 | if (ns) domain['dns-ns'] = ns; 508 | // resolve A 509 | new Promise((resolve, reject) => { 510 | dns.resolve(domainName, 'A', (err, res) => { 511 | if (err) return reject(err); 512 | debug(`${names} DNS A query: ${res}`); 513 | resolve(res); 514 | }); 515 | }) 516 | .then((resolveA) => { 517 | if (resolveA) domain['dns-a'] = resolveA; 518 | const fetchAAAA = new Promise((resolve, reject) => { 519 | dns.resolve(domainName, 'AAAA', (err, res) => { 520 | if (err) return reject(err); 521 | if (!res.length) return resolve(false); 522 | debug(`${names} DNS AAAA query: ${res}`); 523 | resolve(res); 524 | }); 525 | }); 526 | 527 | return fetchAAAA; 528 | }) 529 | .then((resolveAAAA) => { 530 | if (resolveAAAA) domain['dns-aaaa'] = resolveAAAA; 531 | const fetchMX = new Promise((resolve, reject) => { 532 | dns.resolve(domainName, 'MX', (err, res) => { 533 | if (err) return reject(err); 534 | const resolves = res.map((_) => _.exchange); 535 | debug(`${names} DNS MX query: ${JSON.stringify(resolves)}`); 536 | resolve(resolves); 537 | }); 538 | }); 539 | return fetchMX; 540 | }) 541 | .then((resolveMX) => { 542 | if (resolveMX) domain['dns-mx'] = resolveMX; 543 | }) 544 | .catch((err) => { 545 | debug(`${names} DNS query error: ${err.message}`); 546 | }); 547 | }) 548 | .then(() => { 549 | const fetchWhois = new Promise((resolve) => { 550 | const isRegistered = !!(Reflect.has(domain, 'dns-ns') || !Reflect.has(domain, 'dns-a')) 551 | if (!isRegistered) { 552 | debug(`[WHOIS] ${domain['domain-name']}(${domainName}). Domain is not registered.`); 553 | resolve(false); 554 | return false; 555 | } 556 | libwhois(domainName, (err, res) => { 557 | if (err) { 558 | debug(`[WHOIS] ${domain['domain-name']}(${domainName}). Query error. ${err}`); 559 | resolve(false); 560 | return false; 561 | } 562 | const { creationDate, updatedDate } = res; 563 | debug(`[WHOIS] ${domain['domain-name']}(${domainName}) Whois query result: ${JSON.stringify({ creationDate, updatedDate })}`); 564 | return resolve({ creationDate, updatedDate }); 565 | }); 566 | }); 567 | if (this.option_whois) { 568 | return fetchWhois; 569 | } 570 | }) 571 | .then((whois) => { 572 | if (whois) { 573 | const { creationDate, updatedDate } = whois; 574 | if (creationDate) domain['whois-created'] = creationDate; 575 | if (updatedDate) domain['whois-updated'] = updatedDate; 576 | } 577 | const fetchGeoip = new Promise((resolve) => { 578 | const hasResolveA = Reflect.has(domain, 'dns-a'); 579 | if (!hasResolveA) { 580 | debug(`[GEOIP2] ${domain['domain-name']}(${domainName}). Domain has not resolve A.`); 581 | resolve(false); 582 | return false; 583 | } 584 | geoip2.lookupSimple(domain['dns-a'][0], (err, res) => { 585 | if (err) { 586 | debug(`[GEOIP2] ${domain['domain-name']}(${domainName}). ${err.message}`); 587 | return resolve(false); 588 | } 589 | if (!res) { 590 | return resolve(false); 591 | } 592 | debug(`[GEOIP2] ${domain['domain-name']}(${domainName}). ${res.country}`); 593 | resolve(res.country); 594 | }); 595 | }); 596 | if (this.option_geoip) { 597 | return fetchGeoip; 598 | } 599 | return false; 600 | }) 601 | .then((country) => { 602 | if (country) { 603 | domain['geoip-country'] = country; 604 | } 605 | const fetchBannerHTTP = new Promise((resolve) => { 606 | const hasResolveA = Reflect.has(domain, 'dns-a'); 607 | if (!hasResolveA) { 608 | debug(`[BANNERS][HTTP] ${domain['domain-name']}(${domainName}). Domain has not resolve A.`); 609 | resolve(false); 610 | return false; 611 | } 612 | this.__banner_http(domain['dns-a'][0], domainName, (err, banner) => { 613 | if (err) { 614 | debug(`[BANNERS][HTTP] ${domain['domain-name']}(${domainName}). Fetch banner HTTP error: ${err}`); 615 | resolve(false); 616 | return false; 617 | } 618 | debug(`[BANNERS][HTTP] ${domain['domain-name']}(${domainName}): ${banner}`); 619 | resolve(banner); 620 | }); 621 | }); 622 | if (this.option_banners) { 623 | return fetchBannerHTTP; 624 | } 625 | return false; 626 | }) 627 | .then((bannerHTTP) => { 628 | if (bannerHTTP) domain['banner-http'] = bannerHTTP; 629 | 630 | const fetchBannerSMTP = new Promise((resolve) => { 631 | const hasResolveMX = Reflect.has(domain, 'dns-mx'); 632 | if (!hasResolveMX) { 633 | debug(`[BANNERS][SMTP] ${domain['domain-name']}(${domainName}). Domain has not resolve MX.`); 634 | resolve(false); 635 | return false; 636 | } 637 | this.__banner_smtp(domain['dns-mx'][0], (err, banner) => { 638 | if (err) { 639 | debug(`[BANNERS][SMTP] ${domain['domain-name']}(${domainName}).Fetch Banner SMTP Error: ${err}`); 640 | resolve(false); 641 | } 642 | debug(`[BANNERS][SMTP] ${domain['domain-name']}(${domainName}). Banner SMTP: ${banner}`); 643 | resolve(banner); 644 | }); 645 | }); 646 | 647 | if (this.option_banners) { 648 | return fetchBannerSMTP; 649 | } 650 | return false; 651 | }) 652 | .then((bannerSMTP) => { 653 | if (bannerSMTP) domain['banner-smtp'] = bannerSMTP; 654 | 655 | const fetchSSDEEP = new Promise((resolve) => { 656 | const hasResolveA = Reflect.has(domain, 'dns-a'); 657 | if (!hasResolveA) { 658 | debug(`[SSDEEP] ${domain['domain-name']}(${domainName}). Domain has not resolve A.`); 659 | resolve(false); 660 | return false; 661 | } 662 | const options = { url: this.target.href, method: 'GET', timeout: CONF.REQUEST_BANNER_TIMEOUT }; 663 | const headers = { 'User-Agent': `Mozilla/5.0 ${CONF.name}/${CONF.version}` }; 664 | options.headers = headers; 665 | debug(`[SSDEEP] ${domain['domain-name']}(${domainName}). Request Options: ${JSON.stringify(options)}`); 666 | request(options, (err, res, body) => { 667 | if (err) { 668 | resolve(false); 669 | return false; 670 | } 671 | if (res.statusCode === 200) { 672 | const ssdeep_fuzz = libssdeep.hash(body); 673 | const ssdeepScore = libssdeep.compare(this.ssdeep_orig, ssdeep_fuzz); 674 | debug(`SSDEEP Score: ${ssdeepScore}`); 675 | resolve(ssdeepScore); 676 | } 677 | resolve(false); 678 | }); 679 | }); 680 | 681 | if (this.option_ssdeep) { 682 | return fetchSSDEEP; 683 | } 684 | }) 685 | .then((ssdeepScore) => { 686 | if (ssdeepScore) domain['ssdeep-score'] = ssdeepScore; 687 | }) 688 | .then(() => { 689 | callback(domain); 690 | }) 691 | .catch((err) => { 692 | printError(err); 693 | }); 694 | }); 695 | } 696 | } 697 | 698 | exports.DomainFuzz = DomainFuzz; 699 | exports.DomainDict = DomainDict; 700 | exports.DomainThread = DomainThread; 701 | -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const url = require('url'); 3 | const _ = require('lodash'); 4 | const chalk = require('chalk'); 5 | const CONF = require('../config'); 6 | 7 | exports.rsplit = (str, sep, maxsplit) => { 8 | const split = str.split(sep); 9 | if (split.length > maxsplit) { 10 | return maxsplit ? [split.slice(0, -maxsplit).join(sep)].concat(split.slice(-maxsplit)) : split; 11 | } 12 | return split; 13 | }; 14 | 15 | exports.printError = (data) => { 16 | console.error(chalk.red(`Error: ${data}`)); 17 | }; 18 | 19 | exports.printInfo = (data) => { 20 | console.log(chalk.bold(data)); 21 | }; 22 | 23 | exports.parseTarget = (target) => { 24 | let targetCopy = url.parse(target); 25 | if (!targetCopy.protocol) { 26 | targetCopy = url.parse(`http://${target}`); 27 | } 28 | return targetCopy; 29 | }; 30 | 31 | exports.bye = (code) => { 32 | process.exit(code); 33 | }; 34 | 35 | exports.printBanner = () => { 36 | const data = fs.readFileSync(CONF.banner); 37 | const content = data.toString('utf8'); 38 | const sep = '\n'.repeat(6); 39 | const banners = content.split(sep); 40 | let banner = _.sample(banners); 41 | const version = `{${CONF.version}}`; 42 | const prefix = banner.substr(0, banner.length - version.length - 1); 43 | const append = banner.substr(banner.length - 1, 1); 44 | banner = prefix; 45 | banner += `${chalk.bold(version)}${append}\n\n`; 46 | const colors = [chalk.green, chalk.cyan, chalk.magenta, chalk.yellow]; 47 | const color = _.sample(colors); 48 | console.log(color(banner)); 49 | }; 50 | 51 | exports.printResult = (domain) => { 52 | const line = []; 53 | line.push(chalk.blue(domain['domain-name'])); 54 | if (Reflect.has(domain, 'dns-a')) { 55 | line.push(`${chalk.yellow('A')}: ${domain['dns-a']}`); 56 | if (Reflect.has(domain, 'geoip-country')) { 57 | line.push(`(${domain['geoip-country']})`); 58 | } 59 | } 60 | if (Reflect.has(domain, 'dns-aaaa')) { 61 | line.push(`${chalk.yellow('AAAA')}: ${domain['dns-aaaa']}`); 62 | } 63 | if (Reflect.has(domain, 'dns-ns')) { 64 | line.push(`${chalk.yellow('NS')}: ${domain['dns-ns']}`); 65 | } 66 | if (Reflect.has(domain, 'dns-mx')) { 67 | line.push(`${chalk.yellow('MX')}: ${domain['dns-mx']}`); 68 | } 69 | if (Reflect.has(domain, 'banner-http')) { 70 | line.push(`${chalk.yellow('HTTP')}: ${domain['banner-http']}`); 71 | } 72 | if (Reflect.has(domain, 'banner-smtp')) { 73 | line.push(`${chalk.yellow('SMTP')}: ${domain['banner-smtp']}`); 74 | } 75 | if (Reflect.has(domain, 'whois-created')) { 76 | line.push(`${chalk.yellow('WHOIS')}: ${domain['whois-created']}`); 77 | if (Reflect.has(domain, 'whois-updated')) { 78 | line.push(`${domain['whois-updated']}`); 79 | } 80 | } 81 | if (Reflect.has(domain, 'ssdeep-score')) { 82 | line.push(`${chalk.yellow('SSDEEP')}: ${domain['ssdeep-score']}`); 83 | } 84 | // console.log(line); 85 | if (line.length < 2) line.push('-'); 86 | console.log(line.join(' ')); 87 | }; 88 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "domain-fuzz", 3 | "version": "0.0.1", 4 | "author": "M4ster ", 5 | "description": "Find similar-looking domain names that adversaries can use to attack you. Can detect typosquatters, phishing attacks, fraud and corporate espionage. Useful as an additional source of targeted threat intelligence.", 6 | "main": "lib/", 7 | "license": "MIT", 8 | "dependencies": { 9 | "bluebird": "^3.5.0", 10 | "chalk": "^1.1.3", 11 | "commander": "^2.9.0", 12 | "csv": "^1.1.1", 13 | "debug": "^2.6.4", 14 | "geoip2": "^1.0.5", 15 | "lodash": "^4.17.4", 16 | "nodemailer": "^4.0.1", 17 | "progress": "^2.0.0", 18 | "request": "^2.81.0", 19 | "ssdeep": "^0.1.1", 20 | "whois-json": "^1.2.2" 21 | }, 22 | "bin": { 23 | "domainfuzz": "./cli.js" 24 | }, 25 | "engines": { 26 | "node": ">=7.0" 27 | }, 28 | "keywords": [ 29 | "fuzz", 30 | "domain", 31 | "phishing", 32 | "typosquatting", 33 | "domains", 34 | "dns" 35 | ], 36 | "devDependencies": { 37 | "chai": "^3.5.0", 38 | "eslint": "^3.19.0", 39 | "eslint-config-airbnb": "^14.1.0", 40 | "eslint-plugin-import": "^2.2.0", 41 | "eslint-plugin-jsx-a11y": "^4.0.0", 42 | "eslint-plugin-react": "^6.10.3", 43 | "mocha": "^3.3.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | acorn-jsx@^3.0.0: 6 | version "3.0.1" 7 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" 8 | dependencies: 9 | acorn "^3.0.4" 10 | 11 | acorn@^3.0.4: 12 | version "3.3.0" 13 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" 14 | 15 | acorn@^5.0.1: 16 | version "5.0.3" 17 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d" 18 | 19 | ajv-keywords@^1.0.0: 20 | version "1.5.1" 21 | resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" 22 | 23 | ajv@^4.7.0, ajv@^4.9.1: 24 | version "4.11.7" 25 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.7.tgz#8655a5d86d0824985cc471a1d913fb6729a0ec48" 26 | dependencies: 27 | co "^4.6.0" 28 | json-stable-stringify "^1.0.1" 29 | 30 | ansi-escapes@^1.1.0: 31 | version "1.4.0" 32 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" 33 | 34 | ansi-regex@^2.0.0: 35 | version "2.1.1" 36 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 37 | 38 | ansi-styles@^2.2.1: 39 | version "2.2.1" 40 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 41 | 42 | argparse@^1.0.7: 43 | version "1.0.9" 44 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" 45 | dependencies: 46 | sprintf-js "~1.0.2" 47 | 48 | aria-query@^0.3.0: 49 | version "0.3.0" 50 | resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-0.3.0.tgz#cb8a9984e2862711c83c80ade5b8f5ca0de2b467" 51 | dependencies: 52 | ast-types-flow "0.0.7" 53 | 54 | array-union@^1.0.1: 55 | version "1.0.2" 56 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" 57 | dependencies: 58 | array-uniq "^1.0.1" 59 | 60 | array-uniq@^1.0.1: 61 | version "1.0.3" 62 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" 63 | 64 | array.prototype.find@^2.0.1: 65 | version "2.0.4" 66 | resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.0.4.tgz#556a5c5362c08648323ddaeb9de9d14bc1864c90" 67 | dependencies: 68 | define-properties "^1.1.2" 69 | es-abstract "^1.7.0" 70 | 71 | arrify@^1.0.0: 72 | version "1.0.1" 73 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" 74 | 75 | asn1@~0.2.3: 76 | version "0.2.3" 77 | resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" 78 | 79 | assert-plus@1.0.0, assert-plus@^1.0.0: 80 | version "1.0.0" 81 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" 82 | 83 | assert-plus@^0.2.0: 84 | version "0.2.0" 85 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" 86 | 87 | assertion-error@^1.0.1: 88 | version "1.0.2" 89 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" 90 | 91 | ast-types-flow@0.0.7: 92 | version "0.0.7" 93 | resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" 94 | 95 | asynckit@^0.4.0: 96 | version "0.4.0" 97 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 98 | 99 | aws-sign2@~0.6.0: 100 | version "0.6.0" 101 | resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" 102 | 103 | aws4@^1.2.1: 104 | version "1.6.0" 105 | resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" 106 | 107 | babel-code-frame@^6.16.0: 108 | version "6.22.0" 109 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" 110 | dependencies: 111 | chalk "^1.1.0" 112 | esutils "^2.0.2" 113 | js-tokens "^3.0.0" 114 | 115 | balanced-match@^0.4.1: 116 | version "0.4.2" 117 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" 118 | 119 | bcrypt-pbkdf@^1.0.0: 120 | version "1.0.1" 121 | resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" 122 | dependencies: 123 | tweetnacl "^0.14.3" 124 | 125 | bindings@1, bindings@~1.2.0: 126 | version "1.2.1" 127 | resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11" 128 | 129 | bluebird@^3.5.0: 130 | version "3.5.0" 131 | resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" 132 | 133 | boom@2.x.x: 134 | version "2.10.1" 135 | resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" 136 | dependencies: 137 | hoek "2.x.x" 138 | 139 | brace-expansion@^1.0.0: 140 | version "1.1.7" 141 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59" 142 | dependencies: 143 | balanced-match "^0.4.1" 144 | concat-map "0.0.1" 145 | 146 | browser-stdout@1.3.0: 147 | version "1.3.0" 148 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" 149 | 150 | buffer-shims@~1.0.0: 151 | version "1.0.0" 152 | resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" 153 | 154 | builtin-modules@^1.1.1: 155 | version "1.1.1" 156 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 157 | 158 | caller-path@^0.1.0: 159 | version "0.1.0" 160 | resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" 161 | dependencies: 162 | callsites "^0.2.0" 163 | 164 | callsites@^0.2.0: 165 | version "0.2.0" 166 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" 167 | 168 | camel-case@^1.1.1: 169 | version "1.2.2" 170 | resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-1.2.2.tgz#1aca7c4d195359a2ce9955793433c6e5542511f2" 171 | dependencies: 172 | sentence-case "^1.1.1" 173 | upper-case "^1.1.1" 174 | 175 | caseless@~0.12.0: 176 | version "0.12.0" 177 | resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" 178 | 179 | chai@^3.5.0: 180 | version "3.5.0" 181 | resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" 182 | dependencies: 183 | assertion-error "^1.0.1" 184 | deep-eql "^0.1.3" 185 | type-detect "^1.0.0" 186 | 187 | chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: 188 | version "1.1.3" 189 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 190 | dependencies: 191 | ansi-styles "^2.2.1" 192 | escape-string-regexp "^1.0.2" 193 | has-ansi "^2.0.0" 194 | strip-ansi "^3.0.0" 195 | supports-color "^2.0.0" 196 | 197 | "change-case@https://registry.npmjs.org/change-case/-/change-case-2.3.0.tgz": 198 | version "2.3.0" 199 | resolved "https://registry.npmjs.org/change-case/-/change-case-2.3.0.tgz#3d7c04e89dfe8119831ebf859c9e39558235a855" 200 | dependencies: 201 | camel-case "^1.1.1" 202 | constant-case "^1.1.0" 203 | dot-case "^1.1.0" 204 | is-lower-case "^1.1.0" 205 | is-upper-case "^1.1.0" 206 | lower-case "^1.1.1" 207 | lower-case-first "^1.0.0" 208 | param-case "^1.1.0" 209 | pascal-case "^1.1.0" 210 | path-case "^1.1.0" 211 | sentence-case "^1.1.1" 212 | snake-case "^1.1.0" 213 | swap-case "^1.1.0" 214 | title-case "^1.1.0" 215 | upper-case "^1.1.1" 216 | upper-case-first "^1.1.0" 217 | 218 | circular-json@^0.3.1: 219 | version "0.3.1" 220 | resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" 221 | 222 | cli-cursor@^1.0.1: 223 | version "1.0.2" 224 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" 225 | dependencies: 226 | restore-cursor "^1.0.1" 227 | 228 | cli-width@^2.0.0: 229 | version "2.1.0" 230 | resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" 231 | 232 | co@^4.6.0: 233 | version "4.6.0" 234 | resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" 235 | 236 | code-point-at@^1.0.0: 237 | version "1.1.0" 238 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 239 | 240 | combined-stream@^1.0.5, combined-stream@~1.0.5: 241 | version "1.0.5" 242 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" 243 | dependencies: 244 | delayed-stream "~1.0.0" 245 | 246 | commander@2.9.0, commander@^2.9.0: 247 | version "2.9.0" 248 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" 249 | dependencies: 250 | graceful-readlink ">= 1.0.0" 251 | 252 | concat-map@0.0.1: 253 | version "0.0.1" 254 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 255 | 256 | concat-stream@^1.5.2: 257 | version "1.6.0" 258 | resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" 259 | dependencies: 260 | inherits "^2.0.3" 261 | readable-stream "^2.2.2" 262 | typedarray "^0.0.6" 263 | 264 | constant-case@^1.1.0: 265 | version "1.1.2" 266 | resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-1.1.2.tgz#8ec2ca5ba343e00aa38dbf4e200fd5ac907efd63" 267 | dependencies: 268 | snake-case "^1.1.0" 269 | upper-case "^1.1.1" 270 | 271 | contains-path@^0.1.0: 272 | version "0.1.0" 273 | resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" 274 | 275 | core-util-is@~1.0.0: 276 | version "1.0.2" 277 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 278 | 279 | cryptiles@2.x.x: 280 | version "2.0.5" 281 | resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" 282 | dependencies: 283 | boom "2.x.x" 284 | 285 | csv-generate@^1.0.0: 286 | version "1.0.0" 287 | resolved "https://registry.yarnpkg.com/csv-generate/-/csv-generate-1.0.0.tgz#bd52886859d0c925f3e51f60f3abed262fa15caf" 288 | 289 | csv-parse@^1.2.0: 290 | version "1.2.0" 291 | resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-1.2.0.tgz#047b73868ab9a85746e885f637f9ed0fb645a425" 292 | 293 | csv-stringify@^1.0.0: 294 | version "1.0.4" 295 | resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-1.0.4.tgz#bc18bab9ad4cef3195fd257980b58b479c42d3e5" 296 | dependencies: 297 | lodash.get "^4.0.0" 298 | 299 | csv@^1.1.1: 300 | version "1.1.1" 301 | resolved "https://registry.yarnpkg.com/csv/-/csv-1.1.1.tgz#d9952d59b1f964a7afbcdd804d6818a73199a477" 302 | dependencies: 303 | csv-generate "^1.0.0" 304 | csv-parse "^1.2.0" 305 | csv-stringify "^1.0.0" 306 | stream-transform "^0.1.0" 307 | 308 | d@1: 309 | version "1.0.0" 310 | resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" 311 | dependencies: 312 | es5-ext "^0.10.9" 313 | 314 | damerau-levenshtein@^1.0.0: 315 | version "1.0.4" 316 | resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514" 317 | 318 | dashdash@^1.12.0: 319 | version "1.14.1" 320 | resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" 321 | dependencies: 322 | assert-plus "^1.0.0" 323 | 324 | debug@2, debug@^2.1.1, debug@^2.2.0, debug@^2.6.4: 325 | version "2.6.6" 326 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.6.tgz#a9fa6fbe9ca43cf1e79f73b75c0189cbb7d6db5a" 327 | dependencies: 328 | ms "0.7.3" 329 | 330 | debug@2.2.0: 331 | version "2.2.0" 332 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" 333 | dependencies: 334 | ms "0.7.1" 335 | 336 | debug@2.6.0: 337 | version "2.6.0" 338 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b" 339 | dependencies: 340 | ms "0.7.2" 341 | 342 | deep-eql@^0.1.3: 343 | version "0.1.3" 344 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" 345 | dependencies: 346 | type-detect "0.1.1" 347 | 348 | deep-is@~0.1.3: 349 | version "0.1.3" 350 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" 351 | 352 | define-properties@^1.1.2: 353 | version "1.1.2" 354 | resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" 355 | dependencies: 356 | foreach "^2.0.5" 357 | object-keys "^1.0.8" 358 | 359 | del@^2.0.2: 360 | version "2.2.2" 361 | resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" 362 | dependencies: 363 | globby "^5.0.0" 364 | is-path-cwd "^1.0.0" 365 | is-path-in-cwd "^1.0.0" 366 | object-assign "^4.0.1" 367 | pify "^2.0.0" 368 | pinkie-promise "^2.0.0" 369 | rimraf "^2.2.8" 370 | 371 | delayed-stream@~1.0.0: 372 | version "1.0.0" 373 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 374 | 375 | diff@3.2.0: 376 | version "3.2.0" 377 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" 378 | 379 | doctrine@1.5.0, doctrine@^1.2.2: 380 | version "1.5.0" 381 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" 382 | dependencies: 383 | esutils "^2.0.2" 384 | isarray "^1.0.0" 385 | 386 | doctrine@^2.0.0: 387 | version "2.0.0" 388 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" 389 | dependencies: 390 | esutils "^2.0.2" 391 | isarray "^1.0.0" 392 | 393 | dot-case@^1.1.0: 394 | version "1.1.2" 395 | resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-1.1.2.tgz#1e73826900de28d6de5480bc1de31d0842b06bec" 396 | dependencies: 397 | sentence-case "^1.1.2" 398 | 399 | ecc-jsbn@~0.1.1: 400 | version "0.1.1" 401 | resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" 402 | dependencies: 403 | jsbn "~0.1.0" 404 | 405 | emoji-regex@^6.1.0: 406 | version "6.4.2" 407 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.4.2.tgz#a30b6fee353d406d96cfb9fa765bdc82897eff6e" 408 | 409 | es-abstract@^1.7.0: 410 | version "1.7.0" 411 | resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c" 412 | dependencies: 413 | es-to-primitive "^1.1.1" 414 | function-bind "^1.1.0" 415 | is-callable "^1.1.3" 416 | is-regex "^1.0.3" 417 | 418 | es-to-primitive@^1.1.1: 419 | version "1.1.1" 420 | resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" 421 | dependencies: 422 | is-callable "^1.1.1" 423 | is-date-object "^1.0.1" 424 | is-symbol "^1.0.1" 425 | 426 | es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: 427 | version "0.10.15" 428 | resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.15.tgz#c330a5934c1ee21284a7c081a86e5fd937c91ea6" 429 | dependencies: 430 | es6-iterator "2" 431 | es6-symbol "~3.1" 432 | 433 | es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: 434 | version "2.0.1" 435 | resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" 436 | dependencies: 437 | d "1" 438 | es5-ext "^0.10.14" 439 | es6-symbol "^3.1" 440 | 441 | es6-map@^0.1.3: 442 | version "0.1.5" 443 | resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" 444 | dependencies: 445 | d "1" 446 | es5-ext "~0.10.14" 447 | es6-iterator "~2.0.1" 448 | es6-set "~0.1.5" 449 | es6-symbol "~3.1.1" 450 | event-emitter "~0.3.5" 451 | 452 | es6-set@~0.1.5: 453 | version "0.1.5" 454 | resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" 455 | dependencies: 456 | d "1" 457 | es5-ext "~0.10.14" 458 | es6-iterator "~2.0.1" 459 | es6-symbol "3.1.1" 460 | event-emitter "~0.3.5" 461 | 462 | es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: 463 | version "3.1.1" 464 | resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" 465 | dependencies: 466 | d "1" 467 | es5-ext "~0.10.14" 468 | 469 | es6-weak-map@^2.0.1: 470 | version "2.0.2" 471 | resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" 472 | dependencies: 473 | d "1" 474 | es5-ext "^0.10.14" 475 | es6-iterator "^2.0.1" 476 | es6-symbol "^3.1.1" 477 | 478 | escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: 479 | version "1.0.5" 480 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 481 | 482 | escope@^3.6.0: 483 | version "3.6.0" 484 | resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" 485 | dependencies: 486 | es6-map "^0.1.3" 487 | es6-weak-map "^2.0.1" 488 | esrecurse "^4.1.0" 489 | estraverse "^4.1.1" 490 | 491 | eslint-config-airbnb-base@^11.1.0: 492 | version "11.1.3" 493 | resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.1.3.tgz#0e8db71514fa36b977fbcf977c01edcf863e0cf0" 494 | 495 | eslint-config-airbnb@^14.1.0: 496 | version "14.1.0" 497 | resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-14.1.0.tgz#355d290040bbf8e00bf8b4b19f4b70cbe7c2317f" 498 | dependencies: 499 | eslint-config-airbnb-base "^11.1.0" 500 | 501 | eslint-import-resolver-node@^0.2.0: 502 | version "0.2.3" 503 | resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz#5add8106e8c928db2cba232bcd9efa846e3da16c" 504 | dependencies: 505 | debug "^2.2.0" 506 | object-assign "^4.0.1" 507 | resolve "^1.1.6" 508 | 509 | eslint-module-utils@^2.0.0: 510 | version "2.0.0" 511 | resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.0.0.tgz#a6f8c21d901358759cdc35dbac1982ae1ee58bce" 512 | dependencies: 513 | debug "2.2.0" 514 | pkg-dir "^1.0.0" 515 | 516 | eslint-plugin-import@^2.2.0: 517 | version "2.2.0" 518 | resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz#72ba306fad305d67c4816348a4699a4229ac8b4e" 519 | dependencies: 520 | builtin-modules "^1.1.1" 521 | contains-path "^0.1.0" 522 | debug "^2.2.0" 523 | doctrine "1.5.0" 524 | eslint-import-resolver-node "^0.2.0" 525 | eslint-module-utils "^2.0.0" 526 | has "^1.0.1" 527 | lodash.cond "^4.3.0" 528 | minimatch "^3.0.3" 529 | pkg-up "^1.0.0" 530 | 531 | eslint-plugin-jsx-a11y@^4.0.0: 532 | version "4.0.0" 533 | resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-4.0.0.tgz#779bb0fe7b08da564a422624911de10061e048ee" 534 | dependencies: 535 | aria-query "^0.3.0" 536 | ast-types-flow "0.0.7" 537 | damerau-levenshtein "^1.0.0" 538 | emoji-regex "^6.1.0" 539 | jsx-ast-utils "^1.0.0" 540 | object-assign "^4.0.1" 541 | 542 | eslint-plugin-react@^6.10.3: 543 | version "6.10.3" 544 | resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz#c5435beb06774e12c7db2f6abaddcbf900cd3f78" 545 | dependencies: 546 | array.prototype.find "^2.0.1" 547 | doctrine "^1.2.2" 548 | has "^1.0.1" 549 | jsx-ast-utils "^1.3.4" 550 | object.assign "^4.0.4" 551 | 552 | eslint@^3.19.0: 553 | version "3.19.0" 554 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" 555 | dependencies: 556 | babel-code-frame "^6.16.0" 557 | chalk "^1.1.3" 558 | concat-stream "^1.5.2" 559 | debug "^2.1.1" 560 | doctrine "^2.0.0" 561 | escope "^3.6.0" 562 | espree "^3.4.0" 563 | esquery "^1.0.0" 564 | estraverse "^4.2.0" 565 | esutils "^2.0.2" 566 | file-entry-cache "^2.0.0" 567 | glob "^7.0.3" 568 | globals "^9.14.0" 569 | ignore "^3.2.0" 570 | imurmurhash "^0.1.4" 571 | inquirer "^0.12.0" 572 | is-my-json-valid "^2.10.0" 573 | is-resolvable "^1.0.0" 574 | js-yaml "^3.5.1" 575 | json-stable-stringify "^1.0.0" 576 | levn "^0.3.0" 577 | lodash "^4.0.0" 578 | mkdirp "^0.5.0" 579 | natural-compare "^1.4.0" 580 | optionator "^0.8.2" 581 | path-is-inside "^1.0.1" 582 | pluralize "^1.2.1" 583 | progress "^1.1.8" 584 | require-uncached "^1.0.2" 585 | shelljs "^0.7.5" 586 | strip-bom "^3.0.0" 587 | strip-json-comments "~2.0.1" 588 | table "^3.7.8" 589 | text-table "~0.2.0" 590 | user-home "^2.0.0" 591 | 592 | espree@^3.4.0: 593 | version "3.4.2" 594 | resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.2.tgz#38dbdedbedc95b8961a1fbf04734a8f6a9c8c592" 595 | dependencies: 596 | acorn "^5.0.1" 597 | acorn-jsx "^3.0.0" 598 | 599 | esprima@^3.1.1: 600 | version "3.1.3" 601 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" 602 | 603 | esquery@^1.0.0: 604 | version "1.0.0" 605 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" 606 | dependencies: 607 | estraverse "^4.0.0" 608 | 609 | esrecurse@^4.1.0: 610 | version "4.1.0" 611 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220" 612 | dependencies: 613 | estraverse "~4.1.0" 614 | object-assign "^4.0.1" 615 | 616 | estraverse@^4.0.0, estraverse@^4.1.1, estraverse@^4.2.0: 617 | version "4.2.0" 618 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" 619 | 620 | estraverse@~4.1.0: 621 | version "4.1.1" 622 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2" 623 | 624 | esutils@^2.0.2: 625 | version "2.0.2" 626 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 627 | 628 | event-emitter@~0.3.5: 629 | version "0.3.5" 630 | resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" 631 | dependencies: 632 | d "1" 633 | es5-ext "~0.10.14" 634 | 635 | exit-hook@^1.0.0: 636 | version "1.1.1" 637 | resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" 638 | 639 | extend@~3.0.0: 640 | version "3.0.1" 641 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" 642 | 643 | extsprintf@1.0.2: 644 | version "1.0.2" 645 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" 646 | 647 | fast-levenshtein@~2.0.4: 648 | version "2.0.6" 649 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 650 | 651 | ffi@^2.0.0: 652 | version "2.2.0" 653 | resolved "https://registry.yarnpkg.com/ffi/-/ffi-2.2.0.tgz#bf18b04666a29f71227ed56895d5430af47042fa" 654 | dependencies: 655 | bindings "~1.2.0" 656 | debug "2" 657 | nan "2" 658 | ref "1" 659 | ref-struct "1" 660 | 661 | figures@^1.3.5: 662 | version "1.7.0" 663 | resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" 664 | dependencies: 665 | escape-string-regexp "^1.0.5" 666 | object-assign "^4.1.0" 667 | 668 | file-entry-cache@^2.0.0: 669 | version "2.0.0" 670 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" 671 | dependencies: 672 | flat-cache "^1.2.1" 673 | object-assign "^4.0.1" 674 | 675 | find-up@^1.0.0: 676 | version "1.1.2" 677 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" 678 | dependencies: 679 | path-exists "^2.0.0" 680 | pinkie-promise "^2.0.0" 681 | 682 | flat-cache@^1.2.1: 683 | version "1.2.2" 684 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" 685 | dependencies: 686 | circular-json "^0.3.1" 687 | del "^2.0.2" 688 | graceful-fs "^4.1.2" 689 | write "^0.2.1" 690 | 691 | foreach@^2.0.5: 692 | version "2.0.5" 693 | resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" 694 | 695 | forever-agent@~0.6.1: 696 | version "0.6.1" 697 | resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" 698 | 699 | form-data@~2.1.1: 700 | version "2.1.4" 701 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" 702 | dependencies: 703 | asynckit "^0.4.0" 704 | combined-stream "^1.0.5" 705 | mime-types "^2.1.12" 706 | 707 | fs.realpath@^1.0.0: 708 | version "1.0.0" 709 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 710 | 711 | function-bind@^1.0.2, function-bind@^1.1.0: 712 | version "1.1.0" 713 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" 714 | 715 | generate-function@^2.0.0: 716 | version "2.0.0" 717 | resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" 718 | 719 | generate-object-property@^1.1.0: 720 | version "1.2.0" 721 | resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" 722 | dependencies: 723 | is-property "^1.0.0" 724 | 725 | geoip2@^1.0.5: 726 | version "1.0.5" 727 | resolved "https://registry.yarnpkg.com/geoip2/-/geoip2-1.0.5.tgz#3bee6f33040a410ba6fde7e971b2a63008d71de2" 728 | dependencies: 729 | nan "2.3.5" 730 | 731 | getpass@^0.1.1: 732 | version "0.1.7" 733 | resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" 734 | dependencies: 735 | assert-plus "^1.0.0" 736 | 737 | glob@7.1.1, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: 738 | version "7.1.1" 739 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" 740 | dependencies: 741 | fs.realpath "^1.0.0" 742 | inflight "^1.0.4" 743 | inherits "2" 744 | minimatch "^3.0.2" 745 | once "^1.3.0" 746 | path-is-absolute "^1.0.0" 747 | 748 | globals@^9.14.0: 749 | version "9.17.0" 750 | resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" 751 | 752 | globby@^5.0.0: 753 | version "5.0.0" 754 | resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" 755 | dependencies: 756 | array-union "^1.0.1" 757 | arrify "^1.0.0" 758 | glob "^7.0.3" 759 | object-assign "^4.0.1" 760 | pify "^2.0.0" 761 | pinkie-promise "^2.0.0" 762 | 763 | graceful-fs@^4.1.2: 764 | version "4.1.11" 765 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" 766 | 767 | "graceful-readlink@>= 1.0.0": 768 | version "1.0.1" 769 | resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" 770 | 771 | growl@1.9.2: 772 | version "1.9.2" 773 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" 774 | 775 | har-schema@^1.0.5: 776 | version "1.0.5" 777 | resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" 778 | 779 | har-validator@~4.2.1: 780 | version "4.2.1" 781 | resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" 782 | dependencies: 783 | ajv "^4.9.1" 784 | har-schema "^1.0.5" 785 | 786 | has-ansi@^2.0.0: 787 | version "2.0.0" 788 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 789 | dependencies: 790 | ansi-regex "^2.0.0" 791 | 792 | has-flag@^1.0.0: 793 | version "1.0.0" 794 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" 795 | 796 | has@^1.0.1: 797 | version "1.0.1" 798 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" 799 | dependencies: 800 | function-bind "^1.0.2" 801 | 802 | hawk@~3.1.3: 803 | version "3.1.3" 804 | resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" 805 | dependencies: 806 | boom "2.x.x" 807 | cryptiles "2.x.x" 808 | hoek "2.x.x" 809 | sntp "1.x.x" 810 | 811 | hoek@2.x.x: 812 | version "2.16.3" 813 | resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" 814 | 815 | http-signature@~1.1.0: 816 | version "1.1.1" 817 | resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" 818 | dependencies: 819 | assert-plus "^0.2.0" 820 | jsprim "^1.2.2" 821 | sshpk "^1.7.0" 822 | 823 | ignore@^3.2.0: 824 | version "3.2.7" 825 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.7.tgz#4810ca5f1d8eca5595213a34b94f2eb4ed926bbd" 826 | 827 | imurmurhash@^0.1.4: 828 | version "0.1.4" 829 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 830 | 831 | inflight@^1.0.4: 832 | version "1.0.6" 833 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 834 | dependencies: 835 | once "^1.3.0" 836 | wrappy "1" 837 | 838 | inherits@2, inherits@^2.0.3, inherits@~2.0.1: 839 | version "2.0.3" 840 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 841 | 842 | inquirer@^0.12.0: 843 | version "0.12.0" 844 | resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" 845 | dependencies: 846 | ansi-escapes "^1.1.0" 847 | ansi-regex "^2.0.0" 848 | chalk "^1.0.0" 849 | cli-cursor "^1.0.1" 850 | cli-width "^2.0.0" 851 | figures "^1.3.5" 852 | lodash "^4.3.0" 853 | readline2 "^1.0.1" 854 | run-async "^0.1.0" 855 | rx-lite "^3.1.2" 856 | string-width "^1.0.1" 857 | strip-ansi "^3.0.0" 858 | through "^2.3.6" 859 | 860 | interpret@^1.0.0: 861 | version "1.0.3" 862 | resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90" 863 | 864 | is-callable@^1.1.1, is-callable@^1.1.3: 865 | version "1.1.3" 866 | resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" 867 | 868 | is-date-object@^1.0.1: 869 | version "1.0.1" 870 | resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" 871 | 872 | is-fullwidth-code-point@^1.0.0: 873 | version "1.0.0" 874 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 875 | dependencies: 876 | number-is-nan "^1.0.0" 877 | 878 | is-fullwidth-code-point@^2.0.0: 879 | version "2.0.0" 880 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 881 | 882 | is-lower-case@^1.1.0: 883 | version "1.1.3" 884 | resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393" 885 | dependencies: 886 | lower-case "^1.1.0" 887 | 888 | is-my-json-valid@^2.10.0: 889 | version "2.16.0" 890 | resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" 891 | dependencies: 892 | generate-function "^2.0.0" 893 | generate-object-property "^1.1.0" 894 | jsonpointer "^4.0.0" 895 | xtend "^4.0.0" 896 | 897 | is-path-cwd@^1.0.0: 898 | version "1.0.0" 899 | resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" 900 | 901 | is-path-in-cwd@^1.0.0: 902 | version "1.0.0" 903 | resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" 904 | dependencies: 905 | is-path-inside "^1.0.0" 906 | 907 | is-path-inside@^1.0.0: 908 | version "1.0.0" 909 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" 910 | dependencies: 911 | path-is-inside "^1.0.1" 912 | 913 | is-property@^1.0.0: 914 | version "1.0.2" 915 | resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" 916 | 917 | is-regex@^1.0.3: 918 | version "1.0.4" 919 | resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" 920 | dependencies: 921 | has "^1.0.1" 922 | 923 | is-resolvable@^1.0.0: 924 | version "1.0.0" 925 | resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" 926 | dependencies: 927 | tryit "^1.0.1" 928 | 929 | is-symbol@^1.0.1: 930 | version "1.0.1" 931 | resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" 932 | 933 | is-typedarray@~1.0.0: 934 | version "1.0.0" 935 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 936 | 937 | is-upper-case@^1.1.0: 938 | version "1.1.2" 939 | resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-1.1.2.tgz#8d0b1fa7e7933a1e58483600ec7d9661cbaf756f" 940 | dependencies: 941 | upper-case "^1.1.0" 942 | 943 | isarray@^1.0.0, isarray@~1.0.0: 944 | version "1.0.0" 945 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 946 | 947 | isstream@~0.1.2: 948 | version "0.1.2" 949 | resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" 950 | 951 | jodid25519@^1.0.0: 952 | version "1.0.2" 953 | resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" 954 | dependencies: 955 | jsbn "~0.1.0" 956 | 957 | js-tokens@^3.0.0: 958 | version "3.0.1" 959 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" 960 | 961 | js-yaml@^3.5.1: 962 | version "3.8.3" 963 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.3.tgz#33a05ec481c850c8875929166fe1beb61c728766" 964 | dependencies: 965 | argparse "^1.0.7" 966 | esprima "^3.1.1" 967 | 968 | jsbn@~0.1.0: 969 | version "0.1.1" 970 | resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" 971 | 972 | json-schema@0.2.3: 973 | version "0.2.3" 974 | resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" 975 | 976 | json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: 977 | version "1.0.1" 978 | resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" 979 | dependencies: 980 | jsonify "~0.0.0" 981 | 982 | json-stringify-safe@~5.0.1: 983 | version "5.0.1" 984 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 985 | 986 | json3@3.3.2: 987 | version "3.3.2" 988 | resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" 989 | 990 | jsonify@~0.0.0: 991 | version "0.0.0" 992 | resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" 993 | 994 | jsonpointer@^4.0.0: 995 | version "4.0.1" 996 | resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" 997 | 998 | jsprim@^1.2.2: 999 | version "1.4.0" 1000 | resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918" 1001 | dependencies: 1002 | assert-plus "1.0.0" 1003 | extsprintf "1.0.2" 1004 | json-schema "0.2.3" 1005 | verror "1.3.6" 1006 | 1007 | jsx-ast-utils@^1.0.0, jsx-ast-utils@^1.3.4: 1008 | version "1.4.1" 1009 | resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz#3867213e8dd79bf1e8f2300c0cfc1efb182c0df1" 1010 | 1011 | levn@^0.3.0, levn@~0.3.0: 1012 | version "0.3.0" 1013 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" 1014 | dependencies: 1015 | prelude-ls "~1.1.2" 1016 | type-check "~0.3.2" 1017 | 1018 | lodash._baseassign@^3.0.0: 1019 | version "3.2.0" 1020 | resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" 1021 | dependencies: 1022 | lodash._basecopy "^3.0.0" 1023 | lodash.keys "^3.0.0" 1024 | 1025 | lodash._basecopy@^3.0.0: 1026 | version "3.0.1" 1027 | resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" 1028 | 1029 | lodash._basecreate@^3.0.0: 1030 | version "3.0.3" 1031 | resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" 1032 | 1033 | lodash._getnative@^3.0.0: 1034 | version "3.9.1" 1035 | resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" 1036 | 1037 | lodash._isiterateecall@^3.0.0: 1038 | version "3.0.9" 1039 | resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" 1040 | 1041 | lodash.cond@^4.3.0: 1042 | version "4.5.2" 1043 | resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" 1044 | 1045 | lodash.create@3.1.1: 1046 | version "3.1.1" 1047 | resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" 1048 | dependencies: 1049 | lodash._baseassign "^3.0.0" 1050 | lodash._basecreate "^3.0.0" 1051 | lodash._isiterateecall "^3.0.0" 1052 | 1053 | lodash.get@^4.0.0: 1054 | version "4.4.2" 1055 | resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" 1056 | 1057 | lodash.isarguments@^3.0.0: 1058 | version "3.1.0" 1059 | resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" 1060 | 1061 | lodash.isarray@^3.0.0: 1062 | version "3.0.4" 1063 | resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" 1064 | 1065 | lodash.keys@^3.0.0: 1066 | version "3.1.2" 1067 | resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" 1068 | dependencies: 1069 | lodash._getnative "^3.0.0" 1070 | lodash.isarguments "^3.0.0" 1071 | lodash.isarray "^3.0.0" 1072 | 1073 | lodash@^4.0.0, lodash@^4.17.4, lodash@^4.3.0: 1074 | version "4.17.4" 1075 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" 1076 | 1077 | lower-case-first@^1.0.0: 1078 | version "1.0.2" 1079 | resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1" 1080 | dependencies: 1081 | lower-case "^1.1.2" 1082 | 1083 | lower-case@^1.1.0, lower-case@^1.1.1, lower-case@^1.1.2: 1084 | version "1.1.4" 1085 | resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" 1086 | 1087 | mime-db@~1.27.0: 1088 | version "1.27.0" 1089 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" 1090 | 1091 | mime-types@^2.1.12, mime-types@~2.1.7: 1092 | version "2.1.15" 1093 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" 1094 | dependencies: 1095 | mime-db "~1.27.0" 1096 | 1097 | minimatch@^3.0.2, minimatch@^3.0.3: 1098 | version "3.0.3" 1099 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" 1100 | dependencies: 1101 | brace-expansion "^1.0.0" 1102 | 1103 | minimist@0.0.8, minimist@~0.0.1: 1104 | version "0.0.8" 1105 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 1106 | 1107 | mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: 1108 | version "0.5.1" 1109 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 1110 | dependencies: 1111 | minimist "0.0.8" 1112 | 1113 | mocha@^3.3.0: 1114 | version "3.3.0" 1115 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.3.0.tgz#d29b7428d3f52c82e2e65df1ecb7064e1aabbfb5" 1116 | dependencies: 1117 | browser-stdout "1.3.0" 1118 | commander "2.9.0" 1119 | debug "2.6.0" 1120 | diff "3.2.0" 1121 | escape-string-regexp "1.0.5" 1122 | glob "7.1.1" 1123 | growl "1.9.2" 1124 | json3 "3.3.2" 1125 | lodash.create "3.1.1" 1126 | mkdirp "0.5.1" 1127 | supports-color "3.1.2" 1128 | 1129 | ms@0.7.1: 1130 | version "0.7.1" 1131 | resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" 1132 | 1133 | ms@0.7.2: 1134 | version "0.7.2" 1135 | resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" 1136 | 1137 | ms@0.7.3: 1138 | version "0.7.3" 1139 | resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff" 1140 | 1141 | mute-stream@0.0.5: 1142 | version "0.0.5" 1143 | resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" 1144 | 1145 | nan@2, nan@2.3.5: 1146 | version "2.3.5" 1147 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.3.5.tgz#822a0dc266290ce4cd3a12282ca3e7e364668a08" 1148 | 1149 | natural-compare@^1.4.0: 1150 | version "1.4.0" 1151 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 1152 | 1153 | node-whois@^2.1.0: 1154 | version "2.1.3" 1155 | resolved "https://registry.yarnpkg.com/node-whois/-/node-whois-2.1.3.tgz#3c73784045f78284efc8e54b469ebefd23f55773" 1156 | dependencies: 1157 | optimist "^0.6.1" 1158 | underscore "~1.5.2" 1159 | 1160 | nodemailer@^4.0.1: 1161 | version "4.0.1" 1162 | resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-4.0.1.tgz#b95864b07facee8287e8232effd6f1d56ec75ab2" 1163 | 1164 | number-is-nan@^1.0.0: 1165 | version "1.0.1" 1166 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 1167 | 1168 | oauth-sign@~0.8.1: 1169 | version "0.8.2" 1170 | resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" 1171 | 1172 | object-assign@^4.0.1, object-assign@^4.1.0: 1173 | version "4.1.1" 1174 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 1175 | 1176 | object-keys@^1.0.10, object-keys@^1.0.8: 1177 | version "1.0.11" 1178 | resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" 1179 | 1180 | object.assign@^4.0.4: 1181 | version "4.0.4" 1182 | resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.0.4.tgz#b1c9cc044ef1b9fe63606fc141abbb32e14730cc" 1183 | dependencies: 1184 | define-properties "^1.1.2" 1185 | function-bind "^1.1.0" 1186 | object-keys "^1.0.10" 1187 | 1188 | once@^1.3.0: 1189 | version "1.4.0" 1190 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1191 | dependencies: 1192 | wrappy "1" 1193 | 1194 | onetime@^1.0.0: 1195 | version "1.1.0" 1196 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" 1197 | 1198 | optimist@^0.6.1: 1199 | version "0.6.1" 1200 | resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" 1201 | dependencies: 1202 | minimist "~0.0.1" 1203 | wordwrap "~0.0.2" 1204 | 1205 | optionator@^0.8.2: 1206 | version "0.8.2" 1207 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" 1208 | dependencies: 1209 | deep-is "~0.1.3" 1210 | fast-levenshtein "~2.0.4" 1211 | levn "~0.3.0" 1212 | prelude-ls "~1.1.2" 1213 | type-check "~0.3.2" 1214 | wordwrap "~1.0.0" 1215 | 1216 | os-homedir@^1.0.0: 1217 | version "1.0.2" 1218 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 1219 | 1220 | param-case@^1.1.0: 1221 | version "1.1.2" 1222 | resolved "https://registry.yarnpkg.com/param-case/-/param-case-1.1.2.tgz#dcb091a43c259b9228f1c341e7b6a44ea0bf9743" 1223 | dependencies: 1224 | sentence-case "^1.1.2" 1225 | 1226 | pascal-case@^1.1.0: 1227 | version "1.1.2" 1228 | resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-1.1.2.tgz#3e5d64a20043830a7c49344c2d74b41be0c9c99b" 1229 | dependencies: 1230 | camel-case "^1.1.1" 1231 | upper-case-first "^1.1.0" 1232 | 1233 | path-case@^1.1.0: 1234 | version "1.1.2" 1235 | resolved "https://registry.yarnpkg.com/path-case/-/path-case-1.1.2.tgz#50ce6ba0d3bed3dd0b5c2a9c4553697434409514" 1236 | dependencies: 1237 | sentence-case "^1.1.2" 1238 | 1239 | path-exists@^2.0.0: 1240 | version "2.1.0" 1241 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" 1242 | dependencies: 1243 | pinkie-promise "^2.0.0" 1244 | 1245 | path-is-absolute@^1.0.0: 1246 | version "1.0.1" 1247 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1248 | 1249 | path-is-inside@^1.0.1: 1250 | version "1.0.2" 1251 | resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" 1252 | 1253 | path-parse@^1.0.5: 1254 | version "1.0.5" 1255 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" 1256 | 1257 | performance-now@^0.2.0: 1258 | version "0.2.0" 1259 | resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" 1260 | 1261 | pify@^2.0.0: 1262 | version "2.3.0" 1263 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" 1264 | 1265 | pinkie-promise@^2.0.0: 1266 | version "2.0.1" 1267 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" 1268 | dependencies: 1269 | pinkie "^2.0.0" 1270 | 1271 | pinkie@^2.0.0: 1272 | version "2.0.4" 1273 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" 1274 | 1275 | pkg-dir@^1.0.0: 1276 | version "1.0.0" 1277 | resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" 1278 | dependencies: 1279 | find-up "^1.0.0" 1280 | 1281 | pkg-up@^1.0.0: 1282 | version "1.0.0" 1283 | resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26" 1284 | dependencies: 1285 | find-up "^1.0.0" 1286 | 1287 | pluralize@^1.2.1: 1288 | version "1.2.1" 1289 | resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" 1290 | 1291 | prelude-ls@~1.1.2: 1292 | version "1.1.2" 1293 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" 1294 | 1295 | process-nextick-args@~1.0.6: 1296 | version "1.0.7" 1297 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" 1298 | 1299 | progress@^1.1.8: 1300 | version "1.1.8" 1301 | resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" 1302 | 1303 | progress@^2.0.0: 1304 | version "2.0.0" 1305 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" 1306 | 1307 | punycode@^1.4.1: 1308 | version "1.4.1" 1309 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" 1310 | 1311 | qs@~6.4.0: 1312 | version "6.4.0" 1313 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" 1314 | 1315 | readable-stream@^2.2.2: 1316 | version "2.2.9" 1317 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8" 1318 | dependencies: 1319 | buffer-shims "~1.0.0" 1320 | core-util-is "~1.0.0" 1321 | inherits "~2.0.1" 1322 | isarray "~1.0.0" 1323 | process-nextick-args "~1.0.6" 1324 | string_decoder "~1.0.0" 1325 | util-deprecate "~1.0.1" 1326 | 1327 | readline2@^1.0.1: 1328 | version "1.0.1" 1329 | resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" 1330 | dependencies: 1331 | code-point-at "^1.0.0" 1332 | is-fullwidth-code-point "^1.0.0" 1333 | mute-stream "0.0.5" 1334 | 1335 | rechoir@^0.6.2: 1336 | version "0.6.2" 1337 | resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" 1338 | dependencies: 1339 | resolve "^1.1.6" 1340 | 1341 | ref-struct@1: 1342 | version "1.1.0" 1343 | resolved "https://registry.yarnpkg.com/ref-struct/-/ref-struct-1.1.0.tgz#5d5ee65ad41cefc3a5c5feb40587261e479edc13" 1344 | dependencies: 1345 | debug "2" 1346 | ref "1" 1347 | 1348 | ref@1, ref@^1.3.2: 1349 | version "1.3.4" 1350 | resolved "https://registry.yarnpkg.com/ref/-/ref-1.3.4.tgz#724d2bf8ac85f8c8db194d3d85be6efe416bc1e5" 1351 | dependencies: 1352 | bindings "1" 1353 | debug "2" 1354 | nan "2" 1355 | 1356 | request@^2.81.0: 1357 | version "2.81.0" 1358 | resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" 1359 | dependencies: 1360 | aws-sign2 "~0.6.0" 1361 | aws4 "^1.2.1" 1362 | caseless "~0.12.0" 1363 | combined-stream "~1.0.5" 1364 | extend "~3.0.0" 1365 | forever-agent "~0.6.1" 1366 | form-data "~2.1.1" 1367 | har-validator "~4.2.1" 1368 | hawk "~3.1.3" 1369 | http-signature "~1.1.0" 1370 | is-typedarray "~1.0.0" 1371 | isstream "~0.1.2" 1372 | json-stringify-safe "~5.0.1" 1373 | mime-types "~2.1.7" 1374 | oauth-sign "~0.8.1" 1375 | performance-now "^0.2.0" 1376 | qs "~6.4.0" 1377 | safe-buffer "^5.0.1" 1378 | stringstream "~0.0.4" 1379 | tough-cookie "~2.3.0" 1380 | tunnel-agent "^0.6.0" 1381 | uuid "^3.0.0" 1382 | 1383 | require-uncached@^1.0.2: 1384 | version "1.0.3" 1385 | resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" 1386 | dependencies: 1387 | caller-path "^0.1.0" 1388 | resolve-from "^1.0.0" 1389 | 1390 | resolve-from@^1.0.0: 1391 | version "1.0.1" 1392 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" 1393 | 1394 | resolve@^1.1.6: 1395 | version "1.3.3" 1396 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" 1397 | dependencies: 1398 | path-parse "^1.0.5" 1399 | 1400 | restore-cursor@^1.0.1: 1401 | version "1.0.1" 1402 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" 1403 | dependencies: 1404 | exit-hook "^1.0.0" 1405 | onetime "^1.0.0" 1406 | 1407 | rimraf@^2.2.8: 1408 | version "2.6.1" 1409 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" 1410 | dependencies: 1411 | glob "^7.0.5" 1412 | 1413 | run-async@^0.1.0: 1414 | version "0.1.0" 1415 | resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" 1416 | dependencies: 1417 | once "^1.3.0" 1418 | 1419 | rx-lite@^3.1.2: 1420 | version "3.1.2" 1421 | resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" 1422 | 1423 | safe-buffer@^5.0.1: 1424 | version "5.0.1" 1425 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" 1426 | 1427 | sentence-case@^1.1.1, sentence-case@^1.1.2: 1428 | version "1.1.3" 1429 | resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-1.1.3.tgz#8034aafc2145772d3abe1509aa42c9e1042dc139" 1430 | dependencies: 1431 | lower-case "^1.1.1" 1432 | 1433 | shelljs@^0.7.5: 1434 | version "0.7.7" 1435 | resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" 1436 | dependencies: 1437 | glob "^7.0.0" 1438 | interpret "^1.0.0" 1439 | rechoir "^0.6.2" 1440 | 1441 | slice-ansi@0.0.4: 1442 | version "0.0.4" 1443 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" 1444 | 1445 | snake-case@^1.1.0: 1446 | version "1.1.2" 1447 | resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-1.1.2.tgz#0c2f25e305158d9a18d3d977066187fef8a5a66a" 1448 | dependencies: 1449 | sentence-case "^1.1.2" 1450 | 1451 | sntp@1.x.x: 1452 | version "1.0.9" 1453 | resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" 1454 | dependencies: 1455 | hoek "2.x.x" 1456 | 1457 | sprintf-js@~1.0.2: 1458 | version "1.0.3" 1459 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 1460 | 1461 | ssdeep@^0.1.1: 1462 | version "0.1.1" 1463 | resolved "https://registry.yarnpkg.com/ssdeep/-/ssdeep-0.1.1.tgz#225e0d1cf9f2563abfff65df204ed5728721e109" 1464 | dependencies: 1465 | ffi "^2.0.0" 1466 | ref "^1.3.2" 1467 | 1468 | sshpk@^1.7.0: 1469 | version "1.13.0" 1470 | resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c" 1471 | dependencies: 1472 | asn1 "~0.2.3" 1473 | assert-plus "^1.0.0" 1474 | dashdash "^1.12.0" 1475 | getpass "^0.1.1" 1476 | optionalDependencies: 1477 | bcrypt-pbkdf "^1.0.0" 1478 | ecc-jsbn "~0.1.1" 1479 | jodid25519 "^1.0.0" 1480 | jsbn "~0.1.0" 1481 | tweetnacl "~0.14.0" 1482 | 1483 | stream-transform@^0.1.0: 1484 | version "0.1.2" 1485 | resolved "https://registry.yarnpkg.com/stream-transform/-/stream-transform-0.1.2.tgz#7d8e6b4e03ac4781778f8c79517501bfb0762a9f" 1486 | 1487 | string-width@^1.0.1: 1488 | version "1.0.2" 1489 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 1490 | dependencies: 1491 | code-point-at "^1.0.0" 1492 | is-fullwidth-code-point "^1.0.0" 1493 | strip-ansi "^3.0.0" 1494 | 1495 | string-width@^2.0.0: 1496 | version "2.0.0" 1497 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e" 1498 | dependencies: 1499 | is-fullwidth-code-point "^2.0.0" 1500 | strip-ansi "^3.0.0" 1501 | 1502 | string_decoder@~1.0.0: 1503 | version "1.0.0" 1504 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.0.tgz#f06f41157b664d86069f84bdbdc9b0d8ab281667" 1505 | dependencies: 1506 | buffer-shims "~1.0.0" 1507 | 1508 | stringstream@~0.0.4: 1509 | version "0.0.5" 1510 | resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" 1511 | 1512 | strip-ansi@^3.0.0: 1513 | version "3.0.1" 1514 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 1515 | dependencies: 1516 | ansi-regex "^2.0.0" 1517 | 1518 | strip-bom@^3.0.0: 1519 | version "3.0.0" 1520 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" 1521 | 1522 | strip-json-comments@~2.0.1: 1523 | version "2.0.1" 1524 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 1525 | 1526 | supports-color@3.1.2: 1527 | version "3.1.2" 1528 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" 1529 | dependencies: 1530 | has-flag "^1.0.0" 1531 | 1532 | supports-color@^2.0.0: 1533 | version "2.0.0" 1534 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 1535 | 1536 | swap-case@^1.1.0: 1537 | version "1.1.2" 1538 | resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-1.1.2.tgz#c39203a4587385fad3c850a0bd1bcafa081974e3" 1539 | dependencies: 1540 | lower-case "^1.1.1" 1541 | upper-case "^1.1.1" 1542 | 1543 | table@^3.7.8: 1544 | version "3.8.3" 1545 | resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" 1546 | dependencies: 1547 | ajv "^4.7.0" 1548 | ajv-keywords "^1.0.0" 1549 | chalk "^1.1.1" 1550 | lodash "^4.0.0" 1551 | slice-ansi "0.0.4" 1552 | string-width "^2.0.0" 1553 | 1554 | text-table@~0.2.0: 1555 | version "0.2.0" 1556 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 1557 | 1558 | through@^2.3.6: 1559 | version "2.3.8" 1560 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 1561 | 1562 | title-case@^1.1.0: 1563 | version "1.1.2" 1564 | resolved "https://registry.yarnpkg.com/title-case/-/title-case-1.1.2.tgz#fae4a6ae546bfa22d083a0eea910a40d12ed4f5a" 1565 | dependencies: 1566 | sentence-case "^1.1.1" 1567 | upper-case "^1.0.3" 1568 | 1569 | tough-cookie@~2.3.0: 1570 | version "2.3.2" 1571 | resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" 1572 | dependencies: 1573 | punycode "^1.4.1" 1574 | 1575 | tryit@^1.0.1: 1576 | version "1.0.3" 1577 | resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" 1578 | 1579 | tunnel-agent@^0.6.0: 1580 | version "0.6.0" 1581 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" 1582 | dependencies: 1583 | safe-buffer "^5.0.1" 1584 | 1585 | tweetnacl@^0.14.3, tweetnacl@~0.14.0: 1586 | version "0.14.5" 1587 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" 1588 | 1589 | type-check@~0.3.2: 1590 | version "0.3.2" 1591 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" 1592 | dependencies: 1593 | prelude-ls "~1.1.2" 1594 | 1595 | type-detect@0.1.1: 1596 | version "0.1.1" 1597 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" 1598 | 1599 | type-detect@^1.0.0: 1600 | version "1.0.0" 1601 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" 1602 | 1603 | typedarray@^0.0.6: 1604 | version "0.0.6" 1605 | resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" 1606 | 1607 | underscore@~1.5.2: 1608 | version "1.5.2" 1609 | resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.5.2.tgz#1335c5e4f5e6d33bbb4b006ba8c86a00f556de08" 1610 | 1611 | upper-case-first@^1.1.0: 1612 | version "1.1.2" 1613 | resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-1.1.2.tgz#5d79bedcff14419518fd2edb0a0507c9b6859115" 1614 | dependencies: 1615 | upper-case "^1.1.1" 1616 | 1617 | upper-case@^1.0.3, upper-case@^1.1.0, upper-case@^1.1.1: 1618 | version "1.1.3" 1619 | resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" 1620 | 1621 | user-home@^2.0.0: 1622 | version "2.0.0" 1623 | resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" 1624 | dependencies: 1625 | os-homedir "^1.0.0" 1626 | 1627 | util-deprecate@~1.0.1: 1628 | version "1.0.2" 1629 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1630 | 1631 | uuid@^3.0.0: 1632 | version "3.0.1" 1633 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" 1634 | 1635 | verror@1.3.6: 1636 | version "1.3.6" 1637 | resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" 1638 | dependencies: 1639 | extsprintf "1.0.2" 1640 | 1641 | whois-json@^1.2.2: 1642 | version "1.2.2" 1643 | resolved "https://registry.yarnpkg.com/whois-json/-/whois-json-1.2.2.tgz#3078e7fb17c1e144595fe0f83ff9ae4ad0d70cc4" 1644 | dependencies: 1645 | change-case "https://registry.npmjs.org/change-case/-/change-case-2.3.0.tgz" 1646 | node-whois "^2.1.0" 1647 | 1648 | wordwrap@~0.0.2: 1649 | version "0.0.3" 1650 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" 1651 | 1652 | wordwrap@~1.0.0: 1653 | version "1.0.0" 1654 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" 1655 | 1656 | wrappy@1: 1657 | version "1.0.2" 1658 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1659 | 1660 | write@^0.2.1: 1661 | version "0.2.1" 1662 | resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" 1663 | dependencies: 1664 | mkdirp "^0.5.1" 1665 | 1666 | xtend@^4.0.0: 1667 | version "4.0.1" 1668 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" 1669 | --------------------------------------------------------------------------------