mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-26 05:53:39 -04:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
03e2ab6ee7
46 changed files with 781 additions and 336 deletions
app
assets
lib
locale
models
schemas/models
styles
admin
editor/poll
modal
play
templates
views
server
commons
levels
payments
queues
routes
vendor/scripts
|
@ -76,7 +76,7 @@
|
|||
<script src="/lib/ace/ace.js" defer></script>
|
||||
<script src="/javascripts/vendor.js" defer></script>
|
||||
<script src="/javascripts/aether.js" defer></script>
|
||||
<script src="/javascripts/app.js" defer></script> <!-- it's all Backbone! -->
|
||||
<script src="/javascripts/app.js" defer></script>
|
||||
<![endif]>
|
||||
<script>
|
||||
|
||||
|
|
|
@ -72,10 +72,12 @@ module.exports = class LevelLoader extends CocoClass
|
|||
url += "?team=#{@team}" if @team
|
||||
|
||||
session = new LevelSession().setURL url
|
||||
session.project = ['creator', 'team', 'heroConfig', 'codeLanguage', 'submittedCodeLanguage', 'state'] if @headless
|
||||
@sessionResource = @supermodel.loadModel(session, 'level_session', {cache: false})
|
||||
@session = @sessionResource.model
|
||||
if @opponentSessionID
|
||||
opponentSession = new LevelSession().setURL "/db/level.session/#{@opponentSessionID}"
|
||||
opponentSession.project = session.project if @headless
|
||||
@opponentSessionResource = @supermodel.loadModel(opponentSession, 'opponent_session', {cache: false})
|
||||
@opponentSession = @opponentSessionResource.model
|
||||
|
||||
|
|
|
@ -94,14 +94,12 @@
|
|||
campaign_classic_algorithms_description: "... in which you learn the most popular algorithms in Computer Science."
|
||||
|
||||
share_progress_modal:
|
||||
blurb: "You’re making great progress! Tell someone how much you've learned with CodeCombat."
|
||||
blurb: "You’re making great progress! Tell your parent how much you've learned with CodeCombat." #{change}
|
||||
email_invalid: "Email address invalid."
|
||||
form_blurb: "Enter their email below and we’ll show them!"
|
||||
form_blurb: "Enter your parent's email below and we’ll show them!"
|
||||
form_label: "Email Address"
|
||||
placeholder: "email address"
|
||||
title: "Excellent Work, Apprentice"
|
||||
tell_friend: "Tell your Friend"
|
||||
tell_parent: "Tell your Parent"
|
||||
|
||||
login:
|
||||
sign_up: "Create Account"
|
||||
|
@ -263,6 +261,7 @@
|
|||
victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code™!"
|
||||
victory_experience_gained: "XP Gained"
|
||||
victory_gems_gained: "Gems Gained"
|
||||
victory_become_a_viking: "Become a Viking"
|
||||
guide_title: "Guide"
|
||||
tome_minion_spells: "Your Minions' Spells" # Only in old-style levels.
|
||||
tome_read_only_spells: "Read-Only Spells" # Only in old-style levels.
|
||||
|
@ -398,9 +397,9 @@
|
|||
|
||||
subscribe:
|
||||
comparison_blurb: "Sharpen your skills with a CodeCombat subscription!"
|
||||
feature1: "60+ basic levels across 4 worlds"
|
||||
feature1: "80+ basic levels across 4 worlds" # {change}
|
||||
feature2: "7 powerful <strong>new heroes</strong> with unique skills!"
|
||||
feature3: "30+ bonus levels"
|
||||
feature3: "50+ bonus levels" # {change}
|
||||
feature4: "<strong>3500 bonus gems</strong> every month!"
|
||||
feature5: "Video tutorials"
|
||||
feature6: "Premium email support"
|
||||
|
@ -428,6 +427,10 @@
|
|||
parents_blurb1: "With CodeCombat, your child learns by writing real code. They start by learning simple commands, and progress to more advanced topics."
|
||||
parents_blurb2: "For $9.99 USD/mo, they get new challenges every week and personal email support from professional programmers."
|
||||
parents_blurb3: "No Risk: 100% money back guarantee, easy 1-click unsubscribe."
|
||||
payment_methods: "Payment Methods"
|
||||
payment_methods_title: "Accepted Payment Methods"
|
||||
payment_methods_blurb1: "We currently accept credit cards, Alipay, and bitcoins."
|
||||
payment_methods_blurb2: "If you require an alternate form of payment, please contact"
|
||||
stripe_description: "Monthly Subscription"
|
||||
subscription_required_to_play: "You'll need a subscription to play this level."
|
||||
unlock_help_videos: "Subscribe to unlock all video tutorials."
|
||||
|
@ -442,6 +445,7 @@
|
|||
managed_subs: "Managed Subscriptions"
|
||||
managed_subs_desc: "Add subscriptions for other players (students, children, etc.)"
|
||||
group_discounts: "Group discounts"
|
||||
group_discounts_1: "We also offer group discounts for bulk subscriptions."
|
||||
group_discounts_1st: "1st subscription"
|
||||
group_discounts_full: "Full price"
|
||||
group_discounts_2nd: "Subscriptions 2-11"
|
||||
|
@ -588,8 +592,8 @@
|
|||
teacher_subs_1: "Please contact"
|
||||
teacher_subs_2: "to set up a free monthly subscription."
|
||||
sub_includes_title: "What is included in the subscription?"
|
||||
sub_includes_1: "In additional to the 70+ basic levels, students with a monthly subscription get access to these additional features:"
|
||||
sub_includes_2: "40+ practice levels"
|
||||
sub_includes_1: "In addition to the 80+ basic levels, students with a monthly subscription get access to these additional features:" # {change}
|
||||
sub_includes_2: "50+ practice levels" # {change}
|
||||
sub_includes_3: "Video tutorials"
|
||||
sub_includes_4: "Premium email support"
|
||||
sub_includes_5: "7 new heroes with unique skills to master"
|
||||
|
@ -606,7 +610,6 @@
|
|||
how_much_2: "monthly subscription"
|
||||
how_much_3: "costs $9.99, and can be cancelled anytime."
|
||||
how_much_4: "Additionally, we provide discounts for larger groups:"
|
||||
group_discounts_1: "We also offer group discounts for bulk subscriptions."
|
||||
sys_requirements_title: "System Requirements"
|
||||
sys_requirements_1: "A modern web browser. Newer versions of Chrome, Firefox, or Safari. Internet Explorer 9 or later."
|
||||
sys_requirements_2: "CodeCombat is not supported on iPad yet."
|
||||
|
|
|
@ -577,8 +577,8 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
|
|||
|
||||
teachers:
|
||||
title: "CodeCombat: Informações para Professores"
|
||||
# intro_1: "CodeCombat is an online game that teaches programming. Students write code in real programming languages."
|
||||
# intro_2: "No experience required!"
|
||||
intro_1: "O CodeCombat é um jogo 'online' que ensina programação. Os estudantes escrevem código em linguagens de programação reais."
|
||||
intro_2: "Não é necessário ter experiência!"
|
||||
free_title: "Quanto custa?"
|
||||
# cost_china: "CodeCombat in China is free for the first five levels, after which it costs $9.99 per month for access to our other 120+ levels on our exclusive China servers."
|
||||
# free_1: "CodeCombat Basic is FREE! There are 70+ free levels which cover every concept."
|
||||
|
@ -604,8 +604,8 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
|
|||
how_much_1: "Uma"
|
||||
how_much_2: "subscrição mensal"
|
||||
how_much_3: "custa $9.99 e pode ser cancelada a qualquer momento."
|
||||
# how_much_4: "Additionally, we provide discounts for larger groups:"
|
||||
# group_discounts_1: "We also offer group discounts for bulk subscriptions."
|
||||
how_much_4: "Adicionalmente, oferecemos descontos para grupos maiores:"
|
||||
group_discounts_1: "Também oferecemos descontos de grupo para subscrições em massa."
|
||||
sys_requirements_title: "Requisitos do Sistema"
|
||||
sys_requirements_1: "Um navegador moderno. As versões mais recentes do Chrome, Firefox ou Safari. Internet Explorer 9 ou mais recente."
|
||||
sys_requirements_2: "O CodeCombat ainda não é suportado em iPad's."
|
||||
|
@ -867,26 +867,26 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
|
|||
# scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
|
||||
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
|
||||
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
|
||||
scribe_attribute_1: "Habilidade com palavras é basicamente do que precisas. Não apenas gramática e ortografia, mas seres capaz de explicar ideias complicadas a outros."
|
||||
scribe_attribute_1: "Habilidade com palavras é basicamente o que precisas. Não apenas gramática e ortografia, mas seres capaz de explicar ideias complicadas a outros."
|
||||
contact_us_url: "Contacta-nos"
|
||||
scribe_join_description: "fala-nos um bocado de ti, a tua experiência com a programação e o tipo de coisas sobre o qual gostavas de escrever. Começamos a partir daí!"
|
||||
scribe_join_description: "fala-nos um bocado de ti, da tua experiência com a programação e do tipo de coisas sobre as quais gostarias de escrever. Começamos a partir daí!"
|
||||
scribe_subscribe_desc: "Receber e-mails sobre anúncios relativos à escrita de artigos."
|
||||
diplomat_introduction_pref: "Portanto, se há uma coisa que aprendemos com o nosso "
|
||||
diplomat_launch_url: "lançamento em Outubro"
|
||||
diplomat_introduction_suf: "é que há um interesse considerável no CodeCombat noutros países! Estamos a construir um exército de tradutores dispostos a transformar um conjunto de palavras noutro conjuto de palavras, para conseguir que o CodeCombat fique o mais acessível quanto posível em todo o mundo. Se gostas de dar espreitadelas a conteúdos futuros e disponibilizar estes níveis para os teus colegas nacionais o mais depressa possível, então esta classe talvez seja para ti."
|
||||
diplomat_introduction_suf: "é que há um interesse considerável no CodeCombat noutros países! Estamos a construir um exército de tradutores dispostos a transformar um conjunto de palavras num outro conjuto de palavras, para conseguir que o CodeCombat fique o mais acessível quanto posível em todo o mundo. Se gostas de dar espreitadelas a conteúdos futuros e disponibilizar os níveis para os teus colegas nacionais o mais depressa possível, então esta classe talvez seja para ti."
|
||||
diplomat_attribute_1: "Fluência em Inglês e no idioma para o qual gostarias de traduzir. Quando são tentadas passar ideias complicadas, é importante uma excelente compreensão das duas!"
|
||||
diplomat_i18n_page_prefix: "Podes começar a traduzir os nossos níveis se fores à nossa"
|
||||
diplomat_i18n_page: "página de traduções"
|
||||
diplomat_i18n_page_suffix: ", ou a nossa interface e website no GitHub."
|
||||
diplomat_join_pref_github: "Encontra o ficheiro 'locale' do teu idioma "
|
||||
diplomat_github_url: "no GitHub"
|
||||
diplomat_join_suf_github: ", edita-o online e submete um 'pull request'. Assinala ainda esta caixa abaixo para ficares atualizado em relação a novos desenvolvimentos da internacionalização!"
|
||||
diplomat_join_suf_github: ", edita-o online e submete um 'pull request'. Assinala ainda a caixa abaixo para ficares atualizado em relação a novos desenvolvimentos da internacionalização!"
|
||||
diplomat_subscribe_desc: "Receber e-mails sobre desenvolvimentos da i18n e níveis para traduzir."
|
||||
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got forums, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
|
||||
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
|
||||
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
|
||||
ambassador_join_note_strong: "Nota"
|
||||
ambassador_join_note_desc: "Uma das nossas maiores prioridades é construir níveis multijogador onde os jogadores com dificuldade a passar níveis podem invocar feiticeiros mais experientes para serem ajudados. Esta será uma ótima forma para os embixadores fazerem o que sabem. Vamos manter-te atualizado!"
|
||||
ambassador_join_note_desc: "Uma das nossas maiores prioridades é construir níveis multijogador onde os jogadores com dificuldade para passar níveis possam invocar feiticeiros mais experientes para os ajudarem. Esta será uma ótima forma de os embaixadores fazerem o que sabem. Vamos manter-te atualizado!"
|
||||
ambassador_subscribe_desc: "Receber e-mails relativos a novidades do suporte e desenvolvimentos do modo multijogador."
|
||||
changes_auto_save: "As alterações são guardadas automaticamente quando clicas nas caixas."
|
||||
diligent_scribes: "Os Nossos Dedicados Escrivões:"
|
||||
|
|
|
@ -64,7 +64,7 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak",
|
|||
achievements: "Úspechy" # Tooltip on achievement list button from /play
|
||||
account: "Účet" # Tooltip on account button from /play
|
||||
settings: "Nastavenia" # Tooltip on settings button from /play
|
||||
# poll: "Poll" # Tooltip on poll button from /play
|
||||
poll: "Anketa" # Tooltip on poll button from /play
|
||||
next: "Ďalší" # Go from choose hero to choose inventory before playing a level
|
||||
change_hero: "Zmeniť hrdinu" # Go back from choose inventory to choose hero
|
||||
choose_inventory: "Vyzbrojiť sa s predmetmi"
|
||||
|
@ -254,7 +254,7 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak",
|
|||
victory_sign_up: "Přihlásit se pre uloženie progresu"
|
||||
victory_sign_up_poke: "Chceš uložiť svoj kód? Vytvorte si účet zdarma!"
|
||||
victory_rate_the_level: "Ohodnoťte túto úroveň: " # Only in old-style levels.
|
||||
victory_return_to_ladder: "Vrátiť sa na Rebríčky"
|
||||
victory_return_to_ladder: "Rebríčky"
|
||||
victory_play_continue: "Pokračovať"
|
||||
victory_saving_progress: "Stav ukladania"
|
||||
victory_go_home: "Návrat Domov" # Only in old-style levels.
|
||||
|
@ -334,7 +334,7 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak",
|
|||
tip_javascript_java: "Porovnávať Javu a JavaScript je ako porovnávať auto a lietajúci koberec. - Chris Heilmann"
|
||||
tip_move_forward: "Ak nevieš lietať, bež, ak nemôžeš bežať, kráčaj, ak nemôžeš kráčať, choď po štyroch, ale nech už robíš čokoľvek, musíš sa hýbať vpred - Martin Luther King Jr."
|
||||
tip_google: "Máš problém, ktorý nevieš vyriešiť ? Vygoogluj si ho !"
|
||||
tip_adding_evil: "pridanie špitky zla."
|
||||
tip_adding_evil: "Pridanie špitky zla."
|
||||
tip_hate_computers: "Ľudia, ktorí si myslia, že nenávidia počítače, v skutočnosti nenávidia mizerných programátorov. - Larry Niven"
|
||||
tip_open_source_contribute: "Aj ty môžeš zlepšiť CodeCombat !"
|
||||
tip_recurse: "Iterácia je ľudská, rekurzia božská.. - L. Peter Deutsch"
|
||||
|
@ -484,11 +484,11 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak",
|
|||
backstab: "Pichnutie do chrbta" # As in "this dagger does this much backstab damage"
|
||||
skills: "Schopnosti"
|
||||
attack_1: "Upravuje na"
|
||||
attack_2: "hodnotu udávanej"
|
||||
attack_3: "újmy zbraňou."
|
||||
attack_2: "hodnotu udávanej újmy zbraňou pre typ"
|
||||
attack_3: "."
|
||||
health_1: "Upravuje hodnotu zdravia na"
|
||||
health_2: "hodnoty zaručenej"
|
||||
health_3: "brnením."
|
||||
health_2: "hodnoty zaručenej brnením"
|
||||
health_3: "."
|
||||
speed_1: "Pohybuje sa rýchlosťou"
|
||||
speed_2: "metrov za sekundu."
|
||||
available_for_purchase: "Dostupné na zakúpenie" # Shows up when you have unlocked, but not purchased, a hero in the hero store
|
||||
|
@ -542,73 +542,73 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak",
|
|||
editor_config_behaviors_label: "Chytré správanie"
|
||||
editor_config_behaviors_description: "Automaticky doplňuje hranaté a oblé zátvorky a úvodzovky."
|
||||
|
||||
# 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"
|
||||
# why_paragraph_2_italic: "yay a badge"
|
||||
# why_paragraph_2_center: "but fun like"
|
||||
# why_paragraph_2_italic_caps: "NO MOM I HAVE TO FINISH THE LEVEL!"
|
||||
# why_paragraph_2_suffix: "That's why CodeCombat is a multiplayer game, not a gamified lesson course. We won't stop until you can't stop--but this time, that's a good thing."
|
||||
# why_paragraph_3: "If you're going to get addicted to some game, get addicted to this one and become one of the wizards of the tech age."
|
||||
# press_title: "Bloggers/Press"
|
||||
# press_paragraph_1_prefix: "Want to write about us? Feel free to download and use all of the resources included in our"
|
||||
# press_paragraph_1_link: "press packet"
|
||||
# press_paragraph_1_suffix: ". All logos and images may be used without contacting us directly."
|
||||
# team: "Team"
|
||||
# george_title: "Cofounder"
|
||||
# george_blurb: "Businesser"
|
||||
# scott_title: "Cofounder"
|
||||
# scott_blurb: "Reasonable One"
|
||||
# nick_title: "Cofounder"
|
||||
# nick_blurb: "Motivation Guru"
|
||||
# michael_title: "Programmer"
|
||||
# michael_blurb: "Sys Admin"
|
||||
# matt_title: "Programmer"
|
||||
# matt_blurb: "Bicyclist"
|
||||
# cat_title: "Chief Artisan"
|
||||
# cat_blurb: "Airbender"
|
||||
# josh_title: "Game Designer"
|
||||
# josh_blurb: "Floor Is Lava"
|
||||
# jose_title: "Music"
|
||||
# jose_blurb: "Taking Off"
|
||||
# retrostyle_title: "Illustration"
|
||||
# retrostyle_blurb: "RetroStyle Games"
|
||||
about:
|
||||
why_codecombat: "Prečo CodeCombat?"
|
||||
why_paragraph_1: "Ak sa chceš naučiť programovať, nepotrebuješ lekcie. To, čo potrebuješ je možnosť písať veľa kódu a baviť sa pri tom."
|
||||
why_paragraph_2_prefix: "O tom je programovanie. Nemá to byť zábava typu"
|
||||
why_paragraph_2_italic: "jéj, mám ďalší odznak"
|
||||
why_paragraph_2_center: ",ale nadšenie ako"
|
||||
why_paragraph_2_italic_caps: "HNEĎ MAMI, LEN DOKONČÍM TÚTO ÚROVEŇ !"
|
||||
why_paragraph_2_suffix: "CodeCombat je skutočná hra pre viacej hráčov, od ktorej sa dá ťažko odtrhnúť."
|
||||
why_paragraph_3: "Ak už sa máš byť závislý na nejakej hre, tak nech je to táto, pri ktorej sa staneš čarodejníkom technického veku."
|
||||
press_title: "Blogeri/Tlač"
|
||||
press_paragraph_1_prefix: "Chceš o nás písať ? Môžeš si stiahnúť a použiť všetky zdroje zahrnuté v našom"
|
||||
press_paragraph_1_link: "tlačovom balíčku"
|
||||
press_paragraph_1_suffix: ". Všetky logá a obrázky môžeš použiť bez toho, aby si nás priamo kontaktoval."
|
||||
team: "Tím"
|
||||
george_title: "Spoluzakladateľ"
|
||||
george_blurb: "Podnikateľ"
|
||||
scott_title: "Spoluzakladateľ"
|
||||
scott_blurb: "Ten rozumný"
|
||||
nick_title: "Spoluzakladateľ"
|
||||
nick_blurb: "Motivačný Guru"
|
||||
michael_title: "Programátor"
|
||||
michael_blurb: "Systémový administrátor"
|
||||
matt_title: "Programátor"
|
||||
matt_blurb: "Bicyklista"
|
||||
cat_title: "Najvyššia remeselníčka"
|
||||
cat_blurb: "Ohýbačka vzduchu"
|
||||
josh_title: "Dizajnér hier"
|
||||
josh_blurb: "Podlaha je láva"
|
||||
jose_title: "Hudba"
|
||||
jose_blurb: "Vzlet"
|
||||
retrostyle_title: "Ilustrácia"
|
||||
retrostyle_blurb: "Retro hry"
|
||||
|
||||
# teachers:
|
||||
# title: "CodeCombat: Info for Teachers"
|
||||
# intro_1: "CodeCombat is an online game that teaches programming. Students write code in real programming languages."
|
||||
# intro_2: "No experience required!"
|
||||
# free_title: "How much does it cost?"
|
||||
teachers:
|
||||
title: "CodeCombat: Informácie pre učiteľov"
|
||||
intro_1: "CodeCombat je online hra, ktorá učí programovať. Študenti píšu kód v skutočných programovacích jazykoch."
|
||||
intro_2: "Nie sú nutné žiadne predchádzajúce skúsenosti !"
|
||||
free_title: "Koľko to stojí ?"
|
||||
# cost_china: "CodeCombat in China is free for the first five levels, after which it costs $9.99 per month for access to our other 120+ levels on our exclusive China servers."
|
||||
# free_1: "CodeCombat Basic is FREE! There are 70+ free levels which cover every concept."
|
||||
# free_2: "A monthly subscription provides access to video tutorials and extra practice levels."
|
||||
# teacher_subs_title: "Teachers get free subscriptions!"
|
||||
# teacher_subs_1: "Please contact"
|
||||
# teacher_subs_2: "to set up a free monthly subscription."
|
||||
# sub_includes_title: "What is included in the subscription?"
|
||||
# sub_includes_1: "In additional to the 70+ basic levels, students with a monthly subscription get access to these additional features:"
|
||||
# sub_includes_2: "40+ practice levels"
|
||||
# sub_includes_3: "Video tutorials"
|
||||
# sub_includes_4: "Premium email support"
|
||||
# sub_includes_5: "7 new heroes with unique skills to master"
|
||||
# sub_includes_6: "3500 bonus gems every month"
|
||||
# who_for_title: "Who is CodeCombat for?"
|
||||
# who_for_1: "We recommend CodeCombat for students aged 9 and up. No prior programming experience is needed."
|
||||
# who_for_2: "We've designed CodeCombat to appeal to both boys and girls."
|
||||
# material_title: "How much material is there?"
|
||||
free_1: "CodeCombat Basic is ZDARMA ! K dispozícii je 70+ úrovní pokrývajúcich každý koncept."
|
||||
free_2: "Mesačné predplatné poskytuje prístup k videonávodom a k úrovniam na precvičenie navyše."
|
||||
teacher_subs_title: "Pre učiteľov je predplatné zdarma !"
|
||||
teacher_subs_1: "Napíšte na"
|
||||
teacher_subs_2: "pre zriadenie mesačného predplatného zdarma."
|
||||
sub_includes_title: "Čo zahrnuje predplatné ?"
|
||||
sub_includes_1: "Študenti s mesačným predplatným získajú ku 70+ základným úrovniam aj :"
|
||||
sub_includes_2: "40+ tréningových úrovní"
|
||||
sub_includes_3: "Video návody"
|
||||
sub_includes_4: "Prémiovú emailovú podporu"
|
||||
sub_includes_5: "7 nových hrdinov s jedinečnými schopnosťami"
|
||||
sub_includes_6: "3500 bonusových diamantov každý mesiac"
|
||||
who_for_title: "Pre koho je určený CodeComabt ?"
|
||||
who_for_1: "CodeCombat odporúčame pre žiakov od 9 rokov. Nie sú nutné žiadne predchádzajúce skúsenosti s programovaním."
|
||||
who_for_2: "CodeCombat sme navrhli tak, aby oslovil chlapcov aj dievčatá."
|
||||
material_title: "Aký je objem učebnej látky ?"
|
||||
# material_china: "Approximately 22 hours of gameplay spread over 120+ subscriber-only levels so far, with 5 new levels every week."
|
||||
# material_1: "Approximately 8 hours of free content and an additional 14 hours of subscriber content, with 5 new levels every week."
|
||||
# concepts_title: "What concepts are covered?"
|
||||
# how_much_title: "How much does a monthly subscription cost?"
|
||||
# how_much_1: "A"
|
||||
# how_much_2: "monthly subscription"
|
||||
# how_much_3: "costs $9.99, and can be cancelled anytime."
|
||||
# how_much_4: "Additionally, we provide discounts for larger groups:"
|
||||
material_1: "Asi 8 hodín bezplatného obsahu a ďalších 14 hodín pre predplatiteľov. 5 nových úrovní každý týždeň."
|
||||
concepts_title: "Aké pojmy sú pokryté ?"
|
||||
how_much_title: "Koľko stojí mesačné predplatné ?"
|
||||
how_much_1: ""
|
||||
how_much_2: "Mesačné predplatné"
|
||||
how_much_3: ", ktoré môže byť kedykoľvek zrušené, stojí 9.99$."
|
||||
how_much_4: "Zľavy pre väčšie skupiny:"
|
||||
# group_discounts_1: "We also offer group discounts for bulk subscriptions."
|
||||
# sys_requirements_title: "System Requirements"
|
||||
# sys_requirements_1: "A modern web browser. Newer versions of Chrome, Firefox, or Safari. Internet Explorer 9 or later."
|
||||
# sys_requirements_2: "CodeCombat is not supported on iPad yet."
|
||||
sys_requirements_title: "Systémové požiadavky"
|
||||
sys_requirements_1: "Moderný webový prehliadač. Nové verzie prehliadačov Chrome, Firefox alebo Safari. Internet Explorer 9 alebo novší."
|
||||
sys_requirements_2: "CodeCombat nie je zatiaľ podprovaný pre iPad."
|
||||
|
||||
versions:
|
||||
save_version_title: "Ulož novú verziu"
|
||||
|
@ -700,43 +700,43 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak",
|
|||
# beautify: "Beautify your code by standardizing its formatting."
|
||||
# maximize_editor: "Maximize/minimize code editor."
|
||||
|
||||
# community:
|
||||
# main_title: "CodeCombat Community"
|
||||
# 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"
|
||||
# level_editor_suffix: "to create and edit levels. Users have created levels for their classes, friends, hackathons, students, and siblings. If create a new level sounds intimidating you can start by forking one of ours!"
|
||||
# thang_editor_prefix: "We call units within the game 'thangs'. Use the"
|
||||
# thang_editor_suffix: "to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites."
|
||||
# article_editor_prefix: "See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the"
|
||||
# article_editor_suffix: "and help CodeCombat players get the most out of their playtime."
|
||||
# find_us: "Find us on these sites"
|
||||
# social_blog: "Read the CodeCombat blog on Sett"
|
||||
# social_discource: "Join the discussion on our Discourse forum"
|
||||
# social_facebook: "Like CodeCombat on Facebook"
|
||||
# social_twitter: "Follow CodeCombat on Twitter"
|
||||
# social_gplus: "Join CodeCombat on Google+"
|
||||
# social_hipchat: "Chat with us in the public CodeCombat HipChat room"
|
||||
# contribute_to_the_project: "Contribute to the project"
|
||||
community:
|
||||
main_title: "CodeCombat Komunita"
|
||||
introduction: "Pozri si spôsoby ako sa môžeš zapojiť a rozhodni sa, čo ťa najviac láka.Tešime sa na spoluprácu !"
|
||||
level_editor_prefix: "Použi"
|
||||
level_editor_suffix: "na vytvorenie a úpravu úrovní. Uživatelia vytvorili úrovne pre svoje triedy, svojích priateľov, žiakov, súrodencov a aj pre deň kódovania. Ak sa bojíš začínať celkom od začiatku, môžeš začať klonovaním a úpravou našich úrovní."
|
||||
thang_editor_prefix: "Jednotky hry nazývame vecičky - 'thangs'. Použi"
|
||||
thang_editor_suffix: "na úpravu grafiky. Povoľ jednotkám vrhať strely, zmeň smer animácie, zmeň body zásahu alebo nahraj vlastné vektorové sprity."
|
||||
article_editor_prefix: "Vidíš chybu v našich dokumentoch ? Chceš pridať inštrukcie k vlastným výtvorom ? Pozri sa na"
|
||||
article_editor_suffix: "a pomôž hráčom, aby získali, čo najviac z hrania na CodeCombat."
|
||||
find_us: "Nájdeš nás na týchto stránkach"
|
||||
social_blog: "Prečítaj si blog na Sette"
|
||||
social_discource: "Pridaj sa k diskusii na fóre Discourse"
|
||||
social_facebook: "Daj Like CodeCombatu na Facebooku"
|
||||
social_twitter: "Sleduj CodeCombat na Twitteri"
|
||||
social_gplus: "Pripoj sa ku CodeCombatu na Google+"
|
||||
social_hipchat: "Chatujte s nami vo verejnej HipChat miestnosti"
|
||||
contribute_to_the_project: "Prispej svojou prácou"
|
||||
|
||||
# classes:
|
||||
# archmage_title: "Archmage"
|
||||
# archmage_title_description: "(Coder)"
|
||||
# archmage_summary: "If you are a developer interested in coding educational games, become an archmage to help us build CodeCombat!"
|
||||
# artisan_title: "Artisan"
|
||||
# artisan_title_description: "(Level Builder)"
|
||||
# artisan_summary: "Build and share levels for you and your friends to play. Become an Artisan to learn the art of teaching others to program."
|
||||
# adventurer_title: "Adventurer"
|
||||
# adventurer_title_description: "(Level Playtester)"
|
||||
# adventurer_summary: "Get our new levels (even our subscriber content) for free one week early and help us work out bugs before our public release."
|
||||
# scribe_title: "Scribe"
|
||||
# scribe_title_description: "(Article Editor)"
|
||||
# scribe_summary: "Good code needs good documentation. Write, edit, and improve the docs read by millions of players across the globe."
|
||||
# diplomat_title: "Diplomat"
|
||||
# diplomat_title_description: "(Translator)"
|
||||
# diplomat_summary: "CodeCombat is localized in 45+ languages by our Diplomats. Help us out and contribute translations."
|
||||
# ambassador_title: "Ambassador"
|
||||
# ambassador_title_description: "(Support)"
|
||||
# ambassador_summary: "Tame our forum users and provide direction for those with questions. Our ambassadors represent CodeCombat to the world."
|
||||
classes:
|
||||
archmage_title: "Arcimág"
|
||||
archmage_title_description: "(Programátor)"
|
||||
archmage_summary: "Ak si vývojár so záujmom o kódovanie vzdelávacíh hier, staň sa Arcimágom a pomôž nám s vývojom CodeCombatu !"
|
||||
artisan_title: "Remeselník"
|
||||
artisan_title_description: "(Tvorca úrovní)"
|
||||
artisan_summary: "Tvor a zdieľaj úrovne, ktoré si môžu zahrať tvoji priatelia. Staň sa Remeselníkom a nauč sa umenie učiť iných programovať."
|
||||
adventurer_title: "Dobrodruh"
|
||||
adventurer_title_description: "(Testovač úrovní)"
|
||||
adventurer_summary: "Dostaň sa k naším novým úrovniam (dokonca aj k tým pre predplatiteľov) zdarma a o týždeň skôr. Pomôž nám odhaliť chyby pred ich zverejnemím."
|
||||
scribe_title: "Pisár"
|
||||
scribe_title_description: "(Editor)"
|
||||
scribe_summary: "Dobrý kód potrebuje dobrú dokumentáciu. Píš, edituj a vylepši dokumenty, ktoré čítajú milióny hráčov na celom svete."
|
||||
diplomat_title: "Diplomat"
|
||||
diplomat_title_description: "(Prekladateľ)"
|
||||
diplomat_summary: "CodeCombat je preložený vďaka naším diplomatom do 45+ jazykov. Pomôž nám s prekladom."
|
||||
ambassador_title: "Ambasador"
|
||||
ambassador_title_description: "(Poradca)"
|
||||
ambassador_summary: "Kroť použivateľov nášho fóra a nasmeruj na správnu cestu tých, čo sa pýtajú. Naši ambasádori reprezentujú CodeCombat na celom svete."
|
||||
|
||||
# editor:
|
||||
# main_title: "CodeCombat Editors"
|
||||
|
@ -828,10 +828,10 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak",
|
|||
# polls:
|
||||
# priority: "Priority"
|
||||
|
||||
# contribute:
|
||||
# page_title: "Contributing"
|
||||
# intro_blurb: "CodeCombat is 100% open source! Hundreds of dedicated players have helped us build the game into what it is today. Join us and write the next chapter in CodeCombat's quest to teach the world to code!"
|
||||
# alert_account_message_intro: "Hey there!"
|
||||
contribute:
|
||||
page_title: "Prispenie"
|
||||
intro_blurb: "CodeCombat je 100% open source! Stovky nadšených hráčov nám pomohli dostať hru na dnešnú úroveň. Pripoj sa k nám a napíš ďalšiu kapitolu CodeCombatu, ktorý učí svet kódovať!"
|
||||
alert_account_message_intro: "Ahoj!"
|
||||
# alert_account_message: "To subscribe for class emails, you'll need to be logged in first."
|
||||
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
|
||||
# class_attributes: "Class Attributes"
|
||||
|
@ -896,61 +896,61 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak",
|
|||
# translating_diplomats: "Our Translating Diplomats:"
|
||||
# helpful_ambassadors: "Our Helpful Ambassadors:"
|
||||
|
||||
# ladder:
|
||||
# please_login: "Please log in first before playing a ladder game."
|
||||
# my_matches: "My Matches"
|
||||
# simulate: "Simulate"
|
||||
# simulation_explanation: "By simulating games you can get your game ranked faster!"
|
||||
# simulate_games: "Simulate Games!"
|
||||
# simulate_all: "RESET AND SIMULATE GAMES"
|
||||
# games_simulated_by: "Games simulated by you:"
|
||||
# games_simulated_for: "Games simulated for you:"
|
||||
# games_simulated: "Games simulated"
|
||||
# games_played: "Games played"
|
||||
# ratio: "Ratio"
|
||||
# leaderboard: "Leaderboard"
|
||||
# battle_as: "Battle as "
|
||||
# summary_your: "Your "
|
||||
# summary_matches: "Matches - "
|
||||
# summary_wins: " Wins, "
|
||||
# summary_losses: " Losses"
|
||||
# rank_no_code: "No New Code to Rank"
|
||||
# rank_my_game: "Rank My Game!"
|
||||
# rank_submitting: "Submitting..."
|
||||
# rank_submitted: "Submitted for Ranking"
|
||||
# rank_failed: "Failed to Rank"
|
||||
# rank_being_ranked: "Game Being Ranked"
|
||||
# rank_last_submitted: "submitted "
|
||||
# help_simulate: "Help simulate games?"
|
||||
# code_being_simulated: "Your new code is being simulated by other players for ranking. This will refresh as new matches come in."
|
||||
# no_ranked_matches_pre: "No ranked matches for the "
|
||||
# no_ranked_matches_post: " team! Play against some competitors and then come back here to get your game ranked."
|
||||
# choose_opponent: "Choose an Opponent"
|
||||
# select_your_language: "Select your language!"
|
||||
# tutorial_play: "Play Tutorial"
|
||||
# tutorial_recommended: "Recommended if you've never played before"
|
||||
# tutorial_skip: "Skip Tutorial"
|
||||
# tutorial_not_sure: "Not sure what's going on?"
|
||||
# tutorial_play_first: "Play the Tutorial first."
|
||||
# simple_ai: "Simple AI"
|
||||
# warmup: "Warmup"
|
||||
# friends_playing: "Friends Playing"
|
||||
# log_in_for_friends: "Log in to play with your friends!"
|
||||
# social_connect_blurb: "Connect and play against your friends!"
|
||||
# invite_friends_to_battle: "Invite your friends to join you in battle!"
|
||||
# fight: "Fight!"
|
||||
# watch_victory: "Watch your victory"
|
||||
# defeat_the: "Defeat the"
|
||||
# tournament_started: ", started"
|
||||
# tournament_ends: "Tournament ends"
|
||||
# tournament_ended: "Tournament ended"
|
||||
# tournament_rules: "Tournament Rules"
|
||||
# tournament_blurb: "Write code, collect gold, build armies, crush foes, win prizes, and upgrade your career in our $40,000 Greed tournament! Check out the details"
|
||||
# tournament_blurb_criss_cross: "Win bids, construct paths, outwit opponents, grab gems, and upgrade your career in our Criss-Cross tournament! Check out the details"
|
||||
# tournament_blurb_zero_sum: "Unleash your coding creativity in both gold gathering and battle tactics in this alpine mirror match between red sorcerer and blue sorcerer. The tournament began on Friday, March 27 and will run until Monday, April 6 at 5PM PDT. Compete for fun and glory! Check out the details"
|
||||
# tournament_blurb_blog: "on our blog"
|
||||
# rules: "Rules"
|
||||
# winners: "Winners"
|
||||
ladder:
|
||||
please_login: "Pred hraním rebríčkovej hry sa musíš najskôr prihlásiť."
|
||||
my_matches: "Moje súboje"
|
||||
simulate: "Simuluj"
|
||||
simulation_explanation: "Simulovaním sa dostane hra rýchlejšie do rebríčka !!"
|
||||
simulate_games: "Simuluj hry !"
|
||||
simulate_all: "RESETUJ A SIMULUJ HRY"
|
||||
games_simulated_by: "Tebou simulované hry:"
|
||||
games_simulated_for: "Pre teba simulované hry:"
|
||||
games_simulated: "Simulované hry"
|
||||
games_played: "Odohrané hry"
|
||||
ratio: "Pomer"
|
||||
leaderboard: "Rebríček"
|
||||
battle_as: "Hraj ako "
|
||||
summary_your: "Tvoje "
|
||||
summary_matches: "Súboje - počet výhier "
|
||||
summary_wins: ", počet prehier "
|
||||
summary_losses: " "
|
||||
rank_no_code: "Žiadny nový kód na ocenenie"
|
||||
rank_my_game: "Oceň moju hru !"
|
||||
rank_submitting: "Odosielam..."
|
||||
rank_submitted: "Odoslané na ocenenie"
|
||||
rank_failed: "Chyba pri oceňovaní"
|
||||
rank_being_ranked: "Hra je oceňovaná"
|
||||
rank_last_submitted: "odoslané "
|
||||
help_simulate: "Pomôžeš so simuláciou hier ?"
|
||||
code_being_simulated: "Tvoj nový kód je simulovaný iným hráčom. Rebríček sa obnoví po nových súbojoch."
|
||||
no_ranked_matches_pre: "Žiadne ocenené súboje pre "
|
||||
no_ranked_matches_post: " tím ! Hraj proti súperom a potom sa sem vráť a uvidíš ocenenie svojej hry."
|
||||
choose_opponent: "Vyber si súpera"
|
||||
select_your_language: "Vyber si jazyk !"
|
||||
tutorial_play: "Hraj tutoriál"
|
||||
tutorial_recommended: "Odporúčané, pokiaľ si ešte nikdy nehral"
|
||||
tutorial_skip: "Preskoč tutoriál"
|
||||
tutorial_not_sure: "Nie si si istý, čo sa deje ?"
|
||||
tutorial_play_first: "Hraj najskôr tutoriál."
|
||||
simple_ai: "Jednoduchá umelá inteligencia"
|
||||
warmup: "Na rozohratie"
|
||||
friends_playing: "Hra proti priateľom"
|
||||
log_in_for_friends: "Prihlás sa a hraj s priateľmi !"
|
||||
social_connect_blurb: "Pripoj sa a hraj proti svojím priateľom !"
|
||||
invite_friends_to_battle: "Pozvi priateľov a bojuj s nimi !"
|
||||
fight: "Bojuj !"
|
||||
watch_victory: "Pozri si svoju výhru"
|
||||
defeat_the: "Poraz"
|
||||
tournament_started: ", spustený"
|
||||
tournament_ends: "Turnaj končí"
|
||||
tournament_ended: "Turnaj skončil"
|
||||
tournament_rules: "Pravidlá turnaja"
|
||||
tournament_blurb: "Píš kód, zbieraj mince, stavaj armády, rozdrv nepriateľov, vyhraj ceny v hodnote 40,000$. Greed tournament! Pozri sa na detaily."
|
||||
tournament_blurb_criss_cross: "Vyhraj ponuky, buduj cesty, preľsti súperov,zbieraj diamanty grab gems a vylepši svoju kariéru v našom Krížovkárskom turnaji ! Pozri sa na detaily"
|
||||
tournament_blurb_zero_sum: "Odviaž svoju kódovaciu kreativitu pri zbieraní mincí a bojovej taktike v spravodlivom vysokohorskom súboji medzi medzi červenou a modrou čarodejkou. Turnaj začal v piatok 27. marca 2015 a skončil 6. apríla 2015. Súťaž pre zábavu a slávu ! Pozri sa na detaily"
|
||||
tournament_blurb_blog: "v našom blogu."
|
||||
rules: "Pravidlá"
|
||||
winners: "Víťazi"
|
||||
|
||||
user:
|
||||
stats: "Stats"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
storage = require 'core/storage'
|
||||
deltasLib = require 'core/deltas'
|
||||
locale = require 'locale/locale'
|
||||
|
||||
class CocoModel extends Backbone.Model
|
||||
idAttribute: '_id'
|
||||
|
@ -26,6 +27,7 @@ class CocoModel extends Backbone.Model
|
|||
# if fixed, RevertModal will also need the fix
|
||||
|
||||
setProjection: (project) ->
|
||||
# TODO: ends up getting done twice, since the URL is modified and the @project is modified. So don't do this, just set project directly... (?)
|
||||
return if project is @project
|
||||
url = @getURL()
|
||||
url += '&project=' unless /project=/.test url
|
||||
|
@ -399,12 +401,19 @@ class CocoModel extends Backbone.Model
|
|||
# use it to determine what properties actually need to be translated
|
||||
props = workingSchema.props or []
|
||||
props = (prop for prop in props when parentData[prop])
|
||||
#unless props.length
|
||||
# console.log 'props is', props, 'path is', path, 'data is', data, 'parentData is', parentData, 'workingSchema is', workingSchema
|
||||
# langCodeArrays.push _.without _.keys(locale), 'update' # Every language has covered a path with no properties to be translated.
|
||||
# return
|
||||
|
||||
return if 'additionalProperties' of i18n # Workaround for #2630: Programmable is weird
|
||||
|
||||
# get a list of lang codes where its object has keys for every prop to be translated
|
||||
coverage = _.filter(_.keys(i18n), (langCode) ->
|
||||
translations = i18n[langCode]
|
||||
_.all((translations[prop] for prop in props))
|
||||
)
|
||||
#console.log 'got coverage', coverage, 'for', path, props, workingSchema, parentData
|
||||
langCodeArrays.push coverage
|
||||
)
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ _.extend LevelSessionSchema.properties,
|
|||
type: 'boolean' # Not tracked any more
|
||||
frame:
|
||||
type: 'number' # Not tracked any more
|
||||
thangs:
|
||||
thangs: # ... what is this? Is this used?
|
||||
type: 'object'
|
||||
additionalProperties:
|
||||
title: 'Thang'
|
||||
|
@ -241,7 +241,7 @@ _.extend LevelSessionSchema.properties,
|
|||
description: 'The date a match was computed.'
|
||||
playtime:
|
||||
title: 'Playtime so far'
|
||||
description: 'The total seconds of playtime on this session when the match was computed.'
|
||||
description: 'The total seconds of playtime on this session when the match was computed. Not currently tracked.'
|
||||
type: 'number'
|
||||
metrics:
|
||||
type: 'object'
|
||||
|
|
|
@ -274,6 +274,12 @@ _.extend UserSchema.properties,
|
|||
levelSystemMiscPatches: c.int()
|
||||
thangTypeTranslationPatches: c.int()
|
||||
thangTypeMiscPatches: c.int()
|
||||
achievementTranslationPatches: c.int()
|
||||
achievementMiscPatches: c.int()
|
||||
pollTranslationPatches: c.int()
|
||||
pollMiscPatches: c.int()
|
||||
campaignTranslationPatches: c.int()
|
||||
campaignMiscPatches: c.int()
|
||||
|
||||
earned: c.RewardSchema 'earned by achievements'
|
||||
purchased: c.RewardSchema 'purchased with gems or money'
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
height: 500px
|
||||
width: 100%
|
||||
|
||||
// TODO: figure out why this is necessary
|
||||
margin-bottom: 100px
|
||||
|
||||
.x.axis
|
||||
font-size: 9pt
|
||||
path
|
||||
|
|
|
@ -14,4 +14,4 @@
|
|||
#poll-view
|
||||
min-height: 200px
|
||||
position: relative
|
||||
|
||||
z-index: 0
|
||||
|
|
|
@ -118,6 +118,20 @@
|
|||
font-family: $headings-font-family
|
||||
font-size: 18px
|
||||
|
||||
//- Payment methods info popover link
|
||||
|
||||
#payment-methods-info
|
||||
position: absolute
|
||||
right: 38px
|
||||
top: 389px
|
||||
text-decoration: underline
|
||||
cursor: pointer
|
||||
font-weight: bold
|
||||
line-height: 18px
|
||||
color: black
|
||||
font-family: $headings-font-family
|
||||
font-size: 18px
|
||||
|
||||
//- Purchase button
|
||||
|
||||
.purchase-button
|
||||
|
|
|
@ -563,14 +563,20 @@ $gameControlMargin: 30px
|
|||
width: 100%
|
||||
text-align: center
|
||||
|
||||
.campaign-name, .levels-completed, .campaign-locked, .campaign-description
|
||||
.campaign-name, .levels-completed, .campaign-locked
|
||||
margin: 0
|
||||
color: white
|
||||
text-shadow: black 2px 2px 0, black -2px -2px 0, black 2px -2px 0, black -2px 2px 0, black 2px 0px 0, black 0px -2px 0, black -2px 0px 0, black 0px 2px 0
|
||||
|
||||
.campaign-locked
|
||||
margin: 32px 0
|
||||
|
||||
.campaign-description
|
||||
margin: 0px 40px
|
||||
font-size: 22px
|
||||
background: transparent url(/images/level/popover_border_background.png) no-repeat
|
||||
background-size: 100% 100%
|
||||
padding: 12px
|
||||
color: black
|
||||
|
||||
.levels-completed
|
||||
font-size: 22px
|
||||
|
|
|
@ -369,6 +369,11 @@
|
|||
.text-link
|
||||
color: lighten(#0b63bc, 10%)
|
||||
|
||||
.offer
|
||||
display: none
|
||||
|
||||
p
|
||||
color: white
|
||||
|
||||
html.no-borderimage
|
||||
#hero-victory-modal
|
||||
|
|
|
@ -39,24 +39,8 @@
|
|||
font-weight: bold
|
||||
color: black
|
||||
|
||||
p.parent-blurb, p.friend-blurb
|
||||
line-height: 16px
|
||||
display: none
|
||||
|
||||
.tell-parent-btn, .tell-friend-btn
|
||||
margin: 10px
|
||||
border-image: url(/images/level/code_toolbar_submit_button_active.png) 14 20 20 20 fill round
|
||||
color: white
|
||||
// width: 80px
|
||||
font-size: 28px
|
||||
line-height: 28px
|
||||
text-transform: none
|
||||
font-variant: small-caps
|
||||
font-family: "Open Sans Condensed", "Helvetica Neue", Helvetica, Arial, sans-serif
|
||||
|
||||
.send-container
|
||||
margin-top: 10px
|
||||
display: none
|
||||
.email-form
|
||||
.email-input
|
||||
width: 200px
|
||||
|
@ -77,7 +61,7 @@
|
|||
.continue-container
|
||||
margin-top: 10px
|
||||
margin-right: -12px
|
||||
.back-link, .continue-link
|
||||
.continue-link
|
||||
color: black
|
||||
font-weight: normal
|
||||
font-size: 11px
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
extends /templates/base
|
||||
|
||||
block content
|
||||
|
||||
|
||||
if !me.isAdmin()
|
||||
div You must be logged in as an admin to view this page.
|
||||
else
|
||||
|
||||
if total === 0
|
||||
h1 Fetching subscriptions data...
|
||||
h4 Fetching dashboard data...
|
||||
else
|
||||
.container-fluid
|
||||
.row
|
||||
|
@ -37,15 +38,59 @@ block content
|
|||
|
||||
div *Stripe APIs do not return information about inactive subs.
|
||||
|
||||
br
|
||||
|
||||
table.table.table-condensed.concepts-table
|
||||
h2 Recent Subscribers
|
||||
if !subscribers || subscribers.length < 1
|
||||
h4 Fetching recent subscribers...
|
||||
else
|
||||
table.table.table-condensed
|
||||
thead
|
||||
tr
|
||||
th User Start
|
||||
th Sub Start
|
||||
if subscriberCancelled
|
||||
th Cancelled
|
||||
else
|
||||
th
|
||||
th
|
||||
//- th Name
|
||||
th Email
|
||||
th Hero
|
||||
th Level
|
||||
th Last Level
|
||||
th Age
|
||||
th Spoken
|
||||
tbody
|
||||
each subscriber in subscribers
|
||||
tr
|
||||
td= subscriber.user.dateCreated.substring(0, 10)
|
||||
td= subscriber.start.substring(0, 10)
|
||||
td
|
||||
if subscriber.cancel
|
||||
span= subscriber.cancel.substring(0, 10)
|
||||
td
|
||||
if subscriber.user.stripe.sponsorID
|
||||
span Sponsored
|
||||
//- td
|
||||
//- a(href="/user/#{subscriber.user._id}")= subscriber.user.name || 'Anoner'
|
||||
td= subscriber.user.emailLower
|
||||
td= subscriber.hero
|
||||
td= subscriber.level
|
||||
td= subscriber.user.lastLevel
|
||||
td= subscriber.user.ageRange
|
||||
td= subscriber.user.preferredLanguage
|
||||
|
||||
h2 Subscriptions
|
||||
if !subs || subs.length < 1
|
||||
h4 Fetching subscriptions...
|
||||
else
|
||||
table.table.table-condensed
|
||||
thead
|
||||
tr
|
||||
th Day
|
||||
th Total
|
||||
th Started
|
||||
th Cancelled
|
||||
th Net
|
||||
tbody
|
||||
each sub in subs
|
||||
tr
|
||||
|
@ -53,3 +98,4 @@ block content
|
|||
td= sub.total
|
||||
td= sub.started
|
||||
td= sub.cancelled
|
||||
td= sub.started - sub.cancelled
|
||||
|
|
|
@ -14,9 +14,9 @@ block content
|
|||
h2
|
||||
a.spl(href="/editor/level", data-i18n="editor.level_title")
|
||||
p
|
||||
span(data-i18n="community.level_editor_prefix") Use the CodeCombat
|
||||
a.spl.spr(href="/editor/level", data-i18n="editor.level_title")
|
||||
span(data-i18n="community.level_editor_suffix") to create and edit levels. Users have created levels for their classes, friends, hackathons, students, and siblings. If create a new level sounds intimidating you can start by forking one of ours!
|
||||
span.spr(data-i18n="community.level_editor_prefix") Use the CodeCombat
|
||||
a(href="/editor/level", data-i18n="editor.level_title")
|
||||
span.spl(data-i18n="community.level_editor_suffix") to create and edit levels. Users have created levels for their classes, friends, hackathons, students, and siblings. If create a new level sounds intimidating you can start by forking one of ours!
|
||||
|
||||
.community-columns
|
||||
a(href="/editor/thang")
|
||||
|
@ -24,9 +24,9 @@ block content
|
|||
h2
|
||||
a.spl(href="/editor/thang", data-i18n="editor.thang_title")
|
||||
p
|
||||
span(data-i18n="community.thang_editor_prefix") We call units within the game 'thangs'. Use the
|
||||
a.spl.spr(href="/editor/thang", data-i18n="editor.thang_title")
|
||||
span(data-i18n="community.thang_editor_suffix") to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites.
|
||||
span.spr(data-i18n="community.thang_editor_prefix") We call units within the game 'thangs'. Use the
|
||||
a(href="/editor/thang", data-i18n="editor.thang_title")
|
||||
span.spl(data-i18n="community.thang_editor_suffix") to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites.
|
||||
|
||||
.community-columns
|
||||
a(href="/editor/article")
|
||||
|
@ -34,9 +34,9 @@ block content
|
|||
h2
|
||||
a.spl(href="/editor/article", data-i18n="editor.article_title")
|
||||
p
|
||||
span(data-i18n="community.article_editor_prefix") See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the
|
||||
a.spl.spr(href="/editor/article", data-i18n="editor.article_title")
|
||||
span(data-i18n="community.article_editor_suffix") and help CodeCombat players get the most out of their playtime.
|
||||
span.spr(data-i18n="community.article_editor_prefix") See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the
|
||||
a(href="/editor/article", data-i18n="editor.article_title")
|
||||
span.spl(data-i18n="community.article_editor_suffix") and help CodeCombat players get the most out of their playtime.
|
||||
|
||||
div
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
if showRequiredError
|
||||
.alert.alert-success
|
||||
span(data-i18n="signup.required") You need to log in before you can that way.
|
||||
else if mode === 'signup' && showSignupRationale
|
||||
.alert.alert-info
|
||||
span(data-i18n="play_level.victory_sign_up_poke") Want to save your code? Create a free account!
|
||||
|
||||
form.form
|
||||
.form-group
|
||||
|
|
|
@ -16,9 +16,9 @@ block modal-body-content
|
|||
p(data-i18n="contact.subscriber_support") Since you're a CodeCombat subscriber, your email will get our priority support.
|
||||
else
|
||||
p
|
||||
span(data-i18n="contact.subscribe_prefix") If you need help figuring out a level, please
|
||||
a.spl.spr(data-toggle="coco-modal", data-target="core/SubscribeModal", data-i18n="contact.subscribe") buy a CodeCombat subscription
|
||||
span(data-i18n="contact.subscribe_suffix") and we'll be happy to help you with your code.
|
||||
span.spr(data-i18n="contact.subscribe_prefix") If you need help figuring out a level, please
|
||||
a(data-toggle="coco-modal", data-target="core/SubscribeModal", data-i18n="contact.subscribe") buy a CodeCombat subscription
|
||||
span.spl(data-i18n="contact.subscribe_suffix") and we'll be happy to help you with your code.
|
||||
.form
|
||||
.form-group
|
||||
label.control-label(for="contact-email", data-i18n="general.email") Email
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
td.center-ok
|
||||
span.glyphicon.glyphicon-ok
|
||||
#parents-info(data-i18n="subscribe.parents")
|
||||
#payment-methods-info(data-i18n="subscribe.payment_methods")
|
||||
|
||||
button.btn.btn-lg.btn-illustrated.purchase-button(data-i18n="subscribe.subscribe_title")
|
||||
button.btn.btn-lg.btn-illustrated.parent-button(data-i18n="subscribe.parent_button")
|
||||
|
|
|
@ -15,8 +15,8 @@ if campaign
|
|||
if level.unlocksHero && (!level.purchasedHero || editorMode)
|
||||
img.hero-portrait(src="/file/db/thang.type/#{level.unlocksHero}/portrait.png")
|
||||
a(href=level.type == 'hero' ? '#' : level.disabled ? "/play" : "/play/#{level.levelPath || 'level'}/#{level.slug}", disabled=level.disabled, data-level-slug=level.slug, data-level-path=level.levelPath || 'level', data-level-name=level.name)
|
||||
if level.slug == 'apocalypse'
|
||||
img.star(src="/file/db/thang.type/54ea89112b7506e891ca717d/portrait.png")
|
||||
if level.slug == 'lost-viking'
|
||||
img.star(src="/file/db/thang.type/5441c3144e9aeb727cc97111/portrait.png")
|
||||
else if level.requiresSubscription
|
||||
img.star(src="/images/pages/play/star.png")
|
||||
if levelStatusMap[level.slug] === 'complete'
|
||||
|
@ -79,7 +79,7 @@ else
|
|||
else if campaign
|
||||
btn(data-i18n="common.play").btn.btn-illustrated.btn-lg.btn-success.play-button
|
||||
if campaign && campaign.get('description')
|
||||
h3.campaign-description
|
||||
p.campaign-description
|
||||
span= i18n(campaign.attributes, 'description')
|
||||
|
||||
.game-controls.header-font
|
||||
|
|
|
@ -84,8 +84,7 @@ block content
|
|||
| .
|
||||
p
|
||||
strong Tournament ended!
|
||||
//a(href="#winners") Behold the winners
|
||||
span We will announce winners soon
|
||||
a(href="#winners") Behold the winners
|
||||
| . Thanks for playing! You can
|
||||
strong still play
|
||||
| Zero Sum as long as you like.
|
||||
|
@ -122,7 +121,7 @@ block content
|
|||
if level.get('name') == 'Greed'
|
||||
li
|
||||
a(href="#rules", data-toggle="tab", data-i18n="ladder.rules") Rules
|
||||
if level.get('name') == 'Greed' || (level.get('name') == 'Criss-Cross')
|
||||
if level.get('name') == 'Greed' || level.get('name') == 'Criss-Cross' || level.get('name') == 'Zero Sum'
|
||||
li
|
||||
a(href="#winners", data-toggle="tab", data-i18n="ladder.winners") Winners
|
||||
|
||||
|
@ -761,7 +760,7 @@ block content
|
|||
a(href="http://discourse.codecombat.com/") Discourse forum
|
||||
| .
|
||||
|
||||
if level.get('name') == 'Greed' || level.get('name') == 'Criss-Cross'
|
||||
if level.get('name') == 'Greed' || level.get('name') == 'Criss-Cross' || level.get('name') == 'Zero Sum'
|
||||
.tab-pane.well#winners
|
||||
h1(data-i18n="ladder.winners") Winners
|
||||
|
||||
|
@ -769,17 +768,19 @@ block content
|
|||
thead
|
||||
tr
|
||||
th(data-i18n="ladder_prizes.rank") Rank
|
||||
if level.get('name') == 'Criss-Cross'
|
||||
if level.get('name') == 'Criss-Cross' || level.get('name') == 'Zero Sum'
|
||||
th
|
||||
th Human
|
||||
if level.get('name') == 'Greed'
|
||||
if level.get('name') == 'Greed' || level.get('name') == 'Zero Sum'
|
||||
th Human wins/losses/ties
|
||||
else
|
||||
th Human score
|
||||
if level.get('name') == 'Criss-Cross'
|
||||
if level.get('name') == 'Zero Sum'
|
||||
th
|
||||
if level.get('name') == 'Criss-Cross' || level.get('name') == 'Zero Sum'
|
||||
th
|
||||
th Ogre
|
||||
if level.get('name') == 'Greed'
|
||||
if level.get('name') == 'Greed' || level.get('name') == 'Zero Sum'
|
||||
th Ogre wins/losses/ties
|
||||
else
|
||||
th Ogre score
|
||||
|
@ -789,30 +790,38 @@ block content
|
|||
- var ogre = winners.ogres[index]
|
||||
tr
|
||||
td= human.rank
|
||||
if level.get('name') == 'Criss-Cross'
|
||||
if level.get('name') == 'Criss-Cross' || level.get('name') == 'Zero Sum'
|
||||
td.code-language-cell(style="background-image: url(/images/common/code_languages/" + human.codeLanguage + "_icon.png)" title=_.string.capitalize(human.codeLanguage))
|
||||
td= human.name
|
||||
if level.get('name') == 'Greed'
|
||||
if level.get('name') == 'Greed' || level.get('name') == 'Zero Sum'
|
||||
td
|
||||
span.win= human.wins
|
||||
| -
|
||||
span.loss= human.losses
|
||||
| -
|
||||
span.tie= 377 - human.wins - human.losses
|
||||
if level.get('name') == 'Greed'
|
||||
span.tie= 377 - human.wins - human.losses
|
||||
else if level.get('name') == 'Zero Sum'
|
||||
span.tie= 108 - human.wins - human.losses
|
||||
else
|
||||
td
|
||||
span= Math.round(100 * human.score)
|
||||
if ogre
|
||||
if level.get('name') == 'Criss-Cross'
|
||||
if level.get('name') == 'Zero Sum'
|
||||
td= ogre.rank
|
||||
if level.get('name') == 'Criss-Cross' || level.get('name') == 'Zero Sum'
|
||||
td.code-language-cell(style="background-image: url(/images/common/code_languages/" + ogre.codeLanguage + "_icon.png)" title=_.string.capitalize(ogre.codeLanguage))
|
||||
td= ogre.name
|
||||
if level.get('name') == 'Greed'
|
||||
if level.get('name') == 'Greed' || level.get('name') == 'Zero Sum'
|
||||
td
|
||||
span.win= ogre.wins
|
||||
| -
|
||||
span.loss= ogre.losses
|
||||
| -
|
||||
span.tie= 407 - ogre.wins - ogre.losses
|
||||
if level.get('name') == 'Greed'
|
||||
span.tie= 407 - ogre.wins - ogre.losses
|
||||
else if level.get('name') == 'Zero Sum'
|
||||
span.tie= Math.max(0, 163 - ogre.wins - ogre.losses)
|
||||
else
|
||||
td
|
||||
span= Math.round(100 * ogre.score)
|
||||
|
|
|
@ -89,5 +89,12 @@ block modal-footer-content
|
|||
img(src="/images/level/csedweek-logo-final-small.jpg", alt="CS Ed Week Hour of Code", title="I'm finished with my Hour of Code", width=80)
|
||||
strong(data-i18n="play_level.victory_hour_of_code_done") Are You Done?
|
||||
a.text-link(href="http://code.org/api/hour/finish")
|
||||
span(data-i18n="play_level.victory_hour_of_code_done_yes") Yes, I'm finished with my Hour of Code!
|
||||
.clearfix
|
||||
span(data-i18n="play_level.victory_hour_of_code_done_yes") Yes, I am finished with my Hour of Code!
|
||||
.clearfix
|
||||
|
||||
.offer.lost-viking
|
||||
p
|
||||
img.pull-left(src="/file/db/level/55144b509f0c4854051769c1/viking1.png")
|
||||
img.pull-right(src="/file/db/level/55144b509f0c4854051769c1/viking_2.png")
|
||||
| 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.
|
||||
button.btn.btn-illustrated.btn-primary.btn-lg.world-map-button.continue-from-offer-button(data-i18n="play_level.victory_become_a_viking") Become a Viking
|
||||
|
|
|
@ -14,6 +14,14 @@ if docs.length === 1
|
|||
hr
|
||||
h3 Want more programming lessons?
|
||||
ul
|
||||
li
|
||||
strong
|
||||
a(class="resource-link", data-resource="breakout-mentors", href='http://breakoutmentors.com/?referral=codecombat') Breakout Mentors
|
||||
| : Personalized code mentoring for kids from Stanford and UC Berkeley mentors, online or in person.
|
||||
li
|
||||
strong
|
||||
a(class="resource-link", data-resource="ostraining", href='https://www.ostraining.com/codecombat/') OSTraining
|
||||
| : Watch over 2600 videos on how to make great websites with Wordpress, Drupal, Joomla, and more.
|
||||
li
|
||||
strong
|
||||
a(class="resource-link", data-resource="one-month", href='http://mbsy.co/bVRtZ') One Month
|
||||
|
|
|
@ -25,7 +25,10 @@ if topScores
|
|||
td.ago-cell= row.ago
|
||||
td.viewable-cell
|
||||
if viewable
|
||||
.glyphicon.glyphicon-eye-open
|
||||
if (me.get('preferredLanguage', true) || 'en-US').substr(0, 2) == 'en'
|
||||
.btn.btn-xs.btn-info Watch
|
||||
else
|
||||
.glyphicon.glyphicon-eye-open
|
||||
else
|
||||
.glyphicon.glyphicon-eye-close
|
||||
else if loading
|
||||
|
|
|
@ -6,16 +6,6 @@
|
|||
.blurb-container
|
||||
h1(data-i18n="share_progress_modal.title")
|
||||
p(data-i18n="share_progress_modal.blurb")
|
||||
.container-fluid.btn-picker-container
|
||||
.row
|
||||
.col-xs-12.text-center
|
||||
button.btn.btn-illustrated.tell-parent-btn(data-i18n="share_progress_modal.tell_parent")
|
||||
.row
|
||||
.col-xs-12.text-center
|
||||
button.btn.btn-illustrated.tell-friend-btn(data-i18n="share_progress_modal.tell_friend")
|
||||
.row.continue-container
|
||||
.col-xs-12.text-right
|
||||
a.continue-link(data-i18n="common.continue")
|
||||
|
||||
.container-fluid.send-container
|
||||
.row
|
||||
|
@ -30,7 +20,5 @@
|
|||
.col-xs-4.text-right
|
||||
button.btn.btn-illustrated.send-btn(data-i18n="common.send")
|
||||
.row.continue-container
|
||||
.col-xs-6
|
||||
a.back-link(data-i18n="common.back")
|
||||
.col-xs-6.text-right
|
||||
.col-xs-12.text-left
|
||||
a.continue-link(data-i18n="common.continue")
|
||||
|
|
|
@ -13,7 +13,7 @@ module.exports = class CommunityView extends RootView
|
|||
titleDescription = $.i18n.t("classes.#{characterClass}_title_description")
|
||||
summary = $.i18n.t("classes.#{characterClass}_summary")
|
||||
explanation = "<h4>#{title} #{titleDescription}</h4>#{summary}"
|
||||
$(@).find('img').popover(placement: 'bottom', trigger: 'hover', container: 'body', content: explanation, html: true)
|
||||
$(@).find('img').popover(placement: 'top', trigger: 'hover', container: 'body', content: explanation, html: true)
|
||||
|
||||
@$el.find('.logo-row img').each ->
|
||||
$(@).popover(placement: 'bottom', trigger: 'hover', container: 'body')
|
||||
$(@).popover(placement: 'top', trigger: 'hover', container: 'body')
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
RootView = require 'views/core/RootView'
|
||||
template = require 'templates/admin/analytics-subscriptions'
|
||||
RealTimeCollection = require 'collections/RealTimeCollection'
|
||||
ThangType = require 'models/ThangType'
|
||||
User = require 'models/User'
|
||||
|
||||
# TODO: Add last N subscribers table
|
||||
# TODO: Add revenue line
|
||||
# TODO: Graphing code copied/mangled from campaign editor level view. OMG, DRY.
|
||||
|
||||
require 'vendor/d3'
|
||||
|
@ -11,10 +10,11 @@ require 'vendor/d3'
|
|||
module.exports = class AnalyticsSubscriptionsView extends RootView
|
||||
id: 'admin-analytics-subscriptions-view'
|
||||
template: template
|
||||
targetSubCount: 2000
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@resetData()
|
||||
@resetSubscriptionsData()
|
||||
if me.isAdmin()
|
||||
@refreshData()
|
||||
_.delay (=> @refreshData()), 30 * 60 * 1000
|
||||
|
@ -23,6 +23,8 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
context = super()
|
||||
context.analytics = @analytics ? graphs: []
|
||||
context.subs = _.cloneDeep(@subs ? []).reverse()
|
||||
context.subscribers = @subscribers ? []
|
||||
context.subscriberCancelled = _.find context.subscribers, (subscriber) -> subscriber.cancel
|
||||
context.total = @total ? 0
|
||||
context.cancelled = @cancelled ? 0
|
||||
context.monthlyChurn = @monthlyChurn ? 0.0
|
||||
|
@ -33,17 +35,39 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
super()
|
||||
@updateAnalyticsGraphs()
|
||||
|
||||
resetData: ->
|
||||
resetSubscriptionsData: ->
|
||||
@analytics = graphs: []
|
||||
@subs = []
|
||||
@total = 0
|
||||
@cancelled = 0
|
||||
@monthlyChurn = 0.0
|
||||
@monthlyGrowth = 0.0
|
||||
|
||||
refreshData: ->
|
||||
return unless me.isAdmin()
|
||||
@resetData()
|
||||
@resetSubscriptionsData()
|
||||
@getSubscribers()
|
||||
@getSubscriptions()
|
||||
|
||||
getSubscribers: ->
|
||||
options =
|
||||
url: '/db/subscription/-/subscribers'
|
||||
method: 'POST'
|
||||
data: {maxCount: 30}
|
||||
options.error = (model, response, options) =>
|
||||
return if @destroyed
|
||||
console.error 'Failed to get subscribers', response
|
||||
options.success = (subscribers, response, options) =>
|
||||
return if @destroyed
|
||||
@subscribers = subscribers
|
||||
for subscriber in @subscribers
|
||||
subscriber.level = User.levelFromExp subscriber.user.points
|
||||
if hero = subscriber.user.heroConfig?.thangType
|
||||
subscriber.hero = _.invert(ThangType.heroes)[hero]
|
||||
@render?()
|
||||
@supermodel.addRequestResource('get_subscribers', options, 0).load()
|
||||
|
||||
getSubscriptions: ->
|
||||
options =
|
||||
url: '/db/subscription/-/subscriptions'
|
||||
method: 'GET'
|
||||
|
@ -52,7 +76,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
console.error 'Failed to get subscriptions', response
|
||||
options.success = (subs, response, options) =>
|
||||
return if @destroyed
|
||||
@resetData()
|
||||
@resetSubscriptionsData()
|
||||
subDayMap = {}
|
||||
for sub in subs
|
||||
startDay = sub.start.substring(0, 10)
|
||||
|
@ -66,7 +90,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
for day of subDayMap
|
||||
@subs.push
|
||||
day: day
|
||||
started: subDayMap[day]['start']
|
||||
started: subDayMap[day]['start'] or 0
|
||||
cancelled: subDayMap[day]['cancel'] or 0
|
||||
|
||||
@subs.sort (a, b) -> a.day.localeCompare(b.day)
|
||||
|
@ -78,9 +102,9 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
startedLastMonth += sub.started if @subs.length - i < 31
|
||||
@monthlyChurn = @cancelled / startedLastMonth * 100.0 if startedLastMonth > 0
|
||||
if @subs.length > 30 and @subs[@subs.length - 31].total > 0
|
||||
lastMonthTotal = @subs[@subs.length - 31].total
|
||||
thisMonthTotal = @subs[@subs.length - 1].total
|
||||
@monthlyGrowth = (thisMonthTotal - lastMonthTotal) / lastMonthTotal * 100
|
||||
startMonthTotal = @subs[@subs.length - 31].total
|
||||
endMonthTotal = @subs[@subs.length - 1].total
|
||||
@monthlyGrowth = (endMonthTotal / startMonthTotal - 1) * 100
|
||||
@updateAnalyticsGraphData()
|
||||
@render?()
|
||||
@supermodel.addRequestResource('get_subscriptions', options, 0).load()
|
||||
|
@ -98,6 +122,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
# TODO: Where should this metadata live?
|
||||
# TODO: lineIDs assumed to be unique across graphs
|
||||
totalSubsID = 'total-subs'
|
||||
targetSubsID = 'target-subs'
|
||||
startedSubsID = 'started-subs'
|
||||
cancelledSubsID = 'cancelled-subs'
|
||||
netSubsID = 'net-subs'
|
||||
|
@ -106,6 +131,11 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
description: 'Total Active Subscriptions'
|
||||
color: 'green'
|
||||
strokeWidth: 1
|
||||
lineMetadata[targetSubsID] =
|
||||
description: 'Target Total Subscriptions'
|
||||
color: 'gold'
|
||||
strokeWidth: 4
|
||||
opacity: 1.0
|
||||
lineMetadata[startedSubsID] =
|
||||
description: 'New Subscriptions'
|
||||
color: 'blue'
|
||||
|
@ -162,8 +192,9 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
points: levelPoints
|
||||
description: lineMetadata[totalSubsID].description
|
||||
lineColor: lineMetadata[totalSubsID].color
|
||||
strokeWidth: lineMetadata[totalSubsID].strokeWidth
|
||||
min: 0
|
||||
max: d3.max(@subs, (d) -> d.total)
|
||||
max: Math.max(@targetSubCount, d3.max(@subs, (d) -> d.total))
|
||||
|
||||
## Started
|
||||
|
||||
|
@ -196,9 +227,34 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
points: levelPoints
|
||||
description: lineMetadata[startedSubsID].description
|
||||
lineColor: lineMetadata[startedSubsID].color
|
||||
strokeWidth: lineMetadata[startedSubsID].strokeWidth
|
||||
min: 0
|
||||
max: d3.max(@subs, (d) -> d.started)
|
||||
|
||||
## Total subs target
|
||||
|
||||
# Build line data
|
||||
levelPoints = []
|
||||
for sub, i in @subs
|
||||
levelPoints.push
|
||||
x: i
|
||||
y: @targetSubCount
|
||||
day: sub.day
|
||||
pointID: "#{targetSubsID}#{i}"
|
||||
values: []
|
||||
|
||||
levelPoints.splice(0, levelPoints.length - timeframeDays) if levelPoints.length > timeframeDays
|
||||
|
||||
@analytics.graphs[0].lines.push
|
||||
lineID: targetSubsID
|
||||
enabled: true
|
||||
points: levelPoints
|
||||
description: lineMetadata[targetSubsID].description
|
||||
lineColor: lineMetadata[targetSubsID].color
|
||||
strokeWidth: lineMetadata[targetSubsID].strokeWidth
|
||||
min: 0
|
||||
max: @targetSubCount
|
||||
|
||||
## Cancelled
|
||||
averageCancelled = 0
|
||||
|
||||
|
@ -235,6 +291,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
points: levelPoints
|
||||
description: lineMetadata[cancelledSubsID].description
|
||||
lineColor: lineMetadata[cancelledSubsID].color
|
||||
strokeWidth: lineMetadata[cancelledSubsID].strokeWidth
|
||||
min: 0
|
||||
max: d3.max(@subs, (d) -> d.started)
|
||||
|
||||
|
@ -310,7 +367,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
xRange = d3.scale.linear().range([0, width]).domain([d3.min(line.points, (d) -> d.x), d3.max(line.points, (d) -> d.x)])
|
||||
yRange = d3.scale.linear().range([height, 0]).domain([line.min, line.max])
|
||||
|
||||
# x-Axis and guideline once
|
||||
# x-Axis
|
||||
if currentLine is 0
|
||||
startDay = new Date(line.points[0].day)
|
||||
endDay = new Date(line.points[line.points.length - 1].day)
|
||||
|
@ -369,7 +426,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
|
|||
svg.append("text")
|
||||
.attr("x", margin + 40 + 10)
|
||||
.attr("y", margin + height + xAxisHeight + keyHeight * currentLine + (keyHeight + 10) / 2)
|
||||
.attr("fill", line.lineColor)
|
||||
.attr("fill", if line.lineColor is 'gold' then 'orange' else line.lineColor)
|
||||
.attr("class", "key-text")
|
||||
.text(line.description)
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ module.exports = class AuthModal extends ModalView
|
|||
getRenderData: ->
|
||||
c = super()
|
||||
c.showRequiredError = @options.showRequiredError
|
||||
c.showSignupRationale = @options.showSignupRationale
|
||||
c.mode = @mode
|
||||
c.formValues = @previousFormInputs or {}
|
||||
c.me = me
|
||||
|
|
|
@ -37,6 +37,7 @@ module.exports = class SubscribeModal extends ModalView
|
|||
super()
|
||||
@setupParentButtonPopover()
|
||||
@setupParentInfoPopover()
|
||||
@setupPaymentMethodsInfoPopover()
|
||||
|
||||
setupParentButtonPopover: ->
|
||||
popoverTitle = $.i18n.t 'subscribe.parent_email_title'
|
||||
|
@ -85,6 +86,21 @@ module.exports = class SubscribeModal extends ModalView
|
|||
).on 'shown.bs.popover', =>
|
||||
application.tracker?.trackEvent 'Subscription parent hover'
|
||||
|
||||
setupPaymentMethodsInfoPopover: ->
|
||||
popoverTitle = $.i18n.t('subscribe.payment_methods_title')
|
||||
popoverContent = "<p>" + $.i18n.t('subscribe.payment_methods_blurb1') + "</p>"
|
||||
popoverContent += "<p>" + $.i18n.t('subscribe.payment_methods_blurb2') + " <a href='mailto:support@codecombat.com'>support@codecombat.com</a>."
|
||||
@$el.find('#payment-methods-info').popover(
|
||||
animation: true
|
||||
html: true
|
||||
placement: 'top'
|
||||
trigger: 'click'
|
||||
title: popoverTitle
|
||||
content: popoverContent
|
||||
container: @$el
|
||||
).on 'shown.bs.popover', =>
|
||||
application.tracker?.trackEvent 'Subscription payment methods hover'
|
||||
|
||||
onClickParentSendButton: (e) ->
|
||||
# TODO: Popover sometimes dismisses immediately after send
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ module.exports = class I18NEditLevelView extends I18NEditModelView
|
|||
for doc, index in @model.get('documentation')?.specificArticles ? []
|
||||
if i18n = doc.i18n
|
||||
@wrapRow 'Guide article name', ['name'], doc.name, i18n[lang]?.name, ['documentation', 'specificArticles', index]
|
||||
@wrapRow "'#{doc.name}' description", ['description'], doc.description, i18n[lang]?.description, ['documentation', 'specificArticles', index], 'markdown'
|
||||
@wrapRow "'#{doc.name}' body", ['body'], doc.body, i18n[lang]?.body, ['documentation', 'specificArticles', index], 'markdown'
|
||||
|
||||
# sprite dialogues
|
||||
for script, scriptIndex in @model.get('scripts') ? []
|
||||
|
|
|
@ -110,6 +110,8 @@ module.exports = class LadderView extends RootView
|
|||
@$el.find('a[href="#rules"]').tab('show')
|
||||
if link and /#prizes/.test link
|
||||
@$el.find('a[href="#prizes"]').tab('show')
|
||||
if link and /#winners/.test link
|
||||
@$el.find('a[href="#winners"]').tab('show')
|
||||
|
||||
destroy: ->
|
||||
clearInterval @refreshInterval
|
||||
|
|
|
@ -48,7 +48,7 @@ module.exports = class SimulateTabView extends CocoView
|
|||
@startSimulating()
|
||||
|
||||
startSimulating: ->
|
||||
@simulationPageRefreshTimeout = _.delay @refreshAndContinueSimulating, 20 * 60 * 1000
|
||||
@simulationPageRefreshTimeout = _.delay @refreshAndContinueSimulating, 30 * 60 * 1000
|
||||
@simulateNextGame()
|
||||
$('#simulate-button').prop 'disabled', true
|
||||
$('#simulate-button').text 'Simulating...'
|
||||
|
@ -65,7 +65,7 @@ module.exports = class SimulateTabView extends CocoView
|
|||
# Work around simulator getting super slow on Chrome
|
||||
fetchAndSimulateTaskOriginal = @simulator.fetchAndSimulateTask
|
||||
@simulator.fetchAndSimulateTask = =>
|
||||
if @simulator.simulatedByYou >= 5
|
||||
if @simulator.simulatedByYou >= 20
|
||||
console.log '------------------- Destroying Simulator and making a new one -----------------'
|
||||
@simulator.destroy()
|
||||
@simulator = null
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module.exports = results = greed: {}, 'criss-cross': {}
|
||||
module.exports = results = greed: {}, 'criss-cross': {}, 'zero-sum': {}
|
||||
|
||||
results.greed.humans = [
|
||||
{team: 'humans', rank: 1, sessionID: '5381e3537585483905a829c1', name: 'Wizard Dude', playtime: 63184, wins: 363, losses: 0, score: 363}
|
||||
|
@ -746,3 +746,205 @@ results['criss-cross'].ogres = [
|
|||
{team: 'ogres', rank: 72, sessionID: '53f4847afda22e3305bdbea5', codeLanguage: 'javascript', name: 'CodeMinion', score: 9.706964015}
|
||||
{team: 'ogres', rank: 73, sessionID: '53fba49c3baef834054b98c6', codeLanguage: 'javascript', name: 'Moises Banales', score: 8.991630973}
|
||||
]
|
||||
|
||||
results['zero-sum'].humans = [
|
||||
{team: 'humans', rank: 1, userID: '539b571db4c4f9380545317d', sessionID: '55188bcee3ae3a3505f7d1ad', name: 'NoJuice4u', wins: 105, losses: 3, playtime: 46222, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 2, userID: '54ef65eaef838a790598b305', sessionID: '5518349d1f12482609b452ea', name: 'Qenf', wins: 99, losses: 9, playtime: 13554, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 3, userID: '5308bb6cc326dda10cf62d6d', sessionID: '55172d95e3ae3a3505f7a6ed', name: 'Stofflon', wins: 95, losses: 13, playtime: 22609, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 3, userID: '539bccfb6e1d92310506ffa9', sessionID: '5518d8624c73053505254062', name: 'Driphter', wins: 95, losses: 13, playtime: 32555, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 5, userID: '54d2c6ac3e16915505f0cef3', sessionID: '551f2d159800ae33059c5052', name: 'KingCode', wins: 93, losses: 15, playtime: 13510, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 5, userID: '549ee5208f3c153d0518ff24', sessionID: '55195098d69ccd3305a2ea0c', name: 'wabu', wins: 93, losses: 15, playtime: 3274, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 5, userID: '5500505220b2567d0514bab9', sessionID: '551582ecf43d375105fbdf00', name: 'Muadibi', wins: 93, losses: 15, playtime: 30381, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 5, userID: '54f015a0df1b7d7d05610870', sessionID: '55172f2ec13fa03205248953', name: 'Andre95', wins: 93, losses: 15, playtime: 53158, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 9, userID: '54ff548501c724b9072f9f6d', sessionID: '551bd2f91794dc1a112bfc28', name: 'mAsTer_A', wins: 91, losses: 16, playtime: 11860, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 10, userID: '539c13ba6e1d923105072c32', sessionID: '5515a210d792f354050c9339', name: 'rasdasd', wins: 89, losses: 19, playtime: 12710, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 11, userID: '5516520db77a16330597d9a3', sessionID: '55165233de8bc03205975972', name: 'SlamBlasta', wins: 88, losses: 20, playtime: 10063, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 12, userID: '512ef4805a67a8c507000001', sessionID: '550370aeec31df9c691ab632', name: 'Nick', wins: 87, losses: 20, playtime: 22856, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 13, userID: '55164512de8bc032059758dc', sessionID: '55184ea8e3ae3a3505f7c811', name: 'Geoboardman', wins: 87, losses: 21, playtime: 11451, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 13, userID: '551750ca81389437054def79', sessionID: '5517545fe3ae3a3505f7ac1f', name: 'the real Carl Maxwell', wins: 87, losses: 21, playtime: 6242, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 15, userID: '537d01f484c54c6e05c05989', sessionID: '55164e9f4e83223605e7942a', name: 'Serg', wins: 85, losses: 23, playtime: 8176, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 16, userID: '5478a26cc439b9160865b3b3', sessionID: '550ceb075834237a05acda6e', name: 'Tutor Delphia', wins: 83, losses: 25, playtime: 30978, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 17, userID: '551d78734c73053505267238', sessionID: '551dc7046cc7da101fe5fe52', name: 'Kongou', wins: 79, losses: 29, playtime: 561, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 18, userID: '53f4cb0cfda22e3305be24e7', sessionID: '5515ecc4b8185a5205e1a304', name: 'Dothgar', wins: 74, losses: 34, playtime: 4129, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 19, userID: '5520a4caabdb444805e85da1', sessionID: '5522f7ae801bea3905cb6fd9', name: 'Bazhan', wins: 73, losses: 34, playtime: 4466, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 20, userID: '5506e39e84ce5b7905627e41', sessionID: '551bed505afdf532055862e4', name: 'pixx', wins: 73, losses: 35, playtime: 12182, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 21, userID: '5516aa174d24212f05944d19', sessionID: '5517065858852c3405f48e9d', name: 'Haruna', wins: 70, losses: 38, playtime: 19377, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 22, userID: '54a800d3a487d53f056c0bb7', sessionID: '5519bac15cd6bae40951f460', name: 'Mensian', wins: 69, losses: 39, playtime: 17817, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 23, userID: '5519d8885afdf5320557df5c', sessionID: '5519d88e8328b9020debf019', name: 'StabGun', wins: 69, losses: 39, playtime: 3710, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 23, userID: '55187c2c5afdf532055782df', sessionID: '55187c63d69ccd3305a2c33b', name: 'shakesoda', wins: 69, losses: 39, playtime: 19789, codeLanguage: 'lua'}
|
||||
{team: 'humans', rank: 25, userID: '5429a6d19f9fa2bf2c5a4e4e', sessionID: '55173873d69ccd3305a2918c', name: 'FadingSun32', wins: 65, losses: 43, playtime: 113, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 25, userID: '54f9e344d12cf54d069d92dc', sessionID: '550d0ba29e22dc56056be1dd', name: 'xianjin', wins: 65, losses: 43, playtime: 693, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 27, userID: '54fd36429ae7221e06728f3b', sessionID: '550d001c9e22dc56056be0d8', name: 'Jasmine49', wins: 59, losses: 49, playtime: 5222, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 27, userID: '551b205cc13fa03205254f3e', sessionID: '551c04088328b9020dec9ef1', name: 'my98olds', wins: 59, losses: 49, playtime: 22943, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 29, userID: '54bbb1016ef7bdde07101c4e', sessionID: '551807d0c13fa03205249b3d', name: 'PSL', wins: 57, losses: 51, playtime: 2523, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 30, userID: '539ea2ba64edb6fa0bf584f7', sessionID: '5516a002b77a16330597e208', name: 'MarS explorer', wins: 55, losses: 53, playtime: 5966, codeLanguage: 'lua'}
|
||||
{team: 'humans', rank: 30, userID: '548e1d2d24446d3d050281ed', sessionID: '55080c49039bafd50cb92fae', name: 'J_F_B_M', wins: 55, losses: 53, playtime: 7951, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 32, userID: '5489342042443b56076a1ad8', sessionID: '55173465e3ae3a3505f7a7ff', name: 'AnnieHall', wins: 54, losses: 52, playtime: 5576, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 33, userID: '54f1ddf248724e7d052b75fd', sessionID: '551a7f0e5cd6bae409522148', name: 'TiboW', wins: 54, losses: 54, playtime: 942, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 34, userID: '55169c96aedec33205e8acfc', sessionID: '55169df0aedec33205e8ad47', name: 'funny_falcon', wins: 51, losses: 57, playtime: 4486, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 35, userID: '54feee1ae950f7a707ec3461', sessionID: '5515d0933bdee5954e8246df', name: 'Khorrok', wins: 50, losses: 57, playtime: 387, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 36, userID: '54f7e04e8ec032e705abbcd8', sessionID: '550cc8eba605ba5a05120514', name: 'Tan Chuan Jie', wins: 50, losses: 58, playtime: 4787, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 36, userID: '551743df079f2833053c723a', sessionID: '5517582bd69ccd3305a29676', name: 'Majestik', wins: 50, losses: 58, playtime: 15118, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 38, userID: '55005eb295a4228105f6bfc3', sessionID: '550d0e699e22dc56056be203', name: '2SHAWN4YOU', wins: 49, losses: 59, playtime: 935, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 39, userID: '54dcf4ec7b4e13500586e511', sessionID: '5518609b5afdf53205577d82', name: 'Da5id', wins: 46, losses: 61, playtime: 711, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 40, userID: '550420ad2c5fbf7b056a18a0', sessionID: '550cffa5a605ba5a051205d4', name: 'YuanFeng', wins: 46, losses: 62, playtime: 5471, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 41, userID: '54f9cad2d12cf54d069d8465', sessionID: '550cc77d9e22dc56056bdfe8', name: 'abcdefguan', wins: 45, losses: 61, playtime: 4873, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 42, userID: '54f914455cb508f3058b6553', sessionID: '550d00759e22dc56056be0e0', name: 'KaiXFlare', wins: 45, losses: 63, playtime: 5578, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 42, userID: '5443c3609792f94d06eecbb3', sessionID: '5515afd91c3bb18709e26474', name: 'PiedotTaste', wins: 45, losses: 63, playtime: 503, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 44, userID: '53b9fa0194abf748058ea71a', sessionID: '55160678b77a16330597d2ea', name: 'UMD_Liquidator', wins: 44, losses: 64, playtime: 16710, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 45, userID: '550db4c425b6f688062cb7f5', sessionID: '5515bc21fd67e4b4095aae6e', name: 'coderg0d', wins: 43, losses: 65, playtime: 17150, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 46, userID: '53e5783d6c59f5340504a6e9', sessionID: '55162c77de8bc03205975793', name: 'YodaEater', wins: 42, losses: 66, playtime: 15075, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 47, userID: '539cec01ab5dfc3a05cbf2d2', sessionID: '55158457b8185a5205e172a7', name: 'matthewd', wins: 41, losses: 67, playtime: 2166, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 48, userID: '535d52e90f77a8470b782df4', sessionID: '551676f64d24212f059446b6', name: 'binarychase', wins: 40, losses: 68, playtime: 13148, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 49, userID: '54f9064ad12cf54d069d54a4', sessionID: '550cc7469e22dc56056bdfe3', name: 'hussain1998', wins: 39, losses: 69, playtime: 5516, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 49, userID: '539bb5b7ab5dfc3a05cae063', sessionID: '55216e3885fca531055424d6', name: 'DollarAkshay', wins: 39, losses: 69, playtime: 965, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 49, userID: '54cf001ead25d155057ec294', sessionID: '550cc77c9e22dc56056bdfe7', name: 'jasmineseah-17', wins: 39, losses: 69, playtime: 5260, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 52, userID: '55159c561a93145605a65360', sessionID: '55159cde99d51b55053609b4', name: 'PaulT', wins: 37, losses: 71, playtime: 2635, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 53, userID: '54ce3426c39305530570368c', sessionID: '5516a6c74d24212f05944ca9', name: 'Zenador', wins: 36, losses: 70, playtime: 6894, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 54, userID: '550493e2836beb81054ad1c2', sessionID: '551822bc81389437054e089d', name: 'MrWooly', wins: 36, losses: 72, playtime: 440, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 54, userID: '5501d57b3d219b9808c098e9', sessionID: '5517f863079f2833053c8413', name: 'Mouschti', wins: 36, losses: 72, playtime: 532, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 54, userID: '535a3dd5f3c9943f0a4ed434', sessionID: '551f45faed37b43005e2c85d', name: 'Chankorinman', wins: 36, losses: 72, playtime: 581, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 54, userID: '55156d00d792f354050c61ea', sessionID: '5519fe8c5afdf5320557e679', name: 'Pavel87', wins: 36, losses: 72, playtime: 1900, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 54, userID: '5305df9df269d92647ceb862', sessionID: '551a81c2c13fa03205251429', name: 'TimTam', wins: 36, losses: 72, playtime: 1773, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 59, userID: '54be1a95cfb4e9ab16128314', sessionID: '5516e7f758852c3405f487d2', name: 'Albertos', wins: 35, losses: 73, playtime: 335, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 59, userID: '54dddee006024d52057534a0', sessionID: '551a4d835cd6bae409521577', name: 'ryu.dy', wins: 35, losses: 73, playtime: 4247, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 61, userID: '548cf2d0457ef12c0922ce04', sessionID: '551680efc79ef1fd062b57df', name: 'Lee87', wins: 34, losses: 74, playtime: 243, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 61, userID: '54f00e7cbc22bc830591b375', sessionID: '55222ad6d06c12300505737e', name: 'Fame7', wins: 34, losses: 74, playtime: 880, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 61, userID: '527ba37865a2cf8339000efd', sessionID: '5516ea7758852c3405f48871', name: 'Elinus', wins: 34, losses: 74, playtime: 75, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 61, userID: '54b87f637755bf5405a600f7', sessionID: '551dfedc4c73053505269424', name: 'Anonymous', wins: 34, losses: 74, playtime: 531, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 61, userID: '55127452ee12f7580524512f', sessionID: '551c83fb4c73053505263a4e', name: 'Oxidis', wins: 34, losses: 74, playtime: 1526, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 61, userID: '54f94d77802189c30518184c', sessionID: '550cffdfa605ba5a051205d6', name: 'OblivionOverlord', wins: 34, losses: 74, playtime: 4130, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 67, userID: '5515d99c9f2b9c5305f56d5c', sessionID: '551ac6e24c7305350525bb5b', name: 'Anonymous', wins: 32, losses: 76, playtime: 5641, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 67, userID: '540219a742fb9c380ad1eae3', sessionID: '551618f253665d3005251ae0', name: 'shadowfire', wins: 32, losses: 76, playtime: 1105, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 69, userID: '5477bd26c439b9160865589f', sessionID: '5518a3a74c73053505253acf', name: 'anodinia', wins: 31, losses: 77, playtime: 231, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 69, userID: '53346ca2523566907564fd53', sessionID: '5522edd6c9e6fd33051496ed', name: 'Ksionc', wins: 31, losses: 77, playtime: 289, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 69, userID: '54f945e463684f2409c7d498', sessionID: '550cffe1a605ba5a051205d7', name: 'ItsBlitz', wins: 31, losses: 77, playtime: 4889, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 72, userID: '5513153fad27c0b705c2829e', sessionID: '5516bb70b77a16330597e6e0', name: 'iPick', wins: 30, losses: 78, playtime: 1109, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 72, userID: '53049f3350b42adb6e86e046', sessionID: '550cfffba605ba5a051205d8', name: 'gph004', wins: 30, losses: 78, playtime: 4679, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 74, userID: '536eeed3bf08a63905efdd8a', sessionID: '550c79bca98c9c7f05ab05be', name: 'basicer', wins: 28, losses: 77, playtime: 1199, codeLanguage: 'lua'}
|
||||
{team: 'humans', rank: 75, userID: '54623591da18079109220097', sessionID: '5518e6c01f12482609b47160', name: 'FreeKrad', wins: 29, losses: 79, playtime: 1384, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 75, userID: '54cc2cf2f20cb05105c3d036', sessionID: '551bf5b24c73053505260370', name: 'Mihai2015', wins: 29, losses: 79, playtime: 1415, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 75, userID: '550fe04ceb13a37c05136498', sessionID: '551ad43f5cd6bae409525096', name: 'FuzzicalLogic', wins: 29, losses: 79, playtime: 88327, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 75, userID: '52d81ab38133efa92e0000d0', sessionID: '5515a7091a93145605a65bd9', name: 'DamienG002', wins: 29, losses: 79, playtime: 1619, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 75, userID: '550161abf94fb5820504d6d9', sessionID: '551eb864d69ccd3305a4b4bd', name: 'Ien Clack', wins: 29, losses: 79, playtime: 610, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 75, userID: '55080de2190b7bba08dab219', sessionID: '551f459f9800ae33059c539f', name: 'Anonymous', wins: 29, losses: 79, playtime: 651, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 81, userID: '550fc1b5e8cfa180057bcf9a', sessionID: '551dbdb95afdf5320559095b', name: 'Jython', wins: 28, losses: 80, playtime: 965, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 81, userID: '551711f88bdcbad0074fb07e', sessionID: '552189d56a8b7c22069934a6', name: 'GJW1', wins: 28, losses: 80, playtime: 320, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 81, userID: '5391144f82f0bc470523c8ab', sessionID: '550cc74bca461f5705f3d144', name: 'Polaricicle', wins: 28, losses: 80, playtime: 5801, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 84, userID: '548ae4ddaed203880bc9d72d', sessionID: '55213f1c85fca53105541f99', name: 'Brizar', wins: 26, losses: 82, playtime: 1827, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 85, userID: '54fc40f847b0892406d7428c', sessionID: '550d004bca461f5705f3d1ed', name: 'galaxypantz', wins: 25, losses: 82, playtime: 3444, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 86, userID: '55196a90e3ae3a3505f7fdcd', sessionID: '55196b035afdf5320557b249', name: 'zbx', wins: 24, losses: 84, playtime: 4048, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 86, userID: '550d599a03cae479055c02bd', sessionID: '5516a33f58852c3405f47767', name: 'Ben0225', wins: 24, losses: 84, playtime: 6580, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 88, userID: '55158827bf2bea55051d0a0a', sessionID: '551da49c5afdf532055901df', name: 'kpbochenek', wins: 22, losses: 82, playtime: 798, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 89, userID: '547b41f59325e43e052e02a8', sessionID: '5515c3871a93145605a66b4b', name: 'Tamerlan4', wins: 23, losses: 84, playtime: 196, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 90, userID: '53880299d06c503805fdd57e', sessionID: '5519aeb2c13fa0320524f401', name: 'Дор', wins: 22, losses: 85, playtime: 177, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 91, userID: '550701ea75c0eb4a10ac7f4a', sessionID: '550d00bb9e22dc56056be0e5', name: 'Loh June Yong', wins: 22, losses: 86, playtime: 5443, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 92, userID: '52a8f5e7a9fb033114000f08', sessionID: '55158154f43d375105fbdcf8', name: 'Mpgod1234', wins: 21, losses: 86, playtime: 558, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 93, userID: '546e523a047aaa780854a46b', sessionID: '55087d90e810e35a09e335e8', name: 'Popey456963', wins: 21, losses: 87, playtime: 4724, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 94, userID: '54f114d51022997e054ea52b', sessionID: '551d30c8e3ae3a3505f91191', name: 'F_Deity_Link', wins: 20, losses: 87, playtime: 1324, codeLanguage: 'lua'}
|
||||
{team: 'humans', rank: 94, userID: '5515ffd982ee611b05aeb6f7', sessionID: '5516008aa174c81b05465604', name: 'Anonymous', wins: 20, losses: 87, playtime: 113, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 96, userID: '54fad0665d8ec82806aad9bf', sessionID: '550d00129e22dc56056be0d7', name: 'vanessatan', wins: 19, losses: 89, playtime: 5013, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 96, userID: '5487a14a4647d2b006cf7edd', sessionID: '551854a1e3ae3a3505f7c904', name: 'Endercore79', wins: 19, losses: 89, playtime: 769, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 96, userID: '53416ac43a7f7a6358b7029a', sessionID: '55166a794d24212f05944596', name: 'Lylo', wins: 19, losses: 89, playtime: 359, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 99, userID: '5470e99829e4c0710587df4c', sessionID: '5521b204abdb444805e883bb', name: 'Sthomas', wins: 18, losses: 89, playtime: 396, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 99, userID: '54f240e481f9a6750530ed0c', sessionID: '5516db0153665d3005253b4d', name: 'Bosdet', wins: 18, losses: 89, playtime: 5448, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 101, userID: '5495c837fcf9386d07d30866', sessionID: '550c73e1a98c9c7f05ab03ac', name: 'awesome3000', wins: 18, losses: 90, playtime: 2586, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 102, userID: '54c3a0aa83b9575305363fbd', sessionID: '5515f79482ee611b05aeb454', name: 'ninja_star', wins: 17, losses: 90, playtime: 423, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 103, userID: '54cbaa236947cf5405dab7e4', sessionID: '550cd526ca461f5705f3d1a0', name: 'hannie', wins: 16, losses: 90, playtime: 2400, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 104, userID: '550cc15b0f7e6ece0684a2d4', sessionID: '550cc195fa4ee5e0062ed84d', name: 'The AI', wins: 15, losses: 92, playtime: 385, codeLanguage: 'clojure'}
|
||||
{team: 'humans', rank: 105, userID: '546656d5f5522b9805dfd4ca', sessionID: '551f09a0921f633305d4d7d8', name: '1234526', wins: 15, losses: 93, playtime: 909, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 106, userID: '5500418620b2567d0514b763', sessionID: '550d0037a605ba5a051205da', name: 'luxedlyani', wins: 14, losses: 94, playtime: 5487, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 106, userID: '532795fcd2a31ed46c63770e', sessionID: '55205354be496e310568fe50', name: 'kevbot', wins: 14, losses: 94, playtime: 2118, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 108, userID: '53de2603f9fd4335057a50ca', sessionID: '551632595ab8ae3105cad77a', name: 'Sunnyau', wins: 12, losses: 96, playtime: 9882, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 109, userID: '550aa9c9c731583007335e14', sessionID: '55158850d792f354050c7eb5', name: 'Anonymous', wins: 11, losses: 97, playtime: 137, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 110, userID: '551095ad3ab45d7d05d0290f', sessionID: '55209eeed06c123005054edf', name: 'The Dark Slayer 365', wins: 10, losses: 98, playtime: 695, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 111, userID: '5519cb4ae3ae3a3505f828fe', sessionID: '551a570dd69ccd3305a34080', name: 'weiyun', wins: 9, losses: 99, playtime: 2574, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 112, userID: '551285ff39ac155805f4aa0a', sessionID: '551e83bee311d80c07b35d46', name: 'M. Vincent', wins: 8, losses: 100, playtime: 6127, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 113, userID: '54f62d7d50181a8505f97e1d', sessionID: '551f1f29526d5e3505807c00', name: 'Oscha Esservic', wins: 0, losses: 108, playtime: 386, codeLanguage: 'javascript'}
|
||||
{team: 'humans', rank: 113, userID: '52cfa17ec0e2ea5d17001149', sessionID: '551716f258852c3405f49269', name: 'DarkLynk', wins: 0, losses: 108, playtime: 189, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 113, userID: '54f1f2f89bc914830528271f', sessionID: '550cc75a9e22dc56056bdfe4', name: 'Reilord', wins: 0, losses: 108, playtime: 4752, codeLanguage: 'python'}
|
||||
{team: 'humans', rank: 113, userID: '54aab1313feb6a3f05f20854', sessionID: '551c82a25cd6bae409530abb', name: 'Flamethowerland', wins: 0, losses: 108, playtime: 506, codeLanguage: 'python'}
|
||||
]
|
||||
|
||||
results['zero-sum'].ogres = [
|
||||
{team: 'ogres', rank: 1, userID: '532dbc73a622924444b68ed9', sessionID: '551599a499d51b55053606f2', name: 'Wizard Dude', wins: 162, losses: 1, playtime: 43223, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 2, userID: '54ffc9b8a043d19b0a457309', sessionID: '551e1a2ae3ae3a3505f96090', name: 'xxx987654321', wins: 157, losses: 5, playtime: 11649, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 3, userID: '531c8c3ccf439d790a23af04', sessionID: '550c2f5c1cd64bb7050fc8e5', name: 'nemoyatpeace', wins: 153, losses: 9, playtime: 4171, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 4, userID: '54ccc53ab4fb475505282187', sessionID: '55168b6353665d3005252860', name: 'ImDev', wins: 152, losses: 10, playtime: 4842, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 5, userID: '551995ec5cd6bae40951dec9', sessionID: '5519969e5cd6bae40951df59', name: 'wrdctr', wins: 151, losses: 11, playtime: 22070, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 5, userID: '54d9a5d2a9bd9f57050fe822', sessionID: '550c48b13045b78405c96775', name: 'Vlevo', wins: 151, losses: 11, playtime: 41246, codeLanguage: 'clojure'}
|
||||
{team: 'ogres', rank: 7, userID: '548b8c556c32e64e1c437957', sessionID: '551625ac5ab8ae3105cad65f', name: 'Nisha Noire', wins: 150, losses: 12, playtime: 6977, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 7, userID: '551824a31f12482609b44fad', sessionID: '55185272d69ccd3305a2ba9d', name: 'Ovrmrrw', wins: 150, losses: 12, playtime: 4139, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 9, userID: '5503ac1a2c5fbf7b056a0eff', sessionID: '551766524c7305350525145f', name: 'David C Ellis', wins: 147, losses: 14, playtime: 5804, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 10, userID: '5452ed0623ef1e5d089d31e2', sessionID: '55164ac8de8bc0320597591e', name: 'Vivaldi', wins: 146, losses: 15, playtime: 20229, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 11, userID: '52debd1b5432dcf11c000164', sessionID: '55162fc358852c3405f468f6', name: 'Agathanar', wins: 144, losses: 18, playtime: 13849, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 12, userID: '55169fb1de8bc03205976007', sessionID: '5516bbd7aedec33205e8b3c4', name: 'XN137', wins: 140, losses: 22, playtime: 44494, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 13, userID: '55172d51502e8b37053130b2', sessionID: '551840461f12482609b45518', name: 'Sean653', wins: 140, losses: 23, playtime: 5501, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 14, userID: '5512ef72a4febf5905274f07', sessionID: '551851355afdf53205577ac4', name: 'Vincent Maths', wins: 137, losses: 25, playtime: 2812, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 15, userID: '526a4e91c0a4f3a21f000c50', sessionID: '5516728baedec33205e8a5b9', name: 'spicydog', wins: 133, losses: 28, playtime: 3790, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 16, userID: '5511931af72de65605f988b4', sessionID: '5515a3e3bf2bea55051d2225', name: 'Deipablo', wins: 130, losses: 32, playtime: 9331, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 17, userID: '5515b4e1fd67e4b4095aaa5f', sessionID: '5515c034d792f354050ca69e', name: 'i_eet_leefs', wins: 128, losses: 34, playtime: 158, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 18, userID: '54ab32c13feb6a3f05f55e94', sessionID: '5515debc64a969570abf9827', name: 'SaladTongs', wins: 125, losses: 37, playtime: 26496, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 19, userID: '54cb0fbd0623615605392f74', sessionID: '550cc86d9e22dc56056bdfec', name: 'Dragernix', wins: 124, losses: 38, playtime: 4365, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 19, userID: '54f609476b0774880597fdd4', sessionID: '55171a58b77a16330597f89e', name: 'Danylo Dubinin', wins: 124, losses: 38, playtime: 6951, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 21, userID: '549aed0eb530133e053a3acc', sessionID: '55159f149f2b9c5305f551a0', name: 'Spencer Tachick', wins: 123, losses: 39, playtime: 12292, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 21, userID: '5507e6c8e7d9907b054a61e9', sessionID: '55167b894d24212f05944728', name: 'NormannK', wins: 123, losses: 39, playtime: 9490, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 23, userID: '549b8ead1880d5b7065ff57c', sessionID: '55161e90aedec33205e89e2c', name: 'Dymarr', wins: 116, losses: 46, playtime: 281, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 24, userID: '53ca0f0aaa30cd860586b24f', sessionID: '5521bf1b32954a32050203ba', name: 'Edgar', wins: 115, losses: 47, playtime: 4999, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 25, userID: '54fdacd0106d15f105fc7d4c', sessionID: '550cfffbca461f5705f3d1ec', name: 'Midhat', wins: 114, losses: 48, playtime: 5557, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 26, userID: '54f5d94c9be7567905e95099', sessionID: '551d1124d69ccd3305a43329', name: 's_a_n_d', wins: 114, losses: 49, playtime: 3905, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 27, userID: '5515ff2482ee611b05aeb6c6', sessionID: '5515ff641bfec61c050245ab', name: 'Carl Maxwell', wins: 113, losses: 48, playtime: 10208, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 28, userID: '55066eefce02078605ce9126', sessionID: '550d29999e22dc56056be28a', name: 'Koyint', wins: 113, losses: 49, playtime: 524, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 29, userID: '5517d8b0e3ae3a3505f7b73d', sessionID: '5517de29079f2833053c8108', name: 'aknopf', wins: 113, losses: 50, playtime: 203, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 30, userID: '54ffbe6ee950f7a707ec9577', sessionID: '550cc7bc9e22dc56056bdfe9', name: 'chuayupeng', wins: 112, losses: 50, playtime: 4602, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 31, userID: '5506889b127bb387059def67', sessionID: '550d001435dc145905672238', name: 'En Hao', wins: 111, losses: 51, playtime: 5234, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 32, userID: '527bdd42dd3c4aea37001500', sessionID: '55159c75b8185a5205e183dc', name: 'Makaze', wins: 109, losses: 53, playtime: 2213, codeLanguage: 'coffeescript'}
|
||||
{team: 'ogres', rank: 33, userID: '55181575e3ae3a3505f7bf46', sessionID: '55191d035afdf532055796d6', name: 'Satellite One', wins: 106, losses: 51, playtime: 16911, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 34, userID: '54b1773a75e3055205e5a449', sessionID: '550c3a98535111cc0539a3f9', name: 'Catsync', wins: 107, losses: 54, playtime: 381, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 35, userID: '53a0bc84610a6b3505561811', sessionID: '5516185f53665d3005251ac7', name: 'Fluzzarn', wins: 102, losses: 60, playtime: 1835, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 36, userID: '5516bf048bdcbad0074f9c29', sessionID: '5516d0a258852c3405f481da', name: 'Expote2', wins: 100, losses: 62, playtime: 4576, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 37, userID: '54ff5e1a00e4485a07e76bb9', sessionID: '5515ac67fd67e4b4095aa52f', name: 'Twonky', wins: 96, losses: 66, playtime: 6772, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 38, userID: '550003910f91fab20b3624e8', sessionID: '550d00439e22dc56056be0de', name: 'CyanLycan', wins: 95, losses: 66, playtime: 5482, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 39, userID: '54f2b39381f9a6750530f893', sessionID: '550ccb259e22dc56056be001', name: 'Flamanta', wins: 95, losses: 68, playtime: 4734, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 40, userID: '54f0775615cde87c05d6caf4', sessionID: '550cc7ef35dc1459056721be', name: 'Jericho Chua', wins: 93, losses: 69, playtime: 4409, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 41, userID: '539bfd0930a67c3b05d93f2a', sessionID: '55158a0bf43d375105fbe4ec', name: 'reezer', wins: 93, losses: 70, playtime: 5116, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 42, userID: '54d2c4024e4a08550556e01c', sessionID: '550cd3269e22dc56056be050', name: 'Alaete', wins: 92, losses: 69, playtime: 1804, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 43, userID: '53e2f1046c59f534050411f3', sessionID: '550d000e35dc145905672236', name: 'Live2Deliver', wins: 91, losses: 71, playtime: 5362, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 44, userID: '5517858d079f2833053c79a7', sessionID: '551786c7e3ae3a3505f7b0f6', name: 'Kevbot5000', wins: 88, losses: 72, playtime: 93126, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 45, userID: '54f3527fde0f173f14215f40', sessionID: '552210f33ffd333305f2e9b5', name: 'Anonymous', wins: 88, losses: 73, playtime: 346, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 46, userID: '55184fc7c13fa0320524a596', sessionID: '5518516ac13fa0320524a5f1', name: 'Mossan', wins: 85, losses: 77, playtime: 11842, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 47, userID: '539bb1d46e1d92310506ec6b', sessionID: '551ab214d69ccd3305a35b6c', name: 'Belackarad', wins: 84, losses: 78, playtime: 2921, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 48, userID: '534316e1d9a976607ace1f48', sessionID: '5518c7954c73053505253f23', name: 'Racksickle', wins: 84, losses: 79, playtime: 4118, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 49, userID: '5515b3d599d51b55053619e3', sessionID: '5517f05fe3ae3a3505f7b998', name: 'Crul', wins: 82, losses: 81, playtime: 99, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 50, userID: '548bc8bdcb1a6d754f530ef9', sessionID: '5518c2a0d69ccd3305a2cd93', name: 'MonkeykingZach1', wins: 80, losses: 82, playtime: 2904, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 51, userID: '54ea122b6a05ed9a0803f20b', sessionID: '55181b4de3ae3a3505f7c028', name: 'All3ck', wins: 77, losses: 84, playtime: 16269, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 52, userID: '5522bf863ffd333305f30ef5', sessionID: '5522c90cabdb444805e8c0b9', name: 'Fireball42', wins: 73, losses: 87, playtime: 3431, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 53, userID: '5514a8636b06ed1e09bc4c01', sessionID: '55204b8ffe6383360550157d', name: 'Hephaestus2', wins: 73, losses: 89, playtime: 1162, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 54, userID: '539189a2ff512d470582a570', sessionID: '550cc7f3a605ba5a0512050f', name: 'Lee Yang Peng', wins: 72, losses: 88, playtime: 5743, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 55, userID: '546e31004a0dd3de07f2b3f0', sessionID: '5515a3c3518f4e1409379f15', name: 'Blauelf', wins: 72, losses: 91, playtime: 119, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 56, userID: '55125f4ba4febf590526f3ea', sessionID: '551a8d32d69ccd3305a34b40', name: 'Yan4ik', wins: 71, losses: 91, playtime: 7018, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 57, userID: '54cba6498a09e554056f7e83', sessionID: '550cce4f9e22dc56056be01a', name: 'Skyhawk5', wins: 70, losses: 92, playtime: 1415, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 58, userID: '550126ad9201157c05677836', sessionID: '550d003ba605ba5a051205dc', name: 'ohichimaru', wins: 66, losses: 96, playtime: 5118, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 59, userID: '54ea04ede90cfb5005381cae', sessionID: '550d00bc9e22dc56056be0e6', name: 'fafazirah', wins: 65, losses: 98, playtime: 2494, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 60, userID: '54fd92b847b0892406d76ee6', sessionID: '550d015d9e22dc56056be0f2', name: 'Soon Wei', wins: 64, losses: 98, playtime: 5270, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 61, userID: '537d66783dcf67c40571fce9', sessionID: '550976d42e7f640f07bf7cbc', name: 'ProfBoesch', wins: 61, losses: 101, playtime: 2684, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 62, userID: '54ef1ac12fd7dd55052b4bf6', sessionID: '550cc78ea605ba5a0512050d', name: 'ZoppyOS', wins: 60, losses: 101, playtime: 5566, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 63, userID: '54f1e0f2d2969f8405ef6e93', sessionID: '550d03639e22dc56056be123', name: 'hongyue1995', wins: 57, losses: 104, playtime: 3402, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 64, userID: '53b54cda7e17883a0575767a', sessionID: '5515bde81c3bb18709e26cd3', name: 'JavaCaster1', wins: 55, losses: 106, playtime: 91, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 65, userID: '54e3389fab6f345305701d9d', sessionID: '550d003a35dc145905672239', name: 'Aswin A', wins: 54, losses: 108, playtime: 4830, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 66, userID: '53b8f7ab3a63df45051b31d6', sessionID: '551ff648b10646310516d109', name: 'Elizabeth20', wins: 46, losses: 117, playtime: 3329, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 67, userID: '54f82214cebfc7450c16bbe9', sessionID: '550cc7f49e22dc56056bdfeb', name: 'Chaoxide', wins: 45, losses: 118, playtime: 5296, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 68, userID: '54fa96ce9ae7221e0672306b', sessionID: '550cc7e29e22dc56056bdfea', name: 'Xyrilyn', wins: 41, losses: 121, playtime: 5516, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 69, userID: '54f420d8c43ea77705a27522', sessionID: '550cc78535dc1459056721bd', name: 'WangLu', wins: 40, losses: 122, playtime: 5460, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 70, userID: '54a976c1b9a10c3e059a5414', sessionID: '551c623f8328b9020decd431', name: 'germ13', wins: 35, losses: 127, playtime: 4753, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 71, userID: '52619a3e99987a8a0900009e', sessionID: '5516d34058852c3405f48284', name: 'iTruth', wins: 35, losses: 128, playtime: 5077, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 72, userID: '55197724e3ae3a3505f80446', sessionID: '551977265cd6bae40951cafb', name: 'Stowned', wins: 30, losses: 133, playtime: 1594, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 73, userID: '546e6be7da3c21f30848d235', sessionID: '551c5c0c1794dc1a112c536c', name: 'Jonas5', wins: 28, losses: 135, playtime: 663, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 73, userID: '55098a62a2012e800a354350', sessionID: '551dae53e3ae3a3505f94fb9', name: 'coding6', wins: 28, losses: 135, playtime: 66, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 73, userID: '54f160550ac4bd7c05458e7e', sessionID: '55166f02aedec33205e8a541', name: 'Dima2006', wins: 28, losses: 135, playtime: 61, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 76, userID: '54f8b3237a5c02820877960e', sessionID: '551aec19e3ae3a3505f87585', name: 'JakeWolt20', wins: 28, losses: 136, playtime: 34, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 77, userID: '54c6a197c597612313ca1520', sessionID: '5519a05c4c7305350525799e', name: 'maxx89', wins: 27, losses: 136, playtime: 408, codeLanguage: 'javascript'}
|
||||
{team: 'ogres', rank: 78, userID: '550cc15b0f7e6ece0684a2d4', sessionID: '550cc20735f6fd2807b877ae', name: 'The AI', wins: 24, losses: 135, playtime: 128, codeLanguage: 'clojure'}
|
||||
{team: 'ogres', rank: 79, userID: '54903e1e6f2e23450a4fd7ac', sessionID: '5519e6bc8328b9020debf33f', name: 'kev0', wins: 15, losses: 147, playtime: 3459, codeLanguage: 'python'}
|
||||
{team: 'ogres', rank: 80, userID: '54fe734f834d927905307753', sessionID: '5515cefa1a93145605a66f9e', name: 'Anonymous', wins: 14, losses: 149, playtime: 1002, codeLanguage: 'python'}
|
||||
]
|
||||
|
|
|
@ -20,6 +20,7 @@ ShareProgressModal = require 'views/play/modal/ShareProgressModal'
|
|||
UserPollsRecord = require 'models/UserPollsRecord'
|
||||
Poll = require 'models/Poll'
|
||||
PollModal = require 'views/play/modal/PollModal'
|
||||
storage = require 'core/storage'
|
||||
|
||||
trackedHourOfCode = false
|
||||
|
||||
|
@ -148,10 +149,11 @@ module.exports = class CampaignView extends RootView
|
|||
@render()
|
||||
@preloadTopHeroes() unless me.get('heroConfig')?.thangType
|
||||
@$el.find('#campaign-status').delay(4000).animate({top: "-=58"}, 1000) unless @terrain is 'dungeon'
|
||||
if @terrain and me.get('name') and me.get('lastLevel') in ['forgetful-gemsmith', 'signs-and-portents']
|
||||
if @terrain and me.get('anonymous') and me.get('lastLevel') is 'shadow-guard' and me.level() < 4
|
||||
@openModalView new AuthModal supermodel: @supermodel, showSignupRationale: true, mode: 'signup'
|
||||
else if @terrain and me.get('name') and me.get('lastLevel') in ['forgetful-gemsmith', 'signs-and-portents'] and me.level() < 5 and not (me.get('ageRange') in ['18-24', '25-34', '35-44', '45-100']) and not storage.load('sent-parent-email')
|
||||
@openModalView new ShareProgressModal()
|
||||
|
||||
|
||||
setCampaign: (@campaign) ->
|
||||
@render()
|
||||
|
||||
|
@ -198,7 +200,7 @@ module.exports = class CampaignView extends RootView
|
|||
|
||||
if @campaigns
|
||||
context.campaigns = {}
|
||||
for campaign in @campaigns.models
|
||||
for campaign in @campaigns.models when campaign.get('slug') isnt 'auditions'
|
||||
context.campaigns[campaign.get('slug')] = campaign
|
||||
if @sessions.loaded
|
||||
levels = _.values($.extend true, {}, campaign.get('levels') ? {})
|
||||
|
@ -276,10 +278,14 @@ module.exports = class CampaignView extends RootView
|
|||
|
||||
countLevels: (levels) ->
|
||||
count = total: 0, completed: 0
|
||||
for level in levels
|
||||
for level, levelIndex in levels
|
||||
@annotateLevel level unless level.locked? # Annotate if we haven't already.
|
||||
unless level.disabled
|
||||
++count.total
|
||||
unlockedInSameCampaign = levelIndex < 5 # First few are always counted (probably unlocked in previous campaign)
|
||||
for otherLevel in levels when not unlockedInSameCampaign and otherLevel isnt level
|
||||
for reward in (otherLevel.rewards ? []) when reward.level
|
||||
unlockedInSameCampaign ||= reward.level is level.original
|
||||
++count.total if unlockedInSameCampaign or not level.locked
|
||||
++count.completed if @levelStatusMap[level.slug] is 'complete'
|
||||
count
|
||||
|
||||
|
@ -295,7 +301,12 @@ module.exports = class CampaignView extends RootView
|
|||
unless foundNext
|
||||
for nextLevelOriginal in level.nextLevels
|
||||
nextLevel = _.find levels, original: nextLevelOriginal
|
||||
if nextLevel and not nextLevel.locked and @levelStatusMap[nextLevel.slug] isnt 'complete' and (me.isPremium() or not nextLevel.requiresSubscription or nextLevel.slug is 'apocalypse')
|
||||
if nextLevel and not nextLevel.locked and @levelStatusMap[nextLevel.slug] isnt 'complete' and (
|
||||
me.isPremium() or
|
||||
not nextLevel.requiresSubscription or
|
||||
nextLevel.slug is 'apocalypse' or
|
||||
(nextLevel.slug is 'favorable-odds' and not @levelStatusMap['the-raised-sword'])
|
||||
)
|
||||
nextLevel.next = true
|
||||
foundNext = true
|
||||
break
|
||||
|
@ -334,7 +345,7 @@ module.exports = class CampaignView extends RootView
|
|||
@particleMan ?= new ParticleMan()
|
||||
@particleMan.removeEmitters()
|
||||
@particleMan.attach @$el.find('.map')
|
||||
for level in @campaign.renderedLevels ? {} when level.hidden or level.slug is 'apocalypse'
|
||||
for level in @campaign.renderedLevels ? {} when level.hidden or (level.slug is 'apocalypse' and @levelStatusMap[level.slug] isnt 'complete')
|
||||
particleKey = ['level', @terrain]
|
||||
particleKey.push level.type if level.type and level.type isnt 'hero'
|
||||
particleKey.push 'premium' if level.requiresSubscription
|
||||
|
@ -433,7 +444,7 @@ module.exports = class CampaignView extends RootView
|
|||
level = _.find _.values(@campaign.get('levels')), slug: levelSlug
|
||||
|
||||
requiresSubscription = level.requiresSubscription or (me.get('chinaVersion') and not (level.slug in ['dungeons-of-kithgard', 'gems-in-the-deep', 'shadow-guard', 'forgetful-gemsmith', 'signs-and-portents', 'true-names']))
|
||||
canPlayAnyway = not @requiresSubscription or level.adventurer
|
||||
canPlayAnyway = not @requiresSubscription or level.adventurer or @levelStatusMap[level.slug]
|
||||
if requiresSubscription and not canPlayAnyway
|
||||
@openModalView new SubscribeModal()
|
||||
window.tracker?.trackEvent 'Show subscription modal', category: 'Subscription', label: 'map level clicked', level: levelSlug
|
||||
|
|
|
@ -26,6 +26,7 @@ module.exports = class HeroVictoryModal extends ModalView
|
|||
'click .leaderboard-button': 'onClickLeaderboard'
|
||||
'click .return-to-ladder-button': 'onClickReturnToLadder'
|
||||
'click .sign-up-button': 'onClickSignupButton'
|
||||
'click .continue-from-offer-button': 'onClickContinueFromOffer'
|
||||
|
||||
constructor: (options) ->
|
||||
super(options)
|
||||
|
@ -339,7 +340,11 @@ module.exports = class HeroVictoryModal extends ModalView
|
|||
justBeatLevel: @level
|
||||
supermodel: if @options.hasReceivedMemoryWarning then null else @supermodel
|
||||
_.merge options, extraOptions if extraOptions
|
||||
Backbone.Mediator.publish 'router:navigate', route: nextLevelLink, viewClass: require('views/play/CampaignView'), viewArgs: [options, @getNextLevelCampaign()]
|
||||
navigationEvent = route: nextLevelLink, viewClass: require('views/play/CampaignView'), viewArgs: [options, @getNextLevelCampaign()]
|
||||
if @level.get('slug') is 'lost-viking' and not (me.get('age') in ['0-13', '14-17'])
|
||||
@showOffer navigationEvent
|
||||
else
|
||||
Backbone.Mediator.publish 'router:navigate', navigationEvent
|
||||
|
||||
onClickLeaderboard: (e) ->
|
||||
@onClickContinue e, showLeaderboard: true
|
||||
|
@ -355,3 +360,14 @@ module.exports = class HeroVictoryModal extends ModalView
|
|||
e.preventDefault()
|
||||
window.tracker?.trackEvent 'Started Signup', category: 'Play Level', label: 'Hero Victory Modal', level: @level.get('slug')
|
||||
@openModalView new AuthModal {mode: 'signup'}
|
||||
|
||||
showOffer: (@navigationEventUponCompletion) ->
|
||||
@$el.find('.modal-footer > *').hide()
|
||||
@$el.find(".modal-footer > .offer.#{@level.get('slug')}").show()
|
||||
|
||||
onClickContinueFromOffer: (e) ->
|
||||
url = {
|
||||
'lost-viking': 'http://www.vikingcodeschool.com/codecombat?utm_source=codecombat&utm_medium=viking_level&utm_campaign=affiliate&ref=Code+Combat+Elite'
|
||||
}[@level.get('slug')]
|
||||
Backbone.Mediator.publish 'router:navigate', @navigationEventUponCompletion
|
||||
window.open url, '_blank' if url
|
||||
|
|
|
@ -154,7 +154,7 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView
|
|||
break
|
||||
$codearea = $('#code-area')
|
||||
$codearea.on transitionListener, =>
|
||||
$codearea.css 'z-index', 1 unless $('html').hasClass 'fullscreen-editor'
|
||||
$codearea.css 'z-index', 2 unless $('html').hasClass 'fullscreen-editor'
|
||||
|
||||
|
||||
destroy: ->
|
||||
|
|
|
@ -19,7 +19,9 @@ module.exports = class LeaderboardModal extends ModalView
|
|||
constructor: (options) ->
|
||||
super options
|
||||
@levelSlug = @options.levelSlug
|
||||
@level = @supermodel.loadModel(new Level({_id: @levelSlug}, {project: ['name', 'i18n', 'scoreType', 'original']}), 'level').model
|
||||
level = new Level({_id: @levelSlug})
|
||||
level.project = ['name', 'i18n', 'scoreType', 'original']
|
||||
@level = @supermodel.loadModel(level, 'level').model
|
||||
|
||||
getRenderData: (c) ->
|
||||
c = super c
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
ModalView = require 'views/core/ModalView'
|
||||
template = require 'templates/play/modal/share-progress-modal'
|
||||
storage = require 'core/storage'
|
||||
|
||||
module.exports = class SubscribeModal extends ModalView
|
||||
id: 'share-progress-modal'
|
||||
|
@ -8,33 +9,9 @@ module.exports = class SubscribeModal extends ModalView
|
|||
closesOnClickOutside: false
|
||||
|
||||
events:
|
||||
'click .back-link': 'onBackClick'
|
||||
'click .close-btn': 'hide'
|
||||
'click .continue-link': 'hide'
|
||||
'click .send-btn': 'onClickSend'
|
||||
'click .tell-friend-btn': 'onClickTellFriend'
|
||||
'click .tell-parent-btn': 'onClickTellParent'
|
||||
|
||||
onBackClick: (e) ->
|
||||
$('.email-input').val('')
|
||||
$('.send-container').hide()
|
||||
$('.friend-blurb').hide()
|
||||
$('.parent-blurb').hide()
|
||||
$('.btn-picker-container').show()
|
||||
$('.email-input').parent().removeClass('has-error')
|
||||
$('.email-invalid').hide()
|
||||
|
||||
onClickTellFriend: (e) ->
|
||||
@emailType = 'share progress modal friend'
|
||||
$('.btn-picker-container').hide()
|
||||
$('.friend-blurb').show()
|
||||
$('.send-container').show()
|
||||
|
||||
onClickTellParent: (e) ->
|
||||
@emailType = 'share progress modal parent'
|
||||
$('.btn-picker-container').hide()
|
||||
$('.parent-blurb').show()
|
||||
$('.send-container').show()
|
||||
|
||||
onClickSend: (e) ->
|
||||
email = $('.email-input').val()
|
||||
|
@ -45,9 +22,10 @@ module.exports = class SubscribeModal extends ModalView
|
|||
|
||||
request = @supermodel.addRequestResource 'send_one_time_email', {
|
||||
url: '/db/user/-/send_one_time_email'
|
||||
data: {email: email, type: @emailType}
|
||||
data: {email: email, type: 'share progress modal parent'}
|
||||
method: 'POST'
|
||||
}, 0
|
||||
request.load()
|
||||
|
||||
storage.save 'sent-parent-email', true
|
||||
@hide()
|
||||
|
|
|
@ -199,6 +199,8 @@ exports.config =
|
|||
sass:
|
||||
mode: 'ruby'
|
||||
allowCache: true
|
||||
bless:
|
||||
cacheBuster: false
|
||||
|
||||
modules:
|
||||
definition: (path, data) ->
|
||||
|
|
|
@ -206,13 +206,15 @@ module.exports = class Handler
|
|||
return @sendForbiddenError(res)
|
||||
|
||||
getById: (req, res, id) ->
|
||||
# return @sendNotFoundError(res) # for testing
|
||||
return @sendForbiddenError(res) unless @hasAccess(req)
|
||||
|
||||
@getDocumentForIdOrSlug id, (err, document) =>
|
||||
if req.query.project
|
||||
projection = {}
|
||||
projection[field] = 1 for field in req.query.project.split(',')
|
||||
@getDocumentForIdOrSlug id, projection, (err, document) =>
|
||||
return @sendDatabaseError(res, err) if err
|
||||
return @sendNotFoundError(res) unless document?
|
||||
return @sendForbiddenError(res) unless @hasAccessToDocument(req, document)
|
||||
res.setHeader 'Cache-Control', 'no-cache' unless Handler.isID(id + '') # Don't cache if it's a slug instead of an ID
|
||||
@sendSuccess(res, @formatEntity(req, document))
|
||||
|
||||
getByRelationship: (req, res, args...) ->
|
||||
|
@ -490,14 +492,18 @@ module.exports = class Handler
|
|||
|
||||
@isID: (id) -> _.isString(id) and id.length is 24 and id.match(/[a-f0-9]/gi)?.length is 24
|
||||
|
||||
getDocumentForIdOrSlug: (idOrSlug, done) ->
|
||||
getDocumentForIdOrSlug: (idOrSlug, projection, done) ->
|
||||
unless done
|
||||
done = projection # projection is optional argument
|
||||
projection = null
|
||||
idOrSlug = idOrSlug+''
|
||||
if Handler.isID(idOrSlug)
|
||||
@modelClass.findById(idOrSlug).exec (err, document) ->
|
||||
done(err, document)
|
||||
query = @modelClass.findById(idOrSlug)
|
||||
else
|
||||
@modelClass.findOne {slug: idOrSlug}, (err, document) ->
|
||||
done(err, document)
|
||||
query = @modelClass.findOne {slug: idOrSlug}
|
||||
query.select projection if projection
|
||||
query.exec (err, document) ->
|
||||
done(err, document)
|
||||
|
||||
doWaterfallChecks: (req, document, done) ->
|
||||
return done(null, document) unless @waterfallFunctions.length
|
||||
|
|
|
@ -158,7 +158,8 @@ LevelHandler = class LevelHandler extends Handler
|
|||
majorVersion: level.version.major
|
||||
creator: req.user._id+''
|
||||
|
||||
query = Session.find(sessionQuery).select('-screenshot')
|
||||
query = Session.find(sessionQuery).select('-screenshot -transpiledCode')
|
||||
# TODO: take out "code" as well, since that can get huge containing the transpiled code for the lat hero, and find another way of having the LadderSubmissionViews in the MyMatchesTab determine rankin readiness
|
||||
query.exec (err, results) =>
|
||||
if err then @sendDatabaseError(res, err) else @sendSuccess res, results
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class LevelSessionHandler extends Handler
|
|||
if req.user?.isAdmin() or
|
||||
req.user?.id is document.creator or
|
||||
('employer' in (req.user?.get('permissions') ? [])) or
|
||||
!document.submittedCode # TODO: only allow leaderboard access to non-top-5 solutions
|
||||
not document.submittedCode # TODO: only allow leaderboard access to non-top-5 solutions
|
||||
return documentObject
|
||||
else
|
||||
return _.omit documentObject, @privateProperties
|
||||
|
@ -53,6 +53,7 @@ class LevelSessionHandler extends Handler
|
|||
get = (method ? req.method).toLowerCase() is 'get'
|
||||
return true if get and document.get('submitted')
|
||||
return true if get and ('employer' in (req.user?.get('permissions') ? []))
|
||||
return true if get and not document.get('submittedCode') # Allow leaderboard access to non-multiplayer sessions
|
||||
super(arguments...)
|
||||
|
||||
getCodeLanguageCounts: (req, res) ->
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Not paired with a document in the DB, just handles coordinating between
|
||||
# the stripe property in the user with what's being stored in Stripe.
|
||||
|
||||
mongoose = require 'mongoose'
|
||||
async = require 'async'
|
||||
config = require '../../server_config'
|
||||
Handler = require '../commons/Handler'
|
||||
|
@ -23,9 +24,70 @@ class SubscriptionHandler extends Handler
|
|||
console.warn "Subscription Error: #{user.get('slug')} (#{user._id}): '#{msg}'"
|
||||
|
||||
getByRelationship: (req, res, args...) ->
|
||||
return @getSubscribers(req, res) if args[1] is 'subscribers'
|
||||
return @getSubscriptions(req, res) if args[1] is 'subscriptions'
|
||||
super(arguments...)
|
||||
|
||||
getSubscribers: (req, res) ->
|
||||
return @sendForbiddenError(res) unless req.user and req.user.isAdmin()
|
||||
|
||||
maxReturnCount = req.body.maxCount or 20
|
||||
|
||||
# @subscribers ?= []
|
||||
# return @sendSuccess(res, @subscribers) unless _.isEmpty(@subscribers)
|
||||
@subscribers = []
|
||||
|
||||
subscriberIDs = []
|
||||
|
||||
customersProcessed = 0
|
||||
nextBatch = (starting_after, done) =>
|
||||
options = limit: 100
|
||||
options.starting_after = starting_after if starting_after
|
||||
stripe.customers.list options, (err, customers) =>
|
||||
return done(err) if err
|
||||
customersProcessed += customers.data.length
|
||||
|
||||
for customer in customers.data
|
||||
break unless @subscribers.length < maxReturnCount
|
||||
continue unless customer?.subscriptions?.data?.length > 0
|
||||
for subscription in customer.subscriptions.data
|
||||
continue unless subscription.plan.id is 'basic'
|
||||
|
||||
amount = subscription.plan.amount
|
||||
if subscription?.discount?.coupon?
|
||||
if subscription.discount.coupon.percent_off
|
||||
amount = amount * (100 - subscription.discount.coupon.percent_off) / 100;
|
||||
else if subscription.discount.coupon.amount_off
|
||||
amount -= subscription.discount.coupon.amount_off
|
||||
else if customer.discount?.coupon?
|
||||
if customer.discount.coupon.percent_off
|
||||
amount = amount * (100 - customer.discount.coupon.percent_off) / 100
|
||||
else if customer.discount.coupon.amount_off
|
||||
amount -= customer.discount.coupon.amount_off
|
||||
|
||||
continue unless amount > 0
|
||||
|
||||
subscriber = start: new Date(subscription.start * 1000)
|
||||
if subscription.metadata?.id?
|
||||
subscriber.userID = subscription.metadata.id
|
||||
subscriberIDs.push subscription.metadata.id
|
||||
if subscription.cancel_at_period_end
|
||||
subscriber.cancel = new Date(subscription.canceled_at * 1000)
|
||||
subscriber.end = new Date(subscription.current_period_end * 1000)
|
||||
@subscribers.push(subscriber)
|
||||
|
||||
if customers.has_more and @subscribers.length < maxReturnCount
|
||||
return nextBatch(customers.data[customers.data.length - 1].id, done)
|
||||
else
|
||||
return done()
|
||||
nextBatch null, (err) =>
|
||||
return @sendDatabaseError(res, err) if err
|
||||
User.find {_id: {$in: subscriberIDs}}, (err, users) =>
|
||||
return @sendDatabaseError(res, err) if err
|
||||
for user in users
|
||||
subscriber.user = user for subscriber in @subscribers when subscriber.userID is user.id
|
||||
@sendSuccess(res, @subscribers)
|
||||
|
||||
getSubscriptions: (req, res) ->
|
||||
# Returns a list of active subscriptions
|
||||
# TODO: does not handle customers with 11+ active subscriptions
|
||||
|
@ -54,7 +116,6 @@ class SubscriptionHandler extends Handler
|
|||
for subscription in customer.subscriptions.data
|
||||
continue unless subscription.plan.id is 'basic'
|
||||
|
||||
|
||||
amount = subscription.plan.amount
|
||||
if subscription?.discount?.coupon?
|
||||
if subscription.discount.coupon.percent_off
|
||||
|
@ -72,7 +133,7 @@ class SubscriptionHandler extends Handler
|
|||
sub = start: new Date(subscription.start * 1000)
|
||||
if subscription.cancel_at_period_end
|
||||
sub.cancel = new Date(subscription.canceled_at * 1000)
|
||||
sub.end = new Date(sub.current_period_end * 1000)
|
||||
sub.end = new Date(subscription.current_period_end * 1000)
|
||||
@subs.push(sub)
|
||||
|
||||
# Can't fetch all the test Stripe data
|
||||
|
@ -84,9 +145,6 @@ class SubscriptionHandler extends Handler
|
|||
return @sendDatabaseError(res, err) if err
|
||||
@sendSuccess(res, @subs)
|
||||
|
||||
|
||||
|
||||
|
||||
subscribeUser: (req, user, done) ->
|
||||
if (not req.user) or req.user.isAnonymous() or user.isAnonymous()
|
||||
return done({res: 'You must be signed in to subscribe.', code: 403})
|
||||
|
|
|
@ -527,11 +527,11 @@ updateMatchesInSession = (matchObject, sessionID, callback) ->
|
|||
opponentsArray = _.toArray opponentsClone
|
||||
currentMatchObject.opponents = opponentsArray
|
||||
currentMatchObject.codeLanguage = matchObject.opponents[opponentsArray[0].sessionID].codeLanguage
|
||||
currentMatchObject.simulator = @clientResponseObject.simulator
|
||||
currentMatchObject.randomSeed = parseInt(@clientResponseObject.randomSeed or 0, 10)
|
||||
#currentMatchObject.simulator = @clientResponseObject.simulator # Uncomment when actively debugging simulation mismatches
|
||||
#currentMatchObject.randomSeed = parseInt(@clientResponseObject.randomSeed or 0, 10) # Uncomment when actively debugging simulation mismatches
|
||||
LevelSession.findOne {'_id': sessionID}, (err, session) ->
|
||||
session = session.toObject()
|
||||
currentMatchObject.playtime = session.playtime ? 0
|
||||
#currentMatchObject.playtime = session.playtime ? 0 # Not useful if we can only see last 200
|
||||
sessionUpdateObject =
|
||||
$push: {matches: {$each: [currentMatchObject], $slice: -200}}
|
||||
#log.info "Updating session #{sessionID}"
|
||||
|
|
|
@ -727,8 +727,9 @@ sendNextStepsEmail = (user, now, daysAgo) ->
|
|||
'maker-square': isAdult and isFast
|
||||
'the-firehose-project': isAdult and isFast
|
||||
#'mv-code-club': isKid # TODO: geodetect, get landing page URL
|
||||
'breakout-mentors': isKid
|
||||
nAdditionalOffers = Math.max 0, 4 - _.filter(offers).length
|
||||
possibleAdditionalOffers = ['code-school', 'one-month', 'learnable', 'pluralsight']
|
||||
possibleAdditionalOffers = ['ostraining', 'code-school', 'one-month', 'learnable', 'pluralsight']
|
||||
for offer in _.sample possibleAdditionalOffers, nAdditionalOffers
|
||||
offers[offer] = true
|
||||
if user.isPremium()
|
||||
|
|
4
vendor/scripts/checkout.js
vendored
4
vendor/scripts/checkout.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue