This end-point may not be accessed directly via HTTP.
5 |
Please connect via a websocket to send raw data to configured printers.
6 |
7 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | chrome.app.runtime.onLaunched.addListener(function(data) {
2 | // Open main window
3 | chrome.app.window.create('index.html',
4 | { id: 'main',
5 | innerBounds: {width: 600, height: 600}
6 | });
7 | });
8 |
--------------------------------------------------------------------------------
/vendor/websocket-server/README.md:
--------------------------------------------------------------------------------
1 | # websocker-server
2 |
3 | These files are sourced from the Chrome App '[websocket-server](https://github.com/GoogleChrome/chrome-app-samples/blob/master/samples/websocket-server/index.js)' example.
4 |
5 |
6 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 |
3 | var dest = 'chrome-raw-print'
4 |
5 | gulp.task('src', function() {
6 | gulp.src(['src/**'])
7 | .pipe(gulp.dest(dest + '/'))
8 | })
9 |
10 | gulp.task('vendor', function() {
11 | gulp.src(['vendor/**'])
12 | .pipe(gulp.dest(dest + '/vendor'))
13 | })
14 |
15 |
16 | gulp.task('default', ['src', 'vendor']);
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chrome-raw-print",
3 | "version": "0.2",
4 | "description": "Chrome app to enable raw printing from a browser ",
5 | "main": "dest/index.js",
6 | "repository": "git@github.com:receipt-print-hq/chrome-raw-print.git",
7 | "author": "Michael Billington ",
8 | "license": "MIT",
9 | "devDependencies": {
10 | "gulp": "^3.9.1"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": {
3 | "background": {
4 | "scripts": ["main.js"]
5 | }
6 | },
7 | "manifest_version": 2,
8 | "name": "Raw print connector",
9 | "version": "0.2",
10 | "description": "Pass raw data to USB receipt printers",
11 | "icons": {
12 | "128": "icon_128.png"
13 | },
14 | "minimum_chrome_version": "25",
15 | "sockets": {
16 | "tcp": {
17 | "connect": "*"
18 | },
19 | "tcpServer": {
20 | "listen": "*"
21 | }
22 | },
23 | "permissions": ["usb"],
24 | "optional_permissions": [
25 | {"usbDevices": [
26 | {"vendorId": 1046, "productId": 20497},
27 | {"vendorId": 1659, "productId": 8965},
28 | {"vendorId": 1208, "productId": 3587},
29 | {"vendorId": 1352, "productId": 2056},
30 | {"vendorId": 5380, "productId": 26}]
31 | }]
32 | }
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016-18 receipt-print-hq
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
Raw print connector
11 |
12 |
This app allows you to send raw commands to your printer. It is designed to make receipt printers accessible from webpages for point-of-sale kiosks.
13 |
14 |
While this app is open, web pages can pass data to those printers via a websocket. Example code for accessing this websocket from Javascript can be found on the project page.
15 |
16 |
On supported printers, check that:
17 |
18 |
You have permission to print. Check udev for this.
You have unloaded or blacklisted the kernel driver: sudo rmmod usblp on Linux.
This snippet demonstrates how to send raw binary data to a printer from a browser-based Javascript application.
10 |
11 |
A running Chrome App will pick up the data via a local WebSocket, and deliver it to any configured printers.
12 |
13 |
17 |
18 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Raw printing for Chrome
2 |
3 | **Chrome Apps are being discontinued by Google in 2018, so this project will no longer be actively developed. At the time of writing, neither WebUSB nor raw sockets can be used from regular web pages, so you will need to transition to a native app for this functionality once the runtime becomes unavailable.**
4 |
5 | **Thank you to everybody who has used or contributed to this app over the past year and a half!**
6 |
7 | ----
8 |
9 | This is a Chrome app to allow browser-based Javascript code to pass raw data to a supported printer. It is aimed at developers of web-based point-of-sale systems where server-side printing is not feasable.
10 |
11 | This has been developed for use with a USB receipt printer, with an ESC/POS command generator ([escpos-php](https://github.com/mike42/escpos-php)) providing the binary data.
12 |
13 | ## The problem
14 |
15 | It can be difficult to add printing to a web-based point-of-sale system:
16 |
17 | - The local print system does not use raw output, so you get low-quality, rasterised output.
18 | - Allowing inbound connectivity to allow a server to print requires a static IP, and is challenging to secure and debug.
19 |
20 | This app solves the problem by exposing a websocket on localhost. A web-page can then retrieve binary print data from the server, and pass it to the app for printing.
21 |
22 | ## Compatibility
23 |
24 | ### Printer types
25 |
26 | Only USB receipt printers are currently supported.
27 |
28 | - **Networked printers** may be supported in future.
29 | - **Serial/Parallel printers** may be accessed via a USB adaptor.
30 | - **CUPS/IPP/Windows** shared printers are out of scope at this stage, please hook in directly via USB.
31 |
32 | ### Supported printers
33 |
34 | Raw printing for Chrome is loaded with vendor/product ID's for the following printers:
35 |
36 | - Epson TM-T20
37 | - PL2305 Parallel Port
38 | - Winbond Virtual Com Port.
39 |
40 | If your USB printer is not listed, please create a new issue to request support. Because of the way Chrome app permissions work, please include the USB vendor ID and product ID.
41 |
42 | ### Page Description Languages
43 |
44 | This app is simply a connector. In theory, any page description language is supported, provided that you are able to generate it, and your printer can understand it.
45 |
46 | ## Installation
47 |
48 | This application is not yet available in the Chrome store, so the installation steps are a bit unusual:
49 |
50 | - Download and extract the [most recent release](https://github.com/receipt-print-hq/chrome-raw-print/releases).
51 | - Under `chrome://extensions`, tick developer mode, and 'load unpacked extension', and locate the extracted folder.
52 |
53 | 
54 |
55 | - Launch the extension, select your printer
56 | - If not listed, find the USB product, vendor ID, add it to `manifest.md`, and restart.
57 | - Click print
58 | - If it doesn't print, check the error log and see the notes displayed on the app window for the basic things to check.
59 | - In particular, unload the `usblp` kernel module if applicable, as it will claim the USB interface to the printer.
60 |
61 | ## Demo
62 |
63 | A small example web-page available under `example/`, which will print a "Hello World" receipt in ESC/POS if the raw printing app is running, with an ESC/POS printer configured. Steps to try it out:
64 |
65 | - Run the app
66 | - Add a printer
67 | - Open the example web page
68 | - Click a few buttons and hope for output.
69 |
70 | This was tested on an Epson TM-T20.
71 |
72 | # Build
73 |
74 | ```
75 | yarn
76 | gulp
77 | ```
78 |
79 | The `chrome-raw-print` subfolder contains the compiled files.
80 |
81 | ## Contribute
82 |
83 | Pull requests are welcome and appreciated. This project is quite new, please see the issue tracker for ideas of things to work on.
84 |
85 | # Screenshot
86 |
87 | 
88 |
89 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | var $ = function(id) { return document.getElementById(id); };
2 |
3 | /**
4 | * Select and print to USB printers
5 | */
6 | selectedPrinters = [];
7 |
8 | function selectPrinter() {
9 | // Dialog and printer selection
10 | selectedPrinters = [];
11 | var onDeviceFound = function(devices) {
12 | $('printerList').innerHTML = '';
13 | if(devices.length == 0) {
14 | updateStatus('No devices selected');
15 | return;
16 | }
17 | // Refresh the printer list
18 | $('printerList').innerHTML = '
Manufacturer
Product name
';
19 | selectedPrinters = [];
20 | devices.forEach(function(device) {
21 | // Add each printer to list
22 | idStr = device.device
23 | $('printerList').innerHTML += '
';
24 | $(idStr + '-manufacturerName').innerText = device.manufacturerName;
25 | $(idStr + '-productName').innerText = device.productName;
26 | selectedPrinters.push(device);
27 | });
28 | updateStatus(selectedPrinters.length + ' printer(s) selected');
29 | }
30 | // Allow the user to select any devices listed in the manifest
31 | filters = chrome.runtime.getManifest().optional_permissions[0].usbDevices;
32 | chrome.usb.getUserSelectedDevices({'multiple': true, 'filters': filters}, onDeviceFound)
33 | }
34 |
35 | function print() {
36 | // Print text and cut paper. This data contains 'Hello world LF GS V 65 3'
37 | hello = [0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x0a, 0x1d, 0x56, 0x41, 0x03];
38 | var totalDataSize = hello.length;
39 | var data = new ArrayBuffer(totalDataSize);
40 | var dataView = new Uint8Array(data, 0, totalDataSize);
41 | dataView.set(hello, 0)
42 | // Print this data to all devices
43 | printDataToDevices(data, selectedPrinters)
44 | }
45 |
46 | function printDataToDevices(data, devices) {
47 | // For each device, print data to the device
48 | if(devices.length == 0) {
49 | updateStatus("Cannot print: No printers selected.");
50 | return;
51 | }
52 | devices.forEach(function(device) {
53 | printDataToDevice(data, device);
54 | });
55 | }
56 |
57 | function printDataToDevice(data, device) {
58 | // Open a device and print the data to the resulting handle
59 | chrome.usb.openDevice(device, function(handle) {
60 | printDataToHandle(data, device, handle)
61 | });
62 | }
63 |
64 | function printDataToHandle(data, device, handle) {
65 | // Claim interface and print data to it
66 | chrome.usb.claimInterface(handle, 0, function() {
67 | if (chrome.runtime.lastError) {
68 | console.error(chrome.runtime.lastError, device);
69 | updateStatus("Failed to claim interface for device");
70 | return;
71 | }
72 | printDataToInterface(data, device, handle);
73 | });
74 | }
75 |
76 | function printDataToInterface(data, device, handle) {
77 | // Transfer data to a claimed interface on an open device
78 | var info = {
79 | "direction": "out",
80 | "endpoint": 1,
81 | "data": data
82 | };
83 | chrome.usb.bulkTransfer(handle, info, function(transferResult) {
84 | chrome.usb.releaseInterface(handle, 0, function() {
85 | if (chrome.runtime.lastError)
86 | console.error(chrome.runtime.lastError);
87 | return;
88 | });
89 | });
90 | }
91 |
92 | function updateStatus(text) {
93 | // Change status line on page
94 | $('status').innerText = 'Status: ' + text;
95 | }
96 |
97 | window.addEventListener('DOMContentLoaded', function() {
98 | // Hook up buttons
99 | $('selectPrinter').addEventListener('click', selectPrinter);
100 | $('print').addEventListener('click', print);
101 | });
102 |
103 | /**
104 | * Accept raw print data via WebSocket on port 9876 (serialised as byte array)
105 | */
106 | port = 9876;
107 | var server = new http.Server();
108 | var wsServer = new http.WebSocketServer(server);
109 | server.listen(port);
110 | server.addEventListener('request', function(req) {
111 | // Serve a deault page of this chrome application.
112 | url = '/default.html';
113 | req.serveUrl(url);
114 | return true;
115 | });
116 |
117 | wsServer.addEventListener('request', function(req) {
118 | console.log('Client connected');
119 | var socket = req.accept();
120 | socket.addEventListener('message', function(e) {
121 | console.log('Data received', e);
122 | var receivedData = JSON.parse(e.data);
123 | receivedData = new Uint8Array(receivedData).buffer;
124 | printDataToDevices(receivedData, selectedPrinters)
125 | });
126 | socket.addEventListener('close', function() {
127 | console.log('Client disconnected');
128 | });
129 | return true;
130 | });
131 |
--------------------------------------------------------------------------------
/vendor/websocket-server/sha1.js:
--------------------------------------------------------------------------------
1 | // Licensed under the Apache License, Version 2.0 (the "License");
2 | // you may not use this file except in compliance with the License.
3 | // You may obtain a copy of the License at
4 | //
5 | // http://www.apache.org/licenses/LICENSE-2.0
6 | //
7 | // Unless required by applicable law or agreed to in writing, software
8 | // distributed under the License is distributed on an "AS IS" BASIS,
9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | // See the License for the specific language governing permissions and
11 | // limitations under the License.
12 |
13 | // Copyright 2005 Google Inc. All Rights Reserved.
14 |
15 | /**
16 | * @fileoverview SHA-1 cryptographic hash.
17 | * Variable names follow the notation in FIPS PUB 180-3:
18 | * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.
19 | *
20 | * Usage:
21 | * var sha1 = new goog.crypt.sha1();
22 | * sha1.update(bytes);
23 | * var hash = sha1.digest();
24 | *
25 | */
26 |
27 | /**
28 | * SHA-1 cryptographic hash constructor.
29 | *
30 | * The properties declared here are discussed in the above algorithm document.
31 | * @constructor
32 | */
33 | var Sha1 = function() {
34 | /**
35 | * Holds the previous values of accumulated variables a-e in the compress_
36 | * function.
37 | * @type {Array.}
38 | * @private
39 | */
40 | this.chain_ = [];
41 |
42 | /**
43 | * A buffer holding the partially computed hash result.
44 | * @type {Array.}
45 | * @private
46 | */
47 | this.buf_ = [];
48 |
49 | /**
50 | * An array of 80 bytes, each a part of the message to be hashed. Referred to
51 | * as the message schedule in the docs.
52 | * @type {Array.}
53 | * @private
54 | */
55 | this.W_ = [];
56 |
57 | /**
58 | * Contains data needed to pad messages less than 64 bytes.
59 | * @type {Array.}
60 | * @private
61 | */
62 | this.pad_ = [];
63 |
64 | this.pad_[0] = 128;
65 | for (var i = 1; i < 64; ++i) {
66 | this.pad_[i] = 0;
67 | }
68 |
69 | this.reset();
70 | };
71 |
72 |
73 | /**
74 | * Resets the internal accumulator.
75 | */
76 | Sha1.prototype.reset = function() {
77 | this.chain_[0] = 0x67452301;
78 | this.chain_[1] = 0xefcdab89;
79 | this.chain_[2] = 0x98badcfe;
80 | this.chain_[3] = 0x10325476;
81 | this.chain_[4] = 0xc3d2e1f0;
82 |
83 | this.inbuf_ = 0;
84 | this.total_ = 0;
85 | };
86 |
87 |
88 | /**
89 | * Internal helper performing 32 bit left rotate.
90 | * @return {number} w rotated left by r bits.
91 | * @private
92 | */
93 | Sha1.prototype.rotl_ = function(w, r) {
94 | return ((w << r) | (w >>> (32 - r))) & 0xffffffff;
95 | };
96 |
97 |
98 | /**
99 | * Internal compress helper function.
100 | * @param {Array} buf containing block to compress.
101 | * @private
102 | */
103 | Sha1.prototype.compress_ = function(buf) {
104 | var W = this.W_;
105 |
106 | // get 16 big endian words
107 | for (var i = 0; i < 64; i += 4) {
108 | var w = (buf[i] << 24) |
109 | (buf[i + 1] << 16) |
110 | (buf[i + 2] << 8) |
111 | (buf[i + 3]);
112 | W[i / 4] = w;
113 | }
114 |
115 | // expand to 80 words
116 | for (var i = 16; i < 80; i++) {
117 | W[i] = this.rotl_(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
118 | }
119 |
120 | var a = this.chain_[0];
121 | var b = this.chain_[1];
122 | var c = this.chain_[2];
123 | var d = this.chain_[3];
124 | var e = this.chain_[4];
125 | var f, k;
126 |
127 | for (var i = 0; i < 80; i++) {
128 | if (i < 40) {
129 | if (i < 20) {
130 | f = d ^ (b & (c ^ d));
131 | k = 0x5a827999;
132 | } else {
133 | f = b ^ c ^ d;
134 | k = 0x6ed9eba1;
135 | }
136 | } else {
137 | if (i < 60) {
138 | f = (b & c) | (d & (b | c));
139 | k = 0x8f1bbcdc;
140 | } else {
141 | f = b ^ c ^ d;
142 | k = 0xca62c1d6;
143 | }
144 | }
145 |
146 | var t = (this.rotl_(a, 5) + f + e + k + W[i]) & 0xffffffff;
147 | e = d;
148 | d = c;
149 | c = this.rotl_(b, 30);
150 | b = a;
151 | a = t;
152 | }
153 |
154 | this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;
155 | this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;
156 | this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;
157 | this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;
158 | this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;
159 | };
160 |
161 |
162 | /**
163 | * Adds a byte array to internal accumulator.
164 | * @param {Array.} bytes to add to digest.
165 | * @param {number} opt_length is # of bytes to compress.
166 | */
167 | Sha1.prototype.update = function(bytes, opt_length) {
168 | if (!opt_length) {
169 | opt_length = bytes.length;
170 | }
171 |
172 | var n = 0;
173 |
174 | // Optimize for 64 byte chunks at 64 byte boundaries.
175 | if (this.inbuf_ == 0) {
176 | while (n + 64 < opt_length) {
177 | this.compress_(bytes.slice(n, n + 64));
178 | n += 64;
179 | this.total_ += 64;
180 | }
181 | }
182 |
183 | while (n < opt_length) {
184 | this.buf_[this.inbuf_++] = bytes[n++];
185 | this.total_++;
186 |
187 | if (this.inbuf_ == 64) {
188 | this.inbuf_ = 0;
189 | this.compress_(this.buf_);
190 |
191 | // Pick up 64 byte chunks.
192 | while (n + 64 < opt_length) {
193 | this.compress_(bytes.slice(n, n + 64));
194 | n += 64;
195 | this.total_ += 64;
196 | }
197 | }
198 | }
199 | };
200 |
201 |
202 | /**
203 | * @return {Array} byte[20] containing finalized hash.
204 | */
205 | Sha1.prototype.digest = function() {
206 | var digest = [];
207 | var totalBits = this.total_ * 8;
208 |
209 | // Add pad 0x80 0x00*.
210 | if (this.inbuf_ < 56) {
211 | this.update(this.pad_, 56 - this.inbuf_);
212 | } else {
213 | this.update(this.pad_, 64 - (this.inbuf_ - 56));
214 | }
215 |
216 | // Add # bits.
217 | for (var i = 63; i >= 56; i--) {
218 | this.buf_[i] = totalBits & 255;
219 | totalBits >>>= 8;
220 | }
221 |
222 | this.compress_(this.buf_);
223 |
224 | var n = 0;
225 | for (var i = 0; i < 5; i++) {
226 | for (var j = 24; j >= 0; j -= 8) {
227 | digest[n++] = (this.chain_[i] >> j) & 255;
228 | }
229 | }
230 |
231 | return digest;
232 | };
233 |
--------------------------------------------------------------------------------
/vendor/websocket-server/http.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 | * Use of this source code is governed by a BSD-style license that can be
4 | * found in the LICENSE file.
5 | **/
6 |
7 | var http = function() {
8 |
9 | if (!chrome.sockets || !chrome.sockets.tcpServer)
10 | return {};
11 |
12 | // Wrap chrome.sockets.tcp socketId with a Promise API.
13 | var PSocket = (function() {
14 | // chrome.sockets.tcp uses a global listener for incoming data so
15 | // use a map to dispatch to the proper instance.
16 | var socketMap = {};
17 | chrome.sockets.tcp.onReceive.addListener(function(info) {
18 | var pSocket = socketMap[info.socketId];
19 | if (pSocket) {
20 | if (pSocket.handlers) {
21 | // Fulfil the pending read.
22 | pSocket.handlers.resolve(info.data);
23 | delete pSocket.handlers;
24 | }
25 | else {
26 | // No pending read so put data on the queue.
27 | pSocket.readQueue.push(info);
28 | }
29 | }
30 | });
31 |
32 | // Read errors also use a global listener.
33 | chrome.sockets.tcp.onReceiveError.addListener(function(info) {
34 | var pSocket = socketMap[info.socketId];
35 | if (pSocket) {
36 | if (pSocket.handlers) {
37 | // Reject the pending read.
38 | pSocket.handlers.reject(new Error('chrome.sockets.tcp error ' + info.resultCode));
39 | delete pSocket.handlers;
40 | }
41 | else {
42 | // No pending read so put data on the queue.
43 | pSocket.readQueue.push(info);
44 | }
45 | }
46 | });
47 |
48 | // PSocket constructor.
49 | return function(socketId) {
50 | this.socketId = socketId;
51 | this.readQueue = [];
52 |
53 | // Register this instance for incoming data processing.
54 | socketMap[socketId] = this;
55 | chrome.sockets.tcp.setPaused(socketId, false);
56 | };
57 | })();
58 |
59 | // Returns a Promise with read data.
60 | PSocket.prototype.read = function() {
61 | var that = this;
62 | if (this.readQueue.length) {
63 | // Return data from the queue.
64 | var info = this.readQueue.shift();
65 | if (!info.resultCode)
66 | return Promise.resolve(info.data);
67 | else
68 | return Promise.reject(new Error('chrome.sockets.tcp error ' + info.resultCode));
69 | }
70 | else {
71 | // The queue is empty so install handlers.
72 | return new Promise(function(resolve, reject) {
73 | that.handlers = { resolve: resolve, reject: reject };
74 | });
75 | }
76 | };
77 |
78 | // Returns a Promise with the number of bytes written.
79 | PSocket.prototype.write = function(data) {
80 | var that = this;
81 | return new Promise(function(resolve, reject) {
82 | chrome.sockets.tcp.send(that.socketId, data, function(info) {
83 | if (info && info.resultCode >= 0)
84 | resolve(info.bytesSent);
85 | else
86 | reject(new Error('chrome sockets.tcp error ' + (info && info.resultCode)));
87 | });
88 | });
89 | };
90 |
91 | // Returns a Promise.
92 | PSocket.prototype.close = function() {
93 | var that = this;
94 | return new Promise(function(resolve, reject) {
95 | chrome.sockets.tcp.disconnect(that.socketId, function() {
96 | chrome.sockets.tcp.close(that.socketId, resolve);
97 | });
98 | });
99 | };
100 |
101 | // Http response code strings.
102 | var responseMap = {
103 | 200: 'OK',
104 | 301: 'Moved Permanently',
105 | 304: 'Not Modified',
106 | 400: 'Bad Request',
107 | 401: 'Unauthorized',
108 | 403: 'Forbidden',
109 | 404: 'Not Found',
110 | 413: 'Request Entity Too Large',
111 | 414: 'Request-URI Too Long',
112 | 500: 'Internal Server Error'};
113 |
114 | /**
115 | * Convert from an ArrayBuffer to a string.
116 | * @param {ArrayBuffer} buffer The array buffer to convert.
117 | * @return {string} The textual representation of the array.
118 | */
119 | var arrayBufferToString = function(buffer) {
120 | var array = new Uint8Array(buffer);
121 | var str = '';
122 | for (var i = 0; i < array.length; ++i) {
123 | str += String.fromCharCode(array[i]);
124 | }
125 | return str;
126 | };
127 |
128 | /**
129 | * Convert from an UTF-8 array to UTF-8 string.
130 | * @param {array} UTF-8 array
131 | * @return {string} UTF-8 string
132 | */
133 | var ary2utf8 = (function() {
134 |
135 | var patterns = [
136 | {pattern: '0xxxxxxx', bytes: 1},
137 | {pattern: '110xxxxx', bytes: 2},
138 | {pattern: '1110xxxx', bytes: 3},
139 | {pattern: '11110xxx', bytes: 4},
140 | {pattern: '111110xx', bytes: 5},
141 | {pattern: '1111110x', bytes: 6}
142 | ];
143 | patterns.forEach(function(item) {
144 | item.header = item.pattern.replace(/[^10]/g, '');
145 | item.pattern01 = item.pattern.replace(/[^10]/g, '0');
146 | item.pattern01 = parseInt(item.pattern01, 2);
147 | item.mask_length = item.header.length;
148 | item.data_length = 8 - item.header.length;
149 | var mask = '';
150 | for (var i = 0, len = item.mask_length; i < len; i++) {
151 | mask += '1';
152 | }
153 | for (var i = 0, len = item.data_length; i < len; i++) {
154 | mask += '0';
155 | }
156 | item.mask = mask;
157 | item.mask = parseInt(item.mask, 2);
158 | });
159 |
160 | return function(ary) {
161 | var codes = [];
162 | var cur = 0;
163 | while(cur < ary.length) {
164 | var first = ary[cur];
165 | var pattern = null;
166 | for (var i = 0, len = patterns.length; i < len; i++) {
167 | if ((first & patterns[i].mask) == patterns[i].pattern01) {
168 | pattern = patterns[i];
169 | break;
170 | }
171 | }
172 | if (pattern == null) {
173 | throw 'utf-8 decode error';
174 | }
175 | var rest = ary.slice(cur + 1, cur + pattern.bytes);
176 | cur += pattern.bytes;
177 | var code = '';
178 | code += ('00000000' + (first & (255 ^ pattern.mask)).toString(2)).slice(-pattern.data_length);
179 | for (var i = 0, len = rest.length; i < len; i++) {
180 | code += ('00000000' + (rest[i] & parseInt('111111', 2)).toString(2)).slice(-6);
181 | }
182 | codes.push(parseInt(code, 2));
183 | }
184 | return String.fromCharCode.apply(null, codes);
185 | };
186 |
187 | })();
188 |
189 | /**
190 | * Convert from an UTF-8 string to UTF-8 array.
191 | * @param {string} UTF-8 string
192 | * @return {array} UTF-8 array
193 | */
194 | var utf82ary = (function() {
195 |
196 | var patterns = [
197 | {pattern: '0xxxxxxx', bytes: 1},
198 | {pattern: '110xxxxx', bytes: 2},
199 | {pattern: '1110xxxx', bytes: 3},
200 | {pattern: '11110xxx', bytes: 4},
201 | {pattern: '111110xx', bytes: 5},
202 | {pattern: '1111110x', bytes: 6}
203 | ];
204 | patterns.forEach(function(item) {
205 | item.header = item.pattern.replace(/[^10]/g, '');
206 | item.mask_length = item.header.length;
207 | item.data_length = 8 - item.header.length;
208 | item.max_bit_length = (item.bytes - 1) * 6 + item.data_length;
209 | });
210 |
211 | var code2utf8array = function(code) {
212 | var pattern = null;
213 | var code01 = code.toString(2);
214 | for (var i = 0, len = patterns.length; i < len; i++) {
215 | if (code01.length <= patterns[i].max_bit_length) {
216 | pattern = patterns[i];
217 | break;
218 | }
219 | }
220 | if (pattern == null) {
221 | throw 'utf-8 encode error';
222 | }
223 | var ary = [];
224 | for (var i = 0, len = pattern.bytes - 1; i < len; i++) {
225 | ary.unshift(parseInt('10' + ('000000' + code01.slice(-6)).slice(-6), 2));
226 | code01 = code01.slice(0, -6);
227 | }
228 | ary.unshift(parseInt(pattern.header + ('00000000' + code01).slice(-pattern.data_length), 2));
229 | return ary;
230 | };
231 |
232 | return function(str) {
233 | var codes = [];
234 | for (var i = 0, len = str.length; i < len; i++) {
235 | var code = str.charCodeAt(i);
236 | Array.prototype.push.apply(codes, code2utf8array(code));
237 | }
238 | return codes;
239 | };
240 |
241 | })();
242 |
243 | /**
244 | * Convert a string to an ArrayBuffer.
245 | * @param {string} string The string to convert.
246 | * @return {ArrayBuffer} An array buffer whose bytes correspond to the string.
247 | */
248 | var stringToArrayBuffer = function(string) {
249 | var buffer = new ArrayBuffer(string.length);
250 | var bufferView = new Uint8Array(buffer);
251 | for (var i = 0; i < string.length; i++) {
252 | bufferView[i] = string.charCodeAt(i);
253 | }
254 | return buffer;
255 | };
256 |
257 | /**
258 | * An event source can dispatch events. These are dispatched to all of the
259 | * functions listening for that event type with arguments.
260 | * @constructor
261 | */
262 | function EventSource() {
263 | this.listeners_ = {};
264 | };
265 |
266 | EventSource.prototype = {
267 | /**
268 | * Add |callback| as a listener for |type| events.
269 | * @param {string} type The type of the event.
270 | * @param {function(Object|undefined): boolean} callback The function to call
271 | * when this event type is dispatched. Arguments depend on the event
272 | * source and type. The function returns whether the event was "handled"
273 | * which will prevent delivery to the rest of the listeners.
274 | */
275 | addEventListener: function(type, callback) {
276 | if (!this.listeners_[type])
277 | this.listeners_[type] = [];
278 | this.listeners_[type].push(callback);
279 | },
280 |
281 | /**
282 | * Remove |callback| as a listener for |type| events.
283 | * @param {string} type The type of the event.
284 | * @param {function(Object|undefined): boolean} callback The callback
285 | * function to remove from the event listeners for events having type
286 | * |type|.
287 | */
288 | removeEventListener: function(type, callback) {
289 | if (!this.listeners_[type])
290 | return;
291 | for (var i = this.listeners_[type].length - 1; i >= 0; i--) {
292 | if (this.listeners_[type][i] == callback) {
293 | this.listeners_[type].splice(i, 1);
294 | }
295 | }
296 | },
297 |
298 | /**
299 | * Dispatch an event to all listeners for events of type |type|.
300 | * @param {type} type The type of the event being dispatched.
301 | * @param {...Object} var_args The arguments to pass when calling the
302 | * callback function.
303 | * @return {boolean} Returns true if the event was handled.
304 | */
305 | dispatchEvent: function(type, var_args) {
306 | if (!this.listeners_[type])
307 | return false;
308 | for (var i = 0; i < this.listeners_[type].length; i++) {
309 | if (this.listeners_[type][i].apply(
310 | /* this */ null,
311 | /* var_args */ Array.prototype.slice.call(arguments, 1))) {
312 | return true;
313 | }
314 | }
315 | }
316 | };
317 |
318 | /**
319 | * HttpServer provides a lightweight Http web server. Currently it only
320 | * supports GET requests and upgrading to other protocols (i.e. WebSockets).
321 | * @constructor
322 | */
323 | function HttpServer() {
324 | EventSource.apply(this);
325 | this.readyState_ = 0;
326 | }
327 |
328 | HttpServer.prototype = {
329 | __proto__: EventSource.prototype,
330 |
331 | /**
332 | * Listen for connections on |port| using the interface |host|.
333 | * @param {number} port The port to listen for incoming connections on.
334 | * @param {string=} opt_host The host interface to listen for connections on.
335 | * This will default to 0.0.0.0 if not specified which will listen on
336 | * all interfaces.
337 | */
338 | listen: function(port, opt_host) {
339 | var t = this;
340 | chrome.sockets.tcpServer.create(function(socketInfo) {
341 | chrome.sockets.tcpServer.onAccept.addListener(function(acceptInfo) {
342 | if (acceptInfo.socketId === socketInfo.socketId)
343 | t.readRequestFromSocket_(new PSocket(acceptInfo.clientSocketId));
344 | });
345 |
346 | chrome.sockets.tcpServer.listen(
347 | socketInfo.socketId,
348 | opt_host || '0.0.0.0',
349 | port,
350 | 50,
351 | function(result) {
352 | if (!result) {
353 | t.readyState_ = 1;
354 | }
355 | else {
356 | console.log(
357 | 'listen error ' +
358 | chrome.runtime.lastError.message +
359 | ' (normal if another instance is already serving requests)');
360 | }
361 | });
362 | });
363 | },
364 |
365 | readRequestFromSocket_: function(pSocket) {
366 | var t = this;
367 | var requestData = '';
368 | var endIndex = 0;
369 | var onDataRead = function(data) {
370 | requestData += arrayBufferToString(data).replace(/\r\n/g, '\n');
371 | // Check for end of request.
372 | endIndex = requestData.indexOf('\n\n', endIndex);
373 | if (endIndex == -1) {
374 | endIndex = requestData.length - 1;
375 | return pSocket.read().then(onDataRead);
376 | }
377 |
378 | var headers = requestData.substring(0, endIndex).split('\n');
379 | var headerMap = {};
380 | // headers[0] should be the Request-Line
381 | var requestLine = headers[0].split(' ');
382 | headerMap['method'] = requestLine[0];
383 | headerMap['url'] = requestLine[1];
384 | headerMap['Http-Version'] = requestLine[2];
385 | for (var i = 1; i < headers.length; i++) {
386 | requestLine = headers[i].split(':', 2);
387 | if (requestLine.length == 2)
388 | headerMap[requestLine[0]] = requestLine[1].trim();
389 | }
390 | var request = new HttpRequest(headerMap, pSocket);
391 | t.onRequest_(request);
392 | };
393 |
394 | pSocket.read().then(onDataRead).catch(function(e) {
395 | pSocket.close();
396 | });
397 | },
398 |
399 | onRequest_: function(request) {
400 | var type = request.headers['Upgrade'] ? 'upgrade' : 'request';
401 | var keepAlive = request.headers['Connection'] == 'keep-alive';
402 | if (!this.dispatchEvent(type, request))
403 | request.close();
404 | else if (keepAlive)
405 | this.readRequestFromSocket_(request.pSocket_);
406 | },
407 | };
408 |
409 | // MIME types for common extensions.
410 | var extensionTypes = {
411 | 'css': 'text/css',
412 | 'html': 'text/html',
413 | 'htm': 'text/html',
414 | 'jpg': 'image/jpeg',
415 | 'jpeg': 'image/jpeg',
416 | 'js': 'text/javascript',
417 | 'png': 'image/png',
418 | 'svg': 'image/svg+xml',
419 | 'txt': 'text/plain'};
420 |
421 | /**
422 | * Constructs an HttpRequest object which tracks all of the request headers and
423 | * socket for an active Http request.
424 | * @param {Object} headers The HTTP request headers.
425 | * @param {Object} pSocket The socket to use for the response.
426 | * @constructor
427 | */
428 | function HttpRequest(headers, pSocket) {
429 | this.version = 'HTTP/1.1';
430 | this.headers = headers;
431 | this.responseHeaders_ = {};
432 | this.headersSent = false;
433 | this.pSocket_ = pSocket;
434 | this.writes_ = 0;
435 | this.bytesRemaining = 0;
436 | this.finished_ = false;
437 | this.readyState = 1;
438 | }
439 |
440 | HttpRequest.prototype = {
441 | __proto__: EventSource.prototype,
442 |
443 | /**
444 | * Closes the Http request.
445 | */
446 | close: function() {
447 | // The socket for keep alive connections will be re-used by the server.
448 | // Just stop referencing or using the socket in this HttpRequest.
449 | if (this.headers['Connection'] != 'keep-alive')
450 | pSocket.close();
451 |
452 | this.pSocket_ = null;
453 | this.readyState = 3;
454 | },
455 |
456 | /**
457 | * Write the provided headers as a response to the request.
458 | * @param {int} responseCode The HTTP status code to respond with.
459 | * @param {Object} responseHeaders The response headers describing the
460 | * response.
461 | */
462 | writeHead: function(responseCode, responseHeaders) {
463 | var headerString = this.version + ' ' + responseCode + ' ' +
464 | (responseMap[responseCode] || 'Unknown');
465 | this.responseHeaders_ = responseHeaders;
466 | if (this.headers['Connection'] == 'keep-alive')
467 | responseHeaders['Connection'] = 'keep-alive';
468 | if (!responseHeaders['Content-Length'] && responseHeaders['Connection'] == 'keep-alive')
469 | responseHeaders['Transfer-Encoding'] = 'chunked';
470 | for (var i in responseHeaders) {
471 | headerString += '\r\n' + i + ': ' + responseHeaders[i];
472 | }
473 | headerString += '\r\n\r\n';
474 | this.write_(stringToArrayBuffer(headerString));
475 | },
476 |
477 | /**
478 | * Writes data to the response stream.
479 | * @param {string|ArrayBuffer} data The data to write to the stream.
480 | */
481 | write: function(data) {
482 | if (this.responseHeaders_['Transfer-Encoding'] == 'chunked') {
483 | var newline = '\r\n';
484 | var byteLength = (data instanceof ArrayBuffer) ? data.byteLength : data.length;
485 | var chunkLength = byteLength.toString(16).toUpperCase() + newline;
486 | var buffer = new ArrayBuffer(chunkLength.length + byteLength + newline.length);
487 | var bufferView = new Uint8Array(buffer);
488 | for (var i = 0; i < chunkLength.length; i++)
489 | bufferView[i] = chunkLength.charCodeAt(i);
490 | if (data instanceof ArrayBuffer) {
491 | bufferView.set(new Uint8Array(data), chunkLength.length);
492 | } else {
493 | for (var i = 0; i < data.length; i++)
494 | bufferView[chunkLength.length + i] = data.charCodeAt(i);
495 | }
496 | for (var i = 0; i < newline.length; i++)
497 | bufferView[chunkLength.length + byteLength + i] = newline.charCodeAt(i);
498 | data = buffer;
499 | } else if (!(data instanceof ArrayBuffer)) {
500 | data = stringToArrayBuffer(data);
501 | }
502 | this.write_(data);
503 | },
504 |
505 | /**
506 | * Finishes the HTTP response writing |data| before closing.
507 | * @param {string|ArrayBuffer=} opt_data Optional data to write to the stream
508 | * before closing it.
509 | */
510 | end: function(opt_data) {
511 | if (opt_data)
512 | this.write(opt_data);
513 | if (this.responseHeaders_['Transfer-Encoding'] == 'chunked')
514 | this.write('');
515 | this.finished_ = true;
516 | this.checkFinished_();
517 | },
518 |
519 | /**
520 | * Automatically serve the given |url| request.
521 | * @param {string} url The URL to fetch the file to be served from. This is
522 | * retrieved via an XmlHttpRequest and served as the response to the
523 | * request.
524 | */
525 | serveUrl: function(url) {
526 | var t = this;
527 | var xhr = new XMLHttpRequest();
528 | xhr.onloadend = function() {
529 | var type = 'text/plain';
530 | if (this.getResponseHeader('Content-Type')) {
531 | type = this.getResponseHeader('Content-Type');
532 | } else if (url.indexOf('.') != -1) {
533 | var extension = url.substr(url.indexOf('.') + 1);
534 | type = extensionTypes[extension] || type;
535 | }
536 | console.log('Served ' + url);
537 | var contentLength = this.getResponseHeader('Content-Length');
538 | if (xhr.status == 200)
539 | contentLength = (this.response && this.response.byteLength) || 0;
540 | t.writeHead(this.status, {
541 | 'Content-Type': type,
542 | 'Content-Length': contentLength});
543 | t.end(this.response);
544 | };
545 | xhr.open('GET', url, true);
546 | xhr.responseType = 'arraybuffer';
547 | xhr.send();
548 | },
549 |
550 | write_: function(array) {
551 | var t = this;
552 | this.bytesRemaining += array.byteLength;
553 | this.pSocket_.write(array).then(function(bytesWritten) {
554 | t.bytesRemaining -= bytesWritten;
555 | t.checkFinished_();
556 | }).catch(function(e) {
557 | console.error(e.message);
558 | return;
559 | });
560 | },
561 |
562 | checkFinished_: function() {
563 | if (!this.finished_ || this.bytesRemaining > 0)
564 | return;
565 | this.close();
566 | }
567 | };
568 |
569 | /**
570 | * Constructs a server which is capable of accepting WebSocket connections.
571 | * @param {HttpServer} httpServer The Http Server to listen and handle
572 | * WebSocket upgrade requests on.
573 | * @constructor
574 | */
575 | function WebSocketServer(httpServer) {
576 | EventSource.apply(this);
577 | httpServer.addEventListener('upgrade', this.upgradeToWebSocket_.bind(this));
578 | }
579 |
580 | WebSocketServer.prototype = {
581 | __proto__: EventSource.prototype,
582 |
583 | upgradeToWebSocket_: function(request) {
584 | if (request.headers['Upgrade'] != 'websocket' ||
585 | !request.headers['Sec-WebSocket-Key']) {
586 | return false;
587 | }
588 |
589 | if (this.dispatchEvent('request', new WebSocketRequest(request))) {
590 | if (request.pSocket_)
591 | request.reject();
592 | return true;
593 | }
594 |
595 | return false;
596 | }
597 | };
598 |
599 | /**
600 | * Constructs a WebSocket request object from an Http request. This invalidates
601 | * the Http request's socket and offers accept and reject methods for accepting
602 | * and rejecting the WebSocket upgrade request.
603 | * @param {HttpRequest} httpRequest The HTTP request to upgrade.
604 | */
605 | function WebSocketRequest(httpRequest) {
606 | // We'll assume control of the socket for this request.
607 | HttpRequest.apply(this, [httpRequest.headers, httpRequest.pSocket_]);
608 | httpRequest.pSocket_ = null;
609 | }
610 |
611 | WebSocketRequest.prototype = {
612 | __proto__: HttpRequest.prototype,
613 |
614 | /**
615 | * Accepts the WebSocket request.
616 | * @return {WebSocketServerSocket} The websocket for the accepted request.
617 | */
618 | accept: function() {
619 | // Construct WebSocket response key.
620 | var clientKey = this.headers['Sec-WebSocket-Key'];
621 | var toArray = function(str) {
622 | var a = [];
623 | for (var i = 0; i < str.length; i++) {
624 | a.push(str.charCodeAt(i));
625 | }
626 | return a;
627 | }
628 | var toString = function(a) {
629 | var str = '';
630 | for (var i = 0; i < a.length; i++) {
631 | str += String.fromCharCode(a[i]);
632 | }
633 | return str;
634 | }
635 |
636 | // Magic string used for websocket connection key hashing:
637 | // http://en.wikipedia.org/wiki/WebSocket
638 | var magicStr = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
639 |
640 | // clientKey is base64 encoded key.
641 | clientKey += magicStr;
642 | var sha1 = new Sha1();
643 | sha1.reset();
644 | sha1.update(toArray(clientKey));
645 | var responseKey = btoa(toString(sha1.digest()));
646 | var responseHeader = {
647 | 'Upgrade': 'websocket',
648 | 'Connection': 'Upgrade',
649 | 'Sec-WebSocket-Accept': responseKey};
650 | if (this.headers['Sec-WebSocket-Protocol'])
651 | responseHeader['Sec-WebSocket-Protocol'] = this.headers['Sec-WebSocket-Protocol'];
652 | this.writeHead(101, responseHeader);
653 | var socket = new WebSocketServerSocket(this.pSocket_);
654 | // Detach the socket so that we don't use it anymore.
655 | this.pSocket_ = 0;
656 | return socket;
657 | },
658 |
659 | /**
660 | * Rejects the WebSocket request, closing the connection.
661 | */
662 | reject: function() {
663 | this.close();
664 | }
665 | }
666 |
667 | /**
668 | * Constructs a WebSocketServerSocket using the given socketId. This should be
669 | * a socket which has already been upgraded from an Http request.
670 | * @param {number} socketId The socket id with an active websocket connection.
671 | */
672 | function WebSocketServerSocket(pSocket) {
673 | this.pSocket_ = pSocket;
674 | this.readyState = 1;
675 | EventSource.apply(this);
676 | this.readFromSocket_();
677 | }
678 |
679 | WebSocketServerSocket.prototype = {
680 | __proto__: EventSource.prototype,
681 |
682 | /**
683 | * Send |data| on the WebSocket.
684 | * @param {string|Array.|ArrayBuffer} data The data to send over the WebSocket.
685 | */
686 | send: function(data) {
687 | // WebSocket must specify opcode when send frame.
688 | // The opcode for data frame is 1(text) or 2(binary).
689 | if (typeof data == 'string' || data instanceof String) {
690 | this.sendFrame_(1, data);
691 | } else {
692 | this.sendFrame_(2, data);
693 | }
694 | },
695 |
696 | /**
697 | * Begin closing the WebSocket. Note that the WebSocket protocol uses a
698 | * handshake to close the connection, so this call will begin the closing
699 | * process.
700 | */
701 | close: function() {
702 | if (this.readyState === 1) {
703 | this.sendFrame_(8);
704 | this.readyState = 2;
705 | }
706 | },
707 |
708 | readFromSocket_: function() {
709 | var t = this;
710 | var data = [];
711 | var message = '';
712 | var fragmentedOp = 0;
713 | var fragmentedMessages = [];
714 |
715 | var onDataRead = function(dataBuffer) {
716 | var a = new Uint8Array(dataBuffer);
717 | for (var i = 0; i < a.length; i++)
718 | data.push(a[i]);
719 |
720 | while (data.length) {
721 | var length_code = -1;
722 | var data_start = 6;
723 | var mask;
724 | var fin = (data[0] & 128) >> 7;
725 | var op = data[0] & 15;
726 |
727 | if (data.length > 1)
728 | length_code = data[1] & 127;
729 | if (length_code > 125) {
730 | if ((length_code == 126 && data.length > 7) ||
731 | (length_code == 127 && data.length > 14)) {
732 | if (length_code == 126) {
733 | length_code = data[2] * 256 + data[3];
734 | mask = data.slice(4, 8);
735 | data_start = 8;
736 | } else if (length_code == 127) {
737 | length_code = 0;
738 | for (var i = 0; i < 8; i++) {
739 | length_code = length_code * 256 + data[2 + i];
740 | }
741 | mask = data.slice(10, 14);
742 | data_start = 14;
743 | }
744 | } else {
745 | length_code = -1; // Insufficient data to compute length
746 | }
747 | } else {
748 | if (data.length > 5)
749 | mask = data.slice(2, 6);
750 | }
751 |
752 | if (length_code > -1 && data.length >= data_start + length_code) {
753 | var decoded = data.slice(data_start, data_start + length_code).map(function(byte, index) {
754 | return byte ^ mask[index % 4];
755 | });
756 | if (op == 1) {
757 | decoded = ary2utf8(decoded);
758 | }
759 | data = data.slice(data_start + length_code);
760 | if (fin && op > 0) {
761 | // Unfragmented message.
762 | if (!t.onFrame_(op, decoded))
763 | return;
764 | } else {
765 | // Fragmented message.
766 | fragmentedOp = fragmentedOp || op;
767 | fragmentedMessages.push(decoded);
768 | if (fin) {
769 | var joinMessage = null;
770 | if (op == 1) {
771 | joinMessage = fragmentedMessagess.join('');
772 | } else {
773 | joinMessage = fragmentedMessages.reduce(function(pre, cur) {
774 | return Array.prototype.push.apply(pre, cur);
775 | }, []);
776 | }
777 | if (!t.onFrame_(fragmentedOp, joinMessage))
778 | return;
779 | fragmentedOp = 0;
780 | fragmentedMessages = [];
781 | }
782 | }
783 | } else {
784 | break; // Insufficient data, wait for more.
785 | }
786 | }
787 |
788 | return t.pSocket_.read().then(onDataRead);
789 | };
790 |
791 | this.pSocket_.read().then(function(data) {
792 | return onDataRead(data);
793 | }).catch(function(e) {
794 | t.close_();
795 | });
796 | },
797 |
798 | onFrame_: function(op, data) {
799 | if (op == 1 || op == 2) {
800 | if (typeof data == 'string' || data instanceof String) {
801 | // Don't do anything.
802 | } else if (Array.isArray(data)) {
803 | data = new Uint8Array(data).buffer;
804 | } else if (data instanceof ArrayBuffer) {
805 | // Don't do anything.
806 | } else {
807 | data = data.buffer;
808 | }
809 | this.dispatchEvent('message', {'data': data});
810 | } else if (op == 8) {
811 | // A close message must be confirmed before the websocket is closed.
812 | if (this.readyState === 1) {
813 | this.sendFrame_(8);
814 | this.readyState = 2;
815 | } else {
816 | this.close_();
817 | return false;
818 | }
819 | }
820 | return true;
821 | },
822 |
823 | sendFrame_: function(op, data) {
824 | var t = this;
825 | var WebsocketFrameData = function(op, data) {
826 | var ary = data;
827 | if (typeof data == 'string' || data instanceof String) {
828 | ary = utf82ary(data);
829 | }
830 | if (Array.isArray(ary)) {
831 | ary = new Uint8Array(ary);
832 | }
833 | if (ary instanceof ArrayBuffer) {
834 | ary = new Uint8Array(ary);
835 | }
836 | ary = new Uint8Array(ary.buffer);
837 | var length = ary.length;
838 | if (ary.length > 65535)
839 | length += 10;
840 | else if (ary.length > 125)
841 | length += 4;
842 | else
843 | length += 2;
844 | var lengthBytes = 0;
845 | var buffer = new ArrayBuffer(length);
846 | var bv = new Uint8Array(buffer);
847 | bv[0] = 128 | (op & 15); // Fin and type text.
848 | bv[1] = ary.length > 65535 ? 127 :
849 | (ary.length > 125 ? 126 : ary.length);
850 | if (ary.length > 65535)
851 | lengthBytes = 8;
852 | else if (ary.length > 125)
853 | lengthBytes = 2;
854 | var len = ary.length;
855 | for (var i = lengthBytes - 1; i >= 0; i--) {
856 | bv[2 + i] = len & 255;
857 | len = len >> 8;
858 | }
859 | var dataStart = lengthBytes + 2;
860 | for (var i = 0; i < ary.length; i++) {
861 | bv[dataStart + i] = ary[i];
862 | }
863 | return buffer;
864 | }
865 | var array = WebsocketFrameData(op, data || '');
866 | this.pSocket_.write(array).then(function(bytesWritten) {
867 | if (bytesWritten !== array.byteLength)
868 | throw new Error('insufficient write');
869 | }).catch(function(e) {
870 | t.close_();
871 | });
872 | },
873 |
874 | close_: function() {
875 | if (this.readyState !== 3) {
876 | this.pSocket_.close();
877 | this.readyState = 3;
878 | this.dispatchEvent('close');
879 | }
880 | }
881 | };
882 |
883 | return {
884 | 'Server': HttpServer,
885 | 'WebSocketServer': WebSocketServer,
886 | };
887 | }();
888 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | ansi-gray@^0.1.1:
6 | version "0.1.1"
7 | resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251"
8 | dependencies:
9 | ansi-wrap "0.1.0"
10 |
11 | ansi-regex@^2.0.0:
12 | version "2.1.1"
13 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
14 |
15 | ansi-styles@^2.2.1:
16 | version "2.2.1"
17 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
18 |
19 | ansi-wrap@0.1.0:
20 | version "0.1.0"
21 | resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
22 |
23 | archy@^1.0.0:
24 | version "1.0.0"
25 | resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40"
26 |
27 | arr-diff@^4.0.0:
28 | version "4.0.0"
29 | resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
30 |
31 | arr-flatten@^1.1.0:
32 | version "1.1.0"
33 | resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
34 |
35 | arr-union@^3.1.0:
36 | version "3.1.0"
37 | resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
38 |
39 | array-differ@^1.0.0:
40 | version "1.0.0"
41 | resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031"
42 |
43 | array-each@^1.0.1:
44 | version "1.0.1"
45 | resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f"
46 |
47 | array-slice@^1.0.0:
48 | version "1.1.0"
49 | resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4"
50 |
51 | array-uniq@^1.0.2:
52 | version "1.0.3"
53 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
54 |
55 | array-unique@^0.3.2:
56 | version "0.3.2"
57 | resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
58 |
59 | assign-symbols@^1.0.0:
60 | version "1.0.0"
61 | resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
62 |
63 | atob@^2.0.0:
64 | version "2.0.3"
65 | resolved "https://registry.yarnpkg.com/atob/-/atob-2.0.3.tgz#19c7a760473774468f20b2d2d03372ad7d4cbf5d"
66 |
67 | balanced-match@^1.0.0:
68 | version "1.0.0"
69 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
70 |
71 | base@^0.11.1:
72 | version "0.11.2"
73 | resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
74 | dependencies:
75 | cache-base "^1.0.1"
76 | class-utils "^0.3.5"
77 | component-emitter "^1.2.1"
78 | define-property "^1.0.0"
79 | isobject "^3.0.1"
80 | mixin-deep "^1.2.0"
81 | pascalcase "^0.1.1"
82 |
83 | beeper@^1.0.0:
84 | version "1.1.1"
85 | resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809"
86 |
87 | brace-expansion@^1.0.0:
88 | version "1.1.8"
89 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
90 | dependencies:
91 | balanced-match "^1.0.0"
92 | concat-map "0.0.1"
93 |
94 | braces@^2.3.0:
95 | version "2.3.0"
96 | resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.0.tgz#a46941cb5fb492156b3d6a656e06c35364e3e66e"
97 | dependencies:
98 | arr-flatten "^1.1.0"
99 | array-unique "^0.3.2"
100 | define-property "^1.0.0"
101 | extend-shallow "^2.0.1"
102 | fill-range "^4.0.0"
103 | isobject "^3.0.1"
104 | repeat-element "^1.1.2"
105 | snapdragon "^0.8.1"
106 | snapdragon-node "^2.0.1"
107 | split-string "^3.0.2"
108 | to-regex "^3.0.1"
109 |
110 | cache-base@^1.0.1:
111 | version "1.0.1"
112 | resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
113 | dependencies:
114 | collection-visit "^1.0.0"
115 | component-emitter "^1.2.1"
116 | get-value "^2.0.6"
117 | has-value "^1.0.0"
118 | isobject "^3.0.1"
119 | set-value "^2.0.0"
120 | to-object-path "^0.3.0"
121 | union-value "^1.0.0"
122 | unset-value "^1.0.0"
123 |
124 | chalk@^1.0.0:
125 | version "1.1.3"
126 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
127 | dependencies:
128 | ansi-styles "^2.2.1"
129 | escape-string-regexp "^1.0.2"
130 | has-ansi "^2.0.0"
131 | strip-ansi "^3.0.0"
132 | supports-color "^2.0.0"
133 |
134 | class-utils@^0.3.5:
135 | version "0.3.6"
136 | resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
137 | dependencies:
138 | arr-union "^3.1.0"
139 | define-property "^0.2.5"
140 | isobject "^3.0.0"
141 | static-extend "^0.1.1"
142 |
143 | clone-stats@^0.0.1:
144 | version "0.0.1"
145 | resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1"
146 |
147 | clone@^0.2.0:
148 | version "0.2.0"
149 | resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f"
150 |
151 | clone@^1.0.0, clone@^1.0.2:
152 | version "1.0.3"
153 | resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f"
154 |
155 | collection-visit@^1.0.0:
156 | version "1.0.0"
157 | resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
158 | dependencies:
159 | map-visit "^1.0.0"
160 | object-visit "^1.0.0"
161 |
162 | color-support@^1.1.3:
163 | version "1.1.3"
164 | resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
165 |
166 | component-emitter@^1.2.1:
167 | version "1.2.1"
168 | resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
169 |
170 | concat-map@0.0.1:
171 | version "0.0.1"
172 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
173 |
174 | copy-descriptor@^0.1.0:
175 | version "0.1.1"
176 | resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
177 |
178 | core-util-is@~1.0.0:
179 | version "1.0.2"
180 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
181 |
182 | dateformat@^2.0.0:
183 | version "2.2.0"
184 | resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062"
185 |
186 | debug@^2.2.0, debug@^2.3.3:
187 | version "2.6.9"
188 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
189 | dependencies:
190 | ms "2.0.0"
191 |
192 | decode-uri-component@^0.2.0:
193 | version "0.2.0"
194 | resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
195 |
196 | defaults@^1.0.0:
197 | version "1.0.3"
198 | resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
199 | dependencies:
200 | clone "^1.0.2"
201 |
202 | define-property@^0.2.5:
203 | version "0.2.5"
204 | resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116"
205 | dependencies:
206 | is-descriptor "^0.1.0"
207 |
208 | define-property@^1.0.0:
209 | version "1.0.0"
210 | resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6"
211 | dependencies:
212 | is-descriptor "^1.0.0"
213 |
214 | deprecated@^0.0.1:
215 | version "0.0.1"
216 | resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19"
217 |
218 | detect-file@^1.0.0:
219 | version "1.0.0"
220 | resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
221 |
222 | duplexer2@0.0.2:
223 | version "0.0.2"
224 | resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db"
225 | dependencies:
226 | readable-stream "~1.1.9"
227 |
228 | end-of-stream@~0.1.5:
229 | version "0.1.5"
230 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf"
231 | dependencies:
232 | once "~1.3.0"
233 |
234 | escape-string-regexp@^1.0.2:
235 | version "1.0.5"
236 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
237 |
238 | expand-brackets@^2.1.4:
239 | version "2.1.4"
240 | resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
241 | dependencies:
242 | debug "^2.3.3"
243 | define-property "^0.2.5"
244 | extend-shallow "^2.0.1"
245 | posix-character-classes "^0.1.0"
246 | regex-not "^1.0.0"
247 | snapdragon "^0.8.1"
248 | to-regex "^3.0.1"
249 |
250 | expand-tilde@^2.0.0, expand-tilde@^2.0.2:
251 | version "2.0.2"
252 | resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
253 | dependencies:
254 | homedir-polyfill "^1.0.1"
255 |
256 | extend-shallow@^2.0.1:
257 | version "2.0.1"
258 | resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
259 | dependencies:
260 | is-extendable "^0.1.0"
261 |
262 | extend-shallow@^3.0.0:
263 | version "3.0.2"
264 | resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8"
265 | dependencies:
266 | assign-symbols "^1.0.0"
267 | is-extendable "^1.0.1"
268 |
269 | extend@^3.0.0:
270 | version "3.0.1"
271 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
272 |
273 | extglob@^2.0.2:
274 | version "2.0.4"
275 | resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
276 | dependencies:
277 | array-unique "^0.3.2"
278 | define-property "^1.0.0"
279 | expand-brackets "^2.1.4"
280 | extend-shallow "^2.0.1"
281 | fragment-cache "^0.2.1"
282 | regex-not "^1.0.0"
283 | snapdragon "^0.8.1"
284 | to-regex "^3.0.1"
285 |
286 | fancy-log@^1.1.0:
287 | version "1.3.2"
288 | resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.2.tgz#f41125e3d84f2e7d89a43d06d958c8f78be16be1"
289 | dependencies:
290 | ansi-gray "^0.1.1"
291 | color-support "^1.1.3"
292 | time-stamp "^1.0.0"
293 |
294 | fill-range@^4.0.0:
295 | version "4.0.0"
296 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
297 | dependencies:
298 | extend-shallow "^2.0.1"
299 | is-number "^3.0.0"
300 | repeat-string "^1.6.1"
301 | to-regex-range "^2.1.0"
302 |
303 | find-index@^0.1.1:
304 | version "0.1.1"
305 | resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4"
306 |
307 | findup-sync@^2.0.0:
308 | version "2.0.0"
309 | resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc"
310 | dependencies:
311 | detect-file "^1.0.0"
312 | is-glob "^3.1.0"
313 | micromatch "^3.0.4"
314 | resolve-dir "^1.0.1"
315 |
316 | fined@^1.0.1:
317 | version "1.1.0"
318 | resolved "https://registry.yarnpkg.com/fined/-/fined-1.1.0.tgz#b37dc844b76a2f5e7081e884f7c0ae344f153476"
319 | dependencies:
320 | expand-tilde "^2.0.2"
321 | is-plain-object "^2.0.3"
322 | object.defaults "^1.1.0"
323 | object.pick "^1.2.0"
324 | parse-filepath "^1.0.1"
325 |
326 | first-chunk-stream@^1.0.0:
327 | version "1.0.0"
328 | resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e"
329 |
330 | flagged-respawn@^1.0.0:
331 | version "1.0.0"
332 | resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.0.tgz#4e79ae9b2eb38bf86b3bb56bf3e0a56aa5fcabd7"
333 |
334 | for-in@^1.0.1, for-in@^1.0.2:
335 | version "1.0.2"
336 | resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
337 |
338 | for-own@^1.0.0:
339 | version "1.0.0"
340 | resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b"
341 | dependencies:
342 | for-in "^1.0.1"
343 |
344 | fragment-cache@^0.2.1:
345 | version "0.2.1"
346 | resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
347 | dependencies:
348 | map-cache "^0.2.2"
349 |
350 | gaze@^0.5.1:
351 | version "0.5.2"
352 | resolved "https://registry.yarnpkg.com/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f"
353 | dependencies:
354 | globule "~0.1.0"
355 |
356 | get-value@^2.0.3, get-value@^2.0.6:
357 | version "2.0.6"
358 | resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
359 |
360 | glob-stream@^3.1.5:
361 | version "3.1.18"
362 | resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b"
363 | dependencies:
364 | glob "^4.3.1"
365 | glob2base "^0.0.12"
366 | minimatch "^2.0.1"
367 | ordered-read-streams "^0.1.0"
368 | through2 "^0.6.1"
369 | unique-stream "^1.0.0"
370 |
371 | glob-watcher@^0.0.6:
372 | version "0.0.6"
373 | resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-0.0.6.tgz#b95b4a8df74b39c83298b0c05c978b4d9a3b710b"
374 | dependencies:
375 | gaze "^0.5.1"
376 |
377 | glob2base@^0.0.12:
378 | version "0.0.12"
379 | resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56"
380 | dependencies:
381 | find-index "^0.1.1"
382 |
383 | glob@^4.3.1:
384 | version "4.5.3"
385 | resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f"
386 | dependencies:
387 | inflight "^1.0.4"
388 | inherits "2"
389 | minimatch "^2.0.1"
390 | once "^1.3.0"
391 |
392 | glob@~3.1.21:
393 | version "3.1.21"
394 | resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd"
395 | dependencies:
396 | graceful-fs "~1.2.0"
397 | inherits "1"
398 | minimatch "~0.2.11"
399 |
400 | global-modules@^1.0.0:
401 | version "1.0.0"
402 | resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
403 | dependencies:
404 | global-prefix "^1.0.1"
405 | is-windows "^1.0.1"
406 | resolve-dir "^1.0.0"
407 |
408 | global-prefix@^1.0.1:
409 | version "1.0.2"
410 | resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
411 | dependencies:
412 | expand-tilde "^2.0.2"
413 | homedir-polyfill "^1.0.1"
414 | ini "^1.3.4"
415 | is-windows "^1.0.1"
416 | which "^1.2.14"
417 |
418 | globule@~0.1.0:
419 | version "0.1.0"
420 | resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5"
421 | dependencies:
422 | glob "~3.1.21"
423 | lodash "~1.0.1"
424 | minimatch "~0.2.11"
425 |
426 | glogg@^1.0.0:
427 | version "1.0.1"
428 | resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.1.tgz#dcf758e44789cc3f3d32c1f3562a3676e6a34810"
429 | dependencies:
430 | sparkles "^1.0.0"
431 |
432 | graceful-fs@^3.0.0:
433 | version "3.0.11"
434 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818"
435 | dependencies:
436 | natives "^1.1.0"
437 |
438 | graceful-fs@~1.2.0:
439 | version "1.2.3"
440 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364"
441 |
442 | gulp-util@^3.0.0:
443 | version "3.0.8"
444 | resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f"
445 | dependencies:
446 | array-differ "^1.0.0"
447 | array-uniq "^1.0.2"
448 | beeper "^1.0.0"
449 | chalk "^1.0.0"
450 | dateformat "^2.0.0"
451 | fancy-log "^1.1.0"
452 | gulplog "^1.0.0"
453 | has-gulplog "^0.1.0"
454 | lodash._reescape "^3.0.0"
455 | lodash._reevaluate "^3.0.0"
456 | lodash._reinterpolate "^3.0.0"
457 | lodash.template "^3.0.0"
458 | minimist "^1.1.0"
459 | multipipe "^0.1.2"
460 | object-assign "^3.0.0"
461 | replace-ext "0.0.1"
462 | through2 "^2.0.0"
463 | vinyl "^0.5.0"
464 |
465 | gulp@^3.9.1:
466 | version "3.9.1"
467 | resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4"
468 | dependencies:
469 | archy "^1.0.0"
470 | chalk "^1.0.0"
471 | deprecated "^0.0.1"
472 | gulp-util "^3.0.0"
473 | interpret "^1.0.0"
474 | liftoff "^2.1.0"
475 | minimist "^1.1.0"
476 | orchestrator "^0.3.0"
477 | pretty-hrtime "^1.0.0"
478 | semver "^4.1.0"
479 | tildify "^1.0.0"
480 | v8flags "^2.0.2"
481 | vinyl-fs "^0.3.0"
482 |
483 | gulplog@^1.0.0:
484 | version "1.0.0"
485 | resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5"
486 | dependencies:
487 | glogg "^1.0.0"
488 |
489 | has-ansi@^2.0.0:
490 | version "2.0.0"
491 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
492 | dependencies:
493 | ansi-regex "^2.0.0"
494 |
495 | has-gulplog@^0.1.0:
496 | version "0.1.0"
497 | resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce"
498 | dependencies:
499 | sparkles "^1.0.0"
500 |
501 | has-value@^0.3.1:
502 | version "0.3.1"
503 | resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f"
504 | dependencies:
505 | get-value "^2.0.3"
506 | has-values "^0.1.4"
507 | isobject "^2.0.0"
508 |
509 | has-value@^1.0.0:
510 | version "1.0.0"
511 | resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177"
512 | dependencies:
513 | get-value "^2.0.6"
514 | has-values "^1.0.0"
515 | isobject "^3.0.0"
516 |
517 | has-values@^0.1.4:
518 | version "0.1.4"
519 | resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771"
520 |
521 | has-values@^1.0.0:
522 | version "1.0.0"
523 | resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f"
524 | dependencies:
525 | is-number "^3.0.0"
526 | kind-of "^4.0.0"
527 |
528 | homedir-polyfill@^1.0.1:
529 | version "1.0.1"
530 | resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc"
531 | dependencies:
532 | parse-passwd "^1.0.0"
533 |
534 | inflight@^1.0.4:
535 | version "1.0.6"
536 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
537 | dependencies:
538 | once "^1.3.0"
539 | wrappy "1"
540 |
541 | inherits@1:
542 | version "1.0.2"
543 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b"
544 |
545 | inherits@2, inherits@~2.0.1, inherits@~2.0.3:
546 | version "2.0.3"
547 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
548 |
549 | ini@^1.3.4:
550 | version "1.3.5"
551 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
552 |
553 | interpret@^1.0.0:
554 | version "1.1.0"
555 | resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
556 |
557 | is-absolute@^1.0.0:
558 | version "1.0.0"
559 | resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576"
560 | dependencies:
561 | is-relative "^1.0.0"
562 | is-windows "^1.0.1"
563 |
564 | is-accessor-descriptor@^0.1.6:
565 | version "0.1.6"
566 | resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
567 | dependencies:
568 | kind-of "^3.0.2"
569 |
570 | is-accessor-descriptor@^1.0.0:
571 | version "1.0.0"
572 | resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656"
573 | dependencies:
574 | kind-of "^6.0.0"
575 |
576 | is-buffer@^1.1.5:
577 | version "1.1.6"
578 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
579 |
580 | is-data-descriptor@^0.1.4:
581 | version "0.1.4"
582 | resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
583 | dependencies:
584 | kind-of "^3.0.2"
585 |
586 | is-data-descriptor@^1.0.0:
587 | version "1.0.0"
588 | resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7"
589 | dependencies:
590 | kind-of "^6.0.0"
591 |
592 | is-descriptor@^0.1.0:
593 | version "0.1.6"
594 | resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca"
595 | dependencies:
596 | is-accessor-descriptor "^0.1.6"
597 | is-data-descriptor "^0.1.4"
598 | kind-of "^5.0.0"
599 |
600 | is-descriptor@^1.0.0:
601 | version "1.0.2"
602 | resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec"
603 | dependencies:
604 | is-accessor-descriptor "^1.0.0"
605 | is-data-descriptor "^1.0.0"
606 | kind-of "^6.0.2"
607 |
608 | is-extendable@^0.1.0, is-extendable@^0.1.1:
609 | version "0.1.1"
610 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
611 |
612 | is-extendable@^1.0.1:
613 | version "1.0.1"
614 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4"
615 | dependencies:
616 | is-plain-object "^2.0.4"
617 |
618 | is-extglob@^2.1.0:
619 | version "2.1.1"
620 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
621 |
622 | is-glob@^3.1.0:
623 | version "3.1.0"
624 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
625 | dependencies:
626 | is-extglob "^2.1.0"
627 |
628 | is-number@^3.0.0:
629 | version "3.0.0"
630 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
631 | dependencies:
632 | kind-of "^3.0.2"
633 |
634 | is-odd@^1.0.0:
635 | version "1.0.0"
636 | resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-1.0.0.tgz#3b8a932eb028b3775c39bb09e91767accdb69088"
637 | dependencies:
638 | is-number "^3.0.0"
639 |
640 | is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
641 | version "2.0.4"
642 | resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
643 | dependencies:
644 | isobject "^3.0.1"
645 |
646 | is-relative@^1.0.0:
647 | version "1.0.0"
648 | resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d"
649 | dependencies:
650 | is-unc-path "^1.0.0"
651 |
652 | is-unc-path@^1.0.0:
653 | version "1.0.0"
654 | resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d"
655 | dependencies:
656 | unc-path-regex "^0.1.2"
657 |
658 | is-utf8@^0.2.0:
659 | version "0.2.1"
660 | resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
661 |
662 | is-windows@^1.0.1:
663 | version "1.0.1"
664 | resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9"
665 |
666 | isarray@0.0.1:
667 | version "0.0.1"
668 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
669 |
670 | isarray@1.0.0, isarray@~1.0.0:
671 | version "1.0.0"
672 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
673 |
674 | isexe@^2.0.0:
675 | version "2.0.0"
676 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
677 |
678 | isobject@^2.0.0:
679 | version "2.1.0"
680 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
681 | dependencies:
682 | isarray "1.0.0"
683 |
684 | isobject@^3.0.0, isobject@^3.0.1:
685 | version "3.0.1"
686 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
687 |
688 | kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.1.0, kind-of@^3.2.0:
689 | version "3.2.2"
690 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
691 | dependencies:
692 | is-buffer "^1.1.5"
693 |
694 | kind-of@^4.0.0:
695 | version "4.0.0"
696 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57"
697 | dependencies:
698 | is-buffer "^1.1.5"
699 |
700 | kind-of@^5.0.0, kind-of@^5.0.2:
701 | version "5.1.0"
702 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d"
703 |
704 | kind-of@^6.0.0, kind-of@^6.0.2:
705 | version "6.0.2"
706 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
707 |
708 | lazy-cache@^2.0.2:
709 | version "2.0.2"
710 | resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264"
711 | dependencies:
712 | set-getter "^0.1.0"
713 |
714 | liftoff@^2.1.0:
715 | version "2.5.0"
716 | resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec"
717 | dependencies:
718 | extend "^3.0.0"
719 | findup-sync "^2.0.0"
720 | fined "^1.0.1"
721 | flagged-respawn "^1.0.0"
722 | is-plain-object "^2.0.4"
723 | object.map "^1.0.0"
724 | rechoir "^0.6.2"
725 | resolve "^1.1.7"
726 |
727 | lodash._basecopy@^3.0.0:
728 | version "3.0.1"
729 | resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
730 |
731 | lodash._basetostring@^3.0.0:
732 | version "3.0.1"
733 | resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5"
734 |
735 | lodash._basevalues@^3.0.0:
736 | version "3.0.0"
737 | resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7"
738 |
739 | lodash._getnative@^3.0.0:
740 | version "3.9.1"
741 | resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
742 |
743 | lodash._isiterateecall@^3.0.0:
744 | version "3.0.9"
745 | resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c"
746 |
747 | lodash._reescape@^3.0.0:
748 | version "3.0.0"
749 | resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a"
750 |
751 | lodash._reevaluate@^3.0.0:
752 | version "3.0.0"
753 | resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed"
754 |
755 | lodash._reinterpolate@^3.0.0:
756 | version "3.0.0"
757 | resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
758 |
759 | lodash._root@^3.0.0:
760 | version "3.0.1"
761 | resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692"
762 |
763 | lodash.escape@^3.0.0:
764 | version "3.2.0"
765 | resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698"
766 | dependencies:
767 | lodash._root "^3.0.0"
768 |
769 | lodash.isarguments@^3.0.0:
770 | version "3.1.0"
771 | resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
772 |
773 | lodash.isarray@^3.0.0:
774 | version "3.0.4"
775 | resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
776 |
777 | lodash.keys@^3.0.0:
778 | version "3.1.2"
779 | resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
780 | dependencies:
781 | lodash._getnative "^3.0.0"
782 | lodash.isarguments "^3.0.0"
783 | lodash.isarray "^3.0.0"
784 |
785 | lodash.restparam@^3.0.0:
786 | version "3.6.1"
787 | resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
788 |
789 | lodash.template@^3.0.0:
790 | version "3.6.2"
791 | resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f"
792 | dependencies:
793 | lodash._basecopy "^3.0.0"
794 | lodash._basetostring "^3.0.0"
795 | lodash._basevalues "^3.0.0"
796 | lodash._isiterateecall "^3.0.0"
797 | lodash._reinterpolate "^3.0.0"
798 | lodash.escape "^3.0.0"
799 | lodash.keys "^3.0.0"
800 | lodash.restparam "^3.0.0"
801 | lodash.templatesettings "^3.0.0"
802 |
803 | lodash.templatesettings@^3.0.0:
804 | version "3.1.1"
805 | resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5"
806 | dependencies:
807 | lodash._reinterpolate "^3.0.0"
808 | lodash.escape "^3.0.0"
809 |
810 | lodash@~1.0.1:
811 | version "1.0.2"
812 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551"
813 |
814 | lru-cache@2:
815 | version "2.7.3"
816 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952"
817 |
818 | make-iterator@^1.0.0:
819 | version "1.0.0"
820 | resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.0.tgz#57bef5dc85d23923ba23767324d8e8f8f3d9694b"
821 | dependencies:
822 | kind-of "^3.1.0"
823 |
824 | map-cache@^0.2.0, map-cache@^0.2.2:
825 | version "0.2.2"
826 | resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
827 |
828 | map-visit@^1.0.0:
829 | version "1.0.0"
830 | resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f"
831 | dependencies:
832 | object-visit "^1.0.0"
833 |
834 | micromatch@^3.0.4:
835 | version "3.1.5"
836 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.5.tgz#d05e168c206472dfbca985bfef4f57797b4cd4ba"
837 | dependencies:
838 | arr-diff "^4.0.0"
839 | array-unique "^0.3.2"
840 | braces "^2.3.0"
841 | define-property "^1.0.0"
842 | extend-shallow "^2.0.1"
843 | extglob "^2.0.2"
844 | fragment-cache "^0.2.1"
845 | kind-of "^6.0.0"
846 | nanomatch "^1.2.5"
847 | object.pick "^1.3.0"
848 | regex-not "^1.0.0"
849 | snapdragon "^0.8.1"
850 | to-regex "^3.0.1"
851 |
852 | minimatch@^2.0.1:
853 | version "2.0.10"
854 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7"
855 | dependencies:
856 | brace-expansion "^1.0.0"
857 |
858 | minimatch@~0.2.11:
859 | version "0.2.14"
860 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a"
861 | dependencies:
862 | lru-cache "2"
863 | sigmund "~1.0.0"
864 |
865 | minimist@0.0.8:
866 | version "0.0.8"
867 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
868 |
869 | minimist@^1.1.0:
870 | version "1.2.0"
871 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
872 |
873 | mixin-deep@^1.2.0:
874 | version "1.3.0"
875 | resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.0.tgz#47a8732ba97799457c8c1eca28f95132d7e8150a"
876 | dependencies:
877 | for-in "^1.0.2"
878 | is-extendable "^1.0.1"
879 |
880 | mkdirp@^0.5.0:
881 | version "0.5.1"
882 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
883 | dependencies:
884 | minimist "0.0.8"
885 |
886 | ms@2.0.0:
887 | version "2.0.0"
888 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
889 |
890 | multipipe@^0.1.2:
891 | version "0.1.2"
892 | resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b"
893 | dependencies:
894 | duplexer2 "0.0.2"
895 |
896 | nanomatch@^1.2.5:
897 | version "1.2.7"
898 | resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.7.tgz#53cd4aa109ff68b7f869591fdc9d10daeeea3e79"
899 | dependencies:
900 | arr-diff "^4.0.0"
901 | array-unique "^0.3.2"
902 | define-property "^1.0.0"
903 | extend-shallow "^2.0.1"
904 | fragment-cache "^0.2.1"
905 | is-odd "^1.0.0"
906 | kind-of "^5.0.2"
907 | object.pick "^1.3.0"
908 | regex-not "^1.0.0"
909 | snapdragon "^0.8.1"
910 | to-regex "^3.0.1"
911 |
912 | natives@^1.1.0:
913 | version "1.1.1"
914 | resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.1.tgz#011acce1f7cbd87f7ba6b3093d6cd9392be1c574"
915 |
916 | object-assign@^3.0.0:
917 | version "3.0.0"
918 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2"
919 |
920 | object-copy@^0.1.0:
921 | version "0.1.0"
922 | resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
923 | dependencies:
924 | copy-descriptor "^0.1.0"
925 | define-property "^0.2.5"
926 | kind-of "^3.0.3"
927 |
928 | object-visit@^1.0.0:
929 | version "1.0.1"
930 | resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb"
931 | dependencies:
932 | isobject "^3.0.0"
933 |
934 | object.defaults@^1.1.0:
935 | version "1.1.0"
936 | resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf"
937 | dependencies:
938 | array-each "^1.0.1"
939 | array-slice "^1.0.0"
940 | for-own "^1.0.0"
941 | isobject "^3.0.0"
942 |
943 | object.map@^1.0.0:
944 | version "1.0.1"
945 | resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37"
946 | dependencies:
947 | for-own "^1.0.0"
948 | make-iterator "^1.0.0"
949 |
950 | object.pick@^1.2.0, object.pick@^1.3.0:
951 | version "1.3.0"
952 | resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
953 | dependencies:
954 | isobject "^3.0.1"
955 |
956 | once@^1.3.0:
957 | version "1.4.0"
958 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
959 | dependencies:
960 | wrappy "1"
961 |
962 | once@~1.3.0:
963 | version "1.3.3"
964 | resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20"
965 | dependencies:
966 | wrappy "1"
967 |
968 | orchestrator@^0.3.0:
969 | version "0.3.8"
970 | resolved "https://registry.yarnpkg.com/orchestrator/-/orchestrator-0.3.8.tgz#14e7e9e2764f7315fbac184e506c7aa6df94ad7e"
971 | dependencies:
972 | end-of-stream "~0.1.5"
973 | sequencify "~0.0.7"
974 | stream-consume "~0.1.0"
975 |
976 | ordered-read-streams@^0.1.0:
977 | version "0.1.0"
978 | resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126"
979 |
980 | os-homedir@^1.0.0:
981 | version "1.0.2"
982 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
983 |
984 | parse-filepath@^1.0.1:
985 | version "1.0.2"
986 | resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891"
987 | dependencies:
988 | is-absolute "^1.0.0"
989 | map-cache "^0.2.0"
990 | path-root "^0.1.1"
991 |
992 | parse-passwd@^1.0.0:
993 | version "1.0.0"
994 | resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
995 |
996 | pascalcase@^0.1.1:
997 | version "0.1.1"
998 | resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
999 |
1000 | path-parse@^1.0.5:
1001 | version "1.0.5"
1002 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
1003 |
1004 | path-root-regex@^0.1.0:
1005 | version "0.1.2"
1006 | resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d"
1007 |
1008 | path-root@^0.1.1:
1009 | version "0.1.1"
1010 | resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7"
1011 | dependencies:
1012 | path-root-regex "^0.1.0"
1013 |
1014 | posix-character-classes@^0.1.0:
1015 | version "0.1.1"
1016 | resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
1017 |
1018 | pretty-hrtime@^1.0.0:
1019 | version "1.0.3"
1020 | resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1"
1021 |
1022 | process-nextick-args@~1.0.6:
1023 | version "1.0.7"
1024 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
1025 |
1026 | "readable-stream@>=1.0.33-1 <1.1.0-0":
1027 | version "1.0.34"
1028 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
1029 | dependencies:
1030 | core-util-is "~1.0.0"
1031 | inherits "~2.0.1"
1032 | isarray "0.0.1"
1033 | string_decoder "~0.10.x"
1034 |
1035 | readable-stream@^2.1.5:
1036 | version "2.3.3"
1037 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
1038 | dependencies:
1039 | core-util-is "~1.0.0"
1040 | inherits "~2.0.3"
1041 | isarray "~1.0.0"
1042 | process-nextick-args "~1.0.6"
1043 | safe-buffer "~5.1.1"
1044 | string_decoder "~1.0.3"
1045 | util-deprecate "~1.0.1"
1046 |
1047 | readable-stream@~1.1.9:
1048 | version "1.1.14"
1049 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
1050 | dependencies:
1051 | core-util-is "~1.0.0"
1052 | inherits "~2.0.1"
1053 | isarray "0.0.1"
1054 | string_decoder "~0.10.x"
1055 |
1056 | rechoir@^0.6.2:
1057 | version "0.6.2"
1058 | resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
1059 | dependencies:
1060 | resolve "^1.1.6"
1061 |
1062 | regex-not@^1.0.0:
1063 | version "1.0.0"
1064 | resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.0.tgz#42f83e39771622df826b02af176525d6a5f157f9"
1065 | dependencies:
1066 | extend-shallow "^2.0.1"
1067 |
1068 | repeat-element@^1.1.2:
1069 | version "1.1.2"
1070 | resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
1071 |
1072 | repeat-string@^1.6.1:
1073 | version "1.6.1"
1074 | resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
1075 |
1076 | replace-ext@0.0.1:
1077 | version "0.0.1"
1078 | resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924"
1079 |
1080 | resolve-dir@^1.0.0, resolve-dir@^1.0.1:
1081 | version "1.0.1"
1082 | resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
1083 | dependencies:
1084 | expand-tilde "^2.0.0"
1085 | global-modules "^1.0.0"
1086 |
1087 | resolve-url@^0.2.1:
1088 | version "0.2.1"
1089 | resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
1090 |
1091 | resolve@^1.1.6, resolve@^1.1.7:
1092 | version "1.5.0"
1093 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
1094 | dependencies:
1095 | path-parse "^1.0.5"
1096 |
1097 | safe-buffer@~5.1.0, safe-buffer@~5.1.1:
1098 | version "5.1.1"
1099 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
1100 |
1101 | semver@^4.1.0:
1102 | version "4.3.6"
1103 | resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da"
1104 |
1105 | sequencify@~0.0.7:
1106 | version "0.0.7"
1107 | resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c"
1108 |
1109 | set-getter@^0.1.0:
1110 | version "0.1.0"
1111 | resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376"
1112 | dependencies:
1113 | to-object-path "^0.3.0"
1114 |
1115 | set-value@^0.4.3:
1116 | version "0.4.3"
1117 | resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1"
1118 | dependencies:
1119 | extend-shallow "^2.0.1"
1120 | is-extendable "^0.1.1"
1121 | is-plain-object "^2.0.1"
1122 | to-object-path "^0.3.0"
1123 |
1124 | set-value@^2.0.0:
1125 | version "2.0.0"
1126 | resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274"
1127 | dependencies:
1128 | extend-shallow "^2.0.1"
1129 | is-extendable "^0.1.1"
1130 | is-plain-object "^2.0.3"
1131 | split-string "^3.0.1"
1132 |
1133 | sigmund@~1.0.0:
1134 | version "1.0.1"
1135 | resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"
1136 |
1137 | snapdragon-node@^2.0.1:
1138 | version "2.1.1"
1139 | resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
1140 | dependencies:
1141 | define-property "^1.0.0"
1142 | isobject "^3.0.0"
1143 | snapdragon-util "^3.0.1"
1144 |
1145 | snapdragon-util@^3.0.1:
1146 | version "3.0.1"
1147 | resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2"
1148 | dependencies:
1149 | kind-of "^3.2.0"
1150 |
1151 | snapdragon@^0.8.1:
1152 | version "0.8.1"
1153 | resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.1.tgz#e12b5487faded3e3dea0ac91e9400bf75b401370"
1154 | dependencies:
1155 | base "^0.11.1"
1156 | debug "^2.2.0"
1157 | define-property "^0.2.5"
1158 | extend-shallow "^2.0.1"
1159 | map-cache "^0.2.2"
1160 | source-map "^0.5.6"
1161 | source-map-resolve "^0.5.0"
1162 | use "^2.0.0"
1163 |
1164 | source-map-resolve@^0.5.0:
1165 | version "0.5.1"
1166 | resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.1.tgz#7ad0f593f2281598e854df80f19aae4b92d7a11a"
1167 | dependencies:
1168 | atob "^2.0.0"
1169 | decode-uri-component "^0.2.0"
1170 | resolve-url "^0.2.1"
1171 | source-map-url "^0.4.0"
1172 | urix "^0.1.0"
1173 |
1174 | source-map-url@^0.4.0:
1175 | version "0.4.0"
1176 | resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
1177 |
1178 | source-map@^0.5.6:
1179 | version "0.5.7"
1180 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
1181 |
1182 | sparkles@^1.0.0:
1183 | version "1.0.0"
1184 | resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3"
1185 |
1186 | split-string@^3.0.1, split-string@^3.0.2:
1187 | version "3.1.0"
1188 | resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
1189 | dependencies:
1190 | extend-shallow "^3.0.0"
1191 |
1192 | static-extend@^0.1.1:
1193 | version "0.1.2"
1194 | resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
1195 | dependencies:
1196 | define-property "^0.2.5"
1197 | object-copy "^0.1.0"
1198 |
1199 | stream-consume@~0.1.0:
1200 | version "0.1.0"
1201 | resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f"
1202 |
1203 | string_decoder@~0.10.x:
1204 | version "0.10.31"
1205 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
1206 |
1207 | string_decoder@~1.0.3:
1208 | version "1.0.3"
1209 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
1210 | dependencies:
1211 | safe-buffer "~5.1.0"
1212 |
1213 | strip-ansi@^3.0.0:
1214 | version "3.0.1"
1215 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
1216 | dependencies:
1217 | ansi-regex "^2.0.0"
1218 |
1219 | strip-bom@^1.0.0:
1220 | version "1.0.0"
1221 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794"
1222 | dependencies:
1223 | first-chunk-stream "^1.0.0"
1224 | is-utf8 "^0.2.0"
1225 |
1226 | supports-color@^2.0.0:
1227 | version "2.0.0"
1228 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
1229 |
1230 | through2@^0.6.1:
1231 | version "0.6.5"
1232 | resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48"
1233 | dependencies:
1234 | readable-stream ">=1.0.33-1 <1.1.0-0"
1235 | xtend ">=4.0.0 <4.1.0-0"
1236 |
1237 | through2@^2.0.0:
1238 | version "2.0.3"
1239 | resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
1240 | dependencies:
1241 | readable-stream "^2.1.5"
1242 | xtend "~4.0.1"
1243 |
1244 | tildify@^1.0.0:
1245 | version "1.2.0"
1246 | resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a"
1247 | dependencies:
1248 | os-homedir "^1.0.0"
1249 |
1250 | time-stamp@^1.0.0:
1251 | version "1.1.0"
1252 | resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3"
1253 |
1254 | to-object-path@^0.3.0:
1255 | version "0.3.0"
1256 | resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
1257 | dependencies:
1258 | kind-of "^3.0.2"
1259 |
1260 | to-regex-range@^2.1.0:
1261 | version "2.1.1"
1262 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38"
1263 | dependencies:
1264 | is-number "^3.0.0"
1265 | repeat-string "^1.6.1"
1266 |
1267 | to-regex@^3.0.1:
1268 | version "3.0.1"
1269 | resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.1.tgz#15358bee4a2c83bd76377ba1dc049d0f18837aae"
1270 | dependencies:
1271 | define-property "^0.2.5"
1272 | extend-shallow "^2.0.1"
1273 | regex-not "^1.0.0"
1274 |
1275 | unc-path-regex@^0.1.2:
1276 | version "0.1.2"
1277 | resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
1278 |
1279 | union-value@^1.0.0:
1280 | version "1.0.0"
1281 | resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4"
1282 | dependencies:
1283 | arr-union "^3.1.0"
1284 | get-value "^2.0.6"
1285 | is-extendable "^0.1.1"
1286 | set-value "^0.4.3"
1287 |
1288 | unique-stream@^1.0.0:
1289 | version "1.0.0"
1290 | resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b"
1291 |
1292 | unset-value@^1.0.0:
1293 | version "1.0.0"
1294 | resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559"
1295 | dependencies:
1296 | has-value "^0.3.1"
1297 | isobject "^3.0.0"
1298 |
1299 | urix@^0.1.0:
1300 | version "0.1.0"
1301 | resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
1302 |
1303 | use@^2.0.0:
1304 | version "2.0.2"
1305 | resolved "https://registry.yarnpkg.com/use/-/use-2.0.2.tgz#ae28a0d72f93bf22422a18a2e379993112dec8e8"
1306 | dependencies:
1307 | define-property "^0.2.5"
1308 | isobject "^3.0.0"
1309 | lazy-cache "^2.0.2"
1310 |
1311 | user-home@^1.1.1:
1312 | version "1.1.1"
1313 | resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190"
1314 |
1315 | util-deprecate@~1.0.1:
1316 | version "1.0.2"
1317 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
1318 |
1319 | v8flags@^2.0.2:
1320 | version "2.1.1"
1321 | resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4"
1322 | dependencies:
1323 | user-home "^1.1.1"
1324 |
1325 | vinyl-fs@^0.3.0:
1326 | version "0.3.14"
1327 | resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6"
1328 | dependencies:
1329 | defaults "^1.0.0"
1330 | glob-stream "^3.1.5"
1331 | glob-watcher "^0.0.6"
1332 | graceful-fs "^3.0.0"
1333 | mkdirp "^0.5.0"
1334 | strip-bom "^1.0.0"
1335 | through2 "^0.6.1"
1336 | vinyl "^0.4.0"
1337 |
1338 | vinyl@^0.4.0:
1339 | version "0.4.6"
1340 | resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847"
1341 | dependencies:
1342 | clone "^0.2.0"
1343 | clone-stats "^0.0.1"
1344 |
1345 | vinyl@^0.5.0:
1346 | version "0.5.3"
1347 | resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde"
1348 | dependencies:
1349 | clone "^1.0.0"
1350 | clone-stats "^0.0.1"
1351 | replace-ext "0.0.1"
1352 |
1353 | which@^1.2.14:
1354 | version "1.3.0"
1355 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
1356 | dependencies:
1357 | isexe "^2.0.0"
1358 |
1359 | wrappy@1:
1360 | version "1.0.2"
1361 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
1362 |
1363 | "xtend@>=4.0.0 <4.1.0-0", xtend@~4.0.1:
1364 | version "4.0.1"
1365 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
1366 |
--------------------------------------------------------------------------------