From 74699f64f8f78f3c0371aa1e1d2a918518130843 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Tue, 15 May 2018 11:02:18 -0700 Subject: [PATCH 01/11] debug mode print mem & peers --- lib/debug.js | 20 ++++++++++++++++++-- lib/evict.js | 27 +++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 lib/evict.js diff --git a/lib/debug.js b/lib/debug.js index c3562cd1..336b80b9 100644 --- a/lib/debug.js +++ b/lib/debug.js @@ -1,13 +1,29 @@ ;(function(){ if('debug' !== process.env.GUN_ENV){ return } + var db = {}; + console.log("start :)"); global.DEBUG = 1; setInterval(function(){ var mem = process.memoryUsage(); var used = mem.heapUsed / 1024 / 1024; + var print = ''; used = used.toFixed(1); - console.log(used, 'MB'); - }, 1000); + print += used +' MB. ' + if(db.root){ + db.concurrency = Object.keys(db.peers||{}).length; + print += db.concurrency +' peers. '; + } + console.log(print); + }, 2500); + + var Gun = require('../gun'); + Gun.on('opt', function(root){ + this.to.next(root); + if(root.once){ return } + db.root = root; + db.peers = root.opt.peers; + }) }()); \ No newline at end of file diff --git a/lib/evict.js b/lib/evict.js new file mode 100644 index 00000000..048a575a --- /dev/null +++ b/lib/evict.js @@ -0,0 +1,27 @@ +;(function(){ + var Gun = (typeof window !== 'undefined')? window.Gun : require('../gun'); + + var LRU = 1, empty = {}, u; + Gun.on('opt', function(root){ + this.to.next(root); + if(root.once){ return } + root.on('get', function(msg){ + + }) + /* + root.on('in', function(msg){ + this.to.next(msg); + if(msg.get){ + return; + } + Gun.graph.is(msg, function(node, soul){ + var meta = (root.next||empty)[soul]; + if(!meta){ return } + Gun.node.is(node, function(data, key){ + + }); + }); + }); + */ + }); +}()); \ No newline at end of file From 2015a01b6532ddbb534d1a6268c001beb4fe3a88 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Tue, 15 May 2018 22:31:42 -0700 Subject: [PATCH 02/11] experimental GC --- lib/debug.js | 12 +++++++++++- lib/evict.js | 27 +++++++++++++++++++++++---- lib/server.js | 1 + lib/store.js | 2 +- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/lib/debug.js b/lib/debug.js index 336b80b9..bd4f657d 100644 --- a/lib/debug.js +++ b/lib/debug.js @@ -7,14 +7,17 @@ global.DEBUG = 1; setInterval(function(){ var mem = process.memoryUsage(); - var used = mem.heapUsed / 1024 / 1024; + var used = mem.heapTotal / 1024 / 1024; var print = ''; used = used.toFixed(1); print += used +' MB. ' if(db.root){ db.concurrency = Object.keys(db.peers||{}).length; print += db.concurrency +' peers. '; + db.nodes = Object.keys(db.root.graph||{}).length; + print += db.nodes + ' nodes. '; } + if(db.count){ print += db.count + ' msgs. '} console.log(print); }, 2500); @@ -24,6 +27,13 @@ if(root.once){ return } db.root = root; db.peers = root.opt.peers; + + db.count = 0; + root.on('in', function(msg){ + this.to.next(msg); + db.last = msg; + db.count++; + }) }) }()); \ No newline at end of file diff --git a/lib/evict.js b/lib/evict.js index 048a575a..4f2b5817 100644 --- a/lib/evict.js +++ b/lib/evict.js @@ -1,13 +1,32 @@ ;(function(){ var Gun = (typeof window !== 'undefined')? window.Gun : require('../gun'); - var LRU = 1, empty = {}, u; + var ev = {}, empty = {}, u; Gun.on('opt', function(root){ this.to.next(root); if(root.once){ return } - root.on('get', function(msg){ - - }) + if(typeof process == 'undefined'){ return } + var util = process.memoryUsage; + if(!util){ return } + + ev.max = parseFloat(root.opt.memory || process.env.WEB_MEMORY || 512) * 0.8; + + setInterval(check, 250); + function check(){ + var used = ev.used = util().heapTotal / 1024 / 1024; + if(used < ev.max){ return } + setTimeout(GC, 1); + } + function GC(){ + var souls = Object.keys(root.graph||empty); + var toss = Math.ceil(souls.length * 0.1); + //var start = Gun.state(), i = toss; + Gun.list.map(souls, function(soul){ + if(--toss < 0){ return } + root.gun(soul).off(); + }); + //console.log("evicted", i, 'nodes in', ((Gun.state() - start)/1000).toFixed(2), 'sec.'); + } /* root.on('in', function(msg){ this.to.next(msg); diff --git a/lib/server.js b/lib/server.js index 5f6d6c68..f46972e5 100644 --- a/lib/server.js +++ b/lib/server.js @@ -9,6 +9,7 @@ require('./verify'); require('./file'); require('./bye'); + require('./evict'); if('debug' === process.env.GUN_ENV){ require('./debug') } module.exports = Gun; }()); \ No newline at end of file diff --git a/lib/store.js b/lib/store.js index 943e0ac0..359c8607 100644 --- a/lib/store.js +++ b/lib/store.js @@ -10,7 +10,7 @@ Gun.on('opt', function(ctx){ if(ctx.once){ return } if(false !== opt.localStorage && !process.env.AWS_S3_BUCKET){ return } // TODO: Remove this after migration. if(false === opt.radisk){ return } - console.log("BUG WARNING: Radix Storage Engine (RSE) has a known rare edge case, if data gets split between file chunks, a GET may only return the first chunk!!!"); + console.log("BUG WARNING: Radix Storage Engine (RAD) has a known rare edge case, if data gets split between file chunks, a GET may only return the first chunk!!!"); opt.store = opt.store || Store(opt); var rad = Radisk(opt); From 30ae1e739297bc585df08534d6ab3e81889effd1 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Tue, 15 May 2018 22:56:59 -0700 Subject: [PATCH 03/11] make debug available --- lib/debug.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/debug.js b/lib/debug.js index bd4f657d..e6e4f59a 100644 --- a/lib/debug.js +++ b/lib/debug.js @@ -18,13 +18,14 @@ print += db.nodes + ' nodes. '; } if(db.count){ print += db.count + ' msgs. '} - console.log(print); + console.log(db.print = print); }, 2500); var Gun = require('../gun'); Gun.on('opt', function(root){ this.to.next(root); if(root.once){ return } + root.debug = db; db.root = root; db.peers = root.opt.peers; From 102731a71009180dd28e74667e16e0f877dbd158 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Wed, 16 May 2018 10:21:14 -0700 Subject: [PATCH 04/11] fix typo --- lib/evict.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/evict.js b/lib/evict.js index 4f2b5817..0bc91773 100644 --- a/lib/evict.js +++ b/lib/evict.js @@ -23,7 +23,7 @@ //var start = Gun.state(), i = toss; Gun.list.map(souls, function(soul){ if(--toss < 0){ return } - root.gun(soul).off(); + root.gun.get(soul).off(); }); //console.log("evicted", i, 'nodes in', ((Gun.state() - start)/1000).toFixed(2), 'sec.'); } From 7e5fd2e398fb451993063a1126907c778c55717a Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Wed, 16 May 2018 16:46:02 -0700 Subject: [PATCH 05/11] default NodeJS to superpeer! --- gun.js | 7 +++++-- lib/evict.js | 4 ++-- lib/server.js | 8 +++++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/gun.js b/gun.js index 2c830835..04f2df29 100644 --- a/gun.js +++ b/gun.js @@ -748,8 +748,11 @@ function merge(node, soul){ var ctx = this, cat = ctx.gun._, at = (cat.next || empty)[soul]; if(!at){ - ctx.souls[soul] = false; - return + if(!(cat.opt||empty).super){ + ctx.souls[soul] = false; + return; + } + at = (ctx.gun.get(soul)._); } var msg = ctx.map[soul] = { put: node, diff --git a/lib/evict.js b/lib/evict.js index 0bc91773..8b95f558 100644 --- a/lib/evict.js +++ b/lib/evict.js @@ -11,7 +11,7 @@ ev.max = parseFloat(root.opt.memory || process.env.WEB_MEMORY || 512) * 0.8; - setInterval(check, 250); + setInterval(check, 1000); function check(){ var used = ev.used = util().heapTotal / 1024 / 1024; if(used < ev.max){ return } @@ -19,7 +19,7 @@ } function GC(){ var souls = Object.keys(root.graph||empty); - var toss = Math.ceil(souls.length * 0.1); + var toss = Math.ceil(souls.length * 0.01); //var start = Gun.state(), i = toss; Gun.list.map(souls, function(soul){ if(--toss < 0){ return } diff --git a/lib/server.js b/lib/server.js index f46972e5..eec4ba66 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,6 +1,12 @@ ;(function(){ - var Gun = require('../gun'); + var Gun = require('../gun'), u; Gun.serve = require('./serve'); + Gun.on('opt', function(root){ + this.to.next(root); + if(root.once){ return } + if(u !== root.opt.super){ return } + root.opt.super = true; + }) require('../nts'); require('./store'); require('./rs3'); From 7c64c1c08c067921ffec0cd70a072bfe39b7ec61 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Thu, 17 May 2018 12:32:43 -0700 Subject: [PATCH 06/11] more ugly stats --- lib/debug.js | 48 ++++++++++++++++++++++++++++++++++++++++-------- lib/evict.js | 2 +- lib/wire.js | 1 + 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/lib/debug.js b/lib/debug.js index e6e4f59a..a1a26375 100644 --- a/lib/debug.js +++ b/lib/debug.js @@ -1,24 +1,49 @@ ;(function(){ if('debug' !== process.env.GUN_ENV){ return } - var db = {}; + var db = {length: 0, hash: {}}; console.log("start :)"); global.DEBUG = 1; setInterval(function(){ + var print = '', tmp; var mem = process.memoryUsage(); - var used = mem.heapTotal / 1024 / 1024; - var print = ''; + var used = mem.rss / 1024 / 1024; used = used.toFixed(1); - print += used +' MB. ' + print += used +' MB rss. '; + var used = mem.heapTotal / 1024 / 1024; + used = used.toFixed(1); + print += used +' MB hT. '; + var used = mem.heapUsed / 1024 / 1024; + used = used.toFixed(1); + print += used +' MB hU. '; if(db.root){ db.concurrency = Object.keys(db.peers||{}).length; print += db.concurrency +' peers. '; db.nodes = Object.keys(db.root.graph||{}).length; print += db.nodes + ' nodes. '; + if(db.count){ print += db.count + ' msgs. '} + if(tmp = db.root.msgsLength){ + tmp = (tmp / 1024 / 1024).toFixed(2); + print += tmp + ' length MB. '; + } + if(db.last){ print += '\n' + JSON.stringify(db.last, null, 2) } + if(db.hash){ + print += '\nSome 100 Fast Hash Counts: \n' + JSON.stringify(db.hash, null, 2); + var l = Object.keys(db.hash), i = l.length; + if(i > 100){ + i = i - 100; + Gun.list.map(l, function(k){ + if(--i <= 0){ return } + delete db.hash[k]; + }); + } + } + } - if(db.count){ print += db.count + ' msgs. '} - console.log(db.print = print); + db.print = print; + //print = print.split('\n')[0]; + console.log(print); }, 2500); var Gun = require('../gun'); @@ -32,9 +57,16 @@ db.count = 0; root.on('in', function(msg){ this.to.next(msg); - db.last = msg; + if(!msg.NTS){ db.last = msg } db.count++; - }) + var tmp = msg['##']; + if(tmp && msg.put){ + if(!db.hash[tmp]){ db.hash[tmp] = [0, ''] } + db.hash[tmp][0] = (db.hash[tmp][0] || 0) + 1; + var preview = Object.keys(msg.put||{}); + db.hash[tmp][1] = preview.toString(', ').slice(0,500) + ' ...'; + } + }); }) }()); \ No newline at end of file diff --git a/lib/evict.js b/lib/evict.js index 8b95f558..77fa268c 100644 --- a/lib/evict.js +++ b/lib/evict.js @@ -13,7 +13,7 @@ setInterval(check, 1000); function check(){ - var used = ev.used = util().heapTotal / 1024 / 1024; + var used = ev.used = util().rss / 1024 / 1024; if(used < ev.max){ return } setTimeout(GC, 1); } diff --git a/lib/wire.js b/lib/wire.js index 2060d359..2c815cb9 100644 --- a/lib/wire.js +++ b/lib/wire.js @@ -77,6 +77,7 @@ Gun.on('opt', function(ctx){ ctx.on('hi', peer); wire.on('message', function(msg){ //console.log("MESSAGE", msg); + ctx.msgsLength = (ctx.msgsLength || 0) + (msg.data || msg).length; // TEMPORARY, NON-STANDARD, FOR DEBUG opt.mesh.hear(msg.data || msg, peer); }); wire.on('close', function(){ From b6b8cc90f6aa31fc029694bc1ef77e2cff0bae94 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Thu, 17 May 2018 12:33:08 -0700 Subject: [PATCH 07/11] more heavy stats --- lib/debug.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/debug.js b/lib/debug.js index a1a26375..c6965399 100644 --- a/lib/debug.js +++ b/lib/debug.js @@ -42,7 +42,7 @@ } db.print = print; - //print = print.split('\n')[0]; + print = print.split('\n')[0]; console.log(print); }, 2500); From 81ac428e4b08795e41d068836b9ab23182d594b9 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Tue, 22 May 2018 13:58:49 -0700 Subject: [PATCH 08/11] resync queued writes, don't localStorage out self get --- gun.js | 96 ++++++++++++++++++++++++++++++++++++++++++++++----- lib/debug.js | 1 + lib/radisk.js | 8 ++--- lib/rs3.js | 4 +-- package.json | 2 +- 5 files changed, 96 insertions(+), 15 deletions(-) diff --git a/gun.js b/gun.js index 04f2df29..ba520d9b 100644 --- a/gun.js +++ b/gun.js @@ -686,6 +686,8 @@ if(!at.once){ at.on('in', root, at); at.on('out', root, at); + Gun.on('create', at); + at.on('create', at); } at.once = 1; return gun; @@ -939,6 +941,7 @@ function output(msg){ var put, get, at = this.as, back = at.back, root = at.root; + if(!msg.I){ msg.I = at.gun } if(!msg.gun){ msg.gun = at.gun } this.to.next(msg); if(get = msg.get){ @@ -1366,6 +1369,7 @@ as.res = as.res || function(cb){ if(cb){ cb() } }; as.res(function(){ var cat = (as.gun.back(-1)._), ask = cat.ask(function(ack){ + cat.root.on('ack', ack); this.off(); // One response is good enough for us currently. Later we may want to adjust this. if(!as.ack){ return } as.ack(ack, this); @@ -1742,6 +1746,71 @@ If you update anything here, consider updating the other adapters as well. */ + Gun.on('opt', function(root){ + // This code is used to queue offline writes for resync. + // See the next 'opt' code below for actual saving of data. + var ev = this.to, opt = root.opt; + if(root.once){ return ev.next(root) } + if(false === opt.localStorage){ return ev.next(root) } + opt.file = opt.file || 'gun/'; + var gap = Gun.obj.ify(store.getItem('gap/'+opt.file)) || {}; + var empty = Gun.obj.empty, id, to, go; + // add re-sync command. + if(!empty(gap)){ + root.on('localStorage', function(disk){ + this.off(); + var send = {} + Gun.obj.map(gap, function(node, soul){ + Gun.obj.map(node, function(val, key){ + send[soul] = Gun.state.to(disk[soul], key, send[soul]); + }); + }); + setTimeout(function(){ + root.on('out', {put: send, '#': root.ask(ack), I: root.gun}); + },10); + }); + } + + root.on('out', function(msg){ + if(msg.lS){ return } + if(msg.I && msg.put && !msg['@'] && !empty(opt.peers)){ + id = msg['#']; + Gun.graph.is(msg.put, null, map); + if(!to){ to = setTimeout(flush, opt.wait || 1) } + } + this.to.next(msg); + }); + root.on('ack', ack); + + function ack(ack){ // TODO: This is experimental, not sure if we should keep this type of event hook. + if(ack.err || !ack.ok){ return } + var id = ack['@']; + setTimeout(function(){ + Gun.obj.map(gap, function(node, soul){ + Gun.obj.map(node, function(val, key){ + if(id !== val){ return } + delete node[key]; + }); + if(empty(node)){ + delete gap[soul]; + } + }); + flush(); + }, opt.wait || 1); + }; + ev.next(root); + + var map = function(val, key, node, soul){ + (gap[soul] || (gap[soul] = {}))[key] = id; + } + var flush = function(){ + clearTimeout(to); + to = false; + try{store.setItem('gap/'+opt.file, JSON.stringify(gap)); + }catch(e){ Gun.log(err = e || "localStorage failure") } + } + }); + Gun.on('opt', function(root){ this.to.next(root); var opt = root.opt; @@ -1750,6 +1819,8 @@ opt.file = opt.file || opt.prefix || 'gun/'; // support old option name. var graph = root.graph, acks = {}, count = 0, to; var disk = Gun.obj.ify(store.getItem(opt.file)) || {}; + var lS = function(){}, u; + root.on('localStorage', disk); // NON-STANDARD EVENT! root.on('put', function(at){ this.to.next(at); @@ -1763,12 +1834,12 @@ to = setTimeout(flush, opt.wait || 1); }); - root.on('get', function(at){ - this.to.next(at); - var lex = at.get, soul, data, u; + root.on('get', function(msg){ + this.to.next(msg); + var lex = msg.get, soul, data, u; //setTimeout(function(){ if(!lex || !(soul = lex['#'])){ return } - //if(0 >= at.cap){ return } + //if(0 >= msg.cap){ return } var has = lex['.']; data = disk[soul] || u; if(data && has){ @@ -1777,7 +1848,7 @@ if(!data && !Gun.obj.empty(opt.peers)){ // if data not found, don't ack if there are peers. return; // Hmm, what if we have peers but we are disconnected? } - root.on('in', {'@': at['#'], put: Gun.graph.node(data), how: 'lS'}); + root.on('in', {'@': msg['#'], put: Gun.graph.node(data), how: 'lS', lS: msg.I}); //},1); }); @@ -1813,6 +1884,7 @@ var mesh = function(){}; mesh.out = function(msg){ var tmp; + //console.log("count:", msg['#'], msg); if(this.to){ this.to.next(msg) } if((tmp = msg['@']) && (tmp = ctx.dup.s[tmp]) @@ -1886,7 +1958,8 @@ return; // TODO: this still needs to be tested in the browser! } } - if((tmp = msh.to) && (tmp[peer.url] || tmp[peer.id])){ return } // TODO: still needs to be tested + if((tmp = msh.to) && (tmp[peer.url] || tmp[peer.id])){ return } // TODO: still needs to be tested + //console.log('out', JSON.parse(raw)); if(peer.batch){ peer.batch.push(raw); return; @@ -1898,10 +1971,12 @@ peer.batch = null; if(!tmp.length){ return } send(JSON.stringify(tmp), peer); - }, ctx.opt.wait || 1); + }, ctx.opt.gap || ctx.opt.wait || 1); send(raw, peer); } + function send(raw, peer){ + //console.log("send:", raw.slice(raw.indexOf('#'), 20)); var wire = peer.wire; try{ if(wire.send){ @@ -2019,7 +2094,10 @@ opt.WebSocket = websocket; var mesh = opt.mesh = opt.mesh || Gun.Mesh(root); - root.on('out', mesh.out); + //root.on('create', function(at){ + //this.to.next(at); + root.on('out', mesh.out); + //}); opt.wire = opt.wire || open; function open(peer){ @@ -2041,7 +2119,9 @@ mesh.hi(peer); } wire.onmessage = function(msg){ + //console.log('in', JSON.parse(msg.data || msg)); if(!msg){ return } + env.inLength = (env.inLength || 0) + (msg.data || msg).length; // TEMPORARY, NON-STANDARD, FOR DEBUG mesh.hear(msg.data || msg, peer); }; return wire; diff --git a/lib/debug.js b/lib/debug.js index c6965399..2ed48df4 100644 --- a/lib/debug.js +++ b/lib/debug.js @@ -50,6 +50,7 @@ Gun.on('opt', function(root){ this.to.next(root); if(root.once){ return } + console.log(">>>>>>>>>", root); root.debug = db; db.root = root; db.peers = root.opt.peers; diff --git a/lib/radisk.js b/lib/radisk.js index cb2d571d..1c4075fd 100644 --- a/lib/radisk.js +++ b/lib/radisk.js @@ -6,9 +6,9 @@ function Radisk(opt){ opt = opt || {}; opt.file = String(opt.file || 'radata'); - opt.thrash = opt.thrash || opt.wait || 1; + opt.until = opt.until || opt.wait || 1; opt.batch = opt.batch || 10 * 1000; - opt.size = opt.size || (1024 * 1024 * 10); // 10MB + opt.chunk = opt.chunk || (1024 * 1024 * 10); // 10MB opt.code = opt.code || {}; opt.code.from = opt.code.from || '!'; @@ -51,7 +51,7 @@ function Radisk(opt){ if(cb){ r.batch.acks.push(cb) } if(++r.batch.ed >= opt.batch){ return r.thrash() } // (2) clearTimeout(r.batch.to); // (1) - r.batch.to = setTimeout(r.thrash, opt.thrash || 1); + r.batch.to = setTimeout(r.thrash, opt.until || 1); } r.batch = Radix(); @@ -137,7 +137,7 @@ function Radisk(opt){ f.each = function(val, key, k, pre){ f.count++; var enc = Radisk.encode(pre.length) +'#'+ Radisk.encode(k) + (u === val? '' : '='+ Radisk.encode(val)) +'\n'; - if(opt.size < f.text.length + enc.length){ + if(opt.chunk < f.text.length + enc.length){ f.text = ''; f.limit = Math.ceil(f.count/2); f.count = 0; diff --git a/lib/rs3.js b/lib/rs3.js index ce73d99a..aa3ed870 100644 --- a/lib/rs3.js +++ b/lib/rs3.js @@ -10,8 +10,8 @@ Gun.on('opt', function(ctx){ if(ctx.once){ return } if(!process.env.AWS_S3_BUCKET){ return } opt.batch = opt.batch || (1000 * 10); - opt.thrash = opt.thrash || (1000 * 15); - opt.size = opt.size || (1024 * 1024 * 10); // 10MB + opt.until = opt.until || (1000 * 15); + opt.chunk = opt.chunk || (1024 * 1024 * 10); // 10MB try{AWS = require('aws-sdk'); }catch(e){ diff --git a/package.json b/package.json index b3329653..023b9fa5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gun", - "version": "0.9.996", + "version": "0.9.997", "description": "A realtime, decentralized, offline-first, graph data synchronization engine.", "main": "index.js", "browser": "gun.min.js", From 1c45adf1e2e223e11a343af060822f96fdaa7092 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Tue, 22 May 2018 14:12:57 -0700 Subject: [PATCH 09/11] unbuild last push --- gun.min.js | 2 +- src/adapters/localStorage.js | 77 +++++++++++++++++++++++++++++++++--- src/adapters/mesh.js | 8 +++- src/adapters/websocket.js | 7 +++- src/chain.js | 1 + src/put.js | 1 + src/root.js | 9 ++++- 7 files changed, 94 insertions(+), 11 deletions(-) diff --git a/gun.min.js b/gun.min.js index ed29e5bf..1c0c99e5 100644 --- a/gun.min.js +++ b/gun.min.js @@ -1 +1 @@ -!function(){var t;"undefined"!=typeof window&&(t=window),"undefined"!=typeof global&&(t=global);var _=(t=t||{}).console||{log:function(){}};function x(o){return o.slice?x[e(o)]:function(t,n){o(t={exports:{}}),x[e(n)]=t.exports};function e(t){return t.split("/").slice(-1).toString().replace(".js","")}}if("undefined"!=typeof module)var f=module;x(function(t){var p={};p.fns=p.fn={is:function(t){return!!t&&"function"==typeof t}},p.bi={is:function(t){return t instanceof Boolean||"boolean"==typeof t}},p.num={is:function(t){return!h(t)&&(0<=t-parseFloat(t)+1||1/0===t||-1/0===t)}},p.text={is:function(t){return"string"==typeof t}},p.text.ify=function(t){return p.text.is(t)?t:"undefined"!=typeof JSON?JSON.stringify(t):t&&t.toString?t.toString():t},p.text.random=function(t,n){var o="";for(t=t||24,n=n||"0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz";0")){if(!(n>t[">"]))return!1;o=!0}if(p.obj.has(t,"<")){if(!(n",s.drift=0,s.is=function(t,n,o){var e=n&&t&&t[b]&&t[b][s._]||o;if(e)return d(e=e[n])?e:-1/0},s.lex=function(){return s().toString(36).replace(".","")},s.ify=function(t,n,o,e,i){if(!t||!t[b]){if(!i)return;t=u.soul.ify(t,i)}var r=c(t[b],s._);return void 0!==n&&n!==b&&(d(o)&&(r[n]=o),void 0!==e&&(t[n]=e)),t},s.to=function(t,n,o){var e=t[n];return p(e)&&(e=h(e)),s.ify(o,n,s.is(t,n),e,u.soul(t))},function(){function a(t,n){b!==n&&s.ify(this.o,n,this.s)}s.map=function(i,r,u){var t=p(t=i||r)?t:null;return i=v(i=i||r)?i:null,t&&!i?(r=d(r)?r:s(),t[b]=t[b]||{},g(t,a,{o:t,s:r}),t):(u=u||p(r)?r:void 0,r=d(r)?r:s(),function(t,n,o,e){if(!i)return a.call({o:o,s:r},t,n),t;i.call(u||this||{},t,n,o,e),l(o,n)&&void 0===o[n]||a.call({o:o,s:r},t,n)})}}();var f=n.obj,c=f.as,l=f.has,p=f.is,g=f.map,h=f.copy,d=n.num.is,v=n.fn.is,b=u._;t.exports=s})(x,"./state"),x(function(t){var u=x("./type"),f=x("./val"),c=x("./node"),r={};!function(){function i(t,n){if(!t||n!==c.soul(t)||!c.is(t,this.fn,this.as))return!0;this.cb&&(o.n=t,o.as=this.as,this.cb.call(o.as,t,n,o))}function o(t){t&&c.is(o.n,t,o.as)}r.is=function(t,n,o,e){return!(!t||!l(t)||a(t))&&!s(t,i,{cb:n,fn:o,as:e})}}(),function(){function a(t,n){var o;return(o=function(t,n){var o,e=t.seen,i=e.length;for(;i--;)if(o=e[i],n.obj===o.obj)return o;e.push(n)}(t,n))?o:(n.env=t,n.soul=i,c.ify(n.obj,e,n)&&(t.graph[f.rel.is(n.rel)]=n.node),n)}function e(t,n,o){var e,i,r=this,u=r.env;if(c._===n&&g(t,f.rel._))return o._;if(e=s(t,n,o,r,u)){if(n||(r.node=r.node||o||{},g(t,c._)&&(r.node._=h(t._)),r.node=c.soul.ify(r.node,f.rel.is(r.rel)),r.rel=r.rel||f.rel.ify(c.soul(r.node))),(i=u.map)&&(i.call(u.as||{},t,n,o,r),g(o,n))){if(void 0===(t=o[n]))return void p(o,n);if(!(e=s(t,n,o,r,u)))return}if(!n)return r.node;if(!0===e)return t;if((i=a(u,{obj:t,path:r.path.concat(n)})).node)return i.rel}}function i(t){var n=this,o=f.rel.is(n.rel),e=n.env.graph;n.rel=n.rel||f.rel.ify(t),n.rel[f.rel._]=t,n.node&&n.node[c._]&&(n.node[c._][f.rel._]=t),g(e,o)&&(e[t]=e[o],p(e,o))}function s(t,n,o,e,i){var r;return!!f.is(t)||(l(t)?1:(r=i.invalid)?s(t=r.call(i.as||{},t,n,o),n,o,e,i):(i.err="Invalid value at '"+e.path.concat(n).join(".")+"'!",void(u.list.is(t)&&(i.err+=" Use `.set(item)` instead of an Array."))))}r.ify=function(t,n,o){var e={path:[],obj:t};return n?"string"==typeof n?n={soul:n}:n instanceof Function&&(n.map=n):n={},n.soul&&(e.rel=f.rel.ify(n.soul)),n.graph=n.graph||{},n.seen=n.seen||[],n.as=n.as||o,a(n,e),n.root=e.node,n.graph}}(),r.node=function(t){var n=c.soul(t);if(n)return o({},n,t)},function(){function i(t,n){var o,e;if(c._!==n)(o=f.rel.is(t))?(e=this.opt.seen[o])?this.obj[n]=e:this.obj[n]=this.opt.seen[o]=r.to(this.graph,o,this.opt):this.obj[n]=t;else{if(a(t,f.rel._))return;this.obj[n]=h(t)}}r.to=function(t,n,o){if(t){var e={};return o=o||{seen:{}},s(t[n],i,{obj:e,graph:t,opt:o}),e}}}();u.fn.is;var n=u.obj,l=n.is,p=n.del,g=n.has,a=n.empty,o=n.put,s=n.map,h=n.copy;t.exports=r})(x,"./graph"),x(function(t){x("./onto"),t.exports=function(t,n){if(this.on){if(!(t instanceof Function)){if(!t||!n)return;var o=t["#"]||t,e=(this.tag||empty)[o];if(!e)return;return e=this.on(o,n),clearTimeout(e.err),!0}o=n&&n["#"]||Math.random().toString(36).slice(2);if(!t)return o;var i=this.on(o,t,n);return i.err=i.err||setTimeout(function(){i.next({err:"Error: No ACK received yet."}),i.off()},(this.opt||{}).lack||9e3),o}}})(x,"./ask"),x(function(t){var r=x("./type");var u=r.time.is;t.exports=function(e){var i={s:{}};return e=e||{max:1e3,age:9e3},i.check=function(t){var n;return!!(n=i.s[t])&&(n.pass?n.pass=!1:i.track(t))},i.track=function(t,n){var o=i.s[t]||(i.s[t]={});return o.was=u(),n&&(o.pass=!0),i.to||(i.to=setTimeout(function(){var o=u();r.obj.map(i.s,function(t,n){e.age>o-t.was||r.obj.del(i.s,n)}),i.to=null},e.age+9)),o},i}})(x,"./dup"),x(function(t){function c(t){return t instanceof c?(this._={gun:this}).gun:this instanceof c?c.create(this._={gun:this,opt:t}):new c(t)}c.is=function(t){return t instanceof c||t&&t._&&t._.gun&&!0||!1},c.version=.9,(c.chain=c.prototype).toJSON=function(){};var n=x("./type");n.obj.to(n,c),c.HAM=x("./HAM"),c.val=x("./val"),c.node=x("./node"),c.state=x("./state"),c.graph=x("./graph"),c.on=x("./onto"),c.ask=x("./ask"),c.dup=x("./dup"),function(){function o(t){var n,o,e=this.as,i=e.gun;(o=t["#"])||(o=t["#"]=r(9)),(n=e.dup).check(o)||(n.track(o),e.ask(t["@"],t)||(t.get&&c.on.get(t,i),t.put&&c.on.put(t,i)),e.on("out",t))}c.create=function(t){t.root=t.root||t,t.graph=t.graph||{},t.on=t.on||c.on,t.ask=t.ask||c.ask,t.dup=t.dup||c.dup();var n=t.gun.opt(t.opt);return t.once||(t.on("in",o,t),t.on("out",o,t)),t.once=1,n}}(),function(){function i(t,n,o,e){var i=this,r=c.state.is(o,n);if(!r)return i.err="Error: No state on '"+n+"' in node '"+e+"'!";var u=i.graph[e]||v,a=c.state.is(u,n,!0),s=u[n],f=c.HAM(i.machine,r,a,t,s);f.incoming?(i.put[e]=c.state.to(o,n,i.put[e]),(i.diff||(i.diff={}))[e]=c.state.to(o,n,i.diff[e]),i.souls[e]=!0):f.defer&&(i.defer=r<(i.defer||1/0)?r:i.defer)}function r(t,n){var o=this,e=o.gun._,i=(e.next||v)[n];if(i){var r=o.map[n]={put:t,get:n,gun:i.gun},u={ctx:o,msg:r};o.async=!!e.tag.node,o.ack&&(r["@"]=o.ack),g(t,a,u),o.async&&(o.and||e.on("node",function(t){this.to.next(t),t===o.map[t.get]&&(o.souls[t.get]=!1,g(t.put,s,t),g(o.souls,function(t){if(t)return t})||o.c||(o.c=1,this.off(),e.stop={},g(o.map,f,o)))}),o.and=!0,e.on("node",r))}else o.souls[n]=!1}function a(t,n){var o=this.ctx,e=o.graph,i=this.msg,r=i.get,u=i.put,a=i.gun._;e[r]=c.state.to(u,n,e[r]),o.async||(a.put=c.state.to(u,n,a.put))}function s(t,n){var o=this.put,e=this.gun._;e.put=c.state.to(o,n,e.put)}function f(t,n){t.gun&&t.gun._.on("in",t)}c.on.put=function(t,n){var o=n._,e={gun:n,graph:o.graph,put:{},map:{},souls:{},machine:c.state(),ack:t["@"]};if(c.graph.is(t.put,null,i,e)||(e.err="Error: Invalid graph!"),e.err)return o.on("in",{"@":t["#"],err:c.log(e.err)});g(e.put,r,e),e.async||(o.stop={},g(e.map,f,e)),void 0!==e.defer&&setTimeout(function(){c.on.put(t,n)},e.defer-e.machine),e.diff&&o.on("put",p(t,{put:e.diff}))},c.on.get=function(t,n){var o=n._,e=t.get[h],i=o.graph[e],r=t.get[d],u=(o.next||(o.next={}))[e];if(!i||!u)return o.on("get",t);if(r){if(!l(i,r))return o.on("get",t);i=c.state.to(i,r)}else i=c.obj.copy(i);i=c.graph.node(i),o.on("in",{"@":t["#"],how:"mem",put:i,gun:n}),o.on("get",t)}}(),c.chain.opt=function(t){t=t||{};var n=this._,o=t.peers||t;return a(t)||(t={}),a(n.opt)||(n.opt=t),i(o)&&(o=[o]),e(o)&&(o=g(o,function(t,n,o){o(t,{url:t})}),a(n.opt.peers)||(n.opt.peers={}),n.opt.peers=p(o,n.opt.peers)),n.opt.peers=n.opt.peers||{},p(t,n.opt),c.on("opt",n),n.opt.uuid=n.opt.uuid||function(){return s()+r(12)},this};var e=c.list.is,o=c.text,i=o.is,r=o.random,u=c.obj,a=u.is,l=u.has,p=u.to,g=u.map,s=(u.copy,c.state.lex),h=c.val.rel._,d=".",v=(c.node._,c.val.rel.is,{});_.debug=function(t,n){return _.debug.i&&t===_.debug.i&&_.debug.i++&&(_.log.apply(_,arguments)||n)},(c.log=function(){return!c.log.off&&_.log.apply(_,arguments),[].slice.call(arguments).join(" ")}).once=function(t,n,o){return(o=c.log.once)[t]=o[t]||0,o[t]++||c.log(n)},c.log.once("welcome","Hello wonderful person! :) Thanks for using GUN, feel free to ask for help on https://gitter.im/amark/gun and ask StackOverflow questions tagged with 'gun'!"),"undefined"!=typeof window&&(window.Gun=c);try{void 0!==f&&(f.exports=c)}catch(t){}t.exports=c})(x,"./root"),x(function(t){var a=x("./root");a.chain.back=function(t,n){if(-1===(t=t||1)||1/0===t)return this._.root.gun;if(1===t)return(this._.back||this._).gun;var o=this._;if("string"==typeof t&&(t=t.split(".")),t instanceof Array){for(var e=0,i=t.length,r=o;e .once, apologies unexpected."),this.once(t,n)},s.chain.once=function(t,n){var o=this,e=o._,i=e.put;if(0=(u.batch||1e3))return s();n||(n=setTimeout(s,u.wait||1))}),r.on("get",function(t){this.to.next(t);var n,o,e=t.get;if(e&&(n=e["#"])){var i=e["."];(o=a[n]||void 0)&&i&&(o=Gun.state.to(o,i)),(o||Gun.obj.empty(u.peers))&&r.on("in",{"@":t["#"],put:Gun.graph.node(o),how:"lS"})}});var o=function(t,n,o,e){a[e]=Gun.state.to(o,n,a[e])},s=function(){var o;i=0,clearTimeout(n),n=!1;var t=e;e={};try{f.setItem(u.file,JSON.stringify(a))}catch(t){Gun.log(o=t||"localStorage failure")}(o||Gun.obj.empty(u.peers))&&Gun.obj.map(t,function(t,n){r.on("in",{"@":n,err:o,ok:0})})}}})}})(x,"./adapters/localStorage"),x(function(t){var h=x("../type");function o(p){var g=function(){};return g.out=function(t){var n;if(this.to&&this.to.next(t),(n=t["@"])&&(n=p.dup.s[n])&&(n=n.it)&&n.mesh)return g.say(t,n.mesh.via),void(n["##"]=t["##"]);g.say(t)},g.hear=function(t,n){if(t){var o,e,i,r=p.dup,u=t[0];try{i=JSON.parse(t)}catch(t){}if("{"===u){if(!i)return;if(r.check(o=i["#"]))return;if((u=(r.track(o,!0).it=i)["@"])&&i.put&&(u+=e=i["##"]||(i["##"]=g.hash(i)))!=o){if(r.check(u))return;(u=r.s)[e]=u[o]}return(i.mesh=function(){}).via=n,(u=i["><"])&&(i.mesh.to=h.obj.map(u.split(","),function(t,n,o){o(t,!0)})),void p.on("in",i)}if("["!==u);else{if(!i)return;for(var a,s=0;a=i[s++];)g.hear(a,n)}}},function(){function r(n,o){var t=o.wire;try{t.send?t.readyState===t.OPEN?t.send(n):(o.queue=o.queue||[]).push(n):o.say&&o.say(n)}catch(t){(o.queue=o.queue||[]).push(n)}}g.say=function(n,o){var t,e,i;o?(o.wire||p.opt.wire&&p.opt.wire(o))&&(e=n.mesh||u,o!==e.via&&((i=e.raw)||(i=g.raw(n)),(t=n["@"])&&(t=p.dup.s[t])&&(t=t.it)&&t.get&&t["##"]&&t["##"]===n["##"]||(t=e.to)&&(t[o.url]||t[o.id])||(o.batch?o.batch.push(i):(o.batch=[],setTimeout(function(){var t=o.batch;t&&(o.batch=null,t.length&&r(JSON.stringify(t),o))},p.opt.wait||1),r(i,o))))):h.obj.map(p.opt.peers,function(t){g.say(n,t)})}}(),function(){function f(t,n){var o;return n instanceof Object?(h.obj.map(Object.keys(n).sort(),e,{to:o={},on:n}),o):n}function e(t){this.to[t]=this.on[t]}g.raw=function(t){if(!t)return"";var n,o,e,i=p.dup,r=t.mesh||{};if(e=r.raw)return e;if("string"==typeof t)return t;t["@"]&&(e=t.put)&&((o=t["##"])||(n=c(e,f)||"",o=g.hash(t,n),t["##"]=o),(e=i.s)[o=t["@"]+o]=e[t["#"]],t["#"]=o||t["#"],n&&((t=h.obj.to(t)).put=l));var u=0,a=[];h.obj.map(p.opt.peers,function(t){if(a.push(t.url||t.id),9<++u)return!0}),t["><"]=a.join();var s=c(t);return d!==n&&(s=s.replace('"'+l+'"',n)),r&&(r.raw=s),s},g.hash=function(t,n){return o.hash(n||c(t.put,f)||"")||t["#"]||h.text.random(9)};var c=JSON.stringify,l=":])([:"}(),g.hi=function(n){p.on("hi",n);var t=n.queue;n.queue=[],h.obj.map(t,function(t){g.say(t,n)})},g}o.hash=function(t){if("string"!=typeof t)return{err:1};var n=0;if(!t.length)return n;for(var o=0,e=t.length;o")){if(!(n>t[">"]))return!1;o=!0}if(p.obj.has(t,"<")){if(!(n",s.drift=0,s.is=function(t,n,o){var e=n&&t&&t[b]&&t[b][s._]||o;if(e)return d(e=e[n])?e:-1/0},s.lex=function(){return s().toString(36).replace(".","")},s.ify=function(t,n,o,e,i){if(!t||!t[b]){if(!i)return;t=u.soul.ify(t,i)}var r=c(t[b],s._);return void 0!==n&&n!==b&&(d(o)&&(r[n]=o),void 0!==e&&(t[n]=e)),t},s.to=function(t,n,o){var e=t[n];return p(e)&&(e=h(e)),s.ify(o,n,s.is(t,n),e,u.soul(t))},function(){function a(t,n){b!==n&&s.ify(this.o,n,this.s)}s.map=function(i,r,u){var t=p(t=i||r)?t:null;return i=v(i=i||r)?i:null,t&&!i?(r=d(r)?r:s(),t[b]=t[b]||{},g(t,a,{o:t,s:r}),t):(u=u||p(r)?r:void 0,r=d(r)?r:s(),function(t,n,o,e){if(!i)return a.call({o:o,s:r},t,n),t;i.call(u||this||{},t,n,o,e),l(o,n)&&void 0===o[n]||a.call({o:o,s:r},t,n)})}}();var f=n.obj,c=f.as,l=f.has,p=f.is,g=f.map,h=f.copy,d=n.num.is,v=n.fn.is,b=u._;t.exports=s})(x,"./state"),x(function(t){var u=x("./type"),f=x("./val"),c=x("./node"),r={};!function(){function i(t,n){if(!t||n!==c.soul(t)||!c.is(t,this.fn,this.as))return!0;this.cb&&(o.n=t,o.as=this.as,this.cb.call(o.as,t,n,o))}function o(t){t&&c.is(o.n,t,o.as)}r.is=function(t,n,o,e){return!(!t||!l(t)||a(t))&&!s(t,i,{cb:n,fn:o,as:e})}}(),function(){function a(t,n){var o;return(o=function(t,n){var o,e=t.seen,i=e.length;for(;i--;)if(o=e[i],n.obj===o.obj)return o;e.push(n)}(t,n))?o:(n.env=t,n.soul=i,c.ify(n.obj,e,n)&&(t.graph[f.rel.is(n.rel)]=n.node),n)}function e(t,n,o){var e,i,r=this,u=r.env;if(c._===n&&g(t,f.rel._))return o._;if(e=s(t,n,o,r,u)){if(n||(r.node=r.node||o||{},g(t,c._)&&(r.node._=h(t._)),r.node=c.soul.ify(r.node,f.rel.is(r.rel)),r.rel=r.rel||f.rel.ify(c.soul(r.node))),(i=u.map)&&(i.call(u.as||{},t,n,o,r),g(o,n))){if(void 0===(t=o[n]))return void p(o,n);if(!(e=s(t,n,o,r,u)))return}if(!n)return r.node;if(!0===e)return t;if((i=a(u,{obj:t,path:r.path.concat(n)})).node)return i.rel}}function i(t){var n=this,o=f.rel.is(n.rel),e=n.env.graph;n.rel=n.rel||f.rel.ify(t),n.rel[f.rel._]=t,n.node&&n.node[c._]&&(n.node[c._][f.rel._]=t),g(e,o)&&(e[t]=e[o],p(e,o))}function s(t,n,o,e,i){var r;return!!f.is(t)||(l(t)?1:(r=i.invalid)?s(t=r.call(i.as||{},t,n,o),n,o,e,i):(i.err="Invalid value at '"+e.path.concat(n).join(".")+"'!",void(u.list.is(t)&&(i.err+=" Use `.set(item)` instead of an Array."))))}r.ify=function(t,n,o){var e={path:[],obj:t};return n?"string"==typeof n?n={soul:n}:n instanceof Function&&(n.map=n):n={},n.soul&&(e.rel=f.rel.ify(n.soul)),n.graph=n.graph||{},n.seen=n.seen||[],n.as=n.as||o,a(n,e),n.root=e.node,n.graph}}(),r.node=function(t){var n=c.soul(t);if(n)return o({},n,t)},function(){function i(t,n){var o,e;if(c._!==n)(o=f.rel.is(t))?(e=this.opt.seen[o])?this.obj[n]=e:this.obj[n]=this.opt.seen[o]=r.to(this.graph,o,this.opt):this.obj[n]=t;else{if(a(t,f.rel._))return;this.obj[n]=h(t)}}r.to=function(t,n,o){if(t){var e={};return o=o||{seen:{}},s(t[n],i,{obj:e,graph:t,opt:o}),e}}}();u.fn.is;var n=u.obj,l=n.is,p=n.del,g=n.has,a=n.empty,o=n.put,s=n.map,h=n.copy;t.exports=r})(x,"./graph"),x(function(t){x("./onto"),t.exports=function(t,n){if(this.on){if(!(t instanceof Function)){if(!t||!n)return;var o=t["#"]||t,e=(this.tag||empty)[o];if(!e)return;return e=this.on(o,n),clearTimeout(e.err),!0}o=n&&n["#"]||Math.random().toString(36).slice(2);if(!t)return o;var i=this.on(o,t,n);return i.err=i.err||setTimeout(function(){i.next({err:"Error: No ACK received yet."}),i.off()},(this.opt||{}).lack||9e3),o}}})(x,"./ask"),x(function(t){var r=x("./type");var u=r.time.is;t.exports=function(e){var i={s:{}};return e=e||{max:1e3,age:9e3},i.check=function(t){var n;return!!(n=i.s[t])&&(n.pass?n.pass=!1:i.track(t))},i.track=function(t,n){var o=i.s[t]||(i.s[t]={});return o.was=u(),n&&(o.pass=!0),i.to||(i.to=setTimeout(function(){var o=u();r.obj.map(i.s,function(t,n){e.age>o-t.was||r.obj.del(i.s,n)}),i.to=null},e.age+9)),o},i}})(x,"./dup"),x(function(t){function c(t){return t instanceof c?(this._={gun:this}).gun:this instanceof c?c.create(this._={gun:this,opt:t}):new c(t)}c.is=function(t){return t instanceof c||t&&t._&&t._.gun&&!0||!1},c.version=.9,(c.chain=c.prototype).toJSON=function(){};var n=x("./type");n.obj.to(n,c),c.HAM=x("./HAM"),c.val=x("./val"),c.node=x("./node"),c.state=x("./state"),c.graph=x("./graph"),c.on=x("./onto"),c.ask=x("./ask"),c.dup=x("./dup"),function(){function o(t){var n,o,e=this.as,i=e.gun;(o=t["#"])||(o=t["#"]=r(9)),(n=e.dup).check(o)||(n.track(o),e.ask(t["@"],t)||(t.get&&c.on.get(t,i),t.put&&c.on.put(t,i)),e.on("out",t))}c.create=function(t){t.root=t.root||t,t.graph=t.graph||{},t.on=t.on||c.on,t.ask=t.ask||c.ask,t.dup=t.dup||c.dup();var n=t.gun.opt(t.opt);return t.once||(t.on("in",o,t),t.on("out",o,t),c.on("create",t),t.on("create",t)),t.once=1,n}}(),function(){function i(t,n,o,e){var i=this,r=c.state.is(o,n);if(!r)return i.err="Error: No state on '"+n+"' in node '"+e+"'!";var u=i.graph[e]||v,a=c.state.is(u,n,!0),s=u[n],f=c.HAM(i.machine,r,a,t,s);f.incoming?(i.put[e]=c.state.to(o,n,i.put[e]),(i.diff||(i.diff={}))[e]=c.state.to(o,n,i.diff[e]),i.souls[e]=!0):f.defer&&(i.defer=r<(i.defer||1/0)?r:i.defer)}function r(t,n){var o=this,e=o.gun._,i=(e.next||v)[n];if(!i){if(!(e.opt||v).super)return void(o.souls[n]=!1);i=o.gun.get(n)._}var r=o.map[n]={put:t,get:n,gun:i.gun},u={ctx:o,msg:r};o.async=!!e.tag.node,o.ack&&(r["@"]=o.ack),g(t,a,u),o.async&&(o.and||e.on("node",function(t){this.to.next(t),t===o.map[t.get]&&(o.souls[t.get]=!1,g(t.put,s,t),g(o.souls,function(t){if(t)return t})||o.c||(o.c=1,this.off(),e.stop={},g(o.map,f,o)))}),o.and=!0,e.on("node",r))}function a(t,n){var o=this.ctx,e=o.graph,i=this.msg,r=i.get,u=i.put,a=i.gun._;e[r]=c.state.to(u,n,e[r]),o.async||(a.put=c.state.to(u,n,a.put))}function s(t,n){var o=this.put,e=this.gun._;e.put=c.state.to(o,n,e.put)}function f(t,n){t.gun&&t.gun._.on("in",t)}c.on.put=function(t,n){var o=n._,e={gun:n,graph:o.graph,put:{},map:{},souls:{},machine:c.state(),ack:t["@"]};if(c.graph.is(t.put,null,i,e)||(e.err="Error: Invalid graph!"),e.err)return o.on("in",{"@":t["#"],err:c.log(e.err)});g(e.put,r,e),e.async||(o.stop={},g(e.map,f,e)),void 0!==e.defer&&setTimeout(function(){c.on.put(t,n)},e.defer-e.machine),e.diff&&o.on("put",p(t,{put:e.diff}))},c.on.get=function(t,n){var o=n._,e=t.get[h],i=o.graph[e],r=t.get[d],u=(o.next||(o.next={}))[e];if(!i||!u)return o.on("get",t);if(r){if(!l(i,r))return o.on("get",t);i=c.state.to(i,r)}else i=c.obj.copy(i);i=c.graph.node(i),o.on("in",{"@":t["#"],how:"mem",put:i,gun:n}),o.on("get",t)}}(),c.chain.opt=function(t){t=t||{};var n=this._,o=t.peers||t;return a(t)||(t={}),a(n.opt)||(n.opt=t),i(o)&&(o=[o]),e(o)&&(o=g(o,function(t,n,o){o(t,{url:t})}),a(n.opt.peers)||(n.opt.peers={}),n.opt.peers=p(o,n.opt.peers)),n.opt.peers=n.opt.peers||{},p(t,n.opt),c.on("opt",n),n.opt.uuid=n.opt.uuid||function(){return s()+r(12)},this};var e=c.list.is,o=c.text,i=o.is,r=o.random,u=c.obj,a=u.is,l=u.has,p=u.to,g=u.map,s=(u.copy,c.state.lex),h=c.val.rel._,d=".",v=(c.node._,c.val.rel.is,{});_.debug=function(t,n){return _.debug.i&&t===_.debug.i&&_.debug.i++&&(_.log.apply(_,arguments)||n)},(c.log=function(){return!c.log.off&&_.log.apply(_,arguments),[].slice.call(arguments).join(" ")}).once=function(t,n,o){return(o=c.log.once)[t]=o[t]||0,o[t]++||c.log(n)},c.log.once("welcome","Hello wonderful person! :) Thanks for using GUN, feel free to ask for help on https://gitter.im/amark/gun and ask StackOverflow questions tagged with 'gun'!"),"undefined"!=typeof window&&(window.Gun=c);try{void 0!==f&&(f.exports=c)}catch(t){}t.exports=c})(x,"./root"),x(function(t){var a=x("./root");a.chain.back=function(t,n){if(-1===(t=t||1)||1/0===t)return this._.root.gun;if(1===t)return(this._.back||this._).gun;var o=this._;if("string"==typeof t&&(t=t.split(".")),t instanceof Array){for(var e=0,i=t.length,r=o;e .once, apologies unexpected."),this.once(t,n)},s.chain.once=function(t,n){var o=this,e=o._,i=e.put;if(0=(u.batch||1e3))return s();n||(n=setTimeout(s,u.wait||1))}),r.on("get",function(t){this.to.next(t);var n,o,e=t.get;if(e&&(n=e["#"])){var i=e["."];(o=a[n]||void 0)&&i&&(o=Gun.state.to(o,i)),(o||Gun.obj.empty(u.peers))&&r.on("in",{"@":t["#"],put:Gun.graph.node(o),how:"lS",lS:t.I})}});var o=function(t,n,o,e){a[e]=Gun.state.to(o,n,a[e])},s=function(){var o;i=0,clearTimeout(n),n=!1;var t=e;e={};try{c.setItem(u.file,JSON.stringify(a))}catch(t){Gun.log(o=t||"localStorage failure")}(o||Gun.obj.empty(u.peers))&&Gun.obj.map(t,function(t,n){r.on("in",{"@":n,err:o,ok:0})})}}})}})(x,"./adapters/localStorage"),x(function(t){var h=x("../type");function o(p){var g=function(){};return g.out=function(t){var n;if(this.to&&this.to.next(t),(n=t["@"])&&(n=p.dup.s[n])&&(n=n.it)&&n.mesh)return g.say(t,n.mesh.via),void(n["##"]=t["##"]);g.say(t)},g.hear=function(t,n){if(t){var o,e,i,r=p.dup,u=t[0];try{i=JSON.parse(t)}catch(t){}if("{"===u){if(!i)return;if(r.check(o=i["#"]))return;if((u=(r.track(o,!0).it=i)["@"])&&i.put&&(u+=e=i["##"]||(i["##"]=g.hash(i)))!=o){if(r.check(u))return;(u=r.s)[e]=u[o]}return(i.mesh=function(){}).via=n,(u=i["><"])&&(i.mesh.to=h.obj.map(u.split(","),function(t,n,o){o(t,!0)})),void p.on("in",i)}if("["!==u);else{if(!i)return;for(var a,s=0;a=i[s++];)g.hear(a,n)}}},function(){function r(n,o){var t=o.wire;try{t.send?t.readyState===t.OPEN?t.send(n):(o.queue=o.queue||[]).push(n):o.say&&o.say(n)}catch(t){(o.queue=o.queue||[]).push(n)}}g.say=function(n,o){var t,e,i;o?(o.wire||p.opt.wire&&p.opt.wire(o))&&(e=n.mesh||u,o!==e.via&&((i=e.raw)||(i=g.raw(n)),(t=n["@"])&&(t=p.dup.s[t])&&(t=t.it)&&t.get&&t["##"]&&t["##"]===n["##"]||(t=e.to)&&(t[o.url]||t[o.id])||(o.batch?o.batch.push(i):(o.batch=[],setTimeout(function(){var t=o.batch;t&&(o.batch=null,t.length&&r(JSON.stringify(t),o))},p.opt.gap||p.opt.wait||1),r(i,o))))):h.obj.map(p.opt.peers,function(t){g.say(n,t)})}}(),function(){function f(t,n){var o;return n instanceof Object?(h.obj.map(Object.keys(n).sort(),e,{to:o={},on:n}),o):n}function e(t){this.to[t]=this.on[t]}g.raw=function(t){if(!t)return"";var n,o,e,i=p.dup,r=t.mesh||{};if(e=r.raw)return e;if("string"==typeof t)return t;t["@"]&&(e=t.put)&&((o=t["##"])||(n=c(e,f)||"",o=g.hash(t,n),t["##"]=o),(e=i.s)[o=t["@"]+o]=e[t["#"]],t["#"]=o||t["#"],n&&((t=h.obj.to(t)).put=l));var u=0,a=[];h.obj.map(p.opt.peers,function(t){if(a.push(t.url||t.id),9<++u)return!0}),t["><"]=a.join();var s=c(t);return d!==n&&(s=s.replace('"'+l+'"',n)),r&&(r.raw=s),s},g.hash=function(t,n){return o.hash(n||c(t.put,f)||"")||t["#"]||h.text.random(9)};var c=JSON.stringify,l=":])([:"}(),g.hi=function(n){p.on("hi",n);var t=n.queue;n.queue=[],h.obj.map(t,function(t){g.say(t,n)})},g}o.hash=function(t){if("string"!=typeof t)return{err:1};var n=0;if(!t.length)return n;for(var o=0,e=t.length;o= at.cap){ return } + //if(0 >= msg.cap){ return } var has = lex['.']; data = disk[soul] || u; if(data && has){ @@ -45,7 +112,7 @@ Gun.on('opt', function(root){ if(!data && !Gun.obj.empty(opt.peers)){ // if data not found, don't ack if there are peers. return; // Hmm, what if we have peers but we are disconnected? } - root.on('in', {'@': at['#'], put: Gun.graph.node(data), how: 'lS'}); + root.on('in', {'@': msg['#'], put: Gun.graph.node(data), how: 'lS', lS: msg.I}); //},1); }); diff --git a/src/adapters/mesh.js b/src/adapters/mesh.js index 18998902..0ac123d9 100644 --- a/src/adapters/mesh.js +++ b/src/adapters/mesh.js @@ -5,6 +5,7 @@ function Mesh(ctx){ var mesh = function(){}; mesh.out = function(msg){ var tmp; + //console.log("count:", msg['#'], msg); if(this.to){ this.to.next(msg) } if((tmp = msg['@']) && (tmp = ctx.dup.s[tmp]) @@ -78,7 +79,8 @@ function Mesh(ctx){ return; // TODO: this still needs to be tested in the browser! } } - if((tmp = msh.to) && (tmp[peer.url] || tmp[peer.id])){ return } // TODO: still needs to be tested + if((tmp = msh.to) && (tmp[peer.url] || tmp[peer.id])){ return } // TODO: still needs to be tested + //console.log('out', JSON.parse(raw)); if(peer.batch){ peer.batch.push(raw); return; @@ -90,10 +92,12 @@ function Mesh(ctx){ peer.batch = null; if(!tmp.length){ return } send(JSON.stringify(tmp), peer); - }, ctx.opt.wait || 1); + }, ctx.opt.gap || ctx.opt.wait || 1); send(raw, peer); } + function send(raw, peer){ + //console.log("send:", raw.slice(raw.indexOf('#'), 20)); var wire = peer.wire; try{ if(wire.send){ diff --git a/src/adapters/websocket.js b/src/adapters/websocket.js index 03313687..b00424a6 100644 --- a/src/adapters/websocket.js +++ b/src/adapters/websocket.js @@ -18,7 +18,10 @@ Gun.on('opt', function(root){ opt.WebSocket = websocket; var mesh = opt.mesh = opt.mesh || Gun.Mesh(root); - root.on('out', mesh.out); + //root.on('create', function(at){ + //this.to.next(at); + root.on('out', mesh.out); + //}); opt.wire = opt.wire || open; function open(peer){ @@ -40,7 +43,9 @@ Gun.on('opt', function(root){ mesh.hi(peer); } wire.onmessage = function(msg){ + //console.log('in', JSON.parse(msg.data || msg)); if(!msg){ return } + env.inLength = (env.inLength || 0) + (msg.data || msg).length; // TEMPORARY, NON-STANDARD, FOR DEBUG mesh.hear(msg.data || msg, peer); }; return wire; diff --git a/src/chain.js b/src/chain.js index 68789d93..f76b0823 100644 --- a/src/chain.js +++ b/src/chain.js @@ -16,6 +16,7 @@ Gun.chain.chain = function(sub){ function output(msg){ var put, get, at = this.as, back = at.back, root = at.root; + if(!msg.I){ msg.I = at.gun } if(!msg.gun){ msg.gun = at.gun } this.to.next(msg); if(get = msg.get){ diff --git a/src/put.js b/src/put.js index 81755520..856f36c5 100644 --- a/src/put.js +++ b/src/put.js @@ -93,6 +93,7 @@ function batch(){ var as = this; as.res = as.res || function(cb){ if(cb){ cb() } }; as.res(function(){ var cat = (as.gun.back(-1)._), ask = cat.ask(function(ack){ + cat.root.on('ack', ack); this.off(); // One response is good enough for us currently. Later we may want to adjust this. if(!as.ack){ return } as.ack(ack, this); diff --git a/src/root.js b/src/root.js index eee22dd4..0b3e2506 100644 --- a/src/root.js +++ b/src/root.js @@ -35,6 +35,8 @@ Gun.dup = require('./dup'); if(!at.once){ at.on('in', root, at); at.on('out', root, at); + Gun.on('create', at); + at.on('create', at); } at.once = 1; return gun; @@ -97,8 +99,11 @@ Gun.dup = require('./dup'); function merge(node, soul){ var ctx = this, cat = ctx.gun._, at = (cat.next || empty)[soul]; if(!at){ - ctx.souls[soul] = false; - return + if(!(cat.opt||empty).super){ + ctx.souls[soul] = false; + return; + } + at = (ctx.gun.get(soul)._); } var msg = ctx.map[soul] = { put: node, From 43e4b59d9300c3ff1551387f659f8fe1a6a22f43 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Wed, 23 May 2018 23:02:36 -0700 Subject: [PATCH 10/11] don't double send --- gun.js | 33 ++++++++++++++++++++++----------- lib/radisk.js | 4 ++-- lib/server.js | 1 + 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/gun.js b/gun.js index ba520d9b..32f1180b 100644 --- a/gun.js +++ b/gun.js @@ -169,7 +169,7 @@ // On event emitter generic javascript utility. module.exports = function onto(tag, arg, as){ if(!tag){ return {to: onto} } - var tag = (this.tag || (this.tag = {}))[tag] || + var u, tag = (this.tag || (this.tag = {}))[tag] || (this.tag[tag] = {tag: tag, to: onto._ = { next: function(arg){ var tmp; if((tmp = this.to)){ @@ -200,7 +200,7 @@ (be.back = tag.last || tag).to = be; return tag.last = be; } - (tag = tag.to).next(arg); + if((tag = tag.to) && u !== arg){ tag.next(arg) } return tag; }; })(USE, './onto'); @@ -685,7 +685,7 @@ var gun = at.gun.opt(at.opt); if(!at.once){ at.on('in', root, at); - at.on('out', root, at); + at.on('out', root, obj_to(at, {out: root})); Gun.on('create', at); at.on('create', at); } @@ -697,7 +697,13 @@ var ev = this, at = ev.as, gun = at.gun, dup, tmp; //if(!msg.gun){ msg.gun = at.gun } if(!(tmp = msg['#'])){ tmp = msg['#'] = text_rand(9) } - if((dup = at.dup).check(tmp)){ return } + if((dup = at.dup).check(tmp)){ + if(at.out === msg.out){ + msg.out = u; + ev.to.next(msg); + } + return; + } dup.track(tmp); //msg = obj_to(msg);//, {gun: at.gun}); // can we delete this now? if(!at.ask(msg['@'], msg)){ @@ -710,7 +716,11 @@ //at.on('put', put(msg)); } } - at.on('out', msg); + ev.to.next(msg); + if(!at.out){ + msg.out = root; + at.on('out', msg); + } } }()); @@ -1746,7 +1756,7 @@ If you update anything here, consider updating the other adapters as well. */ - Gun.on('opt', function(root){ + Gun.on('create', function(root){ // This code is used to queue offline writes for resync. // See the next 'opt' code below for actual saving of data. var ev = this.to, opt = root.opt; @@ -1811,7 +1821,7 @@ } }); - Gun.on('opt', function(root){ + Gun.on('create', function(root){ this.to.next(root); var opt = root.opt; if(root.once){ return } @@ -1886,6 +1896,7 @@ mesh.out = function(msg){ var tmp; //console.log("count:", msg['#'], msg); if(this.to){ this.to.next(msg) } + //if(mesh.last != msg['#']){ return mesh.last = msg['#'], this.to.next(msg) } if((tmp = msg['@']) && (tmp = ctx.dup.s[tmp]) && (tmp = tmp.it) @@ -1976,11 +1987,11 @@ } function send(raw, peer){ - //console.log("send:", raw.slice(raw.indexOf('#'), 20)); var wire = peer.wire; try{ if(wire.send){ if(wire.readyState === wire.OPEN){ + //console.log("send:", raw); wire.send(raw); } else { (peer.queue = peer.queue || []).push(raw); @@ -2094,10 +2105,10 @@ opt.WebSocket = websocket; var mesh = opt.mesh = opt.mesh || Gun.Mesh(root); - //root.on('create', function(at){ - //this.to.next(at); + root.on('create', function(at){ + this.to.next(at); root.on('out', mesh.out); - //}); + }); opt.wire = opt.wire || open; function open(peer){ diff --git a/lib/radisk.js b/lib/radisk.js index 1c4075fd..708447f9 100644 --- a/lib/radisk.js +++ b/lib/radisk.js @@ -204,7 +204,7 @@ function Radisk(opt){ } g.ack = function(as){ if(!as.ack){ return } - as.ack(g.err, RAD(as.key)); + as.ack(g.err, (RAD || noop)(as.key)); } opt.store.list(g.lex); } @@ -257,7 +257,7 @@ function Radisk(opt){ opt.store.get(file, p.read); } - var q = {}, RAD, u; + var q = {}, noop = function(){}, RAD, u; return r; } diff --git a/lib/server.js b/lib/server.js index eec4ba66..9ecc84e3 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,6 +1,7 @@ ;(function(){ var Gun = require('../gun'), u; Gun.serve = require('./serve'); + process.env.GUN_ENV = process.env.GUN_ENV || 'debug'; Gun.on('opt', function(root){ this.to.next(root); if(root.once){ return } From 12175fdc4967bd90bff91882642b06595a2c79c9 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Wed, 23 May 2018 23:03:48 -0700 Subject: [PATCH 11/11] don't double send --- gun.min.js | 2 +- src/adapters/localStorage.js | 4 ++-- src/adapters/mesh.js | 3 ++- src/adapters/websocket.js | 6 +++--- src/onto.js | 4 ++-- src/root.js | 16 +++++++++++++--- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/gun.min.js b/gun.min.js index 1c0c99e5..a3589ef7 100644 --- a/gun.min.js +++ b/gun.min.js @@ -1 +1 @@ -!function(){var t;"undefined"!=typeof window&&(t=window),"undefined"!=typeof global&&(t=global);var _=(t=t||{}).console||{log:function(){}};function x(o){return o.slice?x[e(o)]:function(t,n){o(t={exports:{}}),x[e(n)]=t.exports};function e(t){return t.split("/").slice(-1).toString().replace(".js","")}}if("undefined"!=typeof module)var f=module;x(function(t){var p={};p.fns=p.fn={is:function(t){return!!t&&"function"==typeof t}},p.bi={is:function(t){return t instanceof Boolean||"boolean"==typeof t}},p.num={is:function(t){return!h(t)&&(0<=t-parseFloat(t)+1||1/0===t||-1/0===t)}},p.text={is:function(t){return"string"==typeof t}},p.text.ify=function(t){return p.text.is(t)?t:"undefined"!=typeof JSON?JSON.stringify(t):t&&t.toString?t.toString():t},p.text.random=function(t,n){var o="";for(t=t||24,n=n||"0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz";0")){if(!(n>t[">"]))return!1;o=!0}if(p.obj.has(t,"<")){if(!(n",s.drift=0,s.is=function(t,n,o){var e=n&&t&&t[b]&&t[b][s._]||o;if(e)return d(e=e[n])?e:-1/0},s.lex=function(){return s().toString(36).replace(".","")},s.ify=function(t,n,o,e,i){if(!t||!t[b]){if(!i)return;t=u.soul.ify(t,i)}var r=c(t[b],s._);return void 0!==n&&n!==b&&(d(o)&&(r[n]=o),void 0!==e&&(t[n]=e)),t},s.to=function(t,n,o){var e=t[n];return p(e)&&(e=h(e)),s.ify(o,n,s.is(t,n),e,u.soul(t))},function(){function a(t,n){b!==n&&s.ify(this.o,n,this.s)}s.map=function(i,r,u){var t=p(t=i||r)?t:null;return i=v(i=i||r)?i:null,t&&!i?(r=d(r)?r:s(),t[b]=t[b]||{},g(t,a,{o:t,s:r}),t):(u=u||p(r)?r:void 0,r=d(r)?r:s(),function(t,n,o,e){if(!i)return a.call({o:o,s:r},t,n),t;i.call(u||this||{},t,n,o,e),l(o,n)&&void 0===o[n]||a.call({o:o,s:r},t,n)})}}();var f=n.obj,c=f.as,l=f.has,p=f.is,g=f.map,h=f.copy,d=n.num.is,v=n.fn.is,b=u._;t.exports=s})(x,"./state"),x(function(t){var u=x("./type"),f=x("./val"),c=x("./node"),r={};!function(){function i(t,n){if(!t||n!==c.soul(t)||!c.is(t,this.fn,this.as))return!0;this.cb&&(o.n=t,o.as=this.as,this.cb.call(o.as,t,n,o))}function o(t){t&&c.is(o.n,t,o.as)}r.is=function(t,n,o,e){return!(!t||!l(t)||a(t))&&!s(t,i,{cb:n,fn:o,as:e})}}(),function(){function a(t,n){var o;return(o=function(t,n){var o,e=t.seen,i=e.length;for(;i--;)if(o=e[i],n.obj===o.obj)return o;e.push(n)}(t,n))?o:(n.env=t,n.soul=i,c.ify(n.obj,e,n)&&(t.graph[f.rel.is(n.rel)]=n.node),n)}function e(t,n,o){var e,i,r=this,u=r.env;if(c._===n&&g(t,f.rel._))return o._;if(e=s(t,n,o,r,u)){if(n||(r.node=r.node||o||{},g(t,c._)&&(r.node._=h(t._)),r.node=c.soul.ify(r.node,f.rel.is(r.rel)),r.rel=r.rel||f.rel.ify(c.soul(r.node))),(i=u.map)&&(i.call(u.as||{},t,n,o,r),g(o,n))){if(void 0===(t=o[n]))return void p(o,n);if(!(e=s(t,n,o,r,u)))return}if(!n)return r.node;if(!0===e)return t;if((i=a(u,{obj:t,path:r.path.concat(n)})).node)return i.rel}}function i(t){var n=this,o=f.rel.is(n.rel),e=n.env.graph;n.rel=n.rel||f.rel.ify(t),n.rel[f.rel._]=t,n.node&&n.node[c._]&&(n.node[c._][f.rel._]=t),g(e,o)&&(e[t]=e[o],p(e,o))}function s(t,n,o,e,i){var r;return!!f.is(t)||(l(t)?1:(r=i.invalid)?s(t=r.call(i.as||{},t,n,o),n,o,e,i):(i.err="Invalid value at '"+e.path.concat(n).join(".")+"'!",void(u.list.is(t)&&(i.err+=" Use `.set(item)` instead of an Array."))))}r.ify=function(t,n,o){var e={path:[],obj:t};return n?"string"==typeof n?n={soul:n}:n instanceof Function&&(n.map=n):n={},n.soul&&(e.rel=f.rel.ify(n.soul)),n.graph=n.graph||{},n.seen=n.seen||[],n.as=n.as||o,a(n,e),n.root=e.node,n.graph}}(),r.node=function(t){var n=c.soul(t);if(n)return o({},n,t)},function(){function i(t,n){var o,e;if(c._!==n)(o=f.rel.is(t))?(e=this.opt.seen[o])?this.obj[n]=e:this.obj[n]=this.opt.seen[o]=r.to(this.graph,o,this.opt):this.obj[n]=t;else{if(a(t,f.rel._))return;this.obj[n]=h(t)}}r.to=function(t,n,o){if(t){var e={};return o=o||{seen:{}},s(t[n],i,{obj:e,graph:t,opt:o}),e}}}();u.fn.is;var n=u.obj,l=n.is,p=n.del,g=n.has,a=n.empty,o=n.put,s=n.map,h=n.copy;t.exports=r})(x,"./graph"),x(function(t){x("./onto"),t.exports=function(t,n){if(this.on){if(!(t instanceof Function)){if(!t||!n)return;var o=t["#"]||t,e=(this.tag||empty)[o];if(!e)return;return e=this.on(o,n),clearTimeout(e.err),!0}o=n&&n["#"]||Math.random().toString(36).slice(2);if(!t)return o;var i=this.on(o,t,n);return i.err=i.err||setTimeout(function(){i.next({err:"Error: No ACK received yet."}),i.off()},(this.opt||{}).lack||9e3),o}}})(x,"./ask"),x(function(t){var r=x("./type");var u=r.time.is;t.exports=function(e){var i={s:{}};return e=e||{max:1e3,age:9e3},i.check=function(t){var n;return!!(n=i.s[t])&&(n.pass?n.pass=!1:i.track(t))},i.track=function(t,n){var o=i.s[t]||(i.s[t]={});return o.was=u(),n&&(o.pass=!0),i.to||(i.to=setTimeout(function(){var o=u();r.obj.map(i.s,function(t,n){e.age>o-t.was||r.obj.del(i.s,n)}),i.to=null},e.age+9)),o},i}})(x,"./dup"),x(function(t){function c(t){return t instanceof c?(this._={gun:this}).gun:this instanceof c?c.create(this._={gun:this,opt:t}):new c(t)}c.is=function(t){return t instanceof c||t&&t._&&t._.gun&&!0||!1},c.version=.9,(c.chain=c.prototype).toJSON=function(){};var n=x("./type");n.obj.to(n,c),c.HAM=x("./HAM"),c.val=x("./val"),c.node=x("./node"),c.state=x("./state"),c.graph=x("./graph"),c.on=x("./onto"),c.ask=x("./ask"),c.dup=x("./dup"),function(){function o(t){var n,o,e=this.as,i=e.gun;(o=t["#"])||(o=t["#"]=r(9)),(n=e.dup).check(o)||(n.track(o),e.ask(t["@"],t)||(t.get&&c.on.get(t,i),t.put&&c.on.put(t,i)),e.on("out",t))}c.create=function(t){t.root=t.root||t,t.graph=t.graph||{},t.on=t.on||c.on,t.ask=t.ask||c.ask,t.dup=t.dup||c.dup();var n=t.gun.opt(t.opt);return t.once||(t.on("in",o,t),t.on("out",o,t),c.on("create",t),t.on("create",t)),t.once=1,n}}(),function(){function i(t,n,o,e){var i=this,r=c.state.is(o,n);if(!r)return i.err="Error: No state on '"+n+"' in node '"+e+"'!";var u=i.graph[e]||v,a=c.state.is(u,n,!0),s=u[n],f=c.HAM(i.machine,r,a,t,s);f.incoming?(i.put[e]=c.state.to(o,n,i.put[e]),(i.diff||(i.diff={}))[e]=c.state.to(o,n,i.diff[e]),i.souls[e]=!0):f.defer&&(i.defer=r<(i.defer||1/0)?r:i.defer)}function r(t,n){var o=this,e=o.gun._,i=(e.next||v)[n];if(!i){if(!(e.opt||v).super)return void(o.souls[n]=!1);i=o.gun.get(n)._}var r=o.map[n]={put:t,get:n,gun:i.gun},u={ctx:o,msg:r};o.async=!!e.tag.node,o.ack&&(r["@"]=o.ack),g(t,a,u),o.async&&(o.and||e.on("node",function(t){this.to.next(t),t===o.map[t.get]&&(o.souls[t.get]=!1,g(t.put,s,t),g(o.souls,function(t){if(t)return t})||o.c||(o.c=1,this.off(),e.stop={},g(o.map,f,o)))}),o.and=!0,e.on("node",r))}function a(t,n){var o=this.ctx,e=o.graph,i=this.msg,r=i.get,u=i.put,a=i.gun._;e[r]=c.state.to(u,n,e[r]),o.async||(a.put=c.state.to(u,n,a.put))}function s(t,n){var o=this.put,e=this.gun._;e.put=c.state.to(o,n,e.put)}function f(t,n){t.gun&&t.gun._.on("in",t)}c.on.put=function(t,n){var o=n._,e={gun:n,graph:o.graph,put:{},map:{},souls:{},machine:c.state(),ack:t["@"]};if(c.graph.is(t.put,null,i,e)||(e.err="Error: Invalid graph!"),e.err)return o.on("in",{"@":t["#"],err:c.log(e.err)});g(e.put,r,e),e.async||(o.stop={},g(e.map,f,e)),void 0!==e.defer&&setTimeout(function(){c.on.put(t,n)},e.defer-e.machine),e.diff&&o.on("put",p(t,{put:e.diff}))},c.on.get=function(t,n){var o=n._,e=t.get[h],i=o.graph[e],r=t.get[d],u=(o.next||(o.next={}))[e];if(!i||!u)return o.on("get",t);if(r){if(!l(i,r))return o.on("get",t);i=c.state.to(i,r)}else i=c.obj.copy(i);i=c.graph.node(i),o.on("in",{"@":t["#"],how:"mem",put:i,gun:n}),o.on("get",t)}}(),c.chain.opt=function(t){t=t||{};var n=this._,o=t.peers||t;return a(t)||(t={}),a(n.opt)||(n.opt=t),i(o)&&(o=[o]),e(o)&&(o=g(o,function(t,n,o){o(t,{url:t})}),a(n.opt.peers)||(n.opt.peers={}),n.opt.peers=p(o,n.opt.peers)),n.opt.peers=n.opt.peers||{},p(t,n.opt),c.on("opt",n),n.opt.uuid=n.opt.uuid||function(){return s()+r(12)},this};var e=c.list.is,o=c.text,i=o.is,r=o.random,u=c.obj,a=u.is,l=u.has,p=u.to,g=u.map,s=(u.copy,c.state.lex),h=c.val.rel._,d=".",v=(c.node._,c.val.rel.is,{});_.debug=function(t,n){return _.debug.i&&t===_.debug.i&&_.debug.i++&&(_.log.apply(_,arguments)||n)},(c.log=function(){return!c.log.off&&_.log.apply(_,arguments),[].slice.call(arguments).join(" ")}).once=function(t,n,o){return(o=c.log.once)[t]=o[t]||0,o[t]++||c.log(n)},c.log.once("welcome","Hello wonderful person! :) Thanks for using GUN, feel free to ask for help on https://gitter.im/amark/gun and ask StackOverflow questions tagged with 'gun'!"),"undefined"!=typeof window&&(window.Gun=c);try{void 0!==f&&(f.exports=c)}catch(t){}t.exports=c})(x,"./root"),x(function(t){var a=x("./root");a.chain.back=function(t,n){if(-1===(t=t||1)||1/0===t)return this._.root.gun;if(1===t)return(this._.back||this._).gun;var o=this._;if("string"==typeof t&&(t=t.split(".")),t instanceof Array){for(var e=0,i=t.length,r=o;e .once, apologies unexpected."),this.once(t,n)},s.chain.once=function(t,n){var o=this,e=o._,i=e.put;if(0=(u.batch||1e3))return s();n||(n=setTimeout(s,u.wait||1))}),r.on("get",function(t){this.to.next(t);var n,o,e=t.get;if(e&&(n=e["#"])){var i=e["."];(o=a[n]||void 0)&&i&&(o=Gun.state.to(o,i)),(o||Gun.obj.empty(u.peers))&&r.on("in",{"@":t["#"],put:Gun.graph.node(o),how:"lS",lS:t.I})}});var o=function(t,n,o,e){a[e]=Gun.state.to(o,n,a[e])},s=function(){var o;i=0,clearTimeout(n),n=!1;var t=e;e={};try{c.setItem(u.file,JSON.stringify(a))}catch(t){Gun.log(o=t||"localStorage failure")}(o||Gun.obj.empty(u.peers))&&Gun.obj.map(t,function(t,n){r.on("in",{"@":n,err:o,ok:0})})}}})}})(x,"./adapters/localStorage"),x(function(t){var h=x("../type");function o(p){var g=function(){};return g.out=function(t){var n;if(this.to&&this.to.next(t),(n=t["@"])&&(n=p.dup.s[n])&&(n=n.it)&&n.mesh)return g.say(t,n.mesh.via),void(n["##"]=t["##"]);g.say(t)},g.hear=function(t,n){if(t){var o,e,i,r=p.dup,u=t[0];try{i=JSON.parse(t)}catch(t){}if("{"===u){if(!i)return;if(r.check(o=i["#"]))return;if((u=(r.track(o,!0).it=i)["@"])&&i.put&&(u+=e=i["##"]||(i["##"]=g.hash(i)))!=o){if(r.check(u))return;(u=r.s)[e]=u[o]}return(i.mesh=function(){}).via=n,(u=i["><"])&&(i.mesh.to=h.obj.map(u.split(","),function(t,n,o){o(t,!0)})),void p.on("in",i)}if("["!==u);else{if(!i)return;for(var a,s=0;a=i[s++];)g.hear(a,n)}}},function(){function r(n,o){var t=o.wire;try{t.send?t.readyState===t.OPEN?t.send(n):(o.queue=o.queue||[]).push(n):o.say&&o.say(n)}catch(t){(o.queue=o.queue||[]).push(n)}}g.say=function(n,o){var t,e,i;o?(o.wire||p.opt.wire&&p.opt.wire(o))&&(e=n.mesh||u,o!==e.via&&((i=e.raw)||(i=g.raw(n)),(t=n["@"])&&(t=p.dup.s[t])&&(t=t.it)&&t.get&&t["##"]&&t["##"]===n["##"]||(t=e.to)&&(t[o.url]||t[o.id])||(o.batch?o.batch.push(i):(o.batch=[],setTimeout(function(){var t=o.batch;t&&(o.batch=null,t.length&&r(JSON.stringify(t),o))},p.opt.gap||p.opt.wait||1),r(i,o))))):h.obj.map(p.opt.peers,function(t){g.say(n,t)})}}(),function(){function f(t,n){var o;return n instanceof Object?(h.obj.map(Object.keys(n).sort(),e,{to:o={},on:n}),o):n}function e(t){this.to[t]=this.on[t]}g.raw=function(t){if(!t)return"";var n,o,e,i=p.dup,r=t.mesh||{};if(e=r.raw)return e;if("string"==typeof t)return t;t["@"]&&(e=t.put)&&((o=t["##"])||(n=c(e,f)||"",o=g.hash(t,n),t["##"]=o),(e=i.s)[o=t["@"]+o]=e[t["#"]],t["#"]=o||t["#"],n&&((t=h.obj.to(t)).put=l));var u=0,a=[];h.obj.map(p.opt.peers,function(t){if(a.push(t.url||t.id),9<++u)return!0}),t["><"]=a.join();var s=c(t);return d!==n&&(s=s.replace('"'+l+'"',n)),r&&(r.raw=s),s},g.hash=function(t,n){return o.hash(n||c(t.put,f)||"")||t["#"]||h.text.random(9)};var c=JSON.stringify,l=":])([:"}(),g.hi=function(n){p.on("hi",n);var t=n.queue;n.queue=[],h.obj.map(t,function(t){g.say(t,n)})},g}o.hash=function(t){if("string"!=typeof t)return{err:1};var n=0;if(!t.length)return n;for(var o=0,e=t.length;o")){if(!(n>t[">"]))return!1;o=!0}if(p.obj.has(t,"<")){if(!(n",s.drift=0,s.is=function(t,n,o){var e=n&&t&&t[b]&&t[b][s._]||o;if(e)return d(e=e[n])?e:-1/0},s.lex=function(){return s().toString(36).replace(".","")},s.ify=function(t,n,o,e,i){if(!t||!t[b]){if(!i)return;t=u.soul.ify(t,i)}var r=c(t[b],s._);return void 0!==n&&n!==b&&(d(o)&&(r[n]=o),void 0!==e&&(t[n]=e)),t},s.to=function(t,n,o){var e=t[n];return p(e)&&(e=h(e)),s.ify(o,n,s.is(t,n),e,u.soul(t))},function(){function a(t,n){b!==n&&s.ify(this.o,n,this.s)}s.map=function(i,r,u){var t=p(t=i||r)?t:null;return i=v(i=i||r)?i:null,t&&!i?(r=d(r)?r:s(),t[b]=t[b]||{},g(t,a,{o:t,s:r}),t):(u=u||p(r)?r:void 0,r=d(r)?r:s(),function(t,n,o,e){if(!i)return a.call({o:o,s:r},t,n),t;i.call(u||this||{},t,n,o,e),l(o,n)&&void 0===o[n]||a.call({o:o,s:r},t,n)})}}();var f=n.obj,c=f.as,l=f.has,p=f.is,g=f.map,h=f.copy,d=n.num.is,v=n.fn.is,b=u._;t.exports=s})(x,"./state"),x(function(t){var u=x("./type"),f=x("./val"),c=x("./node"),r={};!function(){function i(t,n){if(!t||n!==c.soul(t)||!c.is(t,this.fn,this.as))return!0;this.cb&&(o.n=t,o.as=this.as,this.cb.call(o.as,t,n,o))}function o(t){t&&c.is(o.n,t,o.as)}r.is=function(t,n,o,e){return!(!t||!l(t)||a(t))&&!s(t,i,{cb:n,fn:o,as:e})}}(),function(){function a(t,n){var o;return(o=function(t,n){var o,e=t.seen,i=e.length;for(;i--;)if(o=e[i],n.obj===o.obj)return o;e.push(n)}(t,n))?o:(n.env=t,n.soul=i,c.ify(n.obj,e,n)&&(t.graph[f.rel.is(n.rel)]=n.node),n)}function e(t,n,o){var e,i,r=this,u=r.env;if(c._===n&&g(t,f.rel._))return o._;if(e=s(t,n,o,r,u)){if(n||(r.node=r.node||o||{},g(t,c._)&&(r.node._=h(t._)),r.node=c.soul.ify(r.node,f.rel.is(r.rel)),r.rel=r.rel||f.rel.ify(c.soul(r.node))),(i=u.map)&&(i.call(u.as||{},t,n,o,r),g(o,n))){if(void 0===(t=o[n]))return void p(o,n);if(!(e=s(t,n,o,r,u)))return}if(!n)return r.node;if(!0===e)return t;if((i=a(u,{obj:t,path:r.path.concat(n)})).node)return i.rel}}function i(t){var n=this,o=f.rel.is(n.rel),e=n.env.graph;n.rel=n.rel||f.rel.ify(t),n.rel[f.rel._]=t,n.node&&n.node[c._]&&(n.node[c._][f.rel._]=t),g(e,o)&&(e[t]=e[o],p(e,o))}function s(t,n,o,e,i){var r;return!!f.is(t)||(l(t)?1:(r=i.invalid)?s(t=r.call(i.as||{},t,n,o),n,o,e,i):(i.err="Invalid value at '"+e.path.concat(n).join(".")+"'!",void(u.list.is(t)&&(i.err+=" Use `.set(item)` instead of an Array."))))}r.ify=function(t,n,o){var e={path:[],obj:t};return n?"string"==typeof n?n={soul:n}:n instanceof Function&&(n.map=n):n={},n.soul&&(e.rel=f.rel.ify(n.soul)),n.graph=n.graph||{},n.seen=n.seen||[],n.as=n.as||o,a(n,e),n.root=e.node,n.graph}}(),r.node=function(t){var n=c.soul(t);if(n)return o({},n,t)},function(){function i(t,n){var o,e;if(c._!==n)(o=f.rel.is(t))?(e=this.opt.seen[o])?this.obj[n]=e:this.obj[n]=this.opt.seen[o]=r.to(this.graph,o,this.opt):this.obj[n]=t;else{if(a(t,f.rel._))return;this.obj[n]=h(t)}}r.to=function(t,n,o){if(t){var e={};return o=o||{seen:{}},s(t[n],i,{obj:e,graph:t,opt:o}),e}}}();u.fn.is;var n=u.obj,l=n.is,p=n.del,g=n.has,a=n.empty,o=n.put,s=n.map,h=n.copy;t.exports=r})(x,"./graph"),x(function(t){x("./onto"),t.exports=function(t,n){if(this.on){if(!(t instanceof Function)){if(!t||!n)return;var o=t["#"]||t,e=(this.tag||empty)[o];if(!e)return;return e=this.on(o,n),clearTimeout(e.err),!0}o=n&&n["#"]||Math.random().toString(36).slice(2);if(!t)return o;var i=this.on(o,t,n);return i.err=i.err||setTimeout(function(){i.next({err:"Error: No ACK received yet."}),i.off()},(this.opt||{}).lack||9e3),o}}})(x,"./ask"),x(function(t){var r=x("./type");var u=r.time.is;t.exports=function(e){var i={s:{}};return e=e||{max:1e3,age:9e3},i.check=function(t){var n;return!!(n=i.s[t])&&(n.pass?n.pass=!1:i.track(t))},i.track=function(t,n){var o=i.s[t]||(i.s[t]={});return o.was=u(),n&&(o.pass=!0),i.to||(i.to=setTimeout(function(){var o=u();r.obj.map(i.s,function(t,n){e.age>o-t.was||r.obj.del(i.s,n)}),i.to=null},e.age+9)),o},i}})(x,"./dup"),x(function(t){function c(t){return t instanceof c?(this._={gun:this}).gun:this instanceof c?c.create(this._={gun:this,opt:t}):new c(t)}c.is=function(t){return t instanceof c||t&&t._&&t._.gun&&!0||!1},c.version=.9,(c.chain=c.prototype).toJSON=function(){};var n=x("./type");n.obj.to(n,c),c.HAM=x("./HAM"),c.val=x("./val"),c.node=x("./node"),c.state=x("./state"),c.graph=x("./graph"),c.on=x("./onto"),c.ask=x("./ask"),c.dup=x("./dup"),function(){function r(t){var n,o,e=this.as,i=e.gun;(o=t["#"])||(o=t["#"]=u(9)),(n=e.dup).check(o)?e.out===t.out&&(t.out=void 0,this.to.next(t)):(n.track(o),e.ask(t["@"],t)||(t.get&&c.on.get(t,i),t.put&&c.on.put(t,i)),this.to.next(t),e.out||(t.out=r,e.on("out",t)))}c.create=function(t){t.root=t.root||t,t.graph=t.graph||{},t.on=t.on||c.on,t.ask=t.ask||c.ask,t.dup=t.dup||c.dup();var n=t.gun.opt(t.opt);return t.once||(t.on("in",r,t),t.on("out",r,p(t,{out:r})),c.on("create",t),t.on("create",t)),t.once=1,n}}(),function(){function i(t,n,o,e){var i=this,r=c.state.is(o,n);if(!r)return i.err="Error: No state on '"+n+"' in node '"+e+"'!";var u=i.graph[e]||v,a=c.state.is(u,n,!0),s=u[n],f=c.HAM(i.machine,r,a,t,s);f.incoming?(i.put[e]=c.state.to(o,n,i.put[e]),(i.diff||(i.diff={}))[e]=c.state.to(o,n,i.diff[e]),i.souls[e]=!0):f.defer&&(i.defer=r<(i.defer||1/0)?r:i.defer)}function r(t,n){var o=this,e=o.gun._,i=(e.next||v)[n];if(!i){if(!(e.opt||v).super)return void(o.souls[n]=!1);i=o.gun.get(n)._}var r=o.map[n]={put:t,get:n,gun:i.gun},u={ctx:o,msg:r};o.async=!!e.tag.node,o.ack&&(r["@"]=o.ack),g(t,a,u),o.async&&(o.and||e.on("node",function(t){this.to.next(t),t===o.map[t.get]&&(o.souls[t.get]=!1,g(t.put,s,t),g(o.souls,function(t){if(t)return t})||o.c||(o.c=1,this.off(),e.stop={},g(o.map,f,o)))}),o.and=!0,e.on("node",r))}function a(t,n){var o=this.ctx,e=o.graph,i=this.msg,r=i.get,u=i.put,a=i.gun._;e[r]=c.state.to(u,n,e[r]),o.async||(a.put=c.state.to(u,n,a.put))}function s(t,n){var o=this.put,e=this.gun._;e.put=c.state.to(o,n,e.put)}function f(t,n){t.gun&&t.gun._.on("in",t)}c.on.put=function(t,n){var o=n._,e={gun:n,graph:o.graph,put:{},map:{},souls:{},machine:c.state(),ack:t["@"]};if(c.graph.is(t.put,null,i,e)||(e.err="Error: Invalid graph!"),e.err)return o.on("in",{"@":t["#"],err:c.log(e.err)});g(e.put,r,e),e.async||(o.stop={},g(e.map,f,e)),void 0!==e.defer&&setTimeout(function(){c.on.put(t,n)},e.defer-e.machine),e.diff&&o.on("put",p(t,{put:e.diff}))},c.on.get=function(t,n){var o=n._,e=t.get[h],i=o.graph[e],r=t.get[d],u=(o.next||(o.next={}))[e];if(!i||!u)return o.on("get",t);if(r){if(!l(i,r))return o.on("get",t);i=c.state.to(i,r)}else i=c.obj.copy(i);i=c.graph.node(i),o.on("in",{"@":t["#"],how:"mem",put:i,gun:n}),o.on("get",t)}}(),c.chain.opt=function(t){t=t||{};var n=this._,o=t.peers||t;return a(t)||(t={}),a(n.opt)||(n.opt=t),i(o)&&(o=[o]),e(o)&&(o=g(o,function(t,n,o){o(t,{url:t})}),a(n.opt.peers)||(n.opt.peers={}),n.opt.peers=p(o,n.opt.peers)),n.opt.peers=n.opt.peers||{},p(t,n.opt),c.on("opt",n),n.opt.uuid=n.opt.uuid||function(){return s()+u(12)},this};var e=c.list.is,o=c.text,i=o.is,u=o.random,r=c.obj,a=r.is,l=r.has,p=r.to,g=r.map,s=(r.copy,c.state.lex),h=c.val.rel._,d=".",v=(c.node._,c.val.rel.is,{});_.debug=function(t,n){return _.debug.i&&t===_.debug.i&&_.debug.i++&&(_.log.apply(_,arguments)||n)},(c.log=function(){return!c.log.off&&_.log.apply(_,arguments),[].slice.call(arguments).join(" ")}).once=function(t,n,o){return(o=c.log.once)[t]=o[t]||0,o[t]++||c.log(n)},c.log.once("welcome","Hello wonderful person! :) Thanks for using GUN, feel free to ask for help on https://gitter.im/amark/gun and ask StackOverflow questions tagged with 'gun'!"),"undefined"!=typeof window&&(window.Gun=c);try{void 0!==f&&(f.exports=c)}catch(t){}t.exports=c})(x,"./root"),x(function(t){var a=x("./root");a.chain.back=function(t,n){if(-1===(t=t||1)||1/0===t)return this._.root.gun;if(1===t)return(this._.back||this._).gun;var o=this._;if("string"==typeof t&&(t=t.split(".")),t instanceof Array){for(var e=0,i=t.length,r=o;e .once, apologies unexpected."),this.once(t,n)},s.chain.once=function(t,n){var o=this,e=o._,i=e.put;if(0=(u.batch||1e3))return s();n||(n=setTimeout(s,u.wait||1))}),r.on("get",function(t){this.to.next(t);var n,o,e=t.get;if(e&&(n=e["#"])){var i=e["."];(o=a[n]||void 0)&&i&&(o=Gun.state.to(o,i)),(o||Gun.obj.empty(u.peers))&&r.on("in",{"@":t["#"],put:Gun.graph.node(o),how:"lS",lS:t.I})}});var o=function(t,n,o,e){a[e]=Gun.state.to(o,n,a[e])},s=function(){var o;i=0,clearTimeout(n),n=!1;var t=e;e={};try{c.setItem(u.file,JSON.stringify(a))}catch(t){Gun.log(o=t||"localStorage failure")}(o||Gun.obj.empty(u.peers))&&Gun.obj.map(t,function(t,n){r.on("in",{"@":n,err:o,ok:0})})}}})}})(x,"./adapters/localStorage"),x(function(t){var h=x("../type");function o(p){var g=function(){};return g.out=function(t){var n;if(this.to&&this.to.next(t),(n=t["@"])&&(n=p.dup.s[n])&&(n=n.it)&&n.mesh)return g.say(t,n.mesh.via),void(n["##"]=t["##"]);g.say(t)},g.hear=function(t,n){if(t){var o,e,i,r=p.dup,u=t[0];try{i=JSON.parse(t)}catch(t){}if("{"===u){if(!i)return;if(r.check(o=i["#"]))return;if((u=(r.track(o,!0).it=i)["@"])&&i.put&&(u+=e=i["##"]||(i["##"]=g.hash(i)))!=o){if(r.check(u))return;(u=r.s)[e]=u[o]}return(i.mesh=function(){}).via=n,(u=i["><"])&&(i.mesh.to=h.obj.map(u.split(","),function(t,n,o){o(t,!0)})),void p.on("in",i)}if("["!==u);else{if(!i)return;for(var a,s=0;a=i[s++];)g.hear(a,n)}}},function(){function r(n,o){var t=o.wire;try{t.send?t.readyState===t.OPEN?t.send(n):(o.queue=o.queue||[]).push(n):o.say&&o.say(n)}catch(t){(o.queue=o.queue||[]).push(n)}}g.say=function(n,o){var t,e,i;o?(o.wire||p.opt.wire&&p.opt.wire(o))&&(e=n.mesh||u,o!==e.via&&((i=e.raw)||(i=g.raw(n)),(t=n["@"])&&(t=p.dup.s[t])&&(t=t.it)&&t.get&&t["##"]&&t["##"]===n["##"]||(t=e.to)&&(t[o.url]||t[o.id])||(o.batch?o.batch.push(i):(o.batch=[],setTimeout(function(){var t=o.batch;t&&(o.batch=null,t.length&&r(JSON.stringify(t),o))},p.opt.gap||p.opt.wait||1),r(i,o))))):h.obj.map(p.opt.peers,function(t){g.say(n,t)})}}(),function(){function f(t,n){var o;return n instanceof Object?(h.obj.map(Object.keys(n).sort(),e,{to:o={},on:n}),o):n}function e(t){this.to[t]=this.on[t]}g.raw=function(t){if(!t)return"";var n,o,e,i=p.dup,r=t.mesh||{};if(e=r.raw)return e;if("string"==typeof t)return t;t["@"]&&(e=t.put)&&((o=t["##"])||(n=c(e,f)||"",o=g.hash(t,n),t["##"]=o),(e=i.s)[o=t["@"]+o]=e[t["#"]],t["#"]=o||t["#"],n&&((t=h.obj.to(t)).put=l));var u=0,a=[];h.obj.map(p.opt.peers,function(t){if(a.push(t.url||t.id),9<++u)return!0}),t["><"]=a.join();var s=c(t);return d!==n&&(s=s.replace('"'+l+'"',n)),r&&(r.raw=s),s},g.hash=function(t,n){return o.hash(n||c(t.put,f)||"")||t["#"]||h.text.random(9)};var c=JSON.stringify,l=":])([:"}(),g.hi=function(n){p.on("hi",n);var t=n.queue;n.queue=[],h.obj.map(t,function(t){g.say(t,n)})},g}o.hash=function(t){if("string"!=typeof t)return{err:1};var n=0;if(!t.length)return n;for(var o=0,e=t.length;o