diff --git a/content/adventures/ca.yaml b/content/adventures/ca.yaml index 547523efa6f..a8fcc4960ef 100644 --- a/content/adventures/ca.yaml +++ b/content/adventures/ca.yaml @@ -95,6 +95,7 @@ adventures: Torna als nivells anteriors i copia el teu codi de la història. Fes funcionar el codi en aquest nivell afegint cometes als llocs adequats. Recorda: Les variables de la teva pròpia història han d'estar fora de les cometes. Igual que a la segona línia de l'exemple de codi. En aquesta línia, la variable nom es col·loca fora de les cometes. example_code: | + ``` nom {is} {ask} _ Com et dius? _ {print} _ El protagonista es diu _ nom _ @@ -104,6 +105,7 @@ adventures: animals {is} 🦔, 🐿, 🦉, 🦇 {print} _ Sent el so de _ animals {at} {random} {print} name _ li fa por que estigui en un bosc encantat _ + ``` 5: story_text: | En aquest nivell, pots programar diferents finals, cosa que farà que la teva història sigui encara més divertida. @@ -177,9 +179,9 @@ adventures: {print} 'Robin sees an interesting looking book' book = {ask} 'Does Robin buy the book?' {if} book {is} yes - {print} 'Robin buys the book and goes home' + _{print} 'Robin buys the book and goes home' {else} - {print} 'Robin leaves the shop and goes home' + _{print} 'Robin leaves the shop and goes home' {else} {print} 'Robin goes home' ``` @@ -188,23 +190,16 @@ adventures: In this level you can use the {for} command in your story. In this way you could easily program the children's book 'brown bear, brown bear, what do you see'. example_code: | ``` - animals = red bird, black sheep, green frog, yellow duck, little child - {print} 'brown bear' - {print} 'brown bear' - {print} 'What do you see?' - {for} animal {in} animals - {print} 'I see a ' animal ' looking at me' - {print} animal - {print} animal - {print} 'What do you see?' - {print} 'I see all the animals looking at me!' + animals = _ , _ , _ + {print} 'Os bru, Os bru' + {print} 'Què veus?' ``` 12: story_text: In this level you can use the quotation marks to save multiple words in a variable. example_code: | ``` nom = "La Reina d'Englaterra" - {print} nom ' menjava un tall de pastís, quan de sopte...' + {print} nom ' menjava un tall de pastís, quan de sopte…' ``` 13: story_text: | @@ -264,9 +259,9 @@ adventures: {print}('Benvingut a aquesta història!') ``` add_remove_command: - name: '{add} {to} & {remove} {from}' + name: '{add} {to_list} & {remove} {from}' default_save_name: comanda_afegir_borrar - description: Introduint afegeix i esborra de + description: Introduint {add} {to_list} i {remove} {from} levels: 3: story_text: | @@ -305,7 +300,7 @@ adventures: and_or_command: name: '{and} & {or}' default_save_name: i o - description: Introduint i o + description: Introduint {and} & {or} levels: 13: story_text: |- @@ -322,7 +317,7 @@ adventures: ask_command: name: '{ask}' default_save_name: comanda_pregunta - description: Introducció a la comanda preguntar + description: Introducció a la comanda {ask} levels: 1: story_text: | @@ -334,8 +329,9 @@ adventures: {ask} Com et dius? ``` story_text_2: | - ## The echo command - If you want the computer to repeat the answer, you can use the `{echo}` command. The answer will then be echoed back at the end of the sentence, so in this example after hello. + ## La comanda `{echo}` + Si vols que l'ordinador et repeteixi la resposta, pots utilitzar l'ordre `{echo}`. La resposta es mostrarà al final de la frase, com en aquest exemple després d'hola. + . example_code_2: | ``` {print} Hola! @@ -375,8 +371,8 @@ adventures: Copia el teu codi de la pestanya anterior i fes que les variables siguin interactives mitjançant la comanda `{ask}`. example_code_2: | ``` - animals_preferits {is} {ask} Quin són els teus animals preferits? - {print} M'agrada els/les animals_preferits + animal_preferit {is} {ask} Quin és el teu animal preferit? + {print} M'agrada el animal_preferit ``` 18: story_text: The final change we will need to make to get Python code is changing `{ask}` into `{input}`. @@ -389,7 +385,7 @@ adventures: blackjack: name: Blackjack default_save_name: Blackjack - description: Try to get as close to 21 as you can + description: Intenta apropar-te tant com puguis a 21 levels: 17: story_text: | @@ -577,19 +573,19 @@ adventures: _ ``` calculator: - name: Calculator - default_save_name: Calculator - description: Create a calculator + name: Calculadora + default_save_name: Calculadora + description: Crea una calculadora levels: 6: story_text: | Now that you can do maths, you can make a calculator yourself! example_code: | ``` - number_1 {is} {ask} 'Fill in the first number:' - number_2 {is} {ask} 'Fill in the second number:' - correct_answer = number_1 * number_2 - {print} number_1 ' times ' number_2 ' is ' correct_answer + nombre_1 = {ask} 'Escriu el primer nombre:' + nombre_2 = {ask} 'Escriu el segon nombre:' + resposta_correcta = nombre_1 * nombre_2 + {print} nombre_1 ' per ' nombre_2 ' és ' resposta_correcta ``` story_text_2: | ### Exercise @@ -597,21 +593,23 @@ adventures: Fill in the blanks to make it complete! example_code_2: | ``` - correct_answer = 11 * 27 - answer = {ask} 'How much is 11 times 27?' - {if} answer {is} _ {print} 'good job!' - {else} {print} 'Wrong! It was ' _ + resposta_correcta = 11 * 27 + resposta = {ask} 'Quant és 11 per 27?' + {if} resposta {is} _ {print} 'Bona feina!' + {else} {print} 'Incorrecte! Era ' _ ``` story_text_3: | - You can also let the computer do random calculations on its own using {random}. - example_code_3: | - numbers = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 - number_1 = _ - number_2 = _ - correct_answer = number_1 * number_2 - given_answer = 'What is ' number_1 ' times ' number_2 '?' + **Extra** També pots deixar que l'ordinador faci productes aleatoris per ell mateix utilitzant `{random}`. + example_code_3: |- + ``` + nombres = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 + nombre_1 = _ + nombre_2 = _ + resposta_correcta = nombre_1 * nombre_2 + resposta_dada = {ask} 'Quin és ' nombre_1 ' per ' nombre_2 '?' {if} _ {else} _ + ``` 9: story_text: | In a previous level you've created a calculator, in this level you can expand that code so it asks multiple questions. @@ -677,18 +675,26 @@ adventures: example_code: | ``` number = 10 - {for} i {in} {range} 1 to 10 + {for} i {in} {range} 1 {to} 10 {print} i * number ``` 12: story_text: | - Now you can make a calculator that works for decimal numbers. Fill in the blanks to get it to work properly! + En aquest nivell, pots fer una calculadora que funcioni amb nombres decimals. + + ### Exercici 1 + Omple els buits per completar la calculadora. Recorda utilitzar un punt i no una coma per als nombres decimals. + + ### Exercici 2 + Crea un nou programa de pràctica matemàtica, però ara utilitza nombres decimals. + Crea una llista de nombres, tria'n dos per multiplicar i deixa que el jugador respongui. + I, per descomptat, has de validar la resposta! **Extra** Augmenta la dificultat afegint vides: un jugador perd una vida per cada resposta incorrecta i el joc acaba després de tres respostes incorrectes. example_code: | ``` - number1 = {ask} 'What is the first number?' - number2 = {ask} 'What is the second number?' - answer = _ - {print} number1 ' plus ' number2 ' is ' answer + nombre1 = {ask} 'Quin és el primer nombre?' + nombre2 = {ask} 'Quin és el segon nombre?' + resposta = _ + {print} nombre1 ' més ' nombre2 ' és ' _ ``` 13: story_text: | @@ -701,8 +707,8 @@ adventures: Empty the programming field and create your own solution. example_code: | ``` - answer1 = {ask} 'What is 10 times 7?' - answer2 = {ask} 'What is 6 times 7?' + resposta1 = {ask} 'Quin és 10 per 7?' + resposta2 = {ask} 'Quin és 6 per 7?' {if} _ _ _ _ _ _ _ {print} _ ``` @@ -789,7 +795,7 @@ adventures: clear_command: name: '{clear}' default_save_name: clear_command - description: clear command + description: comanda {clear} levels: 4: story_text: | @@ -809,85 +815,85 @@ adventures: {print} 'SURPRISE!' ``` debugging: - name: debugging - default_save_name: debugging - description: debugging adventure + name: depuració + default_save_name: depuració + description: l'aventura de depurar levels: 1: story_text: |- - Welcome to a debugging adventure. Debugging a code means getting rid of mistakes in the code. - That means that in these debugging adventures, we will show you code that does not work yet. - You will have to figure out what's wrong and correct the mistakes. + Benvingut a una aventura de depuració. Depurar un codi significa eliminar errors en el codi. + Això vol dir que en aquestes aventures de depuració, t'ensenyarem codi que encara no funciona. + Hauràs de descobrir què està malament i corregir els errors. - ### Exercise - Debug this code. Good luck! + ### Exercici + Depura aquest codi. Bona sort! example_code: | - **Warning! This code needs to be debugged!** + **Advertència! Aquest codi necessita ser depurat!** ``` - {print} I love programming - Do you love programming too? + {print} M'encanta programar + T'agrada programar també? {echo} - {print} What are your hobbies? - {echo} Your hobbies are + {print} Quins són les teves aficions? + {echo} Les teves aficions són ``` 2: story_text: |- - Welcome to a debugging adventure. Debugging a code means getting rid of mistakes in the code. - That means that in these debugging adventures, we will give you a code that does not work yet. - You will have to figure out what's wrong and correct the mistakes. + Benvingut a una aventura de depuració. Depurar un codi significa eliminar errors en el codi. + Això vol dir que en aquestes aventures de depuració, et donarem un codi que encara no funciona. + Hauràs de descobrir què està malament i corregir els errors. - ### Exercise - Debug this code. Good luck! + ### Exercici + Depura aquest codi. Bona sort! example_code: | - **Warning! This code needs to be debugged!** + **Advertència! Aquest codi necessita ser depurat!** ``` - destination {ask} Where are you going on holidays? - {print} The flight to dstination leaves at 3 pm. - {ask} Did you check in your luggage yet? + destinacio {ask} On vas de vacances? + {print} El vol surt a les 3 de la tarda. + {ask} Ja has fet el check-in del teu equipatge? {echo} - {print} Let me print your boarding pass for you. + {print} Deixa'm imprimir-te la targeta d'embarcament. {sleep} - Here you go! Have a nice trip! + Aquí tens! Que tinguis un bon viatge! ``` 3: story_text: |- - Welcome to a debugging adventure. Debugging a code means getting rid of mistakes in the code. - That means that in these debugging adventures, we will give you a code that does not work yet. - You will have to figure out what's wrong and correct the mistakes. + Benvingut a una aventura de depuració. Depurar un codi significa eliminar errors en el codi. + Això vol dir que en aquestes aventures de depuració, et donarem un codi que encara no funciona. + Hauràs de descobrir què està malament i corregir els errors. - ### Exercise - Debug this code. Good luck! + ### Exercici + Depura aquest codi. Bona sort! example_code: | - **Warning! This code needs to be debugged!** + **Advertència! Aquest codi necessita ser depurat!** ``` - movie_choices {is} dracula, fast and furious, home alone, barbie - chosen_movie {is} movies {at} {random} - {print} Tonight we will watch chosen _movies - like {ask} Do you like that movie? - {print} Tomorrow we will watch something else. - {add} chosen_movie {to} movie_choices - {print} Tomorrow we will watch tomorrows_movie - tomorrows_movie {is} movie_choices {at} {random} - I'll go get the popcorn! {print} + opcions_pelicula {is} dracula, fast and furious, solo en casa, barbie + pelicula_escollida {is} movies {at} {random} + {print} Aquesta nit veurem _pelicula_escollida + com {ask} T'agrada aquesta pel·lícula? + {print} Demà veurem una altra cosa. + {add} pelicula_escollida {to_list} opcions_pelicula + {print} Demà veurem pelicula_dema + pelicula_dema {is} opcions_pelicula {at} {random} + Aniré a buscar les crispetes! {print} ``` 4: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Exercici + Depura aquest codi. Bona sort! example_code: | - **Warning! This code needs to be debugged!** + **Advertència! Aquest codi necessita ser depurat!** ``` - {print} 'Welcome to the online library! - {ask} What genre of books do you like? - {print} You like genre - author {is} {ask} 'Who's your favorite author?' - {print} 'author is your favorite author' - {print} Hmmm... i think you should try... books {at} {random} + {print} 'Benvingut a la biblioteca en línia!' + {ask} Quin gènere de llibres t'agrada? + {print} T'agrada el gènere + autor {is} {ask} 'Qui és el teu autor preferit?' + {print} 'autor és el teu autor preferit' + {print} Hmmm... crec que hauries de provar... llibres {at} {random} ``` 5: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Exercici + Depura aquest codi. Bona sort! example_code: | **Warning! This code needs to be debugged!** ``` @@ -907,8 +913,8 @@ adventures: ``` 6: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Exercici + Depura aquest codi. Bona sort! example_code: | **Warning! This code needs to be debugged!** ``` @@ -929,21 +935,21 @@ adventures: ``` 7: story_text: |- - ### Exercise - Surprise! This program looks more like an output than a code. And yet, we don't want you to just add `{print}` commands in front of each line. - Fix this program to turn it into the nursery rhyme 'Brother John (Frère Jaques)' by using the {repeat} command of course! + ### Exercici + Sorpresa! Aquest programa sembla més una sortida que un codi. I, tanmateix, no volem que simplement afegeixis comandes `{print}` davant de cada línia. + Arregla aquest programa per convertir-lo en la cançó infantil 'Frère Jacques' utilitzant la comanda {repeat}, és clar! example_code: | - **Warning! This code needs to be debugged!** + **Advertència! Aquest codi necessita ser depurat!** ``` - Are you sleeping? - Brother John! - Morning bells are ringing! - Ding, dang, dong! + Frère Jacques, frère Jacques, + Dormez-vous? Dormez-vous? + Sonnez les matines! Sonnez les matines! + Ding, dang, dong. Ding, dang, dong. ``` 8: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Exercici + Depura aquest codi. Bona sort! example_code: | **Warning! This code needs to be debugged!** ``` @@ -967,287 +973,264 @@ adventures: ``` 9: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Exercici + Depura aquest codi. Bona sort! example_code: | - **Warning! This code needs to be debugged!** + **Advertència! Aquest codi necessita ser depurat!** ``` - {print} 'Welcome to our sandwich shop' - amount 'How many sandwiches would you like to buy?' - {repeat} amount {times} - {ask} {is} {ask} 'What kind or bread would you like your sandwich to be?' - types_of_bread {is} white, wheat, rye, garlic, gluten free - {if} chosen_bread in types_of_bread - {print} 'Lovely!' + {print} "Benvingut a la nostra botiga d'entrepans" + quantitat "Quants entrepans t'agradaria comprar?" + {repeat} quantitat {times} + {ask} {is} {ask} "Quin tipus de pa t'agradaria per al teu entrepà?" + tipus_de_pa {is} blanc, blat, sègol, all, sense gluten + {if} pa_elegit in tipus_de_pa + {print} "Excel·lent!" {else} - 'I'm sorry we don't sell that' - topping {is} {ask} 'What kind of topping would you like?' - sauce {is} {ask} 'What kind of sauce would you like?' - {print} One chosen_bread with topping and sauce. - price = amount * 6 - {print} 'That will be 'price dollar' please' + "Ho sento, no venem això" + guarnicio {is} {ask} "Quin tipus de guarnició t'agradaria?" + salsa {is} {ask} "Quin tipus de salsa t'agradaria?" + {print} Un pa_elegit amb guarnicio i salsa. + preu = quantitat * 6 + {print} "Seran " preu " euros, si us plau" ``` - - price = amount * 6 - {print} 'That will be 'price dollar' please' 10: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Exercici + Depura aquest codi. Bona sort! example_code: | - **Warning! This code needs to be debugged!** + **Advertència! Aquest codi necessita ser depurat!** ``` - names = Muad Hasan Samira Noura - activities = fly a kite, go swimming, go hiking, catch tan in the sun - {for} name {is} names - {print} At the beach name loves to activity at random + noms = Muad Hasan Samira Noura + activitats = volar un estel, anar a nedar, fer senderisme, posar-se moreno + {for} nom {is} noms + {print} A la platja, nom li encanta activity {at} {random} ``` 11: story_text: |- - ### Exercise - Debug this calender program. The output of this program is supposed to look like a list of dates. - For example: - - ``` - Hedy calender - Here are all the days of November - November 1 - November 2 - November 3 - ``` - And so on. + ### Exercici + Depura aquest programa de calendari. La sortida d'aquest programa hauria de semblar una llista de dates. + Per exemple: + + ``` + Calendari de Hedy + Tots els dies de novembre: + 1 de novembre + 2 de novembre + 3 de novembre + ``` + I així successivament. + + Tingues en compte que has de provar el teu codi amb molta cura per al mes de febrer, ja que la quantitat de dies en aquest mes canvia als anys de traspàs. + example_code: | + **Advertència! Aquest codi necessita ser depurat!** + ``` + {print} "Calendari de Hedy" + mesos_amb_31_dies = Gener, Març, Maig, Juliol, Setembre, Octubre, Desembre + mesos_amb_30_dies = Abril, Juny, Agost, Novembre + mes = {ask} "Quin mes t'agradaria veure?" + {if} mes {in} mesos_amb_31_dies + dies = 31 + {if} mes {in} mesos_amb_30_dies + dies = 30 + {if} mes = Febrer + anys_de_traspàs = 2020, 2024, 2028, 2036, 2040, 2044, 2028 + any = {ask} "Quin any és?" + {if} any {in} anys_de_traspàs + dies = 29 + {else} + dies = 28 - Mind that you have to test your code extra carefully for the month February, because the amount of days in this month changes in leap years. - example_code: | - **Warning! This code needs to be debugged!** - ``` - print 'Hedy calender' - months_with_31 days = January, March, May, July, September, October, December - months_with_30_days = April, June, August, November - month = ask 'Which month would you like to see?' - if month in months_with_31_days - days = 31 - if month in months_with30_days - days = 30 - if month = February - leap_years = 2020, 2024, 2028, 2036, 2040, 2044, 2028 - year = ask 'What year is it?' - if year in leap_years - days = 29 - else - days = 28 - - print 'Here are all the days of ' moth - for i in range 1 to days - print month i + {print} "Aquí tens tots els dies de " mse + {for} i {in} {range} 1 {to} dies + {print} mes i ``` 12: story_text: |- - ### Exercise - Debug this code. Good luck! - example_code: | - **Warning! This code needs to be debugged!** - ``` - define greet - greetings = 'Hello', 'Hi there', 'Goodevening' - print greetings at random - - define take_order - food = ask 'What would you like to eat?' - print 'One food' - drink = 'What would you like to drink?' - print 'One ' drink - more = ask 'Would you like anything else?' - if more is 'no' - print 'Alright' - else - print 'And ' more - print 'Thank you' - - print 'Welcome to our restaurant' - people = ask 'How many people are in your party tonight?' - for i in range 0 to people - call greet_costumer + ### Exercici + Depura aquest codi. Bona sort! + example_code: | + **Advertència! Aquest codi necessita ser depurat!** + ``` + {define} saludar + greetings = "Hola", "Hola a tots", "Bona tarda" + {print} greetings {at} {random} + + {define} prendre_comanda + menjar = {ask} "Què t'agradaria menjar?" + {print} "Un menjar" + beguda = "Què t'agradaria beure?" + {print} "Una " beguda + mes = {ask} "Vols alguna cosa més?" + {if} mes {is} "no" + {print} "Molt bé" + {else} + {print} "I " mes + {print} "Gràcies" + + {print} "Benvingut al nostre restaurant" + persones = {ask} "Quantes persones sou aquesta nit?" + {for} i {in} {range} 0 {to} persones + {call} saludar_client ``` 13: story_text: |- - ### Exercise - Debug this code. Good luck! - example_code: | - **Warning! This code needs to be debugged!** - ``` - defin movie_recommendation with name - action_movies == 'Die Hard', 'Fast and Furious', 'Inglorious Bastards' - romance_movies = 'Love Actually', 'The Notebook', 'Titanic' - comedy_movies = 'Mr Bean' 'Barbie''Deadpool' - kids_movies = 'Minions', 'Paddington', 'Encanto' - if name is 'Camila' or name is 'Manuel' - recommended_movie = kids_movie at random - if name is 'Pedro' or 'Gabriella' - mood = ask 'What you in the mood for?' - if mood is 'action' - recommended_movie = comedy_movies at random - if mood is 'romance' - recommended_movie = romance_movies - if mood is 'comedy' - recommended_movie = comedy_movies at random - - print 'I would recommend ' recommended_movie ' for ' name - - name = ask 'Who is watching?' - recommendation = ask 'Would you like a recommendation?' - if recommendaion is 'yes' - print movie_recommendation with name - else - print 'No problem!' + ### Exercici + Depura aquest codi. Bona sort! + example_code: | + **Advertència! Aquest codi necessita ser depurat!** + ``` + {define} recomanacio_pelicula {with} nom + pelicules_accio = "Die Hard", "Fast and Furious", "Malditos Bastardos" + pelicules_romantiques = "Love Actually", "Barcelona nit d'estiu", "Titanic" + pelicules_comedia = "Mr Bean", "Barbie", "La casa en flames" + pelicules_nens = "Tintin", "Les tres bessones", "Inside out" + {if} nom {is} "Camila" {or} nom {is} "Manel" + pelicula_recomanada = pelicules_nens {at} {random} + {if} nom {is} "Pere" {or} "Gabriella" + estat_d_ànim = {ask} "Quin estat d'ànim tens?" + {if} estat_d_ànim {is} "acció" + pelicula_recomanada = pelicules_accio {at} {random} + {if} estat_d_ànim {is} "romantica" + pelicula_recomanada = pelicules_romantiques + {if} estat_d_ànim {is} "comedia" + pelicula_recomanada = pelicules_comedia {at} {random} + + {print} "Et recomanaria " pelicula_recomanada " per " nom + + nom = {ask} "Qui està mirant?" + recomanacio = {ask} "Vols una recomanació?" + {if} recomanacio {is} "sí" + {print} recomanacio_pelicula {with} nom + {else} + {print} "Cap problema!" ``` 14: story_text: |- - ### Exercise - Debug this code. Good luck! - example_code: | - **Warning! This code needs to be debugged!** + ### Exercici + Depura aquest codi. Bona sort! + example_code: | + **Advertència! Aquest codi necessita ser depurat!** + ``` + {define} calcular_pulsacions + {print} "Pressiona els dits suaument contra el costat del teu coll" + {print} "(just sota de la mandíbula)" + {print} "Conta el nombre de pulsacions que sents durant 15 segons" + pulsacions == {ask} "Quantes pulsacions sents en 15 segons?" + pols = pulsacions * 4 + {print} "El teu pols és " pols + {if} pols >= 60 {or} pols <= 100 + {print} "El teu pols sembla estar bé" + {else} + {if} pols > 60 + {print} "El teu pols sembla massa baix" + {if} pols < 100 + {print} "El teu pols sembla massa alt" + {print} "Potser hauries de contactar amb un professional mèdic" + + mesurar_pulsacio = {ask} "Vols mesurar el teu pols?" + {if} mesurar_pulsacio = "sí" + {call} calcular_pulsacions + {else} + "Cap problema" ``` - define calculate_heartbeat - print 'Press your fingertips gently against the side of your neck' - print '(just under your jawline)' - print 'Count the number of beats you feel for 15 seconds' - beats == ask 'How many beats do you feel in 15 seconds?' - heartbeat = beats*4 - print 'Your heartbeat is ' heartbeat - if heartbeat >= 60 or heartbeat <= 100 - print 'Your heartbeat seems fine' - else - if heartbeat > 60 - print 'Your heartbeat seems to be too low' - if heartbeat < 100 - print 'Your heartbeat seems to be too high' - print 'You might want to contact a medical professional' - - measure_heartbeat = ask 'Would you like to measure your heartbeat?' - if measure_heartbeat = 'yes' - call measure_heartbeat - else - 'no problem' - ``` - - print '(just under your jawline)' - print 'Count the number of beats you feel for 15 seconds' - beats == ask 'How many beats do you feel in 15 seconds?' - heartbeat = beats*4 - print 'Your heartbeat is ' heartbeat - if heartbeat >= 60 or heartbeat <= 100 - print 'Your heartbeat seems fine' - else - if heartbeat > 60 - print 'Your heartbeat seems to be too low' - if heartbeat < 100 - print 'Your heartbeat seems to be too high' - print 'You might want to contact a medical professional' - - measure_heartbeat = ask 'Would you like to measure your heartbeat?' - if measure_heartbeat = 'yes' - call measure_heartbeat - else - 'no problem' 15: story_text: |- - ### Exercise - Debug this random children's story. Good luck! - example_code: | - **Warning! This code needs to be debugged!** - ``` - names = 'Tanya', 'Romy', 'Kayla', 'Aldrin', 'Ali' - verbs='walking', 'skipping', 'cycling', 'driving', 'running' - locations = 'on a mountaintop', 'in the supermarket', 'to the swimming pool' - hiding_spots = 'behind a tree', under a table', in a box' - sounds = 'a trumpet', 'a car crash', 'thunder' - causes_of_noise = 'a television', 'a kid with firecrackers', 'a magic elephant', 'a dream' - - chosen_ name = names at random - chosen_verb = verbs at random - chosen_location = 'locations at random' - chosen_sounds = noises at random - chosen_spot = hiding_spots random - chosen_causes = causes_of_noise at random - - print chosen_name ' was ' chosen_verb ' ' chosen_location - print 'when they suddenly heard a sound like ' sounds at random - print chosen_name ' looked around, but they couldn't discover where the noise came from' - print chosen_name ' hid ' chosen_spot' - print 'They tried to look around, but couldn't see anything from there' - hidden = 'yes' - while hidden = 'yes' - print chosen_name 'still didn't see anything' - answer = ask 'does ' chosen_name ' move from their hiding spot?' - if answer = 'yes' - hidden == 'no' - print 'chosen_name moved from' chosen_spot - print 'And then they saw it was just' chosen_cause - print chosen_name 'laughed and went on with their day' - print The End + ### Exercici + Depura aquesta història infantil aleatòria. Bona sort! + example_code: | + **Advertència! Aquest codi necessita ser depurat!** + ``` + noms = "Tanya", "Romy", "Kayla", "Aldrin", "Ali" + verbs = "caminant", "saltant", "ciclant", "conduint", "corrent" + llocs = "en un cim", "al supermercat", "cap a la piscina" + llocs_on = "darrera d'un arbre", "sota d'una taula", "dins d'una caixa" + sons = "una trompeta", "un xoc de cotxes", "un tro" + causes_de_sorolls= "un televisor", "un nen amb petards", "un elefant màgic", "un somni" + + elegit_nom = noms {at} {random} + elegit_verb = verbs {at} {random} + elegit_lloc = llocs {at} {random} + elegit_so = sons {at} {random} + elegit_lloc = llocs_on {random} + elegit_causa = causes_de_sorolls {at} {random} + + {print} elegit_nom " estava " elegit_verb " " elegit_lloc + {print} "quan de sobte van sentir un so com " sounds {at} {random} + {print} elegit_nom " va mirar al seu voltant, però no va poder descobrir d'on venia el soroll" + {print} elegit_nom " es va amagar " elegit_lloc + {print} "Van intentar mirar al seu voltant, però no van poder veure res des d'allà" + amagat = "sí" + {while} amagat = "sí" + {print} elegit_nom " encara no veia res" + resposta = {ask} "Es mou " elegit_nom " del seu lloc d'amagat?" + {if} resposta = "sí" + amagat == "no" + {print} elegit_nom " es va moure de " elegit_lloc + {print} "I llavors van veure que només era " elegit_causa + {print} elegit_nom " va riure i va continuar amb el seu dia" + {print} "Fi" ``` 16: story_text: |- - ### Exercise - Debug this code. Good luck! - Tip: Make sure that you only see your score once in the end. - example_code: | - **Warning! This code needs to be debugged!** - ``` - country = ['The Netherlands', 'Poland', 'Turkey', 'Zimbabwe', 'Thailand', 'Brasil', 'Peru', 'Australia', 'India', 'Romania' ] - capitals = 'Amsterdam', 'Warshaw' 'Istanbul', 'Harare', 'Bangkok', 'Brasilia', 'Lima', 'Canberra', 'New Delhi', 'Bucharest' - score = 0 - for i in range 0 to 10 - answer = ask 'What's the capital of ' countries[i] - correct = capital[i] - if answer = correct - print 'Correct!' - score = score + 1 - else - print 'Wrong,' capitals[i] 'in the capital of' countries[i] - print 'You scored ' score ' out of 10' + ### Exercici + Depura aquest codi. Bona sort! + Consell: Assegura't que només vegis la teva puntuació una vegada al final. + example_code: | + **Advertència! Aquest codi necessita ser depurat!** + ``` + país = ['Països Baixos', 'Catalunya', 'Turquia', 'Zimbabwe', 'Tailàndia', 'País Basc', 'Perú', 'Austràlia', 'Índia', 'Romania'] + capitals = 'Amsterdam', 'Barcelona', 'Istanbul', 'Harare', 'Bangkok', 'Bilbao', 'Lima', 'Canberra', 'Nova Delhi', 'Bucarest' + puntuació = 0 + {for} i {in} {range} 0 {to} 10 + resposta = {ask} 'Quina és la capital de ' país[i] + correcte = capitals[i] + {if} resposta = correcte + {print} 'Correcte!' + puntuació = puntuació + 1 + {else} + {print} 'Incorrecte, ' capitals[i] ' és la capital de ' país[i] + {print} 'Has obtingut ' puntuació ' de 10' ``` 17: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Exercici + Depura aquest codi. Bona sort! example_code: | - **Warning! This code needs to be debugged!** + **Advertència! Aquest codi necessita ser depurat!** ``` - define food_order - toppings = ask 'pepperoni, tuna, veggie or cheese?' - size = ask 'big, medium or small?' - number_of_pizza = ask 'How many these pizzas would you like?' + {define} comanda_menjar + ingredients = {ask} "de pepperoni, de tonyina, vegetariana o de formatge?" + mida = {ask} "gran, mitjana o petita?" + nombre_de_pizzas = {ask} "Quantes d'aquestes pizzes voldries?" - print 'YOU ORDERED' - print number_of_pizzas ' size ' topping ' pizza' + {print} "HAS ORDENAT" + {print} nombre_de_pizzas " mida pizza " ingredients - define drinks_order - drink = ask 'water, coke, icetea, lemonade or coffee?' - number_of_drinks = ask 'How many of these drinks would you like?' + {define} comanda_beure + beguda = {ask} "aigua, cola, te gelat, limonada o cafè?" + nombre_de_bebides = {ask} "Quantes d'aquestes begudes voldries?" - print 'YOU ORDERED' - print number_of_drinks ' ' drink + {print} "HAS ORDENAT" + {print} nombre_de_bebides " " beguda - 'Welcome to Hedy pizza' - more_food = ask 'Would you like to order a pizza?' - while more_food = 'yes' - return food_order - more_food = ask 'Would you like to order a pizza?' - more_drinks = ask 'Would you like to order some drinks?' - while more_drinks == 'yes' - call drink_order - more_drinks == ask 'Would you like to order more drinks?' + "Benvingut a Hedy pizza" + més_comanda = {ask} "Voldries demanar una pizza?" + {while} més_comanda = "sí" + {return} comanda_menjar + més_comanda = {ask} "Voldries demanar una pizza?" + més_bebides = {ask} "Voldries demanar alguna beguda?" + {while} més_bebides = "sí" + {call} comanda_beure + més_bebides = {ask} "Voldries demanar més begudes?" - print 'Thanks for ordering!' + {print} "Gràcies per la teva comanda!" ``` 18: story_text: |- - ### Exercise - Debug this Old MacDonald program from level 16. Good luck! + ### Exercici + Depura aquest programa d'Old MacDonald del nivell 16. Bona sort! example_code: | **Warning! This code needs to be debugged!** ``` @@ -1273,11 +1256,12 @@ adventures: levels: 1: story_text: | - Benvingut a Hedy! + Benvingut a Hedy! Aquí pots aprendre a programar pas a pas. - Per provar el codi tan sols has de fer clic al botó 'Executa' sota el bloc de programació. + Prova el codi tu mateix! El botó groc copia el codi d'exemple al teu camp de programació. + Després, prem el botó verd 'Executa codi' sota del camp de programació per executar el codi. - Estàs llest?, ves a la següent pestanya per aprendre la teva primera comanda. + Preparat? Ves a la pestanya següent per aprendre com fer el teu propi codi! example_code: | ``` {print} Hello world! @@ -1341,9 +1325,9 @@ adventures: Al nivell anterior has practicat amb `{ask}` i `{if}`. Ara per exemple pots preguntar als convidats què volen per menjar. Encara, però no pots calcular el preu del sopar per tothom. - El següent nivell serà possible utilitzar la suma, resta i la multiplicació als reus programes. D'aquesta manera podràs calcular preus al teu restaurant, també podràs afegir un codi secret per compartir-lo amb els teus amics i família. + En aquest nivell serà possible utilitzar la suma, resta i la multiplicació als reus programes. D'aquesta manera podràs calcular preus al teu restaurant, també podràs afegir un codi secret per compartir-lo amb els teus amics i família. - Una altra opció del següent nivell serà programar el teu propi joc matemàtic, per ajudar al teu germanet o germaneta a practicar les multiplicacions. + Una altra opció d'aquest nivell serà programar el teu propi joc matemàtic, i podràs ajudar al teu germanet o germaneta a practicar les multiplicacions. Descobreix-ho tu mateix! example_code: | ``` @@ -1356,7 +1340,7 @@ adventures: {if} comanda {is} patates preu_menjar {is} 2 beguda {is} {ask} 'Què voleu per beure?' {if} beguda {is} aigua preu_beguda {is} 0 - else preu_beguda {is} 3 + {else} preu_beguda {is} 3 preu_total {is} preu_menjar + preu_beguda {print} 'Seran ' preu_total ' euros, siusplau' ``` @@ -1383,13 +1367,13 @@ adventures: ``` 9: story_text: | - Bona feina! Has aconseguit un nou nivell! Al nivell anterior has aprés a fer servir múltiples línies de codi dins una comanda {if} o {repeat}. Encara, però no pots combinar-les... - Bones notícies! En aquest nivell estarà permès situar un {if} dins d'un altre {if}, o dins d'una comanda {repeat}. + Bona feina! Has aconseguit un nou nivell! Al nivell anterior has après a fer servir múltiples línies de codi dins una comanda {if} o {repeat}. Encara, però no pots combinar-les... + Bones notícies! En aquest nivell estarà permès situar un {if} dins d'un altre {if}, o dins d'una comanda {repeat}. Posar un bloc de codi dins d'un altre bloc de codi es diu anidament. ```Posar un bloc de codi dins d'un altre bloc de codi es diu anidament. example_code: | ``` resposta = {ask} 'Estàs llest per aprendre una cosa nova?' {if} resposta {is} si - {print} 'Genial!, pots aprendre a fer servir la comanda repeteix dins la comanda si!' + {print} 'Genial!, pots aprendre a fer servir la comanda repeat dins la comanda if!' {print} 'Hurra!' {print} 'Hurra!' {print} 'Hurra!' @@ -1397,12 +1381,12 @@ adventures: {print} 'Potser hauràs de repassar el nivell anterior...' 10: story_text: | - Ho estàs fent molt bé! Als nivells anteriors ens hem trobat amb un petit problema. Has après a repetir línies, però què passa si vols fer petits canvis a la línia. - Per exemple si vols cantar la cançó "si ets feliç i ho saps". Tindrà el següent aspecte: + Ho estàs fent molt bé! En els nivells anteriors encara ens vam haver d'enfrontar a un petit problema. Has après a repetir línies, però què passaria si volguessis canviar lleugerament la línia. + Per exemple, si vols cantar la cançó 'Si ets feliç i ho saps'. Es veuria així: - Si també vols el següent vers 'stomp your feet', i el següent, i el següent, hauràs de canviar el codi completament. - En aquest nivell aprendràs la comanda `{for}`, que et permetrà fer una llista d'accions i repetir el codi amb una noca acció cada vegada! - Fes-hi una ullada! + Si també vols el següent vers 'pica de peus', i el següent, i el següent, hauries de canviar completament el codi. + En aquest nivell, aprendràs la comanda `{for}`, que et permet fer una llista d'accions i repetir el codi amb una altra acció cada vegada! + Fem-hi un cop d'ull! example_code: | ``` {repeat} 2 {times} @@ -1447,7 +1431,7 @@ adventures: ``` 14: story_text: | - Amb el programa següent pots calcular si has aprovat una assignatura (per tant, una nota superior o igual a 5). + Amb el codi d'exemple pots calcular si has aprovat una assignatura (per tant, una nota superior o igual a 5). Pots observar que aquest codi és extremadament ineficient, a causa de la longitud excessiva de la línia 5. Totes les notes de l'1 al 5 s'han programat per separat. Estàs de sort, ja que en aquest nivell aprendràs a fer-ho molt més curt! example_code: | @@ -1469,13 +1453,13 @@ adventures: Durant aquest nivell aprendràs una comanda que fa la vida fàcil amb tot això! example_code: | ``` - joc {is} 'en curs' + joc = 'en curs' {for} i {in} {range} 1 {to} 100 - {if} joc {is} 'en curs' + {if} joc == 'en curs' resposta = {ask} 'Vols continuar?' - {if} resposta {is} 'no' - joc {is} 'acabat' - {if} resposta {is} 'si' + {if} resposta == 'no' + joc = 'acabat' + {if} resposta == 'si' {print} D'acord continuem' ``` 16: @@ -1510,22 +1494,22 @@ adventures: L'enhorabona! Has assolit l'últim nivell de Hedy! El codi has creat aquí pot ser copiat a entorns reals de Python com replit o PyCharm, i pots continuar aprenent allà! Tingues en compte que aquell Python només pot llegir comandes en anglès, així que si has estat utilitzant altres llengües, ara les hauràs de posar en anglès. dice: - name: Dice - default_save_name: Dice - description: Make your own dice + name: Dau + default_save_name: Dau + description: Fes el teu dau levels: 3: story_text: | - In this level we can choose from a list. With that we can let the computer choose one side of the die. - Take a look at the games you have in your closet at home. - Are there games with a (special) die? You can also copy it with this code. - For example, the dice of the game Earthworms with the numbers 1 to 5 and an earthworm on it. + En aquest nivell podem escollir des d'una llista. D'aquesta manera podem fer que l'ordinador tiri un dau. + Busca i dona una ullada als jocs que tens a l'armari a casa. + Tens jocs amb un algun dau normal? (o algun amb un dau especial?) Pots recrear-los amb el següent programa. + Per exemple, el dau del joc del Pikomino té els números de l'1 al 5 i en lloc del 6 un cuc de terra dibuixat. - ![Die of earthworms with 1 to 5 and an earthworm on it](https://cdn.jsdelivr.net/gh/felienne/hedy@24f19e9ac16c981517e7243120bc714912407eb5/coursedata/img/dobbelsteen.jpeg) + ![Dau del Pikomino amb cares de l'1 al 5 més un cuc](https://cdn.jsdelivr.net/gh/felienne/hedy@24f19e9ac16c981517e7243120bc714912407eb5/coursedata/img/dobbelsteen.jpeg) example_code: | ``` - choices {is} 1, 2, 3, 4, 5, earthworm - {print} choices {at} {random} + opcions {is} 1, 2, 3, 4, 5, cuc + {print} opcions {at} {random}! ``` story_text_2: | ### Exercise @@ -1533,7 +1517,7 @@ adventures: Or other special dice from a different game? example_code_2: | ``` - choices {is} _ + opcions {is} _ ``` 4: story_text: | @@ -1541,57 +1525,60 @@ adventures: This time the sample code is not quite complete. Can you finish the code? 5: story_text: | - You can also make a die again in this level using the `{if}`. - Complete the sample code so that the code says "You can stop throwing" once you have thrown an earthworm. + Afegirem les comandes `{if}` i `{else}` als nostres daus! - But maybe you want to recreate a die from a completely different game. That's fine too! Then make up your own reaction, e.g. 'yes' for 6 and 'pity' for something else. + ### Exercici + Completa el codi d'exemple perquè el codi digui "Pots deixar de tirar" un cop hagis tirat un cuc. Ha de dir "Has de tornar a tirar" si has tirat qualsevol altra cosa. + **Extra** Potser vols recrear un dau d'un joc completament diferent. També està bé! Llavors, crea la teva pròpia reacció, per exemple, 'sí' per a 6 i 'quina pena' per a qualsevol altra cosa. example_code: | ``` - choices {is} 1, 2, 3, 4, 5, earthworm - throw {is} _ - {print} 'you have' _ 'thrown' - {if} _ {is} earthworm {print} 'You can stop throwing.' _ {print} 'You have to hear it again!' + opcions {is} 1, 2, 3, 4, 5, cuc + tirada {is} opcions {at} {random} + {print} 'Has tirat ' tirada + _ tirada {is} cuc {print} 'Pots parar de tirar.' + _ {print} 'Has de tornar a tirar' ``` 6: story_text: | - You can also make an Earthworm die again in this, but now you can also calculate how many points have been rolled. - You may know that the worm counts 5 points for Earthworms. Now after a roll you can immediately calculate how many points you have thrown. - This is the code to calculate points for one die: + En aquest nivell pots tornar a fer el dau del Pikomino (dau del cuc de terra), ara, però calcularem quants punts s'han aconseguit tirant el dau. + Com segurament ja saps, el cuc compta per 5 punts. Ara, després d'un llançament, pots calcular immediatament quants punts has aconseguit amb la tirada. + Aquest és el codi per calcular els punts d'un dau: - ### Exercise - Can you make the code so that you get the total score for 8 dice? To do that, you have to cut and paste some lines of the code. + ### Exercici + Pots fer el codi per obtenir la puntuació total per a 8 daus? Per fer-ho, hauràs de copiar i enganxar algunes línies del codi. example_code: | ``` - choices = 1, 2, 3, 4, 5, earthworm - points = 0 - throw = choices {at} {random} - {print} 'you threw' throw - {if} throw {is} earthworm points = points + 5 {else} points = points + throw - {print} 'those are' points ' point' + opcions = 1, 2, 3, 4, 5, cuc + punts= 0 + tirada = opcions {at} {random} + {print} "Has tirat " tirada + {if} tirada {is} cuc punts = punts+ 5 {else} punts = punts + tirada + {print} "Això són " punts " punts " ``` example_code_2: | - Did you manage to calculate the score for 8 dice? That required a lot of cutting and pasting, right? We are going to make that easier in level 7! + Has aconseguit calcular la puntuació per a 8 daus? Segur que això ha fet que el copy-paste tregui fum, oi? Ara ho farem més fàcil que al nivell 7! 7: story_text: | - You can also make a die again in level 5. With the `{repeat}` code you can easily roll a whole hand of dice. - Try to finish the sample code! The dashes should contain multiple commands and characters. + També pots fer un dau en aquest nivell. Amb la comanda`{repeat}` pots tirar fàcilment múltiples daus. - But maybe you want to make a completely different die. Of course you can! + ### Exercici + Prova d'acabar el codi d'exemple! **Extra** Pensa en un joc que coneguis que impliqui un dau i programa'l utilitzant un `{repeat}`. example_code: | ``` - choices = 1, 2, 3, 4, 5, earthworm - {repeat} _ _ {print} _ _ _ + opcions = 1, 2, 3, 4, 5, 6 + _ _ _ _ _ _ _ ``` 10: story_text: | - Is everybody taking too long throwing the dice? In this level you can let Hedy throw all the dice at once! - Can you fill in the correct line of code on the blanks? + ### Exercici + Està tothom trigant massa a llençar els daus? En aquest nivell pots deixar que Hedy llenci tots els daus alhora! + Canvia els noms pels noms dels teus amics o familiars i completa el codi. example_code: | ``` - players = Ann, John, Jesse - choices = 1, 2, 3, 4, 5, 6 - _ - {print} player ' throws ' choices {at} {random} + jugadors = Ann, John, Jesse + opcions = 1, 2, 3, 4, 5, 6 + _ _ _ _ + {print} jugador ' tira ' opcions {at} {random} {sleep} ``` 15: @@ -1619,9 +1606,9 @@ adventures: {print} 'Yes! You have thrown 6 in ' tries ' tries.' ``` dishes: - name: Dishes? - default_save_name: Dishes - description: Use the computer to see who does the dishes (Start at level 2) + name: Plats? + default_save_name: Plats + description: Utilitza l'ordinador per veure qui renta els plats. levels: 3: story_text: | @@ -1630,8 +1617,8 @@ adventures: You first make a list of the members of your family. Then choose `{at} {random}` from the list. example_code: | ``` - people {is} mom, dad, Emma, Sophie - {print} people {at} {random} + gent {is} mama, papa, Emma, Sofia + {print} gent {at} {random} li toca rentar plats ``` story_text_2: | Don't feel like doing the dishes yourself? Hack the program by removing your name from the list with the `{remove}` `{from}` command. @@ -1645,10 +1632,10 @@ adventures: Tip: Don't forget the quotation marks! example_code: | ``` - people {is} mom, dad, Emma, Sophie - {print} _ the dishes are done by _ + gent {is} mama, papa, Emma, Sofia + {print} _ els plats son rentats per _ {sleep} - {print} people {at} _ + {print} gent {at} _ ``` 5: story_text: | @@ -1656,50 +1643,56 @@ adventures: Can you finish the code so that it prints 'too bad' when it is your turn and otherwise 'yes!'? Don't forget the quotes! - example_code: "```\npeople {is} mom, dad, Emma, Sophie\ndishwasher {is} people {at} {random}\n{if} dishwasher {is} Sophie {print} _ too bad I have to do the dishes _ \n{else} {print} 'luckily no dishes because' _ 'is already washing up'\n```\n" + example_code: "```\ngent {is} mama, papa, Emma, Sofia\nnetejador {is} gent {at} {random}\n_ netejador {is} Sofia {print} _ Pffff... em toca rentar plats _\n_ {print} 'per sort no hi ha plats perquè ' _ ' ja els està rentant'\n```\n" 6: story_text: | How often is everyone going to do the dishes? Is that fair? You can count it in this level. example_code: | ``` - people = mom, dad, Emma, Sophie - emma_washes = 0 - dishwasher = people {at} {random} - {print} 'The dishwasher is' dishwasher - {if} dishwasher {is} Emma emma_washes = emma_washes + 1 - {print} 'Emma will do the dishes this week' emma_washes 'times' + persones = mama, papa, Emma, Sofia + emma_renta = 0 + netejadora = persones {at} {random} + {print} 'Li toca rentar plats a ' netejadora + {if} rentadora {is} Emma emma_renta = emma_renta + 1 + {print} 'Emma farà els plats aquesta setmana' emma_renta 'vegades' ``` - Now you can copy lines 3 to 5 a few times (e.g. 7 times for a whole week) to calculate for a whole week again. - Do you make the code for the whole week? + Ara pots copiar de la línia 3 a la 5 unes quantes vegades (pex. 7 vegades per fer una setmana). + Pots fer el codi per calcular tota una setmana? story_text_2: | - If you are extremely unlucky the previous program might choose you to to the dishes for the whole week! That's not fair! - To create a fairer system you can use the `{remove}` command to remove the chosen person from the list. This way you don't have to do the dishes again untill everybody has had a turn. + Si tens molta mala sort, el programa anterior podria triar-te per a rentar plats de tota la setmana! I això no és just! + Per crear un sistema més just, pots utilitzar l'ordre `{remove}` per eliminar la persona escollida de la llista. D'aquesta manera no haureu de tornar a rentar els plats fins que tothom hagi tingut el seu torn. - Monday and tuesday are ready for you! Can you add the rest of the week? - And... can you come up with a solution for when your list is empty? + Dilluns i dimarts ja estan preparats per a tu! Pots afegir la resta de la setmana? + I... pots trobar una solució per a quan la llista estigui buida? example_code_2: | ``` - people = mom, dad, Emma, Sophie - dishwasher = people {at} {random} - {print} 'Monday the dishes are done by: ' dishwasher - {remove} dishwasher {from} people - dishwasher = people {at} {random} - {print} 'Tuesday the dishes are done by: ' dishwasher - {remove} dishwasher {from} people - dishwasher = people {at} {random} + gent = mama, papa, Emma, Sofia + netejador = gent {at} {random} + {print} "Dilluns renta: " netejador + {remove} netejador {from} gent + netejador = gent {at} {random} + {print} "Dimarts renta:: " netejador + {remove} netejador {from} gent ``` 7: story_text: | - With the `{repeat}` you can repeat pieces of code. You can use this to calculate who will be washing dishes for the entire week. + Amb el `{repeat}` pots repetir fragments de codi. Pots utilitzar-ho per calcular qui rentarà els plats durant diversos dies! + ### Exercici + Utilitza l'ordre `{repeat}` per decidir qui ha de rentar els plats durant una setmana sencera. Cada espai en blanc s'ha d'omplir amb una comanda o número! + **Extra** Pots pensar en altres tasques de la casa? Adapta el codi perquè decideixi sobre tres tasques domèstiques. No oblidis imprimir de quines tasques es refereix! example_code: | ``` - people = mom, dad, Emma, Sophie - {repeat} _ _ {print} 'the dishwasher is' _ + gent = mama, papa, Emma, Sofia + {repeat} _ _ {print} 'Rentar plats li toca a ' _ _ _ ``` 10: story_text: | - In this level you could make an even better dish washing shedule. + En aquest nivell pots fer un horari per a tota la setmana d'una manera fàcil! + + ### Exercici + Afegeix-hi una segona tasca, com passar l'aspiradora o endreçar, i assegura't que també estigui dividida durant tota la setmana. +
**Extra** El programa no és just, pots tenir mala sort i haver de rentar durnat tota la setmana. Com pots fer el programa més just? example_code: | ``` days = Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday @@ -1709,8 +1702,8 @@ adventures: ``` elif_command: name: '{elif}' - default_save_name: elif - description: elif + default_save_name: sino + description: '{elif}' levels: 17: story_text: | @@ -2610,7 +2603,7 @@ adventures: is_command: name: '{is}' default_save_name: comanda_es - description: Introducció a la comanda és + description: Introducció a la comanda {is} levels: 2: story_text: | @@ -3139,7 +3132,7 @@ adventures: parrot: name: Lloro default_save_name: Parrot - description: Create your own online pet parrot that will copy you! + description: Crea el teu lloro i fes que repeteixi el que li dius! levels: 1: story_text: | @@ -3162,7 +3155,8 @@ adventures: {echo} 2: story_text: | - Create your own online pet parrot that will copy you! + En el nivell anterior has fet un lloro que repetia el que li deies. En aquest nivell farem que el lloro sigui interactiu utilitzant una variable i la comanda `{ask}` . + També farem el lloro sigui més real afegint la comanda `{sleep}` després de dir una cosa. example_code: | ``` {print} Im Hedy the parrot @@ -4389,14 +4383,14 @@ adventures: Hint: Not all lines need indentation. example_code: | ``` - _ actions = 'clap your hands', 'stomp your feet', 'shout Hurray!' - _ {for} action {in} actions + _ accions = "pica de mans", "pica de peus", "crida Hurra!" + _ {for} accio {in} accions _ {for} i {in} {range} 1 {to} 2 - _ {print} 'if youre happy and you know it' - _ {print} action - _ {print} 'if youre happy and you know it and you really want to show it' - _ {print} 'if youre happy and you know it' - _ {print} action + _ {print} "si ets feliç i ho saps" + _ {print} accio + _ {print} "si ets feliç i ho saps, i ho vols fer saber a tothom" + _ {print} "si ets feliç i ho saps" + _ {print} accio ``` 13: story_text: | diff --git a/content/adventures/es.yaml b/content/adventures/es.yaml index 8bb9c53bd0e..52aa368cbb2 100644 --- a/content/adventures/es.yaml +++ b/content/adventures/es.yaml @@ -625,7 +625,7 @@ adventures: ¿Puedes completar la línea 10 para hacer que el código funcione? ### Ejercicio 2 - Dale al jugador información cuando introduzcan una pregunta, por ejemplo `{print} '¡Correcto!'` o `{print} '¡Error! la respuesta correcta era ' respuesta_correcta` + Dale al jugador información cuando introduzcan una pregunta, por ejemplo `{print}` '¡Correcto!' o `{print}` '¡Incorrecto! La respuesta correcta es ' respuesta_correcta example_code: "```\npuntuación = 0\n{repeat} 10 {times}\n números = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10\n número_1 = números {at} {random}\n número_2 = números {at} {random}\n respuesta_correcta = numero_1 * numero_2\n {print} '¿Cuánto es 'número_1' multiplicado por 'número_2'?'\n respuesta = {ask} 'Escriba su respuesta aquí...'\n {print} 'Tu respuesta es ' respuesta\n {if}_{is}_ \n puntuación = puntuación + 1\n{print} '¡Buen trabajo! Tu puntuación es... 'puntuación' sobre 10!'\n```\n" 10: story_text: | @@ -1009,7 +1009,7 @@ adventures: Ten en cuenta que tienes que probar tu código con mucho cuidado para el mes de febrero, porque la cantidad de días de este mes cambia en los años bisiestos. example_code: | - **¡Atención! Este código necesita ser depurado. + **¡Atención! ¡Este código necesita ser depurado!** ``` {print} 'Calendario Hedy' meses_con_31_dias = Enero, Marzo, Mayo, Julio, Septiembre, Octubre, Diciembre @@ -1027,8 +1027,7 @@ adventures: {else} días = 28 - {print} 'Aquí están todos los días de ' - mes + {print} 'Aquí están todos los días de ' mes {for} i {in} {range} 1 {to} días {print} mes i ``` @@ -1126,36 +1125,36 @@ adventures: ### Ejercicio Depura este cuento infantil al azar. ¡Buena suerte! example_code: | - **¡Atención! ¡Este código necesita ser depurado!** + **¡Atención! Este código necesita ser depurado. ``` - nombres = 'Tanya', 'Romy', 'Kayla', 'Aldrin', 'Ali' - verbos='caminar', 'saltar', 'pedalear', 'conducir', 'correr' - ubicaciones = 'en la cima de una montaña', 'en el supermercado', 'en la piscina' - escondites = 'detrás de un arbol', 'bajo una mesa', 'en una caja' - sonidos = 'a trumpet', 'a car crash', 'thunder' - causas_de_ruido = 'una televisión', 'un niño con petardos', 'un elefante mágico', 'un sueño' - - nombre_ elegido = nombres {at} {random} - verbo_elegido = verbos {at} {random} - ubicacion_elegida = 'ubicaciones {at} {random}' - sonidos_elegidos = ruidos {at} {random} - lugar_elegido = escondites {at} {random} - causas_elegidas = causas_de_ruido {at} {random} - - {print} nombre_elegido ' fue ' verbo_elegido ' ' ubicacion_elegida - {print} 'cuando de repente escucharon un sonido de ' sonidos {at} {random} - {print} nombre_elegido ' miró alrededor, pero no pudieron descubrir de donde provenía el sonido' - {print} nombre_elegido ' se escondió en ' lugar_elegido' - {print} 'Miraron alrededor, pero no pudieron ver nada allí' + names = 'Tanya', 'Romy', 'Kayla', 'Aldrin', 'Ali' + verbs='caminar', 'saltar', 'montar en bici', 'conducir', 'correr' + locations = 'en la cima de una montaña', 'en el supermercado', 'a la piscina' + escondites = «detrás de un árbol», «debajo de una mesa», «en una caja». + sonidos = «una trompeta», «un accidente de coche», «un trueno + causas_del_ruido = 'un televisor', 'un niño con petardos', 'un elefante mágico', 'un sueño' + + chosen_name = nombres {at} {random} + chosen_verb = verbos {at} {random} + chosen_location = 'lugares {at} {random}' + chosen_sounds = ruidos {at} {random} + chosen_spot = hiding_spots {random} + chosen_causes = causes_of_noise {at} {random} + + {print} chosen_name ' era ' verbo_elegido ' chosen_spot + {print} 'cuando de repente oyeron un sonido como ' sonidos {at} {random} + {print} chosen_name ' miraron a su alrededor, pero no pudieron descubrir de dónde procedía el ruido' + {print} chosen_name ' escondieron ' punto_elegido' + {print} 'Intentaron mirar alrededor, pero no pudieron ver nada desde allí' oculto = 'sí' {while} oculto = 'sí' - {print} nombre_elegido 'todavía no ven nada' - respuesta = {ask} '¿Se ha movido ' nombre_elegido ' de su escondite?' + {print} chosen_name 'seguían sin ver nada' + respuesta = {ask} «¿se mueve ' chosen_name ' de su escondite? {if} respuesta = 'sí' oculto == 'no' - {print} 'nombre_elegido se movió de ' lugar_elegido - {print} 'Y entonces vieron que sólo era ' causas_elegidas - {print} nombre_elegido 'se rió y siguieron con su día' + {print} 'chosen_name se movió de' chosen_spot + {print} 'Y entonces vieron que era sólo' chosen_cause + {print} chosen_name 'se rieron y siguieron con su día' {print} Fin ``` 16: @@ -1244,18 +1243,19 @@ adventures: levels: 1: story_text: | - ¡Bienvenido a Hedy! Aquí puedes aprender a cómo programar paso a paso. + ¡Bienvenido a Hedy! Aquí puedes aprender a cómo programar paso a paso. ¡Prueba el código por ti mismo! El botón amarillo copia el código de ejemplo a tu bloque de programación. + Después pulsa el botón verde 'Ejecutar código' debajo del campo de programación para ejecutar el código. ¿Preparado? ¡Entonces ve a la siguiente pestaña para hacer tus propios códigos! example_code: | ``` - {print} Hola Mundo! + {print} ¡Hola Mundo! ``` 2: story_text: | - ¡Enhorabuena! Has alcanzado el nivel 2. ¡Espero que ya hayas hecho algunos códigos increíbles! + ¡Enhorabuena! ¡Has alcanzado el nivel 2! ¡Espero que ya hayas hecho algunos códigos increíbles! Quizás te has dado cuenta en el primer nivel que el comando `{echo}` sólo puede guardar un bit de información cada vez. Por ejemplo en la aventura del restaurante, puedes imprimir lo que el cliente quiere comer, o que quiere de beber, pero no ambas en una misma frase. @@ -1606,7 +1606,7 @@ adventures: Haz tu propia versión del programa. Primero haz una lista de los miembros de tu familia. Luego piensa en una tarea que tenga que ser hecha, y deja que la computadora decida quien debe hacer la tarea con el comando `{at} {random}`. - **Extra** ¿No quieres lavar los platos por ti mismo? Hackea el programa quitando tu nombre de la lista con `{remove} {from}`. + **Extra** ¿No quieres lavar los platos por ti mismo? Hackea el programa quitando tu nombre de la lista con el comando `{remove}` `{from}`. 4: story_text: | Usando comillas puedes hacer más interesante tu programa. @@ -1919,11 +1919,10 @@ adventures: levels: 12: story_text: | - En este nivel aprenderás a usar **funciones**. Una función es un bloque de código que se puede utilizar fácilmente varias veces. Usar funciones nos ayuda a organizar piezas de código que podamos usar de forma repetida. - - Para crear una función, usa `{define}` que da a la función un nombre. Luego pon todas las líneas que desees en la función en un bloque con sangría bajo la línea `{define}`. + En este nivel aprenderás a usar **funciones**. Una función es un bloque de código que se puede utilizar fácilmente varias veces. Usar funciones nos ayuda a organizar piezas de código que podamos usar de forma repetida. Para crear una función, usa `{define}` que da a la función un nombre. Luego pon todas las líneas que desees en la función en un bloque con sangría bajo la línea `{define}`. Deja una línea vacía en tu código para que parezca agradable y limpio. Y ya está, ¡Gran trabajo! ¡Has creado una función! + ¡Ahora, cuando necesitemos ese bloque de código, solo usamos {call} con el nombre de la función para llamarlo! No tenemos que volver a escribir ese bloque de código. Echa un vistazo a este código de ejemplo de un juego de Twister. La función 'turno' contiene un bloque de código que elige qué miembro debe ir donde. @@ -2590,9 +2589,9 @@ adventures: ``` story_text_2: | ### Ejercicio - ¡Hora de crear tus propias variables! - En el código de ejemplo hicimos un ejemplo de la variable `animal_favorito`. En la línea 1 se crea la variable, y en la línea 2 usamos la variable en un comando `{print}`. - Lo primero de todo, termina nuestro ejemplo rellenando tu animal favorito en el hueco en blanco. Después haz 3 códigos como estos por ti mismo. Elige una variable, y establece la variable con el comando `{is}`. Entonces úsala con un comando `{print}`, como hicimos. + ¡Es hora de hacer tus propias variables! + En el código de ejemplo hemos hecho un ejemplo de la variable `favorite_animal`. En la línea 1 la variable está establecida, y en la línea 2 usamos la variable en un comando `{print}. + En primer lugar, terminar nuestro ejemplo rellenando su animal favorito en el blanco. Luego haga al menos 3 de estos códigos usted mismo. Escoge una variable, y establece la variable con el comando `{is}`. Luego úsala con un comando `{print}`, tal como hicimos. example_code_2: | ``` animal_favorito {is} _ @@ -2826,12 +2825,12 @@ adventures: ``` 5: story_text: | - You don't always have to use the `{play}` command to play a whole song, sometimes you just want to play one note. - For example, if you want to make a quiz, you can play a happy high note if the answer is right and a sad low note if the answer is wrong. + No siempre tienes que usar el comando `{play}` para reproducir una canción entera, a veces solo quieres tocar una nota. + Por ejemplo, si quieres hacer un cuestionario, puedes tocar una nota alta feliz si la respuesta es correcta y una nota baja triste si la respuesta es incorrecta. - ### Exercise - Finish the first question by adding a line of code that plays a C3 note if the wrong answer is given. - Then think of 3 more questions to add to this quiz. + ### Ejercicio + Termina la primera pregunta añadiendo una línea de código que reproduzca una nota C3 si se da la respuesta incorrecta. + Luego piensa en 3 preguntas más para agregar a este cuestionario. example_code: | ``` respuesta {is} {ask} '¿Cuál es la capital de Zimbabwe?' @@ -2854,11 +2853,11 @@ adventures: ``` 7: story_text: | - Using the `{repeat}` command can make your codes for melodies a lot shorter! + ¡Utilizar el comando `{repeat}` puede hacer que tus códigos para melodías sean mucho más cortos! - ### Exercise - Finish the code for Twinkle Twinkle Little Star by using the `{repeat}`command. - Then go back to the songs you've made in the previous levels. Can you shorten those codes too? + ### Ejercicio + Termina el código de Twinkle Twinkle Little Star utilizando el comando `{repeat}`. + Luego vuelve a las canciones que has hecho en los niveles anteriores. ¿Puedes acortar también esos códigos? example_code: | ``` {print} 'Brilla Brilla Estrellita' @@ -2868,10 +2867,10 @@ adventures: ``` 8: story_text: | - Now that we can use the `{repeat}` command for multiple lines, we can make songs even more easily! + Ahora que podemos usar el comando `{repeat}` para múltiples líneas, ¡podemos hacer canciones aún más fácilmente! - ### Exercise - Finish the song of Brother John (Frère Jacques). Don't forget to use `{repeat}`! + ### Ejercicio + Termina la canción del Hermano Juan (Frère Jacques). ¡No olvides utilizar `{repeat}`! example_code: | ``` {print} 'Hermano John' @@ -2888,11 +2887,11 @@ adventures: ``` 9: story_text: | - From this level on you can - among other things - use a {repeat} command inside a {repeat} command. - That makes songs like 'Happy birthday' even shorter! + A partir de este nivel puedes, entre otras cosas, utilizar un comando {repeat} dentro de otro {repeat}. + Eso hace que canciones como 'Cumpleaños feliz' sean aún más cortas. - ### Exercise - Finish the song! + ### Ejercicio + ¡Termina la canción! example_code: | ``` primera_vez = sí @@ -3321,10 +3320,10 @@ adventures: ``` story_text_2: | ### Ejercicio - En Hedy puedes encontrar ejercicios en cada aventura. Un ejercicio te permite practicar los nuevos comandos y conceptos, y te permite darle tu propio toque a los códigos de ejemplo. - En este ejercicio verás un espacio en blanco rosa. Tienes que rellenar algo en el lugar del espacio en blanco antes de que se pueda ejecutar tu código. + En Hedy encontrarás ejercicios en cada aventura. Un ejercicio te permite practicar los nuevos comandos y conceptos, y te permite dar tu propio giro a los códigos de ejemplo. + En este ejercicio verás un espacio en blanco de color rosa. Tienes que rellenar algo en el lugar del espacio en blanco antes de que el código pueda ejecutarse. - Rellena el comando `{print}` en el espacio en blanco y después añade cinco líneas de código. Cada línea tiene que empezar con un comando `{print}`. + Rellene el comando `{print}` en el espacio en blanco y luego añada cinco líneas más de código. Cada línea debe comenzar con un comando `{print}`. ¡Diviértete! example_code_2: | ``` @@ -3508,10 +3507,10 @@ adventures: 7: story_text: | ## ¡Repetir! ¡Repetir! ¡Repetir! - El nivel 7 añade el comando `{repeat}`. `{repeat}` se puede usar para ejecutar una línea de código varias veces. Tal que así: + El nivel 7 añade el comando `{repeat}`. `{repeat}` se puede utilizar para ejecutar una línea de código varias veces. Así: ### Ejercicio - Juega con el comando repetir. ¿Puedes ahora hacer la canción de cumpleaños feliz en sólo 3 líneas de código en vez de en 4? + Juega con el comando `{repeat}`. ¿Puedes hacer la canción de cumpleaños feliz en sólo 3 líneas de código en lugar de 4 ahora? example_code: | ``` {repeat} 3 {times} {print} '¡Hedy es divertido!' @@ -3531,8 +3530,10 @@ adventures: ``` 9: story_text: | - En este nivel no puedes usar varias líneas sólo con `{if}` y `{repeat}`, ¡pero si puedes juntarlas! - En este ejemplo ves un comando `{if}` dentro de un comando `{repeat}`. También se permite lo contrario, y también un `{if}` se permite en un `{if}` y un `{repeat}` en un `{repeat}`. + ¡Buen trabajo! ¡Has alcanzado otro nuevo nivel! En el nivel anterior has aprendido a utilizar múltiples líneas de código en un comando `{if}` o `{repeat}`. + Pero aún no puedes combinar ambos... + + Buenas noticias. En este nivel podrás poner un `{if}` dentro de un `{if}`, `{repeat}` dentro de un comando `{repeat}` y entre ellos. ¡Pruébalo! example_code: | ``` @@ -3819,10 +3820,10 @@ adventures: ``` 12: story_text: | - A partir de este nivel puedes usar números decimales para hacer que tu menú sea más realista. + A partir de este nivel, puedes utilizar números decimales para que tu menú sea más realista. ### Ejercicio - ¿Puedes pensar en un código para darle a tus amigos y familiares un 15% de descuento? + ¿Se te ocurre un código para hacer un descuento del 15% a tus amigos y familiares? example_code: | ``` precio = 0.0 @@ -3905,10 +3906,10 @@ adventures: ``` 2: story_text: | - En este nivel puedes practicar usando las variables, ¡así puedes hacer un juego de piedra, papel o tijeras en el próximo nivel! + En este nivel puedes practicar el uso de las variables, ¡para poder hacer el juego de piedra, papel o tijera en el siguiente nivel! ### Ejercicio - Completa el código poniendo la **variable** en los huecos en blanco. - Este juego no es muy interactivo, ¡pero no te preocupes! !En la siguiente pestaña aprenderás como usar las variables con el comando `{ask}` para hacer tu juego interactivo! + Termina el código rellenando la **variable** en el espacio en blanco. + Este juego no es muy interactivo, ¡pero no te preocupes! En la siguiente pestaña aprenderás a usar variables con el comando `{ask}` ¡para hacer tu juego interactivo! example_code: |- ``` opción {is} piedra @@ -4068,12 +4069,12 @@ adventures: Añade un tercer componente al código, como una prenda de ropa o un objeto. example_code: | ``` - nombre = {ask} '¿Cuál es tu nombre?' - {if} nombre {is} '_' + nombre = {ask} ¿Cuál es tu nombre? + {if} nombre {is} _ a = 'Ve al aeropuerto ' {else} - a = 'Ve a la estación de trenes ' - contraseña = {ask} '¿Cuál es la contraseña?' + a = 'Ve a la estación de tren ' + contraseña = {ask} '¿Cuál es la contraseña? {if} contraseña {is} _ b = 'mañana a las 02.00' {else} @@ -4082,13 +4083,13 @@ adventures: ``` 13: story_text: | - Podemos simplificar el código superespía con `{and}`, entonces sólo necesitamos un `{if}`. + Podemos simplificar el código de superspy con `{and}`, de forma que solo necesitemos un `{if}`. ### Ejercicio 1 - Completa el código rellenando el comando correcto en el hueco en blanco. Consejo: El superespía tiene que responder a AMBAS preguntas correctamente, ¡antes de que consigan la información confidencial! + Completa el código rellenando el comando correcto en el espacio en blanco. Consejo: El superespía tiene que responder correctamente a AMBAS preguntas antes de obtener la información confidencial. ### Ejercicio 2 - ¡Queremos confundir aún más al enemigo! Crea una lista con respuestas falsas y selecciona una al azar cuando den una respuesta incorrecta. + Queremos confundir aún más al enemigo. Crea una lista con respuestas falsas y selecciona una al azar cuando se dé una respuesta incorrecta. example_code: | ``` nombre = {ask} '¿Cuál es tu nombre?' @@ -4354,7 +4355,7 @@ adventures: ### Ejercicio ¿Puedes añadir la cantidad correcta de sangría a cada línea para que la canción se reproduzca correctamente? - Nota: No todas las líneas necesitan sangría + Pista: No todas las líneas necesitan sangría. example_code: | ``` _ acciones = 'aplaude', 'mueve los pies así', '¡grita hurra!' @@ -4442,11 +4443,11 @@ adventures: ``` {define} twinkle {print} 'Twinkle' - {print} '...' + {print} _ {call} twinkle - {print} 'Up above the world so high' - {print} 'Like a diamond in the sky' + {print} 'Tan alto sobre el mundo' + {print} 'Como un diamante en el cielo' {call} _ ``` 16: @@ -4650,20 +4651,29 @@ adventures: ``` 2: story_text: | - En este nivel puedes utilizar variables para hacer tu tortuga interactiva. Por ejemplo, puedes preguntar al jugador cuantos pasos dará la tortuga. + En el nivel 1 la tortuga sólo podía girar a izquierda o derecha. ¡Eso es un poco aburrido! + En el nivel 2 puede apuntar su nariz en todas direcciones. + + Use 90 grados para girar un cuarto, 180 grados para girar la mitad, y un círculo completo es 360 grados. + + ### Ejercicio + Este código ahora crea la letra T. ¿Puedes cambiarlo para que sea la letra B? + + **Extra** Cambia la letra por una letra diferente, como la primera de tu nombre. + También puede hacer varias letras, estableciendo el color a `{color}` `{white}` entre ellas. example_code: | ``` - respuesta {is} {ask} ¿Cuántos pasos debería dar la tortuga? - {forward} respuesta + {forward} 20 + {turn} 90 + {forward} 20 + {turn} 180 + {forward} 100 ``` story_text_2: | - Además, en el nivel 1 la tortuga solo podía girar a la derecha o a la izquierda. ¡Qué aburrido! - En el nivel 2 la tortuga puede apuntar su nariz en todas las direcciones. - - Utiliza 90 para girar un cuarto. Lo llamamos grados, un giro completo son 360 grados. + Puedes usar variables para en la tortuga `turn`. ### Ejercicio - ¿Puedes hacer una figura con este código? ¿Quizá un triangulo o un círculo? + Cambia el código para que cree un triángulo. Pista: sólo tienes que cambiar el código en un sitio. example_code_2: | ``` {print} Dibujando figuras @@ -4672,6 +4682,8 @@ adventures: {forward} 25 {turn} ángulo {forward} 25 + {turn} ángulo + {forward} 25 ``` 3: story_text: | @@ -5061,14 +5073,9 @@ adventures: Primero, define una función **por cada forma** que quieras usar en el brazalete. Después, añade las formas al brazalete como este: - Programa de Diseño de Brazalete example_code: | - Sugerencia: Programa para diseñar pulsera - - - Primero, define una función **para cada forma** que quieras usar en tu pulsera. Después, añade las formas a la pulsera tal que así: - + Hint Bracelet Programa de diseño ``` {define} dibujar_un_cuadrado _ @@ -5079,13 +5086,13 @@ adventures: {turn} 180 {for} i {in} {range} 1 {to} 5 - {color} gris - {forward} 100 - forma = {ask} '¿Qué tipo de forma quieres en el siguiente brazalete?' - color_elegido = {ask} '¿En qué color?' - {color} color_elegido - {if} forma = 'cuadrado' - {call} dibujar_un_cuadrado + {color} gris + {forward} 100 + forma= {ask} '¿Qué tipo de forma le gustaría a continuación en el brazalete?' + color_elegido = {ask} '¿En qué color?' + {color} color_elegido + {if} forma = 'cuadrado' + {call} dibujar_un_cuadrado ``` 13: story_text: | @@ -5111,21 +5118,22 @@ adventures: {define} dibuja_una_casa {with} color_elegido _ ``` - Hint Snow Storm + + Tormenta de la Pista de Nieve ``` - {define} draw_snowflake {with} length, color - _ + {define} dibujar_copo_nieve {with} longitud, color + _ - numbers = 10, 20, 30 - colors = _ + números= 10, 20, 30 + colores = _ {for} i {in} {range} 1 {to} 5 - random_number = _ - random_color = _ - {call} draw_snowflake {with} random_number, random_color - {color} white - {turn} random_number * 5 - {forward} 80 + número_aleatorio = _ + color_aleatorio = _ + {call} dibujar_copo_nieve {with} número_aleatorio , color_aleatorio + {color} blanco + {turn} número_aleatorio * 5 + {forward} 80 ``` 14: diff --git a/content/adventures/sr.yaml b/content/adventures/sr.yaml index 32f743aa6df..4ef99110c69 100644 --- a/content/adventures/sr.yaml +++ b/content/adventures/sr.yaml @@ -1,508 +1,511 @@ adventures: story: - name: Priča - default_save_name: Priča - description: Priča + name: Прича + default_save_name: Прича + description: Прича levels: 1: story_text: | - U nivou 1 možeš da osmisliš priču sa različitim glavnim junacima koje ćeš sam uneti. + На нивоу 1 можеш направити причу са различитим главним ликом који сам унесеш. - Na prvoj liniji, koristi `{ask}` i upitaj ko će biti glavni junak priče. + У првој линији, користи `{ask}` и питај ко ће бити главни лик приче. - Posle te prve linije, počni sa `{print}` ako rečenica treba da bude ištampana. - Koristi `{echo}` ako želiš da tvoj glavni junak bude na kraju rečenice. + Након те прве линије, почни са `{print}` ако реченица треба да се испише. + Користиш `{echo}` ако желиш да твој главни лик буде на крају реченице. example_code: | ``` - {ask} Glavni junak priče je - {print} Glavni junak će sada da ide da prošeta u šumu - {echo} On je pomalo uplašen, - {print} Čuje neobične zvuke svuda unaokolo - {print} Boji se da je ovo ukleta šuma + {ask} Главни лик ове приче је + {print} Главни лик сада иде у шуму + {echo} Мало је уплашен, + {print} Чује чудне звуке свуда око себе + {print} Плаши се да је ово уклета шума ``` story_text_2: | - ### Vežbanje - Sada osmisli svoju pricu sa najmanje 6 linija koda. - Ova priča ne sme biti ista kao kod iz primera. - Koristi bar jednu komandu `{ask}` i jednu komandu `{echo}`. - Možeš odabrati bilo koju temu. - Ako ne možeš da smisliš baš ni jednu, upotrebi neku od naših tema: odlazak u bioskop, sportska utakmica ili dan u zološkom vrtu. + ### Вежба + Сада направи своју причу од најмање 6 линија кода. + Ова прича не може бити иста као пример кода. + Користи бар једну `{ask}` и једну `{echo}` команду. + Можеш је направити о било којој теми коју желиш. + Ако не можеш да смислиш тему, користи једну од наших опција: одлазак у биоскоп, спортски меч или дан у зоолошком врту. 2: story_text: | - U nivou 2 možeš učiniti da tvoje priče budu još zabavnijim. Ime tvog glavnog junaka se sada može nalaziti bilo gde u rečenici. + На нивоу 2 можеш учинити своју причу забавнијом. Име твог главног лика сада може бити било где у реченици. - Mada, za to moraš isprogramirati malo dodatnog koda. Glavnog junaka moraš sada imenovati prvo. + Мораш мало више програмирати за то. Прво мораш именовати свог главног лика. - Onda možeš staviti ime bilo gde u rečenici. + Затим можеш ставити то име било где у реченици. example_code: |- ``` - ime {is} {ask} Kako se glavni junak zove? - {print} ime će sada da trči u šumi - {print} ime je pomalo uplašen - {print} On odjednom čuje neobičan zvuk... + name {is} {ask} Како се зове главни лик? + {print} name сада трчи кроз шуму + {print} name је мало уплашен + {print} Одједном чује чудан звук... {sleep} - {print} ime je uplašen da je ovo ukleta šuma + {print} name се плаши да је ово уклета шума ``` story_text_2: | - ### Vežbanje - Sada je vreme da dodaš promenljive u tvoju priču koju si osmislio u prethodnom nivou. - Idi u 'Moji programi', potraži svoju priču o avanturi u nivou 1 i prekopiraj kod. Dodaj taj kod u ekran za unos u ovom nivou. + ### Вежба + Сада је време да додаш променљиве у своју причу коју си направио на претходном нивоу. + Иди на 'Моји програми', пронађи своју причу авантуре са нивоа 1 и копирај код. Налепи код у свој улазни екран на овом нивоу. - Ovaj kod neće raditi u ovom novou, jer još uvek nisi koristio promenljive. - Promeni komande `{ask}` i `{echo}` u svom kodu u tačan oblik koji si naučio u ovom nivou. + Овај код неће радити на овом нивоу, јер још ниси користио променљиве. + Промени `{ask}` команде и `{echo}` команде у свом коду у исправан облик који си научио на овом нивоу. - **Dodatno** Dodaj komandu sleep u svoj kod da bi podigao napetost u svojoj priči. + **Додатно** Додај `{sleep}` команду у свој код да би повећао напетост у својој причи. 3: story_text: | - U nivou 3 možeš osmisliti priču da bude još zanimljivija. Možeš odabrati bilo koje čudovište, životinju ili bilo koju drugu prepreku, ovako: + На нивоу 3 можеш учинити своју причу забавнијом. Можеш користити случајност за било које чудовиште, животињу или другу препреку, овако: example_code: | ``` - životinje {is} 🦔, 🐿, 🦉, 🦇 - {print} On sada cuje zvuk životinje {at} {random} + animals {is} 🦔, 🐿, 🦉, 🦇 + {print} They now hear the sound of an animals {at} {random} ``` story_text_2: | - Komanda `{add}` ti takodje može biti korisna u tvojoj priči. + Команда `{add}` такође може бити корисна у твојој причи. example_code_2: | ``` - {print} On čuje zvuk - životinje {is} 🐿, 🦔, 🦇, 🦉 - životinja {is} {ask} Šta misliš da je to? - {add} životinja {to_list} životinje - {print} to je bila životinje {at} {random} + {print} They hear a sound + animals {is} 🐿, 🦔, 🦇, 🦉 + animal {is} {ask} What do you think it is? + {add} animal {to_list} animals + {print} it was an animals {at} {random} ``` story_text_3: | - Ovo je primer komande `{remove}` u tvojoj priči + Ово је пример команде `{remove}` у твојој причи - ### Vežbanje - Prekopiraj tvoju priču iz prethodnog nivoa u ovaj nivo. - U ovom novou si naučio 3 nove komande `{at} {random}` , `{add} {to_list}` i `{remove} {from}`. - Dodaj nove linije koda u svoju priču, tako da iskoristiš svaku komandu bar jednom. + ### Вежба + Копирај своју причу са претходних нивоа у овај ниво. + На овом нивоу си научио 3 нове команде `{at} {random}`, `{add} {to_list}` и `{remove} {from}`. + Додај нове линије кода у своју причу, тако да све нове команде буду коришћене бар једном у твојој причи. example_code_3: | ``` - {print} Njegov je postao previše težak. - {print} Unutra je bila flaša sa vodom, baterijska lampa i cigla. - ranac {is} vida, lampa, cigla - otpad {is} {ask} Šta bi iz torbe trebalo izbaciti? - {remove} otpad {from} ranac + {print} Његов ранац је постао превише тежак. + {print} Унутра су били флаша воде, батеријска лампа и цигла. + bag {is} вода, батеријска лампа, цигла + dump {is} {ask} Који предмет треба да избаци? + {remove} dump {from} bag ``` 4: story_text: | - ### Vežbanje 1 - Kopiraj primer koda i dodaj znake navoda da bi proradio. + ### Вежба + Копирај пример кода и заврши га додавањем наводника на празна места у линијама 1 и 2. + Празна места у линијама 3 и 4 не треба заменити наводницима, већ командама `{sleep}` и `{clear}`. Можеш ли то учинити? - ### Vežbanje 2 - Idi nazad u prethodni nivo i kopiraj kod svoje priče. Dodaj znake navoda na odgovarajućim mestima kako bi kod proradio i u ovom nivou. - Obrati pažnju: Promenljive u tvojoj priči ne bi trebale da se nalaze izmedju znaka navoda. Baš kao druga linije koda u primeru. U toj liniji promenljiva ime se nalazi izvan znaka navoda. + ### Вежба 2 + Врати се на претходни ниво и копирај свој код приче. Учини да код ради на овом нивоу додавањем наводника на права места. + Пази: Променљиве у твојој причи треба да буду ван наводника. Баш као у другој линији пример кода. У тој линији променљива name је постављена ван наводника. example_code: | ``` - ime {is} {ask} _ Kako se zoveš? _ - {print} _ Glavni junak se zove _ ime - {print} ime _ ide sada da šeta u šumu _ - {print} ime _ je pomalo uplašen _ - životinje {is} 🦔, 🐿, 🦉, 🦇 - {print} _ On čuje zvuk _ životinje {at} {random} - {print} ime _ se boji da je šuma ukleta _ + name {is} {ask} _ Како се зовеш? _ + {print} _ Главни лик се зове _ name + _ + _ + {print} name _ сада иде у шуму _ + {print} name _ је мало уплашен _ + animals {is} 🦔, 🐿, 🦉, 🦇 + {print} _ Чује звук _ animals {at} {random} + {print} name _ се плаши да је ово уклета шума _ ``` 5: story_text: | - U ovom nivou možeš isprogramirati različite završetke, koji će učiniti da tvoja priča bude još zanimljivija. - U primeru kod možeš videti kako možeš osmisliti dva različita završetka. + На овом нивоу можеш програмирати различите завршетке, што ће учинити твоју причу још забавнијом. + У пример коду можеш видети како направити 2 различита завршетка. - ### Vežba 1 - Napiši novu kratku priču sa bar 6 linija koda u vezi teme koju si odabrao. - Nemas ideju? Odaberi onda jednu od ovih tema: superheroji, dosadan dan u školi, sam na napuštenom ostrvu. + ### Вежба 1 + Напиши нову кратку причу од најмање 6 линија кода о теми по твом избору. + Нема инспирације? Изабери једну од ових тема: суперхерој, досадан школски дан, насукан на пустом острву. - Sada daj opciju da igrač odabere srećan ili nesrećan kraj priče, kao što je u primeru. - Isprogramiraj oba završetka. + Сада дај играчу могућност да изабере срећан или лош завршетак, баш као у пример коду. + Програмирај оба завршетка. - ### Vežba 2 - Iskopiraj priču koju si osmislio u svojoj avanturi u prethodnim nivoima. - Pronadji način da dodaš bar po dve komande `{if}` i `{else}` u svoju priču. - Može biti sa srećnim ili nesrećnim završetkom, ali možeš i na druge načine upotrebiti ove komande. + ### Вежба 2 + Копирај причу коју си направио у својој авантури приче на претходним нивоима. + Пронађи начин да додаш бар 2 `{if}` и `{else}` команде у своју причу. + Ово може бити са срећним или лошим завршетком, али можеш и покушати да пронађеш друге начине да укључиш команде. example_code: | ``` - ime {is} {ask} 'Ko šeta šumom?' - {print} ime ' šeta šumom' - {print} ime ' susreće čudovište' - kraj {is} {ask} 'Da li želiš srećan ili nesrećan završetak?' - {if} kraj {is} srećan {print} ime ' uzima mač i čudovište beži glavom bez obzira' - {else} {print} 'Čudovište pojede ' ime + name {is} {ask} 'Ко шета кроз шуму?' + {print} name ' шета кроз шуму' + {print} name ' наилази на чудовиште' + end {is} {ask} 'Да ли желиш срећан или лош завршетак?' + {if} end {is} good {print} name ' узима мач и чудовиште брзо бежи' + {else} {print} 'Чудовиште поједе ' name ``` 7: - story_text: "U priči, neko će ponoviti reči nekoliko puta. Na primer, kada neko zove u pomoć ili peva pesmu.\nU ovom nivou ovakva ponavljanja staviti u svoju priču sa`{repeat}`.\n\n### Vežbanje\nDodaj ponavljanja u svoju priču. Vrati se do svojih sačuvanih programa, odaberi priču iz nivoa 6 i \npronadji liniju sa komandom `{print}` i ponovi je!\n" + story_text: "У причи, неко изговара речи неколико пута. На пример, када неко зове у помоћ или пева песму.\nМожеш ставити такве понављања у своју причу, на овом нивоу са `{repeat}`.\n\n### Вежба\nДодај понављање у своју причу. Врати се на своје сачуване програме, изабери свој програм приче са претходног нивоа и\nпронађи линију која садржи `{print}` и понови је!\n" example_code: | ``` - {print} 'The prince kept calling for help' - {repeat} 5 {times} {print} 'Help!' - {print} 'Why is nobody helping me?' + {print} 'Принц је стално звао у помоћ' + {repeat} 5 {times} {print} 'Помоћ!' + {print} 'Зашто ми нико не помаже?' ``` 8: - story_text: "In this level you can use multiple lines in your {if} commands, this way you can upgrade your happy or sad ending!\n\n### Exercise 1\nThe example code shows two different endings; one where the characters jump in a time machine and one where they do not.\nComplete the blanks with at least one sentence per ending. \n**(extra)** Make the story longer. What happens in the story? You can also add a second `{ask}` with different options.\n \n### Exercise 2\nGo back to your saved programs, choose your story program from level 5. Now write a good and a bad ending of at least three lines long each! \n" + story_text: "На овом нивоу можеш користити више линија у својим `{if}` командама, на тај начин можеш побољшати свој срећан или тужан завршетак!\n\n### Вежба 1\nПример кода показује два различита завршетка; један где ликови скачу у временску машину и један где не скачу.\nПопуни празна места са најмање једном реченицом по завршетку.\n**Додатно** Продужи причу. Шта се дешава у причи? Можеш додати и другу `{ask}` команду са различитим опцијама.\n\n### Вежба 2\nВрати се на своје сачуване програме, изабери свој програм приче са нивоа 5. Сада напиши добар и лош завршетак од најмање три линије сваки!\n" example_code: | ``` - {print} 'Ooo NE! T-rex se približava!' - kraj = {ask} 'Da li želiš srećan ili nesrećan završetak?' - {if} kraj {is} srećan - {print} 'U poslednjem času Ričard je uskočio nazad u vremeplov!' + {print} 'О НЕ! Т-Рекс се приближава!' + end = {ask} 'Да ли желиш срећан или тужан завршетак?' + {if} end {is} happy + {print} 'У последњем тренутку Ричард скаче назад у временску машину!' {print} _ {else} - {print} 'Ooo ne! Rićard je previše spor...' + {print} 'О не! Ричард је преспор...' {print} _ ``` 9: - story_text: "U ovom nivou možeš koristiti komande `{if}` i `{repeat}` unutar comandi `{if}` i `{repeat}`. \nOvo ti daje mnoge opcije i zaista pomaže da tvoja priča bude što interaktivnija.\n\n### Vežbanje 1\nZavrši kod tako da `{if}` radi tačno.\n\n### Vežbanje 2\nDodaj `{if}` i `{else}` za deo priče gde Robin takodje ide kući.\n\n### Vežbanje 3\nIdi nazad na novo 8 tvoje priče i iskoristi bar dva puta `{if}`unutar drugog `{if}`.\n" + story_text: "На овом нивоу можеш користити `{if}` и `{repeat}` команде унутар других `{if}` и `{repeat}` команди.\nОво ти даје много опција и заиста помаже да твоја прича буде интерактивна.\n\n### Вежба 1\nЗаврши код тако да `{if}` ради исправно.\n\n### Вежба 2\nДодај `{if}` и `{else}` за део приче где Робин такође иде кући.\n\n### Вежба 3\nВрати се на своју причу са нивоа 8 и користи бар два `{if}` унутар другог `{if}`.\n" example_code: | ``` - {print} 'Robin se seta po gradu' - lokacija = {ask} 'Da li Robin ide u prodavnicu ili pak kući?' - {if} lokacija {is} prodavnica - {print} 'Ona ulazi u prodavnicu.' - {print} 'Robin vidi knjigu koja izgleda zanimljivo' - knjiga = {ask} 'Da li Robin kupuje knjigu?' - {if} knjiga {is} da - _ {print} 'Robin kupuje knjigu i odlazi kući' + {print} 'Робин шета градом' + location = {ask} 'Да ли Робин улази у продавницу или иде кући?' + {if} location {is} продавница + {print} 'Улази у продавницу.' + {print} 'Робин види занимљиву књигу' + book = {ask} 'Да ли Робин купује књигу?' + {if} book {is} да + _ {print} 'Робин купује књигу и иде кући' _ {else} - _ {print} 'Robin napušta prodavnicu i odlazi kući' + _ {print} 'Робин напушта продавницу и иде кући' {else} - {print} 'Robin odlazi kući' + {print} 'Робин иде кући' ``` 10: story_text: | - U ovom novou možeš koristiti komadnu {for} u svojoj priči. Na ovaj način možeš lako isprogramirati knjigu za decu 'Braon medo, braon medo, sta ti to vidiš'. + На овом нивоу можеш користити команду {for} у својој причи. На овај начин можеш лако програмирати дечију књигу 'Браон медведе, Браон медведе, шта видиш'. - ### Vežbanje + ### Вежба - Pogledaj priča ako je ne znaš i potrudi se da bude ištampana kao u knjizi. - example_code: "```\nživotinje = _ , _ , _ \n{print} 'Braon medo, Braon medo'\n {print} 'Šta ti to vidiš?'\n```\n" + Погледај причу ако је не знаш, и увери се да је исписана као у књизи. + example_code: "```\nживотиње = _ , _ , _ \n{print} 'Браон медведе, Браон медведе'\n{print} 'Шта видиш?'\n```\n" 12: story_text: |- - U ovom nivou znaci navoda će biti potrebni da sačuvaš više reči u promenljivoj. + На овом нивоу ће бити потребни наводници да би се сачувале више речи у променљивој. - ### Vežbanje + ### Вежба - Pronadji priču iz prethodnog nivoa, može biti bilo koji nivo. Sada se postaraj da su znaci navoda dodati na potrebnim mestima. + Пронађи причу са претходног нивоа, било који ниво је у реду. Сада се увери да су наводници додати на правим местима. example_code: | ``` - ime = 'Kraljica Engleske' - {print} ime ' je jela parče torte, kada najednom...' + name = 'Краљица Енглеске' + {print} name ' је јела комад торте, када одједном…' ``` 13: story_text: | - Sa komandama `{and}` i `{or}`, možes osmisliti svestranije priče. Možešeš postaviti dva pitanja i odgovoriti sa kombinacijom odgovora. + Коришћењем команди `{and}` и `{or}`, можеш учинити своје приче разноврснијим. Можеш поставити два питања и одговорити на комбинацију одговора. - ### Vežbanje 1 - Pogledaj primer koda i završi ga. Onda dodaj bar još dve komande `{if}` sa `{and}` ili `{or}`. + ### Вежба 1 + Погледај пример кода и заврши га. Затим додај бар још 2 `{if}` кода са `{and}` или `{or}`. - ### Vežbanje 2 - Pronadji priču iz prethodnog nivoa, i dodaj jedno `{and}` ili `{or}`. + ### Вежба 2 + Пронађи причу са претходног нивоа и додај један `{and}` или `{or}`. example_code: | ``` - {print} 'Naš heroj šeta šumom' - {print} 'Put se račva u dve strane' - put = {ask} 'Koji put bi trebala da odabere?' - oružje = {ask} 'Koje oružje bira?' - {if} put {is} 'levo' {and} oružje {is} 'mač' + {print} 'Наш херој шета кроз шуму' + {print} 'Стаза се раздваја на два пута' + path = {ask} 'Који пут треба да изабере?' + weapon = {ask} 'Које оружје вади?' + {if} path {is} 'лево' {and} weapon {is} 'мач' _ ``` 15: story_text: | - `{while} game == 'on'Koristeći petlju `{while}` tvoje priče mogu biti zanimljivije. Na primer, možeš koristiti `{while} game == 'on'` da bi mogao da igraš sve dok se igra ne završi. - Ili možeš upotrebiti `{while} sword == 'lost'` da igrač ne može da nastavi igru sve dok ne nadje nešto. + Коришћење `{while}` петље може учинити твоје приче занимљивијим. На пример, можеш користити `{while} game == 'on'` тако да можеш играти док игра не буде завршена. + Или можеш користити `{while} sword == 'lost'` тако да играч не може наставити игру док не пронађе нешто. - ### Exercise - The example code shows you how to use the `{while}` loop in a story. Now **think of your own scenario** in which the player has to find something before they can continue. + ### Вежба + Пример кода ти показује како да користиш `{while}` петљу у причи. Сада **смисли свој сценарио** у којем играч мора пронаћи нешто пре него што може наставити. example_code: | ``` - keys = 'lost' - {print} 'You are standing in your garden and you have lost your keys.' - {print} 'Where do you want to look for them?' - {print} 'You can choose: tree, flowerbed, rock, postbox' - {while} keys == 'lost' - location = {ask} 'Where do you want to look?' - {if} location == 'flowerbed' - {print} 'Here they are!' - keys = 'found' + keys = 'изгубљени' + {print} 'Стојиш у свом врту и изгубио си кључеве.' + {print} 'Где желиш да их тражиш?' + {print} 'Можеш изабрати: дрво, цветна гредица, камен, поштанско сандуче' + {while} keys == 'изгубљени' + location = {ask} 'Где желиш да тражиш?' + {if} location == 'цветна гредица' + {print} 'Ево их!' + keys = 'пронађени' {else} - {print} 'Nope they are not at the ' location - {print} 'Now you can enter the house!' + {print} 'Не, нису код ' location + {print} 'Сада можеш ући у кућу!' ``` 18: story_text: | - We are going to print another story, but now we have to use brackets with `{print}`. + Направићемо још једну причу, али сада морамо користити заграде са `{print}`. - ### Exercise 1 - Create a story of at least 5 sentences. You don't have to use 'name' just yet. + ### Вежба 1 + Направите причу од најмање 5 реченица. Још увек не морате користити 'име'. example_code: | ``` - {print}('Welcome to this story!') + {print}('Добродошли у ову причу!') ``` story_text_2: | - ### Exercise 2 - We have already prepared an `{input}` for you. First, use the `name` variable in your story. - Then add a second `{ask}` and use that variable as well. - Tip: Remember the commas in a `{print}` between text and variables! + ### Вежба 2 + Већ смо припремили `{input}` за вас. Прво, користите променљиву `name` у вашој причи. + Затим додајте други `{ask}` и користите ту променљиву такође. + Савет: Запамтите зарезе у `{print}` између текста и променљивих! example_code_2: | ``` - naam = {input}("What's your name?") - {print}('Welcome to this story!') + naam = {input}("Како се зовете?") + {print}('Добродошли у ову причу!') ``` add_remove_command: - name: '{add} {to} & {remove} {from}' + name: '{add} {to_list} & {remove} {from}' default_save_name: add_remove_command - description: introducing add to and remove from + description: увођење {add} {to_list} и {remove} {from} levels: 3: story_text: | - ## Add to - You can add items to the list with the `{add} {to_list}` command. To add an item to a list you can simply type: `{add} penguin {to} animals` or you can use the `{ask}` command like in the example code. + ## Додај у + Можете додати ставке на листу са командом `{add} {to_list}`. Да бисте додали ставку на листу, можете једноставно откуцати: `{add} penguin {to_list} animals` или можете користити команду `{ask}` као у пример коду. example_code: | ``` - animals {is} dog, cat, kangaroo - like {is} {ask} What is your favorite animal? - {add} like {to_list} animals - {print} I choose animals {at} {random} + животиње {is} пас, мачка, кенгур + свиђање {is} {ask} Која је твоја омиљена животиња? + {add} свиђање {to_list} животиње + {print} Бирам животиње {at} {random} ``` story_text_2: | - ## Remove from - If you can add items to a list, of course you can also take them off. This is done with the `{remove} {from}` command. + ## Уклони из + Ако можете додати ставке на листу, наравно да их можете и уклонити. Ово се ради са командом `{remove} {from}`. example_code_2: | ``` - animals {is} dog, cat, kangaroo - dislike {is} {ask} What animal do you not like? - {remove} dislike {from} animals - {print} I choose animals {at} {random} + животиње {is} пас, мачка, кенгур + несвиђање {is} {ask} Која животиња ти се не свиђа? + {remove} несвиђање {from} животиње + {print} Бирам животиње {at} {random} ``` story_text_3: | - ### Exercise - Try out the new commands in this virtual restaurant. Add the flavor the player is hpoing for to the list and remove the flavors they are allergic to. + ### Вежба + Испробајте нове команде у овом виртуелном ресторану. Додајте укус који играч жели на листу и уклоните укусе на које је алергичан. example_code_3: | ``` - {print} Mystery milkshake - flavors {is} strawberry, chocolate, vanilla - hope {is} {ask} What flavor are you hoping for? + {print} Мистериозни милкшејк + укуси {is} јагода, чоколада, ванила + нада {is} {ask} Који укус желите? _ - allergies {is} {ask} Are you allergic to any flavors? + алергије {is} {ask} Да ли сте алергични на неке укусе? _ - {print} You get a flavors {at} {random} milkshake + {print} Добијате милкшејк са укусом {at} {random} ``` and_or_command: - name: '{and} & {or}' - default_save_name: and or - description: introducing and or + name: '{and} и {or}' + default_save_name: и или + description: увод у {and} и {or} levels: 13: story_text: |- - We are now going to learn `{and}` and `{or}`! If you want to check two statements, you don't have to use two `{if}`s but can use `{and}` and `{or}`. + Сада ћемо научити `{and}` и `{or}`! Ако желиш да провериш две изјаве, не мораш користити два `{if}` већ можеш користити `{and}` и `{or}`. - If you use `{and}`, both statements, left and right of the `{and}` need to be true. We can also use `{or}`. Then only one statement needs to be correct. + Ако користиш `{and}`, обе изјаве, лева и десна од `{and}` морају бити тачне. Такође можемо користити `{or}`. Тада само једна изјава мора бити тачна. example_code: | ``` - name = {ask} 'what is your name?' - age = {ask} 'what is your age?' + name = {ask} 'како се зовеш?' + age = {ask} 'колико имаш година?' {if} name {is} 'Hedy' {and} age {is} 2 - {print} 'You are the real Hedy!' + {print} 'Ти си права Hedy!' ``` ask_command: name: '{ask}' default_save_name: ask_command - description: Introduction ask command + description: Увод у команду {ask} levels: 1: story_text: | - ## The ask command - Now that you can use the `{print}` command, you are ready to learn the next command: `{ask}`. With the `{ask}` command, you can ask a question. Check it out: + ## Команда ask + Сада када можете да користите команду `{print}`, спремни сте да научите следећу команду: `{ask}`. Са командом `{ask}`, можете поставити питање. Погледајте: example_code: | ``` - {print} Hello! - {ask} What is your name? + {print} Здраво! + {ask} Како се зовеш? ``` story_text_2: | - ## The echo command - If you want the computer to repeat the answer, you can use the `{echo}` command. The answer will then be echoed back at the end of the sentence, so in this example after hello. + ## Команда `{echo}` + Ако желите да рачунар понови одговор назад, можете користити команду `{echo}`. Одговор ће бити поновљен на крају реченице, тако да у овом примеру након здраво. example_code_2: | ``` - {print} Hello! - {ask} What is your name? - {echo} hello + {print} Здраво! + {ask} Како се зовеш? + {echo} здраво ``` story_text_3: | - ### Exercise - Try out the `{ask}` and `{echo}` commands. Firstly, fill in the blanks to make this program work. - Then ask 2 more questions using the `{ask}` command, after each `{ask}` use an `{echo}` to print the answer on the screen. + ### Вежба + Испробајте команде `{ask}` и `{echo}`. Прво, попуните празнине да би овај програм радио. + Затим поставите још 2 питања користећи команду `{ask}`, након сваке `{ask}` користите `{echo}` да прикажете одговор на екрану. example_code_3: | ``` - _ How are you doing? + _ Како си? _ ``` 2: story_text: | - ## The ask command - Now that we can use **variables** in our codes, we no longer need the `{echo}` command. - We can use variables to store the answers to our questions and this way we can use the answer to multiple questions in our codes. - Check it out: + ## Команда ask + Сада када можемо да користимо **променљиве** у нашим кодовима, више нам није потребна команда `{echo}`. + Можемо користити променљиве да сачувамо одговоре на наша питања и на тај начин можемо користити одговор на више питања у нашим кодовима. + Погледајте: - This way your code is becoming interactive! + На овај начин ваш код постаје интерактиван! example_code: | ``` - name {is} {ask} What is your name? - {print} Hello name - age {is} {ask} How old are you? - {print} name is age years old. + име {is} {ask} Како се зовеш? + {print} Здраво име + године {is} {ask} Колико имаш година? + {print} име има године година. ``` story_text_2: | - ### Exercise - In the previous tab you have practised with setting variables with the `{is}` command. - You have created at least 3 variables and used them with a print command. - Now, instead of setting the variables we want you to make the variables interactive, like we did in our example. + ### Вежба + У претходној картици сте вежбали са постављањем променљивих са командом `{is}`. + Направили сте најмање 3 променљиве и користили их са командом за приказивање. + Сада, уместо да постављате променљиве, желимо да променљиве учините интерактивним, као што смо урадили у нашем примеру. - Copy your code from the previous tab and make the variables interactive by using `{ask}` commands. + Копирајте свој код са претходне картице и учините променљиве интерактивним користећи команде `{ask}`. example_code_2: | ``` - favorite_animal {is} {ask} What is your favorite animal? - {print} I like favorite_animal + омиљена_животиња {is} {ask} Која је твоја омиљена животиња? + {print} Волим омиљена_животиња ``` 18: - story_text: The final change we will need to make to get Python code is changing `{ask}` into `{input}`. + story_text: Последња промена коју ћемо морати да направимо да бисмо добили Python код је промена `{ask}` у `{input}`. example_code: | ``` - {print}('My name is Hedy!') - name = {input}('What is your name?') - {print}('So your name is ', name) + {print}('Моје име је Хеди!') + name = {input}('Како се зовеш?') + {print}('Дакле, твоје име је ', name) ``` blackjack: - name: Blackjack - default_save_name: Blackjack - description: Try to get as close to 21 as you can + name: Блекџек + default_save_name: Блекџек + description: Покушајте да се приближите 21 колико год можете levels: 17: story_text: | - Blackjack is a simple game of cards in which you have to get as close to 21 points as possible. You get two cards. Each card is worth their numeral value, and the face cards (Jack, Queen and King) are worth 10 points. - The Ace is worth either 1 or 11 points (you can choose). The dealer, your opponent, also gets two cards. - If you want, you can get another card, and its points will be added to your total. The dealer can also choose to take another card. - But be careful not to get more than 21 points, because if you do, you lose! - The player who gets closest to 21, without going over it, wins! + Блекџек је једноставна игра са картама у којој морате да се приближите 21 поену колико год можете. Добијате две карте. Свака карта вреди своју нумеричку вредност, а сликовне карте (Жандар, Дама и Краљ) вреде 10 поена. + Ас вреди или 1 или 11 поена (можете изабрати). Дилер, ваш противник, такође добија две карте. + Ако желите, можете добити још једну карту, и њени поени ће бити додати вашем укупном броју. Дилер такође може изабрати да узме још једну карту. + Али пазите да не добијете више од 21 поена, јер ако то урадите, губите! + Играч који се највише приближи 21, а да не пређе ту вредност, побеђује! - ### Exercise - In this adventure we code the first part of our Blackjack game. We'll create a function to calculate how many points a card is worth. + ### Вежба + У овој авантури кодираћемо први део наше игре Блекџек. Направићемо функцију за израчунавање колико поена вреди карта. - ***Set the variables*** - Start by making a list of all the cards, from 2 to Ace. Next make a list of the face cards, so Jack, Queen and King. Then pick a random card from the list of cards to be card_1. + ***Поставите променљиве*** + Почните тако што ћете направити листу свих карата, од 2 до Аса. Затим направите листу сликовних карата, дакле Жандар, Дама и Краљ. Затим изаберите насумичну карту са листе карата да буде card_1. - ***Create a function to calculate the points*** - Create a function that calculates how many points a card is worth. - All the face cards are worth 10 points, the Ace is worth 11 and all the other cards are worth their numeral. - Return the variable `points` at the end of the function. + ***Направите функцију за израчунавање поена*** + Направите функцију која израчунава колико поена вреди карта. + Све сликовне карте вреде 10 поена, Ас вреди 11, а све остале карте вреде своју нумеричку вредност. + Вратите променљиву `points` на крају функције. - ***Test the function*** - Test if your function is working properly. Finish the first print command by filling in which card you've drawn. Then finish the second line by calling the function with card_1. - Run the code a couple of times. Are you happy with the results? Great! Then you can remove the testing part and move on the the next tab! + ***Тестирајте функцију*** + Тестирајте да ли ваша функција ради исправно. Завршите прву команду за приказивање попуњавањем која карта вам је додељена. Затим завршите другу линију позивањем функције са card_1. + Покрените код неколико пута. Да ли сте задовољни резултатима? Одлично! Онда можете уклонити део за тестирање и прећи на следећу картицу! example_code: | ``` - {print} 'BLACKJACK' + {print} 'БЛЕКЏЕК' - # Set these variables - cards = _ - face_cards = _ - card_1 = + # Поставите ове променљиве + карте = _ + сликовне_карте = _ + карта_1 = - # Create a function to calculate the points - {define} calculate_points {with} card: - {if} card {in} face_cards: - points = _ + # Направите функцију за израчунавање поена + {define} израчунај_поене {with} карта: + {if} карта {in} сликовне_карте: + поени = _ {elif} _ _ {else}: _ - _ points + _ поени - # Test your function - {print} 'Your card is a ' _ - {print} 'That is worth ' _ ' points'. + # Тестирајте своју функцију + {print} 'Ваша карта је ' _ + {print} 'То вреди ' _ ' поена'. ``` blackjack_2: - name: Blackjack 2 - default_save_name: Blackjack_2 - description: Blackjack part 2 + name: Блекџек 2 + default_save_name: Блекџек_2 + description: Блекџек део 2 levels: 17: story_text: | - ### Exercise - In this adventure we code the second part of our Blackjack game. + ### Вежба + У овој авантури кодираћемо други део наше игре Блекџек. - ***Paste your code from the previous adventure*** - In the previous adventure you've started a list of variables and created a function to calculate how many points a card is worth. Copy your code and paste it here. Mind that you don't need the testing part, so if you haven't removed that yet, please do so now. + ***Налепи свој код из претходне авантуре*** + У претходној авантури започео си листу променљивих и направио функцију за израчунавање колико поена вреди карта. Копирај свој код и налепи га овде. Имај на уму да ти део за тестирање није потребан, па ако га још ниси уклонио, уради то сада. - ***Add more variables*** - You have already set the lists `cards` and `face_cards` and the variable `card_1`. Underneath those variables create 3 more variables: `card_2`, dealer_card_1` and `dealer_card_2`. These variables are all set to a random card from the list of cards. + ***Додај више променљивих*** + Већ си поставио листе `cards` и `face_cards` и променљиву `card_1`. Испод тих променљивих направи још 3 променљиве: `card_2`, `dealer_card_1` и `dealer_card_2`. Ове променљиве су све постављене на случајну карту са листе карата. - ***Add up points*** - To calculate how many points you have scored we call the function with card 1 and we do it again for card 2. Then we add both these scores together to get your total. - Do the same thing for the dealers points, but be sure to use the dealer's cards and not your own! + ***Сабери поене*** + Да бисмо израчунали колико си поена освојио, позваћемо функцију са картом 1 и урадићемо то поново за карту 2. Затим ћемо сабрати оба ова резултата да добијемо твој укупни резултат. + Уради исто за дилерове поене, али обавезно користи дилерове карте, а не своје! - ***2 Aces*** - You're doing great! Almost all scores can be calculated now. There is only one exception: 2 Aces. If you get 2 Aces, your total is 12 points and not 22 (because 22 points would be losing!). This of course also goes for the dealer. + ***2 аса*** + Одлично ти иде! Сада се могу израчунати скоро сви резултати. Постоји само један изузетак: 2 аса. Ако добијеш 2 аса, твој укупни резултат је 12 поена, а не 22 (јер би 22 поена значило губитак!). Ово наравно важи и за дилера. - ***Show the score*** - Lastly, you want to tell the program to tell you which cards you have drawn and how many points that is. Then show which cards the dealer has and how many points they have. + ***Прикажи резултат*** + На крају, желиш да кажеш програму да ти каже које карте си извукао и колико поена то износи. Затим прикажи које карте је дилер извукао и колико поена има. - ***Continue in the next tab*** - Great! You have finished this part of the game! Copy your code and go to the next tab to learn how to ask for an extra card and to declare a winner. + ***Настави у следећем табу*** + Одлично! Завршио си овај део игре! Копирај свој код и иди на следећи таб да научиш како да тражиш додатну карту и да прогласиш победника. example_code: | ``` - # Paste your code from the previous adventure here + # Налепи свој код из претходне авантуре овде - # Add these variables to the list of variables + # Додај ове променљиве на листу променљивих card_2 = _ dealer_card_1 = _ dealer_card_2 = _ - # Add up your points + # Сабери своје поене your_points_1 = {call} _ {with} card_1 your_points_2 = _ your_total = _ - # Add up the dealers points + # Сабери дилерове поене dealer_points_1 = _ _ _ - # 2 Aces + # 2 аса {if} card_1 == 'Ace' {and} _ your_total = 12 {if} dealer_card_1 _ dealer_total = _ - # Show the score - {print} 'You have drawn a ' _ ' and a ' _ '. That is ' _ ' points' - {print} 'The dealer has drawn a ' _ ' and a ' _ '. That is ' _ ' points' + # Прикажи резултат + {print} 'Извукао си ' _ ' и ' _ '. То је ' _ ' поена' + {print} 'Дилер је извукао ' _ ' и ' _ '. То је ' _ ' поена' ``` blackjack_3: - name: Blackjack 3 - default_save_name: Blackjack_3 - description: Blackjack part 3 + name: Блекџек 3 + default_save_name: Блекџек_3 + description: Блекџек део 3 levels: 17: story_text: | - In the previous tabs you have learned how to draw 2 random cards for yourself and for the dealer and to calculate how many points you both got. - In this adventure we add the option to ask for an extra card for both you and the dealer. + У претходним табовима си научио како да извучеш 2 случајне карте за себе и за дилера и да израчунаш колико поена сте обоје добили. + У овој авантури додајемо опцију да тражиш додатну карту и за себе и за дилера. - ### Exercise - ***Paste your code from the previous adventure*** Firstly, copy your code from the previous tab and paste it here. + ### Вежба + ***Налепи свој код из претходне авантуре*** Прво, копирај свој код из претходног таба и налепи га овде. - ***Extra card for you*** If you want, you can get an extra card to get your total as close to 21 as possible. First ask the player if they want an extra card. - If they do, pick a random card and print what they have drawn. If the card is not an Ace, you can call the function and add the points to your total. - In case the card is an Ace, you can't use the function, because the Ace can be either 1 point or 11 points, depending on how many points you already have earned. - If your total is less than 11, you want the ace to be 11 points (because this is closest to 21). So you add 11 points to your total. - If the total is more than or equal to 11, you want the ace to be 1 point (because you don't want more than 21 points). So you add 1 point to your total. - Lastly, print your new total of points. + ***Додатна карта за тебе*** Ако желиш, можеш добити додатну карту да би твој укупни резултат био што ближи 21. Прво питај играча да ли жели додатну карту. + Ако жели, изабери случајну карту и испиши шта је извукао. Ако карта није ас, можеш позвати функцију и додати поене свом укупном резултату. + У случају да је карта ас, не можеш користити функцију, јер ас може бити или 1 поен или 11 поена, у зависности од тога колико си поена већ освојио. + Ако је твој укупни резултат мањи од 11, желиш да ас буде 11 поена (јер је то најближе 21). Дакле, додаш 11 поена свом укупном резултату. + Ако је укупни резултат већи или једнак 11, желиш да ас буде 1 поен (јер не желиш више од 21 поена). Дакле, додаш 1 поен свом укупном резултату. + На крају, испиши свој нови укупни резултат поена. - ***Extra card for the dealer*** The dealer can also get an extra card. The dealer doesn't need to be asked, because they always get an extra card if their total is less than 17. - Copy the 'Extra card for you code' and paste it in the dealers section. Then change it to fit the dealer picking an extra card and getting points added to their total. + ***Додатна карта за дилера*** Дилер такође може добити додатну карту. Дилера не треба питати, јер увек добија додатну карту ако је његов укупни резултат мањи од 17. + Копирај код за 'Додатну карту за тебе' и налепи га у део за дилера. Затим га промени да одговара дилеру који бира додатну карту и добија поене додате свом укупном резултату. example_code: | ``` - # Paste your code from the previous adventure here + # Налепи свој код из претходне авантуре овде - # Extra card for you + # Додатна карта за тебе hit = {ask} _ {if} hit == 'yes': card_3 = _ @@ -517,40 +520,40 @@ adventures: _ {print} _ - # Extra card for the dealer + # Додатна карта за дилера {if} dealer_total < 17 _ ``` blackjack_4: - name: Blackjack 4 - default_save_name: Blackjack_4 - description: Blackjack part 4 + name: Блекџек 4 + default_save_name: Блекџек_4 + description: Блекџек део 4 levels: 17: story_text: | - In the last 3 adventures you have alsmost created a working blackjack game! The only thing left to do is to decide a winner! + У последње 3 авантуре скоро си направио функционалну игру блекџек! Једино што је остало је да одлучиш ко је победник! - ### Exercise - ***Paste your code from the previous adventure*** Start by pasting the code that you've made so far into your programming field. + ### Вежба + ***Налепи свој код из претходне авантуре*** Почни тако што ћеш налепити код који си до сада направио у своје програмско поље. - ***Decide a winner*** - Firstly, if you and the dealer have an equal amount of points, it's a draw. - Secondly, if the dealer has more than 21 points and you don't, you are the winner. - Thirdly, if both you and the dealer have less than 22 points, we have to see who came closest to 21. We do that by comparing who has the highest score. Is your total higher than the dealer's total, then you are the winner. If not, the dealer wins. - Lastly, in all other scenarios (e.g. you have more than 21 points and the dealer doesn't, or you both have more than 21 points) you are the loser. + ***Одлучи ко је победник*** + Прво, ако ти и дилер имате једнак број поена, то је нерешено. + Друго, ако дилер има више од 21 поена, а ти немаш, ти си победник. + Треће, ако и ти и дилер имате мање од 22 поена, морамо видети ко је ближи 21. То радимо тако што упоређујемо ко има највиши резултат. Ако је твој укупни резултат већи од дилеровог укупног резултата, онда си ти победник. Ако није, дилер побеђује. + На крају, у свим другим сценаријима (нпр. ти имаш више од 21 поена, а дилер нема, или обоје имате више од 21 поена) ти си губитник. - ***Enjoy the game!*** - Does your game work properly? Amazing! You have done a great job! Enjoy your game! - If it doesn't work right away, no worries, you might have made a mistake. Just keep calm and bebug your code using the ladybug button. + ***Уживај у игри!*** + Да ли твоја игра ради исправно? Невероватно! Одлично си урадио! Уживај у својој игри! + Ако не ради одмах, нема проблема, можда си направио грешку. Само остани смирен и отклони грешке у свом коду користећи дугме са бубамаром. example_code: | ``` - # Paste your code from the previous adventure here + # Налепи свој код из претходне авантуре овде - # Decide a winner + # Одлучи ко је победник {if} _ - {print} 'Its a draw! Play again!' + {print} 'Нерешено! Играј поново!' {elif} _ - {print} 'You win!' + {print} 'Ти побеђујеш!' {elif} _ : {if} _: {print} _ @@ -560,50 +563,52 @@ adventures: _ ``` calculator: - name: Calculator - default_save_name: Calculator - description: Create a calculator + name: Калкулатор + default_save_name: Калкулатор + description: Направите калкулатор levels: 6: story_text: | - Now that you can do maths, you can make a calculator yourself! + Сада када знате математику, можете сами направити калкулатор! example_code: | ``` - number_1 {is} {ask} 'Fill in the first number:' - number_2 {is} {ask} 'Fill in the second number:' + number_1 = {ask} 'Унесите први број:' + number_2 = {ask} 'Унесите други број:' correct_answer = number_1 * number_2 - {print} number_1 ' times ' number_2 ' is ' correct_answer + {print} number_1 ' пута ' number_2 ' је ' correct_answer ``` story_text_2: | - ### Exercise - The calculator above will calculate the answer for you, but you can also make a program to test your own maths skills, like this: - Fill in the blanks to make it complete! + ### Вежба + Горњи калкулатор ће израчунати одговор за вас, али можете направити и програм да тестирате своје математичке вештине, овако: + Попуните празнине да бисте га комплетирали! example_code_2: | ``` correct_answer = 11 * 27 - answer = {ask} 'How much is 11 times 27?' - {if} answer {is} _ {print} 'good job!' - {else} {print} 'Wrong! It was ' _ + answer = {ask} 'Колико је 11 пута 27?' + {if} answer {is} _ {print} 'браво!' + {else} {print} 'Погрешно! Тачан одговор је ' _ ``` story_text_3: | - You can also let the computer do random calculations on its own using {random}. - example_code_3: | + **Додатно** Такође можете дозволити рачунару да самостално ради насумичне производе користећи `{random}`. + example_code_3: |- + ``` numbers = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 number_1 = _ number_2 = _ correct_answer = number_1 * number_2 - given_answer = 'What is ' number_1 ' times ' number_2 '?' + given_answer = {ask} 'Колико је ' number_1 ' пута ' number_2 '?' {if} _ {else} _ + ``` 9: story_text: | - In a previous level you've created a calculator, in this level you can expand that code so it asks multiple questions. + На претходном нивоу сте направили калкулатор. На овом нивоу можете проширити тај код тако да поставља више питања. - ### Exercise 1 - Can you finish line 10 to get the code to work? + ### Вежба 1 + Можете ли завршити линију 10 да би код радио? - ### Exercise 2 - Give the player feedback when the enter an answer, like `{print} 'Correct!'` or `{print} 'Wrong! The correct answer is ' correct_answer`. + ### Вежба 2 + Дајте играчу повратне информације када унесе одговор, као што је `{print} 'Correct!'` или `{print} 'Wrong! The correct answer is ' correct_answer`. example_code: | ``` score = 0 @@ -612,28 +617,28 @@ adventures: number_1 = numbers {at} {random} number_2 = numbers {at} {random} correct_answer = number_1 * number_2 - {print} 'What is ' number_1 ' times ' number_2 '?' - answer = {ask} 'Type your answer here...' - {print} 'Your answer is ' answer + {print} 'Колико је ' number_1 ' пута ' number_2 '?' + answer = {ask} 'Унесите свој одговор овде...' + {print} 'Ваш одговор је ' answer {if} _ {is} _ score = score + 1 - {print} 'Great job! Your score is... ' score ' out of 10!' + {print} 'Браво! Ваш резултат је... ' score ' од 10!' ``` 10: story_text: | - This calculator game helps you practise your tables of multiplication! - ### Exercise - Fill in the blanks. We want this program to ask the player these questions: - ``` - How much is 1 times 1? - How much is 1 times 2? - How much is 1 times 3? - How much is 2 times 1? - How much is 2 times 2? - How much is 2 times 3? - How much is 3 times 1? - How much is 3 times 2? - How much is 3 times 3? + Ова игра калкулатора вам помаже да вежбате таблице множења! + ### Вежба + Попуните празнине. Желимо да овај програм поставља играчу ова питања: + ``` + Колико је 1 пута 1? + Колико је 1 пута 2? + Колико је 1 пута 3? + Колико је 2 пута 1? + Колико је 2 пута 2? + Колико је 2 пута 3? + Колико је 3 пута 1? + Колико је 3 пута 2? + Колико је 3 пута 3? _ ``` example_code: | @@ -644,63 +649,71 @@ adventures: answer = {ask} _ correct = number_1 * number_2 {if} answer {is} correct - {print} 'Great job!' + {print} 'Браво!' {else} - {print} 'That is wrong. The right answer is ' correct + {print} 'Погрешно. Тачан одговор је ' correct ``` 11: story_text: | - With a `{for}` you can simplify tables of multiplication practise program. + Са `{for}` можете поједноставити програм за вежбање таблица множења. - ### Exercise 1 - Improve the example code such that it prints a nice multiplication table:
"1 times 10 is 10", "2 times 10 is 20", etc. + ### Вежба 1 + Побољшајте пример кода тако да исписује лепу таблицу множења:
"1 пута 10 је 10", "2 пута 10 је 20", итд. - ### Exercise 2 - Go back to your level 10 multiplication code, and modify it so that it uses a `{for}` and `{range}`. + ### Вежба 2 + Вратите се на свој код за множење на нивоу 10 и измените га тако да користи `{for}` и `{range}`. example_code: | ``` number = 10 - {for} i {in} {range} 1 to 10 + {for} i {in} {range} 1 {to} 10 {print} i * number ``` 12: story_text: | - Now you can make a calculator that works for decimal numbers. Fill in the blanks to get it to work properly! + На овом нивоу, можете направити калкулатор који ради са децималним бројевима. + + ### Вежба 1 + Попуните празнине да бисте завршили калкулатор. Запамтите да користите тачку, а не зарез за децималне бројеве. + + ### Вежба 2 + Направите нови програм за вежбање математике, али сада користите децималне бројеве. + Направите листу бројева, изаберите два за множење и пустите играча да одговори. + И наравно, морате проверити одговор! **Додатно** Повећајте тежину додавањем живота: Играчу се одузима живот за погрешан одговор, а након три погрешна одговора игра се завршава. example_code: | ``` - number1 = {ask} 'What is the first number?' - number2 = {ask} 'What is the second number?' + number1 = {ask} 'Који је први број?' + number2 = {ask} 'Који је други број?' answer = _ - {print} number1 ' plus ' number2 ' is ' answer + {print} number1 ' плус ' number2 ' је ' _ ``` 13: story_text: | - ### Exercise 1 - Let's make the practice program a bit harder. The player now has to answers two questions correctly. Fill out the blanks to complete the program. + ### Вежба 1 + Хајде да учинимо програм за вежбање мало тежим. Играч сада мора да одговори тачно на два питања. Попуните празнине да бисте довршили програм. - ### Exercise 2 - Sometimes, calculations have multiple correct answers. For example, 10 can be divided by 5 and by 2. So the question 'What number divides 10?' can be answered by 2 and by 5. - Ask for a calculation that has multiple correct answers, ask the player to answer it, and determine if it is correct using `{or}`. - Empty the programming field and create your own solution. + ### Вежба 2 + Понекад, прорачуни имају више тачних одговора. На пример, 10 може бити подељено са 5 и са 2. Дакле, на питање 'Који број дели 10?' може се одговорити са 2 и са 5. + Поставите прорачун који има више тачних одговора, замолите играча да одговори на њега и одредите да ли је тачан користећи `{or}`. + Испразните поље за програмирање и направите своје решење. example_code: | ``` - answer1 = {ask} 'What is 10 times 7?' - answer2 = {ask} 'What is 6 times 7?' + одговор1 = {ask} 'Колико је 10 пута 7?' + одговор2 = {ask} 'Колико је 6 пута 7?' {if} _ _ _ _ _ _ _ {print} _ ``` 14: story_text: | - In this adventure you will build a calculator that calculates your mean grade for you. If you get your calculator to work, you can move on to the next adventure, which allows you to add two extra features. + У овој авантури ћете направити калкулатор који израчунава вашу просечну оцену. Ако ваш калкулатор ради, можете прећи на следећу авантуру, која вам омогућава да додате две додатне функције. - ### Exercise 1 - Fill in the blanks to get the calculator to work. - * Start with the fourth line, add a question to figure out what grade the student got. - * In the fifth line you'll want to calculate the total of all grades, so the total = total + grade. - * Then we get to set the return value. We want to return the mean, so the total devided by the amount of tests (4). - * Lastly we finish the code by calling the function in line 8. + ### Вежба 1 + Попуните празнине да би калкулатор радио. + * Почните са четвртим редом, додајте питање да бисте сазнали коју оцену је ученик добио. + * У петом реду ћете желети да израчунате укупан број свих оцена, тако да total = total + grade. + * Затим постављамо повратну вредност. Желимо да вратимо просек, тако да је total подељен са бројем тестова (4). + * На крају завршавамо код позивањем функције у реду 8. - Did you get it? Awesome! Would you like to add even more to your calculator? **This adventure continues in the next tab!** + Јесте ли успели? Сјајно! Да ли бисте желели да додате још више свом калкулатору? **Ова авантура се наставља у следећој картици!** example_code: | ``` {define} calculate_mean_grade @@ -708,25 +721,19 @@ adventures: {for} i {in} {range} 1 {to} 4 grade = {ask} _ total = total + _ - return _ / 4 + {return} _ / 4 mean_grade = {call} _ - {print} 'Your mean grade is ' mean_grade + {print} 'Ваша просечна оцена је ' mean_grade ``` - - total = total + _ - return _ / 4 - - mean_grade = {call} _ - {print} 'Your mean grade is ' mean_grade 15: story_text: | - You can add the `{while}` loop to the calculator game you've learned to make in a previous level. - This makes sure the player can't continue to the next question if they answer incorrectly. + Можете додати `{while}` петљу у игру калкулатора коју сте научили да правите на претходном нивоу. + Ово осигурава да играч не може прећи на следеће питање ако одговори нетачно. - ### Exercise - Add the `{while}` loop in the function, ask the player what number_1 times number_2 is and print their answer. - Then `{call}` the function. + ### Вежба + Додајте `{while}` петљу у функцију, питајте играча колико је number_1 пута number_2 и испишите њихов одговор. + Затим `{call}` функцију. example_code: | ``` {define} new_question @@ -738,46 +745,46 @@ adventures: _ _ _ - {print} 'Well done!' + {print} 'Браво!' - {print} 'Give 10 correct answers to win!' + {print} 'Дајте 10 тачних одговора да победите!' {for} i {in} {range} 1 {to} 10 _ - {print} 'You win!' + {print} 'Победили сте!' ``` calculator_2: - name: Calculator 2 - default_save_name: Calculator 2 - description: Calculator 2 + name: Калкулатор 2 + default_save_name: Калкулатор 2 + description: Калкулатор 2 levels: 14: story_text: | - ### Exercise 2 - **This is the second part of this adventure.** The adventure starts in the previous tab. - Of course, you don't always want to calculate the mean of 4 tests. You might want to calculate the mean of 10 tests or only 2... - We can fix this problem by adding the argument and variable 'amount_of_tests'. - * Start a new line on line 3. Set the amount_of_tests argument by asking the student how many tests they have made. - * Change the 4 in line 4 to the new argument amount_of_tests. - * Lastly, change the 4 in line 6 to amount_of_tests + ### Вежба 2 + **Ово је други део ове авантуре.** Авантурa почиње у претходној картици. + Наравно, не желите увек да израчунавате просек од 4 теста. Можда желите да израчунавате просек од 10 тестова или само 2... + Можемо решити овај проблем додавањем аргумента и променљиве 'amount_of_tests'. + * Почните нову линију на линији 3. Поставите аргумент amount_of_tests питајући ученика колико тестова су урадили. + * Промените 4 у линији 4 на нови аргумент amount_of_tests. + * На крају, промените 4 у линији 6 на amount_of_tests - Try out your new program. Does it work? + Испробајте свој нови програм. Да ли ради? - ### Exercise 3 - Did you want to make your program even better? Great! In the previous program you could only calculate the mean grade of 1 subject, but it would be better if you could calculate the mean grade for all subjects you want! - We won't tell you how to do it, but we will give you one tip: Start your code in line 1 with: define calculate_mean_grade with subject. + ### Вежба 3 + Да ли желите да ваш програм буде још бољи? Одлично! У претходном програму могли сте да израчунавате просечну оцену само за један предмет, али било би боље када бисте могли да израчунавате просечну оцену за све предмете које желите! + Нећемо вам рећи како да то урадите, али ћемо вам дати један савет: Почните свој код у линији 1 са: define calculate_mean_grade with subject. example_code: | ``` - # Use your own code from the previous adventure. + # Користи свој код из претходне авантуре. ``` clear_command: name: '{clear}' - default_save_name: clear_command - description: clear command + default_save_name: команда_очисти + description: '{clear} команда' levels: 4: story_text: | - Time for a new command! With `{clear}` you can clear all the text form your output screen. This way you can prevent your screen getting too full of text. - Beware! If you are using a `{clear}` command, you might need to use a `{sleep}` above it. Otherwise Hedy will clear your screen without giving you the time to read as you can see in the example! + Време је за нову команду! Са `{clear}` можеш очистити сав текст са свог излазног екрана. На овај начин можеш спречити да ти екран постане превише пун текста. + Пази! Ако користиш команду `{clear}`, можда ће ти требати да користиш `{sleep}` изнад ње. У супротном, Hedy ће очистити твој екран без да ти да времена да прочиташ, као што можеш видети у примеру! example_code: | ``` {print} '3' @@ -786,769 +793,780 @@ adventures: {clear} {print} '1' {clear} - {print} 'wait for it...' + {print} 'чекај...' {sleep} 3 {clear} - {print} 'SURPRISE!' + {print} 'ИЗНЕНАЂЕЊЕ!' ``` debugging: - name: debugging - default_save_name: debugging - description: debugging adventure + name: отклањање грешака + default_save_name: отклањање грешака + description: авантура отклањања грешака levels: 1: story_text: |- - Welcome to a debugging adventure. Debugging a code means getting rid of mistakes in the code. - That means that in these debugging adventures, we will show you code that does not work yet. - You will have to figure out what's wrong and correct the mistakes. + Добродошли у авантуру отклањања грешака. Отклањање грешака у коду значи уклањање грешака у коду. + То значи да ћемо вам у овим авантурама отклањања грешака показати код који још увек не ради. + Мораћете да схватите шта није у реду и исправите грешке. - ### Exercise - Debug this code. Good luck! + ### Вежба + Отклоните грешке у овом коду. Срећно! example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба отклонити грешке!** ``` - {print} I love programming - Do you love programming too? + {print} Волим програмирање + Да ли и ти волиш програмирање? {echo} - {print} What are your hobbies? - {echo} Your hobbies are + {print} Који су твоји хобији? + {echo} Твоји хобији су ``` 2: story_text: |- - Welcome to a debugging adventure. Debugging a code means getting rid of mistakes in the code. - That means that in these debugging adventures, we will give you a code that does not work yet. - You will have to figure out what's wrong and correct the mistakes. + Добродошли у авантуру отклањања грешака. Отклањање грешака у коду значи уклањање грешака у коду. + То значи да ћемо вам у овим авантурама отклањања грешака дати код који још увек не ради. + Мораћете да схватите шта није у реду и исправите грешке. - ### Exercise - Debug this code. Good luck! + ### Вежба + Отклоните грешке у овом коду. Срећно! example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба отклонити грешке!** ``` - destination {ask} Where are you going on holidays? - {print} The flight to dstination leaves at 3 pm. - {ask} Did you check in your luggage yet? + destination {ask} Где идеш на одмор? + {print} Лет за dstination полази у 15 часова. + {ask} Да ли си већ чекирао свој пртљаг? {echo} - {print} Let me print your boarding pass for you. + {print} Дозволи ми да ти одштампам карту за укрцавање. {sleep} - Here you go! Have a nice trip! + Изволи! Срећан пут! ``` 3: story_text: |- - Welcome to a debugging adventure. Debugging a code means getting rid of mistakes in the code. - That means that in these debugging adventures, we will give you a code that does not work yet. - You will have to figure out what's wrong and correct the mistakes. + Добродошли у авантуру отклањања грешака. Отклањање грешака у коду значи уклањање грешака у коду. + То значи да ћемо вам у овим авантурама отклањања грешака дати код који још увек не ради. + Мораћете да схватите шта није у реду и исправите грешке. - ### Exercise - Debug this code. Good luck! + ### Вежба + Отклоните грешке у овом коду. Срећно! example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба отклонити грешке!** ``` - movie_choices {is} dracula, fast and furious, home alone, barbie + movie_choices {is} дракула, брзи и жестоки, сам у кући, барби chosen_movie {is} movies {at} {random} - {print} Tonight we will watch chosen _movies - like {ask} Do you like that movie? - {print} Tomorrow we will watch something else. - {add} chosen_movie {to} movie_choices - {print} Tomorrow we will watch tomorrows_movie + {print} Вечерас ћемо гледати chosen _movies + like {ask} Да ли ти се свиђа тај филм? + {print} Сутра ћемо гледати нешто друго. + {add} chosen_movie {to_list} movie_choices + {print} Сутра ћемо гледати tomorrows_movie tomorrows_movie {is} movie_choices {at} {random} - I'll go get the popcorn! {print} + Идем по кокице! {print} ``` 4: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Вежба + Отклоните грешке у овом коду. Срећно! example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба отклонити грешке!** ``` - {print} 'Welcome to the online library! - {ask} What genre of books do you like? - {print} You like genre - author {is} {ask} 'Who's your favorite author?' - {print} 'author is your favorite author' - {print} Hmmm... i think you should try... books {at} {random} + {print} 'Добродошли у онлајн библиотеку! + {ask} Који жанр књига волиш? + {print} Волиш жанр + author {is} {ask} 'Ко је твој омиљени аутор?' + {print} 'author је твој омиљени аутор' + {print} Хммм... мислим да би требало да пробаш... књиге {at} {random} ``` 5: story_text: |- - ### Exercise - Debug this code. Good luck! - example_code: | - **Warning! This code needs to be debugged!** - ``` - {print} Welcome to Swimming Pool Hedy! - class {is} {ask} 'Are you here to join a class today?' - {if} class yes - {print} 'Great! You're joining a class! - {print} {else} 'You will not be joining a class' - discount {is} 'Do you have a discount code?' - {if} discount {is} yes - discount_answer {is} {ask} 'What's your discount code?' + ### Вежба + Отклоните грешке у овом коду. Срећно! + example_code: | + **Упозорење! Овај код треба отклонити грешке!** + ``` + {print} Добродошли у базен Хеди! + class {is} {ask} 'Да ли сте овде да се придружите часу данас?' + {if} class да + {print} 'Сјајно! Придружујете се часу! + {print} {else} 'Нећете се придружити часу' + discount {is} 'Да ли имате код за попуст?' + {if} discount {is} да + discount_answer {is} {ask} 'Који је ваш код за попуст?' discount_codes = Senior4231, Student8786, NewMember6709 {if} discount_answer {is} {in} discount_cods - {print} 'That will be $3,50' - 'That will be $5,50' - {print} 'Have a nice swim!' + {print} 'То ће бити $3,50' + 'То ће бити $5,50' + {print} 'Пријатно пливање!' ``` 6: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Вежба + Отклоните грешке у овом коду. Срећно! example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба отклонити грешке!** ``` - {print} 'Vending machine' - chosen_product = {ask} 'Please select a product' - 1_dollar_products = coke orange juice water - 2_dollar_products = chocolate, cookie, museli bar - 3dollar_prodcuts = potato chips, beef jerky, banana bread + {print} 'Аутомат за продају' + chosen_product = {ask} 'Молимо вас да изаберете производ' + 1_dollar_products = кока-кола, сок од поморанџе, вода + 2_dollar_products = чоколада, кекс, мусли бар + 3dollar_prodcuts = чипс, говеђи џерки, банана хлеб {if} chosen {is} {in} 1_dollar_products price = 1 {if} chosen_product {is} 2_dollar_products price = 2 - {else} chosen_product {in} 3_dollar_products + {else} chosen_product {in} 3_dоллар_продуцтс price = 3 - amount_of_products = '{ask} How many of ' chosen_product would you like to have?' + amount_of_products = '{ask} Колико ' chosen_product желите?' total = price + amount_of_product - {print} 'That will be $' price 'please' + {print} 'То ће бити $' price 'молим' ``` 7: story_text: |- - ### Exercise - Surprise! This program looks more like an output than a code. And yet, we don't want you to just add `{print}` commands in front of each line. - Fix this program to turn it into the nursery rhyme 'Brother John (Frère Jaques)' by using the {repeat} command of course! + ### Вежба + Изненађење! Овај програм више личи на излаз него на код. Ипак, не желимо да само додате `{print}` команде испред сваке линије. + Исправите овај програм да га претворите у дечију песму 'Брат Јован (Frère Jacques)' користећи команду {repeat} наравно! example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба отклонити грешке!** ``` - Are you sleeping? - Brother John! - Morning bells are ringing! - Ding, dang, dong! + Да ли спаваш? + Брате Јоване! + Јутарња звона звоне! + Динг, данг, донг! ``` 8: story_text: |- - ### Exercise - Debug this code. Good luck! - example_code: | - **Warning! This code needs to be debugged!** + ### Вежба + Отклоните грешке у овом коду. Срећно! + example_code: |- + **Упозорење! Овај код треба дебаговати!** ``` - {print} 'Welcome to Manicures and Pedicures by Hedy' - bodypart = {ask} 'Are you getting your fingernails or toenails done today? Or both?' - {if} bodyparts {is} both - {print} That will be $25' + {print} 'Добродошли у Маникир и Педикир код Хеди' + bodypart = {ask} 'Да ли ћете данас радити нокте на рукама или ногама? Или оба?' + {if} bodyparts {is} оба + {print} 'То ће бити $25' price = 25 {else} - {print} That will be $18' + {print} 'То ће бити $18' price = 18 - color = {ask} What color would you like? - sparkles = {ask} 'Would you like some sparkles with that?' - {if} sparkles {is} yes - {print} 'We charge $3 extra for that' + color = {ask} 'Коју боју желите?' + sparkles = {ask} 'Да ли желите шљокице уз то?' + {if} sparkles {is} да + {print} 'Наплаћујемо $3 додатно за то' price = price + 3 - {else} {print} 'No sparkles' {print} 'So no extra charge' + {else} {print} 'Без шљокица' {print} 'Дакле, нема додатних трошкова' {sleep} 5 - {print} 'All done! That will be $' price ' please!' - {print} 'Thank you! Byebye!' + {print} 'Готово! То ће бити $' price ' молим!' + {print} 'Хвала! Довиђења!' ``` 9: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Вежба + Дебагујте овај код. Срећно! example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба дебаговати!** ``` - {print} 'Welcome to our sandwich shop' - amount 'How many sandwiches would you like to buy?' + {print} 'Добродошли у нашу сендвичару' + amount 'Колико сендвича желите да купите?' {repeat} amount {times} - {ask} {is} {ask} 'What kind or bread would you like your sandwich to be?' - types_of_bread {is} white, wheat, rye, garlic, gluten free + {ask} {is} {ask} 'Какву врсту хлеба желите за ваш сендвич?' + types_of_bread {is} бели, пшенични, ражани, бели лук, без глутена {if} chosen_bread in types_of_bread - {print} 'Lovely!' + {print} 'Одлично!' {else} - 'I'm sorry we don't sell that' - topping {is} {ask} 'What kind of topping would you like?' - sauce {is} {ask} 'What kind of sauce would you like?' - {print} One chosen_bread with topping and sauce. + 'Жао ми је, не продајемо то' + topping {is} {ask} 'Коју врсту прелива желите?' + sauce {is} {ask} 'Коју врсту соса желите?' + {print} Један chosen_bread са topping и sauce. price = amount * 6 - {print} 'That will be 'price dollar' please' + {print} 'То ће бити 'price долара' молим' ``` - - price = amount * 6 - {print} 'That will be 'price dollar' please' 10: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Вежба + Дебагујте овај код. Срећно! example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба дебаговати!** ``` - names = Muad Hasan Samira Noura - activities = fly a kite, go swimming, go hiking, catch tan in the sun + names = 'Муад', 'Хасан', 'Самира', 'Нура' + activities = 'пуштање змаја', 'пливање', 'планинарење', 'сунчање' {for} name {is} names - {print} At the beach name loves to activity at random + {print} 'На плажи ' name ' воли да ' activity {at} {random} ``` 11: story_text: |- - ### Exercise - Debug this calender program. The output of this program is supposed to look like a list of dates. - For example: + ### Вежба + Дебагујте овај календарски програм. Излаз овог програма треба да изгледа као листа датума. + На пример: ``` - Hedy calender - Here are all the days of November - November 1 - November 2 - November 3 + Хеди календар + Ево свих дана у новембру + Новембар 1 + Новембар 2 + Новембар 3 ``` - And so on. + И тако даље. - Mind that you have to test your code extra carefully for the month February, because the amount of days in this month changes in leap years. + Имајте на уму да морате додатно тестирати свој код за месец фебруар, јер се број дана у овом месецу мења у преступним годинама. example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба дебаговати!** ``` - print 'Hedy calender' - months_with_31 days = January, March, May, July, September, October, December - months_with_30_days = April, June, August, November - month = ask 'Which month would you like to see?' - if month in months_with_31_days + {print} 'Хеди календар' + months_with_31 days = Јануар, Март, Мај, Јул, Септембар, Октобар, Децембар + months_with_30_days = Април, Јун, Август, Новембар + month = {ask} 'Који месец желите да видите?' + {if} month {in} months_with_31_days days = 31 - if month in months_with30_days + {if} month {in} months_with30_days days = 30 - if month = February + {if} month = Фебруар leap_years = 2020, 2024, 2028, 2036, 2040, 2044, 2028 - year = ask 'What year is it?' - if year in leap_years + year = {ask} 'Која је година?' + {if} year {in} leap_years days = 29 - else + {else} days = 28 - print 'Here are all the days of ' moth - for i in range 1 to days - print month i + {print} 'Ево свих дана у ' moth + {for} i {in} {range} 1 {to} days + {print} month i ``` 12: story_text: |- - ### Exercise - Debug this code. Good luck! - example_code: | - **Warning! This code needs to be debugged!** - ``` - define greet - greetings = 'Hello', 'Hi there', 'Goodevening' - print greetings at random - - define take_order - food = ask 'What would you like to eat?' - print 'One food' - drink = 'What would you like to drink?' - print 'One ' drink - more = ask 'Would you like anything else?' - if more is 'no' - print 'Alright' - else - print 'And ' more - print 'Thank you' - - print 'Welcome to our restaurant' - people = ask 'How many people are in your party tonight?' - for i in range 0 to people - call greet_costumer + ### Вежба + Дебагујте овај код. Срећно! + example_code: | + **Упозорење! Овај код треба дебаговати!** + ``` + {define} greet + greetings = 'Здраво', 'Ћао', 'Добро вече' + {print} greetings {at} {random} + + {define} take_order + food = {ask} 'Шта желите да једете?' + {print} 'Један food' + drink = 'Шта желите да пијете?' + {print} 'Један ' drink + more = {ask} 'Желите ли још нешто?' + {if} more {is} 'не' + {print} 'У реду' + {else} + {print} 'И ' more + {print} 'Хвала' + + {print} 'Добродошли у наш ресторан' + people = {ask} 'Колико људи је у вашој групи вечерас?' + {for} i {in} {range} 0 {to} people + {call} greet_costumer ``` 13: story_text: |- - ### Exercise - Debug this code. Good luck! - example_code: | - **Warning! This code needs to be debugged!** - ``` - defin movie_recommendation with name - action_movies == 'Die Hard', 'Fast and Furious', 'Inglorious Bastards' - romance_movies = 'Love Actually', 'The Notebook', 'Titanic' - comedy_movies = 'Mr Bean' 'Barbie''Deadpool' - kids_movies = 'Minions', 'Paddington', 'Encanto' - if name is 'Camila' or name is 'Manuel' - recommended_movie = kids_movie at random - if name is 'Pedro' or 'Gabriella' - mood = ask 'What you in the mood for?' - if mood is 'action' - recommended_movie = comedy_movies at random - if mood is 'romance' + ### Вежба + Дебагујте овај код. Срећно! + example_code: | + **Упозорење! Овај код треба дебаговати!** + ``` + {define} movie_recommendation {with} name + action_movies = 'Умри мушки', 'Паклене улице', 'Проклетници' + romance_movies = 'Заправо љубав', 'Бележница', 'Титаник' + comedy_movies = 'Господин Бин', 'Барби', 'Дедпул' + kids_movies = 'Мињони', 'Падингтон', 'Енканто' + {if} name {is} 'Камила' {or} name {is} 'Мануел' + recommended_movie = kids_movies {at} {random} + {if} name {is} 'Педро' {or} 'Габријела' + mood = {ask} 'У каквом сте расположењу?' + {if} mood {is} 'акција' + recommended_movie = action_movies {at} {random} + {if} mood {is} 'романтика' recommended_movie = romance_movies - if mood is 'comedy' - recommended_movie = comedy_movies at random + {if} mood {is} 'комедија' + recommended_movie = comedy_movies {at} {random} - print 'I would recommend ' recommended_movie ' for ' name + {print} 'Препоручио бих ' recommended_movie ' за ' name - name = ask 'Who is watching?' - recommendation = ask 'Would you like a recommendation?' - if recommendaion is 'yes' - print movie_recommendation with name - else - print 'No problem!' + name = {ask} 'Ко гледа?' + recommendation = {ask} 'Да ли желите препоруку?' + {if} recommendation {is} 'да' + {print} movie_recommendation {with} name + {else} + {print} 'Нема проблема!' ``` 14: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Вежба + Дебагујте овај код. Срећно! example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба дебаговати!** ``` - define calculate_heartbeat - print 'Press your fingertips gently against the side of your neck' - print '(just under your jawline)' - print 'Count the number of beats you feel for 15 seconds' - beats == ask 'How many beats do you feel in 15 seconds?' + {define} calculate_heartbeat + {print} 'Притисните врхове прстију нежно уз страну вашег врата' + {print} '(одмах испод вилице)' + {print} 'Бројите број откуцаја које осетите за 15 секунди' + beats == {ask} 'Колико откуцаја осећате за 15 секунди?' heartbeat = beats*4 - print 'Your heartbeat is ' heartbeat - if heartbeat >= 60 or heartbeat <= 100 - print 'Your heartbeat seems fine' - else - if heartbeat > 60 - print 'Your heartbeat seems to be too low' - if heartbeat < 100 - print 'Your heartbeat seems to be too high' - print 'You might want to contact a medical professional' - - measure_heartbeat = ask 'Would you like to measure your heartbeat?' - if measure_heartbeat = 'yes' - call measure_heartbeat - else - 'no problem' - ``` - - print '(just under your jawline)' - print 'Count the number of beats you feel for 15 seconds' - beats == ask 'How many beats do you feel in 15 seconds?' - heartbeat = beats*4 - print 'Your heartbeat is ' heartbeat - if heartbeat >= 60 or heartbeat <= 100 - print 'Your heartbeat seems fine' - else - if heartbeat > 60 - print 'Your heartbeat seems to be too low' - if heartbeat < 100 - print 'Your heartbeat seems to be too high' - print 'You might want to contact a medical professional' - - measure_heartbeat = ask 'Would you like to measure your heartbeat?' - if measure_heartbeat = 'yes' - call measure_heartbeat - else - 'no problem' + {print} 'Ваш пулс је ' heartbeat + {if} heartbeat >= 60 {or} heartbeat <= 100 + {print} 'Ваш пулс изгледа у реду' + {else} + {if} heartbeat > 60 + {print} 'Ваш пулс изгледа пренизак' + {if} heartbeat < 100 + {print} 'Ваш пулс изгледа превисок' + {print} 'Можда би требало да се обратите медицинском стручњаку' + + measure_heartbeat = {ask} 'Желите ли да измерите свој пулс?' + {if} measure_heartbeat = 'да' + {call} measure_heartbeat + {else} + 'нема проблема' + ``` 15: story_text: |- - ### Exercise - Debug this random children's story. Good luck! - example_code: | - **Warning! This code needs to be debugged!** - ``` - names = 'Tanya', 'Romy', 'Kayla', 'Aldrin', 'Ali' - verbs='walking', 'skipping', 'cycling', 'driving', 'running' - locations = 'on a mountaintop', 'in the supermarket', 'to the swimming pool' - hiding_spots = 'behind a tree', under a table', in a box' - sounds = 'a trumpet', 'a car crash', 'thunder' - causes_of_noise = 'a television', 'a kid with firecrackers', 'a magic elephant', 'a dream' - - chosen_ name = names at random - chosen_verb = verbs at random - chosen_location = 'locations at random' - chosen_sounds = noises at random - chosen_spot = hiding_spots random - chosen_causes = causes_of_noise at random - - print chosen_name ' was ' chosen_verb ' ' chosen_location - print 'when they suddenly heard a sound like ' sounds at random - print chosen_name ' looked around, but they couldn't discover where the noise came from' - print chosen_name ' hid ' chosen_spot' - print 'They tried to look around, but couldn't see anything from there' - hidden = 'yes' - while hidden = 'yes' - print chosen_name 'still didn't see anything' - answer = ask 'does ' chosen_name ' move from their hiding spot?' - if answer = 'yes' - hidden == 'no' - print 'chosen_name moved from' chosen_spot - print 'And then they saw it was just' chosen_cause - print chosen_name 'laughed and went on with their day' - print The End + ### Вежба + Дебагујте ову случајну дечију причу. Срећно! + example_code: | + **Упозорење! Овај код треба дебаговати!** + ``` + names = 'Тања', 'Роми', 'Кајла', 'Алдрин', 'Али' + verbs='ходање', 'прескакање', 'бициклизам', 'вожња', 'трчање' + locations = 'на врху планине', 'у супермаркету', 'до базена' + hiding_spots = 'иза дрвета', 'испод стола', 'у кутији' + sounds = 'труба', 'саобраћајна несрећа', 'гром' + causes_of_noise = 'телевизор', 'дете са петардама', 'магични слон', 'сан' + + chosen_ name = names {at} {random} + chosen_verb = verbs {at} {random} + chosen_location = 'locations {at} {random}' + chosen_sounds = noises {at} {random} + chosen_spot = hiding_spots {random} + chosen_causes = causes_of_noise {at} {random} + + {print} chosen_name ' је био ' chosen_verb ' ' chosen_location + {print} 'када су одједном чули звук као ' sounds {at} {random} + {print} chosen_name ' је погледао око себе, али није могао да открије одакле долази звук' + {print} chosen_name ' се сакрио ' chosen_spot' + {print} 'Покушали су да погледају око себе, али нису могли ништа да виде одатле' + hidden = 'да' + {while} hidden = 'да' + {print} chosen_name 'још увек није видео ништа' + answer = {ask} 'да ли ' chosen_name ' излази из свог скровишта?' + {if} answer = 'да' + hidden == 'не' + {print} 'chosen_name је изашао из' chosen_spot + {print} 'И онда су видели да је то само' chosen_cause + {print} chosen_name 'се насмејао и наставио свој дан' + {print} Крај ``` 16: story_text: |- - ### Exercise - Debug this code. Good luck! - Tip: Make sure that you only see your score once in the end. + ### Вежба + Дебагујте овај код. Срећно! + Савет: Уверите се да видите свој резултат само на крају. example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба дебаговати!** ``` - country = ['The Netherlands', 'Poland', 'Turkey', 'Zimbabwe', 'Thailand', 'Brasil', 'Peru', 'Australia', 'India', 'Romania' ] - capitals = 'Amsterdam', 'Warshaw' 'Istanbul', 'Harare', 'Bangkok', 'Brasilia', 'Lima', 'Canberra', 'New Delhi', 'Bucharest' + country = ['Холандија', 'Пољска', 'Турска', 'Зимбабве', 'Тајланд', 'Бразил', 'Перу', 'Аустралија', 'Индија', 'Румунија' ] + capitals = 'Амстердам', 'Варшава' 'Истанбул', 'Хараре', 'Бангкок', 'Бразилија', 'Лима', 'Канбера', 'Њу Делхи', 'Букурешт' score = 0 - for i in range 0 to 10 - answer = ask 'What's the capital of ' countries[i] + {for} i {in} {range} 0 {to} 10 + answer = {ask} 'Који је главни град ' countries[i] correct = capital[i] - if answer = correct - print 'Correct!' + {if} answer = correct + {print} 'Тачно!' score = score + 1 - else - print 'Wrong,' capitals[i] 'in the capital of' countries[i] - print 'You scored ' score ' out of 10' + {else} + {print} 'Нетачно,' capitals[i] 'је главни град' countries[i] + {print} 'Освојили сте ' score ' од 10' ``` 17: story_text: |- - ### Exercise - Debug this code. Good luck! + ### Вежба + Дебагујте овај код. Срећно! example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба дебаговати!** ``` - define food_order - toppings = ask 'pepperoni, tuna, veggie or cheese?' - size = ask 'big, medium or small?' - number_of_pizza = ask 'How many these pizzas would you like?' + {define} food_order + toppings = {ask} 'пеперони, туна, вегетаријанска или сир?' + size = {ask} 'велика, средња или мала?' + number_of_pizza = {ask} 'Колико ових пица желите?' - print 'YOU ORDERED' - print number_of_pizzas ' size ' topping ' pizza' + {print} 'НАРУЧИЛИ СТЕ' + {print} number_of_pizzas ' величине ' topping ' пицу' - define drinks_order - drink = ask 'water, coke, icetea, lemonade or coffee?' - number_of_drinks = ask 'How many of these drinks would you like?' + {define} drinks_order + drink = {ask} 'вода, кока-кола, ледени чај, лимунада или кафа?' + number_of_drinks = {ask} 'Колико ових пића желите?' - print 'YOU ORDERED' - print number_of_drinks ' ' drink + {print} 'НАРУЧИЛИ СТЕ' + {print} number_of_drinks ' ' drink - 'Welcome to Hedy pizza' - more_food = ask 'Would you like to order a pizza?' - while more_food = 'yes' - return food_order - more_food = ask 'Would you like to order a pizza?' - more_drinks = ask 'Would you like to order some drinks?' - while more_drinks == 'yes' - call drink_order - more_drinks == ask 'Would you like to order more drinks?' + 'Добродошли у Хеди пицу' + more_food = {ask} 'Да ли желите да наручите пицу?' + {while} more_food = 'да' + {return} food_order + more_food = {ask} 'Да ли желите да наручите пицу?' + more_drinks = {ask} 'Да ли желите да наручите нека пића?' + {while} more_drinks == 'да' + {call} drink_order + more_drinks == {ask} 'Да ли желите да наручите још пића?' - print 'Thanks for ordering!' + {print} 'Хвала на наруџбини!' ``` 18: story_text: |- - ### Exercise - Debug this Old MacDonald program from level 16. Good luck! + ### Вежба + Дебагујте овај програм "Старац Макдоналд" са нивоа 16. Срећно! example_code: | - **Warning! This code needs to be debugged!** + **Упозорење! Овај код треба дебаговати!** ``` - animals = ['pig', 'dog', 'cow'] - sounds = ['oink', 'woof', 'moo'] - for i in range 1 to 3 + animals = ['свиња', 'пас', 'крава'] + sounds = ['оинк', 'ав', 'му'] + {for} i {in} {range} 1 {to} 3 animal = animals[i] sound = sounds[i] - print 'Old MacDonald had a farm' - print 'E I E I O!' - print 'and on that farm he had a ' animal - print 'E I E I O!' - print 'with a ' sound sound ' here' - print 'and a ' sound sound ' there' - print 'here a ' sound - print 'there a ' sound - print 'everywhere a ' sound sound + {print} 'Старац Макдоналд је имао фарму' + {print} 'Е И Е И О!' + {print} 'и на тој фарми је имао ' animal + {print} 'Е И Е И О!' + {print} 'са ' sound sound ' овде' + {print} 'и ' sound sound ' тамо' + {print} 'овде ' sound + {print} 'тамо ' sound + {print} 'свуда ' sound sound ``` default: - name: Uvod - default_save_name: uvod - description: Nivo objašnjenje + name: Увод + default_save_name: увод + description: Објашњење нивоа levels: 1: - story_text: "U Nivou 1 možete koristiti komande `{print}`, `{ask}` i `{echo}`.\n Iskucaj svoj kod u programerskom polju. Ili pritisni zeleno dugme u primeru koda i kod će se iskucati za vas!\nIsprobaj sam kod tako što ćeš pritisnuti zeleno 'Run code' dugme ispod programerskog polja.\n\nMožeš ispisati tekst na ekranu koristeći `{print}` komandu. \n" + story_text: "Добродошли у Хеди! Овде можете научити како да програмирате корак по корак.\n\nИспробајте код сами! Жуто дугме копира пример кода у ваше поље за програмирање.\nЗатим притисните зелено дугме 'Покрени код' испод поља за програмирање да бисте покренули код.\n\nСпремни? Онда идите на следећу картицу да научите како да направите своје кодове!\n" example_code: | ``` - {print} Hello world! + {print} Здраво, свете! ``` 2: story_text: | - Congratulations! You've reached level 2. Hopefully you've already made some awesome codes! - In the first level you might've notice that the `{echo}` command can only save one bit of information at a time. - For example in the restaurant adventure, you could echo what the costumer wanted to eat, or what they wanted to drink, but not both in one sentence. + Честитамо! Достигли сте ниво 2. Надамо се да сте већ направили неке сјајне кодове! + На првом нивоу можда сте приметили да команда `{echo}` може да сачува само једну информацију у исто време. + На пример, у авантури у ресторану, могли сте да ехо-ујете шта је купац желео да једе, или шта је желео да пије, али не обоје у једној реченици. - That changes in level 2. In level 2 you'll learn to work with variables, that allow you to save multiple pieces of information and print them in any place you want. - So let's go to the next tab! + То се мења на нивоу 2. На нивоу 2 ћете научити да радите са променљивама, које вам омогућавају да сачувате више информација и штампате их на било ком месту које желите. + Па хајде да идемо на следећу картицу! example_code: | - **Warning! This code does not work!** - In Hedy commands will change sometimes. `{echo}` for example only works in level 1. In this level you'll learn a better way to echo answers back. + **Упозорење! Овај код не ради!** + У Хедију се команде понекад мењају. `{echo}` на пример ради само на нивоу 1. На овом нивоу ћете научити бољи начин да ехо-ујете одговоре назад. ``` - {print} Welcome at Hedy's - {ask} What would you like to eat? - {echo} So you want - {ask} what would you like to drink? - {echo} So you want + {print} Добродошли у Хедијев + {ask} Шта бисте желели да једете? + {echo} Дакле, желите + {ask} шта бисте желели да пијете? + {echo} Дакле, желите ``` 3: story_text: | - U nivou 3 možeš napraviti listu. Možeš dozvoliti da kompjuter odabere nasumično iz liste. To postižeš sa `{at} {random}`. + На претходном нивоу сте научили шта је променљива и како можете да је користите да би ваше авантуре биле интерактивније. + Али... то није једина ствар коју можете да урадите са променљивама! Такође можете користити променљиве да направите листе. + И можете чак дозволити Хедију да изабере насумичну реч из листе, што вам омогућава да направите праве игре! + Погледајте брзо следећу картицу! 4: story_text: | - U nivou 4 `{ask}` i `{print}` su izmenjeni. - Moraš staviti tekst koji želiš da ispišeš izmedju znaka navoda. - Ovo je korisno, jer sada možeš da ispišeš sve reči koje želiš. Takodje i reči koje si koristio da sačuvaš nešto sa `{is}`. - Većina programskih jezika takodje koriste znake navoda prilikom ispisivanja, šo znači da smo korak bliži pravom programiranju! + На претходним нивоима сте вежбали са променљивама, али можда сте наишли на овај проблем. + Можда сте покушали да покренете код као овај: + + Наравно, желели сте да штампате + + `My name is Sophie` + + али Хеди штампа + + `My Sophie is Sophie` + + На овом нивоу овај проблем је решен коришћењем наводника. example_code: | ``` - {print} 'Treba da koristiš znake navoda od sada pa nadalje!' - odgovor {is} {ask} 'Šta treba da koristimo od sada pa nadalje?' - {print} 'Treba da koristimo' odgovor + име {is} Софи + {print} Моје име је име ``` 5: story_text: | - U nivou 5 se nalazi novina, zvana `{if}`! Sa `{if}` možeš birati izmedju dve različite opcije. - Ovaj kod štampa super! ako odabereš ime Hedy, i bla! ako odabereš nešto drugo. - `{ask}` i `{print}` i dalje rade kao što su i radili u nivou 4. + На претходним нивоима сте већ научили да користите `{at} {random}` што је чинило ваше игре другачијим сваки пут када покренете код. + Али то није баш интерактивно, играч нема никакав утицај на то шта се дешава у игри. + + На овом нивоу ћете научити команду `{if}`, која вам омогућава да дате различите одговоре у вашем програму. На овај начин можете програмирати тајну лозинку за ваш рачунар, на пример. + Па хајде да идемо на следећу картицу за нову команду! example_code: | ``` - ime {is} {ask} 'Kako se zoves?' - {if} ime {is} Hedy {print} 'super!' {else} {print} 'bla!' + лозинка {is} {ask} 'Која је исправна лозинка?' ``` 6: - story_text: "U ovom nivou naučićeš nešto novo: sada možeš da vršiš i matematičke operacije.\n\nSabiranje je lako, pišeš isto kao i u matematici: `5 + 5` na primer. Oduzimanje je takodje lako, `5 - 5`.\n\nMnoženje je malo drugačije, jer ne postoji znak puta na tastaturi. \nZato množimo sa zvezdicom na tipki iznad broja 8: `5 * 5`. Čitaj kao \"5 puta 5\" to najbolje pomaže da zapamtiš.\n" - example_code: | - ``` - {print} '5 plus 5 je ' 5 + 5 - {print} '5 minus 5 je ' 5 - 5 - {print} '5 puta 5 je ' 5 * 5 + story_text: "На претходном нивоу сте вежбали са `{ask}` и `{if}`. На пример, можете питати госте шта би желели да једу.\nМеђутим, оно што још увек не можете да урадите је да израчунате цену за свачију вечеру.\n\nОвај ниво омогућава коришћење сабирања, одузимања и множења у вашим програмима. На овај начин можете израчунати цене у вашем ресторану, али можете такође додати тајни код да бисте својим пријатељима и породици дали попуст.\nЈош једна опција на овом нивоу је програмирање ваше сопствене математичке игре, за вашег млађег брата или сестру да вежбају множење.\nПогледајте сами!\n" + example_code: | + ``` + цена_хране {is} 0 + цена_пића {is} 0 + укупна_цена {is} 0 + {print} 'Добродошли у McHedy' + наруџбина {is} {ask} 'Шта бисте желели да једете?' + {if} наруџбина {is} хамбургер цена_хране {is} 5 + {if} наруџбина {is} помфрит цена_хране {is} 2 + пиће {is} {ask} 'Шта бисте желели да пијете?' + {if} пиће {is} вода цена_пића {is} 0 + {else} цена_пића {is} 3 + укупна_цена {is} цена_хране + цена_пића + {print} 'То ће бити ' укупна_цена ' долара, молим' ``` 7: story_text: | - Nivo 7 dodaje komandu `{repeat}`. `{repeat}` se može koristiti za izvršavanje jedne linije koda više puta. + Одличан посао! Достигли сте следећи ниво, што значи да сте вежбали са `{if}` и `{else}`. Вероватно сте приметили да ваши кодови постају све дужи и дужи. + На пример, ако желите да програмирате 'Срећан рођендан'. + + То је много кода за углавном исте речи изнова и изнова. Срећом, на следећој картици ћете научити решење са командом `{repeat}`, која вам омогућава да поновите линију кода више пута. example_code: | ``` - {repeat} 3 {times} {print} 'Hedy je zabava!' + {print} 'срећан рођендан теби' + {print} 'срећан рођендан теби' + {print} 'срећан рођендан драга Хеди' + {print} 'срећан рођендан теби' ``` 8: story_text: | - `{ask}` i `{print}` i dalje rade kao što ih znamo. Ali `{if}`, `{else}`, i `{repeat}` su promenjeni! - Sada možeš da grupišeš nekoliko linija zajedno, ali moraćeš da uvučeš kod. - To znači pravljenje četiri razmaka na početku linije. Takodje ćeš morati da uvučeš red kada želiš da napraviš odeljak od jedne linije koda. + Сада сте научили како да поновите једну линију кода. Ово је корисно, али није увек довољно. Понекад желите да поновите више линија одједном. + Овај ниво вам омогућава да групишете неколико линија кода и поновите ту малу групу линија све одједном! example_code: | - Ovo je kako komanda `{repeat}` radi sad: ``` - {repeat} 5 {times} - {print} 'Zdravo svima' - {print} 'Ovo je sve ponovljeno 5 puta' - ``` - Ovo je kako komande `{if}` i `{else}` rade sada: - - ``` - ime {is} {ask} 'Kako se zoveš?' - {if} ime {is} Hedy - {print} 'Dobrodošla Hedy' - {print} 'Možeš se igrati na svom računaru!' - {else} - {print} 'ULJEZ!' - {print} 'Ne možeš koristiti ovaj računar!' + {repeat} 5 {times} {print} 'На следећој картици можете поновити више линија кода одједном!' ``` 9: story_text: | - U ovom nivou ne samo da možeš da koristiš višebrojne linije sa `{if}` i `{repeat}`, nego možeš da ih koristis i zajedno! - U primeru ćeš videti komandu `{if}` unutar komande `{repeat}`. Takodje je dozvoljeno i obrnuto. Kao i komanda `{if}` je dozvoljena unutar komande `{if}` i `{repeat}` unutar `{repeat}`. - Pokušaj! + Одличан посао! Достигли сте још један нови ниво! На претходном нивоу сте научили да користите више линија кода у команди {if} или {repeat}. Али још увек не можете да комбинујете то двоје... + Добра вест! На овом нивоу ћете моћи да ставите {if} унутар {if}, или унутар команде {repeat}. Стављање блока кода унутар другог блока кода се зове угњеждавање. ``` Стављање блока кода унутар другог блока кода се зове угњеждавање. example_code: | ``` - {repeat} 3 {times} - hrana = {ask} 'Šta želiš?' - {if} hrana {is} pica - {print} 'super!' - {else} - {print} 'pica je bolja' - ``` + одговор = {ask} 'Да ли сте спремни да научите нешто ново?' + {if} одговор {is} да + {print} 'Одлично! Можете научити да користите команду repeat у команди if!' + {print} 'Ура!' + {print} 'Ура!' + {print} 'Ура!' + {else} + {print} 'Можда би требало да вежбате још мало на претходном нивоу' 10: - story_text: |- - U ovom nivou učimo novi kod zvani`{for}`. Sa `{for}` možeš napraviti listu i koristiti sve elemente. - `{for}` napravi odeljak, kao `{repeat}` i `{if}` tako da sve linije u odeljku moraju da počnu sa razmacima. + story_text: | + Иде вам одлично! На претходним нивоима смо се још увек суочавали са малим проблемом. Научили сте да понављате линије, али шта ако желите да мало промените линију. + На пример, ако желите да певате песму 'ако сте срећни и знате то'. Изгледало би овако: + + Ако желите и следећи стих 'лупај ногама', и следећи, и следећи, морали бисте потпуно да промените код. + На овом нивоу ћете научити команду `{for}`, која вам омогућава да направите листу акција и поновите код са другом акцијом сваки пут! + Погледајте! example_code: | ``` - životinje {is} pas, mačka, riba - {for} životinja {in} životinje - {print} 'Ja volim ' životinja + {repeat} 2 {times} + {print} 'ако сте срећни и знате то пљесните рукама' + {print} 'ако сте срећни и знате то и стварно желите да покажете' + {print} 'ако сте срећни и знате то пљесните рукама' ``` 11: story_text: | - You have reached level 11, you're doing great! In the higher levels, Hedy is focussing more and more on teaching you the programming language Python. - In Python there is no `{repeat}` command, but there is a command that works like {repeat}. Are you curious to find out how to say `{repeat}` in Python language? Quickly go on to find out! + Достигли сте ниво 11, иде вам одлично! На вишим нивоима, Хеди се све више фокусира на учење програмског језика Python. + У Python-у не постоји команда `{repeat}`, али постоји команда која ради као {repeat}. Да ли сте радознали да сазнате како се каже `{repeat}` на језику Python? Брзо идите да сазнате! 12: - story_text: |- - **Decimalni brojevi** - Do sada, Hedy nije dozvoljavao upotrebu decimalnih brojeva kao što je 1.5, ali sada je dozvoljeno. Vodi računa da računar koristi tačku `.` a ne zarez za decimalne brojeve. + story_text: | + Можда сте покушали да користите децималне бројеве у вашој авантури у ресторану. Ако јесте, вероватно сте приметили да Хеди још увек није разумела и увек је заокруживала. + Од овог нивоа можете користити децималне бројеве. example_code: | ``` - {print} 'Dva zarez pet plus dva zarez pet je...' - {print} 2.5 + 2.5 + хамбургер = 5 + пиће = 2 + укупно = хамбургер + пиће + print 'Наручили сте хамбургер и пиће' + print 'То кошта ' укупно ' долара, молим' ``` - - {print} 2.5 + 2.5 13: - story_text: |- - Sada ćemo da naučimo `{and}` i `{or}`! Ako hoćeš da proveriš dve izjave, ne moraš koristiti dva puta {if} nego možeš koristiti `{and}` i `{or}`. - Ako koristiš `{and}`, obe izjave, levo i desno od `{and}` moraju biti istinite. Ali možemo takodje koristiti i `{or}`. U tom slučaju samo jedna izjava mora biti tačna. + story_text: | + На претходним нивоима сте научили како да ставите две `{if}` команде једну унутар друге. Ово функционише добро, али вам даје веома дугачке и непрактичне кодове као овај: + + У овом систему морате дати и исправно корисничко име и исправну лозинку. + На овом нивоу ћете научити команду `{and}` која ће овај код учинити много краћим и разумљивијим! + Погледајте! example_code: | ``` - ime = {ask} 'Kako se zoveš?' - uzrast = {ask} 'koliko imaš godina?' - {if} ime {is} 'Hedy' {and} uzrast {is} 2 - {print} 'Ti si prava Hedy!' + username = {ask} 'Како се зовеш?' + password = {ask} 'Која је твоја лозинка?' + {if} username {is} 'Hedy' + {if} password {is} 'тајна' + {print} 'Добродошла Hedy!' + {else} + {print} 'Приступ одбијен' + {else} + {print} 'Приступ одбијен!' ``` 14: story_text: | - Naučićemo još novih stvari. Možda to već znate iz matematike, znaci manje `<` i veće `>`. - Manje `<` proverava da li je prvi broj manji nego drugi, na primer uzrast `<` 12 proverava da li je uzrast manji od 12 godina. - Ako želiš da proveriš da li je prvi broj manji ili jednak drugom broju, možes koristiti znak manje ili jednako `<=`, na primer uzrast `<=` 11. - Znak više `>` proverava da li je prvi broj veći nego drugi, na primer uzrast `>` 10 proverava da li je uzrast veći od 10. - Ako želiš da proveriš da li je prvi broj veći ili jednak drugom broju, možes koristiti znak veće ili jednako`>=`, na primer uzrast `>=` 11. - Ova poredjenja koristiš sa `{if}`, ovako: + Са примером кода можете израчунати да ли сте положили предмет у школи (дакле, оцена шест или више). + Можете видети да је овај код изузетно неефикасан, због веома дугачког кода у линији 5. + Све различите оцене од 1 до 5 морале су бити програмиране посебно. Срећом за вас, на овом нивоу ћете научити како да то урадите без овог изузетно дугачког кода! example_code: | ``` - uzrast = {ask} 'Koliko imaš godina?' - {if} uzrast > 12 - {print} 'Stariji si od mene!' - ``` - - {if} uzrast < 13 - {print} 'Mladji si od mene!' + прва_оцена = {ask} 'Коју оцену сте добили на првом тесту?' + друга_оцена = {ask} 'Коју оцену сте добили на другом тесту?' + збир = прва_оцена + друга_оцена + просечна_оцена = збир / 2 + {if} просечна_оцена = 1 {or} просечна_оцена = 2 {or} просечна_оцена = 3 {or} просечна_оцена = 4 {or} просечна_оцена = 5 + {print} 'О не! Нисте положили предмет...' {else} - {print} 'Stariji si od mene!' + {print} 'Одлично! Положили сте предмет!' + ``` 15: - story_text: |- - Sada ćemo naučiti novu petlju, `{while}` petlja! Nastavljamo petlju sve dok je izjava tačna. - Tako da nemoj zaboraviti da promeniš vrednost elementa u petlji. - - U primeru koda, nastavljamo sve dok ne dobijemo tačan odgovor. - Ako nikad ne dobijemo tačan odgovor, petlja se neće nikad prekinuti! + story_text: | + У овој игри испод направљен је код да би се осигурало да играч може да игра колико год жели... + Али код је неефикасан и превише дугачак. Такође, шта ако играч жели да игра 101 игру уместо 100? + Не можете играти до бесконачности? + На овом нивоу ћете научити команду која све ово чини много лакшим! example_code: | ``` - odgovor = 0 - {while} odgovor != 25 - odgovor = {ask} 'Koliko je 5 puta 5?' - {print} 'Tačan odgovor je dat' + игра = 'укључено' + {for} i {in} {range} 1 {to} 100 + {if} игра == 'укључено' + одговор = {ask} 'Да ли желите да наставите?' + {if} одговор == 'не' + игра = 'готово' + {if} одговор == 'да' + {print} 'У реду, наставићемо' ``` 16: - story_text: |- - Sada ćemo da napravimo liste kao što se prave u programerskom jeziku Python, sa uglastim zagradama oko liste! Takodje nastavljamo da koristimo znake navoda oko svakog elementa, kao što smo u prethodnim nivoima naučili. - Uglaste zagrade možeš koristiti i da ukažeš na tačno odredjeno mesto u listi. Komanda {at} se više ne može koristiti. - example_code: | + story_text: | + На овом нивоу ћемо се мало више приближити правом Python коду. Такође ћете научити како да упарите две листе заједно. + На овај начин можете програмирати код у којем се исправна животиња упарује са правим звуком. + Јер два кода испод... Очигледно су бесмислица! + example_code: |- ``` - prijatelji = ['Marko', 'Marija', 'Milan'] - srećni_brojevi = [15, 18, 6] - {for} i {in} {range} 1 {to} 3 - {print} 'srećan broj za' prijatelji[i] - {print} ' je ' srećni_brojevi[i] + животиње = 'пилић', 'коњ', 'крава' + звукови = 'кокодакање', 'њиштање', 'мукање' + {for} животиња {in} животиње + {print} 'Једна ' животиња ' каже ' звукови {at} {random} + ``` + Можете такође покушати да то урадите овако, али.... ``` + животиње = 'пилић', 'коњ', 'крава' + звукови = 'кокодакање', 'њиштање', 'мукање' + {for} животиња {in} животиње + {for} звук {in} звукови + {print} 'Једна ' животиња ' каже ' звук + ``` + Напомена: Ови кодови неће радити овако на овом нивоу. Идите на следећу картицу да видите које делове треба да исправите. 17: - story_text: |- - Sada ćemo malo da izmenimo uvlačenje reda. Svaki put kada nam treba uvučeni red, potrebne su nam i dve tačke `:` na kraju prethodnog reda. + story_text: | + Сада ћемо мало променити увлачење. Сваки пут када нам је потребно увлачење, потребан нам је `:` на линији пре увлачења. - U ovom nivou možeš takodje koristiti i novu komandu: `{elif}`. `{elif}` je skraćeno za `{else} {if}` i treba ti kada želiš da napraviš 3 (ili više!) opcije. - Uveri se! + На овом нивоу можете користити и нову команду: `{elif}`. `{elif}` је скраћеница за ``{else} {if}`` и потребна вам је када желите да направите 3 (или више!) опција. + Погледајте! 18: - story_text: |- - Stigli smo do koda pravog programerskog jezika Python-a! To znači da moramo da koristimo navodnike sa {print} i {range} od sada pa nadalje. - To takodje znači da od ovog nivoa možeš koristiti Hedy kod u bilo kom Python okruženju sve dok koristiš komande na Engleskom jeziku. Ako nisi do sada, možeš promeniti podešavanje u meniju komandi. - - {print}('Moje ime je ', ime) + story_text: | + Честитамо! Достигли сте последњи ниво Хедија! Код који сте овде направили можете копирати у праве Python окружења као што су replit или PyCharm, и можете наставити да учите тамо! + Имајте на уму да Python може читати само команде на енглеском језику, тако да ако сте користили друге језике, сада ћете морати да пређете на енглески. dice: - name: Dice - default_save_name: Dice - description: Make your own dice + name: Коцкице + default_save_name: Коцкице + description: Направите своје коцкице levels: 3: story_text: | - In this level we can choose from a list. With that we can let the computer choose one side of the die. - Take a look at the games you have in your closet at home. - Are there games with a (special) die? You can also copy it with this code. - For example, the dice of the game Earthworms with the numbers 1 to 5 and an earthworm on it. + На овом нивоу можемо бирати са листе. Са тим можемо пустити рачунар да изабере једну страну коцке. + Погледајте игре које имате у орману код куће. + Да ли постоје игре са (специјалним) коцкама? Можете их такође копирати овим кодом. + На пример, коцке игре Земљани црви са бројевима од 1 до 5 и црвом на њима. - ![Die of earthworms with 1 to 5 and an earthworm on it](https://cdn.jsdelivr.net/gh/felienne/hedy@24f19e9ac16c981517e7243120bc714912407eb5/coursedata/img/dobbelsteen.jpeg) + ![Коцка земљаних црва са 1 до 5 и црвом на њој](https://cdn.jsdelivr.net/gh/felienne/hedy@24f19e9ac16c981517e7243120bc714912407eb5/coursedata/img/dobbelsteen.jpeg) example_code: | ``` - choices {is} 1, 2, 3, 4, 5, earthworm - {print} You threw _ {at} {random} + избори {is} 1, 2, 3, 4, 5, црв + {print} Бацили сте _ {at} {random} ! ``` story_text_2: | - ### Exercise - The dice in the example above are dice for a specific game. Can you make normal dice? - Or other special dice from a different game? + ### Вежба + Коцке у горњем примеру су коцке за одређену игру. Можете ли направити обичне коцке? + Или друге специјалне коцке из неке друге игре? example_code_2: | ``` - choices {is} _ + избори {is} _ ``` 4: story_text: | - In this level you can also create dice. But this time you can try it yourself, without an example code! + На овом нивоу можете такође направити коцке. Али овог пута можете покушати сами, без пример кода! - ### Exercise - Make your own dice in this level. - Tip: If you have no idea how to make dice. Take a peek at your dice from the previous level, but don't forget to add quotation marks. + ### Вежба + Направите своје коцке на овом нивоу. + Савет: Ако немате идеју како да направите коцке. Погледајте своје коцке са претходног нивоа, али не заборавите да додате наводнике. 5: story_text: | - You can also make a die again in this level using the `{if}`. - Complete the sample code so that the code says "You can stop throwing" once you have thrown an earthworm. + Додаћемо команде `{if}` и `{else}` нашим коцкама! - But maybe you want to recreate a die from a completely different game. That's fine too! Then make up your own reaction, e.g. 'yes' for 6 and 'pity' for something else. + ### Вежба + Завршите пример кода тако да код каже "Можете престати бацати" када баците црва. Требало би да каже "Морате поново бацити" ако сте бацили било шта друго. + **Додатно** Можда желите да направите коцку из потпуно друге игре. То је такође у реду! Онда смислите своју реакцију, нпр. 'да' за 6 и 'штета' за нешто друго. example_code: | ``` - choices {is} 1, 2, 3, 4, 5, earthworm - throw {is} _ - {print} 'you have' _ 'thrown' - {if} _ {is} earthworm {print} 'You can stop throwing.' _ {print} 'You have to hear it again!' + избори {is} 1, 2, 3, 4, 5, црв + бацање {is} избори {at} {random} + {print} 'бацили сте ' бацање + _ бацање {is} црв {print} 'Можете престати бацати.' + _ {print} 'Морате поново бацити!' ``` 6: story_text: | - You can also make an Earthworm die again in this, but now you can also calculate how many points have been rolled. - You may know that the worm counts 5 points for Earthworms. Now after a roll you can immediately calculate how many points you have thrown. - This is the code to calculate points for one die: + Можете такође поново направити коцку Земљаних црва на овом нивоу, али сада можете одмах израчунати колико сте поена бацили. + Можда знате да црв вреди 5 поена за Земљане црве. Сада након бацања можете одмах израчунати колико сте поена бацили. + Ово је код за израчунавање поена за једну коцку: - ### Exercise - Can you make the code so that you get the total score for 8 dice? To do that, you have to cut and paste some lines of the code. + ### Вежба + Можете ли направити код тако да добијете укупни резултат за 8 коцки? За то морате копирати и налепити неке линије кода. example_code: | ``` - choices = 1, 2, 3, 4, 5, earthworm - points = 0 - throw = choices {at} {random} - {print} 'you threw' throw - {if} throw {is} earthworm points = points + 5 {else} points = points + throw - {print} 'those are' points ' point' + избори = 1, 2, 3, 4, 5, црв + поени = 0 + бацање = избори {at} {random} + {print} 'бацили сте ' бацање + {if} бацање {is} црв поени = поени + 5 {else} поени = поени + бацање + {print} 'то су ' поени ' поена' ``` example_code_2: | - Did you manage to calculate the score for 8 dice? That required a lot of cutting and pasting, right? We are going to make that easier in level 7! + Да ли сте успели да израчунате резултат за 8 коцки? То је захтевало много копирања и лепљења, зар не? Учинићемо то лакшим на нивоу 7! 7: story_text: | - You can also make a dice again in level 5. With the `{repeat}` code you can easily roll a whole hand of dice. + Можете такође поново направити коцке на овом нивоу. Са кодом `{repeat}` можете лако бацити целу руку коцки. - ### Exercise - Try to finish the sample code! **(extra)** Think of a game you know that involves a dice and program that using a `{repeat}`. + ### Вежба + Покушајте да завршите пример кода! **Додатно** Смислите игру коју знате која укључује коцке и програмирајте то користећи `{repeat}`. example_code: | ``` - choices = 1, 2, 3, 4, 5, 6 + избори = 1, 2, 3, 4, 5, 6 _ _ _ _ _ _ _ ``` 10: - story_text: "Is everybody taking too long throwing the dice? In this level you can let Hedy throw all the dice at once!\n\n### Exercise \nChange the names into names of your friends or family, and finish the code.\n" + story_text: "### Вежба\nДа ли сви предуго бацају коцке? На овом нивоу можете пустити Хеди да баци све коцке одједном!\nПромените имена у имена ваших пријатеља или породице и завршите код.\n" example_code: | ``` - players = Ann, John, Jesse - choices = 1, 2, 3, 4, 5, 6 + играчи = Ана, Јован, Јесе + избори = 1, 2, 3, 4, 5, 6 _ _ _ _ - {print} player ' throws ' choices {at} {random} + {print} играч ' баца ' избори {at} {random} {sleep} ``` 15: story_text: | - ### Exercise - In this level you can create a little game in which you'll have to throw 6 as fast as possible. - We have started the code, it's up to you to get the game to work! + ### Вежба + На овом нивоу можете направити малу игру у којој ћете морати да баците 6 што брже могуће. + Започели смо код, на вама је да игра проради! - Firstly, add a `{while}` loop that checks if 6 has been thrown or not. - As long as you haven't thrown 6 already, throw the dice on a random number. - Print what the player has thrown. - Add a try to the amount of tries - Wait a second before you throw again, or - in case you've thrown a 6 - before the game ends. + Прво, додајте `{while}` петљу која проверава да ли је 6 бачена или не. + Док не баците 6, бацајте коцку на случајан број. + Испишите шта је играч бацио. + Додајте покушај у број покушаја. + Сачекајте секунду пре него што поново баците, или - у случају да сте бацили 6 - пре него што игра заврши. example_code: | ``` options = 1, 2, 3, 4, 5, 6 - {print} 'Throw 6 as fast as you can!' + {print} 'Баци 6 што брже можеш!' thrown = 0 tries = 0 _ @@ -1556,238 +1574,237 @@ adventures: _ _ _ - {print} 'Yes! You have thrown 6 in ' tries ' tries.' + {print} 'Да! Бацили сте 6 у ' tries ' покушаја.' ``` dishes: - name: Dishes? - default_save_name: Dishes - description: Use the computer to see who does the dishes + name: Судови? + default_save_name: Судови + description: Користите рачунар да видите ко пере судове levels: 3: story_text: | - Do you always disagree at home about who should wash the dishes or change the litter box today? - Then you can let the computer choose very fairly. You can program that in this level! + Да ли се увек не слажете код куће око тога ко треба да пере судове или мења песак у кутији за мачке данас? + Онда можете пустити рачунар да изабере веома фер. Можете то програмирати на овом нивоу! example_code: | ``` - people {is} mom, dad, Emma, Sophie - {print} people {at} {random} has to do the dishes + људи {is} мама, тата, Ема, Софи + {print} људи {at} {random} мора да пере судове ``` story_text_2: | - ### Exercise - Make your own version of the dishwasher program. Firstly make a list of your family members. - Then think of a task that needs to be done, and let the computer decide who has to do the task with the `{at} {random}` command. + ### Вежба + Направите своју верзију програма за прање судова. Прво направите листу чланова ваше породице. + Затим размислите о задатку који треба обавити и пустите рачунар да одлучи ко треба да обави задатак командом `{at} {random}`. - **Extra** Don't feel like doing the dishes yourself? Hack the program by removing your name from the list with the `{remove}` `{from}` command. + **Додатно** Не желите сами да перете судове? Хакирајте програм тако што ћете уклонити своје име са листе командом `{remove}` `{from}`. 4: story_text: | - With quotation marks you can make your dishwashing program even better. + Са наводницима можете учинити свој програм за прање судова још бољим. - ### Exercise - First, fill in right symbols or commands on the blanks to make this example program work. - Did you get it? Great! Now copy your own code from the previous level and make it work in this level by adding quotation marks in the right spots. + ### Вежба + Прво попуните исправне симболе или команде на празним местима да би овај пример програма радио. + Јесте ли успели? Одлично! Сада копирајте свој код са претходног нивоа и учините да ради на овом нивоу додавањем наводника на правим местима. example_code: | ``` - people {is} mom, dad, Emma, Sophie - {print} _ the dishes are done by _ + људи {is} мама, тата, Ема, Софи + {print} _ судови су опрани од _ {sleep} - {print} people {at} _ + {print} људи {at} _ ``` 5: story_text: | - With the `{if}` you can now have more fun with choice in the program. You can have your program respond to the choice that the computer has made. - - Can you finish the code so that it prints 'too bad' when it is your turn and otherwise 'yes!'? - Don't forget the quotes! - example_code: "```\npeople {is} mom, dad, Emma, Sophie\ndishwasher {is} people {at} {random}\n{if} dishwasher {is} Sophie {print} _ too bad I have to do the dishes _ \n{else} {print} 'luckily no dishes because' _ 'is already washing up'\n```\n" + Са `{if}` сада можете имати више забаве са избором у програму. Можете учинити да ваш програм одговори на избор који је рачунар направио. + ### Вежба + Можете ли завршити код тако да исписује 'шта штета' када је ваш ред и иначе 'да!'? + Не заборавите наводнике! + example_code: "```\nљуди {is} мама, тата, Ема, Софи\nмашина_за_судове {is} људи {at} {random}\n_ машина_за_судове {is} Софи {print} _ шта штета, морам да перем судове _\n_ {print} 'срећом нема судова јер ' _ ' већ пере судове'\n```\n" 6: story_text: | - How often is everyone going to do the dishes? Is that fair? You can count it in this level. + Колико често ће свако радити судове? Да ли је то фер? Можете то пребројати на овом нивоу. example_code: | ``` - people = mom, dad, Emma, Sophie - emma_washes = 0 - dishwasher = people {at} {random} - {print} 'The dishwasher is' dishwasher - {if} dishwasher {is} Emma emma_washes = emma_washes + 1 - {print} 'Emma will do the dishes this week' emma_washes 'times' + људи = мама, тата, Ема, Софи + ема_пере = 0 + машина_за_судове = људи {at} {random} + {print} 'Машина за судове је' машина_за_судове + {if} машина_за_судове {is} Ема ема_пере = ема_пере + 1 + {print} 'Ема ће радити судове ове недеље' ема_пере 'пута' ``` - Now you can copy lines 3 to 5 a few times (e.g. 7 times for a whole week) to calculate for a whole week again. - Do you make the code for the whole week? + Сада можете копирати линије 3 до 5 неколико пута (нпр. 7 пута за целу недељу) да бисте поново израчунали за целу недељу. + Да ли правите код за целу недељу? story_text_2: | - If you are extremely unlucky the previous program might choose you to to the dishes for the whole week! That's not fair! - To create a fairer system you can use the `{remove}` command to remove the chosen person from the list. This way you don't have to do the dishes again untill everybody has had a turn. + Ако сте изузетно несрећни, претходни програм може вас изабрати да радите судове целе недеље! То није фер! + Да бисте направили праведнији систем, можете користити команду `{remove}` да уклоните изабрану особу са листе. На тај начин не морате поново радити судове док сви не дођу на ред. - Monday and tuesday are ready for you! Can you add the rest of the week? - And... can you come up with a solution for when your list is empty? + Понедељак и уторак су спремни за вас! Можете ли додати остатак недеље? + И… можете ли смислити решење за када је ваша листа празна? example_code_2: | ``` - people = mom, dad, Emma, Sophie - dishwasher = people {at} {random} - {print} 'Monday the dishes are done by: ' dishwasher - {remove} dishwasher {from} people - dishwasher = people {at} {random} - {print} 'Tuesday the dishes are done by: ' dishwasher - {remove} dishwasher {from} people - dishwasher = people {at} {random} + људи = мама, тата, Ема, Софи + машина_за_судове = људи {at} {random} + {print} 'Понедељак судове ради: ' машина_за_судове + {remove} машина_за_судове {from} људи + машина_за_судове = људи {at} {random} + {print} 'Уторак судове ради: ' машина_за_судове + {remove} машина_за_судове {from} људи ``` 7: story_text: | - With the `{repeat}` you can repeat pieces of code. You can use this to calculate who will be washing dishes for multiple days! - ### Exercise - Use the `{repeat}` command to decide on who needs to wash the dishes for an entire week. Each blank needs to be filled with one command or number! - **(extra)** Can you think of other tasks in the house? Adapt the code so it decides on three household chores. Do not forget to print what tasks it concerns! + Са `{repeat}` можете понављати делове кода. Можете користити ово да израчунате ко ће прати судове више дана! + ### Вежба + Користите команду `{repeat}` да одлучите ко треба да пере судове целе недеље. Сваки празан простор треба да буде попуњен једном командом или бројем! + **Додатно** Можете ли смислити друге задатке у кући? Прилагодите код тако да одлучује о три кућна посла. Не заборавите да испишете о којим задацима се ради! example_code: | ``` - people = mom, dad, Emma, Sophie - {repeat} _ _ {print} 'Dishwashing will be done by ' _ _ _ + људи = мама, тата, Ема, Софи + {repeat} _ _ {print} 'Судове ће радити ' _ _ _ ``` 10: story_text: | - In this level you can make a schedule for the whole week in an easy way! + На овом нивоу можете направити распоред за целу недељу на једноставан начин! - ### Exercise - Add a second chore, such as vacuuming or tidying up, and make sure it is also divided for the whole week. -
**(extra)** The program is not fair, you can be unlucky and wash up all week. How could you make the program more fair? + ### Вежба + Додајте други задатак, као што је усисавање или поспремање, и уверите се да је и он распоређен за целу недељу. +
**Додатно** Програм није фер, можете бити несрећни и прати судове целе недеље. Како бисте могли учинити програм праведнијим? example_code: | ``` - days = Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday - names = mom, dad, Emma, Sophie - {for} day {in} days - {print} names {at} {random} ' does the dishes on ' day + дани = Понедељак, Уторак, Среда, Четвртак, Петак, Субота, Недеља + имена = мама, тата, Ема, Софи + {for} дан {in} дани + {print} имена {at} {random} ' ради судове у ' дан ``` elif_command: name: '{elif}' default_save_name: elif - description: elif + description: '{elif}' levels: 17: story_text: | - In this level you can also use a new command: `{elif}`. `{elif}` is a combination of the keywords `{else}` and `{if}` and you need it when you want to make 3 (or more!) options. - Check it out! + У овом нивоу можеш користити и нову команду: `{elif}`. `{elif}` је комбинација кључних речи `{else}` и `{if}` и потребна ти је када желиш да направиш 3 (или више!) опција. + Пробај! example_code: | ``` - prices = ['1 million dollars', 'an apple pie', 'nothing'] - your_price = prices[{random}] - {print} 'You win ' your_price - {if} your_price == '1 million dollars' : - {print} 'Yeah! You are rich!' - {elif} your_price == 'an apple pie' : - {print} 'Lovely, an apple pie!' + награде = ['1 милион долара', 'пита од јабука', 'ништа'] + твоја_наградa = награде[{random}] + {print} 'Освојио си ' твоја_наградa + {if} твоја_наградa == '1 милион долара' : + {print} 'Да! Богат си!' + {elif} твоја_наградa == 'пита од јабука' : + {print} 'Дивно, пита од јабука!' {else}: - {print} 'Better luck next time..' + {print} 'Више среће следећи пут..' ``` for_command: name: '{for}' - default_save_name: for - description: for command + default_save_name: за + description: '{for} команда' levels: 10: story_text: |- ## For - In this level we learn a new code called `{for}`. With `{for}` you can make a list and use all elements. - `{for}` creates a block, like `{repeat}` and `{if}` so all lines in the block need to start with 4 spaces. + У овом нивоу учимо нови код под називом `{for}`. Са `{for}` можеш направити листу и користити све елементе. + `{for}` ствара блок, као `{repeat}` и `{if}`, тако да све линије у блоку морају почети са 4 празна простора. example_code: | ``` - animals = dog, cat, blobfish - {for} animal {in} animals - {print} 'I love ' animal + животиње = пас, мачка, blobfish + {for} животиња {in} животиње + {print} 'Волим ' животиња ``` story_text_2: | - ### Exercise - Finish this code by adding `{for} action {in} actions` to line 2. + ### Вежба + Завршите овај код додавањем `{for} action {in} actions` на линију 2. example_code_2: | ``` actions = clap your hands, stomp your feet, shout Hurray! _ {repeat} 2 {times} - {print} 'If youre happy and you know it, ' action + {print} 'Ако си срећан и знаш то, ' action {sleep} 2 - {print} 'If youre happy and you know it, and you really want to show it' - {print} 'If youre happy and you know it, ' action + {print} 'Ако си срећан и знаш то, и стварно желиш да покажеш' + {print} 'Ако си срећан и знаш то, ' action {sleep} 3 ``` 11: story_text: |- - U ovom nivou, dodajemo novi oblik za `{for}`. U ranijim nivoima, koristili smo `{for}` sa listom, ali `{for}` možemo koristiti i sa brojevima. - To radimo tako što dodamo ime promenljivoj, i u nastavku dodamo `{in}` `{range}`. Onda napišemo broj sa kojim ćemo početi, `{to}` i broj sa kojim ćemo završiti. + У овом нивоу додајемо нови облик `{for}`. У ранијим нивоима користили смо `{for}` са листом, али можемо користити `{for}` и са бројевима. + То радимо тако што додамо име променљиве, након чега следи `{in}` `{range}`. Затим пишемо број од којег почињемо, `{to}` и број до којег завршавамо. - Probaj u primeru i vidi sta će se desiti! I u ovom nivou ćeš morati da koristiš uvučene redove za sve linije koje dodju ispod `{for}` izjave. + Пробај пример да видиш шта се дешава! У овом нивоу опет ћеш морати да користиш увлачења у линијама испод `{for}` изјава. example_code: | ``` - {for} counter {in} {range} 1 {to} 10 - {print} counter - {print} 'Ready or not. Here I come!' + {for} бројач {in} {range} 1 {to} 10 + {print} бројач + {print} 'Спреман или не. Ево ме!' ``` 17: story_text: | - Now we are going to change indentation a little bit. Every time that we need an indentation, we need `:` at the line before the indentation. + Сада ћемо мало променити увлачење. Сваки пут када нам треба увлачење, потребан нам је `:` на линији пре увлачења. example_code: | ``` {for} i {in} {range} 1 {to} 10: {print} i - {print} 'Ready or not, here I come!' + {print} 'Спреман или не, ево ме!' ``` 18: story_text: | - Lastly, we'll turn `{for} i {in} {range} 1 to 5` into real Python code, like this: + На крају, претворићемо `{for} i {in} {range} 1 to 5` у прави Python код, овако: example_code: | ``` {for} i {in} {range}(1,5): {print} (i) ``` fortune: - name: Fortune teller - default_save_name: Fortune Teller - description: Let Hedy predict the future + name: Пророчанство + default_save_name: Пророчанство + description: Нека Хеди предвиди будућност levels: 1: story_text: | - Have you ever been to a carnival and had your future predicted by a fortune teller? Or have you ever played with a magic eight ball? - Then you probably know that they can't really predict your future, but it's still fun to play! + Да ли сте икада били на карневалу и да вам је пророк предвидео будућност? Или сте икада играли са магичном осмицом? + Тада вероватно знате да они не могу стварно предвидети вашу будућност, али је ипак забавно играти! - In the upcoming levels you can learn how to create your own fortune telling machine! - In level 1 you can start off easy by letting Hedy introduce herself as a fortune teller and let her {echo} the players' answers. - Like this: + У наредним нивоима можете научити како да направите своју машину за предвиђање будућности! + На нивоу 1 можете почети лако тако што ћете дозволити Хеди да се представи као пророк и да `{echo}` одговоре играча. + Овако: example_code: | ``` - _ Hello, I'm Hedy the fortune teller! - _ Who are you? - _ Let me take a look in my crystal ball - _ I see... I see... - _ Your name is + _ Здраво, ја сам Хеди пророк! + _ Ко си ти? + _ Дозволи ми да погледам у моју кристалну куглу + _ Видим... Видим... + _ Твоје име је ``` story_text_2: | - ### Exercise - Copy the example code into your inputscreen and fill in the blanks to make the code work. - **Extra** Change the code and let the fortune teller not only predict your name, but also your age, your favorite sports team or something else about yourself. + ### Вежба + Копирајте пример кода у свој улазни екран и попуните празнине да би код функционисао. + **Додатно** Промените код и дозволите пророку да не само предвиди ваше име, већ и вашу старост, ваш омиљени спортски тим или нешто друго о вама. 3: story_text: | - In the previous levels you've created your first fortune telling machine, but Hedy couldn't really predict anything, only {echo}. - In this level you can use a variable and the `{at} {random}` command to really let Hedy choose an answer for you. Check out this code for instance: + На претходним нивоима сте направили своју прву машину за предвиђање будућности, али Хеди није могла стварно ништа предвидети, само `{echo}`. + На овом нивоу можете користити променљиву и команду `{at} {random}` да стварно дозволите Хеди да изабере одговор за вас. Погледајте овај код на пример: example_code: | ``` - {print} I’m Hedy the fortune teller! - question {is} {ask} What do you want to know? - {print} This is what you want to know: question - answers {is} yes, no, maybe - {print} My crystal ball says... + {print} Ја сам Хеди пророк! + question {is} {ask} Шта желите да знате? + {print} Ово је оно што желите да знате: question + answers {is} да, не, можда + {print} Моја кристална кугла каже... {sleep} 2 {print} answers {at} {random} ``` story_text_2: | - ### Exercise - Now, Hedy can only answer yes, no or maybe. Can you give Hedy more answer options, like 'definitely' or 'ask again'. + ### Вежба + Сада, Хеди може одговорити само да, не или можда. Можете ли дати Хеди више опција за одговоре, као што су 'дефинитивно' или 'питај поново'. 4: story_text: | - ### Exercise - We have removed all the quotation marks from this example code, can you add them in all the right places? + ### Вежба + Уклонили смо све наводнике из овог пример кода, можете ли их додати на сва права места? - ### Exercise 2 - Go back to the previous level and copy your fortune teller code. Make the code work in this level by adding quotation marks in the right spots. + ### Вежба 2 + Вратите се на претходни ниво и копирајте ваш код за гатара. Учини да код ради на овом нивоу додавањем наводника на права места. example_code: | ``` - _ Add the quotation marks to this code _ + _ Додајте наводнике у овај код _ {print} Im Hedy the fortune teller! question {is} {ask} What do you want to know? {print} This is your question: question @@ -1798,131 +1815,132 @@ adventures: ``` 5: story_text: | - In this level you'll learn to (secretly) tip the odds in your favor, when using the fortune teller! - By using `{if}` and `{else}` you can make sure that you will always get a good fotune, while other people might not. - Check out this example to find out how. + ### Вежба + У пример коду видите како да направите програм за гатара који вам омогућава да нагнете шансе у своју корист. Овај варајући програм вам увек каже да ћете освојити лутрију, али ваши пријатељи никада неће победити. + + Искористите ово да направите свој програм, будите креативни! На пример, могли бисте направити код који предвиђа да: + * ваш омиљени спортски тим победи све конкуренте! + * ваш омиљени филм буде изабран за филмску ноћ! + * освојите карте за ваш омиљени шоу! + * ви сте најлепши од свих, као магично огледало Снежане. + Нека ваша машта ради! + + Ваш програм мора да садржи најмање 10 линија кода и мора да има најмање једну `{if}` и `{else}` команду. example_code: | ``` - {print} 'Im Hedy the fortune teller!' - {print} 'I can predict if youll win the lottery tomorrow!' - person {is} {ask} 'Who are you?' - {if} person {is} Hedy {print} 'You will definitely win!🤩' {else} {print} 'Bad luck! Someone else will win!😭' + friends {is} Џордан, Луси, Дејв + {print} 'Могу предвидети да ли ћете сутра освојити лутрију!' + person {is} {ask} 'Ко си ти?' + good_answer {is} Ура! Побеђујеш!, Дефинитивно ћеш победити!, Имамо победника! + bad_answer {is} Лоша срећа! Покушај поново!, Други ће победити, Губиш! + {if} person {in} friends {print} good_answer {at} {random} + {else} {print} bad_answer {at} {random} ``` 6: story_text: | - In this level you can use math in your predictions as a fortune teller. This allows you to make up (silly) formulas to calculate the future. - For example you could calculate how rich you'll get or how many kids you will have when you grow up. + На овом нивоу можете користити математику у својим предвиђањима као пророк. Ово вам омогућава да измислите (смешне) формуле за израчунавање будућности. + На пример, можете израчунати колико ћете се обогатити или колико ћете деце имати када одрастете. - ### Exercise - Can you think of your own (silly) fortune telling machine? + ### Вежба + Можете ли смислити своју (смешну) машину за предвиђање будућности? example_code: | ``` - {print} 'I am Hedy the fortune teller!' - {print} 'I can predict how many kids youll get when you grow up!' - age = {ask} 'How old are you?' - siblings = {ask} 'How many siblings do you have?' - length = {ask} 'How tall are you in centimetres?' + {print} 'Ја сам Хеди пророк!' + {print} 'Могу предвидети колико ћете деце имати када одрастете!' + age = {ask} 'Колико имаш година?' + siblings = {ask} 'Колико браће и сестара имаш?' + length = {ask} 'Колико си висок у центиметрима?' kids = length / age kids = kids - siblings - {print} 'You will get ...' + {print} 'Имаћеш ...' {sleep} - {print} kids ' kids!' - ``` - - If the previous example wasn't silly enough for you, take a look at this one! - ``` - {print} 'Im Hedy the silly fortune teller!' - {print} 'I will predict how smart you are!' - football = {ask} 'On a scale 1-10 how much do you love football?' - bananas = {ask} 'How many bananas did you eat this week?' - hygiene = {ask} 'How many times did you wash your hands today?' - result = bananas + hygiene - result = result * football - {print} 'You are ' result ' percent smart.' + {print} kids ' деце!' ``` 7: story_text: | - In this level you can use the `{repeat}` command to make your machine tell multiple fortunes at once. + ### Вежба + Завршите овај програм који вам говори да ли вас ваша симпатија воли или не. example_code: | ``` - {print} 'Im Hedy the fortune teller!' - {print} 'You can ask 3 questions!' - {repeat} 3 {times} question = {ask} 'What do you want to know?' - answer = yes, no, maybe - {repeat} 3 {times} {print} 'My crystal ball says... ' answer {at} {random} + {print} 'Имам цвет са магичним латицама' + {print} 'Ако уберете латице, цвет ће вам рећи да ли вас ваша симпатија воли' + amount = {ask} 'Колико латица желите да уберете?' + options = они те воле, они те не воле + _ _ _ _ options {at} {random} ``` 8: story_text: | - In the previous levels you've learned how to use `{repeat}` to make the fortune teller answer 3 questions in a row, but we had a problem with printing the questions. - Now that problem is solved, because of the new way of using the `{repeat}` command. - In the next example you can have your fortune teller ask 3 questions and also print them! + У следећем примеру можете дозволити свом пророку да постави више питања и такође их прикаже! - ### Exercise - Can you fill in right command on the blanks? + ### Вежба + Можете ли попунити праву команду на празним местима? example_code: | ``` - {print} 'I am Hedy the fortune teller!' - {print} 'You can ask me 3 questions.' - answers = yes, no, maybe + {print} 'Ја сам Хеди пророк!' + {print} 'Можете ми поставити 3 питања.' + answers = да, не, можда _ _ _ - question = {ask} 'What do you want to know?' + question = {ask} 'Шта желите да знате?' {print} question {sleep} - {print} 'My crystal ball says...' answers {at} {random} + {print} 'Моја кристална кугла каже... ' answers {at} {random} ``` 10: story_text: | - In this level you'll learn how to program the game MASH (mansion, apartment, shack, house). In this game you can predict for all the players at once, what their future will look like. + На овом нивоу ћете научити како да програмирате игру MASH (вила, стан, колиба, кућа). У овој игри можете предвидети за све играче одједном како ће изгледати њихова будућност. - ### Exercise 1 - Add two names to the list and see how the output of the program changes when you run it. + ### Вежба + Попуните празнине користећи нову команду коју сте научили на овом нивоу. example_code: | ``` - houses = mansion, apartment, shack, house - loves = nobody, a royal, their neighbour, their true love - pets = dog, cat, elephant - names = Jenna, Ryan, Jim - {for} name {in} names - {print} name ' lives in a ' houses {at} {random} - {print} name ' will marry ' loves {at} {random} - {print} name ' will get a ' pets {at} {random} ' as their pet.' + houses = вила, стан, колиба, кућа + loves = нико, краљевска особа, њихов комшија, њихова права љубав + pets = пас, мачка, слон + names = Џена, Рајан, Џим + _ + {print} name ' живи у ' houses {at} {random} + {print} name ' ће се удати за ' loves {at} {random} + {print} name ' ће добити ' pets {at} {random} ' као свог љубимца.' {sleep} ``` 12: - story_text: | - In this level you can make your fortunes multiple words. Can you add more different fortunes to the list? + story_text: |- + Од нивоа 12, такође ћете морати да користите наводнике у листама, пре и после сваке ставке. + + ### Вежба + Додајте две предвиђања на листу example_code: | ``` - fortunes = 'you will slip on a banana peel', _ - {print} 'I will take a look in my crystall ball for your future.' - {print} 'I see... I see...' + fortunes = 'пашћеш на кору од банане', _ + {print} 'Погледаћу у своју кристалну куглу за твоју будућност.' + {print} 'Видим... Видим...' {sleep} {print} fortunes {at} {random} ``` functions: - name: functions - default_save_name: functions - description: functions + name: функције + default_save_name: функције + description: функције levels: 12: story_text: | - In this level you'll learn how to use **functions**. A function is a block of code you can easily use multiple times. Using functions helps us organize pieces of code that we can use again and again. - To create a function, use `{define}` and give the function a name. Then put all the lines you want in the function in a indented block under the `{define}` line. - Leave one empty line in your code to make it look nice and neat. Great job! You have created a function! + На овом нивоу ћеш научити како да користиш **функције**. Функција је блок кода који можеш лако користити више пута. Коришћење функција нам помаже да организујемо делове кода које можемо користити изнова и изнова. + Да би креирао функцију, користи `{define}` и дај функцији име. Затим стави све линије које желиш у функцију у увучени блок испод линије `{define}`. + Остави једну празну линију у свом коду да би изгледао лепо и уредно. Одличан посао! Креирао си функцију! - Now, whenever we need that block of code, we just use {call} with the function's name to call it up! We don't have to type that block of code again. + Сада, кад год нам треба тај блок кода, само користимо {call} са именом функције да га позовемо! Не морамо поново да куцамо тај блок кода. - Check out this example code of a game of Twister. The function 'turn' contains a block of code that chooses which limb should go where. + Погледај овај пример кода игре Twister. Функција 'turn' садржи блок кода који бира који уд треба да иде где. - ### Exercise - Finish this code by setting the 2 variables chosen_limb and chosen_color. - Then, choose how many times you want to call the function to give the twister spinner a spin. + ### Вежба + Заврши овај код постављањем 2 променљиве chosen_limb и chosen_color. + Затим, изабери колико пута желиш да позовеш функцију да би дао Twister спинеру окрет. - ### Exercise 2 - Improve your code by adding a variable called 'people'. Use the variable to give all the players their own command in the game. - For example: 'Ahmed, right hand on green' or 'Jessica, left foot on yellow'. + ### Вежба 2 + Побољшај свој код додавањем променљиве зване 'people'. Користи променљиву да би свим играчима дао своју команду у игри. + На пример: 'Ахмед, десна рука на зелено' или 'Џесика, лева нога на жуто'. example_code: | ``` sides = 'left', 'right' @@ -1936,54 +1954,56 @@ adventures: {print} chosen_side ' ' chosen_limb ' on ' chosen_color {print} 'Lets play a game of Twister!' - {for} i {in} {range} 1 to _ + {for} i {in} {range} 1 {to} _ {call} turn {sleep} 2 ``` 13: story_text: | - Now that you've learned how to use functions, you'll learn how to use a function with an argument. - An **argument** is a variable that is used within a function. It is not used outside the function. + Сада када си научио како да користиш функције, научићеш како да користиш функцију са аргументом. + Аргумент је променљива која се користи унутар функције. Не користи се ван функције. - For example in this code we've programmed the first verse of the song 'My Bonnie is over the ocean'. - In this example code the argument `place` is used. Place is a variable that is only used in the function, so an argument. - To use `place` we have programmed the line `define song with place`. - When the function is called, computer will replace the argument `place`, with the piece of text after `call song with`. + На пример, у овом коду смо програмирали први стих песме 'My Bonnie is over the ocean'. + У овом примеру кода користи се аргумент 'place'. Place је променљива која се користи само у функцији, дакле аргумент. + Да бисмо користили 'place', поставили смо `{with} place` након `{define} song`. + Када се функција позове, рачунар ће заменити аргумент 'place' са делом текста након `{call} song {with}`. - ### Exercise - The next verse of this song goes: + ### Вежба + Следећи стих ове песме гласи: - Last night as I lay on my pillow - Last night as I lay on my bed - Last night as I lay on my pillow - I dreamed that my Bonnie is dead + ```not_hedy_code + Синоћ док сам лежао на јастуку + Синоћ док сам лежао у кревету + Синоћ док сам лежао на јастуку + Сањао сам да је мој Бони мртав + ``` - Can you program this verse in the same way as the example? + Можеш ли програмирати овај стих на исти начин као у примеру? example_code: | ``` - {define} song {with} place - {print} 'My Bonnie is over the ' place + {define} песма {with} место + {print} 'Мој Бони је преко ' место - {call} song {with} 'ocean' - {call} song {with} 'sea' - {call} song {with} 'ocean' + {call} песма {with} 'океана' + {call} песма {with} 'мора' + {call} песма {with} 'океана' ``` 14: story_text: | - In the previous levels you have learned to create functions and use arguments with them. Another great use of a function is to let it calculate something for you. - You can give the function a calculation and it will give you the answer of the calculation. This answer is called a **return value**. + На претходним нивоима научили сте да креирате функције и користите аргументе са њима. Још једна сјајна употреба функције је да јој дозволите да нешто израчуна за вас. + Можете дати функцији прорачун и она ће вам дати одговор прорачуна. Овај одговор се зове **враћена вредност**. - For example, in this code the function calculate_new_price will calculate the new price of any item. It will give you the new price as a return value. + На пример, у овом коду функција calculate_new_price ће израчунати нову цену било ког предмета. Она ће вам дати нову цену као враћену вредност. - ### Exercise - Finish this code. We have already made the variable new_price for you, you only need to set it. - You should finish the line of code by calling the function that calculates the new price. + ### Вежба + Завршите овај код. Већ смо направили променљиву new_price за вас, само треба да је подесите. + Треба да завршите линију кода позивањем функције која израчунава нову цену. example_code: | ``` {define} calculate_new_price {with} amount, percentage percentage = percentage / 100 discount_amount = amount * percentage - return amount - discount_amount + {return} amount - discount_amount old_price = {ask} 'How much is on the price tag?' discount = {ask} 'What percentage is the discount?' @@ -1993,17 +2013,17 @@ adventures: ``` 18: story_text: | - Let's make functions the Pythons way! To define a function, we no longer use: + Хајде да направимо функције на Python начин! Да бисмо дефинисали функцију, више не користимо: `{define} name_function {with} argument_1, argument_2:` - but we use: + већ користимо: `{def} name_function(argument_1, argument_2):`. - If you don't want to use arguments, you just leave the space between the parantheses empty. - To call a function, we don't need the `{call}` command anymore. You just type the name of the function. + Ако не желиш да користиш аргументе, једноставно остави простор између заграда празан. + Да би позвао функцију, више нам није потребна команда `{call}`. Само укуцај име функције. example_code: | ``` {def} calculate_score(answer, correct_answer): @@ -2021,153 +2041,153 @@ adventures: {print} ('Your score is... ', score) ``` guess_my_number: - name: Guess my number - default_save_name: guess my number - description: guess my number + name: Погоди мој број + default_save_name: погоди мој број + description: погоди мој број levels: 14: story_text: | - In this level you can program the game 'Guess my number' + На овом нивоу можете програмирати игру 'Погоди мој број' - ### Exercise - Fill in the correct symbols on the blanks to get the game to work. + ### Вежба + Попуните исправне симболе на празним местима да би игра функционисала. example_code: | ``` - {print} 'Guess my number' + {print} 'Погоди мој број' numbers = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 number = numbers {at} {random} game = 'on' {for} i {in} {range} 1 {to} 10 {if} game == 'on' - guess = {ask} 'Which number do you think it is?' + guess = {ask} 'Који број мислите да је?' {if} guess _ number - {print} 'Lower!' + {print} 'Мање!' {if} guess _ number - {print} 'Higher!' + {print} 'Више!' {if} guess _ number - {print} 'You win!' + {print} 'Победили сте!' game = 'over' ``` hangman: - name: Hangman - default_save_name: Hangman - description: Guess the word + name: Вешала + default_save_name: Вешала + description: Погоди реч levels: 17: story_text: | - In this adventure we program a game of hangman. First we make some preparations, then we program the game and in the third part we add a drawing with the turtle. + У овој авантури програмирамо игру вешала. Прво правимо неке припреме, затим програмирамо игру и у трећем делу додајемо цртеж са корњачом. - ### Exercise - ***Set the variables*** In this game of hangman, Player 1 chooses an answer and Player 2 has to guess the letters in this answer. - To let the computer know all the letters in the word, we will turn the answer into a list of letters. We also do this with the guesses Player 2 makes. - We will start the game with 2 empty lists. We have made an empty list for the variable answer for you. Now make an empty list for guessed_letters as well. - Then we fill in how many mistakes were made. At the start of the game, this should be 0. - The variable `amount_letters` tells us how many letters are in the answer. Ask Player 1 to tell us how many letters their word has. - Lastly we tell the computer if the game is over. We use the variable `game_over` and set it to `False`. + ### Вежба + ***Поставите променљиве*** У овој игри вешала, Играч 1 бира одговор, а Играч 2 мора да погоди слова у том одговору. + Да бисмо рачунару дали до знања сва слова у речи, претворићемо одговор у листу слова. То радимо и са погађањима која Играч 2 прави. + Почећемо игру са 2 празне листе. Направили смо празну листу за променљиву одговор за вас. Сада направите празну листу и за погађана_слова. + Затим попуњавамо колико је грешака направљено. На почетку игре, ово би требало да буде 0. + Променљива `amount_letters` нам говори колико слова има у одговору. Питајте Играч 1 да нам каже колико слова има њихова реч. + На крају кажемо рачунару да ли је игра завршена. Користимо променљиву `game_over` и постављамо је на `False`. - ***Choosing the answer*** We want Player 1 to be able to choose the answer. We'll ask them, as many times as necessary, what the next letter is. - Then we add that letter to the answer. Lastly, we add an empty _ to the list of guessed letters, so we get as many _s as there are letters in the answer. + ***Бирање одговора*** Желимо да Играч 1 може да изабере одговор. Питаћемо их, колико год пута је потребно, које је следеће слово. + Затим додајемо то слово у одговор. На крају, додајемо празно _ у листу погађаних слова, тако да добијемо онолико _ колико има слова у одговору. - ***Player 2's turn*** - Tell Player 2 its their turn. Then tell Player 2 how many letters there are in the answer. Finally, print the list of `guessed_letters`. + ***Ред Играч 2*** + Реците Играч 2 да је њихов ред. Затим реците Играч 2 колико слова има у одговору. На крају, одштампајте листу `guessed_letters`. - ***Go to the next tab*** Now that all the starting variables are set, we can start programming the game itself. Check out the next tab to learn how! + ***Идите на следећу картицу*** Сада када су све почетне променљиве постављене, можемо почети са програмирањем саме игре. Погледајте следећу картицу да научите како! example_code: | ``` - print 'Hangman!' + print 'Вешала!' - # Set the variables - answer = [] - guessed_letters = _ - mistakes_made = _ - amount_letters = {ask} _ - _ = 'False' + # Поставите променљиве + одговор = [] + погађана_слова = _ + направљене_грешке = _ + број_слова = {ask} _ + игра_завршена = 'False' - # Choosing the answer + # Бирање одговора {for} _ - letter = {ask} 'Player 1, what is letter ' i '?' + слово = {ask} 'Играч 1, које је слово ' i '?' _ {add} '_' {to} _ - # Player 2 turn + # Ред Играч 2 print _ print _ - print guessed_letters + print погађана_слова ``` hangman_2: - name: Hangman 2 - default_save_name: Hangman_2 - description: Hangman 2 + name: Вешала 2 + default_save_name: Вешала_2 + description: Вешала 2 levels: 17: story_text: | - Now it's time to program the hangman game. + Сада је време да програмирамо игру вешала. - ### Exercise + ### Вежба - ***Paste your code*** Copy your code from the previous tab and paste the code in the programming field. + ***Налепите свој код*** Копирајте свој код са претходне картице и налепите код у поље за програмирање. - ***The game*** This games continues playing until Player 2 is game over. Fill in the while command accordingly. Now, Player 2 is allowed to guess a letter, so ask Player 2 to guess a letter. - We need to check if their answer is correct, so check if their `guess` is (somewhere) in the (list) `answer`. Then we let the computer figure out which of the letter(s) is the guess. We have already programmed that part for you. - Next we want to compliment the player for finding a correct letter and we want to print the list `guessed_letters`, so the player can see their progress. + ***Игра*** Ова игра се наставља док Играч 2 не изгуби. Попуните команду while у складу с тим. Сада, Играч 2 може да погоди слово, па питајте Играч 2 да погоди слово. + Треба да проверимо да ли је њихов одговор тачан, па проверите да ли је њихово `guess` (негде) у (листи) `answer`. Затим ћемо дозволити рачунару да утврди које је слово погађање. Тај део смо већ програмирали за вас. + Следеће, желимо да похвалимо играча за проналажење тачног слова и желимо да одштампамо листу `guessed_letters`, тако да играч може видети свој напредак. - The next part we're going to program is what happens when the player has guessed all of the letters. So if their list of `guessed_letters` is the same as our list `answer`. - If the lists are the same, congratulate Player 2 with their victory and set the variable `game_over` to `True`. + Следећи део који ћемо програмирати је шта се дешава када играч погоди сва слова. Дакле, ако је њихова листа `guessed_letters` иста као наша листа `answer`. + Ако су листе исте, честитајте Играч 2 на победи и поставите променљиву `game_over` на `True`. - Next we'll program what happens when Player 2 guesses wrong (so the `{else}` command). First, tell the player that their guess was wrong. Then increase the `mistakes_made` variable by 1. + Затим ћемо програмирати шта се дешава када Играч 2 погреши (тако да команда `{else}`). Прво, реците играчу да је њихово погађање погрешно. Затим повећајте променљиву `mistakes_made` за 1. - For the last part we'll program what happens when Player 2 has made 10 mistakes. We'll print that Player 1 has won the game. Then we'll print the correct answer. And finally, we'll set our `game_over` variable to `True`, so the game stops. + За последњи део ћемо програмирати шта се дешава када Играч 2 направи 10 грешака. Одштампаћемо да је Играч 1 победио у игри. Затим ћемо одштампати тачан одговор. И на крају, поставићемо нашу променљиву `game_over` на `True`, тако да се игра зауставља. - ***Go to the next tab*** Amazing work! Your game is playable, but wouldn't it be fun if the hangman was actually drawn when Player 2 makes a mistake..? + ***Идите на следећу картицу*** Сјајан рад! Ваша игра је играва, али зар не би било забавно да се вешала заправо цртају када Играч 2 направи грешку..? example_code: | ``` - # Paste your code here + # Налепите свој код овде - # The game - {while} game_over _ - guess = _ + # Игра + {while} игра_завршена _ + погађање = _ {if} _ - {for} i {in} {range} 1 {to} amount_letters: - if answer[i] == guess: - guessed_letters[i] = guess + {for} i {in} {range} 1 {to} број_слова: + if одговор[i] == погађање: + погађана_слова[i] = погађање {print} _ - {if} guessed_letters == _: + {if} погађана_слова == _: {print} _ - game_over = _ + игра_завршена = _ {else}: {print} _ - mistakes_made _ + направљене_грешке _ {if} _ == 10: {print} _ {print} _ _ ``` hangman_3: - name: Hangman 3 - default_save_name: Hangman_3 - description: Hangman 3 + name: Вешала 3 + default_save_name: Вешала_3 + description: Вешала 3 levels: 17: story_text: | - In a game of hangman the mistakes are shown by drawing a part of the hangman each time a mistake has been made. - We now add those drawings with our turtle! + У игри вешала, грешке се приказују цртањем дела вешала сваки пут када се направи грешка. + Сада додајемо те цртеже са нашом корњачом! - ### Exercise - ***Create a function that draws the hangman*** Create a function that draws the hangman in 10 steps. We have already made step 1 for you. + ### Вежба + ***Направите функцију која црта вешала*** Направите функцију која црта вешала у 10 корака. Већ смо направили корак 1 за вас. - ***Test the function*** Test the function by calling the function with 10. If you are happy with the function, remove the line that calls the function for now. We will call the function when the player makes a mistake. + ***Тестирајте функцију*** Тестирајте функцију позивањем функције са 10. Ако сте задовољни функцијом, уклоните линију која позива функцију за сада. Позваћемо функцију када играч направи грешку. - ***Paste your hangman game under your function*** Go back to the previous tab and copy your hangman game. Paste the game underneath your function. + ***Налепите своју игру вешала испод своје функције*** Вратите се на претходну картицу и копирајте своју игру вешала. Налепите игру испод своје функције. - ***Call the function when the player makes a mistake*** Under the line `mistakes_made = mistakes_made + 1` we will call the function. We want the turtle to take the same amount of steps as the player has made mistakes, so we call the function with `mistakes_made` as argument. + ***Позовите функцију када играч направи грешку*** Испод линије `mistakes_made = mistakes_made + 1` позваћемо функцију. Желимо да корњача направи исти број корака колико је играч направио грешака, па позивамо функцију са `mistakes_made` као аргументом. - ***Enjoy your game!*** + ***Уживајте у својој игри!***
- The hangman could look like this + Вешала могу изгледати овако
example_code: | ``` - # Create a function that draws the hangman + # Направите функцију која црта вешала {define} draw_hangman {with} step: {if} step == 1: {color} white @@ -2180,64 +2200,64 @@ adventures: {if} step == 2: _ - # Paste your hangman game here + # Налепите своју игру вешала овде ``` harry_potter: - name: Harry Potter - default_save_name: Harry Potter - description: Harry Potter adventures + name: Хари Потер + default_save_name: Хари Потер + description: Авантуре Хари Потера levels: 10: story_text: | - ### Exercise - We can also make a Harry Potter themed fortune teller. Fill in blanks such that 9 lines are printed. - **Extra** Change the theme of the fortune teller into something else, such as your favorite book, film or tv show. + ### Вежба + Можемо направити и прорицање судбине са темом Хари Потера. Попуни празнине тако да се одштампа 9 линија. + **Додатно** Промени тему прорицања судбине у нешто друго, као што је твоја омиљена књига, филм или ТВ емисија. example_code: | ``` - houses = Gryffindor, Slytherin, Hufflepuff, Ravenclaw - subjects = potions, defence against the dark arts, charms, transfiguration - fears = Voldemort, spiders, failing your OWL test - names = Harry, Ron, Hermione + куће = Грифиндор, Слитерин, Хафлпаф, Рејвенкло + предмети = напици, одбрана од мрачних вештина, чаролије, трансфигурација + страхови = Волдеморт, пауци, неуспех на ОВЛ тесту + имена = Хари, Рон, Хермиона _ - _ {print} name ' is placed in ' houses {at} {random} - _ {print} name ' is great at ' subjects {at} {random} - _ {print} name 's greatest fear is ' fears {at} {random} + _ {print} име ' је распоређен у ' куће {at} {random} + _ {print} име ' је одличан у ' предмети {at} {random} + _ {print} име ' највећи страх је ' страхови {at} {random} ``` haunted: - name: Haunted House - default_save_name: Haunted House - description: Escape from the haunted house + name: Уклети дом + default_save_name: Уклети дом + description: Побегни из уклетог дома levels: 1: story_text: | - In this adventure you are working towards making a game in which you have to escape from a haunted house by picking the correct door. - If you pick the right door you'll survive, but if not a terrible monster might... + У овој авантури радите на прављењу игре у којој морате побећи из уклетог дома одабиром правих врата. + Ако изаберете права врата, преживећете, али ако не, страшно чудовиште би могло... - In level 1 we start our haunted house game by making up a scary story and ask the player what monster they'll see in the haunted house. + На нивоу 1 почињемо нашу игру уклетог дома тако што ћемо смислити страшну причу и питати играча које чудовиште ће видети у уклетом дому. example_code: | ``` - {print} How did I get here? - {print} I remember my friend telling me to go into the old mansion... - {print} and suddenly everything went black. - {print} But how did I end up on the floor...? - {print} My head hurts like Ive been hit by a baseball bat! - {print} What's that sound? - {print} Oh no! I feel like Im not alone in this house! - {print} I need to get out of here! - {print} There are 3 doors in front of me.. - {ask} Which door should i pick? - {echo} I choose door + {print} Како сам доспео овде? + {print} Сећам се да ми је пријатељ рекао да уђем у стару вилу... + {print} и одједном је све постало црно. + {print} Али како сам завршио на поду...? + {print} Глава ме боли као да ме је неко ударио бејзбол палицом! + {print} Шта је то звук? + {print} О не! Осећам као да нисам сам у овој кући! + {print} Морам да изађем одавде! + {print} Испред мене су 3 врата.. + {ask} Која врата треба да изаберем? + {echo} Бирам врата {print} ...? ``` story_text_2: | - ### Exercise - Copy the example code to your input screen by clicking the yellow button. - Now finish the story by adding at least 5 lines of code. - Remember to start each line of codes with a `{print}` command. + ### Вежба + Копирајте пример кода на ваш улазни екран кликом на жуто дугме. + Сада завршите причу додавањем најмање 5 линија кода. + Запамтите да свака линија кода почиње са `{print}` командом. 2: story_text: | - In this haunted house you can choose your monsters with emojis. Of course you could also use words. + У овој уклетој кући можете изабрати своје чудовиште са емоџијима. Наравно, можете користити и речи. example_code: | ``` monster_1 {is} 👻 @@ -2245,14 +2265,15 @@ adventures: monster_3 {is} 👶 {print} You enter the haunted house. {print} Suddenly you see a monster_1 - {print} You run into the other room, but a monster_2 is waiting there for you! + {print} You run into the other room... + {print} But a monster_2 is waiting there for you! {print} Oh no! Quickly get to the kitchen. {print} But as you enter monster_3 attacks you! ``` story_text_2: | - ### Exercise - In the example above the monsters are predetermined. So each time you run your code, the output is the same. - Can you add `{ask}` commands to make the haunted house interactive and have the players choose the monsters they come across? + ### Вежба + У горњем примеру чудовишта су унапред одређена. Тако да сваки пут када покренете свој код, излаз је исти. + Можете ли додати `{ask}` команде да учините уклету кућу интерактивном и да играчи изаберу чудовишта на која наилазе? example_code_2: | ``` monster_1 {is} _ @@ -2260,38 +2281,45 @@ adventures: monster_3 {is} _ {print} You enter the haunted house. {print} Suddenly you see a monster_1 - {print} You run into the other room, but a monster_2 is waiting there for you! + {print} You run into the other room... + {print} But a monster_2 is waiting there for you! {print} Oh no! Quickly get to the kitchen. {print} But as you enter monster_3 attacks you! ``` 3: story_text: | - In the previous levels you've made an introduction to your haunted house game, but as you might have noticed the story would always have a dreadful end. - In this level you can make your story more interactive by changing the outcome of the game; sometimes you'll get eaten, sometimes you'll escape! - Let Hedy decide randomly! + На претходним нивоима направили сте увод у своју игру уклете куће, али као што сте можда приметили, прича би увек имала страшан крај. + На овом нивоу можете учинити своју причу интерактивнијом променом исхода игре; понекад ћете бити поједени, понекад ћете побећи! + Нека Хеди одлучи насумично! + + ### Вежба + Копирајте пример кода и попуните празнине да би функционисао! + + **Додатно** Ова прича је прилично једноставна, можда можете додати мало узбуђења додавањем узбудљивије приче. + Такође, тренутно имате веома ограничене исходе, постоје само 3 опције шта је иза врата. Можда можете смислити више чудовишта да додате на листу! example_code: | ``` - _ Escape from the haunted house! - _ There are 3 doors in front of you... - _ _ _ Which door do you choose? - _ You picked door ... choice - monsters _ a zombie, a vampire, NOTHING YOUVE ESCAPED - _ You see... + _ Побегни из уклете куће! + _ Испред тебе су 3 врата... + _ _ _ Која врата бирате? + _ Изабрао си врата ... choice + monsters _ зомби, вампир, НИШТА, ПОБЕГАО СИ + _ Видиш... {sleep} _ _ _ _ ``` 4: story_text: | - In this level you learn how to use quotation marks in your games. + На овом нивоу учите како да користите наводнике у својим играма. - ### Exercise - Can you make your Haunted House level 4 proof? + ### Вежба + Можете ли учинити свој ниво уклете куће 4 доказаним? - ### Exercise 2 - Go back to the previous level and copy your haunted house code. Make the code work in this level by adding quotation marks in the right spots. + ### Вежба 2 + Вратите се на претходни ниво и копирајте свој код уклете куће. Учини да код ради на овом нивоу додавањем наводника на права места. example_code: | ``` - _ Add quotation marks to this code _ + _ Додајте наводнике у овај код _ {print} Escape from the haunted house! {print} There are 3 doors in front of you... choice {is} {ask} Which door do you choose? @@ -2303,12 +2331,12 @@ adventures: ``` 5: story_text: | - Up until this level the haunted house game always asked the player to choose a door, but as you might have noticed, they didn't really have to answer correctly. - If the player filled in a completely random answer, the game would still work and the player might even win (despite not picking a door). - In this level you can only win the game by picking the same door Hedy picked randomly. + До овог нивоа игра уклете куће увек је тражила од играча да изабере врата, али као што сте можда приметили, нису морали да одговоре тачно. + Ако је играч унео потпуно насумичан одговор, игра би и даље функционисала и играч би можда чак и победио (иако није изабрао врата). + На овом нивоу можете победити у игри само ако изаберете иста врата која је Хеди насумично изабрала. - ### Exercise - Can you find the 4 missing words to complete the code? + ### Вежба + Можете ли пронаћи 4 недостајуће речи да бисте завршили код? example_code: | ``` {print} 'Escape from the haunted house!' @@ -2323,7 +2351,7 @@ adventures: {else} {print} 'Oh no! You are being eaten by a...' monsters {at} {random} ``` 9: - story_text: "In this level you can use nesting, which allows you to make the haunted house even more interactive!\n\n### Exercise\nNow it's very hard to win this game, can you make it easier to win?\nChange your code so it only has one wrong door and two correct doors instead of one correct door and two wrong ones? \nTip: This means changing the variable correct_door into wrong_door, and switching the `{if}` and `{else}` code.\nAnd of course you may also change the story and make it your own. Change the monsters or make it a happy game show where you get a gift!\n" + story_text: "На овом нивоу можете користити угњежђивање, што вам омогућава да учините уклету кућу још интерактивнијом!\n\n### Вежба\nСада је веома тешко победити у овој игри, можете ли је учинити лакшом за победу?\nПромените свој код тако да има само једна погрешна врата и два исправна врата уместо једних исправних врата и два погрешна?\nСавет: Ово значи промену променљиве correct_door у wrong_door и замену `{if}` и `{else}` кода.\nИ наравно, можете променити причу и учинити је својом. Промените чудовишта или направите срећну игру у којој добијате поклон!\n" example_code: | ``` {print} 'Escape from the Haunted House!' @@ -2346,7 +2374,7 @@ adventures: {print} 'Great! You survived!' ``` 11: - story_text: "In this level we've changed the `{for}` command so we can tell the player where they are. \n\n### Exercise 1\nFinish the program so the player knows which room they are in.\n\n### Exercise 2\nMake the program into an adventure by following these steps:\n\n1. Make a list of choices (like: fight or flight)\n2. Make sure the player can choose an option with `{ask}`\n3. Is answer correct? Then they may proceed to the next monster. Do they give a wrong answer? Let the player know with a `{print}`. \n\n **(extra)** If you make a wrong choice, a monster is still shown! How could you change that?\n" + story_text: "На овом нивоу смо променили команду `{for}` тако да можемо рећи играчу где се налази.\n\n### Вежба 1\nЗавршите програм тако да играч зна у којој је соби.\n\n### Вежба 2\nНаправите програм у авантуру пратећи ове кораке:\n\n1. Направите листу избора (као што су: борба или бег)\n2. Уверите се да играч може изабрати опцију са `{ask}`\n3. Да ли је одговор тачан? Онда могу прећи на следеће чудовиште. Дају ли погрешан одговор? Обавестите играча са `{print}`.\n\n**Додатно** Ако направите погрешан избор, чудовиште се и даље приказује! Како бисте то могли променити?\n" example_code: | ``` {print} 'Escape from the Haunted House!' @@ -2357,359 +2385,360 @@ adventures: ``` 14: story_text: | - ### Exercise - In this level you can use the `<` and `>` symbol to introduce lives to your game. - Make sure the player loses a life when they come across the wrong monster and that the game stops if you have no lives left. + ### Вежба + На овом нивоу можете користити симболе `<` и `>` да уведете животе у своју игру. + Уверите се да играч губи живот када наиђе на погрешно чудовиште и да се игра зауставља ако нема више живота. example_code: | ``` - {print} 'Escape from the haunted house' - lives = 3 - doors = 1, 2, 3 - monsters = 'the wicked witch', 'a zombie', 'a sleeping 3 headed dog' + {print} 'Бекство из уклете куће' + животи = 3 + врата = 1, 2, 3 + чудовишта = 'зла вештица', 'зомби', 'успавани троглави пас' {for} i {in} {range} 1 {to} 10 - {if} lives _ - good_door = doors {at} {random} - monster = monsters {at} {random} - chosen_door = {ask} 'Which door do you choose?' - {if} good_door == chosen_door - {print} 'You have chosen the correct door' + {if} животи _ + добра_врата = врата {at} {random} + чудовиште = чудовишта {at} {random} + изабрана_врата = {ask} 'Која врата бирате?' + {if} добра_врата == изабрана_врата + {print} 'Изабрали сте права врата' {else} - {print} 'You see...' monster - {if} monster == 'a sleeping 3 headed dog' - {print} 'Pffieuw.... Its asleep' + {print} 'Видите...' чудовиште + {if} чудовиште == 'успавани троглави пас' + {print} 'Уф... Спава' {else} - {print} 'You lose one life' - lives = _ + {print} 'Губите један живот' + животи = _ {else} - {print} 'GAME OVER' + {print} 'КРАЈ ИГРЕ' ``` 16: story_text: | - ### Exercise - This haunted house game uses the connection between the lists you can use in this level. - For example: all the properties that belong to the zombie are first in all the lists, witch second and vampire third. - Check out the code and fill in `weapons[i]`, `monsters[i]` , `bad_fate[i]`, `good_fate[i]`, `hint[i]` on the correct blanks to get the code to work! - example_code: | - ``` - numbers = [1, 2, 3] - i = numbers[{random}] - hint = ['growling', 'a cackling laugh', 'fluttering batwings'] - monsters = ['zombie', 'witch', 'vampire'] - bad_fate = ['Your brain is eaten', 'You are forever cursed', 'You are bitten'] - good_fate = ['You throw the ham. The zombie is distracted and starts eating it.', 'You set the curtains on fire. The witch flees out of fear for the fire', 'The vampire hates garlic and flees'] - weapons = ['ham', 'lighter', 'garlic'] - {print} 'You are standing in front of an old mansion' - {print} 'Something is not right here' - {print} 'You hear ' _ - {print} 'You are going to explore it' - {print} 'You enter the kitchen and see a lighter, a raw ham and a garlic.' - your_weapon = {ask} 'What do you bring with you?' - {print} 'With your ' your_weapon ' you enter the living room' - {print} 'There you find a ' _ - needed_weapon = _ - {if} your_weapon == needed_weapon - {print} 'You use your ' your_weapon + ### Вежба + Ова игра уклете куће користи везу између листа које можете користити на овом нивоу. + На пример: сва својства која припадају зомбију су прва на свим листама, вештица друга и вампир трећи. + Погледајте код и попуните `weapons[i]`, `monsters[i]`, `bad_fate[i]`, `good_fate[i]`, `hint[i]` на исправним празнинама да бисте добили код који ради! + example_code: | + ``` + бројеви = [1, 2, 3] + i = бројеви[{random}] + наговештај = ['режање', 'злокобан смех', 'лепршање крила слепог миша'] + чудовишта = ['зомби', 'вештица', 'вампир'] + лоша_судбина = ['Ваш мозак је поједен', 'Зауек сте проклети', 'Уједен сте'] + добра_судбина = ['Бацате шунку. Зомби је одвраћен и почиње да је једе.', 'Палите завесе. Вештица бежи од страха од ватре', 'Вампир мрзи бели лук и бежи'] + оружја = ['шунка', 'упаљач', 'бели лук'] + {print} 'Стојите испред старе виле' + {print} 'Нешто није у реду овде' + {print} 'Чујете ' _ + {print} 'Идете да истражите' + {print} 'Улазите у кухињу и видите упаљач, сирову шунку и бели лук.' + ваше_оружје = {ask} 'Шта носите са собом?' + {print} 'Са вашим ' ваше_оружје ' улазите у дневну собу' + {print} 'Тамо налазите ' _ + потребно_оружје = _ + {if} ваше_оружје == потребно_оружје + {print} 'Користите ваше ' ваше_оружје {print} _ - {print} 'YOU WIN!' + {print} 'ПОБЕДИЛИ СТЕ!' {else} - {print} 'You have chosen the wrong weapon...' + {print} 'Изабрали сте погрешно оружје...' {print} _ - {print} 'GAME OVER' + {print} 'КРАЈ ИГРЕ' ``` hotel: - name: hotel - default_save_name: hotel - description: hotel + name: хотел + default_save_name: хотел + description: хотел levels: 13: story_text: | - In the previous adventure you have learned how to use an argument in a function, and you've learned how to combine it with an {ask}. - You might have wondered why you would use functions, because the functions in the example were only one line of code. - Now we will show you what a bigger function looks like and we will use multiple agruments now as well. You'll see how much better it is to use a function once the function gets bigger. - Here is an example of a function with arguments combined with {ask} commands. + У претходној авантури научили сте како да користите аргумент у функцији, и научили сте како да га комбинујете са {ask}. + Можда сте се питали зашто бисте користили функције, јер су функције у примеру биле само једна линија кода. + Сада ћемо вам показати како изгледа већа функција и сада ћемо користити више аргумената. Видећете колико је боље користити функцију када функција постане већа. + Ево примера функције са аргументима комбинованим са {ask} командама. example_code: | ``` {define} welcome_message {with} title, last_name, country, room_number - {print} 'Welcome to Hotel Hedy, ' title ' ' last_name - nice_trip {is} {ask} 'Did you have a nice trip from, ' country '?' - {if} nice_trip {is} 'yes' - {print} 'Lovely!' + {print} 'Добродошли у Хотел Хеди, ' title ' ' last_name + nice_trip {is} {ask} 'Да ли сте имали лепо путовање из, ' country '?' + {if} nice_trip {is} 'да' + {print} 'Дивно!' {else} - {print} 'Sorry to hear that.' - {print} 'Hopefully you can take a nice rest in you room.' - {print} 'Your room number is ' room_number + {print} 'Жао ми је што то чујем.' + {print} 'Надам се да ћете се лепо одморити у својој соби.' + {print} 'Ваш број собе је ' room_number - {print} 'Hello. Please fill in your information to check in.' - title = {ask} 'What is your title (mr, mrs, ms, dr, etc.)?' - name = {ask} 'What is you last name?' - homecountry = {ask} 'What country do you come from?' + {print} 'Здраво. Молимо вас да попуните своје податке за пријаву.' + title = {ask} 'Која је ваша титула (г., гђа., гђица., др, итд.)?' + name = {ask} 'Које је ваше презиме?' + homecountry = {ask} 'Из које земље долазите?' {call} welcome_message {with} title, name, homecountry, 105 ``` - title = {ask} 'What is your title (mr, mrs, ms, dr, etc.)?' - name = {ask} 'What is you last name?' - homecountry = {ask} 'What country do you come from?' + title = {ask} 'Која је ваша титула (г., гђа., гђица., др, итд.)?' + name = {ask} 'Које је ваше презиме?' + homecountry = {ask} 'Из које земље долазите?' {call} welcome_message {with} title, name, homecountry, 105 if_command: - name: '{if} & {else}' + name: '{if} и {else}' default_save_name: if_command - description: Introducing the if command + description: Увођење команде {if} levels: 5: story_text: | ## If... else.... - In level 5 there is something new, the `{if}`! With the `{if}` you can choose between two different options. - This code prints nice if you enter Hedy as a name, and boo! if you enter something else. - `{ask}` and `{print}` still work like they did in level 4. + На нивоу 5 постоји нешто ново, `{if}`! Са командом `{if}` можете бирати између две различите опције. + Овај код исписује лепо ако унесете Хеди као име, и бу! ако унесете нешто друго. + `{ask}` и `{print}` и даље раде као на нивоу 4. example_code: | ``` - name {is} {ask} 'what is your name?' - {if} name {is} Hedy {print} 'nice' {else} {print} 'boo!' + име {is} {ask} 'како се зовеш?' + {if} име {is} Хеди {print} 'лепо' {else} {print} 'бу!' ``` story_text_2: | - Sometimes code with an `{if}` gets really long and does not fit on the line well.
You may also divide the code over two lines, starting the second line at the `{else}` like this: + Понекад код са `{if}` постаје заиста дугачак и не стаје добро у ред.
Такође можете поделити код на два реда, почевши други ред са `{else}` овако: example_code_2: | ``` - name {is} {ask} 'what is your name?' - {if} name {is} Hedy {print} 'nice' - {else} {print} 'boo!' + име {is} {ask} 'како се зовеш?' + {if} име {is} Хеди {print} 'лепо' + {else} {print} 'бу!' ``` story_text_3: | - ### Exercise - Try to create your own code with `{if}` and `{else}`. You can use the example code if you want. + ### Вежба + Покушајте да направите свој код са `{if}` и `{else}`. Можете користити пример кода ако желите. example_code_3: | ``` - answer {is} {ask} '2 + 2 = ?' - _ _ _ 4 _ 'Great job!' - _ _ 'No 2 + 2 = 4' + одговор {is} {ask} '2 + 2 = ?' + _ _ _ 4 _ 'Одличан посао!' + _ _ 'Не, 2 + 2 = 4' ``` 8: story_text: | ## If... Else... - You have learned to repeat a block of lines of code after a `{repeat}` command. - Now you can also use indentation to make blocks after a {if} or {else} command. - Check out the example code. + Научили сте да понављате блок линија кода након команде `{repeat}`. + Сада можете користити увлачење да направите блокове након команде {if} или {else}. + Погледајте пример кода. - ### Exercise - Add an {else} command to the example code. Make a block of line using indentation. You do this by starting each line with 4 spaces. + ### Вежба + Додајте команду {else} у пример кода. Направите блок линија користећи увлачење. То радите тако што сваки ред почињете са 4 размака. example_code: | ``` - name = {ask} 'What is your name?' - {if} name {is} Hedy - {print} 'Welcome Hedy' - {print} 'You can play on your computer!' + име = {ask} 'Како се зовеш?' + {if} име {is} Хеди + {print} 'Добродошла Хеди' + {print} 'Можеш да играш на свом рачунару!' ``` 9: story_text: | - In this level you can also put an {if} command inside another {if} command. + На овом нивоу можете такође ставити `{if}` команду унутар друге `{if}` команде. example_code: | ``` - continue = {ask} 'Do you want to continue?' - {if} continue = yes - sure = {ask} 'Are you sure?' - {if} sure {is} yes - {print} 'We will continue' + наставити = {ask} 'Да ли желиш да наставиш?' + {if} наставити = да + сигуран = {ask} 'Јеси ли сигуран?' + {if} сигуран {is} да + {print} 'Наставићемо' {else} - {print} 'You are not sure' + {print} 'Ниси сигуран' {else} - {print} 'You do not want to continue' + {print} 'Не желиш да наставиш' ``` in_command: name: '{in}' default_save_name: in_command - description: Introducing the in command + description: Увођење команде {in} levels: 5: story_text: | - ## Lists - When we want to check if something is in a list, we can now use the `{in}` command. - This code prints pretty! if you choose green or yellow, and meh otherwise. + ## Листе + Када желимо да проверимо да ли се нешто налази на листи, сада можемо користити команду `{in}`. + Овај код исписује лепо! ако изаберете зелену или жуту, и ме иначе. example_code: | ``` - pretty_colors {is} green, yellow - favorite_color {is} {ask} 'What is your favorite color?' - {if} favorite_color {in} pretty_colors {print} 'pretty!' - {else} {print} 'meh' + лепе_боје {is} зелена, жута + омиљена_боја {is} {ask} 'Која је твоја омиљена боја?' + {if} омиљена_боја {in} лепе_боје {print} 'лепо!' + {else} {print} 'ме' ``` story_text_2: | - ### Exercise - Finish the example code by filling in the blanks with commands that you've learned. - When you've finished the code, try to create a code of your own and use a question that you've thought of yourself. + ### Вежба + Завршите пример кода попуњавањем празнина командама које сте научили. + Када завршите код, покушајте да направите свој код и користите питање које сте сами смислили. example_code_2: | ``` - animals is dog, cow, sheep - answer is ask 'What is your favorite animal?' - _ answer _ animals _ 'Mine too!' - _ _ 'My favorite animals are dogs, cows and sheep' + животиње {is} пас, крава, овца + одговор {is} {ask} 'Која је твоја омиљена животиња?' + _ одговор _ животиње _ 'И моја омиљена!' + _ _ 'Моје омиљене животиње су пси, краве и овце' ``` is_command: name: '{is}' default_save_name: is_command - description: introducing is command + description: увођење команде {is} levels: 2: story_text: | - ## Variables - You can name a word with `{is}`. This is called a **variable**. In this example we made a variable called name and a variable called age. You can use the word name anywhere in your code and it will be replaced by Hedy, like this: + ## Променљиве + Можете именовати реч са `{is}`. Ово се зове **променљива**. У овом примеру смо направили променљиву звану име и променљиву звану године. Можете користити реч име било где у вашем коду и она ће бити замењена са Хеди, овако: example_code: | ``` - name {is} Hedy - age {is} 15 - {print} name is age years old + име {is} Хеди + године {is} 15 + {print} име има године година ``` story_text_2: | - ### Exercise - Time to make your own variables! - In the example code we made an example of the variable `favorite_animal`. In line 1 the variable is set, and in line 2 we haved used the variable in a print command. - Firstly, finish our example by filling in your favorite animal on the blank. Then make at least 3 of these codes yourself. Pick a variable, and set the variable with the {is} command. Then use it with a {print} command, just like we did. + ### Вежба + Време је да направите своје променљиве! + У пример коду смо направили пример променљиве `омиљена_животиња`. У линији 1 променљива је постављена, а у линији 2 смо користили променљиву у команди `{print}`. + Прво, завршите наш пример попуњавањем ваше омиљене животиње на празном месту. Затим направите најмање 3 оваква кода сами. Изаберите променљиву и поставите променљиву са командом `{is}`. Затим је користите са командом `{print}`, као што смо ми урадили. example_code_2: | ``` - favorite_animal {is} _ - {print} I like favorite_animal + омиљена_животиња {is} _ + {print} Волим омиљена_животиња ``` 6: story_text: | - We also make a change in storing a word in a variable! You may now use `=` instead of `{is}` when we store a name or a number in a variable, like this: + Такође правимо промену у чувању речи у променљивој! Сада можете користити `=` уместо `{is}` када чувамо име или број у променљивој, овако: example_code: | ``` - name = Hedy - answer = 20 + 4 + име = Хеди + одговор = 20 + 4 ``` 14: story_text: | - We are going to learn more new items. You might know them already from mathematics, the `<` and `>`. - The `<` checks if the first number is smaller than the second, for example age `<` 12 checks if age is smaller than 12. - If you want to check if the first number is smaller or equal to the second, you can use `<=`, for example age `<=` 11. - The `>` checks if the first number is bigger than the second, for example points `>` 10 checks if points is larger than 10. - If you want to check if the first number is bigger or equal to the second, you can use `>=`, for example points `>=` 11. - You use these comparisons in an `{if}`, like this: + Научићемо више нових ставки. Можда их већ знате из математике, `<` и `>`. + `<` проверава да ли је први број мањи од другог, на пример године `<` 12 проверава да ли су године мање од 12. + Ако желите да проверите да ли је први број мањи или једнак другом, можете користити `<=`, на пример године `<=` 11. + `>` проверава да ли је први број већи од другог, на пример поени `>` 10 проверава да ли су поени већи од 10. + Ако желите да проверите да ли је први број већи или једнак другом, можете користити `>=`, на пример поени `>=` 11. + Користите ове поређења у `{if}`, овако: example_code: | ``` - age = {ask} 'How old are you?' - {if} age > 12 - {print} 'You are older than I am!' + године = {ask} 'Колико имаш година?' + {if} године > 12 + {print} 'Старији си од мене!' + ``` + ``` + године = {ask} 'Колико имаш година?' + {if} године < 12 + {print} 'Млађи си од мене!' + {else} + {print} 'Старији си од мене!' ``` story_text_2: | - From this level on, if you want to compare exactly, you can use two equal signs. This is what most programming languages do: + Од овог нивоа, ако желите да поредите тачно, можете користити два једнака знака. Ово је оно што већина програмских језика ради: example_code_2: | ``` - name = {ask} 'What is your name?' - {if} name == 'Hedy' - {print} 'You are cool!' + име = {ask} 'Како се зовеш?' + {if} име == 'Хеди' + {print} 'Кул си!' ``` story_text_3: | - You can also compare if something is *not* equal to something else using `!=` like this: + Такође можете поредити да ли нешто *није* једнако нечему другом користећи `!=` овако: example_code_3: | ``` - name = {ask} 'What is your name?' - {if} name != 'Hedy' - {print} 'You are not Hedy' + име = {ask} 'Како се зовеш?' + {if} име != 'Хеди' + {print} 'Ниси Хеди' ``` - - {if} age < 13 - {print} 'You are younger than me!' - {else} - {print} 'You are older than me!' language: - name: Language - default_save_name: Language - description: Practice words in a foreign language + name: Језик + default_save_name: Језик + description: Вежбајте речи на страном језику levels: 5: story_text: | - Make your own program to practice your vocabulary in a new language. + Направите свој програм за вежбање вокабулара на новом језику. - ### Exercise - Make the code longer by adding at least 3 more words for the player to learn. - **Extra** Of course, you can choose to use a different language than French. You can change to code to any language you'd like to learn. + ### Вежба + Продужите код додавањем најмање 3 речи које играч треба да научи. + **Додатно** Наравно, можете изабрати да користите други језик осим француског. Можете променити код на било који језик који желите да научите. example_code: | ``` - {print} 'Learn French!' - cat {is} {ask} '🐱' - {if} cat {is} chat {print} 'Terrific!' - {else} {print} 'No, cat is chat' - frog {is} {ask} '🐸' - {if} frog {is} grenouille {print} 'Super!' - {else} {print} 'No, frog is grenouille' + {print} 'Научите француски!' + мачка {is} {ask} '🐱' + {if} мачка {is} chat {print} 'Сјајно!' + {else} {print} 'Не, мачка је chat' + жаба {is} {ask} '🐸' + {if} жаба {is} grenouille {print} 'Супер!' + {else} {print} 'Не, жаба је grenouille' ``` 16: story_text: | - ### Exercise - Take a look at the example code. This is a program to practise French vocabulary. Now make your own program to practice your vocabulary in a new language. - If you don't know any other languages, you can use Google translate or you can use emojis and your native language. + ### Вежба + Погледајте пример кода. Ово је програм за вежбање француског речника. Сада направите свој програм за вежбање речника на новом језику. + Ако не знате ниједан други језик, можете користити Google преводилац или можете користити емоџије и свој матерњи језик. example_code: | ``` - french_words = ['bonjour', 'ordinateur', 'pomme de terre'] - translation = ['hello', 'computer', 'potato'] - score = 0 + француске_речи = ['bonjour', 'ordinateur', 'pomme de terre'] + превод = ['здраво', 'рачунар', 'кромпир'] + резултат = 0 {for} i {in} {range} 1 {to} 3 - answer = {ask} 'What does ' french_words[i] ' mean?' - correct = translation[i] - {if} answer == correct - {print} 'Correct!' - score = score + 1 + одговор = {ask} 'Шта значи ' француске_речи[i] '?' + тачно = превод[i] + {if} одговор == тачно + {print} 'Тачно!' + резултат = резултат + 1 {else} - {print} 'Wrong, ' french_words[i] ' means ' translation[i] - {print} 'You gave ' score ' correct answers.' + {print} 'Погрешно, ' француске_речи[i] ' значи ' превод[i] + {print} 'Дали сте ' резултат ' тачних одговора.' ``` maths: - name: maths - default_save_name: maths - description: Introducing maths + name: математика + default_save_name: математика + description: Увод у математику levels: 6: story_text: | - In this level you learn something new: you can now also calculate. + У овом нивоу учиш нешто ново: сада можеш и да рачунаш. - The plus is easy, you write it like with math: `5 + 5` for example. The minus also works fine, it is `5 - 5`. + Плус је једноставан, пишеш га као у математици: `5 + 5` на пример. Минус такође ради добро, то је `5 - 5`. - The times is a bit different, because there is no times symbol on your keyboard. Just search, there really isn't! - That is why we multiply with the asterisk above 8: `5 * 5`. Read that as "5 times 5" that helps you remember it best. + Путање је мало другачије, јер на тастатури нема симбола за путање. Само потражи, заиста га нема! + Зато множимо са звездицом изнад 8: `5 * 5`. Читај то као "5 пута 5" што ти помаже да то најбоље запамтиш. example_code: | ``` - {print} '5 plus 5 is ' 5 + 5 - {print} '5 minus 5 is ' 5 - 5 - {print} '5 times 5 is ' 5 * 5 + {print} '5 плус 5 је ' 5 + 5 + {print} '5 минус 5 је ' 5 - 5 + {print} '5 пута 5 је ' 5 * 5 + {print} '5 подељено са 5 је ' 5 / 5 ``` 12: story_text: |- - **Decimal numbers** - So far, Hedy did not allow for decimal numbers like 1.5, but now we do allow that. Note that computers use the `.` for decimal numbers. + **Децимални бројеви** + До сада, Hedy није дозвољавала децималне бројеве као што је 1.5, али сада то дозвољавамо. Имај на уму да рачунари користе `.` за децималне бројеве. example_code: | ``` - {print} 'Two and a half plus two and a half is...' + {print} 'Два и по плус два и по је...' {print} 2.5 + 2.5 ``` story_text_2: |- - **Maths with words** - In this level you can also do addition with words like this: + **Математика са речима** + На овом нивоу можете такође радити сабирање са речима овако: example_code_2: | ``` - a = 'Hello ' - b = 'world!' + a = 'Здраво ' + b = 'свете!' {print} a + b ``` - - {print} 2.5 + 2.5 music: - name: music - default_save_name: music - description: Play a tune! + name: музика + default_save_name: музика + description: Пуштај мелодију! levels: 1: story_text: |- - In this level you'll learn how to use the `{play}` command to play a tune! + На овом нивоу ћеш научити како да користиш наредбу `{play}` за свирање мелодије! - Type `{play}` followed by the note you want to play. The scale goes C-D-E-F-G-A-B. - As you can see there are 7 different letters, but we can play more than just 7 notes. - Type a number between 1 and 10 behind the letter to choose the scale, for example after B4 comes C5. - C1 is the lowest note you can play, C10 is the highest. + Куцај `{play}` праћено нотом коју желиш да свираш. Скала иде C-D-E-F-G-A-B. + Као што видиш, постоји 7 различитих слова, али можемо свирати више од само 7 нота. + Куцај број између 1 и 10 иза слова да изабереш скалу, на пример после B4 долази C5. + C1 је најнижа нота коју можеш свирати, C10 је највиша. - ### Exercise - Try out the example code and then play around with it! Can you create your own melody? - In the next level you'll learn how to play some existing songs. + ### Вежба + Испробај пример кода, а затим се играј са њим! Можеш ли створити своју мелодију? + На следећем нивоу ћеш научити како да свираш неке постојеће песме. example_code: |- ``` {play} C4 @@ -2723,11 +2752,11 @@ adventures: ``` 2: story_text: | - ### Exercise - Finish the songs! We have started the codes for some melodies. + ### Вежба + Завршите песме! Почели смо кодове за неке мелодије. example_code: | ``` - {print} Old Mac Donald had a farm + {print} Стари Мекдоналд је имао фарму {play} C5 {play} C5 {play} C5 @@ -2736,7 +2765,7 @@ adventures: {play} A4 {play} G4 ``` - story_text_2: As you can see, you can also use the `{sleep}` command to add a little pause in the song. + story_text_2: Као што видиш, можеш користити и наредбу `{sleep}` да додаш малу паузу у песму. example_code_2: | ``` {print} Twinkle Twinkle Little Star @@ -2753,11 +2782,11 @@ adventures: ``` 3: story_text: | - Create a random melody! + Направите случајну мелодију! - ### Exercise - The example code creates a random melody, but it's very short and not many notes are used. - Add more notes to the list and create a longer melody by copying the last line a couple more times. + ### Вежба + Пример кода прави случајну мелодију, али је веома кратка и не користи много нота. + Додајте више нота у листу и направите дужу мелодију копирањем последње линије још неколико пута. example_code: | ``` notes {is} A4, B4, C4 @@ -2767,11 +2796,11 @@ adventures: ``` 4: story_text: | - Use the `{clear}` command to create a karaoke machine! + Користи наредбу `{clear}` да направиш караоке машину! - ### Exercise - Finish the karaoke version of 'Mary had a little lamb'. - Then, create a karaoke version of any song you'd like! + ### Вежба + Заврши караоке верзију песме 'Mary had a little lamb'. + Затим, направи караоке верзију било које песме коју желиш! example_code: | ``` {print} 'Mary had a little lamb' @@ -2796,12 +2825,12 @@ adventures: ``` 5: story_text: | - You don't always have to use the `{play}` command to play a whole song, sometimes you just want to play one note. - For example, if you want to make a quiz, you can play a happy high note if the answer is right and a sad low note if the answer is wrong. + Не мораш увек користити наредбу `{play}` да би свирао целу песму, понекад желиш само да свираш једну ноту. + На пример, ако желиш да направиш квиз, можеш свирати веселу високу ноту ако је одговор тачан и тужну ниску ноту ако је одговор погрешан. - ### Exercise - Finish the first question by adding a line of code that plays a C3 note if the wrong answer is given. - Then think of 3 more questions to add to this quiz. + ### Вежба + Заврши прво питање додавањем линије кода која свира ноту C3 ако је одговор погрешан. + Затим смисли још 3 питања која ћеш додати у овај квиз. example_code: | ``` answer {is} {ask} 'What is the capital of Zimbabwe?' @@ -2809,10 +2838,10 @@ adventures: _ ``` 6: - story_text: "Instead of playing notes, you can also play numbers now. Simply type `{play} 1` for the lowest note, `{play} 70` for the highest note, or anything in between.\n\n### Exercise\n This calls for musical maths! Try out the example code a couple of times with different starting numbers. \nThen, see if you can compose a song using the numbers.\n" + story_text: "Уместо свирања нота, сада можеш свирати и бројеве. Једноставно куцај `{play} 1` за најнижу ноту, `{play} 70` за највишу ноту, или било који број између.\n\n### Вежба\nОво захтева музичку математику! Испробај пример кода неколико пута са различитим почетним бројевима.\nЗатим, види да ли можеш компоновати песму користећи бројеве.\n" example_code: | ``` - number = {ask} 'Say a starting number between 1 and 67' + number = {ask} 'Реци почетни број између 1 и 67' {print} number {play} number number = number + 1 @@ -2824,27 +2853,27 @@ adventures: ``` 7: story_text: | - Using the `{repeat}` command can make your codes for melodies a lot shorter! + Коришћење наредбе `{repeat}` може учинити твоје кодове за мелодије много краћим! - ### Exercise - Finish the code for Twinkle Twinkle Little Star by using the `{repeat}`command. - Then go back to the songs you've made in the previous levels. Can you shorten those codes too? + ### Вежба + Заврши код за Twinkle Twinkle Little Star користећи наредбу `{repeat}`. + Затим се врати на песме које си направио на претходним нивоима. Можеш ли и те кодове скратити? example_code: | ``` - {print} 'Twinkle Twinkle Little Star' + {print} 'Сјајна, сјајна мала звездо' {repeat} 2 {times} {play} C4 {repeat} 2 {times} {play} G4 _ ``` 8: story_text: | - Now that we can use the `{repeat}` command for multiple lines, we can make songs even more easily! + Сада када можемо користити команду `{repeat}` за више линија, можемо још лакше правити песме! - ### Exercise - Finish the song of Brother John (Frère Jacques). Don't forget to use `{repeat}`! + ### Вежба + Заврши песму "Брат Јован" (Frère Jacques). Не заборави да користиш `{repeat}`! example_code: | ``` - {print} 'Brother John' + {print} 'Брат Јован' {repeat} 2 {times} {play} C {play} D @@ -2858,33 +2887,33 @@ adventures: ``` 9: story_text: | - From this level on you can - among other things - use a {repeat} command inside a {repeat} command. - That makes songs like 'Happy birthday' even shorter! + Од овог нивоа можете - између осталог - користити команду {repeat} унутар команде {repeat}. + То чини песме попут "Срећан рођендан" још краћим! - ### Exercise - Finish the song! + ### Вежба + Заврши песму! example_code: | ``` - first_time = yes + first_time = да {repeat} 2 {times} {repeat} 2 {times} {play} C {play} D {play} C - {if} first_time {is} yes + {if} first_time {is} да {play} F {play} E - first_time {is} no + first_time {is} не {else} _ ``` 12: story_text: | - Use functions in your songs! As you can see in the example code, you can make a function for each line of Twinkle Twinkle Little Star. Once you've programmed the first three lines, all you have to do is call the functions in the order you want them played in. + Користите функције у својим песмама! Као што можете видети у пример коду, можете направити функцију за сваки ред песме "Сјајна, сјајна мала звездо". Када програмирате прва три реда, све што треба да урадите је да позовете функције редом којим желите да се свирају. - ### Exercise - Finish the song of Twinkle Twinkle Little Star. - Then look back at all the songs you've programmed in the levels before, can you make those codes better and shorter using functions too? + ### Вежба + Заврши песму "Сјајна, сјајна мала звездо". + Затим погледајте све песме које сте програмирали у претходним нивоима, можете ли и те кодове учинити бољим и краћим користећи функције? example_code: | ``` {define} first_line @@ -2926,23 +2955,23 @@ adventures: ``` 13: story_text: | - You can use a function with an argument for songs that have line that are almost the same, but slightly different each time. - One example is the song 'Yankee Doodle'. The first 4 notes of the first lines are the same, but each time they are followed by a different couple of notes. + Можете користити функцију са аргументом за песме које имају редове који су скоро исти, али се сваки пут мало разликују. + Један пример је песма "Yankee Doodle". Прве 4 ноте првих редова су исте, али сваки пут су праћене различитим паром нота. - ### Exercise - Can you finish the song of Yankee Doodle? - Can you think of another song to program this way? + ### Вежба + Можете ли завршити песму "Yankee Doodle"? + Можете ли смислити још једну песму коју бисте програмирали на овај начин? example_code: | ``` {print} 'Yankee Doodle' - {define} _ {with} note_1, note_2, note_3 + {define} line_1 {with} note_1, note_2, note_3 {play} C4 {play} C4 {play} D4 {play} E4 - {play} _ - {play} _ - {play} _ + {play} note_1 + {play} note_2 + {play} note_3 {call} line_1 {with} 29, 31, 30 {call} line_1 {with} 29, 28, 0 @@ -2958,51 +2987,51 @@ adventures: ``` 14: story_text: | - You can program music for fun, but you can also use the musical notes to make something useful like a fire alarm! + Можете програмирати музику за забаву, али можете користити и музичке ноте да направите нешто корисно, као што је противпожарни аларм! - ### Exercise - Make sure the fire alarm rings when there is a fire! + ### Вежба + Уверите се да противпожарни аларм звони када има пожара! example_code: | ``` {define} fire_alarm - {print} 'FIRE!' + {print} 'ПОЖАР!' note = 40 {for} i {in} {range} 1 {to} 100 - {if} note _ 50 + {if} note < 50 note = note + 5 - {play} _ + {play} note {else} note = 40 - fire = {ask} 'Is there a fire?' - {if} fire _ 'yes' + fire = {ask} 'Да ли има пожара?' + {if} fire == 'да' {call} fire_alarm ``` 15: story_text: | - **Warning** This adventure can become extremely annoying! - We can also use the {while} command to repeat a song forever. + **Упозорење** Ова авантура може постати изузетно досадна! + Такође можемо користити команду {while} да бисмо понављали песму заувек. - ### Exercise - Finish the never-ending song. + ### Вежба + Завршите бескрајну песму. example_code: | ``` {define} song {play} _ - yes_or_no = {ask} 'Do you want to hear my never-ending song?' - {while} yes_or_no = 'yes' + yes_or_no = {ask} 'Да ли желите да чујете моју бескрајну песму?' + {while} yes_or_no = 'да' {call} song {print} '🥳' ``` 16: story_text: | - Upgrade your Old MacDonald code! + Надоградите свој код за "Старог Макдоналда"! - ### Exercise - Take your code from the 'Sing a Song' adventure and add musical notes to it! - You can make a function for each line in the song and call that function after the line is printed. - We defined the first line for you and called it in the code. Can you finish the whole song? + ### Вежба + Узмите свој код из авантуре "Певај песму" и додајте музичке ноте! + Можете направити функцију за сваки ред у песми и позвати ту функцију након што се ред одштампа. + Дефинисали смо први ред за вас и позвали га у коду. Можете ли завршити целу песму? example_code: | ``` {define} line_1 @@ -3018,18 +3047,18 @@ adventures: for i in range 1 to 3 animal = animals[i] sound = sounds[i] - print 'Old MacDonald had a farm' + print 'Старац Макдоналд имао је фарму' call line_1 - print 'E I E I O!' + print 'Е И Е И О!' _ ``` 17: story_text: | - You can use the {elif} to create different options. + Можете користити {elif} да бисте креирали различите опције. - ### Exercise - Firstly, add colons to get the code to work. - Then finish this code by adding at least 2 other songs for other moods. For example a happy song and an angry song. + ### Вежба + Прво, додајте двотачке да би код радио. + Затим завршите овај код додавањем најмање још 2 песме за друга расположења. На пример, срећну песму и љуту песму. example_code: | ``` {define} scary_song @@ -3041,17 +3070,17 @@ adventures: {play} F {play} D - mood = {ask} 'Which emotion are you feeling?' - {if} mood {is} 'fear' + mood = {ask} 'Коју емоцију осећате?' + {if} mood {is} 'страх' {call} scary_song {elif} _ ``` 18: story_text: | - ### Exercise - Even in this last level of Hedy we can make some music! Be careful of all the syntax that is needed now. - Take a good look at how the functions are defined and called upon in the example code. - Finish the song! + ### Вежба + Чак и на овом последњем нивоу Хеди можемо правити музику! Пазите на сву синтаксу која је сада потребна. + Добро погледајте како су функције дефинисане и позване у пример коду. + Завршите песму! example_code: | ``` {def} line_1(): @@ -3071,108 +3100,117 @@ adventures: {def} line_3(): _ - {print} ('The drunken sailor') - {print} ('What shall we do with the drunken sailor?') + {print} ('Пијани морнар') + {print} ('Шта ћемо са пијаним морнаром?') line_1() line_2() line_3() - {print} ('Early in the morning') + {print} ('Рано ујутро') ``` parrot: - name: Parrot - default_save_name: Parrot - description: Create your own online pet parrot that will copy you! + name: Папагај + default_save_name: Папагај + description: Направи свог онлајн кућног љубимца папагаја који ће те копирати! levels: 1: story_text: | - Create your own online pet parrot that will copy you! + Направи свог онлајн кућног љубимца папагаја који ће те копирати! example_code: | ``` - {print} Im Hedy the parrot - {ask} whats your name? + {print} Ја сам Хеди папагај + {ask} како се зовеш? {echo} {echo} ``` story_text_2: | - ### Exercise - Copy the example code to your input screen by clicking on the yellow button. - Make the parrot ask a different question. Fill in the blanks in the example! - **Extra** You can also let the parrot ask multiple questions. Type in some more lines of code beneath your own code. + ### Вежба + Копирај пример кода на свој улазни екран кликом на жуто дугме. + Нека папагај постави друго питање. Попуни празнине у примеру! + **Додатно** Можеш такође дозволити папагају да постави више питања. Укуцај још неколико линија кода испод свог кода. example_code_2: | ``` - {print} Im Hedy the parrot + {print} Ја сам Хеди папагај {ask} _ {echo} {echo} 2: story_text: | - Create your own online pet parrot that will copy you! + На претходном нивоу направио си папагаја који ће понављати за тобом. На овом нивоу ћемо учинити папагаја интерактивним користећи променљиву и команду `{ask}`. + Такође ћемо учинити папагаја животнијим додавањем команди `{sleep}` након што нешто каже. example_code: | ``` - {print} Im Hedy the parrot - name {is} {ask} whats your name? - {print} name - {sleep} - {print} squawk - {sleep} - {print} name + {print} Ја сам Хеди папагај + име _ _ како се зовеш? + {print} име + _ + {print} крик + _ + {print} име ``` story_text_2: | - ### Exercise - You can use variables to make the parrot say more than only your name. Can you complete this code? + ### Вежба + Прво, заврши линију 2 са командом `{is}` и командом `{ask}`. + Затим попуни команду `{sleep}` на линијама 4 и 6 да би папагај остао тих неко време. + + **Додатно** Можеш ли учинити да папагај пита више од само твог имена додавањем више линија кода? 3: story_text: | - Teach your parrot a new word with `{add}`. - ### Exercise - How can you make your parrot say multiple words? + Научи свог папагаја нову реч са `{add}`. + ### Вежба + Можеш ли додати команду `{add} {to_list}` да би код радио? example_code: | ``` - words {is} squawk, Hedy - {print} Train your parrot! - new_word {is} {ask} Which word do you want to teach them? - {add} new_word {to_list} words - {print} 🧒 Say new_word, Hedy! - {print} 🦜 words {at} {random} + речи {is} крик, Хеди + {print} Тренирај свог папагаја! + нова_реч {is} {ask} Коју реч желиш да га научиш? + _ нова_реч _ речи + {print} 🧒 Реци нова_реч, Хеди! + {print} 🦜 речи {at} {random} ``` 4: story_text: | - In this level we have to use quotation marks with the commands `{ask}` and `{print}`. - ### Exercise - Complete the code by filling in quotation marks on the blanks. + На овом нивоу морамо користити наводнике са командама `{ask}` и `{print}`. + ### Вежба + Заврши код попуњавањем наводника на празним местима. example_code: | ``` - words {is} squawk, Hedy - {print} _ Train your parrot! _ - new_word {is} {ask} _ Which word do you want to teach them? _ - {add} new_word {to_list} words - {print} _ 🧒 Say _ new_word _, Hedy!_ - {print} _ 🦜 _ words {at} {random} + речи {is} крик, Хеди + {print} _ Тренирај свог папагаја! _ + нова_реч {is} {ask} _ Коју реч желиш да га научиш? _ + {add} нова_реч {to_list} речи + {print} _ 🧒 Реци _ нова_реч _, Хеди!_ + {print} _ 🦜 _ речи {at} {random} ``` 5: story_text: | - Reward your parrot if it says the correct word! - Finish the code by filling in the 4 missing commands. + Награди свог папагаја ако каже тачну реч! + + ### Вежба + Заврши код попуњавањем 4 недостајуће команде. example_code: | ``` - words {is} squawk, Hedy - {print} 'Train your parrot!' - new_word {is} {ask} 'Which word do you want to teach them?' - {add} new_word {to_list} words - said_word {is} words {at} {random} - {print} '🧒 Say ' new_word ', Hedy!' - {print} '🦜 ' said_word - _ said_word {is} new_word _ '🧒 Great job, Hedy! 🍪' - _ _ '🧒 No, Hedy! Say ' new_word + речи {is} крик, Хеди + {print} 'Тренирај свог папагаја!' + нова_реч {is} {ask} 'Коју реч желиш да га научиш?' + {add} нова_реч {to_list} речи + речена_реч {is} речи {at} {random} + {print} '🧒 Реци ' нова_реч ', Хеди!' + {print} '🦜 ' речена_реч + _ речена_реч {is} нова_реч _ '🧒 Одличан посао, Хеди! 🍪' + _ _ '🧒 Не, Хеди! Реци ' нова_реч ``` piggybank: - name: Piggy Bank - default_save_name: Piggy Bank - description: Count your pocketmoney! + name: Касица прасица + default_save_name: Касица прасица + description: Преброј свој џепарац! levels: 12: story_text: | - In this adventure you learn how to make a digital piggy bank. - Finish the code to calculate how much money you have and how long you need to save up to buy what you want! + У овој авантури ћете научити како да направите дигиталну касицу прасицу. + + ### Вежба + Завршите код да бисте израчунали колико новца имате и колико дуго треба да штедите да бисте купили оно што желите! + **Додатно** Можда сте већ уштедели нешто новца? Одузмите то од износа који ћете морати да уштедите. example_code: | ``` {print} 'The digital piggy bank' @@ -3186,12 +3224,12 @@ adventures: ``` 14: story_text: | - ### Exercise - In this level you can let Hedy tell you if you have saved up enough money! - Finish this code by filling in the blanks! + ### Вежба + На овом нивоу можете дозволити Хеди да вам каже да ли сте уштедели довољно новца! + Завршите овај код попуњавањем празнина! example_code: | ``` - _ calculate_budget with wish, money, allowance + _ calculate_budget {with} wish, money, allowance to_save = wish - money weeks = to_save / allowance {if} wish _ money @@ -3205,31 +3243,31 @@ adventures: wish = {ask} 'How much money do you need?' allowance = {ask} 'How much pocket money do you get each week?' - {call} calculate_budget with _, _, _ + {call} _ ``` pressit: - name: Key presses - default_save_name: Pressed - description: Try linking a keyboard key to a command! + name: Притисци тастера + default_save_name: Притиснуто + description: Покушајте да повежете тастер на тастатури са командом! levels: 5: story_text: | - In this level there is another new keyword: `{pressed}`! - With `{pressed}` you can use keys on your keyboard to control what lines are used. + На овом нивоу постоји још једна нова кључна реч: `{pressed}`! + Са `{pressed}` можете користити тастере на вашој тастатури да контролишете које линије се користе. - ### Exercise - Look at the example and add one more line of code that reacts to a key press. + ### Вежба + Погледајте пример и додајте још једну линију кода која реагује на притисак тастера. example_code: | ``` - {print} 'Do you want a good (g) or bad (b) ending?' - {if} g {is} {pressed} {print} 'They lived happily ever after ❤' - {else} {print} 'The prince was eaten by a hippopotamus 😭' + {print} 'Да ли желите добар (g) или лош (b) крај?' + {if} g {is} {pressed} {print} 'Живели су срећно до краја живота ❤' + {else} {print} 'Принца је појео хипопотам 😭' ``` story_text_2: | - You can also link turtle commands to keys. + Такође можете повезати команде за корњачу са тастерима. - ### Exercise - Copy the lines a few times so you can create a larger drawing. + ### Вежба + Копирајте линије неколико пута како бисте направили већи цртеж. example_code_2: | ``` {if} y {is} {pressed} {forward} 15 @@ -3237,30 +3275,30 @@ adventures: ``` 7: story_text: | - Now that you have learned about `{repeat}`, we can press keys multiple times. - You can use it to make the turtle walk forward and turn. + Сада када сте научили о `{repeat}`, можемо притискати тастере више пута. + Можете га користити да корњача хода напред и скреће. - ### Exercise - The code you have seen in level 5 only checks the key once. Copy the example code and add a `{repeat}` to it, so that you can press the keys many times. - Use this code to draw something nice. + ### Вежба + Код који сте видели на нивоу 5 проверава тастер само једном. Копирајте пример кода и додајте `{repeat}` у њега, тако да можете притискати тастере више пута. + Користите овај код да нацртате нешто лепо. example_code: | ``` {if} x {is} {pressed} {forward} 15 {else} {turn} 90 ``` 9: story_text: | - Now that you know how to combine statements, you can create a touch type tool with `{pressed}`. + Сада када знате како да комбинујете изјаве, можете направити алат за куцање на додир са `{pressed}`. - ### Exercise - Finish the code. Each time a random letter should be chosen, which you have to press. You get a point for a correct press, and and two points deduction for a wrong press. - **(extra)** Clear the screen after each letter, and show the user how many points they have scored. + ### Вежба + Завршите код. Сваки пут треба изабрати насумично слово које морате притиснути. Добијате поен за тачан притисак, а два поена се одузимају за погрешан притисак. + **Додатно** Очистите екран након сваког слова и покажите кориснику колико поена је освојио. example_code: | ``` points = 0 letters = a, b, c, d, e {repeat} 10 {times} letter = _ _ _ - {print} 'Press the letter ' letter + {print} 'Притисните слово ' letter {if} letter {is} {pressed} _ _ @@ -3268,348 +3306,353 @@ adventures: ``` print_command: name: '{print}' - default_save_name: print - description: Introduction print command + default_save_name: команда за приказивање + description: Увод у команду за приказивање levels: 1: story_text: | - ## The print command - You can print text to the screen using the `{print}` command. + ## Команда за приказивање + Можете приказати текст на екрану користећи команду `{print}`. example_code: | ``` - {print} Hi there, programmer! - {print} Welcome to Hedy! + {print} Здраво, програмеру! + {print} Добродошли у Хеди! ``` story_text_2: | - ### Exercise - In Hedy you will find exercises in every adventure. An exercise allows you to practise the new commands and concepts, and lets you give your own twist to the example codes. - In this exercise you will see a pink blank space. You have to fill something in the place of the blank space before the code can be run. + ### Вежба + У Хедију ћете наћи вежбе у свакој авантури. Вежба вам омогућава да вежбате нове команде и концепте, и да дате свој лични печат примерима кода. + У овој вежби ћете видети ружичасти празан простор. Морате попунити нешто на месту празног простора пре него што код може да се покрене. - Fill in the `{print}` command in the blank space and then add five more lines of code. Each line has to start with a `{print}` command. - Have fun! + Попуните команду `{print}` у празан простор и затим додајте још пет линија кода. Свака линија мора почети са командом `{print}`. + Забавите се! example_code_2: | ``` - _ Hello! + _ Здраво! ``` 18: story_text: |- - We arrived at real Python code! That means we need to use parentheses with `{print}` and `{range}` from now on. - It also means you can use Hedy code from this level in any Python environment as long as you use the English commands. If you haven't until now, you can switch the toggle in the commands menu to do so. + Стигли смо до правог Python кода! То значи да од сада морамо користити заграде са `{print}` и `{range}`. + Такође значи да можете користити Хеди код са овог нивоа у било ком Python окружењу све док користите енглеске команде. Ако до сада нисте, можете пребацити прекидач у менију команди да то урадите. example_code: | ``` - {print}('Hello!') + {print}('Здраво!') {for} i {in} {range}(1, 10): - {print}('This is line ', i) + {print}('Ово је линија ', i) ``` - story_text_2: If you want to print more than one item, you need to separate them by commas. + story_text_2: Ако желите да прикажете више од једне ставке, потребно је да их раздвојите зарезима. example_code_2: | ``` - temperature = 25 - {print}('It is ', temperature, ' degrees outside') + температура = 25 + {print}('Напољу је ', температура, ' степени') + ``` + ``` + име = 'Хеди' + {print}('Моје име је ', име) ``` - - {print}('My name is ', name) quizmaster: - name: Quizmaster - default_save_name: Quizmaster - description: Make your own quiz! + name: Квизмајстор + default_save_name: Квизмајстор + description: Направите свој квиз! levels: 14: story_text: | - ### Exercise - In this adventure you can make your own quiz! Fill in the blanks, add more questions and enjoy your own quiz! - You can make a quiz about anything you like: your hobby, your favorite animal, your favorite book or anything at all! - example_code: | - ``` - {print} 'Make your own quiz' - points_a = 0 - points_b = 0 - {print} 'Question' - {print} 'Answer option A' - {print} 'Answer option B' - answer = {ask} 'Which answer?' - {if} answer == 'A' - points_a = points_a + 1 - {if} answer == 'B' - points_b = points_b + 1 - {print} 'End of the quiz!' - {print} 'Lets see the results!' - {if} points_a > points_b - {print} 'You belong to the A club' - {if} points_b > points_a - {print} 'You belong to the B club' + ### Вежба + У овој авантури можете направити свој квиз! Попуните празнине, додајте још питања и уживајте у свом квизу! + Можете направити квиз о било чему што волите: вашем хобију, вашем омиљеном животињи, вашој омиљеној књизи или било чему другом! + example_code: | + ``` + {print} 'Направите свој квиз' + поени_а = 0 + поени_б = 0 + {print} 'Питање' + {print} 'Опција одговора А' + {print} 'Опција одговора Б' + одговор = {ask} 'Који је одговор?' + {if} одговор == 'A' + поени_а = поени_а + 1 + {if} одговор == 'B' + поени_б = поени_б + 1 + {print} 'Крај квиза!' + {print} 'Хајде да видимо резултате!' + {if} поени_а > поени_б + {print} 'Припадате клубу А' + {if} поени_б > поени_а + {print} 'Припадате клубу Б' ``` quotation_marks: - name: '''quotation marks''' - default_save_name: quotation_marks - description: Introduction quotation marks + name: '''наводници''' + default_save_name: наводници + description: Увођење наводника levels: 4: story_text: | - ## 'Quotation marks' - In level 4 `{ask}` and `{print}` have changed. - You must put text that you want to print between quotation marks. - This is useful, because now you can print all the words you want. Also the words you used to store something with `{is}`. - Most programming languages also use quotation marks when printing, so we are also getting a step closer to real programming! + ## 'Наводници' + На нивоу 4 `{ask}` и `{print}` су се променили. + Морате ставити текст који желите да испишете између наводника. + Ово је корисно, јер сада можете исписати све речи које желите. Такође и речи које сте користили да нешто сачувате са `{is}`. + Већина програмских језика такође користи наводнике при исписивању, тако да смо корак ближе правом програмирању! example_code: | ``` - {print} 'You need to use quotation marks from now on!' - answer {is} {ask} 'What do we need to use from now on?' - {print} 'We need to use ' answer + {print} 'Морате користити наводнике од сада!' + одговор {is} {ask} 'Шта морамо користити од сада?' + {print} 'Морамо користити ' одговор ``` story_text_2: | - ## Contractions - Important! Mind that now that we're using quotation marks, Hedy will get confused when you use the apostrophe for contractions like I'm or What's. - Make sure to remove those apostrophes and change the spelling to I am or What is. - Check out the example code to see the wrong way of using apostrophes. + ## Скраћенице + Важно! Обратите пажњу да сада када користимо наводнике, Хеди ће се збунити када користите апостроф за скраћенице као што су I'm или What's. + Обавезно уклоните те апострофе и промените правопис у I am или What is. + Погледајте пример кода да видите погрешан начин коришћења апострофа. example_code_2: | ``` - _ This is the wrong way of using apostrophes _ + _ Ово је погрешан начин коришћења апострофа _ {print} 'I'm babysitting my sister's kids' {print} 'What's more fun than that?' ``` 12: story_text: | - **All texts need to be in quotation marks** - For this level on you will also have to use quotation marks when storing a text with `=`: + **Сви текстови морају бити у наводницима** + Од овог нивоа ћете такође морати да користите наводнике када чувате текст са `=`: example_code: | ``` - name = 'Hedy the Robot' - {print} 'Hello ' name + име = 'Хеди робот' + {print} 'Здраво ' име ``` story_text_2: | - **All items in lists need quotation marks too** - Lists are texts, so they need quotation marks too. Mind that each single item on the list has quotation marks. - This allows you to save two words as 1 item on the list, for example 'Black Widow'. + **Сви елементи на листама такође морају бити у наводницима** + Листе су текстови, тако да и оне морају бити у наводницима. Обратите пажњу да сваки појединачни елемент на листи има наводнике. + Ово вам омогућава да сачувате две речи као један елемент на листи, на пример 'Црна удовица'. example_code_2: | ``` - superheroes = 'Spiderman', 'Batman', 'Black Widow' - {print} superheroes {at} {random} + суперхероји = 'Спајдермен', 'Бетмен', 'Црна удовица' + {print} суперхероји {at} {random} ``` story_text_3: | - **All text after `{if}` comparisons need quotation marks too** + **Сви текстови након поређења са `{if}` такође морају бити у наводницима** example_code_3: | ``` - name = {ask} 'What is your name?' - {if} name = 'Hedy the Robot' - {print} 'Hi there!' + име = {ask} 'Како се зовеш?' + {if} име = 'Хеди робот' + {print} 'Здраво!' ``` story_text_4: | - **Numbers don't need quotation marks** - For numbers, you do not use quotation marks in the `=`: + **Бројеви не морају бити у наводницима** + За бројеве, не користите наводнике у `=`: example_code_4: | ``` - score = 25 - {print} 'You got ' score + резултат = 25 + {print} 'Освојили сте ' резултат ``` random_command: name: '{random}' default_save_name: random_command - description: introducing at random command + description: увођење команде random levels: 3: story_text: | - ## At random - In this level you can make a list using the `{is}` command. You can let the computer choose a random item from that list. You do that with `{at} {random}`. + ## Насумично + На овом нивоу можете направити листу користећи команду `{is}`. Можете дозволити рачунару да изабере насумичну ставку са те листе. То радите са `{at} {random}`. example_code: | ``` - animals {is} dogs, cats, kangaroos - {print} animals {at} {random} + животиње {is} пси, мачке, кенгури + {print} животиње {at} {random} ``` story_text_2: | - You can use the `{at} {random}` command in a sentence as well. + Можете користити команду `{at} {random}` и у реченици. example_code_2: | ``` food {is} sandwich, slice of pizza, salad, burrito {print} I am going to have a food {at} {random} for lunch. ``` story_text_3: | - ### Exercise - Try out the `{at} {random}` command by making your own gameshow (like the ones on tv) where you choose a door or suitcase and it contains a big price! - Can you do it? We have already put the first lines into the example code. + ### Вежба + Испробајте команду `{at} {random}` тако што ћете направити своју сопствену игрицу (као оне на ТВ-у) где бирате врата или кофер и он садржи велику награду! + Можете ли то урадити? Већ смо ставили прве линије у пример кода. example_code_3: | ``` - {print} The big gameshow! - {print} There are 3 suitcases in front of you... - chosen {is} {ask} Which suitcase do you choose? - prices {is} _ + {print} Велика игрица! + {print} Испред вас су 3 кофера... + изабрано {is} {ask} Који кофер бирате? + награде {is} _ _ ``` 16: story_text: |- - We are going to make lists the Python way, with square brackets around the lists! We also keep the quotation marks around each item like we have learned in previous levels. - We use square brackets to point out a place in a list. For example: `friends[1]` is the first name on the list of friends, as you can see in the first part of the example code. The second part of the example code shows you that we can also match 2 lists using the variable i. + Правићемо листе на Python начин, са квадратним заградама око листа! Такође задржавамо наводнике око сваке ставке као што смо научили у претходним нивоима. + Користимо квадратне заграде да означимо место на листи. На пример: `friends[1]` је прво име на листи пријатеља, као што можете видети у првом делу пример кода. + Други део пример кода показује да можемо такође упарити 2 листе користећи променљиву i. example_code: | ``` - friends = ['Ahmed', 'Ben', 'Cayden'] - {print} friends[1] ' is the first friend on the list.' - {print} friends[2] ' is the second friend on the list.' - {print} friends[3] ' is the third friend on the list.' - #now we will match 2 lists using the variable i - lucky_numbers = [15, 18, 6] + пријатељи = ['Ахмед', 'Бен', 'Кајден'] + {print} пријатељи[1] ' је први пријатељ на листи.' + {print} пријатељи[2] ' је други пријатељ на листи.' + {print} пријатељи[3] ' је трећи пријатељ на листи.' + # сада ћемо упарити 2 листе користећи променљиву i + срећни_бројеви = [15, 18, 6] {for} i {in} {range} 1 {to} 3 - {print} friends[i] 's lucky number is ' lucky_numbers[i] + {print} пријатељи[i] 'ов срећни број је ' срећни_бројеви[i] ``` story_text_2: |- - Now that you've learned to use the brackets in lists, you can also start using the {at} {random} command in the Python way! - You simply type the name of your list with `[random]` behind it! + Сада када сте научили да користите заграде у листама, можете почети да користите и команду {at} {random} на Питон начин! + Само укуцајте име ваше листе са `[random]` иза ње! example_code_2: |- ``` - fruit = ['apple', 'banana', 'cherry'] + fruit = ['јабука', 'банана', 'трешња'] {print} fruit[random] ``` repeat_command: name: '{repeat}' default_save_name: repeat_command - description: repeat command + description: команда {repeat} levels: 7: story_text: | - ## Repeat! Repeat! Repeat! - Level 7 adds the `{repeat}` command. `{repeat}` can be used to execute one line of code multiple times. Like this: + ## Понављај! Понављај! Понављај! + Ниво 7 додаје команду `{repeat}`. `{repeat}` се може користити за извршавање једне линије кода више пута. Овако: - ### Exercise - Play around with the repeat command. Can you make the happy birthday song in only 3 lines of code instead of 4 now? + ### Вежба + Играјте се са командом `{repeat}`. Можете ли направити песму за рођендан у само 3 линије кода уместо 4 сада? example_code: | ``` - {repeat} 3 {times} {print} 'Hedy is fun!' + {repeat} 3 {times} {print} 'Хеди је забавна!' ``` 8: story_text: | - ### Repeat commands and indentation - In this level you can repeat multiple lines of code with only 1 repeat command. - You do this by making a block of lines that you want to repeat. - The lines in this block will need **indentation** . - That means putting four spaces at the beginning of each line. You will also have to indent when you just want to create a block of one line. + ### Понављање команди и увлачење + На овом нивоу можете поновити више линија кода са само једном командом repeat. + То радите тако што правите блок линија које желите да поновите. + Линије у овом блоку ће требати **увлачење**. + То значи стављање четири размака на почетку сваке линије. Такође ћете морати да увлачите када само желите да направите блок од једне линије. example_code: | ``` {repeat} 5 {times} - {print} 'Hello everyone' - {print} 'This is all repeated 5 times' + {print} 'Здраво свима' + {print} 'Ово се понавља 5 пута' ``` 9: story_text: | - Great job! You've reached another new level! In the previous level you've learned to use multiple lines of code in an {if} or {repeat} command. But you can't yet combine the two... - Good news! In this level you will be allowed to put an {if} inside an {if}, or inside a {repeat} command. Putting a block of code inside another block of code is called nesting. ``` Putting a block of code inside another block of code is called nesting. + Одличан посао! Достигли сте још један нови ниво! На претходном нивоу сте научили да користите више линија кода у команди `{if}` или `{repeat}`. + Али још увек не можете да комбинујете то двоје... + + Добра вест! На овом нивоу ћете моћи да ставите `{if}` унутар `{if}`, `{repeat}` унутар `{repeat}` команде и једно у друго. + Пробајте! example_code: | ``` - answer = {ask} 'Are you ready to learn something new?' - {if} answer {is} yes - {print} 'Great! You can learn to use the repeat command in the if command!' - {print} 'Hooray!' - {print} 'Hooray!' - {print} 'Hooray!' - {else} - {print} 'Maybe you should practice some more in the previous level' + {repeat} 3 {times} + наруџбина = {ask} 'Шта желите да наручите?' + {if} наруџбина {is} пица + {print} 'Мммм' + {else} + {print} 'пица је боља!' + ``` repeat_command_2: name: '{repeat} 2' default_save_name: repeat_command_2 - description: repeat command 2 + description: команда {repeat} 2 levels: 7: story_text: | - ## Repeat with other commands and with variables - You have practiced the `{repeat}` command in combination with the `{print}` command now, but did you know you could also use other commands with `{repeat}` ? - In this example code you can see that `{repeat}` can also be used with an `{ask}`, `{if}` or `{else}` command. + ## Понављање са другим командама и са променљивама + Вежбали сте команду `{repeat}` у комбинацији са командом `{print}`, али да ли сте знали да можете користити и друге команде са `{repeat}`? + У овом пример коду можете видети да се `{repeat}` може користити и са командом `{ask}`, `{if}` или `{else}`. example_code: | ``` - {repeat} 2 {times} answer = {ask} 'Did you know you could ask a question multiple times?' - {if} answer {is} yes {repeat} 2 {times} {print} 'You knew that already!' - {else} {repeat} 3 {times} {print} 'You have learned something new!' + {repeat} 2 {times} одговор = {ask} 'Да ли сте знали да можете поставити питање више пута?' + {if} одговор {is} да {repeat} 2 {times} {print} 'Већ сте знали то!' + {else} {repeat} 3 {times} {print} 'Научили сте нешто ново!' ``` story_text_2: | - Another interesting thing you can so with the `{repeat}` command is using variables to set the amount of times something should be repeated. In the example code you can see that we first ask the person how old they are. - Then, in line 3, the question is repeated 'age' times. So we have used the variable 'age' with the `{repeat}` command. + Још једна занимљива ствар коју можете урадити са командом `{repeat}` је коришћење променљивих за подешавање броја пута колико нешто треба да се понови. У пример коду можете видети да прво питамо особу колико има година. + Затим, у трећем реду, питање се понавља 'године' пута. Тако смо користили променљиву 'године' са командом `{repeat}`. example_code_2: | ``` - {print} 'Yay! It is your birthday!' - age = {ask} 'How old are you now?' - {repeat} age {times} {print} 'Hip Hip Hurray!' + {print} 'Јееј! Данас ти је рођендан!' + године = {ask} 'Колико сада имаш година?' + {repeat} године {times} {print} 'Хип Хип Ура!' ``` 8: story_text: | - ### In the block or not? - In this level you have to think carefully which lines of code should be in the block and which shouldn't. - For example: If you want to sing the song *the muffin man*. You only want the line with 'the muffin man' to be repeated twice. - This means the last line shouldn't start with indentation as it doesn't belong to the block. - If you do start the last line with indentation the song will turn out wrong. + ### У блоку или не? + У овом нивоу мораш пажљиво размислити које линије кода треба да буду у блоку, а које не. + На пример: Ако желиш да певеш песму *the muffin man*. Желиш само да се линија са 'the muffin man' понови два пута. + То значи да последња линија не треба да почиње са увлачењем јер не припада блоку. + Ако започнеш последњу линију са увлачењем, песма ће бити погрешна. - ### Exercise - Each line in the example code starts with a blank. Remove the blanks and try to figure out which line need indentation and which don't to make the muffin man song. + ### Вежба + Свака линија у пример коду почиње са празним простором. Уклони празне просторе и покушај да схватиш која линија треба да има увлачење, а која не, како би песма о muffin man-у била исправна. example_code: | ``` - _ {print} 'Do you know the muffin man?' + _ {print} 'Да ли знаш човека од мафина?' _ {repeat} 2 {times} - _ {print} 'The muffin man' - _ {print} 'Do you know the muffin man, who lives on Drury Lane?' + _ {print} 'Човек од мафина' + _ {print} 'Да ли знаш човека од мафина, који живи у Друри Лејну?' ``` restaurant: - name: Restaurant - default_save_name: Restaurant - description: Create your own virtual restaurant + name: Ресторан + default_save_name: Ресторан + description: Направите свој виртуелни ресторан levels: 1: story_text: | - In level 1 you can make your own virtual restaurant and take your guests' orders. + На нивоу 1 можете направити свој виртуелни ресторан и примати наруџбине од својих гостију. story_text_2: | - ### Exercise - Copy the example code into your input screen by clicking the yellow button. - Firstly, fill in the correct command on the blanks to make to code work properly. - Then add at least 4 more lines of code to the restaurant program. - Ask the costumer what they would like to drink and ask if they want to pay with cash or card. - Lastly, think of a nice way to say goodbye to your costumer. + ### Вежба + Копирајте пример кода у свој улазни екран кликом на жути дугме. + Прво, попуните исправну команду у празнине да би код исправно радио. + Затим додајте још најмање 4 реда кода у програм ресторана. + Питајте купца шта би желео да пије и питајте да ли жели да плати готовином или картицом. + На крају, смислите леп начин да се поздравите са својим купцем. example_code_2: | ``` - {print} Welcome to Hedy's restaurant 🍟 - _ What would you like to order? - {echo} So you would like to order - {print} Thank you for your order! - {print} It's on its way! + {print} Добродошли у Хединин ресторан 🍟 + _ Шта бисте желели да наручите? + {echo} Дакле, желите да наручите + {print} Хвала вам на вашој наруџбини! + {print} Наруџбина је на путу! ``` 2: story_text: | - In level 2 you could expand your restaurant by using variables. In level 1 Hedy could only {echo} the order once and only remember the last thing that was ordered. - Now you can use variables and Hedy can remember both the food and the toppings! + На нивоу 2 можете проширити свој ресторан коришћењем променљивих. На нивоу 1 Хеди је могла само `{echo}` наруџбину једном и памтити само последњу наруџбину. + Сада можете користити променљиве и Хеди може памтити и храну и преливе! example_code: | ``` - {print} Welcome to Hedy's restaurant! - {print} Today we're serving pizza or lasagna. - food {is} {ask} What would you like to eat? - {print} Great choice! The food is my favorite! - topping {is} {ask} Would you like meat or veggies on that? - {print} food with topping is on its way! + {print} Добродошли у Хедин ресторан! + {print} Данас служимо пицу или лазање. + food {is} {ask} Шта бисте желели да једете? + {print} Одличан избор! Храна је мој омиљени! + topping {is} {ask} Да ли бисте желели месо или поврће на томе? + {print} food са topping је на путу! ``` story_text_2: | - ### Exercise - Copy your own restaurant code from to previous level to the input screen below. - Fix the code by replacing the `{ask}` and `{echo}` commands and using variables, like you've learned in this level. + ### Вежба + Копирајте свој код ресторана са претходног нивоа у улазни екран испод. + Поправите код заменом `{ask}` и `{echo}` команди и коришћењем променљивих, као што сте научили на овом нивоу. - Now that your code is working again, it's time to add something more. - Look at the last line of the example code: `{print} food with topping is on its way!` - In this single line 2 variables have been used to create a summary of the order. - Now add your own summary of the food and drinks ordered by the customer. + Сада када ваш код поново ради, време је да додате нешто више. + Погледајте последњи ред пример кода: `{print} food са topping је на путу!` + У овом једном реду коришћене су 2 променљиве за креирање резимеа наруџбине. + Сада додајте свој резиме хране и пића које је купац наручио. - **Extra** Now that you've learned how to use variables, you can use as many variables in one line as you'd like. Can you add more variables to your code, like eat in or take-away, cash or card, with or without a straw etc.? + **Додатно** Сада када сте научили како да користите променљиве, можете користити онолико променљивих у једном реду колико желите. Можете ли додати више променљивих у свој код, као што су једење у ресторану или понети, готовина или картица, са или без сламке итд.? 3: story_text: | - Having trouble to decide what you wanna have for dinner? You can let Hedy choose for you! - Simply add lists of your favorite (or least favorite) meals and Hedy can randomly choose your dinner. - You can also have a bit of fun, by letting Hedy choose the price for your dinner as well! What will you get? + Имате проблема да одлучите шта желите за вечеру? Можете дозволити Хеди да изабере за вас! + Једноставно додајте листе својих омиљених (или најмање омиљених) јела и Хеди може насумично изабрати вашу вечеру. + Такође можете мало да се забавите, тако што ћете дозволити Хеди да изабере цену за вашу вечеру! Шта ћете добити? example_code: | ``` - dishes {is} spaghetti, brussels sprouts, hamburgers - {print} You will have dishes {at} {random} tonight! - prices {is} 1 euro, 10 euros, 100 euros - {print} That will be prices {at} {random} please. + dishes {is} шпагете, прокељ, хамбургери + {print} Вечерас ћете имати dishes {at} {random}! + prices {is} 1 евро, 10 евра, 100 евра + {print} То ће бити prices {at} {random}, молим. ``` story_text_2: | - ### Exercise - Now make your own version of the random restaurant. - Make a list of starts, mains, desserts, drinks and prices yourself. - Then use `{print}` and `{at} {random}` commands to tell the costumer what will be on their menu tonight. + ### Вежба + Сада направите своју верзију насумичног ресторана. + Направите листу предјела, главних јела, десерта, пића и цена сами. + Затим користите `{print}` и `{at} {random}` команде да кажете купцу шта ће бити на њиховом менију вечерас. example_code_2: | ``` - {print} Welcome to your own random restaurant! + {print} Добродошли у ваш насумични ресторан! starters {is} _ mains {is} _ desserts {is} _ @@ -3619,508 +3662,524 @@ adventures: ``` 4: story_text: | - ### Exercise - Add the quotation marks to this code to make it work! Be careful: variables should not be in quotation marks. + У ресторану морате користити наводнике када користите `{print}` или `{ask}` команду. + + ### Вежба + Додајте наводнике овом коду да би радио! Пазите: променљиве не треба да буду у наводницима. + Затим, користите `{clear}` команду да прикажете само један ред у исто време на вашем излазном екрану. - ### Exercise 2 - Go back to the previous level and copy your restaurant code. Make the code work in this level by adding quotation marks in the right spots. + ### Вежба 2 + Вратите се на претходни ниво и копирајте свој код ресторана. Учини да код ради на овом нивоу додавањем наводника на правим местима и додајте неке `{clear}` команде. example_code: | ``` - _ Add the quotation marks to this code _ - {print} Welcome to Restaurant Chez Hedy! - {print} Today we are serving pizza or lasagna. - food {is} {ask} What would you like to eat? - {print} Great choice! The food is my favorite! - topping {is} {ask} Would you like meat or veggies on that? - {print} food with topping is on its way! - drinks {is} {ask} What would you like to drink with that? - {print} Thank you for your order. - {print} Your food and drinks will be right there! + _ Додајте наводнике овом коду _ + {print} Добродошли у Ресторан Ше Хеди! + {print} Данас служимо пицу или лазање. + food {is} {ask} Шта бисте желели да једете? + {print} Одличан избор! Храна је мој омиљени! + topping {is} {ask} Да ли бисте желели месо или поврће на томе? + {print} food са topping је на путу! + drinks {is} {ask} Шта бисте желели да пијете уз то? + {print} Хвала вам на наруџбини. + {print} Ваша храна и пиће ће ускоро стићи! ``` 5: story_text: | - In this level the `{if}` command allows you to `{ask}` your customers questions and give different responses to the answers. - In the example below, you see that you can `{ask}` the customer `{if}` they want to hear the specials and Hedy can respond accordingly. + ### Вежба + Пример кода показује како можете програмирати да сте остали без неког артикла на менију у вашем ресторану. + Копирајте свој код ресторана са претходних нивоа. Направите проблем у вашем ресторану и програмирајте га, као што је пример кода урадио. + На пример, могли бисте остати без неког артикла на менију, или не прихватате кредитне картице, или је машина за сладолед покварена. + + **Додатно** Да ли сте програмирали проблем и програмирали одговарајуће одговоре? Затим покушајте да додате више `{if}` и `{else}` команди у свој код. + Покушајте да додате `{if}` након сваке `{ask}` команде у свом коду да бисте код учинили што интерактивнијим! example_code: | ``` - {print} 'Welcome to Restaurant Chez Hedy!' - special {is} {ask} 'Would you like to hear our specials today?' - {if} special {is} yes {print} 'Todays special is chicken piri piri and rice.' {else} {print} 'No problem.' - food {is} {ask} 'What would you like to eat?' - {print} 'One ' food ', coming right up!' - drink {is} {ask} 'What would you like to drink with that?' - {if} drink {is} cola {print} 'Im sorry, we are out of cola!' {else} {print} 'Great choice!' - anything {is} {ask} 'Would you like anything else?' - {print} 'Let me repeat your order...' - {print} 'One ' food - {if} drink {is} cola {print} 'and...' {else} {print} 'One ' drink - {if} anything {is} no {print} 'Thats it!' {else} {print} 'One ' anything - {print} 'Thank you for your order and enjoy your meal!' + drinks_in_stock {is} вода, лимунада, кола, сок од поморанџе + drink {is} {ask} 'Шта бисте желели да пијете?' + {if} drink {in} drinks_in_stock {print} 'Једна ' drink ' стиже!' + {else} {print} 'Жао нам је, не продајемо то' ``` 6: story_text: | - In this level you can use maths to calculate the total price of your customer's order, which can make your virtual restaurant more realistic. + На овом нивоу можете користити математику да израчунате укупну цену наруџбине вашег купца, што може учинити ваш виртуелни ресторан реалистичнијим. + Али можете додати и много више ствари у свој виртуелни ресторан, на пример више курсева. + + ### Вежба + Можете додати много више ствари у свој виртуелни ресторан. На пример, можете ли... + - питати колико људи долази и помножити цену са тим бројем? + - додати још један курс? + - дати људима попуст када унесу (тајни) купон код? + - додати дечји мени? + - смислити друге забавне ствари за додавање? example_code: | - You can make a simple restaurant code, like this: + Можете направити једноставан код ресторана, као овај: ``` - {print} 'Welcome to Restaurant Chez Hedy' - {print} 'Here is our menu:' - {print} 'Our main courses are pizza, lasagne, or spaghetti' - main = {ask} 'Which main course would you like?' + {print} 'Добродошли у Ресторан Ше Хеди' + {print} 'Ево нашег менија:' + {print} 'Наши главни курсеви су пица, лазање или шпагети' + main = {ask} 'Који главни курс бисте желели?' price = 0 - {if} main {is} pizza price = 10 - {if} main {is} lasagne price = 12 - {if} main {is} spaghetti price = 8 - {print} 'You have ordered ' main - {print} 'That will be ' price ' dollars, please' - {print} 'Thank you, enjoy your meal!' + {if} main {is} пица price = 10 + {if} main {is} лазање price = 12 + {if} main {is} шпагети price = 8 + {print} 'Наручили сте ' main + {print} 'То ће бити ' price ' долара, молим' + {print} 'Хвала, уживајте у оброку!' ``` 7: story_text: | - In this level you've learned how to use the `{repeat}` command to repeat a line of code a certain amount of times. - You can use that in your restaurant to `{ask}` multiple people what they'd like to eat. + На овом нивоу сте научили како да користите `{repeat}` команду да поновите линију кода одређени број пута. + Можете то користити у свом ресторану да `{ask}` више људи шта би желели да једу. - ### Exercise - Can you complete the code? Hedy needs to repeat this question as many times as there are people. So if there are 5 people, the question needs to be asked 5 times. - **(extra)** Expand your code with more questions, for example about drinks or sauce. + ### Вежба + Можете ли завршити код? Хеди треба да понови ово питање онолико пута колико има људи. Дакле, ако има 5 људи, питање треба поставити 5 пута. + **Додатно** Проширите свој код са више питања, на пример о пићима или сосу. example_code: | ``` - {print} 'Welcome to Restaurant Chez Hedy' - people = {ask} 'How many people are joining us today?' + {print} 'Добродошли у Ресторан Ше Хеди' + people = {ask} 'Колико људи нам се данас придружује?' ``` 8: story_text: | - In this level you can make your virtual restaurant more elaborate by repeating multiple lines of code. Like this: + На овом нивоу можете учинити свој виртуелни ресторан сложенијим понављањем више линија кода. Као ово: - ### Exercise - This code can be expanded with more items on the menu, for example offering drinks, and/or multiple courses or desserts. Add at least one more item. - **Extra** Add even more items, as many options as you like! + ### Вежба + Овај код може бити проширен са више артикала на менију, на пример понудом пића, и/или више курсева или десерта. Додајте барем још један артикал. + **Додатно** Додајте још више артикала, колико год опција желите! example_code: | ``` - {print} 'Welcome to Restaurant Chez Hedy!' - people = {ask} 'How many people will be joining us today?' - {print} 'Great!' + {print} 'Добродошли у Ресторан Ше Хеди!' + people = {ask} 'Колико људи ће нам се данас придружити?' + {print} 'Одлично!' {repeat} people {times} - food = {ask} 'What would you like to order?' + food = {ask} 'Шта бисте желели да наручите?' {print} food - {print} 'Thank you for ordering!' - {print} 'Enjoy your meal!' + {print} 'Хвала вам на наруџбини!' + {print} 'Уживајте у оброку!' ``` 9: - story_text: "In this level you can use nesting to make your restaurant more realistic and more fun!\n\n### Exercise\nThe indentation was removed in the example code. \nCan you figure out how much indentation each line needs in order for the code to work properly?\nIf the customer orders pizza, Hedy shouldn't ask what sauce the costumer wants.\n\n**(extra)** A restaurant does not stock all sauces. Make a list of available sauces and give a reply with each order whether you sell it.
\n**(extra)** Pizzas have toppings. Ask customers what they want.
\n**(extra)** Do customers want a drink? Ask them too!
\n" + story_text: "На овом нивоу можете користити угњежђивање да бисте учинили свој ресторан реалистичнијим и забавнијим!\n\n### Вежба\nУ пример коду је уклоњено увлачење. \nМожете ли схватити колико увлачења је потребно свакој линији да би код исправно функционисао?\nАко муштерија наручи пицу, Хеди не би требало да пита који сос муштерија жели.\n\n**Додатно** Ресторан не држи све сосове на залихама. Направите листу доступних сосова и одговорите са сваком наруџбином да ли их продајете.
\n**Додатно** Пице имају преливе. Питајте муштерије шта желе.
\n**Додатно** Да ли муштерије желе пиће? Питајте их такође!
\n" example_code: | ``` - {print} 'Welcome to Restaurant Chez Hedy!' - people = {ask} 'How many people will be joining us today?' - {print} 'Great!' + {print} 'Добродошли у ресторан Chez Hedy!' + people = {ask} 'Колико људи ће нам се данас придружити?' + {print} 'Одлично!' price = 0 {repeat} people {times} - _ food = {ask} 'What would you like to order?' + _ food = {ask} 'Шта бисте желели да наручите?' _ {print} food _ {if} food {is} fries _ price = price + 3 - _ sauce = {ask} 'What kind of sauce would you like with your fries?' + _ sauce = {ask} 'Који сос бисте желели уз ваш помфрит?' _ {if} sauce {is} no - _ {print} 'no sauce' + _ {print} 'без соса' _ {else} _ price = price + 1 - _ {print} 'with ' sauce + _ {print} 'са ' sauce _ {if} food {is} pizza _ price = price + 4 - {print} 'That will be ' price ' dollar' - {print} 'Enjoy your meal!' + {print} 'То ће бити ' price ' долара' + {print} 'Уживајте у оброку!' ``` 10: story_text: | - In this level you'll learn how to easily ask orders for different courses. + На овом нивоу ћете научити како лако да питате за наруџбине за различите курсеве. - ### Exercise 1 - Finish the code with an `{ask}` on the blanks such that the customer is asked what they want to eat for each course. - example_code: "```\ncourses = appetizer, main course, dessert\n{for} course {in} courses\n {print} 'What is your order for ' course '?'\n _ \n _\n```\n" + ### Вежба 1 + Завршите код са `{ask}` на празним местима тако да муштерија буде питана шта жели да једе за сваки курс. + example_code: "```\ncourses = предјело, главно јело, десерт\n{for} course {in} courses\n {print} 'Шта је ваша наруџбина за ' course '?'\n _ \n _\n```\n" story_text_2: | - ### Exercise - Of course, you could also order for multiple people! - Can you add the correct amount of indentation before each line to make the code work properly? - Tip: some lines don't need any indentation at all. + ### Вежба + Наравно, можете наручити и за више људи! + Можете ли додати исправну количину увлачења пре сваке линије да би код исправно функционисао? + Савет: неке линије не требају никакво увлачење. example_code_2: | ``` - _ courses = appetizer, main course, dessert - _ names = Timon, Onno + _ courses = предјело, главно јело, десерт + _ names = Тимон, Оно _ {for} name {in} names _ {for} course {in} courses - _ food = {ask} name ', what would you like to eat as your ' course '?' - _ {print} name ' orders ' food ' as their ' course + _ food = {ask} name ', шта бисте желели да једете као ваше ' course '?' + _ {print} name ' наручује ' food ' као своје ' course ``` 11: story_text: | - We can use the `{for}` with `{range}` to print the orders from multiple customers in an orderly manner. + Можемо користити `{for}` са `{range}` да бисмо приказали наруџбине од више муштерија на уредан начин. - ### Exercise - Finish the restaurant code, so that you can ask for the order of multiple people. Print the order number each time: 'Order 1', 'Order 2', etc. - Are you not sure how to go about this? Have a peek at your level 8 code. + ### Вежба + Завршите код ресторана тако да можете питати за наруџбину више људи. Прикажите број наруџбине сваки пут: 'Наруџбина 1', 'Наруџбина 2', итд. + Нисте сигурни како да то урадите? Погледајте свој код са нивоа 8. - **(extra)** In level 9 the restaurant also used prices. You can add that here too! + **Додатно** На нивоу 9 ресторан је такође користио цене. Можете то додати и овде! example_code: | ``` - {print} 'Welcome to Restaurant Hedy!' - people = {ask} 'For how many people would you like to order?' - {print} 'So you want to order for ' people ' people.' - {print} "Let's go!" + {print} 'Добродошли у ресторан Хеди!' + people = {ask} 'За колико људи желите да наручите?' + {print} 'Дакле, желите да наручите за ' people ' људи.' + {print} "Хајде да почнемо!" ``` 12: story_text: | - From this level on you can use decimal numbers to make you menu more realistic. + Од овог нивоа можете користити децималне бројеве да бисте учинили свој мени реалистичнијим. - ### Exercise - Can you think of a code to give your friends and family a 15% discount? + ### Вежба + Можете ли смислити код да дате својим пријатељима и породици попуст од 15%? example_code: | ``` price = 0.0 - food = {ask} 'What would you like to order?' - drink = {ask} 'What would you like to drink?' - {if} food {is} 'hamburger' + food = {ask} 'Шта бисте желели да наручите?' + drink = {ask} 'Шта бисте желели да пијете?' + {if} food {is} 'хамбургер' price = price + 6.50 - {if} food {is} 'pizza' + {if} food {is} 'пица' price = price + 5.75 - {if} drink {is} 'water' + {if} drink {is} 'вода' price = price + 1.20 - {if} drink {is} 'soda' + {if} drink {is} 'сода' price = price + 2.35 - {print} 'That will be ' price ' dollar, please' + {print} 'То ће бити ' price ' долара, молим' ``` 13: story_text: | - In this level we can use the new commands to upgrade our restaurant. - We use `{and}` to see {if} two things are both the case. + На овом нивоу ћете научити нове команде да бисте још више проширили свој код. + + ### Вежба 1 + Поставите `{and}` и `{or}` на логично место у програму. - ### Exercise - Fill in `{and}` and `{or}` on the right blanks. + ### Вежба 2 + Проширите свој ресторан са барем једним `{and}` и једним `{or}`. + На пример, направите специјални купон за попуст који важи само за пицу, или дајте муштерији бесплатно пиће + уз помфрит и палачинке. Или нешто потпуно другачије наравно! example_code: | ``` price = 10 - food = {ask} 'What would you like to eat?' - drinks = {ask} 'What would you like to drink?' - {if} food {is} 'sandwich' _ drinks {is} 'juice' - {print} 'Thats our discount menu' + food = {ask} 'Шта бисте желели да једете?' + drinks = {ask} 'Шта бисте желели да пијете?' + {if} food {is} 'сендвич' _ drinks {is} 'сок' + {print} 'То је наш мени са попустом' price = price - 3 - {if} drinks {is} 'juice' _ drinks {is} 'sap' - {print} 'What a healthy choice!' - {print} 'That will be ' price ' dollars' + {if} drinks {is} 'вода' _ drinks {is} 'сок' + {print} 'То је здрав избор' + {print} 'То ће бити ' price ' долара' ``` 15: story_text: | - With the `{while}` you can make sure your costumers can keep adding orders until they are done. + Са `{while}` можете осигурати да ваши муштерије могу наставити да додају наруџбине док не заврше. - ### Exercise - Correctly add the `{while}` command to this code. + ### Вежба + Правилно додајте команду `{while}` у овај код. example_code: | ``` - {print} 'Welcome at McHedy' - more = 'yes' + {print} 'Добродошли у McHedy' + more = 'да' _ - order = {ask} 'What would you like to order?' + order = {ask} 'Шта бисте желели да наручите?' {print} order - more = {ask} 'Would you like to order anything else?' - {print} 'Thank you!' + more = {ask} 'Да ли бисте желели да наручите још нешто?' + {print} 'Хвала вам!' ``` rock: - name: Rock, paper, scissors - default_save_name: Rock - description: Make your own rock, paper, scissors game + name: Камен, папир, маказе + default_save_name: Камен_2 + description: Направите своју игру камен, папир, маказе levels: 1: story_text: | - In level 1 you can start with a rock, paper, scissors game. + На нивоу 1 можете започети са игром камен, папир, маказе. - With `{ask}` you can make a choice, and with `{echo}` you can repeat that choice. + Са `{ask}` можете направити избор, а са `{echo}` можете поновити тај избор. example_code: | ``` - {print} what do you choose? - {ask} choose from rock, paper or scissors - {echo} so your choice was: + {print} шта бирате? + {ask} изаберите између камен, папир или маказе + {echo} дакле ваш избор је: ``` story_text_2: | - ### Exercise - Instead of using words, you could also use emojis: ✊✋✌ - Can you create a code using emojis? + ### Вежба + Уместо речи, можете користити и емоџије: ✊✋✌ + Можете ли направити код користећи емоџије? example_code_2: | ``` - {print} what do you choose? - {ask} choose from _ - {echo} so your choice was: + {print} шта бирате? + {ask} изаберите из _ + {echo} дакле ваш избор је: ``` 2: story_text: | - In this level you can practise using the variables, so that you can make the rock, paper, scissors game in the next level! - example_code: | + На овом нивоу можете вежбати коришћење променљивих, тако да можете направити игру камен, папир, маказе на следећем нивоу! + ### Вежба + Завршите код попуњавањем **променљиве** на празном месту. + Ова игра није баш интерактивна, али не брините! У следећој картици ћете научити како да користите променљиве са командом `{ask}` да бисте учинили своју игру интерактивном! + example_code: |- ``` - _ {is} {ask} rock, paper, or scissors? - {print} I choose _ + choice {is} камен + {print} Ја бирам _ ``` 3: story_text: | - You can use the `{at} {random}` command to let the computer pick rock, paper or scissors! + Можете користити команду `{at} {random}` да дозволите рачунару да изабере камен, папир или маказе! - ### Exercise - Finish the code by using the `{at} {random}` command. + ### Вежба + Завршите код користећи команду `{at} {random}`. example_code: | ``` - choices {is} rock, paper, scissors - {print} choices {at} {random} + choices {is} камен, папир, маказе + {print} choices _ ``` story_text_2: | - ### Exercise - Copy the example code and fill in the blanks to add an extra player to this game. - - **Extra** Now the players are just called player 1 and player 2. Can you add ask commands (with variables of course) to ask the players' names? - This way you could create this output, for example: `James picks... paper` + **Додатно** Направите игру за два играча. Прво питајте два играча да унесу своја имена. Затим дозволите рачунару да насумично изабере њихове изборе. example_code_2: | ``` - choices {is} rock, paper, scissors - {print} player 1 chooses... choices {at} {random} - {print} player 2 _ + choices {is} камен, папир, маказе + player_1 {is} {ask} Име играча 1: + _ ``` 4: story_text: | - In this level we can further program rock, paper, scissors. But if you want to add text, you have to use quotation marks here too. - ### Exercise - Fill in quotation marks on the blanks. Mind that the variable `choices` should be outside the quotes. + На овом нивоу можемо даље програмирати камен, папир, маказе. Али ако желите да додате текст, морате користити наводнике и овде. + ### Вежба + Попуните наводнике на празним местима. Имајте на уму да променљива `choices` треба да буде ван наводника. example_code: | ``` - choices {is} rock, paper, scissors - {print} _The computer chooses..._ choices {at} {random} + choices {is} камен, папир, маказе + {print} _Рачунар бира..._ choices {at} {random} ``` 5: story_text: | - In this level we can determine who won. - For that you need the new `{if}` code. + На овом нивоу можемо одредити да ли је нерешено или не. За то вам је потребан нови код `{if}`. - Save your choice with the name of choice and the choice of computer as computer choice. - Then you can use `{if}` to see if they are the same or different. - Will you finish the code? + ### Вежба + Завршите код попуњавањем празнина: + * Нека рачунар изабере насумичну опцију + * Питајте играча шта жели да изабере + * Попуните тачне променљиве у реду 4 и 5 + * Завршите ред 6 тако да Хеди може проверити да ли је нерешено или не. example_code: | ``` - options {is} rock, paper, scissors + options {is} камен, папир, маказе computer_choice {is} _ - choice {is} {ask} 'What do you choose?' - {print} 'you chose ' _ - {print} 'computer chose ' _ - {if} _ {is} _ {print} 'tie!' {else} {print} 'no tie' + choice {is} _ + {print} 'изабрали сте ' _ + {print} 'рачунар је изабрао ' _ + {if} _ {is} _ {print} 'нерешено!' {else} {print} 'није нерешено' ``` - Fill in the correct code on the blanks to see {if} it is a draw. + Попуните тачан код на празним местима да видите да ли је нерешено. 9: - story_text: "In this level you can program the whole rock, paper, scissors game by nesting the `{if}` commands. \n\n### Exercise\nCan you finish the code? The program must tell who has won for every combination.\n\n**(extra)** Want to play more than one game? Expand the code so that you can play multiple rounds. You can even use an `{ask}` to ask the user how many rounds they want to play.\n" + story_text: "На овом нивоу можете програмирати целу игру камен, папир, маказе угнежђивањем команди `{if}`.\n\n### Вежба\nМожете ли завршити код? Програм мора да каже ко је победио за сваку комбинацију.\n\n**Додатно** Желите ли да играте више од једне игре? Проширите код тако да можете играти више рунди. Можете чак користити `{ask}` да питате корисника колико рунди жели да игра.\n" example_code: | ``` - choices = rock, paper, scissors - your_choice = {ask} 'What do you choose?' - {print} 'You choose ' your_choice - computer_choice = choices {at} {random} - {print} 'The computer chooses ' computer_choice + choices = камен, папир, маказе + your_choice {is} {ask} 'Шта бирате?' + {print} 'Изабрали сте ' your_choice + computer_choice {is} choices {at} {random} + {print} 'Рачунар је изабрао ' computer_choice {if} computer_choice {is} your_choice - {print} 'Tie' - {if} computer_choice {is} rock - {if} your_choice {is} paper - {print} 'You win!' - {if} your_choice {is} scissors - {print} 'You lose!' - # finish this code + {print} 'Нерешено' + {if} computer_choice {is} камен + {if} your_choice {is} папир + {print} 'Победили сте!' + {if} your_choice {is} маказе + {print} 'Изгубили сте!' + # завршите овај код ``` 10: story_text: | - Feeling too lazy to play the game yourself? Let Hedy play it for you! - You only have to fill in the names of the players and they get a random choice. - - ### Exercise 1 - Finish the program by filling in a list of names. - - ### Exercise 2 - Add a computer player that chooses with each player. - - **(extra)** Go back to your code and decide who wins in each round: the computer or the named person. + ### Вежба + На претходним нивоима често сте правили своју игру камен, папир, маказе. Можете ли завршити код и правилно користити команду `{for}` да игра проради? example_code: | ``` - choices = rock, paper, scissors + choices = _ players = _ - {for} player {in} players - {print} player ' chooses ' choices {at} {random} + {for} _ ``` 13: story_text: | - With the `{and}` command you can shorten your rock, paper, scissors code! Check out the example code below and try to finish it. + Са командом `{and}` можете скратити свој код за камен, папир, маказе! Погледајте пример кода. + + ### Вежба + Завршите код тако да се увек одлучи победник. Покрените свој код неколико пута да бисте проверили да ли се увек исписује победник. example_code: | ``` - options = 'rock', 'paper', 'scissors' - your_choice = {ask} 'What do you choose?' + options = 'камен', 'папир', 'маказе' + your_choice = {ask} 'Шта бирате?' computer_choice = options {at} {random} - {print} 'You choose ' your_choice - {print} 'The computer chooses ' computer_choice + {print} 'Изабрали сте ' your_choice + {print} 'Рачунар је изабрао ' computer_choice {if} computer_choice {is} your_choice - {print} 'Tie' - {if} computer_choice {is} 'rock' {and} your_choice {is} 'paper' - {print} 'You win!' - {if} computer_choice {is} 'rock' {and} your_choice {is} 'scissors' - {print} 'The computer wins!' + {print} 'Нерешено' + {if} computer_choice {is} 'камен' {and} your_choice {is} 'папир' + {print} 'Победили сте!' + {if} computer_choice {is} 'камен' {and} your_choice {is} 'маказе' + {print} 'Рачунар је победио!' _ ``` 15: story_text: | - ### Exercise - Play until you beat the computer! But first, finish the example code... + ### Вежба + Играјте док не победите рачунар! Али прво, завршите пример кода... example_code: | ``` - won = 'no' - options = 'rock', 'paper', 'scissors' - {while} won == 'no' - your_choice = {ask} 'What do you choose?' + won = 'не' + options = 'камен', 'папир', 'маказе' + {while} won == 'не' + your_choice = {ask} 'Шта бирате?' computer_choice = options {at} {random} - {print} 'you chose ' your_choice - {print} 'the computer chose ' computer_choice + {print} 'изабрали сте ' your_choice + {print} 'рачунар је изабрао ' computer_choice {if} computer_choice == your_choice - {print} 'Tie!' - {if} computer_choice == 'rock' {and} your_choice == 'scissors' - {print} 'You lose!' - {if} computer_choice == 'rock' {and} your_choice == 'paper' - {print} 'You win!' - won = 'yes' + {print} 'Нерешено!' + {if} computer_choice == 'камен' {and} your_choice == 'маказе' + {print} 'Изгубили сте!' + {if} computer_choice == 'камен' {and} your_choice == 'папир' + {print} 'Победили сте!' + won = 'да' _ ``` rock_2: - name: Rock, paper, scissors 2 + name: Камен, папир, маказе 2 default_save_name: rock_2 - description: Part 2 of rock, paper, scissors + description: Други део камен, папир, маказе levels: 2: story_text: | - Now that you have learned how to use the `{ask} command, you can make your rock, paper, scissors code interavtive too! + Сада када си научио како да користиш команду `{ask}`, можеш учинити свој код за камен, папир, маказе интерактивним! - ### Exercise - Make the rock, paper, scissors code interactive by adding the `{ask}` command and a question to your rock, paper, scissors code. + ### Вежба + Учини код за камен, папир, маказе интерактивним додавањем команде `{ask}` и питања у свој код за камен, папир, маказе. example_code: | ``` - choice is _ - {print} I choose choice + избор {is} _ + {print} Бирам избор ``` secret: - name: SuperSpy - default_save_name: SuperSpy - description: Make your own spy code + name: СуперШпијун + default_save_name: СуперШпијун + description: Направите свој шпијунски код levels: 12: story_text: | - In this adventure you can create your own super spy code. Encode a message that only the right agent can decipher. - If the enemy tries to crack the code, they will get some false info to waste their time. + У овој авантури можете креирати свој супер шпијунски код. Шифрујте поруку коју само прави агент може дешифровати. + Ако непријатељ покуша да разбије код, добиће лажне информације да изгуби време. + + ### Вежба 1 + Направите свој тајни код за свог супер шпијуна и вратите оба дела само правом шпијуну. - ### Exercise - Make your own secret code for your superspy. Can you make it consist of even more variables? + ### Вежба 2 + Додајте трећу компоненту коду, као што је комад одеће или предмет. example_code: | ``` - name {is} {ask} 'What is your name?' - {if} name {is} '_' - a {is} 'Go to the airport ' + име = {ask} 'Како се зовеш?' + {if} име {is} _ + a = 'Иди на аеродром ' {else} - a {is} 'Go to the trainstation ' - password {is} {ask} 'What is the password?' - {if} password {is} _ - b {is} 'tomorrow at 02.00' + a = 'Иди на железничку станицу ' + лозинка = {ask} 'Која је лозинка?' + {if} лозинка {is} _ + b = 'сутра у 02.00' {else} - b {is} 'today at 10.00' + b = 'данас у 10.00' {print} _ _ _ ``` 13: story_text: | - Can you fill in the right command on the blank? Mind: The superspy has to answer BOTH questions correctly, before they get the confidential information! + Можемо поједноставити супер шпијунски код са `{and}`, тако да нам је потребан само један `{if}`. + + ### Вежба 1 + Довршите код попуњавањем праве команде на празном месту. Савет: Супер шпијун мора тачно одговорити на ОБА питања пре него што добије поверљиве информације! + + ### Вежба 2 + Желимо још више збунити непријатеља! Направите листу са лажним одговорима и изаберите један насумично када се да погрешан одговор. example_code: | ``` - name = {ask} 'What is your name?' - password = {ask} 'What is your password?' - {if} name {is} 'Agent007' _ password {is} 'TOPSECRET' - {print} 'Go to the airport at 02.00' + име = {ask} 'Како се зовеш?' + лозинка = {ask} 'Која је твоја лозинка?' + {if} име {is} 'Агент007' _ лозинка {is} 'СТРОГОПОВЕРЉИВО' + {print} 'Иди на аеродром у 02.00' {else} - {print} 'Go to the trainstation at 10.00' + {print} 'Иди на железничку станицу у 10.00' ``` simon: - name: Simon Says - default_save_name: Simon - description: Make a game of Simon Says + name: Симон каже + default_save_name: Симон + description: Направите игру Симон каже levels: 16: story_text: | - Let's make a game of Simon Says! Simon Says is a memory game in which the player will be given a color. They have to repeat that color back. - If they get it right a color is added to the sequence, so they now have to remember 2 colors, then 3, then 4 etc. the game stops as soon as the player makes a mistake. + Хајде да направимо игру Симон каже! Симон каже је игра памћења у којој ће играчу бити дата боја. Они морају да понове ту боју. + Ако погоде, додаје се нова боја у секвенцу, тако да сада морају да запамте 2 боје, затим 3, затим 4 итд. игра се завршава чим играч направи грешку. - ### Exercise - In this first part of the Simon Says adventure, we'll let the computer pick a random color and add it to a list. + ### Вежба + У овом првом делу авантуре Симон каже, пустићемо рачунар да изабере насумичну боју и дода је у листу. - ***Make 2 lists*** First, make a list called `colors` and fill it with the colors red, yellow, green and blue. - Then make a list called `simon_sequence`. This list will be used as the answer. - At the start of the game this lists need to be empty. unfortunately, we can't create an empty list (yet), so we'll fill it with the words 'empty' and 'list' and we'll remove them from the list immediately. + ***Направите 2 листе*** Прво, направите листу под називом `colors` и попуните је бојама црвена, жута, зелена и плава. + Затим направите листу под називом `simon_sequence`. Ова листа ће се користити као одговор. + На почетку игре ова листа треба да буде празна. нажалост, не можемо још увек направити празну листу, па ћемо је попунити речима 'empty' и 'list' и одмах ћемо их уклонити из листе. - ***Create a function that adds a color to the sequence*** Now that we have an empty list called simon_sequence, we can start filling it with random colors. - We do that with a function, so we can call it everytime there's a new level in our game. Create a function called `add_random_color`. - Then create the variable random_color and set it to a random color. Next, add this random color to the simon_sequence. + ***Направите функцију која додаје боју у секвенцу*** Сада када имамо празну листу под називом simon_sequence, можемо почети да је попуњавамо насумичним бојама. + То радимо са функцијом, тако да можемо да је позовемо сваки пут када постоји нови ниво у нашој игри. Направите функцију под називом `add_random_color`. + Затим направите променљиву random_color и подесите је на насумичну боју. Затим додајте ову насумичну боју у simon_sequence. - ***Create a function that shows the simon_sequence*** Start by naming the new function `show_simon_sequence` with `level` as an argument. Now we want to show as many colors as the level we are in (in level 1 you see 1 color, in level 2 you see 2 colors etc). - So we repeat `level` times, to print the `simon_sequence[i]`. Each time a color is shown, wait for 1 second and then clear the screen. + ***Направите функцију која приказује simon_sequence*** Почните тако што ћете именовати нову функцију `show_simon_sequence` са `level` као аргументом. Сада желимо да прикажемо онолико боја колико је ниво на коме се налазимо (на нивоу 1 видите 1 боју, на нивоу 2 видите 2 боје итд). + Тако да понављамо `level` пута, да бисмо одштампали `simon_sequence[i]`. Сваки пут када се прикаже боја, сачекајте 1 секунду и затим очистите екран. - ***Test your program*** Before you go to the next level, test if the functions are working by calling both of the functions. If they're working you should see a random color in your output screen. - Remove this testing part of your code, copy the code and continue to the next tab to learn more about the simon says game! + ***Тестирајте свој програм*** Пре него што пређете на следећи ниво, тестирајте да ли функције раде позивањем обе функције. Ако раде, требало би да видите насумичну боју на свом излазном екрану. + Уклоните овај део кода за тестирање, копирајте код и наставите на следећу картицу да бисте сазнали више о игри Симон каже! example_code: | ``` - # Make 2 lists + # Направите 2 листе colors = _ _ = ['empty', 'list'] {remove} _ {from} simon_sequence {remove} _ - # Create a function that adds a color + # Направите функцију која додаје боју _ add_random_color _ {add} _ - # Create a function that shows the simon_sequence + # Направите функцију која приказује simon_sequence {define} _ {for} i {in} {range} 1 {to} _ {print} _ _ _ - # Test your program + # Тестирајте свој програм {call} _ {call} show_simon_sequence {with} 1 ``` simon_2: - name: Simon Says 2 - default_save_name: Simon - description: Make a game of Simon Says + name: Симон каже 2 + default_save_name: Симон + description: Направите игру Симон каже levels: 16: story_text: | - We'll continue with our Simon Says game! + Наставићемо са нашом игром Симон каже! - ### Exercise - ***Paste your code here*** Paste your code from the previous level here. Don't forget to remove the part that was just used for testing the functions. + ### Вежба + ***Налепите свој код овде*** Налепите свој код са претходног нивоа овде. Не заборавите да уклоните део који је коришћен само за тестирање функција. - ***Create a function that creates the player_sequence*** The list `player_sequence` is used to capture the answers of the player. First we define the function with the argument level. - Next, we ask level times what the color is that they choose. We call that variable `answer`. Then we add the variable `answer` to the list player_sequence. + ***Направите функцију која креира player_sequence*** Листа `player_sequence` се користи за хватање одговора играча. Прво дефинишемо функцију са аргументом ниво. + Затим, питамо ниво пута коју боју бирају. Ту променљиву називамо `answer`. Затим додајемо променљиву `answer` у листу player_sequence. - ***Setting up the game*** Before we program the game in the next tab, we'll need some starting variables. First, we'll set the variable `level` to 1 and the variable `game_over` to False. - Then we make an introduction for the game. We'll print 'Welcome to Simon Says!' and clear the screen after 1 second. + ***Подешавање игре*** Пре него што програмирамо игру на следећој картици, биће нам потребне неке почетне променљиве. Прво, подесићемо променљиву `level` на 1 и променљиву `game_over` на False. + Затим правимо увод за игру. Одштампаћемо 'Добродошли у Симон каже!' и очистити екран након 1 секунде. - ***Continue to the next tab to finish the game!**** Don't forget to copy your code and take it with you to the next tab. + ***Наставите на следећу картицу да завршите игру!**** Не заборавите да копирате свој код и понесете га са собом на следећу картицу. example_code: | ``` - # Paste your code here + # Налепите свој код овде - # Create a function that creates the player_sequence + # Направите функцију која креира player_sequence {define} _ {for} _ - _ 'What is color number ' i '?' + _ 'Која је боја број ' i '?' {add} answer {to} _ - # Set up + # Подешавање level = _ game_over = _ {print} _ @@ -4128,30 +4187,30 @@ adventures: _ ``` simon_3: - name: Simon Says 3 - default_save_name: Simon - description: Make a game of Simon Says + name: Симон каже 3 + default_save_name: Симо + description: Направи игру Симо каже levels: 16: story_text: | - In this tab we'll program the game of Simon Says! + У овом табу ћемо програмирати игру Симо каже! - ### Exercise - ***Paste your code*** Copy your code from the previous tab and paste it here. + ### Вежба + ***Налепи свој код*** Копирај свој код из претходног таба и налепи га овде. - ***Program the game*** We start by making sure the game goes on while the game isn't over. Then we print what level the player is on, we use the variable level for that. We only show that for 1 second and then we clear the screen again. - Now, we have to create the empty list player_sequence. We've already programmed how to fill the list, with our function `player_sequence`, but we never made the list itself. To create the list we use the same trick as we did in the previous tab. - We'll make a list with the words 'empty' and 'list' on it, and then we remove both these words. Next, we'll call all of the 3 functions that we've created. - Lastly, we'll have to check if the player gave the correct answers (so if the player_sequence and the simon_sequence are the same). - If that's the case, we'll compliment the player. Wait for 1 second and increase the level with 1. - Did the player give the wrong answer, we'll tell them and end the game by setting game_over to 'True' + ***Програмирај игру*** Почећемо тако што ћемо осигурати да игра траје док игра није завршена. Затим ћемо исписати на ком нивоу је играч, користимо променљиву ниво за то. Приказаћемо то само 1 секунду и затим поново очистити екран. + Сада, морамо да направимо празну листу player_sequence. Већ смо програмирали како да попунимо листу, са нашом функцијом `player_sequence`, али никада нисмо направили саму листу. Да бисмо направили листу користимо исти трик као у претходном табу. + Направићемо листу са речима 'empty' и 'list' на њој, а затим ћемо уклонити обе ове речи. Следеће, позваћемо све 3 функције које смо направили. + На крају, морамо проверити да ли је играч дао тачне одговоре (тако да ли су player_sequence и simon_sequence исти). + Ако је то случај, похвалићемо играча. Сачекаћемо 1 секунду и повећати ниво за 1. + Ако је играч дао погрешан одговор, рећи ћемо му и завршити игру постављањем game_over на 'True'. - ***Enjoy your game!*** Great job! Does your game not work? Use the ladybug button to debug your code! + ***Уживај у својој игри!*** Одличан посао! Да ли твоја игра не ради? Користи дугме са бубамаром да отклониш грешке у свом коду! example_code: | ``` - # Paste your code here + # Налепи свој код овде - # The game + # Игра {while} game_over _ {print} _ _ @@ -4173,150 +4232,152 @@ adventures: sleep_command: name: '{sleep}' default_save_name: sleep_command - description: introducing sleep command + description: увођење команде {sleep} levels: 2: story_text: | - ## The sleep command - Another new command in this level is `{sleep}`, which pauses your program for a second. If you type a number behind the {sleep} command, the program pauses for that amount of seconds. + Још једна нова команда на овом нивоу је `{sleep}`, која паузира ваш програм на секунду. Ако укуцате број иза команде {sleep}, програм ће паузирати на тај број секунди. + + ### Вежба + Вежбајте ову нову команду тако што ћете направити свој код у којем ћете користити команду {sleep} најмање 3 пута. Са сваком командом {sleep} време паузе треба да буде различито. example_code: | ``` - {print} My favorite colour is... + {print} Моја омиљена боја је... {sleep} 2 - {print} green! + {print} зелена! ``` songs: - name: Sing a song! - default_save_name: Song - description: Print a song + name: Певај песму! + default_save_name: Песма + description: Одштампај песму levels: 6: story_text: | - Songs often contain a lot of repetition. Sometimes the repetition is also based on counting. - For example, in the well-known song 'Bottles of beer'. You can program that song with a little math. + Песме често садрже много понављања. Понекад је понављање такође засновано на бројању. + На пример, у добро познатој песми 'Бочице пива'. Можеш програмирати ту песму са мало математике. - Tip: Use the read aloud function to let Hedy sing the song to you! + Савет: Користи функцију читања наглас да би Хеди отпевао песму за тебе! - ### Exercise - You can now repeat lines 2 to 7 as many times as you want by copying the lines. + ### Вежба + Сада можеш понављати линије 2 до 7 колико год пута желиш копирањем линија. example_code: | ``` - verse = 99 - {print} verse ' bottles of beer on the wall' - {print} verse ' bottles of beer' - {print} 'Take one down, pass it around' - verse = verse - 1 - {print} verse ' bottles of beer on the wall' + стих = 99 + {print} стих ' бочица пива на зиду' + {print} стих ' бочица пива' + {print} 'Скини једну, пусти је у круг' + стих = стих - 1 + {print} стих ' бочица пива на зиду' {sleep} ``` story_text_2: | - This children's song counts down from 5 little monkeys to 1 monkey. - If you copy line 2 - 7 and paste it under the the code, you can sing the whole song! + Ова дечија песма броји од 5 малих мајмуна до 1 мајмуна. + Ако копираш линије 2 - 7 и налепиш их испод кода, можеш отпевати целу песму! example_code_2: | ``` - number = 6 - number = number - 1 - {print} number ' little monkeys jumping on the bed' - {print} 'One fell off and bumped his head' - {print} 'Mama called the doctor and the doctor said' - {print} 'NO MORE MONKEYS JUMPING ON THE BED!' + број = 6 + број = број - 1 + {print} број ' малих мајмуна скаче по кревету' + {print} 'Један је пао и ударио главу' + {print} 'Мама је позвала доктора и доктор је рекао' + {print} 'НЕМА ВИШЕ МАЈМУНА КОЈИ СКАЧУ ПО КРЕВЕТУ!' {sleep} ``` 7: story_text: | - Songs often contain a lot of repetition. For example... Baby Shark! If you sing it, you keep singing the same thing: + Песме често садрже много понављања. На пример... Бејби Шарк! Ако је певате, стално певате исту ствар: - Baby Shark tututudutudu
- Baby Shark tututudutudu
- Baby Shark tututudutudu
- Baby Shark + Бејби Шарк тутутудутуду
+ Бејби Шарк тутутудутуду
+ Бејби Шарк тутутудутуду
+ Бејби Шарк - ### Exercise - You can print the song Baby Shark with a `{repeat}`? Finish the code by replacing the blanks? - **Extra** After Baby Shark you can of course also program other songs. There are many songs with repetition! - Can you think of one more song and print it? + ### Вежба + Можеш ли одштампати песму Бејби Шарк са `{repeat}`? Заврши код заменом празних места? + **Додатно** Након Бејби Шарк можеш наравно програмирати и друге песме. Постоји много песама са понављањем! + Можеш ли смислити још једну песму и одштампати је? example_code: | ``` - {repeat} _ _ {print} 'Baby Shark tututudutudu' - {print} 'Baby Shark' + {repeat} _ _ {print} 'Бејби Шарк тутутудутуду' + {print} 'Бејби Шарк' ``` 8: story_text: | - In a previous level you've programmed the song 'Bottles of beer'. But without the `{repeat}` command, you had to copy the verses many times. - In this level you can repeat the song 99 times, just by adding one simple line! + На претходном нивоу програмирао си песму 'Бочице пива'. Али без команде `{repeat}`, морао си много пута копирати стихове. + На овом нивоу можеш поновити песму 99 пута, само додавањем једне једноставне линије! - ### Exercise - Add the right command on the blanks and indent the code correctly. + ### Вежба + Додај праву команду на празна места и правилно увуци код. example_code: | ``` - verse = 99 + стих = 99 _ 99 {times} - {print} verse ' bottles of beer on the wall' - {print} verse ' bottles of beer' - {print} 'Take one down, pass it around' - verse = verse - 1 - {print} verse ' bottles of beer on the wall' + {print} стих ' бочица пива на зиду' + {print} стих ' бочица пива' + {print} 'Скини једну, пусти је у круг' + стих = стих - 1 + {print} стих ' бочица пива на зиду' ``` 10: story_text: | - With `{for}` you can print make the whole baby shark song (including all the other sharks in the family) in only 6 lines! + Са `{for}` можеш направити целу песму Бејби Шарк (укључујући све остале ајкуле у породици) у само 6 линија! - ### Exercise 1 - Can you make the baby shark code even shorter by using a `{for}` command? Finish the example code. - example_code: "```\nfamily = baby, mammy, daddy, grandma, grandpa\n_ _ _ _ \n {print} _\n```\n" + ### Вежба 1 + Можеш ли учинити код за Бејби Шарк још краћим коришћењем команде `{for}`? Заврши пример кода. + example_code: "```\nпородица = беба, мама, тата, бака, дека\n_ _ _ _ \n {print} _\n```\n" story_text_2: | - ### Exercise 2 - Print the song Five little moneys jumping on the bed. Look up the text if you don't remember. + ### Вежба 2 + Одштампај песму Пет малих мајмуна који скачу по кревету. Потражи текст ако се не сећаш. - **(extra)** Print the song Old MacDonald had a farm, and make sure all animals make a different sound, using an `{if}`. + **Додатно** Одштампај песму Стари Макдоналд је имао фарму, и увери се да све животиње праве различите звуке, користећи `{if}`. example_code_2: | ``` - monkeys = 5, 4, 3, 2, 1 + мајмуни = 5, 4, 3, 2, 1 ``` 11: story_text: | - In this level you can use the `{for}` with `{range}` to make songs that use counting, like the 5 little monkeys. + На овом нивоу можеш користити `{for}` са `{range}` да направиш песме које користе бројање, као што је песма о 5 малих мајмуна. - ### Exercise 1 - Fill in the blanks and make the code work! If you don't remember the song text, look it up yourself. + ### Вежба 1 + Попуни празнине и учини да код ради! Ако се не сећаш текста песме, потражи га сам. - ### Exercise 2 - The final line of the song is different from the others. Print this line inside the `{for}`, and use an `{if}` to make it work correctly. + ### Вежба 2 + Завршна линија песме је другачија од осталих. Одштампај ову линију унутар `{for}`, и користи `{if}` да би радила исправно. example_code: | ``` - _ monkeys _ _ 5 _ 1 - {print} monkeys ' little monkeys jumping on the bed' + _ мајмуни _ _ 5 _ 1 + {print} мајмуни ' малих мајмуна скаче по кревету' _ ``` 12: story_text: | - In this song we can make it even easier to program 'if you're happy and you know it, clap your hands'. Because we can put all of the actions in a variable, check it out: + У овој песми можемо још лакше програмирати 'ако си срећан и знаш то, пљесни рукама'. Јер можемо ставити све радње у променљиву, погледај: - ### Exercise - Can you add the right amount of indentation to each line to make the song play correctly? - Hint: Not all lines need indentation. + ### Вежба + Можеш ли додати праву количину увлачења свакој линији да би песма радила исправно? + Савет: Нису све линије потребне увлачење. example_code: | ``` - _ actions = 'clap your hands', 'stomp your feet', 'shout Hurray!' - _ {for} action {in} actions + _ радње = 'пљесни рукама', 'лупи ногама', 'викни Ура!' + _ {for} радња {in} радње _ {for} i {in} {range} 1 {to} 2 - _ {print} 'if youre happy and you know it' - _ {print} action - _ {print} 'if youre happy and you know it and you really want to show it' - _ {print} 'if youre happy and you know it' - _ {print} action + _ {print} 'ако си срећан и знаш то' + _ {print} радња + _ {print} 'ако си срећан и знаш то и стварно желиш да покажеш' + _ {print} 'ако си срећан и знаш то' + _ {print} радња ``` 13: story_text: | - In the previous adventure you have learned how to use an argument in a function, but did you know that you could combine them with {ask} commands as well? - In this example we have changed the 'My Bonnie' program and made it interactive. You are now asked where Bonnie is. + У претходној авантури научили сте како да користите аргумент у функцији, али да ли сте знали да их можете комбиновати и са {ask} командама? + У овом примеру смо променили програм 'My Bonnie' и учинили га интерактивним. Сада вас питају где је Бони. example_code: | ``` {define} song {with} place - {print} 'My Bonnie is ' place + {print} 'Моја Бони је ' place - chosen_place = {ask} 'Where do you want Bonnie to be?' - synonym = {ask} 'What is another word for that?' + chosen_place = {ask} 'Где желите да буде Бони?' + synonym = {ask} 'Која је друга реч за то?' {call} song {with} chosen_place {call} song {with} synonym @@ -4324,272 +4385,272 @@ adventures: ``` 16: story_text: | - In this level, you can program a song like OldMacDonald even more quickly. You can connect the right animal to the right sound by simply putting them in the same place in the list. - The Drunken Sailor is also quickly made in this level. You only need 8 lines for the entire song, check it out! + На овом нивоу можеш програмирати песму као што је Стари Макдоналд још брже. Можеш повезати праву животињу са правим звуком једноставним стављањем на исто место у листи. + Пијани морнар је такође брзо направљен на овом нивоу. Потребно ти је само 8 линија за целу песму, погледај! - ### Exercise - Complete the Old MacDonald song by setting the variable `animal` to `animals[i]` and `sound` to `sounds[i]`. + ### Вежба + Заврши песму Стари Макдоналд постављањем променљиве `animal` на `animals[i]` и `sound` на `sounds[i]`. example_code: | ``` - animals = ['pig', 'dog', 'cow'] - sounds = ['oink', 'woof', 'moo'] + животиње = ['свиња', 'пас', 'крава'] + звукови = ['грок', 'ав', 'му'] {for} i {in} {range} 1 {to} 3 - animal = _ - sound = _ - {print} 'Old MacDonald had a farm' - {print} 'E I E I O!' - {print} 'and on that farm he had a ' animal - {print} 'E I E I O!' - {print} 'with a ' sound sound ' here' - {print} 'and a ' sound sound ' there' - {print} 'here a ' sound - {print} 'there a ' sound - {print} 'everywhere a ' sound sound - ``` - - ``` - lines = ['what shall we do with the drunken sailor', 'shave his belly with a rusty razor', 'put him in a long boat till hes sober'] - {for} line {in} lines + животиња = _ + звук = _ + {print} 'Стари Макдоналд је имао фарму' + {print} 'Е И Е И О!' + {print} 'и на тој фарми је имао ' животиња + {print} 'Е И Е И О!' + {print} 'са ' звук звук ' овде' + {print} 'и ' звук звук ' тамо' + {print} 'овде ' звук + {print} 'тамо ' звук + {print} 'свуда ' звук звук + ``` + + ``` + линије = ['шта ћемо радити са пијаним морнаром', 'обриј му стомак рђавом бритвом', 'стави га у дугачки чамац док не отрезни'] + {for} линија {in} линије {for} i {in} {range} 1 {to} 3 - {print} line - {print} 'early in the morning' + {print} линија + {print} 'рано ујутро' {for} i {in} {range} 1 {to} 3 - {print} 'way hay and up she rises' - {print} 'early in the morning' + {print} 'хеј хеј и горе она иде' + {print} 'рано ујутро' ``` 18: story_text: | - In level 16 we made songs using lists. These programs however are no longer working properly in this level. The colons from level 17 and the brackets from level 18 still need to be added. + На нивоу 16 смо правили песме користећи листе. Међутим, ови програми више не раде исправно на овом нивоу. Двојне тачке из нивоа 17 и заграде из нивоа 18 још увек треба додати. - ### Exercise 1 - The Drunken sailor song is given as sample code, but not yet working. - Can you make sure everything works again? To help you, we've put _ in the places of _some_ errors. + ### Вежба 1 + Песма "Пијани морнар" је дата као пример кода, али још увек не ради. + Можете ли осигурати да све поново ради? Да бисмо вам помогли, ставили смо _ на места неких грешака. - ### Exercise 2 - Now also look up your Old MacDonald song from level 16, and correct it. + ### Вежба 2 + Сада такође пронађите своју песму "Стари Макдоналд" са нивоа 16 и исправите је. example_code: | ``` - lines = ['what shall we do with the drunken sailor', 'shave his belly with a rusty razor', 'put him in a long boat till hes sober'] + lines = ['шта ћемо радити са пијаним морнаром', 'обријати му стомак рђавом бритвом', 'ставити га у дугачки чамац док не отрезни'] {for} line {in} lines _ {for} i {in} {range} 1 {to} 3 _ {print} _ line _ - {print} 'early in the morning' + {print} 'рано ујутру' {for} i {in} {range} 1 {to} 3 - {print} 'way hay and up she rises' - {print} 'early in the morning' + {print} 'хајде хеј и горе она иде' + {print} 'рано ујутру' ``` songs_2: - name: Sing a song! 2 - default_save_name: Song 2 - description: Sing a song 2 + name: Певај песму! 2 + default_save_name: Песма 2 + description: Певај песму 2 levels: 12: story_text: | - Songs contain a lot of repetition. We can capture it with a function! - ### Exercise - Look at the example code with the function. Fill out the two lines so the full song is printed. + Песме садрже много понављања. Можемо их обухватити функцијом! + ### Вежба + Погледајте пример кода са функцијом. Попуните две линије тако да се цела песма испише. example_code: | ``` {define} twinkle - {print} 'Twinkle' - {print} '...' + {print} 'Трепери' + {print} _ {call} twinkle - {print} 'Up above the world so high' - {print} 'Like a diamond in the sky' + {print} 'Горе изнад света тако високо' + {print} 'Као дијамант на небу' {call} _ ``` 16: story_text: | - ### Exercise - Finish the nursery rhyme! + ### Вежба + Завршите дечију песмицу! example_code: | ``` - number = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'] - object = ['on his drum', 'on his shoe', 'on his knee', 'on his door', 'on his hive', 'on his sticks', 'up in heaven', 'on his gate', 'on his vine', 'once again'] + number = ['један', 'два', 'три', 'четири', 'пет', 'шест', 'седам', 'осам', 'девет', 'десет'] + object = ['на свом бубњу', 'на својој ципели', 'на свом колену', 'на својим вратима', 'на својој кошници', 'на својим штаповима', 'горе на небу', 'на својој капији', 'на својој лози', 'поново'] _ - {print} 'This old man' - {print} 'He played ' _ - {print} 'He played knick-knack ' _ - {print} 'With a knick-knack paddywhack' - {print} 'Give the dog a bone' - {print} 'This old man came rolling home' + {print} 'Овај стари човек' + {print} 'Он је свирао ' _ + {print} 'Он је свирао кник-кнак ' _ + {print} 'Са кник-кнак педи-ваком' + {print} 'Дајте псу кост' + {print} 'Овај стари човек се вратио кући' {sleep} 8 {clear} ``` story_text_2: | - ### Exersice 2 - Now create your own code for the nursery rhyme 'The wheels on the bus' on the same way! + ### Вежба 2 + Сада направите свој код за дечију песму 'Точкови на аутобусу' на исти начин! example_code_2: | ``` - object = ['wheels', 'doors', _] - movement = [ 'round and round', 'open and shut', _] + object = ['точкови', 'врата', _] + movement = [ 'окрећу се и окрећу', 'отварају се и затварају', _] ``` tic: - name: Tic-Tac-Toe - default_save_name: Tic - description: Play a game of Tic Tac Toe! + name: Икс-Окс + default_save_name: Икс + description: Играјте игру Икс Окс! levels: 16: story_text: | - Let's program a game of tic-tac-toe! + Хајде да програмирамо игру икс-окс! - ### Exercise - In this adventure we'll start with creating an empty field. + ### Вежба + У овој авантури почећемо са креирањем празног поља. - ***Create a list called field*** This list will be our playing field. This list is filled with 9 dots, since there are no x's and o's yet at the start of our game. + ***Креирај листу звану поље*** Ова листа ће бити наше игралиште. Ова листа је испуњена са 9 тачака, јер на почетку наше игре нема иксова и окова. - ***Create a function that prints the field*** Firstly, clear the screen so the old playing fields will be removed. Then we print the first line of our Tic Tac Toe field. This line constists of the first 3 spots in our list field. - We have already programmed this line for you. Now finish the field by printing spot 4, 5, and 6 on the second row and spot 7, 8 and 9 in the third row. + ***Креирај функцију која штампа поље*** Прво, очисти екран да би уклонио стара игралишта. Затим штампамо прву линију нашег поља за икс-окс. Ова линија се састоји од прва 3 места у нашој листи поље. + Већ смо програмирали ову линију за тебе. Сада заврши поље штампањем места 4, 5 и 6 у другом реду и места 7, 8 и 9 у трећем реду. - ***Call the function that prints the field*** Now call the function. + ***Позови функцију која штампа поље*** Сада позови функцију.
- Run the code. Your output should look like this: + Покрени код. Твој излаз треба да изгледа овако:
- ***Continue in the next tab*** In the next tab you'll learn how to program the game itself. + ***Настави у следећој картици*** У следећој картици ћеш научити како да програмираш саму игру. example_code: | ``` - # Create a list called field + # Креирај листу звану поље _ = ['.', '.', '.', '.', '.', '.', '.', '.', '.'] - # Create a function that prints the field + # Креирај функцију која штампа поље {define} print_field _ - {print} 'TIC TAC TOE' + {print} 'ИКС-ОКС' {print} field[1] field[2] field[3] _ _ - # Call the function + # Позови функцију ``` 17: story_text: | - In the previous level you've learned how to make a tic-tac-toe game. The game works, but is quite annoying as it keeps asking you if you've won yet. - Now that we have the {elif} command, we can let the game decide if someone has won and it can stop asking us! + На претходном нивоу сте научили како да направите игру икс-окс. Игра функционише, али је прилично досадна јер вас стално пита да ли сте победили. + Сада када имамо команду {elif}, можемо дозволити игри да одлучи да ли је неко победио и може престати да нас пита! - ### Exercise - ***Paste your code*** Paste your code from the previous level here and make it level 17 proof. In this level you've learned to use a colon everytime you create a block of code. Please add the colons in the correct spots. + ### Вежба + ***Налепите свој код*** Налепите свој код са претходног нивоа овде и учините га ниво 17 доказаним. На овом нивоу сте научили да користите двотачку сваки пут када креирате блок кода. Молимо вас да додате двотачке на исправна места. - ***Create a function that detects if someone's won*** We have started the function for you, paste it under the function `print_field` and finish the function. You can see that this first piece of code checks to see if spot 1, 2 and 3 are the same, because if they are you have 3 in a row. - It also checks if they are not a dot, because if they are, the line might have the same symbols on them, but that's just because it's still empty. - If all these conditions are met, the game is over and the winner is printed. - Finish this function with all possible ways to win. This means you have to make this for the other 2 rows, 3 columns and 2 diagonals. - If you've finished all the other options, the function should return the variable `game_over` so we can use it in our game. + ***Направите функцију која детектује да ли је неко победио*** Почели смо функцију за вас, налепите је испод функције `print_field` и завршите функцију. Можете видети да овај први део кода проверава да ли су места 1, 2 и 3 иста, јер ако јесу, имате 3 у низу. + Такође проверава да ли нису тачке, јер ако јесу, линија може имати исте симболе на њима, али то је само зато што је још увек празна. + Ако су сви ови услови испуњени, игра је завршена и победник се приказује. + Завршите ову функцију са свим могућим начинима за победу. То значи да морате направити ово за преостала 2 реда, 3 колоне и 2 дијагонале. + Када завршите све остале опције, функција треба да врати променљиву `game_over` како бисмо је могли користити у нашој игри. - ***Call the function in the game*** Go to the line `game_over = {ask} 'Did you win?'` and change it to `game_over = {call} detect_winner {with} field, sign`. Now the function will check if there's a winner and the game doesn't need to keep asking anymore! + ***Позовите функцију у игри*** Идите на линију `game_over = {ask} 'Did you win?'` и промените је у `game_over = {call} detect_winner {with} field, sign`. Сада ће функција проверити да ли постоји победник и игра више не мора стално да пита! - ***Enjoy your game!*** Great job! You have finished the game! Enjoy playing it! + ***Уживајте у својој игри!*** Одличан посао! Завршили сте игру! Уживајте у игрању! example_code: | ``` - # Paste your code here and make it level 17 proof + # Налепите свој код овде и учините га ниво 17 доказаним - # Create a function that detects if someone has won + # Направите функцију која детектује да ли је неко победио {define} detect_winner {with} field, sign: {if} field[1] == field[2] {and} field[2] == field[3] {and} field[1] != '.': - game_over = 'yes' - {print} 'Player ' sign 'wins!' + игра_завршена = 'да' + {print} 'Играч ' sign 'побеђује!' {elif}: _ {else}: - game_over = 'no' + игра_завршена = 'не' {return} _ ``` tic_2: - name: Tic-Tac-Toe 2 - default_save_name: Tic - description: Play a game of Tic Tac Toe! + name: Икс-Окс 2 + default_save_name: Икс + description: Играј игру икс-окс! levels: 16: story_text: | - In the previous adventure you've learned how to create a playing field. Now you'll learn how to create the game! + У претходној авантури си научио како да креираш игралиште. Сада ћеш научити како да креираш игру! - ### Exercise - ***Paste your code*** Start by pasting your code from the previous adventure here. + ### Вежба + ***Налепи свој код*** Почни тако што ћеш овде налепити свој код из претходне авантуре. - ***Add variables*** Underneath your list called `field` we'll add 2 more variables that we'll need to program the game. - The variable `game_over` tells us if the game is over, and should be 'no' at the start of the game. - The variable `sign` tells us if it's the turn of player x or player o. Set the variable to 'x'. + ***Додај променљиве*** Испод твоје листе зване `field` додаћемо још 2 променљиве које ће нам бити потребне за програмирање игре. + Променљива `game_over` нам говори да ли је игра завршена, и треба да буде 'не' на почетку игре. + Променљива `sign` нам говори да ли је ред на играча икс или играча окс. Постави променљиву на 'x'. - ***The game*** First use a {while} command, to make sure the game keeps on playing the variable while game_over is set to no. - During the game, we first ask the player which spot they choose. Then we change the field with the number they chose into their sign. - Then we print the field again and we ask the player if they've won yet. Lastly we want to switch whose turn it is, so if the sign is 'x' it should be 'o' and the other way around. + ***Игра*** Прво користи команду {while}, да би осигурао да игра настави да се игра док је променљива игра_завршена постављена на не. + Током игре, прво питамо играча које место бира. Затим мењамо поље са бројем који су изабрали у њихов знак. + Затим поново штампамо поље и питамо играча да ли је победио. На крају желимо да променимо чији је ред, тако да ако је знак 'x' треба да буде 'o' и обрнуто. - ***Test your game*** Does your game work? Great, have fun playing the game! If not, use the ladybug button to debug your code. - You might have noticed one mistake in the code though, you can steal the other player's spot! If the other person chose spot 1, you could simply enter 1 after them and steal their spot. - That's not fair! Go to the next tab to learn how to fix this problem. + ***Тестирај своју игру*** Да ли твоја игра ради? Одлично, забави се играјући игру! Ако не, користи дугме са бубамаром да отклониш грешке у свом коду. + Можда си приметио једну грешку у коду, можеш украсти место другог играча! Ако је друга особа изабрала место 1, могао би једноставно унети 1 после њих и украсти њихово место. + То није фер! Иди на следећу картицу да научиш како да решиш овај проблем. example_code: | ``` - # Paste your code from the previous adventure here + # Налепи свој код из претходне авантуре овде - # Add variables - game_over = _ - sign = _ + # Додај променљиве + игра_завршена = _ + знак = _ - # The game + # Игра {while} _ - choice = _ 'Player ' sign '_?' - field[choice] = _ + избор = _ 'Играч ' знак '_?' + поље[избор] = _ _ print_field - game_over = {ask} _ - {if} sign = 'o' - sign = _ + игра_завршена = {ask} _ + {if} знак = 'o' + знак = _ _ - sign = _ + знак = _ ``` tic_3: - name: Tic-Tac-Toe 3 - default_save_name: Tic - description: Play a game of Tic Tac Toe! + name: Икс-Окс 3 + default_save_name: Икс + description: Играј игру икс-окс! levels: 16: story_text: | - You might have noticed one mistake in the code you've made in the previous adventure. You can steal the other player's spot! If the other person chose spot 1, you could simply enter 1 after them and steal their spot. - That's not fair! In this tab we'll fix that mistake. + Можда си приметио једну грешку у коду који си направио у претходној авантури. Можеш украсти место другог играча! Ако је друга особа изабрала место 1, могао би једноставно унети 1 после њих и украсти њихово место. + То није фер! У овој картици ћемо исправити ту грешку. - ### Exercise - ***Paste your code here*** Paste your code from the previous adventure here. + ### Вежба + ***Налепи свој код овде*** Налепи свој код из претходне авантуре овде. - ***Fix the mistake*** To fix the mistake we replace the line that says `field[choice] = sign`. This turns any spot that the player has chosen into their sign. - Go to the header that says 'Use this to fix the mistake' and finish the code. We first want to check if the chosen spot is still empty, so `if field[choice] = '.'`. If that is the case, you are allowed to take it. - Then we make an else command and print 'Sorry, this spot is already taken' if the spot is not empty. Lastly, we add a {sleep} command, so the players can actually read the text before it gets cleared again. - Now copy this piece of code and replace the line `field[choice] = sign` with this new piece of code. + ***Исправи грешку*** Да бисмо исправили грешку, заменимо линију која каже `field[choice] = sign`. Ово претвара било које место које је играч изабрао у њихов знак. + Иди на наслов који каже 'Користи ово да исправиш грешку' и заврши код. Прво желимо да проверимо да ли је изабрано место још увек празно, тако да `if field[choice] = '.'`. Ако је то случај, дозвољено ти је да га узмеш. + Затим правимо команду иначе и штампамо 'Извини, ово место је већ заузето' ако место није празно. На крају, додамо команду {sleep}, тако да играчи могу заправо прочитати текст пре него што се поново очисти. + Сада копирај овај део кода и замени линију `field[choice] = sign` овим новим делом кода. - ***Play your game!*** Now the game should work properly! Good job! - The only flaw is that you can get a bit annoyed that the game keeps asking you if you've won yet. Do you want to fix that? Go to level 17 and we'll fix it! + ***Играј своју игру!*** Сада би игра требало да ради исправно! Добар посао! + Једина мана је што те може мало нервирати што те игра стално пита да ли си победио. Желиш ли да то поправиш? Иди на ниво 17 и поправићемо то! example_code: | ``` - # Paste your code here + # Налепи свој код овде - # Use this to fix the mistake + # Користи ово да исправиш грешку {if} _ = '.' - field[choice] = sign + поље[избор] = знак {else} {print} _ _ ``` turtle: - name: Turtle - default_save_name: Turtle - description: Make your own drawing + name: Корњача + default_save_name: Корњача + description: Направи свој цртеж levels: 1: story_text: | - You can also use Hedy to draw. By combining turns and lines, you can make a square or stairs! + Можеш такође користити Хеди за цртање. Комбинујући окрете и линије, можеш направити квадрат или степенице! - Using `{forward}` you draw a line forwards. The number behind it determines how far the turtle will walk. `{turn} {right}` turns a quarter turn in clockwise direction, `{turn} {left}` turns counter clockwise. + Користећи `{forward}` црташ линију напред. Број иза одређује колико далеко ће корњача ићи. `{turn} {right}` окреће четвртину у смеру казаљке на сату, `{turn} {left}` окреће супротно од казаљке на сату. - If you want to go backwards, you use the `{forward}` command but with a negative number. So for example `{forward} -100` + Ако желиш да идеш уназад, користиш команду `{forward}` али са негативним бројем. На пример `{forward} -100` example_code: | ``` {forward} 100 {turn} {left} ``` story_text_2: | - ### Exercise - This is the start of a little staircase. Can you make it have 5 steps? + ### Вежба + Ово је почетак малог степеништа. Можете ли направити да има 5 степеника? example_code_2: | ``` {forward} 20 @@ -4600,56 +4661,67 @@ adventures: ``` 2: story_text: | - In this level you can use variables to make the turtle interactive. For example you can ask the player how many steps the turtle must make. + На нивоу 1 корњача је могла само да се окреће лево или десно. То је мало досадно! + На нивоу 2 може усмерити свој нос у свим правцима. + + Користи 90 степени да се окренеш четвртину, 180 да се окренеш половину, а пун круг је 360 степени. + + ### Вежба + Овај код сада ствара слово Т. Можеш ли га променити да направи слово Б? + + **Додатно** Промени слово у друго слово, као што је прво слово твог имена. + Можеш такође направити више слова, постављањем боје на `{color}` `{white}` између. example_code: | ``` - answer {is} {ask} How many steps should the turtle make? - {forward} answer + {forward} 20 + {turn} 90 + {forward} 20 + {turn} 180 + {forward} 100 ``` story_text_2: | - Also, in level 1 the turtle could only turn left or right. That is a bit boring! - In level 2 he can point his nose in all directions. - - Use 90 to turn a quarter. We call this degrees. A full turn is 360 degrees. + Можеш користити променљиве у корњачином `turn`. - ### Exercise - Can you make a figure with this code? Maybe a triangle or a circle? + ### Вежба + Промени код тако да ствара троугао. Савет: потребно је променити код само на једном месту. example_code_2: | ``` - {print} Drawing figures - angle {is} 90 - {turn} angle + {print} Цртање фигура + угао {is} 90 + {turn} угао {forward} 25 - {turn} angle + {turn} угао + {forward} 25 + {turn} угао {forward} 25 ``` 3: story_text: | - In this level you can use `{at} {random}` with the drawing turtle. A random choice makes the turtle walk a different path each time. - Use `{at} {random}` to choose a value from a list. - ### Exercise - Can you copy and paste lines 2 and 3 to create a longer random path? + На овом нивоу можеш користити `{at} {random}` са корњачом за цртање. Случајан избор чини да корњача сваки пут иде другачијим путем. + Користи `{at} {random}` да изабереш вредност са листе. + ### Вежба + Можеш ли копирати и налепити линије 2 и 3 да направиш дужи случајни пут? example_code: | ``` - angles {is} 10, 50, 90, 150, 250 - {turn} angles {at} {random} + углови {is} 10, 50, 90, 150, 250 + {turn} углови {at} {random} {forward} 25 ``` 4: story_text: | - In level 4 you have to use quotation marks with `{print}` and `{ask}`. Also when drawing! + На нивоу 4 морате користити наводнике са `{print}` и `{ask}`. Такође и при цртању! example_code: | ``` - {print} _ Drawing figures _ - angle {is} 90 - {turn} angle + {print} _ Цртање фигура _ + угао {is} 90 + {turn} угао {forward} 25 - {turn} angle + {turn} угао {forward} 25 ``` story_text_2: | - You can also change the color of the lines with the command `{color}`. Check out the example. - You can also use the command `{color} {white}` to make 'invisible' lines. You could use these white lines to move the turtle anywhere in the screen before you start drawing. + Такође можете променити боју линија командом `{color}`. Погледајте пример. + Можете користити команду `{color} {white}` да направите 'невидљиве' линије. Можете користити ове беле линије да померите корњачу било где на екрану пре него што почнете да цртате. example_code_2: | ``` {color} {white} @@ -4663,86 +4735,86 @@ adventures: ``` 5: story_text: | - In level 5 you can make a choice with `{if}`. For example between different types of figures. + На нивоу 5 можете направити избор са `{if}`. На пример, између различитих типова фигура. example_code: | ``` - {print} 'Drawing Figures' - figure {is} {ask} 'Do you want a square or a triangle?' - {if} figure {is} triangle angle {is} 120 - {else} angle {is} 90 - {turn} angle + {print} 'Цртање фигура' + фигура {is} {ask} 'Да ли желите квадрат или троугао?' + {if} фигура {is} троугао угао {is} 120 + {else} угао {is} 90 + {turn} угао {forward} 25 - {turn} angle + {turn} угао {forward} 25 - {turn} angle + {turn} угао {forward} 25 - {turn} angle + {turn} угао {forward} 25 ``` story_text_2: | - ### Exercise - Fill in the correct numbers in this code to get it to work. - After you've done that, you can try to add the option backwards. + ### Вежба + Попуните тачне бројеве у овом коду да би радио. + Након што то урадите, можете покушати да додате опцију уназад. - **Extra** Instead of using 'left' and 'right', remake the program with North, East, South and West. - This way you could add even more directions like Northeast and Southwest etc. + **Додатно** Уместо да користите 'лево' и 'десно', преправите програм са Север, Исток, Југ и Запад. + На овај начин можете додати још више праваца као што су Североисток и Југозапад итд. example_code_2: | ``` - direction {is} {ask} 'Do you want to go left, right, or straight ahead?' - if direction is left turn _ - if direction is right turn _ - forward 100 + правац {is} {ask} 'Да ли желите да идете лево, десно или право?' + {if} правац {is} лево {turn} _ + {if} правац {is} десно {turn} _ + {forward} 100 ``` 6: story_text: | - In this level you can use calculations to draw different figures. - You may have learned in school that turning a full circle is 360 degrees. If not, now you know! - That's why you also use 90 degrees for a square. 360 divided by 4 is 90. - Now that we can do math with Hedy, we can draw all the figures we want! + На овом нивоу можете користити прорачуне за цртање различитих фигура. + Можда сте у школи научили да окретање пуног круга износи 360 степени. Ако нисте, сада знате! + Зато користите и 90 степени за квадрат. 360 подељено са 4 је 90. + Сада када можемо радити математику са Хеди, можемо цртати све фигуре које желимо! example_code: | ``` - angles = {ask} 'How many angles do you want?' - angle = 360 / angles + углови = {ask} 'Колико углова желите?' + угао = 360 / углови {forward} 50 - {turn} angle + {turn} угао {forward} 50 - {turn} angle + {turn} угао {forward} 50 - {turn} angle + {turn} угао {forward} 50 - {turn} angle + {turn} угао {forward} 50 - {turn} angle + {turn} угао {forward} 50 - {turn} angle + {turn} угао ``` 8: - story_text: "Now that we can repeat several lines, we can make figures more easily.\nWe only have to set the angle once and then use that variable in the `{repeat}`.\n\n### Exercise 1\nThe example code creates a square. Change the code so that it create another figure, such as a triangle or a hexagon. \nThis requires a change to two lines of code.\nTip: An entire circle is 360 degrees.\n\n### Exercise 2\nNow create a drawing consisting of at least two polygons.\n" + story_text: "Сада када можемо понављати неколико линија, можемо лакше правити фигуре.\nСамо треба да подесимо угао једном и онда користимо ту променљиву у `{repeat}`.\n\n### Вежба 1\nПример кода креира квадрат. Промените код тако да креира другу фигуру, као што је троугао или хексагон.\nОво захтева промену две линије кода.\nСавет: Цео круг је 360 степени.\n\n### Вежба 2\nСада направите цртеж који се састоји од најмање два полигона.\n" example_code: | ``` - angle = 90 + угао = 90 {repeat} 4 {times} - {turn} angle + {turn} угао {forward} 50 ``` story_text_2: | - **(extra)** We can now improve the program that draws different figures. Finish the code and you can draw any polygon you'd like! + **Додатно** Сада можемо побољшати програм који црта различите фигуре. Завршите код и можете цртати било који полигон који желите! example_code_2: | ``` - figure = {ask} 'How many angles should I draw?' - angle = 360 / figure - {repeat} figure {times} + фигура = {ask} 'Колико углова треба да нацртам?' + угао = 360 / фигура + {repeat} фигура {times} {turn} _ {forward} _ ``` 9: story_text: | - Now that we can use a `{repeat}` inside a `{repeat}`, we can create more complex figures. + Сада када можемо користити `{repeat}` унутар `{repeat}`, можемо креирати сложеније фигуре. - ### Exercise 1 - This code creates three black triangles, change that into five pink squares. + ### Вежба 1 + Овај код креира три црна троугла, промените то у пет ружичастих квадрата. - **(extra)** Create a figure of your own choosing consisting of at least two different shapes types. + **Додатно** Креирајте фигуру по вашем избору која се састоји од најмање два различита типа облика. example_code: | ``` {color} {black} @@ -4756,33 +4828,33 @@ adventures: ``` 10: story_text: | - In this level you can make the turtle draw a figure. - The turtle will travel the distances in the list, one by one, making bigger and bigger steps. - ### Exercise 1 - Add a 90 degree turn in the loop, so that a spiral is drawn. - Add at least 5 numbers to the list, so the spiral grows larger. - **(extra)** can you change the spiral into another shape? Experiment with numbers for the turn! - ### Exercise 2 - The spiral is drawn outwards, make it go inwards? + На овом нивоу можете направити да корњача нацрта фигуру. + Корњача ће путовати растојањима у листи, једно по једно, правећи све веће и веће кораке. + ### Вежба 1 + Додајте скретање од 90 степени у петљу, тако да се нацрта спирала. + Додајте најмање 5 бројева у листу, тако да спирала постане већа. + **(додатно)** можете ли променити спиралу у други облик? Експериментишите са бројевима за скретање! + ### Вежба 2 + Спирала се црта ка споља, направите да иде ка унутра? example_code: | ``` {turn} 90 - distances = 10, 20, 30, 40, 50, 60 - {for} distance {in} distances - {forward} distance + удаљености = 10, 20, 30, 40, 50, 60 + {for} удаљеност {in} удаљености + {forward} удаљеност ``` 12: story_text: | - We can use functions to draw more complex figures with less code. - ### Exercise 1 - Fill the function so that three squares are created. If you want the image to look nicer, you can make the lines between the squares white. + Можемо користити функције да нацртамо сложеније фигуре са мање кода. + ### Вежба 1 + Попуните функцију тако да се направе три квадрата. Ако желите да слика изгледа лепше, можете направити линије између квадрата беле. - ### Exercise 2 - The code can be made even shorter. Place the final lines into a `{repeat}` so the figure remains the same. + ### Вежба 2 + Код може бити још краћи. Ставите завршне линије у `{repeat}` тако да фигура остане иста. - ### Exercise 3 - Create your own drawing with different figures. - Change both the number of figures with the `{repeat}` and the shape of the figures in the `{define}` + ### Вежба 3 + Направите свој цртеж са различитим фигурама. + Промените и број фигура са `{repeat}` и облик фигура у `{define}` example_code: | ``` {define} square @@ -4796,283 +4868,285 @@ adventures: {call} square ``` turtle_draw_it: - name: Draw it! - default_save_name: Draw it - description: Draw this picture with the turtle + name: Нацртај то! + default_save_name: Нацртај то + description: Нацртај ову слику са корњачом levels: 1: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Преправите цртеже са корњачом!
- Rectangle - Square - Stairs + Правоугаоник + Квадрат + Степенице
2: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Преправите цртеже са корњачом!
- Triangle - Arrow - Boat + Троугао + Стрелица + Чамац
3: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Рекреирајте цртеже са корњачом!
- Triangle - Star - Arrow + Троугао + Звезда + Стрелица
4: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Рекреирајте цртеже са корњачом!
- Colored Star - Rainbow - Nested squares + Шарена звезда + Дуга + Угњеждени квадрати
example_code: | - **Extra** Up for a real challenge? Make sure that the colors of these figures are selected randomly, so that each time you run your programs they'll look differently! + **Додатно** За прави изазов? Уверите се да су боје ових фигура изабране насумично, тако да сваки пут када покренете своје програме изгледају другачије! ``` - colors {is} red, orange, yellow, green, blue, purple, pink, brown, gray, black + colors {is} црвена, наранџаста, жута, зелена, плава, љубичаста, ружичаста, браон, сива, црна color _ ``` 5: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Рекреирајте цртеже са корњачом! - **Extra** Make only one code that lets the player decide which letter they'd like to see! And can you add even more letters? + **Додатно** Направите само један код који омогућава играчу да одлучи које слово жели да види! И можете ли додати још више слова?
- F - E - L + Ф + Е + Л
example_code: | - Hint: + Савет: ``` - chosen_letter {is} {ask} 'Which letter would you like to see? F, E or L?' + chosen_letter {is} {ask} 'Које слово желите да видите? Ф, Е или Л?' {if} _ ``` 6: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Рекреирајте цртеже са корњачом! - **Extra** Let the player decide which color the square should be. + **Додатно** Нека играч одлучи које боје квадрат треба да буде. - ***Extra*** Can you make the letter of your own first name and the flag of your own country too? + ***Додатно*** Можете ли направити слово свог имена и заставу своје земље?
- Square - Letters - Flag + Квадрат + Слова + Застава
example_code: | - Hint for the square: + Савет за квадрат: ``` chosen_color = {ask} _ ``` 7: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Рекреирајте цртеже са корњачом!
- Hexagon - Triangle - Fan + Шестоугао + Троугао + Вентилатор
8: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Рекреирајте цртеже са корњачом! - **Extra** The number in brackets indicates in how many lines of code this figure can be drawn. Can you do it in the same amount of lines? + **Додатно** Број у заградама означава у колико редова кода се ова фигура може нацртати. Можете ли то урадити у истом броју редова?
- Square (3) - Randomly colored star (5) - Randomly colored spiral (7) + Квадрат (3) + Насумично обојена звезда (5) + Насумично обојена спирала (7)
9: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Рекреирајте цртеже са корњачом! - **Extra** The number in brackets indicates in how many lines of code this figure can be drawn. Can you do it in the same amount of lines? + **Додатно** Број у заградама означава у колико редова кода се ова фигура може нацртати. Можете ли то урадити у истом броју редова? - **Extra** Give the player a choice which country they would like to see the flag of. + **Додатно** Дајте играчу избор коју заставу земље жели да види.
- Cross (7) - Randomly colored nested squares (8) - Flags + Крст (7) + Насумично обојени угњеждени квадрати (8) + Заставе
example_code: | - Hint for the nested squares: + Савет за угњеждене квадрате: ``` - colors = red, blue, orange, yellow, pink, purple, green, brown, black + colors = црвена, плава, наранџаста, жута, ружичаста, љубичаста, зелена, браон, црна distance = 120 - repeat 5 times + {repeat} 5 {times} _ ``` - Hint for the flags: + Савет за заставе: ``` - country = ask 'which country would you like to see the flag of?' - if country is 'the Netherlands' - color_1 = red - color_2 = white - color_3 = blue + country = {ask} 'коју земљу желите да видите заставу?' + {if} country {is} 'Холандија' + color_1 = црвена + color_2 = бела + color_3 = плава ``` 10: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Рекреирајте цртеже са корњачом!
- Nested Hexagon - Traffic lights + Угњеждени шестоугао + Семафор
example_code: | - Hint Nested Hexagon: + Савет за угњеждени шестоугао: ``` distances = 100, 80, 60, 40, 20 {for} distance {in} distances _ ``` - Hint Traffic Lights: + Савет за семафор: ``` - colors = red, yellow, green + colors = црвена, жута, зелена {for} chosen_color {in} colors - color _ + {color} _ {repeat} _ ``` story_text_2: | - Christmas lights + Божићне лампице example_code_2: | - Hint Christmas Lights: + Савет Божићне лампице: - Start by moving to the left side of the screen with an invisible white line. Then hang up the Christmas lights! + Почните тако што ћете се померити на леву страну екрана са невидљивом белом линијом. Затим окачите Божићне лампице! ``` - {color} white + {color} бела {turn} -90 {forward} 300 {turn} 90 - colors = red, blue, yellow, purple, green, orange, pink - {for} chosen_color {in} colors + боје = црвена, плава, жута, љубичаста, зелена, наранџаста, ружичаста + {for} изабрана_боја {in} боје _ ``` 11: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Преправите цртеже са корњачом!
- Beehive (6) - Fan (5) - Snowflake (13) + Кошница (6) + Вентилатор (5) + Пахуљица (13)
example_code: | - Hint Beehive: + Савет Кошница: ``` - {for} amount_of_combs {in} {range} 1 {to} _ - {for} walls_of_one_comb {in} {range} 1 {to} _ + {for} број_ћелија {in} {range} 1 {to} _ + {for} зидови_једне_ћелије {in} {range} 1 {to} _ {forward} _ {turn} _ {forward} _ {turn} _ ``` - Hint Fan: - Start out like the fan you made in level 7. Or take a peak at the hint for the beehive, because the codes are very similar. + Савет Вентилатор: + Почните као вентилатор који сте направили на нивоу 7. Или погледајте савет за кошницу, јер су кодови веома слични. - Hint Snowflake: Start by making one 'leg' and repeat it 6 times. + Савет Пахуљица: Почните тако што ћете направити једну 'ногу' и поновите је 6 пута. 12: story_text: | - ### Exercise - Recreate the drawings with the turtle! - Hint: Bracelet designing program. Firstly, define a function **for each shape** you want to use on the bacelet. Then, add the shapes to the bacelet like this: - - Bracelet Designing program + ### Вежба + Преправите цртеже са корњачом! + + Прво, дефинишите функцију **за сваки облик** који желите да користите на наруквици. Затим, додајте облике на наруквицу овако: + + Програм за дизајнирање наруквице example_code: | + Савет Програм за дизајнирање наруквице ``` - {define} draw_a_square + {define} нацртај_квадрат _ - {color} white + {color} бела {turn} -90 {forward} 300 {turn} 180 {for} i {in} {range} 1 {to} 5 - {color} gray + {color} сива {forward} 100 - shape = {ask} 'What kind of shape would you like next on the bracelet?' - chosen_color = {ask} 'In which color?' - {color} chosen_color - {if} shape = 'square' - {call} draw_a_square + облик = {ask} 'Који облик желите следећи на наруквици?' + изабрана_боја = {ask} 'Које боје?' + {color} изабрана_боја + {if} облик = 'квадрат' + {call} нацртај_квадрат ``` 13: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Преправите цртеже са корњачом! - Street in different sizes - Colored street - Snow Storm + Улица у различитим величинама + Шарена улица + Снежна олуја example_code: | - Hint Street in different sizes + Савет Улица у различитим величинама ``` - {define} draw_a_house {with} size + {define} нацртај_кућу {with} величина _ - {call} draw_a_house {with} 90 - {call} draw_a_house {with} 60 - {call} draw_a_house {with} 30 + {call} нацртај_кућу {with} 90 + {call} нацртај_кућу {with} 60 + {call} нацртај_кућу {with} 30 ``` - Hint Colored street + Савет Шарена улица ``` - {define} draw_a_house {with} chosen_color + {define} нацртај_кућу {with} изабрана_боја _ ``` - Hint Snow Storm + Савет Снежна олуја ``` - {define} draw_snowflake {with} length, color + {define} нацртај_пахуљицу {with} дужина, боја _ - numbers = 10, 20, 30 - colors = _ + бројеви = 10, 20, 30 + боје = _ {for} i {in} {range} 1 {to} 5 - random_number = _ - random_color = _ - {call} draw_snowflake {with} random_number, random_color - {color} white - {turn} random_number * 5 + случајни_број = _ + случајна_боја = _ + {call} нацртај_пахуљицу {with} случајни_број, случајна_боја + {color} бела + {turn} случајни_број * 5 {forward} 80 ``` 14: story_text: | - ### Exercise - Create a program that asks the player how many corners their figure should have and then creates that figure. - The figure in the image is the output when the player fills in 10. + ### Вежба + Направите програм који пита играча колико углова њихова фигура треба да има и затим креира ту фигуру. + Фигура на слици је резултат када играч унесе 10.
@@ -5080,41 +5154,41 @@ adventures:
example_code: | ``` - {define} calculate_degrees {with} amount_of_corners - _ 360 / amount_of_corners + {define} израчунај_степене {with} број_углова + _ 360 / број_углова - {define} draw_figure {with} degrees + {define} нацртај_фигуру {with} степени _ - {forward} 400/amount_of_corners + {forward} 400/број_углова {turn} _ - amount_of_corners = {ask} _ - degrees = {call} _ {with} _ + број_углова = {ask} _ + степени = {call} _ {with} _ {call} _ {with} {call} _ {with} ``` 15: story_text: | - ### Exercise - Recreate the drawings with the turtle! + ### Вежба + Преправите цртеже са корњачом! - Spiral + Спирала example_code: | - Spiral + Спирала ``` - distance = 5 - {while} distance < 200 - distance = distance + 5 + удаљеност = 5 + {while} удаљеност < 200 + удаљеност = удаљеност + 5 _ ``` story_text_2: | - Fan + Вентилатор example_code_2: | - Fan + Вентилатор ``` - {define} draw_a_square {with} side + {define} нацртај_квадрат {with} страна _ i = 100 @@ -5124,43 +5198,44 @@ adventures: i = i - 3 ``` story_text_3: | - Star + Звезда example_code_3: | - Star - A star is usually drawn using 144-degree-turns. If you change this slightly to 143 degrees for example and repeat the pattern multiple times with a {while} loop you can make this figure. + Звезда + Звезда се обично црта користећи окретање од 144 степена. Ако ово мало промените на 143 степена, на пример, и поновите образац више пута са {while} петљом, можете направити ову фигуру. while_command: name: '{while}' - default_save_name: while_command - description: while + default_save_name: док_команда + description: '{while}' levels: 15: story_text: |- - We are going to learn a new loop, the `{while}` loop! We continue the loop as long as the statement is true. - So don't forget to change the value in the loop. + Научићемо нову петљу, `{while}` петљу! Настављамо петљу све док је изјава тачна. + Зато не заборави да промениш вредност у петљи. - In the example code, we continue until a correct answer has been given. - If the correct answer is never given, the loop never ends! + У пример коду, настављамо док се не добије тачан одговор. + Ако се тачан одговор никада не добије, петља се никада не завршава! example_code: | ``` - answer = 0 - {while} answer != 25 - answer = {ask} 'What is 5 times 5?' - {print} 'A correct answer has been given' + одговор = 0 + {while} одговор != 25 + одговор = {ask} 'Колико је 5 пута 5?' + {print} 'Дат је тачан одговор' ``` years: - name: New Year's - default_save_name: New Year's Countdown - description: Countdown to the New Year! + name: Нова година + default_save_name: Одбројавање до Нове године + description: Одбројавање до Нове године! levels: 11: story_text: | - In this level you can use the `{for}` number `{in}` `{range}` command to countdown to the New Year. + На овом нивоу можеш користити команду `{for}` number `{in}` `{range}` за одбројавање до Нове године. - ### Exercise - Fill in the blanks and make the code work! + ### Вежба + Попуни празна места и учини да код ради! example_code: | ``` {for} number {in} {range} _ {to} _ {print} number - {print} 'Happy New Year!' + {sleep} + {print} 'Срећна Нова година!' ``` diff --git a/content/adventures/zh_Hans.yaml b/content/adventures/zh_Hans.yaml index 7afeef8008f..387ee277682 100644 --- a/content/adventures/zh_Hans.yaml +++ b/content/adventures/zh_Hans.yaml @@ -2563,9 +2563,9 @@ adventures: ``` story_text_2: | ### 练习 - 是时候创建自己的变量了! - 在示例代码中,我们以变量“动物”为例。在第1行中设置了变量,在第2行中,我们在`{print}`命令中使用了变量。 - 首先,在空白处填上你最喜欢的动物,完成我们的例子。然后自己编写至少3个这样的代码。选择一个变量,并使用`{is}`命令设置该变量。然后使用`{print}`命令,就像我们所做的那样。 + 是时候创建自己的变量了! + 在示例代码中,我们创建了一个变量 `favorite_animal` 的示例。在第 1 行中设置了变量,在第 2 行中我们在 `{print}` 命令中使用该变量。 + 首先,通过在空白处填写您最喜欢的动物来完成我们的示例。然后自己创建至少 3 个这样的代码。选择一个变量,并使用 `{is}` 命令设置该变量。然后像我们一样,使用 `{print}` 命令使用它。 example_code_2: | ``` 最喜爱的动物 {is} _ @@ -3853,10 +3853,10 @@ adventures: ``` 2: story_text: | - 在这个关卡中,你可以练习使用变量,这样你就可以在下一个关卡中制作石头、剪刀、布游戏! + 在这一关中,您可以练习使用变量,以便在下一关中制作石头、剪刀、布游戏! ### 练习 - 通过在空格上填写**变量**来完成代码。 - 这个游戏不是很互动,但是不用担心!在下一个选项卡中,您将学习如何使用`{ask}`命令和变量来使您的游戏具有互动性! + 通过在空白处填写**变量**来完成代码。 + 这个游戏的互动性不强,但不用担心!在下一个选项卡中,您将学习如何使用变量和`{ask}`命令让您的游戏具有互动性! example_code: |- ``` 选择 {is} 石头 @@ -4591,28 +4591,39 @@ adventures: ``` 2: story_text: | - 在这一级,你可以使用变量来使海龟互动。例如,你可以问玩家海龟必须走多少步。 + 在第 1 级中,乌龟只能向左或向右转。这有点无聊! + 在第 2 级中,他可以将鼻子指向所有方向。 + + 使用 90 度旋转四分之一,180 度旋转一半,一整圈是 360 度。 + + ### 练习 + 此代码现在创建字母 T。你能改变它来制作字母 B 吗? + + **额外**将字母更改为不同的字母,例如你名字的第一个字母。 + 你还可以通过将颜色设置为 `{color}` `{white}` 来制作多个字母。 example_code: | ``` - 答案 {is} {ask} 海龟应该走多少步? - {forward}答案 + {forward} 20 + {turn} 90 + {forward} 20 + {turn} 180 + {forward} 100 ``` story_text_2: | - 此外,在第1级,海龟只能左转或右转。这有点无聊! - 在第2级,它可以转向任何方向。 - - 用90来转1/4圈。我们管这个叫角度。完整转一圈是360度。 + 您可以使用变量来让乌龟 `turn`. ### 练习 - 你能用这段代码来画一个图形吗?比如三角形或者圆形? + 更改代码,使其创建一个三角形。提示:您只需在一个地方更改代码。 example_code_2: | ``` - {print} 正在画图 + {print} 绘制图形 角度 {is} 90 {turn} 角度 {forward} 25 {turn} 角度 {forward} 25 + {turn} 角度 + {forward} 25 ``` 3: story_text: | diff --git a/content/cheatsheets/fi.yaml b/content/cheatsheets/fi.yaml index d45d034bd76..b9c4e0868b0 100644 --- a/content/cheatsheets/fi.yaml +++ b/content/cheatsheets/fi.yaml @@ -35,7 +35,7 @@ väri {is} {ask} Mikä on lempivärisi? {print} väri on lempivärisi! - name: '{sleep}' - explanation: '`{sleep}` anna Hedyn pitää (muutama) sekunti taukoa.' + explanation: '`{sleep}`:lla voit antaa Hedyn pysähtyä pariksi sekunniksi.' demo_code: |- {print} Annas kun ajattelen sekunnin... {sleep} @@ -104,8 +104,8 @@ väri {is} {ask} 'Mikä on lempivärisi?' {if} väri {in} hienot_värit {print} 'hieno!' {else} {print} 'plääh' - name: '{pressed}' - explanation: Check whether a given key on the keyboard is `{pressed}`. - demo_code: '{if} a {is} {pressed} {print} ''You pressed A!'' {else} {print} ''You pressed another key!''' + explanation: Tarkista, onko näppäimistön tietty näppäin `{pressed}`. + demo_code: '{if} a {is} {pressed} {print} ''Painoit A!'' {else} {print} "Painoit toista näppäintä!"' 6: - name: '{print}' explanation: Tulosta tarkasti käyttäen heittomerkkejä. @@ -115,7 +115,7 @@ demo_code: |- vastaus = {ask} 'Paljonko on 10 plus 10?' {if} vastaus {is} 20 {print} 'Kyllä!' {else} {print} 'Oho' -- name: '{ask} ja {if} kilpikonnan kanssa' +- name: '`{ask}` ja `{if}` kilpikonnan kanssa' explanation: Ask the user how many angles they want. demo_code: |- angles = {ask} 'How many angles?' @@ -159,12 +159,12 @@ {turn} 90 {forward} 50 - name: '{pressed}' - explanation: Check whether a given key on the keyboard is `{pressed}`. + explanation: Tarkista, onko näppäimistön tietty näppäin `{pressed}`. demo_code: |- {if} a {is} {pressed} - {print} 'You pressed A!' + {print} 'Painoit A!' {else} - {print} 'You pressed another key!' + {print} 'Painoit toista näppäintä!' 9: - name: '{if} monelle riville' explanation: The answer of a sum of questions with `{ask}` and see if it is correct. Now we print out two lines. @@ -220,7 +220,7 @@ demo_code: |- nimi = 'Hedy robotti' {print} 'Hei ' nimi -- name: heittomerkit {if} vertailun jälkeen +- name: heittomerkit `{if}` vertailun jälkeen explanation: Teksti lainausmerkeissä komennon `{if}` jälkeen. demo_code: |- nimi = {ask} 'Kuka olet?' @@ -316,7 +316,7 @@ firstfruit = fruit[1] {print} firstfruit - name: Get a random item from a list - explanation: To get a random item from a list we use [random] so fruit[random] means, get a random fruit from the list! + explanation: Saadaksesi satunnaisen kohteen luettelosta käytämme [{random}], joten hedelmä[{random}] tarkoittaa, että ota satunnainen hedelmä luettelosta! demo_code: |- fruit = ['banana', 'apple', 'cherry'] random_fruit = fruit[{random}] diff --git a/content/cheatsheets/ru.yaml b/content/cheatsheets/ru.yaml index b0c7887f40d..1909f8793a5 100644 --- a/content/cheatsheets/ru.yaml +++ b/content/cheatsheets/ru.yaml @@ -3,21 +3,21 @@ explanation: Напечатать что-нибудь с `{print}`. demo_code: '{print} Привет, добро пожаловать в Hedy!' - name: '{ask}' - explanation: спросить что-нибудь с `{ask}`. + explanation: Спросить что-нибудь с `{ask}`. demo_code: '{ask} Какой Ваш любимый цвет?' - name: '{echo}' - explanation: repeat something using `{echo}`. + explanation: Повторить что-то с помощью `{echo}`. demo_code: |- - {ask} What is your favorite color? - {echo} so your favorite color is -- name: '{print} emojis' - explanation: print an emoji with `{print}`. + {ask} Какой ваш любимый цвет? + {echo} ваш любимый цвет +- name: '{print} эмодзи' + explanation: Напечатать эмодзи с помощью `{print}`. demo_code: '{print} 🙋 🌍 ❗' - name: '{forward}' - explanation: Draw a line with `{forward}`. + explanation: Нарисовать линию с помощью `{forward}`. demo_code: '{forward} 100' - name: '{turn}' - explanation: turn the drawing turtle with `{turn}`. + explanation: Повернуть черепашку с помощью `{turn}`. demo_code: |- {forward} 25 {turn} {left} diff --git a/content/cheatsheets/sr.yaml b/content/cheatsheets/sr.yaml index 4e94c702ed9..66fc16cb41d 100644 --- a/content/cheatsheets/sr.yaml +++ b/content/cheatsheets/sr.yaml @@ -1,23 +1,23 @@ 1: - name: '{print}' - explanation: Print something with `{print}`. - demo_code: '{print} Hello welcome to Hedy!' + explanation: Штампај нешто са `{print}`. + demo_code: '{print} Здраво, добродошли у Хеди!' - name: '{ask}' - explanation: Ask something with `{ask}`. - demo_code: '{ask} What is your favorite color?' + explanation: Питај нешто са `{ask}`. + demo_code: '{ask} Која је твоја омиљена боја?' - name: '{echo}' - explanation: Repeat something using `{echo}`. + explanation: Понови нешто користећи `{echo}`. demo_code: |- - {ask} What is your favorite color? - {echo} so your favorite color is -- name: '{print} emojis' - explanation: Print an emoji with `{print}`. + {ask} Која је твоја омиљена боја? + {echo} дакле твоја омиљена боја је +- name: '{print} емотикони' + explanation: Штампај емотикон са `{print}`. demo_code: '{print} 🙋 🌍 ❗' - name: '{forward}' - explanation: Draw a line with `{forward}`. + explanation: Нацртај линију са `{forward}`. demo_code: '{forward} 100' - name: '{turn}' - explanation: Turn the drawing turtle with `{turn}`. + explanation: Окрени цртајућу корњачу са `{turn}`. demo_code: |- {forward} 25 {turn} {left} @@ -25,343 +25,343 @@ {turn} {right} 2: - name: '{is}' - explanation: Give a word a name to use in the program using `{is}`. You can choose the name yourself. + explanation: Дај речи име за коришћење у програму користећи `{is}`. Можеш сам изабрати име. demo_code: |- name {is} Hedy - {print} welcome name + {print} добродошао name - name: '{ask}' - explanation: Ask something with `{ask}`. Beware! You need to give the answer a name with `{is}`. + explanation: Питај нешто са `{ask}`. Пази! Мораш дати одговору име са `{is}`. demo_code: |- - color {is} {ask} What is your favorite color? - {print} color is your favorite! + color {is} {ask} Која је твоја омиљена боја? + {print} color је твоја омиљена! - name: '{sleep}' - explanation: '`{sleep}` let Hedy pause for a (couple of) second(s).' + explanation: 'Са `{sleep}`, можеш дозволити Хеди да паузира на (неколико) секунди.' demo_code: |- - {print} Let me think for one second... + {print} Пустите ме да размислим једну секунду... {sleep} - {print} Hmm.. I need 3 more seconds... + {print} Хмм.. Требају ми још 3 секунде... {sleep} 3 - {print} Eureka! Ive got it! -- name: '{is} with turtle' - explanation: Give a number a name using `{is}`. You can choose the name yourself. + {print} Еурека! Схватио сам! +- name: '{is} са корњачом' + explanation: Дај броју име користећи `{is}`. Можеш сам изабрати име. demo_code: |- angle {is} 90 {turn} angle {forward} 100 3: -- name: Choose random - explanation: Choose a random word from a group with `{at}` and `{random}`. +- name: Изабери насумично + explanation: Изабери насумичну реч из групе са `{at}` и `{random}`. demo_code: |- - animals {is} dog, cat, kangaroo + animals {is} пас, мачка, кенгур {print} animals {at} {random} - name: '{add}' - explanation: '`{add}` an item `{to_list}` a list.' + explanation: '`{add}` ставку `{to_list}` листи.' demo_code: |- - animals {is} cow, cat - {add} dog {to_list} animals + animals {is} крава, мачка + {add} пас {to_list} animals - name: '{remove}' - explanation: '`{remove}` an item `{from}` a list.' + explanation: '`{remove}` ставку `{from}` листе.' demo_code: |- - animals {is} cat, dog, cow - {remove} dog {from} animals + animals {is} мачка, пас, крава + {remove} пас {from} animals 4: - name: '{print}' - explanation: Print exactly using quotation marks. - demo_code: '{print} ''Hello welcome to Hedy.''' + explanation: Испиши тачно користећи наводнике. + demo_code: '{print} ''Здраво, добродошли у Хеди.''' - name: '{is}' - explanation: Give a name to some text and `{print}` without quotation marks. + explanation: Дај име неком тексту и `{print}` без наводника. demo_code: |- name {is} Hedy - {print} 'my name is ' name + {print} 'моје име је ' name - name: '{ask}' - explanation: Ask something with `{ask}`. + explanation: Питај нешто са `{ask}`. demo_code: |- - color {is} {ask} 'What is your favorite color?' - {print} color ' is your favorite!' + color {is} {ask} 'Која је твоја омиљена боја?' + {print} color ' је твоја омиљена!' 5: - name: '{print}' - explanation: Print exactly using quotation marks. - demo_code: '{print} ''Hello welcome to Hedy.''' + explanation: Испиши тачно користећи наводнике. + demo_code: '{print} ''Здраво, добродошли у Хеди.''' - name: '{ask}' - explanation: Ask something with `{ask}`. + explanation: Питај нешто са `{ask}`. demo_code: |- - color {is} {ask} 'What is your favorite color?' - {print} color ' is your favorite!' + color {is} {ask} 'Која је твоја омиљена боја?' + {print} color ' је твоја омиљена!' - name: '{if}' - explanation: Make a choice with `{if}`. + explanation: Направи избор са `{if}`. demo_code: |- - color {is} {ask} 'What is your favorite color?' - {if} color {is} green {print} 'pretty!' {else} {print} 'meh' -- name: '{if} with turtle' - explanation: Make a choice with `{if}`. + color {is} {ask} 'Која је твоја омиљена боја?' + {if} color {is} зелена {print} 'лепа!' {else} {print} 'мех' +- name: '{if} са корњачом' + explanation: Направи избор са `{if}`. demo_code: |- - answer {is} {ask} 'How far should I walk?' - {if} answer {is} far {forward} 100 {else} {forward} 5 + answer {is} {ask} 'Колико далеко треба да ходам?' + {if} answer {is} далеко {forward} 100 {else} {forward} 5 - name: '{in}' - explanation: Check elements with `{in}`. + explanation: Провери елементе са `{in}`. demo_code: |- - pretty_colors {is} green, yellow - color {is} {ask} 'What {is} your favorite color?' - {if} color {in} pretty_colors {print} 'pretty!' {else} {print} 'meh' + pretty_colors {is} зелена, жута + color {is} {ask} 'Која је твоја омиљена боја?' + {if} color {in} pretty_colors {print} 'лепа!' {else} {print} 'мех' - name: '{pressed}' - explanation: Check whether a given key on the keyboard is `{pressed}`. - demo_code: '{if} a {is} {pressed} {print} ''You pressed A!'' {else} {print} ''You pressed another key!''' + explanation: Провери да ли је одређени тастер на тастатури `{pressed}`. + demo_code: '{if} a {is} {pressed} {print} ''Притиснуо си А!'' {else} {print} ''Притиснуо си други тастер!''' 6: - name: '{print}' - explanation: Print exactly using quotation marks. - demo_code: '{print} ''5 times 5 is '' 5 * 5' + explanation: Испиши тачно користећи наводнике. + demo_code: '{print} ''5 пута 5 је '' 5 * 5' - name: '{ask}' - explanation: Ask for a calculation and check whether it is correct. + explanation: Питај за израчунавање и провери да ли је тачно. demo_code: |- - answer = {ask} 'What is 10 plus 10?' - {if} answer {is} 20 {print} 'Yes!' {else} {print} 'Oops' -- name: '{ask} and {if} with turtle' - explanation: Ask the user how many angles they want. + answer = {ask} 'Колико је 10 плус 10?' + {if} answer {is} 20 {print} 'Да!' {else} {print} 'Упс' +- name: '`{ask}` и `{if}` са корњачом' + explanation: Питај корисника колико углова жели. demo_code: |- - angles = {ask} 'How many angles?' + angles = {ask} 'Колико углова?' angle = 360 / angles {forward} 50 7: - name: '{print}' - explanation: Print exactly using quotation marks. - demo_code: '{print} ''Hello welcome to Hedy.''' + explanation: Испиши тачно користећи наводнике. + demo_code: '{print} ''Здраво, добродошао у Хеди.''' - name: '{ask}' - explanation: Ask something with `{ask}`. + explanation: Питај нешто са `{ask}`. demo_code: |- - color = {ask} 'What is your favorite color?' - {print} color ' is your favorite!' + color = {ask} 'Која је твоја омиљена боја?' + {print} color ' је твоја омиљена!' - name: '{if}' - explanation: Make a choice with `{if}`. + explanation: Направи избор са `{if}`. demo_code: |- - color = {ask} 'What is your favorite color?' - {if} color {is} green {print} 'pretty!' {else} {print} 'meh' -- name: '{repeat} with turtle' - explanation: Repeat a line of code with `{repeat}`. + color = {ask} 'Која је твоја омиљена боја?' + {if} color {is} зелена {print} 'лепа!' {else} {print} 'мех' +- name: '{repeat} са корњачом' + explanation: Понови линију кода са `{repeat}`. demo_code: '{repeat} 3 {times} {forward} 10' 8: - name: '{print}' - explanation: Print something. Remember to use a quotation mark for literal printing. - demo_code: '{print} ''5 times 5 is '' 5 * 5' + explanation: Испиши нешто. Запамти да користиш наводнике за дословно исписивање. + demo_code: '{print} ''5 пута 5 је '' 5 * 5' - name: '{ask}' - explanation: Ask for the answer to a sum and check if it is correct. We can now print 2 lines. + explanation: Питај за одговор на збир и провери да ли је тачан. Сада можемо исписати 2 линије. demo_code: |- - answer = {ask} 'What is 5 plus 5?' + answer = {ask} 'Колико је 5 плус 5?' {if} answer {is} 10 - {print} 'Well done!' - {print} 'Indeed, the answer was ' answer + {print} 'Браво!' + {print} 'Заиста, одговор је ' answer {else} - {print} 'Oops!' - {print} 'The answer is 10' -- name: '{repeat} with turtle' - explanation: Repeat multiple lines. + {print} 'Упс!' + {print} 'Одговор је 10' +- name: '{repeat} са корњачом' + explanation: Понови више линија. demo_code: |- {repeat} 4 {times} {turn} 90 {forward} 50 - name: '{pressed}' - explanation: Check whether a given key on the keyboard is `{pressed}`. + explanation: Провери да ли је одређени тастер на тастатури `{pressed}`. demo_code: |- {if} a {is} {pressed} - {print} 'You pressed A!' + {print} 'Притиснуо си А!' {else} - {print} 'You pressed another key!' + {print} 'Притиснуо си други тастер!' 9: -- name: '{if} with multiple lines' - explanation: The answer of a sum of questions with `{ask}` and see if it is correct. Now we print out two lines. +- name: '{if} са више линија' + explanation: Одговор на збир питања са `{ask}` и види да ли је тачан. Сада исписујемо две линије. demo_code: |- - answer = {ask} 'What is 10 plus 10?' + answer = {ask} 'Колико је 10 плус 10?' {if} answer {is} 20 - {print} 'Well done!!' - {print} 'The answer is indeed' answer + {print} 'Браво!!' + {print} 'Одговор је заиста' answer {else} - {print} 'Wrong' - {print} 'The answer is 20' -- name: '{repeat} with turtle' - explanation: Repeat multiple lines. + {print} 'Погрешно' + {print} 'Одговор је 20' +- name: '{repeat} са корњачом' + explanation: Понови више линија. demo_code: |- {repeat} 4 {times} {turn} 90 {forward} 50 10: - name: '{print}' - explanation: Print something. Remember to use a quotation mark for literal printing. - demo_code: '{print} ''5 times 5 is '' 5 * 5' -- name: '{for} with a list' - explanation: Print all things in a list. - demo_code: |- - animals {is} dog, cat, blobfish - {for} animal {in} animals - {print} 'I love ' animal + explanation: Одштампај нешто. Запамти да користиш наводнике за дословно штампање. + demo_code: '{print} ''5 пута 5 је '' 5 * 5' +- name: '{for} са листом' + explanation: Одштампај све ствари из листе. + demo_code: |- + животиње {is} пас, мачка, blobfish + {for} животиња {in} животиње + {print} 'Волим ' животиња 11: -- name: '{for} loop' - explanation: We can use `{for}` with a `{range}`. +- name: '{for} петља' + explanation: Можемо користити `{for}` са `{range}`. demo_code: |- {for} counter {in} {range} 1 {to} 5 {print} counter - name: '{ask}' - explanation: Ask for the answer to a sum and check if it is correct. We can now print 2 lines. + explanation: Питај за одговор на збир и провери да ли је тачан. Сада можемо одштампати 2 линије. demo_code: |- - answer = {ask} 'What is 5 plus 5?' - {if} answer {is} 10 - {print} 'Well done!' - {print} 'Indeed, the answer was ' answer + одговор = {ask} 'Колико је 5 плус 5?' + {if} одговор {is} 10 + {print} 'Браво!' + {print} 'Заиста, одговор је био ' одговор {else} - {print} 'Oops!' - {print} 'The answer is 10' + {print} 'Упс!' + {print} 'Одговор је 10' 12: -- name: float directly - explanation: Decimal numbers. +- name: директно са децималним бројевима + explanation: Децимални бројеви. demo_code: |- - {print} 'Calculate away!' - {print} 'Two and a half plus two and a half is...' + {print} 'Израчунај!' + {print} 'Два и по плус два и по је...' {print} 2.5 + 2.5 -- name: assign text - explanation: Text with quotation marks after `=` +- name: додели текст + explanation: Текст са наводницима после `=` demo_code: |- - name = 'Hedy the Robot' - {print} 'Hello ' name -- name: quotes after {if} comparison - explanation: Text with quotation marks after `{if}`. + име = 'Hedy the Robot' + {print} 'Здраво ' име +- name: наводници после `{if}` поређења + explanation: Текст са наводницима после `{if}`. demo_code: |- - name = {ask} 'Who are you?' - {if} name = 'Hedy' - {print} 'Hi there!' -- name: quotes in list - explanation: A list with quotation marks. + име = {ask} 'Ко си ти?' + {if} име = 'Hedy' + {print} 'Здраво!' +- name: наводници у листи + explanation: Листа са наводницима. demo_code: |- superheroes = 'Iron Man', 'Batman', 'Superman' {print} superheroes {at} {random} 13: - name: '{and}' - explanation: Two parts both need to be correct. + explanation: Оба дела морају бити тачна. demo_code: |- - answer1 = {ask} 'What is 3+2?' - answer2 = {ask} 'What is 2+2?' - {if} answer1 {is} 5 {and} answer2 {is} 4 - {print} 'Both answers are correct!' + одговор1 = {ask} 'Колико је 3+2?' + одговор2 = {ask} 'Колико је 2+2?' + {if} одговор1 {is} 5 {and} одговор2 {is} 4 + {print} 'Оба одговора су тачна!' {else} - {print} 'At least one answer is wrong!' + {print} 'Бар један одговор је нетачан!' - name: '{or}' - explanation: At least 1 of the two parts need to be correct. If both are correct, it is also fine. + explanation: Бар један од два дела мора бити тачан. Ако су оба тачна, такође је у реду. demo_code: |- - answer1 = {ask} 'What is 3+2?' - answer2 = {ask} 'What is 2+2?' - {if} answer1 {is} 5 {or} answer2 {is} 4 - {print} 'At least one answer is correct!' + одговор1 = {ask} 'Колико је 3+2?' + одговор2 = {ask} 'Колико је 2+2?' + {if} одговор1 {is} 5 {or} одговор2 {is} 4 + {print} 'Бар један одговор је тачан!' {else} - {print} 'Both answers are wrong!' + {print} 'Оба одговора су нетачна!' 14: -- name: Smaller - explanation: We use the `<` to check if the first number is smaller than the second number. - demo_code: |- - age = {ask} 'How old are you?' - {if} age < 13 - {print} 'You are younger than me!' -- name: Bigger - explanation: We use the `>` to check if the first number is bigger than the second number. - demo_code: |- - age = {ask} 'How old are you?' - {if} age > 13 - {print} 'You are older than me!' -- name: Equal - explanation: We use the `==` to check if two things are the same. - demo_code: |- - answer = {ask} 'What is 5 * 5?' - {if} answer == 25 - {print} 'That is correct!' -- name: Not equal - explanation: We use the `!=` to check if two things are not the same. - demo_code: |- - answer = {ask} 'What is 5 * 5?' - {if} answer != 25 - {print} 'That is not correct!' -- name: Smaller or equal - explanation: We use the `<=` to check if the first number is smaller than or equal to the second number. - demo_code: |- - age = {ask} 'How old are you?' - {if} age <= 12 - {print} 'You are younger than me!' -- name: Bigger or equal - explanation: We use the `>=` to check if the first number is bigger than or equal to the second number. - demo_code: |- - age = {ask} 'How old are you?' - {if} age >= 14 - {print} 'You are older than me!' +- name: Мање + explanation: Користимо `<` да проверимо да ли је први број мањи од другог броја. + demo_code: |- + године = {ask} 'Колико имаш година?' + {if} године < 13 + {print} 'Млађи си од мене!' +- name: Веће + explanation: Користимо `>` да проверимо да ли је први број већи од другог броја. + demo_code: |- + године = {ask} 'Колико имаш година?' + {if} године > 13 + {print} 'Старији си од мене!' +- name: Једнако + explanation: Користимо `==` да проверимо да ли су две ствари исте. + demo_code: |- + одговор = {ask} 'Колико је 5 * 5?' + {if} одговор == 25 + {print} 'То је тачно!' +- name: Није једнако + explanation: Користимо `!=` да проверимо да ли две ствари нису исте. + demo_code: |- + одговор = {ask} 'Колико је 5 * 5?' + {if} одговор != 25 + {print} 'То није тачно!' +- name: Мање или једнако + explanation: Користимо `<=` да проверимо да ли је први број мањи или једнак другом броју. + demo_code: |- + године = {ask} 'Колико имаш година?' + {if} године <= 12 + {print} 'Млађи си од мене!' +- name: Веће или једнако + explanation: Користимо `>=` да проверимо да ли је први број већи или једнак другом броју. + demo_code: |- + године = {ask} 'Колико имаш година?' + {if} године >= 14 + {print} 'Старији си од мене!' 15: - name: '{while}' - explanation: We can use the `{while}` loop with not equal. - demo_code: |- - answer = 0 - {while} answer != 25 - answer = {ask} 'What is 5 times 5?' - {print} 'A correct answer has been given' -- name: Smaller {while} - explanation: We can also use the `{while}` loop with `<` and `>`. - demo_code: |- - count = 1 - {while} count < 3 - {print} 'We do this ' 3 - count ' more times' - count = count + 1 - {print} 'We are done' + explanation: Можемо користити `{while}` петљу са није једнако. + demo_code: |- + одговор = 0 + {while} одговор != 25 + одговор = {ask} 'Колико је 5 пута 5?' + {print} 'Дат је тачан одговор' +- name: Мање {while} + explanation: Такође можемо користити `{while}` петљу са `<` и `>`. + demo_code: |- + бројач = 1 + {while} бројач < 3 + {print} 'Ово радимо још ' 3 - бројач ' пута' + бројач = бројач + 1 + {print} 'Завршили смо' 16: -- name: square brackets - explanation: Lists with square brackets. - demo_code: |- - fruit = ['apple', 'banana', 'cherry'] - {print} fruit -- name: Get an item from a list - explanation: To get an item from a list we use [number] so fruit[1] means, get the first fruit from the list! - demo_code: |- - fruit = ['banana', 'apple', 'cherry'] - firstfruit = fruit[1] - {print} firstfruit -- name: Get a random item from a list - explanation: To get a random item from a list we use [random] so fruit[random] means, get a random fruit from the list! - demo_code: |- - fruit = ['banana', 'apple', 'cherry'] - random_fruit = fruit[{random}] - {print} random_fruit +- name: угласте заграде + explanation: Листе са угластим заградама. + demo_code: |- + воће = ['јабука', 'банана', 'трешња'] + {print} воће +- name: Узми ставку из листе + explanation: Да узмемо ставку из листе користимо [број] тако да воће[1] значи, узми прво воће из листе! + demo_code: |- + воће = ['банана', 'јабука', 'трешња'] + прво_воће = воће[1] + {print} прво_воће +- name: Узми случајну ставку из листе + explanation: Да узмемо случајну ставку из листе користимо [{random}] тако да воће[{random}] значи, узми случајно воће из листе! + demo_code: |- + воће = ['банана', 'јабука', 'трешња'] + случајно_воће = воће[{random}] + {print} случајно_воће 17: - name: '{elif}' explanation: '`{elif}`' demo_code: |- - a = 2 - {if} a == 1: - {print} 'a is 1' - {elif} a == 2: - {print} 'a is 2' + а = 2 + {if} а == 1: + {print} 'а је 1' + {elif} а == 2: + {print} 'а је 2' {else}: - {print} 'a is not 1 or 2' + {print} 'а није 1 или 2' - name: '{print}' - explanation: When we use a `{for}`, we need to put a `:` behind the `{for}` statement! + explanation: Када користимо `{for}`, морамо ставити `:` иза `{for}` изјаве! demo_code: |- {for} i {in} {range} 1 {to} 12: {print} i {print} 'Ready or not, here I come!' - name: '{if}' - explanation: We need to do the same with all of our `{if}` statements. + explanation: Морамо урадити исто са свим нашим `{if}` изјавама. demo_code: |- - color = {ask} 'What is your favorite color?' - {if} color == 'green': - {print} 'Your favorite color is green' + боја = {ask} 'Која је твоја омиљена боја?' + {if} боја == 'зелена': + {print} 'Твоја омиљена боја је зелена' {else}: - {print} 'Your favorite color is not green' + {print} 'Твоја омиљена боја није зелена' 18: - name: '{print}' - explanation: After `{print}` you need to use parentheses. - demo_code: '{print}(''hi!'')' + explanation: После `{print}` мораш користити заграде. + demo_code: '{print}(''здраво!'')' - name: '{range}' - explanation: After `{range}` you need to use parentheses. + explanation: После `{range}` мораш користити заграде. demo_code: |- {for} i {in} {range} (1,10): - {print}('Hello, times ', i) -- name: '{print} with var' - explanation: With `{print}` you need to use parentheses and commas if you print more items. + {print}('Здраво, пута ', i) +- name: '{print} са променљивом' + explanation: Са `{print}` мораш користити заграде и зарезе ако штампаш више ставки. demo_code: |- - name = 'Hedy' - {print}('my name is ', name) -- name: ask something with {input} - explanation: Use `{input}` instead of `{ask}` to ask something. + име = 'Hedy' + {print}('моје име је ', име) +- name: питај нешто са {input} + explanation: Користи `{input}` уместо `{ask}` да питаш нешто. demo_code: |- - name = {input}('What is your name?') - {print}('So your name is ', name) + име = {input}('Како се зовеш?') + {print}('Дакле, твоје име је ', име) diff --git a/content/client-messages/ca.yaml b/content/client-messages/ca.yaml index e33a10eeefa..977de95e3ef 100644 --- a/content/client-messages/ca.yaml +++ b/content/client-messages/ca.yaml @@ -1,4 +1,4 @@ -CheckInternet: Mireu si la vostra connexió a Internet funciona correctament. +CheckInternet: Mireu si la teva connexió a Internet funciona correctament. Connection_error: No hem pogut arribar al servidor. Empty_output: Aquest codi funciona, però no imprimeix res. Afegiu una comanda d'impressió al vostre codi o utilitzeu la tortuga per obtenir la sortida. Errors_found: Has comès un error! No et preocupis, encara podem executar el programa diff --git a/content/client-messages/sr.yaml b/content/client-messages/sr.yaml index 08c47a29e00..61c3d6eab10 100644 --- a/content/client-messages/sr.yaml +++ b/content/client-messages/sr.yaml @@ -1,21 +1,21 @@ -CheckInternet: Proveri da li imaš internet konekciju. -Connection_error: Ne mogu dostignuti server. -Empty_output: Ovaj kod radi, ali ne prikazuje ništa. Dodaj komandu za prikazivanje u kodu ili koristi turtle da prikažeš rezultat. -Errors_found: Napravio si grešku! Ne brini, i dalje smo uspeli da pokrenemo program -Execute_error: Nešto se pokvarilo dok je program radio. -Other_error: Ups! Možda smo napravili malu grešku. -Program_repair: Možda je ovo ispravan kod, možeš li ga popraviti? -Program_too_long: Tvoj program zahteva mnogo vremena za pokretanje. -ServerError: Napisali ste program koji nismo očekivali. Ako želite da pomognete, pošaljite nam mejl sa nivoom i vašim programom na hello@hedy.org. U međuvremenu, pokušajte nešto malo drugačije i pogledajte još jednom primere. Hvala! -Transpile_error: Ne možemo da pokrenemo tvoj program. +CheckInternet: Проверите да ли ваша интернет веза ради. +Connection_error: Нисмо могли да приступимо серверу. +Empty_output: Овај код ради, али не приказује ништа. Додајте команду за приказивање у ваш код или користите корњачу за добијање излаза. +Errors_found: Направили сте грешку! Не брините, ипак смо покренули програм. +Execute_error: Нешто је пошло наопако приликом покретања програма. +Other_error: Упс! Можда смо направили малу грешку. +Program_repair: Ово би могао бити исправан код, можете ли га поправити? +Program_too_long: Ваш програм траје предуго да се изврши. +ServerError: Написали сте програм који нисмо очекивали. Ако желите да помогнете, пошаљите нам имејл са нивоом и вашим програмом на hello@hedy.org. У међувремену, пробајте нешто мало другачије и поново погледајте примере. Хвала! +Transpile_error: Не можемо да покренемо ваш програм. Transpile_success: -- Dobar posao! -- Neverovatno! -- Dobro urađeno! -- Odlično! -- Bio si odličan! -Transpile_warning: Upozorenje! -Unsaved_Changes: Nisi sačuvao program. Želiš li da izađeš bez čuvanja? +- Добар посао! +- Невероватно! +- Браво! +- Одлично! +- Сјајно си урадио! +Transpile_warning: Упозорење! +Unsaved_Changes: Имате несачуван програм. Да ли желите да изађете без чувања? dice: 🎲 fortune: 🔮, ✨ haunted: 🦇, 👻, 🎃 diff --git a/content/keywords/ru.yaml b/content/keywords/ru.yaml index 6d80c20ad12..56536568894 100644 --- a/content/keywords/ru.yaml +++ b/content/keywords/ru.yaml @@ -1,6 +1,6 @@ add: добавить and: и -ask: запросить +ask: спросить at: в black: чёрный blue: синий diff --git a/content/keywords/sr.yaml b/content/keywords/sr.yaml index 4443ab2e0de..42eac4d06a2 100644 --- a/content/keywords/sr.yaml +++ b/content/keywords/sr.yaml @@ -1,13 +1,13 @@ -add: dodaj -and: i -ask: pitaj -at: na -black: crna -blue: plava -brown: braon -call: call -clear: očisti -color: boja +add: додај +and: и +ask: питај +at: на +black: црна +blue: плава +brown: браон +call: позови +clear: очисти +color: боја comma: ',' d0: '0' d1: '1' @@ -19,49 +19,49 @@ d6: '6' d7: '7' d8: '8' d9: '9' -def: def -define: definiši -echo: pokaži -elif: inače ako -else: inače -'false': 'false' -'False': 'False' -for: za -forward: napred -from: od -gray: siva -green: zelena -if: ako -in: u -input: ulaz -is: je -left: levo -length: dužina -not_in: ne/nije u -or: ili -orange: narandžasta -pink: roze -play: play -pressed: pritisnuto -print: štampaj -purple: ljubičasta +def: деф +define: дефиниши +echo: покажи +elif: иначе ако +else: иначе +'false': 'нетачно' +'False': 'Нетачно' +for: за +forward: напред +from: од +gray: сива +green: зелена +if: ако +in: у +input: улаз +is: је +left: лево +length: дужина +not_in: не/није у +or: или +orange: наранџаста +pink: розе +play: играј +pressed: притиснуто +print: штампај +purple: љубичаста quote: '''' -random: nasumično -range: opseg -red: crvena -remove: obriši -repeat: ponovi -return: vrati -right: desno -sleep: spavanje -step: korak -times: vremena -to: u -to_list: u -'true': 'true' -'True': 'True' -turn: okreni -while: dok -white: bela -with: sa -yellow: žuta +random: насумично +range: опсег +red: црвена +remove: обриши +repeat: понови +return: врати +right: десно +sleep: спавање +step: корак +times: пута +to: до +to_list: до +'true': 'тачно' +'True': 'Тачно' +turn: окрени +while: док +white: бела +with: са +yellow: жута diff --git a/content/pages/bg.yaml b/content/pages/bg.yaml index 8b62192e299..fdd33639b99 100644 --- a/content/pages/bg.yaml +++ b/content/pages/bg.yaml @@ -85,7 +85,7 @@ start-sections: - title: Започни с Хеди text: |- Добре дошли в Хеди, радваме се да ви помогнем да започнете с Хеди. - Нашият [Учетелски наръчник](http://localhost:8080/for-teachers/manual) описва всичките детайли, но тази страница има късо обяснение за да се запознаете преди да влезете в детайли. + Нашият [Учетелски наръчник](https://www.hedy.org/for-teachers/manual) описва всичките детайли, но тази страница има късо обяснение за да се запознаете преди да влезете в детайли. A few highlights that are important to know: * Hedy is a tool designed to help manage a classroom of kids programming! You can create your own classes, lesson plans and follow how kids are doing. diff --git a/content/pages/de.yaml b/content/pages/de.yaml index e5e0d466813..a6ae41bffcf 100644 --- a/content/pages/de.yaml +++ b/content/pages/de.yaml @@ -91,7 +91,7 @@ start-sections: text: |- Willkommen bei Hedy, wir freuen uns dir beim Loslegen zu helfen. - Unsere [Lehranleitung](http://localhost:8080/for-teachers/manual) enthält einen Überblick über alle Features im Detail, aber diese Seite enthält einen kurzen Überblick, damit du weißt was was ist, bevor du einsteigst. + Unsere [Lehranleitung](https://www.hedy.org/for-teachers/manual) enthält einen Überblick über alle Features im Detail, aber diese Seite enthält einen kurzen Überblick, damit du weißt was was ist, bevor du einsteigst. Einige Punkte die wichtig sind: * Hedy ist ein Werkzeug, das entwickelt wurde, um das Unterrichten einer Klasse von Kindern beim Programmieren zu unterstützen! Du kannst deinen eigenen Lektionen und Lehrpläne erzeugen und mitverfolgen, wie die Kinder voran kommen diff --git a/content/pages/en.yaml b/content/pages/en.yaml index 27e7648061f..06bf94a63ab 100644 --- a/content/pages/en.yaml +++ b/content/pages/en.yaml @@ -91,7 +91,7 @@ start-sections: text: |- Welcome to Hedy, we are happy to help you get started with Hedy. - Our [Teacher Manual](http://localhost:8080/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. + Our [Teacher Manual](https://www.hedy.org/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. A few highlights that are important to know: * Hedy is a tool designed to help manage a classroom of kids programming! You can create your own classes, lesson plans and follow how kids are doing. diff --git a/content/pages/es.yaml b/content/pages/es.yaml index 0d909f5115b..937f7eb850c 100644 --- a/content/pages/es.yaml +++ b/content/pages/es.yaml @@ -91,7 +91,7 @@ start-sections: text: |- Bienvenido a Hedy, estamos encantados de ayudarle a empezar con Hedy. - Nuestro [Manual del Profesor](http://localhost:8080/for-teachers/manual) tiene una visión general de todas las características en detalle, pero esta página tiene un breve resumen para que sepa lo que es lo que antes de sumergirse. + Nuestro [Manual del Profesor](https://www.hedy.org/for-teachers/manual) tiene una visión general de todas las características en detalle, pero esta página tiene un breve resumen para que sepa lo que es lo que antes de sumergirse. Algunos aspectos destacados que son importantes saber: * ¡Hedy es una herramienta diseñada para ayudar a gestionar un aula de programación infantil! Usted puede crear sus propias clases, planes de lecciones y seguir cómo los niños están haciendo. @@ -302,11 +302,11 @@ teacher-guide: text: |- Cada nivel contiene diferentes aventuras que puedes encontrar en las pestañas rosas. La primera pestaña rosa explica los nuevos comandos de este nivel. Las siguientes pestañas son aventuras que los alumnos pueden probar y hacer suyas. - Las aventuras están ordenadas de la más fácil a la más difícil, por lo que recomendamos empezar por la izquierda e ir avanzando hacia la derecha. - La última pestaña, "qué sigue", ofrece un pequeño adelanto de lo que aprenderás en el siguiente nivel. Por supuesto, puedes seleccionar las aventuras que quieres que tus alumnos hagan en cada nivel. + Las aventuras están ordenadas de la más fácil a la más difícil, así que te recomendamos que empieces por la izquierda y sigas hacia la derecha. + La última pestaña, «qué sigue», ofrece un pequeño adelanto de lo que aprenderás en el siguiente nivel. Por supuesto, puedes seleccionar las aventuras que quieres que tus alumnos hagan en cada nivel. No siempre tienen que hacer todas las aventuras. Cada aventura contiene un código de ejemplo, que los alumnos pueden probar con el botón verde. El código de ejemplo se copia en el campo de trabajo, donde los alumnos pueden probar el código y ajustarlo para hacerlo suyo. - Estimule a sus alumnos para que conviertan los códigos de ejemplo en sus propios proyectos, añadiendo sus propias ideas y creando su propia variación de la aventura. + Estimule a sus alumnos para que conviertan el código de ejemplo en sus propios proyectos, añadiendo sus propias ideas y creando su propia variación de la aventura. - title: Concursos y rompecabezas text: |- Para evaluar si tus alumnos han aprendido toda la nueva información en el nivel, puedes permitirles que hagan un cuestionario. @@ -419,9 +419,7 @@ teacher-guide: - title: Errores frecuentes key: errores_comunes intro: |- - Tu puedes aprender de tus errores, especialmente programando! - Errar es inevitable y una gran oportunidad para aprender, pero para los profesores puede ser difícil encontrar la solución correcta a un error! - Especialmente mientras el código crece junto a al progreso de los niveles. Es por esto que hemos hecho una lista de los errores frecuentes en cada nivel y sus soluciones. + De los errores se aprende, sobre todo en programación. Cometer errores es inevitable y una gran oportunidad para aprender, pero para los profesores puede ser un reto encontrar la solución correcta a un error. Sobre todo porque los programas son cada vez más largos a medida que los alumnos avanzan de nivel. Por eso hemos elaborado una lista con los errores más frecuentes en cada nivel y sus soluciones. levels: - level: '1' sections: @@ -465,7 +463,7 @@ teacher-guide: error_code: |- {forward} 300 {turn} 90 - solution_text: En el ejemplo, los alumnos tienden a pensar que el comando girar no funciona. Aunque sí funciona, no se puede ver que sucede fuera de la pantalla. Utiliza números más pequeños para evitar que esto ocurra. + solution_text: En el ejemplo, los estudiantes tienden a pensar que el comando de giro falló, a pesar de que hizo lo que se suponía que debía hacer. Lo que ocurrió es que la tortuga sobrepasó los límites de la pantalla. Utiliza números más pequeños para evitar que esto ocurra. solution_code: |- {forward} 100 {turn} 90 @@ -645,7 +643,7 @@ teacher-guide: estado_animo {is} {ask} '¿Cómo estás?' - title: Los alumnos utilizan las comillas equivocadas example: - error_text: Es importante empezar tu clase comprobando si los alumnos saben como usar las comillas adecuadamente. Sino podrían usar las "comillas dobles" o las `torcidas`. + error_text: Es importante empezar la clase comprobando si los alumnos saben escribir correctamente las comillas. En Hedy, los alumnos pueden utilizar comillas simples ('') y dobles («»). Por otro lado, los puntos suspensivos no se consideran comillas válidas (``). error_code: |- {print} `Bienvenido al restaurante` comida {is} {ask} "¿Qué te gustaría pedir?" @@ -687,7 +685,7 @@ teacher-guide: {else} {print} '¡no mola tanto!' - title: Los estudiantes aún olvidan las comillas en ambos lados example: - error_text: Los códigos que usan el comando `if` pueden extenderse mucho y los alumnos tienden a olvidar usar comillas. + error_text: El uso del comando `if` puede hacer que las líneas de código sean muy largas y los alumnos tienden a olvidar el uso de las comillas. error_code: |- {if} nombre {is} Hedy {print} divertido {else} {print} '¡meh! @@ -705,16 +703,16 @@ teacher-guide: solution_code: |- {if} nombre {is} Hedy {print} 'divertido' {else} {print} '¡meh! - - title: Los estudiantes usan nombres largos para las variables que contienen dos palabras + - title: Los alumnos utilizan nombres de variables largos que contienen dos o más palabras example: - error_text: Una variable debería llamarse con una palabra. Puedes usar un guion bajo para conectar dos palabras. Eso cuenta como una. + error_text: Las variables en Hedy no pueden contener espacios, por lo que, con el fin de utilizar juntos varias palabras, los estudiantes necesitan para conectarlos utilizando guiones bajos (_) error_code: puerta elegida es preguntar ¿Qué puerta eliges? solution_text: Añade un guion bajo. solution_code: puerta_elegida {is} {ask} '¿qué puerta eliges?' - title: Los alumnos quieren varias respuestas correctas example: - error_text: Por ejemplo este alumno Hedy le dice a todos sus amigos que son divertidos, pero a otros compañeros les diría que no lo son. - error_code: "{if} nombre {is} Jesse, David, Souf imprimir Eres divertido {else} {print} 'No eres divertido'" + error_text: Por ejemplo, este alumno quiere que Hedy diga a todos sus amigos que son graciosos, mientras que a otros compañeros debería decirles que no lo son. + error_code: "{if} nombre {is} Jesse, David, Souf {print} 'Eres divertido' {else} {print} 'No eres divertido'" solution_text: |- Puedes usar el comando `{in}` para eso. Se explica en un nivel superior, pero ya funciona en el nivel 5. Otra solución es usar varios comandos `{if}` y no comando `{else}`. La desventaja es que no le dirá a los otros compañeros que no son divertidos. @@ -793,7 +791,7 @@ teacher-guide: {print} bebida - title: Los alumnos hacen programas que tardan demasiado en ejecutar example: - error_text: En este nivel es muy fácil hacer códigos extensos. Los alumnos no tienen permitido hacer programas que tarden mucho en cargar (para proteger nuestros servidores). + error_text: En este nivel es muy fácil hacer programas que tarden mucho en completarse. Si el programa tarda demasiado, se detendrá, esto con la intención de evitar forzar la máquina al alumno. error_code: "{repeat} 100 {times} {print} '¿Cuántas veces puedo repetir esto?'" solution_text: Asegúrate que el código no tarda mucho en ejecutarse solution_code: "{repeat} 20 {times} {print} 'Esto es suficiente'" @@ -801,7 +799,7 @@ teacher-guide: sections: - title: Los alumnos usan la sangría mal example: - error_text: La sangría es un nuevo concepto de este nivel, es complicada de usar para algunos alumnos. Asegúrate que practican algunos códigos sencillos antes de hacer un programa entero con ella. + error_text: La sangría es un concepto nuevo en este nivel, y para algunos alumnos puede resultar difícil de aprender. Asegúrate de que practiquen algunos ejemplos sencillos antes de hacer un programa completo con ella. error_code: |- {repeat} 3 {times} {print} 'hola' @@ -842,7 +840,7 @@ teacher-guide: {print} '¡Hip Hip Hurra!' - title: Los alumnos hacen programas que tardan demasiado en ejecutar example: - error_text: En este nivel es muy fácil hacer códigos extensos. Los alumnos no tienen permitido hacer programas que tarden mucho en cargar (para proteger nuestros servidores). + error_text: En este nivel es muy fácil hacer programas que tarden mucho en completarse. Si el programa tarda demasiado, se detendrá, esto con la intención de evitar forzar la máquina al alumno. error_code: |- {repeat} 100 {times} {print} '¿Cuántas veces puedo repetir esto?' @@ -853,9 +851,9 @@ teacher-guide: - title: Los alumnos usan el comando `{if}` para comprobar si el valor de la variable es el mismo que el nombre de la variable example: error_text: |- - Hemos visto este error por algunos de nuestros alumnos. Hacen una contraseña para su ordenador, pero llaman a la contraseña 'contraseña'. - En la línea 2 se pide al ordenador comprobar si la variable contraseña es la misma que la variable contraseña, por lo que sí. Lo que significa que la respuesta siempre es sí. - Así que con este código la respuesta siempre será 'Puedes entrar' sin importar lo que el jugador ponga. + Hemos observado un error común entre nuestros alumnos: intentan crear un programa que compruebe si hay una contraseña, pero hacen que la contraseña sea 'password'. + En la línea 2 se pide al ordenador que compruebe si la variable contraseña es la misma que la variable contraseña, por lo tanto sí. Lo que significa que la respuesta es siempre sí. + Así que con este código la respuesta siempre será 'Puedes entrar' sin importar lo que el jugador rellene. error_code: |- contraseña {is} {ask} '?Cuál es la contraseña?' {if} contraseña {is} contraseña diff --git a/content/pages/fr_CA.yaml b/content/pages/fr_CA.yaml index 3e7beaf9225..415a48d0c62 100644 --- a/content/pages/fr_CA.yaml +++ b/content/pages/fr_CA.yaml @@ -90,7 +90,7 @@ start-sections: text: 'Bienvenue sur Hedy, nous sommes heureux de vous aider à démarrer avec Hedy. - Notre [Manuel de l''enseignant](http://localhost:8080/for-teachers/manual) offre un aperçu détaillé de toutes les fonctionnalités, mais cette page présente un bref aperçu pour que vous sachiez à quoi vous attendre avant de vous plonger. + Notre [Manuel de l''enseignant](https://www.hedy.org/for-teachers/manual) offre un aperçu détaillé de toutes les fonctionnalités, mais cette page présente un bref aperçu pour que vous sachiez à quoi vous attendre avant de vous plonger. Quelques points importants à savoir: diff --git a/content/pages/fy.yaml b/content/pages/fy.yaml index a2a77703123..c138ae0aa4e 100644 --- a/content/pages/fy.yaml +++ b/content/pages/fy.yaml @@ -91,7 +91,7 @@ start-sections: text: |- Welcome to Hedy, we are happy to help you get started with Hedy. - Our [Teacher Manual](http://localhost:8080/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. + Our [Teacher Manual](https://www.hedy.org/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. A few highlights that are important to know: * Hedy is a tool designed to help manage a classroom of kids programming! You can create your own classes, lesson plans and follow how kids are doing. diff --git a/content/pages/hr.yaml b/content/pages/hr.yaml index 7e037dd83fb..8d7b72d0442 100644 --- a/content/pages/hr.yaml +++ b/content/pages/hr.yaml @@ -552,7 +552,7 @@ learn-more-sections: - title: Hedy in the news text: "Some websites and newspapers have written about Hedy since our release in early 2020. We keep a list here:\n* [Java Magazine 04.2023](images/Hedy_Javamagazine2023.pdf)\n* [Tech Optimism - A Solution to the IT Shortage (Dutch), August 2022](https://pom.show/2022/08/12/een-oplossing-voor-het-it-tekort/)\n* [Codeweek Podcast, July 2022](https://codeweek.eu/podcast/26)\n* [Heise.de (German), Januari 2022](https://www.heise.de/news/Hedy-die-mitwachsende-Programmiersprache-6336264.html)\n* [Strumenta, November 2021](https://tomassetti.me/teaching-programming-with-hedy/)\n* [Vives (Dutch), CodeWeek Special October 2021](images/Vives-174-Codeweek.pdf)\n* [CodeWeek.eu - Haunted House Challenge, September 2021](https://codeweek.eu/2021/challenges/haunted-house)\n* [Opensource.com, April 2021](https://opensource.com/article/21/4/hedy-teach-code)\n* [IO Magazine, April 2021](https://ict-research.nl/wordpress/wp-content/uploads/2021/04/IO-magazine-NR1-2021_web.pdf)\n* [Ingeniería De Software (Spanish), February 2021](https://ingenieriadesoftware.es/hedy-mejor-lenguaje-ensenar-programacion-ninos/)\n* [Hello World Magazine, February 2021](images/Hello_World_15_Hedy.pdf)\n* [Discoro, January 2021](https://discoro.wordpress.com/2021/01/09/hedy-gradually-learning-a-programming-language/)\n* [Felienne wins the Dutch award for ICT research for Hedy, January 2021](https://www.nwo.nl/en/news/felienne-hermans-receives-dutch-prize-ict-research-2021)\n* [SlashDot, August 2020](https://news.slashdot.org/story/20/08/17/024248/scientist-proposes-a-new-programming-language-for-teaching-coding-and-python)\n* [GenBeta (Spanish), August 2020](https://www.genbeta.com/desarrollo/nuevo-lenguaje-para-ensenar-programacion-a-ninos-como-se-ensena-a-leer-escribir-forma-gradual-niveles)\n* [Developpez (French), August 2020](https://programmation.developpez.com/actu/308095/Une-scientifique-propose-un-nouveau-langage-de-programmation-pour-enseigner-aux-enfants-le-codage-informatique-au-travers-d-une-approche-graduelle-implementee-en-Python-sur-13-paliers/)\n* [Vives (Dutch), October 2020](images/artikel_vives.pdf) \"Met Hedy stap voor stap leren programmeren\"\n* [Leiden University, April 2020](https://www.universiteitleiden.nl/en/news/2020/03/looking-to-distract-the-kids-while-you-work-from-home-get-them-programming)\n* [Mare (Dutch), April 2020](https://www.mareonline.nl/cultuur/computercode-voor-de-kids/)\n* [AG Connect (Dutch), April 2020](https://www.agconnect.nl/artikel/stapsgewijs-python-leren-programmeren-met-nieuwe-taal-hedy)" start-sections: -- text: "Welcome to Hedy, we are happy to help you get started with Hedy.\n\nOur [Teacher Manual](http://localhost:8080/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in.\n\nA few highlights that are important to know:\n* Hedy is a tool designed to help manage a classroom of kids programming! You can create your own classes, lesson plans and follow how kids are doing.\n* You do not need to know a lot of programming if you begin, Hedy works step by step, also for you!\n* You can use Hedy in your native tongue because it has been translated into many other languages!\n* Every kid can programme!! Hedy is especially helpful for kids who have vision problems because it can read material aloud to you without the need for a mouse.\n* We are here to help, you can find us for example on [Discord](https://discord.gg/8yY7dEme9r) or you can [email-us](hello@hedy.org)." +- text: "Welcome to Hedy, we are happy to help you get started with Hedy.\n\nOur [Teacher Manual](https://www.hedy.org/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in.\n\nA few highlights that are important to know:\n* Hedy is a tool designed to help manage a classroom of kids programming! You can create your own classes, lesson plans and follow how kids are doing.\n* You do not need to know a lot of programming if you begin, Hedy works step by step, also for you!\n* You can use Hedy in your native tongue because it has been translated into many other languages!\n* Every kid can programme!! Hedy is especially helpful for kids who have vision problems because it can read material aloud to you without the need for a mouse.\n* We are here to help, you can find us for example on [Discord](https://discord.gg/8yY7dEme9r) or you can [email-us](hello@hedy.org)." title: Getting started with Hedy - text: "Various teachers worldwide have expressed their passion for Hedy, as some have shared with us:\n\n*Incredibly inspiring! Super good way to make programming a lot more accessible for yourself, but also for students. Very fun to play with and a lot of potential to use with the students. I think it is a very nice tool! I believe this is a valuable way for children to start learning programming. Python and coding have always been very exciting, because the barrier to learning is very high. Now everything is a bit lower and it was explained that it can actually be very easy. I enjoyed seeing how Hedy tries to make programming as accessible as possible for users!*\nNetherlands: Mathematics teachers in training (secondary school)\n\n*Simple interface and good examples.* Teacher: 3rd - 6th grades (elementary)\n\n*Multilingual programming and just the gradual programming concept itself.* US: middle school, 6th-8th grade\n\n*The gradual nature of introducing programming.* Australia: High school\n\n*Continues automatically.* Netherlands: 2 HAVO-VWO\n\n*Both that the explanation can be in Dutch (and the code in English), and that it builds up with more and more possibilities.* Netherlands: Plus class group\n\n*But Hedy and its gradual levels...what an idea, I wanted to personally thank you for creating this. I cannot thank you enough. Also, I have never seen the level of engagement and enthusiasm of my students, as I have seen with Hedy. We have covered till level 5, and plan to spend one more week on it in classes and labs, before starting Python.* Pakistan\n\n*The 'realness' of programming, it resembles how it is in reality.* Netherlands: Plus class group 4 to 8\n\n*Step-by-step activities. Fun activities.* Netherlands: 1e All levels, 2e VWO/HAVO 2e VWO +, 3e HAVO 3e VWO\n\n*I really like Hedy very much and it is also nicely set up, which makes it good to use in primary school. Hedy's gradual approach works very well. The short explanation at the beginning of each level and the short example programs help to give the children a quick insight into what is new in the chosen level. The different assignments that the children can choose also work very well. You see the children choose assignments that appeal to them and they then get to work with them, through the levels. Hedy is great fun for children who are good at programming and want to get a taste of a real programming language. It is good preparation for secondary school as soon as more ICT education is given there.* Netherlands: Oegstgeest Montessori school\n\n*The construction is so good.* Netherlands: Lower secondary school HAVO-VWO\n\n*I can keep the pace of the class.* Netherlands: group 7 en 8\n\n![Felienne teaching kids](/images/teacherfeedback/Fkids1.JPG) *Felienne teaching kids*\n\n\n![Kids learning about Hedy](/images/teacherfeedback/Fkids2.JPG) *Kids learning about Hedy*" title: Teachers about Hedy diff --git a/content/pages/ia.yaml b/content/pages/ia.yaml index d648940d43c..9ee17ac6eda 100644 --- a/content/pages/ia.yaml +++ b/content/pages/ia.yaml @@ -91,7 +91,7 @@ start-sections: text: |- Welcome to Hedy, we are happy to help you get started with Hedy. - Our [Teacher Manual](http://localhost:8080/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. + Our [Teacher Manual](https://www.hedy.org/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. A few highlights that are important to know: * Hedy is a tool designed to help manage a classroom of kids programming! You can create your own classes, lesson plans and follow how kids are doing. diff --git a/content/pages/iba.yaml b/content/pages/iba.yaml index a2a77703123..c138ae0aa4e 100644 --- a/content/pages/iba.yaml +++ b/content/pages/iba.yaml @@ -91,7 +91,7 @@ start-sections: text: |- Welcome to Hedy, we are happy to help you get started with Hedy. - Our [Teacher Manual](http://localhost:8080/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. + Our [Teacher Manual](https://www.hedy.org/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. A few highlights that are important to know: * Hedy is a tool designed to help manage a classroom of kids programming! You can create your own classes, lesson plans and follow how kids are doing. diff --git a/content/pages/it.yaml b/content/pages/it.yaml index a5e349bed44..1a3c6820c1d 100644 --- a/content/pages/it.yaml +++ b/content/pages/it.yaml @@ -88,7 +88,7 @@ start-sections: text: |- Benvenuto in Hedy, siamo contenti di aiutarti a iniziare con Hedy. - Il nostro [Manuale per Insegnanti](http://localhost:8080/for-teachers/manual) fornisce una spiegazione di tutte le funzionalità in dettaglio, mentre in questa pagina troverai una breve panoramica. + Il nostro [Manuale per Insegnanti](https://www.hedy.org/for-teachers/manual) fornisce una spiegazione di tutte le funzionalità in dettaglio, mentre in questa pagina troverai una breve panoramica. Un po' di cose importanti da sapere: * Hedy è uno strumento progettato per aiutare nella gestione di una classe di bambini o ragazzi che programmano! Puoi preparare le tue lezioni, i tuoi piani e seguire quello che gli alunni fanno. diff --git a/content/pages/ms.yaml b/content/pages/ms.yaml index 72ee5a3f090..3113142d2d3 100644 --- a/content/pages/ms.yaml +++ b/content/pages/ms.yaml @@ -91,7 +91,7 @@ start-sections: text: |- Welcome to Hedy, we are happy to help you get started with Hedy. - Our [Teacher Manual](http://localhost:8080/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. + Our [Teacher Manual](https://www.hedy.org/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. A few highlights that are important to know: * Hedy is a tool designed to help manage a classroom of kids programming! You can create your own classes, lesson plans and follow how kids are doing. diff --git a/content/pages/nl.yaml b/content/pages/nl.yaml index c08a26f64cd..c8e80613768 100644 --- a/content/pages/nl.yaml +++ b/content/pages/nl.yaml @@ -97,7 +97,7 @@ start-sections: text: |- Welkom bij Hedy, wij zijn blij jouw te helpen met het starten met Hedy. - Onze [Leraren Handleiding](http://localhost:8080/for-teachers/manual) heeft een overzicht van alle mogelijkheden in detail, echter deze pagina heeft een beknopte versie zodat je dat weet wat het is voordat je er in duikt. + Onze [Leraren Handleiding](https://www.hedy.org/for-teachers/manual) heeft een overzicht van alle mogelijkheden in detail, echter deze pagina heeft een beknopte versie zodat je dat weet wat het is voordat je er in duikt. Een paar hoogtepunten die belangrijk zijn om te weten: * Hedy is een instrument ontworpen om het managen van een klas met kinderen die programmeren! Jij kan je eigen lessen creëren, lesplannen en volgen hoe kinderen het doen. diff --git a/content/pages/peo.yaml b/content/pages/peo.yaml index a2a77703123..c138ae0aa4e 100644 --- a/content/pages/peo.yaml +++ b/content/pages/peo.yaml @@ -91,7 +91,7 @@ start-sections: text: |- Welcome to Hedy, we are happy to help you get started with Hedy. - Our [Teacher Manual](http://localhost:8080/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. + Our [Teacher Manual](https://www.hedy.org/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. A few highlights that are important to know: * Hedy is a tool designed to help manage a classroom of kids programming! You can create your own classes, lesson plans and follow how kids are doing. diff --git a/content/pages/pt_BR.yaml b/content/pages/pt_BR.yaml index f4d9c9c78d5..98256cdd1a1 100644 --- a/content/pages/pt_BR.yaml +++ b/content/pages/pt_BR.yaml @@ -82,7 +82,7 @@ start-sections: text: |- Bem-vindo(a) à Hedy, estamos felizes em ajudá-lo(a) a começar com a Hedy. - Nosso [Manual do Professor](http://localhost:8080/for-teachers/manual) tem uma visão geral de todos os recursos em detalhes, mas esta página tem uma breve visão geral para que você saiba o que é antes de começar. + Nosso [Manual do Professor](https://www.hedy.org/for-teachers/manual) tem uma visão geral de todos os recursos em detalhes, mas esta página tem uma breve visão geral para que você saiba o que é antes de começar. Alguns destaques importantes de se saber: * Hedy é uma ferramenta desenvolvida para ajudar a gerenciar uma sala de aula de programação infantil! Você pode criar suas próprias aulas, planos de aula e acompanhar o desempenho das crianças. diff --git a/content/pages/pt_PT.yaml b/content/pages/pt_PT.yaml index f40c17c558d..d09079f2993 100644 --- a/content/pages/pt_PT.yaml +++ b/content/pages/pt_PT.yaml @@ -91,7 +91,7 @@ start-sections: text: 'Bem-vindo à Hedy, teremos todo o gosto em ajudá-lo a começar a utilizar a Hedy. - O nosso [Manual do Professor](http://localhost:8080/for-teachers/manual) tem uma visão geral de todas as funcionalidades em pormenor, mas esta página tem uma breve visão geral para que saiba o que é o quê antes de começar. + O nosso [Manual do Professor](https://www.hedy.org/for-teachers/manual) tem uma visão geral de todas as funcionalidades em pormenor, mas esta página tem uma breve visão geral para que saiba o que é o quê antes de começar. Alguns destaques que são importantes conhecer: diff --git a/content/pages/ru.yaml b/content/pages/ru.yaml index 58f4151fda9..c11cfd8a128 100644 --- a/content/pages/ru.yaml +++ b/content/pages/ru.yaml @@ -36,8 +36,8 @@ join-sections: text: "# Есть три способа поддержать Hedy!" - title: Улучшение языка text: |- - The gradual and multi-lingual nature of Hedy create a lot of interesting technical challenges. - Find those issues on [Github](https://github.com/hedyorg/hedy/issues?q=is%3Aopen+is%3Aissue+label%3Alanguage). + Постепенная и многоязычная природа Hedy создает множество интересных технических задач. + Их можно найти на [Github](https://github.com/hedyorg/hedy/issues?q=is%3Aopen+is%3Aissue+label%3Alanguage). - title: Перевод Hedy text: |- Не программист? Нет проблем! Еще один способ поддержать Hedy - это перевод ключевых слов, сообщений об ошибках, приключений и прочего контента. @@ -46,14 +46,16 @@ join-sections: Translation status - title: Помочь учителям начать работу text: |- - Hedy is designed to support teachers in providing programming lessons in class. We have specific teacher features like the option to create a class, customize it and see how your students are doing. - If you like Hedy, you can reach out to schools that you know to help teachers get started! We can help you find schools or teachers via [Discord](https://discord.gg/8yY7dEme9r). + Hedy предназначен для поддержки учителей при проведении уроков программирования в классе. У нас есть специальные функции для учителей, например, возможность создать класс, настроить его и посмотреть, что делают ваши ученики. + Если вам нравится Hedy, вы можете обратиться в школы, которые вы знаете, чтобы помочь учителям начать работу! Мы можем помочь вам найти школы или учителей через [Discord](https://discord.gg/8yY7dEme9r). learn-more-sections: - title: Присоединяйтесь к сообществу Hedy text: |- - Дайте нам знать! + Мы любим получать от вас новости! Лучший способ связаться с нами — это присоединиться к нашему серверу в Discord - [Нажмите сюда, чтобы написать нам](mailto:hello@hedy.org "About Hedy") + Вы также можете [отправить нам электронное письмо](mailto:hello@hedy.org «О Хеди»). + + Чтобы быть в курсе последних новостей, [подпишитесь на нашу рассылку](/subscribe). - title: Глубокое погружение! text: |- Хотите узнать больше о философии и дизайне Hedy? Посмотрите выступление Фелиенн на конференции StrangeLoop в 2022 году: @@ -84,47 +86,40 @@ learn-more-sections: * [AG Connect (Dutch), April 2020](https://www.agconnect.nl/artikel/stapsgewijs-python-leren-programmeren-met-nieuwe-taal-hedy) start-sections: - title: Начать с Hedy - text: "*Something about teachers accounts, slides etc*" + text: "Добро пожаловать в Hedy, мы рады помочь вам начать работу с Hedy.\n\nНаш [Учительский справочник](https://www.hedy.org/for-teachers/manual) содержит подробный обзор всех функций, а эта страница предлагает краткий обзор, чтобы вы знали, что к чему, прежде чем углубиться в изучение.\n\nНесколько важных моментов, которые стоит знать: \n* Hedy — это инструмент, созданный для управления классом детей, занимающихся программированием! Вы можете создавать свои собственные классы, планы уроков и следить за успехами детей. Вам не нужно знать много программирования, если вы только начинаете, Хеди работает шаг за шагом, так же как и для вас!\n* Вы можете использовать Hedy на своем родном языке, потому что он был переведен на многие другие языки!\n* Программировать может каждый ребёнок!! Hedy особенно полезна для детей с проблемами зрения, потому что Hedy может читать материалы вслух, без неободимости использовать мышь. Мы готовы вам помочь, и вы можете найти нас, например, на [Discord](https://discord.gg/8yY7dEme9r) или написать нам на [email](hello@hedy.org)." - title: Учителя о Hedy text: |- - A while ago we ran a few short Hedy teachers surveys. - The questions span between suggestions of improvement and Hedy’s best features. - Below is a testimony of their thoughts: + Разные учителя по всему миру выразили свою страсть к Хеди, как некоторые из них поделились с нами: + + *Невероятно вдохновляюще! Отличный способ сделать программирование гораздо более доступным как для себя, так и для студентов. Очень весело играть и много потенциала для использования с учениками. Я думаю, что это очень хороший инструмент! Я считаю, что это ценный способ для детей начать изучать программирование. Программирование и Python всегда были очень увлекательными, потому что барьер для обучения очень высок. Теперь всё немного проще - Hedy показала, что на самом деле это может быть совсем не сложно. Мне понравилось видеть, как Hedy делает программирование максимально доступным для пользователей!* + Нидерланды: Учителя математики на подготовке (secondary school) + + *Простой интерфейс и хорошие примеры.* Учитель: 3-6 классы (elementary) + + *Многоязычное программирование и сам концепт постепенного программирования.* США: средняя школа, 6-8 классы - Simple interface and good examples. *Teacher: 3rd - 6th grades (elementary)* + *Постепенное введение в программирование.* Австралия: старшая школа - Multilingual programming and just the gradual programming concept itself. - *US: middle school, 6th-8th grade* + *Не хочется останавливаться.* Нидерланды: 2 HAVO-VWO - The gradual nature of introducing programming. *Australia: High school* + *И то, что объяснение может быть на голландском языке (а код на английском), и то, что появляется все больше и больше возможностей.* Нидерланды: группа класса Plus - The construction is so good. *Netherlands: Lower secondary school HAVO-VWO* + Но Hedy и его уровни... какая идея! Я хотел бы лично поблагодарить вас за создание этого, даже трудно выразить благодарность в полной мере. Я никогда не видел такого интереса и энтузиазма у своих студентов, как при работе с Hedy. Мы прошли до пятого уровня и планируем заниматься так еще одну неделю, прежде чем начать изучение Python.* Пакистан - I can keep the pace of the class. *Netherlands: group 7 en 8* + *«Реальность» программирования напоминает то, как это происходит на самом деле.* Нидерланды: Плюс-класс группы 4-8 - Continues automatically. *Netherlands: 2 HAVO-VWO* + *Пошаговые действия. Весёлые занятия.* Нидерланды: Все уровни, 2e VWO/HAVO 2e VWO +, 3e HAVO 3e VWO - Both that the explanation can be in Dutch (and the code in English), and that it builds up with more - and more possibilities. *Netherlands: Plus class group 7* + Мне очень нравится Hedy, и она также хорошо организована, так что её удобно использовать в начальной школе. Плавное сложнение уровней в Hedy работает прекрасно. Лаконичное объяснение в начале каждого уровня и маленькие программы в качестве примера помогают детям быстро понять, что нового в выбранном уровне. Разнообразние заданий, которые дети могут выбирать - тоже хорошая идея. Дети сами выбирают задания, которые им интересны, и затем начинают с ними работать, проходя уровни. Hedy — это отличное развлечение для детей, которые хорошо разбираются в программировании и хотят попробовать себя в настоящем языке программирования. Это хорошая подготовка к средней школе, как только там начнут больше уделять внимания ИКТ-образованию. Нидерланды: Монтессори школа в Оегстгейсте - The 'realness' of programming, it resembles how it is in reality. *Netherlands: Plus class group 4 to 8* + *Отличная структура.* Нидерланды: Младшая средняя школа HAVO-VWO - Step-by-step activities. Fun activities. *Netherlands: 1e All levels, 2e VWO/HAVO 2e VWO +, 3e HAVO 3e VWO* + *Я могу удерживать темп занятия.* Нидерланды: группа 7 и 8 - But Hedy and its gradual levels... what an idea, - I wanted to personally thank you for creating this. I cannot thank you enough. Also, I have never seen the level of engagement and enthusiasm of my - students, as I have seen with Hedy. We have covered till level 5, and plan to spend one more week on it in classes and labs, - before starting Python. *Pakistan* + ![Фелиен обучает детей](/images/teacherfeedback/Fkids1.JPG) *Фелиен обучает детей* - I really like Hedy very much and it is also nicely set up, which makes it good to use in primary school. - Hedy's gradual approach works very well. - The short explanation at the beginning of each level and the short example programs help to give the children a quick insight into what is new in the chosen level. - The different assignments that the children can choose also work very well. - You see the children choose assignments that appeal to them and they then get to work with them, - through the levels. Hedy is great fun for children who are good at programming and want to get a - taste of a real programming language. It is good preparation for secondary school as soon as more ICT - education is given there. *Netherlands: Oegstgeest Montessori school* - + ![Дети узнают о Hedy](/images/teacherfeedback/Fkids2.JPG) *Дети узнают о Hedy* teacher-guide: - title: Введение key: интро @@ -143,7 +138,7 @@ teacher-guide: Ученикам (и учителям!) не нужен опыт программирования перед началом работы с Hedy. - title: Как работает Hedy? text: |- - Хеди разделена на уровни, в которых изучаются новые команды. Каждый уровень содержит множество приключений, в которых можно отработать только что выученные команды. + Hedy разделена на уровни, в которых изучаются новые команды. Каждый уровень содержит множество приключений, в которых можно отработать только что выученные команды. Как учитель, вы сами решаете, какие приключения будут доступны вашим ученикам. Будут ли они на этом уровне делать ресторан, калькулятор или дом с привидениями? Внутри каждого уровня приключения расположены от самого простого к самому сложному. Таким образом, ваши ученики постоянно сталкиваются с трудностями. Приключения могут выполняться учениками индивидуально, или вы можете использовать их в классическом обучении. @@ -175,27 +170,27 @@ teacher-guide: subsections: - title: Туториал text: Вы хотите пройти туториал (еще раз)? Нажмите здесь. -- title: Teaching preparations - key: preparations +- title: Подготовка преподавания + key: приготовления subsections: - title: Для учителей - text: You can prepare your classes at the For Teachers page. On this page you'll find everything you'll need to teach with Hedy, like your classes, your adventures and slides. All the functionalities of the for teachers page are explained below. - - title: Creating a Class + text: Вы можете подготовить свои занятия на Странице для учителей. На этой странице вы найдете все, что вам нужно для преподавания с Hedy, например ваши классы, приключения и слайды. Все функции страницы для учителей объяснены ниже. + - title: Создание класса text: |- Как учитель, вы можете создать класс для своих учеников. В этом классе вы можете видеть учетные записи учеников и их программы, а также следить за их успехами. В этом видео показано, как быстро создать класс в Hedy. - - title: Duplicate a class + - title: Дублировать класс text: |- - Are you teaching multiple classes? Then you don't have to customize each class individually. Simply make a class, costumize the class (see "Customize your Class" to learn how) and then duplicate this class as many times as you want. - You can duplicate the class on the 'For Teachers' page. If you duplicate a class, all the class settings are duplicated as well. This means that all the levels and adventures you've mande unavailable for the first class will now be unavailable for the new class(es) as well. - The student accounts and second teacher accounts in your class will not be duplicated into the new class. - - title: Add a second teacher + Ведете несколько классов? В таком случае не обязательно настраивать каждый отдельно. Просто создайте класс, настройте его (посмотрите "Настройка вашего класса", чтобы узнать как) и затем дублируйте этот класс столько раз, сколько захотите. + Вы можете дублировать класс на странице «Для учителей». Если вы дублируете класс, все настройки класса также дублируются. Это означает, что все уровни и приключения, которые вы сделали недоступными для первого класса, теперь также будут недоступны для нового класса(ов). + Учетные записи студентов и учетные записи второго учителя в вашем классе не будут дублироваться в новом классе. + - title: Добавить второго учителя text: |- - Are you not the only teacher that teaches your class? Then you can now add another teacher to the class. Go to the 'For teachers' page and click on the class. Then choose 'Invite a teacher' and fill in the username of your colleague. - Your colleague will get an invitation on their account to join your class. They can see that invitation message by clicking on their username in the upper right corner of the screen and selecting 'My account'. - Once the other teacher accepts the invitation they can customize the class as well. - To remove a second teacher from your class, go to the class page and remove the second teacher. The teacher who's created the class cannot be removed. - - title: Customize your Class + Вы не единственный учитель в классе? Тогда вы можете добавить еще одного учителя в класс. Перейдите на страницу «Для учителей» и нажмите на класс. Затем выберите «Пригласить учителя» и введите имя пользователя вашего коллеги. + Ваш коллега получит приглашение на свой аккаунт присоединиться к вашему классу. Увидеть это приглашение можно, кликнув на свое имя пользователя в правом верхнем углу экрана и выбрав 'Мой аккаунт'. + Приняв приглашение, второй учитель также сможет настраивать класс. + Чтобы удалить второго учителя из вашего класса, перейдите на страницу класса и удалите второго учителя. Учителя, который создал класс, нельзя удалить. + - title: Настроить класс text: |- You can customize your class and choose which adventures are available for your students. This way your students won't be overwhelmed by the amount of adventures and levels, and they can specifically focus on the adventures you'd like them to practice with. Click on your class on the for teachers page and choose 'customize class'. On this page you can select levels, set opening dates, unlock level thresholds and more. @@ -229,7 +224,7 @@ teacher-guide: **Save** Don't forget to save your changes when you're done customizing your class. - - title: Student Accounts + - title: Аккаунты учеников text: |- To add students to your class go to the class page by clicking in the class name on the 'for teachers' page. Then click 'add students'. There are 2 ways to let your students join your class: You can create accounts for them, or they could create their own accounts. @@ -242,22 +237,22 @@ teacher-guide: Your students can also go to the Hedy website and create their own accounts, just like you did. To get them into your class, they simply have to click the invite link. You can find the invite link on the class page and send it to your students. Mind that your students have to be logged in to Hedy when they click the link, in order to make it work smoothly. You can also manually invite a student to your class with the button 'Invite by username'. - - title: Setting preferred language + - title: Установка предпочитаемого языка text: |- - When students create profiles they are supposed to choose a 'preferred language'. Hedy will always be loaded in this selected language. - Changing this language can always be done later on by navigating to 'My account' and 'My personal settings' again. + Когда ученики создают профили, они должны выбрать «предпочитаемый язык». Hedy всегда будет загружаться на этом языке. + Изменить язык можно в любой момент перейдя в «Мой аккаунт» и «Мои личные настройки» снова. - **For non-English speakers** - Not only can you change the language of the adventures to your own language. You can also choose which language the keywords (for example 'print' or 'ask') should be in. - This way you can teach your students to code with English keywords, but you can also let them program in their own language. For example, Dutch students can use the command 'vraag' instead of 'ask'. - If a student wants to switch languages, they can click the keyword switcher. It will switch the keywords from English to the preferred language and back. - Fun fact! Students are allowed program in both English and their own language at the same time! So, if they have trouble remembering some keywords in English, but easily remember other ones they can use both at the same time. + **Для неанглоговорящих** + Вы можете не только изменить язык приключений на свой родной, но также вы можете выбрать, на каком языке должны быть ключевые слова (например, 'печать' или 'спросить'). + Таким образом, вы можете научить своих учеников программировать с использованием английских ключевых слов или на их родном языке. Например, голландские студенты могут использовать команду 'vraag' вместо 'ask'. + Если ученик хочет переключить язык, он может нажать на переключатель, который будет переключать ключевые слова с английского на предпочитаемый язык и обратно. + Забавный факт! Студенты могут программировать как на английском, так и на своём родном языке одновременно! Итак, если у них возникают трудности с запоминанием некоторых ключевых слов на английском, но они легко запоминают другие, они могут использовать оба языка одновременно. - **Video** - This [video](https://www.youtube.com/watch?v=QrVZETj4oLM) show you how to set a preferred language and change the keywords to you preferred language as well. - - title: Storing programs + **Видео** + Это [видео](https://www.youtube.com/watch?v=QrVZETj4oLM) показывает, как установить предпочитаемый язык и изменить ключевые слова на предпочитаемый язык. + - title: Хранение программ text: |- When you are logged in, you'll see My programs next to your profile icon. This option exists for your students too. In My programs you can find all the programs that you've worked on. @@ -424,7 +419,7 @@ teacher-guide: error_text: For example they type a sentence without using print. error_code: Hedy не может напечатать это solution_text: Teach your students to always start a line of code with a command. - solution_code: напечатать Хеди может напечатать это! + solution_code: '{print} Hedy может это напечатать!' - title: Студенты используют заглавные буквы при наборе команд example: error_text: Commands won't work if they are in capitals. @@ -438,7 +433,7 @@ teacher-guide: - title: Студенты используют эхо без вопроса example: error_text: Echo is made to repeat an answer after an ask command. Without ask echo won't do anything. - error_code: эхо Ваше имя + error_code: '{echo} Ваше имя -' solution_text: Add an ask command to make it work. solution_code: |- {ask} What's your name? @@ -457,12 +452,12 @@ teacher-guide: example: error_text: Often students love to try out big numbers when using the turtle, which causes the arrow to walk off the screen. error_code: |- - вперед 300 - поворот 90 - solution_text: In the example. students tend to think that the turn command doesn't work. Eventhough is does work, but you can't see it happening off screen. Use smaller numbers to prevent this from happening. + {forward} 300 + {turn} 90 + solution_text: В этом примере ученики часто думают, что команда поворота не сработала, хотя на самом деле она выполнила то, что должна была. Что произошло, так это то, что черепаха вышла за пределы экрана. Используйте меньшие числа, чтобы это избежать. solution_code: |- - вперед 100 - поворот 90 + {forward} 100 + {turn} 90 - title: "Turtle: Students use the command backward, but that doesn't exist" example: error_text: Назад - это не команда. diff --git a/content/pages/sl.yaml b/content/pages/sl.yaml index e1bebfa608e..ece4fba5307 100644 --- a/content/pages/sl.yaml +++ b/content/pages/sl.yaml @@ -34,7 +34,7 @@ learn-more-sections: text: "Some websites and newspapers have written about Hedy since our release in early 2020. We keep a list here:\n* [Java Magazine 04.2023](images/Hedy_Javamagazine2023.pdf)\n* [Tech Optimism - A Solution to the IT Shortage (Dutch), August 2022](https://pom.show/2022/08/12/een-oplossing-voor-het-it-tekort/)\n* [Codeweek Podcast, July 2022](https://codeweek.eu/podcast/26)\n* [Heise.de (German), Januari 2022](https://www.heise.de/news/Hedy-die-mitwachsende-Programmiersprache-6336264.html)\n* [Strumenta, November 2021](https://tomassetti.me/teaching-programming-with-hedy/)\n* [Vives (Dutch), CodeWeek Special October 2021](images/Vives-174-Codeweek.pdf)\n* [CodeWeek.eu - Haunted House Challenge, September 2021](https://codeweek.eu/2021/challenges/haunted-house)\n* [Opensource.com, April 2021](https://opensource.com/article/21/4/hedy-teach-code)\n* [IO Magazine, April 2021](https://ict-research.nl/wordpress/wp-content/uploads/2021/04/IO-magazine-NR1-2021_web.pdf)\n* [Ingeniería De Software (Spanish), February 2021](https://ingenieriadesoftware.es/hedy-mejor-lenguaje-ensenar-programacion-ninos/)\n* [Hello World Magazine, February 2021](images/Hello_World_15_Hedy.pdf)\n* [Discoro, January 2021](https://discoro.wordpress.com/2021/01/09/hedy-gradually-learning-a-programming-language/)\n* [Felienne wins the Dutch award for ICT research for Hedy, January 2021](https://www.nwo.nl/en/news/felienne-hermans-receives-dutch-prize-ict-research-2021)\n* [SlashDot, August 2020](https://news.slashdot.org/story/20/08/17/024248/scientist-proposes-a-new-programming-language-for-teaching-coding-and-python)\n* [GenBeta (Spanish), August 2020](https://www.genbeta.com/desarrollo/nuevo-lenguaje-para-ensenar-programacion-a-ninos-como-se-ensena-a-leer-escribir-forma-gradual-niveles)\n* [Developpez (French), August 2020](https://programmation.developpez.com/actu/308095/Une-scientifique-propose-un-nouveau-langage-de-programmation-pour-enseigner-aux-enfants-le-codage-informatique-au-travers-d-une-approche-graduelle-implementee-en-Python-sur-13-paliers/)\n* [Vives (Dutch), October 2020](images/artikel_vives.pdf) \"Met Hedy stap voor stap leren programmeren\"\n* [Leiden University, April 2020](https://www.universiteitleiden.nl/en/news/2020/03/looking-to-distract-the-kids-while-you-work-from-home-get-them-programming)\n* [Mare (Dutch), April 2020](https://www.mareonline.nl/cultuur/computercode-voor-de-kids/)\n* [AG Connect (Dutch), April 2020](https://www.agconnect.nl/artikel/stapsgewijs-python-leren-programmeren-met-nieuwe-taal-hedy)" start-sections: - title: Getting started with Hedy - text: "Welcome to Hedy, we are happy to help you get started with Hedy.\n\nOur [Teacher Manual](http://localhost:8080/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in.\n\nA few highlights that are important to know:\n* Hedy is a tool designed to help manage a classroom of kids programming! You can create your own classes, lesson plans and follow how kids are doing.\n* You do not need to know a lot of programming if you begin, Hedy works step by step, also for you!\n* You can use Hedy in your native tongue because it has been translated into many other languages!\n* Every kid can programme!! Hedy is especially helpful for kids who have vision problems because it can read material aloud to you without the need for a mouse.\n* We are here to help, you can find us for example on [Discord](https://discord.gg/8yY7dEme9r) or you can [email-us](hello@hedy.org)." + text: "Welcome to Hedy, we are happy to help you get started with Hedy.\n\nOur [Teacher Manual](https://www.hedy.org/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in.\n\nA few highlights that are important to know:\n* Hedy is a tool designed to help manage a classroom of kids programming! You can create your own classes, lesson plans and follow how kids are doing.\n* You do not need to know a lot of programming if you begin, Hedy works step by step, also for you!\n* You can use Hedy in your native tongue because it has been translated into many other languages!\n* Every kid can programme!! Hedy is especially helpful for kids who have vision problems because it can read material aloud to you without the need for a mouse.\n* We are here to help, you can find us for example on [Discord](https://discord.gg/8yY7dEme9r) or you can [email-us](hello@hedy.org)." - title: Teachers about Hedy text: "Various teachers worldwide have expressed their passion for Hedy, as some have shared with us:\n\n*Incredibly inspiring! Super good way to make programming a lot more accessible for yourself, but also for students. Very fun to play with and a lot of potential to use with the students. I think it is a very nice tool! I believe this is a valuable way for children to start learning programming. Python and coding have always been very exciting, because the barrier to learning is very high. Now everything is a bit lower and it was explained that it can actually be very easy. I enjoyed seeing how Hedy tries to make programming as accessible as possible for users!*\nNetherlands: Mathematics teachers in training (secondary school)\n\n*Simple interface and good examples.* Teacher: 3rd - 6th grades (elementary)\n\n*Multilingual programming and just the gradual programming concept itself.* US: middle school, 6th-8th grade\n\n*The gradual nature of introducing programming.* Australia: High school\n\n*Continues automatically.* Netherlands: 2 HAVO-VWO\n\n*Both that the explanation can be in Dutch (and the code in English), and that it builds up with more and more possibilities.* Netherlands: Plus class group\n\n*But Hedy and its gradual levels...what an idea, I wanted to personally thank you for creating this. I cannot thank you enough. Also, I have never seen the level of engagement and enthusiasm of my students, as I have seen with Hedy. We have covered till level 5, and plan to spend one more week on it in classes and labs, before starting Python.* Pakistan\n\n*The 'realness' of programming, it resembles how it is in reality.* Netherlands: Plus class group 4 to 8\n\n*Step-by-step activities. Fun activities.* Netherlands: 1e All levels, 2e VWO/HAVO 2e VWO +, 3e HAVO 3e VWO\n\n*I really like Hedy very much and it is also nicely set up, which makes it good to use in primary school. Hedy's gradual approach works very well. The short explanation at the beginning of each level and the short example programs help to give the children a quick insight into what is new in the chosen level. The different assignments that the children can choose also work very well. You see the children choose assignments that appeal to them and they then get to work with them, through the levels. Hedy is great fun for children who are good at programming and want to get a taste of a real programming language. It is good preparation for secondary school as soon as more ICT education is given there.* Netherlands: Oegstgeest Montessori school\n\n*The construction is so good.* Netherlands: Lower secondary school HAVO-VWO\n\n*I can keep the pace of the class.* Netherlands: group 7 en 8\n\n![Felienne teaching kids](/images/teacherfeedback/Fkids1.JPG) *Felienne teaching kids*\n\n\n![Kids learning about Hedy](/images/teacherfeedback/Fkids2.JPG) *Kids learning about Hedy*" teacher-guide: diff --git a/content/pages/sr.yaml b/content/pages/sr.yaml index f0e23669f98..ec76fe949ca 100644 --- a/content/pages/sr.yaml +++ b/content/pages/sr.yaml @@ -1,523 +1,541 @@ -title: Hedy documentation +title: Hedy документација home-sections: -- title: Textual programming made easy! +- title: Текстуално програмирање учињено лаким! text: |- - Many schools and teachers around the world want to teach their students programming. Initially this is often done with playful tools, ranging from the Beebot robot to - Scratch Junior or Scratch. After using such tools, kids often want to move to more powerful, textual programming languages, like Python. + Многе школе и наставници широм света желе да науче своје ученике програмирању. У почетку се то често ради са разиграним алатима, од робота Beebot до Scratch Junior или Scratch. Након коришћења таквих алата, деца често желе да пређу на моћније, текстуалне програмске језике, као што је Python. - Python however is hard, because it is only available in English, and requires learners to learn complex programming concepts and syntax at once. - Hedy is the easy way to get started with textual programming languages! Hedy is free to use, open source, and unlike any other textual programming language in three ways. + Међутим, Python је тежак, јер је доступан само на енглеском и захтева од ученика да истовремено науче сложене програмске концепте и синтаксу. + Hedy је лак начин да започнете са текстуалним програмским језицима! Hedy је бесплатан за коришћење, отвореног кода, и за разлику од било ког другог текстуалног програмског језика у три начина. - 1. Hedy is multi-lingual, you can use Hedy in your own language - 2. Hedy is gradual, so you can learn one concept and its syntax a time - 3. Hedy is built for the classroom, allowing teachers to fully customize their student's experience -- title: Multi-lingual programming - text: While almost all textual programming language have keywords in English, such as `for` or `repeat`, Hedy can be used in any language! We currently support 39 different languages, including Spanish, Arabic, Simplified Chinese and Hindi. If your language is not available you can always start a new translation. -- title: Step by step learning - text: Learning a programming language can be overwhelming, since learners have to learn concepts (for example if-else or loops) and syntax (like quotation marks or round brackets) at the same time. In Hedy, concepts are first introduced with little syntax and then refined. A scientifically proven way to learn! -- title: Built for the classroom + 1. Hedy је вишејезичан, можете користити Hedy на свом језику + 2. Hedy је постепен, тако да можете научити један концепт и његову синтаксу у једном тренутку + 3. Hedy је направљен за учионицу, омогућавајући наставницима да у потпуности прилагоде искуство својих ученика +- title: Вишејезично програмирање + text: Док скоро сви текстуални програмски језици имају кључне речи на енглеском, као што су `for` или `repeat`, Hedy се може користити на било ком језику! Тренутно подржавамо 47 различитих језика, укључујући холандски, шпански, арапски, турски, кинески и хинди. Ако ваш језик није доступан, увек можете започети нови превод. +- title: Учење корак по корак + text: Учење програмског језика може бити преоптерећујуће, јер ученици морају истовремено да уче концепте (на пример if-else или петље) и синтаксу (као што су наводници или округле заграде). У Хедију, концепти се прво уводе са мало синтаксе, а затим се усавршавају. Научно доказан начин учења! +- title: Направљено за учионицу text: |- - Hedy is suitable for kids aged 10 and up and designed for classroom use. - Teachers can use our free, built-in lesson plans, but can also author their own lessons and load these into the Hedy user interface. -- title: Programming in context - text: Hedy shows programming in the broadest way possible, and can be used in variety of exciting ways. Hedy allows for the creation of digital and interactive stories, colorful drawings that can be shown on the screen but also drawn with a pen plotter or embroidered on a shirt, and can be used to create games or apps with buttons and keyboard actions. -- title: Is Hedy free? + Хеди је погодан за децу узраста од 10 година и више и дизајниран је за употребу у учионици. + Наставници могу користити наше бесплатне, уграђене планове лекција, али могу и сами креирати своје лекције и учитати их у кориснички интерфејс Хедија. +- title: Програмирање у контексту + text: Хеди приказује програмирање на најширем могућем начину и може се користити на различите узбудљиве начине. Хеди омогућава креирање дигиталних и интерактивних прича, шарених цртежа који се могу приказати на екрану, али и нацртати помоћу пен плотера или извезати на мајици, и може се користити за креирање игара или апликација са дугмадима и акцијама на тастатури. +- title: Да ли је Хеди бесплатан? text: |- - Yes! Hedy is 'Open source', which means that everyone can help us make Hedy better. - You can find our code on [GitHub](https://github.com/hedyorg/hedy). - If you like Hedy and want to contribute, we accept (and are very grateful for) [donations](https://github.com/sponsors/hedyorg)! -- title: Do I need to install anything? - text: No. Hedy works in the browser, which is the program you are using to look at this page. Probably Chrome or Edge or Firefox. Hedy also works on phones and tablets. -- title: Do I need programming experience to teach with Hedy? + Да! Хеди је 'отвореног кода', што значи да свако може помоћи да Хеди буде бољи. + Наш код можете пронаћи на Github. + Ако вам се свиђа Хеди и желите да допринесете, прихватамо (и веома смо захвални за) донације! +- title: Да ли треба да инсталирам нешто? + text: Не. Хеди ради у прегледачу, што је програм који користите за гледање ове странице. Вероватно Chrome или Edge или Firefox. Хеди такође ради на телефонима и таблетима. +- title: Да ли ми је потребно програмерско искуство да бих предавао са Хедијем? text: |- - No, that is not needed. All concepts are explained in the slides and in the interface for learners. - If you create a free teacher's account, you also get access to the teacher's manual with information on how to teach - and frequently made mistakes. + Не, то није потребно. Сви концепти су објашњени у слајдовима и у интерфејсу за ученике. + Ако направите бесплатан налог за наставнике, добијате и приступ приручнику за наставнике са информацијама о томе како предавати + и честим грешкама. join-sections: -- title: Supporting Hedy - text: '# There are three ways in which you can support Hedy!' -- title: Побољшање језика +- title: Подршка за Hedy + text: '# Постоје три начина на која можете подржати Hedy!' +- title: Унапређење језика text: |- - The gradual and multi-lingual nature of Hedy create a lot of interesting technical challenges. - Find those issues on [Github](https://github.com/hedyorg/hedy/issues?q=is%3Aopen+is%3Aissue+label%3Alanguage). -- title: Превођење Hedy-а + Постепена и вишејезична природа Hedy-а ствара много занимљивих техничких изазова. + Пронађите те проблеме на Github-у. +- title: Превођење Хеди text: |- - Not a programmer? No problem! Another way to support Hedy is by [translating keywords, error messages, adventures are other content](https://github.com/hedyorg/hedy/wiki/Hedy-Translation-Tutorial) - - This is the current status, help us complete a language, or add a new one! + Нисте програмер? Нема проблема! Још један начин да подржите Hedy је превођење кључних речи, порука о грешкама, авантура и другог садржаја. + Ово је тренутни статус, помозите нам да завршимо језик или додамо нови! - Translation status -- title: Help teachers get started + Статус превода +- title: Помоћ наставницима да започну text: |- - Hedy is designed to support teachers in providing programming lessons in class. We have specific teacher features like the option to create a class, customize it and see how your students are doing. - If you like Hedy, you can reach out to schools that you know to help teachers get started! We can help you find schools or teachers via [Discord](https://discord.gg/8yY7dEme9r). + Hedy је дизајниран да подржи наставнике у пружању часова програмирања у учионици. Имамо специфичне функције за наставнике као што је опција за креирање разреда, прилагођавање и праћење напретка ученика. + Ако вам се свиђа Hedy, можете контактирати школе које познајете да помогнете наставницима да започну! Можемо вам помоћи да пронађете школе или наставнике преко Discord-а. learn-more-sections: -- title: Join the Hedy Community - text: "We love to hear from you! The best way to get in touch with us is by joining our [Discord server](https://discord.gg/8yY7dEme9r). \n\nYou can also [send us an email](mailto:hello@hedy.org \"About Hedy\")." -- title: A deep dive! +- title: Придружите се Hedy заједници + text: "Волимо да чујемо ваше мишљење! Најбољи начин да нас контактирате је придруживањем нашем Discord серверу.\n\nТакође нам можете [послати имејл](mailto:hello@hedy.org \"О Hedy\").\n\nДа бисте били у току са најновијим вестима, [претплатите се на наш билтен](/subscribe)." +- title: Дубинско истраживање! text: |- - Want to know more about Hedy's philosophy and design? Check out this talk Felienne gave at the StrangeLoop Conference in 2022: + Желите да сазнате више о Hedy филозофији и дизајну? Погледајте овај говор који је Felienne одржала на StrangeLoop конференцији 2022. године: -- title: Hedy in the news +- title: Hedy у вестима text: |- - Some websites and newspapers have written about Hedy since our release in early 2020. We keep a list here: - * [Tech Optimism - A Solution to the IT Shortage (Dutch), August 2022](https://pom.show/2022/08/12/een-oplossing-voor-het-it-tekort/) - * [Codeweek Podcast, July 2022](https://codeweek.eu/podcast/26) - * [Heise.de (German), Januari 2022](https://www.heise.de/news/Hedy-die-mitwachsende-Programmiersprache-6336264.html) - * [Strumenta, November 2021](https://tomassetti.me/teaching-programming-with-hedy/) - * [Vives (Dutch), CodeWeek Special October 2021](images/Vives-174-Codeweek.pdf) - * [CodeWeek.eu - Haunted House Challenge, September 2021](https://codeweek.eu/2021/challenges/haunted-house) - * [Opensource.com, April 2021](https://opensource.com/article/21/4/hedy-teach-code) - * [IO Magazine, April 2021](https://ict-research.nl/wordpress/wp-content/uploads/2021/04/IO-magazine-NR1-2021_web.pdf) - * [Ingeniería De Software (Spanish), February 2021](https://ingenieriadesoftware.es/hedy-mejor-lenguaje-ensenar-programacion-ninos/) - * [Hello World Magazine, February 2021](images/Hello_World_15_Hedy.pdf) - * [Discoro, January 2021](https://discoro.wordpress.com/2021/01/09/hedy-gradually-learning-a-programming-language/) - * [Felienne wins the Dutch award for ICT research for Hedy, January 2021](https://www.nwo.nl/en/news/felienne-hermans-receives-dutch-prize-ict-research-2021) - * [SlashDot, August 2020](https://news.slashdot.org/story/20/08/17/024248/scientist-proposes-a-new-programming-language-for-teaching-coding-and-python) - * [GenBeta (Spanish), August 2020](https://www.genbeta.com/desarrollo/nuevo-lenguaje-para-ensenar-programacion-a-ninos-como-se-ensena-a-leer-escribir-forma-gradual-niveles) - * [Developpez (French), August 2020](https://programmation.developpez.com/actu/308095/Une-scientifique-propose-un-nouveau-langage-de-programmation-pour-enseigner-aux-enfants-le-codage-informatique-au-travers-d-une-approche-graduelle-implementee-en-Python-sur-13-paliers/) - * [Vives (Dutch), October 2020](images/artikel_vives.pdf) "Met Hedy stap voor stap leren programmeren" - * [Leiden University, April 2020](https://www.universiteitleiden.nl/en/news/2020/03/looking-to-distract-the-kids-while-you-work-from-home-get-them-programming) - * [Mare (Dutch), April 2020](https://www.mareonline.nl/cultuur/computercode-voor-de-kids/) - * [AG Connect (Dutch), April 2020](https://www.agconnect.nl/artikel/stapsgewijs-python-leren-programmeren-met-nieuwe-taal-hedy) + Неке веб странице и новине су писале о Hedy од нашег издања почетком 2020. године. Овде водимо списак: + * [Java Magazine 04.2023](images/Hedy_Javamagazine2023.pdf) + * [Tech Optimism - Решение за недостатак ИТ стручњака (холандски), август 2022](https://pom.show/2022/08/12/een-oplossing-voor-het-it-tekort/) + * [Codeweek Podcast, јул 2022](https://codeweek.eu/podcast/26) + * [Heise.de (немачки), јануар 2022](https://www.heise.de/news/Hedy-die-mitwachsende-Programmiersprache-6336264.html) + * [Strumenta, новембар 2021](https://tomassetti.me/teaching-programming-with-hedy/) + * [Vives (холандски), CodeWeek Special октобар 2021](images/Vives-174-Codeweek.pdf) + * [CodeWeek.eu - Haunted House Challenge, септембар 2021](https://codeweek.eu/2021/challenges/haunted-house) + * [Opensource.com, април 2021](https://opensource.com/article/21/4/hedy-teach-code) + * [IO Magazine, април 2021](https://ict-research.nl/wordpress/wp-content/uploads/2021/04/IO-magazine-NR1-2021_web.pdf) + * [Ingeniería De Software (шпански), фебруар 2021](https://ingenieriadesoftware.es/hedy-mejor-lenguaje-ensenar-programacion-ninos/) + * [Hello World Magazine, фебруар 2021](images/Hello_World_15_Hedy.pdf) + * [Discoro, јануар 2021](https://discoro.wordpress.com/2021/01/09/hedy-gradually-learning-a-programming-language/) + * [Felienne осваја холандску награду за ИКТ истраживање за Hedy, јануар 2021](https://www.nwo.nl/en/news/felienne-hermans-receives-dutch-prize-ict-research-2021) + * [SlashDot, август 2020](https://news.slashdot.org/story/20/08/17/024248/scientist-proposes-a-new-programming-language-for-teaching-coding-and-python) + * [GenBeta (шпански), август 2020](https://www.genbeta.com/desarrollo/nuevo-lenguaje-para-ensenar-programacion-a-ninos-como-se-ensena-a-leer-escribir-forma-gradual-niveles) + * [Developpez (француски), август 2020](https://programmation.developpez.com/actu/308095/Une-scientifique-propose-un-nouveau-langage-de-programmation-pour-enseigner-aux-enfants-le-codage-informatique-au-travers-d-une-approche-graduelle-implementee-en-Python-sur-13-paliers/) + * [Vives (холандски), октобар 2020](images/artikel_vives.pdf) "Met Hedy stap voor stap leren programmeren" + * [Leiden University, април 2020](https://www.universiteitleiden.nl/en/news/2020/03/looking-to-distract-the-kids-while-you-work-from-home-get-them-programming) + * [Mare (холандски), април 2020](https://www.mareonline.nl/cultuur/computercode-voor-de-kids/) + * [AG Connect (холандски), април 2020](https://www.agconnect.nl/artikel/stapsgewijs-python-leren-programmeren-met-nieuwe-taal-hedy) start-sections: -- title: Getting started with Hedy - text: '*Something about teachers accounts, slides etc*' -- title: What other teachers say - text: "A while ago we ran a few short Hedy teachers surveys. \nThe questions span between suggestions of improvement and Hedy’s best features. \nBelow is a testimony of their thoughts:\n\nSimple interface and good examples. *Teacher: 3rd - 6th grades (elementary)*\n\nMultilingual programming and just the gradual programming concept itself. - *US: middle school, 6th-8th grade*\n\nThe gradual nature of introducing programming. *Australia: High school*\n\nThe construction is so good. *Netherlands: Lower secondary school HAVO-VWO*\n\nI can keep the pace of the class. *Netherlands: group 7 en 8* \n\nContinues automatically. *Netherlands: 2 HAVO-VWO*\n\nBoth that the explanation can be in Dutch (and the code in English), and that it builds up with more \nand more possibilities. *Netherlands: Plus class group 7*\n\nThe 'realness' of programming, it resembles how it is in reality. *Netherlands: Plus class group 4 to 8*\n\nStep-by-step activities. Fun activities. *Netherlands: 1e All levels, 2e VWO/HAVO 2e VWO +, 3e HAVO 3e VWO*\n\nBut Hedy and its gradual levels... what an idea, \nI wanted to personally thank you for creating this. I cannot thank you enough. Also, I have never seen the level of engagement and enthusiasm of my \nstudents, as I have seen with Hedy. We have covered till level 5, and plan to spend one more week on it in classes and labs, \nbefore starting Python. *Pakistan*\n\nI really like Hedy very much and it is also nicely set up, which makes it good to use in primary school. \nHedy's gradual approach works very well. \nThe short explanation at the beginning of each level and the short example programs help to give the children a quick insight into what is new in the chosen level. \nThe different assignments that the children can choose also work very well. \nYou see the children choose assignments that appeal to them and they then get to work with them, \nthrough the levels. Hedy is great fun for children who are good at programming and want to get a \ntaste of a real programming language. It is good preparation for secondary school as soon as more ICT \neducation is given there. *Netherlands: Oegstgeest Montessori school*\n\n" +- title: Почетак рада са Hedy + text: 'Добродошли у Hedy, драго нам је да вам помогнемо да започнете са Hedy. + + + Наш [Приручник за наставнике](https://www.hedy.org/for-teachers/manual) садржи детаљан преглед свих функција, али ова страница има кратак преглед како бисте знали шта је шта пре него што се упустите у рад. + + + Неколико важних истакнутих тачака: + + * Hedy је алат дизајниран да помогне у управљању учионицом деце која програмирају! Можете креирати своје часове, планове лекција и пратити како деца напредују. + + * Не морате знати много о програмирању ако тек почињете, Hedy ради корак по корак, и за вас! + + * Можете користити Hedy на свом матерњем језику јер је преведен на многе друге језике! + + * Свако дете може програмирати!! Hedy је посебно користан за децу која имају проблеме са видом јер може читати материјал наглас без потребе за мишем. + + * Овде смо да помогнемо, можете нас пронаћи на пример на [Discord-у](https://discord.gg/8yY7dEme9r) или нам можете [послати имејл](hello@hedy.org).' +- title: Наставници о Hedy + text: "Разни наставници широм света изразили су своју страст према Hedy, као што су неки поделили са нама:\n\n*Невероватно инспиративно! Супер добар начин да програмирање учините много приступачнијим за себе, али и за ученике. Веома забавно за играње и пуно потенцијала за коришћење са ученицима. Мислим да је ово веома леп алат! Верујем да је ово вредан начин за децу да почну учити програмирање. Python и кодирање су увек били веома узбудљиви, јер је баријера за учење веома висока. Сада је све мало ниже и објашњено је да може бити веома лако. Уживао сам гледајући како Hedy покушава да учини програмирање што приступачнијим за кориснике!*\nХоландија: Наставници математике у обуци (средња школа)\n\n*Једноставан интерфејс и добри примери.* Наставник: 3. - 6. разред (основна школа)\n\n*Вишејезично програмирање и сам концепт постепеног програмирања.* САД: средња школа, 6. - 8. разред\n\n*Постепена природа увођења програмирања.* Аустралија: средња школа\n\n*Аутоматски наставља.* Холандија: 2 HAVO-VWO\n\n*И то што објашњење може бити на холандском (а код на енглеском), и то што се гради са све више могућности.* Холандија: Плус група\n\n*Али Hedy и њени постепени нивои...какав идеја, желео сам лично да вам захвалим што сте ово створили. Не могу вам довољно захвалити. Такође, никада нисам видео ниво ангажовања и ентузијазма мојих ученика, као што сам видео са Hedy. Покрили смо до нивоа 5, и планирамо да проведемо још једну недељу на томе у часовима и лабораторијама, пре него што почнемо са Python-ом.* Пакистан\n\n*'Реалност' програмирања, подсећа на то како је у стварности.* Холандија: Плус група 4 до 8\n\n*Корак по корак активности. Забавне активности.* Холандија: 1е Сви нивои, 2е VWO/HAVO 2е VWO +, 3е HAVO 3е VWO\n\n*Веома ми се свиђа Hedy и такође је лепо постављен, што га чини добрим за коришћење у основној школи. Постепени приступ Hedy-а ради веома добро. Кратко објашњење на почетку сваког нивоа и кратки пример програми помажу да деца брзо схвате шта је ново у изабраном нивоу. Различити задаци које деца могу изабрати такође раде веома добро. Видите како деца бирају задатке који им се допадају и онда раде на њима, кроз нивое. Hedy је веома забаван за децу која су добра у програмирању и желе да окусе прави програмски језик. То је добра припрема за средњу школу чим се тамо почне давати више ИКТ образовања.* Холандија: Оегстгеест Монтесори школа\n\n*Конструкција је тако добра.* Холандија: Нижи разреди средње школе HAVO-VWO\n\n*Могу да пратим темпо разреда.* Холандија: група 7 и 8\n\n![Felienne учи децу](/images/teacherfeedback/Fkids1.JPG) *Felienne учи децу*\n\n\n![Деца уче о Hedy](/images/teacherfeedback/Fkids2.JPG) *Деца уче о Hedy*" teacher-guide: -- title: Introduction - key: intro +- title: Увод + key: увод subsections: - - title: What's Hedy? + - title: Шта је Хеди? text: |- - Hedy is a textual programming language, specifically developed for (pre-)teens (10 to 15 years old). - In contrast to programming languages for kids, like Scratch, Hedy doesn't use code blocks but textual code. - So with Hedy you'll learn how to type code like the real programmers do, but in small steps with playful exercises. - This way Hedy can function as a stepping stone to real programming languages like Python in an accessible and mostly fun way! - If you want to know more, you can watch this video about the development of Hedy as a programming language. - - title: Target audience + Хеди је текстуални програмски језик, посебно развијен за (пред)тинејџере (10 до 15 година). + За разлику од програмских језика за децу, као што је Scratch, Хеди не користи блокове кода већ текстуални код. + Тако ћете са Хедијем научити како да куцате код као прави програмери, али у малим корацима са разиграним вежбама. + На овај начин Хеди може функционисати као корак ка правим програмским језицима као што је Python на приступачан и углавном забаван начин! + Ако желите да сазнате више, можете погледати овај видео о развоју Хедија као програмског језика. + - title: Циљна публика text: |- - Hedy is developed with middle school and junior high school students in mind (ages 10 - 15). - It's important for the students to be able to read well. We recommend not to start with Hedy before the students have achieved at least a 3rd grade reading level. - Students (and teachers!) don't need any programming experience before starting with Hedy. - - title: How does Hedy work? + Хеди је развијен са ученицима основних и нижих средњих школа на уму (узраста 10 - 15 година). + Важно је да ученици могу добро да читају. Препоручујемо да не почињете са Хедијем пре него што ученици достигну најмање ниво читања трећег разреда. + Ученицима (и наставницима!) није потребно никакво програмерско искуство пре почетка рада са Хедијем. + - title: Како функционише Хеди? text: |- - Hedy is divided into levels, in which new commands are taught. Each level contains a variety of adventures to practice the newly learned commands. - As a teacher, you get to decide which adventures are available for your students. Will they be making a restaurant, a calculator or a haunted house this level? Within each level, the adventures are arranged from easiest to hardest. - So your students keep getting challenged. The adventures can be done by the students individually, or you can use them in a classical instruction. + Хеди је подељен на нивое, у којима се уче нове команде. Сваки ниво садржи разне авантуре за вежбање новоусвојених команди. + Као наставник, ви одлучујете које авантуре ће бити доступне вашим ученицима. Да ли ће правити ресторан, калкулатор или уклету кућу на овом нивоу? У оквиру сваког нивоа, авантуре су распоређене од најлакших до најтежих. + Тако ваши ученици стално добијају нове изазове. Авантуре могу радити појединачно или их можете користити у класичној настави. - The adventures also include a code example, to make sure the less digitally informed teachers are able to use Hedy too! - Of course Hedy also caters to the creative teachers that love to make their own lessonplans and adventures! + Авантуре такође укључују пример кода, како би се осигурало да и наставници са мање дигиталног искуства могу користити Хеди! + Наравно, Хеди је такође прилагођен креативним наставницима који воле да праве своје планове лекција и авантуре! - After programming all the adventures of a certain level, your students can test their knowledge in the quiz. - You can track your students' work and their progress on the class page. - - title: Devices + Након програмирања свих авантура одређеног нивоа, ваши ученици могу тестирати своје знање у квизу. + Можете пратити рад и напредак својих ученика на страници разреда. + - title: Уређаји text: |- - Hedy is web-based, which means it works on any device with a browser (Google Chrome, Firefox, Edge etc), so laptops, Chromebooks, tablets and even smartphones are suitable to use Hedy. - There's no need to download anything before working with Hedy, just go to the website and you're all set! - - title: The Hedy Community + Хеди је веб-базиран, што значи да ради на било ком уређају са прегледачем (Google Chrome, Firefox, Edge итд.), тако да су лаптопови, Chromebooks, таблети и чак паметни телефони погодни за коришћење Хедија. + Нема потребе да преузимате било шта пре рада са Хедијем, само идите на вебсајт и спремни сте! + - title: Хеди заједница text: |- - All Hedy teachers, programmers and other fans are welcome to join our [Discord server](https://discord.gg/8yY7dEme9r). This is the ideal place to chat about Hedy: we have channels where you can show your cool projects and lessons, channels to report bugs, and channels to chat with other teachers and with the Hedy team. - [Here](https://www.youtube.com/watch?v=Lyz_Lnd-_aI) you can find a video on how to join the Discord Community. - - title: Hedy and the GDPR + Сви наставници Хедија, програмери и други обожаваоци су добродошли да се придруже нашем Discord серверу. Ово је идеално место за разговор о Хедију: имамо канале где можете показати своје кул пројекте и лекције, канале за пријаву грешака и канале за ћаскање са другим наставницима и са Хеди тимом. + Овде можете пронаћи видео о томе како се придружити Discord заједници. + - title: Хеди и GDPR text: |- - Organizations in the EU have to comply with the GDPR (General Data Protection Regulation) when processing personal data. - Because this is a complex issue for many schools, you can use all Hedy programming functionalities without sharing personal data. - The easiest way to do this is to use Hedy without creating accounts for the teacher and students. Without accounts, all functionality is available, with the exception of personalizing levels, saving students' programs and viewing their progress. That is limiting, but there are schools that use Hedy in that way. - A second way is for a teacher to create an account with an email address without personal data, for example "docent25@email.com". Apart from an email address, which is only required to reset your password, you do not need to share any information when you create a teacher account. - With a teacher account, you can create anonymous accounts for students, e.g. rainbow-student1, rainbow-student2, etc (See 'Teaching preparations' for a detailed manual). This way you can use all functionality of Hedy, including saving progress, without sharing personal data of yourself or your students. - If the above is not sufficient for your context, we can sign a processing agreement for the processing of your personal data. -- title: Tutorial - key: tutorial + Организације у ЕУ морају да се придржавају GDPR (Општа уредба о заштити података) приликом обраде личних података. + Пошто је ово сложено питање за многе школе, можете користити све функције програмирања Хедија без дељења личних података. + Најлакши начин да то урадите је да користите Хеди без креирања налога за наставника и ученике. Без налога, све функције су доступне, осим персонализације нивоа, чувања програма ученика и прегледа њиховог напретка. То је ограничење, али постоје школе које користе Хеди на тај начин. + + Други начин је да наставник креира налог са имејл адресом без личних података, на пример "docent25@email.com". Поред имејл адресе, која је потребна само за ресетовање лозинке, не морате делити никакве информације када креирате налог наставника. + Са налогом наставника, можете креирати анонимне налоге за ученике, нпр. rainbow-student1, rainbow-student2, итд. (Погледајте 'Припреме за наставу' за детаљан приручник). На овај начин можете користити све функције Хедија, укључујући чување напретка, без дељења личних података о себи или својим ученицима. + + Ако горе наведено није довољно за ваш контекст, можемо потписати уговор о обради за обраду ваших личних података. +- title: Туторијал + key: туторијал subsections: - - title: Tutorial - text: Do you want to follow the tutorial (again)? Click [here](https://hedy.org/tutorial) -- title: Teaching preparations - key: preparations + - title: Туторијал + text: Желите ли да пратите туторијал (поново)? Кликните овде. +- title: Припреме за наставу + key: припреме subsections: - - title: For teachers - text: You can prepare your classes at the For Teachers page. On this page you'll find everything you'll need to teach with Hedy, like your classes, your adventures and slides. All the functionalities of the for teachers page are explained below. - - title: Creating a Class + - title: За наставнике + text: Можете припремити своје часове на страници за наставнике. На овој страници ћете пронаћи све што вам је потребно за предавање са Хедијем, као што су ваши часови, ваше авантуре и слајдови. Све функције странице за наставнике су објашњене у наставку. + - title: Креирање разреда text: |- - As a teacher, you can create a class for your students. In this class you can see the students' accounts and their programs and you could monitor their progress. - This video shows you how to quickly create a class in Hedy. - - title: Duplicate a class + Као наставник, можете креирати разред за своје ученике. У овом разреду можете видети налоге ученика и њихове програме и можете пратити њихов напредак. + Овај видео вам показује како брзо креирати разред у Хедију. + - title: Дуплирање разреда text: |- - Are you teaching multiple classes? Then you don't have to customize each class individually. Simply make a class, costumize the class (see "Customize your Class" to learn how) and then duplicate this class as many times as you want. - You can duplicate the class on the 'For Teachers' page. If you duplicate a class, all the class settings are duplicated as well. This means that all the levels and adventures you've mande unavailable for the first class will now be unavailable for the new class(es) as well. - The student accounts and second teacher accounts in your class will not be duplicated into the new class. - - title: Add a second teacher + Да ли предајете више разреда? Тада не морате прилагођавати сваки разред појединачно. Једноставно направите разред, прилагодите разред (погледајте "Прилагоди свој разред" да бисте сазнали како) и затим дуплирајте овај разред колико год пута желите. + Можете дуплирати разред на страници 'За наставнике'. Ако дуплирате разред, сва подешавања разреда ће бити дуплирана. То значи да ће сви нивои и авантуре које сте учинили недоступним за први разред сада бити недоступни и за нови разред(е). + Налози ученика и други наставнички налози у вашем разреду неће бити дуплирани у нови разред. + - title: Додавање другог наставника text: |- - Are you not the only teacher that teaches your class? Then you can now add another teacher to the class. Go to the 'For teachers' page and click on the class. Then choose 'Invite a teacher' and fill in the username of your colleague. - Your colleague will get an invitation on their account to join your class. They can see that invitation message by clicking on their username in the upper right corner of the screen and selecting 'My account'. - Once the other teacher accepts the invitation they can customize the class as well. - To remove a second teacher from your class, go to the class page and remove the second teacher. The teacher who's created the class cannot be removed. - - title: Customize your Class + Да ли нисте једини наставник који предаје ваш разред? Сада можете додати још једног наставника у разред. Идите на страницу 'За наставнике' и кликните на разред. Затим изаберите 'Позови наставника' и унесите корисничко име вашег колеге. + Ваш колега ће добити позив на свом налогу да се придружи вашем разреду. Они могу видети ту поруку позива кликом на своје корисничко име у горњем десном углу екрана и избором 'Мој налог'. + Када други наставник прихвати позив, такође може прилагодити разред. + Да бисте уклонили другог наставника из вашег разреда, идите на страницу разреда и уклоните другог наставника. Наставник који је креирао разред не може бити уклоњен. + - title: Прилагодите свој разред text: |- - You can customize your class and choose which adventures are available for your students. This way your students won't be overwhelmed by the amount of adventures and levels, and they can specifically focus on the adventures you'd like them to practice with. - Click on your class on the for teachers page and choose 'customize class'. On this page you can select levels, set opening dates, unlock level thresholds and more. + Можете прилагодити свој разред и изабрати које авантуре ће бити доступне вашим ученицима. На овај начин ваши ученици неће бити преоптерећени количином авантура и нивоа, и могу се специфично фокусирати на авантуре које желите да вежбају. + Кликните на свој разред на страници за наставнике и изаберите 'прилагоди разред'. На овој страници можете изабрати нивое, поставити датуме отварања, откључати прагове нивоа и још много тога. - **Select and order adventures** + **Изаберите и наручите авантуре** - In this section you can select and order adventures. The pink tabs are adventures with new commands. The gray tabs are regular adventures. To rearrange the order of the adventures, you can drag the tabs. However, we do advise you to use the regular order of adventures as the Hedy team made sure the adventures go from easiest to hardest. - If you want to remove an adventure for your students, simply click the cross on the adventure's tab. + У овом одељку можете изабрати и наручити авантуре. Розе табови су авантуре са новим командама. Сиви табови су обичне авантуре. Да бисте променили редослед авантура, можете превући табове. Међутим, саветујемо вам да користите редован редослед авантура јер је тим Хеди осигурао да авантуре иду од најлакших до најтежих. + Ако желите да уклоните авантуру за своје ученике, једноставно кликните на крст на табу авантуре. - If you want to add adventures, for instance your own adventure or an adventure you accidentally removed, use this menu to add the adventure to your students' adventures. Simply click the adventure you want to add and it (re)appears in the line of adventures. To undo all your changes to the adventures, click 'Reset'. + Ако желите да додате авантуре, на пример своју авантуру или авантуру коју сте случајно уклонили, користите овај мени да додате авантуру у авантуре ваших ученика. Једноставно кликните на авантуру коју желите да додате и она ће се (поново) појавити у линији авантура. Да бисте поништили све своје промене у авантурама, кликните 'Ресетуј'. - **Opening dates** + **Датуми отварања** - With this feature you can set opening dates for the levels. This way you can make a lesson plan before your course begins and not worry about opening new levels each week. In the image above the first level is opened directly, the second will open the 23th of september, and the 3rd level the week after. The other levels are closed. - Don't want to set opening dates? No problem, just leave this section blank. + Са овом функцијом можете поставити датуме отварања за нивое. На овај начин можете направити план лекција пре него што ваш курс почне и не бринути о отварању нових нивоа сваке недеље. На слици изнад први ниво је отворен директно, други ће се отворити 23. септембра, а трећи ниво недељу дана касније. Остали нивои су затворени. + Не желите да постављате датуме отварања? Нема проблема, само оставите овај одељак празан. - **Unlock level thresholds** + **Откључавање прага нивоа** - This featue allows you to set a threshold for your students' quiz grade, before they can continue to the next level. For example, if you enter "80" your students have to score at least 80% on the quiz before they are allowed to go to the next level. If they haven't met the threshold, they are not allowed to continue and have to retake the quiz. - Don't want to use the threshold? No worries, just keep this section blank. + Ова функција вам омогућава да поставите праг за оцену квиза ваших ученика пре него што могу наставити на следећи ниво. На пример, ако унесете "80", ваши ученици морају постићи најмање 80% на квизу пре него што им буде дозвољено да пређу на следећи ниво. Ако нису испунили праг, није им дозвољено да наставе и морају поново полагати квиз. + Не желите да користите праг? Нема бриге, само оставите овај одељак празан. - - **Other settings** + **Остала подешавања** - There are some other setting that could be usefu to you aswell. Our first extra setting is 'Mandatory developer's mode'. In developers mode the students only see their input and output screens and the run button. The adventures are hidden and there are no cheatsheets available. This might come in handy in a test situation. - If this option is not selected the developer's mode is available for students too as a voluntary option. + Постоје нека друга подешавања која би вам такође могла бити корисна. Наше прво додатно подешавање је 'Обавезни режим програмера'. У режиму програмера ученици виде само своје улазне и излазне екране и дугме за покретање. Авантуре су скривене и нема доступних листа за варање. Ово може бити корисно у ситуацији теста. + Ако ова опција није изабрана, режим програмера је доступан и ученицима као добровољна опција. - If you want all your students to be visible in de class highscore, you can select the second option. - With all the other options you can choose to hide some functions or content for your students, this might help them focus more. + Ако желите да сви ваши ученици буду видљиви у разредном резултату, можете изабрати другу опцију. + Са свим осталим опцијама можете изабрати да сакријете неке функције или садржај за своје ученике, што им може помоћи да се више фокусирају. - **Save** + **Сачувај** - Don't forget to save your changes when you're done customizing your class. - - title: Student Accounts + Не заборавите да сачувате своје промене када завршите са прилагођавањем свог разреда. + - title: Налози ученика text: |- - To add students to your class go to the class page by clicking in the class name on the 'for teachers' page. Then click 'add students'. There are 2 ways to let your students join your class: You can create accounts for them, or they could create their own accounts. + Да бисте додали ученике у свој разред, идите на страницу разреда кликом на име разреда на страници 'за наставнике'. Затим кликните 'додај ученике'. Постоје 2 начина да ваши ученици приступе вашем разреду: Можете креирати налоге за њих, или они могу креирати своје налоге. - **You create accounts for your students** - The easiest way to add students to your class is by creating an account for them. This can be done by clicking the 'create student accounts' button and filling in the usernames and passwords for them. - The students can login with the username and password that you chose. Afterwards, they can change their username or password if they'd like and they'll still remain in your class. - This [video](https://www.youtube.com/watch?v=eEQvik-Ce5M) shows how to add students to your class in the quickest and easiest way. + **Ви креирате налоге за своје ученике** + Најлакши начин да додате ученике у свој разред је креирањем налога за њих. Ово се може урадити кликом на дугме 'креирај ученичке налоге' и попуњавањем корисничких имена и лозинки за њих. + Ученици могу да се пријаве са корисничким именом и лозинком коју сте изабрали. Након тога, могу променити своје корисничко име или лозинку ако желе и још увек ће остати у вашем разреду. + Овај видео показује како да додате ученике у свој разред на најбржи и најлакши начин. - **Students make their own accounts** - Your students can also go to the Hedy website and create their own accounts, just like you did. To get them into your class, they simply have to click the invite link. - You can find the invite link on the class page and send it to your students. Mind that your students have to be logged in to Hedy when they click the link, in order to make it work smoothly. - You can also manually invite a student to your class with the button 'Invite by username'. - - title: Setting preferred language + **Ученици креирају своје налоге** + Ваши ученици такође могу отићи на Хеди вебсајт и креирати своје налоге, баш као што сте ви урадили. Да би ушли у ваш разред, једноставно морају кликнути на линк за позив. + Можете пронаћи линк за позив на страници разреда и послати га својим ученицима. Имајте на уму да ваши ученици морају бити пријављени на Хеди када кликну на линк, како би све функционисало глатко. + Такође можете ручно позвати ученика у свој разред помоћу дугмета 'Позови по корисничком имену'. + - title: Постављање преферираног језика text: |- - When students create profiles they are supposed to choose a 'preferred language'. Hedy will always be loaded in this selected language. - Changing this language can always be done later on by navigating to 'My account' and 'My personal settings' again. - + Када ученици креирају профиле, треба да изаберу 'преферирани језик'. Хеди ће увек бити учитан на овом изабраном језику. + Промена овог језика увек се може извршити касније тако што ћете поново отићи на 'Мој налог' и 'Моја лична подешавања'. - **For non-English speakers** - Not only can you change the language of the adventures to your own language. You can also choose which language the keywords (for example 'print' or 'ask') should be in. - This way you can teach your students to code with English keywords, but you can also let them program in their own language. For example, Dutch students can use the command 'vraag' instead of 'ask'. - If a student wants to switch languages, they can click the keyword switcher. It will switch the keywords from English to the preferred language and back. - Fun fact! Students are allowed program in both English and their own language at the same time! So, if they have trouble remembering some keywords in English, but easily remember other ones they can use both at the same time. + **За оне који не говоре енглески** + Не само да можете променити језик авантура на свој језик. Такође можете изабрати на ком језику ће бити кључне речи (на пример 'print' или 'ask'). + На овај начин можете научити своје ученике да програмирају са енглеским кључним речима, али их такође можете пустити да програмирају на свом језику. На пример, холандски ученици могу користити команду 'vraag' уместо 'ask'. + Ако ученик жели да промени језик, може кликнути на прекидач за кључне речи. Он ће променити кључне речи са енглеског на преферирани језик и назад. + Занимљива чињеница! Ученицима је дозвољено да програмирају и на енглеском и на свом језику у исто време! Дакле, ако имају проблема да запамте неке кључне речи на енглеском, али лако памте друге, могу користити оба језика истовремено. - **Video** - This [video](https://www.youtube.com/watch?v=QrVZETj4oLM) show you how to set a preferred language and change the keywords to you preferred language as well. - - title: Storing programs + **Видео** + Овај видео показује како да поставите преферирани језик и промените кључне речи на свој преферирани језик. + - title: Чување програма text: |- - Because you are now logged in, you'll see the blue banner with My profile and My programs. - These tabs exist for your students too. In My programs you can find all programs that you've saved. + Када сте пријављени, видећете Моји програми поред иконе вашег профила. + Ова опција постоји и за ваше ученике. У Моји програми можете пронаћи све програме на којима сте радили. + По подразумеваној вредности, програми ће бити сачувани у 'Моји програми' када покренете код, и сваких 10 секунди, под њиховим подразумеваним именом + и њиховим нивоом (на пример: Прича 5). Ако желите да сачувате програм под новим именом, само унесите ново име у траку за име. + Тренутно, само један програм може бити сачуван по нивоу, по табу. + + Ви (и ваши ученици) такође можете делити програме користећи дугме за дељење поред имена програма. + Ови програми ће бити објављени на нашој страници за истраживање, да их сви виде и користе. + Ако желите да престанете да делите свој програм, идите на 'Моји програми' и кликните 'Престани делити'. - You can save your projects easily by giving your project a name in the white bar and pressing the green button Save Code. - You (and your students) can also share programs. These programs will be posted on our [explore page](https://hedy.org/explore), for everybody to see and use. - If you want to unshare your program, go to 'My programs' and click 'Unshare'. -- title: Teaching with Hedy - key: teaching + Икона папирног авиона може се користити за предају програма наставнику разреда. Програми који су предати више неће бити могући за уређивање. +- title: Предавање са Хеди + key: предавање subsections: - - title: Teaching with Hedy + - title: Предавање са Хеди text: |- - Hedy contains a lot of different levels that each teach a different new skill. We recommend to teach one level per lesson. - This gives your students the time to fully grasp a new command or concept and practice with it, before moving on to the next level. - We use this structure in our lessons: Introduction, New concepts and commands, let's get to work, puzzels and quizzes. - - title: Slides - text: When giving instructions you might want to use our slides. Our slides are available on the 'For teachers' page. There is a set of slides for each level. In the slides all the new commands for that level are explained. We have aimed to explain why these changes are nessecary or how the new commands come in handy. We also give some examples of how the new commands can be used. You could of course also use your own slides, or just open Hedy and show your students around the website. Whichever you prefer to give the best Hedy lessons! - - title: Introduction + Хеди садржи много различитих нивоа који сваки уче нову вештину. Препоручујемо да предајете један ниво по лекцији. + Ово даје вашим ученицима време да у потпуности схвате нову команду или концепт и вежбају са њим, пре него што пређу на следећи ниво. + Користимо ову структуру у нашим лекцијама: Увод, Нови концепти и команде, хајде да радимо, загонетке и квизови. + - title: Слајдови + text: "Када дајете упутства, можда ћете желети да користите наше слајдове. Наши слајдови су доступни на страници 'За наставнике'. Постоји сет слајдова за сваки ниво. У слајдовима су објашњене све нове команде за тај ниво. Циљ нам је био да објаснимо зашто су ове промене неопходне или како нове команде могу бити корисне.\nТакође дајемо неке примере како се нове команде могу користити. Наравно, можете користити и своје слајдове, или само отворити Хеди и показати својим ученицима вебсајт. Шта год да преферирате да бисте дали најбоље Хеди лекције!" + - title: Увод text: |- - You can start your lessons by activating your students' prior knowledge: What do they already know about the subject, what did they learn in the previous lesson and which mistakes did they make that they've now learned from? - This way all the previously learned commands and frequently made mistakes are fresh in your students' memories, when you start introducing the new lesson. - - title: Introduction of new concepts and commands + Можете започети своје лекције активирањем претходног знања својих ученика: Шта већ знају о теми, шта су научили на претходној лекцији и које грешке су направили из којих су сада научили? + На овај начин све претходно научене команде и често прављене грешке су свеже у сећању ваших ученика када почнете да уводите нову лекцију. + - title: Увођење нових концепата и команди text: |- - The new concepts and commands can be very hard for some students to fully understand. - That's why it's of importance to model the proper use of the new commands to your students. - Especially in the lower levels, where some students have no experience with programming at all, it can be hard for them to understand the new abstract concepts. - Showing a lot of examples makes an abstract concept (for instance: 'What is a variable?') more recognizable and easier to understand ('Look, the variable pet changed into dog'). Our slides could help you with that. - - title: Let's get to work + Нови концепти и команде могу бити веома тешки за неке ученике да их у потпуности разумеју. + Зато је важно да моделујете правилну употребу нових команди својим ученицима. + Посебно на нижим нивоима, где неки ученици уопште немају искуства са програмирањем, може бити тешко за њих да разумеју нове апстрактне концепте. + Показивање много примера чини апстрактни концепт (на пример: 'Шта је променљива?') препознатљивијим и лакшим за разумевање ('Погледај, променљива pet се променила у dog'). Наше слајдове могу вам помоћи у томе. + - title: Хајде да се бацимо на посао text: |- - Each level contains different adventures that you can find in the pink tabs. The first pink tab explains the new commands in this level. - The following tabs are adventures that the students can try out and make their own. - The adventures are arranged from easiest to hardest, so we recommend to start on the left and your your way to the right. - The last tab 'what's next' gives a little teaser of what you'll learn in the next level. Of course, you can select the adventures you want your students to do for each level. - They don't always have to make every adventure. Every adventure contains an example code, that the students can try out with the green button. - The example code gets copied to the workfield, where the students can try out the code and adjust it to make it their own. - Stimulate your students to turn the example code into their own projects by adding their own ideas and making their own variation of the adventure. - - title: Quizzes and puzzels + Сваки ниво садржи различите авантуре које можете пронаћи у розе табовима. Први розе таб објашњава нове команде у овом нивоу. + Следећи табови су авантуре које ученици могу испробати и прилагодити себи. + Авантуре су распоређене од најлакших до најтежих, па препоручујемо да почнете са леве стране и кренете ка десној. + Последњи таб 'шта је следеће' даје мали тизер о томе шта ћете научити у следећем нивоу. Наравно, можете одабрати авантуре које желите да ваши ученици раде за сваки ниво. + Не морају увек да ураде сваку авантуру. Свака авантура садржи пример кода који ученици могу испробати зеленим дугметом. + Пример кода се копира у радно поље, где ученици могу испробати код и прилагодити га да буде њихов. + Подстакните своје ученике да претворе пример кода у своје пројекте додавањем својих идеја и прављењем своје варијације авантуре. + - title: Квизови и слагалице text: |- - To test whether your students have picked up all the new info in the level, you can let them take the quiz. - The quiz contains 10 multiple choice questions about the new concepts and command to that level. - Not every level has a quiz yet, as we are still building the quizzes. - Some levels also contain puzzles. Puzzles show the students a couple of line of code that the students have to put in the right order. + Да бисте тестирали да ли су ваши ученици усвојили све нове информације у нивоу, можете им дозволити да положе квиз. + Квиз садржи 10 питања са вишеструким избором о новим концептима и командама за тај ниво. + Нису сви нивои још увек имају квиз, јер још увек градимо квизове. + Неки нивои такође садрже слагалице. Слагалице показују ученицима неколико линија кода које ученици морају да ставе у прави редослед. - This [video](https://www.youtube.com/watch?v=lNh5EdZVUwc) shows the quizzes and puzzles. - - title: Evaluation + Овај видео показује квизове и слагалице. + - title: Евалуација text: |- - Round up your lesson by having a brief evaluation. What did the students learn? Which hardships did they come across? - How did they learn from their mistakes? And of course: What did they create? - Students are often very proud of their own creations, so it's nice to save a little time and give your students the opportunity to show their work to their classmates. -- title: Teacher Statistics - key: teacher_statistics + Завршите свој час кратком евалуацијом. Шта су ученици научили? Са којим тешкоћама су се сусрели? + Како су научили из својих грешака? И наравно: Шта су створили? + Ученици су често веома поносни на своје креације, па је лепо сачувати мало времена и дати својим ученицима прилику да покажу свој рад својим другарима из разреда. +- title: Статистика наставника + key: статистика_наставника subsections: - title: Live Dashboard text: |- - If you would like to keep track of your students' progress, you can make use of the live dashboard. You can find the live dashboard by clicking 'Live statistics' on your class page. + Ако желите да пратите напредак својих ученика, можете користити ливе дасхбоард. Можете пронаћи ливе дасхбоард кликом на 'Ливе статистика' на страници ваше класе. - All the features of this dashboard are explained below. - - title: Level Selection + Све функције овог дасхбоарда су објашњене у наставку. + - title: Избор нивоа text: |- - Firstly, you can select the levels you'd like to see on the dahsboard. Select the levels your students are currently working on by clicking on the number of that level. Deselect levels that you do not want to see by clicking them again. - In this example level 1 and 2 are selected. You can click on refresh to refresh the dashboard and get the most current stats. - - title: Class Overview + Прво, можете одабрати нивое које желите да видите на дасхбоарду. Одаберите нивое на којима ваши ученици тренутно раде кликом на број тог нивоа. Поништите избор нивоа које не желите да видите кликом на њих поново. + У овом примеру су одабрани нивои 1 и 2. Можете кликнути на освежи да бисте освежили дасхбоард и добили најновије статистике. + - title: Преглед класе text: |- - In the class overview you can see which adventure your students are working on right now. You can see that one student is working on the 'Rock, Paper, Scissors' adventure in level 1, one is working on the 'Fortune Teller' in level 1 and one student is working on the 'Rock, Paper, Scissors' adventure in level 2. - If you'd like to know which of your students is working on the adventure, simply click the number and their accountnames will appear. - You can also see how many of your students have finished the quiz. In this case, one student finished the quiz in level 1. Again, you can click the 1 to see which of your students it is. + У прегледу класе можете видети на којој авантури ваши ученици тренутно раде. Можете видети да један ученик ради на авантури 'Камен, папир, маказе' у нивоу 1, један ради на 'Пророчанство' у нивоу 1 и један ученик ради на авантури 'Камен, папир, маказе' у нивоу 2. + Ако желите да знате који од ваших ученика ради на авантури, једноставно кликните на број и њихова корисничка имена ће се појавити. + Такође можете видети колико ваших ученика је завршило квиз. У овом случају, један ученик је завршио квиз у нивоу 1. Поново, можете кликнути на 1 да видите који од ваших ученика је то. - You can also see one of the students is 'missing' from this overview. That's because he's working on an adventure in level 4, which is not selected. - - title: Student List + Такође можете видети да један од ученика 'недостаје' у овом прегледу. То је зато што ради на авантури у нивоу 4, који није одабран. + - title: Листа ученика text: |- - Here you can find a list of your students and you can see their individual progress. The blue ring shows you what your students are currently working on. + Овде можете пронаћи листу својих ученика и видети њихов индивидуални напредак. Плави прстен вам показује на чему ваши ученици тренутно раде. - It is important to notice that the blue dots means that a students 'attempted' the adventure. This means that they ran a code in this adventure and went on to the next adventure, so this does not automatically mean that they did a good job! - If you want to see how an individual student is getting along, you can click their name in this overview. This is what you see if you click on marleen_h3a for example: + Важно је приметити да плаве тачке значе да је ученик 'покушао' авантуру. То значи да су покренули код у овој авантури и прешли на следећу авантуру, тако да то не значи аутоматски да су добро урадили! + Ако желите да видите како се појединачни ученик сналази, можете кликнути на његово име у овом прегледу. Ово је оно што видите ако кликнете на marleen_h3a на пример: - You see that Marleen is having some trouble programming. She tried to run a program that contains blanks multiple times, so she probably doesn't know that she has to change something in the example code before running it. - In this way this overview can give you a better understanding of what a student is struggling with. - - title: Common Errors + Видите да Марлин има неких проблема са програмирањем. Покушала је да покрене програм који садржи празнине више пута, тако да можда не схвата да мора да промени примере кода пре него што их покрене. + На овај начин овај преглед вам може дати боље разумевање са чим се ученик бори. + - title: Уобичајене грешке text: |- - If you're not only interested in individual struggles of your students, but you'd like to know what the whole class seems to be doing wrong, you can use this oversight of common errors. - The most common error messages that your students are recieving will appear in this oversight for you, so you could give some more instructions to the whole class if needed. - By clicking the error, you can see which students are having trouble with this error. By clicking resolve, you'll remove this error from the list. - - title: Overview of programs per adventure + Ако вас не занимају само индивидуалне борбе ваших ученика, већ желите да знате шта цела класа изгледа ради погрешно, можете користити овај преглед уобичајених грешака. + Најчешће поруке о грешкама које ваши ученици добијају ће се појавити у овом прегледу за вас, тако да можете дати додатна упутства целој класи ако је потребно. + Кликом на грешку, можете видети који ученици имају проблема са том грешком. Кликом на реши, уклонићете ову грешку са листе. + - title: Преглед програма по авантури text: |- - Another useful overview of all the programs your students made in a level can be found on your class page. Go to the class page and click 'Overview of programs per adventure'. Here you'll find this overview. - You could use this overview to check your students' work. If they have made a program in an adventure, an eye appears in your overview. Click the eye to view their work. Did you like it? Then you can check the box and a green tick will appear. - This way you create a nice overview for yourself of your students' results. -- title: Extra Hedy features - key: features + Још један користан преглед свих програма које су ваши ученици направили у нивоу можете пронаћи на страници ваше класе. Идите на страницу класе и кликните на 'Преглед програма по авантури'. Овде ћете пронаћи овај преглед. + Можете користити овај преглед да проверите рад својих ученика. Ако су направили програм у авантури, око се појављује у вашем прегледу. Кликните на око да бисте видели њихов рад. Да ли вам се допало? Тада можете означити поље и појавиће се зелена квачица. + На овај начин креирате леп преглед за себе о резултатима својих ученика. +- title: Додатне Hedy функције + key: карактеристике subsections: - - title: Make your own adventure - text: It is also possible for teachers to create your own adventure. [This video](https://www.youtube.com/watch?v=A0zbXpxX4q4) shows you how to create your own adventure as a teacher and add it to your class(es). - - title: Explore page + - title: Направите своју авантуру + text: Такође је могуће за наставнике да креирају своју авантуру. Овај видео вам показује како да креирате своју авантуру као наставник и додате је својој класи(ама). + - title: Страница за истраживање text: |- - On the [explore](https://hedy.org/explore) page you can view the work of other Hedy users. You can try out their programs and use them as inspiration to create something cool yourself. - You can also add a program you've made to the explore page yourself by clicking 'Save and share code' in the coding screen or go to My Programs and click 'Share'. - Don't want to share your work anymore? Simply go to 'My Programs' and click 'Unshare'. - If you want more information about the explore page, check out this [video](https://www.youtube.com/watch?v=26boFjqvS5Q). - - title: My achievements + На страници за истраживање можете видети рад других Hedy корисника. Можете испробати њихове програме и користити их као инспирацију да сами креирате нешто кул. + Такође можете додати програм који сте направили на страницу за истраживање кликом на 'Сачувај и подели код' на екрану за кодирање или идите на Моји програми и кликните на 'Подели'. + Не желите више да делите свој рад? Једноставно идите на 'Моји програми' и кликните на 'Уклони дељење'. + Ако желите више информација о страници за истраживање, погледајте овај видео. + - title: Моја достигнућа text: |- - If you click on your username in the topright corner of your screen, you can go to [My achievements](https://hedy.org/my-achievements). On this page you achievements are collected. Your students have such a page as well. - When you hover over the badge with your mouse, you'll see how to earn the badge. There are hidden badges too, of which you'll have to find out yourself how to earn them. - If you want more information on the achievements, check out this [video](https://www.youtube.com/watch?v=-FjmKejukCs). - - title: High Scores + Ако кликнете на своје корисничко име у горњем десном углу екрана, можете отићи на Моја достигнућа. На овој страници се прикупљају ваша достигнућа. Ваши ученици такође имају такву страницу. + Када пређете мишем преко значке, видећете како да зарадите значку. Постоје и скривене значке, за које ћете морати сами да откријете како да их зарадите. + Ако желите више информација о достигнућима, погледајте овај видео. + - title: Високи резултати text: |- - On [this page](https://hedy.org/highscores) you can see the high scores of all Hedy users. - In this [video](https://www.youtube.com/watch?v=IqTiUkBVTo8) you can learn some more about the high scores. - - title: Debugger + На овој страници можете видети најбоље резултате свих корисника Hedy. + У овом видеу можете научити нешто више о најбољим резултатима. + - title: Дебагер text: |- - Is your (student's) code not working? There must be a bug (coding mistake) in it! You can use the debugger to find the mistake. - The debugger is the ladybug button in your coding screen. If you press it, you can run your code line by line to find your mistake. - Have you found the mistake? Press the red stop button and the debugger will shut off. - - title: Read aloud - text: Do you want the output of your program to be read aloud? Then you can use the read aloud function that is found under the 'run code' button in your coding screen. - - title: Programmers mode + Да ли ваш (учеников) код не ради? Мора да постоји грешка (грешка у кодирању) у њему! Можете користити дебагер да пронађете грешку. + Дебагер је дугме са бубамаром на вашем екрану за кодирање. Ако га притиснете, можете покренути свој код линију по линију да бисте пронашли грешку. + Да ли сте пронашли грешку? Притисните црвено дугме за заустављање и дебагер ће се искључити. + - title: Читање наглас + text: Да ли желите да излаз вашег програма буде прочитан наглас? Тада можете користити функцију читања наглас која се налази испод дугмета 'покрени код' на вашем екрану за кодирање. + - title: Режим програмера text: |- - Distracted by all the adventures, or do you want to make a long program? Then check out the 'Programmers Mode' switch at the bottom of your coding screen. - Programmers mode allows you and your students to use a bigger coding screen. - - title: Cheat sheets + Да ли вас ометају све авантуре, или желите да направите дугачак програм? Онда погледајте прекидач 'Режим програмера' на дну вашег екрана за кодирање. + Режим програмера омогућава вама и вашим ученицима да користите већи екран за кодирање. + - title: Варалице text: |- - In every level there is a button with this emoji 🤔. You and your students can find the "cheat sheets" there. On this cheat sheet, you can find all the commands that are usable in this level in their correct form. - So if you've forgotten how a command works, simply take a peek at the cheat sheet! - - title: Other useful features - text: This [video](https://www.youtube.com/watch?v=c4MntPPgl1Y) shows you even more features of Hedy, like the cheatsheets and the keyword switcher. -- title: After Hedy - key: after + На сваком нивоу постоји дугме са овим емоџијем 🤔. Ви и ваши ученици можете пронаћи "варалице" тамо. На овој варалици можете пронаћи све команде које су употребљиве на овом нивоу у њиховом исправном облику. + Дакле, ако сте заборавили како команда функционише, једноставно завирите у варалицу! + - title: Видео + text: Овај видео вам показује још више карактеристика Hedy, као што су варалице и прекидач за кључне речи. +- title: После Hedy + key: после subsections: - - title: What to do after Hedy? + - title: Шта радити после Hedy? text: |- - Congratulations on reaching the end of Hedy! Your students have now learned how to create their own basic code in the Python programming language. - Of course, you could keep programming in our Hedy compiler, but it might be more exciting for your students to transfer to a "real" Python interface. - Would you like to continue teaching Python? Then please visit the Python website to learn how to get started in another compiler. + Честитамо на достизању краја Hedy! Ваши ученици су сада научили како да креирају своје основне програме у програмском језику Python. + Наравно, могли бисте наставити програмирање у нашем Hedy компајлеру, али можда би било узбудљивије за ваше ученике да пређу на "прави" Python интерфејс. + Да ли бисте желели да наставите са предавањем Python-а? Онда посетите Python вебсајт да научите како да започнете у другом компајлеру. - Now that your students have a basic knowledge of programming in general, you could also show them around in other textual programming languages. The language might change but the concepts do not, so Hedy will still give them a big advantage. -- title: Answers to the exercises - key: answers + Сада када ваши ученици имају основно знање о програмирању уопште, могли бисте их упознати и са другим текстуалним програмским језицима. Језик се може променити, али концепти не, тако да ће им Hedy и даље пружити велику предност. +- title: Одговори на вежбе + key: одговори intro: |- - The answers to all the exercises can be found on the public profile of the useraccount 'Hedy_answers'. We often encourage students to use their own creativity in their answers, so these answers are merely a guideline as to what a possible correct answer could look like. + Одговори на све вежбе могу се наћи на јавном профилу корисничког налога 'Hedy_answers'. Често охрабрујемо ученике да користе своју креативност у својим одговорима, тако да су ови одговори само смерница како би могао изгледати могући тачан одговор. - To go to the 'Hedy_answers' profile, please click here. -- title: Common mistakes - key: common_mistakes + Да бисте отишли на профил 'Hedy_answers', кликните овде. +- title: Уобичајене грешке + key: уобичајене_грешке intro: |- - You can learn from your mistakes, especially in coding! - Making mistakes is unavoidable, and a great opportunity to learn, but for teachers it can be a challenge to find the correct fix for a mistake! - Especially as the programs get longer and longer as the levels progress. That's why we've made a list with frequently made mistakes in each level, and their solutions. + Можете научити из својих грешака, посебно у кодирању! Прављење грешака је неизбежно и одлична прилика за учење, али за наставнике може бити изазов пронаћи исправно решење за грешку! Посебно како програми постају све дужи и дужи како ученици напредују кроз нивое. Зато смо направили листу са често прављеним грешкама на сваком нивоу и њиховим решењима. levels: - level: '1' sections: - - title: Students forget to type commands + - title: Ученици заборављају да укуцају команде example: - error_text: For example they type a sentence without using print. - error_code: Hedy can't print this - solution_text: Teach your students to always start a line of code with a command. - solution_code: '{print} Hedy can print this!' - - title: Students use capitals when typing commands + error_text: На пример, укуцају реченицу без коришћења {print}. + error_code: Hedy не може да одштампа ово + solution_text: Научите своје ученике да увек започну линију кода са командом. + solution_code: '{print} Hedy може да одштампа ово!' + - title: Ученици користе велика слова када укуцавају команде example: - error_text: Commands won't work if they are in capitals. + error_text: Команде неће радити ако су написане великим словима. error_code: |- - Ask Why does my code fail? - Print Because I'm using capitals. - solution_text: Remove the capitals. + {ask} Зашто мој код не ради? + {print} Зато што користим велика слова. + solution_text: Уклоните велика слова. solution_code: |- - {ask} Why does my code work now? - {print} Because I removed the capitals! - - title: Students use echo without ask + {ask} Зашто мој код сада ради? + {print} Зато што сам уклонио велика слова! + - title: Ученици користе {echo} без {ask} example: - error_text: Echo is made to repeat an answer after an ask command. Without ask echo won't do anything. - error_code: '{echo} Your name is' - solution_text: Add an ask command to make it work. + error_text: '{echo} је направљен да понавља одговор након {ask} команде. Без {ask} {echo} неће радити ништа.' + error_code: '{echo} Твоје име је' + solution_text: Додајте {ask} команду да би радила. solution_code: |- - {ask} What's your name? - {echo} Your name is - - title: Students want their echo word (variable) to be in the middle of a sentence + {ask} Како се зовеш? + {echo} Твоје име је + - title: Ученици желе да њихова {echo} реч (променљива) буде у средини реченице example: - error_text: And they are right! That's why they will learn to use proper variables in the next level. + error_text: И у праву су! Зато ће научити да користе исправне променљиве у следећем нивоу. error_code: |- - {ask} Which programming language is the most fun? - {echo} is the best! - solution_text: 'In level 1 we have to keep it at this:' + {ask} Који програмски језик је најзабавнији? + {echo} је најбољи! + solution_text: 'На нивоу 1 морамо се задржати на овоме:' solution_code: |- - {ask} Which programming language is the most fun? - {echo} The best is... - - title: 'Turtle: Students let the turtle walk off of the screen' + {ask} Који програмски језик је најзабавнији? + {echo} Најбољи је... + - title: 'Корњача: Ученици пуштају корњачу да хода ван екрана' example: - error_text: Often students love to try out big numbers when using the turtle, which causes the arrow to walk off the screen. + error_text: Често ученици воле да испробавају велике бројеве када користе корњачу, што узрокује да стрелица хода ван екрана. error_code: |- {forward} 300 {turn} 90 - solution_text: In the example, students tend to think that the turn command doesn't work. Even though it does work, you can't see it happening off screen. Use smaller numbers to prevent this from happening. + solution_text: У примеру, ученици имају тенденцију да мисле да команда за окретање није успела; иако је урадила оно што је требало. Оно што се догодило је да је корњача прошла границе екрана. Користите мање бројеве да бисте то спречили. solution_code: |- {forward} 100 {turn} 90 - - title: "Turtle: Students use the command backward, but that doesn't exist" + - title: "Корњача: Ученици користе команду backward, али таква команда не постоји." example: - error_text: Backward is not a command. - error_code: backward 100 - solution_text: 'To make the turtle go backwards, you use the forward command and a negative number. For example:' + error_text: Backward није команда. + error_code: назад 100 + solution_text: 'Да би корњача ишла уназад, користите команду {forward} и негативан број. На пример:' solution_code: '{forward} -100' - level: '2' sections: - - title: Students make typos in their commands + - title: Ученици праве типографске грешке у својим командама example: - error_text: Hedy can't recognize a command with a typo. + error_text: Hedy не може препознати команду са типографском грешком. error_code: prinnt Don't make typos - solution_text: Teach your students to read the error messages. This way they can find out themselves what went wrong. + solution_text: Научите своје ученике да читају поруке о грешкама. На тај начин могу сами открити шта је пошло наопако. solution_code: "{print} Don't make typos" - - title: Students forget that the ask command has changed + - title: Ученици заборављају да је команда ask промењена example: - error_text: In this level students learn about variables. The ask command requires a variable as well, but students forget this. - error_code: ask what would you like to eat - solution_text: In this level you have to tell Hedy where to save your answer, so it can be used later on. This is called a variable. - solution_code: order {is} {ask} What would you like to eat - - title: Students try to use the `{echo}` command + error_text: На овом нивоу ученици уче о променљивама. Команда ask такође захтева променљиву, али ученици то заборављају. + error_code: '{ask} шта би желео да једеш' + solution_text: На овом нивоу мораш рећи Хеди где да сачува твој одговор, како би могао бити коришћен касније. То се зове променљива. + solution_code: наруџбина {is} {ask} Шта би желео да једеш + - title: Ученици покушавају да користе команду `{echo}` example: - error_text: For some students it might be frustrating to learn that the `{echo}` command doesn't work anymore. That's why it's very important to explain the advantages of using variables. For example you can use multiple variables in a code, and you can put them anywhere you like in a sentence! + error_text: За неке ученике може бити фрустрирајуће да науче да команда `{echo}` више не ради. Зато је веома важно објаснити предности коришћења променљивих. На пример, можеш користити више променљивих у коду и можеш их ставити било где у реченици! error_code: |- - answer {is} {ask} Why doesn't {echo} work anymore?! + одговор {is} {ask} Зашто {echo} више не ради?! {echo} - solution_text: Use a variable instead. + solution_text: Користи променљиву уместо тога. solution_code: |- - answer {is} {ask} Why doens't {echo} work anymore?! - {print} answer - - title: Students use a variable name or as a normal word + одговор {is} {ask} Зашто {echo} више не ради?! + {print} одговор + - title: Ученици користе име променљиве или као обичну реч example: - error_text: In the example below the word 'name' is used as a variable, but also as a normal text. The output of this code will be 'Hi my Hedy is Hedy'. + error_text: У примеру испод реч 'име' се користи као променљива, али и као обичан текст. Излаз овог кода ће бити 'Здраво моје Хеди је Хеди'. error_code: |- - name {is} Hedy - {print} Hi my name is name - solution_text: So don't use a word you want to use in the text as a variable name. In level 4 this is solved with quotation marks. + име {is} Хеди + {print} Здраво моје име је име + solution_text: Зато немој користити реч коју желиш да користиш у тексту као име променљиве. На нивоу 4 ово је решено са наводницима. solution_code: |- - name {is} Hedy - {print} Hi I'm name - - title: Students use long variable names containing two words. + име {is} Хеди + {print} Здраво ја сам име + - title: Ученици користе дуга имена променљивих која садрже две речи. example: - error_text: A variable should be named with one word. You could use an underscore to connect two words. That counts as one. - error_code: chosen door is ask Which door do you pick - solution_text: Add an underscore. - solution_code: chosen_door {is} {ask} which door do you pick - - title: Students might use two different names for the same variable + error_text: Променљива треба да буде именована једном речју. Можеш користити подвлаку да повежеш две речи. То се рачуна као једна. + error_code: изабрана врата {is} {ask} Која врата би изабрао + solution_text: Додај подвлаку. + solution_code: изабрана_врата {is} {ask} која врата би изабрао + - title: Ученици могу користити два различита имена за исту променљиву example: - error_text: In this example the student has used 'horse' and 'name' for the same variables. + error_text: У овом примеру ученик је користио 'коњ' и 'име' за исте променљиве. error_code: |- - horse {is} {ask} What is your horse called - {print} Your horse is called name - solution_text: Always check whether the variable has the same name throughout the code. Slight differences can be hard to spot (for example plurals) but they will interfere with the code. + коњ {is} {ask} Како се зове твој коњ + {print} Твој коњ се зове име + solution_text: Увек провери да ли променљива има исто име кроз цео код. Мале разлике могу бити тешке за уочавање (на пример множина), али ће ометати код. solution_code: |- - name {is} {ask} What is your horse called - {print} Your horse is called name + име {is} {ask} Како се зове твој коњ + {print} Твој коњ се зове име - level: '3' sections: - - title: Students try to print whole lists + - title: Ученици покушавају да прикажу целе листе example: - error_text: A list can't be printed. You can only print one item from the list with {at} {random}. + error_text: Листа не може бити приказана. Можеш приказати само један елемент са листе са {at} {random}. error_code: |- - groceries {is} apples, milk, chocolate - {print} groceries - solution_text: To print a list of all the groceries, you simply need to put them after a `{print}` command. Else you can use the list to print one item with `{at}` `{random}`. + намирнице {is} јабуке, млеко, чоколада + {print} намирнице + solution_text: Да би приказао листу свих намирница, једноставно их стави после команде `{print}`. Иначе можеш користити листу да прикажеш један елемент са `{at}` `{random}`. solution_code: |- - {print} apples, milk, chocolate + {print} јабуке, млеко, чоколада - # or + # или - groceries {is} apples, milk, chocolate - {print} groceries {at} {random} - - title: Students use the name of a variable or list as regular text + намирнице {is} јабуке, млеко, чоколада + {print} намирнице {at} {random} + - title: Ученици користе име променљиве или листе као обичан текст example: - error_text: This problem probably occured in level 2 as well. Now it can happen with lists too. + error_text: Овај проблем се вероватно појавио и на нивоу 2. Сада се може десити и са листама. error_code: |- - name {is} Hedy - {print} Hi my name is name + име {is} Хеди + {print} Здраво моје име је име - # or + # или - animal {is} rhino, bee, swan - {print} The best animal is... animal {at} {random} - solution_text: Don't use the names of variables or lists in regular text to print. In level 4 this problem is solved with quotation marks. + животиња {is} носорог, пчела, лабуд + {print} Најбоља животиња је... животиња {at} {random} + solution_text: Немој користити имена променљивих или листа у обичном тексту за приказивање. На нивоу 4 овај проблем је решен са наводницима. solution_code: |- - name {is} Hedy - {print} Hi I'm name + име {is} Хеди + {print} Здраво ја сам име - # or + # или - animals {is} rhino, bee, swan - {print} The best animal is... animals {at} {random} - - title: Students forget `{at}` in `{at}` `{random}` + животиње {is} носорог, пчела, лабуд + {print} Најбоља животиња је... животиње {at} {random} + - title: Ученици заборављају `{at}` у `{at}` `{random}` example: - error_text: Like in the example + error_text: Као у примеру error_code: |- - birds {is} sparrow, seagull, robin - {print} birds random - solution_text: This problem is solved by adding the word at. + птице {is} врабац, галеб, црвендаћ + {print} птице random + solution_text: Овај проблем је решен додавањем речи at. solution_code: |- - birds {is} sparrow, seagull, robin - {print} birds {at} {random} - - title: Students forget to use the `{print}` command when also using the `{at}` `{random}` command + птице {is} врабац, галеб, црвендаћ + {print} птице {at} {random} + - title: Ученици заборављају да користе команду `{print}` када такође користе команду `{at}` `{random}` example: error_text: Or they will sometimes put `{at}` `{random}` at the beginning of the line. error_code: |- diff --git a/content/pages/uz.yaml b/content/pages/uz.yaml index 27e7648061f..06bf94a63ab 100644 --- a/content/pages/uz.yaml +++ b/content/pages/uz.yaml @@ -91,7 +91,7 @@ start-sections: text: |- Welcome to Hedy, we are happy to help you get started with Hedy. - Our [Teacher Manual](http://localhost:8080/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. + Our [Teacher Manual](https://www.hedy.org/for-teachers/manual) has an overview of all features in detail, but this page has a brief overview so you know what it what before you dive in. A few highlights that are important to know: * Hedy is a tool designed to help manage a classroom of kids programming! You can create your own classes, lesson plans and follow how kids are doing. diff --git a/content/pages/zh_Hans.yaml b/content/pages/zh_Hans.yaml index 04a44ea458e..d8ab1623f37 100644 --- a/content/pages/zh_Hans.yaml +++ b/content/pages/zh_Hans.yaml @@ -91,7 +91,7 @@ start-sections: text: |- 欢迎来到 海蒂,我们很乐意帮助您开始使用 海蒂。 - 我们的[教师手册](http://localhost:8080/for-teachers/manual) 详细概述了所有功能,但此页面有一个简短的概述,以便您在深入了解之前知道它是什么。 + 我们的[教师手册](https://www.hedy.org/for-teachers/manual) 详细概述了所有功能,但此页面有一个简短的概述,以便您在深入了解之前知道它是什么。 需要了解的一些重要要点: * Hedy 是一款旨在帮助管理儿童编程课堂的工具! 您可以创建自己的课程、课程计划并跟踪孩子们的表现。 diff --git a/content/parsons/ca.yaml b/content/parsons/ca.yaml index fdb749847ac..cf205fd844c 100644 --- a/content/parsons/ca.yaml +++ b/content/parsons/ca.yaml @@ -139,11 +139,11 @@ levels: {repeat} 3 {times} {print} 'Daddy shark tututututudu' {print} 'Daddy shark' 2: - story: Crea la cançó "Les rodes de l'autobús fan voltes i voltes" + story: Crea la cançó "Les rodes de l'autobús van girant" code: |- - {print} "les rodes de l'autobús van" - {repeat} 3 {times} {print} "volt i rodó" - {print} "les rodes de l'autobús fan voltes" + {print} "les rodes de l'autobús girant" + {repeat} 3 {times} {print} "van rodant" + {print} "les rodes de l'autobús girant, van rodant, van rodant" {print} "per tota la ciutat" 8: 1: @@ -177,8 +177,8 @@ levels: 10: 1: story: |- - Ajuda aquesta família creant un calendari per saber qui està cuinant i què li toca a fer a cadascú aquesta setmana. Les comandes d'eliminació s'asseguren que ningú ha de cuinar dues vegades i per garantir un sopar diferent cada dia. - **Atenció!** l'ordre de les variables hauria de ser primer dies, després persones i finalment opcions_sopar. Això també convé a les línies amb ordres d'eliminació. + Ajuda aquesta família creant un calendari per saber qui està cuinant i què li toca a fer a cadascú aquesta setmana. Amb la comanda `{remove}` assegurem que ningú ha de cuinar dues vegades i per garantir un sopar diferent cada dia. + **Atenció!** L'ordre de les variables hauria de ser primer dies, després persones i finalment opcions_sopar. Això també implica a les línies amb la comanda `{remove}`. code: |- dies = dilluns, dimarts, dimecres, dijous, divendres persones = la mare, el pare, en Martí, l'Anna, la Júlia @@ -215,7 +215,7 @@ levels: 2: story: |- Crea un programa que ens expliqui els resultats finals de la fira de la ciència. Primer defineix la variable concursants, després la variable lloc. - **Pista** La línia 5 hauria de ser la comanda sleep (dorm), i hauríeu d'acabar dient felicitats. + **Pista** La línia 5 hauria de tenir la comanda sleep (dorm), i hauries d'acabar amb un text de felicitació. code: |- {print} 'And now we will reveal the results of the science fair' contestants = Vivienne, Paul, Trixy, Bianca, Katya @@ -228,7 +228,7 @@ levels: 12: 1: story: |- - Sing the song 'What shall we do with the drunken sailor'. In case you don't know it, the song goed like this: + Canta la cançó 'What shall we do with the drunken sailor' (Què farem amb el mariner borratxo). Si no la saps va així: What will we do with the drunken sailor What will we do with the drunken sailor @@ -239,16 +239,16 @@ levels: Way hey and up she rises Early in the morning code: |- - verses = 'What will we do with the drunken sailor', 'Way hey and up she rises' - {for} verse {in} verses + versos = 'What will we do with the drunken sailor', 'Way hey and up she rises' + {for} vers {in} versos {for} count {in} {range} 1 {to} 3 - {print} verse + {print} vers {print} 'Early in the morning' 2: - story: Play a game of Twister with us! First define the variable people, then limbs, then colors. + story: Juga al Twister amb nosaltres! Primer defineix la variable persones, després les extremitats i en acabat els colors. code: |- - people = 'Jess', 'Nick', 'Winston' - limbs = 'left hand', 'left foot', 'right hand', 'right foot' - colors = 'red', 'blue', 'green', 'yellow' - {for} person {in} people - {print} person ', put your ' limbs {at} {random} ' on ' colors {at} {random} + gent = "Jordi", "Clark", "Omar" + extremitats = "mà esquerre", "peu esquerre", "mà dret", "peu dret" + colors = "red", "blue", "green", "yellow" + {for} person {in} gent + {print} person ", posa el/la " extremitats {at} {random} " a " colors {at} {random} diff --git a/content/quizzes/ca.yaml b/content/quizzes/ca.yaml index 231aac44b92..4a4e1bc3d6e 100644 --- a/content/quizzes/ca.yaml +++ b/content/quizzes/ca.yaml @@ -1393,32 +1393,32 @@ levels: 6: question_text: What will be the output from this code? code: |- - {print} 'The wheels on the bus go' - {repeat} 3 {times} {print} ' round and round' + {print} 'Les rodes de l'autobús van girant' + {repeat} 3 {times} {print} ' van rodant' mp_choice_options: - option: |- - the wheels on the bus go - round and round + Les rodes de l'autobús van girant + van rodant feedback: Only the second line is repeated 3 times - option: |- - the wheels on the bus go - the wheels on the bus go - the wheels on the bus go - round and round + les rodes de l'autobus van girant + les rodes de l'autobus van girant + les rodes de l'autobus van girant + van rodant feedback: Only the second line is repeated 3 times - option: |- - the wheels on the bus go - round and round - the wheels on the bus go - round and round - the wheels on the bus go - round and round + les rodes de l'autobús van girant + van rodant + les rodes de l'autobús van girant + van rodan + les rodes de l'autobús van girant + van rodan feedback: Only the second line is repeated 3 times - option: |- - the wheels on the bus go - round and round - round and round - round and round + les rodes de l'autobús van girant + van rodant + van rodant + van rodant feedback: All though the town! Perfect! hint: Only 'round and round' is repeated 3 times. correct_answer: D @@ -1569,10 +1569,10 @@ levels: feedback: This is not in the right order. - option: |- ``` - {repeat} 4 {times} 'if youre happy and you know it' - {repeat} 2 times 'clap your hands' - {print} 'and you really want to show it' - {print} 'clap your hands' + {repeat} 4 {times} 'si ets feliç i ho saps' + {repeat} 2 times 'pica de mans' + {print} 'i ho vols fer saber a tothom' + {print} 'pica de mans' ``` feedback: This is not in the right order. hint: Mind the order of the sentences. @@ -2892,14 +2892,16 @@ levels: 10: question_text: Which line of code should be filled in at the ??? to complete the song ? code: |- - actions = 'clap your hands', 'stomp your feet', 'shout Hurray!' - ??? - for i in range 0 to 1 - print 'if youre happy and you know it' - print action - print 'if youre happy and you know it and you really want to show it' - print 'if youre happy and you know it' - print action + ``` + accions = "pica de mans", "pica de peus", "crida Hurra!" + _ + {for} i {in} {range} 0 {to} 1 + {print} "si ets feliç i ho saps" + {print} accio + {print} "si ets feliç i ho saps, i ho vols fer saber a tothom" + {print} "si ets feliç i ho saps" + {print} accio + ``` mp_choice_options: - option: for i in range 1 to 3 feedback: This is a hard one! All the actions on the list must be in the song. diff --git a/content/quizzes/pl.yaml b/content/quizzes/pl.yaml index 6905e9ff561..c84849c1b55 100644 --- a/content/quizzes/pl.yaml +++ b/content/quizzes/pl.yaml @@ -597,25 +597,25 @@ levels: ``` {remove} walkers {from} yesterday ``` - feedback: yesterday is not a variable + feedback: wczoraj nie jest zmienną - option: |- ``` {add} walked_yesterday {to} walkers ``` feedback: This increased the change that the person who walked yesterday now has to do it again. That's mean. - hint: The person who walked the dog yesterday should be removed from the list. + hint: Osoba, która wczoraj wyprowadziła psa, powinna zostać usunięta z listy. correct_answer: A question_score: '10' 4: 1: - question_text: Which of these is true? + question_text: Który z tych kodów jest poprawny? mp_choice_options: - option: '``` {print} ''Jestem bardzo podekscytowany tym quizem!'' ```' - feedback: That's right + feedback: Dokładnie tak - option: "```\n{print}Jestem bardzo podekscytowany tym quizem!\n```" feedback: '{print} potrzebuje teraz cudzysłowu!' - option: '``` @@ -630,11 +630,11 @@ levels: ```' feedback: ostrożnie, używając cudzysłowów i apostrofu - hint: In level 4 you need quotation marks for 2 commands. + hint: Na poziomie 4 potrzebujesz cudzysłowu dla 2 poleceń. correct_answer: A question_score: '10' 2: - question_text: Which code uses the proper quotation marks? + question_text: Który kod używa odpowiednich cudzysłowów? mp_choice_options: - option: |- ``` @@ -655,23 +655,23 @@ levels: ``` {print} ,hello, ``` - feedback: This is a comma, you need quotation marks. - hint: Pick the right quotation marks. + feedback: To przecinek, potrzebujesz cudzysłowu. + hint: Wybierz odpowiednie cudzysłowy. correct_answer: B question_score: '10' 3: - question_text: Where are the quotation marks used correctly? + question_text: Gdzie znaki cudzysłowu zostały użyte poprawnie? mp_choice_options: - option: |- ``` {print} Hi Im Hedy ``` - feedback: Add quotation marks please! + feedback: Dodaj cudzysłowy! - option: |- ``` {print} 'Hi Im Hedy ``` - feedback: Both before and after the words you want to print should be a quotation mark. + feedback: Zarówno przed, jak i po słowach, które chcesz wydrukować, powinien być znakiem cudzysłowu. - option: |- ``` '{print} Hi Im Hedy' @@ -682,96 +682,96 @@ levels: {print} 'Hi Im Hedy' ``` feedback: Perfect! - hint: Both before and after the words you want to print should be a quotation mark. + hint: Zarówno przed, jak i po słowach, które chcesz napisać (print), powinien być znakiem cudzysłowu. correct_answer: D question_score: '10' 4: - question_text: Which statement is true? + question_text: Które wyrażenie jest prawdziwe? mp_choice_options: - - option: 'You need quotation marks around the word `{print}`, like this: `''{print}''`.' - feedback: The quotation marks shouldn't be around the command itself. - - option: You need quotation marks around the words you want to print. + - option: 'Potrzebujesz cudzysłowu wokół słowa `{print}`, w następujący sposób: `''{print}''`.' + feedback: Znaki cudzysłowu nie powinny znajdować się wokół samego polecenia. + - option: Potrzebujesz cudzysłowu wokół słów, które chcesz napisać (print). feedback: Super! - - option: You do not need quotation marks when using the `{ask}` command - feedback: Both `{print}` and `{ask}` require quotation marks - - option: You can choose yourself whether to use quotation marks or not. - feedback: Unfortunately, Hedy is stricter than that. - hint: From level 4 on you need to use quotation marks. + - option: Nie potrzebujesz cudzysłowu podczas korzystania z polecenia `{ask}` + feedback: Zarówno `{print}` i `{ask}` wymagają cudzysłowu + - option: Możesz sam wybrać, czy chcesz użyć cudzysłowu, czy nie. + feedback: Niestety Hedy jest bardziej surowy. + hint: Od poziomu 4 musisz używać cudzysłowów. correct_answer: B question_score: '10' 5: - question_text: What has to be changed in order for the game to work? + question_text: Co należy zmienić, aby gra działała? code: |- - options {is} rock, paper, scissors - {print} 'options {at} {random}' + opcje {is} kamień, papier, nożyczki + {print} 'opcje {at} {random}' mp_choice_options: - option: |- ``` '{print} options {at} {random}' ``` - feedback: Never put the quotation mark in front of the {print} command. + feedback: Nigdy nie umieszczaj znaku cudzysłowu przed poleceniem `{print}`. - option: |- ``` {print} 'options' {at} {random} ``` - feedback: options is a variable. You don't literally want to print 'options {at} {random}'. + feedback: opcje to zmienna. Nie chcesz dosłownie napisać (print) 'opcjie {at}{random}'. - option: |- ``` {print} options {at} {random} ``` - feedback: That's right - - option: Nothing, the game already works! - feedback: Look carefully. There is an error. - hint: You don't want Hedy to literally print 'options {at} {random}', you want it to print 'rock' or 'paper' or 'scissors'. + feedback: Dokładnie tak + - option: Nic, gra już działa! + feedback: Patrz uważnie. Wystąpił błąd. + hint: Nie chcesz, aby Hedy dosłownie napisała (print) 'opcje {at}{random} chcesz, aby napisała (print) 'kamień' lub 'papier' lub 'nożyczki'. correct_answer: C question_score: '10' 6: - question_text: What would be a good next line in this code? - code: prices {is} 1 dollar, 100 dollars, 1 million dollars + question_text: Jaki byłby dobry następny wiersz w tym kodzie? + code: ceny {is} 1 dolar, 100 dolarów, 1 milion dolarów mp_choice_options: - option: |- ``` {print} 'You win...' prices {at} {random} ``` - feedback: Great! You get it! + feedback: Świetnie! Rozumiesz to! - option: |- ``` {print} You win... 'prices {at} {random}' ``` - feedback: Hedy will literally print 'prices {at} {random}' + feedback: Hedy dosłownie napisze (print) ceny {at}{random}'' - option: |- ``` {print} You win... prices {at} {random} ``` - feedback: You need some quotation marks! + feedback: Potrzebujesz cudzysłowu! - option: |- ``` {print} 'You win... prices {at} {random}' ``` - feedback: Hedy will literally print 'prices {at} {random}'' + feedback: Hedy dosłownie napisze (print) ceny {at}{random}'' hint: 'Zastanów się: jaka jest zmienna i czy powinna znajdować się poza cudzysłowami? A jakie normalne słowa powinny być w środku?' correct_answer: A question_score: '10' 7: - question_text: What's wrong with this code? + question_text: Co jest nie tak z tym kodem? code: |- - question {is} {ask} What do you want to know? - answers {is} yes, no, maybe - {print} answers {at} {random} + pytanie {is}{ask} Co chcesz wiedzieć? + odpowiedzi {is} tak, nie, może + {print} odpowiedzi {at} {random} mp_choice_options: - - option: Quotation marks are missing in line 1 + - option: W wierszu 1 brakuje znaków cudzysłowu feedback: Correct! - - option: Quotation marks are missing in line 2 - feedback: A variable doesn't need quotes - - option: Quotation marks are missing in line 3 - feedback: You don't want Hedy to literally print 'answers {at} {random}' so no quotation marks needed here! - - option: Nothing, this code is good as is! - feedback: Look carefully. You missed a mistake! - hint: Check each line on whether they'd need quotation marks or not. + - option: W wierszu 2 brakuje znaków cudzysłowu + feedback: Zmienna nie potrzebuje cudzysłowów + - option: W wierszu 3 brakuje znaków cudzysłowu + feedback: Nie chcesz, aby Hedy dosłownie napisał (print) odpowiedzi {at}{random} , więc nie są tu potrzebne żadne cudzysłowy! + - option: Nic, ten kod jest dobry, jaki jest! + feedback: Patrz uważnie. Przegapiłeś błąd! + hint: Sprawdź każdy wiersz, czy będą potrzebować cudzysłowu, czy nie. correct_answer: A question_score: '10' 8: - question_text: What would be a good next line for this code? + question_text: Jaki byłby dobry następny wiersz dla tego kodu? code: |- {print} 'Welcome at the money show!' {print} 'In front of you are 3 doors' @@ -781,12 +781,12 @@ levels: ``` {print} So you pick door door ``` - feedback: We need quotation marks + feedback: Potrzebujemy cudzysłowów - option: |- ``` {print} 'So you pick ' door door ``` - feedback: If the player chooses door 3, Hedy will say 'So you pick 3 3 + feedback: Jeśli gracz wybierze drzwi 3, Hedy powie „Więc wybierałeś 3 3 - option: |- ``` {print} 'So you pick door ' door diff --git a/grammars/keywords-ru.lark b/grammars/keywords-ru.lark index 783fcc8bc49..8c1bac4fd05 100644 --- a/grammars/keywords-ru.lark +++ b/grammars/keywords-ru.lark @@ -5,7 +5,7 @@ _DEF: ("def" | "def") _SPACE? _RETURN: ("вернуть" | "return") _SPACE? _PRINT: ("печатать" | "print") _SPACE? _PLAY: ("play" | "play") _SPACE -_ASK: ("запросить" | "ask") +_ASK: ("спросить" | "ask") _ECHO: ("повторить" | "echo") _SPACE? _FORWARD: ("вперёд" | "forward") _SPACE? _TURN: ("повернуть" | "turn") _SPACE? diff --git a/grammars/keywords-sr.lark b/grammars/keywords-sr.lark index 87996c35bf0..f70fc846881 100644 --- a/grammars/keywords-sr.lark +++ b/grammars/keywords-sr.lark @@ -1,54 +1,54 @@ -_DEFINE: ("definiši" | "define") _SPACE? -_CALL: ("call" | "call") _SPACE? -_WITH: ("sa" | "with") _SPACE? -_DEF: ("def" | "def") _SPACE? -_RETURN: ("vrati" | "return") _SPACE? -_PRINT: ("štampaj" | "print") _SPACE? -_PLAY: ("play" | "play") _SPACE -_ASK: ("pitaj" | "ask") -_ECHO: ("pokaži" | "echo") _SPACE? -_FORWARD: ("napred" | "forward") _SPACE? -_TURN: ("okreni" | "turn") _SPACE? -left: ("levo" | "left") _SPACE? -right: ("desno" | "right") _SPACE? -black: ("crna" | "black") _SPACE? -blue: ("plava" | "blue") _SPACE? -brown: ("braon" | "brown") _SPACE? -gray: ("siva" | "gray") _SPACE? -green: ("zelena" | "green") _SPACE? -orange: ("narandžasta" | "orange") _SPACE? -pink: ("roze" | "pink") _SPACE? -purple: ("ljubičasta" | "purple") _SPACE? -red: ("crvena" | "red") _SPACE? -white: ("bela" | "white") _SPACE? -yellow: ("žuta" | "yellow") _SPACE? -_IS: _SPACE ("je" | "is") _SPACE -_STANDALONE_IS: ("je" | "is") -_SLEEP: ("spavanje" | "sleep") _SPACE? -_ADD_LIST: ("dodaj" | "add") _SPACE -_TO_LIST: _SPACE? ("u" | "to") _SPACE -_REMOVE: ("obriši" | "remove") _SPACE -_FROM: _SPACE? ("od" | "from") _SPACE -_AT: _SPACE ("na" | "at") _SPACE -random: ("nasumično" | "random") _SPACE? -_IN: _SPACE ("u" | "in") _SPACE -_NOT_IN: _SPACE ("ne/nije u" | "not in") _SPACE -_IF: ("ako" | "if") _SPACE -_ELSE: "inače" | "else" -_AND: _SPACE? ("i" | "and") _SPACE -_REPEAT: ("ponovi" | "repeat") _SPACE -_TIMES: _SPACE ("vremena" | "times") -_FOR: ("za" | "for") _SPACE -_RANGE: ("opseg" | "range") _SPACE? -_TO: _SPACE ("u" | "to") _SPACE -_STEP: "korak" | "step" -_ELIF: _SPACE? ("inače ako" | "elif") _SPACE -_INPUT: ("ulaz" | "input") -_OR: _SPACE? ("ili" | "or") _SPACE -_WHILE: ("dok" | "while") _SPACE -_LENGTH: "dužina" | "length" -_COLOR : ("boja" | "color") _SPACE? -_PRESSED: ("pritisnuto" | "pressed") _SPACE? -clear: ("očisti" | "clear") _SPACE? -TRUE: ("true" | "True" | "true" | "True") _SPACE? -FALSE: ("false" | "False" | "false" | "False") _SPACE? +_DEFINE: ("дефиниши" | "define") _SPACE? +_CALL: ("позови" | "call") _SPACE? +_WITH: ("са" | "with") _SPACE? +_DEF: ("деф" | "def") _SPACE? +_RETURN: ("врати" | "return") _SPACE? +_PRINT: ("штампај" | "print") _SPACE? +_PLAY: ("играј" | "play") _SPACE +_ASK: ("питај" | "ask") +_ECHO: ("покажи" | "echo") _SPACE? +_FORWARD: ("напред" | "forward") _SPACE? +_TURN: ("окрени" | "turn") _SPACE? +left: ("лево" | "left") _SPACE? +right: ("десно" | "right") _SPACE? +black: ("црна" | "black") _SPACE? +blue: ("плава" | "blue") _SPACE? +brown: ("браон" | "brown") _SPACE? +gray: ("сива" | "gray") _SPACE? +green: ("зелена" | "green") _SPACE? +orange: ("наранџаста" | "orange") _SPACE? +pink: ("розе" | "pink") _SPACE? +purple: ("љубичаста" | "purple") _SPACE? +red: ("црвена" | "red") _SPACE? +white: ("бела" | "white") _SPACE? +yellow: ("жута" | "yellow") _SPACE? +_IS: _SPACE ("је" | "is") _SPACE +_STANDALONE_IS: ("је" | "is") +_SLEEP: ("спавање" | "sleep") _SPACE? +_ADD_LIST: ("додај" | "add") _SPACE +_TO_LIST: _SPACE? ("до" | "to") _SPACE +_REMOVE: ("обриши" | "remove") _SPACE +_FROM: _SPACE? ("од" | "from") _SPACE +_AT: _SPACE ("на" | "at") _SPACE +random: ("насумично" | "random") _SPACE? +_IN: _SPACE ("у" | "in") _SPACE +_NOT_IN: _SPACE ("не/није у" | "not in") _SPACE +_IF: ("ако" | "if") _SPACE +_ELSE: "иначе" | "else" +_AND: _SPACE? ("и" | "and") _SPACE +_REPEAT: ("понови" | "repeat") _SPACE +_TIMES: _SPACE ("пута" | "times") +_FOR: ("за" | "for") _SPACE +_RANGE: ("опсег" | "range") _SPACE? +_TO: _SPACE ("до" | "to") _SPACE +_STEP: "корак" | "step" +_ELIF: _SPACE? ("иначе ако" | "elif") _SPACE +_INPUT: ("улаз" | "input") +_OR: _SPACE? ("или" | "or") _SPACE +_WHILE: ("док" | "while") _SPACE +_LENGTH: "дужина" | "length" +_COLOR : ("боја" | "color") _SPACE? +_PRESSED: ("притиснуто" | "pressed") _SPACE? +clear: ("очисти" | "clear") _SPACE? +TRUE: ("тачно" | "Тачно" | "true" | "True") _SPACE? +FALSE: ("нетачно" | "Нетачно" | "false" | "False") _SPACE? diff --git a/grammars/keywords-zun.lark b/grammars/keywords-zun.lark deleted file mode 100644 index 2f844c60471..00000000000 --- a/grammars/keywords-zun.lark +++ /dev/null @@ -1,54 +0,0 @@ -_DEFINE: ("define" | "define") _SPACE? -_CALL: ("call" | "call") _SPACE? -_WITH: ("with" | "with") _SPACE? -_DEF: ("def" | "def") _SPACE? -_RETURN: ("return" | "return") _SPACE? -_PRINT: ("print" | "print") _SPACE? -_PLAY: ("play" | "play") _SPACE -_ASK: ("ask" | "ask") -_ECHO: ("echo" | "echo") _SPACE? -_FORWARD: ("forward" | "forward") _SPACE? -_TURN: ("turn" | "turn") _SPACE? -left: ("left" | "left") _SPACE? -right: ("right" | "right") _SPACE? -black: ("black" | "black") _SPACE? -blue: ("blue" | "blue") _SPACE? -brown: ("brown" | "brown") _SPACE? -gray: ("gray" | "gray") _SPACE? -green: ("green" | "green") _SPACE? -orange: ("orange" | "orange") _SPACE? -pink: ("pink" | "pink") _SPACE? -purple: ("purple" | "purple") _SPACE? -red: ("red" | "red") _SPACE? -white: ("white" | "white") _SPACE? -yellow: ("yellow" | "yellow") _SPACE? -_IS: _SPACE ("is" | "is") _SPACE -_STANDALONE_IS: ("is" | "is") -_SLEEP: ("sleep" | "sleep") _SPACE? -_ADD_LIST: ("add" | "add") _SPACE -_TO_LIST: _SPACE? ("to" | "to") _SPACE -_REMOVE: ("remove" | "remove") _SPACE -_FROM: _SPACE? ("from" | "from") _SPACE -_AT: _SPACE ("at" | "at") _SPACE -random: ("random" | "random") _SPACE? -_IN: _SPACE ("in" | "in") _SPACE -_NOT_IN: _SPACE ("not in" | "not in") _SPACE -_IF: ("if" | "if") _SPACE -_ELSE: "else" | "else" -_AND: _SPACE? ("and" | "and") _SPACE -_REPEAT: ("repeat" | "repeat") _SPACE -_TIMES: _SPACE ("times" | "times") -_FOR: ("for" | "for") _SPACE -_RANGE: ("range" | "range") _SPACE? -_TO: _SPACE ("to" | "to") _SPACE -_STEP: "step" | "step" -_ELIF: _SPACE? ("elif" | "elif") _SPACE -_INPUT: ("input" | "input") -_OR: _SPACE? ("or" | "or") _SPACE -_WHILE: ("while" | "while") _SPACE -_LENGTH: "length" | "length" -_COLOR : ("color" | "color") _SPACE? -_PRESSED: ("pressed" | "pressed") _SPACE? -clear: ("clear" | "clear") _SPACE? -TRUE: ("true" | "True" | "true" | "True") _SPACE? -FALSE: ("false" | "False" | "false" | "False") _SPACE? diff --git a/grammars/level4-Additions.lark b/grammars/level4-Additions.lark index d115554f41b..a716ff75a82 100644 --- a/grammars/level4-Additions.lark +++ b/grammars/level4-Additions.lark @@ -21,9 +21,6 @@ list_access: var_access _AT (INT | random | var_access) // anything can be parsed except for a newline, a space and a list separator textwithoutspaces: /([^\n،,,、 ]+)/ -> text - - - -quoted_text: (/'((?:[^\\']|\\.)*)'/ | /"((?:[^\\"]|\\.)*)"/ | /‘((?:[^\\‘]|\\.)*)’/ | /“((?:[^\\”]|\\.)*)”/ | /«((?:[^\\»]|\\.)*)»/ | /„((?:[^\\“]|\\.)*)“/ ) -> text //text can be between single or double quotes, but quotes may be escaped with \ +quoted_text: (/'((?:[^\\']|\\.)*)'/ | /"((?:[^\\"]|\\.)*)"/ | /‘((?:[^\\‘]|\\.)*)’/ | /“((?:[^\\”]|\\.)*)”/ | /„((?:[^\\“”]|\\.)*)[“”]/ | /”((?:[^\\”]|\\.)*)”/ | /«((?:[^\\»]|\\.)*)»/ | /《((?:[^\\》]|\\.)*)》/ | /「((?:[^\\」]|\\.)*)」/ ) -> text //text can be between single or double quotes, but quotes may be escaped with \ diff --git a/hedy.py b/hedy.py index b2f602d72d4..121ff774a9d 100644 --- a/hedy.py +++ b/hedy.py @@ -520,11 +520,84 @@ class LookupEntry: name: str tree: Tree definition_line: int - access_line: int skip_hashing: bool + access_line: int = None type_: str = None currently_inferring: bool = False # used to detect cyclic type inference + def is_func(self): + return '(' in self.name and '[' not in self.name + + def is_var(self): + return '(' not in self.name and '[' not in self.name + + +class LookupTable: + """The lookup table has a naive implementation of scopes: the start and end lines of every local scope is stored + in a list. Everything else falls in the global scope. Since local scopes cannot be nested, every line in the + code could either belong to one local scope or the global scope.""" + + def __init__(self, local_scopes, entries): + self.local_scopes = local_scopes + self.entries = entries + self.__local_scopes = local_scopes + self.__entries = entries + + def get_all(self): + return self.__entries + + def get_only_vars(self): + """Returns entries which do not represent list access or function definitions""" + return [e for e in self.__entries if e.is_var()] + + def get_all_in_scope(self, access_line): + """Returns the lookup entries for the scope of the given access line.""" + def get_matching_local_scope(line): + for (s, e) in self.__local_scopes: + if s <= line <= e: + return s, e + return None + + def in_global_scope(line): + return not [s for (s, e) in self.__local_scopes if s <= line <= e] + + def is_func_definition(entry): + return entry.is_func() and entry.definition_line in [s for (s, _) in self.__local_scopes] + + local_scope = get_matching_local_scope(access_line) + if local_scope: + start, end = local_scope + # if the variable is in local scope, return the whole local scope combined + # with the part of the global scope defined before the local scope + loc = [e for e in self.__entries if start <= e.definition_line <= end] + glo = [e for e in self.__entries if e.definition_line < start and in_global_scope(e.definition_line)] + return loc + glo + + # if the variable is in the global scope, return the whole global scope + # combined with the function definitions + glo = [e for e in self.__entries if in_global_scope(e.definition_line)] + funcs = [e for e in self.__entries if is_func_definition(e)] + return glo + funcs + + def get_matching(self, var, access_line): + """Returns the lookup entries that match the provided variable name. The access_line is needed to determine + the scope in which the variable is used. Note that in the lookup table, variables are escaped but functions + are not. In other words, the variable `sum` is stored as `_sum`, but the function `sum` is stored as `sum()`. + When calling this method, don't escape func names. """ + + def escape(arg): + arg = str(arg) + letter_or_underscore = r"[\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}_]" + letter_or_numeral = r"[\p{Mn}\p{Mc}\p{Nd}\p{Pc}·]" + var_regex = fr"{letter_or_underscore}({letter_or_underscore}|{letter_or_numeral})*" + function_regex = fr"{var_regex}\(" + if regex.match(function_regex, arg): + return escape_var(arg.split('(')[0]) + return escape_var(arg) + + entries_in_scope = self.get_all_in_scope(access_line) + return [entry for entry in entries_in_scope if escape(entry.name) == escape(var)] + class TypedTree(Tree): def __init__(self, data, children, meta, type_): @@ -588,7 +661,8 @@ class LookupEntryCollector(visitors.Visitor): def __init__(self, level): super().__init__() self.level = level - self.lookup = [] + self.local_scopes = [] + self.lookup_entries = [] def ask(self, tree): # in level 1 there is no variable name on the left side of the ask command @@ -612,8 +686,10 @@ def input(self, tree): # corresponding_lookup_entry.access_line = tree.meta.line def assign(self, tree): - var_name = tree.children[0].children[0] - self.add_to_lookup(var_name, tree.children[1], tree.meta.line) + # when the left-hand-side is a list access, let the 'list_access' child visit to add an entry to the lookup + if tree.children[0].data != 'list_access': + var_name = tree.children[0].children[0] + self.add_to_lookup(var_name, tree.children[1], tree.meta.line) def assign_list(self, tree): var_name = tree.children[0].children[0] @@ -659,7 +735,9 @@ def for_loop(self, tree): self.add_to_lookup(iterator, trimmed_tree, tree.meta.line) def define(self, tree): - self.add_to_lookup(str(tree.children[0].children[0]) + "()", tree, tree.meta.line) + func_name = str(tree.children[0].children[0]) + self.add_local_scope(func_name, tree.meta.line, tree.meta.end_line) + self.add_to_lookup(func_name + "()", tree, tree.meta.line) # add arguments to lookup if tree.children[1].data == 'arguments': @@ -668,21 +746,18 @@ def define(self, tree): def call(self, tree): function_name = tree.children[0].children[0] - names = [x.name for x in self.lookup] + names = [x.name for x in self.lookup_entries] if function_name + "()" not in names: raise exceptions.UndefinedFunctionException(function_name, tree.meta.line) - args_str = "" - if len(tree.children) > 1: - args_str = ", ".join(str(x.children[0]) if isinstance(x, Tree) else str(x) - for x in tree.children[1].children) - self.add_to_lookup(f"{function_name}({args_str})", tree, tree.meta.line) - - def add_to_lookup(self, name, tree, definition_line=None, access_line=None, skip_hashing=False): - entry = LookupEntry(name, tree, definition_line, access_line, skip_hashing) + def add_to_lookup(self, name, tree, definition_line, skip_hashing=False): + entry = LookupEntry(name, tree, definition_line, skip_hashing) hashed_name = escape_var(entry) entry.name = hashed_name - self.lookup.append(entry) + self.lookup_entries.append(entry) + + def add_local_scope(self, scope_name, start_line, end_line): + self.local_scopes.append((start_line, end_line)) # The transformer traverses the whole AST and infers the type of each node. It alters the lookup table entries with @@ -703,7 +778,7 @@ def print(self, tree): def ask(self, tree): if self.level > 1: - self.save_type_to_lookup(tree.children[0].children[0], HedyType.input) + self.save_type_to_lookup(tree.children[0].children[0], tree.meta.line, HedyType.input) self.validate_args_type_allowed(Command.ask, tree.children[1:], tree.meta) return self.to_typed_tree(tree, HedyType.input) @@ -736,7 +811,7 @@ def sleep(self, tree): def assign(self, tree): try: type_ = self.get_type(tree.children[1]) - self.save_type_to_lookup(tree.children[0].children[0], type_) + self.save_type_to_lookup(tree.children[0].children[0], tree.meta.line, type_) except hedy.exceptions.UndefinedVarException as ex: if self.level >= 12: raise hedy.exceptions.UnquotedAssignTextException( @@ -748,7 +823,7 @@ def assign(self, tree): return self.to_typed_tree(tree, HedyType.none) def assign_list(self, tree): - self.save_type_to_lookup(tree.children[0].children[0], HedyType.list) + self.save_type_to_lookup(tree.children[0].children[0], tree.meta.line, HedyType.list) return self.to_typed_tree(tree, HedyType.list) def list_access(self, tree): @@ -760,7 +835,7 @@ def list_access(self, tree): else: # We want list access to be 1-based instead of 0-based, hence the -1 name = f'{list_name}.data[int({tree.children[1]})-1]' - self.save_type_to_lookup(name, HedyType.any) + self.save_type_to_lookup(name, tree.meta.line, HedyType.any) return self.to_typed_tree(tree, HedyType.any) @@ -798,7 +873,7 @@ def for_list(self, tree): command = Command.for_list allowed_types = get_allowed_types(command, self.level) self.check_type_allowed(command, allowed_types, tree.children[1], tree.meta) - self.save_type_to_lookup(tree.children[0].children[0], HedyType.any) + self.save_type_to_lookup(tree.children[0].children[0], tree.meta.line, HedyType.any) return self.to_typed_tree(tree, HedyType.none) def for_loop(self, tree): @@ -809,7 +884,7 @@ def for_loop(self, tree): self.check_type_allowed(command, allowed_types, tree.children[2], tree.meta) iterator = str(tree.children[0]) - self.save_type_to_lookup(iterator, start_type) + self.save_type_to_lookup(iterator, tree.meta.line, start_type) return self.to_typed_tree(tree, HedyType.none) @@ -945,7 +1020,7 @@ def get_type(self, tree): # So, if it cannot be found in the lookup table, then it is an undefined variable for sure. if tree.data in ['var_access', 'var_access_print']: var_name = tree.children[0] - in_lookup, type_in_lookup = self.try_get_type_from_lookup(var_name) + in_lookup, type_in_lookup = self.try_get_type_from_lookup(var_name, tree.meta.line) if in_lookup: return type_in_lookup else: @@ -954,7 +1029,7 @@ def get_type(self, tree): # TypedTree with type 'None' and 'string' could be in the lookup because of the grammar definitions # If the tree has more than 1 child, then it is not a leaf node, so do not search in the lookup if tree.type_ in [HedyType.none, HedyType.string] and len(tree.children) == 1: - in_lookup, type_in_lookup = self.try_get_type_from_lookup(tree.children[0]) + in_lookup, type_in_lookup = self.try_get_type_from_lookup(tree.children[0], tree.meta.line) if in_lookup: return type_in_lookup # If the value is not in the lookup or the type is other than 'None' or 'string', return evaluated type @@ -965,7 +1040,7 @@ def get_var_access_error(self, tree, var_name): if tree.data == 'var_access_print': # is there a variable that is mildly similar? if so, we probably meant that one minimum_distance_allowed = 4 - for var_in_lookup in self.lookup: + for var_in_lookup in self.lookup.get_all_in_scope(tree.meta.line): if calculate_minimum_distance(var_in_lookup.name, var_name) <= minimum_distance_allowed: raise hedy.exceptions.UndefinedVarException(name=var_name, line_number=tree.meta.line) @@ -979,10 +1054,9 @@ def get_var_access_error(self, tree, var_name): def ignore_type(self, type_): return type_ in [HedyType.any, HedyType.none] - def save_type_to_lookup(self, name, inferred_type): - for entry in self.lookup: - if entry.name == escape_var(name): - entry.type_ = inferred_type + def save_type_to_lookup(self, name, line, inferred_type): + for entry in self.lookup.get_matching(name, line): + entry.type_ = inferred_type # Usually, variable definitions are sequential and by the time we need the type of a lookup entry, it would already # be inferred. However, there are valid cases in which the lookup entries will be accessed before their type @@ -992,8 +1066,8 @@ def save_type_to_lookup(self, name, inferred_type): # In the above case, we visit `print i`, before the definition of i in the for cycle. In this case, the tree of # lookup entry is used to infer the type and continue the started validation. This approach might cause issues # in case of cyclic references, e.g. b is b + 1. The flag `inferring` is used as a guard against these cases. - def try_get_type_from_lookup(self, name): - matches = [entry for entry in self.lookup if entry.name == escape_var(name)] + def try_get_type_from_lookup(self, name, access_line): + matches = self.lookup.get_matching(name, access_line) if matches: match = matches[0] if not match.type_: @@ -1172,20 +1246,16 @@ def all_commands(input_string, level, lang='en'): def all_variables(input_string, level, lang='en'): - """Return all variables used in a program string. - - This function is still used by the roles of variables detection - """ + """ Return all variables used in a program string. + This function is still used by the roles of variables detection """ program_root = parse_input(input_string, level, lang) abstract_syntax_tree = ExtractAST().transform(program_root) - vars = set() + lookup = create_lookup_table(abstract_syntax_tree, level, lang, input_string) - for x in lookup: - name = str(x.name) - if '[' not in name: # we also stor list access but that is not needed here - vars.add(name) - return list(vars) + # list access and functions are intentionally omitted here + variables = [str(v.name) for v in lookup.get_only_vars()] + return list(set(variables)) @v_args(meta=True) @@ -1429,12 +1499,16 @@ def process_characters_needing_escape(value): supported_quotes = { - "'": "'", # single straight quotation marks - '"': '"', # double straight quotation marks - '‘': '’', # single curved quotation marks - "“": "”", # double curved quotation marks or English quotes - "„": "“", # inward double curved quotation marks or German quotes - "«": "»", # guillemets or double angular marks or French quotes + "'": ["'"], # single straight quotation marks + '"': ['"'], # double straight quotation marks + '‘': ['’'], # single curved quotation marks + "“": ["”"], # double curved quotation marks or English quotes + "„": ["“", # inward double curved quotation marks or German quotes + "”"], # rightward double curved quotation marks or Polish quotes + '”': ['”'], # rightward double curved quotation marks or Swedish/Finish quotes + "«": ["»"], # guillemets or double angular marks or French quotes + "《": ["》"], # Korean quotes + "「": ["」"], # Japanese quotes } @@ -1452,7 +1526,7 @@ def find_unquoted_segments(s): used_quote = c result += segment segment = c - elif used_quote and c == supported_quotes[used_quote]: + elif used_quote and c in supported_quotes[used_quote]: # if this is a valid closing quote, then empty the buffer as it holds a correctly quoted segment used_quote = None segment = '' @@ -1555,22 +1629,6 @@ def get_fresh_var(self, name): name = '_' + name return name - def get_var_lookup_entries(self, var): - """ Returns the lookup entries that match the provided variable name. Note that in the lookup table, variables - are escaped but functions are not. In other words, the variable `sum` is stored as `_sum`, but the function - `sum` is stored as `sum()`. When calling this method, don't escape func names. """ - def escape(arg): - arg = str(arg) - letter_or_underscore = r"[\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}_]" - letter_or_numeral = r"[\p{Mn}\p{Mc}\p{Nd}\p{Pc}·]" - var_regex = fr"{letter_or_underscore}({letter_or_underscore}|{letter_or_numeral})*" - function_regex = fr"{var_regex}\(" - if regex.match(function_regex, arg): - return escape_var(arg.split('(')[0]) - return escape_var(arg) - - return [entry for entry in self.lookup if escape(entry.name) == escape(var)] - def is_var_defined_before_access(self, var, access_line, var_to_escape=''): """ Returns true if a variable is defined before being accessed. The `var_to_escape` parameter allows the ask command to force the left-hand-side variable to not be defined on the same line.""" @@ -1580,7 +1638,7 @@ def is_before(entry, line): else: return entry.definition_line < line - matching_lookup_entries = self.get_var_lookup_entries(var) + matching_lookup_entries = self.lookup.get_matching(var, access_line) return any([e for e in matching_lookup_entries if is_before(e, access_line)]) def is_variable(self, arg, access_line=100): @@ -1593,7 +1651,7 @@ def is_variable(self, arg, access_line=100): max lines of Hedy code. So, if it is not provided, there is no check on whether the var is defined.""" # Unpacking is needed because sometimes a var reference is parsed as 'text' and transpiled to a LiteralValue var = self.unpack(arg) - entries = self.get_var_lookup_entries(var) + entries = self.lookup.get_matching(var, access_line) if entries: if not self.is_var_defined_before_access(var, access_line): raise hedy.exceptions.AccessBeforeAssignException(var, access_line, entries[0].definition_line) @@ -1674,7 +1732,7 @@ def process_arg_for_fstring(self, arg, access_line=100, var_to_escape=''): print What is your favorite color? In the print statement, `color` is not a var reference, but the literal string 'color'""" - matching_entries = self.get_var_lookup_entries(arg) + matching_entries = self.lookup.get_matching(arg, access_line) is_list = [e for e in matching_entries if e.type_ == HedyType.list and '[' not in e.name] is_var = not is_list and self.is_var_defined_before_access(arg, access_line, var_to_escape) @@ -2094,7 +2152,7 @@ class ConvertToPython_4(ConvertToPython_3): def process_arg_for_fstring(self, name, access_line=100, var_to_escape=''): name = escape_var(self.unpack(name)) - if self.is_variable(name): + if self.is_variable(name, access_line): return f"{{{name}}}" if is_quoted(name): @@ -2246,7 +2304,7 @@ def if_pressed(): points = points + 1 """ lines = lines if isinstance(lines, list) else [lines] - variables = [e.name for e in self.lookup if '(' not in e.name and '[' not in e.name] + variables = [e.name for e in self.lookup.get_only_vars()] if variables and lines: variables = sorted(list(set(variables))) global_vars = f"global {', '.join(variables)}" @@ -2330,7 +2388,7 @@ def play(self, meta, args): time.sleep(0.5)""") + self.add_debug_breakpoint() def process_arg_for_fstring(self, name, access_line=100, var_to_escape=''): - if self.is_variable(name) or self.is_list(name) or self.is_random(name): + if self.is_variable(name, access_line) or self.is_list(name) or self.is_random(name): return f"{{{escape_var(self.unpack(name))}}}" elif isinstance(name, LiteralValue): return self.process_literal_for_fstring(name) @@ -2371,6 +2429,12 @@ def process_arg_for_data_access(self, arg, access_line=100, use_var_value=True): val = arg[1:-1] if is_quoted(arg) else arg return f"'{process_characters_needing_escape(str(val))}'" + def process_arg_for_func(self, arg, access_line): + if self.is_variable_with_definition(arg, access_line): + var_name = escape_var(self.unpack(arg)) + return f"{var_name}" + return self.process_assign_argument(arg) + def assign(self, meta, args): left_hand_side = args[0] right_hand_side = args[1] @@ -2833,7 +2897,7 @@ def process_print_ask_args(self, args, meta, var_to_escape=''): return result def process_arg_for_fstring(self, name, access_line=100, var_to_escape=''): - if self.is_variable(name) or self.is_list(name) or self.is_random(name): + if self.is_variable(name, access_line) or self.is_list(name) or self.is_random(name): return f"{{{escape_var(self.unpack(name))}}}" elif isinstance(name, LiteralValue): return self.process_literal_for_fstring(name) @@ -3017,8 +3081,8 @@ def call(self, meta, args): function_name = self.unpack(args[0]) self.try_register_variable_access(function_name, meta.line) - function_tree = [e.tree for e in self.lookup if e.name == function_name + "()"] - tree_arguments = [c for c in function_tree[0].children if c.data == 'arguments'] + function_tree = self.lookup.get_matching(function_name, meta.line) + tree_arguments = [c for c in function_tree[0].tree.children if c.data == 'arguments'] number_of_defined_arguments = 0 if tree_arguments == [] else len(tree_arguments[0].children) number_of_used_arguments = 0 if len(args) == 1 else len(args[1].children) @@ -3032,7 +3096,7 @@ def call(self, meta, args): if len(args) > 1: flat_args = [x.children[0] if isinstance(x, Tree) else x for x in args[1].children] - args_str = ", ".join([self.process_assign_argument(a) for a in flat_args]) + args_str = ", ".join([self.process_arg_for_func(a, meta.line) for a in flat_args]) for a in args[1].children: self.try_register_variable_access(str(self.unpack(a)), meta.line) else: @@ -3163,7 +3227,7 @@ def change_list_item(self, meta, args): index = self.unpack(args[1]) self.check_variable_usage_and_definition(args[0:3], meta.line) - index = f'{index}.data' if self.is_variable(args[1]) else index + index = f'{index}.data' if self.is_variable(args[1], meta.line) else index left_side = f'{name}.data[int({index})-1]' right_side = self.process_literal_to_value(args[2]) if isinstance(args[2], LiteralValue) else args[2] @@ -3951,11 +4015,11 @@ def is_program_complete(abstract_syntax_tree, level): def create_lookup_table(abstract_syntax_tree, level, lang, input_string): visitor = LookupEntryCollector(level) visitor.visit_topdown(abstract_syntax_tree) - entries = visitor.lookup + lookup_table = LookupTable(visitor.local_scopes, visitor.lookup_entries) - TypeValidator(entries, level, lang, input_string).transform(abstract_syntax_tree) + TypeValidator(lookup_table, level, lang, input_string).transform(abstract_syntax_tree) - return entries + return lookup_table def create_AST(input_string, level, lang="en"): @@ -3981,16 +4045,16 @@ def determine_roles(lookup, input_string, level, lang): all_vars = all_variables(input_string, level, lang) roles_dictionary = {} for var in all_vars: - assignments = [x for x in lookup if x.name == var] + assignments = [x for x in lookup.get_all() if x.name == var] - if (assignments[0].tree.data == 'for_list'): + if assignments[0].tree.data == 'for_list': roles_dictionary[var] = gettext('walker_variable_role') - elif (assignments[0].tree.data == 'for_loop'): + elif assignments[0].tree.data == 'for_loop': roles_dictionary[var] = gettext('stepper_variable_role') - elif (assignments[0].type_ == 'list'): + elif assignments[0].type_ == 'list': roles_dictionary[var] = gettext('list_variable_role') - elif (len(assignments) == 1): - if (assignments[0].type_ == 'input'): + elif len(assignments) == 1: + if assignments[0].type_ == 'input': roles_dictionary[var] = gettext('input_variable_role') else: roles_dictionary[var] = gettext('constant_variable_role') @@ -4037,7 +4101,7 @@ def transpile_inner(input_string, level, lang="en", populate_source_map=False, i source_map.set_python_output(python) if not unused_allowed: - for x in lookup_table: + for x in lookup_table.get_all(): if isinstance(x.name, str) and x.access_line is None and x.name != 'x__x__x__x': x.name = re.sub(r'^_', '', x.name) raise hedy.exceptions.UnusedVariableException( diff --git a/hedy_grammar.py b/hedy_grammar.py index e7012e7295e..2d38018f420 100644 --- a/hedy_grammar.py +++ b/hedy_grammar.py @@ -2,7 +2,7 @@ import warnings from os import path from functools import cache -from hedy_translation import keywords_to_dict +import hedy_translation """ Because of the gradual nature of Hedy, the grammar of every level is just slightly different than the grammar of the @@ -271,7 +271,7 @@ def expand_keyword_not_followed_by_space(**kwargs): def get_translated_keyword(keyword, lang): def get_keyword_value_from_lang(keyword_, lang_): - keywords = keywords_to_dict(lang_) + keywords = hedy_translation.keywords_to_dict(lang_) if keyword_ in keywords: return [k for k in keywords[keyword_] if k] else: diff --git a/highlighting/highlighting-trad.json b/highlighting/highlighting-trad.json index 197fd169ec3..02e96e6df04 100644 --- a/highlighting/highlighting-trad.json +++ b/highlighting/highlighting-trad.json @@ -2364,7 +2364,7 @@ "True": "Истина|True", "add": "добавить|add", "and": "и|and", - "ask": "запросить|ask", + "ask": "спросить|ask", "at": "в|at", "black": "чёрный|black", "blue": "синий|blue", @@ -2537,62 +2537,62 @@ "DIGIT": "0123456789" }, "sr": { - "False": "False", - "True": "True", - "add": "dodaj|add", - "and": "i|and", - "ask": "pitaj|ask", - "at": "na|at", - "black": "crna|black", - "blue": "plava|blue", - "brown": "braon|brown", - "call": "call", - "clear": "očisti|clear", - "color": "boja|color", + "False": "Нетачно|False", + "True": "Тачно|True", + "add": "додај|add", + "and": "и|and", + "ask": "питај|ask", + "at": "на|at", + "black": "црна|black", + "blue": "плава|blue", + "brown": "браон|brown", + "call": "позови|call", + "clear": "очисти|clear", + "color": "боја|color", "comma": ",", - "def": "def", - "define": "definiši|define", - "echo": "pokaži|echo", - "elif": "inače ako|elif", - "else": "inače|else", - "false": "false", - "for": "za|for", - "forward": "napred|forward", - "from": "od|from", - "gray": "siva|gray", - "green": "zelena|green", - "if": "ako|if", - "in": "u|in", - "input": "ulaz|input", - "is": "je|is", - "left": "levo|left", - "length": "dužina|length", - "not_in": "ne/nije u|not in", - "or": "ili|or", - "orange": "narandžasta|orange", - "pink": "roze|pink", - "play": "play", - "pressed": "pritisnuto|pressed", - "print": "štampaj|print", - "purple": "ljubičasta|purple", - "random": "nasumično|random", - "range": "opseg|range", - "red": "crvena|red", - "remove": "obriši|remove", - "repeat": "ponovi|repeat", - "return": "vrati|return", - "right": "desno|right", - "sleep": "spavanje|sleep", - "step": "korak|step", - "times": "vremena|times", - "to": "u|to", - "to_list": "u|to", - "true": "true", - "turn": "okreni|turn", - "while": "dok|while", - "white": "bela|white", - "with": "sa|with", - "yellow": "žuta|yellow", + "def": "деф|def", + "define": "дефиниши|define", + "echo": "покажи|echo", + "elif": "иначе ако|elif", + "else": "иначе|else", + "false": "нетачно|false", + "for": "за|for", + "forward": "напред|forward", + "from": "од|from", + "gray": "сива|gray", + "green": "зелена|green", + "if": "ако|if", + "in": "у|in", + "input": "улаз|input", + "is": "је|is", + "left": "лево|left", + "length": "дужина|length", + "not_in": "не/није у|not in", + "or": "или|or", + "orange": "наранџаста|orange", + "pink": "розе|pink", + "play": "играј|play", + "pressed": "притиснуто|pressed", + "print": "штампај|print", + "purple": "љубичаста|purple", + "random": "насумично|random", + "range": "опсег|range", + "red": "црвена|red", + "remove": "обриши|remove", + "repeat": "понови|repeat", + "return": "врати|return", + "right": "десно|right", + "sleep": "спавање|sleep", + "step": "корак|step", + "times": "пута|times", + "to": "до|to", + "to_list": "до|to", + "true": "тачно|true", + "turn": "окрени|turn", + "while": "док|while", + "white": "бела|white", + "with": "са|with", + "yellow": "жута|yellow", "DIGIT": "0123456789" }, "sv": { diff --git a/package-lock.json b/package-lock.json index 9813e6ef476..c008bf9867e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,8 @@ "version": "0.0.1", "license": "ISC", "dependencies": { - "@ckeditor/ckeditor5-build-classic": "^41.0.0", - "@ckeditor/ckeditor5-code-block": "^41.0.0", + "@ckeditor/ckeditor5-build-classic": "^43.1.1", + "@ckeditor/ckeditor5-code-block": "^43.1.1", "@codemirror/commands": "^6.2.5", "@codemirror/state": "^6.4.0", "@codemirror/theme-one-dark": "^6.1.2", @@ -26,7 +26,7 @@ "chart.js": "^4.4.2", "codemirror": "^6.0.1", "cypress-real-events": "^1.12.0", - "dompurify": "^2.3.5", + "dompurify": "^2.5.4", "istanbul-lib-coverage": "^3.2.0", "jquery-ui-dist": "^1.13.1", "jszip": "^3.10.1", @@ -1852,273 +1852,649 @@ } }, "node_modules/@ckeditor/ckeditor5-adapter-ckfinder": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-adapter-ckfinder/-/ckeditor5-adapter-ckfinder-41.0.0.tgz", - "integrity": "sha512-2N5WqXNtU+5w44t9sasokIxcs1O2dyEutal10UUDdfHL6fyExMibbn0CTPSUhQBWxG8KFawbF0Nqww7BSoXD+A==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-adapter-ckfinder/-/ckeditor5-adapter-ckfinder-43.1.1.tgz", + "integrity": "sha512-DCR98QdQKCYCQFT23CwR6PFLPLT3rlh89++hFIhUpykDz2pljEDC8uFNWjKY+b/5/P/jkTICLtt8+DlF8aN+/Q==", "dependencies": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-upload": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-alignment": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-alignment/-/ckeditor5-alignment-43.1.1.tgz", + "integrity": "sha512-mjQPDmfPgKbMQp8JCR7Vg7MpRax44tSrtyoofSl/oMKDh2bXtwEnMKJlv501scl95S8VN2Pfnxj5+31N89j0Xg==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-autoformat": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-autoformat/-/ckeditor5-autoformat-41.0.0.tgz", - "integrity": "sha512-GxAzOlSarvObBkd+qvy0/fwkNt9x0Pugy8Sh0/7bXDJIkvSXqB4Vecq2l3RA8ATIietW2mD/NYQtu53U1Y8GvQ==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-autoformat/-/ckeditor5-autoformat-43.1.1.tgz", + "integrity": "sha512-/NP29+d5y+AcffZEBJqH42Bj/M76OuBPG3DNEz9XEBbF9ADC9jqb2pYzDgiit/9VukNDtoLJjQ6HGxjdwzdLfg==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-autosave": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-autosave/-/ckeditor5-autosave-43.1.1.tgz", + "integrity": "sha512-GYeEF0NL0KLS33lZ4Uc4R2hAofTH+EE/Pulzg1V0rSIPghLNULsvMRiqe6PnzYDKtD5et1YpaIZRp55DGzJ/gQ==", "dependencies": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-basic-styles": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-basic-styles/-/ckeditor5-basic-styles-41.0.0.tgz", - "integrity": "sha512-5BZnkL0TRbpdyY4Uwj230Aj+iQufO6He/KPlnA5fFglXKG+AyuPubXOY5P5dAX1SOMKpEZ720zSugFTVvM0ErA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-basic-styles/-/ckeditor5-basic-styles-43.1.1.tgz", + "integrity": "sha512-xFfL6JaVkkNRnFET/ld6MGvbifFxJY8bv3zvAAlphXsCBxNDH9cZWzG605PF6SYTucCUXD4dtW0teLMmdzklaQ==", "dependencies": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "ckeditor5": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-block-quote": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-block-quote/-/ckeditor5-block-quote-41.0.0.tgz", - "integrity": "sha512-N3AbHpWllqYVY9/ME2NhQJhJLoZoks8r+7HdhZ7mrSPtOJVdeSN7L9X2LXLIozddQ/zqJXv1oJq5m/qMH9ruTw==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-block-quote/-/ckeditor5-block-quote-43.1.1.tgz", + "integrity": "sha512-VYZlQisRptiiqVRnMVBcwc3yRilpSoFTKiMXTzrYukUZLhPL6fiWVeMe/N9ygtdtGp3oYF/rSNv9H/8e6nNVYw==", "dependencies": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-build-classic": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-build-classic/-/ckeditor5-build-classic-41.0.0.tgz", - "integrity": "sha512-J4Gi1GEGDrZrgOqzKk321Q+LnQ7rTefWqg8DNof5ekRi/09iPweyNWhlSFdPIO6L7UswD7ljoetVjUoB8SqX8w==", - "dependencies": { - "@ckeditor/ckeditor5-adapter-ckfinder": "41.0.0", - "@ckeditor/ckeditor5-autoformat": "41.0.0", - "@ckeditor/ckeditor5-basic-styles": "41.0.0", - "@ckeditor/ckeditor5-block-quote": "41.0.0", - "@ckeditor/ckeditor5-ckbox": "41.0.0", - "@ckeditor/ckeditor5-ckfinder": "41.0.0", - "@ckeditor/ckeditor5-cloud-services": "41.0.0", - "@ckeditor/ckeditor5-easy-image": "41.0.0", - "@ckeditor/ckeditor5-editor-classic": "41.0.0", - "@ckeditor/ckeditor5-essentials": "41.0.0", - "@ckeditor/ckeditor5-heading": "41.0.0", - "@ckeditor/ckeditor5-image": "41.0.0", - "@ckeditor/ckeditor5-indent": "41.0.0", - "@ckeditor/ckeditor5-link": "41.0.0", - "@ckeditor/ckeditor5-list": "41.0.0", - "@ckeditor/ckeditor5-media-embed": "41.0.0", - "@ckeditor/ckeditor5-paragraph": "41.0.0", - "@ckeditor/ckeditor5-paste-from-office": "41.0.0", - "@ckeditor/ckeditor5-table": "41.0.0", - "@ckeditor/ckeditor5-typing": "41.0.0" + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-build-classic/-/ckeditor5-build-classic-43.1.1.tgz", + "integrity": "sha512-yCg+5u2ihdunYxieHsgHWACXbTMQZajy23wtGAuED7Tv+Uf41XPmBmQLoXSY43LyQOeSNvgEFdb6lUrl5Gi05w==", + "dependencies": { + "@ckeditor/ckeditor5-adapter-ckfinder": "43.1.1", + "@ckeditor/ckeditor5-autoformat": "43.1.1", + "@ckeditor/ckeditor5-basic-styles": "43.1.1", + "@ckeditor/ckeditor5-block-quote": "43.1.1", + "@ckeditor/ckeditor5-ckbox": "43.1.1", + "@ckeditor/ckeditor5-ckfinder": "43.1.1", + "@ckeditor/ckeditor5-cloud-services": "43.1.1", + "@ckeditor/ckeditor5-easy-image": "43.1.1", + "@ckeditor/ckeditor5-editor-classic": "43.1.1", + "@ckeditor/ckeditor5-essentials": "43.1.1", + "@ckeditor/ckeditor5-heading": "43.1.1", + "@ckeditor/ckeditor5-image": "43.1.1", + "@ckeditor/ckeditor5-indent": "43.1.1", + "@ckeditor/ckeditor5-link": "43.1.1", + "@ckeditor/ckeditor5-list": "43.1.1", + "@ckeditor/ckeditor5-media-embed": "43.1.1", + "@ckeditor/ckeditor5-paragraph": "43.1.1", + "@ckeditor/ckeditor5-paste-from-office": "43.1.1", + "@ckeditor/ckeditor5-table": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-ckbox": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ckbox/-/ckeditor5-ckbox-41.0.0.tgz", - "integrity": "sha512-8Q8GEs8kBArsWgbOT0c9D33T0AyUCNBcLhV2sHDs4XTg0ldxwDSCkneEJfV5da5ekgp/qacivoF8IVTzjNaHqQ==", - "dependencies": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ckbox/-/ckeditor5-ckbox-43.1.1.tgz", + "integrity": "sha512-2suCDhe5HlutZz52iBXRaVAcht/E4wBdZsF6ZL+hELNuqvYM2PCb2/FZTtxQb50mDlWtJtLidRc49COAr0k1QA==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-upload": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", "blurhash": "2.0.5", - "ckeditor5": "41.0.0", + "ckeditor5": "43.1.1", "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-ckfinder": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ckfinder/-/ckeditor5-ckfinder-41.0.0.tgz", - "integrity": "sha512-IKBkRB84gbLzLMOPnigpBa0WKR0etyIQdsrbD8i7H96fTTNWC0RNxbTyeD0RIbh5/EhJqFQPSds1QnVr5XvHqA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ckfinder/-/ckeditor5-ckfinder-43.1.1.tgz", + "integrity": "sha512-f5N9FtJTSRfEUaJqr0LpekoSAIMktyiwbWeGQhbYseCCV0+Qsw6W/wzuWMFNe5GELg0R/0tG0H59/2m1wTFFbw==", "dependencies": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-clipboard": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-41.0.0.tgz", - "integrity": "sha512-OS0jL9s5P4uFadQYrPkRtx6+KlDkJwMLbQoeEhTpyG4BwF3zf2Q3UE+KdyvULS2er8FtxVu5bx3zeA7DtxYa9w==", - "dependencies": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0", - "@ckeditor/ckeditor5-widget": "41.0.0", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-43.1.1.tgz", + "integrity": "sha512-QF0zyq/NhLFm8V/VBBn+RWjiaAd5eyeCKz7zQKyBcSW27IaazAnG0+HHZeydZkT4vntad71t6bi6ZWzL/MJxwg==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-cloud-services": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-cloud-services/-/ckeditor5-cloud-services-41.0.0.tgz", - "integrity": "sha512-AfsX1ZDYBYUEXzxLiWp9Szl6LIzjNvKFSqsRrY889J2CMmA9LfAcS3tEnXeLqutb9EhcHfpPoSdQLZ3l9UpPew==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-cloud-services/-/ckeditor5-cloud-services-43.1.1.tgz", + "integrity": "sha512-YprETdoRcu/2yxVCuoOrY+f4G0Qus0hIMfMuRZ9jbFWDDwZgHiXrFXvE0W9o9N51rKffWnTbs0GljsaXVit1+g==", "dependencies": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-code-block": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-code-block/-/ckeditor5-code-block-41.0.0.tgz", - "integrity": "sha512-t+HdCrOEiM9oIDFIu+khhRNP/C2K0JTDaChBPx51uFDuwmSGtX35UbaWwEbfXtcZS7NziloTBnD6m+fe9uibeA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-code-block/-/ckeditor5-code-block-43.1.1.tgz", + "integrity": "sha512-Nil+MNeirroHop5Onj23L2v17Jokgc6wvJYqzH+85OvlrJeEsfFauxlW+S6TI3ypZT04yLJ0zdpaZ/FYC5+NxA==", "dependencies": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-core": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-41.0.0.tgz", - "integrity": "sha512-/t4Cl8fxdrjxn4WRobJdRui4WwGUq/qsD3q5W5IzdCQyON1fr+qaDJ4popGfg+MFSNIFFF9/ip5wkgqOexYMOg==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-43.1.1.tgz", + "integrity": "sha512-qtbnD+24dK+ANVUgs+unZ0qX64NA0eG6k344q8fhXuHdPRKk55BDkjdmpv/Fh9Y0beo9EDqUPE/P7agv8lucBg==", "dependencies": { - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-watchdog": "43.1.1", "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-easy-image": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-easy-image/-/ckeditor5-easy-image-41.0.0.tgz", - "integrity": "sha512-DTMpDv4yapvT6bbBLLXvOsJdrn7G8WseIZCrCJWwnaSqH0yQvk/w30fj1MYt6m2lDMmp9Z96/wl/V7tp8QrSRw==", - "dependencies": { - "ckeditor5": "41.0.0" + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-easy-image/-/ckeditor5-easy-image-43.1.1.tgz", + "integrity": "sha512-BSiqxe6rFzNIROz7uny8SyGndQX070hlktJT5sQNO46lB+tsyFScUVXjzduSlm2fCG/2PFA83skR3/7cTAkBbg==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-upload": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-editor-balloon": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-balloon/-/ckeditor5-editor-balloon-43.1.1.tgz", + "integrity": "sha512-hIfocf3a/zXj1SLElF58LIVXOP3GphpajrsNXysSxccb4LNUQjvqMqwYaHDkib0Oh4AznsCwfBE3CJ3grUiI4g==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-editor-classic": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-classic/-/ckeditor5-editor-classic-41.0.0.tgz", - "integrity": "sha512-64E/zrOs6BRSHJ34wIEtRMEOQwceK9TOWZCmXcIqjS+gH7D1O9mCgM3u8wN+Vk/LfHNXNZq/xl27nYG0tHxwww==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-classic/-/ckeditor5-editor-classic-43.1.1.tgz", + "integrity": "sha512-8/yuGbTtY/BF4Oi5wDd9/NHNmIvtb+f5YvqSkG7ZtWy0M+uHru8xM7hhUqUKwrG2jVxB2MFRcDGAE0YlVqs98Q==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-editor-decoupled": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-decoupled/-/ckeditor5-editor-decoupled-43.1.1.tgz", + "integrity": "sha512-Vs7yVUjOM+QiwnS6v987YGen0xwku07pQyhl+ihW6cphJymaJ/kPNvkR2ZCfE5e/Av0ckz14DQj4vOmotx+Vxg==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-editor-inline": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-inline/-/ckeditor5-editor-inline-43.1.1.tgz", + "integrity": "sha512-6rNUJPG23c0Nm4cbb5ReYiARhBk8crdpkYig6sR+8m//ah9SzO0H4H/brHtYHsV6FxOYDwxEJdaMSDP7rWUwkQ==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-editor-multi-root": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-multi-root/-/ckeditor5-editor-multi-root-43.1.1.tgz", + "integrity": "sha512-M1NBPFLZZAVJt22Ipy/JYTeOPPGCRDy3nWnCoBR2U79/FkEQNRyUtkR58EA4dLHdaeAiaWX8w7z2DrLKxOUltw==", "dependencies": { - "ckeditor5": "41.0.0", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-engine": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-41.0.0.tgz", - "integrity": "sha512-SrzyRU4LXkgIFl614Vshciiwq76zbMt3gKR4Gi1xth2Q5jStT2V42KfUJ+aeigD0RevRcOL8X/g/oSXgKudbow==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-43.1.1.tgz", + "integrity": "sha512-gOqbGwEqbJDgbSRM0Dv3ArQRGTmX2pySNdQIseLnENVaq9r5FUu9T2moKYJbGl8t/DIqBAxOtdHQPafrXtk7yg==", "dependencies": { - "@ckeditor/ckeditor5-utils": "41.0.0", + "@ckeditor/ckeditor5-utils": "43.1.1", "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-enter": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-41.0.0.tgz", - "integrity": "sha512-6APFUXOsYcoDVyip2E79gWzE/bmEN1+5eY0ShxJmL4seSD7ipn8TflpGsPjqxe4+bcMBzpfYOcm2wlMxo/Nf6A==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-43.1.1.tgz", + "integrity": "sha512-7JjNCe4qVtiLgnGC8P5WJzcDGTOXzgpos8nPSR52vsqNANNZQ/iAByDoPP7WCIijJHHjeFoBk0ytk2qfXppjkw==", "dependencies": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-essentials": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-essentials/-/ckeditor5-essentials-41.0.0.tgz", - "integrity": "sha512-R80qtyBgPGFDaDsJAF3gqqAAnq8+kLijR1bDsAvHwRY4FN0zhdxfwQOdeIB+OCGBevyYNrJ6MFfX/LSOZj66CA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-essentials/-/ckeditor5-essentials-43.1.1.tgz", + "integrity": "sha512-qbo080qotWmq19SnUkFspT9swHy2160nHFOdtx4LrQtGPbjSzS2EBFNHmkf31gUmEcNZCbegSIl0UT5IvIIV8g==", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-select-all": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-undo": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-find-and-replace": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-find-and-replace/-/ckeditor5-find-and-replace-43.1.1.tgz", + "integrity": "sha512-BmSwyTsL5fAo4I2gRq7gzbU+WNAoaxWOPZCip/cGNdqzV9Utl6kTLx/DdxAhh8B4KTj8Rqv8Cmg1862HMkfKkw==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-font": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-font/-/ckeditor5-font-43.1.1.tgz", + "integrity": "sha512-QQrLf3zWp1T0QttKdFoC/fbEF69hzsHxNzmOeGVwAavgW0qpbpSEvTT5kRHm1tYlGeSR8N6/SVXgb4xHUxwvHg==", "dependencies": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-heading": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-heading/-/ckeditor5-heading-41.0.0.tgz", - "integrity": "sha512-00axXKOHXVDquO6yvQLAmLe4fk3v/x4JK5FHaclIeFILlJvDU5X4r5J2lEK8ClaJ/2EeaLyt+Dnwk/FRpp+0IQ==", - "dependencies": { - "ckeditor5": "41.0.0" + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-heading/-/ckeditor5-heading-43.1.1.tgz", + "integrity": "sha512-Gr4rxChoamevxNf/6DKRYltOcLuCqrqFOCWrOO00JRHN8dHW81TgMJVGf4xeM4bAlFbMSqM3Y2vRCPhtdTAarA==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-paragraph": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-highlight": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-highlight/-/ckeditor5-highlight-43.1.1.tgz", + "integrity": "sha512-hrzzTQ1tAHIUGdNingpyMsrBeb3herfSMXOGylkkTqg/SqtnUlVJbPZ8NVUrmlw6hQQMl7HDqBJGdHoesvB8TA==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-horizontal-line": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-horizontal-line/-/ckeditor5-horizontal-line-43.1.1.tgz", + "integrity": "sha512-FLTTPShC+/E/fAUYAxyMHOLDYCYAAuB3eXHonPekXjiAdkhchPibkIz0c3DgdjRGFhfGE4/XQ4PyU5oa5BKt5w==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-html-embed": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-html-embed/-/ckeditor5-html-embed-43.1.1.tgz", + "integrity": "sha512-ggOFwmpNAiT0nwm/++GZR/9V256mHxA0l7riL422l9YOSToGf5kukemsc7PIifuNoBXCzFrkNipr53ctxZkomA==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-html-support": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-html-support/-/ckeditor5-html-support-43.1.1.tgz", + "integrity": "sha512-eF2eZU6sbU0ml+z8nSd7cDhk3ihrV9R7gih/bWOGvWa94bpaNVOd4c7e3F0ZPQVlxfwT1X99Y7aDNSNcbWs53A==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-image": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-image/-/ckeditor5-image-41.0.0.tgz", - "integrity": "sha512-p7tFXov36cQP3Y3Kyr6Q9a/5BA0Pj5Wq8q0qPb08jpdRb6TCR60WkmiIK9yzSNR3FN4sfq1PG4l4mM4M2MJqaA==", - "dependencies": { - "@ckeditor/ckeditor5-ui": "41.0.0", - "ckeditor5": "41.0.0", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-image/-/ckeditor5-image-43.1.1.tgz", + "integrity": "sha512-6xOJsG9nYIIpwf/Kj0MARts5KK+eZ+awpAvljYgx+xjII4KEAO1dKSKjX5Fmx3zjDWieJelbLit9tvQTcqyq8A==", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-undo": "43.1.1", + "@ckeditor/ckeditor5-upload": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1", "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-indent": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-indent/-/ckeditor5-indent-41.0.0.tgz", - "integrity": "sha512-OpwL9eyKOnQJ3Rv50/ur+fYKd6dpRuEhNUpsf39h0UNbF9i1KU+nUiIU/WLpj3uPPeFKE5DeyM4RQFJuK6oMdw==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-indent/-/ckeditor5-indent-43.1.1.tgz", + "integrity": "sha512-8UjEX0TlnQgxzRkIAwJMcrc4rQSrpFuxUmo4b4xWIuzTg2p/+XdmDebi1p0AekB14ZW9J4UjB0U8NTWJQ++NyA==", "dependencies": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, - "node_modules/@ckeditor/ckeditor5-link": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-link/-/ckeditor5-link-41.0.0.tgz", - "integrity": "sha512-eMnQNUbTaQSCEeZs4PT/WYpeTLeJj39wASygW+m4Cv28zs91RVhS3amXEuOfoTEp2yxaCw+wAlbAlAoOWhPQCg==", + "node_modules/@ckeditor/ckeditor5-language": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-language/-/ckeditor5-language-43.1.1.tgz", + "integrity": "sha512-lNqZn3rTmGDPEvZwAZZF6R1CkhnAh0cPXU4kuIs0+sshUcWGTQTO1l38Qzr4BGLrH1u7S2OilDe5GwfujF2vaA==", "dependencies": { - "@ckeditor/ckeditor5-ui": "41.0.0", - "ckeditor5": "41.0.0", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-link": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-link/-/ckeditor5-link-43.1.1.tgz", + "integrity": "sha512-pk/ginodZGD8H5ezH9uhPjV7bK2wKkx80Eno9pt/c05+rsrHOjcibrS+SXBQ6qbK/W6Zo9ZUFwWC9HyNIiCwqA==", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1", "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-list": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-list/-/ckeditor5-list-41.0.0.tgz", - "integrity": "sha512-KBbGWY7ihhc2IpCNpYoT+mzTThpsS3X7Pz6nQHAkGC3rzrdnfPhSbTnrXqckmMfM6VQzGrXUMWnIwLMDdGfGcw==", - "dependencies": { - "ckeditor5": "41.0.0" + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-list/-/ckeditor5-list-43.1.1.tgz", + "integrity": "sha512-hH9Ny4TRH87Iz7WDw8eVKHFFmY4sOrlbPcXutcZCfYGuiDGAvRaeinAwitnWwy+bs5mAdQcw/araWAgMoVbEpw==", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-markdown-gfm": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-markdown-gfm/-/ckeditor5-markdown-gfm-43.1.1.tgz", + "integrity": "sha512-7hnOEZdow1/aR69RXqTPoTczyAeIkjwYxgXbvt+pWgtJinuGtW97pc2X6ZSivsq+SWa+6UCe3TnzbyUrIdcqzA==", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "ckeditor5": "43.1.1", + "marked": "4.0.12", + "turndown": "7.2.0", + "turndown-plugin-gfm": "1.0.2" } }, "node_modules/@ckeditor/ckeditor5-media-embed": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-media-embed/-/ckeditor5-media-embed-41.0.0.tgz", - "integrity": "sha512-x+umwDKQSB/oCB07r3cYzqWimr4XCOES+iBwFm4gIRp1Prh4DowqaEFipp6WV3goZLParFjkq9aiHaAHXcqO2g==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-media-embed/-/ckeditor5-media-embed-43.1.1.tgz", + "integrity": "sha512-MEydmh/mNUpMpNNV6BDWK8pCC5qn++WPDyDMYSFi9bX8hr9EC7AufoNG+Lh46vEnPl49cAy18WZvlyoX7nCyCA==", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-undo": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-mention": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-mention/-/ckeditor5-mention-43.1.1.tgz", + "integrity": "sha512-ErKPpapKx7HXTDgfGg6h3IRac70gCn6cwLIfuSiJ3bg8DSV5q7Rbi5UG8fRdOiT3mu/ZWI7gdP0ei6t/R6ddeA==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-minimap": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-minimap/-/ckeditor5-minimap-43.1.1.tgz", + "integrity": "sha512-igsONpmmJse/RY/3ZAbtp5mlUzFHHAnFvUaNDPpWVDZ67sSJfCurAJqkrA9zzz4+pErdpryms067c5TAp8H9OQ==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-page-break": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-page-break/-/ckeditor5-page-break-43.1.1.tgz", + "integrity": "sha512-QuY6TYsgDZfeYWw4CZGgUs/3B2gHq4GmfSO4RuOMaQYPPnFOPFlyHEst9LDE6BbAa9ZWCdGlvUVxCfuAEDueww==", "dependencies": { - "@ckeditor/ckeditor5-ui": "41.0.0", - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-paragraph": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-41.0.0.tgz", - "integrity": "sha512-w344YUyhk+ME1fbD0/Dm/xe92OLCMTg5IYEWBpyn20VjnWhu1DPTMJ6NWM6/aGTCZ3bxEIh0UWj4QFr+QstiVA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-43.1.1.tgz", + "integrity": "sha512-9ehs/b2K95W0KPDKwnfxDYHs4ypOtDNT4yB/ZGkJP96NV5XJGGQVBJIVmq0HrMGh4thdwJWofq7ZBIBjN3HMwQ==", "dependencies": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-paste-from-office": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paste-from-office/-/ckeditor5-paste-from-office-41.0.0.tgz", - "integrity": "sha512-QCgLLY9k3LC4iqG9T7m1PyWPZ8c5ZzCcu/Jed3eA9ixjFVFcdL2wkAaiGug50Uw8gfclrsygBAmGrdtH2qSZ7w==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paste-from-office/-/ckeditor5-paste-from-office-43.1.1.tgz", + "integrity": "sha512-dMftOM7eFMqFFZGdzo04PalimSQgNnbAp4adiVVSQDQ9reenWJD9iE1VCT4C5MnX3q4MXGAIBmqOubsqwfI84g==", "dependencies": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-remove-format": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-remove-format/-/ckeditor5-remove-format-43.1.1.tgz", + "integrity": "sha512-LhzNvdJ3SrynhCN0BwAmjG1wNcPFy0nYgraS6Nj+P57up64EzDMCsJZ5EY7SsDgtm1rCRZh8liHfbY/6DLz6Ng==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-restricted-editing": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-restricted-editing/-/ckeditor5-restricted-editing-43.1.1.tgz", + "integrity": "sha512-QwDclw+HEYxJ3uLP0VNo+L0YMhv8uc/6RflEkh2E2w/keiPVrE41vzrAW/G0VD85MMVMdUrmYi98soDPsvZGVA==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-select-all": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-select-all/-/ckeditor5-select-all-41.0.0.tgz", - "integrity": "sha512-5dn8TlkygVjs3WILIBIyQrZBwZ7Ip+VS0aC7LJiNLCc1XIEZOpuP7dHph014IbW+8m7P61DK24AuuNn1J0KCRA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-select-all/-/ckeditor5-select-all-43.1.1.tgz", + "integrity": "sha512-NAxjt604pS6LcEsmH+yMHphrUAV6koACwauyj9llfZErd+VWlzsComiqgEN0ZbZ+iVCem4Fl+TT/82rTcGgtbg==", "dependencies": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1" } }, - "node_modules/@ckeditor/ckeditor5-table": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-table/-/ckeditor5-table-41.0.0.tgz", - "integrity": "sha512-4JTIc42eN+tfW0Sucw867PDdLD2IOajLXPJ8W1MaDjOfM+7RZZ4muCHMOf1LXk69Gfrt3cd2YrRELv3N2fjv5Q==", + "node_modules/@ckeditor/ckeditor5-show-blocks": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-show-blocks/-/ckeditor5-show-blocks-43.1.1.tgz", + "integrity": "sha512-vb9FCIAnWZ0E161x7ulJPtLKtvxI+Rxv8qAikGNrbvLr6x9U9j0Y7WnLtmoYUozKIsRPQ2zFl7qciv1dPoeJTA==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-source-editing": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-source-editing/-/ckeditor5-source-editing-43.1.1.tgz", + "integrity": "sha512-NH5TSZJjroUk9u1eQBlGNSnHvcesednao+YeicZQzRBvPMqIV+6J+MdMj65hlqyfbEsbeHrIKCdMLo/H28+4ZA==", "dependencies": { - "ckeditor5": "41.0.0", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-theme-lark": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-special-characters": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-special-characters/-/ckeditor5-special-characters-43.1.1.tgz", + "integrity": "sha512-PQ4E0Rn7dxftM/h6zRLFptrD2xgMHXUVRZJuV6iejK+C/fVAM51PWOOUGUAPKWH1tY2bryiqdxF3yNyU2fpC4w==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "node_modules/@ckeditor/ckeditor5-style": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-style/-/ckeditor5-style-43.1.1.tgz", + "integrity": "sha512-sDrM3lCNlx9QdZaEeRUjf/ukO3sIriRn3dNs/6n6+pGJThlzju3/ikryywJ5AfxzmpCK7CVx1H2x2R9krSV4PQ==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-table": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-table/-/ckeditor5-table-43.1.1.tgz", + "integrity": "sha512-rm7RcyYdhKlokBPxianNJSVdAQS7ng9T8UMbc7wJBVIEUXgqbqQ57nGm4IIX59FXSA7H9Dj/EFW4DT9YAaITvg==", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1", "lodash-es": "4.17.21" } }, + "node_modules/@ckeditor/ckeditor5-theme-lark": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-theme-lark/-/ckeditor5-theme-lark-43.1.1.tgz", + "integrity": "sha512-7huWGsetISvNOzQurO1zqLL25YnGP3vgsOysKHz0qKgOi+UwXWxG8IYnzHi0qN4ox78vgyCR+nJvzjVz33gJEg==", + "dependencies": { + "@ckeditor/ckeditor5-ui": "43.1.1" + } + }, "node_modules/@ckeditor/ckeditor5-typing": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-41.0.0.tgz", - "integrity": "sha512-uaIU/5X1Ffk2XZZ/3q1NyrINhxPDre8Bnb7+AvzPWtLsdimoCotpzA84h00WVYWS4B5xotrM/eV/MikQvcpRkQ==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-43.1.1.tgz", + "integrity": "sha512-2YB3IfGPWct1oIlYGCL5Z5JQ/g2dpn8zr9syVTQJ/fAPjqi8Ig53lTaCQvpftnq4I+jESXAl4Rr9bIosqDVjAQ==", "dependencies": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-ui": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-41.0.0.tgz", - "integrity": "sha512-0oLE7WQyCcNxwvSJw2gwFgrktK19aqbqzIQJpr8xrn5KfDJw7WWk53/yWye05pAphtGo1VZTOk8YG7OJMvQn2Q==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-43.1.1.tgz", + "integrity": "sha512-GNf0y56cT1HzgaG8wPyNsXlG4lZJMag+UKL6L3Y8uYg9/HurqJjJVnZcCJZ7T1t3D26fOvCIZ3KhW6AtRrnDrA==", "dependencies": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", "color-convert": "2.0.1", "color-parse": "1.4.2", "lodash-es": "4.17.21", @@ -2126,52 +2502,63 @@ } }, "node_modules/@ckeditor/ckeditor5-undo": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-41.0.0.tgz", - "integrity": "sha512-2rF8YqEDZgPa3sD1BVZxlEKxZ7bwqPVCG9f4ebLr9AYSI3DnneitAtiTlkbb2CjcPc4FAcOPFpvQyzavIpkNDg==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-43.1.1.tgz", + "integrity": "sha512-qX8jy5d8H4emWNCmA4EN2ZE/UGfBN1AqhMYtdX73EIxnDwVzT6Hd+GUaScDQoKn7Y81vO5dELPKFddaQN077Ew==", "dependencies": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-upload": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-41.0.0.tgz", - "integrity": "sha512-EGb88xYTyL6Xdi7pFkmhv3Zv2JrKUWvyTXGdUEmLsMqRzxV+VHkVt2HTxHERaZlOa/iY6GzkC4yHGFL+jC28/Q==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-43.1.1.tgz", + "integrity": "sha512-VIylGThmbwCKazx2XZBS8WYW7AYOgZzS8zQ1WDwT80tfOC3cjykNvg59eH7OACDeWud1LD47/idTj0wVC8gsIg==", "dependencies": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1" } }, "node_modules/@ckeditor/ckeditor5-utils": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-41.0.0.tgz", - "integrity": "sha512-7ITAPlFxjPtFa4HnB+zrjgEs0nfPs+QHmf1pOltfIUhpFvg5V6ImIrBvzIaf+AeU5Uf6pNVHjXnqorn9oeqRTA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-43.1.1.tgz", + "integrity": "sha512-x7d1Iy2j6be74Nqv5MwWjBtVX8xv3lsbkUc0n/K26Edql5d2sk05MeA5kyBowHzqFEVDgDOUCj9Thl5KrJpb5w==", "dependencies": { "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-watchdog": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-watchdog/-/ckeditor5-watchdog-41.0.0.tgz", - "integrity": "sha512-S2mP2A+Zil7j7LMZqJhBTXc007gbYJD12xBpa5MQFLcUNLwYR9nj69IM5QmJV50ai0U7znkWQxJai/4BAJvL8Q==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-watchdog/-/ckeditor5-watchdog-43.1.1.tgz", + "integrity": "sha512-/IyxNGhYKzioxwzK+H5NbgzHPNOBHkNbUwnC3vM89OOLxu5g77edEn/kcSBsEABYweddUK8LrPrKKvTcYC+tuw==", "dependencies": { "lodash-es": "4.17.21" } }, "node_modules/@ckeditor/ckeditor5-widget": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-41.0.0.tgz", - "integrity": "sha512-pQomiS4wSlDs17muViabmGzcGAWR/cqtUIJswXAqlaQICdbOIX+tfA9XsZDdekrTZZxZxk+1Zh1UJ4WWK4kmSg==", - "dependencies": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-enter": "41.0.0", - "@ckeditor/ckeditor5-typing": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-43.1.1.tgz", + "integrity": "sha512-3S6T7bImVAX2OHkrKeTRRWn+WE5nJyvrRPNItPTXhxgDPrbAYRpvH3mtcoUjb24cw1dDfHRwolBTXRv1DxqAUw==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "node_modules/@ckeditor/ckeditor5-word-count": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-word-count/-/ckeditor5-word-count-43.1.1.tgz", + "integrity": "sha512-eMLf6iC/yH2ZSJtnfU9W/92J/JYwGhrU8AGsrffGqPkJkHSe9qbSUHhpEyae+Q+GTK6FMU1pEC6tAdlxOWmRcw==", + "dependencies": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", "lodash-es": "4.17.21" } }, @@ -2524,6 +2911,11 @@ "@lezer/common": "^1.0.0" } }, + "node_modules/@mixmark-io/domino": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", + "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3541,23 +3933,67 @@ "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==" }, "node_modules/ckeditor5": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-41.0.0.tgz", - "integrity": "sha512-b1mS43gOmoUtf/fWDYrNxSWhHQFc7Qv9JB5nnePmv1XGIYBa/Bcgp4SSXRSSVl8XfmT9Z7BbYKux0V+ZE45RIQ==", - "dependencies": { - "@ckeditor/ckeditor5-clipboard": "41.0.0", - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-enter": "41.0.0", - "@ckeditor/ckeditor5-paragraph": "41.0.0", - "@ckeditor/ckeditor5-select-all": "41.0.0", - "@ckeditor/ckeditor5-typing": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0", - "@ckeditor/ckeditor5-undo": "41.0.0", - "@ckeditor/ckeditor5-upload": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0", - "@ckeditor/ckeditor5-watchdog": "41.0.0", - "@ckeditor/ckeditor5-widget": "41.0.0" + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-43.1.1.tgz", + "integrity": "sha512-/nVXYI81XT1xzE1SKrmgF5qViHYqf3hC+BhizC8r1RZ82SB28G9gRmahYSt2pMkpI6w165OwXCdWEoIVAtiYRg==", + "dependencies": { + "@ckeditor/ckeditor5-adapter-ckfinder": "43.1.1", + "@ckeditor/ckeditor5-alignment": "43.1.1", + "@ckeditor/ckeditor5-autoformat": "43.1.1", + "@ckeditor/ckeditor5-autosave": "43.1.1", + "@ckeditor/ckeditor5-basic-styles": "43.1.1", + "@ckeditor/ckeditor5-block-quote": "43.1.1", + "@ckeditor/ckeditor5-ckbox": "43.1.1", + "@ckeditor/ckeditor5-ckfinder": "43.1.1", + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-cloud-services": "43.1.1", + "@ckeditor/ckeditor5-code-block": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-easy-image": "43.1.1", + "@ckeditor/ckeditor5-editor-balloon": "43.1.1", + "@ckeditor/ckeditor5-editor-classic": "43.1.1", + "@ckeditor/ckeditor5-editor-decoupled": "43.1.1", + "@ckeditor/ckeditor5-editor-inline": "43.1.1", + "@ckeditor/ckeditor5-editor-multi-root": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-essentials": "43.1.1", + "@ckeditor/ckeditor5-find-and-replace": "43.1.1", + "@ckeditor/ckeditor5-font": "43.1.1", + "@ckeditor/ckeditor5-heading": "43.1.1", + "@ckeditor/ckeditor5-highlight": "43.1.1", + "@ckeditor/ckeditor5-horizontal-line": "43.1.1", + "@ckeditor/ckeditor5-html-embed": "43.1.1", + "@ckeditor/ckeditor5-html-support": "43.1.1", + "@ckeditor/ckeditor5-image": "43.1.1", + "@ckeditor/ckeditor5-indent": "43.1.1", + "@ckeditor/ckeditor5-language": "43.1.1", + "@ckeditor/ckeditor5-link": "43.1.1", + "@ckeditor/ckeditor5-list": "43.1.1", + "@ckeditor/ckeditor5-markdown-gfm": "43.1.1", + "@ckeditor/ckeditor5-media-embed": "43.1.1", + "@ckeditor/ckeditor5-mention": "43.1.1", + "@ckeditor/ckeditor5-minimap": "43.1.1", + "@ckeditor/ckeditor5-page-break": "43.1.1", + "@ckeditor/ckeditor5-paragraph": "43.1.1", + "@ckeditor/ckeditor5-paste-from-office": "43.1.1", + "@ckeditor/ckeditor5-remove-format": "43.1.1", + "@ckeditor/ckeditor5-restricted-editing": "43.1.1", + "@ckeditor/ckeditor5-select-all": "43.1.1", + "@ckeditor/ckeditor5-show-blocks": "43.1.1", + "@ckeditor/ckeditor5-source-editing": "43.1.1", + "@ckeditor/ckeditor5-special-characters": "43.1.1", + "@ckeditor/ckeditor5-style": "43.1.1", + "@ckeditor/ckeditor5-table": "43.1.1", + "@ckeditor/ckeditor5-theme-lark": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-undo": "43.1.1", + "@ckeditor/ckeditor5-upload": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-watchdog": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "@ckeditor/ckeditor5-word-count": "43.1.1" } }, "node_modules/clean-css": { @@ -4000,9 +4436,9 @@ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, "node_modules/dompurify": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.5.tgz", - "integrity": "sha512-kD+f8qEaa42+mjdOpKeztu9Mfx5bv9gVLO6K9jRx4uGvh6Wv06Srn4jr1wPNY2OOUGGSKHNFN+A8MA3v0E0QAQ==" + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.4.tgz", + "integrity": "sha512-l5NNozANzaLPPe0XaAwvg3uZcHtDBnziX/HjsY1UcDj1MxTK8Dd0Kv096jyPK5HRzs/XM5IMj20dW8Fk+HnbUA==" }, "node_modules/dot-case": { "version": "3.0.4", @@ -5685,6 +6121,17 @@ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, + "node_modules/marked": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz", + "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -7332,6 +7779,19 @@ "node": "*" } }, + "node_modules/turndown": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.0.tgz", + "integrity": "sha512-eCZGBN4nNNqM9Owkv9HAtWRYfLA4h909E/WGAWWBpmB275ehNhZyk87/Tpvjbp0jjNl9XwCsbe6bm6CqFsgD+A==", + "dependencies": { + "@mixmark-io/domino": "^2.2.0" + } + }, + "node_modules/turndown-plugin-gfm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/turndown-plugin-gfm/-/turndown-plugin-gfm-1.0.2.tgz", + "integrity": "sha512-vwz9tfvF7XN/jE0dGoBei3FXWuvll78ohzCZQuOb+ZjWrs3a0XhQVomJEb2Qh4VHTPNRO4GPZh0V7VRbiWwkRg==" + }, "node_modules/tw-elements": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/tw-elements/-/tw-elements-1.0.0.tgz", @@ -9038,273 +9498,649 @@ } }, "@ckeditor/ckeditor5-adapter-ckfinder": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-adapter-ckfinder/-/ckeditor5-adapter-ckfinder-41.0.0.tgz", - "integrity": "sha512-2N5WqXNtU+5w44t9sasokIxcs1O2dyEutal10UUDdfHL6fyExMibbn0CTPSUhQBWxG8KFawbF0Nqww7BSoXD+A==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-adapter-ckfinder/-/ckeditor5-adapter-ckfinder-43.1.1.tgz", + "integrity": "sha512-DCR98QdQKCYCQFT23CwR6PFLPLT3rlh89++hFIhUpykDz2pljEDC8uFNWjKY+b/5/P/jkTICLtt8+DlF8aN+/Q==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-upload": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-alignment": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-alignment/-/ckeditor5-alignment-43.1.1.tgz", + "integrity": "sha512-mjQPDmfPgKbMQp8JCR7Vg7MpRax44tSrtyoofSl/oMKDh2bXtwEnMKJlv501scl95S8VN2Pfnxj5+31N89j0Xg==", "requires": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "@ckeditor/ckeditor5-autoformat": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-autoformat/-/ckeditor5-autoformat-41.0.0.tgz", - "integrity": "sha512-GxAzOlSarvObBkd+qvy0/fwkNt9x0Pugy8Sh0/7bXDJIkvSXqB4Vecq2l3RA8ATIietW2mD/NYQtu53U1Y8GvQ==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-autoformat/-/ckeditor5-autoformat-43.1.1.tgz", + "integrity": "sha512-/NP29+d5y+AcffZEBJqH42Bj/M76OuBPG3DNEz9XEBbF9ADC9jqb2pYzDgiit/9VukNDtoLJjQ6HGxjdwzdLfg==", "requires": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-autosave": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-autosave/-/ckeditor5-autosave-43.1.1.tgz", + "integrity": "sha512-GYeEF0NL0KLS33lZ4Uc4R2hAofTH+EE/Pulzg1V0rSIPghLNULsvMRiqe6PnzYDKtD5et1YpaIZRp55DGzJ/gQ==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-basic-styles": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-basic-styles/-/ckeditor5-basic-styles-41.0.0.tgz", - "integrity": "sha512-5BZnkL0TRbpdyY4Uwj230Aj+iQufO6He/KPlnA5fFglXKG+AyuPubXOY5P5dAX1SOMKpEZ720zSugFTVvM0ErA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-basic-styles/-/ckeditor5-basic-styles-43.1.1.tgz", + "integrity": "sha512-xFfL6JaVkkNRnFET/ld6MGvbifFxJY8bv3zvAAlphXsCBxNDH9cZWzG605PF6SYTucCUXD4dtW0teLMmdzklaQ==", "requires": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "ckeditor5": "43.1.1" } }, "@ckeditor/ckeditor5-block-quote": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-block-quote/-/ckeditor5-block-quote-41.0.0.tgz", - "integrity": "sha512-N3AbHpWllqYVY9/ME2NhQJhJLoZoks8r+7HdhZ7mrSPtOJVdeSN7L9X2LXLIozddQ/zqJXv1oJq5m/qMH9ruTw==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-block-quote/-/ckeditor5-block-quote-43.1.1.tgz", + "integrity": "sha512-VYZlQisRptiiqVRnMVBcwc3yRilpSoFTKiMXTzrYukUZLhPL6fiWVeMe/N9ygtdtGp3oYF/rSNv9H/8e6nNVYw==", "requires": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "@ckeditor/ckeditor5-build-classic": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-build-classic/-/ckeditor5-build-classic-41.0.0.tgz", - "integrity": "sha512-J4Gi1GEGDrZrgOqzKk321Q+LnQ7rTefWqg8DNof5ekRi/09iPweyNWhlSFdPIO6L7UswD7ljoetVjUoB8SqX8w==", - "requires": { - "@ckeditor/ckeditor5-adapter-ckfinder": "41.0.0", - "@ckeditor/ckeditor5-autoformat": "41.0.0", - "@ckeditor/ckeditor5-basic-styles": "41.0.0", - "@ckeditor/ckeditor5-block-quote": "41.0.0", - "@ckeditor/ckeditor5-ckbox": "41.0.0", - "@ckeditor/ckeditor5-ckfinder": "41.0.0", - "@ckeditor/ckeditor5-cloud-services": "41.0.0", - "@ckeditor/ckeditor5-easy-image": "41.0.0", - "@ckeditor/ckeditor5-editor-classic": "41.0.0", - "@ckeditor/ckeditor5-essentials": "41.0.0", - "@ckeditor/ckeditor5-heading": "41.0.0", - "@ckeditor/ckeditor5-image": "41.0.0", - "@ckeditor/ckeditor5-indent": "41.0.0", - "@ckeditor/ckeditor5-link": "41.0.0", - "@ckeditor/ckeditor5-list": "41.0.0", - "@ckeditor/ckeditor5-media-embed": "41.0.0", - "@ckeditor/ckeditor5-paragraph": "41.0.0", - "@ckeditor/ckeditor5-paste-from-office": "41.0.0", - "@ckeditor/ckeditor5-table": "41.0.0", - "@ckeditor/ckeditor5-typing": "41.0.0" + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-build-classic/-/ckeditor5-build-classic-43.1.1.tgz", + "integrity": "sha512-yCg+5u2ihdunYxieHsgHWACXbTMQZajy23wtGAuED7Tv+Uf41XPmBmQLoXSY43LyQOeSNvgEFdb6lUrl5Gi05w==", + "requires": { + "@ckeditor/ckeditor5-adapter-ckfinder": "43.1.1", + "@ckeditor/ckeditor5-autoformat": "43.1.1", + "@ckeditor/ckeditor5-basic-styles": "43.1.1", + "@ckeditor/ckeditor5-block-quote": "43.1.1", + "@ckeditor/ckeditor5-ckbox": "43.1.1", + "@ckeditor/ckeditor5-ckfinder": "43.1.1", + "@ckeditor/ckeditor5-cloud-services": "43.1.1", + "@ckeditor/ckeditor5-easy-image": "43.1.1", + "@ckeditor/ckeditor5-editor-classic": "43.1.1", + "@ckeditor/ckeditor5-essentials": "43.1.1", + "@ckeditor/ckeditor5-heading": "43.1.1", + "@ckeditor/ckeditor5-image": "43.1.1", + "@ckeditor/ckeditor5-indent": "43.1.1", + "@ckeditor/ckeditor5-link": "43.1.1", + "@ckeditor/ckeditor5-list": "43.1.1", + "@ckeditor/ckeditor5-media-embed": "43.1.1", + "@ckeditor/ckeditor5-paragraph": "43.1.1", + "@ckeditor/ckeditor5-paste-from-office": "43.1.1", + "@ckeditor/ckeditor5-table": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1" } }, "@ckeditor/ckeditor5-ckbox": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ckbox/-/ckeditor5-ckbox-41.0.0.tgz", - "integrity": "sha512-8Q8GEs8kBArsWgbOT0c9D33T0AyUCNBcLhV2sHDs4XTg0ldxwDSCkneEJfV5da5ekgp/qacivoF8IVTzjNaHqQ==", - "requires": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ckbox/-/ckeditor5-ckbox-43.1.1.tgz", + "integrity": "sha512-2suCDhe5HlutZz52iBXRaVAcht/E4wBdZsF6ZL+hELNuqvYM2PCb2/FZTtxQb50mDlWtJtLidRc49COAr0k1QA==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-upload": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", "blurhash": "2.0.5", - "ckeditor5": "41.0.0", + "ckeditor5": "43.1.1", "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-ckfinder": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ckfinder/-/ckeditor5-ckfinder-41.0.0.tgz", - "integrity": "sha512-IKBkRB84gbLzLMOPnigpBa0WKR0etyIQdsrbD8i7H96fTTNWC0RNxbTyeD0RIbh5/EhJqFQPSds1QnVr5XvHqA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ckfinder/-/ckeditor5-ckfinder-43.1.1.tgz", + "integrity": "sha512-f5N9FtJTSRfEUaJqr0LpekoSAIMktyiwbWeGQhbYseCCV0+Qsw6W/wzuWMFNe5GELg0R/0tG0H59/2m1wTFFbw==", "requires": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "@ckeditor/ckeditor5-clipboard": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-41.0.0.tgz", - "integrity": "sha512-OS0jL9s5P4uFadQYrPkRtx6+KlDkJwMLbQoeEhTpyG4BwF3zf2Q3UE+KdyvULS2er8FtxVu5bx3zeA7DtxYa9w==", - "requires": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0", - "@ckeditor/ckeditor5-widget": "41.0.0", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-43.1.1.tgz", + "integrity": "sha512-QF0zyq/NhLFm8V/VBBn+RWjiaAd5eyeCKz7zQKyBcSW27IaazAnG0+HHZeydZkT4vntad71t6bi6ZWzL/MJxwg==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-cloud-services": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-cloud-services/-/ckeditor5-cloud-services-41.0.0.tgz", - "integrity": "sha512-AfsX1ZDYBYUEXzxLiWp9Szl6LIzjNvKFSqsRrY889J2CMmA9LfAcS3tEnXeLqutb9EhcHfpPoSdQLZ3l9UpPew==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-cloud-services/-/ckeditor5-cloud-services-43.1.1.tgz", + "integrity": "sha512-YprETdoRcu/2yxVCuoOrY+f4G0Qus0hIMfMuRZ9jbFWDDwZgHiXrFXvE0W9o9N51rKffWnTbs0GljsaXVit1+g==", "requires": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "@ckeditor/ckeditor5-code-block": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-code-block/-/ckeditor5-code-block-41.0.0.tgz", - "integrity": "sha512-t+HdCrOEiM9oIDFIu+khhRNP/C2K0JTDaChBPx51uFDuwmSGtX35UbaWwEbfXtcZS7NziloTBnD6m+fe9uibeA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-code-block/-/ckeditor5-code-block-43.1.1.tgz", + "integrity": "sha512-Nil+MNeirroHop5Onj23L2v17Jokgc6wvJYqzH+85OvlrJeEsfFauxlW+S6TI3ypZT04yLJ0zdpaZ/FYC5+NxA==", "requires": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "@ckeditor/ckeditor5-core": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-41.0.0.tgz", - "integrity": "sha512-/t4Cl8fxdrjxn4WRobJdRui4WwGUq/qsD3q5W5IzdCQyON1fr+qaDJ4popGfg+MFSNIFFF9/ip5wkgqOexYMOg==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-43.1.1.tgz", + "integrity": "sha512-qtbnD+24dK+ANVUgs+unZ0qX64NA0eG6k344q8fhXuHdPRKk55BDkjdmpv/Fh9Y0beo9EDqUPE/P7agv8lucBg==", "requires": { - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-watchdog": "43.1.1", "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-easy-image": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-easy-image/-/ckeditor5-easy-image-41.0.0.tgz", - "integrity": "sha512-DTMpDv4yapvT6bbBLLXvOsJdrn7G8WseIZCrCJWwnaSqH0yQvk/w30fj1MYt6m2lDMmp9Z96/wl/V7tp8QrSRw==", - "requires": { - "ckeditor5": "41.0.0" + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-easy-image/-/ckeditor5-easy-image-43.1.1.tgz", + "integrity": "sha512-BSiqxe6rFzNIROz7uny8SyGndQX070hlktJT5sQNO46lB+tsyFScUVXjzduSlm2fCG/2PFA83skR3/7cTAkBbg==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-upload": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-editor-balloon": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-balloon/-/ckeditor5-editor-balloon-43.1.1.tgz", + "integrity": "sha512-hIfocf3a/zXj1SLElF58LIVXOP3GphpajrsNXysSxccb4LNUQjvqMqwYaHDkib0Oh4AznsCwfBE3CJ3grUiI4g==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-editor-classic": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-classic/-/ckeditor5-editor-classic-41.0.0.tgz", - "integrity": "sha512-64E/zrOs6BRSHJ34wIEtRMEOQwceK9TOWZCmXcIqjS+gH7D1O9mCgM3u8wN+Vk/LfHNXNZq/xl27nYG0tHxwww==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-classic/-/ckeditor5-editor-classic-43.1.1.tgz", + "integrity": "sha512-8/yuGbTtY/BF4Oi5wDd9/NHNmIvtb+f5YvqSkG7ZtWy0M+uHru8xM7hhUqUKwrG2jVxB2MFRcDGAE0YlVqs98Q==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "@ckeditor/ckeditor5-editor-decoupled": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-decoupled/-/ckeditor5-editor-decoupled-43.1.1.tgz", + "integrity": "sha512-Vs7yVUjOM+QiwnS6v987YGen0xwku07pQyhl+ihW6cphJymaJ/kPNvkR2ZCfE5e/Av0ckz14DQj4vOmotx+Vxg==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "@ckeditor/ckeditor5-editor-inline": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-inline/-/ckeditor5-editor-inline-43.1.1.tgz", + "integrity": "sha512-6rNUJPG23c0Nm4cbb5ReYiARhBk8crdpkYig6sR+8m//ah9SzO0H4H/brHtYHsV6FxOYDwxEJdaMSDP7rWUwkQ==", "requires": { - "ckeditor5": "41.0.0", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "@ckeditor/ckeditor5-editor-multi-root": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-multi-root/-/ckeditor5-editor-multi-root-43.1.1.tgz", + "integrity": "sha512-M1NBPFLZZAVJt22Ipy/JYTeOPPGCRDy3nWnCoBR2U79/FkEQNRyUtkR58EA4dLHdaeAiaWX8w7z2DrLKxOUltw==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-engine": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-41.0.0.tgz", - "integrity": "sha512-SrzyRU4LXkgIFl614Vshciiwq76zbMt3gKR4Gi1xth2Q5jStT2V42KfUJ+aeigD0RevRcOL8X/g/oSXgKudbow==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-43.1.1.tgz", + "integrity": "sha512-gOqbGwEqbJDgbSRM0Dv3ArQRGTmX2pySNdQIseLnENVaq9r5FUu9T2moKYJbGl8t/DIqBAxOtdHQPafrXtk7yg==", "requires": { - "@ckeditor/ckeditor5-utils": "41.0.0", + "@ckeditor/ckeditor5-utils": "43.1.1", "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-enter": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-41.0.0.tgz", - "integrity": "sha512-6APFUXOsYcoDVyip2E79gWzE/bmEN1+5eY0ShxJmL4seSD7ipn8TflpGsPjqxe4+bcMBzpfYOcm2wlMxo/Nf6A==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-43.1.1.tgz", + "integrity": "sha512-7JjNCe4qVtiLgnGC8P5WJzcDGTOXzgpos8nPSR52vsqNANNZQ/iAByDoPP7WCIijJHHjeFoBk0ytk2qfXppjkw==", "requires": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1" } }, "@ckeditor/ckeditor5-essentials": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-essentials/-/ckeditor5-essentials-41.0.0.tgz", - "integrity": "sha512-R80qtyBgPGFDaDsJAF3gqqAAnq8+kLijR1bDsAvHwRY4FN0zhdxfwQOdeIB+OCGBevyYNrJ6MFfX/LSOZj66CA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-essentials/-/ckeditor5-essentials-43.1.1.tgz", + "integrity": "sha512-qbo080qotWmq19SnUkFspT9swHy2160nHFOdtx4LrQtGPbjSzS2EBFNHmkf31gUmEcNZCbegSIl0UT5IvIIV8g==", + "requires": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-select-all": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-undo": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-find-and-replace": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-find-and-replace/-/ckeditor5-find-and-replace-43.1.1.tgz", + "integrity": "sha512-BmSwyTsL5fAo4I2gRq7gzbU+WNAoaxWOPZCip/cGNdqzV9Utl6kTLx/DdxAhh8B4KTj8Rqv8Cmg1862HMkfKkw==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "@ckeditor/ckeditor5-font": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-font/-/ckeditor5-font-43.1.1.tgz", + "integrity": "sha512-QQrLf3zWp1T0QttKdFoC/fbEF69hzsHxNzmOeGVwAavgW0qpbpSEvTT5kRHm1tYlGeSR8N6/SVXgb4xHUxwvHg==", "requires": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "@ckeditor/ckeditor5-heading": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-heading/-/ckeditor5-heading-41.0.0.tgz", - "integrity": "sha512-00axXKOHXVDquO6yvQLAmLe4fk3v/x4JK5FHaclIeFILlJvDU5X4r5J2lEK8ClaJ/2EeaLyt+Dnwk/FRpp+0IQ==", - "requires": { - "ckeditor5": "41.0.0" + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-heading/-/ckeditor5-heading-43.1.1.tgz", + "integrity": "sha512-Gr4rxChoamevxNf/6DKRYltOcLuCqrqFOCWrOO00JRHN8dHW81TgMJVGf4xeM4bAlFbMSqM3Y2vRCPhtdTAarA==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-paragraph": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-highlight": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-highlight/-/ckeditor5-highlight-43.1.1.tgz", + "integrity": "sha512-hrzzTQ1tAHIUGdNingpyMsrBeb3herfSMXOGylkkTqg/SqtnUlVJbPZ8NVUrmlw6hQQMl7HDqBJGdHoesvB8TA==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-horizontal-line": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-horizontal-line/-/ckeditor5-horizontal-line-43.1.1.tgz", + "integrity": "sha512-FLTTPShC+/E/fAUYAxyMHOLDYCYAAuB3eXHonPekXjiAdkhchPibkIz0c3DgdjRGFhfGE4/XQ4PyU5oa5BKt5w==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-html-embed": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-html-embed/-/ckeditor5-html-embed-43.1.1.tgz", + "integrity": "sha512-ggOFwmpNAiT0nwm/++GZR/9V256mHxA0l7riL422l9YOSToGf5kukemsc7PIifuNoBXCzFrkNipr53ctxZkomA==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-html-support": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-html-support/-/ckeditor5-html-support-43.1.1.tgz", + "integrity": "sha512-eF2eZU6sbU0ml+z8nSd7cDhk3ihrV9R7gih/bWOGvWa94bpaNVOd4c7e3F0ZPQVlxfwT1X99Y7aDNSNcbWs53A==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-image": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-image/-/ckeditor5-image-41.0.0.tgz", - "integrity": "sha512-p7tFXov36cQP3Y3Kyr6Q9a/5BA0Pj5Wq8q0qPb08jpdRb6TCR60WkmiIK9yzSNR3FN4sfq1PG4l4mM4M2MJqaA==", - "requires": { - "@ckeditor/ckeditor5-ui": "41.0.0", - "ckeditor5": "41.0.0", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-image/-/ckeditor5-image-43.1.1.tgz", + "integrity": "sha512-6xOJsG9nYIIpwf/Kj0MARts5KK+eZ+awpAvljYgx+xjII4KEAO1dKSKjX5Fmx3zjDWieJelbLit9tvQTcqyq8A==", + "requires": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-undo": "43.1.1", + "@ckeditor/ckeditor5-upload": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1", "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-indent": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-indent/-/ckeditor5-indent-41.0.0.tgz", - "integrity": "sha512-OpwL9eyKOnQJ3Rv50/ur+fYKd6dpRuEhNUpsf39h0UNbF9i1KU+nUiIU/WLpj3uPPeFKE5DeyM4RQFJuK6oMdw==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-indent/-/ckeditor5-indent-43.1.1.tgz", + "integrity": "sha512-8UjEX0TlnQgxzRkIAwJMcrc4rQSrpFuxUmo4b4xWIuzTg2p/+XdmDebi1p0AekB14ZW9J4UjB0U8NTWJQ++NyA==", "requires": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, - "@ckeditor/ckeditor5-link": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-link/-/ckeditor5-link-41.0.0.tgz", - "integrity": "sha512-eMnQNUbTaQSCEeZs4PT/WYpeTLeJj39wASygW+m4Cv28zs91RVhS3amXEuOfoTEp2yxaCw+wAlbAlAoOWhPQCg==", + "@ckeditor/ckeditor5-language": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-language/-/ckeditor5-language-43.1.1.tgz", + "integrity": "sha512-lNqZn3rTmGDPEvZwAZZF6R1CkhnAh0cPXU4kuIs0+sshUcWGTQTO1l38Qzr4BGLrH1u7S2OilDe5GwfujF2vaA==", "requires": { - "@ckeditor/ckeditor5-ui": "41.0.0", - "ckeditor5": "41.0.0", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-link": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-link/-/ckeditor5-link-43.1.1.tgz", + "integrity": "sha512-pk/ginodZGD8H5ezH9uhPjV7bK2wKkx80Eno9pt/c05+rsrHOjcibrS+SXBQ6qbK/W6Zo9ZUFwWC9HyNIiCwqA==", + "requires": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1", "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-list": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-list/-/ckeditor5-list-41.0.0.tgz", - "integrity": "sha512-KBbGWY7ihhc2IpCNpYoT+mzTThpsS3X7Pz6nQHAkGC3rzrdnfPhSbTnrXqckmMfM6VQzGrXUMWnIwLMDdGfGcw==", - "requires": { - "ckeditor5": "41.0.0" + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-list/-/ckeditor5-list-43.1.1.tgz", + "integrity": "sha512-hH9Ny4TRH87Iz7WDw8eVKHFFmY4sOrlbPcXutcZCfYGuiDGAvRaeinAwitnWwy+bs5mAdQcw/araWAgMoVbEpw==", + "requires": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-markdown-gfm": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-markdown-gfm/-/ckeditor5-markdown-gfm-43.1.1.tgz", + "integrity": "sha512-7hnOEZdow1/aR69RXqTPoTczyAeIkjwYxgXbvt+pWgtJinuGtW97pc2X6ZSivsq+SWa+6UCe3TnzbyUrIdcqzA==", + "requires": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "ckeditor5": "43.1.1", + "marked": "4.0.12", + "turndown": "7.2.0", + "turndown-plugin-gfm": "1.0.2" } }, "@ckeditor/ckeditor5-media-embed": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-media-embed/-/ckeditor5-media-embed-41.0.0.tgz", - "integrity": "sha512-x+umwDKQSB/oCB07r3cYzqWimr4XCOES+iBwFm4gIRp1Prh4DowqaEFipp6WV3goZLParFjkq9aiHaAHXcqO2g==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-media-embed/-/ckeditor5-media-embed-43.1.1.tgz", + "integrity": "sha512-MEydmh/mNUpMpNNV6BDWK8pCC5qn++WPDyDMYSFi9bX8hr9EC7AufoNG+Lh46vEnPl49cAy18WZvlyoX7nCyCA==", + "requires": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-undo": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-mention": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-mention/-/ckeditor5-mention-43.1.1.tgz", + "integrity": "sha512-ErKPpapKx7HXTDgfGg6h3IRac70gCn6cwLIfuSiJ3bg8DSV5q7Rbi5UG8fRdOiT3mu/ZWI7gdP0ei6t/R6ddeA==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "@ckeditor/ckeditor5-minimap": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-minimap/-/ckeditor5-minimap-43.1.1.tgz", + "integrity": "sha512-igsONpmmJse/RY/3ZAbtp5mlUzFHHAnFvUaNDPpWVDZ67sSJfCurAJqkrA9zzz4+pErdpryms067c5TAp8H9OQ==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-page-break": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-page-break/-/ckeditor5-page-break-43.1.1.tgz", + "integrity": "sha512-QuY6TYsgDZfeYWw4CZGgUs/3B2gHq4GmfSO4RuOMaQYPPnFOPFlyHEst9LDE6BbAa9ZWCdGlvUVxCfuAEDueww==", "requires": { - "@ckeditor/ckeditor5-ui": "41.0.0", - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1" } }, "@ckeditor/ckeditor5-paragraph": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-41.0.0.tgz", - "integrity": "sha512-w344YUyhk+ME1fbD0/Dm/xe92OLCMTg5IYEWBpyn20VjnWhu1DPTMJ6NWM6/aGTCZ3bxEIh0UWj4QFr+QstiVA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-43.1.1.tgz", + "integrity": "sha512-9ehs/b2K95W0KPDKwnfxDYHs4ypOtDNT4yB/ZGkJP96NV5XJGGQVBJIVmq0HrMGh4thdwJWofq7ZBIBjN3HMwQ==", "requires": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1" } }, "@ckeditor/ckeditor5-paste-from-office": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paste-from-office/-/ckeditor5-paste-from-office-41.0.0.tgz", - "integrity": "sha512-QCgLLY9k3LC4iqG9T7m1PyWPZ8c5ZzCcu/Jed3eA9ixjFVFcdL2wkAaiGug50Uw8gfclrsygBAmGrdtH2qSZ7w==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paste-from-office/-/ckeditor5-paste-from-office-43.1.1.tgz", + "integrity": "sha512-dMftOM7eFMqFFZGdzo04PalimSQgNnbAp4adiVVSQDQ9reenWJD9iE1VCT4C5MnX3q4MXGAIBmqOubsqwfI84g==", + "requires": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-remove-format": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-remove-format/-/ckeditor5-remove-format-43.1.1.tgz", + "integrity": "sha512-LhzNvdJ3SrynhCN0BwAmjG1wNcPFy0nYgraS6Nj+P57up64EzDMCsJZ5EY7SsDgtm1rCRZh8liHfbY/6DLz6Ng==", "requires": { - "ckeditor5": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-restricted-editing": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-restricted-editing/-/ckeditor5-restricted-editing-43.1.1.tgz", + "integrity": "sha512-QwDclw+HEYxJ3uLP0VNo+L0YMhv8uc/6RflEkh2E2w/keiPVrE41vzrAW/G0VD85MMVMdUrmYi98soDPsvZGVA==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" } }, "@ckeditor/ckeditor5-select-all": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-select-all/-/ckeditor5-select-all-41.0.0.tgz", - "integrity": "sha512-5dn8TlkygVjs3WILIBIyQrZBwZ7Ip+VS0aC7LJiNLCc1XIEZOpuP7dHph014IbW+8m7P61DK24AuuNn1J0KCRA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-select-all/-/ckeditor5-select-all-43.1.1.tgz", + "integrity": "sha512-NAxjt604pS6LcEsmH+yMHphrUAV6koACwauyj9llfZErd+VWlzsComiqgEN0ZbZ+iVCem4Fl+TT/82rTcGgtbg==", "requires": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1" } }, - "@ckeditor/ckeditor5-table": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-table/-/ckeditor5-table-41.0.0.tgz", - "integrity": "sha512-4JTIc42eN+tfW0Sucw867PDdLD2IOajLXPJ8W1MaDjOfM+7RZZ4muCHMOf1LXk69Gfrt3cd2YrRELv3N2fjv5Q==", + "@ckeditor/ckeditor5-show-blocks": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-show-blocks/-/ckeditor5-show-blocks-43.1.1.tgz", + "integrity": "sha512-vb9FCIAnWZ0E161x7ulJPtLKtvxI+Rxv8qAikGNrbvLr6x9U9j0Y7WnLtmoYUozKIsRPQ2zFl7qciv1dPoeJTA==", "requires": { - "ckeditor5": "41.0.0", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-source-editing": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-source-editing/-/ckeditor5-source-editing-43.1.1.tgz", + "integrity": "sha512-NH5TSZJjroUk9u1eQBlGNSnHvcesednao+YeicZQzRBvPMqIV+6J+MdMj65hlqyfbEsbeHrIKCdMLo/H28+4ZA==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-theme-lark": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-special-characters": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-special-characters/-/ckeditor5-special-characters-43.1.1.tgz", + "integrity": "sha512-PQ4E0Rn7dxftM/h6zRLFptrD2xgMHXUVRZJuV6iejK+C/fVAM51PWOOUGUAPKWH1tY2bryiqdxF3yNyU2fpC4w==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1" + } + }, + "@ckeditor/ckeditor5-style": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-style/-/ckeditor5-style-43.1.1.tgz", + "integrity": "sha512-sDrM3lCNlx9QdZaEeRUjf/ukO3sIriRn3dNs/6n6+pGJThlzju3/ikryywJ5AfxzmpCK7CVx1H2x2R9krSV4PQ==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "@ckeditor/ckeditor5-table": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-table/-/ckeditor5-table-43.1.1.tgz", + "integrity": "sha512-rm7RcyYdhKlokBPxianNJSVdAQS7ng9T8UMbc7wJBVIEUXgqbqQ57nGm4IIX59FXSA7H9Dj/EFW4DT9YAaITvg==", + "requires": { + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "ckeditor5": "43.1.1", "lodash-es": "4.17.21" } }, + "@ckeditor/ckeditor5-theme-lark": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-theme-lark/-/ckeditor5-theme-lark-43.1.1.tgz", + "integrity": "sha512-7huWGsetISvNOzQurO1zqLL25YnGP3vgsOysKHz0qKgOi+UwXWxG8IYnzHi0qN4ox78vgyCR+nJvzjVz33gJEg==", + "requires": { + "@ckeditor/ckeditor5-ui": "43.1.1" + } + }, "@ckeditor/ckeditor5-typing": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-41.0.0.tgz", - "integrity": "sha512-uaIU/5X1Ffk2XZZ/3q1NyrINhxPDre8Bnb7+AvzPWtLsdimoCotpzA84h00WVYWS4B5xotrM/eV/MikQvcpRkQ==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-43.1.1.tgz", + "integrity": "sha512-2YB3IfGPWct1oIlYGCL5Z5JQ/g2dpn8zr9syVTQJ/fAPjqi8Ig53lTaCQvpftnq4I+jESXAl4Rr9bIosqDVjAQ==", "requires": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-ui": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-41.0.0.tgz", - "integrity": "sha512-0oLE7WQyCcNxwvSJw2gwFgrktK19aqbqzIQJpr8xrn5KfDJw7WWk53/yWye05pAphtGo1VZTOk8YG7OJMvQn2Q==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-43.1.1.tgz", + "integrity": "sha512-GNf0y56cT1HzgaG8wPyNsXlG4lZJMag+UKL6L3Y8uYg9/HurqJjJVnZcCJZ7T1t3D26fOvCIZ3KhW6AtRrnDrA==", "requires": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", "color-convert": "2.0.1", "color-parse": "1.4.2", "lodash-es": "4.17.21", @@ -9312,52 +10148,63 @@ } }, "@ckeditor/ckeditor5-undo": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-41.0.0.tgz", - "integrity": "sha512-2rF8YqEDZgPa3sD1BVZxlEKxZ7bwqPVCG9f4ebLr9AYSI3DnneitAtiTlkbb2CjcPc4FAcOPFpvQyzavIpkNDg==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-43.1.1.tgz", + "integrity": "sha512-qX8jy5d8H4emWNCmA4EN2ZE/UGfBN1AqhMYtdX73EIxnDwVzT6Hd+GUaScDQoKn7Y81vO5dELPKFddaQN077Ew==", "requires": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1" } }, "@ckeditor/ckeditor5-upload": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-41.0.0.tgz", - "integrity": "sha512-EGb88xYTyL6Xdi7pFkmhv3Zv2JrKUWvyTXGdUEmLsMqRzxV+VHkVt2HTxHERaZlOa/iY6GzkC4yHGFL+jC28/Q==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-43.1.1.tgz", + "integrity": "sha512-VIylGThmbwCKazx2XZBS8WYW7AYOgZzS8zQ1WDwT80tfOC3cjykNvg59eH7OACDeWud1LD47/idTj0wVC8gsIg==", "requires": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0" + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1" } }, "@ckeditor/ckeditor5-utils": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-41.0.0.tgz", - "integrity": "sha512-7ITAPlFxjPtFa4HnB+zrjgEs0nfPs+QHmf1pOltfIUhpFvg5V6ImIrBvzIaf+AeU5Uf6pNVHjXnqorn9oeqRTA==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-43.1.1.tgz", + "integrity": "sha512-x7d1Iy2j6be74Nqv5MwWjBtVX8xv3lsbkUc0n/K26Edql5d2sk05MeA5kyBowHzqFEVDgDOUCj9Thl5KrJpb5w==", "requires": { "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-watchdog": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-watchdog/-/ckeditor5-watchdog-41.0.0.tgz", - "integrity": "sha512-S2mP2A+Zil7j7LMZqJhBTXc007gbYJD12xBpa5MQFLcUNLwYR9nj69IM5QmJV50ai0U7znkWQxJai/4BAJvL8Q==", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-watchdog/-/ckeditor5-watchdog-43.1.1.tgz", + "integrity": "sha512-/IyxNGhYKzioxwzK+H5NbgzHPNOBHkNbUwnC3vM89OOLxu5g77edEn/kcSBsEABYweddUK8LrPrKKvTcYC+tuw==", "requires": { "lodash-es": "4.17.21" } }, "@ckeditor/ckeditor5-widget": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-41.0.0.tgz", - "integrity": "sha512-pQomiS4wSlDs17muViabmGzcGAWR/cqtUIJswXAqlaQICdbOIX+tfA9XsZDdekrTZZxZxk+1Zh1UJ4WWK4kmSg==", - "requires": { - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-enter": "41.0.0", - "@ckeditor/ckeditor5-typing": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0", + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-43.1.1.tgz", + "integrity": "sha512-3S6T7bImVAX2OHkrKeTRRWn+WE5nJyvrRPNItPTXhxgDPrbAYRpvH3mtcoUjb24cw1dDfHRwolBTXRv1DxqAUw==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "lodash-es": "4.17.21" + } + }, + "@ckeditor/ckeditor5-word-count": { + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-word-count/-/ckeditor5-word-count-43.1.1.tgz", + "integrity": "sha512-eMLf6iC/yH2ZSJtnfU9W/92J/JYwGhrU8AGsrffGqPkJkHSe9qbSUHhpEyae+Q+GTK6FMU1pEC6tAdlxOWmRcw==", + "requires": { + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "ckeditor5": "43.1.1", "lodash-es": "4.17.21" } }, @@ -9666,6 +10513,11 @@ "@lezer/common": "^1.0.0" } }, + "@mixmark-io/domino": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", + "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==" + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -10443,23 +11295,67 @@ "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==" }, "ckeditor5": { - "version": "41.0.0", - "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-41.0.0.tgz", - "integrity": "sha512-b1mS43gOmoUtf/fWDYrNxSWhHQFc7Qv9JB5nnePmv1XGIYBa/Bcgp4SSXRSSVl8XfmT9Z7BbYKux0V+ZE45RIQ==", - "requires": { - "@ckeditor/ckeditor5-clipboard": "41.0.0", - "@ckeditor/ckeditor5-core": "41.0.0", - "@ckeditor/ckeditor5-engine": "41.0.0", - "@ckeditor/ckeditor5-enter": "41.0.0", - "@ckeditor/ckeditor5-paragraph": "41.0.0", - "@ckeditor/ckeditor5-select-all": "41.0.0", - "@ckeditor/ckeditor5-typing": "41.0.0", - "@ckeditor/ckeditor5-ui": "41.0.0", - "@ckeditor/ckeditor5-undo": "41.0.0", - "@ckeditor/ckeditor5-upload": "41.0.0", - "@ckeditor/ckeditor5-utils": "41.0.0", - "@ckeditor/ckeditor5-watchdog": "41.0.0", - "@ckeditor/ckeditor5-widget": "41.0.0" + "version": "43.1.1", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-43.1.1.tgz", + "integrity": "sha512-/nVXYI81XT1xzE1SKrmgF5qViHYqf3hC+BhizC8r1RZ82SB28G9gRmahYSt2pMkpI6w165OwXCdWEoIVAtiYRg==", + "requires": { + "@ckeditor/ckeditor5-adapter-ckfinder": "43.1.1", + "@ckeditor/ckeditor5-alignment": "43.1.1", + "@ckeditor/ckeditor5-autoformat": "43.1.1", + "@ckeditor/ckeditor5-autosave": "43.1.1", + "@ckeditor/ckeditor5-basic-styles": "43.1.1", + "@ckeditor/ckeditor5-block-quote": "43.1.1", + "@ckeditor/ckeditor5-ckbox": "43.1.1", + "@ckeditor/ckeditor5-ckfinder": "43.1.1", + "@ckeditor/ckeditor5-clipboard": "43.1.1", + "@ckeditor/ckeditor5-cloud-services": "43.1.1", + "@ckeditor/ckeditor5-code-block": "43.1.1", + "@ckeditor/ckeditor5-core": "43.1.1", + "@ckeditor/ckeditor5-easy-image": "43.1.1", + "@ckeditor/ckeditor5-editor-balloon": "43.1.1", + "@ckeditor/ckeditor5-editor-classic": "43.1.1", + "@ckeditor/ckeditor5-editor-decoupled": "43.1.1", + "@ckeditor/ckeditor5-editor-inline": "43.1.1", + "@ckeditor/ckeditor5-editor-multi-root": "43.1.1", + "@ckeditor/ckeditor5-engine": "43.1.1", + "@ckeditor/ckeditor5-enter": "43.1.1", + "@ckeditor/ckeditor5-essentials": "43.1.1", + "@ckeditor/ckeditor5-find-and-replace": "43.1.1", + "@ckeditor/ckeditor5-font": "43.1.1", + "@ckeditor/ckeditor5-heading": "43.1.1", + "@ckeditor/ckeditor5-highlight": "43.1.1", + "@ckeditor/ckeditor5-horizontal-line": "43.1.1", + "@ckeditor/ckeditor5-html-embed": "43.1.1", + "@ckeditor/ckeditor5-html-support": "43.1.1", + "@ckeditor/ckeditor5-image": "43.1.1", + "@ckeditor/ckeditor5-indent": "43.1.1", + "@ckeditor/ckeditor5-language": "43.1.1", + "@ckeditor/ckeditor5-link": "43.1.1", + "@ckeditor/ckeditor5-list": "43.1.1", + "@ckeditor/ckeditor5-markdown-gfm": "43.1.1", + "@ckeditor/ckeditor5-media-embed": "43.1.1", + "@ckeditor/ckeditor5-mention": "43.1.1", + "@ckeditor/ckeditor5-minimap": "43.1.1", + "@ckeditor/ckeditor5-page-break": "43.1.1", + "@ckeditor/ckeditor5-paragraph": "43.1.1", + "@ckeditor/ckeditor5-paste-from-office": "43.1.1", + "@ckeditor/ckeditor5-remove-format": "43.1.1", + "@ckeditor/ckeditor5-restricted-editing": "43.1.1", + "@ckeditor/ckeditor5-select-all": "43.1.1", + "@ckeditor/ckeditor5-show-blocks": "43.1.1", + "@ckeditor/ckeditor5-source-editing": "43.1.1", + "@ckeditor/ckeditor5-special-characters": "43.1.1", + "@ckeditor/ckeditor5-style": "43.1.1", + "@ckeditor/ckeditor5-table": "43.1.1", + "@ckeditor/ckeditor5-theme-lark": "43.1.1", + "@ckeditor/ckeditor5-typing": "43.1.1", + "@ckeditor/ckeditor5-ui": "43.1.1", + "@ckeditor/ckeditor5-undo": "43.1.1", + "@ckeditor/ckeditor5-upload": "43.1.1", + "@ckeditor/ckeditor5-utils": "43.1.1", + "@ckeditor/ckeditor5-watchdog": "43.1.1", + "@ckeditor/ckeditor5-widget": "43.1.1", + "@ckeditor/ckeditor5-word-count": "43.1.1" } }, "clean-css": { @@ -10799,9 +11695,9 @@ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, "dompurify": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.5.tgz", - "integrity": "sha512-kD+f8qEaa42+mjdOpKeztu9Mfx5bv9gVLO6K9jRx4uGvh6Wv06Srn4jr1wPNY2OOUGGSKHNFN+A8MA3v0E0QAQ==" + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.4.tgz", + "integrity": "sha512-l5NNozANzaLPPe0XaAwvg3uZcHtDBnziX/HjsY1UcDj1MxTK8Dd0Kv096jyPK5HRzs/XM5IMj20dW8Fk+HnbUA==" }, "dot-case": { "version": "3.0.4", @@ -12005,6 +12901,11 @@ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, + "marked": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz", + "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==" + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -13193,6 +14094,19 @@ "safe-buffer": "^5.0.1" } }, + "turndown": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.0.tgz", + "integrity": "sha512-eCZGBN4nNNqM9Owkv9HAtWRYfLA4h909E/WGAWWBpmB275ehNhZyk87/Tpvjbp0jjNl9XwCsbe6bm6CqFsgD+A==", + "requires": { + "@mixmark-io/domino": "^2.2.0" + } + }, + "turndown-plugin-gfm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/turndown-plugin-gfm/-/turndown-plugin-gfm-1.0.2.tgz", + "integrity": "sha512-vwz9tfvF7XN/jE0dGoBei3FXWuvll78ohzCZQuOb+ZjWrs3a0XhQVomJEb2Qh4VHTPNRO4GPZh0V7VRbiWwkRg==" + }, "tw-elements": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/tw-elements/-/tw-elements-1.0.0.tgz", diff --git a/package.json b/package.json index 52f6928c8ae..3e1e0eee8bd 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,8 @@ }, "license": "ISC", "dependencies": { - "@ckeditor/ckeditor5-build-classic": "^41.0.0", - "@ckeditor/ckeditor5-code-block": "^41.0.0", + "@ckeditor/ckeditor5-build-classic": "^43.1.1", + "@ckeditor/ckeditor5-code-block": "^43.1.1", "@codemirror/commands": "^6.2.5", "@codemirror/state": "^6.4.0", "@codemirror/theme-one-dark": "^6.1.2", @@ -45,7 +45,7 @@ "chart.js": "^4.4.2", "codemirror": "^6.0.1", "cypress-real-events": "^1.12.0", - "dompurify": "^2.3.5", + "dompurify": "^2.5.4", "istanbul-lib-coverage": "^3.2.0", "jquery-ui-dist": "^1.13.1", "jszip": "^3.10.1", diff --git a/static/js/appbundle.js b/static/js/appbundle.js index 890006e2038..56a2edb6155 100644 --- a/static/js/appbundle.js +++ b/static/js/appbundle.js @@ -3244,18 +3244,88 @@ var hedyApp = (() => { var require_purify = __commonJS({ "node_modules/dompurify/dist/purify.js"(exports, module) { (function(global2, factory) { - typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global2 = global2 || self, global2.DOMPurify = factory()); + typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global2 = typeof globalThis !== "undefined" ? globalThis : global2 || self, global2.DOMPurify = factory()); })(exports, function() { "use strict"; - function _toConsumableArray(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { - arr2[i] = arr[i]; - } - return arr2; + function _typeof2(obj) { + "@babel/helpers - typeof"; + return _typeof2 = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(obj2) { + return typeof obj2; + } : function(obj2) { + return obj2 && typeof Symbol == "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2; + }, _typeof2(obj); + } + function _setPrototypeOf(o, p) { + _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf2(o2, p2) { + o2.__proto__ = p2; + return o2; + }; + return _setPrototypeOf(o, p); + } + function _isNativeReflectConstruct() { + if (typeof Reflect === "undefined" || !Reflect.construct) + return false; + if (Reflect.construct.sham) + return false; + if (typeof Proxy === "function") + return true; + try { + Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() { + })); + return true; + } catch (e) { + return false; + } + } + function _construct(Parent, args, Class) { + if (_isNativeReflectConstruct()) { + _construct = Reflect.construct; } else { - return Array.from(arr); + _construct = function _construct2(Parent2, args2, Class2) { + var a = [null]; + a.push.apply(a, args2); + var Constructor = Function.bind.apply(Parent2, a); + var instance = new Constructor(); + if (Class2) + _setPrototypeOf(instance, Class2.prototype); + return instance; + }; } + return _construct.apply(null, arguments); + } + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); + } + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) + return _arrayLikeToArray(arr); + } + function _iterableToArray(iter) { + if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) + return Array.from(iter); + } + function _unsupportedIterableToArray(o, minLen) { + if (!o) + return; + if (typeof o === "string") + return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) + n = o.constructor.name; + if (n === "Map" || n === "Set") + return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) + return _arrayLikeToArray(o, minLen); + } + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) + len = arr.length; + for (var i = 0, arr2 = new Array(len); i < len; i++) + arr2[i] = arr[i]; + return arr2; + } + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var hasOwnProperty = Object.hasOwnProperty, setPrototypeOf = Object.setPrototypeOf, isFrozen = Object.isFrozen, getPrototypeOf = Object.getPrototypeOf, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; var freeze = Object.freeze, seal = Object.seal, create = Object.create; @@ -3277,22 +3347,26 @@ var hedyApp = (() => { } if (!construct) { construct = function construct2(Func, args) { - return new (Function.prototype.bind.apply(Func, [null].concat(_toConsumableArray(args))))(); + return _construct(Func, _toConsumableArray(args)); }; } var arrayForEach = unapply(Array.prototype.forEach); var arrayPop = unapply(Array.prototype.pop); var arrayPush = unapply(Array.prototype.push); var stringToLowerCase = unapply(String.prototype.toLowerCase); + var stringToString = unapply(String.prototype.toString); var stringMatch = unapply(String.prototype.match); var stringReplace = unapply(String.prototype.replace); var stringIndexOf = unapply(String.prototype.indexOf); var stringTrim = unapply(String.prototype.trim); var regExpTest = unapply(RegExp.prototype.test); var typeErrorCreate = unconstruct(TypeError); + function numberIsNaN(x) { + return typeof x === "number" && isNaN(x); + } function unapply(func) { return function(thisArg) { - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } return apply(func, thisArg, args); @@ -3300,13 +3374,15 @@ var hedyApp = (() => { } function unconstruct(func) { return function() { - for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } return construct(func, args); }; } - function addToSet(set2, array) { + function addToSet(set2, array, transformCaseFunc) { + var _transformCaseFunc; + transformCaseFunc = (_transformCaseFunc = transformCaseFunc) !== null && _transformCaseFunc !== void 0 ? _transformCaseFunc : stringToLowerCase; if (setPrototypeOf) { setPrototypeOf(set2, null); } @@ -3314,7 +3390,7 @@ var hedyApp = (() => { while (l--) { var element = array[l]; if (typeof element === "string") { - var lcElement = stringToLowerCase(element); + var lcElement = transformCaseFunc(element); if (lcElement !== element) { if (!isFrozen(array)) { array[l] = lcElement; @@ -3328,9 +3404,9 @@ var hedyApp = (() => { } function clone4(object) { var newObject = create(null); - var property = void 0; + var property; for (property in object) { - if (apply(hasOwnProperty, object, [property])) { + if (apply(hasOwnProperty, object, [property]) === true) { newObject[property] = object[property]; } } @@ -3355,44 +3431,32 @@ var hedyApp = (() => { } return fallbackValue; } - var html = freeze(["a", "abbr", "acronym", "address", "area", "article", "aside", "audio", "b", "bdi", "bdo", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "decorator", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "element", "em", "fieldset", "figcaption", "figure", "font", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "img", "input", "ins", "kbd", "label", "legend", "li", "main", "map", "mark", "marquee", "menu", "menuitem", "meter", "nav", "nobr", "ol", "optgroup", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "section", "select", "shadow", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "tr", "track", "tt", "u", "ul", "var", "video", "wbr"]); - var svg = freeze(["svg", "a", "altglyph", "altglyphdef", "altglyphitem", "animatecolor", "animatemotion", "animatetransform", "circle", "clippath", "defs", "desc", "ellipse", "filter", "font", "g", "glyph", "glyphref", "hkern", "image", "line", "lineargradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialgradient", "rect", "stop", "style", "switch", "symbol", "text", "textpath", "title", "tref", "tspan", "view", "vkern"]); + var html$1 = freeze(["a", "abbr", "acronym", "address", "area", "article", "aside", "audio", "b", "bdi", "bdo", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "decorator", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "element", "em", "fieldset", "figcaption", "figure", "font", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "img", "input", "ins", "kbd", "label", "legend", "li", "main", "map", "mark", "marquee", "menu", "menuitem", "meter", "nav", "nobr", "ol", "optgroup", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "section", "select", "shadow", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "tr", "track", "tt", "u", "ul", "var", "video", "wbr"]); + var svg$1 = freeze(["svg", "a", "altglyph", "altglyphdef", "altglyphitem", "animatecolor", "animatemotion", "animatetransform", "circle", "clippath", "defs", "desc", "ellipse", "filter", "font", "g", "glyph", "glyphref", "hkern", "image", "line", "lineargradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialgradient", "rect", "stop", "style", "switch", "symbol", "text", "textpath", "title", "tref", "tspan", "view", "vkern"]); var svgFilters = freeze(["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence"]); var svgDisallowed = freeze(["animate", "color-profile", "cursor", "discard", "fedropshadow", "font-face", "font-face-format", "font-face-name", "font-face-src", "font-face-uri", "foreignobject", "hatch", "hatchpath", "mesh", "meshgradient", "meshpatch", "meshrow", "missing-glyph", "script", "set", "solidcolor", "unknown", "use"]); - var mathMl = freeze(["math", "menclose", "merror", "mfenced", "mfrac", "mglyph", "mi", "mlabeledtr", "mmultiscripts", "mn", "mo", "mover", "mpadded", "mphantom", "mroot", "mrow", "ms", "mspace", "msqrt", "mstyle", "msub", "msup", "msubsup", "mtable", "mtd", "mtext", "mtr", "munder", "munderover"]); + var mathMl$1 = freeze(["math", "menclose", "merror", "mfenced", "mfrac", "mglyph", "mi", "mlabeledtr", "mmultiscripts", "mn", "mo", "mover", "mpadded", "mphantom", "mroot", "mrow", "ms", "mspace", "msqrt", "mstyle", "msub", "msup", "msubsup", "mtable", "mtd", "mtext", "mtr", "munder", "munderover"]); var mathMlDisallowed = freeze(["maction", "maligngroup", "malignmark", "mlongdiv", "mscarries", "mscarry", "msgroup", "mstack", "msline", "msrow", "semantics", "annotation", "annotation-xml", "mprescripts", "none"]); var text = freeze(["#text"]); - var html$1 = freeze(["accept", "action", "align", "alt", "autocapitalize", "autocomplete", "autopictureinpicture", "autoplay", "background", "bgcolor", "border", "capture", "cellpadding", "cellspacing", "checked", "cite", "class", "clear", "color", "cols", "colspan", "controls", "controlslist", "coords", "crossorigin", "datetime", "decoding", "default", "dir", "disabled", "disablepictureinpicture", "disableremoteplayback", "download", "draggable", "enctype", "enterkeyhint", "face", "for", "headers", "height", "hidden", "high", "href", "hreflang", "id", "inputmode", "integrity", "ismap", "kind", "label", "lang", "list", "loading", "loop", "low", "max", "maxlength", "media", "method", "min", "minlength", "multiple", "muted", "name", "nonce", "noshade", "novalidate", "nowrap", "open", "optimum", "pattern", "placeholder", "playsinline", "poster", "preload", "pubdate", "radiogroup", "readonly", "rel", "required", "rev", "reversed", "role", "rows", "rowspan", "spellcheck", "scope", "selected", "shape", "size", "sizes", "span", "srclang", "start", "src", "srcset", "step", "style", "summary", "tabindex", "title", "translate", "type", "usemap", "valign", "value", "width", "xmlns", "slot"]); - var svg$1 = freeze(["accent-height", "accumulate", "additive", "alignment-baseline", "ascent", "attributename", "attributetype", "azimuth", "basefrequency", "baseline-shift", "begin", "bias", "by", "class", "clip", "clippathunits", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", "color-rendering", "cx", "cy", "d", "dx", "dy", "diffuseconstant", "direction", "display", "divisor", "dur", "edgemode", "elevation", "end", "fill", "fill-opacity", "fill-rule", "filter", "filterunits", "flood-color", "flood-opacity", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "fx", "fy", "g1", "g2", "glyph-name", "glyphref", "gradientunits", "gradienttransform", "height", "href", "id", "image-rendering", "in", "in2", "k", "k1", "k2", "k3", "k4", "kerning", "keypoints", "keysplines", "keytimes", "lang", "lengthadjust", "letter-spacing", "kernelmatrix", "kernelunitlength", "lighting-color", "local", "marker-end", "marker-mid", "marker-start", "markerheight", "markerunits", "markerwidth", "maskcontentunits", "maskunits", "max", "mask", "media", "method", "mode", "min", "name", "numoctaves", "offset", "operator", "opacity", "order", "orient", "orientation", "origin", "overflow", "paint-order", "path", "pathlength", "patterncontentunits", "patterntransform", "patternunits", "points", "preservealpha", "preserveaspectratio", "primitiveunits", "r", "rx", "ry", "radius", "refx", "refy", "repeatcount", "repeatdur", "restart", "result", "rotate", "scale", "seed", "shape-rendering", "specularconstant", "specularexponent", "spreadmethod", "startoffset", "stddeviation", "stitchtiles", "stop-color", "stop-opacity", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke", "stroke-width", "style", "surfacescale", "systemlanguage", "tabindex", "targetx", "targety", "transform", "transform-origin", "text-anchor", "text-decoration", "text-rendering", "textlength", "type", "u1", "u2", "unicode", "values", "viewbox", "visibility", "version", "vert-adv-y", "vert-origin-x", "vert-origin-y", "width", "word-spacing", "wrap", "writing-mode", "xchannelselector", "ychannelselector", "x", "x1", "x2", "xmlns", "y", "y1", "y2", "z", "zoomandpan"]); - var mathMl$1 = freeze(["accent", "accentunder", "align", "bevelled", "close", "columnsalign", "columnlines", "columnspan", "denomalign", "depth", "dir", "display", "displaystyle", "encoding", "fence", "frame", "height", "href", "id", "largeop", "length", "linethickness", "lspace", "lquote", "mathbackground", "mathcolor", "mathsize", "mathvariant", "maxsize", "minsize", "movablelimits", "notation", "numalign", "open", "rowalign", "rowlines", "rowspacing", "rowspan", "rspace", "rquote", "scriptlevel", "scriptminsize", "scriptsizemultiplier", "selection", "separator", "separators", "stretchy", "subscriptshift", "supscriptshift", "symmetric", "voffset", "width", "xmlns"]); + var html = freeze(["accept", "action", "align", "alt", "autocapitalize", "autocomplete", "autopictureinpicture", "autoplay", "background", "bgcolor", "border", "capture", "cellpadding", "cellspacing", "checked", "cite", "class", "clear", "color", "cols", "colspan", "controls", "controlslist", "coords", "crossorigin", "datetime", "decoding", "default", "dir", "disabled", "disablepictureinpicture", "disableremoteplayback", "download", "draggable", "enctype", "enterkeyhint", "face", "for", "headers", "height", "hidden", "high", "href", "hreflang", "id", "inputmode", "integrity", "ismap", "kind", "label", "lang", "list", "loading", "loop", "low", "max", "maxlength", "media", "method", "min", "minlength", "multiple", "muted", "name", "nonce", "noshade", "novalidate", "nowrap", "open", "optimum", "pattern", "placeholder", "playsinline", "poster", "preload", "pubdate", "radiogroup", "readonly", "rel", "required", "rev", "reversed", "role", "rows", "rowspan", "spellcheck", "scope", "selected", "shape", "size", "sizes", "span", "srclang", "start", "src", "srcset", "step", "style", "summary", "tabindex", "title", "translate", "type", "usemap", "valign", "value", "width", "xmlns", "slot"]); + var svg = freeze(["accent-height", "accumulate", "additive", "alignment-baseline", "ascent", "attributename", "attributetype", "azimuth", "basefrequency", "baseline-shift", "begin", "bias", "by", "class", "clip", "clippathunits", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", "color-rendering", "cx", "cy", "d", "dx", "dy", "diffuseconstant", "direction", "display", "divisor", "dur", "edgemode", "elevation", "end", "fill", "fill-opacity", "fill-rule", "filter", "filterunits", "flood-color", "flood-opacity", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "fx", "fy", "g1", "g2", "glyph-name", "glyphref", "gradientunits", "gradienttransform", "height", "href", "id", "image-rendering", "in", "in2", "k", "k1", "k2", "k3", "k4", "kerning", "keypoints", "keysplines", "keytimes", "lang", "lengthadjust", "letter-spacing", "kernelmatrix", "kernelunitlength", "lighting-color", "local", "marker-end", "marker-mid", "marker-start", "markerheight", "markerunits", "markerwidth", "maskcontentunits", "maskunits", "max", "mask", "media", "method", "mode", "min", "name", "numoctaves", "offset", "operator", "opacity", "order", "orient", "orientation", "origin", "overflow", "paint-order", "path", "pathlength", "patterncontentunits", "patterntransform", "patternunits", "points", "preservealpha", "preserveaspectratio", "primitiveunits", "r", "rx", "ry", "radius", "refx", "refy", "repeatcount", "repeatdur", "restart", "result", "rotate", "scale", "seed", "shape-rendering", "specularconstant", "specularexponent", "spreadmethod", "startoffset", "stddeviation", "stitchtiles", "stop-color", "stop-opacity", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke", "stroke-width", "style", "surfacescale", "systemlanguage", "tabindex", "targetx", "targety", "transform", "transform-origin", "text-anchor", "text-decoration", "text-rendering", "textlength", "type", "u1", "u2", "unicode", "values", "viewbox", "visibility", "version", "vert-adv-y", "vert-origin-x", "vert-origin-y", "width", "word-spacing", "wrap", "writing-mode", "xchannelselector", "ychannelselector", "x", "x1", "x2", "xmlns", "y", "y1", "y2", "z", "zoomandpan"]); + var mathMl = freeze(["accent", "accentunder", "align", "bevelled", "close", "columnsalign", "columnlines", "columnspan", "denomalign", "depth", "dir", "display", "displaystyle", "encoding", "fence", "frame", "height", "href", "id", "largeop", "length", "linethickness", "lspace", "lquote", "mathbackground", "mathcolor", "mathsize", "mathvariant", "maxsize", "minsize", "movablelimits", "notation", "numalign", "open", "rowalign", "rowlines", "rowspacing", "rowspan", "rspace", "rquote", "scriptlevel", "scriptminsize", "scriptsizemultiplier", "selection", "separator", "separators", "stretchy", "subscriptshift", "supscriptshift", "symmetric", "voffset", "width", "xmlns"]); var xml = freeze(["xlink:href", "xml:id", "xlink:title", "xml:space", "xmlns:xlink"]); - var MUSTACHE_EXPR = seal(/\{\{[\s\S]*|[\s\S]*\}\}/gm); - var ERB_EXPR = seal(/<%[\s\S]*|[\s\S]*%>/gm); + var MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); + var ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm); + var TMPLIT_EXPR = seal(/\${[\w\W]*}/gm); var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); var ARIA_ATTR = seal(/^aria-[\-\w]+$/); var IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i); var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g); - var _typeof2 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) { - return typeof obj; - } : function(obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; - function _toConsumableArray$1(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { - arr2[i] = arr[i]; - } - return arr2; - } else { - return Array.from(arr); - } - } + var DOCTYPE_NAME = seal(/^html$/i); + var CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i); var getGlobal = function getGlobal2() { return typeof window === "undefined" ? null : window; }; var _createTrustedTypesPolicy = function _createTrustedTypesPolicy2(trustedTypes, document2) { - if ((typeof trustedTypes === "undefined" ? "undefined" : _typeof2(trustedTypes)) !== "object" || typeof trustedTypes.createPolicy !== "function") { + if (_typeof2(trustedTypes) !== "object" || typeof trustedTypes.createPolicy !== "function") { return null; } var suffix = null; @@ -3403,8 +3467,11 @@ var hedyApp = (() => { var policyName = "dompurify" + (suffix ? "#" + suffix : ""); try { return trustedTypes.createPolicy(policyName, { - createHTML: function createHTML(html$$1) { - return html$$1; + createHTML: function createHTML(html2) { + return html2; + }, + createScriptURL: function createScriptURL(scriptUrl) { + return scriptUrl; } }); } catch (_) { @@ -3417,7 +3484,7 @@ var hedyApp = (() => { var DOMPurify3 = function DOMPurify4(root) { return createDOMPurify(root); }; - DOMPurify3.version = "2.3.5"; + DOMPurify3.version = "2.5.4"; DOMPurify3.removed = []; if (!window3 || !window3.document || window3.document.nodeType !== 9) { DOMPurify3.isSupported = false; @@ -3447,13 +3514,13 @@ var hedyApp = (() => { } catch (_) { } var hooks = {}; - DOMPurify3.isSupported = typeof getParentNode === "function" && implementation && typeof implementation.createHTMLDocument !== "undefined" && documentMode !== 9; - var MUSTACHE_EXPR$$1 = MUSTACHE_EXPR, ERB_EXPR$$1 = ERB_EXPR, DATA_ATTR$$1 = DATA_ATTR, ARIA_ATTR$$1 = ARIA_ATTR, IS_SCRIPT_OR_DATA$$1 = IS_SCRIPT_OR_DATA, ATTR_WHITESPACE$$1 = ATTR_WHITESPACE; - var IS_ALLOWED_URI$$1 = IS_ALLOWED_URI; + DOMPurify3.isSupported = typeof getParentNode === "function" && implementation && implementation.createHTMLDocument !== void 0 && documentMode !== 9; + var MUSTACHE_EXPR$1 = MUSTACHE_EXPR, ERB_EXPR$1 = ERB_EXPR, TMPLIT_EXPR$1 = TMPLIT_EXPR, DATA_ATTR$1 = DATA_ATTR, ARIA_ATTR$1 = ARIA_ATTR, IS_SCRIPT_OR_DATA$1 = IS_SCRIPT_OR_DATA, ATTR_WHITESPACE$1 = ATTR_WHITESPACE, CUSTOM_ELEMENT$1 = CUSTOM_ELEMENT; + var IS_ALLOWED_URI$1 = IS_ALLOWED_URI; var ALLOWED_TAGS = null; - var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(html), _toConsumableArray$1(svg), _toConsumableArray$1(svgFilters), _toConsumableArray$1(mathMl), _toConsumableArray$1(text))); + var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray(html$1), _toConsumableArray(svg$1), _toConsumableArray(svgFilters), _toConsumableArray(mathMl$1), _toConsumableArray(text))); var ALLOWED_ATTR = null; - var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray$1(html$1), _toConsumableArray$1(svg$1), _toConsumableArray$1(mathMl$1), _toConsumableArray$1(xml))); + var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray(html), _toConsumableArray(svg), _toConsumableArray(mathMl), _toConsumableArray(xml))); var CUSTOM_ELEMENT_HANDLING = Object.seal(Object.create(null, { tagNameCheck: { writable: true, @@ -3479,7 +3546,9 @@ var hedyApp = (() => { var ALLOW_ARIA_ATTR = true; var ALLOW_DATA_ATTR = true; var ALLOW_UNKNOWN_PROTOCOLS = false; + var ALLOW_SELF_CLOSE_IN_ATTR = true; var SAFE_FOR_TEMPLATES = false; + var SAFE_FOR_XML = true; var WHOLE_DOCUMENT = false; var SET_CONFIG = false; var FORCE_BODY = false; @@ -3487,6 +3556,8 @@ var hedyApp = (() => { var RETURN_DOM_FRAGMENT = false; var RETURN_TRUSTED_TYPE = false; var SANITIZE_DOM = true; + var SANITIZE_NAMED_PROPS = false; + var SANITIZE_NAMED_PROPS_PREFIX = "user-content-"; var KEEP_CONTENT = true; var IN_PLACE = false; var USE_PROFILES = {}; @@ -3501,11 +3572,14 @@ var hedyApp = (() => { var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml"; var NAMESPACE = HTML_NAMESPACE; var IS_EMPTY_INPUT = false; - var PARSER_MEDIA_TYPE = void 0; + var ALLOWED_NAMESPACES = null; + var DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString); + var PARSER_MEDIA_TYPE; var SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"]; var DEFAULT_PARSER_MEDIA_TYPE = "text/html"; - var transformCaseFunc = void 0; + var transformCaseFunc; var CONFIG = null; + var MAX_NESTING_DEPTH = 255; var formElement = document2.createElement("form"); var isRegexOrFunction = function isRegexOrFunction2(testValue) { return testValue instanceof RegExp || testValue instanceof Function; @@ -3514,32 +3588,39 @@ var hedyApp = (() => { if (CONFIG && CONFIG === cfg) { return; } - if (!cfg || (typeof cfg === "undefined" ? "undefined" : _typeof2(cfg)) !== "object") { + if (!cfg || _typeof2(cfg) !== "object") { cfg = {}; } cfg = clone4(cfg); - ALLOWED_TAGS = "ALLOWED_TAGS" in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS; - ALLOWED_ATTR = "ALLOWED_ATTR" in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR; - URI_SAFE_ATTRIBUTES = "ADD_URI_SAFE_ATTR" in cfg ? addToSet(clone4(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES; - DATA_URI_TAGS = "ADD_DATA_URI_TAGS" in cfg ? addToSet(clone4(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS; - FORBID_CONTENTS = "FORBID_CONTENTS" in cfg ? addToSet({}, cfg.FORBID_CONTENTS) : DEFAULT_FORBID_CONTENTS; - FORBID_TAGS = "FORBID_TAGS" in cfg ? addToSet({}, cfg.FORBID_TAGS) : {}; - FORBID_ATTR = "FORBID_ATTR" in cfg ? addToSet({}, cfg.FORBID_ATTR) : {}; + PARSER_MEDIA_TYPE = SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE; + transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase; + ALLOWED_TAGS = "ALLOWED_TAGS" in cfg ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS; + ALLOWED_ATTR = "ALLOWED_ATTR" in cfg ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR; + ALLOWED_NAMESPACES = "ALLOWED_NAMESPACES" in cfg ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES; + URI_SAFE_ATTRIBUTES = "ADD_URI_SAFE_ATTR" in cfg ? addToSet(clone4(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES; + DATA_URI_TAGS = "ADD_DATA_URI_TAGS" in cfg ? addToSet(clone4(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS; + FORBID_CONTENTS = "FORBID_CONTENTS" in cfg ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS; + FORBID_TAGS = "FORBID_TAGS" in cfg ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {}; + FORBID_ATTR = "FORBID_ATTR" in cfg ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {}; USE_PROFILES = "USE_PROFILES" in cfg ? cfg.USE_PROFILES : false; ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; + ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; + SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; RETURN_DOM = cfg.RETURN_DOM || false; RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; FORCE_BODY = cfg.FORCE_BODY || false; SANITIZE_DOM = cfg.SANITIZE_DOM !== false; + SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; KEEP_CONTENT = cfg.KEEP_CONTENT !== false; IN_PLACE = cfg.IN_PLACE || false; - IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1; + IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$1; NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE; + CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {}; if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) { CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck; } @@ -3549,10 +3630,6 @@ var hedyApp = (() => { if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === "boolean") { CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements; } - PARSER_MEDIA_TYPE = SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE; - transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? function(x) { - return x; - } : stringToLowerCase; if (SAFE_FOR_TEMPLATES) { ALLOW_DATA_ATTR = false; } @@ -3560,25 +3637,25 @@ var hedyApp = (() => { RETURN_DOM = true; } if (USE_PROFILES) { - ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(text))); + ALLOWED_TAGS = addToSet({}, _toConsumableArray(text)); ALLOWED_ATTR = []; if (USE_PROFILES.html === true) { - addToSet(ALLOWED_TAGS, html); - addToSet(ALLOWED_ATTR, html$1); + addToSet(ALLOWED_TAGS, html$1); + addToSet(ALLOWED_ATTR, html); } if (USE_PROFILES.svg === true) { - addToSet(ALLOWED_TAGS, svg); - addToSet(ALLOWED_ATTR, svg$1); + addToSet(ALLOWED_TAGS, svg$1); + addToSet(ALLOWED_ATTR, svg); addToSet(ALLOWED_ATTR, xml); } if (USE_PROFILES.svgFilters === true) { addToSet(ALLOWED_TAGS, svgFilters); - addToSet(ALLOWED_ATTR, svg$1); + addToSet(ALLOWED_ATTR, svg); addToSet(ALLOWED_ATTR, xml); } if (USE_PROFILES.mathMl === true) { - addToSet(ALLOWED_TAGS, mathMl); - addToSet(ALLOWED_ATTR, mathMl$1); + addToSet(ALLOWED_TAGS, mathMl$1); + addToSet(ALLOWED_ATTR, mathMl); addToSet(ALLOWED_ATTR, xml); } } @@ -3586,22 +3663,22 @@ var hedyApp = (() => { if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) { ALLOWED_TAGS = clone4(ALLOWED_TAGS); } - addToSet(ALLOWED_TAGS, cfg.ADD_TAGS); + addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc); } if (cfg.ADD_ATTR) { if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) { ALLOWED_ATTR = clone4(ALLOWED_ATTR); } - addToSet(ALLOWED_ATTR, cfg.ADD_ATTR); + addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc); } if (cfg.ADD_URI_SAFE_ATTR) { - addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR); + addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc); } if (cfg.FORBID_CONTENTS) { if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) { FORBID_CONTENTS = clone4(FORBID_CONTENTS); } - addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS); + addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc); } if (KEEP_CONTENT) { ALLOWED_TAGS["#text"] = true; @@ -3619,22 +3696,26 @@ var hedyApp = (() => { CONFIG = cfg; }; var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ["mi", "mo", "mn", "ms", "mtext"]); - var HTML_INTEGRATION_POINTS = addToSet({}, ["foreignobject", "desc", "title", "annotation-xml"]); - var ALL_SVG_TAGS = addToSet({}, svg); + var HTML_INTEGRATION_POINTS = addToSet({}, ["foreignobject", "annotation-xml"]); + var COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ["title", "style", "font", "a", "script"]); + var ALL_SVG_TAGS = addToSet({}, svg$1); addToSet(ALL_SVG_TAGS, svgFilters); addToSet(ALL_SVG_TAGS, svgDisallowed); - var ALL_MATHML_TAGS = addToSet({}, mathMl); + var ALL_MATHML_TAGS = addToSet({}, mathMl$1); addToSet(ALL_MATHML_TAGS, mathMlDisallowed); var _checkValidNamespace = function _checkValidNamespace2(element) { var parent = getParentNode(element); if (!parent || !parent.tagName) { parent = { - namespaceURI: HTML_NAMESPACE, + namespaceURI: NAMESPACE, tagName: "template" }; } var tagName = stringToLowerCase(element.tagName); var parentTagName = stringToLowerCase(parent.tagName); + if (!ALLOWED_NAMESPACES[element.namespaceURI]) { + return false; + } if (element.namespaceURI === SVG_NAMESPACE) { if (parent.namespaceURI === HTML_NAMESPACE) { return tagName === "svg"; @@ -3660,13 +3741,17 @@ var hedyApp = (() => { if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) { return false; } - var commonSvgAndHTMLElements = addToSet({}, ["title", "style", "font", "a", "script"]); - return !ALL_MATHML_TAGS[tagName] && (commonSvgAndHTMLElements[tagName] || !ALL_SVG_TAGS[tagName]); + return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]); + } + if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) { + return true; } return false; }; var _forceRemove = function _forceRemove2(node) { - arrayPush(DOMPurify3.removed, { element: node }); + arrayPush(DOMPurify3.removed, { + element: node + }); try { node.parentNode.removeChild(node); } catch (_) { @@ -3705,15 +3790,15 @@ var hedyApp = (() => { } }; var _initDocument = function _initDocument2(dirty) { - var doc2 = void 0; - var leadingWhitespace = void 0; + var doc2; + var leadingWhitespace; if (FORCE_BODY) { dirty = "" + dirty; } else { var matches2 = stringMatch(dirty, /^[\r\n\t ]+/); leadingWhitespace = matches2 && matches2[0]; } - if (PARSER_MEDIA_TYPE === "application/xhtml+xml") { + if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && NAMESPACE === HTML_NAMESPACE) { dirty = '' + dirty + ""; } var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty; @@ -3726,7 +3811,7 @@ var hedyApp = (() => { if (!doc2 || !doc2.documentElement) { doc2 = implementation.createDocument(NAMESPACE, "template", null); try { - doc2.documentElement.innerHTML = IS_EMPTY_INPUT ? "" : dirtyPayload; + doc2.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload; } catch (_) { } } @@ -3740,13 +3825,13 @@ var hedyApp = (() => { return WHOLE_DOCUMENT ? doc2.documentElement : body; }; var _createIterator = function _createIterator2(root) { - return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter2.SHOW_ELEMENT | NodeFilter2.SHOW_COMMENT | NodeFilter2.SHOW_TEXT, null, false); + return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter2.SHOW_ELEMENT | NodeFilter2.SHOW_COMMENT | NodeFilter2.SHOW_TEXT | NodeFilter2.SHOW_PROCESSING_INSTRUCTION | NodeFilter2.SHOW_CDATA_SECTION, null, false); }; var _isClobbered = function _isClobbered2(elm) { - return elm instanceof HTMLFormElement && (typeof elm.nodeName !== "string" || typeof elm.textContent !== "string" || typeof elm.removeChild !== "function" || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== "function" || typeof elm.setAttribute !== "function" || typeof elm.namespaceURI !== "string" || typeof elm.insertBefore !== "function"); + return elm instanceof HTMLFormElement && (typeof elm.__depth !== "undefined" && typeof elm.__depth !== "number" || typeof elm.__removalCount !== "undefined" && typeof elm.__removalCount !== "number" || typeof elm.nodeName !== "string" || typeof elm.textContent !== "string" || typeof elm.removeChild !== "function" || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== "function" || typeof elm.setAttribute !== "function" || typeof elm.namespaceURI !== "string" || typeof elm.insertBefore !== "function" || typeof elm.hasChildNodes !== "function"); }; var _isNode = function _isNode2(object) { - return (typeof Node2 === "undefined" ? "undefined" : _typeof2(Node2)) === "object" ? object instanceof Node2 : object && (typeof object === "undefined" ? "undefined" : _typeof2(object)) === "object" && typeof object.nodeType === "number" && typeof object.nodeName === "string"; + return _typeof2(Node2) === "object" ? object instanceof Node2 : object && _typeof2(object) === "object" && typeof object.nodeType === "number" && typeof object.nodeName === "string"; }; var _executeHook = function _executeHook2(entryPoint, currentNode, data) { if (!hooks[entryPoint]) { @@ -3757,13 +3842,13 @@ var hedyApp = (() => { }); }; var _sanitizeElements = function _sanitizeElements2(currentNode) { - var content2 = void 0; + var content2; _executeHook("beforeSanitizeElements", currentNode, null); if (_isClobbered(currentNode)) { _forceRemove(currentNode); return true; } - if (stringMatch(currentNode.nodeName, /[\u0080-\uFFFF]/)) { + if (regExpTest(/[\u0080-\uFFFF]/, currentNode.nodeName)) { _forceRemove(currentNode); return true; } @@ -3772,7 +3857,7 @@ var hedyApp = (() => { tagName, allowedTags: ALLOWED_TAGS }); - if (!_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) { + if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) { _forceRemove(currentNode); return true; } @@ -3780,23 +3865,33 @@ var hedyApp = (() => { _forceRemove(currentNode); return true; } + if (currentNode.nodeType === 7) { + _forceRemove(currentNode); + return true; + } + if (SAFE_FOR_XML && currentNode.nodeType === 8 && regExpTest(/<[/\w]/g, currentNode.data)) { + _forceRemove(currentNode); + return true; + } if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { + if (!FORBID_TAGS[tagName] && _basicCustomElementTest(tagName)) { + if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) + return false; + if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) + return false; + } if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) { var parentNode = getParentNode(currentNode) || currentNode.parentNode; var childNodes = getChildNodes(currentNode) || currentNode.childNodes; if (childNodes && parentNode) { var childCount = childNodes.length; for (var i = childCount - 1; i >= 0; --i) { - parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode)); + var childClone = cloneNode(childNodes[i], true); + childClone.__removalCount = (currentNode.__removalCount || 0) + 1; + parentNode.insertBefore(childClone, getNextSibling(currentNode)); } } } - if (!FORBID_TAGS[tagName] && _basicCustomElementTest(tagName)) { - if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) - return false; - if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) - return false; - } _forceRemove(currentNode); return true; } @@ -3804,16 +3899,19 @@ var hedyApp = (() => { _forceRemove(currentNode); return true; } - if ((tagName === "noscript" || tagName === "noembed") && regExpTest(/<\/no(script|embed)/i, currentNode.innerHTML)) { + if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) { _forceRemove(currentNode); return true; } if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) { content2 = currentNode.textContent; - content2 = stringReplace(content2, MUSTACHE_EXPR$$1, " "); - content2 = stringReplace(content2, ERB_EXPR$$1, " "); + content2 = stringReplace(content2, MUSTACHE_EXPR$1, " "); + content2 = stringReplace(content2, ERB_EXPR$1, " "); + content2 = stringReplace(content2, TMPLIT_EXPR$1, " "); if (currentNode.textContent !== content2) { - arrayPush(DOMPurify3.removed, { element: currentNode.cloneNode() }); + arrayPush(DOMPurify3.removed, { + element: currentNode.cloneNode() + }); currentNode.textContent = content2; } } @@ -3821,12 +3919,12 @@ var hedyApp = (() => { return false; }; var _isValidAttribute = function _isValidAttribute2(lcTag, lcName, value) { - if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document2 || value in formElement)) { + if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document2 || value in formElement || value === "__depth" || value === "__removalCount")) { return false; } - if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$$1, lcName)) + if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$1, lcName)) ; - else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$$1, lcName)) + else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) { if (_basicCustomElementTest(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) || lcName === "is" && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) @@ -3836,27 +3934,26 @@ var hedyApp = (() => { } } else if (URI_SAFE_ATTRIBUTES[lcName]) ; - else if (regExpTest(IS_ALLOWED_URI$$1, stringReplace(value, ATTR_WHITESPACE$$1, ""))) + else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) ; else if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]) ; - else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$$1, stringReplace(value, ATTR_WHITESPACE$$1, ""))) - ; - else if (!value) + else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, ""))) ; - else { + else if (value) { return false; - } + } else + ; return true; }; var _basicCustomElementTest = function _basicCustomElementTest2(tagName) { - return tagName.indexOf("-") > 0; + return tagName !== "annotation-xml" && stringMatch(tagName, CUSTOM_ELEMENT$1); }; var _sanitizeAttributes = function _sanitizeAttributes2(currentNode) { - var attr = void 0; - var value = void 0; - var lcName = void 0; - var l = void 0; + var attr; + var value; + var lcName; + var l; _executeHook("beforeSanitizeAttributes", currentNode, null); var attributes = currentNode.attributes; if (!attributes) { @@ -3872,7 +3969,7 @@ var hedyApp = (() => { while (l--) { attr = attributes[l]; var _attr = attr, name2 = _attr.name, namespaceURI = _attr.namespaceURI; - value = stringTrim(attr.value); + value = name2 === "value" ? attr.value : stringTrim(attr.value); lcName = transformCaseFunc(name2); hookEvent.attrName = lcName; hookEvent.attrValue = value; @@ -3887,32 +3984,61 @@ var hedyApp = (() => { if (!hookEvent.keepAttr) { continue; } - if (regExpTest(/\/>/i, value)) { + if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) { + _removeAttribute(name2, currentNode); + continue; + } + if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) { _removeAttribute(name2, currentNode); continue; } if (SAFE_FOR_TEMPLATES) { - value = stringReplace(value, MUSTACHE_EXPR$$1, " "); - value = stringReplace(value, ERB_EXPR$$1, " "); + value = stringReplace(value, MUSTACHE_EXPR$1, " "); + value = stringReplace(value, ERB_EXPR$1, " "); + value = stringReplace(value, TMPLIT_EXPR$1, " "); } var lcTag = transformCaseFunc(currentNode.nodeName); if (!_isValidAttribute(lcTag, lcName, value)) { continue; } + if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name")) { + _removeAttribute(name2, currentNode); + value = SANITIZE_NAMED_PROPS_PREFIX + value; + } + if (trustedTypesPolicy && _typeof2(trustedTypes) === "object" && typeof trustedTypes.getAttributeType === "function") { + if (namespaceURI) + ; + else { + switch (trustedTypes.getAttributeType(lcTag, lcName)) { + case "TrustedHTML": { + value = trustedTypesPolicy.createHTML(value); + break; + } + case "TrustedScriptURL": { + value = trustedTypesPolicy.createScriptURL(value); + break; + } + } + } + } try { if (namespaceURI) { currentNode.setAttributeNS(namespaceURI, name2, value); } else { currentNode.setAttribute(name2, value); } - arrayPop(DOMPurify3.removed); + if (_isClobbered(currentNode)) { + _forceRemove(currentNode); + } else { + arrayPop(DOMPurify3.removed); + } } catch (_) { } } _executeHook("afterSanitizeAttributes", currentNode, null); }; var _sanitizeShadowDOM = function _sanitizeShadowDOM2(fragment) { - var shadowNode = void 0; + var shadowNode; var shadowIterator = _createIterator(fragment); _executeHook("beforeSanitizeShadowDOM", fragment, null); while (shadowNode = shadowIterator.nextNode()) { @@ -3920,31 +4046,44 @@ var hedyApp = (() => { if (_sanitizeElements(shadowNode)) { continue; } + var parentNode = getParentNode(shadowNode); + if (shadowNode.nodeType === 1) { + if (parentNode && parentNode.__depth) { + shadowNode.__depth = (shadowNode.__removalCount || 0) + parentNode.__depth + 1; + } else { + shadowNode.__depth = 1; + } + } + if (shadowNode.__depth >= MAX_NESTING_DEPTH || numberIsNaN(shadowNode.__depth)) { + _forceRemove(shadowNode); + } if (shadowNode.content instanceof DocumentFragment) { + shadowNode.content.__depth = shadowNode.__depth; _sanitizeShadowDOM2(shadowNode.content); } _sanitizeAttributes(shadowNode); } _executeHook("afterSanitizeShadowDOM", fragment, null); }; - DOMPurify3.sanitize = function(dirty, cfg) { - var body = void 0; - var importedNode = void 0; - var currentNode = void 0; - var oldNode = void 0; - var returnNode = void 0; + DOMPurify3.sanitize = function(dirty) { + var cfg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; + var body; + var importedNode; + var currentNode; + var oldNode; + var returnNode; IS_EMPTY_INPUT = !dirty; if (IS_EMPTY_INPUT) { dirty = ""; } if (typeof dirty !== "string" && !_isNode(dirty)) { - if (typeof dirty.toString !== "function") { - throw typeErrorCreate("toString is not a function"); - } else { + if (typeof dirty.toString === "function") { dirty = dirty.toString(); if (typeof dirty !== "string") { throw typeErrorCreate("dirty is not a string, aborting"); } + } else { + throw typeErrorCreate("toString is not a function"); } } if (!DOMPurify3.isSupported) { @@ -4002,7 +4141,19 @@ var hedyApp = (() => { if (_sanitizeElements(currentNode)) { continue; } + var parentNode = getParentNode(currentNode); + if (currentNode.nodeType === 1) { + if (parentNode && parentNode.__depth) { + currentNode.__depth = (currentNode.__removalCount || 0) + parentNode.__depth + 1; + } else { + currentNode.__depth = 1; + } + } + if (currentNode.__depth >= MAX_NESTING_DEPTH || numberIsNaN(currentNode.__depth)) { + _forceRemove(currentNode); + } if (currentNode.content instanceof DocumentFragment) { + currentNode.content.__depth = currentNode.__depth; _sanitizeShadowDOM(currentNode.content); } _sanitizeAttributes(currentNode); @@ -4021,15 +4172,19 @@ var hedyApp = (() => { } else { returnNode = body; } - if (ALLOWED_ATTR.shadowroot) { + if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmod) { returnNode = importNode.call(originalDocument, returnNode, true); } return returnNode; } var serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML; + if (WHOLE_DOCUMENT && ALLOWED_TAGS["!doctype"] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) { + serializedHTML = "\n" + serializedHTML; + } if (SAFE_FOR_TEMPLATES) { - serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$$1, " "); - serializedHTML = stringReplace(serializedHTML, ERB_EXPR$$1, " "); + serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$1, " "); + serializedHTML = stringReplace(serializedHTML, ERB_EXPR$1, " "); + serializedHTML = stringReplace(serializedHTML, TMPLIT_EXPR$1, " "); } return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML; }; @@ -4058,7 +4213,7 @@ var hedyApp = (() => { }; DOMPurify3.removeHook = function(entryPoint) { if (hooks[entryPoint]) { - arrayPop(hooks[entryPoint]); + return arrayPop(hooks[entryPoint]); } }; DOMPurify3.removeHooks = function(entryPoint) { @@ -60651,7 +60806,7 @@ ${o3}` : i3; "unsaved_class_changes": "There are unsaved changes, are you sure you want to leave this page?" }, "ca": { - "CheckInternet": "Mireu si la vostra connexi\xF3 a Internet funciona correctament.", + "CheckInternet": "Mireu si la teva connexi\xF3 a Internet funciona correctament.", "Connection_error": "No hem pogut arribar al servidor.", "Empty_output": "Aquest codi funciona, per\xF2 no imprimeix res. Afegiu una comanda d'impressi\xF3 al vostre codi o utilitzeu la tortuga per obtenir la sortida.", "Errors_found": "Has com\xE8s un error! No et preocupis, encara podem executar el programa", @@ -60984,28 +61139,28 @@ ${o3}` : i3; "Transpile_success": "\xA1Buen trabajo!\n\xA1Increible!\n\xA1Bien hecho!\n\xA1Excelente!\n\xA1Lo hiciste genial!", "Transpile_warning": "\xA1Cuidado!", "Unsaved_Changes": "Tu programa no se ha guardado. \xBFDeseas irte sin guardarlo?", - "adventures_completed": "Adventures completed: {number_of_adventures}", + "adventures_completed": "Aventuras completadas: {number_of_adventures}", "adventures_restored": "Se han restaurado las aventuras por defecto.", - "adventures_tried": "Adventures tried", + "adventures_tried": "Aventuras intentadas", "copy_link_to_share": "Copiar enlace para compartir", "customization_deleted": "Personalizaci\xF3n eliminada.", "dice": "\u{1F3B2}", "directly_available": "Directamente abierto", "disabled": "Deshabilitado", - "errors": "Errors", + "errors": "Errores", "fortune": "\u{1F52E}, \u2728", - "graph_title": "Errors per adventure completed on level {level}", + "graph_title": "Errores por aventura completada en el nivel {level}", "haunted": "\u{1F987}, \u{1F47B}, \u{1F383}", "level_title": "Nivel", "multiple_keywords_warning": "Est\xE1 intentando utilizar la palabra clave {orig_keyword}, pero esta palabra clave puede tener varios significados. Por favor, elija la que est\xE1 intentando utilizar de esta lista y c\xF3piela y p\xE9guela en su c\xF3digo, llaves incluidas: {keyword_list}", - "number_of_errors": "Number of errors: {number_of_errors}", - "one_level_error": "You need to select at least one level.", + "number_of_errors": "N\xFAmero de errores: {number_of_errors}", + "one_level_error": "Debes seleccionar al menos un nivel.", "restaurant": "\u{1F363}, \u{1F355}, \u{1F354}", "rock": "\u2702\uFE0F, \u{1F4DC}, \u{1F5FB}", "select_all": "Seleccionar todo", "selected": "Seleccionado", "songs": "\u{1F3B5},\u{1F3B6}", - "successful_runs": "Successful runs: {successful_runs}", + "successful_runs": "Ejecuciones exitosas: {successful_runs}", "teacher_welcome": "\xA1Bienvenido/a a Hedy! Tu cuenta es de tipo profesor, por lo que puedes crear clases e invitar estudiantes.", "turtle": "\u{1F422}", "unsaved_class_changes": "Hay cambios sin guardar, \xBFest\xE1s seguro de que quieres abandonar esta p\xE1gina?" @@ -61784,9 +61939,9 @@ ${o3}` : i3; "Transpile_success": "Goed gedaan!\nGa zo door!\nTopper!\nSuper!\nBravo!", "Transpile_warning": "Let op!", "Unsaved_Changes": "Jouw programma is niet opgeslagen. Wil je weggaan zonder het op te slaan?", - "adventures_completed": "Adventures completed: {number_of_adventures}", + "adventures_completed": "Adventuren afgerond: {number_of_adventures}", "adventures_restored": "De standaardavonturen zijn terug gezet.", - "adventures_tried": "Adventures tried", + "adventures_tried": "Adventuren geprobeerd", "copy_link_to_share": "Kopieer link voor delen", "customization_deleted": "Personalisatie succesvol verwijderd.", "dice": "\u{1F3B2}", @@ -61794,7 +61949,7 @@ ${o3}` : i3; "disabled": "Gedeactiveerd", "errors": "Errors", "fortune": "\u{1F52E}, \u2728", - "graph_title": "Errors per adventure completed on level {level}", + "graph_title": "Fouten per avontuur in level {level}", "haunted": "\u{1F987}, \u{1F47B}, \u{1F383}", "level_title": "Level", "multiple_keywords_warning": "You are trying to use the keyword {orig_keyword}, but this keyword might have several meanings. Please choose the one you're trying to use from this list and copy paste it in your code, curly braces included: {keyword_list}", @@ -62251,19 +62406,19 @@ ${o3}` : i3; "unsaved_class_changes": "There are unsaved changes, are you sure you want to leave this page?" }, "sr": { - "CheckInternet": "Proveri da li ima\u0161 internet konekciju.", - "Connection_error": "Ne mogu dostignuti server.", - "Empty_output": "Ovaj kod radi, ali ne prikazuje ni\u0161ta. Dodaj komandu za prikazivanje u kodu ili koristi turtle da prika\u017Ee\u0161 rezultat.", - "Errors_found": "Napravio si gre\u0161ku! Ne brini, i dalje smo uspeli da pokrenemo program", - "Execute_error": "Ne\u0161to se pokvarilo dok je program radio.", - "Other_error": "Ups! Mo\u017Eda smo napravili malu gre\u0161ku.", - "Program_repair": "Mo\u017Eda je ovo ispravan kod, mo\u017Ee\u0161 li ga popraviti?", - "Program_too_long": "Tvoj program zahteva mnogo vremena za pokretanje.", - "ServerError": "Napisali ste program koji nismo o\u010Dekivali. Ako \u017Eelite da pomognete, po\u0161aljite nam mejl sa nivoom i va\u0161im programom na hello@hedy.org. U me\u0111uvremenu, poku\u0161ajte ne\u0161to malo druga\u010Dije i pogledajte jo\u0161 jednom primere. Hvala!", - "Transpile_error": "Ne mo\u017Eemo da pokrenemo tvoj program.", - "Transpile_success": "Dobar posao!\nNeverovatno!\nDobro ura\u0111eno!\nOdli\u010Dno!\nBio si odli\u010Dan!", - "Transpile_warning": "Upozorenje!", - "Unsaved_Changes": "Nisi sa\u010Duvao program. \u017Deli\u0161 li da iza\u0111e\u0161 bez \u010Duvanja?", + "CheckInternet": "\u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u0435 \u0434\u0430 \u043B\u0438 \u0432\u0430\u0448\u0430 \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442 \u0432\u0435\u0437\u0430 \u0440\u0430\u0434\u0438.", + "Connection_error": "\u041D\u0438\u0441\u043C\u043E \u043C\u043E\u0433\u043B\u0438 \u0434\u0430 \u043F\u0440\u0438\u0441\u0442\u0443\u043F\u0438\u043C\u043E \u0441\u0435\u0440\u0432\u0435\u0440\u0443.", + "Empty_output": "\u041E\u0432\u0430\u0458 \u043A\u043E\u0434 \u0440\u0430\u0434\u0438, \u0430\u043B\u0438 \u043D\u0435 \u043F\u0440\u0438\u043A\u0430\u0437\u0443\u0458\u0435 \u043D\u0438\u0448\u0442\u0430. \u0414\u043E\u0434\u0430\u0458\u0442\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0443 \u0437\u0430 \u043F\u0440\u0438\u043A\u0430\u0437\u0438\u0432\u0430\u045A\u0435 \u0443 \u0432\u0430\u0448 \u043A\u043E\u0434 \u0438\u043B\u0438 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 \u043A\u043E\u0440\u045A\u0430\u0447\u0443 \u0437\u0430 \u0434\u043E\u0431\u0438\u0458\u0430\u045A\u0435 \u0438\u0437\u043B\u0430\u0437\u0430.", + "Errors_found": "\u041D\u0430\u043F\u0440\u0430\u0432\u0438\u043B\u0438 \u0441\u0442\u0435 \u0433\u0440\u0435\u0448\u043A\u0443! \u041D\u0435 \u0431\u0440\u0438\u043D\u0438\u0442\u0435, \u0438\u043F\u0430\u043A \u0441\u043C\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u043B\u0438 \u043F\u0440\u043E\u0433\u0440\u0430\u043C.", + "Execute_error": "\u041D\u0435\u0448\u0442\u043E \u0458\u0435 \u043F\u043E\u0448\u043B\u043E \u043D\u0430\u043E\u043F\u0430\u043A\u043E \u043F\u0440\u0438\u043B\u0438\u043A\u043E\u043C \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0430.", + "Other_error": "\u0423\u043F\u0441! \u041C\u043E\u0436\u0434\u0430 \u0441\u043C\u043E \u043D\u0430\u043F\u0440\u0430\u0432\u0438\u043B\u0438 \u043C\u0430\u043B\u0443 \u0433\u0440\u0435\u0448\u043A\u0443.", + "Program_repair": "\u041E\u0432\u043E \u0431\u0438 \u043C\u043E\u0433\u0430\u043E \u0431\u0438\u0442\u0438 \u0438\u0441\u043F\u0440\u0430\u0432\u0430\u043D \u043A\u043E\u0434, \u043C\u043E\u0436\u0435\u0442\u0435 \u043B\u0438 \u0433\u0430 \u043F\u043E\u043F\u0440\u0430\u0432\u0438\u0442\u0438?", + "Program_too_long": "\u0412\u0430\u0448 \u043F\u0440\u043E\u0433\u0440\u0430\u043C \u0442\u0440\u0430\u0458\u0435 \u043F\u0440\u0435\u0434\u0443\u0433\u043E \u0434\u0430 \u0441\u0435 \u0438\u0437\u0432\u0440\u0448\u0438.", + "ServerError": "\u041D\u0430\u043F\u0438\u0441\u0430\u043B\u0438 \u0441\u0442\u0435 \u043F\u0440\u043E\u0433\u0440\u0430\u043C \u043A\u043E\u0458\u0438 \u043D\u0438\u0441\u043C\u043E \u043E\u0447\u0435\u043A\u0438\u0432\u0430\u043B\u0438. \u0410\u043A\u043E \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043F\u043E\u043C\u043E\u0433\u043D\u0435\u0442\u0435, \u043F\u043E\u0448\u0430\u0459\u0438\u0442\u0435 \u043D\u0430\u043C \u0438\u043C\u0435\u0458\u043B \u0441\u0430 \u043D\u0438\u0432\u043E\u043E\u043C \u0438 \u0432\u0430\u0448\u0438\u043C \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043E\u043C \u043D\u0430 hello@hedy.org. \u0423 \u043C\u0435\u0452\u0443\u0432\u0440\u0435\u043C\u0435\u043D\u0443, \u043F\u0440\u043E\u0431\u0430\u0458\u0442\u0435 \u043D\u0435\u0448\u0442\u043E \u043C\u0430\u043B\u043E \u0434\u0440\u0443\u0433\u0430\u0447\u0438\u0458\u0435 \u0438 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u043F\u0440\u0438\u043C\u0435\u0440\u0435. \u0425\u0432\u0430\u043B\u0430!", + "Transpile_error": "\u041D\u0435 \u043C\u043E\u0436\u0435\u043C\u043E \u0434\u0430 \u043F\u043E\u043A\u0440\u0435\u043D\u0435\u043C\u043E \u0432\u0430\u0448 \u043F\u0440\u043E\u0433\u0440\u0430\u043C.", + "Transpile_success": "\u0414\u043E\u0431\u0430\u0440 \u043F\u043E\u0441\u0430\u043E!\n\u041D\u0435\u0432\u0435\u0440\u043E\u0432\u0430\u0442\u043D\u043E!\n\u0411\u0440\u0430\u0432\u043E!\n\u041E\u0434\u043B\u0438\u0447\u043D\u043E!\n\u0421\u0458\u0430\u0458\u043D\u043E \u0441\u0438 \u0443\u0440\u0430\u0434\u0438\u043E!", + "Transpile_warning": "\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435!", + "Unsaved_Changes": "\u0418\u043C\u0430\u0442\u0435 \u043D\u0435\u0441\u0430\u0447\u0443\u0432\u0430\u043D \u043F\u0440\u043E\u0433\u0440\u0430\u043C. \u0414\u0430 \u043B\u0438 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0438\u0437\u0430\u0452\u0435\u0442\u0435 \u0431\u0435\u0437 \u0447\u0443\u0432\u0430\u045A\u0430?", "adventures_completed": "Adventures completed: {number_of_adventures}", "adventures_restored": "Podrazumevane avanture su vra\u0107ene.", "adventures_tried": "Adventures tried", @@ -98905,7 +99060,7 @@ def note_with_error(value, err): True: "\u0418\u0441\u0442\u0438\u043D\u0430|True", add: "\u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C|add", and: "\u0438|and", - ask: "\u0437\u0430\u043F\u0440\u043E\u0441\u0438\u0442\u044C|ask", + ask: "\u0441\u043F\u0440\u043E\u0441\u0438\u0442\u044C|ask", at: "\u0432|at", black: "\u0447\u0451\u0440\u043D\u044B\u0439|black", blue: "\u0441\u0438\u043D\u0438\u0439|blue", @@ -99078,62 +99233,62 @@ def note_with_error(value, err): DIGIT: "0123456789" }; var sr = { - False: "False", - True: "True", - add: "dodaj|add", - and: "i|and", - ask: "pitaj|ask", - at: "na|at", - black: "crna|black", - blue: "plava|blue", - brown: "braon|brown", - call: "call", - clear: "o\u010Disti|clear", - color: "boja|color", + False: "\u041D\u0435\u0442\u0430\u0447\u043D\u043E|False", + True: "\u0422\u0430\u0447\u043D\u043E|True", + add: "\u0434\u043E\u0434\u0430\u0458|add", + and: "\u0438|and", + ask: "\u043F\u0438\u0442\u0430\u0458|ask", + at: "\u043D\u0430|at", + black: "\u0446\u0440\u043D\u0430|black", + blue: "\u043F\u043B\u0430\u0432\u0430|blue", + brown: "\u0431\u0440\u0430\u043E\u043D|brown", + call: "\u043F\u043E\u0437\u043E\u0432\u0438|call", + clear: "\u043E\u0447\u0438\u0441\u0442\u0438|clear", + color: "\u0431\u043E\u0458\u0430|color", comma: ",", - def: "def", - define: "defini\u0161i|define", - echo: "poka\u017Ei|echo", - elif: "ina\u010De ako|elif", - else: "ina\u010De|else", - false: "false", - for: "za|for", - forward: "napred|forward", - from: "od|from", - gray: "siva|gray", - green: "zelena|green", - if: "ako|if", - in: "u|in", - input: "ulaz|input", - is: "je|is", - left: "levo|left", - length: "du\u017Eina|length", - not_in: "ne/nije u|not in", - or: "ili|or", - orange: "narand\u017Easta|orange", - pink: "roze|pink", - play: "play", - pressed: "pritisnuto|pressed", - print: "\u0161tampaj|print", - purple: "ljubi\u010Dasta|purple", - random: "nasumi\u010Dno|random", - range: "opseg|range", - red: "crvena|red", - remove: "obri\u0161i|remove", - repeat: "ponovi|repeat", - return: "vrati|return", - right: "desno|right", - sleep: "spavanje|sleep", - step: "korak|step", - times: "vremena|times", - to: "u|to", - to_list: "u|to", - true: "true", - turn: "okreni|turn", - while: "dok|while", - white: "bela|white", - with: "sa|with", - yellow: "\u017Euta|yellow", + def: "\u0434\u0435\u0444|def", + define: "\u0434\u0435\u0444\u0438\u043D\u0438\u0448\u0438|define", + echo: "\u043F\u043E\u043A\u0430\u0436\u0438|echo", + elif: "\u0438\u043D\u0430\u0447\u0435 \u0430\u043A\u043E|elif", + else: "\u0438\u043D\u0430\u0447\u0435|else", + false: "\u043D\u0435\u0442\u0430\u0447\u043D\u043E|false", + for: "\u0437\u0430|for", + forward: "\u043D\u0430\u043F\u0440\u0435\u0434|forward", + from: "\u043E\u0434|from", + gray: "\u0441\u0438\u0432\u0430|gray", + green: "\u0437\u0435\u043B\u0435\u043D\u0430|green", + if: "\u0430\u043A\u043E|if", + in: "\u0443|in", + input: "\u0443\u043B\u0430\u0437|input", + is: "\u0458\u0435|is", + left: "\u043B\u0435\u0432\u043E|left", + length: "\u0434\u0443\u0436\u0438\u043D\u0430|length", + not_in: "\u043D\u0435/\u043D\u0438\u0458\u0435 \u0443|not in", + or: "\u0438\u043B\u0438|or", + orange: "\u043D\u0430\u0440\u0430\u043D\u045F\u0430\u0441\u0442\u0430|orange", + pink: "\u0440\u043E\u0437\u0435|pink", + play: "\u0438\u0433\u0440\u0430\u0458|play", + pressed: "\u043F\u0440\u0438\u0442\u0438\u0441\u043D\u0443\u0442\u043E|pressed", + print: "\u0448\u0442\u0430\u043C\u043F\u0430\u0458|print", + purple: "\u0459\u0443\u0431\u0438\u0447\u0430\u0441\u0442\u0430|purple", + random: "\u043D\u0430\u0441\u0443\u043C\u0438\u0447\u043D\u043E|random", + range: "\u043E\u043F\u0441\u0435\u0433|range", + red: "\u0446\u0440\u0432\u0435\u043D\u0430|red", + remove: "\u043E\u0431\u0440\u0438\u0448\u0438|remove", + repeat: "\u043F\u043E\u043D\u043E\u0432\u0438|repeat", + return: "\u0432\u0440\u0430\u0442\u0438|return", + right: "\u0434\u0435\u0441\u043D\u043E|right", + sleep: "\u0441\u043F\u0430\u0432\u0430\u045A\u0435|sleep", + step: "\u043A\u043E\u0440\u0430\u043A|step", + times: "\u043F\u0443\u0442\u0430|times", + to: "\u0434\u043E|to", + to_list: "\u0434\u043E|to", + true: "\u0442\u0430\u0447\u043D\u043E|true", + turn: "\u043E\u043A\u0440\u0435\u043D\u0438|turn", + while: "\u0434\u043E\u043A|while", + white: "\u0431\u0435\u043B\u0430|white", + with: "\u0441\u0430|with", + yellow: "\u0436\u0443\u0442\u0430|yellow", DIGIT: "0123456789" }; var sv = { @@ -104046,6 +104201,7 @@ def note_with_error(value, err): } } function stopDebug() { + var _a3; if (step_debugger === true) { var debugButton = $("#debug_button"); debugButton.show(); @@ -104053,7 +104209,7 @@ def note_with_error(value, err): var stopButton = $("#debug_stop"); var resetButton = $("#debug_restart"); var runButtonContainer = $("#run_button_container"); - document.getElementById("debug_continue").removeAttribute("disabled"); + (_a3 = document.getElementById("debug_continue")) == null ? void 0 : _a3.removeAttribute("disabled"); $("#stopit").hide(); $("#runit").show(); runButtonContainer.show(); @@ -104076,7 +104232,8 @@ def note_with_error(value, err): } } function incrementDebugLine() { - document.getElementById("debug_continue").removeAttribute("disabled"); + var _a3; + (_a3 = document.getElementById("debug_continue")) == null ? void 0 : _a3.removeAttribute("disabled"); const active_suspension = theGlobalDebugger.getActiveSuspension(); const suspension_info = theGlobalDebugger.getSuspensionInfo(active_suspension); const lineNumber = suspension_info.lineno; @@ -126971,7 +127128,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. * */ -/*! @license DOMPurify 2.3.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.5/LICENSE */ +/*! @license DOMPurify 2.5.4 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.5.4/LICENSE */ /** * Tone.js * @author Yotam Mann diff --git a/static/js/appbundle.js.map b/static/js/appbundle.js.map index a87ac1c053f..5a718eb645e 100644 --- a/static/js/appbundle.js.map +++ b/static/js/appbundle.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../node_modules/jszip/dist/jszip.min.js", "../../node_modules/@babel/runtime/helpers/arrayWithHoles.js", "../../node_modules/@babel/runtime/helpers/iterableToArrayLimit.js", "../../node_modules/@babel/runtime/helpers/arrayLikeToArray.js", "../../node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js", "../../node_modules/@babel/runtime/helpers/nonIterableRest.js", "../../node_modules/@babel/runtime/helpers/slicedToArray.js", "../../node_modules/@babel/runtime/helpers/classCallCheck.js", "../../node_modules/@babel/runtime/helpers/typeof.js", "../../node_modules/@babel/runtime/helpers/toPrimitive.js", "../../node_modules/@babel/runtime/helpers/toPropertyKey.js", "../../node_modules/@babel/runtime/helpers/createClass.js", "../../node_modules/automation-events/build/es5/bundle.js", "../../node_modules/dompurify/src/utils.js", "../../node_modules/dompurify/src/tags.js", "../../node_modules/dompurify/src/attrs.js", "../../node_modules/dompurify/src/regexp.js", "../../node_modules/dompurify/src/purify.js", "ckeditor.js", "index.ts", "message-translations.ts", "client-messages.ts", "modal.ts", "app.ts", "../../node_modules/tone/Tone/version.ts", "../../node_modules/standardized-audio-context/src/module.ts", "../../node_modules/standardized-audio-context/src/factories/abort-error.ts", "../../node_modules/standardized-audio-context/src/factories/add-active-input-connection-to-audio-node.ts", "../../node_modules/standardized-audio-context/src/factories/add-audio-node-connections.ts", "../../node_modules/standardized-audio-context/src/factories/add-audio-param-connections.ts", "../../node_modules/standardized-audio-context/src/globals.ts", "../../node_modules/standardized-audio-context/src/helpers/is-constructible.ts", "../../node_modules/standardized-audio-context/src/helpers/split-import-statements.ts", "../../node_modules/standardized-audio-context/src/factories/add-audio-worklet-module.ts", "../../node_modules/standardized-audio-context/src/helpers/get-value-for-key.ts", "../../node_modules/standardized-audio-context/src/helpers/pick-element-from-set.ts", "../../node_modules/standardized-audio-context/src/helpers/delete-passive-input-connection-to-audio-node.ts", "../../node_modules/standardized-audio-context/src/helpers/get-event-listeners-of-audio-node.ts", "../../node_modules/standardized-audio-context/src/helpers/set-internal-state-to-active.ts", "../../node_modules/standardized-audio-context/src/guards/audio-worklet-node.ts", "../../node_modules/standardized-audio-context/src/helpers/set-internal-state-to-passive.ts", "../../node_modules/standardized-audio-context/src/helpers/set-internal-state-to-passive-when-necessary.ts", "../../node_modules/standardized-audio-context/src/factories/add-connection-to-audio-node.ts", "../../node_modules/standardized-audio-context/src/factories/add-passive-input-connection-to-audio-node.ts", "../../node_modules/standardized-audio-context/src/factories/add-silent-connection.ts", "../../node_modules/standardized-audio-context/src/factories/add-unrendered-audio-worklet-node.ts", "../../node_modules/standardized-audio-context/src/factories/analyser-node-constructor.ts", "../../node_modules/standardized-audio-context/src/helpers/is-owned-by-context.ts", "../../node_modules/standardized-audio-context/src/factories/analyser-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/helpers/test-audio-buffer-copy-channel-methods-out-of-bounds-support.ts", "../../node_modules/standardized-audio-context/src/factories/index-size-error.ts", "../../node_modules/standardized-audio-context/src/helpers/wrap-audio-buffer-get-channel-data-method.ts", "../../node_modules/standardized-audio-context/src/factories/audio-buffer-constructor.ts", "../../node_modules/standardized-audio-context/src/constants.ts", "../../node_modules/standardized-audio-context/src/helpers/is-active-audio-node.ts", "../../node_modules/standardized-audio-context/src/factories/audio-buffer-source-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/audio-buffer-source-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/guards/audio-buffer-source-node.ts", "../../node_modules/standardized-audio-context/src/guards/biquad-filter-node.ts", "../../node_modules/standardized-audio-context/src/guards/constant-source-node.ts", "../../node_modules/standardized-audio-context/src/guards/gain-node.ts", "../../node_modules/standardized-audio-context/src/guards/oscillator-node.ts", "../../node_modules/standardized-audio-context/src/guards/stereo-panner-node.ts", "../../node_modules/standardized-audio-context/src/helpers/get-audio-node-connections.ts", "../../node_modules/standardized-audio-context/src/helpers/get-audio-param-connections.ts", "../../node_modules/standardized-audio-context/src/helpers/deactivate-active-audio-node-input-connections.ts", "../../node_modules/standardized-audio-context/src/helpers/deactivate-audio-graph.ts", "../../node_modules/standardized-audio-context/src/helpers/is-valid-latency-hint.ts", "../../node_modules/standardized-audio-context/src/factories/audio-context-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/audio-destination-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/audio-destination-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/audio-listener-factory.ts", "../../node_modules/standardized-audio-context/src/guards/audio-node.ts", "../../node_modules/standardized-audio-context/src/guards/audio-node-output-connection.ts", "../../node_modules/standardized-audio-context/src/helpers/insert-element-in-set.ts", "../../node_modules/standardized-audio-context/src/helpers/add-active-input-connection-to-audio-param.ts", "../../node_modules/standardized-audio-context/src/helpers/add-passive-input-connection-to-audio-param.ts", "../../node_modules/standardized-audio-context/src/guards/native-audio-node-faker.ts", "../../node_modules/standardized-audio-context/src/helpers/connect-native-audio-node-to-native-audio-node.ts", "../../node_modules/standardized-audio-context/src/helpers/delete-active-input-connection.ts", "../../node_modules/standardized-audio-context/src/helpers/delete-active-input-connection-to-audio-param.ts", "../../node_modules/standardized-audio-context/src/helpers/delete-event-listeners-of-audio-node.ts", "../../node_modules/standardized-audio-context/src/helpers/delete-passive-input-connection-to-audio-param.ts", "../../node_modules/standardized-audio-context/src/helpers/disconnect-native-audio-node-from-native-audio-node.ts", "../../node_modules/standardized-audio-context/src/helpers/get-native-audio-node.ts", "../../node_modules/standardized-audio-context/src/helpers/get-native-audio-param.ts", "../../node_modules/standardized-audio-context/src/helpers/is-part-of-a-cycle.ts", "../../node_modules/standardized-audio-context/src/helpers/is-passive-audio-node.ts", "../../node_modules/standardized-audio-context/src/helpers/test-audio-node-disconnect-method-support.ts", "../../node_modules/standardized-audio-context/src/helpers/visit-each-audio-node-once.ts", "../../node_modules/standardized-audio-context/src/guards/native-audio-node.ts", "../../node_modules/standardized-audio-context/src/helpers/wrap-audio-node-disconnect-method.ts", "../../node_modules/standardized-audio-context/src/factories/audio-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/audio-param-factory.ts", "../../node_modules/standardized-audio-context/src/factories/audio-param-renderer.ts", "../../node_modules/standardized-audio-context/src/read-only-map.ts", "../../node_modules/standardized-audio-context/src/factories/audio-worklet-node-constructor.ts", "../../node_modules/standardized-audio-context/src/helpers/copy-from-channel.ts", "../../node_modules/standardized-audio-context/src/helpers/copy-to-channel.ts", "../../node_modules/standardized-audio-context/src/helpers/create-nested-arrays.ts", "../../node_modules/standardized-audio-context/src/helpers/get-audio-worklet-processor.ts", "../../node_modules/standardized-audio-context/src/factories/audio-worklet-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/base-audio-context-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/biquad-filter-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/biquad-filter-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/cache-test-result.ts", "../../node_modules/standardized-audio-context/src/factories/channel-merger-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/channel-merger-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/channel-splitter-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/channel-splitter-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/connect-audio-param.ts", "../../node_modules/standardized-audio-context/src/factories/connect-multiple-outputs.ts", "../../node_modules/standardized-audio-context/src/factories/connected-native-audio-buffer-source-node-factory.ts", "../../node_modules/standardized-audio-context/src/factories/constant-source-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/constant-source-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/convert-number-to-unsigned-long.ts", "../../node_modules/standardized-audio-context/src/factories/convolver-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/convolver-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/create-native-offline-audio-context.ts", "../../node_modules/standardized-audio-context/src/factories/data-clone-error.ts", "../../node_modules/standardized-audio-context/src/helpers/detach-array-buffer.ts", "../../node_modules/standardized-audio-context/src/factories/decode-audio-data.ts", "../../node_modules/standardized-audio-context/src/factories/decrement-cycle-counter.ts", "../../node_modules/standardized-audio-context/src/factories/delay-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/delay-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/delete-active-input-connection-to-audio-node.ts", "../../node_modules/standardized-audio-context/src/factories/delete-unrendered-audio-worklet-node.ts", "../../node_modules/standardized-audio-context/src/guards/delay-node.ts", "../../node_modules/standardized-audio-context/src/factories/detect-cycles.ts", "../../node_modules/standardized-audio-context/src/factories/disconnect-multiple-outputs.ts", "../../node_modules/standardized-audio-context/src/factories/dynamics-compressor-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/dynamics-compressor-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/encoding-error.ts", "../../node_modules/standardized-audio-context/src/factories/evaluate-source.ts", "../../node_modules/standardized-audio-context/src/factories/event-target-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/expose-current-frame-and-current-time.ts", "../../node_modules/standardized-audio-context/src/factories/fetch-source.ts", "../../node_modules/standardized-audio-context/src/factories/gain-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/gain-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/get-active-audio-worklet-node-inputs.ts", "../../node_modules/standardized-audio-context/src/factories/get-audio-node-renderer.ts", "../../node_modules/standardized-audio-context/src/factories/get-audio-node-tail-time.ts", "../../node_modules/standardized-audio-context/src/factories/get-audio-param-renderer.ts", "../../node_modules/standardized-audio-context/src/factories/get-backup-offline-audio-context.ts", "../../node_modules/standardized-audio-context/src/factories/invalid-state-error.ts", "../../node_modules/standardized-audio-context/src/factories/get-native-context.ts", "../../node_modules/standardized-audio-context/src/factories/get-or-create-backup-offline-audio-context.ts", "../../node_modules/standardized-audio-context/src/factories/get-unrendered-audio-worklet-nodes.ts", "../../node_modules/standardized-audio-context/src/factories/invalid-access-error.ts", "../../node_modules/standardized-audio-context/src/helpers/wrap-iir-filter-node-get-frequency-response-method.ts", "../../node_modules/standardized-audio-context/src/factories/iir-filter-node-constructor.ts", "../../node_modules/standardized-audio-context/src/helpers/filter-buffer.ts", "../../node_modules/standardized-audio-context/src/factories/iir-filter-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/increment-cycle-counter-factory.ts", "../../node_modules/standardized-audio-context/src/factories/is-any-audio-context.ts", "../../node_modules/standardized-audio-context/src/factories/is-any-audio-node.ts", "../../node_modules/standardized-audio-context/src/factories/is-any-audio-param.ts", "../../node_modules/standardized-audio-context/src/factories/is-any-offline-audio-context.ts", "../../node_modules/standardized-audio-context/src/factories/is-native-audio-context.ts", "../../node_modules/standardized-audio-context/src/factories/is-native-audio-node.ts", "../../node_modules/standardized-audio-context/src/factories/is-native-audio-param.ts", "../../node_modules/standardized-audio-context/src/factories/is-native-context.ts", "../../node_modules/standardized-audio-context/src/factories/is-native-offline-audio-context.ts", "../../node_modules/standardized-audio-context/src/factories/is-secure-context.ts", "../../node_modules/standardized-audio-context/src/factories/media-element-audio-source-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/media-stream-audio-destination-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/media-stream-audio-source-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/media-stream-track-audio-source-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/minimal-audio-context-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/minimal-base-audio-context-constructor.ts", "../../node_modules/standardized-audio-context/src/helpers/test-promise-support.ts", "../../node_modules/standardized-audio-context/src/factories/minimal-offline-audio-context-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/monitor-connections.ts", "../../node_modules/standardized-audio-context/src/helpers/assign-native-audio-node-option.ts", "../../node_modules/standardized-audio-context/src/helpers/assign-native-audio-node-options.ts", "../../node_modules/standardized-audio-context/src/helpers/test-analyser-node-get-float-time-domain-data-method-support.ts", "../../node_modules/standardized-audio-context/src/helpers/wrap-analyser-node-get-float-time-domain-data-method.ts", "../../node_modules/standardized-audio-context/src/factories/native-analyser-node-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-audio-buffer-constructor.ts", "../../node_modules/standardized-audio-context/src/helpers/assign-native-audio-node-audio-param-value.ts", "../../node_modules/standardized-audio-context/src/helpers/wrap-audio-buffer-source-node-start-method-consecutive-calls.ts", "../../node_modules/standardized-audio-context/src/helpers/wrap-audio-scheduled-source-node-start-method-negative-parameters.ts", "../../node_modules/standardized-audio-context/src/helpers/wrap-audio-scheduled-source-node-stop-method-negative-parameters.ts", "../../node_modules/standardized-audio-context/src/factories/native-audio-buffer-source-node-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-audio-context-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/native-audio-destination-node.ts", "../../node_modules/standardized-audio-context/src/factories/native-audio-worklet-node-constructor.ts", "../../node_modules/standardized-audio-context/src/helpers/test-clonability-of-audio-worklet-node-options.ts", "../../node_modules/standardized-audio-context/src/factories/native-audio-worklet-node-factory.ts", "../../node_modules/standardized-audio-context/src/helpers/compute-buffer-size.ts", "../../node_modules/standardized-audio-context/src/helpers/clone-audio-worklet-node-options.ts", "../../node_modules/standardized-audio-context/src/helpers/create-audio-worklet-processor-promise.ts", "../../node_modules/standardized-audio-context/src/helpers/create-audio-worklet-processor.ts", "../../node_modules/standardized-audio-context/src/factories/native-audio-worklet-node-faker-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-biquad-filter-node.ts", "../../node_modules/standardized-audio-context/src/factories/native-channel-merger-node-factory.ts", "../../node_modules/standardized-audio-context/src/helpers/wrap-channel-splitter-node.ts", "../../node_modules/standardized-audio-context/src/factories/native-channel-splitter-node.ts", "../../node_modules/standardized-audio-context/src/factories/native-constant-source-node-factory.ts", "../../node_modules/standardized-audio-context/src/helpers/intercept-connections.ts", "../../node_modules/standardized-audio-context/src/factories/native-constant-source-node-faker-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-convolver-node-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-delay-node.ts", "../../node_modules/standardized-audio-context/src/factories/native-dynamics-compressor-node-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-gain-node.ts", "../../node_modules/standardized-audio-context/src/factories/native-iir-filter-node-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-iir-filter-node-faker-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-media-element-audio-source-node.ts", "../../node_modules/standardized-audio-context/src/factories/native-media-stream-audio-destination-node.ts", "../../node_modules/standardized-audio-context/src/factories/native-media-stream-audio-source-node.ts", "../../node_modules/standardized-audio-context/src/factories/native-media-stream-track-audio-source-node-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-offline-audio-context-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/native-oscillator-node-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-panner-node-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-panner-node-faker-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-periodic-wave-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-script-processor-node.ts", "../../node_modules/standardized-audio-context/src/factories/native-stereo-panner-node-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-stereo-panner-node-faker-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-wave-shaper-node-factory.ts", "../../node_modules/standardized-audio-context/src/factories/native-wave-shaper-node-faker-factory.ts", "../../node_modules/standardized-audio-context/src/factories/not-supported-error.ts", "../../node_modules/standardized-audio-context/src/factories/offline-audio-context-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/oscillator-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/oscillator-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/panner-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/panner-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/periodic-wave-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/render-automation.ts", "../../node_modules/standardized-audio-context/src/factories/render-inputs-of-audio-node.ts", "../../node_modules/standardized-audio-context/src/factories/render-inputs-of-audio-param.ts", "../../node_modules/standardized-audio-context/src/factories/render-native-offline-audio-context.ts", "../../node_modules/standardized-audio-context/src/factories/set-active-audio-worklet-node-inputs.ts", "../../node_modules/standardized-audio-context/src/factories/set-audio-node-tail-time.ts", "../../node_modules/standardized-audio-context/src/factories/start-rendering.ts", "../../node_modules/standardized-audio-context/src/factories/stereo-panner-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/stereo-panner-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/test-audio-buffer-constructor-support.ts", "../../node_modules/standardized-audio-context/src/factories/test-audio-worklet-processor-post-message-support.ts", "../../node_modules/standardized-audio-context/src/factories/test-offline-audio-context-current-time-support.ts", "../../node_modules/standardized-audio-context/src/factories/unknown-error.ts", "../../node_modules/standardized-audio-context/src/factories/wave-shaper-node-constructor.ts", "../../node_modules/standardized-audio-context/src/factories/wave-shaper-node-renderer-factory.ts", "../../node_modules/standardized-audio-context/src/factories/window.ts", "../../node_modules/standardized-audio-context/src/factories/wrap-audio-buffer-copy-channel-methods.ts", "../../node_modules/standardized-audio-context/src/factories/wrap-audio-buffer-copy-channel-methods-out-of-bounds.ts", "../../node_modules/standardized-audio-context/src/factories/wrap-audio-buffer-source-node-stop-method-nullified-buffer.ts", "../../node_modules/standardized-audio-context/src/factories/wrap-channel-merger-node.ts", "../../node_modules/standardized-audio-context/src/helpers/get-first-sample.ts", "../../node_modules/standardized-audio-context/src/helpers/is-dc-curve.ts", "../../node_modules/standardized-audio-context/src/helpers/overwrite-accessors.ts", "../../node_modules/standardized-audio-context/src/helpers/sanitize-audio-worklet-node-options.ts", "../../node_modules/standardized-audio-context/src/helpers/sanitize-channel-splitter-options.ts", "../../node_modules/standardized-audio-context/src/helpers/sanitize-periodic-wave-options.ts", "../../node_modules/standardized-audio-context/src/helpers/set-value-at-time-until-possible.ts", "../../node_modules/standardized-audio-context/src/helpers/test-audio-buffer-source-node-start-method-consecutive-calls-support.ts", "../../node_modules/standardized-audio-context/src/helpers/test-audio-buffer-source-node-start-method-offset-clamping-support.ts", "../../node_modules/standardized-audio-context/src/helpers/test-audio-buffer-source-node-stop-method-nullified-buffer-support.ts", "../../node_modules/standardized-audio-context/src/helpers/test-audio-scheduled-source-node-start-method-negative-parameters-support.ts", "../../node_modules/standardized-audio-context/src/helpers/test-audio-scheduled-source-node-stop-method-consecutive-calls-support.ts", "../../node_modules/standardized-audio-context/src/helpers/test-audio-scheduled-source-node-stop-method-negative-parameters-support.ts", "../../node_modules/standardized-audio-context/src/helpers/test-audio-worklet-node-options-clonability.ts", "../../node_modules/standardized-audio-context/src/helpers/wrap-audio-buffer-source-node-start-method-offset-clamping.ts", "../../node_modules/standardized-audio-context/src/helpers/wrap-audio-scheduled-source-node-stop-method-consecutive-calls.ts", "../../node_modules/standardized-audio-context/src/helpers/wrap-event-listener.ts", "../../node_modules/tone/Tone/core/util/Debug.ts", "../../node_modules/tone/Tone/core/util/TypeCheck.ts", "../../node_modules/tone/Tone/core/context/AudioContext.ts", "../../node_modules/tslib/tslib.es6.mjs", "../../node_modules/tone/Tone/core/clock/Ticker.ts", "../../node_modules/tone/Tone/core/util/AdvancedTypeCheck.ts", "../../node_modules/tone/Tone/core/util/Defaults.ts", "../../node_modules/tone/Tone/core/Tone.ts", "../../node_modules/tone/Tone/core/util/Math.ts", "../../node_modules/tone/Tone/core/util/Timeline.ts", "../../node_modules/tone/Tone/core/context/ContextInitialization.ts", "../../node_modules/tone/Tone/core/util/Emitter.ts", "../../node_modules/tone/Tone/core/context/BaseContext.ts", "../../node_modules/tone/Tone/core/context/Context.ts", "../../node_modules/tone/Tone/core/context/DummyContext.ts", "../../node_modules/tone/Tone/core/util/Interface.ts", "../../node_modules/tone/Tone/core/context/ToneAudioBuffer.ts", "../../node_modules/tone/Tone/core/context/OfflineContext.ts", "../../node_modules/tone/Tone/core/Global.ts", "../../node_modules/tone/Tone/core/type/Conversions.ts", "../../node_modules/tone/Tone/core/type/TimeBase.ts", "../../node_modules/tone/Tone/core/type/Time.ts", "../../node_modules/tone/Tone/core/type/Frequency.ts", "../../node_modules/tone/Tone/core/type/TransportTime.ts", "../../node_modules/tone/Tone/core/context/ToneWithContext.ts", "../../node_modules/tone/Tone/core/util/StateTimeline.ts", "../../node_modules/tone/Tone/core/context/Param.ts", "../../node_modules/tone/Tone/core/context/ToneAudioNode.ts", "../../node_modules/tone/Tone/core/context/Gain.ts", "../../node_modules/tone/Tone/source/OneShotSource.ts", "../../node_modules/tone/Tone/signal/ToneConstantSource.ts", "../../node_modules/tone/Tone/signal/Signal.ts", "../../node_modules/tone/Tone/core/clock/TickParam.ts", "../../node_modules/tone/Tone/core/clock/TickSignal.ts", "../../node_modules/tone/Tone/core/clock/TickSource.ts", "../../node_modules/tone/Tone/core/clock/Clock.ts", "../../node_modules/tone/Tone/core/context/ToneAudioBuffers.ts", "../../node_modules/tone/Tone/core/type/Midi.ts", "../../node_modules/tone/Tone/core/type/Ticks.ts", "../../node_modules/tone/Tone/core/util/Draw.ts", "../../node_modules/tone/Tone/core/util/IntervalTimeline.ts", "../../node_modules/tone/Tone/component/channel/Volume.ts", "../../node_modules/tone/Tone/core/context/Destination.ts", "../../node_modules/tone/Tone/core/util/TimelineValue.ts", "../../node_modules/tone/Tone/core/clock/TransportEvent.ts", "../../node_modules/tone/Tone/core/clock/TransportRepeatEvent.ts", "../../node_modules/tone/Tone/core/clock/Transport.ts", "../../node_modules/tone/Tone/source/Source.ts", "../../node_modules/tone/Tone/source/buffer/ToneBufferSource.ts", "../../node_modules/tone/Tone/source/Noise.ts", "../../node_modules/tone/Tone/source/oscillator/OscillatorInterface.ts", "../../node_modules/tone/Tone/source/oscillator/ToneOscillatorNode.ts", "../../node_modules/tone/Tone/source/oscillator/Oscillator.ts", "../../node_modules/tone/Tone/signal/SignalOperator.ts", "../../node_modules/tone/Tone/signal/WaveShaper.ts", "../../node_modules/tone/Tone/signal/AudioToGain.ts", "../../node_modules/tone/Tone/signal/Multiply.ts", "../../node_modules/tone/Tone/source/oscillator/AMOscillator.ts", "../../node_modules/tone/Tone/source/oscillator/FMOscillator.ts", "../../node_modules/tone/Tone/source/oscillator/PulseOscillator.ts", "../../node_modules/tone/Tone/source/oscillator/FatOscillator.ts", "../../node_modules/tone/Tone/source/oscillator/PWMOscillator.ts", "../../node_modules/tone/Tone/source/oscillator/OmniOscillator.ts", "../../node_modules/tone/Tone/core/util/Decorator.ts", "../../node_modules/tone/Tone/source/buffer/Player.ts", "../../node_modules/tone/Tone/component/envelope/Envelope.ts", "../../node_modules/tone/Tone/instrument/Instrument.ts", "../../node_modules/tone/Tone/instrument/Monophonic.ts", "../../node_modules/tone/Tone/component/envelope/AmplitudeEnvelope.ts", "../../node_modules/tone/Tone/instrument/Synth.ts", "../../node_modules/tone/Tone/instrument/MembraneSynth.ts", "../../node_modules/tone/Tone/core/worklet/WorkletGlobalScope.ts", "../../node_modules/tone/Tone/core/worklet/ToneAudioWorkletProcessor.worklet.ts", "../../node_modules/tone/Tone/core/worklet/SingleIOProcessor.worklet.ts", "../../node_modules/tone/Tone/core/worklet/DelayLine.worklet.ts", "../../node_modules/tone/Tone/component/filter/FeedbackCombFilter.worklet.ts", "../../node_modules/tone/Tone/instrument/PolySynth.ts", "../../node_modules/tone/Tone/instrument/Sampler.ts", "../../node_modules/tone/Tone/component/channel/Panner.ts", "../../node_modules/tone/Tone/effect/BitCrusher.worklet.ts", "../../node_modules/tone/Tone/effect/Freeverb.ts", "../../node_modules/tone/Tone/effect/JCReverb.ts", "../../node_modules/tone/Tone/component/channel/Solo.ts", "../../node_modules/tone/Tone/component/channel/PanVol.ts", "../../node_modules/tone/Tone/component/channel/Channel.ts", "../../node_modules/tone/Tone/core/context/Listener.ts", "../../node_modules/tone/Tone/index.ts", "event-emitter.ts", "tabs.ts", "pythonPrefixes.ts", "types.ts", "tutorials/utils.ts", "tutorials/intro.ts", "tutorials/teacher.ts", "tutorials/level1.ts", "tutorials/tutorial.ts", "editor.ts", "../../node_modules/@codemirror/state/dist/index.js", "../../node_modules/style-mod/src/style-mod.js", "../../node_modules/w3c-keyname/index.js", "../../node_modules/@codemirror/view/dist/index.js", "../../node_modules/@lezer/common/dist/index.js", "../../node_modules/@lezer/highlight/dist/index.js", "../../node_modules/@codemirror/language/dist/index.js", "../../node_modules/@codemirror/commands/dist/index.js", "../../node_modules/crelt/index.js", "../../node_modules/@codemirror/search/dist/index.js", "cm-decorations.ts", "../../node_modules/@lezer/lr/dist/index.js", "lezer-parsers/level1-parser.terms.ts", "lezer-parsers/level2-parser.terms.ts", "lezer-parsers/level3-parser.terms.ts", "lezer-parsers/level4-parser.terms.ts", "lezer-parsers/level5-parser.terms.ts", "lezer-parsers/level6-parser.terms.ts", "lezer-parsers/level7-parser.terms.ts", "lezer-parsers/level8-parser.terms.ts", "lezer-parsers/level10-parser.terms.ts", "lezer-parsers/level11-parser.terms.ts", "lezer-parsers/level12-parser.terms.ts", "lezer-parsers/level13-parser.terms.ts", "lezer-parsers/level14-parser.terms.ts", "lezer-parsers/level15-parser.terms.ts", "lezer-parsers/level16-parser.terms.ts", "lezer-parsers/level17-parser.terms.ts", "lezer-parsers/level18-parser.terms.ts", "utils.ts", "lezer-parsers/tokens.ts", "lezer-parsers/level1-parser.ts", "lezer-parsers/level2-parser.ts", "lezer-parsers/level3-parser.ts", "lezer-parsers/level4-parser.ts", "lezer-parsers/level5-parser.ts", "lezer-parsers/level6-parser.ts", "lezer-parsers/level7-parser.ts", "lezer-parsers/level8-parser.ts", "lezer-parsers/level9-parser.ts", "lezer-parsers/level10-parser.ts", "lezer-parsers/level11-parser.ts", "lezer-parsers/level12-parser.ts", "lezer-parsers/level13-parser.ts", "lezer-parsers/level14-parser.ts", "lezer-parsers/level15-parser.ts", "lezer-parsers/level16-parser.ts", "lezer-parsers/level17-parser.ts", "lezer-parsers/level18-parser.ts", "lezer-parsers/language-packages.ts", "cm-monokai-theme.ts", "cm-editor.ts", "../../node_modules/sortablejs/modular/sortable.esm.js", "parsons.ts", "browser-helpers/on-element-becomes-visible.ts", "debugging.ts", "local.ts", "teachers.ts", "adventure.ts", "autosave.ts", "../../node_modules/@kurkle/color/dist/color.esm.js", "../../node_modules/chart.js/src/helpers/helpers.core.ts", "../../node_modules/chart.js/src/helpers/helpers.math.ts", "../../node_modules/chart.js/src/helpers/helpers.collection.ts", "../../node_modules/chart.js/src/helpers/helpers.extras.ts", "../../node_modules/chart.js/src/helpers/helpers.easing.ts", "../../node_modules/chart.js/src/helpers/helpers.color.ts", "../../node_modules/chart.js/src/core/core.animations.defaults.js", "../../node_modules/chart.js/src/core/core.layouts.defaults.js", "../../node_modules/chart.js/src/helpers/helpers.intl.ts", "../../node_modules/chart.js/src/core/core.ticks.js", "../../node_modules/chart.js/src/core/core.scale.defaults.js", "../../node_modules/chart.js/src/core/core.defaults.js", "../../node_modules/chart.js/src/helpers/helpers.canvas.ts", "../../node_modules/chart.js/src/helpers/helpers.options.ts", "../../node_modules/chart.js/src/helpers/helpers.config.ts", "../../node_modules/chart.js/src/helpers/helpers.curve.ts", "../../node_modules/chart.js/src/helpers/helpers.dom.ts", "../../node_modules/chart.js/src/helpers/helpers.interpolation.ts", "../../node_modules/chart.js/src/helpers/helpers.rtl.ts", "../../node_modules/chart.js/src/helpers/helpers.segment.js", "../../node_modules/chart.js/src/core/core.animator.js", "../../node_modules/chart.js/src/core/core.animation.js", "../../node_modules/chart.js/src/core/core.animations.js", "../../node_modules/chart.js/src/core/core.datasetController.js", "../../node_modules/chart.js/src/controllers/controller.bar.js", "../../node_modules/chart.js/src/controllers/controller.bubble.js", "../../node_modules/chart.js/src/controllers/controller.doughnut.js", "../../node_modules/chart.js/src/controllers/controller.line.js", "../../node_modules/chart.js/src/controllers/controller.polarArea.js", "../../node_modules/chart.js/src/controllers/controller.pie.js", "../../node_modules/chart.js/src/controllers/controller.radar.js", "../../node_modules/chart.js/src/controllers/controller.scatter.js", "../../node_modules/chart.js/src/core/core.adapters.ts", "../../node_modules/chart.js/src/core/core.interaction.js", "../../node_modules/chart.js/src/core/core.layouts.js", "../../node_modules/chart.js/src/platform/platform.base.js", "../../node_modules/chart.js/src/platform/platform.basic.js", "../../node_modules/chart.js/src/platform/platform.dom.js", "../../node_modules/chart.js/src/platform/index.js", "../../node_modules/chart.js/src/core/core.element.ts", "../../node_modules/chart.js/src/core/core.scale.autoskip.js", "../../node_modules/chart.js/src/core/core.scale.js", "../../node_modules/chart.js/src/core/core.typedRegistry.js", "../../node_modules/chart.js/src/core/core.registry.js", "../../node_modules/chart.js/src/core/core.plugins.js", "../../node_modules/chart.js/src/core/core.config.js", "../../node_modules/chart.js/src/core/core.controller.js", "../../node_modules/chart.js/src/elements/element.arc.ts", "../../node_modules/chart.js/src/elements/element.line.js", "../../node_modules/chart.js/src/elements/element.point.ts", "../../node_modules/chart.js/src/elements/element.bar.js", "../../node_modules/chart.js/src/plugins/plugin.colors.ts", "../../node_modules/chart.js/src/plugins/plugin.decimation.js", "../../node_modules/chart.js/src/plugins/plugin.filler/filler.segment.js", "../../node_modules/chart.js/src/plugins/plugin.filler/filler.helper.js", "../../node_modules/chart.js/src/plugins/plugin.filler/filler.options.js", "../../node_modules/chart.js/src/plugins/plugin.filler/filler.target.stack.js", "../../node_modules/chart.js/src/plugins/plugin.filler/simpleArc.js", "../../node_modules/chart.js/src/plugins/plugin.filler/filler.target.js", "../../node_modules/chart.js/src/plugins/plugin.filler/filler.drawing.js", "../../node_modules/chart.js/src/plugins/plugin.filler/index.js", "../../node_modules/chart.js/src/plugins/plugin.legend.js", "../../node_modules/chart.js/src/plugins/plugin.title.js", "../../node_modules/chart.js/src/plugins/plugin.subtitle.js", "../../node_modules/chart.js/src/plugins/plugin.tooltip.js", "../../node_modules/chart.js/src/scales/scale.category.js", "../../node_modules/chart.js/src/scales/scale.linearbase.js", "../../node_modules/chart.js/src/scales/scale.linear.js", "../../node_modules/chart.js/src/scales/scale.logarithmic.js", "../../node_modules/chart.js/src/scales/scale.radialLinear.js", "../../node_modules/chart.js/src/scales/scale.time.js", "../../node_modules/chart.js/src/scales/scale.timeseries.js", "../../node_modules/chart.js/src/index.ts", "comm.ts", "auth.ts", "local-save-warning.ts", "user-activity.ts", "htmx-integration.ts", "statistics.ts", "logs.ts", "admin.ts", "profile.ts", "initialize.ts", "../../node_modules/tw-elements/src/js/dom/data.js", "../../node_modules/tw-elements/src/js/util/index.js", "../../node_modules/tw-elements/src/js/dom/event-handler.js", "../../node_modules/tw-elements/src/js/base-component.js", "../../node_modules/tw-elements/src/js/components/button.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/enums.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getWindow.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/modifiers/applyStyles.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/getBasePlacement.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/math.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/userAgent.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/contains.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/isTableElement.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getParentNode.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/within.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/getFreshSideObject.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/mergePaddingObject.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/expandToHashMap.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/modifiers/arrow.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/getVariation.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/modifiers/computeStyles.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/modifiers/eventListeners.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/getOppositePlacement.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/rectToClientRect.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/computeOffsets.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/detectOverflow.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/modifiers/flip.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/modifiers/hide.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/modifiers/offset.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/modifiers/popperOffsets.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/getAltAxis.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/modifiers/preventOverflow.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/orderModifiers.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/debounce.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/format.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/validateModifiers.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/uniqueBy.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/utils/mergeByName.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/createPopper.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/popper-lite.js", "../../node_modules/tw-elements/node_modules/@popperjs/core/lib/popper.js", "../../node_modules/tw-elements/src/js/dom/manipulator.js", "../../node_modules/tw-elements/src/js/dom/selector-engine.js", "../../node_modules/tw-elements/src/js/components/dropdown.js", "../../node_modules/tw-elements/src/js/components/collapse.js", "../../node_modules/tw-elements/src/js/util/scrollbar.js", "../../node_modules/tw-elements/src/js/util/backdrop.js", "../../node_modules/tw-elements/src/js/util/focusTrap.js", "../../node_modules/tw-elements/src/js/util/component-functions.js", "../../node_modules/tw-elements/src/js/components/offcanvas.js", "../../node_modules/tw-elements/src/js/components/alert.js", "../../node_modules/tw-elements/src/js/components/carousel.js", "../../node_modules/tw-elements/src/js/components/modal.js", "../../node_modules/tw-elements/src/js/util/sanitizer.js", "../../node_modules/tw-elements/src/js/components/tooltip.js", "../../node_modules/tw-elements/src/js/components/popover.js", "../../node_modules/tw-elements/src/js/navigation/scrollspy.js", "../../node_modules/tw-elements/src/js/navigation/tab.js", "../../node_modules/tw-elements/src/js/components/toast.js", "../../node_modules/tw-elements/node_modules/detect-autofill/dist/detect-autofill.js", "../../node_modules/tw-elements/src/js/forms/input.js", "../../node_modules/tw-elements/src/js/content-styles/animate.js", "../../node_modules/tw-elements/src/js/methods/ripple.js", "../../node_modules/tw-elements/src/js/forms/datepicker/date-utils.js", "../../node_modules/tw-elements/src/js/forms/datepicker/templates.js", "../../node_modules/tw-elements/src/js/util/keycodes.js", "../../node_modules/tw-elements/src/js/forms/datepicker/index.js", "../../node_modules/tw-elements/src/js/forms/timepicker/templates.js", "../../node_modules/tw-elements/src/js/forms/timepicker/utils.js", "../../node_modules/tw-elements/src/js/forms/timepicker/index.js", "../../node_modules/tw-elements/src/js/util/touch/swipe.js", "../../node_modules/tw-elements/src/js/util/touch/index.js", "../../node_modules/tw-elements/src/js/navigation/sidenav.js", "../../node_modules/tw-elements/src/js/components/stepper.js", "../../node_modules/tw-elements/src/js/forms/select/select-option.js", "../../node_modules/tw-elements/src/js/forms/select/selection-model.js", "../../node_modules/tw-elements/src/js/forms/select/util.js", "../../node_modules/tw-elements/src/js/forms/select/templates.js", "../../node_modules/tw-elements/src/js/forms/select/index.js", "../../node_modules/tw-elements/src/js/components/chips/templates.js", "../../node_modules/tw-elements/src/js/components/chips/chip.js", "../../node_modules/tw-elements/src/js/components/chips/index.js", "../../node_modules/tw-elements/src/js/data/chart/chartDefaults.js", "../../node_modules/tw-elements/node_modules/deepmerge/dist/cjs.js", "../../node_modules/tw-elements/src/js/data/chart/charts.js", "../../node_modules/tw-elements/node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js", "../../node_modules/tw-elements/src/js/methods/perfect-scrollbar.js", "../../node_modules/tw-elements/src/js/data/datatables/html/pagination.js", "../../node_modules/tw-elements/src/js/data/datatables/html/columns.js", "../../node_modules/tw-elements/src/js/data/datatables/html/rows.js", "../../node_modules/tw-elements/src/js/data/datatables/html/table.js", "../../node_modules/tw-elements/src/js/data/datatables/util.js", "../../node_modules/tw-elements/src/js/data/datatables/index.js", "../../node_modules/tw-elements/src/js/components/rating.js", "../../node_modules/tw-elements/src/js/components/popconfirm.js", "../../node_modules/tw-elements/src/js/components/lightbox.js", "../../node_modules/tw-elements/src/js/forms/validation/rules.js", "../../node_modules/tw-elements/src/js/forms/validation/validation.js", "../../node_modules/tw-elements/src/js/methods/touch/touchUtil.js", "../../node_modules/tw-elements/src/js/methods/touch/press.js", "../../node_modules/tw-elements/src/js/methods/touch/swipe.js", "../../node_modules/tw-elements/src/js/methods/touch/pan.js", "../../node_modules/tw-elements/src/js/methods/touch/pinch.js", "../../node_modules/tw-elements/src/js/methods/touch/tap.js", "../../node_modules/tw-elements/src/js/methods/touch/rotate.js", "../../node_modules/tw-elements/src/js/methods/touch/index.js", "../../node_modules/tw-elements/src/js/methods/smooth-scroll.js", "../../node_modules/tw-elements/src/js/methods/lazy-load.js", "../../node_modules/tw-elements/src/js/methods/clipboard.js", "../../node_modules/tw-elements/src/js/methods/infinite-scroll.js", "../../node_modules/tw-elements/src/js/methods/loading-management/templates.js", "../../node_modules/tw-elements/src/js/methods/loading-management/index.js", "../../node_modules/tw-elements/src/js/forms/dateTimepicker/utils.js", "../../node_modules/tw-elements/src/js/forms/dateTimepicker/templates.js", "../../node_modules/tw-elements/src/js/forms/dateTimepicker/index.js", "../../node_modules/tw-elements/src/js/methods/sticky.js", "../../node_modules/tw-elements/src/js/autoinit/jqueryInit.js", "../../node_modules/tw-elements/src/js/autoinit/autoinitCallbacks.js", "../../node_modules/tw-elements/src/js/autoinit/chartsInit.js", "../../node_modules/tw-elements/src/js/autoinit/Register.js", "../../node_modules/tw-elements/src/js/autoinit/index.js", "tailwind.ts", "public-adventures.ts", "microbit.ts", "custom-elements.ts"], - "sourcesContent": ["/*!\n\nJSZip v3.10.1 - A JavaScript class for generating and reading zip files\n\n\n(c) 2009-2016 Stuart Knightley \nDual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown.\n\nJSZip uses the library pako released under the MIT license :\nhttps://github.com/nodeca/pako/blob/main/LICENSE\n*/\n\n!function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define([],e);else{(\"undefined\"!=typeof window?window:\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:this).JSZip=e()}}(function(){return function s(a,o,h){function u(r,e){if(!o[r]){if(!a[r]){var t=\"function\"==typeof require&&require;if(!e&&t)return t(r,!0);if(l)return l(r,!0);var n=new Error(\"Cannot find module '\"+r+\"'\");throw n.code=\"MODULE_NOT_FOUND\",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return u(t||e)},i,i.exports,s,a,o,h)}return o[r].exports}for(var l=\"function\"==typeof require&&require,e=0;e>2,s=(3&t)<<4|r>>4,a=1>6:64,o=2>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),l[h++]=t,64!==s&&(l[h++]=r),64!==a&&(l[h++]=n);return l}},{\"./support\":30,\"./utils\":32}],2:[function(e,t,r){\"use strict\";var n=e(\"./external\"),i=e(\"./stream/DataWorker\"),s=e(\"./stream/Crc32Probe\"),a=e(\"./stream/DataLengthProbe\");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a(\"data_length\")),t=this;return e.on(\"end\",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error(\"Bug : uncompressed data size mismatch\")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo(\"compressedSize\",this.compressedSize).withStreamInfo(\"uncompressedSize\",this.uncompressedSize).withStreamInfo(\"crc32\",this.crc32).withStreamInfo(\"compression\",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a(\"uncompressedSize\")).pipe(t.compressWorker(r)).pipe(new a(\"compressedSize\")).withStreamInfo(\"compression\",t)},t.exports=o},{\"./external\":6,\"./stream/Crc32Probe\":25,\"./stream/DataLengthProbe\":26,\"./stream/DataWorker\":27}],3:[function(e,t,r){\"use strict\";var n=e(\"./stream/GenericWorker\");r.STORE={magic:\"\\0\\0\",compressWorker:function(){return new n(\"STORE compression\")},uncompressWorker:function(){return new n(\"STORE decompression\")}},r.DEFLATE=e(\"./flate\")},{\"./flate\":7,\"./stream/GenericWorker\":28}],4:[function(e,t,r){\"use strict\";var n=e(\"./utils\");var o=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t){return void 0!==e&&e.length?\"string\"!==n.getTypeOf(e)?function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}(0|t,e,e.length,0):function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t.charCodeAt(a))];return-1^e}(0|t,e,e.length,0):0}},{\"./utils\":32}],5:[function(e,t,r){\"use strict\";r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null},{}],6:[function(e,t,r){\"use strict\";var n=null;n=\"undefined\"!=typeof Promise?Promise:e(\"lie\"),t.exports={Promise:n}},{lie:37}],7:[function(e,t,r){\"use strict\";var n=\"undefined\"!=typeof Uint8Array&&\"undefined\"!=typeof Uint16Array&&\"undefined\"!=typeof Uint32Array,i=e(\"pako\"),s=e(\"./utils\"),a=e(\"./stream/GenericWorker\"),o=n?\"uint8array\":\"array\";function h(e,t){a.call(this,\"FlateWorker/\"+e),this._pako=null,this._pakoAction=e,this._pakoOptions=t,this.meta={}}r.magic=\"\\b\\0\",s.inherits(h,a),h.prototype.processChunk=function(e){this.meta=e.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,e.data),!1)},h.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0)},h.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null},h.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var t=this;this._pako.onData=function(e){t.push({data:e,meta:t.meta})}},r.compressWorker=function(e){return new h(\"Deflate\",e)},r.uncompressWorker=function(){return new h(\"Inflate\",{})}},{\"./stream/GenericWorker\":28,\"./utils\":32,pako:38}],8:[function(e,t,r){\"use strict\";function A(e,t){var r,n=\"\";for(r=0;r>>=8;return n}function n(e,t,r,n,i,s){var a,o,h=e.file,u=e.compression,l=s!==O.utf8encode,f=I.transformTo(\"string\",s(h.name)),c=I.transformTo(\"string\",O.utf8encode(h.name)),d=h.comment,p=I.transformTo(\"string\",s(d)),m=I.transformTo(\"string\",O.utf8encode(d)),_=c.length!==h.name.length,g=m.length!==d.length,b=\"\",v=\"\",y=\"\",w=h.dir,k=h.date,x={crc32:0,compressedSize:0,uncompressedSize:0};t&&!r||(x.crc32=e.crc32,x.compressedSize=e.compressedSize,x.uncompressedSize=e.uncompressedSize);var S=0;t&&(S|=8),l||!_&&!g||(S|=2048);var z=0,C=0;w&&(z|=16),\"UNIX\"===i?(C=798,z|=function(e,t){var r=e;return e||(r=t?16893:33204),(65535&r)<<16}(h.unixPermissions,w)):(C=20,z|=function(e){return 63&(e||0)}(h.dosPermissions)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(v=A(1,1)+A(B(f),4)+c,b+=\"up\"+A(v.length,2)+v),g&&(y=A(1,1)+A(B(p),4)+m,b+=\"uc\"+A(y.length,2)+y);var E=\"\";return E+=\"\\n\\0\",E+=A(S,2),E+=u.magic,E+=A(a,2),E+=A(o,2),E+=A(x.crc32,4),E+=A(x.compressedSize,4),E+=A(x.uncompressedSize,4),E+=A(f.length,2),E+=A(b.length,2),{fileRecord:R.LOCAL_FILE_HEADER+E+f+b,dirRecord:R.CENTRAL_FILE_HEADER+A(C,2)+E+A(p.length,2)+\"\\0\\0\\0\\0\"+A(z,4)+A(n,4)+f+b+p}}var I=e(\"../utils\"),i=e(\"../stream/GenericWorker\"),O=e(\"../utf8\"),B=e(\"../crc32\"),R=e(\"../signature\");function s(e,t,r,n){i.call(this,\"ZipFileWorker\"),this.bytesWritten=0,this.zipComment=t,this.zipPlatform=r,this.encodeFileName=n,this.streamFiles=e,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}I.inherits(s,i),s.prototype.push=function(e){var t=e.meta.percent||0,r=this.entriesCount,n=this._sources.length;this.accumulate?this.contentBuffer.push(e):(this.bytesWritten+=e.data.length,i.prototype.push.call(this,{data:e.data,meta:{currentFile:this.currentFile,percent:r?(t+100*(r-n-1))/r:100}}))},s.prototype.openedSource=function(e){this.currentSourceOffset=this.bytesWritten,this.currentFile=e.file.name;var t=this.streamFiles&&!e.file.dir;if(t){var r=n(e,t,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}})}else this.accumulate=!0},s.prototype.closedSource=function(e){this.accumulate=!1;var t=this.streamFiles&&!e.file.dir,r=n(e,t,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(r.dirRecord),t)this.push({data:function(e){return R.DATA_DESCRIPTOR+A(e.crc32,4)+A(e.compressedSize,4)+A(e.uncompressedSize,4)}(e),meta:{percent:100}});else for(this.push({data:r.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},s.prototype.flush=function(){for(var e=this.bytesWritten,t=0;t=this.index;t--)r=(r<<8)+this.byteAt(t);return this.index+=e,r},readString:function(e){return n.transformTo(\"string\",this.readData(e))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var e=this.readInt(4);return new Date(Date.UTC(1980+(e>>25&127),(e>>21&15)-1,e>>16&31,e>>11&31,e>>5&63,(31&e)<<1))}},t.exports=i},{\"../utils\":32}],19:[function(e,t,r){\"use strict\";var n=e(\"./Uint8ArrayReader\");function i(e){n.call(this,e)}e(\"../utils\").inherits(i,n),i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{\"../utils\":32,\"./Uint8ArrayReader\":21}],20:[function(e,t,r){\"use strict\";var n=e(\"./DataReader\");function i(e){n.call(this,e)}e(\"../utils\").inherits(i,n),i.prototype.byteAt=function(e){return this.data.charCodeAt(this.zero+e)},i.prototype.lastIndexOfSignature=function(e){return this.data.lastIndexOf(e)-this.zero},i.prototype.readAndCheckSignature=function(e){return e===this.readData(4)},i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{\"../utils\":32,\"./DataReader\":18}],21:[function(e,t,r){\"use strict\";var n=e(\"./ArrayReader\");function i(e){n.call(this,e)}e(\"../utils\").inherits(i,n),i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return new Uint8Array(0);var t=this.data.subarray(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{\"../utils\":32,\"./ArrayReader\":17}],22:[function(e,t,r){\"use strict\";var n=e(\"../utils\"),i=e(\"../support\"),s=e(\"./ArrayReader\"),a=e(\"./StringReader\"),o=e(\"./NodeBufferReader\"),h=e(\"./Uint8ArrayReader\");t.exports=function(e){var t=n.getTypeOf(e);return n.checkSupport(t),\"string\"!==t||i.uint8array?\"nodebuffer\"===t?new o(e):i.uint8array?new h(n.transformTo(\"uint8array\",e)):new s(n.transformTo(\"array\",e)):new a(e)}},{\"../support\":30,\"../utils\":32,\"./ArrayReader\":17,\"./NodeBufferReader\":19,\"./StringReader\":20,\"./Uint8ArrayReader\":21}],23:[function(e,t,r){\"use strict\";r.LOCAL_FILE_HEADER=\"PK\u0003\u0004\",r.CENTRAL_FILE_HEADER=\"PK\u0001\u0002\",r.CENTRAL_DIRECTORY_END=\"PK\u0005\u0006\",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR=\"PK\u0006\u0007\",r.ZIP64_CENTRAL_DIRECTORY_END=\"PK\u0006\u0006\",r.DATA_DESCRIPTOR=\"PK\u0007\\b\"},{}],24:[function(e,t,r){\"use strict\";var n=e(\"./GenericWorker\"),i=e(\"../utils\");function s(e){n.call(this,\"ConvertWorker to \"+e),this.destType=e}i.inherits(s,n),s.prototype.processChunk=function(e){this.push({data:i.transformTo(this.destType,e.data),meta:e.meta})},t.exports=s},{\"../utils\":32,\"./GenericWorker\":28}],25:[function(e,t,r){\"use strict\";var n=e(\"./GenericWorker\"),i=e(\"../crc32\");function s(){n.call(this,\"Crc32Probe\"),this.withStreamInfo(\"crc32\",0)}e(\"../utils\").inherits(s,n),s.prototype.processChunk=function(e){this.streamInfo.crc32=i(e.data,this.streamInfo.crc32||0),this.push(e)},t.exports=s},{\"../crc32\":4,\"../utils\":32,\"./GenericWorker\":28}],26:[function(e,t,r){\"use strict\";var n=e(\"../utils\"),i=e(\"./GenericWorker\");function s(e){i.call(this,\"DataLengthProbe for \"+e),this.propName=e,this.withStreamInfo(e,0)}n.inherits(s,i),s.prototype.processChunk=function(e){if(e){var t=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=t+e.data.length}i.prototype.processChunk.call(this,e)},t.exports=s},{\"../utils\":32,\"./GenericWorker\":28}],27:[function(e,t,r){\"use strict\";var n=e(\"../utils\"),i=e(\"./GenericWorker\");function s(e){i.call(this,\"DataWorker\");var t=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type=\"\",this._tickScheduled=!1,e.then(function(e){t.dataIsReady=!0,t.data=e,t.max=e&&e.length||0,t.type=n.getTypeOf(e),t.isPaused||t._tickAndRepeat()},function(e){t.error(e)})}n.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null},s.prototype.resume=function(){return!!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,n.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(n.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var e=null,t=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case\"string\":e=this.data.substring(this.index,t);break;case\"uint8array\":e=this.data.subarray(this.index,t);break;case\"array\":case\"nodebuffer\":e=this.data.slice(this.index,t)}return this.index=t,this.push({data:e,meta:{percent:this.max?this.index/this.max*100:0}})},t.exports=s},{\"../utils\":32,\"./GenericWorker\":28}],28:[function(e,t,r){\"use strict\";function n(e){this.name=e||\"default\",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}n.prototype={push:function(e){this.emit(\"data\",e)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit(\"end\"),this.cleanUp(),this.isFinished=!0}catch(e){this.emit(\"error\",e)}return!0},error:function(e){return!this.isFinished&&(this.isPaused?this.generatedError=e:(this.isFinished=!0,this.emit(\"error\",e),this.previous&&this.previous.error(e),this.cleanUp()),!0)},on:function(e,t){return this._listeners[e].push(t),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(e,t){if(this._listeners[e])for(var r=0;r \"+e:e}},t.exports=n},{}],29:[function(e,t,r){\"use strict\";var h=e(\"../utils\"),i=e(\"./ConvertWorker\"),s=e(\"./GenericWorker\"),u=e(\"../base64\"),n=e(\"../support\"),a=e(\"../external\"),o=null;if(n.nodestream)try{o=e(\"../nodejs/NodejsStreamOutputAdapter\")}catch(e){}function l(e,o){return new a.Promise(function(t,r){var n=[],i=e._internalType,s=e._outputType,a=e._mimeType;e.on(\"data\",function(e,t){n.push(e),o&&o(t)}).on(\"error\",function(e){n=[],r(e)}).on(\"end\",function(){try{var e=function(e,t,r){switch(e){case\"blob\":return h.newBlob(h.transformTo(\"arraybuffer\",t),r);case\"base64\":return u.encode(t);default:return h.transformTo(e,t)}}(s,function(e,t){var r,n=0,i=null,s=0;for(r=0;r>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t}(e)},s.utf8decode=function(e){return h.nodebuffer?o.transformTo(\"nodebuffer\",e).toString(\"utf-8\"):function(e){var t,r,n,i,s=e.length,a=new Array(2*s);for(t=r=0;t>10&1023,a[r++]=56320|1023&n)}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(e=o.transformTo(h.uint8array?\"uint8array\":\"array\",e))},o.inherits(a,n),a.prototype.processChunk=function(e){var t=o.transformTo(h.uint8array?\"uint8array\":\"array\",e.data);if(this.leftOver&&this.leftOver.length){if(h.uint8array){var r=t;(t=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),t.set(r,this.leftOver.length)}else t=this.leftOver.concat(t);this.leftOver=null}var n=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}(t),i=t;n!==t.length&&(h.uint8array?(i=t.subarray(0,n),this.leftOver=t.subarray(n,t.length)):(i=t.slice(0,n),this.leftOver=t.slice(n,t.length))),this.push({data:s.utf8decode(i),meta:e.meta})},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},s.Utf8DecodeWorker=a,o.inherits(l,n),l.prototype.processChunk=function(e){this.push({data:s.utf8encode(e.data),meta:e.meta})},s.Utf8EncodeWorker=l},{\"./nodejsUtils\":14,\"./stream/GenericWorker\":28,\"./support\":30,\"./utils\":32}],32:[function(e,t,a){\"use strict\";var o=e(\"./support\"),h=e(\"./base64\"),r=e(\"./nodejsUtils\"),u=e(\"./external\");function n(e){return e}function l(e,t){for(var r=0;r>8;this.dir=!!(16&this.externalFileAttributes),0==e&&(this.dosPermissions=63&this.externalFileAttributes),3==e&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||\"/\"!==this.fileNameStr.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var e=n(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=e.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=e.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=e.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=e.readInt(4))}},readExtraFields:function(e){var t,r,n,i=e.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});e.index+4>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t},r.buf2binstring=function(e){return l(e,e.length)},r.binstring2buf=function(e){for(var t=new h.Buf8(e.length),r=0,n=t.length;r>10&1023,o[n++]=56320|1023&i)}return l(o,n)},r.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}},{\"./common\":41}],43:[function(e,t,r){\"use strict\";t.exports=function(e,t,r,n){for(var i=65535&e|0,s=e>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}},{}],46:[function(e,t,r){\"use strict\";var h,c=e(\"../utils/common\"),u=e(\"./trees\"),d=e(\"./adler32\"),p=e(\"./crc32\"),n=e(\"./messages\"),l=0,f=4,m=0,_=-2,g=-1,b=4,i=2,v=8,y=9,s=286,a=30,o=19,w=2*s+1,k=15,x=3,S=258,z=S+x+1,C=42,E=113,A=1,I=2,O=3,B=4;function R(e,t){return e.msg=n[t],t}function T(e){return(e<<1)-(4e.avail_out&&(r=e.avail_out),0!==r&&(c.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0))}function N(e,t){u._tr_flush_block(e,0<=e.block_start?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,F(e.strm)}function U(e,t){e.pending_buf[e.pending++]=t}function P(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t}function L(e,t){var r,n,i=e.max_chain_length,s=e.strstart,a=e.prev_length,o=e.nice_match,h=e.strstart>e.w_size-z?e.strstart-(e.w_size-z):0,u=e.window,l=e.w_mask,f=e.prev,c=e.strstart+S,d=u[s+a-1],p=u[s+a];e.prev_length>=e.good_match&&(i>>=2),o>e.lookahead&&(o=e.lookahead);do{if(u[(r=t)+a]===p&&u[r+a-1]===d&&u[r]===u[s]&&u[++r]===u[s+1]){s+=2,r++;do{}while(u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&sh&&0!=--i);return a<=e.lookahead?a:e.lookahead}function j(e){var t,r,n,i,s,a,o,h,u,l,f=e.w_size;do{if(i=e.window_size-e.lookahead-e.strstart,e.strstart>=f+(f-z)){for(c.arraySet(e.window,e.window,f,f,0),e.match_start-=f,e.strstart-=f,e.block_start-=f,t=r=e.hash_size;n=e.head[--t],e.head[t]=f<=n?n-f:0,--r;);for(t=r=f;n=e.prev[--t],e.prev[t]=f<=n?n-f:0,--r;);i+=f}if(0===e.strm.avail_in)break;if(a=e.strm,o=e.window,h=e.strstart+e.lookahead,u=i,l=void 0,l=a.avail_in,u=x)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x)if(n=u._tr_tally(e,e.strstart-e.match_start,e.match_length-x),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=x){for(e.match_length--;e.strstart++,e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x&&e.match_length<=e.prev_length){for(i=e.strstart+e.lookahead-x,n=u._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-x),e.lookahead-=e.prev_length-1,e.prev_length-=2;++e.strstart<=i&&(e.ins_h=(e.ins_h<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(j(e),0===e.lookahead&&t===l)return A;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,N(e,!1),0===e.strm.avail_out))return A;if(e.strstart-e.block_start>=e.w_size-z&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):(e.strstart>e.block_start&&(N(e,!1),e.strm.avail_out),A)}),new M(4,4,8,4,Z),new M(4,5,16,8,Z),new M(4,6,32,32,Z),new M(4,4,16,16,W),new M(8,16,32,32,W),new M(8,16,128,128,W),new M(8,32,128,256,W),new M(32,128,258,1024,W),new M(32,258,258,4096,W)],r.deflateInit=function(e,t){return Y(e,t,v,15,8,0)},r.deflateInit2=Y,r.deflateReset=K,r.deflateResetKeep=G,r.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?_:(e.state.gzhead=t,m):_},r.deflate=function(e,t){var r,n,i,s;if(!e||!e.state||5>8&255),U(n,n.gzhead.time>>16&255),U(n,n.gzhead.time>>24&255),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(U(n,255&n.gzhead.extra.length),U(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(e.adler=p(e.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(U(n,0),U(n,0),U(n,0),U(n,0),U(n,0),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,3),n.status=E);else{var a=v+(n.w_bits-8<<4)<<8;a|=(2<=n.strategy||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(a|=32),a+=31-a%31,n.status=E,P(n,a),0!==n.strstart&&(P(n,e.adler>>>16),P(n,65535&e.adler)),e.adler=1}if(69===n.status)if(n.gzhead.extra){for(i=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending!==n.pending_buf_size));)U(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.status=103)}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&F(e),n.pending+2<=n.pending_buf_size&&(U(n,255&e.adler),U(n,e.adler>>8&255),e.adler=0,n.status=E)):n.status=E),0!==n.pending){if(F(e),0===e.avail_out)return n.last_flush=-1,m}else if(0===e.avail_in&&T(t)<=T(r)&&t!==f)return R(e,-5);if(666===n.status&&0!==e.avail_in)return R(e,-5);if(0!==e.avail_in||0!==n.lookahead||t!==l&&666!==n.status){var o=2===n.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(j(e),0===e.lookahead)){if(t===l)return A;break}if(e.match_length=0,r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):3===n.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=S){if(j(e),e.lookahead<=S&&t===l)return A;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=x&&0e.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=x?(r=u._tr_tally(e,1,e.match_length-x),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):h[n.level].func(n,t);if(o!==O&&o!==B||(n.status=666),o===A||o===O)return 0===e.avail_out&&(n.last_flush=-1),m;if(o===I&&(1===t?u._tr_align(n):5!==t&&(u._tr_stored_block(n,0,0,!1),3===t&&(D(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),F(e),0===e.avail_out))return n.last_flush=-1,m}return t!==f?m:n.wrap<=0?1:(2===n.wrap?(U(n,255&e.adler),U(n,e.adler>>8&255),U(n,e.adler>>16&255),U(n,e.adler>>24&255),U(n,255&e.total_in),U(n,e.total_in>>8&255),U(n,e.total_in>>16&255),U(n,e.total_in>>24&255)):(P(n,e.adler>>>16),P(n,65535&e.adler)),F(e),0=r.w_size&&(0===s&&(D(r.head),r.strstart=0,r.block_start=0,r.insert=0),u=new c.Buf8(r.w_size),c.arraySet(u,t,l-r.w_size,r.w_size,0),t=u,l=r.w_size),a=e.avail_in,o=e.next_in,h=e.input,e.avail_in=l,e.next_in=0,e.input=t,j(r);r.lookahead>=x;){for(n=r.strstart,i=r.lookahead-(x-1);r.ins_h=(r.ins_h<>>=y=v>>>24,p-=y,0===(y=v>>>16&255))C[s++]=65535&v;else{if(!(16&y)){if(0==(64&y)){v=m[(65535&v)+(d&(1<>>=y,p-=y),p<15&&(d+=z[n++]<>>=y=v>>>24,p-=y,!(16&(y=v>>>16&255))){if(0==(64&y)){v=_[(65535&v)+(d&(1<>>=y,p-=y,(y=s-a)>3,d&=(1<<(p-=w<<3))-1,e.next_in=n,e.next_out=s,e.avail_in=n>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function s(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function a(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg=\"\",t.wrap&&(e.adler=1&t.wrap),t.mode=P,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new I.Buf32(n),t.distcode=t.distdyn=new I.Buf32(i),t.sane=1,t.back=-1,N):U}function o(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,a(e)):U}function h(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15=s.wsize?(I.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(n<(i=s.wsize-s.wnext)&&(i=n),I.arraySet(s.window,t,r-n,i,s.wnext),(n-=i)?(I.arraySet(s.window,t,r-n,n,0),s.wnext=n,s.whave=s.wsize):(s.wnext+=i,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=B(r.check,E,2,0),l=u=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&u)<<8)+(u>>8))%31){e.msg=\"incorrect header check\",r.mode=30;break}if(8!=(15&u)){e.msg=\"unknown compression method\",r.mode=30;break}if(l-=4,k=8+(15&(u>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){e.msg=\"invalid window size\",r.mode=30;break}r.dmax=1<>8&1),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=3;case 3:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>8&255,E[2]=u>>>16&255,E[3]=u>>>24&255,r.check=B(r.check,E,4,0)),l=u=0,r.mode=4;case 4:for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>8),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=5;case 5:if(1024&r.flags){for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>>8&255,r.check=B(r.check,E,2,0)),l=u=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(d=r.length)&&(d=o),d&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,n,s,d,k)),512&r.flags&&(r.check=B(r.check,n,d,s)),o-=d,s+=d,r.length-=d),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break e;for(d=0;k=n[s+d++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&d>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=12;break;case 10:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>=7&l,l-=7&l,r.mode=27;break}for(;l<3;){if(0===o)break e;o--,u+=n[s++]<>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==t)break;u>>>=2,l-=2;break e;case 2:r.mode=17;break;case 3:e.msg=\"invalid block type\",r.mode=30}u>>>=2,l-=2;break;case 14:for(u>>>=7&l,l-=7&l;l<32;){if(0===o)break e;o--,u+=n[s++]<>>16^65535)){e.msg=\"invalid stored block lengths\",r.mode=30;break}if(r.length=65535&u,l=u=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(d=r.length){if(o>>=5,l-=5,r.ndist=1+(31&u),u>>>=5,l-=5,r.ncode=4+(15&u),u>>>=4,l-=4,286>>=3,l-=3}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=T(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg=\"invalid code lengths set\",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=_,l-=_,r.lens[r.have++]=b;else{if(16===b){for(z=_+2;l>>=_,l-=_,0===r.have){e.msg=\"invalid bit length repeat\",r.mode=30;break}k=r.lens[r.have-1],d=3+(3&u),u>>>=2,l-=2}else if(17===b){for(z=_+3;l>>=_)),u>>>=3,l-=3}else{for(z=_+7;l>>=_)),u>>>=7,l-=7}if(r.have+d>r.nlen+r.ndist){e.msg=\"invalid bit length repeat\",r.mode=30;break}for(;d--;)r.lens[r.have++]=k}}if(30===r.mode)break;if(0===r.lens[256]){e.msg=\"invalid code -- missing end-of-block\",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=T(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg=\"invalid literal/lengths set\",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=T(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){e.msg=\"invalid distances set\",r.mode=30;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(6<=o&&258<=h){e.next_out=a,e.avail_out=h,e.next_in=s,e.avail_in=o,r.hold=u,r.bits=l,R(e,c),a=e.next_out,i=e.output,h=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,u=r.hold,l=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(C=r.lencode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,r.length=b,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){e.msg=\"invalid literal/length code\",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;g=(C=r.distcode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,64&g){e.msg=\"invalid distance code\",r.mode=30;break}r.offset=b,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg=\"invalid distance too far back\",r.mode=30;break}r.mode=25;case 25:if(0===h)break e;if(d=c-h,r.offset>d){if((d=r.offset-d)>r.whave&&r.sane){e.msg=\"invalid distance too far back\",r.mode=30;break}p=d>r.wnext?(d-=r.wnext,r.wsize-d):r.wnext-d,d>r.length&&(d=r.length),m=r.window}else m=i,p=a-r.offset,d=r.length;for(hd?(m=R[T+a[v]],A[I+a[v]]):(m=96,0),h=1<>S)+(u-=h)]=p<<24|m<<16|_|0,0!==u;);for(h=1<>=1;if(0!==h?(E&=h-1,E+=h):E=0,v++,0==--O[b]){if(b===w)break;b=t[r+a[v]]}if(k>>7)]}function U(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255}function P(e,t,r){e.bi_valid>d-r?(e.bi_buf|=t<>d-e.bi_valid,e.bi_valid+=r-d):(e.bi_buf|=t<>>=1,r<<=1,0<--t;);return r>>>1}function Z(e,t,r){var n,i,s=new Array(g+1),a=0;for(n=1;n<=g;n++)s[n]=a=a+r[n-1]<<1;for(i=0;i<=t;i++){var o=e[2*i+1];0!==o&&(e[2*i]=j(s[o]++,o))}}function W(e){var t;for(t=0;t>1;1<=r;r--)G(e,s,r);for(i=h;r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],G(e,s,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,s[2*i]=s[2*r]+s[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,s[2*r+1]=s[2*n+1]=i,e.heap[1]=i++,G(e,s,1),2<=e.heap_len;);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,s,a,o,h=t.dyn_tree,u=t.max_code,l=t.stat_desc.static_tree,f=t.stat_desc.has_stree,c=t.stat_desc.extra_bits,d=t.stat_desc.extra_base,p=t.stat_desc.max_length,m=0;for(s=0;s<=g;s++)e.bl_count[s]=0;for(h[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<_;r++)p<(s=h[2*h[2*(n=e.heap[r])+1]+1]+1)&&(s=p,m++),h[2*n+1]=s,u>=7;n>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return o;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return h;for(t=32;t>>3,(s=e.static_len+3+7>>>3)<=i&&(i=s)):i=s=r+5,r+4<=i&&-1!==t?J(e,t,r,n):4===e.strategy||s===i?(P(e,2+(n?1:0),3),K(e,z,C)):(P(e,4+(n?1:0),3),function(e,t,r,n){var i;for(P(e,t-257,5),P(e,r-1,5),P(e,n-4,4),i=0;i>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(A[r]+u+1)]++,e.dyn_dtree[2*N(t)]++),e.last_lit===e.lit_bufsize-1},r._tr_align=function(e){P(e,2,3),L(e,m,z),function(e){16===e.bi_valid?(U(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):8<=e.bi_valid&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)}(e)}},{\"../utils/common\":41}],53:[function(e,t,r){\"use strict\";t.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg=\"\",this.state=null,this.data_type=2,this.adler=0}},{}],54:[function(e,t,r){(function(e){!function(r,n){\"use strict\";if(!r.setImmediate){var i,s,t,a,o=1,h={},u=!1,l=r.document,e=Object.getPrototypeOf&&Object.getPrototypeOf(r);e=e&&e.setTimeout?e:r,i=\"[object process]\"==={}.toString.call(r.process)?function(e){process.nextTick(function(){c(e)})}:function(){if(r.postMessage&&!r.importScripts){var e=!0,t=r.onmessage;return r.onmessage=function(){e=!1},r.postMessage(\"\",\"*\"),r.onmessage=t,e}}()?(a=\"setImmediate$\"+Math.random()+\"$\",r.addEventListener?r.addEventListener(\"message\",d,!1):r.attachEvent(\"onmessage\",d),function(e){r.postMessage(a+e,\"*\")}):r.MessageChannel?((t=new MessageChannel).port1.onmessage=function(e){c(e.data)},function(e){t.port2.postMessage(e)}):l&&\"onreadystatechange\"in l.createElement(\"script\")?(s=l.documentElement,function(e){var t=l.createElement(\"script\");t.onreadystatechange=function(){c(e),t.onreadystatechange=null,s.removeChild(t),t=null},s.appendChild(t)}):function(e){setTimeout(c,0,e)},e.setImmediate=function(e){\"function\"!=typeof e&&(e=new Function(\"\"+e));for(var t=new Array(arguments.length-1),r=0;r arr.length) len = arr.length;\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n return arr2;\n}\nmodule.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;", "var arrayLikeToArray = require(\"./arrayLikeToArray.js\");\nfunction _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}\nmodule.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;", "function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\nmodule.exports = _nonIterableRest, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;", "var arrayWithHoles = require(\"./arrayWithHoles.js\");\nvar iterableToArrayLimit = require(\"./iterableToArrayLimit.js\");\nvar unsupportedIterableToArray = require(\"./unsupportedIterableToArray.js\");\nvar nonIterableRest = require(\"./nonIterableRest.js\");\nfunction _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}\nmodule.exports = _slicedToArray, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;", "function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\nmodule.exports = _classCallCheck, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;", "function _typeof(o) {\n \"@babel/helpers - typeof\";\n\n return (module.exports = _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) {\n return typeof o;\n } : function (o) {\n return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o;\n }, module.exports.__esModule = true, module.exports[\"default\"] = module.exports), _typeof(o);\n}\nmodule.exports = _typeof, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;", "var _typeof = require(\"./typeof.js\")[\"default\"];\nfunction toPrimitive(t, r) {\n if (\"object\" != _typeof(t) || !t) return t;\n var e = t[Symbol.toPrimitive];\n if (void 0 !== e) {\n var i = e.call(t, r || \"default\");\n if (\"object\" != _typeof(i)) return i;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (\"string\" === r ? String : Number)(t);\n}\nmodule.exports = toPrimitive, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;", "var _typeof = require(\"./typeof.js\")[\"default\"];\nvar toPrimitive = require(\"./toPrimitive.js\");\nfunction toPropertyKey(t) {\n var i = toPrimitive(t, \"string\");\n return \"symbol\" == _typeof(i) ? i : String(i);\n}\nmodule.exports = toPropertyKey, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;", "var toPropertyKey = require(\"./toPropertyKey.js\");\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, toPropertyKey(descriptor.key), descriptor);\n }\n}\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, \"prototype\", {\n writable: false\n });\n return Constructor;\n}\nmodule.exports = _createClass, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;", "(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@babel/runtime/helpers/slicedToArray'), require('@babel/runtime/helpers/classCallCheck'), require('@babel/runtime/helpers/createClass')) :\n typeof define === 'function' && define.amd ? define(['exports', '@babel/runtime/helpers/slicedToArray', '@babel/runtime/helpers/classCallCheck', '@babel/runtime/helpers/createClass'], factory) :\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.automationEvents = {}, global._slicedToArray, global._classCallCheck, global._createClass));\n})(this, (function (exports, _slicedToArray, _classCallCheck, _createClass) { 'use strict';\n\n var createExtendedExponentialRampToValueAutomationEvent = function createExtendedExponentialRampToValueAutomationEvent(value, endTime, insertTime) {\n return {\n endTime: endTime,\n insertTime: insertTime,\n type: 'exponentialRampToValue',\n value: value\n };\n };\n\n var createExtendedLinearRampToValueAutomationEvent = function createExtendedLinearRampToValueAutomationEvent(value, endTime, insertTime) {\n return {\n endTime: endTime,\n insertTime: insertTime,\n type: 'linearRampToValue',\n value: value\n };\n };\n\n var createSetValueAutomationEvent = function createSetValueAutomationEvent(value, startTime) {\n return {\n startTime: startTime,\n type: 'setValue',\n value: value\n };\n };\n\n var createSetValueCurveAutomationEvent = function createSetValueCurveAutomationEvent(values, startTime, duration) {\n return {\n duration: duration,\n startTime: startTime,\n type: 'setValueCurve',\n values: values\n };\n };\n\n var getTargetValueAtTime = function getTargetValueAtTime(time, valueAtStartTime, _ref) {\n var startTime = _ref.startTime,\n target = _ref.target,\n timeConstant = _ref.timeConstant;\n return target + (valueAtStartTime - target) * Math.exp((startTime - time) / timeConstant);\n };\n\n var isExponentialRampToValueAutomationEvent = function isExponentialRampToValueAutomationEvent(automationEvent) {\n return automationEvent.type === 'exponentialRampToValue';\n };\n\n var isLinearRampToValueAutomationEvent = function isLinearRampToValueAutomationEvent(automationEvent) {\n return automationEvent.type === 'linearRampToValue';\n };\n\n var isAnyRampToValueAutomationEvent = function isAnyRampToValueAutomationEvent(automationEvent) {\n return isExponentialRampToValueAutomationEvent(automationEvent) || isLinearRampToValueAutomationEvent(automationEvent);\n };\n\n var isSetValueAutomationEvent = function isSetValueAutomationEvent(automationEvent) {\n return automationEvent.type === 'setValue';\n };\n\n var isSetValueCurveAutomationEvent = function isSetValueCurveAutomationEvent(automationEvent) {\n return automationEvent.type === 'setValueCurve';\n };\n\n var getValueOfAutomationEventAtIndexAtTime = function getValueOfAutomationEventAtIndexAtTime(automationEvents, index, time, defaultValue) {\n var automationEvent = automationEvents[index];\n return automationEvent === undefined ? defaultValue : isAnyRampToValueAutomationEvent(automationEvent) || isSetValueAutomationEvent(automationEvent) ? automationEvent.value : isSetValueCurveAutomationEvent(automationEvent) ? automationEvent.values[automationEvent.values.length - 1] : getTargetValueAtTime(time, getValueOfAutomationEventAtIndexAtTime(automationEvents, index - 1, automationEvent.startTime, defaultValue), automationEvent);\n };\n\n var getEndTimeAndValueOfPreviousAutomationEvent = function getEndTimeAndValueOfPreviousAutomationEvent(automationEvents, index, currentAutomationEvent, nextAutomationEvent, defaultValue) {\n return currentAutomationEvent === undefined ? [nextAutomationEvent.insertTime, defaultValue] : isAnyRampToValueAutomationEvent(currentAutomationEvent) ? [currentAutomationEvent.endTime, currentAutomationEvent.value] : isSetValueAutomationEvent(currentAutomationEvent) ? [currentAutomationEvent.startTime, currentAutomationEvent.value] : isSetValueCurveAutomationEvent(currentAutomationEvent) ? [currentAutomationEvent.startTime + currentAutomationEvent.duration, currentAutomationEvent.values[currentAutomationEvent.values.length - 1]] : [currentAutomationEvent.startTime, getValueOfAutomationEventAtIndexAtTime(automationEvents, index - 1, currentAutomationEvent.startTime, defaultValue)];\n };\n\n var isCancelAndHoldAutomationEvent = function isCancelAndHoldAutomationEvent(automationEvent) {\n return automationEvent.type === 'cancelAndHold';\n };\n\n var isCancelScheduledValuesAutomationEvent = function isCancelScheduledValuesAutomationEvent(automationEvent) {\n return automationEvent.type === 'cancelScheduledValues';\n };\n\n var getEventTime = function getEventTime(automationEvent) {\n if (isCancelAndHoldAutomationEvent(automationEvent) || isCancelScheduledValuesAutomationEvent(automationEvent)) {\n return automationEvent.cancelTime;\n }\n if (isExponentialRampToValueAutomationEvent(automationEvent) || isLinearRampToValueAutomationEvent(automationEvent)) {\n return automationEvent.endTime;\n }\n return automationEvent.startTime;\n };\n\n var getExponentialRampValueAtTime = function getExponentialRampValueAtTime(time, startTime, valueAtStartTime, _ref) {\n var endTime = _ref.endTime,\n value = _ref.value;\n if (valueAtStartTime === value) {\n return value;\n }\n if (0 < valueAtStartTime && 0 < value || valueAtStartTime < 0 && value < 0) {\n return valueAtStartTime * Math.pow(value / valueAtStartTime, (time - startTime) / (endTime - startTime));\n }\n return 0;\n };\n\n var getLinearRampValueAtTime = function getLinearRampValueAtTime(time, startTime, valueAtStartTime, _ref) {\n var endTime = _ref.endTime,\n value = _ref.value;\n return valueAtStartTime + (time - startTime) / (endTime - startTime) * (value - valueAtStartTime);\n };\n\n var interpolateValue = function interpolateValue(values, theoreticIndex) {\n var lowerIndex = Math.floor(theoreticIndex);\n var upperIndex = Math.ceil(theoreticIndex);\n if (lowerIndex === upperIndex) {\n return values[lowerIndex];\n }\n return (1 - (theoreticIndex - lowerIndex)) * values[lowerIndex] + (1 - (upperIndex - theoreticIndex)) * values[upperIndex];\n };\n\n var getValueCurveValueAtTime = function getValueCurveValueAtTime(time, _ref) {\n var duration = _ref.duration,\n startTime = _ref.startTime,\n values = _ref.values;\n var theoreticIndex = (time - startTime) / duration * (values.length - 1);\n return interpolateValue(values, theoreticIndex);\n };\n\n var isSetTargetAutomationEvent = function isSetTargetAutomationEvent(automationEvent) {\n return automationEvent.type === 'setTarget';\n };\n\n var AutomationEventList = /*#__PURE__*/function (_Symbol$iterator) {\n function AutomationEventList(defaultValue) {\n _classCallCheck(this, AutomationEventList);\n this._automationEvents = [];\n this._currenTime = 0;\n this._defaultValue = defaultValue;\n }\n _createClass(AutomationEventList, [{\n key: _Symbol$iterator,\n value: function value() {\n return this._automationEvents[Symbol.iterator]();\n }\n }, {\n key: \"add\",\n value: function add(automationEvent) {\n var eventTime = getEventTime(automationEvent);\n if (isCancelAndHoldAutomationEvent(automationEvent) || isCancelScheduledValuesAutomationEvent(automationEvent)) {\n var index = this._automationEvents.findIndex(function (currentAutomationEvent) {\n if (isCancelScheduledValuesAutomationEvent(automationEvent) && isSetValueCurveAutomationEvent(currentAutomationEvent)) {\n return currentAutomationEvent.startTime + currentAutomationEvent.duration >= eventTime;\n }\n return getEventTime(currentAutomationEvent) >= eventTime;\n });\n var removedAutomationEvent = this._automationEvents[index];\n if (index !== -1) {\n this._automationEvents = this._automationEvents.slice(0, index);\n }\n if (isCancelAndHoldAutomationEvent(automationEvent)) {\n var lastAutomationEvent = this._automationEvents[this._automationEvents.length - 1];\n if (removedAutomationEvent !== undefined && isAnyRampToValueAutomationEvent(removedAutomationEvent)) {\n if (lastAutomationEvent !== undefined && isSetTargetAutomationEvent(lastAutomationEvent)) {\n throw new Error('The internal list is malformed.');\n }\n var startTime = lastAutomationEvent === undefined ? removedAutomationEvent.insertTime : isSetValueCurveAutomationEvent(lastAutomationEvent) ? lastAutomationEvent.startTime + lastAutomationEvent.duration : getEventTime(lastAutomationEvent);\n var startValue = lastAutomationEvent === undefined ? this._defaultValue : isSetValueCurveAutomationEvent(lastAutomationEvent) ? lastAutomationEvent.values[lastAutomationEvent.values.length - 1] : lastAutomationEvent.value;\n var value = isExponentialRampToValueAutomationEvent(removedAutomationEvent) ? getExponentialRampValueAtTime(eventTime, startTime, startValue, removedAutomationEvent) : getLinearRampValueAtTime(eventTime, startTime, startValue, removedAutomationEvent);\n var truncatedAutomationEvent = isExponentialRampToValueAutomationEvent(removedAutomationEvent) ? createExtendedExponentialRampToValueAutomationEvent(value, eventTime, this._currenTime) : createExtendedLinearRampToValueAutomationEvent(value, eventTime, this._currenTime);\n this._automationEvents.push(truncatedAutomationEvent);\n }\n if (lastAutomationEvent !== undefined && isSetTargetAutomationEvent(lastAutomationEvent)) {\n this._automationEvents.push(createSetValueAutomationEvent(this.getValue(eventTime), eventTime));\n }\n if (lastAutomationEvent !== undefined && isSetValueCurveAutomationEvent(lastAutomationEvent) && lastAutomationEvent.startTime + lastAutomationEvent.duration > eventTime) {\n var duration = eventTime - lastAutomationEvent.startTime;\n var ratio = (lastAutomationEvent.values.length - 1) / lastAutomationEvent.duration;\n var length = Math.max(2, 1 + Math.ceil(duration * ratio));\n var fraction = duration / (length - 1) * ratio;\n var values = lastAutomationEvent.values.slice(0, length);\n if (fraction < 1) {\n for (var i = 1; i < length; i += 1) {\n var factor = fraction * i % 1;\n values[i] = lastAutomationEvent.values[i - 1] * (1 - factor) + lastAutomationEvent.values[i] * factor;\n }\n }\n this._automationEvents[this._automationEvents.length - 1] = createSetValueCurveAutomationEvent(values, lastAutomationEvent.startTime, duration);\n }\n }\n } else {\n var _index = this._automationEvents.findIndex(function (currentAutomationEvent) {\n return getEventTime(currentAutomationEvent) > eventTime;\n });\n var previousAutomationEvent = _index === -1 ? this._automationEvents[this._automationEvents.length - 1] : this._automationEvents[_index - 1];\n if (previousAutomationEvent !== undefined && isSetValueCurveAutomationEvent(previousAutomationEvent) && getEventTime(previousAutomationEvent) + previousAutomationEvent.duration > eventTime) {\n return false;\n }\n var persistentAutomationEvent = isExponentialRampToValueAutomationEvent(automationEvent) ? createExtendedExponentialRampToValueAutomationEvent(automationEvent.value, automationEvent.endTime, this._currenTime) : isLinearRampToValueAutomationEvent(automationEvent) ? createExtendedLinearRampToValueAutomationEvent(automationEvent.value, eventTime, this._currenTime) : automationEvent;\n if (_index === -1) {\n this._automationEvents.push(persistentAutomationEvent);\n } else {\n if (isSetValueCurveAutomationEvent(automationEvent) && eventTime + automationEvent.duration > getEventTime(this._automationEvents[_index])) {\n return false;\n }\n this._automationEvents.splice(_index, 0, persistentAutomationEvent);\n }\n }\n return true;\n }\n }, {\n key: \"flush\",\n value: function flush(time) {\n var index = this._automationEvents.findIndex(function (currentAutomationEvent) {\n return getEventTime(currentAutomationEvent) > time;\n });\n if (index > 1) {\n var remainingAutomationEvents = this._automationEvents.slice(index - 1);\n var firstRemainingAutomationEvent = remainingAutomationEvents[0];\n if (isSetTargetAutomationEvent(firstRemainingAutomationEvent)) {\n remainingAutomationEvents.unshift(createSetValueAutomationEvent(getValueOfAutomationEventAtIndexAtTime(this._automationEvents, index - 2, firstRemainingAutomationEvent.startTime, this._defaultValue), firstRemainingAutomationEvent.startTime));\n }\n this._automationEvents = remainingAutomationEvents;\n }\n }\n }, {\n key: \"getValue\",\n value: function getValue(time) {\n if (this._automationEvents.length === 0) {\n return this._defaultValue;\n }\n var indexOfNextEvent = this._automationEvents.findIndex(function (automationEvent) {\n return getEventTime(automationEvent) > time;\n });\n var nextAutomationEvent = this._automationEvents[indexOfNextEvent];\n var indexOfCurrentEvent = (indexOfNextEvent === -1 ? this._automationEvents.length : indexOfNextEvent) - 1;\n var currentAutomationEvent = this._automationEvents[indexOfCurrentEvent];\n if (currentAutomationEvent !== undefined && isSetTargetAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent) || nextAutomationEvent.insertTime > time)) {\n return getTargetValueAtTime(time, getValueOfAutomationEventAtIndexAtTime(this._automationEvents, indexOfCurrentEvent - 1, currentAutomationEvent.startTime, this._defaultValue), currentAutomationEvent);\n }\n if (currentAutomationEvent !== undefined && isSetValueAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent))) {\n return currentAutomationEvent.value;\n }\n if (currentAutomationEvent !== undefined && isSetValueCurveAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent) || currentAutomationEvent.startTime + currentAutomationEvent.duration > time)) {\n if (time < currentAutomationEvent.startTime + currentAutomationEvent.duration) {\n return getValueCurveValueAtTime(time, currentAutomationEvent);\n }\n return currentAutomationEvent.values[currentAutomationEvent.values.length - 1];\n }\n if (currentAutomationEvent !== undefined && isAnyRampToValueAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent))) {\n return currentAutomationEvent.value;\n }\n if (nextAutomationEvent !== undefined && isExponentialRampToValueAutomationEvent(nextAutomationEvent)) {\n var _getEndTimeAndValueOf = getEndTimeAndValueOfPreviousAutomationEvent(this._automationEvents, indexOfCurrentEvent, currentAutomationEvent, nextAutomationEvent, this._defaultValue),\n _getEndTimeAndValueOf2 = _slicedToArray(_getEndTimeAndValueOf, 2),\n startTime = _getEndTimeAndValueOf2[0],\n value = _getEndTimeAndValueOf2[1];\n return getExponentialRampValueAtTime(time, startTime, value, nextAutomationEvent);\n }\n if (nextAutomationEvent !== undefined && isLinearRampToValueAutomationEvent(nextAutomationEvent)) {\n var _getEndTimeAndValueOf3 = getEndTimeAndValueOfPreviousAutomationEvent(this._automationEvents, indexOfCurrentEvent, currentAutomationEvent, nextAutomationEvent, this._defaultValue),\n _getEndTimeAndValueOf4 = _slicedToArray(_getEndTimeAndValueOf3, 2),\n _startTime = _getEndTimeAndValueOf4[0],\n _value = _getEndTimeAndValueOf4[1];\n return getLinearRampValueAtTime(time, _startTime, _value, nextAutomationEvent);\n }\n return this._defaultValue;\n }\n }]);\n return AutomationEventList;\n }(Symbol.iterator);\n\n var createCancelAndHoldAutomationEvent = function createCancelAndHoldAutomationEvent(cancelTime) {\n return {\n cancelTime: cancelTime,\n type: 'cancelAndHold'\n };\n };\n\n var createCancelScheduledValuesAutomationEvent = function createCancelScheduledValuesAutomationEvent(cancelTime) {\n return {\n cancelTime: cancelTime,\n type: 'cancelScheduledValues'\n };\n };\n\n var createExponentialRampToValueAutomationEvent = function createExponentialRampToValueAutomationEvent(value, endTime) {\n return {\n endTime: endTime,\n type: 'exponentialRampToValue',\n value: value\n };\n };\n\n var createLinearRampToValueAutomationEvent = function createLinearRampToValueAutomationEvent(value, endTime) {\n return {\n endTime: endTime,\n type: 'linearRampToValue',\n value: value\n };\n };\n\n var createSetTargetAutomationEvent = function createSetTargetAutomationEvent(target, startTime, timeConstant) {\n return {\n startTime: startTime,\n target: target,\n timeConstant: timeConstant,\n type: 'setTarget'\n };\n };\n\n exports.AutomationEventList = AutomationEventList;\n exports.createCancelAndHoldAutomationEvent = createCancelAndHoldAutomationEvent;\n exports.createCancelScheduledValuesAutomationEvent = createCancelScheduledValuesAutomationEvent;\n exports.createExponentialRampToValueAutomationEvent = createExponentialRampToValueAutomationEvent;\n exports.createLinearRampToValueAutomationEvent = createLinearRampToValueAutomationEvent;\n exports.createSetTargetAutomationEvent = createSetTargetAutomationEvent;\n exports.createSetValueAutomationEvent = createSetValueAutomationEvent;\n exports.createSetValueCurveAutomationEvent = createSetValueCurveAutomationEvent;\n\n}));\n", "const {\n hasOwnProperty,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n} = Object;\n\nlet { freeze, seal, create } = Object; // eslint-disable-line import/no-mutable-exports\nlet { apply, construct } = typeof Reflect !== 'undefined' && Reflect;\n\nif (!apply) {\n apply = function (fun, thisValue, args) {\n return fun.apply(thisValue, args);\n };\n}\n\nif (!freeze) {\n freeze = function (x) {\n return x;\n };\n}\n\nif (!seal) {\n seal = function (x) {\n return x;\n };\n}\n\nif (!construct) {\n construct = function (Func, args) {\n return new Func(...args);\n };\n}\n\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayIndexOf = unapply(Array.prototype.indexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySlice = unapply(Array.prototype.slice);\n\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\n\nconst regExpTest = unapply(RegExp.prototype.test);\n\nconst typeErrorCreate = unconstruct(TypeError);\n\nexport function unapply(func) {\n return (thisArg, ...args) => apply(func, thisArg, args);\n}\n\nexport function unconstruct(func) {\n return (...args) => construct(func, args);\n}\n\n/* Add properties to a lookup table */\nexport function addToSet(set, array) {\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n\n let l = array.length;\n while (l--) {\n let element = array[l];\n if (typeof element === 'string') {\n const lcElement = stringToLowerCase(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n\n element = lcElement;\n }\n }\n\n set[element] = true;\n }\n\n return set;\n}\n\n/* Shallow clone an object */\nexport function clone(object) {\n const newObject = create(null);\n\n let property;\n for (property in object) {\n if (apply(hasOwnProperty, object, [property])) {\n newObject[property] = object[property];\n }\n }\n\n return newObject;\n}\n\n/* IE10 doesn't support __lookupGetter__ so lets'\n * simulate it. It also automatically checks\n * if the prop is function or getter and behaves\n * accordingly. */\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n\n object = getPrototypeOf(object);\n }\n\n function fallbackValue(element) {\n console.warn('fallback value for', element);\n return null;\n }\n\n return fallbackValue;\n}\n\nexport {\n // Array\n arrayForEach,\n arrayIndexOf,\n arrayPop,\n arrayPush,\n arraySlice,\n // Object\n freeze,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n hasOwnProperty,\n isFrozen,\n setPrototypeOf,\n seal,\n // RegExp\n regExpTest,\n // String\n stringIndexOf,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringTrim,\n // Errors\n typeErrorCreate,\n // Other\n lookupGetter,\n};\n", "import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'a',\n 'abbr',\n 'acronym',\n 'address',\n 'area',\n 'article',\n 'aside',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blink',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'center',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'content',\n 'data',\n 'datalist',\n 'dd',\n 'decorator',\n 'del',\n 'details',\n 'dfn',\n 'dialog',\n 'dir',\n 'div',\n 'dl',\n 'dt',\n 'element',\n 'em',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'font',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hgroup',\n 'hr',\n 'html',\n 'i',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'map',\n 'mark',\n 'marquee',\n 'menu',\n 'menuitem',\n 'meter',\n 'nav',\n 'nobr',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'picture',\n 'pre',\n 'progress',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'section',\n 'select',\n 'shadow',\n 'small',\n 'source',\n 'spacer',\n 'span',\n 'strike',\n 'strong',\n 'style',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'template',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'track',\n 'tt',\n 'u',\n 'ul',\n 'var',\n 'video',\n 'wbr',\n]);\n\n// SVG\nexport const svg = freeze([\n 'svg',\n 'a',\n 'altglyph',\n 'altglyphdef',\n 'altglyphitem',\n 'animatecolor',\n 'animatemotion',\n 'animatetransform',\n 'circle',\n 'clippath',\n 'defs',\n 'desc',\n 'ellipse',\n 'filter',\n 'font',\n 'g',\n 'glyph',\n 'glyphref',\n 'hkern',\n 'image',\n 'line',\n 'lineargradient',\n 'marker',\n 'mask',\n 'metadata',\n 'mpath',\n 'path',\n 'pattern',\n 'polygon',\n 'polyline',\n 'radialgradient',\n 'rect',\n 'stop',\n 'style',\n 'switch',\n 'symbol',\n 'text',\n 'textpath',\n 'title',\n 'tref',\n 'tspan',\n 'view',\n 'vkern',\n]);\n\nexport const svgFilters = freeze([\n 'feBlend',\n 'feColorMatrix',\n 'feComponentTransfer',\n 'feComposite',\n 'feConvolveMatrix',\n 'feDiffuseLighting',\n 'feDisplacementMap',\n 'feDistantLight',\n 'feFlood',\n 'feFuncA',\n 'feFuncB',\n 'feFuncG',\n 'feFuncR',\n 'feGaussianBlur',\n 'feImage',\n 'feMerge',\n 'feMergeNode',\n 'feMorphology',\n 'feOffset',\n 'fePointLight',\n 'feSpecularLighting',\n 'feSpotLight',\n 'feTile',\n 'feTurbulence',\n]);\n\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nexport const svgDisallowed = freeze([\n 'animate',\n 'color-profile',\n 'cursor',\n 'discard',\n 'fedropshadow',\n 'font-face',\n 'font-face-format',\n 'font-face-name',\n 'font-face-src',\n 'font-face-uri',\n 'foreignobject',\n 'hatch',\n 'hatchpath',\n 'mesh',\n 'meshgradient',\n 'meshpatch',\n 'meshrow',\n 'missing-glyph',\n 'script',\n 'set',\n 'solidcolor',\n 'unknown',\n 'use',\n]);\n\nexport const mathMl = freeze([\n 'math',\n 'menclose',\n 'merror',\n 'mfenced',\n 'mfrac',\n 'mglyph',\n 'mi',\n 'mlabeledtr',\n 'mmultiscripts',\n 'mn',\n 'mo',\n 'mover',\n 'mpadded',\n 'mphantom',\n 'mroot',\n 'mrow',\n 'ms',\n 'mspace',\n 'msqrt',\n 'mstyle',\n 'msub',\n 'msup',\n 'msubsup',\n 'mtable',\n 'mtd',\n 'mtext',\n 'mtr',\n 'munder',\n 'munderover',\n]);\n\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nexport const mathMlDisallowed = freeze([\n 'maction',\n 'maligngroup',\n 'malignmark',\n 'mlongdiv',\n 'mscarries',\n 'mscarry',\n 'msgroup',\n 'mstack',\n 'msline',\n 'msrow',\n 'semantics',\n 'annotation',\n 'annotation-xml',\n 'mprescripts',\n 'none',\n]);\n\nexport const text = freeze(['#text']);\n", "import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'accept',\n 'action',\n 'align',\n 'alt',\n 'autocapitalize',\n 'autocomplete',\n 'autopictureinpicture',\n 'autoplay',\n 'background',\n 'bgcolor',\n 'border',\n 'capture',\n 'cellpadding',\n 'cellspacing',\n 'checked',\n 'cite',\n 'class',\n 'clear',\n 'color',\n 'cols',\n 'colspan',\n 'controls',\n 'controlslist',\n 'coords',\n 'crossorigin',\n 'datetime',\n 'decoding',\n 'default',\n 'dir',\n 'disabled',\n 'disablepictureinpicture',\n 'disableremoteplayback',\n 'download',\n 'draggable',\n 'enctype',\n 'enterkeyhint',\n 'face',\n 'for',\n 'headers',\n 'height',\n 'hidden',\n 'high',\n 'href',\n 'hreflang',\n 'id',\n 'inputmode',\n 'integrity',\n 'ismap',\n 'kind',\n 'label',\n 'lang',\n 'list',\n 'loading',\n 'loop',\n 'low',\n 'max',\n 'maxlength',\n 'media',\n 'method',\n 'min',\n 'minlength',\n 'multiple',\n 'muted',\n 'name',\n 'nonce',\n 'noshade',\n 'novalidate',\n 'nowrap',\n 'open',\n 'optimum',\n 'pattern',\n 'placeholder',\n 'playsinline',\n 'poster',\n 'preload',\n 'pubdate',\n 'radiogroup',\n 'readonly',\n 'rel',\n 'required',\n 'rev',\n 'reversed',\n 'role',\n 'rows',\n 'rowspan',\n 'spellcheck',\n 'scope',\n 'selected',\n 'shape',\n 'size',\n 'sizes',\n 'span',\n 'srclang',\n 'start',\n 'src',\n 'srcset',\n 'step',\n 'style',\n 'summary',\n 'tabindex',\n 'title',\n 'translate',\n 'type',\n 'usemap',\n 'valign',\n 'value',\n 'width',\n 'xmlns',\n 'slot',\n]);\n\nexport const svg = freeze([\n 'accent-height',\n 'accumulate',\n 'additive',\n 'alignment-baseline',\n 'ascent',\n 'attributename',\n 'attributetype',\n 'azimuth',\n 'basefrequency',\n 'baseline-shift',\n 'begin',\n 'bias',\n 'by',\n 'class',\n 'clip',\n 'clippathunits',\n 'clip-path',\n 'clip-rule',\n 'color',\n 'color-interpolation',\n 'color-interpolation-filters',\n 'color-profile',\n 'color-rendering',\n 'cx',\n 'cy',\n 'd',\n 'dx',\n 'dy',\n 'diffuseconstant',\n 'direction',\n 'display',\n 'divisor',\n 'dur',\n 'edgemode',\n 'elevation',\n 'end',\n 'fill',\n 'fill-opacity',\n 'fill-rule',\n 'filter',\n 'filterunits',\n 'flood-color',\n 'flood-opacity',\n 'font-family',\n 'font-size',\n 'font-size-adjust',\n 'font-stretch',\n 'font-style',\n 'font-variant',\n 'font-weight',\n 'fx',\n 'fy',\n 'g1',\n 'g2',\n 'glyph-name',\n 'glyphref',\n 'gradientunits',\n 'gradienttransform',\n 'height',\n 'href',\n 'id',\n 'image-rendering',\n 'in',\n 'in2',\n 'k',\n 'k1',\n 'k2',\n 'k3',\n 'k4',\n 'kerning',\n 'keypoints',\n 'keysplines',\n 'keytimes',\n 'lang',\n 'lengthadjust',\n 'letter-spacing',\n 'kernelmatrix',\n 'kernelunitlength',\n 'lighting-color',\n 'local',\n 'marker-end',\n 'marker-mid',\n 'marker-start',\n 'markerheight',\n 'markerunits',\n 'markerwidth',\n 'maskcontentunits',\n 'maskunits',\n 'max',\n 'mask',\n 'media',\n 'method',\n 'mode',\n 'min',\n 'name',\n 'numoctaves',\n 'offset',\n 'operator',\n 'opacity',\n 'order',\n 'orient',\n 'orientation',\n 'origin',\n 'overflow',\n 'paint-order',\n 'path',\n 'pathlength',\n 'patterncontentunits',\n 'patterntransform',\n 'patternunits',\n 'points',\n 'preservealpha',\n 'preserveaspectratio',\n 'primitiveunits',\n 'r',\n 'rx',\n 'ry',\n 'radius',\n 'refx',\n 'refy',\n 'repeatcount',\n 'repeatdur',\n 'restart',\n 'result',\n 'rotate',\n 'scale',\n 'seed',\n 'shape-rendering',\n 'specularconstant',\n 'specularexponent',\n 'spreadmethod',\n 'startoffset',\n 'stddeviation',\n 'stitchtiles',\n 'stop-color',\n 'stop-opacity',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke',\n 'stroke-width',\n 'style',\n 'surfacescale',\n 'systemlanguage',\n 'tabindex',\n 'targetx',\n 'targety',\n 'transform',\n 'transform-origin',\n 'text-anchor',\n 'text-decoration',\n 'text-rendering',\n 'textlength',\n 'type',\n 'u1',\n 'u2',\n 'unicode',\n 'values',\n 'viewbox',\n 'visibility',\n 'version',\n 'vert-adv-y',\n 'vert-origin-x',\n 'vert-origin-y',\n 'width',\n 'word-spacing',\n 'wrap',\n 'writing-mode',\n 'xchannelselector',\n 'ychannelselector',\n 'x',\n 'x1',\n 'x2',\n 'xmlns',\n 'y',\n 'y1',\n 'y2',\n 'z',\n 'zoomandpan',\n]);\n\nexport const mathMl = freeze([\n 'accent',\n 'accentunder',\n 'align',\n 'bevelled',\n 'close',\n 'columnsalign',\n 'columnlines',\n 'columnspan',\n 'denomalign',\n 'depth',\n 'dir',\n 'display',\n 'displaystyle',\n 'encoding',\n 'fence',\n 'frame',\n 'height',\n 'href',\n 'id',\n 'largeop',\n 'length',\n 'linethickness',\n 'lspace',\n 'lquote',\n 'mathbackground',\n 'mathcolor',\n 'mathsize',\n 'mathvariant',\n 'maxsize',\n 'minsize',\n 'movablelimits',\n 'notation',\n 'numalign',\n 'open',\n 'rowalign',\n 'rowlines',\n 'rowspacing',\n 'rowspan',\n 'rspace',\n 'rquote',\n 'scriptlevel',\n 'scriptminsize',\n 'scriptsizemultiplier',\n 'selection',\n 'separator',\n 'separators',\n 'stretchy',\n 'subscriptshift',\n 'supscriptshift',\n 'symmetric',\n 'voffset',\n 'width',\n 'xmlns',\n]);\n\nexport const xml = freeze([\n 'xlink:href',\n 'xml:id',\n 'xlink:title',\n 'xml:space',\n 'xmlns:xlink',\n]);\n", "import { seal } from './utils.js';\n\n// eslint-disable-next-line unicorn/better-regex\nexport const MUSTACHE_EXPR = seal(/\\{\\{[\\s\\S]*|[\\s\\S]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nexport const ERB_EXPR = seal(/<%[\\s\\S]*|[\\s\\S]*%>/gm);\nexport const DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]/); // eslint-disable-line no-useless-escape\nexport const ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nexport const IS_ALLOWED_URI = seal(\n /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nexport const IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nexport const ATTR_WHITESPACE = seal(\n /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\n", "import * as TAGS from './tags.js';\nimport * as ATTRS from './attrs.js';\nimport * as EXPRESSIONS from './regexp.js';\nimport {\n addToSet,\n clone,\n freeze,\n arrayForEach,\n arrayPop,\n arrayPush,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringIndexOf,\n stringTrim,\n regExpTest,\n typeErrorCreate,\n lookupGetter,\n} from './utils.js';\n\nconst getGlobal = () => (typeof window === 'undefined' ? null : window);\n\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory.\n * @param {Document} document The document object (to determine policy name suffix)\n * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types\n * are not supported).\n */\nconst _createTrustedTypesPolicy = function (trustedTypes, document) {\n if (\n typeof trustedTypes !== 'object' ||\n typeof trustedTypes.createPolicy !== 'function'\n ) {\n return null;\n }\n\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (\n document.currentScript &&\n document.currentScript.hasAttribute(ATTR_NAME)\n ) {\n suffix = document.currentScript.getAttribute(ATTR_NAME);\n }\n\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn(\n 'TrustedTypes policy ' + policyName + ' could not be created.'\n );\n return null;\n }\n};\n\nfunction createDOMPurify(window = getGlobal()) {\n const DOMPurify = (root) => createDOMPurify(root);\n\n /**\n * Version label, exposed for easier checks\n * if DOMPurify is up to date or not\n */\n DOMPurify.version = VERSION;\n\n /**\n * Array of elements that DOMPurify removed during sanitation.\n * Empty if nothing was removed.\n */\n DOMPurify.removed = [];\n\n if (!window || !window.document || window.document.nodeType !== 9) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n\n return DOMPurify;\n }\n\n const originalDocument = window.document;\n\n let { document } = window;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes,\n } = window;\n\n const ElementPrototype = Element.prototype;\n\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n\n const trustedTypesPolicy = _createTrustedTypesPolicy(\n trustedTypes,\n originalDocument\n );\n const emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';\n\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName,\n } = document;\n const { importNode } = originalDocument;\n\n let documentMode = {};\n try {\n documentMode = clone(document).documentMode ? document.documentMode : {};\n } catch (_) {}\n\n let hooks = {};\n\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported =\n typeof getParentNode === 'function' &&\n implementation &&\n typeof implementation.createHTMLDocument !== 'undefined' &&\n documentMode !== 9;\n\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n } = EXPRESSIONS;\n\n let { IS_ALLOWED_URI } = EXPRESSIONS;\n\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [\n ...TAGS.html,\n ...TAGS.svg,\n ...TAGS.svgFilters,\n ...TAGS.mathMl,\n ...TAGS.text,\n ]);\n\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [\n ...ATTRS.html,\n ...ATTRS.svg,\n ...ATTRS.mathMl,\n ...ATTRS.xml,\n ]);\n\n /*\n * Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n const CUSTOM_ELEMENT_HANDLING = Object.seal(\n Object.create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false,\n },\n })\n );\n\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n\n /* Decide if document with ... should be returned */\n let WHOLE_DOCUMENT = false;\n\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n\n /* Output should be free from DOM clobbering attacks? */\n let SANITIZE_DOM = true;\n\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES = {};\n\n /* Tags to ignore content of when KEEP_CONTENT is true */\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, [\n 'annotation-xml',\n 'audio',\n 'colgroup',\n 'desc',\n 'foreignobject',\n 'head',\n 'iframe',\n 'math',\n 'mi',\n 'mn',\n 'mo',\n 'ms',\n 'mtext',\n 'noembed',\n 'noframes',\n 'noscript',\n 'plaintext',\n 'script',\n 'style',\n 'svg',\n 'template',\n 'thead',\n 'title',\n 'video',\n 'xmp',\n ]);\n\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, [\n 'audio',\n 'video',\n 'img',\n 'source',\n 'image',\n 'track',\n ]);\n\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [\n 'alt',\n 'class',\n 'for',\n 'id',\n 'label',\n 'name',\n 'pattern',\n 'placeholder',\n 'role',\n 'summary',\n 'title',\n 'value',\n 'style',\n 'xmlns',\n ]);\n\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n\n /* Parsing of strict XHTML documents */\n let PARSER_MEDIA_TYPE;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc;\n\n /* Keep a reference to config to pass to hooks */\n let CONFIG = null;\n\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n\n const formElement = document.createElement('form');\n\n const isRegexOrFunction = function (testValue) {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n\n /**\n * _parseConfig\n *\n * @param {Object} cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function (cfg) {\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n\n /* Set configuration parameters */\n ALLOWED_TAGS =\n 'ALLOWED_TAGS' in cfg\n ? addToSet({}, cfg.ALLOWED_TAGS)\n : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR =\n 'ALLOWED_ATTR' in cfg\n ? addToSet({}, cfg.ALLOWED_ATTR)\n : DEFAULT_ALLOWED_ATTR;\n URI_SAFE_ATTRIBUTES =\n 'ADD_URI_SAFE_ATTR' in cfg\n ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR)\n : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS =\n 'ADD_DATA_URI_TAGS' in cfg\n ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS)\n : DEFAULT_DATA_URI_TAGS;\n FORBID_CONTENTS =\n 'FORBID_CONTENTS' in cfg\n ? addToSet({}, cfg.FORBID_CONTENTS)\n : DEFAULT_FORBID_CONTENTS;\n FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};\n FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};\n USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck =\n cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\n }\n\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck =\n cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\n }\n\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements ===\n 'boolean'\n ) {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements =\n cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\n }\n\n PARSER_MEDIA_TYPE =\n // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1\n ? (PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE)\n : (PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE);\n\n // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n transformCaseFunc =\n PARSER_MEDIA_TYPE === 'application/xhtml+xml'\n ? (x) => x\n : stringToLowerCase;\n\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, [...TAGS.text]);\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, TAGS.html);\n addToSet(ALLOWED_ATTR, ATTRS.html);\n }\n\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, TAGS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, TAGS.svgFilters);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, TAGS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n }\n\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS);\n }\n\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR);\n }\n\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);\n }\n\n if (cfg.FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS);\n }\n\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n\n CONFIG = cfg;\n };\n\n const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, [\n 'mi',\n 'mo',\n 'mn',\n 'ms',\n 'mtext',\n ]);\n\n const HTML_INTEGRATION_POINTS = addToSet({}, [\n 'foreignobject',\n 'desc',\n 'title',\n 'annotation-xml',\n ]);\n\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n const ALL_SVG_TAGS = addToSet({}, TAGS.svg);\n addToSet(ALL_SVG_TAGS, TAGS.svgFilters);\n addToSet(ALL_SVG_TAGS, TAGS.svgDisallowed);\n\n const ALL_MATHML_TAGS = addToSet({}, TAGS.mathMl);\n addToSet(ALL_MATHML_TAGS, TAGS.mathMlDisallowed);\n\n /**\n *\n *\n * @param {Element} element a DOM element whose namespace is being checked\n * @returns {boolean} Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n const _checkValidNamespace = function (element) {\n let parent = getParentNode(element);\n\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: HTML_NAMESPACE,\n tagName: 'template',\n };\n }\n\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via . If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n\n // The only way to switch from MathML to SVG is via\n // svg if parent is either or MathML\n // text integration points.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return (\n tagName === 'svg' &&\n (parentTagName === 'annotation-xml' ||\n MATHML_TEXT_INTEGRATION_POINTS[parentTagName])\n );\n }\n\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n }\n\n if (element.namespaceURI === MATHML_NAMESPACE) {\n // The only way to switch from HTML namespace to MathML\n // is via . If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n\n // The only way to switch from SVG to MathML is via\n // and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n }\n\n if (element.namespaceURI === HTML_NAMESPACE) {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (\n parent.namespaceURI === SVG_NAMESPACE &&\n !HTML_INTEGRATION_POINTS[parentTagName]\n ) {\n return false;\n }\n\n if (\n parent.namespaceURI === MATHML_NAMESPACE &&\n !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]\n ) {\n return false;\n }\n\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erronously deleted from\n // HTML namespace.\n const commonSvgAndHTMLElements = addToSet({}, [\n 'title',\n 'style',\n 'font',\n 'a',\n 'script',\n ]);\n\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return (\n !ALL_MATHML_TAGS[tagName] &&\n (commonSvgAndHTMLElements[tagName] || !ALL_SVG_TAGS[tagName])\n );\n }\n\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG or MathML). Return false just in case.\n return false;\n };\n\n /**\n * _forceRemove\n *\n * @param {Node} node a DOM node\n */\n const _forceRemove = function (node) {\n arrayPush(DOMPurify.removed, { element: node });\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n node.parentNode.removeChild(node);\n } catch (_) {\n try {\n node.outerHTML = emptyHTML;\n } catch (_) {\n node.remove();\n }\n }\n };\n\n /**\n * _removeAttribute\n *\n * @param {String} name an Attribute name\n * @param {Node} node a DOM node\n */\n const _removeAttribute = function (name, node) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: node.getAttributeNode(name),\n from: node,\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: node,\n });\n }\n\n node.removeAttribute(name);\n\n // We void attribute values for unremovable \"is\"\" attributes\n if (name === 'is' && !ALLOWED_ATTR[name]) {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(node);\n } catch (_) {}\n } else {\n try {\n node.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n\n /**\n * _initDocument\n *\n * @param {String} dirty a string of dirty markup\n * @return {Document} a DOM, filled with the dirty markup\n */\n const _initDocument = function (dirty) {\n /* Create a HTML document */\n let doc;\n let leadingWhitespace;\n\n if (FORCE_BODY) {\n dirty = '' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml') {\n // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n dirty =\n '' +\n dirty +\n '';\n }\n\n const dirtyPayload = trustedTypesPolicy\n ? trustedTypesPolicy.createHTML(dirty)\n : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n } catch (_) {}\n }\n\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n\n const body = doc.body || doc.documentElement;\n\n if (dirty && leadingWhitespace) {\n body.insertBefore(\n document.createTextNode(leadingWhitespace),\n body.childNodes[0] || null\n );\n }\n\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(\n doc,\n WHOLE_DOCUMENT ? 'html' : 'body'\n )[0];\n }\n\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n\n /**\n * _createIterator\n *\n * @param {Document} root document/fragment to create iterator for\n * @return {Iterator} iterator instance\n */\n const _createIterator = function (root) {\n return createNodeIterator.call(\n root.ownerDocument || root,\n root,\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT,\n null,\n false\n );\n };\n\n /**\n * _isClobbered\n *\n * @param {Node} elm element to check for clobbering attacks\n * @return {Boolean} true if clobbered, false if safe\n */\n const _isClobbered = function (elm) {\n return (\n elm instanceof HTMLFormElement &&\n (typeof elm.nodeName !== 'string' ||\n typeof elm.textContent !== 'string' ||\n typeof elm.removeChild !== 'function' ||\n !(elm.attributes instanceof NamedNodeMap) ||\n typeof elm.removeAttribute !== 'function' ||\n typeof elm.setAttribute !== 'function' ||\n typeof elm.namespaceURI !== 'string' ||\n typeof elm.insertBefore !== 'function')\n );\n };\n\n /**\n * _isNode\n *\n * @param {Node} obj object to check whether it's a DOM node\n * @return {Boolean} true is object is a DOM node\n */\n const _isNode = function (object) {\n return typeof Node === 'object'\n ? object instanceof Node\n : object &&\n typeof object === 'object' &&\n typeof object.nodeType === 'number' &&\n typeof object.nodeName === 'string';\n };\n\n /**\n * _executeHook\n * Execute user configurable hooks\n *\n * @param {String} entryPoint Name of the hook's entry point\n * @param {Node} currentNode node to work on with the hook\n * @param {Object} data additional hook parameters\n */\n const _executeHook = function (entryPoint, currentNode, data) {\n if (!hooks[entryPoint]) {\n return;\n }\n\n arrayForEach(hooks[entryPoint], (hook) => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n };\n\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n *\n * @param {Node} currentNode to check for permission to exist\n * @return {Boolean} true if node was killed, false if left alive\n */\n const _sanitizeElements = function (currentNode) {\n let content;\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeElements', currentNode, null);\n\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Check if tagname contains Unicode */\n if (stringMatch(currentNode.nodeName, /[\\u0080-\\uFFFF]/)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Now let's check the element's type and name */\n const tagName = transformCaseFunc(currentNode.nodeName);\n\n /* Execute a hook if present */\n _executeHook('uponSanitizeElement', currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS,\n });\n\n /* Detect mXSS attempts abusing namespace confusion */\n if (\n !_isNode(currentNode.firstElementChild) &&\n (!_isNode(currentNode.content) ||\n !_isNode(currentNode.content.firstElementChild)) &&\n regExpTest(/<[/\\w]/g, currentNode.innerHTML) &&\n regExpTest(/<[/\\w]/g, currentNode.textContent)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Mitigate a problem with templates inside select */\n if (\n tagName === 'select' &&\n regExpTest(/