├── .gitignore ├── LICENSE ├── README.md ├── demo ├── gulpfile.js └── src │ ├── banana-to-entry1.js │ ├── banana.js │ ├── deps │ ├── dep.js │ └── otherdep.js │ ├── entry1.js │ ├── entry2.js │ ├── recurseA.js │ ├── recurseB.js │ └── thinger.js ├── example.png ├── graph.js ├── index.js ├── package.json ├── plugin.js ├── reader.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | demo/dist/ 3 | node_modules/ 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Hello! 🚨 **You probably don't need this anymore** 🚨 as it was originally authored back in 2017. [Rollup](https://rollupjs.org/) has supported generating a minimum bundle graph _for a while now_. 2 | 3 | The README is left below for posterity. 4 | 5 | # srcgraph 6 | 7 | srcgraph code splits ES6 modules. 8 | It accepts multiple JS module entrypoints, and returns the minimum number of modules required to represent the source graph. 9 | If you want to know more, see [my talk from Polymer Summit 2017](https://www.youtube.com/watch?v=fIP4pjAqCtQ&feature=youtu.be&t=27m35s) (links to the discussion of srcgraph). 10 | 11 | srcgraph includes a Gulp plugin which generates said modules. 12 | It can also be run to generate loosely-coupled script tags that do not use `import` and `export.` 13 | 14 | ## Example 15 | 16 | 17 | 18 | On the left, we have an abstract dependency graph. 19 | Imagine that `entry1.js` looks like— 20 | 21 | ```js 22 | // entry1.js 23 | import './A.js'; 24 | ``` 25 | 26 | and `A.js` imports C, and D etc. 27 | 28 | The right side is the output of srcgraph. 29 | 30 | ### Process 31 | 32 | srcgraph walks the dependency graph, marking each node with the entry points that use it. 33 | Nodes that are used by only one entry point are merged into their module. 34 | 35 | However, the remaining nodes (D, E and F) can't be naïvely bundled into a big bag. 36 | Because D and E have unique ways in which they are used, we turn them into individual modules so that the entry points of D and E are still exposed. 37 | Conceptaully we've just made the D and E modules 'bigger' (well, D remains the same size). 38 | They still export the same entry points. 39 | 40 | ### Notes 41 | 42 | If we performed symbol renaming (i.e. so that `entry1.js` can safely import D and E, because the names 'could not collide'), it'd be possible to merge the two D and E modules together. 43 | This is, however, a simple approach that scales to any number of entry points. 44 | 45 | ## Usage 46 | 47 | ### Graph 48 | 49 | To determine the minimum number of modules needed for a complex dependency graph, include and use `graph.js`. 50 | (You can check out the code and run this yourself!) 51 | 52 | ```js 53 | const graph = require('./graph.js'); 54 | graph(['demo/src/entry1.js', 'demo/src/entry2.js']).then((modules) => { 55 | modules.forEach((module) => { 56 | console.info(module); 57 | }); 58 | // modules contains an array of: 59 | // Module{id: './test/entry1.js', srcs: ['./test/entry1.js', './test/A.js', './test/C.js']} 60 | // Module{id: './test/D.js', srcs: ['./test/D.js']} 61 | // .. and so on 62 | }); 63 | ``` 64 | 65 | These modules can be used as arguments to [Rollup](https://rollupjs.org/). 66 | Generate a matching number of modules that include only those src files, and assume all other dependencies are external. 67 | 68 | ### Gulp Plugin 69 | 70 | The Gulp plugin, provided in `plugin.js` (or as `require('srcgraph').gulp`, if you're using this via a package manager), invokes the graph algorithm as well as running Rollup. 71 | 72 | ```js 73 | const gulp = require('gulp'); 74 | const srcgraph = require('srcgraph').gulp; 75 | 76 | gulp.task('rollup', function() { 77 | const options = {}; 78 | return gulp.src(['path/to/your/entrypoints/*.js']) 79 | .pipe(srcgraph(options)) 80 | .pipe(gulp.dest('./dist')); 81 | }); 82 | ``` 83 | 84 | This will write out the minimum number of modules needed inside `dist`. 85 | 86 | If you specify the format as IIFE, then the same file will be generated, but they will simply create global `var` objects. 87 | You'll be responsible for including the files in the right order (unlike ES6 modules, which have import/export statements), but you'll see the same split. 88 | 89 | ```js 90 | const options = {format: 'iife'}; 91 | return gulp.src(['path/to/your/entrypoints/*.js']) 92 | .pipe(srcgraph(options)) 93 | .pipe(gulp.dest('./dist')); // generates code without import and export 94 | ``` 95 | 96 | ## Caveats 97 | 98 | If your ES6 module code relies on the ordering of import statements to run code, then srcgraph may not be for you. 99 | For example: 100 | 101 | ```js 102 | import './code-that-effects-window.js'; // makes window.blah 103 | import './code-that-uses-that-effect.js'; // calls window.blah() 104 | ``` 105 | 106 | If the first dependency is bundled but the second is not, then the second dependency will fail to run—`import` is hoisted, and always runs before other code. 107 | The output would look like: 108 | 109 | ```js 110 | window.blah = function() { 111 | // very important function 112 | }; 113 | import './code-that-uses-that-effect.js'; // calls window.blah(), but runs before any normal code 114 | ``` 115 | 116 | This is fairly uncommon, and the example is contrived, but effects all approaches to split bundling for ES6 modules. 117 | 118 | ## License 119 | 120 | This is available under an [Apache2 license](LICENSE). 121 | -------------------------------------------------------------------------------- /demo/gulpfile.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | const gulp = require('gulp'); 18 | const srcgraph = require('../plugin.js'); 19 | 20 | gulp.task('rollup', function() { 21 | const options = { 22 | format: 'es', 23 | }; 24 | return gulp.src(['src/entry*.js']) 25 | .pipe(srcgraph(options)) 26 | .pipe(gulp.dest('./dist')); 27 | }); 28 | 29 | gulp.task('default', ['rollup']); 30 | -------------------------------------------------------------------------------- /demo/src/banana-to-entry1.js: -------------------------------------------------------------------------------- 1 | import './entry1.js'; 2 | 3 | console.info('banana-to-entry1'); -------------------------------------------------------------------------------- /demo/src/banana.js: -------------------------------------------------------------------------------- 1 | 2 | import './thinger.js'; 3 | 4 | //import './banana.js'; // invalid, just for demo 5 | 6 | import './banana-to-entry1.js'; 7 | 8 | console.info('banana'); -------------------------------------------------------------------------------- /demo/src/deps/dep.js: -------------------------------------------------------------------------------- 1 | import './otherdep.js'; 2 | 3 | console.info('dep'); -------------------------------------------------------------------------------- /demo/src/deps/otherdep.js: -------------------------------------------------------------------------------- 1 | /** header for otherdep */ 2 | 3 | console.info('otherdep'); -------------------------------------------------------------------------------- /demo/src/entry1.js: -------------------------------------------------------------------------------- 1 | /** header for entry1 */ 2 | 3 | console.info('whatever, entry1 calling'); 4 | 5 | import './banana.js'; 6 | import './deps/dep.js'; 7 | -------------------------------------------------------------------------------- /demo/src/entry2.js: -------------------------------------------------------------------------------- 1 | import {thinger} from './thinger.js'; 2 | import './entry1.js'; 3 | import './deps/otherdep.js'; 4 | 5 | console.info('entry2', thinger()); -------------------------------------------------------------------------------- /demo/src/recurseA.js: -------------------------------------------------------------------------------- 1 | import './recurseB.js'; 2 | 3 | console.info('A'); -------------------------------------------------------------------------------- /demo/src/recurseB.js: -------------------------------------------------------------------------------- 1 | import './recurseA.js'; 2 | 3 | console.info('B'); -------------------------------------------------------------------------------- /demo/src/thinger.js: -------------------------------------------------------------------------------- 1 | 2 | console.info('tail'); 3 | 4 | function thinger() { 5 | console.info('thinger in thinger'); 6 | } 7 | 8 | export {thinger}; -------------------------------------------------------------------------------- /example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samthor/srcgraph/2e8843f8bb8341857668c77db2f61ae82192bb73/example.png -------------------------------------------------------------------------------- /graph.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | const reader = require('./reader.js'); 18 | const path = require('path'); 19 | 20 | class BiMap { 21 | /** 22 | * @param {!Map>} deps 23 | */ 24 | constructor(deps) { 25 | this.deps_ = deps; // TODO: copy 26 | 27 | /** @type {!Map>} */ 28 | this.incs_ = new Map(); 29 | 30 | for (const src of deps.keys()) { 31 | this.incs_.set(src, [src]); 32 | } 33 | deps.forEach((required, src) => { 34 | required.forEach((require) => { 35 | const l = this.incs_.get(require); 36 | if (l.indexOf(src) === -1) { 37 | l.push(src); 38 | } 39 | }); 40 | }); 41 | this.incs_.forEach((value) => value.sort()); 42 | } 43 | 44 | /** 45 | * @param {string} src 46 | * @return {!Array} the paths this file requires directly 47 | */ 48 | requires(src) { 49 | return this.deps_.get(src) || []; 50 | } 51 | 52 | /** 53 | * @param {string} src 54 | * @return {!Array} the paths that directly require this file 55 | */ 56 | requiredBy(src) { 57 | return this.incs_.get(src) || []; 58 | } 59 | } 60 | 61 | 62 | class Module { 63 | /** 64 | * @param {string} id 65 | * @param {!Array} srcs 66 | * @param {boolean=} entrypoint 67 | */ 68 | constructor(id, srcs, entrypoint=false) { 69 | this.id = id; 70 | this.srcs = srcs.slice(); 71 | this.entrypoint = entrypoint; 72 | } 73 | 74 | /** 75 | * @param {string} id 76 | * @param {?string=} pwd 77 | * @return {boolean} whether this script is external to this module 78 | */ 79 | external(id, pwd='.') { 80 | if (id.startsWith('./')) { 81 | // these are relative to the module file being evaluated, so don't have an opinion 82 | // e.g., 'foo/bar/test.js' importing './other.js' will see that literal passed here 83 | return undefined; 84 | } else if (!id.startsWith('/')) { 85 | // this is an unknown/unsupported module, it's definitely an extern 86 | return true; 87 | } 88 | const rel = './' + path.relative(pwd, id); 89 | return !this.srcs.includes(rel); 90 | } 91 | } 92 | 93 | /** 94 | * @param {!Array} entrypoints 95 | * @return {Promise>} 96 | */ 97 | module.exports = function(entrypoints) { 98 | entrypoints = entrypoints.map((entrypoint) => { 99 | return entrypoint.startsWith('./') ? entrypoint : './' + entrypoint; 100 | }); 101 | return reader(entrypoints).then((graph) => process(graph, entrypoints)); 102 | }; 103 | 104 | /** 105 | * @param {!Map>} graph 106 | * @param {!Array} entrypoints 107 | * @return {Promise>} 108 | */ 109 | function process(graph, entrypoints) { 110 | const map = new BiMap(graph); 111 | 112 | // walk over graph and set (1< { 115 | const pending = new Set([entrypoint]); 116 | pending.forEach((next) => { 117 | hashes.set(next, (hashes.get(next) || 0) | (1 << n)); 118 | map.requires(next).forEach((src) => pending.add(src)); 119 | }); 120 | }); 121 | 122 | // find all files in the same module 123 | const grow = (from) => { 124 | const hash = hashes.get(from); 125 | const wouldSplitSrc = (src) => { 126 | // entrypoints are always their own starting point 127 | if (entrypoints.includes(src)) { 128 | return true; 129 | } 130 | // checks that the src is the given hash, AND has inputs only matching that hash 131 | if (hashes.get(src) !== hash) { 132 | return true; 133 | } 134 | const all = map.requiredBy(src); 135 | return all.some((other) => hashes.get(other) !== hash); 136 | }; 137 | 138 | // not a module entrypoint 139 | if (!wouldSplitSrc(from)) { 140 | return null; 141 | } 142 | 143 | const include = [from]; 144 | const seen = new Set(include); 145 | 146 | for (let i = 0, curr; curr = include[i]; ++i) { 147 | const pending = map.requires(curr); 148 | for (let j = 0, cand; cand = pending[j]; ++j) { 149 | if (seen.has(cand)) { 150 | continue; 151 | } 152 | seen.add(cand); 153 | if (!wouldSplitSrc(cand)) { 154 | include.push(cand); 155 | } 156 | } 157 | } 158 | 159 | return include; 160 | }; 161 | 162 | const modules = []; 163 | hashes.forEach((hash, src) => { 164 | const srcs = grow(src); 165 | if (srcs) { 166 | const entrypoint = entrypoints.includes(src); 167 | modules.push(new Module(src, srcs, entrypoint)); 168 | } 169 | }); 170 | 171 | return modules; 172 | } 173 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | module.exports = { 18 | gulp: require('./plugin.js'), 19 | graph: require('./graph.js'), 20 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "srcgraph", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "Apache-2.0", 6 | "dependencies": { 7 | "acorn": "^5.1.1", 8 | "rollup": "^0.47.6", 9 | "gulp": "^3.9.1", 10 | "vinyl-sourcemaps-apply": "^0.2.1", 11 | "through2": "^2.0.3" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /plugin.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | const through = require('through2'); 18 | const graph = require('./graph.js'); 19 | const rollup = require('rollup'); 20 | const path = require('path'); 21 | const File = require('vinyl'); 22 | 23 | // TODO: pass around sourcemaps 24 | const sourcemaps = require('vinyl-sourcemaps-apply') 25 | 26 | module.exports = function(options) { 27 | options = Object.assign({ 28 | format: 'es', 29 | }, options); 30 | 31 | const entrypoints = []; 32 | 33 | const moduleNames = new Map(); 34 | function flattenModuleId(id) { 35 | const flat = id.replace(/[^\w]/g, '_'); 36 | 37 | let candidate = flat; 38 | let count = 0; 39 | while (moduleNames.has(candidate)) { 40 | candidate = flat + (++count); 41 | } 42 | moduleNames.set(id, candidate); 43 | return candidate; 44 | } 45 | 46 | function buffer(file, enc, cb) { 47 | if (file.isNull()) { 48 | return cb(null, file); 49 | } else if (file.isStream()) { 50 | return cb(new Error()); 51 | } 52 | entrypoints.push(file); 53 | cb(); 54 | } 55 | 56 | function end() { 57 | // graph wants relative paths 58 | const paths = entrypoints.map((file) => path.relative('.', file.path)); 59 | const absolutePaths = new Map(); 60 | 61 | const process = (moduleName, module) => { 62 | const rollupConf = { 63 | // TODO: local gulp logger? 64 | // onwarn: logger, 65 | entry: module.id, 66 | external: (id) => module.external(id), 67 | }; 68 | const bundleConf = { 69 | format: options.format, 70 | moduleName, 71 | sourceMap: true, 72 | globals: (id) => flattenModuleId(absolutePaths[id]), 73 | }; 74 | return rollup.rollup(rollupConf) 75 | .then((bundle) => bundle.generate(bundleConf)) 76 | .then((result) => { 77 | // got result module, push onto gulp output 78 | this.push(new File({ 79 | path: path.resolve(module.id), 80 | contents: new Buffer(result.code), 81 | })); 82 | }); 83 | }; 84 | 85 | return graph(paths).then((modules) => { 86 | return Promise.all(modules.map((module) => { 87 | // store absolute module path => relative module ID, so we can resolve globals for IIFEs 88 | absolutePaths[path.resolve(module.id)] = module.id; 89 | return process(flattenModuleId(module.id), module); 90 | })); 91 | }); 92 | } 93 | 94 | return new through.obj(buffer, function(cb) { 95 | end.call(this).then(() => cb(null)).catch((err) => cb(err)); 96 | }); 97 | }; 98 | -------------------------------------------------------------------------------- /reader.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | const acorn = require('acorn'); 18 | const walk = require('acorn/dist/walk'); 19 | const fs = require('fs'); 20 | const path = require('path'); 21 | 22 | const options = { 23 | sourceType: 'module', 24 | }; 25 | 26 | /** 27 | * @param {string} target 28 | * @return {!Promise} 29 | */ 30 | function readFile(target) { 31 | return new Promise((resolve, reject) => { 32 | fs.readFile(target, 'utf8', (err, data) => err ? reject(err) : resolve(data)); 33 | }); 34 | } 35 | 36 | /** 37 | * @param {string} 38 | * @return {string} 39 | */ 40 | function localResolve(src) { 41 | if (!src.startsWith('./')) { 42 | return './' + src; 43 | } 44 | return src; 45 | } 46 | 47 | /** 48 | * @param {string|!Promise} target 49 | * @return {!Promise>} return the direct deps of this file 50 | */ 51 | function importsForFile(target) { 52 | return readFile(target).then((data) => { 53 | const dir = path.dirname(target); 54 | 55 | const s = new Set(); 56 | walk.simple(acorn.parse(data, options), { 57 | ImportDeclaration(node) { 58 | const other = node.source.value; 59 | 60 | if (!other.startsWith('./') && !other.startsWith('../')) { 61 | // TODO: unsupported import type 62 | return; 63 | } 64 | 65 | const out = localResolve(path.join(dir, other)); 66 | if (out !== target) { 67 | s.add(out); 68 | } 69 | } 70 | }); 71 | 72 | return [...s]; 73 | }); 74 | } 75 | 76 | /** 77 | * Reads JS source files and returns a Map of their direct dependencies. 78 | * 79 | * @param {!Array} entrypoints 80 | * @return {!Map>} 81 | */ 82 | module.exports = function(entrypoints) { 83 | const all = new Map(); 84 | const pending = new Set(); 85 | 86 | return new Promise((resolve, reject) => { 87 | const maybeResolve = (target) => { 88 | pending.delete(target); 89 | pending.size || resolve(all); 90 | }; 91 | 92 | const push = (target) => { 93 | if (all.has(target)) { 94 | return null; 95 | } 96 | all.set(target, null); 97 | pending.add(target); 98 | 99 | return importsForFile(target) 100 | .then((imports) => { 101 | all.set(target, imports); 102 | imports.forEach(push); 103 | maybeResolve(target); 104 | }) 105 | .catch(reject); 106 | }; 107 | 108 | entrypoints.forEach(push); 109 | }); 110 | }; 111 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | acorn@^5.1.1: 6 | version "5.1.1" 7 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.1.tgz#53fe161111f912ab999ee887a90a0bc52822fd75" 8 | 9 | ansi-regex@^2.0.0: 10 | version "2.1.1" 11 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 12 | 13 | ansi-styles@^2.2.1: 14 | version "2.2.1" 15 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 16 | 17 | archy@^1.0.0: 18 | version "1.0.0" 19 | resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" 20 | 21 | arr-diff@^2.0.0: 22 | version "2.0.0" 23 | resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" 24 | dependencies: 25 | arr-flatten "^1.0.1" 26 | 27 | arr-flatten@^1.0.1: 28 | version "1.1.0" 29 | resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" 30 | 31 | array-differ@^1.0.0: 32 | version "1.0.0" 33 | resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" 34 | 35 | array-each@^1.0.1: 36 | version "1.0.1" 37 | resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" 38 | 39 | array-slice@^1.0.0: 40 | version "1.0.0" 41 | resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.0.0.tgz#e73034f00dcc1f40876008fd20feae77bd4b7c2f" 42 | 43 | array-uniq@^1.0.2: 44 | version "1.0.3" 45 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" 46 | 47 | array-unique@^0.2.1: 48 | version "0.2.1" 49 | resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" 50 | 51 | balanced-match@^1.0.0: 52 | version "1.0.0" 53 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 54 | 55 | beeper@^1.0.0: 56 | version "1.1.1" 57 | resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" 58 | 59 | brace-expansion@^1.0.0: 60 | version "1.1.8" 61 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" 62 | dependencies: 63 | balanced-match "^1.0.0" 64 | concat-map "0.0.1" 65 | 66 | braces@^1.8.2: 67 | version "1.8.5" 68 | resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" 69 | dependencies: 70 | expand-range "^1.8.1" 71 | preserve "^0.2.0" 72 | repeat-element "^1.1.2" 73 | 74 | chalk@^1.0.0, chalk@^1.1.1: 75 | version "1.1.3" 76 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 77 | dependencies: 78 | ansi-styles "^2.2.1" 79 | escape-string-regexp "^1.0.2" 80 | has-ansi "^2.0.0" 81 | strip-ansi "^3.0.0" 82 | supports-color "^2.0.0" 83 | 84 | clone-stats@^0.0.1: 85 | version "0.0.1" 86 | resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" 87 | 88 | clone@^0.2.0: 89 | version "0.2.0" 90 | resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" 91 | 92 | clone@^1.0.0, clone@^1.0.2: 93 | version "1.0.2" 94 | resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" 95 | 96 | concat-map@0.0.1: 97 | version "0.0.1" 98 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 99 | 100 | core-util-is@~1.0.0: 101 | version "1.0.2" 102 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 103 | 104 | dateformat@^2.0.0: 105 | version "2.0.0" 106 | resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.0.0.tgz#2743e3abb5c3fc2462e527dca445e04e9f4dee17" 107 | 108 | defaults@^1.0.0: 109 | version "1.0.3" 110 | resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" 111 | dependencies: 112 | clone "^1.0.2" 113 | 114 | deprecated@^0.0.1: 115 | version "0.0.1" 116 | resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19" 117 | 118 | detect-file@^0.1.0: 119 | version "0.1.0" 120 | resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-0.1.0.tgz#4935dedfd9488648e006b0129566e9386711ea63" 121 | dependencies: 122 | fs-exists-sync "^0.1.0" 123 | 124 | duplexer2@0.0.2: 125 | version "0.0.2" 126 | resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" 127 | dependencies: 128 | readable-stream "~1.1.9" 129 | 130 | end-of-stream@~0.1.5: 131 | version "0.1.5" 132 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf" 133 | dependencies: 134 | once "~1.3.0" 135 | 136 | escape-string-regexp@^1.0.2: 137 | version "1.0.5" 138 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 139 | 140 | expand-brackets@^0.1.4: 141 | version "0.1.5" 142 | resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" 143 | dependencies: 144 | is-posix-bracket "^0.1.0" 145 | 146 | expand-range@^1.8.1: 147 | version "1.8.2" 148 | resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" 149 | dependencies: 150 | fill-range "^2.1.0" 151 | 152 | expand-tilde@^1.2.2: 153 | version "1.2.2" 154 | resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449" 155 | dependencies: 156 | os-homedir "^1.0.1" 157 | 158 | expand-tilde@^2.0.2: 159 | version "2.0.2" 160 | resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" 161 | dependencies: 162 | homedir-polyfill "^1.0.1" 163 | 164 | extend@^3.0.0: 165 | version "3.0.1" 166 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" 167 | 168 | extglob@^0.3.1: 169 | version "0.3.2" 170 | resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" 171 | dependencies: 172 | is-extglob "^1.0.0" 173 | 174 | fancy-log@^1.1.0: 175 | version "1.3.0" 176 | resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948" 177 | dependencies: 178 | chalk "^1.1.1" 179 | time-stamp "^1.0.0" 180 | 181 | filename-regex@^2.0.0: 182 | version "2.0.1" 183 | resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" 184 | 185 | fill-range@^2.1.0: 186 | version "2.2.3" 187 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" 188 | dependencies: 189 | is-number "^2.1.0" 190 | isobject "^2.0.0" 191 | randomatic "^1.1.3" 192 | repeat-element "^1.1.2" 193 | repeat-string "^1.5.2" 194 | 195 | find-index@^0.1.1: 196 | version "0.1.1" 197 | resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" 198 | 199 | findup-sync@^0.4.2: 200 | version "0.4.3" 201 | resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.4.3.tgz#40043929e7bc60adf0b7f4827c4c6e75a0deca12" 202 | dependencies: 203 | detect-file "^0.1.0" 204 | is-glob "^2.0.1" 205 | micromatch "^2.3.7" 206 | resolve-dir "^0.1.0" 207 | 208 | fined@^1.0.1: 209 | version "1.1.0" 210 | resolved "https://registry.yarnpkg.com/fined/-/fined-1.1.0.tgz#b37dc844b76a2f5e7081e884f7c0ae344f153476" 211 | dependencies: 212 | expand-tilde "^2.0.2" 213 | is-plain-object "^2.0.3" 214 | object.defaults "^1.1.0" 215 | object.pick "^1.2.0" 216 | parse-filepath "^1.0.1" 217 | 218 | first-chunk-stream@^1.0.0: 219 | version "1.0.0" 220 | resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" 221 | 222 | flagged-respawn@^0.3.2: 223 | version "0.3.2" 224 | resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-0.3.2.tgz#ff191eddcd7088a675b2610fffc976be9b8074b5" 225 | 226 | for-in@^1.0.1: 227 | version "1.0.2" 228 | resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" 229 | 230 | for-own@^0.1.4: 231 | version "0.1.5" 232 | resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" 233 | dependencies: 234 | for-in "^1.0.1" 235 | 236 | for-own@^1.0.0: 237 | version "1.0.0" 238 | resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" 239 | dependencies: 240 | for-in "^1.0.1" 241 | 242 | fs-exists-sync@^0.1.0: 243 | version "0.1.0" 244 | resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" 245 | 246 | gaze@^0.5.1: 247 | version "0.5.2" 248 | resolved "https://registry.yarnpkg.com/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f" 249 | dependencies: 250 | globule "~0.1.0" 251 | 252 | glob-base@^0.3.0: 253 | version "0.3.0" 254 | resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" 255 | dependencies: 256 | glob-parent "^2.0.0" 257 | is-glob "^2.0.0" 258 | 259 | glob-parent@^2.0.0: 260 | version "2.0.0" 261 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" 262 | dependencies: 263 | is-glob "^2.0.0" 264 | 265 | glob-stream@^3.1.5: 266 | version "3.1.18" 267 | resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b" 268 | dependencies: 269 | glob "^4.3.1" 270 | glob2base "^0.0.12" 271 | minimatch "^2.0.1" 272 | ordered-read-streams "^0.1.0" 273 | through2 "^0.6.1" 274 | unique-stream "^1.0.0" 275 | 276 | glob-watcher@^0.0.6: 277 | version "0.0.6" 278 | resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-0.0.6.tgz#b95b4a8df74b39c83298b0c05c978b4d9a3b710b" 279 | dependencies: 280 | gaze "^0.5.1" 281 | 282 | glob2base@^0.0.12: 283 | version "0.0.12" 284 | resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56" 285 | dependencies: 286 | find-index "^0.1.1" 287 | 288 | glob@^4.3.1: 289 | version "4.5.3" 290 | resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" 291 | dependencies: 292 | inflight "^1.0.4" 293 | inherits "2" 294 | minimatch "^2.0.1" 295 | once "^1.3.0" 296 | 297 | glob@~3.1.21: 298 | version "3.1.21" 299 | resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" 300 | dependencies: 301 | graceful-fs "~1.2.0" 302 | inherits "1" 303 | minimatch "~0.2.11" 304 | 305 | global-modules@^0.2.3: 306 | version "0.2.3" 307 | resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d" 308 | dependencies: 309 | global-prefix "^0.1.4" 310 | is-windows "^0.2.0" 311 | 312 | global-prefix@^0.1.4: 313 | version "0.1.5" 314 | resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f" 315 | dependencies: 316 | homedir-polyfill "^1.0.0" 317 | ini "^1.3.4" 318 | is-windows "^0.2.0" 319 | which "^1.2.12" 320 | 321 | globule@~0.1.0: 322 | version "0.1.0" 323 | resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" 324 | dependencies: 325 | glob "~3.1.21" 326 | lodash "~1.0.1" 327 | minimatch "~0.2.11" 328 | 329 | glogg@^1.0.0: 330 | version "1.0.0" 331 | resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5" 332 | dependencies: 333 | sparkles "^1.0.0" 334 | 335 | graceful-fs@^3.0.0: 336 | version "3.0.11" 337 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" 338 | dependencies: 339 | natives "^1.1.0" 340 | 341 | graceful-fs@~1.2.0: 342 | version "1.2.3" 343 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" 344 | 345 | gulp-util@^3.0.0: 346 | version "3.0.8" 347 | resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" 348 | dependencies: 349 | array-differ "^1.0.0" 350 | array-uniq "^1.0.2" 351 | beeper "^1.0.0" 352 | chalk "^1.0.0" 353 | dateformat "^2.0.0" 354 | fancy-log "^1.1.0" 355 | gulplog "^1.0.0" 356 | has-gulplog "^0.1.0" 357 | lodash._reescape "^3.0.0" 358 | lodash._reevaluate "^3.0.0" 359 | lodash._reinterpolate "^3.0.0" 360 | lodash.template "^3.0.0" 361 | minimist "^1.1.0" 362 | multipipe "^0.1.2" 363 | object-assign "^3.0.0" 364 | replace-ext "0.0.1" 365 | through2 "^2.0.0" 366 | vinyl "^0.5.0" 367 | 368 | gulp@^3.9.1: 369 | version "3.9.1" 370 | resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4" 371 | dependencies: 372 | archy "^1.0.0" 373 | chalk "^1.0.0" 374 | deprecated "^0.0.1" 375 | gulp-util "^3.0.0" 376 | interpret "^1.0.0" 377 | liftoff "^2.1.0" 378 | minimist "^1.1.0" 379 | orchestrator "^0.3.0" 380 | pretty-hrtime "^1.0.0" 381 | semver "^4.1.0" 382 | tildify "^1.0.0" 383 | v8flags "^2.0.2" 384 | vinyl-fs "^0.3.0" 385 | 386 | gulplog@^1.0.0: 387 | version "1.0.0" 388 | resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" 389 | dependencies: 390 | glogg "^1.0.0" 391 | 392 | has-ansi@^2.0.0: 393 | version "2.0.0" 394 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 395 | dependencies: 396 | ansi-regex "^2.0.0" 397 | 398 | has-gulplog@^0.1.0: 399 | version "0.1.0" 400 | resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" 401 | dependencies: 402 | sparkles "^1.0.0" 403 | 404 | homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1: 405 | version "1.0.1" 406 | resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" 407 | dependencies: 408 | parse-passwd "^1.0.0" 409 | 410 | inflight@^1.0.4: 411 | version "1.0.6" 412 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 413 | dependencies: 414 | once "^1.3.0" 415 | wrappy "1" 416 | 417 | inherits@1: 418 | version "1.0.2" 419 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" 420 | 421 | inherits@2, inherits@~2.0.1, inherits@~2.0.3: 422 | version "2.0.3" 423 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 424 | 425 | ini@^1.3.4: 426 | version "1.3.4" 427 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" 428 | 429 | interpret@^1.0.0: 430 | version "1.0.3" 431 | resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90" 432 | 433 | is-absolute@^0.2.3: 434 | version "0.2.6" 435 | resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb" 436 | dependencies: 437 | is-relative "^0.2.1" 438 | is-windows "^0.2.0" 439 | 440 | is-buffer@^1.1.5: 441 | version "1.1.5" 442 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" 443 | 444 | is-dotfile@^1.0.0: 445 | version "1.0.3" 446 | resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" 447 | 448 | is-equal-shallow@^0.1.3: 449 | version "0.1.3" 450 | resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" 451 | dependencies: 452 | is-primitive "^2.0.0" 453 | 454 | is-extendable@^0.1.1: 455 | version "0.1.1" 456 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" 457 | 458 | is-extglob@^1.0.0: 459 | version "1.0.0" 460 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" 461 | 462 | is-glob@^2.0.0, is-glob@^2.0.1: 463 | version "2.0.1" 464 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" 465 | dependencies: 466 | is-extglob "^1.0.0" 467 | 468 | is-number@^2.1.0: 469 | version "2.1.0" 470 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" 471 | dependencies: 472 | kind-of "^3.0.2" 473 | 474 | is-number@^3.0.0: 475 | version "3.0.0" 476 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" 477 | dependencies: 478 | kind-of "^3.0.2" 479 | 480 | is-plain-object@^2.0.3: 481 | version "2.0.4" 482 | resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" 483 | dependencies: 484 | isobject "^3.0.1" 485 | 486 | is-posix-bracket@^0.1.0: 487 | version "0.1.1" 488 | resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" 489 | 490 | is-primitive@^2.0.0: 491 | version "2.0.0" 492 | resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" 493 | 494 | is-relative@^0.2.1: 495 | version "0.2.1" 496 | resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5" 497 | dependencies: 498 | is-unc-path "^0.1.1" 499 | 500 | is-unc-path@^0.1.1: 501 | version "0.1.2" 502 | resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-0.1.2.tgz#6ab053a72573c10250ff416a3814c35178af39b9" 503 | dependencies: 504 | unc-path-regex "^0.1.0" 505 | 506 | is-utf8@^0.2.0: 507 | version "0.2.1" 508 | resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" 509 | 510 | is-windows@^0.2.0: 511 | version "0.2.0" 512 | resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" 513 | 514 | isarray@0.0.1: 515 | version "0.0.1" 516 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 517 | 518 | isarray@1.0.0, isarray@~1.0.0: 519 | version "1.0.0" 520 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 521 | 522 | isexe@^2.0.0: 523 | version "2.0.0" 524 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 525 | 526 | isobject@^2.0.0, isobject@^2.1.0: 527 | version "2.1.0" 528 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 529 | dependencies: 530 | isarray "1.0.0" 531 | 532 | isobject@^3.0.0, isobject@^3.0.1: 533 | version "3.0.1" 534 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" 535 | 536 | kind-of@^3.0.2: 537 | version "3.2.2" 538 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" 539 | dependencies: 540 | is-buffer "^1.1.5" 541 | 542 | kind-of@^4.0.0: 543 | version "4.0.0" 544 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" 545 | dependencies: 546 | is-buffer "^1.1.5" 547 | 548 | liftoff@^2.1.0: 549 | version "2.3.0" 550 | resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.3.0.tgz#a98f2ff67183d8ba7cfaca10548bd7ff0550b385" 551 | dependencies: 552 | extend "^3.0.0" 553 | findup-sync "^0.4.2" 554 | fined "^1.0.1" 555 | flagged-respawn "^0.3.2" 556 | lodash.isplainobject "^4.0.4" 557 | lodash.isstring "^4.0.1" 558 | lodash.mapvalues "^4.4.0" 559 | rechoir "^0.6.2" 560 | resolve "^1.1.7" 561 | 562 | lodash._basecopy@^3.0.0: 563 | version "3.0.1" 564 | resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" 565 | 566 | lodash._basetostring@^3.0.0: 567 | version "3.0.1" 568 | resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" 569 | 570 | lodash._basevalues@^3.0.0: 571 | version "3.0.0" 572 | resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" 573 | 574 | lodash._getnative@^3.0.0: 575 | version "3.9.1" 576 | resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" 577 | 578 | lodash._isiterateecall@^3.0.0: 579 | version "3.0.9" 580 | resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" 581 | 582 | lodash._reescape@^3.0.0: 583 | version "3.0.0" 584 | resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" 585 | 586 | lodash._reevaluate@^3.0.0: 587 | version "3.0.0" 588 | resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" 589 | 590 | lodash._reinterpolate@^3.0.0: 591 | version "3.0.0" 592 | resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" 593 | 594 | lodash._root@^3.0.0: 595 | version "3.0.1" 596 | resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" 597 | 598 | lodash.escape@^3.0.0: 599 | version "3.2.0" 600 | resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" 601 | dependencies: 602 | lodash._root "^3.0.0" 603 | 604 | lodash.isarguments@^3.0.0: 605 | version "3.1.0" 606 | resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" 607 | 608 | lodash.isarray@^3.0.0: 609 | version "3.0.4" 610 | resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" 611 | 612 | lodash.isplainobject@^4.0.4: 613 | version "4.0.6" 614 | resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" 615 | 616 | lodash.isstring@^4.0.1: 617 | version "4.0.1" 618 | resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" 619 | 620 | lodash.keys@^3.0.0: 621 | version "3.1.2" 622 | resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" 623 | dependencies: 624 | lodash._getnative "^3.0.0" 625 | lodash.isarguments "^3.0.0" 626 | lodash.isarray "^3.0.0" 627 | 628 | lodash.mapvalues@^4.4.0: 629 | version "4.6.0" 630 | resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" 631 | 632 | lodash.restparam@^3.0.0: 633 | version "3.6.1" 634 | resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" 635 | 636 | lodash.template@^3.0.0: 637 | version "3.6.2" 638 | resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" 639 | dependencies: 640 | lodash._basecopy "^3.0.0" 641 | lodash._basetostring "^3.0.0" 642 | lodash._basevalues "^3.0.0" 643 | lodash._isiterateecall "^3.0.0" 644 | lodash._reinterpolate "^3.0.0" 645 | lodash.escape "^3.0.0" 646 | lodash.keys "^3.0.0" 647 | lodash.restparam "^3.0.0" 648 | lodash.templatesettings "^3.0.0" 649 | 650 | lodash.templatesettings@^3.0.0: 651 | version "3.1.1" 652 | resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" 653 | dependencies: 654 | lodash._reinterpolate "^3.0.0" 655 | lodash.escape "^3.0.0" 656 | 657 | lodash@~1.0.1: 658 | version "1.0.2" 659 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" 660 | 661 | lru-cache@2: 662 | version "2.7.3" 663 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" 664 | 665 | map-cache@^0.2.0: 666 | version "0.2.2" 667 | resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" 668 | 669 | micromatch@^2.3.7: 670 | version "2.3.11" 671 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" 672 | dependencies: 673 | arr-diff "^2.0.0" 674 | array-unique "^0.2.1" 675 | braces "^1.8.2" 676 | expand-brackets "^0.1.4" 677 | extglob "^0.3.1" 678 | filename-regex "^2.0.0" 679 | is-extglob "^1.0.0" 680 | is-glob "^2.0.1" 681 | kind-of "^3.0.2" 682 | normalize-path "^2.0.1" 683 | object.omit "^2.0.0" 684 | parse-glob "^3.0.4" 685 | regex-cache "^0.4.2" 686 | 687 | minimatch@^2.0.1: 688 | version "2.0.10" 689 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" 690 | dependencies: 691 | brace-expansion "^1.0.0" 692 | 693 | minimatch@~0.2.11: 694 | version "0.2.14" 695 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" 696 | dependencies: 697 | lru-cache "2" 698 | sigmund "~1.0.0" 699 | 700 | minimist@0.0.8: 701 | version "0.0.8" 702 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 703 | 704 | minimist@^1.1.0: 705 | version "1.2.0" 706 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 707 | 708 | mkdirp@^0.5.0: 709 | version "0.5.1" 710 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 711 | dependencies: 712 | minimist "0.0.8" 713 | 714 | multipipe@^0.1.2: 715 | version "0.1.2" 716 | resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" 717 | dependencies: 718 | duplexer2 "0.0.2" 719 | 720 | natives@^1.1.0: 721 | version "1.1.0" 722 | resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.0.tgz#e9ff841418a6b2ec7a495e939984f78f163e6e31" 723 | 724 | normalize-path@^2.0.1: 725 | version "2.1.1" 726 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" 727 | dependencies: 728 | remove-trailing-separator "^1.0.1" 729 | 730 | object-assign@^3.0.0: 731 | version "3.0.0" 732 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" 733 | 734 | object.defaults@^1.1.0: 735 | version "1.1.0" 736 | resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" 737 | dependencies: 738 | array-each "^1.0.1" 739 | array-slice "^1.0.0" 740 | for-own "^1.0.0" 741 | isobject "^3.0.0" 742 | 743 | object.omit@^2.0.0: 744 | version "2.0.1" 745 | resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" 746 | dependencies: 747 | for-own "^0.1.4" 748 | is-extendable "^0.1.1" 749 | 750 | object.pick@^1.2.0: 751 | version "1.2.0" 752 | resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.2.0.tgz#b5392bee9782da6d9fb7d6afaf539779f1234c2b" 753 | dependencies: 754 | isobject "^2.1.0" 755 | 756 | once@^1.3.0: 757 | version "1.4.0" 758 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 759 | dependencies: 760 | wrappy "1" 761 | 762 | once@~1.3.0: 763 | version "1.3.3" 764 | resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" 765 | dependencies: 766 | wrappy "1" 767 | 768 | orchestrator@^0.3.0: 769 | version "0.3.8" 770 | resolved "https://registry.yarnpkg.com/orchestrator/-/orchestrator-0.3.8.tgz#14e7e9e2764f7315fbac184e506c7aa6df94ad7e" 771 | dependencies: 772 | end-of-stream "~0.1.5" 773 | sequencify "~0.0.7" 774 | stream-consume "~0.1.0" 775 | 776 | ordered-read-streams@^0.1.0: 777 | version "0.1.0" 778 | resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126" 779 | 780 | os-homedir@^1.0.0, os-homedir@^1.0.1: 781 | version "1.0.2" 782 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 783 | 784 | parse-filepath@^1.0.1: 785 | version "1.0.1" 786 | resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.1.tgz#159d6155d43904d16c10ef698911da1e91969b73" 787 | dependencies: 788 | is-absolute "^0.2.3" 789 | map-cache "^0.2.0" 790 | path-root "^0.1.1" 791 | 792 | parse-glob@^3.0.4: 793 | version "3.0.4" 794 | resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" 795 | dependencies: 796 | glob-base "^0.3.0" 797 | is-dotfile "^1.0.0" 798 | is-extglob "^1.0.0" 799 | is-glob "^2.0.0" 800 | 801 | parse-passwd@^1.0.0: 802 | version "1.0.0" 803 | resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" 804 | 805 | path-parse@^1.0.5: 806 | version "1.0.5" 807 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" 808 | 809 | path-root-regex@^0.1.0: 810 | version "0.1.2" 811 | resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" 812 | 813 | path-root@^0.1.1: 814 | version "0.1.1" 815 | resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" 816 | dependencies: 817 | path-root-regex "^0.1.0" 818 | 819 | preserve@^0.2.0: 820 | version "0.2.0" 821 | resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" 822 | 823 | pretty-hrtime@^1.0.0: 824 | version "1.0.3" 825 | resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" 826 | 827 | process-nextick-args@~1.0.6: 828 | version "1.0.7" 829 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" 830 | 831 | randomatic@^1.1.3: 832 | version "1.1.7" 833 | resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" 834 | dependencies: 835 | is-number "^3.0.0" 836 | kind-of "^4.0.0" 837 | 838 | "readable-stream@>=1.0.33-1 <1.1.0-0": 839 | version "1.0.34" 840 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" 841 | dependencies: 842 | core-util-is "~1.0.0" 843 | inherits "~2.0.1" 844 | isarray "0.0.1" 845 | string_decoder "~0.10.x" 846 | 847 | readable-stream@^2.1.5: 848 | version "2.3.3" 849 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" 850 | dependencies: 851 | core-util-is "~1.0.0" 852 | inherits "~2.0.3" 853 | isarray "~1.0.0" 854 | process-nextick-args "~1.0.6" 855 | safe-buffer "~5.1.1" 856 | string_decoder "~1.0.3" 857 | util-deprecate "~1.0.1" 858 | 859 | readable-stream@~1.1.9: 860 | version "1.1.14" 861 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" 862 | dependencies: 863 | core-util-is "~1.0.0" 864 | inherits "~2.0.1" 865 | isarray "0.0.1" 866 | string_decoder "~0.10.x" 867 | 868 | rechoir@^0.6.2: 869 | version "0.6.2" 870 | resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" 871 | dependencies: 872 | resolve "^1.1.6" 873 | 874 | regex-cache@^0.4.2: 875 | version "0.4.3" 876 | resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" 877 | dependencies: 878 | is-equal-shallow "^0.1.3" 879 | is-primitive "^2.0.0" 880 | 881 | remove-trailing-separator@^1.0.1: 882 | version "1.1.0" 883 | resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" 884 | 885 | repeat-element@^1.1.2: 886 | version "1.1.2" 887 | resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" 888 | 889 | repeat-string@^1.5.2: 890 | version "1.6.1" 891 | resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" 892 | 893 | replace-ext@0.0.1: 894 | version "0.0.1" 895 | resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" 896 | 897 | resolve-dir@^0.1.0: 898 | version "0.1.1" 899 | resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e" 900 | dependencies: 901 | expand-tilde "^1.2.2" 902 | global-modules "^0.2.3" 903 | 904 | resolve@^1.1.6, resolve@^1.1.7: 905 | version "1.4.0" 906 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" 907 | dependencies: 908 | path-parse "^1.0.5" 909 | 910 | rollup@^0.47.6: 911 | version "0.47.6" 912 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.47.6.tgz#83b90a1890dd3321a3f8d0b2bd216e88483f33de" 913 | 914 | safe-buffer@~5.1.0, safe-buffer@~5.1.1: 915 | version "5.1.1" 916 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" 917 | 918 | semver@^4.1.0: 919 | version "4.3.6" 920 | resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" 921 | 922 | sequencify@~0.0.7: 923 | version "0.0.7" 924 | resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c" 925 | 926 | sigmund@~1.0.0: 927 | version "1.0.1" 928 | resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" 929 | 930 | source-map@^0.5.1: 931 | version "0.5.6" 932 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" 933 | 934 | sparkles@^1.0.0: 935 | version "1.0.0" 936 | resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" 937 | 938 | stream-consume@~0.1.0: 939 | version "0.1.0" 940 | resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" 941 | 942 | string_decoder@~0.10.x: 943 | version "0.10.31" 944 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 945 | 946 | string_decoder@~1.0.3: 947 | version "1.0.3" 948 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" 949 | dependencies: 950 | safe-buffer "~5.1.0" 951 | 952 | strip-ansi@^3.0.0: 953 | version "3.0.1" 954 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 955 | dependencies: 956 | ansi-regex "^2.0.0" 957 | 958 | strip-bom@^1.0.0: 959 | version "1.0.0" 960 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794" 961 | dependencies: 962 | first-chunk-stream "^1.0.0" 963 | is-utf8 "^0.2.0" 964 | 965 | supports-color@^2.0.0: 966 | version "2.0.0" 967 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 968 | 969 | through2@^0.6.1: 970 | version "0.6.5" 971 | resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" 972 | dependencies: 973 | readable-stream ">=1.0.33-1 <1.1.0-0" 974 | xtend ">=4.0.0 <4.1.0-0" 975 | 976 | through2@^2.0.0, through2@^2.0.3: 977 | version "2.0.3" 978 | resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" 979 | dependencies: 980 | readable-stream "^2.1.5" 981 | xtend "~4.0.1" 982 | 983 | tildify@^1.0.0: 984 | version "1.2.0" 985 | resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" 986 | dependencies: 987 | os-homedir "^1.0.0" 988 | 989 | time-stamp@^1.0.0: 990 | version "1.1.0" 991 | resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" 992 | 993 | unc-path-regex@^0.1.0: 994 | version "0.1.2" 995 | resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" 996 | 997 | unique-stream@^1.0.0: 998 | version "1.0.0" 999 | resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b" 1000 | 1001 | user-home@^1.1.1: 1002 | version "1.1.1" 1003 | resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" 1004 | 1005 | util-deprecate@~1.0.1: 1006 | version "1.0.2" 1007 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1008 | 1009 | v8flags@^2.0.2: 1010 | version "2.1.1" 1011 | resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" 1012 | dependencies: 1013 | user-home "^1.1.1" 1014 | 1015 | vinyl-fs@^0.3.0: 1016 | version "0.3.14" 1017 | resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6" 1018 | dependencies: 1019 | defaults "^1.0.0" 1020 | glob-stream "^3.1.5" 1021 | glob-watcher "^0.0.6" 1022 | graceful-fs "^3.0.0" 1023 | mkdirp "^0.5.0" 1024 | strip-bom "^1.0.0" 1025 | through2 "^0.6.1" 1026 | vinyl "^0.4.0" 1027 | 1028 | vinyl-sourcemaps-apply@^0.2.1: 1029 | version "0.2.1" 1030 | resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" 1031 | dependencies: 1032 | source-map "^0.5.1" 1033 | 1034 | vinyl@^0.4.0: 1035 | version "0.4.6" 1036 | resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" 1037 | dependencies: 1038 | clone "^0.2.0" 1039 | clone-stats "^0.0.1" 1040 | 1041 | vinyl@^0.5.0: 1042 | version "0.5.3" 1043 | resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" 1044 | dependencies: 1045 | clone "^1.0.0" 1046 | clone-stats "^0.0.1" 1047 | replace-ext "0.0.1" 1048 | 1049 | which@^1.2.12: 1050 | version "1.3.0" 1051 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" 1052 | dependencies: 1053 | isexe "^2.0.0" 1054 | 1055 | wrappy@1: 1056 | version "1.0.2" 1057 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1058 | 1059 | "xtend@>=4.0.0 <4.1.0-0", xtend@~4.0.1: 1060 | version "4.0.1" 1061 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" 1062 | --------------------------------------------------------------------------------