├── .eslintrc.js ├── .eslintrc.json ├── .gitignore ├── README.md ├── lib └── kernel.lisp ├── package.json ├── scripts └── lint.sh ├── src ├── backend │ ├── index.js │ ├── llvm.js │ ├── utility │ │ ├── Context.js │ │ └── Scope.js │ └── x86.js ├── parser.js └── ulisp.js ├── tests ├── digits.lisp ├── div-mod.lisp ├── fib-no-kernel.lisp ├── fib.lisp ├── function_definition.lisp ├── gt.lisp ├── if.lisp ├── meaning-of-life.lisp ├── plus_sub_mul.lisp ├── print.lisp ├── sys-write.lisp ├── tail-fib.lisp └── two_function_calls.lisp └── yarn.lock /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 3 | 'prettier', 4 | ], 5 | parserOptions: { 6 | ecmaVersion: 2018, 7 | sourceType: 'module', 8 | }, 9 | rules: { 10 | "arrow-parens": [ 11 | 1, 12 | "always" 13 | ], 14 | "class-methods-use-this": 1, 15 | "func-names": 0, 16 | "function-paren-newline": 0, 17 | "no-plusplus": 0, 18 | "object-curly-newline": 0, 19 | "prefer-arrow-callback": 0, 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "plugins": ["prettier"], 4 | "rules": { 5 | "prettier/prettier": "error" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | build 3 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ulisp 2 | 3 | A compiler for a lisp-like language written in JavaScript targeting LLVM, x86 assembly. 4 | 5 | ### Tutorials 6 | 7 | 1. [Lisp to assembly](http://notes.eatonphil.com/compiler-basics-lisp-to-assembly.html) 8 | 2. [User-defined functions and variables](http://notes.eatonphil.com/compiler-basics-functions.html) 9 | 3. [LLVM](http://notes.eatonphil.com/compiler-basics-llvm.html) 10 | 4. [LLVM conditionals and compiling fibonacci](http://notes.eatonphil.com/compiler-basics-llvm-conditionals.html) 11 | 5. [LLVM system calls](http://notes.eatonphil.com/compiler-basics-llvm-system-calls.html) 12 | 6. [An x86 upgrade](http://notes.eatonphil.com/compiler-basics-an-x86-upgrade.html) 13 | 14 | ### Example 15 | 16 | The following program: 17 | 18 | ``` 19 | $ cat tests/fib.lisp 20 | (def fib (n) 21 | (if (< n 2) 22 | n 23 | (+ (fib (- n 1)) (fib (- n 2))))) 24 | 25 | (def main () 26 | (fib 8)) 27 | ``` 28 | 29 | Returns 21 as its exit code when compiled: 30 | 31 | ``` 32 | $ node src/ulisp.js tests/fib.lisp 33 | $ ./build/prog 34 | $ echo $? 35 | 21 36 | ``` 37 | 38 | By generating this LLVM IR: 39 | 40 | ```llvm 41 | define i32 @fib(i32 %n) { 42 | %ifresult7 = alloca i32, align 4 43 | %sym8 = add i32 %n, 0 44 | %sym9 = add i32 2, 0 45 | %sym6 = icmp slt i32 %sym8, %sym9 46 | br i1 %sym6, label %iftrue10, label %iffalse11 47 | iftrue10: 48 | %sym12 = add i32 %n, 0 49 | store i32 %sym12, i32* %ifresult7, align 4 50 | br label %ifend13 51 | iffalse11: 52 | %sym18 = add i32 %n, 0 53 | %sym19 = add i32 1, 0 54 | %sym17 = sub i32 %sym18, %sym19 55 | %sym15 = call i32 @fib(i32 %sym17) 56 | %sym21 = add i32 %n, 0 57 | %sym22 = add i32 2, 0 58 | %sym20 = sub i32 %sym21, %sym22 59 | %sym16 = call i32 @fib(i32 %sym20) 60 | %sym14 = add i32 %sym15, %sym16 61 | store i32 %sym14, i32* %ifresult7, align 4 62 | br label %ifend13 63 | ifend13: 64 | %sym5 = load i32, i32* %ifresult7, align 4 65 | ret i32 %sym5 66 | } 67 | 68 | define i32 @main() { 69 | %sym6 = add i32 8, 0 70 | %sym5 = call i32 @fib(i32 %sym6) 71 | ret i32 %sym5 72 | } 73 | ``` 74 | -------------------------------------------------------------------------------- /lib/kernel.lisp: -------------------------------------------------------------------------------- 1 | (def print-char (c) 2 | (syscall/write 1 &c 1)) 3 | 4 | (def print (n) 5 | (if (> n 9) 6 | (print (/ n 10))) 7 | 8 | (print-char (+ 48 (% n 10)))) 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "eslint-plugin-prettier": "^3.0.1", 4 | "prettier": "^1.16.1" 5 | }, 6 | "scripts": { 7 | "lint": "./scripts/lint.sh", 8 | "lint:fix": "./scripts/lint.sh --fix" 9 | }, 10 | "prettier": { 11 | "singleQuote": true, 12 | "arrowParens": "always", 13 | "trailingComma": "all" 14 | }, 15 | "dependencies": { 16 | "eslint": "^5.15.0", 17 | "eslint-config-prettier": "^4.1.0", 18 | "prettylint": "^1.0.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /scripts/lint.sh: -------------------------------------------------------------------------------- 1 | eslint src/*.js src/**/*.js $1 2 | prettylint src/*.js src/**/*.js $1 3 | -------------------------------------------------------------------------------- /src/backend/index.js: -------------------------------------------------------------------------------- 1 | module.exports.x86 = require('./x86'); 2 | module.exports.llvm = require('./llvm'); 3 | -------------------------------------------------------------------------------- /src/backend/llvm.js: -------------------------------------------------------------------------------- 1 | const cp = require('child_process'); 2 | const fs = require('fs'); 3 | 4 | const { Context } = require('./utility/Context'); 5 | 6 | const SYSCALL_TABLE = { 7 | darwin: { 8 | write: 0x2000004, 9 | exit: 0x2000001, 10 | }, 11 | linux: { 12 | write: 1, 13 | exit: 60, 14 | }, 15 | }[process.platform]; 16 | 17 | class Compiler { 18 | constructor() { 19 | this.outBuffer = []; 20 | this.primitiveFunctions = { 21 | def: this.compileDefine.bind(this), 22 | begin: this.compileBegin.bind(this), 23 | if: this.compileIf.bind(this), 24 | '+': this.compileOp('add'), 25 | '-': this.compileOp('sub'), 26 | '*': this.compileOp('mul'), 27 | '/': this.compileOp('udiv'), 28 | '%': this.compileOp('urem'), 29 | '<': this.compileOp('icmp slt'), 30 | '>': this.compileOp('icmp sgt'), 31 | '=': this.compileOp('icmp eq'), 32 | 'syscall/write': this.compileSyscall(SYSCALL_TABLE.write), 33 | 'syscall/exit': this.compileSyscall(SYSCALL_TABLE.exit), 34 | }; 35 | } 36 | 37 | emit(depth, args) { 38 | const indent = new Array(depth + 1).join(' '); 39 | this.outBuffer.push(indent + args); 40 | } 41 | 42 | compileSyscall(id) { 43 | return (args, destination, context) => { 44 | const argTmps = args 45 | .map((arg) => { 46 | const tmp = context.scope.symbol(); 47 | this.compileExpression(arg, tmp, context); 48 | return tmp.type + ' %' + tmp.value; 49 | }) 50 | .join(', '); 51 | const regs = ['rdi', 'rsi', 'rdx', 'r10', 'r8', 'r9']; 52 | const params = args.map((arg, i) => `{${regs[i]}}`).join(','); 53 | const idTmp = context.scope.symbol().value; 54 | this.emit(1, `%${idTmp} = add i64 ${id}, 0`); 55 | this.emit( 56 | 1, 57 | `%${destination.value} = call ${destination.type} asm sideeffect "syscall", "=r,{rax},${params},~{dirflag},~{fpsr},~{flags}" (i64 %${idTmp}, ${argTmps})`, 58 | ); 59 | }; 60 | } 61 | 62 | compileOp(op) { 63 | return ([a, b], destination, context) => { 64 | const arg1 = context.scope.symbol(); 65 | const arg2 = context.scope.symbol(); 66 | this.compileExpression(a, arg1, context); 67 | this.compileExpression(b, arg2, context); 68 | this.emit( 69 | 1, 70 | `%${destination.value} = ${op} ${arg1.type} %${arg1.value}, %${arg2.value}`, 71 | ); 72 | }; 73 | } 74 | 75 | compileExpression(exp, destination, context) { 76 | // Is a nested function call, compile it 77 | if (Array.isArray(exp)) { 78 | this.compileCall(exp[0], exp.slice(1), destination, context); 79 | return; 80 | } 81 | 82 | if (Number.isInteger(+exp)) { 83 | this.emit(1, `%${destination.value} = add i64 ${exp}, 0`); 84 | return; 85 | } 86 | 87 | // Is a reference, push onto the stack and return its address 88 | if (exp.startsWith('&')) { 89 | const symbol = exp.substring(1); 90 | const tmp = context.scope.symbol(); 91 | this.compileExpression(symbol, tmp, context); 92 | this.emit(1, `%${destination.value} = alloca ${tmp.type}, align 4`); 93 | destination.type = tmp.type + '*'; 94 | this.emit( 95 | 1, 96 | `store ${tmp.type} %${tmp.value}, ${destination.type} %${destination.value}, align 4`, 97 | ); 98 | return; 99 | } 100 | 101 | const res = context.scope.get(exp); 102 | if (res) { 103 | this.emit(1, `%${destination.value} = add ${res.type} %${res.value}, 0`); 104 | } else { 105 | throw new Error( 106 | 'Attempt to reference undefined variable or unsupported literal: ' + 107 | exp, 108 | ); 109 | } 110 | } 111 | 112 | compileBegin(body, destination, context) { 113 | body.forEach((expression, i) => { 114 | const isLast = body.length - 1 === i; 115 | 116 | // Clone just to reset tailCallTree 117 | const contextClone = context.copy(); 118 | contextClone.scope = context.scope; 119 | if (!isLast) { 120 | contextClone.tailCallTree = []; 121 | } 122 | 123 | this.compileExpression( 124 | expression, 125 | isLast ? destination : context.scope.symbol(), 126 | contextClone, 127 | ); 128 | }); 129 | } 130 | 131 | compileIf([test, thenBlock, elseBlock], destination, context) { 132 | const testVariable = context.scope.symbol(); 133 | const result = context.scope.symbol('ifresult'); 134 | // Space for result 135 | result.type = 'i64*'; 136 | this.emit(1, `%${result.value} = alloca i64, align 4`); 137 | 138 | // Compile expression and branch 139 | this.compileExpression(test, testVariable, context); 140 | const trueLabel = context.scope.symbol('iftrue').value; 141 | const falseLabel = context.scope.symbol('iffalse').value; 142 | this.emit( 143 | 1, 144 | `br i1 %${testVariable.value}, label %${trueLabel}, label %${falseLabel}`, 145 | ); 146 | 147 | // Compile true section 148 | this.emit(0, trueLabel + ':'); 149 | const tmp1 = context.scope.symbol(); 150 | this.compileExpression(thenBlock, tmp1, context); 151 | this.emit( 152 | 1, 153 | `store ${tmp1.type} %${tmp1.value}, ${result.type} %${result.value}, align 4`, 154 | ); 155 | const endLabel = context.scope.symbol('ifend').value; 156 | this.emit(1, 'br label %' + endLabel); 157 | 158 | // Compile optional false section 159 | this.emit(0, falseLabel + ':'); 160 | if (elseBlock) { 161 | const tmp2 = context.scope.symbol(); 162 | this.compileExpression(elseBlock, tmp2, context); 163 | this.emit( 164 | 1, 165 | `store ${tmp2.type} %${tmp2.value}, ${result.type} %${result.value}, align 4`, 166 | ); 167 | } 168 | this.emit(1, 'br label %' + endLabel); 169 | 170 | // Compile cleanup 171 | this.emit(0, endLabel + ':'); 172 | this.emit( 173 | 1, 174 | `%${destination.value} = load ${destination.type}, ${result.type} %${result.value}, align 4`, 175 | ); 176 | } 177 | 178 | compileDefine([name, params, ...body], destination, context) { 179 | // Add this function to outer context.scope 180 | const fn = context.scope.register(name); 181 | 182 | // Copy outer context.scope so parameter mappings aren't exposed in outer context.scope. 183 | const childContext = context.copy(); 184 | childContext.tailCallTree.push(fn.value); 185 | 186 | const safeParams = params.map((param) => 187 | // Store parameter mapped to associated local 188 | childContext.scope.register(param), 189 | ); 190 | 191 | this.emit( 192 | 0, 193 | `define i64 @${fn.value}(${safeParams 194 | .map((p) => `${p.type} %${p.value}`) 195 | .join(', ')}) {`, 196 | ); 197 | 198 | // Pass childContext in for reference when body is compiled. 199 | const ret = childContext.scope.symbol(); 200 | this.compileBegin(body, ret, childContext); 201 | 202 | this.emit(1, `ret ${ret.type} %${ret.value}`); 203 | this.emit(0, '}\n'); 204 | } 205 | 206 | compileCall(fun, args, destination, context) { 207 | if (this.primitiveFunctions[fun]) { 208 | this.primitiveFunctions[fun](args, destination, context); 209 | return; 210 | } 211 | 212 | const validFunction = context.scope.get(fun); 213 | if (validFunction) { 214 | const safeArgs = args 215 | .map((a) => { 216 | const res = context.scope.symbol(); 217 | this.compileExpression(a, res, context); 218 | return res.type + ' %' + res.value; 219 | }) 220 | .join(', '); 221 | 222 | const isTailCall = 223 | module.exports.TAIL_CALL_ENABLED && 224 | context.tailCallTree.includes(validFunction.value); 225 | const maybeTail = isTailCall ? 'tail ' : ''; 226 | this.emit( 227 | 1, 228 | `%${destination.value} = ${maybeTail}call ${validFunction.type} @${validFunction.value}(${safeArgs})`, 229 | ); 230 | if (isTailCall) { 231 | this.emit(1, `ret ${destination.type} %${destination.value}`); 232 | } 233 | } else { 234 | throw new Error('Attempt to call undefined function: ' + fun); 235 | } 236 | } 237 | 238 | getOutput() { 239 | return this.outBuffer.join('\n'); 240 | } 241 | } 242 | 243 | module.exports.compile = function(ast) { 244 | const c = new Compiler(); 245 | const context = new Context(); 246 | c.compileCall('begin', ast, context.scope.symbol(), context); 247 | return c.getOutput(); 248 | }; 249 | 250 | module.exports.build = function(buildDir, program) { 251 | const prog = 'prog'; 252 | fs.writeFileSync(buildDir + `/${prog}.ll`, program); 253 | cp.execSync( 254 | `llc --x86-asm-syntax=intel -o ${buildDir}/${prog}.s ${buildDir}/${prog}.ll`, 255 | ); 256 | cp.execSync(`gcc -o ${buildDir}/${prog} -masm=intel ${buildDir}/${prog}.s`); 257 | }; 258 | 259 | module.exports.TAIL_CALL_ENABLED = true; 260 | -------------------------------------------------------------------------------- /src/backend/utility/Context.js: -------------------------------------------------------------------------------- 1 | const { Scope } = require('./Scope'); 2 | 3 | class Context { 4 | constructor() { 5 | this.scope = new Scope(); 6 | this.tailCallTree = []; 7 | } 8 | 9 | copy() { 10 | const c = new Context(); 11 | c.tailCallTree = [...this.tailCallTree]; 12 | c.scope = this.scope.copy(); 13 | return c; 14 | } 15 | } 16 | 17 | module.exports.Context = Context; 18 | -------------------------------------------------------------------------------- /src/backend/utility/Scope.js: -------------------------------------------------------------------------------- 1 | class Scope { 2 | constructor() { 3 | this.locals = {}; 4 | } 5 | 6 | symbol(prefix = 'sym') { 7 | const nth = Object.keys(this.locals).length + 1; 8 | return this.register(prefix + nth); 9 | } 10 | 11 | get(i) { 12 | return this.locals[i]; 13 | } 14 | 15 | register(local) { 16 | let copy = local.replace('-', '_'); 17 | let n = 1; 18 | while (this.locals[copy]) { 19 | copy = local + n++; 20 | } 21 | 22 | this.locals[local] = { 23 | value: copy, 24 | type: 'i64', 25 | }; 26 | return this.locals[local]; 27 | } 28 | 29 | copy() { 30 | const c = new Scope(); 31 | c.locals = { ...this.locals }; 32 | return c; 33 | } 34 | } 35 | 36 | module.exports.Scope = Scope; 37 | -------------------------------------------------------------------------------- /src/backend/x86.js: -------------------------------------------------------------------------------- 1 | const cp = require('child_process'); 2 | const fs = require('fs'); 3 | const os = require('os'); 4 | 5 | function range(n) { 6 | return Array.from(Array(n).keys()); 7 | } 8 | 9 | let GLOBAL_COUNTER = 0; 10 | 11 | const SYSCALL_MAP = { 12 | darwin: { 13 | exit: '0x2000001', 14 | write: '0x2000004', 15 | }, 16 | linux: { 17 | exit: 60, 18 | write: 1, 19 | }, 20 | }[os.platform()]; 21 | 22 | class Scope { 23 | constructor() { 24 | this.localOffset = 1; 25 | this.map = {}; 26 | } 27 | 28 | assign(name) { 29 | const safe = name.replace('-', '_'); 30 | this.map[safe] = this.localOffset++; 31 | return safe; 32 | } 33 | 34 | symbol() { 35 | return this.localOffset++; 36 | } 37 | 38 | lookup(name) { 39 | const safe = name.replace('-', '_'); 40 | if (this.map[safe]) { 41 | return { name: safe, offset: this.map[safe] }; 42 | } 43 | 44 | return null; 45 | } 46 | 47 | copy() { 48 | const s = new Scope(); 49 | // In the future we may need to store s.scopeOffset = this.scopeOffset + 1 50 | // so we can read outer-scoped values at runtime. 51 | s.map = { ...this.map }; 52 | return s; 53 | } 54 | } 55 | 56 | class Compiler { 57 | constructor() { 58 | this.outBuffer = []; 59 | this.primitiveFunctions = { 60 | def: this.compileDefine.bind(this), 61 | begin: this.compileBegin.bind(this), 62 | if: this.compileIf.bind(this), 63 | ...this.prepareArithmeticWrappers(), 64 | ...this.prepareLogicalWrappers(), 65 | ...this.prepareSyscallWrappers(), 66 | }; 67 | } 68 | 69 | prepareArithmeticWrappers() { 70 | // General operatations 71 | const prepareGeneral = (instruction) => (arg, scope, depth) => { 72 | depth++; 73 | this.emit(depth, `# ${instruction.toUpperCase()}`); 74 | 75 | // Compile first argument 76 | this.compileExpression(arg[0], scope, depth); 77 | 78 | // Compile second argument 79 | this.compileExpression(arg[1], scope, depth); 80 | this.emit(depth, `POP RAX`); 81 | 82 | // Compile operation 83 | this.emit(depth, `${instruction.toUpperCase()} [RSP], RAX`); 84 | 85 | this.emit(depth, `# End ${instruction.toUpperCase()}`); 86 | }; 87 | 88 | // Operations that use RAX implicitly 89 | const prepareRax = (instruction, outRegister = 'RAX') => ( 90 | arg, 91 | scope, 92 | depth, 93 | ) => { 94 | depth++; 95 | this.emit(depth, `# ${instruction.toUpperCase()}`); 96 | 97 | // Compile first argument, store in RAX 98 | this.compileExpression(arg[0], scope, depth); 99 | 100 | // Compile second argument 101 | this.compileExpression(arg[1], scope, depth); 102 | 103 | // Must POP _after_ both have been compiled 104 | this.emit(depth, `POP RAX`); 105 | this.emit(depth, `XCHG [RSP], RAX`); 106 | 107 | // Reset RDX for DIV 108 | if (instruction.toUpperCase() === 'DIV') { 109 | this.emit(depth, `XOR RDX, RDX`); 110 | } 111 | 112 | // Compiler operation 113 | this.emit(depth, `${instruction.toUpperCase()} QWORD PTR [RSP]`); 114 | 115 | // Swap the top of the stack 116 | this.emit(depth, `MOV [RSP], ${outRegister}`); 117 | }; 118 | 119 | return { 120 | '+': prepareGeneral('add'), 121 | '-': prepareGeneral('sub'), 122 | '&': prepareGeneral('and'), 123 | '|': prepareGeneral('or'), 124 | '=': prepareGeneral('mov'), 125 | '*': prepareRax('mul'), 126 | '/': prepareRax('div'), 127 | '%': prepareRax('div', 'RDX'), 128 | }; 129 | } 130 | 131 | prepareLogicalWrappers() { 132 | const prepareComparison = (operator) => { 133 | return { 134 | [operator]: (arg, scope, depth) => { 135 | depth++; 136 | this.emit(depth, `# ${operator}`); 137 | 138 | // Compile first argument, store in RAX 139 | this.compileExpression(arg[0], scope, depth); 140 | 141 | // Compile second argument 142 | this.compileExpression(arg[1], scope, depth); 143 | this.emit(depth, `POP RAX`); 144 | 145 | // Compile operation 146 | this.emit(depth, `CMP [RSP], RAX`); 147 | 148 | // Reset RAX to serve as CMOV* dest, MOV to keep flags (vs. XOR) 149 | this.emit(depth, `MOV RAX, 0`); 150 | 151 | // Conditional set [RSP] 152 | const operation = { 153 | '>': 'CMOVA', 154 | '>=': 'CMOVAE', 155 | '<': 'CMOVB', 156 | '<=': 'CMOVBE', 157 | '==': 'CMOVE', 158 | '!=': 'CMOVNE', 159 | }[operator]; 160 | // CMOV* requires the source to be memory or register 161 | this.emit(depth, `MOV DWORD PTR [RSP], 1`); 162 | // CMOV* requires the dest to be a register 163 | this.emit(depth, `${operation} RAX, [RSP]`); 164 | this.emit(depth, `MOV [RSP], RAX`); 165 | this.emit(depth, `# End ${operator}`); 166 | }, 167 | }; 168 | }; 169 | 170 | return { 171 | ...prepareComparison('>'), 172 | ...prepareComparison('>='), 173 | ...prepareComparison('<'), 174 | ...prepareComparison('<='), 175 | ...prepareComparison('=='), 176 | ...prepareComparison('!='), 177 | }; 178 | } 179 | 180 | prepareSyscallWrappers() { 181 | const registers = ['RDI', 'RSI', 'RDX', 'R10', 'R8', 'R9']; 182 | 183 | const wrappers = {}; 184 | Object.keys(SYSCALL_MAP).forEach((key, obj) => { 185 | wrappers[`syscall/${key}`] = (args, scope, depth) => { 186 | if (args.length > registers.length) { 187 | throw new Error(`Too many arguments to syscall/${key}`); 188 | } 189 | 190 | // Compile first 191 | args.forEach((arg) => this.compileExpression(arg, scope, depth)); 192 | 193 | // Then pop to avoid possible register contention 194 | args.forEach((_, i) => 195 | this.emit(depth, `POP ${registers[args.length - i - 1]}`), 196 | ); 197 | 198 | this.emit(depth, `MOV RAX, ${SYSCALL_MAP[key]}`); 199 | this.emit(depth, 'SYSCALL'); 200 | this.emit(depth, `PUSH RAX`); 201 | }; 202 | }); 203 | 204 | return wrappers; 205 | } 206 | 207 | emit(depth, args) { 208 | if (depth === undefined || args === undefined) { 209 | throw new Error('Invalid call to emit'); 210 | } 211 | 212 | const indent = new Array(depth + 1).join(' '); 213 | this.outBuffer.push(indent + args); 214 | } 215 | 216 | compileExpression(arg, scope, depth) { 217 | // Is a nested function call, compile it 218 | if (Array.isArray(arg)) { 219 | this.compileCall(arg[0], arg.slice(1), scope, depth); 220 | return; 221 | } 222 | 223 | if (Number.isInteger(arg)) { 224 | this.emit(depth, `PUSH ${arg}`); 225 | return; 226 | } 227 | 228 | if (arg.startsWith('&')) { 229 | const { offset } = scope.lookup(arg.substring(1)); 230 | // Copy the frame pointer so we can return an offset from it 231 | this.emit(depth, `MOV RAX, RBP`); 232 | const operation = offset < 0 ? 'ADD' : 'SUB'; 233 | this.emit(depth, `${operation} RAX, ${Math.abs(offset * 8)} # ${arg}`); 234 | this.emit(depth, `PUSH RAX`); 235 | return; 236 | } 237 | 238 | const { offset } = scope.lookup(arg); 239 | if (offset) { 240 | const operation = offset < 0 ? '+' : '-'; 241 | this.emit( 242 | depth, 243 | `PUSH [RBP ${operation} ${Math.abs(offset * 8)}] # ${arg}`, 244 | ); 245 | } else { 246 | throw new Error( 247 | 'Attempt to reference undefined variable or unsupported literal: ' + 248 | arg, 249 | ); 250 | } 251 | } 252 | 253 | compileIf([test, then, els], scope, depth) { 254 | this.emit(depth, '# If'); 255 | // Compile test 256 | this.compileExpression(test, scope, depth); 257 | const branch = `else_branch` + GLOBAL_COUNTER++; 258 | // Must pop/use up argument in test 259 | this.emit(0, ''); 260 | this.emit(depth, `POP RAX`); 261 | this.emit(depth, `TEST RAX, RAX`); 262 | this.emit(depth, `JZ .${branch}\n`); 263 | 264 | // Compile then section 265 | this.emit(depth, `# If then`); 266 | this.compileExpression(then, scope, depth); 267 | this.emit(depth, `JMP .after_${branch}\n`); 268 | 269 | // Compile else section 270 | this.emit(depth, `# If else`); 271 | this.emit(0, `.${branch}:`); 272 | if (els) { 273 | this.compileExpression(els, scope, depth); 274 | } else { 275 | this.emit(1, 'PUSH 0 # Null else branch'); 276 | } 277 | this.emit(0, `.after_${branch}:`); 278 | this.emit(depth, '# End if'); 279 | } 280 | 281 | compileBegin(body, scope, depth, topLevel = false) { 282 | body.forEach((expression, i) => { 283 | this.compileExpression(expression, scope, depth); 284 | if (!topLevel && i < body.length - 1) { 285 | this.emit(depth, `POP RAX # Ignore non-final expression`); 286 | } 287 | }); 288 | } 289 | 290 | compileDefine([name, params, ...body], scope, depth) { 291 | // Add this function to outer scope 292 | const safe = scope.assign(name); 293 | 294 | // Copy outer scope so parameter mappings aren't exposed in outer scope. 295 | const childScope = scope.copy(); 296 | 297 | this.emit(0, `${safe}:`); 298 | this.emit(depth, `PUSH RBP`); 299 | this.emit(depth, `MOV RBP, RSP\n`); 300 | 301 | // Copy params into local scope 302 | // NOTE: this doesn't actually copy into the local stack, it 303 | // just references them from the caller. They will need to 304 | // be copied in to support mutation of arguments if that's 305 | // ever a desire. 306 | params.forEach((param, i) => { 307 | childScope.map[param] = -1 * (params.length - i - 1 + 2); 308 | }); 309 | 310 | // Pass childScope in for reference when body is compiled. 311 | this.compileBegin(body, childScope, depth); 312 | 313 | // Save the return value 314 | this.emit(0, ''); 315 | this.emit(depth, `POP RAX`); 316 | this.emit(depth, `POP RBP\n`); 317 | 318 | this.emit(depth, 'RET\n'); 319 | } 320 | 321 | compileCall(fun, args, scope, depth) { 322 | if (this.primitiveFunctions[fun]) { 323 | this.primitiveFunctions[fun](args, scope, depth); 324 | return; 325 | } 326 | 327 | // Compile registers and store on the stack 328 | args.map((arg, i) => this.compileExpression(arg, scope, depth)); 329 | 330 | const fn = scope.lookup(fun); 331 | if (fn) { 332 | this.emit(depth, `CALL ${fn.name}`); 333 | } else { 334 | throw new Error('Attempt to call undefined function: ' + fun); 335 | } 336 | 337 | if (args.length > 1) { 338 | // Drop the args 339 | this.emit(depth, `ADD RSP, ${args.length * 8}`); 340 | } 341 | 342 | if (args.length === 1) { 343 | this.emit(depth, `MOV [RSP], RAX\n`); 344 | } else { 345 | this.emit(depth, 'PUSH RAX\n'); 346 | } 347 | } 348 | 349 | emitPrefix() { 350 | this.emit(1, '.global _main\n'); 351 | 352 | this.emit(1, '.text\n'); 353 | } 354 | 355 | emitPostfix() { 356 | this.emit(0, '_main:'); 357 | this.emit(1, 'CALL main'); 358 | this.emit(1, 'MOV RDI, RAX'); // Set exit arg 359 | this.emit(1, `MOV RAX, ${SYSCALL_MAP['exit']}`); 360 | this.emit(1, 'SYSCALL'); 361 | } 362 | 363 | getOutput() { 364 | const output = this.outBuffer.join('\n'); 365 | 366 | // Leave at most one empty line 367 | return output.replace(/\n\n\n+/g, '\n\n'); 368 | } 369 | } 370 | 371 | module.exports.compile = function(ast) { 372 | const c = new Compiler(); 373 | c.emitPrefix(); 374 | const s = new Scope(); 375 | c.compileBegin(ast, s, 1, true); 376 | c.emitPostfix(); 377 | return c.getOutput(); 378 | }; 379 | 380 | module.exports.build = function(buildDir, program) { 381 | const prog = 'prog'; 382 | fs.writeFileSync(`${buildDir}/${prog}.s`, program); 383 | cp.execSync( 384 | `gcc -mstackrealign -masm=intel -o ${buildDir}/${prog} ${buildDir}/${prog}.s`, 385 | ); 386 | }; 387 | -------------------------------------------------------------------------------- /src/parser.js: -------------------------------------------------------------------------------- 1 | const WHITESPACE = [' ', '\n', '\t']; 2 | 3 | module.exports.parse = function parse(program = '') { 4 | const tokens = []; 5 | let currentToken = ''; 6 | 7 | for (let i = 0; i < program.length; i++) { 8 | const char = program.charAt(i); 9 | 10 | if (char === '(') { 11 | const [parsed, rest] = parse(program.substring(i + 1)); 12 | tokens.push(parsed); 13 | program = rest; 14 | i = -1; 15 | } else if (char === ')') { 16 | if (currentToken.length) { 17 | tokens.push(+currentToken || currentToken); 18 | } 19 | 20 | return [tokens, program.substring(i + 1)]; 21 | } else if (char === ';') { 22 | while (program.charAt(i) !== '\n') { 23 | i++; 24 | } 25 | } else if (WHITESPACE.includes(char)) { 26 | if (currentToken.length) { 27 | tokens.push(+currentToken || currentToken); 28 | } 29 | currentToken = ''; 30 | } else { 31 | currentToken += char; 32 | } 33 | } 34 | 35 | return [tokens, '']; 36 | }; 37 | -------------------------------------------------------------------------------- /src/ulisp.js: -------------------------------------------------------------------------------- 1 | const cp = require('child_process'); 2 | const fs = require('fs'); 3 | 4 | const { parse } = require('./parser'); 5 | const backends = require('./backend'); 6 | 7 | function main(args) { 8 | const kernel = fs.readFileSync(__dirname + '/../lib/kernel.lisp').toString(); 9 | let input = kernel + '\n' + fs.readFileSync(args[2]).toString(); 10 | 11 | let backend = backends.llvm; 12 | 13 | const restArgs = args.slice(3); 14 | for (let i = 0; i < restArgs.length; i++) { 15 | switch (restArgs[i]) { 16 | case '--no-kernel': 17 | input = input.substring(kernel.length + 1); 18 | break; 19 | case '--backend': 20 | case '-b': 21 | backend = backends[restArgs[i + 1]]; 22 | if (!backend) { 23 | console.log('Unsupported backend ' + restArgs[i + 1]); 24 | process.exit(1); 25 | } 26 | i++; 27 | break; 28 | case '--no-tail-call': 29 | case '-n': 30 | backend.TAIL_CALL_ENABLED = false; 31 | break; 32 | } 33 | } 34 | 35 | const [ast] = parse(input); 36 | const program = backend.compile(ast); 37 | 38 | try { 39 | fs.mkdirSync('build'); 40 | } catch (e) {} 41 | backend.build('build', program); 42 | } 43 | 44 | main(process.argv); 45 | -------------------------------------------------------------------------------- /tests/digits.lisp: -------------------------------------------------------------------------------- 1 | (def digits (n c) 2 | (if (< n 10) 3 | (+ c 1) 4 | (digits (/ n 10) (+ c 1)))) 5 | 6 | (def main () 7 | (digits 10234 0)) 8 | -------------------------------------------------------------------------------- /tests/div-mod.lisp: -------------------------------------------------------------------------------- 1 | (def main () 2 | (+ (/ 10 5) (% 1 2))) 3 | -------------------------------------------------------------------------------- /tests/fib-no-kernel.lisp: -------------------------------------------------------------------------------- 1 | (def fib (n) 2 | (if (< n 2) 3 | n 4 | (+ (fib (- n 1)) (fib (- n 2))))) 5 | 6 | (def main () 7 | (fib 10)) 8 | -------------------------------------------------------------------------------- /tests/fib.lisp: -------------------------------------------------------------------------------- 1 | (def fib (n) 2 | (if (< n 2) 3 | n 4 | (+ (fib (- n 1)) (fib (- n 2))))) 5 | 6 | (def main () 7 | (print (fib 20))) 8 | -------------------------------------------------------------------------------- /tests/function_definition.lisp: -------------------------------------------------------------------------------- 1 | (def plus-two (a b) 2 | (+ a (+ b 2))) 3 | 4 | (def main () 5 | (plus-two 3 (plus-two 1 1))) 6 | -------------------------------------------------------------------------------- /tests/gt.lisp: -------------------------------------------------------------------------------- 1 | (def main () 2 | (< 1 2)) 3 | -------------------------------------------------------------------------------- /tests/if.lisp: -------------------------------------------------------------------------------- 1 | (def main () 2 | (if (< 2 1) 3 | 3 4 | 2)) 5 | -------------------------------------------------------------------------------- /tests/meaning-of-life.lisp: -------------------------------------------------------------------------------- 1 | (def main () 2 | (+ 8 (* 2 17))) 3 | -------------------------------------------------------------------------------- /tests/plus_sub_mul.lisp: -------------------------------------------------------------------------------- 1 | (def main () 2 | (* (+ 3 2) 4) 3 | -------------------------------------------------------------------------------- /tests/print.lisp: -------------------------------------------------------------------------------- 1 | (def print-char1 (c) 2 | (syscall/write 1 &c 1)) 3 | 4 | (def print1 (n) 5 | (if (> n 9) 6 | (print1 (/ n 10))) 7 | (print-char1 (+ 48 (% n 10)))) 8 | 9 | (def main () 10 | (print1 123)) 11 | -------------------------------------------------------------------------------- /tests/sys-write.lisp: -------------------------------------------------------------------------------- 1 | (def print (n) 2 | (syscall/sys_write 1 &n 1)) 3 | 4 | (def main () 5 | (print (+ 1 48)) 6 | (print (+ 2 48)) 7 | (print (+ 3 48)) 8 | (print (+ 4 48)) 9 | 10) 10 | -------------------------------------------------------------------------------- /tests/tail-fib.lisp: -------------------------------------------------------------------------------- 1 | (def fib-help (a b n) 2 | (if (= n 0) 3 | a 4 | (fib-help b (+ a b) (- n 1)))) 5 | 6 | (def fib (n) 7 | (fib-help 0 1 n)) 8 | 9 | (def main () 10 | (print (fib 45))) 11 | -------------------------------------------------------------------------------- /tests/two_function_calls.lisp: -------------------------------------------------------------------------------- 1 | (def p1 (c) 2 | (+ c 1)) 3 | 4 | (def plus (a b) 5 | (+ a b)) 6 | 7 | (def main () 8 | (p1 (plus 2 9))) 9 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/code-frame@^7.0.0": 6 | version "7.5.5" 7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" 8 | integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== 9 | dependencies: 10 | "@babel/highlight" "^7.0.0" 11 | 12 | "@babel/highlight@^7.0.0": 13 | version "7.5.0" 14 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" 15 | integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ== 16 | dependencies: 17 | chalk "^2.0.0" 18 | esutils "^2.0.2" 19 | js-tokens "^4.0.0" 20 | 21 | acorn-jsx@^5.0.0: 22 | version "5.1.0" 23 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384" 24 | integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw== 25 | 26 | acorn@^6.0.7: 27 | version "6.4.1" 28 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" 29 | integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== 30 | 31 | ajv@^6.10.2, ajv@^6.9.1: 32 | version "6.10.2" 33 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" 34 | integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== 35 | dependencies: 36 | fast-deep-equal "^2.0.1" 37 | fast-json-stable-stringify "^2.0.0" 38 | json-schema-traverse "^0.4.1" 39 | uri-js "^4.2.2" 40 | 41 | ansi-escapes@^2.0.0: 42 | version "2.0.0" 43 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" 44 | integrity sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs= 45 | 46 | ansi-escapes@^3.2.0: 47 | version "3.2.0" 48 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" 49 | integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== 50 | 51 | ansi-regex@^3.0.0: 52 | version "3.0.0" 53 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 54 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= 55 | 56 | ansi-regex@^4.1.0: 57 | version "4.1.0" 58 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" 59 | integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== 60 | 61 | ansi-styles@^3.2.0, ansi-styles@^3.2.1: 62 | version "3.2.1" 63 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 64 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 65 | dependencies: 66 | color-convert "^1.9.0" 67 | 68 | argparse@^1.0.7: 69 | version "1.0.10" 70 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 71 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 72 | dependencies: 73 | sprintf-js "~1.0.2" 74 | 75 | array-find-index@^1.0.1: 76 | version "1.0.2" 77 | resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" 78 | integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= 79 | 80 | array-union@^1.0.1: 81 | version "1.0.2" 82 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" 83 | integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= 84 | dependencies: 85 | array-uniq "^1.0.1" 86 | 87 | array-uniq@^1.0.1: 88 | version "1.0.3" 89 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" 90 | integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= 91 | 92 | astral-regex@^1.0.0: 93 | version "1.0.0" 94 | resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" 95 | integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== 96 | 97 | balanced-match@^1.0.0: 98 | version "1.0.0" 99 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 100 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 101 | 102 | brace-expansion@^1.1.7: 103 | version "1.1.11" 104 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 105 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 106 | dependencies: 107 | balanced-match "^1.0.0" 108 | concat-map "0.0.1" 109 | 110 | callsites@^3.0.0: 111 | version "3.1.0" 112 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 113 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 114 | 115 | camelcase-keys@^2.0.0: 116 | version "2.1.0" 117 | resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" 118 | integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= 119 | dependencies: 120 | camelcase "^2.0.0" 121 | map-obj "^1.0.0" 122 | 123 | camelcase@^2.0.0: 124 | version "2.1.1" 125 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" 126 | integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= 127 | 128 | chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.2: 129 | version "2.4.2" 130 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 131 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 132 | dependencies: 133 | ansi-styles "^3.2.1" 134 | escape-string-regexp "^1.0.5" 135 | supports-color "^5.3.0" 136 | 137 | chardet@^0.7.0: 138 | version "0.7.0" 139 | resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" 140 | integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== 141 | 142 | cli-cursor@^2.1.0: 143 | version "2.1.0" 144 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" 145 | integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= 146 | dependencies: 147 | restore-cursor "^2.0.0" 148 | 149 | cli-width@^2.0.0: 150 | version "2.2.0" 151 | resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" 152 | integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= 153 | 154 | color-convert@^1.9.0: 155 | version "1.9.3" 156 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 157 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 158 | dependencies: 159 | color-name "1.1.3" 160 | 161 | color-name@1.1.3: 162 | version "1.1.3" 163 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 164 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 165 | 166 | concat-map@0.0.1: 167 | version "0.0.1" 168 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 169 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 170 | 171 | cross-spawn@^6.0.5: 172 | version "6.0.5" 173 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" 174 | integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== 175 | dependencies: 176 | nice-try "^1.0.4" 177 | path-key "^2.0.1" 178 | semver "^5.5.0" 179 | shebang-command "^1.2.0" 180 | which "^1.2.9" 181 | 182 | currently-unhandled@^0.4.1: 183 | version "0.4.1" 184 | resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" 185 | integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= 186 | dependencies: 187 | array-find-index "^1.0.1" 188 | 189 | debug@^4.0.1: 190 | version "4.1.1" 191 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" 192 | integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== 193 | dependencies: 194 | ms "^2.1.1" 195 | 196 | decamelize@^1.1.2: 197 | version "1.2.0" 198 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 199 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 200 | 201 | deep-is@~0.1.3: 202 | version "0.1.3" 203 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" 204 | integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= 205 | 206 | doctrine@^3.0.0: 207 | version "3.0.0" 208 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" 209 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 210 | dependencies: 211 | esutils "^2.0.2" 212 | 213 | emoji-regex@^7.0.1: 214 | version "7.0.3" 215 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" 216 | integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== 217 | 218 | error-ex@^1.2.0: 219 | version "1.3.2" 220 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" 221 | integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== 222 | dependencies: 223 | is-arrayish "^0.2.1" 224 | 225 | escape-string-regexp@^1.0.5: 226 | version "1.0.5" 227 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 228 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 229 | 230 | eslint-config-prettier@^4.1.0: 231 | version "4.3.0" 232 | resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-4.3.0.tgz#c55c1fcac8ce4518aeb77906984e134d9eb5a4f0" 233 | integrity sha512-sZwhSTHVVz78+kYD3t5pCWSYEdVSBR0PXnwjDRsUs8ytIrK8PLXw+6FKp8r3Z7rx4ZszdetWlXYKOHoUrrwPlA== 234 | dependencies: 235 | get-stdin "^6.0.0" 236 | 237 | eslint-formatter-pretty@^1.3.0: 238 | version "1.3.0" 239 | resolved "https://registry.yarnpkg.com/eslint-formatter-pretty/-/eslint-formatter-pretty-1.3.0.tgz#985d9e41c1f8475f4a090c5dbd2dfcf2821d607e" 240 | integrity sha512-5DY64Y1rYCm7cfFDHEGUn54bvCnK+wSUVF07N8oXeqUJFSd+gnYOTXbzelQ1HurESluY6gnEQPmXOIkB4Wa+gA== 241 | dependencies: 242 | ansi-escapes "^2.0.0" 243 | chalk "^2.1.0" 244 | log-symbols "^2.0.0" 245 | plur "^2.1.2" 246 | string-width "^2.0.0" 247 | 248 | eslint-plugin-prettier@^2.2.0: 249 | version "2.7.0" 250 | resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz#b4312dcf2c1d965379d7f9d5b5f8aaadc6a45904" 251 | integrity sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA== 252 | dependencies: 253 | fast-diff "^1.1.1" 254 | jest-docblock "^21.0.0" 255 | 256 | eslint-plugin-prettier@^3.0.1: 257 | version "3.1.1" 258 | resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.1.tgz#507b8562410d02a03f0ddc949c616f877852f2ba" 259 | integrity sha512-A+TZuHZ0KU0cnn56/9mfR7/KjUJ9QNVXUhwvRFSR7PGPe0zQR6PTkmyqg1AtUUEOzTqeRsUwyKFh0oVZKVCrtA== 260 | dependencies: 261 | prettier-linter-helpers "^1.0.0" 262 | 263 | eslint-scope@^4.0.3: 264 | version "4.0.3" 265 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" 266 | integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== 267 | dependencies: 268 | esrecurse "^4.1.0" 269 | estraverse "^4.1.1" 270 | 271 | eslint-utils@^1.3.1: 272 | version "1.4.3" 273 | resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" 274 | integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== 275 | dependencies: 276 | eslint-visitor-keys "^1.1.0" 277 | 278 | eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: 279 | version "1.1.0" 280 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" 281 | integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== 282 | 283 | eslint@^5.15.0: 284 | version "5.16.0" 285 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" 286 | integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== 287 | dependencies: 288 | "@babel/code-frame" "^7.0.0" 289 | ajv "^6.9.1" 290 | chalk "^2.1.0" 291 | cross-spawn "^6.0.5" 292 | debug "^4.0.1" 293 | doctrine "^3.0.0" 294 | eslint-scope "^4.0.3" 295 | eslint-utils "^1.3.1" 296 | eslint-visitor-keys "^1.0.0" 297 | espree "^5.0.1" 298 | esquery "^1.0.1" 299 | esutils "^2.0.2" 300 | file-entry-cache "^5.0.1" 301 | functional-red-black-tree "^1.0.1" 302 | glob "^7.1.2" 303 | globals "^11.7.0" 304 | ignore "^4.0.6" 305 | import-fresh "^3.0.0" 306 | imurmurhash "^0.1.4" 307 | inquirer "^6.2.2" 308 | js-yaml "^3.13.0" 309 | json-stable-stringify-without-jsonify "^1.0.1" 310 | levn "^0.3.0" 311 | lodash "^4.17.11" 312 | minimatch "^3.0.4" 313 | mkdirp "^0.5.1" 314 | natural-compare "^1.4.0" 315 | optionator "^0.8.2" 316 | path-is-inside "^1.0.2" 317 | progress "^2.0.0" 318 | regexpp "^2.0.1" 319 | semver "^5.5.1" 320 | strip-ansi "^4.0.0" 321 | strip-json-comments "^2.0.1" 322 | table "^5.2.3" 323 | text-table "^0.2.0" 324 | 325 | espree@^5.0.1: 326 | version "5.0.1" 327 | resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" 328 | integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== 329 | dependencies: 330 | acorn "^6.0.7" 331 | acorn-jsx "^5.0.0" 332 | eslint-visitor-keys "^1.0.0" 333 | 334 | esprima@^4.0.0: 335 | version "4.0.1" 336 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 337 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 338 | 339 | esquery@^1.0.1: 340 | version "1.0.1" 341 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" 342 | integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== 343 | dependencies: 344 | estraverse "^4.0.0" 345 | 346 | esrecurse@^4.1.0: 347 | version "4.2.1" 348 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" 349 | integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== 350 | dependencies: 351 | estraverse "^4.1.0" 352 | 353 | estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: 354 | version "4.3.0" 355 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" 356 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== 357 | 358 | esutils@^2.0.2: 359 | version "2.0.3" 360 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 361 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 362 | 363 | external-editor@^3.0.3: 364 | version "3.1.0" 365 | resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" 366 | integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== 367 | dependencies: 368 | chardet "^0.7.0" 369 | iconv-lite "^0.4.24" 370 | tmp "^0.0.33" 371 | 372 | fast-deep-equal@^2.0.1: 373 | version "2.0.1" 374 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" 375 | integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= 376 | 377 | fast-diff@^1.1.1, fast-diff@^1.1.2: 378 | version "1.2.0" 379 | resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" 380 | integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== 381 | 382 | fast-json-stable-stringify@^2.0.0: 383 | version "2.0.0" 384 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" 385 | integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= 386 | 387 | fast-levenshtein@~2.0.6: 388 | version "2.0.6" 389 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 390 | integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= 391 | 392 | figures@^2.0.0: 393 | version "2.0.0" 394 | resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" 395 | integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= 396 | dependencies: 397 | escape-string-regexp "^1.0.5" 398 | 399 | file-entry-cache@^5.0.1: 400 | version "5.0.1" 401 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" 402 | integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== 403 | dependencies: 404 | flat-cache "^2.0.1" 405 | 406 | find-up@^1.0.0: 407 | version "1.1.2" 408 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" 409 | integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= 410 | dependencies: 411 | path-exists "^2.0.0" 412 | pinkie-promise "^2.0.0" 413 | 414 | flat-cache@^2.0.1: 415 | version "2.0.1" 416 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" 417 | integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== 418 | dependencies: 419 | flatted "^2.0.0" 420 | rimraf "2.6.3" 421 | write "1.0.3" 422 | 423 | flatted@^2.0.0: 424 | version "2.0.1" 425 | resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" 426 | integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== 427 | 428 | fs.realpath@^1.0.0: 429 | version "1.0.0" 430 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 431 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 432 | 433 | functional-red-black-tree@^1.0.1: 434 | version "1.0.1" 435 | resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" 436 | integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= 437 | 438 | get-stdin@^4.0.1: 439 | version "4.0.1" 440 | resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" 441 | integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= 442 | 443 | get-stdin@^6.0.0: 444 | version "6.0.0" 445 | resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" 446 | integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== 447 | 448 | glob@^7.0.3, glob@^7.1.2, glob@^7.1.3: 449 | version "7.1.6" 450 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" 451 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 452 | dependencies: 453 | fs.realpath "^1.0.0" 454 | inflight "^1.0.4" 455 | inherits "2" 456 | minimatch "^3.0.4" 457 | once "^1.3.0" 458 | path-is-absolute "^1.0.0" 459 | 460 | globals@^11.7.0: 461 | version "11.12.0" 462 | resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" 463 | integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== 464 | 465 | globby@^6.1.0: 466 | version "6.1.0" 467 | resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" 468 | integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= 469 | dependencies: 470 | array-union "^1.0.1" 471 | glob "^7.0.3" 472 | object-assign "^4.0.1" 473 | pify "^2.0.0" 474 | pinkie-promise "^2.0.0" 475 | 476 | graceful-fs@^4.1.2: 477 | version "4.2.3" 478 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" 479 | integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== 480 | 481 | has-flag@^3.0.0: 482 | version "3.0.0" 483 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 484 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 485 | 486 | hosted-git-info@^2.1.4: 487 | version "2.8.5" 488 | resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" 489 | integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg== 490 | 491 | iconv-lite@^0.4.24: 492 | version "0.4.24" 493 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 494 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 495 | dependencies: 496 | safer-buffer ">= 2.1.2 < 3" 497 | 498 | ignore@^3.3.5: 499 | version "3.3.10" 500 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" 501 | integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== 502 | 503 | ignore@^4.0.6: 504 | version "4.0.6" 505 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" 506 | integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== 507 | 508 | import-fresh@^3.0.0: 509 | version "3.2.1" 510 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" 511 | integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== 512 | dependencies: 513 | parent-module "^1.0.0" 514 | resolve-from "^4.0.0" 515 | 516 | imurmurhash@^0.1.4: 517 | version "0.1.4" 518 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 519 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= 520 | 521 | indent-string@^2.1.0: 522 | version "2.1.0" 523 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" 524 | integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= 525 | dependencies: 526 | repeating "^2.0.0" 527 | 528 | inflight@^1.0.4: 529 | version "1.0.6" 530 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 531 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 532 | dependencies: 533 | once "^1.3.0" 534 | wrappy "1" 535 | 536 | inherits@2: 537 | version "2.0.4" 538 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 539 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 540 | 541 | inquirer@^6.2.2: 542 | version "6.5.2" 543 | resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" 544 | integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== 545 | dependencies: 546 | ansi-escapes "^3.2.0" 547 | chalk "^2.4.2" 548 | cli-cursor "^2.1.0" 549 | cli-width "^2.0.0" 550 | external-editor "^3.0.3" 551 | figures "^2.0.0" 552 | lodash "^4.17.12" 553 | mute-stream "0.0.7" 554 | run-async "^2.2.0" 555 | rxjs "^6.4.0" 556 | string-width "^2.1.0" 557 | strip-ansi "^5.1.0" 558 | through "^2.3.6" 559 | 560 | irregular-plurals@^1.0.0: 561 | version "1.4.0" 562 | resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.4.0.tgz#2ca9b033651111855412f16be5d77c62a458a766" 563 | integrity sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y= 564 | 565 | is-arrayish@^0.2.1: 566 | version "0.2.1" 567 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" 568 | integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= 569 | 570 | is-finite@^1.0.0: 571 | version "1.0.2" 572 | resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" 573 | integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= 574 | dependencies: 575 | number-is-nan "^1.0.0" 576 | 577 | is-fullwidth-code-point@^2.0.0: 578 | version "2.0.0" 579 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 580 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 581 | 582 | is-promise@^2.1.0: 583 | version "2.1.0" 584 | resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" 585 | integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= 586 | 587 | is-utf8@^0.2.0: 588 | version "0.2.1" 589 | resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" 590 | integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= 591 | 592 | isexe@^2.0.0: 593 | version "2.0.0" 594 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 595 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 596 | 597 | jest-docblock@^21.0.0: 598 | version "21.2.0" 599 | resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" 600 | integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== 601 | 602 | js-tokens@^4.0.0: 603 | version "4.0.0" 604 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 605 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 606 | 607 | js-yaml@^3.13.0: 608 | version "3.13.1" 609 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" 610 | integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== 611 | dependencies: 612 | argparse "^1.0.7" 613 | esprima "^4.0.0" 614 | 615 | json-schema-traverse@^0.4.1: 616 | version "0.4.1" 617 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 618 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 619 | 620 | json-stable-stringify-without-jsonify@^1.0.1: 621 | version "1.0.1" 622 | resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" 623 | integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= 624 | 625 | levn@^0.3.0, levn@~0.3.0: 626 | version "0.3.0" 627 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" 628 | integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= 629 | dependencies: 630 | prelude-ls "~1.1.2" 631 | type-check "~0.3.2" 632 | 633 | lines-and-columns@^1.1.6: 634 | version "1.1.6" 635 | resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" 636 | integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= 637 | 638 | load-json-file@^1.0.0: 639 | version "1.1.0" 640 | resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" 641 | integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= 642 | dependencies: 643 | graceful-fs "^4.1.2" 644 | parse-json "^2.2.0" 645 | pify "^2.0.0" 646 | pinkie-promise "^2.0.0" 647 | strip-bom "^2.0.0" 648 | 649 | lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14: 650 | version "4.17.15" 651 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" 652 | integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== 653 | 654 | log-symbols@^2.0.0: 655 | version "2.2.0" 656 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" 657 | integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== 658 | dependencies: 659 | chalk "^2.0.1" 660 | 661 | loud-rejection@^1.0.0: 662 | version "1.6.0" 663 | resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" 664 | integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= 665 | dependencies: 666 | currently-unhandled "^0.4.1" 667 | signal-exit "^3.0.0" 668 | 669 | map-obj@^1.0.0, map-obj@^1.0.1: 670 | version "1.0.1" 671 | resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" 672 | integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= 673 | 674 | meow@^3.7.0: 675 | version "3.7.0" 676 | resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" 677 | integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= 678 | dependencies: 679 | camelcase-keys "^2.0.0" 680 | decamelize "^1.1.2" 681 | loud-rejection "^1.0.0" 682 | map-obj "^1.0.1" 683 | minimist "^1.1.3" 684 | normalize-package-data "^2.3.4" 685 | object-assign "^4.0.1" 686 | read-pkg-up "^1.0.1" 687 | redent "^1.0.0" 688 | trim-newlines "^1.0.0" 689 | 690 | mimic-fn@^1.0.0: 691 | version "1.2.0" 692 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" 693 | integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== 694 | 695 | minimatch@^3.0.4: 696 | version "3.0.4" 697 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 698 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 699 | dependencies: 700 | brace-expansion "^1.1.7" 701 | 702 | minimist@0.0.8: 703 | version "0.0.8" 704 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 705 | integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= 706 | 707 | minimist@^1.1.3: 708 | version "1.2.0" 709 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 710 | integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= 711 | 712 | mkdirp@^0.5.1: 713 | version "0.5.1" 714 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 715 | integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= 716 | dependencies: 717 | minimist "0.0.8" 718 | 719 | ms@^2.1.1: 720 | version "2.1.2" 721 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 722 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 723 | 724 | mute-stream@0.0.7: 725 | version "0.0.7" 726 | resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" 727 | integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= 728 | 729 | natural-compare@^1.4.0: 730 | version "1.4.0" 731 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 732 | integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= 733 | 734 | nice-try@^1.0.4: 735 | version "1.0.5" 736 | resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" 737 | integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== 738 | 739 | normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: 740 | version "2.5.0" 741 | resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" 742 | integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== 743 | dependencies: 744 | hosted-git-info "^2.1.4" 745 | resolve "^1.10.0" 746 | semver "2 || 3 || 4 || 5" 747 | validate-npm-package-license "^3.0.1" 748 | 749 | number-is-nan@^1.0.0: 750 | version "1.0.1" 751 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 752 | integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= 753 | 754 | object-assign@^4.0.1: 755 | version "4.1.1" 756 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 757 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 758 | 759 | once@^1.3.0: 760 | version "1.4.0" 761 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 762 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 763 | dependencies: 764 | wrappy "1" 765 | 766 | onetime@^2.0.0: 767 | version "2.0.1" 768 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" 769 | integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= 770 | dependencies: 771 | mimic-fn "^1.0.0" 772 | 773 | optionator@^0.8.2: 774 | version "0.8.3" 775 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" 776 | integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== 777 | dependencies: 778 | deep-is "~0.1.3" 779 | fast-levenshtein "~2.0.6" 780 | levn "~0.3.0" 781 | prelude-ls "~1.1.2" 782 | type-check "~0.3.2" 783 | word-wrap "~1.2.3" 784 | 785 | os-tmpdir@~1.0.2: 786 | version "1.0.2" 787 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 788 | integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= 789 | 790 | parent-module@^1.0.0: 791 | version "1.0.1" 792 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 793 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 794 | dependencies: 795 | callsites "^3.0.0" 796 | 797 | parse-json@^2.2.0: 798 | version "2.2.0" 799 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" 800 | integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= 801 | dependencies: 802 | error-ex "^1.2.0" 803 | 804 | path-exists@^2.0.0: 805 | version "2.1.0" 806 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" 807 | integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= 808 | dependencies: 809 | pinkie-promise "^2.0.0" 810 | 811 | path-is-absolute@^1.0.0: 812 | version "1.0.1" 813 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 814 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 815 | 816 | path-is-inside@^1.0.2: 817 | version "1.0.2" 818 | resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" 819 | integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= 820 | 821 | path-key@^2.0.1: 822 | version "2.0.1" 823 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" 824 | integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= 825 | 826 | path-parse@^1.0.6: 827 | version "1.0.6" 828 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" 829 | integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== 830 | 831 | path-type@^1.0.0: 832 | version "1.1.0" 833 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" 834 | integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= 835 | dependencies: 836 | graceful-fs "^4.1.2" 837 | pify "^2.0.0" 838 | pinkie-promise "^2.0.0" 839 | 840 | pify@^2.0.0: 841 | version "2.3.0" 842 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" 843 | integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= 844 | 845 | pinkie-promise@^2.0.0: 846 | version "2.0.1" 847 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" 848 | integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= 849 | dependencies: 850 | pinkie "^2.0.0" 851 | 852 | pinkie@^2.0.0: 853 | version "2.0.4" 854 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" 855 | integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= 856 | 857 | plur@^2.1.2: 858 | version "2.1.2" 859 | resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" 860 | integrity sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo= 861 | dependencies: 862 | irregular-plurals "^1.0.0" 863 | 864 | prelude-ls@~1.1.2: 865 | version "1.1.2" 866 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" 867 | integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= 868 | 869 | prettier-linter-helpers@^1.0.0: 870 | version "1.0.0" 871 | resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" 872 | integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== 873 | dependencies: 874 | fast-diff "^1.1.2" 875 | 876 | prettier@^1.16.1: 877 | version "1.19.1" 878 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" 879 | integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== 880 | 881 | prettylint@^1.0.0: 882 | version "1.0.0" 883 | resolved "https://registry.yarnpkg.com/prettylint/-/prettylint-1.0.0.tgz#b71720ad9733e098fdd8ebea90c61cda33371aa1" 884 | integrity sha512-IjIAoGeIve8NQR6WbslnMs5rcnEVbJkZN/IXm302wNlSEo+3pIyxroy+3bkEFLP14prz1Aq1GGlKsX0UXHXuEQ== 885 | dependencies: 886 | eslint-formatter-pretty "^1.3.0" 887 | eslint-plugin-prettier "^2.2.0" 888 | globby "^6.1.0" 889 | ignore "^3.3.5" 890 | lines-and-columns "^1.1.6" 891 | meow "^3.7.0" 892 | tslib "^1.8.0" 893 | 894 | progress@^2.0.0: 895 | version "2.0.3" 896 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" 897 | integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== 898 | 899 | punycode@^2.1.0: 900 | version "2.1.1" 901 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 902 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 903 | 904 | read-pkg-up@^1.0.1: 905 | version "1.0.1" 906 | resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" 907 | integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= 908 | dependencies: 909 | find-up "^1.0.0" 910 | read-pkg "^1.0.0" 911 | 912 | read-pkg@^1.0.0: 913 | version "1.1.0" 914 | resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" 915 | integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= 916 | dependencies: 917 | load-json-file "^1.0.0" 918 | normalize-package-data "^2.3.2" 919 | path-type "^1.0.0" 920 | 921 | redent@^1.0.0: 922 | version "1.0.0" 923 | resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" 924 | integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= 925 | dependencies: 926 | indent-string "^2.1.0" 927 | strip-indent "^1.0.1" 928 | 929 | regexpp@^2.0.1: 930 | version "2.0.1" 931 | resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" 932 | integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== 933 | 934 | repeating@^2.0.0: 935 | version "2.0.1" 936 | resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" 937 | integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= 938 | dependencies: 939 | is-finite "^1.0.0" 940 | 941 | resolve-from@^4.0.0: 942 | version "4.0.0" 943 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 944 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 945 | 946 | resolve@^1.10.0: 947 | version "1.13.1" 948 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.13.1.tgz#be0aa4c06acd53083505abb35f4d66932ab35d16" 949 | integrity sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w== 950 | dependencies: 951 | path-parse "^1.0.6" 952 | 953 | restore-cursor@^2.0.0: 954 | version "2.0.0" 955 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" 956 | integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= 957 | dependencies: 958 | onetime "^2.0.0" 959 | signal-exit "^3.0.2" 960 | 961 | rimraf@2.6.3: 962 | version "2.6.3" 963 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" 964 | integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== 965 | dependencies: 966 | glob "^7.1.3" 967 | 968 | run-async@^2.2.0: 969 | version "2.3.0" 970 | resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" 971 | integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= 972 | dependencies: 973 | is-promise "^2.1.0" 974 | 975 | rxjs@^6.4.0: 976 | version "6.5.3" 977 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" 978 | integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== 979 | dependencies: 980 | tslib "^1.9.0" 981 | 982 | "safer-buffer@>= 2.1.2 < 3": 983 | version "2.1.2" 984 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 985 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 986 | 987 | "semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.5.1: 988 | version "5.7.1" 989 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" 990 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== 991 | 992 | shebang-command@^1.2.0: 993 | version "1.2.0" 994 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" 995 | integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= 996 | dependencies: 997 | shebang-regex "^1.0.0" 998 | 999 | shebang-regex@^1.0.0: 1000 | version "1.0.0" 1001 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" 1002 | integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= 1003 | 1004 | signal-exit@^3.0.0, signal-exit@^3.0.2: 1005 | version "3.0.2" 1006 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" 1007 | integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= 1008 | 1009 | slice-ansi@^2.1.0: 1010 | version "2.1.0" 1011 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" 1012 | integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== 1013 | dependencies: 1014 | ansi-styles "^3.2.0" 1015 | astral-regex "^1.0.0" 1016 | is-fullwidth-code-point "^2.0.0" 1017 | 1018 | spdx-correct@^3.0.0: 1019 | version "3.1.0" 1020 | resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" 1021 | integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== 1022 | dependencies: 1023 | spdx-expression-parse "^3.0.0" 1024 | spdx-license-ids "^3.0.0" 1025 | 1026 | spdx-exceptions@^2.1.0: 1027 | version "2.2.0" 1028 | resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" 1029 | integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== 1030 | 1031 | spdx-expression-parse@^3.0.0: 1032 | version "3.0.0" 1033 | resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" 1034 | integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== 1035 | dependencies: 1036 | spdx-exceptions "^2.1.0" 1037 | spdx-license-ids "^3.0.0" 1038 | 1039 | spdx-license-ids@^3.0.0: 1040 | version "3.0.5" 1041 | resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" 1042 | integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== 1043 | 1044 | sprintf-js@~1.0.2: 1045 | version "1.0.3" 1046 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 1047 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 1048 | 1049 | string-width@^2.0.0, string-width@^2.1.0: 1050 | version "2.1.1" 1051 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 1052 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== 1053 | dependencies: 1054 | is-fullwidth-code-point "^2.0.0" 1055 | strip-ansi "^4.0.0" 1056 | 1057 | string-width@^3.0.0: 1058 | version "3.1.0" 1059 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" 1060 | integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== 1061 | dependencies: 1062 | emoji-regex "^7.0.1" 1063 | is-fullwidth-code-point "^2.0.0" 1064 | strip-ansi "^5.1.0" 1065 | 1066 | strip-ansi@^4.0.0: 1067 | version "4.0.0" 1068 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 1069 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= 1070 | dependencies: 1071 | ansi-regex "^3.0.0" 1072 | 1073 | strip-ansi@^5.1.0: 1074 | version "5.2.0" 1075 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" 1076 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== 1077 | dependencies: 1078 | ansi-regex "^4.1.0" 1079 | 1080 | strip-bom@^2.0.0: 1081 | version "2.0.0" 1082 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" 1083 | integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= 1084 | dependencies: 1085 | is-utf8 "^0.2.0" 1086 | 1087 | strip-indent@^1.0.1: 1088 | version "1.0.1" 1089 | resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" 1090 | integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= 1091 | dependencies: 1092 | get-stdin "^4.0.1" 1093 | 1094 | strip-json-comments@^2.0.1: 1095 | version "2.0.1" 1096 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 1097 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= 1098 | 1099 | supports-color@^5.3.0: 1100 | version "5.5.0" 1101 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1102 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1103 | dependencies: 1104 | has-flag "^3.0.0" 1105 | 1106 | table@^5.2.3: 1107 | version "5.4.6" 1108 | resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" 1109 | integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== 1110 | dependencies: 1111 | ajv "^6.10.2" 1112 | lodash "^4.17.14" 1113 | slice-ansi "^2.1.0" 1114 | string-width "^3.0.0" 1115 | 1116 | text-table@^0.2.0: 1117 | version "0.2.0" 1118 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 1119 | integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= 1120 | 1121 | through@^2.3.6: 1122 | version "2.3.8" 1123 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 1124 | integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= 1125 | 1126 | tmp@^0.0.33: 1127 | version "0.0.33" 1128 | resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" 1129 | integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== 1130 | dependencies: 1131 | os-tmpdir "~1.0.2" 1132 | 1133 | trim-newlines@^1.0.0: 1134 | version "1.0.0" 1135 | resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" 1136 | integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= 1137 | 1138 | tslib@^1.8.0, tslib@^1.9.0: 1139 | version "1.10.0" 1140 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" 1141 | integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== 1142 | 1143 | type-check@~0.3.2: 1144 | version "0.3.2" 1145 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" 1146 | integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= 1147 | dependencies: 1148 | prelude-ls "~1.1.2" 1149 | 1150 | uri-js@^4.2.2: 1151 | version "4.2.2" 1152 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" 1153 | integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== 1154 | dependencies: 1155 | punycode "^2.1.0" 1156 | 1157 | validate-npm-package-license@^3.0.1: 1158 | version "3.0.4" 1159 | resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" 1160 | integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== 1161 | dependencies: 1162 | spdx-correct "^3.0.0" 1163 | spdx-expression-parse "^3.0.0" 1164 | 1165 | which@^1.2.9: 1166 | version "1.3.1" 1167 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" 1168 | integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== 1169 | dependencies: 1170 | isexe "^2.0.0" 1171 | 1172 | word-wrap@~1.2.3: 1173 | version "1.2.3" 1174 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" 1175 | integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== 1176 | 1177 | wrappy@1: 1178 | version "1.0.2" 1179 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1180 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1181 | 1182 | write@1.0.3: 1183 | version "1.0.3" 1184 | resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" 1185 | integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== 1186 | dependencies: 1187 | mkdirp "^0.5.1" 1188 | --------------------------------------------------------------------------------