├── .babelrc ├── .eslintrc ├── .gitignore ├── .npmignore ├── CONTRIBUTING.md ├── README.md ├── build ├── d3-loom.js ├── d3-loom.js.map └── d3-loom.min.js ├── example ├── index.html └── lotr_words_location.json ├── index.js ├── lotr.png ├── package-lock.json ├── package.json ├── rollup.config.js └── src ├── compare-value.js ├── constant.js ├── loom.js └── string.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ "es2015" ] 3 | } -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb-base", 3 | "rules": { 4 | "no-param-reassign": "off", 5 | "no-use-before-define": "off", 6 | "func-names": "off", 7 | "no-return-assign": "off", 8 | "no-mixed-operators": "off", 9 | "comma-dangle": "off", 10 | "space-before-function-paren": "off" 11 | } 12 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | npm-debug.log 4 | *.tgz -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | build/*.zip 2 | test/ -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | Any feedback, questions, bug reports, and general discussions are most welcome. 4 | 5 | Please [submit an issue](https://github.com/nbremer/d3-loom/issues/new) to start a discussion. 6 | 7 | If you've created something using d3-loom, we'd love to hear about it! Please [submit an issue](https://github.com/nbremer/d3-loom/issues/new) to request adding a link in the README to your example. 8 | 9 | To get started with development, 10 | 11 | * clone the repository, 12 | * run `npm install` to install dependencies -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # d3-loom 2 | 3 | This is a d3 plugin to create a "loom" visualization. For an extensive explanation of the effects of all the settings decribed farther below, please see the [blog/tutorial I wrote about the loom here](https://www.visualcinnamon.com/2017/08/d3-loom.html). 4 | 5 | [![The words spoken by the Fellowship member during all 3 movies](lotr.png "The words spoken by the Fellowship member during all 3 movies")](https://bl.ocks.org/nbremer/4530f11952a3ef7e007ad6ef93d5adb3) 6 | 7 | The loom layout is meant to create a chart with a group of entities in the center and different group of entities on the outside. They are connected by *strings* where the thickness of the string on the outside represents the connection (i.e. value) of the inner and outer entity. 8 | 9 | Or in the words of Robert Kosara 10 | > One chart to rule them all, one chart to find them; one chart to bring them all and in the darkness bind them 11 | 12 | For example, in the above image, the inner entities are the characters of the Fellowship in the Lord of the Rings movies. The outer entities are the locations in Middle Earth where the movie takes place. The connection/value is the number of words spoken by each character at each location. 13 | 14 | Since this layout was transformed from d3's [chord diagram](https://github.com/d3/d3-chord/blob/master/README.md) many of the below API references will be similar to those from the chord diagram for the *loom* and similar to the ribbon functions for the *strings*. 15 | 16 | ## Installing 17 | 18 | Download the [latest build](build/). **d3-loom** depends on **d3**, so be sure to include a script tag with the [d3 library](http://d3js.org/) before including `d3-loom.js`. In a vanilla environment, a d3 global is exported: 19 | 20 | 21 | ```html 22 | 23 | 24 | 25 | 30 | ``` 31 | 32 | If you use a package manager like [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/en/), say 33 | 34 | ``` 35 | npm install d3-loom 36 | ``` 37 | 38 | or 39 | 40 | ``` 41 | yarn add d3-loom 42 | ``` 43 | 44 | to add [d3-loom](https://www.npmjs.com/package/d3-loom) to your project. AMD, CommonJS, and vanilla environments are supported. 45 | 46 | ## Note 47 | 48 | One thing that I have not (yet) figured out is how to sort the outer groups/entities in such a way to automatically make a visually appealing split in 2 separate halves. This is only relevant when you specify an [empty percentage](#loom_emptyPerc), thus create a gap in the top and bottom. For now you will have to manually order the outer entities in such a way that when split into two groups, the total value of those two groups separately lies close to 50%. However, you don't need to have the exact number of entities on the left half as on the right. The program will try and find a split that separates all the entities in two groups to make them both as close to 50% as possible, but it will not reorder the outer entities to do so. 49 | 50 | ## Feedback 51 | 52 | This is my first attempt at a plugin and it has definitely not been tested well enough. I would therefore love to hear from you about any bugs or errors that you run into while trying to use the plugin. You can create an Issue right here, reach me on Twitter via [@NadiehBremer](https://www.twitter.com/NadiehBremer) or mail me on info *at* visualcinnamon.com 53 | 54 | 55 | ## API Reference 56 | 57 | # d3.loom() 58 | 59 | Constructs a new loom generator with the default settings. 60 | 61 | # loom(data) 62 | 63 | Computes the loom layout for the specified *data*. The length of the returned array is the same as *data*, however, due to sorting of the strings, to reduce overlap, the ordering can be different than the initial data. 64 | 65 | Typically a dataset for the *loom* contains 3 values; the outer entity, the inner entity and the value that connects these two (e.g. outer = location, inner = person, value = days that person stayed in the location): 66 | 67 | ```js 68 | var data = [ 69 | { 70 | outer: "Amsterdam", 71 | inner: "Alexander", 72 | value: 679 73 | }, 74 | { 75 | outer: "Bangkok", 76 | inner: "Brendan", 77 | value: 124 78 | }, 79 | //...and so on 80 | ]; 81 | ``` 82 | 83 | The return value of *loom*(*data*) is an array of *looms*, where each loom represents the connection between an entity in the center of the loom (the *inner*) and the entity on the outside of the loom (the *outer*) and is an object with the following properties: 84 | 85 | * `inner` - the inner subgroup 86 | * `outer` - the outer subgroup 87 | 88 | Both the inner and outer subgroup are also objects. The inner has the following properties: 89 | 90 | * `name` - the [name](#loom_inner) of the inner entity 91 | * `offset` - the [horizontal offset](#loom_widthInner) of the inner string's endpoint from the center 92 | * `x` - the horizontal location of the inner entity 93 | * `y` - the vertical location of the inner entity 94 | 95 | And the outer has the following properties: 96 | 97 | * `groupStartAngle` - the [start angle](#string_groupStartAngle) of the outer group to which the specific string belongs 98 | * `startAngle` - the [start angle](#string_startAngle) of the string at the outer edge in radians 99 | * `endAngle` - the [end angle](#string_endAngle) of the string at the outer edge in radians 100 | * `value` - the numeric [value](#loom_value) of the string 101 | * `index` - the zero-based [sorted index](#loom_sortGroups) of the group 102 | * `subindex` - the zero-based [sorted sub-index](#loom_sortSubgroups) of the string within the group 103 | * `innername` - the [name](#loom_inner) of the connected inner entity 104 | * `outername` - the [name](#loom_outer) of the outer entity 105 | 106 | The *looms* are passed to [d3.string](#string) to display the relationships between the inner and outer entities. 107 | 108 | The *looms* array also defines a two secondary arrays. The first, called *groups*, is an array representing the outer entities. The length of the array is the number of unique outer entities and is an object with the following properties: 109 | 110 | * `startAngle` - the [start angle](#string_startAngle) of the arc in radians 111 | * `endAngle` - the [end angle](#string_endAngle) of the arc in radians 112 | * `value` - the numeric [value](#loom_value) of the arc 113 | * `index` - the zero-based [sorted index](#loom_sortGroups) of the arc 114 | * `outername` - the [name](#loom_outer) of the outer entity 115 | 116 | The *groups* are passed to [d3.arc](https://github.com/d3/d3-shape#arc) to produce a donut chart around the circumference of the loom layout. 117 | 118 | The other array, called, *innergroups*, is an array represting the inner entities. The length of the array is the number of unique inner entities and is an object with the following properties: 119 | 120 | * `name` - the [name](#loom_inner) of the inner entity 121 | * `offset` - the [horizontal offset](#loom_widthInner) of the inner string's endpoint from the center 122 | * `x` - the horizontal location of the inner entity 123 | * `y` - the vertical location of the inner entity 124 | 125 | The *innergroups* are used to create the textual representation of the inner entities in the center of the loom layout. 126 | 127 | # loom.padAngle([angle]) 128 | 129 | If *angle* is specified, sets the pad angle (i.e. the white space) between adjacent outer groups to the specified number in radians and returns this loom layout. If *angle* is not specified, returns the current pad angle, which defaults to zero. 130 | 131 | # loom.inner([inner]) 132 | 133 | The *inner* represents the name/id/... textual value of the entities that will be placed in the center. If *inner* is specified, sets the inner accessor to the specified function and returns this string generator. If *inner* is not specified, returns the current inner accessor, which defaults to: 134 | 135 | ```js 136 | function inner(d) { 137 | return d.inner; 138 | } 139 | ``` 140 | 141 | # loom.outer([outer]) 142 | 143 | The *outer* represents the name/id/... textual value of the entities that will be placed around the loom along a circle. If *outer* is specified, sets the outer accessor to the specified function and returns this string generator. If *outer* is not specified, returns the current outer accessor, which defaults to: 144 | 145 | ```js 146 | function outer(d) { 147 | return d.outer; 148 | } 149 | ``` 150 | 151 | # loom.value([value]) 152 | 153 | The *value* represents the numeric value that is the connection between the inner and outer entity. It is the value that determines the width of the strings on the outside. If *value* is specified, sets the value accessor to the specified function and returns this string generator. If *value* is not specified, returns the current value accessor, which defaults to: 154 | 155 | ```js 156 | function value(d) { 157 | return d.value; 158 | } 159 | ``` 160 | 161 | # loom.heightInner([height]) 162 | 163 | This *height* gives the vertical distance between the inner entities in the center. If *height* is specified, sets the heightInner to the specified number and returns this loom generator. If height is not specified, returns the current heightInner value, which defaults to 20 pixels. 164 | 165 | # loom.widthInner([width]) 166 | 167 | This *width* gives the horizontal distance between the inner endpoints of the strings in the center. It is the value that determines the width of the gap that is created so the text of the inner entities does not overlap the strings. If *width* is specified, sets the widthInner to the specified function or number and returns this loom generator. However, note that this function receives a *d* value that contains the string of the entity in the center (the *inner*). You can therefore make the width depend on the length of the *inner*'s string. If width is not specified, returns the current widthInner value, which defaults to 30 pixels. 168 | 169 | # loom.emptyPerc([value]) 170 | 171 | This *value* gives the percentage of the circle that will be empty to create space in the top and bottom. If *value* is specified, sets the current emptyPerc to the specified number in the range [0,1] and returns this loom generator. If value is not specified, returns the current emptyPerc value, which defaults to 0.2. 172 | 173 | # loom.sortGroups([compare]) 174 | 175 | If *compare* is specified, sets the group comparator to the specified function or null and returns this loom layout. If *compare* is not specified, returns the current group comparator, which defaults to null. If the group comparator is non-null, it is used to sort the outer groups/entities by their total value (i.e. the sum of all the inner strings). See also [d3.ascending](https://github.com/d3/d3-array#ascending) and [d3.descending](https://github.com/d3/d3-array#descending). 176 | 177 | # loom.sortSubgroups([compare]) 178 | 179 | If *compare* is specified, sets the subgroup comparator to the specified function or null and returns this loom layout. If *compare* is not specified, returns the current subgroup comparator, which defaults to null. If the subgroup comparator is non-null, it is used to sort the subgroups (i.e. the separate strings) within each outer entity by their value. See also [d3.ascending](https://github.com/d3/d3-array#ascending) and [d3.descending](https://github.com/d3/d3-array#descending). This sorting applies to both the order of the strings on the outer edge and the vertical order of the inner entities. It is advised to supply a subGroup sorting whenever there is not already a sorting applied to the underlying data, otherwise the inner entities and the strings will be drawn in the exact order as they appear in the data, typically resulting in a lot of overlapping strings. 180 | 181 | # loom.sortLooms([compare]) 182 | 183 | If *compare* is specified, sets the loom comparator to the specified function or null and returns this loom layout. If *compare* is not specified, returns the current loom comparator, which defaults to null. If the loom comparator is non-null, it is used to sort the strings by their value; this only affects the *z*-order of these inner strings (i.e. how they overlap). See also [d3.ascending](https://github.com/d3/d3-array#ascending) and [d3.descending].(https://github.com/d3/d3-array#descending). 184 | 185 | # d3.string() 186 | 187 | Creates a new string generator with the default settings. 188 | 189 | # string(arguments…) 190 | 191 | Generates a string for the given *arguments*. The *arguments* are arbitrary; they are simply propagated to the string's generator's accessor functions along with the `this` object. If the string generator has a context, then the string is rendered to this context as a sequence of path method calls and this function returns void. Otherwise, a path data string is returned. 192 | 193 | Typically, only the [radius](#string_radius), [thicknessInner](#string_thicknessInner), and [pullout](#string_pullout) should be adjusted when used on conjunction with the [loom](#loom), because all the other accessors will work with the default settings. 194 | 195 | # string.radius([radius]) 196 | 197 | If *radius* is specified, sets the radius accessor to the specified function and returns this string generator. If *radius* is not specified, returns the current radius value, which defaults to 100 pixels. 198 | 199 | The *radius* represents the inner radius of the loom and is typically set to a single number. It is advised to always set this value different from the default, depending on the space available within your svg. 200 | 201 | # string.thicknessInner([thickness]) 202 | 203 | If *thickness* is specified, sets the thicknessInner to the specified number and returns this string generator. If *thickness* is not specified, returns the current thicknessInner value, which defaults to 0 pixels. The thicknessInner defines the "height", or thickness, that the strings will have at their endpoints next to the inner entities. 204 | 205 | # string.pullout([pullout]) 206 | 207 | If *pullout* is specified, sets the pullout to the specified number and returns this string generator. If *pullout* is not specified, returns the current pullout value, which defaults to 50 pixels. The pullout defines how far the two circle halves will be placed outward horizontally. 208 | 209 | # string.inner([inner]) 210 | 211 | If *inner* is specified, sets the inner accessor to the specified function and returns this string generator. If *inner* is not specified, returns the current source accessor, which defaults to: 212 | 213 | ```js 214 | function inner(d) { 215 | return d.inner; 216 | } 217 | ``` 218 | 219 | When the string generator is used in conjunction with the *loom*, the resulting loom array will contain an *inner* object. Thus this accessor function does not have to be set separately, but just use the default. 220 | 221 | # string.outer([outer]) 222 | 223 | If *outer* is specified, sets the outer accessor to the specified function and returns this string generator. If *outer* is not specified, returns the current outer accessor, which defaults to: 224 | 225 | ```js 226 | function outer(d) { 227 | return d.outer; 228 | } 229 | ``` 230 | 231 | When the string generator is used in conjunction with the *loom*, the resulting loom array will contain an *outer* object. Thus this accessor function does not have to be set separately, but just use the default. 232 | 233 | # string.groupStartAngle([angle]) 234 | 235 | If *angle* is specified, sets the start angle accessor to the specified function and returns this string generator. If *angle* is not specified, returns the current start angle accessor, which defaults to: 236 | 237 | ```js 238 | function groupStartAngle(d) { 239 | return d.groupStartAngle; 240 | } 241 | ``` 242 | 243 | The *angle* is specified in radians, with 0 at -*y* (12 o'clock) and positive angles proceeding clockwise. This separate assessor is needed to make sure that even when an *emptyPerc* is set, all the strings belonging to the same outer group will be drawn at the same side. It's best make this assessor similar in "function" to the *startAngle* below (i.e. if a constant is added onto the *startAngle* to rotate the whole, then the same constant should be added to the *groupStartAngle*). When the string generator is used in conjunction with the *loom*, the resulting loom array will contain an *groupStartAngle* value within the *outer* object. In that case this accessor function does not have to be set separately, but just use the default. 244 | 245 | # string.startAngle([angle]) 246 | 247 | If *angle* is specified, sets the start angle accessor to the specified function and returns this string generator. If *angle* is not specified, returns the current start angle accessor, which defaults to: 248 | 249 | ```js 250 | function startAngle(d) { 251 | return d.startAngle; 252 | } 253 | ``` 254 | 255 | The *angle* is specified in radians, with 0 at -*y* (12 o'clock) and positive angles proceeding clockwise. When the string generator is used in conjunction with the *loom*, the resulting loom array will contain an *startAngle* value within the *outer* object. In that case this accessor function does not have to be set separately, but just use the default. 256 | 257 | # string.endAngle([angle]) 258 | 259 | If *angle* is specified, sets the end angle accessor to the specified function and returns this string generator. If *angle* is not specified, returns the current end angle accessor, which defaults to: 260 | 261 | ```js 262 | function endAngle(d) { 263 | return d.endAngle; 264 | } 265 | ``` 266 | 267 | The *angle* is specified in radians, with 0 at -*y* (12 o'clock) and positive angles proceeding clockwise. When the string generator is used in conjunction with the *loom*, the resulting loom array will contain an *endAngle* value within the *outer* object. In that case this accessor function does not have to be set separately, but just use the default. 268 | 269 | # string.x([x]) 270 | 271 | If *x* is specified, sets the x accessor to the specified function and returns this string generator. If *x* is not specified, returns the current x accessor, which defaults to: 272 | 273 | ```js 274 | function x(d) { 275 | return d.x; 276 | } 277 | ``` 278 | 279 | The *x* defines the horizontal location where the inner entities are placed, typically in the center of the loom. When the string generator is used in conjunction with the *loom*, the resulting loom array will contain an *x* value within the *inner* object. In that case this accessor function does not have to be set separately, but just use the default. 280 | 281 | # string.y([y]) 282 | 283 | If *y* is specified, sets the y accessor to the specified function and returns this string generator. If *y* is not specified, returns the current y accessor, which defaults to: 284 | 285 | ```js 286 | function y(d) { 287 | return d.y; 288 | } 289 | ``` 290 | 291 | The *y* defines the vertical location where the inner entities are placed. They are typically placed in a column like fashion in the center, one above the other. When the string generator is used in conjunction with the *loom*, the resulting loom array will contain an *y* value within the *inner* object. In that case this accessor function does not have to be set separately, but just use the default. 292 | 293 | # string.offset([offset]) 294 | 295 | If *offset* is specified, sets the offset accessor to the specified function and returns this string generator. If *offset* is not specified, returns the current offset accessor, which defaults to: 296 | 297 | ```js 298 | function offset(d) { 299 | return d.offset; 300 | } 301 | ``` 302 | 303 | The *offset* defines the horizontal space between the inner end points of the strings, so that the text of the inner entities does not overlap the strings. It is typically set through the [widthInner](#loom_widthInner) accessor of the loom and propagates through to the string function. Therefore, when the string generator is used in conjunction with the *loom*, the resulting loom array will contain an *offset* value within the *inner* object. In that case this accessor function does not have to be set separately, but just use the default. 304 | 305 | # string.context([context]) 306 | 307 | If *context* is specified, sets the context and returns this string generator. If *context* is not specified, returns the current context, which defaults to null. If the context is not null, then the [generated string](#_string) is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string representing the generated string is returned. See also [d3-path](https://github.com/d3/d3-path). 308 | -------------------------------------------------------------------------------- /build/d3-loom.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 | (factory((global.d3 = global.d3 || {}))); 5 | }(this, (function (exports) { 'use strict'; 6 | 7 | function compareValue(compare) { 8 | return function (a, b) { 9 | return compare(a.outer.value, b.outer.value); 10 | }; 11 | } 12 | 13 | function constant(x) { 14 | return function () { 15 | return x; 16 | }; 17 | } 18 | 19 | /* Based on the d3v4 d3.chord() function by Mike Bostock 20 | ** Adjusted by Nadieh Bremer - July 2016 */ 21 | 22 | /* global d3 */ 23 | function loom() { 24 | var tau = Math.PI * 2; 25 | 26 | var padAngle = 0; 27 | var sortGroups = null; 28 | var sortSubgroups = null; 29 | var sortLooms = null; 30 | var emptyPerc = 0.2; 31 | var heightInner = 20; 32 | var widthInner = function widthInner() { 33 | return 30; 34 | }; 35 | var value = function value(d) { 36 | return d.value; 37 | }; 38 | var inner = function inner(d) { 39 | return d.inner; 40 | }; 41 | var outer = function outer(d) { 42 | return d.outer; 43 | }; 44 | 45 | function loomLayout(layoutData) { 46 | // Nest the data on the outer variable 47 | var data = d3.nest().key(outer).entries(layoutData); 48 | 49 | var n = data.length; 50 | 51 | // Loop over the outer groups and sum the values 52 | 53 | var groupSums = []; 54 | var groupIndex = d3.range(n); 55 | var subgroupIndex = []; 56 | var looms = []; 57 | looms.groups = new Array(n); 58 | var groups = looms.groups; 59 | var numSubGroups = void 0; 60 | looms.innergroups = []; 61 | var uniqueInner = looms.innergroups; 62 | var uniqueCheck = []; 63 | var k = void 0; 64 | var x = void 0; 65 | var x0 = void 0; 66 | var j = void 0; 67 | var l = void 0; 68 | var s = void 0; 69 | var v = void 0; 70 | var sum = void 0; 71 | var section = void 0; 72 | var remain = void 0; 73 | var counter = void 0; 74 | var reverseOrder = false; 75 | var approxCenter = void 0; 76 | k = 0; 77 | numSubGroups = 0; 78 | for (var i = 0; i < n; i += 1) { 79 | v = data[i].values.length; 80 | sum = 0; 81 | for (j = 0; j < v; j += 1) { 82 | sum += value(data[i].values[j]); 83 | } // for j 84 | groupSums.push(sum); 85 | subgroupIndex.push(d3.range(v)); 86 | numSubGroups += v; 87 | k += sum; 88 | } // for i 89 | 90 | // Sort the groups… 91 | if (sortGroups) { 92 | groupIndex.sort(function (a, b) { 93 | return sortGroups(groupSums[a], groupSums[b]); 94 | }); 95 | } 96 | 97 | // Sort subgroups… 98 | if (sortSubgroups) { 99 | subgroupIndex.forEach(function (d, i) { 100 | d.sort(function (a, b) { 101 | return sortSubgroups(inner(data[i].values[a]), inner(data[i].values[b])); 102 | }); 103 | }); 104 | } 105 | 106 | // After which group are we past the center, taking into account the padding 107 | // TODO: make something for if there is no "nice" split in two... 108 | var padk = k * (padAngle / tau); 109 | l = 0; 110 | for (var _i = 0; _i < n; _i += 1) { 111 | section = groupSums[groupIndex[_i]] + padk; 112 | l += section; 113 | if (l > (k + n * padk) / 2) { 114 | // Check if the group should be added to left or right 115 | remain = k + n * padk - (l - section); 116 | approxCenter = remain / section < 0.5 ? groupIndex[_i] : groupIndex[_i - 1]; 117 | break; 118 | } // if 119 | } // for i 120 | 121 | // How much should be added to k to make the empty part emptyPerc big of the total 122 | var emptyk = k * emptyPerc / (1 - emptyPerc); 123 | k += emptyk; 124 | 125 | // Convert the sum to scaling factor for [0, 2pi]. 126 | k = Math.max(0, tau - padAngle * n) / k; 127 | var dx = k ? padAngle : tau / n; 128 | 129 | // Compute the start and end angle for each group and subgroup. 130 | // Note: Opera has a bug reordering object literal properties! 131 | var subgroups = new Array(numSubGroups); 132 | x = emptyk * 0.25 * k; // starting with quarter of the empty part to the side; 133 | counter = 0; 134 | for (var _i2 = 0; _i2 < n; _i2 += 1) { 135 | var di = groupIndex[_i2]; 136 | var outername = data[di].key; 137 | 138 | x0 = x; 139 | s = subgroupIndex[di].length; 140 | for (j = 0; j < s; j += 1) { 141 | var dj = reverseOrder ? subgroupIndex[di][s - 1 - j] : subgroupIndex[di][j]; 142 | 143 | v = value(data[di].values[dj]); 144 | var innername = inner(data[di].values[dj]); 145 | var a0 = x; 146 | x += v * k; 147 | var a1 = x; 148 | subgroups[counter] = { 149 | index: di, 150 | subindex: dj, 151 | startAngle: a0, 152 | endAngle: a1, 153 | value: v, 154 | outername: outername, 155 | innername: innername, 156 | groupStartAngle: x0 157 | }; 158 | 159 | // Check and save the unique inner names 160 | if (!uniqueCheck[innername]) { 161 | uniqueCheck[innername] = true; 162 | uniqueInner.push({ name: innername }); 163 | } // if 164 | 165 | counter += 1; 166 | } // for j 167 | groups[di] = { 168 | index: di, 169 | startAngle: x0, 170 | endAngle: x, 171 | value: groupSums[di], 172 | outername: outername 173 | }; 174 | x += dx; 175 | // If this is the approximate center, add half of the empty piece for the bottom 176 | if (approxCenter === di) x += emptyk * 0.5 * k; 177 | // If you've crossed the bottom, reverse the order of the inner strings 178 | if (x > Math.PI) reverseOrder = true; 179 | } // for i 180 | 181 | // Sort the inner groups in the same way as the strings 182 | if (sortSubgroups) { 183 | uniqueInner.sort(function (a, b) { 184 | return sortSubgroups(a.name, b.name); 185 | }); 186 | } 187 | 188 | // Find x and y locations of the inner categories 189 | var m = uniqueInner.length; 190 | for (var _i3 = 0; _i3 < m; _i3 += 1) { 191 | uniqueInner[_i3].x = 0; 192 | uniqueInner[_i3].y = -m * heightInner / 2 + _i3 * heightInner; 193 | uniqueInner[_i3].offset = widthInner(uniqueInner[_i3].name, _i3); 194 | } // for i 195 | 196 | // Generate bands for each (non-empty) subgroup-subgroup link 197 | counter = 0; 198 | for (var _i4 = 0; _i4 < n; _i4 += 1) { 199 | var _di = groupIndex[_i4]; 200 | s = subgroupIndex[_di].length; 201 | for (j = 0; j < s; j += 1) { 202 | var outerGroup = subgroups[counter]; 203 | var innerTerm = outerGroup.innername; 204 | // Find the correct inner object based on the name 205 | var innerGroup = searchTerm(innerTerm, 'name', uniqueInner); 206 | if (outerGroup.value) { 207 | looms.push({ inner: innerGroup, outer: outerGroup }); 208 | } // if 209 | counter += 1; 210 | } // for j 211 | } // for i 212 | 213 | return sortLooms ? looms.sort(sortLooms) : looms; 214 | } // loomLayout 215 | 216 | function searchTerm(term, property, arrayToSearch) { 217 | for (var i = 0; i < arrayToSearch.length; i += 1) { 218 | if (arrayToSearch[i][property] === term) { 219 | return arrayToSearch[i]; 220 | } // if 221 | } // for i 222 | return null; 223 | } // searchTerm 224 | 225 | loomLayout.padAngle = function (_) { 226 | return arguments.length ? (padAngle = Math.max(0, _), loomLayout) : padAngle; 227 | }; 228 | 229 | loomLayout.inner = function (_) { 230 | return arguments.length ? (inner = _, loomLayout) : inner; 231 | }; 232 | 233 | loomLayout.outer = function (_) { 234 | return arguments.length ? (outer = _, loomLayout) : outer; 235 | }; 236 | 237 | loomLayout.value = function (_) { 238 | return arguments.length ? (value = _, loomLayout) : value; 239 | }; 240 | 241 | loomLayout.heightInner = function (_) { 242 | return arguments.length ? (heightInner = _, loomLayout) : heightInner; 243 | }; 244 | 245 | loomLayout.widthInner = function (_) { 246 | return arguments.length ? (widthInner = typeof _ === 'function' ? _ : constant(+_), loomLayout) : widthInner; 247 | }; 248 | 249 | loomLayout.emptyPerc = function (_) { 250 | return arguments.length ? (emptyPerc = _ < 1 ? Math.max(0, _) : Math.max(0, _ * 0.01), loomLayout) : emptyPerc; 251 | }; 252 | 253 | loomLayout.sortGroups = function (_) { 254 | return arguments.length ? (sortGroups = _, loomLayout) : sortGroups; 255 | }; 256 | 257 | loomLayout.sortSubgroups = function (_) { 258 | return arguments.length ? (sortSubgroups = _, loomLayout) : sortSubgroups; 259 | }; 260 | 261 | loomLayout.sortLooms = function (_) { 262 | return arguments.length ? (_ == null ? sortLooms = null : (sortLooms = compareValue(_))._ = _, loomLayout) : sortLooms && sortLooms._; 263 | }; 264 | 265 | return loomLayout; 266 | } // loom 267 | 268 | /* global d3 */ 269 | 270 | function string() { 271 | var slice = Array.prototype.slice; 272 | var cos = Math.cos; 273 | var sin = Math.sin; 274 | var halfPi = Math.PI / 2; 275 | var tau = Math.PI * 2; 276 | 277 | var inner = function inner(d) { 278 | return d.inner; 279 | }; 280 | var outer = function outer(d) { 281 | return d.outer; 282 | }; 283 | var radius = function radius() { 284 | return 100; 285 | }; 286 | var groupStartAngle = function groupStartAngle(d) { 287 | return d.groupStartAngle; 288 | }; 289 | var startAngle = function startAngle(d) { 290 | return d.startAngle; 291 | }; 292 | var endAngle = function endAngle(d) { 293 | return d.endAngle; 294 | }; 295 | var x = function x(d) { 296 | return d.x; 297 | }; 298 | var y = function y(d) { 299 | return d.y; 300 | }; 301 | var offset = function offset(d) { 302 | return d.offset; 303 | }; 304 | var pullout = 50; 305 | var thicknessInner = 0; 306 | var context = null; 307 | 308 | function stringLayout() { 309 | var buffer = void 0; 310 | 311 | for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { 312 | args[_key] = arguments[_key]; 313 | } 314 | 315 | var argv = slice.call(args); 316 | var out = outer.apply(this, argv); 317 | var inn = inner.apply(this, argv); 318 | argv[0] = out; 319 | var sr = +radius.apply(this, argv); 320 | var sa0 = startAngle.apply(this, argv) - halfPi; 321 | var sga0 = groupStartAngle.apply(this, argv) - halfPi; 322 | var sa1 = endAngle.apply(this, argv) - halfPi; 323 | var sx0 = sr * cos(sa0); 324 | var sy0 = sr * sin(sa0); 325 | var sx1 = sr * cos(sa1); 326 | var sy1 = sr * sin(sa1); 327 | argv[0] = inn; 328 | // 'tr' is assigned a value but never used 329 | // const tr = +radius.apply(this, (argv)); 330 | var tx = x.apply(this, argv); 331 | var ty = y.apply(this, argv); 332 | var toffset = offset.apply(this, argv); 333 | var xco = void 0; 334 | var yco = void 0; 335 | var xci = void 0; 336 | var yci = void 0; 337 | 338 | // Does the group lie on the left side; 339 | var leftHalf = sga0 + halfPi > Math.PI && sga0 + halfPi < tau; 340 | // If the group lies on the other side, switch the inner point offset 341 | if (leftHalf) toffset = -toffset; 342 | tx += toffset; 343 | // And the height of the end point 344 | var theight = leftHalf ? -thicknessInner : thicknessInner; 345 | 346 | if (!context) { 347 | buffer = d3.path(); 348 | context = buffer; 349 | } 350 | 351 | // Change the pullout based on where the stringLayout is 352 | var pulloutContext = (leftHalf ? -1 : 1) * pullout; 353 | sx0 += pulloutContext; 354 | sx1 += pulloutContext; 355 | // Start at smallest angle of outer arc 356 | context.moveTo(sx0, sy0); 357 | // Circular part along the outer arc 358 | context.arc(pulloutContext, 0, sr, sa0, sa1); 359 | // From end outer arc to center (taking into account the pullout) 360 | xco = d3.interpolateNumber(pulloutContext, sx1)(0.5); 361 | yco = d3.interpolateNumber(0, sy1)(0.5); 362 | if (!leftHalf && sx1 < tx || leftHalf && sx1 > tx) { 363 | // If the outer point lies closer to the center than the inner point 364 | xci = tx + (tx - sx1) / 2; 365 | yci = d3.interpolateNumber(ty + theight / 2, sy1)(0.5); 366 | } else { 367 | xci = d3.interpolateNumber(tx, sx1)(0.25); 368 | yci = ty + theight / 2; 369 | } // else 370 | context.bezierCurveTo(xco, yco, xci, yci, tx, ty + theight / 2); 371 | // Draw a straight line up/down (depending on the side of the circle) 372 | context.lineTo(tx, ty - theight / 2); 373 | // From center (taking into account the pullout) to start of outer arc 374 | xco = d3.interpolateNumber(pulloutContext, sx0)(0.5); 375 | yco = d3.interpolateNumber(0, sy0)(0.5); 376 | if (!leftHalf && sx0 < tx || leftHalf && sx0 > tx) { 377 | // If the outer point lies closer to the center than the inner point 378 | xci = tx + (tx - sx0) / 2; 379 | yci = d3.interpolateNumber(ty - theight / 2, sy0)(0.5); 380 | } else { 381 | xci = d3.interpolateNumber(tx, sx0)(0.25); 382 | yci = ty - theight / 2; 383 | } // else 384 | context.bezierCurveTo(xci, yci, xco, yco, sx0, sy0); 385 | // Close path 386 | context.closePath(); 387 | 388 | if (buffer) { 389 | context = null; 390 | return '' + buffer || null; 391 | } 392 | return null; 393 | } 394 | 395 | stringLayout.radius = function (_) { 396 | return arguments.length ? (radius = typeof _ === 'function' ? _ : constant(+_), stringLayout) : radius; 397 | }; 398 | 399 | stringLayout.groupStartAngle = function (_) { 400 | return arguments.length ? (groupStartAngle = typeof _ === 'function' ? _ : constant(+_), stringLayout) : groupStartAngle; 401 | }; 402 | 403 | stringLayout.startAngle = function (_) { 404 | return arguments.length ? (startAngle = typeof _ === 'function' ? _ : constant(+_), stringLayout) : startAngle; 405 | }; 406 | 407 | stringLayout.endAngle = function (_) { 408 | return arguments.length ? (endAngle = typeof _ === 'function' ? _ : constant(+_), stringLayout) : endAngle; 409 | }; 410 | 411 | stringLayout.x = function (_) { 412 | return arguments.length ? (x = _, stringLayout) : x; 413 | }; 414 | 415 | stringLayout.y = function (_) { 416 | return arguments.length ? (y = _, stringLayout) : y; 417 | }; 418 | 419 | stringLayout.offset = function (_) { 420 | return arguments.length ? (offset = _, stringLayout) : offset; 421 | }; 422 | 423 | stringLayout.thicknessInner = function (_) { 424 | return arguments.length ? (thicknessInner = _, stringLayout) : thicknessInner; 425 | }; 426 | 427 | stringLayout.inner = function (_) { 428 | return arguments.length ? (inner = _, stringLayout) : inner; 429 | }; 430 | 431 | stringLayout.outer = function (_) { 432 | return arguments.length ? (outer = _, stringLayout) : outer; 433 | }; 434 | 435 | stringLayout.pullout = function (_) { 436 | return arguments.length ? (pullout = _, stringLayout) : pullout; 437 | }; 438 | 439 | stringLayout.context = function (_) { 440 | return arguments.length ? (context = _ == null ? null : _, stringLayout) : context; 441 | }; 442 | 443 | return stringLayout; 444 | } 445 | 446 | exports.loom = loom; 447 | exports.string = string; 448 | 449 | Object.defineProperty(exports, '__esModule', { value: true }); 450 | 451 | }))); 452 | //# sourceMappingURL=d3-loom.js.map 453 | -------------------------------------------------------------------------------- /build/d3-loom.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"d3-loom.js","sources":["../src/compare-value.js","../src/constant.js","../src/loom.js","../src/string.js"],"sourcesContent":["export default function compareValue(compare) {\n return (a, b) => compare(a.outer.value, b.outer.value);\n}\n","export default function constant(x) {\n return () => x;\n}\n","/* Based on the d3v4 d3.chord() function by Mike Bostock\n** Adjusted by Nadieh Bremer - July 2016 */\n\n/* global d3 */\nimport compareValue from './compare-value';\nimport constant from './constant';\n\nexport default function loom() {\n const tau = Math.PI * 2;\n\n let padAngle = 0;\n let sortGroups = null;\n let sortSubgroups = null;\n let sortLooms = null;\n let emptyPerc = 0.2;\n let heightInner = 20;\n let widthInner = () => 30;\n let value = d => d.value;\n let inner = d => d.inner;\n let outer = d => d.outer;\n\n function loomLayout(layoutData) {\n // Nest the data on the outer variable\n const data = d3.nest().key(outer).entries(layoutData);\n\n const n = data.length;\n\n // Loop over the outer groups and sum the values\n\n const groupSums = [];\n const groupIndex = d3.range(n);\n const subgroupIndex = [];\n const looms = [];\n looms.groups = new Array(n);\n const groups = looms.groups;\n let numSubGroups;\n looms.innergroups = [];\n const uniqueInner = looms.innergroups;\n const uniqueCheck = [];\n let k;\n let x;\n let x0;\n let j;\n let l;\n let s;\n let v;\n let sum;\n let section;\n let remain;\n let counter;\n let reverseOrder = false;\n let approxCenter;\n k = 0;\n numSubGroups = 0;\n for (let i = 0; i < n; i += 1) {\n v = data[i].values.length;\n sum = 0;\n for (j = 0; j < v; j += 1) {\n sum += value(data[i].values[j]);\n } // for j\n groupSums.push(sum);\n subgroupIndex.push(d3.range(v));\n numSubGroups += v;\n k += sum;\n } // for i\n\n // Sort the groups…\n if (sortGroups) {\n groupIndex.sort((a, b) => sortGroups(groupSums[a], groupSums[b]));\n }\n\n // Sort subgroups…\n if (sortSubgroups) {\n subgroupIndex.forEach((d, i) => {\n d.sort((a, b) =>\n sortSubgroups(inner(data[i].values[a]), inner(data[i].values[b]))\n );\n });\n }\n\n // After which group are we past the center, taking into account the padding\n // TODO: make something for if there is no \"nice\" split in two...\n const padk = k * (padAngle / tau);\n l = 0;\n for (let i = 0; i < n; i += 1) {\n section = groupSums[groupIndex[i]] + padk;\n l += section;\n if (l > (k + n * padk) / 2) {\n // Check if the group should be added to left or right\n remain = k + n * padk - (l - section);\n approxCenter = remain / section < 0.5\n ? groupIndex[i]\n : groupIndex[i - 1];\n break;\n } // if\n } // for i\n\n // How much should be added to k to make the empty part emptyPerc big of the total\n const emptyk = k * emptyPerc / (1 - emptyPerc);\n k += emptyk;\n\n // Convert the sum to scaling factor for [0, 2pi].\n k = Math.max(0, tau - padAngle * n) / k;\n const dx = k ? padAngle : tau / n;\n\n // Compute the start and end angle for each group and subgroup.\n // Note: Opera has a bug reordering object literal properties!\n const subgroups = new Array(numSubGroups);\n x = emptyk * 0.25 * k; // starting with quarter of the empty part to the side;\n counter = 0;\n for (let i = 0; i < n; i += 1) {\n const di = groupIndex[i];\n const outername = data[di].key;\n\n x0 = x;\n s = subgroupIndex[di].length;\n for (j = 0; j < s; j += 1) {\n const dj = reverseOrder\n ? subgroupIndex[di][s - 1 - j]\n : subgroupIndex[di][j];\n\n v = value(data[di].values[dj]);\n const innername = inner(data[di].values[dj]);\n const a0 = x;\n x += v * k;\n const a1 = x;\n subgroups[counter] = {\n index: di,\n subindex: dj,\n startAngle: a0,\n endAngle: a1,\n value: v,\n outername,\n innername,\n groupStartAngle: x0\n };\n\n // Check and save the unique inner names\n if (!uniqueCheck[innername]) {\n uniqueCheck[innername] = true;\n uniqueInner.push({ name: innername });\n } // if\n\n counter += 1;\n } // for j\n groups[di] = {\n index: di,\n startAngle: x0,\n endAngle: x,\n value: groupSums[di],\n outername\n };\n x += dx;\n // If this is the approximate center, add half of the empty piece for the bottom\n if (approxCenter === di) x += emptyk * 0.5 * k;\n // If you've crossed the bottom, reverse the order of the inner strings\n if (x > Math.PI) reverseOrder = true;\n } // for i\n\n // Sort the inner groups in the same way as the strings\n if (sortSubgroups) {\n uniqueInner.sort((a, b) => sortSubgroups(a.name, b.name));\n }\n\n // Find x and y locations of the inner categories\n const m = uniqueInner.length;\n for (let i = 0; i < m; i += 1) {\n uniqueInner[i].x = 0;\n uniqueInner[i].y = -m * heightInner / 2 + i * heightInner;\n uniqueInner[i].offset = widthInner(uniqueInner[i].name, i);\n } // for i\n\n // Generate bands for each (non-empty) subgroup-subgroup link\n counter = 0;\n for (let i = 0; i < n; i += 1) {\n const di = groupIndex[i];\n s = subgroupIndex[di].length;\n for (j = 0; j < s; j += 1) {\n const outerGroup = subgroups[counter];\n const innerTerm = outerGroup.innername;\n // Find the correct inner object based on the name\n const innerGroup = searchTerm(innerTerm, 'name', uniqueInner);\n if (outerGroup.value) {\n looms.push({ inner: innerGroup, outer: outerGroup });\n } // if\n counter += 1;\n } // for j\n } // for i\n\n return sortLooms ? looms.sort(sortLooms) : looms;\n } // loomLayout\n\n function searchTerm(term, property, arrayToSearch) {\n for (let i = 0; i < arrayToSearch.length; i += 1) {\n if (arrayToSearch[i][property] === term) {\n return arrayToSearch[i];\n } // if\n } // for i\n return null;\n } // searchTerm\n\n loomLayout.padAngle = function(_) {\n return arguments.length\n ? ((padAngle = Math.max(0, _)), loomLayout)\n : padAngle;\n };\n\n loomLayout.inner = function(_) {\n return arguments.length ? ((inner = _), loomLayout) : inner;\n };\n\n loomLayout.outer = function(_) {\n return arguments.length ? ((outer = _), loomLayout) : outer;\n };\n\n loomLayout.value = function(_) {\n return arguments.length ? ((value = _), loomLayout) : value;\n };\n\n loomLayout.heightInner = function(_) {\n return arguments.length ? ((heightInner = _), loomLayout) : heightInner;\n };\n\n loomLayout.widthInner = function(_) {\n return arguments.length\n ? ((widthInner = typeof _ === 'function' ? _ : constant(+_)), loomLayout)\n : widthInner;\n };\n\n loomLayout.emptyPerc = function(_) {\n return arguments.length\n ? ((emptyPerc = _ < 1\n ? Math.max(0, _)\n : Math.max(0, _ * 0.01)), loomLayout)\n : emptyPerc;\n };\n\n loomLayout.sortGroups = function(_) {\n return arguments.length ? ((sortGroups = _), loomLayout) : sortGroups;\n };\n\n loomLayout.sortSubgroups = function(_) {\n return arguments.length ? ((sortSubgroups = _), loomLayout) : sortSubgroups;\n };\n\n loomLayout.sortLooms = function(_) {\n return arguments.length\n ? (_ == null\n ? (sortLooms = null)\n : ((sortLooms = compareValue(_))._ = _), loomLayout)\n : sortLooms && sortLooms._;\n };\n\n return loomLayout;\n} // loom\n","/* global d3 */\n\nimport constant from './constant';\n\nexport default function string() {\n const slice = Array.prototype.slice;\n const cos = Math.cos;\n const sin = Math.sin;\n const halfPi = Math.PI / 2;\n const tau = Math.PI * 2;\n\n let inner = d => d.inner;\n let outer = d => d.outer;\n let radius = () => 100;\n let groupStartAngle = d => d.groupStartAngle;\n let startAngle = d => d.startAngle;\n let endAngle = d => d.endAngle;\n let x = d => d.x;\n let y = d => d.y;\n let offset = d => d.offset;\n let pullout = 50;\n let thicknessInner = 0;\n let context = null;\n\n function stringLayout(...args) {\n let buffer;\n const argv = slice.call(args);\n const out = outer.apply(this, argv);\n const inn = inner.apply(this, argv);\n argv[0] = out;\n const sr = +radius.apply(this, argv);\n const sa0 = startAngle.apply(this, argv) - halfPi;\n const sga0 = groupStartAngle.apply(this, argv) - halfPi;\n const sa1 = endAngle.apply(this, argv) - halfPi;\n let sx0 = sr * cos(sa0);\n const sy0 = sr * sin(sa0);\n let sx1 = sr * cos(sa1);\n const sy1 = sr * sin(sa1);\n argv[0] = inn;\n // 'tr' is assigned a value but never used\n // const tr = +radius.apply(this, (argv));\n let tx = x.apply(this, argv);\n const ty = y.apply(this, argv);\n let toffset = offset.apply(this, argv);\n let xco;\n let yco;\n let xci;\n let yci;\n\n // Does the group lie on the left side;\n const leftHalf = sga0 + halfPi > Math.PI && sga0 + halfPi < tau;\n // If the group lies on the other side, switch the inner point offset\n if (leftHalf) toffset = -toffset;\n tx += toffset;\n // And the height of the end point\n const theight = leftHalf ? -thicknessInner : thicknessInner;\n\n if (!context) {\n buffer = d3.path();\n context = buffer;\n }\n\n // Change the pullout based on where the stringLayout is\n const pulloutContext = (leftHalf ? -1 : 1) * pullout;\n sx0 += pulloutContext;\n sx1 += pulloutContext;\n // Start at smallest angle of outer arc\n context.moveTo(sx0, sy0);\n // Circular part along the outer arc\n context.arc(pulloutContext, 0, sr, sa0, sa1);\n // From end outer arc to center (taking into account the pullout)\n xco = d3.interpolateNumber(pulloutContext, sx1)(0.5);\n yco = d3.interpolateNumber(0, sy1)(0.5);\n if ((!leftHalf && sx1 < tx) || (leftHalf && sx1 > tx)) {\n // If the outer point lies closer to the center than the inner point\n xci = tx + (tx - sx1) / 2;\n yci = d3.interpolateNumber(ty + theight / 2, sy1)(0.5);\n } else {\n xci = d3.interpolateNumber(tx, sx1)(0.25);\n yci = ty + theight / 2;\n } // else\n context.bezierCurveTo(xco, yco, xci, yci, tx, ty + theight / 2);\n // Draw a straight line up/down (depending on the side of the circle)\n context.lineTo(tx, ty - theight / 2);\n // From center (taking into account the pullout) to start of outer arc\n xco = d3.interpolateNumber(pulloutContext, sx0)(0.5);\n yco = d3.interpolateNumber(0, sy0)(0.5);\n if ((!leftHalf && sx0 < tx) || (leftHalf && sx0 > tx)) {\n // If the outer point lies closer to the center than the inner point\n xci = tx + (tx - sx0) / 2;\n yci = d3.interpolateNumber(ty - theight / 2, sy0)(0.5);\n } else {\n xci = d3.interpolateNumber(tx, sx0)(0.25);\n yci = ty - theight / 2;\n } // else\n context.bezierCurveTo(xci, yci, xco, yco, sx0, sy0);\n // Close path\n context.closePath();\n\n if (buffer) {\n context = null;\n return `${buffer}` || null;\n }\n return null;\n }\n\n stringLayout.radius = function(_) {\n return arguments.length\n ? ((radius = typeof _ === 'function' ? _ : constant(+_)), stringLayout)\n : radius;\n };\n\n stringLayout.groupStartAngle = function(_) {\n return arguments.length\n ? ((groupStartAngle = typeof _ === 'function'\n ? _\n : constant(+_)), stringLayout)\n : groupStartAngle;\n };\n\n stringLayout.startAngle = function(_) {\n return arguments.length\n ? ((startAngle = typeof _ === 'function'\n ? _\n : constant(+_)), stringLayout)\n : startAngle;\n };\n\n stringLayout.endAngle = function(_) {\n return arguments.length\n ? ((endAngle = typeof _ === 'function' ? _ : constant(+_)), stringLayout)\n : endAngle;\n };\n\n stringLayout.x = function(_) {\n return arguments.length ? ((x = _), stringLayout) : x;\n };\n\n stringLayout.y = function(_) {\n return arguments.length ? ((y = _), stringLayout) : y;\n };\n\n stringLayout.offset = function(_) {\n return arguments.length ? ((offset = _), stringLayout) : offset;\n };\n\n stringLayout.thicknessInner = function(_) {\n return arguments.length\n ? ((thicknessInner = _), stringLayout)\n : thicknessInner;\n };\n\n stringLayout.inner = function(_) {\n return arguments.length ? ((inner = _), stringLayout) : inner;\n };\n\n stringLayout.outer = function(_) {\n return arguments.length ? ((outer = _), stringLayout) : outer;\n };\n\n stringLayout.pullout = function(_) {\n return arguments.length ? ((pullout = _), stringLayout) : pullout;\n };\n\n stringLayout.context = function(_) {\n return arguments.length\n ? ((context = _ == null ? null : _), stringLayout)\n : context;\n };\n\n return stringLayout;\n}\n"],"names":["compareValue","compare","a","b","outer","value","constant","x","loom","tau","Math","PI","padAngle","sortGroups","sortSubgroups","sortLooms","emptyPerc","heightInner","widthInner","d","inner","loomLayout","layoutData","data","d3","nest","key","entries","n","length","groupSums","groupIndex","range","subgroupIndex","looms","groups","Array","numSubGroups","innergroups","uniqueInner","uniqueCheck","k","x0","j","l","s","v","sum","section","remain","counter","reverseOrder","approxCenter","i","values","push","sort","forEach","padk","emptyk","max","dx","subgroups","di","outername","dj","innername","a0","a1","name","m","y","offset","outerGroup","innerTerm","innerGroup","searchTerm","term","property","arrayToSearch","_","arguments","string","slice","prototype","cos","sin","halfPi","radius","groupStartAngle","startAngle","endAngle","pullout","thicknessInner","context","stringLayout","buffer","args","argv","call","out","apply","inn","sr","sa0","sga0","sa1","sx0","sy0","sx1","sy1","tx","ty","toffset","xco","yco","xci","yci","leftHalf","theight","path","pulloutContext","moveTo","arc","interpolateNumber","bezierCurveTo","lineTo","closePath"],"mappings":";;;;;;AAAe,SAASA,YAAT,CAAsBC,OAAtB,EAA+B;SACrC,UAACC,CAAD,EAAIC,CAAJ;WAAUF,QAAQC,EAAEE,KAAF,CAAQC,KAAhB,EAAuBF,EAAEC,KAAF,CAAQC,KAA/B,CAAV;GAAP;;;ACDa,SAASC,QAAT,CAAkBC,CAAlB,EAAqB;SAC3B;WAAMA,CAAN;GAAP;;;ACDF;;;;AAIA,AACA,AAEA,AAAe,SAASC,IAAT,GAAgB;MACvBC,MAAMC,KAAKC,EAAL,GAAU,CAAtB;;MAEIC,WAAW,CAAf;MACIC,aAAa,IAAjB;MACIC,gBAAgB,IAApB;MACIC,YAAY,IAAhB;MACIC,YAAY,GAAhB;MACIC,cAAc,EAAlB;MACIC,aAAa;WAAM,EAAN;GAAjB;MACIb,QAAQ;WAAKc,EAAEd,KAAP;GAAZ;MACIe,QAAQ;WAAKD,EAAEC,KAAP;GAAZ;MACIhB,QAAQ;WAAKe,EAAEf,KAAP;GAAZ;;WAESiB,UAAT,CAAoBC,UAApB,EAAgC;;QAExBC,OAAOC,GAAGC,IAAH,GAAUC,GAAV,CAActB,KAAd,EAAqBuB,OAArB,CAA6BL,UAA7B,CAAb;;QAEMM,IAAIL,KAAKM,MAAf;;;;QAIMC,YAAY,EAAlB;QACMC,aAAaP,GAAGQ,KAAH,CAASJ,CAAT,CAAnB;QACMK,gBAAgB,EAAtB;QACMC,QAAQ,EAAd;UACMC,MAAN,GAAe,IAAIC,KAAJ,CAAUR,CAAV,CAAf;QACMO,SAASD,MAAMC,MAArB;QACIE,qBAAJ;UACMC,WAAN,GAAoB,EAApB;QACMC,cAAcL,MAAMI,WAA1B;QACME,cAAc,EAApB;QACIC,UAAJ;QACIlC,UAAJ;QACImC,WAAJ;QACIC,UAAJ;QACIC,UAAJ;QACIC,UAAJ;QACIC,UAAJ;QACIC,YAAJ;QACIC,gBAAJ;QACIC,eAAJ;QACIC,gBAAJ;QACIC,eAAe,KAAnB;QACIC,qBAAJ;QACI,CAAJ;mBACe,CAAf;SACK,IAAIC,IAAI,CAAb,EAAgBA,IAAIzB,CAApB,EAAuByB,KAAK,CAA5B,EAA+B;UACzB9B,KAAK8B,CAAL,EAAQC,MAAR,CAAezB,MAAnB;YACM,CAAN;WACKc,IAAI,CAAT,EAAYA,IAAIG,CAAhB,EAAmBH,KAAK,CAAxB,EAA2B;eAClBtC,MAAMkB,KAAK8B,CAAL,EAAQC,MAAR,CAAeX,CAAf,CAAN,CAAP;OAJ2B;gBAMnBY,IAAV,CAAeR,GAAf;oBACcQ,IAAd,CAAmB/B,GAAGQ,KAAH,CAASc,CAAT,CAAnB;sBACgBA,CAAhB;WACKC,GAAL;KA1C4B;;;QA8C1BlC,UAAJ,EAAgB;iBACH2C,IAAX,CAAgB,UAACtD,CAAD,EAAIC,CAAJ;eAAUU,WAAWiB,UAAU5B,CAAV,CAAX,EAAyB4B,UAAU3B,CAAV,CAAzB,CAAV;OAAhB;;;;QAIEW,aAAJ,EAAmB;oBACH2C,OAAd,CAAsB,UAACtC,CAAD,EAAIkC,CAAJ,EAAU;UAC5BG,IAAF,CAAO,UAACtD,CAAD,EAAIC,CAAJ;iBACLW,cAAcM,MAAMG,KAAK8B,CAAL,EAAQC,MAAR,CAAepD,CAAf,CAAN,CAAd,EAAwCkB,MAAMG,KAAK8B,CAAL,EAAQC,MAAR,CAAenD,CAAf,CAAN,CAAxC,CADK;SAAP;OADF;;;;;QASIuD,OAAOjB,KAAK7B,WAAWH,GAAhB,CAAb;QACI,CAAJ;SACK,IAAI4C,KAAI,CAAb,EAAgBA,KAAIzB,CAApB,EAAuByB,MAAK,CAA5B,EAA+B;gBACnBvB,UAAUC,WAAWsB,EAAX,CAAV,IAA2BK,IAArC;WACKV,OAAL;UACIJ,IAAI,CAACH,IAAIb,IAAI8B,IAAT,IAAiB,CAAzB,EAA4B;;iBAEjBjB,IAAIb,IAAI8B,IAAR,IAAgBd,IAAII,OAApB,CAAT;uBACeC,SAASD,OAAT,GAAmB,GAAnB,GACXjB,WAAWsB,EAAX,CADW,GAEXtB,WAAWsB,KAAI,CAAf,CAFJ;;OAN2B;KA/DD;;;QA6ExBM,SAASlB,IAAIzB,SAAJ,IAAiB,IAAIA,SAArB,CAAf;SACK2C,MAAL;;;QAGIjD,KAAKkD,GAAL,CAAS,CAAT,EAAYnD,MAAMG,WAAWgB,CAA7B,IAAkCa,CAAtC;QACMoB,KAAKpB,IAAI7B,QAAJ,GAAeH,MAAMmB,CAAhC;;;;QAIMkC,YAAY,IAAI1B,KAAJ,CAAUC,YAAV,CAAlB;QACIsB,SAAS,IAAT,GAAgBlB,CAApB,CAvF8B;cAwFpB,CAAV;SACK,IAAIY,MAAI,CAAb,EAAgBA,MAAIzB,CAApB,EAAuByB,OAAK,CAA5B,EAA+B;UACvBU,KAAKhC,WAAWsB,GAAX,CAAX;UACMW,YAAYzC,KAAKwC,EAAL,EAASrC,GAA3B;;WAEKnB,CAAL;UACI0B,cAAc8B,EAAd,EAAkBlC,MAAtB;WACKc,IAAI,CAAT,EAAYA,IAAIE,CAAhB,EAAmBF,KAAK,CAAxB,EAA2B;YACnBsB,KAAKd,eACPlB,cAAc8B,EAAd,EAAkBlB,IAAI,CAAJ,GAAQF,CAA1B,CADO,GAEPV,cAAc8B,EAAd,EAAkBpB,CAAlB,CAFJ;;YAIItC,MAAMkB,KAAKwC,EAAL,EAAST,MAAT,CAAgBW,EAAhB,CAAN,CAAJ;YACMC,YAAY9C,MAAMG,KAAKwC,EAAL,EAAST,MAAT,CAAgBW,EAAhB,CAAN,CAAlB;YACME,KAAK5D,CAAX;aACKuC,IAAIL,CAAT;YACM2B,KAAK7D,CAAX;kBACU2C,OAAV,IAAqB;iBACZa,EADY;oBAETE,EAFS;sBAGPE,EAHO;oBAITC,EAJS;iBAKZtB,CALY;8BAAA;8BAAA;2BAQFJ;SARnB;;;YAYI,CAACF,YAAY0B,SAAZ,CAAL,EAA6B;sBACfA,SAAZ,IAAyB,IAAzB;sBACYX,IAAZ,CAAiB,EAAEc,MAAMH,SAAR,EAAjB;SAxBuB;;mBA2Bd,CAAX;OAjC2B;aAmCtBH,EAAP,IAAa;eACJA,EADI;oBAECrB,EAFD;kBAGDnC,CAHC;eAIJuB,UAAUiC,EAAV,CAJI;;OAAb;WAOKF,EAAL;;UAEIT,iBAAiBW,EAArB,EAAyBxD,KAAKoD,SAAS,GAAT,GAAelB,CAApB;;UAErBlC,IAAIG,KAAKC,EAAb,EAAiBwC,eAAe,IAAf;KAvIW;;;QA2I1BrC,aAAJ,EAAmB;kBACL0C,IAAZ,CAAiB,UAACtD,CAAD,EAAIC,CAAJ;eAAUW,cAAcZ,EAAEmE,IAAhB,EAAsBlE,EAAEkE,IAAxB,CAAV;OAAjB;;;;QAIIC,IAAI/B,YAAYV,MAAtB;SACK,IAAIwB,MAAI,CAAb,EAAgBA,MAAIiB,CAApB,EAAuBjB,OAAK,CAA5B,EAA+B;kBACjBA,GAAZ,EAAe9C,CAAf,GAAmB,CAAnB;kBACY8C,GAAZ,EAAekB,CAAf,GAAmB,CAACD,CAAD,GAAKrD,WAAL,GAAmB,CAAnB,GAAuBoC,MAAIpC,WAA9C;kBACYoC,GAAZ,EAAemB,MAAf,GAAwBtD,WAAWqB,YAAYc,GAAZ,EAAegB,IAA1B,EAAgChB,GAAhC,CAAxB;KApJ4B;;;cAwJpB,CAAV;SACK,IAAIA,MAAI,CAAb,EAAgBA,MAAIzB,CAApB,EAAuByB,OAAK,CAA5B,EAA+B;UACvBU,MAAKhC,WAAWsB,GAAX,CAAX;UACIpB,cAAc8B,GAAd,EAAkBlC,MAAtB;WACKc,IAAI,CAAT,EAAYA,IAAIE,CAAhB,EAAmBF,KAAK,CAAxB,EAA2B;YACnB8B,aAAaX,UAAUZ,OAAV,CAAnB;YACMwB,YAAYD,WAAWP,SAA7B;;YAEMS,aAAaC,WAAWF,SAAX,EAAsB,MAAtB,EAA8BnC,WAA9B,CAAnB;YACIkC,WAAWpE,KAAf,EAAsB;gBACdkD,IAAN,CAAW,EAAEnC,OAAOuD,UAAT,EAAqBvE,OAAOqE,UAA5B,EAAX;SANuB;mBAQd,CAAX;OAX2B;KAzJD;;WAwKvB1D,YAAYmB,MAAMsB,IAAN,CAAWzC,SAAX,CAAZ,GAAoCmB,KAA3C;GAtL2B;;WAyLpB0C,UAAT,CAAoBC,IAApB,EAA0BC,QAA1B,EAAoCC,aAApC,EAAmD;SAC5C,IAAI1B,IAAI,CAAb,EAAgBA,IAAI0B,cAAclD,MAAlC,EAA0CwB,KAAK,CAA/C,EAAkD;UAC5C0B,cAAc1B,CAAd,EAAiByB,QAAjB,MAA+BD,IAAnC,EAAyC;eAChCE,cAAc1B,CAAd,CAAP;OAF8C;KADD;WAM1C,IAAP;GA/L2B;;aAkMlBzC,QAAX,GAAsB,UAASoE,CAAT,EAAY;WACzBC,UAAUpD,MAAV,IACDjB,WAAWF,KAAKkD,GAAL,CAAS,CAAT,EAAYoB,CAAZ,CAAZ,EAA6B3D,UAD3B,IAEHT,QAFJ;GADF;;aAMWQ,KAAX,GAAmB,UAAS4D,CAAT,EAAY;WACtBC,UAAUpD,MAAV,IAAqBT,QAAQ4D,CAAT,EAAa3D,UAAjC,IAA+CD,KAAtD;GADF;;aAIWhB,KAAX,GAAmB,UAAS4E,CAAT,EAAY;WACtBC,UAAUpD,MAAV,IAAqBzB,QAAQ4E,CAAT,EAAa3D,UAAjC,IAA+CjB,KAAtD;GADF;;aAIWC,KAAX,GAAmB,UAAS2E,CAAT,EAAY;WACtBC,UAAUpD,MAAV,IAAqBxB,QAAQ2E,CAAT,EAAa3D,UAAjC,IAA+ChB,KAAtD;GADF;;aAIWY,WAAX,GAAyB,UAAS+D,CAAT,EAAY;WAC5BC,UAAUpD,MAAV,IAAqBZ,cAAc+D,CAAf,EAAmB3D,UAAvC,IAAqDJ,WAA5D;GADF;;aAIWC,UAAX,GAAwB,UAAS8D,CAAT,EAAY;WAC3BC,UAAUpD,MAAV,IACDX,aAAa,OAAO8D,CAAP,KAAa,UAAb,GAA0BA,CAA1B,GAA8B1E,SAAS,CAAC0E,CAAV,CAA5C,EAA2D3D,UADzD,IAEHH,UAFJ;GADF;;aAMWF,SAAX,GAAuB,UAASgE,CAAT,EAAY;WAC1BC,UAAUpD,MAAV,IACDb,YAAYgE,IAAI,CAAJ,GACVtE,KAAKkD,GAAL,CAAS,CAAT,EAAYoB,CAAZ,CADU,GAEVtE,KAAKkD,GAAL,CAAS,CAAT,EAAYoB,IAAI,IAAhB,CAFH,EAE2B3D,UAHzB,IAIHL,SAJJ;GADF;;aAQWH,UAAX,GAAwB,UAASmE,CAAT,EAAY;WAC3BC,UAAUpD,MAAV,IAAqBhB,aAAamE,CAAd,EAAkB3D,UAAtC,IAAoDR,UAA3D;GADF;;aAIWC,aAAX,GAA2B,UAASkE,CAAT,EAAY;WAC9BC,UAAUpD,MAAV,IAAqBf,gBAAgBkE,CAAjB,EAAqB3D,UAAzC,IAAuDP,aAA9D;GADF;;aAIWC,SAAX,GAAuB,UAASiE,CAAT,EAAY;WAC1BC,UAAUpD,MAAV,IACFmD,KAAK,IAAL,GACIjE,YAAY,IADhB,GAEI,CAACA,YAAYf,aAAagF,CAAb,CAAb,EAA8BA,CAA9B,GAAkCA,CAFtC,EAE0C3D,UAHxC,IAIHN,aAAaA,UAAUiE,CAJ3B;GADF;;SAQO3D,UAAP;;;AC7PF;;AAEA,AAEA,AAAe,SAAS6D,MAAT,GAAkB;MACzBC,QAAQ/C,MAAMgD,SAAN,CAAgBD,KAA9B;MACME,MAAM3E,KAAK2E,GAAjB;MACMC,MAAM5E,KAAK4E,GAAjB;MACMC,SAAS7E,KAAKC,EAAL,GAAU,CAAzB;MACMF,MAAMC,KAAKC,EAAL,GAAU,CAAtB;;MAEIS,QAAQ;WAAKD,EAAEC,KAAP;GAAZ;MACIhB,QAAQ;WAAKe,EAAEf,KAAP;GAAZ;MACIoF,SAAS;WAAM,GAAN;GAAb;MACIC,kBAAkB;WAAKtE,EAAEsE,eAAP;GAAtB;MACIC,aAAa;WAAKvE,EAAEuE,UAAP;GAAjB;MACIC,WAAW;WAAKxE,EAAEwE,QAAP;GAAf;MACIpF,IAAI;WAAKY,EAAEZ,CAAP;GAAR;MACIgE,IAAI;WAAKpD,EAAEoD,CAAP;GAAR;MACIC,SAAS;WAAKrD,EAAEqD,MAAP;GAAb;MACIoB,UAAU,EAAd;MACIC,iBAAiB,CAArB;MACIC,UAAU,IAAd;;WAESC,YAAT,GAA+B;QACzBC,eAAJ;;sCADuBC,IAAM;UAAA;;;QAEvBC,OAAOf,MAAMgB,IAAN,CAAWF,IAAX,CAAb;QACMG,MAAMhG,MAAMiG,KAAN,CAAY,IAAZ,EAAkBH,IAAlB,CAAZ;QACMI,MAAMlF,MAAMiF,KAAN,CAAY,IAAZ,EAAkBH,IAAlB,CAAZ;SACK,CAAL,IAAUE,GAAV;QACMG,KAAK,CAACf,OAAOa,KAAP,CAAa,IAAb,EAAmBH,IAAnB,CAAZ;QACMM,MAAMd,WAAWW,KAAX,CAAiB,IAAjB,EAAuBH,IAAvB,IAA+BX,MAA3C;QACMkB,OAAOhB,gBAAgBY,KAAhB,CAAsB,IAAtB,EAA4BH,IAA5B,IAAoCX,MAAjD;QACMmB,MAAMf,SAASU,KAAT,CAAe,IAAf,EAAqBH,IAArB,IAA6BX,MAAzC;QACIoB,MAAMJ,KAAKlB,IAAImB,GAAJ,CAAf;QACMI,MAAML,KAAKjB,IAAIkB,GAAJ,CAAjB;QACIK,MAAMN,KAAKlB,IAAIqB,GAAJ,CAAf;QACMI,MAAMP,KAAKjB,IAAIoB,GAAJ,CAAjB;SACK,CAAL,IAAUJ,GAAV;;;QAGIS,KAAKxG,EAAE8F,KAAF,CAAQ,IAAR,EAAcH,IAAd,CAAT;QACMc,KAAKzC,EAAE8B,KAAF,CAAQ,IAAR,EAAcH,IAAd,CAAX;QACIe,UAAUzC,OAAO6B,KAAP,CAAa,IAAb,EAAmBH,IAAnB,CAAd;QACIgB,YAAJ;QACIC,YAAJ;QACIC,YAAJ;QACIC,YAAJ;;;QAGMC,WAAWb,OAAOlB,MAAP,GAAgB7E,KAAKC,EAArB,IAA2B8F,OAAOlB,MAAP,GAAgB9E,GAA5D;;QAEI6G,QAAJ,EAAcL,UAAU,CAACA,OAAX;UACRA,OAAN;;QAEMM,UAAUD,WAAW,CAACzB,cAAZ,GAA6BA,cAA7C;;QAEI,CAACC,OAAL,EAAc;eACHtE,GAAGgG,IAAH,EAAT;gBACUxB,MAAV;;;;QAIIyB,iBAAiB,CAACH,WAAW,CAAC,CAAZ,GAAgB,CAAjB,IAAsB1B,OAA7C;WACO6B,cAAP;WACOA,cAAP;;YAEQC,MAAR,CAAef,GAAf,EAAoBC,GAApB;;YAEQe,GAAR,CAAYF,cAAZ,EAA4B,CAA5B,EAA+BlB,EAA/B,EAAmCC,GAAnC,EAAwCE,GAAxC;;UAEMlF,GAAGoG,iBAAH,CAAqBH,cAArB,EAAqCZ,GAArC,EAA0C,GAA1C,CAAN;UACMrF,GAAGoG,iBAAH,CAAqB,CAArB,EAAwBd,GAAxB,EAA6B,GAA7B,CAAN;QACK,CAACQ,QAAD,IAAaT,MAAME,EAApB,IAA4BO,YAAYT,MAAME,EAAlD,EAAuD;;YAE/CA,KAAK,CAACA,KAAKF,GAAN,IAAa,CAAxB;YACMrF,GAAGoG,iBAAH,CAAqBZ,KAAKO,UAAU,CAApC,EAAuCT,GAAvC,EAA4C,GAA5C,CAAN;KAHF,MAIO;YACCtF,GAAGoG,iBAAH,CAAqBb,EAArB,EAAyBF,GAAzB,EAA8B,IAA9B,CAAN;YACMG,KAAKO,UAAU,CAArB;KAvD2B;YAyDrBM,aAAR,CAAsBX,GAAtB,EAA2BC,GAA3B,EAAgCC,GAAhC,EAAqCC,GAArC,EAA0CN,EAA1C,EAA8CC,KAAKO,UAAU,CAA7D;;YAEQO,MAAR,CAAef,EAAf,EAAmBC,KAAKO,UAAU,CAAlC;;UAEM/F,GAAGoG,iBAAH,CAAqBH,cAArB,EAAqCd,GAArC,EAA0C,GAA1C,CAAN;UACMnF,GAAGoG,iBAAH,CAAqB,CAArB,EAAwBhB,GAAxB,EAA6B,GAA7B,CAAN;QACK,CAACU,QAAD,IAAaX,MAAMI,EAApB,IAA4BO,YAAYX,MAAMI,EAAlD,EAAuD;;YAE/CA,KAAK,CAACA,KAAKJ,GAAN,IAAa,CAAxB;YACMnF,GAAGoG,iBAAH,CAAqBZ,KAAKO,UAAU,CAApC,EAAuCX,GAAvC,EAA4C,GAA5C,CAAN;KAHF,MAIO;YACCpF,GAAGoG,iBAAH,CAAqBb,EAArB,EAAyBJ,GAAzB,EAA8B,IAA9B,CAAN;YACMK,KAAKO,UAAU,CAArB;KArE2B;YAuErBM,aAAR,CAAsBT,GAAtB,EAA2BC,GAA3B,EAAgCH,GAAhC,EAAqCC,GAArC,EAA0CR,GAA1C,EAA+CC,GAA/C;;YAEQmB,SAAR;;QAEI/B,MAAJ,EAAY;gBACA,IAAV;aACO,KAAGA,MAAH,IAAe,IAAtB;;WAEK,IAAP;;;eAGWR,MAAb,GAAsB,UAASR,CAAT,EAAY;WACzBC,UAAUpD,MAAV,IACD2D,SAAS,OAAOR,CAAP,KAAa,UAAb,GAA0BA,CAA1B,GAA8B1E,SAAS,CAAC0E,CAAV,CAAxC,EAAuDe,YADrD,IAEHP,MAFJ;GADF;;eAMaC,eAAb,GAA+B,UAAST,CAAT,EAAY;WAClCC,UAAUpD,MAAV,IACD4D,kBAAkB,OAAOT,CAAP,KAAa,UAAb,GAChBA,CADgB,GAEhB1E,SAAS,CAAC0E,CAAV,CAFH,EAEkBe,YAHhB,IAIHN,eAJJ;GADF;;eAQaC,UAAb,GAA0B,UAASV,CAAT,EAAY;WAC7BC,UAAUpD,MAAV,IACD6D,aAAa,OAAOV,CAAP,KAAa,UAAb,GACXA,CADW,GAEX1E,SAAS,CAAC0E,CAAV,CAFH,EAEkBe,YAHhB,IAIHL,UAJJ;GADF;;eAQaC,QAAb,GAAwB,UAASX,CAAT,EAAY;WAC3BC,UAAUpD,MAAV,IACD8D,WAAW,OAAOX,CAAP,KAAa,UAAb,GAA0BA,CAA1B,GAA8B1E,SAAS,CAAC0E,CAAV,CAA1C,EAAyDe,YADvD,IAEHJ,QAFJ;GADF;;eAMapF,CAAb,GAAiB,UAASyE,CAAT,EAAY;WACpBC,UAAUpD,MAAV,IAAqBtB,IAAIyE,CAAL,EAASe,YAA7B,IAA6CxF,CAApD;GADF;;eAIagE,CAAb,GAAiB,UAASS,CAAT,EAAY;WACpBC,UAAUpD,MAAV,IAAqB0C,IAAIS,CAAL,EAASe,YAA7B,IAA6CxB,CAApD;GADF;;eAIaC,MAAb,GAAsB,UAASQ,CAAT,EAAY;WACzBC,UAAUpD,MAAV,IAAqB2C,SAASQ,CAAV,EAAce,YAAlC,IAAkDvB,MAAzD;GADF;;eAIaqB,cAAb,GAA8B,UAASb,CAAT,EAAY;WACjCC,UAAUpD,MAAV,IACDgE,iBAAiBb,CAAlB,EAAsBe,YADpB,IAEHF,cAFJ;GADF;;eAMazE,KAAb,GAAqB,UAAS4D,CAAT,EAAY;WACxBC,UAAUpD,MAAV,IAAqBT,QAAQ4D,CAAT,EAAae,YAAjC,IAAiD3E,KAAxD;GADF;;eAIahB,KAAb,GAAqB,UAAS4E,CAAT,EAAY;WACxBC,UAAUpD,MAAV,IAAqBzB,QAAQ4E,CAAT,EAAae,YAAjC,IAAiD3F,KAAxD;GADF;;eAIawF,OAAb,GAAuB,UAASZ,CAAT,EAAY;WAC1BC,UAAUpD,MAAV,IAAqB+D,UAAUZ,CAAX,EAAee,YAAnC,IAAmDH,OAA1D;GADF;;eAIaE,OAAb,GAAuB,UAASd,CAAT,EAAY;WAC1BC,UAAUpD,MAAV,IACDiE,UAAUd,KAAK,IAAL,GAAY,IAAZ,GAAmBA,CAA9B,EAAkCe,YADhC,IAEHD,OAFJ;GADF;;SAMOC,YAAP;;;;;;;;"} -------------------------------------------------------------------------------- /build/d3-loom.min.js: -------------------------------------------------------------------------------- 1 | !function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(n.d3=n.d3||{})}(this,function(n){"use strict";function t(n){return function(t,e){return n(t.outer.value,e.outer.value)}}function e(n){return function(){return n}}function r(){function n(n){var t=d3.nest().key(p).entries(n),e=t.length,g=[],d=d3.range(e),y=[],m=[];m.groups=new Array(e);var A=m.groups,b=void 0;m.innergroups=[];var x=m.innergroups,M=[],I=void 0,N=void 0,P=void 0,k=void 0,S=void 0,T=void 0,_=void 0,w=void 0,j=void 0,z=void 0,C=void 0,E=!1,G=void 0;I=0,b=0;for(var L=0;L(I+e*O)/2){z=I+e*O-(S-j),G=z/j<.5?d[q]:d[q-1];break}var B=I*f/(1-f);I+=B,I=Math.max(0,u-o*e)/I;var D=I?o:u/e,F=new Array(b);N=.25*B*I,C=0;for(var H=0;HMath.PI&&(E=!0)}l&&x.sort(function(n,t){return l(n.name,t.name)});for(var W=x.length,X=0;XMath.PI&&k+oz?(O=z+(z-w)/2,q=d3.interpolateNumber(C+D/2,j)(.5)):(O=d3.interpolateNumber(z,w)(.25),q=C+D/2),m.bezierCurveTo(G,L,O,q,z,C+D/2),m.lineTo(z,C-D/2),G=d3.interpolateNumber(F,T)(.5),L=d3.interpolateNumber(0,_)(.5),!B&&Tz?(O=z+(z-T)/2,q=d3.interpolateNumber(C-D/2,_)(.5)):(O=d3.interpolateNumber(z,T)(.25),q=C-D/2),m.bezierCurveTo(O,q,G,L,T,_),m.closePath(),n?(m=null,""+n||null):null}var t=Array.prototype.slice,r=Math.cos,u=Math.sin,o=Math.PI/2,i=2*Math.PI,l=function(n){return n.inner},a=function(n){return n.outer},f=function(){return 100},c=function(n){return n.groupStartAngle},h=function(n){return n.startAngle},v=function(n){return n.endAngle},s=function(n){return n.x},p=function(n){return n.y},g=function(n){return n.offset},d=50,y=0,m=null;return n.radius=function(t){return arguments.length?(f="function"==typeof t?t:e(+t),n):f},n.groupStartAngle=function(t){return arguments.length?(c="function"==typeof t?t:e(+t),n):c},n.startAngle=function(t){return arguments.length?(h="function"==typeof t?t:e(+t),n):h},n.endAngle=function(t){return arguments.length?(v="function"==typeof t?t:e(+t),n):v},n.x=function(t){return arguments.length?(s=t,n):s},n.y=function(t){return arguments.length?(p=t,n):p},n.offset=function(t){return arguments.length?(g=t,n):g},n.thicknessInner=function(t){return arguments.length?(y=t,n):y},n.inner=function(t){return arguments.length?(l=t,n):l},n.outer=function(t){return arguments.length?(a=t,n):a},n.pullout=function(t){return arguments.length?(d=t,n):d},n.context=function(t){return arguments.length?(m=null==t?null:t,n):m},n}n.loom=r,n.string=u,Object.defineProperty(n,"__esModule",{value:!0})}); -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 50 | 51 | 52 | 53 | 54 | 55 |
56 | 57 | 211 | 212 | -------------------------------------------------------------------------------- /example/lotr_words_location.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "location": "The Shire", 4 | "character": "Frodo", 5 | "words": 679 6 | }, 7 | { 8 | "location": "The Shire", 9 | "character": "Pippin", 10 | "words": 124 11 | }, 12 | { 13 | "location": "The Shire", 14 | "character": "Sam", 15 | "words": 239 16 | }, 17 | { 18 | "location": "The Shire", 19 | "character": "Gandalf", 20 | "words": 1064 21 | }, 22 | { 23 | "location": "The Shire", 24 | "character": "Merry", 25 | "words": 173 26 | }, 27 | { 28 | "location": "Bree", 29 | "character": "Aragorn", 30 | "words": 258 31 | }, 32 | { 33 | "location": "Bree", 34 | "character": "Frodo", 35 | "words": 125 36 | }, 37 | { 38 | "location": "Bree", 39 | "character": "Merry", 40 | "words": 56 41 | }, 42 | { 43 | "location": "Bree", 44 | "character": "Pippin", 45 | "words": 76 46 | }, 47 | { 48 | "location": "Bree", 49 | "character": "Sam", 50 | "words": 71 51 | }, 52 | { 53 | "location": "Isengard", 54 | "character": "Aragorn", 55 | "words": 3 56 | }, 57 | { 58 | "location": "Isengard", 59 | "character": "Pippin", 60 | "words": 108 61 | }, 62 | { 63 | "location": "Isengard", 64 | "character": "Gimli", 65 | "words": 45 66 | }, 67 | { 68 | "location": "Isengard", 69 | "character": "Gandalf", 70 | "words": 224 71 | }, 72 | { 73 | "location": "Isengard", 74 | "character": "Merry", 75 | "words": 116 76 | }, 77 | { 78 | "location": "Rivendell", 79 | "character": "Frodo", 80 | "words": 153 81 | }, 82 | { 83 | "location": "Rivendell", 84 | "character": "Boromir", 85 | "words": 259 86 | }, 87 | { 88 | "location": "Rivendell", 89 | "character": "Gimli", 90 | "words": 38 91 | }, 92 | { 93 | "location": "Rivendell", 94 | "character": "Legolas", 95 | "words": 34 96 | }, 97 | { 98 | "location": "Rivendell", 99 | "character": "Sam", 100 | "words": 105 101 | }, 102 | { 103 | "location": "Rivendell", 104 | "character": "Gandalf", 105 | "words": 276 106 | }, 107 | { 108 | "location": "Rivendell", 109 | "character": "Aragorn", 110 | "words": 232 111 | }, 112 | { 113 | "location": "Rivendell", 114 | "character": "Merry", 115 | "words": 29 116 | }, 117 | { 118 | "location": "Rivendell", 119 | "character": "Pippin", 120 | "words": 27 121 | }, 122 | { 123 | "location": "Misty Mountains", 124 | "character": "Legolas", 125 | "words": 11 126 | }, 127 | { 128 | "location": "Misty Mountains", 129 | "character": "Merry", 130 | "words": 17 131 | }, 132 | { 133 | "location": "Misty Mountains", 134 | "character": "Pippin", 135 | "words": 10 136 | }, 137 | { 138 | "location": "Misty Mountains", 139 | "character": "Sam", 140 | "words": 3 141 | }, 142 | { 143 | "location": "Misty Mountains", 144 | "character": "Aragorn", 145 | "words": 42 146 | }, 147 | { 148 | "location": "Misty Mountains", 149 | "character": "Boromir", 150 | "words": 76 151 | }, 152 | { 153 | "location": "Misty Mountains", 154 | "character": "Gandalf", 155 | "words": 86 156 | }, 157 | { 158 | "location": "Misty Mountains", 159 | "character": "Gimli", 160 | "words": 66 161 | }, 162 | { 163 | "location": "Misty Mountains", 164 | "character": "Frodo", 165 | "words": 6 166 | }, 167 | { 168 | "location": "Moria", 169 | "character": "Gandalf", 170 | "words": 762 171 | }, 172 | { 173 | "location": "Moria", 174 | "character": "Gimli", 175 | "words": 102 176 | }, 177 | { 178 | "location": "Moria", 179 | "character": "Legolas", 180 | "words": 19 181 | }, 182 | { 183 | "location": "Moria", 184 | "character": "Merry", 185 | "words": 17 186 | }, 187 | { 188 | "location": "Moria", 189 | "character": "Pippin", 190 | "words": 21 191 | }, 192 | { 193 | "location": "Moria", 194 | "character": "Sam", 195 | "words": 32 196 | }, 197 | { 198 | "location": "Moria", 199 | "character": "Frodo", 200 | "words": 90 201 | }, 202 | { 203 | "location": "Moria", 204 | "character": "Boromir", 205 | "words": 55 206 | }, 207 | { 208 | "location": "Moria", 209 | "character": "Aragorn", 210 | "words": 98 211 | }, 212 | { 213 | "location": "Lothlorien", 214 | "character": "Legolas", 215 | "words": 68 216 | }, 217 | { 218 | "location": "Lothlorien", 219 | "character": "Sam", 220 | "words": 64 221 | }, 222 | { 223 | "location": "Lothlorien", 224 | "character": "Merry", 225 | "words": 11 226 | }, 227 | { 228 | "location": "Lothlorien", 229 | "character": "Frodo", 230 | "words": 36 231 | }, 232 | { 233 | "location": "Lothlorien", 234 | "character": "Pippin", 235 | "words": 1 236 | }, 237 | { 238 | "location": "Lothlorien", 239 | "character": "Aragorn", 240 | "words": 55 241 | }, 242 | { 243 | "location": "Lothlorien", 244 | "character": "Boromir", 245 | "words": 176 246 | }, 247 | { 248 | "location": "Lothlorien", 249 | "character": "Gimli", 250 | "words": 165 251 | }, 252 | { 253 | "location": "Parth Galen", 254 | "character": "Sam", 255 | "words": 89 256 | }, 257 | { 258 | "location": "Parth Galen", 259 | "character": "Frodo", 260 | "words": 129 261 | }, 262 | { 263 | "location": "Parth Galen", 264 | "character": "Pippin", 265 | "words": 17 266 | }, 267 | { 268 | "location": "Parth Galen", 269 | "character": "Boromir", 270 | "words": 398 271 | }, 272 | { 273 | "location": "Parth Galen", 274 | "character": "Aragorn", 275 | "words": 319 276 | }, 277 | { 278 | "location": "Parth Galen", 279 | "character": "Gimli", 280 | "words": 60 281 | }, 282 | { 283 | "location": "Parth Galen", 284 | "character": "Legolas", 285 | "words": 52 286 | }, 287 | { 288 | "location": "Parth Galen", 289 | "character": "Merry", 290 | "words": 20 291 | }, 292 | { 293 | "location": "Emyn Muil", 294 | "character": "Sam", 295 | "words": 347 296 | }, 297 | { 298 | "location": "Emyn Muil", 299 | "character": "Frodo", 300 | "words": 223 301 | }, 302 | { 303 | "location": "Rohan", 304 | "character": "Aragorn", 305 | "words": 907 306 | }, 307 | { 308 | "location": "Rohan", 309 | "character": "Legolas", 310 | "words": 407 311 | }, 312 | { 313 | "location": "Rohan", 314 | "character": "Pippin", 315 | "words": 203 316 | }, 317 | { 318 | "location": "Rohan", 319 | "character": "Merry", 320 | "words": 281 321 | }, 322 | { 323 | "location": "Rohan", 324 | "character": "Gandalf", 325 | "words": 671 326 | }, 327 | { 328 | "location": "Rohan", 329 | "character": "Gimli", 330 | "words": 607 331 | }, 332 | { 333 | "location": "Fangorn", 334 | "character": "Gandalf", 335 | "words": 524 336 | }, 337 | { 338 | "location": "Fangorn", 339 | "character": "Legolas", 340 | "words": 73 341 | }, 342 | { 343 | "location": "Fangorn", 344 | "character": "Merry", 345 | "words": 297 346 | }, 347 | { 348 | "location": "Fangorn", 349 | "character": "Pippin", 350 | "words": 276 351 | }, 352 | { 353 | "location": "Fangorn", 354 | "character": "Aragorn", 355 | "words": 108 356 | }, 357 | { 358 | "location": "Fangorn", 359 | "character": "Gimli", 360 | "words": 89 361 | }, 362 | { 363 | "location": "Gondor", 364 | "character": "Boromir", 365 | "words": 132 366 | }, 367 | { 368 | "location": "Gondor", 369 | "character": "Sam", 370 | "words": 822 371 | }, 372 | { 373 | "location": "Gondor", 374 | "character": "Frodo", 375 | "words": 491 376 | }, 377 | { 378 | "location": "Gondor", 379 | "character": "Gandalf", 380 | "words": 1155 381 | }, 382 | { 383 | "location": "Gondor", 384 | "character": "Pippin", 385 | "words": 386 386 | }, 387 | { 388 | "location": "Gondor", 389 | "character": "Aragorn", 390 | "words": 175 391 | }, 392 | { 393 | "location": "Gondor", 394 | "character": "Gimli", 395 | "words": 72 396 | }, 397 | { 398 | "location": "Gondor", 399 | "character": "Merry", 400 | "words": 97 401 | }, 402 | { 403 | "location": "Gondor", 404 | "character": "Legolas", 405 | "words": 8 406 | }, 407 | { 408 | "location": "Mordor", 409 | "character": "Legolas", 410 | "words": 8 411 | }, 412 | { 413 | "location": "Mordor", 414 | "character": "Frodo", 415 | "words": 361 416 | }, 417 | { 418 | "location": "Mordor", 419 | "character": "Aragorn", 420 | "words": 128 421 | }, 422 | { 423 | "location": "Mordor", 424 | "character": "Gandalf", 425 | "words": 32 426 | }, 427 | { 428 | "location": "Mordor", 429 | "character": "Gimli", 430 | "words": 21 431 | }, 432 | { 433 | "location": "Mordor", 434 | "character": "Merry", 435 | "words": 3 436 | }, 437 | { 438 | "location": "Mordor", 439 | "character": "Pippin", 440 | "words": 12 441 | }, 442 | { 443 | "location": "Mordor", 444 | "character": "Sam", 445 | "words": 753 446 | } 447 | ] -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | export { default as loom } from './src/loom'; 2 | export { default as string } from './src/string'; 3 | -------------------------------------------------------------------------------- /lotr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbremer/d3-loom/04c7b59bdfbac82560eb851bc1354a3fd9aaad80/lotr.png -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "d3-loom", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abab": { 8 | "version": "1.0.3", 9 | "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.3.tgz", 10 | "integrity": "sha1-uB3l9ydOxOdW15fNg08wNkJyTl0=", 11 | "dev": true 12 | }, 13 | "acorn": { 14 | "version": "5.1.1", 15 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.1.tgz", 16 | "integrity": "sha512-vOk6uEMctu0vQrvuSqFdJyqj1Q0S5VTDL79qtjo+DhRr+1mmaD+tluFSCZqhvi/JUhXSzoZN2BhtstaPEeE8cw==", 17 | "dev": true 18 | }, 19 | "acorn-globals": { 20 | "version": "3.1.0", 21 | "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", 22 | "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", 23 | "dev": true, 24 | "requires": { 25 | "acorn": "4.0.13" 26 | }, 27 | "dependencies": { 28 | "acorn": { 29 | "version": "4.0.13", 30 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", 31 | "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", 32 | "dev": true 33 | } 34 | } 35 | }, 36 | "acorn-jsx": { 37 | "version": "3.0.1", 38 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", 39 | "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", 40 | "dev": true, 41 | "requires": { 42 | "acorn": "3.3.0" 43 | }, 44 | "dependencies": { 45 | "acorn": { 46 | "version": "3.3.0", 47 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", 48 | "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", 49 | "dev": true 50 | } 51 | } 52 | }, 53 | "ajv": { 54 | "version": "4.11.8", 55 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", 56 | "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", 57 | "dev": true, 58 | "requires": { 59 | "co": "4.6.0", 60 | "json-stable-stringify": "1.0.1" 61 | } 62 | }, 63 | "ajv-keywords": { 64 | "version": "1.5.1", 65 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", 66 | "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", 67 | "dev": true 68 | }, 69 | "align-text": { 70 | "version": "0.1.4", 71 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", 72 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", 73 | "dev": true, 74 | "requires": { 75 | "kind-of": "3.2.2", 76 | "longest": "1.0.1", 77 | "repeat-string": "1.6.1" 78 | } 79 | }, 80 | "amdefine": { 81 | "version": "1.0.1", 82 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", 83 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", 84 | "dev": true, 85 | "optional": true 86 | }, 87 | "ansi-escapes": { 88 | "version": "1.4.0", 89 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", 90 | "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", 91 | "dev": true 92 | }, 93 | "ansi-regex": { 94 | "version": "2.1.1", 95 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 96 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 97 | "dev": true 98 | }, 99 | "ansi-styles": { 100 | "version": "2.2.1", 101 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 102 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", 103 | "dev": true 104 | }, 105 | "argparse": { 106 | "version": "1.0.9", 107 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", 108 | "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", 109 | "dev": true, 110 | "requires": { 111 | "sprintf-js": "1.0.3" 112 | } 113 | }, 114 | "array-equal": { 115 | "version": "1.0.0", 116 | "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", 117 | "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", 118 | "dev": true 119 | }, 120 | "array-union": { 121 | "version": "1.0.2", 122 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", 123 | "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", 124 | "dev": true, 125 | "requires": { 126 | "array-uniq": "1.0.3" 127 | } 128 | }, 129 | "array-uniq": { 130 | "version": "1.0.3", 131 | "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", 132 | "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", 133 | "dev": true 134 | }, 135 | "arrify": { 136 | "version": "1.0.1", 137 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", 138 | "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", 139 | "dev": true 140 | }, 141 | "asn1": { 142 | "version": "0.2.3", 143 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", 144 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", 145 | "dev": true 146 | }, 147 | "assert-plus": { 148 | "version": "0.2.0", 149 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", 150 | "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", 151 | "dev": true 152 | }, 153 | "asynckit": { 154 | "version": "0.4.0", 155 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 156 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", 157 | "dev": true 158 | }, 159 | "aws-sign2": { 160 | "version": "0.6.0", 161 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", 162 | "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", 163 | "dev": true 164 | }, 165 | "aws4": { 166 | "version": "1.6.0", 167 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", 168 | "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", 169 | "dev": true 170 | }, 171 | "babel-code-frame": { 172 | "version": "6.22.0", 173 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", 174 | "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", 175 | "dev": true, 176 | "requires": { 177 | "chalk": "1.1.3", 178 | "esutils": "2.0.2", 179 | "js-tokens": "3.0.2" 180 | } 181 | }, 182 | "babel-core": { 183 | "version": "6.25.0", 184 | "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz", 185 | "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", 186 | "dev": true, 187 | "requires": { 188 | "babel-code-frame": "6.22.0", 189 | "babel-generator": "6.25.0", 190 | "babel-helpers": "6.24.1", 191 | "babel-messages": "6.23.0", 192 | "babel-register": "6.24.1", 193 | "babel-runtime": "6.25.0", 194 | "babel-template": "6.25.0", 195 | "babel-traverse": "6.25.0", 196 | "babel-types": "6.25.0", 197 | "babylon": "6.17.4", 198 | "convert-source-map": "1.5.0", 199 | "debug": "2.6.8", 200 | "json5": "0.5.1", 201 | "lodash": "4.17.4", 202 | "minimatch": "3.0.4", 203 | "path-is-absolute": "1.0.1", 204 | "private": "0.1.7", 205 | "slash": "1.0.0", 206 | "source-map": "0.5.6" 207 | } 208 | }, 209 | "babel-generator": { 210 | "version": "6.25.0", 211 | "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.25.0.tgz", 212 | "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", 213 | "dev": true, 214 | "requires": { 215 | "babel-messages": "6.23.0", 216 | "babel-runtime": "6.25.0", 217 | "babel-types": "6.25.0", 218 | "detect-indent": "4.0.0", 219 | "jsesc": "1.3.0", 220 | "lodash": "4.17.4", 221 | "source-map": "0.5.6", 222 | "trim-right": "1.0.1" 223 | }, 224 | "dependencies": { 225 | "jsesc": { 226 | "version": "1.3.0", 227 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", 228 | "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", 229 | "dev": true 230 | } 231 | } 232 | }, 233 | "babel-helper-call-delegate": { 234 | "version": "6.24.1", 235 | "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", 236 | "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", 237 | "dev": true, 238 | "requires": { 239 | "babel-helper-hoist-variables": "6.24.1", 240 | "babel-runtime": "6.25.0", 241 | "babel-traverse": "6.25.0", 242 | "babel-types": "6.25.0" 243 | } 244 | }, 245 | "babel-helper-define-map": { 246 | "version": "6.24.1", 247 | "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz", 248 | "integrity": "sha1-epdH8ljYlH0y1RX2qhx70CIEoIA=", 249 | "dev": true, 250 | "requires": { 251 | "babel-helper-function-name": "6.24.1", 252 | "babel-runtime": "6.25.0", 253 | "babel-types": "6.25.0", 254 | "lodash": "4.17.4" 255 | } 256 | }, 257 | "babel-helper-function-name": { 258 | "version": "6.24.1", 259 | "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", 260 | "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", 261 | "dev": true, 262 | "requires": { 263 | "babel-helper-get-function-arity": "6.24.1", 264 | "babel-runtime": "6.25.0", 265 | "babel-template": "6.25.0", 266 | "babel-traverse": "6.25.0", 267 | "babel-types": "6.25.0" 268 | } 269 | }, 270 | "babel-helper-get-function-arity": { 271 | "version": "6.24.1", 272 | "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", 273 | "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", 274 | "dev": true, 275 | "requires": { 276 | "babel-runtime": "6.25.0", 277 | "babel-types": "6.25.0" 278 | } 279 | }, 280 | "babel-helper-hoist-variables": { 281 | "version": "6.24.1", 282 | "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", 283 | "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", 284 | "dev": true, 285 | "requires": { 286 | "babel-runtime": "6.25.0", 287 | "babel-types": "6.25.0" 288 | } 289 | }, 290 | "babel-helper-optimise-call-expression": { 291 | "version": "6.24.1", 292 | "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", 293 | "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", 294 | "dev": true, 295 | "requires": { 296 | "babel-runtime": "6.25.0", 297 | "babel-types": "6.25.0" 298 | } 299 | }, 300 | "babel-helper-regex": { 301 | "version": "6.24.1", 302 | "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz", 303 | "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", 304 | "dev": true, 305 | "requires": { 306 | "babel-runtime": "6.25.0", 307 | "babel-types": "6.25.0", 308 | "lodash": "4.17.4" 309 | } 310 | }, 311 | "babel-helper-replace-supers": { 312 | "version": "6.24.1", 313 | "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", 314 | "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", 315 | "dev": true, 316 | "requires": { 317 | "babel-helper-optimise-call-expression": "6.24.1", 318 | "babel-messages": "6.23.0", 319 | "babel-runtime": "6.25.0", 320 | "babel-template": "6.25.0", 321 | "babel-traverse": "6.25.0", 322 | "babel-types": "6.25.0" 323 | } 324 | }, 325 | "babel-helpers": { 326 | "version": "6.24.1", 327 | "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", 328 | "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", 329 | "dev": true, 330 | "requires": { 331 | "babel-runtime": "6.25.0", 332 | "babel-template": "6.25.0" 333 | } 334 | }, 335 | "babel-messages": { 336 | "version": "6.23.0", 337 | "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", 338 | "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", 339 | "dev": true, 340 | "requires": { 341 | "babel-runtime": "6.25.0" 342 | } 343 | }, 344 | "babel-plugin-check-es2015-constants": { 345 | "version": "6.22.0", 346 | "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", 347 | "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", 348 | "dev": true, 349 | "requires": { 350 | "babel-runtime": "6.25.0" 351 | } 352 | }, 353 | "babel-plugin-external-helpers": { 354 | "version": "6.22.0", 355 | "resolved": "https://registry.npmjs.org/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz", 356 | "integrity": "sha1-IoX0iwK9Xe3oUXXK+MYuhq3M76E=", 357 | "dev": true, 358 | "requires": { 359 | "babel-runtime": "6.25.0" 360 | } 361 | }, 362 | "babel-plugin-transform-es2015-arrow-functions": { 363 | "version": "6.22.0", 364 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", 365 | "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", 366 | "dev": true, 367 | "requires": { 368 | "babel-runtime": "6.25.0" 369 | } 370 | }, 371 | "babel-plugin-transform-es2015-block-scoped-functions": { 372 | "version": "6.22.0", 373 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", 374 | "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", 375 | "dev": true, 376 | "requires": { 377 | "babel-runtime": "6.25.0" 378 | } 379 | }, 380 | "babel-plugin-transform-es2015-block-scoping": { 381 | "version": "6.24.1", 382 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz", 383 | "integrity": "sha1-dsKV3DpHQbFmWt/TFnIV3P8ypXY=", 384 | "dev": true, 385 | "requires": { 386 | "babel-runtime": "6.25.0", 387 | "babel-template": "6.25.0", 388 | "babel-traverse": "6.25.0", 389 | "babel-types": "6.25.0", 390 | "lodash": "4.17.4" 391 | } 392 | }, 393 | "babel-plugin-transform-es2015-classes": { 394 | "version": "6.24.1", 395 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", 396 | "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", 397 | "dev": true, 398 | "requires": { 399 | "babel-helper-define-map": "6.24.1", 400 | "babel-helper-function-name": "6.24.1", 401 | "babel-helper-optimise-call-expression": "6.24.1", 402 | "babel-helper-replace-supers": "6.24.1", 403 | "babel-messages": "6.23.0", 404 | "babel-runtime": "6.25.0", 405 | "babel-template": "6.25.0", 406 | "babel-traverse": "6.25.0", 407 | "babel-types": "6.25.0" 408 | } 409 | }, 410 | "babel-plugin-transform-es2015-computed-properties": { 411 | "version": "6.24.1", 412 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", 413 | "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", 414 | "dev": true, 415 | "requires": { 416 | "babel-runtime": "6.25.0", 417 | "babel-template": "6.25.0" 418 | } 419 | }, 420 | "babel-plugin-transform-es2015-destructuring": { 421 | "version": "6.23.0", 422 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", 423 | "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", 424 | "dev": true, 425 | "requires": { 426 | "babel-runtime": "6.25.0" 427 | } 428 | }, 429 | "babel-plugin-transform-es2015-duplicate-keys": { 430 | "version": "6.24.1", 431 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", 432 | "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", 433 | "dev": true, 434 | "requires": { 435 | "babel-runtime": "6.25.0", 436 | "babel-types": "6.25.0" 437 | } 438 | }, 439 | "babel-plugin-transform-es2015-for-of": { 440 | "version": "6.23.0", 441 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", 442 | "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", 443 | "dev": true, 444 | "requires": { 445 | "babel-runtime": "6.25.0" 446 | } 447 | }, 448 | "babel-plugin-transform-es2015-function-name": { 449 | "version": "6.24.1", 450 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", 451 | "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", 452 | "dev": true, 453 | "requires": { 454 | "babel-helper-function-name": "6.24.1", 455 | "babel-runtime": "6.25.0", 456 | "babel-types": "6.25.0" 457 | } 458 | }, 459 | "babel-plugin-transform-es2015-literals": { 460 | "version": "6.22.0", 461 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", 462 | "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", 463 | "dev": true, 464 | "requires": { 465 | "babel-runtime": "6.25.0" 466 | } 467 | }, 468 | "babel-plugin-transform-es2015-modules-amd": { 469 | "version": "6.24.1", 470 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", 471 | "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", 472 | "dev": true, 473 | "requires": { 474 | "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", 475 | "babel-runtime": "6.25.0", 476 | "babel-template": "6.25.0" 477 | } 478 | }, 479 | "babel-plugin-transform-es2015-modules-commonjs": { 480 | "version": "6.24.1", 481 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz", 482 | "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", 483 | "dev": true, 484 | "requires": { 485 | "babel-plugin-transform-strict-mode": "6.24.1", 486 | "babel-runtime": "6.25.0", 487 | "babel-template": "6.25.0", 488 | "babel-types": "6.25.0" 489 | } 490 | }, 491 | "babel-plugin-transform-es2015-modules-systemjs": { 492 | "version": "6.24.1", 493 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", 494 | "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", 495 | "dev": true, 496 | "requires": { 497 | "babel-helper-hoist-variables": "6.24.1", 498 | "babel-runtime": "6.25.0", 499 | "babel-template": "6.25.0" 500 | } 501 | }, 502 | "babel-plugin-transform-es2015-modules-umd": { 503 | "version": "6.24.1", 504 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", 505 | "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", 506 | "dev": true, 507 | "requires": { 508 | "babel-plugin-transform-es2015-modules-amd": "6.24.1", 509 | "babel-runtime": "6.25.0", 510 | "babel-template": "6.25.0" 511 | } 512 | }, 513 | "babel-plugin-transform-es2015-object-super": { 514 | "version": "6.24.1", 515 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", 516 | "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", 517 | "dev": true, 518 | "requires": { 519 | "babel-helper-replace-supers": "6.24.1", 520 | "babel-runtime": "6.25.0" 521 | } 522 | }, 523 | "babel-plugin-transform-es2015-parameters": { 524 | "version": "6.24.1", 525 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", 526 | "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", 527 | "dev": true, 528 | "requires": { 529 | "babel-helper-call-delegate": "6.24.1", 530 | "babel-helper-get-function-arity": "6.24.1", 531 | "babel-runtime": "6.25.0", 532 | "babel-template": "6.25.0", 533 | "babel-traverse": "6.25.0", 534 | "babel-types": "6.25.0" 535 | } 536 | }, 537 | "babel-plugin-transform-es2015-shorthand-properties": { 538 | "version": "6.24.1", 539 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", 540 | "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", 541 | "dev": true, 542 | "requires": { 543 | "babel-runtime": "6.25.0", 544 | "babel-types": "6.25.0" 545 | } 546 | }, 547 | "babel-plugin-transform-es2015-spread": { 548 | "version": "6.22.0", 549 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", 550 | "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", 551 | "dev": true, 552 | "requires": { 553 | "babel-runtime": "6.25.0" 554 | } 555 | }, 556 | "babel-plugin-transform-es2015-sticky-regex": { 557 | "version": "6.24.1", 558 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", 559 | "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", 560 | "dev": true, 561 | "requires": { 562 | "babel-helper-regex": "6.24.1", 563 | "babel-runtime": "6.25.0", 564 | "babel-types": "6.25.0" 565 | } 566 | }, 567 | "babel-plugin-transform-es2015-template-literals": { 568 | "version": "6.22.0", 569 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", 570 | "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", 571 | "dev": true, 572 | "requires": { 573 | "babel-runtime": "6.25.0" 574 | } 575 | }, 576 | "babel-plugin-transform-es2015-typeof-symbol": { 577 | "version": "6.23.0", 578 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", 579 | "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", 580 | "dev": true, 581 | "requires": { 582 | "babel-runtime": "6.25.0" 583 | } 584 | }, 585 | "babel-plugin-transform-es2015-unicode-regex": { 586 | "version": "6.24.1", 587 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", 588 | "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", 589 | "dev": true, 590 | "requires": { 591 | "babel-helper-regex": "6.24.1", 592 | "babel-runtime": "6.25.0", 593 | "regexpu-core": "2.0.0" 594 | } 595 | }, 596 | "babel-plugin-transform-regenerator": { 597 | "version": "6.24.1", 598 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz", 599 | "integrity": "sha1-uNowWtQ8PJm0hI5P5AN7dw0jxBg=", 600 | "dev": true, 601 | "requires": { 602 | "regenerator-transform": "0.9.11" 603 | } 604 | }, 605 | "babel-plugin-transform-strict-mode": { 606 | "version": "6.24.1", 607 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", 608 | "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", 609 | "dev": true, 610 | "requires": { 611 | "babel-runtime": "6.25.0", 612 | "babel-types": "6.25.0" 613 | } 614 | }, 615 | "babel-preset-es2015": { 616 | "version": "6.24.1", 617 | "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", 618 | "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", 619 | "dev": true, 620 | "requires": { 621 | "babel-plugin-check-es2015-constants": "6.22.0", 622 | "babel-plugin-transform-es2015-arrow-functions": "6.22.0", 623 | "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", 624 | "babel-plugin-transform-es2015-block-scoping": "6.24.1", 625 | "babel-plugin-transform-es2015-classes": "6.24.1", 626 | "babel-plugin-transform-es2015-computed-properties": "6.24.1", 627 | "babel-plugin-transform-es2015-destructuring": "6.23.0", 628 | "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", 629 | "babel-plugin-transform-es2015-for-of": "6.23.0", 630 | "babel-plugin-transform-es2015-function-name": "6.24.1", 631 | "babel-plugin-transform-es2015-literals": "6.22.0", 632 | "babel-plugin-transform-es2015-modules-amd": "6.24.1", 633 | "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", 634 | "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", 635 | "babel-plugin-transform-es2015-modules-umd": "6.24.1", 636 | "babel-plugin-transform-es2015-object-super": "6.24.1", 637 | "babel-plugin-transform-es2015-parameters": "6.24.1", 638 | "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", 639 | "babel-plugin-transform-es2015-spread": "6.22.0", 640 | "babel-plugin-transform-es2015-sticky-regex": "6.24.1", 641 | "babel-plugin-transform-es2015-template-literals": "6.22.0", 642 | "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", 643 | "babel-plugin-transform-es2015-unicode-regex": "6.24.1", 644 | "babel-plugin-transform-regenerator": "6.24.1" 645 | } 646 | }, 647 | "babel-register": { 648 | "version": "6.24.1", 649 | "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", 650 | "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", 651 | "dev": true, 652 | "requires": { 653 | "babel-core": "6.25.0", 654 | "babel-runtime": "6.25.0", 655 | "core-js": "2.4.1", 656 | "home-or-tmp": "2.0.0", 657 | "lodash": "4.17.4", 658 | "mkdirp": "0.5.1", 659 | "source-map-support": "0.4.15" 660 | } 661 | }, 662 | "babel-runtime": { 663 | "version": "6.25.0", 664 | "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.25.0.tgz", 665 | "integrity": "sha1-M7mOql1IK7AajRqmtDetKwGuxBw=", 666 | "dev": true, 667 | "requires": { 668 | "core-js": "2.4.1", 669 | "regenerator-runtime": "0.10.5" 670 | } 671 | }, 672 | "babel-template": { 673 | "version": "6.25.0", 674 | "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.25.0.tgz", 675 | "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", 676 | "dev": true, 677 | "requires": { 678 | "babel-runtime": "6.25.0", 679 | "babel-traverse": "6.25.0", 680 | "babel-types": "6.25.0", 681 | "babylon": "6.17.4", 682 | "lodash": "4.17.4" 683 | } 684 | }, 685 | "babel-traverse": { 686 | "version": "6.25.0", 687 | "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz", 688 | "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", 689 | "dev": true, 690 | "requires": { 691 | "babel-code-frame": "6.22.0", 692 | "babel-messages": "6.23.0", 693 | "babel-runtime": "6.25.0", 694 | "babel-types": "6.25.0", 695 | "babylon": "6.17.4", 696 | "debug": "2.6.8", 697 | "globals": "9.18.0", 698 | "invariant": "2.2.2", 699 | "lodash": "4.17.4" 700 | } 701 | }, 702 | "babel-types": { 703 | "version": "6.25.0", 704 | "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.25.0.tgz", 705 | "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", 706 | "dev": true, 707 | "requires": { 708 | "babel-runtime": "6.25.0", 709 | "esutils": "2.0.2", 710 | "lodash": "4.17.4", 711 | "to-fast-properties": "1.0.3" 712 | } 713 | }, 714 | "babelrc-rollup": { 715 | "version": "3.0.0", 716 | "resolved": "https://registry.npmjs.org/babelrc-rollup/-/babelrc-rollup-3.0.0.tgz", 717 | "integrity": "sha1-/Ozb4+tkAM9OdpIzwXhqL6/otWw=", 718 | "dev": true, 719 | "requires": { 720 | "resolve": "1.4.0" 721 | } 722 | }, 723 | "babylon": { 724 | "version": "6.17.4", 725 | "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz", 726 | "integrity": "sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw==", 727 | "dev": true 728 | }, 729 | "balanced-match": { 730 | "version": "1.0.0", 731 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 732 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 733 | "dev": true 734 | }, 735 | "bcrypt-pbkdf": { 736 | "version": "1.0.1", 737 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", 738 | "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", 739 | "dev": true, 740 | "optional": true, 741 | "requires": { 742 | "tweetnacl": "0.14.5" 743 | } 744 | }, 745 | "boom": { 746 | "version": "2.10.1", 747 | "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", 748 | "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", 749 | "dev": true, 750 | "requires": { 751 | "hoek": "2.16.3" 752 | } 753 | }, 754 | "brace-expansion": { 755 | "version": "1.1.8", 756 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", 757 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", 758 | "dev": true, 759 | "requires": { 760 | "balanced-match": "1.0.0", 761 | "concat-map": "0.0.1" 762 | } 763 | }, 764 | "builtin-modules": { 765 | "version": "1.1.1", 766 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 767 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", 768 | "dev": true 769 | }, 770 | "caller-path": { 771 | "version": "0.1.0", 772 | "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", 773 | "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", 774 | "dev": true, 775 | "requires": { 776 | "callsites": "0.2.0" 777 | } 778 | }, 779 | "callsites": { 780 | "version": "0.2.0", 781 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", 782 | "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", 783 | "dev": true 784 | }, 785 | "camelcase": { 786 | "version": "1.2.1", 787 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", 788 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", 789 | "dev": true 790 | }, 791 | "caseless": { 792 | "version": "0.12.0", 793 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 794 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", 795 | "dev": true 796 | }, 797 | "center-align": { 798 | "version": "0.1.3", 799 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", 800 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", 801 | "dev": true, 802 | "requires": { 803 | "align-text": "0.1.4", 804 | "lazy-cache": "1.0.4" 805 | } 806 | }, 807 | "chalk": { 808 | "version": "1.1.3", 809 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 810 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 811 | "dev": true, 812 | "requires": { 813 | "ansi-styles": "2.2.1", 814 | "escape-string-regexp": "1.0.5", 815 | "has-ansi": "2.0.0", 816 | "strip-ansi": "3.0.1", 817 | "supports-color": "2.0.0" 818 | } 819 | }, 820 | "circular-json": { 821 | "version": "0.3.3", 822 | "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", 823 | "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", 824 | "dev": true 825 | }, 826 | "cli-cursor": { 827 | "version": "1.0.2", 828 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", 829 | "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", 830 | "dev": true, 831 | "requires": { 832 | "restore-cursor": "1.0.1" 833 | } 834 | }, 835 | "cli-width": { 836 | "version": "2.1.0", 837 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", 838 | "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=", 839 | "dev": true 840 | }, 841 | "cliui": { 842 | "version": "2.1.0", 843 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", 844 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", 845 | "dev": true, 846 | "requires": { 847 | "center-align": "0.1.3", 848 | "right-align": "0.1.3", 849 | "wordwrap": "0.0.2" 850 | }, 851 | "dependencies": { 852 | "wordwrap": { 853 | "version": "0.0.2", 854 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", 855 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", 856 | "dev": true 857 | } 858 | } 859 | }, 860 | "co": { 861 | "version": "4.6.0", 862 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 863 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", 864 | "dev": true 865 | }, 866 | "code-point-at": { 867 | "version": "1.1.0", 868 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 869 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", 870 | "dev": true 871 | }, 872 | "combined-stream": { 873 | "version": "1.0.5", 874 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", 875 | "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", 876 | "dev": true, 877 | "requires": { 878 | "delayed-stream": "1.0.0" 879 | } 880 | }, 881 | "concat-map": { 882 | "version": "0.0.1", 883 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 884 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 885 | "dev": true 886 | }, 887 | "concat-stream": { 888 | "version": "1.6.0", 889 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", 890 | "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", 891 | "dev": true, 892 | "requires": { 893 | "inherits": "2.0.3", 894 | "readable-stream": "2.3.3", 895 | "typedarray": "0.0.6" 896 | } 897 | }, 898 | "contains-path": { 899 | "version": "0.1.0", 900 | "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", 901 | "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", 902 | "dev": true 903 | }, 904 | "content-type-parser": { 905 | "version": "1.0.1", 906 | "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.1.tgz", 907 | "integrity": "sha1-w+VpiMU8ZRJ/tG1AMqOpACRv3JQ=", 908 | "dev": true 909 | }, 910 | "convert-source-map": { 911 | "version": "1.5.0", 912 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", 913 | "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", 914 | "dev": true 915 | }, 916 | "core-js": { 917 | "version": "2.4.1", 918 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", 919 | "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=", 920 | "dev": true 921 | }, 922 | "core-util-is": { 923 | "version": "1.0.2", 924 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 925 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 926 | "dev": true 927 | }, 928 | "cryptiles": { 929 | "version": "2.0.5", 930 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", 931 | "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", 932 | "dev": true, 933 | "requires": { 934 | "boom": "2.10.1" 935 | } 936 | }, 937 | "cssom": { 938 | "version": "0.3.2", 939 | "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", 940 | "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", 941 | "dev": true 942 | }, 943 | "cssstyle": { 944 | "version": "0.2.37", 945 | "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", 946 | "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", 947 | "dev": true, 948 | "requires": { 949 | "cssom": "0.3.2" 950 | } 951 | }, 952 | "d": { 953 | "version": "1.0.0", 954 | "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", 955 | "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", 956 | "dev": true, 957 | "requires": { 958 | "es5-ext": "0.10.24" 959 | } 960 | }, 961 | "d3-array": { 962 | "version": "1.2.0", 963 | "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.0.tgz", 964 | "integrity": "sha1-FH0mlyDhdMQFen9CvosPPyulMQg=" 965 | }, 966 | "d3-collection": { 967 | "version": "1.0.4", 968 | "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.4.tgz", 969 | "integrity": "sha1-NC39EoN8kJdPM/HMCnha6lcNzcI=" 970 | }, 971 | "d3-color": { 972 | "version": "1.0.3", 973 | "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.0.3.tgz", 974 | "integrity": "sha1-vHZD/KjlOoNH4vva/6I2eWtYUJs=" 975 | }, 976 | "d3-interpolate": { 977 | "version": "1.1.5", 978 | "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.1.5.tgz", 979 | "integrity": "sha1-aeCZ/zkhRxblY8muw+qdHqS4p58=", 980 | "requires": { 981 | "d3-color": "1.0.3" 982 | } 983 | }, 984 | "d3-path": { 985 | "version": "1.0.5", 986 | "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.5.tgz", 987 | "integrity": "sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=" 988 | }, 989 | "dashdash": { 990 | "version": "1.14.1", 991 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 992 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 993 | "dev": true, 994 | "requires": { 995 | "assert-plus": "1.0.0" 996 | }, 997 | "dependencies": { 998 | "assert-plus": { 999 | "version": "1.0.0", 1000 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 1001 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 1002 | "dev": true 1003 | } 1004 | } 1005 | }, 1006 | "debug": { 1007 | "version": "2.6.8", 1008 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", 1009 | "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", 1010 | "dev": true, 1011 | "requires": { 1012 | "ms": "2.0.0" 1013 | } 1014 | }, 1015 | "decamelize": { 1016 | "version": "1.2.0", 1017 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 1018 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 1019 | "dev": true 1020 | }, 1021 | "deep-is": { 1022 | "version": "0.1.3", 1023 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 1024 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 1025 | "dev": true 1026 | }, 1027 | "del": { 1028 | "version": "2.2.2", 1029 | "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", 1030 | "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", 1031 | "dev": true, 1032 | "requires": { 1033 | "globby": "5.0.0", 1034 | "is-path-cwd": "1.0.0", 1035 | "is-path-in-cwd": "1.0.0", 1036 | "object-assign": "4.1.1", 1037 | "pify": "2.3.0", 1038 | "pinkie-promise": "2.0.1", 1039 | "rimraf": "2.6.1" 1040 | } 1041 | }, 1042 | "delayed-stream": { 1043 | "version": "1.0.0", 1044 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 1045 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", 1046 | "dev": true 1047 | }, 1048 | "detect-indent": { 1049 | "version": "4.0.0", 1050 | "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", 1051 | "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", 1052 | "dev": true, 1053 | "requires": { 1054 | "repeating": "2.0.1" 1055 | } 1056 | }, 1057 | "doctrine": { 1058 | "version": "2.0.0", 1059 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", 1060 | "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", 1061 | "dev": true, 1062 | "requires": { 1063 | "esutils": "2.0.2", 1064 | "isarray": "1.0.0" 1065 | } 1066 | }, 1067 | "ecc-jsbn": { 1068 | "version": "0.1.1", 1069 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", 1070 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", 1071 | "dev": true, 1072 | "optional": true, 1073 | "requires": { 1074 | "jsbn": "0.1.1" 1075 | } 1076 | }, 1077 | "error-ex": { 1078 | "version": "1.3.1", 1079 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", 1080 | "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", 1081 | "dev": true, 1082 | "requires": { 1083 | "is-arrayish": "0.2.1" 1084 | } 1085 | }, 1086 | "es5-ext": { 1087 | "version": "0.10.24", 1088 | "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.24.tgz", 1089 | "integrity": "sha1-pVh3yZJLwMjZvTwsvhdJWsFwmxQ=", 1090 | "dev": true, 1091 | "requires": { 1092 | "es6-iterator": "2.0.1", 1093 | "es6-symbol": "3.1.1" 1094 | } 1095 | }, 1096 | "es6-iterator": { 1097 | "version": "2.0.1", 1098 | "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", 1099 | "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", 1100 | "dev": true, 1101 | "requires": { 1102 | "d": "1.0.0", 1103 | "es5-ext": "0.10.24", 1104 | "es6-symbol": "3.1.1" 1105 | } 1106 | }, 1107 | "es6-map": { 1108 | "version": "0.1.5", 1109 | "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", 1110 | "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", 1111 | "dev": true, 1112 | "requires": { 1113 | "d": "1.0.0", 1114 | "es5-ext": "0.10.24", 1115 | "es6-iterator": "2.0.1", 1116 | "es6-set": "0.1.5", 1117 | "es6-symbol": "3.1.1", 1118 | "event-emitter": "0.3.5" 1119 | } 1120 | }, 1121 | "es6-set": { 1122 | "version": "0.1.5", 1123 | "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", 1124 | "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", 1125 | "dev": true, 1126 | "requires": { 1127 | "d": "1.0.0", 1128 | "es5-ext": "0.10.24", 1129 | "es6-iterator": "2.0.1", 1130 | "es6-symbol": "3.1.1", 1131 | "event-emitter": "0.3.5" 1132 | } 1133 | }, 1134 | "es6-symbol": { 1135 | "version": "3.1.1", 1136 | "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", 1137 | "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", 1138 | "dev": true, 1139 | "requires": { 1140 | "d": "1.0.0", 1141 | "es5-ext": "0.10.24" 1142 | } 1143 | }, 1144 | "es6-weak-map": { 1145 | "version": "2.0.2", 1146 | "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", 1147 | "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", 1148 | "dev": true, 1149 | "requires": { 1150 | "d": "1.0.0", 1151 | "es5-ext": "0.10.24", 1152 | "es6-iterator": "2.0.1", 1153 | "es6-symbol": "3.1.1" 1154 | } 1155 | }, 1156 | "escape-string-regexp": { 1157 | "version": "1.0.5", 1158 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 1159 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 1160 | "dev": true 1161 | }, 1162 | "escodegen": { 1163 | "version": "1.8.1", 1164 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", 1165 | "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", 1166 | "dev": true, 1167 | "requires": { 1168 | "esprima": "2.7.3", 1169 | "estraverse": "1.9.3", 1170 | "esutils": "2.0.2", 1171 | "optionator": "0.8.2", 1172 | "source-map": "0.2.0" 1173 | }, 1174 | "dependencies": { 1175 | "esprima": { 1176 | "version": "2.7.3", 1177 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", 1178 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", 1179 | "dev": true 1180 | }, 1181 | "estraverse": { 1182 | "version": "1.9.3", 1183 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", 1184 | "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", 1185 | "dev": true 1186 | }, 1187 | "source-map": { 1188 | "version": "0.2.0", 1189 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", 1190 | "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", 1191 | "dev": true, 1192 | "optional": true, 1193 | "requires": { 1194 | "amdefine": "1.0.1" 1195 | } 1196 | } 1197 | } 1198 | }, 1199 | "escope": { 1200 | "version": "3.6.0", 1201 | "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", 1202 | "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", 1203 | "dev": true, 1204 | "requires": { 1205 | "es6-map": "0.1.5", 1206 | "es6-weak-map": "2.0.2", 1207 | "esrecurse": "4.2.0", 1208 | "estraverse": "4.2.0" 1209 | } 1210 | }, 1211 | "eslint": { 1212 | "version": "3.19.0", 1213 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", 1214 | "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", 1215 | "dev": true, 1216 | "requires": { 1217 | "babel-code-frame": "6.22.0", 1218 | "chalk": "1.1.3", 1219 | "concat-stream": "1.6.0", 1220 | "debug": "2.6.8", 1221 | "doctrine": "2.0.0", 1222 | "escope": "3.6.0", 1223 | "espree": "3.4.3", 1224 | "esquery": "1.0.0", 1225 | "estraverse": "4.2.0", 1226 | "esutils": "2.0.2", 1227 | "file-entry-cache": "2.0.0", 1228 | "glob": "7.1.2", 1229 | "globals": "9.18.0", 1230 | "ignore": "3.3.3", 1231 | "imurmurhash": "0.1.4", 1232 | "inquirer": "0.12.0", 1233 | "is-my-json-valid": "2.16.0", 1234 | "is-resolvable": "1.0.0", 1235 | "js-yaml": "3.9.1", 1236 | "json-stable-stringify": "1.0.1", 1237 | "levn": "0.3.0", 1238 | "lodash": "4.17.4", 1239 | "mkdirp": "0.5.1", 1240 | "natural-compare": "1.4.0", 1241 | "optionator": "0.8.2", 1242 | "path-is-inside": "1.0.2", 1243 | "pluralize": "1.2.1", 1244 | "progress": "1.1.8", 1245 | "require-uncached": "1.0.3", 1246 | "shelljs": "0.7.8", 1247 | "strip-bom": "3.0.0", 1248 | "strip-json-comments": "2.0.1", 1249 | "table": "3.8.3", 1250 | "text-table": "0.2.0", 1251 | "user-home": "2.0.0" 1252 | } 1253 | }, 1254 | "eslint-config-airbnb-base": { 1255 | "version": "11.3.1", 1256 | "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.3.1.tgz", 1257 | "integrity": "sha512-BXVH7PV5yiLjnkv49iOLJ8dWp+ljZf310ytQpqwrunFADiEbWRyN0tPGDU36FgEbdLvhJDWcJOngYDzPF4shDw==", 1258 | "dev": true, 1259 | "requires": { 1260 | "eslint-restricted-globals": "0.1.1" 1261 | } 1262 | }, 1263 | "eslint-import-resolver-node": { 1264 | "version": "0.3.1", 1265 | "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz", 1266 | "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==", 1267 | "dev": true, 1268 | "requires": { 1269 | "debug": "2.6.8", 1270 | "resolve": "1.4.0" 1271 | } 1272 | }, 1273 | "eslint-module-utils": { 1274 | "version": "2.1.1", 1275 | "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", 1276 | "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", 1277 | "dev": true, 1278 | "requires": { 1279 | "debug": "2.6.8", 1280 | "pkg-dir": "1.0.0" 1281 | } 1282 | }, 1283 | "eslint-plugin-import": { 1284 | "version": "2.7.0", 1285 | "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz", 1286 | "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==", 1287 | "dev": true, 1288 | "requires": { 1289 | "builtin-modules": "1.1.1", 1290 | "contains-path": "0.1.0", 1291 | "debug": "2.6.8", 1292 | "doctrine": "1.5.0", 1293 | "eslint-import-resolver-node": "0.3.1", 1294 | "eslint-module-utils": "2.1.1", 1295 | "has": "1.0.1", 1296 | "lodash.cond": "4.5.2", 1297 | "minimatch": "3.0.4", 1298 | "read-pkg-up": "2.0.0" 1299 | }, 1300 | "dependencies": { 1301 | "doctrine": { 1302 | "version": "1.5.0", 1303 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", 1304 | "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", 1305 | "dev": true, 1306 | "requires": { 1307 | "esutils": "2.0.2", 1308 | "isarray": "1.0.0" 1309 | } 1310 | } 1311 | } 1312 | }, 1313 | "eslint-restricted-globals": { 1314 | "version": "0.1.1", 1315 | "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", 1316 | "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", 1317 | "dev": true 1318 | }, 1319 | "espree": { 1320 | "version": "3.4.3", 1321 | "resolved": "https://registry.npmjs.org/espree/-/espree-3.4.3.tgz", 1322 | "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=", 1323 | "dev": true, 1324 | "requires": { 1325 | "acorn": "5.1.1", 1326 | "acorn-jsx": "3.0.1" 1327 | } 1328 | }, 1329 | "esprima": { 1330 | "version": "4.0.0", 1331 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", 1332 | "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", 1333 | "dev": true 1334 | }, 1335 | "esquery": { 1336 | "version": "1.0.0", 1337 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", 1338 | "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", 1339 | "dev": true, 1340 | "requires": { 1341 | "estraverse": "4.2.0" 1342 | } 1343 | }, 1344 | "esrecurse": { 1345 | "version": "4.2.0", 1346 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", 1347 | "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", 1348 | "dev": true, 1349 | "requires": { 1350 | "estraverse": "4.2.0", 1351 | "object-assign": "4.1.1" 1352 | } 1353 | }, 1354 | "estraverse": { 1355 | "version": "4.2.0", 1356 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", 1357 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", 1358 | "dev": true 1359 | }, 1360 | "estree-walker": { 1361 | "version": "0.2.1", 1362 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.2.1.tgz", 1363 | "integrity": "sha1-va/oCVOD2EFNXcLs9MkXO225QS4=", 1364 | "dev": true 1365 | }, 1366 | "esutils": { 1367 | "version": "2.0.2", 1368 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 1369 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 1370 | "dev": true 1371 | }, 1372 | "event-emitter": { 1373 | "version": "0.3.5", 1374 | "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", 1375 | "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", 1376 | "dev": true, 1377 | "requires": { 1378 | "d": "1.0.0", 1379 | "es5-ext": "0.10.24" 1380 | } 1381 | }, 1382 | "exit-hook": { 1383 | "version": "1.1.1", 1384 | "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", 1385 | "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", 1386 | "dev": true 1387 | }, 1388 | "extend": { 1389 | "version": "3.0.1", 1390 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", 1391 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", 1392 | "dev": true 1393 | }, 1394 | "extsprintf": { 1395 | "version": "1.0.2", 1396 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", 1397 | "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", 1398 | "dev": true 1399 | }, 1400 | "fast-levenshtein": { 1401 | "version": "2.0.6", 1402 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1403 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 1404 | "dev": true 1405 | }, 1406 | "figures": { 1407 | "version": "1.7.0", 1408 | "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", 1409 | "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", 1410 | "dev": true, 1411 | "requires": { 1412 | "escape-string-regexp": "1.0.5", 1413 | "object-assign": "4.1.1" 1414 | } 1415 | }, 1416 | "file-entry-cache": { 1417 | "version": "2.0.0", 1418 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", 1419 | "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", 1420 | "dev": true, 1421 | "requires": { 1422 | "flat-cache": "1.2.2", 1423 | "object-assign": "4.1.1" 1424 | } 1425 | }, 1426 | "find-up": { 1427 | "version": "1.1.2", 1428 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", 1429 | "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", 1430 | "dev": true, 1431 | "requires": { 1432 | "path-exists": "2.1.0", 1433 | "pinkie-promise": "2.0.1" 1434 | } 1435 | }, 1436 | "flat-cache": { 1437 | "version": "1.2.2", 1438 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", 1439 | "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", 1440 | "dev": true, 1441 | "requires": { 1442 | "circular-json": "0.3.3", 1443 | "del": "2.2.2", 1444 | "graceful-fs": "4.1.11", 1445 | "write": "0.2.1" 1446 | } 1447 | }, 1448 | "forever-agent": { 1449 | "version": "0.6.1", 1450 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 1451 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", 1452 | "dev": true 1453 | }, 1454 | "form-data": { 1455 | "version": "2.1.4", 1456 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", 1457 | "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", 1458 | "dev": true, 1459 | "requires": { 1460 | "asynckit": "0.4.0", 1461 | "combined-stream": "1.0.5", 1462 | "mime-types": "2.1.16" 1463 | } 1464 | }, 1465 | "fs.realpath": { 1466 | "version": "1.0.0", 1467 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1468 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 1469 | "dev": true 1470 | }, 1471 | "function-bind": { 1472 | "version": "1.1.0", 1473 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", 1474 | "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=", 1475 | "dev": true 1476 | }, 1477 | "generate-function": { 1478 | "version": "2.0.0", 1479 | "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", 1480 | "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", 1481 | "dev": true 1482 | }, 1483 | "generate-object-property": { 1484 | "version": "1.2.0", 1485 | "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", 1486 | "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", 1487 | "dev": true, 1488 | "requires": { 1489 | "is-property": "1.0.2" 1490 | } 1491 | }, 1492 | "getpass": { 1493 | "version": "0.1.7", 1494 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 1495 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 1496 | "dev": true, 1497 | "requires": { 1498 | "assert-plus": "1.0.0" 1499 | }, 1500 | "dependencies": { 1501 | "assert-plus": { 1502 | "version": "1.0.0", 1503 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 1504 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 1505 | "dev": true 1506 | } 1507 | } 1508 | }, 1509 | "glob": { 1510 | "version": "7.1.2", 1511 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 1512 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 1513 | "dev": true, 1514 | "requires": { 1515 | "fs.realpath": "1.0.0", 1516 | "inflight": "1.0.6", 1517 | "inherits": "2.0.3", 1518 | "minimatch": "3.0.4", 1519 | "once": "1.4.0", 1520 | "path-is-absolute": "1.0.1" 1521 | } 1522 | }, 1523 | "globals": { 1524 | "version": "9.18.0", 1525 | "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", 1526 | "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", 1527 | "dev": true 1528 | }, 1529 | "globby": { 1530 | "version": "5.0.0", 1531 | "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", 1532 | "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", 1533 | "dev": true, 1534 | "requires": { 1535 | "array-union": "1.0.2", 1536 | "arrify": "1.0.1", 1537 | "glob": "7.1.2", 1538 | "object-assign": "4.1.1", 1539 | "pify": "2.3.0", 1540 | "pinkie-promise": "2.0.1" 1541 | } 1542 | }, 1543 | "graceful-fs": { 1544 | "version": "4.1.11", 1545 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 1546 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", 1547 | "dev": true 1548 | }, 1549 | "har-schema": { 1550 | "version": "1.0.5", 1551 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", 1552 | "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", 1553 | "dev": true 1554 | }, 1555 | "har-validator": { 1556 | "version": "4.2.1", 1557 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", 1558 | "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", 1559 | "dev": true, 1560 | "requires": { 1561 | "ajv": "4.11.8", 1562 | "har-schema": "1.0.5" 1563 | } 1564 | }, 1565 | "has": { 1566 | "version": "1.0.1", 1567 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", 1568 | "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", 1569 | "dev": true, 1570 | "requires": { 1571 | "function-bind": "1.1.0" 1572 | } 1573 | }, 1574 | "has-ansi": { 1575 | "version": "2.0.0", 1576 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 1577 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 1578 | "dev": true, 1579 | "requires": { 1580 | "ansi-regex": "2.1.1" 1581 | } 1582 | }, 1583 | "hawk": { 1584 | "version": "3.1.3", 1585 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", 1586 | "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", 1587 | "dev": true, 1588 | "requires": { 1589 | "boom": "2.10.1", 1590 | "cryptiles": "2.0.5", 1591 | "hoek": "2.16.3", 1592 | "sntp": "1.0.9" 1593 | } 1594 | }, 1595 | "hoek": { 1596 | "version": "2.16.3", 1597 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", 1598 | "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", 1599 | "dev": true 1600 | }, 1601 | "home-or-tmp": { 1602 | "version": "2.0.0", 1603 | "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", 1604 | "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", 1605 | "dev": true, 1606 | "requires": { 1607 | "os-homedir": "1.0.2", 1608 | "os-tmpdir": "1.0.2" 1609 | } 1610 | }, 1611 | "hosted-git-info": { 1612 | "version": "2.5.0", 1613 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", 1614 | "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", 1615 | "dev": true 1616 | }, 1617 | "html-encoding-sniffer": { 1618 | "version": "1.0.1", 1619 | "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz", 1620 | "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=", 1621 | "dev": true, 1622 | "requires": { 1623 | "whatwg-encoding": "1.0.1" 1624 | } 1625 | }, 1626 | "http-signature": { 1627 | "version": "1.1.1", 1628 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", 1629 | "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", 1630 | "dev": true, 1631 | "requires": { 1632 | "assert-plus": "0.2.0", 1633 | "jsprim": "1.4.0", 1634 | "sshpk": "1.13.1" 1635 | } 1636 | }, 1637 | "iconv-lite": { 1638 | "version": "0.4.13", 1639 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", 1640 | "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", 1641 | "dev": true 1642 | }, 1643 | "ignore": { 1644 | "version": "3.3.3", 1645 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.3.tgz", 1646 | "integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0=", 1647 | "dev": true 1648 | }, 1649 | "imurmurhash": { 1650 | "version": "0.1.4", 1651 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1652 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 1653 | "dev": true 1654 | }, 1655 | "inflight": { 1656 | "version": "1.0.6", 1657 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1658 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1659 | "dev": true, 1660 | "requires": { 1661 | "once": "1.4.0", 1662 | "wrappy": "1.0.2" 1663 | } 1664 | }, 1665 | "inherits": { 1666 | "version": "2.0.3", 1667 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 1668 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 1669 | "dev": true 1670 | }, 1671 | "inquirer": { 1672 | "version": "0.12.0", 1673 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", 1674 | "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", 1675 | "dev": true, 1676 | "requires": { 1677 | "ansi-escapes": "1.4.0", 1678 | "ansi-regex": "2.1.1", 1679 | "chalk": "1.1.3", 1680 | "cli-cursor": "1.0.2", 1681 | "cli-width": "2.1.0", 1682 | "figures": "1.7.0", 1683 | "lodash": "4.17.4", 1684 | "readline2": "1.0.1", 1685 | "run-async": "0.1.0", 1686 | "rx-lite": "3.1.2", 1687 | "string-width": "1.0.2", 1688 | "strip-ansi": "3.0.1", 1689 | "through": "2.3.8" 1690 | } 1691 | }, 1692 | "interpret": { 1693 | "version": "1.0.3", 1694 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", 1695 | "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", 1696 | "dev": true 1697 | }, 1698 | "invariant": { 1699 | "version": "2.2.2", 1700 | "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", 1701 | "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", 1702 | "dev": true, 1703 | "requires": { 1704 | "loose-envify": "1.3.1" 1705 | } 1706 | }, 1707 | "is-arrayish": { 1708 | "version": "0.2.1", 1709 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 1710 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", 1711 | "dev": true 1712 | }, 1713 | "is-buffer": { 1714 | "version": "1.1.5", 1715 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", 1716 | "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", 1717 | "dev": true 1718 | }, 1719 | "is-builtin-module": { 1720 | "version": "1.0.0", 1721 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 1722 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", 1723 | "dev": true, 1724 | "requires": { 1725 | "builtin-modules": "1.1.1" 1726 | } 1727 | }, 1728 | "is-finite": { 1729 | "version": "1.0.2", 1730 | "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", 1731 | "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", 1732 | "dev": true, 1733 | "requires": { 1734 | "number-is-nan": "1.0.1" 1735 | } 1736 | }, 1737 | "is-fullwidth-code-point": { 1738 | "version": "1.0.0", 1739 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 1740 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 1741 | "dev": true, 1742 | "requires": { 1743 | "number-is-nan": "1.0.1" 1744 | } 1745 | }, 1746 | "is-my-json-valid": { 1747 | "version": "2.16.0", 1748 | "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", 1749 | "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", 1750 | "dev": true, 1751 | "requires": { 1752 | "generate-function": "2.0.0", 1753 | "generate-object-property": "1.2.0", 1754 | "jsonpointer": "4.0.1", 1755 | "xtend": "4.0.1" 1756 | } 1757 | }, 1758 | "is-path-cwd": { 1759 | "version": "1.0.0", 1760 | "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", 1761 | "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", 1762 | "dev": true 1763 | }, 1764 | "is-path-in-cwd": { 1765 | "version": "1.0.0", 1766 | "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", 1767 | "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", 1768 | "dev": true, 1769 | "requires": { 1770 | "is-path-inside": "1.0.0" 1771 | } 1772 | }, 1773 | "is-path-inside": { 1774 | "version": "1.0.0", 1775 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", 1776 | "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", 1777 | "dev": true, 1778 | "requires": { 1779 | "path-is-inside": "1.0.2" 1780 | } 1781 | }, 1782 | "is-property": { 1783 | "version": "1.0.2", 1784 | "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", 1785 | "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", 1786 | "dev": true 1787 | }, 1788 | "is-resolvable": { 1789 | "version": "1.0.0", 1790 | "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", 1791 | "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", 1792 | "dev": true, 1793 | "requires": { 1794 | "tryit": "1.0.3" 1795 | } 1796 | }, 1797 | "is-typedarray": { 1798 | "version": "1.0.0", 1799 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 1800 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", 1801 | "dev": true 1802 | }, 1803 | "isarray": { 1804 | "version": "1.0.0", 1805 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 1806 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 1807 | "dev": true 1808 | }, 1809 | "isstream": { 1810 | "version": "0.1.2", 1811 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 1812 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", 1813 | "dev": true 1814 | }, 1815 | "js-tokens": { 1816 | "version": "3.0.2", 1817 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 1818 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", 1819 | "dev": true 1820 | }, 1821 | "js-yaml": { 1822 | "version": "3.9.1", 1823 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", 1824 | "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==", 1825 | "dev": true, 1826 | "requires": { 1827 | "argparse": "1.0.9", 1828 | "esprima": "4.0.0" 1829 | } 1830 | }, 1831 | "jsbn": { 1832 | "version": "0.1.1", 1833 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 1834 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 1835 | "dev": true, 1836 | "optional": true 1837 | }, 1838 | "jsdom": { 1839 | "version": "9.12.0", 1840 | "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz", 1841 | "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=", 1842 | "dev": true, 1843 | "requires": { 1844 | "abab": "1.0.3", 1845 | "acorn": "4.0.13", 1846 | "acorn-globals": "3.1.0", 1847 | "array-equal": "1.0.0", 1848 | "content-type-parser": "1.0.1", 1849 | "cssom": "0.3.2", 1850 | "cssstyle": "0.2.37", 1851 | "escodegen": "1.8.1", 1852 | "html-encoding-sniffer": "1.0.1", 1853 | "nwmatcher": "1.4.1", 1854 | "parse5": "1.5.1", 1855 | "request": "2.81.0", 1856 | "sax": "1.2.4", 1857 | "symbol-tree": "3.2.2", 1858 | "tough-cookie": "2.3.2", 1859 | "webidl-conversions": "4.0.1", 1860 | "whatwg-encoding": "1.0.1", 1861 | "whatwg-url": "4.8.0", 1862 | "xml-name-validator": "2.0.1" 1863 | }, 1864 | "dependencies": { 1865 | "acorn": { 1866 | "version": "4.0.13", 1867 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", 1868 | "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", 1869 | "dev": true 1870 | } 1871 | } 1872 | }, 1873 | "jsesc": { 1874 | "version": "0.5.0", 1875 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", 1876 | "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", 1877 | "dev": true 1878 | }, 1879 | "json-schema": { 1880 | "version": "0.2.3", 1881 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 1882 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", 1883 | "dev": true 1884 | }, 1885 | "json-stable-stringify": { 1886 | "version": "1.0.1", 1887 | "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", 1888 | "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", 1889 | "dev": true, 1890 | "requires": { 1891 | "jsonify": "0.0.0" 1892 | } 1893 | }, 1894 | "json-stringify-safe": { 1895 | "version": "5.0.1", 1896 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 1897 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", 1898 | "dev": true 1899 | }, 1900 | "json5": { 1901 | "version": "0.5.1", 1902 | "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", 1903 | "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", 1904 | "dev": true 1905 | }, 1906 | "jsonify": { 1907 | "version": "0.0.0", 1908 | "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", 1909 | "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", 1910 | "dev": true 1911 | }, 1912 | "jsonpointer": { 1913 | "version": "4.0.1", 1914 | "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", 1915 | "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", 1916 | "dev": true 1917 | }, 1918 | "jsprim": { 1919 | "version": "1.4.0", 1920 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", 1921 | "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", 1922 | "dev": true, 1923 | "requires": { 1924 | "assert-plus": "1.0.0", 1925 | "extsprintf": "1.0.2", 1926 | "json-schema": "0.2.3", 1927 | "verror": "1.3.6" 1928 | }, 1929 | "dependencies": { 1930 | "assert-plus": { 1931 | "version": "1.0.0", 1932 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 1933 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 1934 | "dev": true 1935 | } 1936 | } 1937 | }, 1938 | "kind-of": { 1939 | "version": "3.2.2", 1940 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 1941 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 1942 | "dev": true, 1943 | "requires": { 1944 | "is-buffer": "1.1.5" 1945 | } 1946 | }, 1947 | "lazy-cache": { 1948 | "version": "1.0.4", 1949 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", 1950 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", 1951 | "dev": true 1952 | }, 1953 | "levn": { 1954 | "version": "0.3.0", 1955 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 1956 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 1957 | "dev": true, 1958 | "requires": { 1959 | "prelude-ls": "1.1.2", 1960 | "type-check": "0.3.2" 1961 | } 1962 | }, 1963 | "load-json-file": { 1964 | "version": "2.0.0", 1965 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", 1966 | "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", 1967 | "dev": true, 1968 | "requires": { 1969 | "graceful-fs": "4.1.11", 1970 | "parse-json": "2.2.0", 1971 | "pify": "2.3.0", 1972 | "strip-bom": "3.0.0" 1973 | } 1974 | }, 1975 | "locate-path": { 1976 | "version": "2.0.0", 1977 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", 1978 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", 1979 | "dev": true, 1980 | "requires": { 1981 | "p-locate": "2.0.0", 1982 | "path-exists": "3.0.0" 1983 | }, 1984 | "dependencies": { 1985 | "path-exists": { 1986 | "version": "3.0.0", 1987 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1988 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 1989 | "dev": true 1990 | } 1991 | } 1992 | }, 1993 | "lodash": { 1994 | "version": "4.17.4", 1995 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", 1996 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", 1997 | "dev": true 1998 | }, 1999 | "lodash.cond": { 2000 | "version": "4.5.2", 2001 | "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", 2002 | "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", 2003 | "dev": true 2004 | }, 2005 | "longest": { 2006 | "version": "1.0.1", 2007 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", 2008 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", 2009 | "dev": true 2010 | }, 2011 | "loose-envify": { 2012 | "version": "1.3.1", 2013 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", 2014 | "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", 2015 | "dev": true, 2016 | "requires": { 2017 | "js-tokens": "3.0.2" 2018 | } 2019 | }, 2020 | "mime-db": { 2021 | "version": "1.29.0", 2022 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz", 2023 | "integrity": "sha1-SNJtI1WJZRcErFkWygYAGRQmaHg=", 2024 | "dev": true 2025 | }, 2026 | "mime-types": { 2027 | "version": "2.1.16", 2028 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz", 2029 | "integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=", 2030 | "dev": true, 2031 | "requires": { 2032 | "mime-db": "1.29.0" 2033 | } 2034 | }, 2035 | "minimatch": { 2036 | "version": "3.0.4", 2037 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 2038 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 2039 | "dev": true, 2040 | "requires": { 2041 | "brace-expansion": "1.1.8" 2042 | } 2043 | }, 2044 | "minimist": { 2045 | "version": "0.0.8", 2046 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 2047 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 2048 | "dev": true 2049 | }, 2050 | "mkdirp": { 2051 | "version": "0.5.1", 2052 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 2053 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 2054 | "dev": true, 2055 | "requires": { 2056 | "minimist": "0.0.8" 2057 | } 2058 | }, 2059 | "ms": { 2060 | "version": "2.0.0", 2061 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 2062 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 2063 | "dev": true 2064 | }, 2065 | "mute-stream": { 2066 | "version": "0.0.5", 2067 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", 2068 | "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", 2069 | "dev": true 2070 | }, 2071 | "natural-compare": { 2072 | "version": "1.4.0", 2073 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 2074 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 2075 | "dev": true 2076 | }, 2077 | "normalize-package-data": { 2078 | "version": "2.4.0", 2079 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", 2080 | "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", 2081 | "dev": true, 2082 | "requires": { 2083 | "hosted-git-info": "2.5.0", 2084 | "is-builtin-module": "1.0.0", 2085 | "semver": "5.4.1", 2086 | "validate-npm-package-license": "3.0.1" 2087 | } 2088 | }, 2089 | "number-is-nan": { 2090 | "version": "1.0.1", 2091 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 2092 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", 2093 | "dev": true 2094 | }, 2095 | "nwmatcher": { 2096 | "version": "1.4.1", 2097 | "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.1.tgz", 2098 | "integrity": "sha1-eumwew6oBNt+JfBctf5Al9TklJ8=", 2099 | "dev": true 2100 | }, 2101 | "oauth-sign": { 2102 | "version": "0.8.2", 2103 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", 2104 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", 2105 | "dev": true 2106 | }, 2107 | "object-assign": { 2108 | "version": "4.1.1", 2109 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 2110 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 2111 | "dev": true 2112 | }, 2113 | "once": { 2114 | "version": "1.4.0", 2115 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 2116 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 2117 | "dev": true, 2118 | "requires": { 2119 | "wrappy": "1.0.2" 2120 | } 2121 | }, 2122 | "onetime": { 2123 | "version": "1.1.0", 2124 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", 2125 | "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", 2126 | "dev": true 2127 | }, 2128 | "optionator": { 2129 | "version": "0.8.2", 2130 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 2131 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 2132 | "dev": true, 2133 | "requires": { 2134 | "deep-is": "0.1.3", 2135 | "fast-levenshtein": "2.0.6", 2136 | "levn": "0.3.0", 2137 | "prelude-ls": "1.1.2", 2138 | "type-check": "0.3.2", 2139 | "wordwrap": "1.0.0" 2140 | } 2141 | }, 2142 | "os-homedir": { 2143 | "version": "1.0.2", 2144 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", 2145 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", 2146 | "dev": true 2147 | }, 2148 | "os-tmpdir": { 2149 | "version": "1.0.2", 2150 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 2151 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 2152 | "dev": true 2153 | }, 2154 | "p-limit": { 2155 | "version": "1.1.0", 2156 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", 2157 | "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", 2158 | "dev": true 2159 | }, 2160 | "p-locate": { 2161 | "version": "2.0.0", 2162 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", 2163 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", 2164 | "dev": true, 2165 | "requires": { 2166 | "p-limit": "1.1.0" 2167 | } 2168 | }, 2169 | "parse-json": { 2170 | "version": "2.2.0", 2171 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", 2172 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", 2173 | "dev": true, 2174 | "requires": { 2175 | "error-ex": "1.3.1" 2176 | } 2177 | }, 2178 | "parse5": { 2179 | "version": "1.5.1", 2180 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", 2181 | "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", 2182 | "dev": true 2183 | }, 2184 | "path-exists": { 2185 | "version": "2.1.0", 2186 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", 2187 | "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", 2188 | "dev": true, 2189 | "requires": { 2190 | "pinkie-promise": "2.0.1" 2191 | } 2192 | }, 2193 | "path-is-absolute": { 2194 | "version": "1.0.1", 2195 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 2196 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 2197 | "dev": true 2198 | }, 2199 | "path-is-inside": { 2200 | "version": "1.0.2", 2201 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 2202 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", 2203 | "dev": true 2204 | }, 2205 | "path-parse": { 2206 | "version": "1.0.5", 2207 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", 2208 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", 2209 | "dev": true 2210 | }, 2211 | "path-type": { 2212 | "version": "2.0.0", 2213 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", 2214 | "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", 2215 | "dev": true, 2216 | "requires": { 2217 | "pify": "2.3.0" 2218 | } 2219 | }, 2220 | "performance-now": { 2221 | "version": "0.2.0", 2222 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", 2223 | "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", 2224 | "dev": true 2225 | }, 2226 | "pify": { 2227 | "version": "2.3.0", 2228 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 2229 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", 2230 | "dev": true 2231 | }, 2232 | "pinkie": { 2233 | "version": "2.0.4", 2234 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 2235 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", 2236 | "dev": true 2237 | }, 2238 | "pinkie-promise": { 2239 | "version": "2.0.1", 2240 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 2241 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 2242 | "dev": true, 2243 | "requires": { 2244 | "pinkie": "2.0.4" 2245 | } 2246 | }, 2247 | "pkg-dir": { 2248 | "version": "1.0.0", 2249 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", 2250 | "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", 2251 | "dev": true, 2252 | "requires": { 2253 | "find-up": "1.1.2" 2254 | } 2255 | }, 2256 | "pluralize": { 2257 | "version": "1.2.1", 2258 | "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", 2259 | "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", 2260 | "dev": true 2261 | }, 2262 | "prelude-ls": { 2263 | "version": "1.1.2", 2264 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 2265 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 2266 | "dev": true 2267 | }, 2268 | "private": { 2269 | "version": "0.1.7", 2270 | "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", 2271 | "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", 2272 | "dev": true 2273 | }, 2274 | "process-nextick-args": { 2275 | "version": "1.0.7", 2276 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", 2277 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", 2278 | "dev": true 2279 | }, 2280 | "progress": { 2281 | "version": "1.1.8", 2282 | "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", 2283 | "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", 2284 | "dev": true 2285 | }, 2286 | "punycode": { 2287 | "version": "1.4.1", 2288 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 2289 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", 2290 | "dev": true 2291 | }, 2292 | "qs": { 2293 | "version": "6.4.0", 2294 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", 2295 | "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", 2296 | "dev": true 2297 | }, 2298 | "read-pkg": { 2299 | "version": "2.0.0", 2300 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", 2301 | "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", 2302 | "dev": true, 2303 | "requires": { 2304 | "load-json-file": "2.0.0", 2305 | "normalize-package-data": "2.4.0", 2306 | "path-type": "2.0.0" 2307 | } 2308 | }, 2309 | "read-pkg-up": { 2310 | "version": "2.0.0", 2311 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", 2312 | "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", 2313 | "dev": true, 2314 | "requires": { 2315 | "find-up": "2.1.0", 2316 | "read-pkg": "2.0.0" 2317 | }, 2318 | "dependencies": { 2319 | "find-up": { 2320 | "version": "2.1.0", 2321 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", 2322 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", 2323 | "dev": true, 2324 | "requires": { 2325 | "locate-path": "2.0.0" 2326 | } 2327 | } 2328 | } 2329 | }, 2330 | "readable-stream": { 2331 | "version": "2.3.3", 2332 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", 2333 | "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", 2334 | "dev": true, 2335 | "requires": { 2336 | "core-util-is": "1.0.2", 2337 | "inherits": "2.0.3", 2338 | "isarray": "1.0.0", 2339 | "process-nextick-args": "1.0.7", 2340 | "safe-buffer": "5.1.1", 2341 | "string_decoder": "1.0.3", 2342 | "util-deprecate": "1.0.2" 2343 | } 2344 | }, 2345 | "readline2": { 2346 | "version": "1.0.1", 2347 | "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", 2348 | "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", 2349 | "dev": true, 2350 | "requires": { 2351 | "code-point-at": "1.1.0", 2352 | "is-fullwidth-code-point": "1.0.0", 2353 | "mute-stream": "0.0.5" 2354 | } 2355 | }, 2356 | "rechoir": { 2357 | "version": "0.6.2", 2358 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 2359 | "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", 2360 | "dev": true, 2361 | "requires": { 2362 | "resolve": "1.4.0" 2363 | } 2364 | }, 2365 | "regenerate": { 2366 | "version": "1.3.2", 2367 | "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", 2368 | "integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA=", 2369 | "dev": true 2370 | }, 2371 | "regenerator-runtime": { 2372 | "version": "0.10.5", 2373 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", 2374 | "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", 2375 | "dev": true 2376 | }, 2377 | "regenerator-transform": { 2378 | "version": "0.9.11", 2379 | "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.11.tgz", 2380 | "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", 2381 | "dev": true, 2382 | "requires": { 2383 | "babel-runtime": "6.25.0", 2384 | "babel-types": "6.25.0", 2385 | "private": "0.1.7" 2386 | } 2387 | }, 2388 | "regexpu-core": { 2389 | "version": "2.0.0", 2390 | "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", 2391 | "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", 2392 | "dev": true, 2393 | "requires": { 2394 | "regenerate": "1.3.2", 2395 | "regjsgen": "0.2.0", 2396 | "regjsparser": "0.1.5" 2397 | } 2398 | }, 2399 | "regjsgen": { 2400 | "version": "0.2.0", 2401 | "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", 2402 | "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", 2403 | "dev": true 2404 | }, 2405 | "regjsparser": { 2406 | "version": "0.1.5", 2407 | "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", 2408 | "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", 2409 | "dev": true, 2410 | "requires": { 2411 | "jsesc": "0.5.0" 2412 | } 2413 | }, 2414 | "repeat-string": { 2415 | "version": "1.6.1", 2416 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", 2417 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", 2418 | "dev": true 2419 | }, 2420 | "repeating": { 2421 | "version": "2.0.1", 2422 | "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", 2423 | "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", 2424 | "dev": true, 2425 | "requires": { 2426 | "is-finite": "1.0.2" 2427 | } 2428 | }, 2429 | "request": { 2430 | "version": "2.81.0", 2431 | "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", 2432 | "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", 2433 | "dev": true, 2434 | "requires": { 2435 | "aws-sign2": "0.6.0", 2436 | "aws4": "1.6.0", 2437 | "caseless": "0.12.0", 2438 | "combined-stream": "1.0.5", 2439 | "extend": "3.0.1", 2440 | "forever-agent": "0.6.1", 2441 | "form-data": "2.1.4", 2442 | "har-validator": "4.2.1", 2443 | "hawk": "3.1.3", 2444 | "http-signature": "1.1.1", 2445 | "is-typedarray": "1.0.0", 2446 | "isstream": "0.1.2", 2447 | "json-stringify-safe": "5.0.1", 2448 | "mime-types": "2.1.16", 2449 | "oauth-sign": "0.8.2", 2450 | "performance-now": "0.2.0", 2451 | "qs": "6.4.0", 2452 | "safe-buffer": "5.1.1", 2453 | "stringstream": "0.0.5", 2454 | "tough-cookie": "2.3.2", 2455 | "tunnel-agent": "0.6.0", 2456 | "uuid": "3.1.0" 2457 | } 2458 | }, 2459 | "require-uncached": { 2460 | "version": "1.0.3", 2461 | "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", 2462 | "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", 2463 | "dev": true, 2464 | "requires": { 2465 | "caller-path": "0.1.0", 2466 | "resolve-from": "1.0.1" 2467 | } 2468 | }, 2469 | "resolve": { 2470 | "version": "1.4.0", 2471 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", 2472 | "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", 2473 | "dev": true, 2474 | "requires": { 2475 | "path-parse": "1.0.5" 2476 | } 2477 | }, 2478 | "resolve-from": { 2479 | "version": "1.0.1", 2480 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", 2481 | "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", 2482 | "dev": true 2483 | }, 2484 | "restore-cursor": { 2485 | "version": "1.0.1", 2486 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", 2487 | "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", 2488 | "dev": true, 2489 | "requires": { 2490 | "exit-hook": "1.1.1", 2491 | "onetime": "1.1.0" 2492 | } 2493 | }, 2494 | "right-align": { 2495 | "version": "0.1.3", 2496 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", 2497 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", 2498 | "dev": true, 2499 | "requires": { 2500 | "align-text": "0.1.4" 2501 | } 2502 | }, 2503 | "rimraf": { 2504 | "version": "2.6.1", 2505 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", 2506 | "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", 2507 | "dev": true, 2508 | "requires": { 2509 | "glob": "7.1.2" 2510 | } 2511 | }, 2512 | "rollup": { 2513 | "version": "0.41.6", 2514 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.41.6.tgz", 2515 | "integrity": "sha1-4NBUl4d6OYwQTYFtJzOnGKepTio=", 2516 | "dev": true, 2517 | "requires": { 2518 | "source-map-support": "0.4.15" 2519 | } 2520 | }, 2521 | "rollup-plugin-babel": { 2522 | "version": "2.7.1", 2523 | "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-2.7.1.tgz", 2524 | "integrity": "sha1-FlKBl7D5OKFTb0RoPHqT1XMYL1c=", 2525 | "dev": true, 2526 | "requires": { 2527 | "babel-core": "6.25.0", 2528 | "babel-plugin-transform-es2015-classes": "6.24.1", 2529 | "object-assign": "4.1.1", 2530 | "rollup-pluginutils": "1.5.2" 2531 | } 2532 | }, 2533 | "rollup-pluginutils": { 2534 | "version": "1.5.2", 2535 | "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz", 2536 | "integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=", 2537 | "dev": true, 2538 | "requires": { 2539 | "estree-walker": "0.2.1", 2540 | "minimatch": "3.0.4" 2541 | } 2542 | }, 2543 | "run-async": { 2544 | "version": "0.1.0", 2545 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", 2546 | "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", 2547 | "dev": true, 2548 | "requires": { 2549 | "once": "1.4.0" 2550 | } 2551 | }, 2552 | "rx-lite": { 2553 | "version": "3.1.2", 2554 | "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", 2555 | "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", 2556 | "dev": true 2557 | }, 2558 | "safe-buffer": { 2559 | "version": "5.1.1", 2560 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 2561 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", 2562 | "dev": true 2563 | }, 2564 | "sax": { 2565 | "version": "1.2.4", 2566 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 2567 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", 2568 | "dev": true 2569 | }, 2570 | "semver": { 2571 | "version": "5.4.1", 2572 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", 2573 | "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", 2574 | "dev": true 2575 | }, 2576 | "shelljs": { 2577 | "version": "0.7.8", 2578 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", 2579 | "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", 2580 | "dev": true, 2581 | "requires": { 2582 | "glob": "7.1.2", 2583 | "interpret": "1.0.3", 2584 | "rechoir": "0.6.2" 2585 | } 2586 | }, 2587 | "slash": { 2588 | "version": "1.0.0", 2589 | "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", 2590 | "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", 2591 | "dev": true 2592 | }, 2593 | "slice-ansi": { 2594 | "version": "0.0.4", 2595 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", 2596 | "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", 2597 | "dev": true 2598 | }, 2599 | "sntp": { 2600 | "version": "1.0.9", 2601 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", 2602 | "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", 2603 | "dev": true, 2604 | "requires": { 2605 | "hoek": "2.16.3" 2606 | } 2607 | }, 2608 | "source-map": { 2609 | "version": "0.5.6", 2610 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", 2611 | "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", 2612 | "dev": true 2613 | }, 2614 | "source-map-support": { 2615 | "version": "0.4.15", 2616 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", 2617 | "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", 2618 | "dev": true, 2619 | "requires": { 2620 | "source-map": "0.5.6" 2621 | } 2622 | }, 2623 | "spdx-correct": { 2624 | "version": "1.0.2", 2625 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", 2626 | "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", 2627 | "dev": true, 2628 | "requires": { 2629 | "spdx-license-ids": "1.2.2" 2630 | } 2631 | }, 2632 | "spdx-expression-parse": { 2633 | "version": "1.0.4", 2634 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", 2635 | "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", 2636 | "dev": true 2637 | }, 2638 | "spdx-license-ids": { 2639 | "version": "1.2.2", 2640 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", 2641 | "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", 2642 | "dev": true 2643 | }, 2644 | "sprintf-js": { 2645 | "version": "1.0.3", 2646 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 2647 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 2648 | "dev": true 2649 | }, 2650 | "sshpk": { 2651 | "version": "1.13.1", 2652 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", 2653 | "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", 2654 | "dev": true, 2655 | "requires": { 2656 | "asn1": "0.2.3", 2657 | "assert-plus": "1.0.0", 2658 | "bcrypt-pbkdf": "1.0.1", 2659 | "dashdash": "1.14.1", 2660 | "ecc-jsbn": "0.1.1", 2661 | "getpass": "0.1.7", 2662 | "jsbn": "0.1.1", 2663 | "tweetnacl": "0.14.5" 2664 | }, 2665 | "dependencies": { 2666 | "assert-plus": { 2667 | "version": "1.0.0", 2668 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 2669 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 2670 | "dev": true 2671 | } 2672 | } 2673 | }, 2674 | "string_decoder": { 2675 | "version": "1.0.3", 2676 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 2677 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", 2678 | "dev": true, 2679 | "requires": { 2680 | "safe-buffer": "5.1.1" 2681 | } 2682 | }, 2683 | "string-width": { 2684 | "version": "1.0.2", 2685 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 2686 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 2687 | "dev": true, 2688 | "requires": { 2689 | "code-point-at": "1.1.0", 2690 | "is-fullwidth-code-point": "1.0.0", 2691 | "strip-ansi": "3.0.1" 2692 | } 2693 | }, 2694 | "stringstream": { 2695 | "version": "0.0.5", 2696 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", 2697 | "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", 2698 | "dev": true 2699 | }, 2700 | "strip-ansi": { 2701 | "version": "3.0.1", 2702 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 2703 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 2704 | "dev": true, 2705 | "requires": { 2706 | "ansi-regex": "2.1.1" 2707 | } 2708 | }, 2709 | "strip-bom": { 2710 | "version": "3.0.0", 2711 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 2712 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", 2713 | "dev": true 2714 | }, 2715 | "strip-json-comments": { 2716 | "version": "2.0.1", 2717 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 2718 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 2719 | "dev": true 2720 | }, 2721 | "supports-color": { 2722 | "version": "2.0.0", 2723 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 2724 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", 2725 | "dev": true 2726 | }, 2727 | "symbol-tree": { 2728 | "version": "3.2.2", 2729 | "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", 2730 | "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", 2731 | "dev": true 2732 | }, 2733 | "table": { 2734 | "version": "3.8.3", 2735 | "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", 2736 | "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", 2737 | "dev": true, 2738 | "requires": { 2739 | "ajv": "4.11.8", 2740 | "ajv-keywords": "1.5.1", 2741 | "chalk": "1.1.3", 2742 | "lodash": "4.17.4", 2743 | "slice-ansi": "0.0.4", 2744 | "string-width": "2.1.1" 2745 | }, 2746 | "dependencies": { 2747 | "ansi-regex": { 2748 | "version": "3.0.0", 2749 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 2750 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 2751 | "dev": true 2752 | }, 2753 | "is-fullwidth-code-point": { 2754 | "version": "2.0.0", 2755 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 2756 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 2757 | "dev": true 2758 | }, 2759 | "string-width": { 2760 | "version": "2.1.1", 2761 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 2762 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 2763 | "dev": true, 2764 | "requires": { 2765 | "is-fullwidth-code-point": "2.0.0", 2766 | "strip-ansi": "4.0.0" 2767 | } 2768 | }, 2769 | "strip-ansi": { 2770 | "version": "4.0.0", 2771 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 2772 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 2773 | "dev": true, 2774 | "requires": { 2775 | "ansi-regex": "3.0.0" 2776 | } 2777 | } 2778 | } 2779 | }, 2780 | "text-table": { 2781 | "version": "0.2.0", 2782 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 2783 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 2784 | "dev": true 2785 | }, 2786 | "through": { 2787 | "version": "2.3.8", 2788 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 2789 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 2790 | "dev": true 2791 | }, 2792 | "to-fast-properties": { 2793 | "version": "1.0.3", 2794 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", 2795 | "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", 2796 | "dev": true 2797 | }, 2798 | "tough-cookie": { 2799 | "version": "2.3.2", 2800 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", 2801 | "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", 2802 | "dev": true, 2803 | "requires": { 2804 | "punycode": "1.4.1" 2805 | } 2806 | }, 2807 | "tr46": { 2808 | "version": "0.0.3", 2809 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 2810 | "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", 2811 | "dev": true 2812 | }, 2813 | "trim-right": { 2814 | "version": "1.0.1", 2815 | "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", 2816 | "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", 2817 | "dev": true 2818 | }, 2819 | "tryit": { 2820 | "version": "1.0.3", 2821 | "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", 2822 | "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", 2823 | "dev": true 2824 | }, 2825 | "tunnel-agent": { 2826 | "version": "0.6.0", 2827 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 2828 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 2829 | "dev": true, 2830 | "requires": { 2831 | "safe-buffer": "5.1.1" 2832 | } 2833 | }, 2834 | "tweetnacl": { 2835 | "version": "0.14.5", 2836 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 2837 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 2838 | "dev": true, 2839 | "optional": true 2840 | }, 2841 | "type-check": { 2842 | "version": "0.3.2", 2843 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 2844 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 2845 | "dev": true, 2846 | "requires": { 2847 | "prelude-ls": "1.1.2" 2848 | } 2849 | }, 2850 | "typedarray": { 2851 | "version": "0.0.6", 2852 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 2853 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", 2854 | "dev": true 2855 | }, 2856 | "uglify-js": { 2857 | "version": "2.8.29", 2858 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", 2859 | "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", 2860 | "dev": true, 2861 | "requires": { 2862 | "source-map": "0.5.6", 2863 | "uglify-to-browserify": "1.0.2", 2864 | "yargs": "3.10.0" 2865 | } 2866 | }, 2867 | "uglify-to-browserify": { 2868 | "version": "1.0.2", 2869 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", 2870 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", 2871 | "dev": true, 2872 | "optional": true 2873 | }, 2874 | "user-home": { 2875 | "version": "2.0.0", 2876 | "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", 2877 | "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", 2878 | "dev": true, 2879 | "requires": { 2880 | "os-homedir": "1.0.2" 2881 | } 2882 | }, 2883 | "util-deprecate": { 2884 | "version": "1.0.2", 2885 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2886 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 2887 | "dev": true 2888 | }, 2889 | "uuid": { 2890 | "version": "3.1.0", 2891 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", 2892 | "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", 2893 | "dev": true 2894 | }, 2895 | "validate-npm-package-license": { 2896 | "version": "3.0.1", 2897 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", 2898 | "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", 2899 | "dev": true, 2900 | "requires": { 2901 | "spdx-correct": "1.0.2", 2902 | "spdx-expression-parse": "1.0.4" 2903 | } 2904 | }, 2905 | "verror": { 2906 | "version": "1.3.6", 2907 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", 2908 | "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", 2909 | "dev": true, 2910 | "requires": { 2911 | "extsprintf": "1.0.2" 2912 | } 2913 | }, 2914 | "webidl-conversions": { 2915 | "version": "4.0.1", 2916 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.1.tgz", 2917 | "integrity": "sha1-gBWherg+fhsxFjhIas6B2mziBqA=", 2918 | "dev": true 2919 | }, 2920 | "whatwg-encoding": { 2921 | "version": "1.0.1", 2922 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz", 2923 | "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=", 2924 | "dev": true, 2925 | "requires": { 2926 | "iconv-lite": "0.4.13" 2927 | } 2928 | }, 2929 | "whatwg-url": { 2930 | "version": "4.8.0", 2931 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", 2932 | "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", 2933 | "dev": true, 2934 | "requires": { 2935 | "tr46": "0.0.3", 2936 | "webidl-conversions": "3.0.1" 2937 | }, 2938 | "dependencies": { 2939 | "webidl-conversions": { 2940 | "version": "3.0.1", 2941 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 2942 | "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", 2943 | "dev": true 2944 | } 2945 | } 2946 | }, 2947 | "window-size": { 2948 | "version": "0.1.0", 2949 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", 2950 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", 2951 | "dev": true 2952 | }, 2953 | "wordwrap": { 2954 | "version": "1.0.0", 2955 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 2956 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 2957 | "dev": true 2958 | }, 2959 | "wrappy": { 2960 | "version": "1.0.2", 2961 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2962 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 2963 | "dev": true 2964 | }, 2965 | "write": { 2966 | "version": "0.2.1", 2967 | "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", 2968 | "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", 2969 | "dev": true, 2970 | "requires": { 2971 | "mkdirp": "0.5.1" 2972 | } 2973 | }, 2974 | "xml-name-validator": { 2975 | "version": "2.0.1", 2976 | "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", 2977 | "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", 2978 | "dev": true 2979 | }, 2980 | "xtend": { 2981 | "version": "4.0.1", 2982 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 2983 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", 2984 | "dev": true 2985 | }, 2986 | "yargs": { 2987 | "version": "3.10.0", 2988 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", 2989 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", 2990 | "dev": true, 2991 | "requires": { 2992 | "camelcase": "1.2.1", 2993 | "cliui": "2.1.0", 2994 | "decamelize": "1.2.0", 2995 | "window-size": "0.1.0" 2996 | } 2997 | } 2998 | } 2999 | } 3000 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "d3-loom", 3 | "version": "1.0.2", 4 | "description": "a d3 plugin to create a loom chart layout", 5 | "keywords": [ 6 | "d3", 7 | "d3-module", 8 | "loom", 9 | "layout" 10 | ], 11 | "license": "MIT", 12 | "main": "build/d3-loom.js", 13 | "jsnext:main": "index", 14 | "module": "index", 15 | "homepage": "https://github.com/nbremer/d3-loom", 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/nbremer/d3-loom.git" 19 | }, 20 | "scripts": { 21 | "lint": "eslint src", 22 | "pretest": "npm run lint && rm -rf build && mkdir build && rollup -c", 23 | "build": "npm run pretest", 24 | "prepack": "uglifyjs build/d3-loom.js -c -m -o build/d3-loom.min.js", 25 | "postpublish": "git push; git push --tags" 26 | }, 27 | "devDependencies": { 28 | "babel-plugin-external-helpers": "^6.18.0", 29 | "babel-preset-es2015": "^6.18.0", 30 | "babel-register": "^6.18.0", 31 | "babelrc-rollup": "^3.0.0", 32 | "eslint": "^3.18.0", 33 | "eslint-config-airbnb-base": "^11.1.1", 34 | "eslint-plugin-import": "^2.2.0", 35 | "jsdom": "^9.11.0", 36 | "rollup": "0.41", 37 | "rollup-plugin-babel": "^2.7.1", 38 | "uglify-js": "2" 39 | }, 40 | "dependencies": { 41 | "d3-array": "^1.2.0", 42 | "d3-collection": "^1.0.4", 43 | "d3-interpolate": "^1.1.5", 44 | "d3-path": "^1.0.5" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import babel from 'rollup-plugin-babel'; 2 | import babelrc from 'babelrc-rollup'; 3 | 4 | let pkg = require('./package.json'); 5 | let external = Object.keys(pkg.dependencies); 6 | 7 | export default { 8 | entry: 'index.js', 9 | plugins: [babel(babelrc())], 10 | external: external, 11 | targets: [ 12 | { 13 | dest: pkg.main, 14 | format: 'umd', 15 | moduleName: 'd3', 16 | sourceMap: true 17 | } 18 | ], 19 | globals: { 20 | 'd3-collection': 'd3', 21 | 'd3-array': 'd3', 22 | 'd3-interpolate': 'd3', 23 | 'd3-path': 'd3' 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /src/compare-value.js: -------------------------------------------------------------------------------- 1 | export default function compareValue(compare) { 2 | return (a, b) => compare(a.outer.value, b.outer.value); 3 | } 4 | -------------------------------------------------------------------------------- /src/constant.js: -------------------------------------------------------------------------------- 1 | export default function constant(x) { 2 | return () => x; 3 | } 4 | -------------------------------------------------------------------------------- /src/loom.js: -------------------------------------------------------------------------------- 1 | /* Based on the d3v4 d3.chord() function by Mike Bostock 2 | ** Adjusted by Nadieh Bremer - July 2016 */ 3 | 4 | /* global d3 */ 5 | import compareValue from './compare-value'; 6 | import constant from './constant'; 7 | 8 | export default function loom() { 9 | const tau = Math.PI * 2; 10 | 11 | let padAngle = 0; 12 | let sortGroups = null; 13 | let sortSubgroups = null; 14 | let sortLooms = null; 15 | let emptyPerc = 0.2; 16 | let heightInner = 20; 17 | let widthInner = () => 30; 18 | let value = d => d.value; 19 | let inner = d => d.inner; 20 | let outer = d => d.outer; 21 | 22 | function loomLayout(layoutData) { 23 | // Nest the data on the outer variable 24 | const data = d3.nest().key(outer).entries(layoutData); 25 | 26 | const n = data.length; 27 | 28 | // Loop over the outer groups and sum the values 29 | 30 | const groupSums = []; 31 | const groupIndex = d3.range(n); 32 | const subgroupIndex = []; 33 | const looms = []; 34 | looms.groups = new Array(n); 35 | const groups = looms.groups; 36 | let numSubGroups; 37 | looms.innergroups = []; 38 | const uniqueInner = looms.innergroups; 39 | const uniqueCheck = []; 40 | let k; 41 | let x; 42 | let x0; 43 | let j; 44 | let l; 45 | let s; 46 | let v; 47 | let sum; 48 | let section; 49 | let remain; 50 | let counter; 51 | let reverseOrder = false; 52 | let approxCenter; 53 | k = 0; 54 | numSubGroups = 0; 55 | for (let i = 0; i < n; i += 1) { 56 | v = data[i].values.length; 57 | sum = 0; 58 | for (j = 0; j < v; j += 1) { 59 | sum += value(data[i].values[j]); 60 | } // for j 61 | groupSums.push(sum); 62 | subgroupIndex.push(d3.range(v)); 63 | numSubGroups += v; 64 | k += sum; 65 | } // for i 66 | 67 | // Sort the groups… 68 | if (sortGroups) { 69 | groupIndex.sort((a, b) => sortGroups(groupSums[a], groupSums[b])); 70 | } 71 | 72 | // Sort subgroups… 73 | if (sortSubgroups) { 74 | subgroupIndex.forEach((d, i) => { 75 | d.sort((a, b) => 76 | sortSubgroups(inner(data[i].values[a]), inner(data[i].values[b])) 77 | ); 78 | }); 79 | } 80 | 81 | // After which group are we past the center, taking into account the padding 82 | // TODO: make something for if there is no "nice" split in two... 83 | const padk = k * (padAngle / tau); 84 | l = 0; 85 | for (let i = 0; i < n; i += 1) { 86 | section = groupSums[groupIndex[i]] + padk; 87 | l += section; 88 | if (l > (k + n * padk) / 2) { 89 | // Check if the group should be added to left or right 90 | remain = k + n * padk - (l - section); 91 | approxCenter = remain / section < 0.5 92 | ? groupIndex[i] 93 | : groupIndex[i - 1]; 94 | break; 95 | } // if 96 | } // for i 97 | 98 | // How much should be added to k to make the empty part emptyPerc big of the total 99 | const emptyk = k * emptyPerc / (1 - emptyPerc); 100 | k += emptyk; 101 | 102 | // Convert the sum to scaling factor for [0, 2pi]. 103 | k = Math.max(0, tau - padAngle * n) / k; 104 | const dx = k ? padAngle : tau / n; 105 | 106 | // Compute the start and end angle for each group and subgroup. 107 | // Note: Opera has a bug reordering object literal properties! 108 | const subgroups = new Array(numSubGroups); 109 | x = emptyk * 0.25 * k; // starting with quarter of the empty part to the side; 110 | counter = 0; 111 | for (let i = 0; i < n; i += 1) { 112 | const di = groupIndex[i]; 113 | const outername = data[di].key; 114 | 115 | x0 = x; 116 | s = subgroupIndex[di].length; 117 | for (j = 0; j < s; j += 1) { 118 | const dj = reverseOrder 119 | ? subgroupIndex[di][s - 1 - j] 120 | : subgroupIndex[di][j]; 121 | 122 | v = value(data[di].values[dj]); 123 | const innername = inner(data[di].values[dj]); 124 | const a0 = x; 125 | x += v * k; 126 | const a1 = x; 127 | subgroups[counter] = { 128 | index: di, 129 | subindex: dj, 130 | startAngle: a0, 131 | endAngle: a1, 132 | value: v, 133 | outername, 134 | innername, 135 | groupStartAngle: x0 136 | }; 137 | 138 | // Check and save the unique inner names 139 | if (!uniqueCheck[innername]) { 140 | uniqueCheck[innername] = true; 141 | uniqueInner.push({ name: innername }); 142 | } // if 143 | 144 | counter += 1; 145 | } // for j 146 | groups[di] = { 147 | index: di, 148 | startAngle: x0, 149 | endAngle: x, 150 | value: groupSums[di], 151 | outername 152 | }; 153 | x += dx; 154 | // If this is the approximate center, add half of the empty piece for the bottom 155 | if (approxCenter === di) x += emptyk * 0.5 * k; 156 | // If you've crossed the bottom, reverse the order of the inner strings 157 | if (x > Math.PI) reverseOrder = true; 158 | } // for i 159 | 160 | // Sort the inner groups in the same way as the strings 161 | if (sortSubgroups) { 162 | uniqueInner.sort((a, b) => sortSubgroups(a.name, b.name)); 163 | } 164 | 165 | // Find x and y locations of the inner categories 166 | const m = uniqueInner.length; 167 | for (let i = 0; i < m; i += 1) { 168 | uniqueInner[i].x = 0; 169 | uniqueInner[i].y = -m * heightInner / 2 + i * heightInner; 170 | uniqueInner[i].offset = widthInner(uniqueInner[i].name, i); 171 | } // for i 172 | 173 | // Generate bands for each (non-empty) subgroup-subgroup link 174 | counter = 0; 175 | for (let i = 0; i < n; i += 1) { 176 | const di = groupIndex[i]; 177 | s = subgroupIndex[di].length; 178 | for (j = 0; j < s; j += 1) { 179 | const outerGroup = subgroups[counter]; 180 | const innerTerm = outerGroup.innername; 181 | // Find the correct inner object based on the name 182 | const innerGroup = searchTerm(innerTerm, 'name', uniqueInner); 183 | if (outerGroup.value) { 184 | looms.push({ inner: innerGroup, outer: outerGroup }); 185 | } // if 186 | counter += 1; 187 | } // for j 188 | } // for i 189 | 190 | return sortLooms ? looms.sort(sortLooms) : looms; 191 | } // loomLayout 192 | 193 | function searchTerm(term, property, arrayToSearch) { 194 | for (let i = 0; i < arrayToSearch.length; i += 1) { 195 | if (arrayToSearch[i][property] === term) { 196 | return arrayToSearch[i]; 197 | } // if 198 | } // for i 199 | return null; 200 | } // searchTerm 201 | 202 | loomLayout.padAngle = function(_) { 203 | return arguments.length 204 | ? ((padAngle = Math.max(0, _)), loomLayout) 205 | : padAngle; 206 | }; 207 | 208 | loomLayout.inner = function(_) { 209 | return arguments.length ? ((inner = _), loomLayout) : inner; 210 | }; 211 | 212 | loomLayout.outer = function(_) { 213 | return arguments.length ? ((outer = _), loomLayout) : outer; 214 | }; 215 | 216 | loomLayout.value = function(_) { 217 | return arguments.length ? ((value = _), loomLayout) : value; 218 | }; 219 | 220 | loomLayout.heightInner = function(_) { 221 | return arguments.length ? ((heightInner = _), loomLayout) : heightInner; 222 | }; 223 | 224 | loomLayout.widthInner = function(_) { 225 | return arguments.length 226 | ? ((widthInner = typeof _ === 'function' ? _ : constant(+_)), loomLayout) 227 | : widthInner; 228 | }; 229 | 230 | loomLayout.emptyPerc = function(_) { 231 | return arguments.length 232 | ? ((emptyPerc = _ < 1 233 | ? Math.max(0, _) 234 | : Math.max(0, _ * 0.01)), loomLayout) 235 | : emptyPerc; 236 | }; 237 | 238 | loomLayout.sortGroups = function(_) { 239 | return arguments.length ? ((sortGroups = _), loomLayout) : sortGroups; 240 | }; 241 | 242 | loomLayout.sortSubgroups = function(_) { 243 | return arguments.length ? ((sortSubgroups = _), loomLayout) : sortSubgroups; 244 | }; 245 | 246 | loomLayout.sortLooms = function(_) { 247 | return arguments.length 248 | ? (_ == null 249 | ? (sortLooms = null) 250 | : ((sortLooms = compareValue(_))._ = _), loomLayout) 251 | : sortLooms && sortLooms._; 252 | }; 253 | 254 | return loomLayout; 255 | } // loom 256 | -------------------------------------------------------------------------------- /src/string.js: -------------------------------------------------------------------------------- 1 | /* global d3 */ 2 | 3 | import constant from './constant'; 4 | 5 | export default function string() { 6 | const slice = Array.prototype.slice; 7 | const cos = Math.cos; 8 | const sin = Math.sin; 9 | const halfPi = Math.PI / 2; 10 | const tau = Math.PI * 2; 11 | 12 | let inner = d => d.inner; 13 | let outer = d => d.outer; 14 | let radius = () => 100; 15 | let groupStartAngle = d => d.groupStartAngle; 16 | let startAngle = d => d.startAngle; 17 | let endAngle = d => d.endAngle; 18 | let x = d => d.x; 19 | let y = d => d.y; 20 | let offset = d => d.offset; 21 | let pullout = 50; 22 | let thicknessInner = 0; 23 | let context = null; 24 | 25 | function stringLayout(...args) { 26 | let buffer; 27 | const argv = slice.call(args); 28 | const out = outer.apply(this, argv); 29 | const inn = inner.apply(this, argv); 30 | argv[0] = out; 31 | const sr = +radius.apply(this, argv); 32 | const sa0 = startAngle.apply(this, argv) - halfPi; 33 | const sga0 = groupStartAngle.apply(this, argv) - halfPi; 34 | const sa1 = endAngle.apply(this, argv) - halfPi; 35 | let sx0 = sr * cos(sa0); 36 | const sy0 = sr * sin(sa0); 37 | let sx1 = sr * cos(sa1); 38 | const sy1 = sr * sin(sa1); 39 | argv[0] = inn; 40 | // 'tr' is assigned a value but never used 41 | // const tr = +radius.apply(this, (argv)); 42 | let tx = x.apply(this, argv); 43 | const ty = y.apply(this, argv); 44 | let toffset = offset.apply(this, argv); 45 | let xco; 46 | let yco; 47 | let xci; 48 | let yci; 49 | 50 | // Does the group lie on the left side; 51 | const leftHalf = sga0 + halfPi > Math.PI && sga0 + halfPi < tau; 52 | // If the group lies on the other side, switch the inner point offset 53 | if (leftHalf) toffset = -toffset; 54 | tx += toffset; 55 | // And the height of the end point 56 | const theight = leftHalf ? -thicknessInner : thicknessInner; 57 | 58 | if (!context) { 59 | buffer = d3.path(); 60 | context = buffer; 61 | } 62 | 63 | // Change the pullout based on where the stringLayout is 64 | const pulloutContext = (leftHalf ? -1 : 1) * pullout; 65 | sx0 += pulloutContext; 66 | sx1 += pulloutContext; 67 | // Start at smallest angle of outer arc 68 | context.moveTo(sx0, sy0); 69 | // Circular part along the outer arc 70 | context.arc(pulloutContext, 0, sr, sa0, sa1); 71 | // From end outer arc to center (taking into account the pullout) 72 | xco = d3.interpolateNumber(pulloutContext, sx1)(0.5); 73 | yco = d3.interpolateNumber(0, sy1)(0.5); 74 | if ((!leftHalf && sx1 < tx) || (leftHalf && sx1 > tx)) { 75 | // If the outer point lies closer to the center than the inner point 76 | xci = tx + (tx - sx1) / 2; 77 | yci = d3.interpolateNumber(ty + theight / 2, sy1)(0.5); 78 | } else { 79 | xci = d3.interpolateNumber(tx, sx1)(0.25); 80 | yci = ty + theight / 2; 81 | } // else 82 | context.bezierCurveTo(xco, yco, xci, yci, tx, ty + theight / 2); 83 | // Draw a straight line up/down (depending on the side of the circle) 84 | context.lineTo(tx, ty - theight / 2); 85 | // From center (taking into account the pullout) to start of outer arc 86 | xco = d3.interpolateNumber(pulloutContext, sx0)(0.5); 87 | yco = d3.interpolateNumber(0, sy0)(0.5); 88 | if ((!leftHalf && sx0 < tx) || (leftHalf && sx0 > tx)) { 89 | // If the outer point lies closer to the center than the inner point 90 | xci = tx + (tx - sx0) / 2; 91 | yci = d3.interpolateNumber(ty - theight / 2, sy0)(0.5); 92 | } else { 93 | xci = d3.interpolateNumber(tx, sx0)(0.25); 94 | yci = ty - theight / 2; 95 | } // else 96 | context.bezierCurveTo(xci, yci, xco, yco, sx0, sy0); 97 | // Close path 98 | context.closePath(); 99 | 100 | if (buffer) { 101 | context = null; 102 | return `${buffer}` || null; 103 | } 104 | return null; 105 | } 106 | 107 | stringLayout.radius = function(_) { 108 | return arguments.length 109 | ? ((radius = typeof _ === 'function' ? _ : constant(+_)), stringLayout) 110 | : radius; 111 | }; 112 | 113 | stringLayout.groupStartAngle = function(_) { 114 | return arguments.length 115 | ? ((groupStartAngle = typeof _ === 'function' 116 | ? _ 117 | : constant(+_)), stringLayout) 118 | : groupStartAngle; 119 | }; 120 | 121 | stringLayout.startAngle = function(_) { 122 | return arguments.length 123 | ? ((startAngle = typeof _ === 'function' 124 | ? _ 125 | : constant(+_)), stringLayout) 126 | : startAngle; 127 | }; 128 | 129 | stringLayout.endAngle = function(_) { 130 | return arguments.length 131 | ? ((endAngle = typeof _ === 'function' ? _ : constant(+_)), stringLayout) 132 | : endAngle; 133 | }; 134 | 135 | stringLayout.x = function(_) { 136 | return arguments.length ? ((x = _), stringLayout) : x; 137 | }; 138 | 139 | stringLayout.y = function(_) { 140 | return arguments.length ? ((y = _), stringLayout) : y; 141 | }; 142 | 143 | stringLayout.offset = function(_) { 144 | return arguments.length ? ((offset = _), stringLayout) : offset; 145 | }; 146 | 147 | stringLayout.thicknessInner = function(_) { 148 | return arguments.length 149 | ? ((thicknessInner = _), stringLayout) 150 | : thicknessInner; 151 | }; 152 | 153 | stringLayout.inner = function(_) { 154 | return arguments.length ? ((inner = _), stringLayout) : inner; 155 | }; 156 | 157 | stringLayout.outer = function(_) { 158 | return arguments.length ? ((outer = _), stringLayout) : outer; 159 | }; 160 | 161 | stringLayout.pullout = function(_) { 162 | return arguments.length ? ((pullout = _), stringLayout) : pullout; 163 | }; 164 | 165 | stringLayout.context = function(_) { 166 | return arguments.length 167 | ? ((context = _ == null ? null : _), stringLayout) 168 | : context; 169 | }; 170 | 171 | return stringLayout; 172 | } 173 | --------------------------------------------------------------------------------