├── .gitignore ├── .ruby-version ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── UNLICENSE ├── app ├── assets │ ├── images │ │ └── .keep │ ├── javascripts │ │ ├── application.js │ │ ├── console-ish-input.coffee │ │ ├── custom-keyboards.coffee │ │ ├── image-closer.coffee │ │ ├── main.coffee │ │ ├── notifications.coffee │ │ ├── per-room-history.coffee │ │ ├── prettify-via-curl.coffee │ │ ├── slack_ready_function.coffee │ │ └── support-video-calls.coffee │ └── stylesheets │ │ └── application.scss ├── controllers │ ├── application_controller.rb │ ├── concerns │ │ └── .keep │ └── updates_controller.rb ├── helpers │ └── application_helper.rb ├── mailers │ └── .keep ├── models │ ├── .keep │ └── concerns │ │ └── .keep └── views │ └── layouts │ └── application.html.erb ├── bin ├── bundle ├── rails ├── rake ├── setup └── spring ├── config.ru ├── config ├── application.rb ├── boot.rb ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── cookies_serializer.rb │ ├── filter_parameter_logging.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── session_store.rb │ └── wrap_parameters.rb ├── locales │ └── en.yml ├── routes.rb └── secrets.yml ├── lib ├── assets │ └── .keep └── tasks │ └── .keep ├── log └── .keep ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico └── robots.txt ├── test ├── controllers │ └── .keep ├── fixtures │ └── .keep ├── helpers │ └── .keep ├── integration │ └── .keep ├── mailers │ └── .keep ├── models │ └── .keep └── test_helper.rb └── vendor ├── assets ├── javascripts │ └── .keep └── stylesheets │ └── .keep └── cache ├── actionmailer-4.2.0.gem ├── actionpack-4.2.0.gem ├── actionview-4.2.0.gem ├── activejob-4.2.0.gem ├── activemodel-4.2.0.gem ├── activerecord-4.2.0.gem ├── activesupport-4.2.0.gem ├── arel-6.0.0.gem ├── binding_of_caller-0.7.2.gem ├── builder-3.2.2.gem ├── byebug-5.0.0.gem ├── coffee-rails-4.1.0.gem ├── coffee-script-2.4.1.gem ├── coffee-script-source-1.9.1.1.gem ├── columnize-0.9.0.gem ├── debug_inspector-0.0.2.gem ├── erubis-2.7.0.gem ├── execjs-2.5.2.gem ├── globalid-0.3.5.gem ├── i18n-0.7.0.gem ├── json-1.8.3.gem ├── loofah-2.0.2.gem ├── mail-2.6.3.gem ├── mime-types-2.6.1.gem ├── mini_portile-0.6.2.gem ├── minitest-5.7.0.gem ├── nokogiri-1.6.6.2.gem ├── rack-1.6.4.gem ├── rack-test-0.6.3.gem ├── rails-4.2.0.gem ├── rails-deprecated_sanitizer-1.0.3.gem ├── rails-dom-testing-1.0.6.gem ├── rails-html-sanitizer-1.0.2.gem ├── railties-4.2.0.gem ├── rake-10.4.2.gem ├── sass-3.4.15.gem ├── sass-rails-5.0.3.gem ├── spring-1.3.6.gem ├── sprockets-3.2.0.gem ├── sprockets-rails-2.3.2.gem ├── sprockets-redirect-0.3.0.gem ├── thor-0.19.1.gem ├── thread_safe-0.3.5.gem ├── tilt-1.4.1.gem ├── tzinfo-1.2.2.gem ├── uglifier-2.7.1.gem └── web-console-2.1.3.gem /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | !/log/.keep 17 | /tmp 18 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.1.5-github 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | 4 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 5 | gem 'rails', '4.2.0' 6 | # Use SCSS for stylesheets 7 | gem 'sass-rails', '~> 5.0' 8 | # Use Uglifier as compressor for JavaScript assets 9 | gem 'uglifier', '>= 1.3.0' 10 | # Use CoffeeScript for .coffee assets and views 11 | gem 'coffee-rails', '~> 4.1.0' 12 | gem 'sprockets-redirect' 13 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 14 | # gem 'therubyracer', platforms: :ruby 15 | 16 | # Use ActiveModel has_secure_password 17 | # gem 'bcrypt', '~> 3.1.7' 18 | 19 | # Use Unicorn as the app server 20 | # gem 'unicorn' 21 | 22 | # Use Capistrano for deployment 23 | # gem 'capistrano-rails', group: :development 24 | 25 | group :development, :test do 26 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console 27 | gem 'byebug' 28 | 29 | # Access an IRB console on exception pages or by using <%= console %> in views 30 | gem 'web-console', '~> 2.0' 31 | 32 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 33 | gem 'spring' 34 | end 35 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actionmailer (4.2.0) 5 | actionpack (= 4.2.0) 6 | actionview (= 4.2.0) 7 | activejob (= 4.2.0) 8 | mail (~> 2.5, >= 2.5.4) 9 | rails-dom-testing (~> 1.0, >= 1.0.5) 10 | actionpack (4.2.0) 11 | actionview (= 4.2.0) 12 | activesupport (= 4.2.0) 13 | rack (~> 1.6.0) 14 | rack-test (~> 0.6.2) 15 | rails-dom-testing (~> 1.0, >= 1.0.5) 16 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 17 | actionview (4.2.0) 18 | activesupport (= 4.2.0) 19 | builder (~> 3.1) 20 | erubis (~> 2.7.0) 21 | rails-dom-testing (~> 1.0, >= 1.0.5) 22 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 23 | activejob (4.2.0) 24 | activesupport (= 4.2.0) 25 | globalid (>= 0.3.0) 26 | activemodel (4.2.0) 27 | activesupport (= 4.2.0) 28 | builder (~> 3.1) 29 | activerecord (4.2.0) 30 | activemodel (= 4.2.0) 31 | activesupport (= 4.2.0) 32 | arel (~> 6.0) 33 | activesupport (4.2.0) 34 | i18n (~> 0.7) 35 | json (~> 1.7, >= 1.7.7) 36 | minitest (~> 5.1) 37 | thread_safe (~> 0.3, >= 0.3.4) 38 | tzinfo (~> 1.1) 39 | arel (6.0.0) 40 | binding_of_caller (0.7.2) 41 | debug_inspector (>= 0.0.1) 42 | builder (3.2.2) 43 | byebug (5.0.0) 44 | columnize (= 0.9.0) 45 | coffee-rails (4.1.0) 46 | coffee-script (>= 2.2.0) 47 | railties (>= 4.0.0, < 5.0) 48 | coffee-script (2.4.1) 49 | coffee-script-source 50 | execjs 51 | coffee-script-source (1.9.1.1) 52 | columnize (0.9.0) 53 | debug_inspector (0.0.2) 54 | erubis (2.7.0) 55 | execjs (2.5.2) 56 | globalid (0.3.5) 57 | activesupport (>= 4.1.0) 58 | i18n (0.7.0) 59 | json (1.8.3) 60 | loofah (2.0.2) 61 | nokogiri (>= 1.5.9) 62 | mail (2.6.3) 63 | mime-types (>= 1.16, < 3) 64 | mime-types (2.6.1) 65 | mini_portile (0.6.2) 66 | minitest (5.7.0) 67 | nokogiri (1.6.6.2) 68 | mini_portile (~> 0.6.0) 69 | rack (1.6.4) 70 | rack-test (0.6.3) 71 | rack (>= 1.0) 72 | rails (4.2.0) 73 | actionmailer (= 4.2.0) 74 | actionpack (= 4.2.0) 75 | actionview (= 4.2.0) 76 | activejob (= 4.2.0) 77 | activemodel (= 4.2.0) 78 | activerecord (= 4.2.0) 79 | activesupport (= 4.2.0) 80 | bundler (>= 1.3.0, < 2.0) 81 | railties (= 4.2.0) 82 | sprockets-rails 83 | rails-deprecated_sanitizer (1.0.3) 84 | activesupport (>= 4.2.0.alpha) 85 | rails-dom-testing (1.0.6) 86 | activesupport (>= 4.2.0.beta, < 5.0) 87 | nokogiri (~> 1.6.0) 88 | rails-deprecated_sanitizer (>= 1.0.1) 89 | rails-html-sanitizer (1.0.2) 90 | loofah (~> 2.0) 91 | railties (4.2.0) 92 | actionpack (= 4.2.0) 93 | activesupport (= 4.2.0) 94 | rake (>= 0.8.7) 95 | thor (>= 0.18.1, < 2.0) 96 | rake (10.4.2) 97 | sass (3.4.15) 98 | sass-rails (5.0.3) 99 | railties (>= 4.0.0, < 5.0) 100 | sass (~> 3.1) 101 | sprockets (>= 2.8, < 4.0) 102 | sprockets-rails (>= 2.0, < 4.0) 103 | tilt (~> 1.1) 104 | spring (1.3.6) 105 | sprockets (3.2.0) 106 | rack (~> 1.0) 107 | sprockets-rails (2.3.2) 108 | actionpack (>= 3.0) 109 | activesupport (>= 3.0) 110 | sprockets (>= 2.8, < 4.0) 111 | sprockets-redirect (0.3.0) 112 | activesupport (>= 3.1.0) 113 | rack 114 | thor (0.19.1) 115 | thread_safe (0.3.5) 116 | tilt (1.4.1) 117 | tzinfo (1.2.2) 118 | thread_safe (~> 0.1) 119 | uglifier (2.7.1) 120 | execjs (>= 0.3.0) 121 | json (>= 1.8.0) 122 | web-console (2.1.3) 123 | activemodel (>= 4.0) 124 | binding_of_caller (>= 0.7.2) 125 | railties (>= 4.0) 126 | sprockets-rails (>= 2.0, < 4.0) 127 | 128 | PLATFORMS 129 | ruby 130 | 131 | DEPENDENCIES 132 | byebug 133 | coffee-rails (~> 4.1.0) 134 | rails (= 4.2.0) 135 | sass-rails (~> 5.0) 136 | spring 137 | sprockets-redirect 138 | uglifier (>= 1.3.0) 139 | web-console (~> 2.0) 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Slacks Hacks 2 | ============ 3 | 4 | Proof-of-concept rails app that serves up js/css for injecting into the 5 | [hackable slack client](https://github.com/bhuga/hackable-slack-client). 6 | 7 | Current examples: 8 | 9 | * restyles bot messages quite a bit 10 | * scrolls instead of wraps wide attachment messages (Great for bots!) 11 | * Colors your own messages slightly 12 | * **H E L V E T I C A** 13 | 14 | workflow-tools github slack 15 | 16 | The meat is in https://github.com/bhuga/slacks-hacks/blob/master/app/assets/javascripts/main.coffee and https://github.com/bhuga/slacks-hacks/blob/master/app/assets/stylesheets/application.scss. 17 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/app/assets/images/.keep -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. 9 | // 10 | // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require slack_ready_function 14 | //= require_tree . 15 | -------------------------------------------------------------------------------- /app/assets/javascripts/console-ish-input.coffee: -------------------------------------------------------------------------------- 1 | input = TS.client.ui.$msg_input 2 | 3 | # by default slack won't go to previous commands with 'up', just to the front 4 | # of the line. Fix that if there's no newlines in the message. 5 | input.bind "keydown", (e) -> 6 | return if e.altKey || e.ctrlKey || e.shiftKey 7 | return if input.val().indexOf("\n") != -1 8 | 9 | if (e.which == TS.utility.keymap.up && input.getCursorPosition() >= 1 && !e.movedHistory) 10 | TS.chat_history.onArrowKey(e, input) 11 | input.setCursorPosition(input.val().length) 12 | e.preventDefault() 13 | else if (e.which == TS.utility.keymap.down && input.getCursorPosition() < input.val().length) 14 | TS.chat_history.onArrowKey(e, input) 15 | input.setCursorPosition(input.val().length) 16 | e.preventDefault() 17 | 18 | input.bind "keydown", (e) -> 19 | # ctrl-w 20 | return unless e.ctrlKey == true and e.keyCode == 87 21 | 22 | currentIndex = input.getCursorPosition() 23 | currentValue = input.val() 24 | beforeCurrent = currentValue.substring(0, currentIndex) 25 | 26 | previousWhitespaceIndex = beforeCurrent.lastIndexOf(" ") 27 | previousWhitespaceIndex = 0 if previousWhitespaceIndex == -1 28 | valueWithWordRemoved = currentValue.slice(0, previousWhitespaceIndex) + currentValue.slice(currentIndex) 29 | TS.utility.populateInput(input, valueWithWordRemoved) 30 | input.setCursorPosition(previousWhitespaceIndex) 31 | 32 | input.bind "keydown", (e) -> 33 | # ctrl-k 34 | return unless e.ctrlKey == true and e.keyCode == 75 35 | 36 | currentIndex = input.getCursorPosition() 37 | currentValue = input.val() 38 | TS.utility.populateInput(input, currentValue.slice(0, currentIndex)) 39 | input.setCursorPosition(currentIndex) 40 | 41 | input.bind "keydown", (e) -> 42 | # ctrl-u 43 | return unless e.ctrlKey == true and e.keyCode == 85 44 | 45 | currentIndex = input.getCursorPosition() 46 | currentValue = input.val() 47 | TS.utility.populateInput(input, currentValue.slice(currentIndex)) 48 | input.setCursorPosition(0) 49 | 50 | # here be dragons: !$ 51 | old_submit = TS.view.submit 52 | TS.view.submit = (event) -> 53 | current = input.val() 54 | if current.indexOf("!$") != -1 55 | history = TS.chat_history.initializeChannelHistory(TS.model.active_cid) 56 | last_message = history.entries[0] 57 | last_word = last_message.slice(last_message.trim().lastIndexOf(" ") + 1) 58 | # Prevents expanding `!$`. Should prevent expanding in backticks entirely, maybe? 59 | replaced = current.replace(/(^|[^`])!\$/g, "$1" + last_word) 60 | input.val(replaced) 61 | old_submit(event) 62 | -------------------------------------------------------------------------------- /app/assets/javascripts/custom-keyboards.coffee: -------------------------------------------------------------------------------- 1 | # A rough implementation of 'custom keyboards', similar to 2 | # https://core.telegram.org/bots#keyboards 3 | 4 | fillMessageBar = (text) -> 5 | $("#message-input").val(text) 6 | $("#message-input").focus() 7 | 8 | window.repaintKeyboards = -> 9 | label_regex = /label:([^:/]+)(?::([^:/]+))?/ 10 | buttons = $('a').filter -> 11 | @href.indexOf("https://a.button") == 0 12 | 13 | buttons.each (_, el) -> 14 | fields = el.href.split("/", 5) 15 | label = decodeURIComponent(fields[3]) 16 | command = decodeURIComponent(fields[4]) 17 | button_class = "" 18 | if match = label.match(label_regex) 19 | window.ev = match 20 | console.log match 21 | color = match[2] 22 | button_class = "icon" 23 | label = "" 24 | button = $("") 25 | button.click -> 26 | fillMessageBar(command) 27 | $(el).replaceWith(button) 28 | 29 | images = $('a').filter -> 30 | @href.indexOf("https://a.img.button") == 0 31 | 32 | images.each (_, el) -> 33 | fields = el.href.split("/", 5) 34 | image_url = decodeURIComponent(fields[3]) 35 | command = decodeURIComponent(fields[4]) 36 | button = $("") 37 | button.click -> 38 | fillMessageBar(command) 39 | $(el).replaceWith(button) 40 | 41 | selects = $('a').filter -> 42 | @href.indexOf("https://a.select") == 0 43 | 44 | selects.each (_, el) -> 45 | fields = el.href.split("/").slice(3) 46 | options = fields.map (field, i) -> 47 | field = decodeURIComponent(field) 48 | [title, command] = field.split(":") 49 | selected = if i == 0 then "selected" else "" 50 | "" 51 | select = $("") 52 | select.change -> 53 | fillMessageBar(select.val()) 54 | $(el).replaceWith(select) 55 | 56 | 57 | 58 | slackReadyFunction(window.repaintKeyboards) 59 | -------------------------------------------------------------------------------- /app/assets/javascripts/image-closer.coffee: -------------------------------------------------------------------------------- 1 | # stolen from http://stackoverflow.com/questions/6029251/jquery-bind-event-listener-before-another 2 | # thanks, internet stranger! 3 | $.fn.preBind = (type, data, fn) -> 4 | @each -> 5 | thing = $(@) 6 | thing.bind(type, data, fn); 7 | currentBindings = $._data(this, 'events')[type] 8 | if $.isArray(currentBindings) 9 | currentBindings.unshift(currentBindings.pop()) 10 | return @ 11 | 12 | # Slack uses a giant function, `doLinkThings`, over the entire message. I'm 13 | # not sure why yet, performance somehow? If we want to make something happen 14 | # instead of one of their events, we can't use $(el).bind -- the msg div 15 | # event is attached directly. So we cram our event to the front of the list. 16 | $(TS.client.ui.$msgs_div).preBind 'click', (event) -> 17 | # this crazy offset stuff is because we're using a pseudo-element to add the 18 | # 'X' to click on. These numbers depend on css rules. You might ask, 19 | # What could go wrong?, and I'd say, Why are you injecting javascript if that 20 | # worries you? 21 | return unless $(event.target).hasClass("msg_inline_img_container") 22 | 23 | width = event.target.clientWidth 24 | inXRange = event.offsetX >= (width - 45) && event.offsetX <= (width - 15) 25 | inYRange = event.offsetY >= 15 && event.offsetY <= 45 26 | if inXRange && inYRange 27 | event.preventDefault() 28 | event.stopPropagation() 29 | event.stopImmediatePropagation() 30 | $(event.target).closest('.msg_inline_img_holder').addClass('hidden') 31 | -------------------------------------------------------------------------------- /app/assets/javascripts/main.coffee: -------------------------------------------------------------------------------- 1 | 2 | console.log "Hello from slacks hacks!" 3 | 4 | botify = (selector) -> 5 | selector.each (_, el) -> 6 | if $(el).find('.bot_label').length != 0 7 | $(el).addClass 'bot' 8 | 9 | botAdder = (arg1, msg) -> 10 | botify($('[data-ts="' + msg.ts + '"]')) 11 | 12 | botifyMessages = => 13 | botify($('.message')) 14 | 15 | # Botify the currently-viewed channel 16 | botifyMessages() 17 | 18 | # Attach .sent_by_me to messages sent by the current user 19 | meAdder = (selector) -> 20 | selector.each (_, el) -> 21 | $(el).addClass 'sent_by_me' 22 | 23 | sentByMeMessages = -> 24 | selector = '.message_sender[data-member-id=' + TS.boot_data.user_id + ']' 25 | messages = $(selector).closest('ts-message') 26 | messages.each (_, el) -> 27 | $(el).addClass 'sent_by_me' 28 | 29 | addMultilineToMessages = -> 30 | $('.attachment_flush_text').each (_, el) -> 31 | selection = $(el) 32 | if selection.html().match(/
/) 33 | selection.closest('.content').first().addClass('multiline_attachment') 34 | 35 | # replace slack hardcoded width/height with max width width/height 36 | slackBuildImgDiv = TS.templates.builders.buildInlineImgDiv 37 | TS.templates.builders.buildInlineImgDiv = (args...) -> 38 | # should match css rule for .attachment_group .msg_inline_img_holder .msg_inline_img img 39 | maxImageHeight = 600 40 | 41 | result = slackBuildImgDiv(args...) 42 | width = result.match(/data-width="(\d+)"/)[1] 43 | max_width = TS.client.ui.$msgs_div.width() - 156 44 | 45 | height = result.match(/data-height="(\d+)"/)[1] 46 | max_height = if max_width >= width 47 | height 48 | else 49 | (max_width / width) * height 50 | 51 | if max_height > maxImageHeight 52 | old_max_height = max_height 53 | max_height = maxImageHeight 54 | max_width = (height / old_max_height) * max_width 55 | 56 | #console.log "width: #{width} mw: #{max_width} height: #{height} mh: #{max_height}" 57 | result = result.replace(/
]*>/, 58 | "
") 59 | result 60 | 61 | # when scrolling to the bottom, force a redraw before we actually scroll, or 62 | # our nice big images will throw things off. 63 | slackismtb = TS.client.ui.instaScrollMsgsToBottom 64 | TS.client.ui.instaScrollMsgsToBottom = (args...) -> 65 | TS.client.ui.checkInlineImgsAndIframesMain() 66 | TS.client.msg_pane.rebuild_sig.dispatch() 67 | slackismtb(args...) 68 | 69 | redraw = -> 70 | botifyMessages() 71 | sentByMeMessages() 72 | addMultilineToMessages() 73 | 74 | slackReadyFunction(redraw) 75 | 76 | #window.$div = TS.client.ui.$msgs_div 77 | #window.$scroller_div = TS.client.ui.$msgs_scroller_div 78 | -------------------------------------------------------------------------------- /app/assets/javascripts/notifications.coffee: -------------------------------------------------------------------------------- 1 | # The bounce functions have been added to the main application so we can 2 | # not expose any native functions. see expose-window-apis.js in hackable-slack-client. 3 | # these will be removed "soon" 4 | unless window.dock? 5 | window.dock = {} 6 | 7 | window.dock.bounce = -> 8 | preference = TS.model.prefs.mac_ssb_bounce 9 | return unless preference is "long" or preference is "short" 10 | type = if TS.model.prefs.mac_ssb_bounce == "short" then "informational" else "critical" 11 | host.ipc.send('bounce', { type: type }) 12 | 13 | window.dock.badge = (message) -> 14 | host.ipc.send('badge', { badge_text: message }) 15 | 16 | # At boot, mark all channels as read once. 17 | window.channelsViewedAt = {} 18 | for channel in TS.model.channels when channel.is_member 19 | channelsViewedAt[channel.id] = Date.now() / 1000.0 20 | # Mark channels as viewed later 21 | TS.channels.switched_sig.add -> 22 | console.log("Marking #{TS.channels.getChannelById(TS.model.active_channel_id).name} as viewed") 23 | channelsViewedAt[TS.model.active_channel_id] = (Date.now() / 1000.0) 24 | 25 | previousTotal = 0 26 | 27 | setInterval -> 28 | total = 0 29 | 30 | $("#channel-list .unread_highlights").each (_, el) -> 31 | total += parseInt($(el).text()) 32 | $("#im-list .unread_highlights").each (_, el) -> 33 | total += parseInt($(el).text()) 34 | 35 | # This can cause weird re-bounces in situations like reading messages in 36 | # another window, but this is a lot easier than error-prone individual message 37 | # checking. 38 | if total > 0 && total != previousTotal 39 | dock.bounce() 40 | dock.badge(total.toString()) 41 | else if total == 0 42 | dock.badge("") 43 | 44 | previousTotal = total; 45 | , 2000 46 | -------------------------------------------------------------------------------- /app/assets/javascripts/per-room-history.coffee: -------------------------------------------------------------------------------- 1 | existingMessageHistory = localStorage.getItem("per_room_history") 2 | if existingMessageHistory? 3 | try 4 | history = JSON.parse(existingMessageHistory) 5 | TS.model.per_room_input_history = history 6 | catch e 7 | console.log "Failed to parse existing history. Moving on with life." 8 | 9 | TS.chat_history.initializeChannelHistory = (cid) -> 10 | TS.model.per_room_input_history ||= {} 11 | history = TS.model.per_room_input_history[TS.model.active_cid] 12 | if !history? 13 | history = {} 14 | history.index = -1 15 | history.entries = [] 16 | TS.model.per_room_input_history[TS.model.active_cid] = history 17 | 18 | return history 19 | 20 | TS.chat_history.add = (txt) -> 21 | unless TS.model.prefs?.arrow_history 22 | return 23 | if txt is "" 24 | return 25 | 26 | history = TS.chat_history.initializeChannelHistory(TS.model.active_cid) 27 | 28 | entries = history.entries 29 | 30 | index = entries.indexOf(txt) 31 | if index != -1 32 | entries.splice(index, 1) 33 | entries.unshift(txt.trim()) 34 | entries.splice(30) 35 | localStorage.setItem("per_room_history", JSON.stringify(TS.model.per_room_input_history)) 36 | 37 | TS.chat_history.resetPosition = (why) -> 38 | history = TS.chat_history.initializeChannelHistory(TS.model.active_cid) 39 | history.index = -1 40 | 41 | TS.chat_history.onArrowKey = (e, input) -> 42 | unless TS.model.prefs?.arrow_history 43 | return 44 | history = TS.chat_history.initializeChannelHistory(TS.model.active_cid) 45 | return unless history.entries.length 46 | 47 | txt = input.val() 48 | hist_text = "" 49 | if history.index < 0 50 | history.current = txt 51 | 52 | if e.which == TS.utility.keymap.up 53 | history.index += 1 54 | if history.index >= history.entries.length 55 | history.index = history.entries.length - 1 56 | return 57 | else if e.which == TS.utility.keymap.down 58 | history.index -= 1 59 | if history.index < 0 60 | history.index = -1 61 | hist_text = history.current 62 | else 63 | return 64 | 65 | e.movedHistory = true 66 | hist_text ||= history.entries[history.index] 67 | e.preventDefault() 68 | TS.utility.populateInput(TS.client.ui.$msg_input, hist_text) 69 | input.setCursorPosition(input.val().length) 70 | -------------------------------------------------------------------------------- /app/assets/javascripts/prettify-via-curl.coffee: -------------------------------------------------------------------------------- 1 | window.prettifyJsCommand = -> 2 | urls = $('script').map (_, script) -> 3 | $(script).attr('src') 4 | 5 | jsUrls = _.filter (urls), (url) -> 6 | (url.indexOf("slack-edge")!= -1) && (url.lastIndexOf("js") == url.length - 2) 7 | 8 | console.log jsUrls 9 | commands = jsUrls.map (url) -> 10 | fields = url.split("/") 11 | basename = fields[fields.length - 1] 12 | "curl -s #{url} | js-beautify > #{basename}" 13 | 14 | command = commands.join " ; and " 15 | input = $("") 16 | $('body').append(input) 17 | input.get(0).select() 18 | document.execCommand("copy") 19 | window.input = input 20 | input.remove() 21 | 22 | console.log "Paste your clipboard into the shell" 23 | -------------------------------------------------------------------------------- /app/assets/javascripts/slack_ready_function.coffee: -------------------------------------------------------------------------------- 1 | # 🙈 2 | slackRebuildMsg = TS.client.msg_pane.rebuildMsg 3 | TS.client.msg_pane.rebuild_sig = new signals.Signal 4 | TS.client.msg_pane.rebuildMsg = -> 5 | slackRebuildMsg() 6 | TS.client.msg_pane.rebuild_sig.dispatch() 7 | 8 | window.slackReadyFunction = (func) -> 9 | TS.client.msg_pane.rebuild_sig.add func 10 | 11 | for channel_type in ["groups", "channels", "ims", "mpims"] 12 | TS[channel_type].message_received_sig.add func 13 | TS[channel_type].switched_sig.add func 14 | TS[channel_type].history_fetched_sig.add func 15 | 16 | func() 17 | -------------------------------------------------------------------------------- /app/assets/javascripts/support-video-calls.coffee: -------------------------------------------------------------------------------- 1 | TS.utility.calls.launchVideoCall = (call_info) -> 2 | window.open(TS.boot_data.team_url + "call/" + call_info.id) 3 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any styles 10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new 11 | * file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | */ 16 | #message_edit_form #message-input, 17 | #messages-input-container #message-input, 18 | .inline_message_input_container #message-input, 19 | .ts_tip, 20 | #active_channel_name { 21 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 22 | } 23 | .message_content { 24 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 25 | line-height: 22px; 26 | font-size: 14px; 27 | } 28 | 29 | .attachment_group .msg_inline_img_holder .msg_inline_img img { 30 | max-height: 600px; 31 | } 32 | 33 | .msg_inline_img_holder .msg_inline_img_container { 34 | max-width: 100%; 35 | } 36 | /* 'bot_message' is attached to things from incoming webhooks -- usually notifications. 37 | 'bot' is added to that as well and is hubot replies. */ 38 | 39 | .bot { 40 | background-color: #FAFAFA; 41 | &:hover { 42 | background-color: #FAFAFA; 43 | } 44 | border-bottom: 1px solid #eee; 45 | border-top: 1px solid #eee; 46 | 47 | .inline_attachment_wrapper { 48 | padding-top: 0px; 49 | padding-bottom: 0px; 50 | } 51 | 52 | .message_content { 53 | font-family: Menlo, Consolas, monospace; 54 | font-size: 80%; 55 | font-weight: bold; 56 | } 57 | 58 | .msg_inline_attachment_column { 59 | font-size: .75rem; 60 | } 61 | } 62 | .bot_message .message_content { 63 | color: #bebebe; 64 | } 65 | 66 | ts-message { 67 | padding-top: 0px; 68 | padding-bottom: 0px; 69 | } 70 | 71 | .attachment_group { 72 | max-width: inherit; 73 | margin: 0; 74 | } 75 | 76 | .msg_inline_img_holder .msg_inline_img_container:hover::after { 77 | height: 30px; 78 | width: 30px; 79 | position: absolute; 80 | right:15px; 81 | top: 15px; 82 | background-color: #fff; 83 | font-family: Slack; 84 | font-size: 30px; 85 | line-height: 33px; 86 | font-style: normal; 87 | font-weight: 400; 88 | content: "\E278"; 89 | opacity: 0.5; 90 | border-radius: 4px; 91 | cursor: pointer; 92 | } 93 | 94 | .msg_inline_file_preview_toggler, .inline_img_bytes, .msg_inline_img_collapser { 95 | display: none; 96 | } 97 | 98 | .color_bot_Hubot, .color_bot_hubot { 99 | display: none !important; 100 | } 101 | 102 | /* Allow long bot message to scroll */ 103 | .bot_label ~ .message_body .content.multiline_attachment { 104 | font-family: menlo; 105 | font-size: 12px; 106 | white-space: nowrap; 107 | overflow: auto; 108 | max-width: 100%; 109 | display: block; 110 | } 111 | 112 | /* Move text expander on its own line */ 113 | .bot_label ~ .message_body .dynamic_content_max_width .rest_text_expander { 114 | display: block; 115 | } 116 | 117 | /* Unify timestamp style */ 118 | .timestamp { 119 | float: right; 120 | font-family: menlo; 121 | font-size: 11px; 122 | margin-top: 1px; 123 | } 124 | 125 | /* Smaller avatar becasue of the padding changes */ 126 | ts-message .member_image { 127 | transform: scale(0.8); 128 | } 129 | 130 | ts-message .message_gutter, 131 | ts-message .message_gutter a { 132 | font-family: menlo; 133 | font-size: 11px; 134 | text-align: center; 135 | } 136 | 137 | /* Move star button becasue of the padding changes */ 138 | .message_star_holder { 139 | left: 8px; 140 | position: absolute; 141 | top: -1px; 142 | } 143 | 144 | /* Smaller emojis to go with smaller text */ 145 | .emoji-outer { 146 | transform: scale(0.8); 147 | } 148 | 149 | /* Don't separate bot messages */ 150 | .bot_message + .bot_message, .bot + .bot_message, .bot_message + .bot, .bot + .bot { 151 | border-top: 0; 152 | } 153 | 154 | #messages_container .message_gutter { 155 | padding-left: 20px; 156 | } 157 | 158 | /* disable distracting message hover */ 159 | ts-message.active:not(.standalone):not(.multi_delete_mode):not(.highlight):not(.sent_by_me):not(.bot), ts-message:hover:not(.standalone):not(.multi_delete_mode):not(.highlight):not(.sent_by_me):not(.bot) { 160 | background: inherit; 161 | } 162 | 163 | /* Highlight messages sent by current user */ 164 | ts-message.sent_by_me { 165 | background: #fff9f0; 166 | &:hover { 167 | background: #fff9f0 !important; /* slack's hover selector is incredibly specific */ 168 | } 169 | } 170 | 171 | .inserted_button { 172 | border-radius: 5px; 173 | background: #fbfbfa; 174 | line-height: 11px; 175 | height: 22px; 176 | font-size: 14px; 177 | font-family: Slack-Lato,appleLogo,sans-serif; 178 | font-weight: 700; 179 | text-shadow: none; 180 | color: #555459; 181 | border: thin solid #ddd; 182 | &:hover { 183 | background: #fff; 184 | color: #3aa3e3; 185 | } 186 | 187 | &.icon { 188 | padding-left: 2px; 189 | padding-right: 2px; 190 | } 191 | 192 | .red { 193 | color: #E4061B; 194 | &:hover::before { 195 | color: #F95400; 196 | font-weight: bold; 197 | } 198 | } 199 | .green { 200 | color: #09D209; 201 | &:hover::before { 202 | color: #09D209; 203 | font-weight: bold; 204 | } 205 | } 206 | 207 | &.image { 208 | border-radius: 15px; 209 | height: inherit; 210 | margin: 4px; 211 | padding: 0; 212 | 213 | &:hover { 214 | border-color: #4078C0; 215 | border-width: 5px; 216 | margin: 0; 217 | } 218 | 219 | img { 220 | height: 100px; 221 | border-radius:10px; 222 | } 223 | } 224 | } 225 | 226 | .inserted_select { 227 | width: inherit; 228 | -webkit-appearance: menulist; 229 | font-size: inherit; 230 | } 231 | 232 | pre.special_formatting { 233 | white-space: nowrap; 234 | overflow: auto; 235 | } 236 | 237 | .message_body i .emoji-sizer { 238 | transform: skew(-14deg); 239 | } 240 | 241 | .message_body b .emoji-sizer { 242 | animation-duration: 1.6s; 243 | animation-name: pulse; 244 | animation-timing-function: ease-in-out; 245 | animation-iteration-count: infinite; 246 | } 247 | 248 | @keyframes pulse { 249 | 0%, 100% { 250 | transform: scale(1); 251 | } 252 | 50% { 253 | transform: scale(1.5); 254 | } 255 | } 256 | .file_container.snippet_container.snippet_wrap .CodeMirror .CodeMirror-code>div pre, .file_container.snippet_container.snippet_wrap .sssh-code .sssh-line pre, .message .file_container.snippet_container .CodeMirror .CodeMirror-code>div pre, .message .file_container.snippet_container .sssh-code .sssh-line pre { 257 | white-space: pre; 258 | word-wrap: normal; 259 | } 260 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /app/controllers/updates_controller.rb: -------------------------------------------------------------------------------- 1 | class UpdatesController < ApplicationController 2 | def squirrel 3 | version = params[:version] 4 | if version == latest_version 5 | return head :no_content 6 | end 7 | return render :json => latest_json 8 | end 9 | 10 | private 11 | 12 | def latest_json 13 | { 14 | "url" => "https://dinosaur.s3.amazonaws.com/hackable-slack-client-#{latest_version}.zip", 15 | "notes" => "Latest version", 16 | "name" => latest_version, 17 | "pub_date" => Time.now.iso8601 18 | } 19 | end 20 | 21 | def latest_version 22 | ENV["LATEST_CLIENT_VERSION"] 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/app/mailers/.keep -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/app/models/.keep -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/app/models/concerns/.keep -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SlacksHacks 5 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> 6 | <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> 7 | <%= csrf_meta_tags %> 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | APP_PATH = File.expand_path('../../config/application', __FILE__) 7 | require_relative '../config/boot' 8 | require 'rails/commands' 9 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | require_relative '../config/boot' 7 | require 'rake' 8 | Rake.application.run 9 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | 4 | # path to your application root. 5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 6 | 7 | Dir.chdir APP_ROOT do 8 | # This script is a starting point to setup your application. 9 | # Add necessary setup steps to this file: 10 | 11 | puts "== Installing dependencies ==" 12 | system "gem install bundler --conservative" 13 | system "bundle check || bundle install" 14 | 15 | # puts "\n== Copying sample files ==" 16 | # unless File.exist?("config/database.yml") 17 | # system "cp config/database.yml.sample config/database.yml" 18 | # end 19 | 20 | puts "\n== Preparing database ==" 21 | system "bin/rake db:setup" 22 | 23 | puts "\n== Removing old logs and tempfiles ==" 24 | system "rm -f log/*" 25 | system "rm -rf tmp/cache" 26 | 27 | puts "\n== Restarting application server ==" 28 | system "touch tmp/restart.txt" 29 | end 30 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require "rubygems" 8 | require "bundler" 9 | 10 | if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m) 11 | Gem.paths = { "GEM_PATH" => [Bundler.bundle_path.to_s, *Gem.path].uniq } 12 | gem "spring", match[1] 13 | require "spring/binstub" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require "action_controller/railtie" 4 | require "action_mailer/railtie" 5 | require "sprockets/railtie" 6 | require "rails/test_unit/railtie" 7 | 8 | # Require the gems listed in Gemfile, including any gems 9 | # you've limited to :test, :development, or :production. 10 | Bundler.require(*Rails.groups) 11 | 12 | module SlacksHacks 13 | class Application < Rails::Application 14 | # Settings in config/environments/* take precedence over those specified here. 15 | # Application configuration should go into files in config/initializers 16 | # -- all .rb files in that directory are automatically loaded. 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations. 23 | #config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | 30 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 31 | # yet still be able to expire them through the digest params. 32 | config.assets.digest = true 33 | 34 | # Adds additional error checking when serving assets at runtime. 35 | # Checks for improperly declared sprockets dependencies. 36 | # Raises helpful error messages. 37 | config.assets.raise_runtime_errors = true 38 | 39 | # Raises error for missing translations 40 | # config.action_view.raise_on_missing_translations = true 41 | end 42 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like 20 | # NGINX, varnish or squid. 21 | # config.action_dispatch.rack_cache = true 22 | 23 | # Disable serving static files from the `/public` folder by default since 24 | # Apache or NGINX already handles this. 25 | config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? 26 | 27 | # Compress JavaScripts and CSS. 28 | config.assets.js_compressor = :uglifier 29 | config.assets.digest = true 30 | # config.assets.css_compressor = :sass 31 | 32 | # Do not fallback to assets pipeline if a precompiled asset is missed. 33 | config.assets.compile = false 34 | 35 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 36 | # yet still be able to expire them through the digest params. 37 | config.assets.digest = true 38 | 39 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 40 | 41 | # Specifies the header that your server uses for sending files. 42 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 43 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 44 | 45 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 46 | # config.force_ssl = true 47 | 48 | # Use the lowest log level to ensure availability of diagnostic information 49 | # when problems arise. 50 | config.log_level = :debug 51 | 52 | # Prepend all log lines with the following tags. 53 | # config.log_tags = [ :subdomain, :uuid ] 54 | 55 | # Use a different logger for distributed setups. 56 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 57 | 58 | # Use a different cache store in production. 59 | # config.cache_store = :mem_cache_store 60 | 61 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 62 | # config.action_controller.asset_host = 'http://assets.example.com' 63 | 64 | # Ignore bad email addresses and do not raise email delivery errors. 65 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 66 | # config.action_mailer.raise_delivery_errors = false 67 | 68 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 69 | # the I18n.default_locale when a translation cannot be found). 70 | config.i18n.fallbacks = true 71 | 72 | # Send deprecation notices to registered listeners. 73 | config.active_support.deprecation = :notify 74 | 75 | # Use default logging formatter so that PID and timestamp are not suppressed. 76 | config.log_formatter = ::Logger::Formatter.new 77 | 78 | # Do not dump schema after migrations. 79 | #config.active_record.dump_schema_after_migration = false 80 | end 81 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static file server for tests with Cache-Control for performance. 16 | config.serve_static_files = true 17 | config.static_cache_control = 'public, max-age=3600' 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Randomize the order test cases are executed. 35 | config.active_support.test_order = :random 36 | 37 | # Print deprecation notices to the stderr. 38 | config.active_support.deprecation = :stderr 39 | 40 | # Raises error for missing translations 41 | # config.action_view.raise_on_missing_translations = true 42 | end 43 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :json 4 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_slacks-hacks_session' 4 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | get "/updates" => "updates#squirrel" 3 | end 4 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: c98e9b9c857dc00ca4df93502a8bf7baf150775616f261a03791a85aa033a1e49ea4edc240b52c9a36ceb014fef476f02bf922018f5f913b6334cc90a9d433b5 15 | 16 | test: 17 | secret_key_base: 56c8abd12e84a49d02c4e0cf9bef965adcfc78dd1a6445e091bbf91121cd4a2cb47bee5a4111ccd9119c1cc2927e4afb55fd06e4c0ce091be188bd1efd505ffc 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 23 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/lib/assets/.keep -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/lib/tasks/.keep -------------------------------------------------------------------------------- /log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/log/.keep -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/public/favicon.ico -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /test/controllers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/test/controllers/.keep -------------------------------------------------------------------------------- /test/fixtures/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/test/fixtures/.keep -------------------------------------------------------------------------------- /test/helpers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/test/helpers/.keep -------------------------------------------------------------------------------- /test/integration/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/test/integration/.keep -------------------------------------------------------------------------------- /test/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/test/mailers/.keep -------------------------------------------------------------------------------- /test/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/test/models/.keep -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RAILS_ENV'] ||= 'test' 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 7 | fixtures :all 8 | 9 | # Add more helper methods to be used by all tests here... 10 | end 11 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/assets/javascripts/.keep -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/assets/stylesheets/.keep -------------------------------------------------------------------------------- /vendor/cache/actionmailer-4.2.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/actionmailer-4.2.0.gem -------------------------------------------------------------------------------- /vendor/cache/actionpack-4.2.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/actionpack-4.2.0.gem -------------------------------------------------------------------------------- /vendor/cache/actionview-4.2.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/actionview-4.2.0.gem -------------------------------------------------------------------------------- /vendor/cache/activejob-4.2.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/activejob-4.2.0.gem -------------------------------------------------------------------------------- /vendor/cache/activemodel-4.2.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/activemodel-4.2.0.gem -------------------------------------------------------------------------------- /vendor/cache/activerecord-4.2.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/activerecord-4.2.0.gem -------------------------------------------------------------------------------- /vendor/cache/activesupport-4.2.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/activesupport-4.2.0.gem -------------------------------------------------------------------------------- /vendor/cache/arel-6.0.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/arel-6.0.0.gem -------------------------------------------------------------------------------- /vendor/cache/binding_of_caller-0.7.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/binding_of_caller-0.7.2.gem -------------------------------------------------------------------------------- /vendor/cache/builder-3.2.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/builder-3.2.2.gem -------------------------------------------------------------------------------- /vendor/cache/byebug-5.0.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/byebug-5.0.0.gem -------------------------------------------------------------------------------- /vendor/cache/coffee-rails-4.1.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/coffee-rails-4.1.0.gem -------------------------------------------------------------------------------- /vendor/cache/coffee-script-2.4.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/coffee-script-2.4.1.gem -------------------------------------------------------------------------------- /vendor/cache/coffee-script-source-1.9.1.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/coffee-script-source-1.9.1.1.gem -------------------------------------------------------------------------------- /vendor/cache/columnize-0.9.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/columnize-0.9.0.gem -------------------------------------------------------------------------------- /vendor/cache/debug_inspector-0.0.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/debug_inspector-0.0.2.gem -------------------------------------------------------------------------------- /vendor/cache/erubis-2.7.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/erubis-2.7.0.gem -------------------------------------------------------------------------------- /vendor/cache/execjs-2.5.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/execjs-2.5.2.gem -------------------------------------------------------------------------------- /vendor/cache/globalid-0.3.5.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/globalid-0.3.5.gem -------------------------------------------------------------------------------- /vendor/cache/i18n-0.7.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/i18n-0.7.0.gem -------------------------------------------------------------------------------- /vendor/cache/json-1.8.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/json-1.8.3.gem -------------------------------------------------------------------------------- /vendor/cache/loofah-2.0.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/loofah-2.0.2.gem -------------------------------------------------------------------------------- /vendor/cache/mail-2.6.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/mail-2.6.3.gem -------------------------------------------------------------------------------- /vendor/cache/mime-types-2.6.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/mime-types-2.6.1.gem -------------------------------------------------------------------------------- /vendor/cache/mini_portile-0.6.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/mini_portile-0.6.2.gem -------------------------------------------------------------------------------- /vendor/cache/minitest-5.7.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/minitest-5.7.0.gem -------------------------------------------------------------------------------- /vendor/cache/nokogiri-1.6.6.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/nokogiri-1.6.6.2.gem -------------------------------------------------------------------------------- /vendor/cache/rack-1.6.4.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/rack-1.6.4.gem -------------------------------------------------------------------------------- /vendor/cache/rack-test-0.6.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/rack-test-0.6.3.gem -------------------------------------------------------------------------------- /vendor/cache/rails-4.2.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/rails-4.2.0.gem -------------------------------------------------------------------------------- /vendor/cache/rails-deprecated_sanitizer-1.0.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/rails-deprecated_sanitizer-1.0.3.gem -------------------------------------------------------------------------------- /vendor/cache/rails-dom-testing-1.0.6.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/rails-dom-testing-1.0.6.gem -------------------------------------------------------------------------------- /vendor/cache/rails-html-sanitizer-1.0.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/rails-html-sanitizer-1.0.2.gem -------------------------------------------------------------------------------- /vendor/cache/railties-4.2.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/railties-4.2.0.gem -------------------------------------------------------------------------------- /vendor/cache/rake-10.4.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/rake-10.4.2.gem -------------------------------------------------------------------------------- /vendor/cache/sass-3.4.15.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/sass-3.4.15.gem -------------------------------------------------------------------------------- /vendor/cache/sass-rails-5.0.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/sass-rails-5.0.3.gem -------------------------------------------------------------------------------- /vendor/cache/spring-1.3.6.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/spring-1.3.6.gem -------------------------------------------------------------------------------- /vendor/cache/sprockets-3.2.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/sprockets-3.2.0.gem -------------------------------------------------------------------------------- /vendor/cache/sprockets-rails-2.3.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/sprockets-rails-2.3.2.gem -------------------------------------------------------------------------------- /vendor/cache/sprockets-redirect-0.3.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/sprockets-redirect-0.3.0.gem -------------------------------------------------------------------------------- /vendor/cache/thor-0.19.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/thor-0.19.1.gem -------------------------------------------------------------------------------- /vendor/cache/thread_safe-0.3.5.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/thread_safe-0.3.5.gem -------------------------------------------------------------------------------- /vendor/cache/tilt-1.4.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/tilt-1.4.1.gem -------------------------------------------------------------------------------- /vendor/cache/tzinfo-1.2.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/tzinfo-1.2.2.gem -------------------------------------------------------------------------------- /vendor/cache/uglifier-2.7.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/uglifier-2.7.1.gem -------------------------------------------------------------------------------- /vendor/cache/web-console-2.1.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhuga/slacks-hacks/26331e10b102ada6f2a8c948503ef7b9f39d2f6a/vendor/cache/web-console-2.1.3.gem --------------------------------------------------------------------------------