浏览代码

[bugfix] do not scroll when clicking a room id
[add] prepend ... before typing users
[bugfix] restore avatar when combo-ing /me messages and messages
[add] animate typing ...
[bugfix] updating message change its version
[add] standards messages now sent through RTM ws

B Thibault 8 年之前
父节点
当前提交
793dcd0b55
共有 12 个文件被更改,包括 155 次插入98 次删除
  1. 2 2
      cli/data.js
  2. 15 2
      cli/dom.js
  3. 0 5
      cli/lang/en.js
  4. 0 5
      cli/lang/fr.js
  5. 16 10
      cli/ui.js
  6. 2 2
      cli/workflow.js
  7. 1 1
      srv/public/index.html
  8. 60 60
      srv/public/slack.min.js
  9. 20 1
      srv/public/style.css
  10. 7 2
      srv/src/message.js
  11. 29 6
      srv/src/slack.js
  12. 3 2
      srv/src/slackHistory.js

+ 2 - 2
cli/data.js

@@ -114,7 +114,7 @@ function onMsgReceived(chan, msg) {
         });
         if (areNew) {
             updateTitle();
-            var dom = document.getElementById(chan.id);
+            var dom = document.getElementById("room_" +chan.id);
             if (dom) {
                 dom.classList.add(R.klass.unread);
                 if (highligted)
@@ -141,7 +141,7 @@ function markRoomAsRead(room) {
         HIGHLIGHTED_CHANS.splice(highlightIndex, 1);
         updateTitle();
     }
-    var roomLi = document.getElementById(room.id);
+    var roomLi = document.getElementById("room_" +room.id);
     roomLi.classList.remove(R.klass.unread);
     roomLi.classList.remove(R.klass.unreadHi);
 }

+ 15 - 2
cli/dom.js

@@ -29,7 +29,7 @@ function createChanListItem(chan) {
     var dom = document.createElement("li")
         ,link = document.createElement("a");
 
-    dom.id = chan.id;
+    dom.id = "room_" +chan.id;
     link.href = '#' +chan.id;
     if (chan.isPrivate) {
         dom.className = R.klass.chatList.entry + " " +R.klass.chatList.typePrivate;
@@ -58,7 +58,7 @@ function createImsListItem(ims) {
     var dom = document.createElement("li")
         ,link = document.createElement("a");
 
-    dom.id = ims.id;
+    dom.id = "room_" +ims.id;
     link.href = '#' +ims.id;
     dom.className = R.klass.chatList.entry + " " +R.klass.chatList.typeDirect;
     link.textContent = ims.user.name;
@@ -384,6 +384,19 @@ function createAttachmentDom(channelId, msg, attachment) {
     return rootDom;
 }
 
+/**
+ * @param {Chatter} user
+ * @return {Element}
+**/
+function makeUserIsTypingDom(user) {
+    var dom = document.createElement("li")
+        ,userName = document.createElement("span");
+    userName.textContent = user.name;
+    dom.appendChild(createTypingDisplay());
+    dom.appendChild(userName);
+    return dom;
+}
+
 /**
  * @param {string} servicename
  * @return {Element}

+ 0 - 5
cli/lang/en.js

@@ -6,11 +6,6 @@ lang["en"] = {
     ,edited: "edited"
     ,onlyVisible: "(only visible to you)"
 
-    ,areTyping: function(names) {
-        if (names.length === 1)
-            return names[0] +" is typing";
-        return names.join(", ") +" are typing";
-    }
     ,formatDate: function(ts) {
         if (typeof(ts) !== "string")
             ts = parseFloat(ts);

+ 0 - 5
cli/lang/fr.js

@@ -6,11 +6,6 @@ lang["fr"] = {
     ,edited: "edité"
     ,onlyVisible: "(visible seulement par vous)"
 
-    ,areTyping: function(names) {
-        if (names.length === 1)
-            return names[0] +" est en train d'écrire";
-        return names.join(", ") +" sont en train d'écrire";
-    }
     ,formatDate: function(ts) {
         if (typeof(ts) !== "string")
             ts = parseFloat(ts);

+ 16 - 10
cli/ui.js

@@ -81,7 +81,7 @@ function onTypingUpdated() {
     var typing = SLACK.context.typing;
     for (var chanId in SLACK.context.self.channels) {
         if (!SLACK.context.self.channels[chanId].archived) {
-            var dom = document.getElementById(chanId);
+            var dom = document.getElementById("room_" +chanId);
             if (typing[chanId])
                 dom.classList.add(R.klass.chatList.typing);
             else
@@ -91,7 +91,7 @@ function onTypingUpdated() {
     for (var userId in SLACK.context.users) {
         var ims = SLACK.context.users[userId].privateRoom;
         if (ims && !ims.archived) {
-            var dom = document.getElementById(ims.id);
+            var dom = document.getElementById("room_" +ims.id);
             if (typing[ims.id])
                 dom.classList.add(R.klass.chatList.typing);
             else
@@ -103,20 +103,20 @@ function onTypingUpdated() {
 
 function updateTypingChat() {
     var typing = SLACK.context.typing;
+    document.getElementById(R.id.typing).textContent = "";
     if (SELECTED_ROOM && typing[SELECTED_ROOM.id]) {
-        var typingUserNames = [], isOutOfSync = false;
+        var areTyping = document.createDocumentFragment()
+            ,isOutOfSync = false;
         for (var i in typing[SELECTED_ROOM.id]) {
             var member = SLACK.context.users[i];
             if (member)
-                typingUserNames.push(member.name);
+                areTyping.appendChild(makeUserIsTypingDom(member));
             else
                 isOutOfSync = true;
         }
         if (isOutOfSync)
             outOfSync();
-        document.getElementById(R.id.typing).textContent = locale.areTyping(typingUserNames);
-    } else {
-        document.getElementById(R.id.typing).textContent = "";
+        document.getElementById(R.id.typing).appendChild(areTyping);
     }
 }
 
@@ -135,7 +135,7 @@ function onRoomSelected() {
         });
         name = members.join(", ");
     }
-    var roomLi = document.getElementById(SELECTED_ROOM.id);
+    var roomLi = document.getElementById("room_" +SELECTED_ROOM.id);
     document.getElementById(R.id.currentRoom.title).textContent = name;
     onRoomUpdated();
     focusInput();
@@ -521,8 +521,14 @@ function onRoomUpdated() {
                     firstTsCombo = msg.ts;
                 if ((!prevMsg || prevMsg.ts <= SELECTED_ROOM.lastRead) && msg.ts > SELECTED_ROOM.lastRead)
                     dom.classList.add(R.klass.msg.firstUnread);
-                prevMsg = msg;
-                prevMsgDom = dom;
+                if (msg instanceof MeMessage) {
+                    prevMsg = null;
+                    prevMsgDom = null;
+                    firstTsCombo = 0;
+                } else {
+                    prevMsg = msg;
+                    prevMsgDom = dom;
+                }
                 chatFrag.appendChild(dom);
             }
         });

+ 2 - 2
cli/workflow.js

@@ -109,7 +109,7 @@ function startPolling() {
 function selectRoom(room) {
     if (SELECTED_ROOM)
         unselectRoom();
-    document.getElementById(room.id).classList.add(R.klass.selected);
+    document.getElementById("room_" +room.id).classList.add(R.klass.selected);
     document.body.classList.remove(R.klass.noRoomSelected);
     SELECTED_ROOM = room;
     onRoomSelected();
@@ -118,7 +118,7 @@ function selectRoom(room) {
 }
 
 function unselectRoom() {
-    document.getElementById(SELECTED_ROOM.id).classList.remove(R.klass.selected);
+    document.getElementById("room_" +SELECTED_ROOM.id).classList.remove(R.klass.selected);
 }
 
 /**

+ 1 - 1
srv/public/index.html

@@ -17,7 +17,7 @@
         <div class="slack-chat-container">
             <div class="slack-chat-title" id="currentRoomTitle"></div>
             <div class="slack-chat-content" id="chatWindow"></div>
-            <div class="slack-chat-whoistyping" id="whoistyping"></div>
+            <ul class="slack-chat-whoistyping" id="whoistyping"></ul>
             <div id="replyToContainer" class="replyto-container"></div>
             <ul id="slashList" class="slack-command-list"></ul>
             <div class="slack-chat-control">

+ 60 - 60
srv/public/slack.min.js

@@ -1,71 +1,71 @@
-function m(a){this.id=a;this.version=0}m.prototype.update=function(a,b){void 0!==a.name&&(this.name=a.name);this.version=Math.max(this.version,b)};function r(a){this.a=a.desc;this.name=a.name;this.type=a.type;this.usage=a.usage;this.u=a.category}function x(){this.b={};this.a=[]}
-x.prototype.update=function(a,b){this.b=JSON.parse(a.emoji_use);a.highlight_words?this.a=(a.highlight_words||"").split(",").filter(function(a){return""!==a.trim()}):a.highlights&&(this.a=a.highlights);this.version=Math.max(this.version,b)};function aa(){this.j=null;this.b={};this.a={};this.c=null;this.i={version:0,data:{}};this.g={version:0,data:{}};this.f={};this.A=0}"undefined"!==typeof module&&(module.s.M=aa,module.s.N=m,module.s.P=r);function y(a){this.id=a;this.i=!1;this.a=this.b=0;this.f={};this.version=0}
-y.prototype.update=function(a,b,c){void 0!==a.name&&(this.name=a.name);void 0!==a.is_archived&&(this.g=a.is_archived);void 0!==a.last_read&&(this.b=Math.max(parseFloat(a.last_read),this.b));void 0!==a.last_msg&&(this.a=parseFloat(a.last_msg));void 0!==a.is_private&&(this.j=a.is_private);a.latest&&(this.a=parseFloat(a.latest.ts));void 0!==a.is_starred&&(this.i=a.is_starred);if(a.members&&(this.f={},a.members))for(var d=0,f=a.members.length;d<f;d++){var e=b.a[a.members[d]];this.f[e.id]=e;e.c[this.id]=
-this}this.version=Math.max(this.version,c)};function A(a,b){y.call(this,a);this.c=b;this.name=this.c.name;this.j=!0;b.g=this}A.prototype=Object.create(y.prototype);A.prototype.constructor=A;"undefined"!==typeof module&&(module.s.V=y,module.s.U=A);function B(a,b){this.m=a.user;this.f=a.userName;this.id=a.id||a.ts;this.h=parseFloat(a.ts);this.text="";this.c=[];this.b=this.o=!1;this.a={};this.version=b;this.update(a,b)}function E(a,b){B.call(this,a,b)}function F(a,b){B.call(this,a,b)}
-B.prototype.update=function(a,b){if(a){this.text=a.text||"";a.attachments&&(this.c=a.attachments);this.o=!!a.edited;this.b=!!a.removed;var c=this;this.a={};(a.reactions||[]).forEach(function(a){c.a[a.name]=[];a.users.forEach(function(b){c.a[a.name].push(b)})})}else this.b=!0;this.version=b};function ba(a,b,c,d){this.id="string"===typeof a?a:a.id;this.a=[];this.b=b;c&&ca(this,c,d)}function ca(a,b,c){var d=0;b.forEach(function(a){d=Math.max(da(this,a,c),d)}.bind(a));ea(a)}
-function da(a,b,c){for(var d=!1,f,e=0,k=a.a.length;e<k;e++){var g=a.a[e];if(g.id===b.id){f=g.update(b,c);d=!0;break}}d||(g=!0===b.isMeMessage?new E(b,c):!0===b.isNotice?new F(b,c):new B(b,c),a.a.push(g),f=g.h);for(;a.a.length>a.b;)a.a.shift();return f||0}function fa(a){for(var b=G.b[H.id],c=0,d=b.a.length;c<d&&a>=b.a[c].h;c++)if(b.a[c].h===a)return b.a[c];return null}function ea(a){a.a.sort(function(a,c){return a.h-c.h})}E.prototype=Object.create(B.prototype);E.prototype.constructor=E;
-F.prototype=Object.create(B.prototype);F.prototype.constructor=F;"undefined"!==typeof module&&(module.s={S:B,R:E,T:F,W:ba});function I(a){this.id=a;this.b={small:"",L:""};this.c={};this.g=this.a=null;this.version=0}I.prototype.update=function(a,b){void 0!==a.name&&(this.name=a.name);void 0!==a.deleted&&(this.i=a.deleted);void 0!==a.status&&(this.status=a.status);void 0!==a.presence&&(this.f="away"!==a.presence);void 0!==a.isPresent&&(this.f=a.isPresent);a.isBot&&(this.A=a.isBot);a.profile&&(this.b.small=a.profile.icon_small,this.b.L=a.profile.icon_large);this.version=Math.max(this.version,b)};
-"undefined"!==typeof module&&(module.s.O=I);var J={},K;function ga(){var a;if(!a){for(var b=0,c=navigator.languages.length;b<c;b++)if(J.hasOwnProperty(navigator.languages[b])){a=navigator.languages[b];break}a||(a="en")}K=J[a];console.log("Loading language pack: "+a);if(K.l)for(b in K.l)document.getElementById(b).textContent=K.l[b]};J.fr={K:"Utilisateur inconnu",J:"Channel inconnu",F:"Nouveau message",D:"Reseau",o:"edit&eacute;",G:"(visible seulement par vous)",C:function(a){return 1===a.length?a[0]+" est en train d'\u00e9crire":a.join(", ")+" sont en train d'\u00e9crire"},B:function(a){"string"!==typeof a&&(a=parseFloat(a));var b=new Date,c=new Date;a=new Date(1E3*a);b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0);c.setTime(b.getTime());c.setDate(c.getDate()-1);return a.getTime()>b.getTime()?a.toLocaleTimeString():
-a.getTime()>c.getTime()?"hier, "+a.toLocaleTimeString():a.toLocaleString()},l:{fileUploadCancel:"Annuler",neterror:"Impossible de se connecter au chat !"}};J.en={K:"Unknown member",J:"Unknown channel",F:"New message",D:"Network",o:"edited",G:"(only visible to you)",C:function(a){return 1===a.length?a[0]+" is typing":a.join(", ")+" are typing"},B:function(a){"string"!==typeof a&&(a=parseFloat(a));var b=new Date,c=new Date;a=new Date(1E3*a);b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0);c.setTime(b.getTime());c.setDate(c.getDate()-1);return a.getTime()>b.getTime()?a.toLocaleTimeString():a.getTime()>c.getTime()?"yesterday, "+a.toLocaleTimeString():
-a.toLocaleString()},l:{fileUploadCancel:"Cancel",neterror:"Cannot connect to chat !"}};var L=0;
-function ha(){var a=document.createDocumentFragment(),b=Object.keys(G.a.b||{}),c=[],d=[],f=[],e=[];b.sort(function(a,b){return a[0]!==b[0]?a[0]-b[0]:G.a.b[a].name.localeCompare(G.a.b[b].name)});b.forEach(function(a){a=G.a.b[a];if(!a.g)if(a instanceof A){var b;b=document.createElement("li");var k=document.createElement("a");b.id=a.id;k.href="#"+a.id;b.className="slack-context-room slack-ims";k.textContent=a.c.name;b.appendChild(ia());b.appendChild(k);a.c.f||b.classList.add("away");H===a&&b.classList.add("selected");a.a>
-a.b&&(b.classList.add("unread"),0<=M.indexOf(a)&&b.classList.add("unreadHi"));b&&(a.i?c.push(b):e.push(b))}else b=document.createElement("li"),k=document.createElement("a"),b.id=a.id,k.href="#"+a.id,a.j?(b.className="slack-context-room slack-group",b.dataset.count=Object.keys(a.f||{}).length):b.className="slack-context-room slack-channel",H===a&&b.classList.add("selected"),k.textContent=a.name,b.appendChild(ia()),b.appendChild(k),a.a>a.b&&(b.classList.add("unread"),0<=M.indexOf(a)&&b.classList.add("unreadHi")),
-b&&(a.i?c.push(b):a.j?f.push(b):d.push(b))});c.forEach(function(b){a.appendChild(b)});d.forEach(function(b){a.appendChild(b)});f.forEach(function(b){a.appendChild(b)});e.forEach(function(b){a.appendChild(b)});document.getElementById("chanList").textContent="";document.getElementById("chanList").appendChild(a);ja();N();ka(function(a){document.getElementById("slackCtx").style.backgroundImage="url("+a+")"})}
-function la(){var a=G.a.f,b;for(b in G.a.c.c)if(!G.a.c.c[b].g){var c=document.getElementById(b);a[b]?c.classList.add("slack-context-typing"):c.classList.remove("slack-context-typing")}for(var d in G.a.a)(b=G.a.a[d].g)&&!b.g&&(c=document.getElementById(b.id),a[b.id]?c.classList.add("slack-context-typing"):c.classList.remove("slack-context-typing"));ma()}
-function ma(){var a=G.a.f;if(H&&a[H.id]){var b=[],c=!1,d;for(d in a[H.id])(a=G.a.a[d])?b.push(a.name):c=!0;c&&(G.c=0);document.getElementById("whoistyping").textContent=K.C(b)}else document.getElementById("whoistyping").textContent=""}function O(a){a?document.body.classList.remove("no-network"):document.body.classList.add("no-network");N()}
-function na(){var a=H.name||(H.c?H.c.name:void 0);if(!a){var b=[];H.f.forEach(function(a){b.push(a.name)});a=b.join(", ")}document.getElementById("currentRoomTitle").textContent=a;oa();P();document.getElementById("fileUploadContainer").classList.add("hidden");Q();R&&(R=null,S());T&&(T=null,S());ma()}
-function S(){if(R){document.body.classList.add("replyingTo");var a=document.getElementById("replyToContainer"),b=document.createElement("a");b.addEventListener("click",function(){R=null;S()});b.className="replyto-close";b.textContent="x";a.textContent="";a.appendChild(b);a.appendChild(U("reply_"+H.id,R,!0))}else document.body.classList.remove("replyingTo"),document.getElementById("replyToContainer").textContent="";P()}
-function V(){if(T){document.body.classList.add("replyingTo");var a=document.getElementById("replyToContainer"),b=document.createElement("a");b.addEventListener("click",function(){T=null;V()});b.className="replyto-close";b.textContent="x";a.textContent="";a.appendChild(b);a.appendChild(U("edit_"+H.id,T,!0));document.getElementById("msgInput").value=T.text}else document.body.classList.remove("replyingTo"),document.getElementById("replyToContainer").textContent="";P()}
-window.toggleReaction=function(a,b,c){var d=G.b[a];if(d){a:{for(var f=0,e=d.a.length;f<e;f++)if(d.a[f].id==b){d=d.a[f];break a}d=null}d&&(f=G.a.c.id,d.a[c]&&-1!==d.a[c].indexOf(f)?(d=new XMLHttpRequest,d.open("DELETE","api/reaction?room="+a+"&msg="+b+"&reaction="+encodeURIComponent(c),!0),d.send(null)):pa(a,b,c))}};
-function qa(a){a:{for(var b=a,c={};!c[b];){if(a=G.a.i.data[b])if("alias:"==a.substr(0,6))c[b]=!0,b=a.substr(6);else{b=document.createElement("span");b.className="emoji-custom emoji";b.style.backgroundImage="url('"+a+"')";a=b;break a}break}a=b}"string"===typeof a&&"makeEmoji"in window&&(a=window.makeEmoji(a));return"string"===typeof a?null:a}
-function ra(a){return a.replace(/:([^ \t:]+):/g,function(b,c){var d=qa(c);if(d){var f=document.createElement("span");f.className=b===a?"emoji-medium":"emoji-small";f.appendChild(d);return f.outerHTML}return b})}
-function W(a){a=a.split(/\r?\n/g);for(var b=0,c=a.length;b<c;b++){for(var d=a[b].trim(),f="",e={},k=!1,g=0,d=d.replace(RegExp("<([@#]?)([^>]*)>","g"),function(a,b,c){c=c.split("|");if("@"===b)c[1]?"@"!==c[1][0]&&(c[1]="@"+c[1]):(a=G.a.a[c[0]],c[1]=a?"@"+a.name:K.K),c[0]="#"+c[0],c[2]="slackmsg-link slackmsg-link-user";else if("#"===b)c[1]?"#"!==c[1][0]&&(c[1]="#"+c[1]):(a=G.a.b[c[0]],c[1]=a?"#"+a.name:K.J),c[0]="#"+c[0],c[2]="slackmsg-link slackmsg-link-chan";else if(-1!==c[0].indexOf("://"))c[1]||
-(c[1]=c[0]),c[2]="slackmsg-link";else return a;return'<a href="'+c[0]+'" class="'+c[2]+'"'+(b?"":' target="_blank"')+">"+c[1]+"</a>"}),d=ra(d),l=d.length,n=function(a,b,c){for(;a[b];){var d=a[b];if(("A"<=d&&"Z">=d||"a"<=d&&"z">=d||"0"<=d&&"9">=d||-1!=="\u00e0\u00e8\u00ec\u00f2\u00f9\u00c0\u00c8\u00cc\u00d2\u00d9\u00e1\u00e9\u00ed\u00f3\u00fa\u00fd\u00c1\u00c9\u00cd\u00d3\u00da\u00dd\u00e2\u00ea\u00ee\u00f4\u00fb\u00c2\u00ca\u00ce\u00d4\u00db\u00e3\u00f1\u00f5\u00c3\u00d1\u00d5\u00e4\u00eb\u00ef\u00f6\u00fc\u00ff\u00c4\u00cb\u00cf\u00d6\u00dc\u0178\u00e7\u00c7\u00df\u00d8\u00f8\u00c5\u00e5\u00c6\u00e6\u0153".indexOf(d))&&
+function m(a){this.id=a;this.version=0}m.prototype.update=function(a,b){void 0!==a.name&&(this.name=a.name);this.version=Math.max(this.version,b)};function r(a){this.a=a.desc;this.name=a.name;this.type=a.type;this.usage=a.usage;this.u=a.category}function aa(){this.b={};this.a=[]}
+aa.prototype.update=function(a,b){this.b=JSON.parse(a.emoji_use);a.highlight_words?this.a=(a.highlight_words||"").split(",").filter(function(a){return""!==a.trim()}):a.highlights&&(this.a=a.highlights);this.version=Math.max(this.version,b)};function ba(){this.j=null;this.b={};this.a={};this.c=null;this.i={version:0,data:{}};this.g={version:0,data:{}};this.f={};this.A=0}"undefined"!==typeof module&&(module.s.L=ba,module.s.M=m,module.s.O=r);function x(a){this.id=a;this.i=!1;this.a=this.b=0;this.f={};this.version=0}
+x.prototype.update=function(a,b,c){void 0!==a.name&&(this.name=a.name);void 0!==a.is_archived&&(this.g=a.is_archived);void 0!==a.last_read&&(this.b=Math.max(parseFloat(a.last_read),this.b));void 0!==a.last_msg&&(this.a=parseFloat(a.last_msg));void 0!==a.is_private&&(this.j=a.is_private);a.latest&&(this.a=parseFloat(a.latest.ts));void 0!==a.is_starred&&(this.i=a.is_starred);if(a.members&&(this.f={},a.members))for(var d=0,f=a.members.length;d<f;d++){var e=b.a[a.members[d]];this.f[e.id]=e;e.c[this.id]=
+this}this.version=Math.max(this.version,c)};function y(a,b){x.call(this,a);this.c=b;this.name=this.c.name;this.j=!0;b.g=this}y.prototype=Object.create(x.prototype);y.prototype.constructor=y;"undefined"!==typeof module&&(module.s.U=x,module.s.T=y);function A(a,b){this.m=a.user;this.f=a.userName;this.id=a.id||a.ts;this.h=parseFloat(a.ts);this.text="";this.c=[];this.b=this.o=!1;this.a={};this.version=b;this.update(a,b)}function B(a,b){A.call(this,a,b)}function E(a,b){A.call(this,a,b)}
+A.prototype.update=function(a,b){if(a){this.text=a.text||"";a.attachments&&(this.c=a.attachments);this.o=!!a.edited;this.b=!!a.removed;var c=this;this.a={};(a.reactions||[]).forEach(function(a){c.a[a.name]=[];a.users.forEach(function(b){c.a[a.name].push(b)})})}else this.b=!0;this.version=b};function ca(a,b,c,d){this.id="string"===typeof a?a:a.id;this.a=[];this.b=b;c&&da(this,c,d)}function da(a,b,c){var d=0;b.forEach(function(a){d=Math.max(ea(this,a,c),d)}.bind(a));fa(a)}
+function ea(a,b,c){for(var d=!1,f,e=0,k=a.a.length;e<k;e++){var g=a.a[e];if(g.id===b.id){f=g.update(b,c);d=!0;break}}d||(g=!0===b.isMeMessage?new B(b,c):!0===b.isNotice?new E(b,c):new A(b,c),a.a.push(g),f=g.h);for(;a.a.length>a.b;)a.a.shift();return f||0}function ga(a){for(var b=F.b[G.id],c=0,d=b.a.length;c<d&&a>=b.a[c].h;c++)if(b.a[c].h===a)return b.a[c];return null}function fa(a){a.a.sort(function(a,c){return a.h-c.h})}B.prototype=Object.create(A.prototype);B.prototype.constructor=B;
+E.prototype=Object.create(A.prototype);E.prototype.constructor=E;"undefined"!==typeof module&&(module.s={R:A,P:B,S:E,V:ca});function H(a){this.id=a;this.b={small:"",K:""};this.c={};this.g=this.a=null;this.version=0}H.prototype.update=function(a,b){void 0!==a.name&&(this.name=a.name);void 0!==a.deleted&&(this.i=a.deleted);void 0!==a.status&&(this.status=a.status);void 0!==a.presence&&(this.f="away"!==a.presence);void 0!==a.isPresent&&(this.f=a.isPresent);a.isBot&&(this.A=a.isBot);a.profile&&(this.b.small=a.profile.icon_small,this.b.K=a.profile.icon_large);this.version=Math.max(this.version,b)};
+"undefined"!==typeof module&&(module.s.N=H);var I={},J;function ha(){var a;if(!a){for(var b=0,c=navigator.languages.length;b<c;b++)if(I.hasOwnProperty(navigator.languages[b])){a=navigator.languages[b];break}a||(a="en")}J=I[a];console.log("Loading language pack: "+a);if(J.l)for(b in J.l)document.getElementById(b).textContent=J.l[b]};I.fr={J:"Utilisateur inconnu",I:"Channel inconnu",D:"Nouveau message",C:"Reseau",o:"edit&eacute;",F:"(visible seulement par vous)",B:function(a){"string"!==typeof a&&(a=parseFloat(a));var b=new Date,c=new Date;a=new Date(1E3*a);b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0);c.setTime(b.getTime());c.setDate(c.getDate()-1);return a.getTime()>b.getTime()?a.toLocaleTimeString():a.getTime()>c.getTime()?"hier, "+a.toLocaleTimeString():a.toLocaleString()},l:{fileUploadCancel:"Annuler",
+neterror:"Impossible de se connecter au chat !"}};I.en={J:"Unknown member",I:"Unknown channel",D:"New message",C:"Network",o:"edited",F:"(only visible to you)",B:function(a){"string"!==typeof a&&(a=parseFloat(a));var b=new Date,c=new Date;a=new Date(1E3*a);b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0);c.setTime(b.getTime());c.setDate(c.getDate()-1);return a.getTime()>b.getTime()?a.toLocaleTimeString():a.getTime()>c.getTime()?"yesterday, "+a.toLocaleTimeString():a.toLocaleString()},l:{fileUploadCancel:"Cancel",neterror:"Cannot connect to chat !"}};var K=0;
+function ia(){var a=document.createDocumentFragment(),b=Object.keys(F.a.b||{}),c=[],d=[],f=[],e=[];b.sort(function(a,b){return a[0]!==b[0]?a[0]-b[0]:F.a.b[a].name.localeCompare(F.a.b[b].name)});b.forEach(function(a){a=F.a.b[a];if(!a.g)if(a instanceof y){var b;b=document.createElement("li");var k=document.createElement("a");b.id="room_"+a.id;k.href="#"+a.id;b.className="slack-context-room slack-context-typing slack-ims";k.textContent=a.c.name;b.appendChild(L());b.appendChild(k);a.c.f||b.classList.add("away");G===
+a&&b.classList.add("selected");a.a>a.b&&(b.classList.add("unread"),0<=M.indexOf(a)&&b.classList.add("unreadHi"));b&&(a.i?c.push(b):e.push(b))}else b=document.createElement("li"),k=document.createElement("a"),b.id="room_"+a.id,k.href="#"+a.id,a.j?(b.className="slack-context-room slack-context-typing slack-group",b.dataset.count=Object.keys(a.f||{}).length):b.className="slack-context-room slack-context-typing slack-channel",G===a&&b.classList.add("selected"),k.textContent=a.name,b.appendChild(L()),
+b.appendChild(k),a.a>a.b&&(b.classList.add("unread"),0<=M.indexOf(a)&&b.classList.add("unreadHi")),b&&(a.i?c.push(b):a.j?f.push(b):d.push(b))});c.forEach(function(b){a.appendChild(b)});d.forEach(function(b){a.appendChild(b)});f.forEach(function(b){a.appendChild(b)});e.forEach(function(b){a.appendChild(b)});document.getElementById("chanList").textContent="";document.getElementById("chanList").appendChild(a);ja();N();ka(function(a){document.getElementById("slackCtx").style.backgroundImage="url("+a+
+")"})}function la(){var a=F.a.f,b;for(b in F.a.c.c)if(!F.a.c.c[b].g){var c=document.getElementById("room_"+b);a[b]?c.classList.add("slack-context-typing"):c.classList.remove("slack-context-typing")}for(var d in F.a.a)(b=F.a.a[d].g)&&!b.g&&(c=document.getElementById("room_"+b.id),a[b.id]?c.classList.add("slack-context-typing"):c.classList.remove("slack-context-typing"));ma()}
+function ma(){var a=F.a.f;document.getElementById("whoistyping").textContent="";if(G&&a[G.id]){var b=document.createDocumentFragment(),c=!1,d;for(d in a[G.id])(a=F.a.a[d])?b.appendChild(na(a)):c=!0;c&&(F.c=0);document.getElementById("whoistyping").appendChild(b)}}function O(a){a?document.body.classList.remove("no-network"):document.body.classList.add("no-network");N()}
+function oa(){var a=G.name||(G.c?G.c.name:void 0);if(!a){var b=[];G.f.forEach(function(a){b.push(a.name)});a=b.join(", ")}document.getElementById("currentRoomTitle").textContent=a;pa();P();document.getElementById("fileUploadContainer").classList.add("hidden");Q();R&&(R=null,S());T&&(T=null,S());ma()}
+function S(){if(R){document.body.classList.add("replyingTo");var a=document.getElementById("replyToContainer"),b=document.createElement("a");b.addEventListener("click",function(){R=null;S()});b.className="replyto-close";b.textContent="x";a.textContent="";a.appendChild(b);a.appendChild(U("reply_"+G.id,R,!0))}else document.body.classList.remove("replyingTo"),document.getElementById("replyToContainer").textContent="";P()}
+function V(){if(T){document.body.classList.add("replyingTo");var a=document.getElementById("replyToContainer"),b=document.createElement("a");b.addEventListener("click",function(){T=null;V()});b.className="replyto-close";b.textContent="x";a.textContent="";a.appendChild(b);a.appendChild(U("edit_"+G.id,T,!0));document.getElementById("msgInput").value=T.text}else document.body.classList.remove("replyingTo"),document.getElementById("replyToContainer").textContent="";P()}
+window.toggleReaction=function(a,b,c){var d=F.b[a];if(d){a:{for(var f=0,e=d.a.length;f<e;f++)if(d.a[f].id==b){d=d.a[f];break a}d=null}d&&(f=F.a.c.id,d.a[c]&&-1!==d.a[c].indexOf(f)?(d=new XMLHttpRequest,d.open("DELETE","api/reaction?room="+a+"&msg="+b+"&reaction="+encodeURIComponent(c),!0),d.send(null)):qa(a,b,c))}};
+function ra(a){a:{for(var b=a,c={};!c[b];){if(a=F.a.i.data[b])if("alias:"==a.substr(0,6))c[b]=!0,b=a.substr(6);else{b=document.createElement("span");b.className="emoji-custom emoji";b.style.backgroundImage="url('"+a+"')";a=b;break a}break}a=b}"string"===typeof a&&"makeEmoji"in window&&(a=window.makeEmoji(a));return"string"===typeof a?null:a}
+function sa(a){return a.replace(/:([^ \t:]+):/g,function(b,c){var d=ra(c);if(d){var f=document.createElement("span");f.className=b===a?"emoji-medium":"emoji-small";f.appendChild(d);return f.outerHTML}return b})}
+function W(a){a=a.split(/\r?\n/g);for(var b=0,c=a.length;b<c;b++){for(var d=a[b].trim(),f="",e={},k=!1,g=0,d=d.replace(RegExp("<([@#]?)([^>]*)>","g"),function(a,b,c){c=c.split("|");if("@"===b)c[1]?"@"!==c[1][0]&&(c[1]="@"+c[1]):(a=F.a.a[c[0]],c[1]=a?"@"+a.name:J.J),c[0]="#"+c[0],c[2]="slackmsg-link slackmsg-link-user";else if("#"===b)c[1]?"#"!==c[1][0]&&(c[1]="#"+c[1]):(a=F.a.b[c[0]],c[1]=a?"#"+a.name:J.I),c[0]="#"+c[0],c[2]="slackmsg-link slackmsg-link-chan";else if(-1!==c[0].indexOf("://"))c[1]||
+(c[1]=c[0]),c[2]="slackmsg-link";else return a;return'<a href="'+c[0]+'" class="'+c[2]+'"'+(b?"":' target="_blank"')+">"+c[1]+"</a>"}),d=sa(d),l=d.length,n=function(a,b,c){for(;a[b];){var d=a[b];if(("A"<=d&&"Z">=d||"a"<=d&&"z">=d||"0"<=d&&"9">=d||-1!=="\u00e0\u00e8\u00ec\u00f2\u00f9\u00c0\u00c8\u00cc\u00d2\u00d9\u00e1\u00e9\u00ed\u00f3\u00fa\u00fd\u00c1\u00c9\u00cd\u00d3\u00da\u00dd\u00e2\u00ea\u00ee\u00f4\u00fb\u00c2\u00ca\u00ce\u00d4\u00db\u00e3\u00f1\u00f5\u00c3\u00d1\u00d5\u00e4\u00eb\u00ef\u00f6\u00fc\u00ff\u00c4\u00cb\u00cf\u00d6\u00dc\u0178\u00e7\u00c7\u00df\u00d8\u00f8\u00c5\u00e5\u00c6\u00e6\u0153".indexOf(d))&&
 a[b]!=c&&a[b+1]==c)return!0;b++}return!1},h=function(a){return Object.keys(e).length?'<span class="'+Object.keys(a).join(" ")+'">':""};g<l&&(" "===d[g]||"\t"===d[g]);)g++;"&gt;"===d.substr(g,4)&&(k=!0,g+=4);for(;g<l;g++){var p=d[g];if("<"===p){do f+=d[g++];while(">"!==d[g-1]);g--}else if(!e["slackmsg-style-bold"]&&"*"===p&&d[g+1]&&n(d,g,p))Object.keys(e).length&&(f+="</span>"),e["slackmsg-style-bold"]=!0,f+=h(e);else if(!e["slackmsg-style-strike"]&&"~"===p&&d[g+1]&&n(d,g,p))Object.keys(e).length&&
 (f+="</span>"),e["slackmsg-style-strike"]=!0,f+=h(e);else if(!e["slackmsg-style-code"]&&"`"===p&&d[g+1]&&n(d,g,p))Object.keys(e).length&&(f+="</span>"),e["slackmsg-style-code"]=!0,f+=h(e);else if(!e["slackmsg-style-italic"]&&"_"===p&&d[g+1]&&n(d,g,p))Object.keys(e).length&&(f+="</span>"),e["slackmsg-style-italic"]=!0,f+=h(e);else{var q=!1,f=f+p;do{if(e["slackmsg-style-bold"]&&"*"!==p&&"*"===d[g+1])delete e["slackmsg-style-bold"],q=!0;else if(e["slackmsg-style-strike"]&&"~"!==p&&"~"===d[g+1])delete e["slackmsg-style-strike"],
 q=!0;else if(e["slackmsg-style-code"]&&"`"!==p&&"`"===d[g+1])delete e["slackmsg-style-code"],q=!0;else if(e["slackmsg-style-italic"]&&"_"!==p&&"_"===d[g+1])delete e["slackmsg-style-italic"],q=!0;else break;p=d[++g]}while(g<l);q&&(f+="</span>"+h(e))}}e&&(f+="</span>");a[b]=k?'<span class="slackmsg-style-quote">'+f+"</span>":f}return a.join("<br/>")}
-function U(a,b,c){b instanceof E?(a=sa(a,b,c),a.classList.add("slackmsg-me_message")):a=sa(a,b,c);b.o&&a.classList.add("slackmsg-edited");b instanceof F&&a.classList.add("slackmsg-notice");return a}function ta(a,b){document.getElementById("linkFavicon").href=a||b?"favicon.png?h="+a+"&m="+b:"favicon_ok.png"}
-function N(){var a=M.length,b="";if(Y)b="!"+K.D+" - ",document.getElementById("linkFavicon").href="favicon_err.png";else if(a)b="(!"+a+") - ",ta(a,a);else{var a=0,c;for(c in G.a.b){var d=G.a.b[c];d.a>d.b&&a++}a&&(b="("+a+") - ");ta(0,a)}G.a.j&&(b+=G.a.j.name);document.title=b}
-function ua(){if("Notification"in window)if("granted"===Notification.permission){var a=Date.now();if(L+3E4<a){var b=new Notification(K.F);L=a;setTimeout(function(){b.close()},5E3)}}else"denied"!==Notification.permission&&Notification.requestPermission()}
-function oa(){var a=document.createDocumentFragment(),b=H.id,c=null,d=0,f=null;G.b[b]&&G.b[b].a.forEach(function(e){if(!e.b){var g=U(b,e);c&&c.m===e.m&&e.m?(g.classList.add("slackmsg-same-author"),30>Math.abs(d-e.h)?f.classList.add("slackmsg-same-ts"):d=e.h):d=e.h;(!c||c.h<=H.b)&&e.h>H.b&&g.classList.add("slackmsg-first-unread");c=e;f=g;a.appendChild(g)}});var e=document.getElementById("chatWindow");e.textContent="";e.appendChild(a);e.scrollTop=e.scrollHeight-e.clientHeight;window.hasFocus&&Q()}
-function va(a){function b(a,b){for(b=b||a.target;b!==a.currentTarget&&b;){if(b.classList.contains("slackmsg-item"))return b.id;b=b.parentElement}}for(var c=a.target;c!==a.currentTarget&&c&&!c.classList.contains("slackmsg-hover");){if(c.parentElement&&c.parentElement.classList.contains("slackmsg-hover")){if(a=b(a,c)){a=parseFloat(a.split("_")[1]);var d=fa(a);d&&c.classList.contains("slackmsg-hover-reply")?(T&&(T=null,V()),R!==d&&(R=d,S())):d&&c.classList.contains("slackmsg-hover-reaction")?wa.I(document.body,
-function(a){a&&pa(H.id,d.id,a)}):d&&c.classList.contains("slackmsg-hover-edit")?(R&&(R=null,S()),T!==d&&(T=d,V())):d&&c.classList.contains("slackmsg-hover-remove")&&(R&&(R=null,S()),T&&(T=null,V()),xa(d))}break}c=c.parentElement}}function P(){document.getElementById("msgInput").focus()}function ja(){var a=document.location.hash.substr(1),b=G.a.b[a];b&&b!==H?ya(b):(a=G.a.a[a])&&a.j&&ya(a.j)}
-document.addEventListener("DOMContentLoaded",function(){ga();document.getElementById("chatWindow").addEventListener("click",va);window.addEventListener("hashchange",function(){document.location.hash&&"#"===document.location.hash[0]&&ja()});document.getElementById("fileUploadCancel").addEventListener("click",function(a){a.preventDefault();document.getElementById("fileUploadError").classList.add("hidden");document.getElementById("fileUploadContainer").classList.add("hidden");document.getElementById("fileUploadInput").value=
-"";return!1});document.getElementById("fileUploadForm").addEventListener("submit",function(a){a.preventDefault();a=document.getElementById("fileUploadInput");var b=a.value;b&&(b=b.substr(b.lastIndexOf("\\")+1),za(b,a.files[0],function(a){var b=document.getElementById("fileUploadError");a?(b.textContent=a,b.classList.remove("hidden")):(b.classList.add("hidden"),document.getElementById("fileUploadInput").value="",document.getElementById("fileUploadContainer").classList.add("hidden"))}));return!1});
-document.getElementById("attachFile").addEventListener("click",function(a){a.preventDefault();H&&document.getElementById("fileUploadContainer").classList.remove("hidden");return!1});document.getElementById("msgForm").addEventListener("submit",function(a){a.preventDefault();a=document.getElementById("msgInput");H&&a.value&&Aa(a.value)&&(a.value="",R&&(R=null,S()),T&&(T=null,S()),document.getElementById("slashList").textContent="");P();return!1});window.addEventListener("blur",function(){window.hasFocus=
-!1});window.addEventListener("focus",function(){window.hasFocus=!0;L=0;H&&Q();P()});var a=0;document.getElementById("msgInput").addEventListener("input",function(){if(H){var b=Date.now();a+3E3<b&&(G.a.c.f||H instanceof A)&&(Ba(),a=b);var b=[],c=this.value;if("/"===this.value[0]){var d=c.indexOf(" "),f=-1!==d,d=-1===d?c.length:d,c=c.substr(0,d),e;for(e in G.a.g.data){var k=G.a.g.data[e];(!f&&k.name.substr(0,d)===c||f&&k.name===c)&&b.push(k)}}b.sort(function(a,b){return a.u.localeCompare(b.u)||a.name.localeCompare(b.name)});
-var d=document.getElementById("slashList"),f=document.createDocumentFragment(),g;d.textContent="";e=0;for(c=b.length;e<c;e++)k=b[e],g!==k.u&&(g=k.u,f.appendChild(Ca(k.u))),f.appendChild(Da(k));d.appendChild(f)}});window.hasFocus=!0;(function(){var a=document.getElementById("emojiButton");if("makeEmoji"in window){var c=window.makeEmoji("smile");c?a.innerHTML="<span class='emoji-small'>"+c.outerHTML+"</span>":a.style.backgroundImage='url("smile.svg")';(c=window.makeEmoji("paperclip"))?document.getElementById("attachFile").innerHTML=
-"<span class='emoji-small'>"+c.outerHTML+"</span>":document.getElementById("attachFile").style.backgroundImage='url("public/paperclip.svg")';a.addEventListener("click",function(){wa.I(document.body,function(a){a&&(document.getElementById("msgInput").value+=":"+a+":");P()})})}else a.classList.add("hidden")})();Z()});function ia(){var a=document.createElement("span"),b=document.createElement("span"),c=document.createElement("span"),d=document.createElement("span");a.className="typing-container";b.className="typing-dot1";c.className="typing-dot2";d.className="typing-dot3";b.textContent=c.textContent=d.textContent=".";a.appendChild(b);a.appendChild(c);a.appendChild(d);return a}
-function Ea(a,b,c,d){var f=qa(c);if(f){for(var e=document.createElement("li"),k=document.createElement("a"),g=document.createElement("span"),l=document.createElement("span"),n=[],h=0,p=d.length;h<p;h++){var q=G.a.a[d[h]];q&&n.push(q.name)}n.sort();l.textContent=n.join(", ");g.appendChild(f);g.className="emoji-small";k.href="javascript:toggleReaction('"+a+"', '"+b+"', '"+c+"')";k.appendChild(g);k.appendChild(l);e.className="slackmsg-reaction-item";e.appendChild(k);return e}console.warn("Reaction id not found: "+
+function U(a,b,c){b instanceof B?(a=ta(a,b,c),a.classList.add("slackmsg-me_message")):a=ta(a,b,c);b.o&&a.classList.add("slackmsg-edited");b instanceof E&&a.classList.add("slackmsg-notice");return a}function ua(a,b){document.getElementById("linkFavicon").href=a||b?"favicon.png?h="+a+"&m="+b:"favicon_ok.png"}
+function N(){var a=M.length,b="";if(X)b="!"+J.C+" - ",document.getElementById("linkFavicon").href="favicon_err.png";else if(a)b="(!"+a+") - ",ua(a,a);else{var a=0,c;for(c in F.a.b){var d=F.a.b[c];d.a>d.b&&a++}a&&(b="("+a+") - ");ua(0,a)}F.a.j&&(b+=F.a.j.name);document.title=b}
+function va(){if("Notification"in window)if("granted"===Notification.permission){var a=Date.now();if(K+3E4<a){var b=new Notification(J.D);K=a;setTimeout(function(){b.close()},5E3)}}else"denied"!==Notification.permission&&Notification.requestPermission()}
+function pa(){var a=document.createDocumentFragment(),b=G.id,c=null,d=0,f=null;F.b[b]&&F.b[b].a.forEach(function(e){if(!e.b){var g=U(b,e);c&&c.m===e.m&&e.m?(g.classList.add("slackmsg-same-author"),30>Math.abs(d-e.h)?f.classList.add("slackmsg-same-ts"):d=e.h):d=e.h;(!c||c.h<=G.b)&&e.h>G.b&&g.classList.add("slackmsg-first-unread");e instanceof B?(f=c=null,d=0):(c=e,f=g);a.appendChild(g)}});var e=document.getElementById("chatWindow");e.textContent="";e.appendChild(a);e.scrollTop=e.scrollHeight-e.clientHeight;
+window.hasFocus&&Q()}
+function wa(a){function b(a,b){for(b=b||a.target;b!==a.currentTarget&&b;){if(b.classList.contains("slackmsg-item"))return b.id;b=b.parentElement}}for(var c=a.target;c!==a.currentTarget&&c&&!c.classList.contains("slackmsg-hover");){if(c.parentElement&&c.parentElement.classList.contains("slackmsg-hover")){if(a=b(a,c)){a=parseFloat(a.split("_")[1]);var d=ga(a);d&&c.classList.contains("slackmsg-hover-reply")?(T&&(T=null,V()),R!==d&&(R=d,S())):d&&c.classList.contains("slackmsg-hover-reaction")?xa.H(document.body,
+function(a){a&&qa(G.id,d.id,a)}):d&&c.classList.contains("slackmsg-hover-edit")?(R&&(R=null,S()),T!==d&&(T=d,V())):d&&c.classList.contains("slackmsg-hover-remove")&&(R&&(R=null,S()),T&&(T=null,V()),ya(d))}break}c=c.parentElement}}function P(){document.getElementById("msgInput").focus()}function ja(){var a=document.location.hash.substr(1),b=F.a.b[a];b&&b!==G?za(b):(a=F.a.a[a])&&a.j&&za(a.j)}
+document.addEventListener("DOMContentLoaded",function(){ha();document.getElementById("chatWindow").addEventListener("click",wa);window.addEventListener("hashchange",function(){document.location.hash&&"#"===document.location.hash[0]&&ja()});document.getElementById("fileUploadCancel").addEventListener("click",function(a){a.preventDefault();document.getElementById("fileUploadError").classList.add("hidden");document.getElementById("fileUploadContainer").classList.add("hidden");document.getElementById("fileUploadInput").value=
+"";return!1});document.getElementById("fileUploadForm").addEventListener("submit",function(a){a.preventDefault();a=document.getElementById("fileUploadInput");var b=a.value;b&&(b=b.substr(b.lastIndexOf("\\")+1),Aa(b,a.files[0],function(a){var b=document.getElementById("fileUploadError");a?(b.textContent=a,b.classList.remove("hidden")):(b.classList.add("hidden"),document.getElementById("fileUploadInput").value="",document.getElementById("fileUploadContainer").classList.add("hidden"))}));return!1});
+document.getElementById("attachFile").addEventListener("click",function(a){a.preventDefault();G&&document.getElementById("fileUploadContainer").classList.remove("hidden");return!1});document.getElementById("msgForm").addEventListener("submit",function(a){a.preventDefault();a=document.getElementById("msgInput");G&&a.value&&Ba(a.value)&&(a.value="",R&&(R=null,S()),T&&(T=null,S()),document.getElementById("slashList").textContent="");P();return!1});window.addEventListener("blur",function(){window.hasFocus=
+!1});window.addEventListener("focus",function(){window.hasFocus=!0;K=0;G&&Q();P()});var a=0;document.getElementById("msgInput").addEventListener("input",function(){if(G){var b=Date.now();a+3E3<b&&(F.a.c.f||G instanceof y)&&(Ca(),a=b);var b=[],c=this.value;if("/"===this.value[0]){var d=c.indexOf(" "),f=-1!==d,d=-1===d?c.length:d,c=c.substr(0,d),e;for(e in F.a.g.data){var k=F.a.g.data[e];(!f&&k.name.substr(0,d)===c||f&&k.name===c)&&b.push(k)}}b.sort(function(a,b){return a.u.localeCompare(b.u)||a.name.localeCompare(b.name)});
+var d=document.getElementById("slashList"),f=document.createDocumentFragment(),g;d.textContent="";e=0;for(c=b.length;e<c;e++)k=b[e],g!==k.u&&(g=k.u,f.appendChild(Da(k.u))),f.appendChild(Ea(k));d.appendChild(f)}});window.hasFocus=!0;(function(){var a=document.getElementById("emojiButton");if("makeEmoji"in window){var c=window.makeEmoji("smile");c?a.innerHTML="<span class='emoji-small'>"+c.outerHTML+"</span>":a.style.backgroundImage='url("smile.svg")';(c=window.makeEmoji("paperclip"))?document.getElementById("attachFile").innerHTML=
+"<span class='emoji-small'>"+c.outerHTML+"</span>":document.getElementById("attachFile").style.backgroundImage='url("public/paperclip.svg")';a.addEventListener("click",function(){xa.H(document.body,function(a){a&&(document.getElementById("msgInput").value+=":"+a+":");P()})})}else a.classList.add("hidden")})();Z()});function L(){var a=document.createElement("span"),b=document.createElement("span"),c=document.createElement("span"),d=document.createElement("span");a.className="typing-container";b.className="typing-dot1";c.className="typing-dot2";d.className="typing-dot3";b.textContent=c.textContent=d.textContent=".";a.appendChild(b);a.appendChild(c);a.appendChild(d);return a}
+function Fa(a,b,c,d){var f=ra(c);if(f){for(var e=document.createElement("li"),k=document.createElement("a"),g=document.createElement("span"),l=document.createElement("span"),n=[],h=0,p=d.length;h<p;h++){var q=F.a.a[d[h]];q&&n.push(q.name)}n.sort();l.textContent=n.join(", ");g.appendChild(f);g.className="emoji-small";k.href="javascript:toggleReaction('"+a+"', '"+b+"', '"+c+"')";k.appendChild(g);k.appendChild(l);e.className="slackmsg-reaction-item";e.appendChild(k);return e}console.warn("Reaction id not found: "+
 c);return null}
-function sa(a,b,c){var d=document.createElement("div"),f=document.createElement("div"),e=document.createElement("div"),k=document.createElement("div"),g=document.createElement("img"),l=document.createElement("span"),n=document.createElement("ul"),h=document.createElement("li"),p=document.createElement("ul"),q=document.createElement("ul"),t=G.a.a[b.m];d.id=a+"_"+b.h;d.className="slackmsg-item";e.className="slackmsg-ts";k.className="slackmsg-msg";g.className="slackmsg-author-img";l.className="slackmsg-author-name";
-n.className="slackmsg-hover";h.className="slackmsg-hover-reply";e.innerHTML=K.B(b.h);k.innerHTML=W(b.text);l.textContent=t?t.name:b.f||"?";g.src=t?t.b.small:"";n.appendChild(h);if("makeEmoji"in window){var v=document.createElement("li"),z=window.makeEmoji("arrow_heading_down"),D=window.makeEmoji("smile"),u=window.makeEmoji("pencil2"),t=window.makeEmoji("x");v.className="slackmsg-hover-reaction";D?(v.classList.add("emoji-small"),v.appendChild(D)):v.style.backgroundImage='url("smile.svg")';z?(h.classList.add("emoji-small"),
-h.appendChild(z)):h.style.backgroundImage='url("repl.svg")';n.appendChild(v);b.m===G.a.c.id&&(h=document.createElement("li"),h.className="slackmsg-hover-edit",u?h.classList.add("emoji-small"):h.style.backgroundImage='url("edit.svg")',h.appendChild(u),n.appendChild(h),h=document.createElement("li"),h.className="slackmsg-hover-remove",t?h.classList.add("emoji-small"):h.style.backgroundImage='url("remove.svg")',h.appendChild(t),n.appendChild(h))}else h.style.backgroundImage='url("repl.svg")',b.m===G.a.c.id&&
-(h=document.createElement("li"),h.className="slackmsg-hover-edit",h.style.backgroundImage='url("edit.svg")',n.appendChild(h),h=document.createElement("li"),h.className="slackmsg-hover-remove",h.style.backgroundImage='url("remove.svg")',n.appendChild(h));d.appendChild(g);b instanceof F&&(g=document.createElement("span"),g.className="slackmsg-notice",g.textContent=K.G,f.appendChild(g));f.appendChild(l);f.appendChild(k);f.appendChild(e);f.appendChild(p);b.o&&(e=document.createElement("div"),e.textContent=
-K.o,e.className="slackmsg-edited",f.appendChild(e));f.appendChild(q);f.className="slackmsg-content";p.className="slackmsg-attachments";q.className="slackmsg-reactions";if(!0!==c){if(b.a)for(var C in b.a)(c=Ea(a,b.id,C,b.a[C]))&&q.appendChild(c);b.c.forEach(function(a){var b=document.createElement("li"),c=document.createElement("div"),d=document.createElement("div"),e=document.createElement("a"),f=document.createElement("div"),g=document.createElement("img"),h=document.createElement("a"),k=document.createElement("div"),
+function ta(a,b,c){var d=document.createElement("div"),f=document.createElement("div"),e=document.createElement("div"),k=document.createElement("div"),g=document.createElement("img"),l=document.createElement("span"),n=document.createElement("ul"),h=document.createElement("li"),p=document.createElement("ul"),q=document.createElement("ul"),t=F.a.a[b.m];d.id=a+"_"+b.h;d.className="slackmsg-item";e.className="slackmsg-ts";k.className="slackmsg-msg";g.className="slackmsg-author-img";l.className="slackmsg-author-name";
+n.className="slackmsg-hover";h.className="slackmsg-hover-reply";e.innerHTML=J.B(b.h);k.innerHTML=W(b.text);l.textContent=t?t.name:b.f||"?";g.src=t?t.b.small:"";n.appendChild(h);if("makeEmoji"in window){var v=document.createElement("li"),z=window.makeEmoji("arrow_heading_down"),D=window.makeEmoji("smile"),u=window.makeEmoji("pencil2"),t=window.makeEmoji("x");v.className="slackmsg-hover-reaction";D?(v.classList.add("emoji-small"),v.appendChild(D)):v.style.backgroundImage='url("smile.svg")';z?(h.classList.add("emoji-small"),
+h.appendChild(z)):h.style.backgroundImage='url("repl.svg")';n.appendChild(v);b.m===F.a.c.id&&(h=document.createElement("li"),h.className="slackmsg-hover-edit",u?h.classList.add("emoji-small"):h.style.backgroundImage='url("edit.svg")',h.appendChild(u),n.appendChild(h),h=document.createElement("li"),h.className="slackmsg-hover-remove",t?h.classList.add("emoji-small"):h.style.backgroundImage='url("remove.svg")',h.appendChild(t),n.appendChild(h))}else h.style.backgroundImage='url("repl.svg")',b.m===F.a.c.id&&
+(h=document.createElement("li"),h.className="slackmsg-hover-edit",h.style.backgroundImage='url("edit.svg")',n.appendChild(h),h=document.createElement("li"),h.className="slackmsg-hover-remove",h.style.backgroundImage='url("remove.svg")',n.appendChild(h));d.appendChild(g);b instanceof E&&(g=document.createElement("span"),g.className="slackmsg-notice",g.textContent=J.F,f.appendChild(g));f.appendChild(l);f.appendChild(k);f.appendChild(e);f.appendChild(p);b.o&&(e=document.createElement("div"),e.textContent=
+J.o,e.className="slackmsg-edited",f.appendChild(e));f.appendChild(q);f.className="slackmsg-content";p.className="slackmsg-attachments";q.className="slackmsg-reactions";if(!0!==c){if(b.a)for(var C in b.a)(c=Fa(a,b.id,C,b.a[C]))&&q.appendChild(c);b.c.forEach(function(a){var b=document.createElement("li"),c=document.createElement("div"),d=document.createElement("div"),e=document.createElement("a"),f=document.createElement("div"),g=document.createElement("img"),h=document.createElement("a"),k=document.createElement("div"),
 u=document.createElement("div"),l=document.createElement("img"),n=document.createElement("img"),w=document.createElement("div"),q=document.createElement("img"),C=document.createElement("span"),t=document.createElement("span");b.className="slackmsg-attachment";var v="#e3e4e6";a.color&&("#"===a.color[0]?v=a.color[0]:"good"===a.color?v="#2fa44f":"warning"===a.color?v="#de9e31":"danger"===a.color&&(v="#d50200"));c.style.borderColor=v;c.className="slackmsg-attachment-block";d.className="slackmsg-attachment-pretext";
 a.pretext?d.innerHTML=W(a.pretext):d.classList.add("hidden");e.target="_blank";a.title?(e.innerHTML=W(a.title),a.title_link&&(e.href=a.title_link),e.className="slackmsg-attachment-title"):e.className="hidden slackmsg-attachment-title";h.target="_blank";f.className="slackmsg-author";a.author_name?(h.innerHTML=W(a.author_name),h.href=a.author_link||"",h.className="slackmsg-author-name",g.className="slackmsg-author-img",a.author_icon?g.src=a.author_icon:g.classList.add("hidden")):f.classList.add("hidden");
 u.innerHTML=W(a.text||"");u.a="slackmsg-attachment-text";l.className="slackmsg-attachment-thumb";a.thumb_url?l.src=a.thumb_url:l.classList.add("hidden");n.className="slackmsg-attachment-img";a.image_url?n.src=a.image_url:n.classList.add("hidden");w.className="slackmsg-attachment-footer";C.className="slackmsg-attachment-footer-text";q.className="slackmsg-attachment-footer-icon";a.footer?(C.innerHTML=W(a.footer),a.footer_icon?q.src=a.footer_icon:q.classList.add("hidden")):(q.classList.add("hidden"),
-C.classList.add("hidden"));t.className="slackmsg-ts";a.ts?t.innerHTML=K.B(a.ts):t.classList.add("hidden");f.appendChild(g);f.appendChild(h);k.appendChild(u);k.appendChild(l);w.appendChild(q);w.appendChild(C);w.appendChild(t);c.appendChild(e);c.appendChild(f);c.appendChild(k);c.appendChild(n);c.appendChild(w);b.appendChild(d);b.appendChild(c);b&&p.appendChild(b)})}d.appendChild(f);d.appendChild(n);return d}
-function Ca(a){var b=document.createElement("lh");b.textContent=a;b.className="slack-command-header";return b}
-function Da(a){var b=document.createElement("li"),c=document.createElement("span"),d=document.createElement("span"),f=document.createElement("span");c.textContent=a.name;d.textContent=a.usage;f.textContent=a.a;b.appendChild(c);b.appendChild(d);b.appendChild(f);b.className="slack-command-item";c.className="slack-command-name";d.className="slack-command-usage";f.className="slack-command-desc";return b};var wa=function(){function a(a,b){for(var c=a.target;c!==l&&c&&"LI"!==c.nodeName;)c=c.parentElement;c&&"LI"===c.nodeName&&c.id&&"emojibar-"===c.id.substr(0,9)?b(c.id.substr(9)):b(null)}function b(){if(!c())return!1;w&&w(null);return!0}function c(){return l.parentElement?(l.parentElement.removeChild(n),l.parentElement.removeChild(l),!0):!1}function d(a){var b=0,c;a=void 0===a?t.value:a;if(g()){var d=window.searchEmojis(a);c=f(d);for(var h in v)v[h].visible&&(v[h].visible=!1,p.removeChild(v[h].l));
-h=0;for(var k=c.length;h<k;h++){var u=c[h].name,l=v[u];if(!l){var l=v,X=u,n=u,u=window.makeEmoji(d[u]),w=document.createElement("span");w.appendChild(u);w.className="emoji-medium";u=e(n,w);l=l[X]=u}l.visible||(l.visible=!0,p.appendChild(l.l));b++}}for(h in z)z[h].visible&&(z[h].visible=!1,q.removeChild(z[h].l));c=f(G.a.i.data);h=0;for(k=c.length;h<k;h++)u=c[h].name,""!==a&&u.substr(0,a.length)!==a||"alias:"===G.a.i.data[u].substr(0,6)||(l=z[u],l||(d=z,X=l=u,u=G.a.i.data[u],n=document.createElement("span"),
-w=document.createElement("span"),n.className="emoji emoji-custom",n.style.backgroundImage='url("'+u+'")',w.appendChild(n),w.className="emoji-medium",u=e(X,w),l=d[l]=u),l.visible||(l.visible=!0,q.appendChild(l.l)),b++);return b}function f(a){var b=G.a.c.a.b,c=[],d;for(d in a){var e={name:d,H:0,count:0};a[d].names&&a[d].names.forEach(function(a){e.count+=b[a]||0});c.push(e)}return c=c.sort(function(a,b){var c=b.count-a.count;return c?c:a.H-b.H})}function e(a,b){var c=document.createElement("li");c.appendChild(b);
+C.classList.add("hidden"));t.className="slackmsg-ts";a.ts?t.innerHTML=J.B(a.ts):t.classList.add("hidden");f.appendChild(g);f.appendChild(h);k.appendChild(u);k.appendChild(l);w.appendChild(q);w.appendChild(C);w.appendChild(t);c.appendChild(e);c.appendChild(f);c.appendChild(k);c.appendChild(n);c.appendChild(w);b.appendChild(d);b.appendChild(c);b&&p.appendChild(b)})}d.appendChild(f);d.appendChild(n);return d}
+function na(a){var b=document.createElement("li"),c=document.createElement("span");c.textContent=a.name;b.appendChild(L());b.appendChild(c);return b}function Da(a){var b=document.createElement("lh");b.textContent=a;b.className="slack-command-header";return b}
+function Ea(a){var b=document.createElement("li"),c=document.createElement("span"),d=document.createElement("span"),f=document.createElement("span");c.textContent=a.name;d.textContent=a.usage;f.textContent=a.a;b.appendChild(c);b.appendChild(d);b.appendChild(f);b.className="slack-command-item";c.className="slack-command-name";d.className="slack-command-usage";f.className="slack-command-desc";return b};var xa=function(){function a(a,b){for(var c=a.target;c!==l&&c&&"LI"!==c.nodeName;)c=c.parentElement;c&&"LI"===c.nodeName&&c.id&&"emojibar-"===c.id.substr(0,9)?b(c.id.substr(9)):b(null)}function b(){if(!c())return!1;w&&w(null);return!0}function c(){return l.parentElement?(l.parentElement.removeChild(n),l.parentElement.removeChild(l),!0):!1}function d(a){var b=0,c;a=void 0===a?t.value:a;if(g()){var d=window.searchEmojis(a);c=f(d);for(var h in v)v[h].visible&&(v[h].visible=!1,p.removeChild(v[h].l));
+h=0;for(var k=c.length;h<k;h++){var u=c[h].name,l=v[u];if(!l){var l=v,Y=u,n=u,u=window.makeEmoji(d[u]),w=document.createElement("span");w.appendChild(u);w.className="emoji-medium";u=e(n,w);l=l[Y]=u}l.visible||(l.visible=!0,p.appendChild(l.l));b++}}for(h in z)z[h].visible&&(z[h].visible=!1,q.removeChild(z[h].l));c=f(F.a.i.data);h=0;for(k=c.length;h<k;h++)u=c[h].name,""!==a&&u.substr(0,a.length)!==a||"alias:"===F.a.i.data[u].substr(0,6)||(l=z[u],l||(d=z,Y=l=u,u=F.a.i.data[u],n=document.createElement("span"),
+w=document.createElement("span"),n.className="emoji emoji-custom",n.style.backgroundImage='url("'+u+'")',w.appendChild(n),w.className="emoji-medium",u=e(Y,w),l=d[l]=u),l.visible||(l.visible=!0,q.appendChild(l.l)),b++);return b}function f(a){var b=F.a.c.a.b,c=[],d;for(d in a){var e={name:d,G:0,count:0};a[d].names&&a[d].names.forEach(function(a){e.count+=b[a]||0});c.push(e)}return c=c.sort(function(a,b){var c=b.count-a.count;return c?c:a.G-b.G})}function e(a,b){var c=document.createElement("li");c.appendChild(b);
 c.className="emojibar-list-item";c.id="emojibar-"+a;return{visible:!1,l:c}}function k(a){var b=document.createElement("img"),c=document.createElement("div");b.src=a;c.appendChild(b);c.className="emojibar-header";return c}function g(){return"searchEmojis"in window}var l=document.createElement("div"),n=document.createElement("div"),h=document.createElement("div"),p=document.createElement("ul"),q=document.createElement("ul"),t=document.createElement("input"),v={},z={},D=document.createElement("div"),
 u=document.createElement("span"),C=document.createElement("span"),w;n.addEventListener("click",function(a){var c=l.getBoundingClientRect();(a.screenY<c.top||a.screenY>c.bottom||a.screenX<c.left||a.screenX>c.right)&&b()});n.className="emojibar-overlay";l.className="emojibar";h.className="emojibar-emojis";D.className="emojibar-detail";u.className="emojibar-detail-img";C.className="emojibar-detail-name";p.className=q.className="emojibar-list";t.className="emojibar-search";D.appendChild(u);D.appendChild(C);
-h.appendChild(k(window.emojiProviderHeader));h.appendChild(p);h.appendChild(k("emojicustom.png"));h.appendChild(q);l.appendChild(h);l.appendChild(D);l.appendChild(t);t.addEventListener("keyup",function(){d()});l.addEventListener("mousemove",function(b){a(b,function(a){var b=a?v[a]||z[a]:null;b?(u.innerHTML=b.l.outerHTML,C.textContent=":"+a+":"):(u.textContent="",C.textContent="")})});l.addEventListener("click",function(b){a(b,function(a){a&&c()&&w&&w(a)})});return{isSupported:g,I:function(a,b){return g()?
-(w=b,a.appendChild(n),a.appendChild(l),t.value="",d(),t.focus(),!0):!1},search:d,close:b}}();var G,M=[];function Fa(){this.c=0;this.a=new aa;this.b={}}
-Fa.prototype.update=function(a){var b=Date.now();a.v&&(this.c=a.v);if(a["static"]){var c=this.a,d=a["static"],f=Date.now();if(d.users)for(var e=0,k=d.users.length;e<k;e++){var g=c.a[d.users[e].id];g||(g=c.a[d.users[e].id]=new I(d.users[e].id));g.update(d.users[e],f)}if(d.channels)for(e=0,k=d.channels.length;e<k;e++){g=c.b[d.channels[e].id];if(!g){var g=c.b,l=d.channels[e].id,n;n=d.channels[e];n=n.pv?new A(n.id,c.a[n.user]):new y(n.id);g=g[l]=n}g.update(d.channels[e],c,f)}d.emojis&&(c.i.data=d.emojis,
-c.i.version=f);if(void 0!==d.commands){c.g.data={};for(e in d.commands)c.g.data[e]=new r(d.commands[e]);c.g.version=f}d.team&&(c.j||(c.j=new m(d.team.id)),c.j.update(d.team,f));c.A=Math.max(c.A,f);d.self&&(c.c=c.a[d.self.id],c.c.a||(c.c.a=new x),c.c.a.update(d.self.prefs,f));if(void 0!==d.typing)for(e in c.f={},d.typing){c.f[e]={};for(var h in d.typing[e])c.f[e][h]=f}}for(var p in this.a.b){var q=this.a.b[p];q.a===q.b&&(c=M.indexOf(q),-1!==c&&M.splice(c,1))}if(a.live){for(q in a.live)(p=this.b[q])?
-ca(p,a.live[q],b):this.b[q]=new ba(q,250,a.live[q],b);for(var t in a.live)(b=this.a.b[t])?(this.b[t].a.length&&(q=this.b[t],b.a=Math.max(b.a,q.a[q.a.length-1].h)),b.g||(Ga(b,a.live[t]),H&&a.live[H.id]&&oa())):G.c=0}a["static"]&&(ha(),a["static"].typing&&la())};setInterval(function(){var a=G.a,b=Date.now(),c=!1,d;for(d in a.f){var f=!0,e;for(e in a.f[d])a.f[d][e]+3E3<b?(delete a.f[d][e],c=!0):f=!1;f&&(delete a.f[d],c=!0)}c&&la()},1E3);
-function Ga(a,b){if(a!==H||!window.hasFocus){var c=new RegExp("<@"+G.a.c.id),d=!1,f=!1,e=!1;b.forEach(function(b){if(!(parseFloat(b.ts)<=a.b)){f=!0;var g;if(!(g=a instanceof A||b.text.match(c)))a:{g=G.a.c.a.a;for(var k=0,h=g.length;k<h;k++)if(-1!==b.text.indexOf(g[k])){g=!0;break a}g=!1}g&&(-1===M.indexOf(a)&&(e=!0,M.push(a)),d=!0)}});if(f){N();var k=document.getElementById(a.id);k&&(k.classList.add("unread"),d&&k.classList.add("unreadHi"));e&&!window.hasFocus&&ua()}}}
-function Q(){var a=H,b=M.indexOf(a);if(a.a>a.b){var c=new XMLHttpRequest;c.open("POST","api/markread?room="+a.id+"&ts="+a.a,!0);c.send(null);a.b=a.a}0<=b&&(M.splice(b,1),N());a=document.getElementById(a.id);a.classList.remove("unread");a.classList.remove("unreadHi")}G=new Fa;var ka=function(){function a(a,b){b.sort(function(){return Math.random()-.5});for(var c=0,d=20;d<l-40;d+=h)for(var f=0;f+h<=n;f+=h)e(a,b[c],d,f),c++,c===b.length&&(b.sort(function(a,b){return a.w?b.w?Math.random()-.5:-1:1}),c=0)}function b(a,d){for(var e=0,f=a.length;e<f;e++)if(void 0===a[e].w){c(a[e].src,function(c){a[e].w=c;b(a,d)});return}var g=[];a.forEach(function(a){a.w&&g.push(a.w)});d(g)}function c(a,b){var c=new XMLHttpRequest;c.responseType="blob";c.onreadystatechange=function(){if(4===
+h.appendChild(k(window.emojiProviderHeader));h.appendChild(p);h.appendChild(k("emojicustom.png"));h.appendChild(q);l.appendChild(h);l.appendChild(D);l.appendChild(t);t.addEventListener("keyup",function(){d()});l.addEventListener("mousemove",function(b){a(b,function(a){var b=a?v[a]||z[a]:null;b?(u.innerHTML=b.l.outerHTML,C.textContent=":"+a+":"):(u.textContent="",C.textContent="")})});l.addEventListener("click",function(b){a(b,function(a){a&&c()&&w&&w(a)})});return{isSupported:g,H:function(a,b){return g()?
+(w=b,a.appendChild(n),a.appendChild(l),t.value="",d(),t.focus(),!0):!1},search:d,close:b}}();var F,M=[];function Ga(){this.c=0;this.a=new ba;this.b={}}
+Ga.prototype.update=function(a){var b=Date.now();a.v&&(this.c=a.v);if(a["static"]){var c=this.a,d=a["static"],f=Date.now();if(d.users)for(var e=0,k=d.users.length;e<k;e++){var g=c.a[d.users[e].id];g||(g=c.a[d.users[e].id]=new H(d.users[e].id));g.update(d.users[e],f)}if(d.channels)for(e=0,k=d.channels.length;e<k;e++){g=c.b[d.channels[e].id];if(!g){var g=c.b,l=d.channels[e].id,n;n=d.channels[e];n=n.pv?new y(n.id,c.a[n.user]):new x(n.id);g=g[l]=n}g.update(d.channels[e],c,f)}d.emojis&&(c.i.data=d.emojis,
+c.i.version=f);if(void 0!==d.commands){c.g.data={};for(e in d.commands)c.g.data[e]=new r(d.commands[e]);c.g.version=f}d.team&&(c.j||(c.j=new m(d.team.id)),c.j.update(d.team,f));c.A=Math.max(c.A,f);d.self&&(c.c=c.a[d.self.id],c.c.a||(c.c.a=new aa),c.c.a.update(d.self.prefs,f));if(void 0!==d.typing)for(e in c.f={},d.typing){c.f[e]={};for(var h in d.typing[e])c.f[e][h]=f}}for(var p in this.a.b){var q=this.a.b[p];q.a===q.b&&(c=M.indexOf(q),-1!==c&&M.splice(c,1))}if(a.live){for(q in a.live)(p=this.b[q])?
+da(p,a.live[q],b):this.b[q]=new ca(q,250,a.live[q],b);for(var t in a.live)(b=this.a.b[t])?(this.b[t].a.length&&(q=this.b[t],b.a=Math.max(b.a,q.a[q.a.length-1].h)),b.g||(Ha(b,a.live[t]),G&&a.live[G.id]&&pa())):F.c=0}a["static"]&&(ia(),a["static"].typing&&la())};setInterval(function(){var a=F.a,b=Date.now(),c=!1,d;for(d in a.f){var f=!0,e;for(e in a.f[d])a.f[d][e]+3E3<b?(delete a.f[d][e],c=!0):f=!1;f&&(delete a.f[d],c=!0)}c&&la()},1E3);
+function Ha(a,b){if(a!==G||!window.hasFocus){var c=new RegExp("<@"+F.a.c.id),d=!1,f=!1,e=!1;b.forEach(function(b){if(!(parseFloat(b.ts)<=a.b)){f=!0;var g;if(!(g=a instanceof y||b.text.match(c)))a:{g=F.a.c.a.a;for(var k=0,h=g.length;k<h;k++)if(-1!==b.text.indexOf(g[k])){g=!0;break a}g=!1}g&&(-1===M.indexOf(a)&&(e=!0,M.push(a)),d=!0)}});if(f){N();var k=document.getElementById("room_"+a.id);k&&(k.classList.add("unread"),d&&k.classList.add("unreadHi"));e&&!window.hasFocus&&va()}}}
+function Q(){var a=G,b=M.indexOf(a);if(a.a>a.b){var c=new XMLHttpRequest;c.open("POST","api/markread?room="+a.id+"&ts="+a.a,!0);c.send(null);a.b=a.a}0<=b&&(M.splice(b,1),N());a=document.getElementById("room_"+a.id);a.classList.remove("unread");a.classList.remove("unreadHi")}F=new Ga;var ka=function(){function a(a,b){b.sort(function(){return Math.random()-.5});for(var c=0,d=20;d<l-40;d+=h)for(var f=0;f+h<=n;f+=h)e(a,b[c],d,f),c++,c===b.length&&(b.sort(function(a,b){return a.w?b.w?Math.random()-.5:-1:1}),c=0)}function b(a,d){for(var e=0,f=a.length;e<f;e++)if(void 0===a[e].w){c(a[e].src,function(c){a[e].w=c;b(a,d)});return}var g=[];a.forEach(function(a){a.w&&g.push(a.w)});d(g)}function c(a,b){var c=new XMLHttpRequest;c.responseType="blob";c.onreadystatechange=function(){if(4===
 c.readyState)if(c.response){var a=new Image;a.onload=function(){var c=document.createElement("canvas");c.height=c.width=t;c=c.getContext("2d");c.drawImage(a,0,0,t,t);for(var c=c.getImageData(0,0,t,t),d=0,e=0;e<c.width*c.height*4;e+=4)c.data[e]=c.data[e+1]=c.data[e+2]=(c.data[e]+c.data[e+1]+c.data[e+2])/3,c.data[e+3]=50,d+=c.data[e];if(50>d/(c.height*c.width))for(e=0;e<c.width*c.height*4;e+=4)c.data[e]=c.data[e+1]=c.data[e+2]=255-c.data[e];b(c)};a.onerror=function(){b(null)};a.src=window.URL.createObjectURL(c.response)}else b(null)};
 c.open("GET",a,!0);c.send(null)}function d(){var a=g.createLinearGradient(0,0,0,n);a.addColorStop(0,"#4D394B");a.addColorStop(1,"#201820");g.fillStyle=a;g.fillRect(0,0,l,n);return g.getImageData(0,0,l,n)}function f(a,b){for(var c=(a.height-b.height)/2,d=0;d<b.height;d++)for(var e=0;e<b.width;e++){var f=b.data[4*(d*b.width+e)]/255,g=4*((d+c)*a.width+e+c);a.data[g]*=f;a.data[g+1]*=f;a.data[g+2]*=f}return a}function e(a,b,c,d){var e=Math.floor(d);a=[a.data[e*l*4+0],a.data[e*l*4+1],a.data[e*l*4+2]];g.fillStyle=
-"#"+(1.1*a[0]<<16|1.1*a[1]<<8|1.1*a[2]).toString(16);g.beginPath();g.moveTo(c+h/2,d+p);g.lineTo(c-p+h,d+h/2);g.lineTo(c+h/2,d-p+h);g.lineTo(c+p,d+h/2);g.closePath();g.fill();g.putImageData(f(g.getImageData(c+p,d+p,q,q),b),c+p,d+p)}var k=document.createElement("canvas"),g=k.getContext("2d"),l=k.width=250,n=k.height=290,h=(l-40)/3,p=.1*h,q=Math.floor(h-2*p),t=.5*q,v,z=[],D=!1;return function(c){if(v)c(v);else if(D)z.push(c);else{var e=d(),f=[];D=!0;z.push(c);for(var g in G.a.a)G.a.a[g].i||G.a.a[g].A||
-f.push({src:"api/avatar?user="+g});b(f,function(b){a(e,b);v=k.toDataURL();z.forEach(function(a){a(v)})})}}}();var Y=0,H=null,R=null,T=null;function Ha(a){var b=new XMLHttpRequest;b.timeout=6E4;b.onreadystatechange=function(){if(4===b.readyState)if(b.status){var c=null,d=2===Math.floor(b.status/100);if(d){Y&&(Y=0,O(!0));c=b.response;try{c=JSON.parse(c)}catch(f){c=null}}else Y?(Y+=Math.floor((Y||5)/2),Y=Math.min(60,Y)):(Y=5,O(!1));a(d,c)}else Y&&(Y=0,O(!0)),Ha(a)};b.open("GET","api?v="+G.c,!0);b.send(null)}function Ba(){var a=new XMLHttpRequest;a.open("POST","api/typing?room="+H.id,!0);a.send(null)}
-function Ia(a,b){a?(b&&G.update(b),Z()):setTimeout(Z,1E3*Y)}function Z(){Ha(Ia)}function ya(a){H&&document.getElementById(H.id).classList.remove("selected");document.getElementById(a.id).classList.add("selected");document.body.classList.remove("no-room-selected");H=a;na();H.a&&!G.b[H.id]&&(a=new XMLHttpRequest,a.open("GET","api/hist?room="+H.id,!0),a.send(null))}
-function za(a,b,c){var d=H;new FileReader;var f=new FormData,e=new XMLHttpRequest;f.append("file",b);f.append("filename",a);e.onreadystatechange=function(){4===e.readyState&&(204===e.status?c(null):c(e.statusText))};e.open("POST","api/file?room="+d.id);e.send(f)}
-function Aa(a){if(T){var b=new XMLHttpRequest;b.open("PUT","api/msg?room="+H.id+"&ts="+T.id+"&text="+encodeURIComponent(a),!0);b.send(null);return!0}if("/"===a[0]){var c=a.indexOf(" "),b=-1===c?"":a.substr(c);return(a=G.a.g.data[a.substr(0,-1===c?void 0:c)])?(c=new XMLHttpRequest,c.open("POST","api/cmd?room="+H.id+"&cmd="+encodeURIComponent(a.name.substr(1))+"&args="+encodeURIComponent(b.trim()),!0),c.send(null),!0):!1}var b=H,c=R,d=new XMLHttpRequest;a="api/msg?room="+b.id+"&text="+encodeURIComponent(a);
-if(c){var f=G.a.a[c.m],e="Message";"C"===b.id[0]?e="Channel message":"D"===b.id[0]?e="Direct message":"G"===b.id[0]&&(e="Group message");a+="&attachments="+encodeURIComponent(JSON.stringify([{fallback:c.text,author_name:"<@"+f.id+"|"+f.name+">",author_icon:f.b.small,text:c.text,footer:e,ts:c.h}]))}d.open("POST",a,!0);d.send(null);return!0}function xa(a){var b=new XMLHttpRequest;b.open("DELETE","api/msg?room="+H.id+"&ts="+a.id,!0);b.send(null)}
-function pa(a,b,c){var d=new XMLHttpRequest;d.open("POST","api/reaction?room="+a+"&msg="+b+"&reaction="+encodeURIComponent(c),!0);d.send(null)};
+"#"+(1.1*a[0]<<16|1.1*a[1]<<8|1.1*a[2]).toString(16);g.beginPath();g.moveTo(c+h/2,d+p);g.lineTo(c-p+h,d+h/2);g.lineTo(c+h/2,d-p+h);g.lineTo(c+p,d+h/2);g.closePath();g.fill();g.putImageData(f(g.getImageData(c+p,d+p,q,q),b),c+p,d+p)}var k=document.createElement("canvas"),g=k.getContext("2d"),l=k.width=250,n=k.height=290,h=(l-40)/3,p=.1*h,q=Math.floor(h-2*p),t=.5*q,v,z=[],D=!1;return function(c){if(v)c(v);else if(D)z.push(c);else{var e=d(),f=[];D=!0;z.push(c);for(var g in F.a.a)F.a.a[g].i||F.a.a[g].A||
+f.push({src:"api/avatar?user="+g});b(f,function(b){a(e,b);v=k.toDataURL();z.forEach(function(a){a(v)})})}}}();var X=0,G=null,R=null,T=null;function Ia(a){var b=new XMLHttpRequest;b.timeout=6E4;b.onreadystatechange=function(){if(4===b.readyState)if(b.status){var c=null,d=2===Math.floor(b.status/100);if(d){X&&(X=0,O(!0));c=b.response;try{c=JSON.parse(c)}catch(f){c=null}}else X?(X+=Math.floor((X||5)/2),X=Math.min(60,X)):(X=5,O(!1));a(d,c)}else X&&(X=0,O(!0)),Ia(a)};b.open("GET","api?v="+F.c,!0);b.send(null)}function Ca(){var a=new XMLHttpRequest;a.open("POST","api/typing?room="+G.id,!0);a.send(null)}
+function Ja(a,b){a?(b&&F.update(b),Z()):setTimeout(Z,1E3*X)}function Z(){Ia(Ja)}function za(a){G&&document.getElementById("room_"+G.id).classList.remove("selected");document.getElementById("room_"+a.id).classList.add("selected");document.body.classList.remove("no-room-selected");G=a;oa();G.a&&!F.b[G.id]&&(a=new XMLHttpRequest,a.open("GET","api/hist?room="+G.id,!0),a.send(null))}
+function Aa(a,b,c){var d=G;new FileReader;var f=new FormData,e=new XMLHttpRequest;f.append("file",b);f.append("filename",a);e.onreadystatechange=function(){4===e.readyState&&(204===e.status?c(null):c(e.statusText))};e.open("POST","api/file?room="+d.id);e.send(f)}
+function Ba(a){if(T){var b=new XMLHttpRequest;b.open("PUT","api/msg?room="+G.id+"&ts="+T.id+"&text="+encodeURIComponent(a),!0);b.send(null);return!0}if("/"===a[0]){var c=a.indexOf(" "),b=-1===c?"":a.substr(c);return(a=F.a.g.data[a.substr(0,-1===c?void 0:c)])?(c=new XMLHttpRequest,c.open("POST","api/cmd?room="+G.id+"&cmd="+encodeURIComponent(a.name.substr(1))+"&args="+encodeURIComponent(b.trim()),!0),c.send(null),!0):!1}var b=G,c=R,d=new XMLHttpRequest;a="api/msg?room="+b.id+"&text="+encodeURIComponent(a);
+if(c){var f=F.a.a[c.m],e="Message";"C"===b.id[0]?e="Channel message":"D"===b.id[0]?e="Direct message":"G"===b.id[0]&&(e="Group message");a+="&attachments="+encodeURIComponent(JSON.stringify([{fallback:c.text,author_name:"<@"+f.id+"|"+f.name+">",author_icon:f.b.small,text:c.text,footer:e,ts:c.h}]))}d.open("POST",a,!0);d.send(null);return!0}function ya(a){var b=new XMLHttpRequest;b.open("DELETE","api/msg?room="+G.id+"&ts="+a.id,!0);b.send(null)}
+function qa(a,b,c){var d=new XMLHttpRequest;d.open("POST","api/reaction?room="+a+"&msg="+b+"&reaction="+encodeURIComponent(c),!0);d.send(null)};

+ 20 - 1
srv/public/style.css

@@ -1,3 +1,12 @@
+@keyframes upAndDown {
+    0% { bottom: 1px; }
+    16.66667% { bottom: 1px; }
+    32.33333% { bottom: 1px; }
+    50% { bottom: 4px; }
+    66.66667% { bottom: 4px; }
+    83.33333% { bottom: 4px; }
+    100% { bottom: 1px; }
+}
 
 body { display: flex; margin: 0; padding: 0; font-family: Lato, sans-serif; height: 100%; }
 
@@ -31,6 +40,10 @@ body { display: flex; margin: 0; padding: 0; font-family: Lato, sans-serif; heig
 .slack-chat-content { flex: 1; overflow: auto; }
 .slack-chat-title { display: inline-block; padding: 14px 10px; font-size: 1.75em; font-style: italic; }
 .slack-chat-whoistyping { margin: 0; padding: 0 10px; height: 1.5em; line-height: 1.5em; background: #EAEAEA; }
+.slack-chat-whoistyping > li { display: inline; }
+.slack-chat-whoistyping .typing-container { margin: 0 5px; background: rgb(156, 156, 156); padding: 0 2px; border-radius: 2px; display: inline-block; height: 14px; line-height: 12px ;}
+.slack-chat-whoistyping .typing-container::after { content: " "; height: 5px; width: 4px; display: inline-block; position: absolute; right: -7px; top: 0px; border-top: 7px solid rgb(156, 156, 156); border-right: 10px solid transparent; border-radius: 4px; }
+
 .slack-chat-control { display: inline-block; width: 100%; height: 2em; padding: 14px 0; }
 .slack-chat-control > * { display: inline-block; height: 100%; }
 .slack-context-room:not(.selected).unread, .slack-context-room:not(.selected).unread > a { font-weight: bold; color: white; }
@@ -46,7 +59,7 @@ body { display: flex; margin: 0; padding: 0; font-family: Lato, sans-serif; heig
 .slackmsg-msg { display: block; vertical-align: top; }
 .slackmsg-reactions:empty,.slackmsg-attachments:empty { display: none; }
 .slackmsg-reactions { padding: 0 0 0 40px; margin: 5px 0; }
-.slackmsg-attachments { padding: 0 0 0 40px; }
+.slackmsg-attachments { padding: 0; }
 .slackmsg-ts { font-size: 0.75em; font-style: italic; }
 
 .slackmsg-notice { background: rgba(255, 255, 0, 0.2); }
@@ -123,3 +136,9 @@ body { display: flex; margin: 0; padding: 0; font-family: Lato, sans-serif; heig
 .emojibar-search { width: 300px; margin: 5px auto; }
 .emojibar-overlay { position: fixed; top: 0; bottom: 0; left: 0; right: 0;  background: rgba(0, 0, 0, 0.2); }
 
+.typing-container { position: relative; }
+.typing-container > * { position: relative; bottom: 1px; font-size: 18px; animation-name: upAndDown; animation-duration: 3s; animation-iteration-count: infinite; }
+.typing-container .typing-dot1 { animation-delay: 0; }
+.typing-container .typing-dot2 { animation-delay: 0.5s; }
+.typing-container .typing-dot3 { animation-delay: 1s; }
+

+ 7 - 2
srv/src/message.js

@@ -119,8 +119,12 @@ Message.prototype.toStatic = function() {
 Message.prototype.addReaction = function(reaction, userId, ts) {
     if (!this.reactions[reaction])
         this.reactions[reaction] = [];
-    this.reactions[reaction].push(userId);
-    this.version = ts;
+    if (this.reactions[reaction].indexOf(userId) === -1) {
+        this.reactions[reaction].push(userId);
+        this.version = ts;
+        return true;
+    }
+    return false;
 };
 
 /**
@@ -145,6 +149,7 @@ Message.prototype.removeReaction = function(reaction, userId, ts) {
     }
     if (updated)
         this.version = ts;
+    return updated;
 };
 
 Message.prototype.hasReactionForUser = function(reaction, userId) {

+ 29 - 6
srv/src/slack.js

@@ -56,6 +56,7 @@ function Slack(sess, manager) {
     this.rtm = null;
     this.data = new SlackData(this);
     this.history = {};
+    this.pendingRtm = {};
     this.connected = false;
     this.closing = false;
 }
@@ -223,6 +224,13 @@ Slack.prototype.getLiveUpdates = function(knownVersion) {
 };
 
 Slack.prototype.onMessage = function(msg, t) {
+    if (msg["ok"] === true && msg["reply_to"] && this.pendingRtm[msg["reply_to"]]) {
+        var ts = msg["ts"]
+            ,rtmId = msg["reply_to"];
+        msg = this.pendingRtm[rtmId];
+        msg["ts"] = ts;
+        delete this.pendingRtm[rtmId];
+    }
     this.data.onMessage(msg, t);
     if ((msg["channel"] || msg["channel_id"] || (msg["item"] && msg["item"]["channel"])) && msg["type"] && UPDATE_LIVE.indexOf(msg["type"]) !== -1) {
         var channelId = msg["channel"] || msg["channel_id"] || msg["item"]["channel"]
@@ -400,12 +408,27 @@ Slack.prototype.sendMeMsg = function(channel, text) {
  * @param {Array.<Object>=} attachments
 **/
 Slack.prototype.sendMsg = function(channel, text, attachments) {
-    httpsRequest(SLACK_ENDPOINT +GETAPI.postMsg
-        +"?token=" +this.token
-        +"&channel=" +channel.id
-        +"&text=" +text.join("\n")
-        + (attachments ? ("&attachments=" +encodeURIComponent(JSON.stringify(attachments))) : "")
-        +"&as_user=true");
+    if (attachments) {
+        httpsRequest(SLACK_ENDPOINT +GETAPI.postMsg
+            +"?token=" +this.token
+            +"&channel=" +channel.id
+            +"&text=" +text.join("\n")
+            + (attachments ? ("&attachments=" +encodeURIComponent(JSON.stringify(attachments))) : "")
+            +"&as_user=true");
+    } else {
+        var decodedText = [];
+        text.forEach(function(i) {
+            decodedText.push(decodeURIComponent(i));
+        });
+        var fullDecodedText = decodedText.join("\n");
+        this.pendingRtm[this.rtmId] = {
+            type: 'message',
+            channel: channel.id,
+            user: this.data.self.id,
+            text: fullDecodedText
+        };
+        this.rtm.send('{"id":' +this.rtmId++ +',"type":"message","channel":"' +channel.id +'", "text":' +JSON.stringify(fullDecodedText) +'}');
+    }
 };
 
 /**

+ 3 - 2
srv/src/slackHistory.js

@@ -43,8 +43,9 @@ SlackHistory.prototype.push = function(ev, t) {
             modifArg = null;
         }
         for (var i =0, nbMsg = this.messages.length; i < nbMsg; i++) {
-            if (this.messages[i].id === targetId) {
-                this.messages[i].update(modifArg, t);
+            msg = this.messages[i];
+            if (msg.id === targetId) {
+                msg.update(modifArg, t);
                 exists = true;
                 break;
             }