From 2969eee093db565a95b86c76e8c8e1ed671fc114 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 11:57:35 -0800 Subject: [PATCH 01/21] feat(2020-day-01): find matching expenses in expense report Finds matching expenses in an array matching a checksum --- 2020/day-01/expenseValidation.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 2020/day-01/expenseValidation.js diff --git a/2020/day-01/expenseValidation.js b/2020/day-01/expenseValidation.js new file mode 100644 index 0000000..75eeb70 --- /dev/null +++ b/2020/day-01/expenseValidation.js @@ -0,0 +1,32 @@ + +/** + * Validates a list of records by comparing every combination + * to the checksum. Stops when the first match is found + */ +const validateRecords = (records, checksum = 2020) => { + const results = [] + + // We're using Array.find() at each level so it stops looping + // onced matched. This game has a habit of throwing huge + // data sets to discourage brute-forcing + const matcher = records.find((record) => { + const match = records.find(matchRec => record + matchRec === checksum) + if (match) { + results.push(match) + return true + } + return false + }) + if (matcher) { + results.push(matcher) + } + + if (results.length < 2) { + throw new Error('Couldn\'t find a checksum match') + } + return results +} + +module.exports = { + validateRecords +} From b2990e77ab35b168f5d58d533386dea42b4e28af Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 12:16:06 -0800 Subject: [PATCH 02/21] feat(2020-day-01): multiply matching expenses for part 1 solution --- 2020/day-01/index.js | 1 + 2020/day-01/input.txt | 200 ++++++++++++++++++++++++++++++++++++++++ 2020/day-01/solution.js | 66 +++++++++++++ 3 files changed, 267 insertions(+) create mode 100644 2020/day-01/index.js create mode 100644 2020/day-01/input.txt create mode 100644 2020/day-01/solution.js diff --git a/2020/day-01/index.js b/2020/day-01/index.js new file mode 100644 index 0000000..a7e4223 --- /dev/null +++ b/2020/day-01/index.js @@ -0,0 +1 @@ +require('./solution') diff --git a/2020/day-01/input.txt b/2020/day-01/input.txt new file mode 100644 index 0000000..e297f2b --- /dev/null +++ b/2020/day-01/input.txt @@ -0,0 +1,200 @@ +1539 +1914 +1866 +1407 +1706 +1423 +1834 +1700 +1573 +1486 +1743 +1394 +1693 +1705 +1530 +1811 +1626 +1473 +1901 +1481 +1527 +1841 +1891 +1750 +1343 +1899 +401 +1896 +1627 +1593 +1541 +874 +1484 +1210 +1692 +1963 +1964 +1780 +671 +1862 +1393 +1309 +1740 +1831 +1932 +1185 +1979 +1504 +1663 +1610 +1494 +1511 +1103 +1738 +1816 +1871 +1545 +1595 +1784 +1412 +1815 +1998 +1783 +1770 +1426 +1699 +1416 +1880 +1612 +1989 +1360 +1869 +1762 +1690 +1999 +1990 +1521 +1730 +703 +1463 +1670 +1472 +1413 +1669 +1502 +1548 +1475 +1694 +1314 +1980 +980 +1667 +890 +1569 +1456 +1406 +1924 +1973 +1965 +1533 +1827 +2000 +1847 +1520 +1729 +1512 +1555 +1566 +1505 +1672 +1169 +1835 +1850 +1493 +1861 +1288 +1675 +1676 +1556 +1320 +1757 +1870 +1642 +1903 +1372 +1967 +1894 +176 +1908 +1418 +1535 +1487 +1496 +1491 +1611 +1970 +1758 +1563 +1766 +1629 +1937 +1763 +1829 +1772 +1632 +1517 +1736 +1971 +1721 +1716 +1429 +1408 +1560 +1958 +1359 +1890 +1825 +1536 +1819 +1697 +1887 +1832 +2005 +892 +1471 +1425 +1677 +1673 +1128 +1878 +1062 +1470 +1875 +1854 +1518 +1568 +1919 +256 +1532 +1711 +1944 +1344 +1330 +1636 +1957 +1709 +1551 +1983 +1674 +1671 +1959 +1760 +1689 +1767 +1477 +1589 +1897 +1144 +1982 +1544 \ No newline at end of file diff --git a/2020/day-01/solution.js b/2020/day-01/solution.js new file mode 100644 index 0000000..a1bea37 --- /dev/null +++ b/2020/day-01/solution.js @@ -0,0 +1,66 @@ +const fs = require('fs') +const path = require('path') +const filePath = path.join(__dirname, 'input.txt') +const { validateRecords } = require('./expenseValidation') +const { inputToArray } = require('../../2018/inputParser') + +fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { + if (err) throw err + + initData = inputToArray(initData.trim()) + .map(el => Number(el)) + + const resetInput = () => { + // Deep copy to ensure we aren't mutating the original data + return JSON.parse(JSON.stringify(initData)) + } + + const part1 = () => { + const data = resetInput() + const results = validateRecords(data) + + return results[0] * results[1] + } + + // const part2 = ({ target, maxNoun, maxVerb }) => { + // // Helper for running the program with specified noun and verb inputs + // const tryProgram = ({ + // noun, + // verb + // }) => { + // const data = resetInput() + // data[1] = noun + // data[2] = verb + // runProgram({ data }) + // console.debug(`Running with noun:${noun} and verb:${verb} produces ${data[0]}`) + // return Number(data[0]) + // } + + // // Manipulate and loop through attempts for Part 2 + // let noun = -1 + // while (noun <= maxNoun) { + // let verb = -1 + // noun++ + // while (verb <= maxVerb) { + // verb++ + // const output = tryProgram({ + // noun, + // verb + // }) + // // Break the search loop on success + // if (output === target) { + // return 100 * noun + verb + // } + // } + // } + // } + + const answers = [] + answers.push(part1()) + // answers.push(part2()) + + answers.forEach((ans, idx) => { + console.info(`-- Part ${idx + 1} --`) + console.info(`Answer: ${ans}`) + }) +}) From 672e1cd1813a292a160fd3ac9b77961812fc71e4 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 13:36:16 -0800 Subject: [PATCH 03/21] refactor(2020-day-01): use recursion for expense records checksum search This will allow for 2020 Day 01 Part 2 to specify an arbitrary number of expense reports --- 2020/day-01/expenseValidation.js | 59 ++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/2020/day-01/expenseValidation.js b/2020/day-01/expenseValidation.js index 75eeb70..d6b2091 100644 --- a/2020/day-01/expenseValidation.js +++ b/2020/day-01/expenseValidation.js @@ -2,25 +2,62 @@ /** * Validates a list of records by comparing every combination * to the checksum. Stops when the first match is found + * @param {array} records List of records to check + * @param {int} checksum The target sum that records should add up to + * @param {int} goal The number of records we hope to find */ -const validateRecords = (records, checksum = 2020) => { +const validateRecords = (records, checksum = 2020, goal = 2) => { const results = [] - // We're using Array.find() at each level so it stops looping - // onced matched. This game has a habit of throwing huge - // data sets to discourage brute-forcing - const matcher = records.find((record) => { - const match = records.find(matchRec => record + matchRec === checksum) - if (match) { - results.push(match) + const obj = { foo: 'bar' } + // Intentionally using `function()` instead of `() =>` because + // the thisArg won't get passed to the find callback otherwise + // https://stackoverflow.com/questions/46639131/javascript-array-prototype-find-second-argument-thisarg-not-working + function testRecursive (record, idx, arr, parent) { + console.log(`recurse check ${record} - `, parent) + console.log(this) + } + records.find(testRecursive, obj) + + function matcher (record) { + this.depth = this.depth || 1 // depth tracking starts at level 1 + this.tracker = this.tracker || 0 // for basic sums, start counter at 0 + const subTotal = this.tracker + record + // Found a match, don't keep searching! + if (subTotal === this.target) { + results.push(record) return true } + // When subtotal exceeds target, return immediately and don't waste time + // on more loops that won't get results + if (subTotal > this.target) { + return false + } + // If we're already at max depth, don't waste time on more loops + if (this.depth >= this.maxDepth) { + return false + } + // Check the next level down + const res = records.find(matcher, { + maxDepth: this.maxDepth, + target: this.target, + depth: this.depth + 1, + tracker: this.tracker + record + }) + // Children matched, so record this one as well + if (res) { + results.push(record) + return true + } + // Nothing found with this combo, step to the next sibling return false - }) - if (matcher) { - results.push(matcher) } + records.find(matcher, { + maxDepth: goal, + target: checksum + }) + if (results.length < 2) { throw new Error('Couldn\'t find a checksum match') } From 9f96cd37d0b30a9668a7c4b1294c8a7ce54d80ee Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 14:40:05 -0800 Subject: [PATCH 04/21] fix(2020-day-01): find the exact number of desired expense records If the desired number is 3, don't stop if 2 meet the checksum requirements. --- 2020/day-01/expenseValidation.js | 6 +++--- 2020/day-01/expenseValidation.test.js | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/2020/day-01/expenseValidation.js b/2020/day-01/expenseValidation.js index d6b2091..caf3cb3 100644 --- a/2020/day-01/expenseValidation.js +++ b/2020/day-01/expenseValidation.js @@ -23,8 +23,8 @@ const validateRecords = (records, checksum = 2020, goal = 2) => { this.depth = this.depth || 1 // depth tracking starts at level 1 this.tracker = this.tracker || 0 // for basic sums, start counter at 0 const subTotal = this.tracker + record - // Found a match, don't keep searching! - if (subTotal === this.target) { + // Found a match in the specified with desired qty of results, don't keep searching! + if (subTotal === this.target && this.depth >= goal) { results.push(record) return true } @@ -44,7 +44,7 @@ const validateRecords = (records, checksum = 2020, goal = 2) => { depth: this.depth + 1, tracker: this.tracker + record }) - // Children matched, so record this one as well + // Propogate maches back up the recursion chain, capturing each if (res) { results.push(record) return true diff --git a/2020/day-01/expenseValidation.test.js b/2020/day-01/expenseValidation.test.js index e8f549c..d442861 100644 --- a/2020/day-01/expenseValidation.test.js +++ b/2020/day-01/expenseValidation.test.js @@ -23,6 +23,16 @@ describe('--- 2020 Day 1: Report Repair ---', () => { expect(testData.indexOf(result)).to.be.greaterThan(-1) }) }) + it('it can find a specified number of records adding up to 2020', () => { + const expected = [979, 366, 675] + const results = validateRecords(testData, undefined, 3) + // Should same number of results + expect(results.length).to.equal(expected.length) + // Result order is unnecessary, but all expected hould be in the result set + expected.forEach(result => { + expect(testData.indexOf(result)).to.be.greaterThan(-1) + }) + }) it('it supports specifying an alternate checksum', () => { const arrSum = (arr) => arr.reduce((x, y) => x + y, 0) const expected = [testData[3], testData[5]] From f5ccd425c4ed2f851b8812dc421e4ff5229aa871 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 14:43:56 -0800 Subject: [PATCH 05/21] refactor(2020-day-01): remove sample code --- 2020/day-01/expenseValidation.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/2020/day-01/expenseValidation.js b/2020/day-01/expenseValidation.js index caf3cb3..a514b83 100644 --- a/2020/day-01/expenseValidation.js +++ b/2020/day-01/expenseValidation.js @@ -9,16 +9,9 @@ const validateRecords = (records, checksum = 2020, goal = 2) => { const results = [] - const obj = { foo: 'bar' } // Intentionally using `function()` instead of `() =>` because // the thisArg won't get passed to the find callback otherwise // https://stackoverflow.com/questions/46639131/javascript-array-prototype-find-second-argument-thisarg-not-working - function testRecursive (record, idx, arr, parent) { - console.log(`recurse check ${record} - `, parent) - console.log(this) - } - records.find(testRecursive, obj) - function matcher (record) { this.depth = this.depth || 1 // depth tracking starts at level 1 this.tracker = this.tracker || 0 // for basic sums, start counter at 0 @@ -53,6 +46,7 @@ const validateRecords = (records, checksum = 2020, goal = 2) => { return false } + // Parse the records to find results records.find(matcher, { maxDepth: goal, target: checksum From 616b619c30e8f7d4983b468dc5d723b6ac3e2748 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 15:04:42 -0800 Subject: [PATCH 06/21] feat(2020-day-01): find 3 expenses totaling 2020 --- 2020/day-01/expenseValidation.test.js | 44 +++++++++++++++++++------- 2020/day-01/solution.js | 45 +++++---------------------- 2 files changed, 40 insertions(+), 49 deletions(-) diff --git a/2020/day-01/expenseValidation.test.js b/2020/day-01/expenseValidation.test.js index d442861..0e2258e 100644 --- a/2020/day-01/expenseValidation.test.js +++ b/2020/day-01/expenseValidation.test.js @@ -1,6 +1,15 @@ /* eslint-env mocha */ const { expect } = require('chai') const { validateRecords } = require('./expenseValidation') + +/** + * Sum all the values in an array + */ +const arrSum = (arr) => arr.reduce((x, y) => x + y, 0) +/** + * Multiply all the values in an array + */ +const arrMult = (arr) => arr.reduce((x, y) => x * y, 1) const testData = [ 1721, 979, @@ -15,26 +24,19 @@ describe('--- 2020 Day 1: Report Repair ---', () => { describe('validateRecords()', () => { it('it finds the two records that sum to 2020', () => { const expected = [1721, 299] - const results = validateRecords(testData, 2020) + const results = validateRecords(testData, undefined, 2) // Should be 2 results expect(results.length).to.equal(2) // Result order is unnecessary, but all expected hould be in the result set expected.forEach(result => { expect(testData.indexOf(result)).to.be.greaterThan(-1) }) - }) - it('it can find a specified number of records adding up to 2020', () => { - const expected = [979, 366, 675] - const results = validateRecords(testData, undefined, 3) - // Should same number of results - expect(results.length).to.equal(expected.length) - // Result order is unnecessary, but all expected hould be in the result set - expected.forEach(result => { - expect(testData.indexOf(result)).to.be.greaterThan(-1) - }) + // Results add up to the checksum + expect(arrSum(results)).to.equal(2020) + // Confirm the multiplied total + expect(arrMult(results)).to.equal(514579) }) it('it supports specifying an alternate checksum', () => { - const arrSum = (arr) => arr.reduce((x, y) => x + y, 0) const expected = [testData[3], testData[5]] const checksum = arrSum(expected) const results = validateRecords(testData, checksum) @@ -55,4 +57,22 @@ describe('--- 2020 Day 1: Report Repair ---', () => { }) }) }) + describe('Part 2', () => { + describe('validateRecords()', () => { + it('it can find a specified number of records adding up to 2020', () => { + const expected = [979, 366, 675] + const results = validateRecords(testData, undefined, 3) + // Should same number of results + expect(results.length).to.equal(expected.length) + // Result order is unnecessary, but all expected hould be in the result set + expected.forEach(result => { + expect(testData.indexOf(result)).to.be.greaterThan(-1) + }) + // Results add up to the checksum + expect(arrSum(results)).to.equal(2020) + // Confirm the multiplied total + expect(arrMult(results)).to.equal(241861950) + }) + }) + }) }) diff --git a/2020/day-01/solution.js b/2020/day-01/solution.js index a1bea37..92ee010 100644 --- a/2020/day-01/solution.js +++ b/2020/day-01/solution.js @@ -17,47 +17,18 @@ fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { const part1 = () => { const data = resetInput() - const results = validateRecords(data) - - return results[0] * results[1] + return validateRecords(data) // Find 2 results for 2020 + .reduce((total, res) => total * res, 1) } - // const part2 = ({ target, maxNoun, maxVerb }) => { - // // Helper for running the program with specified noun and verb inputs - // const tryProgram = ({ - // noun, - // verb - // }) => { - // const data = resetInput() - // data[1] = noun - // data[2] = verb - // runProgram({ data }) - // console.debug(`Running with noun:${noun} and verb:${verb} produces ${data[0]}`) - // return Number(data[0]) - // } - - // // Manipulate and loop through attempts for Part 2 - // let noun = -1 - // while (noun <= maxNoun) { - // let verb = -1 - // noun++ - // while (verb <= maxVerb) { - // verb++ - // const output = tryProgram({ - // noun, - // verb - // }) - // // Break the search loop on success - // if (output === target) { - // return 100 * noun + verb - // } - // } - // } - // } - + const part2 = () => { + const data = resetInput() + return validateRecords(data, undefined, 3) // Find 3 results for 2020 + .reduce((total, res) => total * res, 1) + } const answers = [] answers.push(part1()) - // answers.push(part2()) + answers.push(part2()) answers.forEach((ans, idx) => { console.info(`-- Part ${idx + 1} --`) From 5c3f9088747c1f4639328dbaf8a6233d4d5a3c26 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 16:17:58 -0800 Subject: [PATCH 07/21] feat: templatize new day creation Create new days with `npm run new`. A new day's folder will be created based on input year and day. --- README.md | 3 +- package-lock.json | 1929 +++++++++++++++++++++++++++++++- package.json | 4 +- plop-templates/day/index.js | 1 + plop-templates/day/input.txt | 0 plop-templates/day/solution.js | 35 + plop-templates/plopfile.js | 30 + 7 files changed, 1990 insertions(+), 12 deletions(-) create mode 100644 plop-templates/day/index.js create mode 100644 plop-templates/day/input.txt create mode 100644 plop-templates/day/solution.js create mode 100644 plop-templates/plopfile.js diff --git a/README.md b/README.md index 815abce..d6c81c5 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,10 @@ [![Build Status](https://travis-ci.com/amclin/advent-of-code.svg?branch=master)](https://travis-ci.com/amclin/advent-of-code) [![codecov](https://codecov.io/gh/amclin/advent-of-code/branch/master/graph/badge.svg)](https://codecov.io/gh/amclin/advent-of-code) +## Start a boilerplate for a new day +`npm run new` ### Special Instructions Run by modifying `index.js` to point to the puzzle you want to execute. - #### 2019:Day 02 Day 2 requires the use of BigInt which is added to Javascript in ES2020 and I didn't include a polyfill. This limits the solution to [Javascript engines with BigInt support](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) diff --git a/package-lock.json b/package-lock.json index 78292f2..bc09895 100644 --- a/package-lock.json +++ b/package-lock.json @@ -215,6 +215,16 @@ "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", "dev": true }, + "@babel/runtime-corejs3": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.12.5.tgz", + "integrity": "sha512-roGr54CsTmNPPzZoCP1AmDXuBoNao7tnSA83TXTwt+UK5QVyh1DIJnrgYRPWKCF2flqZQXwa7Yr8v7VmLzF0YQ==", + "dev": true, + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + } + }, "@babel/template": { "version": "7.10.1", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", @@ -838,6 +848,58 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/fined": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/fined/-/fined-1.1.2.tgz", + "integrity": "sha512-hzzTS+X9EqDhx4vwdch/DOZci/bfh5J6Nyz8lqvyfBg2ROx2fPafX+LpDfpVgSvQKj0EYkwTYpBO3z2etwbkOw==", + "dev": true + }, + "@types/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/inquirer": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-6.5.0.tgz", + "integrity": "sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw==", + "dev": true, + "requires": { + "@types/through": "*", + "rxjs": "^6.4.0" + } + }, + "@types/interpret": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/interpret/-/interpret-1.1.1.tgz", + "integrity": "sha512-HZ4d0m2Ebl8DmrOdYZHgYyipj/8Ftq1/ssB/oQR7fqfUrwtTP7IW3BDi2V445nhPBLzZjEkApaPVp83moSCXlA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/liftoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@types/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha512-1jsThE//wKDK+hYM+NJqswI+K9lfR0YNMctteOxAzk/aemI0rQsVDk6Dia0zkPfBWFTh+hiDmrGQXqP1tyM+eg==", + "dev": true, + "requires": { + "@types/fined": "*", + "@types/interpret": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, "@types/minimist": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", @@ -868,6 +930,15 @@ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "dev": true }, + "@types/through": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz", + "integrity": "sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -1034,6 +1105,30 @@ "integrity": "sha1-oMoMvCmltz6Dbuvhy/bF4OTrgvk=", "dev": true }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, "array-ify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", @@ -1051,12 +1146,24 @@ "is-string": "^1.0.5" } }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true + }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -1069,6 +1176,12 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", @@ -1081,12 +1194,73 @@ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, "before-after-hook": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz", @@ -1136,6 +1310,23 @@ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, "caching-transform": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", @@ -1154,6 +1345,16 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -1217,6 +1418,32 @@ } } }, + "change-case": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.1.0.tgz", + "integrity": "sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==", + "dev": true, + "requires": { + "camel-case": "^3.0.0", + "constant-case": "^2.0.0", + "dot-case": "^2.1.0", + "header-case": "^1.0.0", + "is-lower-case": "^1.1.0", + "is-upper-case": "^1.1.0", + "lower-case": "^1.1.1", + "lower-case-first": "^1.0.0", + "no-case": "^2.3.2", + "param-case": "^2.1.0", + "pascal-case": "^2.0.0", + "path-case": "^2.1.0", + "sentence-case": "^2.1.0", + "snake-case": "^2.1.0", + "swap-case": "^1.1.0", + "title-case": "^2.1.0", + "upper-case": "^1.1.1", + "upper-case-first": "^1.1.0" + } + }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -1245,6 +1472,29 @@ "readdirp": "~3.5.0" } }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, "clean-stack": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.1.0.tgz", @@ -1260,6 +1510,12 @@ "restore-cursor": "^3.1.0" } }, + "cli-spinners": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.5.0.tgz", + "integrity": "sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ==", + "dev": true + }, "cli-table": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", @@ -1308,6 +1564,12 @@ } } }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, "codecov": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.8.1.tgz", @@ -1333,6 +1595,16 @@ } } }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1370,12 +1642,28 @@ "dot-prop": "^5.1.0" } }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "constant-case": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", + "integrity": "sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=", + "dev": true, + "requires": { + "snake-case": "^2.1.0", + "upper-case": "^1.1.1" + } + }, "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", @@ -1452,6 +1740,18 @@ "safe-buffer": "~5.1.1" } }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js-pure": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.8.1.tgz", + "integrity": "sha512-Se+LaxqXlVXGvmexKGPvnUIYC1jwXu1H6Pkyb3uBM5d8/NELMYCHs/4/roD7721NxrTLyv7e5nXd5/QLBO+10g==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -1555,6 +1855,12 @@ } } }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", @@ -1593,6 +1899,15 @@ } } }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -1602,6 +1917,47 @@ "object-keys": "^1.0.12" } }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, "deglob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/deglob/-/deglob-4.0.1.tgz", @@ -1663,6 +2019,12 @@ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", "dev": true }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -1695,6 +2057,15 @@ "esutils": "^2.0.2" } }, + "dot-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", + "integrity": "sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=", + "dev": true, + "requires": { + "no-case": "^2.2.0" + } + }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -2257,6 +2628,101 @@ } } }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + } + } + }, "external-editor": { "version": "3.1.0", "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", @@ -2268,6 +2734,71 @@ "tmp": "^0.0.33" } }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, "fast-deep-equal": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", @@ -2439,11 +2970,167 @@ "semver-regex": "^2.0.0" } }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + }, + "dependencies": { + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + } + } + }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true }, "flat-cache": { "version": "2.0.1", @@ -2473,6 +3160,21 @@ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, "foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -2526,6 +3228,15 @@ } } }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", @@ -2626,6 +3337,12 @@ "pump": "^3.0.0" } }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, "git-log-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", @@ -2684,6 +3401,30 @@ "is-glob": "^4.0.1" } }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -2760,6 +3501,23 @@ "function-bind": "^1.1.1" } }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -2772,6 +3530,58 @@ "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", "dev": true }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "hasha": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.0.tgz", @@ -2796,6 +3606,25 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "header-case": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", + "integrity": "sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=", + "dev": true, + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.3" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, "hook-std": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-2.0.0.tgz", @@ -3061,6 +3890,12 @@ } } }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, "into-stream": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-5.1.1.tgz", @@ -3071,6 +3906,36 @@ "p-is-promise": "^3.0.0" } }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -3086,6 +3951,12 @@ "binary-extensions": "^2.0.0" } }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, "is-builtin-module": { "version": "1.0.0", "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", @@ -3110,12 +3981,57 @@ "has": "^1.0.3" } }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", "dev": true }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3137,6 +4053,15 @@ "is-extglob": "^2.1.1" } }, + "is-lower-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", + "integrity": "sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=", + "dev": true, + "requires": { + "lower-case": "^1.1.0" + } + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -3182,6 +4107,15 @@ "has": "^1.0.3" } }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -3218,6 +4152,24 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-upper-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", + "integrity": "sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=", + "dev": true, + "requires": { + "upper-case": "^1.1.0" + } + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -3230,12 +4182,24 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, + "isbinaryfile": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz", + "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, "issue-parser": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", @@ -3526,6 +4490,33 @@ "type-check": "~0.3.2" } }, + "liftoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "dev": true, + "requires": { + "extend": "^3.0.0", + "findup-sync": "^2.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + }, + "dependencies": { + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + } + } + }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", @@ -3586,6 +4577,12 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", @@ -3685,6 +4682,21 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "lower-case-first": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", + "integrity": "sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=", + "dev": true, + "requires": { + "lower-case": "^1.1.2" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -3711,12 +4723,36 @@ } } }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, "map-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", "dev": true }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, "marked": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.5.tgz", @@ -4042,13 +5078,43 @@ "kind-of": "^6.0.3" } }, - "mkdirp": { - "version": "0.5.5", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { - "minimist": "^1.2.5" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" } }, "mocha": { @@ -4307,6 +5373,25 @@ "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", "dev": true }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -4331,6 +5416,15 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "requires": { + "lower-case": "^1.1.1" + } + }, "node-emoji": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", @@ -4346,6 +5440,90 @@ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", "dev": true }, + "node-plop": { + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/node-plop/-/node-plop-0.26.2.tgz", + "integrity": "sha512-q444beWkMvZwAiYC3BRGJUHgRlpOItQHy+xdy6egXg8KjxDY/Ro309spQTNvH01qK9A8XF6pc0xLKbrHDpxW7w==", + "dev": true, + "requires": { + "@babel/runtime-corejs3": "^7.9.2", + "@types/inquirer": "^6.5.0", + "change-case": "^3.1.0", + "del": "^5.1.0", + "globby": "^10.0.1", + "handlebars": "^4.4.3", + "inquirer": "^7.1.0", + "isbinaryfile": "^4.0.2", + "lodash.get": "^4.4.2", + "mkdirp": "^0.5.1", + "resolve": "^1.12.0" + }, + "dependencies": { + "del": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", + "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", + "dev": true, + "requires": { + "globby": "^10.0.1", + "graceful-fs": "^4.2.2", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.1", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0" + } + }, + "globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + } + } + }, "node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -8032,6 +9210,37 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "object-inspect": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", @@ -8044,6 +9253,15 @@ "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", "dev": true }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, "object.assign": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", @@ -8056,6 +9274,18 @@ "object-keys": "^1.0.11" } }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, "object.entries": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", @@ -8080,6 +9310,25 @@ "has": "^1.0.3" } }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, "object.values": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", @@ -8124,6 +9373,85 @@ "word-wrap": "~1.2.3" } }, + "ora": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", + "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^2.0.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "os-tmpdir": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -8209,6 +9537,15 @@ "release-zalgo": "^1.0.0" } }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dev": true, + "requires": { + "no-case": "^2.2.0" + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -8218,6 +9555,17 @@ "callsites": "^3.0.0" } }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -8227,6 +9575,37 @@ "error-ex": "^1.2.0" } }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "pascal-case": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", + "integrity": "sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=", + "dev": true, + "requires": { + "camel-case": "^3.0.0", + "upper-case-first": "^1.1.0" + } + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", + "integrity": "sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=", + "dev": true, + "requires": { + "no-case": "^2.2.0" + } + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -8251,6 +9630,21 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", @@ -8338,6 +9732,70 @@ "find-up": "^2.1.0" } }, + "plop": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/plop/-/plop-2.7.4.tgz", + "integrity": "sha512-SaqN3mwug/Ur2RE/ryo05oLTLy+8qZGwosNt9JnrFWca+dLCsPJR1j2ZXwjrccmNu6LA7eB56lRyk/G0fKf9HA==", + "dev": true, + "requires": { + "@types/liftoff": "^2.5.0", + "chalk": "^1.1.3", + "interpret": "^1.2.0", + "liftoff": "^2.5.0", + "minimist": "^1.2.0", + "node-plop": "~0.26.2", + "ora": "^3.4.0", + "v8flags": "^2.0.10" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -8484,6 +9942,15 @@ } } }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -8511,6 +9978,22 @@ "esprima": "~4.0.0" } }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -8535,6 +10018,18 @@ "es6-error": "^4.0.1" } }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -8556,12 +10051,28 @@ "path-parse": "^1.0.6" } }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -8572,6 +10083,12 @@ "signal-exit": "^3.0.2" } }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", @@ -8620,6 +10137,15 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -8838,6 +10364,16 @@ "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", "dev": true }, + "sentence-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", + "integrity": "sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=", + "dev": true, + "requires": { + "no-case": "^2.2.0", + "upper-case-first": "^1.1.2" + } + }, "serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", @@ -8853,6 +10389,38 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + } + } + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -8913,12 +10481,162 @@ "is-fullwidth-code-point": "^2.0.0" } }, + "snake-case": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", + "integrity": "sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=", + "dev": true, + "requires": { + "no-case": "^2.2.0" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, "spawn-error-forwarder": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", @@ -8991,6 +10709,15 @@ "through": "2" } }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, "split2": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", @@ -9137,6 +10864,27 @@ } } }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, "stream-combiner2": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", @@ -9281,6 +11029,16 @@ } } }, + "swap-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", + "integrity": "sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=", + "dev": true, + "requires": { + "lower-case": "^1.1.1", + "upper-case": "^1.1.1" + } + }, "table": { "version": "5.4.6", "resolved": "http://registry.npmjs.org/table/-/table-5.4.6.tgz", @@ -9406,6 +11164,16 @@ } } }, + "title-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", + "integrity": "sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=", + "dev": true, + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.0.3" + } + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -9421,6 +11189,38 @@ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -9491,6 +11291,24 @@ "dev": true, "optional": true }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", @@ -9518,6 +11336,61 @@ "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", "dev": true }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "upper-case-first": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", + "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", + "dev": true, + "requires": { + "upper-case": "^1.1.1" + } + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -9527,6 +11400,12 @@ "punycode": "^2.1.0" } }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, "url-join": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", @@ -9539,6 +11418,18 @@ "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=", "dev": true }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", + "dev": true + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -9557,6 +11448,15 @@ "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", "dev": true }, + "v8flags": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", + "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "dev": true, + "requires": { + "user-home": "^1.1.1" + } + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -9567,6 +11467,15 @@ "spdx-expression-parse": "^3.0.0" } }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/package.json b/package.json index a0a47d9..50ecb97 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "posttest": "nyc report --reporter=html --reporter=text-lcov > coverage.lcov", "lint": "standard", "semantic-release": "semantic-release", - "report-coverage": "codecov" + "report-coverage": "codecov", + "new": "plop --plopfile ./plop-templates/plopfile.js" }, "repository": { "type": "git", @@ -33,6 +34,7 @@ "codecov": "^3.8.1", "mocha": "^8.2.1", "nyc": "^15.1.0", + "plop": "^2.7.4", "semantic-release": "^17.3.0", "standard": "^14.3.4" } diff --git a/plop-templates/day/index.js b/plop-templates/day/index.js new file mode 100644 index 0000000..a7e4223 --- /dev/null +++ b/plop-templates/day/index.js @@ -0,0 +1 @@ +require('./solution') diff --git a/plop-templates/day/input.txt b/plop-templates/day/input.txt new file mode 100644 index 0000000..e69de29 diff --git a/plop-templates/day/solution.js b/plop-templates/day/solution.js new file mode 100644 index 0000000..779f7ea --- /dev/null +++ b/plop-templates/day/solution.js @@ -0,0 +1,35 @@ +const fs = require('fs') +const path = require('path') +const filePath = path.join(__dirname, 'input.txt') +const { inputToArray } = require('../../2018/inputParser') + +fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { + if (err) throw err + + initData = inputToArray(initData.trim()) + + const resetInput = () => { + // Deep copy to ensure we aren't mutating the original data + return JSON.parse(JSON.stringify(initData)) + } + + const part1 = () => { + const data = resetInput() + console.debug(data) + return 'No answer yet' + } + + const part2 = () => { + const data = resetInput() + console.debug(data) + return 'No answer yet' + } + const answers = [] + answers.push(part1()) + answers.push(part2()) + + answers.forEach((ans, idx) => { + console.info(`-- Part ${idx + 1} --`) + console.info(`Answer: ${ans}`) + }) +}) diff --git a/plop-templates/plopfile.js b/plop-templates/plopfile.js new file mode 100644 index 0000000..1fdd674 --- /dev/null +++ b/plop-templates/plopfile.js @@ -0,0 +1,30 @@ +module.exports = function (plop) { + const zeroPad = (day) => { + if (day.length < 2) { + day = `0${day}` + } + return `${day}` + } + + // controller generator + plop.setGenerator('Day', { + description: 'application controller logic', + prompts: [{ + type: 'input', + name: 'year', + message: 'Which year?', + default: new Date().getFullYear() + }, { + type: 'input', + name: 'day', + message: 'Which day?' + }], + actions: (data) => { + return [{ + type: 'addMany', + destination: `../{{year}}/day-${zeroPad(data.day)}`, + templateFiles: 'day/**.*' + }] + } + }) +} From 572d6bce674fc3d8ec55dc5a46502b75c7650b76 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 18:08:19 -0800 Subject: [PATCH 08/21] refactor(2020-day-02): initialize for 2020 day 02 --- 2020/day-02/index.js | 1 + 2020/day-02/input.txt | 0 2020/day-02/solution.js | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 2020/day-02/index.js create mode 100644 2020/day-02/input.txt create mode 100644 2020/day-02/solution.js diff --git a/2020/day-02/index.js b/2020/day-02/index.js new file mode 100644 index 0000000..a7e4223 --- /dev/null +++ b/2020/day-02/index.js @@ -0,0 +1 @@ +require('./solution') diff --git a/2020/day-02/input.txt b/2020/day-02/input.txt new file mode 100644 index 0000000..e69de29 diff --git a/2020/day-02/solution.js b/2020/day-02/solution.js new file mode 100644 index 0000000..779f7ea --- /dev/null +++ b/2020/day-02/solution.js @@ -0,0 +1,35 @@ +const fs = require('fs') +const path = require('path') +const filePath = path.join(__dirname, 'input.txt') +const { inputToArray } = require('../../2018/inputParser') + +fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { + if (err) throw err + + initData = inputToArray(initData.trim()) + + const resetInput = () => { + // Deep copy to ensure we aren't mutating the original data + return JSON.parse(JSON.stringify(initData)) + } + + const part1 = () => { + const data = resetInput() + console.debug(data) + return 'No answer yet' + } + + const part2 = () => { + const data = resetInput() + console.debug(data) + return 'No answer yet' + } + const answers = [] + answers.push(part1()) + answers.push(part2()) + + answers.forEach((ans, idx) => { + console.info(`-- Part ${idx + 1} --`) + console.info(`Answer: ${ans}`) + }) +}) From ee012b2b66eeeccb7338c15c0023c34235e68282 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 18:32:21 -0800 Subject: [PATCH 09/21] feat(2020-day-02): utilities for formatting and validating passwords criteria per instructions in part 1 --- 2020/day-02/cleanupPasswords.js | 47 ++++++++++++++++++++++++++++ 2020/day-02/cleanupPasswords.test.js | 42 +++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 2020/day-02/cleanupPasswords.js create mode 100644 2020/day-02/cleanupPasswords.test.js diff --git a/2020/day-02/cleanupPasswords.js b/2020/day-02/cleanupPasswords.js new file mode 100644 index 0000000..085ad18 --- /dev/null +++ b/2020/day-02/cleanupPasswords.js @@ -0,0 +1,47 @@ +/** + * Splits a password record into its component parts + */ +const splitRecord = (row) => { + const record = row.split(': ') + .map((el) => el.trim()) + + return { + rule: record[0], + password: record[1] + } +} + +/** + * Splits a password validation rule into its component parts + */ +const splitRule = (rule) => { + const splitRow = rule.split(/-| /) + + return { + min: Number(splitRow[0]), + max: Number(splitRow[1]), + char: String(splitRow[2]) + } +} + +/** + * Validates a password against the specified rule + */ +const isValid = (rule, password) => { + // count how many times `rule.char` exists in `password` + const count = ( + password.match( + new RegExp(rule.char, 'g') + ) || [] + ).length + // check the conditions + if (count < rule.min) return false + if (count > rule.max) return false + return true +} + +module.exports = { + splitRecord, + splitRule, + isValid +} diff --git a/2020/day-02/cleanupPasswords.test.js b/2020/day-02/cleanupPasswords.test.js new file mode 100644 index 0000000..5e83afe --- /dev/null +++ b/2020/day-02/cleanupPasswords.test.js @@ -0,0 +1,42 @@ +/* eslint-env mocha */ +const { expect } = require('chai') +const { splitRecord, splitRule, isValid } = require('./cleanupPasswords') + +const testData = [ + '1-3 a: abcde', + '1-3 b: cdefg', + '2-9 c: ccccccccc' +] + +describe('--- Day 2: Password Philosophy ---', () => { + describe('Part 1', () => { + describe('splitRecord()', () => { + it('splits a password record into components parts', () => { + testData.forEach((row, idx) => { + const { rule, password } = splitRecord(row) + expect(`${rule}: ${password}`).to.equal(testData[idx]) + }) + }) + }) + describe('splitRule()', () => { + it('splits a password formatting rule into component parts', () => { + testData.forEach((row, idx) => { + const { rule, password } = splitRecord(row) + const { min, max, char } = splitRule(rule) + expect(`${min}-${max} ${char}: ${password}`).to.equal(testData[idx]) + }) + }) + }) + describe('isValid()', () => { + it('checks if a specified password matches the specified rule', () => { + const expectedResults = [true, false, true] + testData.forEach((row, idx) => { + const { rule, password } = splitRecord(row) + const { min, max, char } = splitRule(rule) + expect(isValid({ min, max, char }, password)) + .to.equal(expectedResults[idx]) + }) + }) + }) + }) +}) From 85de1c2616e03c9171e4fdb894eac7eb0639d1f3 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 18:50:19 -0800 Subject: [PATCH 10/21] feat(2020-day-02): find the number of valid passwords Solution for part 1 --- 2020/day-02/cleanupPasswords.js | 11 +- 2020/day-02/cleanupPasswords.test.js | 20 +- 2020/day-02/input.txt | 1000 ++++++++++++++++++++++++++ 2020/day-02/solution.js | 9 +- 4 files changed, 1031 insertions(+), 9 deletions(-) diff --git a/2020/day-02/cleanupPasswords.js b/2020/day-02/cleanupPasswords.js index 085ad18..042bc94 100644 --- a/2020/day-02/cleanupPasswords.js +++ b/2020/day-02/cleanupPasswords.js @@ -27,7 +27,7 @@ const splitRule = (rule) => { /** * Validates a password against the specified rule */ -const isValid = (rule, password) => { +const isValidPassword = (rule, password) => { // count how many times `rule.char` exists in `password` const count = ( password.match( @@ -40,8 +40,15 @@ const isValid = (rule, password) => { return true } +const isValidRecord = (record) => { + const { rule, password } = splitRecord(record) + const { min, max, char } = splitRule(rule) + return isValidPassword({ min, max, char }, password) +} + module.exports = { splitRecord, splitRule, - isValid + isValidRecord, + isValidPassword } diff --git a/2020/day-02/cleanupPasswords.test.js b/2020/day-02/cleanupPasswords.test.js index 5e83afe..01602fa 100644 --- a/2020/day-02/cleanupPasswords.test.js +++ b/2020/day-02/cleanupPasswords.test.js @@ -1,6 +1,6 @@ /* eslint-env mocha */ const { expect } = require('chai') -const { splitRecord, splitRule, isValid } = require('./cleanupPasswords') +const { splitRecord, splitRule, isValidPassword, isValidRecord } = require('./cleanupPasswords') const testData = [ '1-3 a: abcde', @@ -27,13 +27,27 @@ describe('--- Day 2: Password Philosophy ---', () => { }) }) }) - describe('isValid()', () => { + describe('isValidPassword()', () => { it('checks if a specified password matches the specified rule', () => { const expectedResults = [true, false, true] testData.forEach((row, idx) => { const { rule, password } = splitRecord(row) const { min, max, char } = splitRule(rule) - expect(isValid({ min, max, char }, password)) + expect(isValidPassword({ min, max, char }, password)) + .to.equal(expectedResults[idx]) + }) + }) + it('won\'t allow more than the specified character count', () => { + const badPass = 'abcabcabcabc' + expect(isValidPassword({ min: 2, max: 3, char: 'a' }, badPass)) + .to.equal(false) + }) + }) + describe('isValidRecord()', () => { + it('checks if a specified record contains valid rule and password', () => { + const expectedResults = [true, false, true] + testData.forEach((row, idx) => { + expect(isValidRecord(row)) .to.equal(expectedResults[idx]) }) }) diff --git a/2020/day-02/input.txt b/2020/day-02/input.txt index e69de29..fe6d97c 100644 --- a/2020/day-02/input.txt +++ b/2020/day-02/input.txt @@ -0,0 +1,1000 @@ +1-4 m: mrfmmbjxr +5-16 b: bbbbhbbbbpbxbbbcb +7-8 x: qxrxmxccxxx +9-11 k: kkkkkkktmkhk +8-12 g: sgwvdxzhkvndv +6-9 v: zvmvvmvvvd +8-19 f: ffffsplmfflffhtfrfj +5-16 p: pppppppppspppjpcp +2-3 w: wwmw +7-19 j: jjjjjjjjjjjjjjjjjjvj +5-9 q: wqzqqqqqq +14-15 g: gggggggggglggfgg +4-6 p: tppzkppdt +11-14 p: vppgpktpppppptpppqp +5-9 f: bfflffrfgf +7-9 p: ppppptbzn +1-3 l: lllvn +2-4 g: qvcdg +1-3 m: wsmdv +1-5 v: vvvvvvvv +10-14 l: lckqlgjllltlwbl +3-4 t: bsttftltjhbqbgtm +15-17 j: jjzjjjjjhjjjjjjpzjj +2-3 t: thtt +6-17 f: ffwkwzjtjktvsfmfhvsf +3-5 b: rqxbb +4-7 m: nbcmcwmmxrxqvtjfmm +1-2 v: gzvvvv +1-3 w: hkwhv +7-8 p: pppppppp +3-4 h: hhnwh +2-4 t: ttrtjtththkr +3-4 w: wwww +4-6 s: xsntgrftmpx +4-7 s: ssskssmsbs +10-15 m: bmmrbmmmmlmmmmmm +12-13 w: wqpwdmwllnjwx +5-14 n: nnnnlnnnnnnnnmnn +5-6 k: kktkfczk +5-7 r: nrdrtrvr +4-6 c: ccqchcc +2-9 l: fnldtfnbxjlvnlsnjhml +1-13 d: dlchvkccnwrcc +5-7 j: jjjjjjj +3-5 z: zzzzz +6-12 f: ffffflvmfhfx +8-10 w: wwwwwwwwww +3-4 r: rrbtr +3-11 b: bbbrbbvphbxbqk +16-17 n: nqhknnnnsnnnnnnnnnb +18-20 k: kkkkkkkkkkkkkkkkkhtj +3-15 r: ktvzqbmbrvczprfcw +9-11 q: qnqqdqqqgrrqsqq +3-5 p: pvppp +7-11 m: mfcdmmxmmmp +7-8 t: ttttktnt +5-6 b: bbpbbbv +14-16 z: zzzzzzzzzrzzblzw +11-12 j: jkjjjkjjjjjjgj +7-9 q: qqqqqqqqqq +10-11 f: cfffffffffff +4-6 c: nccccc +7-8 r: gmdlqfpwmrr +6-8 v: nvvpdnjx +8-12 x: xxlxxbbxxxxx +8-10 s: ssxssssssss +5-12 z: zhzdfzgdzzhzlz +11-12 k: qbkhvqjpqzfq +2-11 w: wwmlttwjflwdjcpclww +2-16 w: twkkmcrxmvjtwxlwsksf +6-8 s: sssfxbskvs +5-6 s: ssnsxsbs +10-19 l: ndzmdxqlnllxsbbwvsl +2-4 g: gggg +5-10 x: zxxxsxxxxxxxsxx +7-15 f: ffbrbdtzvdffktxfm +7-8 m: xmkmmmmmtmm +9-13 s: hksrdhzlsdmps +15-17 b: bbbbbbbrbbbbbbbrbb +3-5 x: xxxxxxx +2-6 t: wtltztnct +3-15 v: vvwvvvvvhvvvbwwvmdvr +12-14 p: ppphsppppppbphp +8-9 t: ttttvttttttt +2-3 c: cchvj +8-9 z: vzzzzzzgl +11-12 q: qqmqqqqqqqsnqqqqqqq +12-13 d: dddddddddddmd +8-9 t: wttttttqt +7-8 p: ppppvvcw +4-5 g: gncgj +12-13 s: sssssssssssmw +7-9 f: pswpnjftf +11-16 p: ppppnpkpkzppcpzbppp +1-12 q: ksqrqpqnqmqxqb +2-10 l: lllllllllll +17-18 z: zzzzzzzzzzzxzzzzzz +11-12 g: qggbjgggggssgggrk +3-4 s: bpss +6-8 v: vwvvvrvvv +3-4 t: tglktt +4-12 l: kvrnzqslwrdkfll +12-16 b: fbbbbbnbbvbbbbbcbbb +5-6 t: ttttzz +5-8 w: sqwhwwxw +8-9 z: zzzvztzrzzzz +3-6 l: llvdlt +7-8 r: mrcvnrrr +10-11 k: kkkkkkkkkmc +1-3 n: nnnmn +4-16 c: dqlcbclcrxkkszvcv +9-10 g: fxssmlmgbh +5-6 p: nwpfpp +3-7 w: cwhgrfshdwhwwll +14-16 l: llllllllllllllpll +3-4 f: ffff +4-9 d: dcdddxzvmrd +4-11 w: jwwnwwwwwvx +3-4 t: ttvc +4-17 r: rrsrrrrrrrrrbtrrrr +8-9 x: wqxxxcfdx +6-8 d: qgddwddtdddlc +12-13 v: vvjvvvvvzvvtvv +3-4 g: sghxg +3-4 b: ckbbmprfbbmzgqtkbw +5-6 x: xxxxxv +10-13 f: zpfffbfchxfffffjff +5-6 f: ffffwf +12-19 l: mlllllplllldllnsllql +4-5 v: vvvvp +5-8 w: vjwvghggwww +1-3 n: lnnn +16-18 p: ppppppvpppppwppppppp +15-18 z: zzzzzzzzzzzzzzjzzg +4-6 b: bbmbbb +5-7 z: wzlwzmzzzzzzzzzzzwz +8-12 p: gppmpppvppkzpcnpb +16-19 h: hhbhhhhhhhhhhhlnhhw +2-3 n: nnnn +3-10 m: mmntfkdjftmtmmbm +3-5 j: jjjjw +4-6 z: zjnzzzdzz +1-7 s: zsvsssf +6-7 v: vtvvvcg +3-12 f: qsrtmnxkvlcmt +5-11 q: mqgqqqqqrpch +5-9 g: msxkggnggg +3-8 v: vvvvhvjvdvxtr +4-6 k: jcklxdhkwhsqhq +6-7 x: vppxbhcjzxdqx +2-3 n: ntrg +7-8 g: gggwgjdhg +1-3 d: dddd +14-18 l: llllllllwlllxllllllz +8-19 g: ggggghggkhgrtzcgrrk +7-14 q: phzxvmbxxfsfwr +8-14 r: hbjmdrhnpxnwgz +15-17 d: dddddpddddldddtdgddd +6-7 k: kkkkkgkkq +2-12 w: wwzwwwwwwwwww +5-8 q: qqqqqqqzqqwqqzqcq +5-6 z: czzzrz +14-15 b: bbbrzhbbbbnxbgbb +12-13 d: dgddddddddtvddddvbz +3-5 v: vvvvv +13-16 q: qqqqqvzwqqqqqqqq +2-3 n: jpznnwfpchs +7-10 w: jwwpwkwwwpw +6-7 b: bbcnbcjxbbb +14-17 w: wqtwwwwwnwcwwbsww +3-14 w: gwwwwwwwhwwnxwwwww +4-9 w: mwllcfjfwwwjp +9-12 n: nnnnnnnhnwjnn +2-4 j: jjjjj +3-6 t: mrmttccttqt +16-17 p: ppmjpgptzgbppphfbp +12-17 v: vvvvvvvvvvvvvfvvvv +13-15 x: xxxxxxxxxxxxxxgx +2-4 d: dddddddd +2-5 t: ttmvt +13-14 j: jjjjjjjjjjjjtj +3-5 r: ggmrdf +7-8 f: ffdfflszfsfffqff +10-11 t: ttpttttttrgtt +8-12 j: jjjjqdhzjhjdj +19-20 z: zbzzzzzzzzzzzzzzzzrq +7-11 b: bbbbbhbbbxbbb +4-9 p: gzmkkbtpkzpgthklpq +2-5 b: bbbbxgb +4-13 k: kkkkkkzktckkkwkjkk +10-12 q: vrxznfqqnqgq +15-16 m: mmmmkmmmmmmmmmmmm +15-18 h: hlhhvhchthhhhtphhh +2-3 m: mftzmc +6-11 s: ksssssssssszs +5-6 q: qqqpqkq +7-8 n: nnfnnnnpn +6-8 c: chfcllrvxcnnjhtc +6-8 k: kkkkkxlk +2-4 s: tsspb +9-12 q: qqqqqqqqqqqqqq +17-20 h: hhhhhhhhhhhhhhhhhhhh +6-13 r: rrrrrgrrrrrrn +4-8 f: fffrfffz +13-14 n: nbnnnngnnnnnnpz +8-11 f: fvffsfqftcffff +3-5 w: vwhxz +8-10 x: nmxxknlptx +3-4 p: pppt +17-18 v: vvvvvvhkvvvvvnvvjlvv +10-15 z: twnsdkmgpvzfmzg +3-5 n: njnjnkghp +10-12 q: qvqqqqqqqqqq +6-7 r: rrrrrrrr +3-4 t: qltt +2-16 f: gffflcvtpfkfcjfrjvfs +3-5 s: swssp +11-13 l: lrpllllllvtslwllllld +1-3 n: nnnn +3-5 g: jjggnvg +4-5 b: bvbbb +13-15 l: llvllllllllllnll +5-6 j: hjjjjfsj +3-4 b: bkfbnb +5-8 z: zdzzzzzzzrzzz +3-4 r: rrrx +2-12 c: mczhvchkmjdrjh +12-16 x: sjxbcgdqtpfxflsxx +2-4 c: tcxf +4-5 w: kwjww +1-2 r: rrrwzc +4-7 d: ddddddkdd +5-6 q: qqqqqp +13-16 l: flljlllvnzlllllclldl +3-6 j: jjjpjj +3-4 g: gxgg +10-11 n: nnnnnnnnnnn +2-5 j: ztchj +4-6 j: pjzzrmjvhcxn +4-11 c: jchcccgccckc +11-12 d: dddddddddddd +6-7 n: nznnnnnntnnnnzpjfjnn +8-9 k: kbkkkkkkk +13-18 x: xbxxmxqxxxmxkxsxxxx +7-16 r: rrrrrrzrrrrrrrjmrrr +3-5 h: hhqhd +1-2 b: bbmb +2-3 n: rlnntn +2-8 q: qnfqnqhx +2-5 b: bjbbh +5-11 t: twtjnpttqtvtttptt +16-17 w: wtmwwhxtgwrrswwfblll +8-16 g: ggggghshggdggggcpwg +1-3 l: lsllzl +11-13 n: nnnvncnnmvnqnnnnn +6-7 s: ssqssss +10-18 t: tttnmjxttjttttttdzt +4-10 n: nkvncgtdpz +16-18 p: cphtrgffcpphfspxppgp +2-6 k: kkhgkskkm +6-20 r: fhrwtrzwrddfrndnrlgr +2-8 w: lkwnccgw +6-10 x: lxxxxxxgxwxxxrxqxx +4-9 q: tqtpgqjzdmqfq +9-12 k: kkkkkqbkkckkkjkql +5-9 r: rrrrrrrhcr +17-20 h: hhshshhhhhhhshhhbhhq +7-9 s: dngddfsss +12-13 q: qqqqqqqqqqqcq +2-6 v: vqtvvvv +8-10 c: cccfcncccccc +14-15 m: mmmmmmmmmmmmmmdm +7-14 s: ssslssfdssflvvsj +2-5 z: wcllj +2-11 n: cvnrlftcjct +8-16 k: krzkfbkkqkhnsjkjgkk +2-7 q: mvhvqnzdjw +5-8 l: lgbnlnclkllll +4-12 l: llllmllrlgllrklnlrbt +7-10 j: jjjjjjnjjcjsj +1-2 k: dgwmgsn +2-5 z: zjmxc +6-7 c: ccccccccc +14-17 k: bkkkkkkkkkkkndkkkk +2-4 x: xxjxtxbq +7-9 w: drjcfwzwwwfwwfzxww +4-5 p: pppwc +4-5 r: rrrvm +1-8 r: qrrrmrrrrr +16-18 l: llllllllldllltlklk +1-11 p: pwcpppbppppppp +5-19 w: wwwwwwwwwwwwwwwcwww +17-18 k: kkkkkwkkkkkkkkkkkxk +12-15 f: fsffffffflfqgfx +6-13 d: zddpdvddrvrdxq +1-10 f: ffffffrfkb +13-14 x: xxxxxxxxxxxxxxx +16-20 j: jjjjjjjdwjjfjjjjjjdj +8-11 r: rrrrrrrrrrrr +15-16 x: dxjxxxdxxxxxxxxxwxx +3-9 m: mjhqdgkmzmsmtdmhfn +2-7 k: kkkhwgtxlkmkqkk +11-15 m: mmgmmmmnsjmmlmmm +1-2 v: wvvk +8-14 s: zssssssssssssts +3-4 z: ztbzzr +4-10 x: xxkmqxxxxx +3-5 p: pkppppppppzpp +3-15 q: qpqmkqfqqlqqdfqtkqq +16-17 d: ddddddzbxcdddcddq +4-5 s: nqssf +4-5 s: sssbks +4-5 s: tsjlhsbsmt +1-5 z: zzzbztzf +1-4 l: pvsgtvt +3-6 b: bbbjbb +2-4 d: wkdvd +16-18 w: wwwwwwwrwwwwwwwzwkw +15-17 t: tqttjttttttttvtttt +5-9 q: qcqqqqdtqq +8-11 s: sssssssfssssssssssss +5-6 x: xxxvcpbxr +13-15 d: ddwdtctnjdcdpch +5-6 z: zzzwzzzq +3-7 v: bsphcnvwvtvphdp +3-4 q: vhcprqqgdmlfpwqqw +11-18 b: bfbbbfbbbbvhwbbbzlb +12-15 c: cccccccccccccqfcc +4-10 j: jjjjjjjjjjjw +8-14 s: ssssssspmssssssssms +6-15 b: jxnbdvxbbbcbrsbxrs +10-12 s: ssssjsssssfs +8-12 f: ffffdfkqflfpf +8-9 w: wwwwwwwwz +7-10 z: fzzlzzbtmthzzzz +2-3 k: kqzzb +11-12 s: ssssssssssls +16-17 r: rrrrhrrrrrrrrrrnr +3-11 b: czpbpbzswgcddm +4-8 z: cnzztzgzqz +18-19 m: mjmmmmmmmmmmmmmmmpk +10-13 q: gqqqqqqsxqqqqdtqkq +10-11 x: nxmbxxxrgpmxxxfnxxxz +2-5 x: xbxzrxd +9-14 l: llllpljlllfllwv +1-2 m: mmmmmm +1-3 b: fblbbfbbbbbtbbgbbb +3-4 g: gnnccg +8-9 f: fffffffkffff +5-6 r: rrrrhf +7-8 l: lwlwllllllctl +5-7 j: jrjjwgjvkkncnjbqc +3-4 b: bbsbb +4-13 c: jmcczvkbxccdf +4-5 g: wgrgg +7-8 d: dgddddzh +3-8 h: hhbhhhhhhhh +15-16 l: llldllllllldlllllll +11-15 r: rrgrrrrrrrnrrgxr +10-11 l: lllllllllll +4-5 x: xfdbjsmbbcxdphvlfkxr +9-12 m: rqmnmrmhcmmms +3-8 b: tzsnnndnbwgbskbb +4-10 v: vvkvvdrvwvc +9-11 j: jjjdjjjjjsj +6-11 b: hbbmbbbbbbjbtrbbbz +13-16 v: vvpvvvbvcvvvvvvvv +11-14 j: jjjjjjljjjtjjmj +7-11 v: cvdglnvjxkvvgptxvp +1-6 t: ttjqtttzt +7-10 f: ffwpzfxjfgffzf +4-7 d: dddgddp +4-19 n: mjbdzqxhtfbnbfxrpgnh +6-13 d: ddddddddddddd +2-4 t: rhkd +5-9 c: ccrcxzjdzccx +3-4 j: fwjj +15-19 q: qqqtxqqqqqqqqqqqqqqq +1-11 c: gcccccmccctcc +3-5 d: dxhhdr +8-12 k: pkvrkkkvkkmbkcxjwktk +9-11 p: ppnpppppxppp +11-12 p: dppcsppppppqppp +7-8 b: bbbbbbmbqp +7-8 c: cbccccccc +8-9 b: bbbbbbbcrbb +2-6 z: gzlnpzpkhjwwqtswcrz +5-6 d: dddsdkd +1-5 w: dxwkgwwwwwwmwwwww +4-7 q: qqqnwqlqrqdcqpq +6-9 m: lmmmdmmvmmmm +7-8 h: hhhghhxh +2-3 j: jjjj +1-4 r: rrrw +4-7 m: mmjmmrm +4-5 j: vljjrj +19-20 j: jjjjjtjjjjjjjjjjjjgx +2-6 h: xhltfh +5-11 s: ssssjsssssss +3-4 b: bbbb +1-5 g: chgmtgnn +6-7 j: jjjjjjz +3-8 c: cccccrccccc +3-17 s: sslstssssssssspsgs +17-18 x: bxxxxxxxqxxxxxxxkwxx +9-10 q: qfqqzqqqsddqqqqqqq +6-10 k: kmkkkxvqkrk +5-9 f: kffffffffcdfffffplf +5-6 r: rrrrrz +2-5 d: hdgzt +7-10 k: zkrllwkkkjrkqfkkk +9-11 b: bbrkbbbbcbqqb +8-12 g: gfgkgggggggggggggg +12-14 s: sssjsspstlvlsrsssss +4-8 g: pqgzcgvgflgntlp +13-14 j: jjjjjjjjjjjjjx +4-6 k: kkkmqpk +3-5 j: sjjbjlvjjvjr +2-9 c: ckccjxzcrcctbfn +10-12 n: hvnnnnxnntnlnn +11-15 m: mmrmmmdmmmlmmmjqm +6-8 p: qpzrrpcpbxg +5-8 w: xwdzcgclxwsvfwtwbxnw +3-8 q: qzqzhlzc +2-3 v: hvvvvltft +5-12 s: tgvsswttkwfssnsqjsxk +5-17 b: bbbbbbbbbbbrbcbbbhb +3-6 p: ppjpzw +3-5 k: kkxvkswk +4-8 v: vbvrvxvgrvvwwvvm +3-12 v: njvvgvdcjvvtvvcnvg +4-5 n: bnnnrn +8-9 l: jlvxdlpll +12-14 w: fkwwwwwwcwwjwmwc +1-4 q: wmqrzpqhj +4-7 t: tctsttlt +13-14 h: hhhhhhhhhhhhhf +2-3 j: jmjjjjj +5-6 v: vvvvlv +5-13 v: fnxvvvvvnvqvvvvvws +16-17 l: gllllllllllgwqlll +1-2 s: pnpfsqw +6-13 g: ntzqggvbnwxrgskg +5-12 k: krxmbxqbkhxlnvdxdkkq +14-18 d: ddddddddjdddbdddddd +4-7 z: zzzzxzzs +15-18 d: dddddddddbddddpddh +8-11 x: slxxxxxjkxxxrsdx +4-6 n: nnnfzzn +1-4 h: gslcmnhhfhvz +1-4 d: tddqds +2-3 c: fccp +2-5 k: mkqrknj +9-16 g: gpggdggwgwgwglggg +2-5 h: hhjds +4-5 b: zbnvld +6-14 m: mfqmnmqtdmmzmm +7-8 j: thvcsgjn +1-5 x: xwjdxdqjtc +4-17 r: fqbrqrnpslndrmjdhpjp +4-5 c: ccccw +5-6 v: vvvvdm +5-12 n: nnqzjntfnnnd +3-4 c: nccqlccq +1-10 p: nrvvzpppqpn +9-16 v: jvvrpvvvvvzvhhvvgz +12-13 s: sjsslsssfxxkrssstkss +1-3 t: vtwbh +5-16 q: sxxfrqhqtvzbzqwg +5-9 z: dnzlhzzzsdzz +15-16 d: pdddddjddpkdddtdddd +3-4 p: pplqppp +7-9 s: scsslshsqssw +2-3 v: vxvxv +8-9 w: wqwwwwwgshww +8-9 k: kkkkkkkkc +9-10 v: vhfvvnvvtvvb +1-12 z: zzzbzzzzzzzdzzzz +6-7 b: bbbbbwhb +12-13 z: zzzsvtlzzzzzz +1-3 s: pssssssxw +8-9 w: xwwwwwwdzw +1-4 x: xxkxxx +10-12 f: fffffffpffvffff +18-19 w: wwspwwzwwqcrwwhwwww +6-8 s: ssssstsks +5-6 j: jjcjgm +2-5 p: wprwpxbdkrfpmppqpd +8-18 n: nnnnnnnnnnnnnnnnnn +4-11 c: txncpqclrlc +2-10 f: ffcffftfffxrxf +1-4 t: ttttttt +4-9 f: zdpjffffbfbl +6-7 f: kfsffffffm +1-4 b: bbdn +6-12 k: kkhkkkkdqkbkjkkkl +3-4 n: kmnn +4-11 l: kllcllldllclll +7-19 w: pfwdwdnkblwzgkfnfmh +3-9 z: zzphzdnhqwlzzwzz +15-16 h: hhhhhhhnhhhhhhhd +1-4 l: vllll +2-13 l: hdhvgdrlltlmjptzq +1-3 p: njvpltppbkxpfpppp +1-2 j: kkjv +10-11 c: ccccccmcccjcc +5-8 v: tqvmvtwvzfczvvvvw +6-9 x: xxmxxxfxxxxx +1-10 z: zgzzztmdtkzzpxztbgpp +10-12 g: ggwzjgdsgbnggl +5-6 j: jvxjvjj +4-7 x: xnxxmgxxtjxxkj +13-14 d: ddddmddddddddd +12-15 c: cccccccccccnccc +16-17 n: nnnnnnnntnnnnngnmn +1-12 m: bzckgvmmbdcxtgtmb +4-7 l: ljllllljl +5-11 w: wzvzwwrkmtwh +11-13 l: lmtpwxlllhlgllwvqnp +6-10 f: fvgkffqvcfffdbfff +3-5 j: kbfjjj +1-2 h: hhztdpbttnc +8-10 b: bbbbjbbqkbbbd +1-13 c: hccvcxtcclpckzd +6-10 w: wwwwwtwwzrwwf +2-3 j: fjnnj +2-4 j: njtjjjxrjv +4-5 w: fwwzw +7-9 k: qbnkghdbqlz +2-9 s: dsdftlzsszlf +4-5 v: vvvvd +1-2 w: fbfwwb +4-7 t: tttttmt +3-10 h: hhhhnhhhskhh +3-8 w: qwswwswfl +1-3 p: pmpgpp +2-7 n: nmmgnssmtn +2-3 j: djvjgjp +6-13 x: jxxbxxgnxvbxx +6-10 v: vrvvvvvvdz +2-3 b: bbbbjrkwnc +1-2 h: fshnf +1-5 n: htsknrzqnntknfnjx +5-9 d: kkgtwrdjmxkzc +12-13 x: xxxxxxxxxxxxx +2-10 m: wmmmmmdpmmmmh +2-12 n: xttqcmfkvnlkzskjhmzn +6-9 m: mmmmmxmkp +10-16 m: gmmdqmjmflmmmmmcmmm +13-14 p: pprprppppspxfgnptppp +1-16 b: gcnbbnbbmsjxnbppcb +10-11 d: dkdddddfjmpvdddd +1-9 f: zlfwstnzp +14-15 n: nnnnnndnnnnnrnnvcndn +2-6 l: lvvldlzdzgdf +6-10 z: zzzzztzzzhzz +13-14 n: nnnnnnnnnnnngln +8-9 z: zjqztzztqzzbxzz +2-3 v: dwcv +4-6 m: kmmmkmm +5-9 g: wtgfgdmxkx +3-5 b: vbzbf +10-11 w: wwwwwwwvwwz +2-8 s: sztstsnssq +2-6 l: lldzcslxdwghmn +1-2 n: vmznndnnnbrhknjwzkzx +3-4 k: kknp +1-5 h: hhhhhhh +12-13 z: zzzzzlszzzzzxz +1-12 m: mtbspfpdgpznrsmvgq +11-13 q: qqqqkqnqhqrqrq +14-18 d: dtdrdddddddddxfddddd +1-6 q: bqqqqqgqqqq +1-7 c: dlmvcsztzpx +4-6 g: gmgggg +5-6 s: ssswsssgdghv +8-9 k: kkkkkkkgn +1-17 s: ssssssssssksssssss +4-5 b: qqtlsh +5-6 g: gggggg +2-11 r: drkpvrrlrtrvrjhpd +3-7 k: fkkhmddh +6-7 h: hhhwhnfph +3-4 p: ptppmwpnps +3-6 w: hwcshlrm +7-8 d: dtddqddzn +1-6 s: sslsbssbsg +12-15 n: tbnnjknnkwnnnnsnnnz +8-9 z: zzzzzzzzz +2-5 w: kjnwn +4-7 m: mmmtdjmmmmtl +4-7 h: dqfhzrqhfhntzhkhhdvb +3-5 g: zvflgg +5-12 s: lvsvqnvssgcx +11-19 p: pcppvppplpwppppjlps +5-19 p: gkpmfxlmppczdnhbqcw +5-17 b: mdzljsdvxdmbbbbddvrw +1-5 s: shpdss +2-5 t: btggtltvw +1-6 b: sbbbbbb +3-6 w: wwpsfkwnrrr +13-18 f: ffffwfffsfffwffffn +4-5 m: mpmmmxmmggvnb +5-6 z: pwsqhcztlf +8-11 d: ddddddddddlf +1-2 t: xttt +6-8 m: mmmpmvmmm +16-17 h: hhhhhhhhhhhhhhhrw +1-5 g: gpgpgg +3-7 p: gplrpzp +11-18 t: ftqnxttzttxtgttntrtt +10-11 z: zzzzzzdzzlgzzz +3-10 z: lzfzzzzszbzzztj +2-10 l: khdbddnxltnk +4-8 b: tbbcjsnbrbhfb +3-6 x: xgsxmn +9-13 t: ttttttttmtttt +7-11 l: fllllllzllmdshrll +18-19 g: hffqfwssgqpcnmddkcw +3-4 m: mmhvmc +1-3 w: vwnw +5-6 r: rrrrrb +2-4 j: rjqj +5-7 b: kgblcbbdrb +3-5 g: jgggggg +1-11 v: vvrvvhxvrvvnrvvv +3-14 w: ncwphcwvjwhdpwqkg +6-7 x: xxxfqmkvxx +13-14 v: vvvvvvvvvvvvkt +2-12 x: xzcvvxhhwwxxc +6-14 m: mdtnmjmhmnmmmmm +15-16 z: zzzzzzzzzznzzzzzzz +4-6 s: mcssdssjshscvcl +11-12 b: bnbbbmbjsbxbbbbbj +7-13 c: cccfhccczccwcccsc +3-4 m: cgtmmm +5-10 l: hxhbggrllmtgn +6-8 d: sdfdddlv +4-9 x: xxxxxvxxcx +11-12 c: rcmqkzjccccrdccmc +1-3 g: jgng +4-5 l: lvlll +9-16 n: rnnnqjnvqnnnlnnwdnnn +4-10 x: crdxgxrfjhr +1-5 f: tgdffffffqf +15-16 q: qqqqqqqqvqbfqknqqqqq +9-11 s: sssnffssksq +3-4 v: vqvvv +5-19 z: jthjzpgmwjbftzvmnpzk +3-10 w: mpxhrrnqdvncwssqwlxz +14-15 b: bzbbbbbsbbbbbbbbbbb +3-5 j: jpjvjjrjtmjj +3-6 w: wwmwwzw +1-6 c: ccccvzcccm +10-11 m: mmvwgmjmmmrqjmmmglm +2-3 f: fffw +6-12 m: bmbzmmrshmmz +5-6 n: nnnnnn +4-5 k: kmsgkwvkk +6-8 t: tttttbttt +4-5 j: vtmvsqjl +5-6 q: qshzdqqk +1-3 w: dwgw +8-9 q: qbqqqqqwq +5-10 m: lmmmkgmmwb +6-9 n: nnnlnnnnn +4-5 t: tntct +6-8 g: hgngghgw +6-9 t: gttwtgvpgtlt +6-7 l: lllllll +4-5 j: jhjkjjm +13-15 h: hhhhhhhhhhhhxnh +1-4 m: mmmmm +4-6 q: cqrtqsdqqzrknf +9-13 f: fffffffffzfvff +2-16 p: prxdxjpkppgpxsjwpppp +3-4 r: rrzh +1-2 g: cglblsnkg +1-3 f: xqnfwjmmwqffd +13-14 q: qqqqqqqqqqqqvjqq +18-19 g: dggggggggggggggggvgg +5-6 s: dsssssss +4-6 z: szdzzb +9-12 t: xtltpgftttmtt +10-16 m: mqmmmmmmmcmmmmqx +3-7 c: cpccngcvccm +2-16 s: jsdfsjsjtswhkvmsskj +2-3 c: kccc +4-16 k: qhndnqmrvjcczfkpds +4-6 n: nnnrkxl +9-10 s: ssssssssds +2-3 z: hfzcz +2-3 s: sssz +8-10 b: qbbbjbbbbw +7-16 k: gcvskkjkkkkwkzkz +7-9 n: nnnnnnhnnnn +1-10 q: qjxqmqxcgg +9-11 l: jdhjbbcnlzll +7-14 l: llrlxlllllltlnl +3-6 f: wfdqfbrf +3-8 t: ttzttmtvttzpl +10-12 v: vfvvvvvvvsvv +5-6 v: vvvvvm +11-13 t: ttttxtttttptttctttt +3-4 k: kkdm +4-6 n: nnnlnt +13-15 m: mmmmmbmmmbmmmmmm +5-6 l: klllnl +2-3 f: flzff +3-4 r: frrs +1-5 d: cqwkvsdqdvb +9-15 l: jvtfqczlnlwdpclxwp +12-14 t: ttttttlqtpttnt +11-12 m: mmmmmmmmmmmm +4-5 j: jjjkbjjjjj +9-12 w: wwwwwwwwkwxkwcb +6-12 q: tcqrqqqqxjqqqqmqhq +5-6 m: mmmsmmmm +2-5 t: mttbttprttddtv +10-13 t: tttttttttttztt +10-11 f: kmqfxttfkfd +5-7 v: vrlzpvjtvv +6-7 l: nlllllj +1-5 q: szdbqqkqqtkmssq +3-4 q: kcmlwqzczwms +13-16 b: bsbbbbbbbbrbsbbpzbb +9-11 d: dddsdbddkdkdd +2-15 j: xkjnntffvvxfnntcv +4-6 v: hvvvcvqvrwv +9-12 j: qjjjjdjgqhrjjfjrdj +8-10 v: vvvvvvvnvnvv +4-9 t: ttttthttt +8-16 g: ggggklggcggggxgg +1-3 z: wpqz +4-5 g: wgdnmxccgj +8-11 r: rrrrrrrxrrmd +1-9 f: ffffsfgdbsqfffzf +7-8 q: qzqqqqrrq +12-13 n: nnnnnnnnnnnnnn +8-12 j: jpjjjmjjjjjzj +1-4 j: nvjw +7-13 z: zzzzsnzxzznzrzgzzzz +14-16 z: zzzzzzzzzzzzzzzm +1-4 x: xxxxnxh +8-15 k: gnrkktkpcmklkksnkk +2-4 h: klph +11-16 c: ccckzdccgckpcccsc +15-16 l: dlllllllllllllll +2-3 s: dsxss +1-4 v: jvvv +2-8 t: ktkdtxkt +1-3 t: ftftttttt +4-5 k: kkkbkk +4-6 g: llqcggg +4-14 r: fmdvrrwlstlbjr +2-16 p: rpdfhpbqfwxlxhhc +6-8 j: jjjjjjjjj +1-7 f: fnnffblbqffkrff +1-3 k: rfqwlnnkzdq +15-16 s: ssssswssssssskssss +11-13 z: zzzzngfzzzzzz +5-7 h: hhbhhcnhfghhhv +2-7 j: zjrmjgmjdkp +5-8 z: bzzzpzzrzzzz +12-16 j: jtjnjjjjgjjjjjjsj +5-9 s: ssssssssms +2-3 s: ssss +13-14 d: ddddddddddddkt +12-13 r: wfdtrknrhvrrc +6-8 p: vpxphxngzhnkppppfp +2-3 j: jtjx +3-6 k: tkkvjkb +2-6 t: tvftftvbfx +5-7 z: zzzqzzz +14-15 h: whdhxhhhhhhhfxzhhh +3-4 g: ngjgg +9-10 z: zzzzztzztq +2-7 f: fffffqfszchff +4-6 f: lfqjnzccffjslsdf +5-6 z: lpzzzzsz +11-13 t: tttttwtttttttttttt +2-6 z: zzzzzz +9-10 m: mmmmmmmmjm +5-6 w: xwggfcwvwlx +1-4 j: jjjjjljjjjjjj +8-10 t: ttttttwttt +5-12 x: zxxxxxxpxxxn +3-4 v: vvlrv +3-6 h: hhhwhlxhlrhl +2-5 p: cptsjktp +4-11 j: bmjjjjjjnwwdk +15-17 p: ppppppppppfpppvpp +7-11 m: wnnmmwmtmmxmm +9-19 k: kkkkkjkkhwkcvkkkmknw +11-15 s: sspssbshssscssssss +1-8 s: sssssmssssssssssss +4-8 x: xxxxdxxx +9-10 n: nnnrnlnnnnnnnnnnnnnn +10-11 d: ddddddddddn +5-9 z: tzzzqzbmzzzqzjkzlr +9-20 f: fffffnfffffffsfnffff +5-6 g: gvggggg +13-14 x: xxxxxxxxxxxxxxx +6-7 v: vvvzvvvv +5-10 l: kbcvlfvlszndtlldjlh +4-9 s: vkcsdvszthkwmmmxs +3-4 b: jbmb +2-4 w: nmwm +5-10 z: tztzzfzgdzzszq +2-8 k: kzkkkkzwf +16-17 d: vxvzdgzwssqdcgbdb +4-5 b: bbbbb +7-9 w: wwfwwwjwln +5-12 k: ljkkkqfvqtkkxsd +5-7 q: qqqqhqqq +8-9 n: vnnnnnnpstnn +5-10 m: mmgzmmmmmm +3-14 q: qgbvqjxqnqqqqqqq +2-4 c: cccc +3-7 b: szbbkbdbmbbzbqs +1-5 m: mhmmc +3-6 n: nnlvnnvnq +2-3 c: mccc +11-12 m: ddmmmmxmmmmwfmmm +8-10 n: nnnnnrnnnn +1-12 g: sgbggglnggddgggsngrx +7-9 p: phppppppp +4-5 q: qxqqqq +3-7 v: vwsvvrvxvvvvvvwvvdlv +8-18 j: jmjcjjltjmjwjzrllgcj +2-14 r: rdrrrrrrrrrrrp +2-4 r: cxcbkmr +6-9 r: vtlnnvbcndqhrxkkjp +2-3 s: hxssnsswzc +10-16 r: csrsrxrrrrrrfrfdrr +7-9 w: wwbwmvrwdxww +12-14 p: pppbpppppppgpt +2-7 n: nnnnnnnn +3-12 f: mhjxfxgbbvffpclfffg +10-14 l: lllskllljllllll +11-16 l: lwlklllglzllllllll +13-14 h: hhhhhhhhhhhhhdhhhh +1-2 t: tttb +1-6 z: zzzrrzzbf +1-6 v: jrvzvvrs +3-6 g: jggbnl +17-18 x: xxxxxxxxxxxxxxxxrx +8-17 f: xnmffffbwfdcfrdfw +3-9 k: jmkdvkdnk +7-9 m: mmmmmmdml +9-11 c: cdmshccckqmcccccckp +16-17 g: gggggngggggggggggdg +7-8 n: nnknnnnnnn +3-13 n: fjhgrspsnkmnf +14-17 z: zzzzzzzzzzzzzqzzzzzt +13-14 r: rrrtrrfsvrzngw +7-8 k: kvkvkpvc +1-2 b: bbpbb +1-7 n: tchnrtbtldnmnnvvnn +3-4 s: sssssjv +1-9 l: cllllztmlllrzfl +9-10 x: qjxxxxxxdhxxxxxh +6-7 p: ppppfppv +3-8 q: mkqzqqbqzjrqbq +6-8 x: xxxxxxxx +1-7 f: ffffffff +5-16 b: jbbbbbqcbbbbbbfb +9-11 c: ccccccccccq +1-2 x: fqkx +4-12 z: znzzzzzzzzzzzzz +3-4 l: lglll +9-11 m: mmmmmmmmmms +14-17 x: xrxpxgkxxzdrxxxxckxv +3-5 t: gxjbbfcpmkbkxbtwbt +5-6 j: jmjjjj +14-15 g: ggggggggggggggx +6-7 l: lllllbl +2-14 q: qqtsqkqvqqqpxzqqcqq +2-4 w: fwhw +4-5 m: mzmtkm +2-4 g: ghghgp +5-6 r: rrrrnl +1-4 h: chghhw +7-12 r: rrrzglvrrrrsrr +1-7 x: xxcxdwxjmx +5-12 r: rrgrrffwtrrnrrqrrjnr +2-5 r: srdqrlxrkrrdkr +3-4 t: ttdg +11-12 s: bfjrkqqgdtlwrskmfrp +3-5 n: nnrnfzsnm +10-15 z: zzzzhzzqqczxwzqztv +2-7 f: ffgdfgff +7-10 d: ddtbdddddjtdqfdddfq +2-9 k: gkrkkkkkkkkhkqkx +13-14 n: nngnlnnnhnnnnnnnn +6-9 r: qrxrxzrff +7-9 m: mmmmmtmqqmml +11-12 p: pppppppppppp +10-13 j: jjjjjjjjjznvbjj +1-2 c: ccvc +7-8 m: mmmmtdmckkpmcbkjmm +5-8 j: sjptjjbjjjjj +6-8 d: jchdwrhd +5-6 z: lqzzzzkrzzvzwbbzktp +6-8 l: ztbltlll +2-3 z: zkrxzp +7-18 g: phgpgggqgzgnmwlpkwd +8-9 f: hffffffqf +17-19 p: pppppphpppppppppzpp +2-3 z: zzzfg +1-2 v: bfvj +4-8 b: bcbbbbbb +15-16 s: ppsnsssssssnssss +2-3 m: mnsm +2-4 h: hwfshh +9-15 h: hhwhhhhxhhhhhhh +17-18 n: nnnnnnnnnnnnnnnnnn +7-11 n: nnnnnqpnlbgqnqnshn +15-16 j: cdjmbcwdppvvjqvv +6-11 p: ppplppppxpt +4-5 r: rrrrrr +10-11 w: wwwwwwwwwww +3-7 p: pzppzspppmkxbldwpnwf +2-12 w: zwdljlzwgxfwvtdm +2-10 f: mzfjqfspgfrfhst +14-15 m: mzmmmvhwmdmmdpz +1-12 r: vrxrrtrxgvrd +4-5 n: nnnnnnpn +6-12 x: xkbwfsxxxxxkxxxxk +4-6 n: mncnxn +9-10 f: ffffpfqftbf +3-5 b: bzwbk +4-7 c: ncdcccc +11-12 t: dgdkrjgsgtlf +8-11 z: rqzdjqznrpkzmblbt +1-3 z: zfzx +2-4 z: kzgzkp +6-10 v: jvvvvvvvvs +2-9 v: vrvvvvvvvc +5-6 q: qqqqqqc +6-10 p: ppdknlgpqkp +10-13 z: zzzzzzzzzzzzvz +19-20 g: dtckblrmggknmxwnrjgg +4-18 p: ppcjpqfpcxtphlppmhcx +6-7 n: nnsnnknthn +10-11 f: fffffffffff +2-4 f: ffccltsfgk +6-11 d: dsqddtddddjcnssrcd +7-13 x: xxxxxqlxxxxfw +12-13 r: rrrdrrrrrmrrrr +15-17 p: pqppppppppppvppppppp +7-8 j: jjjjjrdp +4-6 v: vvvvvt +1-4 t: tltftjtjhz +9-15 j: jjjjjjhjjjjjjjkjj +6-7 c: ccccccccz +8-9 x: xxjxxxxxsx +4-5 h: hhrhh +2-3 g: cgnm +8-10 l: llqlgllzlvrllg +12-13 c: cvnbccpzzxcccfh +3-8 z: zbzrwzzzwrzbqnr +6-7 n: nnnnnnn +8-11 j: tjqjrjggjxxjggjj +7-12 l: bsvxdhljlcsj +3-6 j: jjfjjjjb +2-3 z: dzztwhmzqdx +9-12 v: vvvvvvmvzvvcv +13-14 v: vvvzvvvvvvvvvk +6-7 g: fgggghgng +13-14 h: wcghlwdbjhpdphkcv +1-2 t: nncsg +6-7 w: kwjwwxlwz +4-5 z: zzztvz +3-4 n: nvbvngnw +15-17 z: zzzzzzzzzzzzzzzzzzp +8-10 r: rrrstrgxrhrr +8-10 g: cggggggvgcg +1-4 m: mmvbz +3-14 j: bdbhbjnjnrldhwlbrkrj +1-4 r: rrkrnnd +2-3 f: fvwc +4-13 c: ccccvcgwbhwrcqf +3-9 c: jcghltcfkjchxmccccbs +3-5 h: hhhshm +5-9 h: hhhsjhhhhgthfgldw +4-12 h: mcwvwwphwwbc +6-11 g: gqgggvggggh +9-15 x: xxxxxxxxxxxxxxsx +16-18 t: rmqqtbtvttsdtjvbttl +9-20 f: cllnvlfkfrwzpqxwqgnn +9-18 v: vvvvvvvvzvvvvvvzvxvv +4-5 f: fzffbfvfff +1-5 p: pppppp +1-7 z: zjvchwzqjrtxzgz +4-9 v: vvvvvvvvvv +5-8 w: cwwwzwwb +7-8 r: rrrrxrrr +8-9 f: sgdcqfhfcfsflb +3-7 g: gdgtnfggq \ No newline at end of file diff --git a/2020/day-02/solution.js b/2020/day-02/solution.js index 779f7ea..d3ca3f9 100644 --- a/2020/day-02/solution.js +++ b/2020/day-02/solution.js @@ -1,12 +1,13 @@ const fs = require('fs') const path = require('path') const filePath = path.join(__dirname, 'input.txt') -const { inputToArray } = require('../../2018/inputParser') +const { linesToArray } = require('../../2018/inputParser') +const { isValidRecord } = require('./cleanupPasswords') fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { if (err) throw err - initData = inputToArray(initData.trim()) + initData = linesToArray(initData.trim()) const resetInput = () => { // Deep copy to ensure we aren't mutating the original data @@ -15,8 +16,8 @@ fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { const part1 = () => { const data = resetInput() - console.debug(data) - return 'No answer yet' + // Count the valid passwords + return data.filter(isValidRecord).length } const part2 = () => { From d1de0f25b95ab0624f4017f3f8c34eab3c2df9c8 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 19:15:07 -0800 Subject: [PATCH 11/21] refactor(2020-day-02): prep for different password validation rules Rules provided were for old employers --- 2020/day-02/cleanupPasswords.js | 20 +++++++++++--------- 2020/day-02/cleanupPasswords.test.js | 12 ++++++------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/2020/day-02/cleanupPasswords.js b/2020/day-02/cleanupPasswords.js index 042bc94..7b4dde3 100644 --- a/2020/day-02/cleanupPasswords.js +++ b/2020/day-02/cleanupPasswords.js @@ -14,7 +14,7 @@ const splitRecord = (row) => { /** * Splits a password validation rule into its component parts */ -const splitRule = (rule) => { +const oldSplitRule = (rule) => { const splitRow = rule.split(/-| /) return { @@ -27,7 +27,7 @@ const splitRule = (rule) => { /** * Validates a password against the specified rule */ -const isValidPassword = (rule, password) => { +const oldIsValidPassword = (rule, password) => { // count how many times `rule.char` exists in `password` const count = ( password.match( @@ -40,15 +40,17 @@ const isValidPassword = (rule, password) => { return true } -const isValidRecord = (record) => { +const oldIsValidRecord = (record) => { const { rule, password } = splitRecord(record) - const { min, max, char } = splitRule(rule) - return isValidPassword({ min, max, char }, password) + const parsedRule = oldSplitRule(rule) + return oldIsValidPassword(parsedRule, password) } module.exports = { - splitRecord, - splitRule, - isValidRecord, - isValidPassword + old: { + splitRule: oldSplitRule, + isValidPassword: oldIsValidPassword, + isValidRecord: oldIsValidRecord + }, + splitRecord } diff --git a/2020/day-02/cleanupPasswords.test.js b/2020/day-02/cleanupPasswords.test.js index 01602fa..93f407b 100644 --- a/2020/day-02/cleanupPasswords.test.js +++ b/2020/day-02/cleanupPasswords.test.js @@ -1,6 +1,6 @@ /* eslint-env mocha */ const { expect } = require('chai') -const { splitRecord, splitRule, isValidPassword, isValidRecord } = require('./cleanupPasswords') +const { splitRecord, old } = require('./cleanupPasswords') const testData = [ '1-3 a: abcde', @@ -22,7 +22,7 @@ describe('--- Day 2: Password Philosophy ---', () => { it('splits a password formatting rule into component parts', () => { testData.forEach((row, idx) => { const { rule, password } = splitRecord(row) - const { min, max, char } = splitRule(rule) + const { min, max, char } = old.splitRule(rule) expect(`${min}-${max} ${char}: ${password}`).to.equal(testData[idx]) }) }) @@ -32,14 +32,14 @@ describe('--- Day 2: Password Philosophy ---', () => { const expectedResults = [true, false, true] testData.forEach((row, idx) => { const { rule, password } = splitRecord(row) - const { min, max, char } = splitRule(rule) - expect(isValidPassword({ min, max, char }, password)) + const { min, max, char } = old.splitRule(rule) + expect(old.isValidPassword({ min, max, char }, password)) .to.equal(expectedResults[idx]) }) }) it('won\'t allow more than the specified character count', () => { const badPass = 'abcabcabcabc' - expect(isValidPassword({ min: 2, max: 3, char: 'a' }, badPass)) + expect(old.isValidPassword({ min: 2, max: 3, char: 'a' }, badPass)) .to.equal(false) }) }) @@ -47,7 +47,7 @@ describe('--- Day 2: Password Philosophy ---', () => { it('checks if a specified record contains valid rule and password', () => { const expectedResults = [true, false, true] testData.forEach((row, idx) => { - expect(isValidRecord(row)) + expect(old.isValidRecord(row)) .to.equal(expectedResults[idx]) }) }) From 97c08346ec0f0c504be46fd5a77f96bac343c54d Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 19:45:36 -0800 Subject: [PATCH 12/21] feat(2020-day-03): count the valid passwords under the new rules Rules changed, as shopkeeper was thinking about old employer in Part 1 --- 2020/day-02/cleanupPasswords.js | 45 ++++++++++++++++++++++++++++ 2020/day-02/cleanupPasswords.test.js | 33 +++++++++++++++++++- 2020/day-02/solution.js | 10 +++---- 3 files changed, 82 insertions(+), 6 deletions(-) diff --git a/2020/day-02/cleanupPasswords.js b/2020/day-02/cleanupPasswords.js index 7b4dde3..8770749 100644 --- a/2020/day-02/cleanupPasswords.js +++ b/2020/day-02/cleanupPasswords.js @@ -13,6 +13,7 @@ const splitRecord = (row) => { /** * Splits a password validation rule into its component parts + * using the original rules */ const oldSplitRule = (rule) => { const splitRow = rule.split(/-| /) @@ -24,8 +25,25 @@ const oldSplitRule = (rule) => { } } +/** + * Splits a password validation rule into its component parts + * using the new rules + */ +const newSplitRule = (rule) => { + const splitRow = rule.split(/-| /) + + return { + positions: [ + Number(splitRow[0]), + Number(splitRow[1]) + ], + char: String(splitRow[2]) + } +} + /** * Validates a password against the specified rule + * using the original rules */ const oldIsValidPassword = (rule, password) => { // count how many times `rule.char` exists in `password` @@ -40,17 +58,44 @@ const oldIsValidPassword = (rule, password) => { return true } +/** + * Validates a password against the specified rule + * using the new rules + */ +const newIsValidPassword = (rule, password) => { + let matches = 0 + rule.positions.forEach((pos) => { + // index starts with 1 + if (password[pos - 1] === rule.char) { + matches++ + } + }) + // Only one match allowed, not 2, not 0 + return (matches === 1) +} + const oldIsValidRecord = (record) => { const { rule, password } = splitRecord(record) const parsedRule = oldSplitRule(rule) return oldIsValidPassword(parsedRule, password) } +const newIsValidRecord = (record) => { + const { rule, password } = splitRecord(record) + const parsedRule = newSplitRule(rule) + return newIsValidPassword(parsedRule, password) +} + module.exports = { old: { splitRule: oldSplitRule, isValidPassword: oldIsValidPassword, isValidRecord: oldIsValidRecord }, + cur: { + splitRule: newSplitRule, + isValidPassword: newIsValidPassword, + isValidRecord: newIsValidRecord + }, splitRecord } diff --git a/2020/day-02/cleanupPasswords.test.js b/2020/day-02/cleanupPasswords.test.js index 93f407b..9f95ab2 100644 --- a/2020/day-02/cleanupPasswords.test.js +++ b/2020/day-02/cleanupPasswords.test.js @@ -1,6 +1,6 @@ /* eslint-env mocha */ const { expect } = require('chai') -const { splitRecord, old } = require('./cleanupPasswords') +const { splitRecord, old, cur } = require('./cleanupPasswords') const testData = [ '1-3 a: abcde', @@ -53,4 +53,35 @@ describe('--- Day 2: Password Philosophy ---', () => { }) }) }) + describe('Part 2', () => { + describe('splitRule()', () => { + it('splits a password formatting rule into component parts', () => { + testData.forEach((row, idx) => { + const { rule, password } = splitRecord(row) + const { positions, char } = cur.splitRule(rule) + expect(`${positions.join('-')} ${char}: ${password}`).to.equal(testData[idx]) + }) + }) + }) + describe('isValidPassword()', () => { + it('checks if a specified password matches the specified rule', () => { + const expectedResults = [true, false, false] + testData.forEach((row, idx) => { + const { rule, password } = splitRecord(row) + const ruleObj = cur.splitRule(rule) + expect(cur.isValidPassword(ruleObj, password)) + .to.equal(expectedResults[idx]) + }) + }) + }) + describe('isValidRecord()', () => { + it('checks if a specified record contains valid rule and password', () => { + const expectedResults = [true, false, false] + testData.forEach((row, idx) => { + expect(cur.isValidRecord(row)) + .to.equal(expectedResults[idx]) + }) + }) + }) + }) }) diff --git a/2020/day-02/solution.js b/2020/day-02/solution.js index d3ca3f9..f595f32 100644 --- a/2020/day-02/solution.js +++ b/2020/day-02/solution.js @@ -2,7 +2,7 @@ const fs = require('fs') const path = require('path') const filePath = path.join(__dirname, 'input.txt') const { linesToArray } = require('../../2018/inputParser') -const { isValidRecord } = require('./cleanupPasswords') +const { old, cur } = require('./cleanupPasswords') fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { if (err) throw err @@ -16,14 +16,14 @@ fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { const part1 = () => { const data = resetInput() - // Count the valid passwords - return data.filter(isValidRecord).length + // Count the valid passwords with old rules + return data.filter(old.isValidRecord).length } const part2 = () => { const data = resetInput() - console.debug(data) - return 'No answer yet' + // Count the valid passwords with new rules + return data.filter(cur.isValidRecord).length } const answers = [] answers.push(part1()) From 7a704d81dc1b2acf1cc6113c0acee8df425f811a Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 21:11:18 -0800 Subject: [PATCH 13/21] feat(2020-day-03): check a route to the airport for trees --- 2020/day-03/airportRoute.js | 33 +++++++++++++++++++++++++++ 2020/day-03/airportRoute.test.js | 39 ++++++++++++++++++++++++++++++++ 2020/day-03/index.js | 1 + 3 files changed, 73 insertions(+) create mode 100644 2020/day-03/airportRoute.js create mode 100644 2020/day-03/airportRoute.test.js create mode 100644 2020/day-03/index.js diff --git a/2020/day-03/airportRoute.js b/2020/day-03/airportRoute.js new file mode 100644 index 0000000..7b4743c --- /dev/null +++ b/2020/day-03/airportRoute.js @@ -0,0 +1,33 @@ +const queryPosition = ({ map, position }) => { + // check vertical position + const row = map.rows[position[1]] + // check horizontal which repeats + return row[(position[0] % row.length)] +} + +const positionHasTree = ({ map, position }) => { + return (queryPosition({ map, position }) === '#') +} + +const countTreesOnRoute = ({ + map, + start = [0, 0], + slope = [3, 1] +}) => { + let treeCount = 0 + const position = start + const advance = () => { + position[0] += slope[0] + position[1] += slope[1] + } + while (position[1] < map.rows.length) { + if (positionHasTree({ map, position })) treeCount++ + advance() + } + return treeCount +} + +module.exports = { + countTreesOnRoute, + positionHasTree +} diff --git a/2020/day-03/airportRoute.test.js b/2020/day-03/airportRoute.test.js new file mode 100644 index 0000000..ba640a5 --- /dev/null +++ b/2020/day-03/airportRoute.test.js @@ -0,0 +1,39 @@ +/* eslint-env mocha */ +const { expect } = require('chai') +const { positionHasTree, countTreesOnRoute } = require('./airportRoute') +const testData = [ + '..##.......', + '#...#...#..', + '.#....#..#.', + '..#.#...#.#', + '.#...##..#.', + '..#.##.....', + '.#.#.#....#', + '.#........#', + '#.##...#...', + '#...##....#', + '.#..#...#.#' +] + +describe('--- Day 3: Toboggan Trajectory ---', () => { + describe('Part 1', () => { + describe('positionHasTree()', () => { + it('can find a tree', () => { + expect(positionHasTree({ map: { rows: testData }, position: [4, 5] })).to.equal(true) + expect(positionHasTree({ map: { rows: testData }, position: [8, 9] })).to.equal(false) + }) + it('can handle the horizontal terrain repeat', () => { + expect(positionHasTree({ map: { rows: testData }, position: [25, 5] })).to.equal(false) + }) + }) + describe('countTreesOnRoute()', () => { + it('tallies the number of trees on the route', () => { + expect( + countTreesOnRoute({ + map: { rows: testData } + }) + ).to.equal(7) + }) + }) + }) +}) diff --git a/2020/day-03/index.js b/2020/day-03/index.js new file mode 100644 index 0000000..a7e4223 --- /dev/null +++ b/2020/day-03/index.js @@ -0,0 +1 @@ +require('./solution') From b25ec56e55ad492117d05018e0d6d2b4d2fcc647 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 21:16:02 -0800 Subject: [PATCH 14/21] feat(2020-day-03): find number of tree collisions on provided route Solution for part 1 --- 2020/day-03/input.txt | 323 ++++++++++++++++++++++++++++++++++++++++ 2020/day-03/solution.js | 35 +++++ 2 files changed, 358 insertions(+) create mode 100644 2020/day-03/input.txt create mode 100644 2020/day-03/solution.js diff --git a/2020/day-03/input.txt b/2020/day-03/input.txt new file mode 100644 index 0000000..086d326 --- /dev/null +++ b/2020/day-03/input.txt @@ -0,0 +1,323 @@ +...........#..#.#.###....#..... +...#..#...........#.#...#...... +#.....#..#........#...#..##.... +..#...##.#.....#.............#. +#.#..#......#.....#....#....... +.....#......#..#....#.....#.... +.......#.#..............#...... +.....#...#..........##...#..... +...#....#.#...#.#........#...#. +..#.........###.......##...##.. +.#....#...........#........#..# +..#.............##............. +..#.##.#....#................#. +.....##.#.......#....#...#..... +......#.#....##................ +..#..........###..#..#.#..#.... +....#..............#....##..#.# +.#.........#.#....#.#.#....#... +..#.....#......##.#....#....... +..#.#....#..#.#...##....###.... +...#......##...#........#.#..#. +.##.#.......##....#............ +...##..#.#............#...#.#.. +.##...##.#..#.................. +..#......##......#......##..... +.....##...#..#...#.........#... +.##.#.....#..#..#.##....##....# +..#.#......#.......##.......... +......................#......## +##.#...#.................#.#.#. +......#.#..........#.....##.#.. +#.#......#.....#...........#... +.....#...#.......#..#..#.#...#. +...........#......#.#...#...... +....##...##...........#......#. +.........#.##.................. +......#...#....#......##.##...# +......#...#.#########......#... +.......#.#...#.......#..#...... +............#...#...#.###...##. +...........#..........#...#.... +...#..#.#................#.#..# +..#....#.....#.............#.#. +....##......#........#....#.... +........##...............#....# +........#..#...#..............# +...#....#.#...#..#...#....#.#.# +.........#.......#....##....... +#.##..............#.#........## +......................###...... +.........#....##..##....#.#.#.. +.#...##.#.#...#....##..#.....#. +....................#.#......#. +.#..#.......................#.. +..#..#.............#..#....#... +...#...#..#...#...#.#..#.##.... +........#....#...#....#........ +.#.....#........#.........#...# +...#......#..#..#..####..#..... +#....#..............#.##....... +.#....#.............##...#..... +....#...#.##........##......#.. +##....#...#.......#..#........# +....##........................# +..................#..#......... +..#....#........#..#.......#... +#...#..#....#...##...........#. +.........#..#..#.#.##.......... +....#.#..#.....#..#.#.#.#..#.## +##................#.##.....#... +.#.....###..#..#..#.....#....## +...#...........#..........####. +.#.....#....#......#.##..#.#... +..#...##....#................#. +........#.......#......#.#..... +....#.#.#.#....#...#......#..#. +...........#......#..#......... +###...##......##.#..#....##.... +##....##.........#..#....###... +#.#.....#....#......#...#..##.. +#....##.#..............#.##.... +.#........#.#.........#...#.... +......................#......#. +........#..#..##.....#..#.#.... +..#...###.................#..#. +...#...#............#.......... +.##.......#..#.........#....#.. +.#..............#....#....##... +...............##..#.#.......## +.#.....#....#...#..#.......#..# +#..#.............#....#......#. +.....#.#......#.........###..#. +.#...#.#...............#....#.. +#......#.............#......... +.#.##.#.####...#..#.##..#.....# +.....#......#..#...#.......#... +#........###...#.....#..#.....# +....#.#.....#...#..........#... +...#.#.......#.#......#..#.##.. +..#..........#.#..#.......#.#.. +#...#.#..............#...###.#. +...#..#...#............###..... +..#..#...#.#............#..#... +.###.#.....................#..# +....#....#..#.....##.##........ +#....#....#.#..#.........#..... +.#.....##....#............##..# +#....#.#...#...#..#.#......#... +#.....##.....##.....##.#...##.. +...##...#..#..####.#........#.. +.........#...#......##..##..#.. +..#.....###.#..#..####.#....... +.......#......#...#..##....#... +.#.....#.#.#..#....#...#..##... +..........#.#...#...#.#..#..... +....#.....#........#.....##..#. +..#.#.##.........#...##.....##. +.........#.##....#............# +............##.....#.......#.#. +......#.....#...#..#..###...... +##.....#.......#...##.#....#... +...........##......#..##...#.#. +..#.#.#.#...#.......#....#...#. +#.............#.....#.#...###.. +##....#.......#.....#..##.#.... +...#.......#....#.........##... +......#.......#......##.##..... +..#......#...#.#........#...... +....#.#....#.#.##......#.....#. +#......#.........#..#....#..... +........#..#....##.....#....... +#......##....#.##....#......#.. +..#.......#............##.....# +...........#...#...........#... +#.......#...#....#....#...#.#.# +..###..#........#........#..... +..#..###...........#.#......#.. +.#...........#......#.......... +.#.......#.....#.......#....... +..#......##.#............#....# +#..........#.....#.#..#........ +.....#...##.##.......#......#.. +..........#.....#........#.#.#. +....#......#.....#......#.#.... +.........#.#.#..#...##....#...# +.........#.......#...##...#.#.. +.##........#...............#... +.......#....#...........##..... +.........###......#.........#.# +......#.......#...#..........#. +...#.#..........##......#...#.. +#.......#.#..........#......... +................#..#......#..## +.....#...#....#.#.....#........ +#.....#....#...........#....#.. +#....#.#..#...##....#...##.#... +...#.....#......#.#....#..#..#. +..#................#...#.#..##. +..........#..............#..#.# +.....##.....#..#.###........... +....#.#......#.#...........#... +.#....#.#.........##.#....#.... +.#.#........#........###....#.. +##.#................#...#..#... +.......#......##..#.....#..#.#. +...#............#......###...## +#.#...........#.........#...... +.....#.#.#.................#... +....#..............#...#.#..... +...#.#.....##..#............... +.#..##...#....##.....###..#.... +...............#...#...#.#.###. +.###....#.....#...#.#......#... +...#..#.....#.......#..##.#.... +...........#..#....##..#...#... +...#...#..........#.......##.#. +............#.#.......#........ +....#.........#.....#.......... +...#.###.##..#...##..####..#..# +.#.#...#..#...................# +.....#..#.....##..#............ +....#......#...##..#.##........ +...#...............#..#.....##. +...#......#.........#.#..##.... +.#....#.##.......#......#...... +....#.......#....#..........#.. +#.#.#....###.#.#.............#. +..##..###........#.#..#.#..#... +......#.#............##.#...### +.........#.#....#####.....##... +............##......#.#..#..... +...#.....#.....###....#........ +##..........####.##.#.#........ +....................##.....##.# +#.#............#........#...... +....#...##.....#......#....#... +...###.#..##..................# +..###......#..............#.#.# +.#...#...........#....#........ +....#............#..#..#.#..... +...#.........#.#.........#.#### +..#...#...#...#...........#.... +...............#.#......##..#.. +#....#.#.......#.#..#......#..# +........#.#....#..#...#..#...#. +...#..#.......#...........#.... +...........#.......#........... +.#......#................#..... +....#.#.#...#......#..#...#.... +................#.#.#....#..... +.........................##..#. +.#...........#............##... +#...............#.....##.#.#..# +.........#.......###....#.....# +....##...#...#.....#..#........ +........#.....#..#.#.#...#..#.. +......#.......#.#.........#.#.. +#......#............#...#....#. +#..##...#..#................#.. +.##...#...#.....#.##.......#..# +.......#.##........##..##...... +##.#..##...............#.....#. +......#....#..##...#......###.# +#........##..#....#.#......#... +.#......##.#...#.#...#......... +.#.#...#..#.............#...... +.##..........#..........#...... +.#.....#.....#..............#.# +..#.........#..#.#.....#.#....# +..#.##..............##...#..### +....................#.......... +......###..#..#...........#.... +..#..........#.......#...#..... +...#......#......#............. +....##..............#.#.....#.. +........#.#......#..#........## +.............#...#.#.........## +...###...#..........##.......#. +.#..........#...##..#.#.....#.. +##...#.........#............... +......#....#....#.....#.....#.. +..........#....#...#...#..#...# +...##....#.#.#..#...##......... +#......#.#...##.###...#....#... +##.......##.#......##..#...#... +......#.............#.##.....## +#.......###....####.#...##....# +..#...#..#.......#..........#.. +#.....#..#..#..#.##...###...#.. +.....##.#..#..#..#.#....#...#.. +..#...#..................##.... +....#.#........##.............. +#...#.......##...#...#.#....... +..#...#........##....#.#....... +..........###...###...#......#. +#.....#..###...##...##..#..#..# +..#.....##.....#.......##..#.#. +........#........#.........#... +.................#....#.......# +.......#...#.....#...#.#....... +....##...............#...##...# +.##...#................#...#... +.............#................. +.#..#....#....#.#....#......... +.#.#..#..........#.......#..... +.....##.....##...#..#.......... +#...#.#.........#......#..#.... +........#....#...#....#.#.##... +....#..#........#...#...#...... +.#..#.....#.#...#.........#.... +.#..#..#...........#..#....#... +....###.............#..#....... +#......#..#..##..........#.#... +#..#..#.##..#...#.#.#.......... +....###......#.##.....#....#... +.##..#...#......##.#........... +..#..#.......#.....#.##....#.#. +.......#.#.#........#....##.... +..##...#....#...............### +#..##..#...........#.#....##... +...##..#.....................#. +###......#....#....###..#...##. +.........##............#..#...# +..#..........#...#.#.#......#.# +.......#.....##..##......#.##.. +#..........#.....##.#.......... +#.......#.#...#...#....#....... +#...#.....##.......#.#..#.#.#.. +.........#.#.#..#..#...#.###... +.................##...#....#... +###.......#..........##...#.... +#.#..#.........#....##.#....... +......#.#.....#........#....... +.......#.#........#......#.#..# +..............#..#...##....#..# +#...........#...##.....#..#.#.. +..#....#..#.#.#...#..#....#.#.. +...##.#.....#..#...##..#.....#. +..#.#................#........# +......#...#.............#...... +.##............#....#...#..#... +....#...#...........#.......#.. +.###..#.......#.............#.# +.#.#....#.#...........#.#...... +...#.........#.........#..#.... +...#..........#.#.....#.#...... +.....#........#....##......#... +..#.#.#......#..#.#......#....# +.#.#..#................#.#..... +.#.#.........##...#.......#.#.# +#..#.....#...#..#...........#.. +..##......####......#..#....### +#.....###....#.#........#..#..# +..##.#...#.#..##..........#..#. +#.........#.#.............#...# +...#.#...#...#.#.#....##....... +##.##...#.....#...#...........# +....#........#.#.....#......... +.................##..#..##...## +.....##....#...#...#.....#..#.. +....#...#........#............# +..#...........##....#...#...##. +.....#......#.........#..##.#.. \ No newline at end of file diff --git a/2020/day-03/solution.js b/2020/day-03/solution.js new file mode 100644 index 0000000..6d13efb --- /dev/null +++ b/2020/day-03/solution.js @@ -0,0 +1,35 @@ +const fs = require('fs') +const path = require('path') +const filePath = path.join(__dirname, 'input.txt') +const { linesToArray } = require('../../2018/inputParser') +const { countTreesOnRoute } = require('./airportRoute') + +fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { + if (err) throw err + + initData = linesToArray(initData.trim()) + + const resetInput = () => { + // Deep copy to ensure we aren't mutating the original data + return JSON.parse(JSON.stringify(initData)) + } + + const part1 = () => { + const data = resetInput() + return countTreesOnRoute({ map: { rows: data } }) + } + + const part2 = () => { + const data = resetInput() + console.debug(data) + return 'No answer yet' + } + const answers = [] + answers.push(part1()) + answers.push(part2()) + + answers.forEach((ans, idx) => { + console.info(`-- Part ${idx + 1} --`) + console.info(`Answer: ${ans}`) + }) +}) From 41736ff59be7fa2ec78df27fec2cd6310198cdbc Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 21:23:35 -0800 Subject: [PATCH 15/21] feat(2020-day-03): calculate tree collisions for multiple slopes Solution for part 2 --- 2020/day-03/solution.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/2020/day-03/solution.js b/2020/day-03/solution.js index 6d13efb..f915c14 100644 --- a/2020/day-03/solution.js +++ b/2020/day-03/solution.js @@ -21,8 +21,20 @@ fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { const part2 = () => { const data = resetInput() - console.debug(data) - return 'No answer yet' + const slopes = [ + [1, 1], + [3, 1], // Same as default + [5, 1], + [7, 1], + [1, 2] + ] + // Multiple the results of multiple slopes + return slopes.reduce((itr, slope) => { + return itr * countTreesOnRoute({ + map: { rows: data }, + slope + }) + }, 1) } const answers = [] answers.push(part1()) From c1771218ae4035b042438300daf4689c8c1e2c40 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 21:30:09 -0800 Subject: [PATCH 16/21] feat(2020-day-04): stub out day 4 --- 2020/day-04/index.js | 1 + 2020/day-04/input.txt | 0 2020/day-04/solution.js | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 2020/day-04/index.js create mode 100644 2020/day-04/input.txt create mode 100644 2020/day-04/solution.js diff --git a/2020/day-04/index.js b/2020/day-04/index.js new file mode 100644 index 0000000..a7e4223 --- /dev/null +++ b/2020/day-04/index.js @@ -0,0 +1 @@ +require('./solution') diff --git a/2020/day-04/input.txt b/2020/day-04/input.txt new file mode 100644 index 0000000..e69de29 diff --git a/2020/day-04/solution.js b/2020/day-04/solution.js new file mode 100644 index 0000000..779f7ea --- /dev/null +++ b/2020/day-04/solution.js @@ -0,0 +1,35 @@ +const fs = require('fs') +const path = require('path') +const filePath = path.join(__dirname, 'input.txt') +const { inputToArray } = require('../../2018/inputParser') + +fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { + if (err) throw err + + initData = inputToArray(initData.trim()) + + const resetInput = () => { + // Deep copy to ensure we aren't mutating the original data + return JSON.parse(JSON.stringify(initData)) + } + + const part1 = () => { + const data = resetInput() + console.debug(data) + return 'No answer yet' + } + + const part2 = () => { + const data = resetInput() + console.debug(data) + return 'No answer yet' + } + const answers = [] + answers.push(part1()) + answers.push(part2()) + + answers.forEach((ans, idx) => { + console.info(`-- Part ${idx + 1} --`) + console.info(`Answer: ${ans}`) + }) +}) From 63570604881e046d7268377ef4da43f8d2fff20f Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 22:46:56 -0800 Subject: [PATCH 17/21] feat(2020-day-04): scan and validate passport records --- 2020/day-04/passports.js | 49 ++++++++++++++++++++++++++++++ 2020/day-04/passports.test.js | 52 ++++++++++++++++++++++++++++++++ package-lock.json | 56 +++++++++++++++++++++++------------ package.json | 3 ++ 4 files changed, 141 insertions(+), 19 deletions(-) create mode 100644 2020/day-04/passports.js create mode 100644 2020/day-04/passports.test.js diff --git a/2020/day-04/passports.js b/2020/day-04/passports.js new file mode 100644 index 0000000..fae4ae0 --- /dev/null +++ b/2020/day-04/passports.js @@ -0,0 +1,49 @@ +// Convert a passport scan into a useable object +const parseScan = (scan) => { + const passport = {} + scan.trim() + .split(/\s+/) + .forEach((field) => { + const parsed = field.split(':') + passport[parsed[0]] = parsed[1] + }) + return passport +} + +const getType = (passport) => { + if (passport.cid) { + return 'normal' + } + return 'polar' +} + +const requiredFields = [ + 'byr', + 'iyr', + 'eyr', + 'hgt', + 'hcl', + 'ecl', + 'pid', + 'cid' +] + +const validate = (passport) => { + const fieldsToCheck = JSON.parse(JSON.stringify(requiredFields)) // quick deep copy + // polar records don't have cid, but are otherwise valid + if (getType(passport) === 'polar') { + delete fieldsToCheck.splice([fieldsToCheck.indexOf('cid')], 1) + } + // Check for fields + fieldsToCheck.forEach((field) => { + if (!passport[field]) { + throw new Error(`Missing field ${field}`) + } + }) + return true +} + +module.exports = { + parseScan, + validate +} diff --git a/2020/day-04/passports.test.js b/2020/day-04/passports.test.js new file mode 100644 index 0000000..25c5676 --- /dev/null +++ b/2020/day-04/passports.test.js @@ -0,0 +1,52 @@ +/* eslint-env mocha */ +const { expect } = require('chai') +const { parseScan, validate } = require('./passports') + +const valid = [ + `ecl:gry pid:860033327 eyr:2020 hcl:#fffffd + byr:1937 iyr:2017 cid:147 hgt:183cm`, + `hcl:#ae17e1 iyr:2013 + eyr:2024 + ecl:brn pid:760753108 byr:1931 + hgt:179cm` +] + +const invalid = [ + `iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884 + hcl:#cfa07d byr:1929`, + `hcl:#cfa07d eyr:2025 pid:166559648 + iyr:2011 ecl:brn hgt:59in` +] + +describe('--- Day 4: Passport Processing ---', () => { + describe('Part 1', () => { + describe('parseScan()', () => { + it('parses an individual record into an addressable object', () => { + const res = parseScan(valid[0]) + expect(res).to.deep.equal({ + ecl: 'gry', + pid: '860033327', + eyr: '2020', + hcl: '#fffffd', + byr: '1937', + iyr: '2017', + cid: '147', + hgt: '183cm' + }) + }) + }) + describe('validate()', () => { + it('verifies all required fields in a passport', () => { + valid.forEach((scan, idx) => { + const passport = parseScan(scan) + // Valid when all required fields + expect(validate(passport)).to.equal(true) + }) + }) + it('errors on invalid passports', () => { + const passport = parseScan(invalid[0]) + expect(() => validate(passport)).to.throw('Missing field hgt') + }) + }) + }) +}) diff --git a/package-lock.json b/package-lock.json index bc09895..aebc1a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1729,6 +1729,29 @@ "split2": "^2.0.0", "through2": "^4.0.0", "trim-off-newlines": "^1.0.0" + }, + "dependencies": { + "split2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", + "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", + "dev": true, + "requires": { + "through2": "^2.0.2" + }, + "dependencies": { + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + } } }, "convert-source-map": { @@ -3770,8 +3793,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.5", @@ -10134,8 +10156,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", @@ -10719,22 +10740,21 @@ } }, "split2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", - "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", - "dev": true, + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "requires": { - "through2": "^2.0.2" + "readable-stream": "^3.0.0" }, "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } } } @@ -10938,7 +10958,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -11433,8 +11452,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "uuid": { "version": "3.4.0", diff --git a/package.json b/package.json index 50ecb97..6a0d501 100644 --- a/package.json +++ b/package.json @@ -37,5 +37,8 @@ "plop": "^2.7.4", "semantic-release": "^17.3.0", "standard": "^14.3.4" + }, + "dependencies": { + "split2": "^3.2.2" } } From 2a050ca31f31d003eee42f1cdf86c55c073fdb16 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sun, 6 Dec 2020 23:26:34 -0800 Subject: [PATCH 18/21] feat(2020-day-04): process a stream of passports to count valid ones Solution for part 1 --- 2020/day-04/input.txt | 1129 +++++++++++++++++++++++++++++++++++++++ 2020/day-04/solution.js | 82 ++- 2 files changed, 1185 insertions(+), 26 deletions(-) diff --git a/2020/day-04/input.txt b/2020/day-04/input.txt index e69de29..740962b 100644 --- a/2020/day-04/input.txt +++ b/2020/day-04/input.txt @@ -0,0 +1,1129 @@ +eyr:2029 byr:1931 hcl:z cid:128 +ecl:amb hgt:150cm iyr:2015 pid:148714704 + +byr:2013 hgt:70cm pid:76982670 ecl:#4f9a1c +hcl:9e724b eyr:1981 iyr:2027 + +pid:261384974 iyr:2015 +hgt:172cm eyr:2020 +byr:2001 hcl:#59c2d9 ecl:amb cid:163 + +eyr:2024 hcl:#b6652a +cid:340 +byr:1929 ecl:oth iyr:2014 pid:186640193 +hgt:193in + +iyr:2015 eyr:2024 hgt:184cm +ecl:blu hcl:#a97842 byr:1959 pid:932817398 + +iyr:1933 hcl:7c63aa cid:72 eyr:2028 +ecl:hzl +byr:2009 hgt:164cm pid:104496116 + +byr:1980 +hgt:181cm pid:192793676 hcl:8f6ae6 iyr:2021 eyr:1978 + +pid:#63f479 hgt:75cm +hcl:z iyr:1956 +byr:2024 ecl:#051344 + +byr:2014 pid:159cm +hgt:161cm +ecl:#b4eef2 +iyr:2027 eyr:1933 hcl:743b1a + +cid:79 hgt:172cm byr:1932 eyr:2020 pid:127319843 hcl:#6b5442 iyr:2017 ecl:brn + +ecl:gry eyr:2020 byr:1976 +pid:093137171 iyr:2012 hgt:178cm hcl:#733820 + +byr:1933 hcl:#733820 hgt:165cm eyr:2027 iyr:2018 ecl:oth pid:0952910465 + +iyr:2014 +byr:1965 pid:304542033 +eyr:2032 +ecl:brn hgt:153in cid:259 hcl:z + +byr:2004 ecl:amb iyr:2013 +hcl:#a97842 +hgt:68in +pid:248926471 eyr:1930 + +pid:048596900 iyr:2021 byr:2021 eyr:2021 cid:104 +hcl:c3c9e0 ecl:hzl +hgt:75cm + +pid:590195280 cid:159 byr:1951 hcl:#ceb3a1 ecl:brn iyr:2012 hgt:189cm eyr:2024 + +iyr:2015 pid:639647361 hcl:#b6652a +hgt:151cm byr:1957 cid:284 +ecl:gry +eyr:2026 + +ecl:blu hgt:175cm pid:462959720 hcl:#602927 iyr:2014 byr:1972 +eyr:2023 + +ecl:blu eyr:2023 hgt:175cm +pid:090406335 hcl:#b6652a iyr:2012 byr:1921 + +eyr:2025 hcl:#733820 +pid:775468504 ecl:hzl byr:1934 hgt:187cm iyr:2019 + +ecl:#b35d5b hgt:121 hcl:z iyr:2002 eyr:2034 +byr:2014 + +ecl:hzl byr:2026 hgt:77 iyr:1952 +hcl:#a97842 pid:#1461ed +eyr:1921 + +iyr:2019 +hgt:171in eyr:2040 pid:788162609 ecl:grn byr:2023 + +hcl:#efcc98 eyr:2039 hgt:158cm byr:2026 pid:216112069 + +ecl:blu hcl:#fffffd eyr:2020 pid:496018604 +byr:1982 hgt:168cm +cid:70 iyr:2016 + +eyr:2031 iyr:1958 +hcl:#c0946f hgt:181in ecl:#f88f2c pid:7896132641 + +byr:1933 cid:118 eyr:2037 hcl:#cfa07d iyr:2030 +ecl:#686f76 hgt:170 + +iyr:2010 +hgt:161cm ecl:grn byr:1958 hcl:#7d3b0c +pid:523557068 + +hcl:ba3af2 pid:157cm eyr:2037 cid:135 ecl:zzz hgt:153 byr:2030 + +ecl:grn byr:1967 cid:191 +iyr:2012 hcl:#866857 +pid:822899368 hgt:152cm eyr:2024 + +iyr:2015 +cid:343 hcl:#6b5442 pid:119981062 hgt:67in eyr:2027 +ecl:gry +byr:2001 + +pid:#c68245 ecl:blu hgt:107 hcl:74f3fb eyr:1996 iyr:1955 byr:2025 + +hgt:63cm eyr:1925 +iyr:2019 byr:2013 pid:#3ab227 ecl:#e33d1d hcl:#efcc98 + +byr:1941 eyr:2029 iyr:2011 hgt:159cm +hcl:#602927 +ecl:brn cid:245 pid:977877701 + +pid:575539099 +eyr:2031 byr:1987 ecl:oth hcl:#cfa07d +iyr:2017 +hgt:69cm + +pid:563180951 hgt:153cm ecl:amb iyr:2016 +byr:1951 hcl:#341e13 eyr:2029 +cid:277 + +hcl:#623a2f iyr:2011 hgt:171cm byr:1929 ecl:oth +eyr:2024 pid:959212059 + +byr:1943 ecl:#3925f3 hgt:68cm pid:155cm cid:127 eyr:2011 +hcl:2a53fd +iyr:2030 + +hgt:160in byr:2014 pid:7846412647 +hcl:2d18c8 +ecl:#8655df eyr:2034 iyr:2023 + +byr:1932 hgt:170cm cid:331 eyr:2020 pid:52551410 ecl:gry +iyr:2013 +hcl:#c6944c + +hcl:#888785 pid:177cm ecl:oth +hgt:160cm eyr:2021 byr:1957 +iyr:2013 + +iyr:2020 pid:6245137 eyr:2027 cid:111 hgt:181cm +byr:2024 ecl:gmt hcl:fe8828 + +pid:648300488 cid:230 hcl:#efcc98 +byr:1989 hgt:159cm +ecl:gry iyr:2015 +eyr:2030 + +iyr:1929 cid:144 hgt:168in pid:185cm +byr:2017 hcl:z eyr:1960 ecl:#d406d2 + +hcl:3a4933 +hgt:155cm +pid:337576945 byr:1925 iyr:2014 ecl:brn eyr:2026 + +pid:170cm cid:291 eyr:2017 iyr:2017 hgt:177cm hcl:z ecl:gmt + +pid:271148544 hgt:163cm +byr:1926 hcl:#fffffd iyr:2013 +eyr:2022 + +hgt:64in iyr:2030 ecl:#15c6b5 eyr:2028 byr:2025 +pid:3426144 + +eyr:1923 byr:1943 hcl:#64d609 iyr:2017 pid:154cm hgt:160cm ecl:brn + +hcl:#602927 hgt:170cm ecl:utc iyr:1954 pid:370180054 +byr:1925 cid:162 +eyr:1983 + +hcl:#888785 byr:1932 hgt:163cm +eyr:2026 +ecl:grn pid:799844918 + +eyr:2029 +ecl:blu cid:231 hgt:157cm +pid:609233861 +hcl:#462640 +byr:1940 iyr:2012 + +iyr:2025 +byr:2004 pid:#e92a77 +eyr:2014 cid:78 +ecl:zzz hgt:187in hcl:76be6e + +eyr:2027 iyr:2012 ecl:brn byr:1955 pid:128923308 +cid:313 hgt:156cm hcl:#623a2f + +hcl:#ceb3a1 +hgt:178cm byr:1984 +pid:121442385 eyr:2036 iyr:2014 ecl:hzl + +eyr:2038 ecl:#c6149f iyr:1983 +cid:304 hgt:193 byr:2019 +hcl:z pid:5871630079 + +iyr:2028 eyr:2002 +hgt:146 +hcl:#623a2f +pid:390145814 +byr:1937 + +pid:923652966 ecl:amb +eyr:2027 hgt:174cm byr:1932 iyr:2014 +hcl:#fffffd + +iyr:2026 cid:202 byr:1995 hcl:69c01a +hgt:164cm eyr:2020 ecl:hzl + +hgt:156cm +byr:2004 +pid:537532371 +hcl:z iyr:1988 +eyr:2024 +ecl:utc + +iyr:2018 byr:1924 hcl:#602927 cid:132 pid:947815343 eyr:2030 ecl:grn + +byr:1978 hcl:#c0946f iyr:2012 hgt:67cm +eyr:2032 pid:929470763 ecl:amb + +eyr:2028 +pid:545502229 ecl:gry +hcl:#866857 hgt:182cm +byr:1964 iyr:2016 + +hcl:z cid:82 hgt:108 byr:2010 pid:#1650b3 eyr:2020 iyr:2017 ecl:hzl + +iyr:2018 +hgt:61cm +ecl:lzr byr:1980 hcl:1d4bc2 cid:306 +pid:763925614 eyr:2006 + +byr:2021 eyr:2029 +pid:610596568 +ecl:oth +hcl:#7d3b0c +iyr:2010 cid:83 hgt:156cm + +cid:181 ecl:hzl +hcl:#8d79d2 +hgt:192cm +byr:1958 iyr:2014 eyr:2026 pid:118367138 + +byr:1978 +eyr:2020 +iyr:2025 hgt:176cm +ecl:grn hcl:faedc2 + +hgt:156cm eyr:1989 pid:#7acc45 cid:235 hcl:1332ba +ecl:#2b7525 iyr:1950 byr:1943 + +pid:147647267 hcl:#341e13 +ecl:hzl +iyr:2019 +byr:1975 +hgt:153cm eyr:2020 + +iyr:2026 hgt:170cm ecl:oth +byr:2017 pid:047129729 +eyr:2024 hcl:#733820 + +hcl:#fffffd byr:1960 ecl:gry eyr:2023 +iyr:2013 hgt:186cm pid:145757697 + +hgt:64in +ecl:amb +byr:1930 pid:808797855 iyr:2019 +hcl:#b6652a eyr:2022 + +eyr:2030 +hcl:z iyr:2013 hgt:165cm ecl:#5ba775 +pid:168306092 byr:1988 + +eyr:2026 ecl:gry iyr:2020 hcl:#b6652a hgt:177cm +byr:1991 pid:780666689 + +iyr:2020 +pid:#d08e64 eyr:2010 hcl:411b04 cid:140 hgt:76cm ecl:grn byr:2005 + +iyr:1945 +pid:973836167 ecl:zzz +hcl:z hgt:181in byr:2008 eyr:1993 + +cid:58 eyr:2024 hgt:159cm byr:1977 ecl:hzl pid:402427328 +hcl:#888785 +iyr:2012 + +pid:533381616 byr:2027 +eyr:2040 hgt:60cm iyr:2023 hcl:z +ecl:gmt + +pid:229044973 cid:149 hgt:178in eyr:2029 +byr:2006 ecl:dne iyr:2012 +hcl:bf4bc2 + +hgt:161cm byr:1973 ecl:oth iyr:2015 hcl:#341e13 pid:658452720 +eyr:2024 + +hcl:#efcc98 hgt:156cm +byr:1931 iyr:1997 pid:0548175409 ecl:utc + +pid:575623915 iyr:2017 eyr:2023 hcl:#733820 byr:1938 +ecl:blu +hgt:185cm + +hcl:#55ebaa +hgt:157cm ecl:blu byr:1945 +pid:946614649 +eyr:2020 iyr:2012 + +hgt:158cm hcl:#b80425 iyr:2017 eyr:2025 ecl:gry +byr:1944 pid:838975683 + +hcl:#41731c iyr:2020 byr:1971 ecl:oth +hgt:186cm +eyr:2030 pid:495358045 + +pid:3884291521 +eyr:2037 hgt:74cm byr:2003 ecl:hzl iyr:2022 hcl:#888785 cid:124 + +hgt:175cm cid:340 byr:1921 +pid:183491348 +iyr:2017 ecl:brn hcl:#602927 eyr:2028 + +hcl:#cfa07d +hgt:161cm byr:2006 +eyr:2024 +pid:109854634 +ecl:xry iyr:2024 + +ecl:#ec6311 hcl:z iyr:2015 +pid:#783693 +eyr:1932 +cid:271 +hgt:82 + +ecl:grn +hgt:164cm hcl:#efcc98 eyr:2020 pid:824236769 +byr:1952 iyr:2014 + +eyr:1964 pid:85558869 byr:2017 hcl:c81d94 +iyr:2028 +hgt:63cm +ecl:#c00640 cid:115 + +byr:2010 +pid:431600716 +hcl:z hgt:112 ecl:#3057e9 eyr:2027 iyr:2017 cid:91 + +byr:2026 +eyr:2037 +pid:3800489571 ecl:grn +cid:91 hcl:94b4d1 hgt:59cm + +cid:199 byr:2030 +iyr:2021 +hcl:c55653 +hgt:168cm +pid:160cm + +hgt:68cm +byr:2025 iyr:2023 eyr:1983 +hcl:0004d4 ecl:#19fca6 pid:89901951 + +hgt:170cm byr:2012 +eyr:1981 hcl:c95b58 +pid:#d28b3f cid:302 iyr:1953 ecl:#151ea4 + +hcl:#6b5442 eyr:2024 hgt:161cm +cid:210 ecl:#793ac0 +pid:480283173 +iyr:2019 byr:1967 + +cid:82 ecl:amb iyr:2017 eyr:2023 byr:1980 hgt:59in hcl:#888785 pid:323524654 + +hcl:#341e13 hgt:154cm +iyr:2015 eyr:2023 +byr:1953 ecl:blu pid:872964523 + +iyr:2019 +byr:1945 hcl:#efcc98 +hgt:155in +ecl:#1608c7 eyr:2030 pid:406045604 + +ecl:lzr byr:2015 iyr:1938 +eyr:2026 hcl:z +pid:542894703 hgt:185 + +eyr:2021 hcl:#cfa07d ecl:hzl hgt:82 +iyr:2018 byr:1932 +pid:661993261 + +ecl:brn hcl:#602927 +hgt:193cm pid:572216250 +byr:1929 eyr:2020 iyr:2010 cid:206 + +ecl:amb +eyr:2025 +pid:932260335 byr:1978 iyr:2012 +hcl:#cfa07d +cid:260 hgt:67in + +pid:635410614 +byr:1948 hgt:156cm hcl:#071bc0 eyr:2026 +ecl:grn +cid:275 +iyr:2014 + +hcl:#8a4888 byr:1986 +iyr:2010 ecl:amb cid:113 +pid:974757414 hgt:174cm +eyr:2024 + +byr:1934 ecl:amb iyr:2016 +pid:280206549 hgt:176cm +eyr:2020 hcl:#fffffd + +pid:544634927 +eyr:2021 hgt:188cm byr:1947 iyr:2020 +hcl:#008716 ecl:oth +cid:97 + +eyr:2026 pid:863010622 +byr:1978 hcl:#b6652a hgt:157cm cid:323 iyr:2020 ecl:blu + +cid:105 +byr:1926 +hcl:#6b5442 pid:049198636 eyr:2026 hgt:75in +iyr:2018 ecl:blu + +eyr:2038 hgt:76cm byr:2020 pid:9036865757 iyr:2025 +ecl:#a2c975 +hcl:z +cid:340 + +pid:425619875 cid:263 byr:1935 +eyr:2028 hgt:192cm iyr:2010 hcl:#a6ddfc ecl:hzl + +cid:107 hgt:189cm +hcl:#733820 ecl:blu +eyr:2028 iyr:2020 pid:814895947 + +cid:96 hgt:74in +hcl:z +pid:170cm ecl:#0240fd byr:2004 iyr:2013 eyr:1936 + +ecl:blu +eyr:2027 hcl:#341e13 +iyr:2020 +cid:94 +hgt:174cm + +iyr:2013 ecl:amb +eyr:2030 hcl:#b6652a +byr:1964 +pid:329942894 + +byr:1995 ecl:hzl eyr:2030 +hgt:177cm hcl:#341e13 +cid:64 + +eyr:2027 pid:708191313 +ecl:#390609 byr:2022 iyr:2010 cid:292 hgt:129 +hcl:#733820 + +hcl:#733820 ecl:hzl eyr:2030 +iyr:2011 +hgt:156cm +byr:2002 pid:932464949 + +iyr:1941 +byr:2027 ecl:xry eyr:1949 pid:82479270 +hgt:175 hcl:z +cid:157 + +byr:1927 pid:708954312 eyr:2028 ecl:oth hgt:167cm hcl:#602927 iyr:2011 + +cid:125 eyr:2034 iyr:2030 +hgt:116 byr:2030 +hcl:f773ce pid:#d24ed1 ecl:lzr + +hcl:#efcc98 byr:1947 pid:423105162 ecl:brn iyr:2019 hgt:154cm +eyr:2026 +cid:174 + +iyr:2017 +ecl:gry +hcl:#341e13 +pid:314487906 eyr:2038 hgt:171cm byr:2014 + +pid:630479640 ecl:brn hgt:163cm +iyr:2013 eyr:2028 byr:1998 hcl:#866857 + +iyr:2013 hcl:z byr:2016 +ecl:#43d879 pid:996281170 +cid:200 hgt:153 eyr:2030 + +byr:2023 +pid:081908248 iyr:2020 +eyr:2035 +hgt:175in ecl:grt hcl:30ab42 + +iyr:2018 byr:1995 eyr:2029 ecl:grn pid:882123182 hgt:62cm hcl:#fffffd + +byr:1978 hcl:z +iyr:1923 ecl:blu eyr:2037 pid:#1f3467 hgt:186cm + +cid:264 ecl:#ab07c5 iyr:1927 hcl:2d6f9c +hgt:74cm byr:2008 pid:874594495 eyr:2035 + +ecl:lzr hgt:69cm +hcl:76854c cid:336 pid:7830555583 +iyr:1920 +byr:2021 eyr:2038 + +hgt:160cm byr:2029 ecl:#7f9d1b hcl:z iyr:1975 +pid:652466273 +eyr:2031 + +ecl:oth +eyr:2027 iyr:2019 pid:544347482 +byr:1988 hgt:182cm hcl:#cfa07d + +hgt:176cm iyr:2016 hcl:ec1dc3 +pid:521230755 byr:2030 ecl:amb eyr:2025 + +pid:005216805 byr:1951 +ecl:hzl hcl:#efcc98 eyr:2022 +iyr:2016 +hgt:154cm + +byr:1943 hcl:#866857 +eyr:1984 hgt:64cm +pid:3105984 iyr:1997 +ecl:lzr + +eyr:2024 +byr:1931 pid:929699878 hgt:169cm cid:81 hcl:#efcc98 + +iyr:2011 pid:558972589 +hgt:163cm cid:155 eyr:2025 byr:1952 ecl:oth +hcl:#c0946f + +pid:787560595 eyr:2036 +hcl:#888785 byr:1999 iyr:1971 ecl:blu + +hgt:165in pid:032310066 +eyr:1926 byr:1954 ecl:brn hcl:41964f iyr:2023 + +hcl:#733820 +pid:563740385 +hgt:184cm +iyr:1959 +ecl:gmt cid:242 byr:1999 + +pid:4949046383 byr:2011 hcl:fcf63b +ecl:hzl +hgt:174in +iyr:2023 eyr:1939 + +cid:331 +ecl:grt hcl:z eyr:2003 hgt:172in byr:2012 iyr:1954 pid:#9f4663 + +cid:223 byr:1939 eyr:2025 +ecl:oth hgt:161cm iyr:2015 pid:214576789 hcl:#866857 + +ecl:oth pid:912009529 byr:1968 hgt:161cm +hcl:#ceb3a1 eyr:2023 iyr:2017 + +pid:858541281 hgt:150cm eyr:2021 +iyr:2013 ecl:gry +hcl:#fffffd byr:1959 + +ecl:#0024e0 byr:2006 cid:107 +iyr:2015 hcl:684416 hgt:94 pid:152cm eyr:2031 + +byr:1987 hcl:z +ecl:gry pid:#246fe1 hgt:65cm eyr:1992 iyr:2020 + +pid:426999585 +ecl:hzl byr:1949 hcl:#888785 hgt:191cm +iyr:2020 eyr:2020 + +byr:1951 hcl:#623a2f +cid:308 ecl:hzl +hgt:174cm pid:226138254 +eyr:2028 +iyr:2018 + +ecl:brn hgt:62in +eyr:2020 hcl:#ceb3a1 pid:650916481 +byr:1940 +iyr:2018 + +hcl:#efcc98 ecl:brn +byr:1940 eyr:2024 pid:#68d3ab +hgt:177cm cid:83 +iyr:2017 + +pid:9704738756 hcl:#fffffd eyr:1925 +iyr:2019 byr:1929 ecl:blu hgt:191cm + +ecl:brn hgt:151cm hcl:#c0946f iyr:2018 pid:602505609 eyr:2020 +byr:1974 + +hgt:178cm +eyr:2023 byr:1922 +iyr:2013 +hcl:#fffffd pid:205291054 ecl:blu + +byr:1985 +iyr:2016 hcl:#ceb3a1 hgt:161cm eyr:2030 ecl:amb +pid:871809978 + +iyr:2027 ecl:#d9c9cb hgt:110 +eyr:2034 +hcl:99d4ee pid:13355969 cid:168 + +ecl:utc byr:2019 +iyr:2016 hgt:173in cid:266 +hcl:z eyr:2033 +pid:1835189643 + +pid:364874100 ecl:amb hcl:#6b5442 hgt:184cm +iyr:2017 eyr:2026 byr:1920 cid:127 + +ecl:dne eyr:2020 +byr:2018 cid:262 +iyr:2010 hgt:60cm +pid:95409983 hcl:z + +eyr:2026 +pid:135963889 iyr:2018 hcl:#ceb3a1 +ecl:amb + +hcl:#341e13 eyr:2028 iyr:2014 byr:1978 +cid:309 +pid:503628987 +ecl:oth hgt:159cm + +hcl:#a97842 +pid:171194014 hgt:193cm eyr:2023 +byr:1945 ecl:grt +iyr:2019 + +eyr:1967 cid:135 hcl:z +ecl:gmt +iyr:2024 pid:#a87744 +byr:2023 hgt:168cm + +pid:169cm +cid:337 ecl:hzl hcl:#888785 byr:1927 hgt:153cm +iyr:2022 eyr:2020 + +byr:1963 hcl:#fffffd eyr:2021 +hgt:62in pid:702188504 iyr:2013 +ecl:hzl + +iyr:2024 ecl:amb hcl:#ceb3a1 +eyr:2017 pid:49752568 hgt:179cm byr:1938 + +byr:2006 +ecl:#08021a +eyr:2022 pid:520309937 +hgt:61in hcl:#ceb3a1 +iyr:2013 + +hgt:150cm hcl:#733820 byr:1971 ecl:zzz cid:347 +iyr:2020 eyr:2020 pid:6028818045 + +byr:2005 hgt:69cm +ecl:lzr hcl:z iyr:2009 eyr:2038 pid:79626157 + +iyr:2020 byr:2015 pid:882923693 hcl:#888785 eyr:2030 +ecl:xry hgt:65in + +hcl:z hgt:187cm pid:4397913655 iyr:1973 eyr:1925 +ecl:#93ae1a + +hgt:169cm +iyr:2019 eyr:2023 pid:678937529 +ecl:blu byr:1998 hcl:#fffffd + +cid:87 hcl:#efcc98 +ecl:#e56390 +iyr:2013 hgt:191in +eyr:2027 pid:923358773 byr:1960 + +hgt:190cm byr:1939 +cid:55 eyr:2026 ecl:blu hcl:#623a2f pid:363917612 +iyr:2012 + +pid:177cm hgt:165cm cid:276 eyr:2002 byr:2010 hcl:#7bea4c iyr:2017 +ecl:grt + +byr:2023 eyr:2031 +iyr:1987 hgt:172 hcl:z +pid:4973557135 ecl:#7517e2 + +eyr:2036 iyr:1989 ecl:#ef5492 hgt:188in pid:#b50065 +hcl:92e9ee byr:2015 + +pid:873654822 iyr:2016 cid:310 +hgt:76in +eyr:2029 hcl:#888785 byr:1958 +ecl:brn + +iyr:2013 ecl:amb byr:2024 +hgt:166cm +cid:221 eyr:2040 pid:358648642 hcl:#733820 + +hgt:181cm cid:295 ecl:blu eyr:2027 +iyr:2016 +byr:1932 +hcl:#2502ba +pid:177357899 + +pid:154588649 eyr:2028 +byr:1945 iyr:2020 +ecl:amb cid:220 +hgt:189cm hcl:#a97842 + +iyr:2011 +eyr:2030 cid:143 byr:1998 pid:403108989 +ecl:oth hcl:#6b5442 +hgt:151cm + +pid:071042426 cid:217 iyr:2017 ecl:grn byr:1989 eyr:2026 hgt:193cm hcl:#7d3b0c + +eyr:2025 +iyr:2025 pid:3942412883 hcl:#cfa07d cid:237 ecl:utc hgt:182 + +iyr:2012 eyr:1982 byr:2029 pid:8573047090 +hgt:159in ecl:#1e0124 hcl:#b6652a + +hcl:53c64f ecl:gmt iyr:1984 byr:2029 +hgt:59cm +pid:#106076 eyr:2031 + +hcl:#733820 iyr:2019 +eyr:2031 +pid:706963298 +hgt:134 +byr:2004 + +byr:2012 cid:161 +eyr:2039 ecl:gry hgt:61cm iyr:1949 pid:870113802 hcl:z + +byr:1961 eyr:2023 pid:353075198 iyr:2020 hcl:#888785 ecl:oth +hgt:163cm + +byr:2001 iyr:2015 +hgt:159cm hcl:#623a2f ecl:#3303fc +pid:86352609 eyr:2030 + +pid:392475721 ecl:brn byr:1927 iyr:2014 eyr:2024 hcl:#fffffd + +hgt:160cm eyr:2022 byr:1979 iyr:2010 +pid:974489456 +hcl:#efcc98 + +ecl:grn eyr:2024 +hgt:166cm byr:1961 +pid:221051556 +hcl:#6b5442 +iyr:2028 + +iyr:2010 cid:156 +byr:2005 hgt:155cm ecl:amb eyr:1988 +hcl:#866857 +pid:169cm + +eyr:2038 byr:1991 pid:#9b82ce +iyr:2027 hcl:z +cid:278 hgt:59cm ecl:#179d81 + +ecl:blu hgt:151cm +iyr:2013 +cid:117 pid:129843687 hcl:#c429e7 byr:1961 +eyr:2022 + +hcl:#602927 byr:1996 pid:507775673 eyr:2020 hgt:153cm ecl:oth +cid:251 iyr:2010 + +hgt:170cm ecl:oth iyr:2010 eyr:2025 hcl:#602927 byr:1983 pid:113809908 + +hcl:#c0946f pid:172142380 +iyr:2017 byr:1926 +hgt:190cm eyr:2028 +ecl:brn + +pid:812443511 hcl:#6b5442 eyr:2021 ecl:amb +cid:60 iyr:2017 hgt:157cm byr:1926 + +hgt:177cm +ecl:gry eyr:2022 hcl:#888785 pid:570572334 byr:1943 iyr:2017 + +pid:#967cbc hcl:z byr:2020 ecl:oth eyr:2035 iyr:2015 +cid:99 hgt:65cm + +iyr:2019 pid:285935311 hcl:#4c1ee4 byr:1954 eyr:2028 hgt:157cm + +ecl:xry eyr:1939 +pid:192cm +hgt:114 +hcl:b97555 byr:2004 iyr:1970 + +ecl:grn byr:2021 iyr:2030 +hcl:z pid:305489303 hgt:61cm eyr:2020 + +eyr:2036 hgt:179cm +pid:#8be5f5 byr:1981 +hcl:#cb5848 iyr:2015 + +iyr:2011 ecl:oth hgt:176cm cid:344 pid:539941547 hcl:#efcc98 + +eyr:1987 ecl:amb +byr:2029 pid:046017350 +cid:182 iyr:2011 hcl:z hgt:191cm + +iyr:2019 byr:1948 eyr:2020 ecl:hzl hgt:176cm hcl:#733820 pid:235101182 + +ecl:hzl +eyr:2029 pid:262843012 hgt:76in hcl:#efcc98 iyr:2015 byr:1931 + +iyr:2011 ecl:blu hgt:184cm +byr:1945 +hcl:#c0946f pid:105042852 + +iyr:2010 +pid:485638522 hcl:949a37 eyr:2030 +hgt:193cm +ecl:gry byr:2021 + +pid:565896801 eyr:2029 hcl:#fffffd ecl:amb iyr:2016 byr:1977 +hgt:170cm + +byr:1987 +hcl:#c0946f pid:931311386 +iyr:2010 eyr:2022 + +eyr:2030 +hgt:177cm hcl:#a97842 byr:1978 +ecl:hzl pid:358177000 +iyr:2014 + +iyr:2025 +pid:3639383157 cid:82 hcl:f2aec0 hgt:179cm +eyr:1944 byr:1969 +ecl:#e167d3 + +hgt:107 ecl:gmt iyr:2030 hcl:#866857 byr:2026 eyr:1990 pid:#87773e + +cid:220 hcl:z iyr:1921 hgt:65cm byr:1998 ecl:#34397f eyr:2035 + +hcl:44e552 pid:#6f341e ecl:#59aeb1 +eyr:1926 hgt:187 iyr:1988 +byr:1991 + +hcl:z hgt:70cm pid:653386115 iyr:1964 byr:2026 cid:103 +ecl:#b81c45 eyr:2034 + +hcl:#623a2f cid:307 pid:204266921 hgt:172cm +iyr:2012 +ecl:hzl +eyr:2021 +byr:1984 + +hgt:192cm +byr:1930 pid:39349843 hcl:#866857 iyr:2013 cid:130 ecl:blu eyr:1962 + +cid:97 eyr:2036 pid:#279c0b ecl:dne hgt:186in iyr:1973 hcl:691266 + +byr:2026 hgt:185cm hcl:z ecl:grt pid:#562f7a eyr:1986 iyr:2029 + +ecl:brn +hcl:#b6652a eyr:2028 +pid:570023672 +byr:1988 hgt:162cm iyr:2015 + +hgt:180in ecl:zzz hcl:5b1477 byr:2024 +eyr:2028 +pid:#b03174 + +pid:157cm eyr:1989 hgt:188cm +iyr:2015 +hcl:3362a9 ecl:gry byr:2027 + +pid:111584950 +byr:1941 ecl:grn iyr:2013 hgt:179cm hcl:#866857 +eyr:2024 + +ecl:#7f4baa +iyr:2015 hcl:de1367 +eyr:2024 byr:1959 +pid:#cf4e78 hgt:60cm + +byr:2024 eyr:1953 pid:21579220 +hgt:179 +cid:94 +hcl:#a97842 +iyr:1977 ecl:xry + +hgt:179cm eyr:2020 +ecl:hzl hcl:#efcc98 +pid:905622096 byr:1929 + +ecl:oth +byr:2001 eyr:2008 iyr:2020 +hcl:#ceb3a1 pid:244298637 hgt:160cm + +eyr:2030 +byr:1972 hcl:#341e13 +ecl:grn iyr:2014 pid:274475554 hgt:71in + +byr:1938 hcl:z iyr:1956 pid:153cm hgt:62cm ecl:grt +eyr:2036 + +hgt:177cm cid:276 iyr:1921 hcl:19aa96 pid:843799864 eyr:2033 +ecl:#812d68 + +pid:686496844 +ecl:brn hcl:#733820 +byr:1948 iyr:2010 eyr:2020 +hgt:164cm + +pid:39436322 ecl:blu hcl:25b3d4 hgt:185in +iyr:2019 byr:1959 eyr:2022 + +pid:119603708 hcl:#866857 byr:1983 hgt:157cm iyr:1978 ecl:hzl eyr:1945 + +cid:331 hcl:z iyr:2017 +pid:255988517 +byr:2015 +eyr:2020 ecl:amb +hgt:171 + +hgt:180cm iyr:2013 ecl:brn +hcl:#602927 byr:1943 +pid:898265221 eyr:2025 + +eyr:2024 +hgt:163cm +pid:892793767 byr:1971 ecl:oth iyr:2013 cid:119 hcl:#02f6b3 + +byr:1920 cid:221 +pid:#7515a7 hgt:160in +eyr:1921 iyr:1983 hcl:z + +byr:2029 hcl:z hgt:75cm eyr:1975 pid:184cm iyr:1992 ecl:dne + +iyr:1990 +hgt:174in eyr:1961 ecl:brn +hcl:#a3313e byr:2029 + +hgt:191cm eyr:2026 iyr:2019 ecl:brn +byr:1930 hcl:#7d3b0c cid:174 + +ecl:amb iyr:2015 hgt:163cm +pid:664966673 hcl:#602927 eyr:2026 cid:229 byr:1941 + +pid:3123244013 eyr:2037 iyr:2022 hcl:103dfa +hgt:156cm byr:2027 ecl:gmt cid:195 + +cid:151 ecl:blu pid:693382940 +iyr:2011 byr:1954 +hgt:170cm eyr:2030 hcl:#866857 + +hcl:#341e13 eyr:2023 byr:1948 iyr:2010 pid:607929427 +ecl:oth hgt:160cm + +hcl:#c0946f +ecl:brn +hgt:189cm +cid:116 iyr:2013 pid:277606931 +byr:1975 + +eyr:2027 +cid:206 ecl:gry iyr:2010 hcl:#866857 byr:1997 hgt:190cm pid:687577894 + +eyr:2029 iyr:2015 pid:681485527 +byr:1925 hgt:152cm +ecl:amb hcl:#341e13 + +eyr:2030 +hcl:#c396d9 +hgt:159cm pid:686268817 +ecl:brn byr:1983 +iyr:2017 + +eyr:2038 byr:2012 +cid:303 +iyr:1941 hcl:z ecl:utc pid:203595168 +hgt:71cm + +pid:863355278 hcl:#888785 +iyr:2018 +byr:1953 eyr:2022 hgt:167cm +ecl:amb + +pid:141244310 eyr:2025 hcl:#733820 ecl:amb hgt:154cm cid:61 iyr:2017 +byr:1929 + +pid:361065637 +hcl:#623a2f byr:1964 iyr:2015 eyr:2027 ecl:gry hgt:67in + +cid:117 ecl:brn iyr:2025 byr:1982 +hcl:#ceb3a1 hgt:185cm +pid:34652522 + +cid:275 ecl:#7a4722 eyr:2001 byr:2018 iyr:1995 +hgt:105 +pid:95250112 hcl:z + +iyr:2017 ecl:amb hgt:152cm hcl:#733820 cid:57 eyr:2020 pid:701621326 +byr:1944 + +hcl:#18171d +ecl:brn iyr:2015 hgt:175cm eyr:2028 pid:311636591 cid:113 +byr:1979 + +ecl:grn +hgt:185cm +pid:920998407 iyr:2016 byr:1930 eyr:2029 hcl:#7d3b0c + +iyr:2021 eyr:1931 +hcl:z byr:2010 +hgt:177in +pid:#cfb659 ecl:zzz + +cid:171 hcl:#888785 iyr:2010 byr:1970 ecl:hzl +pid:141430645 hgt:160cm +eyr:2026 + +hgt:172cm ecl:gry +pid:428207256 cid:237 hcl:#733820 iyr:2012 +eyr:2027 byr:1951 + +hgt:70cm cid:76 ecl:#c544c3 byr:2019 +pid:6133497812 +hcl:#efcc98 +eyr:2037 iyr:2015 + +hgt:176in pid:582383714 byr:1980 ecl:amb hcl:08097e iyr:2020 eyr:2021 + +ecl:oth +eyr:2024 +hgt:176cm byr:1923 +iyr:2014 pid:737058734 +hcl:#b6652a cid:203 + +ecl:amb +eyr:2029 +hgt:186cm +pid:440986981 iyr:2010 hcl:#cfa07d +byr:1967 + +pid:8729818647 hcl:z +ecl:#ae70eb cid:168 hgt:161cm iyr:2030 +eyr:2020 byr:2022 + +hcl:#43a092 hgt:165cm byr:1961 +pid:026098019 +iyr:2019 eyr:2020 ecl:amb + +cid:154 hgt:192cm +eyr:2016 iyr:2030 +ecl:brn pid:#8e0762 byr:2020 + +hgt:175cm ecl:brn byr:1944 +pid:553456151 iyr:2016 eyr:2027 hcl:#085f41 + +ecl:gry +byr:1975 eyr:2025 cid:122 pid:111078821 +hcl:#b6652a iyr:2015 +hgt:151cm + +hgt:159cm pid:946458516 eyr:2020 hcl:#a97842 byr:1972 +iyr:2016 cid:88 ecl:oth + +eyr:2023 +cid:156 +byr:1999 +hgt:186cm hcl:#fffffd pid:499141155 +ecl:grn + +hcl:#888785 hgt:165cm pid:864544116 +ecl:gry byr:1937 +iyr:2020 eyr:2026 + +hgt:155cm +iyr:2018 ecl:blu +hcl:#a97842 +byr:1994 eyr:2024 + +eyr:2021 iyr:2019 hgt:175cm cid:127 byr:1982 hcl:#888785 ecl:amb + +eyr:2022 iyr:2011 ecl:blu +pid:202081532 hcl:z hgt:177in byr:1923 + +iyr:2017 cid:213 hcl:#fffffd +ecl:hzl +hgt:193cm pid:564823661 byr:1966 eyr:2030 + +hcl:#623a2f iyr:2014 hgt:177cm byr:1950 ecl:amb +cid:290 eyr:2025 pid:669369557 + +hgt:67cm +eyr:2028 ecl:brn +hcl:411b18 pid:222472243 + +byr:1981 ecl:gry hcl:#b6652a eyr:2033 iyr:1943 pid:832989613 hgt:167cm + +byr:1970 +cid:172 hcl:#64fbcb eyr:2007 +ecl:hzl pid:982450142 +hgt:61cm iyr:2019 + +eyr:2025 +hgt:161cm iyr:1962 +pid:394421140 +ecl:gry +cid:209 hcl:#efcc98 byr:2001 \ No newline at end of file diff --git a/2020/day-04/solution.js b/2020/day-04/solution.js index 779f7ea..ac08905 100644 --- a/2020/day-04/solution.js +++ b/2020/day-04/solution.js @@ -1,35 +1,65 @@ const fs = require('fs') const path = require('path') +const split2 = require('split2') const filePath = path.join(__dirname, 'input.txt') -const { inputToArray } = require('../../2018/inputParser') +const { parseScan, validate } = require('./passports') -fs.readFile(filePath, { encoding: 'utf8' }, (err, initData) => { - if (err) throw err +const answers = [] - initData = inputToArray(initData.trim()) +const part1 = () => { + let recordBuffer = '' + let validCount = 0 + let invalidCount = 0 + let totalCount = 0 - const resetInput = () => { - // Deep copy to ensure we aren't mutating the original data - return JSON.parse(JSON.stringify(initData)) + const processBuffer = () => { + // Handle the record in the buffer + const passport = parseScan(recordBuffer) + try { + if (validate(passport)) { + validCount++ + } + } catch (e) { + invalidCount++ + console.warn(e.message) + console.debug('Invalid passport', passport) + } + totalCount++ } - const part1 = () => { - const data = resetInput() - console.debug(data) - return 'No answer yet' - } + fs.createReadStream(filePath) + .pipe(split2()) + .on('data', (data) => { + // Emmpty line indicates record separator + if (data.trim() === '') { + processBuffer() + // flush buffer + recordBuffer = '' + return + } + // Add the line to the buffer + recordBuffer += data.trim() + '\n' + }) + .on('end', () => { + // get the final record from the buffer + processBuffer() + console.info('Total passports found:', totalCount) + console.info('Invalid passports', invalidCount) + answers.push(validCount) + answers.push(part2()) - const part2 = () => { - const data = resetInput() - console.debug(data) - return 'No answer yet' - } - const answers = [] - answers.push(part1()) - answers.push(part2()) - - answers.forEach((ans, idx) => { - console.info(`-- Part ${idx + 1} --`) - console.info(`Answer: ${ans}`) - }) -}) + answers.forEach((ans, idx) => { + console.info(`-- Part ${idx + 1} --`) + console.info(`Answer: ${ans}`) + }) + }) + + console.debug('Invalid passports:', invalidCount) + return validCount +} + +const part2 = () => { + return 'No answer yet' +} + +part1() From c139381f1a606a16608e41f3c3ddd2fb0053d558 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Mon, 7 Dec 2020 00:02:36 -0800 Subject: [PATCH 19/21] fix(2020-day-04): suppress excess noise in run log --- 2020/day-04/solution.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/2020/day-04/solution.js b/2020/day-04/solution.js index ac08905..ab0c7d0 100644 --- a/2020/day-04/solution.js +++ b/2020/day-04/solution.js @@ -1,3 +1,4 @@ +const DEBUG = false; const fs = require('fs') const path = require('path') const split2 = require('split2') @@ -21,8 +22,10 @@ const part1 = () => { } } catch (e) { invalidCount++ - console.warn(e.message) - console.debug('Invalid passport', passport) + if (DEBUG) { + console.warn(e.message) + console.debug('Invalid passport', passport) + } } totalCount++ } From cfe17254bac8ddb7ca30d6f623943d1cd7e0a46e Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Mon, 7 Dec 2020 00:15:49 -0800 Subject: [PATCH 20/21] feat(2020-day-04): optional field-level validation rules Skip field-level validation with validate(passport, false) --- 2020/day-04/passports.js | 84 ++++++++++++++++++++++++++++++++++- 2020/day-04/passports.test.js | 43 ++++++++++++++++-- 2020/day-04/solution.js | 4 +- 3 files changed, 125 insertions(+), 6 deletions(-) diff --git a/2020/day-04/passports.js b/2020/day-04/passports.js index fae4ae0..44ff755 100644 --- a/2020/day-04/passports.js +++ b/2020/day-04/passports.js @@ -28,7 +28,76 @@ const requiredFields = [ 'cid' ] -const validate = (passport) => { +const rules = { + byr: (byr) => { + // byr (Birth Year) - four digits; at least 1920 and at most 2002 + return ( + String(byr).length === 4 && + Number(byr) >= 1920 && + Number(byr) <= 2002 + ) + }, + iyr: (iyr) => { + // iyr (Issue Year) - four digits; at least 2010 and at most 2020. + return ( + String(iyr).length === 4 && + Number(iyr) >= 2010 && + Number(iyr) <= 2020 + ) + }, + eyr: (eyr) => { + // eyr (Expiration Year) - four digits; at least 2020 and at most 2030. + return ( + String(eyr).length === 4 && + Number(eyr) >= 2020 && + Number(eyr) <= 2030 + ) + }, + hgt: (hgt) => { + // hgt (Height) - a number followed by either cm or in: + // If cm, the number must be at least 150 and at most 193. + // If in, the number must be at least 59 and at most 76. + const unit = hgt.slice(hgt.length - 2) + const value = hgt.slice(0, hgt.length - 2) + return ( + ( + unit === 'cm' && + value >= 150 && + value <= 193 + ) || ( + unit === 'in' && + value >= 59 && + value <= 76 + ) + ) + }, + hcl: (hcl) => { + // hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f. + const regexp = /^#[0-9a-fA-F]+$/ // hex color + return ( + regexp.test(hcl) && + hcl.length === 7 + ) + }, + ecl: (ecl) => { + // ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth. + const allowed = ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth'] + return allowed.includes(ecl) + }, + pid: (pid) => { + // pid (Passport ID) - a nine-digit number, including leading zeroes. + return ( + String(pid).length === 9 && + Number(pid) > 0 + ) + }, + cid: (cid) => { + // cid (Country ID) - ignored, missing or not. + return true + } +} + +const validate = (passport, checkFields = true) => { const fieldsToCheck = JSON.parse(JSON.stringify(requiredFields)) // quick deep copy // polar records don't have cid, but are otherwise valid if (getType(passport) === 'polar') { @@ -36,9 +105,22 @@ const validate = (passport) => { } // Check for fields fieldsToCheck.forEach((field) => { + // Check for required vield if (!passport[field]) { throw new Error(`Missing field ${field}`) } + // Skip field validation when disabled + if (!checkFields) { + return + } + // Validate field against rules + if ( + !rules[field]( + passport[field] + ) + ) { + throw new Error(`Invalid field value ${field}:${passport[field]}`) + } }) return true } diff --git a/2020/day-04/passports.test.js b/2020/day-04/passports.test.js index 25c5676..400211f 100644 --- a/2020/day-04/passports.test.js +++ b/2020/day-04/passports.test.js @@ -18,6 +18,30 @@ const invalid = [ iyr:2011 ecl:brn hgt:59in` ] +const invalidValues = [ + `eyr:1972 cid:100 + hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926`, + `iyr:2019 + hcl:#602927 eyr:1967 hgt:170cm + ecl:grn pid:012533040 byr:1946`, + `hcl:dab227 iyr:2012, + ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277`, + `hgt:59cm ecl:zzz + eyr:2038 hcl:74454a iyr:2023 + pid:3556412378 byr:2007` +] +const validValues = [ + `pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980 + hcl:#623a2f`, + `eyr:2029 ecl:blu cid:129 byr:1989 + iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm`, + `hcl:#888785 + hgt:164cm byr:2001 iyr:2015 cid:88 + pid:545766238 ecl:hzl + eyr:2022`, + 'iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719' +] + describe('--- Day 4: Passport Processing ---', () => { describe('Part 1', () => { describe('parseScan()', () => { @@ -36,16 +60,29 @@ describe('--- Day 4: Passport Processing ---', () => { }) }) describe('validate()', () => { - it('verifies all required fields in a passport', () => { + it('verifies presences of all required fields in a passport', () => { valid.forEach((scan, idx) => { const passport = parseScan(scan) // Valid when all required fields - expect(validate(passport)).to.equal(true) + expect(validate(passport, false)).to.equal(true) }) }) it('errors on invalid passports', () => { const passport = parseScan(invalid[0]) - expect(() => validate(passport)).to.throw('Missing field hgt') + expect(() => validate(passport, false)).to.throw('Missing field hgt') + }) + it('verifies the vield values agaisnt the type rules', () => { + validValues.forEach((scan, idx) => { + const passport = parseScan(scan) + // Valid when all required fields + expect(validate(passport)).to.equal(true) + }) + }) + it('errors on invalid passports', () => { + invalidValues.forEach((scan) => { + const passport = parseScan(scan) + expect(() => validate(passport)).to.throw() + }) }) }) }) diff --git a/2020/day-04/solution.js b/2020/day-04/solution.js index ab0c7d0..e63c777 100644 --- a/2020/day-04/solution.js +++ b/2020/day-04/solution.js @@ -1,4 +1,4 @@ -const DEBUG = false; +const DEBUG = true const fs = require('fs') const path = require('path') const split2 = require('split2') @@ -17,7 +17,7 @@ const part1 = () => { // Handle the record in the buffer const passport = parseScan(recordBuffer) try { - if (validate(passport)) { + if (validate(passport, false)) { validCount++ } } catch (e) { From 131652c009d8aba8b616be5292ac74ec10d5a744 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Mon, 7 Dec 2020 00:21:14 -0800 Subject: [PATCH 21/21] feat(2020-day-04): count all passports that have all fields valid Solution for part 2 --- 2020/day-04/solution.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/2020/day-04/solution.js b/2020/day-04/solution.js index e63c777..5885f43 100644 --- a/2020/day-04/solution.js +++ b/2020/day-04/solution.js @@ -7,9 +7,10 @@ const { parseScan, validate } = require('./passports') const answers = [] -const part1 = () => { +const scanPassports = () => { let recordBuffer = '' let validCount = 0 + let validWithFieldsCount = 0 let invalidCount = 0 let totalCount = 0 @@ -20,6 +21,9 @@ const part1 = () => { if (validate(passport, false)) { validCount++ } + if (validate(passport)) { + validWithFieldsCount++ + } } catch (e) { invalidCount++ if (DEBUG) { @@ -49,7 +53,7 @@ const part1 = () => { console.info('Total passports found:', totalCount) console.info('Invalid passports', invalidCount) answers.push(validCount) - answers.push(part2()) + answers.push(validWithFieldsCount) answers.forEach((ans, idx) => { console.info(`-- Part ${idx + 1} --`) @@ -61,8 +65,4 @@ const part1 = () => { return validCount } -const part2 = () => { - return 'No answer yet' -} - -part1() +scanPassports()