From 0f51037f2fce81e23c68f75d368e219ce80d8640 Mon Sep 17 00:00:00 2001 From: Daniel Cho Date: Fri, 26 Jul 2024 15:07:29 -0400 Subject: [PATCH 01/23] add: new messages file with French translations --- src/messages.json | 530 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 515 insertions(+), 15 deletions(-) diff --git a/src/messages.json b/src/messages.json index df09a1b4..8e86e981 100644 --- a/src/messages.json +++ b/src/messages.json @@ -525,25 +525,525 @@ "WorldSelector.Title": "Scene Background" }, "fr": { - "App.blockMode": "Block in French", - "App.changeMode": "Change Mode in French", + "ActionPanel.action.delete": "supprimer {stepNumber} {stepName}", + "ActionPanel.action.moveToNextStep": "remplacer l'étape {stepNumber} {stepName} {nextStepInfo}", + "ActionPanel.action.moveToPreviousStep": "remplacer l'étape {stepNumber} {stepName} {previousStepInfo}", + "ActionPanel.action.replace": "remplacer l'étape {stepNumber} {stepName} {selectedCommandName}", + "ActionPanel.selectedCommandName": "{selectedCommandName} avec action sélectionner", + "ActionsMenu.title": "action", + "ActionsMenu.toggleActionsMenu": "configurer les actions disponibles", + "ActionsMenuItem.command.backward1": "reculer d'un pas", + "ActionsMenuItem.command.forward1": "avancer d'une pas", + "ActionsMenuItem.command.left45": "tourner à gauche de 45 degrées", + "ActionsMenuItem.command.left90": "tourner à gauche de 90 degréees", + "ActionsMenuItem.command.loop": "boucle", + "ActionsMenuItem.command.right45": "tourner à droite 45 degrées", + "ActionsMenuItem.command.right90": "tourner à droite 90 degrées", + "ActionsMenuItem.unusedItemToggleLabel": "(action)", + "ActionsMenuItem.usedItemToggleLabel": "utilisé", + "ActionsSimplificationModal.cancel": "annuler", + "ActionsSimplificationModal.save": "sauvegarder", + "ActionsSimplificationModal.title": "actions disponibles", + "Announcement.actionSelected": "{commandType} {command} sélectionnée", + "Announcement.noActionSelected": "aucune action sélectionnée", + "Announcement.add": "{commandType} ajouté {command}", + "Announcement.control": "controle", + "Announcement.delete": "suprimé {commandType} {command}", + "Announcement.deleteAll": "suprimmer le programme", + "Announcement.endLoop": "boucle {loopLabel}", + "Announcement.forward1": "avance 1 case", + "Announcement.forward2": "avance 2 cases", + "Announcement.forward3": "avance 3 cases", + "Announcement.backward1": "reculer d'1 case", + "Announcement.backward2": "reculer 2 cases", + "Announcement.backward3": "reculer 3 cases", + "Announcement.left45": "tourner à gauche de 45 degrées", + "Announcement.left90": "tourner a gauche de 90 degréees", + "Announcement.left180": "turner à gauche de 180 degréees", + "Announcement.loop": "boucle", + "Announcement.moveToPrevious": "déplacer vers la gauche", + "Announcement.moveToNext": "déplacer vers la droite", + "Announcement.movement": "mouvement ", + "Announcement.replace": "mouvement {oldCommand} remplacer par une {newCommand}", + "Announcement.right45": "tourner a droite 45 degrées", + "Announcement.right90": "tourner a droite 90 degrées", + "Announcement.right180": "turner a droite 180 degrées", + "Announcement.startLoop": "boucle {loopLabel}", + "App.appHeading": "Weavly", + "App.appHeading.link": "Weavly, en savoir plus sur Weavly a Weavly point org", + "App.blockMode": "bloc", + "App.changeMode": "changer de mode", "App.connectToDash": "Se connecter à Dash", + "App.privacyModalToggle": "intimité", + "App.privacyModalToggle.ariaLabel": "politique de confidentialité de Weavly", "App.run": "Lancer", - "App.speechRecognition": "Speech Recognition in French", - "App.textMode": "Text in French", - "CommandPalette.movementsTitle": "Movements in French", - "CommandPalette.soundsTitle": "Sounds in French", - "CommandPaletteCommand.forward": "Forward in French", - "CommandPaletteCommand.left": "Left in French", - "CommandPaletteCommand.right": "Right in French", + "App.speechRecognition": "reconnaisance de la parole", + "App.textMode": "Texte", + "BluetoothApiWarning.errorIconLabel": "advertissent", + "BluetoothApiWarning.message": "la connection du robot dash fonctionne seulement en Chrome", + "Camping.bear": "l`ours noire", + "Camping.branch": "branche d'arbre", + "Camping.character": "écureuil", + "Camping.fire": "le feu de camp", + "Camping.label": "une scène de camping. un ours noir atteint un tronc d'arbre sûre le côté gauche de la scène. une branche 'arbre traverse le haut des la scène et une échelle de corde y est suspendu. il y a une tente ouvert sur le côté droit de la scène. un lac et un feu de camp sont au milieu de la scène. votre personnage dans cette scène est une écureuil.", + "Camping.ladder": "une échelle de corde", + "Camping.lake": "le lac", + "Camping.name": "voyage de camping", + "Camping.tentdoor": "la porte de la tente", + "Camping.trunk": "le tronc d\u0000'arbre ", + "CharacterAriaLive.movementAriaLabel": "Le {character} bouge", + "Command.backward1": "à l'envers 1 carré", + "Command.backward2": "a l'envers 2 carrées", + "Command.backward3": "à l'envers 3 carrées", + "Command.endLoop": "{loopLabel} fin de boucle", + "Command.forward1": "avancer d'une case", + "Command.forward2": "avancer de 2 cases", + "Command.forward3": "avancer de 3 cases", + "Command.left45": "tourner à gauche 45 degrées", + "Command.left90": "tourner à gauche 90 degrées", + "Command.left180": "tourner à gauche 180 degréees", + "Command.loop": "boucle", + "Command.loop.label": "{loopLabel} de boucle", + "Command.right45": "tourner à droite 45 degrées", + "Command.right90": "tourner à droite 90 degrees", + "Command.right180": "tourner à droite 180 degréees", + "Command.startLoop": "début de boucle {loopLabel}", + "CommandInfo.previousStep": "avant l'étape {previousStepNumber} {command}", + "CommandInfo.previousStep.endLoop": "dans la boucle {loopLabel}", + "CommandInfo.previousStep.inLoop": "avant l'étape {previousStepNumber} {command} de la boucle {loopLabel}", + "CommandInfo.previousStep.loop": "avant l'étape {previousStepNumber} {command}", + "CommandInfo.previousStep.startLoop": "hors boucle {loopLabel}", + "CommandInfo.nextStep": "après l'étape {next step number} {command}", + "CommandInfo.nextStep.endLoop": "hors boucle {loopLabel}", + "CommandInfo.nextStep.inLoop": "après l'étape {next step number} {command} de la boucle {loopLabel}", + "CommandInfo.nextStep.loop": "après l'étape {next step number} {command}", + "CommandInfo.nextStep.startLoop": "en boucle {loopLabel}", + "CommandPalette.controlsTitle": "contrôles", + "CommandPalette.movementsTitle": "Mouvements", + "CommandPalette.shortMovementsTitle": "bouge", + "CommandPalette.soundsTitle": "sons", + "ConfirmDeleteAllModal.cancelButton": "annuler", + "ConfirmDeleteAllModal.confirmButton": "supprimer", + "ConfirmDeleteAllModal.content": "êtes-vous sûr de voulair suprimer tous les étapes de ton programme?", + "ConfirmDeleteAllModal.title": "supprimer le programme", + "CharacterPositionController.editPosition.turnLeft": "turne le charactère a la gauche", + "CharacterPositionController.editPosition.turnRight": "turne le charactère a la droite", + "CharacterPositionController.editPosition.moveUp": "déplacer le personnage vers le haut", + "CharacterPositionController.editPosition.moveRight": "déplacer le personnage vers la droite", + "CharacterPositionController.editPosition.moveDown": "déplacer le personnage vers le bas", + "CharacterPositionController.editPosition.moveLeft": "déplacer le personnage vers la gauche", + "CharacterPositionController.editPosition.columnPosition": "position de la colonne des charactères", + "CharacterPositionController.editPosition.rowPosition": "position de la ranger des charactères", + "DashConnectionErrorModal.cancelButton": "anuler la connextion", + "DashConnectionErrorModal.error": "erreur de connextion", + "DashConnectionErrorModal.firstMessage": "assurez vous que le bluetooth de votre appareil est désactiver", + "DashConnectionErrorModal.retryButton": "réessayer", + "DashConnectionErrorModal.secondMessage": "assurez vous que Dash est activé et se troue a proximité de votre appareil", + "DashConnectionErrorModal.title": "quelque chose s'est mal passé!", + "DeepOcean.babyJellyfish": "un bébé méduse", + "DeepOcean.character": "le sous-marin", + "DeepOcean.coral": "corail", + "DeepOcean.fish": "un poisson", + "DeepOcean.fishGroup": "le groupe de poissons", + "DeepOcean.jellyfish": "le méduse", + "DeepOcean.label": "une scène sous marine. Un grand requin fait le tours des eaux au-dessous d'un coffre de trésores au fond du fond marin. Le coffre est rempli de bijoux et de pieces d'ors. Poissons et méduses nagent autour des coraux et des algues. Votre personnage dans ce scène est un sous-marin.", + "DeepOcean.name": "Océan profond", + "DeepOcean.shark": "le renard", + "DeepOcean.treasure": "the trésore", "DeviceConnectControl.notConnected": "Pas connecté", "DeviceConnectControl.connecting": "Connexion en cours", "DeviceConnectControl.connected": "Connecté", - "ProgramBlockEditor.command.forward": "Forward, position {index} of current program in French", - "ProgramBlockEditor.command.left": "Left, position {index} of current program in French", - "ProgramBlockEditor.command.none": "Empty block, position {index} of current program in French", - "ProgramBlockEditor.command.right": "Right, position {index} of current program in French", - "ProgramBlockEditor.editorAction.clear": "Clear and start new program in French", - "ProgramTextEditor.programLabel": "Logiciel:" + "Direction.0": "haut", + "Direction.1": "en haut à droite", + "Direction.2": "droite", + "Direction.3": "en bas à droite", + "Direction.4": "bas", + "Direction.5": "en bas à gauche", + "Direction.6": "gauche", + "Direction.7": "en haut à gauce", + "Savannah.alligator": "L'alligator", + "Savannah.babyAlligator": "le bébé alligator", + "Savannah.babyGiraffe": "le bébé giraffe", + "Savannah.bush": "une buisson", + "Savannah.character": "le jeep", + "Savannah.flamingo": "le flamant rose", + "Savannah.giraffe": "le giraffe", + "Savannah.hippo": "l'hippopotame", + "Savannah.label": "Une scène de Savane. Un lion rugit au sommet d'une falaise au-dessous de l'horizon. Une mère et son bébé giraffe parcourent la savane. Deux, crocodiles, un flamant rose et un hippopotame boivent de l'eau d'un étang entourné d'arbres. Votre personnage dans cette scène est un Jeep", + "Savannah.lion": "le lion", + "Savannah.name": "Jungle", + "Savannah.pond": "l'étang", + "Savannah.tree": "l'arbre", + "KeyboardInputModal.Cancel": "annuler", + "KeyboardInputModal.Description.addCommandToBeginning": "appuyer sur la {key} pour ajouter la commande sélectionnée au début du programme", + "KeyboardInputModal.Description.addCommandToEnd": "appuyer sur la {key} pour ajouter la commande sélectionnée à la fin du programme", + "KeyboardInputModal.Description.announceScene": "appuyer sur la {key} pour annoncer la position du charactère et l'orientation", + "KeyboardInputModal.Description.deleteCurrentStep": "appuyer sur la {key} pour surpimer l'étape actuellement ciblée", + "KeyboardInputModal.Description.decreaseProgramSpeed": "appuyer sur la {key} pour ralentir la lecture du programme", + "KeyboardInputModal.Description.increaseProgramSpeed": "appuyer sur la {key} pour accélérer la lecture du programme", + "KeyboardInputModal.Description.playPauseProgram": "appuyer sur la {key} pour lire ou mettre en pause le programme", + "KeyboardInputModal.Description.refreshScene": "appuyer sur la {key} pour réfraîchir la scène", + "KeyboardInputModal.Description.showHide": "appuyer sur la {key} pour voir le menu racourci de l'ordinateur", + "KeyboardInputModal.Description.stopProgram": "appuyer sur la {key} pour arrêter le programme", + "KeyboardInputModal.Description.toggleAnnouncements": "appuyer sur la {key} pour basculer les annonces", + "KeyboardInputModal.KeyLabels.Alt": "alt", + "KeyboardInputModal.KeyLabels.Control": "contôle", + "KeyboardInputModal.KeyLabels.QuestionMark": "point d'interrogation", + "KeyboardInputModal.KeyLabels.GreaterThan": "plus grand que", + "KeyboardInputModal.KeyLabels.LessThan": "plus petit que", + "KeyboardInputModal.KeyLabels.A": "a", + "KeyboardInputModal.KeyLabels.B": "b", + "KeyboardInputModal.KeyLabels.D": "d", + "KeyboardInputModal.KeyLabels.E": "e", + "KeyboardInputModal.KeyLabels.I": "i", + "KeyboardInputModal.KeyLabels.P": "p", + "KeyboardInputModal.KeyLabels.S": "s", + "KeyboardInputModal.KeyLabels.R": "r", + "KeyboardInputModal.KeyIcons.Alt": "alt", + "KeyboardInputModal.KeyIcons.Control": "ctrl", + "KeyboardInputModal.KeyIcons.Shift": "déclage", + "KeyboardInputModal.KeyIcons.QuestionMark": "?", + "KeyboardInputModal.KeyIcons.GreaterThan": ">", + "KeyboardInputModal.KeyIcons.LessThan": "<", + "KeyboardInputModal.KeyIcons.A": "A", + "KeyboardInputModal.KeyIcons.B": "B", + "KeyboardInputModal.KeyIcons.D": "D", + "KeyboardInputModal.KeyIcons.E": "E", + "KeyboardInputModal.KeyIcons.I": "I", + "KeyboardInputModal.KeyIcons.P": "P", + "KeyboardInputModal.KeyIcons.S": "S", + "KeyboardInputModal.KeyIcons.R": "R", + "KeyboardInputModal.Save": "sauvegarder ", + "KeyboardInputModal.Scheme.Descriptions.controlalt": "contrôle+alt (apple: contrôle+option)", + "KeyboardInputModal.Scheme.Descriptions.alt": "alt (apple: option)", + "KeyboardInputModal.ShowHide.AriaLabel": "afficher le menu des raccourcis claviers", + "KeyboardInputModal.Title": "raccourcis clavier", + "KeyboardInputModal.Toggle.AriaLabel": "basculer les raccourcis claviers", + "KeyboardInputModal.Toggle.Label": "keyboard shortcuts", + "KeyboardInputModal.Toggle.Off": "à l'arrête", + "KeyboardInputModal.Toggle.On": "sur", + "Landmarks.bigBen": "Tour Big Ben", + "Landmarks.burAlArab": "Le bâtiment Burj al Arab", + "Landmarks.character": "robot", + "Landmarks.cnTower": "La tour CN", + "Landmarks.colosseum": "Le Colossuem", + "Landmarks.easterIsland": "les statues de l'île de pacques", + "Landmarks.eiffelTower": "La Tour Eiffel", + "Landmarks.fairyChimneys": "cheminées de fées", + "Landmarks.floatingMarket": "le marché flottant de Vietnam", + "Landmarks.grandCanyon": "Le grand Canyon", + "Landmarks.greatPyramid": "la grande pyramide de Gizeh", + "Landmarks.greatSphinx": "la grande sphinx de Gizeh", + "Landmarks.greatWall": "La grande muraille de Chine", + "Landmarks.label": "Une grande scène mondiale qui contient 23 monuments célèbres trouver dans le monde. Un avion vole depuis le point supérieur gauche. Un train part du point supérieur droite. Les points de repère sont situés à différents endroits de cet scène, notament le fameux Sphinx en Egypte, la Tour Eiffel en France, la tour de Tokyo au Japon et le marché flottant au Vietnam. Votre personage pour explorer cette scène est Bot.", + "Landmarks.leaningTowerPisa": "La tour penché de Pize", + "Landmarks.machuPicchu": "Matchu Picchu", + "Landmarks.name": "Repères", + "Landmarks.niagaraFalls": "chutes du Niagara", + "Landmarks.operaHouse": "L'Opéra de Sydney", + "Landmarks.plane": "un avion", + "Landmarks.stBasils": "Cathédrale Saint-Basile", + "Landmarks.statueLiberty": "la statue de la Liberté", + "Landmarks.stonehenge": "Stonehenge", + "Landmarks.tableMountain": "table montagne", + "Landmarks.tajMahal": "le palais Taj Mahal", + "Landmarks.tokyoTower": "la tour de Tokyo", + "Landmarks.train": "un train", + "Landmarks.windmill": "les moulins à vents des Pais-Bas", + "PenDownToggleSwitch.penDown": "Stylo vers le bas", + "PlayButton.play": "jouer", + "PlayButton.pause": "pause", + "PlayControls.heading": "jouer aux commandes", + "PrivacyModal.close": "fermer", + "PrivacyModal.title": "Weavly politique de confidentialité", + "ProgramBlockEditor.toggleAddNodeExpandMode": "ajouter un note en mode développer", + "ProgramBlockEditor.beginningBlock": "ajouté l'action selectionnée {command} au début du programme", + "ProgramBlockEditor.betweenBlocks": "ajouté l'action selectionée {command} entre la position {prevCommand} et la position {postCommand}", + "ProgramBlockEditor.lastBlock": "ajouté l'action sélectionée {command} à la fin du programme", + "ProgramBlockEditor.blocks.noCommandSelected": "assurez vous qu'une action est sélectionée", + "ProgramBlockEditor.command": "{command}, possition, {index} du programme en cours", + "ProgramBlockEditor.nestedCommand": "{command}, possition, {index} du boucle, {parentLoopLabel}", + "ProgramBlockEditor.program.deleteAll": "suprrimer tout les étapes de votre programme", + "ProgramBlockEditor.programHeading": "programme", + "ProgramTextEditor.programLabel": "Logiciel:", + "ProgramSequence.heading": "vitesse de lecture du programme", + "ProgramSpeedController.slider": "vitesse de lecture du programme", + "Scene.heading": "scène", + "ShareModal.close": "fermé", + "ShareModal.copy": "copier le lien", + "ShareModal.title": "lien de partage", + "ShareModal.description1": "un lien vers le programme que vous avez créer à été copié dans le presse-papier", + "ShareModal.description2": "vous pouvez également copier le lien ci-dessous et le partager avec qui vous voulez", + "Sketchpad.character": "le robot", + "Sketchpad.label": "un croquis vierge avec une ligne de quadrillage. Votre charactère dans se scène est un robot", + "SoundOptionsModal.allSounds": "tout les sons", + "SoundOptionsModal.announcements": "annonces audio", + "SoundOptionsModal.cancelButton": "annuler", + "SoundOptionsModal.musicalSounds": "sons musicaux ", + "SoundOptionsModal.saveButton": "sauvegarder ", + "SoundOptionsModal.title": "options sonores", + "SoundOptionsModal.toggleOff": "étient", + "SoundOptionsModal.toggleOn": "allumer", + "Sketchpad.name": "un croquis ", + "StopButton": "arrête", + "ThemeSelector.cancelButton": "annuler", + "ThemeSelector.saveButton": "sauvegarder ", + "ThemeSelector.iconButton": "sélecteur du thème", + "ThemeSelector.option.default": "défaut", + "ThemeSelector.option.light": "clair", + "ThemeSelector.option.dark": "sombre", + "ThemeSelector.option.gray": "niveaux de gris", + "ThemeSelector.option.contrast": "contraste élèvé", + "ThemeSelector.title": "thèmes", + "RefreshButton": "rafraîchir", + "ShareButton": "partager", + "Space.aliens": "les aliens", + "Space.asteroid": "une astéroïde", + "Space.character": "le vaisseaux spaciale", + "Space.earth": "la Terre", + "Space.label": "Une scène spaciale avec la Terre, Mars, Saturne, et la Lune répartis en espace. Entre les planètes, il y a des roches spaciales, des météores, un satellite et deux extraterrestres . Votre personnage dans ce scène est un vaisseaux spaciale", + "Space.mars": "Mars", + "Space.meteor": "Une météore", + "Space.moon": "La Lune", + "Space.name": "Espace", + "Space.satellite": "le satélitte", + "Space.saturn": "Saturne", + "Space.star": "Une étoile", + "WorldSelector.Cancel": "annuler", + "WorldSelector.Save": "sauvegarder ", + "WorldSelector.Prompt": "selectionner une arrière plan pour votre scène", + "WorldSelector.Title": "fond de scène", + "Announcement.cannotMoveNext": "à la fin du programme, incapable de se déplacer vers la droite", + "Announcement.cannotMovePrevious": "au début du programme, incapable de se déplacer vers la gauche", + "Announcement.cannotReplaceLoopBlocks": "remplacer n'est pas disponible pour les boucles", + "Haunted.chair": "la chaise", + "Haunted.character": "la lampe de poche", + "Haunted.fireplace": "la cheminée", + "Haunted.label": "Une scène de manoire effrayante. Le corridor d'entrée comporte un grand escalier commençant un bas à droite et allant en haut à gauche. Des peintures hantées, un mirroir et une crâne de cerf effrayant sont accrochées au mur. Les chauves sourris volent. Un feu brûle dans la chiminée située sous la cage d'escalier. Une grande chaise confortable est devant le feu. Les étagères d'une grande bibliothèque à gauche de la scène sont remplis de livres, potions et plantes. Votre personnage dans cette scène est une lampe de poche.", + "Haunted.name": "une maison hauntée", + "Haunted.shelf": "la bibliothèque", + "Haunted.stairs": "les escaliers", + "Marble.bricks": "briques", + "Marble.character": "une bille", + "Marble.label": "Une labyrinthe fait de briques de différentes couleurs. Votre personnage dans cette scène est une bille. Il y a un chemin à travers le labyrinthe qui commence là où se trouve votre bille et il existe plusieurs façons d'échapper du labyrinthe.", + "Marble.name": "course de billes", + "AmusementPark.character": "le billet", + "AmusementPark.entrance": "entrée", + "AmusementPark.ferrisWheel": "grande roue", + "AmusementPark.gameBooth": "stand de jeu", + "AmusementPark.goKarts": "karts", + "AmusementPark.label": "Une scène de parc d'attractions. Une scène avec vos attractions préférées: des montagnes rousses, un grand roue, un bateau pirate, des karts, une blançoir, et un manège. Il y a d'autres choses amusantes à faire, comme un stand de jeux, et une parc aquatique, et si vous voulez des collations, il y a une stand de collations. Votre personnage est un ticket.", + "AmusementPark.merryGoRound": "manège", + "AmusementPark.name": "parc d'attractions", + "AmusementPark.pirateShip": "navire pirate", + "AmusementPark.snackStand": "stand de collations", + "AmusementPark.swingRide": "tour de balançoire", + "AmusementPark.rollerCoaster": "montagnes rousses", + "AmusementPark.waterPark": "parc aquatique", + "AmusementPark.waterSlide": "glissade d'eau", + "AmusementPark.whaleFountain": "fontaine des baleines", + "AtlanticCanada.character": "Insulaire de Cap", + "AtlanticCanada.fishProcessingPlant": "usine de transformation des poissons", + "AtlanticCanada.fogBank": "banc de brouillard", + "AtlanticCanada.house": "une maison", + "AtlanticCanada.iceberg": "in iceberg", + "AtlanticCanada.label": "Scène de voyage Atlantique. Voyagez au Canada atlntique à travers l'océan Atlantique. La météo est imprévisable dans l'océan , certaines parties de l'océan peuvent être orageuses et certaines parties de l'océan peuvent être couverte de brouillard. Voyagez en toute sécurité pour visiter une usine de transformation du poisson et une village terrestre; vous pourriez rencontrer des icebergs ou des baleine sur votre chemin. Votre personnage dans cette scène est un bateau de pêche, également connu sous le nom Cape Islander dans le Canada Atlantique.", + "AtlanticCanada.land": "la terre", + "AtlanticCanada.lighthouse": "la phare", + "AtlanticCanada.name": "atlantique Canada", + "AtlanticCanada.trees": "arbres", + "AtlanticCanada.rowingBoatOnTheShore": "un bateau à rames sur le rivage", + "AtlanticCanada.sailboat": "un bateau a voile", + "AtlanticCanada.shoal": "un banc de poissons", + "AtlanticCanada.shore": "la rive", + "AtlanticCanada.storms": "tempêtes", + "AtlanticCanada.water": "l'eau", + "AtlanticCanada.whale": "une baleine", + "CharacterDescriptionBuilder.positionAndDirection": "À {columnLabel} {rowLabel} face à {direction}", + "CharacterDescriptionBuilder.positionAndDirectionAndItem": "À {columnLabel} {rowLabel} sur {item} orienté vers {direction}", + "CharacterMessageBuilder.hitWall": "ton personnage a heurté un mur {columnLabel} {rowLabel}", + "CharacterMessageBuilder.endOfScene": "Votre personnage à atteint la fin de la scène", + "CharacterPositionController.editPosition.designMode.moveUp": "déplacer le pinceau vers le haut", + "CharacterPositionController.editPosition.designMode.moveRight": "déplacer le pinceau vers la droite", + "CharacterPositionController.editPosition.designMode.moveDown": "déplacer le pinceau vers le bas", + "CharacterPositionController.editPosition.designMode.moveLeft": "déplacer le pinceau vers la gauche", + "CharacterPositionController.editPosition.designMode.columnPosition": "position de la colonne du pinceau", + "CharacterPositionController.editPosition.designMode.rowPosition": "position de rang du pinceau", + "CharacterPositionController.paintbrushButtonEraserSelected": "effacer le carré", + "CharacterPositionController.paintbrushButtonNoSelection": "peindre un carré de fond", + "CharacterPositionController.paintbrushButtonTileSelected": "peinture {tile}", + "CharacterPositionController.setStartButton": "définir la position de départ", + "CustomBackgroundDesignModeButton.customBackgroundDesignMode": "mode de conception arrière plan personnalisé", + "DesignModeCursorDescriptionBuilder.position": "à {columnLabel} {rowLabel} ", + "DesignModeCursorDescriptionBuilder.positionAndItem": "À {columnLabel} {rowLabel} sur {item}", + "EuropeTrip.C1": "Islande", + "EuropeTrip.E1": "le Royaume-Uni", + "EuropeTrip.F1": "Norvège", + "EuropeTrip.G1": "Norvège et Suède", + "EuropeTrip.H1": "Suède", + "EuropeTrip.I1": "Cathéralde d'Helsinki en Finlande", + "EuropeTrip.J1": "Finlande", + "EuropeTrip.C2": "une balleine en Islande", + "EuropeTrip.D2": "Irlande et le Royaume-Uni", + "EuropeTrip.E2": "le Royaume-Uni", + "EuropeTrip.F2": "un drakkar à Norway", + "EuropeTrip.G2": "Danemark et Norvège et Suède", + "EuropeTrip.H2": "Galma Stan sur la Suède", + "EuropeTrip.I2": "Tallinn en Estonie; également sur cette place est Finlande et Lettonie", + "EuropeTrip.C3": "Irelande", + "EuropeTrip.D3": "un trèfle en irlande; aussi sur cette place le Royaume-Uni", + "EuropeTrip.E3": "un bus à impériale au Royaume-Uni", + "EuropeTrip.F3": "un moulin-à-vent aux Pays-Bas", + "EuropeTrip.G3": "pâtisserie danoise aux Danemark; également sur cette place l'Allemagne et la Suède", + "EuropeTrip.H3": "Pologne et Suède", + "EuropeTrip.I3": "des marguerites en Lettonie et le châteaux de l'Île de Trakai en Lutuanie; aussi sur cette pièce Biéloroussie", + "EuropeTrip.J3": "bibliothèque nationale aux Biéloroussie", + "EuropeTrip.D4": "France te le Royaume-Uni", + "EuropeTrip.E4": "chocolate en Belgique; aussi sur cette pièce est la France et le Royaume-Uni", + "EuropeTrip.F4": "un bretzel en Allemagne; aussi das cette pièce le Belgique, Luxembourg, et Pays-Bas", + "EuropeTrip.G4": "Colonnade du moulin en République tchèque; également sur cette pièce est l'Allemagne et Pologne", + "EuropeTrip.H4": "Kielbasa aux Pologne", + "EuropeTrip.I4": "Biéroussie et Pologne et Ukraine", + "EuropeTrip.J4": "Biéroussie et Ukraine", + "EuropeTrip.K4": "Ukraine", + "EuropeTrip.L4": "Ukraine", + "EuropeTrip.C5": "Espagne", + "EuropeTrip.D5": "France", + "EuropeTrip.E5": "La tour eiffel en France", + "EuropeTrip.F5": "un montre en Suisse; aussi sur cette pièce l'Autriche, France et l'Allemagne", + "EuropeTrip.G5": "un violon en Autruche et Bled sur la Sloavquie; aussi sur cette pièce le République tzchège et l'Allemagne", + "EuropeTrip.H5": "le paprika en Hongrie et la cérémique en Slovaquie; également sur cette place Autriche et République tscheque et Slovénie", + "EuropeTrip.I5": "Châteux de Peles en Roumaine; aussi sur cette pièce Hongrie, Sloavquie, et Ukraine", + "EuropeTrip.J5": "tournesol en Moldavie; aussi sur cette pièce Roumaine et l'Ukraine", + "EuropeTrip.K5": "Monastère au dôme doré de Saint-Micheal en Ukraine", + "EuropeTrip.L5": "Ukraine", + "EuropeTrip.B6": "la tour de Saint Vincent en Portugal", + "EuropeTrip.C6": "Portugal et Espagne", + "EuropeTrip.D6": "France et Espagne", + "EuropeTrip.E6": "LA tour Eiffel en France", + "EuropeTrip.F6": "France et Italie", + "EuropeTrip.G6": "le miel en Croatie et Bled en Slovanie; également sur cette pièce est l'Italie", + "EuropeTrip.H6": "la mosquée Sinan Pacha au Kosovo et l'église Saint-Sava en Serbie et Stari Most en Bosnie-Herzégovine ; également sur cette place la Croatie et la Hongrie et le Monténégro", + "EuropeTrip.I6": "Église Saint-Sava en Serbie ; également sur cette place la Bulgarie et la Roumanie", + "EuropeTrip.J6": "Bulgaria et Moldova et Romanie", + "EuropeTrip.K6": "Ukraine", + "EuropeTrip.B7": "Portugal ", + "EuropeTrip.C7": "Guitare Flamenco en Espagne", + "EuropeTrip.D7": "Espagne", + "EuropeTrip.E7": "Espagne", + "EuropeTrip.F7": "France et Italie", + "EuropeTrip.G7": "pizza en Italie", + "EuropeTrip.H7": "une chargia en Albanie et la mosquée Sinan Pacha au Kosovo et un yacht au Monténégro ; également sur cette place Macédoine du Nord", + "EuropeTrip.I7": "Rose Valley en Bulgarie et Millennium Cross en Macédoine du Nord ; également sur cette place la Grèce et le Kosovo", + "EuropeTrip.J7": "Bulgarie et Turquie", + "EuropeTrip.K7": "café en Turquie", + "EuropeTrip.L7": "Turquie", + "EuropeTrip.G8": "Italie", + "EuropeTrip.H8": "Grèce et Italie", + "EuropeTrip.I8": "le Parthenon en Grèce", + "EuropeTrip.J8": "Grèce et Turquie", + "EuropeTrip.K8": "olives en Chypre; aussi sur cette case Turquie", + "EuropeTrip.L8": "olives en Chypre; aussi sur cette case Turquie", + "EuropeTrip.character": "l'avion", + "EuropeTrip.label": "Une scène de voyage en Europe contenant une carte de Europe avec des attractions touristiques. L'Islande est située en haut à gauche de la scène. Chypre est située en bas à droite de la scène. Les attractions touristiques sont située dans le pays connu pour des attractions, comme le Violon en Autriche, près du centre de la scène. Votre personnage dans cette scène est un avion.", + "EuropeTrip.name": "Voyage en Europe", + "GroceryStore.apples": "pommes", + "GroceryStore.bagOfRice": "sac de riz", + "GroceryStore.bananas": "bananes", + "GroceryStore.bottles": "bouteilles", + "GroceryStore.bread": "pain", + "GroceryStore.broccoli": "brocoli", + "GroceryStore.cans": "canettes", + "GroceryStore.carrots": "carottes", + "GroceryStore.ceilingLight": "plafonnier", + "GroceryStore.character": "le panier", + "GroceryStore.cheese": "fromage", + "GroceryStore.chicken": "poulet", + "GroceryStore.chocolateMilk": "lait au chocolat", + "GroceryStore.cucumbers": "concombres", + "GroceryStore.eggplants": "aubergines", + "GroceryStore.eggs": "oeufs ", + "GroceryStore.fish": "poisson", + "GroceryStore.grapes": "raisins", + "GroceryStore.greenVegetables": "légumes verts", + "GroceryStore.groundBeef": "le boeuf haché ", + "GroceryStore.jars": "pots", + "GroceryStore.label": "Une scène d'epicerie. En haut au milieu se trouve un frigo contenent de la viande et du poisson. En haut à droite se trouve des pots, des canettes et d'autres articles de garde-manger. A gauche du magasin se trouve des pains et des légumes. Au milieu vers le bas se trouve les fruits. Et en bas à droite se trouve un frigo contenant des produits laitier et d'autre produits réfrigérés. Votre personnage dans cette scène est un panier d'épicerie", + "GroceryStore.milk": "lait ", + "GroceryStore.name": "Épicerie", + "GroceryStore.onions": "onions", + "GroceryStore.orangeJuice": "jus d'orange", + "GroceryStore.oranges": "oranges", + "GroceryStore.pasta": "pâtes", + "GroceryStore.pears": "des poires", + "GroceryStore.pineapples": "ananas", + "GroceryStore.potatoes": "patates", + "GroceryStore.refrigerator": "frigo ou réfrigirateur", + "GroceryStore.steak": "steak", + "GroceryStore.strawberries": "fraises", + "GroceryStore.tofu": "tofu", + "GroceryStore.tomatoes": "tomates", + "GroceryStore.watermelons": "melon-d'eau", + "GroceryStore.yogurt": "yaourte", + "MusicBand.character": "la note de musique", + "MusicBand.drumKit": "la batterie", + "MusicBand.guitar": "la guitare", + "MusicBand.label": "Une scène de groupe de bande avec des instruments de musique. Les instruments sont déposés sur 2 rangées, une rangée au milieu de la scène et une vers le bas de la scène. Dans la rangée supérieur, il ya une guitar, une batterie et un saxophone. Sur la rangée inférieur, il y a un tambourin, un xylophone avec un maillet, une microphone sur un pied et une synthétiseur. Au sommet de la scène. des projecteurs éclairent les instruments et dans les coins inférieurs à droit se trouve les haut-parleurs. Votre personnage dans cette scène est un note de musique.", + "MusicBand.loudspeaker": "un haut-parleur", + "MusicBand.microphone": "un mircrophone sur un pied", + "MusicBand.name": "Groupe de musique", + "MusicBand.saxophone": "le saxophone", + "MusicBand.spotlight": "un projeteur", + "MusicBand.synthesizer": "une synthésiseur", + "MusicBand.tambourine": "une tambourine", + "MusicBand.xylophone": "un xylophone avec un maillet", + "Scene.description": "Scène, dans {world}, grille {numColumns} par {numRows}. {characterDescription}", + "SceneMessage.close": "fermée le message", + "TileDescription.black": "noire", + "TileDescription.brown": "brun", + "TileDescription.darkBlue": "bleu foncer", + "TileDescription.gem": "gem", + "TileDescription.gold": "gold", + "TileDescription.green": "vert", + "TileDescription.grey": "gris", + "TileDescription.lightBlue": "bleu claire", + "TileDescription.none": "gomme de fond personnalisée", + "TileDescription.orange": "orange", + "TileDescription.pink": "rose", + "TileDescription.purple": "violet", + "TileDescription.red": "rouge", + "TileDescription.treats": "friandises", + "TileDescription.wall": "mur", + "TileDescription.white": "blanc", + "TileDescription.yellow": "jaune", + "TilePanel.heading": "Conception de fond personnalisée", + "Sports.badmintonShuttlecock": "volant de badminton", + "Sports.baseballGloveAndBall": "gant de balle et baseball", + "Sports.basketball": "basketball", + "Sports.bicycle": "bicylette", + "Sports.bowlingBallAndPins": "boulles et quilles de bowling", + "Sports.boxingGloves": "gants de boxing", + "Sports.character": "voiture de golf", + "Sports.cricketBatAndBall": "batte et balle de cricket", + "Sports.curlingStone": "pierre à friser", + "Sports.fieldHockeyStickAndBall": "bâton et balle pour hockey sur gazon", + "Sports.football": "football", + "Sports.golfBall": "balle de golf", + "Sports.hockeyStickAndPuck": "bâton de hockey et rondelle", + "Sports.iceSkates": "patins de glace", + "Sports.label": "Une scène de sports avec 23 différentes pièces d'équipement sportif propagé sur la scène. Votre personnage est un voiture de golf.", + "Sports.martialArtsUniform": "uniforme arts martiaux", + "Sports.name": "sports", + "Sports.rowingBoat": "canot à rames", + "Sports.runningShoes": "chaussures de cours", + "Sports.singlet": "maillot", + "Sports.skisAndSkiPoles": "skis et bâtons de skis", + "Sports.soccerBall": "ballon de soccer", + "Sports.swimmingGoggles": "lunettes de plongée", + "Sports.tableTennisRacket": "raquette de tennis de table", + "Sports.tennisRacketAndBall": "raquette et balle de tennis", + "Sports.volleyballBall": "ballon de volleyball", + "WorldSelectorButton.heading": "Sélecteur de fond de scène", + "WorldSelectorButton.label": "Sélecteur de fond de scène" } } From 47ede16b7b1ef8f1f6e4424e480d17c838111561 Mon Sep 17 00:00:00 2001 From: Daniel Cho Date: Fri, 26 Jul 2024 16:06:24 -0400 Subject: [PATCH 02/23] fix: sort the messages file in alphabetical order --- src/messages.json | 961 +++++++++++++++++++++++----------------------- 1 file changed, 482 insertions(+), 479 deletions(-) diff --git a/src/messages.json b/src/messages.json index 8e86e981..b05d735c 100644 --- a/src/messages.json +++ b/src/messages.json @@ -28,15 +28,17 @@ "AmusementPark.merryGoRound": "merry go round", "AmusementPark.name": "Amusement Park", "AmusementPark.pirateShip": "pirate ship", + "AmusementPark.rollerCoaster": "roller coaster", "AmusementPark.snackStand": "snack stand", "AmusementPark.swingRide": "swing ride", - "AmusementPark.rollerCoaster": "roller coaster", "AmusementPark.waterPark": "water park", "AmusementPark.waterSlide": "water slide", "AmusementPark.whaleFountain": "whale fountain", "Announcement.actionSelected": "{commandType} {command} selected", - "Announcement.noActionSelected": "no action selected", "Announcement.add": "added {commandType} {command}", + "Announcement.backward1": "backward 1 square", + "Announcement.backward2": "backward 2 squares", + "Announcement.backward3": "backward 3 squares", "Announcement.cannotMoveNext": "At the end of the program, unable to move right", "Announcement.cannotMovePrevious": "At the beginning of the program, unable to move left", "Announcement.cannotReplaceLoopBlocks": "replace is not available for loops", @@ -47,20 +49,18 @@ "Announcement.forward1": "forward 1 square", "Announcement.forward2": "forward 2 squares", "Announcement.forward3": "forward 3 squares", - "Announcement.backward1": "backward 1 square", - "Announcement.backward2": "backward 2 squares", - "Announcement.backward3": "backward 3 squares", + "Announcement.left180": "turn left 180 degrees", "Announcement.left45": "turn left 45 degrees", "Announcement.left90": "turn left 90 degrees", - "Announcement.left180": "turn left 180 degrees", "Announcement.loop": "loop", - "Announcement.moveToPrevious": "moved to left", - "Announcement.moveToNext": "moved to right", "Announcement.movement": "movement", + "Announcement.moveToNext": "moved to right", + "Announcement.moveToPrevious": "moved to left", + "Announcement.noActionSelected": "no action selected", "Announcement.replace": "movement {oldCommand} replaced with {newCommand}", + "Announcement.right180": "turn right 180 degrees", "Announcement.right45": "turn right 45 degrees", "Announcement.right90": "turn right 90 degrees", - "Announcement.right180": "turn right 180 degrees", "Announcement.startLoop": "loop {loopLabel}", "App.appHeading": "Weavly", "App.appHeading.link": "Weavly, learn more about Weavly at Weavly dot org", @@ -81,12 +81,12 @@ "AtlanticCanada.land": "the land", "AtlanticCanada.lighthouse": "a light house", "AtlanticCanada.name": "Atlantic Canada", - "AtlanticCanada.trees": "trees", "AtlanticCanada.rowingBoatOnTheShore": "a rowing boat on the shore", "AtlanticCanada.sailboat": "a sailboat", "AtlanticCanada.shoal": "a shoal of fish", "AtlanticCanada.shore": "the shore", "AtlanticCanada.storms": "storms", + "AtlanticCanada.trees": "trees", "AtlanticCanada.water": "the water", "AtlanticCanada.whale": "a whale", "BluetoothApiWarning.errorIconLabel": "Warning", @@ -104,8 +104,26 @@ "CharacterAriaLive.movementAriaLabel": "{character} is moving", "CharacterDescriptionBuilder.positionAndDirection": "At {columnLabel} {rowLabel} facing {direction}", "CharacterDescriptionBuilder.positionAndDirectionAndItem": "At {columnLabel} {rowLabel} on {item} facing {direction}", - "CharacterMessageBuilder.hitWall": "Your character hit a wall on {columnLabel}{rowLabel}", "CharacterMessageBuilder.endOfScene": "Your character has reached the end of the scene", + "CharacterMessageBuilder.hitWall": "Your character hit a wall on {columnLabel}{rowLabel}", + "CharacterPositionController.editPosition.columnPosition": "Character column position", + "CharacterPositionController.editPosition.designMode.columnPosition": "Paintbrush column position", + "CharacterPositionController.editPosition.designMode.moveDown": "Move the paintbrush down", + "CharacterPositionController.editPosition.designMode.moveLeft": "Move the paintbrush left", + "CharacterPositionController.editPosition.designMode.moveRight": "Move the paintbrush right", + "CharacterPositionController.editPosition.designMode.moveUp": "Move the paintbrush up", + "CharacterPositionController.editPosition.designMode.rowPosition": "Paintbrush row position", + "CharacterPositionController.editPosition.moveDown": "Move the character down", + "CharacterPositionController.editPosition.moveLeft": "Move the character left", + "CharacterPositionController.editPosition.moveRight": "Move the character right", + "CharacterPositionController.editPosition.moveUp": "Move the character up", + "CharacterPositionController.editPosition.rowPosition": "Character row position", + "CharacterPositionController.editPosition.turnLeft": "Turn the character left", + "CharacterPositionController.editPosition.turnRight": "Turn the character right", + "CharacterPositionController.paintbrushButtonEraserSelected": "erase square", + "CharacterPositionController.paintbrushButtonNoSelection": "paint background square", + "CharacterPositionController.paintbrushButtonTileSelected": "paint {tile}", + "CharacterPositionController.setStartButton": "set the starting position", "Command.backward1": "backward 1 square", "Command.backward2": "backward 2 squares", "Command.backward3": "backward 3 squares", @@ -113,25 +131,25 @@ "Command.forward1": "forward 1 square", "Command.forward2": "forward 2 squares", "Command.forward3": "forward 3 squares", + "Command.left180": "turn left 180 degrees", "Command.left45": "turn left 45 degrees", "Command.left90": "turn left 90 degrees", - "Command.left180": "turn left 180 degrees", "Command.loop": "loop", "Command.loop.label": "loop {loopLabel}", + "Command.right180": "turn right 180 degrees", "Command.right45": "turn right 45 degrees", "Command.right90": "turn right 90 degrees", - "Command.right180": "turn right 180 degrees", "Command.startLoop": "beginning of loop {loopLabel}", - "CommandInfo.previousStep": "before step {previousStepNumber} {command}", - "CommandInfo.previousStep.endLoop": "into loop {loopLabel}", - "CommandInfo.previousStep.inLoop": "before step {previousStepNumber} {command} of loop {loopLabel}", - "CommandInfo.previousStep.loop": "before step {previousStepNumber} {command}", - "CommandInfo.previousStep.startLoop": "out of loop {loopLabel}", "CommandInfo.nextStep": "after step {nextStepNumber} {command}", "CommandInfo.nextStep.endLoop": "out of loop {loopLabel}", "CommandInfo.nextStep.inLoop": "after step {nextStepNumber} {command} of loop {loopLabel}", "CommandInfo.nextStep.loop": "after step {nextStepNumber} {command}", "CommandInfo.nextStep.startLoop": "into loop {loopLabel}", + "CommandInfo.previousStep": "before step {previousStepNumber} {command}", + "CommandInfo.previousStep.endLoop": "into loop {loopLabel}", + "CommandInfo.previousStep.inLoop": "before step {previousStepNumber} {command} of loop {loopLabel}", + "CommandInfo.previousStep.loop": "before step {previousStepNumber} {command}", + "CommandInfo.previousStep.startLoop": "out of loop {loopLabel}", "CommandPalette.controlsTitle": "Controls", "CommandPalette.movementsTitle": "Movements", "CommandPalette.shortMovementsTitle": "Move", @@ -140,24 +158,6 @@ "ConfirmDeleteAllModal.confirmButton": "Delete", "ConfirmDeleteAllModal.content": "Are you sure you want to delete all steps of your program?", "ConfirmDeleteAllModal.title": "Delete Program", - "CharacterPositionController.editPosition.turnLeft": "Turn the character left", - "CharacterPositionController.editPosition.turnRight": "Turn the character right", - "CharacterPositionController.editPosition.moveUp": "Move the character up", - "CharacterPositionController.editPosition.moveRight": "Move the character right", - "CharacterPositionController.editPosition.moveDown": "Move the character down", - "CharacterPositionController.editPosition.moveLeft": "Move the character left", - "CharacterPositionController.editPosition.columnPosition": "Character column position", - "CharacterPositionController.editPosition.rowPosition": "Character row position", - "CharacterPositionController.editPosition.designMode.moveUp": "Move the paintbrush up", - "CharacterPositionController.editPosition.designMode.moveRight": "Move the paintbrush right", - "CharacterPositionController.editPosition.designMode.moveDown": "Move the paintbrush down", - "CharacterPositionController.editPosition.designMode.moveLeft": "Move the paintbrush left", - "CharacterPositionController.editPosition.designMode.columnPosition": "Paintbrush column position", - "CharacterPositionController.editPosition.designMode.rowPosition": "Paintbrush row position", - "CharacterPositionController.paintbrushButtonEraserSelected": "erase square", - "CharacterPositionController.paintbrushButtonNoSelection": "paint background square", - "CharacterPositionController.paintbrushButtonTileSelected": "paint {tile}", - "CharacterPositionController.setStartButton": "set the starting position", "CustomBackgroundDesignModeButton.customBackgroundDesignMode": "custom background design mode", "DashConnectionErrorModal.cancelButton": "Cancel connection", "DashConnectionErrorModal.error": "Connection Error", @@ -177,9 +177,9 @@ "DeepOcean.treasure": "the treasure", "DesignModeCursorDescriptionBuilder.position": "At {columnLabel} {rowLabel}", "DesignModeCursorDescriptionBuilder.positionAndItem": "At {columnLabel} {rowLabel} on {item}", - "DeviceConnectControl.notConnected": "Not connected", - "DeviceConnectControl.connecting": "Connecting", "DeviceConnectControl.connected": "Connected", + "DeviceConnectControl.connecting": "Connecting", + "DeviceConnectControl.notConnected": "Not connected", "Direction.0": "up", "Direction.1": "upper right", "Direction.2": "right", @@ -188,75 +188,75 @@ "Direction.5": "lower left", "Direction.6": "left", "Direction.7": "upper left", + "EuropeTrip.B6": "the Tower of Saint Vincent on Portugal", + "EuropeTrip.B7": "Portugal", "EuropeTrip.C1": "Iceland", - "EuropeTrip.E1": "the United Kingdom", - "EuropeTrip.F1": "Norway", - "EuropeTrip.G1": "Norway and Sweden", - "EuropeTrip.H1": "Sweden", - "EuropeTrip.I1": "Helsinki Cathedral on Finland", - "EuropeTrip.J1": "Finland", "EuropeTrip.C2": "a whale on Iceland", - "EuropeTrip.D2": "Ireland and the United Kingdom", - "EuropeTrip.E2": "the United Kingdom", - "EuropeTrip.F2": "a longship on Norway", - "EuropeTrip.G2": "Denmark and Norway and Sweden", - "EuropeTrip.H2": "Gamla Stan on Sweden", - "EuropeTrip.I2": "Tallinn on Estonia; also in this square Finland and Latvia", "EuropeTrip.C3": "Ireland", + "EuropeTrip.C5": "Spain", + "EuropeTrip.C6": "Portugal and Spain", + "EuropeTrip.C7": "Flamenco guitar on Spain", + "EuropeTrip.character": "the airplane", + "EuropeTrip.D2": "Ireland and the United Kingdom", "EuropeTrip.D3": "a shamrock on Ireland; also in this square the United Kingdom", - "EuropeTrip.E3": "a double-decker bus on the United Kingdom", - "EuropeTrip.F3": "a windmill on the Netherlands", - "EuropeTrip.G3": "Danish pastry on Denmark; also in this square Germany and Sweden", - "EuropeTrip.H3": "Poland and Sweden", - "EuropeTrip.I3": "daisies on Latvia and Trakai Island Castle on Lithuania; also in this square Belarus", - "EuropeTrip.J3": "National Library on Belarus", "EuropeTrip.D4": "France and the United Kingdom", - "EuropeTrip.E4": "chocolate on Belgium; also in this square France and the United Kingdom", - "EuropeTrip.F4": "a pretzel on Germany; also in this square Belgium and Luxembourg and the Netherlands", - "EuropeTrip.G4": "Mill Colonnade on Czech Republic; also in this square Germany and Poland", - "EuropeTrip.H4": "Kielbasa on Poland", - "EuropeTrip.I4": "Belarus and Poland and Ukraine", - "EuropeTrip.J4": "Belarus and Ukraine", - "EuropeTrip.K4": "Ukraine", - "EuropeTrip.L4": "Ukraine", - "EuropeTrip.C5": "Spain", "EuropeTrip.D5": "France", - "EuropeTrip.E5": "Eiffel Tower on France", - "EuropeTrip.F5": "a watch on Switzerland; also in this square Austria and France and Germany", - "EuropeTrip.G5": "a violin on Austria and Bled on Slovenia; also in this square Czech Republic and Germany", - "EuropeTrip.H5": "paprika on Hungary and ceramics on Slovakia; also in this square Austria and Czech Republic and Slovenia", - "EuropeTrip.I5": "Peles Castle on Romania; also in this square Hungary and Slovakia and Ukraine", - "EuropeTrip.J5": "sunflower on Moldova; also in this square Romania and Ukraine", - "EuropeTrip.K5": "Saint Michael's Golden-Domed Monastery on Ukraine", - "EuropeTrip.L5": "Ukraine", - "EuropeTrip.B6": "the Tower of Saint Vincent on Portugal", - "EuropeTrip.C6": "Portugal and Spain", "EuropeTrip.D6": "France and Spain", - "EuropeTrip.E6": "Eiffel Tower on France", - "EuropeTrip.F6": "France and Italy", - "EuropeTrip.G6": "honey on Croatia and Bled on Slovenia; also in this square Italy", - "EuropeTrip.H6": "Sinan Pasha Mosque on Kosovo and Church of Saint Sava on Serbia and Stari Most on Bosnia and Herzegovina; also in this square Croatia and Hungary and Montenegro", - "EuropeTrip.I6": "Church of Saint Sava on Serbia; also in this square Bulgaria and Romania", - "EuropeTrip.J6": "Bulgaria and Moldova and Romania", - "EuropeTrip.K6": "Ukraine", - "EuropeTrip.B7": "Portugal", - "EuropeTrip.C7": "Flamenco guitar on Spain", "EuropeTrip.D7": "Spain", + "EuropeTrip.E1": "the United Kingdom", + "EuropeTrip.E2": "the United Kingdom", + "EuropeTrip.E3": "a double-decker bus on the United Kingdom", + "EuropeTrip.E4": "chocolate on Belgium; also in this square France and the United Kingdom", + "EuropeTrip.E5": "Eiffel Tower on France", + "EuropeTrip.E6": "Eiffel Tower on France", "EuropeTrip.E7": "Spain", + "EuropeTrip.F1": "Norway", + "EuropeTrip.F2": "a longship on Norway", + "EuropeTrip.F3": "a windmill on the Netherlands", + "EuropeTrip.F4": "a pretzel on Germany; also in this square Belgium and Luxembourg and the Netherlands", + "EuropeTrip.F5": "a watch on Switzerland; also in this square Austria and France and Germany", + "EuropeTrip.F6": "France and Italy", "EuropeTrip.F7": "France and Italy", + "EuropeTrip.G1": "Norway and Sweden", + "EuropeTrip.G2": "Denmark and Norway and Sweden", + "EuropeTrip.G3": "Danish pastry on Denmark; also in this square Germany and Sweden", + "EuropeTrip.G4": "Mill Colonnade on Czech Republic; also in this square Germany and Poland", + "EuropeTrip.G5": "a violin on Austria and Bled on Slovenia; also in this square Czech Republic and Germany", + "EuropeTrip.G6": "honey on Croatia and Bled on Slovenia; also in this square Italy", "EuropeTrip.G7": "pizza on Italy", - "EuropeTrip.H7": "a shargia on Albania and Sinan Pasha Mosque on Kosovo and a yacht on Montenegro; also in this square North Macedonia", - "EuropeTrip.I7": "Rose Valley on Bulgaria and Millennium Cross on North Macedonia; also in this square Greece and Kosovo", - "EuropeTrip.J7": "Bulgaria and Türkiye", - "EuropeTrip.K7": "coffee on Türkiye", - "EuropeTrip.L7": "Türkiye", "EuropeTrip.G8": "Italy", + "EuropeTrip.H1": "Sweden", + "EuropeTrip.H2": "Gamla Stan on Sweden", + "EuropeTrip.H3": "Poland and Sweden", + "EuropeTrip.H4": "Kielbasa on Poland", + "EuropeTrip.H5": "paprika on Hungary and ceramics on Slovakia; also in this square Austria and Czech Republic and Slovenia", + "EuropeTrip.H6": "Sinan Pasha Mosque on Kosovo and Church of Saint Sava on Serbia and Stari Most on Bosnia and Herzegovina; also in this square Croatia and Hungary and Montenegro", + "EuropeTrip.H7": "a shargia on Albania and Sinan Pasha Mosque on Kosovo and a yacht on Montenegro; also in this square North Macedonia", "EuropeTrip.H8": "Greece and Italy", + "EuropeTrip.I1": "Helsinki Cathedral on Finland", + "EuropeTrip.I2": "Tallinn on Estonia; also in this square Finland and Latvia", + "EuropeTrip.I3": "daisies on Latvia and Trakai Island Castle on Lithuania; also in this square Belarus", + "EuropeTrip.I4": "Belarus and Poland and Ukraine", + "EuropeTrip.I5": "Peles Castle on Romania; also in this square Hungary and Slovakia and Ukraine", + "EuropeTrip.I6": "Church of Saint Sava on Serbia; also in this square Bulgaria and Romania", + "EuropeTrip.I7": "Rose Valley on Bulgaria and Millennium Cross on North Macedonia; also in this square Greece and Kosovo", "EuropeTrip.I8": "the Parthenon on Greece", + "EuropeTrip.J1": "Finland", + "EuropeTrip.J3": "National Library on Belarus", + "EuropeTrip.J4": "Belarus and Ukraine", + "EuropeTrip.J5": "sunflower on Moldova; also in this square Romania and Ukraine", + "EuropeTrip.J6": "Bulgaria and Moldova and Romania", + "EuropeTrip.J7": "Bulgaria and Türkiye", "EuropeTrip.J8": "Greece and Türkiye", + "EuropeTrip.K4": "Ukraine", + "EuropeTrip.K5": "Saint Michael's Golden-Domed Monastery on Ukraine", + "EuropeTrip.K6": "Ukraine", + "EuropeTrip.K7": "coffee on Türkiye", "EuropeTrip.K8": "olives on Cyprus; also in this square Türkiye", + "EuropeTrip.L4": "Ukraine", + "EuropeTrip.L5": "Ukraine", + "EuropeTrip.L7": "Türkiye", "EuropeTrip.L8": "olives on Cyprus; also in this square Türkiye", - "EuropeTrip.character": "the airplane", "EuropeTrip.label": "A Europe trip scene containing a map of Europe with tourist attractions. Iceland is located near the top left of the scene. Cyprus is located at the bottom right of the scene. Tourist attractions are located on the country known for the attraction, such as the violin on Austria near the centre of the scene. Your character in this scene is an airplane.", "EuropeTrip.name": "Europe Trip", "GroceryStore.apples": "apples", @@ -302,7 +302,7 @@ "Haunted.deerSkull": "the deer skull", "Haunted.fireplace": "the fireplace", "Haunted.label": "A spooky mansion scene. The front hall has a large staircase starting at the bottom right and going to the top left. Haunted paintings, a mirror, and a creepy deer skull hang on the wall. Bats are flying around. A fire burns in the fireplace below the stairwell. A big comfy chair is in front of the fire. The shelves of a large bookshelf on the left of the scene is stacked with books, potions and plants. Your character in this scene is a flashlight.", - "Haunted.mirror": "the mirror", + "une scène de manoir effrayante, le hall de entrée a un grand escalier commançant en bas à droite et allant en haut à gauche. Des paintures hauntées un mirroir et une crâne de cerf effrayant sont affichées au murs. Les chauves souris volent. Un feu brûle dans la cheminée soous la cage d'escaliers. Une grand chaise confortable est devant le feu. Les étagers d'une grande bibliothèque à gauche de la scène sont remplis de livres, de potions et de plantes. Votre personnage dans se scène est une main tenant une bougie.Haunted.mirror": "the mirror", "Haunted.name": "Haunted House", "Haunted.painting": "a painting", "Haunted.shelf": "the bookshelf", @@ -311,44 +311,44 @@ "KeyboardInputModal.Description.addCommandToBeginning": "Press {key} to add the selected command to the beginning of the program.", "KeyboardInputModal.Description.addCommandToEnd": "Press {key} to add the selected command to the end of the program.", "KeyboardInputModal.Description.announceScene": "Press {key} to announce the character position and orientation.", - "KeyboardInputModal.Description.deleteCurrentStep": "Press {key} to delete the currently focused step.", "KeyboardInputModal.Description.decreaseProgramSpeed": "Press {key} to make the program play slower.", + "KeyboardInputModal.Description.deleteCurrentStep": "Press {key} to delete the currently focused step.", "KeyboardInputModal.Description.increaseProgramSpeed": "Press {key} to make the program play faster.", "KeyboardInputModal.Description.playPauseProgram": "Press {key} to play or pause the program.", "KeyboardInputModal.Description.refreshScene": "Press {key} to refresh the scene.", "KeyboardInputModal.Description.showHide": "Press {key} to show the keyboard shortcuts menu.", "KeyboardInputModal.Description.stopProgram": "Press {key} to stop the program.", "KeyboardInputModal.Description.toggleAnnouncements": "Press {key} to toggle announcements.", - "KeyboardInputModal.KeyLabels.Alt": "Alt", - "KeyboardInputModal.KeyLabels.Control": "Control", - "KeyboardInputModal.KeyLabels.QuestionMark": "question mark", - "KeyboardInputModal.KeyLabels.GreaterThan": "greater than", - "KeyboardInputModal.KeyLabels.LessThan": "less than", - "KeyboardInputModal.KeyLabels.A": "a", - "KeyboardInputModal.KeyLabels.B": "b", - "KeyboardInputModal.KeyLabels.D": "d", - "KeyboardInputModal.KeyLabels.E": "e", - "KeyboardInputModal.KeyLabels.I": "i", - "KeyboardInputModal.KeyLabels.P": "p", - "KeyboardInputModal.KeyLabels.S": "s", - "KeyboardInputModal.KeyLabels.R": "r", - "KeyboardInputModal.KeyIcons.Alt": "Alt", - "KeyboardInputModal.KeyIcons.Control": "Ctrl", - "KeyboardInputModal.KeyIcons.Shift": "Shift", - "KeyboardInputModal.KeyIcons.QuestionMark": "?", - "KeyboardInputModal.KeyIcons.GreaterThan": ">", - "KeyboardInputModal.KeyIcons.LessThan": "<", "KeyboardInputModal.KeyIcons.A": "A", + "KeyboardInputModal.KeyIcons.Alt": "Alt", "KeyboardInputModal.KeyIcons.B": "B", + "KeyboardInputModal.KeyIcons.Control": "Ctrl", "KeyboardInputModal.KeyIcons.D": "D", "KeyboardInputModal.KeyIcons.E": "E", + "KeyboardInputModal.KeyIcons.GreaterThan": ">", "KeyboardInputModal.KeyIcons.I": "I", + "KeyboardInputModal.KeyIcons.LessThan": "<", "KeyboardInputModal.KeyIcons.P": "P", - "KeyboardInputModal.KeyIcons.S": "S", + "KeyboardInputModal.KeyIcons.QuestionMark": "?", "KeyboardInputModal.KeyIcons.R": "R", + "KeyboardInputModal.KeyIcons.S": "S", + "KeyboardInputModal.KeyIcons.Shift": "Shift", + "KeyboardInputModal.KeyLabels.A": "a", + "KeyboardInputModal.KeyLabels.Alt": "Alt", + "KeyboardInputModal.KeyLabels.B": "b", + "KeyboardInputModal.KeyLabels.Control": "Control", + "KeyboardInputModal.KeyLabels.D": "d", + "KeyboardInputModal.KeyLabels.E": "e", + "KeyboardInputModal.KeyLabels.GreaterThan": "greater than", + "KeyboardInputModal.KeyLabels.I": "i", + "KeyboardInputModal.KeyLabels.LessThan": "less than", + "KeyboardInputModal.KeyLabels.P": "p", + "KeyboardInputModal.KeyLabels.QuestionMark": "question mark", + "KeyboardInputModal.KeyLabels.R": "r", + "KeyboardInputModal.KeyLabels.S": "s", "KeyboardInputModal.Save": "Save", - "KeyboardInputModal.Scheme.Descriptions.controlalt": "Control+Alt (Apple: Control+Option)", "KeyboardInputModal.Scheme.Descriptions.alt": "Alt (Apple: Option)", + "KeyboardInputModal.Scheme.Descriptions.controlalt": "Control+Alt (Apple: Control+Option)", "KeyboardInputModal.ShowHide.AriaLabel": "Display keyboard shortcuts menu", "KeyboardInputModal.Title": "Keyboard Shortcuts", "KeyboardInputModal.Toggle.AriaLabel": "Keyboard shortcuts toggle", @@ -375,8 +375,8 @@ "Landmarks.niagaraFalls": "Niagara Falls", "Landmarks.operaHouse": "The Sydney Opera House", "Landmarks.plane": "a plane", - "Landmarks.stBasils": "Saint Basil's Cathedral", "Landmarks.statueLiberty": "The Statue of Liberty", + "Landmarks.stBasils": "Saint Basil's Cathedral", "Landmarks.stonehenge": "Stonehenge", "Landmarks.tableMountain": "Table Mountain", "Landmarks.tajMahal": "The Taj Mahal Palace", @@ -400,46 +400,49 @@ "MusicBand.tambourine": "the tambourine", "MusicBand.xylophone": "the xylophone with mallet", "PenDownToggleSwitch.penDown": "Pen down", - "PlayButton.play": "Play", "PlayButton.pause": "Pause", + "PlayButton.play": "Play", "PlayControls.heading": "Play Controls", "PrivacyModal.close": "Close", "PrivacyModal.title": "Weavly Privacy Policy", - "ProgramBlockEditor.toggleAddNodeExpandMode": "add node expanded mode", "ProgramBlockEditor.beginningBlock": "Add selected action {command} to the beginning of the program", "ProgramBlockEditor.betweenBlocks": "Add selected action {command} between position {prevCommand} and position {postCommand}", - "ProgramBlockEditor.lastBlock": "Add selected action {command} to the end of the program", "ProgramBlockEditor.blocks.noCommandSelected": "Make sure an action is selected", "ProgramBlockEditor.command": "{command}, position {index} of current program", + "ProgramBlockEditor.lastBlock": "Add selected action {command} to the end of the program", "ProgramBlockEditor.nestedCommand": "{command}, position {index} of Loop {parentLoopLabel}", "ProgramBlockEditor.program.deleteAll": "Delete all steps of your program", "ProgramBlockEditor.programHeading": "Program", - "ProgramTextEditor.programLabel": "Program:", + "ProgramBlockEditor.toggleAddNodeExpandMode": "add node expanded mode", "ProgramSequence.heading": "Program Sequence", "ProgramSpeedController.slider": "Program play speed", - "Savannah.alligator": "the Alligator", - "Savannah.babyAlligator": "the Baby Alligator", - "Savannah.babyGiraffe": "the Baby Giraffe", - "Savannah.bush": "a Bush", - "Savannah.character": "the jeep", - "Savannah.flamingo": "the Flamingo", - "Savannah.giraffe": "the Giraffe", - "Savannah.hippo": "the Hippo", - "Savannah.label": "A savannah scene. A lion roars at the top of a cliff above the horizon. A mother and baby giraffe roam the savannah. Two crocodiles, a flamingo and a hippopotamus drink water from a pond surrounded by trees. Your character in this scene is a Jeep.", - "Savannah.lion": "the Lion", + "ProgramTextEditor.programLabel": "Program:", + "RefreshButton": "Refresh", + "savannah.alligator": "the Alligator", + "savannah.babyAlligator": "the Baby Alligator", + "savannah.babyGiraffe": "the Baby Giraffe", + "savannah.bush": "a Bush", + "savannah.character": "the jeep", + "savannah.flamingo": "the Flamingo", + "savannah.giraffe": "the Giraffe", + "savannah.hippo": "the Hippo", + "savannah.label": "A savannah scene. A lion roars at the top of a cliff above the horizon. A mother and baby giraffe roam the savannah. Two crocodiles, a flamingo and a hippopotamus drink water from a pond surrounded by trees. Your character in this scene is a Jeep.", + "savannah.lion": "the Lion", "Savannah.name": "Savannah", - "Savannah.pond": "the Pond", - "Savannah.tree": "a Tree", - "Scene.heading": "Scene", + "savannah.pond": "the Pond", + "savannah.tree": "a Tree", "Scene.description": "Scene, in {world}, {numColumns} by {numRows} grid. {characterDescription}", + "Scene.heading": "Scene", "SceneMessage.close": "close message", + "ShareButton": "Share", "ShareModal.close": "Close", "ShareModal.copy": "Copy link", - "ShareModal.title": "Share Link", "ShareModal.description1": "A link to the program you created was copied to the clipboard.", "ShareModal.description2": "You can also copy the link below to share it with anyone you like.", + "ShareModal.title": "Share Link", "Sketchpad.character": "the robot", "Sketchpad.label": "A blank sketchbook with grid lines. Your character in this scene is a Robot.", + "Sketchpad.name": "Sketchpad", "SoundOptionsModal.allSounds": "All Sounds", "SoundOptionsModal.announcements": "Audio Announcements", "SoundOptionsModal.cancelButton": "Cancel", @@ -448,37 +451,6 @@ "SoundOptionsModal.title": "Sound Options", "SoundOptionsModal.toggleOff": "Off", "SoundOptionsModal.toggleOn": "On", - "Sketchpad.name": "Sketchpad", - "StopButton": "Stop", - "ThemeSelector.cancelButton": "Cancel", - "ThemeSelector.saveButton": "Save", - "ThemeSelector.iconButton": "Theme Selector", - "ThemeSelector.option.default": "Default", - "ThemeSelector.option.light": "Light", - "ThemeSelector.option.dark": "Dark", - "ThemeSelector.option.gray": "Grayscale", - "ThemeSelector.option.contrast": "High Contrast", - "ThemeSelector.title": "Themes", - "TileDescription.black": "black", - "TileDescription.brown": "brown", - "TileDescription.darkBlue": "dark blue", - "TileDescription.gem": "gem", - "TileDescription.gold": "gold", - "TileDescription.green": "green", - "TileDescription.grey": "grey", - "TileDescription.lightBlue": "light blue", - "TileDescription.none": "custom background eraser", - "TileDescription.orange": "orange", - "TileDescription.pink": "pink", - "TileDescription.purple": "purple", - "TileDescription.red": "red", - "TileDescription.treats": "treats", - "TileDescription.wall": "wall", - "TileDescription.white": "white", - "TileDescription.yellow": "yellow", - "TilePanel.heading": "Custom Background Design", - "RefreshButton": "Refresh", - "ShareButton": "Share", "Space.aliens": "the Aliens", "Space.asteroid": "an asteroid", "Space.character": "the spaceship", @@ -517,12 +489,40 @@ "Sports.tableTennisRacket": "table tennis racket", "Sports.tennisRacketAndBall": "tennis racket and ball", "Sports.volleyballBall": "volleyball ball", - "WorldSelectorButton.heading": "Scene Background selector", - "WorldSelectorButton.label": "Scene Background selector", + "StopButton": "Stop", + "ThemeSelector.cancelButton": "Cancel", + "ThemeSelector.iconButton": "Theme Selector", + "ThemeSelector.option.contrast": "High Contrast", + "ThemeSelector.option.dark": "Dark", + "ThemeSelector.option.default": "Default", + "ThemeSelector.option.gray": "Grayscale", + "ThemeSelector.option.light": "Light", + "ThemeSelector.saveButton": "Save", + "ThemeSelector.title": "Themes", + "TileDescription.black": "black", + "TileDescription.brown": "brown", + "TileDescription.darkBlue": "dark blue", + "TileDescription.gem": "gem", + "TileDescription.gold": "gold", + "TileDescription.green": "green", + "TileDescription.grey": "grey", + "TileDescription.lightBlue": "light blue", + "TileDescription.none": "custom background eraser", + "TileDescription.orange": "orange", + "TileDescription.pink": "pink", + "TileDescription.purple": "purple", + "TileDescription.red": "red", + "TileDescription.treats": "treats", + "TileDescription.wall": "wall", + "TileDescription.white": "white", + "TileDescription.yellow": "yellow", + "TilePanel.heading": "Custom Background Design", "WorldSelector.Cancel": "Cancel", - "WorldSelector.Save": "Save", "WorldSelector.Prompt": "Select a background for your scene.", - "WorldSelector.Title": "Scene Background" + "WorldSelector.Save": "Save", + "WorldSelector.Title": "Scene Background", + "WorldSelectorButton.heading": "Scene Background selector", + "WorldSelectorButton.label": "Scene Background selector" }, "fr": { "ActionPanel.action.delete": "supprimer {stepNumber} {stepName}", @@ -544,9 +544,29 @@ "ActionsSimplificationModal.cancel": "annuler", "ActionsSimplificationModal.save": "sauvegarder", "ActionsSimplificationModal.title": "actions disponibles", + "AmusementPark.character": "the train", + "AmusementPark.entrance": "entrée", + "AmusementPark.ferrisWheel": "grande roue", + "AmusementPark.gameBooth": "stand de jeu", + "AmusementPark.goKarts": "karts", + "AmusementPark.label": "Une scène de parc d'attractions. Une scène avec vos attractions préférées: des montagnes rousses, un grand roue, un bateau pirate, des karts, une blançoir, et un manège. Il y a d'autres choses amusantes à faire, comme un stand de jeux, et une parc aquatique, et si vous voulez des collations, il y a une stand de collations. Votre personnage est un ticket.", + "AmusementPark.merryGoRound": "manège", + "AmusementPark.name": "parc d'attractions", + "AmusementPark.pirateShip": "navire pirate", + "AmusementPark.rollerCoaster": "montagnes rousses", + "AmusementPark.snackStand": "stand de collations", + "AmusementPark.swingRide": "tour de balançoire", + "AmusementPark.waterPark": "parc aquatique", + "AmusementPark.waterSlide": "glissade d'eau", + "AmusementPark.whaleFountain": "fontaine des baleines", "Announcement.actionSelected": "{commandType} {command} sélectionnée", - "Announcement.noActionSelected": "aucune action sélectionnée", "Announcement.add": "{commandType} ajouté {command}", + "Announcement.backward1": "reculer d'1 case", + "Announcement.backward2": "reculer 2 cases", + "Announcement.backward3": "reculer 3 cases", + "Announcement.cannotMoveNext": "à la fin du programme, incapable de se déplacer vers la droite", + "Announcement.cannotMovePrevious": "au début du programme, incapable de se déplacer vers la gauche", + "Announcement.cannotReplaceLoopBlocks": "remplacer n'est pas disponible pour les boucles", "Announcement.control": "controle", "Announcement.delete": "suprimé {commandType} {command}", "Announcement.deleteAll": "suprimmer le programme", @@ -554,20 +574,18 @@ "Announcement.forward1": "avance 1 case", "Announcement.forward2": "avance 2 cases", "Announcement.forward3": "avance 3 cases", - "Announcement.backward1": "reculer d'1 case", - "Announcement.backward2": "reculer 2 cases", - "Announcement.backward3": "reculer 3 cases", + "Announcement.left180": "turner à gauche de 180 degréees", "Announcement.left45": "tourner à gauche de 45 degrées", "Announcement.left90": "tourner a gauche de 90 degréees", - "Announcement.left180": "turner à gauche de 180 degréees", "Announcement.loop": "boucle", - "Announcement.moveToPrevious": "déplacer vers la gauche", - "Announcement.moveToNext": "déplacer vers la droite", "Announcement.movement": "mouvement ", + "Announcement.moveToNext": "déplacer vers la droite", + "Announcement.moveToPrevious": "déplacer vers la gauche", + "Announcement.noActionSelected": "aucune action sélectionnée", "Announcement.replace": "mouvement {oldCommand} remplacer par une {newCommand}", + "Announcement.right180": "turner a droite 180 degrées", "Announcement.right45": "tourner a droite 45 degrées", "Announcement.right90": "tourner a droite 90 degrées", - "Announcement.right180": "turner a droite 180 degrées", "Announcement.startLoop": "boucle {loopLabel}", "App.appHeading": "Weavly", "App.appHeading.link": "Weavly, en savoir plus sur Weavly a Weavly point org", @@ -579,11 +597,28 @@ "App.run": "Lancer", "App.speechRecognition": "reconnaisance de la parole", "App.textMode": "Texte", + "AtlanticCanada.character": "Insulaire de Cap", + "AtlanticCanada.fishProcessingPlant": "usine de transformation des poissons", + "AtlanticCanada.fogBank": "banc de brouillard", + "AtlanticCanada.house": "une maison", + "AtlanticCanada.iceberg": "in iceberg", + "AtlanticCanada.label": "Scène de voyage Atlantique. Voyagez au Canada atlntique à travers l'océan Atlantique. La météo est imprévisable dans l'océan , certaines parties de l'océan peuvent être orageuses et certaines parties de l'océan peuvent être couverte de brouillard. Voyagez en toute sécurité pour visiter une usine de transformation du poisson et une village terrestre; vous pourriez rencontrer des icebergs ou des baleine sur votre chemin. Votre personnage dans cette scène est un bateau de pêche, également connu sous le nom Cape Islander dans le Canada Atlantique.", + "AtlanticCanada.land": "la terre", + "AtlanticCanada.lighthouse": "la phare", + "AtlanticCanada.name": "atlantique Canada", + "AtlanticCanada.rowingBoatOnTheShore": "un bateau à rames sur le rivage", + "AtlanticCanada.sailboat": "un bateau a voile", + "AtlanticCanada.shoal": "un banc de poissons", + "AtlanticCanada.shore": "la rive", + "AtlanticCanada.storms": "tempêtes", + "AtlanticCanada.trees": "arbres", + "AtlanticCanada.water": "l'eau", + "AtlanticCanada.whale": "une baleine", "BluetoothApiWarning.errorIconLabel": "advertissent", "BluetoothApiWarning.message": "la connection du robot dash fonctionne seulement en Chrome", "Camping.bear": "l`ours noire", "Camping.branch": "branche d'arbre", - "Camping.character": "écureuil", + "Camping.character": "the squirrel", "Camping.fire": "le feu de camp", "Camping.label": "une scène de camping. un ours noir atteint un tronc d'arbre sûre le côté gauche de la scène. une branche 'arbre traverse le haut des la scène et une échelle de corde y est suspendu. il y a une tente ouvert sur le côté droit de la scène. un lac et un feu de camp sont au milieu de la scène. votre personnage dans cette scène est une écureuil.", "Camping.ladder": "une échelle de corde", @@ -592,6 +627,28 @@ "Camping.tentdoor": "la porte de la tente", "Camping.trunk": "le tronc d\u0000'arbre ", "CharacterAriaLive.movementAriaLabel": "Le {character} bouge", + "CharacterDescriptionBuilder.positionAndDirection": "À {columnLabel} {rowLabel} face à {direction}", + "CharacterDescriptionBuilder.positionAndDirectionAndItem": "À {column Label} {rowLabel} sur {item} orienté vers {direction}", + "CharacterMessageBuilder.endOfScene": "Votre personnage à atteint la fin de la scène", + "CharacterMessageBuilder.hitWall": "ton personnage a heurté un mur {columnLabel} {rowLabel}", + "CharacterPositionController.editPosition.columnPosition": "position de la colonne des charactères", + "CharacterPositionController.editPosition.designMode.columnPosition": "position de la colonne du pinceau", + "CharacterPositionController.editPosition.designMode.moveDown": "déplacer le pinceau vers le bas", + "CharacterPositionController.editPosition.designMode.moveLeft": "déplacer le pinceau vers la gauche", + "CharacterPositionController.editPosition.designMode.moveRight": "déplacer le pinceau vers la droite", + "CharacterPositionController.editPosition.designMode.moveUp": "déplacer le pinceau vers le haut", + "CharacterPositionController.editPosition.designMode.rowPosition": "position de rang du pinceau", + "CharacterPositionController.editPosition.moveDown": "déplacer le personnage vers le bas", + "CharacterPositionController.editPosition.moveLeft": "déplacer le personnage vers la gauche", + "CharacterPositionController.editPosition.moveRight": "déplacer le personnage vers la droite", + "CharacterPositionController.editPosition.moveUp": "déplacer le personnage vers le haut", + "CharacterPositionController.editPosition.rowPosition": "position de la ranger des charactères", + "CharacterPositionController.editPosition.turnLeft": "turne le charactère a la gauche", + "CharacterPositionController.editPosition.turnRight": "turne le charactère a la droite", + "CharacterPositionController.paintbrushButtonEraserSelected": "effacer le carré", + "CharacterPositionController.paintbrushButtonNoSelection": "peindre un carré de fond", + "CharacterPositionController.paintbrushButtonTileSelected": "peinture {tile}", + "CharacterPositionController.setStartButton": "définir la position de départ", "Command.backward1": "à l'envers 1 carré", "Command.backward2": "a l'envers 2 carrées", "Command.backward3": "à l'envers 3 carrées", @@ -599,25 +656,25 @@ "Command.forward1": "avancer d'une case", "Command.forward2": "avancer de 2 cases", "Command.forward3": "avancer de 3 cases", + "Command.left180": "tourner à gauche 180 degréees", "Command.left45": "tourner à gauche 45 degrées", "Command.left90": "tourner à gauche 90 degrées", - "Command.left180": "tourner à gauche 180 degréees", "Command.loop": "boucle", "Command.loop.label": "{loopLabel} de boucle", + "Command.right180": "tourner à droite 180 degréees", "Command.right45": "tourner à droite 45 degrées", "Command.right90": "tourner à droite 90 degrees", - "Command.right180": "tourner à droite 180 degréees", "Command.startLoop": "début de boucle {loopLabel}", - "CommandInfo.previousStep": "avant l'étape {previousStepNumber} {command}", - "CommandInfo.previousStep.endLoop": "dans la boucle {loopLabel}", - "CommandInfo.previousStep.inLoop": "avant l'étape {previousStepNumber} {command} de la boucle {loopLabel}", - "CommandInfo.previousStep.loop": "avant l'étape {previousStepNumber} {command}", - "CommandInfo.previousStep.startLoop": "hors boucle {loopLabel}", "CommandInfo.nextStep": "après l'étape {next step number} {command}", "CommandInfo.nextStep.endLoop": "hors boucle {loopLabel}", "CommandInfo.nextStep.inLoop": "après l'étape {next step number} {command} de la boucle {loopLabel}", "CommandInfo.nextStep.loop": "après l'étape {next step number} {command}", "CommandInfo.nextStep.startLoop": "en boucle {loopLabel}", + "CommandInfo.previousStep": "avant l'étape {previousStepNumber} {command}", + "CommandInfo.previousStep.endLoop": "dans la boucle {loopLabel}", + "CommandInfo.previousStep.inLoop": "avant l'étape {previousStepNumber} {command} de la boucle {loopLabel}", + "CommandInfo.previousStep.loop": "avant l'étape {previousStepNumber} {command}", + "CommandInfo.previousStep.startLoop": "hors boucle {loopLabel}", "CommandPalette.controlsTitle": "contrôles", "CommandPalette.movementsTitle": "Mouvements", "CommandPalette.shortMovementsTitle": "bouge", @@ -626,14 +683,7 @@ "ConfirmDeleteAllModal.confirmButton": "supprimer", "ConfirmDeleteAllModal.content": "êtes-vous sûr de voulair suprimer tous les étapes de ton programme?", "ConfirmDeleteAllModal.title": "supprimer le programme", - "CharacterPositionController.editPosition.turnLeft": "turne le charactère a la gauche", - "CharacterPositionController.editPosition.turnRight": "turne le charactère a la droite", - "CharacterPositionController.editPosition.moveUp": "déplacer le personnage vers le haut", - "CharacterPositionController.editPosition.moveRight": "déplacer le personnage vers la droite", - "CharacterPositionController.editPosition.moveDown": "déplacer le personnage vers le bas", - "CharacterPositionController.editPosition.moveLeft": "déplacer le personnage vers la gauche", - "CharacterPositionController.editPosition.columnPosition": "position de la colonne des charactères", - "CharacterPositionController.editPosition.rowPosition": "position de la ranger des charactères", + "CustomBackgroundDesignModeButton.customBackgroundDesignMode": "mode de conception arrière plan personnalisé", "DashConnectionErrorModal.cancelButton": "anuler la connextion", "DashConnectionErrorModal.error": "erreur de connextion", "DashConnectionErrorModal.firstMessage": "assurez vous que le bluetooth de votre appareil est désactiver", @@ -650,9 +700,11 @@ "DeepOcean.name": "Océan profond", "DeepOcean.shark": "le renard", "DeepOcean.treasure": "the trésore", - "DeviceConnectControl.notConnected": "Pas connecté", - "DeviceConnectControl.connecting": "Connexion en cours", + "DesignModeCursorDescriptionBuilder.position": "à {columnLabel} {rowLabel} ", + "DesignModeCursorDescriptionBuilder.positionAndItem": "À {columnLabel} {rowLabel} sur {item}", "DeviceConnectControl.connected": "Connecté", + "DeviceConnectControl.connecting": "Connexion en cours", + "DeviceConnectControl.notConnected": "Pas connecté", "Direction.0": "haut", "Direction.1": "en haut à droite", "Direction.2": "droite", @@ -661,290 +713,75 @@ "Direction.5": "en bas à gauche", "Direction.6": "gauche", "Direction.7": "en haut à gauce", - "Savannah.alligator": "L'alligator", - "Savannah.babyAlligator": "le bébé alligator", - "Savannah.babyGiraffe": "le bébé giraffe", - "Savannah.bush": "une buisson", - "Savannah.character": "le jeep", - "Savannah.flamingo": "le flamant rose", - "Savannah.giraffe": "le giraffe", - "Savannah.hippo": "l'hippopotame", - "Savannah.label": "Une scène de Savane. Un lion rugit au sommet d'une falaise au-dessous de l'horizon. Une mère et son bébé giraffe parcourent la savane. Deux, crocodiles, un flamant rose et un hippopotame boivent de l'eau d'un étang entourné d'arbres. Votre personnage dans cette scène est un Jeep", - "Savannah.lion": "le lion", - "Savannah.name": "Jungle", - "Savannah.pond": "l'étang", - "Savannah.tree": "l'arbre", - "KeyboardInputModal.Cancel": "annuler", - "KeyboardInputModal.Description.addCommandToBeginning": "appuyer sur la {key} pour ajouter la commande sélectionnée au début du programme", - "KeyboardInputModal.Description.addCommandToEnd": "appuyer sur la {key} pour ajouter la commande sélectionnée à la fin du programme", - "KeyboardInputModal.Description.announceScene": "appuyer sur la {key} pour annoncer la position du charactère et l'orientation", - "KeyboardInputModal.Description.deleteCurrentStep": "appuyer sur la {key} pour surpimer l'étape actuellement ciblée", - "KeyboardInputModal.Description.decreaseProgramSpeed": "appuyer sur la {key} pour ralentir la lecture du programme", - "KeyboardInputModal.Description.increaseProgramSpeed": "appuyer sur la {key} pour accélérer la lecture du programme", - "KeyboardInputModal.Description.playPauseProgram": "appuyer sur la {key} pour lire ou mettre en pause le programme", - "KeyboardInputModal.Description.refreshScene": "appuyer sur la {key} pour réfraîchir la scène", - "KeyboardInputModal.Description.showHide": "appuyer sur la {key} pour voir le menu racourci de l'ordinateur", - "KeyboardInputModal.Description.stopProgram": "appuyer sur la {key} pour arrêter le programme", - "KeyboardInputModal.Description.toggleAnnouncements": "appuyer sur la {key} pour basculer les annonces", - "KeyboardInputModal.KeyLabels.Alt": "alt", - "KeyboardInputModal.KeyLabels.Control": "contôle", - "KeyboardInputModal.KeyLabels.QuestionMark": "point d'interrogation", - "KeyboardInputModal.KeyLabels.GreaterThan": "plus grand que", - "KeyboardInputModal.KeyLabels.LessThan": "plus petit que", - "KeyboardInputModal.KeyLabels.A": "a", - "KeyboardInputModal.KeyLabels.B": "b", - "KeyboardInputModal.KeyLabels.D": "d", - "KeyboardInputModal.KeyLabels.E": "e", - "KeyboardInputModal.KeyLabels.I": "i", - "KeyboardInputModal.KeyLabels.P": "p", - "KeyboardInputModal.KeyLabels.S": "s", - "KeyboardInputModal.KeyLabels.R": "r", - "KeyboardInputModal.KeyIcons.Alt": "alt", - "KeyboardInputModal.KeyIcons.Control": "ctrl", - "KeyboardInputModal.KeyIcons.Shift": "déclage", - "KeyboardInputModal.KeyIcons.QuestionMark": "?", - "KeyboardInputModal.KeyIcons.GreaterThan": ">", - "KeyboardInputModal.KeyIcons.LessThan": "<", - "KeyboardInputModal.KeyIcons.A": "A", - "KeyboardInputModal.KeyIcons.B": "B", - "KeyboardInputModal.KeyIcons.D": "D", - "KeyboardInputModal.KeyIcons.E": "E", - "KeyboardInputModal.KeyIcons.I": "I", - "KeyboardInputModal.KeyIcons.P": "P", - "KeyboardInputModal.KeyIcons.S": "S", - "KeyboardInputModal.KeyIcons.R": "R", - "KeyboardInputModal.Save": "sauvegarder ", - "KeyboardInputModal.Scheme.Descriptions.controlalt": "contrôle+alt (apple: contrôle+option)", - "KeyboardInputModal.Scheme.Descriptions.alt": "alt (apple: option)", - "KeyboardInputModal.ShowHide.AriaLabel": "afficher le menu des raccourcis claviers", - "KeyboardInputModal.Title": "raccourcis clavier", - "KeyboardInputModal.Toggle.AriaLabel": "basculer les raccourcis claviers", - "KeyboardInputModal.Toggle.Label": "keyboard shortcuts", - "KeyboardInputModal.Toggle.Off": "à l'arrête", - "KeyboardInputModal.Toggle.On": "sur", - "Landmarks.bigBen": "Tour Big Ben", - "Landmarks.burAlArab": "Le bâtiment Burj al Arab", - "Landmarks.character": "robot", - "Landmarks.cnTower": "La tour CN", - "Landmarks.colosseum": "Le Colossuem", - "Landmarks.easterIsland": "les statues de l'île de pacques", - "Landmarks.eiffelTower": "La Tour Eiffel", - "Landmarks.fairyChimneys": "cheminées de fées", - "Landmarks.floatingMarket": "le marché flottant de Vietnam", - "Landmarks.grandCanyon": "Le grand Canyon", - "Landmarks.greatPyramid": "la grande pyramide de Gizeh", - "Landmarks.greatSphinx": "la grande sphinx de Gizeh", - "Landmarks.greatWall": "La grande muraille de Chine", - "Landmarks.label": "Une grande scène mondiale qui contient 23 monuments célèbres trouver dans le monde. Un avion vole depuis le point supérieur gauche. Un train part du point supérieur droite. Les points de repère sont situés à différents endroits de cet scène, notament le fameux Sphinx en Egypte, la Tour Eiffel en France, la tour de Tokyo au Japon et le marché flottant au Vietnam. Votre personage pour explorer cette scène est Bot.", - "Landmarks.leaningTowerPisa": "La tour penché de Pize", - "Landmarks.machuPicchu": "Matchu Picchu", - "Landmarks.name": "Repères", - "Landmarks.niagaraFalls": "chutes du Niagara", - "Landmarks.operaHouse": "L'Opéra de Sydney", - "Landmarks.plane": "un avion", - "Landmarks.stBasils": "Cathédrale Saint-Basile", - "Landmarks.statueLiberty": "la statue de la Liberté", - "Landmarks.stonehenge": "Stonehenge", - "Landmarks.tableMountain": "table montagne", - "Landmarks.tajMahal": "le palais Taj Mahal", - "Landmarks.tokyoTower": "la tour de Tokyo", - "Landmarks.train": "un train", - "Landmarks.windmill": "les moulins à vents des Pais-Bas", - "PenDownToggleSwitch.penDown": "Stylo vers le bas", - "PlayButton.play": "jouer", - "PlayButton.pause": "pause", - "PlayControls.heading": "jouer aux commandes", - "PrivacyModal.close": "fermer", - "PrivacyModal.title": "Weavly politique de confidentialité", - "ProgramBlockEditor.toggleAddNodeExpandMode": "ajouter un note en mode développer", - "ProgramBlockEditor.beginningBlock": "ajouté l'action selectionnée {command} au début du programme", - "ProgramBlockEditor.betweenBlocks": "ajouté l'action selectionée {command} entre la position {prevCommand} et la position {postCommand}", - "ProgramBlockEditor.lastBlock": "ajouté l'action sélectionée {command} à la fin du programme", - "ProgramBlockEditor.blocks.noCommandSelected": "assurez vous qu'une action est sélectionée", - "ProgramBlockEditor.command": "{command}, possition, {index} du programme en cours", - "ProgramBlockEditor.nestedCommand": "{command}, possition, {index} du boucle, {parentLoopLabel}", - "ProgramBlockEditor.program.deleteAll": "suprrimer tout les étapes de votre programme", - "ProgramBlockEditor.programHeading": "programme", - "ProgramTextEditor.programLabel": "Logiciel:", - "ProgramSequence.heading": "vitesse de lecture du programme", - "ProgramSpeedController.slider": "vitesse de lecture du programme", - "Scene.heading": "scène", - "ShareModal.close": "fermé", - "ShareModal.copy": "copier le lien", - "ShareModal.title": "lien de partage", - "ShareModal.description1": "un lien vers le programme que vous avez créer à été copié dans le presse-papier", - "ShareModal.description2": "vous pouvez également copier le lien ci-dessous et le partager avec qui vous voulez", - "Sketchpad.character": "le robot", - "Sketchpad.label": "un croquis vierge avec une ligne de quadrillage. Votre charactère dans se scène est un robot", - "SoundOptionsModal.allSounds": "tout les sons", - "SoundOptionsModal.announcements": "annonces audio", - "SoundOptionsModal.cancelButton": "annuler", - "SoundOptionsModal.musicalSounds": "sons musicaux ", - "SoundOptionsModal.saveButton": "sauvegarder ", - "SoundOptionsModal.title": "options sonores", - "SoundOptionsModal.toggleOff": "étient", - "SoundOptionsModal.toggleOn": "allumer", - "Sketchpad.name": "un croquis ", - "StopButton": "arrête", - "ThemeSelector.cancelButton": "annuler", - "ThemeSelector.saveButton": "sauvegarder ", - "ThemeSelector.iconButton": "sélecteur du thème", - "ThemeSelector.option.default": "défaut", - "ThemeSelector.option.light": "clair", - "ThemeSelector.option.dark": "sombre", - "ThemeSelector.option.gray": "niveaux de gris", - "ThemeSelector.option.contrast": "contraste élèvé", - "ThemeSelector.title": "thèmes", - "RefreshButton": "rafraîchir", - "ShareButton": "partager", - "Space.aliens": "les aliens", - "Space.asteroid": "une astéroïde", - "Space.character": "le vaisseaux spaciale", - "Space.earth": "la Terre", - "Space.label": "Une scène spaciale avec la Terre, Mars, Saturne, et la Lune répartis en espace. Entre les planètes, il y a des roches spaciales, des météores, un satellite et deux extraterrestres . Votre personnage dans ce scène est un vaisseaux spaciale", - "Space.mars": "Mars", - "Space.meteor": "Une météore", - "Space.moon": "La Lune", - "Space.name": "Espace", - "Space.satellite": "le satélitte", - "Space.saturn": "Saturne", - "Space.star": "Une étoile", - "WorldSelector.Cancel": "annuler", - "WorldSelector.Save": "sauvegarder ", - "WorldSelector.Prompt": "selectionner une arrière plan pour votre scène", - "WorldSelector.Title": "fond de scène", - "Announcement.cannotMoveNext": "à la fin du programme, incapable de se déplacer vers la droite", - "Announcement.cannotMovePrevious": "au début du programme, incapable de se déplacer vers la gauche", - "Announcement.cannotReplaceLoopBlocks": "remplacer n'est pas disponible pour les boucles", - "Haunted.chair": "la chaise", - "Haunted.character": "la lampe de poche", - "Haunted.fireplace": "la cheminée", - "Haunted.label": "Une scène de manoire effrayante. Le corridor d'entrée comporte un grand escalier commençant un bas à droite et allant en haut à gauche. Des peintures hantées, un mirroir et une crâne de cerf effrayant sont accrochées au mur. Les chauves sourris volent. Un feu brûle dans la chiminée située sous la cage d'escalier. Une grande chaise confortable est devant le feu. Les étagères d'une grande bibliothèque à gauche de la scène sont remplis de livres, potions et plantes. Votre personnage dans cette scène est une lampe de poche.", - "Haunted.name": "une maison hauntée", - "Haunted.shelf": "la bibliothèque", - "Haunted.stairs": "les escaliers", - "Marble.bricks": "briques", - "Marble.character": "une bille", - "Marble.label": "Une labyrinthe fait de briques de différentes couleurs. Votre personnage dans cette scène est une bille. Il y a un chemin à travers le labyrinthe qui commence là où se trouve votre bille et il existe plusieurs façons d'échapper du labyrinthe.", - "Marble.name": "course de billes", - "AmusementPark.character": "le billet", - "AmusementPark.entrance": "entrée", - "AmusementPark.ferrisWheel": "grande roue", - "AmusementPark.gameBooth": "stand de jeu", - "AmusementPark.goKarts": "karts", - "AmusementPark.label": "Une scène de parc d'attractions. Une scène avec vos attractions préférées: des montagnes rousses, un grand roue, un bateau pirate, des karts, une blançoir, et un manège. Il y a d'autres choses amusantes à faire, comme un stand de jeux, et une parc aquatique, et si vous voulez des collations, il y a une stand de collations. Votre personnage est un ticket.", - "AmusementPark.merryGoRound": "manège", - "AmusementPark.name": "parc d'attractions", - "AmusementPark.pirateShip": "navire pirate", - "AmusementPark.snackStand": "stand de collations", - "AmusementPark.swingRide": "tour de balançoire", - "AmusementPark.rollerCoaster": "montagnes rousses", - "AmusementPark.waterPark": "parc aquatique", - "AmusementPark.waterSlide": "glissade d'eau", - "AmusementPark.whaleFountain": "fontaine des baleines", - "AtlanticCanada.character": "Insulaire de Cap", - "AtlanticCanada.fishProcessingPlant": "usine de transformation des poissons", - "AtlanticCanada.fogBank": "banc de brouillard", - "AtlanticCanada.house": "une maison", - "AtlanticCanada.iceberg": "in iceberg", - "AtlanticCanada.label": "Scène de voyage Atlantique. Voyagez au Canada atlntique à travers l'océan Atlantique. La météo est imprévisable dans l'océan , certaines parties de l'océan peuvent être orageuses et certaines parties de l'océan peuvent être couverte de brouillard. Voyagez en toute sécurité pour visiter une usine de transformation du poisson et une village terrestre; vous pourriez rencontrer des icebergs ou des baleine sur votre chemin. Votre personnage dans cette scène est un bateau de pêche, également connu sous le nom Cape Islander dans le Canada Atlantique.", - "AtlanticCanada.land": "la terre", - "AtlanticCanada.lighthouse": "la phare", - "AtlanticCanada.name": "atlantique Canada", - "AtlanticCanada.trees": "arbres", - "AtlanticCanada.rowingBoatOnTheShore": "un bateau à rames sur le rivage", - "AtlanticCanada.sailboat": "un bateau a voile", - "AtlanticCanada.shoal": "un banc de poissons", - "AtlanticCanada.shore": "la rive", - "AtlanticCanada.storms": "tempêtes", - "AtlanticCanada.water": "l'eau", - "AtlanticCanada.whale": "une baleine", - "CharacterDescriptionBuilder.positionAndDirection": "À {columnLabel} {rowLabel} face à {direction}", - "CharacterDescriptionBuilder.positionAndDirectionAndItem": "À {columnLabel} {rowLabel} sur {item} orienté vers {direction}", - "CharacterMessageBuilder.hitWall": "ton personnage a heurté un mur {columnLabel} {rowLabel}", - "CharacterMessageBuilder.endOfScene": "Votre personnage à atteint la fin de la scène", - "CharacterPositionController.editPosition.designMode.moveUp": "déplacer le pinceau vers le haut", - "CharacterPositionController.editPosition.designMode.moveRight": "déplacer le pinceau vers la droite", - "CharacterPositionController.editPosition.designMode.moveDown": "déplacer le pinceau vers le bas", - "CharacterPositionController.editPosition.designMode.moveLeft": "déplacer le pinceau vers la gauche", - "CharacterPositionController.editPosition.designMode.columnPosition": "position de la colonne du pinceau", - "CharacterPositionController.editPosition.designMode.rowPosition": "position de rang du pinceau", - "CharacterPositionController.paintbrushButtonEraserSelected": "effacer le carré", - "CharacterPositionController.paintbrushButtonNoSelection": "peindre un carré de fond", - "CharacterPositionController.paintbrushButtonTileSelected": "peinture {tile}", - "CharacterPositionController.setStartButton": "définir la position de départ", - "CustomBackgroundDesignModeButton.customBackgroundDesignMode": "mode de conception arrière plan personnalisé", - "DesignModeCursorDescriptionBuilder.position": "à {columnLabel} {rowLabel} ", - "DesignModeCursorDescriptionBuilder.positionAndItem": "À {columnLabel} {rowLabel} sur {item}", + "EuropeTrip.B6": "la tour de Saint Vincent en Portugal", + "EuropeTrip.B7": "Portugal ", "EuropeTrip.C1": "Islande", - "EuropeTrip.E1": "le Royaume-Uni", - "EuropeTrip.F1": "Norvège", - "EuropeTrip.G1": "Norvège et Suède", - "EuropeTrip.H1": "Suède", - "EuropeTrip.I1": "Cathéralde d'Helsinki en Finlande", - "EuropeTrip.J1": "Finlande", "EuropeTrip.C2": "une balleine en Islande", - "EuropeTrip.D2": "Irlande et le Royaume-Uni", - "EuropeTrip.E2": "le Royaume-Uni", - "EuropeTrip.F2": "un drakkar à Norway", - "EuropeTrip.G2": "Danemark et Norvège et Suède", - "EuropeTrip.H2": "Galma Stan sur la Suède", - "EuropeTrip.I2": "Tallinn en Estonie; également sur cette place est Finlande et Lettonie", "EuropeTrip.C3": "Irelande", + "EuropeTrip.C5": "Espagne", + "EuropeTrip.C6": "Portugal et Espagne", + "EuropeTrip.C7": "Guitare Flamenco en Espagne", + "EuropeTrip.character": "l'avion", + "EuropeTrip.D2": "Irlande et le Royaume-Uni", "EuropeTrip.D3": "un trèfle en irlande; aussi sur cette place le Royaume-Uni", - "EuropeTrip.E3": "un bus à impériale au Royaume-Uni", - "EuropeTrip.F3": "un moulin-à-vent aux Pays-Bas", - "EuropeTrip.G3": "pâtisserie danoise aux Danemark; également sur cette place l'Allemagne et la Suède", - "EuropeTrip.H3": "Pologne et Suède", - "EuropeTrip.I3": "des marguerites en Lettonie et le châteaux de l'Île de Trakai en Lutuanie; aussi sur cette pièce Biéloroussie", - "EuropeTrip.J3": "bibliothèque nationale aux Biéloroussie", "EuropeTrip.D4": "France te le Royaume-Uni", - "EuropeTrip.E4": "chocolate en Belgique; aussi sur cette pièce est la France et le Royaume-Uni", - "EuropeTrip.F4": "un bretzel en Allemagne; aussi das cette pièce le Belgique, Luxembourg, et Pays-Bas", - "EuropeTrip.G4": "Colonnade du moulin en République tchèque; également sur cette pièce est l'Allemagne et Pologne", - "EuropeTrip.H4": "Kielbasa aux Pologne", - "EuropeTrip.I4": "Biéroussie et Pologne et Ukraine", - "EuropeTrip.J4": "Biéroussie et Ukraine", - "EuropeTrip.K4": "Ukraine", - "EuropeTrip.L4": "Ukraine", - "EuropeTrip.C5": "Espagne", "EuropeTrip.D5": "France", - "EuropeTrip.E5": "La tour eiffel en France", - "EuropeTrip.F5": "un montre en Suisse; aussi sur cette pièce l'Autriche, France et l'Allemagne", - "EuropeTrip.G5": "un violon en Autruche et Bled sur la Sloavquie; aussi sur cette pièce le République tzchège et l'Allemagne", - "EuropeTrip.H5": "le paprika en Hongrie et la cérémique en Slovaquie; également sur cette place Autriche et République tscheque et Slovénie", - "EuropeTrip.I5": "Châteux de Peles en Roumaine; aussi sur cette pièce Hongrie, Sloavquie, et Ukraine", - "EuropeTrip.J5": "tournesol en Moldavie; aussi sur cette pièce Roumaine et l'Ukraine", - "EuropeTrip.K5": "Monastère au dôme doré de Saint-Micheal en Ukraine", - "EuropeTrip.L5": "Ukraine", - "EuropeTrip.B6": "la tour de Saint Vincent en Portugal", - "EuropeTrip.C6": "Portugal et Espagne", "EuropeTrip.D6": "France et Espagne", - "EuropeTrip.E6": "LA tour Eiffel en France", - "EuropeTrip.F6": "France et Italie", - "EuropeTrip.G6": "le miel en Croatie et Bled en Slovanie; également sur cette pièce est l'Italie", - "EuropeTrip.H6": "la mosquée Sinan Pacha au Kosovo et l'église Saint-Sava en Serbie et Stari Most en Bosnie-Herzégovine ; également sur cette place la Croatie et la Hongrie et le Monténégro", - "EuropeTrip.I6": "Église Saint-Sava en Serbie ; également sur cette place la Bulgarie et la Roumanie", - "EuropeTrip.J6": "Bulgaria et Moldova et Romanie", - "EuropeTrip.K6": "Ukraine", - "EuropeTrip.B7": "Portugal ", - "EuropeTrip.C7": "Guitare Flamenco en Espagne", "EuropeTrip.D7": "Espagne", + "EuropeTrip.E1": "le Royaume-Uni", + "EuropeTrip.E2": "le Royaume-Uni", + "EuropeTrip.E3": "un bus à impériale au Royaume-Uni", + "EuropeTrip.E4": "chocolate en Belgique; aussi sur cette pièce est la France et le Royaume-Uni", + "EuropeTrip.E5": "La tour eiffel en France", + "EuropeTrip.E6": "LA tour Eiffel en France", "EuropeTrip.E7": "Espagne", + "EuropeTrip.F1": "Norvège", + "EuropeTrip.F2": "un drakkar à Norway", + "EuropeTrip.F3": "un moulin-à-vent aux Pays-Bas", + "EuropeTrip.F4": "un bretzel en Allemagne; aussi das cette pièce le Belgique, Luxembourg, et Pays-Bas", + "EuropeTrip.F5": "un montre en Suisse; aussi sur cette pièce l'Autriche, France et l'Allemagne", + "EuropeTrip.F6": "France et Italie", "EuropeTrip.F7": "France et Italie", + "EuropeTrip.G1": "Norvège et Suède", + "EuropeTrip.G2": "Danemark et Norvège et Suède", + "EuropeTrip.G3": "pâtisserie danoise aux Danemark; également sur cette place l'Allemagne et la Suède", + "EuropeTrip.G4": "Colonnade du moulin en République tchèque; également sur cette pièce est l'Allemagne et Pologne", + "EuropeTrip.G5": "un violon en Autruche et Bled sur la Sloavquie; aussi sur cette pièce le République tzchège et l'Allemagne", + "EuropeTrip.G6": "le miel en Croatie et Bled en Slovanie; également sur cette pièce est l'Italie", "EuropeTrip.G7": "pizza en Italie", - "EuropeTrip.H7": "une chargia en Albanie et la mosquée Sinan Pacha au Kosovo et un yacht au Monténégro ; également sur cette place Macédoine du Nord", - "EuropeTrip.I7": "Rose Valley en Bulgarie et Millennium Cross en Macédoine du Nord ; également sur cette place la Grèce et le Kosovo", - "EuropeTrip.J7": "Bulgarie et Turquie", - "EuropeTrip.K7": "café en Turquie", - "EuropeTrip.L7": "Turquie", "EuropeTrip.G8": "Italie", + "EuropeTrip.H1": "Suède", + "EuropeTrip.H2": "Galma Stan sur la Suède", + "EuropeTrip.H3": "Pologne et Suède", + "EuropeTrip.H4": "Kielbasa aux Pologne", + "EuropeTrip.H5": "le paprika en Hongrie et la cérémique en Slovaquie; également sur cette place Autriche et République tscheque et Slovénie", + "EuropeTrip.H6": "la mosquée Sinan Pacha au Kosovo et l'église Saint-Sava en Serbie et Stari Most en Bosnie-Herzégovine ; également sur cette place la Croatie et la Hongrie et le Monténégro", + "EuropeTrip.H7": "une chargia en Albanie et la mosquée Sinan Pacha au Kosovo et un yacht au Monténégro ; également sur cette place Macédoine du Nord", "EuropeTrip.H8": "Grèce et Italie", + "EuropeTrip.I1": "Cathéralde d'Helsinki en Finlande", + "EuropeTrip.I2": "Tallinn en Estonie; également sur cette place est Finlande et Lettonie", + "EuropeTrip.I3": "des marguerites en Lettonie et le châteaux de l'Île de Trakai en Lutuanie; aussi sur cette pièce Biéloroussie", + "EuropeTrip.I4": "Biéroussie et Pologne et Ukraine", + "EuropeTrip.I5": "Châteux de Peles en Roumaine; aussi sur cette pièce Hongrie, Sloavquie, et Ukraine", + "EuropeTrip.I6": "Église Saint-Sava en Serbie ; également sur cette place la Bulgarie et la Roumanie", + "EuropeTrip.I7": "Rose Valley en Bulgarie et Millennium Cross en Macédoine du Nord ; également sur cette place la Grèce et le Kosovo", "EuropeTrip.I8": "le Parthenon en Grèce", + "EuropeTrip.J1": "Finlande", + "EuropeTrip.J3": "bibliothèque nationale aux Biéloroussie", + "EuropeTrip.J4": "Biéroussie et Ukraine", + "EuropeTrip.J5": "tournesol en Moldavie; aussi sur cette pièce Roumaine et l'Ukraine", + "EuropeTrip.J6": "Bulgaria et Moldova et Romanie", + "EuropeTrip.J7": "Bulgarie et Turquie", "EuropeTrip.J8": "Grèce et Turquie", + "EuropeTrip.K4": "Ukraine", + "EuropeTrip.K5": "Monastère au dôme doré de Saint-Micheal en Ukraine", + "EuropeTrip.K6": "Ukraine", + "EuropeTrip.K7": "café en Turquie", "EuropeTrip.K8": "olives en Chypre; aussi sur cette case Turquie", + "EuropeTrip.L4": "Ukraine", + "EuropeTrip.L5": "Ukraine", + "EuropeTrip.L7": "Turquie", "EuropeTrip.L8": "olives en Chypre; aussi sur cette case Turquie", - "EuropeTrip.character": "l'avion", "EuropeTrip.label": "Une scène de voyage en Europe contenant une carte de Europe avec des attractions touristiques. L'Islande est située en haut à gauche de la scène. Chypre est située en bas à droite de la scène. Les attractions touristiques sont située dans le pays connu pour des attractions, comme le Violon en Autriche, près du centre de la scène. Votre personnage dans cette scène est un avion.", "EuropeTrip.name": "Voyage en Europe", "GroceryStore.apples": "pommes", @@ -985,6 +822,96 @@ "GroceryStore.tomatoes": "tomates", "GroceryStore.watermelons": "melon-d'eau", "GroceryStore.yogurt": "yaourte", + "Haunted.chair": "la chaise", + "Haunted.character": "la lampe de poche", + "Haunted.deerSkull": "the deer skull", + "Haunted.fireplace": "la cheminée", + "Haunted.label": "Une scène de manoire effrayante. Le corridor d'entrée comporte un grand escalier commençant un bas à droite et allant en haut à gauche. Des peintures hantées, un mirroir et une crâne de cerf effrayant sont accrochées au mur. Les chauves sourris volent. Un feu brûle dans la chiminée située sous la cage d'escalier. Une grande chaise confortable est devant le feu. Les étagères d'une grande bibliothèque à gauche de la scène sont remplis de livres, potions et plantes. Votre personnage dans cette scène est une lampe de poche.", + "une scène de manoir effrayante, le hall de entrée a un grand escalier commançant en bas à droite et allant en haut à gauche. Des paintures hauntées un mirroir et une crâne de cerf effrayant sont affichées au murs. Les chauves souris volent. Un feu brûle dans la cheminée soous la cage d'escaliers. Une grand chaise confortable est devant le feu. Les étagers d'une grande bibliothèque à gauche de la scène sont remplis de livres, de potions et de plantes. Votre personnage dans se scène est une main tenant une bougie.Haunted.mirror": "the mirror", + "Haunted.name": "une maison hauntée", + "Haunted.painting": "a painting", + "Haunted.shelf": "la bibliothèque", + "Haunted.stairs": "les escaliers", + "KeyboardInputModal.Cancel": "annuler", + "KeyboardInputModal.Description.addCommandToBeginning": "appuyer sur la {key} pour ajouter la commande sélectionnée au début du programme", + "KeyboardInputModal.Description.addCommandToEnd": "appuyer sur la {key} pour ajouter la commande sélectionnée à la fin du programme", + "KeyboardInputModal.Description.announceScene": "appuyer sur la {key} pour annoncer la position du charactère et l'orientation", + "KeyboardInputModal.Description.decreaseProgramSpeed": "appuyer sur la {key} pour ralentir la lecture du programme", + "KeyboardInputModal.Description.deleteCurrentStep": "appuyer sur la {key} pour surpimer l'étape actuellement ciblée", + "KeyboardInputModal.Description.increaseProgramSpeed": "appuyer sur la {key} pour accélérer la lecture du programme", + "KeyboardInputModal.Description.playPauseProgram": "appuyer sur la {key} pour lire ou mettre en pause le programme", + "KeyboardInputModal.Description.refreshScene": "appuyer sur la {key} pour réfraîchir la scène", + "KeyboardInputModal.Description.showHide": "appuyer sur la {key} pour voir le menu racourci de l'ordinateur", + "KeyboardInputModal.Description.stopProgram": "appuyer sur la {key} pour arrêter le programme", + "KeyboardInputModal.Description.toggleAnnouncements": "appuyer sur la {key} pour basculer les annonces", + "KeyboardInputModal.KeyIcons.A": "A", + "KeyboardInputModal.KeyIcons.Alt": "alt", + "KeyboardInputModal.KeyIcons.B": "B", + "KeyboardInputModal.KeyIcons.Control": "ctrl", + "KeyboardInputModal.KeyIcons.D": "D", + "KeyboardInputModal.KeyIcons.E": "E", + "KeyboardInputModal.KeyIcons.GreaterThan": ">", + "KeyboardInputModal.KeyIcons.I": "I", + "KeyboardInputModal.KeyIcons.LessThan": "<", + "KeyboardInputModal.KeyIcons.P": "P", + "KeyboardInputModal.KeyIcons.QuestionMark": "?", + "KeyboardInputModal.KeyIcons.R": "R", + "KeyboardInputModal.KeyIcons.S": "S", + "KeyboardInputModal.KeyIcons.Shift": "déclage", + "KeyboardInputModal.KeyLabels.A": "a", + "KeyboardInputModal.KeyLabels.Alt": "alt", + "KeyboardInputModal.KeyLabels.B": "b", + "KeyboardInputModal.KeyLabels.Control": "contôle", + "KeyboardInputModal.KeyLabels.D": "d", + "KeyboardInputModal.KeyLabels.E": "e", + "KeyboardInputModal.KeyLabels.GreaterThan": "plus grand que", + "KeyboardInputModal.KeyLabels.I": "i", + "KeyboardInputModal.KeyLabels.LessThan": "plus petit que", + "KeyboardInputModal.KeyLabels.P": "p", + "KeyboardInputModal.KeyLabels.QuestionMark": "point d'interrogation", + "KeyboardInputModal.KeyLabels.R": "r", + "KeyboardInputModal.KeyLabels.S": "s", + "KeyboardInputModal.Save": "sauvegarder ", + "KeyboardInputModal.Scheme.Descriptions.alt": "alt (apple: option)", + "KeyboardInputModal.Scheme.Descriptions.controlalt": "contrôle+alt (apple: contrôle+option)", + "KeyboardInputModal.ShowHide.AriaLabel": "afficher le menu des raccourcis claviers", + "KeyboardInputModal.Title": "raccourcis clavier", + "KeyboardInputModal.Toggle.AriaLabel": "basculer les raccourcis claviers", + "KeyboardInputModal.Toggle.Label": "keyboard shortcuts", + "KeyboardInputModal.Toggle.Off": "à l'arrête", + "KeyboardInputModal.Toggle.On": "sur", + "Landmarks.bigBen": "Tour Big Ben", + "Landmarks.burAlArab": "Le bâtiment Burj al Arab", + "Landmarks.character": "the robot", + "Landmarks.cnTower": "La tour CN", + "Landmarks.colosseum": "Le Colossuem", + "Landmarks.easterIsland": "les statues de l'île de pacques", + "Landmarks.eiffelTower": "La Tour Eiffel", + "Landmarks.fairyChimneys": "cheminées de fées", + "Landmarks.floatingMarket": "le marché flottant de Vietnam", + "Landmarks.grandCanyon": "Le grand Canyon", + "Landmarks.greatPyramid": "la grande pyramide de Gizeh", + "Landmarks.greatSphinx": "la grande sphinx de Gizeh", + "Landmarks.greatWall": "La grande muraille de Chine", + "Landmarks.label": "Une grande scène mondiale qui contient 23 monuments célèbres trouver dans le monde. Un avion vole depuis le point supérieur gauche. Un train part du point supérieur droite. Les points de repère sont situés à différents endroits de cet scène, notament le fameux Sphinx en Egypte, la Tour Eiffel en France, la tour de Tokyo au Japon et le marché flottant au Vietnam. Votre personage pour explorer cette scène est Bot.", + "Landmarks.leaningTowerPisa": "La tour penché de Pize", + "Landmarks.machuPicchu": "Matchu Picchu", + "Landmarks.name": "Repères", + "Landmarks.niagaraFalls": "chutes du Niagara", + "Landmarks.operaHouse": "L'Opéra de Sydney", + "Landmarks.plane": "un avion", + "Landmarks.statueLiberty": "la statue de la Liberté", + "Landmarks.stBasils": "Cathédrale Saint-Basile", + "Landmarks.stonehenge": "Stonehenge", + "Landmarks.tableMountain": "table montagne", + "Landmarks.tajMahal": "le palais Taj Mahal", + "Landmarks.tokyoTower": "la tour de Tokyo", + "Landmarks.train": "un train", + "Landmarks.windmill": "les moulins à vents des Pais-Bas", + "Marble.bricks": "briques", + "Marble.character": "une bille", + "Marble.label": "Une labyrinthe fait de briques de différentes couleurs. Votre personnage dans cette scène est une bille. Il y a un chemin à travers le labyrinthe qui commence là où se trouve votre bille et il existe plusieurs façons d'échapper du labyrinthe.", + "Marble.name": "course de billes", "MusicBand.character": "la note de musique", "MusicBand.drumKit": "la batterie", "MusicBand.guitar": "la guitare", @@ -997,26 +924,70 @@ "MusicBand.synthesizer": "une synthésiseur", "MusicBand.tambourine": "une tambourine", "MusicBand.xylophone": "un xylophone avec un maillet", - "Scene.description": "Scène, dans {world}, grille {numColumns} par {numRows}. {characterDescription}", + "PenDownToggleSwitch.penDown": "Stylo vers le bas", + "PlayButton.pause": "pause", + "PlayButton.play": "jouer", + "PlayControls.heading": "jouer aux commandes", + "PrivacyModal.close": "fermer", + "PrivacyModal.title": "Weavly politique de confidentialité", + "ProgramBlockEditor.beginningBlock": "ajouté l'action selectionnée {command} au début du programme", + "ProgramBlockEditor.betweenBlocks": "ajouté l'action selectionée {command} entre la position {prevCommand} et la position {postCommand}", + "ProgramBlockEditor.blocks.noCommandSelected": "assurez vous qu'une action est sélectionée", + "ProgramBlockEditor.command": "{command}, possition, {index} du programme en cours", + "ProgramBlockEditor.lastBlock": "ajouté l'action sélectionée {command} à la fin du programme", + "ProgramBlockEditor.nestedCommand": "{command}, possition, {index} du boucle, {parentLoopLabel}", + "ProgramBlockEditor.program.deleteAll": "suprrimer tout les étapes de votre programme", + "ProgramBlockEditor.programHeading": "programme", + "ProgramBlockEditor.toggleAddNodeExpandMode": "ajouter un note en mode développer", + "ProgramSequence.heading": "vitesse de lecture du programme", + "ProgramSpeedController.slider": "vitesse de lecture du programme", + "ProgramTextEditor.programLabel": "Logiciel:", + "RefreshButton": "rafraîchir", + "savannah.alligator": "L'alligator", + "savannah.babyAlligator": "le bébé alligator", + "savannah.babyGiraffe": "le bébé giraffe", + "savannah.bush": "une buisson", + "savannah.character": "le jeep", + "savannah.flamingo": "le flamant rose", + "savannah.giraffe": "le giraffe", + "savannah.hippo": "l'hippopotame", + "savannah.label": "Une scène de Savane. Un lion rugit au sommet d'une falaise au-dessous de l'horizon. Une mère et son bébé giraffe parcourent la savane. Deux, crocodiles, un flamant rose et un hippopotame boivent de l'eau d'un étang entourné d'arbres. Votre personnage dans cette scène est un Jeep", + "savannah.lion": "le lion", + "Savannah.name": "Savannah", + "savannah.pond": "l'étang", + "savannah.tree": "l'arbre", + "Scene.description": "Scène, dans {world}, grille {numColumns} par {numRows}. {Description du personnage}", + "Scene.heading": "scène", "SceneMessage.close": "fermée le message", - "TileDescription.black": "noire", - "TileDescription.brown": "brun", - "TileDescription.darkBlue": "bleu foncer", - "TileDescription.gem": "gem", - "TileDescription.gold": "gold", - "TileDescription.green": "vert", - "TileDescription.grey": "gris", - "TileDescription.lightBlue": "bleu claire", - "TileDescription.none": "gomme de fond personnalisée", - "TileDescription.orange": "orange", - "TileDescription.pink": "rose", - "TileDescription.purple": "violet", - "TileDescription.red": "rouge", - "TileDescription.treats": "friandises", - "TileDescription.wall": "mur", - "TileDescription.white": "blanc", - "TileDescription.yellow": "jaune", - "TilePanel.heading": "Conception de fond personnalisée", + "ShareButton": "partager", + "ShareModal.close": "fermé", + "ShareModal.copy": "copier le lien", + "ShareModal.description1": "un lien vers le programme que vous avez créer à été copié dans le presse-papier", + "ShareModal.description2": "vous pouvez également copier le lien ci-dessous et le partager avec qui vous voulez", + "ShareModal.title": "lien de partage", + "Sketchpad.character": "le robot", + "Sketchpad.label": "un croquis vierge avec une ligne de quadrillage. Votre charactère dans se scène est un robot", + "Sketchpad.name": "un croquis ", + "SoundOptionsModal.allSounds": "tout les sons", + "SoundOptionsModal.announcements": "annonces audio", + "SoundOptionsModal.cancelButton": "annuler", + "SoundOptionsModal.musicalSounds": "sons musicaux ", + "SoundOptionsModal.saveButton": "sauvegarder ", + "SoundOptionsModal.title": "options sonores", + "SoundOptionsModal.toggleOff": "étient", + "SoundOptionsModal.toggleOn": "allumer", + "Space.aliens": "les aliens", + "Space.asteroid": "une astéroïde", + "Space.character": "le vaisseaux spaciale", + "Space.earth": "la Terre", + "Space.label": "Une scène spaciale avec la Terre, Mars, Saturne, et la Lune répartis en espace. Entre les planètes, il y a des roches spaciales, des météores, un satellite et deux extraterrestres . Votre personnage dans ce scène est un vaisseaux spaciale", + "Space.mars": "Mars", + "Space.meteor": "Une météore", + "Space.moon": "La Lune", + "Space.name": "Espace", + "Space.satellite": "le satélitte", + "Space.saturn": "Saturne", + "Space.star": "Une étoile", "Sports.badmintonShuttlecock": "volant de badminton", "Sports.baseballGloveAndBall": "gant de balle et baseball", "Sports.basketball": "basketball", @@ -1043,6 +1014,38 @@ "Sports.tableTennisRacket": "raquette de tennis de table", "Sports.tennisRacketAndBall": "raquette et balle de tennis", "Sports.volleyballBall": "ballon de volleyball", + "StopButton": "arrête", + "ThemeSelector.cancelButton": "annuler", + "ThemeSelector.iconButton": "sélecteur du thème", + "ThemeSelector.option.contrast": "contraste élèvé", + "ThemeSelector.option.dark": "sombre", + "ThemeSelector.option.default": "défaut", + "ThemeSelector.option.gray": "niveaux de gris", + "ThemeSelector.option.light": "clair", + "ThemeSelector.saveButton": "sauvegarder ", + "ThemeSelector.title": "thèmes", + "TileDescription.black": "noire", + "TileDescription.brown": "brun", + "TileDescription.darkBlue": "bleu foncer", + "TileDescription.gem": "gem", + "TileDescription.gold": "gold", + "TileDescription.green": "vert", + "TileDescription.grey": "gris", + "TileDescription.lightBlue": "bleu claire", + "TileDescription.none": "gomme de fond personnalisée", + "TileDescription.orange": "orange", + "TileDescription.pink": "rose", + "TileDescription.purple": "violet", + "TileDescription.red": "rouge", + "TileDescription.treats": "friandises", + "TileDescription.wall": "mur", + "TileDescription.white": "blanc", + "TileDescription.yellow": "jaune", + "TilePanel.heading": "Conception de fond personnalisée", + "WorldSelector.Cancel": "annuler", + "WorldSelector.Prompt": "selectionner une arrière plan pour votre scène", + "WorldSelector.Save": "sauvegarder ", + "WorldSelector.Title": "fond de scène", "WorldSelectorButton.heading": "Sélecteur de fond de scène", "WorldSelectorButton.label": "Sélecteur de fond de scène" } From b784239f7075125fb36f2f12a18e78b13590c5a8 Mon Sep 17 00:00:00 2001 From: Daniel Cho Date: Fri, 26 Jul 2024 16:59:33 -0400 Subject: [PATCH 03/23] fix: errors in messages --- src/messages.json | 56 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/messages.json b/src/messages.json index b05d735c..9d3f3609 100644 --- a/src/messages.json +++ b/src/messages.json @@ -302,7 +302,7 @@ "Haunted.deerSkull": "the deer skull", "Haunted.fireplace": "the fireplace", "Haunted.label": "A spooky mansion scene. The front hall has a large staircase starting at the bottom right and going to the top left. Haunted paintings, a mirror, and a creepy deer skull hang on the wall. Bats are flying around. A fire burns in the fireplace below the stairwell. A big comfy chair is in front of the fire. The shelves of a large bookshelf on the left of the scene is stacked with books, potions and plants. Your character in this scene is a flashlight.", - "une scène de manoir effrayante, le hall de entrée a un grand escalier commançant en bas à droite et allant en haut à gauche. Des paintures hauntées un mirroir et une crâne de cerf effrayant sont affichées au murs. Les chauves souris volent. Un feu brûle dans la cheminée soous la cage d'escaliers. Une grand chaise confortable est devant le feu. Les étagers d'une grande bibliothèque à gauche de la scène sont remplis de livres, de potions et de plantes. Votre personnage dans se scène est une main tenant une bougie.Haunted.mirror": "the mirror", + "Haunted.mirror": "the mirror", "Haunted.name": "Haunted House", "Haunted.painting": "a painting", "Haunted.shelf": "the bookshelf", @@ -418,19 +418,19 @@ "ProgramSpeedController.slider": "Program play speed", "ProgramTextEditor.programLabel": "Program:", "RefreshButton": "Refresh", - "savannah.alligator": "the Alligator", - "savannah.babyAlligator": "the Baby Alligator", - "savannah.babyGiraffe": "the Baby Giraffe", - "savannah.bush": "a Bush", - "savannah.character": "the jeep", - "savannah.flamingo": "the Flamingo", - "savannah.giraffe": "the Giraffe", - "savannah.hippo": "the Hippo", - "savannah.label": "A savannah scene. A lion roars at the top of a cliff above the horizon. A mother and baby giraffe roam the savannah. Two crocodiles, a flamingo and a hippopotamus drink water from a pond surrounded by trees. Your character in this scene is a Jeep.", - "savannah.lion": "the Lion", + "Savannah.alligator": "the Alligator", + "Savannah.babyAlligator": "the Baby Alligator", + "Savannah.babyGiraffe": "the Baby Giraffe", + "Savannah.bush": "a Bush", + "Savannah.character": "the jeep", + "Savannah.flamingo": "the Flamingo", + "Savannah.giraffe": "the Giraffe", + "Savannah.hippo": "the Hippo", + "Savannah.label": "A savannah scene. A lion roars at the top of a cliff above the horizon. A mother and baby giraffe roam the savannah. Two crocodiles, a flamingo and a hippopotamus drink water from a pond surrounded by trees. Your character in this scene is a Jeep.", + "Savannah.lion": "the Lion", "Savannah.name": "Savannah", - "savannah.pond": "the Pond", - "savannah.tree": "a Tree", + "Savannah.pond": "the Pond", + "Savannah.tree": "a Tree", "Scene.description": "Scene, in {world}, {numColumns} by {numRows} grid. {characterDescription}", "Scene.heading": "Scene", "SceneMessage.close": "close message", @@ -628,7 +628,7 @@ "Camping.trunk": "le tronc d\u0000'arbre ", "CharacterAriaLive.movementAriaLabel": "Le {character} bouge", "CharacterDescriptionBuilder.positionAndDirection": "À {columnLabel} {rowLabel} face à {direction}", - "CharacterDescriptionBuilder.positionAndDirectionAndItem": "À {column Label} {rowLabel} sur {item} orienté vers {direction}", + "CharacterDescriptionBuilder.positionAndDirectionAndItem": "À {columnLabel} {rowLabel} sur {item} orienté vers {direction}", "CharacterMessageBuilder.endOfScene": "Votre personnage à atteint la fin de la scène", "CharacterMessageBuilder.hitWall": "ton personnage a heurté un mur {columnLabel} {rowLabel}", "CharacterPositionController.editPosition.columnPosition": "position de la colonne des charactères", @@ -827,7 +827,7 @@ "Haunted.deerSkull": "the deer skull", "Haunted.fireplace": "la cheminée", "Haunted.label": "Une scène de manoire effrayante. Le corridor d'entrée comporte un grand escalier commençant un bas à droite et allant en haut à gauche. Des peintures hantées, un mirroir et une crâne de cerf effrayant sont accrochées au mur. Les chauves sourris volent. Un feu brûle dans la chiminée située sous la cage d'escalier. Une grande chaise confortable est devant le feu. Les étagères d'une grande bibliothèque à gauche de la scène sont remplis de livres, potions et plantes. Votre personnage dans cette scène est une lampe de poche.", - "une scène de manoir effrayante, le hall de entrée a un grand escalier commançant en bas à droite et allant en haut à gauche. Des paintures hauntées un mirroir et une crâne de cerf effrayant sont affichées au murs. Les chauves souris volent. Un feu brûle dans la cheminée soous la cage d'escaliers. Une grand chaise confortable est devant le feu. Les étagers d'une grande bibliothèque à gauche de la scène sont remplis de livres, de potions et de plantes. Votre personnage dans se scène est une main tenant une bougie.Haunted.mirror": "the mirror", + "Haunted.mirror": "the mirror", "Haunted.name": "une maison hauntée", "Haunted.painting": "a painting", "Haunted.shelf": "la bibliothèque", @@ -943,20 +943,20 @@ "ProgramSpeedController.slider": "vitesse de lecture du programme", "ProgramTextEditor.programLabel": "Logiciel:", "RefreshButton": "rafraîchir", - "savannah.alligator": "L'alligator", - "savannah.babyAlligator": "le bébé alligator", - "savannah.babyGiraffe": "le bébé giraffe", - "savannah.bush": "une buisson", - "savannah.character": "le jeep", - "savannah.flamingo": "le flamant rose", - "savannah.giraffe": "le giraffe", - "savannah.hippo": "l'hippopotame", - "savannah.label": "Une scène de Savane. Un lion rugit au sommet d'une falaise au-dessous de l'horizon. Une mère et son bébé giraffe parcourent la savane. Deux, crocodiles, un flamant rose et un hippopotame boivent de l'eau d'un étang entourné d'arbres. Votre personnage dans cette scène est un Jeep", - "savannah.lion": "le lion", + "Savannah.alligator": "L'alligator", + "Savannah.babyAlligator": "le bébé alligator", + "Savannah.babyGiraffe": "le bébé giraffe", + "Savannah.bush": "une buisson", + "Savannah.character": "le jeep", + "Savannah.flamingo": "le flamant rose", + "Savannah.giraffe": "le giraffe", + "Savannah.hippo": "l'hippopotame", + "Savannah.label": "Une scène de Savane. Un lion rugit au sommet d'une falaise au-dessous de l'horizon. Une mère et son bébé giraffe parcourent la savane. Deux, crocodiles, un flamant rose et un hippopotame boivent de l'eau d'un étang entourné d'arbres. Votre personnage dans cette scène est un Jeep", + "Savannah.lion": "le lion", "Savannah.name": "Savannah", - "savannah.pond": "l'étang", - "savannah.tree": "l'arbre", - "Scene.description": "Scène, dans {world}, grille {numColumns} par {numRows}. {Description du personnage}", + "Savannah.pond": "l'étang", + "Savannah.tree": "l'arbre", + "Scene.description": "Scène, dans {world}, grille {numColumns} par {numRows}. {characterDescription}", "Scene.heading": "scène", "SceneMessage.close": "fermée le message", "ShareButton": "partager", From d2f993d786f88da93b901b9a4f140a74ad5e12b8 Mon Sep 17 00:00:00 2001 From: Daniel Cho Date: Thu, 22 Aug 2024 11:17:57 -0400 Subject: [PATCH 04/23] fix: update messages --- src/messages.json | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/messages.json b/src/messages.json index 9d3f3609..71c914ff 100644 --- a/src/messages.json +++ b/src/messages.json @@ -539,17 +539,17 @@ "ActionsMenuItem.command.loop": "boucle", "ActionsMenuItem.command.right45": "tourner à droite 45 degrées", "ActionsMenuItem.command.right90": "tourner à droite 90 degrées", - "ActionsMenuItem.unusedItemToggleLabel": "(action)", - "ActionsMenuItem.usedItemToggleLabel": "utilisé", + "ActionsMenuItem.unusedItemToggleLabel": "{action}", + "ActionsMenuItem.usedItemToggleLabel": "(utilisé)", "ActionsSimplificationModal.cancel": "annuler", "ActionsSimplificationModal.save": "sauvegarder", "ActionsSimplificationModal.title": "actions disponibles", - "AmusementPark.character": "the train", + "AmusementPark.character": "le train", "AmusementPark.entrance": "entrée", "AmusementPark.ferrisWheel": "grande roue", "AmusementPark.gameBooth": "stand de jeu", "AmusementPark.goKarts": "karts", - "AmusementPark.label": "Une scène de parc d'attractions. Une scène avec vos attractions préférées: des montagnes rousses, un grand roue, un bateau pirate, des karts, une blançoir, et un manège. Il y a d'autres choses amusantes à faire, comme un stand de jeux, et une parc aquatique, et si vous voulez des collations, il y a une stand de collations. Votre personnage est un ticket.", + "AmusementPark.label": "Une scène de parc d'attractions. Une scène avec vos attractions préférées: des montagnes rousses, un grand roue, un bateau pirate, des karts, une blançoir, et un manège. Il y a d'autres choses amusantes à faire, comme un stand de jeux, et une parc aquatique, et si vous voulez des collations, il y a une stand de collations. Votre personnage dans cette scène est un train.", "AmusementPark.merryGoRound": "manège", "AmusementPark.name": "parc d'attractions", "AmusementPark.pirateShip": "navire pirate", @@ -578,7 +578,7 @@ "Announcement.left45": "tourner à gauche de 45 degrées", "Announcement.left90": "tourner a gauche de 90 degréees", "Announcement.loop": "boucle", - "Announcement.movement": "mouvement ", + "Announcement.movement": "mouvement", "Announcement.moveToNext": "déplacer vers la droite", "Announcement.moveToPrevious": "déplacer vers la gauche", "Announcement.noActionSelected": "aucune action sélectionnée", @@ -618,14 +618,14 @@ "BluetoothApiWarning.message": "la connection du robot dash fonctionne seulement en Chrome", "Camping.bear": "l`ours noire", "Camping.branch": "branche d'arbre", - "Camping.character": "the squirrel", + "Camping.character": "l'écureuil", "Camping.fire": "le feu de camp", "Camping.label": "une scène de camping. un ours noir atteint un tronc d'arbre sûre le côté gauche de la scène. une branche 'arbre traverse le haut des la scène et une échelle de corde y est suspendu. il y a une tente ouvert sur le côté droit de la scène. un lac et un feu de camp sont au milieu de la scène. votre personnage dans cette scène est une écureuil.", "Camping.ladder": "une échelle de corde", "Camping.lake": "le lac", "Camping.name": "voyage de camping", "Camping.tentdoor": "la porte de la tente", - "Camping.trunk": "le tronc d\u0000'arbre ", + "Camping.trunk": "le tronc d'arbre", "CharacterAriaLive.movementAriaLabel": "Le {character} bouge", "CharacterDescriptionBuilder.positionAndDirection": "À {columnLabel} {rowLabel} face à {direction}", "CharacterDescriptionBuilder.positionAndDirectionAndItem": "À {columnLabel} {rowLabel} sur {item} orienté vers {direction}", @@ -700,7 +700,7 @@ "DeepOcean.name": "Océan profond", "DeepOcean.shark": "le renard", "DeepOcean.treasure": "the trésore", - "DesignModeCursorDescriptionBuilder.position": "à {columnLabel} {rowLabel} ", + "DesignModeCursorDescriptionBuilder.position": "à {columnLabel} {rowLabel}", "DesignModeCursorDescriptionBuilder.positionAndItem": "À {columnLabel} {rowLabel} sur {item}", "DeviceConnectControl.connected": "Connecté", "DeviceConnectControl.connecting": "Connexion en cours", @@ -714,7 +714,7 @@ "Direction.6": "gauche", "Direction.7": "en haut à gauce", "EuropeTrip.B6": "la tour de Saint Vincent en Portugal", - "EuropeTrip.B7": "Portugal ", + "EuropeTrip.B7": "Portugal", "EuropeTrip.C1": "Islande", "EuropeTrip.C2": "une balleine en Islande", "EuropeTrip.C3": "Irelande", @@ -803,7 +803,7 @@ "GroceryStore.fish": "poisson", "GroceryStore.grapes": "raisins", "GroceryStore.greenVegetables": "légumes verts", - "GroceryStore.groundBeef": "le boeuf haché ", + "GroceryStore.groundBeef": "le boeuf haché", "GroceryStore.jars": "pots", "GroceryStore.label": "Une scène d'epicerie. En haut au milieu se trouve un frigo contenent de la viande et du poisson. En haut à droite se trouve des pots, des canettes et d'autres articles de garde-manger. A gauche du magasin se trouve des pains et des légumes. Au milieu vers le bas se trouve les fruits. Et en bas à droite se trouve un frigo contenant des produits laitier et d'autre produits réfrigérés. Votre personnage dans cette scène est un panier d'épicerie", "GroceryStore.milk": "lait ", @@ -824,12 +824,12 @@ "GroceryStore.yogurt": "yaourte", "Haunted.chair": "la chaise", "Haunted.character": "la lampe de poche", - "Haunted.deerSkull": "the deer skull", + "Haunted.deerSkull": "la crâne d'une cerf", "Haunted.fireplace": "la cheminée", "Haunted.label": "Une scène de manoire effrayante. Le corridor d'entrée comporte un grand escalier commençant un bas à droite et allant en haut à gauche. Des peintures hantées, un mirroir et une crâne de cerf effrayant sont accrochées au mur. Les chauves sourris volent. Un feu brûle dans la chiminée située sous la cage d'escalier. Une grande chaise confortable est devant le feu. Les étagères d'une grande bibliothèque à gauche de la scène sont remplis de livres, potions et plantes. Votre personnage dans cette scène est une lampe de poche.", - "Haunted.mirror": "the mirror", + "Haunted.mirror": "le mirror", "Haunted.name": "une maison hauntée", - "Haunted.painting": "a painting", + "Haunted.painting": "une peinture", "Haunted.shelf": "la bibliothèque", "Haunted.stairs": "les escaliers", "KeyboardInputModal.Cancel": "annuler", @@ -882,7 +882,7 @@ "KeyboardInputModal.Toggle.On": "sur", "Landmarks.bigBen": "Tour Big Ben", "Landmarks.burAlArab": "Le bâtiment Burj al Arab", - "Landmarks.character": "the robot", + "Landmarks.character": "le robot", "Landmarks.cnTower": "La tour CN", "Landmarks.colosseum": "Le Colossuem", "Landmarks.easterIsland": "les statues de l'île de pacques", @@ -893,7 +893,7 @@ "Landmarks.greatPyramid": "la grande pyramide de Gizeh", "Landmarks.greatSphinx": "la grande sphinx de Gizeh", "Landmarks.greatWall": "La grande muraille de Chine", - "Landmarks.label": "Une grande scène mondiale qui contient 23 monuments célèbres trouver dans le monde. Un avion vole depuis le point supérieur gauche. Un train part du point supérieur droite. Les points de repère sont situés à différents endroits de cet scène, notament le fameux Sphinx en Egypte, la Tour Eiffel en France, la tour de Tokyo au Japon et le marché flottant au Vietnam. Votre personage pour explorer cette scène est Bot.", + "Landmarks.label": "Une grande scène mondiale qui contient 23 monuments célèbres trouver dans le monde. Un avion vole depuis le point supérieur gauche. Un train part du point supérieur droite. Les points de repère sont situés à différents endroits de cet scène, notament le fameux Sphinx en Egypte, la Tour Eiffel en France, la tour de Tokyo au Japon et le marché flottant au Vietnam. Votre caractère pour explorer cette scène est un robot.", "Landmarks.leaningTowerPisa": "La tour penché de Pize", "Landmarks.machuPicchu": "Matchu Picchu", "Landmarks.name": "Repères", @@ -953,7 +953,7 @@ "Savannah.hippo": "l'hippopotame", "Savannah.label": "Une scène de Savane. Un lion rugit au sommet d'une falaise au-dessous de l'horizon. Une mère et son bébé giraffe parcourent la savane. Deux, crocodiles, un flamant rose et un hippopotame boivent de l'eau d'un étang entourné d'arbres. Votre personnage dans cette scène est un Jeep", "Savannah.lion": "le lion", - "Savannah.name": "Savannah", + "Savannah.name": "Savane", "Savannah.pond": "l'étang", "Savannah.tree": "l'arbre", "Scene.description": "Scène, dans {world}, grille {numColumns} par {numRows}. {characterDescription}", @@ -967,12 +967,12 @@ "ShareModal.title": "lien de partage", "Sketchpad.character": "le robot", "Sketchpad.label": "un croquis vierge avec une ligne de quadrillage. Votre charactère dans se scène est un robot", - "Sketchpad.name": "un croquis ", + "Sketchpad.name": "un croquis", "SoundOptionsModal.allSounds": "tout les sons", "SoundOptionsModal.announcements": "annonces audio", "SoundOptionsModal.cancelButton": "annuler", - "SoundOptionsModal.musicalSounds": "sons musicaux ", - "SoundOptionsModal.saveButton": "sauvegarder ", + "SoundOptionsModal.musicalSounds": "sons musicaux", + "SoundOptionsModal.saveButton": "sauvegarder", "SoundOptionsModal.title": "options sonores", "SoundOptionsModal.toggleOff": "étient", "SoundOptionsModal.toggleOn": "allumer", @@ -1022,7 +1022,7 @@ "ThemeSelector.option.default": "défaut", "ThemeSelector.option.gray": "niveaux de gris", "ThemeSelector.option.light": "clair", - "ThemeSelector.saveButton": "sauvegarder ", + "ThemeSelector.saveButton": "sauvegarder", "ThemeSelector.title": "thèmes", "TileDescription.black": "noire", "TileDescription.brown": "brun", @@ -1044,7 +1044,7 @@ "TilePanel.heading": "Conception de fond personnalisée", "WorldSelector.Cancel": "annuler", "WorldSelector.Prompt": "selectionner une arrière plan pour votre scène", - "WorldSelector.Save": "sauvegarder ", + "WorldSelector.Save": "sauvegarder", "WorldSelector.Title": "fond de scène", "WorldSelectorButton.heading": "Sélecteur de fond de scène", "WorldSelectorButton.label": "Sélecteur de fond de scène" From 48b8c97bd625e017300369222645da42c4fbe8d1 Mon Sep 17 00:00:00 2001 From: Daniel Cho Date: Fri, 23 Aug 2024 13:45:16 -0400 Subject: [PATCH 05/23] fix: remove unused messages --- src/messages.json | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/messages.json b/src/messages.json index 71c914ff..9d786a35 100644 --- a/src/messages.json +++ b/src/messages.json @@ -14,7 +14,6 @@ "ActionsMenuItem.command.loop": "Loop", "ActionsMenuItem.command.right45": "Turn right 45 degrees", "ActionsMenuItem.command.right90": "Turn right 90 degrees", - "ActionsMenuItem.unusedItemToggleLabel": "{action}", "ActionsMenuItem.usedItemToggleLabel": "(Used)", "ActionsSimplificationModal.cancel": "Cancel", "ActionsSimplificationModal.save": "Save", @@ -64,14 +63,9 @@ "Announcement.startLoop": "loop {loopLabel}", "App.appHeading": "Weavly", "App.appHeading.link": "Weavly, learn more about Weavly at Weavly dot org", - "App.blockMode": "Block", - "App.changeMode": "Change Mode", "App.connectToDash": "Connect to Dash", "App.privacyModalToggle": "Privacy", "App.privacyModalToggle.ariaLabel": "Weavly privacy policy", - "App.run": "Run", - "App.speechRecognition": "Speech Recognition", - "App.textMode": "Text", "AtlanticCanada.character": "Cape islander", "AtlanticCanada.fishProcessingPlant": "a fish processing plant", "AtlanticCanada.fogBank": "fog bank", @@ -152,8 +146,6 @@ "CommandInfo.previousStep.startLoop": "out of loop {loopLabel}", "CommandPalette.controlsTitle": "Controls", "CommandPalette.movementsTitle": "Movements", - "CommandPalette.shortMovementsTitle": "Move", - "CommandPalette.soundsTitle": "Sounds", "ConfirmDeleteAllModal.cancelButton": "Cancel", "ConfirmDeleteAllModal.confirmButton": "Delete", "ConfirmDeleteAllModal.content": "Are you sure you want to delete all steps of your program?", @@ -416,7 +408,6 @@ "ProgramBlockEditor.toggleAddNodeExpandMode": "add node expanded mode", "ProgramSequence.heading": "Program Sequence", "ProgramSpeedController.slider": "Program play speed", - "ProgramTextEditor.programLabel": "Program:", "RefreshButton": "Refresh", "Savannah.alligator": "the Alligator", "Savannah.babyAlligator": "the Baby Alligator", @@ -539,7 +530,6 @@ "ActionsMenuItem.command.loop": "boucle", "ActionsMenuItem.command.right45": "tourner à droite 45 degrées", "ActionsMenuItem.command.right90": "tourner à droite 90 degrées", - "ActionsMenuItem.unusedItemToggleLabel": "{action}", "ActionsMenuItem.usedItemToggleLabel": "(utilisé)", "ActionsSimplificationModal.cancel": "annuler", "ActionsSimplificationModal.save": "sauvegarder", @@ -589,14 +579,9 @@ "Announcement.startLoop": "boucle {loopLabel}", "App.appHeading": "Weavly", "App.appHeading.link": "Weavly, en savoir plus sur Weavly a Weavly point org", - "App.blockMode": "bloc", - "App.changeMode": "changer de mode", "App.connectToDash": "Se connecter à Dash", "App.privacyModalToggle": "intimité", "App.privacyModalToggle.ariaLabel": "politique de confidentialité de Weavly", - "App.run": "Lancer", - "App.speechRecognition": "reconnaisance de la parole", - "App.textMode": "Texte", "AtlanticCanada.character": "Insulaire de Cap", "AtlanticCanada.fishProcessingPlant": "usine de transformation des poissons", "AtlanticCanada.fogBank": "banc de brouillard", @@ -677,8 +662,6 @@ "CommandInfo.previousStep.startLoop": "hors boucle {loopLabel}", "CommandPalette.controlsTitle": "contrôles", "CommandPalette.movementsTitle": "Mouvements", - "CommandPalette.shortMovementsTitle": "bouge", - "CommandPalette.soundsTitle": "sons", "ConfirmDeleteAllModal.cancelButton": "annuler", "ConfirmDeleteAllModal.confirmButton": "supprimer", "ConfirmDeleteAllModal.content": "êtes-vous sûr de voulair suprimer tous les étapes de ton programme?", @@ -941,7 +924,6 @@ "ProgramBlockEditor.toggleAddNodeExpandMode": "ajouter un note en mode développer", "ProgramSequence.heading": "vitesse de lecture du programme", "ProgramSpeedController.slider": "vitesse de lecture du programme", - "ProgramTextEditor.programLabel": "Logiciel:", "RefreshButton": "rafraîchir", "Savannah.alligator": "L'alligator", "Savannah.babyAlligator": "le bébé alligator", From 2eb4e2b89b9c19bd35c6c2e9fffd0b44cae7bd07 Mon Sep 17 00:00:00 2001 From: Daniel Cho Date: Fri, 23 Aug 2024 14:08:58 -0400 Subject: [PATCH 06/23] fix: replace redundant messages with common message --- src/ActionsSimplificationModal.js | 4 ++-- src/ConfirmDeleteAllModal.js | 2 +- src/KeyboardInputModal.js | 8 +++---- src/SoundOptionsModal.js | 8 +++---- src/ThemeSelector.js | 4 ++-- src/WorldSelector.js | 4 ++-- src/messages.json | 38 +++++++------------------------ 7 files changed, 23 insertions(+), 45 deletions(-) diff --git a/src/ActionsSimplificationModal.js b/src/ActionsSimplificationModal.js index c8f57552..33893ad2 100644 --- a/src/ActionsSimplificationModal.js +++ b/src/ActionsSimplificationModal.js @@ -54,14 +54,14 @@ class ActionsSimplificationModal extends React.Component diff --git a/src/KeyboardInputModal.js b/src/KeyboardInputModal.js index f8dbb1be..d766e578 100644 --- a/src/KeyboardInputModal.js +++ b/src/KeyboardInputModal.js @@ -182,13 +182,13 @@ class KeyboardInputModal extends React.Component
diff --git a/src/SoundOptionsModal.js b/src/SoundOptionsModal.js index 7df0dfcd..57822406 100644 --- a/src/SoundOptionsModal.js +++ b/src/SoundOptionsModal.js @@ -94,7 +94,7 @@ class SoundOptionsModal extends React.Component
- {this.props.intl.formatMessage({ id: 'SoundOptionsModal.toggleOff' })} + {this.props.intl.formatMessage({ id: 'Off' })}
- {this.props.intl.formatMessage({ id: 'SoundOptionsModal.toggleOn' })} + {this.props.intl.formatMessage({ id: 'On' })}
@@ -126,8 +126,8 @@ class SoundOptionsModal extends React.Component Date: Wed, 4 Sep 2024 10:36:51 -0400 Subject: [PATCH 07/23] fix: update privacy policy messages to be stored in localization file --- src/PrivacyModal.js | 94 +++++++++++++++++++-------------------------- src/messages.json | 31 +++++++++++++++ 2 files changed, 71 insertions(+), 54 deletions(-) diff --git a/src/PrivacyModal.js b/src/PrivacyModal.js index 0bd5edca..47a65251 100644 --- a/src/PrivacyModal.js +++ b/src/PrivacyModal.js @@ -42,107 +42,93 @@ class PrivacyModal extends React.Component {
-
Updated January 4th, 2024
+
{this.props.intl.formatMessage({ id: 'PrivacyModal.section010.Heading'})}

- At Weavly, we believe that privacy is a fundamental human right, and acknowledge how important - it is to our community—especially with regards to both children and parents. + {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block010'})}

-

This page explains:

+

{this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block020'})}

  • - What type of information we store on our website (http://create.weavly.org/) + {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.list010.item010'})}
  • - How that information is used and processed + {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.list010.item020'})}
  • - How we keep your information safe + {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.list010.item030'})}
-
What information does Weavly store?
+
{this.props.intl.formatMessage({ id: 'PrivacyModal.section020.Heading'})}

- As you use Weavly, we may store information on how Weavly is accessed and used by you. We store - the following information independently on every browser/device pair that you use Weavly on: + {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block010'})}

    -
  • Your prefered settings for display colour theme and keyboard shortcuts
  • -
  • Your visible set of action blocks on the action panel
  • -
  • Your selected background for the scene
  • -
  • Your created program
  • -
  • Any line that is drawn on the scene as a result of running your program
  • -
  • The last position of your character on the scene
  • -
  • The starting position of your character
  • -
  • The version of Weavly that was used
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item010'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item020'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item030'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item040'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item050'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item060'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item070'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item080'})}

- You can delete any information that Weavly has generated from your usage by clearing your - browser's cache and local storage. Check your browser's documentation for details. + {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block030'})}

-
How does Weavly use this information?
+
{this.props.intl.formatMessage({ id: 'PrivacyModal.section030.Heading'})}

- The generated information is kept in a local storage on your device to make your use of Weavly - more convenient: + {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block010'})}

  • - Your settings for the coding environment are stored so you don't have to adjust them every - time you launch Weavly + {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block020.list010.item010'})}
  • - If you happen to accidentally or intentionally close your browser, the coding environment - will be the same as when you left it for the next time you launch Weavly + {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block020.list010.item020'})}

- Although storing your information in the browser makes it convenient - for every time you access Weavly, it may cause problems on shared computers. As a result, - someone that uses the computer after you may be able to access your Weavly settings and program. + {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block030'})}

-
How do we keep your information safe?
+
{this.props.intl.formatMessage({ id: 'PrivacyModal.section040.Heading'})}
-

The security of your data is important to us, but please keep in mind that no method of - electronic storage is 100% secure. We currently use browser local storage to store the specified - data. The information is stored in the browser by domain (create.weavly.org) and only code - running from that domain may access it. Thus, other websites cannot access the data. However, - local storage is not encrypted on disk and someone with access to the device could get access to - the data.

+

{this.props.intl.formatMessage({ id: 'PrivacyModal.section040.block010'})}

-
Children's Privacy
+
{this.props.intl.formatMessage({ id: 'PrivacyModal.section050.Heading'})}
-

- We do not knowingly collect personally identifiable information from anyone under the age of 18. - If you are a parent or guardian and you have become aware that we have collected Personal Data - from your children without verification of parental consent, we can take steps to remove that - information from our servers. Please contact us. +

${this.props.intl.formatMessage({ id: 'PrivacyModal.contactUs' })}` } + )} + }>

-
Changes to This Privacy Policy
+
{this.props.intl.formatMessage({ id: 'PrivacyModal.section060.Heading'})}

- We may update our Privacy Policy from time to time. We will notify you of any changes by posting - the new Privacy Policy on this page. We will let you know of any changes becoming effective by - updating the “effective date” at the top of this Privacy Policy. You are advised to review this - Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when - they are posted on this page. + {this.props.intl.formatMessage({ id: 'PrivacyModal.section060.block010'})}

-
Contact Us
+
{this.props.intl.formatMessage({ id: 'PrivacyModal.section070.Heading'})}
-

- If you have any questions about this Privacy Policy, - please contact - us. +

${this.props.intl.formatMessage({ id: 'PrivacyModal.contactUs' })}` } + )} + }>

diff --git a/src/messages.json b/src/messages.json index e30c38bd..39a0fe47 100644 --- a/src/messages.json +++ b/src/messages.json @@ -392,6 +392,37 @@ "PlayButton.play": "Play", "PlayControls.heading": "Play Controls", "PrivacyModal.close": "Close", + "PrivacyModal.contactUs": "contact us", + "PrivacyModal.section010.Heading": "Updated January 4th, 2024", + "PrivacyModal.section010.block010": "At Weavly, we believe that privacy is a fundamental human right, and acknowledge how important it is to our community—especially with regards to both children and parents.", + "PrivacyModal.section010.block020": "This page explains:", + "PrivacyModal.section010.block030.list010.item010": "What type of information we store on our website (http://create.weavly.org/)", + "PrivacyModal.section010.block030.list010.item020": "How that information is used and processed", + "PrivacyModal.section010.block030.list010.item030": "How we keep your information safe", + "PrivacyModal.section020.Heading": "What information does Weavly store?", + "PrivacyModal.section020.block010": "As you use Weavly, we may store information on how Weavly is accessed and used by you. We store the following information independently on every browser/device pair that you use Weavly on:", + "PrivacyModal.section020.block020.list010.item010": "Your prefered settings for display colour theme and keyboard shortcuts", + "PrivacyModal.section020.block020.list010.item020": "Your visible set of action blocks on the action panel", + "PrivacyModal.section020.block020.list010.item030": "Your selected background for the scene", + "PrivacyModal.section020.block020.list010.item040": "Your created program", + "PrivacyModal.section020.block020.list010.item050": "Any line that is drawn on the scene as a result of running your program", + "PrivacyModal.section020.block020.list010.item060": "The last position of your character on the scene", + "PrivacyModal.section020.block020.list010.item070": "The starting position of your character", + "PrivacyModal.section020.block020.list010.item080": "The version of Weavly that was used", + "PrivacyModal.section020.block030": "You can delete any information that Weavly has generated from your usage by clearing your browser's cache and local storage. Check your browser's documentation for details.", + "PrivacyModal.section030.Heading": "How does Weavly use this information?", + "PrivacyModal.section030.block010": "The generated information is kept in a local storage on your device to make your use of Weavly more convenient:", + "PrivacyModal.section030.block020.list010.item010": "Your settings for the coding environment are stored so you don't have to adjust them every time you launch Weavly", + "PrivacyModal.section030.block020.list010.item020": "If you happen to accidentally or intentionally close your browser, the coding environment will be the same as when you left it for the next time you launch Weavly", + "PrivacyModal.section030.block030": "Although storing your information in the browser makes it convenient for every time you access Weavly, it may cause problems on shared computers. As a result, someone that uses the computer after you may be able to access your Weavly settings and program.", + "PrivacyModal.section040.Heading": "How do we keep your information safe?", + "PrivacyModal.section040.block010": "The security of your data is important to us, but please keep in mind that no method of electronic storage is 100% secure. We currently use browser local storage to store the specified data. The information is stored in the browser by domain (create.weavly.org) and only code running from that domain may access it. Thus, other websites cannot access the data. However, local storage is not encrypted on disk and someone with access to the device could get access to the data.", + "PrivacyModal.section050.Heading": "Children's Privacy", + "PrivacyModal.section050.block010": "We do not knowingly collect personally identifiable information from anyone under the age of 18. If you are a parent or guardian and you have become aware that we have collected Personal Data from your children without verification of parental consent, we can take steps to remove that information from our servers. Please {contactLink}", + "PrivacyModal.section060.Heading": "Changes to This Privacy Policy", + "PrivacyModal.section060.block010": "We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page. We will let you know of any changes becoming effective by updating the “effective date” at the top of this Privacy Policy. You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.", + "PrivacyModal.section070.Heading": "Contact Us", + "PrivacyModal.section070.block010": "If you have any questions about this Privacy Policy, please {contactLink}.", "PrivacyModal.title": "Weavly Privacy Policy", "ProgramBlockEditor.beginningBlock": "Add selected action {command} to the beginning of the program", "ProgramBlockEditor.betweenBlocks": "Add selected action {command} between position {prevCommand} and position {postCommand}", From feb9f1336a426751a80ecd0b888b2960c44e1bfc Mon Sep 17 00:00:00 2001 From: Daniel Cho Date: Wed, 4 Sep 2024 11:06:31 -0400 Subject: [PATCH 08/23] fix: simplify key for list items and fix lint issues --- src/PrivacyModal.js | 28 ++++++++++++++-------------- src/messages.json | 26 +++++++++++++------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/PrivacyModal.js b/src/PrivacyModal.js index 47a65251..5458e6fc 100644 --- a/src/PrivacyModal.js +++ b/src/PrivacyModal.js @@ -51,13 +51,13 @@ class PrivacyModal extends React.Component {
  • - {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.list010.item010'})} + {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.item010'})}
  • - {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.list010.item020'})} + {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.item020'})}
  • - {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.list010.item030'})} + {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.item030'})}
@@ -68,14 +68,14 @@ class PrivacyModal extends React.Component {

    -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item010'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item020'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item030'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item040'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item050'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item060'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item070'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.list010.item080'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item010'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item020'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item030'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item040'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item050'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item060'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item070'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item080'})}

@@ -90,10 +90,10 @@ class PrivacyModal extends React.Component {

  • - {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block020.list010.item010'})} + {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block020.item010'})}
  • - {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block020.list010.item020'})} + {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block020.item020'})}
@@ -128,7 +128,7 @@ class PrivacyModal extends React.Component { { id: 'PrivacyModal.section070.block010'}, { contactLink: `${this.props.intl.formatMessage({ id: 'PrivacyModal.contactUs' })}` } )} - }> + }>

diff --git a/src/messages.json b/src/messages.json index 39a0fe47..4622123f 100644 --- a/src/messages.json +++ b/src/messages.json @@ -396,24 +396,24 @@ "PrivacyModal.section010.Heading": "Updated January 4th, 2024", "PrivacyModal.section010.block010": "At Weavly, we believe that privacy is a fundamental human right, and acknowledge how important it is to our community—especially with regards to both children and parents.", "PrivacyModal.section010.block020": "This page explains:", - "PrivacyModal.section010.block030.list010.item010": "What type of information we store on our website (http://create.weavly.org/)", - "PrivacyModal.section010.block030.list010.item020": "How that information is used and processed", - "PrivacyModal.section010.block030.list010.item030": "How we keep your information safe", + "PrivacyModal.section010.block030.item010": "What type of information we store on our website (http://create.weavly.org/)", + "PrivacyModal.section010.block030.item020": "How that information is used and processed", + "PrivacyModal.section010.block030.item030": "How we keep your information safe", "PrivacyModal.section020.Heading": "What information does Weavly store?", "PrivacyModal.section020.block010": "As you use Weavly, we may store information on how Weavly is accessed and used by you. We store the following information independently on every browser/device pair that you use Weavly on:", - "PrivacyModal.section020.block020.list010.item010": "Your prefered settings for display colour theme and keyboard shortcuts", - "PrivacyModal.section020.block020.list010.item020": "Your visible set of action blocks on the action panel", - "PrivacyModal.section020.block020.list010.item030": "Your selected background for the scene", - "PrivacyModal.section020.block020.list010.item040": "Your created program", - "PrivacyModal.section020.block020.list010.item050": "Any line that is drawn on the scene as a result of running your program", - "PrivacyModal.section020.block020.list010.item060": "The last position of your character on the scene", - "PrivacyModal.section020.block020.list010.item070": "The starting position of your character", - "PrivacyModal.section020.block020.list010.item080": "The version of Weavly that was used", + "PrivacyModal.section020.block020.item010": "Your prefered settings for display colour theme and keyboard shortcuts", + "PrivacyModal.section020.block020.item020": "Your visible set of action blocks on the action panel", + "PrivacyModal.section020.block020.item030": "Your selected background for the scene", + "PrivacyModal.section020.block020.item040": "Your created program", + "PrivacyModal.section020.block020.item050": "Any line that is drawn on the scene as a result of running your program", + "PrivacyModal.section020.block020.item060": "The last position of your character on the scene", + "PrivacyModal.section020.block020.item070": "The starting position of your character", + "PrivacyModal.section020.block020.item080": "The version of Weavly that was used", "PrivacyModal.section020.block030": "You can delete any information that Weavly has generated from your usage by clearing your browser's cache and local storage. Check your browser's documentation for details.", "PrivacyModal.section030.Heading": "How does Weavly use this information?", "PrivacyModal.section030.block010": "The generated information is kept in a local storage on your device to make your use of Weavly more convenient:", - "PrivacyModal.section030.block020.list010.item010": "Your settings for the coding environment are stored so you don't have to adjust them every time you launch Weavly", - "PrivacyModal.section030.block020.list010.item020": "If you happen to accidentally or intentionally close your browser, the coding environment will be the same as when you left it for the next time you launch Weavly", + "PrivacyModal.section030.block020.item010": "Your settings for the coding environment are stored so you don't have to adjust them every time you launch Weavly", + "PrivacyModal.section030.block020.item020": "If you happen to accidentally or intentionally close your browser, the coding environment will be the same as when you left it for the next time you launch Weavly", "PrivacyModal.section030.block030": "Although storing your information in the browser makes it convenient for every time you access Weavly, it may cause problems on shared computers. As a result, someone that uses the computer after you may be able to access your Weavly settings and program.", "PrivacyModal.section040.Heading": "How do we keep your information safe?", "PrivacyModal.section040.block010": "The security of your data is important to us, but please keep in mind that no method of electronic storage is 100% secure. We currently use browser local storage to store the specified data. The information is stored in the browser by domain (create.weavly.org) and only code running from that domain may access it. Thus, other websites cannot access the data. However, local storage is not encrypted on disk and someone with access to the device could get access to the data.", From b93ef725b9b72719fa365980f38c045c1fb23a14 Mon Sep 17 00:00:00 2001 From: Daniel Cho Date: Mon, 23 Sep 2024 09:11:51 -0400 Subject: [PATCH 09/23] fix: format the messages --- src/PrivacyModal.js | 44 +++++++++++--------------------------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/src/PrivacyModal.js b/src/PrivacyModal.js index 5458e6fc..34b70dcf 100644 --- a/src/PrivacyModal.js +++ b/src/PrivacyModal.js @@ -44,28 +44,18 @@ class PrivacyModal extends React.Component {
{this.props.intl.formatMessage({ id: 'PrivacyModal.section010.Heading'})}
-

- {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block010'})} -

+

{this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block010'})}

{this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block020'})}

    -
  • - {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.item010'})} -
  • -
  • - {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.item020'})} -
  • -
  • - {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.item030'})} -
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.item010'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.item020'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.item030'})}
{this.props.intl.formatMessage({ id: 'PrivacyModal.section020.Heading'})}
-

- {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block010'})} -

+

{this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block010'})}

  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item010'})}
  • @@ -78,28 +68,18 @@ class PrivacyModal extends React.Component {
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item080'})}
-

- {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block030'})} -

+

{this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block030'})}

{this.props.intl.formatMessage({ id: 'PrivacyModal.section030.Heading'})}
-

- {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block010'})} -

+

{this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block010'})}

    -
  • - {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block020.item010'})} -
  • -
  • - {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block020.item020'})} -
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block020.item010'})}
  • +
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block020.item020'})}
-

- {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block030'})} -

+

{this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block030'})}

{this.props.intl.formatMessage({ id: 'PrivacyModal.section040.Heading'})}
@@ -117,9 +97,7 @@ class PrivacyModal extends React.Component {
{this.props.intl.formatMessage({ id: 'PrivacyModal.section060.Heading'})}
-

- {this.props.intl.formatMessage({ id: 'PrivacyModal.section060.block010'})} -

+

{this.props.intl.formatMessage({ id: 'PrivacyModal.section060.block010'})}

{this.props.intl.formatMessage({ id: 'PrivacyModal.section070.Heading'})}
From 5045736adf6ffcddeff1bcd56d05c8c25e301243 Mon Sep 17 00:00:00 2001 From: Daniel Cho Date: Mon, 23 Sep 2024 09:13:12 -0400 Subject: [PATCH 10/23] fix: combine messages for the command replacement and move to next/previous --- src/ActionPanel.js | 116 +++++++++++++++++++++++++--------------- src/ActionPanel.test.js | 14 ++--- src/messages.json | 26 +++++---- 3 files changed, 91 insertions(+), 65 deletions(-) diff --git a/src/ActionPanel.js b/src/ActionPanel.js index 109264b0..6f42b9c8 100644 --- a/src/ActionPanel.js +++ b/src/ActionPanel.js @@ -54,26 +54,21 @@ class ActionPanel extends React.Component { ); } - let selectedCommandName = ''; - if (this.props.selectedCommandName != null) { - selectedCommandName = this.props.intl.formatMessage( - { id: 'ActionPanel.selectedCommandName' }, - { selectedCommandName: - this.props.intl.formatMessage({id: `Command.${this.props.selectedCommandName}`}) - } - ); - } + let selectedCommandName = this.props.selectedCommandName != null ? + this.props.intl.formatMessage({id: `Command.${this.props.selectedCommandName}`}) : ''; + + console.log(this.makePreviousStepAriaLabel(stepNumber, stepName)); return { 'stepNumber': stepNumber, 'stepName': stepName, 'selectedCommandName': selectedCommandName, - 'previousStepInfo': this.makePreviousStepInfo(), - 'nextStepInfo': this.makeNextStepInfo() - }; + 'previousStepAriaLabel': this.makePreviousStepAriaLabel(stepNumber, stepName), + 'nextStepAriaLabel': this.makeNextStepAriaLabel(stepNumber, stepName) + } } - makePreviousStepInfo(): ?string { + makePreviousStepAriaLabel(stepNumber: ?number | string, stepName: string): string { const currentStep = this.props.programSequence.getProgramStepAt(this.props.pressedStepIndex); if (this.props.pressedStepIndex > 0) { const prevStep = this.props.programSequence.getProgramStepAt(this.props.pressedStepIndex - 1); @@ -81,15 +76,21 @@ class ActionPanel extends React.Component { const prevStepName = prevStep.block; // When previous step is startLoop, aria-label communicates that movePrevious will move out of the current loop if (prevStepName === 'startLoop' && currentStep.block !== 'endLoop') { - return this.props.intl.formatMessage( - { id: 'CommandInfo.previousStep.startLoop' }, - { loopLabel: prevStep.label } + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.startLoop'}, + { + stepNumber, + stepName, + loopLabel: prevStep.label + } ); // When previous step is endLoop, aria-label communicates that movePrevious will move into a loop } else if (prevStepName === 'endLoop') { - return this.props.intl.formatMessage( - { id: 'CommandInfo.previousStep.endLoop'}, - { loopLabel: prevStep.label } + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.endLoop'}, + { + stepNumber, + stepName, + loopLabel: prevStep.label + } ); } else { // When previous step is not loops and current step is endLoop, calculate the index the loop will move by @@ -98,11 +99,12 @@ class ActionPanel extends React.Component { const startLoopIndex = this.props.programSequence.getMatchingLoopBlockIndex(this.props.pressedStepIndex); const program = this.props.programSequence.getProgram(); if (startLoopIndex != null && program[startLoopIndex - 1] != null) { - return this.props.intl.formatMessage( - { id: 'CommandInfo.previousStep.loop' }, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.command'}, { + stepNumber, + stepName, previousStepNumber: startLoopIndex, - command: this.props.intl.formatMessage({id: `Command.${program[startLoopIndex - 1].block}`}) + command: this.props.intl.formatMessage({id: `Command.${program[startLoopIndex - 1].block}`}), } ) } @@ -110,19 +112,21 @@ class ActionPanel extends React.Component { } else if (cachedPreviousStepLoopData != null && cachedPreviousStepLoopData.get('containingLoopPosition') != null && cachedPreviousStepLoopData.get('containingLoopLabel') != null) { - return this.props.intl.formatMessage( - { id: 'CommandInfo.previousStep.inLoop'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.inLoop'}, { + stepNumber, + stepName, previousStepNumber: cachedPreviousStepLoopData.get('containingLoopPosition'), command: this.props.intl.formatMessage({id: `Command.${prevStepName}`}), - loopLabel: cachedPreviousStepLoopData.get('containingLoopLabel') + loopLabel: cachedPreviousStepLoopData.get('containingLoopLabel'), } ) // When previous step is a movements step and not in a loop, aria-label communicates position within the program } else { - return this.props.intl.formatMessage( - { id: 'CommandInfo.previousStep'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.command'}, { + stepNumber, + stepName, previousStepNumber: this.props.pressedStepIndex, command: this.props.intl.formatMessage({id: `Command.${prevStepName}`}) } @@ -130,9 +134,15 @@ class ActionPanel extends React.Component { } } } + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep'}, + { + stepNumber, + stepName + } + ); } - makeNextStepInfo(): ?string { + makeNextStepAriaLabel(stepNumber: ?number | string, stepName: string): string { const currentStep = this.props.programSequence.getProgramStepAt(this.props.pressedStepIndex); if (this.props.pressedStepIndex < (this.props.programSequence.getProgramLength() - 1)) { const nextStep = this.props.programSequence.getProgramStepAt(this.props.pressedStepIndex + 1); @@ -140,15 +150,21 @@ class ActionPanel extends React.Component { const nextStepName = nextStep.block; // When next step is startLoop, aria-label communicates that moveNext will move into a loop if (nextStepName === 'startLoop') { - return this.props.intl.formatMessage( - { id: 'CommandInfo.nextStep.startLoop'}, - { loopLabel: nextStep.label } + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.startLoop'}, + { + stepNumber, + stepName, + loopLabel: nextStep.label + } ); // When next step is endLoop, aria-label communicates that moveNext will move out of the current loop } else if (nextStepName === 'endLoop' && currentStep.block !== 'startLoop') { - return this.props.intl.formatMessage( - { id: 'CommandInfo.nextStep.endLoop'}, - { loopLabel: nextStep.label } + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.endLoop'}, + { + stepNumber, + stepName, + loopLabel: nextStep.label + } ); } else { // When next step is not loops and current step is startLoop, calculate the index the loop will move by @@ -157,11 +173,12 @@ class ActionPanel extends React.Component { const endLoopIndex = this.props.programSequence.getMatchingLoopBlockIndex(this.props.pressedStepIndex); const program = this.props.programSequence.getProgram(); if (endLoopIndex != null && program[endLoopIndex + 1] != null) { - return this.props.intl.formatMessage( - { id: 'CommandInfo.nextStep.loop' }, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.command'}, { + stepNumber, + stepName, nextStepNumber: endLoopIndex + 2, - command: this.props.intl.formatMessage({id: `Command.${program[endLoopIndex + 1].block}`}) + command: this.props.intl.formatMessage({id: `Command.${program[endLoopIndex + 1].block}`}), } ); } @@ -169,9 +186,10 @@ class ActionPanel extends React.Component { } else if (cachedNextStepLoopData != null && cachedNextStepLoopData.get('containingLoopPosition') != null && cachedNextStepLoopData.get('containingLoopLabel') != null) { - return this.props.intl.formatMessage( - { id: 'CommandInfo.nextStep.inLoop'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.inLoop'}, { + stepNumber, + stepName, nextStepNumber: cachedNextStepLoopData.get('containingLoopPosition'), command: this.props.intl.formatMessage({id: `Command.${nextStepName}`}), loopLabel: cachedNextStepLoopData.get('containingLoopLabel') @@ -179,9 +197,10 @@ class ActionPanel extends React.Component { ); // When next step is a movements step and not in a loop, aria-label communicates position within the program } else { - return this.props.intl.formatMessage( - { id: 'CommandInfo.nextStep'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.command'}, { + stepNumber, + stepName, nextStepNumber: this.props.pressedStepIndex + 2, command: this.props.intl.formatMessage({id: `Command.${nextStep.block}`}) } @@ -189,6 +208,12 @@ class ActionPanel extends React.Component { } } } + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep'}, + { + stepNumber, + stepName + } + ); } getReplaceIsVisible(): boolean { @@ -219,6 +244,9 @@ class ActionPanel extends React.Component { const moveToPreviousStepIsDisabled = this.props.programSequence.moveToPreviousStepDisabled(this.props.pressedStepIndex); const replaceIsVisible = this.getReplaceIsVisible(); const replaceIsDisabled = this.props.selectedCommandName == null; + const replaceMessage = replaceIsDisabled ? + this.props.intl.formatMessage({id:'ActionPanel.action.replace.noAction'}, stepMessageData) : + this.props.intl.formatMessage({id:'ActionPanel.action.replace.withAction'}, stepMessageData); return (
@@ -245,7 +273,7 @@ class ActionPanel extends React.Component { name='replaceCurrentStep' disabled={replaceIsDisabled} disabledClassName='ActionPanel__action-buttons--disabled' - aria-label={this.props.intl.formatMessage({id:'ActionPanel.action.replace'}, stepMessageData)} + aria-label={replaceMessage} className='ActionPanel__action-buttons focus-trap-action-panel__action-panel-button' onClick={this.handleClickReplace}> { name='moveToPreviousStep' disabled={moveToPreviousStepIsDisabled} disabledClassName='ActionPanel__action-buttons--disabled' - aria-label={this.props.intl.formatMessage({id:'ActionPanel.action.moveToPreviousStep'}, stepMessageData)} + aria-label={stepMessageData.previousStepAriaLabel} className='ActionPanel__action-buttons focus-trap-action-panel__action-panel-button' onClick={this.handleClickMoveToPreviousStep}> { name='moveToNextStep' disabled={moveToNextStepIsDisabled} disabledClassName='ActionPanel__action-buttons--disabled' - aria-label={this.props.intl.formatMessage({id:'ActionPanel.action.moveToNextStep'}, stepMessageData)} + aria-label={stepMessageData.nextStepAriaLabel} className='ActionPanel__action-buttons focus-trap-action-panel__action-panel-button' onClick={this.handleClickMoveToNextStep}> { selectedCommandName: null }); const replaceButton = getActionPanelOptionButtons(wrapper, 'replaceCurrentStep'); - const expectedAriaLabel = 'Replace Step 2 turn left 45 degrees '; + const expectedAriaLabel = 'Replace Step 2 turn left 45 degrees'; expect(replaceButton.get(0).props['aria-label']).toBe(expectedAriaLabel); expect(replaceButton.get(0).props['disabled']).toBe(true); }); @@ -126,7 +126,7 @@ describe('ActionPanel options', () => { pressedStepIndex: 0 }); const moveToPreviousStepButton = getActionPanelOptionButtons(wrapper, 'moveToPreviousStep'); - const expectedAriaLabel = 'Move Step 1 forward 1 square '; + const expectedAriaLabel = 'Move Step 1 forward 1 square'; expect(moveToPreviousStepButton.get(0).props['aria-label']).toBe(expectedAriaLabel); expect(moveToPreviousStepButton.get(0).props['disabled']).toBe(true); moveToPreviousStepButton.simulate('click'); @@ -149,7 +149,7 @@ describe('ActionPanel options', () => { pressedStepIndex: 0 }); const moveToPreviousStepButton = getActionPanelOptionButtons(wrapper, 'moveToPreviousStep'); - const expectedAriaLabel = "Move Step 1 loop A "; + const expectedAriaLabel = "Move Step 1 loop A"; expect(moveToPreviousStepButton.get(0).props['disabled']).toBe(true); moveToPreviousStepButton.simulate('click'); expect(moveToPreviousStepButton.get(0).props['aria-label']).toBe(expectedAriaLabel); @@ -172,7 +172,7 @@ describe('ActionPanel options', () => { pressedStepIndex: 2 }); const moveToPreviousStepButton = getActionPanelOptionButtons(wrapper, 'moveToPreviousStep'); - const expectedAriaLabel = "Move Step 3 loop A "; + const expectedAriaLabel = "Move Step 3 loop A"; expect(moveToPreviousStepButton.get(0).props['disabled']).toBe(true); moveToPreviousStepButton.simulate('click'); expect(moveToPreviousStepButton.get(0).props['aria-label']).toBe(expectedAriaLabel); @@ -336,7 +336,7 @@ describe('ActionPanel options', () => { pressedStepIndex: 2 }); const moveToNextStepButton = getActionPanelOptionButtons(wrapper, 'moveToNextStep'); - const expectedAriaLabel = 'Move Step 3 turn right 45 degrees '; + const expectedAriaLabel = 'Move Step 3 turn right 45 degrees'; expect(moveToNextStepButton.get(0).props['aria-label']).toBe(expectedAriaLabel); expect(moveToNextStepButton.get(0).props['disabled']).toBe(true); moveToNextStepButton.simulate('click'); @@ -359,7 +359,7 @@ describe('ActionPanel options', () => { pressedStepIndex: 0 }); const moveToNextStepButton = getActionPanelOptionButtons(wrapper, 'moveToNextStep'); - const expectedAriaLabel = "Move Step 1 loop A "; + const expectedAriaLabel = "Move Step 1 loop A"; expect(moveToNextStepButton.get(0).props['disabled']).toBe(true); moveToNextStepButton.simulate('click'); expect(moveToNextStepButton.get(0).props['aria-label']).toBe(expectedAriaLabel); @@ -382,7 +382,7 @@ describe('ActionPanel options', () => { pressedStepIndex: 2 }); const moveToNextStepButton = getActionPanelOptionButtons(wrapper, 'moveToNextStep'); - const expectedAriaLabel = "Move Step 3 loop A "; + const expectedAriaLabel = "Move Step 3 loop A"; expect(moveToNextStepButton.get(0).props['disabled']).toBe(true); moveToNextStepButton.simulate('click'); expect(moveToNextStepButton.get(0).props['aria-label']).toBe(expectedAriaLabel); diff --git a/src/messages.json b/src/messages.json index 4622123f..a319efbb 100644 --- a/src/messages.json +++ b/src/messages.json @@ -1,10 +1,18 @@ { "en": { "ActionPanel.action.delete": "Delete Step {stepNumber} {stepName}", - "ActionPanel.action.moveToNextStep": "Move Step {stepNumber} {stepName} {nextStepInfo}", - "ActionPanel.action.moveToPreviousStep": "Move Step {stepNumber} {stepName} {previousStepInfo}", - "ActionPanel.action.replace": "Replace Step {stepNumber} {stepName} {selectedCommandName}", - "ActionPanel.selectedCommandName": "with selected action {selectedCommandName}", + "ActionPanel.action.moveToNextStep": "Move Step {stepNumber} {stepName}", + "ActionPanel.action.moveToNextStep.command": "Move Step {stepNumber} {stepName} after step {nextStepNumber} {command}", + "ActionPanel.action.moveToNextStep.endLoop": "Move Step {stepNumber} {stepName} out of loop {loopLabel}", + "ActionPanel.action.moveToNextStep.inLoop": "Move Step {stepNumber} {stepName} after step {nextStepNumber} {command} of loop {loopLabel}", + "ActionPanel.action.moveToNextStep.startLoop": "Move Step {stepNumber} {stepName} into loop {loopLabel}", + "ActionPanel.action.moveToPreviousStep": "Move Step {stepNumber} {stepName}", + "ActionPanel.action.moveToPreviousStep.command": "Move Step {stepNumber} {stepName} before step {previousStepNumber} {command}", + "ActionPanel.action.moveToPreviousStep.endLoop": "Move Step {stepNumber} {stepName} into loop {loopLabel}", + "ActionPanel.action.moveToPreviousStep.inLoop": "Move Step {stepNumber} {stepName} before step {previousStepNumber} {command} of loop {loopLabel}", + "ActionPanel.action.moveToPreviousStep.startLoop": "Move Step {stepNumber} {stepName} out of loop {loopLabel}", + "ActionPanel.action.replace.noAction": "Replace Step {stepNumber} {stepName}", + "ActionPanel.action.replace.withAction": "Replace Step {stepNumber} {stepName} with selected action {selectedCommandName}", "ActionsMenu.title": "Actions", "ActionsMenu.toggleActionsMenu": "configure available actions", "ActionsMenuItem.command.backward1": "Move backward 1 step", @@ -133,16 +141,6 @@ "Command.right45": "turn right 45 degrees", "Command.right90": "turn right 90 degrees", "Command.startLoop": "beginning of loop {loopLabel}", - "CommandInfo.nextStep": "after step {nextStepNumber} {command}", - "CommandInfo.nextStep.endLoop": "out of loop {loopLabel}", - "CommandInfo.nextStep.inLoop": "after step {nextStepNumber} {command} of loop {loopLabel}", - "CommandInfo.nextStep.loop": "after step {nextStepNumber} {command}", - "CommandInfo.nextStep.startLoop": "into loop {loopLabel}", - "CommandInfo.previousStep": "before step {previousStepNumber} {command}", - "CommandInfo.previousStep.endLoop": "into loop {loopLabel}", - "CommandInfo.previousStep.inLoop": "before step {previousStepNumber} {command} of loop {loopLabel}", - "CommandInfo.previousStep.loop": "before step {previousStepNumber} {command}", - "CommandInfo.previousStep.startLoop": "out of loop {loopLabel}", "CommandPalette.controlsTitle": "Controls", "CommandPalette.movementsTitle": "Movements", "ConfirmDeleteAllModal.confirmButton": "Delete", From 6ef7e445272fdcce45c46db58e65445659214db7 Mon Sep 17 00:00:00 2001 From: Daniel Cho Date: Mon, 23 Sep 2024 09:18:23 -0400 Subject: [PATCH 11/23] fix: lint issues --- src/ActionPanel.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/ActionPanel.js b/src/ActionPanel.js index 6f42b9c8..cb007faa 100644 --- a/src/ActionPanel.js +++ b/src/ActionPanel.js @@ -54,11 +54,9 @@ class ActionPanel extends React.Component { ); } - let selectedCommandName = this.props.selectedCommandName != null ? + const selectedCommandName = this.props.selectedCommandName != null ? this.props.intl.formatMessage({id: `Command.${this.props.selectedCommandName}`}) : ''; - console.log(this.makePreviousStepAriaLabel(stepNumber, stepName)); - return { 'stepNumber': stepNumber, 'stepName': stepName, @@ -77,7 +75,7 @@ class ActionPanel extends React.Component { // When previous step is startLoop, aria-label communicates that movePrevious will move out of the current loop if (prevStepName === 'startLoop' && currentStep.block !== 'endLoop') { return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.startLoop'}, - { + { stepNumber, stepName, loopLabel: prevStep.label @@ -244,7 +242,7 @@ class ActionPanel extends React.Component { const moveToPreviousStepIsDisabled = this.props.programSequence.moveToPreviousStepDisabled(this.props.pressedStepIndex); const replaceIsVisible = this.getReplaceIsVisible(); const replaceIsDisabled = this.props.selectedCommandName == null; - const replaceMessage = replaceIsDisabled ? + const replaceMessage = replaceIsDisabled ? this.props.intl.formatMessage({id:'ActionPanel.action.replace.noAction'}, stepMessageData) : this.props.intl.formatMessage({id:'ActionPanel.action.replace.withAction'}, stepMessageData); return ( From c2e70da697ebcae5a8cc1232727414c3236ee5ae Mon Sep 17 00:00:00 2001 From: Daniel Cho Date: Mon, 23 Sep 2024 12:59:09 -0400 Subject: [PATCH 12/23] fix: separate step numbers and step names from add node aria label --- src/ProgramBlockEditor.js | 10 ++++++---- src/messages.json | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ProgramBlockEditor.js b/src/ProgramBlockEditor.js index cfbfe8e9..1400f4df 100644 --- a/src/ProgramBlockEditor.js +++ b/src/ProgramBlockEditor.js @@ -557,15 +557,17 @@ export class ProgramBlockEditor extends React.Component Date: Mon, 23 Sep 2024 13:01:29 -0400 Subject: [PATCH 13/23] fix: return aria labels for ActionPanel in a method --- src/ActionPanel.js | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/ActionPanel.js b/src/ActionPanel.js index cb007faa..fbbc76c2 100644 --- a/src/ActionPanel.js +++ b/src/ActionPanel.js @@ -33,7 +33,7 @@ class ActionPanel extends React.Component { this.actionPanelRef = React.createRef(); } - makeStepMessageData() { + makeAriaLabels() { const currentStep = this.props.programSequence.getProgramStepAt(this.props.pressedStepIndex); let stepNumber = this.props.pressedStepIndex + 1; @@ -54,13 +54,16 @@ class ActionPanel extends React.Component { ); } - const selectedCommandName = this.props.selectedCommandName != null ? - this.props.intl.formatMessage({id: `Command.${this.props.selectedCommandName}`}) : ''; + const replaceStepAriaLabel = this.props.selectedCommandName != null ? + this.props.intl.formatMessage( + {id:'ActionPanel.action.replace.withAction'}, + { stepNumber, stepName, selectedCommandName: this.props.intl.formatMessage({id: `Command.${this.props.selectedCommandName}`}) } + ) : + this.props.intl.formatMessage({id:'ActionPanel.action.replace.noAction'}, { stepNumber, stepName }); return { - 'stepNumber': stepNumber, - 'stepName': stepName, - 'selectedCommandName': selectedCommandName, + replaceStepAriaLabel, + 'deleteStepAriaLabel': this.props.intl.formatMessage({id:'ActionPanel.action.delete'}, { stepNumber, stepName }), 'previousStepAriaLabel': this.makePreviousStepAriaLabel(stepNumber, stepName), 'nextStepAriaLabel': this.makeNextStepAriaLabel(stepNumber, stepName) } @@ -237,14 +240,12 @@ class ActionPanel extends React.Component { }; render() { - const stepMessageData = this.makeStepMessageData(); + const ariaLabels = this.makeAriaLabels(); const moveToNextStepIsDisabled = this.props.programSequence.moveToNextStepDisabled(this.props.pressedStepIndex); const moveToPreviousStepIsDisabled = this.props.programSequence.moveToPreviousStepDisabled(this.props.pressedStepIndex); const replaceIsVisible = this.getReplaceIsVisible(); const replaceIsDisabled = this.props.selectedCommandName == null; - const replaceMessage = replaceIsDisabled ? - this.props.intl.formatMessage({id:'ActionPanel.action.replace.noAction'}, stepMessageData) : - this.props.intl.formatMessage({id:'ActionPanel.action.replace.withAction'}, stepMessageData); + return (
@@ -258,7 +259,7 @@ class ActionPanel extends React.Component { { name='replaceCurrentStep' disabled={replaceIsDisabled} disabledClassName='ActionPanel__action-buttons--disabled' - aria-label={replaceMessage} + aria-label={ariaLabels.replaceStepAriaLabel} className='ActionPanel__action-buttons focus-trap-action-panel__action-panel-button' onClick={this.handleClickReplace}> { name='moveToPreviousStep' disabled={moveToPreviousStepIsDisabled} disabledClassName='ActionPanel__action-buttons--disabled' - aria-label={stepMessageData.previousStepAriaLabel} + aria-label={ariaLabels.previousStepAriaLabel} className='ActionPanel__action-buttons focus-trap-action-panel__action-panel-button' onClick={this.handleClickMoveToPreviousStep}> { name='moveToNextStep' disabled={moveToNextStepIsDisabled} disabledClassName='ActionPanel__action-buttons--disabled' - aria-label={stepMessageData.nextStepAriaLabel} + aria-label={ariaLabels.nextStepAriaLabel} className='ActionPanel__action-buttons focus-trap-action-panel__action-panel-button' onClick={this.handleClickMoveToNextStep}> Date: Mon, 30 Sep 2024 09:47:16 -0400 Subject: [PATCH 14/23] fix: update messages placeholders --- src/ActionPanel.js | 88 +++++++-------- src/ActionPanel.test.js | 4 +- src/AnnouncementBuilder.js | 32 +++--- src/AnnouncementBuilder.test.js | 32 +++--- src/App.js | 4 +- src/App.test.js | 6 +- src/CharacterAriaLive.js | 2 +- src/CharacterDescriptionBuilder.js | 2 +- src/CommandPaletteCommand.js | 4 +- src/CommandPaletteCommand.test.js | 12 +- src/DesignModeCursorDescriptionBuilder.js | 2 +- src/KeyboardInputModal.js | 2 +- src/ProgramBlockEditor.js | 30 ++--- src/ProgramChangeController.test.js | 60 +++++----- src/Scene.js | 10 +- src/messages.json | 129 +++++++++++----------- 16 files changed, 209 insertions(+), 210 deletions(-) diff --git a/src/ActionPanel.js b/src/ActionPanel.js index 0a718cdf..e85cf5b6 100644 --- a/src/ActionPanel.js +++ b/src/ActionPanel.js @@ -15,7 +15,7 @@ import './ActionPanel.scss'; type ActionPanelProps = { focusedOptionName: ?string, - selectedCommandName: ?string, + selectedActionName: ?string, programSequence: ProgramSequence, pressedStepIndex: number, intl: IntlShape, @@ -42,53 +42,53 @@ class ActionPanel extends React.Component { stepNumber = cachedCurrentStepLoopData.getContainingLoopPosition(); } - let stepName = ''; + let stepActionName = ''; if (currentStep.block === 'startLoop' || currentStep.block === 'endLoop') { - stepName = this.props.intl.formatMessage( + stepActionName = this.props.intl.formatMessage( { id: 'Command.loop.label' }, { loopLabel: currentStep.label } ); } else { - stepName = this.props.intl.formatMessage( + stepActionName = this.props.intl.formatMessage( { id: `Command.${currentStep.block}` } ); } - const replaceStepAriaLabel = this.props.selectedCommandName != null ? + const replaceStepAriaLabel = this.props.selectedActionName != null ? this.props.intl.formatMessage( - {id:'ActionPanel.action.replace.withAction'}, - { stepNumber, stepName, selectedCommandName: this.props.intl.formatMessage({id: `Command.${this.props.selectedCommandName}`}) } + {id:'ActionPanel.action.replace.withSelectedAction'}, + { stepNumber, stepActionName, selectedActionName: this.props.intl.formatMessage({id: `Command.${this.props.selectedActionName}`}) } ) : - this.props.intl.formatMessage({id:'ActionPanel.action.replace.noAction'}, { stepNumber, stepName }); + this.props.intl.formatMessage({id:'ActionPanel.action.replace.noSelectedAction'}, { stepNumber, stepActionName }); return { replaceStepAriaLabel, - 'deleteStepAriaLabel': this.props.intl.formatMessage({id:'ActionPanel.action.delete'}, { stepNumber, stepName }), - 'previousStepAriaLabel': this.makePreviousStepAriaLabel(stepNumber, stepName), - 'nextStepAriaLabel': this.makeNextStepAriaLabel(stepNumber, stepName) + 'deleteStepAriaLabel': this.props.intl.formatMessage({id:'ActionPanel.action.delete'}, { stepNumber, stepActionName }), + 'previousStepAriaLabel': this.makePreviousStepAriaLabel(stepNumber, stepActionName), + 'nextStepAriaLabel': this.makeNextStepAriaLabel(stepNumber, stepActionName) } } - makePreviousStepAriaLabel(stepNumber: ?number | string, stepName: string): string { + makePreviousStepAriaLabel(stepNumber: ?number | string, stepActionName: string): string { const currentStep = this.props.programSequence.getProgramStepAt(this.props.pressedStepIndex); if (this.props.pressedStepIndex > 0) { const prevStep = this.props.programSequence.getProgramStepAt(this.props.pressedStepIndex - 1); const cachedPreviousStepLoopData = prevStep.cache; // When previous step is startLoop, aria-label communicates that movePrevious will move out of the current loop if (prevStep.block === 'startLoop' && currentStep.block !== 'endLoop') { - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.startLoop'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.outOfLoop'}, { stepNumber, - stepName, + stepActionName, loopLabel: prevStep.label } ); // When previous step is endLoop, aria-label communicates that movePrevious will move into a loop } else if (prevStep.block === 'endLoop') { - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.endLoop'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.intoLoop'}, { stepNumber, - stepName, + stepActionName, loopLabel: prevStep.label } ); @@ -99,67 +99,67 @@ class ActionPanel extends React.Component { const startLoopIndex = this.props.programSequence.getMatchingLoopBlockIndex(this.props.pressedStepIndex); const program = this.props.programSequence.getProgram(); if (startLoopIndex != null && program[startLoopIndex - 1] != null) { - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.command'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep'}, { stepNumber, - stepName, + stepActionName, previousStepNumber: startLoopIndex, - command: this.props.intl.formatMessage({id: `Command.${program[startLoopIndex - 1].block}`}), + previousStepActionName: this.props.intl.formatMessage({id: `Command.${program[startLoopIndex - 1].block}`}), } ) } // When previous step is wrapped in a loop, aria-label communicates position within a loop } else if (cachedPreviousStepLoopData != null) { - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.inLoop'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.withInLoop'}, { stepNumber, - stepName, + stepActionName, previousStepNumber: cachedPreviousStepLoopData.getContainingLoopPosition(), - command: this.props.intl.formatMessage({id: `Command.${prevStep.block}`}), + previousStepActionName: this.props.intl.formatMessage({id: `Command.${prevStep.block}`}), loopLabel: cachedPreviousStepLoopData.getContainingLoopLabel(), } ) // When previous step is a movements step and not in a loop, aria-label communicates position within the program } else { - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.command'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep'}, { stepNumber, - stepName, + stepActionName, previousStepNumber: this.props.pressedStepIndex, - command: this.props.intl.formatMessage({id: `Command.${prevStep.block}`}) + previousStepActionName: this.props.intl.formatMessage({id: `Command.${prevStep.block}`}) } ); } } } - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.disabled'}, { stepNumber, - stepName + stepActionName } ); } - makeNextStepAriaLabel(stepNumber: ?number | string, stepName: string): string { + makeNextStepAriaLabel(stepNumber: ?number | string, stepActionName: string): string { const currentStep = this.props.programSequence.getProgramStepAt(this.props.pressedStepIndex); if (this.props.pressedStepIndex < (this.props.programSequence.getProgramLength() - 1)) { const nextStep = this.props.programSequence.getProgramStepAt(this.props.pressedStepIndex + 1); const cachedNextStepLoopData = nextStep.cache; // When next step is startLoop, aria-label communicates that moveNext will move into a loop if (nextStep.block === 'startLoop') { - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.startLoop'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.intoLoop'}, { stepNumber, - stepName, + stepActionName, loopLabel: nextStep.label } ); // When next step is endLoop, aria-label communicates that moveNext will move out of the current loop } else if (nextStep.block === 'endLoop' && currentStep.block !== 'startLoop') { - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.endLoop'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.outOfLoop'}, { stepNumber, - stepName, + stepActionName, loopLabel: nextStep.label } ); @@ -170,43 +170,43 @@ class ActionPanel extends React.Component { const endLoopIndex = this.props.programSequence.getMatchingLoopBlockIndex(this.props.pressedStepIndex); const program = this.props.programSequence.getProgram(); if (endLoopIndex != null && program[endLoopIndex + 1] != null) { - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.command'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep'}, { stepNumber, - stepName, + stepActionName, nextStepNumber: endLoopIndex + 2, - command: this.props.intl.formatMessage({id: `Command.${program[endLoopIndex + 1].block}`}), + nextStepActionName: this.props.intl.formatMessage({id: `Command.${program[endLoopIndex + 1].block}`}), } ); } // When next step is wrapped in a loop, aria-label communicates position within a loop } else if (cachedNextStepLoopData != null) { - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.inLoop'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.withInLoop'}, { stepNumber, - stepName, + stepActionName, nextStepNumber: cachedNextStepLoopData.getContainingLoopPosition(), - command: this.props.intl.formatMessage({id: `Command.${nextStep.block}`}), + nextStepActionName: this.props.intl.formatMessage({id: `Command.${nextStep.block}`}), loopLabel: cachedNextStepLoopData.getContainingLoopLabel() } ); // When next step is a movements step and not in a loop, aria-label communicates position within the program } else { - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.command'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep'}, { stepNumber, - stepName, + stepActionName, nextStepNumber: this.props.pressedStepIndex + 2, - command: this.props.intl.formatMessage({id: `Command.${nextStep.block}`}) + nextStepActionName: this.props.intl.formatMessage({id: `Command.${nextStep.block}`}) } ); } } } - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.disabled'}, { stepNumber, - stepName + stepActionName } ); } @@ -238,7 +238,7 @@ class ActionPanel extends React.Component { const moveToNextStepIsDisabled = this.props.programSequence.moveToNextStepDisabled(this.props.pressedStepIndex); const moveToPreviousStepIsDisabled = this.props.programSequence.moveToPreviousStepDisabled(this.props.pressedStepIndex); const replaceIsVisible = this.getReplaceIsVisible(); - const replaceIsDisabled = this.props.selectedCommandName == null; + const replaceIsDisabled = this.props.selectedActionName == null; return ( diff --git a/src/ActionPanel.test.js b/src/ActionPanel.test.js index 2daf9b4f..cc2205eb 100644 --- a/src/ActionPanel.test.js +++ b/src/ActionPanel.test.js @@ -24,7 +24,7 @@ function createMountActionPanel(props) { {}, { focusedOptionName: null, - selectedCommandName: 'right45', + selectedActionName: 'right45', programSequence: new ProgramSequence( [ {block: 'forward1'}, @@ -101,7 +101,7 @@ describe('ActionPanel options', () => { test('Given that there is no selected action, then the Replace button should be disabled', () => { const { wrapper } = createMountActionPanel({ pressedStepIndex: 1, - selectedCommandName: null + selectedActionName: null }); const replaceButton = getActionPanelOptionButtons(wrapper, 'replaceCurrentStep'); const expectedAriaLabel = 'Replace Step 2 turn left 45 degrees'; diff --git a/src/AnnouncementBuilder.js b/src/AnnouncementBuilder.js index dbfb0be6..bd88dfed 100644 --- a/src/AnnouncementBuilder.js +++ b/src/AnnouncementBuilder.js @@ -16,21 +16,21 @@ export default class AnnouncementBuilder { } buildSelectActionAnnouncement(action: string): AnnouncementData { - let commandType = null; + let actionType = null; if (action === 'loop') { - commandType = this.intl.formatMessage({ + actionType = this.intl.formatMessage({ id: 'Announcement.control' }); } else { - commandType = this.intl.formatMessage({ + actionType = this.intl.formatMessage({ id: 'Announcement.movement' }); } return { messageIdSuffix: 'actionSelected', values: { - commandType: commandType, - command: this.intl.formatMessage({ + actionType, + actionName: this.intl.formatMessage({ id: `Announcement.${action}` }), } @@ -38,21 +38,21 @@ export default class AnnouncementBuilder { } buildAddStepAnnouncement(action: string): AnnouncementData { - let commandType = null; + let actionType = null; if (action === 'loop') { - commandType = this.intl.formatMessage({ + actionType = this.intl.formatMessage({ id: 'Announcement.control' }); } else { - commandType = this.intl.formatMessage({ + actionType = this.intl.formatMessage({ id: 'Announcement.movement' }); } return { messageIdSuffix: 'add', values: { - commandType: commandType, - command: this.intl.formatMessage({ + actionType, + actionName: this.intl.formatMessage({ id: `Announcement.${action}` }), } @@ -64,10 +64,10 @@ export default class AnnouncementBuilder { return { messageIdSuffix: 'delete', values: { - commandType: this.intl.formatMessage({ + actionType: this.intl.formatMessage({ id: "Announcement.control" }), - command: this.intl.formatMessage( + actionName: this.intl.formatMessage( { id: `Announcement.${programBlock.block}` }, @@ -81,10 +81,10 @@ export default class AnnouncementBuilder { return { messageIdSuffix: 'delete', values: { - commandType: this.intl.formatMessage({ + actionType: this.intl.formatMessage({ id: "Announcement.movement" }), - command: this.intl.formatMessage( + actionName: this.intl.formatMessage( { id: `Announcement.${programBlock.block}` } @@ -100,10 +100,10 @@ export default class AnnouncementBuilder { return { messageIdSuffix: 'replace', values: { - oldCommand: this.intl.formatMessage({ + oldActionName: this.intl.formatMessage({ id: `Announcement.${programBlock.block}` }), - newCommand: this.intl.formatMessage({ + newActionName: this.intl.formatMessage({ id: `Announcement.${selectedAction}` }) } diff --git a/src/AnnouncementBuilder.test.js b/src/AnnouncementBuilder.test.js index b9858765..0c986ed5 100644 --- a/src/AnnouncementBuilder.test.js +++ b/src/AnnouncementBuilder.test.js @@ -22,16 +22,16 @@ test('Test buildSelectActionAnnouncement()', () => { expect(announcementBuilder.buildSelectActionAnnouncement('loop')).toStrictEqual({ messageIdSuffix: 'actionSelected', values: { - commandType: 'control', - command: 'loop' + actionType: 'control', + actionName: 'loop' } }); expect(announcementBuilder.buildSelectActionAnnouncement('forward1')).toStrictEqual({ messageIdSuffix: 'actionSelected', values: { - commandType: 'movement', - command: 'forward 1 square' + actionType: 'movement', + actionName: 'forward 1 square' } }); }); @@ -44,16 +44,16 @@ test('Test buildAddStepAnnouncement()', () => { expect(announcementBuilder.buildAddStepAnnouncement('loop')).toStrictEqual({ messageIdSuffix: 'add', values: { - commandType: 'control', - command: 'loop' + actionType: 'control', + actionName: 'loop' } }); expect(announcementBuilder.buildAddStepAnnouncement('forward1')).toStrictEqual({ messageIdSuffix: 'add', values: { - commandType: 'movement', - command: 'forward 1 square' + actionType: 'movement', + actionName: 'forward 1 square' } }); }); @@ -71,8 +71,8 @@ describe('Test buildDeleteStepAnnouncement()', () => { expect(announcementBuilder.buildDeleteStepAnnouncement(startLoopBlock)).toStrictEqual({ messageIdSuffix: 'delete', values: { - commandType: 'control', - command: 'loop A' + actionType: 'control', + actionName: 'loop A' } }); }); @@ -88,8 +88,8 @@ describe('Test buildDeleteStepAnnouncement()', () => { expect(announcementBuilder.buildDeleteStepAnnouncement(endLoopBlock)).toStrictEqual({ messageIdSuffix: 'delete', values: { - commandType: 'control', - command: 'loop A' + actionType: 'control', + actionName: 'loop A' } }); }); @@ -104,8 +104,8 @@ describe('Test buildDeleteStepAnnouncement()', () => { expect(announcementBuilder.buildDeleteStepAnnouncement(forwardBlock)).toStrictEqual({ messageIdSuffix: 'delete', values: { - commandType: 'movement', - command: 'forward 1 square' + actionType: 'movement', + actionName: 'forward 1 square' } }); }); @@ -123,8 +123,8 @@ test('Test buildReplaceStepAnnouncement()', () => { expect(announcementBuilder.buildReplaceStepAnnouncement(forwardBlock, 'right45')).toStrictEqual({ messageIdSuffix: 'replace', values: { - oldCommand: 'forward 1 square', - newCommand: 'turn right 45 degrees' + oldActionName: 'forward 1 square', + newActionName: 'turn right 45 degrees' } }); }); diff --git a/src/App.js b/src/App.js index f43f1305..03333440 100644 --- a/src/App.js +++ b/src/App.js @@ -285,7 +285,7 @@ export class App extends React.Component { }); } - getSelectedCommandName() { + getSelectedActionName() { if (this.state.selectedAction !== null) { return this.state.selectedAction; } else { @@ -1013,7 +1013,7 @@ export class App extends React.Component { { ReactDOM.unmountComponentAtNode(div); }); -it('Should play a sound when selectedCommandName changes', () => { +it('Should play a sound when selectedActionName changes', () => { const { app, audioManagerMock } = mountApp({}); // Update the selectedAction @@ -64,8 +64,8 @@ it('Should play a sound when selectedCommandName changes', () => { expect(audioManagerMock.playAnnouncement.mock.calls.length).toBe(1); expect(audioManagerMock.playAnnouncement.mock.calls[0][0]).toBe('actionSelected'); expect(audioManagerMock.playAnnouncement.mock.calls[0][2]).toStrictEqual({ - "commandType": "movement", - "command": "forward 1 square" + "actionType": "movement", + "actionName": "forward 1 square" }); }); }); diff --git a/src/CharacterAriaLive.js b/src/CharacterAriaLive.js index 6365cbcc..a37bd9f8 100644 --- a/src/CharacterAriaLive.js +++ b/src/CharacterAriaLive.js @@ -40,7 +40,7 @@ class CharacterAriaLive extends React.Component { }); const text = this.props.intl.formatMessage( { id:'CharacterAriaLive.movementAriaLabel' }, - { character: characterLabel } + { sceneCharacter: characterLabel } ); this.setLiveRegion(text); } diff --git a/src/CharacterDescriptionBuilder.js b/src/CharacterDescriptionBuilder.js index 481b8136..06c8db56 100644 --- a/src/CharacterDescriptionBuilder.js +++ b/src/CharacterDescriptionBuilder.js @@ -38,7 +38,7 @@ export default class CharacterDescriptionBuilder { { columnLabel: columnLabel, rowLabel: rowLabel, - item: itemLabel, + backgroundItem: itemLabel, direction: directionLabel } ); diff --git a/src/CommandPaletteCommand.js b/src/CommandPaletteCommand.js index a6f083d1..90c3fd69 100644 --- a/src/CommandPaletteCommand.js +++ b/src/CommandPaletteCommand.js @@ -12,7 +12,7 @@ type CommandPaletteCommandProps = { commandName: CommandName, intl: IntlShape, isDraggingCommand: boolean, - selectedCommandName: ?CommandName, + selectedActionName: ?CommandName, onSelect: (commandName: CommandName) => void, onDragStart: (commandName: CommandName) => void, onDragEnd: () => void @@ -34,7 +34,7 @@ class CommandPaletteCommand extends React.Component { {}}/> ); expect(hasPressedClass(wrapper)).toBe(false); @@ -43,7 +43,7 @@ test('Pressed state is false when selecedCommandName is another command', () => {}}/> ); expect(hasPressedClass(wrapper)).toBe(false); @@ -55,7 +55,7 @@ test('Pressed state is true when selecedCommandName is this command', () => { {}}/> ); expect(hasPressedClass(wrapper)).toBe(true); @@ -69,7 +69,7 @@ test('Clicking the button calls the callback onSelect with commandName', () => { ); @@ -80,8 +80,8 @@ test('Clicking the button calls the callback onSelect with commandName', () => { // Verify that onSelect is called with the commandName expect(mockSelectHandler.mock.calls.length).toBe(1); expect(mockSelectHandler.mock.calls[0][0]).toBe('forward1'); - // Update the selectedCommandName - wrapper.setProps({selectedCommandName: 'forward1'}); + // Update the selectedActionName + wrapper.setProps({selectedActionName: 'forward1'}); wrapper.update(); // Click again button.simulate('click'); diff --git a/src/DesignModeCursorDescriptionBuilder.js b/src/DesignModeCursorDescriptionBuilder.js index 00ce7fec..05bb6ab4 100644 --- a/src/DesignModeCursorDescriptionBuilder.js +++ b/src/DesignModeCursorDescriptionBuilder.js @@ -36,7 +36,7 @@ export default class DesignModeCursorDescriptionBuilder { { columnLabel: columnLabel, rowLabel: rowLabel, - item: itemLabel + backgroundItem: itemLabel } ); } else { diff --git a/src/KeyboardInputModal.js b/src/KeyboardInputModal.js index d766e578..b733a902 100644 --- a/src/KeyboardInputModal.js +++ b/src/KeyboardInputModal.js @@ -152,7 +152,7 @@ class KeyboardInputModal extends React.Component
diff --git a/src/ProgramBlockEditor.js b/src/ProgramBlockEditor.js index 22f64930..b076b989 100644 --- a/src/ProgramBlockEditor.js +++ b/src/ProgramBlockEditor.js @@ -455,7 +455,7 @@ export class ProgramBlockEditor extends React.Component { expect(audioManagerMock.playAnnouncement.mock.calls.length).toBe(1); expect(audioManagerMock.playAnnouncement.mock.calls[0][0]).toBe('add'); expect(audioManagerMock.playAnnouncement.mock.calls[0][2]).toStrictEqual({ - commandType: 'movement', - command: 'forward 3 squares' + actionType: 'movement', + actionName: 'forward 3 squares' }); // The focus, scrolling, and animation should be set up @@ -135,8 +135,8 @@ describe('Test addSelectedActionToProgramEnd()', () => { expect(audioManagerMock.playAnnouncement.mock.calls.length).toBe(1); expect(audioManagerMock.playAnnouncement.mock.calls[0][0]).toBe('add'); expect(audioManagerMock.playAnnouncement.mock.calls[0][2]).toStrictEqual({ - commandType: 'movement', - command: 'forward 3 squares' + actionType: 'movement', + actionName: 'forward 3 squares' }); // The focus, scrolling, and animation should be set up @@ -195,8 +195,8 @@ type DeleteStepTestCase = { program: Program, deleteStepIndex: number, deleteStepName: string, - expectedAnnouncementCommandType: string, - expectedAnnouncementCommand: string + expectedAnnouncementActionType: string, + expectedAnnouncementAction: string }; describe('Test deleteProgramStep()', () => { @@ -208,8 +208,8 @@ describe('Test deleteProgramStep()', () => { ], deleteStepIndex: 0, deleteStepName: 'forward1', - expectedAnnouncementCommandType: 'movement', - expectedAnnouncementCommand: 'forward 1 square' + expectedAnnouncementActionType: 'movement', + expectedAnnouncementAction: 'forward 1 square' }, { program: [ @@ -219,8 +219,8 @@ describe('Test deleteProgramStep()', () => { ], deleteStepIndex: 0, deleteStepName: 'startLoop', - expectedAnnouncementCommandType: 'control', - expectedAnnouncementCommand: 'loop A' + expectedAnnouncementActionType: 'control', + expectedAnnouncementAction: 'loop A' }, { program: [ @@ -230,8 +230,8 @@ describe('Test deleteProgramStep()', () => { ], deleteStepIndex: 1, deleteStepName: 'endLoop', - expectedAnnouncementCommandType: 'control', - expectedAnnouncementCommand: 'loop A' + expectedAnnouncementActionType: 'control', + expectedAnnouncementAction: 'loop A' } ]: Array))('When deleting a step not at the end, then focus is set to the step now at the deleted index', (testData: DeleteStepTestCase, done) => { @@ -252,8 +252,8 @@ describe('Test deleteProgramStep()', () => { expect(audioManagerMock.playAnnouncement.mock.calls.length).toBe(1); expect(audioManagerMock.playAnnouncement.mock.calls[0][0]).toBe('delete'); expect(audioManagerMock.playAnnouncement.mock.calls[0][2]).toStrictEqual({ - commandType: testData.expectedAnnouncementCommandType, - command: testData.expectedAnnouncementCommand + actionType: testData.expectedAnnouncementActionType, + actionName: testData.expectedAnnouncementAction }); // The add-node after the program should be focused @@ -280,8 +280,8 @@ describe('Test deleteProgramStep()', () => { ], deleteStepIndex: 1, deleteStepName: 'forward2', - expectedAnnouncementCommandType: 'movement', - expectedAnnouncementCommand: 'forward 2 squares' + expectedAnnouncementActionType: 'movement', + expectedAnnouncementAction: 'forward 2 squares' }, { program: [ @@ -291,8 +291,8 @@ describe('Test deleteProgramStep()', () => { ], deleteStepIndex: 1, deleteStepName: 'startLoop', - expectedAnnouncementCommandType: 'control', - expectedAnnouncementCommand: 'loop A' + expectedAnnouncementActionType: 'control', + expectedAnnouncementAction: 'loop A' }, { program: [ @@ -302,8 +302,8 @@ describe('Test deleteProgramStep()', () => { ], deleteStepIndex: 2, deleteStepName: 'endLoop', - expectedAnnouncementCommandType: 'control', - expectedAnnouncementCommand: 'loop A' + expectedAnnouncementActionType: 'control', + expectedAnnouncementAction: 'loop A' } ]: Array))('When deleting the step at the end, then focus is set to the add-node after the program', (testData: DeleteStepTestCase, done) => { @@ -324,8 +324,8 @@ describe('Test deleteProgramStep()', () => { expect(audioManagerMock.playAnnouncement.mock.calls.length).toBe(1); expect(audioManagerMock.playAnnouncement.mock.calls[0][0]).toBe('delete'); expect(audioManagerMock.playAnnouncement.mock.calls[0][2]).toStrictEqual({ - commandType: testData.expectedAnnouncementCommandType, - command: testData.expectedAnnouncementCommand + actionType: testData.expectedAnnouncementActionType, + actionName: testData.expectedAnnouncementAction }); // The add-node after the program should be focused @@ -463,8 +463,8 @@ describe('Test replaceProgramStep()', () => { expect(audioManagerMock.playAnnouncement.mock.calls.length).toBe(1); expect(audioManagerMock.playAnnouncement.mock.calls[0][0]).toBe('replace'); expect(audioManagerMock.playAnnouncement.mock.calls[0][2]).toStrictEqual({ - oldCommand: "turn left 45 degrees", - newCommand: "turn right 45 degrees" + oldActionName: "turn left 45 degrees", + newActionName: "turn right 45 degrees" }); // The focus, scrolling, and animation should be set up @@ -501,7 +501,7 @@ describe('Test moveProgramStepNext()', () => { {block: 'forward2'}, {block: 'forward1'} ], - expectedAnnouncementCommand: 'moveToNext', + expectedAnnouncementAction: 'moveToNext', expectedFocusCommandBlockAfterUpdateCall: 1 }, { @@ -520,7 +520,7 @@ describe('Test moveProgramStepNext()', () => { {block: 'startLoop', label: 'A', iterations: 1}, {block: 'endLoop', label: 'A'}, ], - expectedAnnouncementCommand: 'moveToNext', + expectedAnnouncementAction: 'moveToNext', expectedFocusCommandBlockAfterUpdateCall: 0 } ]))('When movement is possible, then the program should be updated and all expected activities invoked', (testData, done) => { @@ -535,7 +535,7 @@ describe('Test moveProgramStepNext()', () => { // The announcement should be made expect(audioManagerMock.playAnnouncement.mock.calls.length).toBe(1); - expect(audioManagerMock.playAnnouncement.mock.calls[0][0]).toBe(testData.expectedAnnouncementCommand); + expect(audioManagerMock.playAnnouncement.mock.calls[0][0]).toBe(testData.expectedAnnouncementAction); // $FlowFixMe: Jest mock API const programBlockEditorMock = ProgramBlockEditor.mock.instances[0]; @@ -593,7 +593,7 @@ describe('Test moveProgramStepPrevious()', () => { {block: 'forward2'}, {block: 'forward1'} ], - expectedAnnouncementCommand: 'moveToPrevious', + expectedAnnouncementAction: 'moveToPrevious', expectedFocusCommandBlockAfterUpdateCall: 1 }, { @@ -612,7 +612,7 @@ describe('Test moveProgramStepPrevious()', () => { {block: 'forward1'}, {block: 'forward2'} ], - expectedAnnouncementCommand: 'moveToPrevious', + expectedAnnouncementAction: 'moveToPrevious', expectedFocusCommandBlockAfterUpdateCall: 0 }, ]))('When movement is possible, then the program should be updated and all expected activities invoked', (testData, done) => { @@ -627,7 +627,7 @@ describe('Test moveProgramStepPrevious()', () => { // The announcement should be made expect(audioManagerMock.playAnnouncement.mock.calls.length).toBe(1); - expect(audioManagerMock.playAnnouncement.mock.calls[0][0]).toBe(testData.expectedAnnouncementCommand); + expect(audioManagerMock.playAnnouncement.mock.calls[0][0]).toBe(testData.expectedAnnouncementAction); // $FlowFixMe: Jest mock API const programBlockEditorMock = ProgramBlockEditor.mock.instances[0]; diff --git a/src/Scene.js b/src/Scene.js index 251ad553..e47b45de 100644 --- a/src/Scene.js +++ b/src/Scene.js @@ -68,7 +68,7 @@ class Scene extends React.Component { } generateAriaLabel() { - const worldLabel = this.props.intl.formatMessage({id: this.props.world + '.name'}); + const backgroundName = this.props.intl.formatMessage({id: this.props.world + '.name'}); const numColumns = this.props.dimensions.getWidth(); const numRows = this.props.dimensions.getHeight(); @@ -81,10 +81,10 @@ class Scene extends React.Component { return this.props.intl.formatMessage( { id: 'Scene.description' }, { - world: worldLabel, - numColumns: numColumns, - numRows: numRows, - characterDescription: characterDescription + backgroundName, + numColumns, + numRows, + characterDescription } ); } diff --git a/src/messages.json b/src/messages.json index c3a84be5..b333e0ee 100644 --- a/src/messages.json +++ b/src/messages.json @@ -1,18 +1,18 @@ { "en": { - "ActionPanel.action.delete": "Delete Step {stepNumber} {stepName}", - "ActionPanel.action.moveToNextStep": "Move Step {stepNumber} {stepName}", - "ActionPanel.action.moveToNextStep.command": "Move Step {stepNumber} {stepName} after step {nextStepNumber} {command}", - "ActionPanel.action.moveToNextStep.endLoop": "Move Step {stepNumber} {stepName} out of loop {loopLabel}", - "ActionPanel.action.moveToNextStep.inLoop": "Move Step {stepNumber} {stepName} after step {nextStepNumber} {command} of loop {loopLabel}", - "ActionPanel.action.moveToNextStep.startLoop": "Move Step {stepNumber} {stepName} into loop {loopLabel}", - "ActionPanel.action.moveToPreviousStep": "Move Step {stepNumber} {stepName}", - "ActionPanel.action.moveToPreviousStep.command": "Move Step {stepNumber} {stepName} before step {previousStepNumber} {command}", - "ActionPanel.action.moveToPreviousStep.endLoop": "Move Step {stepNumber} {stepName} into loop {loopLabel}", - "ActionPanel.action.moveToPreviousStep.inLoop": "Move Step {stepNumber} {stepName} before step {previousStepNumber} {command} of loop {loopLabel}", - "ActionPanel.action.moveToPreviousStep.startLoop": "Move Step {stepNumber} {stepName} out of loop {loopLabel}", - "ActionPanel.action.replace.noAction": "Replace Step {stepNumber} {stepName}", - "ActionPanel.action.replace.withAction": "Replace Step {stepNumber} {stepName} with selected action {selectedCommandName}", + "ActionPanel.action.delete": "Delete Step {stepNumber} {stepActionName}", + "ActionPanel.action.moveToNextStep": "Move Step {stepNumber} {stepActionName} after step {nextStepNumber} {nextStepActionName}", + "ActionPanel.action.moveToNextStep.disabled": "Move Step {stepNumber} {stepActionName}", + "ActionPanel.action.moveToNextStep.outOfLoop": "Move Step {stepNumber} {stepActionName} out of loop {loopLabel}", + "ActionPanel.action.moveToNextStep.withInLoop": "Move Step {stepNumber} {stepActionName} after step {nextStepNumber} {nextStepActionName} of loop {loopLabel}", + "ActionPanel.action.moveToNextStep.intoLoop": "Move Step {stepNumber} {stepActionName} into loop {loopLabel}", + "ActionPanel.action.moveToPreviousStep": "Move Step {stepNumber} {stepActionName} before step {previousStepNumber} {previousStepActionName}", + "ActionPanel.action.moveToPreviousStep.disabled": "Move Step {stepNumber} {stepActionName}", + "ActionPanel.action.moveToPreviousStep.intoLoop": "Move Step {stepNumber} {stepActionName} into loop {loopLabel}", + "ActionPanel.action.moveToPreviousStep.withInLoop": "Move Step {stepNumber} {stepActionName} before step {previousStepNumber} {previousStepActionName} of loop {loopLabel}", + "ActionPanel.action.moveToPreviousStep.outOfLoop": "Move Step {stepNumber} {stepActionName} out of loop {loopLabel}", + "ActionPanel.action.replace.noSelectedAction": "Replace Step {stepNumber} {stepActionName}", + "ActionPanel.action.replace.withSelectedAction": "Replace Step {stepNumber} {stepActionName} with selected action {selectedActionName}", "ActionsMenu.title": "Actions", "ActionsMenu.toggleActionsMenu": "configure available actions", "ActionsMenuItem.command.backward1": "Move backward 1 step", @@ -39,8 +39,8 @@ "AmusementPark.waterPark": "water park", "AmusementPark.waterSlide": "water slide", "AmusementPark.whaleFountain": "whale fountain", - "Announcement.actionSelected": "{commandType} {command} selected", - "Announcement.add": "added {commandType} {command}", + "Announcement.actionSelected": "{actionType} {actionName} selected", + "Announcement.add": "added {actionType} {actionName}", "Announcement.backward1": "backward 1 square", "Announcement.backward2": "backward 2 squares", "Announcement.backward3": "backward 3 squares", @@ -48,7 +48,7 @@ "Announcement.cannotMovePrevious": "At the beginning of the program, unable to move left", "Announcement.cannotReplaceLoopBlocks": "replace is not available for loops", "Announcement.control": "control", - "Announcement.delete": "deleted {commandType} {command}", + "Announcement.delete": "deleted {actionType} {actionName}", "Announcement.deleteAll": "delete program?", "Announcement.endLoop": "loop {loopLabel}", "Announcement.forward1": "forward 1 square", @@ -62,7 +62,7 @@ "Announcement.moveToNext": "moved to right", "Announcement.moveToPrevious": "moved to left", "Announcement.noActionSelected": "no action selected", - "Announcement.replace": "movement {oldCommand} replaced with {newCommand}", + "Announcement.replace": "movement {oldActionName} replaced with {newActionName}", "Announcement.right180": "turn right 180 degrees", "Announcement.right45": "turn right 45 degrees", "Announcement.right90": "turn right 90 degrees", @@ -102,9 +102,9 @@ "Camping.tentdoor": "the tent door", "Camping.trunk": "the tree trunk", "Cancel": "Cancel", - "CharacterAriaLive.movementAriaLabel": "{character} is moving", + "CharacterAriaLive.movementAriaLabel": "{sceneCharacter} is moving", "CharacterDescriptionBuilder.positionAndDirection": "At {columnLabel} {rowLabel} facing {direction}", - "CharacterDescriptionBuilder.positionAndDirectionAndItem": "At {columnLabel} {rowLabel} on {item} facing {direction}", + "CharacterDescriptionBuilder.positionAndDirectionAndItem": "At {columnLabel} {rowLabel} on {backgroundItem} facing {direction}", "CharacterMessageBuilder.endOfScene": "Your character has reached the end of the scene", "CharacterMessageBuilder.hitWall": "Your character hit a wall on {columnLabel}{rowLabel}", "CharacterPositionController.editPosition.columnPosition": "Character column position", @@ -164,7 +164,7 @@ "DeepOcean.shark": "the shark", "DeepOcean.treasure": "the treasure", "DesignModeCursorDescriptionBuilder.position": "At {columnLabel} {rowLabel}", - "DesignModeCursorDescriptionBuilder.positionAndItem": "At {columnLabel} {rowLabel} on {item}", + "DesignModeCursorDescriptionBuilder.positionAndItem": "At {columnLabel} {rowLabel} on {backgroundItem}", "DeviceConnectControl.connected": "Connected", "DeviceConnectControl.connecting": "Connecting", "DeviceConnectControl.notConnected": "Not connected", @@ -295,17 +295,17 @@ "Haunted.painting": "a painting", "Haunted.shelf": "the bookshelf", "Haunted.stairs": "the stairs", - "KeyboardInputModal.Description.addCommandToBeginning": "Press {key} to add the selected command to the beginning of the program.", - "KeyboardInputModal.Description.addCommandToEnd": "Press {key} to add the selected command to the end of the program.", - "KeyboardInputModal.Description.announceScene": "Press {key} to announce the character position and orientation.", - "KeyboardInputModal.Description.decreaseProgramSpeed": "Press {key} to make the program play slower.", - "KeyboardInputModal.Description.deleteCurrentStep": "Press {key} to delete the currently focused step.", - "KeyboardInputModal.Description.increaseProgramSpeed": "Press {key} to make the program play faster.", - "KeyboardInputModal.Description.playPauseProgram": "Press {key} to play or pause the program.", - "KeyboardInputModal.Description.refreshScene": "Press {key} to refresh the scene.", - "KeyboardInputModal.Description.showHide": "Press {key} to show the keyboard shortcuts menu.", - "KeyboardInputModal.Description.stopProgram": "Press {key} to stop the program.", - "KeyboardInputModal.Description.toggleAnnouncements": "Press {key} to toggle announcements.", + "KeyboardInputModal.Description.addCommandToBeginning": "Press {keyboardShortcut} to add the selected command to the beginning of the program.", + "KeyboardInputModal.Description.addCommandToEnd": "Press {keyboardShortcut} to add the selected command to the end of the program.", + "KeyboardInputModal.Description.announceScene": "Press {keyboardShortcut} to announce the character position and orientation.", + "KeyboardInputModal.Description.decreaseProgramSpeed": "Press {keyboardShortcut} to make the program play slower.", + "KeyboardInputModal.Description.deleteCurrentStep": "Press {keyboardShortcut} to delete the currently focused step.", + "KeyboardInputModal.Description.increaseProgramSpeed": "Press {keyboardShortcut} to make the program play faster.", + "KeyboardInputModal.Description.playPauseProgram": "Press {keyboardShortcut} to play or pause the program.", + "KeyboardInputModal.Description.refreshScene": "Press {keyboardShortcut} to refresh the scene.", + "KeyboardInputModal.Description.showHide": "Press {keyboardShortcut} to show the keyboard shortcuts menu.", + "KeyboardInputModal.Description.stopProgram": "Press {keyboardShortcut} to stop the program.", + "KeyboardInputModal.Description.toggleAnnouncements": "Press {keyboardShortcut} to toggle announcements.", "KeyboardInputModal.KeyIcons.A": "A", "KeyboardInputModal.KeyIcons.Alt": "Alt", "KeyboardInputModal.KeyIcons.B": "B", @@ -422,12 +422,12 @@ "PrivacyModal.section070.Heading": "Contact Us", "PrivacyModal.section070.block010": "If you have any questions about this Privacy Policy, please {contactLink}.", "PrivacyModal.title": "Weavly Privacy Policy", - "ProgramBlockEditor.beginningBlock": "Add selected action {command} to the beginning of the program", - "ProgramBlockEditor.betweenBlocks": "Add selected action {command} between position {prevCommandStepNumber}, {prevCommand} and position {nextCommandStepNumber}, {nextCommand}", + "ProgramBlockEditor.beginningBlock": "Add selected action {actionName} to the beginning of the program", + "ProgramBlockEditor.betweenBlocks": "Add selected action {actionName} between position {previousStepNumber}, {previousStepActionName} and position {nextStepNumber}, {nextStepActionName}", "ProgramBlockEditor.blocks.noCommandSelected": "Make sure an action is selected", - "ProgramBlockEditor.command": "{command}, position {index} of current program", - "ProgramBlockEditor.lastBlock": "Add selected action {command} to the end of the program", - "ProgramBlockEditor.nestedCommand": "{command}, position {index} of Loop {parentLoopLabel}", + "ProgramBlockEditor.command": "{blockName}, position {index} of current program", + "ProgramBlockEditor.lastBlock": "Add selected action {actionName} to the end of the program", + "ProgramBlockEditor.nestedCommand": "{blockName}, position {index} of Loop {parentLoopLabel}", "ProgramBlockEditor.program.deleteAll": "Delete all steps of your program", "ProgramBlockEditor.programHeading": "Program", "ProgramBlockEditor.toggleAddNodeExpandMode": "add node expanded mode", @@ -448,7 +448,7 @@ "Savannah.pond": "the Pond", "Savannah.tree": "a Tree", "Save": "Save", - "Scene.description": "Scene, in {world}, {numColumns} by {numRows} grid. {characterDescription}", + "Scene.description": "Scene, in {backgroundName}, {numColumns} by {numRows} grid. {characterDescription}", "Scene.heading": "Scene", "SceneMessage.close": "close message", "ShareButton": "Share", @@ -534,11 +534,10 @@ "WorldSelectorButton.label": "Scene Background selector" }, "fr": { - "ActionPanel.action.delete": "supprimer {stepNumber} {stepName}", - "ActionPanel.action.moveToNextStep": "remplacer l'étape {stepNumber} {stepName} {nextStepInfo}", - "ActionPanel.action.moveToPreviousStep": "remplacer l'étape {stepNumber} {stepName} {previousStepInfo}", - "ActionPanel.action.replace": "remplacer l'étape {stepNumber} {stepName} {selectedCommandName}", - "ActionPanel.selectedCommandName": "{selectedCommandName} avec action sélectionner", + "ActionPanel.action.delete": "supprimer {stepNumber} {stepActionName}", + "ActionPanel.action.moveToNextStep": "remplacer l'étape {stepNumber} {stepActionName} {nextStepInfo}", + "ActionPanel.action.moveToPreviousStep": "remplacer l'étape {stepNumber} {stepActionName} {previousStepInfo}", + "ActionPanel.action.replace": "remplacer l'étape {stepNumber} {stepActionName} {selectedActionName}", "ActionsMenu.title": "action", "ActionsMenu.toggleActionsMenu": "configurer les actions disponibles", "ActionsMenuItem.command.backward1": "reculer d'un pas", @@ -565,8 +564,8 @@ "AmusementPark.waterPark": "parc aquatique", "AmusementPark.waterSlide": "glissade d'eau", "AmusementPark.whaleFountain": "fontaine des baleines", - "Announcement.actionSelected": "{commandType} {command} sélectionnée", - "Announcement.add": "{commandType} ajouté {command}", + "Announcement.actionSelected": "{actionType} {actionName} sélectionnée", + "Announcement.add": "{actionType} ajouté {actionName}", "Announcement.backward1": "reculer d'1 case", "Announcement.backward2": "reculer 2 cases", "Announcement.backward3": "reculer 3 cases", @@ -574,7 +573,7 @@ "Announcement.cannotMovePrevious": "au début du programme, incapable de se déplacer vers la gauche", "Announcement.cannotReplaceLoopBlocks": "remplacer n'est pas disponible pour les boucles", "Announcement.control": "controle", - "Announcement.delete": "suprimé {commandType} {command}", + "Announcement.delete": "suprimé {actionType} {actionName}", "Announcement.deleteAll": "suprimmer le programme", "Announcement.endLoop": "boucle {loopLabel}", "Announcement.forward1": "avance 1 case", @@ -588,7 +587,7 @@ "Announcement.moveToNext": "déplacer vers la droite", "Announcement.moveToPrevious": "déplacer vers la gauche", "Announcement.noActionSelected": "aucune action sélectionnée", - "Announcement.replace": "mouvement {oldCommand} remplacer par une {newCommand}", + "Announcement.replace": "mouvement {oldActionName} remplacer par une {newActionName}", "Announcement.right180": "turner a droite 180 degrées", "Announcement.right45": "tourner a droite 45 degrées", "Announcement.right90": "tourner a droite 90 degrées", @@ -628,9 +627,9 @@ "Camping.tentdoor": "la porte de la tente", "Camping.trunk": "le tronc d'arbre", "Cancel": "Annuler", - "CharacterAriaLive.movementAriaLabel": "Le {character} bouge", + "CharacterAriaLive.movementAriaLabel": "Le {sceneCharacter} bouge", "CharacterDescriptionBuilder.positionAndDirection": "À {columnLabel} {rowLabel} face à {direction}", - "CharacterDescriptionBuilder.positionAndDirectionAndItem": "À {columnLabel} {rowLabel} sur {item} orienté vers {direction}", + "CharacterDescriptionBuilder.positionAndDirectionAndItem": "À {columnLabel} {rowLabel} sur {backgroundItem} orienté vers {direction}", "CharacterMessageBuilder.endOfScene": "Votre personnage à atteint la fin de la scène", "CharacterMessageBuilder.hitWall": "ton personnage a heurté un mur {columnLabel} {rowLabel}", "CharacterPositionController.editPosition.columnPosition": "position de la colonne des charactères", @@ -700,7 +699,7 @@ "DeepOcean.shark": "le renard", "DeepOcean.treasure": "the trésore", "DesignModeCursorDescriptionBuilder.position": "à {columnLabel} {rowLabel}", - "DesignModeCursorDescriptionBuilder.positionAndItem": "À {columnLabel} {rowLabel} sur {item}", + "DesignModeCursorDescriptionBuilder.positionAndItem": "À {columnLabel} {rowLabel} sur {backgroundItem}", "DeviceConnectControl.connected": "Connecté", "DeviceConnectControl.connecting": "Connexion en cours", "DeviceConnectControl.notConnected": "Pas connecté", @@ -831,17 +830,17 @@ "Haunted.painting": "une peinture", "Haunted.shelf": "la bibliothèque", "Haunted.stairs": "les escaliers", - "KeyboardInputModal.Description.addCommandToBeginning": "appuyer sur la {key} pour ajouter la commande sélectionnée au début du programme", - "KeyboardInputModal.Description.addCommandToEnd": "appuyer sur la {key} pour ajouter la commande sélectionnée à la fin du programme", - "KeyboardInputModal.Description.announceScene": "appuyer sur la {key} pour annoncer la position du charactère et l'orientation", - "KeyboardInputModal.Description.decreaseProgramSpeed": "appuyer sur la {key} pour ralentir la lecture du programme", - "KeyboardInputModal.Description.deleteCurrentStep": "appuyer sur la {key} pour surpimer l'étape actuellement ciblée", - "KeyboardInputModal.Description.increaseProgramSpeed": "appuyer sur la {key} pour accélérer la lecture du programme", - "KeyboardInputModal.Description.playPauseProgram": "appuyer sur la {key} pour lire ou mettre en pause le programme", - "KeyboardInputModal.Description.refreshScene": "appuyer sur la {key} pour réfraîchir la scène", - "KeyboardInputModal.Description.showHide": "appuyer sur la {key} pour voir le menu racourci de l'ordinateur", - "KeyboardInputModal.Description.stopProgram": "appuyer sur la {key} pour arrêter le programme", - "KeyboardInputModal.Description.toggleAnnouncements": "appuyer sur la {key} pour basculer les annonces", + "KeyboardInputModal.Description.addCommandToBeginning": "appuyer sur la {keyboardShortcut} pour ajouter la commande sélectionnée au début du programme", + "KeyboardInputModal.Description.addCommandToEnd": "appuyer sur la {keyboardShortcut} pour ajouter la commande sélectionnée à la fin du programme", + "KeyboardInputModal.Description.announceScene": "appuyer sur la {keyboardShortcut} pour annoncer la position du charactère et l'orientation", + "KeyboardInputModal.Description.decreaseProgramSpeed": "appuyer sur la {keyboardShortcut} pour ralentir la lecture du programme", + "KeyboardInputModal.Description.deleteCurrentStep": "appuyer sur la {keyboardShortcut} pour surpimer l'étape actuellement ciblée", + "KeyboardInputModal.Description.increaseProgramSpeed": "appuyer sur la {keyboardShortcut} pour accélérer la lecture du programme", + "KeyboardInputModal.Description.playPauseProgram": "appuyer sur la {keyboardShortcut} pour lire ou mettre en pause le programme", + "KeyboardInputModal.Description.refreshScene": "appuyer sur la {keyboardShortcut} pour réfraîchir la scène", + "KeyboardInputModal.Description.showHide": "appuyer sur la {keyboardShortcut} pour voir le menu racourci de l'ordinateur", + "KeyboardInputModal.Description.stopProgram": "appuyer sur la {keyboardShortcut} pour arrêter le programme", + "KeyboardInputModal.Description.toggleAnnouncements": "appuyer sur la {keyboardShortcut} pour basculer les annonces", "KeyboardInputModal.KeyIcons.A": "A", "KeyboardInputModal.KeyIcons.Alt": "alt", "KeyboardInputModal.KeyIcons.B": "B", @@ -927,12 +926,12 @@ "PlayControls.heading": "jouer aux commandes", "PrivacyModal.close": "fermer", "PrivacyModal.title": "Weavly politique de confidentialité", - "ProgramBlockEditor.beginningBlock": "ajouté l'action selectionnée {command} au début du programme", - "ProgramBlockEditor.betweenBlocks": "ajouté l'action selectionée {command} entre la position {prevCommand} et la position {postCommand}", + "ProgramBlockEditor.beginningBlock": "ajouté l'action selectionnée {actionName} au début du programme", + "ProgramBlockEditor.betweenBlocks": "ajouté l'action selectionée {actionName} entre la position {previousStepNumber}, {previousStepActionName} et la position {nextStepNumber}, {nextStepActionName}", "ProgramBlockEditor.blocks.noCommandSelected": "assurez vous qu'une action est sélectionée", - "ProgramBlockEditor.command": "{command}, possition, {index} du programme en cours", - "ProgramBlockEditor.lastBlock": "ajouté l'action sélectionée {command} à la fin du programme", - "ProgramBlockEditor.nestedCommand": "{command}, possition, {index} du boucle, {parentLoopLabel}", + "ProgramBlockEditor.command": "{blockName}, possition, {index} du programme en cours", + "ProgramBlockEditor.lastBlock": "ajouté l'action sélectionée {actionName} à la fin du programme", + "ProgramBlockEditor.nestedCommand": "{blockName}, possition, {index} du boucle, {parentLoopLabel}", "ProgramBlockEditor.program.deleteAll": "suprrimer tout les étapes de votre programme", "ProgramBlockEditor.programHeading": "programme", "ProgramBlockEditor.toggleAddNodeExpandMode": "ajouter un note en mode développer", From 11b1a929a1391bdfddc8059c0cc051aef36eed21 Mon Sep 17 00:00:00 2001 From: Daniel Cho Date: Wed, 23 Oct 2024 09:33:41 -0400 Subject: [PATCH 15/23] fix: update based on PR feedback --- src/ActionPanel.js | 4 ++-- src/ProgramChangeController.test.js | 18 +++++++++--------- src/messages.json | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/ActionPanel.js b/src/ActionPanel.js index e85cf5b6..c211f0a4 100644 --- a/src/ActionPanel.js +++ b/src/ActionPanel.js @@ -110,7 +110,7 @@ class ActionPanel extends React.Component { } // When previous step is wrapped in a loop, aria-label communicates position within a loop } else if (cachedPreviousStepLoopData != null) { - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.withInLoop'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToPreviousStep.withinLoop'}, { stepNumber, stepActionName, @@ -181,7 +181,7 @@ class ActionPanel extends React.Component { } // When next step is wrapped in a loop, aria-label communicates position within a loop } else if (cachedNextStepLoopData != null) { - return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.withInLoop'}, + return this.props.intl.formatMessage({id: 'ActionPanel.action.moveToNextStep.withinLoop'}, { stepNumber, stepActionName, diff --git a/src/ProgramChangeController.test.js b/src/ProgramChangeController.test.js index 3ca01d21..49b0c27a 100644 --- a/src/ProgramChangeController.test.js +++ b/src/ProgramChangeController.test.js @@ -196,7 +196,7 @@ type DeleteStepTestCase = { deleteStepIndex: number, deleteStepName: string, expectedAnnouncementActionType: string, - expectedAnnouncementAction: string + expectedAnnouncementActionName: string }; describe('Test deleteProgramStep()', () => { @@ -209,7 +209,7 @@ describe('Test deleteProgramStep()', () => { deleteStepIndex: 0, deleteStepName: 'forward1', expectedAnnouncementActionType: 'movement', - expectedAnnouncementAction: 'forward 1 square' + expectedAnnouncementActionName: 'forward 1 square' }, { program: [ @@ -220,7 +220,7 @@ describe('Test deleteProgramStep()', () => { deleteStepIndex: 0, deleteStepName: 'startLoop', expectedAnnouncementActionType: 'control', - expectedAnnouncementAction: 'loop A' + expectedAnnouncementActionName: 'loop A' }, { program: [ @@ -231,7 +231,7 @@ describe('Test deleteProgramStep()', () => { deleteStepIndex: 1, deleteStepName: 'endLoop', expectedAnnouncementActionType: 'control', - expectedAnnouncementAction: 'loop A' + expectedAnnouncementActionName: 'loop A' } ]: Array))('When deleting a step not at the end, then focus is set to the step now at the deleted index', (testData: DeleteStepTestCase, done) => { @@ -253,7 +253,7 @@ describe('Test deleteProgramStep()', () => { expect(audioManagerMock.playAnnouncement.mock.calls[0][0]).toBe('delete'); expect(audioManagerMock.playAnnouncement.mock.calls[0][2]).toStrictEqual({ actionType: testData.expectedAnnouncementActionType, - actionName: testData.expectedAnnouncementAction + actionName: testData.expectedAnnouncementActionName }); // The add-node after the program should be focused @@ -281,7 +281,7 @@ describe('Test deleteProgramStep()', () => { deleteStepIndex: 1, deleteStepName: 'forward2', expectedAnnouncementActionType: 'movement', - expectedAnnouncementAction: 'forward 2 squares' + expectedAnnouncementActionName: 'forward 2 squares' }, { program: [ @@ -292,7 +292,7 @@ describe('Test deleteProgramStep()', () => { deleteStepIndex: 1, deleteStepName: 'startLoop', expectedAnnouncementActionType: 'control', - expectedAnnouncementAction: 'loop A' + expectedAnnouncementActionName: 'loop A' }, { program: [ @@ -303,7 +303,7 @@ describe('Test deleteProgramStep()', () => { deleteStepIndex: 2, deleteStepName: 'endLoop', expectedAnnouncementActionType: 'control', - expectedAnnouncementAction: 'loop A' + expectedAnnouncementActionName: 'loop A' } ]: Array))('When deleting the step at the end, then focus is set to the add-node after the program', (testData: DeleteStepTestCase, done) => { @@ -325,7 +325,7 @@ describe('Test deleteProgramStep()', () => { expect(audioManagerMock.playAnnouncement.mock.calls[0][0]).toBe('delete'); expect(audioManagerMock.playAnnouncement.mock.calls[0][2]).toStrictEqual({ actionType: testData.expectedAnnouncementActionType, - actionName: testData.expectedAnnouncementAction + actionName: testData.expectedAnnouncementActionName }); // The add-node after the program should be focused diff --git a/src/messages.json b/src/messages.json index b333e0ee..dd3ffc13 100644 --- a/src/messages.json +++ b/src/messages.json @@ -4,12 +4,12 @@ "ActionPanel.action.moveToNextStep": "Move Step {stepNumber} {stepActionName} after step {nextStepNumber} {nextStepActionName}", "ActionPanel.action.moveToNextStep.disabled": "Move Step {stepNumber} {stepActionName}", "ActionPanel.action.moveToNextStep.outOfLoop": "Move Step {stepNumber} {stepActionName} out of loop {loopLabel}", - "ActionPanel.action.moveToNextStep.withInLoop": "Move Step {stepNumber} {stepActionName} after step {nextStepNumber} {nextStepActionName} of loop {loopLabel}", + "ActionPanel.action.moveToNextStep.withinLoop": "Move Step {stepNumber} {stepActionName} after step {nextStepNumber} {nextStepActionName} of loop {loopLabel}", "ActionPanel.action.moveToNextStep.intoLoop": "Move Step {stepNumber} {stepActionName} into loop {loopLabel}", "ActionPanel.action.moveToPreviousStep": "Move Step {stepNumber} {stepActionName} before step {previousStepNumber} {previousStepActionName}", "ActionPanel.action.moveToPreviousStep.disabled": "Move Step {stepNumber} {stepActionName}", "ActionPanel.action.moveToPreviousStep.intoLoop": "Move Step {stepNumber} {stepActionName} into loop {loopLabel}", - "ActionPanel.action.moveToPreviousStep.withInLoop": "Move Step {stepNumber} {stepActionName} before step {previousStepNumber} {previousStepActionName} of loop {loopLabel}", + "ActionPanel.action.moveToPreviousStep.withinLoop": "Move Step {stepNumber} {stepActionName} before step {previousStepNumber} {previousStepActionName} of loop {loopLabel}", "ActionPanel.action.moveToPreviousStep.outOfLoop": "Move Step {stepNumber} {stepActionName} out of loop {loopLabel}", "ActionPanel.action.replace.noSelectedAction": "Replace Step {stepNumber} {stepActionName}", "ActionPanel.action.replace.withSelectedAction": "Replace Step {stepNumber} {stepActionName} with selected action {selectedActionName}", @@ -952,7 +952,7 @@ "Savannah.pond": "l'étang", "Savannah.tree": "l'arbre", "Save": "Sauvegarder", - "Scene.description": "Scène, dans {world}, grille {numColumns} par {numRows}. {characterDescription}", + "Scene.description": "Scène, dans {backgroundName}, grille {numColumns} par {numRows}. {characterDescription}", "Scene.heading": "scène", "SceneMessage.close": "fermée le message", "ShareButton": "partager", From 8bb37d675c7f8fb395f5759eed861ff87deb8ead Mon Sep 17 00:00:00 2001 From: Simon Bates Date: Thu, 24 Oct 2024 13:24:05 -0400 Subject: [PATCH 16/23] Add messages2tsv.js and tsv2messages.js --- tools/messages2tsv.js | 52 +++++++++++++++++++++++++++++++++++++++++++ tools/tsv2messages.js | 49 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 tools/messages2tsv.js create mode 100644 tools/tsv2messages.js diff --git a/tools/messages2tsv.js b/tools/messages2tsv.js new file mode 100644 index 00000000..5141b2c9 --- /dev/null +++ b/tools/messages2tsv.js @@ -0,0 +1,52 @@ +const fs = require('fs'); + +function writeTSV(messages, stream) { + const langCodes = getLangCodes(messages); + const messageKeys = getAllMessageKeys(messages, langCodes); + // Header + stream.write("keys"); + for (const lang of langCodes) { + stream.write(`\t${lang}`); + } + stream.write("\n"); + // Messages + for (const key of messageKeys) { + stream.write(key); + for (const lang of langCodes) { + stream.write("\t"); + if (Object.hasOwn(messages[lang], key)) { + stream.write(messages[lang][key]); + } else { + stream.write("MISSING"); + } + } + stream.write("\n"); + } +} + +function getLangCodes(messages) { + return Object.keys(messages).sort(); +} + +function getAllMessageKeys(messages, langCodes) { + const messageKeys = new Set(); + for (const lang of langCodes) { + for (const key of Object.keys(messages[lang])) { + messageKeys.add(key); + } + } + return Array.from(messageKeys).sort(); +} + +if (process.argv.length !== 4) { + process.stderr.write("usage: messages2tsv.js output-file input-file\n"); + process.exit(2); +} + +const outputFilename = process.argv[2]; +const inputFilename = process.argv[3]; + +const messages = JSON.parse(fs.readFileSync(inputFilename, {encoding: 'utf8'})); +const outStream = fs.createWriteStream(outputFilename, {encoding: 'utf8'}); + +writeTSV(messages, outStream); diff --git a/tools/tsv2messages.js b/tools/tsv2messages.js new file mode 100644 index 00000000..ff7c8539 --- /dev/null +++ b/tools/tsv2messages.js @@ -0,0 +1,49 @@ +const fs = require('fs'); +const readline = require('readline'); + +function readMessagesFromTSV(stream, callback) { + let langCodes = []; + const messages = {}; + + const rl = readline.createInterface({ + input: stream, + crlfDelay: Infinity + }); + + let firstLine = true; + rl.on('line', (line) => { + const cols = line.split("\t"); + if (firstLine) { + langCodes = cols.slice(1); + for (const lang of langCodes) { + messages[lang] = {}; + } + firstLine = false; + } else { + if (cols.length > 0) { + const key = cols[0]; + for (let i = 0; i < langCodes.length; i++) { + messages[langCodes[i]][key] = cols[i+1]; + } + } + } + }); + + rl.on('close', () => { + callback(messages); + }); +} + +if (process.argv.length !== 4) { + process.stderr.write("usage: tsv2messages.js output-file input-file\n"); + process.exit(2); +} + +const outputFilename = process.argv[2]; +const inputFilename = process.argv[3]; + +const inStream = fs.createReadStream(inputFilename, {encoding: 'utf8'}); + +readMessagesFromTSV(inStream, (messages) => { + fs.writeFileSync(outputFilename, JSON.stringify(messages, null, 4), {encoding: 'utf8'}); +}); From db78632f646594965290aa5fb5d8e807e6276117 Mon Sep 17 00:00:00 2001 From: Simon Bates Date: Thu, 24 Oct 2024 13:47:56 -0400 Subject: [PATCH 17/23] Sort messages.json keys in ASCII order --- src/messages.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/messages.json b/src/messages.json index dd3ffc13..e508e9d6 100644 --- a/src/messages.json +++ b/src/messages.json @@ -3,14 +3,14 @@ "ActionPanel.action.delete": "Delete Step {stepNumber} {stepActionName}", "ActionPanel.action.moveToNextStep": "Move Step {stepNumber} {stepActionName} after step {nextStepNumber} {nextStepActionName}", "ActionPanel.action.moveToNextStep.disabled": "Move Step {stepNumber} {stepActionName}", + "ActionPanel.action.moveToNextStep.intoLoop": "Move Step {stepNumber} {stepActionName} into loop {loopLabel}", "ActionPanel.action.moveToNextStep.outOfLoop": "Move Step {stepNumber} {stepActionName} out of loop {loopLabel}", "ActionPanel.action.moveToNextStep.withinLoop": "Move Step {stepNumber} {stepActionName} after step {nextStepNumber} {nextStepActionName} of loop {loopLabel}", - "ActionPanel.action.moveToNextStep.intoLoop": "Move Step {stepNumber} {stepActionName} into loop {loopLabel}", "ActionPanel.action.moveToPreviousStep": "Move Step {stepNumber} {stepActionName} before step {previousStepNumber} {previousStepActionName}", "ActionPanel.action.moveToPreviousStep.disabled": "Move Step {stepNumber} {stepActionName}", "ActionPanel.action.moveToPreviousStep.intoLoop": "Move Step {stepNumber} {stepActionName} into loop {loopLabel}", - "ActionPanel.action.moveToPreviousStep.withinLoop": "Move Step {stepNumber} {stepActionName} before step {previousStepNumber} {previousStepActionName} of loop {loopLabel}", "ActionPanel.action.moveToPreviousStep.outOfLoop": "Move Step {stepNumber} {stepActionName} out of loop {loopLabel}", + "ActionPanel.action.moveToPreviousStep.withinLoop": "Move Step {stepNumber} {stepActionName} before step {previousStepNumber} {previousStepActionName} of loop {loopLabel}", "ActionPanel.action.replace.noSelectedAction": "Replace Step {stepNumber} {stepActionName}", "ActionPanel.action.replace.withSelectedAction": "Replace Step {stepNumber} {stepActionName} with selected action {selectedActionName}", "ActionsMenu.title": "Actions", @@ -58,9 +58,9 @@ "Announcement.left45": "turn left 45 degrees", "Announcement.left90": "turn left 90 degrees", "Announcement.loop": "loop", - "Announcement.movement": "movement", "Announcement.moveToNext": "moved to right", "Announcement.moveToPrevious": "moved to left", + "Announcement.movement": "movement", "Announcement.noActionSelected": "no action selected", "Announcement.replace": "movement {oldActionName} replaced with {newActionName}", "Announcement.right180": "turn right 180 degrees", @@ -184,7 +184,6 @@ "EuropeTrip.C5": "Spain", "EuropeTrip.C6": "Portugal and Spain", "EuropeTrip.C7": "Flamenco guitar on Spain", - "EuropeTrip.character": "the airplane", "EuropeTrip.D2": "Ireland and the United Kingdom", "EuropeTrip.D3": "a shamrock on Ireland; also in this square the United Kingdom", "EuropeTrip.D4": "France and the United Kingdom", @@ -245,6 +244,7 @@ "EuropeTrip.L5": "Ukraine", "EuropeTrip.L7": "Türkiye", "EuropeTrip.L8": "olives on Cyprus; also in this square Türkiye", + "EuropeTrip.character": "the airplane", "EuropeTrip.label": "A Europe trip scene containing a map of Europe with tourist attractions. Iceland is located near the top left of the scene. Cyprus is located at the bottom right of the scene. Tourist attractions are located on the country known for the attraction, such as the violin on Austria near the centre of the scene. Your character in this scene is an airplane.", "EuropeTrip.name": "Europe Trip", "GroceryStore.apples": "apples", @@ -359,8 +359,8 @@ "Landmarks.niagaraFalls": "Niagara Falls", "Landmarks.operaHouse": "The Sydney Opera House", "Landmarks.plane": "a plane", - "Landmarks.statueLiberty": "The Statue of Liberty", "Landmarks.stBasils": "Saint Basil's Cathedral", + "Landmarks.statueLiberty": "The Statue of Liberty", "Landmarks.stonehenge": "Stonehenge", "Landmarks.tableMountain": "Table Mountain", "Landmarks.tajMahal": "The Taj Mahal Palace", @@ -583,9 +583,9 @@ "Announcement.left45": "tourner à gauche de 45 degrées", "Announcement.left90": "tourner a gauche de 90 degréees", "Announcement.loop": "boucle", - "Announcement.movement": "mouvement", "Announcement.moveToNext": "déplacer vers la droite", "Announcement.moveToPrevious": "déplacer vers la gauche", + "Announcement.movement": "mouvement", "Announcement.noActionSelected": "aucune action sélectionnée", "Announcement.replace": "mouvement {oldActionName} remplacer par une {newActionName}", "Announcement.right180": "turner a droite 180 degrées", @@ -719,7 +719,6 @@ "EuropeTrip.C5": "Espagne", "EuropeTrip.C6": "Portugal et Espagne", "EuropeTrip.C7": "Guitare Flamenco en Espagne", - "EuropeTrip.character": "l'avion", "EuropeTrip.D2": "Irlande et le Royaume-Uni", "EuropeTrip.D3": "un trèfle en irlande; aussi sur cette place le Royaume-Uni", "EuropeTrip.D4": "France te le Royaume-Uni", @@ -780,6 +779,7 @@ "EuropeTrip.L5": "Ukraine", "EuropeTrip.L7": "Turquie", "EuropeTrip.L8": "olives en Chypre; aussi sur cette case Turquie", + "EuropeTrip.character": "l'avion", "EuropeTrip.label": "Une scène de voyage en Europe contenant une carte de Europe avec des attractions touristiques. L'Islande est située en haut à gauche de la scène. Chypre est située en bas à droite de la scène. Les attractions touristiques sont située dans le pays connu pour des attractions, comme le Violon en Autriche, près du centre de la scène. Votre personnage dans cette scène est un avion.", "EuropeTrip.name": "Voyage en Europe", "GroceryStore.apples": "pommes", @@ -894,8 +894,8 @@ "Landmarks.niagaraFalls": "chutes du Niagara", "Landmarks.operaHouse": "L'Opéra de Sydney", "Landmarks.plane": "un avion", - "Landmarks.statueLiberty": "la statue de la Liberté", "Landmarks.stBasils": "Cathédrale Saint-Basile", + "Landmarks.statueLiberty": "la statue de la Liberté", "Landmarks.stonehenge": "Stonehenge", "Landmarks.tableMountain": "table montagne", "Landmarks.tajMahal": "le palais Taj Mahal", From f7f90111516e80332a25ed80e48486c7674a7878 Mon Sep 17 00:00:00 2001 From: Simon Bates Date: Fri, 25 Oct 2024 10:39:50 -0400 Subject: [PATCH 18/23] Add check_messages.js --- tools/check_messages.js | 30 ++++++++++++++++++++++++++++++ tools/messages2tsv.js | 21 ++++----------------- tools/messagesUtils.js | 19 +++++++++++++++++++ 3 files changed, 53 insertions(+), 17 deletions(-) create mode 100644 tools/check_messages.js create mode 100644 tools/messagesUtils.js diff --git a/tools/check_messages.js b/tools/check_messages.js new file mode 100644 index 00000000..cc351461 --- /dev/null +++ b/tools/check_messages.js @@ -0,0 +1,30 @@ +const messagesUtils = require('./messagesUtils.js'); + +function checkMessages(messages) { + const langCodes = messagesUtils.getLangCodes(messages); + const messageKeys = messagesUtils.getAllMessageKeys(messages, langCodes); + let ok = true; + for (const lang of langCodes) { + for (const key of messageKeys) { + if (!Object.hasOwn(messages[lang], key)) { + process.stderr.write(`Missing: ${lang}.${key}\n`); + ok = false; + } + } + } + return ok; +} + +if (process.argv.length !== 3) { + process.stderr.write("usage: check_messages.js file\n"); + process.exit(2); +} + +const filename = process.argv[2]; + +const messages = messagesUtils.loadMessages(filename); + +const ok = checkMessages(messages); +if (!ok) { + process.exit(1); +} diff --git a/tools/messages2tsv.js b/tools/messages2tsv.js index 5141b2c9..a03a642d 100644 --- a/tools/messages2tsv.js +++ b/tools/messages2tsv.js @@ -1,8 +1,9 @@ const fs = require('fs'); +const messagesUtils = require('./messagesUtils.js'); function writeTSV(messages, stream) { - const langCodes = getLangCodes(messages); - const messageKeys = getAllMessageKeys(messages, langCodes); + const langCodes = messagesUtils.getLangCodes(messages); + const messageKeys = messagesUtils.getAllMessageKeys(messages, langCodes); // Header stream.write("keys"); for (const lang of langCodes) { @@ -24,20 +25,6 @@ function writeTSV(messages, stream) { } } -function getLangCodes(messages) { - return Object.keys(messages).sort(); -} - -function getAllMessageKeys(messages, langCodes) { - const messageKeys = new Set(); - for (const lang of langCodes) { - for (const key of Object.keys(messages[lang])) { - messageKeys.add(key); - } - } - return Array.from(messageKeys).sort(); -} - if (process.argv.length !== 4) { process.stderr.write("usage: messages2tsv.js output-file input-file\n"); process.exit(2); @@ -46,7 +33,7 @@ if (process.argv.length !== 4) { const outputFilename = process.argv[2]; const inputFilename = process.argv[3]; -const messages = JSON.parse(fs.readFileSync(inputFilename, {encoding: 'utf8'})); +const messages = messagesUtils.loadMessages(inputFilename); const outStream = fs.createWriteStream(outputFilename, {encoding: 'utf8'}); writeTSV(messages, outStream); diff --git a/tools/messagesUtils.js b/tools/messagesUtils.js new file mode 100644 index 00000000..d4ced3c4 --- /dev/null +++ b/tools/messagesUtils.js @@ -0,0 +1,19 @@ +const fs = require('fs'); + +exports.loadMessages = function(filename) { + return JSON.parse(fs.readFileSync(filename, {encoding: 'utf8'})); +}; + +exports.getLangCodes = function(messages) { + return Object.keys(messages).sort(); +}; + +exports.getAllMessageKeys = function(messages, langCodes) { + const messageKeys = new Set(); + for (const lang of langCodes) { + for (const key of Object.keys(messages[lang])) { + messageKeys.add(key); + } + } + return Array.from(messageKeys).sort(); +}; From 3f658591bb23c61ac7ad1aeda9392bc488ba020e Mon Sep 17 00:00:00 2001 From: Simon Bates Date: Fri, 25 Oct 2024 10:43:33 -0400 Subject: [PATCH 19/23] Use Unix line endings --- tools/messages2tsv.js | 78 +++++++++++++++++----------------- tools/tsv2messages.js | 98 +++++++++++++++++++++---------------------- 2 files changed, 88 insertions(+), 88 deletions(-) diff --git a/tools/messages2tsv.js b/tools/messages2tsv.js index a03a642d..e7211730 100644 --- a/tools/messages2tsv.js +++ b/tools/messages2tsv.js @@ -1,39 +1,39 @@ -const fs = require('fs'); -const messagesUtils = require('./messagesUtils.js'); - -function writeTSV(messages, stream) { - const langCodes = messagesUtils.getLangCodes(messages); - const messageKeys = messagesUtils.getAllMessageKeys(messages, langCodes); - // Header - stream.write("keys"); - for (const lang of langCodes) { - stream.write(`\t${lang}`); - } - stream.write("\n"); - // Messages - for (const key of messageKeys) { - stream.write(key); - for (const lang of langCodes) { - stream.write("\t"); - if (Object.hasOwn(messages[lang], key)) { - stream.write(messages[lang][key]); - } else { - stream.write("MISSING"); - } - } - stream.write("\n"); - } -} - -if (process.argv.length !== 4) { - process.stderr.write("usage: messages2tsv.js output-file input-file\n"); - process.exit(2); -} - -const outputFilename = process.argv[2]; -const inputFilename = process.argv[3]; - -const messages = messagesUtils.loadMessages(inputFilename); -const outStream = fs.createWriteStream(outputFilename, {encoding: 'utf8'}); - -writeTSV(messages, outStream); +const fs = require('fs'); +const messagesUtils = require('./messagesUtils.js'); + +function writeTSV(messages, stream) { + const langCodes = messagesUtils.getLangCodes(messages); + const messageKeys = messagesUtils.getAllMessageKeys(messages, langCodes); + // Header + stream.write("keys"); + for (const lang of langCodes) { + stream.write(`\t${lang}`); + } + stream.write("\n"); + // Messages + for (const key of messageKeys) { + stream.write(key); + for (const lang of langCodes) { + stream.write("\t"); + if (Object.hasOwn(messages[lang], key)) { + stream.write(messages[lang][key]); + } else { + stream.write("MISSING"); + } + } + stream.write("\n"); + } +} + +if (process.argv.length !== 4) { + process.stderr.write("usage: messages2tsv.js output-file input-file\n"); + process.exit(2); +} + +const outputFilename = process.argv[2]; +const inputFilename = process.argv[3]; + +const messages = messagesUtils.loadMessages(inputFilename); +const outStream = fs.createWriteStream(outputFilename, {encoding: 'utf8'}); + +writeTSV(messages, outStream); diff --git a/tools/tsv2messages.js b/tools/tsv2messages.js index ff7c8539..408d91ae 100644 --- a/tools/tsv2messages.js +++ b/tools/tsv2messages.js @@ -1,49 +1,49 @@ -const fs = require('fs'); -const readline = require('readline'); - -function readMessagesFromTSV(stream, callback) { - let langCodes = []; - const messages = {}; - - const rl = readline.createInterface({ - input: stream, - crlfDelay: Infinity - }); - - let firstLine = true; - rl.on('line', (line) => { - const cols = line.split("\t"); - if (firstLine) { - langCodes = cols.slice(1); - for (const lang of langCodes) { - messages[lang] = {}; - } - firstLine = false; - } else { - if (cols.length > 0) { - const key = cols[0]; - for (let i = 0; i < langCodes.length; i++) { - messages[langCodes[i]][key] = cols[i+1]; - } - } - } - }); - - rl.on('close', () => { - callback(messages); - }); -} - -if (process.argv.length !== 4) { - process.stderr.write("usage: tsv2messages.js output-file input-file\n"); - process.exit(2); -} - -const outputFilename = process.argv[2]; -const inputFilename = process.argv[3]; - -const inStream = fs.createReadStream(inputFilename, {encoding: 'utf8'}); - -readMessagesFromTSV(inStream, (messages) => { - fs.writeFileSync(outputFilename, JSON.stringify(messages, null, 4), {encoding: 'utf8'}); -}); +const fs = require('fs'); +const readline = require('readline'); + +function readMessagesFromTSV(stream, callback) { + let langCodes = []; + const messages = {}; + + const rl = readline.createInterface({ + input: stream, + crlfDelay: Infinity + }); + + let firstLine = true; + rl.on('line', (line) => { + const cols = line.split("\t"); + if (firstLine) { + langCodes = cols.slice(1); + for (const lang of langCodes) { + messages[lang] = {}; + } + firstLine = false; + } else { + if (cols.length > 0) { + const key = cols[0]; + for (let i = 0; i < langCodes.length; i++) { + messages[langCodes[i]][key] = cols[i+1]; + } + } + } + }); + + rl.on('close', () => { + callback(messages); + }); +} + +if (process.argv.length !== 4) { + process.stderr.write("usage: tsv2messages.js output-file input-file\n"); + process.exit(2); +} + +const outputFilename = process.argv[2]; +const inputFilename = process.argv[3]; + +const inStream = fs.createReadStream(inputFilename, {encoding: 'utf8'}); + +readMessagesFromTSV(inStream, (messages) => { + fs.writeFileSync(outputFilename, JSON.stringify(messages, null, 4), {encoding: 'utf8'}); +}); From dd5ab8e10a55d3a33a7402f65bed9e04e8571de7 Mon Sep 17 00:00:00 2001 From: Simon Bates Date: Mon, 28 Oct 2024 13:52:22 -0400 Subject: [PATCH 20/23] Add "UI." prefix to messages that are visible in the UI --- docs/adding-new-world-checklist.md | 2 +- src/ActionsMenuItem.js | 4 +- src/ActionsSimplificationModal.js | 10 +- src/App.js | 12 +- src/CharacterMessageBuilder.js | 4 +- src/ConfirmDeleteAllModal.js | 10 +- src/KeyboardInputModal.js | 24 +- src/KeyboardInputSchemes.js | 44 +-- src/PrivacyModal.js | 68 ++--- src/ProgramBlockEditor.js | 2 +- src/Scene.js | 2 +- src/ShareModal.js | 12 +- src/SoundOptionsModal.js | 16 +- src/ThemeSelector.js | 8 +- src/WorldSelector.js | 10 +- src/messages.json | 452 ++++++++++++++--------------- 16 files changed, 339 insertions(+), 341 deletions(-) diff --git a/docs/adding-new-world-checklist.md b/docs/adding-new-world-checklist.md index d49b4162..29b0e242 100644 --- a/docs/adding-new-world-checklist.md +++ b/docs/adding-new-world-checklist.md @@ -23,7 +23,7 @@ `'All worlds should be displayed as options and only one is checked'` test in `WorldSelector.test.js` for the new world - Add entries to `messages.json` - - `.name`: the name of the world + - `UI..name`: the name of the world - `.character`: the name of the character - `.label`: the label used for the world in the Scene Background dialog diff --git a/src/ActionsMenuItem.js b/src/ActionsMenuItem.js index 79e95338..2e248ce8 100644 --- a/src/ActionsMenuItem.js +++ b/src/ActionsMenuItem.js @@ -34,8 +34,8 @@ export class ActionsMenuItem extends React.Component< ActionsMenuItemProps, {} > render () { // We don't use FormattedMessage as we are working with a complex chain of templates. - let commandName = this.props.intl.formatMessage({ id: `ActionsMenuItem.command.${this.props.itemKey}` }); - const usedLabel = this.props.intl.formatMessage({ id: 'ActionsMenuItem.usedItemToggleLabel' }); + let commandName = this.props.intl.formatMessage({ id: `UI.ActionsMenuItem.command.${this.props.itemKey}` }); + const usedLabel = this.props.intl.formatMessage({ id: 'UI.ActionsMenuItem.usedItemToggleLabel' }); if (this.props.isUsed) { commandName += " " + usedLabel; } diff --git a/src/ActionsSimplificationModal.js b/src/ActionsSimplificationModal.js index 33893ad2..f7a397a3 100644 --- a/src/ActionsSimplificationModal.js +++ b/src/ActionsSimplificationModal.js @@ -54,14 +54,14 @@ class ActionsSimplificationModal extends React.Component

- +

@@ -91,7 +91,7 @@ class ActionsSimplificationModal extends React.Component - +
diff --git a/src/App.js b/src/App.js index 03333440..f9e1ecb2 100644 --- a/src/App.js +++ b/src/App.js @@ -1321,13 +1321,13 @@ export class App extends React.Component { className="App__PrivacyModal__toggle-button" onClick={this.handleClickPrivacyButton} > - +
{

- +

- +

@@ -1508,7 +1508,7 @@ export class App extends React.Component {

- +

@@ -1601,7 +1601,7 @@ export class App extends React.Component { aria-hidden={true} />
- {this.props.intl.formatMessage({id:'ShareButton'})} + {this.props.intl.formatMessage({id:'UI.ShareButton'})}
diff --git a/src/CharacterMessageBuilder.js b/src/CharacterMessageBuilder.js index c04db41a..43d6a580 100644 --- a/src/CharacterMessageBuilder.js +++ b/src/CharacterMessageBuilder.js @@ -27,7 +27,7 @@ export default class CharacterMessageBuilder { buildEndOfSceneMessage(): string { return this.intl.formatMessage( { - id:'CharacterMessageBuilder.endOfScene' + id:'UI.CharacterMessageBuilder.endOfScene' } ); } @@ -37,7 +37,7 @@ export default class CharacterMessageBuilder { const rowLabel = this.dimensions.getRowLabel(y); return this.intl.formatMessage( { - id:'CharacterMessageBuilder.hitWall' + id:'UI.CharacterMessageBuilder.hitWall' }, { columnLabel: columnLabel == null ? '' : columnLabel, diff --git a/src/ConfirmDeleteAllModal.js b/src/ConfirmDeleteAllModal.js index 695077f8..d99f67ac 100644 --- a/src/ConfirmDeleteAllModal.js +++ b/src/ConfirmDeleteAllModal.js @@ -23,24 +23,24 @@ class ConfirmDeleteAllModal extends React.Component
- +
diff --git a/src/KeyboardInputModal.js b/src/KeyboardInputModal.js index b733a902..dc4fde65 100644 --- a/src/KeyboardInputModal.js +++ b/src/KeyboardInputModal.js @@ -115,12 +115,12 @@ class KeyboardInputModal extends React.Component {altKeyIcon} @@ -129,12 +129,12 @@ class KeyboardInputModal extends React.Component {controlKeyIcon} @@ -142,7 +142,7 @@ class KeyboardInputModal extends React.Component
@@ -165,7 +165,7 @@ class KeyboardInputModal extends React.Component { - const messageId = "KeyboardInputModal.Scheme.Descriptions." + schemeName; + const messageId = "UI.KeyboardInputModal.Scheme.Descriptions." + schemeName; const optionText = this.props.intl.formatMessage({ id: messageId }); selectOptionElements.push(
diff --git a/src/KeyboardInputSchemes.js b/src/KeyboardInputSchemes.js index ff9e377f..2f382987 100644 --- a/src/KeyboardInputSchemes.js +++ b/src/KeyboardInputSchemes.js @@ -543,20 +543,20 @@ export const KeyboardInputSchemes: KeyboardInputSchemesType = { }; const labelMessageKeysByCode = { - "KeyA": "KeyboardInputModal.KeyLabels.A", - "KeyB": "KeyboardInputModal.KeyLabels.B", - "KeyD": "KeyboardInputModal.KeyLabels.D", - "KeyE": "KeyboardInputModal.KeyLabels.E", - "KeyI": "KeyboardInputModal.KeyLabels.I", - "KeyP": "KeyboardInputModal.KeyLabels.P", - "KeyS": "KeyboardInputModal.KeyLabels.S", - "KeyR": "KeyboardInputModal.KeyLabels.R" + "KeyA": "UI.KeyboardInputModal.KeyLabels.A", + "KeyB": "UI.KeyboardInputModal.KeyLabels.B", + "KeyD": "UI.KeyboardInputModal.KeyLabels.D", + "KeyE": "UI.KeyboardInputModal.KeyLabels.E", + "KeyI": "UI.KeyboardInputModal.KeyLabels.I", + "KeyP": "UI.KeyboardInputModal.KeyLabels.P", + "KeyS": "UI.KeyboardInputModal.KeyLabels.S", + "KeyR": "UI.KeyboardInputModal.KeyLabels.R" }; const labelMessageKeysByKey = { - "?": "KeyboardInputModal.KeyLabels.QuestionMark", - ">": "KeyboardInputModal.KeyLabels.GreaterThan", - "<": "KeyboardInputModal.KeyLabels.LessThan" + "?": "UI.KeyboardInputModal.KeyLabels.QuestionMark", + ">": "UI.KeyboardInputModal.KeyLabels.GreaterThan", + "<": "UI.KeyboardInputModal.KeyLabels.LessThan" }; export function getLabelMessageKeyFromKeyDef (keyDef: KeyDef) { @@ -572,20 +572,20 @@ export function getLabelMessageKeyFromKeyDef (keyDef: KeyDef) { }; const iconMessageKeysByCode = { - "KeyA": "KeyboardInputModal.KeyIcons.A", - "KeyB": "KeyboardInputModal.KeyIcons.B", - "KeyD": "KeyboardInputModal.KeyIcons.D", - "KeyE": "KeyboardInputModal.KeyIcons.E", - "KeyI": "KeyboardInputModal.KeyIcons.I", - "KeyP": "KeyboardInputModal.KeyIcons.P", - "KeyS": "KeyboardInputModal.KeyIcons.S", - "KeyR": "KeyboardInputModal.KeyIcons.R" + "KeyA": "UI.KeyboardInputModal.KeyIcons.A", + "KeyB": "UI.KeyboardInputModal.KeyIcons.B", + "KeyD": "UI.KeyboardInputModal.KeyIcons.D", + "KeyE": "UI.KeyboardInputModal.KeyIcons.E", + "KeyI": "UI.KeyboardInputModal.KeyIcons.I", + "KeyP": "UI.KeyboardInputModal.KeyIcons.P", + "KeyS": "UI.KeyboardInputModal.KeyIcons.S", + "KeyR": "UI.KeyboardInputModal.KeyIcons.R" }; const iconMessageKeysByKey = { - "?": "KeyboardInputModal.KeyIcons.QuestionMark", - ">": "KeyboardInputModal.KeyIcons.GreaterThan", - "<": "KeyboardInputModal.KeyIcons.LessThan" + "?": "UI.KeyboardInputModal.KeyIcons.QuestionMark", + ">": "UI.KeyboardInputModal.KeyIcons.GreaterThan", + "<": "UI.KeyboardInputModal.KeyIcons.LessThan" }; export function getIconMessageKeyFromKeyDef (keyDef: KeyDef) { diff --git a/src/PrivacyModal.js b/src/PrivacyModal.js index 34b70dcf..ce812a77 100644 --- a/src/PrivacyModal.js +++ b/src/PrivacyModal.js @@ -20,7 +20,7 @@ type PrivacyModalProps = { class PrivacyModal extends React.Component { render() { const closeButtonProperties = { - label: this.props.intl.formatMessage({ id: 'PrivacyModal.close'} ), + label: this.props.intl.formatMessage({ id: 'UI.Close'} ), isPrimary: true, onClick: this.props.onClose }; @@ -35,76 +35,76 @@ class PrivacyModal extends React.Component { >
-
{this.props.intl.formatMessage({ id: 'PrivacyModal.section010.Heading'})}
+
{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section010.Heading'})}
-

{this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block010'})}

-

{this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block020'})}

+

{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section010.block010'})}

+

{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section010.block020'})}

    -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.item010'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.item020'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section010.block030.item030'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section010.block030.item010'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section010.block030.item020'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section010.block030.item030'})}
-
{this.props.intl.formatMessage({ id: 'PrivacyModal.section020.Heading'})}
+
{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section020.Heading'})}
-

{this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block010'})}

+

{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section020.block010'})}

    -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item010'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item020'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item030'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item040'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item050'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item060'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item070'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block020.item080'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section020.block020.item010'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section020.block020.item020'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section020.block020.item030'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section020.block020.item040'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section020.block020.item050'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section020.block020.item060'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section020.block020.item070'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section020.block020.item080'})}
-

{this.props.intl.formatMessage({ id: 'PrivacyModal.section020.block030'})}

+

{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section020.block030'})}

-
{this.props.intl.formatMessage({ id: 'PrivacyModal.section030.Heading'})}
+
{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section030.Heading'})}
-

{this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block010'})}

+

{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section030.block010'})}

    -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block020.item010'})}
  • -
  • {this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block020.item020'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section030.block020.item010'})}
  • +
  • {this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section030.block020.item020'})}
-

{this.props.intl.formatMessage({ id: 'PrivacyModal.section030.block030'})}

+

{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section030.block030'})}

-
{this.props.intl.formatMessage({ id: 'PrivacyModal.section040.Heading'})}
+
{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section040.Heading'})}
-

{this.props.intl.formatMessage({ id: 'PrivacyModal.section040.block010'})}

+

{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section040.block010'})}

-
{this.props.intl.formatMessage({ id: 'PrivacyModal.section050.Heading'})}
+
{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section050.Heading'})}

${this.props.intl.formatMessage({ id: 'PrivacyModal.contactUs' })}` } + { id: 'UI.PrivacyModal.section050.block010'}, + { contactLink: `${this.props.intl.formatMessage({ id: 'UI.PrivacyModal.contactUs' })}` } )} }>

-
{this.props.intl.formatMessage({ id: 'PrivacyModal.section060.Heading'})}
+
{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section060.Heading'})}
-

{this.props.intl.formatMessage({ id: 'PrivacyModal.section060.block010'})}

+

{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section060.block010'})}

-
{this.props.intl.formatMessage({ id: 'PrivacyModal.section070.Heading'})}
+
{this.props.intl.formatMessage({ id: 'UI.PrivacyModal.section070.Heading'})}

${this.props.intl.formatMessage({ id: 'PrivacyModal.contactUs' })}` } + { id: 'UI.PrivacyModal.section070.block010'}, + { contactLink: `${this.props.intl.formatMessage({ id: 'UI.PrivacyModal.contactUs' })}` } )} }>

diff --git a/src/ProgramBlockEditor.js b/src/ProgramBlockEditor.js index b076b989..7310f393 100644 --- a/src/ProgramBlockEditor.js +++ b/src/ProgramBlockEditor.js @@ -757,7 +757,7 @@ export class ProgramBlockEditor extends React.Component

- +

{ } generateAriaLabel() { - const backgroundName = this.props.intl.formatMessage({id: this.props.world + '.name'}); + const backgroundName = this.props.intl.formatMessage({id: `UI.${this.props.world}.name`}); const numColumns = this.props.dimensions.getWidth(); const numRows = this.props.dimensions.getHeight(); diff --git a/src/ShareModal.js b/src/ShareModal.js index 4be33db7..e639dac5 100644 --- a/src/ShareModal.js +++ b/src/ShareModal.js @@ -27,34 +27,34 @@ class ShareModal extends React.Component { render () { const buttonProperties = [{ - label: this.props.intl.formatMessage({id: 'ShareModal.close'}), + label: this.props.intl.formatMessage({id: 'UI.Close'}), onClick: this.props.onClose, isPrimary: false }]; - const copyButtonLabel = this.props.intl.formatMessage({ id: 'ShareModal.copy'}); + const copyButtonLabel = this.props.intl.formatMessage({ id: 'UI.ShareModal.copy'}); return(
-

-

+

+

- {this.props.intl.formatMessage({ id: 'Off' })} + {this.props.intl.formatMessage({ id: 'UI.Off' })}
- {this.props.intl.formatMessage({ id: 'On' })} + {this.props.intl.formatMessage({ id: 'UI.On' })}
@@ -126,14 +126,14 @@ class SoundOptionsModal extends React.Component diff --git a/src/ThemeSelector.js b/src/ThemeSelector.js index f1582b51..a85dcd8b 100644 --- a/src/ThemeSelector.js +++ b/src/ThemeSelector.js @@ -106,7 +106,7 @@ class ThemeSelector extends React.Component - +
); } @@ -131,13 +131,13 @@ class ThemeSelector extends React.Component diff --git a/src/WorldSelector.js b/src/WorldSelector.js index 54e1a316..630cc5b4 100644 --- a/src/WorldSelector.js +++ b/src/WorldSelector.js @@ -127,7 +127,7 @@ class WorldSelector extends React.Component
@@ -166,20 +166,20 @@ class WorldSelector extends React.Component
- +
{this.renderWorldOptions()}
diff --git a/src/messages.json b/src/messages.json index e508e9d6..0097dd91 100644 --- a/src/messages.json +++ b/src/messages.json @@ -13,17 +13,17 @@ "ActionPanel.action.moveToPreviousStep.withinLoop": "Move Step {stepNumber} {stepActionName} before step {previousStepNumber} {previousStepActionName} of loop {loopLabel}", "ActionPanel.action.replace.noSelectedAction": "Replace Step {stepNumber} {stepActionName}", "ActionPanel.action.replace.withSelectedAction": "Replace Step {stepNumber} {stepActionName} with selected action {selectedActionName}", - "ActionsMenu.title": "Actions", + "UI.ActionsMenu.title": "Actions", "ActionsMenu.toggleActionsMenu": "configure available actions", - "ActionsMenuItem.command.backward1": "Move backward 1 step", - "ActionsMenuItem.command.forward1": "Move forward 1 step", - "ActionsMenuItem.command.left45": "Turn left 45 degrees", - "ActionsMenuItem.command.left90": "Turn left 90 degrees", - "ActionsMenuItem.command.loop": "Loop", - "ActionsMenuItem.command.right45": "Turn right 45 degrees", - "ActionsMenuItem.command.right90": "Turn right 90 degrees", - "ActionsMenuItem.usedItemToggleLabel": "(Used)", - "ActionsSimplificationModal.title": "Available Actions", + "UI.ActionsMenuItem.command.backward1": "Move backward 1 step", + "UI.ActionsMenuItem.command.forward1": "Move forward 1 step", + "UI.ActionsMenuItem.command.left45": "Turn left 45 degrees", + "UI.ActionsMenuItem.command.left90": "Turn left 90 degrees", + "UI.ActionsMenuItem.command.loop": "Loop", + "UI.ActionsMenuItem.command.right45": "Turn right 45 degrees", + "UI.ActionsMenuItem.command.right90": "Turn right 90 degrees", + "UI.ActionsMenuItem.usedItemToggleLabel": "(Used)", + "UI.ActionsSimplificationModal.title": "Available Actions", "AmusementPark.character": "the train", "AmusementPark.entrance": "entrance", "AmusementPark.ferrisWheel": "ferris wheel", @@ -31,7 +31,7 @@ "AmusementPark.goKarts": "go karts", "AmusementPark.label": "An amusement park scene. A scene with your favourite rides; there's a roller coaster, ferris wheel, pirate ship, go karts, swing ride and merry go round! There's other fun things to do, like a game booth and water park, and if you want some snacks, there is a snack stand as well. Your character is a train.", "AmusementPark.merryGoRound": "merry go round", - "AmusementPark.name": "Amusement Park", + "UI.AmusementPark.name": "Amusement Park", "AmusementPark.pirateShip": "pirate ship", "AmusementPark.rollerCoaster": "roller coaster", "AmusementPark.snackStand": "snack stand", @@ -70,7 +70,7 @@ "App.appHeading": "Weavly", "App.appHeading.link": "Weavly, learn more about Weavly at Weavly dot org", "App.connectToDash": "Connect to Dash", - "App.privacyModalToggle": "Privacy", + "UI.App.privacyModalToggle": "Privacy", "App.privacyModalToggle.ariaLabel": "Weavly privacy policy", "AtlanticCanada.character": "Cape islander", "AtlanticCanada.fishProcessingPlant": "a fish processing plant", @@ -80,7 +80,7 @@ "AtlanticCanada.label": "Atlantic Canada scene. Travel Atlantic Canada through the Atlantic ocean. Weather is unpredictable in the Atlantic ocean, some parts of the ocean can be stormy, and some parts of the ocean can be covered with fog. Travel safe to visit a fish processing plant, and a village on the land; you might face icebergs or whales on the way. Your character in this scene is a fishing boat, also known as a Cape Islander in Atlantic Canada.", "AtlanticCanada.land": "the land", "AtlanticCanada.lighthouse": "a light house", - "AtlanticCanada.name": "Atlantic Canada", + "UI.AtlanticCanada.name": "Atlantic Canada", "AtlanticCanada.rowingBoatOnTheShore": "a rowing boat on the shore", "AtlanticCanada.sailboat": "a sailboat", "AtlanticCanada.shoal": "a shoal of fish", @@ -98,15 +98,15 @@ "Camping.label": "A camping trip scene. A black bear is reaching up a tree trunk on the left side of the scene. A tree branch goes across the top of the scene and has a rope ladder hanging from it. There is an open tent on the right side of the scene. A lake and campfire are in the middle of the scene. Your character in this scene is a squirrel.", "Camping.ladder": "the rope ladder", "Camping.lake": "the lake", - "Camping.name": "Camping Trip", + "UI.Camping.name": "Camping Trip", "Camping.tentdoor": "the tent door", "Camping.trunk": "the tree trunk", - "Cancel": "Cancel", + "UI.Cancel": "Cancel", "CharacterAriaLive.movementAriaLabel": "{sceneCharacter} is moving", "CharacterDescriptionBuilder.positionAndDirection": "At {columnLabel} {rowLabel} facing {direction}", "CharacterDescriptionBuilder.positionAndDirectionAndItem": "At {columnLabel} {rowLabel} on {backgroundItem} facing {direction}", - "CharacterMessageBuilder.endOfScene": "Your character has reached the end of the scene", - "CharacterMessageBuilder.hitWall": "Your character hit a wall on {columnLabel}{rowLabel}", + "UI.CharacterMessageBuilder.endOfScene": "Your character has reached the end of the scene", + "UI.CharacterMessageBuilder.hitWall": "Your character hit a wall on {columnLabel}{rowLabel}", "CharacterPositionController.editPosition.columnPosition": "Character column position", "CharacterPositionController.editPosition.designMode.columnPosition": "Paintbrush column position", "CharacterPositionController.editPosition.designMode.moveDown": "Move the paintbrush down", @@ -141,11 +141,11 @@ "Command.right45": "turn right 45 degrees", "Command.right90": "turn right 90 degrees", "Command.startLoop": "beginning of loop {loopLabel}", - "CommandPalette.controlsTitle": "Controls", - "CommandPalette.movementsTitle": "Movements", - "ConfirmDeleteAllModal.confirmButton": "Delete", - "ConfirmDeleteAllModal.content": "Are you sure you want to delete all steps of your program?", - "ConfirmDeleteAllModal.title": "Delete Program", + "UI.CommandPalette.controlsTitle": "Controls", + "UI.CommandPalette.movementsTitle": "Movements", + "UI.ConfirmDeleteAllModal.confirmButton": "Delete", + "UI.ConfirmDeleteAllModal.content": "Are you sure you want to delete all steps of your program?", + "UI.ConfirmDeleteAllModal.title": "Delete Program", "CustomBackgroundDesignModeButton.customBackgroundDesignMode": "custom background design mode", "DashConnectionErrorModal.cancelButton": "Cancel connection", "DashConnectionErrorModal.error": "Connection Error", @@ -160,7 +160,7 @@ "DeepOcean.fishGroup": "the group of fish", "DeepOcean.jellyfish": "the Jellyfish", "DeepOcean.label": "An underwater scene. A large shark circles the waters above a treasure chest at the bottom of the sea floor. The chest is filled with jewels and gold coins. Fish and jellyfish swim around coral and seaweed. Your character in this scene is a submarine.", - "DeepOcean.name": "Deep Ocean", + "UI.DeepOcean.name": "Deep Ocean", "DeepOcean.shark": "the shark", "DeepOcean.treasure": "the treasure", "DesignModeCursorDescriptionBuilder.position": "At {columnLabel} {rowLabel}", @@ -246,7 +246,7 @@ "EuropeTrip.L8": "olives on Cyprus; also in this square Türkiye", "EuropeTrip.character": "the airplane", "EuropeTrip.label": "A Europe trip scene containing a map of Europe with tourist attractions. Iceland is located near the top left of the scene. Cyprus is located at the bottom right of the scene. Tourist attractions are located on the country known for the attraction, such as the violin on Austria near the centre of the scene. Your character in this scene is an airplane.", - "EuropeTrip.name": "Europe Trip", + "UI.EuropeTrip.name": "Europe Trip", "GroceryStore.apples": "apples", "GroceryStore.bagOfRice": "bag of rice", "GroceryStore.bananas": "bananas", @@ -270,7 +270,7 @@ "GroceryStore.jars": "jars", "GroceryStore.label": "A grocery store scene. In the top middle there is a refrigerator containing meat and fish. In the top right there are jars, cans, and other pantry items. On the left of the store there are breads and vegetables. In the middle towards the bottom there are fruits. And in the bottom right there is a refrigerator containing dairy and other refrigerated items. Your character in this scene is a shopping cart.", "GroceryStore.milk": "milk", - "GroceryStore.name": "Grocery Store", + "UI.GroceryStore.name": "Grocery Store", "GroceryStore.onions": "onions", "GroceryStore.orangeJuice": "orange juice", "GroceryStore.oranges": "oranges", @@ -291,52 +291,52 @@ "Haunted.fireplace": "the fireplace", "Haunted.label": "A spooky mansion scene. The front hall has a large staircase starting at the bottom right and going to the top left. Haunted paintings, a mirror, and a creepy deer skull hang on the wall. Bats are flying around. A fire burns in the fireplace below the stairwell. A big comfy chair is in front of the fire. The shelves of a large bookshelf on the left of the scene is stacked with books, potions and plants. Your character in this scene is a flashlight.", "Haunted.mirror": "the mirror", - "Haunted.name": "Haunted House", + "UI.Haunted.name": "Haunted House", "Haunted.painting": "a painting", "Haunted.shelf": "the bookshelf", "Haunted.stairs": "the stairs", - "KeyboardInputModal.Description.addCommandToBeginning": "Press {keyboardShortcut} to add the selected command to the beginning of the program.", - "KeyboardInputModal.Description.addCommandToEnd": "Press {keyboardShortcut} to add the selected command to the end of the program.", - "KeyboardInputModal.Description.announceScene": "Press {keyboardShortcut} to announce the character position and orientation.", - "KeyboardInputModal.Description.decreaseProgramSpeed": "Press {keyboardShortcut} to make the program play slower.", - "KeyboardInputModal.Description.deleteCurrentStep": "Press {keyboardShortcut} to delete the currently focused step.", - "KeyboardInputModal.Description.increaseProgramSpeed": "Press {keyboardShortcut} to make the program play faster.", - "KeyboardInputModal.Description.playPauseProgram": "Press {keyboardShortcut} to play or pause the program.", - "KeyboardInputModal.Description.refreshScene": "Press {keyboardShortcut} to refresh the scene.", - "KeyboardInputModal.Description.showHide": "Press {keyboardShortcut} to show the keyboard shortcuts menu.", - "KeyboardInputModal.Description.stopProgram": "Press {keyboardShortcut} to stop the program.", - "KeyboardInputModal.Description.toggleAnnouncements": "Press {keyboardShortcut} to toggle announcements.", - "KeyboardInputModal.KeyIcons.A": "A", - "KeyboardInputModal.KeyIcons.Alt": "Alt", - "KeyboardInputModal.KeyIcons.B": "B", - "KeyboardInputModal.KeyIcons.Control": "Ctrl", - "KeyboardInputModal.KeyIcons.D": "D", - "KeyboardInputModal.KeyIcons.E": "E", - "KeyboardInputModal.KeyIcons.GreaterThan": ">", - "KeyboardInputModal.KeyIcons.I": "I", - "KeyboardInputModal.KeyIcons.LessThan": "<", - "KeyboardInputModal.KeyIcons.P": "P", - "KeyboardInputModal.KeyIcons.QuestionMark": "?", - "KeyboardInputModal.KeyIcons.R": "R", - "KeyboardInputModal.KeyIcons.S": "S", - "KeyboardInputModal.KeyIcons.Shift": "Shift", - "KeyboardInputModal.KeyLabels.A": "a", - "KeyboardInputModal.KeyLabels.Alt": "Alt", - "KeyboardInputModal.KeyLabels.B": "b", - "KeyboardInputModal.KeyLabels.Control": "Control", - "KeyboardInputModal.KeyLabels.D": "d", - "KeyboardInputModal.KeyLabels.E": "e", - "KeyboardInputModal.KeyLabels.GreaterThan": "greater than", - "KeyboardInputModal.KeyLabels.I": "i", - "KeyboardInputModal.KeyLabels.LessThan": "less than", - "KeyboardInputModal.KeyLabels.P": "p", - "KeyboardInputModal.KeyLabels.QuestionMark": "question mark", - "KeyboardInputModal.KeyLabels.R": "r", - "KeyboardInputModal.KeyLabels.S": "s", - "KeyboardInputModal.Scheme.Descriptions.alt": "Alt (Apple: Option)", - "KeyboardInputModal.Scheme.Descriptions.controlalt": "Control+Alt (Apple: Control+Option)", + "UI.KeyboardInputModal.Description.addCommandToBeginning": "Press {keyboardShortcut} to add the selected command to the beginning of the program.", + "UI.KeyboardInputModal.Description.addCommandToEnd": "Press {keyboardShortcut} to add the selected command to the end of the program.", + "UI.KeyboardInputModal.Description.announceScene": "Press {keyboardShortcut} to announce the character position and orientation.", + "UI.KeyboardInputModal.Description.decreaseProgramSpeed": "Press {keyboardShortcut} to make the program play slower.", + "UI.KeyboardInputModal.Description.deleteCurrentStep": "Press {keyboardShortcut} to delete the currently focused step.", + "UI.KeyboardInputModal.Description.increaseProgramSpeed": "Press {keyboardShortcut} to make the program play faster.", + "UI.KeyboardInputModal.Description.playPauseProgram": "Press {keyboardShortcut} to play or pause the program.", + "UI.KeyboardInputModal.Description.refreshScene": "Press {keyboardShortcut} to refresh the scene.", + "UI.KeyboardInputModal.Description.showHide": "Press {keyboardShortcut} to show the keyboard shortcuts menu.", + "UI.KeyboardInputModal.Description.stopProgram": "Press {keyboardShortcut} to stop the program.", + "UI.KeyboardInputModal.Description.toggleAnnouncements": "Press {keyboardShortcut} to toggle announcements.", + "UI.KeyboardInputModal.KeyIcons.A": "A", + "UI.KeyboardInputModal.KeyIcons.Alt": "Alt", + "UI.KeyboardInputModal.KeyIcons.B": "B", + "UI.KeyboardInputModal.KeyIcons.Control": "Ctrl", + "UI.KeyboardInputModal.KeyIcons.D": "D", + "UI.KeyboardInputModal.KeyIcons.E": "E", + "UI.KeyboardInputModal.KeyIcons.GreaterThan": ">", + "UI.KeyboardInputModal.KeyIcons.I": "I", + "UI.KeyboardInputModal.KeyIcons.LessThan": "<", + "UI.KeyboardInputModal.KeyIcons.P": "P", + "UI.KeyboardInputModal.KeyIcons.QuestionMark": "?", + "UI.KeyboardInputModal.KeyIcons.R": "R", + "UI.KeyboardInputModal.KeyIcons.S": "S", + "UI.KeyboardInputModal.KeyIcons.Shift": "Shift", + "UI.KeyboardInputModal.KeyLabels.A": "a", + "UI.KeyboardInputModal.KeyLabels.Alt": "Alt", + "UI.KeyboardInputModal.KeyLabels.B": "b", + "UI.KeyboardInputModal.KeyLabels.Control": "Control", + "UI.KeyboardInputModal.KeyLabels.D": "d", + "UI.KeyboardInputModal.KeyLabels.E": "e", + "UI.KeyboardInputModal.KeyLabels.GreaterThan": "greater than", + "UI.KeyboardInputModal.KeyLabels.I": "i", + "UI.KeyboardInputModal.KeyLabels.LessThan": "less than", + "UI.KeyboardInputModal.KeyLabels.P": "p", + "UI.KeyboardInputModal.KeyLabels.QuestionMark": "question mark", + "UI.KeyboardInputModal.KeyLabels.R": "r", + "UI.KeyboardInputModal.KeyLabels.S": "s", + "UI.KeyboardInputModal.Scheme.Descriptions.alt": "Alt (Apple: Option)", + "UI.KeyboardInputModal.Scheme.Descriptions.controlalt": "Control+Alt (Apple: Control+Option)", "KeyboardInputModal.ShowHide.AriaLabel": "Display keyboard shortcuts menu", - "KeyboardInputModal.Title": "Keyboard Shortcuts", + "UI.KeyboardInputModal.Title": "Keyboard Shortcuts", "KeyboardInputModal.Toggle.AriaLabel": "Keyboard shortcuts toggle", "KeyboardInputModal.Toggle.Label": "Keyboard Shortcuts", "Landmarks.bigBen": "Big Ben Tower", @@ -355,7 +355,7 @@ "Landmarks.label": "A world scene that contains 23 famous landmarks found around the world. A plane is flying from the top left corner. A train is traveling from the bottom right corner. Landmarks are located in different locations in this scene including the famous Sphinx in Egypt, Eiffel Tower in France, Tokyo Tower in Japan, and Floating Market in Vietnam. Your character to explore this scene is a robot", "Landmarks.leaningTowerPisa": "The Leaning Tower of Pisa", "Landmarks.machuPicchu": "Machu Picchu", - "Landmarks.name": "Landmarks", + "UI.Landmarks.name": "Landmarks", "Landmarks.niagaraFalls": "Niagara Falls", "Landmarks.operaHouse": "The Sydney Opera House", "Landmarks.plane": "a plane", @@ -370,58 +370,57 @@ "Marble.bricks": "bricks", "Marble.character": "the marble", "Marble.label": "A maze made of bricks in different colours. Your character in this scene is a marble. There is a path through the maze that starts where your marble is and there are multiple ways to escape the maze.", - "Marble.name": "Marble Run", + "UI.Marble.name": "Marble Run", "MusicBand.character": "the music note", "MusicBand.drumKit": "the drum kit", "MusicBand.guitar": "the guitar", "MusicBand.label": "A music band scene with musical instruments. The instruments are arranged in 2 rows, with one row in the middle of the scene and one towards the bottom of the scene. In the upper row, there is a guitar, a drum kit, and a saxophone. In the lower row, there is a tambourine, a xylophone with a mallet, a microphone on a stand, and a synthesizer. Across the top of the scene spotlights light the instruments. And in the lower left and right corners there are loudspeakers. Your character in this scene is a music note.", "MusicBand.loudspeaker": "a loudspeaker", "MusicBand.microphone": "the microphone on a stand", - "MusicBand.name": "Music Band", + "UI.MusicBand.name": "Music Band", "MusicBand.saxophone": "the saxophone", "MusicBand.spotlight": "a spotlight", "MusicBand.synthesizer": "the synthesizer", "MusicBand.tambourine": "the tambourine", "MusicBand.xylophone": "the xylophone with mallet", - "Off": "Off", - "On": "On", + "UI.Off": "Off", + "UI.On": "On", "PenDownToggleSwitch.penDown": "Pen down", "PlayButton.pause": "Pause", "PlayButton.play": "Play", "PlayControls.heading": "Play Controls", - "PrivacyModal.close": "Close", - "PrivacyModal.contactUs": "contact us", - "PrivacyModal.section010.Heading": "Updated January 4th, 2024", - "PrivacyModal.section010.block010": "At Weavly, we believe that privacy is a fundamental human right, and acknowledge how important it is to our community—especially with regards to both children and parents.", - "PrivacyModal.section010.block020": "This page explains:", - "PrivacyModal.section010.block030.item010": "What type of information we store on our website (http://create.weavly.org/)", - "PrivacyModal.section010.block030.item020": "How that information is used and processed", - "PrivacyModal.section010.block030.item030": "How we keep your information safe", - "PrivacyModal.section020.Heading": "What information does Weavly store?", - "PrivacyModal.section020.block010": "As you use Weavly, we may store information on how Weavly is accessed and used by you. We store the following information independently on every browser/device pair that you use Weavly on:", - "PrivacyModal.section020.block020.item010": "Your prefered settings for display colour theme and keyboard shortcuts", - "PrivacyModal.section020.block020.item020": "Your visible set of action blocks on the action panel", - "PrivacyModal.section020.block020.item030": "Your selected background for the scene", - "PrivacyModal.section020.block020.item040": "Your created program", - "PrivacyModal.section020.block020.item050": "Any line that is drawn on the scene as a result of running your program", - "PrivacyModal.section020.block020.item060": "The last position of your character on the scene", - "PrivacyModal.section020.block020.item070": "The starting position of your character", - "PrivacyModal.section020.block020.item080": "The version of Weavly that was used", - "PrivacyModal.section020.block030": "You can delete any information that Weavly has generated from your usage by clearing your browser's cache and local storage. Check your browser's documentation for details.", - "PrivacyModal.section030.Heading": "How does Weavly use this information?", - "PrivacyModal.section030.block010": "The generated information is kept in a local storage on your device to make your use of Weavly more convenient:", - "PrivacyModal.section030.block020.item010": "Your settings for the coding environment are stored so you don't have to adjust them every time you launch Weavly", - "PrivacyModal.section030.block020.item020": "If you happen to accidentally or intentionally close your browser, the coding environment will be the same as when you left it for the next time you launch Weavly", - "PrivacyModal.section030.block030": "Although storing your information in the browser makes it convenient for every time you access Weavly, it may cause problems on shared computers. As a result, someone that uses the computer after you may be able to access your Weavly settings and program.", - "PrivacyModal.section040.Heading": "How do we keep your information safe?", - "PrivacyModal.section040.block010": "The security of your data is important to us, but please keep in mind that no method of electronic storage is 100% secure. We currently use browser local storage to store the specified data. The information is stored in the browser by domain (create.weavly.org) and only code running from that domain may access it. Thus, other websites cannot access the data. However, local storage is not encrypted on disk and someone with access to the device could get access to the data.", - "PrivacyModal.section050.Heading": "Children's Privacy", - "PrivacyModal.section050.block010": "We do not knowingly collect personally identifiable information from anyone under the age of 18. If you are a parent or guardian and you have become aware that we have collected Personal Data from your children without verification of parental consent, we can take steps to remove that information from our servers. Please {contactLink}", - "PrivacyModal.section060.Heading": "Changes to This Privacy Policy", - "PrivacyModal.section060.block010": "We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page. We will let you know of any changes becoming effective by updating the “effective date” at the top of this Privacy Policy. You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.", - "PrivacyModal.section070.Heading": "Contact Us", - "PrivacyModal.section070.block010": "If you have any questions about this Privacy Policy, please {contactLink}.", - "PrivacyModal.title": "Weavly Privacy Policy", + "UI.PrivacyModal.contactUs": "contact us", + "UI.PrivacyModal.section010.Heading": "Updated January 4th, 2024", + "UI.PrivacyModal.section010.block010": "At Weavly, we believe that privacy is a fundamental human right, and acknowledge how important it is to our community—especially with regards to both children and parents.", + "UI.PrivacyModal.section010.block020": "This page explains:", + "UI.PrivacyModal.section010.block030.item010": "What type of information we store on our website (http://create.weavly.org/)", + "UI.PrivacyModal.section010.block030.item020": "How that information is used and processed", + "UI.PrivacyModal.section010.block030.item030": "How we keep your information safe", + "UI.PrivacyModal.section020.Heading": "What information does Weavly store?", + "UI.PrivacyModal.section020.block010": "As you use Weavly, we may store information on how Weavly is accessed and used by you. We store the following information independently on every browser/device pair that you use Weavly on:", + "UI.PrivacyModal.section020.block020.item010": "Your prefered settings for display colour theme and keyboard shortcuts", + "UI.PrivacyModal.section020.block020.item020": "Your visible set of action blocks on the action panel", + "UI.PrivacyModal.section020.block020.item030": "Your selected background for the scene", + "UI.PrivacyModal.section020.block020.item040": "Your created program", + "UI.PrivacyModal.section020.block020.item050": "Any line that is drawn on the scene as a result of running your program", + "UI.PrivacyModal.section020.block020.item060": "The last position of your character on the scene", + "UI.PrivacyModal.section020.block020.item070": "The starting position of your character", + "UI.PrivacyModal.section020.block020.item080": "The version of Weavly that was used", + "UI.PrivacyModal.section020.block030": "You can delete any information that Weavly has generated from your usage by clearing your browser's cache and local storage. Check your browser's documentation for details.", + "UI.PrivacyModal.section030.Heading": "How does Weavly use this information?", + "UI.PrivacyModal.section030.block010": "The generated information is kept in a local storage on your device to make your use of Weavly more convenient:", + "UI.PrivacyModal.section030.block020.item010": "Your settings for the coding environment are stored so you don't have to adjust them every time you launch Weavly", + "UI.PrivacyModal.section030.block020.item020": "If you happen to accidentally or intentionally close your browser, the coding environment will be the same as when you left it for the next time you launch Weavly", + "UI.PrivacyModal.section030.block030": "Although storing your information in the browser makes it convenient for every time you access Weavly, it may cause problems on shared computers. As a result, someone that uses the computer after you may be able to access your Weavly settings and program.", + "UI.PrivacyModal.section040.Heading": "How do we keep your information safe?", + "UI.PrivacyModal.section040.block010": "The security of your data is important to us, but please keep in mind that no method of electronic storage is 100% secure. We currently use browser local storage to store the specified data. The information is stored in the browser by domain (create.weavly.org) and only code running from that domain may access it. Thus, other websites cannot access the data. However, local storage is not encrypted on disk and someone with access to the device could get access to the data.", + "UI.PrivacyModal.section050.Heading": "Children's Privacy", + "UI.PrivacyModal.section050.block010": "We do not knowingly collect personally identifiable information from anyone under the age of 18. If you are a parent or guardian and you have become aware that we have collected Personal Data from your children without verification of parental consent, we can take steps to remove that information from our servers. Please {contactLink}", + "UI.PrivacyModal.section060.Heading": "Changes to This Privacy Policy", + "UI.PrivacyModal.section060.block010": "We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page. We will let you know of any changes becoming effective by updating the “effective date” at the top of this Privacy Policy. You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.", + "UI.PrivacyModal.section070.Heading": "Contact Us", + "UI.PrivacyModal.section070.block010": "If you have any questions about this Privacy Policy, please {contactLink}.", + "UI.PrivacyModal.title": "Weavly Privacy Policy", "ProgramBlockEditor.beginningBlock": "Add selected action {actionName} to the beginning of the program", "ProgramBlockEditor.betweenBlocks": "Add selected action {actionName} between position {previousStepNumber}, {previousStepActionName} and position {nextStepNumber}, {nextStepActionName}", "ProgramBlockEditor.blocks.noCommandSelected": "Make sure an action is selected", @@ -429,7 +428,7 @@ "ProgramBlockEditor.lastBlock": "Add selected action {actionName} to the end of the program", "ProgramBlockEditor.nestedCommand": "{blockName}, position {index} of Loop {parentLoopLabel}", "ProgramBlockEditor.program.deleteAll": "Delete all steps of your program", - "ProgramBlockEditor.programHeading": "Program", + "UI.ProgramBlockEditor.programHeading": "Program", "ProgramBlockEditor.toggleAddNodeExpandMode": "add node expanded mode", "ProgramSequence.heading": "Program Sequence", "ProgramSpeedController.slider": "Program play speed", @@ -444,26 +443,25 @@ "Savannah.hippo": "the Hippo", "Savannah.label": "A savannah scene. A lion roars at the top of a cliff above the horizon. A mother and baby giraffe roam the savannah. Two crocodiles, a flamingo and a hippopotamus drink water from a pond surrounded by trees. Your character in this scene is a Jeep.", "Savannah.lion": "the Lion", - "Savannah.name": "Savannah", + "UI.Savannah.name": "Savannah", "Savannah.pond": "the Pond", "Savannah.tree": "a Tree", - "Save": "Save", + "UI.Save": "Save", "Scene.description": "Scene, in {backgroundName}, {numColumns} by {numRows} grid. {characterDescription}", "Scene.heading": "Scene", "SceneMessage.close": "close message", - "ShareButton": "Share", - "ShareModal.close": "Close", - "ShareModal.copy": "Copy link", - "ShareModal.description1": "A link to the program you created was copied to the clipboard.", - "ShareModal.description2": "You can also copy the link below to share it with anyone you like.", - "ShareModal.title": "Share Link", + "UI.ShareButton": "Share", + "UI.ShareModal.copy": "Copy link", + "UI.ShareModal.description1": "A link to the program you created was copied to the clipboard.", + "UI.ShareModal.description2": "You can also copy the link below to share it with anyone you like.", + "UI.ShareModal.title": "Share Link", "Sketchpad.character": "the robot", "Sketchpad.label": "A blank sketchbook with grid lines. Your character in this scene is a Robot.", - "Sketchpad.name": "Sketchpad", - "SoundOptionsModal.allSounds": "All Sounds", - "SoundOptionsModal.announcements": "Audio Announcements", - "SoundOptionsModal.musicalSounds": "Musical Sounds", - "SoundOptionsModal.title": "Sound Options", + "UI.Sketchpad.name": "Sketchpad", + "UI.SoundOptionsModal.allSounds": "All Sounds", + "UI.SoundOptionsModal.announcements": "Audio Announcements", + "UI.SoundOptionsModal.musicalSounds": "Musical Sounds", + "UI.SoundOptionsModal.title": "Sound Options", "Space.aliens": "the Aliens", "Space.asteroid": "an asteroid", "Space.character": "the spaceship", @@ -472,7 +470,7 @@ "Space.mars": "Mars", "Space.meteor": "a Meteor", "Space.moon": "the Moon", - "Space.name": "Space", + "UI.Space.name": "Space", "Space.satellite": "the satellite", "Space.saturn": "Saturn", "Space.star": "a star", @@ -492,7 +490,7 @@ "Sports.iceSkates": "ice skates", "Sports.label": "A sports scene with 23 different pieces of sporting equipment spread across the scene. Your character is a golf cart", "Sports.martialArtsUniform": "martial arts uniform", - "Sports.name": "Sports", + "UI.Sports.name": "Sports", "Sports.rowingBoat": "rowing boat", "Sports.runningShoes": "running shoes", "Sports.singlet": "singlet", @@ -504,12 +502,12 @@ "Sports.volleyballBall": "volleyball ball", "StopButton": "Stop", "ThemeSelector.iconButton": "Theme Selector", - "ThemeSelector.option.contrast": "High Contrast", - "ThemeSelector.option.dark": "Dark", - "ThemeSelector.option.default": "Default", - "ThemeSelector.option.gray": "Grayscale", - "ThemeSelector.option.light": "Light", - "ThemeSelector.title": "Themes", + "UI.ThemeSelector.option.contrast": "High Contrast", + "UI.ThemeSelector.option.dark": "Dark", + "UI.ThemeSelector.option.default": "Default", + "UI.ThemeSelector.option.gray": "Grayscale", + "UI.ThemeSelector.option.light": "Light", + "UI.ThemeSelector.title": "Themes", "TileDescription.black": "black", "TileDescription.brown": "brown", "TileDescription.darkBlue": "dark blue", @@ -528,8 +526,9 @@ "TileDescription.white": "white", "TileDescription.yellow": "yellow", "TilePanel.heading": "Custom Background Design", - "WorldSelector.Prompt": "Select a background for your scene.", - "WorldSelector.Title": "Scene Background", + "UI.Close": "Close", + "UI.WorldSelector.Prompt": "Select a background for your scene.", + "UI.WorldSelector.Title": "Scene Background", "WorldSelectorButton.heading": "Scene Background selector", "WorldSelectorButton.label": "Scene Background selector" }, @@ -538,17 +537,17 @@ "ActionPanel.action.moveToNextStep": "remplacer l'étape {stepNumber} {stepActionName} {nextStepInfo}", "ActionPanel.action.moveToPreviousStep": "remplacer l'étape {stepNumber} {stepActionName} {previousStepInfo}", "ActionPanel.action.replace": "remplacer l'étape {stepNumber} {stepActionName} {selectedActionName}", - "ActionsMenu.title": "action", + "UI.ActionsMenu.title": "action", "ActionsMenu.toggleActionsMenu": "configurer les actions disponibles", - "ActionsMenuItem.command.backward1": "reculer d'un pas", - "ActionsMenuItem.command.forward1": "avancer d'une pas", - "ActionsMenuItem.command.left45": "tourner à gauche de 45 degrées", - "ActionsMenuItem.command.left90": "tourner à gauche de 90 degréees", - "ActionsMenuItem.command.loop": "boucle", - "ActionsMenuItem.command.right45": "tourner à droite 45 degrées", - "ActionsMenuItem.command.right90": "tourner à droite 90 degrées", - "ActionsMenuItem.usedItemToggleLabel": "(utilisé)", - "ActionsSimplificationModal.title": "actions disponibles", + "UI.ActionsMenuItem.command.backward1": "reculer d'un pas", + "UI.ActionsMenuItem.command.forward1": "avancer d'une pas", + "UI.ActionsMenuItem.command.left45": "tourner à gauche de 45 degrées", + "UI.ActionsMenuItem.command.left90": "tourner à gauche de 90 degréees", + "UI.ActionsMenuItem.command.loop": "boucle", + "UI.ActionsMenuItem.command.right45": "tourner à droite 45 degrées", + "UI.ActionsMenuItem.command.right90": "tourner à droite 90 degrées", + "UI.ActionsMenuItem.usedItemToggleLabel": "(utilisé)", + "UI.ActionsSimplificationModal.title": "actions disponibles", "AmusementPark.character": "le train", "AmusementPark.entrance": "entrée", "AmusementPark.ferrisWheel": "grande roue", @@ -556,7 +555,7 @@ "AmusementPark.goKarts": "karts", "AmusementPark.label": "Une scène de parc d'attractions. Une scène avec vos attractions préférées: des montagnes rousses, un grand roue, un bateau pirate, des karts, une blançoir, et un manège. Il y a d'autres choses amusantes à faire, comme un stand de jeux, et une parc aquatique, et si vous voulez des collations, il y a une stand de collations. Votre personnage dans cette scène est un train.", "AmusementPark.merryGoRound": "manège", - "AmusementPark.name": "parc d'attractions", + "UI.AmusementPark.name": "parc d'attractions", "AmusementPark.pirateShip": "navire pirate", "AmusementPark.rollerCoaster": "montagnes rousses", "AmusementPark.snackStand": "stand de collations", @@ -595,7 +594,7 @@ "App.appHeading": "Weavly", "App.appHeading.link": "Weavly, en savoir plus sur Weavly a Weavly point org", "App.connectToDash": "Se connecter à Dash", - "App.privacyModalToggle": "intimité", + "UI.App.privacyModalToggle": "intimité", "App.privacyModalToggle.ariaLabel": "politique de confidentialité de Weavly", "AtlanticCanada.character": "Insulaire de Cap", "AtlanticCanada.fishProcessingPlant": "usine de transformation des poissons", @@ -605,7 +604,7 @@ "AtlanticCanada.label": "Scène de voyage Atlantique. Voyagez au Canada atlntique à travers l'océan Atlantique. La météo est imprévisable dans l'océan , certaines parties de l'océan peuvent être orageuses et certaines parties de l'océan peuvent être couverte de brouillard. Voyagez en toute sécurité pour visiter une usine de transformation du poisson et une village terrestre; vous pourriez rencontrer des icebergs ou des baleine sur votre chemin. Votre personnage dans cette scène est un bateau de pêche, également connu sous le nom Cape Islander dans le Canada Atlantique.", "AtlanticCanada.land": "la terre", "AtlanticCanada.lighthouse": "la phare", - "AtlanticCanada.name": "atlantique Canada", + "UI.AtlanticCanada.name": "atlantique Canada", "AtlanticCanada.rowingBoatOnTheShore": "un bateau à rames sur le rivage", "AtlanticCanada.sailboat": "un bateau a voile", "AtlanticCanada.shoal": "un banc de poissons", @@ -623,15 +622,15 @@ "Camping.label": "une scène de camping. un ours noir atteint un tronc d'arbre sûre le côté gauche de la scène. une branche 'arbre traverse le haut des la scène et une échelle de corde y est suspendu. il y a une tente ouvert sur le côté droit de la scène. un lac et un feu de camp sont au milieu de la scène. votre personnage dans cette scène est une écureuil.", "Camping.ladder": "une échelle de corde", "Camping.lake": "le lac", - "Camping.name": "voyage de camping", + "UI.Camping.name": "voyage de camping", "Camping.tentdoor": "la porte de la tente", "Camping.trunk": "le tronc d'arbre", - "Cancel": "Annuler", + "UI.Cancel": "Annuler", "CharacterAriaLive.movementAriaLabel": "Le {sceneCharacter} bouge", "CharacterDescriptionBuilder.positionAndDirection": "À {columnLabel} {rowLabel} face à {direction}", "CharacterDescriptionBuilder.positionAndDirectionAndItem": "À {columnLabel} {rowLabel} sur {backgroundItem} orienté vers {direction}", - "CharacterMessageBuilder.endOfScene": "Votre personnage à atteint la fin de la scène", - "CharacterMessageBuilder.hitWall": "ton personnage a heurté un mur {columnLabel} {rowLabel}", + "UI.CharacterMessageBuilder.endOfScene": "Votre personnage à atteint la fin de la scène", + "UI.CharacterMessageBuilder.hitWall": "ton personnage a heurté un mur {columnLabel} {rowLabel}", "CharacterPositionController.editPosition.columnPosition": "position de la colonne des charactères", "CharacterPositionController.editPosition.designMode.columnPosition": "position de la colonne du pinceau", "CharacterPositionController.editPosition.designMode.moveDown": "déplacer le pinceau vers le bas", @@ -676,11 +675,11 @@ "CommandInfo.previousStep.inLoop": "avant l'étape {previousStepNumber} {command} de la boucle {loopLabel}", "CommandInfo.previousStep.loop": "avant l'étape {previousStepNumber} {command}", "CommandInfo.previousStep.startLoop": "hors boucle {loopLabel}", - "CommandPalette.controlsTitle": "contrôles", - "CommandPalette.movementsTitle": "Mouvements", - "ConfirmDeleteAllModal.confirmButton": "supprimer", - "ConfirmDeleteAllModal.content": "êtes-vous sûr de voulair suprimer tous les étapes de ton programme?", - "ConfirmDeleteAllModal.title": "supprimer le programme", + "UI.CommandPalette.controlsTitle": "contrôles", + "UI.CommandPalette.movementsTitle": "Mouvements", + "UI.ConfirmDeleteAllModal.confirmButton": "supprimer", + "UI.ConfirmDeleteAllModal.content": "êtes-vous sûr de voulair suprimer tous les étapes de ton programme?", + "UI.ConfirmDeleteAllModal.title": "supprimer le programme", "CustomBackgroundDesignModeButton.customBackgroundDesignMode": "mode de conception arrière plan personnalisé", "DashConnectionErrorModal.cancelButton": "anuler la connextion", "DashConnectionErrorModal.error": "erreur de connextion", @@ -695,7 +694,7 @@ "DeepOcean.fishGroup": "le groupe de poissons", "DeepOcean.jellyfish": "le méduse", "DeepOcean.label": "une scène sous marine. Un grand requin fait le tours des eaux au-dessous d'un coffre de trésores au fond du fond marin. Le coffre est rempli de bijoux et de pieces d'ors. Poissons et méduses nagent autour des coraux et des algues. Votre personnage dans ce scène est un sous-marin.", - "DeepOcean.name": "Océan profond", + "UI.DeepOcean.name": "Océan profond", "DeepOcean.shark": "le renard", "DeepOcean.treasure": "the trésore", "DesignModeCursorDescriptionBuilder.position": "à {columnLabel} {rowLabel}", @@ -781,7 +780,7 @@ "EuropeTrip.L8": "olives en Chypre; aussi sur cette case Turquie", "EuropeTrip.character": "l'avion", "EuropeTrip.label": "Une scène de voyage en Europe contenant une carte de Europe avec des attractions touristiques. L'Islande est située en haut à gauche de la scène. Chypre est située en bas à droite de la scène. Les attractions touristiques sont située dans le pays connu pour des attractions, comme le Violon en Autriche, près du centre de la scène. Votre personnage dans cette scène est un avion.", - "EuropeTrip.name": "Voyage en Europe", + "UI.EuropeTrip.name": "Voyage en Europe", "GroceryStore.apples": "pommes", "GroceryStore.bagOfRice": "sac de riz", "GroceryStore.bananas": "bananes", @@ -805,7 +804,7 @@ "GroceryStore.jars": "pots", "GroceryStore.label": "Une scène d'epicerie. En haut au milieu se trouve un frigo contenent de la viande et du poisson. En haut à droite se trouve des pots, des canettes et d'autres articles de garde-manger. A gauche du magasin se trouve des pains et des légumes. Au milieu vers le bas se trouve les fruits. Et en bas à droite se trouve un frigo contenant des produits laitier et d'autre produits réfrigérés. Votre personnage dans cette scène est un panier d'épicerie", "GroceryStore.milk": "lait ", - "GroceryStore.name": "Épicerie", + "UI.GroceryStore.name": "Épicerie", "GroceryStore.onions": "onions", "GroceryStore.orangeJuice": "jus d'orange", "GroceryStore.oranges": "oranges", @@ -826,52 +825,52 @@ "Haunted.fireplace": "la cheminée", "Haunted.label": "Une scène de manoire effrayante. Le corridor d'entrée comporte un grand escalier commençant un bas à droite et allant en haut à gauche. Des peintures hantées, un mirroir et une crâne de cerf effrayant sont accrochées au mur. Les chauves sourris volent. Un feu brûle dans la chiminée située sous la cage d'escalier. Une grande chaise confortable est devant le feu. Les étagères d'une grande bibliothèque à gauche de la scène sont remplis de livres, potions et plantes. Votre personnage dans cette scène est une lampe de poche.", "Haunted.mirror": "le mirror", - "Haunted.name": "une maison hauntée", + "UI.Haunted.name": "une maison hauntée", "Haunted.painting": "une peinture", "Haunted.shelf": "la bibliothèque", "Haunted.stairs": "les escaliers", - "KeyboardInputModal.Description.addCommandToBeginning": "appuyer sur la {keyboardShortcut} pour ajouter la commande sélectionnée au début du programme", - "KeyboardInputModal.Description.addCommandToEnd": "appuyer sur la {keyboardShortcut} pour ajouter la commande sélectionnée à la fin du programme", - "KeyboardInputModal.Description.announceScene": "appuyer sur la {keyboardShortcut} pour annoncer la position du charactère et l'orientation", - "KeyboardInputModal.Description.decreaseProgramSpeed": "appuyer sur la {keyboardShortcut} pour ralentir la lecture du programme", - "KeyboardInputModal.Description.deleteCurrentStep": "appuyer sur la {keyboardShortcut} pour surpimer l'étape actuellement ciblée", - "KeyboardInputModal.Description.increaseProgramSpeed": "appuyer sur la {keyboardShortcut} pour accélérer la lecture du programme", - "KeyboardInputModal.Description.playPauseProgram": "appuyer sur la {keyboardShortcut} pour lire ou mettre en pause le programme", - "KeyboardInputModal.Description.refreshScene": "appuyer sur la {keyboardShortcut} pour réfraîchir la scène", - "KeyboardInputModal.Description.showHide": "appuyer sur la {keyboardShortcut} pour voir le menu racourci de l'ordinateur", - "KeyboardInputModal.Description.stopProgram": "appuyer sur la {keyboardShortcut} pour arrêter le programme", - "KeyboardInputModal.Description.toggleAnnouncements": "appuyer sur la {keyboardShortcut} pour basculer les annonces", - "KeyboardInputModal.KeyIcons.A": "A", - "KeyboardInputModal.KeyIcons.Alt": "alt", - "KeyboardInputModal.KeyIcons.B": "B", - "KeyboardInputModal.KeyIcons.Control": "ctrl", - "KeyboardInputModal.KeyIcons.D": "D", - "KeyboardInputModal.KeyIcons.E": "E", - "KeyboardInputModal.KeyIcons.GreaterThan": ">", - "KeyboardInputModal.KeyIcons.I": "I", - "KeyboardInputModal.KeyIcons.LessThan": "<", - "KeyboardInputModal.KeyIcons.P": "P", - "KeyboardInputModal.KeyIcons.QuestionMark": "?", - "KeyboardInputModal.KeyIcons.R": "R", - "KeyboardInputModal.KeyIcons.S": "S", - "KeyboardInputModal.KeyIcons.Shift": "déclage", - "KeyboardInputModal.KeyLabels.A": "a", - "KeyboardInputModal.KeyLabels.Alt": "alt", - "KeyboardInputModal.KeyLabels.B": "b", - "KeyboardInputModal.KeyLabels.Control": "contôle", - "KeyboardInputModal.KeyLabels.D": "d", - "KeyboardInputModal.KeyLabels.E": "e", - "KeyboardInputModal.KeyLabels.GreaterThan": "plus grand que", - "KeyboardInputModal.KeyLabels.I": "i", - "KeyboardInputModal.KeyLabels.LessThan": "plus petit que", - "KeyboardInputModal.KeyLabels.P": "p", - "KeyboardInputModal.KeyLabels.QuestionMark": "point d'interrogation", - "KeyboardInputModal.KeyLabels.R": "r", - "KeyboardInputModal.KeyLabels.S": "s", - "KeyboardInputModal.Scheme.Descriptions.alt": "alt (apple: option)", - "KeyboardInputModal.Scheme.Descriptions.controlalt": "contrôle+alt (apple: contrôle+option)", + "UI.KeyboardInputModal.Description.addCommandToBeginning": "appuyer sur la {keyboardShortcut} pour ajouter la commande sélectionnée au début du programme", + "UI.KeyboardInputModal.Description.addCommandToEnd": "appuyer sur la {keyboardShortcut} pour ajouter la commande sélectionnée à la fin du programme", + "UI.KeyboardInputModal.Description.announceScene": "appuyer sur la {keyboardShortcut} pour annoncer la position du charactère et l'orientation", + "UI.KeyboardInputModal.Description.decreaseProgramSpeed": "appuyer sur la {keyboardShortcut} pour ralentir la lecture du programme", + "UI.KeyboardInputModal.Description.deleteCurrentStep": "appuyer sur la {keyboardShortcut} pour surpimer l'étape actuellement ciblée", + "UI.KeyboardInputModal.Description.increaseProgramSpeed": "appuyer sur la {keyboardShortcut} pour accélérer la lecture du programme", + "UI.KeyboardInputModal.Description.playPauseProgram": "appuyer sur la {keyboardShortcut} pour lire ou mettre en pause le programme", + "UI.KeyboardInputModal.Description.refreshScene": "appuyer sur la {keyboardShortcut} pour réfraîchir la scène", + "UI.KeyboardInputModal.Description.showHide": "appuyer sur la {keyboardShortcut} pour voir le menu racourci de l'ordinateur", + "UI.KeyboardInputModal.Description.stopProgram": "appuyer sur la {keyboardShortcut} pour arrêter le programme", + "UI.KeyboardInputModal.Description.toggleAnnouncements": "appuyer sur la {keyboardShortcut} pour basculer les annonces", + "UI.KeyboardInputModal.KeyIcons.A": "A", + "UI.KeyboardInputModal.KeyIcons.Alt": "alt", + "UI.KeyboardInputModal.KeyIcons.B": "B", + "UI.KeyboardInputModal.KeyIcons.Control": "ctrl", + "UI.KeyboardInputModal.KeyIcons.D": "D", + "UI.KeyboardInputModal.KeyIcons.E": "E", + "UI.KeyboardInputModal.KeyIcons.GreaterThan": ">", + "UI.KeyboardInputModal.KeyIcons.I": "I", + "UI.KeyboardInputModal.KeyIcons.LessThan": "<", + "UI.KeyboardInputModal.KeyIcons.P": "P", + "UI.KeyboardInputModal.KeyIcons.QuestionMark": "?", + "UI.KeyboardInputModal.KeyIcons.R": "R", + "UI.KeyboardInputModal.KeyIcons.S": "S", + "UI.KeyboardInputModal.KeyIcons.Shift": "déclage", + "UI.KeyboardInputModal.KeyLabels.A": "a", + "UI.KeyboardInputModal.KeyLabels.Alt": "alt", + "UI.KeyboardInputModal.KeyLabels.B": "b", + "UI.KeyboardInputModal.KeyLabels.Control": "contôle", + "UI.KeyboardInputModal.KeyLabels.D": "d", + "UI.KeyboardInputModal.KeyLabels.E": "e", + "UI.KeyboardInputModal.KeyLabels.GreaterThan": "plus grand que", + "UI.KeyboardInputModal.KeyLabels.I": "i", + "UI.KeyboardInputModal.KeyLabels.LessThan": "plus petit que", + "UI.KeyboardInputModal.KeyLabels.P": "p", + "UI.KeyboardInputModal.KeyLabels.QuestionMark": "point d'interrogation", + "UI.KeyboardInputModal.KeyLabels.R": "r", + "UI.KeyboardInputModal.KeyLabels.S": "s", + "UI.KeyboardInputModal.Scheme.Descriptions.alt": "alt (apple: option)", + "UI.KeyboardInputModal.Scheme.Descriptions.controlalt": "contrôle+alt (apple: contrôle+option)", "KeyboardInputModal.ShowHide.AriaLabel": "afficher le menu des raccourcis claviers", - "KeyboardInputModal.Title": "raccourcis clavier", + "UI.KeyboardInputModal.Title": "raccourcis clavier", "KeyboardInputModal.Toggle.AriaLabel": "basculer les raccourcis claviers", "KeyboardInputModal.Toggle.Label": "keyboard shortcuts", "Landmarks.bigBen": "Tour Big Ben", @@ -890,7 +889,7 @@ "Landmarks.label": "Une grande scène mondiale qui contient 23 monuments célèbres trouver dans le monde. Un avion vole depuis le point supérieur gauche. Un train part du point supérieur droite. Les points de repère sont situés à différents endroits de cet scène, notament le fameux Sphinx en Egypte, la Tour Eiffel en France, la tour de Tokyo au Japon et le marché flottant au Vietnam. Votre caractère pour explorer cette scène est un robot.", "Landmarks.leaningTowerPisa": "La tour penché de Pize", "Landmarks.machuPicchu": "Matchu Picchu", - "Landmarks.name": "Repères", + "UI.Landmarks.name": "Repères", "Landmarks.niagaraFalls": "chutes du Niagara", "Landmarks.operaHouse": "L'Opéra de Sydney", "Landmarks.plane": "un avion", @@ -905,27 +904,26 @@ "Marble.bricks": "briques", "Marble.character": "une bille", "Marble.label": "Une labyrinthe fait de briques de différentes couleurs. Votre personnage dans cette scène est une bille. Il y a un chemin à travers le labyrinthe qui commence là où se trouve votre bille et il existe plusieurs façons d'échapper du labyrinthe.", - "Marble.name": "course de billes", + "UI.Marble.name": "course de billes", "MusicBand.character": "la note de musique", "MusicBand.drumKit": "la batterie", "MusicBand.guitar": "la guitare", "MusicBand.label": "Une scène de groupe de bande avec des instruments de musique. Les instruments sont déposés sur 2 rangées, une rangée au milieu de la scène et une vers le bas de la scène. Dans la rangée supérieur, il ya une guitar, une batterie et un saxophone. Sur la rangée inférieur, il y a un tambourin, un xylophone avec un maillet, une microphone sur un pied et une synthétiseur. Au sommet de la scène. des projecteurs éclairent les instruments et dans les coins inférieurs à droit se trouve les haut-parleurs. Votre personnage dans cette scène est un note de musique.", "MusicBand.loudspeaker": "un haut-parleur", "MusicBand.microphone": "un mircrophone sur un pied", - "MusicBand.name": "Groupe de musique", + "UI.MusicBand.name": "Groupe de musique", "MusicBand.saxophone": "le saxophone", "MusicBand.spotlight": "un projeteur", "MusicBand.synthesizer": "une synthésiseur", "MusicBand.tambourine": "une tambourine", "MusicBand.xylophone": "un xylophone avec un maillet", - "Off": "étient", - "On": "Sur", + "UI.Off": "étient", + "UI.On": "Sur", "PenDownToggleSwitch.penDown": "Stylo vers le bas", "PlayButton.pause": "pause", "PlayButton.play": "jouer", "PlayControls.heading": "jouer aux commandes", - "PrivacyModal.close": "fermer", - "PrivacyModal.title": "Weavly politique de confidentialité", + "UI.PrivacyModal.title": "Weavly politique de confidentialité", "ProgramBlockEditor.beginningBlock": "ajouté l'action selectionnée {actionName} au début du programme", "ProgramBlockEditor.betweenBlocks": "ajouté l'action selectionée {actionName} entre la position {previousStepNumber}, {previousStepActionName} et la position {nextStepNumber}, {nextStepActionName}", "ProgramBlockEditor.blocks.noCommandSelected": "assurez vous qu'une action est sélectionée", @@ -933,7 +931,7 @@ "ProgramBlockEditor.lastBlock": "ajouté l'action sélectionée {actionName} à la fin du programme", "ProgramBlockEditor.nestedCommand": "{blockName}, possition, {index} du boucle, {parentLoopLabel}", "ProgramBlockEditor.program.deleteAll": "suprrimer tout les étapes de votre programme", - "ProgramBlockEditor.programHeading": "programme", + "UI.ProgramBlockEditor.programHeading": "programme", "ProgramBlockEditor.toggleAddNodeExpandMode": "ajouter un note en mode développer", "ProgramSequence.heading": "vitesse de lecture du programme", "ProgramSpeedController.slider": "vitesse de lecture du programme", @@ -948,26 +946,25 @@ "Savannah.hippo": "l'hippopotame", "Savannah.label": "Une scène de Savane. Un lion rugit au sommet d'une falaise au-dessous de l'horizon. Une mère et son bébé giraffe parcourent la savane. Deux, crocodiles, un flamant rose et un hippopotame boivent de l'eau d'un étang entourné d'arbres. Votre personnage dans cette scène est un Jeep", "Savannah.lion": "le lion", - "Savannah.name": "Savane", + "UI.Savannah.name": "Savane", "Savannah.pond": "l'étang", "Savannah.tree": "l'arbre", - "Save": "Sauvegarder", + "UI.Save": "Sauvegarder", "Scene.description": "Scène, dans {backgroundName}, grille {numColumns} par {numRows}. {characterDescription}", "Scene.heading": "scène", "SceneMessage.close": "fermée le message", - "ShareButton": "partager", - "ShareModal.close": "fermé", - "ShareModal.copy": "copier le lien", - "ShareModal.description1": "un lien vers le programme que vous avez créer à été copié dans le presse-papier", - "ShareModal.description2": "vous pouvez également copier le lien ci-dessous et le partager avec qui vous voulez", - "ShareModal.title": "lien de partage", + "UI.ShareButton": "partager", + "UI.ShareModal.copy": "copier le lien", + "UI.ShareModal.description1": "un lien vers le programme que vous avez créer à été copié dans le presse-papier", + "UI.ShareModal.description2": "vous pouvez également copier le lien ci-dessous et le partager avec qui vous voulez", + "UI.ShareModal.title": "lien de partage", "Sketchpad.character": "le robot", "Sketchpad.label": "un croquis vierge avec une ligne de quadrillage. Votre charactère dans se scène est un robot", - "Sketchpad.name": "un croquis", - "SoundOptionsModal.allSounds": "tout les sons", - "SoundOptionsModal.announcements": "annonces audio", - "SoundOptionsModal.musicalSounds": "sons musicaux", - "SoundOptionsModal.title": "options sonores", + "UI.Sketchpad.name": "un croquis", + "UI.SoundOptionsModal.allSounds": "tout les sons", + "UI.SoundOptionsModal.announcements": "annonces audio", + "UI.SoundOptionsModal.musicalSounds": "sons musicaux", + "UI.SoundOptionsModal.title": "options sonores", "Space.aliens": "les aliens", "Space.asteroid": "une astéroïde", "Space.character": "le vaisseaux spaciale", @@ -976,7 +973,7 @@ "Space.mars": "Mars", "Space.meteor": "Une météore", "Space.moon": "La Lune", - "Space.name": "Espace", + "UI.Space.name": "Espace", "Space.satellite": "le satélitte", "Space.saturn": "Saturne", "Space.star": "Une étoile", @@ -996,7 +993,7 @@ "Sports.iceSkates": "patins de glace", "Sports.label": "Une scène de sports avec 23 différentes pièces d'équipement sportif propagé sur la scène. Votre personnage est un voiture de golf.", "Sports.martialArtsUniform": "uniforme arts martiaux", - "Sports.name": "sports", + "UI.Sports.name": "sports", "Sports.rowingBoat": "canot à rames", "Sports.runningShoes": "chaussures de cours", "Sports.singlet": "maillot", @@ -1008,12 +1005,12 @@ "Sports.volleyballBall": "ballon de volleyball", "StopButton": "arrête", "ThemeSelector.iconButton": "sélecteur du thème", - "ThemeSelector.option.contrast": "contraste élèvé", - "ThemeSelector.option.dark": "sombre", - "ThemeSelector.option.default": "défaut", - "ThemeSelector.option.gray": "niveaux de gris", - "ThemeSelector.option.light": "clair", - "ThemeSelector.title": "thèmes", + "UI.ThemeSelector.option.contrast": "contraste élèvé", + "UI.ThemeSelector.option.dark": "sombre", + "UI.ThemeSelector.option.default": "défaut", + "UI.ThemeSelector.option.gray": "niveaux de gris", + "UI.ThemeSelector.option.light": "clair", + "UI.ThemeSelector.title": "thèmes", "TileDescription.black": "noire", "TileDescription.brown": "brun", "TileDescription.darkBlue": "bleu foncer", @@ -1032,8 +1029,9 @@ "TileDescription.white": "blanc", "TileDescription.yellow": "jaune", "TilePanel.heading": "Conception de fond personnalisée", - "WorldSelector.Prompt": "selectionner une arrière plan pour votre scène", - "WorldSelector.Title": "fond de scène", + "UI.Close": "fermer", + "UI.WorldSelector.Prompt": "selectionner une arrière plan pour votre scène", + "UI.WorldSelector.Title": "fond de scène", "WorldSelectorButton.heading": "Sélecteur de fond de scène", "WorldSelectorButton.label": "Sélecteur de fond de scène" } From d346ff0027c57ef7ec33ab6677d56daaba62aba0 Mon Sep 17 00:00:00 2001 From: Simon Bates Date: Mon, 28 Oct 2024 13:59:01 -0400 Subject: [PATCH 21/23] Sort messages --- src/messages.json | 438 +++++++++++++++++++++++----------------------- 1 file changed, 219 insertions(+), 219 deletions(-) diff --git a/src/messages.json b/src/messages.json index 0097dd91..3e31a97f 100644 --- a/src/messages.json +++ b/src/messages.json @@ -13,17 +13,7 @@ "ActionPanel.action.moveToPreviousStep.withinLoop": "Move Step {stepNumber} {stepActionName} before step {previousStepNumber} {previousStepActionName} of loop {loopLabel}", "ActionPanel.action.replace.noSelectedAction": "Replace Step {stepNumber} {stepActionName}", "ActionPanel.action.replace.withSelectedAction": "Replace Step {stepNumber} {stepActionName} with selected action {selectedActionName}", - "UI.ActionsMenu.title": "Actions", "ActionsMenu.toggleActionsMenu": "configure available actions", - "UI.ActionsMenuItem.command.backward1": "Move backward 1 step", - "UI.ActionsMenuItem.command.forward1": "Move forward 1 step", - "UI.ActionsMenuItem.command.left45": "Turn left 45 degrees", - "UI.ActionsMenuItem.command.left90": "Turn left 90 degrees", - "UI.ActionsMenuItem.command.loop": "Loop", - "UI.ActionsMenuItem.command.right45": "Turn right 45 degrees", - "UI.ActionsMenuItem.command.right90": "Turn right 90 degrees", - "UI.ActionsMenuItem.usedItemToggleLabel": "(Used)", - "UI.ActionsSimplificationModal.title": "Available Actions", "AmusementPark.character": "the train", "AmusementPark.entrance": "entrance", "AmusementPark.ferrisWheel": "ferris wheel", @@ -31,7 +21,6 @@ "AmusementPark.goKarts": "go karts", "AmusementPark.label": "An amusement park scene. A scene with your favourite rides; there's a roller coaster, ferris wheel, pirate ship, go karts, swing ride and merry go round! There's other fun things to do, like a game booth and water park, and if you want some snacks, there is a snack stand as well. Your character is a train.", "AmusementPark.merryGoRound": "merry go round", - "UI.AmusementPark.name": "Amusement Park", "AmusementPark.pirateShip": "pirate ship", "AmusementPark.rollerCoaster": "roller coaster", "AmusementPark.snackStand": "snack stand", @@ -70,7 +59,6 @@ "App.appHeading": "Weavly", "App.appHeading.link": "Weavly, learn more about Weavly at Weavly dot org", "App.connectToDash": "Connect to Dash", - "UI.App.privacyModalToggle": "Privacy", "App.privacyModalToggle.ariaLabel": "Weavly privacy policy", "AtlanticCanada.character": "Cape islander", "AtlanticCanada.fishProcessingPlant": "a fish processing plant", @@ -80,7 +68,6 @@ "AtlanticCanada.label": "Atlantic Canada scene. Travel Atlantic Canada through the Atlantic ocean. Weather is unpredictable in the Atlantic ocean, some parts of the ocean can be stormy, and some parts of the ocean can be covered with fog. Travel safe to visit a fish processing plant, and a village on the land; you might face icebergs or whales on the way. Your character in this scene is a fishing boat, also known as a Cape Islander in Atlantic Canada.", "AtlanticCanada.land": "the land", "AtlanticCanada.lighthouse": "a light house", - "UI.AtlanticCanada.name": "Atlantic Canada", "AtlanticCanada.rowingBoatOnTheShore": "a rowing boat on the shore", "AtlanticCanada.sailboat": "a sailboat", "AtlanticCanada.shoal": "a shoal of fish", @@ -98,15 +85,11 @@ "Camping.label": "A camping trip scene. A black bear is reaching up a tree trunk on the left side of the scene. A tree branch goes across the top of the scene and has a rope ladder hanging from it. There is an open tent on the right side of the scene. A lake and campfire are in the middle of the scene. Your character in this scene is a squirrel.", "Camping.ladder": "the rope ladder", "Camping.lake": "the lake", - "UI.Camping.name": "Camping Trip", "Camping.tentdoor": "the tent door", "Camping.trunk": "the tree trunk", - "UI.Cancel": "Cancel", "CharacterAriaLive.movementAriaLabel": "{sceneCharacter} is moving", "CharacterDescriptionBuilder.positionAndDirection": "At {columnLabel} {rowLabel} facing {direction}", "CharacterDescriptionBuilder.positionAndDirectionAndItem": "At {columnLabel} {rowLabel} on {backgroundItem} facing {direction}", - "UI.CharacterMessageBuilder.endOfScene": "Your character has reached the end of the scene", - "UI.CharacterMessageBuilder.hitWall": "Your character hit a wall on {columnLabel}{rowLabel}", "CharacterPositionController.editPosition.columnPosition": "Character column position", "CharacterPositionController.editPosition.designMode.columnPosition": "Paintbrush column position", "CharacterPositionController.editPosition.designMode.moveDown": "Move the paintbrush down", @@ -141,11 +124,6 @@ "Command.right45": "turn right 45 degrees", "Command.right90": "turn right 90 degrees", "Command.startLoop": "beginning of loop {loopLabel}", - "UI.CommandPalette.controlsTitle": "Controls", - "UI.CommandPalette.movementsTitle": "Movements", - "UI.ConfirmDeleteAllModal.confirmButton": "Delete", - "UI.ConfirmDeleteAllModal.content": "Are you sure you want to delete all steps of your program?", - "UI.ConfirmDeleteAllModal.title": "Delete Program", "CustomBackgroundDesignModeButton.customBackgroundDesignMode": "custom background design mode", "DashConnectionErrorModal.cancelButton": "Cancel connection", "DashConnectionErrorModal.error": "Connection Error", @@ -160,7 +138,6 @@ "DeepOcean.fishGroup": "the group of fish", "DeepOcean.jellyfish": "the Jellyfish", "DeepOcean.label": "An underwater scene. A large shark circles the waters above a treasure chest at the bottom of the sea floor. The chest is filled with jewels and gold coins. Fish and jellyfish swim around coral and seaweed. Your character in this scene is a submarine.", - "UI.DeepOcean.name": "Deep Ocean", "DeepOcean.shark": "the shark", "DeepOcean.treasure": "the treasure", "DesignModeCursorDescriptionBuilder.position": "At {columnLabel} {rowLabel}", @@ -246,7 +223,6 @@ "EuropeTrip.L8": "olives on Cyprus; also in this square Türkiye", "EuropeTrip.character": "the airplane", "EuropeTrip.label": "A Europe trip scene containing a map of Europe with tourist attractions. Iceland is located near the top left of the scene. Cyprus is located at the bottom right of the scene. Tourist attractions are located on the country known for the attraction, such as the violin on Austria near the centre of the scene. Your character in this scene is an airplane.", - "UI.EuropeTrip.name": "Europe Trip", "GroceryStore.apples": "apples", "GroceryStore.bagOfRice": "bag of rice", "GroceryStore.bananas": "bananas", @@ -270,7 +246,6 @@ "GroceryStore.jars": "jars", "GroceryStore.label": "A grocery store scene. In the top middle there is a refrigerator containing meat and fish. In the top right there are jars, cans, and other pantry items. On the left of the store there are breads and vegetables. In the middle towards the bottom there are fruits. And in the bottom right there is a refrigerator containing dairy and other refrigerated items. Your character in this scene is a shopping cart.", "GroceryStore.milk": "milk", - "UI.GroceryStore.name": "Grocery Store", "GroceryStore.onions": "onions", "GroceryStore.orangeJuice": "orange juice", "GroceryStore.oranges": "oranges", @@ -291,52 +266,10 @@ "Haunted.fireplace": "the fireplace", "Haunted.label": "A spooky mansion scene. The front hall has a large staircase starting at the bottom right and going to the top left. Haunted paintings, a mirror, and a creepy deer skull hang on the wall. Bats are flying around. A fire burns in the fireplace below the stairwell. A big comfy chair is in front of the fire. The shelves of a large bookshelf on the left of the scene is stacked with books, potions and plants. Your character in this scene is a flashlight.", "Haunted.mirror": "the mirror", - "UI.Haunted.name": "Haunted House", "Haunted.painting": "a painting", "Haunted.shelf": "the bookshelf", "Haunted.stairs": "the stairs", - "UI.KeyboardInputModal.Description.addCommandToBeginning": "Press {keyboardShortcut} to add the selected command to the beginning of the program.", - "UI.KeyboardInputModal.Description.addCommandToEnd": "Press {keyboardShortcut} to add the selected command to the end of the program.", - "UI.KeyboardInputModal.Description.announceScene": "Press {keyboardShortcut} to announce the character position and orientation.", - "UI.KeyboardInputModal.Description.decreaseProgramSpeed": "Press {keyboardShortcut} to make the program play slower.", - "UI.KeyboardInputModal.Description.deleteCurrentStep": "Press {keyboardShortcut} to delete the currently focused step.", - "UI.KeyboardInputModal.Description.increaseProgramSpeed": "Press {keyboardShortcut} to make the program play faster.", - "UI.KeyboardInputModal.Description.playPauseProgram": "Press {keyboardShortcut} to play or pause the program.", - "UI.KeyboardInputModal.Description.refreshScene": "Press {keyboardShortcut} to refresh the scene.", - "UI.KeyboardInputModal.Description.showHide": "Press {keyboardShortcut} to show the keyboard shortcuts menu.", - "UI.KeyboardInputModal.Description.stopProgram": "Press {keyboardShortcut} to stop the program.", - "UI.KeyboardInputModal.Description.toggleAnnouncements": "Press {keyboardShortcut} to toggle announcements.", - "UI.KeyboardInputModal.KeyIcons.A": "A", - "UI.KeyboardInputModal.KeyIcons.Alt": "Alt", - "UI.KeyboardInputModal.KeyIcons.B": "B", - "UI.KeyboardInputModal.KeyIcons.Control": "Ctrl", - "UI.KeyboardInputModal.KeyIcons.D": "D", - "UI.KeyboardInputModal.KeyIcons.E": "E", - "UI.KeyboardInputModal.KeyIcons.GreaterThan": ">", - "UI.KeyboardInputModal.KeyIcons.I": "I", - "UI.KeyboardInputModal.KeyIcons.LessThan": "<", - "UI.KeyboardInputModal.KeyIcons.P": "P", - "UI.KeyboardInputModal.KeyIcons.QuestionMark": "?", - "UI.KeyboardInputModal.KeyIcons.R": "R", - "UI.KeyboardInputModal.KeyIcons.S": "S", - "UI.KeyboardInputModal.KeyIcons.Shift": "Shift", - "UI.KeyboardInputModal.KeyLabels.A": "a", - "UI.KeyboardInputModal.KeyLabels.Alt": "Alt", - "UI.KeyboardInputModal.KeyLabels.B": "b", - "UI.KeyboardInputModal.KeyLabels.Control": "Control", - "UI.KeyboardInputModal.KeyLabels.D": "d", - "UI.KeyboardInputModal.KeyLabels.E": "e", - "UI.KeyboardInputModal.KeyLabels.GreaterThan": "greater than", - "UI.KeyboardInputModal.KeyLabels.I": "i", - "UI.KeyboardInputModal.KeyLabels.LessThan": "less than", - "UI.KeyboardInputModal.KeyLabels.P": "p", - "UI.KeyboardInputModal.KeyLabels.QuestionMark": "question mark", - "UI.KeyboardInputModal.KeyLabels.R": "r", - "UI.KeyboardInputModal.KeyLabels.S": "s", - "UI.KeyboardInputModal.Scheme.Descriptions.alt": "Alt (Apple: Option)", - "UI.KeyboardInputModal.Scheme.Descriptions.controlalt": "Control+Alt (Apple: Control+Option)", "KeyboardInputModal.ShowHide.AriaLabel": "Display keyboard shortcuts menu", - "UI.KeyboardInputModal.Title": "Keyboard Shortcuts", "KeyboardInputModal.Toggle.AriaLabel": "Keyboard shortcuts toggle", "KeyboardInputModal.Toggle.Label": "Keyboard Shortcuts", "Landmarks.bigBen": "Big Ben Tower", @@ -355,7 +288,6 @@ "Landmarks.label": "A world scene that contains 23 famous landmarks found around the world. A plane is flying from the top left corner. A train is traveling from the bottom right corner. Landmarks are located in different locations in this scene including the famous Sphinx in Egypt, Eiffel Tower in France, Tokyo Tower in Japan, and Floating Market in Vietnam. Your character to explore this scene is a robot", "Landmarks.leaningTowerPisa": "The Leaning Tower of Pisa", "Landmarks.machuPicchu": "Machu Picchu", - "UI.Landmarks.name": "Landmarks", "Landmarks.niagaraFalls": "Niagara Falls", "Landmarks.operaHouse": "The Sydney Opera House", "Landmarks.plane": "a plane", @@ -370,57 +302,21 @@ "Marble.bricks": "bricks", "Marble.character": "the marble", "Marble.label": "A maze made of bricks in different colours. Your character in this scene is a marble. There is a path through the maze that starts where your marble is and there are multiple ways to escape the maze.", - "UI.Marble.name": "Marble Run", "MusicBand.character": "the music note", "MusicBand.drumKit": "the drum kit", "MusicBand.guitar": "the guitar", "MusicBand.label": "A music band scene with musical instruments. The instruments are arranged in 2 rows, with one row in the middle of the scene and one towards the bottom of the scene. In the upper row, there is a guitar, a drum kit, and a saxophone. In the lower row, there is a tambourine, a xylophone with a mallet, a microphone on a stand, and a synthesizer. Across the top of the scene spotlights light the instruments. And in the lower left and right corners there are loudspeakers. Your character in this scene is a music note.", "MusicBand.loudspeaker": "a loudspeaker", "MusicBand.microphone": "the microphone on a stand", - "UI.MusicBand.name": "Music Band", "MusicBand.saxophone": "the saxophone", "MusicBand.spotlight": "a spotlight", "MusicBand.synthesizer": "the synthesizer", "MusicBand.tambourine": "the tambourine", "MusicBand.xylophone": "the xylophone with mallet", - "UI.Off": "Off", - "UI.On": "On", "PenDownToggleSwitch.penDown": "Pen down", "PlayButton.pause": "Pause", "PlayButton.play": "Play", "PlayControls.heading": "Play Controls", - "UI.PrivacyModal.contactUs": "contact us", - "UI.PrivacyModal.section010.Heading": "Updated January 4th, 2024", - "UI.PrivacyModal.section010.block010": "At Weavly, we believe that privacy is a fundamental human right, and acknowledge how important it is to our community—especially with regards to both children and parents.", - "UI.PrivacyModal.section010.block020": "This page explains:", - "UI.PrivacyModal.section010.block030.item010": "What type of information we store on our website (http://create.weavly.org/)", - "UI.PrivacyModal.section010.block030.item020": "How that information is used and processed", - "UI.PrivacyModal.section010.block030.item030": "How we keep your information safe", - "UI.PrivacyModal.section020.Heading": "What information does Weavly store?", - "UI.PrivacyModal.section020.block010": "As you use Weavly, we may store information on how Weavly is accessed and used by you. We store the following information independently on every browser/device pair that you use Weavly on:", - "UI.PrivacyModal.section020.block020.item010": "Your prefered settings for display colour theme and keyboard shortcuts", - "UI.PrivacyModal.section020.block020.item020": "Your visible set of action blocks on the action panel", - "UI.PrivacyModal.section020.block020.item030": "Your selected background for the scene", - "UI.PrivacyModal.section020.block020.item040": "Your created program", - "UI.PrivacyModal.section020.block020.item050": "Any line that is drawn on the scene as a result of running your program", - "UI.PrivacyModal.section020.block020.item060": "The last position of your character on the scene", - "UI.PrivacyModal.section020.block020.item070": "The starting position of your character", - "UI.PrivacyModal.section020.block020.item080": "The version of Weavly that was used", - "UI.PrivacyModal.section020.block030": "You can delete any information that Weavly has generated from your usage by clearing your browser's cache and local storage. Check your browser's documentation for details.", - "UI.PrivacyModal.section030.Heading": "How does Weavly use this information?", - "UI.PrivacyModal.section030.block010": "The generated information is kept in a local storage on your device to make your use of Weavly more convenient:", - "UI.PrivacyModal.section030.block020.item010": "Your settings for the coding environment are stored so you don't have to adjust them every time you launch Weavly", - "UI.PrivacyModal.section030.block020.item020": "If you happen to accidentally or intentionally close your browser, the coding environment will be the same as when you left it for the next time you launch Weavly", - "UI.PrivacyModal.section030.block030": "Although storing your information in the browser makes it convenient for every time you access Weavly, it may cause problems on shared computers. As a result, someone that uses the computer after you may be able to access your Weavly settings and program.", - "UI.PrivacyModal.section040.Heading": "How do we keep your information safe?", - "UI.PrivacyModal.section040.block010": "The security of your data is important to us, but please keep in mind that no method of electronic storage is 100% secure. We currently use browser local storage to store the specified data. The information is stored in the browser by domain (create.weavly.org) and only code running from that domain may access it. Thus, other websites cannot access the data. However, local storage is not encrypted on disk and someone with access to the device could get access to the data.", - "UI.PrivacyModal.section050.Heading": "Children's Privacy", - "UI.PrivacyModal.section050.block010": "We do not knowingly collect personally identifiable information from anyone under the age of 18. If you are a parent or guardian and you have become aware that we have collected Personal Data from your children without verification of parental consent, we can take steps to remove that information from our servers. Please {contactLink}", - "UI.PrivacyModal.section060.Heading": "Changes to This Privacy Policy", - "UI.PrivacyModal.section060.block010": "We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page. We will let you know of any changes becoming effective by updating the “effective date” at the top of this Privacy Policy. You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.", - "UI.PrivacyModal.section070.Heading": "Contact Us", - "UI.PrivacyModal.section070.block010": "If you have any questions about this Privacy Policy, please {contactLink}.", - "UI.PrivacyModal.title": "Weavly Privacy Policy", "ProgramBlockEditor.beginningBlock": "Add selected action {actionName} to the beginning of the program", "ProgramBlockEditor.betweenBlocks": "Add selected action {actionName} between position {previousStepNumber}, {previousStepActionName} and position {nextStepNumber}, {nextStepActionName}", "ProgramBlockEditor.blocks.noCommandSelected": "Make sure an action is selected", @@ -428,7 +324,6 @@ "ProgramBlockEditor.lastBlock": "Add selected action {actionName} to the end of the program", "ProgramBlockEditor.nestedCommand": "{blockName}, position {index} of Loop {parentLoopLabel}", "ProgramBlockEditor.program.deleteAll": "Delete all steps of your program", - "UI.ProgramBlockEditor.programHeading": "Program", "ProgramBlockEditor.toggleAddNodeExpandMode": "add node expanded mode", "ProgramSequence.heading": "Program Sequence", "ProgramSpeedController.slider": "Program play speed", @@ -443,25 +338,13 @@ "Savannah.hippo": "the Hippo", "Savannah.label": "A savannah scene. A lion roars at the top of a cliff above the horizon. A mother and baby giraffe roam the savannah. Two crocodiles, a flamingo and a hippopotamus drink water from a pond surrounded by trees. Your character in this scene is a Jeep.", "Savannah.lion": "the Lion", - "UI.Savannah.name": "Savannah", "Savannah.pond": "the Pond", "Savannah.tree": "a Tree", - "UI.Save": "Save", "Scene.description": "Scene, in {backgroundName}, {numColumns} by {numRows} grid. {characterDescription}", "Scene.heading": "Scene", "SceneMessage.close": "close message", - "UI.ShareButton": "Share", - "UI.ShareModal.copy": "Copy link", - "UI.ShareModal.description1": "A link to the program you created was copied to the clipboard.", - "UI.ShareModal.description2": "You can also copy the link below to share it with anyone you like.", - "UI.ShareModal.title": "Share Link", "Sketchpad.character": "the robot", "Sketchpad.label": "A blank sketchbook with grid lines. Your character in this scene is a Robot.", - "UI.Sketchpad.name": "Sketchpad", - "UI.SoundOptionsModal.allSounds": "All Sounds", - "UI.SoundOptionsModal.announcements": "Audio Announcements", - "UI.SoundOptionsModal.musicalSounds": "Musical Sounds", - "UI.SoundOptionsModal.title": "Sound Options", "Space.aliens": "the Aliens", "Space.asteroid": "an asteroid", "Space.character": "the spaceship", @@ -470,7 +353,6 @@ "Space.mars": "Mars", "Space.meteor": "a Meteor", "Space.moon": "the Moon", - "UI.Space.name": "Space", "Space.satellite": "the satellite", "Space.saturn": "Saturn", "Space.star": "a star", @@ -490,7 +372,6 @@ "Sports.iceSkates": "ice skates", "Sports.label": "A sports scene with 23 different pieces of sporting equipment spread across the scene. Your character is a golf cart", "Sports.martialArtsUniform": "martial arts uniform", - "UI.Sports.name": "Sports", "Sports.rowingBoat": "rowing boat", "Sports.runningShoes": "running shoes", "Sports.singlet": "singlet", @@ -502,12 +383,6 @@ "Sports.volleyballBall": "volleyball ball", "StopButton": "Stop", "ThemeSelector.iconButton": "Theme Selector", - "UI.ThemeSelector.option.contrast": "High Contrast", - "UI.ThemeSelector.option.dark": "Dark", - "UI.ThemeSelector.option.default": "Default", - "UI.ThemeSelector.option.gray": "Grayscale", - "UI.ThemeSelector.option.light": "Light", - "UI.ThemeSelector.title": "Themes", "TileDescription.black": "black", "TileDescription.brown": "brown", "TileDescription.darkBlue": "dark blue", @@ -526,7 +401,132 @@ "TileDescription.white": "white", "TileDescription.yellow": "yellow", "TilePanel.heading": "Custom Background Design", + "UI.ActionsMenu.title": "Actions", + "UI.ActionsMenuItem.command.backward1": "Move backward 1 step", + "UI.ActionsMenuItem.command.forward1": "Move forward 1 step", + "UI.ActionsMenuItem.command.left45": "Turn left 45 degrees", + "UI.ActionsMenuItem.command.left90": "Turn left 90 degrees", + "UI.ActionsMenuItem.command.loop": "Loop", + "UI.ActionsMenuItem.command.right45": "Turn right 45 degrees", + "UI.ActionsMenuItem.command.right90": "Turn right 90 degrees", + "UI.ActionsMenuItem.usedItemToggleLabel": "(Used)", + "UI.ActionsSimplificationModal.title": "Available Actions", + "UI.AmusementPark.name": "Amusement Park", + "UI.App.privacyModalToggle": "Privacy", + "UI.AtlanticCanada.name": "Atlantic Canada", + "UI.Camping.name": "Camping Trip", + "UI.Cancel": "Cancel", + "UI.CharacterMessageBuilder.endOfScene": "Your character has reached the end of the scene", + "UI.CharacterMessageBuilder.hitWall": "Your character hit a wall on {columnLabel}{rowLabel}", "UI.Close": "Close", + "UI.CommandPalette.controlsTitle": "Controls", + "UI.CommandPalette.movementsTitle": "Movements", + "UI.ConfirmDeleteAllModal.confirmButton": "Delete", + "UI.ConfirmDeleteAllModal.content": "Are you sure you want to delete all steps of your program?", + "UI.ConfirmDeleteAllModal.title": "Delete Program", + "UI.DeepOcean.name": "Deep Ocean", + "UI.EuropeTrip.name": "Europe Trip", + "UI.GroceryStore.name": "Grocery Store", + "UI.Haunted.name": "Haunted House", + "UI.KeyboardInputModal.Description.addCommandToBeginning": "Press {keyboardShortcut} to add the selected command to the beginning of the program.", + "UI.KeyboardInputModal.Description.addCommandToEnd": "Press {keyboardShortcut} to add the selected command to the end of the program.", + "UI.KeyboardInputModal.Description.announceScene": "Press {keyboardShortcut} to announce the character position and orientation.", + "UI.KeyboardInputModal.Description.decreaseProgramSpeed": "Press {keyboardShortcut} to make the program play slower.", + "UI.KeyboardInputModal.Description.deleteCurrentStep": "Press {keyboardShortcut} to delete the currently focused step.", + "UI.KeyboardInputModal.Description.increaseProgramSpeed": "Press {keyboardShortcut} to make the program play faster.", + "UI.KeyboardInputModal.Description.playPauseProgram": "Press {keyboardShortcut} to play or pause the program.", + "UI.KeyboardInputModal.Description.refreshScene": "Press {keyboardShortcut} to refresh the scene.", + "UI.KeyboardInputModal.Description.showHide": "Press {keyboardShortcut} to show the keyboard shortcuts menu.", + "UI.KeyboardInputModal.Description.stopProgram": "Press {keyboardShortcut} to stop the program.", + "UI.KeyboardInputModal.Description.toggleAnnouncements": "Press {keyboardShortcut} to toggle announcements.", + "UI.KeyboardInputModal.KeyIcons.A": "A", + "UI.KeyboardInputModal.KeyIcons.Alt": "Alt", + "UI.KeyboardInputModal.KeyIcons.B": "B", + "UI.KeyboardInputModal.KeyIcons.Control": "Ctrl", + "UI.KeyboardInputModal.KeyIcons.D": "D", + "UI.KeyboardInputModal.KeyIcons.E": "E", + "UI.KeyboardInputModal.KeyIcons.GreaterThan": ">", + "UI.KeyboardInputModal.KeyIcons.I": "I", + "UI.KeyboardInputModal.KeyIcons.LessThan": "<", + "UI.KeyboardInputModal.KeyIcons.P": "P", + "UI.KeyboardInputModal.KeyIcons.QuestionMark": "?", + "UI.KeyboardInputModal.KeyIcons.R": "R", + "UI.KeyboardInputModal.KeyIcons.S": "S", + "UI.KeyboardInputModal.KeyIcons.Shift": "Shift", + "UI.KeyboardInputModal.KeyLabels.A": "a", + "UI.KeyboardInputModal.KeyLabels.Alt": "Alt", + "UI.KeyboardInputModal.KeyLabels.B": "b", + "UI.KeyboardInputModal.KeyLabels.Control": "Control", + "UI.KeyboardInputModal.KeyLabels.D": "d", + "UI.KeyboardInputModal.KeyLabels.E": "e", + "UI.KeyboardInputModal.KeyLabels.GreaterThan": "greater than", + "UI.KeyboardInputModal.KeyLabels.I": "i", + "UI.KeyboardInputModal.KeyLabels.LessThan": "less than", + "UI.KeyboardInputModal.KeyLabels.P": "p", + "UI.KeyboardInputModal.KeyLabels.QuestionMark": "question mark", + "UI.KeyboardInputModal.KeyLabels.R": "r", + "UI.KeyboardInputModal.KeyLabels.S": "s", + "UI.KeyboardInputModal.Scheme.Descriptions.alt": "Alt (Apple: Option)", + "UI.KeyboardInputModal.Scheme.Descriptions.controlalt": "Control+Alt (Apple: Control+Option)", + "UI.KeyboardInputModal.Title": "Keyboard Shortcuts", + "UI.Landmarks.name": "Landmarks", + "UI.Marble.name": "Marble Run", + "UI.MusicBand.name": "Music Band", + "UI.Off": "Off", + "UI.On": "On", + "UI.PrivacyModal.contactUs": "contact us", + "UI.PrivacyModal.section010.Heading": "Updated January 4th, 2024", + "UI.PrivacyModal.section010.block010": "At Weavly, we believe that privacy is a fundamental human right, and acknowledge how important it is to our community—especially with regards to both children and parents.", + "UI.PrivacyModal.section010.block020": "This page explains:", + "UI.PrivacyModal.section010.block030.item010": "What type of information we store on our website (http://create.weavly.org/)", + "UI.PrivacyModal.section010.block030.item020": "How that information is used and processed", + "UI.PrivacyModal.section010.block030.item030": "How we keep your information safe", + "UI.PrivacyModal.section020.Heading": "What information does Weavly store?", + "UI.PrivacyModal.section020.block010": "As you use Weavly, we may store information on how Weavly is accessed and used by you. We store the following information independently on every browser/device pair that you use Weavly on:", + "UI.PrivacyModal.section020.block020.item010": "Your prefered settings for display colour theme and keyboard shortcuts", + "UI.PrivacyModal.section020.block020.item020": "Your visible set of action blocks on the action panel", + "UI.PrivacyModal.section020.block020.item030": "Your selected background for the scene", + "UI.PrivacyModal.section020.block020.item040": "Your created program", + "UI.PrivacyModal.section020.block020.item050": "Any line that is drawn on the scene as a result of running your program", + "UI.PrivacyModal.section020.block020.item060": "The last position of your character on the scene", + "UI.PrivacyModal.section020.block020.item070": "The starting position of your character", + "UI.PrivacyModal.section020.block020.item080": "The version of Weavly that was used", + "UI.PrivacyModal.section020.block030": "You can delete any information that Weavly has generated from your usage by clearing your browser's cache and local storage. Check your browser's documentation for details.", + "UI.PrivacyModal.section030.Heading": "How does Weavly use this information?", + "UI.PrivacyModal.section030.block010": "The generated information is kept in a local storage on your device to make your use of Weavly more convenient:", + "UI.PrivacyModal.section030.block020.item010": "Your settings for the coding environment are stored so you don't have to adjust them every time you launch Weavly", + "UI.PrivacyModal.section030.block020.item020": "If you happen to accidentally or intentionally close your browser, the coding environment will be the same as when you left it for the next time you launch Weavly", + "UI.PrivacyModal.section030.block030": "Although storing your information in the browser makes it convenient for every time you access Weavly, it may cause problems on shared computers. As a result, someone that uses the computer after you may be able to access your Weavly settings and program.", + "UI.PrivacyModal.section040.Heading": "How do we keep your information safe?", + "UI.PrivacyModal.section040.block010": "The security of your data is important to us, but please keep in mind that no method of electronic storage is 100% secure. We currently use browser local storage to store the specified data. The information is stored in the browser by domain (create.weavly.org) and only code running from that domain may access it. Thus, other websites cannot access the data. However, local storage is not encrypted on disk and someone with access to the device could get access to the data.", + "UI.PrivacyModal.section050.Heading": "Children's Privacy", + "UI.PrivacyModal.section050.block010": "We do not knowingly collect personally identifiable information from anyone under the age of 18. If you are a parent or guardian and you have become aware that we have collected Personal Data from your children without verification of parental consent, we can take steps to remove that information from our servers. Please {contactLink}", + "UI.PrivacyModal.section060.Heading": "Changes to This Privacy Policy", + "UI.PrivacyModal.section060.block010": "We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page. We will let you know of any changes becoming effective by updating the “effective date” at the top of this Privacy Policy. You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.", + "UI.PrivacyModal.section070.Heading": "Contact Us", + "UI.PrivacyModal.section070.block010": "If you have any questions about this Privacy Policy, please {contactLink}.", + "UI.PrivacyModal.title": "Weavly Privacy Policy", + "UI.ProgramBlockEditor.programHeading": "Program", + "UI.Savannah.name": "Savannah", + "UI.Save": "Save", + "UI.ShareButton": "Share", + "UI.ShareModal.copy": "Copy link", + "UI.ShareModal.description1": "A link to the program you created was copied to the clipboard.", + "UI.ShareModal.description2": "You can also copy the link below to share it with anyone you like.", + "UI.ShareModal.title": "Share Link", + "UI.Sketchpad.name": "Sketchpad", + "UI.SoundOptionsModal.allSounds": "All Sounds", + "UI.SoundOptionsModal.announcements": "Audio Announcements", + "UI.SoundOptionsModal.musicalSounds": "Musical Sounds", + "UI.SoundOptionsModal.title": "Sound Options", + "UI.Space.name": "Space", + "UI.Sports.name": "Sports", + "UI.ThemeSelector.option.contrast": "High Contrast", + "UI.ThemeSelector.option.dark": "Dark", + "UI.ThemeSelector.option.default": "Default", + "UI.ThemeSelector.option.gray": "Grayscale", + "UI.ThemeSelector.option.light": "Light", + "UI.ThemeSelector.title": "Themes", "UI.WorldSelector.Prompt": "Select a background for your scene.", "UI.WorldSelector.Title": "Scene Background", "WorldSelectorButton.heading": "Scene Background selector", @@ -537,17 +537,7 @@ "ActionPanel.action.moveToNextStep": "remplacer l'étape {stepNumber} {stepActionName} {nextStepInfo}", "ActionPanel.action.moveToPreviousStep": "remplacer l'étape {stepNumber} {stepActionName} {previousStepInfo}", "ActionPanel.action.replace": "remplacer l'étape {stepNumber} {stepActionName} {selectedActionName}", - "UI.ActionsMenu.title": "action", "ActionsMenu.toggleActionsMenu": "configurer les actions disponibles", - "UI.ActionsMenuItem.command.backward1": "reculer d'un pas", - "UI.ActionsMenuItem.command.forward1": "avancer d'une pas", - "UI.ActionsMenuItem.command.left45": "tourner à gauche de 45 degrées", - "UI.ActionsMenuItem.command.left90": "tourner à gauche de 90 degréees", - "UI.ActionsMenuItem.command.loop": "boucle", - "UI.ActionsMenuItem.command.right45": "tourner à droite 45 degrées", - "UI.ActionsMenuItem.command.right90": "tourner à droite 90 degrées", - "UI.ActionsMenuItem.usedItemToggleLabel": "(utilisé)", - "UI.ActionsSimplificationModal.title": "actions disponibles", "AmusementPark.character": "le train", "AmusementPark.entrance": "entrée", "AmusementPark.ferrisWheel": "grande roue", @@ -555,7 +545,6 @@ "AmusementPark.goKarts": "karts", "AmusementPark.label": "Une scène de parc d'attractions. Une scène avec vos attractions préférées: des montagnes rousses, un grand roue, un bateau pirate, des karts, une blançoir, et un manège. Il y a d'autres choses amusantes à faire, comme un stand de jeux, et une parc aquatique, et si vous voulez des collations, il y a une stand de collations. Votre personnage dans cette scène est un train.", "AmusementPark.merryGoRound": "manège", - "UI.AmusementPark.name": "parc d'attractions", "AmusementPark.pirateShip": "navire pirate", "AmusementPark.rollerCoaster": "montagnes rousses", "AmusementPark.snackStand": "stand de collations", @@ -594,7 +583,6 @@ "App.appHeading": "Weavly", "App.appHeading.link": "Weavly, en savoir plus sur Weavly a Weavly point org", "App.connectToDash": "Se connecter à Dash", - "UI.App.privacyModalToggle": "intimité", "App.privacyModalToggle.ariaLabel": "politique de confidentialité de Weavly", "AtlanticCanada.character": "Insulaire de Cap", "AtlanticCanada.fishProcessingPlant": "usine de transformation des poissons", @@ -604,7 +592,6 @@ "AtlanticCanada.label": "Scène de voyage Atlantique. Voyagez au Canada atlntique à travers l'océan Atlantique. La météo est imprévisable dans l'océan , certaines parties de l'océan peuvent être orageuses et certaines parties de l'océan peuvent être couverte de brouillard. Voyagez en toute sécurité pour visiter une usine de transformation du poisson et une village terrestre; vous pourriez rencontrer des icebergs ou des baleine sur votre chemin. Votre personnage dans cette scène est un bateau de pêche, également connu sous le nom Cape Islander dans le Canada Atlantique.", "AtlanticCanada.land": "la terre", "AtlanticCanada.lighthouse": "la phare", - "UI.AtlanticCanada.name": "atlantique Canada", "AtlanticCanada.rowingBoatOnTheShore": "un bateau à rames sur le rivage", "AtlanticCanada.sailboat": "un bateau a voile", "AtlanticCanada.shoal": "un banc de poissons", @@ -622,15 +609,11 @@ "Camping.label": "une scène de camping. un ours noir atteint un tronc d'arbre sûre le côté gauche de la scène. une branche 'arbre traverse le haut des la scène et une échelle de corde y est suspendu. il y a une tente ouvert sur le côté droit de la scène. un lac et un feu de camp sont au milieu de la scène. votre personnage dans cette scène est une écureuil.", "Camping.ladder": "une échelle de corde", "Camping.lake": "le lac", - "UI.Camping.name": "voyage de camping", "Camping.tentdoor": "la porte de la tente", "Camping.trunk": "le tronc d'arbre", - "UI.Cancel": "Annuler", "CharacterAriaLive.movementAriaLabel": "Le {sceneCharacter} bouge", "CharacterDescriptionBuilder.positionAndDirection": "À {columnLabel} {rowLabel} face à {direction}", "CharacterDescriptionBuilder.positionAndDirectionAndItem": "À {columnLabel} {rowLabel} sur {backgroundItem} orienté vers {direction}", - "UI.CharacterMessageBuilder.endOfScene": "Votre personnage à atteint la fin de la scène", - "UI.CharacterMessageBuilder.hitWall": "ton personnage a heurté un mur {columnLabel} {rowLabel}", "CharacterPositionController.editPosition.columnPosition": "position de la colonne des charactères", "CharacterPositionController.editPosition.designMode.columnPosition": "position de la colonne du pinceau", "CharacterPositionController.editPosition.designMode.moveDown": "déplacer le pinceau vers le bas", @@ -675,11 +658,6 @@ "CommandInfo.previousStep.inLoop": "avant l'étape {previousStepNumber} {command} de la boucle {loopLabel}", "CommandInfo.previousStep.loop": "avant l'étape {previousStepNumber} {command}", "CommandInfo.previousStep.startLoop": "hors boucle {loopLabel}", - "UI.CommandPalette.controlsTitle": "contrôles", - "UI.CommandPalette.movementsTitle": "Mouvements", - "UI.ConfirmDeleteAllModal.confirmButton": "supprimer", - "UI.ConfirmDeleteAllModal.content": "êtes-vous sûr de voulair suprimer tous les étapes de ton programme?", - "UI.ConfirmDeleteAllModal.title": "supprimer le programme", "CustomBackgroundDesignModeButton.customBackgroundDesignMode": "mode de conception arrière plan personnalisé", "DashConnectionErrorModal.cancelButton": "anuler la connextion", "DashConnectionErrorModal.error": "erreur de connextion", @@ -694,7 +672,6 @@ "DeepOcean.fishGroup": "le groupe de poissons", "DeepOcean.jellyfish": "le méduse", "DeepOcean.label": "une scène sous marine. Un grand requin fait le tours des eaux au-dessous d'un coffre de trésores au fond du fond marin. Le coffre est rempli de bijoux et de pieces d'ors. Poissons et méduses nagent autour des coraux et des algues. Votre personnage dans ce scène est un sous-marin.", - "UI.DeepOcean.name": "Océan profond", "DeepOcean.shark": "le renard", "DeepOcean.treasure": "the trésore", "DesignModeCursorDescriptionBuilder.position": "à {columnLabel} {rowLabel}", @@ -780,7 +757,6 @@ "EuropeTrip.L8": "olives en Chypre; aussi sur cette case Turquie", "EuropeTrip.character": "l'avion", "EuropeTrip.label": "Une scène de voyage en Europe contenant une carte de Europe avec des attractions touristiques. L'Islande est située en haut à gauche de la scène. Chypre est située en bas à droite de la scène. Les attractions touristiques sont située dans le pays connu pour des attractions, comme le Violon en Autriche, près du centre de la scène. Votre personnage dans cette scène est un avion.", - "UI.EuropeTrip.name": "Voyage en Europe", "GroceryStore.apples": "pommes", "GroceryStore.bagOfRice": "sac de riz", "GroceryStore.bananas": "bananes", @@ -804,7 +780,6 @@ "GroceryStore.jars": "pots", "GroceryStore.label": "Une scène d'epicerie. En haut au milieu se trouve un frigo contenent de la viande et du poisson. En haut à droite se trouve des pots, des canettes et d'autres articles de garde-manger. A gauche du magasin se trouve des pains et des légumes. Au milieu vers le bas se trouve les fruits. Et en bas à droite se trouve un frigo contenant des produits laitier et d'autre produits réfrigérés. Votre personnage dans cette scène est un panier d'épicerie", "GroceryStore.milk": "lait ", - "UI.GroceryStore.name": "Épicerie", "GroceryStore.onions": "onions", "GroceryStore.orangeJuice": "jus d'orange", "GroceryStore.oranges": "oranges", @@ -825,52 +800,10 @@ "Haunted.fireplace": "la cheminée", "Haunted.label": "Une scène de manoire effrayante. Le corridor d'entrée comporte un grand escalier commençant un bas à droite et allant en haut à gauche. Des peintures hantées, un mirroir et une crâne de cerf effrayant sont accrochées au mur. Les chauves sourris volent. Un feu brûle dans la chiminée située sous la cage d'escalier. Une grande chaise confortable est devant le feu. Les étagères d'une grande bibliothèque à gauche de la scène sont remplis de livres, potions et plantes. Votre personnage dans cette scène est une lampe de poche.", "Haunted.mirror": "le mirror", - "UI.Haunted.name": "une maison hauntée", "Haunted.painting": "une peinture", "Haunted.shelf": "la bibliothèque", "Haunted.stairs": "les escaliers", - "UI.KeyboardInputModal.Description.addCommandToBeginning": "appuyer sur la {keyboardShortcut} pour ajouter la commande sélectionnée au début du programme", - "UI.KeyboardInputModal.Description.addCommandToEnd": "appuyer sur la {keyboardShortcut} pour ajouter la commande sélectionnée à la fin du programme", - "UI.KeyboardInputModal.Description.announceScene": "appuyer sur la {keyboardShortcut} pour annoncer la position du charactère et l'orientation", - "UI.KeyboardInputModal.Description.decreaseProgramSpeed": "appuyer sur la {keyboardShortcut} pour ralentir la lecture du programme", - "UI.KeyboardInputModal.Description.deleteCurrentStep": "appuyer sur la {keyboardShortcut} pour surpimer l'étape actuellement ciblée", - "UI.KeyboardInputModal.Description.increaseProgramSpeed": "appuyer sur la {keyboardShortcut} pour accélérer la lecture du programme", - "UI.KeyboardInputModal.Description.playPauseProgram": "appuyer sur la {keyboardShortcut} pour lire ou mettre en pause le programme", - "UI.KeyboardInputModal.Description.refreshScene": "appuyer sur la {keyboardShortcut} pour réfraîchir la scène", - "UI.KeyboardInputModal.Description.showHide": "appuyer sur la {keyboardShortcut} pour voir le menu racourci de l'ordinateur", - "UI.KeyboardInputModal.Description.stopProgram": "appuyer sur la {keyboardShortcut} pour arrêter le programme", - "UI.KeyboardInputModal.Description.toggleAnnouncements": "appuyer sur la {keyboardShortcut} pour basculer les annonces", - "UI.KeyboardInputModal.KeyIcons.A": "A", - "UI.KeyboardInputModal.KeyIcons.Alt": "alt", - "UI.KeyboardInputModal.KeyIcons.B": "B", - "UI.KeyboardInputModal.KeyIcons.Control": "ctrl", - "UI.KeyboardInputModal.KeyIcons.D": "D", - "UI.KeyboardInputModal.KeyIcons.E": "E", - "UI.KeyboardInputModal.KeyIcons.GreaterThan": ">", - "UI.KeyboardInputModal.KeyIcons.I": "I", - "UI.KeyboardInputModal.KeyIcons.LessThan": "<", - "UI.KeyboardInputModal.KeyIcons.P": "P", - "UI.KeyboardInputModal.KeyIcons.QuestionMark": "?", - "UI.KeyboardInputModal.KeyIcons.R": "R", - "UI.KeyboardInputModal.KeyIcons.S": "S", - "UI.KeyboardInputModal.KeyIcons.Shift": "déclage", - "UI.KeyboardInputModal.KeyLabels.A": "a", - "UI.KeyboardInputModal.KeyLabels.Alt": "alt", - "UI.KeyboardInputModal.KeyLabels.B": "b", - "UI.KeyboardInputModal.KeyLabels.Control": "contôle", - "UI.KeyboardInputModal.KeyLabels.D": "d", - "UI.KeyboardInputModal.KeyLabels.E": "e", - "UI.KeyboardInputModal.KeyLabels.GreaterThan": "plus grand que", - "UI.KeyboardInputModal.KeyLabels.I": "i", - "UI.KeyboardInputModal.KeyLabels.LessThan": "plus petit que", - "UI.KeyboardInputModal.KeyLabels.P": "p", - "UI.KeyboardInputModal.KeyLabels.QuestionMark": "point d'interrogation", - "UI.KeyboardInputModal.KeyLabels.R": "r", - "UI.KeyboardInputModal.KeyLabels.S": "s", - "UI.KeyboardInputModal.Scheme.Descriptions.alt": "alt (apple: option)", - "UI.KeyboardInputModal.Scheme.Descriptions.controlalt": "contrôle+alt (apple: contrôle+option)", "KeyboardInputModal.ShowHide.AriaLabel": "afficher le menu des raccourcis claviers", - "UI.KeyboardInputModal.Title": "raccourcis clavier", "KeyboardInputModal.Toggle.AriaLabel": "basculer les raccourcis claviers", "KeyboardInputModal.Toggle.Label": "keyboard shortcuts", "Landmarks.bigBen": "Tour Big Ben", @@ -889,7 +822,6 @@ "Landmarks.label": "Une grande scène mondiale qui contient 23 monuments célèbres trouver dans le monde. Un avion vole depuis le point supérieur gauche. Un train part du point supérieur droite. Les points de repère sont situés à différents endroits de cet scène, notament le fameux Sphinx en Egypte, la Tour Eiffel en France, la tour de Tokyo au Japon et le marché flottant au Vietnam. Votre caractère pour explorer cette scène est un robot.", "Landmarks.leaningTowerPisa": "La tour penché de Pize", "Landmarks.machuPicchu": "Matchu Picchu", - "UI.Landmarks.name": "Repères", "Landmarks.niagaraFalls": "chutes du Niagara", "Landmarks.operaHouse": "L'Opéra de Sydney", "Landmarks.plane": "un avion", @@ -904,26 +836,21 @@ "Marble.bricks": "briques", "Marble.character": "une bille", "Marble.label": "Une labyrinthe fait de briques de différentes couleurs. Votre personnage dans cette scène est une bille. Il y a un chemin à travers le labyrinthe qui commence là où se trouve votre bille et il existe plusieurs façons d'échapper du labyrinthe.", - "UI.Marble.name": "course de billes", "MusicBand.character": "la note de musique", "MusicBand.drumKit": "la batterie", "MusicBand.guitar": "la guitare", "MusicBand.label": "Une scène de groupe de bande avec des instruments de musique. Les instruments sont déposés sur 2 rangées, une rangée au milieu de la scène et une vers le bas de la scène. Dans la rangée supérieur, il ya une guitar, une batterie et un saxophone. Sur la rangée inférieur, il y a un tambourin, un xylophone avec un maillet, une microphone sur un pied et une synthétiseur. Au sommet de la scène. des projecteurs éclairent les instruments et dans les coins inférieurs à droit se trouve les haut-parleurs. Votre personnage dans cette scène est un note de musique.", "MusicBand.loudspeaker": "un haut-parleur", "MusicBand.microphone": "un mircrophone sur un pied", - "UI.MusicBand.name": "Groupe de musique", "MusicBand.saxophone": "le saxophone", "MusicBand.spotlight": "un projeteur", "MusicBand.synthesizer": "une synthésiseur", "MusicBand.tambourine": "une tambourine", "MusicBand.xylophone": "un xylophone avec un maillet", - "UI.Off": "étient", - "UI.On": "Sur", "PenDownToggleSwitch.penDown": "Stylo vers le bas", "PlayButton.pause": "pause", "PlayButton.play": "jouer", "PlayControls.heading": "jouer aux commandes", - "UI.PrivacyModal.title": "Weavly politique de confidentialité", "ProgramBlockEditor.beginningBlock": "ajouté l'action selectionnée {actionName} au début du programme", "ProgramBlockEditor.betweenBlocks": "ajouté l'action selectionée {actionName} entre la position {previousStepNumber}, {previousStepActionName} et la position {nextStepNumber}, {nextStepActionName}", "ProgramBlockEditor.blocks.noCommandSelected": "assurez vous qu'une action est sélectionée", @@ -931,7 +858,6 @@ "ProgramBlockEditor.lastBlock": "ajouté l'action sélectionée {actionName} à la fin du programme", "ProgramBlockEditor.nestedCommand": "{blockName}, possition, {index} du boucle, {parentLoopLabel}", "ProgramBlockEditor.program.deleteAll": "suprrimer tout les étapes de votre programme", - "UI.ProgramBlockEditor.programHeading": "programme", "ProgramBlockEditor.toggleAddNodeExpandMode": "ajouter un note en mode développer", "ProgramSequence.heading": "vitesse de lecture du programme", "ProgramSpeedController.slider": "vitesse de lecture du programme", @@ -946,25 +872,13 @@ "Savannah.hippo": "l'hippopotame", "Savannah.label": "Une scène de Savane. Un lion rugit au sommet d'une falaise au-dessous de l'horizon. Une mère et son bébé giraffe parcourent la savane. Deux, crocodiles, un flamant rose et un hippopotame boivent de l'eau d'un étang entourné d'arbres. Votre personnage dans cette scène est un Jeep", "Savannah.lion": "le lion", - "UI.Savannah.name": "Savane", "Savannah.pond": "l'étang", "Savannah.tree": "l'arbre", - "UI.Save": "Sauvegarder", "Scene.description": "Scène, dans {backgroundName}, grille {numColumns} par {numRows}. {characterDescription}", "Scene.heading": "scène", "SceneMessage.close": "fermée le message", - "UI.ShareButton": "partager", - "UI.ShareModal.copy": "copier le lien", - "UI.ShareModal.description1": "un lien vers le programme que vous avez créer à été copié dans le presse-papier", - "UI.ShareModal.description2": "vous pouvez également copier le lien ci-dessous et le partager avec qui vous voulez", - "UI.ShareModal.title": "lien de partage", "Sketchpad.character": "le robot", "Sketchpad.label": "un croquis vierge avec une ligne de quadrillage. Votre charactère dans se scène est un robot", - "UI.Sketchpad.name": "un croquis", - "UI.SoundOptionsModal.allSounds": "tout les sons", - "UI.SoundOptionsModal.announcements": "annonces audio", - "UI.SoundOptionsModal.musicalSounds": "sons musicaux", - "UI.SoundOptionsModal.title": "options sonores", "Space.aliens": "les aliens", "Space.asteroid": "une astéroïde", "Space.character": "le vaisseaux spaciale", @@ -973,7 +887,6 @@ "Space.mars": "Mars", "Space.meteor": "Une météore", "Space.moon": "La Lune", - "UI.Space.name": "Espace", "Space.satellite": "le satélitte", "Space.saturn": "Saturne", "Space.star": "Une étoile", @@ -993,7 +906,6 @@ "Sports.iceSkates": "patins de glace", "Sports.label": "Une scène de sports avec 23 différentes pièces d'équipement sportif propagé sur la scène. Votre personnage est un voiture de golf.", "Sports.martialArtsUniform": "uniforme arts martiaux", - "UI.Sports.name": "sports", "Sports.rowingBoat": "canot à rames", "Sports.runningShoes": "chaussures de cours", "Sports.singlet": "maillot", @@ -1005,12 +917,6 @@ "Sports.volleyballBall": "ballon de volleyball", "StopButton": "arrête", "ThemeSelector.iconButton": "sélecteur du thème", - "UI.ThemeSelector.option.contrast": "contraste élèvé", - "UI.ThemeSelector.option.dark": "sombre", - "UI.ThemeSelector.option.default": "défaut", - "UI.ThemeSelector.option.gray": "niveaux de gris", - "UI.ThemeSelector.option.light": "clair", - "UI.ThemeSelector.title": "thèmes", "TileDescription.black": "noire", "TileDescription.brown": "brun", "TileDescription.darkBlue": "bleu foncer", @@ -1029,7 +935,101 @@ "TileDescription.white": "blanc", "TileDescription.yellow": "jaune", "TilePanel.heading": "Conception de fond personnalisée", + "UI.ActionsMenu.title": "action", + "UI.ActionsMenuItem.command.backward1": "reculer d'un pas", + "UI.ActionsMenuItem.command.forward1": "avancer d'une pas", + "UI.ActionsMenuItem.command.left45": "tourner à gauche de 45 degrées", + "UI.ActionsMenuItem.command.left90": "tourner à gauche de 90 degréees", + "UI.ActionsMenuItem.command.loop": "boucle", + "UI.ActionsMenuItem.command.right45": "tourner à droite 45 degrées", + "UI.ActionsMenuItem.command.right90": "tourner à droite 90 degrées", + "UI.ActionsMenuItem.usedItemToggleLabel": "(utilisé)", + "UI.ActionsSimplificationModal.title": "actions disponibles", + "UI.AmusementPark.name": "parc d'attractions", + "UI.App.privacyModalToggle": "intimité", + "UI.AtlanticCanada.name": "atlantique Canada", + "UI.Camping.name": "voyage de camping", + "UI.Cancel": "Annuler", + "UI.CharacterMessageBuilder.endOfScene": "Votre personnage à atteint la fin de la scène", + "UI.CharacterMessageBuilder.hitWall": "ton personnage a heurté un mur {columnLabel} {rowLabel}", "UI.Close": "fermer", + "UI.CommandPalette.controlsTitle": "contrôles", + "UI.CommandPalette.movementsTitle": "Mouvements", + "UI.ConfirmDeleteAllModal.confirmButton": "supprimer", + "UI.ConfirmDeleteAllModal.content": "êtes-vous sûr de voulair suprimer tous les étapes de ton programme?", + "UI.ConfirmDeleteAllModal.title": "supprimer le programme", + "UI.DeepOcean.name": "Océan profond", + "UI.EuropeTrip.name": "Voyage en Europe", + "UI.GroceryStore.name": "Épicerie", + "UI.Haunted.name": "une maison hauntée", + "UI.KeyboardInputModal.Description.addCommandToBeginning": "appuyer sur la {keyboardShortcut} pour ajouter la commande sélectionnée au début du programme", + "UI.KeyboardInputModal.Description.addCommandToEnd": "appuyer sur la {keyboardShortcut} pour ajouter la commande sélectionnée à la fin du programme", + "UI.KeyboardInputModal.Description.announceScene": "appuyer sur la {keyboardShortcut} pour annoncer la position du charactère et l'orientation", + "UI.KeyboardInputModal.Description.decreaseProgramSpeed": "appuyer sur la {keyboardShortcut} pour ralentir la lecture du programme", + "UI.KeyboardInputModal.Description.deleteCurrentStep": "appuyer sur la {keyboardShortcut} pour surpimer l'étape actuellement ciblée", + "UI.KeyboardInputModal.Description.increaseProgramSpeed": "appuyer sur la {keyboardShortcut} pour accélérer la lecture du programme", + "UI.KeyboardInputModal.Description.playPauseProgram": "appuyer sur la {keyboardShortcut} pour lire ou mettre en pause le programme", + "UI.KeyboardInputModal.Description.refreshScene": "appuyer sur la {keyboardShortcut} pour réfraîchir la scène", + "UI.KeyboardInputModal.Description.showHide": "appuyer sur la {keyboardShortcut} pour voir le menu racourci de l'ordinateur", + "UI.KeyboardInputModal.Description.stopProgram": "appuyer sur la {keyboardShortcut} pour arrêter le programme", + "UI.KeyboardInputModal.Description.toggleAnnouncements": "appuyer sur la {keyboardShortcut} pour basculer les annonces", + "UI.KeyboardInputModal.KeyIcons.A": "A", + "UI.KeyboardInputModal.KeyIcons.Alt": "alt", + "UI.KeyboardInputModal.KeyIcons.B": "B", + "UI.KeyboardInputModal.KeyIcons.Control": "ctrl", + "UI.KeyboardInputModal.KeyIcons.D": "D", + "UI.KeyboardInputModal.KeyIcons.E": "E", + "UI.KeyboardInputModal.KeyIcons.GreaterThan": ">", + "UI.KeyboardInputModal.KeyIcons.I": "I", + "UI.KeyboardInputModal.KeyIcons.LessThan": "<", + "UI.KeyboardInputModal.KeyIcons.P": "P", + "UI.KeyboardInputModal.KeyIcons.QuestionMark": "?", + "UI.KeyboardInputModal.KeyIcons.R": "R", + "UI.KeyboardInputModal.KeyIcons.S": "S", + "UI.KeyboardInputModal.KeyIcons.Shift": "déclage", + "UI.KeyboardInputModal.KeyLabels.A": "a", + "UI.KeyboardInputModal.KeyLabels.Alt": "alt", + "UI.KeyboardInputModal.KeyLabels.B": "b", + "UI.KeyboardInputModal.KeyLabels.Control": "contôle", + "UI.KeyboardInputModal.KeyLabels.D": "d", + "UI.KeyboardInputModal.KeyLabels.E": "e", + "UI.KeyboardInputModal.KeyLabels.GreaterThan": "plus grand que", + "UI.KeyboardInputModal.KeyLabels.I": "i", + "UI.KeyboardInputModal.KeyLabels.LessThan": "plus petit que", + "UI.KeyboardInputModal.KeyLabels.P": "p", + "UI.KeyboardInputModal.KeyLabels.QuestionMark": "point d'interrogation", + "UI.KeyboardInputModal.KeyLabels.R": "r", + "UI.KeyboardInputModal.KeyLabels.S": "s", + "UI.KeyboardInputModal.Scheme.Descriptions.alt": "alt (apple: option)", + "UI.KeyboardInputModal.Scheme.Descriptions.controlalt": "contrôle+alt (apple: contrôle+option)", + "UI.KeyboardInputModal.Title": "raccourcis clavier", + "UI.Landmarks.name": "Repères", + "UI.Marble.name": "course de billes", + "UI.MusicBand.name": "Groupe de musique", + "UI.Off": "étient", + "UI.On": "Sur", + "UI.PrivacyModal.title": "Weavly politique de confidentialité", + "UI.ProgramBlockEditor.programHeading": "programme", + "UI.Savannah.name": "Savane", + "UI.Save": "Sauvegarder", + "UI.ShareButton": "partager", + "UI.ShareModal.copy": "copier le lien", + "UI.ShareModal.description1": "un lien vers le programme que vous avez créer à été copié dans le presse-papier", + "UI.ShareModal.description2": "vous pouvez également copier le lien ci-dessous et le partager avec qui vous voulez", + "UI.ShareModal.title": "lien de partage", + "UI.Sketchpad.name": "un croquis", + "UI.SoundOptionsModal.allSounds": "tout les sons", + "UI.SoundOptionsModal.announcements": "annonces audio", + "UI.SoundOptionsModal.musicalSounds": "sons musicaux", + "UI.SoundOptionsModal.title": "options sonores", + "UI.Space.name": "Espace", + "UI.Sports.name": "sports", + "UI.ThemeSelector.option.contrast": "contraste élèvé", + "UI.ThemeSelector.option.dark": "sombre", + "UI.ThemeSelector.option.default": "défaut", + "UI.ThemeSelector.option.gray": "niveaux de gris", + "UI.ThemeSelector.option.light": "clair", + "UI.ThemeSelector.title": "thèmes", "UI.WorldSelector.Prompt": "selectionner une arrière plan pour votre scène", "UI.WorldSelector.Title": "fond de scène", "WorldSelectorButton.heading": "Sélecteur de fond de scène", From 16cf4a5a798b6810b251b400a573e1872e0dc1c3 Mon Sep 17 00:00:00 2001 From: Simon Bates Date: Mon, 24 Mar 2025 14:44:05 -0400 Subject: [PATCH 22/23] Update messages and French translations --- src/CharacterDescriptionBuilder.js | 6 +- src/messages.json | 602 +++++++++++++++-------------- 2 files changed, 319 insertions(+), 289 deletions(-) diff --git a/src/CharacterDescriptionBuilder.js b/src/CharacterDescriptionBuilder.js index 06c8db56..8e3a4ad3 100644 --- a/src/CharacterDescriptionBuilder.js +++ b/src/CharacterDescriptionBuilder.js @@ -28,7 +28,7 @@ export default class CharacterDescriptionBuilder { this.intl ); - const directionLabel = this.intl.formatMessage({id: `Direction.${characterState.direction}`}); + const facingDirectionLabel = this.intl.formatMessage({id: `FacingDirection.${characterState.direction}`}); if (itemLabel) { return this.intl.formatMessage( @@ -39,7 +39,7 @@ export default class CharacterDescriptionBuilder { columnLabel: columnLabel, rowLabel: rowLabel, backgroundItem: itemLabel, - direction: directionLabel + facingDirection: facingDirectionLabel } ); } else { @@ -50,7 +50,7 @@ export default class CharacterDescriptionBuilder { { columnLabel: columnLabel, rowLabel: rowLabel, - direction: directionLabel + facingDirection: facingDirectionLabel } ); } diff --git a/src/messages.json b/src/messages.json index af3630b5..cf25c36b 100644 --- a/src/messages.json +++ b/src/messages.json @@ -33,9 +33,9 @@ "Announcement.backward1": "backward 1 square", "Announcement.backward2": "backward 2 squares", "Announcement.backward3": "backward 3 squares", - "Announcement.cannotMoveNext": "At the end of the program, unable to move right", - "Announcement.cannotMovePrevious": "At the beginning of the program, unable to move left", - "Announcement.cannotReplaceLoopBlocks": "replace is not available for loops", + "Announcement.cannotMoveNext": "At the end of the program, unable to move forward", + "Announcement.cannotMovePrevious": "At the beginning of the program, unable to move backward", + "Announcement.cannotReplaceLoopBlocks": "cannot replace \"beginning of loop\" or \"end of loop\" blocks", "Announcement.control": "control", "Announcement.delete": "deleted {actionType} {actionName}", "Announcement.deleteAll": "delete program?", @@ -87,8 +87,8 @@ "Camping.tentdoor": "the tent door", "Camping.trunk": "the tree trunk", "CharacterAriaLive.movementAriaLabel": "{sceneCharacter} is moving", - "CharacterDescriptionBuilder.positionAndDirection": "At {columnLabel} {rowLabel} facing {direction}", - "CharacterDescriptionBuilder.positionAndDirectionAndItem": "At {columnLabel} {rowLabel} on {backgroundItem} facing {direction}", + "CharacterDescriptionBuilder.positionAndDirection": "At {columnLabel} {rowLabel} {facingDirection}", + "CharacterDescriptionBuilder.positionAndDirectionAndItem": "At {columnLabel} {rowLabel} on {backgroundItem} {facingDirection}", "CharacterPositionController.editPosition.columnPosition": "Character column position", "CharacterPositionController.editPosition.designMode.columnPosition": "Paintbrush column position", "CharacterPositionController.editPosition.designMode.moveDown": "Move the paintbrush down", @@ -138,14 +138,14 @@ "DeviceConnectControl.connected": "Connected", "DeviceConnectControl.connecting": "Connecting", "DeviceConnectControl.notConnected": "Not connected", - "Direction.0": "up", - "Direction.1": "upper right", - "Direction.2": "right", - "Direction.3": "lower right", - "Direction.4": "down", - "Direction.5": "lower left", - "Direction.6": "left", - "Direction.7": "upper left", + "FacingDirection.0": "facing up", + "FacingDirection.1": "facing upper right", + "FacingDirection.2": "facing right", + "FacingDirection.3": "facing lower right", + "FacingDirection.4": "facing down", + "FacingDirection.5": "facing lower left", + "FacingDirection.6": "facing left", + "FacingDirection.7": "facing upper left", "EuropeTrip.B6": "the Tower of Saint Vincent on Portugal", "EuropeTrip.B7": "Portugal", "EuropeTrip.C1": "Iceland", @@ -278,7 +278,7 @@ "Landmarks.greatPyramid": "The Great Pyramid of Giza", "Landmarks.greatSphinx": "The Great Sphinx of Giza", "Landmarks.greatWall": "The Great Wall of China", - "Landmarks.label": "A world scene that contains 23 famous landmarks found around the world. A plane is flying from the top left corner. A train is traveling from the bottom right corner. Landmarks are located in different locations in this scene including the famous Sphinx in Egypt, Eiffel Tower in France, Tokyo Tower in Japan, and Floating Market in Vietnam. Your character to explore this scene is a robot", + "Landmarks.label": "A world scene that contains 23 famous landmarks found around the world. A plane is flying from the top left corner. A train is traveling from the bottom right corner. Landmarks are located in different locations in this scene including the famous Sphinx in Egypt, Eiffel Tower in France, Tokyo Tower in Japan, and Floating Market in Vietnam. Your character to explore this scene is a robot.", "Landmarks.leaningTowerPisa": "The Leaning Tower of Pisa", "Landmarks.machuPicchu": "Machu Picchu", "Landmarks.niagaraFalls": "Niagara Falls", @@ -317,7 +317,7 @@ "ProgramBlockEditor.lastBlock": "Add selected action {actionName} to the end of the program", "ProgramBlockEditor.nestedCommand": "{blockName}, position {index} of Loop {parentLoopLabel}", "ProgramBlockEditor.program.deleteAll": "Delete all steps of your program", - "ProgramBlockEditor.toggleAddNodeExpandMode": "add node expanded mode", + "ProgramBlockEditor.toggleAddNodeExpandMode": "show \"add\" buttons", "ProgramSequence.heading": "Program Sequence", "ProgramSpeedController.slider": "Program play speed", "RefreshButton": "Refresh", @@ -363,7 +363,7 @@ "Sports.golfBall": "golf ball", "Sports.hockeyStickAndPuck": "hockey stick and puck", "Sports.iceSkates": "ice skates", - "Sports.label": "A sports scene with 23 different pieces of sporting equipment spread across the scene. Your character is a golf cart", + "Sports.label": "A sports scene with 23 different pieces of sporting equipment spread across the scene. Your character is a golf cart.", "Sports.martialArtsUniform": "martial arts uniform", "Sports.rowingBoat": "rowing boat", "Sports.runningShoes": "running shoes", @@ -526,223 +526,222 @@ "WorldSelectorButton.label": "Scene Background selector" }, "fr": { - "ActionPanel.action.delete": "supprimer {stepNumber} {stepActionName}", - "ActionPanel.action.moveToNextStep": "remplacer l'étape {stepNumber} {stepActionName} {nextStepInfo}", - "ActionPanel.action.moveToPreviousStep": "remplacer l'étape {stepNumber} {stepActionName} {previousStepInfo}", - "ActionPanel.action.replace": "remplacer l'étape {stepNumber} {stepActionName} {selectedActionName}", + "ActionPanel.action.delete": "supprimer l'étape {stepNumber} {stepActionName}", + "ActionPanel.action.moveToNextStep": "déplacer l'étape {stepNumber} {stepActionName} après l'étape {nextStepNumber} {nextStepActionName}", + "ActionPanel.action.moveToNextStep.disabled": "déplacer l'étape {stepNumber} {stepActionName}", + "ActionPanel.action.moveToNextStep.intoLoop": "déplacer l'étape {stepNumber} {stepActionName} dans la boucle {loopLabel}", + "ActionPanel.action.moveToNextStep.outOfLoop": "sortir l’étape {stepNumber} {stepActionName} de la boucle {loopLabel}", + "ActionPanel.action.moveToNextStep.withinLoop": "déplacer l'étape {stepNumber} {stepActionName} après l'étape {nextStepNumber} {nextStepActionName} de la boucle {loopLabel}", + "ActionPanel.action.moveToPreviousStep": "déplacer l'étape {stepNumber} {stepActionName} avant l'étape {nextStepNumber} {nextStepActionName}", + "ActionPanel.action.moveToPreviousStep.disabled": "déplacer l'étape {stepNumber} {stepActionName}", + "ActionPanel.action.moveToPreviousStep.intoLoop": "déplacer l'étape {stepNumber} {stepActionName} dans la boucle {loopLabel}", + "ActionPanel.action.moveToPreviousStep.outOfLoop": "sortir l’étape {stepNumber} {stepActionName} de la boucle {loopLabel}", + "ActionPanel.action.moveToPreviousStep.withinLoop": "déplacer l'étape {stepNumber} {stepActionName} avant l'étape {previousStepNumber} {previousStepActionName} de la boucle {loopLabel}", + "ActionPanel.action.replace.noSelectedAction": "remplacer l'étape {stepNumber} {stepActionName}", + "ActionPanel.action.replace.withSelectedAction": "remplacer l'étape {stepNumber} {stepActionName} par l'action sélectionnée {selectedActionName}", "ActionsMenu.toggleActionsMenu": "configurer les actions disponibles", "AmusementPark.character": "le train", "AmusementPark.entrance": "entrée", "AmusementPark.ferrisWheel": "grande roue", - "AmusementPark.gameBooth": "stand de jeu", + "AmusementPark.gameBooth": "kiosque de jeu", "AmusementPark.goKarts": "karts", - "AmusementPark.label": "Une scène de parc d'attractions. Une scène avec vos attractions préférées: des montagnes rousses, un grand roue, un bateau pirate, des karts, une blançoir, et un manège. Il y a d'autres choses amusantes à faire, comme un stand de jeux, et une parc aquatique, et si vous voulez des collations, il y a une stand de collations. Votre personnage dans cette scène est un train.", + "AmusementPark.label": "Une scène de parc d'attractions. Une scène avec vos manèges préférées; il y a des montagnes rousses, une grande roue, un bateau pirate, des karts, une balançoire, et un manège ! Il y a d'autres choses amusantes à faire, comme un kiosque de jeux et un parc aquatique, et si vous voulez des collations, il y a aussi un kiosque de collations.Ton personnage est un train.", "AmusementPark.merryGoRound": "manège", "AmusementPark.pirateShip": "navire pirate", "AmusementPark.rollerCoaster": "montagnes rousses", - "AmusementPark.snackStand": "stand de collations", - "AmusementPark.swingRide": "tour de balançoire", + "AmusementPark.snackStand": "kiosque de collations", + "AmusementPark.swingRide": "balançoire", "AmusementPark.waterPark": "parc aquatique", "AmusementPark.waterSlide": "glissade d'eau", "AmusementPark.whaleFountain": "fontaine des baleines", - "Announcement.actionSelected": "{actionType} {actionName} sélectionnée", - "Announcement.add": "{actionType} ajouté {actionName}", - "Announcement.backward1": "reculer d'1 case", - "Announcement.backward2": "reculer 2 cases", - "Announcement.backward3": "reculer 3 cases", - "Announcement.cannotMoveNext": "à la fin du programme, incapable de se déplacer vers la droite", - "Announcement.cannotMovePrevious": "au début du programme, incapable de se déplacer vers la gauche", - "Announcement.cannotReplaceLoopBlocks": "remplacer n'est pas disponible pour les boucles", - "Announcement.control": "controle", - "Announcement.delete": "suprimé {actionType} {actionName}", - "Announcement.deleteAll": "suprimmer le programme", + "Announcement.actionSelected": "{actionType} {actionName} sélectionné", + "Announcement.add": "{actionType} {actionName} ajouté", + "Announcement.backward1": "reculer d'un carré", + "Announcement.backward2": "reculer de 2 carrés", + "Announcement.backward3": "reculer de 3 carrés", + "Announcement.cannotMoveNext": "à la fin du programme, incapable d'avancer", + "Announcement.cannotMovePrevious": "au début du programme, incapable de reculer", + "Announcement.cannotReplaceLoopBlocks": "ne peut pas remplacer les blocs « début de boucle » ou « fin de boucle »", + "Announcement.control": "contrôle", + "Announcement.delete": "{actionType} {actionName} supprimé", + "Announcement.deleteAll": "suprimmer le programme ?", "Announcement.endLoop": "boucle {loopLabel}", - "Announcement.forward1": "avance 1 case", - "Announcement.forward2": "avance 2 cases", - "Announcement.forward3": "avance 3 cases", - "Announcement.left180": "turner à gauche de 180 degréees", - "Announcement.left45": "tourner à gauche de 45 degrées", - "Announcement.left90": "tourner a gauche de 90 degréees", + "Announcement.forward1": "avancer d'un carré", + "Announcement.forward2": "avancer de 2 carrés", + "Announcement.forward3": "avancer de 3 carrés", + "Announcement.left180": "tourner à gauche à 180 degrés", + "Announcement.left45": "tourner à gauche à 45 degrés", + "Announcement.left90": "tourner à gauche à 90 degrés", "Announcement.loop": "boucle", - "Announcement.moveToNext": "déplacer vers la droite", - "Announcement.moveToPrevious": "déplacer vers la gauche", + "Announcement.moveToNext": "déplacé vers la droite", + "Announcement.moveToPrevious": "déplacé vers la gauche", "Announcement.movement": "mouvement", "Announcement.noActionSelected": "aucune action sélectionnée", - "Announcement.replace": "mouvement {oldActionName} remplacer par une {newActionName}", - "Announcement.right180": "turner a droite 180 degrées", - "Announcement.right45": "tourner a droite 45 degrées", - "Announcement.right90": "tourner a droite 90 degrées", + "Announcement.replace": "mouvement {oldActionName} remplacé par {newActionName}", + "Announcement.right180": "tourner à droite à 180 degrés", + "Announcement.right45": "tourner à droite à 45 degrés", + "Announcement.right90": "tourner à droite à 90 degrés", "Announcement.startLoop": "boucle {loopLabel}", "App.appHeading": "Weavly", - "App.appHeading.link": "Weavly, en savoir plus sur Weavly a Weavly point org", + "App.appHeading.link": "Weavly, en savoir plus sur Weavly sur Weavly point org", "App.privacyModalToggle.ariaLabel": "politique de confidentialité de Weavly", - "AtlanticCanada.character": "Insulaire de Cap", - "AtlanticCanada.fishProcessingPlant": "usine de transformation des poissons", + "AtlanticCanada.character": "Cape Islander", + "AtlanticCanada.fishProcessingPlant": "usine de transformation du poisson", "AtlanticCanada.fogBank": "banc de brouillard", "AtlanticCanada.house": "une maison", - "AtlanticCanada.iceberg": "in iceberg", - "AtlanticCanada.label": "Scène de voyage Atlantique. Voyagez au Canada atlntique à travers l'océan Atlantique. La météo est imprévisable dans l'océan , certaines parties de l'océan peuvent être orageuses et certaines parties de l'océan peuvent être couverte de brouillard. Voyagez en toute sécurité pour visiter une usine de transformation du poisson et une village terrestre; vous pourriez rencontrer des icebergs ou des baleine sur votre chemin. Votre personnage dans cette scène est un bateau de pêche, également connu sous le nom Cape Islander dans le Canada Atlantique.", + "AtlanticCanada.iceberg": "un iceberg", + "AtlanticCanada.label": "Scène du Canada atlantique. Parcourez le Canada atlantique à travers l'océan Atlantique. La temps est imprévisable dans l'océan Atlantique, certaines parties de l'océan peuvent être orageuses et certaines parties de l'océan peuvent être couvertes de brouillard. Voyagez en toute sécurité pour visiter une usine de transformation du poisson et une village sur terre ; vous pourriez rencontrer des icebergs ou des baleine en chemin. Votre personnage dans cette scène est un bateau de pêche, également connu sous le nom de Cape Islander dans le Canada atlantique.", "AtlanticCanada.land": "la terre", - "AtlanticCanada.lighthouse": "la phare", + "AtlanticCanada.lighthouse": "un phare", "AtlanticCanada.rowingBoatOnTheShore": "un bateau à rames sur le rivage", - "AtlanticCanada.sailboat": "un bateau a voile", + "AtlanticCanada.sailboat": "un voilier", "AtlanticCanada.shoal": "un banc de poissons", - "AtlanticCanada.shore": "la rive", + "AtlanticCanada.shore": "le rivage", "AtlanticCanada.storms": "tempêtes", "AtlanticCanada.trees": "arbres", "AtlanticCanada.water": "l'eau", "AtlanticCanada.whale": "une baleine", - "BluetoothApiWarning.errorIconLabel": "advertissent", - "BluetoothApiWarning.message": "la connection du robot dash fonctionne seulement en Chrome", - "Camping.bear": "l`ours noire", - "Camping.branch": "branche d'arbre", + "BluetoothApiWarning.errorIconLabel": "avertissement", + "BluetoothApiWarning.message": "La connexion du robot Dash ne fonctionne actuellement que dans Chrome.", + "Camping.bear": "l'ours noire", + "Camping.branch": "la branche d'arbre", "Camping.character": "l'écureuil", "Camping.fire": "le feu de camp", - "Camping.label": "une scène de camping. un ours noir atteint un tronc d'arbre sûre le côté gauche de la scène. une branche 'arbre traverse le haut des la scène et une échelle de corde y est suspendu. il y a une tente ouvert sur le côté droit de la scène. un lac et un feu de camp sont au milieu de la scène. votre personnage dans cette scène est une écureuil.", + "Camping.label": "Une scène de camping. Un ours noir grimpe sur un tronc d'arbre sur le côté gauche de la scène. Une branche d'arbre traverse le haut de la scène et une échelle de corde y est suspendue. Il y a une tente ouverte sur le côté droit de la scène. Un lac et un feu de camp se trouvent au milieu de la scène. Votre personnage dans cette scène est un écureuil.", "Camping.ladder": "une échelle de corde", "Camping.lake": "le lac", "Camping.tentdoor": "la porte de la tente", "Camping.trunk": "le tronc d'arbre", - "CharacterAriaLive.movementAriaLabel": "Le {sceneCharacter} bouge", - "CharacterDescriptionBuilder.positionAndDirection": "À {columnLabel} {rowLabel} face à {direction}", - "CharacterDescriptionBuilder.positionAndDirectionAndItem": "À {columnLabel} {rowLabel} sur {backgroundItem} orienté vers {direction}", - "CharacterPositionController.editPosition.columnPosition": "position de la colonne des charactères", + "CharacterAriaLive.movementAriaLabel": "{sceneCharacter} bouge", + "CharacterDescriptionBuilder.positionAndDirection": "À {columnLabel} {rowLabel} {facingDirection}", + "CharacterDescriptionBuilder.positionAndDirectionAndItem": "À {columnLabel} {rowLabel} sur {backgroundItem} {facingDirection}", + "CharacterPositionController.editPosition.columnPosition": "position de la colonne de charactères", "CharacterPositionController.editPosition.designMode.columnPosition": "position de la colonne du pinceau", "CharacterPositionController.editPosition.designMode.moveDown": "déplacer le pinceau vers le bas", "CharacterPositionController.editPosition.designMode.moveLeft": "déplacer le pinceau vers la gauche", "CharacterPositionController.editPosition.designMode.moveRight": "déplacer le pinceau vers la droite", "CharacterPositionController.editPosition.designMode.moveUp": "déplacer le pinceau vers le haut", - "CharacterPositionController.editPosition.designMode.rowPosition": "position de rang du pinceau", + "CharacterPositionController.editPosition.designMode.rowPosition": "position de la rangée du pinceau", "CharacterPositionController.editPosition.moveDown": "déplacer le personnage vers le bas", "CharacterPositionController.editPosition.moveLeft": "déplacer le personnage vers la gauche", "CharacterPositionController.editPosition.moveRight": "déplacer le personnage vers la droite", "CharacterPositionController.editPosition.moveUp": "déplacer le personnage vers le haut", - "CharacterPositionController.editPosition.rowPosition": "position de la ranger des charactères", - "CharacterPositionController.editPosition.turnLeft": "turne le charactère a la gauche", - "CharacterPositionController.editPosition.turnRight": "turne le charactère a la droite", + "CharacterPositionController.editPosition.rowPosition": "position de la rangée du personnage", + "CharacterPositionController.editPosition.turnLeft": "tournez le personnage à gauche", + "CharacterPositionController.editPosition.turnRight": "tournez le personnage à droite", "CharacterPositionController.paintbrushButtonEraserSelected": "effacer le carré", "CharacterPositionController.paintbrushButtonNoSelection": "peindre un carré de fond", - "CharacterPositionController.paintbrushButtonTileSelected": "peinture {tile}", + "CharacterPositionController.paintbrushButtonTileSelected": "peindre {tile}", "CharacterPositionController.setStartButton": "définir la position de départ", - "Command.backward1": "à l'envers 1 carré", - "Command.backward2": "a l'envers 2 carrées", - "Command.backward3": "à l'envers 3 carrées", - "Command.endLoop": "{loopLabel} fin de boucle", - "Command.forward1": "avancer d'une case", - "Command.forward2": "avancer de 2 cases", - "Command.forward3": "avancer de 3 cases", - "Command.left180": "tourner à gauche 180 degréees", - "Command.left45": "tourner à gauche 45 degrées", - "Command.left90": "tourner à gauche 90 degrées", + "Command.backward1": "reculer d'un carré", + "Command.backward2": "reculer de 2 carrés", + "Command.backward3": "reculer de 3 carrés", + "Command.endLoop": "fin de boucle {loopLabel}", + "Command.forward1": "avancer d'un carré", + "Command.forward2": "avancer de 2 carrés", + "Command.forward3": "avancer de 3 carrés", + "Command.left180": "tourner à gauche à 180 degrés", + "Command.left45": "tourner à gauche à 45 degrés", + "Command.left90": "tourner à gauche à 90 degrés", "Command.loop": "boucle", - "Command.loop.label": "{loopLabel} de boucle", - "Command.right180": "tourner à droite 180 degréees", - "Command.right45": "tourner à droite 45 degrées", - "Command.right90": "tourner à droite 90 degrees", + "Command.loop.label": "boucle {loopLabel}", + "Command.right180": "tourner à droite à 180 degrés", + "Command.right45": "tourner à droite à 45 degrés", + "Command.right90": "tourner à droite à 90 degrés", "Command.startLoop": "début de boucle {loopLabel}", - "CommandInfo.nextStep": "après l'étape {next step number} {command}", - "CommandInfo.nextStep.endLoop": "hors boucle {loopLabel}", - "CommandInfo.nextStep.inLoop": "après l'étape {next step number} {command} de la boucle {loopLabel}", - "CommandInfo.nextStep.loop": "après l'étape {next step number} {command}", - "CommandInfo.nextStep.startLoop": "en boucle {loopLabel}", - "CommandInfo.previousStep": "avant l'étape {previousStepNumber} {command}", - "CommandInfo.previousStep.endLoop": "dans la boucle {loopLabel}", - "CommandInfo.previousStep.inLoop": "avant l'étape {previousStepNumber} {command} de la boucle {loopLabel}", - "CommandInfo.previousStep.loop": "avant l'étape {previousStepNumber} {command}", - "CommandInfo.previousStep.startLoop": "hors boucle {loopLabel}", - "CustomBackgroundDesignModeButton.customBackgroundDesignMode": "mode de conception arrière plan personnalisé", + "CustomBackgroundDesignModeButton.customBackgroundDesignMode": "mode de conception d'arrière-plan personnalisé", "DeepOcean.babyJellyfish": "un bébé méduse", "DeepOcean.character": "le sous-marin", "DeepOcean.coral": "corail", "DeepOcean.fish": "un poisson", "DeepOcean.fishGroup": "le groupe de poissons", "DeepOcean.jellyfish": "le méduse", - "DeepOcean.label": "une scène sous marine. Un grand requin fait le tours des eaux au-dessous d'un coffre de trésores au fond du fond marin. Le coffre est rempli de bijoux et de pieces d'ors. Poissons et méduses nagent autour des coraux et des algues. Votre personnage dans ce scène est un sous-marin.", - "DeepOcean.shark": "le renard", - "DeepOcean.treasure": "the trésore", - "DesignModeCursorDescriptionBuilder.position": "à {columnLabel} {rowLabel}", + "DeepOcean.label": "Une scène sous-marine. Un grand requin fait le tour des eaux au-dessus d'un coffre au trésor au fond de la mer. Le coffre est rempli de bijoux et de pièces d'or. Poissons et méduses nagent autour des coraux et des algues. Ton personnage dans cette scène est un sous-marin.", + "DeepOcean.shark": "le requin", + "DeepOcean.treasure": "le trésor", + "DesignModeCursorDescriptionBuilder.position": "À {columnLabel} {rowLabel}", "DesignModeCursorDescriptionBuilder.positionAndItem": "À {columnLabel} {rowLabel} sur {backgroundItem}", "DeviceConnectControl.connected": "Connecté", "DeviceConnectControl.connecting": "Connexion en cours", "DeviceConnectControl.notConnected": "Pas connecté", - "Direction.0": "haut", - "Direction.1": "en haut à droite", - "Direction.2": "droite", - "Direction.3": "en bas à droite", - "Direction.4": "bas", - "Direction.5": "en bas à gauche", - "Direction.6": "gauche", - "Direction.7": "en haut à gauce", - "EuropeTrip.B6": "la tour de Saint Vincent en Portugal", + "FacingDirection.0": "face vers le haut", + "FacingDirection.1": "en haut à droite", + "FacingDirection.2": "face à droite", + "FacingDirection.3": "en bas à droite", + "FacingDirection.4": "face vers le bas", + "FacingDirection.5": "en bas à gauche", + "FacingDirection.6": "face à gauche", + "FacingDirection.7": "en haut à gauche", + "EuropeTrip.B6": "la Tour de Saint Vincent au Portugal", "EuropeTrip.B7": "Portugal", "EuropeTrip.C1": "Islande", - "EuropeTrip.C2": "une balleine en Islande", + "EuropeTrip.C2": "une baleine en Islande", "EuropeTrip.C3": "Irelande", "EuropeTrip.C5": "Espagne", "EuropeTrip.C6": "Portugal et Espagne", - "EuropeTrip.C7": "Guitare Flamenco en Espagne", - "EuropeTrip.D2": "Irlande et le Royaume-Uni", - "EuropeTrip.D3": "un trèfle en irlande; aussi sur cette place le Royaume-Uni", - "EuropeTrip.D4": "France te le Royaume-Uni", + "EuropeTrip.C7": "Guitare flamenco en Espagne", + "EuropeTrip.D2": "Irlande et Royaume-Uni", + "EuropeTrip.D3": "un trèfle sur l'Irlande ; aussi sur cette place le Royaume-Uni", + "EuropeTrip.D4": "France et Royaume-Uni", "EuropeTrip.D5": "France", "EuropeTrip.D6": "France et Espagne", "EuropeTrip.D7": "Espagne", "EuropeTrip.E1": "le Royaume-Uni", "EuropeTrip.E2": "le Royaume-Uni", - "EuropeTrip.E3": "un bus à impériale au Royaume-Uni", - "EuropeTrip.E4": "chocolate en Belgique; aussi sur cette pièce est la France et le Royaume-Uni", - "EuropeTrip.E5": "La tour eiffel en France", - "EuropeTrip.E6": "LA tour Eiffel en France", + "EuropeTrip.E3": "un autobus à deux étages au Royaume-Uni", + "EuropeTrip.E4": "chocolat en Belgique; aussi sur cette place la France et le Royaume-Uni", + "EuropeTrip.E5": "La Tour Eiffel en France", + "EuropeTrip.E6": "La Tour Eiffel en France", "EuropeTrip.E7": "Espagne", "EuropeTrip.F1": "Norvège", - "EuropeTrip.F2": "un drakkar à Norway", - "EuropeTrip.F3": "un moulin-à-vent aux Pays-Bas", - "EuropeTrip.F4": "un bretzel en Allemagne; aussi das cette pièce le Belgique, Luxembourg, et Pays-Bas", - "EuropeTrip.F5": "un montre en Suisse; aussi sur cette pièce l'Autriche, France et l'Allemagne", + "EuropeTrip.F2": "un drakkar sur la Norvège", + "EuropeTrip.F3": "un moulin à vent aux Pays-Bas", + "EuropeTrip.F4": "un bretzel sur l'Allemagne ; également sur cette place Belgique et Luxembourg et Pays-Bas", + "EuropeTrip.F5": "une surveillance de la Suisse ; également sur cette place Autriche et France et Allemagne", "EuropeTrip.F6": "France et Italie", "EuropeTrip.F7": "France et Italie", "EuropeTrip.G1": "Norvège et Suède", - "EuropeTrip.G2": "Danemark et Norvège et Suède", - "EuropeTrip.G3": "pâtisserie danoise aux Danemark; également sur cette place l'Allemagne et la Suède", - "EuropeTrip.G4": "Colonnade du moulin en République tchèque; également sur cette pièce est l'Allemagne et Pologne", - "EuropeTrip.G5": "un violon en Autruche et Bled sur la Sloavquie; aussi sur cette pièce le République tzchège et l'Allemagne", - "EuropeTrip.G6": "le miel en Croatie et Bled en Slovanie; également sur cette pièce est l'Italie", + "EuropeTrip.G2": "Danemark and Norvège et Suède", + "EuropeTrip.G3": "Pâtisserie danoise au Danemark ; aussi sur cette place l'Allemagne et la Suède", + "EuropeTrip.G4": "Colonnade du moulin en République tchèque ; aussi sur cette place l'Allemagne et la Pologne", + "EuropeTrip.G5": "un violon sur l'Autriche et Bled sur la Slovénie ; également sur cette place en République tchèque et en Allemagne", + "EuropeTrip.G6": "le miel en Croatie et Bled en Slovénie ; aussi sur cette place Italie", "EuropeTrip.G7": "pizza en Italie", "EuropeTrip.G8": "Italie", "EuropeTrip.H1": "Suède", - "EuropeTrip.H2": "Galma Stan sur la Suède", + "EuropeTrip.H2": "Galma Stan en Suède", "EuropeTrip.H3": "Pologne et Suède", - "EuropeTrip.H4": "Kielbasa aux Pologne", - "EuropeTrip.H5": "le paprika en Hongrie et la cérémique en Slovaquie; également sur cette place Autriche et République tscheque et Slovénie", - "EuropeTrip.H6": "la mosquée Sinan Pacha au Kosovo et l'église Saint-Sava en Serbie et Stari Most en Bosnie-Herzégovine ; également sur cette place la Croatie et la Hongrie et le Monténégro", + "EuropeTrip.H4": "Kielbasa sur la Pologne", + "EuropeTrip.H5": "le paprika en Hongrie et la céramique en Slovaquie ; également sur cette place Autriche et la République tchèque et Slovénie", + "EuropeTrip.H6": "la mosquée Sinan Pacha au Kosovo et l'église Saint-Sava en Serbie et Stari Most en Bosnie-Herzégovine ; aussi sur cette place la Croatie et la Hongrie et le Monténégro", "EuropeTrip.H7": "une chargia en Albanie et la mosquée Sinan Pacha au Kosovo et un yacht au Monténégro ; également sur cette place Macédoine du Nord", "EuropeTrip.H8": "Grèce et Italie", - "EuropeTrip.I1": "Cathéralde d'Helsinki en Finlande", - "EuropeTrip.I2": "Tallinn en Estonie; également sur cette place est Finlande et Lettonie", - "EuropeTrip.I3": "des marguerites en Lettonie et le châteaux de l'Île de Trakai en Lutuanie; aussi sur cette pièce Biéloroussie", + "EuropeTrip.I1": "La cathédrale d'Helsinki est la Finlande", + "EuropeTrip.I2": "Tallinn en Estonie ; également sur cette place la Finlande et la Lettonie", + "EuropeTrip.I3": "des marguerites en Lettonie et le château de l'île de Trakai en Lituanie ; aussi sur cette place Biélorussie", "EuropeTrip.I4": "Biéroussie et Pologne et Ukraine", - "EuropeTrip.I5": "Châteux de Peles en Roumaine; aussi sur cette pièce Hongrie, Sloavquie, et Ukraine", - "EuropeTrip.I6": "Église Saint-Sava en Serbie ; également sur cette place la Bulgarie et la Roumanie", - "EuropeTrip.I7": "Rose Valley en Bulgarie et Millennium Cross en Macédoine du Nord ; également sur cette place la Grèce et le Kosovo", - "EuropeTrip.I8": "le Parthenon en Grèce", + "EuropeTrip.I5": "Château de Peles en Roumanie ; également sur cette place la Hongrie et la Slovaquie et l'Ukraine", + "EuropeTrip.I6": "Église Saint-Sava en Serbie ; aussi sur cette place la Bulgarie et la Roumanie", + "EuropeTrip.I7": "Vallée Rose en Bulgarie et Millennium Cross en Macédoine du Nord ; également sur cette place la Grèce et le Kosovo", + "EuropeTrip.I8": "le Parthénon sur la Grèce", "EuropeTrip.J1": "Finlande", - "EuropeTrip.J3": "bibliothèque nationale aux Biéloroussie", - "EuropeTrip.J4": "Biéroussie et Ukraine", - "EuropeTrip.J5": "tournesol en Moldavie; aussi sur cette pièce Roumaine et l'Ukraine", + "EuropeTrip.J3": "Bibliothèque nationale sur la Biélorussie", + "EuropeTrip.J4": "Biélorussie et Ukraine", + "EuropeTrip.J5": "tournesol en Moldavie ; aussi sur cette place la Roumanie et l'Ukraine", "EuropeTrip.J6": "Bulgaria et Moldova et Romanie", "EuropeTrip.J7": "Bulgarie et Turquie", "EuropeTrip.J8": "Grèce et Turquie", "EuropeTrip.K4": "Ukraine", - "EuropeTrip.K5": "Monastère au dôme doré de Saint-Micheal en Ukraine", + "EuropeTrip.K5": "Monastère au dôme doré de Saint-Michel en Ukraine", "EuropeTrip.K6": "Ukraine", "EuropeTrip.K7": "café en Turquie", - "EuropeTrip.K8": "olives en Chypre; aussi sur cette case Turquie", + "EuropeTrip.K8": "olives à Chypre; aussi sur cette place Türkiye", "EuropeTrip.L4": "Ukraine", "EuropeTrip.L5": "Ukraine", "EuropeTrip.L7": "Turquie", - "EuropeTrip.L8": "olives en Chypre; aussi sur cette case Turquie", + "EuropeTrip.L8": "olives à Chypre; aussi sur cette place Türkiye", "EuropeTrip.character": "l'avion", - "EuropeTrip.label": "Une scène de voyage en Europe contenant une carte de Europe avec des attractions touristiques. L'Islande est située en haut à gauche de la scène. Chypre est située en bas à droite de la scène. Les attractions touristiques sont située dans le pays connu pour des attractions, comme le Violon en Autriche, près du centre de la scène. Votre personnage dans cette scène est un avion.", + "EuropeTrip.label": "Une scène de voyage en Europe contenant une carte de l'Europe avec des attractions touristiques. L'Islande est située en haut à gauche de la scène. Chypre est située en bas à droite de la scène. Les attractions touristiques sont situées dans le pays connu pour l'attraction, comme le violon en Autriche, près du centre de la scène. Ton personnage dans cette scène est un avion.", "GroceryStore.apples": "pommes", "GroceryStore.bagOfRice": "sac de riz", "GroceryStore.bananas": "bananes", @@ -758,74 +757,74 @@ "GroceryStore.chocolateMilk": "lait au chocolat", "GroceryStore.cucumbers": "concombres", "GroceryStore.eggplants": "aubergines", - "GroceryStore.eggs": "oeufs ", + "GroceryStore.eggs": "oeufs", "GroceryStore.fish": "poisson", "GroceryStore.grapes": "raisins", "GroceryStore.greenVegetables": "légumes verts", - "GroceryStore.groundBeef": "le boeuf haché", + "GroceryStore.groundBeef": "boeuf haché", "GroceryStore.jars": "pots", - "GroceryStore.label": "Une scène d'epicerie. En haut au milieu se trouve un frigo contenent de la viande et du poisson. En haut à droite se trouve des pots, des canettes et d'autres articles de garde-manger. A gauche du magasin se trouve des pains et des légumes. Au milieu vers le bas se trouve les fruits. Et en bas à droite se trouve un frigo contenant des produits laitier et d'autre produits réfrigérés. Votre personnage dans cette scène est un panier d'épicerie", - "GroceryStore.milk": "lait ", + "GroceryStore.label": "Une scène d'épicerie. En haut au centre se trouve un frigo contenant de la viande et du poisson. En haut à droite se trouvent des pots, des canettes et d'autres articles de garde-manger. À gauche du magasin se trouvent des pains et des légumes. Au milieu vers le bas se trouvent des fruits. Et en bas à droite se trouve un frigo avec des produits laitiers et d'autres produits réfrigérés. Ton personnage dans cette scène est un caddie.", + "GroceryStore.milk": "lait", "GroceryStore.onions": "onions", "GroceryStore.orangeJuice": "jus d'orange", "GroceryStore.oranges": "oranges", "GroceryStore.pasta": "pâtes", - "GroceryStore.pears": "des poires", + "GroceryStore.pears": "poires", "GroceryStore.pineapples": "ananas", "GroceryStore.potatoes": "patates", - "GroceryStore.refrigerator": "frigo ou réfrigirateur", + "GroceryStore.refrigerator": "frigo", "GroceryStore.steak": "steak", "GroceryStore.strawberries": "fraises", "GroceryStore.tofu": "tofu", "GroceryStore.tomatoes": "tomates", - "GroceryStore.watermelons": "melon-d'eau", - "GroceryStore.yogurt": "yaourte", + "GroceryStore.watermelons": "melons d'eau", + "GroceryStore.yogurt": "yogourt", "Haunted.chair": "la chaise", "Haunted.character": "la lampe de poche", - "Haunted.deerSkull": "la crâne d'une cerf", + "Haunted.deerSkull": "le crâne de chevreuil", "Haunted.fireplace": "la cheminée", - "Haunted.label": "Une scène de manoire effrayante. Le corridor d'entrée comporte un grand escalier commençant un bas à droite et allant en haut à gauche. Des peintures hantées, un mirroir et une crâne de cerf effrayant sont accrochées au mur. Les chauves sourris volent. Un feu brûle dans la chiminée située sous la cage d'escalier. Une grande chaise confortable est devant le feu. Les étagères d'une grande bibliothèque à gauche de la scène sont remplis de livres, potions et plantes. Votre personnage dans cette scène est une lampe de poche.", - "Haunted.mirror": "le mirror", + "Haunted.label": "Une scène de manoir effrayante. Le hall d'entrée comporte un grand escalier partant du bas à droite et allant en haut à gauche. Des peintures hantées, un miroir et un crâne de cerf effrayant sont accrochés au mur. Les chauves-souris volent. Un feu brûle dans la cheminée sous la cage d'escalier. Une grande chaise confortable est devant le feu. Les tablettes d'une grande bibliothèque à gauche de la scène sont remplies de livres, de potions et de plantes. Votre personnage dans cette scène est une lampe de poche.", + "Haunted.mirror": "le miroir", "Haunted.painting": "une peinture", "Haunted.shelf": "la bibliothèque", "Haunted.stairs": "les escaliers", "KeyboardInputModal.ShowHide.AriaLabel": "afficher le menu des raccourcis claviers", - "KeyboardInputModal.Toggle.AriaLabel": "basculer les raccourcis claviers", - "KeyboardInputModal.Toggle.Label": "keyboard shortcuts", + "KeyboardInputModal.Toggle.AriaLabel": "Basculement des raccourcis clavier", + "KeyboardInputModal.Toggle.Label": "Raccourcis clavier", "Landmarks.bigBen": "Tour Big Ben", "Landmarks.burAlArab": "Le bâtiment Burj al Arab", "Landmarks.character": "le robot", - "Landmarks.cnTower": "La tour CN", - "Landmarks.colosseum": "Le Colossuem", - "Landmarks.easterIsland": "les statues de l'île de pacques", + "Landmarks.cnTower": "La Tour CN", + "Landmarks.colosseum": "Le Colisée", + "Landmarks.easterIsland": "Les statues de l'île de Pâques", "Landmarks.eiffelTower": "La Tour Eiffel", - "Landmarks.fairyChimneys": "cheminées de fées", - "Landmarks.floatingMarket": "le marché flottant de Vietnam", - "Landmarks.grandCanyon": "Le grand Canyon", - "Landmarks.greatPyramid": "la grande pyramide de Gizeh", - "Landmarks.greatSphinx": "la grande sphinx de Gizeh", - "Landmarks.greatWall": "La grande muraille de Chine", - "Landmarks.label": "Une grande scène mondiale qui contient 23 monuments célèbres trouver dans le monde. Un avion vole depuis le point supérieur gauche. Un train part du point supérieur droite. Les points de repère sont situés à différents endroits de cet scène, notament le fameux Sphinx en Egypte, la Tour Eiffel en France, la tour de Tokyo au Japon et le marché flottant au Vietnam. Votre caractère pour explorer cette scène est un robot.", - "Landmarks.leaningTowerPisa": "La tour penché de Pize", + "Landmarks.fairyChimneys": "Cheminées de fées", + "Landmarks.floatingMarket": "Le marché flottant du Vietnam", + "Landmarks.grandCanyon": "Le Grand Canyon", + "Landmarks.greatPyramid": "La Grande Pyramide de Gizeh", + "Landmarks.greatSphinx": "Le Grand Sphinx de Gizeh", + "Landmarks.greatWall": "La Grande Muraille de Chine", + "Landmarks.label": "Une scène mondiale qui contient 23 monuments célèbres trouvés dans le monde entier. Un avion vole du coin supérieur gauche. Un train circule du coin inférieur droit. Les monuments sont situés à différents endroits de cette scène, notamment le célèbre Sphinx en Égypte, la Tour Eiffel en France, la Tour de Tokyo au Japon et le marché flottant au Vietnam. Votre personnage pour explorer cette scène est un robot.", + "Landmarks.leaningTowerPisa": "La tour penchée de Pise", "Landmarks.machuPicchu": "Matchu Picchu", - "Landmarks.niagaraFalls": "chutes du Niagara", + "Landmarks.niagaraFalls": "Chutes du Niagara", "Landmarks.operaHouse": "L'Opéra de Sydney", "Landmarks.plane": "un avion", "Landmarks.stBasils": "Cathédrale Saint-Basile", "Landmarks.statueLiberty": "la statue de la Liberté", "Landmarks.stonehenge": "Stonehenge", - "Landmarks.tableMountain": "table montagne", + "Landmarks.tableMountain": "Montagne de la Table", "Landmarks.tajMahal": "le palais Taj Mahal", - "Landmarks.tokyoTower": "la tour de Tokyo", + "Landmarks.tokyoTower": "la Tour de Tokyo", "Landmarks.train": "un train", "Landmarks.windmill": "les moulins à vents des Pais-Bas", "Marble.bricks": "briques", - "Marble.character": "une bille", - "Marble.label": "Une labyrinthe fait de briques de différentes couleurs. Votre personnage dans cette scène est une bille. Il y a un chemin à travers le labyrinthe qui commence là où se trouve votre bille et il existe plusieurs façons d'échapper du labyrinthe.", + "Marble.character": "la bille", + "Marble.label": "Un labyrinthe fait de briques de différentes couleurs. Ton personnage dans cette scène est une bille. Il y a un sentier à travers le labyrinthe qui commence là où se trouve votre bille et il y a plusieurs façons d'échapper au labyrinthe.", "MusicBand.character": "la note de musique", "MusicBand.drumKit": "la batterie", "MusicBand.guitar": "la guitare", - "MusicBand.label": "Une scène de groupe de bande avec des instruments de musique. Les instruments sont déposés sur 2 rangées, une rangée au milieu de la scène et une vers le bas de la scène. Dans la rangée supérieur, il ya une guitar, une batterie et un saxophone. Sur la rangée inférieur, il y a un tambourin, un xylophone avec un maillet, une microphone sur un pied et une synthétiseur. Au sommet de la scène. des projecteurs éclairent les instruments et dans les coins inférieurs à droit se trouve les haut-parleurs. Votre personnage dans cette scène est un note de musique.", + "MusicBand.label": "Une scène de groupe de musique avec des instruments de musique. Les instruments sont disposés sur 2 rangées, une rangée au milieu de la scène et une en bas de la scène. Dans la rangée du haut, il y a une guitare, une batterie et un saxophone. Dans la rangée du bas, il y a un tambourin, un xylophone avec un maillet, un microphone sur pied et un synthétiseur. Au sommet de la scène, des projecteurs éclairent les instruments. Et dans les coins inférieurs gauche et droit se trouvent des haut-parleurs. Votre personnage dans cette scène est une note de musique.", "MusicBand.loudspeaker": "un haut-parleur", "MusicBand.microphone": "un mircrophone sur un pied", "MusicBand.saxophone": "le saxophone", @@ -835,130 +834,130 @@ "MusicBand.xylophone": "un xylophone avec un maillet", "PenDownToggleSwitch.penDown": "Stylo vers le bas", "PlayButton.pause": "pause", - "PlayButton.play": "jouer", - "PlayControls.heading": "jouer aux commandes", - "ProgramBlockEditor.beginningBlock": "ajouté l'action selectionnée {actionName} au début du programme", - "ProgramBlockEditor.betweenBlocks": "ajouté l'action selectionée {actionName} entre la position {previousStepNumber}, {previousStepActionName} et la position {nextStepNumber}, {nextStepActionName}", - "ProgramBlockEditor.blocks.noCommandSelected": "assurez vous qu'une action est sélectionée", - "ProgramBlockEditor.command": "{blockName}, possition, {index} du programme en cours", - "ProgramBlockEditor.lastBlock": "ajouté l'action sélectionée {actionName} à la fin du programme", - "ProgramBlockEditor.nestedCommand": "{blockName}, possition, {index} du boucle, {parentLoopLabel}", - "ProgramBlockEditor.program.deleteAll": "suprrimer tout les étapes de votre programme", - "ProgramBlockEditor.toggleAddNodeExpandMode": "ajouter un note en mode développer", - "ProgramSequence.heading": "vitesse de lecture du programme", - "ProgramSpeedController.slider": "vitesse de lecture du programme", - "RefreshButton": "rafraîchir", + "PlayButton.play": "lire", + "PlayControls.heading": "Commandes de lire", + "ProgramBlockEditor.beginningBlock": "Ajouter l'action sélectionnée {actionName} au début du programme", + "ProgramBlockEditor.betweenBlocks": "Ajouter l'action sélectionnée {actionName} entre la position {previousStepNumber}, {previousStepActionName} et la position {nextStepNumber}, {nextStepActionName}", + "ProgramBlockEditor.blocks.noCommandSelected": "Assurez-vous qu'une action est sélectionnée", + "ProgramBlockEditor.command": "{blockName}, position {index} du programme actuel", + "ProgramBlockEditor.lastBlock": "Ajouter l'action sélectionnée {actionName} à la fin du programme", + "ProgramBlockEditor.nestedCommand": "{blockName}, position {index} de la boucle {parentLoopLabel}", + "ProgramBlockEditor.program.deleteAll": "Supprimez toutes les étapes de votre programme", + "ProgramBlockEditor.toggleAddNodeExpandMode": "afficher les boutons « ajouter »", + "ProgramSequence.heading": "Séquence du programme", + "ProgramSpeedController.slider": "Vitesse de lecture du programme", + "RefreshButton": "Rafraîchir", "Savannah.alligator": "L'alligator", "Savannah.babyAlligator": "le bébé alligator", "Savannah.babyGiraffe": "le bébé giraffe", "Savannah.bush": "une buisson", - "Savannah.character": "le jeep", - "Savannah.flamingo": "le flamant rose", + "Savannah.character": "la jeep", + "Savannah.flamingo": "le flamant", "Savannah.giraffe": "le giraffe", "Savannah.hippo": "l'hippopotame", - "Savannah.label": "Une scène de Savane. Un lion rugit au sommet d'une falaise au-dessous de l'horizon. Une mère et son bébé giraffe parcourent la savane. Deux, crocodiles, un flamant rose et un hippopotame boivent de l'eau d'un étang entourné d'arbres. Votre personnage dans cette scène est un Jeep", + "Savannah.label": "Une scène de savane. Un lion rugit au sommet d’une falaise au-dessus de l’horizon. Une mère et son bébé girafe parcourent la savane. Deux crocodiles, un flamant rose et un hippopotame boivent l'eau d'un étang entouré d'arbres. Ton personnage dans cette scène est un Jeep.", "Savannah.lion": "le lion", "Savannah.pond": "l'étang", - "Savannah.tree": "l'arbre", - "Scene.description": "Scène, dans {backgroundName}, grille {numColumns} par {numRows}. {characterDescription}", + "Savannah.tree": "un arbre", + "Scene.description": "Scène, dans {backgroundName}, une grille {numColumns} par {numRows}. {characterDescription}", "Scene.heading": "scène", - "SceneMessage.close": "fermée le message", + "SceneMessage.close": "fermer le message", "Sketchpad.character": "le robot", - "Sketchpad.label": "un croquis vierge avec une ligne de quadrillage. Votre charactère dans se scène est un robot", - "Space.aliens": "les aliens", - "Space.asteroid": "une astéroïde", - "Space.character": "le vaisseaux spaciale", + "Sketchpad.label": "Un carnet de croquis vierge avec des lignes de quadrillage. Ton personnage dans cette scène est un robot.", + "Space.aliens": "les extraterrestres", + "Space.asteroid": "un astéroïde", + "Space.character": "le vaisseau spatial", "Space.earth": "la Terre", - "Space.label": "Une scène spaciale avec la Terre, Mars, Saturne, et la Lune répartis en espace. Entre les planètes, il y a des roches spaciales, des météores, un satellite et deux extraterrestres . Votre personnage dans ce scène est un vaisseaux spaciale", + "Space.label": "Une scène spatiale avec la Terre, Mars, Saturne et la Lune réparties dans l'espace. Entre ces planètes se trouvent des roches spatiales, des météores, un satellite et deux extraterrestres. Votre personnage dans cette scène est un vaisseau spatial.", "Space.mars": "Mars", - "Space.meteor": "Une météore", + "Space.meteor": "un météore", "Space.moon": "La Lune", - "Space.satellite": "le satélitte", + "Space.satellite": "le satellite", "Space.saturn": "Saturne", - "Space.star": "Une étoile", + "Space.star": "une étoile", "Sports.badmintonShuttlecock": "volant de badminton", - "Sports.baseballGloveAndBall": "gant de balle et baseball", + "Sports.baseballGloveAndBall": "gant et balle de baseball", "Sports.basketball": "basketball", - "Sports.bicycle": "bicylette", - "Sports.bowlingBallAndPins": "boulles et quilles de bowling", - "Sports.boxingGloves": "gants de boxing", - "Sports.character": "voiture de golf", + "Sports.bicycle": "bicyclette", + "Sports.bowlingBallAndPins": "boule de quilles et quilles", + "Sports.boxingGloves": "gants de boxe", + "Sports.character": "la voiturette de golf", "Sports.cricketBatAndBall": "batte et balle de cricket", "Sports.curlingStone": "pierre à friser", - "Sports.fieldHockeyStickAndBall": "bâton et balle pour hockey sur gazon", + "Sports.fieldHockeyStickAndBall": "bâton et balle de hockey sur gazon", "Sports.football": "football", "Sports.golfBall": "balle de golf", "Sports.hockeyStickAndPuck": "bâton de hockey et rondelle", - "Sports.iceSkates": "patins de glace", - "Sports.label": "Une scène de sports avec 23 différentes pièces d'équipement sportif propagé sur la scène. Votre personnage est un voiture de golf.", - "Sports.martialArtsUniform": "uniforme arts martiaux", - "Sports.rowingBoat": "canot à rames", - "Sports.runningShoes": "chaussures de cours", - "Sports.singlet": "maillot", - "Sports.skisAndSkiPoles": "skis et bâtons de skis", + "Sports.iceSkates": "patins à glace", + "Sports.label": "Une scène sportive avec 23 équipements sportifs différents répartis sur la scène. Votre personnage est une voiturette de golf.", + "Sports.martialArtsUniform": "uniforme d'arts martiaux", + "Sports.rowingBoat": "bateau à rames", + "Sports.runningShoes": "chaussures de course", + "Sports.singlet": "chandail", + "Sports.skisAndSkiPoles": "skis et bâtons de ski", "Sports.soccerBall": "ballon de soccer", - "Sports.swimmingGoggles": "lunettes de plongée", - "Sports.tableTennisRacket": "raquette de tennis de table", + "Sports.swimmingGoggles": "lunettes de natation", + "Sports.tableTennisRacket": "raquette de ping-pong", "Sports.tennisRacketAndBall": "raquette et balle de tennis", "Sports.volleyballBall": "ballon de volleyball", - "StopButton": "arrête", - "ThemeSelector.iconButton": "sélecteur du thème", + "StopButton": "Arrêt", + "ThemeSelector.iconButton": "Sélecteur de thème", "TileDescription.black": "noire", "TileDescription.brown": "brun", - "TileDescription.darkBlue": "bleu foncer", - "TileDescription.gem": "gem", - "TileDescription.gold": "gold", + "TileDescription.darkBlue": "bleu foncé", + "TileDescription.gem": "gemme", + "TileDescription.gold": "or", "TileDescription.green": "vert", "TileDescription.grey": "gris", - "TileDescription.lightBlue": "bleu claire", - "TileDescription.none": "gomme de fond personnalisée", + "TileDescription.lightBlue": "bleu pâle", + "TileDescription.none": "gomme d'arrière-plan personnalisée", "TileDescription.orange": "orange", "TileDescription.pink": "rose", - "TileDescription.purple": "violet", + "TileDescription.purple": "pourpre", "TileDescription.red": "rouge", "TileDescription.treats": "friandises", "TileDescription.wall": "mur", "TileDescription.white": "blanc", "TileDescription.yellow": "jaune", - "TilePanel.heading": "Conception de fond personnalisée", - "UI.ActionsMenu.title": "action", - "UI.ActionsMenuItem.command.backward1": "reculer d'un pas", - "UI.ActionsMenuItem.command.forward1": "avancer d'une pas", - "UI.ActionsMenuItem.command.left45": "tourner à gauche de 45 degrées", - "UI.ActionsMenuItem.command.left90": "tourner à gauche de 90 degréees", - "UI.ActionsMenuItem.command.loop": "boucle", - "UI.ActionsMenuItem.command.right45": "tourner à droite 45 degrées", - "UI.ActionsMenuItem.command.right90": "tourner à droite 90 degrées", + "TilePanel.heading": "Conception d'arrière-plan personnalisée", + "UI.ActionsMenu.title": "Actions", + "UI.ActionsMenuItem.command.backward1": "Reculer d'un pas", + "UI.ActionsMenuItem.command.forward1": "Avancer d'un pas", + "UI.ActionsMenuItem.command.left45": "Tourner à gauche à 45 degrés", + "UI.ActionsMenuItem.command.left90": "Tourner à gauche à 90 degrés", + "UI.ActionsMenuItem.command.loop": "Boucle", + "UI.ActionsMenuItem.command.right45": "Tourner à droite à 45 degrées", + "UI.ActionsMenuItem.command.right90": "Tourner à droite à 90 degrées", "UI.ActionsMenuItem.usedItemToggleLabel": "(utilisé)", - "UI.ActionsSimplificationModal.title": "actions disponibles", - "UI.AmusementPark.name": "parc d'attractions", - "UI.App.privacyModalToggle": "intimité", - "UI.AtlanticCanada.name": "atlantique Canada", - "UI.Camping.name": "voyage de camping", + "UI.ActionsSimplificationModal.title": "Actions disponibles", + "UI.AmusementPark.name": "Parc d'attractions", + "UI.App.privacyModalToggle": "Confidentialité", + "UI.AtlanticCanada.name": "Canada atlantique", + "UI.Camping.name": "Voyage de camping", "UI.Cancel": "Annuler", - "UI.CharacterMessageBuilder.endOfScene": "Votre personnage à atteint la fin de la scène", - "UI.CharacterMessageBuilder.hitWall": "ton personnage a heurté un mur {columnLabel} {rowLabel}", - "UI.Close": "fermer", - "UI.CommandPalette.controlsTitle": "contrôles", + "UI.CharacterMessageBuilder.endOfScene": "Votre personnage a atteint la fin de la scène", + "UI.CharacterMessageBuilder.hitWall": "Votre personnage a frappé un mur sur {columnLabel}{rowLabel}", + "UI.Close": "Fermer", + "UI.CommandPalette.controlsTitle": "Contrôles", "UI.CommandPalette.movementsTitle": "Mouvements", - "UI.ConfirmDeleteAllModal.confirmButton": "supprimer", - "UI.ConfirmDeleteAllModal.content": "êtes-vous sûr de voulair suprimer tous les étapes de ton programme?", - "UI.ConfirmDeleteAllModal.title": "supprimer le programme", + "UI.ConfirmDeleteAllModal.confirmButton": "Supprimer", + "UI.ConfirmDeleteAllModal.content": "Êtes-vous certain de vouloir supprimer toutes les étapes de votre programme ?", + "UI.ConfirmDeleteAllModal.title": "Supprimer le programme", "UI.DeepOcean.name": "Océan profond", "UI.EuropeTrip.name": "Voyage en Europe", "UI.GroceryStore.name": "Épicerie", - "UI.Haunted.name": "une maison hauntée", - "UI.KeyboardInputModal.Description.addCommandToBeginning": "appuyer sur la {keyboardShortcut} pour ajouter la commande sélectionnée au début du programme", - "UI.KeyboardInputModal.Description.addCommandToEnd": "appuyer sur la {keyboardShortcut} pour ajouter la commande sélectionnée à la fin du programme", - "UI.KeyboardInputModal.Description.announceScene": "appuyer sur la {keyboardShortcut} pour annoncer la position du charactère et l'orientation", - "UI.KeyboardInputModal.Description.decreaseProgramSpeed": "appuyer sur la {keyboardShortcut} pour ralentir la lecture du programme", - "UI.KeyboardInputModal.Description.deleteCurrentStep": "appuyer sur la {keyboardShortcut} pour surpimer l'étape actuellement ciblée", - "UI.KeyboardInputModal.Description.increaseProgramSpeed": "appuyer sur la {keyboardShortcut} pour accélérer la lecture du programme", - "UI.KeyboardInputModal.Description.playPauseProgram": "appuyer sur la {keyboardShortcut} pour lire ou mettre en pause le programme", - "UI.KeyboardInputModal.Description.refreshScene": "appuyer sur la {keyboardShortcut} pour réfraîchir la scène", - "UI.KeyboardInputModal.Description.showHide": "appuyer sur la {keyboardShortcut} pour voir le menu racourci de l'ordinateur", - "UI.KeyboardInputModal.Description.stopProgram": "appuyer sur la {keyboardShortcut} pour arrêter le programme", - "UI.KeyboardInputModal.Description.toggleAnnouncements": "appuyer sur la {keyboardShortcut} pour basculer les annonces", + "UI.Haunted.name": "Maison hantée", + "UI.KeyboardInputModal.Description.addCommandToBeginning": "Appuyez sur {keyboardShortcut} pour ajouter la commande sélectionnée au début du programme.", + "UI.KeyboardInputModal.Description.addCommandToEnd": "Appuyez sur {keyboardShortcut} pour ajouter la commande sélectionnée à la fin du programme.", + "UI.KeyboardInputModal.Description.announceScene": "Appuyez sur {keyboardShortcut} pour annoncer la position et l'orientation du caractère.", + "UI.KeyboardInputModal.Description.decreaseProgramSpeed": "Appuyez sur {keyboardShortcut} pour ralentir la lecture du programme.", + "UI.KeyboardInputModal.Description.deleteCurrentStep": "Appuyez sur {keyboardShortcut} pour supprimer l'étape actuellement ciblée.", + "UI.KeyboardInputModal.Description.increaseProgramSpeed": "Appuyez sur {keyboardShortcut} pour accélérer la lecture du programme.", + "UI.KeyboardInputModal.Description.playPauseProgram": "Appuyez sur {keyboardShortcut} pour lire ou mettre en pause le programme.", + "UI.KeyboardInputModal.Description.refreshScene": "Appuyez sur {keyboardShortcut} pour rafraîchir la scène.", + "UI.KeyboardInputModal.Description.showHide": "Appuyez sur {keyboardShortcut} pour afficher le menu des raccourcis clavier.", + "UI.KeyboardInputModal.Description.stopProgram": "Appuyez sur {keyboardShortcut} pour arrêter le programme.", + "UI.KeyboardInputModal.Description.toggleAnnouncements": "Appuyez sur {keyboardShortcut} pour basculer entre les annonces.", "UI.KeyboardInputModal.KeyIcons.A": "A", "UI.KeyboardInputModal.KeyIcons.Alt": "alt", "UI.KeyboardInputModal.KeyIcons.B": "B", @@ -976,7 +975,7 @@ "UI.KeyboardInputModal.KeyLabels.A": "a", "UI.KeyboardInputModal.KeyLabels.Alt": "alt", "UI.KeyboardInputModal.KeyLabels.B": "b", - "UI.KeyboardInputModal.KeyLabels.Control": "contôle", + "UI.KeyboardInputModal.KeyLabels.Control": "contrôle", "UI.KeyboardInputModal.KeyLabels.D": "d", "UI.KeyboardInputModal.KeyLabels.E": "e", "UI.KeyboardInputModal.KeyLabels.GreaterThan": "plus grand que", @@ -986,39 +985,70 @@ "UI.KeyboardInputModal.KeyLabels.QuestionMark": "point d'interrogation", "UI.KeyboardInputModal.KeyLabels.R": "r", "UI.KeyboardInputModal.KeyLabels.S": "s", - "UI.KeyboardInputModal.Scheme.Descriptions.alt": "alt (apple: option)", - "UI.KeyboardInputModal.Scheme.Descriptions.controlalt": "contrôle+alt (apple: contrôle+option)", + "UI.KeyboardInputModal.Scheme.Descriptions.alt": "alt (Apple: option)", + "UI.KeyboardInputModal.Scheme.Descriptions.controlalt": "contrôle+alt (Apple: contrôle+option)", "UI.KeyboardInputModal.Title": "raccourcis clavier", - "UI.Landmarks.name": "Repères", - "UI.Marble.name": "course de billes", + "UI.Landmarks.name": "Points de repère", + "UI.Marble.name": "Course de billes", "UI.MusicBand.name": "Groupe de musique", "UI.Off": "étient", - "UI.On": "Sur", - "UI.PrivacyModal.title": "Weavly politique de confidentialité", + "UI.On": "allumé", + "UI.PrivacyModal.contactUs": "Contactez-nous", + "UI.PrivacyModal.section010.Heading": "Mis à jour le 4 janvier 2024", + "UI.PrivacyModal.section010.block010": "Chez Weavly, nous croyons que la vie privée est un droit humain fondamental et reconnaissons son importance pour notre communauté, en particulier en ce qui concerne les enfants et les parents.", + "UI.PrivacyModal.section010.block020": "Cette page explique :", + "UI.PrivacyModal.section010.block030.item010": "Quel type d'informations nous stockons sur notre site Web (http://create.weavly.org/)", + "UI.PrivacyModal.section010.block030.item020": "Comment ces renseignements sont utilisés et traités", + "UI.PrivacyModal.section010.block030.item030": "Comment nous protégeons vos renseignements", + "UI.PrivacyModal.section020.Heading": "Quelles informations Weavly stocke-t-il ?", + "UI.PrivacyModal.section020.block010": "Lorsque vous utilisez Weavly, nous pouvons stocker des informations sur la façon dont vous accédez et utilisez Weavly. Nous stockons les informations suivantes indépendamment sur chaque paire navigateur/appareil sur lequel vous utilisez Weavly :", + "UI.PrivacyModal.section020.block020.item010": "Vos réglages préférés pour le thème de couleur d'affichage et les raccourcis clavier", + "UI.PrivacyModal.section020.block020.item020": "Your visible set of action blocks on the action panel", + "UI.PrivacyModal.section020.block020.item030": "Votre arrière-plan sélectionné pour la scène", + "UI.PrivacyModal.section020.block020.item040": "Votre programme créé", + "UI.PrivacyModal.section020.block020.item050": "Toute ligne tracée sur la scène suite à l'exécution de votre programme", + "UI.PrivacyModal.section020.block020.item060": "La dernière position de ton personnage sur la scène", + "UI.PrivacyModal.section020.block020.item070": "La position de départ de votre personnage", + "UI.PrivacyModal.section020.block020.item080": "La version de Weavly utilisée", + "UI.PrivacyModal.section020.block030": "Vous pouvez supprimer toutes les informations générées par Weavly à partir de votre utilisation en effaçant le cache et le stockage local de votre navigateur. Consultez la documentation de votre navigateur pour plus de détails.", + "UI.PrivacyModal.section030.Heading": "Comment Weavly utilise-t-il ces renseignements ?", + "UI.PrivacyModal.section030.block010": "Les informations générées sont conservées dans un stockage local sur votre appareil pour rendre votre utilisation de Weavly plus pratique :", + "UI.PrivacyModal.section030.block020.item010": "Vos paramètres pour l'environnement de codage sont stockés afin que vous n'ayez pas à les ajuster à chaque fois que vous lancez Weavly", + "UI.PrivacyModal.section030.block020.item020": "Si vous fermez accidentellement ou intentionnellement votre navigateur, l'environnement de codage sera le même que lorsque vous l'avez quitté la prochaine fois que vous lancerez Weavly", + "UI.PrivacyModal.section030.block030": "Bien que le stockage de vos informations dans le navigateur soit pratique chaque fois que vous accédez à Weavly, cela peut entraîner des problèmes sur les ordinateurs partagés. Par conséquent, quelqu'un qui utilise l'ordinateur après vous pourra peut-être accéder à vos paramètres et à votre programme Weavly.", + "UI.PrivacyModal.section040.Heading": "Comment protégeons-nous vos renseignements ?", + "UI.PrivacyModal.section040.block010": "La sécurité de vos données est importante pour nous, mais n'oubliez pas qu'aucune méthode de stockage électronique n'est sécurisée à 100 %. Nous utilisons actuellement le stockage local du navigateur pour stocker les données spécifiées. Les informations sont stockées dans le navigateur par domaine (create.weavly.org) et seul le code exécuté à partir de ce domaine peut y accéder. Ainsi, d’autres sites Web ne peuvent pas accéder aux données. Cependant, le stockage local n'est pas chiffré sur le disque et toute personne ayant accès à l'appareil peut accéder aux données.", + "UI.PrivacyModal.section050.Heading": "Confidentialité des enfants", + "UI.PrivacyModal.section050.block010": "Nous ne recueillons pas sciemment de renseignements personnels identifiables auprès d'une personne de moins de 18 ans. on peut prendre des mesures pour supprimer ces informations. S'il vous plaît {contactLink}", + "UI.PrivacyModal.section060.Heading": "Modifications à cette politique de confidentialité", + "UI.PrivacyModal.section060.block010": "Nous pouvons mettre à jour notre politique de confidentialité de temps à autre. Nous vous aviserons de tout changement en publiant la nouvelle politique de confidentialité sur cette page. Nous vous aviserons de tout changement entrant en vigueur en mettant à jour la « date d’entrée en vigueur » en haut de la présente politique de confidentialité. Il vous est recommandé de consulter périodiquement cette politique de confidentialité pour tout changement. Les modifications apportées à cette politique de confidentialité entrent en vigueur dès leur publication sur cette page.", + "UI.PrivacyModal.section070.Heading": "Contactez-nous", + "UI.PrivacyModal.section070.block010": "Si vous avez des questions sur cette politique de confidentialité, veuillez {contactLink}.", + "UI.PrivacyModal.title": "Politique de confidentialité de Weavly ", "UI.ProgramBlockEditor.programHeading": "programme", "UI.Savannah.name": "Savane", - "UI.Save": "Sauvegarder", - "UI.ShareButton": "partager", - "UI.ShareModal.copy": "copier le lien", - "UI.ShareModal.description1": "un lien vers le programme que vous avez créer à été copié dans le presse-papier", - "UI.ShareModal.description2": "vous pouvez également copier le lien ci-dessous et le partager avec qui vous voulez", - "UI.ShareModal.title": "lien de partage", - "UI.Sketchpad.name": "un croquis", - "UI.SoundOptionsModal.allSounds": "tout les sons", - "UI.SoundOptionsModal.announcements": "annonces audio", - "UI.SoundOptionsModal.musicalSounds": "sons musicaux", - "UI.SoundOptionsModal.title": "options sonores", + "UI.Save": "Enregistrer", + "UI.ShareButton": "Partager", + "UI.ShareModal.copy": "Copier le lien", + "UI.ShareModal.description1": "Un lien vers le programme que vous avez créé a été copié dans le presse-papiers.", + "UI.ShareModal.description2": "Vous pouvez aussi copier le lien ci-dessous pour le partager avec qui vous voulez.", + "UI.ShareModal.title": "Partager le lien", + "UI.Sketchpad.name": "Carnet de croquis", + "UI.SoundOptionsModal.allSounds": "Tous les sons", + "UI.SoundOptionsModal.announcements": "Annonces audio", + "UI.SoundOptionsModal.musicalSounds": "Sons musicaux", + "UI.SoundOptionsModal.title": "Options sonores", "UI.Space.name": "Espace", - "UI.Sports.name": "sports", - "UI.ThemeSelector.option.contrast": "contraste élèvé", - "UI.ThemeSelector.option.dark": "sombre", - "UI.ThemeSelector.option.default": "défaut", - "UI.ThemeSelector.option.gray": "niveaux de gris", - "UI.ThemeSelector.option.light": "clair", - "UI.ThemeSelector.title": "thèmes", - "UI.WorldSelector.Prompt": "selectionner une arrière plan pour votre scène", - "UI.WorldSelector.Title": "fond de scène", - "WorldSelectorButton.heading": "Sélecteur de fond de scène", - "WorldSelectorButton.label": "Sélecteur de fond de scène" + "UI.Sports.name": "Sports", + "UI.ThemeSelector.option.contrast": "Contraste élevé", + "UI.ThemeSelector.option.dark": "Sombre", + "UI.ThemeSelector.option.default": "Défaut", + "UI.ThemeSelector.option.gray": "Niveaux de gris", + "UI.ThemeSelector.option.light": "Clair", + "UI.ThemeSelector.title": "Thèmes", + "UI.WorldSelector.Prompt": "Choisissez un arrière-plan pour votre scène.", + "UI.WorldSelector.Title": "Arrière-plan de scène", + "WorldSelectorButton.heading": "Sélecteur d'arrière-plan de scène", + "WorldSelectorButton.label": "Sélecteur d'arrière-plan de scène" } -} +} \ No newline at end of file From 72b37a5e701083cf28d8796cca9d8d20032caa8b Mon Sep 17 00:00:00 2001 From: Simon Bates Date: Mon, 24 Mar 2025 14:51:08 -0400 Subject: [PATCH 23/23] Sort messages --- src/messages.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/messages.json b/src/messages.json index cf25c36b..ef764586 100644 --- a/src/messages.json +++ b/src/messages.json @@ -138,14 +138,6 @@ "DeviceConnectControl.connected": "Connected", "DeviceConnectControl.connecting": "Connecting", "DeviceConnectControl.notConnected": "Not connected", - "FacingDirection.0": "facing up", - "FacingDirection.1": "facing upper right", - "FacingDirection.2": "facing right", - "FacingDirection.3": "facing lower right", - "FacingDirection.4": "facing down", - "FacingDirection.5": "facing lower left", - "FacingDirection.6": "facing left", - "FacingDirection.7": "facing upper left", "EuropeTrip.B6": "the Tower of Saint Vincent on Portugal", "EuropeTrip.B7": "Portugal", "EuropeTrip.C1": "Iceland", @@ -216,6 +208,14 @@ "EuropeTrip.L8": "olives on Cyprus; also in this square Türkiye", "EuropeTrip.character": "the airplane", "EuropeTrip.label": "A Europe trip scene containing a map of Europe with tourist attractions. Iceland is located near the top left of the scene. Cyprus is located at the bottom right of the scene. Tourist attractions are located on the country known for the attraction, such as the violin on Austria near the centre of the scene. Your character in this scene is an airplane.", + "FacingDirection.0": "facing up", + "FacingDirection.1": "facing upper right", + "FacingDirection.2": "facing right", + "FacingDirection.3": "facing lower right", + "FacingDirection.4": "facing down", + "FacingDirection.5": "facing lower left", + "FacingDirection.6": "facing left", + "FacingDirection.7": "facing upper left", "GroceryStore.apples": "apples", "GroceryStore.bagOfRice": "bag of rice", "GroceryStore.bananas": "bananas", @@ -664,14 +664,6 @@ "DeviceConnectControl.connected": "Connecté", "DeviceConnectControl.connecting": "Connexion en cours", "DeviceConnectControl.notConnected": "Pas connecté", - "FacingDirection.0": "face vers le haut", - "FacingDirection.1": "en haut à droite", - "FacingDirection.2": "face à droite", - "FacingDirection.3": "en bas à droite", - "FacingDirection.4": "face vers le bas", - "FacingDirection.5": "en bas à gauche", - "FacingDirection.6": "face à gauche", - "FacingDirection.7": "en haut à gauche", "EuropeTrip.B6": "la Tour de Saint Vincent au Portugal", "EuropeTrip.B7": "Portugal", "EuropeTrip.C1": "Islande", @@ -742,6 +734,14 @@ "EuropeTrip.L8": "olives à Chypre; aussi sur cette place Türkiye", "EuropeTrip.character": "l'avion", "EuropeTrip.label": "Une scène de voyage en Europe contenant une carte de l'Europe avec des attractions touristiques. L'Islande est située en haut à gauche de la scène. Chypre est située en bas à droite de la scène. Les attractions touristiques sont situées dans le pays connu pour l'attraction, comme le violon en Autriche, près du centre de la scène. Ton personnage dans cette scène est un avion.", + "FacingDirection.0": "face vers le haut", + "FacingDirection.1": "en haut à droite", + "FacingDirection.2": "face à droite", + "FacingDirection.3": "en bas à droite", + "FacingDirection.4": "face vers le bas", + "FacingDirection.5": "en bas à gauche", + "FacingDirection.6": "face à gauche", + "FacingDirection.7": "en haut à gauche", "GroceryStore.apples": "pommes", "GroceryStore.bagOfRice": "sac de riz", "GroceryStore.bananas": "bananes",