Polish language translations bug fixes.

Polish language translations bug fixes.

--- app/locale/pl.coffee
+++ app/locale/pl.coffee
@@ -97,7 +97,7 @@
   diplomat_suggestion:
     title: "Pomóż w tłumaczeniu CodeCombat!"
     sub_heading: "Potrzebujemy twoich zdolności językowych."
-    pitch_body: "Tworzymy CodeCombat w języku angielskim, jednak nasi gracze pochodzą z całego świata. Wielu z nich chciałoby zagrać zagrać w swoim języku, ponieważ nie znają angielskiego, więc jeśli znasz oba języki zostań Dyplomatą i pomóż w tłumaczeniu strony CodeCombat, jak i samej gry."
+    pitch_body: "Tworzymy CodeCombat w języku angielskim, jednak nasi gracze pochodzą z całego świata. Wielu z nich chciałoby zagrać w swoim języku, ponieważ nie znają angielskiego, więc jeśli znasz oba języki zostań Dyplomatą i pomóż w tłumaczeniu strony CodeCombat, jak i samej gry."
     missing_translations: "Dopóki nie przetłumaczymy wszystkiego na polski, będziesz widział niektóre napisy w języku angielskim."
     learn_more: "Dowiedz się więcej o Dyplomatach"
     subscribe_as_diplomat: "Dołącz do Dyplomatów"
@@ -191,7 +191,7 @@
     multiplayer_title: "Ustawienia multiplayer"
     multiplayer_link_description: "Przekaż ten link, jeśli chcesz, by ktoś do ciebie dołączył."
     multiplayer_hint_label: "Podpowiedź:"
-    multiplayer_hint: "Klikjnij link by zaznaczyć wszystko, potem wciśnij Cmd-C lub Ctrl-C by skopiować ten link."
+    multiplayer_hint: "Kliknij link by zaznaczyć wszystko, potem wciśnij Cmd-C lub Ctrl-C by skopiować ten link."
     multiplayer_coming_soon: "Wkrótce więcej opcji multiplayer"
     guide_title: "Przewodnik"
     tome_minion_spells: "Czary twojego podopiecznego"
@@ -233,12 +233,12 @@
     main_title: "Edytory CodeCombat"
     main_description: "Stwórz własne poziomy, kampanie, jednostki i materiały edukacyjne. Zapewniamy wszystkie narzędzia, jakich będziesz potrzebował!"
     article_title: "Edytor artykułów"
-    article_description: "Pisz artykuły, które dostarczą graczom wiedzy co do konceptów programistycznych, które będą mogli użyć w poziomach i kampaniach."
+    article_description: "Pisz artykuły, które dostarczą graczom wiedzy co do konceptów programistycznych, których będą mogli użyć w poziomach i kampaniach."
     thang_title: "Edytor obiektów"
     thang_description: "Twórz jednostki, definiuj ich domyślną logikę, grafiki i dźwięki. Aktualnie wspiera wyłącznie importowanie grafik wektorowych wyeksportowanych przez Flash."
     level_title: "Edytor poziomów"
     level_description: "Zawiera narzędzia do skryptowania, przesyłania dźwięków i konstruowania spersonalizowanych logik, by móc tworzyć najrozmaitsze poziomy. Wszystko to, czego sami używamy!"
-    security_notice: "Wiele ważnych fukncji nie jest obecnie domyślnie włączonych we wspomnianych edytorach. Wraz z ulepszeniem zabezpieczenia tych narzędzi, staną się one dostępne publicznie. Jeśli chciałbyś użyć ich już teraz, "
+    security_notice: "Wiele ważnych funkcji nie jest obecnie domyślnie włączonych we wspomnianych edytorach. Wraz z ulepszeniem zabezpieczenia tych narzędzi, staną się one dostępne publicznie. Jeśli chciałbyś użyć ich już teraz, "
     contact_us: "skontaktuj się z nami!"
     hipchat_prefix: "Możesz nas też spotkać w naszym"
     hipchat_url: "pokoju HipChat."
@@ -252,7 +252,7 @@
     level_tab_systems: "Systemy"
     level_tab_thangs_title: "Aktualne obiekty"
     level_tab_thangs_conditions: "Warunki początkowe"
-    level_tab_thangs_add: "Dodoaj obiekty"
+    level_tab_thangs_add: "Dodaj obiekty"
     level_settings_title: "Ustawienia"
     level_component_tab_title: "Aktualne komponenty"
     level_component_btn_new: "Stwórz nowy komponent"
@@ -311,9 +311,9 @@
     who_is_codecombat: "Czym jest CodeCombat?"
     why_codecombat: "Dlaczego CodeCombat?"
     who_description_prefix: "założyli CodeCombat w 2013 roku. Stworzyliśmy również "
-    who_description_suffix: "w roku 2008, doprowadzajac go do pierwszego miejsca wśród aplikacji do nauki zapisu chińskich i japońskich znaków zarówno wśród aplikacji internetowych, jak i aplikcji dla iOS."
+    who_description_suffix: "w roku 2008, doprowadzajac go do pierwszego miejsca wśród aplikacji do nauki zapisu chińskich i japońskich znaków zarówno wśród aplikacji internetowych, jak i aplikacji dla iOS."
     who_description_ending: "Teraz nadszedł czas, by nauczyć ludzi programowania."
-    why_paragraph_1: "Podczas tworzenia Skrittera, George nie umiał programować i ciągle towarzyszyła mu frustracja - nie mógł zaimplementować swoich pomysłów. Próbował się uczyć, lecz lekcje były zbyt wolne. Jego współlokator, chcąc się przebranżowić, spróbował Codeacademy, lecz \"nudziło go to.\" Każdego tygodnia któryś z kolegów podchodził do Codeacadem, by wkrótce potem zrezygnować. Zdaliśmy sobie sprawę, że mamy do czynienia z tym samym problemem, który rozwiązaliśmy Skritterem: ludzie uczący się umiejętności poprzez powolne, ciężkie lekcje, podczas gdy potrzebują oni szybkiej, energicznej praktyki. Wiemy, jak to naprawić."
+    why_paragraph_1: "Podczas tworzenia Skrittera, George nie umiał programować i ciągle towarzyszyła mu frustracja - nie mógł zaimplementować swoich pomysłów. Próbował się uczyć, lecz lekcje były zbyt wolne. Jego współlokator, chcąc się przebranżowić, spróbował Codeacademy, lecz \"nudziło go to.\" Każdego tygodnia któryś z kolegów podchodził do Codeacademy, by wkrótce potem zrezygnować. Zdaliśmy sobie sprawę, że mamy do czynienia z tym samym problemem, który rozwiązaliśmy Skritterem: ludzie uczący się umiejętności poprzez powolne, ciężkie lekcje, podczas gdy potrzebują oni szybkiej, energicznej praktyki. Wiemy, jak to naprawić."
     why_paragraph_2: "Chcesz nauczyć się programowania? Nie potrzeba ci lekcji. Potrzeba ci pisania dużej ilości kodu w sposób sprawiający ci przyjemność."
     why_paragraph_3_prefix: "O to chodzi w programowaniu - musi sprawiać radość. Nie radość w stylu"
     why_paragraph_3_italic: "hura, nowa odznaka"
@@ -325,9 +325,9 @@
     why_ending_url: "Zostań czarodziejem już teraz!"
     george_description: "CEO, człowiek od biznesu, web designer, game designer, i mistrz wszystkich początkujących programistów."
     scott_description: "Programista niezwykły, software architect, czarodziej kuchenny i mistrz finansów. Scott to ten rozsądny."
-    nick_description: "Programistyczny czarownik, ekscentryczny magik i eksperymentator pełną gębą. Nich może robić cokolwiek, a decyduje się pracować przy CodeCombat."
+    nick_description: "Programistyczny czarownik, ekscentryczny magik i eksperymentator pełną gębą. Nick może robić cokolwiek, a decyduje się pracować przy CodeCombat."
     jeremy_description: "Magik od kontaktów z klientami, tester użyteczności i organizator społeczności; prawdopodobnie już rozmawiałeś z Jeremym."
-    michael_description: "Programista, sys-admin, cudowne dziecko studiów technicznych, Michael to osoba utrzymująca nase serwery online."
+    michael_description: "Programista, sys-admin, cudowne dziecko studiów technicznych, Michael to osoba utrzymująca nasze serwery online."

   legal:
     page_title: "Nota prawna"
@@ -348,7 +348,7 @@
     email_settings_url: "twoje ustawienia e-mail"
     email_description_suffix: "lub poprzez linki w e-mailach, które wysyłamy, możesz zmienić swoje ustawienia i w prosty sposób wypisać się z subskrypcji w dowolnym momencie."
     cost_title: "Koszty"
-    cost_description: "W tym momencie CodeCombat jest w stu procentach darmowe! Jednym z naszych głównych celów jest, by utrzymac taki stan rzeczy, aby jak najwięcej ludzi miało dostęp do gry, bez względu na ich zasobnośc. Jeśli nadejdą gorsze dni, dopuszczamy możliwość wprowadzenia płatnych subskrypcji lub pobierania opłat za część zawartości, ale wolelibyśmy, by tak się nie stało. Przy odrobinie szczęścia, uda nam się podtrzymać obecną sytuację dzięki:"
+    cost_description: "W tym momencie CodeCombat jest w stu procentach darmowe! Jednym z naszych głównych celów jest, by utrzymać taki stan rzeczy, aby jak najwięcej ludzi miało dostęp do gry, bez względu na ich zasobność. Jeśli nadejdą gorsze dni, dopuszczamy możliwość wprowadzenia płatnych subskrypcji lub pobierania opłat za część zawartości, ale wolelibyśmy, by tak się nie stało. Przy odrobinie szczęścia, uda nam się podtrzymać obecną sytuację dzięki:"
     recruitment_title: "Rekrutacji"
     recruitment_description_prefix: "Dzięki CodeCombat, staniesz się potężnym czarodziejem - nie tylko w grze, ale również w prawdziwym życiu."
     url_hire_programmers: "Firmy nie nadążają z zatrudnianiem programistów"
@@ -385,7 +385,7 @@
     rights_description: "Opisy"
     rights_writings: "Teksty"
     rights_media: "Multimedia (dźwięki, muzyka) i jakiekolwiek inne typy prac i zasobów stworzonych specjalnie dla danego poziomu, które nie zostały publicznie udostępnione do tworzenia poziomów."
-    rights_clarification: "Gwoli wyjaśnienia, wszystko, co jest dostępne w Edytorze Poziomów w celu tworzenia nowych poziomów podlega licencji CC, podczas gdy zasoby stworzone w Edytorze Poziomów lub przesłane w toku tworzenia poziomu - nie."
+    rights_clarification: "Gwoli wyjaśnienia, wszystko, co jest dostępne w Edytorze Poziomów w celu tworzenia nowych poziomów, podlega licencji CC, podczas gdy zasoby stworzone w Edytorze Poziomów lub przesłane w toku tworzenia poziomu - nie."
     nutshell_title: "W skrócie"
     nutshell_description: "Wszelkie zasoby, które dostarczamy w Edytorze Poziomów są darmowe w użyciu w jakikolwiek sposób w celu tworzenia poziomów. Jednocześnie, zastrzegamy sobie prawo do ograniczenia rozpowszechniania poziomów (stworzonych przez codecombat.com) jako takich, aby mogła być za nie w przyszłości pobierana opłata, jeśli dojdzie do takiej konieczności."
     canonical: "Angielska wersja tego dokumentu jest ostateczna, kanoniczną wersją. Jeśli zachodzą jakieś rozbieżności pomiędzy tłumaczeniami, dokument anglojęzyczny ma pierwszeństwo."


Update sr.coffee

Update sr.coffee

I have removed hashtags and signed CLA.  Hope that everything will work fine now. Sory for mistakes this Github is a little confusing at beginning.
Greetings

--- app/locale/sr.coffee
+++ app/locale/sr.coffee
@@ -9,22 +9,22 @@
 #    old_browser_suffix: "You can try anyway, but it probably won't work."
 #    ipad_browser: "Bad news: CodeCombat doesn't run on iPad in the browser. Good news: our native iPad app is awaiting Apple approval."
 #    campaign: "Campaign"
-#    for_beginners: "За почетнике"
-#    multiplayer: "Мултиплејер" # Not currently shown on home page
-#    for_developers: "За Девелопере" # Not currently shown on home page.
-#    or_ipad: "Или скини за iPad"
+    for_beginners: "За почетнике"
+    multiplayer: "Мултиплејер" # Not currently shown on home page
+    for_developers: "За Девелопере" # Not currently shown on home page.
+    or_ipad: "Или скини за iPad"

   nav:
     play: "Нивои" # The top nav bar entry where players choose which levels to play
-#    community: "Заједница"
-#    courses: "Курсеви"
+    community: "Заједница"
+    courses: "Курсеви"
     editor: "Уређивач"
     blog: "Блог"
     forum: "Форум"
-#    account: "Налог"
-#    profile: "Профил"
-#    stats: "Stats"
-#    code: "Код"
+    account: "Налог"
+    profile: "Профил"
+    stats: "Статистика"
+    code: "Код"
     admin: "Админ" # Only shows up when you are an admin
     home: "Почетна"
     contribute: "Допринеси"
@@ -32,8 +32,8 @@
     about: "О нама"
     contact: "Контакт"
     twitter_follow: "Прати"
-#    teachers: "Учитељи"
-#    careers: "Каријере"
+    teachers: "Учитељи"
+    careers: "Каријере"

   modal:
     close: "Затвори"
@@ -51,29 +51,29 @@
     subscribe_as_diplomat: "Претплати се као Дипломата"

   play:
-#    play_as: "Играј као" # Ladder page
-#    compete: "Такмичи се!" # Course details page
-#    spectate: "Посматрај" # Ladder page
-#    players: "играчи" # Hover over a level on /play
-#    hours_played: "потребно сати играња" # Hover over a level on /play
-#    items: "Ствари" # Tooltip on item shop button from /play
-#    unlock: "Откључај" # For purchasing items and heroes
-#    confirm: "Потврди"
-#    owned: "У поседу" # For items you own
-#    locked: "Закључани"
-#    purchasable: "Могуће купити" # For a hero you unlocked but haven't purchased
-#    available: "Доступни"
-#    skills_granted: "Обезбеђени скилови" # Property documentation details
-#    heroes: "Хероји" # Tooltip on hero shop button from /play
-#    achievements: "Достигнућа" # Tooltip on achievement list button from /play
-#    account: "Налог" # Tooltip on account button from /play
-#    settings: "Подешавања" # Tooltip on settings button from /play
-#    poll: "Покрени" # Tooltip on poll button from /play
-#    next: "Следећи" # Go from choose hero to choose inventory before playing a level
-#    change_hero: "Промени Хероја" # Go back from choose inventory to choose hero
-#    buy_gems: "Купи драгуље"
-#    subscription_required: "Потребна пријава"
-#    anonymous: "Анонимни играч"
+    play_as: "Играј као" # Ladder page
+    compete: "Такмичи се!" # Course details page
+    spectate: "Посматрај" # Ladder page
+   players: "играчи" # Hover over a level on /play
+    hours_played: "потребно сати играња" # Hover over a level on /play
+    items: "Ствари" # Tooltip on item shop button from /play
+    unlock: "Откључај" # For purchasing items and heroes
+    confirm: "Потврди"
+    owned: "У поседу" # For items you own
+    locked: "Закључани"
+    purchasable: "Могуће купити" # For a hero you unlocked but haven't purchased
+    available: "Доступни"
+    skills_granted: "Обезбеђени скилови" # Property documentation details
+   heroes: "Хероји" # Tooltip on hero shop button from /play
+    achievements: "Достигнућа" # Tooltip on achievement list button from /play
+    account: "Налог" # Tooltip on account button from /play
+    settings: "Подешавања" # Tooltip on settings button from /play
+    poll: "Покрени" # Tooltip on poll button from /play
+    next: "Следећи" # Go from choose hero to choose inventory before playing a level
+    change_hero: "Промени Хероја" # Go back from choose inventory to choose hero
+    buy_gems: "Купи драгуље"
+    subscription_required: "Потребна пријава"
+    anonymous: "Анонимни играч"
     level_difficulty: "Тежина: "
 #    play_classroom_version: "Play Classroom Version" # Choose a level in campaign version that you also can play in one of your courses
     campaign_beginner: "Почетничка кампања"
@@ -97,39 +97,39 @@
   login:
     sign_up: "Направи Налог"
     log_in: "Улогуј Се"
-#    logging_in: "Логовање"
+    logging_in: "Логовање"
     log_out: "Излогуј Се"
-#    forgot_password: "Да ли си заборавио шифру?"
+    forgot_password: "Да ли си заборавио шифру?"
 #    authenticate_gplus: "Authenticate G+"
 #    load_profile: "Load G+ Profile"
-#    finishing: "Завршавање"
-#    sign_in_with_facebook: "Учлани се преко Фејсбука"
-#    sign_in_with_gplus: "Учлани се преко Гугл +"
-#    signup_switch: "Да ли желиш да направиш налог?"
+    finishing: "Завршавање"
+    sign_in_with_facebook: "Учлани се преко Фејсбука"
+    sign_in_with_gplus: "Учлани се преко Гугл +"
+    signup_switch: "Да ли желиш да направиш налог?"

   signup:
     email_announcements: "Примај обавештења на мејл"
     creating: "Прављење налога..."
     sign_up: "Упиши се"
     log_in: "улогуј се са шифром"
-#    required: "Мораш да се улогујеш пре него што наставиш"
-#    login_switch: "Већ имаш налог?"
-#    school_name: "Име школе и града"
-#    optional: "опционо"
+    required: "Мораш да се улогујеш пре него што наставиш"
+    login_switch: "Већ имаш налог?"
+    school_name: "Име школе и града"
+    optional: "опционо"
 #    school_name_placeholder: "Example High School, Springfield, IL"

   recover:
     recover_account_title: "Поврати налог"
-#    send_password: "Пошаљи помоћну шифру"
-#    recovery_sent: "Послат мејл за потврду опоравка."
+    send_password: "Пошаљи помоћну шифру"
+    recovery_sent: "Послат мејл за потврду опоравка."

 #  items:
-#    primary: "Примарни"
-#    secondary: "Секундарни"
-#    armor: "Оклоп"
-#    accessories: "Опрема"
+    primary: "Примарни"
+    secondary: "Секундарни"
+    armor: "Оклоп"
+    accessories: "Опрема"
 #    misc: "Misc"
-#    books: "Књиге"
+    books: "Књиге"

   common:
 #    back: "Back" # When used as an action verb, like "Navigate backward"
@@ -137,22 +137,22 @@
     loading: "Учитавање"
     saving: "Чување..."
     sending: "Шаље се..."
-#    send: "Пошаљи"
+    send: "Пошаљи"
     cancel: "Откажи"
-#    save: "Сачувај"
-#    publish: "Објави"
-#    create: "Створи"
+    save: "Сачувај"
+    publish: "Објави"
+   create: "Створи"
 #    fork: "Fork"
     play: "Нивои" # When used as an action verb, like "Play next level"
 #    retry: "Retry"
 #    actions: "Actions"
-#    info: "Инфо"
-#    help: "Помоћ"
-#    watch: "Одгледај"
-#    unwatch: "Не гледај"
-#    submit_patch: "Потврди закрпу"
-#    submit_changes: "Потврди измене"
-#    save_changes: "Сачувај измене"
+    info: "Инфо"
+    help: "Помоћ"
+    watch: "Одгледај"
+    unwatch: "Не гледај"
+   submit_patch: "Потврди закрпу"
+    submit_changes: "Потврди измене"
+    save_changes: "Сачувај измене"

   general:
 #    and: "and"
@@ -259,11 +259,11 @@
 #    victory_review_placeholder: "How was the level?"
     victory_hour_of_code_done: "Јеси ли завршио?"
     victory_hour_of_code_done_yes: "Да, завршио сам свој Сат Кода!"
-#    victory_experience_gained: "Добијено искуство"
-#    victory_gems_gained: "Добијени драгуљи"
-#    victory_new_item: "Нови Итем"
+    victory_experience_gained: "Добијено искуство"
+    victory_gems_gained: "Добијени драгуљи"
+    victory_new_item: "Нови Итем"
 #    victory_viking_code_school: "Holy smokes, that was a hard level you just beat! If you aren't already a software developer, you should be. You just got fast-tracked for acceptance with Viking Code School, where you can take your skills to the next level and become a professional web developer in 14 weeks."
-#    victory_become_a_viking: "Постани Викинг"
+    victory_become_a_viking: "Постани Викинг"
     guide_title: "Водич"
 #    tome_cast_button_run: "Run"
 #    tome_cast_button_running: "Running"
@@ -274,7 +274,7 @@
 #    tome_see_all_methods: "See all methods you can edit" # Title text for method list selector (shown when there are multiple programmable methods).
     tome_select_a_thang: "Изабери неког за "
     tome_available_spells: "Доступне чини"
-#    tome_your_skills: "Твоје вештине"
+    tome_your_skills: "Твоје вештине"
 #    tome_current_method: "Current Method"
 #    code_saved: "Code Saved"
 #    skip_tutorial: "Skip (esc)"
@@ -375,16 +375,16 @@
 #    gold_collected: "Gold Collected"

 #  inventory:
-#    equipped_item: "Опремљен"
-#    required_purchase_title: "Потребно"
-#    available_item: "Доступно"
-#    restricted_title: "Забрањено"
-#    should_equip: "(Дупли-клик за опремање)"
-#    equipped: "(опремљен/а)"
+    equipped_item: "Опремљен"
+    required_purchase_title: "Потребно"
+    available_item: "Доступно"
+    restricted_title: "Забрањено"
+    should_equip: "(Дупли-клик за опремање)"
+   equipped: "(опремљен/а)"
 #    locked: "(locked)"
 #    restricted: "(restricted in this level)"
-#    equip: "Опреми"
-#    unequip: "Скини"
+    equip: "Опреми"
+    unequip: "Скини"

 #  buy_gems:
 #    few_gems: "A few gems"


Enabled some translations

Enabled some translations

--- app/locale/vi.coffee
+++ app/locale/vi.coffee
@@ -480,7 +480,7 @@
 #    returns: "Returns"
 #    granted_by: "Granted by"

-#  save_load:
+  save_load:
     granularity_saved_games: "Đã lưu"
     granularity_change_history: "Lịch sử"

@@ -509,7 +509,7 @@
 #    editor_config_behaviors_label: "Smart Behaviors"
 #    editor_config_behaviors_description: "Autocompletes brackets, braces, and quotes."

-#  about:
+  about:
 #    why_codecombat: "Why CodeCombat?"
 #    why_paragraph_1: "If you want to learn to program, you don't need lessons. You need to write a lot of code and have a great time doing it."
 #    why_paragraph_2_prefix: "That's what programming is about. It's gotta be fun. Not fun like"
@@ -659,7 +659,7 @@
 #    beautify: "Beautify your code by standardizing its formatting."
 #    maximize_editor: "Maximize/minimize code editor."

-#  community:
+  community:
     main_title: "Cộng đồng CodeCombat"
 #    introduction: "Check out the ways you can get involved below and decide what sounds the most fun. We look forward to working with you!"
 #    level_editor_prefix: "Use the CodeCombat"


Fix repository hint on accounts pages.

Fix repository hint on accounts pages.

Accounts and the profile are currently separate controllers, so
whenever you switched the account, the message would be hidden.

--- assets/scripts/app/controllers/account_index.coffee
+++ assets/scripts/app/controllers/account_index.coffee
@@ -10,3 +10,11 @@

   toggle: (hook) ->
     hook.toggle()
+
+  showPrivateReposHint: (->
+    Travis.config.show_repos_hint == 'private'
+  ) .property()
+
+  showPublicReposHint: (->
+    Travis.config.show_repos_hint == 'public'
+  ) .property()


use a real profile

use a real profile

--- apps/fair_organizer/client/index.coffee
+++ apps/fair_organizer/client/index.coffee
@@ -3,6 +3,7 @@
 moment = require 'moment'
 sd = require('sharify').data
 Fair = require '../../../models/fair.coffee'
+Profile = require '../../../models/profile.coffee'
 FairOrganizer = require '../../../models/fair_organizer.coffee'
 Articles = require '../../../collections/articles.coffee'
 Clock = require '../../../components/clock/view.coffee'
@@ -59,8 +60,7 @@
     el: $('body')

   following = new Following null, kind: 'profile' if sd.CURRENT_USER
-  profile = new Backbone.Model id: fairOrg.get('profile_id')
-  profile.href = => "/#{fairOrg.get('profile_id')}"
+  profile = new Profile id: fairOrg.get('profile_id')

   new FollowButton
     el: $('#fair-organizer-follow')


Ignore sections that are not visible, fix #2712

We need to ignore:

- Sections with `xforms-disabled`, which at least happens when we have a non-relevant nested section in a repeated section, because of #2031. Note that this section is `:visible`, but hidden from users by being rendered offscreen.
- Sections that are not `:visible`, which is the case for a section in the repeat template. In that case, the section really isn't `:visible` as inside an element with `.xforms-repeat-template`, which is `display: none`.

--- src/resources/forms/orbeon/builder/resources/section-grid-repeat/section-editor.coffee
+++ src/resources/forms/orbeon/builder/resources/section-grid-repeat/section-editor.coffee
@@ -144,7 +144,7 @@
         do ->
             labelClickInterceptors = []
             Builder.onOffsetMayHaveChanged ->
-                sections = $('.xbl-fr-section')
+                sections = $('.xbl-fr-section:visible:not(.xforms-disabled)')
                 # Create interceptor divs, so we have enough to cover all the sections
                 _.each _.range(sections.length - labelClickInterceptors.length), ->
                     container = $ '<div class="fb-section-label-editor-click-interceptor">'


fix syntax for country list

fix syntax for country list

--- assets/coffeescript/country_list.coffee
+++ assets/coffeescript/country_list.coffee
@@ -748,7 +748,7 @@
     countryName: 'Israel'
     locationFormat: 'City'
     usesPostalCode: true
-    postalCodeFormat: '99999','9999999',
+    postalCodeFormat: '99999, 9999999',
     capitalCity: null
     inEU: false
   India:


add note on w3d compatibility with pupil mobile

--- assets/coffeescript/product_list.coffee
+++ assets/coffeescript/product_list.coffee
@@ -38,7 +38,7 @@
     w3d:
       id: 'w3d'
       title_store: '3d'
-      description_store: "Intel RealSense R200 RGBD camera. Provides depth image and monocular RGB color image."
+      description_store: "Intel RealSense R200 RGBD camera. Provides depth image and monocular RGB color image. (Note: This sensor is not compatible with Pupil Mobile)."
       tech_specs:
         sensor: "See Intel R200 data sheet for details"
         fov:"See Intel R200 data sheet for details"
@@ -563,7 +563,7 @@
       cost: 650
       title_product: 'Pupil Mobile Bundle'
       title_store: "Pupil Mobile Bundle"
-      description_store: "Connect your Pupil headset to the Moto Z2 play. Record up to 4 hours of video locally on the phone, or stream video and sensor data over Wifi. The bundle comes with: Moto Z2 Play (black), hot-swappable Moto power pack, 64gb SD card, USBC-USBC cable, and is pre-loaded with the Pupil Mobile app."
+      description_store: "Connect your Pupil headset to the Moto Z2 play. Record up to 4 hours of video locally on the phone, or stream video and sensor data over Wifi. The bundle comes with: Moto Z2 Play (black), hot-swappable Moto power pack, 64gb SD card, USBC-USBC cable, and is pre-loaded with the Pupil Mobile app. (Note: Pupil headsets with 3d world camera are not compatible with Pupil Mobile)."
       description_cart: "Moto Z2 Play (black), hot-swappable Moto power pack, 64gb SD card, USBC-USBC cable, and is pre-loaded with the Pupil Mobile app. Connects to Pupil headset via USBC cable (included)."
       img: [additional_product_path,'pm_nexus5x.jpg'].join('/')
     support6:


Make help query regular expression case insensitive.

--- src/scripts/help.coffee
+++ src/scripts/help.coffee
@@ -9,7 +9,7 @@
   robot.respond /help\s*(.*)?$/i, (msg) ->
     cmds = robot.helpCommands()
     if msg.match[1]
-      cmds = cmds.filter (cmd) -> cmd.match(new RegExp(msg.match[1]))
+      cmds = cmds.filter (cmd) -> cmd.match(new RegExp(msg.match[1], 'i'))
     emit = cmds.join("\n")
     unless robot.name is 'Hubot'
       emit = emit.replace(/(H|h)ubot/g, robot.name)


Replace _.clone with jquery's deep extend

--- src/scripts/main.coffee
+++ src/scripts/main.coffee
@@ -62,7 +62,11 @@
         cb()

   duplicate: ->
-    attrs = _.clone(@model.attributes)
+    # attrs = _.clone(@model.attributes)
+    # underscore's clone won't do deep cloning, resulting in duplicated controls
+    # having same value on save.
+    # So, we use jquery's extend method
+    attrs = $.extend(true, {}, @model.attributes);
     delete attrs['id']
     attrs['label'] += ' Copy'
     @parentView.createField attrs, { position: @model.indexInDOM() + 1 }


Ignore removelistener on doc not loaded

Ignore removelistener on doc not loaded

Fixes #117

--- src/server/model.coffee
+++ src/server/model.coffee
@@ -575,8 +575,9 @@
   # This is synchronous.
   @removeListener = (docName, listener) ->
     # The document should already be loaded.
-    doc = docs[docName]
-    throw new Error 'removeListener called but document not loaded' unless doc
+    # If it's not we probably hit a race condition where the browser closes
+    # before the document opened. In that case, ignore.
+    return unless doc = docs[docName]

     doc.eventEmitter.removeListener 'op', listener
     refreshReapingTimeout docName


Possible fix for images with direct mask in Sketch

--- framer/Importer.coffee
+++ framer/Importer.coffee
@@ -76,6 +76,13 @@
 		if info.maskFrame
 			layerInfo.frame = info.maskFrame
 			layerInfo.clip = true
+
+		# Possible fix for images that have a mask in Sketch
+		# So if a layer without children has a mask, Sketch imports the full image
+		# That is whay we then take the image frame over the mask frame again
+		if superLayer?.clip and info.children.length is 0
+			layerInfo.frame = info.image.frame
+			layerInfo.clip = false

 		# Figure out what the super layer should be. If this layer has a contentLayer
 		# (like a scroll view) we attach it to that instead.


Setting the name of layers to their id

Setting the name of layers to their id

--- framer/SVGLayer.coffee
+++ framer/SVGLayer.coffee
@@ -30,6 +30,7 @@
 			disableBorder: true
 		if elements?
 			for element in elements
+				options.name = element.id
 				if element instanceof SVGGElement
 					@elements[element.id] = new SVGGroup(element, options)
 					continue


Bypass Angular.js exception mangling.

Bypass Angular.js exception mangling.

--- app/app.coffee
+++ app/app.coffee
@@ -41,6 +41,12 @@
   (require './modules/sr').name
   (require './modules/vm').name
 ]
+
+  # Prevent Angular.js from mangling exception stack (interfere with
+  # source maps).
+  .factory '$exceptionHandler', ->
+    return (exception) -> throw exception
+
   .config ($urlRouterProvider, $tooltipProvider) ->
     # Redirects unmatched URLs to `/`.
     $urlRouterProvider.otherwise '/'
@@ -49,6 +55,7 @@
     $tooltipProvider.options
       appendToBody: true
       placement: 'bottom'
+
   .run ($rootScope, $state, xoApi, editableOptions, editableThemes, notify, $templateCache) ->
     $rootScope.$on '$stateChangeStart', (event, state, stateParams) ->
       {user} = xoApi


TAP5-2125: Ajax form submissions via jQuery may pass t:formdata as "t:formdata[]" if there are multiple values

--- tapestry-core/src/main/coffeescript/org/apache/tapestry5/t5-core-dom-jquery.coffee
+++ tapestry-core/src/main/coffeescript/org/apache/tapestry5/t5-core-dom-jquery.coffee
@@ -402,6 +402,7 @@
       url: url
       type: options.method?.toUpperCase() or "POST"
       contentType: options.contentType
+      traditional: true
       data: options.parameters
       # jQuery doesn't have the equivalent of Protoype's onException
       error: (jqXHR, textStatus, errorThrown) ->


Fix #2, part 2: Don't show tags-input every time new props are received

--- app/assets/javascripts/rglossa/components/centre/search_inputs/cwb_multiword_term.jsx.coffee
+++ app/assets/javascripts/rglossa/components/centre/search_inputs/cwb_multiword_term.jsx.coffee
@@ -44,6 +44,8 @@
     # search expression in the CQP query view, in which case the multiword view
     # will be mounted anew when we switch to it and the tags will be set up
     # by componentDidMount.
+    if not nextProps.term.pos and not nextProps.term.features.length
+      return
     tagsInput = @getTagsInput()

     if nextProps.term.pos isnt @props.term.pos


<model> Driver - Properly removingdrivers modules from cache before destruction.

--- server/models/driver.coffee
+++ server/models/driver.coffee
@@ -67,7 +67,12 @@
 				async.parallel [
 					(cb) -> superDestroy ((err) -> cb 'Error removing driver from DB', null)
 					,
-					(cb) -> rimraf (DRIVERS_DIR + thisDriver.name), ((err) -> cb 'Error removing driver\'s files', null)
+					(cb) ->
+						modulePath = DRIVERS_DIR + thisDriver.name
+						# Removing module from cache:
+						delete require.cache[require.resolve(modulePath)]
+						# Deleting module directory:
+						rimraf (modulePath), ((err) -> cb 'Error removing driver\'s files', null)
 					,
 					(cb) ->
 						err = null
@@ -205,8 +210,9 @@
 			# Clearing the previous drivers arrays (without changing the ref!)
 			for k,v in sensorsDrivers
 				delete sensorsDrivers[k] if sensorsDrivers.hasOwnProperty(k)
+
 			for k,v in actuatorsDrivers
-				delete actuatorsDrivers[k] if actuatorsDrivers.hasOwnProperty(k)
+				delete actuat

 			# Refilling them:
 			for driver in drivers


3525 small fix. both r/l side out of bound should be good

--- app/assets/volume/slot.coffee
+++ app/assets/volume/slot.coffee
@@ -937,7 +937,7 @@
         return

     $scope.positionBackgroundStyle = (l, i) ->
-      if l[i].lt.p > 1
+      if l[i].lt.p > 1 || l[i].ut.p < 0
         visibility: "hidden"
       else
         new TimeSegment(l[i].l, if i+1 of l then l[i+1].l else Infinity).style()


slot updateRange: allow both ends to push out in both directions

Fixes #3585

--- app/assets/volume/slot.coffee
+++ app/assets/volume/slot.coffee
@@ -233,8 +233,12 @@
       u = -Infinity
       for c in [$scope.assets, records, $scope.consents]
         for t in c
-          l = t.l if isFinite(t.l) && t.l < l
-          u = t.u if isFinite(t.u) && t.u > u
+          if isFinite(t.l)
+            l = t.l if t.l < l
+            u = t.l if t.l > u
+          if isFinite(t.u)
+            l = t.u if t.u < l
+            u = t.u if t.u > u
       fullRange.l = finite(slot.segment.l, l, 0)
       fullRange.u = finite(slot.segment.u, u, 0)
       resetRange()


log for each get/try/release lock

log for each get/try/release lock

--- app/coffee/LockManager.coffee
+++ app/coffee/LockManager.coffee
@@ -30,14 +30,16 @@
 	tryLock : (doc_id, callback = (err, isFree)->)->
 		lockValue = LockManager.randomLock()
 		key = keys.blockingKey(doc_id:doc_id)
+		logger.log {doc_id: doc_id, key: key}, "tryLock"
 		rclient.set key, lockValue, "EX", @LOCK_TTL, "NX", (err, gotLock)->
 			return callback(err) if err?
 			if gotLock == "OK"
 				metrics.inc "doc-not-blocking"
+				logger.log {doc_id: doc_id, key: key, lockValue: lockValue}, "got lock"
 				callback err, true, lockValue
 			else
 				metrics.inc "doc-blocking"
-				logger.log {doc_id}, "doc is locked"
+				logger.log {doc_id: doc_id, key: key}, "doc is locked"
 				callback err, false

 	getLock: (doc_id, callback = (error, lockValue) ->) ->
@@ -54,6 +56,7 @@
 				if gotLock
 					callback(null, lockValue)
 				else
+					logger.log {doc_id: doc_id, delay: testInterval}, "will retry lock"
 					setTimeout attempt, testInterval
 					# back off when the lock is taken to avoid overloading
 					testInterval = Math.min(testInterval * 2, LockManager.MAX_TEST_INTERVAL)
@@ -75,7 +78,9 @@
 		rclient.eval LockManager.unlockScript, 1, key, lockValue, (err, result) ->
 			if err?
 				return callback(err)
-			if result? and result isnt 1 # successful unlock should release exactly one key
-				logger.error {doc_id:doc_id, lockValue:lockValue, redis_err:err, redis_result:result}, "unlocking error"
+			else if result? and result isnt 1 # successful unlock should release exactly one key
+				logger.error {doc_id:doc_id, key:key, lockValue:lockValue, redis_err:err, redis_result:result}, "unlocking error"
 				return callback(new Error("tried to release timed out lock"))
-			callback(err,result)
+			else
+				logger.log {doc_id:doc_id, key:key, lockValue:lockValue}, "released lock"
+				callback(err,result)


animation hack timeout

animation hack timeout

--- app/coffee/modules/nav.coffee
+++ app/coffee/modules/nav.coffee
@@ -75,7 +75,7 @@
             #animation hack
             setTimeout ( ->
                 $(document.body).toggleClass("open-projects-nav")
-            ), 0
+            ), 61

         $el.on "click", ".projects-list > li > a", (event) ->
             $(document.body)


Get collection detail subjects.

Get collection detail subjects.

--- app/javascripts/routes.coffee
+++ app/javascripts/routes.coffee
@@ -92,6 +92,17 @@
             url: ''
             resolve:
               Subject: 'Subject'
+              subjects: (Subject, project) ->
+                # The selection criterion is the project name.
+                cond = REST.where(project: project)
+                # The id is always fetched. In addition, the
+                # project/collection/number secondary key is fetched.
+                # No other fields are fetched.
+                fields = REST.map(['project', 'collection', 'number'])
+                # The HTML query parameter.
+                param = _.extend(_.clone(cond), fields)
+                # Delegate to the resource.
+                Subject.query(param).$promise
               collection: ($stateParams) ->
                 _s.capitalize($stateParams.collection)
               charting: (Subject, project, collection) ->


Account Settings: Credentials: Use already defined variable.

--- client/account/lib/accountcredentiallistitem.coffee
+++ client/account/lib/accountcredentiallistitem.coffee
@@ -13,13 +13,13 @@

     super options, data

+    delegate            = @getDelegate()
     { providers }       = globals.config
-    delegate            = @getDelegate()
     { owner, provider } = @getData()

     @providerTag = new KDCustomHTMLView
       cssClass : 'tag'
-      partial  : @getData().provider
+      partial  : provider

     @providerTag.setCss 'background-color', providers[provider].color


re-add original test

re-add original test

--- modules/plot/test/spec.coffee
+++ modules/plot/test/spec.coffee
@@ -255,6 +255,16 @@

     describe "render", ->
       it 'should display when the height is positive', ->
+        selection = hx.detached('div').style('height', '400px')
+        hx.select('body').add(selection)
+        graph = new hx.Graph(selection.node())
+        axis = graph.addAxis('linear', 'linear')
+        a1 = axis.addSeries()
+        graph.render()
+        selection.selectAll('.hx-series').size().should.equal(2)
+        selection.remove()
+
+      it 'should display when the height is positive using fluent api', ->
         graphOpts =
           axes: [
             series: [['line']]


Style account link

Style account link

--- app/panoptes/account-bar.cjsx
+++ app/panoptes/account-bar.cjsx
@@ -21,7 +21,7 @@

-        Account
+        Account
         <button className="secret-button sign-out-button" type="button" onClick={@handleSignOutClick}>Sign out</button>


Add note

Add note

--- grammars/emphasis.cson
+++ grammars/emphasis.cson
@@ -1,3 +1,5 @@
+# NOTE
+# Copy-and-paste from language-gfm package. Needs some work I think.
 'name': 'Markdown emphasis (inline)'
 'scopeName': 'emphasis.source.md'
 'fileTypes': []


shortcuts: rename line motion key combinations

--- client/ide/views/shortcutsview/shortcutsview.coffee
+++ client/ide/views/shortcutsview/shortcutsview.coffee
@@ -73,8 +73,8 @@
       'Preview file'           : 'Ctrl-Alt-P'
       'Go to top'              : { Others: 'Ctrl-Home',      Apple: 'Meta-Up'   }
       'Go to bottom'           : { Others: 'Ctrl-End',       Apple: 'Meta-Down' }
-      'Go line up'             : 'Ctrl-N'
-      'Go line down'           : 'Ctrl-P'
+      'Go to next line'        : 'Ctrl-N'
+      'Go to previous line'    : 'Ctrl-P'
       'Go to left'             : 'Ctrl-B'
       'Go to right'            : 'Ctrl-F'
       'Go to end'              : { Others: 'Ctrl-End',       Apple: 'Meta-Down' }


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/timed_events.coffee
+++ src/timed_events.coffee
@@ -24,7 +24,7 @@
   @name every
   @methodOf TimedEvents#
   @param {Number} n The number of frames to wait before executing the callback
-  @param {Function} fn The
+  @param {Function} fn The code to exec
   ###
   every: (n, fn) ->
     if I.age.mod(n) is 0


actually sort things

actually sort things

--- js/inner/project.coffee
+++ js/inner/project.coffee
@@ -141,7 +141,7 @@
       if @branches()[branch_name]
         recent = @branches()[branch_name].recent_builds or []
         running = @branches()[branch_name].running_builds or []
-        recent.concat(running).sort(@buildSort)
+        recent.concat(running).sort(Project.buildSort)
       else
         []

@@ -214,16 +214,16 @@

   @buildNumSort: (l, r) ->
     if l.build_num > r.build_num
+      1
+    else if l.build_num < r.build_num
       -1
-    else if l.build_num < r.build_num
-      1
     else
       0

   @buildSort: (l, r) ->
-    time_sort = @buildTimeSort(l, r)
+    time_sort = Project.buildTimeSort(l, r)
     if time_sort is 0
-      @buildNumSort(l, r)
+      Project.buildNumSort(l, r)
     else
       time_sort


.

Former-commit-id: cc9a66b2d61f13e5ac509d92f4efbd2dd5940501 [formerly e0f56d4f251efc4eb8e0dac67eb602e759275bda] [formerly a6a68f72482710ad7ed224273c8006b42961503f [formerly bdbefdbcb71d25d17b9fcab9370341c20ce499ff]] [formerly cdc6da7276a53b38440025ba0cd830ccf9ca161f [formerly b90f86c0d98d52a9ffc89319c8f960eb3741e22f] [formerly cc25377058f113ed0d183eb2c8e6658b84792c11 [formerly cc25377058f113ed0d183eb2c8e6658b84792c11 [formerly 6709750f7ac937becf99cb4c1e4780ee092828cb]]]]
Former-commit-id: fcc4a5f862acc90060859597d3dc5fab71af6a5c [formerly 04ce7e2af8d875a4b725dc8bed0b7903799dd088] [formerly fb9ea1e5b1bb13323d2467eed5132ea2f17d902d [formerly 37043940b8f6efc6278b3a0828270ca8e8453b2e]]
Former-commit-id: 8b05644853dfa3f2c2d36e5945cfd958c47c299a [formerly ca37383069566a8ec85d1cff215276faa082c528]
Former-commit-id: 0cd818d467037083929e6a0b8f41e93ca052c24a
Former-commit-id: ed7bde79e9cf4b956775d78f8f6e85c0a2635ae3

--- @client/third_party_auth.coffee
+++ @client/third_party_auth.coffee
@@ -19,14 +19,14 @@
     @popup = @openPopupWindow(url)

   pollLoginPopup : ->
-    try
-      if @popup? && @popup.document && window.document && window.document.domain == @popup.document.domain && @popup.current_user_hash?
-        @callback @popup.current_user_hash
-        @popup.close()
-        @popup = null
-        clearInterval(@polling_interval)
-    catch e
-      console.error e
+    # try
+    if @popup? && @popup.document && window.document && window.document.domain == @popup.document.domain && @popup.current_user_hash?
+      @callback @popup.current_user_hash
+      @popup.close()
+      @popup = null
+      clearInterval(@polling_interval)
+    # catch e
+    #   console.error e

   openPopupWindow : (url) ->
     openidpopup = window.open(url, 'openid_popup', 'width=450,height=500,location=1,status=1,resizable=yes')


Autofocuses search

Autofocuses search

--- app/assets/javascripts/launchpad/search.js.coffee
+++ app/assets/javascripts/launchpad/search.js.coffee
@@ -5,6 +5,7 @@
     $('[data-behavior=search]').autocomplete
       delay: 0
       html: true
+      autoFocus: true
       focus: (event, ui) -> false
       select: (event, ui) ->
         document.location = ui.item.link


Add touchmove for scrolling

Add touchmove for scrolling

--- app/assets/javascripts/nembrot.document.js.coffee
+++ app/assets/javascripts/nembrot.document.js.coffee
@@ -134,6 +134,13 @@
   $('footer img.qr_code').remove()
   $('footer').prepend('<img class="qr_code" src="https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=' + location.href + '" alt="QR code">')

+add_scrolling_class = () ->
+  clearTimeout(window.scrolling)
+  $('body').addClass('scrolling')
+  window.scrolling = setTimeout(->
+    $('body').removeClass('scrolling')
+  , 1000)
+
 # Document hooks ******************************************************************************************************

 $ ->
@@ -163,12 +170,11 @@
   $(document).on 'click', '.fb-like', ->
     fix_facebook_dialog()

+  $(document).on 'touchmove', 'body', ->
+    add_scrolling_class()
+
   $(window).scroll ->
-    clearTimeout(window.scrolling)
-    $('body').addClass('scrolling')
-    window.scrolling = setTimeout(->
-      $('body').removeClass('scrolling')
-    , 1000)
+    add_scrolling_class()

   $(window).mousemove ->
     clearTimeout(window.mousemoving)


No line smoothing

No line smoothing

--- app/assets/javascripts/prosperity/graph.js.coffee
+++ app/assets/javascripts/prosperity/graph.js.coffee
@@ -18,6 +18,7 @@
           xkey: "x"
           ykeys: []
           labels: []
+          smooth: false

         chartOptions.postUnits = '%' if json.key == 'change'


Allow hashtags param for Twitter (#110)

Allow hashtags param for Twitter (#110)

--- app/assets/javascripts/social-share-button.coffee
+++ app/assets/javascripts/social-share-button.coffee
@@ -29,9 +29,10 @@
       when "weibo"
         SocialShareButton.openUrl("http://service.weibo.com/share/share.php?url=#{url}&type=3&pic=#{img}&title=#{title}&appkey=#{appkey}", 620, 370)
       when "twitter"
+        hashtags = encodeURIComponent($(el).data(site + '-hashtags') || $parent.data('hashtags') || '')
         via_str = ''
         via_str = "&via=#{via}" if via.length > 0
-        SocialShareButton.openUrl("https://twitter.com/intent/tweet?url=#{url}&text=#{title}#{via_str}", 650, 300)
+        SocialShareButton.openUrl("https://twitter.com/intent/tweet?url=#{url}&text=#{title}&hashtags=#{hashtags}#{via_str}", 650, 300)
       when "douban"
         SocialShareButton.openUrl("http://shuo.douban.com/!service/share?href=#{url}&name=#{title}&image=#{img}&sel=#{desc}", 770, 470)
       when "facebook"


add urls

add urls

--- app/assets/javascripts/social-share-button.coffee
+++ app/assets/javascripts/social-share-button.coffee
@@ -37,6 +37,10 @@
         SocialShareButton.openUrl("http://shuo.douban.com/!service/share?href=#{url}&name=#{title}&image=#{img}&sel=#{desc}", 770, 470)
       when "facebook"
         SocialShareButton.openUrl("http://www.facebook.com/sharer/sharer.php?u=#{url}&display=popup&title=#{title}&description=#{desc}", 555, 400)
+      when "hootsuite"
+        SocialShareButton.openUrl("https://hootsuite.com/hootlet/social-share?partner=Netvibes&#{url}&title=#{title}")
+      when "buffer"
+        SocialShareButton.openUrl("http://bufferapp.com/add?url=#{url}&text=#{title}")
       when "line"
         SocialShareButton.openUrl("https://timeline.line.me/social-plugin/share?url=#{url}")
       when "qq"


More \vspace removal in import

More \vspace removal in import

--- client/import.coffee
+++ client/import.coffee
@@ -418,7 +418,7 @@
         body = body.replace /\\label{([^{}]*)}/g, (match, label) ->
           labels[label] = title2section title
           ''
-        .replace /^\s*\\vspace\*?\s*{[^{}]*}/, ''  ## used to place wrapfigures
+        .replace /\\vspace\*?\s*{[^{}]*}/g, ''  ## used to place wrapfigures
         console.log "Importing '#{title}'"
         messages.push
           title: title


activity: fix data synchronization bug when a user unfollows a channel

--- client/app/lib/activity/sidebar/activitysidebar.coffee
+++ client/app/lib/activity/sidebar/activitysidebar.coffee
@@ -266,7 +266,9 @@

   accountRemovedFromChannel: (update) ->

-    {id} = update.channel
+    {id, typeConstant} = update.channel
+    {unreadCount, participantCount} = update
+    {socialapi}                     = kd.singletons

     return  if update.isParticipant

@@ -277,6 +279,15 @@

     # TODO update participants in sidebar

+    # TODO I have added these lines for channel data synchronization,
+    # but do not think that this is the right place for doing this.
+    socialapi.cacheable typeConstant, id, (err, channel) ->
+
+      return kd.warn err  if err
+
+      channel.isParticipant    = no
+      channel.participantCount = participantCount
+      channel.emit 'update'

   channelUpdateHappened: (update) -> kd.warn 'dont use this, :::educational purposes only!:::', update


Sidebar: Existence check to front app variable

--- client/app/lib/activity/sidebar/activitysidebar.coffee
+++ client/app/lib/activity/sidebar/activitysidebar.coffee
@@ -532,7 +532,7 @@

     frontApp = kd.singletons.appManager.getFrontApp()

-    if frontApp.options.name is 'IDE'
+    if frontApp?.options.name is 'IDE'
       machine   = frontApp.mountedMachine
       workspace = frontApp.workspaceData


manifests static var assigned to an instance var

--- client/landing/app/MainApp/kodingappscontroller.coffee
+++ client/landing/app/MainApp/kodingappscontroller.coffee
@@ -67,6 +67,7 @@
     super

     @kiteController = @getSingleton('kiteController')
+    @manifests = KodingAppsController.manifests

   # #
   # FETCHERS


instead of pane data just pass to pane itself, we need to handle this for Ace focus issue

--- client/landing/app/MainApp/maintabs/maintabview.coffee
+++ client/landing/app/MainApp/maintabs/maintabview.coffee
@@ -31,8 +31,9 @@
     super pane

     paneMainView = pane.getMainView()
+
     if paneMainView.data?.constructor.name is 'FSFile'
-      @getSingleton('mainController').emit "SelectedFileChanged", paneMainView.data
+      @getSingleton('mainController').emit "SelectedFileChanged", paneMainView

     paneMainView.handleEvent type : "click"
     @handleEvent {type : "MainTabPaneShown", pane}


home: minor styles fix

home: minor styles fix

--- client/landing/site.landing/coffee/home/AppView.coffee
+++ client/landing/site.landing/coffee/home/AppView.coffee
@@ -21,7 +21,7 @@
     @infoDots = []

     @signUpForm = new HomeRegisterForm
-      cssClass    : 'TeamsModal--middle login-form register no-anim'
+      cssClass    : 'login-form register no-anim'
       buttonTitle : 'SIGN UP'
       callback    : (formData) =>
         router.requireApp 'Login', (controller) =>


Register object after initialization

Register object after initialization

--- client/Framework/core/KDObject.coffee
+++ client/Framework/core/KDObject.coffee
@@ -12,10 +12,10 @@
     @setDelegate options.delegate if options.delegate
     @registerKDObjectInstance()

+    super
+
     if options.testPath
       KD.registerInstanceForTesting this
-
-    super

     @on 'error', error
     @once 'ready', => @readyState = READY


realtime: discard duplicate messages

realtime: discard duplicate messages

--- client/Main/realtimecontroller.coffee
+++ client/Main/realtimecontroller.coffee
@@ -5,6 +5,9 @@
     # when we remove broker completely, we no longer need to
     # make another caching here
     @channels = {}
+
+    # this is used for discarding events that are received multiple times
+    @eventCache = {}

     @localStorage  = KD.getSingleton("localStorageController").storage "realtime"

@@ -163,8 +166,15 @@
       @pubnub.subscribe
         channel : pubnubChannelName
         message : (message, env, channel) =>
+
           return  unless message
-          {eventName, body} = message
+
+          {eventName, body, eventId} = message
+
+          return  if @eventCache[eventId]
+
+          @eventCache[eventId] = yes
+
           # when a user is connected in two browsers, and leaves a channel, in second one
           # they receive RemovedFromChannel event for their own. Therefore we must unsubscribe
           # user from all connected devices.


feeder: removed some logs

feeder: removed some logs

--- client/app/Applications/Feeder.kdapplication/Controllers/FeederResultsController.coffee
+++ client/app/Applications/Feeder.kdapplication/Controllers/FeederResultsController.coffee
@@ -110,10 +110,8 @@
         pane.listWrapper.setHeight window.innerHeight

     unless KD.isLoggedIn()
-      log "hello"
       KD.utils.wait 1000, cb
     else
-      log "is it me"
       app.appStorage?.fetchValue "onboardingMessageIsReadFor#{name.capitalize()}Tab", (value)->
         return if value
         KD.utils.wait 1000, cb


collection shouldn't inc depth, just pass it on

--- client/lanes/models/Collection.coffee
+++ client/lanes/models/Collection.coffee
@@ -43,7 +43,6 @@
         new @constructor( @invoke( 'clone' ), @options )

     serialize: (options = {depth: 1}) ->
-        options.depth += 1
         this.map (model) ->
             if model.serialize
                 model.serialize(options)


No need for Annotator's adder.

No need for Annotator's adder.

It just adds an unnecessary DOM element.

--- client/lib/annotator/annotator.coffee
+++ client/lib/annotator/annotator.coffee
@@ -37,6 +37,9 @@
     super $displayWrapper,
       noScan: true
     delete @options.noScan
+
+    # We have out own UI for adding annotations, so we remove Annotator's
+    @adder.remove()

     @_annotations = {}
     @selectedAnnotationId = null


Using unset! to unbind the cmd-< default binding.

--- home/.atom/keymap.cson
+++ home/.atom/keymap.cson
@@ -18,7 +18,7 @@
 #

 '.workspace .editor:not(.mini), .workspace':
-  'cmd-<': ''
+  'cmd-<': 'unset!'

 '.platform-darwin .editor':
   'ctrl-cmd-i': 'script:run'


Use string interpolation and document regex

--- client/views/events/event_show.coffee
+++ client/views/events/event_show.coffee
@@ -36,8 +36,9 @@
   'when': ->
     "#{moment(@from).format('lll')} - #{moment(@to).format('lll')}"
   'maps': ->
+    # Regex to replace spaces with '+' symbol
     event_url = @location.replace(/\s+/g, '+').toLowerCase()
-    "http://maps.google.com/?q=" + event_url + ',+philadelphia'
+    "http://maps.google.com/?q=#{ event_url },+philadelphia"
   'parse': (d) ->
     regex = /((http\:\/\/|https\:\/\/)|(www\.))+(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/g
     d = d.replace regex, (value) ->


removed console.info

removed console.info

--- core/app/backbone/collections/search_collection.coffee
+++ core/app/backbone/collections/search_collection.coffee
@@ -13,7 +13,6 @@
   searchFor: throttle (query) ->
     query = $.trim(query)
     return if query == @query
-    console.info "searching for #{query}"
     @jqxhr?.abort()

     if query == ''


comment out exception which causes issues; tweaks

--- lib/adaptor/ipfs.coffee
+++ lib/adaptor/ipfs.coffee
@@ -11,14 +11,12 @@
     {host, port} = args
     host ?= process?.env?.IPFS_HOST
     port ?= process?.env?.IPFS_PORT
-    if !window? and !host?
-      throw new Error "host must be defined when running outside of a browser"
+    # if !window? and !host?
+    #   throw new Error "host must be defined when running outside of a browser"
     ipfs = Promise.promisifyAll ipfsApi host, port
     ipfs.versionAsync()
-      .then ->
+      .then =>
         return new ipfsAdaptor {ipfs}
-      # .catch ->
-      #   return null

   constructor: ({@ipfs}) ->
     unless @ipfs instanceof ipfsApi


Recognize exact matches when scoring search queries

--- vendor/assets/javascripts/chosen/parser.coffee
+++ vendor/assets/javascripts/chosen/parser.coffee
@@ -283,7 +283,12 @@
                 unless option.match_type is -1
                   option.match_type = expression_index

-                option.score += num_options * (expressions.length - option.match_type) / (word_index + 1)
+                option.score += switch option.match_type
+                  when 0
+                    num_options * (expressions.length - option.match_type)
+                  else
+                    num_options * (expressions.length - option.match_type) / (word_index + 1)
+
                 break
               else if expression_index is expressions.length - 1
                 option.score -= num_options * expressions.length / words.length


:new: A working AutoComplete Better Term Identification Fixes steelbrain/atom-hack#36

--- lib/autocomplete.coffee
+++ lib/autocomplete.coffee
@@ -1,27 +1,44 @@
 module.exports = (Main)->
   Instance = null
   Provider =
+    exclusive: true
     selector: '.source.php,.source.cpp'
     blacklist: '.comment'
-    requestHandler: (options) ->
-      console.log options
-      [{
-        word: 'hello',
-        prefix: 'h',
-        label: 'world',
-        renderLabelAsHtml: true,
-        className: 'globe',
-        onWillConfirm: -> # Do something here before the word has replaced the prefix (if you need, you usually don't need to),
-        onDidConfirm: -> # Do something here after the word has replaced the prefix (if you need, you usually don't need to)
-      }]
-    dispose: ->
-      # Your dispose logic here
+    requestHandler:(options)->
+      AutoComplete.suggestions(options.buffer,options.editor)
   class AutoComplete
+    @points = ['"',"'",' ',')','(',',','{','}',':','-','+','>','<',';',"\n","\r"]
     @activate:->
       return if Main.Status.AutoComplete
       Instance = atom.services.provide('autocomplete.provider', '1.0.0', {provider:Provider})
       Main.Status.AutoComplete = true
     @deactivate:->
-      return unless Main.Status.AutoComplete
+      return unless Main.Status.AutoComplete+
       Instance.dispose()
-      Main.Status.AutoComplete = false+      Main.Status.AutoComplete = false
+    @suggestions:(buffer,editor)->
+      path = editor.getPath()
+      text = buffer.getText()
+      index = buffer.characterIndexForPosition(editor.getCursorBufferPosition())
+      text = text.substr(0,index)+'AUTO332'+text.substr(index)
+      prefix = @prefix(text,index)
+      return new Promise (resolve)->
+        Main.V.H.exec(['--auto-complete'],text,path).then (result)->
+          toReturn = []
+          result = result.stdout.split("\n").filter((e)-> e)
+          if result.length
+            result.forEach (entry)->
+              entry = entry.split(' ')
+              if entry[0].substr(0,1) is ':'
+                toReturn.push {word:entry[0].replace(':',''),label:entry.join(' '),prefix:prefix}
+              else
+                toReturn.push {word:entry[0],label:entry.slice(1).join(' '),prefix:prefix}
+          resolve toReturn
+    @prefix:(text,index)->
+      LaText = []
+      while((index = index-1))
+        char = text.substr(index,1)
+        if @points.indexOf(char) isnt -1
+          break
+        LaText.push char
+      return LaText.reverse().join('').trim()


Update currently selected diff on activate

--- lib/changes-view.coffee
+++ lib/changes-view.coffee
@@ -168,7 +168,11 @@
         if @changeIsStaged(status)
           @renderChangeSummary(status, 'staged')

-      @querySelector('.change')?.click() unless @querySelector('.change.selected')
+      if current = @querySelector('.change.selected')
+        current.click()
+      else
+        @querySelector('.change')?.click()
+
       @diffsNode.innerHTML = '' unless @querySelector('.change.selected')

       @updateCommitButton()


currencyが途中で失われる問題を解消

currencyが途中で失われる問題を解消

--- source/js/page/asset.coffee
+++ source/js/page/asset.coffee
@@ -11,11 +11,13 @@
     list: withdrawalList
   data:
     item:
-      currency: "JPY"
       absAmount: ""
   created: ->
     @initialized()
   methods:
     actionSuccessMessage: -> "依頼を受け付けました"
+    registerData: ->
+      @item.currency = "JPY"
+      @item


I hate Mac.

I hate Mac.

--- views/components/main/parts/teitoku-panel.cjsx
+++ views/components/main/parts/teitoku-panel.cjsx
@@ -1,9 +1,8 @@
 path = require 'path-extra'
-i18n = require 'i18n'
 {ROOT, layout, _, $, $$, React, ReactBootstrap, toggleModal} = window
 {log, warn, error} = window
 {Panel, Grid, Col, OverlayTrigger, Tooltip} = ReactBootstrap
-{__, __n} = i18n
+{__, __n} = require 'i18n'
 order = if layout == 'horizonal' or window.doubleTabbed then [1, 3, 5, 7, 2, 4, 6, 8] else [1..8]

 rankName = ['', '元帥', '大将', '中将', '少将', '大佐', '中佐', '新米中佐', '少佐', '中堅少佐', '新米少佐']


Update teitoku-panel.cjsx

Update teitoku-panel.cjsx

--- views/components/main/parts/teitoku-panel.cjsx
+++ views/components/main/parts/teitoku-panel.cjsx
@@ -27,7 +27,7 @@
                <Col xs={6}>Lv. {state.level} {state.nickname} [{rankName[state.rank]}]</Col>
                <Col xs={6}>Exp. {state.exp}</Col>
              </Grid>
-      else
+   else
       return <Grid>
                 <Col xs={6}>Lv. {state.level} {state.nickname} [{rankName[state.rank]}]</Col>
                 <Col xs={6}>Next. {state.nextExp}</Col>


Added method TableView#rowFor

Added method TableView#rowFor

--- lib/ST/TableView.coffee
+++ lib/ST/TableView.coffee
@@ -98,6 +98,9 @@
         for item in @_ordered
           @_tbody.append @_rowsByUid[item._uid]

+  @method 'rowFor', (item) ->
+    item && item._uid && @_rowsByUid[item._uid]
+
   @method 'render', ->
     @renderTable()
     @element().append @_tableElement


command: remove config.actions

command: remove config.actions

--- lib/commands/run.coffee
+++ lib/commands/run.coffee
@@ -37,7 +37,7 @@
         continue unless service.plugin
         instance = array_get(service.instances, (instance) -> instance.node.id is node.id)
         n.call service.plugin, mixme {}, instance.options
-    n.call config.actions, ->
+    n.call -> # config.actions,
       for service in node.services
         service = s.service service.cluster, service.service
         continue if params.modules and multimatch(service.module, params.modules).length is 0


Fix cascade in cache key

Fix cascade in cache key

--- lib/autoprefixer.coffee
+++ lib/autoprefixer.coffee
@@ -27,7 +27,7 @@

   loadPrefixes = (opts) ->
     browsers = new Browsers(module.exports.data.browsers, reqs, opts)
-    key      = browsers.selected.join(', ') + (!!options.cascade).toString()
+    key      = browsers.selected.join(', ') + options.cascade
     cache[key] ||= new Prefixes(module.exports.data.prefixes, browsers, options)

   plugin = (css, result) ->


some cleanup

some cleanup

--- client/landing/app/Applications/Activity.kdapplication/views/newmemberbucket.coffee
+++ client/landing/app/Applications/Activity.kdapplication/views/newmemberbucket.coffee
@@ -80,64 +80,6 @@
       click       : (e)=>
         @emit "moreLinkClicked"

-  # pistachio:->
-
-  #   participants = @getData()
-  #   {hasMore, totalCount, group, separator} = @getOptions()
-
-  #   @createMoreLink()
-  #   l = if @getData().length < 4 then @getData().length else 3
-  #   tmpl = ""
-  #   for i in [0...l]
-  #     tmpl += "{{> @participant#{i}}}"
-  #     tmpl += separator if i isnt l-1
-
-  #   if totalCount > @getData().length
-  #     tmpl += " and {{> @more}}"
-
-  #   tmpl += " became a member."
-  #   # tmpl += "{{> @loader }}"
-
-
-# SLIGHTLY OLD
-
-# class NewMemberBucketData extends KDObject
-
-#   constructor:(options, @buckets)->
-
-#     @bongo_ = {}
-#     @meta   = @buckets[0].meta
-#     @bongo_.constructorName = "NewMemberBucketData"
-#     super
-
-# class NewMemberBucketView extends JView
-
-#   constructor: (options = {}, data)->
-
-#     options.cssClass = "new-member"
-
-#     super
-
-#     @group = new LinkGroup {}, @getData().buckets.map (bucket)-> bucket.anchor
-
-#   viewAppended:->
-
-#     super
-
-#     @timer = @utils.wait 800, =>
-#       @$('.fx').removeClass "out hidden"
-#       @timer = @utils.wait 400, =>
-#         @$('.fx').addClass "hidden"
-
-#   pistachio:->
-#     """
-#
-#
-#     {{> @group}}
-#     became member.
-#     """
-
-

 # OLD


fix bug for 99 to 100 boundary

fix bug for 99 to 100 boundary

--- lib/item-reducer.coffee
+++ lib/item-reducer.coffee
@@ -37,8 +37,7 @@
   if state.showColumn
     toColumn = (item) -> item.point.column
     maxColumn = normalItems.map(toColumn).reduce(byMax, 0)
-    maxColumnWidth = Math.max(String(maxColumn).length, 2)
-    console.log maxColumn
+    maxColumnWidth = Math.max(String(maxColumn + 1).length, 2)

   for item in normalItems
     item._lineHeader = getLineHeaderForItem(item.point, maxLineWidth, maxColumnWidth)


Adds a subscription to screen-lines-changed

When the minimap is created, the minimap view changes the editor width,
and build it self on an outdated version, the `screen-lines-changed`
event allow us to be notified when the editor have updated the screen
lines after resize.

--- lib/minimap-view.coffee
+++ lib/minimap-view.coffee
@@ -79,9 +79,11 @@
     @scrollViewLines = @scrollView.find('.lines')

     # current editor binds scroll events
+    @unsubscribe @editor, 'screen-lines-changed'
     @unsubscribe @editor, 'scroll-top-changed.editor'
     @unsubscribe @editor, 'scroll-left-changed.editor'

+    @subscribe @editor, 'screen-lines-changed', => @miniEditorView.update()
     @subscribe @editor, 'scroll-top-changed.editor', @updateScroll
     @subscribe @editor, 'scroll-left-changed.editor', @updateScroll


remove resetMinimapTransform and initialed miniWrapper scale

--- lib/minimap-view.coffee
+++ lib/minimap-view.coffee
@@ -32,6 +32,8 @@
     @minimapScale = @scale(@scaleX, @scaleY)
     @miniScrollView = @miniEditorView.scrollView
     @minimapScroll = 0
+
+    @transform @miniWrapper[0], @minimapScale

   initialize: ->

@@ -77,8 +79,6 @@
   deactivatePaneViewMinimap: ->
     @paneView.removeClass('with-minimap')
     @detachFromPaneView()
-
-  resetMinimapTransform: -> @transform @miniWrapper[0], @scale()

   minimapIsAttached: -> @paneView.find('.minimap').length is 1


also, because of preference about paren change

--- lib/mode-manager.coffee
+++ lib/mode-manager.coffee
@@ -30,11 +30,11 @@
     else
       @mode is mode

-  onWillActivateMode: (fn) -> @emitter.on 'will-activate-mode', fn
-  onDidActivateMode: (fn) -> @emitter.on 'did-activate-mode', fn
-  onWillDeactivateMode: (fn) -> @emitter.on 'will-deactivate-mode', fn
-  preemptWillDeactivateMode: (fn) -> @emitter.on 'will-deactivate-mode', fn
-  onDidDeactivateMode: (fn) -> @emitter.on 'did-deactivate-mode', fn
+  onWillActivateMode: (fn) -> @emitter.on('will-activate-mode', fn)
+  onDidActivateMode: (fn) -> @emitter.on('did-activate-mode', fn)
+  onWillDeactivateMode: (fn) -> @emitter.on('will-deactivate-mode', fn)
+  preemptWillDeactivateMode: (fn) -> @emitter.on('will-deactivate-mode', fn)
+  onDidDeactivateMode: (fn) -> @emitter.on('did-deactivate-mode', fn)

   # activate: Public
   #  Use this method to change mode, DONT use other direct method.
@@ -43,7 +43,7 @@
     # Avoid odd state(=visual-mode but selection is empty)
     return if (mode is 'visual') and @editor.isEmpty()

-    @emitter.emit 'will-activate-mode', {mode, submode}
+    @emitter.emit('will-activate-mode', {mode, submode})

     if (mode is 'visual') and (submode is @submode)
       [mode, submode] = ['normal', null]
@@ -65,12 +65,12 @@

     @vimState.statusBarManager.update(@mode, @submode)
     @vimState.updateCursorsVisibility()
-    @emitter.emit 'did-activate-mode', {@mode, @submode}
+    @emitter.emit('did-activate-mode', {@mode, @submode})

   deactivate: ->
-    @emitter.emit 'will-deactivate-mode', {@mode, @submode}
+    @emitter.emit('will-deactivate-mode', {@mode, @submode})
     @deactivator?.dispose()
-    @emitter.emit 'did-deactivate-mode', {@mode, @submode}
+    @emitter.emit('did-deactivate-mode', {@mode, @submode})

   # Normal
   # -------------------------


Updated open ss variable regex

Updated open ss variable regex


Fixed #7 with a nice cast-end sound (just reverse of cast sound).

--- app/views/play/level/tome/cast_button_view.coffee
+++ app/views/play/level/tome/cast_button_view.coffee
@@ -57,7 +57,7 @@

   onCastSpells: (e) ->
     @casting = true
-    Backbone.Mediator.publish 'play-sound', trigger: 'cast', volume: 0.25
+    Backbone.Mediator.publish 'play-sound', trigger: 'cast', volume: 0.5
     @updateCastButton()
     @onWorldLoadProgressChanged progress: 0

@@ -67,6 +67,7 @@

   onNewWorld: (e) ->
     @casting = false
+    Backbone.Mediator.publish 'play-sound', trigger: 'cast-end', volume: 0.5
     @updateCastButton()

   updateCastButton: ->


Removed superfluous comment

Removed superfluous comment

--- app/views/play/level/tome/cast_button_view.coffee
+++ app/views/play/level/tome/cast_button_view.coffee
@@ -74,7 +74,6 @@

   updateCastButton: ->
     return if _.some @spells, (spell) => not spell.loaded
-    #this is going to have some problems...

     async.some _.values(@spells), (spell, callback) =>
       spell.hasChangedSignificantly spell.getSource(), null, callback


wording

wording

--- test/cachet-test.coffee
+++ test/cachet-test.coffee
@@ -45,7 +45,7 @@
         done()

   describe 'incident commands', ->
-    it 'should allow to create "investigating" incidents', (done) ->
+    it 'should allow to declare "investigating" incidents', (done) ->
       json = {
         name:"foo",
         message:"msg",
@@ -60,7 +60,7 @@
         assert.include response, 'Incident `#123` declared'
         done()

-    it 'should allow to create "identified" incidents', (done) ->
+    it 'should allow to declare "identified" incidents', (done) ->
       json = {
         name:"foo",
         message:"msg",
@@ -75,7 +75,7 @@
         assert.include response, 'Incident `#124` declared'
         done()

-    it 'should allow to create "watching" incidents', (done) ->
+    it 'should allow to declare "watching" incidents', (done) ->
       json = {
         name:"foo",
         message:"msg",
@@ -90,7 +90,7 @@
         assert.include response, 'Incident `#125` declared'
         done()

-    it 'should allow to create "fixed" incidents', (done) ->
+    it 'should allow to declare "fixed" incidents', (done) ->
       json = {
         name:"foo",
         message:"msg",
@@ -105,7 +105,7 @@
         assert.include response, 'Incident `#126` declared'
         done()

-    it 'should allow to create incidents on known components', (done) ->
+    it 'should allow to declare incidents on known components', (done) ->
       helper.converse @robot, @user, '/cachet component set foo 3', (envelope, response) ->
         assert.include response, 'The component \'foo\' (id = 3) has been set'


Use standard name

Use standard name

--- bin/uglify.coffee
+++ bin/uglify.coffee
@@ -1,7 +1,7 @@
 #!/usr/bin/env coffee
 #
 fs = require 'fs'
-UglifyJS = require 'uglify-js'
+UglifyJS = require 'uglifyjs'
 version = require('../package.json').version

 ast = UglifyJS.parse(fs.readFileSync('src/bugsnag.js').toString('utf8'),


Clamp framerate to 15fps minimum

Clamp framerate to 15fps minimum

--- app/js/world.coffee
+++ app/js/world.coffee
@@ -56,6 +56,9 @@
   # Public: update callback. dt is raw javascript time delta in ms.
   update: (dt) ->
     return if @paused
+
+    # clamp dt to 15fps minimum
+    dt = 66 if dt > 66

     dt = dt / 1000 * @speedFactor
     dt = dt / 5 if @slow


fix compile and error messages

fix compile and error messages

--- lib/local_server.coffee
+++ lib/local_server.coffee
@@ -92,8 +92,7 @@
     cleanError = if err.replace
       err.replace(/(\r\n|\n|\r)/gm, '
')
     else
-      ""
-    @bs.notify("

compile
-    error#{cleanError}

")
+      "compile error!"
+    @bs.notify(cleanError, 100000)

 module.exports = Server


debug index tests

debug index tests

--- test/index_tests.coffee
+++ test/index_tests.coffee
@@ -3,7 +3,7 @@
 Client = require('request-json').JsonClient
 app = require('../server')

-client = new Client("http://localhost:7000/")
+client = new Client("http://localhost:8888/")

 # connection to DB for "hand work"
@@ -25,6 +25,7 @@
             docType: "Note"

         client.post "data/", note, (error, response, body) ->
+            console.log error if error
             client.post "data/index/#{body._id}",
                 fields: ["title", "content"]
                 , callback
@@ -32,20 +33,20 @@

 describe "Indexation", ->

+    # Start application before starting tests.
+    before (done) ->
+        app.listen(8888)
+        done()
+
     # Clear DB, create a new one, then init data for tests.
     before (done) ->
         client.del "data/index/clear-all/", (err, response) ->
+            console.log err if err
             db.destroy ->
                 console.log 'DB destroyed'
                 db.create ->
                     console.log 'DB recreated'
                     done()
-
-    # Start application before starting tests.
-    before (done) ->
-        app.listen(8888)
-        done()
-

     describe "indexing and searching", ->


Update jstips-test.coffee

Update jstips-test.coffee

--- test/jstips-test.coffee
+++ test/jstips-test.coffee
@@ -13,5 +13,5 @@
     require('../src/jstips')(@robot)

   it 'registers a respond listener', ->
-    expect(@robot.respond).to.have.been.calledWith(/jstip/)
+    expect(@robot.respond).to.have.been.calledWith(/jstip/i)


Green tests for Normalisers.place on title

--- test/normalizers.coffee
+++ test/normalizers.coffee
@@ -39,3 +39,15 @@
 			KEYS.forEach (key) ->
 				it "should properly set #{key}", (test) ->
 					test.equal actual[key], expected[key]
+
+		describe 'with a title reference', ->
+			actual = Normalizers.place 'Titre'
+
+			expected =
+				name: 'titre'
+				raw: 'Titre'
+
+			KEYS.forEach (key) ->
+				it "should properly set #{key}", (test) ->
+					test.equal actual[key], expected[key]
+


test: cast info properties

test: cast info properties

--- test/option.cast.coffee
+++ test/option.cast.coffee
@@ -56,7 +56,22 @@

   describe 'function', ->

-    it 'custom function', (next) ->
+    it.only 'custom function', (next) ->
+      parse """
+      hello
+      """,
+        cast: (value, context) ->
+          Object.keys context
+      , (err, records) ->
+        records.should.eql [
+          [[
+            'column', 'empty_lines', 'error', 'header', 'index'
+            'invalid_field_length', 'quoting', 'lines', 'records'
+          ]]
+        ] unless err
+        next err
+
+    it 'return anything, eg a string or an object', (next) ->
       parse """
       2000-01-01,date1
       2050-11-27,date2


Fix tests, and add test for brain event

Fix tests, and add test for brain event

--- test/remind-test.coffee
+++ test/remind-test.coffee
@@ -5,8 +5,10 @@
 expect = chai.expect

 describe "remind", ->
-    beforeEach ->
+    before ->
         @robot =
+            brain:
+                on: sinon.spy()
             respond: sinon.spy()
             hear: sinon.spy()

@@ -20,3 +22,6 @@

     it "registers a hear listener", ->
         expect(@robot.hear).to.have.been.calledWith(/(.+)/i)
+
+    it "registers a brain event listener", ->
+        expect(@robot.brain.on).to.have.been.calledWith("loaded")


Revert "color for loading message"

Revert "color for loading message"

This reverts commit ba66e5f112d19ceff52bfc31bad3a101a5620f03.

--- lib/query_runner.coffee
+++ lib/query_runner.coffee
@@ -78,8 +78,9 @@
       sass = "[DEVELOPMENT] #{sass}"

     params =
+      text: sass
       as_user: true
-      attachments: [{text: sass, color: "#64518A", unfurl_links: false, unfurl_media: false}]
+      attachments: [] # Override some Botkit stuff
       unfurl_links: false
       unfurl_media: false


Cursors now appear where we want them to! Fixes #4704961

--- javascripts/lib/math/expression_manipulation.coffee
+++ javascripts/lib/math/expression_manipulation.coffee
@@ -386,7 +386,6 @@
     class NegateLast extends ExpressionManipulation
       negateComp: (comp)->
         last = comp.last()
-

         if last instanceof @comps.classes.number
           last.negatedD()


Only one modal

Only one modal

--- sources/tuktuk.modal.coffee
+++ sources/tuktuk.modal.coffee
@@ -13,8 +13,8 @@
   ###
   show = (modal_id)->
     lock.addClass("active").show()
-    modal = tk.dom("[data-tuktuk=modal]##{modal_id}").first()
-    modal.addClass "active"
+    tk.dom("[data-tuktuk=modal]").removeClass("active")
+    modal = tk.dom("[data-tuktuk=modal]##{modal_id}").addClass "active"
     @

   ###
@@ -32,7 +32,7 @@
       @loading: Describe method
   ###
   loading = (text) ->
-    lock.attr("data-loading", "true").addClass("active")
+    lock.attr("data-loading", "true").addClass("active").show()
     @

   _Instance: (->


refactor to use if/else instead of returns for control flow

--- lib/assets/javascripts/turbograft/turbolinks.coffee
+++ lib/assets/javascripts/turbograft/turbolinks.coffee
@@ -132,15 +132,16 @@
     options.updatePushState ?= true
     if upstreamDocument = processResponse(xhr)
       reflectNewUrl url if options.updatePushState
-      unless options.partialReplace
-        return new TurboHead(document, upstreamDocument).update(
+      if options.partialReplace
+        updateBody(upstreamDocument, xhr, options)
+      else
+        new TurboHead(document, upstreamDocument).update(
           onHeadUpdateSuccess = ->
             updateBody(upstreamDocument, xhr, options)
           ,
           onHeadUpdateError = ->
             Turbolinks.fullPageNavigate(url.absolute)
         )
-      return updateBody(upstreamDocument, xhr, options)
     else
       triggerEvent 'page:error', xhr
       Turbolinks.fullPageNavigate(url.absolute) if url?


Document visible field

Document visible field

--- imports/disappear.coffee
+++ imports/disappear.coffee
@@ -51,6 +51,8 @@
 ##   node: <DOM element>
 ##   appear: -> ...callback when it is visible...
 ##   disappear: -> ...callback when it is invisible...
+## The object will be modified to have a `visible` field set to true or false
+## as its visibility changes.
 export track = (tracked) ->
   #checkOne tracked
   tracking.push tracked


Remove console.log

Remove console.log

--- catalog/src/js/loading.coffee
+++ catalog/src/js/loading.coffee
@@ -2,10 +2,8 @@

 export default {
   show: ->
-    console.log('show loading')
     $('.loading').show()

   hide: ->
-    console.log('hide loading')
     $('.loading').hide()
 }


Nuke stray call to Editor.logLines

Nuke stray call to Editor.logLines

--- spec/app/editor-spec.coffee
+++ spec/app/editor-spec.coffee
@@ -927,8 +927,6 @@
             editor.visibleLines.trigger 'mouseup'
             expect(editor.getSelectedText()).toBe "    return sort(left).concat(pivot).concat(sort(right));"

-            editor.logLines()
-
             # Quad click
             point = [12, 3]
             editor.visibleLines.trigger mousedownEvent(editor: editor, point: point, originalEvent: {detail: 1})


:poop:

:poop:

--- spec/app/editor-spec.coffee
+++ spec/app/editor-spec.coffee
@@ -515,7 +515,7 @@
         rootView.height(200)
         rootView.width(200)

-        config.update("editor.fontSize", fontSize)
+        config.update("editor.fontSize", 10)
         lineHeightBefore = editor.lineHeight
         charWidthBefore = editor.charWidth
         editor.setCursorScreenPosition [5, 6]
@@ -1559,7 +1559,6 @@
         expect(editor.renderedLines.find('.line').text()).toBe "•a line with tabs▸ and spaces•¬"

         config.update("editor.showInvisibles", false)
-        config.update()
         expect(editor.renderedLines.find('.line').text()).toBe " a line with tabs  and spaces "

       it "displays newlines(¬) as their own token outside of the other tokens scope", ->


Remove unused import

Remove unused import

--- spec/app/editor-spec.coffee
+++ spec/app/editor-spec.coffee
@@ -8,7 +8,6 @@
 {$$} = require 'space-pen'
 _ = require 'underscore'
 fs = require 'fs'
-Git = require 'git'

 describe "Editor", ->
   [buffer, editor, cachedLineHeight] = []


Make window specs pass without getActiveEditor/getEditors

--- spec/app/window-spec.coffee
+++ spec/app/window-spec.coffee
@@ -46,16 +46,17 @@
       expect(window.close).toHaveBeenCalled()

   describe ".reload()", ->
+    beforeEach ->
+      spyOn($native, "reload")
+
     it "returns false when no buffers are modified", ->
-      spyOn($native, "reload")
       window.reload()
       expect($native.reload).toHaveBeenCalled()

-    it "shows alert when a modifed buffer exists", ->
+    it "shows an alert when a modifed buffer exists", ->
       rootView.open('sample.js')
-      rootView.getActiveEditor().insertText("hi")
+      rootView.getActiveView().insertText("hi")
       spyOn(atom, "confirm")
-      spyOn($native, "reload")
       window.reload()
       expect($native.reload).not.toHaveBeenCalled()
       expect(atom.confirm).toHaveBeenCalled()
@@ -103,13 +104,13 @@

     it "unsubscribes from all buffers", ->
       rootView.open('sample.js')
-      editor1 = rootView.getActiveEditor()
-      editor2 = editor1.splitRight()
-      expect(window.rootView.getEditors().length).toBe 2
+      buffer = rootView.getActivePaneItem().buffer
+      rootView.getActivePane().splitRight()
+      expect(window.rootView.find('.editor').length).toBe 2

       window.shutdown()

-      expect(editor1.getBuffer().subscriptionCount()).toBe 0
+      expect(buffer.subscriptionCount()).toBe 0

     it "only serializes window state the first time it is called", ->
       deactivateSpy = spyOn(atom, "setRootViewStateForPath").andCallThrough()


increase kite timeout to 15s

increase kite timeout to 15s

--- client/Main/kite/kite2.coffee
+++ client/Main/kite/kite2.coffee
@@ -44,4 +44,4 @@
         # .tellOld is deprecated, but still used internally here temporarily
         @tellOld options, callback

-    .timeout classTimeout ? 5000
+    .timeout classTimeout ? 15000


Terminal: starttab vmitem shows loading when it fails to fetch state

--- client/Terminal/vmitem.coffee
+++ client/Terminal/vmitem.coffee
@@ -22,7 +22,7 @@

     @notice = new KDCustomHTMLView
       tagName : 'i'
-      partial : '0%'
+      partial : 'LOADING'

     @progress = new KDCustomHTMLView
       tagName  : 'cite'
@@ -79,16 +79,21 @@
   handleVMInfo:(info)->

     unless info
-      @loader.hide()
-      @notice.updatePartial 'FAILED'
+      @unsetClass 'ready'
+      @loader.show()
+      @notice.updatePartial 'LOADING'
       return

     { state } = info
     switch state.toLowerCase()
       when "running"
+        @loader.hide()
+        @unsetClass 'off'
         @notice.updatePartial 'READY'
         @setClass 'ready'
       when "stopped"
+        @loader.hide()
+        @unsetClass 'ready'
         @setClass 'off'
         @notice.updatePartial 'OFF'


group bundle: simplify vm bookkeeping

group bundle: simplify vm bookkeeping

--- workers/social/lib/social/models/bundle/groupbundle.coffee
+++ workers/social/lib/social/models/bundle/groupbundle.coffee
@@ -64,20 +64,17 @@
       subs.forEach (sub) ->
         paidVMs = sub.quantity

-      createdVMs = 0
-      JVM.someData
-        planOwner: paymentMethodId
-        planCode : planCode
-      ,
-        name     : 1
-      , {}, (err, cursor)=>
-        cursor.toArray (err, arr)=>
-          return callback err  if err
-          createdVMs = arr.length or 0
-          firstVM = group.slug in ['koding','guests'] and \
-                    createdVMs == 0 and planCode is 'free'
+      selector    =
+        planOwner : paymentMethodId
+        planCode  : planCode

-          callback null, paidVMs > createdVMs or firstVM
+      JVM.count selector, (err, count = 0) ->
+        return callback err  if err
+
+        firstVM = group.slug in ['koding','guests'] and
+                  count is 0 and planCode is 'free'
+
+        callback null, paidVMs > count or firstVM

   createVM: (account, group, data, callback) ->


Add browserify docs

Add browserify docs

--- coffee/formats/package.coffee
+++ coffee/formats/package.coffee
@@ -416,4 +416,48 @@

See npm help config to see the list of config options that can be overridden.

   '''

+  # Browserify
+  'browser': '''
+
Browser

+
Browserify specific

+
+
The browser field allows you to specify browser-specific versions of your files.  Rather than your main file, you might wish to have browserify use a different entry point when this module is bundled for the browser:

+
+
"browser": "./browser.js"

+
+
You can also override multiple files:

+
+
"browser": {
+      "fs": "level-fs",
+      "./lib/ops.js": "./browser/opts.js"
+    }
+

+  '''
+
+  'browserify\.transform(\.INDEX)?': '''
+
Transform

+
Browserify specific

+
+
Transforms are applied to your modules during the Browserify bundling process.  You can use them to do things like include file contents or compile CoffeeScript.

+
+
For example, to enable the brfs transform:

+
+
"browserify": {"transform": ["brfs"]}

+
+
Be sure to include the necessary module in your dependencies or devDependencies as well.

+  '''
+
+  'browserify': '''
+
Browserify

+
+
The browserify section allows you to provide specific configuration to the Browserify bundler.

+
+
"browserify": {
+      "transform": [
+        "coffeeify"
+      ]
+    },
+

+  '''
+
 module.exports = context


Update cards-es.coffee

Update cards-es.coffee

--- coffeescripts/cards-es.coffee
+++ coffeescripts/cards-es.coffee
@@ -1151,7 +1151,7 @@
         '"Visir"':
             text: """Después de que una nave aliada ejecute una maniobra con una velocidad de 1, si esa nave está situada a alcance 1 de ti y no se ha solapado con ninguna nave, puedes asignarle 1 de tus fichas de Concentración o Evasión."""
             ship: "Segador TIE"
-        'Captain Feroph"':
+        'Captain Feroph':
             name: 'Capitán Feroph'
             ship: "Segador TIE"
             text: '''Cuando te defiendas, si el atacante está interferido, añade 1 resultado %EVADE% a tu tirada.'''
@@ -2254,7 +2254,7 @@
             name: "Formación de fuego cruzado"
             ship: "Bombardero B/SF-17"
             text: '''Sólo bombardero B/SF-17.%LINEBREAK%Cuando te defiendas, si hay por lo menos 1 otra nave aliada de la Reistencia situada a alcance 1-2 del atacante, puedes añadir 1 resultado %FOCUS% a tu tirada.'''
-        '''Advanced Ailerons''':
+        'Advanced Ailerons':
             name: "Alerones avanzados"
             ship: "Segador TIE"
             text: '''Sólo Segador TIE.%LINEBREAK%Tus maniobras (%BANKLEFT% 3) y (%BANKRIGHT% 3) se consideran blancas.%LINEBREAK%Inmediatamente antes de revelar tu selector de maniobras, si no estás bajo tensión, debes ejecutar una manibora blanca (%BANKLEFT% 1), (%STRAIGHT% 1) o (%BANKRIGHT% 1).'''


some card names were in english

some card names were in english

Corrected.

--- coffeescripts/cards-es.coffee
+++ coffeescripts/cards-es.coffee
@@ -716,22 +716,27 @@
             name: "Oficial de Flota"
             text: """Acción: Elige hasta 2 naves aliadas a alcance 1-2 y asigna 1 ficha de Concentración a cada una de ellas. Después recibes una ficha de Tensión."""
         "Lone Wolf":
+            name: "Lobo solitario"
             text: """Cuando ataques o defiendas, si no hay ninguna nave aliada a alcance 1-2, pues retirar 1 de tus resultados de cara vacía."""
         "Stay On Target":
+            name: "Seguir el Objetivo"
             text: """Cuando reveles tu dial de maniobra, puedes cambiarlo y seleccionar una maniobra diferente con la misma velocidad.

Trata la nueva maniobra seleccionada como si fuera roja."""
         "Dash Rendar":
             text: """Puedes realizar ataques mientras te solapas con un obstáculo.

Tus ataques no pueden ser obstruidos."""
         '"Leebo"':
             text: """Acción: Realiza una acción gratuita de Impulso. Recibe 1 marcador de iones."""
         "Ruthlessness":
+            name: "Crueldad"
             text: """Después de que realices un ataque que impacte, tu debes elegir 1 nave a alcance 1 del defensor (a parte de ti).  Esa nave sufre 1 daño."""
         "Intimidation":
+            name: "Intimidación"
             text: """Mientras estes en contacto con una nave enemiga, reduce su agilidad en 1."""
         "Ysanne Isard":
             text: """Al comienzo de la fase de combate, si no tienes escudos y al menos tienes 1 carta dedaño asignada a tu nave, puedes realizar una acción gratuita de Evadir."""
         "Moff Jerjerrod":
             text: """Cuando se te asigna un carta de daño boca arribar, puedes descartar esta mejora u otra de %CREW% para poner boca abajo esa carta de daño (sin resolver su efecto)."""
         "Ion Torpedoes":
+            name: "Torpedos de Iones"
             text: """Ataque (Blanco Fijado): Retira el blanco fijado y descarta esta carta para realizar este ataque.

Si el ataque impacta, el defensor y cada nave a alcance 1 de él recibe 1 marcador de iones."""

     modification_translations =


Fix manifest for Gozanti.

Fix manifest for Gozanti.

fixes #299

--- coffeescripts/manifest.coffee
+++ coffeescripts/manifest.coffee
@@ -2573,19 +2573,49 @@
             count: 2
         }
         {
+            name: 'Marksmanship'
+            type: 'upgrade'
+            count: 1
+        }
+        {
+            name: 'Expert Handling'
+            type: 'upgrade'
+            count: 1
+        }
+        {
             name: 'Expose'
             type: 'upgrade'
             count: 1
         }
         {
-            name: 'Marksmanship'
-            type: 'upgrade'
-            count: 1
-        }
-        {
-            name: 'Expert Handling'
-            type: 'upgrade'
-            count: 1
+            name: 'Ion Torpedoes'
+            type: 'upgrade'
+            count: 1
+        }
+        {
+            name: 'Cluster Missiles'
+            type: 'upgrade'
+            count: 1
+        }
+        {
+            name: 'Homing Missiles'
+            type: 'upgrade'
+            count: 1
+        }
+        {
+            name: 'Dual Laser Turret'
+            type: 'upgrade'
+            count: 1
+        }
+        {
+            name: 'Broadcast Array'
+            type: 'upgrade'
+            count: 1
+        }
+        {
+            name: 'Construction Droid'
+            type: 'upgrade'
+            count: 2
         }
         {
             name: 'Agent Kallus'
@@ -2598,14 +2628,9 @@
             count: 1
         }
         {
-            name: 'Broadcast Array'
-            type: 'upgrade'
-            count: 1
-        }
-        {
-            name: 'Dual Laser Turret'
-            type: 'upgrade'
-            count: 1
+            name: 'Ordnance Experts'
+            type: 'upgrade'
+            count: 2
         }
         {
             name: 'Docking Clamps'
@@ -2613,7 +2638,7 @@
             count: 1
         }
         {
-            name: 'Ordnance Experts'
+            name: 'Cluster Bombs'
             type: 'upgrade'
             count: 2
         }


Update tests for follows page.

Update tests for follows page.

--- apps/favorites_follows/test/client/follows.coffee
+++ apps/favorites_follows/test/client/follows.coffee
@@ -95,7 +95,7 @@
     describe '#setupFollowingItems', ->

       it 'renders the first page of following artists', ->
-        $results = @view.$el.find('.follows').children()
+        $results = @view.$el.find('.follows .follows-item')
         $results.length.should.equal 2
         $results.eq(0).html().should.include 'artist1'
         $results.eq(1).html().should.include 'artist2'
@@ -104,19 +104,21 @@
     describe '#loadNextPage', ->

       it 'renders the next pages individually until the end', ->
-        $following = @view.$el.find('.follows')
         @view.loadNextPage()
-        $following.children().length.should.equal 4
-        $following.children().eq(0).html().should.include 'artist1'
-        $following.children().eq(1).html().should.include 'artist2'
-        $following.children().eq(2).html().should.include 'artist3'
-        $following.children().eq(3).html().should.include 'artist4'
+        $following = @view.$el.find('.follows .follows-item')
+        $following.length.should.equal 4
+        $following.eq(0).html().should.include 'artist1'
+        $following.eq(1).html().should.include 'artist2'
+        $following.eq(2).html().should.include 'artist3'
+        $following.eq(3).html().should.include 'artist4'
         @view.loadNextPage()
-        $following.children().length.should.equal 5
-        $following.children().eq(0).html().should.include 'artist1'
-        $following.children().eq(1).html().should.include 'artist2'
-        $following.children().eq(2).html().should.include 'artist3'
-        $following.children().eq(3).html().should.include 'artist4'
-        $following.children().eq(4).html().should.include 'artist5'
+        $following = @view.$el.find('.follows .follows-item')
+        $following.length.should.equal 5
+        $following.eq(0).html().should.include 'artist1'
+        $following.eq(1).html().should.include 'artist2'
+        $following.eq(2).html().should.include 'artist3'
+        $following.eq(3).html().should.include 'artist4'
+        $following.eq(4).html().should.include 'artist5'
         @view.loadNextPage()
-        $following.children().length.should.equal 5
+        $following = @view.$el.find('.follows .follows-item')
+        $following.length.should.equal 5


don't need jquery to construct urls

don't need jquery to construct urls

--- app/opentsdb.coffee
+++ app/opentsdb.coffee
@@ -1,5 +1,5 @@
 _ = require 'underscore'
-$ = require 'jquery'
+URI = require 'URIjs'
 Q = require 'q'
 Html = require './html'
 modules = require './modules'
@@ -52,13 +52,13 @@
     "#{title}: #{message}"

   data_url: ({time_series, start, end, aggregation, group}) ->
-    base_url = settings.get 'base_url'
+    base_url = settings.get('base_url')
     if not base_url?
-      throw new Error 'OpenTSDB base_url not set'
+      throw new Error('OpenTSDB base_url not set')
     start ?= '1d-ago'
-    m = _.map time_series, opentsdb.to_metric_string
+    m = _.map(time_series, opentsdb.to_metric_string)
     params = {start, end, m, ascii: true}
-    "#{base_url}/q?#{$.param params, true}"
+    new URI("#{base_url}/q").setQuery(params).toString()

   tsd: (params) ->
     http.get(opentsdb.data_url(params), dataType: 'text')


Update home page copy

Update home page copy

Capitalized "Earth" 10/29/2015

--- app/pages/home.cjsx
+++ app/pages/home.cjsx
@@ -11,7 +11,7 @@
     hero:
       tagline: 'Take part in an amazing wildlife comeback story!'
       overview: '''
-      Gorongosa National Park in Mozambique was once among the most diverse places on earth, but decades of war decimated the park’s large animal populations. Now, an international conservation effort is working to restore the park’s wildlife — and we need you to help document this incredible recovery. Join us in identifying Gorongosa’s animals in trail camera photos and become part of our conservation team!
+      Gorongosa National Park in Mozambique was once among the most diverse places on Earth, but decades of war decimated the park’s large animal populations. Now, an international conservation effort is working to restore the park’s wildlife — and we need you to help document this incredible recovery. Join us in identifying Gorongosa’s animals in trail camera photos and become part of our conservation team!
       '''
     learnMore: 'Learn More'
     getStarted: 'Get Started!'


Do not require a login for builds

Do not require a login for builds

Fixes: #578
Change-Type: patch

--- lib/actions/build.coffee
+++ lib/actions/build.coffee
@@ -47,7 +47,6 @@
 module.exports =
 	signature: 'build [source]'
 	description: 'Build a single image or a multicontainer project locally'
-	permission: 'user'
 	primary: true
 	help: '''
 		Use this command to build an image or a complete multicontainer project


Fixed bug in connection request digest authentication caused authentication response being sent over a new connection

--- lib/api-functions.coffee
+++ lib/api-functions.coffee
@@ -8,8 +8,12 @@

 connectionRequest = (deviceId, callback) ->
+  # ensure socket is reused in case of digest authentication
+  agent = new http.Agent({maxSockets : 1})
+
   conReq = (url, authString, callback) ->
     options = URL.parse(url)
+    options.agent = agent

     if authString
       options.headers = {'Authorization' : authString}
@@ -18,6 +22,8 @@
       if res.statusCode == 401
         authHeader = auth.parseAuthHeader(res.headers['www-authenticate'])
       callback(res.statusCode, authHeader)
+      # don't need body, go ahead and emit events to free up the socket for possible reuse
+      res.resume()
     )

     request.on('error', (err) ->


removed unused method - get back here after merge conflict

--- core/app/backbone/models/wheel.coffee
+++ core/app/backbone/models/wheel.coffee
@@ -106,7 +106,3 @@
       error: =>
         @turnOnActiveOpinionType opinion_type
         options.error?()
-
-  toJSON: ->
-    _.extend {}, super(),
-      opinion_types_array: @opinionTypesArray()


remove debugging get settings function

remove debugging get settings function

--- app.coffee
+++ app.coffee
@@ -143,11 +143,6 @@
 app.get "/smoke_test_force", (req, res)->
 	smokeTest.run(require.resolve(__dirname + "/test/smoke/js/SmokeTests.js"))(req, res)

-
-#TODO delete this
-app.get "/settings", (req, res)->
-	res.json(Settings)
-
 profiler = require "v8-profiler"
 app.get "/profile", (req, res) ->
 	time = parseInt(req.query.time || "1000")


Disabled debugger start/stop messages. #203, #218

--- lib/node-debugger.coffee
+++ lib/node-debugger.coffee
@@ -37,9 +37,9 @@
     @disposables = new CompositeDisposable()
     _debugger = new Debugger(atom)
     @disposables.add _debugger.subscribeDisposable 'connected', ->
-      atom.notifications.addSuccess('connected, enjoy debugging : )')
+      #atom.notifications.addSuccess('connected, enjoy debugging : )')
     @disposables.add _debugger.subscribeDisposable 'disconnected', ->
-      atom.notifications.addInfo('finish debugging : )')
+      #atom.notifications.addInfo('finish debugging : )')
     @disposables.add atom.commands.add('atom-workspace', {
       'node-debugger:start-resume': @startOrResume
       'node-debugger:start-active-file': @startActiveFile


Remove excess code

Remove excess code

--- lib/notifications.coffee
+++ lib/notifications.coffee
@@ -411,9 +411,6 @@
   linkTag = (text, tag, group) ->
     "#{text}"

-  linkToTags = (group, tags, html) ->
-    (linkToTag(group, tag.key, html) for tag in sortTags tags).join(', ') or '(none)'
-
   notificationEmail = (notifications) ->
     return unless notifications.length > 0
     user = findUsername notifications[0].to


Update Dutch Translations

Update Dutch Translations

While using the app I noticed some translations were not in context or inline with WordPress translations. Changed those!

--- lib/translations/nl.cson
+++ lib/translations/nl.cson
@@ -12,15 +12,15 @@
     "home": "Home"
     "tags": "Tags"
     "pages": "Pagina's"
-    "posts": "Posts"
+    "posts": "Berichten"
     "authors": "Auteurs"
     "search": "Zoeken"
     "bookmarks": "bladwijzers"
     "socialNetworks": "Sociale netwerken"
     "categories": "Categorieën"
     "settings": "Instellingen"
-    "customPosts": "Eigen posts"
-    "customTaxonomy": "Eigen taxanomie"
+    "customPosts": "Aangepaste berichten"
+    "customTaxonomy": "Aangepaste taxanomie"
 "pushNotifications":
     "newContent":
         "title": "Nieuwe inhoud!"
@@ -55,7 +55,7 @@
 "pages":
     "title": "Pagina's"
 "posts":
-    "title": "Posts"
+    "title": "Berichten"
     "featured": "Uitgelicht"
 "post":
     "comments": "Reactie's"
@@ -65,9 +65,9 @@
 "params":
     "title": "Instellingen"
     "offlineMode": "Offline mode (binnenkort)"
-    "fontSize": "Post lettertype grootte"
+    "fontSize": "Lettertype grootte"
     "language": "Taal"
-    "pushNotifications": "Push meldingen"
+    "pushNotifications": "Push berichten"
 "languages":
     "en": "Engels"
     "fr": "Frans"


Replaced deprecated .on 'changed' with .onDidChange

--- lib/vendor/dialog.coffee
+++ lib/vendor/dialog.coffee
@@ -15,7 +15,7 @@
     @on 'core:confirm', => @onConfirm(@miniEditor.getText())
     @on 'core:cancel', => @cancel()

-    @miniEditor.getEditor().getBuffer().on 'changed', => @showError()
+    @miniEditor.getEditor().getBuffer().onDidChange => @showError()

     @miniEditor.setText(initialText)


smart URLs seems to work

smart URLs seems to work

--- vpn.coffee
+++ vpn.coffee
@@ -15,7 +15,24 @@
 Router.route "/driver_lines/:_id/:name?",
   name: "driver_line_show"
   action: ->
-    @render "driver_line_show"
+    using_canonical_name=false
+    doc = DriverLines.findOne _id: @params._id
+    if @params.name?
+      if doc? and @params.name == doc.name
+        using_canonical_name = true
+
+    if doc?
+      if using_canonical_name
+        @render "driver_line_show"
+      else
+        @redirect( "driver_line_show", {_id:@params._id,name:doc.name} )
+    else
+      # The _id is not in the database. Should maybe do a 404. For
+      # now, render with blank data.
+      # FIXME in the future (See
+      # https://github.com/EventedMind/iron-router/issues/237 )
+      @render "PageNotFound"
+
   data: ->
     DriverLines.findOne _id: @params._id

@@ -78,7 +95,7 @@
 @remove_binary_data = (my_id) ->
   rnt = (doc) ->
     index = doc[@field_name].indexOf(@my_id)
-
+
     # No need to check for index==-1 because we know it does not (except race condition).
     doc[@field_name].splice index, 1
     t2 = {}
@@ -96,7 +113,7 @@
     field_name: field_name

   doc = BinaryData.findOne(my_id)
-
+
   S3.delete doc.relative_url
   BinaryData.remove my_id
   return
@@ -104,7 +121,7 @@
 @remove_neuron_type = (my_id) ->
   rnt = (doc) ->
     index = doc.neuron_types.indexOf(@my_id)
-
+
     # No need to check for index==-1 because we know it does not (except race condition).
     doc.neuron_types.splice index, 1
     @coll.update doc._id,
@@ -122,7 +139,7 @@
 @remove_neuropil = (my_id) ->
   rn = (doc) ->
     index = doc.neuropils.indexOf(@my_id)
-
+
     # No need to check for index==-1 because we know it does not (except race condition).
     doc.neuropils.splice index, 1
     @coll.update doc._id,