Merge branch 'master' into production

This commit is contained in:
Nick Winter 2015-04-03 09:07:37 -07:00
commit d73328ef54
6 changed files with 250 additions and 150 deletions

View file

@ -11,7 +11,7 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
for_beginners: "Für Afänger" for_beginners: "Für Afänger"
multiplayer: "Multiplayer" # Not currently shown on home page multiplayer: "Multiplayer" # Not currently shown on home page
for_developers: "Für Entwickler" # Not currently shown on home page. for_developers: "Für Entwickler" # Not currently shown on home page.
# or_ipad: "Or download for iPad" or_ipad: "Oder lads fürs iPad abä"
nav: nav:
play: "Levels" # The top nav bar entry where players choose which levels to play play: "Levels" # The top nav bar entry where players choose which levels to play
@ -58,7 +58,7 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
owned: "Scho gkauft" # For items you own owned: "Scho gkauft" # For items you own
locked: "Nonig freischaltbar" locked: "Nonig freischaltbar"
# purchasable: "Purchasable" # For a hero you unlocked but haven't purchased # purchasable: "Purchasable" # For a hero you unlocked but haven't purchased
# available: "Available" available: "vorhandä"
# skills_granted: "Skills Granted" # Property documentation details # skills_granted: "Skills Granted" # Property documentation details
heroes: "Helde" # Tooltip on hero shop button from /play heroes: "Helde" # Tooltip on hero shop button from /play
achievements: "Achievements" # Tooltip on achievement list button from /play achievements: "Achievements" # Tooltip on achievement list button from /play
@ -93,15 +93,15 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
# campaign_classic_algorithms: "Classic Algorithms" # campaign_classic_algorithms: "Classic Algorithms"
# campaign_classic_algorithms_description: "... in which you learn the most popular algorithms in Computer Science." # campaign_classic_algorithms_description: "... in which you learn the most popular algorithms in Computer Science."
# share_progress_modal: share_progress_modal:
# blurb: "Youre making great progress! Tell someone how much you've learned with CodeCombat." blurb: "Du machsch grossi Fortschritts! Verzells öperem wieviel du glernt häsch mit CodeCombat."
# email_invalid: "Email address invalid." email_invalid: "Email Adrässä isch falsch."
# form_blurb: "Enter their email below and well show them!" # form_blurb: "Enter their email below and well show them!"
# form_label: "Email Address" form_label: "Email Adrässä"
# placeholder: "email address" placeholder: "Email Adrässä"
# title: "Excellent Work, Apprentice" # title: "Excellent Work, Apprentice"
# tell_friend: "Tell your Friend" tell_friend: "Sägs dim Kolleg oder dinere Kollegin"
# tell_parent: "Tell your Parent" tell_parent: "Sägs dinä Elterä"
login: login:
sign_up: "Account erstelle" sign_up: "Account erstelle"
@ -130,13 +130,13 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
send_password: "Recovery Password sende" send_password: "Recovery Password sende"
# recovery_sent: "Recovery email sent." # recovery_sent: "Recovery email sent."
# items: items:
# primary: "Primary" # primary: "Primary"
# secondary: "Secondary" # secondary: "Secondary"
# armor: "Armor" # armor: "Armor"
# accessories: "Accessories" # accessories: "Accessories"
# misc: "Misc" misc: "Diverses"
# books: "Books" books: "Büecher"
common: common:
# back: "Back" # When used as an action verb, like "Navigate backward" # back: "Back" # When used as an action verb, like "Navigate backward"
@ -154,8 +154,8 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
play: "Spiele" # When used as an action verb, like "Play next level" play: "Spiele" # When used as an action verb, like "Play next level"
retry: "nomol versuche" retry: "nomol versuche"
# actions: "Actions" # actions: "Actions"
# info: "Info" info: "Info"
# help: "Help" help: "Hilf"
# watch: "Watch" # watch: "Watch"
# unwatch: "Unwatch" # unwatch: "Unwatch"
submit_patch: "Patch ireiche" submit_patch: "Patch ireiche"
@ -184,7 +184,7 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
# redo_shortcut: "(Ctrl+Shift+Z)" # redo_shortcut: "(Ctrl+Shift+Z)"
# play_preview: "Play preview of current level" # play_preview: "Play preview of current level"
result: "Resultat" result: "Resultat"
# results: "Results" results: "Resultat"
description: "Beschriibig" description: "Beschriibig"
or: "oder" or: "oder"
# subject: "Subject" # subject: "Subject"
@ -205,9 +205,9 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
hard: "Schwer" hard: "Schwer"
player: "Spieler" player: "Spieler"
player_level: "Stufe" # Like player level 5, not like level: Dungeons of Kithgard player_level: "Stufe" # Like player level 5, not like level: Dungeons of Kithgard
# warrior: "Warrior" warrior: "Krieger"
# ranger: "Ranger" # ranger: "Ranger"
# wizard: "Wizard" wizard: "Zauberer"
units: units:
second: "Sekunde" second: "Sekunde"
@ -235,15 +235,15 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
restart: "Neu starte" restart: "Neu starte"
goals: "Ziel" goals: "Ziel"
goal: "Goal" goal: "Goal"
# running: "Running..." running: "s lauft..."
success: "Erfolg!" success: "Erfolg!"
incomplete: "Unvollständig" incomplete: "Unvollständig"
timed_out: "Ziit abglaufe" timed_out: "Ziit abglaufe"
failing: "Fehler" failing: "Fehler"
action_timeline: "Aktionsziitleiste" action_timeline: "Aktionsziitleiste"
click_to_select: "Klick uf e Einheit zum sie uswähle." click_to_select: "Klick uf e Einheit zum sie uswähle."
# control_bar_multiplayer: "Multiplayer" control_bar_multiplayer: "Mehrspiiler"
# control_bar_join_game: "Join Game" control_bar_join_game: "Mitspiilä"
reload: "Neu lade" reload: "Neu lade"
reload_title: "De ganze Code neu lade?" reload_title: "De ganze Code neu lade?"
reload_really: "Bisch sicher du willsch level neu lade bis zrugg zum Afang?" reload_really: "Bisch sicher du willsch level neu lade bis zrugg zum Afang?"
@ -256,8 +256,8 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
victory_rate_the_level: "Bewerte das Level: " # Only in old-style levels. victory_rate_the_level: "Bewerte das Level: " # Only in old-style levels.
victory_return_to_ladder: "Zrugg zum letzte Level" victory_return_to_ladder: "Zrugg zum letzte Level"
victory_play_continue: "Wiiter spile" victory_play_continue: "Wiiter spile"
# victory_saving_progress: "Saving Progress" victory_saving_progress: "Fortschritt abspaicherä"
# victory_go_home: "Go Home" # Only in old-style levels. victory_go_home: "Goon Hai" # Only in old-style levels.
victory_review: "Verzell üs meh!" # Only in old-style levels. victory_review: "Verzell üs meh!" # Only in old-style levels.
victory_hour_of_code_done: "Bisch fertig?" victory_hour_of_code_done: "Bisch fertig?"
victory_hour_of_code_done_yes: "Jo, ich bin fertig mit mim Hour of Code™!" victory_hour_of_code_done_yes: "Jo, ich bin fertig mit mim Hour of Code™!"
@ -272,21 +272,21 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
# tome_cast_button_ran: "Ran" # tome_cast_button_ran: "Ran"
# tome_submit_button: "Submit" # tome_submit_button: "Submit"
# tome_reload_method: "Reload original code for this method" # Title text for individual method reload button. # tome_reload_method: "Reload original code for this method" # Title text for individual method reload button.
# tome_select_method: "Select a Method" tome_select_method: "Wähl a Methodä"
# tome_see_all_methods: "See all methods you can edit" # Title text for method list selector (shown when there are multiple programmable methdos). # tome_see_all_methods: "See all methods you can edit" # Title text for method list selector (shown when there are multiple programmable methdos).
tome_select_a_thang: "Wähl öpper us für" tome_select_a_thang: "Wähl öpper us für"
tome_available_spells: "Verfüegbari Zaubersprüch" tome_available_spells: "Verfüegbari Zaubersprüch"
# tome_your_skills: "Your Skills" tome_your_skills: "Dini Fähigkaitä"
tome_help: "Hilf" tome_help: "Hilf"
# tome_current_method: "Current Method" tome_current_method: "Aktuelli Modus"
# hud_continue_short: "Continue" hud_continue_short: "Wiitermache"
code_saved: "Code gpeicheret" code_saved: "Code gpeicheret"
skip_tutorial: "Überspringe (esc)" skip_tutorial: "Überspringe (esc)"
keyboard_shortcuts: "Shortcuts" keyboard_shortcuts: "Shortcuts"
# loading_ready: "Ready!" loading_ready: "Berait!"
loading_start: "Level starte" loading_start: "Level starte"
# problem_alert_title: "Fix Your Code" problem_alert_title: "Reparier diin Code"
# problem_alert_help: "Help" problem_alert_help: "Hilf"
time_current: "Jetzt:" time_current: "Jetzt:"
time_total: "Max:" time_total: "Max:"
time_goto: "Goh zu:" time_goto: "Goh zu:"
@ -341,18 +341,18 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
game_menu: game_menu:
# inventory_tab: "Inventory" # inventory_tab: "Inventory"
# save_load_tab: "Save/Load" save_load_tab: "Spaicherä/Ladä"
# options_tab: "Options" options_tab: "Optionä"
# guide_tab: "Guide" # guide_tab: "Guide"
# guide_video_tutorial: "Video Tutorial" # guide_video_tutorial: "Video Tutorial"
# guide_tips: "Tips" guide_tips: "Tipps"
multiplayer_tab: "Multiplayer" multiplayer_tab: "Multiplayer"
# auth_tab: "Sign Up" # auth_tab: "Sign Up"
# inventory_caption: "Equip your hero" # inventory_caption: "Equip your hero"
# choose_hero_caption: "Choose hero, language" # choose_hero_caption: "Choose hero, language"
# save_load_caption: "... and view history" # save_load_caption: "... and view history"
# options_caption: "Configure settings" # options_caption: "Configure settings"
# guide_caption: "Docs and tips" guide_caption: "Doku und Tipps"
# multiplayer_caption: "Play with friends!" # multiplayer_caption: "Play with friends!"
# auth_caption: "Save your progress." # auth_caption: "Save your progress."

View file

@ -454,8 +454,8 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
no_users_subscribed: "No se suscribieron usuarios, por favor revisa las direcciones de email." no_users_subscribed: "No se suscribieron usuarios, por favor revisa las direcciones de email."
current_recipients: "Recipientes actuales" current_recipients: "Recipientes actuales"
unsubscribing: "Desuscribiendo..." unsubscribing: "Desuscribiendo..."
# subscribe_prepaid: "Click Subscribe to use prepaid code" subscribe_prepaid: "Click en suscribirse para utlizar un código prepago"
# using_prepaid: "Using prepaid code for monthly subscription" using_prepaid: "Usar código prepago para una suscribción mensual"
choose_hero: choose_hero:
choose_hero: "Elige tu héroe" choose_hero: "Elige tu héroe"
@ -572,40 +572,40 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
josh_blurb: "El piso es Lava" josh_blurb: "El piso es Lava"
jose_title: "Música" jose_title: "Música"
jose_blurb: "Despegar" jose_blurb: "Despegar"
retrostyle_title: "Ilustracin" retrostyle_title: "Ilustración"
retrostyle_blurb: "Juegos con estilo Retro" retrostyle_blurb: "Juegos con estilo Retro"
teachers: teachers:
title: "CodeCombat para Profesores" # {change} title: "CodeCombat para Profesores" # {change}
# intro_1: "CodeCombat is an online game that teaches programming. Students write code in real programming languages." intro_1: "CodeCombat es un juego online que enseña a programar.Los estudiantes escriben código en idiomas de programación real."
# intro_2: "No experience required!" intro_2: "No se necesita experiencia previa!"
# free_title: "How much does it cost?" free_title: "¿Cuanto cuesta?"
# 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." # 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_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." # free_2: "A monthly subscription provides access to video tutorials and extra practice levels."
# teacher_subs_title: "Teachers get free subscriptions!" teacher_subs_title: "¡Los amestros obtienen subscripciones gratuitas!"
# teacher_subs_1: "Please contact" # teacher_subs_1: "Please contact"
# teacher_subs_2: "to set up a free monthly subscription." teacher_subs_2: "to set up a free monthly subscriptiron."
# sub_includes_title: "What is included in the subscription?" sub_includes_title: "¿Qué se incluye en la suscripción?"
# sub_includes_1: "In additional to the 70+ basic levels, students with a monthly subscription get access to these additional features:" sub_includes_1: "Adicionalmente a los más de 70 niveles básicos, los estudiantes con una suscripción mensual obtienen acceso a estas características adicionales:"
# sub_includes_2: "40+ practice levels" sub_includes_2: "Más de 40 niveles de práctica"
# sub_includes_3: "Video tutorials" sub_includes_3: "Video tutoriales"
# sub_includes_4: "Premium email support" # sub_includes_4: "Premium email support"
# sub_includes_5: "7 new heroes with unique skills to master" sub_includes_5: "7 heroes nuevos con habilidades unicas que dominar"
# sub_includes_6: "3500 bonus gems every month" sub_includes_6: "bonificación de 3500 gemas cada mes"
# who_for_title: "Who is CodeCombat for?" who_for_title: "¿Para quienes es CodeCombat?"
# who_for_1: "We recommend CodeCombat for students aged 9 and up. No prior programming experience is needed." # 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." # who_for_2: "We've designed CodeCombat to appeal to both boys and girls."
# material_title: "How much material is there?" # material_title: "How much material is there?"
# material_china: "Approximately 22 hours of gameplay spread over 120+ subscriber-only levels so far, with 5 new levels every week." # 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." # 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?" # concepts_title: "What concepts are covered?"
# how_much_title: "How much does a monthly subscription cost?" how_much_title: "¿Cuánto cuesta una subscripción mensual?"
# how_much_1: "A" how_much_1: "una"
# how_much_2: "monthly subscription" how_much_2: "suscribción mensual"
# how_much_3: "costs $9.99, and can be cancelled anytime." how_much_3: "Cuesta u$s9.99, y puede ser cancelada en cualquier momento."
# how_much_4: "Additionally, we provide discounts for larger groups:" how_much_4: "Adicionalmente, nosotros otorgamos descuentos a grupos grandes:"
# group_discounts_1: "We also offer group discounts for bulk subscriptions." group_discounts_1: "También ofrecemos descuentes grupales para suscripciones en masa."
sys_requirements_title: "Requerimientos del sistema" sys_requirements_title: "Requerimientos del sistema"
sys_requirements_1: "Debido que CodeCombat es un juego, es más difícil para las computadoras correrlo en relación a un tutorial escrito o un video. Para que todos puedan jugar, hemos optimizado la web para correr rápidamente en todos los navegadores modernos y en maquinas antiguas. Dicho esto, aquí están nuestras sugerencias para sacar el máximo provecho de su experiencia en la Hora del Código:" # {change} sys_requirements_1: "Debido que CodeCombat es un juego, es más difícil para las computadoras correrlo en relación a un tutorial escrito o un video. Para que todos puedan jugar, hemos optimizado la web para correr rápidamente en todos los navegadores modernos y en maquinas antiguas. Dicho esto, aquí están nuestras sugerencias para sacar el máximo provecho de su experiencia en la Hora del Código:" # {change}
sys_requirements_2: "Usar una versión actualizada del navegador Chrome o Firefox." # {change} sys_requirements_2: "Usar una versión actualizada del navegador Chrome o Firefox." # {change}
@ -941,7 +941,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
fight: "Pelea!" fight: "Pelea!"
watch_victory: "Observa tu Victoria" watch_victory: "Observa tu Victoria"
defeat_the: "Derrota a" defeat_the: "Derrota a"
# tournament_started: ", started" tournament_started: ", iniciado"
tournament_ends: "Final de Torneo" tournament_ends: "Final de Torneo"
tournament_ended: "Finalizó el Torneo" tournament_ended: "Finalizó el Torneo"
tournament_rules: "Reglas del Torneo" tournament_rules: "Reglas del Torneo"

View file

@ -64,7 +64,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
achievements: "Logros" # Tooltip on achievement list button from /play achievements: "Logros" # Tooltip on achievement list button from /play
account: "Cuenta" # Tooltip on account button from /play account: "Cuenta" # Tooltip on account button from /play
settings: "Ajustes" # Tooltip on settings button from /play settings: "Ajustes" # Tooltip on settings button from /play
# poll: "Poll" # Tooltip on poll button from /play poll: "Encuesta" # Tooltip on poll button from /play
next: "Siguiente Heroe" # Go from choose hero to choose inventory before playing a level next: "Siguiente Heroe" # Go from choose hero to choose inventory before playing a level
change_hero: "Seleccionar Heroe" # Go back from choose inventory to choose hero change_hero: "Seleccionar Heroe" # Go back from choose inventory to choose hero
choose_inventory: "Equipar Objetos" choose_inventory: "Equipar Objetos"
@ -77,7 +77,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
awaiting_levels_adventurer_prefix: "Liberamos cinco niveles cada semana." awaiting_levels_adventurer_prefix: "Liberamos cinco niveles cada semana."
awaiting_levels_adventurer: "Regístrate como Aventurero" awaiting_levels_adventurer: "Regístrate como Aventurero"
awaiting_levels_adventurer_suffix: "para ser el primero en jugar nuevos niveles." awaiting_levels_adventurer_suffix: "para ser el primero en jugar nuevos niveles."
# adjust_volume: "Adjust volume" adjust_volume: "Ajustar volúmen"
choose_your_level: "Elige tu nivel" # The rest of this section is the old play view at /play-old and isn't very important. choose_your_level: "Elige tu nivel" # The rest of this section is the old play view at /play-old and isn't very important.
adventurer_prefix: "Puedes elegir cualquier pantalla o charlar en " adventurer_prefix: "Puedes elegir cualquier pantalla o charlar en "
adventurer_forum: "el foro del aventurero " adventurer_forum: "el foro del aventurero "
@ -93,15 +93,15 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
campaign_classic_algorithms: "Algoritmos Clasicos" campaign_classic_algorithms: "Algoritmos Clasicos"
campaign_classic_algorithms_description: "... donde aprendes los algoritmos mas populares de la informatica." campaign_classic_algorithms_description: "... donde aprendes los algoritmos mas populares de la informatica."
# share_progress_modal: share_progress_modal:
# blurb: "Youre making great progress! Tell someone how much you've learned with CodeCombat." blurb: "¡Estás teniendo un gran progreso! Cuéntale a alguien que tanto habeis aprendido con CodeCombat."
# email_invalid: "Email address invalid." email_invalid: "La dirección de correo electrónico no es válida."
# form_blurb: "Enter their email below and well show them!" form_blurb: "¡Introduzca su correo electrónico y nosotros les mostraremos!"
# form_label: "Email Address" form_label: "Correo Electrónico"
# placeholder: "email address" placeholder: "correo electrónico"
# title: "Excellent Work, Apprentice" title: "Excelente Trabajo Aprendiz"
# tell_friend: "Tell your Friend" tell_friend: "Decirle a un amigo"
# tell_parent: "Tell your Parent" tell_parent: "Decirle a mis padres"
login: login:
sign_up: "Crear una cuenta" sign_up: "Crear una cuenta"
@ -139,8 +139,8 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
books: "Libros" books: "Libros"
common: common:
# back: "Back" # When used as an action verb, like "Navigate backward" back: "Volver" # When used as an action verb, like "Navigate backward"
# continue: "Continue" # When used as an action verb, like "Continue forward" continue: "Continuar" # When used as an action verb, like "Continue forward"
loading: "Cargando..." loading: "Cargando..."
saving: "Guardando..." saving: "Guardando..."
sending: "Enviando..." sending: "Enviando..."
@ -154,7 +154,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
play: "Jugar" # When used as an action verb, like "Play next level" play: "Jugar" # When used as an action verb, like "Play next level"
retry: "Reintentar" retry: "Reintentar"
actions: "Acciones" actions: "Acciones"
# info: "Info" info: "Información"
help: "Ayuda" help: "Ayuda"
watch: "Mirar" watch: "Mirar"
unwatch: "Pasar" unwatch: "Pasar"
@ -172,16 +172,16 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
rejected: "Rechazado" rejected: "Rechazado"
# withdrawn: "Withdrawn" # withdrawn: "Withdrawn"
# submitter: "Submitter" # submitter: "Submitter"
# submitted: "Submitted" submitted: "Enviado"
commit_msg: "Mensaje de Asignación o Commit" commit_msg: "Mensaje de Asignación o Commit"
# review: "Review" # review: "Review"
version_history: "Historial de versión" version_history: "Historial de versión"
version_history_for: "Historial de las versiones de: " version_history_for: "Historial de las versiones de: "
select_changes: "Selecciona dos cambios más abajo para ver la diferencia." select_changes: "Selecciona dos cambios más abajo para ver la diferencia."
undo_prefix: "Deshacer" undo_prefix: "Deshacer"
# undo_shortcut: "(Ctrl+Z)" undo_shortcut: "(Ctrl+Z)"
redo_prefix: "Rehacer" redo_prefix: "Rehacer"
# redo_shortcut: "(Ctrl+Shift+Z)" redo_shortcut: "(Ctrl+Shift+Z)" #tal vez sea mejor usar el común Control+Y
play_preview: "Reproducir una vista previa del nivel actual" play_preview: "Reproducir una vista previa del nivel actual"
result: "Resultado" result: "Resultado"
results: "Resultados" results: "Resultados"
@ -205,8 +205,8 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
hard: "Difícil" hard: "Difícil"
player: "Jugador" player: "Jugador"
player_level: "Nivel" # Like player level 5, not like level: Dungeons of Kithgard player_level: "Nivel" # Like player level 5, not like level: Dungeons of Kithgard
# warrior: "Warrior" warrior: "Guerrero"
# ranger: "Ranger" # ranger: "Ranger" #guardabosques?
wizard: "Mago" wizard: "Mago"
units: units:
@ -326,18 +326,18 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
tip_superpower: "Programar es lo más parecido que tenemos a un superpoder." tip_superpower: "Programar es lo más parecido que tenemos a un superpoder."
# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds" # tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds"
# tip_no_code: "No code is faster than no code." # tip_no_code: "No code is faster than no code."
# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries" tip_code_never_lies: "El código nunca os miente, los comentarios algunas veces. — Ron Jeffries"
# tip_reusable_software: "Before software can be reusable it first has to be usable." # tip_reusable_software: "Before software can be reusable it first has to be usable."
# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is //" # tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is //"
# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates" # tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates"
# tip_source_code: "I want to change the world but they would not give me the source code." # tip_source_code: "I want to change the world but they would not give me the source code."
# tip_javascript_java: "Java is to JavaScript what Car is to Carpet. - Chris Heilmann" # tip_javascript_java: "Java is to JavaScript what Car is to Carpet. - Chris Heilmann"
# tip_move_forward: "Whatever you do, keep moving forward. - Martin Luther King Jr." # tip_move_forward: "Whatever you do, keep moving forward. - Martin Luther King Jr."
# tip_google: "Have a problem you can't solve? Google it!" tip_google: "¿Teneis un problema que no podeis resolver? ¡Googleadlo!"
# tip_adding_evil: "Adding a pinch of evil." # tip_adding_evil: "Adding a pinch of evil."
# tip_hate_computers: "That's the thing about people who think they hate computers. What they really hate is lousy programmers. - Larry Niven" # tip_hate_computers: "That's the thing about people who think they hate computers. What they really hate is lousy programmers. - Larry Niven"
# tip_open_source_contribute: "You can help CodeCombat improve!" # tip_open_source_contribute: "You can help CodeCombat improve!"
# tip_recurse: "To iterate is human, to recurse divine. - L. Peter Deutsch" tip_recurse: "Iterar es humano, recursar es divino. - L. Peter Deutsch"
game_menu: game_menu:
inventory_tab: "Inventario" inventory_tab: "Inventario"
@ -356,18 +356,18 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
multiplayer_caption: "Juega con amigos!" multiplayer_caption: "Juega con amigos!"
auth_caption: "Salvar tu progreso." auth_caption: "Salvar tu progreso."
# leaderboard: leaderboard:
# leaderboard: "Leaderboard" # leaderboard: "Leaderboard"
# view_other_solutions: "View Other Solutions" # view_other_solutions: "View Other Solutions"
# scores: "Scores" scores: "Puntuaciones"
# top_players: "Top Players by" # top_players: "Top Players by"
# day: "Today" day: "Hoy"
# week: "This Week" week: "Esta semana"
# all: "All-Time" # all: "All-Time"
# time: "Time" # time: "Time"
# damage_taken: "Damage Taken" # damage_taken: "Damage Taken"
# damage_dealt: "Damage Dealt" # damage_dealt: "Damage Dealt"
# difficulty: "Difficulty" difficulty: "Difficultad"
# gold_collected: "Gold Collected" # gold_collected: "Gold Collected"
inventory: inventory:
@ -402,16 +402,16 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
# feature2: "7 powerful <strong>new heroes</strong> with unique skills!" # feature2: "7 powerful <strong>new heroes</strong> with unique skills!"
# feature3: "30+ bonus levels" # feature3: "30+ bonus levels"
# feature4: "<strong>3500 bonus gems</strong> every month!" # feature4: "<strong>3500 bonus gems</strong> every month!"
# feature5: "Video tutorials" feature5: "Vídeo tutoriales"
# feature6: "Premium email support" # feature6: "Premium email support"
# free: "Free" free: "Gratis"
# month: "month" month: "mes"
subscribe_title: "Suscríbete" subscribe_title: "Suscríbete"
# unsubscribe: "Unsubscribe" # unsubscribe: "Unsubscribe"
# confirm_unsubscribe: "Confirm Unsubscribe" # confirm_unsubscribe: "Confirm Unsubscribe"
# never_mind: "Never Mind, I Still Love You" # never_mind: "Never Mind, I Still Love You"
# thank_you_months_prefix: "Thank you for supporting us these last" # thank_you_months_prefix: "Thank you for supporting us these last"
# thank_you_months_suffix: "months." thank_you_months_suffix: "meses."
# thank_you: "Thank you for supporting CodeCombat." # thank_you: "Thank you for supporting CodeCombat."
# sorry_to_see_you_go: "Sorry to see you go! Please let us know what we could have done better." # sorry_to_see_you_go: "Sorry to see you go! Please let us know what we could have done better."
# unsubscribe_feedback_placeholder: "O, what have we done?" # unsubscribe_feedback_placeholder: "O, what have we done?"
@ -470,7 +470,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
lua_blurb: "Lenguaje Script para Juegos." lua_blurb: "Lenguaje Script para Juegos."
io_blurb: "Simple pero oscuro." io_blurb: "Simple pero oscuro."
status: "Estado" status: "Estado"
# hero_type: "Type" hero_type: "Tipo"
weapons: "Armas" weapons: "Armas"
weapons_warrior: "Espadas - Corto Alcance, Sin Magia" weapons_warrior: "Espadas - Corto Alcance, Sin Magia"
weapons_ranger: "Ballestas, Pistolas - Largo Alcance, Sin Magia" weapons_ranger: "Ballestas, Pistolas - Largo Alcance, Sin Magia"
@ -570,12 +570,12 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
# cat_blurb: "Airbender" # cat_blurb: "Airbender"
# josh_title: "Game Designer" # josh_title: "Game Designer"
# josh_blurb: "Floor Is Lava" # josh_blurb: "Floor Is Lava"
# jose_title: "Music" jose_title: "Música"
# jose_blurb: "Taking Off" # jose_blurb: "Taking Off"
# retrostyle_title: "Illustration" # retrostyle_title: "Illustration"
# retrostyle_blurb: "RetroStyle Games" # retrostyle_blurb: "RetroStyle Games"
# teachers: teachers:
# title: "CodeCombat: Info for Teachers" # title: "CodeCombat: Info for Teachers"
# intro_1: "CodeCombat is an online game that teaches programming. Students write code in real programming languages." # intro_1: "CodeCombat is an online game that teaches programming. Students write code in real programming languages."
# intro_2: "No experience required!" # intro_2: "No experience required!"
@ -602,7 +602,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
# concepts_title: "What concepts are covered?" # concepts_title: "What concepts are covered?"
# how_much_title: "How much does a monthly subscription cost?" # how_much_title: "How much does a monthly subscription cost?"
# how_much_1: "A" # how_much_1: "A"
# how_much_2: "monthly subscription" how_much_2: "suscripción mensual"
# how_much_3: "costs $9.99, and can be cancelled anytime." # how_much_3: "costs $9.99, and can be cancelled anytime."
# how_much_4: "Additionally, we provide discounts for larger groups:" # how_much_4: "Additionally, we provide discounts for larger groups:"
# group_discounts_1: "We also offer group discounts for bulk subscriptions." # group_discounts_1: "We also offer group discounts for bulk subscriptions."
@ -751,7 +751,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
pick_a_terrain: "Escoge un Terreno" pick_a_terrain: "Escoge un Terreno"
# dungeon: "Dungeon" # dungeon: "Dungeon"
# indoor: "Indoor" # indoor: "Indoor"
# desert: "Desert" desert: "Desierto" #desert like take a desert in desert? :P
grassy: "Cubierto de hierba" grassy: "Cubierto de hierba"
small: "Pequeño" small: "Pequeño"
# large: "Large" # large: "Large"
@ -818,7 +818,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
# achievement_query_goals: "Key achievement off of level goals" # achievement_query_goals: "Key achievement off of level goals"
level_completion: "Porcentaje de Nivel Completado" level_completion: "Porcentaje de Nivel Completado"
pop_i18n: "Poblar I18N" pop_i18n: "Poblar I18N"
# tasks: "Tasks" tasks: "Tareas"
# clear_storage: "Clear your local changes" # clear_storage: "Clear your local changes"
article: article:
@ -998,11 +998,11 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
service: "Servicio" service: "Servicio"
price: "Precio" price: "Precio"
gems: "Joyas" gems: "Joyas"
# active: "Active" active: "Activo"
# subscribed: "Subscribed" # subscribed: "Subscribed"
# unsubscribed: "Unsubscribed" # unsubscribed: "Unsubscribed"
# active_until: "Active Until" # active_until: "Active Until"
# cost: "Cost" cost: "Costo"
next_payment: "Siguiente Pago" next_payment: "Siguiente Pago"
card: "Tarjeta" card: "Tarjeta"
status_unsubscribed_active: "No estás suscrito y no seras facturado, pero tu cuenta sigue activa por ahora." status_unsubscribed_active: "No estás suscrito y no seras facturado, pero tu cuenta sigue activa por ahora."
@ -1078,7 +1078,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
feedback: "Apoyo" feedback: "Apoyo"
payment_info: "Información de Pago" payment_info: "Información de Pago"
# campaigns: "Campaigns" # campaigns: "Campaigns"
# poll: "Poll" poll: "Encuesta"
# user_polls_record: "Poll Voting History" # user_polls_record: "Poll Voting History"
delta: delta:

View file

@ -2,8 +2,8 @@ RootView = require 'views/core/RootView'
template = require 'templates/admin/analytics-subscriptions' template = require 'templates/admin/analytics-subscriptions'
RealTimeCollection = require 'collections/RealTimeCollection' RealTimeCollection = require 'collections/RealTimeCollection'
# TODO: Add last N subscribers table
# TODO: Add revenue line # TODO: Add revenue line
# TODO: Add LTV line
# TODO: Graphing code copied/mangled from campaign editor level view. OMG, DRY. # TODO: Graphing code copied/mangled from campaign editor level view. OMG, DRY.
require 'vendor/d3' require 'vendor/d3'
@ -14,14 +14,15 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
constructor: (options) -> constructor: (options) ->
super options super options
@resetData()
if me.isAdmin() if me.isAdmin()
@refreshData() @refreshData()
_.delay (=> @refreshData()), 30 * 60 * 1000 _.delay (=> @refreshData()), 30 * 60 * 1000
getRenderData: -> getRenderData: ->
context = super() context = super()
context.analytics = @analytics context.analytics = @analytics ? graphs: []
context.subs = @subs ? [] context.subs = _.cloneDeep(@subs ? []).reverse()
context.total = @total ? 0 context.total = @total ? 0
context.cancelled = @cancelled ? 0 context.cancelled = @cancelled ? 0
context.monthlyChurn = @monthlyChurn ? 0.0 context.monthlyChurn = @monthlyChurn ? 0.0
@ -31,14 +32,26 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
super() super()
@updateAnalyticsGraphs() @updateAnalyticsGraphs()
refreshData: -> resetData: ->
return unless me.isAdmin()
@analytics = graphs: [] @analytics = graphs: []
@subs = [] @subs = []
@total = 0 @total = 0
@cancelled = 0 @cancelled = 0
@monthlyChurn = 0.0 @monthlyChurn = 0.0
onSuccess = (subs) =>
refreshData: ->
return unless me.isAdmin()
@resetData()
options =
url: '/db/subscription/-/subscriptions'
method: 'GET'
options.error = (model, response, options) =>
return if @destroyed
console.error 'Failed to get subscriptions', response
options.success = (subs, response, options) =>
return if @destroyed
@resetData()
subDayMap = {} subDayMap = {}
for sub in subs for sub in subs
startDay = sub.start.substring(0, 10) startDay = sub.start.substring(0, 10)
@ -63,15 +76,9 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
sub.total = @total sub.total = @total
startedLastMonth += sub.started if @subs.length - i < 31 startedLastMonth += sub.started if @subs.length - i < 31
@monthlyChurn = @cancelled / startedLastMonth * 100.0 @monthlyChurn = @cancelled / startedLastMonth * 100.0
@updateAnalyticsGraphData() @updateAnalyticsGraphData()
@render() @render?()
@supermodel.addRequestResource('subscriptions', { @supermodel.addRequestResource('get_subscriptions', options, 0).load()
url: '/db/subscription/-/subscriptions'
method: 'GET'
success: onSuccess
}, 0).load()
updateAnalyticsGraphData: -> updateAnalyticsGraphData: ->
# console.log 'updateAnalyticsGraphData' # console.log 'updateAnalyticsGraphData'
@ -79,6 +86,8 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
# Currently only one graph # Currently only one graph
@analytics.graphs = [graphID: 'total-subs', lines: []] @analytics.graphs = [graphID: 'total-subs', lines: []]
timeframeDays = 60
return unless @subs?.length > 0 return unless @subs?.length > 0
# TODO: Where should this metadata live? # TODO: Where should this metadata live?
@ -86,16 +95,24 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
totalSubsID = 'total-subs' totalSubsID = 'total-subs'
startedSubsID = 'started-subs' startedSubsID = 'started-subs'
cancelledSubsID = 'cancelled-subs' cancelledSubsID = 'cancelled-subs'
netSubsID = 'net-subs'
lineMetadata = {} lineMetadata = {}
lineMetadata[totalSubsID] = lineMetadata[totalSubsID] =
description: 'Total Active Subscriptions' description: 'Total Active Subscriptions'
color: 'green' color: 'green'
strokeWidth: 1
lineMetadata[startedSubsID] = lineMetadata[startedSubsID] =
description: 'New Subscriptions' description: 'New Subscriptions'
color: 'blue' color: 'blue'
strokeWidth: 1
lineMetadata[cancelledSubsID] = lineMetadata[cancelledSubsID] =
description: 'Cancelled Subscriptions' description: 'Cancelled Subscriptions'
color: 'red' color: 'red'
strokeWidth: 1
lineMetadata[netSubsID] =
description: '7-day Average Net Subscriptions'
color: 'black'
strokeWidth: 4
days = (sub.day for sub in @subs) days = (sub.day for sub in @subs)
if days.length > 0 if days.length > 0
@ -132,7 +149,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
levelPoints[i].x = i levelPoints[i].x = i
levelPoints[i].pointID = "#{totalSubsID}#{i}" levelPoints[i].pointID = "#{totalSubsID}#{i}"
levelPoints.splice(0, levelPoints.length - 60) if levelPoints.length > 60 levelPoints.splice(0, levelPoints.length - timeframeDays) if levelPoints.length > timeframeDays
@analytics.graphs[0].lines.push @analytics.graphs[0].lines.push
lineID: totalSubsID lineID: totalSubsID
@ -166,7 +183,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
levelPoints[i].x = i levelPoints[i].x = i
levelPoints[i].pointID = "#{startedSubsID}#{i}" levelPoints[i].pointID = "#{startedSubsID}#{i}"
levelPoints.splice(0, levelPoints.length - 60) if levelPoints.length > 60 levelPoints.splice(0, levelPoints.length - timeframeDays) if levelPoints.length > timeframeDays
@analytics.graphs[0].lines.push @analytics.graphs[0].lines.push
lineID: startedSubsID lineID: startedSubsID
@ -178,16 +195,21 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
max: d3.max(@subs, (d) -> d.started) max: d3.max(@subs, (d) -> d.started)
## Cancelled ## Cancelled
averageCancelled = 0
# Build line data # Build line data
levelPoints = [] levelPoints = []
cancelled = []
for sub, i in @subs for sub, i in @subs
if i >= @subs.length - 30
cancelled.push sub.cancelled
levelPoints.push levelPoints.push
x: i x: i
y: sub.cancelled y: sub.cancelled
day: sub.day day: sub.day
pointID: "#{cancelledSubsID}#{i}" pointID: "#{cancelledSubsID}#{i}"
values: [] values: []
averageCancelled = cancelled.reduce((a, b) -> a + b) / cancelled.length
# Ensure points for each day # Ensure points for each day
for day, i in days for day, i in days
@ -200,7 +222,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
levelPoints[i].x = i levelPoints[i].x = i
levelPoints[i].pointID = "#{cancelledSubsID}#{i}" levelPoints[i].pointID = "#{cancelledSubsID}#{i}"
levelPoints.splice(0, levelPoints.length - 60) if levelPoints.length > 60 levelPoints.splice(0, levelPoints.length - timeframeDays) if levelPoints.length > timeframeDays
@analytics.graphs[0].lines.push @analytics.graphs[0].lines.push
lineID: cancelledSubsID lineID: cancelledSubsID
@ -211,6 +233,52 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
min: 0 min: 0
max: d3.max(@subs, (d) -> d.started) max: d3.max(@subs, (d) -> d.started)
## 7-Day Net Subs
# Build line data
levelPoints = []
sevenNets = []
for sub, i in @subs
net = 0
if i >= @subs.length - 30
sevenNets.push sub.started - sub.cancelled
else
sevenNets.push sub.started - averageCancelled
if sevenNets.length > 7
sevenNets.shift()
if sevenNets.length is 7
net = sevenNets.reduce((a, b) -> a + b) / 7
levelPoints.push
x: i
y: net
day: sub.day
pointID: "#{netSubsID}#{i}"
values: []
# Ensure points for each day
for day, i in days
if levelPoints.length <= i or levelPoints[i].day isnt day
prevY = if i > 0 then levelPoints[i - 1].y else 0.0
levelPoints.splice i, 0,
y: prevY
day: day
values: []
levelPoints[i].x = i
levelPoints[i].pointID = "#{netSubsID}#{i}"
levelPoints.splice(0, levelPoints.length - timeframeDays) if levelPoints.length > timeframeDays
@analytics.graphs[0].lines.push
lineID: netSubsID
enabled: true
points: levelPoints
description: lineMetadata[netSubsID].description
lineColor: lineMetadata[netSubsID].color
strokeWidth: lineMetadata[netSubsID].strokeWidth
min: 0
max: d3.max(@subs, (d) -> d.started)
updateAnalyticsGraphs: -> updateAnalyticsGraphs: ->
# Build d3 graphs # Build d3 graphs
return unless @analytics?.graphs?.length > 0 return unless @analytics?.graphs?.length > 0
@ -229,7 +297,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
svg = d3.select(containerSelector).append("svg") svg = d3.select(containerSelector).append("svg")
.attr("width", containerWidth) .attr("width", containerWidth)
.attr("height", containerHeight) .attr("height", containerHeight)
width = containerWidth - margin * 2 - yAxisWidth * graphLineCount width = containerWidth - margin * 2 - yAxisWidth * 2
height = containerHeight - margin * 2 - xAxisHeight - keyHeight * graphLineCount height = containerHeight - margin * 2 - xAxisHeight - keyHeight * graphLineCount
currentLine = 0 currentLine = 0
for line in graph.lines for line in graph.lines
@ -251,36 +319,39 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
.call(xAxis) .call(xAxis)
.selectAll("text") .selectAll("text")
.attr("dy", ".35em") .attr("dy", ".35em")
.attr("transform", "translate(" + (margin + yAxisWidth * (graphLineCount - 1)) + "," + (height + margin) + ")") .attr("transform", "translate(" + (margin + yAxisWidth) + "," + (height + margin) + ")")
.style("text-anchor", "start") .style("text-anchor", "start")
if line.lineID is 'started-subs'
# Horizontal guidelines # Horizontal guidelines
# svg.selectAll(".line") marks = (Math.round(i * line.max / 5) for i in [1...5])
# .data([10, 30, 50, 70, 90]) svg.selectAll(".line")
# .enter() .data(marks)
# .append("line") .enter()
# .attr("x1", margin + yAxisWidth * graphLineCount) .append("line")
# .attr("y1", (d) -> margin + yRange(d)) .attr("x1", margin + yAxisWidth * 2)
# .attr("x2", margin + yAxisWidth * graphLineCount + width) .attr("y1", (d) -> margin + yRange(d))
# .attr("y2", (d) -> margin + yRange(d)) .attr("x2", margin + yAxisWidth * 2 + width)
# .attr("stroke", line.lineColor) .attr("y2", (d) -> margin + yRange(d))
# .style("opacity", "0.5") .attr("stroke", line.lineColor)
.style("opacity", "0.5")
# y-Axis if currentLine < 2
yAxisRange = d3.scale.linear().range([height, 0]).domain([line.min, line.max]) # y-Axis
yAxis = d3.svg.axis() yAxisRange = d3.scale.linear().range([height, 0]).domain([line.min, line.max])
.scale(yRange) yAxis = d3.svg.axis()
.orient("left") .scale(yRange)
svg.append("g") .orient("left")
.attr("class", "y axis") svg.append("g")
.attr("transform", "translate(" + (margin + yAxisWidth * currentLine) + "," + margin + ")") .attr("class", "y axis")
.style("color", line.lineColor) .attr("transform", "translate(" + (margin + yAxisWidth * currentLine) + "," + margin + ")")
.call(yAxis) .style("color", line.lineColor)
.selectAll("text") .call(yAxis)
.attr("y", 0) .selectAll("text")
.attr("x", 0) .attr("y", 0)
.attr("fill", line.lineColor) .attr("x", 0)
.style("text-anchor", "start") .attr("fill", line.lineColor)
.style("text-anchor", "start")
# Key # Key
svg.append("line") svg.append("line")
@ -302,7 +373,7 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
.data(line.points) .data(line.points)
.enter() .enter()
.append("circle") .append("circle")
.attr("transform", "translate(" + (margin + yAxisWidth * graphLineCount) + "," + margin + ")") .attr("transform", "translate(" + (margin + yAxisWidth * 2) + "," + margin + ")")
.attr("cx", (d) -> xRange(d.x)) .attr("cx", (d) -> xRange(d.x))
.attr("cy", (d) -> yRange(d.y)) .attr("cy", (d) -> yRange(d.y))
.attr("r", 2) .attr("r", 2)
@ -316,8 +387,8 @@ module.exports = class AnalyticsSubscriptionsView extends RootView
.interpolate("linear") .interpolate("linear")
svg.append("path") svg.append("path")
.attr("d", d3line(line.points)) .attr("d", d3line(line.points))
.attr("transform", "translate(" + (margin + yAxisWidth * graphLineCount) + "," + margin + ")") .attr("transform", "translate(" + (margin + yAxisWidth * 2) + "," + margin + ")")
.style("stroke-width", 1) .style("stroke-width", line.strokeWidth)
.style("stroke", line.lineColor) .style("stroke", line.lineColor)
.style("fill", "none") .style("fill", "none")
currentLine++ currentLine++

View file

@ -0,0 +1,27 @@
// Print out campaign level counts
// Usage:
// mongo <address>:<port>/<database> <script file> -u <username> -p <password>
var cursor = db.campaigns.find({}, {slug: 1, levels: 1});
var allFree = 0;
var allPremium = 0;
while (cursor.hasNext()) {
var doc = cursor.next();
if (doc.slug === 'auditions') continue;
var free = 0;
var premium = 0;
for (var levelID in doc.levels) {
if (doc.levels[levelID].requiresSubscription) {
premium++;
}
else {
free++;
}
}
print(free + " " + premium + " " + (free + premium) + " " + doc.slug);
allFree += free;
allPremium += premium;
}
print(allFree + " " + allPremium + " " + (allFree + allPremium) + " overall");

View file

@ -13,8 +13,8 @@ if(config.stripe.secretKey.indexOf('sk_test_')==0) {
stripe = require('stripe')(config.stripe.secretKey); stripe = require('stripe')(config.stripe.secretKey);
var range = { var range = {
gt: ''+(new Date('2015-02-01').getTime()/1000), gt: ''+(new Date('2015-03-01').getTime()/1000),
lt: ''+(new Date('2015-03-01').getTime()/1000) lt: ''+(new Date('2015-04-01').getTime()/1000)
}; };
begin = function(starting_after) { begin = function(starting_after) {
@ -25,12 +25,14 @@ begin = function(starting_after) {
stripe.invoices.list(query, onInvoicesReceived); stripe.invoices.list(query, onInvoicesReceived);
} }
customersPaid = [] customersPaid = [];
onInvoicesReceived = function(err, invoices) { onInvoicesReceived = function(err, invoices) {
for(var i in invoices.data) { for(var i in invoices.data) {
var invoice = invoices.data[i]; var invoice = invoices.data[i];
if(!invoice.paid) { continue; } if(!invoice.paid) { continue; }
if(!invoice.total) { continue; } // not paying anything!
//console.log(invoice);
customersPaid.push(invoice.customer); customersPaid.push(invoice.customer);
} }
if(invoices.has_more) { if(invoices.has_more) {
@ -38,10 +40,10 @@ onInvoicesReceived = function(err, invoices) {
begin(invoices.data[i].id); begin(invoices.data[i].id);
} }
else { else {
console.log('How many customers paid for a subscription:', _.unique(customersPaid).length); console.log('--- Actual active total customers:', _.unique(customersPaid).length);
loadNewCustomers(); loadNewCustomers();
} }
} };
loadNewCustomers = function(starting_after) { loadNewCustomers = function(starting_after) {
query = {created: range, limit: 100}; query = {created: range, limit: 100};
@ -49,7 +51,7 @@ loadNewCustomers = function(starting_after) {
query.starting_after = starting_after; query.starting_after = starting_after;
} }
stripe.customers.list(query, onCustomersReceived); stripe.customers.list(query, onCustomersReceived);
} };
newCustomersPaid = []; newCustomersPaid = [];
@ -64,8 +66,8 @@ onCustomersReceived = function(err, customers) {
loadNewCustomers(customers.data[i].id); loadNewCustomers(customers.data[i].id);
} }
else { else {
console.log('How many new customers paid for a subscription:', newCustomersPaid.length); console.log('--- Actual new customers:', newCustomersPaid.length);
} }
} };
begin(); begin();