diff --git a/assets/blockly/msg/js/en.js b/assets/blockly/msg/js/en.js
index b5c5e2a..f480021 100755
--- a/assets/blockly/msg/js/en.js
+++ b/assets/blockly/msg/js/en.js
@@ -429,4 +429,17 @@ Blockly.Msg["VARIABLES_HUE"] = "330";
Blockly.Msg["TEXTS_HUE"] = "160";
Blockly.Msg["PROCEDURES_HUE"] = "290";
Blockly.Msg["COLOUR_HUE"] = "20";
-Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";
\ No newline at end of file
+Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";
+
+
+Blockly.Msg["SUMOROBOT_STOP"] = "Move STOP";
+Blockly.Msg["SUMOROBOT_LEFT"] = "Move Left";
+Blockly.Msg["SUMOROBOT_RIGHT"] = "Move Right";
+Blockly.Msg["SUMOROBOT_FORWARD"] = "Move Forward";
+Blockly.Msg["SUMOROBOT_BACKWARD"] = "Move Backward";
+Blockly.Msg["SUMOROBOT_SEARCH"] = "Move Search";
+Blockly.Msg["SUMOROBOT_OPPONENT"] = "Opponent";
+Blockly.Msg["SUMOROBOT_LINE_LEFT"] = "Line Left";
+Blockly.Msg["SUMOROBOT_LINE_MIDDLE"] = "Line Middle";
+Blockly.Msg["SUMOROBOT_LINE_RIGHT"] = "Line Right";
+Blockly.Msg["SUMOROBOT_SLEEP"] = "Sleep"
diff --git a/assets/blockly/msg/js/et.js b/assets/blockly/msg/js/et.js
new file mode 100644
index 0000000..4799007
--- /dev/null
+++ b/assets/blockly/msg/js/et.js
@@ -0,0 +1,447 @@
+// This file was automatically generated. Do not modify.
+
+'use strict';
+
+goog.provide('Blockly.Msg.et');
+
+goog.require('Blockly.Msg');
+
+Blockly.Msg["ADD_COMMENT"] = "Lisa kommentaar";
+Blockly.Msg["CANNOT_DELETE_VARIABLE_PROCEDURE"] = "Can't delete the variable '%1' because it's part of the definition of the function '%2'"; // untranslated
+Blockly.Msg["CHANGE_VALUE_TITLE"] = "Muuda väärtust:";
+Blockly.Msg["CLEAN_UP"] = "Korista plokid kokku";
+Blockly.Msg["COLLAPSE_ALL"] = "Tõmba plokid kokku";
+Blockly.Msg["COLLAPSE_BLOCK"] = "Tõmba plokk kokku";
+Blockly.Msg["COLOUR_BLEND_COLOUR1"] = "1. värvist";
+Blockly.Msg["COLOUR_BLEND_COLOUR2"] = "2. värvist";
+Blockly.Msg["COLOUR_BLEND_HELPURL"] = "http://meyerweb.com/eric/tools/color-blend/"; // untranslated
+Blockly.Msg["COLOUR_BLEND_RATIO"] = "suhtega";
+Blockly.Msg["COLOUR_BLEND_TITLE"] = "segu";
+Blockly.Msg["COLOUR_BLEND_TOOLTIP"] = "Segab kaks värvi määratud suhtega (0.0 - 1.0) kokku.";
+Blockly.Msg["COLOUR_PICKER_HELPURL"] = "https://en.wikipedia.org/wiki/Color";
+Blockly.Msg["COLOUR_PICKER_TOOLTIP"] = "Valitud värv paletist.";
+Blockly.Msg["COLOUR_RANDOM_HELPURL"] = "http://randomcolour.com"; // untranslated
+Blockly.Msg["COLOUR_RANDOM_TITLE"] = "juhuslik värv";
+Blockly.Msg["COLOUR_RANDOM_TOOLTIP"] = "Juhuslikult valitud värv.";
+Blockly.Msg["COLOUR_RGB_BLUE"] = "sinisest";
+Blockly.Msg["COLOUR_RGB_GREEN"] = "rohelisest";
+Blockly.Msg["COLOUR_RGB_HELPURL"] = "http://www.december.com/html/spec/colorper.html"; // untranslated
+Blockly.Msg["COLOUR_RGB_RED"] = "punasest";
+Blockly.Msg["COLOUR_RGB_TITLE"] = "segu";
+Blockly.Msg["COLOUR_RGB_TOOLTIP"] = "Tekitab värvi määratud hulgast punasest, rohelisest ja sinisest. Kõik väärtused peavad olema 0 ja 100 vahel.";
+Blockly.Msg["CONTROLS_FLOW_STATEMENTS_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks"; // untranslated
+Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK"] = "välju kordusest";
+Blockly.Msg["CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE"] = "katkesta see kordus ja liigu järgmisele";
+Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK"] = "Väljub kordusest ja liigub edasi korduse järel oleva koodi käivitamisele.";
+Blockly.Msg["CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE"] = "Katkestab korduses oleva koodi käivitamise ja käivitab järgmise korduse.";
+Blockly.Msg["CONTROLS_FLOW_STATEMENTS_WARNING"] = "Hoiatus: Seda plokki saab kasutada ainult korduse sees.";
+Blockly.Msg["CONTROLS_FOREACH_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#for-each"; // untranslated
+Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "iga elemendiga %1 loendis %2";
+Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "Iga elemendiga loendis anna muutujale '%1' elemendi väärtus ja kõivita plokis olevad käsud.";
+Blockly.Msg["CONTROLS_FOR_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#count-with"; // untranslated
+Blockly.Msg["CONTROLS_FOR_TITLE"] = "loendus muutujaga %1 alates %2 kuni %3, %4 kaupa";
+Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "Annab muutujale '%1' väärtused ühest numbrist teiseni, muutes seda intervalli kaupa ja käivitab igal muudatusel ploki sees oleva koodi.";
+Blockly.Msg["CONTROLS_IF_ELSEIF_TOOLTIP"] = "Lisab „kui“ plokile tingimuse.";
+Blockly.Msg["CONTROLS_IF_ELSE_TOOLTIP"] = "Lisab „kui“ plokile lõpliku tingimuseta koodiploki.";
+Blockly.Msg["CONTROLS_IF_HELPURL"] = "https://github.com/google/blockly/wiki/IfElse"; // untranslated
+Blockly.Msg["CONTROLS_IF_IF_TOOLTIP"] = "Selle „kui“ ploki muutmine sektsioonide lisamise, eemaldamise ja järjestamisega.";
+Blockly.Msg["CONTROLS_IF_MSG_ELSE"] = "vastasel juhul";
+Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"] = "vastasel juhul, kui";
+Blockly.Msg["CONTROLS_IF_MSG_IF"] = "kui";
+Blockly.Msg["CONTROLS_IF_TOOLTIP_1"] = "Kui avaldis on tõene, käivita ploki sees olevad käsud.";
+Blockly.Msg["CONTROLS_IF_TOOLTIP_2"] = "Kui avaldis on tõene, käivita käsud esimesest plokist. Vastasel juhul käivita käsud teisest plokist.";
+Blockly.Msg["CONTROLS_IF_TOOLTIP_3"] = "Kui esimene avaldis on tõene, käivita käsud esimesest plokist. Vastasel juhul, kui teine avaldis on tõene, käivita käsud teisest plokist.";
+Blockly.Msg["CONTROLS_IF_TOOLTIP_4"] = "Kui esimene avaldis on tõene, käivita käsud esimesest plokist. Vastasel juhul, kui teine avaldis on tõene, käivita käsud teisest plokist. Kui ükski avaldistest pole tõene, käivita käsud viimasest plokist.";
+Blockly.Msg["CONTROLS_REPEAT_HELPURL"] = "https://en.wikipedia.org/wiki/For_loop";
+Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "käivita";
+Blockly.Msg["CONTROLS_REPEAT_TITLE"] = "%1 korda";
+Blockly.Msg["CONTROLS_REPEAT_TOOLTIP"] = "Plokis olevate käskude käivitamine määratud arv kordi.";
+Blockly.Msg["CONTROLS_WHILEUNTIL_HELPURL"] = "https://github.com/google/blockly/wiki/Loops#repeat"; // untranslated
+Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_UNTIL"] = "seni kuni pole";
+Blockly.Msg["CONTROLS_WHILEUNTIL_OPERATOR_WHILE"] = "seni kuni on";
+Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL"] = "Plokis olevaid käske korratakse seni kui avaldis pole tõene.";
+Blockly.Msg["CONTROLS_WHILEUNTIL_TOOLTIP_WHILE"] = "Plokis olevaid käske korratakse seni kui avaldis on tõene.";
+Blockly.Msg["DELETE_ALL_BLOCKS"] = "Kas kustutada kõik %1 plokki?";
+Blockly.Msg["DELETE_BLOCK"] = "Kustuta plokk";
+Blockly.Msg["DELETE_VARIABLE"] = "Kustuta muutuja '%1'";
+Blockly.Msg["DELETE_VARIABLE_CONFIRMATION"] = "Kas kustutada %1 kohas kasutatav muutuja '%2'?";
+Blockly.Msg["DELETE_X_BLOCKS"] = "Kustuta %1 plokki";
+Blockly.Msg["DISABLE_BLOCK"] = "Keela ploki kasutamine";
+Blockly.Msg["DUPLICATE_BLOCK"] = "Tekita duplikaat";
+Blockly.Msg["DUPLICATE_COMMENT"] = "Duplicate Comment"; // untranslated
+Blockly.Msg["ENABLE_BLOCK"] = "Luba ploki kasutamine";
+Blockly.Msg["EXPAND_ALL"] = "Laota plokid laiali";
+Blockly.Msg["EXPAND_BLOCK"] = "Laota plokk laiali";
+Blockly.Msg["EXTERNAL_INPUTS"] = "Sisendid ploki taga";
+Blockly.Msg["HELP"] = "Abi";
+Blockly.Msg["INLINE_INPUTS"] = "Sisendid ploki sees";
+Blockly.Msg["IOS_CANCEL"] = "Cancel"; // untranslated
+Blockly.Msg["IOS_ERROR"] = "Error"; // untranslated
+Blockly.Msg["IOS_OK"] = "OK"; // untranslated
+Blockly.Msg["IOS_PROCEDURES_ADD_INPUT"] = "+ Add Input"; // untranslated
+Blockly.Msg["IOS_PROCEDURES_ALLOW_STATEMENTS"] = "Allow statements"; // untranslated
+Blockly.Msg["IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR"] = "This function has duplicate inputs."; // untranslated
+Blockly.Msg["IOS_PROCEDURES_INPUTS"] = "INPUTS"; // untranslated
+Blockly.Msg["IOS_VARIABLES_ADD_BUTTON"] = "Add"; // untranslated
+Blockly.Msg["IOS_VARIABLES_ADD_VARIABLE"] = "+ Add Variable"; // untranslated
+Blockly.Msg["IOS_VARIABLES_DELETE_BUTTON"] = "Kustuta";
+Blockly.Msg["IOS_VARIABLES_EMPTY_NAME_ERROR"] = "Tühja muutuja nime ei saa kasutada.";
+Blockly.Msg["IOS_VARIABLES_RENAME_BUTTON"] = "Rename"; // untranslated
+Blockly.Msg["IOS_VARIABLES_VARIABLE_NAME"] = "Muutuja nimi";
+Blockly.Msg["LISTS_CREATE_EMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-empty-list"; // untranslated
+Blockly.Msg["LISTS_CREATE_EMPTY_TITLE"] = "tühi loend";
+Blockly.Msg["LISTS_CREATE_EMPTY_TOOLTIP"] = "Tagastab loendi, mille pikkus on 0 ja milles pole ühtegi elementi.";
+Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TITLE_ADD"] = "loend";
+Blockly.Msg["LISTS_CREATE_WITH_CONTAINER_TOOLTIP"] = "Loendiploki elementide lisamine, eemaldamine või järjestuse muutmine.";
+Blockly.Msg["LISTS_CREATE_WITH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with"; // untranslated
+Blockly.Msg["LISTS_CREATE_WITH_INPUT_WITH"] = "uus loend";
+Blockly.Msg["LISTS_CREATE_WITH_ITEM_TOOLTIP"] = "Elemendi lisamine loendisse.";
+Blockly.Msg["LISTS_CREATE_WITH_TOOLTIP"] = "Tekitab mistahes arvust elementidest loendi.";
+Blockly.Msg["LISTS_GET_INDEX_FIRST"] = "esimene element";
+Blockly.Msg["LISTS_GET_INDEX_FROM_END"] = "element # (lõpust)";
+Blockly.Msg["LISTS_GET_INDEX_FROM_START"] = "element #";
+Blockly.Msg["LISTS_GET_INDEX_GET"] = "võetud";
+Blockly.Msg["LISTS_GET_INDEX_GET_REMOVE"] = "võetud ja eemaldatud";
+Blockly.Msg["LISTS_GET_INDEX_LAST"] = "viimane element";
+Blockly.Msg["LISTS_GET_INDEX_RANDOM"] = "juhuslik element";
+Blockly.Msg["LISTS_GET_INDEX_REMOVE"] = "eemalda";
+Blockly.Msg["LISTS_GET_INDEX_TAIL"] = ""; // untranslated
+Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FIRST"] = "Tagastab loendi esimese elemendi.";
+Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_FROM"] = "Tagastab loendis määratud asukohal oleva elemendi.";
+Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_LAST"] = "Tagastab loendi viimase elemendi.";
+Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_RANDOM"] = "Tagastab loendi juhusliku elemendi.";
+Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST"] = "Tagastab ja eemaldab loendist esimese elemendi.";
+Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM"] = "Tagastab ja eemaldab loendist määratud asukohal oleva elemendi.";
+Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST"] = "Tagastab ja eemaldab loendist viimase elemendi.";
+Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM"] = "Tagastab ja eemaldab loendist juhusliku elemendi.";
+Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST"] = "Eemaldab loendist esimese elemendi.";
+Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM"] = "Eemaldab loendist määratud asukohal oleva elemendi.";
+Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST"] = "Eemaldab loendist viimase elemendi.";
+Blockly.Msg["LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM"] = "Eemaldab loendist juhusliku elemendi.";
+Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_END"] = "elemendini # (lõpust)";
+Blockly.Msg["LISTS_GET_SUBLIST_END_FROM_START"] = "elemendini #";
+Blockly.Msg["LISTS_GET_SUBLIST_END_LAST"] = "lõpuni";
+Blockly.Msg["LISTS_GET_SUBLIST_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist"; // untranslated
+Blockly.Msg["LISTS_GET_SUBLIST_START_FIRST"] = "alamloend algusest";
+Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_END"] = "alamloend elemendist # (lõpust)";
+Blockly.Msg["LISTS_GET_SUBLIST_START_FROM_START"] = "alamloend elemendist #";
+Blockly.Msg["LISTS_GET_SUBLIST_TAIL"] = ""; // untranslated
+Blockly.Msg["LISTS_GET_SUBLIST_TOOLTIP"] = "Tekitab loendi määratud osast koopia.";
+Blockly.Msg["LISTS_INDEX_FROM_END_TOOLTIP"] = "Viimane element on %1.";
+Blockly.Msg["LISTS_INDEX_FROM_START_TOOLTIP"] = "Esimene element on %1.";
+Blockly.Msg["LISTS_INDEX_OF_FIRST"] = "esimene leitud";
+Blockly.Msg["LISTS_INDEX_OF_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list"; // untranslated
+Blockly.Msg["LISTS_INDEX_OF_LAST"] = "viimase leitud";
+Blockly.Msg["LISTS_INDEX_OF_TOOLTIP"] = "Tagastab esimese/viimase loendist leitud objekti asukoha (objekti järjekorranumbri loendis). Kui objekti ei leita, tagastab %1.";
+Blockly.Msg["LISTS_INLIST"] = "loendis";
+Blockly.Msg["LISTS_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#is-empty"; // untranslated
+Blockly.Msg["LISTS_ISEMPTY_TITLE"] = "%1 on tühi";
+Blockly.Msg["LISTS_ISEMPTY_TOOLTIP"] = "Tagastab „tõene“ kui loend on tühi.";
+Blockly.Msg["LISTS_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#length-of"; // untranslated
+Blockly.Msg["LISTS_LENGTH_TITLE"] = "%1 pikkus";
+Blockly.Msg["LISTS_LENGTH_TOOLTIP"] = "Tagastab loendi pikkuse.";
+Blockly.Msg["LISTS_REPEAT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#create-list-with"; // untranslated
+Blockly.Msg["LISTS_REPEAT_TITLE"] = "loend pikkusega %2 elemendist %1";
+Blockly.Msg["LISTS_REPEAT_TOOLTIP"] = "Tekitab uue loendi, millesse lisatakse ühte elementi pikkusega määratud arv kordi.";
+Blockly.Msg["LISTS_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#reversing-a-list"; // untranslated
+Blockly.Msg["LISTS_REVERSE_MESSAGE0"] = "reverse %1"; // untranslated
+Blockly.Msg["LISTS_REVERSE_TOOLTIP"] = "Reverse a copy of a list."; // untranslated
+Blockly.Msg["LISTS_SET_INDEX_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#in-list--set"; // untranslated
+Blockly.Msg["LISTS_SET_INDEX_INPUT_TO"] = ", väärtus";
+Blockly.Msg["LISTS_SET_INDEX_INSERT"] = "lisa asukohale";
+Blockly.Msg["LISTS_SET_INDEX_SET"] = "asenda";
+Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST"] = "Lisab loendi algusesse uue elemendi.";
+Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_FROM"] = "Lisab määratud asukohale loendis uue elemendi.";
+Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_LAST"] = "Lisab loendi lõppu uue elemendi.";
+Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM"] = "Lisab juhuslikule kohale loendis uue elemendi.";
+Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FIRST"] = "Asendab loendis esimese elemendi.";
+Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_FROM"] = "Asendab loendis määratud kohal oleva elemendi.";
+Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_LAST"] = "Asendab loendis viimase elemendi.";
+Blockly.Msg["LISTS_SET_INDEX_TOOLTIP_SET_RANDOM"] = "Asendab loendis juhusliku elemendi.";
+Blockly.Msg["LISTS_SORT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
+Blockly.Msg["LISTS_SORT_ORDER_ASCENDING"] = "kasvavalt";
+Blockly.Msg["LISTS_SORT_ORDER_DESCENDING"] = "kahanevalt";
+Blockly.Msg["LISTS_SORT_TITLE"] = "%1 %2 sorteeritud %3";
+Blockly.Msg["LISTS_SORT_TOOLTIP"] = "Loendi koopia sorteerimine.";
+Blockly.Msg["LISTS_SORT_TYPE_IGNORECASE"] = "tähestiku järgi (tähesuurust eirates)";
+Blockly.Msg["LISTS_SORT_TYPE_NUMERIC"] = "arvväärtuste järgi";
+Blockly.Msg["LISTS_SORT_TYPE_TEXT"] = "tähestiku järgi";
+Blockly.Msg["LISTS_SPLIT_HELPURL"] = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists"; // untranslated
+Blockly.Msg["LISTS_SPLIT_LIST_FROM_TEXT"] = "loend, tekitatud tekstist";
+Blockly.Msg["LISTS_SPLIT_TEXT_FROM_LIST"] = "tekst, tekitatud loendist";
+Blockly.Msg["LISTS_SPLIT_TOOLTIP_JOIN"] = "Ühendab tekstide loendis olevad tükid üheks tekstiks, asetades tükkide vahele eraldaja.";
+Blockly.Msg["LISTS_SPLIT_TOOLTIP_SPLIT"] = "Tükeldab teksti eraldajade kohalt ja asetab tükid tekstide loendisse.";
+Blockly.Msg["LISTS_SPLIT_WITH_DELIMITER"] = "eraldajaga";
+Blockly.Msg["LOGIC_BOOLEAN_FALSE"] = "väär";
+Blockly.Msg["LOGIC_BOOLEAN_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#values"; // untranslated
+Blockly.Msg["LOGIC_BOOLEAN_TOOLTIP"] = "Tagastab tõeväärtuse – kas „tõene“ või „väär“.";
+Blockly.Msg["LOGIC_BOOLEAN_TRUE"] = "tõene";
+Blockly.Msg["LOGIC_COMPARE_HELPURL"] = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
+Blockly.Msg["LOGIC_COMPARE_TOOLTIP_EQ"] = "Tagastab „tõene“, kui avaldiste väärtused on võrdsed.";
+Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GT"] = "Tagastab „tõene“, kui esimese avaldise väärtus on suurem kui teise väärtus.";
+Blockly.Msg["LOGIC_COMPARE_TOOLTIP_GTE"] = "Tagastab „tõene“, kui esimese avaldise väärtus on suurem või võrdne teise väärtusega.";
+Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LT"] = "Tagastab „tõene“, kui esimese avaldise väärtus on väiksem kui teise väärtus.";
+Blockly.Msg["LOGIC_COMPARE_TOOLTIP_LTE"] = "Tagastab „tõene“, kui esimese avaldise väärtus on väiksem või võrdne teise väärtusega.";
+Blockly.Msg["LOGIC_COMPARE_TOOLTIP_NEQ"] = "Tagastab „tõene“, kui avaldiste väärtused pole võrdsed.";
+Blockly.Msg["LOGIC_NEGATE_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#not"; // untranslated
+Blockly.Msg["LOGIC_NEGATE_TITLE"] = "pole %1";
+Blockly.Msg["LOGIC_NEGATE_TOOLTIP"] = "Tagastab „tõene“, kui avaldis on väär. Tagastab „väär“, kui avaldis on tõene.";
+Blockly.Msg["LOGIC_NULL"] = "null";
+Blockly.Msg["LOGIC_NULL_HELPURL"] = "https://en.wikipedia.org/wiki/Nullable_type"; // untranslated
+Blockly.Msg["LOGIC_NULL_TOOLTIP"] = "Tagastab nulli.";
+Blockly.Msg["LOGIC_OPERATION_AND"] = "ja";
+Blockly.Msg["LOGIC_OPERATION_HELPURL"] = "https://github.com/google/blockly/wiki/Logic#logical-operations"; // untranslated
+Blockly.Msg["LOGIC_OPERATION_OR"] = "või";
+Blockly.Msg["LOGIC_OPERATION_TOOLTIP_AND"] = "Tagastab „tõene“, kui mõlemad avaldised on tõesed.";
+Blockly.Msg["LOGIC_OPERATION_TOOLTIP_OR"] = "Tagastab „tõene“, kui vähemalt üks avaldistest on tõene.";
+Blockly.Msg["LOGIC_TERNARY_CONDITION"] = "tingimus";
+Blockly.Msg["LOGIC_TERNARY_HELPURL"] = "https://en.wikipedia.org/wiki/%3F:"; // untranslated
+Blockly.Msg["LOGIC_TERNARY_IF_FALSE"] = "kui väär";
+Blockly.Msg["LOGIC_TERNARY_IF_TRUE"] = "kui tõene";
+Blockly.Msg["LOGIC_TERNARY_TOOLTIP"] = "Kui tingimuse väärtus on tõene, tagastab „kui tõene“ väärtuse, vastasel juhul „kui väär“ väärtuse.";
+Blockly.Msg["MATH_ADDITION_SYMBOL"] = "+"; // untranslated
+Blockly.Msg["MATH_ARITHMETIC_HELPURL"] = "https://et.wikipedia.org/wiki/Aritmeetika";
+Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_ADD"] = "Tagastab kahe arvu summa.";
+Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_DIVIDE"] = "Tagastab kahe arvu jagatise.";
+Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MINUS"] = "Tagastab kahe arvu vahe.";
+Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_MULTIPLY"] = "Tagastab kahe arvu korrutise.";
+Blockly.Msg["MATH_ARITHMETIC_TOOLTIP_POWER"] = "Tagastab esimese arvu teise arvu astmes.";
+Blockly.Msg["MATH_ATAN2_HELPURL"] = "https://en.wikipedia.org/wiki/Atan2"; // untranslated
+Blockly.Msg["MATH_ATAN2_TITLE"] = "atan2 of X:%1 Y:%2"; // untranslated
+Blockly.Msg["MATH_ATAN2_TOOLTIP"] = "Return the arctangent of point (X, Y) in degrees from -180 to 180."; // untranslated
+Blockly.Msg["MATH_CHANGE_HELPURL"] = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
+Blockly.Msg["MATH_CHANGE_TITLE"] = "muuda %1 %2 võrra";
+Blockly.Msg["MATH_CHANGE_TOOLTIP"] = "Lisab arvu muutujale '%1'.";
+Blockly.Msg["MATH_CONSTANT_HELPURL"] = "https://en.wikipedia.org/wiki/Mathematical_constant";
+Blockly.Msg["MATH_CONSTANT_TOOLTIP"] = "Tagastab ühe konstantidest: π (3,141…), e (2,718…), φ (1.618…), √2) (1,414…), √½ (0,707…), või ∞ (infinity).";
+Blockly.Msg["MATH_CONSTRAIN_HELPURL"] = "https://en.wikipedia.org/wiki/Clamping_(graphics)"; // untranslated
+Blockly.Msg["MATH_CONSTRAIN_TITLE"] = "%1 piirang %2 ja %3 vahele";
+Blockly.Msg["MATH_CONSTRAIN_TOOLTIP"] = "Piirab arvu väärtuse toodud piiridesse (piirarvud kaasa arvatud).";
+Blockly.Msg["MATH_DIVISION_SYMBOL"] = "÷"; // untranslated
+Blockly.Msg["MATH_IS_DIVISIBLE_BY"] = "jagub arvuga";
+Blockly.Msg["MATH_IS_EVEN"] = "on paarisarv";
+Blockly.Msg["MATH_IS_NEGATIVE"] = "on negatiivne arv";
+Blockly.Msg["MATH_IS_ODD"] = "on paaritu arv";
+Blockly.Msg["MATH_IS_POSITIVE"] = "on positiivne arv";
+Blockly.Msg["MATH_IS_PRIME"] = "on algarv";
+Blockly.Msg["MATH_IS_TOOLTIP"] = "Kontrollib kas arv on paarisarv, paaritu arv, algarv, täisarv, positiivne, negatiivne või jagub kindla arvuga. Tagastab „tõene“ või „väär“.";
+Blockly.Msg["MATH_IS_WHOLE"] = "on täisarv";
+Blockly.Msg["MATH_MODULO_HELPURL"] = "https://en.wikipedia.org/wiki/Modulo_operation";
+Blockly.Msg["MATH_MODULO_TITLE"] = "%1 ÷ %2 jääk";
+Blockly.Msg["MATH_MODULO_TOOLTIP"] = "Tagastab esimese numbri teisega jagamisel tekkiva jäägi.";
+Blockly.Msg["MATH_MULTIPLICATION_SYMBOL"] = "×"; // untranslated
+Blockly.Msg["MATH_NUMBER_HELPURL"] = "https://et.wikipedia.org/wiki/Arv";
+Blockly.Msg["MATH_NUMBER_TOOLTIP"] = "Arv.";
+Blockly.Msg["MATH_ONLIST_HELPURL"] = ""; // untranslated
+Blockly.Msg["MATH_ONLIST_OPERATOR_AVERAGE"] = "loendi keskmine";
+Blockly.Msg["MATH_ONLIST_OPERATOR_MAX"] = "loendi maksimum";
+Blockly.Msg["MATH_ONLIST_OPERATOR_MEDIAN"] = "loendi mediaan";
+Blockly.Msg["MATH_ONLIST_OPERATOR_MIN"] = "loendi miinimum";
+Blockly.Msg["MATH_ONLIST_OPERATOR_MODE"] = "loendi moodid";
+Blockly.Msg["MATH_ONLIST_OPERATOR_RANDOM"] = "juhuslik element loendist";
+Blockly.Msg["MATH_ONLIST_OPERATOR_STD_DEV"] = "loendi standardhälve";
+Blockly.Msg["MATH_ONLIST_OPERATOR_SUM"] = "loendi summa";
+Blockly.Msg["MATH_ONLIST_TOOLTIP_AVERAGE"] = "Tagastab loendis olevate arvväärtuste aritmeetilise keskmise.";
+Blockly.Msg["MATH_ONLIST_TOOLTIP_MAX"] = "Tagastab suurima loendis oleva arvu.";
+Blockly.Msg["MATH_ONLIST_TOOLTIP_MEDIAN"] = "Return the median number in the list.";
+Blockly.Msg["MATH_ONLIST_TOOLTIP_MIN"] = "Tagastab väikseima loendis oleva arvu.";
+Blockly.Msg["MATH_ONLIST_TOOLTIP_MODE"] = "Tagastab loendi kõige sagedamini esinevate loendi liikmetega.";
+Blockly.Msg["MATH_ONLIST_TOOLTIP_RANDOM"] = "Tagastab juhusliku elemendi loendist.";
+Blockly.Msg["MATH_ONLIST_TOOLTIP_STD_DEV"] = "Tagastab loendi standardhälbe.";
+Blockly.Msg["MATH_ONLIST_TOOLTIP_SUM"] = "Tagastab kõigi loendis olevate arvude summa.";
+Blockly.Msg["MATH_POWER_SYMBOL"] = "^"; // untranslated
+Blockly.Msg["MATH_RANDOM_FLOAT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
+Blockly.Msg["MATH_RANDOM_FLOAT_TITLE_RANDOM"] = "juhuslik murdosa";
+Blockly.Msg["MATH_RANDOM_FLOAT_TOOLTIP"] = "Tagastab juhusliku murdosa 0.0 (kaasa arvatud) and 1.0 (välja arvatud) vahel.";
+Blockly.Msg["MATH_RANDOM_INT_HELPURL"] = "https://en.wikipedia.org/wiki/Random_number_generation";
+Blockly.Msg["MATH_RANDOM_INT_TITLE"] = "juhuslik täisarv %1 ja %2 vahel";
+Blockly.Msg["MATH_RANDOM_INT_TOOLTIP"] = "Tagastab juhusliku täisarvu toodud piiride vahel (piirarvud kaasa arvatud).";
+Blockly.Msg["MATH_ROUND_HELPURL"] = "https://en.wikipedia.org/wiki/Rounding";
+Blockly.Msg["MATH_ROUND_OPERATOR_ROUND"] = "ümarda";
+Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDDOWN"] = "ümarda alla";
+Blockly.Msg["MATH_ROUND_OPERATOR_ROUNDUP"] = "ümarda üles";
+Blockly.Msg["MATH_ROUND_TOOLTIP"] = "Ümardab arvu üles või alla.";
+Blockly.Msg["MATH_SINGLE_HELPURL"] = "https://et.wikipedia.org/wiki/Ruutjuur";
+Blockly.Msg["MATH_SINGLE_OP_ABSOLUTE"] = "absoluutväärtus";
+Blockly.Msg["MATH_SINGLE_OP_ROOT"] = "ruutjuur";
+Blockly.Msg["MATH_SINGLE_TOOLTIP_ABS"] = "Tagastab arvu absoluutväärtuse.";
+Blockly.Msg["MATH_SINGLE_TOOLTIP_EXP"] = "Tagasta e arvu astmes.";
+Blockly.Msg["MATH_SINGLE_TOOLTIP_LN"] = "Tagastab arvu naturaallogaritmi.";
+Blockly.Msg["MATH_SINGLE_TOOLTIP_LOG10"] = "Tagastab arvu kümnendlogaritm.";
+Blockly.Msg["MATH_SINGLE_TOOLTIP_NEG"] = "Tagastab arvu vastandväärtuse.";
+Blockly.Msg["MATH_SINGLE_TOOLTIP_POW10"] = "Tagastab 10 arvu astmes.";
+Blockly.Msg["MATH_SINGLE_TOOLTIP_ROOT"] = "Tagastab arvu ruutjuure.";
+Blockly.Msg["MATH_SUBTRACTION_SYMBOL"] = "-"; // untranslated
+Blockly.Msg["MATH_TRIG_ACOS"] = "acos"; // untranslated
+Blockly.Msg["MATH_TRIG_ASIN"] = "asin"; // untranslated
+Blockly.Msg["MATH_TRIG_ATAN"] = "atan"; // untranslated
+Blockly.Msg["MATH_TRIG_COS"] = "cos"; // untranslated
+Blockly.Msg["MATH_TRIG_HELPURL"] = "https://et.wikipedia.org/wiki/Trigonomeetrilised_funktsioonid";
+Blockly.Msg["MATH_TRIG_SIN"] = "sin"; // untranslated
+Blockly.Msg["MATH_TRIG_TAN"] = "tan"; // untranslated
+Blockly.Msg["MATH_TRIG_TOOLTIP_ACOS"] = "Tagastab arvu arkuskoosiinuse.";
+Blockly.Msg["MATH_TRIG_TOOLTIP_ASIN"] = "Tagastab arvu arkussiinuse.";
+Blockly.Msg["MATH_TRIG_TOOLTIP_ATAN"] = "Tagastab arvu arkustangensi.";
+Blockly.Msg["MATH_TRIG_TOOLTIP_COS"] = "Tagastab arvu (kraadid) kosiinuse.";
+Blockly.Msg["MATH_TRIG_TOOLTIP_SIN"] = "Tagastab arvu (kraadid) siinuse.";
+Blockly.Msg["MATH_TRIG_TOOLTIP_TAN"] = "Tagastab arvu (kraadid) tangensi.";
+Blockly.Msg["NEW_COLOUR_VARIABLE"] = "Create colour variable..."; // untranslated
+Blockly.Msg["NEW_NUMBER_VARIABLE"] = "Create number variable..."; // untranslated
+Blockly.Msg["NEW_STRING_VARIABLE"] = "Create string variable..."; // untranslated
+Blockly.Msg["NEW_VARIABLE"] = "Uus muutuja ...";
+Blockly.Msg["NEW_VARIABLE_TITLE"] = "Uue muutuja nimi:";
+Blockly.Msg["NEW_VARIABLE_TYPE_TITLE"] = "New variable type:"; // untranslated
+Blockly.Msg["ORDINAL_NUMBER_SUFFIX"] = ""; // untranslated
+Blockly.Msg["PROCEDURES_ALLOW_STATEMENTS"] = "kood plokis";
+Blockly.Msg["PROCEDURES_BEFORE_PARAMS"] = "sisenditega:";
+Blockly.Msg["PROCEDURES_CALLNORETURN_HELPURL"] = "https://et.wikipedia.org/wiki/Alamprogramm";
+Blockly.Msg["PROCEDURES_CALLNORETURN_TOOLTIP"] = "Käivitab kasutaja defineeritud funktsiooni '%1'.";
+Blockly.Msg["PROCEDURES_CALLRETURN_HELPURL"] = "https://et.wikipedia.org/wiki/Alamprogramm";
+Blockly.Msg["PROCEDURES_CALLRETURN_TOOLTIP"] = "Run the user-defined function '%1' and use its output.";
+Blockly.Msg["PROCEDURES_CALL_BEFORE_PARAMS"] = "sisenditega:";
+Blockly.Msg["PROCEDURES_CREATE_DO"] = "Tekita '%1' plokk";
+Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"] = "Funktsiooni kirjeldus ...";
+Blockly.Msg["PROCEDURES_DEFNORETURN_DO"] = ""; // untranslated
+Blockly.Msg["PROCEDURES_DEFNORETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine"; // untranslated
+Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"] = "teeme midagi";
+Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"] = "funktsioon";
+Blockly.Msg["PROCEDURES_DEFNORETURN_TOOLTIP"] = "Tekitab funktsiooni, mis ei tagasta midagi.";
+Blockly.Msg["PROCEDURES_DEFRETURN_HELPURL"] = "https://en.wikipedia.org/wiki/Subroutine"; // untranslated
+Blockly.Msg["PROCEDURES_DEFRETURN_RETURN"] = "tagasta";
+Blockly.Msg["PROCEDURES_DEFRETURN_TOOLTIP"] = "Tekitab funktsiooni, mis tagastab midagi.";
+Blockly.Msg["PROCEDURES_DEF_DUPLICATE_WARNING"] = "Hoiatus: Sel funktsioonil on mitu sama nimega sisendit.";
+Blockly.Msg["PROCEDURES_HIGHLIGHT_DEF"] = "Tõsta funktsiooni definitsioon esile";
+Blockly.Msg["PROCEDURES_IFRETURN_HELPURL"] = "http://c2.com/cgi/wiki?GuardClause"; // untranslated
+Blockly.Msg["PROCEDURES_IFRETURN_TOOLTIP"] = "Kui väärtus on tõene, tagastatakse teine väärtus.";
+Blockly.Msg["PROCEDURES_IFRETURN_WARNING"] = "Hoiatus: Seda plokki saab kasutada ainult funktsiooni definitsioonis.";
+Blockly.Msg["PROCEDURES_MUTATORARG_TITLE"] = "sisend nimega:";
+Blockly.Msg["PROCEDURES_MUTATORARG_TOOLTIP"] = "Lisab funktsioonile sisendi.";
+Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TITLE"] = "sisendid";
+Blockly.Msg["PROCEDURES_MUTATORCONTAINER_TOOLTIP"] = "Funktsiooni sisendite lisamine, eemaldamine või järjestuse muutmine.";
+Blockly.Msg["REDO"] = "Tee uuesti";
+Blockly.Msg["REMOVE_COMMENT"] = "Eemalda kommentaar";
+Blockly.Msg["RENAME_VARIABLE"] = "Nimeta muutuja ümber ...";
+Blockly.Msg["RENAME_VARIABLE_TITLE"] = "Muutuja „%1“ uus nimi:";
+Blockly.Msg["TEXT_APPEND_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification"; // untranslated
+Blockly.Msg["TEXT_APPEND_TITLE"] = "lisa muutuja %1 lõppu tekst %2";
+Blockly.Msg["TEXT_APPEND_TOOLTIP"] = "Lisab teksti muutuja „%1“ väärtuse lõppu.";
+Blockly.Msg["TEXT_CHANGECASE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#adjusting-text-case"; // untranslated
+Blockly.Msg["TEXT_CHANGECASE_OPERATOR_LOWERCASE"] = "väikeste tähtedega";
+Blockly.Msg["TEXT_CHANGECASE_OPERATOR_TITLECASE"] = "Suurte Esitähtedega";
+Blockly.Msg["TEXT_CHANGECASE_OPERATOR_UPPERCASE"] = "SUURTE TÄHTEDEGA";
+Blockly.Msg["TEXT_CHANGECASE_TOOLTIP"] = "Tagastab muudetud tähesuurusega teksti koopia.";
+Blockly.Msg["TEXT_CHARAT_FIRST"] = "esimene sümbol";
+Blockly.Msg["TEXT_CHARAT_FROM_END"] = "lõpust sümbol #";
+Blockly.Msg["TEXT_CHARAT_FROM_START"] = "sümbol #";
+Blockly.Msg["TEXT_CHARAT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-text"; // untranslated
+Blockly.Msg["TEXT_CHARAT_LAST"] = "viimane sümbol";
+Blockly.Msg["TEXT_CHARAT_RANDOM"] = "juhuslik sümbol";
+Blockly.Msg["TEXT_CHARAT_TAIL"] = ""; // untranslated
+Blockly.Msg["TEXT_CHARAT_TITLE"] = "in text %1 %2"; // untranslated
+Blockly.Msg["TEXT_CHARAT_TOOLTIP"] = "Tagastab tekstis määratud asukohal oleva sümboli.";
+Blockly.Msg["TEXT_COUNT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#counting-substrings"; // untranslated
+Blockly.Msg["TEXT_COUNT_MESSAGE0"] = "count %1 in %2"; // untranslated
+Blockly.Msg["TEXT_COUNT_TOOLTIP"] = "Loenda, mitu korda mingi tekst esineb teise teksti sees.";
+Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TOOLTIP"] = "Objekti lisamine tekstile.";
+Blockly.Msg["TEXT_CREATE_JOIN_TITLE_JOIN"] = "ühenda";
+Blockly.Msg["TEXT_CREATE_JOIN_TOOLTIP"] = "Tekstiploki muutmine sektsioonide lisamise, eemaldamise või järjestuse muutmisega.";
+Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_END"] = "kuni (lõpust) sümbolini #";
+Blockly.Msg["TEXT_GET_SUBSTRING_END_FROM_START"] = "kuni sümbolini #";
+Blockly.Msg["TEXT_GET_SUBSTRING_END_LAST"] = "kuni viimase sümbolini";
+Blockly.Msg["TEXT_GET_SUBSTRING_HELPURL"] = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text"; // untranslated
+Blockly.Msg["TEXT_GET_SUBSTRING_INPUT_IN_TEXT"] = "tekstist";
+Blockly.Msg["TEXT_GET_SUBSTRING_START_FIRST"] = "alates esimesest sümbolist";
+Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_END"] = "alates (lõpust) sümbolist #";
+Blockly.Msg["TEXT_GET_SUBSTRING_START_FROM_START"] = "alates sümbolist #";
+Blockly.Msg["TEXT_GET_SUBSTRING_TAIL"] = ""; // untranslated
+Blockly.Msg["TEXT_GET_SUBSTRING_TOOLTIP"] = "Tagastab määratud tüki tekstist.";
+Blockly.Msg["TEXT_INDEXOF_HELPURL"] = "https://github.com/google/blockly/wiki/Text#finding-text"; // untranslated
+Blockly.Msg["TEXT_INDEXOF_OPERATOR_FIRST"] = "esimese leitud tekstitüki";
+Blockly.Msg["TEXT_INDEXOF_OPERATOR_LAST"] = "viimase leitud tekstitüki";
+Blockly.Msg["TEXT_INDEXOF_TITLE"] = "tekstist %1 %2 %3 asukoht";
+Blockly.Msg["TEXT_INDEXOF_TOOLTIP"] = "Tagastab esimesest tekstist esimese/viimase leitud teise teksti asukoha (indeksi). Kui teksti ei leita, tagastab %1.";
+Blockly.Msg["TEXT_ISEMPTY_HELPURL"] = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text"; // untranslated
+Blockly.Msg["TEXT_ISEMPTY_TITLE"] = "%1 on tühi";
+Blockly.Msg["TEXT_ISEMPTY_TOOLTIP"] = "Tagastab „tõene“, kui tekstis pole ühtegi sümbolit.";
+Blockly.Msg["TEXT_JOIN_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-creation"; // untranslated
+Blockly.Msg["TEXT_JOIN_TITLE_CREATEWITH"] = "tekita tekst";
+Blockly.Msg["TEXT_JOIN_TOOLTIP"] = "Tekitab teksti ühendades mistahes arvu elemente.";
+Blockly.Msg["TEXT_LENGTH_HELPURL"] = "https://github.com/google/blockly/wiki/Text#text-modification"; // untranslated
+Blockly.Msg["TEXT_LENGTH_TITLE"] = "%1 pikkus";
+Blockly.Msg["TEXT_LENGTH_TOOLTIP"] = "Tagastab sümbolite aru (ka tühikud) toodud tekstis.";
+Blockly.Msg["TEXT_PRINT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#printing-text"; // untranslated
+Blockly.Msg["TEXT_PRINT_TITLE"] = "trüki %1";
+Blockly.Msg["TEXT_PRINT_TOOLTIP"] = "Trükib määratud teksti, numbri või mõne muu objekti väärtuse.";
+Blockly.Msg["TEXT_PROMPT_HELPURL"] = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user"; // untranslated
+Blockly.Msg["TEXT_PROMPT_TOOLTIP_NUMBER"] = "Küsib kasutajalt teadet näidates mingit arvu.";
+Blockly.Msg["TEXT_PROMPT_TOOLTIP_TEXT"] = "Küsib kasutajalt teadet näidates mingit teksti.";
+Blockly.Msg["TEXT_PROMPT_TYPE_NUMBER"] = "kasutajalt küsitud arv teatega";
+Blockly.Msg["TEXT_PROMPT_TYPE_TEXT"] = "kasutajalt küsitud tekst teatega";
+Blockly.Msg["TEXT_REPLACE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#replacing-substrings"; // untranslated
+Blockly.Msg["TEXT_REPLACE_MESSAGE0"] = "replace %1 with %2 in %3"; // untranslated
+Blockly.Msg["TEXT_REPLACE_TOOLTIP"] = "Replace all occurances of some text within some other text."; // untranslated
+Blockly.Msg["TEXT_REVERSE_HELPURL"] = "https://github.com/google/blockly/wiki/Text#reversing-text"; // untranslated
+Blockly.Msg["TEXT_REVERSE_MESSAGE0"] = "reverse %1"; // untranslated
+Blockly.Msg["TEXT_REVERSE_TOOLTIP"] = "Reverses the order of the characters in the text."; // untranslated
+Blockly.Msg["TEXT_TEXT_HELPURL"] = "https://en.wikipedia.org/wiki/String_(computer_science)";
+Blockly.Msg["TEXT_TEXT_TOOLTIP"] = "Täht, sõna või rida teksti.";
+Blockly.Msg["TEXT_TRIM_HELPURL"] = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces"; // untranslated
+Blockly.Msg["TEXT_TRIM_OPERATOR_BOTH"] = "mõlemalt poolt eemaldatud tühikutega";
+Blockly.Msg["TEXT_TRIM_OPERATOR_LEFT"] = "algusest eemaldatud tühikutega";
+Blockly.Msg["TEXT_TRIM_OPERATOR_RIGHT"] = "lõpust eemaldatud tühikutega";
+Blockly.Msg["TEXT_TRIM_TOOLTIP"] = "Tagastab koopia tekstist, millel on tühikud ühelt või mõlemalt poolt eemaldatud.";
+Blockly.Msg["TODAY"] = "Täna";
+Blockly.Msg["UNDO"] = "Võta tagasi";
+Blockly.Msg["VARIABLES_DEFAULT_NAME"] = "objekt";
+Blockly.Msg["VARIABLES_GET_CREATE_SET"] = "Tekita 'määra „%1“ väärtuseks' plokk";
+Blockly.Msg["VARIABLES_GET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#get"; // untranslated
+Blockly.Msg["VARIABLES_GET_TOOLTIP"] = "Tagastab selle muutuja väärtuse.";
+Blockly.Msg["VARIABLES_SET"] = "määra %1 väärtuseks %2";
+Blockly.Msg["VARIABLES_SET_CREATE_GET"] = "Tekita '„%1“ väärtus' plokk";
+Blockly.Msg["VARIABLES_SET_HELPURL"] = "https://github.com/google/blockly/wiki/Variables#set"; // untranslated
+Blockly.Msg["VARIABLES_SET_TOOLTIP"] = "Määrab selle muutuja väärtuse võrdseks sisendi väärtusega.";
+Blockly.Msg["VARIABLE_ALREADY_EXISTS"] = "'%1'-nimeline muutuja on juba olemas.";
+Blockly.Msg["VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE"] = "A variable named '%1' already exists for another type: '%2'."; // untranslated
+Blockly.Msg["WORKSPACE_COMMENT_DEFAULT_TEXT"] = "Say something..."; // untranslated
+Blockly.Msg["PROCEDURES_DEFRETURN_TITLE"] = Blockly.Msg["PROCEDURES_DEFNORETURN_TITLE"];
+Blockly.Msg["CONTROLS_IF_IF_TITLE_IF"] = Blockly.Msg["CONTROLS_IF_MSG_IF"];
+Blockly.Msg["CONTROLS_WHILEUNTIL_INPUT_DO"] = Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"];
+Blockly.Msg["CONTROLS_IF_MSG_THEN"] = Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"];
+Blockly.Msg["CONTROLS_IF_ELSE_TITLE_ELSE"] = Blockly.Msg["CONTROLS_IF_MSG_ELSE"];
+Blockly.Msg["PROCEDURES_DEFRETURN_PROCEDURE"] = Blockly.Msg["PROCEDURES_DEFNORETURN_PROCEDURE"];
+Blockly.Msg["LISTS_GET_SUBLIST_INPUT_IN_LIST"] = Blockly.Msg["LISTS_INLIST"];
+Blockly.Msg["LISTS_GET_INDEX_INPUT_IN_LIST"] = Blockly.Msg["LISTS_INLIST"];
+Blockly.Msg["MATH_CHANGE_TITLE_ITEM"] = Blockly.Msg["VARIABLES_DEFAULT_NAME"];
+Blockly.Msg["PROCEDURES_DEFRETURN_DO"] = Blockly.Msg["PROCEDURES_DEFNORETURN_DO"];
+Blockly.Msg["CONTROLS_IF_ELSEIF_TITLE_ELSEIF"] = Blockly.Msg["CONTROLS_IF_MSG_ELSEIF"];
+Blockly.Msg["LISTS_GET_INDEX_HELPURL"] = Blockly.Msg["LISTS_INDEX_OF_HELPURL"];
+Blockly.Msg["CONTROLS_FOREACH_INPUT_DO"] = Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"];
+Blockly.Msg["LISTS_SET_INDEX_INPUT_IN_LIST"] = Blockly.Msg["LISTS_INLIST"];
+Blockly.Msg["CONTROLS_FOR_INPUT_DO"] = Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"];
+Blockly.Msg["LISTS_CREATE_WITH_ITEM_TITLE"] = Blockly.Msg["VARIABLES_DEFAULT_NAME"];
+Blockly.Msg["TEXT_APPEND_VARIABLE"] = Blockly.Msg["VARIABLES_DEFAULT_NAME"];
+Blockly.Msg["TEXT_CREATE_JOIN_ITEM_TITLE_ITEM"] = Blockly.Msg["VARIABLES_DEFAULT_NAME"];
+Blockly.Msg["LISTS_INDEX_OF_INPUT_IN_LIST"] = Blockly.Msg["LISTS_INLIST"];
+Blockly.Msg["PROCEDURES_DEFRETURN_COMMENT"] = Blockly.Msg["PROCEDURES_DEFNORETURN_COMMENT"];
+
+Blockly.Msg["MATH_HUE"] = "230";
+Blockly.Msg["LOOPS_HUE"] = "120";
+Blockly.Msg["LISTS_HUE"] = "260";
+Blockly.Msg["LOGIC_HUE"] = "210";
+Blockly.Msg["VARIABLES_HUE"] = "330";
+Blockly.Msg["TEXTS_HUE"] = "160";
+Blockly.Msg["PROCEDURES_HUE"] = "290";
+Blockly.Msg["COLOUR_HUE"] = "20";
+Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";
+
+Blockly.Msg["SUMOROBOT_STOP"] = "Liigu Peatu";
+Blockly.Msg["SUMOROBOT_LEFT"] = "Liigu Vasakule";
+Blockly.Msg["SUMOROBOT_RIGHT"] = "Liigu Paremale";
+Blockly.Msg["SUMOROBOT_FORWARD"] = "Liigu Edasi";
+Blockly.Msg["SUMOROBOT_BACKWARD"] = "Liigu Tagsi";
+Blockly.Msg["SUMOROBOT_SEARCH"] = "Liigu Otsi";
+Blockly.Msg["SUMOROBOT_OPPONENT"] = "Vastane";
+Blockly.Msg["SUMOROBOT_LINE_LEFT"] = "Joon vasakul";
+Blockly.Msg["SUMOROBOT_LINE_MIDDLE"] = "Joon keskel";
+Blockly.Msg["SUMOROBOT_LINE_RIGHT"] = "Joon paremal";
+Blockly.Msg["SUMOROBOT_SLEEP"] = "Maga"
diff --git a/assets/img/checkmark-64.png b/assets/img/checkmark-64.png
new file mode 100644
index 0000000..cf6c291
Binary files /dev/null and b/assets/img/checkmark-64.png differ
diff --git a/assets/js/blockly.js b/assets/js/blockly.js
index 3f8eb50..9b0d94d 100755
--- a/assets/js/blockly.js
+++ b/assets/js/blockly.js
@@ -1,6 +1,7 @@
// Blockly workspace
var workspace;
+
window.addEventListener('load', function() {
// To remember the control_if blockId
var controlBlockId = '';
@@ -10,29 +11,58 @@ window.addEventListener('load', function() {
// Remote previous and next statement from control_if block
Blockly.defineBlocksWithJsonArray([
- {
- "type": "controls_if",
- "message0": "%{BKY_CONTROLS_IF_MSG_IF} %1",
- "args0": [
- {
- "type": "input_value",
- "name": "IF0",
- "check": "Boolean"
- }
- ],
- "message1": "%{BKY_CONTROLS_IF_MSG_THEN} %1",
- "args1": [
- {
- "type": "input_statement",
- "name": "DO0"
- }
- ],
- "colour": "%{BKY_LOGIC_HUE}",
- "helpUrl": "%{BKY_CONTROLS_IF_HELPURL}",
- "mutator": "controls_if_mutator",
- "extensions": ["controls_if_tooltip"]
- }
- ]);
+ {
+ "type": "controls_if",
+ "message0": "%{BKY_CONTROLS_IF_MSG_IF} %1",
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "IF0",
+ "check": "Boolean"
+ }
+ ],
+ "message1": "%{BKY_CONTROLS_IF_MSG_THEN} %1",
+ "args1": [
+ {
+ "type": "input_statement",
+ "name": "DO0"
+ }
+ ],
+ "colour": "%{BKY_LOGIC_HUE}",
+ "helpUrl": "%{BKY_CONTROLS_IF_HELPURL}",
+ "mutator": "controls_if_mutator",
+ "extensions": ["controls_if_tooltip"]
+ },
+ {
+ "type": "logic_operation",
+ "message0": "%1 %2 %3",
+ "args0": [
+ {
+ "type": "input_value",
+ "name": "A",
+ "check": "Boolean"
+ },
+ {
+ "type": "field_dropdown",
+ "name": "OP",
+ "options": [
+ ["%{BKY_LOGIC_OPERATION_AND}", "AND"],
+ ["%{BKY_LOGIC_OPERATION_OR}", "OR"]
+ ]
+ },
+ {
+ "type": "input_value",
+ "name": "B",
+ "check": "Boolean"
+ }
+ ],
+ "inputsInline": true,
+ "output": "Boolean",
+ "colour": "%{BKY_LOGIC_HUE}",
+ "helpUrl": "%{BKY_LOGIC_OPERATION_HELPURL}",
+ "extensions": ["logic_op_tooltip"]
+ }
+]);
// Make control_if mutator icon bigger
Blockly.Icon.prototype.renderIcon = function(cursorX) {
@@ -82,9 +112,9 @@ window.addEventListener('load', function() {
init: function() {
this.setColour('#e98017');
this.appendDummyInput()
- .appendField('sleep')
+ .appendField(Blockly.Msg.SUMOROBOT_SLEEP)
.appendField(new Blockly.FieldTextInput('1000',
- Blockly.FieldNumber.numberValidator), 'SLEEP');
+ Blockly.FieldNumber.numberValidator), "SLEEP");
this.setPreviousStatement(true);
this.setNextStatement(true);
}
@@ -93,16 +123,16 @@ window.addEventListener('load', function() {
Blockly.Blocks['sumorobot_move'] = {
init: function() {
var OPERATORS = [
- ['move stop', 'STOP'],
- ['move left', 'LEFT'],
- ['move right', 'RIGHT'],
- ['move search', 'SEARCH'],
- ['move forward', 'FORWARD'],
- ['move backward', 'BACKWARD']
+ [Blockly.Msg.SUMOROBOT_STOP, 'STOP'],
+ [Blockly.Msg.SUMOROBOT_LEFT, 'LEFT'],
+ [Blockly.Msg.SUMOROBOT_RIGHT, 'RIGHT'],
+ [Blockly.Msg.SUMOROBOT_SEARCH, 'SEARCH'],
+ [Blockly.Msg.SUMOROBOT_FORWARD, 'FORWARD'],
+ [Blockly.Msg.SUMOROBOT_BACKWARD, 'BACKWARD']
];
this.setColour('#d6382d');
var dropdown = new Blockly.FieldDropdown(OPERATORS);
- this.appendDummyInput().appendField(dropdown, 'MOVE');
+ this.appendDummyInput().appendField(dropdown, 'Move');
this.setPreviousStatement(true);
this.setNextStatement(true);
}
@@ -111,7 +141,7 @@ window.addEventListener('load', function() {
Blockly.Blocks['sumorobot_opponent'] = {
init: function() {
this.setColour('#0099E6');
- this.appendDummyInput().appendField('opponent');
+ this.appendDummyInput().appendField(Blockly.Msg.SUMOROBOT_OPPONENT);
this.setOutput(true, 'Boolean');
}
};
@@ -119,9 +149,9 @@ window.addEventListener('load', function() {
Blockly.Blocks['sumorobot_line'] = {
init: function() {
var OPERATORS = [
- ['line left', 'LEFT'],
- ['line right', 'RIGHT'],
- ['line middle', 'MIDDLE']
+ [Blockly.Msg.SUMOROBOT_LINE_LEFT, 'LEFT'],
+ [Blockly.Msg.SUMOROBOT_LINE_MIDDLE, 'MIDDLE'],
+ [Blockly.Msg.SUMOROBOT_LINE_RIGHT, 'RIGHT']
];
this.setColour('#E6BF00');
var dropdown = new Blockly.FieldDropdown(OPERATORS);
@@ -131,12 +161,12 @@ window.addEventListener('load', function() {
};
Blockly.Python['sumorobot_sleep'] = function(block) {
- var code = 'sumorobot.sleep(' + parseFloat(block.getFieldValue('SLEEP')) + ');;' + block.id + '\n';
+ var code = 'sumorobot.sleep(' + parseFloat(block.getFieldValue("SLEEP")) + ');;' + block.id + '\n';
return code;
};
Blockly.Python['sumorobot_move'] = function(block) {
- var code = 'sumorobot.move(' + block.getFieldValue('MOVE') + ');;' + block.id + '\n';
+ var code = 'sumorobot.move(' + block.getFieldValue('Move') + ');;' + block.id + '\n';
return code;
};
@@ -150,17 +180,17 @@ window.addEventListener('load', function() {
return [code, Blockly.Python.ORDER_ATOMIC];
};
- // Inject Blockly
+ // Inject Blocklyresiz
var blocklyArea = document.getElementById('blocklyArea');
var blocklyDiv = document.getElementById('blocklyDiv');
workspace = Blockly.inject(blocklyDiv, {
media: 'assets/blockly/media/',
- scrollbars: false,
+ scrollbars: true,
trashcan: true,
sounds: true,
zoom: {
controls: true,
- startScale: 1.2
+ startScale: 1.0
},
toolbox: document.getElementById('toolbox')
});
diff --git a/assets/js/main.js b/assets/js/main.js
index 3e04ab1..8265ae0 100755
--- a/assets/js/main.js
+++ b/assets/js/main.js
@@ -1,7 +1,7 @@
// The local/remote server URL
//var ROBOT_SERVER = '192.168.2.1:80';
-var ROBOT_SERVER = '165.227.140.64:80';
-
+//var ROBOT_SERVER = '165.227.140.64:80';
+var ROBOT_SERVER = 'sumo.koodur.com:80';
// The sumorobot object
var sumorobot;
// Disable / enable coding mode
@@ -112,6 +112,16 @@ window.addEventListener('load', function() {
}
});
+
+ function stopProcessCode() {
+ // Stop highlighting blocks and lines
+ lines = [];
+ workspace.highlightBlock('');
+ if (range_id) {
+ readOnlyCodingEditor.session.removeMarker(range_id);
+ }
+ }
+
var range_id;
var lines = [];
var foundTrue = false;
@@ -119,7 +129,8 @@ window.addEventListener('load', function() {
function processCode(index) {
if(sumorobot.disconnected || !sumorobot.codeExecute) {
- $('.btn-stop').click();
+ //$('.btn-stop').click();
+ stopProcessCode();
return;
}
@@ -140,11 +151,11 @@ window.addEventListener('load', function() {
} else if (/opponent/.test(code)) {
foundTrue = (sumorobot.sensors['opponent'] < 40.0);
} else if (/LEFT/.test(code)) {
- foundTrue = (sumorobot.sensors['line_left'] > 2000);
+ foundTrue = (sumorobot.sensors['line_left'] < 2500);
} else if (/RIGHT/.test(code)) {
- foundTrue = (sumorobot.sensors['line_right'] > 2000);
+ foundTrue = (sumorobot.sensors['line_right'] < 2500);
} else if (/MIDDLE/.test(code)) {
- foundTrue = (sumorobot.sensors['line_middle'] > 2000);
+ foundTrue = (sumorobot.sensors['line_middle'] < 2500);
} else {
foundTrue = true;
}
@@ -170,6 +181,18 @@ window.addEventListener('load', function() {
setTimeout(function() { processCode(index) }, timeout);
}
+
+ $('.btn-upload').click(function() {
+ if(codingEnabled) {
+ parsedCode = codingEditor.getValue();
+ } else {
+ parsedCode = Blockly.Python.workspaceToCode(workspace).replace(/;;.{20}/g, '');
+ }
+
+ sumorobot.send('code', parsedCode.replace(/"/g, '\\"').replace(/\n/g, ';;'));
+ lines = Blockly.Python.workspaceToCode(workspace).split('\n').filter(Boolean);
+ });
+
// Start button listener
$('.btn-start').click(function() {
// When we are in Python coding mode
@@ -182,22 +205,17 @@ window.addEventListener('load', function() {
parsedCode = Blockly.Python.workspaceToCode(workspace).replace(/;;.{20}/g, '');
}
// Escape the qoutes, replace new lines and send the code
- sumorobot.send('code', parsedCode.replace(/"/g, '\\"').replace(/\n/g, ';;'));
+ sumorobot.send('start', parsedCode.replace(/"/g, '\\"').replace(/\n/g, ';;'));
// Split into lines of code and filter empty lines
lines = Blockly.Python.workspaceToCode(workspace).split('\n').filter(Boolean);
// Process the code starting from the first line
- processCode(0);
+ //processCode(0);
});
// Stop button listener
$('.btn-stop').click(function() {
sumorobot.send('stop');
- // Stop highlighting blocks and lines
- lines = [];
- workspace.highlightBlock('');
- if (range_id) {
- readOnlyCodingEditor.session.removeMarker(range_id);
- }
+ stopProcessCode();
});
// Enter (return) keypress listener on robot ID field
@@ -227,7 +245,15 @@ window.addEventListener('load', function() {
}
// Connect to the selected robots WebSocket
sumorobot = new Sumorobot(`ws://${ROBOT_SERVER}/p2p/browser/sumo-${robotId}/`, robotId);
+
+ $(sumorobot).on('start',function(){
+ //console.log("START");
+ lines = Blockly.Python.workspaceToCode(workspace).split('\n').filter(Boolean);
+ processCode(0);
+ });
+
// Hide the configuration panel
$('#panel').hide();
});
+
});
diff --git a/assets/js/sumorobot.js b/assets/js/sumorobot.js
index 0b3ccdb..de2ea55 100755
--- a/assets/js/sumorobot.js
+++ b/assets/js/sumorobot.js
@@ -16,6 +16,8 @@ var Sumorobot = function(wsUri, robotId) {
this.moving = false;
this.codeExecute = false;
+
+ self.previousCodeExecuteValue = false;
// Sensor data
this.sensors = {
'opponent': 99,
@@ -66,21 +68,30 @@ Sumorobot.prototype.connect = function() {
// When scope is received
var data = evt.data.replace(/'/g, '"').toLowerCase();
self.disconnected = false;
+ var message = JSON.parse(data);
+
+ if(message.cmd == "sensors") {
+ self.sensors = message.data;
+ self.codeExecute = self.sensors.state;
+ }else if(message.cmd == "code_upload") {
+ if(message.status) {
+ alert("Ülesslaadimine õnnestus");
+ } else {
+ alert("Ülesslaadimine ebaõnnestus");
+ }
+ }
// Get SumoRobot battery voltage
- self.sensors = JSON.parse(data);
- self.codeExecute = self.sensors.state;
- // When sensor data received
- if (self.sensors['battery_voltage']) {
- if (self.sensors['battery_voltage'] > 4.0) {
- $("#battery img").attr("src", "assets/img/battery_full.png");
- } else if (self.sensors['battery_voltage'] > 3.1) {
- $("#battery img").attr("src", "assets/img/battery_half.png");
- } else {
- $("#battery img").attr("src", "assets/img/battery_empty.png");
- }
+ if(self.codeExecute && !self.previousCodeExecuteValue){
+ $(self).trigger("start");
}
+
+ self.previousCodeExecuteValue = self.codeExecute;
+
// Count data received packets
+
+ $("#battery img").attr("src", "assets/img/checkmark-64.png");
+
self.watchdogCounter += 1;
};
// When there is an WebSocket error
@@ -93,7 +104,7 @@ Sumorobot.prototype.connect = function() {
Sumorobot.prototype.send = function(cmd, val) {
if (cmd !== 'ping' && cmd !== 'stop') {
this.moving = true;
- this.codeExecute = true;
+ //this.codeExecute = true;
} else {
this.moving = false;
}
diff --git a/index.html b/index.html
index 2be45dd..a5c556f 100755
--- a/index.html
+++ b/index.html
@@ -21,7 +21,7 @@
-
+
@@ -66,6 +66,7 @@