about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651
diff options
context:
space:
mode:
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/slack-20180913.651')
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/helm-slack.el201
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-action.el90
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-action.elcbin0 -> 2181 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-attachment.el529
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-attachment.elcbin0 -> 24543 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-autoloads.el59
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-bot-message.el102
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-bot-message.elcbin0 -> 3613 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-buffer.el448
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-buffer.elcbin0 -> 23284 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-channel.el277
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-channel.elcbin0 -> 13677 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-conversations.el278
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-conversations.elcbin0 -> 8276 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-buffer.el377
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-buffer.elcbin0 -> 15525 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-edit-element-buffer.el111
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-edit-element-buffer.elcbin0 -> 7011 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.el343
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.elcbin0 -> 20333 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-emoji.el93
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-emoji.elcbin0 -> 2619 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-info-buffer.el146
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-info-buffer.elcbin0 -> 8593 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-list-buffer.el79
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-list-buffer.elcbin0 -> 6471 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file.el550
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file.elcbin0 -> 31210 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-group.el287
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-group.elcbin0 -> 13948 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-im.el249
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-im.elcbin0 -> 11397 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-buffer.el429
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-buffer.elcbin0 -> 20267 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-compose-buffer.el51
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-compose-buffer.elcbin0 -> 5310 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-edit-buffer.el94
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-edit-buffer.elcbin0 -> 6769 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-editor.el130
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-editor.elcbin0 -> 5956 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-formatter.el337
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-formatter.elcbin0 -> 10735 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-notification.el145
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-notification.elcbin0 -> 5056 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-reaction.el146
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-reaction.elcbin0 -> 4739 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-sender.el177
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-sender.elcbin0 -> 5276 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-share-buffer.el75
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-share-buffer.elcbin0 -> 6301 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message.el454
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message.elcbin0 -> 24260 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-item.el43
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-item.elcbin0 -> 1940 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-items-buffer.el102
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-items-buffer.elcbin0 -> 6983 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pkg.el11
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reaction.el117
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reaction.elcbin0 -> 4950 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reminder.el237
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reminder.elcbin0 -> 11732 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reply.el49
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reply.elcbin0 -> 1206 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request-worker.el143
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request-worker.elcbin0 -> 4976 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request.el162
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request.elcbin0 -> 7568 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-buffer.el170
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-buffer.elcbin0 -> 7015 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-info-buffer.el173
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-info-buffer.elcbin0 -> 8184 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-message-compose-buffer.el69
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-message-compose-buffer.elcbin0 -> 3069 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room.el471
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room.elcbin0 -> 20873 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search-result-buffer.el129
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search-result-buffer.elcbin0 -> 8392 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search.el263
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search.elcbin0 -> 14759 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-selectable.el88
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-selectable.elcbin0 -> 5540 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-slash-commands.el164
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-slash-commands.elcbin0 -> 9024 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-star.el250
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-star.elcbin0 -> 15856 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-stars-buffer.el140
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-stars-buffer.elcbin0 -> 8510 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-team.el324
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-team.elcbin0 -> 14874 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-buffer.el148
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-buffer.elcbin0 -> 9639 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-compose-buffer.el79
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-compose-buffer.elcbin0 -> 3536 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread.el333
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread.elcbin0 -> 15802 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-message.el35
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-message.elcbin0 -> 1596 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-profile-buffer.el96
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-profile-buffer.elcbin0 -> 6699 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user.el398
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user.elcbin0 -> 16033 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-util.el481
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-util.elcbin0 -> 15444 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-websocket.el1073
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-websocket.elcbin0 -> 39824 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack.el229
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack.elcbin0 -> 7627 bytes
107 files changed, 12234 insertions, 0 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/helm-slack.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/helm-slack.el
new file mode 100644
index 000000000000..8ee39d4b948b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/helm-slack.el
@@ -0,0 +1,201 @@
+;;; helm-slack.el ---                                -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'helm)
+(require 'slack-team)
+(require 'slack-room-info-buffer)
+(require 'slack-conversations)
+(require 'slack-user-profile-buffer)
+
+(defvar helm-slack-actions
+      (helm-make-actions
+       "Display channel" #'helm-slack-display-room
+       "Archive channel" #'helm-slack-archive-room
+       "Invite user to channel" #'helm-slack-invite-to-room
+       "Kick user from channel" #'helm-slack-kick-from-room
+       "List user in channel" #'helm-slack-list-member-in-room
+       "Join channel" #'helm-slack-join-room
+       "Leave channel" #'helm-slack-leave-room
+       "Rename channel" #'helm-slack-rename-room
+       "Set purpose for channel" #'helm-slack-set-purpose-for-room
+       "Set topic of channel" #'helm-slack-set-topic-of-room
+       ))
+
+(defvar helm-slack-members-actions
+  (helm-make-actions "Display User" #'helm-slack-display-user))
+
+
+(defvar helm-slack-channels-source (helm-build-sync-source "Channels (Slack)"
+                                     :persistent-action #'helm-slack-persistent-action
+                                     :action helm-slack-actions
+                                     :candidates #'helm-slack-build-channels-candidates))
+
+(defvar helm-slack-groups-source (helm-build-sync-source "Private Channels (Slack)"
+                                   :persistent-action #'helm-slack-persistent-action
+                                   :action helm-slack-actions
+                                   :candidates #'helm-slack-build-groups-candidates))
+
+(defvar helm-slack-ims-source (helm-build-sync-source "Direct Messages (Slack)"
+                                :persistent-action #'helm-slack-persistent-action
+                                :action helm-slack-actions
+                                :candidates #'helm-slack-build-ims-candidates))
+
+(defvar helm-slack-source (helm-build-sync-source "Slack"
+                            :persistent-action #'helm-slack-persistent-action
+                            :action helm-slack-actions
+                            :candidates #'helm-slack-build-candidates))
+
+(defcustom helm-slack-sources
+  '(helm-slack-source)
+  "Default helm sources.
+pre defined sources are `helm-slack-channels-source', `helm-slack-groups-source', `helm-slack-ims-source', `helm-slack-source'"
+  :type 'list
+  :group 'slack)
+
+(defun helm-slack-build-channels-candidates ()
+  (helm-slack-build--candidates #'(lambda (team) (oref team channels))))
+
+(defun helm-slack-build-groups-candidates ()
+  (helm-slack-build--candidates #'(lambda (team) (oref team groups))))
+
+(defun helm-slack-build-ims-candidates ()
+  (helm-slack-build--candidates #'(lambda (team) (oref team ims))))
+
+(defun helm-slack-build-candidates ()
+  (helm-slack-build--candidates #'(lambda (team) (with-slots (channels groups ims) team
+                                                   (append channels groups ims)))))
+
+(defun helm-slack-build--candidates (rooms-selector)
+  (cl-loop for team in slack-teams
+           as rooms = (funcall rooms-selector team)
+           nconc (cl-labels
+                     ((filter (rooms) (cl-remove-if #'slack-room-hidden-p
+                                                    rooms))
+                      (collector (label room) (list label room team)))
+                   (let ((slack-display-team-name
+                          (< 1 (length slack-teams))))
+                     (slack-room-names (append rooms nil) team
+                                       #'filter #'collector)))))
+
+(defmacro helm-slack-bind-room-and-team (candidate &rest body)
+  (declare (indent 2) (debug t))
+  `(let ((room (car ,candidate))
+         (team (cadr ,candidate)))
+     ,@body))
+
+(defmacro helm-slack-bind-user-and-team (candidate &rest body)
+  (declare (indent 2) (debug t))
+  `(let ((user (car ,candidate))
+         (team (cadr ,candidate)))
+     ,@body))
+
+(defun helm-slack-persistent-action (candidate)
+  (helm-slack-bind-room-and-team candidate
+      (let* ((buffer (slack-create-room-info-buffer room team)))
+        (switch-to-buffer (slack-buffer-buffer buffer)))))
+
+(defun helm-slack-display-room (candidate)
+  (helm-slack-bind-room-and-team candidate
+      (slack-room-display room team)))
+
+(defun helm-slack-archive-room (candidate)
+  (helm-slack-bind-room-and-team candidate
+      (slack-conversations-archive room team)))
+
+(defun helm-slack-invite-to-room (candidate)
+  (helm-slack-bind-room-and-team candidate
+      (slack-conversations-invite room team)))
+
+(defun helm-slack-join-room (candidate)
+  (helm-slack-bind-room-and-team candidate
+      (slack-conversations-join room team)))
+
+(defun helm-slack-leave-room (candidate)
+  (helm-slack-bind-room-and-team candidate
+      (slack-conversations-leave room team)))
+
+(defun helm-slack-rename-room (candidate)
+  (helm-slack-bind-room-and-team candidate
+      (slack-conversations-rename room team)))
+
+(defun helm-slack-set-purpose-for-room (candidate)
+  (helm-slack-bind-room-and-team candidate
+      (slack-conversations-set-purpose room team)))
+
+(defun helm-slack-set-topic-of-room (candidate)
+  (helm-slack-bind-room-and-team candidate
+      (slack-conversations-set-topic room team)))
+
+(defun helm-slack-kick-from-room (candidate)
+  (helm-slack-bind-room-and-team candidate
+      (slack-conversations-kick room team)))
+
+(defun helm-slack-list-member-in-room (candidate)
+  (helm-slack-bind-room-and-team candidate
+      (helm-slack-members-in-room room team)))
+
+(defun helm-slack-members-in-room (room team)
+  (let ((candidates nil)
+        (cursor nil))
+    (cl-labels
+        ((inject-team (candidates)
+                      (mapcar #'(lambda (candidate)
+                                  (list (car candidate)
+                                        (cdr candidate)
+                                        team))
+                              candidates))
+         (on-members-success (members next-cursor)
+                             (setq candidates (append candidates
+                                                      members))
+                             (setq cursor next-cursor)))
+      (while (or (null cursor)
+                 (< 0 (length cursor)))
+        (slack-conversations-members room
+                                     team
+                                     cursor
+                                     #'on-members-success))
+      (helm
+       :prompt "Select Member : "
+       :sources (helm-build-sync-source "Members"
+                  :candidates (inject-team candidates)
+                  :action helm-slack-members-actions)))))
+
+(defun helm-slack-display-user (candidate)
+  (helm-slack-bind-user-and-team candidate
+      (let* ((user-id (plist-get user :id))
+             (buffer (slack-create-user-profile-buffer team
+                                                       user-id)))
+        (slack-buffer-display buffer))))
+
+(defun helm-slack ()
+  "Helm Slack"
+  (interactive)
+  (helm
+   :prompt "Select Channel : "
+   :sources helm-slack-sources))
+
+(provide 'helm-slack)
+;;; helm-slack.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-action.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-action.el
new file mode 100644
index 000000000000..b3fc1b41203d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-action.el
@@ -0,0 +1,90 @@
+;;; slack-action.el ---                              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'slack-util)
+
+(defvar slack-action-keymap
+  (let ((keymap (make-sparse-keymap)))
+    (define-key keymap (kbd "RET") #'slack-action-run)
+    (define-key keymap [mouse-1] #'slack-action-run)
+    keymap))
+
+(defface slack-message-action-face
+  '((t (:box (:line-width 1 :style released-button))))
+  "Face used to action."
+  :group 'slack)
+
+(defun slack-message-run-action ()
+  (interactive)
+  (slack-if-let* ((buffer slack-current-buffer)
+                  (room (oref buffer room))
+                  (ts (slack-get-ts))
+                  (message (slack-room-find-message room ts))
+                  (_not-ephemeral-messagep (not (oref message is-ephemeral))))
+      (slack-buffer-execute-message-action buffer ts)))
+
+(defun slack-action-run ()
+  (interactive)
+  (slack-if-let* ((bot (get-text-property (point) 'bot))
+                  (payload (get-text-property (point) 'payload))
+                  (buffer slack-current-buffer)
+                  (team (oref buffer team)))
+      (let ((url "https://slack.com/api/chat.action")
+            (params (list (cons "bot" bot)
+                          (cons "payload" payload))))
+        (cl-labels
+            ((log-error (err) (format "Error: %s, URL: %s, PARAMS: %s"
+                                      err
+                                      url
+                                      params))
+             (on-success (&key data &allow-other-keys)
+                         (slack-request-handle-error
+                          (data "slack-action-run" #'log-error))))
+          (slack-request
+           (slack-request-create
+            url
+            team
+            :type "POST"
+            :params params
+            :success #'on-success))))))
+
+(defun slack-display-inline-action ()
+  (goto-char (point-min))
+  (let ((regexp "<slack-action://\\(.*?\\)/\\(.*?\\)|\\(.*?\\)>"))
+    (while (re-search-forward regexp (point-max) t)
+      (let ((bot (match-string 1))
+            (payload (match-string 2))
+            (label (match-string 3))
+            (beg (- (match-beginning 1) 16))
+            (end (+ (match-end 3) 1)))
+        (replace-match (propertize label
+                                   'face 'slack-message-action-face
+                                   'bot bot
+                                   'payload payload
+                                   'org-text (match-string 0)
+                                   'keymap slack-action-keymap))))))
+
+(provide 'slack-action)
+;;; slack-action.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-action.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-action.elc
new file mode 100644
index 000000000000..7f670126b659
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-action.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-attachment.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-attachment.el
new file mode 100644
index 000000000000..c51f8851843b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-attachment.el
@@ -0,0 +1,529 @@
+;;; slack-attachment.el ---                          -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-request)
+(require 'slack-selectable)
+
+(defclass slack-attachment ()
+  ((fallback :initarg :fallback :initform nil)
+   (title :initarg :title :initform nil)
+   (title-link :initarg :title_link :initform nil)
+   (pretext :initarg :pretext :initform nil)
+   (text :initarg :text :initform nil)
+   (author-name :initarg :author_name :initform nil)
+   (author-link :initarg :author_link)
+   (author-icon :initarg :author_icon)
+   (fields :initarg :fields :initform '())
+   (image-url :initarg :image_url :initform nil)
+   (image-width :initarg :image_width :initform nil)
+   (image-height :initarg :image_height :initform nil)
+   (thumb-url :initarg :thumb_url)
+   (is-share :initarg :is_share :initform nil)
+   (footer :initarg :footer :initform nil)
+   (color :initarg :color :initform nil)
+   (ts :initarg :ts :initform nil)
+   (author-subname :initarg :author_subname :initform nil)
+   (callback-id :initarg :callback_id :initform nil)
+   (id :initarg :id :initform nil)
+   (actions :initarg :actions :initform '())))
+
+(defclass slack-shared-message (slack-attachment)
+  ((channel-id :initarg :channel_id :initform nil)
+   (channel-name :initarg :channel_name :initform nil)
+   (from-url :initarg :from_url :initform nil)))
+
+(defclass slack-attachment-field ()
+  ((title :initarg :title :initform nil)
+   (value :initarg :value :initform nil)
+   (short :initarg :short :initform nil)))
+
+(defclass slack-attachment-action-confirmation ()
+  ((title :initarg :title :initform nil)
+   (text :initarg :text :type string)
+   (ok-text :initarg :ok_text :type string :initform "Okay")
+   (dismiss-text :initarg :dismiss_text :type string :initform "Cancel")))
+
+(defclass slack-attachment-action ()
+  ((id :initarg :id :type string)
+   (name :initarg :name :type string)
+   (text :initarg :text :type string)
+   (type :initarg :type :type string)
+   (value :initarg :value :initform nil)
+   (confirm :initarg :confirm :initform nil
+            :type (or null slack-attachment-action-confirmation))
+   (style :initarg :style :type string :initform "default")
+   (url :initarg :url :type (or null string) :initform nil)))
+
+(defclass slack-attachment-select-action (slack-attachment-action slack-selectable)
+  ((min-query-length :initarg :min_query_length :type (or null number) :initform nil)))
+
+(defclass slack-attachment-select-action-option (slack-selectable-option) ())
+
+(defclass slack-attachment-select-action-option-group
+  (slack-selectable-option-group) ())
+
+
+
+(defun slack-attachment-action-create (payload)
+  (cl-labels
+      ((create-option (option)
+                      (apply #'make-instance
+                             'slack-attachment-select-action-option
+                             (slack-collect-slots
+                              'slack-attachment-select-action-option
+                              option)))
+       (create-option-group
+        (option-group)
+        (when (plist-get option-group :options)
+          (setq option-group
+                (plist-put option-group
+                           :options
+                           (mapcar #'create-option
+                                   (plist-get option-group :options)))))
+        (apply #'make-instance
+               'slack-attachment-select-action-option-group
+               (slack-collect-slots
+                'slack-attachment-select-action-option-group
+                option-group))))
+    (let* ((properties payload)
+           (type (plist-get payload :type)))
+
+      (when (plist-get payload :confirm)
+        (setq properties (plist-put properties
+                                    :confirm
+                                    (apply #'make-instance
+                                           'slack-attachment-action-confirmation
+                                           (slack-collect-slots
+                                            'slack-attachment-action-confirmation
+                                            (plist-get payload :confirm))))))
+      (cond
+       ((string= type "select")
+        (progn
+          (setq properties
+                (plist-put properties
+                           :options
+                           (mapcar #'create-option
+                                   (plist-get properties :options))))
+          (setq properties
+                (plist-put properties
+                           :option_groups
+                           (mapcar #'create-option-group
+                                   (plist-get properties :option_groups))))
+          (setq properties
+                (plist-put properties
+                           :selected_options
+                           (mapcar #'create-option
+                                   (plist-get properties :selected_options))))
+          (apply #'make-instance 'slack-attachment-select-action
+                 (slack-collect-slots 'slack-attachment-select-action properties))))
+       (t
+        (apply #'make-instance 'slack-attachment-action
+               (slack-collect-slots 'slack-attachment-action properties)))))))
+
+(defun slack-attachment-create (payload)
+  (let ((properties payload))
+    (setq payload
+          (plist-put payload :fields
+                     (mapcar #'(lambda (field)
+                                 (apply #'slack-attachment-field
+                                        (slack-collect-slots 'slack-attachment-field
+                                                             field)))
+                             (append (plist-get payload :fields) nil))))
+    (setq payload
+          (plist-put payload :actions
+                     (mapcar #'slack-attachment-action-create
+                             (plist-get payload :actions))))
+
+    (when (numberp (plist-get payload :ts))
+      (setq payload
+            (plist-put payload :ts (number-to-string (plist-get payload :ts)))))
+
+    ;; (message "PAYLOAD: %s" payload)
+
+    (if (plist-get payload :is_share)
+        (apply #'slack-shared-message "shared-attachment"
+               (slack-collect-slots 'slack-shared-message payload))
+      (apply #'slack-attachment "attachment"
+             (slack-collect-slots 'slack-attachment payload)))))
+
+(defmethod slack-image-spec ((this slack-attachment))
+  (with-slots (image-url image-height image-width) this
+    (when image-url
+      (list image-url image-width image-height slack-image-max-height))))
+
+(defface slack-message-action-primary-face
+  '((t (:box (:line-width 1 :style released-button)
+             :foreground "#2aa198")))
+  "Face used to primary action."
+  :group 'slack)
+
+(defface slack-message-action-danger-face
+  '((t (:box (:line-width 1 :style released-button)
+             :foreground "#FF6E64")))
+  "Face used to danger action."
+  :group 'slack)
+
+(defvar slack-attachment-action-keymap
+  (let ((keymap (make-sparse-keymap)))
+    (define-key keymap (kbd "RET") #'slack-attachment-action-run)
+    (define-key keymap [mouse-1] #'slack-attachment-action-run)
+    keymap))
+
+(defmethod slack-attachment-action-run-payload ((this slack-attachment-action)
+                                                team
+                                                common-payload
+                                                service-id)
+  (with-slots (id name text type value style) this
+    (cons (cons "actions" (list (list (cons "id" id)
+                                      (cons "name" name)
+                                      (cons "text" text)
+                                      (cons "type" type)
+                                      (cons "value" value)
+                                      (cons "style" style))))
+          common-payload)))
+
+(defmethod slack-attachment-action-get-suggestions ((this
+                                                     slack-attachment-select-action)
+                                                    team
+                                                    common-payload
+                                                    service-id
+                                                    after-success)
+  (with-slots (name) this
+    (let ((url "https://slack.com/api/chat.attachmentSuggestion")
+          (params (list (cons "service_id" service-id)
+                        (cons "payload"
+                              (json-encode-alist
+                               (cons
+                                (cons "name" name)
+                                (cons (cons "value"
+                                            (read-from-minibuffer
+                                             (format "Start typing to see results... (minimum: %s) "
+                                                     (oref this min-query-length))))
+                                      common-payload)))))))
+
+      (cl-labels
+          ((log-error (err)
+                      (slack-log (format "Error: %s, URL: %s, PARAMS: %s"
+                                         err
+                                         url
+                                         params)
+                                 team :level 'error))
+           (on-success (&key data &allow-other-keys)
+                       (slack-request-handle-error
+                        (data "slack-attachment-action-get-suggestions"
+                              #'log-error))
+                       (funcall after-success (plist-get data :options))))
+        (slack-request
+         (slack-request-create
+          url
+          team
+          :type "POST"
+          :success #'on-success
+          :params params
+          :sync t))))))
+
+(defmethod slack-attachment-action-selected-options ((this
+                                                      slack-attachment-select-action)
+                                                     team
+                                                     common-payload
+                                                     service-id)
+  (with-slots (data-source) this
+    (cond
+     ((string= data-source "external")
+      (let ((option))
+        (cl-labels
+            ((on-success (options)
+                         (let ((selected
+                                (funcall slack-completing-read-function
+                                         ""
+                                         (cons "" (mapcar #'(lambda (e)
+                                                              (plist-get e :text))
+                                                          options))
+                                         nil t)))
+
+                           (setq option
+                                 (cl-find-if #'(lambda (e)
+                                                 (string= selected
+                                                          (plist-get e :text)))
+                                             options)))))
+          (slack-attachment-action-get-suggestions this
+                                                   team
+                                                   common-payload
+                                                   service-id
+                                                   #'on-success)
+          (if option
+              (list (list (cons "value" (plist-get option :value))))
+            (slack-attachment-action-selected-options
+             this team common-payload service-id)))))
+     ((string= data-source "conversations")
+      (let ((room-id (oref (slack-room-select (append (oref team channels)
+                                                      (oref team groups)
+                                                      (oref team ims))
+                                              team)
+                           id)))
+        (list (list (cons "value" room-id)))))
+     ((string= data-source "channels")
+      (let ((channel-id (oref (slack-room-select (oref team channels)
+                                                 team) id)))
+        (list (list (cons "value" channel-id)))))
+     ((string= data-source "users")
+      (let ((user-id (plist-get (slack--user-select team) :id)))
+        (list (list (cons "value" user-id)))))
+     ((string= data-source "static")
+      (slack-if-let*
+          ((option (slack-selectable-select-from-static-data-source this))
+           (selected-options (list (list (cons "value"
+                                               (oref option value))))))
+          selected-options
+        (error "Option is not selected")))
+     (t (error "%s's data-source: %s is not implemented"
+               (oref this name)
+               (oref this data-source))))))
+
+(defmethod slack-attachment-action-run-payload ((this slack-attachment-select-action)
+                                                team
+                                                common-payload
+                                                service-id)
+  (with-slots (id name text type value style data-source min-query-length) this
+    (slack-if-let*
+        ((selected-options (slack-attachment-action-selected-options this
+                                                                     team
+                                                                     common-payload
+                                                                     service-id)))
+        (cons (cons "actions"
+                    (list (list (cons "id" id)
+                                (cons "name" name)
+                                (cons "text" text)
+                                (cons "type" type)
+                                (cons "style" style)
+                                (cons "data_source" data-source)
+                                (cons "min_query_length" min-query-length)
+                                (cons "selected_options" selected-options))))
+              common-payload)
+      (error "Option is not selected"))))
+
+(defmethod slack-attachment-action-confirm ((this slack-attachment-action))
+  (with-slots (confirm) this
+    (if confirm
+        (with-slots (title text ok-text dismiss-text) confirm
+          (yes-or-no-p (format "%s%s"
+                               (if title
+                                   (format "%s\n" title)
+                                 "")
+                               text)))
+      t)))
+
+(defun slack-attachment-action-run ()
+  (interactive)
+  (slack-if-let* ((buffer slack-current-buffer)
+                  (room (oref buffer room))
+                  (team (oref buffer team))
+                  (type (get-text-property (point) 'type))
+                  (attachment-id (get-text-property (point) 'attachment-id))
+                  (ts (slack-get-ts))
+                  (message (slack-room-find-message room ts))
+                  (action (get-text-property (point) 'action)))
+      (when (slack-attachment-action-confirm action)
+        (slack-if-let* ((callback-id (get-text-property (point) 'callback-id))
+                        (common-payload (list
+                                         (cons "attachment_id" (number-to-string
+                                                                attachment-id))
+                                         (cons "callback_id" callback-id)
+                                         (cons "is_ephemeral" (oref message
+                                                                    is-ephemeral))
+                                         (cons "message_ts" ts)
+                                         (cons "channel_id" (oref room id))))
+                        (service-id (if (slack-bot-message-p message)
+                                        (slack-message-bot-id message)
+                                      "B01")))
+            (let ((url "https://slack.com/api/chat.attachmentAction")
+                  (params (list (cons "payload"
+                                      (json-encode-alist
+                                       (slack-attachment-action-run-payload
+                                        action
+                                        team
+                                        common-payload
+                                        service-id)))
+                                (cons "service_id" service-id)
+                                (cons "client_token"
+                                      (slack-team-client-token team)))))
+              (cl-labels
+                  ((log-error (err)
+                              (slack-log (format "Error: %s, URL: %s, PARAMS: %s"
+                                                 err
+                                                 url
+                                                 params)
+                                         team
+                                         :level 'error))
+                   (on-success (&key data &allow-other-keys)
+                               (slack-request-handle-error
+                                (data "slack-attachment-action-run" #'log-error))))
+                (slack-request
+                 (slack-request-create
+                  url
+                  team
+                  :type "POST"
+                  :params params
+                  :success #'on-success))))
+          (slack-if-let* ((url (oref action url)))
+              (browse-url url))))))
+
+(defmethod slack-attachment-callback-id ((this slack-attachment))
+  (oref this callback-id))
+
+(defmethod slack-attachment-id ((this slack-attachment))
+  (oref this id))
+
+(defmethod slack-attachment-action-face ((this slack-attachment-action))
+  (with-slots (style) this
+    (or (and (string= "danger" style)
+             'slack-message-action-danger-face)
+        (and (string= "primary" style)
+             'slack-message-action-primary-face)
+        'slack-message-action-face)))
+
+(defmethod slack-attachment-action-display-text ((this slack-attachment-action))
+  (replace-regexp-in-string ":" " " (oref this text)))
+
+
+(defmethod slack-attachment-action-display-text ((this slack-attachment-select-action))
+  (let ((base (call-next-method)))
+    (with-slots (selected-options) this
+      (format "%s%s" base (if (and selected-options (car selected-options))
+                              (format " (%s)"
+                                      (slack-selectable-text (car selected-options)))
+                            "")))))
+
+
+(defmethod slack-attachment-action-to-string ((action slack-attachment-select-action)
+                                              attachment team)
+  (with-slots (id name text type data-source style options option-groups) action
+    (let* ((callback-id (slack-attachment-callback-id attachment))
+           (attachment-id (slack-attachment-id attachment))
+           (face (slack-attachment-action-face action)))
+      (propertize (slack-attachment-action-display-text action)
+                  'type type
+                  'face face
+                  'attachment-id attachment-id
+                  'callback-id callback-id
+                  'action action
+                  'keymap slack-attachment-action-keymap))))
+
+(defmethod slack-attachment-action-to-string ((action slack-attachment-action)
+                                              attachment team)
+  (with-slots (id name text type value style) action
+    (let* ((callback-id (slack-attachment-callback-id attachment))
+           (attachment-id (slack-attachment-id attachment))
+           (face (slack-attachment-action-face action)))
+      (propertize (slack-attachment-action-display-text action)
+                  'type type
+                  'face face
+                  'keymap slack-attachment-action-keymap
+                  'attachment-id attachment-id
+                  'callback-id callback-id
+                  'action action))))
+
+(defmethod slack-message-to-string ((attachment slack-attachment) team)
+  (with-slots
+      (fallback text ts color from-url footer fields pretext actions) attachment
+    (let* ((pad-raw (propertize "|" 'face 'slack-attachment-pad))
+           (pad (or (and color (propertize pad-raw 'face (list :foreground (concat "#" color))))
+                    pad-raw))
+           (header-raw (slack-attachment-header attachment))
+           (header (and (not (slack-string-blankp header-raw))
+                        (format "%s\t%s" pad
+                                (propertize header-raw
+                                            'face 'slack-attachment-header))))
+           (pretext (and pretext (format "%s\t%s" pad pretext)))
+           (body (and text (format "%s\t%s" pad (mapconcat #'identity
+                                                           (split-string text "\n")
+                                                           (format "\n\t%s\t" pad)))))
+           (fields (if fields (mapconcat #'(lambda (field)
+                                             (slack-attachment-field-to-string field
+                                                                               (format "\t%s" pad)))
+                                         fields
+                                         (format "\n\t%s\n" pad))))
+           (actions (if actions
+                        (format "%s\t%s"
+                                pad
+                                (mapconcat #'(lambda (action)
+                                               (slack-attachment-action-to-string
+                                                action
+                                                attachment
+                                                team))
+                                           actions
+                                           " "))))
+           (footer (if footer
+                       (format "%s\t%s"
+                               pad
+                               (propertize
+                                (format "%s%s" footer
+                                        (or (and ts (format "|%s" (slack-message-time-to-string ts)))
+                                            ""))
+                                'face 'slack-attachment-footer))))
+           (image (slack-image-string (slack-image-spec attachment)
+                                      (format "\t%s\t" pad))))
+      (slack-message-unescape-string
+       (slack-format-message
+        (or (and header (format "\t%s\n" header)) "")
+        (or (and pretext (format "\t%s\n" pretext)) "")
+        (or (and body (format "\t%s" body)) "")
+        (or (and fields fields) "")
+        (or (and actions (format "\t%s" actions)) "")
+        (or (and footer (format "\n\t%s" footer)) "")
+        (or (and image (< 0 (length image))
+                 (format "\n\t%s\t%s" pad image)) ""))
+       team))))
+
+(defmethod slack-attachment-header ((attachment slack-attachment))
+  (with-slots (title title-link author-name author-subname) attachment
+    (concat (or (and title title-link (slack-linkfy title title-link))
+                title
+                "")
+            (or author-name author-subname ""))))
+
+(defmethod slack-attachment-field-to-string ((field slack-attachment-field) &optional pad)
+  (unless pad (setq pad ""))
+  (let ((title (propertize (or (oref field title) "") 'face 'slack-attachment-field-title))
+        (value (mapconcat #'(lambda (e) (format "\t%s" e))
+                          (split-string (or (oref field value) "") "\n")
+                          (format "\n%s\t" pad))))
+    (format "%s\t%s\n%s\t%s" pad title pad value)))
+
+(defmethod slack-attachment-to-alert ((a slack-attachment))
+  (with-slots (title fallback pretext) a
+    (if (and title (< 0 (length title)))
+        title
+      (if (and pretext (< 0 (length pretext)))
+          (format "%s\n%s" pretext fallback)
+        fallback))))
+
+(defmethod slack-selectable-prompt ((this slack-attachment-select-action))
+  (format "%s :" (oref this text)))
+
+(provide 'slack-attachment)
+;;; slack-attachment.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-attachment.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-attachment.elc
new file mode 100644
index 000000000000..555a22489773
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-attachment.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-autoloads.el
new file mode 100644
index 000000000000..8ab3abc48d75
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-autoloads.el
@@ -0,0 +1,59 @@
+;;; slack-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "slack" "slack.el" (23450 31802 42642 184000))
+;;; Generated autoloads from slack.el
+
+(autoload 'slack-start "slack" "\
+
+
+\(fn &optional TEAM)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "slack-team" "slack-team.el" (23450 31802 96924
+;;;;;;  354000))
+;;; Generated autoloads from slack-team.el
+
+(autoload 'slack-register-team "slack-team" "\
+PLIST must contain :name :client-id :client-secret with value.
+setting :token will reduce your configuration step.
+you will notified when receive message with channel included in subscribed-channels.
+if :default is t and `slack-prefer-current-team' is t, skip selecting team when channels listed.
+you can change current-team with `slack-change-current-team'
+
+\(fn &rest PLIST)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("helm-slack.el" "slack-action.el" "slack-attachment.el"
+;;;;;;  "slack-bot-message.el" "slack-buffer.el" "slack-channel.el"
+;;;;;;  "slack-conversations.el" "slack-dialog-buffer.el" "slack-dialog-edit-element-buffer.el"
+;;;;;;  "slack-dialog.el" "slack-emoji.el" "slack-file-info-buffer.el"
+;;;;;;  "slack-file-list-buffer.el" "slack-file.el" "slack-group.el"
+;;;;;;  "slack-im.el" "slack-message-buffer.el" "slack-message-compose-buffer.el"
+;;;;;;  "slack-message-edit-buffer.el" "slack-message-editor.el"
+;;;;;;  "slack-message-formatter.el" "slack-message-notification.el"
+;;;;;;  "slack-message-reaction.el" "slack-message-sender.el" "slack-message-share-buffer.el"
+;;;;;;  "slack-message.el" "slack-pinned-item.el" "slack-pinned-items-buffer.el"
+;;;;;;  "slack-pkg.el" "slack-reaction.el" "slack-reminder.el" "slack-reply.el"
+;;;;;;  "slack-request-worker.el" "slack-request.el" "slack-room-buffer.el"
+;;;;;;  "slack-room-info-buffer.el" "slack-room-message-compose-buffer.el"
+;;;;;;  "slack-room.el" "slack-search-result-buffer.el" "slack-search.el"
+;;;;;;  "slack-selectable.el" "slack-slash-commands.el" "slack-star.el"
+;;;;;;  "slack-stars-buffer.el" "slack-thread-message-buffer.el"
+;;;;;;  "slack-thread-message-compose-buffer.el" "slack-thread.el"
+;;;;;;  "slack-user-message.el" "slack-user-profile-buffer.el" "slack-user.el"
+;;;;;;  "slack-util.el" "slack-websocket.el") (23450 31802 126602
+;;;;;;  293000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; slack-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-bot-message.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-bot-message.el
new file mode 100644
index 000000000000..1f60ff281a2b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-bot-message.el
@@ -0,0 +1,102 @@
+;;; slack-bot-message.el --- bot message class        -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-message)
+(require 'slack-message-formatter)
+(require 'slack-util)
+
+(defmethod slack-message-bot-id ((this slack-bot-message))
+  (oref this bot-id))
+
+(defun slack-find-bot (id team)
+  (with-slots (bots) team
+    (cl-find-if (lambda (bot)
+                  (string= id (plist-get bot :id)))
+                bots)))
+
+(defun slack-find-bot-by-name (name team)
+  (with-slots (bots) team
+    (cl-find-if #'(lambda (bot)
+                    (string= name (plist-get bot :name)))
+                bots)))
+
+(defmethod slack-bot-name ((m slack-bot-message) team)
+  (or (unless (slack-string-blankp (oref m username))
+        (oref m username))
+      (when (slot-boundp m 'bot-id)
+        (let ((bot (slack-find-bot (oref m bot-id) team)))
+          (plist-get bot :name)))
+      "Unknown Bot"))
+
+(defmethod slack-message-to-alert ((m slack-bot-message) team)
+  (let ((text (if (slot-boundp m 'text)
+                  (oref m text))))
+    (with-slots (attachments) m
+      (if (and text (< 0 (length text)))
+          (slack-message-unescape-string text team)
+        (let ((attachment-string (mapconcat #'slack-attachment-to-alert attachments " ")))
+          (slack-message-unescape-string attachment-string team))))))
+
+(defmethod slack-message-sender-name ((m slack-bot-message) team)
+  (slack-bot-name m team))
+
+(defmethod slack-message-sender-id ((m slack-bot-message))
+  (oref m bot-id))
+
+(defun slack-bot-image-url (bot size)
+  (let ((icons (plist-get bot :icons)))
+    (cond
+     ((eq size 36) (plist-get icons :image_36))
+     ((eq size 48) (plist-get icons :image_48))
+     ((eq size 72) (plist-get icons :image_72))
+     (t (plist-get icons :image_36)))))
+
+(defun slack-bot-fetch-image (bot size team)
+  (let* ((image-url (slack-bot-image-url bot size))
+         (file-path (and image-url (slack-profile-image-path image-url team))))
+    (when file-path
+      (if (file-exists-p file-path) file-path
+        (slack-url-copy-file image-url file-path))
+      file-path)))
+
+(cl-defun slack-bot-image (bot team &optional (size 36))
+  (when bot
+    (let ((image (slack-bot-fetch-image bot size team)))
+      (when image
+        (create-image image nil nil :ascent 80)))))
+
+(defmethod slack-bot-find ((m slack-bot-message) team)
+  (or (and (slot-boundp m 'bot-id)
+           (slack-find-bot (slack-message-sender-id m) team))
+      (slack-user-find-by-name (oref m username) team)))
+
+(defmethod slack-message-profile-image ((m slack-bot-message) team)
+  (let ((bot (slack-bot-find m team)))
+    (slack-bot-image bot team)))
+
+(provide 'slack-bot-message)
+;;; slack-bot-message.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-bot-message.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-bot-message.elc
new file mode 100644
index 000000000000..f63e5596a7c4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-bot-message.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-buffer.el
new file mode 100644
index 000000000000..ea56844e177f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-buffer.el
@@ -0,0 +1,448 @@
+;;; slack-buffer.el --- slack buffer                  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'lui)
+(require 'slack-util)
+(require 'slack-room)
+
+(define-derived-mode slack-buffer-mode lui-mode "Slack Buffer"
+  (setq-local default-directory slack-default-directory)
+  (add-hook 'lui-pre-output-hook 'slack-buffer-buttonize-link nil t)
+  (add-hook 'lui-pre-output-hook 'slack-add-face-lazy nil t)
+  (add-hook 'lui-post-output-hook 'slack-display-image t t)
+  (lui-set-prompt " "))
+
+(defvar-local slack-current-buffer nil)
+
+(defclass slack-buffer ()
+  ((team :initarg :team :type slack-team)))
+
+(defun slack-buffer-push-new-3 (class a team)
+  (let ((buf (get-buffer (slack-buffer-name class a team))))
+    (unless (slack-buffer-find class a team)
+      (push buf
+            (slot-value team class)))
+    buf))
+
+(defun slack-buffer-push-new-4 (class a b team)
+  (let ((buf (get-buffer (slack-buffer-name class a b team))))
+    (unless (slack-buffer-find class a b team)
+      (push buf (slot-value team class)))
+    buf))
+
+(defmethod slack-buffer-find :static ((class slack-buffer) room team)
+  (slack-if-let* ((buf (cl-find-if
+                  #'(lambda (buf)
+                      (string= (buffer-name buf)
+                               (slack-buffer-name class room team)))
+                  (slot-value team class))))
+      (with-current-buffer buf slack-current-buffer)))
+
+(defmethod slack-buffer-buffer ((this slack-buffer))
+  (or (get-buffer (slack-buffer-name this))
+      (slack-buffer-init-buffer this)))
+
+(defmethod slack-buffer-display ((this slack-buffer))
+  (condition-case err
+      (funcall slack-buffer-function (slack-buffer-buffer this))
+    (error (progn
+             (slack-if-let* ((buf (get-buffer (slack-buffer-name this))))
+                 (kill-buffer buf))
+             (signal (car err) (cdr err))))))
+
+(defmethod slack-buffer-name ((this slack-buffer))
+  "*Slack*")
+
+(defun slack-message-buffer-on-killed ()
+  (slack-if-let* ((buf slack-current-buffer)
+            (class (eieio-object-class-name buf))
+            (cb (current-buffer)))
+      (set-slot-value (oref buf team) class
+                      (cl-remove-if #'(lambda (e) (equal e cb))
+                                    (slot-value (oref buf team) class)))))
+
+(defun slack-buffer-replace-image (buffer ts)
+  (and (buffer-live-p buffer)
+       (with-current-buffer buffer
+         (slack-buffer--replace slack-current-buffer ts))))
+
+(defun slack-display-image ()
+  (goto-char (point-min))
+  (while (re-search-forward "\\[Image\\]" (point-max) t)
+    (slack-if-let* ((spec (get-text-property (1- (point)) 'slack-image-spec))
+                    (end (point))
+                    (beg (previous-single-property-change end 'slack-image-spec))
+                    (cur-buffer (current-buffer))
+                    (url (car spec))
+                    (ts (get-text-property beg 'ts))
+                    (path (slack-image-path url)))
+        (let* ((no-token-p (get-text-property (1- (point)) 'no-token))
+               (token (and (not no-token-p)
+                           (oref (oref slack-current-buffer team)
+                                 token))))
+          (cl-labels
+              ((on-success ()
+                           (slack-buffer-replace-image cur-buffer ts)))
+            (unless (file-exists-p path)
+              (slack-url-copy-file url
+                                   path
+                                   :success #'on-success
+                                   :token token)))))))
+
+(defmethod slack-buffer-init-buffer :after (this)
+  (slack-if-let* ((buf (get-buffer (slack-buffer-name this))))
+      (progn
+        (with-current-buffer buf
+          (slack-buffer-enable-emojify)
+          (add-hook 'kill-buffer-hook 'slack-message-buffer-on-killed nil t))
+        buf)))
+
+(defmethod slack-buffer-set-current-buffer ((this slack-buffer))
+  (setq-local slack-current-buffer this))
+
+
+(defmethod slack-buffer-init-buffer ((this slack-buffer))
+  (generate-new-buffer (slack-buffer-name this)))
+
+(defmethod slack-buffer-replace ((this slack-buffer) message)
+  (with-slots (team) this
+    (with-current-buffer (slack-buffer-buffer this)
+      (lui-replace (slack-message-to-string message team)
+                   (lambda ()
+                     (equal (get-text-property (point) 'ts)
+                            (slack-ts message)))))))
+
+(defun slack-buffer-subscribe-cursor-event (window prev-point type)
+  (slack-if-let* ((buffer slack-current-buffer))
+      (progn
+        (slack-log (format "CURSOR-EVENT: BUFFER: %s, PREV-POINT: %s, POINT: %s, TYPE: %s"
+                           (buffer-name (window-buffer window))
+                           prev-point
+                           (point)
+                           type)
+                   (oref buffer team)
+                   :level 'trace)
+
+        (when (eq type 'entered)
+          (unless (slack-team-mark-as-read-immediatelyp (oref buffer team))
+            (slack-buffer-update-mark buffer))
+          (add-hook 'post-command-hook 'slack-reaction-echo-description t t))
+
+        (when (eq type 'left)
+          (remove-hook 'post-command-hook 'slack-reaction-echo-description t)))))
+
+(defmethod slack-buffer-insert ((this slack-buffer) message &optional not-tracked-p)
+  (let ((lui-time-stamp-time (slack-message-time-stamp message))
+        (team (oref this team)))
+    (lui-insert-with-text-properties
+     (slack-message-to-string message team)
+     'not-tracked-p not-tracked-p
+     'ts (slack-ts message)
+     'slack-last-ts lui-time-stamp-last
+     'cursor-sensor-functions '(slack-buffer-subscribe-cursor-event))
+    (lui-insert "" t)
+    ))
+
+(defmethod slack-buffer-insert-load-more ((this slack-buffer))
+  (let ((str (propertize "(load more)\n"
+                         'face '(:underline t :weight bold)
+                         'keymap (let ((map (make-sparse-keymap)))
+                                   (define-key map (kbd "RET")
+                                     #'(lambda ()
+                                         (interactive)
+                                         (slack-buffer-load-more this)))
+                                   map)
+                         'loading-message t)))
+    (let ((lui-time-stamp-position nil))
+      (lui-insert str))))
+
+(defmethod slack-buffer-loading-message-end-point ((this slack-buffer))
+  (next-single-property-change (point-min) 'loading-message))
+
+(defmethod slack-buffer-delete-load-more-string ((this slack-buffer))
+  (let ((loading-message-end
+         (slack-buffer-loading-message-end-point this)))
+    (delete-region (point-min) loading-message-end)))
+
+(defmethod slack-buffer-prepare-marker-for-history ((_this slack-buffer))
+  (set-marker lui-output-marker (point-min)))
+
+(defmethod slack-buffer-insert--history ((this slack-buffer))
+  (if (slack-buffer-has-next-page-p this)
+      (slack-buffer-insert-load-more this)
+    (let ((lui-time-stamp-position nil))
+      (lui-insert "(no more messages)\n")))
+
+  (slack-buffer-insert-history this))
+
+(defmethod slack-buffer-load-more ((this slack-buffer))
+  (with-slots (team) this
+    (let ((cur-point (point)))
+      (if (slack-buffer-has-next-page-p this)
+          (cl-labels
+              ((after-success
+                ()
+                (with-current-buffer (slack-buffer-buffer this)
+                  (let ((inhibit-read-only t))
+                    (slack-buffer-delete-load-more-string this)
+                    (slack-buffer-prepare-marker-for-history this)
+                    (slack-buffer-insert--history this)
+                    (lui-recover-output-marker)))))
+            (slack-buffer-request-history this #'after-success))
+        (message "No more items.")))))
+
+(defmethod slack-buffer-display-file ((this slack-buffer) file-id)
+  (with-slots (team) this
+    (cl-labels
+        ((open (file _)
+               (slack-buffer-display
+                (slack-create-file-info-buffer team file))))
+      (slack-file-request-info file-id 1 team #'open))))
+
+(defmethod slack-buffer-cant-execute ((this slack-buffer))
+  (error "Can't execute this command from %s" (eieio-object-class-name this)))
+
+(defmethod slack-buffer-display-pins-list ((this slack-buffer))
+  (slack-buffer-cant-execute this))
+(defmethod slack-buffer-pins-add ((this slack-buffer) ts)
+  (slack-buffer-cant-execute this))
+(defmethod slack-buffer-pins-remove ((this slack-buffer) ts)
+  (slack-buffer-cant-execute this))
+(defmethod slack-buffer-display-user-profile ((this slack-buffer))
+  (slack-buffer-cant-execute this))
+(defmethod slack-buffer-copy-link ((this slack-buffer) ts)
+  (slack-buffer-cant-execute this))
+(defmethod slack-file-upload-params ((this slack-buffer))
+  (slack-buffer-cant-execute this))
+(defmethod slack-buffer-execute-message-action ((this slack-buffer) _ts)
+  (slack-buffer-cant-execute this))
+
+(defvar lui-prompt-string "> ")
+
+(defvar slack-mode-map
+  (let ((map (make-sparse-keymap)))
+    ;; (define-key map (kbd "C-s C-r") #'slack-room-update-messages)
+    ;; (define-key map (kbd "C-s C-b") #'slack-message-write-another-buffer)
+    map))
+
+(defcustom slack-default-directory
+  (expand-file-name (concat (or (getenv "HOME") "~") "/"))
+  "default directory at Slack Buffer.")
+
+(define-derived-mode slack-mode lui-mode "Slack"
+  ""
+  (setq-local default-directory slack-default-directory)
+  (lui-set-prompt lui-prompt-string)
+  (setq lui-input-function 'slack-message--send))
+
+(define-derived-mode slack-info-mode lui-mode "Slack Info"
+  ""
+  (setq-local default-directory slack-default-directory)
+  (lui-set-prompt lui-prompt-string))
+
+(defcustom slack-buffer-emojify nil
+  "Show emoji with `emojify' if true."
+  :group 'slack)
+
+(defcustom slack-buffer-create-on-notify nil
+  "Create a room buffer when notification received if it does not yet exist"
+  :group 'slack)
+
+(defmacro slack-buffer-widen (&rest body)
+  `(save-excursion
+     (save-restriction
+       (widen)
+       ,@body)))
+
+(defun slack-buffer-enable-emojify ()
+  (if slack-buffer-emojify
+      (let ((emojify (require 'emojify nil t)))
+        (unless emojify
+          (error "Emojify is not installed"))
+        (emojify-mode t))))
+
+(defun slack-buffer-goto (ts)
+  (let ((point (slack-buffer-ts-eq (point-min) (point-max) ts)))
+    (when point
+      (goto-char point))))
+
+(defface slack-preview-face
+  (let* ((default-bg (or (face-background 'default) "unspecified-bg"))
+         (light-bg (if (equal default-bg "unspecified-bg")
+                       "unspecified-bg"
+                     (color-darken-name default-bg 3)))
+         (dark-bg (if (equal default-bg "unspecified-bg")
+                      "unspecified-bg"
+                    (color-lighten-name default-bg 3))))
+    `((default :inherit (fixed-pitch shadow) :slant normal :weight normal)
+      (((type graphic) (class color) (background dark)) (:background ,dark-bg))
+      (((type graphic) (class color) (background light)) (:background ,light-bg))))
+  "Used preview text and code blocks"
+  :group 'slack)
+
+(defun slack-put-preview-overlay (start end)
+  (let ((overlay (make-overlay start end)))
+    (overlay-put overlay 'face 'slack-preview-face)))
+
+(defalias 'slack-put-email-body-overlay 'slack-put-preview-overlay)
+(defalias 'slack-put-code-block-overlay 'slack-put-preview-overlay)
+
+(defun slack-search-code-block ()
+  (while (re-search-forward "`\\([^`]\\|\n\\)" (point-max) t)
+    (let* ((block-begin (- (point) 4))
+           (block-p (and (<= (point-min) block-begin)
+                         (string= (buffer-substring-no-properties block-begin
+                                                                  (+ block-begin 3))
+                                  "```")))
+           (beg (or (and block-p block-begin) (- (point) 2)))
+           (end-regex (or (and block-p "```") "[^`]`[^`]")))
+
+      (goto-char (+ beg (or (and block-p 3) 1)))
+
+      (if (re-search-forward end-regex (point-max) t)
+          (let* ((end (or (and block-p (1+ (point))) (- (point) 1))))
+            (slack-put-code-block-overlay beg end)
+            (put-text-property beg end 'slack-disable-buttonize t)
+            (goto-char end))))))
+
+
+(defun slack-add-face-lazy ()
+  (let* ((start (or (get-text-property (point-min) 'slack-defer-face)
+                    (next-single-property-change (point-min) 'slack-defer-face)))
+         (end (and start (next-single-property-change start 'slack-defer-face))))
+    (when (and start end)
+      (let ((face-or-func (get-text-property start 'slack-defer-face)))
+        (if (functionp face-or-func)
+            (funcall face-or-func start end)
+          (add-text-properties start end (list 'face face)))))))
+
+(defun slack-buffer-buttonize-link ()
+  (let ((regex "<\\(http://\\|https://\\)\\(.*?\\)|\\([[:ascii:][:nonascii:]]*?\\)>"))
+    (ignore-errors
+      (goto-char (point-min))
+      (while (re-search-forward regex nil t)
+        (let* ((url-begin (match-beginning 1))
+               (cur-point (point))
+               (disabled (get-text-property cur-point 'slack-disable-buttonize))
+               (replace (match-string 3)))
+          (if disabled
+              (replace-match replace nil)
+            (let ((url (concat (match-string 1) (match-string 2))))
+              (replace-match replace nil)
+              (make-button (1- url-begin)
+                           (+ (1- url-begin) (length replace))
+                           'type 'lui-button
+                           'action 'lui-button-activate
+                           'lui-button-function 'browse-url
+                           'lui-button-arguments (list url)))))))))
+
+(defun slack-buffer-show-typing-p (buffer)
+  (cl-case slack-typing-visibility
+    ('frame (slack-buffer-in-current-frame buffer))
+    ('buffer (slack-buffer-current-p buffer))
+    ('never nil)))
+
+(defun slack-buffer-current-p (buffer)
+  (if buffer
+      (string= (buffer-name buffer)
+               (buffer-name (current-buffer)))))
+
+(defun slack-buffer-in-current-frame (buffer)
+  (if buffer
+      (cl-member (buffer-name buffer)
+                 (mapcar #'buffer-name
+                         (mapcar #'window-buffer (window-list)))
+                 :test #'string=)))
+
+(defmacro slack-buffer-goto-char (find-point &rest else)
+  `(let* ((cur-point (point))
+          (ts (get-text-property cur-point 'ts)))
+     (let ((next-point ,find-point))
+       (if next-point
+           (goto-char next-point)
+         (if (< 0 (length ',else))
+             ,@else)))))
+
+(defun slack-buffer-goto-next-message ()
+  (interactive)
+  (slack-buffer-goto-char
+   (slack-buffer-next-point cur-point (point-max) ts)
+   (message "You are on Last Message.")))
+
+(defun slack-buffer-goto-prev-message ()
+  (interactive)
+  (slack-buffer-goto-char
+   (slack-buffer-prev-point cur-point (point-min) ts)
+   (message "You are on First Message.")))
+
+(defun slack-buffer-goto-first-message ()
+  (interactive)
+  (goto-char
+   (slack-buffer-next-point (point-min) (point-max) "0")))
+
+(defun slack-buffer-goto-last-message ()
+  (interactive)
+  (goto-char
+   (slack-buffer-prev-point (point-max) (point-min) (format-time-string "%s"))))
+
+(defun slack-buffer-header-p (point)
+  (let ((face (get-text-property point 'face)))
+    (string= (format "%s" face) "slack-message-output-header")))
+
+(defun slack-buffer-next-point (start end ts)
+  (cl-loop for i from start to end
+           if (and (string< ts
+                            (get-text-property i 'ts))
+                   (slack-buffer-header-p i))
+           return i))
+
+(defun slack-buffer-prev-point (start end ts)
+  (cl-loop for i from start downto end
+           if (and (string< (get-text-property i 'ts)
+                            ts)
+                   (slack-buffer-header-p i))
+           return i))
+
+(defun slack-buffer-ts-eq (start end ts)
+  (if (and start end)
+      (cl-loop for i from start to end
+               if (string= (get-text-property i 'ts)
+                           ts)
+               return i)))
+
+(defun slack--get-channel-id ()
+  (interactive)
+  (with-current-buffer (current-buffer)
+    (slack-if-let* ((buffer slack-current-buffer)
+                    (boundp (slot-boundp buffer 'room))
+                    (room (oref buffer room)))
+        (progn
+          (kill-new (oref room id))
+          (message "%s" (oref room id))))))
+
+(provide 'slack-buffer)
+;;; slack-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-buffer.elc
new file mode 100644
index 000000000000..d56ceafe7bbb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-channel.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-channel.el
new file mode 100644
index 000000000000..d41fcbb4728b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-channel.el
@@ -0,0 +1,277 @@
+;;; slack-channel.el ---slack channel implement      -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-group)
+(require 'slack-buffer)
+(require 'slack-util)
+(require 'slack-request)
+
+(defvar slack-buffer-function)
+
+(defconst slack-channel-history-url "https://slack.com/api/channels.history")
+(defconst slack-channel-list-url "https://slack.com/api/channels.list")
+(defconst slack-channel-buffer-name "*Slack - Channel*")
+(defconst slack-channel-update-mark-url "https://slack.com/api/channels.mark")
+(defconst slack-create-channel-url "https://slack.com/api/channels.create")
+(defconst slack-channel-rename-url "https://slack.com/api/channels.rename")
+(defconst slack-channel-invite-url "https://slack.com/api/channels.invite")
+(defconst slack-channel-leave-url "https://slack.com/api/channels.leave")
+(defconst slack-channel-join-url "https://slack.com/api/channels.join")
+(defconst slack-channel-info-url "https://slack.com/api/channels.info")
+(defconst slack-channel-archive-url "https://slack.com/api/channels.archive")
+(defconst slack-channel-unarchive-url "https://slack.com/api/channels.unarchive")
+(defconst slack-channel-info-url "https://slack.com/api/channels.info")
+
+(defclass slack-channel (slack-group)
+  ((is-member :initarg :is_member :initform nil)
+   (num-members :initarg :num_members :initform 0)))
+
+(defmethod slack-merge ((this slack-channel) other)
+  (call-next-method)
+  (with-slots (is-member num-members) this
+    (setq is-member (oref other is-member))
+    (setq num-members (oref other num-members))))
+
+(defmethod slack-room-buffer-name ((room slack-channel) team)
+  (concat slack-channel-buffer-name
+          " : "
+          (slack-room-display-name room team)))
+
+(defun slack-channel-names (team &optional filter)
+  (with-slots (channels) team
+    (slack-room-names channels team filter)))
+
+(defmethod slack-room-member-p ((room slack-channel))
+  (oref room is-member))
+
+(defun slack-channel-select ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (room (slack-room-select
+                (cl-loop for team in (list team)
+                         for channels = (oref team channels)
+                         nconc channels)
+                team)))
+    (slack-room-display room team)))
+
+(defun slack-channel-list-update (&optional team after-success)
+  (interactive)
+  (let ((team (or team (slack-team-select))))
+    (cl-labels ((on-list-update
+                 (&key data &allow-other-keys)
+                 (slack-request-handle-error
+                  (data "slack-channel-list-update")
+                  (slack-merge-list (oref team channels)
+                                    (mapcar #'(lambda (d)
+                                                (slack-room-create d
+                                                                   team
+                                                                   'slack-channel))
+                                            (plist-get data :channels)))
+
+                  (if after-success
+                      (funcall after-success team))
+                  (mapc #'(lambda (room)
+                            (slack-request-worker-push
+                             (slack-room-create-info-request room team)))
+                        (oref team channels))
+                  (slack-log "Slack Channel List Updated" team :level 'info))))
+      (slack-room-list-update slack-channel-list-url
+                              #'on-list-update
+                              team
+                              :sync nil))))
+
+(defmethod slack-room-update-mark-url ((_room slack-channel))
+  slack-channel-update-mark-url)
+
+(defun slack-create-channel ()
+  (interactive)
+  (let ((team (slack-team-select)))
+    (cl-labels
+        ((on-create-channel (&key data &allow-other-keys)
+                            (slack-request-handle-error
+                             (data "slack-channel-create"))))
+      (slack-create-room slack-create-channel-url
+                         team
+                         #'on-create-channel))))
+
+(defun slack-channel-rename ()
+  (interactive)
+  (slack-room-rename slack-channel-rename-url
+                     #'slack-channel-names))
+
+(defun slack-channel-invite ()
+  (interactive)
+  (slack-room-invite slack-channel-invite-url
+                     #'slack-channel-names))
+
+(defun slack-channel-leave (&optional team select)
+  (interactive)
+  (let* ((team (or team (slack-team-select)))
+         (channel (slack-current-room-or-select
+                   #'(lambda ()
+                       (slack-channel-names
+                        team
+                        #'(lambda (channels)
+                            (cl-remove-if-not #'slack-room-member-p
+                                              channels))))
+                   select)))
+    (slack-channel-request-leave channel team)))
+
+(defun slack-channel-request-leave (channel team)
+  (cl-labels
+      ((on-channel-leave (&key data &allow-other-keys)
+                         (slack-request-handle-error
+                          (data "slack-channel-leave")
+                          (oset channel is-member nil)
+                          (message "Left Channel: %s"
+                                   (slack-room-name channel team)))))
+    (slack-room-request-with-id slack-channel-leave-url
+                                (oref channel id)
+                                team
+                                #'on-channel-leave)))
+
+(defun slack-channel-join (&optional team select)
+  (interactive)
+  (cl-labels
+      ((filter-channel (channels)
+                       (cl-remove-if
+                        #'(lambda (c)
+                            (or (slack-room-member-p c)
+                                (slack-room-archived-p c)))
+                        channels)))
+    (let* ((team (or team (slack-team-select)))
+           (channel (slack-current-room-or-select
+                     #'(lambda ()
+                         (slack-channel-names team
+                                              #'filter-channel))
+                     select)))
+      (slack-channel-request-join channel team))))
+
+(defun slack-channel-request-join (channel team)
+  (cl-labels
+      ((on-channel-join (&key data &allow-other-keys)
+                        (slack-request-handle-error
+                         (data "slack-channel-join"))))
+    (slack-request
+     (slack-request-create
+      slack-channel-join-url
+      team
+      :params (list (cons "name" (slack-room-name channel team)))
+      :success #'on-channel-join))))
+
+(defun slack-channel-create-from-info (id team)
+  (cl-labels
+      ((on-create-from-info
+        (&key data &allow-other-keys)
+        (slack-request-handle-error
+         (data "slack-channel-create-from-info")
+         (let* ((c-data (plist-get data :channel)))
+           (if (plist-get c-data :is_channel)
+               (let ((channel (slack-room-create c-data team 'slack-channel)))
+                 (with-slots (channels) team (push channel channels))
+                 (message "Channel: %s created"
+                          (slack-room-display-name channel
+                                                   team))))))))
+    (slack-channel-fetch-info id team #'on-create-from-info)))
+
+(defun slack-channel-fetch-info (id team success)
+  (slack-request
+   (slack-request-create
+    slack-channel-info-url
+    team
+    :params (list (cons "channel" id))
+    :success success)))
+
+(defun slack-channel-archive ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (channel (slack-current-room-or-select
+                   #'(lambda ()
+                       (slack-channel-names
+                        team
+                        #'(lambda (channels)
+                            (cl-remove-if #'slack-room-archived-p
+                                          channels)))))))
+    (cl-labels
+        ((on-channel-archive (&key data &allow-other-keys)
+                             (slack-request-handle-error
+                              (data "slack-channel-archive"))))
+      (slack-room-request-with-id slack-channel-archive-url
+                                  (oref channel id)
+                                  team
+                                  #'on-channel-archive))))
+
+(defun slack-channel-unarchive ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (channel (slack-current-room-or-select
+                   #'(lambda ()
+                       (slack-channel-names
+                        team
+                        #'(lambda (channels)
+                            (cl-remove-if-not #'slack-room-archived-p
+                                              channels)))))))
+    (cl-labels
+        ((on-channel-unarchive (&key data &allow-other-keys)
+                               (slack-request-handle-error
+                                (data "slack-channel-unarchive"))))
+      (slack-room-request-with-id slack-channel-unarchive-url
+                                  (oref channel id)
+                                  team
+                                  #'on-channel-unarchive))))
+
+(defmethod slack-room-subscribedp ((room slack-channel) team)
+  (with-slots (subscribed-channels) team
+    (let ((name (slack-room-name room team)))
+      (and name
+           (memq (intern name) subscribed-channels)))))
+
+(defmethod slack-room-get-info-url ((_room slack-channel))
+  slack-channel-info-url)
+
+(defmethod slack-room-update-info ((room slack-channel) data team)
+  (let ((new-room (slack-room-create (plist-get data :channel)
+                                     team
+                                     'slack-channel)))
+
+    (slack-merge room new-room)))
+
+(defmethod slack-room-history-url ((_room slack-channel))
+  slack-channel-history-url)
+
+(defmethod slack-room-replies-url ((_room slack-channel))
+  "https://slack.com/api/channels.replies")
+
+(defmethod slack-room-hidden-p ((room slack-channel))
+  (slack-room-archived-p room))
+
+(defmethod slack-room-member-p ((this slack-channel))
+  (oref this is-member))
+
+(provide 'slack-channel)
+;;; slack-channel.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-channel.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-channel.elc
new file mode 100644
index 000000000000..01339737bd16
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-channel.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-conversations.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-conversations.el
new file mode 100644
index 000000000000..f752d0c14783
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-conversations.el
@@ -0,0 +1,278 @@
+;;; slack-conversations.el ---                       -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'slack-request)
+(require 'slack-room)
+
+(defconst slack-conversations-archive-url
+  "https://slack.com/api/conversations.archive")
+(defconst slack-conversations-invite-url
+  "https://slack.com/api/conversations.invite")
+(defconst slack-conversations-join-url
+  "https://slack.com/api/conversations.join")
+(defconst slack-conversations-leave-url
+  "https://slack.com/api/conversations.leave")
+(defconst slack-conversations-rename-url
+  "https://slack.com/api/conversations.rename")
+(defconst slack-conversations-set-purpose-url
+  "https://slack.com/api/conversations.setPurpose")
+(defconst slack-conversations-set-topic-url
+  "https://slack.com/api/conversations.setTopic")
+(defconst slack-conversations-members-url
+  "https://slack.com/api/conversations.members")
+(defconst slack-conversations-kick-url
+  "https://slack.com/api/conversations.kick")
+
+(cl-defun slack-conversations-success-handler (team &key on-errors on-success)
+  (cl-function
+   (lambda (&key data &allow-other-keys)
+     (cl-labels
+         ((replace-underscore-with-space (s)
+                                         (replace-regexp-in-string "_"
+                                                                   " "
+                                                                   s))
+          (log-error
+           (_)
+           (slack-if-let*
+               ((err (plist-get data :error))
+                (message (format "%s"
+                                 (replace-underscore-with-space
+                                  err))))
+               (slack-log message team :level 'error))
+           (slack-if-let*
+               ((errors (plist-get data :errors))
+                (has-handler (functionp on-errors)))
+               (funcall on-errors errors))))
+       (slack-request-handle-error
+        (data "conversations" #'log-error)
+        (slack-if-let* ((warning (plist-get data :warning)))
+            (slack-log (format "%s" (replace-underscore-with-space
+                                     warning))
+                       team
+                       :level 'warn)
+          (when (functionp on-success)
+            (funcall on-success data))))))))
+
+(defun slack-conversations-archive (room team)
+  (let ((id (oref room id)))
+    (slack-request
+     (slack-request-create
+      slack-conversations-archive-url
+      team
+      :type "POST"
+      :params (list (cons "channel" id))
+      :success (slack-conversations-success-handler team)))))
+
+(defun slack-conversations-invite (room team)
+  (let* ((channel (oref room id))
+         (user-names (slack-user-names team))
+         (users nil))
+    (cl-labels
+        ((already-selected-p
+          (user-name)
+          (cl-find-if #'(lambda (e)
+                          (string= e
+                                   (plist-get (cdr user-name)
+                                              :id)))
+                      users))
+         (filter-selected (user-names)
+                          (cl-remove-if #'already-selected-p
+                                        user-names)))
+      (cl-loop for i from 1 upto 30
+               as candidates = (filter-selected user-names)
+               as selected = (slack-select-from-list
+                                 (candidates "Select User: "))
+               while selected
+               do (push (plist-get selected :id) users)))
+    (setq users (mapconcat #'identity users ","))
+
+    (cl-labels
+        ((errors-handler
+          (errors)
+          (let ((message
+                 (mapconcat #'(lambda (err)
+                                (let ((msg (plist-get err :error))
+                                      (user (plist-get err :user)))
+                                  (format "%s%s"
+                                          (replace-regexp-in-string "_" " " msg)
+                                          (or (and user (format ": %s" user))
+                                              ""))))
+                            errors
+                            ", ")))
+            (slack-log message team :level 'error))))
+      (slack-request
+       (slack-request-create
+        slack-conversations-invite-url
+        team
+        :type "POST"
+        :params (list (cons "channel" channel)
+                      (cons "users" users))
+        :success (slack-conversations-success-handler team
+                                                      :on-errors
+                                                      #'errors-handler))))))
+
+(defun slack-conversations-join (room team)
+  (let ((channel (oref room id)))
+    (slack-request
+     (slack-request-create
+      slack-conversations-join-url
+      team
+      :type "POST"
+      :params (list (cons "channel" channel))
+      :success (slack-conversations-success-handler team)))))
+
+(defun slack-conversations-leave (room team)
+  (let ((channel (oref room id)))
+    (slack-request
+     (slack-request-create
+      slack-conversations-leave-url
+      team
+      :type "POST"
+      :params (list (cons "channel" channel))
+      :success (slack-conversations-success-handler team)))))
+
+(defun slack-conversations-rename (room team)
+  (let ((channel (oref room id))
+        (name (read-from-minibuffer "Name: ")))
+    (slack-request
+     (slack-request-create
+      slack-conversations-rename-url
+      team
+      :type "POST"
+      :params (list (cons "channel" channel)
+                    (cons "name" name))
+      :success (slack-conversations-success-handler team)))))
+
+(defun slack-conversations-set-purpose (room team)
+  (let ((channel (oref room id))
+        (purpose (read-from-minibuffer "Purpose: ")))
+    (cl-labels
+        ((on-success (data)
+                     (let* ((channel (plist-get data :channel))
+                            (purpose (plist-get channel :purpose)))
+                       (oset room purpose purpose))))
+      (slack-request
+       (slack-request-create
+        slack-conversations-set-purpose-url
+        team
+        :type "POST"
+        :params (list (cons "channel" channel)
+                      (cons "purpose" purpose))
+        :success (slack-conversations-success-handler team
+                                                      :on-success
+                                                      #'on-success))))))
+
+(defun slack-conversations-set-topic (room team)
+  (let ((channel (oref room id))
+        (topic (read-from-minibuffer "Topic: ")))
+    (cl-labels
+        ((on-success (data)
+                     (let* ((channel (plist-get data :channel))
+                            (topic (plist-get channel :topic)))
+                       (oset room topic topic))))
+      (slack-request
+       (slack-request-create
+        slack-conversations-set-topic-url
+        team
+        :type "POST"
+        :params (list (cons "channel" channel)
+                      (cons "topic" topic))
+        :success (slack-conversations-success-handler team
+                                                      :on-success
+                                                      #'on-success))))))
+
+(defun slack-conversations-members (room team &optional cursor after-success)
+  (let ((channel (oref room id)))
+    (cl-labels
+        ((build-users
+          (members)
+          (cl-remove-if-not #'(lambda (user-name)
+                                (cl-find (plist-get (cdr user-name)
+                                                    :id)
+                                         members
+                                         :test #'string=))
+                            (slack-user-names team)))
+         (on-success
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-conversations-membe")
+           (let* ((members (plist-get data :members))
+                  (meta (plist-get data :response_metadata))
+                  (next-cursor (plist-get meta :next_cursor)))
+             (when (functionp after-success)
+               (funcall after-success
+                        (build-users members)
+                        next-cursor))))))
+      (slack-request
+       (slack-request-create
+        slack-conversations-members-url
+        team
+        :type "GET"
+        :sync t
+        :params (list (cons "channel" channel)
+                      (and cursor (cons "cursor" cursor))
+                      ;; (cons "limit" "1")
+                      )
+        :success #'on-success)))))
+
+(defun slack-conversations-kick (room team)
+  (let ((channel (oref room id))
+        (cursor nil)
+        (user nil)
+        (candidates nil))
+    (cl-labels
+        ((on-member-success (members next-cursor)
+                            (setq candidates members)
+                            (setq cursor next-cursor))
+         (select-member (candidates)
+                        (funcall #'completing-read
+                                 "Select User: " candidates)))
+      (while (not user)
+        (slack-conversations-members room
+                                     team
+                                     cursor
+                                     #'on-member-success)
+        (let ((selected (cl-assoc (select-member (or (and (< 0 (length cursor))
+                                                          (append candidates
+                                                                  (cons "Next page"
+                                                                        'next-page)))
+                                                     candidates))
+                                  candidates
+                                  :test #'string=)))
+          (when selected
+            (unless (eq 'next-page (cdr selected))
+              (setq user (plist-get (cdr selected) :id))))))
+
+      (slack-request
+       (slack-request-create
+        slack-conversations-kick-url
+        team
+        :type "POST"
+        :params (list (cons "channel" channel)
+                      (cons "user" user))
+        :success (slack-conversations-success-handler team))))))
+
+(provide 'slack-conversations)
+;;; slack-conversations.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-conversations.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-conversations.elc
new file mode 100644
index 000000000000..3ca9b1d339b5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-conversations.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-buffer.el
new file mode 100644
index 000000000000..c1d42cb4dca9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-buffer.el
@@ -0,0 +1,377 @@
+;;; slack-dialog-buffer.el ---                       -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-buffer)
+(require 'slack-dialog)
+
+(define-derived-mode slack-dialog-buffer-mode fundamental-mode "Slack Dialog Buffer"
+  (setq-local default-directory slack-default-directory)
+  (setq-local buffer-read-only t))
+
+(defvar slack-dialog-submit-button-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "RET") #'slack-dialog-buffer-submit)
+    (define-key map [mouse-1] #'slack-dialog-buffer-submit)
+    map))
+
+(defvar slack-dialog-cancel-button-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "RET") #'slack-dialog-buffer-cancel)
+    (define-key map [mouse-1] #'slack-dialog-buffer-cancel)
+    map))
+
+(defvar slack-dialog-select-element-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "RET") #'slack-dialog-buffer-select)
+    (define-key map [mouse-1] #'slack-dialog-buffer-select)
+    map))
+
+(defface slack-dialog-element-placeholder-face
+  '((t (:inherit font-lock-comment-face :slant normal
+                 ;; :box (:line-width 1 :color "#fff")
+                 )))
+  "Used to dialog's element placeholder"
+  :group 'slack)
+
+(defface slack-dialog-element-error-face
+  '((t (:inherit font-lock-warning-face)))
+  "Used to dialog's element error message"
+  :group 'slack)
+
+(defface slack-dialog-element-hint-face
+  '((t (:inherit font-lock-comment-face :slant italic)))
+  "Used to dialog's element hint"
+  :group 'slack)
+
+(defface slack-dialog-element-label-face
+  '((t (:weight bold)))
+  "Used to dialog's element label"
+  :group 'slack)
+
+(defface slack-dialog-select-element-input-face
+  '((t (:box (:line-width 1 :style released-button))))
+  "Used to dialog's select element input"
+  :group 'slack)
+
+(defface slack-dialog-title-face
+  '((t (:weight bold :height 1.2)))
+  "Used to dialog's title"
+  :group 'slack)
+
+(defface slack-dialog-submit-button-face
+  '((t (:box (:line-width 1 :style released-button)
+             :foreground "#2aa198")))
+  "Used to dialog's submit button"
+  :group 'slack)
+
+(defface slack-dialog-cancel-button-face
+  '((t (:box (:line-width 1 :style released-button))))
+  "Used to dialog's cancel button"
+  :group 'slack)
+
+(defclass slack-dialog-buffer (slack-buffer)
+  ((dialog-id :initarg :dialog-id :type string)
+   (dialog :initarg :dialog :type slack-dialog)))
+
+(defmethod slack-buffer-name :static ((_class slack-dialog-buffer) dialog-id dialog team)
+  (with-slots (title) dialog
+    (format "*Slack Dialog - %s [%s] : %s*"
+            title
+            dialog-id
+            (slack-team-name team))))
+
+(defmethod slack-buffer-name ((this slack-dialog-buffer))
+  (with-slots (dialog-id dialog team) this
+    (slack-buffer-name 'slack-dialog-buffer
+                       dialog-id dialog team)))
+
+(defmethod slack-buffer-find :static ((class slack-dialog-buffer)
+                                      dialog-id dialog team)
+  (slack-buffer-find-4 class dialog-id dialog team))
+
+(defmethod slack-buffer-insert-label ((this slack-dialog-element))
+  (with-slots (label optional) this
+    (insert (propertize label
+                        'face 'slack-dialog-element-label-face))
+    (when optional
+      (insert " (optional)"))))
+
+(defmethod slack-buffer-insert-hint ((this slack-dialog-text-element))
+  (with-slots (hint) this
+    (when hint
+      (insert "\n")
+      (insert (propertize hint
+                          'face 'slack-dialog-element-hint-face))
+      (insert "\n"))))
+
+(defvar slack-dialog-element-edit-button-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "RET") #'slack-dialog-buffer-open-edit-element-buffer)
+    (define-key map [mouse-1] #'slack-dialog-buffer-open-edit-element-buffer)
+    map))
+
+(defmethod slack-buffer-insert-edit-button ((this slack-dialog-text-element))
+  (insert (propertize " Edit "
+                      'face '(:box (:line-width 1 :style released-button))
+                      'keymap slack-dialog-element-edit-button-map
+                      'slack-dialog-element this)))
+
+(defun slack-dialog-buffer-open-edit-element-buffer ()
+  (interactive)
+  (slack-if-let*
+      ((element (get-text-property (point) 'slack-dialog-element))
+       (buffer slack-current-buffer)
+       (team (oref buffer team))
+       (edit-buffer (slack-create-dialog-element-edit-buffer
+                     buffer element team)))
+      (slack-buffer-display edit-buffer)))
+
+(defmethod slack-buffer-insert-placeholder ((this slack-dialog-text-element))
+  (with-slots (placeholder) this
+    (insert (propertize placeholder
+                        'face 'slack-dialog-element-placeholder-face))))
+
+(defmethod slack-buffer-insert-errors ((this slack-dialog-element))
+  (with-slots (errors) this
+    (mapc #'(lambda (err)
+              (insert (propertize (oref err error-message)
+                                  'face 'slack-dialog-element-error-face))
+              (insert "\n"))
+          errors)))
+
+(defmethod slack-buffer-insert ((this slack-dialog-text-element))
+  (with-slots (value placeholder errors) this
+    (slack-buffer-insert-label this)
+    (insert " ")
+    (slack-buffer-insert-edit-button this)
+    (insert "\n")
+    (if value
+        (insert value)
+      (if placeholder
+          (slack-buffer-insert-placeholder this)
+        (insert "Click Edit")))
+    (insert "\n")
+    (slack-buffer-insert-errors this)
+    (slack-buffer-insert-hint this)))
+
+(defmethod slack-buffer-insert ((this slack-dialog-textarea-element))
+  (with-slots (value placeholder) this
+    (slack-buffer-insert-label this)
+    (insert "  ")
+    (slack-buffer-insert-edit-button this)
+    (insert "\n")
+    (if value
+        (insert value)
+      (if placeholder
+          (slack-buffer-insert-placeholder this)
+        (insert "Click Edit")))
+    (insert "\n")
+    (slack-buffer-insert-errors this)
+    (slack-buffer-insert-hint this)))
+
+(defun slack-dialog-buffer-select ()
+  (interactive)
+  (slack-if-let*
+      ((buffer slack-current-buffer)
+       (team (oref buffer team))
+       (dialog (oref buffer dialog))
+       (dialog-id (oref buffer dialog-id))
+       (element-name (get-text-property (point) 'slack-dialog-element-name))
+       (dialog-element (cl-find-if #'(lambda (el) (string= element-name
+                                                           (oref el name)))
+                                   (oref dialog elements)))
+       (selected (slack-dialog--execute dialog-element
+                                        dialog-id
+                                        team))
+       (label (car selected))
+       (value (cdr selected))
+       (option (make-instance 'slack-dialog-select-option
+                              :label label
+                              :value value)))
+      (progn
+        (oset dialog-element selected-options (list option))
+        (oset dialog-element value value)
+        (slack-dialog-buffer-redisplay buffer))))
+
+(defmethod slack-buffer-insert-select-button ((this slack-dialog-select-element))
+  (let ((label (slack-if-let*
+                   ((selected (slack-dialog-selected-option this)))
+                   (slack-selectable-text selected)
+                 "Choose an option...")))
+
+    (insert (propertize (format " %s " label)
+                        'face 'slack-dialog-select-element-input-face
+                        'keymap slack-dialog-select-element-map
+                        'slack-dialog-element-name (oref this name)))))
+
+(defmethod slack-buffer-insert ((this slack-dialog-select-element))
+  (slack-buffer-insert-label this)
+  (insert "\n")
+  (slack-buffer-insert-select-button this)
+  (insert "\n")
+  (slack-buffer-insert-errors this))
+
+(defun slack-dialog-buffer-submit ()
+  (interactive)
+  (slack-if-let*
+      ((buffer slack-current-buffer))
+      (slack-dialog-buffer--submit buffer)))
+
+(defmethod slack-dialog-buffer--submit ((this slack-dialog-buffer))
+  (with-slots (dialog dialog-id team) this
+    (with-slots (elements) dialog
+      (dolist (element elements)
+        (let ((value (slack-dialog-element-value element)))
+          (slack-dialog-element-validate element value)))
+      (let ((params (mapcar #'(lambda (element)
+                                (cons (oref element name)
+                                      (slack-dialog-element-value element)))
+                            elements)))
+        (cl-labels
+            ((create-dialog-element-error
+              (payload)
+              (make-instance #'slack-dialog-element-error
+                             :name (plist-get payload :name)
+                             :error-message (plist-get payload :error)))
+             (set-dialog-element-error
+              (dialog-error elements)
+              (slack-if-let*
+                  ((element (cl-find-if #'(lambda (el)
+                                            (string= (oref el name)
+                                                     (oref dialog-error name)))
+                                        elements))
+                   (new-errors (cons dialog-error
+                                     (cl-remove-if #'(lambda (e)
+                                                       (string= (oref e name)
+                                                                (oref dialog-error
+                                                                      name)))
+                                                   (oref element errors)))))
+                  (oset element errors new-errors)))
+             (after-success
+              (data)
+              (slack-if-let* ((err (plist-get data :error)))
+                  (progn
+                    (oset dialog error-message err)
+                    (dolist (dialog-error (mapcar #'create-dialog-element-error
+                                                  (plist-get data :dialog_errors)))
+                      (set-dialog-element-error dialog-error elements))
+
+                    (slack-dialog-buffer-redisplay this))
+                (slack-dialog-buffer-kill-buffer this))))
+          (slack-dialog-clear-errors dialog)
+          (slack-dialog--submit dialog dialog-id team params #'after-success))))))
+
+(defun slack-dialog-buffer-cancel ()
+  (interactive)
+  (slack-if-let* ((buffer slack-current-buffer))
+      (with-slots (dialog dialog-id team) buffer
+        (slack-dialog-notify-cancel dialog dialog-id team)
+        (slack-dialog-buffer-kill-buffer buffer))))
+
+(defmethod slack-dialog-buffer-kill-buffer ((this slack-dialog-buffer))
+  (slack-if-let* ((buffer-name (slack-buffer-name this))
+                  (buf (get-buffer buffer-name))
+                  (win (get-buffer-window buf)))
+      (progn
+        (kill-buffer buf)
+        (when (< 1 (count-windows))
+          (delete-window win)))))
+
+(defmethod slack-buffer-insert ((this slack-dialog-buffer))
+  (with-slots (dialog) this
+    (with-slots (error-message title elements submit-label) dialog
+      (let ((inhibit-read-only t))
+        (insert (propertize title
+                            'face 'slack-dialog-title-face))
+        (when error-message
+          (insert "\n")
+          (insert (propertize error-message
+                              'face 'slack-dialog-element-error-face)))
+        (insert "\n\n")
+        (mapc #'(lambda (el)
+                  (slack-buffer-insert el)
+                  (insert "\n"))
+              elements)
+        (insert "\n")
+        (insert (propertize " Cancel "
+                            'face 'slack-dialog-cancel-button-face
+                            'keymap slack-dialog-cancel-button-map))
+        (insert "\t")
+        (insert (propertize (format " %s " submit-label)
+                            'face 'slack-dialog-submit-button-face
+                            'keymap slack-dialog-submit-button-map))
+        (goto-char (point-min))))))
+
+(defmethod slack-buffer-init-buffer ((this slack-dialog-buffer))
+  (let* ((buf (generate-new-buffer (slack-buffer-name this)))
+         (dialog (oref this dialog))
+         (dialog-id (oref this dialog-id))
+         (team (oref this team)))
+    (with-current-buffer buf
+      (slack-dialog-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (slack-buffer-insert this))
+    (slack-buffer-push-new-4 'slack-dialog-buffer
+                             dialog-id dialog team)))
+
+(defun slack-create-dialog-buffer (dialog-id dialog team)
+  (slack-if-let*
+      ((buf (slack-buffer-find 'slack-dialog-buffer
+                               dialog-id
+                               dialog
+                               team)))
+      buf
+    (make-instance 'slack-dialog-buffer
+                   :dialog-id dialog-id
+                   :dialog dialog
+                   :team team)))
+
+(defmethod slack-dialog-buffer-save-element-value ((this slack-dialog-buffer)
+                                                   name
+                                                   value)
+  (with-slots (dialog) this
+    (with-slots (elements) dialog
+      (let ((element (cl-find-if #'(lambda (el)
+                                     (string= name
+                                              (oref el name)))
+                                 elements)))
+        (oset element value value)
+        (slack-dialog-buffer-redisplay this)))))
+
+(defmethod slack-dialog-buffer-redisplay ((this slack-dialog-buffer))
+  (slack-if-let* ((bufname (slack-buffer-name this))
+                  (buf (get-buffer bufname)))
+      (with-current-buffer buf
+        (let ((inhibit-read-only t)
+              (cur-point (point)))
+          (delete-region (point-min) (point-max))
+          (slack-buffer-insert this)
+          (when (and (< (point-min) cur-point)
+                     (< cur-point (point-max)))
+            (goto-char cur-point))))))
+
+(provide 'slack-dialog-buffer)
+;;; slack-dialog-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-buffer.elc
new file mode 100644
index 000000000000..2b254a6ad435
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-edit-element-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-edit-element-buffer.el
new file mode 100644
index 000000000000..53b23c388678
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-edit-element-buffer.el
@@ -0,0 +1,111 @@
+;;; slack-dialog-edit-element-buffer.el ---          -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-dialog-buffer)
+
+(defclass slack-dialog-edit-element-buffer (slack-buffer)
+  ((dialog-buffer :initarg :dialog-buffer :type slack-dialog-buffer)
+   (element :initarg :element :type slack-dialog-element)))
+
+(define-derived-mode slack-dialog-edit-element-buffer-mode fundamental-mode "Slack Dialog Edit Element Buffer"
+  (setq-local default-directory slack-default-directory))
+
+(setq slack-dialog-edit-element-buffer-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-c")
+      #'slack-dialog-edit-buffer-save-content)
+    (define-key map (kbd "C-c C-k")
+      #'slack-dialog-edit-buffer-abort)
+    map))
+
+(defun slack-dialog-edit-buffer-save-content ()
+  (interactive)
+  (let ((content (buffer-substring-no-properties (point-min)
+                                                 (point-max)))
+        (buffer slack-current-buffer))
+    (with-slots (element dialog-buffer) buffer
+      (slack-dialog-edit-buffer-abort)
+      (slack-dialog-buffer-save-element-value dialog-buffer
+                                              (oref element name)
+                                              content))))
+
+(defun slack-dialog-edit-buffer-abort ()
+  (interactive)
+  (let* ((buffer-name (slack-buffer-name slack-current-buffer))
+         (buf (get-buffer buffer-name))
+         (win (get-buffer-window buf)))
+    (kill-buffer buf)
+    (when (< 1 (count-windows))
+      (delete-window win))))
+
+(defmethod slack-buffer-name :static ((_class slack-dialog-edit-element-buffer)
+                                      dialog-buffer element team)
+  (with-slots (dialog dialog-id) dialog-buffer
+    (with-slots (name) element
+      (with-slots (title) dialog
+        (format "* Slack Dialog Edit Element - %s [%s] edit %s : %s"
+                title dialog-id name (slack-team-name team))))))
+
+(defmethod slack-buffer-find :static ((class slack-dialog-edit-element-buffer)
+                                      dialog-buffer element team)
+  (slack-buffer-find-4 class dialog-buffer element team))
+
+(defmethod slack-buffer-name ((this slack-dialog-edit-element-buffer))
+  (with-slots (dialog-buffer element team) this
+    (slack-buffer-name 'slack-dialog-edit-element-buffer
+                       dialog-buffer element team)))
+
+(defun slack-create-dialog-element-edit-buffer (dialog-buffer element team)
+  (slack-if-let*
+      ((buf (slack-buffer-find 'slack-dialog-edit-element-buffer
+                               dialog-buffer
+                               element
+                               team)))
+      buf
+    (make-instance 'slack-dialog-edit-element-buffer
+                   :dialog-buffer dialog-buffer
+                   :element element
+                   :team team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-dialog-edit-element-buffer))
+  (let* ((buf (generate-new-buffer (slack-buffer-name this)))
+         (element (oref this element)))
+    (with-current-buffer buf
+      (slack-dialog-edit-element-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (goto-char (point-min))
+      (with-slots (value label) element
+        (setq-local header-line-format
+                    (format "%s: C-c to save content" label))
+        (insert (or value ""))))
+    (slack-buffer-push-new-4 'slack-dialog-edit-element-buffer
+                             (oref this dialog-buffer)
+                             element
+                             (oref this team))))
+
+
+(provide 'slack-dialog-edit-element-buffer)
+;;; slack-dialog-edit-element-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-edit-element-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-edit-element-buffer.elc
new file mode 100644
index 000000000000..dd06a1723d0a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog-edit-element-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.el
new file mode 100644
index 000000000000..e62f2a46ec13
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.el
@@ -0,0 +1,343 @@
+;;; slack-dialog.el ---                              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-selectable)
+
+(defclass slack-dialog ()
+  ((title :initarg :title :type string)
+   (callback-id :initarg :callback_id :type string)
+   (elements :initarg :elements :type list)
+   (state :initarg :state :type (or null string) :initform nil)
+   (submit-label :initarg :submit_label :type string :initform "Submit")
+   (notify-on-cancel :initarg :notify_on_cancel :type boolean :initform nil)
+   (error-message :initarg :error-message :type (or null string) :initform nil)
+   ))
+
+(defclass slack-dialog-element ()
+  ((name :initarg :name :type string)
+   (label :initarg :label :type string)
+   (type :initarg :type :type string)
+   (optional :initarg :optional :type boolean :initform nil)
+   (placeholder :initarg :placeholder :type (or null string) :initform nil)
+   (value :initarg :value :type (or null string) :initform nil)
+   (errors :initarg :errors :type list :initform '())))
+
+(defclass slack-dialog-element-error ()
+  ((name :initarg :name :type string)
+   (error-message :initarg :error-message :type string)))
+
+(defclass slack-dialog-text-element (slack-dialog-element)
+  ((max-length :initarg :max_length :type number :initform 150)
+   (min-length :initarg :min_length :type number :initform 0)
+   (hint :initarg :hint :type (or null string) :initform nil)
+   ;; one of email, number, tel or url
+   (subtype :initarg :subtype :type (or null string) :initform nil)))
+
+(defclass slack-dialog-textarea-element (slack-dialog-text-element)
+  ((max-length :initarg :max_length :type number :initform 3000)))
+
+(defclass slack-dialog-select-element (slack-dialog-element slack-selectable)
+  ((min-query-length :initarg :min_query_length :type (or null number) :initform nil)))
+
+(defclass slack-dialog-select-option (slack-selectable-option)
+  ((label :initarg :label :type string)))
+
+(defclass slack-dialog-select-option-group (slack-selectable-option-group)
+  ((label :initarg :label :type string)))
+
+(defmethod slack-dialog-element-value ((this slack-dialog-element))
+  (or (oref this value) ""))
+
+(defmethod slack-dialog-element-value ((this slack-dialog-select-element))
+  (with-slots (data-source selected-options) this
+    (or (cond
+         ((string= data-source "external")
+          (and selected-options
+               (car selected-options)
+               (oref (car selected-options) value)))
+         (t (oref this value)))
+        "")))
+
+(defmethod slack-equalp ((this slack-dialog-element) other)
+  (string= (oref this name)
+           (oref other name)))
+
+(defmethod slack-dialog-selected-option ((this slack-dialog-select-element))
+  (with-slots (data-source value options selected-options) this
+    (if (string= data-source "static")
+        (cl-find-if #'(lambda (op) (string= (oref op value)
+                                            value))
+                    options)
+      (and selected-options (car selected-options)))))
+
+(defmethod slack-selectable-text ((this slack-dialog-select-option))
+  (oref this label))
+
+(defmethod slack-selectable-text ((this slack-dialog-select-option-group))
+  (oref this label))
+
+(defmethod slack-selectable-prompt ((this slack-dialog-select-element))
+  (format "%s :"
+          (oref this label)))
+
+(defun slack-dialog-text-element-create (payload)
+  (apply #'make-instance 'slack-dialog-text-element
+         (slack-collect-slots 'slack-dialog-text-element payload)))
+
+(defun slack-dialog-textarea-element-create (payload)
+  (apply #'make-instance 'slack-dialog-textarea-element
+         (slack-collect-slots 'slack-dialog-textarea-element payload)))
+
+(defun slack-dialog-select-element-create (payload)
+  (let ((options
+         (mapcar #'(lambda (e)
+                     (apply #'make-instance 'slack-dialog-select-option
+                            (slack-collect-slots 'slack-dialog-select-option
+                                                 e)))
+                 (plist-get payload :options)))
+        (option-groups
+         (mapcar #'(lambda (e)
+                     (apply #'make-instance
+                            'slack-dialog-select-option-group
+                            (slack-collect-slots 'slack-dialog-select-option-group
+                                                 e)))
+                 (plist-get payload :option_groups))))
+    (setq payload (plist-put payload :options options))
+    (setq payload (plist-put payload :option_groups option-groups))
+    (apply #'make-instance 'slack-dialog-select-element
+           (slack-collect-slots 'slack-dialog-select-element
+                                payload))))
+
+(defun slack-dialog-element-create (payload)
+  (let ((type (plist-get payload :type)))
+    (cond
+     ((string= type "select")
+      (slack-dialog-select-element-create payload))
+     ((string= type "text")
+      (slack-dialog-text-element-create payload))
+     ((string= type "textarea")
+      (slack-dialog-textarea-element-create payload))
+     (t (error "Unknown dialog element type: %s" type)))))
+
+(defun slack-dialog-create (payload)
+  (let ((elements (mapcar #'slack-dialog-element-create
+                          (plist-get payload :elements))))
+    (setq payload (plist-put payload :elements elements))
+    (apply #'make-instance 'slack-dialog
+           (slack-collect-slots 'slack-dialog payload))))
+
+(defmethod slack-dialog-element-validate ((this slack-dialog-element) value)
+  (with-slots (optional label) this
+    (when (and (not optional)
+               (or (null value)
+                   (< (length value) 1)))
+      (error "%s must not be empty" label))))
+
+(defmethod slack-dialog-element-validate ((_this slack-dialog-select-element) _value)
+  (call-next-method))
+
+(defmethod slack-dialog-element-validate ((this slack-dialog-text-element) value)
+  (call-next-method)
+  (with-slots (min-length max-length label) this
+    (when (< max-length (length value))
+      (error "%s must be less than %s" label max-length))
+    (when (< (length value) min-length)
+      (error "%s must be greater than %s" label min-length))))
+
+(defmethod slack-dialog-execute ((this slack-dialog-text-element) _dialog-id team)
+  (with-slots (hint value placeholder label optional) this
+    (let* ((prompt (format "%s%s%s : "
+                           label
+                           (if hint (format " (%s)" hint) "")
+                           (if optional " (optional)" "")))
+           (value (read-from-minibuffer prompt value)))
+      (slack-dialog-element-validate this value)
+      value)))
+
+(defmethod slack-dialog-execute ((this slack-dialog-textarea-element) _dialog-id team)
+  (call-next-method))
+
+(defmethod slack-dialog-select-element-get-suggestions ((this slack-dialog-select-element)
+                                                        dialog-id team after-success)
+  (let* ((url "https://slack.com/api/dialog.selectSuggestion")
+         (min-query-length (oref this min-query-length))
+         (prompt (format "Type hints to see options (minimum: %s) : " min-query-length))
+         (params (list (cons "dialog_id" dialog-id)
+                       (cons "name" (oref this name))
+                       (cons "value" (read-from-minibuffer prompt)))))
+    (cl-labels
+        ((on-success (&key data &allow-other-keys)
+                     (slack-request-handle-error
+                      (data "slack-dialog-select-fetch-suggestion")
+                      (funcall after-success data))))
+      (slack-request
+       (slack-request-create
+        url
+        team
+        :type "POST"
+        :params params
+        :sync t
+        :success #'on-success)))))
+
+(defmethod slack-dialog-execute ((this slack-dialog-select-element) dialog-id team)
+  (slack-if-let* ((selected (slack-dialog--execute this dialog-id team)))
+      (cdr selected)))
+
+(defmethod slack-dialog--execute ((this slack-dialog-select-element) dialog-id team)
+  (with-slots (data-source) this
+    (cond
+     ((string= data-source "external")
+      (let ((result-option nil))
+        (cl-labels
+            ((log-error (err)
+                        (slack-log (format "Error: %s" err) team :level 'error))
+             (select (options)
+                     (slack-if-let*
+                         ((selected (completing-read "Choose an Option..."
+                                                     (mapcar #'(lambda (option)
+                                                                 (plist-get option :label))
+                                                             options)
+                                                     nil t)))
+                         (cl-find-if #'(lambda (option) (string= selected
+                                                                 (plist-get option :label)))
+                                     options)))
+             (after-success (data)
+                            (slack-request-handle-error
+                             (data "slack-dialog-execute"
+                                   #'log-error)
+                             (let ((option-groups (plist-get data :option_groups))
+                                   (options (plist-get data :options)))
+                               (when option-groups
+                                 (slack-if-let* ((selected-option-group (select option-groups)))
+                                     (setq options (plist-get selected-option-group :options))))
+                               (when options
+                                 (slack-if-let* ((selected (select options)))
+                                     (setq result-option selected)))))))
+          (slack-dialog-select-element-get-suggestions this
+                                                       dialog-id
+                                                       team
+                                                       #'after-success)
+          (if result-option
+              (cons (plist-get result-option :label)
+                    (plist-get result-option :value))))))
+     ((string= data-source "conversations")
+      (slack-if-let* ((rooms (append (oref team channels)
+                                     (oref team groups)
+                                     (oref team ims)))
+                      (room (slack-room-select rooms team)))
+          (cons (slack-room-name room team)
+                (oref room id))))
+     ((string= data-source "channels")
+      (slack-if-let* ((channels (oref team channels))
+                      (channel (slack-room-select channels team)))
+          (cons (slack-room-name channel team)
+                (oref channel id))))
+     ((string= data-source "users")
+      (slack-if-let* ((id (plist-get (slack--user-select team) :id)))
+          (cons (slack-user-name id team)
+                id)))
+     ((string= "static" data-source)
+      (slack-if-let* ((selected (slack-selectable-select-from-static-data-source this)))
+          (cons (oref selected label)
+                (oref selected value))))
+     (t (error "Unknown element's data-source: %s" data-source))
+     )))
+
+(defmethod slack-dialog--submit ((_this slack-dialog)
+                                 dialog-id team submission
+                                 &optional after-success)
+  (let ((url "https://slack.com/api/dialog.submit")
+        (params (list (cons "submission" (json-encode-alist submission))
+                      (cons "dialog_id" dialog-id))))
+    (cl-labels
+        ((on-success (&key data &allow-other-keys)
+                     (when (functionp after-success)
+                       (funcall after-success data))))
+      (slack-request
+       (slack-request-create
+        url
+        team
+        :type "POST"
+        :params params
+        :success #'on-success)))))
+
+(defmethod slack-dialog-submit ((this slack-dialog) dialog-id team)
+  (with-slots (elements) this
+    (let ((submission (mapcar #'(lambda (element)
+                                  (let ((value (slack-dialog-execute element dialog-id team)))
+                                    (cons (oref element name) value)))
+                              elements)))
+      (slack-dialog--submit this dialog-id team submission))))
+
+(defun slack-dialog-get (id team)
+  (let ((url "https://slack.com/api/dialog.get")
+        (params (list (cons "dialog_id" id))))
+    (cl-labels
+        ((on-success (&key data &allow-other-keys)
+                     (slack-request-handle-error
+                      (data "slack-dialog-get")
+                      (slack-if-let*
+                          ((payload (plist-get data :dialog))
+                           (dialog (slack-dialog-create payload)))
+                          ;; (slack-dialog-submit dialog id team)
+                          (slack-buffer-display
+                           (slack-create-dialog-buffer id
+                                                       dialog
+                                                       team))
+                        ))))
+      (slack-request
+       (slack-request-create
+        url
+        team
+        :type "POST"
+        :params params
+        :success #'on-success)))))
+
+(defmethod slack-dialog-notify-cancel ((this slack-dialog) dialog-id team)
+  (slack-if-let* ((url "https://slack.com/api/dialog.notifyCancel")
+                  (params (list (cons "dialog_id" dialog-id)))
+                  (notify-cancelp (oref this notify-on-cancel)))
+      (cl-labels
+          ((on-success (&key data &allow-other-keys)
+                       (slack-request-handle-error
+                        (data "slack-dialog-notify-cancel"))))
+        (slack-request
+         (slack-request-create
+          url
+          team
+          :type "POST"
+          :params params
+          :success #'on-success)))))
+
+(defmethod slack-dialog-clear-errors ((this slack-dialog))
+  (oset this error-message nil)
+  (dolist (element (oref this elements))
+    (oset element errors nil)))
+
+(provide 'slack-dialog)
+;;; slack-dialog.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.elc
new file mode 100644
index 000000000000..25bf207a1af9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-dialog.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-emoji.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-emoji.el
new file mode 100644
index 000000000000..baec1b03b86f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-emoji.el
@@ -0,0 +1,93 @@
+;;; slack-emoji.el ---                               -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'slack-request)
+
+(defconst slack-emoji-list "https://slack.com/api/emoji.list")
+
+(defun slack-emoji-watch-download-complete (team paths)
+  (if (eq (length (cl-remove-if #'identity (mapcar #'file-exists-p paths)))
+          0)
+      (when (timerp (oref team emoji-download-watch-timer))
+        (cancel-timer (oref team emoji-download-watch-timer))
+        (oset team emoji-download-watch-timer nil)
+        (emojify-create-emojify-emojis t))))
+
+(defun slack-request-emoji (team)
+  (if (require 'emojify nil t)
+      (cl-labels
+          ((handle-alias (name emojis)
+                         (let* ((raw-url (plist-get emojis name))
+                                (alias (if (string-prefix-p "alias:" raw-url)
+                                           (intern (format ":%s" (cadr (split-string raw-url ":")))))))
+                           (or (and alias (or (plist-get emojis alias)
+                                              (let ((emoji (emojify-get-emoji (format "%s:" alias))))
+                                                (if emoji
+                                                    (concat (emojify-image-dir) "/" (gethash "image" emoji))))))
+                               raw-url)))
+           (push-new-emoji (emoji)
+                           (cl-pushnew emoji emojify-user-emojis
+                                       :test #'string=
+                                       :key #'car))
+           (on-success
+            (&key data &allow-other-keys)
+            (slack-request-handle-error
+             (data "slack-request-emoji")
+             (emojify-create-emojify-emojis)
+             (let* ((emojis (plist-get data :emoji))
+                    (names (cl-remove-if
+                            #'(lambda (key) (not (plist-member emojis key)))
+                            emojis))
+                    (paths
+                     (mapcar
+                      #'(lambda (name)
+                          (let* ((url (handle-alias name emojis))
+                                 (path (if (file-exists-p url) url
+                                         (slack-image-path url)))
+                                 (emoji (cons (format "%s:" name)
+                                              (list (cons "name" (substring (symbol-name name) 1))
+                                                    (cons "image" path)
+                                                    (cons "style" "github")))))
+                            (if (file-exists-p path)
+                                (push-new-emoji emoji)
+                              (slack-url-copy-file
+                               url
+                               path
+                               :success #'(lambda () (push-new-emoji emoji))))
+
+                            path))
+                      names)))
+
+               (oset team
+                     emoji-download-watch-timer
+                     (run-with-idle-timer 5 t #'slack-emoji-watch-download-complete team paths))))))
+        (slack-request
+         (slack-request-create
+          slack-emoji-list
+          team
+          :success #'on-success)))))
+
+(provide 'slack-emoji)
+;;; slack-emoji.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-emoji.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-emoji.elc
new file mode 100644
index 000000000000..1330302ab41c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-emoji.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-info-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-info-buffer.el
new file mode 100644
index 000000000000..da0f62ec6eba
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-info-buffer.el
@@ -0,0 +1,146 @@
+;;; slack-file-info-buffer.el ---                    -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-buffer)
+(require 'slack-message)
+
+(define-derived-mode slack-file-info-buffer-mode slack-buffer-mode  "Slack File Info"
+  (add-hook 'lui-post-output-hook 'slack-display-image t t))
+
+(defclass slack-file-info-buffer (slack-buffer)
+  ((file :initarg :file :type slack-file)))
+
+(defmethod slack-buffer-name :static ((class slack-file-info-buffer) file team)
+  (format "*Slack - %s File: %s"
+          (oref team name)
+          (or (oref file title)
+              (oref file name)
+              (oref file id))))
+
+(defun slack-create-file-info-buffer (team file)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-file-info-buffer
+                                             file
+                                             team)))
+      (progn
+        (oset buffer file file)
+        buffer)
+    (slack-file-info-buffer :team team :file file)))
+
+(defmethod slack-buffer-init-buffer :after ((this slack-file-info-buffer))
+  (with-slots (file team) this
+    (let ((class (eieio-object-class-name this)))
+      (slack-buffer-push-new-3 class file team))))
+
+(defmethod slack-buffer-name ((this slack-file-info-buffer))
+  (with-slots (file team) this
+    (slack-buffer-name (eieio-object-class-name this)
+                       file
+                       team)))
+
+(defmethod slack-buffer-buffer ((this slack-file-info-buffer))
+  (slack-if-let* ((buf (get-buffer (slack-buffer-name this))))
+      (progn
+        (with-current-buffer buf
+          (let ((inhibit-read-only t))
+            (slack-buffer-insert this)))
+        buf)
+    (slack-buffer-init-buffer this)))
+
+(defmethod slack-buffer-init-buffer ((this slack-file-info-buffer))
+  (let ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-file-info-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (slack-buffer-insert this))
+    buf))
+
+(defmethod slack-buffer-file-to-string ((this slack-file-info-buffer))
+  (with-slots (file team) this
+    (let* ((header (format "%s %s\n"
+                           (slack-message-put-header-property (oref file title))
+                           (if (oref file is-starred) ":star:" "")))
+           (body (slack-message-body-to-string file team))
+           (thumb (or (and (slack-file-image-p file)
+                           (slack-message-large-image-to-string file))
+                      (slack-message-image-to-string file)))
+           (comments (mapconcat #'(lambda (comment)
+                                    (slack-message-to-string comment team))
+                                (oref file comments)
+                                "\n")))
+      (propertize (slack-format-message header
+                                        body
+                                        thumb
+                                        "\n"
+                                        comments)
+                  'file-id (oref file id)))))
+
+(defmethod slack-buffer-insert ((this slack-file-info-buffer))
+  (delete-region (point-min) lui-output-marker)
+  (with-slots (file team) this
+    (let ((lui-time-stamp-position nil))
+      (lui-insert-with-text-properties
+       (slack-buffer-file-to-string this)
+       ;; saved-text-properties not working??
+       'file-id (oref file id)
+       'ts (slack-ts file)))))
+
+(defmethod slack-buffer-add-reaction-to-message
+  ((this slack-file-info-buffer) reaction _ts)
+  (with-slots (file team) this
+    (slack-file-add-reaction (oref file id) reaction team)))
+
+(defmethod slack-buffer-add-star ((this slack-file-info-buffer) _ts)
+  (let ((url slack-message-stars-add-url))
+    (with-slots (file team) this
+      (slack-message-star-api-request url
+                                      (list (slack-message-star-api-params file))
+                                      team))))
+
+(defmethod slack-buffer-remove-star ((this slack-file-info-buffer) _ts)
+  (let ((url slack-message-stars-remove-url))
+    (with-slots (file team) this
+      (slack-message-star-api-request url
+                                      (list (slack-message-star-api-params
+                                             file))
+                                      team))))
+
+(defmethod slack-buffer--replace ((this slack-file-info-buffer) _ts)
+  (slack-if-let* ((buffer (get-buffer (slack-buffer-name this))))
+      (with-current-buffer buffer
+        (let ((inhibit-read-only t))
+          (slack-buffer-insert this)))))
+
+(defmethod slack-buffer-update ((this slack-file-info-buffer))
+  (with-slots (file team) this
+    (let ((buffer (get-buffer (slack-buffer-name this))))
+      (with-current-buffer buffer
+        (let ((inhibit-read-only t))
+          (slack-buffer-insert this))))))
+
+(provide 'slack-file-info-buffer)
+;;; slack-file-info-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-info-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-info-buffer.elc
new file mode 100644
index 000000000000..5344c55cc2d1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-info-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-list-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-list-buffer.el
new file mode 100644
index 000000000000..527cdc919917
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-list-buffer.el
@@ -0,0 +1,79 @@
+;;; slack-file-list-buffer.el ---                    -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-room-buffer)
+
+(define-derived-mode slack-file-list-buffer-mode slack-buffer-mode "Slack File List Buffer")
+
+(defclass slack-file-list-buffer (slack-message-buffer) ())
+
+(defmethod slack-buffer-name ((_this slack-file-list-buffer))
+  (format "%s" (call-next-method)))
+
+(defmethod slack-buffer-major-mode ((this slack-file-list-buffer))
+  'slack-file-list-buffer-mode)
+
+(defmethod slack-create-message-buffer ((room slack-file-room) team)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-file-list-buffer
+                                             room
+                                             team)))
+      buffer
+    (slack-file-list-buffer :room room :team team)))
+
+(cl-defmethod slack-buffer-update ((this slack-file-list-buffer) message &key replace)
+  (with-slots (room team) this
+    (let ((buffer (get-buffer (slack-buffer-name this))))
+      (if replace (slack-buffer-replace this message)
+        (with-current-buffer buffer
+          (slack-buffer-insert this message))))))
+
+(defmethod slack-buffer-insert ((this slack-file-list-buffer) message &optional not-tracked-p)
+  (let ((lui-time-stamp-time (slack-message-time-stamp message))
+        (ts (slack-ts message))
+        (team (oref this team)))
+    (lui-insert-with-text-properties
+     (slack-message-to-string message ts team)
+     'not-tracked-p not-tracked-p
+     'ts ts
+     'slack-last-ts lui-time-stamp-last)
+    (lui-insert "" t)
+    ))
+
+(defmethod slack-buffer-replace ((this slack-file-list-buffer)
+                                 message)
+  (with-slots (team) this
+    (with-current-buffer (slack-buffer-buffer this)
+      (lui-replace (slack-message-to-string message
+                                            (slack-ts message)
+                                            team)
+                   (lambda ()
+                     (equal (get-text-property (point) 'ts)
+                            (slack-ts message)))))))
+
+(provide 'slack-file-list-buffer)
+;;; slack-file-list-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-list-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-list-buffer.elc
new file mode 100644
index 000000000000..ecc2ec89d475
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file-list-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file.el
new file mode 100644
index 000000000000..f6ac4242e87b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file.el
@@ -0,0 +1,550 @@
+;;; slack-file.el ---  handle files                  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2016  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-room)
+(require 'slack-request)
+
+(defconst slack-file-history-url "https://slack.com/api/files.list")
+(defconst slack-file-list-url "https://slack.com/api/files.list")
+(defconst slack-file-upload-url "https://slack.com/api/files.upload")
+(defconst slack-file-delete-url "https://slack.com/api/files.delete")
+
+(defclass slack-file ()
+  ((id :initarg :id)
+   (created :initarg :created)
+   (name :initarg :name)
+   (size :initarg :size)
+   (public :initarg :public)
+   (filetype :initarg :filetype)
+   (user :initarg :user)
+   (preview :initarg :preview)
+   (permalink :initarg :permalink)
+   (channels :initarg :channels :type list)
+   (groups :initarg :groups :type list)
+   (ims :initarg :ims :type list)
+   (username :initarg :username)
+   (page :initarg :page :initform 1)
+   (pages :initarg :pages :initform nil)
+   (thumb-64 :initarg :thumb_64 :initform nil)
+   (thumb-80 :initarg :thumb_80 :initform nil)
+   (thumb-360 :initarg :thumb_360 :initform nil)
+   (thumb-360-w :initarg :thumb_360_w :initform nil)
+   (thumb-360-h :initarg :thumb_360_h :initform nil)
+   (thumb-160 :initarg :thumb_160 :initform nil)
+   (thumb-pdf :initarg :thumb_pdf :initform nil)
+   (thumb-pdf-w :initarg :thumb_pdf_w :initform nil)
+   (thumb-pdf-h :initarg :thumb_pdf_h :initform nil)
+   (original-w :initarg :original_w :initform nil)
+   (original-h :initarg :original_h :initform nil)
+   (is-starred :initarg :is_starred :initform nil)
+   (mimetype :initarg :mimetype :type string :initform "")
+   (title :initarg :title :type (or null string) :initform nil)
+   (pretty-type :initarg :pretty_type :type (or null string) :initform nil)
+   (is-public :initarg :is_public :initform nil)
+   (url :initarg :url :initform "" :type string)
+   (url-download :initarg :url_download :initform "" :type string)
+   (url-private :initarg :url_private :initform "" :type string)
+   (url-private-download :initarg :url_private_download :initform "" :type string)
+   (timestamp :initarg :timestamp :type number)
+   (comments :initarg :comments :type list :initform '())
+   ))
+
+(defclass slack-file-email (slack-file)
+  ((from :initarg :from :type (or null list) :initform nil)
+   (to :initarg :to :type (or null list) :initform nil)
+   ;; TODO verify type
+   (cc :initarg :cc :type (or null list) :initform nil)
+   (subject :initarg :subject :type (or null string))
+   (plain-text :initarg :plain_text :type string)
+   (preview-plain-text :initarg :preview_plain_text :type string)
+   (is-expanded :initform nil :type boolean)))
+
+(defclass slack-file-email-from ()
+  ((address :initarg :address :type string)
+   (name :initarg :name :type string)
+   (original :initarg :original :type string)))
+
+(defclass slack-file-email-to (slack-file-email-from) ())
+(defclass slack-file-email-cc (slack-file-email-from) ())
+
+(defclass slack-file-comment ()
+  ((id :initarg :id :type string)
+   (created :initarg :created :type number)
+   (timestamp :initarg :timestamp :type number)
+   (user :initarg :user :type string)
+   (is-intro :initarg :is_intro)
+   (comment :initarg :comment :type string)))
+
+(defmethod slack-merge ((old slack-reaction) new)
+  (with-slots (count users) old
+    (setq count (oref new count))
+    (setq users (cl-remove-duplicates (append users (oref new users))
+                                      :test #'string=))))
+
+(defmethod slack-merge ((old string) _new) old)
+(defmethod slack-equalp ((old string) new) (string= old new))
+
+(defmethod slack-merge ((old slack-file) new)
+  (cl-labels
+      ((slack-merge-string-list
+        (new old)
+        (cl-remove-duplicates (append new old) :test #'string=)))
+
+    (slack-merge-list (oref old channels) (oref new channels))
+    (slack-merge-list (oref old groups) (oref new groups))
+    (slack-merge-list (oref old ims) (oref new ims))
+    ))
+
+(defclass slack-file-room (slack-room) ())
+
+(defun slack-file-find (id team)
+  (let ((files (oref (slack-file-room-obj team) messages)))
+    (cl-find-if #'(lambda (file) (string= (oref file id) id))
+                files)))
+
+(defun slack-file-room-obj (team)
+  (with-slots (file-room) team
+    (if file-room
+        file-room
+      (setq file-room (slack-file-room "file-room"
+                                       :name "Files"
+                                       :id "F"
+                                       :created (format-time-string "%s")
+                                       :latest nil
+                                       :unread_count 0
+                                       :unread_count_display 0
+                                       :messages '())))))
+
+(defun slack-file-create-email-from (payload &optional type)
+  (and payload
+       (make-instance (or (and (eq type 'to) 'slack-file-email-to)
+                          (and (eq type 'cc) 'slack-file-email-cc)
+                          'slack-file-email-from)
+                      :original (plist-get payload :original)
+                      :name (plist-get payload :name)
+                      :address (plist-get payload :address))))
+
+(defun slack-file-create (payload)
+  (setq payload (append payload nil))
+  (plist-put payload :channels (append (plist-get payload :channels) nil))
+  (plist-put payload :groups (append (plist-get payload :groups) nil))
+  (plist-put payload :ims (append (plist-get payload :ims) nil))
+  (plist-put payload :pinned_to (append (plist-get payload :pinned_to) nil))
+  (plist-put payload :channel "F")
+  (let* ((file (if (string= "email" (plist-get payload :filetype))
+                   (progn
+                     (plist-put payload :from
+                                (mapcar #'slack-file-create-email-from
+                                        (plist-get payload :from)))
+                     (plist-put payload :to
+                                (mapcar #'(lambda (e)
+                                            (slack-file-create-email-from e 'to))
+                                        (plist-get payload :to)))
+                     (plist-put payload :cc
+                                (mapcar #'(lambda (e)
+                                            (slack-file-create-email-from e 'cc))
+                                        (plist-get payload :cc)))
+                     (apply #'slack-file-email "file-email"
+                            (slack-collect-slots 'slack-file-email
+                                                 payload)))
+
+                 (apply #'slack-file "file"
+                        (slack-collect-slots 'slack-file payload))))
+         )
+    file))
+
+(defmethod slack-message-equal ((f slack-file) other)
+  (string= (oref f id) (oref other id)))
+
+(defmethod slack-equalp ((old slack-file) new)
+  (string= (oref old id) (oref new id)))
+
+(defmethod slack-file-pushnew ((f slack-file) team)
+  (let ((room (slack-file-room-obj team)))
+    (slack-merge-list (oref room messages) (list f))
+    ;; (oset room messages (slack-room-sort-messages (oref room messages)))
+    ;; (slack-room-update-latest room (car (last (oref room messages))))
+    ))
+
+(defconst slack-file-info-url "https://slack.com/api/files.info")
+
+(defun slack-file-update ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (with-slots (file team) buf
+        (slack-if-let* ((page (oref file page)))
+            (slack-file-request-info
+             file page team
+             #'(lambda (file team)
+                 (slack-redisplay file team)))))))
+
+(defun slack-file-comment-create (payload)
+  (apply 'make-instance 'slack-file-comment
+         (slack-collect-slots 'slack-file-comment payload)))
+
+(defun slack-file-request-info (file-id page team &optional after-success)
+  (cl-labels
+      ((on-file-info (&key data &allow-other-keys)
+                     (slack-request-handle-error
+                      (data "slack-file-info")
+                      (let* ((paging (plist-get data :paging))
+                             (file (slack-file-create (plist-get data :file)))
+                             (comments (mapcar #'slack-file-comment-create
+                                               (plist-get data :comments))))
+                        (oset file comments comments)
+                        (slack-file-pushnew file team)
+                        (if after-success
+                            (funcall after-success file team))))))
+    (slack-request
+     (slack-request-create
+      slack-file-info-url
+      team
+      :params (list (cons "file" file-id)
+                    (cons "page" (number-to-string page)))
+      :success #'on-file-info))))
+
+(defmethod slack-file-gdoc-p ((this slack-file))
+  (string= (oref this filetype) "gdoc"))
+
+(defmethod slack-file-gdoc-to-string ((this slack-file))
+  (with-slots (pretty-type name title url-private permalink) this
+    (let ((title (propertize (format "<%s|%s>" permalink (or title name))
+                             'face '(:weight bold)))
+          (description (format "<%s|%s>" url-private pretty-type)))
+      (slack-format-message title description))))
+
+(defmethod slack-message-body-to-string ((file slack-file) team)
+  (cond
+   ((slack-file-gdoc-p file) (slack-file-gdoc-to-string file))
+   (t (with-slots (name title size filetype permalink) file
+        (slack-message-put-text-property
+         (format "name: %s\nsize: %s\ntype: %s\n%s\n"
+                 (or title name) size filetype permalink))))))
+
+(defmethod slack-team-display-image-inlinep ((_file slack-file) team)
+  (slack-team-display-file-image-inlinep team))
+
+(defmethod slack-message-image-to-string ((file slack-file))
+  (slack-image-string (slack-file-thumb-image-spec file)))
+
+(defmethod slack-file-image-p ((this slack-file))
+  (string= (car (split-string (oref this mimetype) "/"))
+           "image"))
+
+(defmethod slack-message-large-image-to-string ((file slack-file))
+  (slack-image-string (slack-file-image-spec file)))
+
+(defmethod slack-message-to-string ((this slack-file-email) ts team)
+  (let ((body (slack-file-summary this ts team))
+        (thumb (slack-image-string (slack-file-thumb-image-spec this))))
+    (slack-format-message body thumb)))
+
+(defmethod slack-message-to-string ((this slack-file) ts team)
+  (let ((body (slack-file-summary this ts team))
+        (thumb (slack-image-string (slack-file-thumb-image-spec this))))
+    (slack-format-message body thumb)))
+
+(defmethod slack-message-to-string ((this slack-file-comment) team)
+  (with-slots (user comment) this
+    (let ((name (slack-user-name user team))
+          (status (slack-user-status user team)))
+      (format "%s\n%s\n"
+              (propertize (format "%s %s" name status)
+                          'face 'slack-message-output-header)
+              (slack-message-unescape-string comment team)))))
+
+(defun slack-file-list ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (room (slack-file-room-obj team)))
+    (slack-room-display room team)))
+
+(cl-defmethod slack-room-history-request ((room slack-file-room) team &key oldest after-success async)
+  (cl-labels
+      ((on-file-list
+        (&key data &allow-other-keys)
+        (slack-request-handle-error
+         (data "slack-file-list")
+         (let ((files (cl-loop for e in (plist-get data :files)
+                               collect (slack-file-create e))))
+           (if oldest
+               (slack-room-set-prev-messages room files)
+             (slack-room-set-messages room files)))
+         (if after-success
+             (funcall after-success)))))
+    (slack-request
+     (slack-request-create
+      slack-file-list-url
+      team
+      :params (list (if oldest
+                        (cons "ts_to" oldest)))
+      :success #'on-file-list))))
+
+(defun slack-file-select-sharing-channels (current-room-name team)
+  (cl-labels
+      ((select-channels
+        (channels acc)
+        (let ((selected (apply slack-completing-read-function
+                               (if acc
+                                   (list "Select another channel (or leave empty): "
+                                         (cons "" channels) nil t)
+                                 (list "Select channel: " channels nil t current-room-name)))))
+          (if (< 0 (length selected))
+              (select-channels (cl-remove-if (lambda (x) (equal selected (car-safe x))) channels)
+                               (cons selected acc))
+            acc)))
+       (channel-id (selected channels)
+                   (oref (cdr (cl-assoc selected channels :test #'string=))
+                         id)))
+    (let* ((channels (slack-room-names
+                      (append (oref team ims)
+                              (oref team channels)
+                              (oref team groups))
+                      team))
+           (target-channels (select-channels channels '())))
+      (mapcar #'(lambda (selected) (channel-id selected channels))
+              (cl-delete-if #'null target-channels)))))
+
+(defun slack-file-select-upload-file-as-buffer ()
+  (find-file-noselect
+   (car (find-file-read-args
+         "Select File: "
+         (confirm-nonexistent-file-or-buffer)))
+   t t))
+
+(defun slack-file-upload ()
+  (interactive)
+  (slack-if-let*
+      ((slack-buffer slack-current-buffer)
+       (team (oref slack-buffer team))
+       (buf (slack-file-select-upload-file-as-buffer))
+       (filename (read-from-minibuffer "Filename: "
+                                       (file-name-nondirectory
+                                        (buffer-file-name buf))))
+       (filetype (read-from-minibuffer "Filetype: "
+                                       (file-name-extension
+                                        (buffer-file-name buf))))
+       (initial-comment (read-from-minibuffer "Message: ")))
+      (cl-labels
+          ((on-file-upload (&key data &allow-other-keys)
+                           (slack-request-handle-error
+                            (data "slack-file-upload"))))
+
+        (slack-request
+         (slack-request-create
+          slack-file-upload-url
+          team
+          :type "POST"
+          :params (append (slack-file-upload-params slack-buffer)
+                          (list
+                           (cons "filename" filename)
+                           (cons "filetype" filetype)
+                           (if initial-comment
+                               (cons "initial_comment" initial-comment))))
+          :files (list (cons "file" buf))
+          :headers (list (cons "Content-Type" "multipart/form-data"))
+          :success #'on-file-upload)))
+    (error "Call from message buffer or thread buffer")))
+
+(defun slack-file-delete ()
+  (interactive)
+  (cl-labels
+      ((on-file-delete (&key data &allow-other-keys)
+                       (slack-request-handle-error
+                        (data "slack-file-delete"))))
+    (let* ((team (slack-team-select))
+           (files (oref (slack-file-room-obj team) messages))
+           (your-files (cl-remove-if #'(lambda (f)
+                                         (not (string= (oref f user)
+                                                       (oref team self-id))))
+                                     files))
+           (candidates (mapcar #'(lambda (f)
+                                   (cons (concat
+                                          (slack-message-time-to-string (slack-ts f))
+                                          " "
+                                          (oref f (or title name)))
+                                         f))
+                               your-files))
+           (selected (funcall slack-completing-read-function "Select File: " candidates))
+           (deleting-file (cdr (cl-assoc selected candidates :test #'string=))))
+      (slack-request
+       (slack-request-create
+        slack-file-delete-url
+        team
+        :params (list (cons "file" (oref deleting-file id)))
+        :success #'on-file-delete)))))
+
+(defmethod slack-file-id ((file slack-file))
+  (oref file id))
+
+(defmethod slack-file-channel ((_file slack-file))
+  nil)
+
+(defmethod slack-file-thumb-image-spec ((file slack-file))
+  (with-slots (thumb-360 thumb-360-w thumb-360-h thumb-160 thumb-80 thumb-64 thumb-pdf thumb-pdf-w thumb-pdf-h) file
+    (or (and thumb-360 (list thumb-360 thumb-360-w thumb-360-h))
+        (and thumb-160 (list thumb-160 nil nil))
+        (and thumb-80 (list thumb-80 nil nil))
+        (and thumb-64 (list thumb-64 nil nil))
+        (and thumb-pdf (list thumb-pdf thumb-pdf-w thumb-pdf-h))
+        (list nil nil nil))))
+
+(defmethod slack-file-image-spec ((this slack-file))
+  (with-slots (is-public url-download url-private-download) this
+    (list url-private-download
+          nil
+          nil
+          nil
+          (floor (* 0.9 (frame-pixel-width))))))
+
+(defmethod slack-file-channel-ids ((file slack-file))
+  (append (oref file channels)
+          (oref file ims)
+          (oref file groups)))
+
+(defun slack-file-link-info (file-id text)
+  (propertize text
+              'file file-id
+              'face '(:underline t :weight bold)
+              'keymap (let ((map (make-sparse-keymap)))
+                        (define-key map (kbd "RET")
+                          #'slack-file-display)
+                        map)))
+
+(defmethod slack-file-summary ((file slack-file) _ts team)
+  (with-slots (pretty-type mimetype permalink name title) file
+    (format "uploaded this %s: %s <%s|open in browser>"
+            (or pretty-type mimetype)
+            (slack-file-link-info (oref file id)
+                                  (slack-message-unescape-string (or title name)
+                                                                 team))
+            permalink)))
+
+(defmethod slack-file-summary ((this slack-file-email) ts team)
+  (with-slots (preview-plain-text plain-text is-expanded) this
+    (let* ((has-more (< (length preview-plain-text)
+                        (length plain-text)))
+           (body (slack-message-unescape-string
+                  (or (and is-expanded plain-text)
+                      (or (and has-more (format "%sโ€ฆ" preview-plain-text))
+                          preview-plain-text))
+                  team)))
+      (format "%s\n\n%s\n\n%s"
+              (call-next-method)
+              (propertize body
+                          'slack-defer-face #'slack-put-preview-overlay)
+              (propertize (or (and is-expanded "Collapse โ†‘")
+                              "+ Click to expand inline")
+                          'face '(:underline t)
+                          'keymap (let ((map (make-sparse-keymap)))
+                                    (define-key map (kbd "RET")
+                                      #'(lambda ()
+                                          (interactive)
+                                          (slack-buffer-toggle-email-expand
+                                           slack-current-buffer
+                                           ts (oref this id))))
+                                    map))))))
+
+(defmacro slack-with-file (id team &rest body)
+  (declare (indent 2) (debug t))
+  `(cl-loop for file in (oref (slack-file-room-obj ,team) messages)
+            do (when (string= (oref file id) ,id)
+                 ,@body)))
+
+(defmethod slack-room-buffer-name ((this slack-file) _team)
+  (with-slots (name) this
+    (format "*Slack File - %s*" name)))
+
+(define-derived-mode slack-file-info-mode lui-mode "Slack File Info"
+  ""
+  (setq-local default-directory slack-default-directory)
+  )
+
+(defun slack-file-display ()
+  (interactive)
+  (slack-if-let* ((id (get-text-property (point) 'file))
+                  (buf slack-current-buffer))
+      (slack-buffer-display-file buf id)))
+
+(defmethod slack-message-star-added ((this slack-file))
+  (oset this is-starred t))
+
+(defmethod slack-message-star-removed ((this slack-file))
+  (oset this is-starred nil))
+
+(defmethod slack-message-star-api-params ((this slack-file))
+  (cons "file" (oref this id)))
+
+(defun slack-file-process-star-api (url team file-id)
+  (slack-with-file file-id team
+    (slack-message-star-api-request url
+                                    (list (slack-message-star-api-params file))
+                                    team)))
+
+(defmethod slack-message-body-to-string ((this slack-file-email) _team)
+  (let ((from (format "From: %s" (mapconcat #'(lambda (e) (oref e original))
+                                            (oref this from)
+                                            ", ")))
+        (to (format "To: %s" (mapconcat #'(lambda (e) (oref e original))
+                                        (oref this to)
+                                        ", ")))
+        (cc (format "CC: %s" (mapconcat #'(lambda (e) (oref e original))
+                                        (oref this cc)
+                                        ", ")))
+        (subject (format "Subject: %s" (oref this subject)))
+        (body (propertize (format "\n%s" (oref this plain-text))
+                          'slack-defer-face #'slack-put-email-body-overlay))
+        (date (format "Date: %s" (slack-message-time-to-string (oref this created)))))
+    (mapconcat #'identity
+               (list from to cc subject date body)
+               "\n")))
+
+(defun slack-redisplay (file team)
+  ;; (slack-if-let* ((buffer (slack-buffer-find 'slack-file-info-buffer file team)))
+  ;;     (slack-buffer--replace buffer nil))
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-file-list-buffer
+                                             (slack-file-room-obj team)
+                                             team)))
+      (slack-buffer-replace buffer file)))
+
+(defmethod slack-message-update ((this slack-file) team &rest _args)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-file-info-buffer
+                                             this
+                                             team)))
+      (progn
+        (oset buffer file this)
+        (slack-buffer-update buffer))))
+
+(defmethod slack-ts ((this slack-file))
+  (number-to-string (oref this timestamp)))
+
+(defmethod slack-thread-message-p ((this slack-file))
+  nil)
+
+(provide 'slack-file)
+;;; slack-file.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file.elc
new file mode 100644
index 000000000000..927bb346ee9c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-file.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-group.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-group.el
new file mode 100644
index 000000000000..f26538bf9e5f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-group.el
@@ -0,0 +1,287 @@
+;;; slack-group.el --- slack private group interface  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  Yuya Minami
+
+;; Author: Yuya Minami
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-util)
+(require 'slack-buffer)
+(require 'slack-request)
+
+(defconst slack-group-history-url "https://slack.com/api/groups.history")
+(defconst slack--group-open-url "https://slack.com/api/groups.open")
+(defconst slack-group-buffer-name "*Slack - Private Group*")
+(defconst slack-group-list-url "https://slack.com/api/groups.list")
+(defconst slack-group-update-mark-url "https://slack.com/api/groups.mark")
+(defconst slack-create-group-url "https://slack.com/api/groups.create")
+(defconst slack-group-rename-url "https://slack.com/api/groups.rename")
+(defconst slack-group-invite-url "https://slack.com/api/groups.invite")
+(defconst slack-group-leave-url "https://slack.com/api/groups.leave")
+(defconst slack-group-archive-url "https://slack.com/api/groups.archive")
+(defconst slack-group-unarchive-url "https://slack.com/api/groups.unarchive")
+(defconst slack-mpim-close-url "https://slack.com/api/mpim.close")
+(defconst slack-mpim-open-url "https://slack.com/api/mpim.open")
+(defconst slack-group-info-url "https://slack.com/api/groups.info")
+
+(defvar slack-buffer-function)
+
+(defclass slack-group (slack-room)
+  ((is-group :initarg :is_group :initform nil)
+   (creator :initarg :creator :initform "")
+   (is-archived :initarg :is_archived :initform nil)
+   (is-mpim :initarg :is_mpim :initform nil)
+   (topic :initarg :topic :initform nil)
+   (purpose :initarg :purpose :initform nil)))
+
+(defmethod slack-merge ((this slack-group) other)
+  (call-next-method)
+  (with-slots (is-group creator is-archived is-mpim members topic purpose) this
+    (setq is-group (oref other is-group))
+    (setq creator (oref other creator))
+    (setq is-archived (oref other is-archived))
+    (setq is-mpim (oref other is-mpim))
+    (setq members (oref other members))
+    (setq topic (oref other topic))
+    (setq purpose (oref other purpose))))
+
+(defun slack-group-names (team &optional filter)
+  (with-slots (groups) team
+    (slack-room-names groups team filter)))
+
+(defmethod slack-room-subscribedp ((room slack-group) team)
+  (with-slots (subscribed-channels) team
+    (let ((name (slack-room-name room team)))
+      (and name
+           (memq (intern name) subscribed-channels)))))
+
+(defmethod slack-room-buffer-name ((room slack-group) team)
+  (concat slack-group-buffer-name
+          " : "
+          (slack-room-display-name room team)))
+
+(defun slack-group-select ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (room (slack-room-select
+                (cl-loop for team in (list team)
+                         for groups = (oref team groups)
+                         nconc groups)
+                team)))
+    (slack-room-display room team)))
+
+(defun slack-group-list-update (&optional team after-success)
+  (interactive)
+  (let ((team (or team (slack-team-select))))
+    (cl-labels ((on-list-update
+                 (&key data &allow-other-keys)
+                 (slack-request-handle-error
+                  (data "slack-group-list-update")
+                  (slack-merge-list (oref team groups)
+                                    (mapcar #'(lambda (g)
+                                                (slack-room-create
+                                                 g team 'slack-group))
+                                            (plist-get data :groups)))
+                  (if after-success
+                      (funcall after-success team))
+                  (mapc #'(lambda (room)
+                            (slack-room-info-request room team))
+                        (oref team groups))
+                  (slack-log "Slack Group List Updated" team :level 'info))))
+      (slack-room-list-update slack-group-list-url
+                              #'on-list-update
+                              team
+                              :sync nil))))
+
+
+(defmethod slack-room-update-mark-url ((_room slack-group))
+  slack-group-update-mark-url)
+
+(defun slack-create-group ()
+  (interactive)
+  (let ((team (slack-team-select)))
+    (cl-labels
+        ((on-create-group (&key data &allow-other-keys)
+                          (slack-request-handle-error
+                           (data "slack-create-group"))))
+      (slack-create-room slack-create-group-url
+                         team
+                         #'on-create-group))))
+
+(defun slack-group-rename ()
+  (interactive)
+  (slack-room-rename slack-group-rename-url
+                     #'slack-group-names))
+
+(defun slack-group-invite ()
+  (interactive)
+  (slack-room-invite slack-group-invite-url
+                     #'slack-group-names))
+
+(defun slack-group-leave ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (group (slack-current-room-or-select
+                 #'(lambda ()
+                     (slack-group-names team)))))
+    (cl-labels
+        ((on-group-leave
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-group-leave")
+           (with-slots (groups) team
+             (setq groups
+                   (cl-delete-if #'(lambda (g)
+                                     (slack-room-equal-p group g))
+                                 groups)))
+           (message "Left Group: %s"
+                    (slack-room-display-name group team)))))
+      (slack-room-request-with-id slack-group-leave-url
+                                  (oref group id)
+                                  team
+                                  #'on-group-leave))))
+
+(defmethod slack-room-archived-p ((room slack-group))
+  (oref room is-archived))
+
+(defun slack-group-archive ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (group (slack-current-room-or-select
+                 #'(lambda ()
+                     (slack-group-names
+                      team
+                      #'(lambda (groups)
+                          (cl-remove-if #'slack-room-archived-p
+                                        groups)))))))
+    (cl-labels
+        ((on-group-archive (&key data &allow-other-keys)
+                           (slack-request-handle-error
+                            (data "slack-group-archive"))))
+      (slack-room-request-with-id slack-group-archive-url
+                                  (oref group id)
+                                  team
+                                  #'on-group-archive))))
+
+(defun slack-group-unarchive ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (group (slack-current-room-or-select
+                 #'(lambda ()
+                     (slack-group-names
+                      team
+                      #'(lambda (groups)
+                          (cl-remove-if-not #'slack-room-archived-p
+                                            groups)))))))
+    (cl-labels
+        ((on-group-unarchive (&key _data &allow-other-keys)
+                             (data "slack-group-unarchive")))
+      (slack-room-request-with-id slack-group-unarchive-url
+                                  (oref group id)
+                                  team
+                                  #'on-group-unarchive))))
+
+
+(defun slack-group-members-s (group team)
+  (with-slots (members) group
+    (mapconcat #'(lambda (user)
+                   (slack-user-name user
+                                    team))
+               members ", ")))
+
+(defun slack-group-mpim-open ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (users (slack-user-names team)))
+    (cl-labels
+        ((select-users (users acc)
+                       (let ((selected (funcall slack-completing-read-function "Select User: "
+                                                users nil t)))
+                         (if (< 0 (length selected))
+                             (select-users users
+                                           (push (cdr (cl-assoc selected users :test #'string=)) acc))
+                           acc)))
+         (on-success
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-group-mpim-open"))))
+      (slack-request
+       (slack-request-create
+        slack-mpim-open-url
+        team
+        :type "POST"
+        :params (list (cons "users" (mapconcat (lambda (u) (plist-get u :id)) (select-users users '()) ",")))
+        :success #'on-success)))))
+
+(defun slack-group-mpim-close ()
+  (interactive)
+  (let* ((team (slack-team-select)))
+    (slack-select-from-list
+        ((slack-group-names team #'(lambda (groups)
+                                     (cl-remove-if-not #'slack-mpim-p
+                                                       groups)))
+         "Select MPIM: ")
+        (cl-labels
+            ((on-success
+              (&key data &allow-other-keys)
+              (slack-request-handle-error
+               (data "slack-group-mpim-close")
+               (let ((group (slack-room-find (oref selected id) team)))
+                 (with-slots (groups) team
+                   (setq groups
+                         (cl-delete-if #'(lambda (g)
+                                           (slack-room-equal-p group g))
+                                       groups)))
+                 (if (plist-get data :already_closed)
+                     (message "Direct Message Channel with %s Already Closed"
+                              (slack-group-members-s group team)))))))
+          (slack-request
+           (slack-request-create
+            slack-mpim-close-url
+            team
+            :type "POST"
+            :params (list (cons "channel" (oref selected id)))
+            :success #'on-success))))))
+
+
+(defmethod slack-mpim-p ((room slack-group))
+  (oref room is-mpim))
+
+(defmethod slack-room-get-info-url ((_room slack-group))
+  slack-group-info-url)
+
+(defmethod slack-room-update-info ((room slack-group) data team)
+  (let ((new-room (slack-room-create (plist-get data :group)
+                                     team
+                                     'slack-group)))
+    (slack-merge room new-room)))
+
+(defmethod slack-room-history-url ((_room slack-group))
+  slack-group-history-url)
+
+(defmethod slack-room-replies-url ((_room slack-group))
+  "https://slack.com/api/groups.replies")
+
+(provide 'slack-group)
+;;; slack-group.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-group.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-group.elc
new file mode 100644
index 000000000000..c07a081f913b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-group.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-im.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-im.el
new file mode 100644
index 000000000000..ba224483e03c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-im.el
@@ -0,0 +1,249 @@
+;;; slack-im.el ---slack direct message interface    -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-room)
+(require 'slack-buffer)
+(require 'slack-user)
+(require 'slack-request)
+
+(defvar slack-buffer-function)
+
+(defconst slack-im-history-url "https://slack.com/api/im.history")
+(defconst slack-im-buffer-name "*Slack - Direct Messages*")
+(defconst slack-user-list-url "https://slack.com/api/users.list")
+(defconst slack-im-list-url "https://slack.com/api/im.list")
+(defconst slack-im-close-url "https://slack.com/api/im.close")
+(defconst slack-im-open-url "https://slack.com/api/im.open")
+(defconst slack-im-update-mark-url "https://slack.com/api/im.mark")
+
+(defclass slack-im (slack-room)
+  ((user :initarg :user :initform "")
+   (is-open :initarg :is_open :initform t)
+   (is-user-deleted :initarg :is_user_deleted :initform nil)))
+
+(defmethod slack-merge ((this slack-im) other)
+  (call-next-method)
+  (with-slots (user is-open) this
+    (setq user (oref other user))
+    (setq is-open (oref other is-open))))
+
+(defmethod slack-room-open-p ((room slack-im))
+  (oref room is-open)
+  (not (oref room is-user-deleted)))
+
+(defmethod slack-im-user-presence ((room slack-im) team)
+  (slack-user-presence-to-string (slack-user-find room team)))
+
+(defmethod slack-im-user-dnd-status ((room slack-im) team)
+  (slack-user-dnd-status-to-string (slack-user-find room
+                                                    team)))
+
+(defmethod slack-room-name ((room slack-im) team)
+  (with-slots (user) room
+    (slack-user-name user team)))
+
+(defmethod slack-room-display-name ((room slack-im) team)
+  "To Display emoji in minibuffer configure `emojify-inhibit-in-buffer-functions'"
+  (let* ((status (slack-user-status (oref room user) team))
+         (room-name (or (and status
+                             (format "%s %s"
+                                     (slack-room-name room team)
+                                     status))
+                        (slack-room-name room team))))
+    (if slack-display-team-name
+        (format "%s - %s"
+                (slack-team-name team)
+                room-name)
+      room-name)))
+
+(defun slack-im-user-name (im team)
+  (with-slots (user) im
+    (slack-user-name user team)))
+
+(defun slack-im-names (team)
+  (with-slots (ims) team
+    (slack-room-names ims
+                      team
+                      #'(lambda (ims)
+                          (cl-remove-if #'(lambda (im) (not (oref im is-open)))
+                                        ims)))))
+
+(defmethod slack-room-buffer-name ((room slack-im) team)
+  (concat slack-im-buffer-name
+          " : "
+          (slack-room-display-name room team)))
+
+(defun slack-im-select ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (candidates (cl-loop for team in (list team)
+                              for ims = (cl-remove-if #'(lambda (im)
+                                                          (not (oref im is-open)))
+                                                      (oref team ims))
+                              nconc ims))
+         (room (slack-room-select candidates team)))
+    (slack-room-display room team)))
+
+(defun slack-user-equal-p (a b)
+  (string= (plist-get a :id) (plist-get b :id)))
+
+(defun slack-user-pushnew (user team)
+  (with-slots (users) team
+    (cl-pushnew user users :test #'slack-user-equal-p)))
+
+(defun slack-im-update-room-list (users team &optional after-success)
+  (cl-labels ((on-update-room-list
+               (&key data &allow-other-keys)
+               (slack-request-handle-error
+                (data "slack-im-update-room-list")
+                (mapc #'(lambda (u) (slack-user-pushnew u team))
+                      (append users nil))
+                (slack-merge-list (oref team ims)
+                                  (mapcar #'(lambda (d)
+                                              (slack-room-create d team 'slack-im))
+                                          (plist-get data :ims)))
+                (if after-success
+                    (funcall after-success team))
+                (slack-request-dnd-team-info team)
+                (mapc #'(lambda (room)
+                          (slack-room-info-request room team))
+                      (oref team ims))
+                (slack-log "Slack Im List Updated" team :level 'info))))
+    (slack-room-list-update slack-im-list-url
+                            #'on-update-room-list
+                            team
+                            :sync nil)))
+
+(defun slack-im-list-update (&optional team after-success)
+  (interactive)
+  (let ((team (or team (slack-team-select))))
+    (cl-labels
+        ((on-list-update
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-im-list-update")
+           (let* ((members (append (plist-get data :members) nil)))
+             (slack-im-update-room-list members team after-success)))))
+      (slack-request
+       (slack-request-create
+        slack-user-list-url
+        team
+        :success #'on-list-update)))))
+
+(defmethod slack-room-update-mark-url ((_room slack-im))
+  slack-im-update-mark-url)
+
+(defun slack-im-close ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (alist (cl-remove-if #'(lambda (im-names)
+                                  (not (oref (cdr im-names) is-open)))
+                              (slack-im-names team))))
+    (slack-select-from-list
+        (alist "Select User: ")
+        (cl-labels
+            ((on-success
+              (&key data &allow-other-keys)
+              (slack-request-handle-error
+               (data "slack-im-close")
+               (if (plist-get data :already_closed)
+                   (let ((im (slack-room-find (oref selected id) team)))
+                     (oset im is-open nil)
+                     (message "Direct Message Channel with %s Already Closed"
+                              (slack-user-name (oref im user) team)))))))
+          (slack-request
+           (slack-request-create
+            slack-im-close-url
+            team
+            :type "POST"
+            :params (list (cons "channel" (oref selected id)))
+            :success #'on-success))))))
+
+(defun slack-im-open (&optional user after-success)
+  (interactive)
+  (let* ((team (slack-team-select))
+         (user (or user (slack-select-from-list
+                            ((slack-user-name-alist
+                              team
+                              :filter #'(lambda (users) (cl-remove-if #'slack-user-hidden-p users)))
+                             "Select User: ")))))
+    (cl-labels
+        ((on-success
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-im-open")
+           (if (plist-get data :already_open)
+               (let ((im (slack-room-find (plist-get (plist-get data :channel) :id) team)))
+                 (oset im is-open t)
+                 (message "Direct Message Channel with %s Already Open"
+                          (slack-user-name (oref im user) team))))
+           (when (functionp after-success)
+             (funcall after-success)))))
+      (slack-request
+       (slack-request-create
+        slack-im-open-url
+        team
+        :type "POST"
+        :params (list (cons "user" (plist-get user :id)))
+        :success #'on-success)))))
+
+(defmethod slack-room-label-prefix ((room slack-im) team)
+  (format "%s "
+          (or
+           (slack-im-user-dnd-status room team)
+           (slack-im-user-presence room team))))
+
+(defmethod slack-room-get-info-url ((_room slack-im))
+  slack-im-open-url)
+
+(defmethod slack-room-update-info ((room slack-im) data team)
+  (let ((new-room (slack-room-create (plist-get data :channel)
+                                     team
+                                     'slack-im)))
+
+    (slack-merge room new-room)))
+
+(defmethod slack-room-info-request-params ((room slack-im))
+  (list (cons "user" (oref room user))
+        (cons "return_im" "true")))
+
+(defmethod slack-room-get-members ((room slack-im))
+  (list (oref room user)))
+
+(defun slack-im-find-by-user-id (user-id team)
+  (cl-find-if #'(lambda (im) (string= user-id (oref im user)))
+              (oref team ims)))
+
+(defmethod slack-room-history-url ((_room slack-im))
+  slack-im-history-url)
+
+(defmethod slack-room-replies-url ((_room slack-im))
+  "https://slack.com/api/im.replies")
+
+(provide 'slack-im)
+;;; slack-im.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-im.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-im.elc
new file mode 100644
index 000000000000..3bba70fbf39a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-im.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-buffer.el
new file mode 100644
index 000000000000..3ed9fc14f9a4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-buffer.el
@@ -0,0 +1,429 @@
+;;; slack-message-buffer.el ---                      -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-util)
+(require 'slack-room-buffer)
+(require 'slack-buffer)
+(require 'slack-request)
+(require 'slack-action)
+
+(defface slack-new-message-marker-face
+  '((t (:foreground "#d33682"
+                    :weight bold
+                    :height 0.8)))
+  "Face used to New Message Marker."
+  :group 'slack)
+
+(define-derived-mode slack-message-buffer-mode slack-mode "Slack Message Buffer"
+  (add-hook 'lui-pre-output-hook 'slack-buffer-buttonize-link nil t)
+  (add-hook 'lui-pre-output-hook 'slack-add-face-lazy nil t)
+  (add-hook 'lui-pre-output-hook 'slack-search-code-block nil t)
+  (add-hook 'lui-post-output-hook 'slack-display-image t t)
+  (add-hook 'lui-pre-output-hook 'slack-display-inline-action t t)
+  ;; TODO move to `slack-room-buffer' ?
+  (cursor-sensor-mode)
+  (setq-local lui-max-buffer-size nil)
+  )
+
+(defclass slack-message-buffer (slack-room-buffer)
+  ((oldest :initform nil :type (or null string))
+   (latest :initform nil :type (or null string))
+   (marker-overlay :initform nil)
+   (update-mark-timer :initform '(nil . nil)) ;; (timestamp . timer)
+   ))
+
+(defmethod slack-buffer-last-read ((this slack-message-buffer))
+  (with-slots (room) this
+    (oref room last-read)))
+
+(cl-defmethod slack-buffer-update-mark ((this slack-message-buffer) &key (force nil))
+  (with-slots (room update-mark-timer team) this
+    (let* ((ts (slack-get-ts))
+           (timer-timeout-sec (or (and force 0) 5))
+           (prev-mark (or (car update-mark-timer)
+                          (slack-buffer-last-read this)))
+           (prev-timer (cdr update-mark-timer)))
+      (when (or force (or (string< prev-mark ts)
+                          (string= prev-mark ts)))
+        (slack-log (format "%s: update mark to %s"
+                           (slack-room-name room team)
+                           ts)
+                   (oref this team))
+        (when (timerp prev-timer)
+          (cancel-timer prev-timer))
+        (cl-labels
+            ((update-mark ()
+                          (slack-buffer-update-mark-request this ts)))
+          (setq update-mark-timer
+                (cons ts (run-at-time timer-timeout-sec nil #'update-mark))))))))
+
+(defmethod slack-buffer-update-mark-request ((this slack-message-buffer) ts &optional after-success)
+  (with-slots (room team) this
+    (when (slack-room-member-p room)
+      (cl-labels ((on-update-mark (&key data &allow-other-keys)
+                                  (slack-request-handle-error
+                                   (data "slack-buffer-update-mark-request")
+                                   (oset room last-read ts)
+                                   (slack-buffer-update-marker-overlay this)
+                                   (when (functionp after-success)
+                                     (funcall after-success)))))
+        (with-slots (id) room
+          (slack-request
+           (slack-request-create
+            (slack-room-update-mark-url room)
+            team
+            :type "POST"
+            :params (list (cons "channel"  id)
+                          (cons "ts"  ts))
+            :success #'on-update-mark)))))))
+
+(defmethod slack-buffer-send-message ((this slack-message-buffer) message)
+  (with-slots (room team) this
+    (slack-message-send-internal message (oref room id) team)))
+
+(defmethod slack-buffer-latest-ts ((this slack-message-buffer))
+  (with-slots (room) this
+    (slack-if-let* ((latest (oref room latest)))
+        (slack-ts latest))))
+
+(defmethod slack-buffer-buffer ((this slack-message-buffer))
+  (let ((buffer-already-exists-p (get-buffer (slack-buffer-name this)))
+        (buffer (call-next-method))
+        (last-read (slack-buffer-last-read this)))
+    (with-current-buffer buffer
+      (if (slack-team-mark-as-read-immediatelyp (oref this team))
+          (progn
+            (unless buffer-already-exists-p
+              (goto-char (marker-position lui-input-marker)))
+            (and (slack-buffer-latest-ts this)
+                 (slack-buffer-update-mark-request this
+                                                   (slack-buffer-latest-ts this))))
+        (unless (string= "0" last-read)
+          (unless buffer-already-exists-p
+            (slack-buffer-goto last-read))
+          (slack-buffer-update-marker-overlay this))))
+
+    buffer))
+
+(defmethod slack-buffer-display-unread-threads ((this slack-message-buffer))
+  (with-slots (room team) this
+    (let* ((threads (mapcar #'(lambda (m) (oref m thread))
+                            (cl-remove-if
+                             #'(lambda (m)
+                                 (or (not (slack-message-thread-parentp m))
+                                     (not (< 0 (oref (oref m thread) unread-count)))))
+                             (oref room messages))))
+           (alist (mapcar #'(lambda (thread)
+                              (cons (slack-thread-title thread team) thread))
+                          (cl-sort threads
+                                   #'string>
+                                   :key #'(lambda (thread) (oref thread thread-ts)))))
+           (selected (slack-select-from-list (alist "Select Thread: "))))
+      (slack-thread-show-messages selected room team))))
+
+(defmethod slack-buffer-start-thread ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (let* ((message (slack-room-find-message room ts))
+           (buf (slack-create-thread-message-buffer room team ts)))
+      (when (slack-reply-broadcast-message-p message)
+        (error "Can't start thread from broadcasted message"))
+      (slack-buffer-display buf))))
+
+(defmethod slack-buffer-major-mode ((this slack-message-buffer))
+  'slack-message-buffer-mode)
+
+(defmethod slack-buffer-init-buffer ((this slack-message-buffer))
+  (let ((buf (call-next-method)))
+    (with-current-buffer buf
+      (funcall (slack-buffer-major-mode this))
+      (slack-buffer-set-current-buffer this)
+      (goto-char (point-min))
+
+      (slack-buffer-insert-load-more this)
+
+      (with-slots (room team latest) this
+        (let* ((messages (slack-room-sorted-messages room))
+               (latest-message (car (last messages)))
+               (oldest-message (car messages)))
+          (cl-loop for m in messages
+                   do (if (and (or (null latest)
+                                   (string< latest (slack-ts m)))
+                               (or (not (slack-thread-message-p m))
+                                   (slack-reply-broadcast-message-p m)))
+                          (slack-buffer-insert this m t)))
+          (when latest-message
+            (slack-buffer-update-lastest this (slack-ts latest-message)))
+          (when oldest-message
+            (slack-buffer-update-oldest this oldest-message))))
+      )
+    (with-slots (room team) this
+      (let* ((class (eieio-object-class-name this)))
+        (slack-buffer-push-new-3 class room team)))
+    buf))
+
+
+(cl-defmethod slack-buffer-update ((this slack-message-buffer) message &key replace)
+  (with-slots (room team) this
+    (let ((buffer (get-buffer (slack-buffer-name this))))
+      (when (and (slack-team-mark-as-read-immediatelyp team)
+                 (slack-buffer-in-current-frame buffer))
+        (slack-buffer-update-mark-request this (slack-ts message)))
+
+      (if replace (slack-buffer-replace this message)
+        (slack-buffer-update-lastest this (slack-ts message))
+        (with-current-buffer buffer
+          (slack-buffer-insert this message))))))
+
+(defmethod slack-buffer-display-message-compose-buffer ((this slack-message-buffer))
+  (with-slots (room team) this
+    (let ((buf (slack-create-room-message-compose-buffer room team)))
+      (slack-buffer-display buf))))
+
+(defmethod slack-buffer-update-lastest ((this slack-message-buffer) latest)
+  (with-slots ((prev-latest latest)) this
+    (if (or (null prev-latest)
+            (string< prev-latest latest))
+        (setq prev-latest latest))))
+
+(defmethod slack-buffer-display-thread ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (let ((thread (slack-room-find-thread room ts)))
+      (if thread (slack-thread-show-messages thread room team)
+        (slack-thread-start)))))
+
+(defmethod slack-buffer-display-edit-message-buffer ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (let ((buf (slack-create-edit-message-buffer room team ts)))
+      (slack-buffer-display buf))))
+
+(defmethod slack-create-message-buffer ((room slack-room) team)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-message-buffer
+                                             room
+                                             team)))
+      buffer
+    (slack-message-buffer :room room :team team)))
+
+
+(defmethod slack-buffer-share-message ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (let ((buf (slack-create-message-share-buffer room team ts)))
+      (slack-buffer-display buf))))
+
+(defmethod slack-buffer-add-reaction-to-message
+  ((this slack-message-buffer) reaction ts)
+  (with-slots (room team) this
+    (slack-message-reaction-add reaction ts room team)))
+
+(defmethod slack-buffer-remove-reaction-from-message
+  ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (let* ((message (slack-room-find-message room ts))
+           (reactions (slack-message-reactions message))
+           (reaction (slack-message-reaction-select reactions)))
+      (slack-message-reaction-remove reaction ts room team))))
+
+(defmethod slack-buffer-pins-remove ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (slack-message-pins-request slack-message-pins-remove-url
+                                room team ts)))
+
+(defmethod slack-buffer-pins-add ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (slack-message-pins-request slack-message-pins-add-url
+                                room team ts)))
+(defmethod slack-buffer-remove-star ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (slack-message-star-api-request slack-message-stars-remove-url
+                                        (list (cons "channel" (oref room id))
+                                              (slack-message-star-api-params message))
+                                        team))))
+
+(defmethod slack-buffer-add-star ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (slack-message-star-api-request slack-message-stars-add-url
+                                        (list (cons "channel" (oref room id))
+                                              (slack-message-star-api-params message))
+                                        team))))
+
+(defmethod slack-buffer-update-oldest ((this slack-message-buffer) message)
+  (when (and message (or (null (oref this oldest))
+                         (string< (slack-ts message) (oref this oldest))))
+    (oset this oldest (slack-ts message))))
+
+(defmethod slack-buffer-load-missing-messages ((this slack-message-buffer))
+  (with-slots (room team) this
+    (cl-labels
+        ((request-messages (latest)
+                           (slack-room-history-request room team
+                                                       :latest latest
+                                                       :count 100
+                                                       :after-success #'after-success))
+         (after-success (has-more)
+                        (let* ((messages (slack-room-sorted-messages room))
+                               (oldest-message (car messages))
+                               (latest-message (car (last messages))))
+                          (if has-more
+                              (request-messages (slack-ts latest-message))
+                            (progn
+                              (with-current-buffer (slack-buffer-buffer this)
+                                (let ((inhibit-read-only t))
+                                  (slack-buffer-delete-overlay this)
+                                  (delete-region (point-min)
+                                                 (marker-position lui-output-marker)))
+                                (slack-buffer-prepare-marker-for-history this)
+                                (slack-buffer-insert-load-more this)
+                                (cl-loop for m in messages
+                                         do (slack-buffer-insert this m t))
+                                (slack-buffer-goto (slack-buffer-last-read this))
+                                (slack-buffer-update-marker-overlay this))
+                              (when oldest-message
+                                (slack-buffer-update-oldest this
+                                                            oldest-message)))))))
+      (oset room messages nil)
+      (request-messages nil))))
+
+(defmethod slack-buffer-load-more ((this slack-message-buffer))
+  (with-slots (room team oldest) this
+    (let ((current-ts (let ((change (next-single-property-change (point) 'ts)))
+                        (when change
+                          (get-text-property change 'ts))))
+          (cur-point (point)))
+      (cl-labels
+          ((update-buffer
+            (messages)
+            (with-current-buffer (slack-buffer-buffer this)
+              (slack-buffer-widen
+               (let ((inhibit-read-only t))
+                 (goto-char (point-min))
+
+                 (slack-if-let* ((loading-message-end
+                                  (slack-buffer-loading-message-end-point this)))
+                     (progn
+                       (slack-buffer-delete-overlay this)
+                       (delete-region (point-min) loading-message-end))
+                   (message "loading-message-end not found, oldest: %s" oldest))
+
+                 (set-marker lui-output-marker (point-min))
+                 (if (and messages (< 0 (length messages)))
+                     (slack-buffer-insert-load-more this)
+                   (let ((lui-time-stamp-position nil))
+                     (lui-insert "(no more messages)\n")))
+
+                 (cl-loop for m in messages
+                          do (slack-buffer-insert this m t))
+                 (lui-recover-output-marker)
+                 (slack-buffer-update-marker-overlay this)
+                 ))
+              (if current-ts
+                  (slack-buffer-goto current-ts)
+                (goto-char cur-point))))
+           (after-success (&rest _ignore)
+                          (let ((messages (cl-remove-if #'(lambda (e)
+                                                            (or (string< oldest e)
+                                                                (string= oldest e)))
+                                                        (slack-room-sorted-messages room)
+                                                        :key #'slack-ts)))
+                            (update-buffer messages)
+                            (slack-buffer-update-oldest this (car messages)))))
+        (slack-room-history-request room team
+                                    :oldest oldest
+                                    :after-success #'after-success)))))
+
+(defmethod slack-buffer-display-pins-list ((this slack-message-buffer))
+  (with-slots (room team) this
+    (cl-labels
+        ((on-pins-list (&key data &allow-other-keys)
+                       (slack-request-handle-error
+                        (data "slack-room-pins-list")
+                        (let* ((buf (slack-create-pinned-items-buffer
+                                     room team (plist-get data :items))))
+                          (slack-buffer-display buf)))))
+      (slack-request
+       (slack-request-create
+        slack-room-pins-list-url
+        team
+        :params (list (cons "channel" (oref room id)))
+        :success #'on-pins-list)))))
+
+(defmethod slack-buffer-display-user-profile ((this slack-message-buffer))
+  (with-slots (room team) this
+    (let* ((members (cl-remove-if
+                     #'(lambda (e)
+                         (or (slack-user-self-p e team)
+                             (slack-user-hidden-p
+                              (slack-user--find e team))))
+                     (slack-room-get-members room)))
+           (user-alist (mapcar #'(lambda (u) (cons (slack-user-name u team) u))
+                               members))
+           (user-id (if (eq 1 (length members))
+                        (car members)
+                      (slack-select-from-list (user-alist "Select User: ")))))
+      (let ((buf (slack-create-user-profile-buffer team user-id)))
+        (slack-buffer-display buf)))))
+
+(defmethod slack-buffer-delete-overlay ((this slack-message-buffer))
+  (when (oref this marker-overlay)
+    (delete-overlay (oref this marker-overlay))))
+
+(defmethod slack-buffer-update-marker-overlay ((this slack-message-buffer))
+  (let ((buf (get-buffer (slack-buffer-name this))))
+    (and buf (with-current-buffer buf
+               (let* ((last-read (slack-buffer-last-read this))
+                      (beg (slack-buffer-ts-eq (point-min) (point-max) last-read))
+                      (end (and beg (next-single-property-change beg 'ts))))
+                 (when (and beg end)
+                   (if (oref this marker-overlay)
+                       (move-overlay (oref this marker-overlay)
+                                     beg end)
+                     (progn
+                       (oset this marker-overlay (make-overlay beg end))
+                       (let ((after-string
+                              (propertize "New Message"
+                                          'face
+                                          'slack-new-message-marker-face)))
+                         (overlay-put (oref this marker-overlay)
+                                      'after-string
+                                      (format "\n%s" after-string)))))))))))
+
+(defmethod slack-buffer-replace ((this slack-message-buffer) message)
+  (call-next-method)
+  (slack-buffer-update-marker-overlay this))
+
+(defmethod slack-file-upload-params ((this slack-message-buffer))
+  (with-slots (room team) this
+    (list (cons "channels"
+                (mapconcat #'identity
+                           (slack-file-select-sharing-channels
+                            (slack-room-label room team)
+                            team)
+                           ",")))))
+
+(provide 'slack-message-buffer)
+;;; slack-message-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-buffer.elc
new file mode 100644
index 000000000000..41803497b5c0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-compose-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-compose-buffer.el
new file mode 100644
index 000000000000..7bf581086194
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-compose-buffer.el
@@ -0,0 +1,51 @@
+;;; slack-message-compose-buffer.el ---              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-buffer)
+
+(define-derived-mode slack-message-compose-buffer-mode
+  slack-edit-message-mode
+  "Slack Compose Message")
+
+(defclass slack-message-compose-buffer (slack-buffer) ())
+
+(defmethod slack-buffer-send-message ((this slack-message-compose-buffer) _message)
+  (let ((buffer (slack-buffer-buffer this)))
+    (with-current-buffer buffer
+      (kill-buffer)
+      (if (> (count-windows) 1) (delete-window)))))
+
+(defmethod slack-buffer-init-buffer ((this slack-message-compose-buffer))
+  (let ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-message-compose-buffer-mode)
+      (slack-buffer-set-current-buffer this))
+    buf))
+
+
+(provide 'slack-message-compose-buffer)
+;;; slack-message-compose-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-compose-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-compose-buffer.elc
new file mode 100644
index 000000000000..4b5fe10abfda
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-compose-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-edit-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-edit-buffer.el
new file mode 100644
index 000000000000..50dc4bf47496
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-edit-buffer.el
@@ -0,0 +1,94 @@
+;;; slack-message-edit-buffer.el ---                 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-message-compose-buffer)
+
+(define-derived-mode slack-message-edit-buffer-mode
+  slack-edit-message-mode
+  "Slack Edit Message")
+
+(defclass slack-message-edit-buffer (slack-message-compose-buffer)
+  ((room :initarg :room :type slack-room)
+   (ts :initarg :ts :type string)))
+
+(defun slack-buffer-find-4 (class a b team)
+  (slack-if-let* ((buf (cl-find-if #'(lambda (buf)
+                                 (string= (buffer-name buf)
+                                          (slack-buffer-name class a b team)))
+                             (slot-value team class))))
+      (with-current-buffer buf slack-current-buffer)))
+
+(defun slack-create-edit-message-buffer (room team ts)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-message-edit-buffer
+                                       room ts team)))
+      buffer
+    (slack-message-edit-buffer :room room :team team :ts ts)))
+
+(defmethod slack-buffer-find :static
+  ((class slack-message-edit-buffer) room ts team)
+  (slack-buffer-find-4 class room ts team))
+
+(defmethod slack-buffer-name :static
+  ((class slack-message-edit-buffer) room  ts team)
+  (format "*Slack - %s : %s Edit Message %s"
+          (oref team name)
+          (slack-room-name room team)
+          ts))
+
+(defmethod slack-buffer-name ((this slack-message-edit-buffer))
+  (with-slots (room team ts) this
+    (slack-buffer-name (eieio-object-class-name this)
+                       room ts team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-message-edit-buffer))
+  (with-slots (room team ts) this
+    (let* ((buf (call-next-method))
+           (message (slack-room-find-message room ts)))
+      (with-current-buffer buf
+        (slack-message-edit-buffer-mode)
+        (slack-buffer-set-current-buffer this)
+        (insert (slack-message-unescape-string
+                 (slack-message-get-text message)
+                 team)))
+      (with-slots (room ts team) this
+        (slack-buffer-push-new-4 (eieio-object-class-name this)
+                                 room
+                                 ts
+                                 team))
+      buf)))
+
+(defmethod slack-buffer-send-message ((this slack-message-edit-buffer) message)
+  (with-slots (room team ts) this
+    (slack-if-let* ((m (slack-room-find-message room ts)))
+        (progn
+          (slack-message--edit (oref room id) team ts message)
+          (call-next-method)))))
+
+
+(provide 'slack-message-edit-buffer)
+;;; slack-message-edit-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-edit-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-edit-buffer.elc
new file mode 100644
index 000000000000..473fa3cd1ea9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-edit-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-editor.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-editor.el
new file mode 100644
index 000000000000..1c592cf65784
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-editor.el
@@ -0,0 +1,130 @@
+;;; slack-message-editor.el ---  edit message interface  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'slack-util)
+(require 'slack-room)
+(require 'slack-message-sender)
+
+(defconst slack-message-edit-url "https://slack.com/api/chat.update")
+(defconst slack-message-edit-buffer-name "*Slack - Edit message*")
+(defconst slack-message-write-buffer-name "*Slack - Write message*")
+(defconst slack-message-share-buffer-name "*Slack - Share message*")
+(defconst slack-share-url "https://slack.com/api/chat.shareMessage")
+(defvar slack-buffer-function)
+(defvar slack-target-ts)
+(make-local-variable 'slack-target-ts)
+(defvar slack-message-edit-buffer-type)
+(make-local-variable 'slack-message-edit-buffer-type)
+
+(defvar slack-edit-message-mode-map
+  (let ((keymap (make-sparse-keymap)))
+    (define-key keymap (kbd "C-s C-m") #'slack-message-embed-mention)
+    (define-key keymap (kbd "C-s C-c") #'slack-message-embed-channel)
+    (define-key keymap (kbd "C-c C-k") #'slack-message-cancel-edit)
+    (define-key keymap (kbd "C-c C-c") #'slack-message-send-from-buffer)
+    keymap))
+
+(define-derived-mode slack-edit-message-mode fundamental-mode "Slack Edit Msg"
+  ""
+  (slack-buffer-enable-emojify))
+
+(defun slack-message-share ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-share-message buf (slack-get-ts))))
+
+(defun slack-message-share--send (team room ts msg)
+  (let* ((slack-room-list (or (and (object-of-class-p room 'slack-channel)
+                                   (slack-message-room-list team))
+                              (list (cons (slack-room-display-name room team)
+                                          room))))
+         (share-channel-id (oref (slack-select-from-list
+                                     (slack-room-list
+                                      "Select Channel: "
+                                      :initial
+                                      (slack-room-name room team)))
+                                 id)))
+    (cl-labels
+        ((on-success (&key data &allow-other-keys)
+                     (slack-request-handle-error
+                      (data "slack-message-share"))))
+      (slack-request
+       (slack-request-create
+        slack-share-url
+        team
+        :type "POST"
+        :params (list (cons "channel" (oref room id))
+                      (cons "timestamp" ts)
+                      (cons "text" (slack-message-prepare-links
+                                    (slack-escape-message msg)
+                                    team))
+                      (cons "share_channel" share-channel-id))
+        :success #'on-success)))))
+
+(defun slack-message-write-another-buffer ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-display-message-compose-buffer buf)))
+
+(defmethod slack-message-get-user-id ((m slack-user-message))
+  (oref m user))
+
+(defun slack-message-edit ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-display-edit-message-buffer buf (slack-get-ts))))
+
+
+(defun slack-message-cancel-edit ()
+  (interactive)
+  (let ((buffer (slack-buffer-buffer slack-current-buffer)))
+    (with-current-buffer buffer
+      (erase-buffer)
+      (if (> (count-windows) 1) (delete-window)))))
+
+(defun slack-message-send-from-buffer ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer)
+            (text (buffer-substring-no-properties (point-min) (point-max))))
+      (slack-buffer-send-message buf text)))
+
+(defun slack-message--edit (channel team ts text)
+  (cl-labels ((on-edit (&key data &allow-other-keys)
+                       (slack-request-handle-error
+                        (data "slack-message--edit"))))
+    (slack-request
+     (slack-request-create
+      slack-message-edit-url
+      team
+      :type "POST"
+      :params (list (cons "channel" channel)
+                    (cons "ts" ts)
+                    (cons "text" (slack-message-prepare-links
+                                  (slack-escape-message text)
+                                  team)))
+      :success #'on-edit))))
+
+(provide 'slack-message-editor)
+;;; slack-message-editor.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-editor.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-editor.elc
new file mode 100644
index 000000000000..674de8184985
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-editor.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-formatter.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-formatter.el
new file mode 100644
index 000000000000..190c3a498ae6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-formatter.el
@@ -0,0 +1,337 @@
+;;; slack-message-formatter.el --- format message text  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-user)
+(require 'slack-room)
+
+(defface slack-profile-image-face
+  '((t (:background "#fff")))
+  "Face used to profile image."
+  :group 'slack)
+
+(defface slack-message-output-text
+  '((t (:weight normal :height 0.9)))
+  "Face used to text message."
+  :group 'slack)
+
+(defface slack-message-output-header
+  '((t (:foreground "#FFA000"
+                    :weight bold
+                    :height 1.0
+                    :underline t)))
+  "Face used to text message."
+  :group 'slack)
+
+(defface slack-message-output-reaction
+  '((t (:box (:line-width 1 :style released-button))))
+  "Face used to reactions."
+  :group 'slack)
+
+(defface slack-message-deleted-face
+  '((t (:strike-through t)))
+  "Face used to deleted message."
+  :group 'slack)
+
+(defface slack-attachment-header
+  '((t (:weight bold)))
+  "Face used to shared message header."
+  :group 'slack)
+
+(defface slack-attachment-footer
+  '((t (:height 0.8)))
+  "Face used to shared message footer."
+  :group 'slack)
+
+(defface slack-attachment-pad
+  '((t (:weight ultra-bold)))
+  "Face used to shared message pad."
+  :group 'slack)
+
+(defface slack-attachment-field-title
+  '((t (:weight bold :height 1.0)))
+  "Face used to attachment field title."
+  :group 'slack)
+
+(defcustom slack-date-formats
+  '((date_num . "%Y-%m-%d")
+    (date . "%B %d,%Y")
+    (date_short . "%b %d,%Y")
+    (date_long . "%A %B %d,%Y")
+    (date_pretty . "%B %d,%Y")
+    (date_short_pretty . "%b %d,%Y")
+    (date_long_pretty . "%A %B %d,%Y")
+    (time . "%H:%M")
+    (time_secs . "%H:%M:%S"))
+  "Date formats for Slack's date token.
+this format string passed to `format-time-string' function.
+see \"Formatting dates\" section in https://api.slack.com/docs/message-formatting"
+  :group 'slack)
+
+(defun slack-message-put-header-property (header)
+  (if header
+      (propertize header 'face 'slack-message-output-header)))
+
+(defun slack-message-put-text-property (text)
+  (if text
+      (propertize text 'face 'slack-message-output-text)))
+
+(defun slack-message-put-hard (text)
+  (if text
+      (propertize text 'hard t)))
+
+(defun slack-message-put-deleted-property (text)
+  (if text
+      (propertize text 'face 'slack-message-deleted-face)))
+
+(defun slack-message-time-to-string (ts)
+  (when ts
+    (when (stringp ts)
+      (setf ts (string-to-number ts)))
+    (format-time-string "%Y-%m-%d %H:%M:%S"
+                        (seconds-to-time ts))))
+
+(defmethod slack-message-header ((m slack-message) team)
+  (slack-message-sender-name m team))
+
+(defmethod slack-message-starred-p ((m slack-message))
+  (oref m is-starred))
+
+(defmethod slack-message-starred-str ((m slack-message))
+  (if (slack-message-starred-p m)
+      ":star:"
+    ""))
+
+(defun slack-format-message (&rest args)
+  (let ((messages args))
+    (mapconcat #'identity
+               (cl-remove-if #'(lambda (e) (< (length e) 1)) messages)
+               "\n")))
+
+(defmethod slack-message-profile-image ((m slack-message) team)
+  (slack-user-image (slack-user-find m team) team))
+
+(defmethod slack-message-header-with-image ((m slack-message) header team)
+  (let ((image (slack-message-profile-image m team)))
+    (if image
+        (format "%s %s" (propertize "image"
+                                    'display image
+                                    'face 'slack-profile-image-face)
+                header)
+      header)))
+
+(defun slack-message-header-to-string (m team)
+  (let ((header (format "%s %s"
+                        (slack-message-put-header-property
+                         (slack-message-header m team))
+                        (slack-message-starred-str m))))
+    (if (slack-team-display-profile-imagep team)
+        (slack-message-header-with-image m header team)
+      header)))
+
+(defmethod slack-message-body-to-string ((m slack-message) team)
+  (let ((raw-body (slack-message-body m team)))
+    (if (oref m deleted-at)
+        (slack-message-put-deleted-property raw-body)
+      (slack-message-put-text-property raw-body))))
+
+
+(defun slack-format-reactions (reactions team)
+  (concat "\n"
+          (mapconcat #'(lambda (r) (slack-reaction-to-string r team))
+                     reactions
+                     " ")))
+
+(defmethod slack-message-reaction-to-string ((m slack-message) team)
+  (let ((reactions (slack-message-reactions m)))
+    (when reactions
+      (slack-format-reactions reactions team))))
+
+(defmethod slack-message-to-string ((m slack-message) team)
+  (let ((text (if (slot-boundp m 'text) (oref m text))))
+    (let* ((header (slack-message-header-to-string m team))
+           (attachment-body (slack-message-attachment-body m team))
+           (body (slack-message-body-to-string m team))
+           (files (mapconcat #'(lambda (file)
+                                 (slack-message-to-string file
+                                                          (slack-ts m)
+                                                          team))
+                             (oref m files) "\n"))
+           (reactions (slack-message-reaction-to-string m team))
+           (thread (slack-thread-to-string m team)))
+      (slack-format-message header body
+                            (if (< 0 (length files))
+                                (format "\n%s" files)
+                              files)
+                            attachment-body reactions thread))))
+
+(defmethod slack-message-body ((m slack-message) team)
+  (with-slots (text) m
+    (slack-message-unescape-string text team)))
+
+(defmethod slack-message-body ((m slack-reply-broadcast-message) team)
+  (format "Replied to a thread: \n%s"
+          (slack-message-unescape-string (oref m text) team)))
+
+(defmethod slack-message-body-to-string ((m slack-file-comment-message) team)
+  (with-slots (file comment deleted-at) m
+    (let ((commented-user (slack-user-name (plist-get comment :user)
+                                           team))
+          (comment-body (plist-get comment :comment))
+          (file-id (plist-get file :id))
+          (file-user (slack-user-name (plist-get file :user)
+                                      team))
+          (file-title (plist-get file :title))
+          (text-propertize (or
+                            (and deleted-at
+                                 #'slack-message-put-deleted-property)
+                            #'slack-message-put-text-property)))
+      (format "%s %s: %s"
+              (funcall text-propertize
+                       (format "@%s commented on @%s's file"
+                               commented-user
+                               file-user))
+              (slack-file-link-info file-id file-title)
+              (funcall text-propertize
+                       comment-body)))))
+
+(defmethod slack-team-display-image-inlinep ((_m slack-message) team)
+  (slack-team-display-attachment-image-inlinep team))
+
+(defmethod slack-message-attachment-body ((m slack-message) team)
+  (with-slots (attachments) m
+    (let ((body (mapconcat #'(lambda (attachment)
+                               (slack-message-to-string attachment team))
+                           attachments "\n\t-\n")))
+      (if (< 0 (length body))
+          (slack-message-unescape-string (format "\n%s" body) team)))))
+
+(defmethod slack-message-to-alert ((m slack-message) team)
+  (with-slots (text attachments files) m
+    (let ((alert-text
+           (cond
+            ((and text (< 0 (length text))) text)
+            ((and attachments (< 0 (length attachments)))
+             (mapconcat #'slack-attachment-to-alert attachments " "))
+            ((and files (< 0 (length files)))
+             (mapconcat #'(lambda (file) (oref file title)) files " ")))))
+      (slack-message-unescape-string alert-text team))))
+
+(defun slack-message-unescape-string (text team)
+  (when text
+    (let* ((and-unescpaed
+            (replace-regexp-in-string "&amp;" "&" text))
+           (lt-unescaped
+            (replace-regexp-in-string "&lt;" "<" and-unescpaed))
+           (gt-unescaped
+            (replace-regexp-in-string "&gt;" ">" lt-unescaped)))
+      (slack-message-unescape-date-format
+       (slack-message-unescape-command
+        (slack-message-unescape-user-id
+         (slack-message-unescape-channel gt-unescaped team)
+         team))))))
+
+(defun slack-message-unescape-user-id (text team)
+  (let ((user-regexp "<@\\(U.*?\\)>"))
+    (cl-labels ((unescape-user-id
+                 (text)
+                 (concat "@" (or
+                              (slack-message-replace-user-name text)
+                              (let ((user (slack-user--find (match-string 1 text) team)))
+                                (plist-get user :name))
+                              (match-string 1 text)))))
+      (replace-regexp-in-string user-regexp
+                                #'unescape-user-id
+                                text t t))))
+
+(defun slack-message-replace-user-name (text)
+  (let ((user-name-regexp "<@U.*?|\\(.*?\\)>"))
+    (cl-labels ((replace-user-id-with-name (text)
+                                           (match-string 1 text)))
+      (if (string-match-p user-name-regexp text)
+          (replace-regexp-in-string user-name-regexp
+                                    #'replace-user-id-with-name
+                                    text nil t)))))
+
+(defun slack-message-unescape-date-format (text)
+  (let ((date-regexp "<!date^\\([[:digit:]]*\\)^\\(.*?\\)\\(\\^.*\\)?|\\(.*\\)>")
+        (time-format-regexp "{\\(.*?\\)}"))
+    (cl-labels
+        ((unescape-date-string
+          (text)
+          (let* ((time (match-string 1 text))
+                 (format-string (match-string 2 text))
+                 (link (match-string 3 text))
+                 (fallback (match-string 4 text)))
+            (replace-regexp-in-string time-format-regexp
+                                      #'(lambda (text)
+                                          (unescape-datetime-format time
+                                                                    link
+                                                                    text
+                                                                    fallback))
+                                      format-string)))
+         (unescape-datetime-format
+          (unix-time link text fallback)
+          (let* ((match (match-string 1 text))
+                 (template (cl-assoc (intern match) slack-date-formats)))
+            (if template
+                (slack-linkfy
+                 (format-time-string (cdr template)
+                                     (float-time (string-to-number unix-time)))
+                 (and link (substring link 1 (length link))))
+              fallback))))
+      (replace-regexp-in-string date-regexp
+                                #'unescape-date-string
+                                text nil t))))
+
+(defun slack-message-unescape-command (text)
+  (let ((command-regexp "<!\\(.*?\\)>"))
+    (cl-labels ((unescape-command
+                 (text)
+                 (let ((match (match-string 1 text)))
+                   (if (string-prefix-p "date" match)
+                       (format "<!%s>" match)
+                     (concat "@" match)))))
+      (replace-regexp-in-string command-regexp
+                                #'unescape-command
+                                text nil t))))
+
+(defun slack-message-unescape-channel (text team)
+  (let ((channel-regexp "<#\\(C.*?\\)\\(|.*?\\)?>"))
+    (cl-labels ((unescape-channel
+                 (text)
+                 (let ((name (match-string 2 text))
+                       (id (match-string 1 text)))
+                   (concat "#" (or (and name (substring name 1))
+                                   (slack-if-let* ((room (slack-room-find id team)))
+                                       (oref room name)
+                                     id))))))
+      (replace-regexp-in-string channel-regexp
+                                #'unescape-channel
+                                text t))))
+
+(provide 'slack-message-formatter)
+;;; slack-message-formatter.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-formatter.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-formatter.elc
new file mode 100644
index 000000000000..e72f84b1cbe3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-formatter.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-notification.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-notification.el
new file mode 100644
index 000000000000..35d8f6c67165
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-notification.el
@@ -0,0 +1,145 @@
+;;; slack-message-notification.el --- message notification  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-message)
+(require 'slack-message-formatter)
+(require 'slack-buffer)
+(require 'slack-im)
+(require 'alert)
+
+(defvar alert-default-style)
+
+(defcustom slack-message-custom-notifier nil
+  "Custom notification function.\ntake 3 Arguments.\n(lambda (MESSAGE ROOM TEAM) ...)."
+  :group 'slack)
+
+(defcustom slack-message-im-notification-title-format-function
+  #'(lambda (team-name room-name thread-messagep)
+      (format "%s - %s" team-name (if thread-messagep
+                                      (format "Thread in %s" room-name)
+                                    room-name)))
+  "Function to format notification title for IM message.\ntake 3 Arguments.\n(lambda (TEAM-NAME ROOM-NAME THREAD-MESSAGEP) ...)."
+  :type 'function
+  :group 'slack)
+
+(defcustom slack-message-notification-title-format-function
+  #'(lambda (team-name room-name thread-messagep)
+      (format "%s - %s" team-name (if thread-messagep
+                                      (format "Thread in #%s" room-name)
+                                    (format "#%s" room-name))))
+  "Function to format notification title for non-IM message.\ntake 3 Arguments.\n(lambda (TEAM-NAME ROOM-NAME THREAD-MESSAGEP) ...)."
+  :type 'function
+  :group 'slack)
+
+(defcustom slack-alert-icon nil
+  "String passed as the :icon argument to `alert'."
+  :type '(choice file (const :tag "Stock alert icon" nil))
+  :group 'slack)
+
+(defvar slack-modeline nil)
+
+(defcustom slack-modeline-formatter #'slack-default-modeline-formatter
+  "Format modeline with Arg '((team-name . unread-count))."
+  :group 'slack)
+
+(defun slack-message-notify (message room team)
+  (if slack-message-custom-notifier
+      (funcall slack-message-custom-notifier message room team)
+    (slack-message-notify-alert message room team)))
+
+(defun slack-message-notify-alert (message room team)
+  (if (and (not (slack-message-minep message team))
+           (or (slack-im-p room)
+               (and (slack-group-p room) (slack-mpim-p room))
+               (slack-room-subscribedp room team)
+               (string-match (format "@%s" (plist-get (oref team self) :name))
+                             (or (slack-message-body message team) ""))))
+      (let ((team-name (oref team name))
+            (room-name (slack-room-name room team))
+            (text (with-temp-buffer
+                    (goto-char (point-min))
+                    (insert (slack-message-to-alert message team))
+                    (slack-buffer-buttonize-link)
+                    (buffer-substring-no-properties (point-min)
+                                                    (point-max))))
+            (user-name (slack-message-sender-name message team)))
+        (if (and (eq alert-default-style 'notifier)
+                 (slack-im-p room)
+                 (or (eq (aref text 0) ?\[)
+                     (eq (aref text 0) ?\{)
+                     (eq (aref text 0) ?\<)
+                     (eq (aref text 0) ?\()))
+            (setq text (concat "\\" text)))
+        (alert (if (slack-im-p room) text (format "%s: %s" user-name text))
+               :icon slack-alert-icon
+               :title (if (slack-im-p room)
+                          (funcall slack-message-im-notification-title-format-function
+                                   team-name room-name (slack-thread-messagep message))
+                        (funcall slack-message-notification-title-format-function
+                                 team-name room-name (slack-thread-messagep message)))
+               :category 'slack))))
+
+(defmethod slack-message-sender-equalp ((_m slack-message) _sender-id)
+  nil)
+
+(defmethod slack-message-minep ((m slack-message) team)
+  (if team
+      (with-slots (self-id) team
+        (slack-message-sender-equalp m self-id))
+    (slack-message-sender-equalp m (oref team self-id))))
+
+(defun slack-default-modeline-formatter (alist)
+  "Arg is alist of '((team-name . unread-count))"
+  (if (= 1 (length alist))
+      (format "[ %s: %s ]" (caar alist) (cdar alist))
+    (mapconcat #'(lambda (e) (format "[ %s: %s ]" (car e) (cdr e)))
+               alist " ")))
+
+(defun slack-enable-modeline ()
+  (add-to-list 'global-mode-string '(:eval slack-modeline) t))
+
+(defun slack-update-modeline ()
+  (let ((teams (cl-remove-if-not #'slack-team-modeline-enabledp slack-teams)))
+    (when (< 0 (length teams))
+      (setq slack-modeline
+            (funcall slack-modeline-formatter
+                     (mapcar #'(lambda (e) (cons (or (oref e modeline-name) (slack-team-name e))
+                                                 (slack-team-get-unread-messages e)))
+                             teams)))
+      (force-mode-line-update))))
+
+(defun slack-message-test-notification ()
+  "Debug notification.
+Execute this function when cursor is on some message."
+  (interactive)
+  (let ((ts (slack-get-ts)))
+    (with-slots (room team) slack-current-buffer
+      (let ((message (slack-room-find-message room ts)))
+        (slack-message-notify message room team)))))
+
+(provide 'slack-message-notification)
+;;; slack-message-notification.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-notification.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-notification.elc
new file mode 100644
index 000000000000..8bd41165ab67
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-notification.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-reaction.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-reaction.el
new file mode 100644
index 000000000000..5014723c7cc3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-reaction.el
@@ -0,0 +1,146 @@
+;;; slack-message-reaction.el --- adding, removing reaction from message  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'slack-util)
+(require 'slack-message)
+(require 'slack-reaction)
+(require 'slack-room)
+(require 'slack-file)
+(require 'slack-request)
+
+(defconst slack-message-reaction-add-url "https://slack.com/api/reactions.add")
+(defconst slack-message-reaction-remove-url "https://slack.com/api/reactions.remove")
+(defcustom slack-invalid-emojis '("^:flag_" "tone[[:digit:]]:$" "-" "^[^:].*[^:]$" "\\Ca")
+  "Invalid emoji regex. Slack server treated some emojis as Invalid."
+  :group 'slack)
+
+(defun slack-get-file-id ()
+  (get-text-property 0 'file-id (thing-at-point 'line)))
+
+(defun slack-file-add-reaction (file-id reaction team)
+  (slack-message-reaction-add-request (list (cons "name" reaction)
+                                            (cons "file" file-id))
+                                      team))
+
+(defun slack-message--add-reaction (buf reaction)
+  (slack-buffer-add-reaction-to-message buf reaction (slack-get-ts)))
+
+(defun slack-message-add-reaction ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer)
+                  (reaction (slack-message-reaction-input)))
+      (slack-message--add-reaction buf reaction)))
+
+(defun slack-file-remove-reaction (file-id team)
+  (slack-with-file file-id team
+    (let ((reaction (slack-message-reaction-select
+                     (slack-message-reactions file))))
+      (slack-message-reaction-remove-request
+       (list (cons "file" file-id)
+             (cons "name" reaction))
+       team))))
+
+(defun slack-message-remove-reaction ()
+  (interactive)
+  (slack-buffer-remove-reaction-from-message slack-current-buffer
+                                             (slack-get-ts)))
+
+(defun slack-message-show-reaction-users ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (with-slots (team) buf
+        (slack-if-let* ((reaction (ignore-errors
+                                    (get-text-property (point)
+                                                       'reaction))))
+            (let ((user-names (slack-reaction-user-names reaction
+                                                         team)))
+              (message "reacted users: %s"
+                       (mapconcat #'identity user-names ", ")))
+          (message "Can't get reaction:")))))
+
+(defun slack-message-reaction-select (reactions)
+  (let ((list (mapcar #'(lambda (r)
+                          (cons (oref r name)
+                                (oref r name)))
+                      reactions)))
+    (slack-select-from-list
+        (list "Select Reaction: ")
+        selected)))
+
+(defun slack-select-emoji ()
+  (if (fboundp 'emojify-completing-read)
+      (emojify-completing-read "Select Emoji: ")
+    (read-from-minibuffer "Emoji: ")))
+
+(defun slack-message-reaction-input ()
+  (let ((reaction (slack-select-emoji)))
+    (if (and (string-prefix-p ":" reaction)
+             (string-suffix-p ":" reaction))
+        (substring reaction 1 -1)
+      reaction)))
+
+(defun slack-message-reaction-add (reaction ts room team)
+  (slack-if-let* ((message (slack-room-find-message room ts)))
+      (let ((params (list (cons "channel" (oref room id))
+                          (slack-message-get-param-for-reaction message)
+                          (cons "name" reaction))))
+        (slack-message-reaction-add-request params team))))
+
+(defun slack-message-reaction-add-request (params team)
+  (cl-labels ((on-reaction-add
+               (&key data &allow-other-keys)
+               (slack-request-handle-error
+                (data "slack-message-reaction-add-request"))))
+    (slack-request
+     (slack-request-create
+      slack-message-reaction-add-url
+      team
+      :type "POST"
+      :params params
+      :success #'on-reaction-add))))
+
+(defun slack-message-reaction-remove (reaction ts room team)
+  (slack-if-let* ((message (slack-room-find-message room ts)))
+      (let ((params (list (cons "channel" (oref room id))
+                          (slack-message-get-param-for-reaction message)
+                          (cons "name" reaction))))
+        (slack-message-reaction-remove-request params team))))
+
+(defun slack-message-reaction-remove-request (params team)
+  (cl-labels ((on-reaction-remove
+               (&key data &allow-other-keys)
+               (slack-request-handle-error
+                (data "slack-message-reaction-remove-request"))))
+    (slack-request
+     (slack-request-create
+      slack-message-reaction-remove-url
+      team
+      :type "POST"
+      :params params
+      :success #'on-reaction-remove))))
+
+(provide 'slack-message-reaction)
+;;; slack-message-reaction.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-reaction.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-reaction.elc
new file mode 100644
index 000000000000..a023e9c24731
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-reaction.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-sender.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-sender.el
new file mode 100644
index 000000000000..dbd2c1ad53e0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-sender.el
@@ -0,0 +1,177 @@
+;;; slack-message-sender.el --- slack message concern message sending  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'json)
+(require 'slack-util)
+(require 'slack-websocket)
+(require 'slack-room)
+(require 'slack-im)
+(require 'slack-group)
+(require 'slack-message)
+(require 'slack-channel)
+(require 'slack-slash-commands)
+
+(defvar slack-message-minibuffer-local-map nil)
+(defvar slack-buffer-function)
+
+(defun slack-message-send ()
+  (interactive)
+  (slack-message--send (slack-message-read-from-minibuffer)))
+
+(defun slack-message-inc-id (team)
+  (with-slots (message-id) team
+    (if (eq message-id (1- most-positive-fixnum))
+        (setq message-id 1)
+      (cl-incf message-id))))
+
+(defun slack-escape-message (message)
+  "Escape '<,' '>' & '&' in MESSAGE."
+  (replace-regexp-in-string
+   ">" "&gt;"
+   (replace-regexp-in-string
+    "<" "&lt;"
+    (replace-regexp-in-string "&" "&amp;" message))))
+
+(defun slack-link-users (message team)
+  "Add links to all references to valid users in MESSAGE."
+  (replace-regexp-in-string
+   "@\\<\\([A-Za-z0-9._\-]+\\)\\>"
+   #'(lambda (text)
+       (let* ((username (match-string 1 text))
+              (id (slack-user-get-id username team)))
+         (if id
+             (format "<@%s|%s>" id username)
+           (cond
+            ((string= username "here") "<!here|here>")
+            ((cl-find username '("channel" "group") :test #'string=) "<!channel>")
+            ((string= username "everyone") "<!everyone>")
+            (t text)))))
+   message t))
+
+(defun slack-link-channels (message team)
+  "Add links to all references to valid channels in MESSAGE."
+  (let ((channel-ids
+         (mapcar #'(lambda (x)
+                     (let ((channel (cdr x)))
+                       (cons (slack-room-name channel team)
+                             (slot-value channel 'id))))
+                 (slack-channel-names team))))
+    (replace-regexp-in-string
+     "#\\<\\([A-Za-z0-9_\-]+\\)\\>"
+     #'(lambda (text)
+         (let* ((channel (match-string 1 text))
+                (id (cdr (assoc channel channel-ids))))
+           (if id
+               (format "<#%s|%s>" id channel)
+             text)))
+     message t)))
+
+(defun slack-message-prepare-links (message team)
+  (slack-link-channels (slack-link-users message team) team))
+
+(defun slack-message--send (message)
+  (slack-if-let* ((buf slack-current-buffer)
+                  (team (oref buf team))
+                  (room (oref buf room)))
+      (if (string-prefix-p "/" message)
+          (slack-if-let* ((command-and-arg (slack-slash-commands-parse message team)))
+              (slack-command-run (car command-and-arg)
+                                 team
+                                 (oref room id)
+                                 :text (cdr command-and-arg))
+            (error "Unknown slash command: %s"
+                   (car (split-string message))))
+        (slack-buffer-send-message buf message))))
+
+(defun slack-message-send-internal (message channel-id team)
+  (slack-message-inc-id team)
+  (with-slots (message-id sent-message self-id) team
+    (let* ((m (list :id message-id
+                    :channel channel-id
+                    :type "message"
+                    :user self-id
+                    :text (slack-message-prepare-links
+                           (slack-escape-message message)
+                           team)))
+           (obj (slack-message-create m team)))
+      (slack-ws-send m team)
+      (puthash message-id obj sent-message))))
+
+(defun slack-message-read-room (team)
+  (let* ((list (slack-message-room-list team))
+         (choices (mapcar #'car list))
+         (room-name (slack-message-read-room-list "Select Room: " choices))
+         (room (cdr (cl-assoc room-name list :test #'string=))))
+    room))
+
+(defun slack-message-read-room-list (prompt choices)
+  (let ((completion-ignore-case t))
+    (funcall slack-completing-read-function (format "%s" prompt)
+             choices nil t nil nil choices)))
+
+(defun slack-message-room-list (team)
+  (append (slack-group-names team)
+          (slack-im-names team)
+          (slack-channel-names team)))
+
+(defun slack-message-read-from-minibuffer ()
+  (let ((prompt "Message: "))
+    (slack-message-setup-minibuffer-keymap)
+    (read-from-minibuffer
+     prompt
+     nil
+     slack-message-minibuffer-local-map)))
+
+(defun slack-message-setup-minibuffer-keymap ()
+  (unless slack-message-minibuffer-local-map
+    (setq slack-message-minibuffer-local-map
+          (let ((map (make-sparse-keymap)))
+            (define-key map (kbd "RET") 'newline)
+            (set-keymap-parent map minibuffer-local-map)
+            map))))
+
+(defun slack-message-embed-channel ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (with-slots (team) buf
+        (slack-select-from-list
+            ((slack-channel-names team) "Select Channel: ")
+            (insert (concat "#" (slack-room-name selected team)))))))
+
+(defun slack-message-embed-mention ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (with-slots (team) buf
+        (let* ((pre-defined (list (list "here" :name "here")
+                                  (list "channel" :name "channel")))
+               (alist (append pre-defined (slack-user-names team))))
+          (slack-select-from-list
+              (alist "Select User: ")
+              (insert (concat "@" (plist-get selected :name))))))))
+
+(provide 'slack-message-sender)
+;;; slack-message-sender.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-sender.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-sender.elc
new file mode 100644
index 000000000000..1c75c5cf5e9f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-sender.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-share-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-share-buffer.el
new file mode 100644
index 000000000000..2e999b29d3ac
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-share-buffer.el
@@ -0,0 +1,75 @@
+;;; slack-message-share-buffer.el ---                -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-room-buffer)
+
+(define-derived-mode slack-message-share-buffer-mode
+  slack-message-compose-buffer-mode
+  "Slack Share Message")
+
+(defclass slack-message-share-buffer (slack-message-compose-buffer)
+  ((ts :initarg :ts :type string)
+   (room :initarg :room :type slack-room)))
+
+(defun slack-create-message-share-buffer (room team ts)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-message-share-buffer
+                                    room ts team)))
+      buf
+    (slack-message-share-buffer :room room :team team :ts ts)))
+
+(defmethod slack-buffer-find :static ((class slack-message-share-buffer) room ts team)
+  (slack-buffer-find-4 class room ts team))
+
+(defmethod slack-buffer-name :static ((class slack-message-share-buffer) room ts team)
+  (format "*Slack - %s : %s  Share Message - %s"
+          (oref team name)
+          (slack-room-name room team)
+          ts))
+
+(defmethod slack-buffer-name ((this slack-message-share-buffer))
+  (with-slots (room ts team) this
+    (slack-buffer-name 'slack-message-share-buffer
+                       room ts team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-message-share-buffer))
+  (let* ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-message-share-buffer-mode)
+      (slack-buffer-set-current-buffer this))
+    (with-slots (room ts team) this
+      (slack-buffer-push-new-4 'slack-message-share-buffer
+                               room ts team))
+    buf))
+
+(defmethod slack-buffer-send-message ((this slack-message-share-buffer) message)
+  (with-slots (room team ts) this
+    (slack-message-share--send team room ts message)
+    (call-next-method)))
+
+(provide 'slack-message-share-buffer)
+;;; slack-message-share-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-share-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-share-buffer.elc
new file mode 100644
index 000000000000..c3e433223e89
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message-share-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message.el
new file mode 100644
index 000000000000..11360f47c44b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message.el
@@ -0,0 +1,454 @@
+;;; slack-message.el --- slack-message                -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'subr-x)
+(require 'slack-util)
+(require 'slack-reaction)
+(require 'slack-request)
+(require 'slack-attachment)
+
+(defcustom slack-message-custom-delete-notifier nil
+  "Custom notification function for deleted message.\ntake 3 Arguments.\n(lambda (MESSAGE ROOM TEAM) ...)."
+  :group 'slack)
+
+(defconst slack-message-pins-add-url "https://slack.com/api/pins.add")
+(defconst slack-message-pins-remove-url "https://slack.com/api/pins.remove")
+(defconst slack-message-stars-add-url "https://slack.com/api/stars.add")
+(defconst slack-message-stars-remove-url "https://slack.com/api/stars.remove")
+
+(defclass slack-message ()
+  ((type :initarg :type :type string)
+   (subtype :initarg :subtype)
+   (channel :initarg :channel :initform nil)
+   (ts :initarg :ts :type string :initform "")
+   (text :initarg :text :type (or null string) :initform nil)
+   (item-type :initarg :item_type)
+   (attachments :initarg :attachments :type (or null list) :initform nil)
+   (reactions :initarg :reactions :type (or null list))
+   (is-starred :initarg :is_starred :type boolean :initform nil)
+   (pinned-to :initarg :pinned_to :type (or null list))
+   (deleted-at :initarg :deleted-at :initform nil)
+   (thread :initarg :thread :initform nil)
+   (thread-ts :initarg :thread_ts :initform nil)
+   (hide :initarg :hide :initform nil)
+   (files :initarg :files :initform '())
+   (edited :initarg :edited :initform nil)
+   (is-ephemeral :initarg :is_ephemeral :initform nil)))
+
+(defclass slack-message-edited ()
+  ((user :initarg :user :type string)
+   (ts :initarg :ts :type string)))
+
+(defclass slack-reply (slack-message)
+  ((user :initarg :user :initform nil)
+   (reply-to :initarg :reply_to :type integer)
+   (id :initarg :id :type integer)))
+
+(defclass slack-user-message (slack-message)
+  ((user :initarg :user :type string)
+   (id :initarg :id)
+   (inviter :initarg :inviter)))
+
+(defclass slack-reply-broadcast-message (slack-user-message)
+  ((broadcast-thread-ts :initarg :broadcast_thread_ts :initform nil)))
+
+(defclass slack-bot-message (slack-message)
+  ((bot-id :initarg :bot_id :type string)
+   (username :initarg :username :type string :initform "")
+   (icons :initarg :icons)))
+
+(defclass slack-file-comment-message (slack-message)
+  ((file :initarg :file :initform nil)
+   (comment :initarg :comment :initform nil)))
+
+(defmethod slack-message-sender-name ((m slack-file-comment-message) team)
+  (with-slots (comment) m
+    (slack-user-name (plist-get comment :user) team)))
+
+(defmethod slack-message-sender-id ((m slack-file-comment-message))
+  (with-slots (comment) m
+    (plist-get comment :user)))
+
+(defgeneric slack-message-sender-name  (slack-message team))
+(defgeneric slack-message-to-string (slack-message))
+(defgeneric slack-message-to-alert (slack-message))
+(defmethod slack-message-bot-id ((_this slack-message)) nil)
+
+(defgeneric slack-room-buffer-name (room team))
+
+(defun slack-room-find (id team)
+  (if (and id team)
+      (cl-labels ((find-room (room)
+                             (string= id (oref room id))))
+        (cond
+         ((string-prefix-p "F" id) (slack-file-room-obj team))
+         ((string-prefix-p "C" id) (cl-find-if #'find-room
+                                               (oref team channels)))
+         ((string-prefix-p "G" id) (cl-find-if #'find-room
+                                               (oref team groups)))
+         ((string-prefix-p "D" id) (cl-find-if #'find-room
+                                               (oref team ims)))
+         ((string-prefix-p "Q" id) (cl-find-if #'find-room
+                                               (oref team search-results)))))))
+
+(defun slack-reaction-create (payload)
+  (apply #'slack-reaction "reaction"
+         (slack-collect-slots 'slack-reaction payload)))
+
+(defmethod slack-message-set-attachments ((m slack-message) payload)
+  (let ((attachments (append (plist-get payload :attachments) nil)))
+    (if (< 0 (length attachments))
+        (oset m attachments
+              (mapcar #'slack-attachment-create attachments))))
+  m)
+
+(defmethod slack-message-set-file ((m slack-message) payload team)
+  (let ((files (mapcar #'(lambda (file) (slack-file-create file))
+                       (plist-get payload :files))))
+    (oset m files files)
+    m))
+
+(defmethod slack-message-set-thread ((m slack-message) team payload)
+  (when (slack-message-thread-parentp m)
+    (oset m thread (slack-thread-create m team payload))))
+
+(defun slack-reply-broadcast-message-create (payload)
+  (let ((parent (cl-first (plist-get payload :attachments))))
+    (plist-put payload :broadcast_thread_ts (plist-get parent :ts))
+    (apply #'slack-reply-broadcast-message "reply-broadcast"
+           (slack-collect-slots 'slack-reply-broadcast-message payload))))
+
+(cl-defun slack-message-create (payload team &key room)
+  (when payload
+    (plist-put payload :reactions (append (plist-get payload :reactions) nil))
+    (plist-put payload :attachments (append (plist-get payload :attachments) nil))
+    (plist-put payload :pinned_to (append (plist-get payload :pinned_to) nil))
+    (if room
+        (plist-put payload :channel (oref room id)))
+    (cl-labels
+        ((create-message
+          (payload)
+          (let ((subtype (plist-get payload :subtype)))
+            (cond
+             ((plist-member payload :reply_to)
+              (apply #'slack-reply "reply"
+                     (slack-collect-slots 'slack-reply payload)))
+             ((or (and subtype (or (string-equal "reply_broadcast" subtype)
+                                   (string= "thread_broadcast" subtype)))
+                  (plist-get payload :reply_broadcast))
+              (slack-reply-broadcast-message-create payload))
+             ((and (plist-member payload :user) (plist-get payload :user))
+              (apply #'slack-user-message "user-msg"
+                     (slack-collect-slots 'slack-user-message payload)))
+             ((and subtype (string= "bot_message" subtype))
+              (apply #'slack-bot-message "bot-msg"
+                     (slack-collect-slots 'slack-bot-message payload)))
+             ((and subtype (string= "file_comment" subtype))
+              (apply #'slack-file-comment-message "file_comment"
+                     (slack-collect-slots 'slack-file-comment-message payload)))
+             (t (progn
+                  (slack-log (format "Unknown Message Type: %s" payload)
+                             team :level 'warn)
+                  (apply #'slack-message "unknown message"
+                         (slack-collect-slots 'slack-message payload))))))))
+
+      (let ((message (create-message payload)))
+        (when message
+          (slack-message-set-edited message payload)
+          (slack-message-set-attachments message payload)
+          (oset message reactions
+                (mapcar #'slack-reaction-create (plist-get payload :reactions)))
+          (slack-message-set-file message payload team)
+          (slack-message-set-thread message team payload)
+          message)))))
+
+(defmethod slack-message-set-edited ((this slack-message) payload)
+  (if (plist-get payload :edited)
+      (oset this edited (apply #'make-instance slack-message-edited
+                               (slack-collect-slots 'slack-message-edited
+                                                    (plist-get payload :edited))))))
+
+(defmethod slack-message-edited-at ((this slack-message))
+  (with-slots (edited) this
+    (when edited
+      (oref edited ts))))
+
+(defmethod slack-message-equal ((m slack-message) n)
+  (string= (slack-ts m) (slack-ts n)))
+
+(defmethod slack-message-get-thread ((parent slack-message) team)
+  (let ((thread (oref parent thread)))
+    (unless thread
+      (oset parent thread (slack-thread-create parent team)))
+    (oref parent thread)))
+
+(defmethod slack-message-sender-name ((m slack-message) team)
+  (slack-user-name (oref m user) team))
+
+(defmethod slack-message-sender-id ((m slack-message))
+  (oref m user))
+
+(defun slack-message-pins-add ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-pins-add buf (slack-get-ts))))
+
+(defun slack-message-pins-remove ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-pins-remove buf (slack-get-ts))))
+
+(defun slack-message-pins-request (url room team ts)
+  (cl-labels ((on-pins-add
+               (&key data &allow-other-keys)
+               (slack-request-handle-error
+                (data "slack-message-pins-request"))))
+    (slack-request
+     (slack-request-create
+      url
+      team
+      :params (list (cons "channel" (oref room id))
+                    (cons "timestamp" ts))
+      :success #'on-pins-add
+      ))))
+
+(defmethod slack-ts ((this slack-message))
+  (oref this ts))
+
+(defun slack-ts-to-time (ts)
+  (seconds-to-time (string-to-number ts)))
+
+(defun slack-message-time-stamp (message)
+  (slack-ts-to-time (slack-ts message)))
+
+(defmethod slack-user-find ((m slack-message) team)
+  (slack-user--find (slack-message-sender-id m) team))
+
+(defun slack-message-copy-link ()
+  (interactive)
+  (slack-buffer-copy-link slack-current-buffer (slack-get-ts)))
+
+(defmethod slack-message-star-added ((m slack-message))
+  (oset m is-starred t))
+
+(defmethod slack-message-star-removed ((m slack-message))
+  (oset m is-starred nil))
+
+(defun slack-message-star-api-request (url params team)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data url))))
+    (slack-request
+     (slack-request-create
+      url
+      team
+      :params params
+      :success #'on-success))))
+
+(defun slack-message-remove-star ()
+  (interactive)
+  (slack-buffer-remove-star slack-current-buffer (slack-get-ts)))
+
+(defun slack-message-add-star ()
+  (interactive)
+  (slack-buffer-add-star slack-current-buffer (slack-get-ts)))
+
+(defmethod slack-message-star-api-params ((m slack-message))
+  (cons "timestamp" (slack-ts m)))
+
+(defmethod slack-reaction-delete ((this slack-message) reaction)
+  (with-slots (reactions) this
+    (setq reactions (slack-reaction--delete reactions reaction))))
+
+(defmethod slack-reaction-push ((this slack-message) reaction)
+  (push reaction (oref this reactions)))
+
+(defmethod slack-reaction-find ((m slack-message) reaction)
+  (slack-reaction--find (oref m reactions) reaction))
+
+(defmethod slack-message-reactions ((this slack-message))
+  (oref this reactions))
+
+(defmethod slack-message-get-param-for-reaction ((m slack-message))
+  (cons "timestamp" (slack-ts m)))
+
+(defmethod slack-message-append-reaction ((m slack-message) reaction &optional _type _file-id)
+  (slack-if-let* ((old-reaction (slack-reaction-find m reaction)))
+      (slack-reaction-join old-reaction reaction)
+    (slack-reaction-push m reaction)))
+
+(defmethod slack-message-pop-reaction ((m slack-message) reaction &optional _type _file-id)
+  (slack-message--pop-reaction m reaction))
+
+(defun slack-message--pop-reaction (message reaction)
+  (let* ((old-reaction (slack-reaction-find message reaction))
+         (decl-p (< 1 (oref old-reaction count))))
+    (if decl-p
+        (with-slots (count users) old-reaction
+          (cl-decf count)
+          (setq users (cl-remove-if
+                       #'(lambda (old-user)
+                           (cl-find old-user
+                                    (oref reaction users)
+                                    :test #'string=))
+                       users)))
+      (slack-reaction-delete message reaction))))
+
+(defmethod slack-message-get-text ((m slack-message))
+  (oref m text))
+
+(defmethod slack-thread-message-update-buffer ((message slack-message)
+                                               room team replace)
+  (slack-if-let* ((parent (slack-room-find-thread-parent room message)))
+      (progn
+        (slack-room-update-buffer room team parent t)
+        (if (slack-reply-broadcast-message-p message)
+            (slack-room-update-buffer room team message replace))
+        (slack-if-let* ((thread (slack-message-get-thread parent team)))
+            (progn
+              (slack-if-let* ((buf (slack-buffer-find 'slack-thread-message-buffer
+                                                      room
+                                                      (oref thread thread-ts)
+                                                      team)))
+                  (slack-buffer-update buf message :replace replace)))))))
+
+(defmethod slack-message-update ((message slack-message) team &optional replace no-notify)
+  (slack-if-let*
+      ((room (slack-room-find (oref message channel) team))
+       (ts (slack-ts message))
+       (no-same-message (if replace t
+                          (not (slack-room-find-message room ts)))))
+
+      (progn
+        (slack-room-push-message room message)
+        (slack-room-update-latest room message)
+        (if (slack-thread-message-p message)
+            (slack-thread-message-update-buffer message room team replace)
+          (slack-room-update-buffer room team message replace)
+          (slack-room-inc-unread-count room))
+
+        (unless no-notify
+          (slack-message-notify message room team))
+        (slack-update-modeline))))
+
+(defun slack-message-delete ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-delete-message buf (slack-get-ts))))
+
+(defmethod slack-message-deleted ((message slack-message) room team)
+  (if (slack-thread-message-p message)
+      (slack-if-let* ((parent (slack-room-find-thread-parent room message))
+                      (thread (slack-message-get-thread parent team)))
+          (progn
+            (slack-thread-delete-message thread message)
+            (slack-if-let* ((buffer (slack-buffer-find 'slack-thread-message-buffer
+                                                       room
+                                                       (oref thread thread-ts)
+                                                       team)))
+                (slack-buffer-message-delete buffer (slack-ts message)))
+            (slack-message-update parent team t)))
+    (slack-if-let* ((buf (slack-buffer-find 'slack-message-buffer
+                                            room
+                                            team)))
+        (slack-buffer-message-delete buf (slack-ts message))))
+
+  (if slack-message-custom-delete-notifier
+      (funcall slack-message-custom-delete-notifier message room team)
+    (alert "message deleted"
+           :icon slack-alert-icon
+           :title (format "\\[%s] from %s"
+                          (slack-room-display-name room team)
+                          (slack-message-sender-name message team))
+           :category 'slack)))
+
+(defmethod slack-message-changed--copy ((this slack-message) other)
+  (let ((changed nil))
+    (with-slots (text attachments edited) this
+      (unless (string= text (oref other text))
+        (setq text (oref other text))
+        (setq changed t))
+      (setq attachments (oref other attachments))
+      (setq edited (oref other edited)))
+    changed))
+
+(defmethod slack-thread-message-p ((this slack-message))
+  (and (oref this thread-ts)
+       (not (string= (slack-ts this) (oref this thread-ts)))))
+
+(defmethod slack-thread-message-p ((this slack-reply-broadcast-message))
+  (call-next-method))
+
+(defmethod slack-message-thread-parentp ((m slack-message))
+  (let* ((thread (oref m thread))
+         (thread-ts (or (and thread (oref thread thread-ts))
+                        (oref m thread-ts))))
+    (and thread-ts (string= (slack-ts m) thread-ts))))
+
+(defun slack-message-update-mark ()
+  "Update Channel's last-read marker to this message."
+  (interactive)
+  (slack-if-let* ((buffer slack-current-buffer))
+      (slack-buffer-update-mark buffer :force t)))
+
+(defmethod slack-message--inspect ((this slack-message) room team)
+  (format "RAW: %s\nROOM: %s\nMESSAGE: %s\nATTACHMENTS: %s - %s\nFILES: %s - %s"
+          (oref this text)
+          (oref room id)
+          (eieio-object-class this)
+          (length (oref this attachments))
+          (mapcar (lambda (e) (format "\n(TITLE: %s\nPRETEXT: %s\nTEXT: %s)"
+                                      (slack-message-unescape-channel
+                                       (oref e title)
+                                       team)
+                                      (oref e pretext)
+                                      (oref e text)))
+                  (oref this attachments))
+          (length (oref this files))
+          (mapcar (lambda (e) (format "(TITLE: %s)"
+                                      (oref e title)))
+                  (oref this files))))
+
+(defmethod slack-message--inspect ((this slack-file-comment-message) room team)
+  (let ((super (call-next-method)))
+    (with-slots (file comment) this
+      (format "%s\nFILE:%s\nCOMMENT:%s"
+              super
+              file comment))))
+
+(defun slack-message-inspect ()
+  (interactive)
+  (slack-if-let* ((ts (slack-get-ts))
+                  (buffer slack-current-buffer))
+      (with-slots (room team) buffer
+        (slack-if-let* ((message (slack-room-find-message room ts))
+                        (text (slack-message--inspect message room team)))
+            (message "%s" text)))))
+
+(provide 'slack-message)
+;;; slack-message.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message.elc
new file mode 100644
index 000000000000..ef0d8a57365e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-message.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-item.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-item.el
new file mode 100644
index 000000000000..dfb9a11a4e4c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-item.el
@@ -0,0 +1,43 @@
+;;; slack-pinned-item.el ---                         -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+
+(defclass slack-pinned-item ()
+  ((message :initarg :message)))
+
+(defun slack-pinned-item-create (message)
+  (slack-pinned-item :message message))
+
+(defmethod slack-ts ((this slack-pinned-item))
+  (slack-ts (oref this message)))
+
+(defmethod slack-message-to-string ((this slack-pinned-item) team)
+  (with-slots (message) this
+    (slack-message-to-string message team)))
+
+(provide 'slack-pinned-item)
+;;; slack-pinned-item.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-item.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-item.elc
new file mode 100644
index 000000000000..af92bb6a9713
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-item.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-items-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-items-buffer.el
new file mode 100644
index 000000000000..536195a1553a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-items-buffer.el
@@ -0,0 +1,102 @@
+;;; slack-pinned-items-buffer.el ---                 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-room-buffer)
+
+(define-derived-mode slack-pinned-items-buffer-mode slack-buffer-mode "Slack Pinned Items")
+
+(defclass slack-pinned-items-buffer (slack-room-buffer)
+  ((items :initarg :items :type list)))
+
+(defmethod slack-buffer-name :static ((class slack-pinned-items-buffer) room team)
+  (format "%s %s" (call-next-method) "Pinned Items"))
+
+(defmethod slack-buffer-name ((this slack-pinned-items-buffer))
+  (with-slots (room team) this
+    (slack-buffer-name 'slack-pinned-items-buffer
+                       room team)))
+
+(defmethod slack-buffer-buffer ((this slack-pinned-items-buffer))
+  (slack-if-let* ((buf (get-buffer (slack-buffer-name this))))
+      (progn
+        (slack-pinned-items-buffer-insert-items this)
+        buf)
+    (slack-buffer-init-buffer this)))
+
+(defmethod slack-pinned-items-buffer-insert-items ((this slack-pinned-items-buffer))
+  (let* ((buf (get-buffer (slack-buffer-name this)))
+         (header-face '(:underline t :weight bold))
+         (buf-header (propertize "Pinned Items\n" 'face header-face)))
+    (with-current-buffer buf
+      (let ((inhibit-read-only t))
+        (delete-region (point-min) lui-output-marker))
+      (let ((lui-time-stamp-position nil))
+        (lui-insert buf-header t))
+      (with-slots (team items) this
+        (if (< 0 (length items))
+            (cl-loop for m in items
+                     do (slack-buffer-insert this m t))
+          (let ((inhibit-read-only t))
+            (insert "No Pinned Items")))))))
+
+(defmethod slack-buffer-init-buffer ((this slack-pinned-items-buffer))
+  (let* ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-pinned-items-buffer-mode)
+      (slack-buffer-set-current-buffer this))
+    (slack-pinned-items-buffer-insert-items this)
+    (with-slots (room team) this
+      (slack-buffer-push-new-3 'slack-pinned-items-buffer room team))
+    buf))
+
+(defun slack-create-pinned-items-buffer (room team items)
+
+  (cl-labels
+      ((create-item
+        (item)
+        (let ((type (plist-get item :type)))
+          (slack-pinned-item-create
+           (cond
+            ((string= type "message")
+             (slack-message-create (plist-get item :message)
+                                   team :room room))
+            ((string= type "file")
+             (or (slack-file-find (plist-get (plist-get item :file) :id) team)
+                 (slack-file-create (plist-get item :file)))))))))
+    (slack-if-let* ((buf (slack-buffer-find 'slack-pinned-items-buffer room team)))
+        (progn
+          (oset buf items (mapcar #'create-item items))
+          buf)
+      (slack-pinned-items-buffer :room room
+                                 :team team
+                                 :items (mapcar #'create-item items)))))
+
+
+
+(provide 'slack-pinned-items-buffer)
+;;; slack-pinned-items-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-items-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-items-buffer.elc
new file mode 100644
index 000000000000..06b81d65fd60
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pinned-items-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pkg.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pkg.el
new file mode 100644
index 000000000000..acb78f329c89
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-pkg.el
@@ -0,0 +1,11 @@
+(define-package "slack" "20180913.651" "Slack client for Emacs"
+  '((websocket "1.8")
+    (request "0.2.0")
+    (oauth2 "0.10")
+    (circe "2.2")
+    (alert "1.2")
+    (emojify "0.2"))
+  :url "https://github.com/yuya373/emacs-slack")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reaction.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reaction.el
new file mode 100644
index 000000000000..d0cff1a80370
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reaction.el
@@ -0,0 +1,117 @@
+;;; slack-reaction.el ---  deal with reactions       -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+
+(defclass slack-reaction ()
+  ((name :initarg :name :type string)
+   (count :initarg :count :type integer)
+   (users :initarg :users :initform ())))
+
+(defmethod slack-reaction-join ((r slack-reaction) other)
+  (if (string= (oref r name) (oref other name))
+      (progn
+        (cl-incf (oref r count))
+        (oset r users (append (oref other users) (oref r users)))
+        r)))
+
+(defmethod slack-reaction-user-names ((r slack-reaction) team)
+  (with-slots (users) r
+    (mapcar #'(lambda (u) (slack-user-name u team))
+            users)))
+
+(defmethod slack-equalp ((r slack-reaction) other)
+  (slack-reaction-equalp r other))
+
+(defmethod slack-reaction-equalp ((r slack-reaction) other)
+  (string= (oref r name) (oref other name)))
+
+(defmethod slack-reaction-help-text ((r slack-reaction) team)
+  (let ((user-names (slack-reaction-user-names r team)))
+    (format "%s reacted with :%s:"
+            (mapconcat #'identity user-names ", ")
+            (oref r name))))
+
+(defvar slack-reaction-keymap
+  (let ((keymap (make-sparse-keymap)))
+    (define-key keymap (kbd "RET") #'slack-reaction-toggle)
+    (define-key keymap [mouse-1] #'slack-reaction-toggle)
+    keymap))
+
+(defun slack-reaction-toggle ()
+  (interactive)
+  (slack-if-let* ((buffer slack-current-buffer)
+                  (reaction (get-text-property (point) 'reaction))
+                  (reaction-name (oref reaction name))
+                  (reaction-users (oref reaction users))
+                  (team (oref buffer team))
+                  (self-id (oref team self-id)))
+      (if (cl-find-if #'(lambda (id) (string= id self-id)) reaction-users)
+          (slack-message-reaction-remove reaction-name
+                                         (slack-get-ts)
+                                         (oref buffer room)
+                                         team)
+        (slack-message--add-reaction buffer reaction-name))))
+
+(defun slack-reaction-help-echo (_window _string pos)
+  (slack-if-let* ((buffer slack-current-buffer)
+                  (reaction (get-text-property pos 'reaction))
+                  (team (oref buffer team)))
+      (slack-reaction-help-text reaction team)))
+
+(defmethod slack-reaction-to-string ((r slack-reaction) team)
+  (propertize (format " :%s: %d " (oref r name) (oref r count))
+              'face 'slack-message-output-reaction
+              'mouse-face 'highlight
+              'keymap slack-reaction-keymap
+              'reaction r
+              'help-echo #'slack-reaction-help-echo))
+
+(defun slack-reaction-echo-description ()
+  (slack-if-let* ((buffer slack-current-buffer)
+                  (reaction (get-text-property (point) 'reaction))
+                  (team (oref buffer team)))
+      (message (slack-reaction-help-text reaction team))))
+
+(defun slack-reaction-notify (payload team room)
+  (let* ((user-id (plist-get payload :user))
+         (reaction (plist-get payload :reaction))
+         (msg (slack-user-message "msg"
+                                  :text (format "added reaction %s" reaction)
+                                  :user user-id)))
+    (slack-message-notify msg room team)))
+
+(defun slack-reaction--find (reactions reaction)
+  (cl-find-if #'(lambda (e) (slack-reaction-equalp e reaction))
+              reactions))
+
+(defun slack-reaction--delete (reactions reaction)
+  (cl-delete-if #'(lambda (e) (slack-reaction-equalp e reaction))
+                reactions))
+
+(provide 'slack-reaction)
+;;; slack-reaction.el ends here
+
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reaction.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reaction.elc
new file mode 100644
index 000000000000..220b289a5bee
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reaction.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reminder.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reminder.el
new file mode 100644
index 000000000000..8d2ab413ddab
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reminder.el
@@ -0,0 +1,237 @@
+;;; slack-reminder.el ---                            -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2016  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-team)
+(require 'slack-request)
+
+(defconst slack-reminder-list-url "https://slack.com/api/reminders.list")
+(defconst slack-reminder-delete-url "https://slack.com/api/reminders.delete")
+(defconst slack-reminder-complete-url "https://slack.com/api/reminders.complete")
+(defconst slack-reminder-info-url "https://slack.com/api/reminders.info")
+
+(defclass slack-reminder-base ()
+  ((id :initarg :id :type string)
+   (creator :initarg :creator :type string)
+   (user :initarg :user :type string)
+   (text :initarg :text :type string)))
+
+(defclass slack-recurring-reminder (slack-reminder-base)
+  ())
+
+(defclass slack-reminder (slack-reminder-base)
+  ((time :initarg :time :type integer)
+   (complete-ts :initarg :complete_ts :type integer)))
+
+(defmethod slack-reminder-user ((r slack-reminder-base) team)
+  (slack-user-find r team))
+
+(defmethod slack-reminder-creator ((r slack-reminder-base) team)
+  (slack-user--find (oref r creator) team))
+
+(defmethod slack-reminder-completedp ((r slack-reminder))
+  (not (eq 0 (oref r complete-ts))))
+
+(defmethod slack-reminder-completedp ((_r slack-recurring-reminder))
+  nil)
+
+(defun slack-reminder-create (payload)
+  (let ((klass (if (eq :json-false (plist-get payload :recurring))
+                   'slack-reminder
+                 'slack-recurring-reminder)))
+    (apply #'make-instance klass
+           (slack-collect-slots klass payload))))
+
+(defmethod slack-reminder-to-body ((r slack-reminder))
+  (with-slots (text time complete-ts) r
+    (let ((time-str (format "Remind At: %s"
+                            (slack-message-time-to-string
+                             (number-to-string time))))
+          (completed (format "Completed: %s"
+                             (if (eq complete-ts 0)
+                                 "Not Yet"
+                               (slack-message-time-to-string
+                                (number-to-string complete-ts))))))
+      (format "%s\n%s\n\n%s" time-str completed text))))
+
+(defmethod slack-reminder-to-body ((r slack-recurring-reminder))
+  (oref r text))
+
+(defmethod slack-reminder-to-string ((r slack-reminder-base) team)
+  (with-slots (creator user) r
+    (let* ((header (slack-message-put-header-property
+                    (format "From: %s To: %s"
+                            (slack-user-name creator team)
+                            (slack-user-name user team))))
+           (body (slack-reminder-to-body r)))
+      (format "%s\n%s\n\n" header body))))
+
+(defmethod slack-create-reminder-buffer ((team slack-team))
+  (let* ((buf-name "*Slack - Reminders*")
+         (buf (get-buffer-create buf-name)))
+    (with-current-buffer buf
+      (setq buffer-read-only nil)
+      (erase-buffer)
+      (goto-char (point-min))
+      (with-slots (reminders) team
+        (cl-loop for reminder in reminders
+                 do (insert (slack-reminder-to-string reminder team))))
+      (setq buffer-read-only t))
+    buf))
+
+(defmethod slack-reminder-sort-key ((r slack-reminder))
+  (oref r time))
+
+(defmethod slack-reminder-sort-key ((r slack-recurring-reminder))
+  0)
+
+(defun slack-reminder-sort (team)
+  (with-slots (reminders) team
+    (setq reminders
+          (cl-sort reminders #'<
+                   :key #'(lambda (r) (slack-reminder-sort-key r))))))
+
+(defun slack-reminder-list ()
+  (interactive)
+  (let ((team (slack-team-select)))
+    (cl-labels
+        ((on-reminder-list
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-reminder-list")
+           (oset team reminders
+                 (cl-loop
+                  for payload in (slack-decode
+                                  (append (plist-get data :reminders)
+                                          nil))
+                  collect (slack-reminder-create payload)))
+           (slack-reminder-sort team)
+           (if (< 0 (length (oref team reminders)))
+               (funcall
+                slack-buffer-function
+                (slack-create-reminder-buffer team))
+             (message "No Reminders!")))))
+      (slack-request
+       (slack-request-create
+        slack-reminder-list-url
+        team
+        :success #'on-reminder-list)))))
+
+(defmethod slack-reminders-alist ((team slack-team) &optional filter)
+  (cl-labels ((text (r)
+                    (with-slots (creator user text) r
+                      (format "Creator: %s Target: %s Content: %s"
+                              (slack-user-name creator team)
+                              (slack-user-name user team)
+                              text))))
+    (with-slots (reminders) team
+      (mapcar #'(lambda (r) (cons (text r) r))
+              (if filter
+                  (cl-remove-if-not #'(lambda (r) (funcall filter r))
+                                    reminders)
+                reminders)))))
+
+(defmethod slack-team-delete-reminder ((team slack-team) r)
+  (with-slots (reminders) team
+    (setq reminders
+          (cl-remove-if #'(lambda (e)
+                            (string= (oref e id) (oref r id)))
+                        reminders))))
+
+(defun slack-reminder-select (team &optional filter)
+  (slack-select-from-list
+      ((slack-reminders-alist team filter) "Select: ")))
+
+(defun slack-reminder-delete ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (reminder (slack-reminder-select team)))
+    (cl-labels
+        ((on-reminder-delete (&key data &allow-other-keys)
+                             (slack-request-handle-error
+                              (data "slack-reminder-delete")
+                              (slack-team-delete-reminder team reminder)
+                              (message "Reminder Deleted!"))))
+      (slack-request
+       (slack-request-create
+        slack-reminder-delete-url
+        team
+        :params (list (cons "reminder" (oref reminder id)))
+        :success #'on-reminder-delete)))))
+
+(defmethod slack-reminder-info ((r slack-reminder-base) team callback)
+  (cl-labels
+      ((on-reminder-info (&key data &allow-other-keys)
+                         (slack-request-handle-error
+                          (data "slack-reminder-info")
+                          (let ((reminder (slack-reminder-create
+                                           (plist-get (slack-decode data)
+                                                      :reminder))))
+                            (funcall callback reminder)))))
+    (slack-request
+     (slack-request-create
+      slack-reminder-info-url
+      team
+      :params (list (cons "reminder" (oref r id)))
+      :success #'on-reminder-info))))
+
+(defmethod slack-reminder-refresh ((r slack-reminder-base) team)
+  (slack-reminder-info
+   r team
+   #'(lambda (reminder)
+       (with-slots (reminders) team
+         (setq reminders
+               (cl-remove-if #'(lambda (e) (string= (oref e id)
+                                                    (oref reminder id)))
+                             reminders))
+         (push reminder reminders))
+       (message "Reminder Updated!"))))
+
+(defun slack-reminder-complete ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (reminder (slack-reminder-select
+                    team
+                    #'(lambda (r)
+                        (not (slack-reminder-completedp r))))))
+    (cl-labels
+        ((on-reminder-complete (&key data &allow-other-keys)
+                               (slack-request-handle-error
+                                (data "slack-reminder-complete")
+                                (slack-reminder-refresh reminder team))))
+      (slack-request
+       (slack-request-create
+        slack-reminder-complete-url
+        team
+        :params (list (cons "reminder" (oref reminder id)))
+        :success #'on-reminder-complete)))))
+
+(defmethod slack-user-find ((r slack-reminder-base) team)
+  (slack-user--find (oref r user) team))
+
+(provide 'slack-reminder)
+;;; slack-reminder.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reminder.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reminder.elc
new file mode 100644
index 000000000000..19a16c9e6cc1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reminder.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reply.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reply.el
new file mode 100644
index 000000000000..8a6489e88bb4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reply.el
@@ -0,0 +1,49 @@
+;;; slack-reply.el ---handle reply from slack        -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-message)
+
+(defmethod slack-message-handle-reply ((m slack-reply) team)
+  (with-slots (reply-to) m
+    (let ((sent-msg (slack-message-find-sent m team)))
+      (if sent-msg
+          (progn
+            (oset sent-msg ts (slack-ts m))
+            (slack-message-update sent-msg team))))))
+
+(defmethod slack-message-find-sent ((m slack-reply) team)
+  (with-slots (reply-to) m
+    (with-slots (sent-message) team
+      (let ((found (gethash reply-to sent-message)))
+        (remhash reply-to sent-message)
+        found))))
+
+(defmethod slack-message-sender-equalp ((m slack-reply) sender-id)
+  (string= (oref m user) sender-id))
+
+
+(provide 'slack-reply)
+;;; slack-reply.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reply.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reply.elc
new file mode 100644
index 000000000000..d5c798fa0792
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-reply.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request-worker.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request-worker.el
new file mode 100644
index 000000000000..13068f94800c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request-worker.el
@@ -0,0 +1,143 @@
+;;; slack-request-worker.el ---                      -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-request)
+(require 'slack-team)
+
+(defcustom slack-request-worker-max-request-limit 30
+  "Max request count perform simultaneously."
+  :group 'slack)
+
+(defvar slack-request-worker-instance nil)
+
+(defclass slack-request-worker ()
+  ((queue :initform '() :type list)
+   (timer :initform nil)
+   (current-request-count :initform 0 :type integer)
+   ))
+
+(defun slack-request-worker-create ()
+  "Create `slack-request-worker' instance."
+  (make-instance 'slack-request-worker))
+
+(defmethod slack-request-worker-push ((this slack-request-worker) req)
+  (let ((l '()))
+    (cl-pushnew req (oref this queue)
+                :test #'slack-equalp)))
+
+(defun slack-request-worker-set-timer ()
+  (cl-labels
+      ((on-timeout ()
+                   (slack-request-worker-execute)
+                   (when (timerp slack-request-worker-instance)
+                     (cancel-timer slack-request-worker-instance))
+                   (slack-request-worker-set-timer)))
+    (oset slack-request-worker-instance timer
+          (run-at-time 1 nil #'on-timeout))))
+
+(defun slack-request-worker-execute ()
+  "Pop request from queue until `slack-request-worker-max-request-limit', and execute."
+  (when slack-request-worker-instance
+    (let ((do '())
+          (skip '())
+          (current (time-to-seconds))
+          (limit (- slack-request-worker-max-request-limit
+                    (oref slack-request-worker-instance
+                          current-request-count))))
+
+      (cl-loop for req in (reverse (oref slack-request-worker-instance queue))
+               do (if (and (< (oref req execute-at) current)
+                           (< (length do) limit))
+                      (push req do)
+                    (push req skip)))
+
+      ;; (message "[WORKER] QUEUE: %s, LIMIT: %s, CURRENT: %s, DO: %s, SKIP: %s"
+      ;;          (length (oref slack-request-worker-instance queue))
+      ;;          slack-request-worker-max-request-limit
+      ;;          (oref slack-request-worker-instance current-request-count)
+      ;;          (length do)
+      ;;          (length skip))
+
+      (oset slack-request-worker-instance queue skip)
+
+      (cl-labels
+          ((decl-request-count
+            ()
+            (cl-decf (oref slack-request-worker-instance
+                           current-request-count))))
+        (cl-loop for req in do
+                 do (progn
+                      (cl-incf (oref slack-request-worker-instance
+                                     current-request-count))
+                      (slack-request req
+                                     :on-success #'decl-request-count
+                                     :on-error #'decl-request-count
+                                     )))))))
+
+(defmethod slack-request-worker-push ((req slack-request-request))
+  (unless slack-request-worker-instance
+    (setq slack-request-worker-instance
+          (slack-request-worker-create)))
+  (slack-request-worker-push slack-request-worker-instance req)
+  (unless (oref slack-request-worker-instance timer)
+    (slack-request-worker-set-timer)))
+
+(defun slack-request-worker-quit ()
+  "Cancel timer and remove `slack-request-worker-instance'."
+  (when (and slack-request-worker-instance
+             (timerp (oref slack-request-worker-instance timer)))
+    (cancel-timer (oref slack-request-worker-instance timer)))
+  (setq slack-request-worker-instance nil))
+
+(defmethod slack-request-worker-remove-request ((team slack-team))
+  "Remove request from TEAM in queue."
+  (when slack-request-worker-instance
+    (let ((to-remove '())
+          (new-queue '())
+          (all (oref slack-request-worker-instance queue)))
+
+      (dolist (req all)
+        (if (string= (oref (oref req team) id)
+                     (oref team id))
+            (push req to-remove)
+          (push req new-queue)))
+
+      (dolist (req to-remove)
+        (when (and (oref req response)
+                   (not (request-response-done-p (oref req response))))
+          (request-abort (oref req response))))
+
+      (oset slack-request-worker-instance queue new-queue)
+      (slack-log (format "Remove Request from Worker, ALL: %s, REMOVED: %s, NEW-QUEUE: %s"
+                         (length all)
+                         (length to-remove)
+                         (length new-queue))
+                 team :level 'debug))))
+
+(provide 'slack-request-worker)
+;;; slack-request-worker.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request-worker.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request-worker.elc
new file mode 100644
index 000000000000..069a00cf3aaf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request-worker.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request.el
new file mode 100644
index 000000000000..43c97face3c1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request.el
@@ -0,0 +1,162 @@
+;;; slack-request.el ---slack request function       -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'json)
+(require 'request)
+(require 'slack-util)
+
+(defcustom slack-request-timeout 10
+  "Request Timeout in seconds."
+  :group 'slack)
+
+(defun slack-parse ()
+  (let ((json-object-type 'plist)
+        (json-array-type 'list))
+    (json-read)))
+
+(defun slack-request-parse-payload (payload)
+  (let ((json-object-type 'plist)
+        (json-array-type 'list))
+    (condition-case err-var
+        (json-read-from-string payload)
+      (json-end-of-file nil))))
+
+(defclass slack-request-request ()
+  ((response :initform nil)
+   (url :initarg :url)
+   (team :initarg :team)
+   (type :initarg :type :initform "GET")
+   (success :initarg :success)
+   (error :initarg :error :initform nil)
+   (params :initarg :params :initform nil)
+   (data :initarg :data :initform nil)
+   (parser :initarg :parser :initform #'slack-parse)
+   (sync :initarg :sync :initform nil)
+   (files :initarg :files :initform nil)
+   (headers :initarg :headers :initform nil)
+   (timeout :initarg :timeout :initform `,slack-request-timeout)
+   (execute-at :initform 0.0 :type float)))
+
+(cl-defun slack-request-create
+    (url team &key type success error params data parser sync files headers timeout)
+  (let ((args (list
+               :url url :team team :type type
+               :success success :error error
+               :params params :data data :parser parser
+               :sync sync :files files :headers headers
+               :timeout timeout))
+        (ret nil))
+    (mapc #'(lambda (maybe-key)
+              (let ((value (plist-get args maybe-key)))
+                (when value
+                  (setq ret (plist-put ret maybe-key value)))))
+          args)
+    (apply #'make-instance 'slack-request-request ret)))
+
+(defmethod slack-equalp ((this slack-request-request) other)
+  (and (string= (oref (oref this team) id)
+                (oref (oref other team) id))
+       (string= "GET" (oref this type))
+       (string= "GET" (oref other type))
+       (string= (oref this url)
+                (oref other url))
+       (equalp (oref this params)
+               (oref other params))))
+
+(defmethod slack-request-retry-request ((req slack-request-request) retry-after team)
+  (oset req execute-at (+ retry-after (time-to-seconds)))
+  (slack-request-worker-push req))
+
+(cl-defmethod slack-request ((req slack-request-request)
+                             &key (on-success nil) (on-error nil))
+  (let ((team (oref req team)))
+    (with-slots (url type success error params data parser sync files headers timeout) req
+      (cl-labels
+          ((on-success (&key data &allow-other-keys)
+                       (funcall success :data data)
+                       (slack-log
+                        (format "Request Finished. URL: %s, PARAMS: %s"
+                                url
+                                params)
+                        team :level 'trace)
+                       (when (functionp on-success)
+                         (funcall on-success)))
+           (on-error (&key error-thrown symbol-status response data)
+                     (slack-if-let* ((retry-after (request-response-header response "retry-after"))
+                                     (retry-after-sec (string-to-number retry-after)))
+                         (progn
+                           (slack-request-retry-request req retry-after-sec team)
+                           (slack-log (format "Retrying Request After: %s second, URL: %s, PARAMS: %s"
+                                              retry-after-sec
+                                              url
+                                              params)
+                                      team))
+                       (slack-log (format "Request Failed. URL: %s, PARAMS: %s, ERROR-THROWN: %s, SYMBOL-STATUS: %s, DATA: %s"
+                                          url
+                                          params
+                                          error-thrown
+                                          symbol-status
+                                          data)
+                                  team
+                                  :level 'error)
+                       (when (functionp error)
+                         (funcall error
+                                  :error-thrown error-thrown
+                                  :symbol-status symbol-status
+                                  :response response
+                                  :data data))
+                       (when (functionp on-error)
+                         (funcall on-error)))))
+        (oset req response
+              (request
+               url
+               :type type
+               :sync sync
+               :params (cons (cons "token" (oref team token))
+                             params)
+               :data data
+               :files files
+               :headers headers
+               :parser parser
+               :success #'on-success
+               :error #'on-error
+               :timeout timeout))))))
+
+
+(cl-defmacro slack-request-handle-error ((data req-name &optional handler) &body body)
+  "Bind error to e if present in DATA."
+  `(if (eq (plist-get ,data :ok) :json-false)
+       (if ,handler
+           (funcall ,handler (plist-get ,data :error))
+         (message "Failed to request %s: %s"
+                  ,req-name
+                  (plist-get ,data :error)))
+     (progn
+       ,@body)))
+
+(provide 'slack-request)
+;;; slack-request.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request.elc
new file mode 100644
index 000000000000..9779eb774677
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-request.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-buffer.el
new file mode 100644
index 000000000000..6b477ccb9db4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-buffer.el
@@ -0,0 +1,170 @@
+;;; slack-room-buffer.el ---                         -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-buffer)
+(require 'slack-request)
+
+(defconst slack-message-delete-url "https://slack.com/api/chat.delete")
+(defconst slack-get-permalink-url "https://slack.com/api/chat.getPermalink")
+
+(defclass slack-room-buffer (slack-buffer)
+  ((room :initarg :room :type slack-room)))
+
+(defmethod slack-buffer-name :static ((class slack-room-buffer) room team)
+  (slack-if-let* ((room-name (slack-room-name room team)))
+      (format  "*Slack - %s : %s"
+               (oref team name)
+               room-name)))
+
+(defmethod slack-buffer-name ((this slack-room-buffer))
+  (with-slots (room team) this
+    (slack-buffer-name (eieio-object-class-name this) room team)))
+
+(defmethod slack-buffer-delete-message ((this slack-room-buffer) ts)
+  (with-slots (room team) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (cl-labels
+            ((on-delete
+              (&key data &allow-other-keys)
+              (slack-request-handle-error
+               (data "slack-message-delete"))))
+          (if (yes-or-no-p "Are you sure you want to delete this message?")
+              (slack-request
+               (slack-request-create
+                slack-message-delete-url
+                team
+                :type "POST"
+                :params (list (cons "ts" (slack-ts message))
+                              (cons "channel" (oref room id)))
+                :success #'on-delete))
+            (message "Canceled"))))))
+
+(defmethod slack-buffer-message-delete ((this slack-room-buffer) ts)
+  (let ((buffer (slack-buffer-buffer this)))
+    (with-current-buffer buffer
+      (lui-delete #'(lambda () (equal (get-text-property (point) 'ts)
+                                      ts))))))
+
+(defmethod slack-buffer-copy-link ((this slack-room-buffer) ts)
+  (with-slots (room team) this
+    (slack-if-let* ((message (slack-room-find-message room ts))
+                    (template "https://%s.slack.com/archives/%s/p%s%s"))
+        (cl-labels
+            ((on-success (&key data &allow-other-keys)
+                         (slack-request-handle-error
+                          (data "slack-get-permalink")
+                          (let ((permalink (plist-get data :permalink)))
+                            (kill-new permalink)
+                            (message "Link Copied to Clipboard")))))
+          (slack-request
+           (slack-request-create
+            slack-get-permalink-url
+            team
+            :type "POST"
+            :params (list (cons "channel" (oref room id))
+                          (cons "message_ts" ts))
+            :success #'on-success))))))
+
+(defmethod slack-buffer--replace ((this slack-room-buffer) ts)
+  (with-slots (room) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (slack-buffer-replace this message))))
+
+(defmethod slack-buffer-toggle-email-expand ((this slack-room-buffer) ts file-id)
+  (with-slots (room) this
+    (slack-if-let* ((message (slack-room-find-message room ts))
+                    (file (cl-find-if
+                           #'(lambda (e) (string= (oref e id)
+                                                  file-id))
+                           (oref message files))))
+        (progn
+          (oset file is-expanded (not (oref file is-expanded)))
+          (slack-buffer-update this message :replace t)))))
+
+;; POST
+(defconst slack-actions-list-url "https://slack.com/api/apps.actions.list")
+;; POST
+;; params (action_id, type, app_id, channel, message_ts)
+(defconst slack-actions-run-url "https://slack.com/api/apps.actions.run")
+
+(defmethod slack-buffer-execute-message-action ((this slack-room-buffer) ts)
+  (with-slots (team room) this
+    (cl-labels
+        ((select
+          (app-actions)
+          (let ((choices (mapcan
+                          #'(lambda (app)
+                              (mapcar #'(lambda (action)
+                                          (cons (format "%s - %s"
+                                                        (plist-get action :name)
+                                                        (plist-get app :app_name))
+                                                (cons app action)))
+                                      (plist-get app :actions)))
+                          app-actions)))
+            (cdr (cl-assoc (funcall slack-completing-read-function
+                                    "Select Action: " choices)
+                           choices :test #'string=))))
+         (on-success-run (&key data &allow-other-keys)
+                         (slack-request-handle-error
+                          (data "slack-buffer-execute-message-action"
+                                #'(lambda (err) (slack-log (format "%s" err)
+                                                           team
+                                                           :level 'error)))))
+         (on-success-list
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-buffer-execute-message-action")
+           (slack-if-let*
+               ((app-actions (plist-get data :app_actions))
+                (selected (select app-actions))
+                (params (list (cons "message_ts" ts)
+                              (cons "channel" (oref room id))
+                              (cons "type" (plist-get (cdr selected)
+                                                      :type))
+                              (cons "action_id" (plist-get (cdr selected)
+                                                           :action_id))
+                              (cons "app_id" (plist-get (car selected)
+                                                        :app_id))
+                              (cons "client_token"
+                                    (slack-team-client-token team)))))
+               (slack-request
+                (slack-request-create
+                 slack-actions-run-url
+                 team
+                 :type "POST"
+                 :params params
+                 :success #'on-success-run))))))
+      (slack-request
+       (slack-request-create
+        slack-actions-list-url
+        team
+        :type "POST"
+        :success #'on-success-list)))))
+
+(provide 'slack-room-buffer)
+;;; slack-room-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-buffer.elc
new file mode 100644
index 000000000000..3f3fd8639ad2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-info-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-info-buffer.el
new file mode 100644
index 000000000000..f7043c032217
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-info-buffer.el
@@ -0,0 +1,173 @@
+;;; slack-room-info-buffer.el ---                    -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-group)
+(require 'slack-room-buffer)
+
+(defclass slack-room-info-buffer (slack-room-buffer) ())
+
+(define-derived-mode slack-room-info-buffer-mode fundamental-mode
+  "Slack Room Info"
+  (setq-local default-directory slack-default-directory)
+  (setq-local buffer-read-only t))
+
+(defmethod slack-buffer-name :static ((class slack-room-info-buffer) room team)
+  (slack-if-let* ((room-name (slack-room-name room team)))
+      (format "*Slack Room Info - %s : %s"
+              (slack-team-name team)
+              room-name)))
+
+(defmethod slack-buffer-name ((this slack-room-info-buffer))
+  (with-slots (room team) this
+    (slack-buffer-name (eieio-object-class-name this) room team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-room-info-buffer))
+  (let* ((bufname (slack-buffer-name this))
+         (buf (generate-new-buffer bufname)))
+    (with-current-buffer buf
+      (slack-room-info-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (slack-buffer-insert this)
+      (goto-char (point-min)))
+    (with-slots (room team) this
+      (let ((class (eieio-object-class-name this)))
+        (slack-buffer-push-new-3 class room team)))
+    buf))
+
+(defface slack-room-info-title-face
+  '((t (:weight bold :height 1.5)))
+  "Used to room info title."
+  :group 'slack)
+
+(defface slack-room-info-title-room-name-face
+  '((t (:inherit slack-room-info-title-face :foreground "#FFA000")))
+  "Used to room info title."
+  :group 'slack)
+
+(defface slack-room-info-section-title-face
+  '((t (:weight bold :height 1.2)))
+  "Used to room info section title."
+  :group 'slack)
+
+(defface slack-room-info-section-label-face
+  '((t (:weight bold)))
+  "Used to room info section title."
+  :group 'slack)
+
+(defmethod slack-buffer-insert ((this slack-room-info-buffer))
+  (with-slots (room team) this
+    (let ((inhibit-read-only t))
+      (insert (propertize "About "
+                          'face 'slack-room-info-title-face))
+      (insert (propertize (slack-room-name room team)
+                          'face 'slack-room-info-title-room-name-face))
+      (insert "\n")
+      (insert "\n")
+      (insert (propertize "Channel Details"
+                          'face 'slack-room-info-section-title-face))
+      (insert "\n")
+
+      (slack-buffer-insert-purpose room)
+      (slack-buffer-insert-topic room)
+      (slack-buffer-insert-created room team)
+      )))
+
+(defmethod slack-buffer-insert-created ((room slack-room) _team)
+  (with-slots (created) room
+    (when created
+      (insert (propertize "Created"
+                          'face 'slack-room-info-section-label-face))
+      (insert ":  ")
+      (insert (slack-message-time-to-string
+               (number-to-string created))))))
+
+(defmethod slack-buffer-insert-created ((room slack-group) team)
+  (call-next-method)
+  (with-slots (creator) room
+    (when creator
+      (let ((user (slack-user--find creator team)))
+        (insert (format " by %s" (plist-get user :real_name)))))
+    ))
+
+(defmethod slack-buffer-insert-purpose ((room slack-group))
+  (with-slots (purpose) room
+    (when purpose
+      (insert (propertize "Purpose"
+                          'face 'slack-room-info-section-label-face))
+      (insert ":  ")
+      (slack-if-let*
+          ((purpose-value (plist-get purpose :value))
+           (not-blank-p (and purpose-value
+                             (< 0 (length purpose-value)))))
+          (insert (format "%s\n" purpose-value))
+        (insert (propertize "Set purpose"
+                            'face '(:box (:line-width
+                                          1
+                                          :style
+                                          released-button))))
+        (insert "\n")))))
+
+(defmethod slack-buffer-insert-purpose ((room slack-room)))
+
+(defmethod slack-buffer-insert-topic ((room slack-group))
+  (with-slots (topic) room
+    (when topic
+      (insert (propertize "Topic"
+                          'face 'slack-room-info-section-label-face))
+      (insert ":  ")
+      (slack-if-let*
+          ((topic-value (plist-get topic :value))
+           (not-blank-p (and topic-value
+                             (< 0 (length topic-value)))))
+          (insert (format "%s\n" topic-value))
+        (insert (propertize "Set Topic"
+                            'face '(:box (:line-width
+                                          1
+                                          :style
+                                          released-button))))
+        (insert "\n")))))
+
+(defmethod slack-buffer-insert-topic ((room slack-room)))
+
+(defmethod slack-create-room-info-buffer ((room slack-room) team)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-room-info-buffer
+                                             room team)))
+      buffer
+    (slack-room-info-buffer :room room :team team)))
+
+(defmethod slack-buffer-buffer ((this slack-room-info-buffer))
+  (slack-if-let* ((buf (get-buffer (slack-buffer-name this))))
+      (with-current-buffer buf
+        (let ((inhibit-read-only t))
+          (delete-region (point-min) (point-max))
+          (slack-buffer-insert this))
+        buf)
+    (slack-buffer-init-buffer this)))
+
+
+(provide 'slack-room-info-buffer)
+;;; slack-room-info-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-info-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-info-buffer.elc
new file mode 100644
index 000000000000..be358a2cf9b1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-info-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-message-compose-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-message-compose-buffer.el
new file mode 100644
index 000000000000..02391570f27c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-message-compose-buffer.el
@@ -0,0 +1,69 @@
+;;; slack-room-message-compose-buffer.el ---              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-message-compose-buffer)
+
+(defclass slack-room-message-compose-buffer (slack-message-compose-buffer)
+  ((room :initarg :room type slack-room)))
+
+(defun slack-create-room-message-compose-buffer (room team)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-room-message-compose-buffer
+                                    room team)))
+      buf
+    (slack-room-message-compose-buffer :room room :team team)))
+
+(defmethod slack-buffer-name :static ((class slack-room-message-compose-buffer) room team)
+  (format "*Slack - %s : %s Compose Message"
+          (oref team name)
+          (slack-room-name room team)))
+
+(defmethod slack-buffer-name ((this slack-room-message-compose-buffer))
+  (with-slots (room team) this
+    (slack-buffer-name (eieio-object-class-name this)
+                       room team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-room-message-compose-buffer))
+  (let* ((buf (call-next-method)))
+    (with-current-buffer buf
+      (setq buffer-read-only nil)
+      (erase-buffer)
+      (message "C-c C-c to send edited msg"))
+    (with-slots (room team) this
+      (slack-buffer-push-new-3 'slack-room-message-compose-buffer
+                               room team))
+    buf))
+
+(defmethod slack-buffer-send-message ((this slack-room-message-compose-buffer) message)
+  (let ((buffer (slack-buffer-buffer this)))
+    (with-slots (room team) this
+      (slack-message-send-internal message (oref room id) team)
+      (call-next-method))))
+
+
+(provide 'slack-room-message-compose-buffer)
+;;; slack-room-message-compose-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-message-compose-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-message-compose-buffer.elc
new file mode 100644
index 000000000000..d7c9f9b5fca8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room-message-compose-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room.el
new file mode 100644
index 000000000000..a9632e9483e1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room.el
@@ -0,0 +1,471 @@
+;;; slack-room.el --- slack generic room interface    -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'lui)
+(require 'slack-util)
+(require 'slack-request)
+(require 'slack-message)
+(require 'slack-pinned-item)
+
+(defvar slack-buffer-function)
+(defconst slack-room-pins-list-url "https://slack.com/api/pins.list")
+
+(defclass slack-room ()
+  ((name :initarg :name :type (or null string) :initform nil)
+   (id :initarg :id)
+   (created :initarg :created)
+   (latest :initarg :latest)
+   (unread-count :initarg :unread_count :initform 0 :type integer)
+   (unread-count-display :initarg :unread_count_display :initform 0 :type integer)
+   (messages :initarg :messages :initform ())
+   (last-read :initarg :last_read :type string :initform "0")
+   (members :initarg :members :type list :initform '())))
+
+
+(defgeneric slack-room-name (room team))
+(defgeneric slack-room-history (room team &optional oldest after-success sync))
+(defgeneric slack-room-update-mark-url (room))
+
+(defmethod slack-equalp ((this slack-room) other)
+  (string= (oref this id)
+           (oref other id)))
+
+(defmethod slack-merge ((this slack-room) other)
+  "except MESSAGES"
+  (oset this name (oref other name))
+  (oset this id (oref other id))
+  (oset this created (oref other created))
+  (oset this latest (oref other latest))
+  (oset this unread-count (oref other unread-count))
+  (oset this unread-count-display (oref other unread-count-display))
+  (unless (string= "0" (oref other last-read))
+    (oset this last-read (oref other last-read))))
+
+(defun slack-room-create (payload team class)
+  (cl-labels
+      ((prepare (p)
+                (plist-put p :members
+                           (append (plist-get p :members) nil))
+                p))
+    (let* ((attributes (slack-collect-slots class (prepare payload)))
+           (room (apply #'make-instance class attributes)))
+      (oset room latest (slack-message-create (plist-get payload :latest) team :room room))
+      room)))
+
+(defmethod slack-room-subscribedp ((_room slack-room) _team)
+  nil)
+
+(defmethod slack-room-buffer-name ((room slack-room) team)
+  (concat "*Slack*"
+          " : "
+          (slack-room-display-name room team)))
+
+(cl-defmacro slack-select-from-list ((alist prompt &key initial) &body body)
+  "Bind candidates from selected."
+  (declare (indent 2) (debug t))
+  (let ((key (cl-gensym)))
+    `(let* ((,key (let ((completion-ignore-case t))
+                    (funcall slack-completing-read-function (format "%s" ,prompt)
+                             ,alist nil t ,initial)))
+            (selected (cdr (cl-assoc ,key ,alist :test #'string=))))
+       ,@body
+       selected)))
+
+(defmethod slack-room-hidden-p ((room slack-room))
+  (slack-room-hiddenp room))
+
+(defun slack-room-hiddenp (room)
+  (or (not (slack-room-member-p room))
+      (slack-room-archived-p room)
+      (not (slack-room-open-p room))))
+
+(defmacro slack-room-names (rooms team &optional filter collecter)
+  `(cl-labels
+       ((latest-ts (room)
+                   (with-slots (latest) room
+                     (if latest (slack-ts latest) "0")))
+        (sort-rooms (rooms)
+                    (nreverse (cl-sort rooms #'string< :key #'latest-ts))))
+     (cl-loop for room in (sort-rooms (if ,filter
+                                          (funcall ,filter ,rooms)
+                                        ,rooms))
+              as label = (slack-room-label room team)
+              collect (if (functionp ,collecter)
+                          (funcall ,collecter label room)
+                        (cons label room)))))
+
+(defun slack-room-select (rooms team)
+  (let* ((alist (slack-room-names
+                 rooms team #'(lambda (rs) (cl-remove-if #'slack-room-hidden-p rs)))))
+    (slack-select-from-list (alist "Select Channel: "))))
+
+(cl-defun slack-room-list-update (url success team &key (sync t))
+  (slack-request
+   (slack-request-create
+    url
+    team
+    :success success)))
+
+(defun slack-room-find-message (room ts)
+  (cl-find-if #'(lambda (m) (string= ts (slack-ts m)))
+              (oref room messages)
+              :from-end t))
+
+(defun slack-room-find-thread-parent (room thread-message)
+  (slack-room-find-message room (oref thread-message thread-ts)))
+
+(defmethod slack-message-thread ((this slack-message) _room)
+  (oref this thread))
+
+(defmethod slack-message-thread ((this slack-reply-broadcast-message) room)
+  (let ((message (slack-room-find-message room
+                                          (or (oref this broadcast-thread-ts)
+                                              (oref this thread-ts)))))
+    (slack-message-thread message room)))
+
+(defun slack-room-find-thread (room ts)
+  (let ((message (slack-room-find-message room ts)))
+    (when message
+      (slack-message-thread message room))))
+
+(defmethod slack-room-display-name ((room slack-room) team)
+  (let ((room-name (slack-room-name room team)))
+    (if slack-display-team-name
+        (format "%s - %s"
+                (slack-team-name team)
+                room-name)
+      room-name)))
+
+(defmethod slack-room-label-prefix ((_room slack-room) _team)
+  "  ")
+
+(defmethod slack-room-unread-count-str ((room slack-room))
+  (with-slots (unread-count-display) room
+    (if (< 0 unread-count-display)
+        (concat " ("
+                (number-to-string unread-count-display)
+                ")")
+      "")))
+
+(defmethod slack-room-label ((room slack-room) team)
+  (format "%s%s%s"
+          (slack-room-label-prefix room team)
+          (slack-room-display-name room team)
+          (slack-room-unread-count-str room)))
+
+(defmethod slack-room-name ((room slack-room) _team)
+  (oref room name))
+
+(defun slack-room-sort-messages (messages)
+  (cl-sort messages #'string< :key #'slack-ts))
+
+(defun slack-room-reject-thread-message (messages)
+  (cl-remove-if #'(lambda (m) (and (not (eq (eieio-object-class-name m)
+                                            'slack-reply-broadcast-message))
+                                   (slack-thread-message-p m)))
+                messages))
+
+(defmethod slack-room-sorted-messages ((room slack-room))
+  (with-slots (messages) room
+    (slack-room-sort-messages (copy-sequence messages))))
+
+(defmethod slack-room-set-prev-messages ((room slack-room) prev-messages)
+  (slack-room-set-messages room
+                           (append (oref room messages)
+                                   prev-messages)))
+
+(defmethod slack-room-append-messages ((room slack-room) messages)
+  (slack-room-set-messages room
+                           (append messages (oref room messages))))
+
+(defmethod slack-room-update-latest ((room slack-room) message)
+  (when (and message
+             (not (slack-thread-message-p message)))
+    (with-slots (latest) room
+      (if (or (null latest)
+              (string< (slack-ts latest) (slack-ts message)))
+          (setq latest message)))))
+
+(defmethod slack-room-push-message ((room slack-room) message)
+  (with-slots (messages) room
+    (setq messages
+          (cl-remove-if #'(lambda (n) (slack-message-equal message n))
+                        messages))
+    (push message messages)))
+
+(defmethod slack-room-set-messages ((room slack-room) messages)
+  (let* ((sorted (slack-room-sort-messages
+                  (cl-delete-duplicates messages
+                                        :test #'slack-message-equal)))
+         (oldest (car sorted))
+         (latest (car (last sorted))))
+    (oset room messages sorted)
+    (slack-room-update-latest room latest)))
+
+(defmethod slack-room-prev-messages ((room slack-room) from)
+  (with-slots (messages) room
+    (cl-remove-if #'(lambda (m)
+                      (or (string< from (slack-ts m))
+                          (string= from (slack-ts m))))
+                  (slack-room-sort-messages (copy-sequence messages)))))
+
+(defmethod slack-room-update-mark ((room slack-room) team ts)
+  (cl-labels ((on-update-mark (&key data &allow-other-keys)
+                              (slack-request-handle-error
+                               (data "slack-room-update-mark"))))
+    (with-slots (id) room
+      (slack-request
+       (slack-request-create
+        (slack-room-update-mark-url room)
+        team
+        :type "POST"
+        :params (list (cons "channel"  id)
+                      (cons "ts"  ts))
+        :success #'on-update-mark)))))
+
+(defun slack-room-pins-list ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-display-pins-list buf)))
+
+(defun slack-select-rooms ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (room (slack-room-select
+                (cl-loop for team in (list team)
+                         append (with-slots (groups ims channels) team
+                                  (append ims groups channels)))
+                team)))
+    (slack-room-display room team)))
+
+(defun slack-create-room (url team success)
+  (slack-request
+   (slack-request-create
+    url
+    team
+    :type "POST"
+    :params (list (cons "name" (read-from-minibuffer "Name: ")))
+    :success success)))
+
+(defun slack-room-rename (url room-alist-func)
+  (cl-labels
+      ((on-rename-success (&key data &allow-other-keys)
+                          (slack-request-handle-error
+                           (data "slack-room-rename"))))
+    (let* ((team (slack-team-select))
+           (room-alist (funcall room-alist-func team))
+           (room (slack-select-from-list
+                     (room-alist "Select Channel: ")))
+           (name (read-from-minibuffer "New Name: ")))
+      (slack-request
+       (slack-request-create
+        url
+        team
+        :params (list (cons "channel" (oref room id))
+                      (cons "name" name))
+        :success #'on-rename-success)))))
+
+(defmacro slack-current-room-or-select (room-alist-func &optional select)
+  `(if (and (not ,select)
+            (bound-and-true-p slack-current-buffer)
+            (slot-boundp slack-current-buffer 'room))
+       (oref slack-current-buffer room)
+     (let* ((room-alist (funcall ,room-alist-func)))
+       (slack-select-from-list
+           (room-alist "Select Channel: ")))))
+
+(defmacro slack-room-invite (url room-alist-func)
+  `(cl-labels
+       ((on-group-invite (&key data &allow-other-keys)
+                         (slack-request-handle-error
+                          (data "slack-room-invite")
+                          (if (plist-get data :already_in_group)
+                              (message "User already in group")
+                            (message "Invited!")))))
+     (let* ((team (slack-team-select))
+            (room (slack-current-room-or-select
+                   #'(lambda ()
+                       (funcall ,room-alist-func team
+                                #'(lambda (rooms)
+                                    (cl-remove-if #'slack-room-archived-p
+                                                  rooms))))))
+            (user-id (plist-get (slack-select-from-list
+                                    ((slack-user-names team)
+                                     "Select User: ")) :id)))
+       (slack-request
+        (slack-request-create
+         ,url
+         team
+         :params (list (cons "channel" (oref room id))
+                       (cons "user" user-id))
+         :success #'on-group-invite)))))
+
+(defmethod slack-room-member-p ((_room slack-room)) t)
+
+(defmethod slack-room-archived-p ((_room slack-room)) nil)
+
+(defmethod slack-room-open-p ((_room slack-room)) t)
+
+(defmethod slack-room-equal-p ((room slack-room) other)
+  (string= (oref room id) (oref other id)))
+
+(defun slack-room-deleted (id team)
+  (let ((room (slack-room-find id team)))
+    (cond
+     ((object-of-class-p room 'slack-channel)
+      (with-slots (channels) team
+        (setq channels (cl-delete-if #'(lambda (c) (slack-room-equal-p room c))
+                                     channels)))
+      (message "Channel: %s deleted"
+               (slack-room-display-name room team))))))
+
+(cl-defun slack-room-request-with-id (url id team success)
+  (slack-request
+   (slack-request-create
+    url
+    team
+    :params (list (cons "channel" id))
+    :success success)))
+
+(defmethod slack-room-inc-unread-count ((room slack-room))
+  (cl-incf (oref room unread-count-display)))
+
+(defun slack-room-find-by-name (name team)
+  (cl-labels
+      ((find-by-name (rooms name)
+                     (cl-find-if #'(lambda (e) (string= name
+                                                        (slack-room-name e team)))
+                                 rooms)))
+    (or (find-by-name (oref team groups) name)
+        (find-by-name (oref team channels) name)
+        (find-by-name (oref team ims) name))))
+
+(defmethod slack-room-info-request-params ((room slack-room))
+  (list (cons "channel" (oref room id))))
+
+(defmethod slack-room-create-info-request ((room slack-room) team)
+  (cl-labels
+      ((on-success
+        (&key data &allow-other-keys)
+        (slack-request-handle-error
+         (data "slack-room-info-request"
+               #'(lambda (e)
+                   (if (not (string= e "user_disabled"))
+                       (message "Failed to request slack-room-info-request: %s" e))))
+         (slack-room-update-info room data team))))
+    (slack-request-create
+     (slack-room-get-info-url room)
+     team
+     :params (slack-room-info-request-params room)
+     :success #'on-success)))
+
+(defmethod slack-room-info-request ((room slack-room) team)
+  (slack-request
+   (slack-room-create-info-request room team)))
+
+(defmethod slack-room-get-members ((room slack-room))
+  (oref room members))
+
+(defun slack-room-user-select ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-display-user-profile buf)))
+
+(defun slack-select-unread-rooms ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (room (slack-room-select
+                (cl-loop for team in (list team)
+                         append (with-slots (groups ims channels) team
+                                  (cl-remove-if
+                                   #'(lambda (room)
+                                       (not (< 0 (oref room
+                                                       unread-count-display))))
+                                   (append ims groups channels))))
+                team)))
+    (slack-room-display room team)))
+
+(defmethod slack-user-find ((room slack-room) team)
+  (slack-user--find (oref room user) team))
+
+(defun slack-room-display (room team)
+  (cl-labels
+      ((open (buf)
+             (slack-buffer-display buf)))
+    (let* ((buf (slack-buffer-find (or (and (eq (eieio-object-class-name room)
+                                                'slack-file-room)
+                                            'slack-file-list-buffer)
+                                       'slack-message-buffer)
+                                   room team)))
+      (if buf (open buf)
+        (message "No Message in %s, fetching from server..." (slack-room-name room team))
+        (slack-room-history-request
+         room team
+         :after-success #'(lambda (&rest _ignore)
+                            (open (slack-create-message-buffer room team))))))))
+
+(defmethod slack-room-update-buffer ((this slack-room) team message replace)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-message-buffer this team)))
+      (slack-buffer-update buffer message :replace replace)
+    (and slack-buffer-create-on-notify
+         (slack-room-history-request
+          this team
+          :after-success #'(lambda (&rest _ignore)
+                             (tracking-add-buffer
+                              (slack-buffer-buffer
+                               (slack-create-message-buffer this team))))))))
+
+(cl-defmethod slack-room-history-request ((room slack-room) team &key oldest latest count after-success async)
+  (cl-labels
+      ((on-request-update
+        (&key data &allow-other-keys)
+        (slack-request-handle-error
+         (data "slack-room-request-update")
+         (let ((messages
+                 (cl-loop for message in (plist-get data :messages)
+                          collect (slack-message-create message team :room room)))
+               (has-more (not (eq :json-false (plist-get data :has_more)))))
+           (if oldest (slack-room-set-prev-messages room messages)
+             (if latest (slack-room-append-messages room messages)
+               (slack-room-set-messages room messages)))
+           (if (and after-success (functionp after-success))
+               (funcall after-success has-more))))))
+    (slack-request
+     (slack-request-create
+      (slack-room-history-url room)
+      team
+      :params (list (cons "channel" (oref room id))
+                    (if oldest (cons "latest" oldest))
+                    (if latest (cons "oldest" latest))
+                    (cons "count" (number-to-string (or count 100))))
+      :success #'on-request-update))))
+
+(defmethod slack-room-member-p ((this slack-room))
+  t)
+
+(provide 'slack-room)
+;;; slack-room.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room.elc
new file mode 100644
index 000000000000..68e4cb9edd7a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-room.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search-result-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search-result-buffer.el
new file mode 100644
index 000000000000..a24792ff25e5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search-result-buffer.el
@@ -0,0 +1,129 @@
+;;; slack-search-result-buffer.el ---                -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-buffer)
+
+(define-derived-mode slack-search-result-buffer-mode slack-buffer-mode "Slack Search Result"
+  (remove-hook 'lui-post-output-hook 'slack-display-image t))
+
+(defclass slack-search-result-buffer (slack-buffer)
+  ((search-result :initarg :search-result :type slack-search-result)))
+
+(defmethod slack-buffer-name :static ((class slack-search-result-buffer) search-result team)
+  (with-slots (query sort sort-dir) search-result
+    (format "*Slack - %s : Search Result - QUERY: %s, ORDER BY: %s %s"
+            (oref team name)
+            query
+            sort
+            (upcase sort-dir))))
+
+(defmethod slack-buffer-name ((this slack-search-result-buffer))
+  (with-slots (search-result team) this
+    (slack-buffer-name (eieio-object-class-name this) search-result team)))
+
+(defun slack-create-search-result-buffer (search-result team)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-search-result-buffer
+                                             search-result
+                                             team)))
+      buffer
+    (make-instance 'slack-search-result-buffer
+                   :team team
+                   :search-result search-result)))
+
+(defmethod slack-buffer-insert ((this slack-search-result-buffer) match)
+  (with-slots (team) this
+    (let* ((time (slack-ts-to-time (slack-ts match)))
+           (lui-time-stamp-time time)
+           (lui-time-stamp-format "[%Y-%m-%d %H:%M:%S]"))
+      (lui-insert (slack-message-to-string match team) t)
+      (lui-insert "" t))))
+
+(defmethod slack-buffer-has-next-page-p ((this slack-search-result-buffer))
+  (with-slots (search-result) this
+    (slack-search-has-next-page-p search-result)))
+
+(defmethod slack-buffer-insert-history ((this slack-search-result-buffer))
+  (with-slots (team search-result) this
+    (let* ((paging (oref search-result paging))
+           (per-page (oref paging count))
+           (matches (last (oref search-result matches) per-page))
+           (cur-point (point)))
+      (cl-loop for match in matches
+               do (slack-buffer-insert this match))
+      (goto-char cur-point))))
+
+(defmethod slack-buffer-request-history ((this slack-search-result-buffer) after-success)
+  (with-slots (team search-result) this
+    (slack-search-request search-result after-success team
+                          (slack-search-paging-next-page
+                           (oref search-result paging)))))
+
+(defmethod slack-buffer-init-buffer ((this slack-search-result-buffer))
+  (let ((buffer (generate-new-buffer (slack-buffer-name this))))
+    (with-current-buffer buffer
+      (slack-search-result-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (with-slots (search-result) this
+        (let* ((messages (oref search-result matches)))
+          (cl-loop for m in messages
+                   do (slack-buffer-insert this m)))
+        (let ((lui-time-stamp-position nil))
+          (if (slack-search-has-next-page-p search-result)
+              (slack-buffer-insert-load-more this)))))
+
+    (with-slots (search-result team) this
+      (slack-buffer-push-new-3 'slack-search-result-buffer
+                               search-result
+                               team))
+    buffer))
+
+(defmethod slack-buffer-loading-message-end-point ((this slack-search-result-buffer))
+  (previous-single-property-change (point-max)
+                                   'loading-message))
+
+(defmethod slack-buffer-delete-load-more-string ((this slack-search-result-buffer))
+  (let* ((inhibit-read-only t)
+         (loading-message-end
+          (slack-buffer-loading-message-end-point this))
+         (loading-message-start
+          (previous-single-property-change loading-message-end
+                                           'loading-message)))
+    (delete-region loading-message-start
+                   loading-message-end)))
+
+(defmethod slack-buffer-prepare-marker-for-history ((_this slack-search-result-buffer)))
+
+(defmethod slack-buffer-insert--history ((this slack-search-result-buffer))
+  (slack-buffer-insert-history this)
+  (if (slack-buffer-has-next-page-p this)
+      (slack-buffer-insert-load-more this)
+    (let ((lui-time-stamp-position nil))
+      (lui-insert "(no more messages)\n"))))
+
+(provide 'slack-search-result-buffer)
+;;; slack-search-result-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search-result-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search-result-buffer.elc
new file mode 100644
index 000000000000..ea38b58bc333
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search-result-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search.el
new file mode 100644
index 000000000000..3379220754dd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search.el
@@ -0,0 +1,263 @@
+;;; slack-search.el ---                              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2016  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-request)
+
+(defface slack-search-result-message-header-face
+  '((t (:weight bold :height 1.1 :underline t)))
+  "Face used to search message header."
+  :group 'slack)
+;; (:inherit (markdown-code-face font-lock-constant-face))
+(defface slack-search-result-message-username-face
+  '((t (:inherit slack-message-output-header :underline nil)))
+  ""
+  :group 'slack)
+
+(defclass slack-search-paging ()
+  ((count :initarg :count :type number)
+   (total :initarg :total :type number)
+   (page :initarg :page :type number)
+   (pages :initarg :pages :type number)))
+
+(defclass slack-search-result (slack-room)
+  ((query :initarg :query :type string)
+   (sort :initarg :sort :type string)
+   (sort-dir :initarg :sort-dir :type string)
+   (total :initarg :total :type number)
+   (matches :initarg :matches :initform nil :type (or null list))
+   (paging :initarg :paging :type slack-search-paging)))
+
+(defclass slack-file-search-result (slack-search-result) ())
+
+(defclass slack-search-message ()
+  ((message :initarg :message :type slack-message)
+
+   (channel :initarg :channel :type slack-search-message-channel)
+   (user :initarg :user :type string)
+   (username :initarg :username :type string)
+   (permalink :initarg :permalink :type string)
+
+   (previous-2 :initarg :previous-2 :type (or null slack-search-message-around-message) :initform nil)
+   (previous :initarg :previous :type (or null slack-search-message-around-message) :initform nil)
+   (next :initarg :next :type (or null slack-search-message-around-message) :initform nil)
+   (next-2 :initarg :next-2 :type (or null slack-search-message-around-message) :initform nil)))
+
+(defclass slack-search-message-channel ()
+  ((id :initarg :id :type string)
+   (name :initarg :name :type string)))
+
+(defclass slack-search-message-around-message ()
+  ((user :initarg :user :type string)
+   (username :initarg :username :type string)
+   (text :initarg :text :type string)
+   (ts :initarg :ts :type string)
+   (type :initarg :type :type string)))
+
+(defmethod slack-merge ((this slack-search-result) other)
+  (oset this query (oref other query))
+  (oset this sort (oref other sort))
+  (oset this sort-dir (oref other sort-dir))
+  (oset this total (oref other total))
+  (oset this matches (append (oref this matches) (oref other matches)))
+  (oset this paging (oref other paging)))
+
+(defmethod slack-message-to-string ((this slack-search-message) team)
+  (with-slots (channel username) this
+    (let* ((room (slack-room-find (oref channel id) team))
+           (header (propertize (format "%s%s"
+                                       (if (slack-channel-p room)
+                                           "#" "@")
+                                       (slack-room-name room team))
+                               'face 'slack-search-result-message-header-face)))
+      (propertize (format "%s\n%s"
+                          header
+                          (slack-message-to-string (oref this message) team))
+                  'ts (slack-ts this)))))
+
+(defmethod slack-ts ((this slack-search-message))
+  (slack-ts (oref this message)))
+
+(defmethod slack-search-has-next-page-p ((this slack-search-result))
+  (slack-search-paging-next-page (oref this paging)))
+
+(defmethod slack-search-paging-next-page ((this slack-search-paging))
+  (with-slots (pages page) this
+    (unless (< pages (1+ page))
+      (1+ page))))
+
+(defun slack-search-create-message-channel (payload)
+  (and payload
+       (make-instance 'slack-search-message-channel
+                      :id (plist-get payload :id)
+                      :name (plist-get payload :name))))
+
+(defun slack-search-create-around-message (payload)
+  (and payload
+       (make-instance 'slack-search-message-around-message
+                      :user (plist-get payload :user)
+                      :username (plist-get payload :username)
+                      :text (plist-get payload :text)
+                      :ts (plist-get payload :ts)
+                      :type (plist-get payload :type))))
+
+(defun slack-search-create-message (payload team)
+  (setq payload (append payload nil))
+  (let* ((channel (slack-search-create-message-channel
+                   (plist-get payload :channel)))
+         (previous-2 (slack-search-create-around-message
+                      (plist-get payload :previous_2)))
+         (previous (slack-search-create-around-message
+                    (plist-get payload :previous)))
+         (next (slack-search-create-around-message
+                (plist-get payload :next)))
+         (next-2 (slack-search-create-around-message
+                  (plist-get payload :next_2)))
+         (room (slack-room-find (oref channel id) team)))
+
+    (unless (< 0 (length (plist-get payload :user)))
+      (plist-put payload :user nil)
+      (plist-put payload :subtype "bot_message"))
+
+    (make-instance 'slack-search-message
+                   :message (slack-message-create payload team :room room)
+                   :channel channel
+                   :previous-2 previous-2
+                   :previous previous
+                   :next next
+                   :next-2 next-2)))
+
+(defun slack-search-create-paging (payload)
+  (and payload
+       (make-instance 'slack-search-paging
+                      :count (plist-get payload :count)
+                      :total (plist-get payload :total)
+                      :page (plist-get payload :page)
+                      :pages (plist-get payload :pages))))
+
+(defun slack-search-create-result (payload sort sort-dir team)
+  (let* ((messages (plist-get payload :messages))
+         (matches (mapcar #'(lambda (e) (slack-search-create-message e team))
+                          (plist-get messages :matches)))
+         (paging (slack-search-create-paging
+                  (plist-get messages :paging))))
+    (make-instance 'slack-search-result
+                   :query (plist-get payload :query)
+                   :total (plist-get messages :total)
+                   :paging paging
+                   :matches matches
+                   :sort sort
+                   :sort-dir sort-dir)))
+
+(defun slack-search-create-file-result (payload sort sort-dir)
+  (let* ((files (plist-get payload :files))
+         (matches (mapcar #'slack-file-create
+                          (plist-get files :matches)))
+         (paging (slack-search-create-paging
+                  (plist-get files :paging))))
+    (make-instance 'slack-search-result
+                   :query (plist-get payload :query)
+                   :total (plist-get files :total)
+                   :paging paging
+                   :matches matches
+                   :sort sort
+                   :sort-dir sort-dir)))
+
+(defun slack-search-query-params ()
+  (let ((team (slack-team-select))
+        (query (read-from-minibuffer "Query: "))
+        (sort (funcall slack-completing-read-function "Sort: " `("score" "timestamp")
+                       nil t))
+        (sort-dir (funcall slack-completing-read-function "Direction: " `("desc" "asc")
+                           nil t)))
+    (list team query sort sort-dir)))
+
+(defun slack-search-from-messages ()
+  (interactive)
+  (cl-destructuring-bind (team query sort sort-dir) (slack-search-query-params)
+    (let ((instance (make-instance 'slack-search-result
+                                   :sort sort
+                                   :sort-dir sort-dir
+                                   :query query)))
+      (cl-labels
+          ((after-success ()
+                          (let ((buffer (slack-create-search-result-buffer instance team)))
+                            (slack-buffer-display buffer))))
+        (slack-search-request instance #'after-success team)))))
+
+(defun slack-search-from-files ()
+  (interactive)
+  (cl-destructuring-bind (team query sort sort-dir) (slack-search-query-params)
+    (let ((instance (make-instance 'slack-file-search-result
+                                   :sort sort
+                                   :sort-dir sort-dir
+                                   :query query)))
+      (cl-labels
+          ((after-success ()
+                          (let ((buffer (slack-create-search-result-buffer instance team)))
+                            (slack-buffer-display buffer))))
+        (slack-search-request instance #'after-success team)))))
+
+(defmethod slack-search-request-url ((_this slack-search-result))
+  "https://slack.com/api/search.messages")
+
+(defmethod slack-search-request-url ((_this slack-file-search-result))
+  "https://slack.com/api/search.files")
+
+(cl-defmethod slack-search-request ((this slack-search-result)
+                                    after-success team &optional (page 1))
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-search-request")
+                    (let ((search-result
+                           (if (slack-file-search-result-p this)
+                               (slack-search-create-file-result data
+                                                                (oref this sort)
+                                                                (oref this sort-dir))
+                             (slack-search-create-result data
+                                                         (oref this sort)
+                                                         (oref this sort-dir)
+                                                         team))))
+                      (slack-merge this search-result)
+                      (funcall after-success)))))
+    (with-slots (query sort sort-dir) this
+      (if (< 0 (length query))
+          (slack-request
+           (slack-request-create
+            (slack-search-request-url this)
+            team
+            :type "POST"
+            :params (list (cons "query" query)
+                          (cons "sort" sort)
+                          (cons "sort_dir" sort-dir)
+                          (cons "page" (number-to-string page)))
+            :success #'on-success))))))
+
+
+(provide 'slack-search)
+;;; slack-search.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search.elc
new file mode 100644
index 000000000000..907e9c50c4a8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-search.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-selectable.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-selectable.el
new file mode 100644
index 000000000000..a4a04d8a18f2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-selectable.el
@@ -0,0 +1,88 @@
+;;; slack-selectable.el ---                          -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+
+(defclass slack-selectable ()
+  (
+   ;; one of users, channels, conversations, external or static
+   (data-source :initarg :data_source :type string :initform "static")
+   (options :initarg :options :initform nil)
+   (option-groups :initarg :option_groups :initform nil)
+   (selected-options :initarg :selected_options :type (or null list) :initform '())
+   ))
+
+(defclass slack-selectable-option ()
+  ((text :initarg :text :type string)
+   (value :initarg :value :type string)))
+
+(defclass slack-selectable-option-group ()
+  ((text :initarg :text :type string)
+   (options :initarg :options :initform nil)))
+
+(defmethod slack-selectable-text ((this slack-selectable-option))
+  (oref this text))
+
+(defmethod slack-selectable-text ((this slack-selectable-option-group))
+  (oref this text))
+
+(defmethod slack-selectable-select-from-static-data-source ((this slack-selectable))
+  (cl-labels
+      ((select-option (options)
+                      (select (slack-selectable-prompt this)
+                              (mapcar #'(lambda (option)
+                                          (cons (slack-selectable-text option)
+                                                (oref option value)))
+                                      options)))
+       (select-option-group
+        (option-groups)
+        (slack-if-let*
+            ((text (select (slack-selectable-prompt this)
+                           (mapcar #'(lambda (option-group)
+                                       (slack-selectable-text option-group))
+                                   option-groups))))
+            (find-option text option-groups)))
+       (find-option (text options)
+                    (cl-find-if #'(lambda (option)
+                                    (string= text (slack-selectable-text option)))
+                                options))
+       (select (prompt options)
+               (funcall slack-completing-read-function
+                        prompt
+                        options
+                        nil t)))
+    (with-slots (options option-groups) this
+      (slack-if-let*
+          ((options (if option-groups
+                        (oref (select-option-group option-groups)
+                              options)
+                      options))
+           (option-text (select-option options)))
+          (find-option option-text options)))))
+
+(provide 'slack-selectable)
+;;; slack-selectable.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-selectable.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-selectable.elc
new file mode 100644
index 000000000000..f460144295c7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-selectable.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-slash-commands.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-slash-commands.el
new file mode 100644
index 000000000000..4287a3eb9926
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-slash-commands.el
@@ -0,0 +1,164 @@
+;;; slack-slash-commands.el ---                      -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+
+(defclass slack-command ()
+  ((name :initarg :name :type string)
+   (type :initarg :type :type string)
+   (usage :initarg :usage :type string :initform "")
+   (desc :initarg :desc :type string :initform "")
+   (alias-of :initarg :alias_of :type (or null string) :initform nil)))
+
+(defclass slack-core-command (slack-command)
+  ((canonical-name :initarg :canonical_name :type string)))
+
+(defclass slack-app-command (slack-command)
+  ((app :initarg :app :type string)))
+
+(defclass slack-service-command (slack-command)
+  ((service-name :initarg :service_name :type string)))
+
+(defmethod slack-equalp ((this slack-command) other)
+  (string= (oref this name) (oref other name)))
+
+(defun slack-slash-commands-parse (text team)
+  "Return (command . arguments) or nil."
+  (when (string-prefix-p "/" text)
+    (let* ((tokens (split-string text " "))
+           (maybe-command (car tokens))
+           (command (slack-command-find maybe-command team)))
+      (when command
+        (cons command
+              (mapconcat #'identity (cdr tokens) " "))))))
+
+(defun slack-slash-commands-join (team _args)
+  (slack-channel-join team t))
+
+(defun slack-command-create (command)
+  (cl-labels
+      ((slack-core-command-create
+        (payload)
+        (apply #'make-instance 'slack-core-command
+               (slack-collect-slots 'slack-core-command payload)))
+       (slack-app-command-create
+        (payload)
+        (apply #'make-instance 'slack-app-command
+               (slack-collect-slots 'slack-app-command payload)))
+       (slack-service-command-create
+        (payload)
+        (apply #'make-instance 'slack-service-command
+               (slack-collect-slots 'slack-service-command payload))))
+    (let ((type (plist-get command :type)))
+      (cond
+       ((string= type "core")
+        (slack-core-command-create command))
+       ((string= type "app")
+        (slack-app-command-create command))
+       ((string= type "service")
+        (slack-service-command-create command))
+       (t (apply #'make-instance 'slack-command command))))))
+
+(defun slack-command-list-update (&optional team)
+  (interactive)
+  (let ((team (or team (slack-team-select))))
+    (cl-labels
+        ((on-success
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-commands-list-request")
+           (let ((commands (mapcar #'(lambda (command) (slack-command-create command))
+                                   (cl-remove-if-not #'listp
+                                                     (plist-get data :commands)))))
+             (oset team commands commands)
+             (slack-log "Slack Command List Updated" team :level 'info)))))
+      (slack-request
+       (slack-request-create
+        "https://slack.com/api/commands.list"
+        team
+        :type "POST"
+        :success #'on-success)))))
+
+(defun slack-command-find (name team)
+  (let ((commands (oref team commands)))
+    (cl-find-if #'(lambda (command) (string= name
+                                             (oref command name)))
+                commands)))
+
+(defmethod slack-command-company-doc-string ((this slack-command) team)
+  (if (oref this alias-of)
+      (let ((command (slack-command-find (oref this alias-of)
+                                         team)))
+        (when command
+          (slack-command-company-doc-string command team)))
+    (with-slots (usage desc) this
+      (format "%s%s"
+              (or (and (< 0 (length usage))
+                       (format "%s\n" usage))
+                  "")
+              desc))))
+
+(cl-defmethod slack-command-run ((command slack-command) team channel
+                                 &key (text nil))
+  (let ((disp "")
+        (client-token (slack-team-client-token team))
+        (command (oref command name)))
+    (cond
+     ((or (string= command "/join")
+          (string= command "/open")) (error "/join and /open are not supported yet"))
+     (t
+      (cl-labels
+          ((on-success (&key data &allow-other-keys)
+                       (slack-request-handle-error
+                        (data "slack-command-run")
+                        (slack-if-let* ((response (plist-get data :response)))
+                            (slack-if-let*
+                                ((user (slack-user--find "USLACKBOT" team))
+                                 (payload (list :text response
+                                                :is_ephemeral t
+                                                :user (plist-get user :id)
+                                                :id (plist-get user :id)
+                                                :type "message"
+                                                :channel channel
+                                                :ts (number-to-string
+                                                     (time-to-seconds))))
+                                 (message (slack-message-create payload team)))
+                                (slack-message-update message team)
+                              (message "%s" (slack-message-unescape-string response
+                                                                           team)))))))
+        (slack-request
+         (slack-request-create
+          "https://slack.com/api/chat.command"
+          team
+          :params (list (cons "disp" disp)
+                        (cons "client_token" client-token)
+                        (cons "command" command)
+                        (cons "channel" channel)
+                        (when text
+                          (cons "text" text)))
+          :success #'on-success)))))))
+
+(provide 'slack-slash-commands)
+;;; slack-slash-commands.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-slash-commands.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-slash-commands.elc
new file mode 100644
index 000000000000..5b52059a201e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-slash-commands.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-star.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-star.el
new file mode 100644
index 000000000000..fbe3af0c9330
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-star.el
@@ -0,0 +1,250 @@
+;;; slack-stars.el ---                               -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-request)
+
+(defconst slack-stars-list-url "https://slack.com/api/stars.list")
+
+(defclass slack-star ()
+  ((paging :initarg :paging :type slack-star-paging)
+   (items :initarg :items :type (or null list) :initform nil)))
+
+(defclass slack-star-paging ()
+  ((per-page :initarg :per-page :type number)
+   (spill :initarg :spill :type number) ;; ??
+   (total :initarg :total :type number)
+   (page :initarg :page :type number)
+   (pages :initarg :pages :type number)))
+
+(defclass slack-star-item ()
+  ((date-create :initarg :date-create :type string)))
+
+(defclass slack-star-message (slack-star-item)
+  ((channel :initarg :channel :type string)
+   (message :initarg :message :type slack-message)))
+
+(defclass slack-star-file (slack-star-item)
+  ((file :initarg :file :type slack-file)))
+
+(defclass slack-star-channel (slack-star-item) ;; Ch ??
+  ((channel :initarg :channel :type string))) ;; ID
+
+(defclass slack-star-group (slack-star-item) ;; Gh ??
+  ((group :initarg :group :type string))) ;; ID
+
+(defclass slack-star-im (slack-star-item) ;; Dh ??
+  ((channel :initarg :channel :type string))) ;; ID
+
+(defmethod slack-star-item-message ((this slack-star-message))
+  (oref this message))
+
+(defmethod slack-star-item-message ((this slack-star-file))
+  (oref this file))
+
+(defmethod slack-ts ((this slack-star-item))
+  (oref this date-create))
+
+(defmethod slack-next-page ((this slack-star-paging))
+  (with-slots (pages page) this
+    (unless (< pages (1+ page))
+      (1+ page))))
+
+(defmethod slack-star-has-next-page-p ((this slack-star))
+  (slack-next-page (oref this paging)))
+
+(defmethod slack-per-page ((this slack-star-paging))
+  (oref this per-page))
+
+(defmethod slack-star-per-page ((this slack-star))
+  (slack-per-page (oref this paging)))
+
+(defmethod slack-star-items ((this slack-star))
+  (oref this items))
+
+(defmethod slack-merge ((old slack-star) new)
+  (with-slots (paging items) old
+    (setq paging (oref new paging))
+    (setq items (append (oref new items) items))))
+
+(defmethod slack-to-string ((this slack-star-message) team)
+  (with-slots (message) this
+    (slack-message-to-string message team)))
+
+(defmethod slack-to-string ((this slack-star-file) team)
+  (with-slots (date-create file) this
+    (slack-message-to-string file date-create team)))
+
+(defun slack-create-star-paging (payload)
+  ;; (:per_page 20 :spill 0 :page 1 :total 61 :pages 4)
+  (make-instance 'slack-star-paging
+                 :per-page (plist-get payload :per_page)
+                 :spill (plist-get payload :spill)
+                 :page (plist-get payload :page)
+                 :total (plist-get payload :total)
+                 :pages (plist-get payload :pages)
+                 ))
+
+(defun slack-create-star-items (payload team)
+  (mapcar #'(lambda (e) (slack-create-star-item e team))
+          payload))
+
+(defun slack-create-star-item (payload team)
+  (let* ((type (plist-get payload :type))
+         (date-create (format "%s" (plist-get payload :date_create)))
+         (file-payload (plist-get payload :file))
+         (file (and file-payload
+                    (if (or (slack-file-p file-payload)
+                            (slack-file-email-p file-payload))
+                        file-payload
+                      (slack-file-create file-payload))))
+         (file-id (and file (oref file id))))
+    (cond
+     ((string= type "message")
+      (make-instance 'slack-star-message
+                     :date-create date-create
+                     :channel (plist-get payload :channel)
+                     :message (slack-message-create (plist-get payload :message)
+                                                    team)))
+     ((string= type "file")
+      (make-instance 'slack-star-file
+                     :date-create date-create
+                     :file file))
+     ((string= type "channel")
+      (make-instance 'slack-star-channel
+                     :date-create date-create
+                     :channel (plist-get payload :channel)))
+     ((string= type "im")
+      (make-instance 'slack-star-im
+                     :date-create date-create
+                     :channel (plist-get payload :channel)))
+     ((string= type "group")
+      (make-instance 'slack-star-group
+                     :date-create date-create
+                     :group (plist-get payload :group))))))
+
+;; (:per_page 20 :spill 0 :page 1 :total 61 :pages 4)
+(defun slack-create-star-paging (payload)
+  (make-instance 'slack-star-paging
+                 :per-page (plist-get payload :per_page)
+                 :spill (plist-get payload :spill)
+                 :page (plist-get payload :page)
+                 :total (plist-get payload :total)
+                 :pages (plist-get payload :pages)))
+
+(defun slack-create-star (payload team)
+  (let ((items (slack-create-star-items (plist-get payload :items)
+                                        team))
+        (paging (slack-create-star-paging (plist-get payload :paging))))
+    (make-instance 'slack-star
+                   :items (reverse items)
+                   :paging paging)))
+
+(defun slack-stars-list-request (team &optional page after-success)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-stars-list-request")
+                    (let ((star (slack-create-star data team)))
+                      (if (oref team star)
+                          (if page
+                              (slack-merge (oref team star) star)
+                            (oset team star star))
+                        (oset team star star)))
+                    (if after-success
+                        (funcall after-success)))))
+    (slack-request
+     (slack-request-create
+      slack-stars-list-url
+      team
+      :type "POST"
+      :data (list (cons "exclude" "Ch,Gh,Dh")
+                  (cons "count" "20")
+                  (cons "page" (number-to-string (or page 1))))
+      :success #'on-success))))
+
+
+(defun slack-stars-list ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (buf (slack-buffer-find 'slack-stars-buffer team)))
+    (if buf (slack-buffer-display buf)
+      (slack-stars-list-request
+       team nil
+       #'(lambda () (slack-buffer-display (slack-create-stars-buffer team)))))))
+
+(defmethod slack-message-star-api-params ((this slack-star-item))
+  (list (slack-message-star-api-params (slack-star-item-message this))))
+
+(defmethod slack-message-star-api-params ((this slack-star-message))
+  (append (list (cons "channel" (oref this channel)))
+          (call-next-method)))
+
+(defmethod slack-star-remove-star ((this slack-star) ts team)
+  (slack-if-let* ((item (cl-find-if #'(lambda (e) (string= (oref e date-create) ts))
+                              (oref this items))))
+      (slack-message-star-api-request slack-message-stars-remove-url
+                                      (slack-message-star-api-params item)
+                                      team)))
+
+(defmethod slack-star-remove ((this slack-star) payload team)
+  (let ((date-create (format "%s" (plist-get payload :date_create))))
+    (oset this items (cl-remove-if #'(lambda (e) (string= (slack-ts e)
+                                                          date-create))
+                                   (oref this items)))
+    (slack-if-let* ((buffer (slack-buffer-find 'slack-stars-buffer team)))
+        (slack-buffer-message-delete buffer date-create))))
+
+(defmethod slack-star-add ((this slack-star) payload team)
+  (setq payload (append payload nil))
+  (cl-labels
+      ((create-star (payload)
+                    (slack-create-star-item payload team))
+       (append-star-item (item)
+                         (oset this items (append (oref this items) (list item))))
+       (insert-to-buffer (item)
+                         (slack-if-let* ((buffer (slack-buffer-find 'slack-stars-buffer
+                                                                    team)))
+                             (with-current-buffer (slack-buffer-buffer buffer)
+                               (slack-buffer-insert buffer item)))))
+    (if (plist-get payload :file)
+        (cl-labels
+            ((insert-star (payload file)
+                          (let ((item (create-star (plist-put payload :file file))))
+                            (append-star-item item)
+                            (insert-to-buffer item))))
+          (let ((file-id (plist-get (plist-get payload :file) :id)))
+            (slack-if-let* ((file (slack-file-find file-id team)))
+                (insert-star payload file)
+              (slack-file-request-info file-id 1 team
+                                       #'(lambda (file _team)
+                                           (insert-star payload file))))))
+      (let ((item (create-star payload)))
+        (append-star-item item)
+        (insert-to-buffer item)))))
+
+(provide 'slack-star)
+;;; slack-stars.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-star.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-star.elc
new file mode 100644
index 000000000000..04ad4e22f5d4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-star.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-stars-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-stars-buffer.el
new file mode 100644
index 000000000000..ed87b6530521
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-stars-buffer.el
@@ -0,0 +1,140 @@
+;;; slack-stars-buffer.el ---                        -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-team)
+(require 'slack-buffer)
+
+(define-derived-mode slack-stars-buffer-mode slack-buffer-mode "Slack Stars Buffer")
+
+(defclass slack-stars-buffer (slack-buffer)
+  ((oldest :type string :initform "")))
+
+(defmethod slack-buffer-name :static ((_class slack-stars-buffer) team)
+  (format "*Slack - %s : Stars*" (oref team name)))
+
+(defmethod slack-buffer-name ((this slack-stars-buffer))
+  (slack-buffer-name 'slack-stars-buffer (oref this team)))
+
+(defmethod slack-buffer-find :static ((class slack-stars-buffer) team)
+  (slack-if-let* ((buf (cl-find-if #'(lambda (e) (string= (buffer-name e)
+                                                    (slack-buffer-name class team)))
+                             (slot-value team class))))
+      (with-current-buffer buf slack-current-buffer)))
+
+(defmethod slack-buffer-insert ((this slack-stars-buffer) item &optional not-tracked-p)
+  (let ((lui-time-stamp-time (seconds-to-time
+                              (string-to-number
+                               (slack-ts
+                                (slack-star-item-message item))))))
+    (lui-insert-with-text-properties
+     (slack-to-string item (oref this team))
+     'ts (slack-ts item)
+     'not-tracked-p not-tracked-p)
+    (lui-insert "" t)))
+
+(defmethod slack-buffer-has-next-page-p ((this slack-stars-buffer))
+  (with-slots (team) this
+    (slack-star-has-next-page-p (oref team star))))
+
+(defmethod slack-buffer-insert-history ((this slack-stars-buffer))
+  (with-slots (team) this
+    (let ((items (slack-star-items (oref team star)))
+          (before-oldest (oref this oldest)))
+      (oset this oldest (slack-ts (car items)))
+      (cl-loop for item in items
+               do (and (string< (slack-ts item) before-oldest)
+                       (slack-buffer-insert this item t)))
+
+      (slack-if-let* ((point (slack-buffer-ts-eq (point-min)
+                                           (point-max)
+                                           before-oldest)))
+          (goto-char point)))))
+
+(defmethod slack-buffer-request-history ((this slack-stars-buffer) after-success)
+  (with-slots (team) this
+    (slack-stars-list-request team
+                              (slack-next-page (oref (oref team star) paging))
+                              after-success)))
+
+
+(defmethod slack-buffer-update-oldest ((this slack-stars-buffer) item)
+  (when (string< (oref this oldest) (slack-ts item))
+    (oset this oldest (slack-ts item))))
+
+(defmethod slack-buffer-init-buffer ((this slack-stars-buffer))
+  (let* ((buf (generate-new-buffer (slack-buffer-name this)))
+         (star (oref (oref this team) star))
+         (items (slack-star-items star))
+         (oldest-message (car items)))
+    (when oldest-message
+      (slack-buffer-update-oldest this oldest-message))
+    (with-current-buffer buf
+      (slack-stars-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (slack-buffer-insert-load-more this)
+      (with-slots (star) (oref this team)
+        (cl-loop for m in (oref star items)
+                 do (slack-buffer-insert this m)))
+      (goto-char (point-max)))
+    (unless (oref (oref this team) slack-stars-buffer)
+      (push buf (oref (oref this team) slack-stars-buffer)))
+    buf))
+
+(defun slack-create-stars-buffer (team)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-stars-buffer team)))
+      buf
+    (make-instance 'slack-stars-buffer
+                   :team team)))
+
+(defmethod slack-buffer-remove-star ((this slack-stars-buffer) ts)
+  (with-slots (team) this
+    (with-slots (star) team
+      (slack-star-remove-star star ts team))))
+
+(defmethod slack-buffer-message-delete ((this slack-stars-buffer) ts)
+  (let ((buffer (slack-buffer-buffer this))
+        (inhibit-read-only t))
+    (with-current-buffer buffer
+      (slack-if-let* ((beg (slack-buffer-ts-eq (point-min) (point-max) ts))
+                      (end (next-single-property-change beg 'ts)))
+          (delete-region beg end)))))
+
+(defmethod slack-buffer--replace ((this slack-stars-buffer) ts)
+  (with-slots (team) this
+    (with-slots (star) team
+      (let* ((items (slack-star-items star))
+             (item (cl-find-if #'(lambda (e) (string= (slack-ts e)
+                                                      ts))
+                               items)))
+        (lui-replace (slack-to-string item team)
+                     #'(lambda ()
+                         (string= (get-text-property (point) 'ts)
+                                  ts)))))))
+
+(provide 'slack-stars-buffer)
+;;; slack-stars-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-stars-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-stars-buffer.elc
new file mode 100644
index 000000000000..61dd3bef92cc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-stars-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-team.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-team.el
new file mode 100644
index 000000000000..abb0ac77288c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-team.el
@@ -0,0 +1,324 @@
+;;; slack-team.el ---  team class                    -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2016  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-util)
+
+(defvar slack-teams nil)
+(defvar slack-current-team nil)
+(defcustom slack-prefer-current-team nil
+  "If set to t, using `slack-current-team' for interactive function.
+use `slack-change-current-team' to change `slack-current-team'"
+  :group 'slack)
+
+(defcustom slack-modeline-count-only-subscribed-channel t
+  "Count unread only subscribed channel."
+  :group 'slack)
+
+(defclass slack-team-threads ()
+  ((initializedp :initform nil)
+   (has-more :initform t)
+   (total-unread-replies :initform 0 :type number)
+   (new-threads-count :initform 0 :type number)))
+
+(defclass slack-team ()
+  ((id :initarg :id)
+   (token :initarg :token :initform nil)
+   (client-id :initarg :client-id)
+   (client-secret :initarg :client-secret)
+   (name :initarg :name :initform nil)
+   (domain :initarg :domain)
+   (self :initarg :self)
+   (self-id :initarg :self-id)
+   (self-name :initarg :self-name)
+   (channels :initarg :channels :initform nil)
+   (groups :initarg :groups :initform nil)
+   (ims :initarg :ims :initform nil)
+   (file-room :initform nil)
+   (search-results :initform nil)
+   (users :initarg :users :initform nil)
+   (bots :initarg :bots :initform nil)
+   (ws-url :initarg :ws-url)
+   (ws-conn :initarg :ws-conn :initform nil)
+   (ping-timer :initform nil)
+   (check-ping-timeout-timer :initform nil)
+   (check-ping-timeout-sec :initarg :check-ping-timeout-sec :initform 20)
+   (reconnect-auto :initarg :reconnect-auto :initform t)
+   (reconnect-timer :initform nil)
+   (reconnect-after-sec :initform 10)
+   (reconnect-count :initform 0)
+   (reconnect-count-max :initform 360)
+   (last-pong :initform nil)
+   (waiting-send :initform nil)
+   (sent-message :initform (make-hash-table))
+   (message-id :initform 0)
+   (connected :initform nil)
+   (subscribed-channels :initarg :subscribed-channels
+                        :type list :initform nil)
+   (typing :initform nil)
+   (typing-timer :initform nil)
+   (reminders :initform nil :type list)
+   (ping-check-timers :initform (make-hash-table :test 'equal))
+   (threads :type slack-team-threads :initform (make-instance 'slack-team-threads))
+   (modeline-enabled :initarg :modeline-enabled :initform nil)
+   (modeline-name :initarg :modeline-name :initform nil)
+   (websocket-event-log-enabled :initarg :websocket-event-log-enabled :initform nil)
+   (display-profile-image :initarg :display-profile-image :initform nil)
+   (display-attachment-image-inline :initarg :display-attachment-image-inline :initform nil)
+   (display-file-image-inline :initarg :display-file-image-inline :initform nil)
+   (waiting-requests :initform nil)
+   (authorize-request :initform nil)
+   (emoji-download-watch-timer :initform nil)
+   (websocket-nowait :initarg :websocket-nowait :initform nil)
+   (star :initform nil)
+   (slack-message-buffer :initform nil :type (or null list))
+   (slack-file-info-buffer :initform nil :type (or null list))
+   (slack-file-list-buffer :initform nil :type (or null list))
+   (slack-message-edit-buffer :initform nil :type (or null list))
+   (slack-pinned-items-buffer :initform nil :type (or null list))
+   (slack-user-profile-buffer :initform nil :type (or null list))
+   (slack-thread-message-buffer :initform nil :type (or null list))
+   (slack-message-share-buffer :initform nil :type (or null list))
+   (slack-room-message-compose-buffer :initform nil :type (or null list))
+   (slack-thread-message-compose-buffer :initform nil :type (or null list))
+   (slack-stars-buffer :initform nil :type (or null list))
+   (slack-search-result-buffer :initform nil :type (or null list))
+   (slack-dialog-buffer :initform nil :type (or null list))
+   (slack-dialog-edit-element-buffer :initform nil :type (or null list))
+   (slack-room-info-buffer :initform nil :type (or null list))
+   (reconnect-url :initform "" :type string)
+   (full-and-display-names :initarg :full-and-display-names :initform nil)
+   (websocket-connect-timeout-timer :initform nil)
+   (websocket-connect-timeout-sec :type number :initform 20) ;; websocket url is valid for 30 seconds.
+   (mark-as-read-immediately :initarg :mark-as-read-immediately :initform t)
+   (inhibit-reconnection :initform nil)
+   (commands :initform '() :type list)
+   ))
+
+(cl-defmethod slack-team-kill-buffers ((this slack-team) &key (except nil))
+  (let* ((l (list 'slack-message-buffer
+                  'slack-file-info-buffer
+                  'slack-file-list-buffer
+                  'slack-message-edit-buffer
+                  'slack-pinned-items-buffer
+                  'slack-user-profile-buffer
+                  'slack-thread-message-buffer
+                  'slack-message-share-buffer
+                  'slack-room-message-compose-buffer
+                  'slack-thread-message-compose-buffer
+                  'slack-search-result-buffer
+                  'slack-stars-buffer))
+         (slots (cl-remove-if #'(lambda (e) (cl-find e except)) l)))
+    (cl-loop for slot in slots
+             do (cl-loop for buffer in (slot-value this slot)
+                         do (kill-buffer buffer)))))
+
+(defun slack-team-find (id)
+  (cl-find-if #'(lambda (team) (string= id (oref team id)))
+              slack-teams))
+
+(defmethod slack-team-disconnect ((team slack-team))
+  (slack-ws-close team))
+
+(defmethod slack-team-equalp ((team slack-team) other)
+  (with-slots (token) team
+    (string= token (oref other token))))
+
+(defmethod slack-team-name ((team slack-team))
+  (oref team name))
+
+;;;###autoload
+(defun slack-register-team (&rest plist)
+  "PLIST must contain :name :client-id :client-secret with value.
+setting :token will reduce your configuration step.
+you will notified when receive message with channel included in subscribed-channels.
+if :default is t and `slack-prefer-current-team' is t, skip selecting team when channels listed.
+you can change current-team with `slack-change-current-team'"
+  (interactive
+   (let ((name (read-from-minibuffer "Team Name: "))
+         (client-id (read-from-minibuffer "Client Id: "))
+         (client-secret (read-from-minibuffer "Client Secret: "))
+         (token (read-from-minibuffer "Token: ")))
+     (list :name name :client-id client-id :client-secret client-secret
+           :token token)))
+  (cl-labels ((same-client-id
+               (client-id)
+               (cl-find-if #'(lambda (team)
+                               (string= client-id (oref team client-id)))
+                           slack-teams))
+              (missing (plist)
+                       (cl-remove-if
+                        #'null
+                        (mapcar #'(lambda (key)
+                                    (unless (plist-member plist key)
+                                      key))
+                                '(:name :client-id :client-secret)))))
+    (let ((missing (missing plist)))
+      (if missing
+          (error "Missing Keyword: %s" missing)))
+    (let ((team (apply #'slack-team "team"
+                       (slack-collect-slots 'slack-team plist))))
+      (let ((same-team (cl-find-if
+                        #'(lambda (o) (slack-team-equalp team o))
+                        slack-teams)))
+        (if same-team
+            (progn
+              (slack-team-disconnect same-team)
+              (slack-start team))))
+
+      (setq slack-teams
+            (cons team
+                  (cl-remove-if #'(lambda (other)
+                                    (slack-team-equalp team other))
+                                slack-teams)))
+      (if (plist-get plist :default)
+          (setq slack-current-team team)))))
+
+(defun slack-team-find-by-name (name)
+  (if name
+      (cl-find-if #'(lambda (team) (string= name (oref team name)))
+                  slack-teams)))
+
+(cl-defun slack-team-select (&optional no-default include-not-connected)
+  (cl-labels ((select-team ()
+                           (slack-team-find-by-name
+                            (funcall slack-completing-read-function
+                                     "Select Team: "
+                                     (mapcar #'(lambda (team) (oref team name))
+                                             (if include-not-connected
+                                                 slack-teams
+                                               (slack-team-connected-list)))))))
+    (let ((team (if (and slack-prefer-current-team
+                         slack-current-team
+                         (not no-default))
+                    slack-current-team
+                  (select-team))))
+      ;; (if (and slack-prefer-current-team
+      ;;          (not slack-current-team)
+      ;;          (not no-default))
+      ;;     (if (yes-or-no-p (format "Set %s to current-team?"
+      ;;                              (oref team name)))
+      ;;         (setq slack-current-team team)))
+      team)))
+
+(defmethod slack-team-connectedp ((team slack-team))
+  (oref team connected))
+
+(defun slack-team-connected-list ()
+  (cl-remove-if #'null
+                (mapcar #'(lambda (team)
+                            (if (slack-team-connectedp team) team))
+                        slack-teams)))
+
+(defun slack-change-current-team ()
+  (interactive)
+  (let ((team (slack-team-find-by-name
+               (funcall slack-completing-read-function
+                        "Select Team: "
+                        (mapcar #'(lambda (team) (oref team name))
+                                slack-teams)))))
+    (setq slack-current-team team)
+    (message "Set slack-current-team to %s" (or (and team (oref team name))
+                                                "nil"))
+    (setq slack-teams
+          (cons team (cl-remove-if #'(lambda (e)
+                                       (string= (oref e id)
+                                                (oref slack-current-team id)))
+                                   slack-teams)))
+    (if team
+        (slack-team-connect team))))
+
+(defmethod slack-team-connect ((team slack-team))
+  (unless (slack-team-connectedp team)
+    (slack-start team)))
+
+(defun slack-team-delete ()
+  (interactive)
+  (let ((selected (slack-team-select t t)))
+    (if (yes-or-no-p (format "Delete %s from `slack-teams'?"
+                             (oref selected name)))
+        (progn
+          (setq slack-teams
+                (cl-remove-if #'(lambda (team)
+                                  (slack-team-equalp selected team))
+                              slack-teams))
+          (slack-team-disconnect selected)
+          (message "Delete %s from `slack-teams'" (oref selected name))))))
+
+(defmethod slack-team-init-ping-check-timers ((team slack-team))
+  (oset team ping-check-timers (make-hash-table :test 'equal)))
+
+(defmethod slack-team-get-ping-check-timers ((team slack-team))
+  (if (not (slot-boundp team 'ping-check-timers))
+      (slack-team-init-ping-check-timers team))
+  (oref team ping-check-timers))
+
+(defmethod slack-team-need-token-p ((team slack-team))
+  (with-slots (token) team
+    (or (not token) (< (length token) 1))))
+
+(defun slack-team-get-unread-messages (team)
+  (cl-labels
+      ((count-unread (rooms)
+                     (cl-reduce #'(lambda (a e) (+ a (oref e unread-count-display)))
+                                rooms :initial-value 0)))
+    (with-slots (ims channels groups) team
+      (let ((rooms (append ims channels groups)))
+        (+ (count-unread (if slack-modeline-count-only-subscribed-channel
+                             (cl-remove-if-not #'(lambda (e) (slack-room-subscribedp e team))
+                                               rooms)
+                           rooms)))))))
+
+(defun slack-team-modeline-enabledp (team)
+  (oref team modeline-enabled))
+
+(defmethod slack-team-event-log-enabledp ((team slack-team))
+  (oref team websocket-event-log-enabled))
+
+(defmethod slack-team-display-profile-imagep ((team slack-team))
+  (oref team display-profile-image))
+
+(defmethod slack-team-display-attachment-image-inlinep ((team slack-team))
+  (oref team display-attachment-image-inline))
+
+(defmethod slack-team-display-file-image-inlinep ((team slack-team))
+  (oref team display-file-image-inline))
+
+(defmethod slack-team-mark-as-read-immediatelyp ((team slack-team))
+  (oref team mark-as-read-immediately))
+
+(defvar slack-team-random-numbers-for-client-token
+  (let ((result nil))
+    (dotimes (_ 10)
+      (push (random 10) result))
+    (mapconcat #'number-to-string result "")))
+
+(defmethod slack-team-client-token ((team slack-team))
+  (format "EmacsSlack-%s-%s"
+          (oref team id)
+          slack-team-random-numbers-for-client-token))
+
+(provide 'slack-team)
+;;; slack-team.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-team.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-team.elc
new file mode 100644
index 000000000000..8e09ae2b86f1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-team.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-buffer.el
new file mode 100644
index 000000000000..6ad6e5a93e42
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-buffer.el
@@ -0,0 +1,148 @@
+;;; slack-thread-message-buffer.el ---               -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-room-buffer)
+
+(define-derived-mode slack-thread-message-buffer-mode
+  slack-buffer-mode
+  "Slack Thread Message"
+  (lui-set-prompt lui-prompt-string)
+  (setq lui-input-function 'slack-thread-message--send))
+
+(defclass slack-thread-message-buffer (slack-room-buffer)
+  ((thread-ts :initarg :thread-ts :type string)))
+
+(defmethod slack-buffer-find :static ((class slack-thread-message-buffer) room ts team)
+  (slack-buffer-find-4 class room ts team))
+
+(defun slack-create-thread-message-buffer (room team thread-ts)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-thread-message-buffer
+                                          room thread-ts team)))
+      buf
+    (slack-thread-message-buffer :room room
+                                 :team team
+                                 :thread-ts thread-ts)))
+
+(defmethod slack-buffer-name :static ((class slack-thread-message-buffer) room ts team)
+  (format "*Slack - %s : %s Thread - %s"
+          (oref team name)
+          (slack-room-name room team)
+          ts))
+
+(defmethod slack-buffer-name ((this slack-thread-message-buffer))
+  (with-slots (room thread-ts team) this
+    (slack-buffer-name 'slack-thread-message-buffer
+                       room thread-ts team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-thread-message-buffer))
+  (let* ((buf (generate-new-buffer (slack-buffer-name this))))
+    (with-current-buffer buf
+      (slack-thread-message-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (goto-char lui-input-marker)
+      (with-slots (room thread-ts team) this
+        (slack-if-let* ((message (slack-room-find-message room thread-ts)))
+            (progn
+              (slack-buffer-insert this message t)
+              (let ((lui-time-stamp-position nil))
+                (lui-insert (format "%s\n" (make-string lui-fill-column ?=)) t))
+              (let ((thread (slack-message-thread message room)))
+                (and thread
+                     (cl-loop for m in (oref thread messages)
+                              do (slack-buffer-insert this m))))))))
+
+    (with-slots (room thread-ts team) this
+      (slack-buffer-push-new-4 (eieio-object-class-name this)
+                               room
+                               thread-ts
+                               team))
+
+    buf))
+
+(defmethod slack-buffer-display-message-compose-buffer
+  ((this slack-thread-message-buffer))
+  (with-slots (room team thread-ts) this
+    (let ((buf (slack-create-thread-message-compose-buffer
+                room thread-ts team)))
+      (slack-buffer-display buf))))
+
+
+(defmethod slack-buffer-send-message ((this slack-thread-message-buffer) message)
+  (with-slots (room team thread-ts) this
+    (slack-thread-send-message room team message thread-ts)))
+
+(defmethod slack-buffer-add-reaction-to-message
+  ((this slack-thread-message-buffer) reaction ts)
+  (with-slots (room team) this
+    (slack-message-reaction-add reaction ts room team)))
+
+(defmethod slack-buffer-remove-reaction-from-message
+  ((this slack-thread-message-buffer) ts)
+  (with-slots (room team) this
+    (let* ((message (slack-room-find-message room ts))
+           (reaction (slack-message-reaction-select
+                      (slack-message-reactions message))))
+      (slack-message-reaction-remove reaction ts room team))))
+
+(defmethod slack-buffer-add-star ((this slack-thread-message-buffer) ts)
+  (with-slots (room team) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (slack-message-star-api-request slack-message-stars-add-url
+                                        (list (cons "channel" (oref room id))
+                                              (slack-message-star-api-params message))
+                                        team))))
+
+(defmethod slack-buffer-remove-star ((this slack-thread-message-buffer) ts)
+  (with-slots (room team) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (slack-message-star-api-request slack-message-stars-remove-url
+                                        (list (cons "channel" (oref room id))
+                                              (slack-message-star-api-params message))
+                                        team))))
+
+(cl-defmethod slack-buffer-update ((this slack-thread-message-buffer) message &key replace)
+  (if replace (slack-buffer-replace this message)
+    (with-current-buffer (slack-buffer-buffer this)
+      (slack-buffer-insert this message))))
+
+(defmethod slack-buffer-display-edit-message-buffer ((this slack-thread-message-buffer) ts)
+  (with-slots (room team) this
+    (let ((buf (slack-create-edit-message-buffer room team ts)))
+      (slack-buffer-display buf))))
+
+(defmethod slack-buffer-share-message ((this slack-thread-message-buffer) ts)
+  (with-slots (room team) this
+    (let ((buf (slack-create-message-share-buffer room team ts)))
+      (slack-buffer-display buf))))
+
+(defmethod slack-file-upload-params ((this slack-thread-message-buffer))
+  (list (cons "thread_ts" (oref this thread-ts))
+        (cons "channels" (oref (oref this room) id))))
+
+(provide 'slack-thread-message-buffer)
+;;; slack-thread-message-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-buffer.elc
new file mode 100644
index 000000000000..0b1a149cc504
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-compose-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-compose-buffer.el
new file mode 100644
index 000000000000..4c4f276d1fe5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-compose-buffer.el
@@ -0,0 +1,79 @@
+;;; slack-thread-message-compose-buffer.el ---       -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-message-compose-buffer)
+
+(defclass slack-thread-message-compose-buffer (slack-message-compose-buffer)
+  ((room :initarg :room :type slack-room)
+   (thread-ts :initarg :thread-ts :type string)))
+
+(defmethod slack-buffer-find :static ((class slack-thread-message-compose-buffer) room ts team)
+  (slack-buffer-find-4 class room ts team))
+
+(defmethod slack-buffer-name :static
+  ((class slack-thread-message-compose-buffer) room ts team)
+  (format "*Slack - %s : %s Compose Thread Message - %s*"
+          (oref team name)
+          (slack-room-name room team)
+          ts))
+
+(defmethod slack-buffer-name ((this slack-thread-message-compose-buffer))
+  (with-slots (room thread-ts team) this
+    (slack-buffer-name 'slack-thread-message-compose-buffer
+                       room thread-ts team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-thread-message-compose-buffer))
+  (let ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-message-compose-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (setq buffer-read-only nil)
+      (erase-buffer))
+    (with-slots (room thread-ts team) this
+      (slack-buffer-push-new-4 'slack-thread-message-compose-buffer
+                               room thread-ts team))
+    buf))
+
+(defun slack-create-thread-message-compose-buffer (room ts team)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-thread-message-compose-buffer
+                                    room ts team)))
+      buf
+    (slack-thread-message-compose-buffer :room room
+                                         :team team
+                                         :thread-ts ts)))
+
+(defmethod slack-buffer-send-message
+  ((this slack-thread-message-compose-buffer) message)
+  (let ((buffer (slack-buffer-buffer this)))
+    (with-slots (room team thread-ts) this
+      (slack-thread-send-message room team message thread-ts)))
+  (call-next-method))
+
+
+(provide 'slack-thread-message-compose-buffer)
+;;; slack-thread-message-compose-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-compose-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-compose-buffer.elc
new file mode 100644
index 000000000000..a9a504d44dfb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread-message-compose-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread.el
new file mode 100644
index 000000000000..2a9c6f98a8a0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread.el
@@ -0,0 +1,333 @@
+;;; slack-thread.el ---                              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'lui)
+(require 'slack-util)
+(require 'slack-room)
+(require 'slack-channel)
+(require 'slack-im)
+(require 'slack-message)
+(require 'slack-request)
+
+(defvar lui-prompt-string "> ")
+(defconst all-threads-url "https://slack.com/api/subscriptions.thread.getView")
+(defconst thread-mark-url "https://slack.com/api/subscriptions.thread.mark")
+
+(defcustom slack-thread-also-send-to-room 'ask
+  "Whether a thread message should also be sent to its room.
+If nil: don't send to the room.
+If `ask': ask the user every time.
+Any other non-nil value: send to the room."
+  :type '(choice (const :tag "Never send message to the room." nil)
+                 (const :tag "Ask the user every time." ask)
+                 (const :tag "Always send message to the room." t)))
+
+(define-derived-mode slack-thread-mode slack-mode "Slack - Thread"
+  ""
+  (lui-set-prompt lui-prompt-string)
+  (setq lui-input-function 'slack-thread-message--send))
+
+(defclass slack-thread ()
+  ((thread-ts :initarg :thread_ts :initform "")
+   (messages :initarg :messages :initform '())
+   (has-unreads :initarg :has_unreads :initform nil)
+   (mention-count :initarg :mention_count :initform 0)
+   (reply-count :initarg :reply_count :initform 0)
+   (replies :initarg :replies :initform '())
+   (active :initarg :active :initform t)
+   (root :initarg :root :type slack-message)
+   (unread-count :initarg :unread_count :initform 0)
+   (last-read :initarg :last_read :initform "0")))
+
+(defmethod slack-thread-messagep ((m slack-message))
+  (if (and (oref m thread-ts) (not (slack-message-thread-parentp m)))
+      t
+    nil))
+
+(defun slack-thread-start ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-start-thread buf (slack-get-ts))))
+
+(defun slack-thread-message--send (message)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-send-message buf message)))
+
+(defun slack-thread-send-message (room team message thread-ts)
+  (let ((message (slack-message-prepare-links
+                  (slack-escape-message message)
+                  team))
+        (broadcast (if (eq slack-thread-also-send-to-room 'ask)
+                       (y-or-n-p (format "Also send to %s ? "
+                                         (slack-room-name room team)))
+                     slack-thread-also-send-to-room)))
+    (progn
+      (slack-message-inc-id team)
+      (with-slots (message-id sent-message self-id) team
+        (let* ((payload (list :id message-id
+                              :channel (oref room id)
+                              :reply_broadcast broadcast
+                              :thread_ts thread-ts
+                              :type "message"
+                              :user self-id
+                              :text message))
+               (obj (slack-message-create payload team :room room)))
+          (slack-ws-send payload team)
+          (puthash message-id obj sent-message))))))
+
+(defun slack-thread-show-or-create ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (if (slack-thread-message-buffer-p buf)
+          (error "Already in thread")
+        (slack-buffer-display-thread buf (slack-get-ts)))))
+
+(cl-defmethod slack-thread-request-messages ((thread slack-thread) room team &key after-success)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-thread-request-messages")
+                    (let ((messages (mapcar #'(lambda (payload)
+                                                (slack-message-create payload
+                                                                      team
+                                                                      :room room))
+                                            (plist-get data :messages))))
+                      (oset thread messages
+                            (slack-room-sort-messages
+                             (cl-remove-if #'slack-message-thread-parentp
+                                           messages)))))
+                   (if after-success
+                       (funcall after-success))))
+
+    (slack-request
+     (slack-request-create
+      (slack-room-replies-url room)
+      team
+      :params (list (cons "thread_ts" (oref thread thread-ts))
+                    (cons "channel" (oref room id)))
+      :success #'on-success))))
+
+(defmethod slack-thread-show-messages ((thread slack-thread) room team)
+  (cl-labels
+      ((after-success ()
+                      (let ((buf (slack-create-thread-message-buffer
+                                  room team (oref thread thread-ts))))
+                        (slack-buffer-display buf))))
+    (slack-thread-request-messages thread room team
+                                   :after-success #'after-success)))
+
+(defmethod slack-thread-to-string ((m slack-message) team)
+  (with-slots (thread) m
+    (if thread
+        (let* ((usernames (mapconcat #'identity
+                                     (cl-remove-duplicates
+                                      (mapcar #'(lambda (reply)
+                                                  (slack-user-name
+                                                   (plist-get reply :user)
+                                                   team))
+                                              (oref thread replies))
+                                      :test #'string=)
+                                     " "))
+               (text (format "\n%s reply from %s"
+                             (oref thread reply-count)
+                             usernames)))
+          (propertize text
+                      'face '(:underline t)
+                      'keymap (let ((map (make-sparse-keymap)))
+                                (define-key map [mouse-1] #'slack-thread-show-or-create)
+                                (define-key map (kbd "RET") #'slack-thread-show-or-create)
+                                map)))
+      "")))
+
+(defmethod slack-thread-create ((m slack-message) team &optional payload)
+  (if payload
+      (let ((replies (plist-get payload :replies))
+            (reply-count (plist-get payload :reply_count))
+            (unread-count (plist-get payload :unread_count))
+            (last-read (plist-get payload :last_read)))
+        (make-instance 'slack-thread
+                       :thread_ts (slack-ts m)
+                       :root m
+                       :replies replies
+                       :reply_count (or reply-count 0)
+                       :unread_count (or unread-count 1)
+                       :last_read last-read))
+    (make-instance 'slack-thread
+                   :thread_ts (slack-ts m)
+                   :root m)))
+
+(defmethod slack-merge ((old slack-thread) new)
+  (oset old replies (oref new replies))
+  (oset old reply-count (oref new reply-count))
+  (oset old unread-count (oref new unread-count)))
+
+(defun slack-thread-update-state (payload team)
+  (slack-if-let* ((message-payload (plist-get payload :message))
+                  (thread-ts (plist-get message-payload :thread_ts))
+                  (room (slack-room-find (plist-get payload :channel) team))
+                  (message (slack-room-find-message room thread-ts))
+                  (thread (slack-message-get-thread message team))
+                  (new-thread (slack-thread-create message team message-payload)))
+      (progn
+        (slack-merge thread new-thread)
+        (slack-message-update message team t t))
+    (message "THREAD_TS: %s, ROOM: %s, MESSAGE: %s THREAD: %s, NEW_THREAD:%s"
+             thread-ts
+             (not (null room))
+             (not (null message))
+             (not (null thread))
+             (not (null new-thread)))))
+
+(defmethod slack-thread-equal ((thread slack-thread) other)
+  (and (string-equal (oref thread thread-ts)
+                     (oref other thread-ts))
+       (string-equal (oref (oref thread root) channel)
+                     (oref (oref other root) channel))))
+
+(cl-defun slack-thread-get-all (&key (sync nil) (ts nil))
+  (let ((team (slack-team-select)))
+    (cl-labels
+        ((on-success (&key data &allow-other-keys)
+                     (slack-request-handle-error
+                      (data "slack-thread-get-all")
+                      (let ((threads-data (append (plist-get data :threads) nil))
+                            (total-unread (plist-get data :total_unread_replies))
+                            (more (if (eq :json-false (plist-get data :has_more)) nil t))
+                            (new-count (plist-get data :new_threads_count)))
+                        (with-slots (threads) team
+                          (with-slots
+                              (initializedp total-unread-replies new-threads-count has-more) threads
+                            (setq has-more more)
+                            (setq initializedp t)
+                            (setq total-unread-replies total-unread)
+                            (setq new-threads-count new-count)
+                            (let ((parents (cl-loop for thread in threads-data
+                                                    collect (slack-message-create
+                                                             (plist-get thread :root_msg) team))))
+                              (mapc #'(lambda (parent) (slack-message-update parent team nil t))
+                                    parents))))))))
+      (slack-request
+       (slack-request-create
+        all-threads-url
+        team
+        :type "POST"
+        :params (list (cons "limit" "10")
+                      (cons "current_ts" (or ts (format-time-string "%s"))))
+        :success #'on-success)))))
+
+(defmethod slack-thread-title ((thread slack-thread) team)
+  (with-slots (root) thread
+    (let ((room (slack-room-find (oref root channel) team))
+          (body (slack-message-body root team)))
+      (when room
+        (format "%s - %s" (slack-room-name room team)
+                (concat (substring body 0 (min 50 (length body))) "..."))))))
+
+(defun slack-thread-select (&optional reload)
+  (interactive)
+  (cl-labels
+      ((load-threads (threads)
+                     (slack-thread-get-all :sync t
+                                           :ts (cl-first
+                                                (cl-sort
+                                                 (mapcar #'(lambda (thread) (oref thread thread-ts)) threads)
+                                                 #'string<))))
+       (select-thread (threads team has-more)
+                      (let* ((alist (cl-remove-if-not
+                                     #'(lambda (cons) (car cons))
+                                     (mapcar #'(lambda (thread)
+                                                 (let ((title (slack-thread-title thread team)))
+                                                   (and title (cons title thread))))
+                                             threads)))
+                             (maybe-has-more (if has-more
+                                                 (append alist (list (cons "(load more)" 'load-more))) alist))
+                             (selected (slack-select-from-list (maybe-has-more "Select Thread: "))))
+                        selected))
+       (collect-thread-parents (messages)
+                               (mapcar #'(lambda (m) (oref m thread))
+                                       (cl-remove-if #'(lambda (m) (not (slack-message-thread-parentp m)))
+                                                     messages)))
+       (collect-threads (team)
+                        (cl-loop for room in (with-slots (groups ims channels) team
+                                               (append ims groups channels))
+                                 append (collect-thread-parents (oref room messages)))))
+
+    (let* ((team (slack-team-select)))
+
+      (with-slots (initializedp has-more) (oref team threads)
+        (if (or (not initializedp) has-more) (load-threads (collect-threads team))))
+
+      (let ((selected (select-thread (collect-threads team) team nil)))
+        (if (eq selected 'load-more)
+            (slack-thread-select t)
+          (slack-thread-show-messages selected
+                                      (slack-room-find (oref (oref selected root) channel) team)
+                                      team))))))
+
+(defmethod slack-thread-delete-message ((thread slack-thread) message)
+  (with-slots (messages reply-count) thread
+    (setq messages (cl-remove-if #'(lambda (e)
+                                     (string= (slack-ts e)
+                                              (slack-ts message)))
+                                 messages))
+    (setq reply-count (length messages))))
+
+(defmethod slack-thread-update-mark ((thread slack-thread) room msg team)
+  (with-slots (thread-ts) thread
+    (with-slots (id) room
+      (with-slots (ts) msg
+        (cl-labels
+            ((on-success (&key data &allow-other-keys)
+                         (slack-request-handle-error
+                          (data "slack-thread-mark"))))
+
+          (slack-request
+           (slack-request-create
+            thread-mark-url
+            team
+            :params (list (cons "channel" id)
+                          (cons "thread_ts" thread-ts)
+                          (cons "ts" ts))
+            :success #'on-success)))))))
+
+(defmethod slack-thread-marked ((thread slack-thread) payload)
+  (let ((unread-count (plist-get payload :unread_count))
+        (last-read (plist-get payload :last_read)))
+    (oset thread unread-count unread-count)
+    (oset thread last-read last-read)))
+
+(defun slack-room-unread-threads ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-display-unread-threads buf)))
+
+(defmethod slack-thread-update-last-read ((thread slack-thread) msg)
+  (with-slots (ts) msg
+    (oset thread last-read ts)))
+
+(provide 'slack-thread)
+;;; slack-thread.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread.elc
new file mode 100644
index 000000000000..3612ab3223ab
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-thread.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-message.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-message.el
new file mode 100644
index 000000000000..a79edb9de110
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-message.el
@@ -0,0 +1,35 @@
+;;; package --- Summary
+;;; Commentary:
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-message-formatter)
+(require 'slack-message-reaction)
+(require 'slack-message-editor)
+
+(defvar slack-user-message-keymap
+  (let ((keymap (make-sparse-keymap)))
+    keymap))
+
+(defmethod slack-message-sender-equalp ((m slack-user-message) sender-id)
+  (string= (oref m user) sender-id))
+
+(defmethod slack-message-header ((m slack-user-message) team)
+  (with-slots (ts deleted-at) m
+    (let* ((name (slack-message-sender-name m team))
+           (status (slack-user-status (slack-message-sender-id m) team))
+           (time (slack-message-time-to-string ts))
+           (edited-at (slack-message-time-to-string (slack-message-edited-at m)))
+           (deleted-at (slack-message-time-to-string deleted-at))
+           (header (or (and status (< 0 (length status))
+                            (format "%s %s" name status))
+                       (format "%s" name))))
+      (if deleted-at
+          (format "%s deleted_at: %s" header deleted-at)
+        (if edited-at
+            (format "%s edited_at: %s" header edited-at)
+          header)))))
+
+(provide 'slack-user-message)
+;;; slack-user-message.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-message.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-message.elc
new file mode 100644
index 000000000000..627aaa504562
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-message.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-profile-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-profile-buffer.el
new file mode 100644
index 000000000000..e0e645c27a22
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-profile-buffer.el
@@ -0,0 +1,96 @@
+;;; slack-user-profile-buffer.el ---                 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-buffer)
+
+(define-derived-mode slack-user-profile-buffer-mode slack-buffer-mode "Slack User Profile")
+
+(defclass slack-user-profile-buffer (slack-buffer)
+  ((user-id :initarg :user-id :type string)))
+
+(defun slack-create-user-profile-buffer (team user-id)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-user-profile-buffer
+                                    user-id team)))
+      buf
+    (slack-user-profile-buffer :team team
+                               :user-id user-id)))
+
+(defmethod slack-buffer-buffer ((this slack-user-profile-buffer))
+  (slack-if-let* ((buf (get-buffer (slack-buffer-name this))))
+      (progn
+        (slack-buffer--insert this)
+        buf)
+    (slack-buffer-init-buffer this)))
+
+(defmethod slack-buffer-name :static ((class slack-user-profile-buffer) user-id team)
+  (format "*Slack - %s : Profile - %s*" (oref team name) (slack-user-name user-id team)))
+
+(defmethod slack-buffer-name ((this slack-user-profile-buffer))
+  (with-slots (user-id team) this
+    (slack-buffer-name 'slack-user-profile-buffer
+                       user-id
+                       team)))
+
+(defmethod slack-buffer--insert ((this slack-user-profile-buffer))
+  (let ((buf (get-buffer (slack-buffer-name this))))
+    (with-current-buffer buf
+      (let ((inhibit-read-only t))
+        (setq buffer-read-only nil)
+        (erase-buffer)
+        (goto-char (point-min))
+        (with-slots (user-id team) this
+          (insert (propertize (slack-user-profile-to-string user-id team)
+                              'ts 'dummy)))
+        (setq buffer-read-only t)
+        (slack-buffer-enable-emojify)
+        (goto-char (point-min))
+        (slack-display-image)))))
+
+(defmethod slack-buffer-init-buffer ((this slack-user-profile-buffer))
+  (let ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-user-profile-buffer-mode)
+      (slack-buffer-set-current-buffer this))
+    (slack-buffer--insert this)
+    buf))
+
+(defmethod slack-buffer-display-im ((this slack-user-profile-buffer))
+  (with-slots (user-id team) this
+    (let ((im (slack-im-find-by-user-id user-id team)))
+      (slack-room-display im team))))
+
+(defmethod slack-buffer--replace ((this slack-user-profile-buffer) _ts)
+  (with-current-buffer (current-buffer)
+    (let ((inhibit-read-only t))
+      (delete-region (point-min) (point-max))
+      (slack-buffer--insert this))))
+
+
+
+(provide 'slack-user-profile-buffer)
+;;; slack-user-profile-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-profile-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-profile-buffer.elc
new file mode 100644
index 000000000000..9c0175679046
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user-profile-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user.el
new file mode 100644
index 000000000000..3653a6d1c184
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user.el
@@ -0,0 +1,398 @@
+;;; slack-user.el ---slack user interface            -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'slack-util)
+(require 'slack-request)
+(require 'slack-room)
+
+(defconst slack-dnd-team-info-url "https://slack.com/api/dnd.teamInfo")
+(defconst slack-dnd-end-dnd-url "https://slack.com/api/dnd.endDnd")
+(defconst slack-dnd-set-snooze-url "https://slack.com/api/dnd.setSnooze")
+(defconst slack-set-presence-url "https://slack.com/api/users.setPresence")
+(defconst slack-user-info-url "https://slack.com/api/users.info")
+(defconst slack-user-profile-set-url "https://slack.com/api/users.profile.set")
+(defconst slack-bot-info-url "https://slack.com/api/bots.info")
+(defconst slack-bot-list-url "https://slack.com/api/bots.list")
+(defvar slack-current-user-id nil)
+
+(defun slack-user--find (id team)
+  (with-slots (users) team
+    (cl-find-if (lambda (user)
+                  (string= id (plist-get user :id)))
+                users)))
+
+(defun slack-user-find-by-name (name team)
+  (with-slots (users) team
+    (cl-find-if (lambda (user)
+                  (string= name (plist-get user :name)))
+                users)))
+
+(defun slack-user-get-id (name team)
+  (let ((user (slack-user-find-by-name name team)))
+    (if user
+        (plist-get user :id))))
+
+(defun slack-user-name (id team)
+  (slack-if-let* ((user (slack-user--find id team)))
+      (if (oref team full-and-display-names)
+          (plist-get user :real_name)
+        (plist-get user :name))))
+
+(defun slack-user-status (id team)
+  (let* ((user (slack-user--find id team))
+         (profile (and user (plist-get user :profile)))
+         (emoji (and profile (plist-get profile :status_emoji)))
+         (text (and profile (plist-get profile :status_text))))
+    (mapconcat #'identity (cl-remove-if #'null (list emoji text))
+               " ")))
+
+(defun slack-user-names (team)
+  (with-slots (users) team
+    (mapcar (lambda (u) (cons (plist-get u :name) u))
+            (cl-remove-if #'slack-user-hidden-p users))))
+
+(defun slack-user-dnd-in-range-p (user)
+  (let ((current (time-to-seconds))
+        (dnd-start (plist-get (plist-get user :dnd_status) :next_dnd_start_ts))
+        (dnd-end (plist-get (plist-get user :dnd_status) :next_dnd_end_ts)))
+    (and dnd-start dnd-end
+         (<= dnd-start current)
+         (<= current dnd-end))))
+
+(defun slack-user-dnd-status-to-string (user)
+  (if (slack-user-dnd-in-range-p user)
+      "Z"
+    nil))
+
+(defun slack-user-presence-to-string (user)
+  (if (string= (plist-get user :presence) "active")
+      "*"
+    " "))
+
+(defun slack-user-set-status ()
+  (interactive)
+  (let ((team (slack-team-select))
+        (emoji (slack-select-emoji))
+        (text (read-from-minibuffer "Text: ")))
+    (slack-user-set-status-request  team emoji text)))
+
+(defun slack-user-set-status-request (team emoji text)
+  (cl-labels ((on-success
+               (&key data &allow-other-keys)
+               (slack-request-handle-error
+                (data "slack-user-set-status-request"))))
+    (slack-request
+     (slack-request-create
+      slack-user-profile-set-url
+      team
+      :type "POST"
+      :data (list (cons "id" (oref team self-id))
+                  (cons "profile"
+                        (json-encode (list (cons "status_text" text)
+                                           (cons "status_emoji" emoji)))))
+      :success #'on-success))))
+
+(defun slack-bot-info-request (bot_id team &optional after-success)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-bot-info-request")
+                    (push (plist-get data :bot) (oref team bots))
+                    (if after-success
+                        (funcall after-success team)))))
+    (slack-request
+     (slack-request-create
+      slack-bot-info-url
+      team
+      :params (list (cons "bot" bot_id))
+      :success #'on-success))))
+
+(defun slack-bot-list-update (&optional team)
+  (interactive)
+  (let ((team (or team (slack-team-select))))
+    (cl-labels
+        ((on-success
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-bot-list-update")
+           (oset team bots (append (plist-get data :bots) nil)))))
+      (slack-request
+       (slack-request-create
+        slack-bot-list-url
+        team
+        :success #'on-success)))))
+
+(defface slack-user-profile-header-face
+  '((t (:foreground "#FFA000"
+                    :weight bold
+                    :height 1.5)))
+  "Face used to user profile header."
+  :group 'slack)
+
+(defface slack-user-profile-property-name-face
+  '((t (:weight bold :height 1.2)))
+  "Face used to user property."
+  :group 'slack)
+
+(define-derived-mode slack-user-profile-mode fundamental-mode "Slack User"
+  ""
+  (setq-local default-directory slack-default-directory))
+
+(defun slack-user-profile (user)
+  (plist-get user :profile))
+
+(defun slack-user-fname (user)
+  (plist-get (slack-user-profile user) :first_name))
+
+(defun slack-user-lname (user)
+  (plist-get (slack-user-profile user) :last_name))
+
+(defun slack-user-header (user)
+  (let* ((fname (slack-user-fname user))
+         (lname (slack-user-lname user))
+         (name (plist-get user :name)))
+    (or (and fname lname
+             (format "%s %s - @%s"
+                     (slack-user-fname user)
+                     (slack-user-lname user)
+                     (plist-get user :name)))
+        name)))
+
+(defun slack-user-timezone (user)
+  (let ((offset (/ (plist-get user :tz_offset) (* 60 60))))
+    (format "%s, %s"
+            (or (plist-get user :tz)
+                (plist-get user :tz_label))
+            (if (<= 0 offset)
+                (format "+%s hour" offset)
+              (format "%s hour" offset)))))
+
+(defun slack-user-property-to-str (value title)
+  (and value (< 0 (length value))
+       (format "%s\n\t%s"
+               (propertize title 'face 'slack-user-profile-property-name-face)
+               value)))
+
+(defun slack-user-profile-to-string (id team)
+  (let* ((user (slack-user--find id team))
+         (image (slack-image-string (list (slack-user-image-url user 512)
+                                          nil nil nil (window-width
+                                                       (get-buffer-window
+                                                        (current-buffer))
+                                                       t))
+                                    nil t))
+         (profile (slack-user-profile user))
+         (header (propertize (slack-user-header user)
+                             'face 'slack-user-profile-header-face))
+         (presence (slack-user-property-to-str (plist-get user :presence) "Presence"))
+         (status (slack-user-property-to-str (slack-user-status id team) "Status"))
+         (timezone (slack-user-property-to-str (slack-user-timezone user) "Timezone"))
+         (email (slack-user-property-to-str (plist-get profile :email) "Email"))
+         (phone (slack-user-property-to-str (plist-get profile :phone) "Phone"))
+         (skype (slack-user-property-to-str (plist-get profile :skype) "Skype"))
+         (body (mapconcat #'identity
+                          (cl-remove-if #'null
+                                        (list presence status timezone email phone skype))
+                          "\n"))
+         (dm-button (propertize "[Open Direct Message]"
+                                'face '(:underline t)
+                                'keymap (let ((map (make-sparse-keymap)))
+                                          (define-key map (kbd "RET")
+                                            #'(lambda ()
+                                                (interactive)
+                                                (slack-if-let* ((buf slack-current-buffer))
+                                                    (slack-buffer-display-im buf))))
+                                          map))))
+    (format "\n%s\n\n%s%s\n%s\n\n%s" image header (format "  (%s)" id) body dm-button)))
+
+(defun slack-user-self-p (user-id team)
+  (string= user-id (oref team self-id)))
+
+(defun slack-user-name-alist (team &key filter)
+  (let ((users (oref team users)))
+    (mapcar #'(lambda (e) (cons (slack-user-name (plist-get e :id) team) e))
+            (if filter (funcall filter users)
+              users))))
+
+(defun slack-user-hidden-p (user)
+  (not (eq (plist-get user :deleted) :json-false)))
+
+(defun slack--user-select (team)
+  (slack-select-from-list ((slack-user-names team) "Select User: ")))
+
+(defun slack-user-select ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (alist (slack-user-name-alist
+                 team
+                 :filter #'(lambda (users)
+                             (cl-remove-if #'slack-user-hidden-p users)))))
+    (slack-select-from-list (alist "Select User: ")
+        (let ((buf (slack-create-user-profile-buffer team (plist-get selected :id))))
+          (slack-buffer-display buf)))))
+
+(cl-defun slack-user-info-request (user-id team &key after-success)
+  (cl-labels
+      ((on-success
+        (&key data &allow-other-keys)
+        (slack-request-handle-error
+         (data "slack-user-info-request")
+         (oset team users (cons (plist-get data :user)
+                                (cl-remove-if #'(lambda (user)
+                                                  (string= (plist-get user :id) user-id))
+                                              (oref team users))))
+         (slack-im-open (plist-get data :user))
+         (when after-success (funcall after-success)))))
+    (slack-request
+     (slack-request-create
+      slack-user-info-url
+      team
+      :params (list (cons "user" user-id))
+      :success #'on-success))))
+
+(defun slack-user-image-url-24 (user)
+  (plist-get (slack-user-profile user) :image_24))
+
+(defun slack-user-image-url-32 (user)
+  (plist-get (slack-user-profile user) :image_32))
+
+(defun slack-user-image-url-48 (user)
+  (plist-get (slack-user-profile user) :image_48))
+
+(defun slack-user-image-url-72 (user)
+  (plist-get (slack-user-profile user) :image_72))
+
+(defun slack-user-image-url-512 (user)
+  (plist-get (slack-user-profile user) :image_512))
+
+(defun slack-user-image-url (user size)
+  (cond
+   ((eq size 24) (slack-user-image-url-24 user))
+   ((eq size 32) (slack-user-image-url-32 user))
+   ((eq size 48) (slack-user-image-url-48 user))
+   ((eq size 72) (slack-user-image-url-72 user))
+   ((eq size 512) (slack-user-image-url-512 user))
+   (t (slack-user-image-url-32 user))))
+
+(defun slack-user-fetch-image (user size team)
+  (let* ((image-url (slack-user-image-url user size))
+         (file-path (and image-url (slack-profile-image-path image-url team))))
+    (when file-path
+      (if (file-exists-p file-path) file-path
+        (slack-url-copy-file image-url file-path
+                             :success (lambda ()
+                                        (slack-log (format "Success download Image: %s"
+                                                           file-path)
+                                                   team)))))
+    file-path))
+
+(cl-defun slack-user-image (user team &optional (size 32))
+  (when user
+    (let ((image (slack-user-fetch-image user size team)))
+      (when image
+        (create-image image nil nil :ascent 80)))))
+
+(defun slack-user-presence (user)
+  (plist-get user :presence))
+
+(defun slack-request-set-presence (team &optional presence)
+  (unless presence
+    (let ((current-presence (slack-user-presence (slack-user--find (oref team self-id)
+                                                                   team))))
+
+      (setq presence (or (and (string= current-presence "away") "auto")
+                         "away"))
+      ))
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-request-set-presence"))))
+    (slack-request
+     (slack-request-create
+      slack-set-presence-url
+      team
+      :success #'on-success
+      :params (list (cons "presence" presence))))))
+
+(defun slack-request-dnd-set-snooze (team time)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-request-dnd-set-snooze")
+                    (message "setSnooze: %s" data))))
+    (let* ((input (slack-parse-time-string time))
+           (num-minutes (and time (/ (- (time-to-seconds input) (time-to-seconds))
+                                     60))))
+      (unless num-minutes
+        (error "Invalid time string %s" time))
+      (slack-request
+       (slack-request-create
+        slack-dnd-set-snooze-url
+        team
+        :success #'on-success
+        :params (list (cons "num_minutes" (format "%s" num-minutes))))))))
+
+(defun slack-request-dnd-end-dnd (team)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-request-dnd-end-dnd")
+                    (message "endDnd: %s" data))))
+    (slack-request
+     (slack-request-create
+      slack-dnd-end-dnd-url
+      team
+      :success #'on-success
+      ))))
+
+(defun slack-user-update-dnd-status (user dnd-status)
+  (plist-put user :dnd_status dnd-status))
+
+(defun slack-request-dnd-team-info (team &optional after-success)
+  (cl-labels
+      ((on-success
+        (&key data &allow-other-keys)
+        (slack-request-handle-error
+         (data "slack-request-dnd-team-info")
+         (let ((users (plist-get data :users)))
+           (oset team users
+                 (cl-loop for user in (oref team users)
+                          collect (plist-put
+                                   user
+                                   :dnd_status
+                                   (plist-get users
+                                              (intern (format ":%s"
+                                                              (plist-get user :id)))))))))
+        (when (functionp after-success)
+          (funcall after-success team))))
+    (slack-request
+     (slack-request-create
+      slack-dnd-team-info-url
+      team
+      :success #'on-success))))
+
+(provide 'slack-user)
+;;; slack-user.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user.elc
new file mode 100644
index 000000000000..530af0770d6f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-user.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-util.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-util.el
new file mode 100644
index 000000000000..dd415a941d02
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-util.el
@@ -0,0 +1,481 @@
+;;; slack-util.el ---utility functions               -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'timer)
+(require 'diary-lib)
+
+(defcustom slack-profile-image-file-directory temporary-file-directory
+  "Default directory for slack profile images."
+  :group 'slack)
+
+(defcustom slack-image-file-directory temporary-file-directory
+  "Default directory for slack images."
+  :group 'slack)
+
+(defcustom slack-image-max-height 300
+  "Max Height of image.  nil is unlimited.  integer."
+  :group 'slack)
+
+(defconst slack-log-levels
+  '(;; debugging
+    (trace . 40) (debug . 30)
+    ;; information
+    (info . 20)
+    ;; errors
+    (warn . 10) (error . 0))
+  "Named logging levels.")
+
+(defcustom slack-log-level 'info
+  "Used in `slack-message-logger'.
+One of 'info, 'debug"
+  :group 'slack)
+
+(defcustom slack-log-time-format
+  "[%Y-%m-%d %H:%M:%S]"
+  "Time format for log."
+  :group 'slack)
+
+(defalias 'slack-if-let*
+  (if (fboundp 'if-let*)
+      'if-let*
+    'if-let))
+
+(defun slack-seq-to-list (seq)
+  (if (listp seq) seq (append seq nil)))
+
+(defun slack-decode (seq)
+  (cl-loop for e in (slack-seq-to-list seq)
+           collect (if (stringp e)
+                       (decode-coding-string e 'utf-8)
+                     (if (listp e)
+                         (slack-decode e)
+                       e))))
+
+(defun slack-class-have-slot-p (class slot)
+  (and (symbolp slot)
+       (let* ((stripped (substring (symbol-name slot) 1))
+              (replaced (replace-regexp-in-string "_" "-"
+                                                  stripped))
+              (symbolized (intern replaced)))
+         (slot-exists-p class symbolized))))
+
+(defun slack-collect-slots (class seq)
+  (let ((plist (slack-seq-to-list seq)))
+    (cl-loop for p in plist
+             if (and (slack-class-have-slot-p class p)
+                     (plist-member plist p))
+             nconc (let ((value (plist-get plist p)))
+                     (list p (if (stringp value)
+                                 (decode-coding-string value 'utf-8)
+                               (if (eq :json-false value)
+                                   nil
+                                 value)))))))
+(defun slack-log-level-to-int (level)
+  (slack-if-let* ((cell (cl-assoc level slack-log-levels)))
+      (cdr cell)
+    20))
+
+
+(defun slack-message-logger (message level team)
+  "Display message using `message'."
+  (let ((user-level (slack-log-level-to-int slack-log-level))
+        (current-level (slack-log-level-to-int level)))
+    (when (<= current-level user-level)
+      (message (format "%s [%s] [%s] %s"
+                       (format-time-string slack-log-time-format)
+                       level
+                       (oref team name)
+                       message)))))
+
+(cl-defun slack-log (msg team &key
+                         (logger #'slack-message-logger)
+                         (level 'debug))
+  "LEVEL is one of 'trace, 'debug, 'info, 'warn, 'error"
+  (let ((log (format "%s [%s] %s - %s"
+                     (format-time-string slack-log-time-format)
+                     level
+                     msg
+                     (oref team name)))
+        (buf (get-buffer-create (slack-log-buffer-name team))))
+    (when (functionp logger)
+      (funcall logger msg level team))
+    (with-current-buffer buf
+      (setq buffer-read-only nil)
+      (save-excursion
+        (goto-char (point-max))
+        (insert log)
+        (insert "\n"))
+      (setq buffer-read-only t))))
+
+(defun company-slack-backend (command &optional arg &rest ignored)
+  "Completion backend for slack chats.  It currently understands
+@USER; adding #CHANNEL should be a simple matter of programming."
+  (interactive (list 'interactive))
+  (cl-labels
+      ((start-from-line-beginning (str)
+                                  (let ((prompt-length (length lui-prompt-string)))
+                                    (>= 0 (- (current-column) prompt-length (length str)))))
+       (prefix-type (str) (cond
+                           ((string-prefix-p "@" str) 'user)
+                           ((string-prefix-p "#" str) 'channel)
+                           ((and (string-prefix-p "/" str)
+                                 (start-from-line-beginning str))
+                            'slash)))
+       (content (str) (substring str 1 nil)))
+    (cl-case command
+      (interactive (company-begin-backend 'company-slack-backend))
+      (prefix (when (string= "slack" (car (split-string (format "%s" major-mode) "-")))
+                  ;; (cl-find major-mode '(slack-mode
+                  ;;                         slack-edit-message-mode
+                  ;;                         slack-thread-mode))
+                (company-grab-line "\\(\\W\\|^\\)\\(@\\w*\\|#\\w*\\|/\\w*\\)"
+                                   2)))
+      (candidates (let ((content (content arg)))
+                    (cl-case (prefix-type arg)
+                      (user
+                       (cl-loop for user in (oref slack-current-team users)
+                                if (and (not (eq (plist-get user :deleted) t))
+                                        (string-prefix-p content
+                                                         (plist-get user :name)))
+                                collect (concat "@" (plist-get user :name))))
+                      (channel
+                       (cl-loop for team in (oref slack-current-team channels)
+                                if (string-prefix-p content
+                                                    (oref team name))
+                                collect (concat "#" (oref team name))))
+                      (slash
+                       (cl-loop for command in (oref slack-current-team commands)
+                                if (string-prefix-p (concat "/" content)
+                                                    (oref command name))
+                                collect (oref command name))
+                       ))))
+      (doc-buffer
+       (cl-case (prefix-type arg)
+         (slash
+          (company-doc-buffer
+           (let* ((team slack-current-team)
+                  (command (slack-command-find arg team)))
+             (when command
+               (slack-command-company-doc-string command team))))))))))
+
+(defun slack-get-ts ()
+  (get-text-property 0 'ts (thing-at-point 'line)))
+
+(defun slack-linkfy (text link)
+  (if (not (slack-string-blankp link))
+      (format "<%s|%s>" link text)
+    text))
+
+(defun slack-string-blankp (str)
+  (if str
+      (> 1 (length str))
+    t))
+
+(defun slack-log-buffer-name (team)
+  (format "*Slack Log - %s*" (slack-team-name team)))
+
+(defun slack-log-open-buffer ()
+  (interactive)
+  (let ((team (slack-team-select)))
+    (funcall slack-buffer-function (get-buffer-create (slack-log-buffer-name team)))))
+
+(defun slack-event-log-buffer-name (team)
+  (format "*Slack Event Log - %s*" (slack-team-name team)))
+
+(defun slack-log-websocket-payload (payload team)
+  (let* ((bufname (slack-event-log-buffer-name team))
+         (buf (get-buffer-create bufname)))
+    (when buf
+      (with-current-buffer buf
+        (setq buffer-read-only nil)
+        (save-excursion
+          (goto-char (point-max))
+          (insert (format "[%s] %s\n"
+                          (format-time-string "%Y-%m-%d %H:%M:%S")
+                          payload)))
+        (setq buffer-read-only t)))))
+
+(defun slack-log-open-websocket-buffer ()
+  (interactive)
+  (if websocket-debug
+      (progn
+        (let* ((team (slack-team-select))
+               (websocket (oref team ws-conn)))
+          (if websocket
+              (funcall slack-buffer-function
+                       (websocket-get-debug-buffer-create websocket))
+            (error "Websocket is not connected"))))
+    (error "`websocket-debug` is not t")))
+
+(defun slack-log-open-event-buffer ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (bufname (slack-event-log-buffer-name team))
+         (buf (get-buffer bufname)))
+    (if buf
+        (funcall slack-buffer-function buf)
+      (error "No Event Log Buffer"))))
+
+(defun slack-profile-image-path (image-url team)
+  (expand-file-name
+   (concat (md5 (concat (slack-team-name team) "-" image-url))
+           "."
+           (file-name-extension image-url))
+   slack-profile-image-file-directory))
+
+(cl-defun slack-image--create (path &key (width nil) (height nil) (max-height nil) (max-width nil))
+  (let* ((imagemagick-available-p (image-type-available-p 'imagemagick))
+         (image (apply #'create-image (append (list path (and imagemagick-available-p 'imagemagick) nil)
+                                              (if height (list :height height))
+                                              (if width (list :width width))
+                                              (if max-height
+                                                  (list :max-height max-height))
+                                              (if max-width
+                                                  (list :max-width max-width))))))
+    (if (and (display-graphic-p) imagemagick-available-p)
+        (slack-image-shrink image max-height)
+      image)))
+
+(defun slack-image-exists-p (image-spec)
+  (file-exists-p (slack-image-path (car image-spec))))
+
+(defun slack-image-string (spec &optional pad no-token)
+  "SPEC: (list URL WIDTH HEIGHT MAX-HEIGHT MAX-WIDTH)"
+  (if spec
+      (slack-if-let* ((path (slack-image-path (car spec))))
+          (if (file-exists-p path)
+              (slack-mapconcat-images
+               (slack-image-slice
+                (slack-image--create path
+                                     :width (cadr spec)
+                                     :height (caddr spec)
+                                     :max-height (cadddr spec)
+                                     :max-width (cadr (cdddr spec))))
+               pad)
+            (propertize "[Image]"
+                        'slack-image-spec spec
+                        'no-token no-token))
+        "")
+    ""))
+
+(defun slack-image-path (image-url)
+  (and image-url
+       (expand-file-name
+        (concat (md5 image-url)
+                "."
+                (file-name-extension image-url))
+        slack-image-file-directory)))
+
+(defun slack-image-slice (image)
+  (when image
+    (let* ((line-height 50.0)
+           (height (or (plist-get (cdr image) :height)
+                       (cdr (image-size image t))))
+           (line-count (/ height line-height))
+           (line (/ 1.0 line-count)))
+      (if (< line-height height)
+          (cl-loop for i from 0 to (- line-count 1)
+                   collect (list (list 'slice 0 (* line i) 1.0 line)
+                                 image))
+        (list image)))))
+
+(defun slack-image-shrink (image &optional max-height)
+  (unless (image-type-available-p 'imagemagick)
+    (error "Need Imagemagick"))
+  (if max-height
+      (let* ((data (plist-get (cdr image) :data))
+             (file (plist-get (cdr image) :file))
+             (size (image-size image t))
+             (height (cdr size))
+             (width (car size))
+             (h (min height max-height))
+             (w (if (< max-height height)
+                    (ceiling
+                     (* (/ (float max-height) height)
+                        width))
+                  width)))
+        (create-image (or file data) 'imagemagick data :height h :width w))
+    image))
+
+(defun slack-mapconcat-images (images &optional pad)
+  (when images
+    (cl-labels
+        ((sort-images (images)
+                      (let ((compare (if (or (and (eq system-type 'darwin)
+                                                  (< emacs-major-version 26))
+                                             (< emacs-major-version 25))
+                                         #'>
+                                       #'<)))
+                        (cl-sort images compare :key
+                                 #'(lambda (image) (caddr (car image))))))
+         (propertize-image (image)
+                           (propertize "image"
+                                       'display image
+                                       'face 'slack-profile-image-face)))
+      (mapconcat #'propertize-image
+                 (sort-images images)
+                 (format "\n%s" (or pad ""))))))
+
+(cl-defun slack-url-copy-file (url newname &key (success nil) (error nil) (sync nil) (token nil))
+  (if (executable-find "curl")
+      (slack-curl-downloader url newname
+                             :success success
+                             :error error
+                             :token token)
+    (cl-labels
+        ((on-success (&key data &allow-other-keys)
+                     (when (functionp success) (funcall success)))
+         (on-error (&key error-thrown symbol-status response data)
+                   (message "Error Fetching Image: %s %s %s, url: %s"
+                            (request-response-status-code response)
+                            error-thrown symbol-status url)
+                   (if (file-exists-p newname)
+                       (delete-file newname))
+                   (case (request-response-status-code response)
+                     (403 nil)
+                     (404 nil)
+                     (t (when (functionp error)
+                          (funcall error
+                                   (request-response-status-code response)
+                                   error-thrown
+                                   symbol-status
+                                   url)))))
+         (parser () (mm-write-region (point-min) (point-max)
+                                     newname nil nil nil 'binary t)))
+      (let* ((url-obj (url-generic-parse-url url))
+             (need-token-p (and url-obj
+                                (string-match-p "slack"
+                                                (url-host url-obj))))
+             (use-https-p (and url-obj
+                               (string= "https" (url-type url-obj)))))
+        (request
+         url
+         :success #'on-success
+         :error #'on-error
+         :parser #'parser
+         :sync sync
+         :headers (if (and token use-https-p need-token-p)
+                      (list (cons "Authorization" (format "Bearer %s" token)))))))))
+
+(defun slack-render-image (image team)
+  (let ((buf (get-buffer-create
+              (format "*Slack - %s Image*" (slack-team-name team)))))
+    (with-current-buffer buf
+      (setq buffer-read-only nil)
+      (erase-buffer)
+      (if image
+          (insert (slack-mapconcat-images (slack-image-slice image)))
+        (insert "Loading Image..."))
+      (setq buffer-read-only t)
+      (goto-char (point-min)))
+
+    buf))
+
+(defun slack-parse-time-string (time)
+  "TIME should be one of:
+- a string giving todayโ€™s time like \"11:23pm\"
+  (the acceptable formats are HHMM, H:MM, HH:MM, HHam, HHAM,
+  HHpm, HHPM, HH:MMam, HH:MMAM, HH:MMpm, or HH:MMPM;
+  a period โ€˜.โ€™ can be used instead of a colon โ€˜:โ€™ to separate
+  the hour and minute parts);
+- a string giving specific date and time like \"1991/03/23 03:00\";
+- a string giving a relative time like \"90\" or \"2 hours 35 minutes\"
+  (the acceptable forms are a number of seconds without units
+  or some combination of values using units in โ€˜timer-duration-wordsโ€™);
+- a number of seconds from now;"
+  (if (numberp time)
+      (setq time (timer-relative-time nil time)))
+  (if (stringp time)
+      (let ((secs (timer-duration time)))
+        (if secs
+            (setq time (timer-relative-time nil secs)))))
+  (if (stringp time)
+      (progn
+        (let* ((date-and-time (split-string time " "))
+               (date (and (eq (length date-and-time) 2) (split-string (car date-and-time) "/")))
+               (time-str (or (and (eq (length date-and-time) 2) (cadr date-and-time))
+                             (car date-and-time)))
+               (hhmm (diary-entry-time time-str))
+               (now (or (and date (decode-time
+                                   (encode-time 0 0 0
+                                                (string-to-number (nth 2 date))
+                                                (string-to-number (nth 1 date))
+                                                (string-to-number (nth 0 date))
+                                                )))
+                        (decode-time))))
+          (if (>= hhmm 0)
+              (setq time
+                    (encode-time 0 (% hhmm 100) (/ hhmm 100) (nth 3 now)
+                                 (nth 4 now) (nth 5 now) (nth 8 now)))))))
+  time)
+
+(defmacro slack-merge-list (old-list new-list)
+  `(cl-loop for n in ,new-list
+            do (let ((o (cl-find-if #'(lambda (e) (slack-equalp n e))
+                                    ,old-list)))
+                 (if o (slack-merge o n)
+                   (push n ,old-list)))))
+
+(cl-defun slack-curl-downloader (url name &key (success nil) (error nil) (token nil))
+  (cl-labels
+      ((sentinel (proc event)
+                 (cond
+                  ((string-equal "finished\n" event)
+                   (when (functionp success) (funcall success)))
+                  (t
+                   (let ((status (process-status proc))
+                         (output (with-current-buffer (process-buffer proc)
+                                   (buffer-substring-no-properties (point-min)
+                                                                   (point-max)))))
+                     (if (functionp error)
+                         (funcall error status output url name)
+                       (message "Download Failed. STATUS: %s, EVENT: %s, URL: %s, NAME: %s, OUTPUT: %s"
+                                status
+                                event
+                                url
+                                name
+                                output))
+                     (if (file-exists-p name)
+                         (delete-file name))
+                     (delete-process proc))))))
+    (let* ((url-obj (url-generic-parse-url url))
+           (need-token-p (and url-obj
+                              (string-match-p "slack" (url-host url-obj))))
+           (header (or (and token
+                            need-token-p
+                            (string-prefix-p "https" url)
+                            (format "-H 'Authorization: Bearer %s'" token))
+                       ""))
+           (output (format "--output '%s'" name))
+           (command (format "curl --silent --show-error --fail --location %s %s '%s'" output header url))
+           (proc (start-process-shell-command "slack-curl-downloader"
+                                              "slack-curl-downloader"
+                                              command)))
+      (set-process-sentinel proc #'sentinel))))
+
+(provide 'slack-util)
+;;; slack-util.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-util.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-util.elc
new file mode 100644
index 000000000000..ee44e25c6994
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-util.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-websocket.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-websocket.el
new file mode 100644
index 000000000000..b81d72b268b9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-websocket.el
@@ -0,0 +1,1073 @@
+;;; slack-websocket.el --- slack websocket interface  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  ๅ—ๅ„ชไนŸ
+
+;; Author: ๅ—ๅ„ชไนŸ <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'websocket)
+(require 'slack-util)
+(require 'slack-request)
+(require 'slack-message)
+(require 'slack-team)
+(require 'slack-reply)
+(require 'slack-file)
+(require 'slack-dialog)
+(defconst slack-api-test-url "https://slack.com/api/api.test")
+
+(defclass slack-typing ()
+  ((room :initarg :room :initform nil)
+   (limit :initarg :limit :initform nil)
+   (users :initarg :users :initform nil)))
+
+(defclass slack-typing-user ()
+  ((limit :initarg :limit :initform nil)
+   (user-name :initarg :user-name :initform nil)))
+
+(defun slack-ws-set-connect-timeout-timer (team)
+  (slack-ws-cancel-connect-timeout-timer team)
+  (cl-labels
+      ((on-timeout ()
+                   (slack-log (format "websocket open timeout")
+                              team)
+                   (slack-ws-close team)
+                   (slack-ws-set-reconnect-timer team)))
+    (oset team websocket-connect-timeout-timer
+          (run-at-time (oref team websocket-connect-timeout-sec)
+                       nil
+                       #'on-timeout))))
+
+(defun slack-ws-cancel-connect-timeout-timer (team)
+  (when (timerp (oref team websocket-connect-timeout-timer))
+    (cancel-timer (oref team websocket-connect-timeout-timer))
+    (oset team websocket-connect-timeout-timer nil)))
+
+(cl-defun slack-ws-open (team &key (on-open nil) (ws-url nil))
+  (slack-if-let* ((conn (oref team ws-conn))
+                  (state (websocket-ready-state conn)))
+      (cond ((websocket-openp conn)
+             (slack-log "Websocket is Already Open" team))
+            ((eq state 'connecting)
+             (slack-log "Websocket is connecting" team))
+            ((eq state 'closed)
+             (slack-log "Websocket is closed" team)))
+
+    (progn
+      (slack-ws-set-connect-timeout-timer team)
+      (cl-labels
+          ((on-message (websocket frame)
+                       (slack-ws-on-message websocket frame team))
+           (handle-on-open (_websocket)
+                           (oset team reconnect-count 0)
+                           (oset team connected t)
+                           (slack-log "WebSocket on-open"
+                                      team :level 'debug)
+                           (when (functionp on-open)
+                             (funcall on-open)))
+           (on-close (websocket)
+                     (oset team ws-conn nil)
+                     (oset team connected nil)
+                     (slack-log (format "Websocket on-close: STATE: %s"
+                                        (websocket-ready-state websocket))
+                                team :level 'debug)
+                     (unwind-protect
+                         (progn
+                           (unless (oref team inhibit-reconnection)
+                             (slack-ws-set-reconnect-timer team)))
+                       (oset team inhibit-reconnection nil)))
+           (on-error (_websocket type err)
+                     (slack-log (format "Error on `websocket-open'. TYPE: %s, ERR: %s"
+                                        type err)
+                                team
+                                :level 'error)))
+        (oset team ws-conn
+              (condition-case error-var
+                  (websocket-open (or ws-url (oref team ws-url))
+                                  :on-message #'on-message
+                                  :on-open #'handle-on-open
+                                  :on-close #'on-close
+                                  :on-error #'on-error
+                                  :nowait (oref team websocket-nowait))
+                (error
+                 (slack-log (format "An Error occured while opening websocket connection: %s"
+                                    error-var)
+                            team
+                            :level 'error)
+                 ;; (slack-ws-close team)
+                 ;; (slack-ws-set-reconnect-timer team)
+                 nil)))))))
+
+(cl-defun slack-ws-close (&optional team (close-reconnection nil))
+  (interactive)
+  (unless team
+    (setq team slack-teams))
+  (let ((called-interactively (called-interactively-p 'any)))
+    (cl-labels
+        ((close (team)
+                (slack-ws-cancel-ping-timer team)
+                (slack-ws-cancel-ping-check-timers team)
+                (when (or close-reconnection
+                          called-interactively)
+                  (slack-ws-cancel-reconnect-timer team)
+                  (oset team inhibit-reconnection t))
+                (with-slots (connected ws-conn last-pong) team
+                  (when ws-conn
+                    (websocket-close ws-conn)
+                    (slack-log "Slack Websocket Closed" team)))))
+      (if (listp team)
+          (progn
+            (mapc #'close team)
+            (slack-request-worker-quit))
+        (close team)
+        (slack-request-worker-remove-request team)
+        )
+      )))
+
+(defun slack-ws-send (payload team)
+  (with-slots (waiting-send ws-conn) team
+    (push payload waiting-send)
+    (cl-labels
+        ((reconnect ()
+                    (slack-ws-close team)
+                    (slack-ws-set-reconnect-timer team)))
+      (if (websocket-openp ws-conn)
+          (condition-case err
+              (websocket-send-text ws-conn (json-encode payload))
+            (error
+             (slack-log (format "Error in `slack-ws-send`: %s" err)
+                        team :level 'debug)
+             (reconnect)))
+        (reconnect)))))
+
+(defun slack-ws-resend (team)
+  (with-slots (waiting-send) team
+    (let ((candidate waiting-send))
+      (setq waiting-send nil)
+      (cl-loop for msg in candidate
+               do (slack-ws-send msg team)))))
+
+;; (:type error :error (:msg Socket URL has expired :code 1))
+(defun slack-ws-handle-error (payload team)
+  (let* ((err (plist-get payload :error))
+         (code (plist-get err :code)))
+    (cond
+     ((eq 1 code)
+      (slack-ws-close team)
+      (slack-ws-set-reconnect-timer team))
+     (t (slack-log (format "Unknown Error: %s, MSG: %s"
+                           code (plist-get err :msg))
+                   team)))))
+
+(defun slack-ws-on-message (_websocket frame team)
+  ;; (message "%s" (slack-request-parse-payload
+  ;;                (websocket-frame-payload frame)))
+  (when (websocket-frame-completep frame)
+    (let* ((payload (slack-request-parse-payload
+                     (websocket-frame-payload frame)))
+           (decoded-payload (and payload (slack-decode payload)))
+           (type (and decoded-payload
+                      (plist-get decoded-payload :type))))
+      ;; (message "%s" decoded-payload)
+      (when (slack-team-event-log-enabledp team)
+        (slack-log-websocket-payload decoded-payload team))
+      (when decoded-payload
+        (cond
+         ((string= type "error")
+          (slack-ws-handle-error decoded-payload team))
+         ((string= type "pong")
+          (slack-ws-handle-pong decoded-payload team))
+         ((string= type "hello")
+          (slack-ws-cancel-connect-timeout-timer team)
+          (slack-ws-cancel-reconnect-timer team)
+          (slack-cancel-notify-adandon-reconnect)
+          (slack-ws-set-ping-timer team)
+          (slack-ws-resend team)
+          (slack-log "Slack Websocket Is Ready!" team :level 'info))
+         ((plist-get decoded-payload :reply_to)
+          (slack-ws-handle-reply decoded-payload team))
+         ((string= type "message")
+          (slack-ws-handle-message decoded-payload team))
+         ((string= type "reaction_added")
+          (slack-ws-handle-reaction-added decoded-payload team))
+         ((string= type "reaction_removed")
+          (slack-ws-handle-reaction-removed decoded-payload team))
+         ((string= type "channel_created")
+          (slack-ws-handle-channel-created decoded-payload team))
+         ((or (string= type "channel_archive")
+              (string= type "group_archive"))
+          (slack-ws-handle-room-archive decoded-payload team))
+         ((or (string= type "channel_unarchive")
+              (string= type "group_unarchive"))
+          (slack-ws-handle-room-unarchive decoded-payload team))
+         ((string= type "channel_deleted")
+          (slack-ws-handle-channel-deleted decoded-payload team))
+         ((or (string= type "channel_rename")
+              (string= type "group_rename"))
+          (slack-ws-handle-room-rename decoded-payload team))
+         ((or (string= type "channel_left")
+              (string= type "group_left"))
+          (slack-ws-handle-room-left decoded-payload team))
+         ((string= type "channel_joined")
+          (slack-ws-handle-channel-joined decoded-payload team))
+         ((string= type "group_joined")
+          (slack-ws-handle-group-joined decoded-payload team))
+         ((string= type "presence_change")
+          (slack-ws-handle-presence-change decoded-payload team))
+         ((or (string= type "bot_added")
+              (string= type "bot_changed"))
+          (slack-ws-handle-bot decoded-payload team))
+         ((string= type "file_created")
+          (slack-ws-handle-file-created decoded-payload team))
+         ((or (string= type "file_deleted")
+              (string= type "file_unshared"))
+          (slack-ws-handle-file-deleted decoded-payload team))
+         ((or (string= type "im_marked")
+              (string= type "channel_marked")
+              (string= type "group_marked"))
+          (slack-ws-handle-room-marked decoded-payload team))
+         ((string= type "thread_marked")
+          (slack-ws-handle-thread-marked decoded-payload team))
+         ((string= type "thread_subscribed")
+          (slack-ws-handle-thread-subscribed decoded-payload team))
+         ((string= type "im_open")
+          (slack-ws-handle-im-open decoded-payload team))
+         ((string= type "im_close")
+          (slack-ws-handle-im-close decoded-payload team))
+         ((string= type "team_join")
+          (slack-ws-handle-team-join decoded-payload team))
+         ((string= type "user_typing")
+          (slack-ws-handle-user-typing decoded-payload team))
+         ((string= type "user_change")
+          (slack-ws-handle-user-change decoded-payload team))
+         ((string= type "member_joined_channel")
+          (slack-ws-handle-member-joined-channel decoded-payload team))
+         ((string= type "member_left_channel")
+          (slack-ws-handle-member-left_channel decoded-payload team))
+         ((or (string= type "dnd_updated")
+              (string= type "dnd_updated_user"))
+          (slack-ws-handle-dnd-updated decoded-payload team))
+         ((string= type "star_added")
+          (slack-ws-handle-star-added decoded-payload team))
+         ((string= type "star_removed")
+          (slack-ws-handle-star-removed decoded-payload team))
+         ((string= type "reconnect_url")
+          (slack-ws-handle-reconnect-url decoded-payload team))
+         ((string= type "app_conversation_invite_request")
+          (slack-ws-handle-app-conversation-invite-request decoded-payload team))
+         ((string= type "commands_changed")
+          (slack-ws-handle-commands-changed decoded-payload team))
+         ((string= type "dialog_opened")
+          (slack-ws-handle-dialog-opened decoded-payload team))
+         )))))
+
+(defun slack-ws-handle-reconnect-url (payload team)
+  (oset team reconnect-url (plist-get payload :url)))
+
+(defun slack-user-typing (team)
+  (with-slots (typing typing-timer) team
+    (with-slots (limit users room) typing
+      (let ((current (float-time)))
+        (if (and typing-timer (timerp typing-timer)
+                 (< limit current))
+            (progn
+              (cancel-timer typing-timer)
+              (setq typing-timer nil)
+              (setq typing nil))
+          (if (slack-buffer-show-typing-p
+               (get-buffer (slack-room-buffer-name room team)))
+              (let ((team-name (slack-team-name team))
+                    (room-name (slack-room-name room team))
+                    (visible-users (cl-remove-if
+                                    #'(lambda (u) (< (oref u limit) current))
+                                    users)))
+                (slack-log
+                 (format "Slack [%s - %s] %s is typing..."
+                         team-name room-name
+                         (mapconcat #'(lambda (u) (oref u user-name))
+                                    visible-users
+                                    ", "))
+                 team
+                 :level 'info))))))))
+
+(defun slack-ws-handle-user-typing (payload team)
+  (let* ((user (slack-user-name (plist-get payload :user) team))
+         (room (slack-room-find (plist-get payload :channel) team)))
+    (if (and user room
+             (slack-buffer-show-typing-p (get-buffer (slack-room-buffer-name room team))))
+        (let ((limit (+ 3 (float-time))))
+          (with-slots (typing typing-timer) team
+            (if (and typing (equal room (oref typing room)))
+                (with-slots ((typing-limit limit)
+                             (typing-room room) users) typing
+                  (setq typing-limit limit)
+                  (let ((typing-user (make-instance 'slack-typing-user
+                                                    :limit limit
+                                                    :user-name user)))
+                    (setq users
+                          (cons typing-user
+                                (cl-remove-if #'(lambda (u)
+                                                  (string= (oref u user-name)
+                                                           user))
+                                              users))))))
+            (unless typing
+              (let ((new-typing (make-instance 'slack-typing
+                                               :room room :limit limit))
+                    (typing-user (make-instance 'slack-typing-user
+                                                :limit limit :user-name user)))
+                (oset new-typing users (list typing-user))
+                (setq typing new-typing))
+              (setq typing-timer
+                    (run-with-timer t 1 #'slack-user-typing team))))))))
+
+(defun slack-ws-handle-team-join (payload team)
+  (let ((user (slack-decode (plist-get payload :user))))
+    (slack-user-info-request
+     (plist-get user :id) team
+     :after-success #'(lambda ()
+                        (slack-log (format "User %s Joind Team: %s"
+                                           (plist-get (slack-user--find (plist-get user :id)
+                                                                        team)
+                                                      :name)
+                                           (slack-team-name team))
+                                   team
+                                   :level 'info)))))
+
+(defun slack-ws-handle-im-open (payload team)
+  (cl-labels
+      ((notify
+        (im)
+        (slack-room-history-request
+         im team
+         :after-success #'(lambda (&rest _ignore)
+                            (slack-log (format "Direct Message Channel with %s is Open"
+                                               (slack-user-name (oref im user) team))
+                                       team :level 'info))
+         :async t)))
+    (let ((exist (slack-room-find (plist-get payload :channel) team)))
+      (if exist
+          (progn
+            (oset exist is-open t)
+            (notify exist))
+        (with-slots (ims) team
+          (let ((im (slack-room-create
+                     (list :id (plist-get payload :channel)
+                           :user (plist-get payload :user))
+                     team 'slack-im)))
+            (setq ims (cons im ims))
+            (notify im)))))))
+
+(defun slack-ws-handle-im-close (payload team)
+  (let ((im (slack-room-find (plist-get payload :channel) team)))
+    (when im
+      (oset im is-open nil)
+      (slack-log (format "Direct Message Channel with %s is Closed"
+                         (slack-user-name (oref im user) team))
+                 team :level 'info))))
+
+(defun slack-ws-handle-message (payload team)
+  (let ((subtype (plist-get payload :subtype)))
+    (cond
+     ((and subtype (string= subtype "message_changed"))
+      (slack-ws-change-message payload team))
+     ((and subtype (string= subtype "message_deleted"))
+      (slack-ws-delete-message payload team))
+     ((and subtype (string= subtype "message_replied"))
+      (slack-thread-update-state payload team))
+     (t
+      (slack-ws-update-message payload team)))))
+
+(defun slack-ws-change-message (payload team)
+  (slack-if-let* ((room-id (plist-get payload :channel))
+                  (room (slack-room-find room-id team))
+                  (message-payload (plist-get payload :message))
+                  (ts (plist-get message-payload :ts))
+                  (base (slack-room-find-message room ts))
+                  (new-message (slack-message-create message-payload
+                                                     team
+                                                     :room room)))
+      (slack-message-update base team t
+                            (not (slack-message-changed--copy base new-message)))))
+
+
+(defun slack-ws-delete-message (payload team)
+  (slack-if-let* ((room-id (plist-get payload :channel))
+                  (room (slack-room-find room-id team))
+                  (ts (plist-get payload :deleted_ts))
+                  (message (slack-room-find-message room ts)))
+      (slack-message-deleted message room team)))
+
+(defun slack-ws-update-message (payload team)
+  (let ((subtype (plist-get payload :subtype)))
+    (if (string= subtype "bot_message")
+        (slack-ws-update-bot-message payload team)
+      (slack-message-update (slack-message-create payload team)
+                            team))))
+
+(defun slack-ws-update-bot-message (payload team)
+  (let* ((bot-id (plist-get payload :bot_id))
+         (username (plist-get payload :username))
+         (user (plist-get payload :user))
+         (bot (or (slack-find-bot bot-id team)
+                  (slack-find-bot-by-name username team)
+                  (slack-user--find user team)))
+         (message (slack-message-create payload team)))
+    (if bot
+        (slack-message-update message team)
+      (slack-bot-info-request bot-id
+                              team
+                              #'(lambda (team)
+                                  (slack-message-update message team))))))
+
+(defun slack-ws-remove-from-resend-queue (payload team)
+  (with-slots (waiting-send) team
+    (slack-log (format "waiting-send: %s" (length waiting-send))
+               team :level 'trace)
+    (setq waiting-send
+          (cl-remove-if #'(lambda (e) (eq (plist-get e :id)
+                                          (plist-get payload :reply_to)))
+                        waiting-send))
+    (slack-log (format "waiting-send: %s" (length waiting-send))
+               team :level 'trace)))
+
+(defun slack-ws-handle-reply (payload team)
+  (let ((ok (plist-get payload :ok)))
+    (if (eq ok :json-false)
+        (let ((err (plist-get payload :error)))
+          (slack-log (format "Error code: %s msg: %s"
+                             (plist-get err :code)
+                             (plist-get err :msg))
+                     team))
+      (let ((message-id (plist-get payload :reply_to)))
+        (when (integerp message-id)
+          (slack-message-handle-reply
+           (slack-message-create payload team)
+           team)
+          (slack-ws-remove-from-resend-queue payload team))))))
+
+(defun slack-ws-handle-reaction-added-to-file (file-id reaction team)
+  (let* ((file (slack-file-find file-id team))
+         (item-type "file"))
+    (cl-labels
+        ((update (&rest _args)
+                 (slack-with-file file-id team
+                   (slack-message-append-reaction file reaction)
+                   (slack-message-update file team)
+                   (cl-loop for channel in (slack-file-channel-ids file)
+                            do (slack-if-let*
+                                   ((channel (slack-room-find channel team))
+                                    (message (slack-room-find-file-share-message
+                                              channel (oref file id))))
+
+                                   (progn
+                                     (slack-message-append-reaction message
+                                                                    reaction
+                                                                    item-type
+                                                                    file-id)
+                                     (slack-message-update message
+                                                           team t t)))))))
+      (if file (update)
+        (slack-file-request-info file-id 1 team #'update)))))
+
+(defun slack-ws-handle-reaction-added (payload team)
+  (let* ((item (plist-get payload :item))
+         (item-type (plist-get item :type))
+         (reaction (make-instance 'slack-reaction
+                                  :name (plist-get payload :reaction)
+                                  :count 1
+                                  :users (list (plist-get payload :user)))))
+    (cl-labels
+        ((update-message (message)
+                         (slack-message-append-reaction message reaction item-type)
+                         (slack-message-update message team t t)))
+      (cond
+       ((string= item-type "file")
+        (slack-ws-handle-reaction-added-to-file (plist-get item :file)
+                                                reaction
+                                                team))
+       ((string= item-type "message")
+        (slack-if-let* ((room (slack-room-find (plist-get item :channel) team))
+                        (message (slack-room-find-message room (plist-get item :ts))))
+            (progn
+              (update-message message)
+              (slack-reaction-notify payload team room))))))))
+
+(defun slack-ws-handle-reaction-removed-from-file (file-id reaction team)
+  (let* ((file (slack-file-find file-id team))
+         (item-type "file"))
+    (cl-labels
+        ((update (&rest _args)
+                 (slack-with-file file-id team
+                   (slack-message-pop-reaction file reaction)
+                   (slack-message-update file team)
+                   (cl-loop for channel in (slack-file-channel-ids file)
+                            do (slack-if-let*
+                                   ((channel (slack-room-find channel team))
+                                    (message (slack-room-find-file-share-message
+                                              channel (oref file id))))
+                                   (progn
+                                     (slack-message-pop-reaction message
+                                                                 reaction
+                                                                 item-type
+                                                                 file-id)
+                                     (slack-message-update message team t t)))))))
+      (if file (update)
+        (slack-file-request-info file-id 1 team #'update)))))
+
+(defun slack-ws-handle-reaction-removed (payload team)
+  (let* ((item (plist-get payload :item))
+         (item-type (plist-get item :type))
+         (reaction (make-instance 'slack-reaction
+                                  :name (plist-get payload :reaction)
+                                  :count 1
+                                  :users (list (plist-get payload :user)))))
+    (cl-labels
+        ((update-message (message)
+                         (slack-message-pop-reaction message reaction item-type)
+                         (slack-message-update message team t t)))
+      (cond
+       ((string= item-type "file")
+        (slack-ws-handle-reaction-removed-from-file (plist-get item :file)
+                                                    reaction
+                                                    team))
+       ((string= item-type "message")
+        (slack-if-let* ((room (slack-room-find (plist-get item :channel) team))
+                        (message (slack-room-find-message room (plist-get item :ts))))
+            (progn
+              (update-message message)
+              (slack-reaction-notify payload team room))))))))
+
+(defun slack-ws-handle-channel-created (payload team)
+  (let ((channel (slack-room-create (plist-get payload :channel)
+                                    team 'slack-channel)))
+    (push channel (oref team channels))
+    (slack-room-info-request channel team)
+    (slack-log (format "Created channel %s"
+                       (slack-room-display-name channel team))
+               team :level 'info)))
+
+(defun slack-ws-handle-room-archive (payload team)
+  (let* ((id (plist-get payload :channel))
+         (room (slack-room-find id team)))
+    (oset room is-archived t)
+    (slack-log (format "Channel: %s is archived"
+                       (slack-room-display-name room team))
+               team :level 'info)))
+
+(defun slack-ws-handle-room-unarchive (payload team)
+  (let* ((id (plist-get payload :channel))
+         (room (slack-room-find id team)))
+    (oset room is-archived nil)
+    (slack-log (format "Channel: %s is unarchived"
+                       (slack-room-display-name room team))
+               team :level 'info)))
+
+(defun slack-ws-handle-channel-deleted (payload team)
+  (let ((id (plist-get payload :channel)))
+    (slack-room-deleted id team)))
+
+(defun slack-ws-handle-room-rename (payload team)
+  (let* ((c (plist-get payload :channel))
+         (room (slack-room-find (plist-get c :id) team))
+         (old-name (slack-room-name room team))
+         (new-name (plist-get c :name)))
+    (oset room name new-name)
+    (slack-log (format "Renamed channel from %s to %s"
+                       old-name
+                       new-name)
+               team :level 'info)))
+(defun slack-ws-handle-group-joined (payload team)
+  (let ((group (slack-room-create (plist-get payload :channel) team 'slack-group)))
+    (push group (oref team groups))
+    (slack-room-info-request group team)
+    (slack-log (format "Joined group %s"
+                       (slack-room-display-name group team))
+               team :level 'info)))
+
+(defun slack-ws-handle-channel-joined (payload team)
+  (let ((channel (slack-room-find (plist-get (plist-get payload :channel) :id) team)))
+    (slack-room-info-request channel team)
+    (slack-log (format "Joined channel %s"
+                       (slack-room-display-name channel team))
+               team :level 'info)))
+
+(defun slack-ws-handle-presence-change (payload team)
+  (let* ((id (plist-get payload :user))
+         (user (slack-user--find id team))
+         (presence (plist-get payload :presence)))
+    (plist-put user :presence presence)))
+
+(defun slack-ws-handle-bot (payload team)
+  (let ((bot (plist-get payload :bot)))
+    (with-slots (bots) team
+      (push bot bots))))
+
+(defun slack-ws-handle-file-created (payload team)
+  (slack-if-let* ((file-id (plist-get (plist-get payload :file) :id))
+                  (room (slack-file-room-obj team))
+                  (buffer (slack-buffer-find 'slack-file-list-buffer
+                                             room
+                                             team)))
+      (slack-file-request-info file-id 1 team
+                               #'(lambda (file _team)
+                                   (slack-buffer-update buffer file)))))
+
+(defun slack-ws-handle-file-deleted (payload team)
+  (let ((file-id (plist-get payload :file_id))
+        (room (slack-file-room-obj team)))
+    (with-slots (messages) room
+      (setq messages (cl-remove-if #'(lambda (f)
+                                       (string= file-id (oref f id)))
+                                   messages)))))
+
+(defun slack-ws-cancel-ping-timer (team)
+  (with-slots (ping-timer) team
+    (if (timerp ping-timer)
+        (cancel-timer ping-timer))
+    (setq ping-timer nil)))
+
+(defun slack-ws-set-ping-timer (team)
+  (slack-ws-cancel-ping-timer team)
+  (cl-labels ((ping ()
+                    (slack-ws-ping team)))
+    (oset team ping-timer (run-at-time 10 nil #'ping))))
+
+(defun slack-ws-current-time-str ()
+  (number-to-string (time-to-seconds (current-time))))
+
+(defun slack-ws-ping (team)
+  (slack-message-inc-id team)
+  (with-slots (message-id) team
+    (let* ((time (slack-ws-current-time-str))
+           (m (list :id message-id
+                    :type "ping"
+                    :time time)))
+      (slack-ws-set-check-ping-timer team time)
+      (slack-ws-send m team)
+      (slack-log (format "Send PING: %s" time)
+                 team :level 'trace))))
+
+(defun slack-ws-set-check-ping-timer (team time)
+  (puthash time (run-at-time (oref team check-ping-timeout-sec)
+                             nil #'slack-ws-ping-timeout team)
+           (oref team ping-check-timers)))
+
+
+(defun slack-ws-ping-timeout (team)
+  (slack-log "Slack Websocket PING Timeout." team :level 'warn)
+  (slack-ws-close team)
+  (slack-ws-set-reconnect-timer team))
+
+(defun slack-ws-cancel-ping-check-timers (team)
+  (maphash #'(lambda (key value)
+               (if (timerp value)
+                   (cancel-timer value)))
+           (oref team ping-check-timers))
+  (slack-team-init-ping-check-timers team))
+
+(defvar slack-disconnected-timer nil)
+(defun slack-notify-abandon-reconnect (team)
+  (unless slack-disconnected-timer
+    (setq slack-disconnected-timer
+          (run-with-idle-timer 5 t
+                               #'(lambda ()
+                                   (slack-log
+                                    "Reconnect Count Exceeded. Manually invoke `slack-start'."
+                                    team :level 'error))))))
+
+(defun slack-cancel-notify-adandon-reconnect ()
+  (if (and slack-disconnected-timer
+           (timerp slack-disconnected-timer))
+      (progn
+        (cancel-timer slack-disconnected-timer)
+        (setq slack-disconnected-timer nil))))
+
+(defun slack-request-api-test (team &optional after-success)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-request-api-test")
+                    (if after-success
+                        (funcall after-success)))))
+    (slack-request
+     (slack-request-create
+      slack-api-test-url
+      team
+      :type "POST"
+      :success #'on-success))))
+
+(defun slack-on-authorize-for-reconnect (data team)
+  (let ((team-data (plist-get data :team))
+        (self-data (plist-get data :self)))
+    (oset team ws-url (plist-get data :url))
+    (oset team domain (plist-get team-data :domain))
+    (oset team id (plist-get team-data :id))
+    (oset team name (plist-get team-data :name))
+    (oset team self self-data)
+    (oset team self-id (plist-get self-data :id))
+    (oset team self-name (plist-get self-data :name))
+    (cl-labels
+        ((on-open ()
+                  (slack-channel-list-update team)
+                  (slack-group-list-update team)
+                  (slack-im-list-update team)
+                  (slack-bot-list-update team)
+                  (cl-loop for buffer in (oref team slack-message-buffer)
+                           do (slack-if-let*
+                                  ((live-p (buffer-live-p buffer))
+                                   (slack-buffer (with-current-buffer buffer
+                                                   (and (bound-and-true-p
+                                                         slack-current-buffer)
+                                                        slack-current-buffer))))
+                                  (slack-buffer-load-missing-messages
+                                   slack-buffer)))
+                  (slack-team-kill-buffers
+                   team :except '(slack-message-buffer
+                                  slack-message-edit-buffer
+                                  slack-message-share-buffer
+                                  slack-room-message-compose-buffer))))
+      (slack-ws-open team :on-open #'on-open))))
+
+(defun slack-authorize-for-reconnect (team)
+  (cl-labels
+      ((on-error (&key error-thrown symbol-status &allow-other-keys)
+                 (slack-log (format "Slack Reconnect Failed: %s, %s"
+                                    error-thrown
+                                    symbol-status)
+                            team)
+                 (slack-ws-set-reconnect-timer team))
+       (on-success (data)
+                   (slack-on-authorize-for-reconnect data team)))
+    (slack-authorize team #'on-error #'on-success)))
+
+(defun slack-ws-reconnect (team &optional force)
+  "Reconnect if `reconnect-count' is not exceed `reconnect-count-max'.
+if FORCE is t, ignore `reconnect-count-max'.
+TEAM is one of `slack-teams'"
+  (cl-labels ((abort (team)
+                     (slack-notify-abandon-reconnect team)
+                     (slack-ws-close team t))
+              (use-reconnect-url ()
+                                 (slack-log "Reconnect with reconnect-url" team)
+                                 (slack-ws-open team
+                                                :ws-url (oref team reconnect-url)))
+              (do-reconnect (team)
+                            (cl-incf (oref team reconnect-count))
+                            (slack-ws-close team)
+                            (if (< 0 (length (oref team reconnect-url)))
+                                (slack-request-api-test team
+                                                        #'use-reconnect-url)
+                              (slack-authorize-for-reconnect team))))
+    (with-slots
+        (reconnect-count (reconnect-max reconnect-count-max)) team
+      (if (and (not force) reconnect-max (< reconnect-max reconnect-count))
+          (abort team)
+        (do-reconnect team)
+        (slack-log (format "Slack Websocket Try To Reconnect %s/%s"
+                           reconnect-count
+                           reconnect-max)
+                   team
+                   :level 'warn
+                   )))))
+
+(defun slack-ws-set-reconnect-timer (team)
+  (slack-ws-cancel-reconnect-timer team)
+  (cl-labels
+      ((on-timeout ()
+                   (slack-ws-reconnect team)))
+    (oset team reconnect-timer
+          (run-at-time (oref team reconnect-after-sec)
+                       nil
+                       #'on-timeout))))
+
+(defun slack-ws-cancel-reconnect-timer (team)
+  (with-slots (reconnect-timer) team
+    (if (timerp reconnect-timer)
+        (cancel-timer reconnect-timer))
+    (setq reconnect-timer nil)))
+
+(defun slack-ws-handle-pong (payload team)
+  (slack-ws-remove-from-resend-queue payload team)
+  (let* ((key (plist-get payload :time))
+         (timer (gethash key (oref team ping-check-timers))))
+    (slack-log (format "Receive PONG: %s" key)
+               team :level 'trace)
+    (slack-ws-set-ping-timer team)
+    (when timer
+      (cancel-timer timer)
+      (remhash key (oref team ping-check-timers))
+      (slack-log (format "Remove PING Check Timer: %s" key)
+                 team :level 'trace))))
+
+(defun slack-ws-handle-room-marked (payload team)
+  (slack-if-let* ((channel (plist-get payload :channel))
+                  (room (slack-room-find channel team))
+                  (ts (plist-get payload :ts))
+                  (unread-count-display (plist-get payload :unread_count_display)))
+      (progn
+        (oset room unread-count-display unread-count-display)
+        (oset room last-read ts)
+        (slack-update-modeline))))
+
+(defun slack-ws-handle-thread-marked (payload team)
+  (let* ((subscription (plist-get payload :subscription))
+         (thread-ts (plist-get subscription :thread_ts))
+         (channel (plist-get subscription :channel))
+         (room (slack-room-find channel team))
+         (parent (and room (slack-room-find-message room thread-ts))))
+    (when (and parent (oref parent thread))
+      (slack-thread-marked (oref parent thread) subscription))))
+
+(defun slack-ws-handle-thread-subscribed (payload team)
+  (let* ((thread-data (plist-get payload :subscription))
+         (room (slack-room-find (plist-get thread-data :channel) team))
+         (message (and (slack-room-find-message room (plist-get thread-data :thread_ts))))
+         (thread (and message (oref message thread))))
+    (when thread
+      (slack-thread-marked thread thread-data))))
+
+(defun slack-ws-handle-user-change (payload team)
+  (let* ((user (plist-get payload :user))
+         (id (plist-get user :id)))
+    (with-slots (users) team
+      (setq users
+            (cons user
+                  (cl-remove-if #'(lambda (u)
+                                    (string= id (plist-get u :id)))
+                                users))))))
+
+(defun slack-ws-handle-member-joined-channel (payload team)
+  (slack-if-let* ((user (plist-get payload :user))
+                  (channel (slack-room-find (plist-get payload :channel) team)))
+      (progn
+        (cl-pushnew user (oref channel members)
+                    :test #'string=)
+        (slack-log (format "%s joined %s"
+                           (slack-user-name user team)
+                           (slack-room-name channel team))
+                   team
+                   :level 'info))))
+
+(defun slack-ws-handle-member-left_channel (payload team)
+  (slack-if-let* ((user (plist-get payload :user))
+                  (channel (slack-room-find (plist-get payload :channel) team)))
+      (progn
+        (oset channel members
+              (cl-remove-if #'(lambda (e) (string= e user))
+                            (oref channel members)))
+        (slack-log (format "%s left %s"
+                           (slack-user-name user team)
+                           (slack-room-name channel team))
+                   team
+                   :level 'info))))
+
+(defun slack-ws-handle-dnd-updated (payload team)
+  (let* ((user (slack-user--find (plist-get payload :user) team))
+         (updated (slack-user-update-dnd-status user (plist-get payload :dnd_status))))
+    (oset team users
+          (cons updated (cl-remove-if #'(lambda (user) (string= (plist-get user :id)
+                                                                (plist-get updated :id)))
+                                      (oref team users))))))
+
+;; [star_added event | Slack](https://api.slack.com/events/star_added)
+(defun slack-ws-handle-star-added-to-file (file-id team)
+  (let ((file (slack-file-find file-id team)))
+    (cl-labels
+        ((update (&rest _args)
+                 (slack-with-file file-id team
+                   (slack-message-star-added file)
+                   (slack-message-update file team))))
+      (if file (update)
+        (slack-file-request-info file-id 1 team #'update)))))
+
+(defun slack-ws-handle-star-added (payload team)
+  (let* ((item (plist-get payload :item))
+         (item-type (plist-get item :type)))
+    (cl-labels
+        ((update-message (message)
+                         (slack-message-star-added message)
+                         (slack-message-update message team t t)))
+      (cond
+       ((string= item-type "file")
+        (slack-ws-handle-star-added-to-file (plist-get (plist-get item :file) :id)
+                                            team))
+       ((string= item-type "message")
+        (slack-if-let* ((room (slack-room-find (plist-get item :channel) team))
+                        (ts (plist-get (plist-get item :message) :ts))
+                        (message (slack-room-find-message room ts)))
+            (update-message message)))))
+    (slack-if-let* ((star (oref team star)))
+        (slack-star-add star item team))))
+
+
+;; [2018-07-25 16:30:03] (:type star_added :user U1013370U :item (:type file :file (:id FBWDT9VH8) :date_create 1532503802 :file_id FBWDT9VH8 :user_id USLACKBOT) :event_ts 1532503802.000378)
+(defun slack-ws-handle-star-removed-from-file (file-id team)
+  (let ((file (slack-file-find file-id team)))
+    (cl-labels
+        ((update (&rest _args)
+                 (slack-with-file file-id team
+                   (slack-message-star-removed file)
+                   (slack-message-update file team))))
+      (if file (update)
+        (slack-file-request-info file-id 1 team #'update)))))
+
+(defun slack-ws-handle-star-removed (payload team)
+  (let* ((item (plist-get payload :item))
+         (item-type (plist-get item :type)))
+    (cl-labels
+        ((update-message (message)
+                         (slack-message-star-removed message)
+                         (slack-message-update message team t t)))
+      (cond
+       ((string= item-type "file")
+        (slack-ws-handle-star-removed-from-file (plist-get (plist-get item :file) :id)
+                                                team))
+       ((string= item-type "message")
+        (slack-if-let* ((room (slack-room-find (plist-get item :channel) team))
+                        (ts (plist-get (plist-get item :message) :ts))
+                        (message (slack-room-find-message room ts)))
+            (update-message message)))))
+
+    (slack-if-let* ((star (oref team star)))
+        (slack-star-remove star item team))))
+
+(defun slack-ws-handle-app-conversation-invite-request (payload team)
+  (let* ((app-user (plist-get payload :app_user))
+         (channel-id (plist-get payload :channel_id))
+         (invite-message-ts (plist-get payload :invite_message_ts))
+         (scope-info (plist-get payload :scope_info))
+         (room (slack-room-find channel-id team)))
+    (if (yes-or-no-p (format "%s\n%s\n"
+                             (format "%s would like to do following in %s"
+                                     (slack-user-name app-user team)
+                                     (slack-room-name room team))
+                             (mapconcat #'(lambda (scope)
+                                            (format "* %s"
+                                                    (plist-get scope
+                                                               :short_description)))
+                                        scope-info
+                                        "\n")))
+        (slack-app-conversation-allow-invite-request team
+                                                     :channel channel-id
+                                                     :app-user app-user
+                                                     :invite-message-ts invite-message-ts)
+      (slack-app-conversation-deny-invite-request team
+                                                  :channel channel-id
+                                                  :app-user app-user
+                                                  :invite-message-ts invite-message-ts))))
+
+(cl-defun slack-app-conversation-allow-invite-request (team &key channel
+                                                            app-user
+                                                            invite-message-ts)
+  (let ((url "https://slack.com/api/apps.permissions.internal.add")
+        (params (list (cons "channel" channel)
+                      (cons "app_user" app-user)
+                      (cons "invite_message_ts" invite-message-ts)
+                      (cons "did_confirm" "true")
+                      (cons "send_ephemeral_error_message" "true"))))
+    (cl-labels
+        ((log-error (err)
+                    (slack-log (format "Error: %s, URL: %s, PARAMS: %s"
+                                       err
+                                       url
+                                       params)
+                               team :level 'error))
+         (on-success (&key data &allow-other-keys)
+                     (slack-request-handle-error
+                      (data "slack-app-conversation-allow-invite-request"
+                            #'log-error)
+                      (message "DATA: %s" data))))
+      (slack-request
+       (slack-request-create
+        url
+        team
+        :type "POST"
+        :params params
+        :success #'on-success)))))
+
+(cl-defun slack-app-conversation-deny-invite-request (team &key channel
+                                                           app-user
+                                                           invite-message-ts)
+  (let ((url "https://slack.com/api/apps.permissions.internal.denyAdd")
+        (params (list (cons "channel" channel)
+                      (cons "app_user" app-user)
+                      (cons "invite_message_ts" invite-message-ts))))
+    (cl-labels
+        ((log-error (err)
+                    (slack-log (format "Error: %s, URL: %s, PARAMS: %s"
+                                       err
+                                       url
+                                       params)
+                               team :level 'error))
+         (on-success (&key data &allow-other-keys)
+                     (slack-request-handle-error
+                      (data "slack-app-conversation-deny-invite-request"
+                            #'log-error)
+                      (message "DATA: %s" data))))
+      (slack-request
+       (slack-request-create
+        url
+        team
+        :type "POST"
+        :params params
+        :success #'on-success)))))
+
+(defun slack-ws-handle-commands-changed (payload team)
+  (let ((commands-updated (mapcar #'slack-command-create
+                                  (plist-get payload :commands_updated)))
+        (commands-removed (mapcar #'slack-command-create
+                                  (plist-get payload :commands_removed)))
+        (commands '()))
+    (cl-loop for command in (oref team commands)
+             if (and (not (cl-find-if #'(lambda (e) (slack-equalp command e))
+                                      commands-removed))
+                     (not (cl-find-if #'(lambda (e) (slack-equalp command e))
+                                      commands-updated)))
+             do (push command commands))
+    (cl-loop for command in commands-updated
+             do (push command commands))
+    (oset team commands commands)))
+
+(defun slack-ws-handle-dialog-opened (payload team)
+  (slack-if-let*
+      ((dialog-id (plist-get payload :dialog_id))
+       (client-token (plist-get payload :client_token))
+       (valid-client-tokenp (string= (slack-team-client-token team)
+                                     client-token)))
+      (slack-dialog-get dialog-id team)))
+
+(defun slack-ws-handle-room-left (payload team)
+  (slack-if-let* ((room (slack-room-find (plist-get payload :channel)
+                                         team)))
+      (progn
+        (when (slot-exists-p room 'is-member)
+          (oset room is-member nil))
+        (when (and (not (slack-channel-p room)) (slack-group-p room))
+          (oset team groups
+                (cl-remove-if #'(lambda (e)
+                                  (slack-room-equal-p e room))
+                              (oref team groups))))
+        (slack-log (format "You left %s" (slack-room-name room team))
+                   team :level 'info))))
+
+
+(provide 'slack-websocket)
+;;; slack-websocket.el ends here
+
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-websocket.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-websocket.elc
new file mode 100644
index 000000000000..03f7cd624564
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack-websocket.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack.el
new file mode 100644
index 000000000000..56e821c86163
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack.el
@@ -0,0 +1,229 @@
+;;; slack.el --- slack client for emacs              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords: tools
+;; Version: 0.0.2
+;; Package-Requires: ((websocket "1.8") (request "0.2.0") (oauth2 "0.10") (circe "2.3") (alert "1.2") (emojify "0.4") (emacs "24.4"))
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'cl-lib)
+(require 'subr-x)
+(require 'oauth2)
+(require 'color)
+
+(require 'slack-util)
+(require 'slack-team)
+(require 'slack-channel)
+(require 'slack-im)
+(require 'slack-file)
+(require 'slack-message-notification)
+(require 'slack-message-sender)
+(require 'slack-message-editor)
+(require 'slack-message-reaction)
+(require 'slack-user-message)
+(require 'slack-bot-message)
+(require 'slack-search)
+(require 'slack-reminder)
+(require 'slack-thread)
+(require 'slack-attachment)
+(require 'slack-emoji)
+(require 'slack-star)
+
+(require 'slack-buffer)
+(require 'slack-message-buffer)
+(require 'slack-message-edit-buffer)
+(require 'slack-message-share-buffer)
+(require 'slack-thread-message-buffer)
+(require 'slack-room-message-compose-buffer)
+(require 'slack-pinned-items-buffer)
+(require 'slack-user-profile-buffer)
+(require 'slack-file-list-buffer)
+(require 'slack-file-info-buffer)
+(require 'slack-thread-message-compose-buffer)
+(require 'slack-search-result-buffer)
+(require 'slack-stars-buffer)
+(require 'slack-dialog-buffer)
+(require 'slack-dialog-edit-element-buffer)
+
+(require 'slack-websocket)
+(require 'slack-request)
+(require 'slack-request-worker)
+
+(when (featurep 'helm)
+  (require 'helm-slack))
+
+(defgroup slack nil
+  "Emacs Slack Client"
+  :prefix "slack-"
+  :group 'tools)
+
+(defcustom slack-redirect-url "http://localhost:8080"
+  "Redirect url registered for Slack.")
+(defcustom slack-buffer-function #'switch-to-buffer-other-window
+  "Function to print buffer.")
+
+(defvar slack-use-register-team-string
+  "use `slack-register-team' instead.")
+
+(defcustom slack-client-id nil
+  "Client ID provided by Slack.")
+(make-obsolete-variable
+ 'slack-client-id slack-use-register-team-string
+ "0.0.2")
+(defcustom slack-client-secret nil
+  "Client Secret Provided by Slack.")
+(make-obsolete-variable
+ 'slack-client-secret slack-use-register-team-string
+ "0.0.2")
+(defcustom slack-token nil
+  "Slack token provided by Slack.
+set this to save request to Slack if already have.")
+(make-obsolete-variable
+ 'slack-token slack-use-register-team-string
+ "0.0.2")
+(defcustom slack-room-subscription '()
+  "Group or Channel list to subscribe notification."
+  :group 'slack)
+(make-obsolete-variable
+ 'slack-room-subscription slack-use-register-team-string
+ "0.0.2")
+(defcustom slack-typing-visibility 'frame
+  "When to show typing indicator.
+frame means typing slack buffer is in the current frame, show typing indicator.
+buffer means typing slack buffer is the current buffer, show typing indicator.
+never means never show typing indicator."
+  :type '(choice (const frame)
+                 (const buffer)
+                 (const never)))
+
+(defcustom slack-display-team-name t
+  "If nil, only display channel, im, group name."
+  :group 'slack)
+
+(defcustom slack-completing-read-function #'completing-read
+  "Require same argument with `completing-read'."
+  :group 'slack)
+
+(defconst slack-oauth2-authorize "https://slack.com/oauth/authorize")
+(defconst slack-oauth2-access "https://slack.com/api/oauth.access")
+(defconst slack-authorize-url "https://slack.com/api/rtm.start")
+(defconst slack-rtm-connect-url "https://slack.com/api/rtm.connect")
+
+(defun slack-authorize (team &optional error-callback success-callback)
+  (let ((authorize-request (oref team authorize-request)))
+    (if (and authorize-request (not (request-response-done-p authorize-request)))
+        (slack-log "Authorize Already Requested" team)
+      (cl-labels
+          ((on-error (&key error-thrown symbol-status response data)
+                     (oset team authorize-request nil)
+                     (slack-log (format "Slack Authorize Failed: %s" error-thrown)
+                                team)
+                     (when (functionp error-callback)
+                       (funcall error-callback
+                                :error-thrown error-thrown
+                                :symbol-status symbol-status
+                                :response response
+                                :data data)))
+           (on-success (&key data &allow-other-keys)
+                       (oset team authorize-request nil)
+                       (if success-callback
+                           (funcall success-callback data)
+                         (slack-on-authorize data team))))
+        (let ((request (slack-request
+                        (slack-request-create
+                         slack-rtm-connect-url
+                         team
+                         :params (list (cons "mpim_aware" "1"))
+                         :success #'on-success
+                         :error #'on-error))))
+          (oset team authorize-request request))))))
+
+(defun slack-update-team (data team)
+  (let ((self (plist-get data :self))
+        (team-data (plist-get data :team)))
+    (oset team id (plist-get team-data :id))
+    (oset team name (plist-get team-data :name))
+    (oset team self self)
+    (oset team self-id (plist-get self :id))
+    (oset team self-name (plist-get self :name))
+    (oset team ws-url (plist-get data :url))
+    (oset team domain (plist-get team-data :domain))
+    team))
+
+(cl-defun slack-on-authorize (data team)
+  (slack-request-handle-error
+   (data "slack-authorize")
+   (slack-log (format "Slack Authorization Finished" (oref team name)) team)
+   (let ((team (slack-update-team data team)))
+     (cl-labels
+         ((on-open ()
+                   (slack-channel-list-update team)
+                   (slack-group-list-update team)
+                   (slack-im-list-update team)
+                   (slack-bot-list-update team)
+                   (slack-request-emoji team)
+                   (slack-command-list-update team)
+                   (slack-update-modeline)))
+       (slack-ws-open team :on-open #'on-open)))))
+
+(defun slack-on-authorize-e
+    (&key error-thrown &allow-other-keys &rest_)
+  (error "slack-authorize: %s" error-thrown))
+
+(defun slack-oauth2-auth (team)
+  (with-slots (client-id client-secret) team
+    (oauth2-auth
+     slack-oauth2-authorize
+     slack-oauth2-access
+     client-id
+     client-secret
+     "client"
+     nil
+     slack-redirect-url)))
+
+(defun slack-request-token (team)
+  (with-slots (token) team
+    (setq token
+          (oauth2-token-access-token
+           (slack-oauth2-auth team)))))
+
+;;;###autoload
+(defun slack-start (&optional team)
+  (interactive)
+  (cl-labels ((start
+               (team)
+               (slack-team-kill-buffers team)
+               (slack-ws-close team)
+               (when (slack-team-need-token-p team)
+                 (slack-request-token team)
+                 (kill-new (oref team token))
+                 (message "Your Token is added to kill ring."))
+               (slack-authorize team)))
+    (if team
+        (start team)
+      (if slack-teams
+          (cl-loop for team in slack-teams
+                   do (start team))
+        (slack-start (call-interactively #'slack-register-team))))
+    (slack-enable-modeline)))
+
+(provide 'slack)
+;;; slack.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack.elc
new file mode 100644
index 000000000000..90fbe67ac873
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180913.651/slack.elc
Binary files differ