Fix description in case of multiple lines that break an inner query/arg

--- admin/static/coffee/dataexplorer.coffee
+++ admin/static/coffee/dataexplorer.coffee
@@ -190,12 +190,14 @@

         line_height: 13

-        show_suggestion: ->
+        show_suggestion: =>
+            console.log @codemirror.getCursor().line
             margin = ((@codemirror.getCursor().line+1)*@line_height) + 'px'
             @.$('.suggestion_full_container').css 'margin-top', margin
             @.$('.suggestion_name_list').css 'display', 'block'

         show_suggestion_description: ->
+            console.log @codemirror.getCursor().line
             margin = ((@codemirror.getCursor().line+1)*@line_height) + 'px'
             @.$('.suggestion_full_container').css 'margin-top', margin
             @.$('.suggestion_description').css 'display', 'block'
@@ -326,6 +328,8 @@

         add_description: (fn) =>
             if @descriptions[fn]?
+                margin = ((@codemirror.getCursor().line+1)*@line_height) + 'px'
+                @.$('.suggestion_full_container').css 'margin-top', margin
                 @.$('.suggestion_description').html @descriptions[fn]
                 @.$('.suggestion_description').css 'display', 'block'


nicer code

nicer code

--- lib/util/tooltip.coffee
+++ lib/util/tooltip.coffee
@@ -95,9 +95,9 @@

   positionOverlay: ->
     bounding = @parent.getBoundingClientRect()
-    @view.style.bottom   = document.documentElement.clientHeight - bounding.top + 'px'
-    switch @position
+    @view.style.bottom = document.documentElement.clientHeight - bounding.top + 'px'
+    @view.style.left = switch @position
       when 'left'
-        @view.style.left = bounding.left + 'px'
+        bounding.left + 'px'
       when 'right'
-        @view.style.left = bounding.left + bounding.width -  @view.offsetWidth + 'px'
+        bounding.left + bounding.width - @view.offsetWidth + 'px'


Yet another typo

Yet another typo

--- server/serversystem/manager.coffee
+++ server/serversystem/manager.coffee
@@ -32,7 +32,7 @@
        if sock?
           console.log "told server "+serv._id+" to kill instance "+alob.id
           sock.send "shutdownServer|"+alob.id
-    if alob.status is 2
+    if lob.status is 2
       lobbies.remove({_id: id})
   else
     lobbies.remove {_id: id}


Fixed swimlane javascript

Fixed swimlane javascript

--- app/assets/javascripts/swimlanes.coffee
+++ app/assets/javascripts/swimlanes.coffee
@@ -36,9 +36,7 @@
                 return
             connectWith: '.connectedSortable'
             revert: true).disableSelection()
-        return
-
-
+
         $( '#add' ).validate
             rules:
                 name:
@@ -63,7 +61,7 @@
                 else
                     error.insertAfter element
                 return
-
+
         $("#add").submit (e) ->
           url = "/api/issues"
           console.log $("#add").serialize()
@@ -75,7 +73,7 @@
             success: (data) ->
               #$("#projects-row").append(generateProjectCard(data.name, data.description, '#', '#', '#'))
               $("#swimlane_" + data.status_id).append($("<li class = 'ui-state-default'>").append(generateIssueCard(data.name,data.description,data.category,data.story_points,data.id)))
-              $("#addModal").modal('close');
+              $("#swimlaneModal").modal('close');
               return
             error: (req, msg, stat) ->
               console.log(req)
@@ -86,7 +84,6 @@
               # $("#errorMsg").html(errorsHTML)
               return
           e.preventDefault()
-
           return
         return
 this.app.swimlanes = new SwimlanesController


:new: Make exePath a config

:new: Make exePath a config


DevTools: Updated Firebase instance name.

--- client/DevTools/AppView.coffee
+++ client/DevTools/AppView.coffee
@@ -48,7 +48,7 @@
     @addSubView @workspace      = new CollaborativeWorkspace
       name                      : "Koding DevTools"
       delegate                  : this
-      firebaseInstance          : "tw-local"
+      firebaseInstance          : "koding-dev-tools"
       panels                    : [
         title                   : "Koding DevTools"
         layout                  :


another fix for dataset page

another fix for dataset page

--- client/code/router/main.coffee
+++ client/code/router/main.coffee
@@ -83,6 +83,7 @@
         @subnavView.showView subnavView

   dataset: (box) ->
+    doNotNavigate = false
     model = Cu.Model.Dataset.findOrCreate box: box, merge: true
     toolsDone = app.tools().fetch()
     modelDone = model.fetch()
@@ -98,9 +99,18 @@
           contentView = new Cu.View.PluginContent {model: dataTablesView}
           @appView.showView contentView
         else
-          app.navigate "/dataset/#{model.id}/settings", trigger: true
+          views.once 'update:tool', =>
+            doNotNavigate = true
+            views.findByToolName 'datatables-view-tool', (dataTablesView) =>
+              subnavView = new Cu.View.DatasetNav {model: model, view: dataTablesView}
+              @subnavView.showView subnavView
+              contentView = new Cu.View.PluginContent {model: dataTablesView}
+              @appView.showView contentView

-
+          setTimeout ->
+            unless doNotNavigate
+              app.navigate "/dataset/#{model.id}/settings", trigger: true
+          , 200

   datasetSettings: (box) ->
     mod = Cu.Model.Dataset.findOrCreate box: box


Update pl.coffee

Update pl.coffee

--- app/locale/pl.coffee
+++ app/locale/pl.coffee
@@ -21,28 +21,28 @@
     accessible_to: "Dostępne dla"
     everyone: "każdego"
     democratizing: "Powszechny dostęp do nauki programowania jest podstawą naszej filozofii. Każdy powinien nauczyć się programować."
-    forgot_learning: "Moi uczniowie tak się zaangażowali, aż zapomnieli że właśnie uczą się programowania."
-    wanted_to_do: " Zawsze chciałem nauczyć się programowania, nie sądziłem że będę mógł nauczyć się tego w szkole."
+    forgot_learning: "Moi uczniowie tak bardzo wciągneli się w grę, aż zapomnieli że właśnie uczą się programowania."
+    wanted_to_do: " Zawsze chciałem nauczyć się programowania, nie sądziłem że uda mi się to w szkole."
     why_games: "Dlaczego nauka przez gry jest tak ważna?"
     games_reward: "Gry wynagradzają rozwiązywanie prawdziwych problemów."
     encourage: "Gry są medium, które zachęca do interakcji oraz odkrywania metodą prób i błędów. Dobra gra potrafi zachęcić gracza do rozwijania swoich umiejętności, co jest takim samym krytycznym procesem jak podczas nauki."
     excel: "Gry celują w wynagradzanie"
     struggle: "rozwiązania prawdziwych wyzwań"
     kind_of_struggle: " takich których wynikiem w procesie nauczania jest zaangażowanie oraz"
-    motivating: "motywacja"
+    motivating: "motywacja,"
     not_tedious: "nie trud."
     gaming_is_good: "Wyniki badań sugerują pozytywny wpływ gier na stymulację procesów myślowych dzieci."
     game_based: "Kiedy "
     compared: "porównamy"
-    conventional: "system nauczania oparty na grze z tradycyjnym, różnica jest wyraźna: dzięki grom uczniowie dłużej pamiętają, lepiej się koncentrują "
+    conventional: "system nauczania oparty na grze z tradycyjnym, różnica jest wyraźna: dzięki grom uczniowie szybciej zapamiętują, lepiej się koncentrują, "
     perform_at_higher_level: "oraz osiągają lepsze wyniki."
     feedback: "Gry dostarczają także natychmiastową informację zwrotną, która pozwala uczniom dostosować ich rozwiązanie i zrozumieć pomysł całościowo, zamiast być ograniczonym tylko do odpowiedzi dobrze albo źle."
-    real_game: "Prawdziwa gra z prawdziwym kodowaniem."
-    great_game: "Dobra gra to coś więcej niż tylko odznaki czy osiągnięcia - to podróż, dobrze dobrane zagadki i możliwość sprostania wyzwaniom samodzielnie z uczuciem pewności."
-    agency: "CodeCombat jest grą, która daje graczom tą samodzielność i pewność, to dzięki naszemu silnikowi pisania kodu, który pomaga zarówno początkującym jak i zaawansowanym uczniom pisać poprawny kod."
+    real_game: "Gra, w której piszesz prawdziwy kod."
+    great_game: "Dobra gra to coś więcej niż tylko odznaki czy osiągnięcia - to podróż, dobrze dobrane zagadki i możliwość samodzielnego sprostania nawet najtrudniejszym wyzwaniom."
+    agency: "CodeCombat jest grą, która daje graczom tą samodzielność i pewność, żę uda im się rozwiązać zadanie. Wszystko to dzięki naszemu silnikowi pisania kodu, który pomaga zarówno początkującym jak i zaawansowanym uczniom pisać poprawny kod."
     request_demo_title: "Namów swoich uczniów już dziś!"
     request_demo_subtitle: "Zamów wersję demo i pozwól swoim uczniom zacząć w mniej niż godzinę."
-    get_started_title: "Utwórz swoją klasę już dziś"
+    get_started_title: "Załóż swoją klasę już dziś"
     get_started_subtitle: "Przygotuj klasę, dodaj uczniów i śledź ich postęp w nauce."
     request_demo: "Zapytaj o wersję demo"
     setup_a_class: "Przygotuj klasę"
@@ -528,13 +528,13 @@
     tip_premature_optimization: "Przedwczesna optymalizacja jest źródłem wszelkiego zła. - Donald Knuth"
     tip_brute_force: "Masz jakieś wątpliwości? Użyj techniki brute force. - Ken Thompson"
     tip_extrapolation: "Są dwa typy ludzi: ci, co potrafią ekstrapolować z niepełnych danych..."
-#    tip_superpower: "Coding is the closest thing we have to a superpower."
-#    tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds"
+    tip_superpower: "Umieć programować jest rzeczą bardzo podobną do posiadania super mocy."
+    tip_control_destiny: "W prawdziwym Open Source, to ty kontrolujesz swoje przeznaczenie. - Linus Torvalds"
     tip_no_code: "Nie ma szybszego kodu od braku kodu"
     tip_code_never_lies: "Kod nigdy nie kłamie, komentarze czasami tak. — Ron Jeffries"
     tip_reusable_software: "Zanim kod stanie się reużywalny musi zacząć działać."
     tip_optimization_operator: "Każdy język programowania ma operator optymalizujący. W większości z nich tym operatorem jest ‘//’"
-#    tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates"
+    tip_lines_of_code: "Mierzenie postępu programowania liniami kodu jest jak mierzenie postępu budowy samolotu za pomocą ciężaru. — Bill Gates"
     tip_source_code: "Chciałbym zmienić świat, ale nie chcą mi dać kodu źródłowego."
     tip_javascript_java: "Java jest tak podobna do JavaScriptu jak minister do ministranta"
     tip_move_forward: "Nie ważne co robisz. Ważne, że przesz do przodu. - Martin Luther King Jr."
@@ -542,22 +542,22 @@
     tip_adding_evil: "Dodajemy szczyptę zła."
     tip_hate_computers: "To jest właśnie problem z ludźmi, którzy nie nawidzą komputerów. Tak naprawdę nie nawidzą kiepskich programistów. - Larry Niven"
     tip_open_source_contribute: "Możesz pomóc w ulepszeniu CodeCombat!"
-#    tip_recurse: "To iterate is human, to recurse divine. - L. Peter Deutsch"
+    tip_recurse: "Iteracja jest rzeczą ludzką, rekursja boską. - L. Peter Deutsch"
     tip_free_your_mind: "Musisz to wszystko zostawić, Neo. Strach, wątpliwość i niewiarę. Uwolnij swój umysł. - Morfeusz"
     tip_strong_opponents: "Nawet najsilniejsi przeciwnicy mają słabe punkty. - Itachi Uchiha"
     tip_paper_and_pen: "Przed rozpoczęciem kodowania zawsze dobrze jest wziąć kartkę papieru i wszystko dobrze rozplanować."
     tip_solve_then_write: "Najpierw rozwiąż problem, a potem napisz kod. - John Johnson"
     tip_compiler_ignores_comments: "Czasami mi się wydaje, że kompilator ignoruje moje komentarze."
     tip_understand_recursion: "Żeby zrozumieć rekurencję, trzeba najpierw zrozumieć rekurencję."
-#    tip_life_and_polymorphism: "Open Source is like a totally polymorphic heterogeneous structure: All types are welcome."
+    tip_life_and_polymorphism: "Open Source jest jak całkowicie polimorficzna, heterogeniczna struktura: Wszystkie typy są mile widziane."
     tip_mistakes_proof_of_trying: "Błędy w twoich kodzie są oznaką, że się starasz."
     tip_adding_orgres: "Zaokrąglanie ogrów."
     tip_sharpening_swords: "Ostrzymy miecze."
     tip_ratatouille: "Nigdy nie pozwólcie, aby ograniczało was to, kim jesteście. Duch nie zna granic. - Gusteau, Ratatuj"
     tip_nemo: "Wiesz co się robi jak życie dołuje? Mówi się trudno... i płynie się dalej. - Dory, Gdzie jest Nemo"
-#    tip_internet_weather: "Just move to the internet, it's great here. We get to live inside where the weather is always awesome. - John Green"
-#    tip_nerds: "Nerds are allowed to love stuff, like jump-up-and-down-in-the-chair-can't-control-yourself love it. - John Green"
-#    tip_self_taught: "I taught myself 90% of what I've learned. And that's normal! - Hank Green"
+    tip_internet_weather: "Przenieś się do internetu, jest tu wspaniale. Żyjemy w miejscu, gdzie pogoda jest zawsze super. - John Green"
+    tip_nerds: "Maniaki komputerowe mają prawo robić różne dziwne rzeczy, takie jak skaczę-z-radości-na-krześle-i-nie-mogę-przestać, kocham to. - John Green"
+    tip_self_taught: "Nauczyłem się 90% tego co się dowiedziałem. I jest to całkowicie normalne! - Hank Green"
     tip_luna_lovegood: "Nie przejmuj się. Jesteś tak samo zdrowy na umyśle jak ja. - Luna Lovegood"
     tip_good_idea: "Najlepszym sposobem na dobry pomysł jest wiele pomysłów. - Linus Pauling"
     tip_programming_not_about_computers: "Informatyka ma tyle samo wspólnego z komputerami, co astronomia ma z teleskopami. - Edsger Dijkstra"
@@ -668,7 +668,7 @@
     sale_button_title: "Zaoszczędź $21 kupując roczną subskrypcję"
     stripe_description: "Miesięczna subskrypcja"
     stripe_description_year_sale: "Roczna subskrypcja (zniżka ${{discount}})"
-    subscription_required_to_play: "Do zagrania w ten poziom wymagana jest subskrypcja."
+    subscription_required_to_play: "Żeby zagrać w ten poziom musisz posiadać subskrypcję."
     unlock_help_videos: "Subskrybuj, aby odblokować wszystkie wideo tutoriale."
     personal_sub: "Osobista subskrypcja" # Accounts Subscription View below
     loading_info: "Wczytywanie informacji o subskrypcji..."
@@ -677,16 +677,16 @@
     currently_free: "Obecnie posiadasz darmową subskrypcję"
     currently_free_until: "Twoja obecna subskrypcja wygaśnie"
     was_free_until: "Twoja obecna darmowa subskrypcja wygaśnie"
-    managed_subs: "Managed Subscriptions"
+#    managed_subs: "Managed Subscriptions"
     subscribing: "Zapisywanie do subskrypcji..."
     current_recipients: "Obecni odbiorcy"
     unsubscribing: "Anulowanie subskrypcji"
     subscribe_prepaid: "Kliknij `Zapisz się`, aby użyć kodu prepaid"
     using_prepaid: "Używasz kodu prepaid dla miesięcznych subskrypcji"
-    feature_levels: "Dostęp do __premiumLevelsCount__ bonusowych poziomów"
-    feature_gems: "Co miesiąc dostajesz __gems__ klejnotów"
-    feature_heroes: "Dostęp do ekskluzywnych bohaterów"
-    feature_games: "Tworzenie gier dla swoich przyjaciół"
+    feature_levels: "__premiumLevelsCount__ bonusowych poziomów"
+    feature_gems: "__gems__ klejnotów co miesiąc"
+    feature_heroes: "Ekskluzywni bohaterowie"
+    feature_games: "Tworzenie gier dla znajomych"
     feature_websites: "Tworzenie stron i aplikacji"
     feature_items: "Założysz potężniejsze przedmioty"
     month_price: "$__price__/miesiąc"
@@ -694,30 +694,30 @@
     lifetime_price: "$__price__"
     year_subscription: "Roczna subskrypcja"
     year_price: "$__price__/rok"
-    kids_message_1: "Dzieciaki! Wyślemy emaila do Waszych rodziców z prośbą o wykupienie Wam subskrypcji."
+    kids_message_1: "Wyślemy emaila do Waszych rodziców z prośbą o wykupienie Wam subskrypcji."
     kids_message_2: "Zapytaj rodzica"
-    support_part1: "Potrzebujesz pomocy? Wyślij emaila do"
+    support_part1: "Potrzebujesz pomocy? Jeśli masz jakieś pytania, to napisz do nas na"
     support_part2: "support@codecombat.com"
-    support_part3: "jak masz pytania."
+    support_part3: "."

   announcement:
     cuddly_companions: "Milusi towarzysze!"
-#    kindling_name: "Kindling Elemental"
-#    kindling_description: "Kindling Elementals just want to keep you warm at night. And during the day. All the time, really."
+    kindling_name: "Żywioł Ognia"
+    kindling_description: "Żywioły ognia chcą tylko, żeby było ci ciepło w nocy. I za dnia. W sumie, to cały czas."
     griffin_name: "Mały Gryf"
     griffin_description: "Gryfy to pół orły, pół lwy. Czyż nie są urocze?"
     raven_name: "Kruk"
     raven_description: "Kruki doskonale radzą sobie w przynoszeniu błyszczących buteleczek z lekarstwami."
-    mimic_name: "Mim"
-#    mimic_description: "Mimics can pick up coins for you. Move them on top of coins to increase your gold supply."
+    mimic_name: "Mimik"
+    mimic_description: "Mimiki pomagają w zbieraniu monet za ciebie. Przemieść je na monetę, aby zwiększyć zapasy złota."
     cougar_name: "Puma"
 #    cougar_description: "Cougars like to earn a PhD by Purring Happily Daily."
     fox_name: "Niebieski Lis"
     fox_description: "Niebieskie lisy są bardzo cwane, uwielbiają też kopać dziury w piachu i śniegu!"
-#    pugicorn_name: "Pugicorn"
-#    pugicorn_description: "Pugicorns are some of the rarest creatures and can cast spells!"
+    pugicorn_name: "Piesorożec"
+    pugicorn_description: "Piesorożce to jedne z najrzadszych stworzeń, oraz potrafią rzucać czary!"
     wolf_name: "Szczenię Wilka"
-#    wolf_description: "Wolf pups excel in hunting, gathering, and playing a mean game of hide-and-seek!"
+    wolf_description: "Szczenię wilka jest znakomite w polowaniu i zbieraniu, uwielbia też grę w chowanego!"
     ball_name: "Czerwona piszcząca piła"
     ball_description: "piłka.zapiszcz()"
     collect_pets: "Zdobywaj zwierzaki dla swoich bohaterów!"
@@ -740,8 +740,8 @@
     pet_blurb_1: "Zwierzaki nie są tylko uroczymi towarzyszami, zapewniają także unikatowe umiejętności. Mały Gryf może przelatywać nad przeszkodami pomoagając bohaterowi, Szczenię Wilka umie przynosić lekarstwa, a Puma potrafi mówić!"
     pet_blurb_2: "Zbierz wszystkie zwierzaki i poznaj ich unikalne zdolności!"
     pet_caption: "Przygarnij zwierzaka do towarzystwa!"
-#    game_dev_blurb: "Learn game scripting and build new levels to share with your friends! Place the items you want, write code for unit logic and behavior, and see if your friends can beat the level!"
-#    game_dev_caption: "Design your own games to challenge your friends!"
+    game_dev_blurb: "Naucz się pisania gier i stwórz poziomy, którymi później możesz podzielić się ze znajomymi! Umieszczaj jakie chcesz przedmioty, pisz kod, który odpowiedzialny będzie za zachowanie się przeciwników i sprawdź, czy twoim kolegom uda się pokonać twój poziom"
+    game_dev_caption: "Stwórz własne gry i zobacz który z twoich przyjaciół je pokona!"
     everything_in_premium: "Wszystko co dostaniesz wraz z CodeCombat Premium:"
     list_gems: "Co miesiąc będziesz dostawać klejnoty na zakup sprzętu"
     list_levels: "Dostęp do __premiumLevelsCount__, a nawet więcej poziomów"
@@ -749,8 +749,8 @@
     list_game_dev: "Stworzysz grę dla swoich przyjaciół"
     list_web_dev: "Zbudujesz strony internetowe i interaktywne aplikacje"
     list_items: "Będziesz mógł używać zwierzaków"
-#    list_support: "Get Premium support to help you debug tricky code"
-#    list_clans: "Create private clans to invite your friends and compete on a group leaderboard"
+    list_support: "Otrzymasz pomoc w rozwiązywaniu podchwytliwych zadań"
+    list_clans: "Będziesz mógł tworzyć prywatne klany i konkurować z przyjaciółmi"

   choose_hero:
     choose_hero: "Wybierz swojego bohatera"
@@ -862,7 +862,7 @@
     josh_c_title: "Twórca gry"
     josh_c_blurb: "Tworzy nowe gry"
     robin_title: "Menedżer produktu"
-#    robin_blurb: "Ships things"
+    robin_blurb: "Wysyła rzeczy"
     josh_title: "Projektant gier"
     josh_blurb: "Podłoga to lawa"
     phoenix_title: "Programista"
@@ -932,22 +932,22 @@
   special_offer:
     special_offer: "Specjalna oferta"
     project_based_title: "Kursy bazujące na projektach"
-#    project_based_description: "Web and Game Development courses feature shareable final projects."
-#    great_for_clubs_title: "Great for clubs and electives"
-#    great_for_clubs_description: "Teachers can purchase up to __maxQuantityStarterLicenses__ Starter Licenses per year."
-    low_price_title: "Jedynie __starterLicensePrice__ za ucznia"
-#    low_price_description: "Starter Licenses are active for __starterLicenseLengthMonths__ months from purchase."
-#    three_great_courses: "Three great courses included in the Starter License:"
-#    license_limit_description: "Teachers can purchase up to __maxQuantityStarterLicenses__ Starter Licenses. You have already purchased __quantityAlreadyPurchased__. If you need more, contact __supportEmail__. Starter Licenses are valid for __starterLicenseLengthMonths__ months."
-#    student_starter_license: "Student Starter License"
-#    purchase_starter_licenses: "Purchase Starter Licenses"
-#    purchase_starter_licenses_to_grant: "Purchase Starter Licenses to grant access to __starterLicenseCourseList__"
-#    starter_licenses_can_be_used: "Starter Licenses can be used to assign additional courses immediately after purchase."
+    project_based_description: "Kursy tworzenie gier i stron internetowych dają możliwość podzielenia się gotowym projektem."
+    great_for_clubs_title: "Idelane dla kół i klubów szkolnych"
+    great_for_clubs_description: "Nauczyciele mogą kupić maksymalnie __maxQuantityStarterLicenses__ licencji startowych na rok."
+    low_price_title: "Jedyne __starterLicensePrice__ za ucznia"
+    low_price_description: "Licencje startowe są aktywne przez __starterLicenseLengthMonths__ miesięcy od daty ich zakupu."
+    three_great_courses: "Tzry świetne kursy dostępne w licencji startowej:"
+    license_limit_description: "Nauczyciele mogą kupić aż do __maxQuantityStarterLicenses__ licencji startowych. Ty posiadasz już ich __quantityAlreadyPurchased__. Jeśli potrzebujesz więcej napisz na __supportEmail__. Licencje startowe są ważne przez __starterLicenseLengthMonths__ miesięcy."
+    student_starter_license: "Licencje startowe uczniów"
+    purchase_starter_licenses: "Kup licencje startowe"
+    purchase_starter_licenses_to_grant: "Kup licencję startową, aby uzyskać dostęp do __starterLicenseCourseList__ kursów"
+    starter_licenses_can_be_used: "Licencje startowe mogą być natychmiast użyte do rozdysponowania."
     pay_now: "Zapłać teraz"
     we_accept_all_major_credit_cards: "Akceptujemy większość kart płatniczych."
-#    cs2_description: "builds on the foundation from Introduction to Computer Science, diving into if-statements, functions, events and more."
-#    wd1_description: "introduces the basics of HTML and CSS while teaching skills needed for students to build their first webpage."
-#    gd1_description: "uses syntax students are already familiar with to show them how to build and share their own playable game levels."
+    cs2_description: "najpierw łagodnie zaczyna od podstaw, aby następnie zanurzyć uczniów w instrukcjach warunkowych, funkcjach, zdarzeniach, itp..."
+    wd1_description: "wprowadza w podstawy składni HTML i CSS, oraz uczy jak stworzyć swoją pierwszą stronę internetową."
+    gd1_description: "używa składni, którą uczniowie już znają, aby pokazać im jak stworzyć własny, grywalny poziom w grze."
     see_an_example_project: "zobacz przykładowy projekt"
     get_started_today: "Zacznij dziś!"
     want_all_the_courses: "Chcesz wszytskie kursy? Poproś o informacje o pełnej licencji."
@@ -977,21 +977,21 @@
     phone_number_help: "Jak możemy skontaktować się z tobą w ciągu dnia pracy?"
     primary_role_label: "Twoja główna rola"
     role_default: "Wybierz rolę"
-#    primary_role_default: "Select Primary Role"
-#    purchaser_role_default: "Select Purchaser Role"
+    primary_role_default: "Wybierz kim jesteś"
+    purchaser_role_default: "Rola w zakupie subskrypcji"
     tech_coordinator: "Koordynator technologii"
     advisor: "Specjalista od nauczania/Doradca"
     principal: "Dyrektor"
     superintendent: "Kurator"
     parent: "Rodzic"
-#    purchaser_role_label: "Your Purchaser Role"
-#    influence_advocate: "Influence/Advocate"
-#    evaluate_recommend: "Evaluate/Recommend"
-#    approve_funds: "Approve Funds"
-#    no_purchaser_role: "No role in purchase decisions"
+    purchaser_role_label: "Jaki masz wpływ na zakup"
+    influence_advocate: "Wpływam/Doradzam"
+    evaluate_recommend: "Oceniam/Polecam"
+    approve_funds: "Akceptuje środni Funds"
+    no_purchaser_role: "Brak żadnej roli"
     district_label: "Okręg"
     district_name: "Nazwa okręgu"
-    district_na: "Wprowadź N/A jeżeli nie dotyczy"
+    district_na: "Wprowadź `-` jeśli nie dotyczy"
     organization_label: "Szkoła"
     school_name: "Nazwa szkoły"
     city: "Miasto"
@@ -1017,12 +1017,12 @@
     finish_signup_p: "Create an account to set up a class, add your students, and monitor their progress as they learn computer science."
     signup_with: "Zarejestruj się z:"
     connect_with: "Połącz się z:"
-#    conversion_warning: "WARNING: Your current account is a Student Account. Once you submit this form, your account will be updated to a Teacher Account."
-#    learn_more_modal: "Teacher accounts on CodeCombat have the ability to monitor student progress, assign licenses and manage classrooms. Teacher accounts cannot be a part of a classroom - if you are currently enrolled in a class using this account, you will no longer be able to access it once you update to a Teacher Account."
+    conversion_warning: "UWAGA: Obecnie posiadasz konto ucznia. Po wysłaniu tego formularza zostanie ono zaktualizowane do konta nauczyciela."
+    learn_more_modal: "Konta nauczyciela w CodeCombat mają możliwość monitorowania postępów uczniów, używania licencji i tworzenia klas. Konto nauczyciela nie może być częścią klasy - jeśli jesteś obecnie zapisany do jakiejś klasy, nie będziesz mógł już jej odwiedzać po aktualizacji do konta nauczyciela."
     create_account: "Stwórz konto dla nauczyciela"
     create_account_subtitle: "Uzyskaj wyłączny dostęp do narzędzi pomocnych podczas zajęć. Utwórz swoją klasę, dodaj uczniów i śledź ich postępy!"
     convert_account_title: "Aktualizuj do konta nauczyciela"
-    not: "Nie"
+    not: "Nie jesteś"

   versions:
     save_version_title: "Zapisz nową wersję"
@@ -1255,14 +1255,14 @@
     not_you: "To nie ty?"
     continue_playing: "Kontynuuj grę"
     option1_header: "Zaproś uczniów poprzez email"
-#    option1_body: "Note: If your students do not have email addresses, they can enter your unique Class Code when creating a Student Account to make email addresses optional."
+    option1_body: "Uwaga: Jeśli twoi uczniowie nie posiadają adresu email, mogą wpisać unikalny kod klasy podczas tworzenia konta ucznia, przez co adres email nie będzie już wymagany."
     remove_student1: "Usuń ucznia"
     are_you_sure: "Na pewno chcesz usunąć tego ucznia z klasy?"
-#    remove_description1: "Student will lose access to this classroom and assigned classes. Progress and gameplay is NOT lost, and the student can be added back to the classroom at any time."
-#    remove_description2: "The activated paid license will not be returned."
-    keep_student: "Keep Student"
+    remove_description1: "Uczeń straci dostęp do klasy i przypisanych mu kursów. Postęp w grze natomiast NIE zostanie utracony, uczeń może zostać dołączony do klasy w każdym momencie."
+    remove_description2: "Aktywowana licencja nie zostanie zwrócona."
+    keep_student: "Zachowaj ucznia"
     removing_user: "Usuwanie użytkownika"
-#    subtitle: "Review course overviews and levels" # Flat style redesign
+    subtitle: "Zobacz opisy kursów i poziomy" # Flat style redesign
     changelog: "Pokaż ostatnie zmiany w poziomach kursu."
     select_language: "Wybierz język"
     select_level: "Wybierz poziom"
@@ -1301,23 +1301,23 @@
     update_account_teachers_can2: "Zapisywać/usuwać uczniów z kursów"
     update_account_teachers_can3: "Odblokować wszystkie poziomy kursów do przetestowania"
     update_account_teachers_can4: "Dostęp do funkcji tylko dla nauczyciela w momencie ich udostępnienia przez nas"
-#    update_account_teachers_warning: "Warning: You will be removed from all classes that you have previously joined and will not be able to play as a student."
+    update_account_teachers_warning: "Uwaga: Zostaniesz usunięty ze wszystkich klas, do których wcześniej dołaczyłeś i nie będziesz mógł już grać jako uczeń."
     update_account_remain_teacher: "Pozostań nauczycielem"
     update_account_update_teacher: "Zostań nauczycielem"
     update_account_am_student: "Jestem uczniem"
     update_account_remove_access: "Usuń dostęp do klas, które stworzyłem"
     update_account_students_can: "Konto ucznia może:"
-    update_account_students_can1: "Dołącz do klasy"
-#    update_account_students_can2: "Play through courses as a student and track your own progress"
-#    update_account_students_can3: "Compete against classmates in arenas"
-#    update_account_students_can4: "Access new student-only features as we release them"
+    update_account_students_can1: "Dołączyć do klasy"
+    update_account_students_can2: "Grać w kursach jak uczeń i śledzić swój własny postęp"
+    update_account_students_can3: "Rywalizować z innymi uczniami z klasy w arenach"
+    update_account_students_can4: "Dostęp do funkcji tylko dla uczniów w momencie ich udostępnienia przez nas"
     update_account_students_warning: "Uwaga: Nie będziesz mógł zarządzać klasami, które do tej pory posiadasz, oraz tworzyć nowych."
     update_account_remain_student: "Pozostań uczniem"
     update_account_update_student: "Zostań uczniem"
-#    need_a_class_code: "You'll need a Class Code for the class you're joining:"
+    need_a_class_code: "Wpisz kod klasy do której chcesz dołączyć:"
     update_account_not_sure: "Nie jesteś pewien co masz wybrać? Email"
-#    update_account_confirm_update_student: "Are you sure you want to update your account to a Student experience?"
-#    update_account_confirm_update_student2: "You will not be able to manage any classes that you have previously created or create new classes. Your previously created classes will be removed from CodeCombat and cannot be restored."
+    update_account_confirm_update_student: "Na pewno chcesz zaktualizować swoje konto do konta ucznia?"
+    update_account_confirm_update_student2: "Nie będziesz mógł już zarządzać klasami które posiadasz, oraz tworzyć nowych klas. Twoje obecne klasy zostana usunięte z CodeCombat i nie będzie można ich już przywrócić."
     instructor: "Instruktor: "
     youve_been_invited_1: "Otrzymałeś zaproszenie, do dołaczenia do "
     youve_been_invited_2: ", gdzie nauczysz się "
@@ -1332,13 +1332,13 @@
     select_this_hero: "Wybierz tego bohatera"
     current_hero: "Obecny bohater:"
     change_hero: "Zmień bohatera"
-#    web_dev_language_transition: "All classes program in HTML / JavaScript for this course.  Classes that have been using Python will start with extra JavaScript intro levels to ease the transition.  Classes that are already using JavaScript will skip the intro levels."
-#    course_membership_required_to_play: "You'll need to join a course to play this level."
-#    license_required_to_play: "Ask your teacher to assign a license to you so you can continue to play CodeCombat!"
+    web_dev_language_transition: "Wszystkie klasy będą używać HTML / JavaScript w tym kursie.  Klasy, które wcześniej uczyły sie Pythona, będą miały kilka dodatkowych lekcji z JavaScriptu, aby ułatwić przestawienie się na nowy język.  Klasy, które używały JavaScriptu rozpoczną grę bez tych lekcji."
+    course_membership_required_to_play: "Musisz dołączyć do kursu, aby móc grać w ten poziom."
+    license_required_to_play: "Poproś nauczyciela o przydzielenie ci licencji, abyś mógł kontynuować rozgrywkę w CodeCombat!"

   teacher:
-#    assigning_course: "Assigning course"
-#    course_solution: "Course Solution"
+    assigning_course: "Przydziel kurs"
+    course_solution: "Rozwiązania kursu"
     level_overview_solutions: "Opisy i rozwiązania poziomów"
     no_student_assigned: "Do kursu nie został dołączony żaden uczeń."
     paren_new: "(nowy)"
@@ -1354,10 +1354,10 @@
     teacher_account_required: "Ta strona wymaga dostępu na poziomie nauczyciela."
     create_teacher_account: "Stwórz konto nauczyciela"
     what_is_a_teacher_account: "Co to jest konto nauczyciela?"
-#    teacher_account_explanation: "A CodeCombat Teacher account allows you to set up classrooms, monitor students’ progress as they work through courses, manage licenses and access resources to aid in your curriculum-building."
+    teacher_account_explanation: "Konto nauczyciela w CodeCombat pozwala na stworzenie klasy, monitorowanie postępów uczniów w trakcie kursów, zarządzanie licencjami, oraz dostęp do zasobów pomocnych w budowie programów zajęć."
     current_classes: "Obecne klasy"
     archived_classes: "Zarchiwizowane klasy"
-#    archived_classes_blurb: "Classes can be archived for future reference. Unarchive a class to view it in the Current Classes list again."
+    archived_classes_blurb: "Klasy mogą zostać zarchiwizowane na przyszłe potrzeby. Anuluj archiwizację klasy, aby móc znowu ją przeglądać w widoku klas."
     view_class: "pokaż klasę"
     archive_class: "archiwizuj klasę"
     unarchive_class: "anuluj archiwizację"
@@ -1400,21 +1400,21 @@
     students_not_assigned: "Uczniowie, którzy nie zostali zapisani do {{courseName}}"
     course_overview: "Przegląd kursu"
     copy_class_code: "Kopiuj kod klasy"
-#    class_code_blurb: "Students can join your class using this Class Code. No email address is required when creating a Student account with this Class Code."
+    class_code_blurb: "Uczniowie moga dołaczyc do kasy używając właśnie tego kodu. Podczas tworzenia konta ucznia wystarczy podać ten kod kasy, a dres email nie będzie wymagany."
     copy_class_url: "Kopiuj URL klasy"
-#    class_join_url_blurb: "You can also post this unique class URL to a shared webpage."
+    class_join_url_blurb: "Możesz także umieścić ten unikalny URL klasy na waszej wspólnej stronie."
     add_students_manually: "Zaproś uczniów poprzez email"
-#    bulk_assign: "Bulk-assign"
+    bulk_assign: "Masowe przydzielanie"
     assigned_msg_1: "{{numberAssigned}} uczniów zostało dołączonych do kursu {{courseName}}."
     assigned_msg_2: "{{numberEnrolled}} licencji zostało przypisanych."
     assigned_msg_3: "Posiadasz jeszcze {{remainingSpots}} dostępnych licencji."
     assign_course: "Przypisz kurs"
-#    not_assigned_modal_title: "Courses were not assigned"
-#    not_assigned_modal_starter_body_1: "This course requires a Starter License. You do not have enough Starter Licenses available to assign this course to all __selected__ selected students."
-#    not_assigned_modal_starter_body_2: "Purchase Starter Licenses to grant access to this course."
-#    not_assigned_modal_full_body_1: "This course requires a Full License. You do not have enough Full Licenses available to assign this course to all __selected__ selected students."
-#    not_assigned_modal_full_body_2: "You only have __numFullLicensesAvailable__ Full Licenses available (__numStudentsWithoutFullLicenses__ students do not currently have a Full License active)."
-#    not_assigned_modal_full_body_3: "Please select fewer students, or reach out to __supportEmail__ for assistance."
+    not_assigned_modal_title: "Kurs nie został przypisany"
+    not_assigned_modal_starter_body_1: "Ten kurs wymaga licencji startowej. Nie masz wystarczającej licby licencji startowych, aby je przydzielić do __selected__ zaznaczonych uczniów."
+    not_assigned_modal_starter_body_2: "Kup licencje startowe, aby mieć dostęp do tego kursu."
+    not_assigned_modal_full_body_1: "Ten kurs wymaga pełnej licencji. Nie masz wystarczającej liczby pełnych licencji, aby je przydzielić do __selected__ zaznaczonych uczniów."
+    not_assigned_modal_full_body_2: "Posiadasz jedynie __numFullLicensesAvailable__ dostępnych pełnych licencji (__numStudentsWithoutFullLicenses__ uczniów nie posiada obecnie aktywnej pełnej licencji)."
+    not_assigned_modal_full_body_3: "Proszę wybrać mniej uczniów, albo wyślij wiadomość na __supportEmail__ po poradę."
     assign_to_selected_students: "Przypisz do zaznaczonych uczniów"
     assigned: "Przypisany"
     enroll_selected_students: "Zapisz wybranych uczniów"
@@ -1442,8 +1442,8 @@
     end_date: "data zakonczenia:"
 #    get_enrollments_blurb: " We'll help you build a solution that meets the needs of your class, school or district."
 #    how_to_apply_licenses_blurb_1: "When a teacher assigns a course to a student for the first time, we’ll automatically apply a license. Use the bulk-assign dropdown in your classroom to assign a course to selected students:"
-#    how_to_apply_licenses_blurb_2: "Can I still apply a license without assigning a course?"
-#    how_to_apply_licenses_blurb_3: "Yes — go to the License Status tab in your classroom and click \"Apply License\" to any student who does not have an active license."
+    how_to_apply_licenses_blurb_2: "Mogę zastosować licencję, bez przydzielania kursu?"
+    how_to_apply_licenses_blurb_3: "Tak — przejdź do sekcji \"Status licencji\" w swojej klasie, a następnie kliknij na \"Zastosuj licencję\", aby przydzielić ja uczniowi, który jej jeszcze nie posiada."
     request_sent: "Wysłano prośbę!"
     license_status: "Status licencji"
     status_expired: "Licencja wygasła {{date}}"
@@ -1458,9 +1458,9 @@
     educator_faq: "FAQ dla nauczycieli"
     educator_faq_desc: "Najczęściej zadawane pytania odnośnie korzystania z CodeCombat w twojej klasie lub szkole."
     teacher_getting_started: "Przewodnik dla nauczyciela"
-#    teacher_getting_started_desc: "New to CodeCombat? Download this Teacher Getting Started Guide to set up your account, create your first class, and invite students to the first course."
+    teacher_getting_started_desc: "Nowy w CodeCombat? Pobierz ten `Przewodnik dla nauczyciela`. Z jego pomocą założysz konto, stworzysz swoją pierwszą klasę, oraz zaprosisz swoich uczniów do udziału w kursach."
     student_getting_started: "Przewodnik dla ucznia"
-#    student_getting_started_desc: "You can distribute this guide to your students before starting CodeCombat so that they can familiarize themselves with the code editor. This guide can be used for both Python and JavaScript classrooms."
+    student_getting_started_desc: "Możesz rozdać ten przewodnik uczniom zanim zaczną naukę w CodeCombat, aby mogli zapoznać się z edytorem kodu. Przewodnik ten może znaleźć zastosowanie zarówno dla języka Python, jak i JavaScript."
     cs1: "Wprowadzenie do informatyki"
     cs2: "Informatyka 2"
     cs3: "Informatyka 3"


Edit last message working

Edit last message working

--- client/lib/chatMessages.coffee
+++ client/lib/chatMessages.coffee
@@ -61,7 +61,7 @@
 		self.typingTimeout = null

 	startEditingLastMessage = (rid, imput) ->
-		lastMessage = ChatMessage.findOne { rid: rid, t: {$exists: false}, uid: Meteor.userId() }, { sort: { ts: -1 } }
+		lastMessage = ChatMessage.findOne { rid: rid, t: {$exists: false}, 'u._id': Meteor.userId() }, { sort: { ts: -1 } }
 		if not lastMessage?
 			return


Update pl.coffee

Update pl.coffee

--- app/locale/pl.coffee
+++ app/locale/pl.coffee
@@ -151,9 +151,9 @@
     campaign_multiplayer: "Kampania dla wielu graczy"
     campaign_multiplayer_description: "... w której konkurujesz z innymi graczami."
     brain_pop_done: "Pokonałeś ogry kodem! Wygrałeś!"
-#    brain_pop_challenge: "Challenge yourself to play again using a different programming language!"
-#    replay: "Replay"
-#    back_to_classroom: "Back to Classroom"
+    brain_pop_challenge: "Zmierz się ponownie z zagadkami, tym razem wybierając inny język programowania!"
+    replay: "Graj od nowa"
+    back_to_classroom: "Wróć do klasy"

   code:
     if: "jeżeli" # Keywords--these translations show up on hover, so please translate them all, even if it's kind of long. (In the code editor, they will still be in English.)
@@ -631,9 +631,9 @@
     purchase: "Kup"
     purchased: "Zakupiono"

-#  earn_gems:
-#    prompt_title: "Not Enough Gems"
-#    prompt_body: "Keep playing to earn more!"
+  earn_gems:
+    prompt_title: "Za mało klejnotów"
+    prompt_body: "Graj dalej, a zdobędziesz ich więcej!"

   subscribe:
     subscribe_modal_title: "CodeCombat Premium"
@@ -683,9 +683,9 @@
     will_be_cancelled: "Zostanie anulowana"
     currently_free: "Obecnie posiadasz darmową subskrypcję"
     currently_free_until: "Twoja obecna subskrypcja wygaśnie"
-#    free_subscription: "Free subscription"
+    free_subscription: "Darmowa subskrypcja"
     was_free_until: "Twoja obecna darmowa subskrypcja wygaśnie"
-#    managed_subs: "Managed Subscriptions"
+    managed_subs: "Zarządzane subskrypcje"
     subscribing: "Zapisywanie do subskrypcji..."
     current_recipients: "Obecni odbiorcy"
     unsubscribing: "Anulowanie subskrypcji"
@@ -719,7 +719,7 @@
     mimic_name: "Mimik"
     mimic_description: "Mimiki pomagają w zbieraniu monet za ciebie. Przemieść je na monetę, aby zwiększyć zapasy złota."
     cougar_name: "Puma"
-#    cougar_description: "Cougars like to earn a PhD by Purring Happily Daily."
+    cougar_description: "Pumy uwielbiają wylegiwać się na słońcu."
     fox_name: "Niebieski Lis"
     fox_description: "Niebieskie lisy są bardzo cwane, uwielbiają też kopać dziury w piachu i śniegu!"
     pugicorn_name: "Piesorożec"
@@ -1320,7 +1320,7 @@
     update_account_students_can3: "Rywalizować z innymi uczniami z klasy w arenach"
     update_account_students_can4: "Dostęp do funkcji tylko dla uczniów w momencie ich udostępnienia przez nas"
     update_account_students_warning: "Uwaga: Nie będziesz mógł zarządzać klasami, które do tej pory posiadasz, oraz tworzyć nowych."
-#    unsubscribe_warning: "Warning: You will be unsubscribed from your monthly subscription."
+    unsubscribe_warning: "Uwaga: Twoja miesięczna subskrypcja zostanie anulowana."
     update_account_remain_student: "Pozostań uczniem"
     update_account_update_student: "Zostań uczniem"
     need_a_class_code: "Wpisz kod klasy do której chcesz dołączyć:"
@@ -1434,7 +1434,7 @@
     all_students: "Wszyscy uczniowie"
     apply_licenses: "Zastosuj licencje"
     not_enough_enrollments: "Brak wsytarczającej liczby licencji."
-#    enrollments_blurb: "Students are required to have a license to access any content after the first course."
+    enrollments_blurb: "Uczniowie potrzebują licencji, aby móc kontynuować naukę po pierwszym kursie."
     how_to_apply_licenses: "Jak zastosować licencję"
     export_student_progress: "Eksport postępu studentów (do CSV)"
     send_email_to: "Wyślij email do odzyskiwania hasła do:"
@@ -2034,7 +2034,7 @@
     boolean_and: "Boolowski 'and'"
     boolean_equality: "Boolowska równość"
     boolean_greater_less: "Boolowski większy/mniejszy"
-#    boolean_logic_shortcircuit: "Boolean Logic Shortcircuiting"
+    boolean_logic_shortcircuit: "Skróty w logice boole'a"
     boolean_not: "Boolowski 'not'"
     boolean_operator_precedence: "Boolowskie pierwszeństwo operatorów"
     boolean_or: "Boolowski 'or'"
@@ -2234,14 +2234,14 @@
     email_taken: "Email jest już w użyciu"
     username_taken: "Nazwa użytkownika jest już w użyciu"

-#  esper:
-#    line_no: "Line $1: "
-#    x_not_a_function: "`$1` is not a function"
-#    type_error: "TypeError: "
-#    reference_error: "ReferenceError: "
-#    spelling_issues: "Look out for spelling issues: did you mean `$1` instead of `$2`?"
-#    capitalization_issues: "Look out for capitalization: `$1` should be `$2`."
-#    py_empty_block: "Empty $1. Put 4 spaces in front of statements inside the $2."
-#    fx_missing_paren: "If you want to call `$1` as function, you need `()`'s"
-#    unmatched_token: "Unmatched `$1`.  Every opening `$2` needs a closing `$3` to match it."
-#    unterminated_string: "Unterminated string. Add a matching `\"` at the end of your string."
+  esper:
+    line_no: "Wiersz $1: "
+    x_not_a_function: "`$1` nie jest funkcją"
+    type_error: "TypeError (błąd typu): "
+    reference_error: "ReferenceError (błąd referencji): "
+    spelling_issues: "Sprawdź dobrze pisownię: może chodziło ci o `$1` zamiast `$2`?"
+    capitalization_issues: "Uważaj na duże i małe litery: `$1` powinno wyglądać tak: `$2`."
+    py_empty_block: "Pusty $1. Wstaw 4 spacje przed instrukcją wewnątrz $2."
+    fx_missing_paren: "Jeśli chcesz wywołać `$1` jako funkcję, powinieneś użyć `()`"
+    unmatched_token: "Nawias `$1` nie ma pary.  Każdy otwierający nawias `$2` powinien posiadać jego zamykający odpowiednik `$3`."
+    unterminated_string: "Ciąg znaków nie ma końca. Umieść odpowiedni znak `\"` na końcu swojego ciągu znaków."


update courses section

update courses section

--- app/locale/ru.coffee
+++ app/locale/ru.coffee
@@ -31,7 +31,7 @@
     contact: "Связаться"
     twitter_follow: "Подписаться"
     teachers: "Учителям"
-#    careers: "Careers"
+    careers: "Карьера"

   modal:
     close: "Закрыть"
@@ -411,7 +411,7 @@
     feature7: "Частные Кланы"
     free: "Бесплатно"
     month: "месяц"
-#    must_be_logged: "You must be logged in first. Please create an account or log in from the menu above."
+    must_be_logged: "Вы должны быть залогинены. Вы можете создать аккаунт или зайти в созданный с помощью меню выше."
     subscribe_title: "Подпишись"
     unsubscribe: "Отписаться"
     confirm_unsubscribe: "Подтвердить отмену подписки"
@@ -528,8 +528,8 @@
   skill_docs:
     writable: "доступно для записи" # Hover over "attack" in Your Skills while playing a level to see most of this
     read_only: "только чтение"
-#    action: "Action"
-#    spell: "Spell"
+    action: "Действие"
+    spell: "Заклинание"
     action_name: "имя"
     action_cooldown: "Применяется"
     action_specific_cooldown: "Восстановление"
@@ -614,7 +614,7 @@
     free_1: "В наличии более 80 БЕСПЛАТНЫХ уровней, которые покрывают каждый концепт." # {change}
     free_2: "Месячная подписка предоставляет доступ к видео-урокам и дополнительным уровням."
     teacher_subs_title: "Учителя получают бесплатные подписки!"
-#    teacher_subs_0: "We offer free subscriptions to teachers for evaluation purposes."
+    teacher_subs_0: "Мы предлагаем бесплатную подписку для тестирования студентов."
     teacher_subs_1: "Пожалуйста, заполните нашу"
     teacher_subs_2: "Анкету учителя"
     teacher_subs_3: "для настройки вашей подписки."
@@ -843,89 +843,89 @@
     last_played: "Последняя игра"
     leagues_explanation: "Играйте в лиге против других членов клана на мультиплеерной арене."

-#  courses:
-#    course: "Course"
-#    courses: "courses"
-#    not_enrolled: "You are not enrolled in this course."
-#    visit_pref: "Please visit the"
-#    visit_suf: "page to enroll."
-#    select_class: "Select one of your classes"
-#    unnamed: "*unnamed*"
-#    select: "Select"
-#    unnamed_class: "Unnamed Class"
-#    edit_settings: "edit class settings"
-#    edit_settings1: "Edit Class Settings"
-#    progress: "Class Progress"
-#    add_students: "Add Students"
-#    stats: "Statistics"
-#    total_students: "Total students:"
-#    average_time: "Average level play time:"
-#    total_time: "Total play time:"
-#    average_levels: "Average levels completed:"
-#    total_levels: "Total levels completed:"
-#    furthest_level: "Furthest level completed:"
-#    concepts_covered: "Concepts Covered"
-#    students: "Students"
-#    students1: "students"
-#    expand_details: "Expand details"
-#    concepts: "Concepts"
-#    levels: "levels"
-#    played: "Played"
-#    play_time: "Play time:"
-#    completed: "Completed:"
-#    invite_students: "Invite students to join this class."
-#    enter_emails: "Enter student emails to invite, one per line"
-#    send_invites: "Send Invites"
-#    title: "Title"
-#    description: "Description"
-#    languages_available: "Select programming languages available to the class:"
-#    all_lang: "All Languages"
-#    show_progress: "Show student progress to everyone in the class"
-#    creating_class: "Creating class..."
-#    purchasing_course: "Purchasing course..."
-#    buy_course: "Buy Course"
-#    buy_course1: "Buy this course"
-#    create_class: "Create Class"
-#    select_all_courses: "Select 'All Courses' for a 50% discount!"
-#    all_courses: "All Courses"
-#    number_students: "Number of students"
-#    enter_number_students: "Enter the number of students you need for this class."
-#    name_class: "Name your class"
-#    displayed_course_page: "This will be displayed on the course page for you and your students. It can be changed later."
-#    buy: "Buy"
-#    purchasing_for: "You are purchasing a license for"
-#    creating_for: "You are creating a class for"
-#    for: "for" # Like in 'for 30 students'
-#    receive_code: "Afterwards you will receive an unlock code to distribute to your students, which they can use to enroll in your class."
-#    free_trial: "Free trial for teachers!"
-#    get_access: "to get individual access to all courses for evalutaion purposes."
-#    questions: "Questions?"
-#    faq: "Courses FAQ"
-#    question: "Q:" # Like in 'Question'
-#    question1: "What's the difference between these courses and the single player game?"
-#    answer: "A:" # Like in 'Answer'
-#    answer1: "The single player game is designed for individuals, while the courses are designed for classes."
-#    answer2: "The single player game has items, gems, hero selection, leveling up, and in-app purchases. Courses have classroom management features and streamlined student-focused level pacing."
-#    teachers_click: "Teachers Click Here"
-#    students_click: "Students Click Here"
-#    courses_on_coco: "Courses on CodeCombat"
-#    designed_to: "Courses are designed to introduce computer science concepts using CodeCombat's fun and engaging environment. CodeCombat levels are organized around key topics to encourage progressive learning, over the course of 5 hours."
-#    more_in_less: "Learn more in less time"
-#    no_experience: "No coding experience necesssary"
-#    easy_monitor: "Easily monitor student progress"
-#    purchase_for_class: "Purchase a course for your entire class. It's easy to sign up your students!"
-#    see_the: "See the"
-#    more_info: "for more information."
-#    choose_course: "Choose Your Course:"
-#    enter_code: "Enter an unlock code"
-#    enter_code1: "Enter unlock code"
-#    enroll: "Enroll"
-#    pick_from_classes: "Pick from your current classes"
-#    enter: "Enter"
-#    or: "Or"
-#    topics: "Topics"
-#    hours_content: "Hours of content:"
-#    get_free: "Get FREE course"
+  courses:
+    course: "Курс"
+    courses: "Курсы"
+    not_enrolled: "Вы не записаны на этот курс."
+    visit_pref: "Пожалуйста, зайдите на"
+    visit_suf: "страницу для записи."
+    select_class: "Выберите один из классов"
+    unnamed: "*безымянный*"
+    select: "Выберите"
+    unnamed_class: "Безымянный класс"
+    edit_settings: "изменить настройки класса"
+    edit_settings1: "Изменить настройки класса"
+    progress: "Прогресс класса"
+    add_students: "Добавить студентов"
+    stats: "Статистика"
+    total_students: "Всего студентов:"
+    average_time: "Среднее время в игре:"
+    total_time: "Всего времени в игре:"
+    average_levels: "Среднее кол-во завершенных уровней:"
+    total_levels: "Всего уровней завершено:"
+    furthest_level: "Самый большой завершенный уровень:"
+    concepts_covered: "Концептов покрыто"
+    students: "Студенты"
+    students1: "студенты"
+    expand_details: "Показать детали"
+    concepts: "Концепты"
+    levels: "уровни"
+    played: "Сыграно"
+    play_time: "Время в игре:"
+    completed: "Завершено:"
+    invite_students: "Пригласите студентов в класс."
+    enter_emails: "Введите email студентов по одному на строке, которых вы хотите пригласить"
+    send_invites: "Отправить приглашения"
+    title: "Тема"
+    description: "Описание"
+    languages_available: "Выберите языки программирования, доступные классу:"
+    all_lang: "Все языки"
+    show_progress: "Показывать прогресс студентов всему классу"
+    creating_class: "Создание класса..."
+    purchasing_course: "Покупка курса..."
+    buy_course: "Купить курс"
+    buy_course1: "Купить этот курс"
+    create_class: "Создать класс"
+    select_all_courses: "Выбрать 'Все курсы' для 50% скидки!"
+    all_courses: "Все курсы"
+    number_students: "Кол-во студентов"
+    enter_number_students: "Введите кол-во студентов, нужное для вашего класса."
+    name_class: "Назовите ваш класс"
+    displayed_course_page: "Это будет видно на странице курсе для вас и ваших студентов. Потом вы сможете это изменить."
+    buy: "Купить"
+    purchasing_for: "Вы покупаете лицензию для"
+    creating_for: "Вы создаете класс для"
+    for: "для" # Like in 'for 30 students'
+    receive_code: "После вы получите код, который нужно будет отправить вашим студентам, чтобы они могли записаться на курс."
+    free_trial: "Бесплатный пробный период для учителей!"
+    get_access: "чтобы получить личный доступ ко всем курсам."
+    questions: "Вопросы?"
+    faq: "FAQ по курсам"
+    question: "В:" # Like in 'Question'
+    question1: "Какое различие между этими курсами и обычной одиночной игрой?"
+    answer: "О:" # Like in 'Answer'
+    answer1: "Одиночная игра разработана для одиночного прохождения, а курсы для классов."
+    answer2: "В одиночное игре есть предметы, самоцветы, выбор героев, прокачка уровней и внутриигровые покупки. В курсах есть управление классом и уклон, чтобы студенты сосредотачивались на своем прогрессе."
+    teachers_click: "Учителям сюда"
+    students_click: "Студентам сюда"
+    courses_on_coco: "Курсы на CodeCombat"
+    designed_to: "Курсы разработаны чтобы научить основам информатики через игру и веселье. Уровни огранизованы по самым основным ключевым, чтобы все 5 часов курса было интересно заниматься."
+    more_in_less: "Изучайте больше за меньшее время"
+    no_experience: "Не требуется опыта программирования"
+    easy_monitor: "Легко отслеживать прогресс студентов"
+    purchase_for_class: "Купите курс для всего вашего класса. Студентов очень легко добавлять!"
+    see_the: "Смотрите"
+    more_info: "для доп. информации."
+    choose_course: "Выберите ваш курс:"
+    enter_code: "Введите код"
+    enter_code1: "Введите код"
+    enroll: "Записаться"
+    pick_from_classes: "Выбрать из вашего класса"
+    enter: "Войти"
+    or: "Или"
+    topics: "Темы"
+    hours_content: "Много часов материала:"
+    get_free: "Получить бесплатный курс"

   classes:
     archmage_title: "Архимаг"
@@ -1212,7 +1212,7 @@
     recently_played: "Недавно сыграно"
     no_recent_games: "Нет сыгранных игр за последние две недели."
     payments: "Платежи"
-#    prepaid: "Prepaid"
+    prepaid: "Предоплата"
     purchased: "Куплено"
     sale: "Распродажа"
     subscription: "Подписка"


* update object unit-test

* update object unit-test

--- test/object-test.coffee
+++ test/object-test.coffee
@@ -12,6 +12,16 @@
 Type            = require '../src/object'
 ObjectValue     = require '../src/value/object'
 setImmediate    = setImmediate || process.nextTick
+
+register        = Type.register
+
+###
+class PasswordType
+  register PasswordType, Type.String
+  _initialize: (aOptions)->
+    super(aOptions)
+    @min = 6 # redefine the min property.
+###

 describe "ObjectType", ->
   object = Type("Object")
@@ -37,8 +47,54 @@
         "attributes": {}
         "name":"Object"
         "fullName":"/type/Object"
+    it "should get type info to obj with attributes", ->
+      attrs =
+        a:"string"
+        b:
+          type:"number"
+          min: 2
+          max: 10
+        c:
+          type: "string"
+          required: true
+        d:
+          type: "object"
+          attributes:
+            d1:"number"
+            d2:
+              type:"string"
+              required: true
+            d3:
+              type: "number"
+              min: 3
+              max: 5
+      t = object.cloneType attributes: attrs
+      result = t.toObject()
+      result.should.be.deep.equal
+        name: 'Object'
+        fullName: '/type/Object'
+        attributes:
+          a: "String"
+          b:
+            type:"Number"
+            min: 2
+            max: 10
+          c:
+            type: "String"
+            required: true
+          d:
+            type: "Object"
+            attributes:
+              d1: "Number"
+              d2:
+                type:"String"
+                required: true
+              d3:
+                type: "Number"
+                min: 3
+                max: 5
     it "should get value info to obj", ->
-      result = object.create({a:1})
+      result = object.create({a:1}) #create object value
       result = result.toObject()
       #result = extend {}, result #TODO why deep equal is not same?
       #result = JSON.parse JSON.stringify result
@@ -100,22 +156,34 @@
           d2:
             type:"string"
             required: true
+          d3:
+            type: "number"
+            min: 3
+            max: 5
     it "should validate a value and do not raise error", ->
       t.validate({c:"hi"}).should.be.equal true
       t.validate({a:""}, false).should.be.equal false
-      t.errors.should.be.deep.equal ["name": "[attribute c]", "message": "is required"]
+      t.errors.should.be.deep.equal ["name": "c", "message": "is required"]
       t.validate({b:12}, false).should.be.equal false
       t.errors.should.be.deep.equal [
-        "name": "[attribute b]"
+        "name": "b"
         "message": "should be equal or less than maximum value: 10"
       ,
-        "name": "[attribute c]"
+        "name": "c"
         "message": "is required"
       ]
     it "should validate a object attribute value and do not raise error", ->
       t.validate({c:"hi", d:{d2:""}}).should.be.equal true
       t.validate({c:"hi", d:{d1:1}}, false).should.be.equal false
-      t.errors.should.be.deep.equal ["name": "[attribute d.d2]", "message": "is required"]
+      t.errors.should.be.deep.equal ["name": "d.d2", "message": "is required"]
+      t.validate({c:"hi", d:{d1:1, d3: 6}}, false).should.be.equal false
+      t.errors.should.be.deep.equal [
+        "name": "d.d2"
+        "message": "is required"
+      ,
+        "name": "d.d3"
+        "message": "should be equal or less than maximum value: 5"
+      ]
     it "should validate a value and raise error", ->
       should.throw t.validate.bind(t, 0), 'is an invalid'
       should.throw t.validate.bind(t, 11), 'is an invalid'
@@ -125,13 +193,13 @@
       t1 = t.cloneType strict:true
       t1.validate({"e":"","c":""}, false).should.be.equal false
       t1.errors.should.be.deep.equal [
-        "name": "[attribute e]"
+        "name": "e"
         "message": "is unknown"
       ]
     it "should validate object string on strict mode", ->
       t1 = t.cloneType strict:true
       t1.validate('{"e":"","c":""}', false).should.be.equal false
       t1.errors.should.be.deep.equal [
-        "name": "[attribute e]"
+        "name": "e"
         "message": "is unknown"
       ]


ru.coffee premium_features translate

ru.coffee premium_features translate

premium_features and one pet to russian

--- app/locale/ru.coffee
+++ app/locale/ru.coffee
@@ -442,7 +442,7 @@
     back_to_map: "Вернуться к карте"
     directions: "Направления"
     edit_level: "Редактировать Уровень"
-#    keep_learning: "Keep Learning"
+    keep_learning: "Продолжайте обучение!"
     explore_codecombat: "Исследовать CodeCombat"
     finished_hoc: "Я закончил свой Час кода"
     get_certificate: "Получить сертификат!"
@@ -605,7 +605,7 @@

   play_game_dev_level:
     created_by: "Создано {{name}}"
-#    created_during_hoc: "Created during Hour of Code"
+    created_during_hoc: "Созданный в течении Часа Кода"
     restart: "Переиграть уровень"
     play: "Начать уровень"
     play_more_codecombat: "Играй больше CodeCombat"
@@ -769,8 +769,8 @@
     now_available: "Сейчас доступны подписчикам"
     subscriber: "подписчик"
     cuddly_companions: "Милые компаньоны!" # Pet Announcement Modal
-#    kindling_name: "Kindling Elemental"
-#    kindling_description: "Kindling Elementals just want to keep you warm at night. And during the day. All the time, really."
+    kindling_name: "Огненный Элементаль"
+    kindling_description: "Огненные Элементали помогают согреться в ночи. И днем. В действительности - всё время."
     griffin_name: "Малыш Грифон"
     griffin_description: "Грифоны - наполовину орлы, наполовину львы, полностью прекрасны."
     raven_name: "Ворон"
@@ -810,25 +810,25 @@
   premium_features:
     get_premium: "Получи
CodeCombat
Премиум" # Fit into the banner on the /features page
     master_coder: "Стань мастером програмирования, подписавшись сегодня!"
-#    paypal_redirect: "You will be redirected to PayPal to complete the subscription process."
+    paypal_redirect: "Вы будете перенаправлены на PayPal, чтобы завершить процесс подписки."
     subscribe_now: "Подпишись сейчас"
-#    hero_blurb_1: "Get access to __premiumHeroesCount__ super-charged subscriber-only heroes! Harness the unstoppable power of Okar Stompfoot, the deadly precision of Naria of the Leaf, or summon \"adorable\" skeletons with Nalfar Cryptor."
-#    hero_blurb_2: "Premium Warriors unlock stunning martial skills like Warcry, Stomp, and Hurl Enemy. Or, play as a Ranger, using stealth and bows, throwing knives, traps! Try your skill as a true coding Wizard, and unleash a powerful array of Primordial, Necromantic or Elemental magic!"
+    hero_blurb_1: "Получите доступ к __premiumHeroesCount__ суперкрутым героям для подписчиков! Почувствуйте непреодолимую силу Окара Стомпфута, смертельную точность Нарии Листа, или призовите \"прелестных\" скелетов с Нальфаром Криптором!"
+    hero_blurb_2: "Воинам с Премиумом доступны потрясающие боевые навыки, например Боевой Клич, Стомп и Проклятие! Также они могут играть за Рейнджера, используя скрытность и стрелы, метательные ножи и ловушки! Попробуй свои силы как истинный Маг кода, высвободи могущественный массив Древней Магии, Некромантии или Магии Элементов!"
     hero_caption: "Новые захватывающие герои!"
-#    pet_blurb_1: "Pets aren't just adorable companions, they also provide unique functionality and methods. The Baby Griffon can carry units through the air, the Wolf Pup plays catch with enemy arrows, the Cougar is fond of chasing ogres around, and the Mimic attracts coins like a magnet!"
-#    pet_blurb_2: "Collect all the pets to discover their unique abilities!"
-#    pet_caption: "Adopt pets to accompany your hero!"
-#    game_dev_blurb: "Learn game scripting and build new levels to share with your friends! Place the items you want, write code for unit logic and behavior, and see if your friends can beat the level!"
+    pet_blurb_1: "Питомцы - не только прекрасные компаньоны, они также предоставляют уникальные методы и функциональность. Малыш Грифон может переносить юниты по воздуху, Волчонок, играя, ловит стрелы врагов, Пума любит преследовать огров, а Мимик притягивает монеты, как магнит!"
+    pet_blurb_2: "Собери их всех - исследуй все уникальные способности питомцев!"
+    pet_caption: "Приручите питомцев для компании своему герою!"
+    game_dev_blurb: "Учите игровой скриптинг и создавайте новые уровни, чтобы обмениваться ими со своими друзьями! Помещайте предметы, которые хотите, пишите код для логики юнита и его предпочтений и увидьте, когда ваши друзья смогут справиться с уровнем!"
     game_dev_caption: "Проектируй собственные игры, чтобы бросить вызов своим друзьям!"
     everything_in_premium: "Всё, что вы получите в CodeCombat Премиум:"
-#    list_gems: "Receive bonus gems to buy gear, pets, and heroes"
+    list_gems: "Получите бонусные самоцветы, чтобы купить снаряжение, питомцев и героев!"
     list_levels: "Получи доступ к __premiumLevelsCount__ дополнительным уровням"
     list_heroes: "Разблокируй эксклюзивных героев, включая класы рейнджера и волшебника"
     list_game_dev: "Создавай и делись играми с друзьями"
     list_web_dev: "Создавай веб-сайты и интерактивные приложения"
-#    list_items: "Equip Premium-only items like pets"
-#    list_support: "Get Premium support to help you debug tricky code"
-#    list_clans: "Create private clans to invite your friends and compete on a group leaderboard"
+    list_items: "Экипируйте Премиум-предметы, например, питомцев"
+    list_support: "Получите Премиум-поддержку, которая поможет Вам исправить запутанный код"
+    list_clans: "Создайте личные кланы, пригласите в них друзей и конкурируйте в рейтинге лидеров"

   choose_hero:
     choose_hero: "Выбери героя"


Fix for #3661

Fix for #3661

--- admin/static/coffee/app.coffee
+++ admin/static/coffee/app.coffee
@@ -292,10 +292,11 @@
                                     position: pos.add(1)
                                     num_shards: status('shards').count()
                                     primary_id: primary_id
-                                    primary_name: primary_name
+                                    primary_name: primary_name.default('-')
                                     primary_state: shard('replicas').filter(
-                                        server: primary_name
-                                    )('state')(0)
+                                        server: primary_name,
+                                        {default: r.error()}
+                                    )('state')(0).default('missing')
                             ).filter((shard) ->
                                 r.expr(['ready', 'looking_for_primary_replica'])
                                     .contains(shard('primary_state')).not()


Fixing ship logic

Fixing ship logic

--- ship.coffee
+++ ship.coffee
@@ -7,7 +7,7 @@
       direction: Math.random()*Math.PI*2
       health: 100
       position: [Math.random(), Math.random()]
-      velocity: [0.08, 0.09]
+      velocity: [Math.random(), Math.random()]
       score: 0

     options = _.merge(defaultOptions, options)
@@ -33,16 +33,14 @@
     @direction = data.direction

   runFrame: (timeDiff)->
-    @position = [@velocity[0]*timeDiff, @velocity[1]*timeDiff]
-    @position[0] = Math.abs(@position[0] % 1) if @position[0]>1 || @position[0] < 0
-    @position[1] = Math.abs(@position[1] % 1) if @position[1]>1 || @position[1] < 0
-
+    @position = [@position[0] + @velocity[0]*timeDiff, @position[1] + @velocity[1]*timeDiff]
+    @position[0] = @position[0] % 1
+    @position[0] = 1 - @position[0] if @position[0] < 0
+    @position[1] = @position[1] % 1
+    @position[1] = 1 - @position[1] if @position[1] < 0

     @velocity = [@velocity[0]*0.9999, @velocity[1]*0.9999]
-    @velocity[0] = 1 if @velocity[0] > 1
-    @velocity[1] = 1 if @velocity[1] > 1
-    @velocity[0] = 0 if @velocity[0] < 0
-    @velocity[1] = 0 if @velocity[1] < 0
-
+    @velocity[0] = Math.max(0, Math.min(@velocity[0], 1));
+    @velocity[1] = Math.max(0, Math.min(@velocity[1], 1));

 module.exports = Ship


reset shift report hours on cancelTeam; #204

--- both/methods/shift/shiftSchedule.coffee
+++ both/methods/shift/shiftSchedule.coffee
@@ -45,6 +45,9 @@
 							$addToSet: 'teams.$.declined': participant

 					Meteor.call 'openTeam', shiftId, teamId
+
+				if team.report? && team.report.init
+					Meteor.call 'updateReport', shiftId, teamId, 'hours', 0

 				Meteor.call 'sendCancelTeam', shiftId, teamId, message


Test `revokeInvite`

Test `revokeInvite`

--- services/web/test/UnitTests/coffee/Collaborators/CollaboratorsInviteHandlerTests.coffee
+++ services/web/test/UnitTests/coffee/Collaborators/CollaboratorsInviteHandlerTests.coffee
@@ -17,7 +17,8 @@
 					this[k] = v
 				this
 			save: sinon.stub()
-			findOne: sinon.stub()
+			@findOne: sinon.stub()
+			@remove: sinon.stub()
 		@Project = {}
 		@Crypto = Crypto
 		@CollaboratorsInviteHandler = SandboxedModule.require modulePath, requires:
@@ -33,6 +34,7 @@
 		@sendingUserId = ObjectId()
 		@email = "user@example.com"
 		@userId = ObjectId()
+		@inviteId = ObjectId()
 		@privileges = "readAndWrite"

 	describe 'inviteToProject', ->
@@ -89,3 +91,36 @@
 				@call (err, invite) =>
 					expect(err).to.be.instanceof Error
 					done()
+
+	describe 'revokeInvite', ->
+
+		beforeEach ->
+			@ProjectInvite.remove.callsArgWith(1, null)
+			@CollaboratorsEmailHandler.notifyUserOfProjectInvite = sinon.stub()
+			@call = (callback) =>
+				@CollaboratorsInviteHandler.revokeInvite @projectId, @inviteId, callback
+
+		describe 'when all goes well', ->
+
+			beforeEach ->
+
+			it 'should not produce an error', (done) ->
+				@call (err) =>
+					expect(err).to.not.be.instanceof Error
+					done()
+
+			it 'should call ProjectInvite.remove', (done) ->
+				@call (err) =>
+					@ProjectInvite.remove.callCount.should.equal 1
+					@ProjectInvite.remove.calledWith({projectId: @projectId, _id: @inviteId}).should.equal true
+					done()
+
+		describe 'when remove produces an error', ->
+
+			beforeEach ->
+				@ProjectInvite.remove.callsArgWith(1, new Error('woops'))
+
+			it 'should produce an error', (done) ->
+				@call (err) =>
+					expect(err).to.be.instanceof Error
+					done()


Handle alternative type of disconnected error in web UI.

--- admin/static/coffee/app.coffee
+++ admin/static/coffee/app.coffee
@@ -126,13 +126,20 @@
                                             result.toArray (err, result) =>
                                                 # This happens if people load the page with the back button
                                                 # In which case, we just restart the query
-                                                if err?.message is "This HTTP connection is not open"
+                                                # TODO: Why do we sometimes get an Error object
+                                                #  with message == "[...]", and other times a
+                                                #  RqlClientError with msg == "[...]."?
+                                                if err?.msg is "This HTTP connection is not open." \
+                                                        or err?.message is "This HTTP connection is not open"
+                                                    console.log "Connection lost. Retrying."
                                                     return @run query, delay, callback, index
                                                 callback(err, result)
                                                 if @timers[index]?
                                                     @timers[index].timeout = setTimeout fn, delay
                                         else
-                                            if err?.message is "This HTTP connection is not open"
+                                            if err?.msg is "This HTTP connection is not open." \
+                                                    or err?.message is "This HTTP connection is not open"
+                                                console.log "Connection lost. Retrying."
                                                 return @run query, delay, callback, index
                                             callback(err, result)
                                             if @timers[index]?