git ssb

16+

Dominic / patchbay



Commit f2e0672ea2122a0681f222b03f03d0e227303352

Merge branch 'opinionate' of ssb://%s9mSFATE4RGyJx9wgH22lBrvD4CgUQW4yeguSWWjtqc=.sha256 into evmaster

Ev Bogue committed on 11/12/2016, 3:32:57 AM
Parent: 9334dd2b798b099cd5e9bd7e007f444359f466bb
Parent: 99b8a9a471f85c47bbb7f32dc108e456f881b14d

Files changed

index.jschanged
package.jsonchanged
plugs.jschanged
util.jschanged
build.jsdeleted
basic.jsadded
embedded.jsadded
modules/_screen_view.jsdeleted
modules/about.jsdeleted
modules/app.jsdeleted
modules/audio-mp3.jsdeleted
modules/avatar-edit.jsdeleted
modules/avatar-image.jsdeleted
modules/avatar-link.jsdeleted
modules/avatar-name.jsdeleted
modules/avatar-profile.jsdeleted
modules/avatar.jsdeleted
modules/avatar_fallback.pngdeleted
modules/blob-url.jsdeleted
modules/channel.jsdeleted
modules/compose.jsdeleted
modules/crypto.jsdeleted
modules/feed.jsdeleted
modules/file-input.jsdeleted
modules/follow.jsdeleted
modules/git.jsdeleted
modules/index.jsdeleted
modules/invite.jsdeleted
modules/like.jsdeleted
modules/markdown.jsdeleted
modules/menu.jsdeleted
modules/message-confirm.jsdeleted
modules/message-link.jsdeleted
modules/message-name.jsdeleted
modules/message.jsdeleted
modules/meta-image.jsdeleted
modules/music-release-cc.jsdeleted
modules/music-release.jsdeleted
modules/names.jsdeleted
modules/network.jsdeleted
modules/notifications.jsdeleted
modules/post.jsdeleted
modules/private.jsdeleted
modules/public.jsdeleted
modules/query.jsdeleted
modules/raw.jsdeleted
modules/relationships.jsdeleted
modules/search-box.jsdeleted
modules/search.jsdeleted
modules/setup.jsdeleted
modules/split.jsdeleted
modules/suggest-mentions.jsdeleted
modules/suggest.jsdeleted
modules/tabs.jsdeleted
modules/thread.jsdeleted
modules/timestamp.jsdeleted
modules/versions.jsdeleted
modules_basic/about.jsadded
modules_basic/avatar-edit.jsadded
modules_basic/avatar-image.jsadded
modules_basic/avatar-link.jsadded
modules_basic/avatar-name.jsadded
modules_basic/avatar-profile.jsadded
modules_basic/avatar.jsadded
modules_basic/compose.jsadded
modules_basic/feed.jsadded
modules_basic/follow.jsadded
modules_basic/index.jsadded
modules_basic/invite.jsadded
modules_basic/like.jsadded
modules_basic/markdown.jsadded
modules_basic/message-link.jsadded
modules_basic/message-name.jsadded
modules_basic/message.jsadded
modules_basic/names.jsadded
modules_basic/post.jsadded
modules_basic/private.jsadded
modules_basic/public.jsadded
modules_basic/relationships.jsadded
modules_basic/search-box.jsadded
modules_basic/setup.jsadded
modules_basic/suggest-mentions.jsadded
modules_basic/suggest.jsadded
modules_basic/thread.jsadded
modules_basic/timestamp.jsadded
modules_core/_screen_view.jsadded
modules_core/app.jsadded
modules_core/blob-url.jsadded
modules_core/crypto.jsadded
modules_core/file-input.jsadded
modules_core/index.jsadded
modules_core/menu.jsadded
modules_core/message-confirm.jsadded
modules_core/sbot.jsadded
modules_core/tabs.jsadded
sbot-api.jsdeleted
modules_embedded/index.jsadded
modules_embedded/sbot.jsadded
modules_extra/audio-mp3.jsadded
modules_extra/channel.jsadded
modules_extra/git.jsadded
modules_extra/index.jsadded
modules_extra/meta-image.jsadded
modules_extra/music-release-cc.jsadded
modules_extra/music-release.jsadded
modules_extra/network.jsadded
modules_extra/notifications.jsadded
modules_extra/query.jsadded
modules_extra/raw.jsadded
modules_extra/search.jsadded
modules_extra/split.jsadded
modules_extra/versions.jsadded
ui.jsdeleted
scripts/build.jsadded
scripts/create-index.jsadded
scripts/dir.jsadded
scripts/style.jsadded
yarn.lockadded
index.jsView
@@ -1,33 +1,6 @@
1-var h = require('hyperscript')
1 +require('depject')(
2 + require('./modules_core'),
3 + require('./modules_basic'),
4 + require('./modules_extra')
5 +).plugs.app[0]()
26
3-window.addEventListener('error', window.onError = function (e) {
4- document.body.appendChild(h('div.error',
5- h('h1', e.message),
6- h('big', h('code', e.filename + ':' + e.lineno)),
7- h('pre', e.error ? (e.error.stack || e.error.toString()) : e.toString())))
8-})
9-
10-var u = require('./util')
11-var pull = require('pull-stream')
12-var combine = require('depject')
13-var fs = require('fs')
14-var path = require('path')
15-var SbotApi = require('./sbot-api')
16-
17-document.head.appendChild(h('style', require('./style.css.json')))
18-
19-var modules = require('./modules')
20-
21-var u = require('./util')
22-
23-modules['sbot-api.js'] = SbotApi()
24-combine(modules)
25-
26-if(process.title === 'node') {
27- console.log(require('depject/graph')(modules))
28- process.exit(0)
29-}
30-
31-document.body.appendChild(modules['app.js'].app())
32-
33-
package.jsonView
@@ -1,17 +1,17 @@
11 {
22 "name": "patchbay",
33 "description": "a pluggable patchwork",
4- "version": "4.0.1",
4 + "version": "4.1.0",
55 "homepage": "https://github.com/dominictarr/patchbay",
66 "repository": {
77 "type": "git",
88 "url": "git://github.com/dominictarr/patchbay.git"
99 },
1010 "dependencies": {
1111 "cont": "^1.0.3",
1212 "dataurl-": "^0.1.0",
13- "depject": "^1.0.1",
13 + "depject": "^2.0.0",
1414 "hjson": "^2.0.3",
1515 "human-time": "0.0.1",
1616 "hypercombo": "0.1.0",
1717 "hypercrop": "^1.0.1",
@@ -20,45 +20,50 @@
2020 "hyperprogress": "0.1.0",
2121 "hyperscript": "^1.4.7",
2222 "hypertabs": "^2.2.0",
2323 "is-visible": "^2.0.4",
24 + "kvgraph": "^0.1.0",
2425 "map-filter-reduce": "^3.0.1",
2526 "mime-types": "^2.1.11",
2627 "moment": "^2.13.0",
2728 "open-external": "^0.1.1",
2829 "peaks.js": "^0.4.7",
2930 "pull-cat": "^1.1.9",
30- "pull-many": "^1.0.6",
31- "pull-next": "0.0.0",
31 + "pull-many": "^1.0.7",
32 + "pull-next": "^0.0.1",
3233 "pull-paramap": "^1.1.6",
3334 "pull-reconnect": "^0.0.3",
3435 "pull-scroll": "^0.2.0",
35- "pull-stream": "^3.3.2",
36 + "pull-stream": "^3.4.5",
37 + "scuttlebot": "^8.7.2",
3638 "simple-mime": "^0.1.0",
3739 "split-buffer": "^1.0.0",
40 + "ssb-blobs": "^0.1.7",
3841 "ssb-avatar": "^0.2.0",
3942 "ssb-client": "^4.0.3",
4043 "ssb-config": "^2.1.1",
4144 "ssb-feed": "^2.2.1",
45 + "ssb-git": "^0.4.1",
4246 "ssb-keys": "^6.1.0",
47 + "ssb-links": "^2.0.0",
4348 "ssb-markdown": "^3.0.0",
4449 "ssb-mentions": "^0.1.0",
50 + "ssb-query": "^0.1.1",
4551 "ssb-ref": "^2.6.2",
4652 "ssb-sort": "^1.0.0",
53 + "ssb-ws": "^0.6.2",
4754 "suggest-box": "^2.2.1",
4855 "text-node-searcher": "^1.1.0",
4956 "visualize-buffer": "0.0.0"
5057 },
5158 "devDependencies": {
5259 "browselectrify": "^1.0.1"
5360 },
54- "browser": {
55- "./modules/index.js": "./modules/_index.js"
56- },
5761 "scripts": {
58- "build": "node build.js > modules/_index.js && mkdir -p build && browselectrify index.js > build/bundle.js",
62 + "build": "node scripts/style.js && mkdir -p build && browselectrify index.js > build/bundle.js",
5963 "graph": "node index.js | dot -Tsvg > graph.svg",
6064 "test": "set -e; for t in test/*.js; do node $t; done"
6165 },
6266 "author": "Dominic Tarr <dominic.tarr@gmail.com> (http://dominictarr.com)",
6367 "license": "MIT"
6468 }
69 +
plugs.jsView
@@ -1,10 +1,11 @@
1-var u = require('./util')
2-
31 exports.first = function first(plug) {
42 return function () {
53 var args = [].slice.call(arguments)
6- return u.firstPlug(plug, args)
4 + for(var i = 0; i < plug.length; i++) {
5 + var val = plug[i].apply(null, args)
6 + if(val) return val
7 + }
78 }
89 }
910
1011 exports.map = function (plug) {
@@ -16,5 +17,4 @@
1617 }
1718 }
1819
1920
20-
util.jsView
@@ -1,39 +1,26 @@
11 var pull = require('pull-stream')
22 var Next = require('pull-next')
33
4-function first (list, test) {
5- for(var i in list) {
6- var value = test(list[i], i, list)
7- if(value) return value
4 +function get (obj, path) {
5 + if(!obj) return undefined
6 + if('string' === typeof path) return obj[path]
7 + if(Array.isArray(path)) {
8 + for(var i = 0; obj && i < path.length; i++)
9 + obj = obj[path[i]]
10 + return obj
811 }
912 }
1013
11-function decorate (list, value, caller) {
12- caller = caller || function (d,e,v) { return d(e, v) }
13-
14- return list.reduce(function (element, decorator) {
15- return caller(decorator, element, value) || element
16- }, null)
14 +function clone (obj) {
15 + var _obj = {}
16 + for(var k in obj) _obj[k] = obj[k]
17 + return _obj
1718 }
1819
19-function get(obj, path) {
20- if(obj == null) return obj
21- if('string' === typeof path) return obj[path]
22- for(var i = 0; i < path.length; i++) {
23- obj = obj[path[i]]
24- if(obj == null) return
25- }
26- return obj
27-
28-}
29-
30-exports.first = first
31-exports.decorate = decorate
32-
3320 exports.next = function (createStream, opts, property, range) {
3421
35- range = range || opts.reverse ? 'lt' : 'gt'
22 + range = range || (opts.reverse ? 'lt' : 'gt')
3623 property = property || 'timestamp'
3724
3825 var last = null, count = -1
3926 return Next(function () {
@@ -43,12 +30,14 @@
4330 if(value == null) return
4431 last = null
4532 }
4633 return pull(
47- createStream(opts),
34 + createStream(clone(opts)),
4835 pull.through(function (msg) {
4936 count ++
50- if(!msg.sync) last = msg
37 + if(!msg.sync) {
38 + last = msg
39 + }
5140 }, function (err) {
5241 //retry on errors...
5342 if(err) return count = -1
5443 //end stream if there were no results
@@ -57,12 +46,6 @@
5746 )
5847 })
5948 }
6049
61-exports.firstPlug = function (plugs, args) {
62- if(!Array.isArray(plugs)) throw new Error('plugs must be an array')
63- return exports.first(plugs, function (fn) {
64- return fn.apply(null, args)
65- })
66-}
6750
6851
build.jsView
@@ -1,22 +1,0 @@
1-var fs = require('fs')
2-var path = require('path')
3-
4-fs.writeFileSync(
5- path.join(__dirname, 'style.css.json'),
6- JSON.stringify(fs.readFileSync(path.join(__dirname, 'style.css'), 'utf8'))
7-)
8-
9-
10-fs.writeFileSync(path.join(__dirname, 'modules', '_index.js'),
11- 'module.exports = {\n'
12- +
13- fs.readdirSync(path.join(__dirname, 'modules'))
14- .filter(function (file) {
15- return file !== '_index.js' && /\.js$/.test(file)
16- })
17- .map(function (file) {
18- return ' '+JSON.stringify(file) + ": require('./"+file+"')"
19- }).join(',\n')
20- +
21- '\n}'
22-)
basic.jsView
@@ -1,0 +1,6 @@
1 +require('depject')(
2 + require('./modules_core'),
3 + require('./modules_basic')
4 +).plugs.app[0]()
5 +
6 +
embedded.jsView
@@ -1,0 +1,9 @@
1 +require('depject')(
2 + require('./modules_embedded'),
3 + require('./modules_basic'),
4 + require('./modules_extra')
5 +).plugs.app[0]()
6 +
7 +
8 +
9 +
modules/_screen_view.jsView
@@ -1,8 +1,0 @@
1-
2-//this is just an UGLY HACK, because depject does not
3-//support recursion...
4-
5-var sv = require('../plugs').first(exports.screen_view = [])
6-exports._screen_view = function (value) {
7- return sv(value)
8-}
modules/about.jsView
@@ -1,40 +1,0 @@
1-
2-var h = require('hyperscript')
3-
4-function idLink (id) {
5- return h('a', {href:'#'+id}, id)
6-}
7-
8-function asLink (ln) {
9- return 'string' === typeof ln ? ln : ln.link
10-}
11-
12-var blob_url = require('../plugs').first(exports.blob_url = [])
13-
14-exports.message_content = function (msg) {
15- if(msg.value.content.type !== 'about') return
16-
17- if(!msg.value.content.image && !msg.value.content.name)
18- return
19-
20- var about = msg.value.content
21- var id = msg.value.content.about
22- return h('p',
23- about.about === msg.value.author
24- ? h('span', 'self-identifies ')
25- : h('span', 'identifies ', idLink(id)),
26- ' as ',
27- h('a', {href:"#"+about.about},
28- about.name || null,
29- about.image
30- ? h('img.avatar--fullsize', {src: blob_url(about.image)})
31- : null
32- )
33- )
34-
35-}
36-
37-
38-
39-
40-
modules/app.jsView
@@ -1,57 +1,0 @@
1-var plugs = require('../plugs')
2-var h = require('hyperscript')
3-
4-var screen_view = plugs.first(exports.screen_view = [])
5-
6-
7-exports.app = function () {
8- function hash() {
9- return window.location.hash.substring(1)
10- }
11-
12- var view = screen_view(hash() || 'tabs')
13-
14- var screen = h('div.screen.column', view)
15-
16- window.onhashchange = function (ev) {
17- var _view = view
18- view = screen_view(hash() || 'tabs')
19-
20- if(_view) screen.replaceChild(view, _view)
21- else document.body.appendChild(view)
22- }
23-
24-
25- return screen
26-
27-}
28-
29-
30-
31-
32-
33-
34-
35-
36-
37-
38-
39-
40-
41-
42-
43-
44-
45-
46-
47-
48-
49-
50-
51-
52-
53-
54-
55-
56-
57-
modules/audio-mp3.jsView
@@ -1,51 +1,0 @@
1-var markdown = require('ssb-markdown');
2-var h = require('hyperscript');
3-var u = require('../util');
4-var ref = require('ssb-ref');
5-
6-//render a message
7-
8-var plugs = require('../plugs');
9-var message_link = plugs.first(exports.message_link = []);
10-var message_confirm = plugs.first(exports.message_confirm = []);
11-var sbot_links = plugs.first(exports.sbot_links = []);
12-var blob_url = plugs.first(exports.blob_url = []);
13-
14-exports.message_content = function(msg, sbot) {
15- if (msg.value.content.type !== 'audio-mp3')
16- return;
17-
18- var v = msg.value.content;
19- return h('div',
20- h('h2', "(" + v.Track + ") " + v.Title),
21- // h('img', { "src" : blob_url(v.cover) }),
22- h('audio', {
23- "controls" : true,
24- "src" : blob_url(v.link)
25- }))
26- // h('dl',
27- // Object.keys(v).map(function(k) {
28- // return [
29- // h("dt", k),
30- // h("dd", v[k]),
31- // ]
32- // })))
33-
34- // "Album": "the fall of",
35- // "Crc32": "038becab",
36- // "Creator": "bleupulp",
37- // "Format": "VBR MP3",
38- // "Height": "0",
39- // "Length": "375.23",
40- // "Md5": "2c517c8e813da5f940c8c7e77d4b7f3f",
41- // "Mtime": "1399498698",
42- // "Name": "2_bleupulp_-_clouds.mp3",
43- // "Sha1": "9f6a96a3d5571ed1ec2a7da38ffebdcd5f181482",
44- // "Size": "15009000",
45-
46- // "Title": "clouds",
47- // "Track": "2",
48- // "Width": "0",
49-
50-}
51-
modules/avatar-edit.jsView
@@ -1,141 +1,0 @@
1-var dataurl = require('dataurl-')
2-var hyperfile = require('hyperfile')
3-var hypercrop = require('hypercrop')
4-var hyperlightbox = require('hyperlightbox')
5-var h = require('hyperscript')
6-var pull = require('pull-stream')
7-var getAvatar = require('ssb-avatar')
8-var plugs = require('../plugs')
9-var ref = require('ssb-ref')
10-var visualize = require('visualize-buffer')
11-var self_id = require('../keys').id
12-
13-var confirm = plugs.first(exports.message_confirm = [])
14-var sbot_blobs_add = plugs.first(exports.sbot_blobs_add = [])
15-var blob_url = plugs.first(exports.blob_url = [])
16-var sbot_links = plugs.first(exports.sbot_links = [])
17-var avatar_name = plugs.first(exports.avatar_name = [])
18-
19-function crop (d, cb) {
20- var data
21- var canvas = hypercrop(h('img', {src: d}))
22-
23- return h('div.column.avatar_pic',
24- canvas,
25- //canvas.selection,
26- h('div.row.avatar_pic__controls',
27- h('button', 'okay', {onclick: function () {
28- cb(null, canvas.selection.toDataURL())
29- }}),
30- h('button', 'cancel', {onclick: function () {
31- cb(new Error('canceled'))
32- }})
33- )
34- )
35-}
36-
37-exports.avatar_edit = function (id) {
38-
39- var img = visualize(new Buffer(id.substring(1), 'base64'), 256)
40- img.classList.add('avatar--large')
41-
42- var lb = hyperlightbox()
43- var name_input = h('input', {placeholder: 'rename'})
44- var name = avatar_name(id)
45- var selected = null, selected_data = null
46-
47- getAvatar({links: sbot_links}, self_id, id, function (err, avatar) {
48- if (err) return console.error(err)
49- //don't show user has already selected an avatar.
50- if(selected) return
51- if(ref.isBlob(avatar.image))
52- img.src = blob_url(avatar.image)
53- })
54-
55- var also_pictured = h('div.profile__alsopicturedas.wrap')
56-
57- pull(
58- sbot_links({dest: id, rel: 'about', values: true}),
59- pull.map(function (e) {
60- return e.value.content.image
61- }),
62- pull.filter(function (e) {
63- return e && 'string' == typeof e.link
64- }),
65- pull.unique('link'),
66- pull.drain(function (image) {
67- also_pictured.appendChild(
68- h('a', {href:'#', onclick: function (ev) {
69- ev.stopPropagation()
70- ev.preventDefault()
71- selected = image
72- img.src = blob_url(image.link || image)
73- }},
74- h('img.avatar--thumbnail', {src: blob_url(image)})
75- )
76- )
77- })
78- )
79-
80- return h('div.row.profile',
81- lb,
82- img,
83- h('div.column.profile__info',
84- h('strong', name),
85- name_input,
86-
87- hyperfile.asDataURL(function (data) {
88- var el = crop(data, function (err, data) {
89- if(data) {
90- img.src = data
91- var _data = dataurl.parse(data)
92- pull(
93- pull.once(_data.data),
94- sbot_blobs_add(function (err, hash) {
95- //TODO. Alerts are EVIL.
96- //I use them only in a moment of weakness.
97-
98- if(err) return alert(err.stack)
99- selected = {
100- link: hash,
101- size: _data.data.length,
102- type: _data.mimetype,
103- width: 512,
104- height: 512
105- }
106-
107- })
108- )
109- }
110- lb.close()
111- })
112- lb.show(el)
113- }),
114- h('button', 'update', {onclick: function () {
115- if(name_input.value)
116- name.textContent = name_input.value
117-
118- if(selected)
119- confirm({
120- type: 'about',
121- about: id,
122- name: name_input.value || undefined,
123- image: selected
124- })
125- else if(name_input.value) //name only
126- confirm({
127- type: 'about',
128- about: id,
129- name: name_input.value || undefined,
130- })
131- else
132- //another moment of weakness
133- alert('must select a name or image')
134- }}),
135- also_pictured
136- )
137- )
138-}
139-
140-
141-
modules/avatar-image.jsView
@@ -1,108 +1,0 @@
1-
2-var getAvatar = require('ssb-avatar')
3-var h = require('hyperscript')
4-var ref = require('ssb-ref')
5-var path = require('path')
6-var visualize = require('visualize-buffer')
7-
8-var plugs = require('../plugs')
9-var sbot_query = plugs.first(exports.sbot_query = [])
10-var blob_url = require('../plugs').first(exports.blob_url = [])
11-
12-var pull = require('pull-stream')
13-
14-var id = require('../keys').id
15-
16-var avatars = AVATARS = {}
17-
18-function isFunction (f) {
19- return 'function' === typeof f
20-}
21-
22-var self_id = require('../keys').id
23-
24-var ready = false
25-var waiting = []
26-
27-var last = 0
28-
29-//blah blah
30-exports.connection_status = function (err) {
31- if (err) return
32-pull(
33- sbot_query({
34- query: [{
35- $filter: {
36- timestamp: {$gt: last || 0 },
37- value: { content: {
38- type: "about",
39- about: {$prefix: "@"},
40- image: {link: {$prefix: "&"}}
41- }}
42- }},
43- {
44- $map: {
45- id: ["value", "content", "about"],
46- image: ["value", "content", "image", "link"],
47- by: ["value", "author"],
48- ts: 'timestamp'
49- }}],
50- live: true
51- }),
52- pull.drain(function (a) {
53- if(a.sync) {
54- ready = true
55- while(waiting.length) waiting.shift()()
56- return
57- }
58- last = a.ts
59- //set image for avatar.
60- //overwrite another avatar
61- //you picked.
62- if(
63- //if there is no avatar
64- (!avatars[a.id]) ||
65- //if i chose this avatar
66- (a.by == self_id) ||
67- //they chose their own avatar,
68- //and current avatar was not chosen by me
69- (a.by === a.id && avatars[a.id].by != self_id)
70- )
71- avatars[a.id] = a
72-
73- })
74-)
75-}
76-
77-exports.avatar_image = function (author, classes) {
78- classes = classes || ''
79- if(classes && 'string' === typeof classes) classes = '.avatar--'+classes
80-
81- var img = visualize(new Buffer(author.substring(1), 'base64'), 256)
82- ;(classes || '').split('.').filter(Boolean).forEach(function (c) {
83- img.classList.add(c)
84- })
85-
86- function go () {
87- if(avatars[author]) img.src = blob_url(avatars[author].image)
88- }
89-
90- if(!ready)
91- waiting.push(go)
92- else go()
93-
94- return img
95-}
96-
97-
98-
99-
100-
101-
102-
103-
104-
105-
106-
107-
108-
modules/avatar-link.jsView
@@ -1,18 +1,0 @@
1-var h = require('hyperscript')
2-var plugs = require('../plugs')
3-var avatar_name = plugs.first(exports.avatar_name = [])
4-
5-var signifier = require('../plugs').first(exports.signifier = [])
6-
7-exports.avatar_link = function (id, element) {
8-
9- var link = h('a.avatar', {href: "#"+id, title: id}, element)
10-
11- signifier(id, function (_, names) {
12- if(names.length)
13- link.title = names[0].name + '\n '+id
14- })
15-
16- return link
17-}
18-
modules/avatar-name.jsView
@@ -1,22 +1,0 @@
1-
2-var signifier = require('../plugs').first(exports.signifier = [])
3-var h = require('hyperscript')
4-
5-exports.avatar_name =
6-function name (id) {
7- var n = h('span', id.substring(0, 10))
8-
9- //choose the most popular name for this person.
10- //for anything like this you'll see I have used sbot.links2
11- //which is the ssb-links plugin. as you'll see the query interface
12- //is pretty powerful!
13- //TODO: "most popular" name is easily gameable.
14- //must come up with something better than this.
15-
16- signifier(id, function (_, names) {
17- if(names.length) n.textContent = names[0].name
18- })
19-
20- return n
21-}
22-
modules/avatar-profile.jsView
@@ -1,74 +1,0 @@
1-var h = require('hyperscript')
2-var plugs = require('../plugs')
3-var pull = require('pull-stream')
4-
5-var avatar_image_link = plugs.first(exports.avatar_image_link = [])
6-var avatar_action = plugs.map(exports.avatar_action = [])
7-var avatar_edit = plugs.first(exports.avatar_edit = [])
8-
9-var follows = plugs.first(exports.follows = [])
10-var followers = plugs.first(exports.followers = [])
11-
12-function streamToList(stream, el) {
13- pull(
14- stream,
15- pull.drain(function (item) {
16- if(item) el.appendChild(item)
17- })
18- )
19- return el
20-}
21-
22-function image_link (id) {
23- return avatar_image_link(id, 'thumbnail')
24-}
25-
26-exports.avatar_profile = function (id) {
27-
28- var follows_el = h('div.profile__follows.wrap')
29- var friends_el = h('div.profile__friendss.wrap')
30- var followers_el = h('div.profile__followers.wrap')
31- var a, b
32-
33- pull(follows(id), pull.unique(), pull.collect(function (err, ary) {
34- a = ary || []; next()
35- }))
36- pull(followers(id), pull.unique(), pull.collect(function (err, ary) {
37- b = ary || {}; next()
38- }))
39-
40- function next () {
41- if(!(a && b)) return
42- var _c = [], _a = [], _b = []
43-
44- a.forEach(function (id) {
45- if(!~b.indexOf(id)) _a.push(id)
46- else _c.push(id)
47- })
48- b.forEach(function (id) {
49- if(!~_c.indexOf(id)) _b.push(id)
50- })
51- function add (ary, el) {
52- ary.forEach(function (id) { el.appendChild(image_link(id)) })
53- }
54-
55- add(_a, follows_el)
56- add(_c, friends_el)
57- add(_b, followers_el)
58- }
59-
60-
61- return h('div.column.profile',
62- avatar_edit(id),
63- avatar_action(id),
64- h('div.profile__relationships.column',
65- h('strong', 'follows'),
66- follows_el,
67- h('strong', 'friends'),
68- friends_el,
69- h('strong', 'followers'),
70- followers_el
71- )
72- )
73-}
74-
modules/avatar.jsView
@@ -1,23 +1,0 @@
1-var h = require('hyperscript')
2-var u = require('../util')
3-var plugs = require('../plugs')
4-
5-var avatar_name = plugs.first(exports.avatar_name = [])
6-var avatar_image = plugs.first(exports.avatar_image = [])
7-var avatar_link = plugs.first(exports.avatar_link = [])
8-
9-exports.avatar = function (author, classes) {
10- return exports.avatar_image_name_link(author, classes)
11-}
12-
13-exports.avatar_image_name_link = function (author, classes) {
14- return avatar_link(author, [
15- avatar_image(author, classes),
16- avatar_name(author)
17- ])
18-}
19-
20-exports.avatar_image_link = function (author, classes) {
21- return avatar_link(author, avatar_image(author, classes))
22-}
23-
modules/avatar_fallback.png
modules/avatar_fallback.png
modules/blob-url.jsView
@@ -1,9 +1,0 @@
1-var config = require('../config')
2-
3-exports.blob_url = function (link) {
4- if('string' == typeof link.link)
5- link = link.link
6- return config().blobsUrl + '/'+link
7-}
8-
9-
modules/channel.jsView
@@ -1,52 +1,0 @@
1-var h = require('hyperscript')
2-var u = require('../util')
3-var pull = require('pull-stream')
4-var Scroller = require('pull-scroll')
5-
6-var plugs = require('../plugs')
7-var message_render = plugs.first(exports.message_render = [])
8-var message_compose = plugs.first(exports.message_compose = [])
9-var sbot_log = plugs.first(exports.sbot_log = [])
10-var sbot_query = plugs.first(exports.sbot_query = [])
11-
12-exports.message_meta = function (msg) {
13- var chan = msg.value.content.channel
14- if (chan)
15- return h('a', {href: '##'+chan}, '#'+chan)
16-}
17-
18-exports.screen_view = function (path) {
19- if(path[0] === '#') {
20- var channel = path.substr(1)
21-
22- var content = h('div.column.scroller__content')
23- var div = h('div.column.scroller',
24- {style: {'overflow':'auto'}},
25- h('div.scroller__wrapper',
26- message_compose({type: 'post', channel: channel}),
27- content
28- )
29- )
30-
31- function matchesChannel(msg) {
32- if (msg.sync) console.error('SYNC', msg)
33- var c = msg && msg.value && msg.value.content
34- return c && c.channel === channel
35- }
36-
37- pull(
38- sbot_log({old: false}),
39- pull.filter(matchesChannel),
40- Scroller(div, content, message_render, true, false)
41- )
42-
43- pull(
44- sbot_query({reverse: true, query: [
45- {$filter: {value: {content: {channel: channel}}}}
46- ]}),
47- Scroller(div, content, message_render, false, false)
48- )
49-
50- return div
51- }
52-}
modules/compose.jsView
@@ -1,150 +1,0 @@
1-'use strict'
2-var h = require('hyperscript')
3-var u = require('../util')
4-var suggest = require('suggest-box')
5-var cont = require('cont')
6-var mentions = require('ssb-mentions')
7-var lightbox = require('hyperlightbox')
8-
9-var plugs = require('../plugs')
10-
11-//var suggest = plugs.map(exports.suggest = [])
12-var publish = plugs.first(exports.sbot_publish = [])
13-var message_content = plugs.first(exports.message_content = [])
14-var message_confirm = plugs.first(exports.message_confirm = [])
15-var file_input = plugs.first(exports.file_input = [])
16-
17-exports.suggest = []
18-
19-function id (e) { return e }
20-
21-/*
22- opts can take
23-
24- placeholder: string. placeholder text, defaults to "Write a message"
25- prepublish: function. called before publishing a message.
26- shrink: boolean. set to false, to make composer not shrink (or hide controls) when unfocused.
27-*/
28-
29-exports.message_compose = function (meta, opts, cb) {
30- if('function' === typeof cb) {
31- if('function' === typeof opts)
32- opts = {prepublish: opts}
33- }
34-
35- if(!opts) opts = {}
36- opts.prepublish = opts.prepublish || id
37-
38- var accessories
39- meta = meta || {}
40- if(!meta.type) throw new Error('message must have type')
41- var ta = h('textarea', {
42- placeholder: opts.placeholder || 'Write a message',
43- style: {height: opts.shrink === false ? '200px' : ''}
44- })
45-
46- if(opts.shrink !== false) {
47- var blur
48- ta.addEventListener('focus', function () {
49- clearTimeout(blur)
50- if(!ta.value) {
51- ta.style.height = '200px'
52- }
53- accessories.style.display = 'block'
54- })
55- ta.addEventListener('blur', function () {
56- //don't shrink right away, so there is time
57- //to click the publish button.
58- clearTimeout(blur)
59- blur = setTimeout(function () {
60- if(ta.value) return
61- ta.style.height = '50px'
62- accessories.style.display = 'none'
63- }, 200)
64- })
65- }
66-
67- ta.addEventListener('keydown', function (ev) {
68- if(ev.keyCode === 13 && ev.ctrlKey) publish()
69- })
70-
71- var files = []
72- var filesById = {}
73-
74- function publish() {
75- publishBtn.disabled = true
76- var content
77- try {
78- content = JSON.parse(ta.value)
79- } catch (err) {
80- meta.text = ta.value
81- meta.mentions = mentions(ta.value).map(function (mention) {
82- // merge markdown-detected mention with file info
83- var file = filesById[mention.link]
84- if (file) {
85- if (file.type) mention.type = file.type
86- if (file.size) mention.size = file.size
87- }
88- return mention
89- })
90- try {
91- meta = opts.prepublish(meta)
92- } catch (err) {
93- publishBtn.disabled = false
94- if (cb) cb(err)
95- else alert(err.message)
96- }
97- return message_confirm(meta, done)
98- }
99- message_confirm(content, done)
100-
101- function done (err, msg) {
102- publishBtn.disabled = false
103- if(err) return alert(err.stack)
104- else if (msg) ta.value = ''
105-
106- if (cb) cb(err, msg)
107- }
108- }
109-
110-
111- var publishBtn = h('button', 'Publish', {onclick: publish})
112- var composer =
113- h('div.compose', h('div.column', ta,
114- accessories = h('div.row.compose__controls',
115- //hidden until you focus the textarea
116- {style: {display: opts.shrink === false ? '' : 'none'}},
117- file_input(function (file) {
118- files.push(file)
119- filesById[file.link] = file
120-
121- var embed = file.type.indexOf('image/') === 0 ? '!' : ''
122- ta.value += embed + '['+file.name+']('+file.link+')'
123- console.log('added:', file)
124- }),
125- publishBtn)
126- )
127- )
128-
129- suggest(ta, function (word, cb) {
130- cont.para(exports.suggest.map(function (fn) {
131- return function (cb) { fn(word, cb) }
132- }))
133- (function (err, results) {
134- if(err) console.error(err)
135- results = results.reduce(function (ary, item) {
136- return ary.concat(item)
137- }, []).sort(function (a, b) {
138- return b.rank - a.rank
139- }).filter(Boolean)
140-
141- cb(null, results)
142- })
143- }, {})
144-
145- return composer
146-
147-}
148-
149-
150-
modules/crypto.jsView
@@ -1,48 +1,0 @@
1-var ref = require('ssb-ref')
2-var keys = require('../keys')
3-var ssbKeys = require('ssb-keys')
4-
5-function unbox_value(msg) {
6- var plaintext = ssbKeys.unbox(msg.content, keys)
7- if(!plaintext) return null
8- return {
9- previous: msg.previous,
10- author: msg.author,
11- sequence: msg.sequence,
12- timestamp: msg.timestamp,
13- hash: msg.hash,
14- content: plaintext,
15- private: true
16- }
17-}
18-
19-
20-var sbot_publish = require('../plugs').first(exports.sbot_publish = [])
21-
22-exports.message_unbox = function (msg) {
23- if(msg.value) {
24- var value = unbox_value(msg.value)
25- if(value)
26- return {
27- key: msg.key, value: value, timestamp: msg.timestamp
28- }
29- }
30- else
31- return unbox_value(msg)
32-}
33-
34-exports.message_box = function (content) {
35- return ssbKeys.box(content, content.recps.map(function (e) {
36- return ref.isFeed(e) ? e : e.link
37- }))
38-}
39-
40-exports.publish = function (content, id) {
41- if(content.recps)
42- content = exports.message_box(content)
43- sbot_publish(content, function (err, msg) {
44- if(err) throw err
45- console.log('PUBLISHED', msg)
46- })
47-}
48-
modules/feed.jsView
@@ -1,56 +1,0 @@
1-var ref = require('ssb-ref')
2-var ui = require('../ui')
3-var Scroller = require('pull-scroll')
4-var h = require('hyperscript')
5-var pull = require('pull-stream')
6-var u = require('../util')
7-
8-var plugs = require('../plugs')
9-var sbot_user_feed = plugs.first(exports.sbot_user_feed = [])
10-var message_render = plugs.first(exports.message_render = [])
11-var avatar_profile = plugs.first(exports.avatar_profile = [])
12-var signifier = plugs.first(exports.signifier = [])
13-
14-exports.screen_view = function (id) {
15- //TODO: header of user info, avatars, names, follows.
16-
17- if(ref.isFeed(id)) {
18-
19- var content = h('div.column.scroller__content')
20- var div = h('div.column.scroller',
21- {style: {'overflow':'auto'}},
22- h('div.scroller__wrapper',
23- h('div', avatar_profile(id)),
24- content
25- )
26- )
27-
28- signifier(id, function (_, names) {
29- if(names.length) div.title = names[0].name
30- })
31-
32-
33- pull(
34- sbot_user_feed({id: id, old: false, live: true}),
35- Scroller(div, content, message_render, true, false)
36- )
37-
38- //how to handle when have scrolled past the start???
39-
40- pull(
41- u.next(sbot_user_feed, {
42- id: id, reverse: true,
43- limit: 50, live: false
44- }, ['value', 'sequence']),
45- Scroller(div, content, message_render, false, false)
46- )
47-
48- return div
49-
50- }
51-}
52-
53-
54-
55-
56-
modules/file-input.jsView
@@ -1,37 +1,0 @@
1-var u = require('../util')
2-var h = require('hyperscript')
3-var pull = require('pull-stream')
4-var mime = require('simple-mime')('application/octect-stream')
5-var split = require('split-buffer')
6-
7-var plugs = require('../plugs')
8-
9-var add = plugs.first(exports.sbot_blobs_add = [])
10-
11-exports.file_input = function FileInput(onAdded) {
12-
13- return h('input', { type: 'file',
14- onchange: function (ev) {
15- var file = ev.target.files[0]
16- if (!file) return
17- var reader = new FileReader()
18- reader.onload = function () {
19- pull(
20- pull.values(split(new Buffer(reader.result), 64*1024)),
21- add(function (err, blob) {
22- if(err) return console.error(err)
23- onAdded({
24- link: blob,
25- name: file.name,
26- size: reader.result.length || reader.result.byteLength,
27- type: mime(file.name)
28- })
29-
30- })
31- )
32- }
33- reader.readAsArrayBuffer(file)
34- }
35- })
36-}
37-
modules/follow.jsView
@@ -1,84 +1,0 @@
1-var h = require('hyperscript')
2-var u = require('../util')
3-var plugs = require('../plugs')
4-var avatar = plugs.first(exports.avatar = [])
5-var avatar_name = plugs.first(exports.avatar_name = [])
6-var avatar_link = plugs.first(exports.avatar_link = [])
7-var pull = require('pull-stream')
8-var plugs = require('../plugs')
9-
10-//render a message when someone follows someone,
11-//so you see new users
12-function isRelated(value, name) {
13- return value ? name : value === false ? 'un'+name : ''
14-}
15-
16-exports.message_content =
17-exports.message_content_mini = function (msg) {
18- var content = msg.value.content
19- if(content.type == 'contact' && content.contact) {
20- var relation = isRelated(content.following, 'follows')
21- if(content.blocking) relation = 'blocks'
22- return [
23- relation, ' ',
24- avatar_link(content.contact, avatar_name(content.contact), '')
25- ]
26- }
27-}
28-
29-exports.message_content = function (msg) {
30-
31- var content = msg.value.content
32- if(content.type == 'contact' && content.contact) {
33- var relation = isRelated(content.following, 'follows')
34- if(content.blocking) relation = 'blocks'
35- return h('div.contact', relation, avatar(msg.value.content.contact, 'thumbnail'))
36- }
37-}
38-
39-var message_confirm = plugs.first(exports.message_confirm = [])
40-var follower_of = plugs.first(exports.follower_of = [])
41-
42-exports.avatar_action = function (id) {
43- var follows_you, you_follow
44-
45- var self_id = require('../keys').id
46- follower_of(self_id, id, function (err, f) {
47- you_follow = f
48- update()
49- })
50- follower_of(id, self_id, function (err, f) {
51- follows_you = f
52- update()
53- })
54-
55- var state = h('label')
56- var label = h('label')
57-
58- function update () {
59- state.textContent = (
60- follows_you && you_follow ? 'friend'
61- : follows_you ? 'follows you'
62- : you_follow ? 'you follow'
63- : ''
64- )
65-
66- label.textContent = you_follow ? 'unfollow' : 'follow'
67- }
68-
69- return h('div', state,
70- h('a', {href:'#', onclick: function () {
71- message_confirm({
72- type: 'contact',
73- contact: id,
74- following: !you_follow
75- }, function (err) {
76- //TODO: update after following.
77- })
78- }}, h('br'), label)
79- )
80-}
81-
82-
83-
84-
modules/git.jsView
@@ -1,473 +1,0 @@
1-var h = require('hyperscript')
2-var pull = require('pull-stream')
3-var paramap = require('pull-paramap')
4-var cat = require('pull-cat')
5-var human = require('human-time')
6-var combobox = require('hypercombo')
7-
8-var plugs = require('../plugs')
9-var message_link = plugs.first(exports.message_link = [])
10-var message_confirm = plugs.first(exports.message_confirm = [])
11-var message_compose = plugs.first(exports.message_compose = [])
12-var sbot_links = plugs.first(exports.sbot_links = [])
13-var sbot_links2 = plugs.first(exports.sbot_links2 = [])
14-var sbot_get = plugs.first(exports.sbot_get = [])
15-var getAvatar = require('ssb-avatar')
16-var avatar_name = plugs.first(exports.avatar_name = [])
17-var markdown = plugs.first(exports.markdown = [])
18-
19-var self_id = require('../keys').id
20-
21-function shortRefName(ref) {
22- return ref.replace(/^refs\/(heads|tags)\//, '')
23-}
24-
25-function getRefs(msg) {
26- var refs = {}
27- var commitTitles = {}
28- return pull(
29- sbot_links({
30- reverse: true,
31- source: msg.value.author,
32- dest: msg.key,
33- rel: 'repo',
34- values: true
35- }),
36- pull.map(function (link) {
37- var refUpdates = link.value.content.refs || {}
38- var commits = link.value.content.commits
39- if(commits) {
40- for(var i = 0; i < commits.length; i++) {
41- var commit = commits[i]
42- if(commit && commit.sha1 && commit.title) {
43- commitTitles[commit.sha1] = commit.title
44- }
45- }
46- }
47- return Object.keys(refUpdates).reverse().map(function (ref) {
48- if(refs[ref]) return
49- refs[ref] = true
50- var rev = refUpdates[ref]
51- if(!rev) return
52- return {
53- name: ref,
54- rev: rev,
55- link: link,
56- title: commitTitles[rev],
57- }
58- }).filter(Boolean)
59- }),
60- pull.flatten()
61- )
62-}
63-
64-function getForks(id) {
65- return pull(
66- sbot_links({
67- reverse: true,
68- dest: id,
69- rel: 'upstream'
70- }),
71- pull.map(function (link) {
72- return {
73- id: link.key,
74- author: link.source
75- }
76- })
77- )
78-}
79-
80-function repoText(id) {
81- var text = document.createTextNode(id.substr(0, 10) + '…')
82- getAvatar({links: sbot_links, get: sbot_get}, self_id, id,
83- function (err, avatar) {
84- if(err) return console.error(err)
85- text.nodeValue = avatar.name
86- })
87- return text
88-}
89-
90-function repoLink(id) {
91- return h('a', {href: '#'+id}, repoText(id))
92-}
93-
94-function repoName(id) {
95- return h('ins', repoText(id))
96-}
97-
98-function getIssueState(id, cb) {
99- pull(
100- sbot_links({dest: id, rel: 'issues', values: true, reverse: true}),
101- pull.map(function (msg) {
102- return msg.value.content.issues
103- }),
104- pull.flatten(),
105- pull.filter(function (issue) {
106- return issue.link === id
107- }),
108- pull.map(function (issue) {
109- return issue.merged ? 'merged' : issue.open ? 'open' : 'closed'
110- }),
111- pull.take(1),
112- pull.collect(function (err, updates) {
113- cb(err, updates && updates[0] || 'open')
114- })
115- )
116-}
117-
118-//todo:
119-function messageTimestampLink(msg) {
120- var date = new Date(msg.value.timestamp)
121- return h('a.timestamp', {
122- timestamp: msg.value.timestamp,
123- title: date,
124- href: '#'+msg.key
125- }, human(date))
126-}
127-
128-// a thead+tbody where the thead only is added when the first row is added
129-function tableRows(headerRow) {
130- var thead = h('thead'), tbody = h('tbody')
131- var first = true
132- var t = [thead, tbody]
133- t.append = function (row) {
134- if (first) {
135- first = false
136- thead.appendChild(headerRow)
137- }
138- tbody.appendChild(row)
139- }
140- return t
141-}
142-
143-function renderIssueEdit(c) {
144- var id = c.issue || c.link
145- return [
146- c.title ? h('p', 'renamed issue ', message_link(id),
147- ' to ', h('ins', c.title)) : null,
148- c.open === false ? h('p', 'closed issue ', message_link(id)) : null,
149- c.open === true ? h('p', 'reopened issue ', message_link(id)) : null]
150-}
151-
152-exports.message_content = function (msg, sbot) {
153- var c = msg.value.content
154-
155- if(c.type === 'git-repo') {
156- var branchesT, tagsT, openIssuesT, closedIssuesT, openPRsT, closedPRsT
157- var forksT
158- var div = h('div',
159- h('p', 'git repo ', repoName(msg.key)),
160- c.upstream ? h('p', 'fork of ', repoLink(c.upstream)) : '',
161- h('p', h('code', 'ssb://' + msg.key)),
162- h('div.git-table-wrapper', {style: {'max-height': '12em'}},
163- h('table',
164- branchesT = tableRows(h('tr',
165- h('th', 'branch'),
166- h('th', 'commit'),
167- h('th', 'last update'))),
168- tagsT = tableRows(h('tr',
169- h('th', 'tag'),
170- h('th', 'commit'),
171- h('th', 'last update'))))),
172- h('div.git-table-wrapper', {style: {'max-height': '16em'}},
173- h('table',
174- openIssuesT = tableRows(h('tr',
175- h('th', 'open issues'))),
176- closedIssuesT = tableRows(h('tr',
177- h('th', 'closed issues'))))),
178- h('div.git-table-wrapper', {style: {'max-height': '16em'}},
179- h('table',
180- openPRsT = tableRows(h('tr',
181- h('th', 'open pull requests'))),
182- closedPRsT = tableRows(h('tr',
183- h('th', 'closed pull requests'))))),
184- h('div.git-table-wrapper',
185- h('table',
186- forksT = tableRows(h('tr',
187- h('th', 'forks'))))),
188- h('div', h('a', {href: '#', onclick: function (e) {
189- e.preventDefault()
190- this.parentNode.replaceChild(issueForm(msg), this)
191- }}, 'New Issue…')),
192- h('div', h('a', {href: '#', onclick: function (e) {
193- e.preventDefault()
194- this.parentNode.replaceChild(pullRequestForm(msg), this)
195- }}, 'New Pull Request…')))
196-
197- pull(getRefs(msg), pull.drain(function (ref) {
198- var parts = /^refs\/(heads|tags)\/(.*)$/.exec(ref.name) || []
199- var t
200- if(parts[1] === 'heads') t = branchesT
201- else if(parts[1] === 'tags') t = tagsT
202- if(t) t.append(h('tr',
203- h('td', parts[2]),
204- h('td', h('code', ref.rev)),
205- h('td', messageTimestampLink(ref.link))))
206- }, function (err) {
207- if(err) console.error(err)
208- }))
209-
210- // list issues and pull requests
211- pull(
212- sbot_links({
213- reverse: true,
214- dest: msg.key,
215- rel: 'project',
216- values: true
217- }),
218- paramap(function (link, cb) {
219- getIssueState(link.key, function (err, state) {
220- if(err) return cb(err)
221- link.state = state
222- cb(null, link)
223- })
224- }),
225- pull.drain(function (link) {
226- var c = link.value.content
227- var title = c.title || (c.text ? c.text.length > 70
228- ? c.text.substr(0, 70) + '…'
229- : c.text : link.key)
230- var author = link.value.author
231- var t = c.type === 'pull-request'
232- ? link.state === 'open' ? openPRsT : closedPRsT
233- : link.state === 'open' ? openIssuesT : closedIssuesT
234- t.append(h('tr',
235- h('td',
236- h('a', {href: '#'+link.key}, title), h('br'),
237- h('small',
238- 'opened ', messageTimestampLink(link),
239- ' by ', h('a', {href: '#'+author}, avatar_name(author))))))
240- }, function (err) {
241- if (err) console.error(err)
242- })
243- )
244-
245- // list forks
246- pull(
247- getForks(msg.key),
248- pull.drain(function (fork) {
249- forksT.append(h('tr', h('td',
250- repoLink(fork.id),
251- ' by ', h('a', {href: '#'+fork.author}, avatar_name(fork.author)))))
252- }, function (err) {
253- if (err) console.error(err)
254- })
255- )
256-
257- return div
258- }
259-
260- if(c.type === 'git-update') {
261- return [
262- h('p', 'pushed to ', repoLink(c.repo)),
263- c.refs ? h('ul', Object.keys(c.refs).map(function (ref) {
264- var rev = c.refs[ref]
265- return h('li',
266- shortRefName(ref) + ': ',
267- rev ? h('code', rev) : h('em', 'deleted'))
268- })) : null,
269- Array.isArray(c.commits) ? [
270- h('ul',
271- c.commits.map(function (commit) {
272- return h('li',
273- typeof commit.sha1 === 'string' ?
274- [h('code', commit.sha1.substr(0, 8)), ' '] : null,
275- commit.title ?
276- h('q', commit.title) : null)
277- }),
278- c.commits_more > 0 ?
279- h('li', '+ ', c.commits_more, ' more') : null)
280- ] : null,
281- Array.isArray(c.issues) ? c.issues.map(function (issue) {
282- if (issue.merged === true)
283- return h('p', 'Merged ', message_link(issue.link), ' in ',
284- h('code', issue.object), ' ', h('q', issue.label))
285- if (issue.open === false)
286- return h('p', 'Closed ', message_link(issue.link), ' in ',
287- h('code', issue.object), ' ', h('q', issue.label))
288- }) : null
289- ]
290- }
291-
292- if(c.type === 'issue-edit') {
293- return h('div',
294- c.issue ? renderIssueEdit(c) : null,
295- c.issues ? c.issues.map(renderIssueEdit) : null)
296- }
297-
298- if(c.type === 'issue') {
299- return h('div',
300- h('p', 'opened issue on ', repoLink(c.project)),
301- c.title ? h('h4', c.title) : '',
302- markdown(c)
303- )
304- }
305-
306- if(c.type === 'pull-request') {
307- return h('div',
308- h('p', 'opened pull-request ',
309- 'to ', repoLink(c.repo), ':', c.branch, ' ',
310- 'from ', repoLink(c.head_repo), ':', c.head_branch),
311- c.title ? h('h4', c.title) : '',
312- markdown(c)
313- )
314- }
315-}
316-
317-exports.message_meta = function (msg, sbot) {
318- var type = msg.value.content.type
319- if (type === 'issue' || type === 'pull-request') {
320- var el = h('em', '...')
321- // TODO: update if issue is changed
322- getIssueState(msg.key, function (err, state) {
323- if (err) return console.error(err)
324- el.textContent = state
325- })
326- return el
327- }
328-}
329-
330-function findMessageContent(el) {
331- for(; el; el = el.parentNode) {
332- if(el.classList.contains('message')) {
333- return el.querySelector('.message_content')
334- }
335- }
336-}
337-
338-function issueForm(msg, contentEl) {
339- var form = h('form',
340- h('strong', 'New Issue:'),
341- message_compose(
342- {type: 'issue', project: msg.key},
343- function (value) { return value },
344- function (err, issue) {
345- if(err) return alert(err)
346- if(!issue) return
347- var title = issue.value.content.text
348- if(title.length > 70) title = title.substr(0, 70) + '…'
349- form.appendChild(h('div',
350- h('a', {href: '#'+issue.key}, title)
351- ))
352- }
353- )
354- )
355- return form
356-}
357-
358-function branchMenu(msg, full) {
359- return combobox({
360- style: {'max-width': '14ex'},
361- placeholder: 'branch…',
362- default: 'master',
363- read: msg && pull(getRefs(msg), pull.map(function (ref) {
364- var m = /^refs\/heads\/(.*)$/.exec(ref.name)
365- if(!m) return
366- var branch = m[1]
367- var label = branch
368- if(full) {
369- var updated = new Date(ref.link.value.timestamp)
370- label = branch +
371- ' · ' + human(updated) +
372- ' · ' + ref.rev.substr(1, 8) +
373- (ref.title ? ' · "' + ref.title + '"' : '')
374- }
375- return h('option', {value: branch}, label)
376- }))
377- })
378-}
379-
380-function pullRequestForm(msg) {
381- var headRepoInput
382- var headBranchInput = branchMenu()
383- var branchInput = branchMenu(msg)
384- var form = h('form',
385- h('strong', 'New Pull Request:'),
386- h('div',
387- 'from ',
388- headRepoInput = combobox({
389- style: {'max-width': '26ex'},
390- onchange: function () {
391- // list branches for selected repo
392- var repoId = this.value
393- if(repoId) sbot_get(repoId, function (err, value) {
394- if(err) console.error(err)
395- var msg = value && {key: repoId, value: value}
396- headBranchInput = headBranchInput.swap(branchMenu(msg, true))
397- })
398- else headBranchInput = headBranchInput.swap(branchMenu())
399- },
400- read: pull(cat([
401- pull.once({id: msg.key, author: msg.value.author}),
402- getForks(msg.key)
403- ]), pull.map(function (fork) {
404- return h('option', {value: fork.id},
405- repoLink(fork.id), ' by ', avatar_name(fork.author))
406- }))
407- }),
408- ':',
409- headBranchInput,
410- ' to ',
411- repoName(msg.key),
412- ':',
413- branchInput),
414- message_compose(
415- {
416- type: 'pull-request',
417- project: msg.key,
418- repo: msg.key,
419- },
420- function (value) {
421- value.branch = branchInput.value
422- value.head_repo = headRepoInput.value
423- value.head_branch = headBranchInput.value
424- return value
425- },
426- function (err, issue) {
427- if(err) return alert(err)
428- if(!issue) return
429- var title = issue.value.content.text
430- if(title.length > 70) title = title.substr(0, 70) + '…'
431- form.appendChild(h('div',
432- h('a', {href: '#'+issue.key}, title)
433- ))
434- }
435- )
436- )
437- return form
438-}
439-
440-exports.message_action = function (msg, sbot) {
441- var c = msg.value.content
442- if(c.type === 'issue' || c.type === 'pull-request') {
443- var isOpen
444- var a = h('a', {href: '#', onclick: function (e) {
445- e.preventDefault()
446- message_confirm({
447- type: 'issue-edit',
448- root: msg.key,
449- issues: [{
450- link: msg.key,
451- open: !isOpen
452- }]
453- }, function (err, msg) {
454- if(err) return alert(err)
455- if(!msg) return
456- isOpen = msg.value.content.open
457- update()
458- })
459- }})
460- getIssueState(msg.key, function (err, state) {
461- if (err) return console.error(err)
462- isOpen = state === 'open'
463- update()
464- })
465- function update() {
466- a.textContent = c.type === 'pull-request'
467- ? isOpen ? 'Close Pull Request' : 'Reopen Pull Request'
468- : isOpen ? 'Close Issue' : 'Reopen Issue'
469- }
470- return a
471- }
472-}
473-
modules/index.jsView
@@ -1,8 +1,0 @@
1-var fs = require('fs')
2-
3-fs.readdirSync(__dirname).forEach(function (e) {
4- if(e !== '_index.js' && /\js$/.test(e))
5- exports[e] = require('./'+e)
6-})
7-
8-
modules/invite.jsView
@@ -1,112 +1,0 @@
1-
2-var ref = require('ssb-ref')
3-var ssbClient = require('ssb-client')
4-var id = require('../keys').id
5-var h = require('hyperscript')
6-
7-var Progress = require('hyperprogress')
8-
9-var plugs = require('../plugs')
10-var sbot_publish = plugs.first(exports.sbot_publish = [])
11-var sbot_gossip_connect = plugs.first(exports.sbot_gossip_connect = [])
12-var follower_of = plugs.first(exports.follower_of = [])
13-
14-exports.invite_parse = function (invite) {
15- return ref.parseInvite(invite)
16-}
17-
18-exports.invite_accept = function (invite, onProgress, cb) {
19- var data = exports.invite_parse(invite)
20- if(!data) return cb(new Error('not a valid invite code:' + invite))
21-
22- onProgress('connecting...')
23-
24- sbot_gossip_connect(data.remote, function (err) {
25- if(err) console.log(err)
26- })
27-
28- ssbClient(null, {
29- remote: data.invite,
30- manifest: { invite: {use: 'async'}, getAddress: 'async' }
31- }, function (err, sbot) {
32- if(err) return cb(err)
33- onProgress('requesting follow...')
34- console.log(sbot)
35- sbot.invite.use({feed: id}, function (err, msg) {
36-
37- //if they already follow us, just check we actually follow them.
38- if(err) follower_of(id, data.key, function (_err, follows) {
39- if(follows) cb(err)
40- else next()
41- })
42- else next()
43-
44- function next () {
45- onProgress('following...')
46-
47- //remove the seed from the shs address.
48- //then it's correct address.
49- //this should make the browser connect to this as remote.
50- //we don't want to do this if when using this locally, though.
51- if(process.title === 'browser')
52- localStorage.remote = data.remote
53-
54- sbot_publish({
55- type: 'contact',
56- contact: data.key,
57- following: true,
58- }, cb)
59- }
60- })
61- })
62-}
63-
64-exports.screen_view = function (invite) {
65-
66- var data = ref.parseInvite(invite)
67- if(!data) return
68-
69- var progress = Progress(4)
70-
71- //connect to server
72- //request follow
73- //post pub announce
74- //post follow pub
75- var div = h('div.column',
76- h('div',
77- "you have been invited to join:", h('br'),
78- h('code', data.invite)
79- ),
80- h('button', 'accept', {onclick: attempt}),
81- progress
82- )
83-
84- function attempt () {
85- exports.invite_accept(invite, function (message) {
86- progress.next(message)
87- }, function (err) {
88- if(err) return progress.fail(err)
89- progress.complete()
90- //check for redirect
91- var parts = location.hash.substring(1).split('#')
92-
93- //TODO: handle in a consistent way with either hashrouting
94- //or with tabs...
95- if(parts[0] === data.invite)
96- location.hash = data.redirect
97- else
98- console.log("NO REDIRECT")
99- })
100- }
101-
102- // If we are in the browser,
103- // and do not already have a remote set, automatically trigger the invite.
104- if(process.title == 'browser' && !localStorage.remote) attempt()
105-
106- return div
107-}
108-
109-
110-
111-
112-
modules/like.jsView
@@ -1,62 +1,0 @@
1-
2-var h = require('hyperscript')
3-var u = require('../util')
4-var pull = require('pull-stream')
5-
6-var plugs = require('../plugs')
7-
8-var message_confirm = plugs.first(exports.message_confirm = [])
9-var message_link = plugs.first(exports.message_link = [])
10-var sbot_links = plugs.first(exports.sbot_links = [])
11-
12-
13-exports.message_content =
14-exports.message_content_mini = function (msg, sbot) {
15- if(msg.value.content.type !== 'vote') return
16- var link = msg.value.content.vote.link
17- return [
18- msg.value.content.vote.value > 0 ? 'dug' : 'undug',
19- ' ', message_link(link)
20- ]
21-}
22-
23-exports.message_meta = function (msg, sbot) {
24- var digs = h('a')
25-
26- var votes = []
27- for(var k in CACHE) {
28- if(CACHE[k].content.type == 'vote' &&
29- (CACHE[k].content.vote == msg.key ||
30- CACHE[k].content.vote.link == msg.key
31- ))
32- votes.push({source: CACHE[k].author, dest: k, rel: 'vote'})
33- }
34-
35- if(votes.length === 1)
36- digs.textContent = ' 1 Dig'
37- if(votes.length > 1)
38- digs.textContent = ' ' + votes.length + ' Digs'
39-
40- return digs
41-}
42-
43-exports.message_action = function (msg, sbot) {
44- if(msg.value.content.type !== 'vote')
45- return h('a.dig', {href: '#', onclick: function () {
46- var dig = {
47- type: 'vote',
48- vote: { link: msg.key, value: 1, expression: 'Dig' }
49- }
50- if(msg.value.content.recps) {
51- dig.recps = msg.value.content.recps.map(function (e) {
52- return e && typeof e !== 'string' ? e.link : e
53- })
54- dig.private = true
55- }
56- //TODO: actually publish...
57-
58- message_confirm(dig)
59- }}, 'Dig')
60-
61-}
62-
modules/markdown.jsView
@@ -1,31 +1,0 @@
1-var markdown = require('ssb-markdown')
2-var h = require('hyperscript')
3-var ref = require('ssb-ref')
4-//
5-
6-var blob_url = require('../plugs').first(exports.blob_url = [])
7-
8-exports.markdown = function (content) {
9- if('string' === typeof content)
10- content = {text: content}
11- //handle patchwork style mentions.
12- var mentions = {}
13- if(Array.isArray(content.mentions))
14- content.mentions.forEach(function (link) {
15- if(link.name) mentions["@"+link.name] = link.link
16- })
17-
18- var md = h('div.markdown')
19- md.innerHTML = markdown.block(content.text, {
20- toUrl: function (id) {
21- if(ref.isBlob(id)) return blob_url(id)
22- return '#'+(mentions[id]?mentions[id]:id)
23- }
24- })
25-
26- return md
27-
28-}
29-
30-
31-
modules/menu.jsView
@@ -1,31 +1,0 @@
1-var plugs = require('../plugs')
2-var h = require('hyperscript')
3-
4-var menu_items = plugs.map(exports.menu_items = [])
5-
6-var status = h('div.status.error') //start off disconnected
7- var list = h('div.menu.column', {style: 'display: none;'})
8-
9-var menu = h('div.column', status, list , {
10- onmouseover: function (e) {
11- list.style.display = 'flex'
12- }, onmouseout: function () {
13- list.style.display = 'none'
14- }
15-})
16-
17-exports.connection_status = function (err) {
18- if(err) status.classList.add('error')
19- else status.classList.remove('error')
20-}
21-
22-exports.menu = function () {
23- menu_items().forEach(function (el) {
24- list.appendChild(el)
25- })
26-
27- return menu
28-}
29-
30-
31-
modules/message-confirm.jsView
@@ -1,61 +1,0 @@
1-var lightbox = require('hyperlightbox')
2-var h = require('hyperscript')
3-var u = require('../util')
4-var self_id = require('../keys').id
5-//publish or add
6-
7-var plugs = require('../plugs')
8-
9-var publish = plugs.first(exports.sbot_publish = [])
10-var message_content = plugs.first(exports.message_content = [])
11-var avatar = plugs.first(exports.avatar = [])
12-var message_meta = plugs.map(exports.message_meta = [])
13-
14-exports.message_confirm = function (content, cb) {
15-
16- cb = cb || function () {}
17-
18- var lb = lightbox()
19- document.body.appendChild(lb)
20-
21- var msg = {
22- key: "DRAFT",
23- value: {
24- author: self_id,
25- previous: null,
26- sequence: null,
27- timestamp: Date.now(),
28- content: content
29- }
30- }
31-
32- var okay = h('button', 'okay', {onclick: function () {
33- lb.remove()
34- publish(content, cb)
35- }})
36-
37- var cancel = h('button', 'Cancel', {onclick: function () {
38- lb.remove()
39- cb(null)
40- }})
41-
42- okay.addEventListener('keydown', function (ev) {
43- if(ev.keyCode === 27) cancel.click() //escape
44- })
45-
46- lb.show(h('div.column.message-confirm',
47- h('div.message',
48- h('div.title.row',
49- h('div.avatar', avatar(msg.value.author, 'thumbnail')),
50- h('div.message_meta.row', message_meta(msg))
51- ),
52- h('div.message_content', message_content(msg)
53- || h('pre', JSON.stringify(msg, null, 2)))
54- ),
55- h('div.row.message-confirm__controls', okay, cancel)
56- ))
57-
58- okay.focus()
59-
60-}
61-
modules/message-link.jsView
@@ -1,33 +1,0 @@
1-var h = require('hyperscript')
2-var ref = require('ssb-ref')
3-
4-var first = require('../plugs').first
5-var sbot_get = first(exports.sbot_get = [])
6-var message_name = first(exports.message_name = [])
7-
8-exports.message_link = function (id) {
9-
10- if('string' !== typeof id)
11- throw new Error('link must be to message id')
12-
13- var link = h('a', {href: '#'+id}, id.substring(0, 10)+'...')
14-
15- if(ref.isMsg(id))
16- message_name(id, function (err, name) {
17- if(err) console.error(err)
18- else link.textContent = name
19- })
20-
21- return link
22-}
23-
24-
25-
26-
27-
28-
29-
30-
31-
32-
33-
modules/message-name.jsView
@@ -1,15 +1,0 @@
1-
2-var sbot_get = require('../plugs').first(exports.sbot_get = [])
3-
4-exports.message_name = function (id, cb) {
5- sbot_get(id, function (err, value) {
6- if(err && err.name == 'NotFoundError')
7- return cb(null, id.substring(0, 10)+'...(missing)')
8- if(value.content.type === 'post' && 'string' === typeof value.content.text)
9- return cb(null, value.content.text.substring(0, 40)+'...')
10- else if('string' === typeof value.content.text)
11- return cb(null, value.content.type + ':'+value.content.text.substring(0, 20))
12- else
13- return cb(null, id.substring(0, 10)+'...')
14- })
15-}
modules/message.jsView
@@ -1,98 +1,0 @@
1-var h = require('hyperscript')
2-var u = require('../util')
3-var pull = require('pull-stream')
4-
5-var plugs = require('../plugs')
6-var message_content = plugs.first(exports.message_content = [])
7-var message_content_mini = plugs.first(exports.message_content_mini = [])
8-var avatar = plugs.first(exports.avatar = [])
9-var avatar_name = plugs.first(exports.avatar_name = [])
10-var avatar_link = plugs.first(exports.avatar_link = [])
11-var message_meta = plugs.map(exports.message_meta = [])
12-var message_action = plugs.map(exports.message_action = [])
13-var message_link = plugs.first(exports.message_link = [])
14-
15-var sbot_links = plugs.first(exports.sbot_links = [])
16-
17-exports.message_render = function (msg, sbot) {
18- var elMini = message_content_mini(msg)
19- if (elMini) {
20- var div = h('div.message.message--mini',
21- h('div.row',
22- h('div',
23- avatar_link(msg.value.author, avatar_name(msg.value.author)),
24- h('span.message_content', elMini)),
25- h('div.message_meta.row', message_meta(msg))
26- )
27- )
28- div.setAttribute('tabindex', '0')
29- return div
30- }
31-
32- var el = message_content(msg)
33- if(!el) return
34-
35- var links = []
36- for(var k in CACHE) {
37- var _msg = CACHE[k]
38- if(Array.isArray(_msg.content.mentions)) {
39- for(var i = 0; i < _msg.content.mentions.length; i++)
40- if(_msg.content.mentions[i].link == msg.key)
41- links.push(k)
42- }
43- }
44-
45- var backlinks = h('div.backlinks')
46- if(links.length)
47- backlinks.appendChild(h('label', 'backlinks:',
48- h('div', links.map(function (key) {
49- return message_link(key)
50- }))
51- ))
52-
53-
54-// pull(
55-// sbot_links({dest: msg.key, rel: 'mentions', keys: true}),
56-// pull.collect(function (err, links) {
57-// if(links.length)
58-// backlinks.appendChild(h('label', 'backlinks:',
59-// h('div', links.map(function (link) {
60-// return message_link(link.key)
61-// }))
62-// ))
63-// })
64-// )
65-
66- var msg = h('div.message',
67- h('div.title.row',
68- h('div.avatar', avatar(msg.value.author, 'thumbnail')),
69- h('div.message_meta.row', message_meta(msg))
70- ),
71- h('div.message_content', el),
72- h('div.message_actions.row',
73- h('div.actions', message_action(msg),
74- h('a', {href: '#' + msg.key}, 'Reply')
75- )
76- ),
77- backlinks,
78- {onkeydown: function (ev) {
79- //on enter, hit first meta.
80- if(ev.keyCode == 13) {
81- msg.querySelector('.enter').click()
82- }
83- }}
84- )
85-
86- // ); hyperscript does not seem to set attributes correctly.
87- msg.setAttribute('tabindex', '0')
88-
89- return msg
90-}
91-
92-
93-
94-
95-
96-
97-
98-
modules/meta-image.jsView
@@ -1,48 +1,0 @@
1-var markdown = require('ssb-markdown');
2-var h = require('hyperscript');
3-var u = require('../util');
4-var ref = require('ssb-ref');
5-
6-//render a message
7-
8-var plugs = require('../plugs');
9-var message_link = plugs.first(exports.message_link = []);
10-var message_confirm = plugs.first(exports.message_confirm = []);
11-var sbot_links = plugs.first(exports.sbot_links = []);
12-var blob_url = plugs.first(exports.blob_url = []);
13-
14-exports.message_content = function(msg, sbot) {
15- if (msg.value.content.type !== 'meta-image')
16- return;
17-
18- var v = msg.value.content;
19- return h('div',
20- // h('h2', "(" + v.Track + ") " + v.Title),
21- h('img', { "src" : blob_url(v.link) }))
22-
23- // h('dl',
24- // Object.keys(v).map(function(k) {
25- // return [
26- // h("dt", k),
27- // h("dd", v[k]),
28- // ]
29- // })))
30-
31- // "Album": "the fall of",
32- // "Crc32": "038becab",
33- // "Creator": "bleupulp",
34- // "Format": "VBR MP3",
35- // "Height": "0",
36- // "Length": "375.23",
37- // "Md5": "2c517c8e813da5f940c8c7e77d4b7f3f",
38- // "Mtime": "1399498698",
39- // "Name": "2_bleupulp_-_clouds.mp3",
40- // "Sha1": "9f6a96a3d5571ed1ec2a7da38ffebdcd5f181482",
41- // "Size": "15009000",
42-
43- // "Title": "clouds",
44- // "Track": "2",
45- // "Width": "0",
46-
47-}
48-
modules/music-release-cc.jsView
@@ -1,80 +1,0 @@
1-var markdown = require('ssb-markdown');
2-var h = require('hyperscript');
3-var u = require('../util');
4-var ref = require('ssb-ref');
5-
6-//render a message
7-
8-var plugs = require('../plugs');
9-var message_link = plugs.first(exports.message_link = []);
10-var message_confirm = plugs.first(exports.message_confirm = []);
11-var sbot_links = plugs.first(exports.sbot_links = []);
12-var blob_url = plugs.first(exports.blob_url = []);
13-
14-exports.message_content = function(msg, sbot) {
15- if (msg.value.content.type !== 'music-release-cc')
16- return;
17-
18- var tracks = msg.value.content.tracks;
19- return h('div',
20- h('img', { "src" : blob_url(msg.value.content.cover) }),
21- h('h1', msg.value.content.title),
22- h('ol',
23- Object.keys(tracks).map(function(k) {
24- var t = tracks[k];
25- return h('li', t.fname,
26- h("br"),
27- h('audio', {
28- "controls" : true,
29- "src" : blob_url(t.link)
30- }))
31- })),
32- h('p',
33- "More info:", h('a', { href : msg.value.content.archivedotorg }, "archive.org"),
34- h("br"),
35- "License:", h('a', { href : msg.value.content.license }, "Link")))
36-}
37-
38-// copied from like.js
39-
40-// inspiration for waveform range selection
41-
42-// idea: handout invite codes for upload of tracks to be cached by the pub
43-
44-// exports.message_meta = function (msg, sbot) {
45-
46-// var yupps = h('a')
47-
48-// pull(
49-// sbot_links({dest: msg.key, rel: 'vote'}),
50-// pull.collect(function (err, votes) {
51-// if(votes.length === 1)
52-// yupps.textContent = ' 1 yup'
53-// if(votes.length)
54-// yupps.textContent = ' ' + votes.length + ' yupps'
55-// })
56-// )
57-
58-// return yupps
59-// }
60-
61-// exports.message_action = function (msg, sbot) {
62-// if(msg.value.content.type !== 'vote')
63-// return h('a', {href: '#', onclick: function () {
64-// var yup = {
65-// type: 'vote',
66-// vote: { link: msg.key, value: 1, expression: 'yup' }
67-// }
68-// if(msg.value.content.recps) {
69-// yup.recps = msg.value.content.recps.map(function (e) {
70-// return e && typeof e !== 'string' ? e.link : e
71-// })
72-// yup.private = true
73-// }
74-// //TODO: actually publish...
75-
76-// message_confirm(yup)
77-// }}, 'yup')
78-
79-// }
80-
modules/music-release.jsView
@@ -1,41 +1,0 @@
1-var markdown = require('ssb-markdown');
2-var h = require('hyperscript');
3-var u = require('../util');
4-var ref = require('ssb-ref');
5-
6-//render a message
7-
8-var plugs = require('../plugs');
9-var message_link = plugs.first(exports.message_link = []);
10-var message_confirm = plugs.first(exports.message_confirm = []);
11-var sbot_links = plugs.first(exports.sbot_links = []);
12-
13-exports.message_content = function(msg, sbot) {
14- if (msg.value.content.type !== 'music-release')
15- return;
16-
17- var v = msg.value.content;
18- return h('div',
19- // h('img', { "src" : "http://localhost:7777/" + encodeURIComponent(v.cover) }),
20- h('h1', v.Title),
21- h("p", v.Description),
22- h("dl",
23-
24- h("dt", "Creator"),
25- h("dd", v.Creator),
26-
27- h("dt", "Identifier"),
28- h("dd", v.Identifier),
29-
30- h("dt", "Published"),
31- h("dd", v.Publicdate),
32-
33- h("dt", "Runtime"),
34- h("dd", v.Runtime),
35-
36- h("dt", "Source"),
37- h("dd", v.Source),
38-
39- h("dt", "License"),
40- h("dd", h('a', { href : v.Licenseurl }, "Link"))))
41-}
modules/names.jsView
@@ -1,148 +1,0 @@
1-var pull = require('pull-stream')
2-var many = require('pull-many')
3-var mfr = require('map-filter-reduce')
4-
5-function all(stream, cb) {
6- pull(stream, pull.collect(cb))
7-}
8-
9-var plugs = require('../plugs')
10-var sbot_links2 = plugs.first(exports.sbot_links2 = [])
11-var sbot_query = plugs.first(exports.sbot_query = [])
12-
13-/*
14- filter(rel: ['mentions', prefix('@')]) | reduce(name: rel[1], value: count())
15-*/
16-
17-var filter = {
18- $filter: {
19- rel: ["mentions", {$prefix: "@"}]
20- }
21-}
22-var map = {
23- $map: {
24- name: ['rel', 1],
25- id: 'dest',
26- ts: 'ts',
27- }
28-}
29-
30-var reduce = {
31- $reduce: {
32- name: 'name',
33- id: 'id',
34- rank: {$count: true},
35- ts: {$max: 'ts'}
36- }
37-}
38-
39-var filter2 = {
40- $filter: {
41- value: {
42- content: {
43- type: "about",
44- name: {"$prefix": ""},
45- about: {"$prefix": "@"} //better: match regexp.
46- }
47- }
48- }
49-}
50-
51-var map2 = {
52- $map: {
53- name: ["value", "content", "name"],
54- id: ['value', 'content', 'about'],
55- ts: "timestamp"
56- }
57-}
58-
59-//union with this query...
60-
61-var names = NAMES = []
62-function update(name) {
63- var n = names.find(function (e) {
64- return e.id == name.id && e.name == e.name
65- })
66- if(!n) {
67- name.rank = 1
68- //this should be inserted at the right place...
69- names.push(name)
70- }
71- else
72- n.rank = n.rank += (name.rank || 1)
73-}
74-
75-var ready = false, waiting = []
76-
77-var merge = {
78- $reduce: {
79- name: 'name',
80- id: 'id',
81- rank: {$sum: 'rank'},
82- ts: {$max: 'ts'}
83- }
84-}
85-
86-function add_at(stream) {
87- return pull(stream, pull.map(function (e) {
88- if(!/^@/.test(e.name)) e.name = '@'+e.name
89- return e
90- })
91- )
92-}
93-
94-exports.connection_status = function (err) {
95- if(!err) {
96- pull(
97- many([
98- sbot_links2({query: [filter, map, reduce]}),
99- add_at(sbot_query({query: [filter2, map2, reduce]}))
100- ]),
101- //reducing also ensures order by the lookup properties
102- //in this case: [name, id]
103- mfr.reduce(merge),
104- pull.collect(function (err, ary) {
105- if(!err) {
106- NAMES = names = ary
107- ready = true
108- while(waiting.length) waiting.shift()()
109- }
110- })
111- )
112-
113- pull(many([
114- sbot_links2({query: [filter, map], old: false}),
115- add_at(sbot_query({query: [filter2, map2], old: false}))
116- ]),
117- pull.drain(update))
118- }
119-}
120-
121-function async(fn) {
122- return function (value, cb) {
123- function go () { cb(null, fn(value)) }
124- if(ready) go()
125- else waiting.push(go)
126- }
127-}
128-
129-function rank(ary) {
130- //sort by most used, or most recently used
131- return ary.sort(function (a, b) { return b.rank - a.rank || b.ts - a.ts })
132-}
133-
134-//we are just iterating over the entire array.
135-//if this becomes a problem, maintain two arrays
136-//one of each sort order, but do not duplicate the objects.
137-//that should mean the space required is just 2x object references,
138-//not 2x objects, and we can use binary search to find matches.
139-
140-exports.signifier = async(function (id) {
141- return rank(names.filter(function (e) { return e.id == id}))
142-})
143-
144-exports.signified = async(function (name) {
145- var rx = new RegExp('^'+name)
146- return rank(names.filter(function (e) { return rx.test(e.name) }))
147-})
148-
modules/network.jsView
@@ -1,146 +1,0 @@
1-var isVisible = require('is-visible').isVisible
2-var h = require('hyperscript')
3-var plugs = require('../plugs')
4-
5-var avatar = plugs.first(exports.avatar = [])
6-var sbot_gossip_peers = plugs.first(exports.sbot_gossip_peers = [])
7-var sbot_gossip_connect = plugs.first(exports.sbot_gossip_connect = [])
8-//sbot_gossip_connect
9-//sbot_gossip_add
10-
11-var human = require('human-time')
12-
13-function legacyToMultiServer(addr) {
14- return 'net:'+addr.host + ':'+addr.port + '~shs:'+addr.key.substring(1).replace('.ed25519','')
15-}
16-
17-exports.menu_items = function () {
18- return h('a', {href: '#/network'}, '/network')
19-}
20-
21-//types of peers
22-
23-
24-//on the same wifi network
25-function isLocal (e) {
26- // don't rely on private ip address, because
27- // cjdns creates fake private ip addresses.
28- return ip.isPrivate(e.host) && e.type === 'local'
29-}
30-
31-
32-//pub is running scuttlebot >=8
33-//have connected successfully.
34-function isLongterm (e) {
35- return e.ping && e.ping.rtt && e.ping.rtt.mean > 0
36-}
37-
38-//pub is running scuttlebot < 8
39-//have connected sucessfully
40-function isLegacy (peer) {
41- return /connect/.test(peer.state) || (peer.duration && peer.duration.mean) > 0 && !isLongterm(peer)
42-}
43-
44-//tried to connect, but failed.
45-function isInactive (e) {
46- return e.stateChange && e.duration && e.duration.mean == 0
47-}
48-
49-//havn't tried to connect peer yet.
50-function isUnattempted (e) {
51- return !e.stateChange
52-}
53-
54-function getType (e) {
55- return (
56- isLongterm(e) ? 'modern'
57- : isLegacy(e) ? 'legacy'
58- : isInactive(e) ? 'inactive'
59- : isUnattempted(e) ? 'unattempted'
60- : 'other' //should never happen
61- )
62-}
63-
64-var states = {
65- connected: 3,
66- connecting: 2
67-}
68-
69-var types = {
70- modern: 4,
71- legacy: 3,
72- inactive: 2,
73- unattempted: 1,
74- other: 0
75-}
76-
77-function round(n) {
78- return Math.round(n*100)/100
79-}
80-
81-function duration (s) {
82- if(!s) return s
83- if (Math.abs(s) > 30000)
84- return round(s/60000)+'m'
85- else if (Math.abs(s) > 500)
86- return round(s/1000)+'s'
87- else
88- return round(s)+'ms'
89-}
90-
91-exports.screen_view = function (path) {
92-
93- if(path !== '/network') return
94-
95- var ol = h('ul.network')
96-
97- ;(function poll () {
98-
99- //if this tab isn't open, don't update.
100- //todo: make a better way to do this...
101- if(!isVisible(ol))
102- return setTimeout(poll, 1000)
103-
104- sbot_gossip_peers(function (err, list) {
105- ol.innerHTML = ''
106- list.sort(function (a, b) {
107- return (
108- (states[b.state] || 0) - (states[a.state] || 0)
109- || types[getType(b)] - types[getType(a)]
110- || b.stateChange - a.stateChange
111- )
112- }).forEach(function (peer) {
113- ol.appendChild(h('div',
114- avatar(peer.key, 'thumbnail'),
115- h('div',
116- peer.state || 'not connected',
117- ' ',
118- getType(peer),
119- ' ',
120- //TODO: show nicer details, with labels. etc.
121- peer.ping && peer.ping.rtt ? duration(peer.ping.rtt.mean) : '',
122- ' ',
123- peer.ping && peer.ping.skew ? duration(peer.ping.skew.mean) : '',
124- h('label',
125- {title: new Date(peer.stateChange).toString()},
126- peer.stateChange && ('(' + human(new Date(peer.stateChange))) + ')')
127- ),
128- 'source:'+peer.source,
129- h('pre', legacyToMultiServer(peer)),
130- h('button', 'connect', {onclick: function () {
131- sbot_gossip_connect(peer, function (err) {
132- if(err) console.error(err)
133- else console.log('connected to', peer)
134- })
135- }})
136- )
137- )
138- })
139-
140- setTimeout(poll, 5000)
141- })
142-
143- })()
144-
145- return h('div.column.scroll-y', ol)
146-}
modules/notifications.jsView
@@ -1,151 +1,0 @@
1-var h = require('hyperscript')
2-var u = require('../util')
3-var pull = require('pull-stream')
4-var Scroller = require('pull-scroll')
5-var paramap = require('pull-paramap')
6-var plugs = require('../plugs')
7-var cont = require('cont')
8-var ref = require('ssb-ref')
9-
10-var message_render = plugs.first(exports.message_render = [])
11-var sbot_log = plugs.first(exports.sbot_log = [])
12-var sbot_get = plugs.first(exports.sbot_get = [])
13-var sbot_user_feed = plugs.first(exports.sbot_user_feed = [])
14-var message_unbox = plugs.first(exports.message_unbox = [])
15-
16-function unbox() {
17- return pull(
18- pull.map(function (msg) {
19- return msg.value && 'string' === typeof msg.value.content ?
20- message_unbox(msg) : msg
21- }),
22- pull.filter(Boolean)
23- )
24-}
25-
26-function notifications(ourIds) {
27-
28- function linksToUs(link) {
29- return link && link.link in ourIds
30- }
31-
32- function isOurMsg(id, cb) {
33- if (!id) return cb(null, false)
34- if (typeof id === 'object' && typeof id.link === 'string') id = id.link
35- if (!ref.isMsg(id)) return cb(null, false)
36- sbot_get(id, function (err, msg) {
37- if (err && err.name == 'NotFoundError') cb(null, false)
38- else if (err) cb(err)
39- else if (msg.content.type === 'issue' || msg.content.type === 'pull-request')
40- isOurMsg(msg.content.repo || msg.content.project, cb)
41- else cb(err, msg.author in ourIds)
42- })
43- }
44-
45- function isAnyOurMessage(msg, ids, cb) {
46- cont.para(ids.map(function (id) {
47- return function (cb) { isOurMsg(id, cb) }
48- }))
49- (function (err, results) {
50- if (err) cb(err)
51- else if (results.some(Boolean)) cb(null, msg)
52- else cb()
53- })
54- }
55-
56- return paramap(function (msg, cb) {
57- var c = msg.value && msg.value.content
58- if (!c || typeof c !== 'object') return cb()
59- if (msg.value.author in ourIds) return cb()
60-
61- if (c.mentions && Array.isArray(c.mentions) && c.mentions.some(linksToUs))
62- return cb(null, msg)
63-
64- if (msg.private)
65- return cb(null, msg)
66-
67- switch (c.type) {
68- case 'post':
69- if (c.branch || c.root)
70- return isAnyOurMessage(msg, [].concat(c.branch, c.root), cb)
71- else return cb()
72-
73- case 'contact':
74- return cb(null, c.contact in ourIds ? msg : null)
75-
76- case 'vote':
77- if (c.vote && c.vote.link)
78- return isOurMsg(c.vote.link, function (err, isOurs) {
79- cb(err, isOurs ? msg : null)
80- })
81- else return cb()
82-
83- case 'issue':
84- case 'pull-request':
85- return isOurMsg(c.project || c.repo, function (err, isOurs) {
86- cb(err, isOurs ? msg : null)
87- })
88-
89- case 'issue-edit':
90- return isAnyOurMessage(msg, [c.issue].concat(c.issues), cb)
91-
92- default:
93- cb()
94- }
95- }, 4)
96-}
97-
98-function getFirstMessage(feedId, cb) {
99- sbot_user_feed({id: feedId, gte: 0, limit: 1})(null, cb)
100-}
101-
102-exports.screen_view = function (path) {
103- if(path === '/notifications') {
104- var ids = {}
105- var oldest
106-
107- var id = require('../keys').id
108- ids[id] = true
109- getFirstMessage(id, function (err, msg) {
110- if (err) return console.error(err)
111- if (!oldest || msg.value.timestamp < oldest) {
112- oldest = msg.value.timestamp
113- }
114- })
115-
116- var content = h('div.column.scroller__content')
117- var div = h('div.column.scroller',
118- {style: {'overflow':'auto'}},
119- h('div.scroller__wrapper',
120- content
121- )
122- )
123-
124- pull(
125- u.next(sbot_log, {old: false, limit: 100}),
126- unbox(),
127- notifications(ids),
128- pull.filter(),
129- Scroller(div, content, message_render, true, false)
130- )
131-
132- pull(
133- u.next(sbot_log, {reverse: true, limit: 100, live: false}),
134- unbox(),
135- notifications(ids),
136- pull.filter(),
137- pull.take(function (msg) {
138- // abort stream after we pass the oldest messages of our feeds
139- return !oldest || msg.value.timestamp > oldest
140- }),
141- Scroller(div, content, message_render, false, false)
142- )
143-
144- return div
145- }
146-}
147-
148-
149-
150-
151-
modules/post.jsView
@@ -1,37 +1,0 @@
1-var markdown = require('ssb-markdown')
2-var h = require('hyperscript')
3-var u = require('../util')
4-var ref = require('ssb-ref')
5-
6-//render a message
7-
8-var plugs = require('../plugs')
9-var message_link = plugs.first(exports.message_link = [])
10-var markdown = plugs.first(exports.markdown = [])
11-
12-exports.message_content = function (data) {
13- if(!data.value.content || !data.value.content.text) return
14-
15- var root = data.value.content.root
16- var re = !root ? null : h('span', 're: ', message_link(root))
17-
18- return h('div',
19- re,
20- markdown(data.value.content)
21- )
22-
23-}
24-
25-
26-
27-
28-
29-
30-
31-
32-
33-
34-
35-
36-
37-
modules/private.jsView
@@ -1,86 +1,0 @@
1-var h = require('hyperscript')
2-var ui = require('../ui')
3-var u = require('../util')
4-var pull = require('pull-stream')
5-var Scroller = require('pull-scroll')
6-var ref = require('ssb-ref')
7-
8-var plugs = require('../plugs')
9-
10-var message_render = plugs.first(exports.message_render = [])
11-var message_compose = plugs.first(exports.message_compose = [])
12-var message_unbox = plugs.first(exports.message_unbox = [])
13-var sbot_log = plugs.first(exports.sbot_log = [])
14-var avatar_image_link = plugs.first(exports.avatar_image_link = [])
15-
16-function unbox () {
17- return pull(
18- pull.filter(function (msg) {
19- return 'string' == typeof msg.value.content
20- }),
21- pull.map(function (msg) {
22- return message_unbox(msg)
23- }),
24- pull.filter(Boolean)
25- )
26-}
27-
28-exports.screen_view = function (path) {
29-
30- if(path === '/private') {
31- //if(process.title === 'browser')
32- //return h('div', h('h4', 'Private messages are not supported in the lite client.'))
33-
34-
35- var id = require('../keys').id
36- var compose = message_compose(
37- {type: 'post', recps: [], private: true},
38- {
39- prepublish: function (msg) {
40- msg.recps = [id].concat(msg.mentions).filter(function (e) {
41- return ref.isFeed('string' === typeof e ? e : e.link)
42- })
43- if(!msg.recps.length)
44- throw new Error('cannot make private message without recipients - just mention the user in an at reply in the message you send')
45- return msg
46- },
47- placeholder: 'Write a private message'
48- }
49- )
50-
51- var content = h('div.column.scroller__content')
52- var div = h('div.column.scroller',
53- {style: {'overflow':'auto'}},
54- h('div.scroller__wrapper', compose, content)
55- )
56-
57- pull(
58- u.next(sbot_log, {old: false, limit: 100}),
59- unbox(),
60- Scroller(div, content, message_render, true, false)
61- )
62-
63- pull(
64- u.next(sbot_log, {reverse: true, limit: 1000}),
65- unbox(),
66- Scroller(div, content, message_render, false, false, function (err) {
67- if(err) throw err
68- })
69- )
70-
71- return div
72- }
73-}
74-
75-function map(ary, iter) {
76- if(Array.isArray(ary)) return ary.map(iter)
77-}
78-
79-exports.message_meta = function (msg) {
80- if(msg.value.content.recps || msg.value.private)
81- return h('span.row', 'PRIVATE', map(msg.value.content.recps, function (id) {
82- return avatar_image_link('string' == typeof id ? id : id.link, 'thumbnail')
83- }))
84-}
85-
86-
modules/public.jsView
@@ -1,57 +1,0 @@
1-var h = require('hyperscript')
2-var ui = require('../ui')
3-var u = require('../util')
4-var pull = require('pull-stream')
5-var Scroller = require('pull-scroll')
6-
7-var plugs = require('../plugs')
8-var message_render = plugs.first(exports.message_render = [])
9-var message_compose = plugs.first(exports.message_compose = [])
10-var sbot_log = plugs.first(exports.sbot_log = [])
11-
12-exports.screen_view = function (path, sbot) {
13- if(path === '/public') {
14-
15- var content = h('div.column.scroller__content')
16- var div = h('div.column.scroller',
17- {style: {'overflow':'auto'}},
18- h('div.scroller__wrapper',
19- message_compose({type: 'post'}, {placeholder: 'Write a public message'}),
20- content
21- )
22- )
23-
24- pull(
25- u.next(sbot_log, {old: false, limit: 100}),
26- Scroller(div, content, message_render, true, false)
27- )
28-
29- pull(
30- u.next(sbot_log, {reverse: true, limit: 100, live: false}),
31- Scroller(div, content, message_render, false, false)
32- )
33-
34- return div
35- }
36-}
37-
38-
39-
40-
41-
42-
43-
44-
45-
46-
47-
48-
49-
50-
51-
52-
53-
54-
55-
56-
57-
modules/query.jsView
@@ -1,56 +1,0 @@
1-var h = require('hyperscript')
2-var pull = require('pull-stream')
3-var HJSON = require('hjson')
4-
5-var sbot_query = require('../plugs').first(exports.sbot_query = [])
6-
7-exports.menu_items = function () {
8- return h('a', {href:'#/query'}, '/query')
9-}
10-
11-exports.screen_view = function (path) {
12- if(path != '/query') return
13- var output, status, editor, stream, query
14-
15- function parse () {
16- try {
17- query = HJSON.parse(editor.value)
18- } catch (err) {
19- return status.textContent = err.message
20- }
21- status.textContent = 'okay'
22- }
23-
24- return h('div.column.scroll',
25- editor = h('textarea', {style: 'min-height:100px;', oninput: parse, onkeydown: function (e) {
26- if(!(e.keyCode === 13 && e.ctrlKey)) return
27-
28- status.textContent = 'running...'
29- parse()
30- output.innerHTML = ''
31- if(stream) stream.abort()
32-
33- console.log(query)
34-
35- stream = pull(
36- sbot_query({query: query, limit: 100}),
37- pull.drain(function (data) {
38- output.appendChild(h('pre.query__data',
39- JSON.stringify(data, null, 2)
40- ))
41- }, function (err) {
42- if(err) status.textContent = err.stack
43- })
44- )
45- }}),
46- status = h('div.query__status'),
47- output = h('div.column.query__output', {style: 'overflow-y: scroll;'})
48- )
49-}
50-
51-
52-
53-
54-
55-
56-
modules/raw.jsView
@@ -1,52 +1,0 @@
1-var h = require('hyperscript')
2-var u = require('../util')
3-var pull = require('pull-stream')
4-var Scroller = require('pull-scroll')
5-
6-var plugs = require('../plugs')
7-var message_render = plugs.first(exports.message_render = [])
8-var message_compose = plugs.first(exports.message_compose = [])
9-
10-// from ssb-ref
11-var refRegex = /((?:@|%|&)[A-Za-z0-9\/+]{43}=\.[\w\d]+)/g
12-
13-exports.linkify = function (text) {
14- var arr = text.split(refRegex)
15- for (var i = 1; i < arr.length; i += 2) {
16- arr[i] = h('a', {href: '#' + arr[i]}, arr[i])
17- }
18- return arr
19-}
20-
21-exports.message_meta = function (msg) {
22- var tmp = h('div')
23- var el
24- var pre
25- return h('input', {
26- type: 'checkbox',
27- title: 'View Data',
28- onclick: function () {
29- var msgEl = this.parentNode.parentNode.parentNode
30- var msgContentEl = msgEl.querySelector('.message_content')
31- if (this.checked) {
32- // move away the content
33- while (el = msgContentEl.firstChild)
34- tmp.appendChild(el)
35- // show the raw stuff
36- if (!pre) pre = h('pre', exports.linkify(JSON.stringify({
37- key: msg.key,
38- value: msg.value
39- }, 0, 2)))
40- msgContentEl.appendChild(pre)
41- } else {
42- // hide the raw stuff
43- msgContentEl.removeChild(pre)
44- // put back the content
45- while (el = tmp.firstChild)
46- msgContentEl.appendChild(el)
47- }
48- }
49- })
50-}
51-
52-
modules/relationships.jsView
@@ -1,50 +1,0 @@
1-var pull = require('pull-stream')
2-var plugs = require('../plugs')
3-
4-var sbot_query = plugs.first(exports.sbot_query = [])
5-
6-//this is a bit crude, and doesn't actually show unfollows yet.
7-
8-function makeQuery (a, b) {
9- return {"$filter": {
10- value: {
11- author: a,
12- content: {
13- type: 'contact',
14- contact: b,
15- following: true
16- }
17- },
18- }}
19-}
20-
21-
22-exports.follows = function (id, cb) {
23- return sbot_query({query: [
24- makeQuery(id, {$prefix:"@"}),
25- {"$map": ['value', 'content', 'contact']}
26- ]})
27-}
28-
29-exports.followers = function (id) {
30- return sbot_query({query: [
31- makeQuery({$prefix:"@"}, id),
32- {"$map": ['value', 'author']}
33- ]})
34-}
35-
36-exports.follower_of = function (source, dest, cb) {
37- pull(
38- sbot_query({query: [
39- makeQuery(source, dest),
40- {$map: ['value', 'content', 'following']}
41- ]}),
42- pull.collect(function (err, ary) {
43- if(err) return cb(err)
44- else cb(null, ary.pop()) //will be true, or undefined/false
45- })
46- )
47-}
48-
49-
50-
modules/search-box.jsView
@@ -1,111 +1,0 @@
1-var h = require('hyperscript')
2-var suggest = require('suggest-box')
3-var pull = require('pull-stream')
4-var plugs = require('../plugs')
5-var sbot_query = plugs.first(exports.sbot_query = [])
6-var sbot_links2 = plugs.first(exports.sbot_links2 = [])
7-
8-var channels = []
9-
10-var signified = require('../plugs').first(exports.signified = [])
11-
12-var builtinTabs = [
13- '/public', '/private', '/notifications',
14- '/network', '/query', '/versions'
15-].map(function (name) {
16- return {
17- title: name,
18- value: name,
19- }
20-})
21-
22-exports.search_box = function (go) {
23-
24- var suggestBox
25- var search = h('input.searchprompt', {
26- type: 'search',
27- placeholder: 'Commands',
28- onkeydown: function (ev) {
29- switch (ev.keyCode) {
30- case 13: // enter
31- if (suggestBox && suggestBox.active) {
32- suggestBox.complete()
33- ev.stopPropagation()
34- }
35- if (go(search.value.trim(), !ev.ctrlKey))
36- search.blur()
37- return
38- case 27: // escape
39- ev.preventDefault()
40- search.blur()
41- return
42- }
43- }
44- })
45-
46- search.activate = function (sigil, ev) {
47- search.focus()
48- ev.preventDefault()
49- if (search.value[0] === sigil) {
50- search.selectionStart = 1
51- search.selectionEnd = search.value.length
52- } else {
53- search.value = sigil
54- }
55- }
56-
57- var suggestions = {}
58-
59- // delay until the element has a parent
60- setTimeout(function () {
61- suggestBox = suggest(search, function (word, cb) {
62- if(/^#\w/.test(word))
63- cb(null, channels.filter(function (chan) {
64- return ('#'+chan.name).substring(0, word.length) === word
65- })
66- .map(function (chan) {
67- var name = '#'+chan.name
68- return {
69- title: name,
70- value: name,
71- subtitle: chan.rank
72- }
73- }))
74- else if(/^@\w/.test(word)) {
75- signified(word, function (_, names) {
76- cb(null, names.map(function (e) {
77- return {
78- title: e.name + ':'+e.id.substring(0, 10),
79- value: e.id,
80- subtitle: e.rank
81- }
82- }))
83- })
84- } else if(/^\//.test(word)) {
85- cb(null, builtinTabs.filter(function (name) {
86- return name.value.substr(0, word.length) === word
87- }))
88- }
89- }, {})
90- }, 10)
91-
92-
93- pull(
94- sbot_query({query: [
95- {$filter: {value: {content: {channel: {$gt: ''}}}}},
96- {$reduce: {
97- name: ['value', 'content', 'channel'],
98- rank: {$count: true}
99- }}
100- ]}),
101- pull.collect(function (err, chans) {
102- if (err) return console.error(err)
103- channels = chans
104- })
105- )
106-
107- return search
108-}
109-
110-
111-
modules/search.jsView
@@ -1,105 +1,0 @@
1-var h = require('hyperscript')
2-var u = require('../util')
3-var pull = require('pull-stream')
4-var Scroller = require('pull-scroll')
5-var TextNodeSearcher = require('text-node-searcher')
6-
7-var plugs = require('../plugs')
8-var message_render = plugs.first(exports.message_render = [])
9-var sbot_log = plugs.first(exports.sbot_log = [])
10-var whitespace = /\s+/
11-
12-function andSearch(terms, inputs) {
13- for(var i = 0; i < terms.length; i++) {
14- var match = false
15- for(var j = 0; j < inputs.length; j++) {
16- if(terms[i].test(inputs[j])) match = true
17- }
18- //if a term was not matched by anything, filter this one
19- if(!match) return false
20- }
21- return true
22-}
23-
24-function searchFilter(terms) {
25- return function (msg) {
26- var c = msg && msg.value && msg.value.content
27- return c && (
28- msg.key == terms[0] ||
29- andSearch(terms.map(function (term) {
30- return new RegExp('\\b'+term+'\\b', 'i')
31- }), [c.text, c.name, c.title])
32- )
33- }
34-}
35-
36-function createOrRegExp(ary) {
37- return new RegExp(ary.map(function (e) {
38- return '\\b'+e+'\\b'
39- }).join('|'), 'i')
40-}
41-
42-function highlight(el, query) {
43- var searcher = new TextNodeSearcher({container: el})
44- searcher.query = query
45- searcher.highlight()
46- return el
47-}
48-
49-exports.screen_view = function (path) {
50- if(path[0] === '?') {
51- var query = path.substr(1).trim().split(whitespace)
52- var _matches = searchFilter(query)
53-
54- var total = 0, matches = 0
55-
56- var header = h('div.search_header', '')
57- var content = h('div.column.scroller__content')
58- var div = h('div.column.scroller',
59- {style: {'overflow':'auto'}},
60- h('div.scroller__wrapper',
61- header,
62- content
63- )
64- )
65-
66- function matchesQuery (data) {
67- total++
68- var m = _matches(data)
69- if(m) matches++
70- header.textContent = 'searched:'+total+', found:'+matches
71- return m
72- }
73-
74-
75-
76- function renderMsg(msg) {
77- var el = message_render(msg)
78- highlight(el, createOrRegExp(query))
79- return el
80- }
81-
82- pull(
83- sbot_log({old: false}),
84- pull.filter(matchesQuery),
85- Scroller(div, content, renderMsg, true, false)
86- )
87-
88- pull(
89- u.next(sbot_log, {reverse: true, limit: 500, live: false}),
90- pull.filter(matchesQuery),
91- Scroller(div, content, renderMsg, false, false)
92- )
93-
94- return div
95- }
96-}
97-
98-
99-
100-
101-
102-
103-
104-
105-
modules/setup.jsView
@@ -1,145 +1,0 @@
1-
2-var h = require('hyperscript')
3-var pull = require('pull-stream')
4-
5-var plugs = require('../plugs')
6-
7-var avatar_edit = plugs.first(exports.avatar_edit = [])
8-var invite_parse = plugs.first(exports.invite_parse = [])
9-var invite_accept = plugs.first(exports.invite_accept = [])
10-var sbot_progress = plugs.first(exports.sbot_progress = [])
11-var sbot_query = plugs.first(exports.sbot_query = [])
12-var avatar = plugs.first(exports.avatar = [])
13-
14-//maybe this could show the pubs, or
15-//if someone locally follows you,
16-//it could show the second degree pubs?
17-
18-//maybe show the network as animated graph?
19-
20-function followers_query (id) {
21- return [{$filter: {
22- value: {content: {
23- type: "contact",
24- contact: id,
25- following: true,
26-// autofollow: true
27- }}
28- }}]
29-}
30-
31-//test whether we are connected to the ssb network.
32-exports.setup_is_fresh_install = function (cb) {
33- //test by checking whether you have any friends following you?
34- pull(
35- sbot_query({query: followers_query(id), limit: 1, live: false}),
36- pull.collect(function (err, ary) {
37- cb(err, !!ary.length)
38- })
39- )
40-}
41-
42-function invite_form () {
43- var accept = h('button', 'enter code', {disabled: true, onclick: function () {
44- invite_accept(input.value, function (msg) {
45- status.textContent = msg
46- }, function (err) {
47- if(err) {
48- accept.textContent = 'error:'+(err.message || err.stack || error.type)
49- console.error(err)
50- }
51- else {
52- input.value = ''
53- accept.textContent = 'success!'
54- }
55- })
56- }})
57-
58- function parseInput () {
59- if(!input.value) {
60- accept.disabled = true
61- accept.textContent = 'enter code'
62- }
63- else if(!invite_parse(input.value)) {
64- accept.disabled = true
65- accept.textContent = 'invalid code'
66- }
67- else {
68- accept.disabled = false
69- accept.textContent = 'accept'
70- }
71- }
72-
73- var input = h('input.wide', {placeholder: 'invite code', oninput: parseInput, onchange: parseInput})
74-
75- return h('div.invite-form.row', input, accept)
76-}
77-
78-exports.progress_bar = function () {
79- var liquid = h('div.hyperprogress__liquid', '.')
80- var bar = h('div.hyperprogress__bar', liquid)
81- liquid.style.width = '0%'
82-
83- pull(
84- sbot_progress(),
85- pull.drain(function (e) {
86- liquid.style.width = Math.round((e.progress/e.total)*100)+'%'
87- })
88- )
89-
90- return bar
91-}
92-
93-//show the first 5 followers, and how they join you to the network.
94-//so this will show if a local peer follows you.
95-
96-//when you join the network, I want this to show as people follow you.
97-//that could be when a pub accepts the invite, or when a local peer accepts.
98-
99-exports.setup_joined_network = function (id) {
100- var followers = h('div.column')
101- var label = h('label', 'not connected to a network')
102- var joined = h('div.setup__joined', label,followers)
103-
104- pull(
105- sbot_query({query: followers_query(id), limit: 5, live: true, sync: false}),
106- pull.drain(function (follower) {
107- if(follower.sync) return
108- label.textContent = 'connected to network via...'
109- followers.appendChild(
110- avatar(follower.value.author, 'thumbnail')
111- )
112- })
113- )
114-
115- return joined
116-}
117-
118-exports.screen_view = function (path) {
119-
120- if(path !== '/setup') return
121-
122- var id = require('../keys').id
123-
124- //set up an avatar
125-
126-
127- var status = h('span')
128- var invite = h('input', {placeholder: 'invite code'})
129- return h('div.scroller', h('div.scroller__wrapper',
130- h('h1', 'welcome to patchbay!'),
131- h('div',
132- 'please choose avatar image and name',
133- avatar_edit(id)
134- ),
135- h('h2', 'join network'),
136- invite_form(),
137- //show avatars of anyone on the same local network.
138- //show realtime changes in your followers, especially for local.
139-
140- exports.progress_bar(),
141- exports.setup_joined_network(require('../keys').id)
142- ))
143-}
144-
145-
modules/split.jsView
@@ -1,17 +1,0 @@
1-var h = require('hyperscript')
2-
3-var screen_view =
4- require('../plugs').first(exports._screen_view = [])
5-
6-exports.screen_view = function (path) {
7- var m = /^split\s*\((.*)\)$/.exec(path)
8- if(!m)
9- return
10-
11- return h('div.row',
12- m[1].split(',').map(function (e) {
13- return screen_view(e.trim())
14- }).filter(Boolean)
15- )
16-}
17-
modules/suggest-mentions.jsView
@@ -1,40 +1,0 @@
1-var pull = require('pull-stream')
2-var cont = require('cont')
3-function isImage (filename) {
4- return /\.(gif|jpg|png|svg)$/i.test(filename)
5-}
6-
7-var sbot_links2 = require('../plugs').first(exports.sbot_links2 = [])
8-var blob_url = require('../plugs').first(exports.blob_url = [])
9-var signified = require('../plugs').first(exports.signified = [])
10-
11-exports.suggest = cont.to(function (word, cb) {
12- if(!/^@\w/.test(word)) return cb()
13-
14-
15- signified(word, function (err, names) {
16- if(err) cb(err)
17- else cb(null, names.map(function (e) {
18- return {
19- title: e.name + ': ' + e.id.substring(0,10)+' ('+e.rank+')',
20- value: '['+e.name+']('+e.id+')',
21- rank: e.rank,
22- //TODO: avatar images...
23- }
24- }))
25- })
26-})
27-
28-
29-
30-
31-
32-
33-
34-
35-
36-
37-
38-
39-
40-
modules/suggest.jsView
@@ -1,3 +1,0 @@
1-
2-
3-
modules/tabs.jsView
@@ -1,214 +1,0 @@
1-var Tabs = require('hypertabs')
2-var h = require('hyperscript')
3-var pull = require('pull-stream')
4-var u = require('../util')
5-var keyscroll = require('../keyscroll')
6-var open = require('open-external')
7-
8-function ancestor (el) {
9- if(!el) return
10- if(el.tagName !== 'A') return ancestor(el.parentElement)
11- return el
12-}
13-
14-var plugs = require('../plugs')
15-var screen_view = plugs.first(exports._screen_view = [])
16-var search_box = plugs.first(exports.search_box = [])
17-var menu = plugs.first(exports.menu = [])
18-
19-exports.message_render = []
20-
21-exports.screen_view = function (path) {
22- if(path !== 'tabs')
23- return
24-
25- function setSelected (indexes) {
26- var ids = indexes.map(function (index) {
27- return tabs.get(index).id
28- })
29- if(ids.length > 1)
30- search.value = 'split('+ids.join(',')+')'
31- else
32- search.value = ids[0]
33- }
34-
35- var search
36- var tabs = Tabs(setSelected)
37-
38- search = search_box(function (path, change) {
39-
40- if(tabs.has(path)) {
41- tabs.select(path)
42- return true
43- }
44- var el = screen_view(path)
45-
46- if(el) {
47- if(!el.title) el.title = path
48- el.scroll = keyscroll(el.querySelector('.scroller__content'))
49- tabs.add(el, change)
50-// localStorage.openTabs = JSON.stringify(tabs.tabs)
51- return change
52- }
53- })
54-
55- //reposition hypertabs menu to inside a container...
56- tabs.insertBefore(h('div.header.row',
57- h('div.header__tabs.row', tabs.firstChild), //tabs
58- h('div.header__search.row.end', h('div', search), menu())
59- ), tabs.firstChild)
60-// tabs.insertBefore(search, tabs.firstChild.nextSibling)
61-
62- var saved = []
63-// try { saved = JSON.parse(localStorage.openTabs) }
64-// catch (_) { }
65-
66- if(!saved || saved.length < 3)
67- saved = ['/public', '/private', '/notifications']
68-
69- saved.forEach(function (path) {
70- var el = screen_view(path)
71- el.id = el.id || path
72- if (!el) return
73- el.scroll = keyscroll(el.querySelector('.scroller__content'))
74- if(el) tabs.add(el, false, false)
75- })
76-
77- tabs.select(0)
78-
79- //handle link clicks
80- window.onclick = function (ev) {
81- var link = ancestor(ev.target)
82- if(!link) return
83- var path = link.hash.substring(1)
84-
85- ev.preventDefault()
86- ev.stopPropagation()
87-
88- //open external links.
89- //this ought to be made into something more runcible
90- if(open.isExternal(link.href)) return open(link.href)
91-
92- if(tabs.has(path))
93- return tabs.select(path, !ev.ctrlKey, !!ev.shiftKey)
94-
95- var el = screen_view(path)
96- if(el) {
97- el.id = el.id || path
98- el.scroll = keyscroll(el.querySelector('.scroller__content'))
99- tabs.add(el, !ev.ctrlKey, !!ev.shiftKey)
100-// localStorage.openTabs = JSON.stringify(tabs.tabs)
101- }
102-
103- return false
104- }
105-
106- window.addEventListener('keydown', function (ev) {
107- if (ev.target.nodeName === 'INPUT' || ev.target.nodeName === 'TEXTAREA')
108- return
109- switch(ev.keyCode) {
110-
111- // scroll through tabs
112- case 72: // h
113- return tabs.selectRelative(-1)
114- case 76: // l
115- return tabs.selectRelative(1)
116-
117- // scroll through messages
118- case 74: // j
119- return tabs.get(tabs.selected[0]).scroll(1)
120- case 75: // k
121- return tabs.get(tabs.selected[0]).scroll(-1)
122-
123- // close a tab
124- case 88: // x
125- if (tabs.selected) {
126- var sel = tabs.selected
127- var i = sel.reduce(function (a, b) { return Math.min(a, b) })
128- tabs.remove(sel)
129- tabs.select(Math.max(i-1, 0))
130- }
131- return
132-
133- // activate the search field
134- case 191: // /
135- if (ev.shiftKey)
136- search.activate('?', ev)
137- else
138- search.activate('/', ev)
139- return
140-
141- // navigate to a feed
142- case 50: // 2
143- if (ev.shiftKey)
144- search.activate('@', ev)
145- return
146-
147- // navigate to a channel
148- case 51: // 3
149- if (ev.shiftKey)
150- search.activate('#', ev)
151- return
152- }
153- })
154-
155- // errors tab
156- var errorsContent = h('div.column.scroller__content')
157- var errors = h('div.column.scroller',
158- {style: {'overflow':'auto'}},
159- h('div.scroller__wrapper',
160- errorsContent
161- )
162- )
163-
164- // remove loader error handler
165- if (window.onError) {
166- window.removeEventListener('error', window.onError)
167- delete window.onError
168- }
169-
170- var errors = h('div.errors', {id: 'errors'})
171-
172- // put errors in a tab
173- window.addEventListener('error', function (ev) {
174- var err = ev.error || ev
175- if(!tabs.has('errors'))
176- tabs.add(errors, false)
177- var el = h('div.message',
178- h('strong', err.message),
179- h('pre', err.stack))
180- if (errorsContent.firstChild)
181- errorsContent.insertBefore(el, errorsContent.firstChild)
182- else
183- errorsContent.appendChild(el)
184- })
185-
186- if (process.versions.electron) {
187- window.addEventListener('contextmenu', function (ev) {
188- ev.preventDefault()
189- var remote = require('electron').remote
190- var Menu = remote.Menu
191- var MenuItem = remote.MenuItem
192- var menu = new Menu()
193- menu.append(new MenuItem({
194- label: 'Inspect Element',
195- click: function () {
196- remote.getCurrentWindow().inspectElement(ev.x, ev.y)
197- }
198- }))
199- menu.popup(remote.getCurrentWindow())
200- })
201- }
202-
203- return tabs
204-}
205-
206-
207-
208-
209-
210-
211-
212-
213-
214-
modules/thread.jsView
@@ -1,126 +1,0 @@
1-var ui = require('../ui')
2-var pull = require('pull-stream')
3-var Cat = require('pull-cat')
4-var sort = require('ssb-sort')
5-var ref = require('ssb-ref')
6-var h = require('hyperscript')
7-var u = require('../util')
8-var Scroller = require('pull-scroll')
9-var self_id = require('../keys').id
10-
11-function once (cont) {
12- var ended = false
13- return function (abort, cb) {
14- if(abort) return cb(abort)
15- else if (ended) return cb(ended)
16- else
17- cont(function (err, data) {
18- if(err) return cb(ended = err)
19- ended = true
20- cb(null, data)
21- })
22- }
23-}
24-
25-var plugs = require('../plugs')
26-
27-var message_render = plugs.first(exports.message_render = [])
28-var message_name = plugs.first(exports.message_name = [])
29-var message_compose = plugs.first(exports.message_compose = [])
30-var message_unbox = plugs.first(exports.message_unbox = [])
31-
32-var sbot_get = plugs.first(exports.sbot_get = [])
33-var sbot_links = plugs.first(exports.sbot_links = [])
34-
35-function getThread (root, cb) {
36- //in this case, it's inconvienent that panel only takes
37- //a stream. maybe it would be better to accept an array?
38-
39- sbot_get(root, function (err, value) {
40- var msg = {key: root, value: value}
41-// if(value.content.root) return getThread(value.content.root, cb)
42-
43- pull(
44- sbot_links({rel: 'root', dest: root, values: true, keys: true}),
45- pull.collect(function (err, ary) {
46- if(err) return cb(err)
47- ary.unshift(msg)
48- cb(null, ary)
49- })
50- )
51- })
52-
53-}
54-
55-exports.screen_view = function (id) {
56- if(ref.isMsg(id)) {
57- var meta = {
58- type: 'post',
59- root: id,
60- branch: id //mutated when thread is loaded.
61- }
62-
63- var content = h('div.column.scroller__content')
64- var div = h('div.column.scroller',
65- {style: {'overflow-y': 'auto'}},
66- h('div.scroller__wrapper',
67- content,
68- message_compose(meta, {shrink: false, placeholder: 'Write a reply'})
69- )
70- )
71-
72- message_name(id, function (err, name) {
73- div.title = name
74- })
75-
76- pull(
77- sbot_links({
78- rel: 'root', dest: id, keys: true, old: false
79- }),
80- pull.drain(function (msg) {
81- loadThread() //redraw thread
82- }, function () {} )
83- )
84-
85-
86- function loadThread () {
87- getThread(id, function (err, thread) {
88- //would probably be better keep an id for each message element
89- //(i.e. message key) and then update it if necessary.
90- //also, it may have moved (say, if you received a missing message)
91- content.innerHTML = ''
92- //decrypt
93- thread = thread.map(function (msg) {
94- return 'string' === typeof msg.value.content ? message_unbox(msg) : msg
95- })
96-
97- if(err) return content.appendChild(h('pre', err.stack))
98- sort(thread).map(message_render).filter(Boolean).forEach(function (el) {
99- content.appendChild(el)
100- })
101-
102- var branches = sort.heads(thread)
103- meta.branch = branches.length > 1 ? branches : branches[0]
104- meta.root = thread[0].value.content.root || thread[0].key
105- meta.channel = thread[0].value.content.channel
106-
107- var recps = thread[0].value.content.recps
108- var private = thread[0].value.private
109- if(private) {
110- if(recps)
111- meta.recps = recps
112- else
113- meta.recps = [thread[0].value.author, self_id]
114- }
115- })
116- }
117-
118- loadThread()
119- return div
120- }
121-}
122-
123-
124-
125-
126-
modules/timestamp.jsView
@@ -1,21 +1,0 @@
1-var h = require('hyperscript')
2-var human = require('human-time')
3-
4-function updateTimestampEl(el) {
5- el.firstChild.nodeValue = human(new Date(el.timestamp))
6- return el
7-}
8-
9-setInterval(function () {
10- var els = [].slice.call(document.querySelectorAll('.timestamp'))
11- els.forEach(updateTimestampEl)
12-}, 60e3)
13-
14-exports.message_meta = function (msg) {
15- return updateTimestampEl(h('a.enter.timestamp', {
16- href: '#'+msg.key,
17- timestamp: msg.value.timestamp,
18- title: new Date(msg.value.timestamp)
19- }, ''))
20-}
21-
modules/versions.jsView
@@ -1,36 +1,0 @@
1-var h = require('hyperscript')
2-
3-exports.menu_items = function () {
4- return h('a', {href: '#/versions'}, '/versions')
5-}
6-
7-exports.screen_view = function (path) {
8- if(path !== '/versions') return
9-
10- if('undefined' === typeof WebBoot)
11- return h('h1', 'must run with web-boot enabled enviroment')
12-
13- var content = h('div.column')
14-
15- WebBoot.versions(function (err, log) {
16- log.forEach(function (e, i) {
17- content.appendChild(
18- h('div.row',
19- h('a', {
20- href: '#/run:'+e.value,
21- onclick: function () {
22- WebBoot.run(e.value, function () {
23- console.log('rebooting to:', e.value)
24- })
25- }
26- }, ' ', e.value, ' ', new Date(e.ts)),
27- !i && h('label', '(current)')
28- )
29- )
30- })
31-
32- })
33-
34- return content
35-}
36-
modules_basic/about.jsView
@@ -1,0 +1,40 @@
1 +
2 +var h = require('hyperscript')
3 +
4 +function idLink (id) {
5 + return h('a', {href:'#'+id}, id)
6 +}
7 +
8 +function asLink (ln) {
9 + return 'string' === typeof ln ? ln : ln.link
10 +}
11 +
12 +var blob_url = require('../plugs').first(exports.blob_url = [])
13 +
14 +exports.message_content = function (msg) {
15 + if(msg.value.content.type !== 'about') return
16 +
17 + if(!msg.value.content.image && !msg.value.content.name)
18 + return
19 +
20 + var about = msg.value.content
21 + var id = msg.value.content.about
22 + return h('p',
23 + about.about === msg.value.author
24 + ? h('span', 'self-identifies ')
25 + : h('span', 'identifies ', idLink(id)),
26 + ' as ',
27 + h('a', {href:"#"+about.about},
28 + about.name || null,
29 + about.image
30 + ? h('img.avatar--fullsize', {src: blob_url(about.image)})
31 + : null
32 + )
33 + )
34 +
35 +}
36 +
37 +
38 +
39 +
40 +
modules_basic/avatar-edit.jsView
@@ -1,0 +1,141 @@
1 +var dataurl = require('dataurl-')
2 +var hyperfile = require('hyperfile')
3 +var hypercrop = require('hypercrop')
4 +var hyperlightbox = require('hyperlightbox')
5 +var h = require('hyperscript')
6 +var pull = require('pull-stream')
7 +var getAvatar = require('ssb-avatar')
8 +var plugs = require('../plugs')
9 +var ref = require('ssb-ref')
10 +var visualize = require('visualize-buffer')
11 +var self_id = require('../keys').id
12 +
13 +var confirm = plugs.first(exports.message_confirm = [])
14 +var sbot_blobs_add = plugs.first(exports.sbot_blobs_add = [])
15 +var blob_url = plugs.first(exports.blob_url = [])
16 +var sbot_links = plugs.first(exports.sbot_links = [])
17 +var avatar_name = plugs.first(exports.avatar_name = [])
18 +
19 +function crop (d, cb) {
20 + var data
21 + var canvas = hypercrop(h('img', {src: d}))
22 +
23 + return h('div.column.avatar_pic',
24 + canvas,
25 + //canvas.selection,
26 + h('div.row.avatar_pic__controls',
27 + h('button', 'okay', {onclick: function () {
28 + cb(null, canvas.selection.toDataURL())
29 + }}),
30 + h('button', 'cancel', {onclick: function () {
31 + cb(new Error('canceled'))
32 + }})
33 + )
34 + )
35 +}
36 +
37 +exports.avatar_edit = function (id) {
38 +
39 + var img = visualize(new Buffer(id.substring(1), 'base64'), 256)
40 + img.classList.add('avatar--large')
41 +
42 + var lb = hyperlightbox()
43 + var name_input = h('input', {placeholder: 'rename'})
44 + var name = avatar_name(id)
45 + var selected = null, selected_data = null
46 +
47 + getAvatar({links: sbot_links}, self_id, id, function (err, avatar) {
48 + if (err) return console.error(err)
49 + //don't show user has already selected an avatar.
50 + if(selected) return
51 + if(ref.isBlob(avatar.image))
52 + img.src = blob_url(avatar.image)
53 + })
54 +
55 + var also_pictured = h('div.profile__alsopicturedas.wrap')
56 +
57 + pull(
58 + sbot_links({dest: id, rel: 'about', values: true}),
59 + pull.map(function (e) {
60 + return e.value.content.image
61 + }),
62 + pull.filter(function (e) {
63 + return e && 'string' == typeof e.link
64 + }),
65 + pull.unique('link'),
66 + pull.drain(function (image) {
67 + also_pictured.appendChild(
68 + h('a', {href:'#', onclick: function (ev) {
69 + ev.stopPropagation()
70 + ev.preventDefault()
71 + selected = image
72 + img.src = blob_url(image.link || image)
73 + }},
74 + h('img.avatar--thumbnail', {src: blob_url(image)})
75 + )
76 + )
77 + })
78 + )
79 +
80 + return h('div.row.profile',
81 + lb,
82 + img,
83 + h('div.column.profile__info',
84 + h('strong', name),
85 + name_input,
86 +
87 + hyperfile.asDataURL(function (data) {
88 + var el = crop(data, function (err, data) {
89 + if(data) {
90 + img.src = data
91 + var _data = dataurl.parse(data)
92 + pull(
93 + pull.once(_data.data),
94 + sbot_blobs_add(function (err, hash) {
95 + //TODO. Alerts are EVIL.
96 + //I use them only in a moment of weakness.
97 +
98 + if(err) return alert(err.stack)
99 + selected = {
100 + link: hash,
101 + size: _data.data.length,
102 + type: _data.mimetype,
103 + width: 512,
104 + height: 512
105 + }
106 +
107 + })
108 + )
109 + }
110 + lb.close()
111 + })
112 + lb.show(el)
113 + }),
114 + h('button', 'update', {onclick: function () {
115 + if(name_input.value)
116 + name.textContent = name_input.value
117 +
118 + if(selected)
119 + confirm({
120 + type: 'about',
121 + about: id,
122 + name: name_input.value || undefined,
123 + image: selected
124 + })
125 + else if(name_input.value) //name only
126 + confirm({
127 + type: 'about',
128 + about: id,
129 + name: name_input.value || undefined,
130 + })
131 + else
132 + //another moment of weakness
133 + alert('must select a name or image')
134 + }}),
135 + also_pictured
136 + )
137 + )
138 +}
139 +
140 +
141 +
modules_basic/avatar-image.jsView
@@ -1,0 +1,108 @@
1 +
2 +var getAvatar = require('ssb-avatar')
3 +var h = require('hyperscript')
4 +var ref = require('ssb-ref')
5 +var path = require('path')
6 +var visualize = require('visualize-buffer')
7 +
8 +var plugs = require('../plugs')
9 +var sbot_query = plugs.first(exports.sbot_query = [])
10 +var blob_url = require('../plugs').first(exports.blob_url = [])
11 +
12 +var pull = require('pull-stream')
13 +
14 +var id = require('../keys').id
15 +
16 +var avatars = AVATARS = {}
17 +
18 +function isFunction (f) {
19 + return 'function' === typeof f
20 +}
21 +
22 +var self_id = require('../keys').id
23 +
24 +var ready = false
25 +var waiting = []
26 +
27 +var last = 0
28 +
29 +//blah blah
30 +exports.connection_status = function (err) {
31 + if (err) return
32 +pull(
33 + sbot_query({
34 + query: [{
35 + $filter: {
36 + timestamp: {$gt: last || 0 },
37 + value: { content: {
38 + type: "about",
39 + about: {$prefix: "@"},
40 + image: {link: {$prefix: "&"}}
41 + }}
42 + }},
43 + {
44 + $map: {
45 + id: ["value", "content", "about"],
46 + image: ["value", "content", "image", "link"],
47 + by: ["value", "author"],
48 + ts: 'timestamp'
49 + }}],
50 + live: true
51 + }),
52 + pull.drain(function (a) {
53 + if(a.sync) {
54 + ready = true
55 + while(waiting.length) waiting.shift()()
56 + return
57 + }
58 + last = a.ts
59 + //set image for avatar.
60 + //overwrite another avatar
61 + //you picked.
62 + if(
63 + //if there is no avatar
64 + (!avatars[a.id]) ||
65 + //if i chose this avatar
66 + (a.by == self_id) ||
67 + //they chose their own avatar,
68 + //and current avatar was not chosen by me
69 + (a.by === a.id && avatars[a.id].by != self_id)
70 + )
71 + avatars[a.id] = a
72 +
73 + })
74 +)
75 +}
76 +
77 +exports.avatar_image = function (author, classes) {
78 + classes = classes || ''
79 + if(classes && 'string' === typeof classes) classes = '.avatar--'+classes
80 +
81 + var img = visualize(new Buffer(author.substring(1), 'base64'), 256)
82 + ;(classes || '').split('.').filter(Boolean).forEach(function (c) {
83 + img.classList.add(c)
84 + })
85 +
86 + function go () {
87 + if(avatars[author]) img.src = blob_url(avatars[author].image)
88 + }
89 +
90 + if(!ready)
91 + waiting.push(go)
92 + else go()
93 +
94 + return img
95 +}
96 +
97 +
98 +
99 +
100 +
101 +
102 +
103 +
104 +
105 +
106 +
107 +
108 +
modules_basic/avatar-link.jsView
@@ -1,0 +1,18 @@
1 +var h = require('hyperscript')
2 +var plugs = require('../plugs')
3 +var avatar_name = plugs.first(exports.avatar_name = [])
4 +
5 +var signifier = require('../plugs').first(exports.signifier = [])
6 +
7 +exports.avatar_link = function (id, element) {
8 +
9 + var link = h('a.avatar', {href: "#"+id, title: id}, element)
10 +
11 + signifier(id, function (_, names) {
12 + if(names.length)
13 + link.title = names[0].name + '\n '+id
14 + })
15 +
16 + return link
17 +}
18 +
modules_basic/avatar-name.jsView
@@ -1,0 +1,22 @@
1 +
2 +var signifier = require('../plugs').first(exports.signifier = [])
3 +var h = require('hyperscript')
4 +
5 +exports.avatar_name =
6 +function name (id) {
7 + var n = h('span', id.substring(0, 10))
8 +
9 + //choose the most popular name for this person.
10 + //for anything like this you'll see I have used sbot.links2
11 + //which is the ssb-links plugin. as you'll see the query interface
12 + //is pretty powerful!
13 + //TODO: "most popular" name is easily gameable.
14 + //must come up with something better than this.
15 +
16 + signifier(id, function (_, names) {
17 + if(names.length) n.textContent = names[0].name
18 + })
19 +
20 + return n
21 +}
22 +
modules_basic/avatar-profile.jsView
@@ -1,0 +1,74 @@
1 +var h = require('hyperscript')
2 +var plugs = require('../plugs')
3 +var pull = require('pull-stream')
4 +
5 +var avatar_image_link = plugs.first(exports.avatar_image_link = [])
6 +var avatar_action = plugs.map(exports.avatar_action = [])
7 +var avatar_edit = plugs.first(exports.avatar_edit = [])
8 +
9 +var follows = plugs.first(exports.follows = [])
10 +var followers = plugs.first(exports.followers = [])
11 +
12 +function streamToList(stream, el) {
13 + pull(
14 + stream,
15 + pull.drain(function (item) {
16 + if(item) el.appendChild(item)
17 + })
18 + )
19 + return el
20 +}
21 +
22 +function image_link (id) {
23 + return avatar_image_link(id, 'thumbnail')
24 +}
25 +
26 +exports.avatar_profile = function (id) {
27 +
28 + var follows_el = h('div.profile__follows.wrap')
29 + var friends_el = h('div.profile__friendss.wrap')
30 + var followers_el = h('div.profile__followers.wrap')
31 + var a, b
32 +
33 + pull(follows(id), pull.unique(), pull.collect(function (err, ary) {
34 + a = ary || []; next()
35 + }))
36 + pull(followers(id), pull.unique(), pull.collect(function (err, ary) {
37 + b = ary || {}; next()
38 + }))
39 +
40 + function next () {
41 + if(!(a && b)) return
42 + var _c = [], _a = [], _b = []
43 +
44 + a.forEach(function (id) {
45 + if(!~b.indexOf(id)) _a.push(id)
46 + else _c.push(id)
47 + })
48 + b.forEach(function (id) {
49 + if(!~_c.indexOf(id)) _b.push(id)
50 + })
51 + function add (ary, el) {
52 + ary.forEach(function (id) { el.appendChild(image_link(id)) })
53 + }
54 +
55 + add(_a, follows_el)
56 + add(_c, friends_el)
57 + add(_b, followers_el)
58 + }
59 +
60 +
61 + return h('div.column.profile',
62 + avatar_edit(id),
63 + avatar_action(id),
64 + h('div.profile__relationships.column',
65 + h('strong', 'follows'),
66 + follows_el,
67 + h('strong', 'friends'),
68 + friends_el,
69 + h('strong', 'followers'),
70 + followers_el
71 + )
72 + )
73 +}
74 +
modules_basic/avatar.jsView
@@ -1,0 +1,23 @@
1 +var h = require('hyperscript')
2 +var u = require('../util')
3 +var plugs = require('../plugs')
4 +
5 +var avatar_name = plugs.first(exports.avatar_name = [])
6 +var avatar_image = plugs.first(exports.avatar_image = [])
7 +var avatar_link = plugs.first(exports.avatar_link = [])
8 +
9 +exports.avatar = function (author, classes) {
10 + return exports.avatar_image_name_link(author, classes)
11 +}
12 +
13 +exports.avatar_image_name_link = function (author, classes) {
14 + return avatar_link(author, [
15 + avatar_image(author, classes),
16 + avatar_name(author)
17 + ])
18 +}
19 +
20 +exports.avatar_image_link = function (author, classes) {
21 + return avatar_link(author, avatar_image(author, classes))
22 +}
23 +
modules_basic/compose.jsView
@@ -1,0 +1,150 @@
1 +'use strict'
2 +var h = require('hyperscript')
3 +var u = require('../util')
4 +var suggest = require('suggest-box')
5 +var cont = require('cont')
6 +var mentions = require('ssb-mentions')
7 +var lightbox = require('hyperlightbox')
8 +
9 +var plugs = require('../plugs')
10 +
11 +//var suggest = plugs.map(exports.suggest = [])
12 +var publish = plugs.first(exports.sbot_publish = [])
13 +var message_content = plugs.first(exports.message_content = [])
14 +var message_confirm = plugs.first(exports.message_confirm = [])
15 +var file_input = plugs.first(exports.file_input = [])
16 +
17 +exports.suggest = []
18 +
19 +function id (e) { return e }
20 +
21 +/*
22 + opts can take
23 +
24 + placeholder: string. placeholder text, defaults to "Write a message"
25 + prepublish: function. called before publishing a message.
26 + shrink: boolean. set to false, to make composer not shrink (or hide controls) when unfocused.
27 +*/
28 +
29 +exports.message_compose = function (meta, opts, cb) {
30 + if('function' === typeof cb) {
31 + if('function' === typeof opts)
32 + opts = {prepublish: opts}
33 + }
34 +
35 + if(!opts) opts = {}
36 + opts.prepublish = opts.prepublish || id
37 +
38 + var accessories
39 + meta = meta || {}
40 + if(!meta.type) throw new Error('message must have type')
41 + var ta = h('textarea', {
42 + placeholder: opts.placeholder || 'Write a message',
43 + style: {height: opts.shrink === false ? '200px' : ''}
44 + })
45 +
46 + if(opts.shrink !== false) {
47 + var blur
48 + ta.addEventListener('focus', function () {
49 + clearTimeout(blur)
50 + if(!ta.value) {
51 + ta.style.height = '200px'
52 + }
53 + accessories.style.display = 'block'
54 + })
55 + ta.addEventListener('blur', function () {
56 + //don't shrink right away, so there is time
57 + //to click the publish button.
58 + clearTimeout(blur)
59 + blur = setTimeout(function () {
60 + if(ta.value) return
61 + ta.style.height = '50px'
62 + accessories.style.display = 'none'
63 + }, 200)
64 + })
65 + }
66 +
67 + ta.addEventListener('keydown', function (ev) {
68 + if(ev.keyCode === 13 && ev.ctrlKey) publish()
69 + })
70 +
71 + var files = []
72 + var filesById = {}
73 +
74 + function publish() {
75 + publishBtn.disabled = true
76 + var content
77 + try {
78 + content = JSON.parse(ta.value)
79 + } catch (err) {
80 + meta.text = ta.value
81 + meta.mentions = mentions(ta.value).map(function (mention) {
82 + // merge markdown-detected mention with file info
83 + var file = filesById[mention.link]
84 + if (file) {
85 + if (file.type) mention.type = file.type
86 + if (file.size) mention.size = file.size
87 + }
88 + return mention
89 + })
90 + try {
91 + meta = opts.prepublish(meta)
92 + } catch (err) {
93 + publishBtn.disabled = false
94 + if (cb) cb(err)
95 + else alert(err.message)
96 + }
97 + return message_confirm(meta, done)
98 + }
99 + message_confirm(content, done)
100 +
101 + function done (err, msg) {
102 + publishBtn.disabled = false
103 + if(err) return alert(err.stack)
104 + else if (msg) ta.value = ''
105 +
106 + if (cb) cb(err, msg)
107 + }
108 + }
109 +
110 +
111 + var publishBtn = h('button', 'Publish', {onclick: publish})
112 + var composer =
113 + h('div.compose', h('div.column', ta,
114 + accessories = h('div.row.compose__controls',
115 + //hidden until you focus the textarea
116 + {style: {display: opts.shrink === false ? '' : 'none'}},
117 + file_input(function (file) {
118 + files.push(file)
119 + filesById[file.link] = file
120 +
121 + var embed = file.type.indexOf('image/') === 0 ? '!' : ''
122 + ta.value += embed + '['+file.name+']('+file.link+')'
123 + console.log('added:', file)
124 + }),
125 + publishBtn)
126 + )
127 + )
128 +
129 + suggest(ta, function (word, cb) {
130 + cont.para(exports.suggest.map(function (fn) {
131 + return function (cb) { fn(word, cb) }
132 + }))
133 + (function (err, results) {
134 + if(err) console.error(err)
135 + results = results.reduce(function (ary, item) {
136 + return ary.concat(item)
137 + }, []).sort(function (a, b) {
138 + return b.rank - a.rank
139 + }).filter(Boolean)
140 +
141 + cb(null, results)
142 + })
143 + }, {})
144 +
145 + return composer
146 +
147 +}
148 +
149 +
150 +
modules_basic/feed.jsView
@@ -1,0 +1,56 @@
1 +var ref = require('ssb-ref')
2 +var Scroller = require('pull-scroll')
3 +var h = require('hyperscript')
4 +var pull = require('pull-stream')
5 +var u = require('../util')
6 +
7 +var plugs = require('../plugs')
8 +var sbot_user_feed = plugs.first(exports.sbot_user_feed = [])
9 +var message_render = plugs.first(exports.message_render = [])
10 +var avatar_profile = plugs.first(exports.avatar_profile = [])
11 +var signifier = plugs.first(exports.signifier = [])
12 +
13 +exports.screen_view = function (id) {
14 + //TODO: header of user info, avatars, names, follows.
15 +
16 + if(ref.isFeed(id)) {
17 +
18 + var content = h('div.column.scroller__content')
19 + var div = h('div.column.scroller',
20 + {style: {'overflow':'auto'}},
21 + h('div.scroller__wrapper',
22 + h('div', avatar_profile(id)),
23 + content
24 + )
25 + )
26 +
27 + signifier(id, function (_, names) {
28 + if(names.length) div.title = names[0].name
29 + })
30 +
31 +
32 + pull(
33 + sbot_user_feed({id: id, old: false, live: true}),
34 + Scroller(div, content, message_render, true, false)
35 + )
36 +
37 + //how to handle when have scrolled past the start???
38 +
39 + pull(
40 + u.next(sbot_user_feed, {
41 + id: id, reverse: true,
42 + limit: 50, live: false
43 + }, ['value', 'sequence']),
44 + Scroller(div, content, message_render, false, false)
45 + )
46 +
47 + return div
48 +
49 + }
50 +}
51 +
52 +
53 +
54 +
55 +
56 +
modules_basic/follow.jsView
@@ -1,0 +1,84 @@
1 +var h = require('hyperscript')
2 +var u = require('../util')
3 +var plugs = require('../plugs')
4 +var avatar = plugs.first(exports.avatar = [])
5 +var avatar_name = plugs.first(exports.avatar_name = [])
6 +var avatar_link = plugs.first(exports.avatar_link = [])
7 +var pull = require('pull-stream')
8 +var plugs = require('../plugs')
9 +
10 +//render a message when someone follows someone,
11 +//so you see new users
12 +function isRelated(value, name) {
13 + return value ? name : value === false ? 'un'+name : ''
14 +}
15 +
16 +exports.message_content =
17 +exports.message_content_mini = function (msg) {
18 + var content = msg.value.content
19 + if(content.type == 'contact' && content.contact) {
20 + var relation = isRelated(content.following, 'follows')
21 + if(content.blocking) relation = 'blocks'
22 + return [
23 + relation, ' ',
24 + avatar_link(content.contact, avatar_name(content.contact), '')
25 + ]
26 + }
27 +}
28 +
29 +exports.message_content = function (msg) {
30 +
31 + var content = msg.value.content
32 + if(content.type == 'contact' && content.contact) {
33 + var relation = isRelated(content.following, 'follows')
34 + if(content.blocking) relation = 'blocks'
35 + return h('div.contact', relation, avatar(msg.value.content.contact, 'thumbnail'))
36 + }
37 +}
38 +
39 +var message_confirm = plugs.first(exports.message_confirm = [])
40 +var follower_of = plugs.first(exports.follower_of = [])
41 +
42 +exports.avatar_action = function (id) {
43 + var follows_you, you_follow
44 +
45 + var self_id = require('../keys').id
46 + follower_of(self_id, id, function (err, f) {
47 + you_follow = f
48 + update()
49 + })
50 + follower_of(id, self_id, function (err, f) {
51 + follows_you = f
52 + update()
53 + })
54 +
55 + var state = h('label')
56 + var label = h('label')
57 +
58 + function update () {
59 + state.textContent = (
60 + follows_you && you_follow ? 'friend'
61 + : follows_you ? 'follows you'
62 + : you_follow ? 'you follow'
63 + : ''
64 + )
65 +
66 + label.textContent = you_follow ? 'unfollow' : 'follow'
67 + }
68 +
69 + return h('div', state,
70 + h('a', {href:'#', onclick: function () {
71 + message_confirm({
72 + type: 'contact',
73 + contact: id,
74 + following: !you_follow
75 + }, function (err) {
76 + //TODO: update after following.
77 + })
78 + }}, h('br'), label)
79 + )
80 +}
81 +
82 +
83 +
84 +
modules_basic/index.jsView
@@ -1,0 +1,29 @@
1 +module.exports = {
2 + "about.js": require('./about.js'),
3 + "avatar-edit.js": require('./avatar-edit.js'),
4 + "avatar-image.js": require('./avatar-image.js'),
5 + "avatar-link.js": require('./avatar-link.js'),
6 + "avatar-name.js": require('./avatar-name.js'),
7 + "avatar-profile.js": require('./avatar-profile.js'),
8 + "avatar.js": require('./avatar.js'),
9 + "compose.js": require('./compose.js'),
10 + "feed.js": require('./feed.js'),
11 + "follow.js": require('./follow.js'),
12 + "invite.js": require('./invite.js'),
13 + "like.js": require('./like.js'),
14 + "markdown.js": require('./markdown.js'),
15 + "message-link.js": require('./message-link.js'),
16 + "message-name.js": require('./message-name.js'),
17 + "message.js": require('./message.js'),
18 + "names.js": require('./names.js'),
19 + "post.js": require('./post.js'),
20 + "private.js": require('./private.js'),
21 + "public.js": require('./public.js'),
22 + "relationships.js": require('./relationships.js'),
23 + "search-box.js": require('./search-box.js'),
24 + "setup.js": require('./setup'),
25 + "suggest-mentions.js": require('./suggest-mentions.js'),
26 + "suggest.js": require('./suggest.js'),
27 + "thread.js": require('./thread.js'),
28 + "timestamp.js": require('./timestamp.js')
29 +}
modules_basic/invite.jsView
@@ -1,0 +1,112 @@
1 +
2 +var ref = require('ssb-ref')
3 +var ssbClient = require('ssb-client')
4 +var id = require('../keys').id
5 +var h = require('hyperscript')
6 +
7 +var Progress = require('hyperprogress')
8 +
9 +var plugs = require('../plugs')
10 +var sbot_publish = plugs.first(exports.sbot_publish = [])
11 +var sbot_gossip_connect = plugs.first(exports.sbot_gossip_connect = [])
12 +var follower_of = plugs.first(exports.follower_of = [])
13 +
14 +exports.invite_parse = function (invite) {
15 + return ref.parseInvite(invite)
16 +}
17 +
18 +exports.invite_accept = function (invite, onProgress, cb) {
19 + var data = exports.invite_parse(invite)
20 + if(!data) return cb(new Error('not a valid invite code:' + invite))
21 +
22 + onProgress('connecting...')
23 +
24 + sbot_gossip_connect(data.remote, function (err) {
25 + if(err) console.log(err)
26 + })
27 +
28 + ssbClient(null, {
29 + remote: data.invite,
30 + manifest: { invite: {use: 'async'}, getAddress: 'async' }
31 + }, function (err, sbot) {
32 + if(err) return cb(err)
33 + onProgress('requesting follow...')
34 + console.log(sbot)
35 + sbot.invite.use({feed: id}, function (err, msg) {
36 +
37 + //if they already follow us, just check we actually follow them.
38 + if(err) follower_of(id, data.key, function (_err, follows) {
39 + if(follows) cb(err)
40 + else next()
41 + })
42 + else next()
43 +
44 + function next () {
45 + onProgress('following...')
46 +
47 + //remove the seed from the shs address.
48 + //then it's correct address.
49 + //this should make the browser connect to this as remote.
50 + //we don't want to do this if when using this locally, though.
51 + if(process.title === 'browser')
52 + localStorage.remote = data.remote
53 +
54 + sbot_publish({
55 + type: 'contact',
56 + contact: data.key,
57 + following: true,
58 + }, cb)
59 + }
60 + })
61 + })
62 +}
63 +
64 +exports.screen_view = function (invite) {
65 +
66 + var data = ref.parseInvite(invite)
67 + if(!data) return
68 +
69 + var progress = Progress(4)
70 +
71 + //connect to server
72 + //request follow
73 + //post pub announce
74 + //post follow pub
75 + var div = h('div.column',
76 + h('div',
77 + "you have been invited to join:", h('br'),
78 + h('code', data.invite)
79 + ),
80 + h('button', 'accept', {onclick: attempt}),
81 + progress
82 + )
83 +
84 + function attempt () {
85 + exports.invite_accept(invite, function (message) {
86 + progress.next(message)
87 + }, function (err) {
88 + if(err) return progress.fail(err)
89 + progress.complete()
90 + //check for redirect
91 + var parts = location.hash.substring(1).split('#')
92 +
93 + //TODO: handle in a consistent way with either hashrouting
94 + //or with tabs...
95 + if(parts[0] === data.invite)
96 + location.hash = data.redirect
97 + else
98 + console.log("NO REDIRECT")
99 + })
100 + }
101 +
102 + // If we are in the browser,
103 + // and do not already have a remote set, automatically trigger the invite.
104 + if(process.title == 'browser' && !localStorage.remote) attempt()
105 +
106 + return div
107 +}
108 +
109 +
110 +
111 +
112 +
modules_basic/like.jsView
@@ -1,0 +1,62 @@
1 +
2 +var h = require('hyperscript')
3 +var u = require('../util')
4 +var pull = require('pull-stream')
5 +
6 +var plugs = require('../plugs')
7 +
8 +var message_confirm = plugs.first(exports.message_confirm = [])
9 +var message_link = plugs.first(exports.message_link = [])
10 +var sbot_links = plugs.first(exports.sbot_links = [])
11 +
12 +
13 +exports.message_content =
14 +exports.message_content_mini = function (msg, sbot) {
15 + if(msg.value.content.type !== 'vote') return
16 + var link = msg.value.content.vote.link
17 + return [
18 + msg.value.content.vote.value > 0 ? 'dug' : 'undug',
19 + ' ', message_link(link)
20 + ]
21 +}
22 +
23 +exports.message_meta = function (msg, sbot) {
24 + var digs = h('a')
25 +
26 + var votes = []
27 + for(var k in CACHE) {
28 + if(CACHE[k].content.type == 'vote' &&
29 + (CACHE[k].content.vote == msg.key ||
30 + CACHE[k].content.vote.link == msg.key
31 + ))
32 + votes.push({source: CACHE[k].author, dest: k, rel: 'vote'})
33 + }
34 +
35 + if(votes.length === 1)
36 + digs.textContent = ' 1 Dig'
37 + if(votes.length > 1)
38 + digs.textContent = ' ' + votes.length + ' Digs'
39 +
40 + return digs
41 +}
42 +
43 +exports.message_action = function (msg, sbot) {
44 + if(msg.value.content.type !== 'vote')
45 + return h('a.dig', {href: '#', onclick: function () {
46 + var dig = {
47 + type: 'vote',
48 + vote: { link: msg.key, value: 1, expression: 'Dig' }
49 + }
50 + if(msg.value.content.recps) {
51 + dig.recps = msg.value.content.recps.map(function (e) {
52 + return e && typeof e !== 'string' ? e.link : e
53 + })
54 + dig.private = true
55 + }
56 + //TODO: actually publish...
57 +
58 + message_confirm(dig)
59 + }}, 'Dig')
60 +
61 +}
62 +
modules_basic/markdown.jsView
@@ -1,0 +1,28 @@
1 +var markdown = require('ssb-markdown')
2 +var h = require('hyperscript')
3 +var ref = require('ssb-ref')
4 +
5 +var blob_url = require('../plugs').first(exports.blob_url = [])
6 +
7 +exports.markdown = function (content) {
8 + if('string' === typeof content)
9 + content = {text: content}
10 + //handle patchwork style mentions.
11 + var mentions = {}
12 + if(Array.isArray(content.mentions))
13 + content.mentions.forEach(function (link) {
14 + if(link.name) mentions["@"+link.name] = link.link
15 + })
16 +
17 + var md = h('div.markdown')
18 + md.innerHTML = markdown.block(content.text, {
19 + toUrl: function (id) {
20 + if(ref.isBlob(id)) return blob_url(id)
21 + return '#'+(mentions[id]?mentions[id]:id)
22 + }
23 + })
24 +
25 + return md
26 +
27 +}
28 +
modules_basic/message-link.jsView
@@ -1,0 +1,33 @@
1 +var h = require('hyperscript')
2 +var ref = require('ssb-ref')
3 +
4 +var first = require('../plugs').first
5 +var sbot_get = first(exports.sbot_get = [])
6 +var message_name = first(exports.message_name = [])
7 +
8 +exports.message_link = function (id) {
9 +
10 + if('string' !== typeof id)
11 + throw new Error('link must be to message id')
12 +
13 + var link = h('a', {href: '#'+id}, id.substring(0, 10)+'...')
14 +
15 + if(ref.isMsg(id))
16 + message_name(id, function (err, name) {
17 + if(err) console.error(err)
18 + else link.textContent = name
19 + })
20 +
21 + return link
22 +}
23 +
24 +
25 +
26 +
27 +
28 +
29 +
30 +
31 +
32 +
33 +
modules_basic/message-name.jsView
@@ -1,0 +1,15 @@
1 +
2 +var sbot_get = require('../plugs').first(exports.sbot_get = [])
3 +
4 +exports.message_name = function (id, cb) {
5 + sbot_get(id, function (err, value) {
6 + if(err && err.name == 'NotFoundError')
7 + return cb(null, id.substring(0, 10)+'...(missing)')
8 + if(value.content.type === 'post' && 'string' === typeof value.content.text)
9 + return cb(null, value.content.text.substring(0, 40)+'...')
10 + else if('string' === typeof value.content.text)
11 + return cb(null, value.content.type + ':'+value.content.text.substring(0, 20))
12 + else
13 + return cb(null, id.substring(0, 10)+'...')
14 + })
15 +}
modules_basic/message.jsView
@@ -1,0 +1,98 @@
1 +var h = require('hyperscript')
2 +var u = require('../util')
3 +var pull = require('pull-stream')
4 +
5 +var plugs = require('../plugs')
6 +var message_content = plugs.first(exports.message_content = [])
7 +var message_content_mini = plugs.first(exports.message_content_mini = [])
8 +var avatar = plugs.first(exports.avatar = [])
9 +var avatar_name = plugs.first(exports.avatar_name = [])
10 +var avatar_link = plugs.first(exports.avatar_link = [])
11 +var message_meta = plugs.map(exports.message_meta = [])
12 +var message_action = plugs.map(exports.message_action = [])
13 +var message_link = plugs.first(exports.message_link = [])
14 +
15 +var sbot_links = plugs.first(exports.sbot_links = [])
16 +
17 +exports.message_render = function (msg, sbot) {
18 + var elMini = message_content_mini(msg)
19 + if (elMini) {
20 + var div = h('div.message.message--mini',
21 + h('div.row',
22 + h('div',
23 + avatar_link(msg.value.author, avatar_name(msg.value.author)),
24 + h('span.message_content', elMini)),
25 + h('div.message_meta.row', message_meta(msg))
26 + )
27 + )
28 + div.setAttribute('tabindex', '0')
29 + return div
30 + }
31 +
32 + var el = message_content(msg)
33 + if(!el) return
34 +
35 + var links = []
36 + for(var k in CACHE) {
37 + var _msg = CACHE[k]
38 + if(Array.isArray(_msg.content.mentions)) {
39 + for(var i = 0; i < _msg.content.mentions.length; i++)
40 + if(_msg.content.mentions[i].link == msg.key)
41 + links.push(k)
42 + }
43 + }
44 +
45 + var backlinks = h('div.backlinks')
46 + if(links.length)
47 + backlinks.appendChild(h('label', 'backlinks:',
48 + h('div', links.map(function (key) {
49 + return message_link(key)
50 + }))
51 + ))
52 +
53 +
54 +// pull(
55 +// sbot_links({dest: msg.key, rel: 'mentions', keys: true}),
56 +// pull.collect(function (err, links) {
57 +// if(links.length)
58 +// backlinks.appendChild(h('label', 'backlinks:',
59 +// h('div', links.map(function (link) {
60 +// return message_link(link.key)
61 +// }))
62 +// ))
63 +// })
64 +// )
65 +
66 + var msg = h('div.message',
67 + h('div.title.row',
68 + h('div.avatar', avatar(msg.value.author, 'thumbnail')),
69 + h('div.message_meta.row', message_meta(msg))
70 + ),
71 + h('div.message_content', el),
72 + h('div.message_actions.row',
73 + h('div.actions', message_action(msg),
74 + h('a', {href: '#' + msg.key}, 'Reply')
75 + )
76 + ),
77 + backlinks,
78 + {onkeydown: function (ev) {
79 + //on enter, hit first meta.
80 + if(ev.keyCode == 13) {
81 + msg.querySelector('.enter').click()
82 + }
83 + }}
84 + )
85 +
86 + // ); hyperscript does not seem to set attributes correctly.
87 + msg.setAttribute('tabindex', '0')
88 +
89 + return msg
90 +}
91 +
92 +
93 +
94 +
95 +
96 +
97 +
98 +
modules_basic/names.jsView
@@ -1,0 +1,148 @@
1 +var pull = require('pull-stream')
2 +var many = require('pull-many')
3 +var mfr = require('map-filter-reduce')
4 +
5 +function all(stream, cb) {
6 + pull(stream, pull.collect(cb))
7 +}
8 +
9 +var plugs = require('../plugs')
10 +var sbot_links2 = plugs.first(exports.sbot_links2 = [])
11 +var sbot_query = plugs.first(exports.sbot_query = [])
12 +
13 +/*
14 + filter(rel: ['mentions', prefix('@')]) | reduce(name: rel[1], value: count())
15 +*/
16 +
17 +var filter = {
18 + $filter: {
19 + rel: ["mentions", {$prefix: "@"}]
20 + }
21 +}
22 +var map = {
23 + $map: {
24 + name: ['rel', 1],
25 + id: 'dest',
26 + ts: 'ts',
27 + }
28 +}
29 +
30 +var reduce = {
31 + $reduce: {
32 + name: 'name',
33 + id: 'id',
34 + rank: {$count: true},
35 + ts: {$max: 'ts'}
36 + }
37 +}
38 +
39 +var filter2 = {
40 + $filter: {
41 + value: {
42 + content: {
43 + type: "about",
44 + name: {"$prefix": ""},
45 + about: {"$prefix": "@"} //better: match regexp.
46 + }
47 + }
48 + }
49 +}
50 +
51 +var map2 = {
52 + $map: {
53 + name: ["value", "content", "name"],
54 + id: ['value', 'content', 'about'],
55 + ts: "timestamp"
56 + }
57 +}
58 +
59 +//union with this query...
60 +
61 +var names = NAMES = []
62 +function update(name) {
63 + var n = names.find(function (e) {
64 + return e.id == name.id && e.name == e.name
65 + })
66 + if(!n) {
67 + name.rank = 1
68 + //this should be inserted at the right place...
69 + names.push(name)
70 + }
71 + else
72 + n.rank = n.rank += (name.rank || 1)
73 +}
74 +
75 +var ready = false, waiting = []
76 +
77 +var merge = {
78 + $reduce: {
79 + name: 'name',
80 + id: 'id',
81 + rank: {$sum: 'rank'},
82 + ts: {$max: 'ts'}
83 + }
84 +}
85 +
86 +function add_at(stream) {
87 + return pull(stream, pull.map(function (e) {
88 + if(!/^@/.test(e.name)) e.name = '@'+e.name
89 + return e
90 + })
91 + )
92 +}
93 +
94 +exports.connection_status = function (err) {
95 + if(!err) {
96 + pull(
97 + many([
98 + sbot_links2({query: [filter, map, reduce]}),
99 + add_at(sbot_query({query: [filter2, map2, reduce]}))
100 + ]),
101 + //reducing also ensures order by the lookup properties
102 + //in this case: [name, id]
103 + mfr.reduce(merge),
104 + pull.collect(function (err, ary) {
105 + if(!err) {
106 + NAMES = names = ary
107 + ready = true
108 + while(waiting.length) waiting.shift()()
109 + }
110 + })
111 + )
112 +
113 + pull(many([
114 + sbot_links2({query: [filter, map], old: false}),
115 + add_at(sbot_query({query: [filter2, map2], old: false}))
116 + ]),
117 + pull.drain(update))
118 + }
119 +}
120 +
121 +function async(fn) {
122 + return function (value, cb) {
123 + function go () { cb(null, fn(value)) }
124 + if(ready) go()
125 + else waiting.push(go)
126 + }
127 +}
128 +
129 +function rank(ary) {
130 + //sort by most used, or most recently used
131 + return ary.sort(function (a, b) { return b.rank - a.rank || b.ts - a.ts })
132 +}
133 +
134 +//we are just iterating over the entire array.
135 +//if this becomes a problem, maintain two arrays
136 +//one of each sort order, but do not duplicate the objects.
137 +//that should mean the space required is just 2x object references,
138 +//not 2x objects, and we can use binary search to find matches.
139 +
140 +exports.signifier = async(function (id) {
141 + return rank(names.filter(function (e) { return e.id == id}))
142 +})
143 +
144 +exports.signified = async(function (name) {
145 + var rx = new RegExp('^'+name)
146 + return rank(names.filter(function (e) { return rx.test(e.name) }))
147 +})
148 +
modules_basic/post.jsView
@@ -1,0 +1,37 @@
1 +var markdown = require('ssb-markdown')
2 +var h = require('hyperscript')
3 +var u = require('../util')
4 +var ref = require('ssb-ref')
5 +
6 +//render a message
7 +
8 +var plugs = require('../plugs')
9 +var message_link = plugs.first(exports.message_link = [])
10 +var markdown = plugs.first(exports.markdown = [])
11 +
12 +exports.message_content = function (data) {
13 + if(!data.value.content || !data.value.content.text) return
14 +
15 + var root = data.value.content.root
16 + var re = !root ? null : h('span', 're: ', message_link(root))
17 +
18 + return h('div',
19 + re,
20 + markdown(data.value.content)
21 + )
22 +
23 +}
24 +
25 +
26 +
27 +
28 +
29 +
30 +
31 +
32 +
33 +
34 +
35 +
36 +
37 +
modules_basic/private.jsView
@@ -1,0 +1,85 @@
1 +var h = require('hyperscript')
2 +var u = require('../util')
3 +var pull = require('pull-stream')
4 +var Scroller = require('pull-scroll')
5 +var ref = require('ssb-ref')
6 +
7 +var plugs = require('../plugs')
8 +
9 +var message_render = plugs.first(exports.message_render = [])
10 +var message_compose = plugs.first(exports.message_compose = [])
11 +var message_unbox = plugs.first(exports.message_unbox = [])
12 +var sbot_log = plugs.first(exports.sbot_log = [])
13 +var avatar_image_link = plugs.first(exports.avatar_image_link = [])
14 +
15 +function unbox () {
16 + return pull(
17 + pull.filter(function (msg) {
18 + return 'string' == typeof msg.value.content
19 + }),
20 + pull.map(function (msg) {
21 + return message_unbox(msg)
22 + }),
23 + pull.filter(Boolean)
24 + )
25 +}
26 +
27 +exports.screen_view = function (path) {
28 +
29 + if(path === '/private') {
30 + //if(process.title === 'browser')
31 + //return h('div', h('h4', 'Private messages are not supported in the lite client.'))
32 +
33 +
34 + var id = require('../keys').id
35 + var compose = message_compose(
36 + {type: 'post', recps: [], private: true},
37 + {
38 + prepublish: function (msg) {
39 + msg.recps = [id].concat(msg.mentions).filter(function (e) {
40 + return ref.isFeed('string' === typeof e ? e : e.link)
41 + })
42 + if(!msg.recps.length)
43 + throw new Error('cannot make private message without recipients - just mention the user in an at reply in the message you send')
44 + return msg
45 + },
46 + placeholder: 'Write a private message'
47 + }
48 + )
49 +
50 + var content = h('div.column.scroller__content')
51 + var div = h('div.column.scroller',
52 + {style: {'overflow':'auto'}},
53 + h('div.scroller__wrapper', compose, content)
54 + )
55 +
56 + pull(
57 + u.next(sbot_log, {old: false, limit: 100}),
58 + unbox(),
59 + Scroller(div, content, message_render, true, false)
60 + )
61 +
62 + pull(
63 + u.next(sbot_log, {reverse: true, limit: 1000}),
64 + unbox(),
65 + Scroller(div, content, message_render, false, false, function (err) {
66 + if(err) throw err
67 + })
68 + )
69 +
70 + return div
71 + }
72 +}
73 +
74 +function map(ary, iter) {
75 + if(Array.isArray(ary)) return ary.map(iter)
76 +}
77 +
78 +exports.message_meta = function (msg) {
79 + if(msg.value.content.recps || msg.value.private)
80 + return h('span.row', 'PRIVATE', map(msg.value.content.recps, function (id) {
81 + return avatar_image_link('string' == typeof id ? id : id.link, 'thumbnail')
82 + }))
83 +}
84 +
85 +
modules_basic/public.jsView
@@ -1,0 +1,57 @@
1 +var h = require('hyperscript')
2 +var u = require('../util')
3 +var pull = require('pull-stream')
4 +var Scroller = require('pull-scroll')
5 +
6 +var plugs = require('../plugs')
7 +var message_render = plugs.first(exports.message_render = [])
8 +var message_compose = plugs.first(exports.message_compose = [])
9 +var sbot_log = plugs.first(exports.sbot_log = [])
10 +
11 +exports.screen_view = function (path, sbot) {
12 + if(path === '/public') {
13 +
14 + var content = h('div.column.scroller__content')
15 + var div = h('div.column.scroller',
16 + {style: {'overflow':'auto'}},
17 + h('div.scroller__wrapper',
18 + message_compose({type: 'post'}, {placeholder: 'Write a public message'}),
19 + content
20 + )
21 + )
22 +
23 + pull(
24 + u.next(sbot_log, {old: false, limit: 100}),
25 + Scroller(div, content, message_render, true, false)
26 + )
27 +
28 + pull(
29 + u.next(sbot_log, {reverse: true, limit: 100, live: false}),
30 + Scroller(div, content, message_render, false, false)
31 + )
32 +
33 + return div
34 + }
35 +}
36 +
37 +
38 +
39 +
40 +
41 +
42 +
43 +
44 +
45 +
46 +
47 +
48 +
49 +
50 +
51 +
52 +
53 +
54 +
55 +
56 +
57 +
modules_basic/relationships.jsView
@@ -1,0 +1,50 @@
1 +var pull = require('pull-stream')
2 +var plugs = require('../plugs')
3 +
4 +var sbot_query = plugs.first(exports.sbot_query = [])
5 +
6 +//this is a bit crude, and doesn't actually show unfollows yet.
7 +
8 +function makeQuery (a, b) {
9 + return {"$filter": {
10 + value: {
11 + author: a,
12 + content: {
13 + type: 'contact',
14 + contact: b,
15 + following: true
16 + }
17 + },
18 + }}
19 +}
20 +
21 +
22 +exports.follows = function (id, cb) {
23 + return sbot_query({query: [
24 + makeQuery(id, {$prefix:"@"}),
25 + {"$map": ['value', 'content', 'contact']}
26 + ]})
27 +}
28 +
29 +exports.followers = function (id) {
30 + return sbot_query({query: [
31 + makeQuery({$prefix:"@"}, id),
32 + {"$map": ['value', 'author']}
33 + ]})
34 +}
35 +
36 +exports.follower_of = function (source, dest, cb) {
37 + pull(
38 + sbot_query({query: [
39 + makeQuery(source, dest),
40 + {$map: ['value', 'content', 'following']}
41 + ]}),
42 + pull.collect(function (err, ary) {
43 + if(err) return cb(err)
44 + else cb(null, ary.pop()) //will be true, or undefined/false
45 + })
46 + )
47 +}
48 +
49 +
50 +
modules_basic/search-box.jsView
@@ -1,0 +1,112 @@
1 +var h = require('hyperscript')
2 +var suggest = require('suggest-box')
3 +var pull = require('pull-stream')
4 +var plugs = require('../plugs')
5 +var sbot_query = plugs.first(exports.sbot_query = [])
6 +var sbot_links2 = plugs.first(exports.sbot_links2 = [])
7 +
8 +var channels = []
9 +
10 +var signified = require('../plugs').first(exports.signified = [])
11 +
12 +//TODO: this list should be generated from plugs
13 +var builtinTabs = [
14 + '/public', '/private', '/notifications',
15 + '/network', '/query', '/versions'
16 +].map(function (name) {
17 + return {
18 + title: name,
19 + value: name,
20 + }
21 +})
22 +
23 +exports.search_box = function (go) {
24 +
25 + var suggestBox
26 + var search = h('input.searchprompt', {
27 + type: 'search',
28 + placeholder: 'Commands',
29 + onkeydown: function (ev) {
30 + switch (ev.keyCode) {
31 + case 13: // enter
32 + if (suggestBox && suggestBox.active) {
33 + suggestBox.complete()
34 + ev.stopPropagation()
35 + }
36 + if (go(search.value.trim(), !ev.ctrlKey))
37 + search.blur()
38 + return
39 + case 27: // escape
40 + ev.preventDefault()
41 + search.blur()
42 + return
43 + }
44 + }
45 + })
46 +
47 + search.activate = function (sigil, ev) {
48 + search.focus()
49 + ev.preventDefault()
50 + if (search.value[0] === sigil) {
51 + search.selectionStart = 1
52 + search.selectionEnd = search.value.length
53 + } else {
54 + search.value = sigil
55 + }
56 + }
57 +
58 + var suggestions = {}
59 +
60 + // delay until the element has a parent
61 + setTimeout(function () {
62 + suggestBox = suggest(search, function (word, cb) {
63 + if(/^#\w/.test(word))
64 + cb(null, channels.filter(function (chan) {
65 + return ('#'+chan.name).substring(0, word.length) === word
66 + })
67 + .map(function (chan) {
68 + var name = '#'+chan.name
69 + return {
70 + title: name,
71 + value: name,
72 + subtitle: chan.rank
73 + }
74 + }))
75 + else if(/^@\w/.test(word)) {
76 + signified(word, function (_, names) {
77 + cb(null, names.map(function (e) {
78 + return {
79 + title: e.name + ':'+e.id.substring(0, 10),
80 + value: e.id,
81 + subtitle: e.rank
82 + }
83 + }))
84 + })
85 + } else if(/^\//.test(word)) {
86 + cb(null, builtinTabs.filter(function (name) {
87 + return name.value.substr(0, word.length) === word
88 + }))
89 + }
90 + }, {})
91 + }, 10)
92 +
93 +
94 + pull(
95 + sbot_query({query: [
96 + {$filter: {value: {content: {channel: {$gt: ''}}}}},
97 + {$reduce: {
98 + name: ['value', 'content', 'channel'],
99 + rank: {$count: true}
100 + }}
101 + ]}),
102 + pull.collect(function (err, chans) {
103 + if (err) return console.error(err)
104 + channels = chans
105 + })
106 + )
107 +
108 + return search
109 +}
110 +
111 +
112 +
modules_basic/setup.jsView
@@ -1,0 +1,145 @@
1 +
2 +var h = require('hyperscript')
3 +var pull = require('pull-stream')
4 +
5 +var plugs = require('../plugs')
6 +
7 +var avatar_edit = plugs.first(exports.avatar_edit = [])
8 +var invite_parse = plugs.first(exports.invite_parse = [])
9 +var invite_accept = plugs.first(exports.invite_accept = [])
10 +var sbot_progress = plugs.first(exports.sbot_progress = [])
11 +var sbot_query = plugs.first(exports.sbot_query = [])
12 +var avatar = plugs.first(exports.avatar = [])
13 +
14 +//maybe this could show the pubs, or
15 +//if someone locally follows you,
16 +//it could show the second degree pubs?
17 +
18 +//maybe show the network as animated graph?
19 +
20 +function followers_query (id) {
21 + return [{$filter: {
22 + value: {content: {
23 + type: "contact",
24 + contact: id,
25 + following: true,
26 +// autofollow: true
27 + }}
28 + }}]
29 +}
30 +
31 +//test whether we are connected to the ssb network.
32 +exports.setup_is_fresh_install = function (cb) {
33 + //test by checking whether you have any friends following you?
34 + pull(
35 + sbot_query({query: followers_query(id), limit: 1, live: false}),
36 + pull.collect(function (err, ary) {
37 + cb(err, !!ary.length)
38 + })
39 + )
40 +}
41 +
42 +function invite_form () {
43 + var accept = h('button', 'enter code', {disabled: true, onclick: function () {
44 + invite_accept(input.value, function (msg) {
45 + status.textContent = msg
46 + }, function (err) {
47 + if(err) {
48 + accept.textContent = 'error:'+(err.message || err.stack || error.type)
49 + console.error(err)
50 + }
51 + else {
52 + input.value = ''
53 + accept.textContent = 'success!'
54 + }
55 + })
56 + }})
57 +
58 + function parseInput () {
59 + if(!input.value) {
60 + accept.disabled = true
61 + accept.textContent = 'enter code'
62 + }
63 + else if(!invite_parse(input.value)) {
64 + accept.disabled = true
65 + accept.textContent = 'invalid code'
66 + }
67 + else {
68 + accept.disabled = false
69 + accept.textContent = 'accept'
70 + }
71 + }
72 +
73 + var input = h('input.wide', {placeholder: 'invite code', oninput: parseInput, onchange: parseInput})
74 +
75 + return h('div.invite-form.row', input, accept)
76 +}
77 +
78 +exports.progress_bar = function () {
79 + var liquid = h('div.hyperprogress__liquid', '.')
80 + var bar = h('div.hyperprogress__bar', liquid)
81 + liquid.style.width = '0%'
82 +
83 + pull(
84 + sbot_progress(),
85 + pull.drain(function (e) {
86 + liquid.style.width = Math.round((e.progress/e.total)*100)+'%'
87 + })
88 + )
89 +
90 + return bar
91 +}
92 +
93 +//show the first 5 followers, and how they join you to the network.
94 +//so this will show if a local peer follows you.
95 +
96 +//when you join the network, I want this to show as people follow you.
97 +//that could be when a pub accepts the invite, or when a local peer accepts.
98 +
99 +exports.setup_joined_network = function (id) {
100 + var followers = h('div.column')
101 + var label = h('label', 'not connected to a network')
102 + var joined = h('div.setup__joined', label,followers)
103 +
104 + pull(
105 + sbot_query({query: followers_query(id), limit: 5, live: true, sync: false}),
106 + pull.drain(function (follower) {
107 + if(follower.sync) return
108 + label.textContent = 'connected to network via...'
109 + followers.appendChild(
110 + avatar(follower.value.author, 'thumbnail')
111 + )
112 + })
113 + )
114 +
115 + return joined
116 +}
117 +
118 +exports.screen_view = function (path) {
119 +
120 + if(path !== '/setup') return
121 +
122 + var id = require('../keys').id
123 +
124 + //set up an avatar
125 +
126 +
127 + var status = h('span')
128 + var invite = h('input', {placeholder: 'invite code'})
129 + return h('div.scroller', h('div.scroller__wrapper',
130 + h('h1', 'welcome to patchbay!'),
131 + h('div',
132 + 'please choose avatar image and name',
133 + avatar_edit(id)
134 + ),
135 + h('h2', 'join network'),
136 + invite_form(),
137 + //show avatars of anyone on the same local network.
138 + //show realtime changes in your followers, especially for local.
139 +
140 + exports.progress_bar(),
141 + exports.setup_joined_network(require('../keys').id)
142 + ))
143 +}
144 +
145 +
modules_basic/suggest-mentions.jsView
@@ -1,0 +1,40 @@
1 +var pull = require('pull-stream')
2 +var cont = require('cont')
3 +function isImage (filename) {
4 + return /\.(gif|jpg|png|svg)$/i.test(filename)
5 +}
6 +
7 +var sbot_links2 = require('../plugs').first(exports.sbot_links2 = [])
8 +var blob_url = require('../plugs').first(exports.blob_url = [])
9 +var signified = require('../plugs').first(exports.signified = [])
10 +
11 +exports.suggest = cont.to(function (word, cb) {
12 + if(!/^@\w/.test(word)) return cb()
13 +
14 +
15 + signified(word, function (err, names) {
16 + if(err) cb(err)
17 + else cb(null, names.map(function (e) {
18 + return {
19 + title: e.name + ': ' + e.id.substring(0,10)+' ('+e.rank+')',
20 + value: '['+e.name+']('+e.id+')',
21 + rank: e.rank,
22 + //TODO: avatar images...
23 + }
24 + }))
25 + })
26 +})
27 +
28 +
29 +
30 +
31 +
32 +
33 +
34 +
35 +
36 +
37 +
38 +
39 +
40 +
modules_basic/suggest.jsView
@@ -1,0 +1,3 @@
1 +
2 +
3 +
modules_basic/thread.jsView
@@ -1,0 +1,122 @@
1 +var pull = require('pull-stream')
2 +var Cat = require('pull-cat')
3 +var sort = require('ssb-sort')
4 +var ref = require('ssb-ref')
5 +var h = require('hyperscript')
6 +var u = require('../util')
7 +var Scroller = require('pull-scroll')
8 +var self_id = require('../keys').id
9 +
10 +function once (cont) {
11 + var ended = false
12 + return function (abort, cb) {
13 + if(abort) return cb(abort)
14 + else if (ended) return cb(ended)
15 + else
16 + cont(function (err, data) {
17 + if(err) return cb(ended = err)
18 + ended = true
19 + cb(null, data)
20 + })
21 + }
22 +}
23 +
24 +var plugs = require('../plugs')
25 +
26 +var message_render = plugs.first(exports.message_render = [])
27 +var message_name = plugs.first(exports.message_name = [])
28 +var message_compose = plugs.first(exports.message_compose = [])
29 +var message_unbox = plugs.first(exports.message_unbox = [])
30 +
31 +var sbot_get = plugs.first(exports.sbot_get = [])
32 +var sbot_links = plugs.first(exports.sbot_links = [])
33 +
34 +function getThread (root, cb) {
35 + //in this case, it's inconvienent that panel only takes
36 + //a stream. maybe it would be better to accept an array?
37 +
38 + sbot_get(root, function (err, value) {
39 + var msg = {key: root, value: value}
40 +// if(value.content.root) return getThread(value.content.root, cb)
41 +
42 + pull(
43 + sbot_links({rel: 'root', dest: root, values: true, keys: true}),
44 + pull.collect(function (err, ary) {
45 + if(err) return cb(err)
46 + ary.unshift(msg)
47 + cb(null, ary)
48 + })
49 + )
50 + })
51 +
52 +}
53 +
54 +exports.screen_view = function (id) {
55 + if(ref.isMsg(id)) {
56 + var meta = {
57 + type: 'post',
58 + root: id,
59 + branch: id //mutated when thread is loaded.
60 + }
61 +
62 + var content = h('div.column.scroller__content')
63 + var div = h('div.column.scroller',
64 + {style: {'overflow-y': 'auto'}},
65 + h('div.scroller__wrapper',
66 + content,
67 + message_compose(meta, {shrink: false, placeholder: 'Write a reply'})
68 + )
69 + )
70 +
71 + message_name(id, function (err, name) {
72 + div.title = name
73 + })
74 +
75 + pull(
76 + sbot_links({
77 + rel: 'root', dest: id, keys: true, old: false
78 + }),
79 + pull.drain(function (msg) {
80 + loadThread() //redraw thread
81 + }, function () {} )
82 + )
83 +
84 +
85 + function loadThread () {
86 + getThread(id, function (err, thread) {
87 + //would probably be better keep an id for each message element
88 + //(i.e. message key) and then update it if necessary.
89 + //also, it may have moved (say, if you received a missing message)
90 + content.innerHTML = ''
91 + //decrypt
92 + thread = thread.map(function (msg) {
93 + return 'string' === typeof msg.value.content ? message_unbox(msg) : msg
94 + })
95 +
96 + if(err) return content.appendChild(h('pre', err.stack))
97 + sort(thread).map(message_render).filter(Boolean).forEach(function (el) {
98 + content.appendChild(el)
99 + })
100 +
101 + var branches = sort.heads(thread)
102 + meta.branch = branches.length > 1 ? branches : branches[0]
103 + meta.root = thread[0].value.content.root || thread[0].key
104 + meta.channel = thread[0].value.content.channel
105 +
106 + var recps = thread[0].value.content.recps
107 + var private = thread[0].value.private
108 + if(private) {
109 + if(recps)
110 + meta.recps = recps
111 + else
112 + meta.recps = [thread[0].value.author, self_id]
113 + }
114 + })
115 + }
116 +
117 + loadThread()
118 + return div
119 + }
120 +}
121 +
122 +
modules_basic/timestamp.jsView
@@ -1,0 +1,21 @@
1 +var h = require('hyperscript')
2 +var human = require('human-time')
3 +
4 +function updateTimestampEl(el) {
5 + el.firstChild.nodeValue = human(new Date(el.timestamp))
6 + return el
7 +}
8 +
9 +setInterval(function () {
10 + var els = [].slice.call(document.querySelectorAll('.timestamp'))
11 + els.forEach(updateTimestampEl)
12 +}, 60e3)
13 +
14 +exports.message_meta = function (msg) {
15 + return updateTimestampEl(h('a.enter.timestamp', {
16 + href: '#'+msg.key,
17 + timestamp: msg.value.timestamp,
18 + title: new Date(msg.value.timestamp)
19 + }, ''))
20 +}
21 +
modules_core/_screen_view.jsView
@@ -1,0 +1,10 @@
1 +
2 +//this is just an UGLY HACK, because depject does not
3 +//support recursion...
4 +
5 +//used by tabs and split views
6 +
7 +var sv = require('../plugs').first(exports.screen_view = [])
8 +exports._screen_view = function (value) {
9 + return sv(value)
10 +}
modules_core/app.jsView
@@ -1,0 +1,68 @@
1 +var plugs = require('../plugs')
2 +var h = require('hyperscript')
3 +
4 +var screen_view = plugs.first(exports.screen_view = [])
5 +
6 +
7 +exports.app = function () {
8 + document.head.appendChild(h('style', require('../style.css.json')))
9 +
10 + window.addEventListener('error', window.onError = function (e) {
11 + document.body.appendChild(h('div.error',
12 + h('h1', e.message),
13 + h('big', h('code', e.filename + ':' + e.lineno)),
14 + h('pre', e.error ? (e.error.stack || e.error.toString()) : e.toString())))
15 + })
16 +
17 + function hash() {
18 + return window.location.hash.substring(1)
19 + }
20 +
21 + var view = screen_view(hash() || 'tabs')
22 +
23 + var screen = h('div.screen.column', view)
24 +
25 + window.onhashchange = function (ev) {
26 + var _view = view
27 + view = screen_view(hash() || 'tabs')
28 +
29 + if(_view) screen.replaceChild(view, _view)
30 + else document.body.appendChild(view)
31 + }
32 +
33 + document.body.appendChild(screen)
34 +
35 + return screen
36 +
37 +}
38 +
39 +
40 +
41 +
42 +
43 +
44 +
45 +
46 +
47 +
48 +
49 +
50 +
51 +
52 +
53 +
54 +
55 +
56 +
57 +
58 +
59 +
60 +
61 +
62 +
63 +
64 +
65 +
66 +
67 +
68 +
modules_core/blob-url.jsView
@@ -1,0 +1,9 @@
1 +var config = require('../config')
2 +
3 +exports.blob_url = function (link) {
4 + if('string' == typeof link.link)
5 + link = link.link
6 + return config().blobsUrl + '/'+link
7 +}
8 +
9 +
modules_core/crypto.jsView
@@ -1,0 +1,48 @@
1 +var ref = require('ssb-ref')
2 +var keys = require('../keys')
3 +var ssbKeys = require('ssb-keys')
4 +
5 +function unbox_value(msg) {
6 + var plaintext = ssbKeys.unbox(msg.content, keys)
7 + if(!plaintext) return null
8 + return {
9 + previous: msg.previous,
10 + author: msg.author,
11 + sequence: msg.sequence,
12 + timestamp: msg.timestamp,
13 + hash: msg.hash,
14 + content: plaintext,
15 + private: true
16 + }
17 +}
18 +
19 +
20 +var sbot_publish = require('../plugs').first(exports.sbot_publish = [])
21 +
22 +exports.message_unbox = function (msg) {
23 + if(msg.value) {
24 + var value = unbox_value(msg.value)
25 + if(value)
26 + return {
27 + key: msg.key, value: value, timestamp: msg.timestamp
28 + }
29 + }
30 + else
31 + return unbox_value(msg)
32 +}
33 +
34 +exports.message_box = function (content) {
35 + return ssbKeys.box(content, content.recps.map(function (e) {
36 + return ref.isFeed(e) ? e : e.link
37 + }))
38 +}
39 +
40 +exports.publish = function (content, id) {
41 + if(content.recps)
42 + content = exports.message_box(content)
43 + sbot_publish(content, function (err, msg) {
44 + if(err) throw err
45 + console.log('PUBLISHED', msg)
46 + })
47 +}
48 +
modules_core/file-input.jsView
@@ -1,0 +1,37 @@
1 +var u = require('../util')
2 +var h = require('hyperscript')
3 +var pull = require('pull-stream')
4 +var mime = require('simple-mime')('application/octect-stream')
5 +var split = require('split-buffer')
6 +
7 +var plugs = require('../plugs')
8 +
9 +var add = plugs.first(exports.sbot_blobs_add = [])
10 +
11 +exports.file_input = function FileInput(onAdded) {
12 +
13 + return h('input', { type: 'file',
14 + onchange: function (ev) {
15 + var file = ev.target.files[0]
16 + if (!file) return
17 + var reader = new FileReader()
18 + reader.onload = function () {
19 + pull(
20 + pull.values(split(new Buffer(reader.result), 64*1024)),
21 + add(function (err, blob) {
22 + if(err) return console.error(err)
23 + onAdded({
24 + link: blob,
25 + name: file.name,
26 + size: reader.result.length || reader.result.byteLength,
27 + type: mime(file.name)
28 + })
29 +
30 + })
31 + )
32 + }
33 + reader.readAsArrayBuffer(file)
34 + }
35 + })
36 +}
37 +
modules_core/index.jsView
@@ -1,0 +1,11 @@
1 +module.exports = {
2 + "_screen_view.js": require('./_screen_view.js'),
3 + "app.js": require('./app.js'),
4 + "blob-url.js": require('./blob-url.js'),
5 + "crypto.js": require('./crypto.js'),
6 + "file-input.js": require('./file-input.js'),
7 + "menu.js": require('./menu.js'),
8 + "message-confirm.js": require('./message-confirm.js'),
9 + "tabs.js": require('./tabs.js'),
10 + "sbot.js": require('./sbot.js')
11 +}
modules_core/menu.jsView
@@ -1,0 +1,31 @@
1 +var plugs = require('../plugs')
2 +var h = require('hyperscript')
3 +
4 +var menu_items = plugs.map(exports.menu_items = [])
5 +
6 +var status = h('div.status.error') //start off disconnected
7 + var list = h('div.menu.column', {style: 'display: none;'})
8 +
9 +var menu = h('div.column', status, list , {
10 + onmouseover: function (e) {
11 + list.style.display = 'flex'
12 + }, onmouseout: function () {
13 + list.style.display = 'none'
14 + }
15 +})
16 +
17 +exports.connection_status = function (err) {
18 + if(err) status.classList.add('error')
19 + else status.classList.remove('error')
20 +}
21 +
22 +exports.menu = function () {
23 + menu_items().forEach(function (el) {
24 + list.appendChild(el)
25 + })
26 +
27 + return menu
28 +}
29 +
30 +
31 +
modules_core/message-confirm.jsView
@@ -1,0 +1,61 @@
1 +var lightbox = require('hyperlightbox')
2 +var h = require('hyperscript')
3 +var u = require('../util')
4 +var self_id = require('../keys').id
5 +//publish or add
6 +
7 +var plugs = require('../plugs')
8 +
9 +var publish = plugs.first(exports.sbot_publish = [])
10 +var message_content = plugs.first(exports.message_content = [])
11 +var avatar = plugs.first(exports.avatar = [])
12 +var message_meta = plugs.map(exports.message_meta = [])
13 +
14 +exports.message_confirm = function (content, cb) {
15 +
16 + cb = cb || function () {}
17 +
18 + var lb = lightbox()
19 + document.body.appendChild(lb)
20 +
21 + var msg = {
22 + key: "DRAFT",
23 + value: {
24 + author: self_id,
25 + previous: null,
26 + sequence: null,
27 + timestamp: Date.now(),
28 + content: content
29 + }
30 + }
31 +
32 + var okay = h('button', 'okay', {onclick: function () {
33 + lb.remove()
34 + publish(content, cb)
35 + }})
36 +
37 + var cancel = h('button', 'Cancel', {onclick: function () {
38 + lb.remove()
39 + cb(null)
40 + }})
41 +
42 + okay.addEventListener('keydown', function (ev) {
43 + if(ev.keyCode === 27) cancel.click() //escape
44 + })
45 +
46 + lb.show(h('div.column.message-confirm',
47 + h('div.message',
48 + h('div.title.row',
49 + h('div.avatar', avatar(msg.value.author, 'thumbnail')),
50 + h('div.message_meta.row', message_meta(msg))
51 + ),
52 + h('div.message_content', message_content(msg)
53 + || h('pre', JSON.stringify(msg, null, 2)))
54 + ),
55 + h('div.row.message-confirm__controls', okay, cancel)
56 + ))
57 +
58 + okay.focus()
59 +
60 +}
61 +
modules_core/sbot.jsView
@@ -1,0 +1,157 @@
1 +var pull = require('pull-stream')
2 +var ssbKeys = require('ssb-keys')
3 +var ref = require('ssb-ref')
4 +var Reconnect = require('pull-reconnect')
5 +var path = require('path')
6 +var config = require('ssb-config/inject')(process.env.ssb_appname)
7 +config.keys = ssbKeys.loadOrCreateSync(path.join(config.path, 'secret'))
8 +
9 +function Hash (onHash) {
10 + var buffers = []
11 + return pull.through(function (data) {
12 + buffers.push('string' === typeof data
13 + ? new Buffer(data, 'utf8')
14 + : data
15 + )
16 + }, function (err) {
17 + if(err && !onHash) throw err
18 + var b = buffers.length > 1 ? Buffer.concat(buffers) : buffers[0]
19 + var h = '&'+ssbKeys.hash(b)
20 + onHash && onHash(err, h)
21 + })
22 +}
23 +//uncomment this to use from browser...
24 +//also depends on having ssb-ws installed.
25 +//var createClient = require('ssb-lite')
26 +var createClient = require('ssb-client')
27 +
28 +var createConfig = require('ssb-config/inject')
29 +
30 +var createFeed = require('ssb-feed')
31 +var keys = require('../keys')
32 +var ssbKeys = require('ssb-keys')
33 +
34 +
35 +var cache = CACHE = {}
36 +
37 +var opts = createConfig()
38 +var sbot = null
39 +var connection_status = []
40 +
41 +var rec = Reconnect(function (isConn) {
42 + function notify (value) {
43 + console.log('connection_status', value, connection_status)
44 + isConn(value); connection_status.forEach(function (fn) { fn(value) })
45 + }
46 +
47 + createClient(keys, {
48 + manifest: require('../manifest.json'),
49 + remote: require('../config')().remote
50 + }, function (err, _sbot) {
51 + if(err)
52 + return notify(err)
53 +
54 + sbot = _sbot
55 + sbot.on('closed', function () {
56 + sbot = null
57 + notify(new Error('closed'))
58 + })
59 +
60 + notify()
61 + })
62 +})
63 +
64 +var internal = {
65 + getLatest: rec.async(function (id, cb) {
66 + sbot.getLatest(id, cb)
67 + }),
68 + add: rec.async(function (msg, cb) {
69 + sbot.add(msg, cb)
70 + })
71 +}
72 +
73 +var feed = createFeed(internal, keys, {remote: true})
74 +
75 +module.exports = {
76 + connection_status: connection_status,
77 + sbot_blobs_add: rec.sink(function (cb) {
78 + return pull(
79 + Hash(function (err, id) {
80 + if(err) return cb(err)
81 + //completely UGLY hack to tell when the blob has been sucessfully written...
82 + var start = Date.now(), n = 5
83 + ;(function next () {
84 + setTimeout(function () {
85 + sbot.blobs.has(id, function (err, has) {
86 + if(has) return cb(null, id)
87 + if(n--) next()
88 + else cb(new Error('write failed'))
89 + })
90 + }, Date.now() - start)
91 + })()
92 + }),
93 + sbot.blobs.add()
94 + )
95 + }),
96 + sbot_links: rec.source(function (query) {
97 + return sbot.links(query)
98 + }),
99 + sbot_links2: rec.source(function (query) {
100 + return sbot.links2.read(query)
101 + }),
102 + sbot_query: rec.source(function (query) {
103 + return sbot.query.read(query)
104 + }),
105 + sbot_log: rec.source(function (opts) {
106 + return pull(
107 + sbot.createLogStream(opts),
108 + pull.through(function (e) {
109 + CACHE[e.key] = CACHE[e.key] || e.value
110 + })
111 + )
112 + }),
113 + sbot_user_feed: rec.source(function (opts) {
114 + return sbot.createUserStream(opts)
115 + }),
116 + sbot_get: rec.async(function (key, cb) {
117 + if(CACHE[key]) cb(null, CACHE[key])
118 + else sbot.get(key, function (err, value) {
119 + if(err) return cb(err)
120 + cb(null, CACHE[key] = value)
121 + })
122 + }),
123 + sbot_gossip_peers: rec.async(function (cb) {
124 + sbot.gossip.peers(cb)
125 + }),
126 + //liteclient won't have permissions for this
127 + sbot_gossip_connect: rec.async(function (opts, cb) {
128 + sbot.gossip.connect(opts, cb)
129 + }),
130 + sbot_progress: rec.source(function () {
131 + return sbot.replicate.changes()
132 + }),
133 + sbot_publish: rec.async(function (content, cb) {
134 + if(content.recps)
135 + content = ssbKeys.box(content, content.recps.map(function (e) {
136 + return ref.isFeed(e) ? e : e.link
137 + }))
138 + else if(content.mentions)
139 + content.mentions.forEach(function (mention) {
140 + if(ref.isBlob(mention.link)) {
141 + sbot.blobs.push(mention.link, function (err) {
142 + if(err) console.error(err)
143 + })
144 + }
145 + })
146 +
147 + feed.add(content, function (err, msg) {
148 + if(err) console.error(err)
149 + else if(!cb) console.log(msg)
150 + cb && cb(err, msg)
151 + })
152 + }),
153 + sbot_whoami: rec.async(function (cb) {
154 + sbot.whoami(cb)
155 + })
156 +}
157 +
modules_core/tabs.jsView
@@ -1,0 +1,215 @@
1 +var Tabs = require('hypertabs')
2 +var h = require('hyperscript')
3 +var pull = require('pull-stream')
4 +var u = require('../util')
5 +var keyscroll = require('../keyscroll')
6 +var open = require('open-external')
7 +
8 +function ancestor (el) {
9 + if(!el) return
10 + if(el.tagName !== 'A') return ancestor(el.parentElement)
11 + return el
12 +}
13 +
14 +var plugs = require('../plugs')
15 +var screen_view = plugs.first(exports._screen_view = [])
16 +var search_box = plugs.first(exports.search_box = [])
17 +var menu = plugs.first(exports.menu = [])
18 +
19 +exports.message_render = []
20 +
21 +exports.screen_view = function (path) {
22 + if(path !== 'tabs')
23 + return
24 +
25 + function setSelected (indexes) {
26 + var ids = indexes.map(function (index) {
27 + return tabs.get(index).id
28 + })
29 + if(ids.length > 1)
30 + search.value = 'split('+ids.join(',')+')'
31 + else
32 + search.value = ids[0]
33 + }
34 +
35 + var search
36 + var tabs = Tabs(setSelected)
37 +
38 + search = search_box(function (path, change) {
39 +
40 + if(tabs.has(path)) {
41 + tabs.select(path)
42 + return true
43 + }
44 + var el = screen_view(path)
45 +
46 + if(el) {
47 + if(!el.title) el.title = path
48 + el.scroll = keyscroll(el.querySelector('.scroller__content'))
49 + tabs.add(el, change)
50 +// localStorage.openTabs = JSON.stringify(tabs.tabs)
51 + return change
52 + }
53 + })
54 +
55 + //reposition hypertabs menu to inside a container...
56 + tabs.insertBefore(h('div.header.row',
57 + h('div.header__tabs.row', tabs.firstChild), //tabs
58 + h('div.header__search.row.end', h('div', search), menu())
59 + ), tabs.firstChild)
60 +// tabs.insertBefore(search, tabs.firstChild.nextSibling)
61 +
62 + var saved = []
63 +// try { saved = JSON.parse(localStorage.openTabs) }
64 +// catch (_) { }
65 +
66 + if(!saved || saved.length < 3)
67 + saved = ['/public', '/private', '/notifications']
68 +
69 + saved.forEach(function (path) {
70 + var el = screen_view(path)
71 + if(!el) return
72 + el.id = el.id || path
73 + if (!el) return
74 + el.scroll = keyscroll(el.querySelector('.scroller__content'))
75 + if(el) tabs.add(el, false, false)
76 + })
77 +
78 + tabs.select(0)
79 +
80 + //handle link clicks
81 + window.onclick = function (ev) {
82 + var link = ancestor(ev.target)
83 + if(!link) return
84 + var path = link.hash.substring(1)
85 +
86 + ev.preventDefault()
87 + ev.stopPropagation()
88 +
89 + //open external links.
90 + //this ought to be made into something more runcible
91 + if(open.isExternal(link.href)) return open(link.href)
92 +
93 + if(tabs.has(path))
94 + return tabs.select(path, !ev.ctrlKey, !!ev.shiftKey)
95 +
96 + var el = screen_view(path)
97 + if(el) {
98 + el.id = el.id || path
99 + el.scroll = keyscroll(el.querySelector('.scroller__content'))
100 + tabs.add(el, !ev.ctrlKey, !!ev.shiftKey)
101 +// localStorage.openTabs = JSON.stringify(tabs.tabs)
102 + }
103 +
104 + return false
105 + }
106 +
107 + window.addEventListener('keydown', function (ev) {
108 + if (ev.target.nodeName === 'INPUT' || ev.target.nodeName === 'TEXTAREA')
109 + return
110 + switch(ev.keyCode) {
111 +
112 + // scroll through tabs
113 + case 72: // h
114 + return tabs.selectRelative(-1)
115 + case 76: // l
116 + return tabs.selectRelative(1)
117 +
118 + // scroll through messages
119 + case 74: // j
120 + return tabs.get(tabs.selected[0]).scroll(1)
121 + case 75: // k
122 + return tabs.get(tabs.selected[0]).scroll(-1)
123 +
124 + // close a tab
125 + case 88: // x
126 + if (tabs.selected) {
127 + var sel = tabs.selected
128 + var i = sel.reduce(function (a, b) { return Math.min(a, b) })
129 + tabs.remove(sel)
130 + tabs.select(Math.max(i-1, 0))
131 + }
132 + return
133 +
134 + // activate the search field
135 + case 191: // /
136 + if (ev.shiftKey)
137 + search.activate('?', ev)
138 + else
139 + search.activate('/', ev)
140 + return
141 +
142 + // navigate to a feed
143 + case 50: // 2
144 + if (ev.shiftKey)
145 + search.activate('@', ev)
146 + return
147 +
148 + // navigate to a channel
149 + case 51: // 3
150 + if (ev.shiftKey)
151 + search.activate('#', ev)
152 + return
153 + }
154 + })
155 +
156 + // errors tab
157 + var errorsContent = h('div.column.scroller__content')
158 + var errors = h('div.column.scroller',
159 + {style: {'overflow':'auto'}},
160 + h('div.scroller__wrapper',
161 + errorsContent
162 + )
163 + )
164 +
165 + // remove loader error handler
166 + if (window.onError) {
167 + window.removeEventListener('error', window.onError)
168 + delete window.onError
169 + }
170 +
171 + var errors = h('div.errors', {id: 'errors'})
172 +
173 + // put errors in a tab
174 + window.addEventListener('error', function (ev) {
175 + var err = ev.error || ev
176 + if(!tabs.has('errors'))
177 + tabs.add(errors, false)
178 + var el = h('div.message',
179 + h('strong', err.message),
180 + h('pre', err.stack))
181 + if (errorsContent.firstChild)
182 + errorsContent.insertBefore(el, errorsContent.firstChild)
183 + else
184 + errorsContent.appendChild(el)
185 + })
186 +
187 + if (process.versions.electron) {
188 + window.addEventListener('contextmenu', function (ev) {
189 + ev.preventDefault()
190 + var remote = require('electron').remote
191 + var Menu = remote.Menu
192 + var MenuItem = remote.MenuItem
193 + var menu = new Menu()
194 + menu.append(new MenuItem({
195 + label: 'Inspect Element',
196 + click: function () {
197 + remote.getCurrentWindow().inspectElement(ev.x, ev.y)
198 + }
199 + }))
200 + menu.popup(remote.getCurrentWindow())
201 + })
202 + }
203 +
204 + return tabs
205 +}
206 +
207 +
208 +
209 +
210 +
211 +
212 +
213 +
214 +
215 +
sbot-api.jsView
@@ -1,164 +1,0 @@
1-var pull = require('pull-stream')
2-var ssbKeys = require('ssb-keys')
3-var ref = require('ssb-ref')
4-var Reconnect = require('pull-reconnect')
5-
6-function Hash (onHash) {
7- var buffers = []
8- return pull.through(function (data) {
9- buffers.push('string' === typeof data
10- ? new Buffer(data, 'utf8')
11- : data
12- )
13- }, function (err) {
14- if(err && !onHash) throw err
15- var b = buffers.length > 1 ? Buffer.concat(buffers) : buffers[0]
16- var h = '&'+ssbKeys.hash(b)
17- onHash && onHash(err, h)
18- })
19-}
20-//uncomment this to use from browser...
21-//also depends on having ssb-ws installed.
22-//var createClient = require('ssb-lite')
23-var createClient = require('ssb-client')
24-
25-var createConfig = require('ssb-config/inject')
26-
27-var createFeed = require('ssb-feed')
28-var keys = require('./keys')
29-var ssbKeys = require('ssb-keys')
30-
31-
32-var cache = CACHE = {}
33-
34-module.exports = function () {
35- var opts = createConfig()
36- var sbot = null
37- var connection_status = []
38-
39-
40- var rec = Reconnect(function (isConn) {
41-// var remote
42-// if('undefined' !== typeof localStorage)
43-// remote = localStorage.remote
44-
45- function notify (value) {
46- console.log('connection_status', value, connection_status)
47- isConn(value); connection_status.forEach(function (fn) { fn(value) })
48- }
49-
50- createClient(keys, {
51- manifest: require('./manifest.json'),
52- remote: require('./config')().remote
53- }, function (err, _sbot) {
54- if(err)
55- return notify(err)
56-
57- sbot = _sbot
58- sbot.on('closed', function () {
59- sbot = null
60- notify(new Error('closed'))
61- })
62-
63- notify()
64- })
65- })
66-
67- var internal = {
68- getLatest: rec.async(function (id, cb) {
69- sbot.getLatest(id, cb)
70- }),
71- add: rec.async(function (msg, cb) {
72- sbot.add(msg, cb)
73- })
74- }
75-
76- var feed = createFeed(internal, keys, {remote: true})
77-
78- return {
79- connection_status: connection_status,
80- sbot_blobs_add: rec.sink(function (cb) {
81- return pull(
82- Hash(function (err, id) {
83- if(err) return cb(err)
84- //completely UGLY hack to tell when the blob has been sucessfully written...
85- var start = Date.now(), n = 5
86- ;(function next () {
87- setTimeout(function () {
88- sbot.blobs.has(id, function (err, has) {
89- if(has) return cb(null, id)
90- if(n--) next()
91- else cb(new Error('write failed'))
92- })
93- }, Date.now() - start)
94- })()
95- }),
96- sbot.blobs.add()
97- )
98- }),
99- sbot_links: rec.source(function (query) {
100- return sbot.links(query)
101- }),
102- sbot_links2: rec.source(function (query) {
103- return sbot.links2.read(query)
104- }),
105- sbot_query: rec.source(function (query) {
106- return sbot.query.read(query)
107- }),
108- sbot_log: rec.source(function (opts) {
109- return pull(
110- sbot.createLogStream(opts),
111- pull.through(function (e) {
112- CACHE[e.key] = CACHE[e.key] || e.value
113- })
114- )
115- }),
116- sbot_user_feed: rec.source(function (opts) {
117- return sbot.createUserStream(opts)
118- }),
119- sbot_get: rec.async(function (key, cb) {
120- if(CACHE[key]) cb(null, CACHE[key])
121- else sbot.get(key, function (err, value) {
122- if(err) return cb(err)
123- cb(null, CACHE[key] = value)
124- })
125- }),
126- sbot_gossip_peers: rec.async(function (cb) {
127- sbot.gossip.peers(cb)
128- }),
129- //liteclient won't have permissions for this
130- sbot_gossip_connect: rec.async(function (opts, cb) {
131- sbot.gossip.connect(opts, cb)
132- }),
133- sbot_publish: rec.async(function (content, cb) {
134- if(content.recps)
135- content = ssbKeys.box(content, content.recps.map(function (e) {
136- return ref.isFeed(e) ? e : e.link
137- }))
138- else if(content.mentions)
139- content.mentions.forEach(function (mention) {
140- if(ref.isBlob(mention.link)) {
141- sbot.blobs.push(mention.link, function (err) {
142- if(err) console.error(err)
143- })
144- }
145- })
146-
147- feed.add(content, function (err, msg) {
148- if(err) console.error(err)
149- else if(!cb) console.log(msg)
150- cb && cb(err, msg)
151- })
152- }),
153- sbot_whoami: rec.async(function (cb) {
154- sbot.whoami(cb)
155- }),
156- sbot_progress: rec.source(function () {
157- return sbot.replicate.changes()
158- })
159- }
160-}
161-
162-
163-
164-
modules_embedded/index.jsView
@@ -1,0 +1,11 @@
1 +module.exports = {
2 + "_screen_view.js": require('../modules_core/_screen_view.js'),
3 + "app.js": require('../modules_core/app.js'),
4 + "blob-url.js": require('../modules_core/blob-url.js'),
5 + "crypto.js": require('../modules_core/crypto.js'),
6 + "file-input.js": require('../modules_core/file-input.js'),
7 + "menu.js": require('../modules_core/menu.js'),
8 + "message-confirm.js": require('../modules_core/message-confirm.js'),
9 + "tabs.js": require('../modules_core/tabs.js'),
10 + "sbot.js": require('./sbot.js')
11 +}
modules_embedded/sbot.jsView
@@ -1,0 +1,139 @@
1 +var pull = require('pull-stream')
2 +var ssbKeys = require('ssb-keys')
3 +var ref = require('ssb-ref')
4 +var Reconnect = require('pull-reconnect')
5 +var path = require('path')
6 +var config = require('ssb-config/inject')(process.env.ssb_appname)
7 +config.keys = ssbKeys.loadOrCreateSync(path.join(config.path, 'secret'))
8 +
9 +function Hash (onHash) {
10 + var buffers = []
11 + return pull.through(function (data) {
12 + buffers.push('string' === typeof data
13 + ? new Buffer(data, 'utf8')
14 + : data
15 + )
16 + }, function (err) {
17 + if(err && !onHash) throw err
18 + var b = buffers.length > 1 ? Buffer.concat(buffers) : buffers[0]
19 + var h = '&'+ssbKeys.hash(b)
20 + onHash && onHash(err, h)
21 + })
22 +}
23 +//uncomment this to use from browser...
24 +//also depends on having ssb-ws installed.
25 +//var createClient = require('ssb-lite')
26 +var createClient = require('ssb-client')
27 +
28 +var createConfig = require('ssb-config/inject')
29 +
30 +var createFeed = require('ssb-feed')
31 +var keys = require('../keys')
32 +var ssbKeys = require('ssb-keys')
33 +
34 +
35 +var cache = CACHE = {}
36 +
37 +var opts = createConfig()
38 +var sbot = null
39 +var connection_status = []
40 +
41 + var createSbot = require('scuttlebot')
42 + .use(require('scuttlebot/plugins/gossip'))
43 + .use(require('scuttlebot/plugins/friends'))
44 + .use(require('scuttlebot/plugins/replicate'))
45 + .use(require('ssb-blobs'))
46 + .use(require('scuttlebot/plugins/invite'))
47 + .use(require('scuttlebot/plugins/block'))
48 + .use(require('scuttlebot/plugins/local'))
49 + .use(require('ssb-ws'))
50 + .use(require('ssb-query'))
51 + .use(require('ssb-links'))
52 + var sbot = createSbot(config)
53 +
54 +
55 +var rec = Reconnect(function (isConn) {
56 +
57 + function notify (value) {
58 + console.log('connection_status', value, connection_status)
59 + isConn(value); connection_status.forEach(function (fn) { fn(value) })
60 + }
61 +
62 + return setTimeout(notify)
63 +})
64 +
65 +var internal = {
66 + getLatest: sbot.getLatest,
67 + add: sbot.add,
68 +}
69 +
70 +var feed = createFeed(internal, keys, {remote: true})
71 +
72 +module.exports = {
73 + connection_status: connection_status,
74 + sbot_blobs_add: function (cb) {
75 + return pull(
76 + Hash(function (err, id) {
77 + if(err) return cb(err)
78 + //completely UGLY hack to tell when the blob has been sucessfully written...
79 + var start = Date.now(), n = 5
80 + ;(function next () {
81 + setTimeout(function () {
82 + sbot.blobs.has(id, function (err, has) {
83 + if(has) return cb(null, id)
84 + if(n--) next()
85 + else cb(new Error('write failed'))
86 + })
87 + }, Date.now() - start)
88 + })()
89 + }),
90 + sbot.blobs.add()
91 + )
92 + },
93 + sbot_links: sbot.links,
94 + sbot_links2: sbot.links2.read,
95 + sbot_query: sbot.query.read,
96 + sbot_log: function (opts) {
97 + return pull(
98 + sbot.createLogStream(opts),
99 + pull.through(function (e) {
100 + CACHE[e.key] = CACHE[e.key] || e.value
101 + })
102 + )
103 + },
104 + sbot_user_feed: sbot.createUserStream,
105 + sbot_get: function (key, cb) {
106 + if(CACHE[key]) cb(null, CACHE[key])
107 + else sbot.get(key, function (err, value) {
108 + if(err) return cb(err)
109 + cb(null, CACHE[key] = value)
110 + })
111 + },
112 + sbot_gossip_peers: sbot.gossip.peers,
113 + sbot_gossip_connect: sbot.gossip.connect,
114 + sbot_progress: sbot.gossip.change,
115 + sbot_publish: function (content, cb) {
116 + if(content.recps)
117 + content = ssbKeys.box(content, content.recps.map(function (e) {
118 + return ref.isFeed(e) ? e : e.link
119 + }))
120 + else if(content.mentions)
121 + content.mentions.forEach(function (mention) {
122 + if(ref.isBlob(mention.link)) {
123 + sbot.blobs.push(mention.link, function (err) {
124 + if(err) console.error(err)
125 + })
126 + }
127 + })
128 +
129 + feed.add(content, function (err, msg) {
130 + if(err) console.error(err)
131 + else if(!cb) console.log(msg)
132 + cb && cb(err, msg)
133 + })
134 + },
135 + sbot_whoami: sbot.whoami,
136 +}
137 +
138 +
139 +
modules_extra/audio-mp3.jsView
@@ -1,0 +1,51 @@
1 +var markdown = require('ssb-markdown');
2 +var h = require('hyperscript');
3 +var u = require('../util');
4 +var ref = require('ssb-ref');
5 +
6 +//render a message
7 +
8 +var plugs = require('../plugs');
9 +var message_link = plugs.first(exports.message_link = []);
10 +var message_confirm = plugs.first(exports.message_confirm = []);
11 +var sbot_links = plugs.first(exports.sbot_links = []);
12 +var blob_url = plugs.first(exports.blob_url = []);
13 +
14 +exports.message_content = function(msg, sbot) {
15 + if (msg.value.content.type !== 'audio-mp3')
16 + return;
17 +
18 + var v = msg.value.content;
19 + return h('div',
20 + h('h2', "(" + v.Track + ") " + v.Title),
21 + // h('img', { "src" : blob_url(v.cover) }),
22 + h('audio', {
23 + "controls" : true,
24 + "src" : blob_url(v.link)
25 + }))
26 + // h('dl',
27 + // Object.keys(v).map(function(k) {
28 + // return [
29 + // h("dt", k),
30 + // h("dd", v[k]),
31 + // ]
32 + // })))
33 +
34 + // "Album": "the fall of",
35 + // "Crc32": "038becab",
36 + // "Creator": "bleupulp",
37 + // "Format": "VBR MP3",
38 + // "Height": "0",
39 + // "Length": "375.23",
40 + // "Md5": "2c517c8e813da5f940c8c7e77d4b7f3f",
41 + // "Mtime": "1399498698",
42 + // "Name": "2_bleupulp_-_clouds.mp3",
43 + // "Sha1": "9f6a96a3d5571ed1ec2a7da38ffebdcd5f181482",
44 + // "Size": "15009000",
45 +
46 + // "Title": "clouds",
47 + // "Track": "2",
48 + // "Width": "0",
49 +
50 +}
51 +
modules_extra/channel.jsView
@@ -1,0 +1,52 @@
1 +var h = require('hyperscript')
2 +var u = require('../util')
3 +var pull = require('pull-stream')
4 +var Scroller = require('pull-scroll')
5 +
6 +var plugs = require('../plugs')
7 +var message_render = plugs.first(exports.message_render = [])
8 +var message_compose = plugs.first(exports.message_compose = [])
9 +var sbot_log = plugs.first(exports.sbot_log = [])
10 +var sbot_query = plugs.first(exports.sbot_query = [])
11 +
12 +exports.message_meta = function (msg) {
13 + var chan = msg.value.content.channel
14 + if (chan)
15 + return h('a', {href: '##'+chan}, '#'+chan)
16 +}
17 +
18 +exports.screen_view = function (path) {
19 + if(path[0] === '#') {
20 + var channel = path.substr(1)
21 +
22 + var content = h('div.column.scroller__content')
23 + var div = h('div.column.scroller',
24 + {style: {'overflow':'auto'}},
25 + h('div.scroller__wrapper',
26 + message_compose({type: 'post', channel: channel}),
27 + content
28 + )
29 + )
30 +
31 + function matchesChannel(msg) {
32 + if (msg.sync) console.error('SYNC', msg)
33 + var c = msg && msg.value && msg.value.content
34 + return c && c.channel === channel
35 + }
36 +
37 + pull(
38 + sbot_log({old: false}),
39 + pull.filter(matchesChannel),
40 + Scroller(div, content, message_render, true, false)
41 + )
42 +
43 + pull(
44 + sbot_query({reverse: true, query: [
45 + {$filter: {value: {content: {channel: channel}}}}
46 + ]}),
47 + Scroller(div, content, message_render, false, false)
48 + )
49 +
50 + return div
51 + }
52 +}
modules_extra/git.jsView
@@ -1,0 +1,478 @@
1 +var h = require('hyperscript')
2 +var pull = require('pull-stream')
3 +var paramap = require('pull-paramap')
4 +var cat = require('pull-cat')
5 +var human = require('human-time')
6 +var combobox = require('hypercombo')
7 +
8 +var plugs = require('../plugs')
9 +var message_link = plugs.first(exports.message_link = [])
10 +var message_confirm = plugs.first(exports.message_confirm = [])
11 +var message_compose = plugs.first(exports.message_compose = [])
12 +var sbot_links = plugs.first(exports.sbot_links = [])
13 +var sbot_links2 = plugs.first(exports.sbot_links2 = [])
14 +var sbot_get = plugs.first(exports.sbot_get = [])
15 +var getAvatar = require('ssb-avatar')
16 +var avatar_name = plugs.first(exports.avatar_name = [])
17 +var markdown = plugs.first(exports.markdown = [])
18 +var KVGraph = require('kvgraph')
19 +var mergeRepo = require('ssb-git/merge')
20 +
21 +var self_id = require('../keys').id
22 +
23 +function shortRefName(ref) {
24 + return ref.replace(/^refs\/(heads|tags)\//, '')
25 +}
26 +
27 +function getRefs(msg) {
28 + var updates = new KVGraph('key')
29 + var _cb, _refs
30 + pull(
31 + sbot_links({
32 + reverse: true,
33 + // source: msg.value.author,
34 + dest: msg.key,
35 + rel: 'repo',
36 + values: true
37 + }),
38 + pull.drain(function (link) {
39 + if (link.value.content.type === 'git-update') {
40 + updates.add(link)
41 + }
42 + }, function (err) {
43 + var refs = updates.reduceRight(mergeRepo).refs
44 + var cb = _cb
45 + if (cb) delete _cb, cb(err, refs)
46 + else _refs = refs
47 + })
48 + )
49 +
50 + return pull(
51 + function fn(end, cb) {
52 + if (end || fn.ended) cb(true)
53 + fn.ended = true
54 + if (_refs) cb(_refs)
55 + else _cb = cb
56 + },
57 + pull.flatten()
58 + )
59 +}
60 +
61 +function getForks(id) {
62 + return pull(
63 + sbot_links({
64 + reverse: true,
65 + dest: id,
66 + rel: 'upstream'
67 + }),
68 + pull.map(function (link) {
69 + return {
70 + id: link.key,
71 + author: link.source
72 + }
73 + })
74 + )
75 +}
76 +
77 +function repoText(id) {
78 + var text = document.createTextNode(id.substr(0, 10) + '…')
79 + getAvatar({links: sbot_links, get: sbot_get}, self_id, id,
80 + function (err, avatar) {
81 + if(err) return console.error(err)
82 + text.nodeValue = avatar.name
83 + })
84 + return text
85 +}
86 +
87 +function repoLink(id) {
88 + return h('a', {href: '#'+id}, repoText(id))
89 +}
90 +
91 +function repoName(id) {
92 + return h('ins', repoText(id))
93 +}
94 +
95 +function getIssueState(id, cb) {
96 + pull(
97 + sbot_links({dest: id, rel: 'issues', values: true, reverse: true}),
98 + pull.map(function (msg) {
99 + return msg.value.content.issues
100 + }),
101 + pull.flatten(),
102 + pull.filter(function (issue) {
103 + return issue.link === id
104 + }),
105 + pull.map(function (issue) {
106 + return issue.merged ? 'merged' : issue.open ? 'open' : 'closed'
107 + }),
108 + pull.take(1),
109 + pull.collect(function (err, updates) {
110 + cb(err, updates && updates[0] || 'open')
111 + })
112 + )
113 +}
114 +
115 +//todo:
116 +function messageTimestampLink(msg) {
117 + var date = new Date(msg.value.timestamp)
118 + return h('a.timestamp', {
119 + timestamp: msg.value.timestamp,
120 + title: date,
121 + href: '#'+msg.key
122 + }, human(date))
123 +}
124 +
125 +// a thead+tbody where the thead only is added when the first row is added
126 +function tableRows(headerRow) {
127 + var thead = h('thead'), tbody = h('tbody')
128 + var first = true
129 + var t = [thead, tbody]
130 + t.append = function (row) {
131 + if (first) {
132 + first = false
133 + thead.appendChild(headerRow)
134 + }
135 + tbody.appendChild(row)
136 + }
137 + return t
138 +}
139 +
140 +function renderIssueEdit(c) {
141 + var id = c.issue || c.link
142 + return [
143 + c.title ? h('p', 'renamed issue ', message_link(id),
144 + ' to ', h('ins', c.title)) : null,
145 + c.open === false ? h('p', 'closed issue ', message_link(id)) : null,
146 + c.open === true ? h('p', 'reopened issue ', message_link(id)) : null]
147 +}
148 +
149 +exports.message_content = function (msg, sbot) {
150 + var c = msg.value.content
151 +
152 + if(c.type === 'git-repo') {
153 + var branchesT, tagsT, openIssuesT, closedIssuesT, openPRsT, closedPRsT
154 + var forksT
155 + var div = h('div',
156 + h('p', 'git repo ', repoName(msg.key)),
157 + c.upstream ? h('p', 'fork of ', repoLink(c.upstream)) : '',
158 + h('p', h('code', 'ssb://' + msg.key)),
159 + h('div.git-table-wrapper', {style: {'max-height': '12em'}},
160 + h('table',
161 + branchesT = tableRows(h('tr',
162 + h('th', 'branch'),
163 + h('th', 'commit'),
164 + h('th', 'last update'))),
165 + tagsT = tableRows(h('tr',
166 + h('th', 'tag'),
167 + h('th', 'commit'),
168 + h('th', 'last update'))))),
169 + h('div.git-table-wrapper', {style: {'max-height': '16em'}},
170 + h('table',
171 + openIssuesT = tableRows(h('tr',
172 + h('th', 'open issues'))),
173 + closedIssuesT = tableRows(h('tr',
174 + h('th', 'closed issues'))))),
175 + h('div.git-table-wrapper', {style: {'max-height': '16em'}},
176 + h('table',
177 + openPRsT = tableRows(h('tr',
178 + h('th', 'open pull requests'))),
179 + closedPRsT = tableRows(h('tr',
180 + h('th', 'closed pull requests'))))),
181 + h('div.git-table-wrapper',
182 + h('table',
183 + forksT = tableRows(h('tr',
184 + h('th', 'forks'))))),
185 + h('div', h('a', {href: '#', onclick: function (e) {
186 + e.preventDefault()
187 + this.parentNode.replaceChild(issueForm(msg), this)
188 + }}, 'New Issue…')),
189 + h('div', h('a', {href: '#', onclick: function (e) {
190 + e.preventDefault()
191 + this.parentNode.replaceChild(pullRequestForm(msg), this)
192 + }}, 'New Pull Request…')))
193 +
194 + pull(getRefs(msg), pull.drain(function (ref) {
195 + var name = ref.realname || ref.name
196 + var author = ref.link && ref.link.value.author
197 + var parts = /^refs\/(heads|tags)\/(.*)$/.exec(name) || []
198 + var shortName = parts[2]
199 + var t
200 + if(parts[1] === 'heads') t = branchesT
201 + else if(parts[1] === 'tags') t = tagsT
202 + if(t) t.append(h('tr',
203 + h('td', shortName,
204 + ref.conflict ? [
205 + h('br'),
206 + h('a', {href: '#'+author}, avatar_name(author))
207 + ] : ''),
208 + h('td', h('code', ref.hash)),
209 + h('td', messageTimestampLink(ref.link))))
210 + }, function (err) {
211 + if(err) console.error(err)
212 + }))
213 +
214 + // list issues and pull requests
215 + pull(
216 + sbot_links({
217 + reverse: true,
218 + dest: msg.key,
219 + rel: 'project',
220 + values: true
221 + }),
222 + paramap(function (link, cb) {
223 + getIssueState(link.key, function (err, state) {
224 + if(err) return cb(err)
225 + link.state = state
226 + cb(null, link)
227 + })
228 + }),
229 + pull.drain(function (link) {
230 + var c = link.value.content
231 + var title = c.title || (c.text ? c.text.length > 70
232 + ? c.text.substr(0, 70) + '…'
233 + : c.text : link.key)
234 + var author = link.value.author
235 + var t = c.type === 'pull-request'
236 + ? link.state === 'open' ? openPRsT : closedPRsT
237 + : link.state === 'open' ? openIssuesT : closedIssuesT
238 + t.append(h('tr',
239 + h('td',
240 + h('a', {href: '#'+link.key}, title), h('br'),
241 + h('small',
242 + 'opened ', messageTimestampLink(link),
243 + ' by ', h('a', {href: '#'+author}, avatar_name(author))))))
244 + }, function (err) {
245 + if (err) console.error(err)
246 + })
247 + )
248 +
249 + // list forks
250 + pull(
251 + getForks(msg.key),
252 + pull.drain(function (fork) {
253 + forksT.append(h('tr', h('td',
254 + repoLink(fork.id),
255 + ' by ', h('a', {href: '#'+fork.author}, avatar_name(fork.author)))))
256 + }, function (err) {
257 + if (err) console.error(err)
258 + })
259 + )
260 +
261 + return div
262 + }
263 +
264 + if(c.type === 'git-update') {
265 + return [
266 + h('p', 'pushed to ', repoLink(c.repo)),
267 + c.refs ? h('ul', Object.keys(c.refs).map(function (ref) {
268 + var rev = c.refs[ref]
269 + return h('li',
270 + shortRefName(ref) + ': ',
271 + rev ? h('code', rev) : h('em', 'deleted'))
272 + })) : null,
273 + Array.isArray(c.commits) ? [
274 + h('ul',
275 + c.commits.map(function (commit) {
276 + return h('li',
277 + typeof commit.sha1 === 'string' ?
278 + [h('code', commit.sha1.substr(0, 8)), ' '] : null,
279 + commit.title ?
280 + h('q', commit.title) : null)
281 + }),
282 + c.commits_more > 0 ?
283 + h('li', '+ ', c.commits_more, ' more') : null)
284 + ] : null,
285 + Array.isArray(c.issues) ? c.issues.map(function (issue) {
286 + if (issue.merged === true)
287 + return h('p', 'Merged ', message_link(issue.link), ' in ',
288 + h('code', issue.object), ' ', h('q', issue.label))
289 + if (issue.open === false)
290 + return h('p', 'Closed ', message_link(issue.link), ' in ',
291 + h('code', issue.object), ' ', h('q', issue.label))
292 + }) : null
293 + ]
294 + }
295 +
296 + if(c.type === 'issue-edit'
297 + || (c.type === 'post' && c.text === '')) {
298 + return h('div',
299 + c.issue ? renderIssueEdit(c) : null,
300 + c.issues ? c.issues.map(renderIssueEdit) : null)
301 + }
302 +
303 + if(c.type === 'issue') {
304 + return h('div',
305 + h('p', 'opened issue on ', repoLink(c.project)),
306 + c.title ? h('h4', c.title) : '',
307 + markdown(c)
308 + )
309 + }
310 +
311 + if(c.type === 'pull-request') {
312 + return h('div',
313 + h('p', 'opened pull-request ',
314 + 'to ', repoLink(c.repo), ':', c.branch, ' ',
315 + 'from ', repoLink(c.head_repo), ':', c.head_branch),
316 + c.title ? h('h4', c.title) : '',
317 + markdown(c)
318 + )
319 + }
320 +}
321 +
322 +exports.message_meta = function (msg, sbot) {
323 + var type = msg.value.content.type
324 + if (type === 'issue' || type === 'pull-request') {
325 + var el = h('em', '...')
326 + // TODO: update if issue is changed
327 + getIssueState(msg.key, function (err, state) {
328 + if (err) return console.error(err)
329 + el.textContent = state
330 + })
331 + return el
332 + }
333 +}
334 +
335 +function findMessageContent(el) {
336 + for(; el; el = el.parentNode) {
337 + if(el.classList.contains('message')) {
338 + return el.querySelector('.message_content')
339 + }
340 + }
341 +}
342 +
343 +function issueForm(msg, contentEl) {
344 + var form = h('form',
345 + h('strong', 'New Issue:'),
346 + message_compose(
347 + {type: 'issue', project: msg.key},
348 + function (value) { return value },
349 + function (err, issue) {
350 + if(err) return alert(err)
351 + if(!issue) return
352 + var title = issue.value.content.text
353 + if(title.length > 70) title = title.substr(0, 70) + '…'
354 + form.appendChild(h('div',
355 + h('a', {href: '#'+issue.key}, title)
356 + ))
357 + }
358 + )
359 + )
360 + return form
361 +}
362 +
363 +function branchMenu(msg, full) {
364 + return combobox({
365 + style: {'max-width': '14ex'},
366 + placeholder: 'branch…',
367 + default: 'master',
368 + read: msg && pull(getRefs(msg), pull.map(function (ref) {
369 + var m = /^refs\/heads\/(.*)$/.exec(ref.name)
370 + if(!m) return
371 + var branch = m[1]
372 + var label = branch
373 + if(full) {
374 + var updated = new Date(ref.link.value.timestamp)
375 + label = branch +
376 + ' · ' + human(updated) +
377 + ' · ' + ref.hash.substr(1, 8) +
378 + (ref.title ? ' · "' + ref.title + '"' : '')
379 + }
380 + return h('option', {value: branch}, label)
381 + }))
382 + })
383 +}
384 +
385 +function pullRequestForm(msg) {
386 + var headRepoInput
387 + var headBranchInput = branchMenu()
388 + var branchInput = branchMenu(msg)
389 + var form = h('form',
390 + h('strong', 'New Pull Request:'),
391 + h('div',
392 + 'from ',
393 + headRepoInput = combobox({
394 + style: {'max-width': '26ex'},
395 + onchange: function () {
396 + // list branches for selected repo
397 + var repoId = this.value
398 + if(repoId) sbot_get(repoId, function (err, value) {
399 + if(err) console.error(err)
400 + var msg = value && {key: repoId, value: value}
401 + headBranchInput = headBranchInput.swap(branchMenu(msg, true))
402 + })
403 + else headBranchInput = headBranchInput.swap(branchMenu())
404 + },
405 + read: pull(cat([
406 + pull.once({id: msg.key, author: msg.value.author}),
407 + getForks(msg.key)
408 + ]), pull.map(function (fork) {
409 + return h('option', {value: fork.id},
410 + repoLink(fork.id), ' by ', avatar_name(fork.author))
411 + }))
412 + }),
413 + ':',
414 + headBranchInput,
415 + ' to ',
416 + repoName(msg.key),
417 + ':',
418 + branchInput),
419 + message_compose(
420 + {
421 + type: 'pull-request',
422 + project: msg.key,
423 + repo: msg.key,
424 + },
425 + function (value) {
426 + value.branch = branchInput.value
427 + value.head_repo = headRepoInput.value
428 + value.head_branch = headBranchInput.value
429 + return value
430 + },
431 + function (err, issue) {
432 + if(err) return alert(err)
433 + if(!issue) return
434 + var title = issue.value.content.text
435 + if(title.length > 70) title = title.substr(0, 70) + '…'
436 + form.appendChild(h('div',
437 + h('a', {href: '#'+issue.key}, title)
438 + ))
439 + }
440 + )
441 + )
442 + return form
443 +}
444 +
445 +exports.message_action = function (msg, sbot) {
446 + var c = msg.value.content
447 + if(c.type === 'issue' || c.type === 'pull-request') {
448 + var isOpen
449 + var a = h('a', {href: '#', onclick: function (e) {
450 + e.preventDefault()
451 + message_confirm({
452 + type: 'issue-edit',
453 + root: msg.key,
454 + issues: [{
455 + link: msg.key,
456 + open: !isOpen
457 + }]
458 + }, function (err, msg) {
459 + if(err) return alert(err)
460 + if(!msg) return
461 + isOpen = msg.value.content.open
462 + update()
463 + })
464 + }})
465 + getIssueState(msg.key, function (err, state) {
466 + if (err) return console.error(err)
467 + isOpen = state === 'open'
468 + update()
469 + })
470 + function update() {
471 + a.textContent = c.type === 'pull-request'
472 + ? isOpen ? 'Close Pull Request' : 'Reopen Pull Request'
473 + : isOpen ? 'Close Issue' : 'Reopen Issue'
474 + }
475 + return a
476 + }
477 +}
478 +
modules_extra/index.jsView
@@ -1,0 +1,17 @@
1 +module.exports = {
2 + "audio-mp3.js": require('./audio-mp3.js'),
3 + "channel.js": require('./channel.js'),
4 + "git.js": require('./git.js'),
5 + "notifications.js": require('./notifications.js'),
6 + "meta-image.js": require('./meta-image.js'),
7 + "music-release-cc.js": require('./music-release-cc.js'),
8 + "music-release.js": require('./music-release.js'),
9 + "network.js": require('./network.js'),
10 + "query.js": require('./query.js'),
11 + "raw.js": require('./raw.js'),
12 + "search.js": require('./search'),
13 + "split.js": require('./split.js'),
14 + "versions.js": require('./versions.js')
15 +}
16 +
17 +
modules_extra/meta-image.jsView
@@ -1,0 +1,48 @@
1 +var markdown = require('ssb-markdown');
2 +var h = require('hyperscript');
3 +var u = require('../util');
4 +var ref = require('ssb-ref');
5 +
6 +//render a message
7 +
8 +var plugs = require('../plugs');
9 +var message_link = plugs.first(exports.message_link = []);
10 +var message_confirm = plugs.first(exports.message_confirm = []);
11 +var sbot_links = plugs.first(exports.sbot_links = []);
12 +var blob_url = plugs.first(exports.blob_url = []);
13 +
14 +exports.message_content = function(msg, sbot) {
15 + if (msg.value.content.type !== 'meta-image')
16 + return;
17 +
18 + var v = msg.value.content;
19 + return h('div',
20 + // h('h2', "(" + v.Track + ") " + v.Title),
21 + h('img', { "src" : blob_url(v.link) }))
22 +
23 + // h('dl',
24 + // Object.keys(v).map(function(k) {
25 + // return [
26 + // h("dt", k),
27 + // h("dd", v[k]),
28 + // ]
29 + // })))
30 +
31 + // "Album": "the fall of",
32 + // "Crc32": "038becab",
33 + // "Creator": "bleupulp",
34 + // "Format": "VBR MP3",
35 + // "Height": "0",
36 + // "Length": "375.23",
37 + // "Md5": "2c517c8e813da5f940c8c7e77d4b7f3f",
38 + // "Mtime": "1399498698",
39 + // "Name": "2_bleupulp_-_clouds.mp3",
40 + // "Sha1": "9f6a96a3d5571ed1ec2a7da38ffebdcd5f181482",
41 + // "Size": "15009000",
42 +
43 + // "Title": "clouds",
44 + // "Track": "2",
45 + // "Width": "0",
46 +
47 +}
48 +
modules_extra/music-release-cc.jsView
@@ -1,0 +1,80 @@
1 +var markdown = require('ssb-markdown');
2 +var h = require('hyperscript');
3 +var u = require('../util');
4 +var ref = require('ssb-ref');
5 +
6 +//render a message
7 +
8 +var plugs = require('../plugs');
9 +var message_link = plugs.first(exports.message_link = []);
10 +var message_confirm = plugs.first(exports.message_confirm = []);
11 +var sbot_links = plugs.first(exports.sbot_links = []);
12 +var blob_url = plugs.first(exports.blob_url = []);
13 +
14 +exports.message_content = function(msg, sbot) {
15 + if (msg.value.content.type !== 'music-release-cc')
16 + return;
17 +
18 + var tracks = msg.value.content.tracks;
19 + return h('div',
20 + h('img', { "src" : blob_url(msg.value.content.cover) }),
21 + h('h1', msg.value.content.title),
22 + h('ol',
23 + Object.keys(tracks).map(function(k) {
24 + var t = tracks[k];
25 + return h('li', t.fname,
26 + h("br"),
27 + h('audio', {
28 + "controls" : true,
29 + "src" : blob_url(t.link)
30 + }))
31 + })),
32 + h('p',
33 + "More info:", h('a', { href : msg.value.content.archivedotorg }, "archive.org"),
34 + h("br"),
35 + "License:", h('a', { href : msg.value.content.license }, "Link")))
36 +}
37 +
38 +// copied from like.js
39 +
40 +// inspiration for waveform range selection
41 +
42 +// idea: handout invite codes for upload of tracks to be cached by the pub
43 +
44 +// exports.message_meta = function (msg, sbot) {
45 +
46 +// var yupps = h('a')
47 +
48 +// pull(
49 +// sbot_links({dest: msg.key, rel: 'vote'}),
50 +// pull.collect(function (err, votes) {
51 +// if(votes.length === 1)
52 +// yupps.textContent = ' 1 yup'
53 +// if(votes.length)
54 +// yupps.textContent = ' ' + votes.length + ' yupps'
55 +// })
56 +// )
57 +
58 +// return yupps
59 +// }
60 +
61 +// exports.message_action = function (msg, sbot) {
62 +// if(msg.value.content.type !== 'vote')
63 +// return h('a', {href: '#', onclick: function () {
64 +// var yup = {
65 +// type: 'vote',
66 +// vote: { link: msg.key, value: 1, expression: 'yup' }
67 +// }
68 +// if(msg.value.content.recps) {
69 +// yup.recps = msg.value.content.recps.map(function (e) {
70 +// return e && typeof e !== 'string' ? e.link : e
71 +// })
72 +// yup.private = true
73 +// }
74 +// //TODO: actually publish...
75 +
76 +// message_confirm(yup)
77 +// }}, 'yup')
78 +
79 +// }
80 +
modules_extra/music-release.jsView
@@ -1,0 +1,41 @@
1 +var markdown = require('ssb-markdown');
2 +var h = require('hyperscript');
3 +var u = require('../util');
4 +var ref = require('ssb-ref');
5 +
6 +//render a message
7 +
8 +var plugs = require('../plugs');
9 +var message_link = plugs.first(exports.message_link = []);
10 +var message_confirm = plugs.first(exports.message_confirm = []);
11 +var sbot_links = plugs.first(exports.sbot_links = []);
12 +
13 +exports.message_content = function(msg, sbot) {
14 + if (msg.value.content.type !== 'music-release')
15 + return;
16 +
17 + var v = msg.value.content;
18 + return h('div',
19 + // h('img', { "src" : "http://localhost:7777/" + encodeURIComponent(v.cover) }),
20 + h('h1', v.Title),
21 + h("p", v.Description),
22 + h("dl",
23 +
24 + h("dt", "Creator"),
25 + h("dd", v.Creator),
26 +
27 + h("dt", "Identifier"),
28 + h("dd", v.Identifier),
29 +
30 + h("dt", "Published"),
31 + h("dd", v.Publicdate),
32 +
33 + h("dt", "Runtime"),
34 + h("dd", v.Runtime),
35 +
36 + h("dt", "Source"),
37 + h("dd", v.Source),
38 +
39 + h("dt", "License"),
40 + h("dd", h('a', { href : v.Licenseurl }, "Link"))))
41 +}
modules_extra/network.jsView
@@ -1,0 +1,148 @@
1 +var isVisible = require('is-visible').isVisible
2 +var h = require('hyperscript')
3 +var plugs = require('../plugs')
4 +
5 +var avatar = plugs.first(exports.avatar = [])
6 +var sbot_gossip_peers = plugs.first(exports.sbot_gossip_peers = [])
7 +var sbot_gossip_connect = plugs.first(exports.sbot_gossip_connect = [])
8 +//sbot_gossip_connect
9 +//sbot_gossip_add
10 +
11 +var human = require('human-time')
12 +
13 +function legacyToMultiServer(addr) {
14 + return 'net:'+addr.host + ':'+addr.port + '~shs:'+addr.key.substring(1).replace('.ed25519','')
15 +}
16 +
17 +exports.menu_items = function () {
18 + return h('a', {href: '#/network'}, '/network')
19 +}
20 +
21 +//types of peers
22 +
23 +
24 +//on the same wifi network
25 +function isLocal (e) {
26 + // don't rely on private ip address, because
27 + // cjdns creates fake private ip addresses.
28 + return ip.isPrivate(e.host) && e.type === 'local'
29 +}
30 +
31 +
32 +//pub is running scuttlebot >=8
33 +//have connected successfully.
34 +function isLongterm (e) {
35 + return e.ping && e.ping.rtt && e.ping.rtt.mean > 0
36 +}
37 +
38 +//pub is running scuttlebot < 8
39 +//have connected sucessfully
40 +function isLegacy (peer) {
41 + return /connect/.test(peer.state) || (peer.duration && peer.duration.mean) > 0 && !isLongterm(peer)
42 +}
43 +
44 +//tried to connect, but failed.
45 +function isInactive (e) {
46 + return e.stateChange && (e.duration && e.duration.mean == 0)
47 +}
48 +
49 +//havn't tried to connect peer yet.
50 +function isUnattempted (e) {
51 + return !e.stateChange
52 +}
53 +
54 +function getType (e) {
55 + return (
56 + isLongterm(e) ? 'modern'
57 + : isLegacy(e) ? 'legacy'
58 + : isInactive(e) ? 'inactive'
59 + : isUnattempted(e) ? 'unattempted'
60 + : 'other' //should never happen
61 + )
62 +}
63 +
64 +var states = {
65 + connected: 3,
66 + connecting: 2
67 +}
68 +
69 +var types = {
70 + modern: 4,
71 + legacy: 3,
72 + inactive: 2,
73 + unattempted: 1,
74 + other: 0
75 +}
76 +
77 +function round(n) {
78 + return Math.round(n*100)/100
79 +}
80 +
81 +function duration (s) {
82 + if(!s) return s
83 + if (Math.abs(s) > 30000)
84 + return round(s/60000)+'m'
85 + else if (Math.abs(s) > 500)
86 + return round(s/1000)+'s'
87 + else
88 + return round(s)+'ms'
89 +}
90 +
91 +exports.screen_view = function (path) {
92 +
93 + if(path !== '/network') return
94 +
95 + var ol = h('ul.network')
96 +
97 + ;(function poll () {
98 +
99 + //if this tab isn't open, don't update.
100 + //todo: make a better way to do this...
101 + if(!isVisible(ol))
102 + return setTimeout(poll, 1000)
103 +
104 + sbot_gossip_peers(function (err, list) {
105 + ol.innerHTML = ''
106 + list.sort(function (a, b) {
107 + return (
108 + (states[b.state] || 0) - (states[a.state] || 0)
109 + || types[getType(b)] - types[getType(a)]
110 + || b.stateChange - a.stateChange
111 + )
112 + }).forEach(function (peer) {
113 + ol.appendChild(h('div',
114 + avatar(peer.key, 'thumbnail'),
115 + h('div',
116 + peer.state || 'not connected',
117 + ' ',
118 + getType(peer),
119 + ' ',
120 + //TODO: show nicer details, with labels. etc.
121 + (peer.ping && peer.ping.rtt) ? duration(peer.ping.rtt.mean) : '',
122 + ' ',
123 + (peer.ping && peer.ping.skew) ? duration(peer.ping.skew.mean) : '',
124 + h('label',
125 + {title: new Date(peer.stateChange).toString()},
126 + peer.stateChange && ('(' + human(new Date(peer.stateChange))) + ')')
127 + ),
128 + 'source:'+peer.source,
129 + h('pre', legacyToMultiServer(peer)),
130 + h('button', 'connect', {onclick: function () {
131 + sbot_gossip_connect(peer, function (err) {
132 + if(err) console.error(err)
133 + else console.log('connected to', peer)
134 + })
135 + }})
136 + )
137 + )
138 + })
139 +
140 + setTimeout(poll, 5000)
141 + })
142 +
143 + })()
144 +
145 + return h('div.column.scroll-y', ol)
146 +}
147 +
148 +
modules_extra/notifications.jsView
@@ -1,0 +1,151 @@
1 +var h = require('hyperscript')
2 +var u = require('../util')
3 +var pull = require('pull-stream')
4 +var Scroller = require('pull-scroll')
5 +var paramap = require('pull-paramap')
6 +var plugs = require('../plugs')
7 +var cont = require('cont')
8 +var ref = require('ssb-ref')
9 +
10 +var message_render = plugs.first(exports.message_render = [])
11 +var sbot_log = plugs.first(exports.sbot_log = [])
12 +var sbot_get = plugs.first(exports.sbot_get = [])
13 +var sbot_user_feed = plugs.first(exports.sbot_user_feed = [])
14 +var message_unbox = plugs.first(exports.message_unbox = [])
15 +
16 +function unbox() {
17 + return pull(
18 + pull.map(function (msg) {
19 + return msg.value && 'string' === typeof msg.value.content ?
20 + message_unbox(msg) : msg
21 + }),
22 + pull.filter(Boolean)
23 + )
24 +}
25 +
26 +function notifications(ourIds) {
27 +
28 + function linksToUs(link) {
29 + return link && link.link in ourIds
30 + }
31 +
32 + function isOurMsg(id, cb) {
33 + if (!id) return cb(null, false)
34 + if (typeof id === 'object' && typeof id.link === 'string') id = id.link
35 + if (!ref.isMsg(id)) return cb(null, false)
36 + sbot_get(id, function (err, msg) {
37 + if (err && err.name == 'NotFoundError') cb(null, false)
38 + else if (err) cb(err)
39 + else if (msg.content.type === 'issue' || msg.content.type === 'pull-request')
40 + isOurMsg(msg.content.repo || msg.content.project, cb)
41 + else cb(err, msg.author in ourIds)
42 + })
43 + }
44 +
45 + function isAnyOurMessage(msg, ids, cb) {
46 + cont.para(ids.map(function (id) {
47 + return function (cb) { isOurMsg(id, cb) }
48 + }))
49 + (function (err, results) {
50 + if (err) cb(err)
51 + else if (results.some(Boolean)) cb(null, msg)
52 + else cb()
53 + })
54 + }
55 +
56 + return paramap(function (msg, cb) {
57 + var c = msg.value && msg.value.content
58 + if (!c || typeof c !== 'object') return cb()
59 + if (msg.value.author in ourIds) return cb()
60 +
61 + if (c.mentions && Array.isArray(c.mentions) && c.mentions.some(linksToUs))
62 + return cb(null, msg)
63 +
64 + if (msg.private)
65 + return cb(null, msg)
66 +
67 + switch (c.type) {
68 + case 'post':
69 + if (c.branch || c.root)
70 + return isAnyOurMessage(msg, [].concat(c.branch, c.root), cb)
71 + else return cb()
72 +
73 + case 'contact':
74 + return cb(null, c.contact in ourIds ? msg : null)
75 +
76 + case 'vote':
77 + if (c.vote && c.vote.link)
78 + return isOurMsg(c.vote.link, function (err, isOurs) {
79 + cb(err, isOurs ? msg : null)
80 + })
81 + else return cb()
82 +
83 + case 'issue':
84 + case 'pull-request':
85 + return isOurMsg(c.project || c.repo, function (err, isOurs) {
86 + cb(err, isOurs ? msg : null)
87 + })
88 +
89 + case 'issue-edit':
90 + return isAnyOurMessage(msg, [c.issue].concat(c.issues), cb)
91 +
92 + default:
93 + cb()
94 + }
95 + }, 4)
96 +}
97 +
98 +function getFirstMessage(feedId, cb) {
99 + sbot_user_feed({id: feedId, gte: 0, limit: 1})(null, cb)
100 +}
101 +
102 +exports.screen_view = function (path) {
103 + if(path === '/notifications') {
104 + var ids = {}
105 + var oldest
106 +
107 + var id = require('../keys').id
108 + ids[id] = true
109 + getFirstMessage(id, function (err, msg) {
110 + if (err) return console.error(err)
111 + if (!oldest || msg.value.timestamp < oldest) {
112 + oldest = msg.value.timestamp
113 + }
114 + })
115 +
116 + var content = h('div.column.scroller__content')
117 + var div = h('div.column.scroller',
118 + {style: {'overflow':'auto'}},
119 + h('div.scroller__wrapper',
120 + content
121 + )
122 + )
123 +
124 + pull(
125 + u.next(sbot_log, {old: false, limit: 100}),
126 + unbox(),
127 + notifications(ids),
128 + pull.filter(),
129 + Scroller(div, content, message_render, true, false)
130 + )
131 +
132 + pull(
133 + u.next(sbot_log, {reverse: true, limit: 100, live: false}),
134 + unbox(),
135 + notifications(ids),
136 + pull.filter(),
137 + pull.take(function (msg) {
138 + // abort stream after we pass the oldest messages of our feeds
139 + return !oldest || msg.value.timestamp > oldest
140 + }),
141 + Scroller(div, content, message_render, false, false)
142 + )
143 +
144 + return div
145 + }
146 +}
147 +
148 +
149 +
150 +
151 +
modules_extra/query.jsView
@@ -1,0 +1,56 @@
1 +var h = require('hyperscript')
2 +var pull = require('pull-stream')
3 +var HJSON = require('hjson')
4 +
5 +var sbot_query = require('../plugs').first(exports.sbot_query = [])
6 +
7 +exports.menu_items = function () {
8 + return h('a', {href:'#/query'}, '/query')
9 +}
10 +
11 +exports.screen_view = function (path) {
12 + if(path != '/query') return
13 + var output, status, editor, stream, query
14 +
15 + function parse () {
16 + try {
17 + query = HJSON.parse(editor.value)
18 + } catch (err) {
19 + return status.textContent = err.message
20 + }
21 + status.textContent = 'okay'
22 + }
23 +
24 + return h('div.column.scroll',
25 + editor = h('textarea', {style: 'min-height:100px;', oninput: parse, onkeydown: function (e) {
26 + if(!(e.keyCode === 13 && e.ctrlKey)) return
27 +
28 + status.textContent = 'running...'
29 + parse()
30 + output.innerHTML = ''
31 + if(stream) stream.abort()
32 +
33 + console.log(query)
34 +
35 + stream = pull(
36 + sbot_query({query: query, limit: 100}),
37 + pull.drain(function (data) {
38 + output.appendChild(h('pre.query__data',
39 + JSON.stringify(data, null, 2)
40 + ))
41 + }, function (err) {
42 + if(err) status.textContent = err.stack
43 + })
44 + )
45 + }}),
46 + status = h('div.query__status'),
47 + output = h('div.column.query__output', {style: 'overflow-y: scroll;'})
48 + )
49 +}
50 +
51 +
52 +
53 +
54 +
55 +
56 +
modules_extra/raw.jsView
@@ -1,0 +1,52 @@
1 +var h = require('hyperscript')
2 +var u = require('../util')
3 +var pull = require('pull-stream')
4 +var Scroller = require('pull-scroll')
5 +
6 +var plugs = require('../plugs')
7 +var message_render = plugs.first(exports.message_render = [])
8 +var message_compose = plugs.first(exports.message_compose = [])
9 +
10 +// from ssb-ref
11 +var refRegex = /((?:@|%|&)[A-Za-z0-9\/+]{43}=\.[\w\d]+)/g
12 +
13 +exports.linkify = function (text) {
14 + var arr = text.split(refRegex)
15 + for (var i = 1; i < arr.length; i += 2) {
16 + arr[i] = h('a', {href: '#' + arr[i]}, arr[i])
17 + }
18 + return arr
19 +}
20 +
21 +exports.message_meta = function (msg) {
22 + var tmp = h('div')
23 + var el
24 + var pre
25 + return h('input', {
26 + type: 'checkbox',
27 + title: 'View Data',
28 + onclick: function () {
29 + var msgEl = this.parentNode.parentNode.parentNode
30 + var msgContentEl = msgEl.querySelector('.message_content')
31 + if (this.checked) {
32 + // move away the content
33 + while (el = msgContentEl.firstChild)
34 + tmp.appendChild(el)
35 + // show the raw stuff
36 + if (!pre) pre = h('pre', exports.linkify(JSON.stringify({
37 + key: msg.key,
38 + value: msg.value
39 + }, 0, 2)))
40 + msgContentEl.appendChild(pre)
41 + } else {
42 + // hide the raw stuff
43 + msgContentEl.removeChild(pre)
44 + // put back the content
45 + while (el = tmp.firstChild)
46 + msgContentEl.appendChild(el)
47 + }
48 + }
49 + })
50 +}
51 +
52 +
modules_extra/search.jsView
@@ -1,0 +1,105 @@
1 +var h = require('hyperscript')
2 +var u = require('../util')
3 +var pull = require('pull-stream')
4 +var Scroller = require('pull-scroll')
5 +var TextNodeSearcher = require('text-node-searcher')
6 +
7 +var plugs = require('../plugs')
8 +var message_render = plugs.first(exports.message_render = [])
9 +var sbot_log = plugs.first(exports.sbot_log = [])
10 +var whitespace = /\s+/
11 +
12 +function andSearch(terms, inputs) {
13 + for(var i = 0; i < terms.length; i++) {
14 + var match = false
15 + for(var j = 0; j < inputs.length; j++) {
16 + if(terms[i].test(inputs[j])) match = true
17 + }
18 + //if a term was not matched by anything, filter this one
19 + if(!match) return false
20 + }
21 + return true
22 +}
23 +
24 +function searchFilter(terms) {
25 + return function (msg) {
26 + var c = msg && msg.value && msg.value.content
27 + return c && (
28 + msg.key == terms[0] ||
29 + andSearch(terms.map(function (term) {
30 + return new RegExp('\\b'+term+'\\b', 'i')
31 + }), [c.text, c.name, c.title])
32 + )
33 + }
34 +}
35 +
36 +function createOrRegExp(ary) {
37 + return new RegExp(ary.map(function (e) {
38 + return '\\b'+e+'\\b'
39 + }).join('|'), 'i')
40 +}
41 +
42 +function highlight(el, query) {
43 + var searcher = new TextNodeSearcher({container: el})
44 + searcher.query = query
45 + searcher.highlight()
46 + return el
47 +}
48 +
49 +exports.screen_view = function (path) {
50 + if(path[0] === '?') {
51 + var query = path.substr(1).trim().split(whitespace)
52 + var _matches = searchFilter(query)
53 +
54 + var total = 0, matches = 0
55 +
56 + var header = h('div.search_header', '')
57 + var content = h('div.column.scroller__content')
58 + var div = h('div.column.scroller',
59 + {style: {'overflow':'auto'}},
60 + h('div.scroller__wrapper',
61 + header,
62 + content
63 + )
64 + )
65 +
66 + function matchesQuery (data) {
67 + total++
68 + var m = _matches(data)
69 + if(m) matches++
70 + header.textContent = 'searched:'+total+', found:'+matches
71 + return m
72 + }
73 +
74 +
75 +
76 + function renderMsg(msg) {
77 + var el = message_render(msg)
78 + highlight(el, createOrRegExp(query))
79 + return el
80 + }
81 +
82 + pull(
83 + sbot_log({old: false}),
84 + pull.filter(matchesQuery),
85 + Scroller(div, content, renderMsg, true, false)
86 + )
87 +
88 + pull(
89 + u.next(sbot_log, {reverse: true, limit: 500, live: false}),
90 + pull.filter(matchesQuery),
91 + Scroller(div, content, renderMsg, false, false)
92 + )
93 +
94 + return div
95 + }
96 +}
97 +
98 +
99 +
100 +
101 +
102 +
103 +
104 +
105 +
modules_extra/split.jsView
@@ -1,0 +1,17 @@
1 +var h = require('hyperscript')
2 +
3 +var screen_view =
4 + require('../plugs').first(exports._screen_view = [])
5 +
6 +exports.screen_view = function (path) {
7 + var m = /^split\s*\((.*)\)$/.exec(path)
8 + if(!m)
9 + return
10 +
11 + return h('div.row',
12 + m[1].split(',').map(function (e) {
13 + return screen_view(e.trim())
14 + }).filter(Boolean)
15 + )
16 +}
17 +
modules_extra/versions.jsView
@@ -1,0 +1,36 @@
1 +var h = require('hyperscript')
2 +
3 +exports.menu_items = function () {
4 + return h('a', {href: '#/versions'}, '/versions')
5 +}
6 +
7 +exports.screen_view = function (path) {
8 + if(path !== '/versions') return
9 +
10 + if('undefined' === typeof WebBoot)
11 + return h('h1', 'must run with web-boot enabled enviroment')
12 +
13 + var content = h('div.column')
14 +
15 + WebBoot.versions(function (err, log) {
16 + log.forEach(function (e, i) {
17 + content.appendChild(
18 + h('div.row',
19 + h('a', {
20 + href: '#/run:'+e.value,
21 + onclick: function () {
22 + WebBoot.run(e.value, function () {
23 + console.log('rebooting to:', e.value)
24 + })
25 + }
26 + }, ' ', e.value, ' ', new Date(e.ts)),
27 + !i && h('label', '(current)')
28 + )
29 + )
30 + })
31 +
32 + })
33 +
34 + return content
35 +}
36 +
ui.jsView
@@ -1,24 +1,0 @@
1-var h = require('hyperscript')
2-var pull = require('pull-stream')
3-var u = require('./util')
4-var Scroller = require('pull-scroll')
5-
6-exports.createStream = function createStream (stream, render) {
7- var div = h('div.column', {style: {'overflow-y': 'auto'}})
8-
9- pull(
10- stream,
11- Scroller(div, div, render, false, false)
12- )
13-
14- return div
15-}
16-
17-exports.createRenderers = function (renderers, sbot) {
18- return function (data) {
19- return u.first(renderers, function (fn) {
20- return fn(data, sbot)
21- })
22- }
23-}
24-
scripts/build.jsView
@@ -1,0 +1,18 @@
1 +var fs = require('fs')
2 +var path = require('path')
3 +
4 +console.log(
5 + 'module.exports = {\n'
6 + +
7 + fs.readdirSync(path.join(__dirname, process.argv[2]))
8 +// .filter(function (file) {
9 +// return file !== '_index.js' && /\.js$/.test(file)
10 +// })
11 + .map(function (file) {
12 + return ' '+JSON.stringify(file) + ": require('./"+file+"')"
13 + }).join(',\n')
14 + +
15 + '\n}'
16 +)
17 +
18 +
scripts/create-index.jsView
@@ -1,0 +1,8 @@
1 +var fs = require('fs')
2 +var path = require('path')
3 +
4 +fs.writeFileSync(
5 + path.join(__dirname, '..', 'style.css.json'),
6 + JSON.stringify(fs.readFileSync(path.join(__dirname, '..', 'style.css'), 'utf8'))
7 +)
8 +
scripts/dir.jsView
@@ -1,0 +1,18 @@
1 +var fs = require('fs')
2 +var path = require('path')
3 +
4 +console.log(
5 + 'module.exports = {\n'
6 + +
7 + fs.readdirSync(path.join(process.cwd(), process.argv[2]))
8 + .filter(function (file) {
9 + return file !== 'index.js' && /\.js$/.test(file)
10 + })
11 + .map(function (file) {
12 + return ' '+JSON.stringify(file) + ": require('./"+file+"')"
13 + }).join(',\n')
14 + +
15 + '\n}'
16 +)
17 +
18 +
scripts/style.jsView
@@ -1,0 +1,8 @@
1 +var fs = require('fs')
2 +var path = require('path')
3 +
4 +fs.writeFileSync(
5 + path.join(__dirname, '..', 'style.css.json'),
6 + JSON.stringify(fs.readFileSync(path.join(__dirname, '..', 'style.css'), 'utf8'))
7 +)
8 +
yarn.lockView
@@ -1,0 +1,3912 @@
1 +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 +# yarn lockfile v1
3 +abbrev@1:
4 + version "1.0.9"
5 + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135"
6 +
7 +abstract-leveldown@~0.12.1:
8 + version "0.12.4"
9 + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz#29e18e632e60e4e221d5810247852a63d7b2e410"
10 + dependencies:
11 + xtend "~3.0.0"
12 +
13 +abstract-leveldown@~2.4.0:
14 + version "2.4.1"
15 + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.4.1.tgz#b3bfedb884eb693a12775f0c55e9f0a420ccee64"
16 + dependencies:
17 + xtend "~4.0.0"
18 +
19 +acorn@^1.0.3:
20 + version "1.2.2"
21 + resolved "https://registry.yarnpkg.com/acorn/-/acorn-1.2.2.tgz#c8ce27de0acc76d896d2b1fad3df588d9e82f014"
22 +
23 +acorn@^2.7.0:
24 + version "2.7.0"
25 + resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7"
26 +
27 +after@~0.8.1:
28 + version "0.8.2"
29 + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
30 +
31 +ansi-escapes@^1.0.0:
32 + version "1.4.0"
33 + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
34 +
35 +ansi-regex@^2.0.0:
36 + version "2.0.0"
37 + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.0.0.tgz#c5061b6e0ef8a81775e50f5d66151bf6bf371107"
38 +
39 +ansi-styles@^2.2.1:
40 + version "2.2.1"
41 + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
42 +
43 +ansi-styles@~1.0.0:
44 + version "1.0.0"
45 + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178"
46 +
47 +ansi@^0.3.0, ansi@~0.3.1:
48 + version "0.3.1"
49 + resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21"
50 +
51 +anymatch@^1.3.0:
52 + version "1.3.0"
53 + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507"
54 + dependencies:
55 + arrify "^1.0.0"
56 + micromatch "^2.1.5"
57 +
58 +aproba@^1.0.3:
59 + version "1.0.4"
60 + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.0.4.tgz#2713680775e7614c8ba186c065d4e2e52d1072c0"
61 +
62 +are-we-there-yet@~1.1.2:
63 + version "1.1.2"
64 + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3"
65 + dependencies:
66 + delegates "^1.0.0"
67 + readable-stream "^2.0.0 || ^1.1.13"
68 +
69 +arr-diff@^2.0.0:
70 + version "2.0.0"
71 + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
72 + dependencies:
73 + arr-flatten "^1.0.1"
74 +
75 +arr-flatten@^1.0.1:
76 + version "1.0.1"
77 + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b"
78 +
79 +array-filter@~0.0.0:
80 + version "0.0.1"
81 + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec"
82 +
83 +array-index@^1.0.0:
84 + version "1.0.0"
85 + resolved "https://registry.yarnpkg.com/array-index/-/array-index-1.0.0.tgz#ec56a749ee103e4e08c790b9c353df16055b97f9"
86 + dependencies:
87 + debug "^2.2.0"
88 + es6-symbol "^3.0.2"
89 +
90 +array-map@~0.0.0:
91 + version "0.0.0"
92 + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
93 +
94 +array-reduce@~0.0.0:
95 + version "0.0.0"
96 + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
97 +
98 +array-union@^1.0.1:
99 + version "1.0.2"
100 + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
101 + dependencies:
102 + array-uniq "^1.0.1"
103 +
104 +array-uniq@^1.0.1:
105 + version "1.0.3"
106 + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
107 +
108 +array-unique@^0.2.1:
109 + version "0.2.1"
110 + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
111 +
112 +arraybuffer-base64@^1.0.0:
113 + version "1.0.0"
114 + resolved "https://registry.yarnpkg.com/arraybuffer-base64/-/arraybuffer-base64-1.0.0.tgz#fd0217ba2ba8d48633663fa43a8093768029da30"
115 +
116 +arrify@^1.0.0:
117 + version "1.0.1"
118 + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
119 +
120 +asn1.js@^4.0.0:
121 + version "4.8.1"
122 + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.8.1.tgz#3949b7f5fd1e8bedc13be3abebf477f93490c810"
123 + dependencies:
124 + bn.js "^4.0.0"
125 + inherits "^2.0.1"
126 + minimalistic-assert "^1.0.0"
127 +
128 +asn1@~0.2.3:
129 + version "0.2.3"
130 + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
131 +
132 +asn1js@^1.2.12:
133 + version "1.2.12"
134 + resolved "https://registry.yarnpkg.com/asn1js/-/asn1js-1.2.12.tgz#87d5ee797596ae2d2a3cb0247220dc42ffc3f211"
135 +
136 +assert-plus@^0.2.0:
137 + version "0.2.0"
138 + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
139 +
140 +assert-plus@^1.0.0:
141 + version "1.0.0"
142 + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
143 +
144 +assert@~1.3.0:
145 + version "1.3.0"
146 + resolved "https://registry.yarnpkg.com/assert/-/assert-1.3.0.tgz#03939a622582a812cc202320a0b9a56c9b815849"
147 + dependencies:
148 + util "0.10.3"
149 +
150 +astw@^2.0.0:
151 + version "2.0.0"
152 + resolved "https://registry.yarnpkg.com/astw/-/astw-2.0.0.tgz#08121ac8288d35611c0ceec663f6cd545604897d"
153 + dependencies:
154 + acorn "^1.0.3"
155 +
156 +async-each@^1.0.0:
157 + version "1.0.1"
158 + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
159 +
160 +async@^1.4.0:
161 + version "1.5.2"
162 + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
163 +
164 +asynckit@^0.4.0:
165 + version "0.4.0"
166 + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
167 +
168 +attach-ware@^1.0.0:
169 + version "1.1.1"
170 + resolved "https://registry.yarnpkg.com/attach-ware/-/attach-ware-1.1.1.tgz#28f51393dd8bb8bdaad972342519bf09621a35a3"
171 + dependencies:
172 + unherit "^1.0.0"
173 +
174 +audio-context@^0.1.0:
175 + version "0.1.0"
176 + resolved "https://registry.yarnpkg.com/audio-context/-/audio-context-0.1.0.tgz#116ee83d566e10e7e845f29d9b1e1bc2ea3520d2"
177 + dependencies:
178 + global "~4.2.1"
179 +
180 +aws-sign2@~0.6.0:
181 + version "0.6.0"
182 + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
183 +
184 +aws4@^1.2.1:
185 + version "1.5.0"
186 + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755"
187 +
188 +bail@^1.0.0:
189 + version "1.0.1"
190 + resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.1.tgz#912579de8b391aadf3c5fdf4cd2a0fc225df3bc2"
191 +
192 +balanced-match@^0.4.1:
193 + version "0.4.2"
194 + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
195 +
196 +base64-js@^1.0.2:
197 + version "1.2.0"
198 + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1"
199 +
200 +base64-js@0.0.2:
201 + version "0.0.2"
202 + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.2.tgz#024f0f72afa25b75f9c0ee73cd4f55ec1bed9784"
203 +
204 +bash-color@~0.0.3:
205 + version "0.0.4"
206 + resolved "https://registry.yarnpkg.com/bash-color/-/bash-color-0.0.4.tgz#e9be8ce33540cada4881768c59bd63865736e913"
207 +
208 +bcrypt-pbkdf@^1.0.0:
209 + version "1.0.0"
210 + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz#3ca76b85241c7170bf7d9703e7b9aa74630040d4"
211 + dependencies:
212 + tweetnacl "^0.14.3"
213 +
214 +binary-extensions@^1.0.0:
215 + version "1.7.0"
216 + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.7.0.tgz#6c1610db163abfb34edfe42fa423343a1e01185d"
217 +
218 +binary-search@^1.2.0:
219 + version "1.3.2"
220 + resolved "https://registry.yarnpkg.com/binary-search/-/binary-search-1.3.2.tgz#88c9b7bd2b7221d352da78ec887f5af2549e4de2"
221 +
222 +binary-xhr@0.0.2:
223 + version "0.0.2"
224 + resolved "https://registry.yarnpkg.com/binary-xhr/-/binary-xhr-0.0.2.tgz#210cb075ad177aa448a6efa288c10a899c3b3987"
225 + dependencies:
226 + inherits "1.0.0"
227 +
228 +bindings@^1.2.1, bindings@~1.2.1:
229 + version "1.2.1"
230 + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11"
231 +
232 +bl@^1.0.0, bl@~1.1.2:
233 + version "1.1.2"
234 + resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398"
235 + dependencies:
236 + readable-stream "~2.0.5"
237 +
238 +bl@~0.8.1:
239 + version "0.8.2"
240 + resolved "https://registry.yarnpkg.com/bl/-/bl-0.8.2.tgz#c9b6bca08d1bc2ea00fc8afb4f1a5fd1e1c66e4e"
241 + dependencies:
242 + readable-stream "~1.0.26"
243 +
244 +bl@~1.0.0:
245 + version "1.0.3"
246 + resolved "https://registry.yarnpkg.com/bl/-/bl-1.0.3.tgz#fc5421a28fd4226036c3b3891a66a25bc64d226e"
247 + dependencies:
248 + readable-stream "~2.0.5"
249 +
250 +blake2s@~1.0.0, blake2s@~1.0.1:
251 + version "1.0.1"
252 + resolved "https://registry.yarnpkg.com/blake2s/-/blake2s-1.0.1.tgz#1598822a320ece6aa401ba982954f82f61b0cd7b"
253 +
254 +block-stream@*:
255 + version "0.0.9"
256 + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
257 + dependencies:
258 + inherits "~2.0.0"
259 +
260 +bluebird@^3.0.6:
261 + version "3.4.6"
262 + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f"
263 +
264 +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
265 + version "4.11.6"
266 + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215"
267 +
268 +boom@2.x.x:
269 + version "2.10.1"
270 + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
271 + dependencies:
272 + hoek "2.x.x"
273 +
274 +bops@~0.1.0:
275 + version "0.1.1"
276 + resolved "https://registry.yarnpkg.com/bops/-/bops-0.1.1.tgz#062e02a8daa801fa10f2e5dbe6740cff801fe17e"
277 + dependencies:
278 + base64-js "0.0.2"
279 + to-utf8 "0.0.1"
280 +
281 +brace-expansion@^1.0.0:
282 + version "1.1.6"
283 + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9"
284 + dependencies:
285 + balanced-match "^0.4.1"
286 + concat-map "0.0.1"
287 +
288 +braces@^1.8.2:
289 + version "1.8.5"
290 + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
291 + dependencies:
292 + expand-range "^1.8.1"
293 + preserve "^0.2.0"
294 + repeat-element "^1.1.2"
295 +
296 +broadcast-stream@~0.0.0:
297 + version "0.0.0"
298 + resolved "https://registry.yarnpkg.com/broadcast-stream/-/broadcast-stream-0.0.0.tgz#dcb3f0612296fe72096e25fe8665aec99865e1bf"
299 +
300 +brorand@^1.0.1:
301 + version "1.0.6"
302 + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.0.6.tgz#4028706b915f91f7b349a2e0bf3c376039d216e5"
303 +
304 +browselectrify@^1.0.1:
305 + version "1.0.1"
306 + resolved "https://registry.yarnpkg.com/browselectrify/-/browselectrify-1.0.1.tgz#6e21e4bbdd6ad9af42bd6de07a1ba87e04df9860"
307 + dependencies:
308 + browserify "^13.0.1"
309 + pull-cat "^1.1.10"
310 + pull-file "^0.5.0"
311 + pull-stream "^3.4.3"
312 + stream-to-pull-stream "^1.7.0"
313 +
314 +browser-pack@^6.0.1:
315 + version "6.0.1"
316 + resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.0.1.tgz#779887c792eaa1f64a46a22c8f1051cdcd96755f"
317 + dependencies:
318 + combine-source-map "~0.7.1"
319 + defined "^1.0.0"
320 + JSONStream "^1.0.3"
321 + through2 "^2.0.0"
322 + umd "^3.0.0"
323 +
324 +browser-resolve@^1.11.0, browser-resolve@^1.7.0:
325 + version "1.11.2"
326 + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce"
327 + dependencies:
328 + resolve "1.1.7"
329 +
330 +browser-split@0.0.0:
331 + version "0.0.0"
332 + resolved "https://registry.yarnpkg.com/browser-split/-/browser-split-0.0.0.tgz#41419caef769755929dd518967d3eec0a6262771"
333 +
334 +browserify-aes@^1.0.0, browserify-aes@^1.0.4:
335 + version "1.0.6"
336 + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.0.6.tgz#5e7725dbdef1fd5930d4ebab48567ce451c48a0a"
337 + dependencies:
338 + buffer-xor "^1.0.2"
339 + cipher-base "^1.0.0"
340 + create-hash "^1.1.0"
341 + evp_bytestokey "^1.0.0"
342 + inherits "^2.0.1"
343 +
344 +browserify-cipher@^1.0.0:
345 + version "1.0.0"
346 + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.0.tgz#9988244874bf5ed4e28da95666dcd66ac8fc363a"
347 + dependencies:
348 + browserify-aes "^1.0.4"
349 + browserify-des "^1.0.0"
350 + evp_bytestokey "^1.0.0"
351 +
352 +browserify-des@^1.0.0:
353 + version "1.0.0"
354 + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.0.tgz#daa277717470922ed2fe18594118a175439721dd"
355 + dependencies:
356 + cipher-base "^1.0.1"
357 + des.js "^1.0.0"
358 + inherits "^2.0.1"
359 +
360 +browserify-rsa@^4.0.0:
361 + version "4.0.1"
362 + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524"
363 + dependencies:
364 + bn.js "^4.1.0"
365 + randombytes "^2.0.1"
366 +
367 +browserify-sign@^4.0.0:
368 + version "4.0.0"
369 + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.0.tgz#10773910c3c206d5420a46aad8694f820b85968f"
370 + dependencies:
371 + bn.js "^4.1.1"
372 + browserify-rsa "^4.0.0"
373 + create-hash "^1.1.0"
374 + create-hmac "^1.1.2"
375 + elliptic "^6.0.0"
376 + inherits "^2.0.1"
377 + parse-asn1 "^5.0.0"
378 +
379 +browserify-zlib@~0.1.2:
380 + version "0.1.4"
381 + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d"
382 + dependencies:
383 + pako "~0.2.0"
384 +
385 +browserify@^13.0.1:
386 + version "13.1.0"
387 + resolved "https://registry.yarnpkg.com/browserify/-/browserify-13.1.0.tgz#d81a018e98dd7ca706ec04253d20f8a03b2af8ae"
388 + dependencies:
389 + assert "~1.3.0"
390 + browser-pack "^6.0.1"
391 + browser-resolve "^1.11.0"
392 + browserify-zlib "~0.1.2"
393 + buffer "^4.1.0"
394 + concat-stream "~1.5.1"
395 + console-browserify "^1.1.0"
396 + constants-browserify "~1.0.0"
397 + crypto-browserify "^3.0.0"
398 + defined "^1.0.0"
399 + deps-sort "^2.0.0"
400 + domain-browser "~1.1.0"
401 + duplexer2 "~0.1.2"
402 + events "~1.1.0"
403 + glob "^5.0.15"
404 + has "^1.0.0"
405 + htmlescape "^1.1.0"
406 + https-browserify "~0.0.0"
407 + inherits "~2.0.1"
408 + insert-module-globals "^7.0.0"
409 + JSONStream "^1.0.3"
410 + labeled-stream-splicer "^2.0.0"
411 + module-deps "^4.0.2"
412 + os-browserify "~0.1.1"
413 + parents "^1.0.1"
414 + path-browserify "~0.0.0"
415 + process "~0.11.0"
416 + punycode "^1.3.2"
417 + querystring-es3 "~0.2.0"
418 + read-only-stream "^2.0.0"
419 + readable-stream "^2.0.2"
420 + resolve "^1.1.4"
421 + shasum "^1.0.0"
422 + shell-quote "^1.4.3"
423 + stream-browserify "^2.0.0"
424 + stream-http "^2.0.0"
425 + string_decoder "~0.10.0"
426 + subarg "^1.0.0"
427 + syntax-error "^1.1.1"
428 + through2 "^2.0.0"
429 + timers-browserify "^1.0.1"
430 + tty-browserify "~0.0.0"
431 + url "~0.11.0"
432 + util "~0.10.1"
433 + vm-browserify "~0.0.1"
434 + xtend "^4.0.0"
435 +
436 +buffer-shims@^1.0.0:
437 + version "1.0.0"
438 + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51"
439 +
440 +buffer-v6-polyfill@^1.0.3:
441 + version "1.0.3"
442 + resolved "https://registry.yarnpkg.com/buffer-v6-polyfill/-/buffer-v6-polyfill-1.0.3.tgz#bc695c6f19d00a63e83338c36cd68f3f5dcba3e8"
443 +
444 +buffer-xor@^1.0.2:
445 + version "1.0.3"
446 + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
447 +
448 +buffer@^4.1.0:
449 + version "4.9.1"
450 + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298"
451 + dependencies:
452 + base64-js "^1.0.2"
453 + ieee754 "^1.1.4"
454 + isarray "^1.0.0"
455 +
456 +builtin-status-codes@^2.0.0:
457 + version "2.0.0"
458 + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-2.0.0.tgz#6f22003baacf003ccd287afe6872151fddc58579"
459 +
460 +bytewise-core@^1.2.2:
461 + version "1.2.3"
462 + resolved "https://registry.yarnpkg.com/bytewise-core/-/bytewise-core-1.2.3.tgz#3fb410c7e91558eb1ab22a82834577aa6bd61d42"
463 + dependencies:
464 + typewise-core "^1.2"
465 +
466 +bytewise@^1.1.0, bytewise@~1.1.0:
467 + version "1.1.0"
468 + resolved "https://registry.yarnpkg.com/bytewise/-/bytewise-1.1.0.tgz#1d13cbff717ae7158094aa881b35d081b387253e"
469 + dependencies:
470 + bytewise-core "^1.2.2"
471 + typewise "^1.0.3"
472 +
473 +bytewise@~0.7.1:
474 + version "0.7.1"
475 + resolved "https://registry.yarnpkg.com/bytewise/-/bytewise-0.7.1.tgz#43a479d763c85256d5467c8fe05a734f4f2eac2e"
476 + dependencies:
477 + bops "~0.1.0"
478 +
479 +camelcase@^2.0.0:
480 + version "2.1.1"
481 + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
482 +
483 +caseless@~0.11.0:
484 + version "0.11.0"
485 + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7"
486 +
487 +ccount@^1.0.0:
488 + version "1.0.1"
489 + resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.1.tgz#665687945168c218ec77ff61a4155ae00227a96c"
490 +
491 +chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1:
492 + version "1.1.3"
493 + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
494 + dependencies:
495 + ansi-styles "^2.2.1"
496 + escape-string-regexp "^1.0.2"
497 + has-ansi "^2.0.0"
498 + strip-ansi "^3.0.0"
499 + supports-color "^2.0.0"
500 +
501 +chalk@~0.4.0:
502 + version "0.4.0"
503 + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f"
504 + dependencies:
505 + ansi-styles "~1.0.0"
506 + has-color "~0.1.0"
507 + strip-ansi "~0.1.0"
508 +
509 +character-entities-html4@^1.0.0:
510 + version "1.0.1"
511 + resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.0.1.tgz#c550d23c052574a61a8925f9d503faff6305c026"
512 +
513 +character-entities-legacy@^1.0.0:
514 + version "1.0.1"
515 + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.0.1.tgz#f659037653f9beeace2e9d44490c72a4d4fe3857"
516 +
517 +character-entities@^1.0.0:
518 + version "1.1.0"
519 + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.1.0.tgz#704c928e2d2a879a3db6a926a6dd68fcd2bec7ac"
520 +
521 +character-reference-invalid@^1.0.0:
522 + version "1.0.1"
523 + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.0.1.tgz#cc413afbedb03554c2321fbff9356ec937505eaf"
524 +
525 +chloride-test@^1.1.0:
526 + version "1.1.1"
527 + resolved "https://registry.yarnpkg.com/chloride-test/-/chloride-test-1.1.1.tgz#9b87a2ccc9ab5982868cddaf9bf373f9b001e4df"
528 + dependencies:
529 + json-buffer "^2.0.11"
530 +
531 +chloride@^2.0.1, chloride@^2.1.1, chloride@^2.2.0, chloride@^2.2.1:
532 + version "2.2.4"
533 + resolved "https://registry.yarnpkg.com/chloride/-/chloride-2.2.4.tgz#620b141c6ea66cc897de560e3ebb801b6677ca0b"
534 + dependencies:
535 + is-electron "^2.0.0"
536 + sodium-browserify "^1.0.3"
537 + sodium-browserify-tweetnacl "^0.2.0"
538 + optionalDependencies:
539 + sodium-prebuilt "1.0.22"
540 +
541 +chokidar@^1.0.5:
542 + version "1.6.0"
543 + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.0.tgz#90c32ad4802901d7713de532dc284e96a63ad058"
544 + dependencies:
545 + anymatch "^1.3.0"
546 + async-each "^1.0.0"
547 + glob-parent "^2.0.0"
548 + inherits "^2.0.1"
549 + is-binary-path "^1.0.0"
550 + is-glob "^2.0.0"
551 + path-is-absolute "^1.0.0"
552 + readdirp "^2.0.0"
553 + optionalDependencies:
554 + fsevents "^1.0.0"
555 +
556 +cipher-base@^1.0.0, cipher-base@^1.0.1:
557 + version "1.0.3"
558 + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.3.tgz#eeabf194419ce900da3018c207d212f2a6df0a07"
559 + dependencies:
560 + inherits "^2.0.1"
561 +
562 +class-list@~0.1.0, class-list@~0.1.1:
563 + version "0.1.1"
564 + resolved "https://registry.yarnpkg.com/class-list/-/class-list-0.1.1.tgz#9b9745192c4179b5da0a0d7633658e3c70d796cb"
565 + dependencies:
566 + indexof "0.0.1"
567 +
568 +cli-cursor@^1.0.2:
569 + version "1.0.2"
570 + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
571 + dependencies:
572 + restore-cursor "^1.0.1"
573 +
574 +co@3.1.0:
575 + version "3.1.0"
576 + resolved "https://registry.yarnpkg.com/co/-/co-3.1.0.tgz#4ea54ea5a08938153185e15210c68d9092bc1b78"
577 +
578 +code-point-at@^1.0.0:
579 + version "1.0.1"
580 + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.0.1.tgz#1104cd34f9b5b45d3eba88f1babc1924e1ce35fb"
581 + dependencies:
582 + number-is-nan "^1.0.0"
583 +
584 +collapse-white-space@^1.0.0:
585 + version "1.0.2"
586 + resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.2.tgz#9c463fb9c6d190d2dcae21a356a01bcae9eeef6d"
587 +
588 +combine-source-map@~0.7.1:
589 + version "0.7.2"
590 + resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.7.2.tgz#0870312856b307a87cc4ac486f3a9a62aeccc09e"
591 + dependencies:
592 + convert-source-map "~1.1.0"
593 + inline-source-map "~0.6.0"
594 + lodash.memoize "~3.0.3"
595 + source-map "~0.5.3"
596 +
597 +combined-stream@^1.0.5, combined-stream@~1.0.5:
598 + version "1.0.5"
599 + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
600 + dependencies:
601 + delayed-stream "~1.0.0"
602 +
603 +commander@^2.0.0, commander@^2.9.0:
604 + version "2.9.0"
605 + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
606 + dependencies:
607 + graceful-readlink ">= 1.0.0"
608 +
609 +concat-map@0.0.1:
610 + version "0.0.1"
611 + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
612 +
613 +concat-stream@^1.0.0, concat-stream@~1.5.0, concat-stream@~1.5.1:
614 + version "1.5.2"
615 + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266"
616 + dependencies:
617 + inherits "~2.0.1"
618 + readable-stream "~2.0.0"
619 + typedarray "~0.0.5"
620 +
621 +console-browserify@^1.1.0:
622 + version "1.1.0"
623 + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10"
624 + dependencies:
625 + date-now "^0.1.4"
626 +
627 +console-control-strings@^1.0.0, console-control-strings@~1.1.0:
628 + version "1.1.0"
629 + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
630 +
631 +constants-browserify@~1.0.0:
632 + version "1.0.0"
633 + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
634 +
635 +cont@^1.0.3, cont@~1.0.0, cont@~1.0.1, cont@~1.0.3:
636 + version "1.0.3"
637 + resolved "https://registry.yarnpkg.com/cont/-/cont-1.0.3.tgz#6874f1e935fca99d048caeaaad9a0aeb020bcce0"
638 + dependencies:
639 + continuable "~1.2.0"
640 + continuable-para "~1.2.0"
641 + continuable-series "~1.2.0"
642 +
643 +continuable-hash@~0.1.4:
644 + version "0.1.4"
645 + resolved "https://registry.yarnpkg.com/continuable-hash/-/continuable-hash-0.1.4.tgz#81c74d41771d8c92783e1e00e5f11b34d6dfc78c"
646 + dependencies:
647 + continuable "~1.1.6"
648 +
649 +continuable-list@~0.1.5:
650 + version "0.1.6"
651 + resolved "https://registry.yarnpkg.com/continuable-list/-/continuable-list-0.1.6.tgz#87cf06ec580716e10dff95fb0b84c5f0e8acac5f"
652 + dependencies:
653 + continuable "~1.1.6"
654 +
655 +continuable-para@~1.2.0:
656 + version "1.2.0"
657 + resolved "https://registry.yarnpkg.com/continuable-para/-/continuable-para-1.2.0.tgz#445510f649459dd0fc35c872015146122731c583"
658 + dependencies:
659 + continuable-hash "~0.1.4"
660 + continuable-list "~0.1.5"
661 +
662 +continuable-series@~1.2.0:
663 + version "1.2.0"
664 + resolved "https://registry.yarnpkg.com/continuable-series/-/continuable-series-1.2.0.tgz#3243397ae93a71d655b3026834a51590b958b9e8"
665 +
666 +continuable@~1.1.6:
667 + version "1.1.8"
668 + resolved "https://registry.yarnpkg.com/continuable/-/continuable-1.1.8.tgz#dc877b474160870ae3bcde87336268ebe50597d5"
669 +
670 +continuable@~1.2.0:
671 + version "1.2.0"
672 + resolved "https://registry.yarnpkg.com/continuable/-/continuable-1.2.0.tgz#08277468d41136200074ccf87294308d169f25b6"
673 +
674 +convert-source-map@~1.1.0:
675 + version "1.1.3"
676 + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860"
677 +
678 +core-util-is@~1.0.0:
679 + version "1.0.2"
680 + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
681 +
682 +create-ecdh@^4.0.0:
683 + version "4.0.0"
684 + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d"
685 + dependencies:
686 + bn.js "^4.1.0"
687 + elliptic "^6.0.0"
688 +
689 +create-hash@^1.1.0, create-hash@^1.1.1:
690 + version "1.1.2"
691 + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.2.tgz#51210062d7bb7479f6c65bb41a92208b1d61abad"
692 + dependencies:
693 + cipher-base "^1.0.1"
694 + inherits "^2.0.1"
695 + ripemd160 "^1.0.0"
696 + sha.js "^2.3.6"
697 +
698 +create-hmac@^1.1.0, create-hmac@^1.1.2:
699 + version "1.1.4"
700 + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.4.tgz#d3fb4ba253eb8b3f56e39ea2fbcb8af747bd3170"
701 + dependencies:
702 + create-hash "^1.1.0"
703 + inherits "^2.0.1"
704 +
705 +cryptiles@2.x.x:
706 + version "2.0.5"
707 + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
708 + dependencies:
709 + boom "2.x.x"
710 +
711 +crypto-browserify@^3.0.0:
712 + version "3.11.0"
713 + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.0.tgz#3652a0906ab9b2a7e0c3ce66a408e957a2485522"
714 + dependencies:
715 + browserify-cipher "^1.0.0"
716 + browserify-sign "^4.0.0"
717 + create-ecdh "^4.0.0"
718 + create-hash "^1.1.0"
719 + create-hmac "^1.1.0"
720 + diffie-hellman "^5.0.0"
721 + inherits "^2.0.1"
722 + pbkdf2 "^3.0.3"
723 + public-encrypt "^4.0.0"
724 + randombytes "^2.0.0"
725 +
726 +d@^0.1.1, d@~0.1.1:
727 + version "0.1.1"
728 + resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309"
729 + dependencies:
730 + es5-ext "~0.10.2"
731 +
732 +dashdash@^1.12.0:
733 + version "1.14.0"
734 + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.0.tgz#29e486c5418bf0f356034a993d51686a33e84141"
735 + dependencies:
736 + assert-plus "^1.0.0"
737 +
738 +dataurl-@^0.1.0:
739 + version "0.1.0"
740 + resolved "https://registry.yarnpkg.com/dataurl-/-/dataurl--0.1.0.tgz#3db6ed6f5d18a3f80e32658deb037a4422d3a9d6"
741 +
742 +date-now@^0.1.4:
743 + version "0.1.4"
744 + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
745 +
746 +debug@^2.0.0, debug@^2.2.0, debug@~2.2.0:
747 + version "2.2.0"
748 + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da"
749 + dependencies:
750 + ms "0.7.1"
751 +
752 +deep-equal@~0.2.1:
753 + version "0.2.2"
754 + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.2.2.tgz#84b745896f34c684e98f2ce0e42abaf43bba017d"
755 +
756 +deep-equal@~1.0.0:
757 + version "1.0.1"
758 + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
759 +
760 +deep-extend@^0.4.0, deep-extend@~0.4.0:
761 + version "0.4.1"
762 + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253"
763 +
764 +deep-extend@~0.2.5:
765 + version "0.2.11"
766 + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.2.11.tgz#7a16ba69729132340506170494bc83f7076fe08f"
767 +
768 +deferred-leveldown@~0.2.0:
769 + version "0.2.0"
770 + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-0.2.0.tgz#2cef1f111e1c57870d8bbb8af2650e587cd2f5b4"
771 + dependencies:
772 + abstract-leveldown "~0.12.1"
773 +
774 +deferred-leveldown@~1.2.1:
775 + version "1.2.1"
776 + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.1.tgz#5d25c3310f5fe909946f6240dc9f90dd109a71ef"
777 + dependencies:
778 + abstract-leveldown "~2.4.0"
779 +
780 +defined@^1.0.0:
781 + version "1.0.0"
782 + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
783 +
784 +delayed-stream@~1.0.0:
785 + version "1.0.0"
786 + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
787 +
788 +delegates@^1.0.0:
789 + version "1.0.0"
790 + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
791 +
792 +depject@^2.0.0:
793 + version "2.0.0"
794 + resolved "https://registry.yarnpkg.com/depject/-/depject-2.0.0.tgz#5ccd4d48b26e024d919472e8311e1c36c5864798"
795 +
796 +deps-sort@^2.0.0:
797 + version "2.0.0"
798 + resolved "https://registry.yarnpkg.com/deps-sort/-/deps-sort-2.0.0.tgz#091724902e84658260eb910748cccd1af6e21fb5"
799 + dependencies:
800 + JSONStream "^1.0.3"
801 + shasum "^1.0.0"
802 + subarg "^1.0.0"
803 + through2 "^2.0.0"
804 +
805 +des.js@^1.0.0:
806 + version "1.0.0"
807 + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc"
808 + dependencies:
809 + inherits "^2.0.1"
810 + minimalistic-assert "^1.0.0"
811 +
812 +detab@^1.0.0:
813 + version "1.0.2"
814 + resolved "https://registry.yarnpkg.com/detab/-/detab-1.0.2.tgz#01bc2a4abe7bc7cc67c3039808edbae47049a0ee"
815 + dependencies:
816 + repeat-string "^1.5.2"
817 +
818 +detective@^4.0.0:
819 + version "4.3.1"
820 + resolved "https://registry.yarnpkg.com/detective/-/detective-4.3.1.tgz#9fb06dd1ee8f0ea4dbcc607cda39d9ce1d4f726f"
821 + dependencies:
822 + acorn "^1.0.3"
823 + defined "^1.0.0"
824 +
825 +diffie-hellman@^5.0.0:
826 + version "5.0.2"
827 + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e"
828 + dependencies:
829 + bn.js "^4.1.0"
830 + miller-rabin "^4.0.0"
831 + randombytes "^2.0.0"
832 +
833 +dom-walk@^0.1.0:
834 + version "0.1.1"
835 + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
836 +
837 +domain-browser@~1.1.0:
838 + version "1.1.7"
839 + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
840 +
841 +duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2:
842 + version "0.1.4"
843 + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
844 + dependencies:
845 + readable-stream "^2.0.2"
846 +
847 +duplexer2@~0.0.2:
848 + version "0.0.2"
849 + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db"
850 + dependencies:
851 + readable-stream "~1.1.9"
852 +
853 +ecc-jsbn@~0.1.1:
854 + version "0.1.1"
855 + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
856 + dependencies:
857 + jsbn "~0.1.0"
858 +
859 +ed2curve@^0.1.4:
860 + version "0.1.4"
861 + resolved "https://registry.yarnpkg.com/ed2curve/-/ed2curve-0.1.4.tgz#94a44248bb87da35db0eff7af0aa576168117f59"
862 + dependencies:
863 + tweetnacl "0.x.x"
864 +
865 +elegant-spinner@^1.0.0:
866 + version "1.0.1"
867 + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
868 +
869 +elliptic@^6.0.0:
870 + version "6.3.2"
871 + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.2.tgz#e4c81e0829cf0a65ab70e998b8232723b5c1bc48"
872 + dependencies:
873 + bn.js "^4.4.0"
874 + brorand "^1.0.1"
875 + hash.js "^1.0.0"
876 + inherits "^2.0.1"
877 +
878 +emoji-named-characters@^1.0.2:
879 + version "1.0.2"
880 + resolved "https://registry.yarnpkg.com/emoji-named-characters/-/emoji-named-characters-1.0.2.tgz#cdeb36d0e66002c4b9d7bf1dfbc3a199fb7d409b"
881 +
882 +end-of-stream@^1.0.0, end-of-stream@^1.1.0:
883 + version "1.1.0"
884 + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.1.0.tgz#e9353258baa9108965efc41cb0ef8ade2f3cfb07"
885 + dependencies:
886 + once "~1.3.0"
887 +
888 +errno@~0.1.1:
889 + version "0.1.4"
890 + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d"
891 + dependencies:
892 + prr "~0.0.0"
893 +
894 +es5-ext@^0.10.7, es5-ext@~0.10.11, es5-ext@~0.10.2:
895 + version "0.10.12"
896 + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047"
897 + dependencies:
898 + es6-iterator "2"
899 + es6-symbol "~3.1"
900 +
901 +es6-iterator@2:
902 + version "2.0.0"
903 + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.0.tgz#bd968567d61635e33c0b80727613c9cb4b096bac"
904 + dependencies:
905 + d "^0.1.1"
906 + es5-ext "^0.10.7"
907 + es6-symbol "3"
908 +
909 +es6-symbol@^3.0.2, es6-symbol@~3.1, es6-symbol@3:
910 + version "3.1.0"
911 + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.0.tgz#94481c655e7a7cad82eba832d97d5433496d7ffa"
912 + dependencies:
913 + d "~0.1.1"
914 + es5-ext "~0.10.11"
915 +
916 +escape-string-regexp@^1.0.2:
917 + version "1.0.5"
918 + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
919 +
920 +eventemitter2@~1.0.0:
921 + version "1.0.5"
922 + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-1.0.5.tgz#f983610517b1737c0b9dc643beca93893c04df18"
923 +
924 +events@~1.1.0:
925 + version "1.1.1"
926 + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
927 +
928 +evp_bytestokey@^1.0.0:
929 + version "1.0.0"
930 + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz#497b66ad9fef65cd7c08a6180824ba1476b66e53"
931 + dependencies:
932 + create-hash "^1.1.1"
933 +
934 +execspawn@^1.0.1:
935 + version "1.0.1"
936 + resolved "https://registry.yarnpkg.com/execspawn/-/execspawn-1.0.1.tgz#8286f9dde7cecde7905fbdc04e24f368f23f8da6"
937 + dependencies:
938 + util-extend "^1.0.1"
939 +
940 +exit-hook@^1.0.0:
941 + version "1.1.1"
942 + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
943 +
944 +expand-brackets@^0.1.4:
945 + version "0.1.5"
946 + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
947 + dependencies:
948 + is-posix-bracket "^0.1.0"
949 +
950 +expand-range@^1.8.1:
951 + version "1.8.2"
952 + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
953 + dependencies:
954 + fill-range "^2.1.0"
955 +
956 +expand-template@^1.0.0:
957 + version "1.0.3"
958 + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.0.3.tgz#6c303323177a62b1b22c070279f7861287b69b1a"
959 +
960 +explain-error@^1.0.1, explain-error@~1.0.1:
961 + version "1.0.3"
962 + resolved "https://registry.yarnpkg.com/explain-error/-/explain-error-1.0.3.tgz#f4e2b21152120d94db36d93bef03a5c42bfedce9"
963 +
964 +extend.js@0.0.2:
965 + version "0.0.2"
966 + resolved "https://registry.yarnpkg.com/extend.js/-/extend.js-0.0.2.tgz#0f9c7a81a1f208b703eb0c3131fe5716ac6ecd15"
967 +
968 +extend@^3.0.0, extend@~3.0.0:
969 + version "3.0.0"
970 + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4"
971 +
972 +extglob@^0.3.1:
973 + version "0.3.2"
974 + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
975 + dependencies:
976 + is-extglob "^1.0.0"
977 +
978 +extsprintf@1.0.2:
979 + version "1.0.2"
980 + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550"
981 +
982 +fast-future@~1.0.0:
983 + version "1.0.1"
984 + resolved "https://registry.yarnpkg.com/fast-future/-/fast-future-1.0.1.tgz#6cbd22d999ab39cd10fc79392486e7a678716818"
985 +
986 +filename-regex@^2.0.0:
987 + version "2.0.0"
988 + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775"
989 +
990 +fill-range@^2.1.0:
991 + version "2.2.3"
992 + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723"
993 + dependencies:
994 + is-number "^2.1.0"
995 + isobject "^2.0.0"
996 + randomatic "^1.1.3"
997 + repeat-element "^1.1.2"
998 + repeat-string "^1.5.2"
999 +
1000 +for-in@^0.1.5:
1001 + version "0.1.6"
1002 + resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.6.tgz#c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8"
1003 +
1004 +for-own@^0.1.3:
1005 + version "0.1.4"
1006 + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.4.tgz#0149b41a39088c7515f51ebe1c1386d45f935072"
1007 + dependencies:
1008 + for-in "^0.1.5"
1009 +
1010 +forever-agent@~0.6.1:
1011 + version "0.6.1"
1012 + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
1013 +
1014 +form-data@~2.0.0:
1015 + version "2.0.0"
1016 + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.0.0.tgz#6f0aebadcc5da16c13e1ecc11137d85f9b883b25"
1017 + dependencies:
1018 + asynckit "^0.4.0"
1019 + combined-stream "^1.0.5"
1020 + mime-types "^2.1.11"
1021 +
1022 +fs.realpath@^1.0.0:
1023 + version "1.0.0"
1024 + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
1025 +
1026 +fsevents@^1.0.0:
1027 + version "1.0.14"
1028 + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.0.14.tgz#558e8cc38643d8ef40fe45158486d0d25758eee4"
1029 + dependencies:
1030 + nan "^2.3.0"
1031 + node-pre-gyp "^0.6.29"
1032 +
1033 +fstream-ignore@~1.0.5:
1034 + version "1.0.5"
1035 + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105"
1036 + dependencies:
1037 + fstream "^1.0.0"
1038 + inherits "2"
1039 + minimatch "^3.0.0"
1040 +
1041 +fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10:
1042 + version "1.0.10"
1043 + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.10.tgz#604e8a92fe26ffd9f6fae30399d4984e1ab22822"
1044 + dependencies:
1045 + graceful-fs "^4.1.2"
1046 + inherits "~2.0.0"
1047 + mkdirp ">=0.5 0"
1048 + rimraf "2"
1049 +
1050 +function-bind@^1.0.2:
1051 + version "1.1.0"
1052 + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771"
1053 +
1054 +gauge@~1.2.5:
1055 + version "1.2.7"
1056 + resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93"
1057 + dependencies:
1058 + ansi "^0.3.0"
1059 + has-unicode "^2.0.0"
1060 + lodash.pad "^4.1.0"
1061 + lodash.padend "^4.1.0"
1062 + lodash.padstart "^4.1.0"
1063 +
1064 +gauge@~2.6.0:
1065 + version "2.6.0"
1066 + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.6.0.tgz#d35301ad18e96902b4751dcbbe40f4218b942a46"
1067 + dependencies:
1068 + aproba "^1.0.3"
1069 + console-control-strings "^1.0.0"
1070 + has-color "^0.1.7"
1071 + has-unicode "^2.0.0"
1072 + object-assign "^4.1.0"
1073 + signal-exit "^3.0.0"
1074 + string-width "^1.0.1"
1075 + strip-ansi "^3.0.1"
1076 + wide-align "^1.1.0"
1077 +
1078 +generate-function@^2.0.0:
1079 + version "2.0.0"
1080 + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
1081 +
1082 +generate-object-property@^1.1.0:
1083 + version "1.2.0"
1084 + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
1085 + dependencies:
1086 + is-property "^1.0.0"
1087 +
1088 +getpass@^0.1.1:
1089 + version "0.1.6"
1090 + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6"
1091 + dependencies:
1092 + assert-plus "^1.0.0"
1093 +
1094 +ghreleases@^1.0.2:
1095 + version "1.0.5"
1096 + resolved "https://registry.yarnpkg.com/ghreleases/-/ghreleases-1.0.5.tgz#a20f8194074311e19d84ccba7a6e08c4b434fd80"
1097 + dependencies:
1098 + after "~0.8.1"
1099 + ghrepos "~2.0.0"
1100 + ghutils "~3.2.0"
1101 + simple-mime "~0.1.0"
1102 + url-template "~2.0.6"
1103 + xtend "~4.0.0"
1104 +
1105 +ghrepos@~2.0.0:
1106 + version "2.0.0"
1107 + resolved "https://registry.yarnpkg.com/ghrepos/-/ghrepos-2.0.0.tgz#d66eae9d98a3b5398e460d6db7e10a742692e81b"
1108 + dependencies:
1109 + ghutils "~3.2.0"
1110 +
1111 +ghutils@~3.2.0:
1112 + version "3.2.0"
1113 + resolved "https://registry.yarnpkg.com/ghutils/-/ghutils-3.2.0.tgz#cbae545d88f4194754004603d4b5cb9c6537864e"
1114 + dependencies:
1115 + jsonist "~1.2.0"
1116 + xtend "~4.0.0"
1117 +
1118 +github-from-package@0.0.0:
1119 + version "0.0.0"
1120 + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
1121 +
1122 +glob-base@^0.3.0:
1123 + version "0.3.0"
1124 + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
1125 + dependencies:
1126 + glob-parent "^2.0.0"
1127 + is-glob "^2.0.0"
1128 +
1129 +glob-parent@^2.0.0:
1130 + version "2.0.0"
1131 + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28"
1132 + dependencies:
1133 + is-glob "^2.0.0"
1134 +
1135 +glob@^5.0.15:
1136 + version "5.0.15"
1137 + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
1138 + dependencies:
1139 + inflight "^1.0.4"
1140 + inherits "2"
1141 + minimatch "2 || 3"
1142 + once "^1.3.0"
1143 + path-is-absolute "^1.0.0"
1144 +
1145 +glob@^6.0.1:
1146 + version "6.0.4"
1147 + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
1148 + dependencies:
1149 + inflight "^1.0.4"
1150 + inherits "2"
1151 + minimatch "2 || 3"
1152 + once "^1.3.0"
1153 + path-is-absolute "^1.0.0"
1154 +
1155 +glob@^7.0.3, glob@^7.0.5, "glob@3 || 4 || 5 || 6 || 7":
1156 + version "7.1.1"
1157 + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
1158 + dependencies:
1159 + fs.realpath "^1.0.0"
1160 + inflight "^1.0.4"
1161 + inherits "2"
1162 + minimatch "^3.0.2"
1163 + once "^1.3.0"
1164 + path-is-absolute "^1.0.0"
1165 +
1166 +global@~4.2.1:
1167 + version "4.2.1"
1168 + resolved "https://registry.yarnpkg.com/global/-/global-4.2.1.tgz#c16801e9a47f0b0b847a156d419dc143b5a4e8b3"
1169 + dependencies:
1170 + min-document "^2.6.1"
1171 + process "~0.5.1"
1172 +
1173 +globby@^4.0.0:
1174 + version "4.1.0"
1175 + resolved "https://registry.yarnpkg.com/globby/-/globby-4.1.0.tgz#080f54549ec1b82a6c60e631fc82e1211dbe95f8"
1176 + dependencies:
1177 + array-union "^1.0.1"
1178 + arrify "^1.0.0"
1179 + glob "^6.0.1"
1180 + object-assign "^4.0.1"
1181 + pify "^2.0.0"
1182 + pinkie-promise "^2.0.0"
1183 +
1184 +graceful-fs@^4.1.2:
1185 + version "4.1.9"
1186 + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.9.tgz#baacba37d19d11f9d146d3578bc99958c3787e29"
1187 +
1188 +"graceful-readlink@>= 1.0.0":
1189 + version "1.0.1"
1190 + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
1191 +
1192 +graphmitter@^1.6.3:
1193 + version "1.6.3"
1194 + resolved "https://registry.yarnpkg.com/graphmitter/-/graphmitter-1.6.3.tgz#b140a52e539592b4757a339c5a42674563b86eb7"
1195 +
1196 +har-validator@~2.0.6:
1197 + version "2.0.6"
1198 + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d"
1199 + dependencies:
1200 + chalk "^1.1.1"
1201 + commander "^2.9.0"
1202 + is-my-json-valid "^2.12.4"
1203 + pinkie-promise "^2.0.0"
1204 +
1205 +has-ansi@^2.0.0:
1206 + version "2.0.0"
1207 + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
1208 + dependencies:
1209 + ansi-regex "^2.0.0"
1210 +
1211 +has-color@^0.1.7, has-color@~0.1.0:
1212 + version "0.1.7"
1213 + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f"
1214 +
1215 +has-unicode@^2.0.0:
1216 + version "2.0.1"
1217 + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
1218 +
1219 +has@^1.0.0, has@^1.0.1:
1220 + version "1.0.1"
1221 + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
1222 + dependencies:
1223 + function-bind "^1.0.2"
1224 +
1225 +hash.js@^1.0.0:
1226 + version "1.0.3"
1227 + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.0.3.tgz#1332ff00156c0a0ffdd8236013d07b77a0451573"
1228 + dependencies:
1229 + inherits "^2.0.1"
1230 +
1231 +hawk@~3.1.3:
1232 + version "3.1.3"
1233 + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
1234 + dependencies:
1235 + boom "2.x.x"
1236 + cryptiles "2.x.x"
1237 + hoek "2.x.x"
1238 + sntp "1.x.x"
1239 +
1240 +he@^0.5.0:
1241 + version "0.5.0"
1242 + resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2"
1243 +
1244 +hjson@^2.0.3:
1245 + version "2.1.0"
1246 + resolved "https://registry.yarnpkg.com/hjson/-/hjson-2.1.0.tgz#9e9b23b94079b64bf2023f0186f3a5c76d2fbb48"
1247 +
1248 +hmac@~1.0.1:
1249 + version "1.0.1"
1250 + resolved "https://registry.yarnpkg.com/hmac/-/hmac-1.0.1.tgz#16bda6b8ad5ae70848a1b9ec7c6f3577dfb19b24"
1251 +
1252 +hoek@2.x.x:
1253 + version "2.16.3"
1254 + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
1255 +
1256 +homedir@^0.6.0:
1257 + version "0.6.0"
1258 + resolved "https://registry.yarnpkg.com/homedir/-/homedir-0.6.0.tgz#2b21db66bf08a6db38249a3eff52d7d18706af1e"
1259 +
1260 +hoox@0.0.1:
1261 + version "0.0.1"
1262 + resolved "https://registry.yarnpkg.com/hoox/-/hoox-0.0.1.tgz#08a74d9272a9cc83ae8e6bbe0303f0ee76432094"
1263 +
1264 +html-element@^2.0.0:
1265 + version "2.1.1"
1266 + resolved "https://registry.yarnpkg.com/html-element/-/html-element-2.1.1.tgz#d80cc7a7d4e7fd590358d0bc9414f9eb0163003c"
1267 + dependencies:
1268 + class-list "~0.1.1"
1269 +
1270 +html-element@~1.3.0:
1271 + version "1.3.0"
1272 + resolved "https://registry.yarnpkg.com/html-element/-/html-element-1.3.0.tgz#d75ecb5dae874b1de60a0bf8794bbd1984d0f209"
1273 + dependencies:
1274 + class-list "~0.1.1"
1275 +
1276 +htmlescape@^1.1.0:
1277 + version "1.1.1"
1278 + resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351"
1279 +
1280 +http-signature@~1.1.0:
1281 + version "1.1.1"
1282 + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
1283 + dependencies:
1284 + assert-plus "^0.2.0"
1285 + jsprim "^1.2.2"
1286 + sshpk "^1.7.0"
1287 +
1288 +https-browserify@~0.0.0:
1289 + version "0.0.1"
1290 + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
1291 +
1292 +human-time@0.0.1:
1293 + version "0.0.1"
1294 + resolved "https://registry.yarnpkg.com/human-time/-/human-time-0.0.1.tgz#280d0336379199306b2e1518e3d5f6381cb8507d"
1295 +
1296 +hypercombo@0.1.0:
1297 + version "0.1.0"
1298 + resolved "https://registry.yarnpkg.com/hypercombo/-/hypercombo-0.1.0.tgz#142f1aa31ab5d23da6daa8e9dae2c257fc9e5c14"
1299 + dependencies:
1300 + hyperscript "^2.0.2"
1301 + pull-stream "^3.4.3"
1302 +
1303 +hypercrop@^1.0.1:
1304 + version "1.0.1"
1305 + resolved "https://registry.yarnpkg.com/hypercrop/-/hypercrop-1.0.1.tgz#3abe3c616d739d671f0b3522b8cd43f0c105aeae"
1306 + dependencies:
1307 + hyperscript "^1.4.7"
1308 +
1309 +hyperfile@^1.1.0, hyperfile@^1.1.1:
1310 + version "1.1.1"
1311 + resolved "https://registry.yarnpkg.com/hyperfile/-/hyperfile-1.1.1.tgz#733bc6c668fb9a216008c4f336531f894dbc79f3"
1312 + dependencies:
1313 + hyperscript "^1.4.7"
1314 +
1315 +hyperlightbox@^0.1.3:
1316 + version "0.1.3"
1317 + resolved "https://registry.yarnpkg.com/hyperlightbox/-/hyperlightbox-0.1.3.tgz#818da3a8b6e6f4cf73cab659beafca7abe5a0c0c"
1318 + dependencies:
1319 + hyperscript "^1.4.7"
1320 +
1321 +hyperprogress@^0.1.0:
1322 + version "0.1.1"
1323 + resolved "https://registry.yarnpkg.com/hyperprogress/-/hyperprogress-0.1.1.tgz#e530c6163aa2b1283eac192192225a762f09c344"
1324 +
1325 +hyperprogress@0.1.0:
1326 + version "0.1.0"
1327 + resolved "https://registry.yarnpkg.com/hyperprogress/-/hyperprogress-0.1.0.tgz#46f3ab8d1bc5fd140d22aea96651734924e6a62e"
1328 +
1329 +hyperquest@~1.2.0:
1330 + version "1.2.0"
1331 + resolved "https://registry.yarnpkg.com/hyperquest/-/hyperquest-1.2.0.tgz#39e1fef66888dc7ce0dec6c0dd814f6fc8944ad5"
1332 + dependencies:
1333 + duplexer2 "~0.0.2"
1334 + through2 "~0.6.3"
1335 +
1336 +hyperscript@^1.4.7, hyperscript@~1.4.2:
1337 + version "1.4.7"
1338 + resolved "https://registry.yarnpkg.com/hyperscript/-/hyperscript-1.4.7.tgz#1f23d880f8436caac25b91a7ac39747b89a72618"
1339 + dependencies:
1340 + browser-split "0.0.0"
1341 + class-list "~0.1.0"
1342 + html-element "~1.3.0"
1343 +
1344 +hyperscript@^2.0.2:
1345 + version "2.0.2"
1346 + resolved "https://registry.yarnpkg.com/hyperscript/-/hyperscript-2.0.2.tgz#3839cba45554bdfe27bb81c2142d1684f8135af5"
1347 + dependencies:
1348 + browser-split "0.0.0"
1349 + class-list "~0.1.0"
1350 + html-element "^2.0.0"
1351 +
1352 +hypertabs@^2.2.0:
1353 + version "2.2.1"
1354 + resolved "https://registry.yarnpkg.com/hypertabs/-/hypertabs-2.2.1.tgz#5b66ddc3e9ee45b57ee5a4fdc9fd33560a0425ae"
1355 + dependencies:
1356 + hyperscript "^1.4.7"
1357 +
1358 +ieee754@^1.1.4:
1359 + version "1.1.8"
1360 + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
1361 +
1362 +increment-buffer@~1.0.0:
1363 + version "1.0.0"
1364 + resolved "https://registry.yarnpkg.com/increment-buffer/-/increment-buffer-1.0.0.tgz#5eeadf45466d7b69ba3b1c00af8a54ddd0542d38"
1365 +
1366 +indexof@0.0.1:
1367 + version "0.0.1"
1368 + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
1369 +
1370 +inflight@^1.0.4:
1371 + version "1.0.5"
1372 + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.5.tgz#db3204cd5a9de2e6cd890b85c6e2f66bcf4f620a"
1373 + dependencies:
1374 + once "^1.3.0"
1375 + wrappy "1"
1376 +
1377 +inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1, inherits@2:
1378 + version "2.0.3"
1379 + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
1380 +
1381 +inherits@1.0.0:
1382 + version "1.0.0"
1383 + resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.0.tgz#38e1975285bf1f7ba9c84da102bb12771322ac48"
1384 +
1385 +inherits@2.0.1:
1386 + version "2.0.1"
1387 + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
1388 +
1389 +ini@~1.3.0:
1390 + version "1.3.4"
1391 + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
1392 +
1393 +inline-source-map@~0.6.0:
1394 + version "0.6.2"
1395 + resolved "https://registry.yarnpkg.com/inline-source-map/-/inline-source-map-0.6.2.tgz#f9393471c18a79d1724f863fa38b586370ade2a5"
1396 + dependencies:
1397 + source-map "~0.5.3"
1398 +
1399 +insert-module-globals@^7.0.0:
1400 + version "7.0.1"
1401 + resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.0.1.tgz#c03bf4e01cb086d5b5e5ace8ad0afe7889d638c3"
1402 + dependencies:
1403 + combine-source-map "~0.7.1"
1404 + concat-stream "~1.5.1"
1405 + is-buffer "^1.1.0"
1406 + JSONStream "^1.0.3"
1407 + lexical-scope "^1.2.0"
1408 + process "~0.11.0"
1409 + through2 "^2.0.0"
1410 + xtend "^4.0.0"
1411 +
1412 +ip@^0.3.3, ip@~0.3.2:
1413 + version "0.3.3"
1414 + resolved "https://registry.yarnpkg.com/ip/-/ip-0.3.3.tgz#8ee8309e92f0b040d287f72efaca1a21702d3fb4"
1415 +
1416 +ip@^1.1.2, ip@^1.1.3:
1417 + version "1.1.3"
1418 + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.3.tgz#12b16294a38925486d618a1103506e4eb4f8b296"
1419 +
1420 +irregular-plurals@^1.0.0:
1421 + version "1.2.0"
1422 + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.2.0.tgz#38f299834ba8c00c30be9c554e137269752ff3ac"
1423 +
1424 +is-alphabetical@^1.0.0:
1425 + version "1.0.0"
1426 + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.0.tgz#e2544c13058255f2144cb757066cd3342a1c8c46"
1427 +
1428 +is-alphanumerical@^1.0.0:
1429 + version "1.0.0"
1430 + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.0.tgz#e06492e719c1bf15dec239e4f1af5f67b4d6e7bf"
1431 + dependencies:
1432 + is-alphabetical "^1.0.0"
1433 + is-decimal "^1.0.0"
1434 +
1435 +is-binary-path@^1.0.0:
1436 + version "1.0.1"
1437 + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
1438 + dependencies:
1439 + binary-extensions "^1.0.0"
1440 +
1441 +is-buffer@^1.0.2, is-buffer@^1.1.0:
1442 + version "1.1.4"
1443 + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b"
1444 +
1445 +is-decimal@^1.0.0:
1446 + version "1.0.0"
1447 + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.0.tgz#940579b6ea63c628080a69e62bda88c8470b4fe0"
1448 +
1449 +is-dotfile@^1.0.0:
1450 + version "1.0.2"
1451 + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d"
1452 +
1453 +is-electron@^2.0.0:
1454 + version "2.0.0"
1455 + resolved "https://registry.yarnpkg.com/is-electron/-/is-electron-2.0.0.tgz#c82d3599640f7df91c84eaaee76bc56713c6ac79"
1456 +
1457 +is-equal-shallow@^0.1.3:
1458 + version "0.1.3"
1459 + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534"
1460 + dependencies:
1461 + is-primitive "^2.0.0"
1462 +
1463 +is-extendable@^0.1.1:
1464 + version "0.1.1"
1465 + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
1466 +
1467 +is-extglob@^1.0.0:
1468 + version "1.0.0"
1469 + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
1470 +
1471 +is-fullwidth-code-point@^1.0.0:
1472 + version "1.0.0"
1473 + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
1474 + dependencies:
1475 + number-is-nan "^1.0.0"
1476 +
1477 +is-glob@^2.0.0, is-glob@^2.0.1:
1478 + version "2.0.1"
1479 + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
1480 + dependencies:
1481 + is-extglob "^1.0.0"
1482 +
1483 +is-hexadecimal@^1.0.0:
1484 + version "1.0.0"
1485 + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.0.tgz#5c459771d2af9a2e3952781fd54fcb1bcfe4113c"
1486 +
1487 +is-my-json-valid@^2.12.4:
1488 + version "2.15.0"
1489 + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz#936edda3ca3c211fd98f3b2d3e08da43f7b2915b"
1490 + dependencies:
1491 + generate-function "^2.0.0"
1492 + generate-object-property "^1.1.0"
1493 + jsonpointer "^4.0.0"
1494 + xtend "^4.0.0"
1495 +
1496 +is-number@^2.0.2, is-number@^2.1.0:
1497 + version "2.1.0"
1498 + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
1499 + dependencies:
1500 + kind-of "^3.0.2"
1501 +
1502 +is-posix-bracket@^0.1.0:
1503 + version "0.1.1"
1504 + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
1505 +
1506 +is-primitive@^2.0.0:
1507 + version "2.0.0"
1508 + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
1509 +
1510 +is-property@^1.0.0:
1511 + version "1.0.2"
1512 + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
1513 +
1514 +is-typedarray@~1.0.0:
1515 + version "1.0.0"
1516 + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
1517 +
1518 +is-valid-domain@~0.0.1:
1519 + version "0.0.2"
1520 + resolved "https://registry.yarnpkg.com/is-valid-domain/-/is-valid-domain-0.0.2.tgz#3e7a9423ff7c3b2fe11663afbd6d3837a251fb77"
1521 +
1522 +is-visible@^2.0.1, is-visible@^2.0.4:
1523 + version "2.1.1"
1524 + resolved "https://registry.yarnpkg.com/is-visible/-/is-visible-2.1.1.tgz#6721ed5cc730f9187709643fd60bf3e8481dddaf"
1525 + dependencies:
1526 + iselement "^1.1.3"
1527 + style-properties "^1.3.1"
1528 +
1529 +is@^3.1.0:
1530 + version "3.1.0"
1531 + resolved "https://registry.yarnpkg.com/is/-/is-3.1.0.tgz#2945d205d691cbfe4833e3f8a11c8ae94673f2a7"
1532 +
1533 +isarray@^1.0.0, isarray@~1.0.0, isarray@1.0.0:
1534 + version "1.0.0"
1535 + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
1536 +
1537 +isarray@~0.0.1, isarray@0.0.1:
1538 + version "0.0.1"
1539 + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
1540 +
1541 +iselement@^1.1.3:
1542 + version "1.1.4"
1543 + resolved "https://registry.yarnpkg.com/iselement/-/iselement-1.1.4.tgz#7e55b52a8ebca50a7e2e80e5b8d2840f32353146"
1544 +
1545 +isexe@^1.1.1:
1546 + version "1.1.2"
1547 + resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0"
1548 +
1549 +isobject@^2.0.0:
1550 + version "2.1.0"
1551 + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
1552 + dependencies:
1553 + isarray "1.0.0"
1554 +
1555 +isstream@~0.1.2:
1556 + version "0.1.2"
1557 + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
1558 +
1559 +jodid25519@^1.0.0:
1560 + version "1.0.2"
1561 + resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967"
1562 + dependencies:
1563 + jsbn "~0.1.0"
1564 +
1565 +jsbn@~0.1.0:
1566 + version "0.1.0"
1567 + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.0.tgz#650987da0dd74f4ebf5a11377a2aa2d273e97dfd"
1568 +
1569 +json-buffer@^2.0.11:
1570 + version "2.0.11"
1571 + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-2.0.11.tgz#3e441fda3098be8d1e3171ad591bc62a33e2d55f"
1572 +
1573 +json-schema@0.2.3:
1574 + version "0.2.3"
1575 + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
1576 +
1577 +json-stable-stringify@~0.0.0:
1578 + version "0.0.1"
1579 + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz#611c23e814db375527df851193db59dd2af27f45"
1580 + dependencies:
1581 + jsonify "~0.0.0"
1582 +
1583 +json-stringify-safe@~5.0.0, json-stringify-safe@~5.0.1:
1584 + version "5.0.1"
1585 + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
1586 +
1587 +jsonify@~0.0.0:
1588 + version "0.0.0"
1589 + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
1590 +
1591 +jsonist@~1.2.0:
1592 + version "1.2.0"
1593 + resolved "https://registry.yarnpkg.com/jsonist/-/jsonist-1.2.0.tgz#da7555a5da1002d53ba30c3f0e05a2808fb82f34"
1594 + dependencies:
1595 + bl "~1.0.0"
1596 + hyperquest "~1.2.0"
1597 + json-stringify-safe "~5.0.0"
1598 + xtend "~4.0.0"
1599 +
1600 +jsonparse@^1.2.0:
1601 + version "1.2.0"
1602 + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.2.0.tgz#5c0c5685107160e72fe7489bddea0b44c2bc67bd"
1603 +
1604 +jsonpointer@^4.0.0:
1605 + version "4.0.0"
1606 + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.0.tgz#6661e161d2fc445f19f98430231343722e1fcbd5"
1607 +
1608 +JSONStream@^1.0.3:
1609 + version "1.2.1"
1610 + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.2.1.tgz#32aa5790e799481083b49b4b7fa94e23bae69bf9"
1611 + dependencies:
1612 + jsonparse "^1.2.0"
1613 + through ">=2.2.7 <3"
1614 +
1615 +jsprim@^1.2.2:
1616 + version "1.3.1"
1617 + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.3.1.tgz#2a7256f70412a29ee3670aaca625994c4dcff252"
1618 + dependencies:
1619 + extsprintf "1.0.2"
1620 + json-schema "0.2.3"
1621 + verror "1.3.6"
1622 +
1623 +kind-of@^3.0.2:
1624 + version "3.0.4"
1625 + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.0.4.tgz#7b8ecf18a4e17f8269d73b501c9f232c96887a74"
1626 + dependencies:
1627 + is-buffer "^1.0.2"
1628 +
1629 +konva@~1.0.0:
1630 + version "1.0.3"
1631 + resolved "https://registry.yarnpkg.com/konva/-/konva-1.0.3.tgz#f06122a59574e0ed66dfa95dbd3a686785e5b3a1"
1632 +
1633 +labeled-stream-splicer@^2.0.0:
1634 + version "2.0.0"
1635 + resolved "https://registry.yarnpkg.com/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz#a52e1d138024c00b86b1c0c91f677918b8ae0a59"
1636 + dependencies:
1637 + inherits "^2.0.1"
1638 + isarray "~0.0.1"
1639 + stream-splicer "^2.0.0"
1640 +
1641 +letiny-core@^2.0.1:
1642 + version "2.0.3"
1643 + resolved "https://registry.yarnpkg.com/letiny-core/-/letiny-core-2.0.3.tgz#f8e383f64e0a939d8dea56c00fe2ab0c767a9a97"
1644 + dependencies:
1645 + node-forge "^0.6.38"
1646 + request "^2.55.0"
1647 + rsa-compat "^1.2.3"
1648 + optionalDependencies:
1649 + ursa "^0.9.1"
1650 +
1651 +letsencrypt-express@^1.1.5:
1652 + version "1.2.0"
1653 + resolved "https://registry.yarnpkg.com/letsencrypt-express/-/letsencrypt-express-1.2.0.tgz#d7e6e7ba6b076217ec12edb554c267bd6be5a990"
1654 + dependencies:
1655 + homedir "^0.6.0"
1656 + letsencrypt "^1.5.0"
1657 + localhost.daplie.com-certificates "^1.1.2"
1658 + mkdirp "^0.5.1"
1659 +
1660 +letsencrypt@^1.5.0:
1661 + version "1.5.8"
1662 + resolved "https://registry.yarnpkg.com/letsencrypt/-/letsencrypt-1.5.8.tgz#85e38c5a69f9f9c6360617c1760648efddce7c62"
1663 + dependencies:
1664 + asn1js "^1.2.12"
1665 + bluebird "^3.0.6"
1666 + homedir "^0.6.0"
1667 + letiny-core "^2.0.1"
1668 + mkdirp "^0.5.1"
1669 + node.extend "^1.1.5"
1670 + pkijs "^1.3.27"
1671 + pyconf "^1.1.2"
1672 + request "^2.67.0"
1673 + rsa-compat "^1.2.1"
1674 + safe-replace "^1.0.2"
1675 +
1676 +level-codec@~6.1.0:
1677 + version "6.1.0"
1678 + resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-6.1.0.tgz#f5df0a99582f76dac43855151ab6f4e4d0d60045"
1679 +
1680 +level-errors@^1.0.3, level-errors@~1.0.3:
1681 + version "1.0.4"
1682 + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.4.tgz#3585e623974c737a93755492a43c0267cda4425f"
1683 + dependencies:
1684 + errno "~0.1.1"
1685 +
1686 +level-iterator-stream@~1.3.0:
1687 + version "1.3.1"
1688 + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed"
1689 + dependencies:
1690 + inherits "^2.0.1"
1691 + level-errors "^1.0.3"
1692 + readable-stream "^1.0.33"
1693 + xtend "^4.0.0"
1694 +
1695 +level-live-stream@~1.4.9:
1696 + version "1.4.11"
1697 + resolved "https://registry.yarnpkg.com/level-live-stream/-/level-live-stream-1.4.11.tgz#77a57544c446412e310f5a5cc479b5d584bbbf7a"
1698 + dependencies:
1699 + level-sublevel "~6.3.1"
1700 + pull-level "^1.4.1"
1701 + pull-stream-to-stream "~1.2.4"
1702 +
1703 +level-memview@~0.0.0:
1704 + version "0.0.0"
1705 + resolved "https://registry.yarnpkg.com/level-memview/-/level-memview-0.0.0.tgz#46d35373ae34e342cf4a574a5e3514a1d4753a20"
1706 + dependencies:
1707 + level-live-stream "~1.4.9"
1708 + pull-level "~1.2.0"
1709 + pull-stream "~2.26.0"
1710 +
1711 +level-packager@~1.2.0:
1712 + version "1.2.0"
1713 + resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-1.2.0.tgz#1db6709e81bb8dbf1c089792910e20f7e6430056"
1714 + dependencies:
1715 + levelup "~1.3.0"
1716 +
1717 +level-peek@^2.0.1:
1718 + version "2.0.1"
1719 + resolved "https://registry.yarnpkg.com/level-peek/-/level-peek-2.0.1.tgz#90daee917898df1c049518fbbd3a5b9441559e45"
1720 + dependencies:
1721 + pull-level "^2.0.3"
1722 + pull-stream "~2.24.0"
1723 +
1724 +level-post@~1.0.3:
1725 + version "1.0.5"
1726 + resolved "https://registry.yarnpkg.com/level-post/-/level-post-1.0.5.tgz#2a66390409bf6a1621a444bab6f016444cc9802c"
1727 + dependencies:
1728 + ltgt "^2.1.2"
1729 +
1730 +level-sublevel@^6.6.0:
1731 + version "6.6.0"
1732 + resolved "https://registry.yarnpkg.com/level-sublevel/-/level-sublevel-6.6.0.tgz#675f2f6a3d437b10700e840069bcb331a5c8362f"
1733 + dependencies:
1734 + bytewise "~1.1.0"
1735 + levelup "~0.19.0"
1736 + ltgt "~2.1.1"
1737 + pull-stream "~2.21.0"
1738 + typewiselite "~1.0.0"
1739 + xtend "~4.0.0"
1740 +
1741 +level-sublevel@~6.3.1:
1742 + version "6.3.17"
1743 + resolved "https://registry.yarnpkg.com/level-sublevel/-/level-sublevel-6.3.17.tgz#6d514fe432619199fa300911bfdfa3f98de761cb"
1744 + dependencies:
1745 + bytewise "~0.7.1"
1746 + levelup "~0.19.0"
1747 + ltgt "~2.0.0"
1748 + pull-stream "~2.21.0"
1749 + typewiselite "~1.0.0"
1750 + xtend "~4.0.0"
1751 +
1752 +level@^1.4.0:
1753 + version "1.4.0"
1754 + resolved "https://registry.yarnpkg.com/level/-/level-1.4.0.tgz#640c742097e515a6785c66c5f8a5464a01c2f581"
1755 + dependencies:
1756 + level-packager "~1.2.0"
1757 + leveldown "~1.4.0"
1758 +
1759 +leveldown@~1.4.0:
1760 + version "1.4.6"
1761 + resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-1.4.6.tgz#c627baa4c6765fd3ebf94f3b30a7aefdb9c893fb"
1762 + dependencies:
1763 + abstract-leveldown "~2.4.0"
1764 + bindings "~1.2.1"
1765 + fast-future "~1.0.0"
1766 + nan "~2.3.0"
1767 + prebuild "^4.1.1"
1768 +
1769 +levelup@~0.19.0:
1770 + version "0.19.1"
1771 + resolved "https://registry.yarnpkg.com/levelup/-/levelup-0.19.1.tgz#f3a6a7205272c4b5f35e412ff004a03a0aedf50b"
1772 + dependencies:
1773 + bl "~0.8.1"
1774 + deferred-leveldown "~0.2.0"
1775 + errno "~0.1.1"
1776 + prr "~0.0.0"
1777 + readable-stream "~1.0.26"
1778 + semver "~5.1.0"
1779 + xtend "~3.0.0"
1780 +
1781 +levelup@~1.3.0:
1782 + version "1.3.3"
1783 + resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.3.tgz#bf9db62bdb6188d08eaaa2efcf6cc311916f41fd"
1784 + dependencies:
1785 + deferred-leveldown "~1.2.1"
1786 + level-codec "~6.1.0"
1787 + level-errors "~1.0.3"
1788 + level-iterator-stream "~1.3.0"
1789 + prr "~1.0.1"
1790 + semver "~5.1.0"
1791 + xtend "~4.0.0"
1792 +
1793 +lexical-scope@^1.2.0:
1794 + version "1.2.0"
1795 + resolved "https://registry.yarnpkg.com/lexical-scope/-/lexical-scope-1.2.0.tgz#fcea5edc704a4b3a8796cdca419c3a0afaf22df4"
1796 + dependencies:
1797 + astw "^2.0.0"
1798 +
1799 +libsodium-wrappers@^0.2.9:
1800 + version "0.2.12"
1801 + resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.2.12.tgz#51fb50774b8edc517927b307b812a46c3a467e1e"
1802 + dependencies:
1803 + libsodium "0.2.12"
1804 +
1805 +libsodium@0.2.12:
1806 + version "0.2.12"
1807 + resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.2.12.tgz#83083564dcf089cb82a5035be92ba5d224a2ccde"
1808 +
1809 +localhost.daplie.com-certificates@^1.1.2:
1810 + version "1.2.3"
1811 + resolved "https://registry.yarnpkg.com/localhost.daplie.com-certificates/-/localhost.daplie.com-certificates-1.2.3.tgz#f8958077ba152e33301aa87195211dd28fdb0266"
1812 +
1813 +lodash.memoize@~3.0.3:
1814 + version "3.0.4"
1815 + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f"
1816 +
1817 +lodash.pad@^4.1.0:
1818 + version "4.5.1"
1819 + resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70"
1820 +
1821 +lodash.padend@^4.1.0:
1822 + version "4.6.1"
1823 + resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e"
1824 +
1825 +lodash.padstart@^4.1.0:
1826 + version "4.6.1"
1827 + resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b"
1828 +
1829 +log-symbols@^1.0.2:
1830 + version "1.0.2"
1831 + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
1832 + dependencies:
1833 + chalk "^1.0.0"
1834 +
1835 +log-update@^1.0.1:
1836 + version "1.0.2"
1837 + resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1"
1838 + dependencies:
1839 + ansi-escapes "^1.0.0"
1840 + cli-cursor "^1.0.2"
1841 +
1842 +longest-streak@^1.0.0:
1843 + version "1.0.0"
1844 + resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-1.0.0.tgz#d06597c4d4c31b52ccb1f5d8f8fe7148eafd6965"
1845 +
1846 +looper@^2.0.0:
1847 + version "2.0.0"
1848 + resolved "https://registry.yarnpkg.com/looper/-/looper-2.0.0.tgz#66cd0c774af3d4fedac53794f742db56da8f09ec"
1849 +
1850 +looper@^3.0.0, looper@~3.0.0:
1851 + version "3.0.0"
1852 + resolved "https://registry.yarnpkg.com/looper/-/looper-3.0.0.tgz#2efa54c3b1cbaba9b94aee2e5914b0be57fbb749"
1853 +
1854 +ltgt@^2.1.2, ltgt@~2.1.1:
1855 + version "2.1.2"
1856 + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.1.2.tgz#e7472324fee690afc0d5ecf900403ce5788a311d"
1857 +
1858 +ltgt@~2.0.0:
1859 + version "2.0.0"
1860 + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.0.0.tgz#b40ed1e337caf577c0a963f9cffbc680318009c2"
1861 +
1862 +map-filter-reduce@^3.0.1, map-filter-reduce@^3.0.2:
1863 + version "3.0.2"
1864 + resolved "https://registry.yarnpkg.com/map-filter-reduce/-/map-filter-reduce-3.0.2.tgz#8acec6be70422999514e79f39db7d2719458ba6d"
1865 + dependencies:
1866 + binary-search "^1.2.0"
1867 + pull-sink-through "0.0.0"
1868 + pull-stream "^3.4.3"
1869 + typewiselite "^1.0.0"
1870 +
1871 +map-merge@^1.1.0, map-merge@~1.1.0:
1872 + version "1.1.0"
1873 + resolved "https://registry.yarnpkg.com/map-merge/-/map-merge-1.1.0.tgz#6a6fc58c95d8aab46c2bdde44d515b6ee06fce34"
1874 +
1875 +markdown-table@^0.4.0:
1876 + version "0.4.0"
1877 + resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-0.4.0.tgz#890c2c1b3bfe83fb00e4129b8e4cfe645270f9d1"
1878 +
1879 +mdmanifest@^1.0.4:
1880 + version "1.0.8"
1881 + resolved "https://registry.yarnpkg.com/mdmanifest/-/mdmanifest-1.0.8.tgz#c04891883c28c83602e1d06b05a11037e359b4c8"
1882 + dependencies:
1883 + minimist "^1.2.0"
1884 + remark "^3.2.2"
1885 + remark-html "^2.0.2"
1886 + word-wrap "^1.1.0"
1887 +
1888 +micromatch@^2.1.5:
1889 + version "2.3.11"
1890 + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
1891 + dependencies:
1892 + arr-diff "^2.0.0"
1893 + array-unique "^0.2.1"
1894 + braces "^1.8.2"
1895 + expand-brackets "^0.1.4"
1896 + extglob "^0.3.1"
1897 + filename-regex "^2.0.0"
1898 + is-extglob "^1.0.0"
1899 + is-glob "^2.0.1"
1900 + kind-of "^3.0.2"
1901 + normalize-path "^2.0.1"
1902 + object.omit "^2.0.0"
1903 + parse-glob "^3.0.4"
1904 + regex-cache "^0.4.2"
1905 +
1906 +miller-rabin@^4.0.0:
1907 + version "4.0.0"
1908 + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.0.tgz#4a62fb1d42933c05583982f4c716f6fb9e6c6d3d"
1909 + dependencies:
1910 + bn.js "^4.0.0"
1911 + brorand "^1.0.1"
1912 +
1913 +mime-db@~1.24.0:
1914 + version "1.24.0"
1915 + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.24.0.tgz#e2d13f939f0016c6e4e9ad25a8652f126c467f0c"
1916 +
1917 +mime-types@^2.1.11, mime-types@~2.1.7:
1918 + version "2.1.12"
1919 + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.12.tgz#152ba256777020dd4663f54c2e7bc26381e71729"
1920 + dependencies:
1921 + mime-db "~1.24.0"
1922 +
1923 +min-document@^2.6.1:
1924 + version "2.19.0"
1925 + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
1926 + dependencies:
1927 + dom-walk "^0.1.0"
1928 +
1929 +minimalistic-assert@^1.0.0:
1930 + version "1.0.0"
1931 + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3"
1932 +
1933 +minimatch@^3.0.0, minimatch@^3.0.2, "minimatch@2 || 3", minimatch@3:
1934 + version "3.0.3"
1935 + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774"
1936 + dependencies:
1937 + brace-expansion "^1.0.0"
1938 +
1939 +minimist@^1.1.0, minimist@^1.1.2, minimist@^1.1.3, minimist@^1.2.0:
1940 + version "1.2.0"
1941 + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
1942 +
1943 +minimist@~0.0.7:
1944 + version "0.0.10"
1945 + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
1946 +
1947 +minimist@0.0.8:
1948 + version "0.0.8"
1949 + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
1950 +
1951 +mkdirp@^0.5.0, mkdirp@^0.5.1, "mkdirp@>=0.5 0", mkdirp@~0.5.0, mkdirp@~0.5.1:
1952 + version "0.5.1"
1953 + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
1954 + dependencies:
1955 + minimist "0.0.8"
1956 +
1957 +module-deps@^4.0.2:
1958 + version "4.0.7"
1959 + resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-4.0.7.tgz#edfeb3937be7359bc14a6672c22ef124887f6ed2"
1960 + dependencies:
1961 + browser-resolve "^1.7.0"
1962 + concat-stream "~1.5.0"
1963 + defined "^1.0.0"
1964 + detective "^4.0.0"
1965 + duplexer2 "^0.1.2"
1966 + inherits "^2.0.1"
1967 + JSONStream "^1.0.3"
1968 + parents "^1.0.0"
1969 + readable-stream "^2.0.2"
1970 + resolve "^1.1.3"
1971 + stream-combiner2 "^1.1.1"
1972 + subarg "^1.0.0"
1973 + through2 "^2.0.0"
1974 + xtend "^4.0.0"
1975 +
1976 +moment@^2.13.0:
1977 + version "2.15.1"
1978 + resolved "https://registry.yarnpkg.com/moment/-/moment-2.15.1.tgz#e979c2a29e22888e60f396f2220a6118f85cd94c"
1979 +
1980 +monotonic-timestamp@~0.0.8, monotonic-timestamp@~0.0.9:
1981 + version "0.0.9"
1982 + resolved "https://registry.yarnpkg.com/monotonic-timestamp/-/monotonic-timestamp-0.0.9.tgz#5ba5adc7aac85e1d7ce77be847161ed246b39603"
1983 +
1984 +ms@0.7.1:
1985 + version "0.7.1"
1986 + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
1987 +
1988 +multiblob-http@^0.2.0:
1989 + version "0.2.0"
1990 + resolved "https://registry.yarnpkg.com/multiblob-http/-/multiblob-http-0.2.0.tgz#09c820eda9b83f6b98bce884b75846926e6be151"
1991 + dependencies:
1992 + pull-stream "^3.4.3"
1993 + stream-to-pull-stream "^1.7.0"
1994 +
1995 +multiblob@^1.10.0, multiblob@^1.10.1:
1996 + version "1.10.2"
1997 + resolved "https://registry.yarnpkg.com/multiblob/-/multiblob-1.10.2.tgz#4c47a1e4e90c3cbae95bbce0631ba67204676b3d"
1998 + dependencies:
1999 + blake2s "~1.0.1"
2000 + cont "~1.0.1"
2001 + explain-error "~1.0.1"
2002 + mkdirp "~0.5.0"
2003 + pull-cat "^1.1.8"
2004 + pull-defer "^0.2.2"
2005 + pull-file "^0.5.0"
2006 + pull-glob "~1.0.6"
2007 + pull-live "^1.0.0"
2008 + pull-notify "0.0.2"
2009 + pull-paramap "^1.1.4"
2010 + pull-stream "^3.3.0"
2011 + pull-write-file "^0.2.1"
2012 + rc "~0.5.4"
2013 + rimraf "~2.2.8"
2014 +
2015 +multicb@^1.0.0:
2016 + version "1.2.1"
2017 + resolved "https://registry.yarnpkg.com/multicb/-/multicb-1.2.1.tgz#e2499df476a7f8f8d52ded265d13b2c1a69d9827"
2018 +
2019 +multiserver@^1.2.0, multiserver@^1.7.0:
2020 + version "1.7.2"
2021 + resolved "https://registry.yarnpkg.com/multiserver/-/multiserver-1.7.2.tgz#01c324693f5f8d55eef2fb5f7950917a28c0eec0"
2022 + dependencies:
2023 + pull-cat "~1.1.5"
2024 + pull-stream "^3.4.3"
2025 + pull-ws "^3.2.2"
2026 + secret-handshake "^1.1.1"
2027 + separator-escape "0.0.0"
2028 + socks "1.1.9"
2029 + stream-to-pull-stream "^1.7.2"
2030 +
2031 +muxrpc-validation@^2.0.0:
2032 + version "2.0.1"
2033 + resolved "https://registry.yarnpkg.com/muxrpc-validation/-/muxrpc-validation-2.0.1.tgz#cd650d172025fe9d064230aab38ca6328dd16f2f"
2034 + dependencies:
2035 + pull-stream "^2.28.3"
2036 + zerr "^1.0.1"
2037 +
2038 +muxrpc@^6.1.1, muxrpc@^6.2.2, muxrpc@^6.3.3:
2039 + version "6.3.3"
2040 + resolved "https://registry.yarnpkg.com/muxrpc/-/muxrpc-6.3.3.tgz#68ad940ef7f601df9da9ef2211b0a173d5286f9d"
2041 + dependencies:
2042 + explain-error "^1.0.1"
2043 + packet-stream "~2.0.0"
2044 + packet-stream-codec "^1.1.1"
2045 + pull-goodbye "~0.0.1"
2046 + pull-stream "^3.2.3"
2047 +
2048 +muxrpcli@^1.0.0:
2049 + version "1.0.5"
2050 + resolved "https://registry.yarnpkg.com/muxrpcli/-/muxrpcli-1.0.5.tgz#3c1d554369c93e6af0c3f6faa54ee8c9868dca55"
2051 + dependencies:
2052 + minimist "^1.2.0"
2053 + pull-stream "^2.28.3"
2054 + stream-to-pull-stream "^1.6.6"
2055 + word-wrap "^1.1.0"
2056 +
2057 +mv@^2.1.1:
2058 + version "2.1.1"
2059 + resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2"
2060 + dependencies:
2061 + mkdirp "~0.5.1"
2062 + ncp "~2.0.0"
2063 + rimraf "~2.4.0"
2064 +
2065 +mynosql-query@~1.0.0:
2066 + version "1.0.0"
2067 + resolved "https://registry.yarnpkg.com/mynosql-query/-/mynosql-query-1.0.0.tgz#d12c6cf4912c9234f4c90a2c8106116a13bc637a"
2068 +
2069 +nan@^2.0.9, nan@^2.3.0, nan@^2.3.3:
2070 + version "2.4.0"
2071 + resolved "https://registry.yarnpkg.com/nan/-/nan-2.4.0.tgz#fb3c59d45fe4effe215f0b890f8adf6eb32d2232"
2072 +
2073 +nan@~2.3.0:
2074 + version "2.3.5"
2075 + resolved "https://registry.yarnpkg.com/nan/-/nan-2.3.5.tgz#822a0dc266290ce4cd3a12282ca3e7e364668a08"
2076 +
2077 +ncp@~2.0.0:
2078 + version "2.0.0"
2079 + resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3"
2080 +
2081 +node-forge@^0.6.38, node-forge@^0.6.41:
2082 + version "0.6.43"
2083 + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.6.43.tgz#70c40ca7ed9f0f4aa35b424507ca9e45246bfe09"
2084 +
2085 +node-gyp@^3.0.3:
2086 + version "3.4.0"
2087 + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.4.0.tgz#dda558393b3ecbbe24c9e6b8703c71194c63fa36"
2088 + dependencies:
2089 + fstream "^1.0.0"
2090 + glob "^7.0.3"
2091 + graceful-fs "^4.1.2"
2092 + minimatch "^3.0.2"
2093 + mkdirp "^0.5.0"
2094 + nopt "2 || 3"
2095 + npmlog "0 || 1 || 2 || 3"
2096 + osenv "0"
2097 + path-array "^1.0.0"
2098 + request "2"
2099 + rimraf "2"
2100 + semver "2.x || 3.x || 4 || 5"
2101 + tar "^2.0.0"
2102 + which "1"
2103 +
2104 +node-ninja@^1.0.1:
2105 + version "1.0.2"
2106 + resolved "https://registry.yarnpkg.com/node-ninja/-/node-ninja-1.0.2.tgz#20a09e57b92e2df591993d4bf098ac3e727062b6"
2107 + dependencies:
2108 + fstream "^1.0.0"
2109 + glob "3 || 4 || 5 || 6 || 7"
2110 + graceful-fs "^4.1.2"
2111 + minimatch "3"
2112 + mkdirp "^0.5.0"
2113 + nopt "2 || 3"
2114 + npmlog "0 || 1 || 2"
2115 + osenv "0"
2116 + path-array "^1.0.0"
2117 + request "2"
2118 + rimraf "2"
2119 + semver "2.x || 3.x || 4 || 5"
2120 + tar "^2.0.0"
2121 + which "1"
2122 +
2123 +node-pre-gyp@^0.6.29:
2124 + version "0.6.30"
2125 + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.30.tgz#64d3073a6f573003717ccfe30c89023297babba1"
2126 + dependencies:
2127 + mkdirp "~0.5.0"
2128 + nopt "~3.0.1"
2129 + npmlog "4.x"
2130 + rc "~1.1.0"
2131 + request "2.x"
2132 + rimraf "~2.5.0"
2133 + semver "~5.3.0"
2134 + tar "~2.2.0"
2135 + tar-pack "~3.1.0"
2136 +
2137 +node-uuid@~1.4.7:
2138 + version "1.4.7"
2139 + resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.7.tgz#6da5a17668c4b3dd59623bda11cf7fa4c1f60a6f"
2140 +
2141 +node.extend@^1.1.5:
2142 + version "1.1.6"
2143 + resolved "https://registry.yarnpkg.com/node.extend/-/node.extend-1.1.6.tgz#a7b882c82d6c93a4863a5504bd5de8ec86258b96"
2144 + dependencies:
2145 + is "^3.1.0"
2146 +
2147 +nomnom@1.8.0:
2148 + version "1.8.0"
2149 + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.0.tgz#dcbbf531b9299c11b7d7845066045b5237d2c8d9"
2150 + dependencies:
2151 + chalk "~0.4.0"
2152 + underscore "~1.6.0"
2153 +
2154 +non-private-ip@^1.2.1, non-private-ip@^1.3.0:
2155 + version "1.4.1"
2156 + resolved "https://registry.yarnpkg.com/non-private-ip/-/non-private-ip-1.4.1.tgz#adba2df680cae6cd6b056110229420efb6ccf483"
2157 + dependencies:
2158 + ip "~0.3.2"
2159 +
2160 +non-private-ip@~1.1.0:
2161 + version "1.1.0"
2162 + resolved "https://registry.yarnpkg.com/non-private-ip/-/non-private-ip-1.1.0.tgz#46f45352d50f687340e4c011f7163ca6d1907403"
2163 + dependencies:
2164 + ip "~0.3.2"
2165 +
2166 +noop-logger@^0.1.0:
2167 + version "0.1.1"
2168 + resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2"
2169 +
2170 +nopt@~3.0.1, "nopt@2 || 3":
2171 + version "3.0.6"
2172 + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
2173 + dependencies:
2174 + abbrev "1"
2175 +
2176 +normalize-path@^2.0.1:
2177 + version "2.0.1"
2178 + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a"
2179 +
2180 +normalize-uri@^1.0.0:
2181 + version "1.0.0"
2182 + resolved "https://registry.yarnpkg.com/normalize-uri/-/normalize-uri-1.0.0.tgz#c2407bca400808202a108f6776e335ca03bfa69f"
2183 +
2184 +npm-prefix@^1.0.1:
2185 + version "1.2.0"
2186 + resolved "https://registry.yarnpkg.com/npm-prefix/-/npm-prefix-1.2.0.tgz#e619455f7074ba54cc66d6d0d37dd9f1be6bcbc0"
2187 + dependencies:
2188 + rc "^1.1.0"
2189 + shellsubstitute "^1.1.0"
2190 + untildify "^2.1.0"
2191 +
2192 +npmlog@^2.0.0, "npmlog@0 || 1 || 2":
2193 + version "2.0.4"
2194 + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692"
2195 + dependencies:
2196 + ansi "~0.3.1"
2197 + are-we-there-yet "~1.1.2"
2198 + gauge "~1.2.5"
2199 +
2200 +"npmlog@0 || 1 || 2 || 3":
2201 + version "3.1.2"
2202 + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-3.1.2.tgz#2d46fa874337af9498a2f12bb43d8d0be4a36873"
2203 + dependencies:
2204 + are-we-there-yet "~1.1.2"
2205 + console-control-strings "~1.1.0"
2206 + gauge "~2.6.0"
2207 + set-blocking "~2.0.0"
2208 +
2209 +npmlog@4.x:
2210 + version "4.0.0"
2211 + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.0.tgz#e094503961c70c1774eb76692080e8d578a9f88f"
2212 + dependencies:
2213 + are-we-there-yet "~1.1.2"
2214 + console-control-strings "~1.1.0"
2215 + gauge "~2.6.0"
2216 + set-blocking "~2.0.0"
2217 +
2218 +number-is-nan@^1.0.0:
2219 + version "1.0.1"
2220 + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
2221 +
2222 +oauth-sign@~0.8.1:
2223 + version "0.8.2"
2224 + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
2225 +
2226 +object-assign@^4.0.1, object-assign@^4.1.0:
2227 + version "4.1.0"
2228 + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0"
2229 +
2230 +object.omit@^2.0.0:
2231 + version "2.0.0"
2232 + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.0.tgz#868597333d54e60662940bb458605dd6ae12fe94"
2233 + dependencies:
2234 + for-own "^0.1.3"
2235 + is-extendable "^0.1.1"
2236 +
2237 +observ-debounce@^1.1.1:
2238 + version "1.1.1"
2239 + resolved "https://registry.yarnpkg.com/observ-debounce/-/observ-debounce-1.1.1.tgz#304e97c85adda70ecd7f08da450678ef90f0b707"
2240 + dependencies:
2241 + observ "~0.2.0"
2242 +
2243 +observ@~0.2.0:
2244 + version "0.2.0"
2245 + resolved "https://registry.yarnpkg.com/observ/-/observ-0.2.0.tgz#0bc39b3e29faa5f9e6caa5906cb8392df400aa68"
2246 +
2247 +observable@^2.1.4:
2248 + version "2.1.4"
2249 + resolved "https://registry.yarnpkg.com/observable/-/observable-2.1.4.tgz#a0f6bff42ec1e0a069874a9b0c3d15f4cef43a34"
2250 +
2251 +on-change-network@0.0.2:
2252 + version "0.0.2"
2253 + resolved "https://registry.yarnpkg.com/on-change-network/-/on-change-network-0.0.2.tgz#d977249477f91726949d80e82346dab6ef45216b"
2254 +
2255 +on-wakeup@^1.0.0:
2256 + version "1.0.1"
2257 + resolved "https://registry.yarnpkg.com/on-wakeup/-/on-wakeup-1.0.1.tgz#00d79d987dde7c8117bee74bb4903f6f6dafa52b"
2258 +
2259 +once@^1.3.0, once@^1.3.1:
2260 + version "1.4.0"
2261 + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
2262 + dependencies:
2263 + wrappy "1"
2264 +
2265 +once@~1.3.0, once@~1.3.3:
2266 + version "1.3.3"
2267 + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20"
2268 + dependencies:
2269 + wrappy "1"
2270 +
2271 +onetime@^1.0.0:
2272 + version "1.1.0"
2273 + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
2274 +
2275 +open-external@^0.1.1:
2276 + version "0.1.1"
2277 + resolved "https://registry.yarnpkg.com/open-external/-/open-external-0.1.1.tgz#19fad3551841a774f063c371b39fb27175ca8d2e"
2278 +
2279 +options@>=0.0.5:
2280 + version "0.0.6"
2281 + resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f"
2282 +
2283 +os-browserify@~0.1.1:
2284 + version "0.1.2"
2285 + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.1.2.tgz#49ca0293e0b19590a5f5de10c7f265a617d8fe54"
2286 +
2287 +os-homedir@^1.0.0, os-homedir@^1.0.1:
2288 + version "1.0.2"
2289 + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
2290 +
2291 +os-tmpdir@^1.0.0:
2292 + version "1.0.2"
2293 + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
2294 +
2295 +osenv@~0.1.0, osenv@0:
2296 + version "0.1.3"
2297 + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.3.tgz#83cf05c6d6458fc4d5ac6362ea325d92f2754217"
2298 + dependencies:
2299 + os-homedir "^1.0.0"
2300 + os-tmpdir "^1.0.0"
2301 +
2302 +packet-stream-codec@^1.1.1:
2303 + version "1.1.1"
2304 + resolved "https://registry.yarnpkg.com/packet-stream-codec/-/packet-stream-codec-1.1.1.tgz#107dec850ad9d27a63310eb1470e82a7e90a1c58"
2305 + dependencies:
2306 + pull-reader "^1.2.4"
2307 + pull-through "^1.0.17"
2308 +
2309 +packet-stream@~2.0.0:
2310 + version "2.0.0"
2311 + resolved "https://registry.yarnpkg.com/packet-stream/-/packet-stream-2.0.0.tgz#6bfc7b2e478a341c64f902caa766d6c43dfa65d1"
2312 +
2313 +pako@~0.2.0:
2314 + version "0.2.9"
2315 + resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
2316 +
2317 +parents@^1.0.0, parents@^1.0.1:
2318 + version "1.0.1"
2319 + resolved "https://registry.yarnpkg.com/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751"
2320 + dependencies:
2321 + path-platform "~0.11.15"
2322 +
2323 +parse-asn1@^5.0.0:
2324 + version "5.0.0"
2325 + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.0.0.tgz#35060f6d5015d37628c770f4e091a0b5a278bc23"
2326 + dependencies:
2327 + asn1.js "^4.0.0"
2328 + browserify-aes "^1.0.0"
2329 + create-hash "^1.1.0"
2330 + evp_bytestokey "^1.0.0"
2331 + pbkdf2 "^3.0.3"
2332 +
2333 +parse-entities@^1.0.0:
2334 + version "1.1.0"
2335 + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.0.tgz#4bc58f35fdc8e65dded35a12f2e40223ca24a3f7"
2336 + dependencies:
2337 + character-entities "^1.0.0"
2338 + character-entities-legacy "^1.0.0"
2339 + character-reference-invalid "^1.0.0"
2340 + has "^1.0.1"
2341 + is-alphanumerical "^1.0.0"
2342 + is-decimal "^1.0.0"
2343 + is-hexadecimal "^1.0.0"
2344 +
2345 +parse-glob@^3.0.4:
2346 + version "3.0.4"
2347 + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
2348 + dependencies:
2349 + glob-base "^0.3.0"
2350 + is-dotfile "^1.0.0"
2351 + is-extglob "^1.0.0"
2352 + is-glob "^2.0.0"
2353 +
2354 +path-array@^1.0.0:
2355 + version "1.0.1"
2356 + resolved "https://registry.yarnpkg.com/path-array/-/path-array-1.0.1.tgz#7e2f0f35f07a2015122b868b7eac0eb2c4fec271"
2357 + dependencies:
2358 + array-index "^1.0.0"
2359 +
2360 +path-browserify@~0.0.0:
2361 + version "0.0.0"
2362 + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a"
2363 +
2364 +path-is-absolute@^1.0.0:
2365 + version "1.0.1"
2366 + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
2367 +
2368 +path-platform@~0.11.15:
2369 + version "0.11.15"
2370 + resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2"
2371 +
2372 +pbkdf2@^3.0.3:
2373 + version "3.0.9"
2374 + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.9.tgz#f2c4b25a600058b3c3773c086c37dbbee1ffe693"
2375 + dependencies:
2376 + create-hmac "^1.1.2"
2377 +
2378 +peaks.js@^0.4.7:
2379 + version "0.4.9"
2380 + resolved "https://registry.yarnpkg.com/peaks.js/-/peaks.js-0.4.9.tgz#65a7ab28d7ef4a7034d8e63d41eb778e3fe66f51"
2381 + dependencies:
2382 + eventemitter2 "~1.0.0"
2383 + konva "~1.0.0"
2384 + waveform-data "^1.5.2"
2385 +
2386 +pify@^2.0.0:
2387 + version "2.3.0"
2388 + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
2389 +
2390 +pinkie-promise@^2.0.0:
2391 + version "2.0.1"
2392 + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
2393 + dependencies:
2394 + pinkie "^2.0.0"
2395 +
2396 +pinkie@^2.0.0:
2397 + version "2.0.4"
2398 + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
2399 +
2400 +pkijs@^1.3.27:
2401 + version "1.3.27"
2402 + resolved "https://registry.yarnpkg.com/pkijs/-/pkijs-1.3.27.tgz#ae52fbdec9eb9bc58850e2900d31c92210c84d61"
2403 +
2404 +plur@^2.0.0:
2405 + version "2.1.2"
2406 + resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a"
2407 + dependencies:
2408 + irregular-plurals "^1.0.0"
2409 +
2410 +prebuild@^4.1.0, prebuild@^4.1.1:
2411 + version "4.3.0"
2412 + resolved "https://registry.yarnpkg.com/prebuild/-/prebuild-4.3.0.tgz#8af94be3e57e5f6e509f9348e91ad9252dfb4ee2"
2413 + dependencies:
2414 + async "^1.4.0"
2415 + execspawn "^1.0.1"
2416 + expand-template "^1.0.0"
2417 + ghreleases "^1.0.2"
2418 + github-from-package "0.0.0"
2419 + minimist "^1.1.2"
2420 + mkdirp "^0.5.1"
2421 + node-gyp "^3.0.3"
2422 + node-ninja "^1.0.1"
2423 + noop-logger "^0.1.0"
2424 + npmlog "^2.0.0"
2425 + os-homedir "^1.0.1"
2426 + pump "^1.0.0"
2427 + rc "^1.0.3"
2428 + simple-get "^1.4.2"
2429 + tar-fs "^1.7.0"
2430 + tar-stream "^1.2.1"
2431 + xtend "^4.0.1"
2432 +
2433 +preserve@^0.2.0:
2434 + version "0.2.0"
2435 + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
2436 +
2437 +private-box@^0.2.1:
2438 + version "0.2.1"
2439 + resolved "https://registry.yarnpkg.com/private-box/-/private-box-0.2.1.tgz#1df061afca5b3039c7feaadd0daf0f56f07e3ec0"
2440 + dependencies:
2441 + chloride "^2.2.1"
2442 +
2443 +private-box@~0.0.3:
2444 + version "0.0.3"
2445 + resolved "https://registry.yarnpkg.com/private-box/-/private-box-0.0.3.tgz#99fcd2448eae3aeb76d0a9e32f0c3c0adc8eed29"
2446 + dependencies:
2447 + chloride "^2.0.1"
2448 +
2449 +process-nextick-args@~1.0.6:
2450 + version "1.0.7"
2451 + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
2452 +
2453 +process@~0.11.0:
2454 + version "0.11.9"
2455 + resolved "https://registry.yarnpkg.com/process/-/process-0.11.9.tgz#7bd5ad21aa6253e7da8682264f1e11d11c0318c1"
2456 +
2457 +process@~0.5.1:
2458 + version "0.5.2"
2459 + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
2460 +
2461 +prr@~0.0.0:
2462 + version "0.0.0"
2463 + resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a"
2464 +
2465 +prr@~1.0.1:
2466 + version "1.0.1"
2467 + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
2468 +
2469 +public-encrypt@^4.0.0:
2470 + version "4.0.0"
2471 + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6"
2472 + dependencies:
2473 + bn.js "^4.1.0"
2474 + browserify-rsa "^4.0.0"
2475 + create-hash "^1.1.0"
2476 + parse-asn1 "^5.0.0"
2477 + randombytes "^2.0.1"
2478 +
2479 +pull-abortable@~4.0.0:
2480 + version "4.0.0"
2481 + resolved "https://registry.yarnpkg.com/pull-abortable/-/pull-abortable-4.0.0.tgz#7017a984c3b834de77bac38c10b776f22dfc1843"
2482 +
2483 +pull-box-stream@^1.0.9:
2484 + version "1.0.11"
2485 + resolved "https://registry.yarnpkg.com/pull-box-stream/-/pull-box-stream-1.0.11.tgz#e74f3de1907c05c9f26b1a5f9e74a078ad1e86d7"
2486 + dependencies:
2487 + chloride "^2.1.1"
2488 + increment-buffer "~1.0.0"
2489 + pull-reader "^1.2.5"
2490 + pull-stream "^3.2.3"
2491 + pull-through "^1.0.18"
2492 + split-buffer "~1.0.0"
2493 +
2494 +pull-cat@^1.1.10, pull-cat@^1.1.8, pull-cat@^1.1.9, "pull-cat@>=1.1 <2", pull-cat@~1.1.5:
2495 + version "1.1.11"
2496 + resolved "https://registry.yarnpkg.com/pull-cat/-/pull-cat-1.1.11.tgz#b642dd1255da376a706b6db4fa962f5fdb74c31b"
2497 +
2498 +pull-core@~1.0.0:
2499 + version "1.0.0"
2500 + resolved "https://registry.yarnpkg.com/pull-core/-/pull-core-1.0.0.tgz#e0eb93918dfa70963ed09e36f63daa15b76b38a4"
2501 +
2502 +pull-core@~1.1.0, pull-core@1:
2503 + version "1.1.0"
2504 + resolved "https://registry.yarnpkg.com/pull-core/-/pull-core-1.1.0.tgz#3d8127d6dac1475705c9800961f59d66c8046c8a"
2505 +
2506 +pull-defer@^0.2.2:
2507 + version "0.2.2"
2508 + resolved "https://registry.yarnpkg.com/pull-defer/-/pull-defer-0.2.2.tgz#0887b0ffb30af32a56dbecfa72c1672271f07b13"
2509 +
2510 +pull-file@^0.5.0:
2511 + version "0.5.0"
2512 + resolved "https://registry.yarnpkg.com/pull-file/-/pull-file-0.5.0.tgz#b3ca405306e082f9d4528288933badb2b656365b"
2513 + dependencies:
2514 + pull-utf8-decoder "^1.0.2"
2515 +
2516 +pull-fs@~1.1.6:
2517 + version "1.1.6"
2518 + resolved "https://registry.yarnpkg.com/pull-fs/-/pull-fs-1.1.6.tgz#f184f6a7728bb4d95641376bead69f6f66df47cd"
2519 + dependencies:
2520 + pull-file "^0.5.0"
2521 + pull-stream "^3.3.0"
2522 + pull-traverse "^1.0.3"
2523 + pull-write-file "^0.2.1"
2524 +
2525 +pull-glob@~1.0.6:
2526 + version "1.0.6"
2527 + resolved "https://registry.yarnpkg.com/pull-glob/-/pull-glob-1.0.6.tgz#dea5ac5948ee15978dab24d777202927f68ae8a6"
2528 + dependencies:
2529 + pull-fs "~1.1.6"
2530 + pull-stream "^3.3.0"
2531 +
2532 +pull-goodbye@~0.0.1:
2533 + version "0.0.1"
2534 + resolved "https://registry.yarnpkg.com/pull-goodbye/-/pull-goodbye-0.0.1.tgz#4d9371ef0e22dce32000ea949c922f2f9f8f69ea"
2535 +
2536 +pull-handshake@^1.1.1:
2537 + version "1.1.4"
2538 + resolved "https://registry.yarnpkg.com/pull-handshake/-/pull-handshake-1.1.4.tgz#6000a0fd018884cdfd737254f8cc60ab2a637791"
2539 + dependencies:
2540 + pull-cat "^1.1.9"
2541 + pull-pair "~1.1.0"
2542 + pull-pushable "^2.0.0"
2543 + pull-reader "^1.2.3"
2544 +
2545 +pull-inactivity@~2.1.1:
2546 + version "2.1.1"
2547 + resolved "https://registry.yarnpkg.com/pull-inactivity/-/pull-inactivity-2.1.1.tgz#68ed39b24568f953ae6feb9e22cfa3c8eef6dfbe"
2548 + dependencies:
2549 + pull-abortable "~4.0.0"
2550 + pull-stream "~2.26.0"
2551 +
2552 +pull-level@^1.4.1, pull-level@^1.5.2:
2553 + version "1.5.2"
2554 + resolved "https://registry.yarnpkg.com/pull-level/-/pull-level-1.5.2.tgz#2b4bdc8eab8d4f2e3708b49512350b14bb035b56"
2555 + dependencies:
2556 + level-post "~1.0.3"
2557 + pull-cat "^1.1.9"
2558 + pull-pushable "^2.0.0"
2559 + pull-stream "^3.4.0"
2560 + pull-window "^2.1.4"
2561 + stream-to-pull-stream "^1.6.6"
2562 +
2563 +pull-level@^2.0.2, pull-level@^2.0.3:
2564 + version "2.0.3"
2565 + resolved "https://registry.yarnpkg.com/pull-level/-/pull-level-2.0.3.tgz#9500635e257945d6feede185f5d7a24773455b17"
2566 + dependencies:
2567 + level-post "~1.0.3"
2568 + pull-cat "^1.1.9"
2569 + pull-live "^1.0.1"
2570 + pull-pushable "^2.0.0"
2571 + pull-stream "^3.4.0"
2572 + pull-window "^2.1.4"
2573 + stream-to-pull-stream "^1.7.1"
2574 +
2575 +pull-level@~1.2.0:
2576 + version "1.2.0"
2577 + resolved "https://registry.yarnpkg.com/pull-level/-/pull-level-1.2.0.tgz#53b32122650eb15d35b60e54321fba11cf5c6e66"
2578 + dependencies:
2579 + level-post "~1.0.3"
2580 + pull-cat ">=1.1 <2"
2581 + pull-pushable "1"
2582 + pull-stream ">=2.20 <3"
2583 + pull-window ">=2.1.2 <3"
2584 + stream-to-pull-stream "1.3"
2585 +
2586 +pull-live@^1.0.0, pull-live@^1.0.1:
2587 + version "1.0.1"
2588 + resolved "https://registry.yarnpkg.com/pull-live/-/pull-live-1.0.1.tgz#a4ecee01e330155e9124bbbcf4761f21b38f51f5"
2589 + dependencies:
2590 + pull-cat "^1.1.9"
2591 + pull-stream "^3.4.0"
2592 +
2593 +pull-many:
2594 + version "1.0.7"
2595 + resolved "https://registry.yarnpkg.com/pull-many/-/pull-many-1.0.7.tgz#6fbfaaf521f76c39d0adb7e7a13450603d3e79fd"
2596 + dependencies:
2597 + pull-stream "^3.4.5"
2598 +
2599 +pull-many@~1.0.6:
2600 + version "1.0.6"
2601 + resolved "https://registry.yarnpkg.com/pull-many/-/pull-many-1.0.6.tgz#2389d3385be17fb0b45bff59efe09a3a6c460bb4"
2602 + dependencies:
2603 + pull-stream "~2.27.0"
2604 +
2605 +pull-next:
2606 + version "0.0.1"
2607 + resolved "https://registry.yarnpkg.com/pull-next/-/pull-next-0.0.1.tgz#1b6048d036cfae66642fd61fbb506fda9536cf1f"
2608 +
2609 +pull-notify@^0.1.0:
2610 + version "0.1.1"
2611 + resolved "https://registry.yarnpkg.com/pull-notify/-/pull-notify-0.1.1.tgz#6f86ff95d270b89c3ebf255b6031b7032dc99cca"
2612 + dependencies:
2613 + pull-pushable "^2.0.0"
2614 +
2615 +pull-notify@0.0.0:
2616 + version "0.0.0"
2617 + resolved "https://registry.yarnpkg.com/pull-notify/-/pull-notify-0.0.0.tgz#cb68db63b800eace4c0a23c514b352e372fba8b3"
2618 + dependencies:
2619 + pull-pushable "~1.1.4"
2620 +
2621 +pull-notify@0.0.2:
2622 + version "0.0.2"
2623 + resolved "https://registry.yarnpkg.com/pull-notify/-/pull-notify-0.0.2.tgz#280bbba1a57683e22a38206b2989465f24051821"
2624 + dependencies:
2625 + pull-pushable "^2.0.0"
2626 +
2627 +pull-pair@^1.1.0, pull-pair@~1.1.0:
2628 + version "1.1.0"
2629 + resolved "https://registry.yarnpkg.com/pull-pair/-/pull-pair-1.1.0.tgz#7ee427263fdf4da825397ac0a05e1ab4b74bd76d"
2630 +
2631 +pull-paramap@^1.1.3, pull-paramap@^1.1.4, pull-paramap@^1.1.6:
2632 + version "1.2.0"
2633 + resolved "https://registry.yarnpkg.com/pull-paramap/-/pull-paramap-1.2.0.tgz#c96f83eb3e5ea7c964a78ff97d5ec5159c4ee258"
2634 +
2635 +pull-paramap@~1.1.1:
2636 + version "1.1.6"
2637 + resolved "https://registry.yarnpkg.com/pull-paramap/-/pull-paramap-1.1.6.tgz#a0532a57eb0c041230a625dc0cceaa55aa6e93fd"
2638 +
2639 +pull-pause@0.0.0:
2640 + version "0.0.0"
2641 + resolved "https://registry.yarnpkg.com/pull-pause/-/pull-pause-0.0.0.tgz#101a628d717e19dfbf9800e9dec8f25d30461969"
2642 +
2643 +pull-ping@^1.0.1:
2644 + version "1.0.1"
2645 + resolved "https://registry.yarnpkg.com/pull-ping/-/pull-ping-1.0.1.tgz#d28649bf1e39dc09d2d7ce943a3f02216000bd4b"
2646 + dependencies:
2647 + pull-pushable "^2.0.0"
2648 + pull-stream "^3.2.0"
2649 +
2650 +pull-pushable@^2.0.0:
2651 + version "2.0.1"
2652 + resolved "https://registry.yarnpkg.com/pull-pushable/-/pull-pushable-2.0.1.tgz#02bdca51a39cf585f483fbecde2fc9378076f212"
2653 +
2654 +pull-pushable@~1.1.4, pull-pushable@1:
2655 + version "1.1.4"
2656 + resolved "https://registry.yarnpkg.com/pull-pushable/-/pull-pushable-1.1.4.tgz#7664d6741f72687ef5c89f533b78682f3de9a20e"
2657 + dependencies:
2658 + pull-stream "~2.18.2"
2659 +
2660 +pull-reader@^1.2.2, pull-reader@^1.2.3, pull-reader@^1.2.4, pull-reader@^1.2.5:
2661 + version "1.2.8"
2662 + resolved "https://registry.yarnpkg.com/pull-reader/-/pull-reader-1.2.8.tgz#a673c837dae6bbace25fd0480fc6ab5583158463"
2663 +
2664 +pull-reconnect@^0.0.3:
2665 + version "0.0.3"
2666 + resolved "https://registry.yarnpkg.com/pull-reconnect/-/pull-reconnect-0.0.3.tgz#53dce9cd2f2b9b210e88895e19f2ffc67621dc9e"
2667 + dependencies:
2668 + pull-defer "^0.2.2"
2669 +
2670 +pull-scroll@^0.2.0:
2671 + version "0.2.2"
2672 + resolved "https://registry.yarnpkg.com/pull-scroll/-/pull-scroll-0.2.2.tgz#61425a6c97f5d94191ad21dbedabe5af33347d16"
2673 + dependencies:
2674 + hyperscript "^1.4.7"
2675 + is-visible "^2.0.1"
2676 + observable "^2.1.4"
2677 + pull-pause "0.0.0"
2678 + pull-stream "^3.0.1"
2679 + request-animation-loop "^0.1.0"
2680 +
2681 +pull-sink-through@0.0.0:
2682 + version "0.0.0"
2683 + resolved "https://registry.yarnpkg.com/pull-sink-through/-/pull-sink-through-0.0.0.tgz#d3c0492f3a80b4ed204af67c4b4f935680fc5b1f"
2684 +
2685 +pull-stream, pull-stream@^3.0.0, pull-stream@^3.0.1, pull-stream@^3.1.0, pull-stream@^3.2.0, pull-stream@^3.2.3, pull-stream@^3.3.0, pull-stream@^3.4.0, pull-stream@^3.4.2, pull-stream@^3.4.3, pull-stream@^3.4.5:
2686 + version "3.4.5"
2687 + resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-3.4.5.tgz#dab04df30f28d1da8db0f236805f25436b01ba72"
2688 +
2689 +pull-stream-to-stream@~1.2.4:
2690 + version "1.2.6"
2691 + resolved "https://registry.yarnpkg.com/pull-stream-to-stream/-/pull-stream-to-stream-1.2.6.tgz#dd9fa3732edb3d16e67cd1f224bca38a6d5748c7"
2692 + dependencies:
2693 + pull-core "1"
2694 +
2695 +pull-stream-to-stream@~1.3.0:
2696 + version "1.3.3"
2697 + resolved "https://registry.yarnpkg.com/pull-stream-to-stream/-/pull-stream-to-stream-1.3.3.tgz#f283f5b63c39a1e49d334e3c81d2c15ce851e9b4"
2698 +
2699 +pull-stream@^2.28.3, "pull-stream@>=2.20 <3":
2700 + version "2.28.4"
2701 + resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-2.28.4.tgz#7ea97413c1619c20bc3bdf9e10e91347b03253e4"
2702 + dependencies:
2703 + pull-core "~1.1.0"
2704 +
2705 +pull-stream@~2.18.2:
2706 + version "2.18.3"
2707 + resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-2.18.3.tgz#7a07962234d7579c908860db8c27f7f34fd45000"
2708 + dependencies:
2709 + pull-core "~1.0.0"
2710 +
2711 +pull-stream@~2.21.0:
2712 + version "2.21.0"
2713 + resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-2.21.0.tgz#5b04e0bb35ffe64744fa9bb68465a84f9e1fe5d1"
2714 + dependencies:
2715 + pull-core "~1.0.0"
2716 +
2717 +pull-stream@~2.24.0:
2718 + version "2.24.1"
2719 + resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-2.24.1.tgz#30a3ba8f7eb73db80ed59e8236a4debfc6eb3c27"
2720 + dependencies:
2721 + pull-core "~1.0.0"
2722 +
2723 +pull-stream@~2.26.0:
2724 + version "2.26.1"
2725 + resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-2.26.1.tgz#4bf2559de87b8af2f5b96b7190d2ee431ca1e519"
2726 + dependencies:
2727 + pull-core "~1.1.0"
2728 +
2729 +pull-stream@~2.27.0:
2730 + version "2.27.0"
2731 + resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-2.27.0.tgz#fdf0eb910cdc4041d65956c00bee30dbbd00a068"
2732 + dependencies:
2733 + pull-core "~1.1.0"
2734 +
2735 +pull-stringify@~1.2.2:
2736 + version "1.2.2"
2737 + resolved "https://registry.yarnpkg.com/pull-stringify/-/pull-stringify-1.2.2.tgz#5a1c34e0075faf2f2f6d46004e36dccd33bd7c7c"
2738 +
2739 +pull-through@^1.0.17, pull-through@^1.0.18:
2740 + version "1.0.18"
2741 + resolved "https://registry.yarnpkg.com/pull-through/-/pull-through-1.0.18.tgz#8dd62314263e59cf5096eafbb127a2b6ef310735"
2742 + dependencies:
2743 + looper "~3.0.0"
2744 +
2745 +pull-traverse@^1.0.3:
2746 + version "1.0.3"
2747 + resolved "https://registry.yarnpkg.com/pull-traverse/-/pull-traverse-1.0.3.tgz#74fb5d7be7fa6bd7a78e97933e199b7945866938"
2748 +
2749 +pull-utf8-decoder@^1.0.2:
2750 + version "1.0.2"
2751 + resolved "https://registry.yarnpkg.com/pull-utf8-decoder/-/pull-utf8-decoder-1.0.2.tgz#a7afa2384d1e6415a5d602054126cc8de3bcbce7"
2752 +
2753 +pull-window@^2.1.4, "pull-window@>=2.1.2 <3":
2754 + version "2.1.4"
2755 + resolved "https://registry.yarnpkg.com/pull-window/-/pull-window-2.1.4.tgz#fc3b86feebd1920c7ae297691e23f705f88552f0"
2756 + dependencies:
2757 + looper "^2.0.0"
2758 +
2759 +pull-write-file@^0.2.1:
2760 + version "0.2.1"
2761 + resolved "https://registry.yarnpkg.com/pull-write-file/-/pull-write-file-0.2.1.tgz#8ee97b6824b6a56b0939aed5f370bf0e23c7b077"
2762 +
2763 +pull-write@^1.0.2, pull-write@^1.1.0:
2764 + version "1.1.0"
2765 + resolved "https://registry.yarnpkg.com/pull-write/-/pull-write-1.1.0.tgz#7c1d132ce9a2ef75102c2354fe5d7b107bb510b8"
2766 +
2767 +pull-ws@^3.2.2:
2768 + version "3.2.8"
2769 + resolved "https://registry.yarnpkg.com/pull-ws/-/pull-ws-3.2.8.tgz#0b3abebac15399e15d0db24cbedddc7dd8363f2e"
2770 + dependencies:
2771 + relative-url "^1.0.2"
2772 + ws "^1.1.0"
2773 +
2774 +pump@^1.0.0:
2775 + version "1.0.1"
2776 + resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.1.tgz#f1f1409fb9bd1085bbdb576b43b84ec4b5eadc1a"
2777 + dependencies:
2778 + end-of-stream "^1.1.0"
2779 + once "^1.3.1"
2780 +
2781 +punycode@^1.3.2:
2782 + version "1.4.1"
2783 + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
2784 +
2785 +punycode@1.3.2:
2786 + version "1.3.2"
2787 + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
2788 +
2789 +pyconf@^1.1.2:
2790 + version "1.1.2"
2791 + resolved "https://registry.yarnpkg.com/pyconf/-/pyconf-1.1.2.tgz#61a7aa299ff6ee57b8c687ad355a55d2e7a86a6b"
2792 + dependencies:
2793 + safe-replace "^1.0.2"
2794 +
2795 +qs@~6.2.0:
2796 + version "6.2.1"
2797 + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.1.tgz#ce03c5ff0935bc1d9d69a9f14cbd18e568d67625"
2798 +
2799 +querystring-es3@~0.2.0:
2800 + version "0.2.1"
2801 + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
2802 +
2803 +querystring@0.2.0:
2804 + version "0.2.0"
2805 + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
2806 +
2807 +randomatic@^1.1.3:
2808 + version "1.1.5"
2809 + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.5.tgz#5e9ef5f2d573c67bd2b8124ae90b5156e457840b"
2810 + dependencies:
2811 + is-number "^2.0.2"
2812 + kind-of "^3.0.2"
2813 +
2814 +randombytes@^2.0.0, randombytes@^2.0.1:
2815 + version "2.0.3"
2816 + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.3.tgz#674c99760901c3c4112771a31e521dc349cc09ec"
2817 +
2818 +rc@^1.0.3, rc@^1.1.0, rc@^1.1.6, rc@~1.1.0:
2819 + version "1.1.6"
2820 + resolved "https://registry.yarnpkg.com/rc/-/rc-1.1.6.tgz#43651b76b6ae53b5c802f1151fa3fc3b059969c9"
2821 + dependencies:
2822 + deep-extend "~0.4.0"
2823 + ini "~1.3.0"
2824 + minimist "^1.2.0"
2825 + strip-json-comments "~1.0.4"
2826 +
2827 +rc@~0.5.4:
2828 + version "0.5.5"
2829 + resolved "https://registry.yarnpkg.com/rc/-/rc-0.5.5.tgz#541cc3300f464b6dfe6432d756f0f2dd3e9eb199"
2830 + dependencies:
2831 + deep-extend "~0.2.5"
2832 + ini "~1.3.0"
2833 + minimist "~0.0.7"
2834 + strip-json-comments "0.1.x"
2835 +
2836 +read-only-stream@^2.0.0:
2837 + version "2.0.0"
2838 + resolved "https://registry.yarnpkg.com/read-only-stream/-/read-only-stream-2.0.0.tgz#2724fd6a8113d73764ac288d4386270c1dbf17f0"
2839 + dependencies:
2840 + readable-stream "^2.0.2"
2841 +
2842 +readable-stream@^1.0.33, readable-stream@~1.1.9:
2843 + version "1.1.14"
2844 + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
2845 + dependencies:
2846 + core-util-is "~1.0.0"
2847 + inherits "~2.0.1"
2848 + isarray "0.0.1"
2849 + string_decoder "~0.10.x"
2850 +
2851 +readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2, readable-stream@^2.1.0, readable-stream@~2.1.4:
2852 + version "2.1.5"
2853 + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0"
2854 + dependencies:
2855 + buffer-shims "^1.0.0"
2856 + core-util-is "~1.0.0"
2857 + inherits "~2.0.1"
2858 + isarray "~1.0.0"
2859 + process-nextick-args "~1.0.6"
2860 + string_decoder "~0.10.x"
2861 + util-deprecate "~1.0.1"
2862 +
2863 +"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.26:
2864 + version "1.0.34"
2865 + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
2866 + dependencies:
2867 + core-util-is "~1.0.0"
2868 + inherits "~2.0.1"
2869 + isarray "0.0.1"
2870 + string_decoder "~0.10.x"
2871 +
2872 +readable-stream@~2.0.0, readable-stream@~2.0.5:
2873 + version "2.0.6"
2874 + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
2875 + dependencies:
2876 + core-util-is "~1.0.0"
2877 + inherits "~2.0.1"
2878 + isarray "~1.0.0"
2879 + process-nextick-args "~1.0.6"
2880 + string_decoder "~0.10.x"
2881 + util-deprecate "~1.0.1"
2882 +
2883 +readdirp@^2.0.0:
2884 + version "2.1.0"
2885 + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
2886 + dependencies:
2887 + graceful-fs "^4.1.2"
2888 + minimatch "^3.0.2"
2889 + readable-stream "^2.0.2"
2890 + set-immediate-shim "^1.0.1"
2891 +
2892 +regex-cache@^0.4.2:
2893 + version "0.4.3"
2894 + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145"
2895 + dependencies:
2896 + is-equal-shallow "^0.1.3"
2897 + is-primitive "^2.0.0"
2898 +
2899 +relative-url@^1.0.2:
2900 + version "1.0.2"
2901 + resolved "https://registry.yarnpkg.com/relative-url/-/relative-url-1.0.2.tgz#d21c52a72d6061018bcee9f9c9fc106bf7d65287"
2902 +
2903 +remark-html@^2.0.2:
2904 + version "2.0.2"
2905 + resolved "https://registry.yarnpkg.com/remark-html/-/remark-html-2.0.2.tgz#592a347bdd3d5881f4f080c98b5b152fb1407a92"
2906 + dependencies:
2907 + collapse-white-space "^1.0.0"
2908 + detab "^1.0.0"
2909 + normalize-uri "^1.0.0"
2910 + object-assign "^4.0.1"
2911 + trim "0.0.1"
2912 + trim-lines "^1.0.0"
2913 + unist-util-visit "^1.0.0"
2914 +
2915 +remark@^3.2.2:
2916 + version "3.2.3"
2917 + resolved "https://registry.yarnpkg.com/remark/-/remark-3.2.3.tgz#802a38c3aa98c9e1e3ea015eeba211d27cb65e1f"
2918 + dependencies:
2919 + camelcase "^2.0.0"
2920 + ccount "^1.0.0"
2921 + chalk "^1.0.0"
2922 + chokidar "^1.0.5"
2923 + collapse-white-space "^1.0.0"
2924 + commander "^2.0.0"
2925 + concat-stream "^1.0.0"
2926 + debug "^2.0.0"
2927 + elegant-spinner "^1.0.0"
2928 + extend.js "0.0.2"
2929 + glob "^6.0.1"
2930 + globby "^4.0.0"
2931 + he "^0.5.0"
2932 + log-update "^1.0.1"
2933 + longest-streak "^1.0.0"
2934 + markdown-table "^0.4.0"
2935 + minimatch "^3.0.0"
2936 + npm-prefix "^1.0.1"
2937 + parse-entities "^1.0.0"
2938 + repeat-string "^1.5.0"
2939 + stringify-entities "^1.0.0"
2940 + to-vfile "^1.0.0"
2941 + trim "^0.0.1"
2942 + trim-trailing-lines "^1.0.0"
2943 + unified "^2.0.0"
2944 + user-home "^2.0.0"
2945 + vfile "^1.1.0"
2946 + vfile-find-down "^1.0.0"
2947 + vfile-find-up "^1.0.0"
2948 + vfile-reporter "^1.5.0"
2949 + ware "^1.3.0"
2950 +
2951 +repeat-element@^1.1.2:
2952 + version "1.1.2"
2953 + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
2954 +
2955 +repeat-string@^1.5.0, repeat-string@^1.5.2:
2956 + version "1.5.4"
2957 + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.5.4.tgz#64ec0c91e0f4b475f90d5b643651e3e6e5b6c2d5"
2958 +
2959 +request-animation-loop@^0.1.0:
2960 + version "0.1.0"
2961 + resolved "https://registry.yarnpkg.com/request-animation-loop/-/request-animation-loop-0.1.0.tgz#d320c6465d0a4c318b30b598ed1ff9cf84d22b9b"
2962 +
2963 +request@^2.55.0, request@^2.67.0, request@2, request@2.x:
2964 + version "2.75.0"
2965 + resolved "https://registry.yarnpkg.com/request/-/request-2.75.0.tgz#d2b8268a286da13eaa5d01adf5d18cc90f657d93"
2966 + dependencies:
2967 + aws-sign2 "~0.6.0"
2968 + aws4 "^1.2.1"
2969 + bl "~1.1.2"
2970 + caseless "~0.11.0"
2971 + combined-stream "~1.0.5"
2972 + extend "~3.0.0"
2973 + forever-agent "~0.6.1"
2974 + form-data "~2.0.0"
2975 + har-validator "~2.0.6"
2976 + hawk "~3.1.3"
2977 + http-signature "~1.1.0"
2978 + is-typedarray "~1.0.0"
2979 + isstream "~0.1.2"
2980 + json-stringify-safe "~5.0.1"
2981 + mime-types "~2.1.7"
2982 + node-uuid "~1.4.7"
2983 + oauth-sign "~0.8.1"
2984 + qs "~6.2.0"
2985 + stringstream "~0.0.4"
2986 + tough-cookie "~2.3.0"
2987 + tunnel-agent "~0.4.1"
2988 +
2989 +resolve@^1.1.3, resolve@^1.1.4, resolve@1.1.7:
2990 + version "1.1.7"
2991 + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
2992 +
2993 +restore-cursor@^1.0.1:
2994 + version "1.0.1"
2995 + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
2996 + dependencies:
2997 + exit-hook "^1.0.0"
2998 + onetime "^1.0.0"
2999 +
3000 +rimraf@^2.4.2, rimraf@~2.5.0, rimraf@~2.5.1, rimraf@2:
3001 + version "2.5.4"
3002 + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04"
3003 + dependencies:
3004 + glob "^7.0.5"
3005 +
3006 +rimraf@~2.2.8:
3007 + version "2.2.8"
3008 + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582"
3009 +
3010 +rimraf@~2.4.0:
3011 + version "2.4.5"
3012 + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da"
3013 + dependencies:
3014 + glob "^6.0.1"
3015 +
3016 +ripemd160@^1.0.0:
3017 + version "1.0.1"
3018 + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-1.0.1.tgz#93a4bbd4942bc574b69a8fa57c71de10ecca7d6e"
3019 +
3020 +rsa-compat@^1.2.1, rsa-compat@^1.2.3:
3021 + version "1.2.7"
3022 + resolved "https://registry.yarnpkg.com/rsa-compat/-/rsa-compat-1.2.7.tgz#7c4636de798885a9f3c90436ea3804e35b1684c8"
3023 + dependencies:
3024 + buffer-v6-polyfill "^1.0.3"
3025 + node-forge "^0.6.41"
3026 + optionalDependencies:
3027 + ursa "^0.9.4"
3028 +
3029 +safe-replace@^1.0.2:
3030 + version "1.0.2"
3031 + resolved "https://registry.yarnpkg.com/safe-replace/-/safe-replace-1.0.2.tgz#b181ab4095acdf6ab0a8f840517491ca8a9922ba"
3032 +
3033 +scuttlebot@^8.7.2:
3034 + version "8.7.2"
3035 + resolved "https://registry.yarnpkg.com/scuttlebot/-/scuttlebot-8.7.2.tgz#928afe842b525f3632d470f392104e46f2e8ed5f"
3036 + dependencies:
3037 + bash-color "~0.0.3"
3038 + broadcast-stream "~0.0.0"
3039 + cont "~1.0.3"
3040 + explain-error "~1.0.1"
3041 + graphmitter "^1.6.3"
3042 + ip "^0.3.3"
3043 + level-memview "~0.0.0"
3044 + map-merge "~1.1.0"
3045 + mdmanifest "^1.0.4"
3046 + minimist "^1.1.3"
3047 + mkdirp "~0.5.0"
3048 + multiblob "^1.10.1"
3049 + multicb "^1.0.0"
3050 + muxrpc "^6.1.1"
3051 + muxrpc-validation "^2.0.0"
3052 + muxrpcli "^1.0.0"
3053 + mv "^2.1.1"
3054 + mynosql-query "~1.0.0"
3055 + nomnom "1.8.0"
3056 + non-private-ip "~1.1.0"
3057 + observ "~0.2.0"
3058 + observ-debounce "^1.1.1"
3059 + on-change-network "0.0.2"
3060 + on-wakeup "^1.0.0"
3061 + osenv "~0.1.0"
3062 + pull-abortable "~4.0.0"
3063 + pull-cat "~1.1.5"
3064 + pull-file "^0.5.0"
3065 + pull-inactivity "~2.1.1"
3066 + pull-level "^2.0.2"
3067 + pull-many "~1.0.6"
3068 + pull-notify "0.0.0"
3069 + pull-paramap "~1.1.1"
3070 + pull-ping "^1.0.1"
3071 + pull-pushable "^2.0.0"
3072 + pull-stream "^3.0.0"
3073 + pull-stream-to-stream "~1.3.0"
3074 + pull-stringify "~1.2.2"
3075 + rimraf "^2.4.2"
3076 + secret-stack "^2.5.0"
3077 + secure-scuttlebutt "^15.4.1"
3078 + ssb-blobs "^0.1.6"
3079 + ssb-client "^4.0.2"
3080 + ssb-config "^2.0.0"
3081 + ssb-feed "^2.2.0"
3082 + ssb-keys "^5.1.2"
3083 + ssb-msgs "~5.0.0"
3084 + ssb-ref "^2.3.2"
3085 + statistics "^2.0.1"
3086 + stream-to-pull-stream "^1.6.10"
3087 + zerr "^1.0.0"
3088 +
3089 +secret-handshake@^0.5.0:
3090 + version "0.5.0"
3091 + resolved "https://registry.yarnpkg.com/secret-handshake/-/secret-handshake-0.5.0.tgz#8ce49cd3235a2e1d9ad640d2e022b0b3b8a29995"
3092 + dependencies:
3093 + chloride "^2.0.1"
3094 + deep-equal "~1.0.0"
3095 + pull-box-stream "^1.0.9"
3096 + pull-cat "~1.1.5"
3097 + pull-defer "^0.2.2"
3098 + pull-handshake "^1.1.1"
3099 + pull-pair "^1.1.0"
3100 + pull-pushable "^2.0.0"
3101 + pull-reader "^1.2.2"
3102 + pull-stream "^3.2.0"
3103 + stream-to-pull-stream "^1.6.2"
3104 +
3105 +secret-handshake@^1.1.1:
3106 + version "1.1.1"
3107 + resolved "https://registry.yarnpkg.com/secret-handshake/-/secret-handshake-1.1.1.tgz#5036a826cdd99ce7fedacae4b92ebc8913e8fedb"
3108 + dependencies:
3109 + chloride "^2.0.1"
3110 + deep-equal "~1.0.0"
3111 + pull-box-stream "^1.0.9"
3112 + pull-handshake "^1.1.1"
3113 + pull-stream "^3.4.5"
3114 +
3115 +secret-stack@^2.5.0:
3116 + version "2.5.2"
3117 + resolved "https://registry.yarnpkg.com/secret-stack/-/secret-stack-2.5.2.tgz#af3256146e573c62da7f860e8f3e2f6d01da6b14"
3118 + dependencies:
3119 + hoox "0.0.1"
3120 + map-merge "^1.1.0"
3121 + muxrpc "^6.2.2"
3122 + non-private-ip "^1.3.0"
3123 + pull-inactivity "~2.1.1"
3124 + pull-stream "~2.27.0"
3125 + secret-handshake "^0.5.0"
3126 + stream-to-pull-stream "^1.6.1"
3127 +
3128 +secure-scuttlebutt@^15.4.1:
3129 + version "15.4.2"
3130 + resolved "https://registry.yarnpkg.com/secure-scuttlebutt/-/secure-scuttlebutt-15.4.2.tgz#f4c9684abd5a2ab33908ff6c2bc0cbfb2d75650f"
3131 + dependencies:
3132 + cont "~1.0.0"
3133 + deep-equal "~0.2.1"
3134 + explain-error "~1.0.1"
3135 + level "^1.4.0"
3136 + level-peek "^2.0.1"
3137 + level-sublevel "^6.6.0"
3138 + ltgt "~2.0.0"
3139 + monotonic-timestamp "~0.0.8"
3140 + pull-cat "~1.1.5"
3141 + pull-defer "^0.2.2"
3142 + pull-level "^2.0.3"
3143 + pull-live "^1.0.1"
3144 + pull-notify "^0.1.0"
3145 + pull-paramap "^1.1.6"
3146 + pull-stream "^3.4.0"
3147 + pull-write "^1.1.0"
3148 + ssb-feed "^2.2.0"
3149 + ssb-keys "^6.0.0"
3150 + ssb-msgs "^5.0.0"
3151 + ssb-ref "^2.0.0"
3152 + stream-to-pull-stream "^1.7.2"
3153 + typewiselite "^1.0.0"
3154 +
3155 +semver@~5.1.0:
3156 + version "5.1.1"
3157 + resolved "https://registry.yarnpkg.com/semver/-/semver-5.1.1.tgz#a3292a373e6f3e0798da0b20641b9a9c5bc47e19"
3158 +
3159 +semver@~5.3.0, "semver@2.x || 3.x || 4 || 5":
3160 + version "5.3.0"
3161 + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
3162 +
3163 +separator-escape@0.0.0:
3164 + version "0.0.0"
3165 + resolved "https://registry.yarnpkg.com/separator-escape/-/separator-escape-0.0.0.tgz#e433676932020454e3c14870c517ea1de56c2fa4"
3166 +
3167 +set-blocking@~2.0.0:
3168 + version "2.0.0"
3169 + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
3170 +
3171 +set-immediate-shim@^1.0.1:
3172 + version "1.0.1"
3173 + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
3174 +
3175 +sha.js@^2.3.6, sha.js@^2.4.4, sha.js@^2.4.5, sha.js@~2.4.4:
3176 + version "2.4.5"
3177 + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.5.tgz#27d171efcc82a118b99639ff581660242b506e7c"
3178 + dependencies:
3179 + inherits "^2.0.1"
3180 +
3181 +shasum@^1.0.0:
3182 + version "1.0.2"
3183 + resolved "https://registry.yarnpkg.com/shasum/-/shasum-1.0.2.tgz#e7012310d8f417f4deb5712150e5678b87ae565f"
3184 + dependencies:
3185 + json-stable-stringify "~0.0.0"
3186 + sha.js "~2.4.4"
3187 +
3188 +shell-quote@^1.4.3:
3189 + version "1.6.1"
3190 + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767"
3191 + dependencies:
3192 + array-filter "~0.0.0"
3193 + array-map "~0.0.0"
3194 + array-reduce "~0.0.0"
3195 + jsonify "~0.0.0"
3196 +
3197 +shellsubstitute@^1.1.0:
3198 + version "1.1.0"
3199 + resolved "https://registry.yarnpkg.com/shellsubstitute/-/shellsubstitute-1.1.0.tgz#970b2459c5af53deb34284f15a4af95f50911c69"
3200 +
3201 +signal-exit@^3.0.0:
3202 + version "3.0.1"
3203 + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.1.tgz#5a4c884992b63a7acd9badb7894c3ee9cfccad81"
3204 +
3205 +simple-get@^1.4.2:
3206 + version "1.4.3"
3207 + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-1.4.3.tgz#e9755eda407e96da40c5e5158c9ea37b33becbeb"
3208 + dependencies:
3209 + once "^1.3.1"
3210 + unzip-response "^1.0.0"
3211 + xtend "^4.0.0"
3212 +
3213 +simple-mime@^0.1.0, simple-mime@~0.1.0:
3214 + version "0.1.0"
3215 + resolved "https://registry.yarnpkg.com/simple-mime/-/simple-mime-0.1.0.tgz#95f517c4f466d7cff561a71fc9dab2596ea9ef2e"
3216 +
3217 +smart-buffer@^1.0.4:
3218 + version "1.0.11"
3219 + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-1.0.11.tgz#3050337098a8e4cdf0350fef63dd146049ff940a"
3220 +
3221 +sntp@1.x.x:
3222 + version "1.0.9"
3223 + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
3224 + dependencies:
3225 + hoek "2.x.x"
3226 +
3227 +socks@1.1.9:
3228 + version "1.1.9"
3229 + resolved "https://registry.yarnpkg.com/socks/-/socks-1.1.9.tgz#628d7e4d04912435445ac0b6e459376cb3e6d691"
3230 + dependencies:
3231 + ip "^1.1.2"
3232 + smart-buffer "^1.0.4"
3233 +
3234 +sodium-browserify-tweetnacl@^0.2.0:
3235 + version "0.2.1"
3236 + resolved "https://registry.yarnpkg.com/sodium-browserify-tweetnacl/-/sodium-browserify-tweetnacl-0.2.1.tgz#afe42a6796820da69b7c29e8c8f5907b7c8c67a8"
3237 + dependencies:
3238 + chloride-test "^1.1.0"
3239 + ed2curve "^0.1.4"
3240 + sha.js "^2.4.5"
3241 + tweetnacl "^0.14.1"
3242 + tweetnacl-auth "^0.3.0"
3243 +
3244 +sodium-browserify@^1.0.3:
3245 + version "1.2.0"
3246 + resolved "https://registry.yarnpkg.com/sodium-browserify/-/sodium-browserify-1.2.0.tgz#39f2330bd3ddfc34595b7c9ce7c96112baa1bc21"
3247 + dependencies:
3248 + libsodium-wrappers "^0.2.9"
3249 + sha.js "^2.4.4"
3250 + tweetnacl "^0.14.1"
3251 +
3252 +sodium-prebuilt@1.0.22:
3253 + version "1.0.22"
3254 + resolved "https://registry.yarnpkg.com/sodium-prebuilt/-/sodium-prebuilt-1.0.22.tgz#f4c806f1e69b0b20c557959aeb3afb9defd53f46"
3255 + dependencies:
3256 + nan "^2.0.9"
3257 + prebuild "^4.1.0"
3258 +
3259 +source-map@~0.5.3:
3260 + version "0.5.6"
3261 + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
3262 +
3263 +split-buffer@^1.0.0, split-buffer@~1.0.0:
3264 + version "1.0.0"
3265 + resolved "https://registry.yarnpkg.com/split-buffer/-/split-buffer-1.0.0.tgz#b7e8e0ab51345158b72c1f6dbef2406d51f1d027"
3266 +
3267 +ssb-avatar@^0.1.0:
3268 + version "0.1.0"
3269 + resolved "https://registry.yarnpkg.com/ssb-avatar/-/ssb-avatar-0.1.0.tgz#afaccba158667e74bf21501220ba895b6bd580b8"
3270 + dependencies:
3271 + pull-cat "^1.1.9"
3272 + pull-stream "^3.4.3"
3273 + ssb-msgs "^5.2.0"
3274 +
3275 +ssb-blobs, ssb-blobs@^0.1.6:
3276 + version "0.1.7"
3277 + resolved "https://registry.yarnpkg.com/ssb-blobs/-/ssb-blobs-0.1.7.tgz#36b4798716a06531fb75584081522fcb25ecb924"
3278 + dependencies:
3279 + cont "^1.0.3"
3280 + level "^1.4.0"
3281 + multiblob "^1.10.0"
3282 + pull-level "^1.5.2"
3283 + pull-notify "^0.1.0"
3284 + pull-stream "^3.3.0"
3285 + ssb-ref "^2.3.0"
3286 +
3287 +ssb-client@^4.0.2, ssb-client@^4.0.3:
3288 + version "4.3.0"
3289 + resolved "https://registry.yarnpkg.com/ssb-client/-/ssb-client-4.3.0.tgz#8db38001585b54cac57dc6ff214fb61a89758dce"
3290 + dependencies:
3291 + explain-error "^1.0.1"
3292 + multiserver "^1.7.0"
3293 + muxrpc "^6.3.3"
3294 + ssb-config "^2.0.0"
3295 + ssb-keys "^6.0.0"
3296 +
3297 +ssb-config@^2.0.0, ssb-config@^2.1.1:
3298 + version "2.2.0"
3299 + resolved "https://registry.yarnpkg.com/ssb-config/-/ssb-config-2.2.0.tgz#41cad038a8575af4062d3fd57d3b167be85b03bc"
3300 + dependencies:
3301 + deep-extend "^0.4.0"
3302 + non-private-ip "^1.2.1"
3303 + os-homedir "^1.0.1"
3304 + rc "^1.1.6"
3305 +
3306 +ssb-feed@^2.2.0, ssb-feed@^2.2.1:
3307 + version "2.2.1"
3308 + resolved "https://registry.yarnpkg.com/ssb-feed/-/ssb-feed-2.2.1.tgz#b3b0d79609ce81d880241e80a2e1b98fdc1d8898"
3309 + dependencies:
3310 + cont "~1.0.3"
3311 + monotonic-timestamp "~0.0.9"
3312 + pull-stream "^3.4.2"
3313 + ssb-keys "^6.0.0"
3314 + ssb-ref "^2.0.0"
3315 +
3316 +ssb-keys@^5.1.2:
3317 + version "5.1.2"
3318 + resolved "https://registry.yarnpkg.com/ssb-keys/-/ssb-keys-5.1.2.tgz#2b19c4b66a66b9a30c2ad18544277156adce560b"
3319 + dependencies:
3320 + blake2s "~1.0.0"
3321 + chloride "^2.0.1"
3322 + deep-equal "~0.2.1"
3323 + hmac "~1.0.1"
3324 + mkdirp "~0.5.0"
3325 + private-box "~0.0.3"
3326 + ssb-ref "^2.0.0"
3327 +
3328 +ssb-keys@^6.0.0, ssb-keys@^6.1.0:
3329 + version "6.1.2"
3330 + resolved "https://registry.yarnpkg.com/ssb-keys/-/ssb-keys-6.1.2.tgz#a56238e39c8553b19a4926626186c24058d0a0b1"
3331 + dependencies:
3332 + blake2s "~1.0.0"
3333 + chloride "^2.2.0"
3334 + deep-equal "~0.2.1"
3335 + hmac "~1.0.1"
3336 + mkdirp "~0.5.0"
3337 + private-box "^0.2.1"
3338 + ssb-ref "^2.0.0"
3339 +
3340 +ssb-links:
3341 + version "2.0.0"
3342 + resolved "https://registry.yarnpkg.com/ssb-links/-/ssb-links-2.0.0.tgz#28be5f9620d585abc92d8fdb617edab45ac371d0"
3343 + dependencies:
3344 + pull-stream "^3.1.0"
3345 + ssb-msgs "^5.2.0"
3346 + streamview-links "^2.0.0"
3347 +
3348 +ssb-markdown@^3.0.0:
3349 + version "3.0.0"
3350 + resolved "https://registry.yarnpkg.com/ssb-markdown/-/ssb-markdown-3.0.0.tgz#68cafa26ed17a0b7a933ad9fa53327f6c00c9c78"
3351 + dependencies:
3352 + emoji-named-characters "^1.0.2"
3353 + ssb-marked "^0.5.4"
3354 + ssb-msgs "^5.2.0"
3355 + ssb-ref "^2.3.0"
3356 +
3357 +ssb-marked@^0.5.4:
3358 + version "0.5.4"
3359 + resolved "https://registry.yarnpkg.com/ssb-marked/-/ssb-marked-0.5.4.tgz#e2f0a17854d968a41e707dee6161c783f907330f"
3360 +
3361 +ssb-mentions@^0.1.0:
3362 + version "0.1.0"
3363 + resolved "https://registry.yarnpkg.com/ssb-mentions/-/ssb-mentions-0.1.0.tgz#cba7fe169fa089132f7db3db47e427b0a4870c23"
3364 + dependencies:
3365 + ssb-marked "^0.5.4"
3366 + ssb-ref "^2.3.0"
3367 +
3368 +ssb-msgs@^5.0.0, ssb-msgs@^5.2.0:
3369 + version "5.2.0"
3370 + resolved "https://registry.yarnpkg.com/ssb-msgs/-/ssb-msgs-5.2.0.tgz#c681da5cd70c574c922dca4f03c521538135c243"
3371 + dependencies:
3372 + ssb-ref "^2.0.0"
3373 +
3374 +ssb-msgs@~5.0.0:
3375 + version "5.0.0"
3376 + resolved "https://registry.yarnpkg.com/ssb-msgs/-/ssb-msgs-5.0.0.tgz#394829a67f2aa1b1232ff3aef89999cfacde1165"
3377 + dependencies:
3378 + ssb-ref "^2.0.0"
3379 +
3380 +ssb-query:
3381 + version "0.1.1"
3382 + resolved "https://registry.yarnpkg.com/ssb-query/-/ssb-query-0.1.1.tgz#f4ae4820ce7ed19d45f0e149d0df070dc1b1640c"
3383 + dependencies:
3384 + explain-error "^1.0.1"
3385 + pull-stream "^3.4.2"
3386 + streamview-links "^2.0.0"
3387 +
3388 +ssb-ref@^2.0.0, ssb-ref@^2.3.0, ssb-ref@^2.3.2:
3389 + version "2.6.2"
3390 + resolved "https://registry.yarnpkg.com/ssb-ref/-/ssb-ref-2.6.2.tgz#2aa19f1036854c7165f960fa6f962f12f0605277"
3391 + dependencies:
3392 + ip "^1.1.3"
3393 + is-valid-domain "~0.0.1"
3394 +
3395 +ssb-sort@^1.0.0:
3396 + version "1.0.0"
3397 + resolved "https://registry.yarnpkg.com/ssb-sort/-/ssb-sort-1.0.0.tgz#8e9956f50752d2b158247b06e49c3f491c1cd27b"
3398 + dependencies:
3399 + ssb-ref "^2.3.0"
3400 +
3401 +ssb-sort@0.0.0:
3402 + version "0.0.0"
3403 + resolved "https://registry.yarnpkg.com/ssb-sort/-/ssb-sort-0.0.0.tgz#384c2eb3fa48cc46c5f11d596bf686619fa8979f"
3404 + dependencies:
3405 + ssb-ref "^2.3.0"
3406 +
3407 +ssb-ws:
3408 + version "0.6.2"
3409 + resolved "https://registry.yarnpkg.com/ssb-ws/-/ssb-ws-0.6.2.tgz#ac84a3af2648f558db87a8882541b786ec3ffc7c"
3410 + dependencies:
3411 + multiblob-http "^0.2.0"
3412 + multiserver "^1.2.0"
3413 + muxrpc "^6.3.3"
3414 + pull-stream "^3.4.3"
3415 + ssb-ref "^2.3.0"
3416 + ssb-sort "0.0.0"
3417 + stack "^0.1.0"
3418 + web-bootloader "^0.1.0"
3419 + optionalDependencies:
3420 + letsencrypt-express "^1.1.5"
3421 +
3422 +sshpk@^1.7.0:
3423 + version "1.10.1"
3424 + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.10.1.tgz#30e1a5d329244974a1af61511339d595af6638b0"
3425 + dependencies:
3426 + asn1 "~0.2.3"
3427 + assert-plus "^1.0.0"
3428 + dashdash "^1.12.0"
3429 + getpass "^0.1.1"
3430 + optionalDependencies:
3431 + bcrypt-pbkdf "^1.0.0"
3432 + ecc-jsbn "~0.1.1"
3433 + jodid25519 "^1.0.0"
3434 + jsbn "~0.1.0"
3435 + tweetnacl "~0.14.0"
3436 +
3437 +stack@^0.1.0:
3438 + version "0.1.0"
3439 + resolved "https://registry.yarnpkg.com/stack/-/stack-0.1.0.tgz#e923598a9be51e617682cb21cf1b2818a449ada2"
3440 +
3441 +statistics@^2.0.1:
3442 + version "2.0.1"
3443 + resolved "https://registry.yarnpkg.com/statistics/-/statistics-2.0.1.tgz#cb8b101ad1e46189bd0c47f649d36a7e8e90ee52"
3444 +
3445 +stream-browserify@^2.0.0:
3446 + version "2.0.1"
3447 + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db"
3448 + dependencies:
3449 + inherits "~2.0.1"
3450 + readable-stream "^2.0.2"
3451 +
3452 +stream-combiner2@^1.1.1:
3453 + version "1.1.1"
3454 + resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe"
3455 + dependencies:
3456 + duplexer2 "~0.1.0"
3457 + readable-stream "^2.0.2"
3458 +
3459 +stream-http@^2.0.0:
3460 + version "2.4.0"
3461 + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.4.0.tgz#9599aa8e263667ce4190e0dc04a1d065d3595a7e"
3462 + dependencies:
3463 + builtin-status-codes "^2.0.0"
3464 + inherits "^2.0.1"
3465 + readable-stream "^2.1.0"
3466 + to-arraybuffer "^1.0.0"
3467 + xtend "^4.0.0"
3468 +
3469 +stream-splicer@^2.0.0:
3470 + version "2.0.0"
3471 + resolved "https://registry.yarnpkg.com/stream-splicer/-/stream-splicer-2.0.0.tgz#1b63be438a133e4b671cc1935197600175910d83"
3472 + dependencies:
3473 + inherits "^2.0.1"
3474 + readable-stream "^2.0.2"
3475 +
3476 +stream-to-pull-stream@^1.6.1, stream-to-pull-stream@^1.6.10, stream-to-pull-stream@^1.6.2, stream-to-pull-stream@^1.6.6, stream-to-pull-stream@^1.7.0, stream-to-pull-stream@^1.7.1, stream-to-pull-stream@^1.7.2:
3477 + version "1.7.2"
3478 + resolved "https://registry.yarnpkg.com/stream-to-pull-stream/-/stream-to-pull-stream-1.7.2.tgz#757609ae1cebd33c7432d4afbe31ff78650b9dde"
3479 + dependencies:
3480 + looper "^3.0.0"
3481 + pull-stream "^3.2.3"
3482 +
3483 +stream-to-pull-stream@1.3:
3484 + version "1.3.1"
3485 + resolved "https://registry.yarnpkg.com/stream-to-pull-stream/-/stream-to-pull-stream-1.3.1.tgz#f5be9be0f1e94bb3d1ae668bff8e9251b85a6c6e"
3486 + dependencies:
3487 + pull-core "~1.0.0"
3488 +
3489 +streamview-links@^2.0.0:
3490 + version "2.1.1"
3491 + resolved "https://registry.yarnpkg.com/streamview-links/-/streamview-links-2.1.1.tgz#d9b75ac3b35a25fce7ed9304dc9811d3ba383ff1"
3492 + dependencies:
3493 + bytewise "^1.1.0"
3494 + explain-error "^1.0.1"
3495 + level "^1.4.0"
3496 + ltgt "^2.1.2"
3497 + map-filter-reduce "^3.0.2"
3498 + pull-level "^2.0.2"
3499 + pull-live "^1.0.1"
3500 + pull-paramap "^1.1.3"
3501 + pull-sink-through "0.0.0"
3502 + pull-stream "^3.4.0"
3503 + pull-write "^1.0.2"
3504 +
3505 +string_decoder@~0.10.0, string_decoder@~0.10.x:
3506 + version "0.10.31"
3507 + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
3508 +
3509 +string-width@^1.0.0, string-width@^1.0.1:
3510 + version "1.0.2"
3511 + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
3512 + dependencies:
3513 + code-point-at "^1.0.0"
3514 + is-fullwidth-code-point "^1.0.0"
3515 + strip-ansi "^3.0.0"
3516 +
3517 +stringify-entities@^1.0.0:
3518 + version "1.2.0"
3519 + resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-1.2.0.tgz#b53ab7fc33972cab0d7a1006a82f1318af4572e1"
3520 + dependencies:
3521 + character-entities-html4 "^1.0.0"
3522 + character-entities-legacy "^1.0.0"
3523 +
3524 +stringstream@~0.0.4:
3525 + version "0.0.5"
3526 + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
3527 +
3528 +strip-ansi@^3.0.0, strip-ansi@^3.0.1:
3529 + version "3.0.1"
3530 + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
3531 + dependencies:
3532 + ansi-regex "^2.0.0"
3533 +
3534 +strip-ansi@~0.1.0:
3535 + version "0.1.1"
3536 + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991"
3537 +
3538 +strip-json-comments@~1.0.4:
3539 + version "1.0.4"
3540 + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91"
3541 +
3542 +strip-json-comments@0.1.x:
3543 + version "0.1.3"
3544 + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-0.1.3.tgz#164c64e370a8a3cc00c9e01b539e569823f0ee54"
3545 +
3546 +style-properties@^1.3.1:
3547 + version "1.3.1"
3548 + resolved "https://registry.yarnpkg.com/style-properties/-/style-properties-1.3.1.tgz#7f8617421f2959157f08d09eecba8688a15854c5"
3549 +
3550 +subarg@^1.0.0:
3551 + version "1.0.0"
3552 + resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2"
3553 + dependencies:
3554 + minimist "^1.1.0"
3555 +
3556 +suggest-box@^2.2.1:
3557 + version "2.2.2"
3558 + resolved "https://registry.yarnpkg.com/suggest-box/-/suggest-box-2.2.2.tgz#2182293a6b86d91109fef9643d2cb3cb6ca557ef"
3559 + dependencies:
3560 + hyperscript "~1.4.2"
3561 + textarea-caret-position "^0.1.1"
3562 +
3563 +supports-color@^2.0.0:
3564 + version "2.0.0"
3565 + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
3566 +
3567 +syntax-error@^1.1.1:
3568 + version "1.1.6"
3569 + resolved "https://registry.yarnpkg.com/syntax-error/-/syntax-error-1.1.6.tgz#b4549706d386cc1c1dc7c2423f18579b6cade710"
3570 + dependencies:
3571 + acorn "^2.7.0"
3572 +
3573 +tar-fs@^1.7.0:
3574 + version "1.13.2"
3575 + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.13.2.tgz#433e879f9538d7e1e883ba914904f339c6414835"
3576 + dependencies:
3577 + mkdirp "^0.5.0"
3578 + pump "^1.0.0"
3579 + tar-stream "^1.1.2"
3580 +
3581 +tar-pack@~3.1.0:
3582 + version "3.1.4"
3583 + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.1.4.tgz#bc8cf9a22f5832739f12f3910dac1eb97b49708c"
3584 + dependencies:
3585 + debug "~2.2.0"
3586 + fstream "~1.0.10"
3587 + fstream-ignore "~1.0.5"
3588 + once "~1.3.3"
3589 + readable-stream "~2.1.4"
3590 + rimraf "~2.5.1"
3591 + tar "~2.2.1"
3592 + uid-number "~0.0.6"
3593 +
3594 +tar-stream@^1.1.2, tar-stream@^1.2.1:
3595 + version "1.5.2"
3596 + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.2.tgz#fbc6c6e83c1a19d4cb48c7d96171fc248effc7bf"
3597 + dependencies:
3598 + bl "^1.0.0"
3599 + end-of-stream "^1.0.0"
3600 + readable-stream "^2.0.0"
3601 + xtend "^4.0.0"
3602 +
3603 +tar@^2.0.0, tar@~2.2.0, tar@~2.2.1:
3604 + version "2.2.1"
3605 + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
3606 + dependencies:
3607 + block-stream "*"
3608 + fstream "^1.0.2"
3609 + inherits "2"
3610 +
3611 +text-node-searcher@^1.1.0:
3612 + version "1.1.1"
3613 + resolved "https://registry.yarnpkg.com/text-node-searcher/-/text-node-searcher-1.1.1.tgz#dca6bd752564a215a6f5fded0f19089f16173f4a"
3614 +
3615 +text-table@^0.2.0:
3616 + version "0.2.0"
3617 + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
3618 +
3619 +textarea-caret-position@^0.1.1:
3620 + version "0.1.1"
3621 + resolved "https://registry.yarnpkg.com/textarea-caret-position/-/textarea-caret-position-0.1.1.tgz#34372aa755008b1a8451b8a1bb8f07795270fd70"
3622 +
3623 +"through@>=2.2.7 <3":
3624 + version "2.3.8"
3625 + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
3626 +
3627 +through2@^2.0.0:
3628 + version "2.0.1"
3629 + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.1.tgz#384e75314d49f32de12eebb8136b8eb6b5d59da9"
3630 + dependencies:
3631 + readable-stream "~2.0.0"
3632 + xtend "~4.0.0"
3633 +
3634 +through2@~0.6.3:
3635 + version "0.6.5"
3636 + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48"
3637 + dependencies:
3638 + readable-stream ">=1.0.33-1 <1.1.0-0"
3639 + xtend ">=4.0.0 <4.1.0-0"
3640 +
3641 +timers-browserify@^1.0.1:
3642 + version "1.4.2"
3643 + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d"
3644 + dependencies:
3645 + process "~0.11.0"
3646 +
3647 +to-arraybuffer@^1.0.0:
3648 + version "1.0.1"
3649 + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
3650 +
3651 +to-utf8@0.0.1:
3652 + version "0.0.1"
3653 + resolved "https://registry.yarnpkg.com/to-utf8/-/to-utf8-0.0.1.tgz#d17aea72ff2fba39b9e43601be7b3ff72e089852"
3654 +
3655 +to-vfile@^1.0.0:
3656 + version "1.0.0"
3657 + resolved "https://registry.yarnpkg.com/to-vfile/-/to-vfile-1.0.0.tgz#88defecd43adb2ef598625f0e3d59f7f342941ba"
3658 + dependencies:
3659 + vfile "^1.0.0"
3660 +
3661 +tough-cookie@~2.3.0:
3662 + version "2.3.1"
3663 + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.1.tgz#99c77dfbb7d804249e8a299d4cb0fd81fef083fd"
3664 +
3665 +trim-lines@^1.0.0:
3666 + version "1.0.0"
3667 + resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-1.0.0.tgz#c30caf5d15513443f44ce86e5cf338ec3b1fb25d"
3668 +
3669 +trim-trailing-lines@^1.0.0:
3670 + version "1.0.0"
3671 + resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.0.0.tgz#dbb638247a2232f669121c458fccd48fc2670c8e"
3672 +
3673 +trim@^0.0.1, trim@0.0.1:
3674 + version "0.0.1"
3675 + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd"
3676 +
3677 +tty-browserify@~0.0.0:
3678 + version "0.0.0"
3679 + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
3680 +
3681 +tunnel-agent@~0.4.1:
3682 + version "0.4.3"
3683 + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb"
3684 +
3685 +tweetnacl-auth@^0.3.0:
3686 + version "0.3.0"
3687 + resolved "https://registry.yarnpkg.com/tweetnacl-auth/-/tweetnacl-auth-0.3.0.tgz#c8303e192742ef8694fb913d18a93450a08491e8"
3688 + dependencies:
3689 + tweetnacl "0.x.x"
3690 +
3691 +tweetnacl@^0.14.1, tweetnacl@^0.14.3, tweetnacl@~0.14.0, tweetnacl@0.x.x:
3692 + version "0.14.3"
3693 + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.3.tgz#3da382f670f25ded78d7b3d1792119bca0b7132d"
3694 +
3695 +typedarray@~0.0.5:
3696 + version "0.0.6"
3697 + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
3698 +
3699 +typewise-core@^1.2, typewise-core@^1.2.0:
3700 + version "1.2.0"
3701 + resolved "https://registry.yarnpkg.com/typewise-core/-/typewise-core-1.2.0.tgz#97eb91805c7f55d2f941748fa50d315d991ef195"
3702 +
3703 +typewise@^1.0.3:
3704 + version "1.0.3"
3705 + resolved "https://registry.yarnpkg.com/typewise/-/typewise-1.0.3.tgz#1067936540af97937cc5dcf9922486e9fa284651"
3706 + dependencies:
3707 + typewise-core "^1.2.0"
3708 +
3709 +typewiselite@^1.0.0, typewiselite@~1.0.0:
3710 + version "1.0.0"
3711 + resolved "https://registry.yarnpkg.com/typewiselite/-/typewiselite-1.0.0.tgz#c8882fa1bb1092c06005a97f34ef5c8508e3664e"
3712 +
3713 +uid-number@~0.0.6:
3714 + version "0.0.6"
3715 + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
3716 +
3717 +ultron@1.0.x:
3718 + version "1.0.2"
3719 + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa"
3720 +
3721 +umd@^3.0.0:
3722 + version "3.0.1"
3723 + resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.1.tgz#8ae556e11011f63c2596708a8837259f01b3d60e"
3724 +
3725 +underscore@~1.6.0:
3726 + version "1.6.0"
3727 + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8"
3728 +
3729 +unherit@^1.0.0, unherit@^1.0.4:
3730 + version "1.1.0"
3731 + resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.0.tgz#6b9aaedfbf73df1756ad9e316dd981885840cd7d"
3732 + dependencies:
3733 + inherits "^2.0.1"
3734 + xtend "^4.0.1"
3735 +
3736 +unified@^2.0.0:
3737 + version "2.1.4"
3738 + resolved "https://registry.yarnpkg.com/unified/-/unified-2.1.4.tgz#14bc6cd40d98ffff75b405506bad873ecbbac3ba"
3739 + dependencies:
3740 + attach-ware "^1.0.0"
3741 + bail "^1.0.0"
3742 + extend "^3.0.0"
3743 + unherit "^1.0.4"
3744 + vfile "^1.0.0"
3745 + ware "^1.3.0"
3746 +
3747 +unist-util-visit@^1.0.0:
3748 + version "1.1.0"
3749 + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.1.0.tgz#2029869661db425ee082a82e2e02dd6cfc95db99"
3750 +
3751 +untildify@^2.1.0:
3752 + version "2.1.0"
3753 + resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0"
3754 + dependencies:
3755 + os-homedir "^1.0.0"
3756 +
3757 +unzip-response@^1.0.0:
3758 + version "1.0.1"
3759 + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.1.tgz#4a73959f2989470fa503791cefb54e1dbbc68412"
3760 +
3761 +url-template@~2.0.6:
3762 + version "2.0.8"
3763 + resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21"
3764 +
3765 +url@~0.11.0:
3766 + version "0.11.0"
3767 + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
3768 + dependencies:
3769 + punycode "1.3.2"
3770 + querystring "0.2.0"
3771 +
3772 +ursa@^0.9.1, ursa@^0.9.4:
3773 + version "0.9.4"
3774 + resolved "https://registry.yarnpkg.com/ursa/-/ursa-0.9.4.tgz#0a2abfb7dc4267f733b0f8f2fc7f2c895d40a413"
3775 + dependencies:
3776 + bindings "^1.2.1"
3777 + nan "^2.3.3"
3778 +
3779 +user-home@^2.0.0:
3780 + version "2.0.0"
3781 + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f"
3782 + dependencies:
3783 + os-homedir "^1.0.0"
3784 +
3785 +util-deprecate@~1.0.1:
3786 + version "1.0.2"
3787 + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
3788 +
3789 +util-extend@^1.0.1:
3790 + version "1.0.3"
3791 + resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f"
3792 +
3793 +util@~0.10.1, util@0.10.3:
3794 + version "0.10.3"
3795 + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
3796 + dependencies:
3797 + inherits "2.0.1"
3798 +
3799 +verror@1.3.6:
3800 + version "1.3.6"
3801 + resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c"
3802 + dependencies:
3803 + extsprintf "1.0.2"
3804 +
3805 +vfile-find-down@^1.0.0:
3806 + version "1.0.0"
3807 + resolved "https://registry.yarnpkg.com/vfile-find-down/-/vfile-find-down-1.0.0.tgz#84a4d66d03513f6140a84e0776ef0848d4f0ad95"
3808 + dependencies:
3809 + to-vfile "^1.0.0"
3810 +
3811 +vfile-find-up@^1.0.0:
3812 + version "1.0.0"
3813 + resolved "https://registry.yarnpkg.com/vfile-find-up/-/vfile-find-up-1.0.0.tgz#5604da6fe453b34350637984eb5fe4909e280390"
3814 + dependencies:
3815 + to-vfile "^1.0.0"
3816 +
3817 +vfile-reporter@^1.5.0:
3818 + version "1.5.0"
3819 + resolved "https://registry.yarnpkg.com/vfile-reporter/-/vfile-reporter-1.5.0.tgz#21a7009bfe55e24df8ff432aa5bf6f6efa74e418"
3820 + dependencies:
3821 + chalk "^1.1.0"
3822 + log-symbols "^1.0.2"
3823 + plur "^2.0.0"
3824 + repeat-string "^1.5.0"
3825 + string-width "^1.0.0"
3826 + text-table "^0.2.0"
3827 + vfile-sort "^1.0.0"
3828 +
3829 +vfile-sort@^1.0.0:
3830 + version "1.0.0"
3831 + resolved "https://registry.yarnpkg.com/vfile-sort/-/vfile-sort-1.0.0.tgz#17ee491ba43e8951bb22913fcff32a7dc4d234d4"
3832 +
3833 +vfile@^1.0.0, vfile@^1.1.0:
3834 + version "1.4.0"
3835 + resolved "https://registry.yarnpkg.com/vfile/-/vfile-1.4.0.tgz#c0fd6fa484f8debdb771f68c31ed75d88da97fe7"
3836 +
3837 +visualize-buffer@0.0.0:
3838 + version "0.0.0"
3839 + resolved "https://registry.yarnpkg.com/visualize-buffer/-/visualize-buffer-0.0.0.tgz#a68d399bb0a71dfd4c2a3498b822a8908d4b0a5b"
3840 +
3841 +vm-browserify@~0.0.1:
3842 + version "0.0.4"
3843 + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"
3844 + dependencies:
3845 + indexof "0.0.1"
3846 +
3847 +ware@^1.3.0:
3848 + version "1.3.0"
3849 + resolved "https://registry.yarnpkg.com/ware/-/ware-1.3.0.tgz#d1b14f39d2e2cb4ab8c4098f756fe4b164e473d4"
3850 + dependencies:
3851 + wrap-fn "^0.1.0"
3852 +
3853 +waveform-data@^1.5.2:
3854 + version "1.5.3"
3855 + resolved "https://registry.yarnpkg.com/waveform-data/-/waveform-data-1.5.3.tgz#074f0344ed14c2a1e8b9bf764df169ad80b23ead"
3856 + dependencies:
3857 + audio-context "^0.1.0"
3858 +
3859 +web-bootloader@^0.1.0:
3860 + version "0.1.2"
3861 + resolved "https://registry.yarnpkg.com/web-bootloader/-/web-bootloader-0.1.2.tgz#de18224ce986333ea988c38e376e8818f2902486"
3862 + dependencies:
3863 + arraybuffer-base64 "^1.0.0"
3864 + binary-xhr "0.0.2"
3865 + hyperfile "^1.1.1"
3866 + hyperprogress "^0.1.0"
3867 +
3868 +which@1:
3869 + version "1.2.11"
3870 + resolved "https://registry.yarnpkg.com/which/-/which-1.2.11.tgz#c8b2eeea6b8c1659fa7c1dd4fdaabe9533dc5e8b"
3871 + dependencies:
3872 + isexe "^1.1.1"
3873 +
3874 +wide-align@^1.1.0:
3875 + version "1.1.0"
3876 + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad"
3877 + dependencies:
3878 + string-width "^1.0.1"
3879 +
3880 +word-wrap@^1.1.0:
3881 + version "1.1.0"
3882 + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.1.0.tgz#356153d61d10610d600785c5d701288e0ae764a6"
3883 +
3884 +wrap-fn@^0.1.0:
3885 + version "0.1.5"
3886 + resolved "https://registry.yarnpkg.com/wrap-fn/-/wrap-fn-0.1.5.tgz#f21b6e41016ff4a7e31720dbc63a09016bdf9845"
3887 + dependencies:
3888 + co "3.1.0"
3889 +
3890 +wrappy@1:
3891 + version "1.0.2"
3892 + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
3893 +
3894 +ws@^1.1.0:
3895 + version "1.1.1"
3896 + resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.1.tgz#082ddb6c641e85d4bb451f03d52f06eabdb1f018"
3897 + dependencies:
3898 + options ">=0.0.5"
3899 + ultron "1.0.x"
3900 +
3901 +xtend@^4.0.0, xtend@^4.0.1, "xtend@>=4.0.0 <4.1.0-0", xtend@~4.0.0:
3902 + version "4.0.1"
3903 + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
3904 +
3905 +xtend@~3.0.0:
3906 + version "3.0.0"
3907 + resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a"
3908 +
3909 +zerr@^1.0.0, zerr@^1.0.1:
3910 + version "1.0.4"
3911 + resolved "https://registry.yarnpkg.com/zerr/-/zerr-1.0.4.tgz#62814dd799eff8361f2a228f41f705c5e19de4c9"
3912 +

Built with git-ssb-web