From ffdfc2707eac0a59f27a681418dc040518f47434 Mon Sep 17 00:00:00 2001 From: tomvantilburg Date: Fri, 9 Dec 2016 20:35:33 +0100 Subject: [PATCH 1/2] securing json input for idb --- bower.json | 2 +- dist/cow.js | 84 ++++--------------------------------------- dist/cow.min.js | 6 ++-- dist/cow.nodb.js | 76 +-------------------------------------- dist/cow.node.js | 76 +-------------------------------------- dist/cow.node.min.js | 6 ++-- package.json | 2 +- src/cow2.indexeddb.js | 8 +++-- src/cow2.messenger.js | 74 -------------------------------------- test/index.html | 6 ++-- 10 files changed, 24 insertions(+), 316 deletions(-) diff --git a/bower.json b/bower.json index 6e95196..733cd99 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "cow", - "version": "2.3.0-beta", + "version": "2.3.0-rc1", "main": "dist/cow.js", "homepage": "https://github.com/Geodan/cow", "description": "Concurrent Online WebGIS", diff --git a/dist/cow.js b/dist/cow.js index 56584d9..912d484 100644 --- a/dist/cow.js +++ b/dist/cow.js @@ -670,7 +670,8 @@ Cow.localdb.prototype.write = function(config){ console.warn('Abort error'); }; var store = trans.objectStore(storename); - var request = store.put(record); + //parse / stringify will remove artifacts from other libs + var request = store.put(JSON.parse(JSON.stringify(record))); request.onsuccess = function(e) { resolve(request.result); }; @@ -698,8 +699,9 @@ Cow.localdb.prototype.writeAll = function(config){ var record = list[i]; record._id = record._id.toString(); record.projectid = projectid; - var request = store.put(record); - request.onsuccess = function(e) { + //parse / stringify will remove artifacts from other libs + var request = store.put(JSON.parse(JSON.stringify(record))); + request.onsuccess = function(e) { //continue }; request.onerror = function(e) { @@ -2298,77 +2300,6 @@ Cow.websocket.prototype._onClose = function(event){ _.extend(Cow.websocket.prototype, Events); }.call(this)); -/*TT: -Added this from https://gist.github.com/revolunet/843889 -to enable LZW encoding -*/ -// LZW-compress a string -function lzw_encode(s) { - var dict = {}; - var data = (s + "").split(""); - var out = []; - var currChar; - var phrase = data[0]; - var code = 256; - for (var i=1; i 1 ? dict[phrase] : phrase.charCodeAt(0)); - dict[phrase + currChar] = code; - code++; - phrase=currChar; - } - } - out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0)); - for (var i=0; i1?c[f]:f.charCodeAt(0)),c[f+b]=g,g++,f=b);e.push(f.length>1?c[f]:f.charCodeAt(0));for(var h=0;hj?d[i]:c[j]?c[j]:f+e,g.push(b),e=b.charAt(0),c[h]=f+e,h++,f=b}return g.join("")}function encode_utf8(a){return unescape(encodeURIComponent(a))}function decode_utf8(a){try{return decodeURIComponent(escape(a))}catch(b){console.warn(b,a)}}(function(){var a=[],b=(a.push,a.slice),c=(a.splice,{on:function(a,b,c){if(!e(this,"on",a,[b,c])||!b)return this;this._events||(this._events={});var d=this._events[a]||(this._events[a]=[]);return d.push({callback:b,context:c,ctx:c||this}),this},once:function(a,b,c){if(!e(this,"once",a,[b,c])||!b)return this;var d=this,f=_.once(function(){d.off(a,f),b.apply(this,arguments)});return f._callback=b,this.on(a,f,c)},off:function(a,b,c){var d,f,g,h,i,j,k,l;if(!this._events||!e(this,"off",a,[b,c]))return this;if(!a&&!b&&!c)return this._events=void 0,this;for(h=a?[a]:_.keys(this._events),i=0,j=h.length;j>i;i++)if(a=h[i],g=this._events[a]){if(this._events[a]=d=[],b||c)for(k=0,l=g.length;l>k;k++)f=g[k],(b&&b!==f.callback&&b!==f.callback._callback||c&&c!==f.context)&&d.push(f);d.length||delete this._events[a]}return this},trigger:function(a){if(!this._events)return this;var c=b.call(arguments,1);if(!e(this,"trigger",a,c))return this;var d=this._events[a],g=this._events.all;return d&&f(d,c),g&&f(g,arguments),this},stopListening:function(a,b,c){var d=this._listeningTo;if(!d)return this;var e=!b&&!c;c||"object"!=typeof b||(c=this),a&&((d={})[a._listenId]=a);for(var f in d)a=d[f],a.off(b,c,this),(e||_.isEmpty(a._events))&&delete this._listeningTo[f];return this}}),d=/\s+/,e=function(a,b,c,e){if(!c)return!0;if("object"==typeof c){for(var f in c)a[b].apply(a,[f,c[f]].concat(e));return!1}if(d.test(c)){for(var g=c.split(d),h=0,i=g.length;i>h;h++)a[b].apply(a,[g[h]].concat(e));return!1}return!0},f=function(a,b){var c,d=-1,e=a.length,f=b[0],g=b[1],h=b[2];switch(b.length){case 0:for(;++d0&&this._deltas[0].userid&&(a=this._store._core.users(this._deltas[0].userid.toString())),a},updater:function(a){if(a)return this.updater_on(a);if(this._deltas.length>0&&this._deltas[this._deltas.length-1].userid){var b=this._deltas[this._deltas.length-1].userid;return this._store._core.users(b.toString())}return null},updated:function(a){return a?(this._updated=a,this):this._updated},touch:function(){return this.updated((new Date).getTime()),this._dirty=!0,this},deleted:function(a){return void 0!==a&&"boolean"==typeof a?(this._deleted!==a&&(this._deleted=a,this.updated((new Date).getTime()),this._dirty=!0),this):void 0!==a&&"number"==typeof a?this.deleted_on(a):this._deleted},dirty:function(a){return void 0!==a?(this._dirty!==a&&(this._dirty=a,this.updated((new Date).getTime())),this):this._dirty},ttl:function(a){return void 0!==a?(this._ttl!==a&&(this._ttl=a),this):this._ttl},expired:function(){var a=(new Date).getTime()-this.updated();return!!(this._ttl&&a>this._ttl)},data:function(a,b){return a?a&&"object"==typeof a&&!b?(this._data=a,this._deltaq=a,this.dirty(!0),this):a&&"string"==typeof a&&"undefined"==typeof b?this._data[a]:a&&"number"==typeof a&&"undefined"==typeof b?this.data_on(a):a&&"undefined"!=typeof b?("object"==typeof b&&(b=JSON.parse(JSON.stringify(b))),this._data[a]!=b&&(this._data[a]=b,this._deltaq[a]=b,this.dirty(!0)),this):void 0:"object"==typeof this._data?JSON.parse(JSON.stringify(this._data)):this._data},data_on:function(a){if(athis._updated)return this.data();var b={},c=_.sortBy(this.deltas(),function(a){return a.timestamp});return c.forEach(function(c){c.timestamp<=a&&_.extend(b,c.data)}),b},deleted_on:function(a){if(athis._updated)return this.deleted();var b={},c=_.sortBy(this.deltas(),function(a){return a.timestamp});return c.forEach(function(c){c.timestamp<=a&&(b=c.deleted)}),b},updater_on:function(a){if(athis._updated)return this.updater();var b=_.sortBy(this.deltas(),function(a){return a.timestamp});return b.forEach(function(b){b.timestamp<=a}),null},deltas:function(a,b,c,d){if(!a)return this._deltas.sort(function(a,b){return a.timestamp-b.timestamp});if(a&&!b){for(var e=0;ec._ttl&&b.localdb.delRecord({storename:b._storename,projectid:b._projectid,id:c._id})}),b.trigger("datachange"),b._isloaded=!0,a()},function(a){console.warn("DB Fail"),c(a)})},function(a){console.warn("DB Fail"),c(a)}):(b._isloaded=!0,a())}),this.synced=new Promise(function(a,c){b.loaded.then(function(){b.on("synced",function(){a()})}),b.loaded["catch"](function(a){console.error(a.message),c()})})},Cow.syncstore.prototype={_loadFromDb:function(){var a=this;return new Promise(function(b,c){a.localdb.getRecords({storename:a._storename,projectid:a._projectid}).then(function(c){c.forEach(function(b){var c=a._recordproto(b._id);c.inflate(b);for(var d=c.updated(),e=(new Date).getTime(),f=e-d,g=!1,h=0;h=c._updated&&(g=!0);g||!(f<=c._ttl)&&c._ttl?c._ttl&&f>c._ttl&&a.localdb.delRecord({storename:a._storename,projectid:a._projectid,id:c._id}):a._records.push(c)}),a.trigger("datachange"),b()},function(a){console.warn("DB Fail"),c(a)})})},_getRecords:function(a){for(var b=[],c=0;c-1&&b.push(d)}return b},_getRecord:function(a){for(var b=0;b0&&(this._commitqueue.projectid=this._projectid,this.localdb.writeAll(this._commitqueue),this._commitqueue.data=[])},_getRecordsOn:function(a){var b=[];return this._records.forEach(function(c){a=c._updated?b.push(c):c.data(a)&&b.push(c))}),b},records:function(a){return a&&Array.isArray(a)?this._getRecords(a):a&&"object"==typeof a?this._addRecord({source:"UI",data:a}).dirty(!0):a&&"string"==typeof a?this._getRecord(a):a&&"number"==typeof a?this._getRecordsOn(a):this._records},_removeRecord:function(a){for(var b=0;bf._updated&&c.requestlist.push(i._id);var j=d.indexOf(f._id);j>=0&&d.splice(j,1)}}-1!=g||f.deleted()||f.expired()||c.pushlist.push(f.deflate())}}for(e=0;e=0&&e.splice(c,1),this.data("permissions",e),this}throw"type should be a string";case 2:if("string"==typeof a){for(e=this.permissions(),f=0;f=0)if(Array.isArray(b))for(f=0;f=0&&g.splice(c,1)}else{for(c=null,f=0;f=0&&g.splice(c,1)}d.groups=g,this.data("permissions",e)}return this}throw"type should be a string";default:throw"wrong argument number"}}},_.extend(Cow.item.prototype,Cow.record.prototype)}.call(this),function(){var a=this;"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=Cow||{}),exports.Cow=Cow||{}):a.Cow=Cow||{},Cow.project=function(a){var b=this;this._id=a._id||Cow.utils.idgen(),this._store=a.store,this._core=this._store._core,this._maxAge=this._core._maxAge,this._dirty="true",this._ttl=this._store._maxAge,this._deleted=!1,this._created=(new Date).getTime(),this._updated=(new Date).getTime(),this._data={},this._deltaq={},this._deltas=[],this._deltasforupload=[];var c="groups";this._groupStore=_.extend(new Cow.syncstore({dbname:c,noIDB:!1,core:b._core,maxAge:this._maxAge}),{_records:[],_recordproto:function(a){return new Cow.group({_id:a,store:this})},_type:"groups",_dbname:c,_projectid:this._id,dbname:function(a){this._dbname=a}}),c="items",this._itemStore=_.extend(new Cow.syncstore({dbname:c,noIDB:!1,core:b._core,maxAge:this._maxAge}),{_recordproto:function(a){return new Cow.item({_id:a,store:this})},_projectid:this._id,_records:[],_type:"items",_dbname:c,dbname:function(a){this._dbname=a}})},Cow.project.prototype={closed:function(a){if(void 0!==a){this._closed=a;var b=this.deflate();return b.closed=this._closed,this._store._db_write({source:"UI",data:b}),this}return this._closed},groupStore:function(){return this._groupStore},groups:function(a){return this._groupStore.records(a)},itemStore:function(){return this._itemStore},items:function(a){return this._itemStore.records(a)},myGroups:function(){for(var a=this.groups(),b=this._core.user().id(),c=[],d=0;dc&&(b._sendhistory.shift(),b._amountsendhistory.shift()),b._reqhistory.push(b._numreqs),b._amountreqhistory.push(b._amountreq),b._reqhistory.length>c&&(b._reqhistory.shift(),b._amountreqhistory.shift()),b._numsends=0,b._amountsend=0,b._numreqs=0,b._amountreq=0},1e3)},Cow.messenger.prototype.activitylog=function(){return{reqhistory:this._reqhistory,sendhistory:this._sendhistory,amountreqhistory:this._amountreqhistory,amountsendhistory:this._amountsendhistory}},Cow.messenger.prototype.sendData=function(a,b,c){var d={};d.sender=this._core.peerid(),d.target=c,d.action=b,d.payload=lzwCompress.pack(a);var e;try{e=JSON.stringify(d)}catch(f){console.error(f,d)}this.ws.send(e),this._numsends++,this._amountsend=+e.length},Cow.messenger.prototype._onError=function(a){},Cow.messenger.prototype._onMessage=function(a){var b=this._core,c=JSON.parse(a.data),d=c.sender,e=b.peerid(),f=c.action;if("connected"==c.action)c.payload=c.payload;else try{c.payload=lzwCompress.unpack(c.payload)}catch(g){this.trigger("notice","Error in lzwCompress "+g)}var h=c.payload,i=c.target;switch(d!=e&&(this._core.messenger()._numreqs++,this._core.messenger()._amountreq=+a.data.length),f){case"command":d!=e&&this._core.messenger()._onCommand(c);break;case"connected":this._core.messenger()._onConnect(h);break;case"peerGone":this._core.messenger()._onPeerGone(h);break;case"newList":d!=e&&this._core.messenger()._onNewList(h,d);break;case"syncinfo":d!=e&&this._core.messenger()._onSyncinfo(h,d);break;case"wantedList":i==e&&this._core.messenger()._onWantedList(h);break;case"missingRecord":i==e&&this._core.messenger()._onMissingRecord(h);break;case"requestedRecord":d!=e&&this._core.messenger()._onMissingRecord(h);break;case"updatedRecord":d!=e&&this._core.messenger()._onUpdatedRecord(h)}},Cow.messenger.prototype._onConnect=function(a){function b(){console.log("Starting sync"),c._core.projectStore().sync(),c._core.socketserverStore().sync(),c._core.peerStore().sync(),c._core.userStore().sync(),c._core.projectStore().synced.then(function(){for(var a=c._core.projects(),b=0;bh)return c.trigger("notice","Time difference between server and client larger ("+Math.abs(f-g)+"ms) than allowed ("+h+" ms)."),void c.ws.disconnect();if(void 0!==e&&e!=this._core._herdname)return c.trigger("notice","Key on server ("+e+") not the same as client key ("+this._core._herdname+")."),void c.ws.disconnect();this._core.user()&&d.data("userid",this._core.user().id()),d.data("version",this._core.version()),d.deleted(!1).sync(),this.trigger("connected",a);var i=[this._core.socketserverStore().loaded,this._core.peerStore().loaded,this._core.userStore().loaded,this._core.projectStore().loaded];Promise.all(i).then(function(){for(var a=c._core.projects(),d=[],e=0;e0&&this.sendData(d,"wantedList",b),g.pushlist.forEach(function(d){msg={syncType:a.syncType,project:f,record:d},c.sendData(msg,"missingRecord",b)})}},Cow.messenger.prototype._amIAlpha=function(){var a=null,b=this._core.alphaPeer(),c=this._core.peer();return a=c.id()==b.id()},Cow.messenger.prototype._onSyncinfo=function(a){var b=this._getStore(a);b.syncinfo.toReceive=a.syncinfo.IWillSent,b.syncinfo.toSent=a.syncinfo.IShallReceive,b.syncinfo.toReceive.length<1&&b.trigger("synced")},Cow.messenger.prototype._onWantedList=function(a){var b=this,c=this._getStore(a),d=c.requestRecords(a.list);d.forEach(function(d){msg={syncType:a.syncType,project:c._projectid,record:d},b.sendData(msg,"requestedRecord")})},Cow.messenger.prototype._onMissingRecord=function(a){var b=this._getStore(a),c=a.record,d=b._addRecord({source:"WS",data:c});if(b._commit(),b.trigger("datachange"),b.syncinfo.toReceive=_.without(b.syncinfo.toReceive,c._id),b.syncinfo.toReceive.length<1&&b.trigger("synced"),c.deltas&&d.deltas()){var e=_.pluck(d.deltas(),"timestamp"),f=_.pluck(c.deltas,"timestamp"),g=_.difference(e,f);g.length>0&&b.syncRecord(d)}},Cow.messenger.prototype._onUpdatedRecord=function(a){var b=this._getStore(a),c=a.record;b._addRecord({source:"WS",data:c}),b._commit(),b.trigger("datachange")},Cow.messenger.prototype._onCommand=function(a){var b=this._core,c=a.payload,d=c.command,e=c.target;c.params;if(this.trigger("command",a),"kickPeer"==d&&a.target==b.peerid()&&(b.socketserver("invalid"),b.disconnect()),"purgePeer"==d&&e&&e==this._core.peerid()&&(b.projects().forEach(function(a){a.itemStore().clear(),a.groupStore().clear()}),b.projectStore().clear(),b.userStore().clear()),"flushProject"==d){var f,g=c.projectid;b.projects(g)&&(f=b.projects(g),f.itemStore().clear())}"ping"==d&&this.sendData({command:"pong"},"command",a.sender)},_.extend(Cow.messenger.prototype,Events)}.call(this),function(){var a=this;"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=Cow||{}),exports.Cow=Cow||{}):a.Cow=Cow||{},Cow.core=function(a){var b=this;"undefined"==typeof a&&(a={}),this._version="2.3.0-beta",this._herdname=a.herdname||"cow",this._userid=null,this._socketserverid=null,this._projectid=null,this._wsUrl=null,this._peerid=null,this._maxAge=a.maxAge||10368e6,this._autoReconnect=a.autoReconnect||!0,this._localdb=new Cow.localdb({dbname:this._herdname,core:this}),this._projectStore=_.extend(new Cow.syncstore({dbname:"projects",noIDB:!1,noDeltas:!1,core:b,maxAge:this._maxAge}),{_records:[],_recordproto:function(a){return new Cow.project({_id:a,store:this})},_dbname:"projects",_type:"projects"}),this._peerStore=_.extend(new Cow.syncstore({dbname:"peers",noIDB:!0,noDeltas:!0,core:this}),{_records:[],_recordproto:function(a){return new Cow.peer({_id:a,store:this})},_dbname:"peers",_type:"peers",removePeer:function(a){return this._removeRecord(a)}}),this._userStore=_.extend(new Cow.syncstore({dbname:"users",noIDB:!1,noDeltas:!0,core:this}),{_records:[],_recordproto:function(a){return new Cow.user({_id:a,store:this})},_dbname:"users",_type:"users"}),this._socketserverStore=_.extend(new Cow.syncstore({dbname:"socketservers",noIDB:!1,noDeltas:!0,core:this}),{_records:[],_recordproto:function(a){return new Cow.socketserver({_id:a,store:this})},_dbname:"socketservers",_type:"socketservers"}),this._websocket=new Cow.websocket({core:this,url:this._wsUrl}),this._messenger=new Cow.messenger({core:this})},Cow.core.prototype={peerid:function(a){return a?(this._peerid=a.toString(),this._peerid):this._peerid?this._peerid.toString():null},project:function(a){if(a){a=a.toString();var b=this.projects(a);return b?(this._projectid=a,this.peer()&&this.peer().data("activeproject",a).sync(),this.trigger("projectChanged"),!0):(console.warn("Trying to select a non existing project"),!1)}return this._projectid?this.projects(this._projectid):!1},user:function(a){return a?(a=a.toString(),this._userid=a,this.peer()&&this.peers(this.peerid())&&this.peer().data("userid",a).sync(),this.users(a)):this._userid?this.users(this._userid):!1},version:function(){return this._version},socketserver:function(a){return a?(a=a.toString(),this._socketserverid=a,this.socketservers(a)):this._socketserverid?this.socketservers(this._socketserverid):!1},peer:function(){return this.peerid()?this.peers(this.peerid()):!1},location:function(a){return a?(this._location=a,this.peerid()&&this.peers(this.peerid()).data("location",a).sync(),this._location):this._location},projectStore:function(){return this._projectStore},projects:function(a){return this._projectStore.records(a)},peerStore:function(){return this._peerStore},peers:function(a){return this._peerStore.records(a)},socketserverStore:function(){return this._socketserverStore},socketservers:function(a){return this._socketserverStore.records(a)},userStore:function(){return this._userStore},users:function(a){return this._userStore.records(a)},activeUsers:function(){for(var a=[],b=this.peers().filter(function(a){return!a.deleted()}),c=0;ci;i++)if(a=h[i],g=this._events[a]){if(this._events[a]=d=[],b||c)for(k=0,l=g.length;l>k;k++)f=g[k],(b&&b!==f.callback&&b!==f.callback._callback||c&&c!==f.context)&&d.push(f);d.length||delete this._events[a]}return this},trigger:function(a){if(!this._events)return this;var c=b.call(arguments,1);if(!e(this,"trigger",a,c))return this;var d=this._events[a],g=this._events.all;return d&&f(d,c),g&&f(g,arguments),this},stopListening:function(a,b,c){var d=this._listeningTo;if(!d)return this;var e=!b&&!c;c||"object"!=typeof b||(c=this),a&&((d={})[a._listenId]=a);for(var f in d)a=d[f],a.off(b,c,this),(e||_.isEmpty(a._events))&&delete this._listeningTo[f];return this}}),d=/\s+/,e=function(a,b,c,e){if(!c)return!0;if("object"==typeof c){for(var f in c)a[b].apply(a,[f,c[f]].concat(e));return!1}if(d.test(c)){for(var g=c.split(d),h=0,i=g.length;i>h;h++)a[b].apply(a,[g[h]].concat(e));return!1}return!0},f=function(a,b){var c,d=-1,e=a.length,f=b[0],g=b[1],h=b[2];switch(b.length){case 0:for(;++d0&&this._deltas[0].userid&&(a=this._store._core.users(this._deltas[0].userid.toString())),a},updater:function(a){if(a)return this.updater_on(a);if(this._deltas.length>0&&this._deltas[this._deltas.length-1].userid){var b=this._deltas[this._deltas.length-1].userid;return this._store._core.users(b.toString())}return null},updated:function(a){return a?(this._updated=a,this):this._updated},touch:function(){return this.updated((new Date).getTime()),this._dirty=!0,this},deleted:function(a){return void 0!==a&&"boolean"==typeof a?(this._deleted!==a&&(this._deleted=a,this.updated((new Date).getTime()),this._dirty=!0),this):void 0!==a&&"number"==typeof a?this.deleted_on(a):this._deleted},dirty:function(a){return void 0!==a?(this._dirty!==a&&(this._dirty=a,this.updated((new Date).getTime())),this):this._dirty},ttl:function(a){return void 0!==a?(this._ttl!==a&&(this._ttl=a),this):this._ttl},expired:function(){var a=(new Date).getTime()-this.updated();return!!(this._ttl&&a>this._ttl)},data:function(a,b){return a?a&&"object"==typeof a&&!b?(this._data=a,this._deltaq=a,this.dirty(!0),this):a&&"string"==typeof a&&"undefined"==typeof b?this._data[a]:a&&"number"==typeof a&&"undefined"==typeof b?this.data_on(a):a&&"undefined"!=typeof b?("object"==typeof b&&(b=JSON.parse(JSON.stringify(b))),this._data[a]!=b&&(this._data[a]=b,this._deltaq[a]=b,this.dirty(!0)),this):void 0:"object"==typeof this._data?JSON.parse(JSON.stringify(this._data)):this._data},data_on:function(a){if(athis._updated)return this.data();var b={},c=_.sortBy(this.deltas(),function(a){return a.timestamp});return c.forEach(function(c){c.timestamp<=a&&_.extend(b,c.data)}),b},deleted_on:function(a){if(athis._updated)return this.deleted();var b={},c=_.sortBy(this.deltas(),function(a){return a.timestamp});return c.forEach(function(c){c.timestamp<=a&&(b=c.deleted)}),b},updater_on:function(a){if(athis._updated)return this.updater();var b=_.sortBy(this.deltas(),function(a){return a.timestamp});return b.forEach(function(b){b.timestamp<=a}),null},deltas:function(a,b,c,d){if(!a)return this._deltas.sort(function(a,b){return a.timestamp-b.timestamp});if(a&&!b){for(var e=0;ec._ttl&&b.localdb.delRecord({storename:b._storename,projectid:b._projectid,id:c._id})}),b.trigger("datachange"),b._isloaded=!0,a()},function(a){console.warn("DB Fail"),c(a)})},function(a){console.warn("DB Fail"),c(a)}):(b._isloaded=!0,a())}),this.synced=new Promise(function(a,c){b.loaded.then(function(){b.on("synced",function(){a()})}),b.loaded["catch"](function(a){console.error(a.message),c()})})},Cow.syncstore.prototype={_loadFromDb:function(){var a=this;return new Promise(function(b,c){a.localdb.getRecords({storename:a._storename,projectid:a._projectid}).then(function(c){c.forEach(function(b){var c=a._recordproto(b._id);c.inflate(b);for(var d=c.updated(),e=(new Date).getTime(),f=e-d,g=!1,h=0;h=c._updated&&(g=!0);g||!(f<=c._ttl)&&c._ttl?c._ttl&&f>c._ttl&&a.localdb.delRecord({storename:a._storename,projectid:a._projectid,id:c._id}):a._records.push(c)}),a.trigger("datachange"),b()},function(a){console.warn("DB Fail"),c(a)})})},_getRecords:function(a){for(var b=[],c=0;c-1&&b.push(d)}return b},_getRecord:function(a){for(var b=0;b0&&(this._commitqueue.projectid=this._projectid,this.localdb.writeAll(this._commitqueue),this._commitqueue.data=[])},_getRecordsOn:function(a){var b=[];return this._records.forEach(function(c){a=c._updated?b.push(c):c.data(a)&&b.push(c))}),b},records:function(a){return a&&Array.isArray(a)?this._getRecords(a):a&&"object"==typeof a?this._addRecord({source:"UI",data:a}).dirty(!0):a&&"string"==typeof a?this._getRecord(a):a&&"number"==typeof a?this._getRecordsOn(a):this._records},_removeRecord:function(a){for(var b=0;bf._updated&&c.requestlist.push(i._id);var j=d.indexOf(f._id);j>=0&&d.splice(j,1)}}-1!=g||f.deleted()||f.expired()||c.pushlist.push(f.deflate())}}for(e=0;e=0&&e.splice(c,1),this.data("permissions",e),this}throw"type should be a string";case 2:if("string"==typeof a){for(e=this.permissions(),f=0;f=0)if(Array.isArray(b))for(f=0;f=0&&g.splice(c,1)}else{for(c=null,f=0;f=0&&g.splice(c,1)}d.groups=g,this.data("permissions",e)}return this}throw"type should be a string";default:throw"wrong argument number"}}},_.extend(Cow.item.prototype,Cow.record.prototype)}.call(this),function(){var a=this;"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=Cow||{}),exports.Cow=Cow||{}):a.Cow=Cow||{},Cow.project=function(a){var b=this;this._id=a._id||Cow.utils.idgen(),this._store=a.store,this._core=this._store._core,this._maxAge=this._core._maxAge,this._dirty="true",this._ttl=this._store._maxAge,this._deleted=!1,this._created=(new Date).getTime(),this._updated=(new Date).getTime(),this._data={},this._deltaq={},this._deltas=[],this._deltasforupload=[];var c="groups";this._groupStore=_.extend(new Cow.syncstore({dbname:c,noIDB:!1,core:b._core,maxAge:this._maxAge}),{_records:[],_recordproto:function(a){return new Cow.group({_id:a,store:this})},_type:"groups",_dbname:c,_projectid:this._id,dbname:function(a){this._dbname=a}}),c="items",this._itemStore=_.extend(new Cow.syncstore({dbname:c,noIDB:!1,core:b._core,maxAge:this._maxAge}),{_recordproto:function(a){return new Cow.item({_id:a,store:this})},_projectid:this._id,_records:[],_type:"items",_dbname:c,dbname:function(a){this._dbname=a}})},Cow.project.prototype={closed:function(a){if(void 0!==a){this._closed=a;var b=this.deflate();return b.closed=this._closed,this._store._db_write({source:"UI",data:b}),this}return this._closed},groupStore:function(){return this._groupStore},groups:function(a){return this._groupStore.records(a)},itemStore:function(){return this._itemStore},items:function(a){return this._itemStore.records(a)},myGroups:function(){for(var a=this.groups(),b=this._core.user().id(),c=[],d=0;dc&&(b._sendhistory.shift(),b._amountsendhistory.shift()),b._reqhistory.push(b._numreqs),b._amountreqhistory.push(b._amountreq),b._reqhistory.length>c&&(b._reqhistory.shift(),b._amountreqhistory.shift()),b._numsends=0,b._amountsend=0,b._numreqs=0,b._amountreq=0},1e3)},Cow.messenger.prototype.activitylog=function(){return{reqhistory:this._reqhistory,sendhistory:this._sendhistory,amountreqhistory:this._amountreqhistory,amountsendhistory:this._amountsendhistory}},Cow.messenger.prototype.sendData=function(a,b,c){var d={};d.sender=this._core.peerid(),d.target=c,d.action=b,d.payload=lzwCompress.pack(a);var e;try{e=JSON.stringify(d)}catch(f){console.error(f,d)}this.ws.send(e),this._numsends++,this._amountsend=+e.length},Cow.messenger.prototype._onError=function(a){},Cow.messenger.prototype._onMessage=function(a){var b=this._core,c=JSON.parse(a.data),d=c.sender,e=b.peerid(),f=c.action;if("connected"==c.action)c.payload=c.payload;else try{c.payload=lzwCompress.unpack(c.payload)}catch(g){this.trigger("notice","Error in lzwCompress "+g)}var h=c.payload,i=c.target;switch(d!=e&&(this._core.messenger()._numreqs++,this._core.messenger()._amountreq=+a.data.length),f){case"command":d!=e&&this._core.messenger()._onCommand(c);break;case"connected":this._core.messenger()._onConnect(h);break;case"peerGone":this._core.messenger()._onPeerGone(h);break;case"newList":d!=e&&this._core.messenger()._onNewList(h,d);break;case"syncinfo":d!=e&&this._core.messenger()._onSyncinfo(h,d);break;case"wantedList":i==e&&this._core.messenger()._onWantedList(h);break;case"missingRecord":i==e&&this._core.messenger()._onMissingRecord(h);break;case"requestedRecord":d!=e&&this._core.messenger()._onMissingRecord(h);break;case"updatedRecord":d!=e&&this._core.messenger()._onUpdatedRecord(h)}},Cow.messenger.prototype._onConnect=function(a){function b(){console.log("Starting sync"),c._core.projectStore().sync(),c._core.socketserverStore().sync(),c._core.peerStore().sync(),c._core.userStore().sync(),c._core.projectStore().synced.then(function(){for(var a=c._core.projects(),b=0;bh)return c.trigger("notice","Time difference between server and client larger ("+Math.abs(f-g)+"ms) than allowed ("+h+" ms)."),void c.ws.disconnect();if(void 0!==e&&e!=this._core._herdname)return c.trigger("notice","Key on server ("+e+") not the same as client key ("+this._core._herdname+")."),void c.ws.disconnect();this._core.user()&&d.data("userid",this._core.user().id()),d.data("version",this._core.version()),d.deleted(!1).sync(),this.trigger("connected",a);var i=[this._core.socketserverStore().loaded,this._core.peerStore().loaded,this._core.userStore().loaded,this._core.projectStore().loaded];Promise.all(i).then(function(){for(var a=c._core.projects(),d=[],e=0;e0&&this.sendData(d,"wantedList",b),g.pushlist.forEach(function(d){msg={syncType:a.syncType,project:f,record:d},c.sendData(msg,"missingRecord",b)})}},Cow.messenger.prototype._amIAlpha=function(){var a=null,b=this._core.alphaPeer(),c=this._core.peer();return a=c.id()==b.id()},Cow.messenger.prototype._onSyncinfo=function(a){var b=this._getStore(a);b.syncinfo.toReceive=a.syncinfo.IWillSent,b.syncinfo.toSent=a.syncinfo.IShallReceive,b.syncinfo.toReceive.length<1&&b.trigger("synced")},Cow.messenger.prototype._onWantedList=function(a){var b=this,c=this._getStore(a),d=c.requestRecords(a.list);d.forEach(function(d){msg={syncType:a.syncType,project:c._projectid,record:d},b.sendData(msg,"requestedRecord")})},Cow.messenger.prototype._onMissingRecord=function(a){var b=this._getStore(a),c=a.record,d=b._addRecord({source:"WS",data:c});if(b._commit(),b.trigger("datachange"),b.syncinfo.toReceive=_.without(b.syncinfo.toReceive,c._id),b.syncinfo.toReceive.length<1&&b.trigger("synced"),c.deltas&&d.deltas()){var e=_.pluck(d.deltas(),"timestamp"),f=_.pluck(c.deltas,"timestamp"),g=_.difference(e,f);g.length>0&&b.syncRecord(d)}},Cow.messenger.prototype._onUpdatedRecord=function(a){var b=this._getStore(a),c=a.record;b._addRecord({source:"WS",data:c}),b._commit(),b.trigger("datachange")},Cow.messenger.prototype._onCommand=function(a){var b=this._core,c=a.payload,d=c.command,e=c.target;c.params;if(this.trigger("command",a),"kickPeer"==d&&a.target==b.peerid()&&(b.socketserver("invalid"),b.disconnect()),"purgePeer"==d&&e&&e==this._core.peerid()&&(b.projects().forEach(function(a){a.itemStore().clear(),a.groupStore().clear()}),b.projectStore().clear(),b.userStore().clear()),"flushProject"==d){var f,g=c.projectid;b.projects(g)&&(f=b.projects(g),f.itemStore().clear())}"ping"==d&&this.sendData({command:"pong"},"command",a.sender)},_.extend(Cow.messenger.prototype,Events)}.call(this),function(){var a=this;"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=Cow||{}),exports.Cow=Cow||{}):a.Cow=Cow||{},Cow.core=function(a){var b=this;"undefined"==typeof a&&(a={}),this._version="2.3.0-rc1",this._herdname=a.herdname||"cow",this._userid=null,this._socketserverid=null,this._projectid=null,this._wsUrl=null,this._peerid=null,this._maxAge=a.maxAge||10368e6,this._autoReconnect=a.autoReconnect||!0,this._localdb=new Cow.localdb({dbname:this._herdname,core:this}),this._projectStore=_.extend(new Cow.syncstore({dbname:"projects",noIDB:!1,noDeltas:!1,core:b,maxAge:this._maxAge}),{_records:[],_recordproto:function(a){return new Cow.project({_id:a,store:this})},_dbname:"projects",_type:"projects"}),this._peerStore=_.extend(new Cow.syncstore({dbname:"peers",noIDB:!0,noDeltas:!0,core:this}),{_records:[],_recordproto:function(a){return new Cow.peer({_id:a,store:this})},_dbname:"peers",_type:"peers",removePeer:function(a){return this._removeRecord(a)}}),this._userStore=_.extend(new Cow.syncstore({dbname:"users",noIDB:!1,noDeltas:!0,core:this}),{_records:[],_recordproto:function(a){return new Cow.user({_id:a,store:this})},_dbname:"users",_type:"users"}),this._socketserverStore=_.extend(new Cow.syncstore({dbname:"socketservers",noIDB:!1,noDeltas:!0,core:this}),{_records:[],_recordproto:function(a){return new Cow.socketserver({_id:a,store:this})},_dbname:"socketservers",_type:"socketservers"}),this._websocket=new Cow.websocket({core:this,url:this._wsUrl}),this._messenger=new Cow.messenger({core:this})},Cow.core.prototype={peerid:function(a){return a?(this._peerid=a.toString(),this._peerid):this._peerid?this._peerid.toString():null},project:function(a){if(a){a=a.toString();var b=this.projects(a);return b?(this._projectid=a,this.peer()&&this.peer().data("activeproject",a).sync(),this.trigger("projectChanged"),!0):(console.warn("Trying to select a non existing project"),!1)}return this._projectid?this.projects(this._projectid):!1},user:function(a){return a?(a=a.toString(),this._userid=a,this.peer()&&this.peers(this.peerid())&&this.peer().data("userid",a).sync(),this.users(a)):this._userid?this.users(this._userid):!1},version:function(){return this._version},socketserver:function(a){return a?(a=a.toString(),this._socketserverid=a,this.socketservers(a)):this._socketserverid?this.socketservers(this._socketserverid):!1},peer:function(){return this.peerid()?this.peers(this.peerid()):!1},location:function(a){return a?(this._location=a,this.peerid()&&this.peers(this.peerid()).data("location",a).sync(),this._location):this._location},projectStore:function(){return this._projectStore},projects:function(a){return this._projectStore.records(a)},peerStore:function(){return this._peerStore},peers:function(a){return this._peerStore.records(a)},socketserverStore:function(){return this._socketserverStore},socketservers:function(a){return this._socketserverStore.records(a)},userStore:function(){return this._userStore},users:function(a){return this._userStore.records(a)},activeUsers:function(){for(var a=[],b=this.peers().filter(function(a){return!a.deleted()}),c=0;c 1 ? dict[phrase] : phrase.charCodeAt(0)); - dict[phrase + currChar] = code; - code++; - phrase=currChar; - } - } - out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0)); - for (var i=0; i 1 ? dict[phrase] : phrase.charCodeAt(0)); - dict[phrase + currChar] = code; - code++; - phrase=currChar; - } - } - out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0)); - for (var i=0; i1?c[f]:f.charCodeAt(0)),c[f+b]=g,g++,f=b);e.push(f.length>1?c[f]:f.charCodeAt(0));for(var h=0;hj?d[i]:c[j]?c[j]:f+e,g.push(b),e=b.charAt(0),c[h]=f+e,h++,f=b}return g.join("")}function encode_utf8(a){return unescape(encodeURIComponent(a))}function decode_utf8(a){try{return decodeURIComponent(escape(a))}catch(b){console.warn(b,a)}}(function(){var a=[],b=(a.push,a.slice),c=(a.splice,{on:function(a,b,c){if(!e(this,"on",a,[b,c])||!b)return this;this._events||(this._events={});var d=this._events[a]||(this._events[a]=[]);return d.push({callback:b,context:c,ctx:c||this}),this},once:function(a,b,c){if(!e(this,"once",a,[b,c])||!b)return this;var d=this,f=_.once(function(){d.off(a,f),b.apply(this,arguments)});return f._callback=b,this.on(a,f,c)},off:function(a,b,c){var d,f,g,h,i,j,k,l;if(!this._events||!e(this,"off",a,[b,c]))return this;if(!a&&!b&&!c)return this._events=void 0,this;for(h=a?[a]:_.keys(this._events),i=0,j=h.length;j>i;i++)if(a=h[i],g=this._events[a]){if(this._events[a]=d=[],b||c)for(k=0,l=g.length;l>k;k++)f=g[k],(b&&b!==f.callback&&b!==f.callback._callback||c&&c!==f.context)&&d.push(f);d.length||delete this._events[a]}return this},trigger:function(a){if(!this._events)return this;var c=b.call(arguments,1);if(!e(this,"trigger",a,c))return this;var d=this._events[a],g=this._events.all;return d&&f(d,c),g&&f(g,arguments),this},stopListening:function(a,b,c){var d=this._listeningTo;if(!d)return this;var e=!b&&!c;c||"object"!=typeof b||(c=this),a&&((d={})[a._listenId]=a);for(var f in d)a=d[f],a.off(b,c,this),(e||_.isEmpty(a._events))&&delete this._listeningTo[f];return this}}),d=/\s+/,e=function(a,b,c,e){if(!c)return!0;if("object"==typeof c){for(var f in c)a[b].apply(a,[f,c[f]].concat(e));return!1}if(d.test(c)){for(var g=c.split(d),h=0,i=g.length;i>h;h++)a[b].apply(a,[g[h]].concat(e));return!1}return!0},f=function(a,b){var c,d=-1,e=a.length,f=b[0],g=b[1],h=b[2];switch(b.length){case 0:for(;++d0&&this._deltas[0].userid&&(a=this._store._core.users(this._deltas[0].userid.toString())),a},updater:function(a){if(a)return this.updater_on(a);if(this._deltas.length>0&&this._deltas[this._deltas.length-1].userid){var b=this._deltas[this._deltas.length-1].userid;return this._store._core.users(b.toString())}return null},updated:function(a){return a?(this._updated=a,this):this._updated},touch:function(){return this.updated((new Date).getTime()),this._dirty=!0,this},deleted:function(a){return void 0!==a&&"boolean"==typeof a?(this._deleted!==a&&(this._deleted=a,this.updated((new Date).getTime()),this._dirty=!0),this):void 0!==a&&"number"==typeof a?this.deleted_on(a):this._deleted},dirty:function(a){return void 0!==a?(this._dirty!==a&&(this._dirty=a,this.updated((new Date).getTime())),this):this._dirty},ttl:function(a){return void 0!==a?(this._ttl!==a&&(this._ttl=a),this):this._ttl},expired:function(){var a=(new Date).getTime()-this.updated();return!!(this._ttl&&a>this._ttl)},data:function(a,b){return a?a&&"object"==typeof a&&!b?(this._data=a,this._deltaq=a,this.dirty(!0),this):a&&"string"==typeof a&&"undefined"==typeof b?this._data[a]:a&&"number"==typeof a&&"undefined"==typeof b?this.data_on(a):a&&"undefined"!=typeof b?("object"==typeof b&&(b=JSON.parse(JSON.stringify(b))),this._data[a]!=b&&(this._data[a]=b,this._deltaq[a]=b,this.dirty(!0)),this):void 0:"object"==typeof this._data?JSON.parse(JSON.stringify(this._data)):this._data},data_on:function(a){if(athis._updated)return this.data();var b={},c=_.sortBy(this.deltas(),function(a){return a.timestamp});return c.forEach(function(c){c.timestamp<=a&&_.extend(b,c.data)}),b},deleted_on:function(a){if(athis._updated)return this.deleted();var b={},c=_.sortBy(this.deltas(),function(a){return a.timestamp});return c.forEach(function(c){c.timestamp<=a&&(b=c.deleted)}),b},updater_on:function(a){if(athis._updated)return this.updater();var b=_.sortBy(this.deltas(),function(a){return a.timestamp});return b.forEach(function(b){b.timestamp<=a}),null},deltas:function(a,b,c,d){if(!a)return this._deltas.sort(function(a,b){return a.timestamp-b.timestamp});if(a&&!b){for(var e=0;ec._ttl&&b.localdb.delRecord({storename:b._storename,projectid:b._projectid,id:c._id})}),b.trigger("datachange"),b._isloaded=!0,a()},function(a){console.warn("DB Fail"),c(a)})},function(a){console.warn("DB Fail"),c(a)}):(b._isloaded=!0,a())}),this.synced=new Promise(function(a,c){b.loaded.then(function(){b.on("synced",function(){a()})}),b.loaded["catch"](function(a){console.error(a.message),c()})})},Cow.syncstore.prototype={_loadFromDb:function(){var a=this;return new Promise(function(b,c){a.localdb.getRecords({storename:a._storename,projectid:a._projectid}).then(function(c){c.forEach(function(b){var c=a._recordproto(b._id);c.inflate(b);for(var d=c.updated(),e=(new Date).getTime(),f=e-d,g=!1,h=0;h=c._updated&&(g=!0);g||!(f<=c._ttl)&&c._ttl?c._ttl&&f>c._ttl&&a.localdb.delRecord({storename:a._storename,projectid:a._projectid,id:c._id}):a._records.push(c)}),a.trigger("datachange"),b()},function(a){console.warn("DB Fail"),c(a)})})},_getRecords:function(a){for(var b=[],c=0;c-1&&b.push(d)}return b},_getRecord:function(a){for(var b=0;b0&&(this._commitqueue.projectid=this._projectid,this.localdb.writeAll(this._commitqueue),this._commitqueue.data=[])},_getRecordsOn:function(a){var b=[];return this._records.forEach(function(c){a=c._updated?b.push(c):c.data(a)&&b.push(c))}),b},records:function(a){return a&&Array.isArray(a)?this._getRecords(a):a&&"object"==typeof a?this._addRecord({source:"UI",data:a}).dirty(!0):a&&"string"==typeof a?this._getRecord(a):a&&"number"==typeof a?this._getRecordsOn(a):this._records},_removeRecord:function(a){for(var b=0;bf._updated&&c.requestlist.push(i._id);var j=d.indexOf(f._id);j>=0&&d.splice(j,1)}}-1!=g||f.deleted()||f.expired()||c.pushlist.push(f.deflate())}}for(e=0;e=0&&e.splice(c,1),this.data("permissions",e),this}throw"type should be a string";case 2:if("string"==typeof a){for(e=this.permissions(),f=0;f=0)if(Array.isArray(b))for(f=0;f=0&&g.splice(c,1)}else{for(c=null,f=0;f=0&&g.splice(c,1)}d.groups=g,this.data("permissions",e)}return this}throw"type should be a string";default:throw"wrong argument number"}}},_.extend(Cow.item.prototype,Cow.record.prototype)}.call(this),function(){var a=this;"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=Cow||{}),exports.Cow=Cow||{}):a.Cow=Cow||{},Cow.project=function(a){var b=this;this._id=a._id||Cow.utils.idgen(),this._store=a.store,this._core=this._store._core,this._maxAge=this._core._maxAge,this._dirty="true",this._ttl=this._store._maxAge,this._deleted=!1,this._created=(new Date).getTime(),this._updated=(new Date).getTime(),this._data={},this._deltaq={},this._deltas=[],this._deltasforupload=[];var c="groups";this._groupStore=_.extend(new Cow.syncstore({dbname:c,noIDB:!1,core:b._core,maxAge:this._maxAge}),{_records:[],_recordproto:function(a){return new Cow.group({_id:a,store:this})},_type:"groups",_dbname:c,_projectid:this._id,dbname:function(a){this._dbname=a}}),c="items",this._itemStore=_.extend(new Cow.syncstore({dbname:c,noIDB:!1,core:b._core,maxAge:this._maxAge}),{_recordproto:function(a){return new Cow.item({_id:a,store:this})},_projectid:this._id,_records:[],_type:"items",_dbname:c,dbname:function(a){this._dbname=a}})},Cow.project.prototype={closed:function(a){if(void 0!==a){this._closed=a;var b=this.deflate();return b.closed=this._closed,this._store._db_write({source:"UI",data:b}),this}return this._closed},groupStore:function(){return this._groupStore},groups:function(a){return this._groupStore.records(a)},itemStore:function(){return this._itemStore},items:function(a){return this._itemStore.records(a)},myGroups:function(){for(var a=this.groups(),b=this._core.user().id(),c=[],d=0;dc&&(b._sendhistory.shift(),b._amountsendhistory.shift()),b._reqhistory.push(b._numreqs),b._amountreqhistory.push(b._amountreq),b._reqhistory.length>c&&(b._reqhistory.shift(),b._amountreqhistory.shift()),b._numsends=0,b._amountsend=0,b._numreqs=0,b._amountreq=0},1e3)},Cow.messenger.prototype.activitylog=function(){return{reqhistory:this._reqhistory,sendhistory:this._sendhistory,amountreqhistory:this._amountreqhistory,amountsendhistory:this._amountsendhistory}},Cow.messenger.prototype.sendData=function(a,b,c){var d={};d.sender=this._core.peerid(),d.target=c,d.action=b,d.payload=lzwCompress.pack(a);var e;try{e=JSON.stringify(d)}catch(f){console.error(f,d)}this.ws.send(e),this._numsends++,this._amountsend=+e.length},Cow.messenger.prototype._onError=function(a){},Cow.messenger.prototype._onMessage=function(a){var b=this._core,c=JSON.parse(a.data),d=c.sender,e=b.peerid(),f=c.action;if("connected"==c.action)c.payload=c.payload;else try{c.payload=lzwCompress.unpack(c.payload)}catch(g){this.trigger("notice","Error in lzwCompress "+g)}var h=c.payload,i=c.target;switch(d!=e&&(this._core.messenger()._numreqs++,this._core.messenger()._amountreq=+a.data.length),f){case"command":d!=e&&this._core.messenger()._onCommand(c);break;case"connected":this._core.messenger()._onConnect(h);break;case"peerGone":this._core.messenger()._onPeerGone(h);break;case"newList":d!=e&&this._core.messenger()._onNewList(h,d);break;case"syncinfo":d!=e&&this._core.messenger()._onSyncinfo(h,d);break;case"wantedList":i==e&&this._core.messenger()._onWantedList(h);break;case"missingRecord":i==e&&this._core.messenger()._onMissingRecord(h);break;case"requestedRecord":d!=e&&this._core.messenger()._onMissingRecord(h);break;case"updatedRecord":d!=e&&this._core.messenger()._onUpdatedRecord(h)}},Cow.messenger.prototype._onConnect=function(a){function b(){console.log("Starting sync"),c._core.projectStore().sync(),c._core.socketserverStore().sync(),c._core.peerStore().sync(),c._core.userStore().sync(),c._core.projectStore().synced.then(function(){for(var a=c._core.projects(),b=0;bh)return c.trigger("notice","Time difference between server and client larger ("+Math.abs(f-g)+"ms) than allowed ("+h+" ms)."),void c.ws.disconnect();if(void 0!==e&&e!=this._core._herdname)return c.trigger("notice","Key on server ("+e+") not the same as client key ("+this._core._herdname+")."),void c.ws.disconnect();this._core.user()&&d.data("userid",this._core.user().id()),d.data("version",this._core.version()),d.deleted(!1).sync(),this.trigger("connected",a);var i=[this._core.socketserverStore().loaded,this._core.peerStore().loaded,this._core.userStore().loaded,this._core.projectStore().loaded];Promise.all(i).then(function(){for(var a=c._core.projects(),d=[],e=0;e0&&this.sendData(d,"wantedList",b),g.pushlist.forEach(function(d){msg={syncType:a.syncType,project:f,record:d},c.sendData(msg,"missingRecord",b)})}},Cow.messenger.prototype._amIAlpha=function(){var a=null,b=this._core.alphaPeer(),c=this._core.peer();return a=c.id()==b.id()},Cow.messenger.prototype._onSyncinfo=function(a){var b=this._getStore(a);b.syncinfo.toReceive=a.syncinfo.IWillSent,b.syncinfo.toSent=a.syncinfo.IShallReceive,b.syncinfo.toReceive.length<1&&b.trigger("synced")},Cow.messenger.prototype._onWantedList=function(a){var b=this,c=this._getStore(a),d=c.requestRecords(a.list);d.forEach(function(d){msg={syncType:a.syncType,project:c._projectid,record:d},b.sendData(msg,"requestedRecord")})},Cow.messenger.prototype._onMissingRecord=function(a){var b=this._getStore(a),c=a.record,d=b._addRecord({source:"WS",data:c});if(b._commit(),b.trigger("datachange"),b.syncinfo.toReceive=_.without(b.syncinfo.toReceive,c._id),b.syncinfo.toReceive.length<1&&b.trigger("synced"),c.deltas&&d.deltas()){var e=_.pluck(d.deltas(),"timestamp"),f=_.pluck(c.deltas,"timestamp"),g=_.difference(e,f);g.length>0&&b.syncRecord(d)}},Cow.messenger.prototype._onUpdatedRecord=function(a){var b=this._getStore(a),c=a.record;b._addRecord({source:"WS",data:c}),b._commit(),b.trigger("datachange")},Cow.messenger.prototype._onCommand=function(a){var b=this._core,c=a.payload,d=c.command,e=c.target;c.params;if(this.trigger("command",a),"kickPeer"==d&&a.target==b.peerid()&&(b.socketserver("invalid"),b.disconnect()),"purgePeer"==d&&e&&e==this._core.peerid()&&(b.projects().forEach(function(a){a.itemStore().clear(),a.groupStore().clear()}),b.projectStore().clear(),b.userStore().clear()),"flushProject"==d){var f,g=c.projectid;b.projects(g)&&(f=b.projects(g),f.itemStore().clear())}"ping"==d&&this.sendData({command:"pong"},"command",a.sender)},_.extend(Cow.messenger.prototype,Events)}.call(this),function(){var a=this;"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=Cow||{}),exports.Cow=Cow||{}):a.Cow=Cow||{},Cow.core=function(a){var b=this;"undefined"==typeof a&&(a={}),this._version="2.3.0-beta",this._herdname=a.herdname||"cow",this._userid=null,this._socketserverid=null,this._projectid=null,this._wsUrl=null,this._peerid=null,this._maxAge=a.maxAge||10368e6,this._autoReconnect=a.autoReconnect||!0,this._localdb=new Cow.localdb({dbname:this._herdname,core:this}),this._projectStore=_.extend(new Cow.syncstore({dbname:"projects",noIDB:!1,noDeltas:!1,core:b,maxAge:this._maxAge}),{_records:[],_recordproto:function(a){return new Cow.project({_id:a,store:this})},_dbname:"projects",_type:"projects"}),this._peerStore=_.extend(new Cow.syncstore({dbname:"peers",noIDB:!0,noDeltas:!0,core:this}),{_records:[],_recordproto:function(a){return new Cow.peer({_id:a,store:this})},_dbname:"peers",_type:"peers",removePeer:function(a){return this._removeRecord(a)}}),this._userStore=_.extend(new Cow.syncstore({dbname:"users",noIDB:!1,noDeltas:!0,core:this}),{_records:[],_recordproto:function(a){return new Cow.user({_id:a,store:this})},_dbname:"users",_type:"users"}),this._socketserverStore=_.extend(new Cow.syncstore({dbname:"socketservers",noIDB:!1,noDeltas:!0,core:this}),{_records:[],_recordproto:function(a){return new Cow.socketserver({_id:a,store:this})},_dbname:"socketservers",_type:"socketservers"}),this._websocket=new Cow.websocket({core:this,url:this._wsUrl}),this._messenger=new Cow.messenger({core:this})},Cow.core.prototype={peerid:function(a){return a?(this._peerid=a.toString(),this._peerid):this._peerid?this._peerid.toString():null},project:function(a){if(a){a=a.toString();var b=this.projects(a);return b?(this._projectid=a,this.peer()&&this.peer().data("activeproject",a).sync(),this.trigger("projectChanged"),!0):(console.warn("Trying to select a non existing project"),!1)}return this._projectid?this.projects(this._projectid):!1},user:function(a){return a?(a=a.toString(),this._userid=a,this.peer()&&this.peers(this.peerid())&&this.peer().data("userid",a).sync(),this.users(a)):this._userid?this.users(this._userid):!1},version:function(){return this._version},socketserver:function(a){return a?(a=a.toString(),this._socketserverid=a,this.socketservers(a)):this._socketserverid?this.socketservers(this._socketserverid):!1},peer:function(){return this.peerid()?this.peers(this.peerid()):!1},location:function(a){return a?(this._location=a,this.peerid()&&this.peers(this.peerid()).data("location",a).sync(),this._location):this._location},projectStore:function(){return this._projectStore},projects:function(a){return this._projectStore.records(a)},peerStore:function(){return this._peerStore},peers:function(a){return this._peerStore.records(a)},socketserverStore:function(){return this._socketserverStore},socketservers:function(a){return this._socketserverStore.records(a)},userStore:function(){return this._userStore},users:function(a){return this._userStore.records(a)},activeUsers:function(){for(var a=[],b=this.peers().filter(function(a){return!a.deleted()}),c=0;ci;i++)if(a=h[i],g=this._events[a]){if(this._events[a]=d=[],b||c)for(k=0,l=g.length;l>k;k++)f=g[k],(b&&b!==f.callback&&b!==f.callback._callback||c&&c!==f.context)&&d.push(f);d.length||delete this._events[a]}return this},trigger:function(a){if(!this._events)return this;var c=b.call(arguments,1);if(!e(this,"trigger",a,c))return this;var d=this._events[a],g=this._events.all;return d&&f(d,c),g&&f(g,arguments),this},stopListening:function(a,b,c){var d=this._listeningTo;if(!d)return this;var e=!b&&!c;c||"object"!=typeof b||(c=this),a&&((d={})[a._listenId]=a);for(var f in d)a=d[f],a.off(b,c,this),(e||_.isEmpty(a._events))&&delete this._listeningTo[f];return this}}),d=/\s+/,e=function(a,b,c,e){if(!c)return!0;if("object"==typeof c){for(var f in c)a[b].apply(a,[f,c[f]].concat(e));return!1}if(d.test(c)){for(var g=c.split(d),h=0,i=g.length;i>h;h++)a[b].apply(a,[g[h]].concat(e));return!1}return!0},f=function(a,b){var c,d=-1,e=a.length,f=b[0],g=b[1],h=b[2];switch(b.length){case 0:for(;++d0&&this._deltas[0].userid&&(a=this._store._core.users(this._deltas[0].userid.toString())),a},updater:function(a){if(a)return this.updater_on(a);if(this._deltas.length>0&&this._deltas[this._deltas.length-1].userid){var b=this._deltas[this._deltas.length-1].userid;return this._store._core.users(b.toString())}return null},updated:function(a){return a?(this._updated=a,this):this._updated},touch:function(){return this.updated((new Date).getTime()),this._dirty=!0,this},deleted:function(a){return void 0!==a&&"boolean"==typeof a?(this._deleted!==a&&(this._deleted=a,this.updated((new Date).getTime()),this._dirty=!0),this):void 0!==a&&"number"==typeof a?this.deleted_on(a):this._deleted},dirty:function(a){return void 0!==a?(this._dirty!==a&&(this._dirty=a,this.updated((new Date).getTime())),this):this._dirty},ttl:function(a){return void 0!==a?(this._ttl!==a&&(this._ttl=a),this):this._ttl},expired:function(){var a=(new Date).getTime()-this.updated();return!!(this._ttl&&a>this._ttl)},data:function(a,b){return a?a&&"object"==typeof a&&!b?(this._data=a,this._deltaq=a,this.dirty(!0),this):a&&"string"==typeof a&&"undefined"==typeof b?this._data[a]:a&&"number"==typeof a&&"undefined"==typeof b?this.data_on(a):a&&"undefined"!=typeof b?("object"==typeof b&&(b=JSON.parse(JSON.stringify(b))),this._data[a]!=b&&(this._data[a]=b,this._deltaq[a]=b,this.dirty(!0)),this):void 0:"object"==typeof this._data?JSON.parse(JSON.stringify(this._data)):this._data},data_on:function(a){if(athis._updated)return this.data();var b={},c=_.sortBy(this.deltas(),function(a){return a.timestamp});return c.forEach(function(c){c.timestamp<=a&&_.extend(b,c.data)}),b},deleted_on:function(a){if(athis._updated)return this.deleted();var b={},c=_.sortBy(this.deltas(),function(a){return a.timestamp});return c.forEach(function(c){c.timestamp<=a&&(b=c.deleted)}),b},updater_on:function(a){if(athis._updated)return this.updater();var b=_.sortBy(this.deltas(),function(a){return a.timestamp});return b.forEach(function(b){b.timestamp<=a}),null},deltas:function(a,b,c,d){if(!a)return this._deltas.sort(function(a,b){return a.timestamp-b.timestamp});if(a&&!b){for(var e=0;ec._ttl&&b.localdb.delRecord({storename:b._storename,projectid:b._projectid,id:c._id})}),b.trigger("datachange"),b._isloaded=!0,a()},function(a){console.warn("DB Fail"),c(a)})},function(a){console.warn("DB Fail"),c(a)}):(b._isloaded=!0,a())}),this.synced=new Promise(function(a,c){b.loaded.then(function(){b.on("synced",function(){a()})}),b.loaded["catch"](function(a){console.error(a.message),c()})})},Cow.syncstore.prototype={_loadFromDb:function(){var a=this;return new Promise(function(b,c){a.localdb.getRecords({storename:a._storename,projectid:a._projectid}).then(function(c){c.forEach(function(b){var c=a._recordproto(b._id);c.inflate(b);for(var d=c.updated(),e=(new Date).getTime(),f=e-d,g=!1,h=0;h=c._updated&&(g=!0);g||!(f<=c._ttl)&&c._ttl?c._ttl&&f>c._ttl&&a.localdb.delRecord({storename:a._storename,projectid:a._projectid,id:c._id}):a._records.push(c)}),a.trigger("datachange"),b()},function(a){console.warn("DB Fail"),c(a)})})},_getRecords:function(a){for(var b=[],c=0;c-1&&b.push(d)}return b},_getRecord:function(a){for(var b=0;b0&&(this._commitqueue.projectid=this._projectid,this.localdb.writeAll(this._commitqueue),this._commitqueue.data=[])},_getRecordsOn:function(a){var b=[];return this._records.forEach(function(c){a=c._updated?b.push(c):c.data(a)&&b.push(c))}),b},records:function(a){return a&&Array.isArray(a)?this._getRecords(a):a&&"object"==typeof a?this._addRecord({source:"UI",data:a}).dirty(!0):a&&"string"==typeof a?this._getRecord(a):a&&"number"==typeof a?this._getRecordsOn(a):this._records},_removeRecord:function(a){for(var b=0;bf._updated&&c.requestlist.push(i._id);var j=d.indexOf(f._id);j>=0&&d.splice(j,1)}}-1!=g||f.deleted()||f.expired()||c.pushlist.push(f.deflate())}}for(e=0;e=0&&e.splice(c,1),this.data("permissions",e),this}throw"type should be a string";case 2:if("string"==typeof a){for(e=this.permissions(),f=0;f=0)if(Array.isArray(b))for(f=0;f=0&&g.splice(c,1)}else{for(c=null,f=0;f=0&&g.splice(c,1)}d.groups=g,this.data("permissions",e)}return this}throw"type should be a string";default:throw"wrong argument number"}}},_.extend(Cow.item.prototype,Cow.record.prototype)}.call(this),function(){var a=this;"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=Cow||{}),exports.Cow=Cow||{}):a.Cow=Cow||{},Cow.project=function(a){var b=this;this._id=a._id||Cow.utils.idgen(),this._store=a.store,this._core=this._store._core,this._maxAge=this._core._maxAge,this._dirty="true",this._ttl=this._store._maxAge,this._deleted=!1,this._created=(new Date).getTime(),this._updated=(new Date).getTime(),this._data={},this._deltaq={},this._deltas=[],this._deltasforupload=[];var c="groups";this._groupStore=_.extend(new Cow.syncstore({dbname:c,noIDB:!1,core:b._core,maxAge:this._maxAge}),{_records:[],_recordproto:function(a){return new Cow.group({_id:a,store:this})},_type:"groups",_dbname:c,_projectid:this._id,dbname:function(a){this._dbname=a}}),c="items",this._itemStore=_.extend(new Cow.syncstore({dbname:c,noIDB:!1,core:b._core,maxAge:this._maxAge}),{_recordproto:function(a){return new Cow.item({_id:a,store:this})},_projectid:this._id,_records:[],_type:"items",_dbname:c,dbname:function(a){this._dbname=a}})},Cow.project.prototype={closed:function(a){if(void 0!==a){this._closed=a;var b=this.deflate();return b.closed=this._closed,this._store._db_write({source:"UI",data:b}),this}return this._closed},groupStore:function(){return this._groupStore},groups:function(a){return this._groupStore.records(a)},itemStore:function(){return this._itemStore},items:function(a){return this._itemStore.records(a)},myGroups:function(){for(var a=this.groups(),b=this._core.user().id(),c=[],d=0;dc&&(b._sendhistory.shift(),b._amountsendhistory.shift()),b._reqhistory.push(b._numreqs),b._amountreqhistory.push(b._amountreq),b._reqhistory.length>c&&(b._reqhistory.shift(),b._amountreqhistory.shift()),b._numsends=0,b._amountsend=0,b._numreqs=0,b._amountreq=0},1e3)},Cow.messenger.prototype.activitylog=function(){return{reqhistory:this._reqhistory,sendhistory:this._sendhistory,amountreqhistory:this._amountreqhistory,amountsendhistory:this._amountsendhistory}},Cow.messenger.prototype.sendData=function(a,b,c){var d={};d.sender=this._core.peerid(),d.target=c,d.action=b,d.payload=lzwCompress.pack(a);var e;try{e=JSON.stringify(d)}catch(f){console.error(f,d)}this.ws.send(e),this._numsends++,this._amountsend=+e.length},Cow.messenger.prototype._onError=function(a){},Cow.messenger.prototype._onMessage=function(a){var b=this._core,c=JSON.parse(a.data),d=c.sender,e=b.peerid(),f=c.action;if("connected"==c.action)c.payload=c.payload;else try{c.payload=lzwCompress.unpack(c.payload)}catch(g){this.trigger("notice","Error in lzwCompress "+g)}var h=c.payload,i=c.target;switch(d!=e&&(this._core.messenger()._numreqs++,this._core.messenger()._amountreq=+a.data.length),f){case"command":d!=e&&this._core.messenger()._onCommand(c);break;case"connected":this._core.messenger()._onConnect(h);break;case"peerGone":this._core.messenger()._onPeerGone(h);break;case"newList":d!=e&&this._core.messenger()._onNewList(h,d);break;case"syncinfo":d!=e&&this._core.messenger()._onSyncinfo(h,d);break;case"wantedList":i==e&&this._core.messenger()._onWantedList(h);break;case"missingRecord":i==e&&this._core.messenger()._onMissingRecord(h);break;case"requestedRecord":d!=e&&this._core.messenger()._onMissingRecord(h);break;case"updatedRecord":d!=e&&this._core.messenger()._onUpdatedRecord(h)}},Cow.messenger.prototype._onConnect=function(a){function b(){console.log("Starting sync"),c._core.projectStore().sync(),c._core.socketserverStore().sync(),c._core.peerStore().sync(),c._core.userStore().sync(),c._core.projectStore().synced.then(function(){for(var a=c._core.projects(),b=0;bh)return c.trigger("notice","Time difference between server and client larger ("+Math.abs(f-g)+"ms) than allowed ("+h+" ms)."),void c.ws.disconnect();if(void 0!==e&&e!=this._core._herdname)return c.trigger("notice","Key on server ("+e+") not the same as client key ("+this._core._herdname+")."),void c.ws.disconnect();this._core.user()&&d.data("userid",this._core.user().id()),d.data("version",this._core.version()),d.deleted(!1).sync(),this.trigger("connected",a);var i=[this._core.socketserverStore().loaded,this._core.peerStore().loaded,this._core.userStore().loaded,this._core.projectStore().loaded];Promise.all(i).then(function(){for(var a=c._core.projects(),d=[],e=0;e0&&this.sendData(d,"wantedList",b),g.pushlist.forEach(function(d){msg={syncType:a.syncType,project:f,record:d},c.sendData(msg,"missingRecord",b)})}},Cow.messenger.prototype._amIAlpha=function(){var a=null,b=this._core.alphaPeer(),c=this._core.peer();return a=c.id()==b.id()},Cow.messenger.prototype._onSyncinfo=function(a){var b=this._getStore(a);b.syncinfo.toReceive=a.syncinfo.IWillSent,b.syncinfo.toSent=a.syncinfo.IShallReceive,b.syncinfo.toReceive.length<1&&b.trigger("synced")},Cow.messenger.prototype._onWantedList=function(a){var b=this,c=this._getStore(a),d=c.requestRecords(a.list); +d.forEach(function(d){msg={syncType:a.syncType,project:c._projectid,record:d},b.sendData(msg,"requestedRecord")})},Cow.messenger.prototype._onMissingRecord=function(a){var b=this._getStore(a),c=a.record,d=b._addRecord({source:"WS",data:c});if(b._commit(),b.trigger("datachange"),b.syncinfo.toReceive=_.without(b.syncinfo.toReceive,c._id),b.syncinfo.toReceive.length<1&&b.trigger("synced"),c.deltas&&d.deltas()){var e=_.pluck(d.deltas(),"timestamp"),f=_.pluck(c.deltas,"timestamp"),g=_.difference(e,f);g.length>0&&b.syncRecord(d)}},Cow.messenger.prototype._onUpdatedRecord=function(a){var b=this._getStore(a),c=a.record;b._addRecord({source:"WS",data:c}),b._commit(),b.trigger("datachange")},Cow.messenger.prototype._onCommand=function(a){var b=this._core,c=a.payload,d=c.command,e=c.target;c.params;if(this.trigger("command",a),"kickPeer"==d&&a.target==b.peerid()&&(b.socketserver("invalid"),b.disconnect()),"purgePeer"==d&&e&&e==this._core.peerid()&&(b.projects().forEach(function(a){a.itemStore().clear(),a.groupStore().clear()}),b.projectStore().clear(),b.userStore().clear()),"flushProject"==d){var f,g=c.projectid;b.projects(g)&&(f=b.projects(g),f.itemStore().clear())}"ping"==d&&this.sendData({command:"pong"},"command",a.sender)},_.extend(Cow.messenger.prototype,Events)}.call(this),function(){var a=this;"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=Cow||{}),exports.Cow=Cow||{}):a.Cow=Cow||{},Cow.core=function(a){var b=this;"undefined"==typeof a&&(a={}),this._version="2.3.0-rc1",this._herdname=a.herdname||"cow",this._userid=null,this._socketserverid=null,this._projectid=null,this._wsUrl=null,this._peerid=null,this._maxAge=a.maxAge||10368e6,this._autoReconnect=a.autoReconnect||!0,this._localdb=new Cow.localdb({dbname:this._herdname,core:this}),this._projectStore=_.extend(new Cow.syncstore({dbname:"projects",noIDB:!1,noDeltas:!1,core:b,maxAge:this._maxAge}),{_records:[],_recordproto:function(a){return new Cow.project({_id:a,store:this})},_dbname:"projects",_type:"projects"}),this._peerStore=_.extend(new Cow.syncstore({dbname:"peers",noIDB:!0,noDeltas:!0,core:this}),{_records:[],_recordproto:function(a){return new Cow.peer({_id:a,store:this})},_dbname:"peers",_type:"peers",removePeer:function(a){return this._removeRecord(a)}}),this._userStore=_.extend(new Cow.syncstore({dbname:"users",noIDB:!1,noDeltas:!0,core:this}),{_records:[],_recordproto:function(a){return new Cow.user({_id:a,store:this})},_dbname:"users",_type:"users"}),this._socketserverStore=_.extend(new Cow.syncstore({dbname:"socketservers",noIDB:!1,noDeltas:!0,core:this}),{_records:[],_recordproto:function(a){return new Cow.socketserver({_id:a,store:this})},_dbname:"socketservers",_type:"socketservers"}),this._websocket=new Cow.websocket({core:this,url:this._wsUrl}),this._messenger=new Cow.messenger({core:this})},Cow.core.prototype={peerid:function(a){return a?(this._peerid=a.toString(),this._peerid):this._peerid?this._peerid.toString():null},project:function(a){if(a){a=a.toString();var b=this.projects(a);return b?(this._projectid=a,this.peer()&&this.peer().data("activeproject",a).sync(),this.trigger("projectChanged"),!0):(console.warn("Trying to select a non existing project"),!1)}return this._projectid?this.projects(this._projectid):!1},user:function(a){return a?(a=a.toString(),this._userid=a,this.peer()&&this.peers(this.peerid())&&this.peer().data("userid",a).sync(),this.users(a)):this._userid?this.users(this._userid):!1},version:function(){return this._version},socketserver:function(a){return a?(a=a.toString(),this._socketserverid=a,this.socketservers(a)):this._socketserverid?this.socketservers(this._socketserverid):!1},peer:function(){return this.peerid()?this.peers(this.peerid()):!1},location:function(a){return a?(this._location=a,this.peerid()&&this.peers(this.peerid()).data("location",a).sync(),this._location):this._location},projectStore:function(){return this._projectStore},projects:function(a){return this._projectStore.records(a)},peerStore:function(){return this._peerStore},peers:function(a){return this._peerStore.records(a)},socketserverStore:function(){return this._socketserverStore},socketservers:function(a){return this._socketserverStore.records(a)},userStore:function(){return this._userStore},users:function(a){return this._userStore.records(a)},activeUsers:function(){for(var a=[],b=this.peers().filter(function(a){return!a.deleted()}),c=0;c 1 ? dict[phrase] : phrase.charCodeAt(0)); - dict[phrase + currChar] = code; - code++; - phrase=currChar; - } - } - out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0)); - for (var i=0; iConsole