├── .gitignore ├── async-waituntil-polyfill.js ├── comments.inc.txt ├── comments.json ├── comments.ndjson.txt ├── end.html ├── index.html ├── merge-responses.js ├── package.json ├── parser.js ├── server-render.html ├── server.js ├── start.html ├── streaming-element.js ├── streaming-iframe.js ├── streaming-parser.js ├── streaming-sw.js ├── styles.css ├── sw-stream └── index.html ├── sw.js ├── text-streams.js ├── xhr-innerhtml.js ├── xhr-json.js ├── xhr-ndjson.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /async-waituntil-polyfill.js: -------------------------------------------------------------------------------- 1 | { 2 | const waitUntil = ExtendableEvent.prototype.waitUntil; 3 | const respondWith = FetchEvent.prototype.respondWith; 4 | const promisesMap = new WeakMap(); 5 | 6 | ExtendableEvent.prototype.waitUntil = function(promise) { 7 | const extendableEvent = this; 8 | let promises = promisesMap.get(extendableEvent); 9 | 10 | if (promises) { 11 | promises.push(Promise.resolve(promise)); 12 | return; 13 | } 14 | 15 | promises = [Promise.resolve(promise)]; 16 | promisesMap.set(extendableEvent, promises); 17 | 18 | // call original method 19 | return waitUntil.call(extendableEvent, Promise.resolve().then(function processPromises() { 20 | const len = promises.length; 21 | 22 | // wait for all to settle 23 | return Promise.all(promises.map(p => p.catch(()=>{}))).then(() => { 24 | // have new items been added? If so, wait again 25 | if (promises.length != len) return processPromises(); 26 | // we're done! 27 | promisesMap.delete(extendableEvent); 28 | // reject if one of the promises rejected 29 | return Promise.all(promises); 30 | }); 31 | })); 32 | }; 33 | 34 | FetchEvent.prototype.respondWith = function(promise) { 35 | this.waitUntil(promise); 36 | return respondWith.call(this, promise); 37 | }; 38 | } -------------------------------------------------------------------------------- /end.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Streaming content demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |

Load comments using:

19 | 29 |
30 | 31 | -------------------------------------------------------------------------------- /merge-responses.js: -------------------------------------------------------------------------------- 1 | function mergeResponses(responsePromises) { 2 | const readers = responsePromises.map(p => Promise.resolve(p).then(r => r.body.getReader())); 3 | let fullStreamedResolve; 4 | let fullyStreamedReject; 5 | const fullyStreamed = new Promise((r, rr) => { 6 | fullStreamedResolve = r; 7 | fullyStreamedReject = rr; 8 | }); 9 | 10 | const readable = new ReadableStream({ 11 | pull(controller) { 12 | return readers[0].then(r => r.read()).then(result => { 13 | if (result.done) { 14 | readers.shift(); 15 | 16 | if (!readers[0]) { 17 | controller.close(); 18 | fullStreamedResolve(); 19 | return; 20 | } 21 | return this.pull(controller); 22 | } 23 | 24 | controller.enqueue(result.value); 25 | }).catch(err => { 26 | fullyStreamedReject(err); 27 | throw err; 28 | }); 29 | }, 30 | cancel() { 31 | fullStreamedResolve(); 32 | } 33 | }); 34 | 35 | return responsePromises[0].then(response => ({ 36 | fullyStreamed, 37 | response: new Response(readable, { 38 | headers: response.headers 39 | }) 40 | })); 41 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "browserify": "^14.4.0", 4 | "compressible": "^2.0.9", 5 | "compression": "^1.6.2", 6 | "dom-treeadapter": "RReverser/dom-treeadapter", 7 | "express": "^4.14.0", 8 | "parse5": "^3.0.2" 9 | }, 10 | "scripts": { 11 | "build": "browserify -r dom-treeadapter -r parse5/lib/parser -o parser.js", 12 | "serve": "node server.js" 13 | }, 14 | "private": true, 15 | "repository": "git@github.com:jakearchibald/streaming-html.git", 16 | "author": "Jake Archibald ", 17 | "license": "MIT" 18 | } 19 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const compression = require('compression'); 3 | const compressible = require('compressible'); 4 | const app = express(); 5 | 6 | app.use(compression({ 7 | filter: () => true 8 | })); 9 | app.use('/', express.static('.')); 10 | 11 | app.listen(3000, () => { 12 | console.log('Example app listening on port 3000!'); 13 | }); -------------------------------------------------------------------------------- /start.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Streaming content demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |

Load comments using:

16 | 25 |
26 |

Service worker render

-------------------------------------------------------------------------------- /streaming-element.js: -------------------------------------------------------------------------------- 1 | customElements.define('streaming-element', class StreamingElement extends HTMLElement { 2 | constructor() { 3 | super(); 4 | 5 | const iframeReady = new Promise(resolve => { 6 | const iframe = document.createElement('iframe'); 7 | iframe.style.display = 'none'; 8 | document.body.appendChild(iframe); 9 | 10 | iframe.onload = () => { 11 | iframe.onload = null; 12 | resolve(iframe); 13 | }; 14 | iframe.src = ''; 15 | }); 16 | 17 | async function end() { 18 | const iframe = await iframeReady; 19 | iframe.contentDocument.write(''); 20 | iframe.contentDocument.close(); 21 | iframe.remove(); 22 | } 23 | 24 | this.writable = new WritableStream({ 25 | start: async () => { 26 | const iframe = await iframeReady; 27 | iframe.contentDocument.write(''); 28 | this.appendChild(iframe.contentDocument.querySelector('streaming-element-inner')); 29 | }, 30 | async write(chunk) { 31 | const iframe = await iframeReady; 32 | iframe.contentDocument.write(chunk); 33 | }, 34 | close: end, 35 | abort: end 36 | }); 37 | } 38 | }); 39 | 40 | document.querySelector('.streaming-element').addEventListener('click', async () => { 41 | const content = document.querySelector('.content'); 42 | content.innerHTML = ''; 43 | 44 | const streamingElement = document.createElement('streaming-element'); 45 | content.appendChild(streamingElement); 46 | 47 | const response = await fetch('comments.inc.txt'); 48 | 49 | response.body 50 | .pipeThrough(new TextDecoder()) 51 | .pipeTo(streamingElement.writable); 52 | }); -------------------------------------------------------------------------------- /streaming-iframe.js: -------------------------------------------------------------------------------- 1 | document.querySelector('.streaming-iframe').addEventListener('click', function() { 2 | var content = document.querySelector('.content'); 3 | var iframe = document.createElement('iframe'); 4 | iframe.style.display = 'none'; 5 | document.body.appendChild(iframe); 6 | var iframeReady = new Promise(function(resolve) { 7 | iframe.onload = function() { 8 | iframe.onload = null; 9 | resolve(); 10 | }; 11 | iframe.src = ''; 12 | }); 13 | 14 | content.innerHTML = ''; 15 | iframeReady.then(function() { 16 | var xhr = new XMLHttpRequest(); 17 | var pos = 0; 18 | iframe.contentDocument.write(''); 19 | content.appendChild(iframe.contentDocument.querySelector('streaming-element-inner')); 20 | 21 | xhr.onprogress = function() { 22 | iframe.contentDocument.write(xhr.response.slice(pos)); 23 | pos = xhr.response.length; 24 | }; 25 | 26 | xhr.onload = function() { 27 | iframe.contentDocument.write(''); 28 | iframe.contentDocument.close(); 29 | document.body.removeChild(iframe); 30 | }; 31 | 32 | xhr.responseType = "text"; 33 | xhr.open('GET', 'comments.inc.txt'); 34 | xhr.send(); 35 | }); 36 | }); -------------------------------------------------------------------------------- /streaming-parser.js: -------------------------------------------------------------------------------- 1 | document.querySelector('.streaming-parser').addEventListener('click', async () => { 2 | const Parser = require('parse5/lib/parser'); 3 | const domTreeAdapter = require('dom-treeadapter')(document); 4 | 5 | const fragmentContext = document.querySelector('.content'); 6 | fragmentContext.innerHTML = ''; 7 | 8 | const response = await fetch('comments.inc.txt'); 9 | 10 | const parser = new Parser({ 11 | treeAdapter: domTreeAdapter 12 | }); 13 | 14 | parser._bootstrap(document, fragmentContext); 15 | 16 | if (parser.treeAdapter.getTagName(fragmentContext) === 'template') 17 | parser._pushTmplInsertionMode('IN_TEMPLATE_MODE'); 18 | 19 | parser._initTokenizerForFragmentParsing(); 20 | 21 | for (let el = fragmentContext; el; el = el.parentElement) { 22 | parser.openElements.items.unshift(el); 23 | parser.openElements.stackTop++; 24 | } 25 | 26 | parser.openElements._updateCurrentElement(); 27 | 28 | parser._resetInsertionMode(); 29 | parser._findFormInFragmentContext(); 30 | 31 | response.body 32 | .pipeThrough(new TextDecoder()) 33 | .pipeTo(new WritableStream({ 34 | write(chunk) { 35 | parser.tokenizer.write(chunk, false); 36 | parser._runParsingLoop(null); 37 | }, 38 | close() { 39 | parser.tokenizer.write('', true); 40 | parser._runParsingLoop(null); 41 | } 42 | })); 43 | }); -------------------------------------------------------------------------------- /streaming-sw.js: -------------------------------------------------------------------------------- 1 | new ReadableStream(); 2 | navigator.serviceWorker.register('sw.js', {scope: 'sw-stream'}).then(reg => { 3 | const oldestWorker = reg.active || reg.waiting || reg.installing; 4 | 5 | function checkState() { 6 | if (oldestWorker.state == 'activating' || oldestWorker.state == 'activated') { 7 | document.querySelector('.sw-stream').disabled = false; 8 | } 9 | } 10 | 11 | checkState(); 12 | oldestWorker.addEventListener('statechange', checkState); 13 | }); -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 3 | font-size: 14px; 4 | line-height: 1.5; 5 | color: #333; 6 | background-color: #fff; 7 | } 8 | .content { 9 | position: relative; 10 | margin: 1rem 0; 11 | } 12 | .actions li { 13 | margin: 1rem 0; 14 | } 15 | .actions form { 16 | display: inline; 17 | } 18 | .pl-c { color: rgb(150, 152, 150); } 19 | .pl-c1, .pl-s .pl-v { color: rgb(0, 134, 179); } 20 | .pl-e, .pl-en { color: rgb(121, 93, 163); } 21 | .pl-smi, .pl-s .pl-s1 { color: rgb(51, 51, 51); } 22 | .pl-k { color: rgb(167, 29, 93); } 23 | .pl-s, .pl-pds, .pl-s .pl-pse .pl-s1, .pl-sr, .pl-sr .pl-cce, .pl-sr .pl-sre, .pl-sr .pl-sra { color: rgb(24, 54, 145); } 24 | .pl-v { color: rgb(237, 106, 67); } 25 | .octicon { display: inline-block; vertical-align: text-top; fill: currentcolor; } 26 | a { background-color: transparent; } 27 | b, strong { font-weight: inherit; } 28 | b, strong { font-weight: bolder; } 29 | img { border-style: none; } 30 | svg:not(:root) { overflow: hidden; } 31 | code, kbd, pre, samp { font-family: monospace, monospace; font-size: 1em; } 32 | hr { box-sizing: content-box; height: 0px; overflow: visible; } 33 | button, input, select, textarea { font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; margin: 0px; } 34 | button, input { overflow: visible; } 35 | button, select { text-transform: none; } 36 | button, html [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; } 37 | * { box-sizing: border-box; } 38 | input, select, textarea, button { font-family: inherit; font-size: inherit; line-height: inherit; } 39 | a { color: rgb(64, 120, 192); text-decoration: none; } 40 | strong { font-weight: 600; } 41 | hr, .rule { height: 0px; margin: 15px 0px; overflow: hidden; background: transparent; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-left-color: initial; border-image: initial; border-bottom-style: solid; border-bottom-color: rgb(221, 221, 221); } 42 | hr::before, .rule::before { display: table; content: ""; } 43 | table { border-spacing: 0px; border-collapse: collapse; } 44 | td, th { padding: 0px; } 45 | button { cursor: pointer; } 46 | h1, h2, h3, h4, h5, h6 { margin-top: 0px; margin-bottom: 0px; } 47 | h2 { font-size: 24px; font-weight: 600; } 48 | h3 { font-size: 20px; font-weight: 600; } 49 | h4 { font-size: 16px; font-weight: 600; } 50 | h5 { font-size: 14px; font-weight: 600; } 51 | p { margin-top: 0px; margin-bottom: 10px; } 52 | blockquote { margin: 0px; } 53 | ul, ol { padding-left: 0px; margin-top: 0px; margin-bottom: 0px; } 54 | ol ol, ul ol { list-style-type: lower-roman; } 55 | tt, code { font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 12px; } 56 | pre { margin-top: 0px; margin-bottom: 0px; font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; } 57 | .octicon { vertical-align: text-bottom; } 58 | .btn { position: relative; display: inline-block; padding: 6px 12px; font-size: 14px; font-weight: 600; line-height: 20px; color: rgb(51, 51, 51); white-space: nowrap; vertical-align: middle; cursor: pointer; user-select: none; background-color: rgb(238, 238, 238); background-image: linear-gradient(rgb(252, 252, 252), rgb(238, 238, 238)); border: 1px solid rgb(213, 213, 213); border-radius: 3px; -webkit-appearance: none; } 59 | .btn-primary { color: rgb(255, 255, 255); text-shadow: rgba(0, 0, 0, 0.14902) 0px -1px 0px; background-color: rgb(108, 198, 68); background-image: linear-gradient(rgb(145, 221, 112), rgb(85, 174, 46)); border: 1px solid rgb(90, 173, 53); } 60 | .hidden-text-expander { display: block; } 61 | .hidden-text-expander.inline { position: relative; top: -1px; display: inline-block; margin-left: 5px; line-height: 0; } 62 | .hidden-text-expander a, .ellipsis-expander { display: inline-block; height: 12px; padding: 0px 5px 5px; font-size: 12px; font-weight: bold; line-height: 6px; color: rgb(85, 85, 85); text-decoration: none; vertical-align: middle; background: rgb(221, 221, 221); border: 0px; border-radius: 1px; } 63 | .btn-link { display: inline-block; padding: 0px; font-size: inherit; color: rgb(64, 120, 192); text-decoration: none; white-space: nowrap; cursor: pointer; user-select: none; background-color: transparent; border: 0px; -webkit-appearance: none; } 64 | .btn-link:disabled { color: rgb(118, 118, 118); pointer-events: none; cursor: default; } 65 | input, textarea { font-feature-settings: 'liga' 0; } 66 | .tooltipped { position: relative; } 67 | .tooltipped::after { position: absolute; z-index: 1000000; display: none; padding: 5px 8px; font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 11px; line-height: 1.5; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; -webkit-font-smoothing: subpixel-antialiased; color: rgb(255, 255, 255); text-align: center; text-decoration: none; text-shadow: none; text-transform: none; letter-spacing: normal; word-wrap: break-word; white-space: pre; pointer-events: none; content: attr(aria-label); background: rgba(0, 0, 0, 0.8); border-radius: 3px; opacity: 0; } 68 | .tooltipped::before { position: absolute; z-index: 1000001; display: none; width: 0px; height: 0px; color: rgba(0, 0, 0, 0.8); pointer-events: none; content: ""; border: 5px solid transparent; opacity: 0; } 69 | .tooltipped-s::before, .tooltipped-se::before, .tooltipped-sw::before { top: auto; right: 50%; bottom: -5px; margin-right: -5px; border-bottom-color: rgba(0, 0, 0, 0.8); } 70 | .tooltipped-se::after { right: auto; left: 50%; margin-left: -15px; } 71 | .tooltipped-n::before, .tooltipped-ne::before, .tooltipped-nw::before { top: -5px; right: 50%; bottom: auto; margin-right: -5px; border-top-color: rgba(0, 0, 0, 0.8); } 72 | .tooltipped-s::after, .tooltipped-n::after { transform: translateX(50%); } 73 | .tooltipped-multiline::after { width: max-content; max-width: 250px; word-break: break-word; word-wrap: normal; white-space: pre-line; border-collapse: separate; } 74 | .float-right { float: right !important; } 75 | .d-block { display: block !important; } 76 | .d-none { display: none !important; } 77 | .mr-1 { margin-right: 4px !important; } 78 | .text-bold { font-weight: 600 !important; } 79 | .avatar { display: inline-block; overflow: hidden; line-height: 1; vertical-align: middle; border-radius: 3px; } 80 | .avatar-small { border-radius: 2px; } 81 | .markdown-body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 16px; line-height: 1.5; word-wrap: break-word; } 82 | .markdown-body::before { display: table; content: ""; } 83 | .markdown-body::after { display: table; clear: both; content: ""; } 84 | .markdown-body > :first-child { margin-top: 0px !important; } 85 | .markdown-body > :last-child { margin-bottom: 0px !important; } 86 | .markdown-body p, .markdown-body blockquote, .markdown-body ul, .markdown-body ol, .markdown-body dl, .markdown-body table, .markdown-body pre { margin-top: 0px; margin-bottom: 16px; } 87 | .markdown-body hr { height: 0.25em; padding: 0px; margin: 24px 0px; background-color: rgb(231, 231, 231); border: 0px; } 88 | .markdown-body blockquote { padding: 0px 1em; color: rgb(119, 119, 119); border-left: 0.25em solid rgb(221, 221, 221); } 89 | .markdown-body blockquote > :first-child { margin-top: 0px; } 90 | .markdown-body blockquote > :last-child { margin-bottom: 0px; } 91 | .markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { margin-top: 24px; margin-bottom: 16px; font-weight: 600; line-height: 1.25; } 92 | .markdown-body h1 tt, .markdown-body h1 code, .markdown-body h2 tt, .markdown-body h2 code, .markdown-body h3 tt, .markdown-body h3 code, .markdown-body h4 tt, .markdown-body h4 code, .markdown-body h5 tt, .markdown-body h5 code, .markdown-body h6 tt, .markdown-body h6 code { font-size: inherit; } 93 | .markdown-body h2 { padding-bottom: 0.3em; font-size: 1.5em; border-bottom: 1px solid rgb(238, 238, 238); } 94 | .markdown-body h3 { font-size: 1.25em; } 95 | .markdown-body h4 { font-size: 1em; } 96 | .markdown-body h5 { font-size: 0.875em; } 97 | .markdown-body ul, .markdown-body ol { padding-left: 2em; } 98 | .markdown-body ul ul, .markdown-body ul ol, .markdown-body ol ol, .markdown-body ol ul { margin-top: 0px; margin-bottom: 0px; } 99 | .markdown-body li + li { margin-top: 0.25em; } 100 | .markdown-body code, .markdown-body tt { padding: 0.2em 0px; margin: 0px; font-size: 85%; background-color: rgba(0, 0, 0, 0.0392157); border-radius: 3px; } 101 | .markdown-body code::before, .markdown-body code::after, .markdown-body tt::before, .markdown-body tt::after { letter-spacing: -0.2em; content: " "; } 102 | .markdown-body pre { word-wrap: normal; } 103 | .markdown-body pre > code { padding: 0px; margin: 0px; font-size: 100%; word-break: normal; white-space: pre; background: transparent; border: 0px; } 104 | .markdown-body .highlight { margin-bottom: 16px; } 105 | .markdown-body .highlight pre { margin-bottom: 0px; word-break: normal; } 106 | .markdown-body .highlight pre, .markdown-body pre { padding: 16px; overflow: auto; font-size: 85%; line-height: 1.45; background-color: rgb(247, 247, 247); border-radius: 3px; } 107 | .markdown-body pre code, .markdown-body pre tt { display: inline; padding: 0px; margin: 0px; overflow: visible; line-height: inherit; word-wrap: normal; background-color: transparent; border: 0px; } 108 | .markdown-body pre code::before, .markdown-body pre code::after, .markdown-body pre tt::before, .markdown-body pre tt::after { content: normal; } 109 | .state { display: inline-block; padding: 4px 8px; font-weight: 600; line-height: 20px; color: rgb(255, 255, 255); text-align: center; background-color: rgb(153, 153, 153); border-radius: 3px; } 110 | .state-open, .state-proposed, .state-reopened { background-color: rgb(108, 198, 68); } 111 | .state-closed { background-color: rgb(189, 44, 0); } 112 | .comment-body { width: 100%; padding: 15px; overflow: visible; font-size: 14px; } 113 | .comment-body .highlight { background-color: transparent; overflow: visible !important; } 114 | .commit-desc { display: none; } 115 | .commit-desc pre { max-width: 700px; margin-top: 10px; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 11px; line-height: 1.45; color: rgb(89, 96, 99); white-space: pre-wrap; } 116 | .timeline-commits { width: 100%; margin-top: 5px; border-collapse: separate; } 117 | .timeline-commits td { padding-top: 4px; padding-right: 8px; padding-bottom: 4px; font-size: 12px; line-height: 16px; vertical-align: top; background-color: transparent; } 118 | .discussion-item .timeline-commits .commit-author { display: none; } 119 | .timeline-commits .commit-gravatar { width: 16px; padding-left: 10px; } 120 | .timeline-commits .commit-author { width: 200px; padding-right: 20px; white-space: nowrap; } 121 | .timeline-commits .author { font-weight: bold; color: rgb(85, 85, 85); } 122 | .timeline-commits .commit-message { max-width: 550px; min-height: 0px; } 123 | .timeline-commits .commit-message > code a { color: rgb(85, 85, 85); } 124 | .timeline-commits .commit-desc pre { overflow: visible; color: rgb(118, 118, 118); } 125 | .timeline-commits .hidden-text-expander { margin-top: 3px; margin-left: 0px; vertical-align: top; } 126 | .timeline-commits .hidden-text-expander .ellipsis-expander { height: 13px; background-color: rgb(238, 238, 238); } 127 | .timeline-commits .commit-sig-status { width: 60px; padding-right: 4px; text-align: right; } 128 | .timeline-commits .commit-ci-status { width: 16px; padding-right: 4px; } 129 | .timeline-commits .commit-meta { width: 50px; text-align: right; } 130 | .commit-icon { display: table-cell; width: 16px; color: rgb(204, 204, 204); } 131 | .commit-icon .octicon { background-color: rgb(255, 255, 255); } 132 | .commit-id { color: rgb(187, 187, 187); } 133 | .discussion-timeline::before { position: absolute; top: 0px; bottom: 0px; left: 79px; z-index: -1; display: block; width: 2px; content: ""; background-color: rgb(243, 243, 243); } 134 | .timeline-comment-wrapper > .timeline-comment::after, .timeline-comment-wrapper > .timeline-comment::before, .timeline-new-comment .timeline-comment::after, .timeline-new-comment .timeline-comment::before { position: absolute; top: 11px; right: 100%; left: -16px; display: block; width: 0px; height: 0px; pointer-events: none; content: " "; border-color: transparent; border-style: solid solid outset; } 135 | .timeline-comment-wrapper > .timeline-comment::before, .timeline-new-comment .timeline-comment::before { border-width: 8px; border-right-color: rgb(221, 221, 221); } 136 | .timeline-comment-wrapper { position: relative; padding-left: 60px; margin-top: 15px; margin-bottom: 15px; border-top: 2px solid rgb(255, 255, 255); border-bottom: 2px solid rgb(255, 255, 255); } 137 | .timeline-comment-wrapper:first-child { margin-top: 0px; } 138 | .timeline-comment-avatar { float: left; margin-left: -60px; border-radius: 3px; } 139 | .timeline-comment { position: relative; background-color: rgb(255, 255, 255); border: 1px solid rgb(221, 221, 221); border-radius: 3px; } 140 | .timeline-comment-header { padding-right: 15px; padding-left: 15px; color: rgb(118, 118, 118); background-color: rgb(247, 247, 247); border-bottom: 1px solid rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; } 141 | .timeline-comment-header .author { color: rgb(85, 85, 85); } 142 | .timeline-comment-header .timestamp { color: inherit; white-space: nowrap; } 143 | .timeline-comment-header .timestamp.timestamp-edited { cursor: default; } 144 | .timeline-comment-label { float: right; padding: 2px 5px; margin: 8px 0px 0px 10px; font-size: 12px; cursor: default; border: 1px solid rgba(0, 0, 0, 0.0980392); border-radius: 3px; } 145 | .timeline-comment-header-text { max-width: 78%; padding-top: 10px; padding-bottom: 10px; } 146 | .timeline-comment-actions { float: right; margin-right: -5px; margin-left: 10px; } 147 | .discussion-item-ref .commit-gravatar { padding-right: 5px; padding-left: 2px; } 148 | .discussion-item-ref .state { padding: 1px 5px; margin-left: 8px; font-size: 12px; } 149 | .discussion-item-ref .state .octicon { width: 1em; font-size: 14px; } 150 | .discussion-item + .discussion-item, .discussion-item-review + .discussion-item { padding-top: 15px; border-top: 1px solid rgb(245, 245, 245); } 151 | .discussion-item { position: relative; padding-left: 25px; margin: 15px 0px 15px 79px; } 152 | .discussion-item .author { font-weight: 600; color: rgb(85, 85, 85); } 153 | .discussion-item .timestamp { color: inherit; white-space: nowrap; } 154 | .discussion-item-icon { float: left; width: 32px; height: 32px; margin-top: -7px; margin-left: -40px; line-height: 28px; color: rgb(118, 118, 118); text-align: center; background-color: rgb(243, 243, 243); border: 2px solid rgb(255, 255, 255); border-radius: 50%; } 155 | .discussion-item-icon .octicon-pencil { font-size: 14px; } 156 | .discussion-item-header { min-height: 30px; padding-top: 5px; padding-bottom: 5px; line-height: 20px; color: rgb(118, 118, 118); word-wrap: break-word; } 157 | .discussion-item-header .avatar { width: 16px; height: 16px; } 158 | .discussion-item-header:last-child { padding-bottom: 0px; } 159 | .discussion-item-entity { font-weight: 600; color: rgb(51, 51, 51); } 160 | .discussion-item-ref-title .issue-num { font-weight: normal; color: rgb(118, 118, 118); } 161 | .discussion-item-ref-title .title-link { color: rgb(51, 51, 51); } 162 | .discussion-item-rollup-ref .state { margin-top: 2px; } 163 | .discussion-item .renamed-was, .discussion-item .renamed-is { font-weight: bold; color: rgb(51, 51, 51); } 164 | .discussion-timeline-actions { background-color: rgb(255, 255, 255); border-top: 2px solid rgb(243, 243, 243); } 165 | g-emoji { font-family: "Apple Color Emoji", "Segoe UI", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 18px; font-weight: normal; line-height: 20px; vertical-align: middle; } 166 | html.emoji-size-boost g-emoji { margin-right: 3px; } 167 | .user-mention, .team-mention { font-weight: 600; color: rgb(51, 51, 51); white-space: nowrap; } 168 | .comment-reactions::before { display: table; content: ""; } 169 | .comment-reactions::after { display: table; clear: both; content: ""; } 170 | .comment-reactions.has-reactions { border-top: 1px solid rgb(229, 229, 229); } 171 | .reaction-summary-item { float: left; padding: 9px 15px 7px; line-height: 18px; border-right: 1px solid rgb(229, 229, 229); } 172 | .comment-reactions-options .reaction-summary-item:first-child { border-bottom-left-radius: 2px; } 173 | .signed-out-comment { padding: 15px; margin-top: 15px; margin-left: 64px; background-color: rgb(255, 249, 234); border: 1px solid rgb(223, 216, 194); border-radius: 3px; } 174 | .signed-out-comment .btn { margin-right: 3px; vertical-align: baseline; } 175 | hr { border-bottom-color: rgb(238, 238, 238); } 176 | .btn-link { font-family: inherit; } 177 | .text-bold { font-weight: 500 !important; } -------------------------------------------------------------------------------- /sw-stream/index.html: -------------------------------------------------------------------------------- 1 | 2 |

If you can see this, the service worker wasn't installed.

3 |

Go back.

-------------------------------------------------------------------------------- /sw.js: -------------------------------------------------------------------------------- 1 | importScripts( 2 | 'async-waituntil-polyfill.js', 3 | 'merge-responses.js' 4 | ); 5 | 6 | addEventListener('install', event => { 7 | event.waitUntil( 8 | caches.open('streaming-sw-test-static-v1').then(cache => 9 | cache.addAll([ 10 | 'start.html', 11 | 'end.html' 12 | ]) 13 | ) 14 | ); 15 | }); 16 | 17 | addEventListener('fetch', event => { 18 | const url = new URL(event.request.url); 19 | 20 | if (!url.pathname.endsWith('sw-stream')) return; 21 | 22 | const parts = [ 23 | caches.match('start.html'), 24 | fetch('comments.inc.txt'), 25 | caches.match('end.html') 26 | ]; 27 | 28 | event.respondWith( 29 | mergeResponses(parts).then(({fullyStreamed, response}) => { 30 | event.waitUntil(fullyStreamed); 31 | return response; 32 | }) 33 | ); 34 | }); -------------------------------------------------------------------------------- /text-streams.js: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Polyfill for Stream support for TextEncoder and TextDecoder 16 | 17 | (function() { 18 | 'use strict'; 19 | 20 | const real = { 21 | TextEncoder: self.TextEncoder, 22 | TextDecoder: self.TextDecoder 23 | }; 24 | 25 | class TextEncoder { 26 | constructor() { 27 | this._realEncoder = new real.TextEncoder(); 28 | this._transform = undefined; 29 | } 30 | 31 | encode(input = '') { 32 | if (this._transform !== undefined) { 33 | // Do not permit encode() if readable or writable are locked. 34 | this._transform.readable.getReader().releaseLock(); 35 | this._transform.writable.getWriter().releaseLock(); 36 | } 37 | return this._realEncoder.encode(input); 38 | } 39 | 40 | get readable() { 41 | if (this._transform === undefined) { 42 | createEncodeTransform(this); 43 | } 44 | return this._transform.readable; 45 | } 46 | 47 | get writable() { 48 | if (this._transform === undefined) { 49 | createEncodeTransform(this); 50 | } 51 | return this._transform.writable; 52 | } 53 | } 54 | 55 | class TextDecoder { 56 | constructor(label = 'utf-8', options = {}) { 57 | this._realDecoder = new real.TextDecoder(label, options); 58 | this._transform = undefined; 59 | } 60 | 61 | get encoding() { 62 | return this._realDecoder.encoding; 63 | } 64 | 65 | get fatal() { 66 | return this._realDecoder.fatal; 67 | } 68 | 69 | get ignoreBOM() { 70 | return this._realDecoder.ignoreBOM; 71 | } 72 | 73 | decode(input = '', options = {}) { 74 | if (this._transform !== undefined) { 75 | // Do not permit encode() if readable or writable are locked. 76 | this._transform.readable.getReader().releaseLock(); 77 | this._transform.writable.getWriter().releaseLock(); 78 | } 79 | return this._realDecoder.decode(input, options); 80 | } 81 | 82 | get readable() { 83 | if (this._transform === undefined) { 84 | createDecodeTransform(this); 85 | } 86 | return this._transform.readable; 87 | } 88 | 89 | get writable() { 90 | if (this._transform === undefined) { 91 | createDecodeTransform(this); 92 | } 93 | return this._transform.writable; 94 | } 95 | } 96 | 97 | class TextEncodeTransformer { 98 | constructor(encoder) { 99 | this._encoder = encoder; 100 | } 101 | 102 | transform(chunk, controller) { 103 | controller.enqueue(this._encoder.encode(chunk)); 104 | } 105 | } 106 | 107 | function createEncodeTransform(textEncoder) { 108 | textEncoder._transform = new TransformStream(new TextEncodeTransformer(textEncoder._realEncoder)); 109 | } 110 | 111 | class TextDecodeTransformer { 112 | constructor(decoder) { 113 | this._decoder = decoder; 114 | } 115 | 116 | transform(chunk, controller) { 117 | controller.enqueue(this._decoder.decode(chunk, {stream: true})); 118 | } 119 | 120 | flush(controller) { 121 | // If {fatal: false} in options (the default), then the final call to 122 | // decode() can produce extra output (usually the unicode replacement 123 | // character 0xFFFD). When fatal is true, this call is just used for its 124 | // side-effect of throwing a TypeError exception if the input is incomplete. 125 | var output = this._decoder.decode(); 126 | if (output !== '') { 127 | controller.enqueue(output); 128 | } 129 | controller.close(); 130 | } 131 | } 132 | 133 | function createDecodeTransform(textDecoder) { 134 | textDecoder._transform = new TransformStream( 135 | new TextDecodeTransformer(textDecoder._realDecoder)); 136 | } 137 | 138 | self['TextEncoder'] = TextEncoder; 139 | self['TextDecoder'] = TextDecoder; 140 | 141 | })(); 142 | 143 | (function() { 144 | 'use strict'; 145 | 146 | if ('TransformStream' in self) { 147 | return; 148 | } 149 | 150 | // Methods on the transform stream controller object 151 | 152 | function TransformStreamCloseReadable(transformStream) { 153 | // console.log('TransformStreamCloseReadable()'); 154 | 155 | if (transformStream._errored === true) { 156 | throw new TypeError('TransformStream is already errored'); 157 | } 158 | 159 | if (transformStream._readableClosed === true) { 160 | throw new TypeError('Readable side is already closed'); 161 | } 162 | 163 | TransformStreamCloseReadableInternal(transformStream); 164 | } 165 | 166 | function TransformStreamEnqueueToReadable(transformStream, chunk) { 167 | // console.log('TransformStreamEnqueueToReadable()'); 168 | 169 | if (transformStream._errored === true) { 170 | throw new TypeError('TransformStream is already errored'); 171 | } 172 | 173 | if (transformStream._readableClosed === true) { 174 | throw new TypeError('Readable side is already closed'); 175 | } 176 | 177 | // We throttle transformer.transform invocation based on the backpressure of the ReadableStream, but we still 178 | // accept TransformStreamEnqueueToReadable() calls. 179 | 180 | const controller = transformStream._readableController; 181 | 182 | try { 183 | ReadableStreamDefaultControllerEnqueue(controller, chunk); 184 | } catch (e) { 185 | // This happens when readableStrategy.size() throws. 186 | // The ReadableStream has already errored itself. 187 | transformStream._readableClosed = true; 188 | TransformStreamErrorIfNeeded(transformStream, e); 189 | 190 | throw transformStream._storedError; 191 | } 192 | 193 | const desiredSize = ReadableStreamDefaultControllerGetDesiredSize(controller); 194 | const maybeBackpressure = desiredSize <= 0; 195 | 196 | if (maybeBackpressure === true && transformStream._backpressure === false) { 197 | // This allows pull() again. When desiredSize is 0, it's possible that a pull() will happen immediately (but 198 | // asynchronously) after this because of pending read()s and set _backpressure back to false. 199 | // 200 | // If pull() could be called from inside enqueue(), then this logic would be wrong. This cannot happen 201 | // because there is always a promise pending from start() or pull() when _backpressure is false. 202 | TransformStreamSetBackpressure(transformStream, true); 203 | } 204 | } 205 | 206 | function TransformStreamError(transformStream, e) { 207 | if (transformStream._errored === true) { 208 | throw new TypeError('TransformStream is already errored'); 209 | } 210 | 211 | TransformStreamErrorInternal(transformStream, e); 212 | } 213 | 214 | // Abstract operations. 215 | 216 | function TransformStreamCloseReadableInternal(transformStream) { 217 | assert(transformStream._errored === false); 218 | assert(transformStream._readableClosed === false); 219 | 220 | try { 221 | ReadableStreamDefaultControllerClose(transformStream._readableController); 222 | } catch (e) { 223 | assert(false); 224 | } 225 | 226 | transformStream._readableClosed = true; 227 | } 228 | 229 | function TransformStreamErrorIfNeeded(transformStream, e) { 230 | if (transformStream._errored === false) { 231 | TransformStreamErrorInternal(transformStream, e); 232 | } 233 | } 234 | 235 | function TransformStreamErrorInternal(transformStream, e) { 236 | // console.log('TransformStreamErrorInternal()'); 237 | 238 | assert(transformStream._errored === false); 239 | 240 | transformStream._errored = true; 241 | transformStream._storedError = e; 242 | 243 | if (transformStream._writableDone === false) { 244 | WritableStreamDefaultControllerError(transformStream._writableController, e); 245 | } 246 | if (transformStream._readableClosed === false) { 247 | ReadableStreamDefaultControllerError(transformStream._readableController, e); 248 | } 249 | } 250 | 251 | // Used for preventing the next write() call on TransformStreamSink until there 252 | // is no longer backpressure. 253 | function TransformStreamReadableReadyPromise(transformStream) { 254 | assert(transformStream._backpressureChangePromise !== undefined, 255 | '_backpressureChangePromise should have been initialized'); 256 | 257 | if (transformStream._backpressure === false) { 258 | return Promise.resolve(); 259 | } 260 | 261 | assert(transformStream._backpressure === true, '_backpressure should have been initialized'); 262 | 263 | return transformStream._backpressureChangePromise; 264 | } 265 | 266 | function TransformStreamSetBackpressure(transformStream, backpressure) { 267 | // console.log(`TransformStreamSetBackpressure(${backpressure})`); 268 | 269 | // Passes also when called during construction. 270 | assert(transformStream._backpressure !== backpressure, 271 | 'TransformStreamSetBackpressure() should be called only when backpressure is changed'); 272 | 273 | if (transformStream._backpressureChangePromise !== undefined) { 274 | // The fulfillment value is just for a sanity check. 275 | transformStream._backpressureChangePromise_resolve(backpressure); 276 | } 277 | 278 | transformStream._backpressureChangePromise = new Promise(resolve => { 279 | transformStream._backpressureChangePromise_resolve = resolve; 280 | }); 281 | 282 | transformStream._backpressureChangePromise.then(resolution => { 283 | assert(resolution !== backpressure, 284 | '_backpressureChangePromise should be fulfilled only when backpressure is changed'); 285 | }); 286 | 287 | transformStream._backpressure = backpressure; 288 | } 289 | 290 | function TransformStreamDefaultTransform(chunk, transformStreamController) { 291 | const transformStream = transformStreamController._controlledTransformStream; 292 | TransformStreamEnqueueToReadable(transformStream, chunk); 293 | return Promise.resolve(); 294 | } 295 | 296 | function TransformStreamTransform(transformStream, chunk) { 297 | // console.log('TransformStreamTransform()'); 298 | 299 | assert(transformStream._errored === false); 300 | assert(transformStream._transforming === false); 301 | assert(transformStream._backpressure === false); 302 | 303 | transformStream._transforming = true; 304 | 305 | const transformer = transformStream._transformer; 306 | const controller = transformStream._transformStreamController; 307 | 308 | const transformPromise = PromiseInvokeOrPerformFallback(transformer, 'transform', [chunk, controller], 309 | TransformStreamDefaultTransform, [chunk, controller]); 310 | 311 | return transformPromise.then( 312 | () => { 313 | transformStream._transforming = false; 314 | 315 | return TransformStreamReadableReadyPromise(transformStream); 316 | }, 317 | e => { 318 | TransformStreamErrorIfNeeded(transformStream, e); 319 | return Promise.reject(e); 320 | }); 321 | } 322 | 323 | function IsTransformStreamDefaultController(x) { 324 | if (!typeIsObject(x)) { 325 | return false; 326 | } 327 | 328 | if (!Object.prototype.hasOwnProperty.call(x, '_controlledTransformStream')) { 329 | return false; 330 | } 331 | 332 | return true; 333 | } 334 | 335 | function IsTransformStream(x) { 336 | if (!typeIsObject(x)) { 337 | return false; 338 | } 339 | 340 | if (!Object.prototype.hasOwnProperty.call(x, '_transformStreamController')) { 341 | return false; 342 | } 343 | 344 | return true; 345 | } 346 | 347 | class TransformStreamSink { 348 | constructor(transformStream, startPromise) { 349 | this._transformStream = transformStream; 350 | this._startPromise = startPromise; 351 | } 352 | 353 | start(c) { 354 | const transformStream = this._transformStream; 355 | 356 | transformStream._writableController = c; 357 | 358 | return this._startPromise.then(() => TransformStreamReadableReadyPromise(transformStream)); 359 | } 360 | 361 | write(chunk) { 362 | // console.log('TransformStreamSink.write()'); 363 | 364 | const transformStream = this._transformStream; 365 | 366 | return TransformStreamTransform(transformStream, chunk); 367 | } 368 | 369 | abort() { 370 | const transformStream = this._transformStream; 371 | transformStream._writableDone = true; 372 | TransformStreamErrorInternal(transformStream, new TypeError('Writable side aborted')); 373 | } 374 | 375 | close() { 376 | // console.log('TransformStreamSink.close()'); 377 | 378 | const transformStream = this._transformStream; 379 | 380 | assert(transformStream._transforming === false); 381 | 382 | transformStream._writableDone = true; 383 | 384 | const flushPromise = PromiseInvokeOrNoop(transformStream._transformer, 385 | 'flush', [transformStream._transformStreamController]); 386 | // Return a promise that is fulfilled with undefined on success. 387 | return flushPromise.then(() => { 388 | if (transformStream._errored === true) { 389 | return Promise.reject(transformStream._storedError); 390 | } 391 | if (transformStream._readableClosed === false) { 392 | TransformStreamCloseReadableInternal(transformStream); 393 | } 394 | return Promise.resolve(); 395 | }).catch(r => { 396 | TransformStreamErrorIfNeeded(transformStream, r); 397 | return Promise.reject(transformStream._storedError); 398 | }); 399 | } 400 | } 401 | 402 | class TransformStreamSource { 403 | constructor(transformStream, startPromise) { 404 | this._transformStream = transformStream; 405 | this._startPromise = startPromise; 406 | } 407 | 408 | start(c) { 409 | const transformStream = this._transformStream; 410 | 411 | transformStream._readableController = c; 412 | 413 | return this._startPromise.then(() => { 414 | // Prevent the first pull() call until there is backpressure. 415 | 416 | assert(transformStream._backpressureChangePromise !== undefined, 417 | '_backpressureChangePromise should have been initialized'); 418 | 419 | if (transformStream._backpressure === true) { 420 | return Promise.resolve(); 421 | } 422 | 423 | assert(transformStream._backpressure === false, '_backpressure should have been initialized'); 424 | 425 | return transformStream._backpressureChangePromise; 426 | }); 427 | } 428 | 429 | pull() { 430 | // console.log('TransformStreamSource.pull()'); 431 | 432 | const transformStream = this._transformStream; 433 | 434 | // Invariant. Enforced by the promises returned by start() and pull(). 435 | assert(transformStream._backpressure === true, 'pull() should be never called while _backpressure is false'); 436 | 437 | assert(transformStream._backpressureChangePromise !== undefined, 438 | '_backpressureChangePromise should have been initialized'); 439 | 440 | TransformStreamSetBackpressure(transformStream, false); 441 | 442 | // Prevent the next pull() call until there is backpressure. 443 | return transformStream._backpressureChangePromise; 444 | } 445 | 446 | cancel() { 447 | const transformStream = this._transformStream; 448 | transformStream._readableClosed = true; 449 | TransformStreamErrorInternal(transformStream, new TypeError('Readable side canceled')); 450 | } 451 | } 452 | 453 | class TransformStreamDefaultController { 454 | constructor(transformStream) { 455 | if (IsTransformStream(transformStream) === false) { 456 | throw new TypeError('TransformStreamDefaultController can only be ' + 457 | 'constructed with a TransformStream instance'); 458 | } 459 | 460 | if (transformStream._transformStreamController !== undefined) { 461 | throw new TypeError('TransformStreamDefaultController instances can ' + 462 | 'only be created by the TransformStream constructor'); 463 | } 464 | 465 | this._controlledTransformStream = transformStream; 466 | } 467 | 468 | get desiredSize() { 469 | if (IsTransformStreamDefaultController(this) === false) { 470 | throw defaultControllerBrandCheckException('desiredSize'); 471 | } 472 | 473 | const transformStream = this._controlledTransformStream; 474 | const readableController = transformStream._readableController; 475 | 476 | return ReadableStreamDefaultControllerGetDesiredSize(readableController); 477 | } 478 | 479 | enqueue(chunk) { 480 | if (IsTransformStreamDefaultController(this) === false) { 481 | throw defaultControllerBrandCheckException('enqueue'); 482 | } 483 | 484 | TransformStreamEnqueueToReadable(this._controlledTransformStream, chunk); 485 | } 486 | 487 | close() { 488 | if (IsTransformStreamDefaultController(this) === false) { 489 | throw defaultControllerBrandCheckException('close'); 490 | } 491 | 492 | TransformStreamCloseReadable(this._controlledTransformStream); 493 | } 494 | 495 | error(reason) { 496 | if (IsTransformStreamDefaultController(this) === false) { 497 | throw defaultControllerBrandCheckException('error'); 498 | } 499 | 500 | TransformStreamError(this._controlledTransformStream, reason); 501 | } 502 | } 503 | 504 | class TransformStream { 505 | constructor(transformer = {}) { 506 | this._transformer = transformer; 507 | const { readableStrategy, writableStrategy } = transformer; 508 | 509 | this._transforming = false; 510 | this._errored = false; 511 | this._storedError = undefined; 512 | 513 | this._writableController = undefined; 514 | this._readableController = undefined; 515 | this._transformStreamController = undefined; 516 | 517 | this._writableDone = false; 518 | this._readableClosed = false; 519 | 520 | this._backpressure = undefined; 521 | this._backpressureChangePromise = undefined; 522 | this._backpressureChangePromise_resolve = undefined; 523 | 524 | this._transformStreamController = new TransformStreamDefaultController(this); 525 | 526 | let startPromise_resolve; 527 | const startPromise = new Promise(resolve => { 528 | startPromise_resolve = resolve; 529 | }); 530 | 531 | const source = new TransformStreamSource(this, startPromise); 532 | 533 | this._readable = new ReadableStream(source, readableStrategy); 534 | 535 | const sink = new TransformStreamSink(this, startPromise); 536 | 537 | this._writable = new WritableStream(sink, writableStrategy); 538 | 539 | assert(this._writableController !== undefined); 540 | assert(this._readableController !== undefined); 541 | 542 | const desiredSize = ReadableStreamDefaultControllerGetDesiredSize(this._readableController); 543 | // Set _backpressure based on desiredSize. As there is no read() at this point, we can just interpret 544 | // desiredSize being non-positive as backpressure. 545 | TransformStreamSetBackpressure(this, desiredSize <= 0); 546 | 547 | const transformStream = this; 548 | const startResult = InvokeOrNoop(transformer, 'start', 549 | [transformStream._transformStreamController]); 550 | startPromise_resolve(startResult); 551 | startPromise.catch(e => { 552 | // The underlyingSink and underlyingSource will error the readable and writable ends on their own. 553 | if (transformStream._errored === false) { 554 | transformStream._errored = true; 555 | transformStream._storedError = e; 556 | } 557 | }); 558 | } 559 | 560 | get readable() { 561 | if (IsTransformStream(this) === false) { 562 | throw streamBrandCheckException('readable'); 563 | } 564 | 565 | return this._readable; 566 | } 567 | 568 | get writable() { 569 | if (IsTransformStream(this) === false) { 570 | throw streamBrandCheckException('writable'); 571 | } 572 | 573 | return this._writable; 574 | } 575 | } 576 | 577 | // Helper functions for the TransformStreamDefaultController. 578 | 579 | function defaultControllerBrandCheckException(name) { 580 | return new TypeError( 581 | `TransformStreamDefaultController.prototype.${name} can only be used on a TransformStreamDefaultController`); 582 | } 583 | 584 | // Stubs for abstract operations used from ReadableStream and WritableStream. 585 | 586 | function ReadableStreamDefaultControllerEnqueue(controller, chunk) { 587 | controller.enqueue(chunk); 588 | } 589 | 590 | function ReadableStreamDefaultControllerGetDesiredSize(controller) { 591 | return controller.desiredSize; 592 | } 593 | 594 | function ReadableStreamDefaultControllerClose(controller) { 595 | controller.close(); 596 | } 597 | 598 | function ReadableStreamDefaultControllerError(controller, e) { 599 | controller.error(e); 600 | } 601 | 602 | function WritableStreamDefaultControllerError(controller, e) { 603 | controller.error(e); 604 | } 605 | 606 | // Helper functions for the TransformStream. 607 | 608 | function streamBrandCheckException(name) { 609 | return new TypeError( 610 | `TransformStream.prototype.${name} can only be used on a TransformStream`); 611 | } 612 | 613 | // Copied from helpers.js. 614 | function IsPropertyKey(argument) { 615 | return typeof argument === 'string' || typeof argument === 'symbol'; 616 | } 617 | 618 | function typeIsObject(x) { 619 | return (typeof x === 'object' && x !== null) || typeof x === 'function'; 620 | } 621 | 622 | function Call(F, V, args) { 623 | if (typeof F !== 'function') { 624 | throw new TypeError('Argument is not a function'); 625 | } 626 | 627 | return Function.prototype.apply.call(F, V, args); 628 | } 629 | 630 | function InvokeOrNoop(O, P, args) { 631 | assert(O !== undefined); 632 | assert(IsPropertyKey(P)); 633 | assert(Array.isArray(args)); 634 | 635 | const method = O[P]; 636 | if (method === undefined) { 637 | return undefined; 638 | } 639 | 640 | return Call(method, O, args); 641 | }; 642 | 643 | function PromiseInvokeOrNoop(O, P, args) { 644 | assert(O !== undefined); 645 | assert(IsPropertyKey(P)); 646 | assert(Array.isArray(args)); 647 | try { 648 | return Promise.resolve(InvokeOrNoop(O, P, args)); 649 | } catch (returnValueE) { 650 | return Promise.reject(returnValueE); 651 | } 652 | }; 653 | 654 | function PromiseInvokeOrPerformFallback(O, P, args, F, argsF) { 655 | assert(O !== undefined); 656 | assert(IsPropertyKey(P)); 657 | assert(Array.isArray(args)); 658 | assert(Array.isArray(argsF)); 659 | 660 | let method; 661 | try { 662 | method = O[P]; 663 | } catch (methodE) { 664 | return Promise.reject(methodE); 665 | } 666 | 667 | if (method === undefined) { 668 | return F(...argsF); 669 | } 670 | 671 | try { 672 | return Promise.resolve(Call(method, O, args)); 673 | } catch (e) { 674 | return Promise.reject(e); 675 | } 676 | }; 677 | 678 | // DIY assert() implementation 679 | function assert(predicate, s) { 680 | class TransformStreamInternalLogicError extends Error { 681 | constructor(s) { 682 | super(s); 683 | } 684 | } 685 | if (!predicate) { 686 | console.log(`TransformStream internal logic error: assertion failed: s`); 687 | throw new TransformStreamInternalLogicError(s); 688 | } 689 | } 690 | 691 | self['TransformStream'] = TransformStream; 692 | 693 | })(); 694 | -------------------------------------------------------------------------------- /xhr-innerhtml.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var content = document.querySelector('.content'); 4 | 5 | document.querySelector('.xhr-innerhtml').addEventListener('click', function() { 6 | content.innerHTML = ''; 7 | var xhr = new XMLHttpRequest(); 8 | 9 | xhr.onload = function() { 10 | content.innerHTML = xhr.response; 11 | }; 12 | 13 | xhr.responseType = 'text'; 14 | xhr.open('GET', 'comments.inc.txt'); 15 | xhr.send(); 16 | }); 17 | 18 | })(); -------------------------------------------------------------------------------- /xhr-json.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var content = document.querySelector('.content'); 4 | 5 | document.querySelector('.xhr-json').addEventListener('click', function() { 6 | content.innerHTML = '' + 7 | '
' + 8 | '
' + 9 | '
' + 10 | '
' + 11 | '
' + 12 | '
' + 13 | '
' + 14 | '
' + 15 | '
' + 16 | '
' + 17 | '
' + 18 | '
' + 19 | '
' + 20 | '
'; 21 | 22 | var xhr = new XMLHttpRequest(); 23 | 24 | xhr.onload = function() { 25 | var container = content.querySelector('.js-discussion'); 26 | 27 | xhr.response.comments.forEach(function(comment) { 28 | var div = document.createElement('div'); 29 | div.className = comment.class; 30 | div.innerHTML = comment.html; 31 | container.appendChild(div); 32 | }); 33 | }; 34 | 35 | xhr.responseType = 'json'; 36 | xhr.open('GET', 'comments.json'); 37 | xhr.send(); 38 | }); 39 | 40 | })(); -------------------------------------------------------------------------------- /xhr-ndjson.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | function streamJSON(url, callback) { 3 | return new Promise(function(resolve, reject) { 4 | var xhr = new XMLHttpRequest(); 5 | var pos = 0; 6 | 7 | function processChunk(chunk) { 8 | try { 9 | var data = JSON.parse(chunk); 10 | } 11 | catch (err) { 12 | reject(Error('Error parsing: ' + chunk)); 13 | xhr.abort(); 14 | return; 15 | } 16 | 17 | callback(data); 18 | } 19 | 20 | xhr.onprogress = function() { 21 | var parts = xhr.response.slice(pos).split('\n'); 22 | 23 | parts.slice(0, -1).forEach(function(part) { 24 | processChunk(part); 25 | pos += part.length + 1; 26 | }); 27 | }; 28 | 29 | xhr.onload = function() { 30 | var chunk = xhr.response.slice(pos); 31 | if (chunk) processChunk(chunk); 32 | resolve(); 33 | }; 34 | 35 | xhr.onerror = function() { 36 | reject(Error('Connection failed')); 37 | }; 38 | 39 | xhr.responseType = 'text'; 40 | xhr.open('GET', url); 41 | xhr.send(); 42 | }); 43 | } 44 | 45 | 46 | var content = document.querySelector('.content'); 47 | 48 | document.querySelector('.xhr-ndjson').addEventListener('click', function() { 49 | content.innerHTML = '' + 50 | '
' + 51 | '
' + 52 | '
' + 53 | '
' + 54 | '
' + 55 | '
' + 56 | '
' + 57 | '
' + 58 | '
' + 59 | '
' + 60 | '
' + 61 | '
' + 62 | '
' + 63 | '
'; 64 | 65 | var container = content.querySelector('.js-discussion'); 66 | 67 | streamJSON('comments.ndjson.txt', function(comment) { 68 | var div = document.createElement('div'); 69 | div.className = comment.class; 70 | div.innerHTML = comment.html; 71 | container.appendChild(div); 72 | }); 73 | }); 74 | 75 | })(); -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/node@^6.0.46": 6 | version "6.0.88" 7 | resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.88.tgz#f618f11a944f6a18d92b5c472028728a3e3d4b66" 8 | 9 | JSONStream@^1.0.3: 10 | version "1.3.1" 11 | resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.1.tgz#707f761e01dae9e16f1bcf93703b78c70966579a" 12 | dependencies: 13 | jsonparse "^1.2.0" 14 | through ">=2.2.7 <3" 15 | 16 | accepts@~1.3.3: 17 | version "1.3.3" 18 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" 19 | dependencies: 20 | mime-types "~2.1.11" 21 | negotiator "0.6.1" 22 | 23 | acorn@^4.0.3: 24 | version "4.0.13" 25 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" 26 | 27 | array-filter@~0.0.0: 28 | version "0.0.1" 29 | resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" 30 | 31 | array-flatten@1.1.1: 32 | version "1.1.1" 33 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 34 | 35 | array-map@~0.0.0: 36 | version "0.0.0" 37 | resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" 38 | 39 | array-reduce@~0.0.0: 40 | version "0.0.0" 41 | resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" 42 | 43 | asn1.js@^4.0.0: 44 | version "4.9.1" 45 | resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.1.tgz#48ba240b45a9280e94748990ba597d216617fd40" 46 | dependencies: 47 | bn.js "^4.0.0" 48 | inherits "^2.0.1" 49 | minimalistic-assert "^1.0.0" 50 | 51 | assert@^1.4.0: 52 | version "1.4.1" 53 | resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" 54 | dependencies: 55 | util "0.10.3" 56 | 57 | astw@^2.0.0: 58 | version "2.2.0" 59 | resolved "https://registry.yarnpkg.com/astw/-/astw-2.2.0.tgz#7bd41784d32493987aeb239b6b4e1c57a873b917" 60 | dependencies: 61 | acorn "^4.0.3" 62 | 63 | balanced-match@^1.0.0: 64 | version "1.0.0" 65 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 66 | 67 | base64-js@^1.0.2: 68 | version "1.2.1" 69 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" 70 | 71 | bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: 72 | version "4.11.8" 73 | resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" 74 | 75 | brace-expansion@^1.1.7: 76 | version "1.1.8" 77 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" 78 | dependencies: 79 | balanced-match "^1.0.0" 80 | concat-map "0.0.1" 81 | 82 | brorand@^1.0.1: 83 | version "1.1.0" 84 | resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" 85 | 86 | browser-pack@^6.0.1: 87 | version "6.0.2" 88 | resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.0.2.tgz#f86cd6cef4f5300c8e63e07a4d512f65fbff4531" 89 | dependencies: 90 | JSONStream "^1.0.3" 91 | combine-source-map "~0.7.1" 92 | defined "^1.0.0" 93 | through2 "^2.0.0" 94 | umd "^3.0.0" 95 | 96 | browser-resolve@^1.11.0, browser-resolve@^1.7.0: 97 | version "1.11.2" 98 | resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" 99 | dependencies: 100 | resolve "1.1.7" 101 | 102 | browserify-aes@^1.0.0, browserify-aes@^1.0.4: 103 | version "1.0.8" 104 | resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.0.8.tgz#c8fa3b1b7585bb7ba77c5560b60996ddec6d5309" 105 | dependencies: 106 | buffer-xor "^1.0.3" 107 | cipher-base "^1.0.0" 108 | create-hash "^1.1.0" 109 | evp_bytestokey "^1.0.3" 110 | inherits "^2.0.1" 111 | safe-buffer "^5.0.1" 112 | 113 | browserify-cipher@^1.0.0: 114 | version "1.0.0" 115 | resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.0.tgz#9988244874bf5ed4e28da95666dcd66ac8fc363a" 116 | dependencies: 117 | browserify-aes "^1.0.4" 118 | browserify-des "^1.0.0" 119 | evp_bytestokey "^1.0.0" 120 | 121 | browserify-des@^1.0.0: 122 | version "1.0.0" 123 | resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.0.tgz#daa277717470922ed2fe18594118a175439721dd" 124 | dependencies: 125 | cipher-base "^1.0.1" 126 | des.js "^1.0.0" 127 | inherits "^2.0.1" 128 | 129 | browserify-rsa@^4.0.0: 130 | version "4.0.1" 131 | resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" 132 | dependencies: 133 | bn.js "^4.1.0" 134 | randombytes "^2.0.1" 135 | 136 | browserify-sign@^4.0.0: 137 | version "4.0.4" 138 | resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" 139 | dependencies: 140 | bn.js "^4.1.1" 141 | browserify-rsa "^4.0.0" 142 | create-hash "^1.1.0" 143 | create-hmac "^1.1.2" 144 | elliptic "^6.0.0" 145 | inherits "^2.0.1" 146 | parse-asn1 "^5.0.0" 147 | 148 | browserify-zlib@~0.1.2: 149 | version "0.1.4" 150 | resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" 151 | dependencies: 152 | pako "~0.2.0" 153 | 154 | browserify@^14.4.0: 155 | version "14.4.0" 156 | resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.4.0.tgz#089a3463af58d0e48d8cd4070b3f74654d5abca9" 157 | dependencies: 158 | JSONStream "^1.0.3" 159 | assert "^1.4.0" 160 | browser-pack "^6.0.1" 161 | browser-resolve "^1.11.0" 162 | browserify-zlib "~0.1.2" 163 | buffer "^5.0.2" 164 | cached-path-relative "^1.0.0" 165 | concat-stream "~1.5.1" 166 | console-browserify "^1.1.0" 167 | constants-browserify "~1.0.0" 168 | crypto-browserify "^3.0.0" 169 | defined "^1.0.0" 170 | deps-sort "^2.0.0" 171 | domain-browser "~1.1.0" 172 | duplexer2 "~0.1.2" 173 | events "~1.1.0" 174 | glob "^7.1.0" 175 | has "^1.0.0" 176 | htmlescape "^1.1.0" 177 | https-browserify "^1.0.0" 178 | inherits "~2.0.1" 179 | insert-module-globals "^7.0.0" 180 | labeled-stream-splicer "^2.0.0" 181 | module-deps "^4.0.8" 182 | os-browserify "~0.1.1" 183 | parents "^1.0.1" 184 | path-browserify "~0.0.0" 185 | process "~0.11.0" 186 | punycode "^1.3.2" 187 | querystring-es3 "~0.2.0" 188 | read-only-stream "^2.0.0" 189 | readable-stream "^2.0.2" 190 | resolve "^1.1.4" 191 | shasum "^1.0.0" 192 | shell-quote "^1.6.1" 193 | stream-browserify "^2.0.0" 194 | stream-http "^2.0.0" 195 | string_decoder "~1.0.0" 196 | subarg "^1.0.0" 197 | syntax-error "^1.1.1" 198 | through2 "^2.0.0" 199 | timers-browserify "^1.0.1" 200 | tty-browserify "~0.0.0" 201 | url "~0.11.0" 202 | util "~0.10.1" 203 | vm-browserify "~0.0.1" 204 | xtend "^4.0.0" 205 | 206 | buffer-xor@^1.0.3: 207 | version "1.0.3" 208 | resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" 209 | 210 | buffer@^5.0.2: 211 | version "5.0.7" 212 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.0.7.tgz#570a290b625cf2603290c1149223d27ccf04db97" 213 | dependencies: 214 | base64-js "^1.0.2" 215 | ieee754 "^1.1.4" 216 | 217 | builtin-status-codes@^3.0.0: 218 | version "3.0.0" 219 | resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" 220 | 221 | bytes@2.3.0: 222 | version "2.3.0" 223 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.3.0.tgz#d5b680a165b6201739acb611542aabc2d8ceb070" 224 | 225 | cached-path-relative@^1.0.0: 226 | version "1.0.1" 227 | resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.1.tgz#d09c4b52800aa4c078e2dd81a869aac90d2e54e7" 228 | 229 | cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: 230 | version "1.0.4" 231 | resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" 232 | dependencies: 233 | inherits "^2.0.1" 234 | safe-buffer "^5.0.1" 235 | 236 | combine-source-map@~0.7.1: 237 | version "0.7.2" 238 | resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.7.2.tgz#0870312856b307a87cc4ac486f3a9a62aeccc09e" 239 | dependencies: 240 | convert-source-map "~1.1.0" 241 | inline-source-map "~0.6.0" 242 | lodash.memoize "~3.0.3" 243 | source-map "~0.5.3" 244 | 245 | compressible@^2.0.9, compressible@~2.0.8: 246 | version "2.0.9" 247 | resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.9.tgz#6daab4e2b599c2770dd9e21e7a891b1c5a755425" 248 | dependencies: 249 | mime-db ">= 1.24.0 < 2" 250 | 251 | compression@^1.6.2: 252 | version "1.6.2" 253 | resolved "https://registry.yarnpkg.com/compression/-/compression-1.6.2.tgz#cceb121ecc9d09c52d7ad0c3350ea93ddd402bc3" 254 | dependencies: 255 | accepts "~1.3.3" 256 | bytes "2.3.0" 257 | compressible "~2.0.8" 258 | debug "~2.2.0" 259 | on-headers "~1.0.1" 260 | vary "~1.1.0" 261 | 262 | concat-map@0.0.1: 263 | version "0.0.1" 264 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 265 | 266 | concat-stream@~1.5.0, concat-stream@~1.5.1: 267 | version "1.5.2" 268 | resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" 269 | dependencies: 270 | inherits "~2.0.1" 271 | readable-stream "~2.0.0" 272 | typedarray "~0.0.5" 273 | 274 | console-browserify@^1.1.0: 275 | version "1.1.0" 276 | resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" 277 | dependencies: 278 | date-now "^0.1.4" 279 | 280 | constants-browserify@~1.0.0: 281 | version "1.0.0" 282 | resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" 283 | 284 | content-disposition@0.5.1: 285 | version "0.5.1" 286 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.1.tgz#87476c6a67c8daa87e32e87616df883ba7fb071b" 287 | 288 | content-type@~1.0.2: 289 | version "1.0.2" 290 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" 291 | 292 | convert-source-map@~1.1.0: 293 | version "1.1.3" 294 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860" 295 | 296 | cookie-signature@1.0.6: 297 | version "1.0.6" 298 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 299 | 300 | cookie@0.3.1: 301 | version "0.3.1" 302 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" 303 | 304 | core-util-is@~1.0.0: 305 | version "1.0.2" 306 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 307 | 308 | create-ecdh@^4.0.0: 309 | version "4.0.0" 310 | resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d" 311 | dependencies: 312 | bn.js "^4.1.0" 313 | elliptic "^6.0.0" 314 | 315 | create-hash@^1.1.0, create-hash@^1.1.2: 316 | version "1.1.3" 317 | resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd" 318 | dependencies: 319 | cipher-base "^1.0.1" 320 | inherits "^2.0.1" 321 | ripemd160 "^2.0.0" 322 | sha.js "^2.4.0" 323 | 324 | create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: 325 | version "1.1.6" 326 | resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.6.tgz#acb9e221a4e17bdb076e90657c42b93e3726cf06" 327 | dependencies: 328 | cipher-base "^1.0.3" 329 | create-hash "^1.1.0" 330 | inherits "^2.0.1" 331 | ripemd160 "^2.0.0" 332 | safe-buffer "^5.0.1" 333 | sha.js "^2.4.8" 334 | 335 | crypto-browserify@^3.0.0: 336 | version "3.11.1" 337 | resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.1.tgz#948945efc6757a400d6e5e5af47194d10064279f" 338 | dependencies: 339 | browserify-cipher "^1.0.0" 340 | browserify-sign "^4.0.0" 341 | create-ecdh "^4.0.0" 342 | create-hash "^1.1.0" 343 | create-hmac "^1.1.0" 344 | diffie-hellman "^5.0.0" 345 | inherits "^2.0.1" 346 | pbkdf2 "^3.0.3" 347 | public-encrypt "^4.0.0" 348 | randombytes "^2.0.0" 349 | 350 | date-now@^0.1.4: 351 | version "0.1.4" 352 | resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" 353 | 354 | debug@~2.2.0: 355 | version "2.2.0" 356 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" 357 | dependencies: 358 | ms "0.7.1" 359 | 360 | defined@^1.0.0: 361 | version "1.0.0" 362 | resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" 363 | 364 | depd@~1.1.0: 365 | version "1.1.0" 366 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" 367 | 368 | deps-sort@^2.0.0: 369 | version "2.0.0" 370 | resolved "https://registry.yarnpkg.com/deps-sort/-/deps-sort-2.0.0.tgz#091724902e84658260eb910748cccd1af6e21fb5" 371 | dependencies: 372 | JSONStream "^1.0.3" 373 | shasum "^1.0.0" 374 | subarg "^1.0.0" 375 | through2 "^2.0.0" 376 | 377 | des.js@^1.0.0: 378 | version "1.0.0" 379 | resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" 380 | dependencies: 381 | inherits "^2.0.1" 382 | minimalistic-assert "^1.0.0" 383 | 384 | destroy@~1.0.4: 385 | version "1.0.4" 386 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 387 | 388 | detective@^4.0.0: 389 | version "4.5.0" 390 | resolved "https://registry.yarnpkg.com/detective/-/detective-4.5.0.tgz#6e5a8c6b26e6c7a254b1c6b6d7490d98ec91edd1" 391 | dependencies: 392 | acorn "^4.0.3" 393 | defined "^1.0.0" 394 | 395 | diffie-hellman@^5.0.0: 396 | version "5.0.2" 397 | resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" 398 | dependencies: 399 | bn.js "^4.1.0" 400 | miller-rabin "^4.0.0" 401 | randombytes "^2.0.0" 402 | 403 | dom-treeadapter@RReverser/dom-treeadapter: 404 | version "0.1.0" 405 | resolved "https://codeload.github.com/RReverser/dom-treeadapter/tar.gz/6ff685a5f47cf7db2d4c63fcd0403155535ba9ae" 406 | dependencies: 407 | nodetype-enum "^1.1.1" 408 | 409 | domain-browser@~1.1.0: 410 | version "1.1.7" 411 | resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" 412 | 413 | duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2: 414 | version "0.1.4" 415 | resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" 416 | dependencies: 417 | readable-stream "^2.0.2" 418 | 419 | ee-first@1.1.1: 420 | version "1.1.1" 421 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 422 | 423 | elliptic@^6.0.0: 424 | version "6.4.0" 425 | resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" 426 | dependencies: 427 | bn.js "^4.4.0" 428 | brorand "^1.0.1" 429 | hash.js "^1.0.0" 430 | hmac-drbg "^1.0.0" 431 | inherits "^2.0.1" 432 | minimalistic-assert "^1.0.0" 433 | minimalistic-crypto-utils "^1.0.0" 434 | 435 | encodeurl@~1.0.1: 436 | version "1.0.1" 437 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" 438 | 439 | escape-html@~1.0.3: 440 | version "1.0.3" 441 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 442 | 443 | etag@~1.7.0: 444 | version "1.7.0" 445 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.7.0.tgz#03d30b5f67dd6e632d2945d30d6652731a34d5d8" 446 | 447 | events@~1.1.0: 448 | version "1.1.1" 449 | resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" 450 | 451 | evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: 452 | version "1.0.3" 453 | resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" 454 | dependencies: 455 | md5.js "^1.3.4" 456 | safe-buffer "^5.1.1" 457 | 458 | express@^4.14.0: 459 | version "4.14.0" 460 | resolved "https://registry.yarnpkg.com/express/-/express-4.14.0.tgz#c1ee3f42cdc891fb3dc650a8922d51ec847d0d66" 461 | dependencies: 462 | accepts "~1.3.3" 463 | array-flatten "1.1.1" 464 | content-disposition "0.5.1" 465 | content-type "~1.0.2" 466 | cookie "0.3.1" 467 | cookie-signature "1.0.6" 468 | debug "~2.2.0" 469 | depd "~1.1.0" 470 | encodeurl "~1.0.1" 471 | escape-html "~1.0.3" 472 | etag "~1.7.0" 473 | finalhandler "0.5.0" 474 | fresh "0.3.0" 475 | merge-descriptors "1.0.1" 476 | methods "~1.1.2" 477 | on-finished "~2.3.0" 478 | parseurl "~1.3.1" 479 | path-to-regexp "0.1.7" 480 | proxy-addr "~1.1.2" 481 | qs "6.2.0" 482 | range-parser "~1.2.0" 483 | send "0.14.1" 484 | serve-static "~1.11.1" 485 | type-is "~1.6.13" 486 | utils-merge "1.0.0" 487 | vary "~1.1.0" 488 | 489 | finalhandler@0.5.0: 490 | version "0.5.0" 491 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.5.0.tgz#e9508abece9b6dba871a6942a1d7911b91911ac7" 492 | dependencies: 493 | debug "~2.2.0" 494 | escape-html "~1.0.3" 495 | on-finished "~2.3.0" 496 | statuses "~1.3.0" 497 | unpipe "~1.0.0" 498 | 499 | forwarded@~0.1.0: 500 | version "0.1.0" 501 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363" 502 | 503 | fresh@0.3.0: 504 | version "0.3.0" 505 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f" 506 | 507 | fs.realpath@^1.0.0: 508 | version "1.0.0" 509 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 510 | 511 | function-bind@^1.0.2: 512 | version "1.1.1" 513 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 514 | 515 | glob@^7.1.0: 516 | version "7.1.2" 517 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 518 | dependencies: 519 | fs.realpath "^1.0.0" 520 | inflight "^1.0.4" 521 | inherits "2" 522 | minimatch "^3.0.4" 523 | once "^1.3.0" 524 | path-is-absolute "^1.0.0" 525 | 526 | has@^1.0.0: 527 | version "1.0.1" 528 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" 529 | dependencies: 530 | function-bind "^1.0.2" 531 | 532 | hash-base@^2.0.0: 533 | version "2.0.2" 534 | resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1" 535 | dependencies: 536 | inherits "^2.0.1" 537 | 538 | hash-base@^3.0.0: 539 | version "3.0.4" 540 | resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" 541 | dependencies: 542 | inherits "^2.0.1" 543 | safe-buffer "^5.0.1" 544 | 545 | hash.js@^1.0.0, hash.js@^1.0.3: 546 | version "1.1.3" 547 | resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" 548 | dependencies: 549 | inherits "^2.0.3" 550 | minimalistic-assert "^1.0.0" 551 | 552 | hmac-drbg@^1.0.0: 553 | version "1.0.1" 554 | resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" 555 | dependencies: 556 | hash.js "^1.0.3" 557 | minimalistic-assert "^1.0.0" 558 | minimalistic-crypto-utils "^1.0.1" 559 | 560 | htmlescape@^1.1.0: 561 | version "1.1.1" 562 | resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351" 563 | 564 | http-errors@~1.5.0: 565 | version "1.5.1" 566 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750" 567 | dependencies: 568 | inherits "2.0.3" 569 | setprototypeof "1.0.2" 570 | statuses ">= 1.3.1 < 2" 571 | 572 | https-browserify@^1.0.0: 573 | version "1.0.0" 574 | resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" 575 | 576 | ieee754@^1.1.4: 577 | version "1.1.8" 578 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" 579 | 580 | indexof@0.0.1: 581 | version "0.0.1" 582 | resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" 583 | 584 | inflight@^1.0.4: 585 | version "1.0.6" 586 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 587 | dependencies: 588 | once "^1.3.0" 589 | wrappy "1" 590 | 591 | inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: 592 | version "2.0.3" 593 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 594 | 595 | inherits@2.0.1: 596 | version "2.0.1" 597 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" 598 | 599 | inline-source-map@~0.6.0: 600 | version "0.6.2" 601 | resolved "https://registry.yarnpkg.com/inline-source-map/-/inline-source-map-0.6.2.tgz#f9393471c18a79d1724f863fa38b586370ade2a5" 602 | dependencies: 603 | source-map "~0.5.3" 604 | 605 | insert-module-globals@^7.0.0: 606 | version "7.0.1" 607 | resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.0.1.tgz#c03bf4e01cb086d5b5e5ace8ad0afe7889d638c3" 608 | dependencies: 609 | JSONStream "^1.0.3" 610 | combine-source-map "~0.7.1" 611 | concat-stream "~1.5.1" 612 | is-buffer "^1.1.0" 613 | lexical-scope "^1.2.0" 614 | process "~0.11.0" 615 | through2 "^2.0.0" 616 | xtend "^4.0.0" 617 | 618 | ipaddr.js@1.1.1: 619 | version "1.1.1" 620 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.1.1.tgz#c791d95f52b29c1247d5df80ada39b8a73647230" 621 | 622 | is-buffer@^1.1.0: 623 | version "1.1.5" 624 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" 625 | 626 | isarray@~0.0.1: 627 | version "0.0.1" 628 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 629 | 630 | isarray@~1.0.0: 631 | version "1.0.0" 632 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 633 | 634 | json-stable-stringify@~0.0.0: 635 | version "0.0.1" 636 | resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz#611c23e814db375527df851193db59dd2af27f45" 637 | dependencies: 638 | jsonify "~0.0.0" 639 | 640 | jsonify@~0.0.0: 641 | version "0.0.0" 642 | resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" 643 | 644 | jsonparse@^1.2.0: 645 | version "1.3.1" 646 | resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" 647 | 648 | labeled-stream-splicer@^2.0.0: 649 | version "2.0.0" 650 | resolved "https://registry.yarnpkg.com/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz#a52e1d138024c00b86b1c0c91f677918b8ae0a59" 651 | dependencies: 652 | inherits "^2.0.1" 653 | isarray "~0.0.1" 654 | stream-splicer "^2.0.0" 655 | 656 | lexical-scope@^1.2.0: 657 | version "1.2.0" 658 | resolved "https://registry.yarnpkg.com/lexical-scope/-/lexical-scope-1.2.0.tgz#fcea5edc704a4b3a8796cdca419c3a0afaf22df4" 659 | dependencies: 660 | astw "^2.0.0" 661 | 662 | lodash.memoize@~3.0.3: 663 | version "3.0.4" 664 | resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" 665 | 666 | md5.js@^1.3.4: 667 | version "1.3.4" 668 | resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" 669 | dependencies: 670 | hash-base "^3.0.0" 671 | inherits "^2.0.1" 672 | 673 | media-typer@0.3.0: 674 | version "0.3.0" 675 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 676 | 677 | merge-descriptors@1.0.1: 678 | version "1.0.1" 679 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 680 | 681 | methods@~1.1.2: 682 | version "1.1.2" 683 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 684 | 685 | miller-rabin@^4.0.0: 686 | version "4.0.0" 687 | resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.0.tgz#4a62fb1d42933c05583982f4c716f6fb9e6c6d3d" 688 | dependencies: 689 | bn.js "^4.0.0" 690 | brorand "^1.0.1" 691 | 692 | "mime-db@>= 1.24.0 < 2", mime-db@~1.25.0: 693 | version "1.25.0" 694 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.25.0.tgz#c18dbd7c73a5dbf6f44a024dc0d165a1e7b1c392" 695 | 696 | mime-types@~2.1.11, mime-types@~2.1.13: 697 | version "2.1.13" 698 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.13.tgz#e07aaa9c6c6b9a7ca3012c69003ad25a39e92a88" 699 | dependencies: 700 | mime-db "~1.25.0" 701 | 702 | mime@1.3.4: 703 | version "1.3.4" 704 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" 705 | 706 | minimalistic-assert@^1.0.0: 707 | version "1.0.0" 708 | resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" 709 | 710 | minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: 711 | version "1.0.1" 712 | resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" 713 | 714 | minimatch@^3.0.4: 715 | version "3.0.4" 716 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 717 | dependencies: 718 | brace-expansion "^1.1.7" 719 | 720 | minimist@^1.1.0: 721 | version "1.2.0" 722 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 723 | 724 | module-deps@^4.0.8: 725 | version "4.1.1" 726 | resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-4.1.1.tgz#23215833f1da13fd606ccb8087b44852dcb821fd" 727 | dependencies: 728 | JSONStream "^1.0.3" 729 | browser-resolve "^1.7.0" 730 | cached-path-relative "^1.0.0" 731 | concat-stream "~1.5.0" 732 | defined "^1.0.0" 733 | detective "^4.0.0" 734 | duplexer2 "^0.1.2" 735 | inherits "^2.0.1" 736 | parents "^1.0.0" 737 | readable-stream "^2.0.2" 738 | resolve "^1.1.3" 739 | stream-combiner2 "^1.1.1" 740 | subarg "^1.0.0" 741 | through2 "^2.0.0" 742 | xtend "^4.0.0" 743 | 744 | ms@0.7.1: 745 | version "0.7.1" 746 | resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" 747 | 748 | negotiator@0.6.1: 749 | version "0.6.1" 750 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" 751 | 752 | nodetype-enum@^1.1.1: 753 | version "1.1.1" 754 | resolved "https://registry.yarnpkg.com/nodetype-enum/-/nodetype-enum-1.1.1.tgz#32cfa7e59b1be20dab34bdb3df305864fdef8c70" 755 | 756 | on-finished@~2.3.0: 757 | version "2.3.0" 758 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 759 | dependencies: 760 | ee-first "1.1.1" 761 | 762 | on-headers@~1.0.1: 763 | version "1.0.1" 764 | resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" 765 | 766 | once@^1.3.0: 767 | version "1.4.0" 768 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 769 | dependencies: 770 | wrappy "1" 771 | 772 | os-browserify@~0.1.1: 773 | version "0.1.2" 774 | resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.1.2.tgz#49ca0293e0b19590a5f5de10c7f265a617d8fe54" 775 | 776 | pako@~0.2.0: 777 | version "0.2.9" 778 | resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" 779 | 780 | parents@^1.0.0, parents@^1.0.1: 781 | version "1.0.1" 782 | resolved "https://registry.yarnpkg.com/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751" 783 | dependencies: 784 | path-platform "~0.11.15" 785 | 786 | parse-asn1@^5.0.0: 787 | version "5.1.0" 788 | resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712" 789 | dependencies: 790 | asn1.js "^4.0.0" 791 | browserify-aes "^1.0.0" 792 | create-hash "^1.1.0" 793 | evp_bytestokey "^1.0.0" 794 | pbkdf2 "^3.0.3" 795 | 796 | parse5@^3.0.2: 797 | version "3.0.2" 798 | resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.2.tgz#05eff57f0ef4577fb144a79f8b9a967a6cc44510" 799 | dependencies: 800 | "@types/node" "^6.0.46" 801 | 802 | parseurl@~1.3.1: 803 | version "1.3.1" 804 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" 805 | 806 | path-browserify@~0.0.0: 807 | version "0.0.0" 808 | resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" 809 | 810 | path-is-absolute@^1.0.0: 811 | version "1.0.1" 812 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 813 | 814 | path-parse@^1.0.5: 815 | version "1.0.5" 816 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" 817 | 818 | path-platform@~0.11.15: 819 | version "0.11.15" 820 | resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" 821 | 822 | path-to-regexp@0.1.7: 823 | version "0.1.7" 824 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 825 | 826 | pbkdf2@^3.0.3: 827 | version "3.0.14" 828 | resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade" 829 | dependencies: 830 | create-hash "^1.1.2" 831 | create-hmac "^1.1.4" 832 | ripemd160 "^2.0.1" 833 | safe-buffer "^5.0.1" 834 | sha.js "^2.4.8" 835 | 836 | process-nextick-args@~1.0.6: 837 | version "1.0.7" 838 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" 839 | 840 | process@~0.11.0: 841 | version "0.11.10" 842 | resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" 843 | 844 | proxy-addr@~1.1.2: 845 | version "1.1.2" 846 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.2.tgz#b4cc5f22610d9535824c123aef9d3cf73c40ba37" 847 | dependencies: 848 | forwarded "~0.1.0" 849 | ipaddr.js "1.1.1" 850 | 851 | public-encrypt@^4.0.0: 852 | version "4.0.0" 853 | resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6" 854 | dependencies: 855 | bn.js "^4.1.0" 856 | browserify-rsa "^4.0.0" 857 | create-hash "^1.1.0" 858 | parse-asn1 "^5.0.0" 859 | randombytes "^2.0.1" 860 | 861 | punycode@1.3.2: 862 | version "1.3.2" 863 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" 864 | 865 | punycode@^1.3.2: 866 | version "1.4.1" 867 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" 868 | 869 | qs@6.2.0: 870 | version "6.2.0" 871 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.0.tgz#3b7848c03c2dece69a9522b0fae8c4126d745f3b" 872 | 873 | querystring-es3@~0.2.0: 874 | version "0.2.1" 875 | resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" 876 | 877 | querystring@0.2.0: 878 | version "0.2.0" 879 | resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" 880 | 881 | randombytes@^2.0.0, randombytes@^2.0.1: 882 | version "2.0.5" 883 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79" 884 | dependencies: 885 | safe-buffer "^5.1.0" 886 | 887 | range-parser@~1.2.0: 888 | version "1.2.0" 889 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" 890 | 891 | read-only-stream@^2.0.0: 892 | version "2.0.0" 893 | resolved "https://registry.yarnpkg.com/read-only-stream/-/read-only-stream-2.0.0.tgz#2724fd6a8113d73764ac288d4386270c1dbf17f0" 894 | dependencies: 895 | readable-stream "^2.0.2" 896 | 897 | readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.6: 898 | version "2.3.3" 899 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" 900 | dependencies: 901 | core-util-is "~1.0.0" 902 | inherits "~2.0.3" 903 | isarray "~1.0.0" 904 | process-nextick-args "~1.0.6" 905 | safe-buffer "~5.1.1" 906 | string_decoder "~1.0.3" 907 | util-deprecate "~1.0.1" 908 | 909 | readable-stream@~2.0.0: 910 | version "2.0.6" 911 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" 912 | dependencies: 913 | core-util-is "~1.0.0" 914 | inherits "~2.0.1" 915 | isarray "~1.0.0" 916 | process-nextick-args "~1.0.6" 917 | string_decoder "~0.10.x" 918 | util-deprecate "~1.0.1" 919 | 920 | resolve@1.1.7: 921 | version "1.1.7" 922 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" 923 | 924 | resolve@^1.1.3, resolve@^1.1.4: 925 | version "1.4.0" 926 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" 927 | dependencies: 928 | path-parse "^1.0.5" 929 | 930 | ripemd160@^2.0.0, ripemd160@^2.0.1: 931 | version "2.0.1" 932 | resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7" 933 | dependencies: 934 | hash-base "^2.0.0" 935 | inherits "^2.0.1" 936 | 937 | safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 938 | version "5.1.1" 939 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" 940 | 941 | send@0.14.1: 942 | version "0.14.1" 943 | resolved "https://registry.yarnpkg.com/send/-/send-0.14.1.tgz#a954984325392f51532a7760760e459598c89f7a" 944 | dependencies: 945 | debug "~2.2.0" 946 | depd "~1.1.0" 947 | destroy "~1.0.4" 948 | encodeurl "~1.0.1" 949 | escape-html "~1.0.3" 950 | etag "~1.7.0" 951 | fresh "0.3.0" 952 | http-errors "~1.5.0" 953 | mime "1.3.4" 954 | ms "0.7.1" 955 | on-finished "~2.3.0" 956 | range-parser "~1.2.0" 957 | statuses "~1.3.0" 958 | 959 | serve-static@~1.11.1: 960 | version "1.11.1" 961 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.11.1.tgz#d6cce7693505f733c759de57befc1af76c0f0805" 962 | dependencies: 963 | encodeurl "~1.0.1" 964 | escape-html "~1.0.3" 965 | parseurl "~1.3.1" 966 | send "0.14.1" 967 | 968 | setprototypeof@1.0.2: 969 | version "1.0.2" 970 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.2.tgz#81a552141ec104b88e89ce383103ad5c66564d08" 971 | 972 | sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4: 973 | version "2.4.9" 974 | resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d" 975 | dependencies: 976 | inherits "^2.0.1" 977 | safe-buffer "^5.0.1" 978 | 979 | shasum@^1.0.0: 980 | version "1.0.2" 981 | resolved "https://registry.yarnpkg.com/shasum/-/shasum-1.0.2.tgz#e7012310d8f417f4deb5712150e5678b87ae565f" 982 | dependencies: 983 | json-stable-stringify "~0.0.0" 984 | sha.js "~2.4.4" 985 | 986 | shell-quote@^1.6.1: 987 | version "1.6.1" 988 | resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" 989 | dependencies: 990 | array-filter "~0.0.0" 991 | array-map "~0.0.0" 992 | array-reduce "~0.0.0" 993 | jsonify "~0.0.0" 994 | 995 | source-map@~0.5.3: 996 | version "0.5.7" 997 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 998 | 999 | "statuses@>= 1.3.1 < 2", statuses@~1.3.0: 1000 | version "1.3.1" 1001 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" 1002 | 1003 | stream-browserify@^2.0.0: 1004 | version "2.0.1" 1005 | resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" 1006 | dependencies: 1007 | inherits "~2.0.1" 1008 | readable-stream "^2.0.2" 1009 | 1010 | stream-combiner2@^1.1.1: 1011 | version "1.1.1" 1012 | resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" 1013 | dependencies: 1014 | duplexer2 "~0.1.0" 1015 | readable-stream "^2.0.2" 1016 | 1017 | stream-http@^2.0.0: 1018 | version "2.7.2" 1019 | resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad" 1020 | dependencies: 1021 | builtin-status-codes "^3.0.0" 1022 | inherits "^2.0.1" 1023 | readable-stream "^2.2.6" 1024 | to-arraybuffer "^1.0.0" 1025 | xtend "^4.0.0" 1026 | 1027 | stream-splicer@^2.0.0: 1028 | version "2.0.0" 1029 | resolved "https://registry.yarnpkg.com/stream-splicer/-/stream-splicer-2.0.0.tgz#1b63be438a133e4b671cc1935197600175910d83" 1030 | dependencies: 1031 | inherits "^2.0.1" 1032 | readable-stream "^2.0.2" 1033 | 1034 | string_decoder@~0.10.x: 1035 | version "0.10.31" 1036 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 1037 | 1038 | string_decoder@~1.0.0, string_decoder@~1.0.3: 1039 | version "1.0.3" 1040 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" 1041 | dependencies: 1042 | safe-buffer "~5.1.0" 1043 | 1044 | subarg@^1.0.0: 1045 | version "1.0.0" 1046 | resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" 1047 | dependencies: 1048 | minimist "^1.1.0" 1049 | 1050 | syntax-error@^1.1.1: 1051 | version "1.3.0" 1052 | resolved "https://registry.yarnpkg.com/syntax-error/-/syntax-error-1.3.0.tgz#1ed9266c4d40be75dc55bf9bb1cb77062bb96ca1" 1053 | dependencies: 1054 | acorn "^4.0.3" 1055 | 1056 | through2@^2.0.0: 1057 | version "2.0.3" 1058 | resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" 1059 | dependencies: 1060 | readable-stream "^2.1.5" 1061 | xtend "~4.0.1" 1062 | 1063 | "through@>=2.2.7 <3": 1064 | version "2.3.8" 1065 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 1066 | 1067 | timers-browserify@^1.0.1: 1068 | version "1.4.2" 1069 | resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d" 1070 | dependencies: 1071 | process "~0.11.0" 1072 | 1073 | to-arraybuffer@^1.0.0: 1074 | version "1.0.1" 1075 | resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" 1076 | 1077 | tty-browserify@~0.0.0: 1078 | version "0.0.0" 1079 | resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" 1080 | 1081 | type-is@~1.6.13: 1082 | version "1.6.14" 1083 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.14.tgz#e219639c17ded1ca0789092dd54a03826b817cb2" 1084 | dependencies: 1085 | media-typer "0.3.0" 1086 | mime-types "~2.1.13" 1087 | 1088 | typedarray@~0.0.5: 1089 | version "0.0.6" 1090 | resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" 1091 | 1092 | umd@^3.0.0: 1093 | version "3.0.1" 1094 | resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.1.tgz#8ae556e11011f63c2596708a8837259f01b3d60e" 1095 | 1096 | unpipe@~1.0.0: 1097 | version "1.0.0" 1098 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 1099 | 1100 | url@~0.11.0: 1101 | version "0.11.0" 1102 | resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" 1103 | dependencies: 1104 | punycode "1.3.2" 1105 | querystring "0.2.0" 1106 | 1107 | util-deprecate@~1.0.1: 1108 | version "1.0.2" 1109 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1110 | 1111 | util@0.10.3, util@~0.10.1: 1112 | version "0.10.3" 1113 | resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" 1114 | dependencies: 1115 | inherits "2.0.1" 1116 | 1117 | utils-merge@1.0.0: 1118 | version "1.0.0" 1119 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" 1120 | 1121 | vary@~1.1.0: 1122 | version "1.1.0" 1123 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.0.tgz#e1e5affbbd16ae768dd2674394b9ad3022653140" 1124 | 1125 | vm-browserify@~0.0.1: 1126 | version "0.0.4" 1127 | resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" 1128 | dependencies: 1129 | indexof "0.0.1" 1130 | 1131 | wrappy@1: 1132 | version "1.0.2" 1133 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1134 | 1135 | xtend@^4.0.0, xtend@~4.0.1: 1136 | version "4.0.1" 1137 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" 1138 | --------------------------------------------------------------------------------