UNPKG

parse-sb3-blocks

Version:

Parse sb3 blocks, and generate scratchblocks formatted code.

1 lines 2.55 MB
{"version":3,"file":"parse-sb3-blocks.cjs","sources":["../src/block-mapping/all-blocks.js","../src/block-mapping/block-enum.js","../src/block-mapping/translations.js","../src/block-mapping/options.js","../src/block-mapping/special-messages.js","../src/sanitizer.js","../src/block-mapping/block-mapping.js","../src/block-type/block.js","../src/block-type/boolean-block.js","../src/block-type/c-block.js","../src/block-type/e-block.js","../src/block-type/reporter-block.js","../src/block-type/variable.js","../src/block-type/definition.js","../src/block-type/procedure-call.js","../src/input/icon.js","../src/input/menu.js","../src/input/input.js","../src/input/stack.js","../src/parser/parse.js","../src/parser/to-scratchblocks.js"],"sourcesContent":["import { BOOLEAN_BLOCK, C_BLOCK, E_BLOCK, REPORTER_BLOCK } from './block-enum.js';\n\nexport default {\n motion_movesteps: {\n defaultMessage: 'move {STEPS} steps',\n },\n motion_turnright: {\n defaultMessage: 'turn {ICON} {DEGREES} degrees',\n },\n motion_turnleft: {\n defaultMessage: 'turn {ICON} {DEGREES} degrees',\n },\n motion_pointindirection: {\n defaultMessage: 'point in direction {DIRECTION}',\n },\n motion_pointtowards: {\n defaultMessage: 'point towards {TOWARDS}',\n },\n motion_gotoxy: {\n defaultMessage: 'go to x:{X} y:{Y}',\n },\n motion_goto: {\n defaultMessage: 'go to {TO}',\n },\n motion_glidesecstoxy: {\n defaultMessage: 'glide {SECS} secs to x:{X} y:{Y}',\n },\n motion_glideto: {\n defaultMessage: 'glide {SECS} secs to {TO}',\n },\n motion_changexby: {\n defaultMessage: 'change x by {DX}',\n },\n motion_setx: {\n defaultMessage: 'set x to {X}',\n },\n motion_changeyby: {\n defaultMessage: 'change y by {DY}',\n },\n motion_sety: {\n defaultMessage: 'set y to {Y}',\n },\n motion_ifonedgebounce: {\n defaultMessage: 'if on edge, bounce',\n },\n motion_setrotationstyle: {\n defaultMessage: 'set rotation style {STYLE}',\n },\n motion_xposition: {\n defaultMessage: 'x position',\n type: REPORTER_BLOCK,\n },\n motion_yposition: {\n defaultMessage: 'y position',\n type: REPORTER_BLOCK,\n },\n motion_direction: {\n defaultMessage: 'direction',\n type: REPORTER_BLOCK,\n },\n looks_sayforsecs: {\n defaultMessage: 'say {MESSAGE} for {SECS} seconds',\n },\n looks_say: {\n defaultMessage: 'say {MESSAGE}',\n },\n looks_thinkforsecs: {\n defaultMessage: 'think {MESSAGE} for {SECS} seconds',\n },\n looks_think: {\n defaultMessage: 'think {MESSAGE}',\n },\n looks_show: {\n defaultMessage: 'show',\n },\n looks_hide: {\n defaultMessage: 'hide',\n },\n looks_changeeffectby: {\n defaultMessage: 'change {EFFECT} effect by {CHANGE}',\n defaultOptions: {\n category: 'looks',\n },\n },\n looks_seteffectto: {\n defaultMessage: 'set {EFFECT} effect to {VALUE}',\n defaultOptions: {\n category: 'looks',\n },\n },\n looks_cleargraphiceffects: {\n defaultMessage: 'clear graphic effects',\n },\n looks_changesizeby: {\n defaultMessage: 'change size by {CHANGE}',\n },\n looks_setsizeto: {\n defaultMessage: 'set size to {SIZE} %',\n },\n looks_size: {\n defaultMessage: 'size',\n type: REPORTER_BLOCK,\n },\n looks_switchcostumeto: {\n defaultMessage: 'switch costume to {COSTUME}',\n },\n looks_nextcostume: {\n defaultMessage: 'next costume',\n },\n looks_switchbackdropto: {\n defaultMessage: 'switch backdrop to {BACKDROP}',\n },\n looks_gotofrontback: {\n defaultMessage: 'go to {FRONT_BACK} layer',\n },\n looks_goforwardbackwardlayers: {\n defaultMessage: 'go {FORWARD_BACKWARD} {NUM} layers',\n },\n looks_backdropnumbername: {\n defaultMessage: 'backdrop {NUMBER_NAME}',\n type: REPORTER_BLOCK,\n },\n looks_costumenumbername: {\n defaultMessage: 'costume {NUMBER_NAME}',\n type: REPORTER_BLOCK,\n },\n looks_switchbackdroptoandwait: {\n defaultMessage: 'switch backdrop to {BACKDROP} and wait',\n },\n looks_nextbackdrop: {\n defaultMessage: 'next backdrop',\n translationKey: 'LOOKS_NEXTBACKDROP_BLOCK',\n },\n sound_play: {\n defaultMessage: 'start sound {SOUND_MENU}',\n },\n sound_playuntildone: {\n defaultMessage: 'play sound {SOUND_MENU} until done',\n },\n sound_stopallsounds: {\n defaultMessage: 'stop all sounds',\n },\n sound_seteffectto: {\n defaultMessage: 'set {EFFECT} effect to {VALUE}',\n translationKey: 'SOUND_SETEFFECTO', // typo in scratch-blocks\n defaultOptions: {\n category: 'sound',\n },\n },\n sound_changeeffectby: {\n defaultMessage: 'change {EFFECT} effect by {VALUE}',\n defaultOptions: {\n category: 'sound',\n },\n },\n sound_cleareffects: {\n defaultMessage: 'clear sound effects',\n },\n sound_changevolumeby: {\n defaultMessage: 'change volume by {VOLUME}',\n },\n sound_setvolumeto: {\n defaultMessage: 'set volume to {VOLUME} %',\n },\n sound_volume: {\n defaultMessage: 'volume',\n type: REPORTER_BLOCK,\n },\n event_whenflagclicked: {\n defaultMessage: 'when {ICON} clicked',\n },\n event_whenthisspriteclicked: {\n defaultMessage: 'when this sprite clicked',\n },\n event_whenstageclicked: {\n defaultMessage: 'when stage clicked',\n },\n event_whenbroadcastreceived: {\n defaultMessage: 'when I receive {BROADCAST_OPTION}',\n },\n event_whenbackdropswitchesto: {\n defaultMessage: 'when backdrop switches to {BACKDROP}',\n },\n event_whengreaterthan: {\n defaultMessage: 'when {WHENGREATERTHANMENU} > {VALUE}',\n },\n event_broadcast: {\n defaultMessage: 'broadcast {BROADCAST_INPUT}',\n },\n event_broadcastandwait: {\n defaultMessage: 'broadcast {BROADCAST_INPUT} and wait',\n },\n event_whenkeypressed: {\n defaultMessage: 'when {KEY_OPTION} key pressed',\n defaultOptions: {\n category: 'events',\n },\n },\n control_forever: {\n defaultMessage: 'forever',\n type: C_BLOCK,\n },\n control_repeat: {\n defaultMessage: 'repeat {TIMES}',\n type: C_BLOCK,\n },\n control_if: {\n defaultMessage: 'if {CONDITION} then',\n type: C_BLOCK,\n boolArg: ['CONDITION'],\n },\n control_if_else: {\n defaultMessage: 'if {CONDITION} then',\n translationKey: 'CONTROL_IF',\n type: E_BLOCK,\n boolArg: ['CONDITION'],\n },\n control_else: {\n defaultMessage: 'else',\n },\n control_stop: {\n defaultMessage: 'stop {STOP_OPTION}',\n },\n control_wait: {\n defaultMessage: 'wait for {DURATION} seconds',\n },\n control_wait_until: {\n defaultMessage: 'wait until {CONDITION}',\n translationKey: 'CONTROL_WAITUNTIL',\n boolArg: ['CONDITION'],\n },\n control_repeat_until: {\n defaultMessage: 'repeat until {CONDITION}',\n translationKey: 'CONTROL_REPEATUNTIL',\n type: C_BLOCK,\n boolArg: ['CONDITION'],\n },\n control_start_as_clone: {\n defaultMessage: 'when I start as a clone',\n translationKey: 'CONTROL_STARTASCLONE',\n },\n control_create_clone_of: {\n defaultMessage: 'create clone of {CLONE_OPTION}',\n translationKey: 'CONTROL_CREATECLONEOF',\n },\n control_delete_this_clone: {\n defaultMessage: 'delete this clone',\n translationKey: 'CONTROL_DELETETHISCLONE',\n },\n sensing_touchingobject: {\n defaultMessage: 'touching {TOUCHINGOBJECTMENU} ?',\n type: BOOLEAN_BLOCK,\n },\n sensing_touchingcolor: {\n defaultMessage: 'touching color {COLOR} ?',\n type: BOOLEAN_BLOCK,\n },\n sensing_coloristouchingcolor: {\n defaultMessage: 'color {COLOR} is touching {COLOR2} ?',\n type: BOOLEAN_BLOCK,\n },\n sensing_distanceto: {\n defaultMessage: 'distance to {DISTANCETOMENU}',\n type: REPORTER_BLOCK,\n },\n sensing_askandwait: {\n defaultMessage: 'ask {QUESTION} and wait',\n },\n sensing_answer: {\n defaultMessage: 'answer',\n type: REPORTER_BLOCK,\n },\n sensing_keypressed: {\n defaultMessage: 'key {KEY_OPTION} pressed?',\n type: BOOLEAN_BLOCK,\n },\n sensing_mousedown: {\n defaultMessage: 'mouse down?',\n type: BOOLEAN_BLOCK,\n },\n sensing_mousex: {\n defaultMessage: 'mouse x',\n type: REPORTER_BLOCK,\n },\n sensing_mousey: {\n defaultMessage: 'mouse y',\n type: REPORTER_BLOCK,\n },\n sensing_setdragmode: {\n defaultMessage: 'set drag mode {DRAG_MODE}',\n },\n sensing_loudness: {\n defaultMessage: 'loudness',\n type: REPORTER_BLOCK,\n },\n sensing_timer: {\n defaultMessage: 'timer',\n type: REPORTER_BLOCK,\n },\n sensing_resettimer: {\n defaultMessage: 'reset timer',\n },\n sensing_of: {\n defaultMessage: '{PROPERTY} of {OBJECT}',\n type: REPORTER_BLOCK,\n },\n sensing_current: {\n defaultMessage: 'current {CURRENTMENU}',\n type: REPORTER_BLOCK,\n },\n sensing_dayssince2000: {\n defaultMessage: 'days since 2000',\n type: REPORTER_BLOCK,\n },\n sensing_username: {\n defaultMessage: 'username',\n type: REPORTER_BLOCK,\n },\n operator_add: {\n defaultMessage: '{NUM1} + {NUM2}',\n translationKey: 'OPERATORS_ADD',\n type: REPORTER_BLOCK,\n },\n operator_subtract: {\n defaultMessage: '{NUM1} - {NUM2}',\n translationKey: 'OPERATORS_SUBTRACT',\n type: REPORTER_BLOCK,\n },\n operator_multiply: {\n defaultMessage: '{NUM1} * {NUM2}',\n translationKey: 'OPERATORS_MULTIPLY',\n type: REPORTER_BLOCK,\n },\n operator_divide: {\n defaultMessage: '{NUM1} / {NUM2}',\n translationKey: 'OPERATORS_DIVIDE',\n type: REPORTER_BLOCK,\n },\n operator_random: {\n defaultMessage: 'pick random {FROM} to {TO}',\n translationKey: 'OPERATORS_RANDOM',\n type: REPORTER_BLOCK,\n },\n operator_lt: {\n defaultMessage: '{OPERAND1} < {OPERAND2}',\n translationKey: 'OPERATORS_LT',\n type: BOOLEAN_BLOCK,\n },\n operator_equals: {\n defaultMessage: '{OPERAND1} = {OPERAND2}',\n translationKey: 'OPERATORS_EQUALS',\n type: BOOLEAN_BLOCK,\n },\n operator_gt: {\n defaultMessage: '{OPERAND1} > {OPERAND2}',\n translationKey: 'OPERATORS_GT',\n type: BOOLEAN_BLOCK,\n },\n operator_and: {\n defaultMessage: '{OPERAND1} and {OPERAND2}',\n translationKey: 'OPERATORS_AND',\n type: BOOLEAN_BLOCK,\n boolArg: ['OPERAND1', 'OPERAND2'],\n },\n operator_or: {\n defaultMessage: '{OPERAND1} or {OPERAND2}',\n translationKey: 'OPERATORS_OR',\n type: BOOLEAN_BLOCK,\n boolArg: ['OPERAND1', 'OPERAND2'],\n },\n operator_not: {\n defaultMessage: 'not {OPERAND}',\n translationKey: 'OPERATORS_NOT',\n type: BOOLEAN_BLOCK,\n boolArg: ['OPERAND'],\n },\n operator_join: {\n defaultMessage: 'join {STRING1} {STRING2}',\n translationKey: 'OPERATORS_JOIN',\n type: REPORTER_BLOCK,\n },\n operator_letter_of: {\n defaultMessage: 'letter {LETTER} of {STRING}',\n translationKey: 'OPERATORS_LETTEROF',\n type: REPORTER_BLOCK,\n },\n operator_length: {\n defaultMessage: 'length of {STRING}',\n translationKey: 'OPERATORS_LENGTH',\n type: REPORTER_BLOCK,\n },\n operator_contains: {\n defaultMessage: '{STRING1} contains {STRING2} ?',\n translationKey: 'OPERATORS_CONTAINS',\n type: BOOLEAN_BLOCK,\n },\n operator_mod: {\n defaultMessage: '{NUM1} mod {NUM2}',\n translationKey: 'OPERATORS_MOD',\n type: REPORTER_BLOCK,\n },\n operator_round: {\n defaultMessage: 'round {NUM}',\n translationKey: 'OPERATORS_ROUND',\n type: REPORTER_BLOCK,\n },\n operator_mathop: {\n defaultMessage: '{OPERATOR} of {NUM}',\n translationKey: 'OPERATORS_MATHOP',\n type: REPORTER_BLOCK,\n },\n data_variable: {\n noTranslation: true,\n },\n data_setvariableto: {\n defaultMessage: 'set {VARIABLE} to {VALUE}',\n },\n data_changevariableby: {\n defaultMessage: 'change {VARIABLE} by {VALUE}',\n },\n data_showvariable: {\n defaultMessage: 'show variable {VARIABLE}',\n },\n data_hidevariable: {\n defaultMessage: 'hide variable {VARIABLE}',\n },\n data_listcontents: {\n noTranslation: true,\n },\n data_addtolist: {\n defaultMessage: 'add {ITEM} to {LIST}',\n },\n data_deleteoflist: {\n defaultMessage: 'delete {INDEX} of {LIST}',\n },\n data_deletealloflist: {\n defaultMessage: 'delete all of {LIST}',\n },\n data_insertatlist: {\n defaultMessage: 'insert {ITEM} at {INDEX} of {LIST}',\n },\n data_replaceitemoflist: {\n defaultMessage: 'replace item {INDEX} of {LIST} with {ITEM}',\n },\n data_itemoflist: {\n defaultMessage: 'item {INDEX} of {LIST}',\n type: REPORTER_BLOCK,\n },\n data_itemnumoflist: {\n defaultMessage: 'item # of {ITEM} in {LIST}',\n type: REPORTER_BLOCK,\n },\n data_lengthoflist: {\n defaultMessage: 'length of {LIST}',\n type: REPORTER_BLOCK,\n },\n data_listcontainsitem: {\n defaultMessage: '{LIST} contains {ITEM} ?',\n type: BOOLEAN_BLOCK,\n },\n data_showlist: {\n defaultMessage: 'show list {LIST}',\n },\n data_hidelist: {\n defaultMessage: 'hide list {LIST}',\n },\n procedures_definition: {\n defaultMessage: 'define {PROC}',\n },\n procedures_call: {\n noTranslation: true,\n },\n argument_reporter_boolean: {\n noTranslation: true,\n type: BOOLEAN_BLOCK,\n },\n argument_reporter_string_number: {\n noTranslation: true,\n type: REPORTER_BLOCK,\n },\n pen_clear: {\n defaultMessage: 'erase all',\n translationKey: 'pen.clear',\n },\n pen_stamp: {\n defaultMessage: 'stamp',\n translationKey: 'pen.stamp',\n },\n pen_penDown: {\n defaultMessage: 'pen down',\n translationKey: 'pen.penDown',\n },\n pen_penUp: {\n defaultMessage: 'pen up',\n translationKey: 'pen.penUp',\n },\n pen_setPenColorToColor: {\n defaultMessage: 'set pen color to {COLOR}',\n translationKey: 'pen.setColor',\n },\n pen_changePenColorParamBy: {\n defaultMessage: 'change pen {COLOR_PARAM} by {VALUE}',\n translationKey: 'pen.changeColorParam',\n remap: {\n COLOR_PARAM: 'colorParam',\n },\n },\n pen_setPenColorParamTo: {\n defaultMessage: 'set pen {COLOR_PARAM} to {VALUE}',\n translationKey: 'pen.setColorParam',\n remap: {\n COLOR_PARAM: 'colorParam',\n },\n },\n pen_changePenSizeBy: {\n defaultMessage: 'change pen size by {SIZE}',\n translationKey: 'pen.changeSize',\n },\n pen_setPenSizeTo: {\n defaultMessage: 'set pen size to {SIZE}',\n translationKey: 'pen.setSize',\n },\n music_playDrumForBeats: {\n defaultMessage: 'play drum {DRUM} for {BEATS} beats',\n translationKey: 'music.playDrumForBeats',\n },\n music_restForBeats: {\n defaultMessage: 'rest for {BEATS} beats',\n translationKey: 'music.restForBeats',\n },\n music_playNoteForBeats: {\n defaultMessage: 'play note {NOTE} for {BEATS} beats',\n translationKey: 'music.playNoteForBeats',\n },\n music_setInstrument: {\n defaultMessage: 'set instrument to {INSTRUMENT}',\n translationKey: 'music.setInstrument',\n },\n music_setTempo: {\n defaultMessage: 'set tempo to {TEMPO}',\n translationKey: 'music.setTempo',\n },\n music_changeTempo: {\n defaultMessage: 'change tempo by {TEMPO}',\n translationKey: 'music.changeTempo',\n },\n music_getTempo: {\n defaultMessage: 'tempo',\n translationKey: 'music.getTempo',\n type: REPORTER_BLOCK,\n },\n videoSensing_whenMotionGreaterThan: {\n defaultMessage: 'when video motion > {REFERENCE}',\n translationKey: 'videoSensing.whenMotionGreaterThan',\n },\n videoSensing_videoOn: {\n defaultMessage: 'video {ATTRIBUTE} on {SUBJECT}',\n translationKey: 'videoSensing.videoOn',\n type: REPORTER_BLOCK,\n },\n videoSensing_videoToggle: {\n defaultMessage: 'turn video {VIDEO_STATE}',\n translationKey: 'videoSensing.videoToggle',\n },\n videoSensing_setVideoTransparency: {\n defaultMessage: 'set video transparency to {TRANSPARENCY}',\n translationKey: 'videoSensing.setVideoTransparency',\n },\n text2speech_speakAndWait: {\n defaultMessage: 'speak {WORDS}',\n translationKey: 'text2speech.speakAndWaitBlock',\n },\n text2speech_setVoice: {\n defaultMessage: 'set voice to {VOICE}',\n translationKey: 'text2speech.setVoiceBlock',\n remap: {\n VOICE: 'voices',\n },\n },\n text2speech_setLanguage: {\n defaultMessage: 'set language to {LANGUAGE}',\n translationKey: 'text2speech.setLanguageBlock',\n remap: {\n LANGUAGE: 'languages',\n },\n },\n translate_getTranslate: {\n defaultMessage: 'translate {WORDS} to {LANGAUGE}',\n translationKey: 'translate.translateBlock',\n type: REPORTER_BLOCK,\n remap: {\n LANGUAGE: 'languages',\n },\n },\n translate_getViewerLanguage: {\n defaultMessage: 'language',\n translationKey: 'translate.viewerLanguage',\n type: REPORTER_BLOCK,\n },\n boost_motorOnFor: {\n defaultMessage: 'turn motor {MOTOR_ID} for {DURATION} seconds',\n translationKey: 'boost.motorOnFor',\n },\n boost_motorOnForRotation: {\n defaultMessage: 'turn motor {MOTOR_ID} for {ROTATION} rotations',\n translationKey: 'boost.motorOnForRotation',\n },\n boost_motorOn: {\n defaultMessage: 'turn motor {MOTOR_ID} on',\n translationKey: 'boost.motorOn',\n },\n boost_motorOff: {\n defaultMessage: 'turn motor {MOTOR_ID} off',\n translationKey: 'boost.motorOff',\n },\n boost_setMotorPower: {\n defaultMessage: 'set motor {MOTOR_ID} speed to {POWER} %',\n translationKey: 'boost.setMotorPower',\n },\n boost_setMotorDirection: {\n defaultMessage: 'set motor {MOTOR_ID} direction {MOTOR_DIRECTION}',\n translationKey: 'boost.setMotorDirection',\n },\n boost_getMotorPosition: {\n defaultMessage: 'motor {MOTOR_REPORTER_ID} position',\n translationKey: 'boost.getMotorPosition',\n type: REPORTER_BLOCK,\n },\n boost_whenColor: {\n defaultMessage: 'when {COLOR} brick seen',\n translationKey: 'boost.whenColor',\n },\n boost_seeingColor: {\n defaultMessage: 'seeing {COLOR} brick?',\n translationKey: 'boost.seeingColor',\n type: BOOLEAN_BLOCK,\n },\n boost_whenTilted: {\n defaultMessage: 'when tilted {TILT_DIRECTION_ANY}',\n translationKey: 'boost.whenTilted',\n },\n boost_getTiltAngle: {\n defaultMessage: 'tilt angle {TILT_DIRECTION}',\n translationKey: 'boost.getTiltAngle',\n type: REPORTER_BLOCK,\n },\n boost_setLightHue: {\n defaultMessage: 'set light color to {HUE}',\n translationKey: 'boost.setLightHue',\n },\n ev3_motorTurnClockwise: {\n defaultMessage: 'motor {PORT} turn this way for {TIME} seconds',\n translationKey: 'ev3.motorTurnClockwise',\n remap: {\n PORT: 'motorPorts',\n },\n },\n ev3_motorTurnCounterClockwise: {\n defaultMessage: 'motor {PORT} turn that way for {TIME} seconds',\n translationKey: 'ev3.motorTurnCounterClockwise',\n remap: {\n PORT: 'motorPorts',\n },\n },\n ev3_motorSetPower: {\n defaultMessage: 'motor {PORT} set power {POWER} %',\n translationKey: 'ev3.motorSetPower',\n remap: {\n PORT: 'motorPorts',\n },\n },\n ev3_getMotorPosition: {\n defaultMessage: 'motor {PORT} position',\n translationKey: 'ev3.getMotorPosition',\n type: REPORTER_BLOCK,\n remap: {\n PORT: 'motorPorts',\n },\n },\n ev3_whenButtonPressed: {\n defaultMessage: 'when button {PORT} pressed',\n translationKey: 'ev3.whenButtonPressed',\n remap: {\n PORT: 'sensorPorts',\n },\n },\n ev3_whenDistanceLessThan: {\n defaultMessage: 'when distance < {DISTANCE}',\n translationKey: 'ev3.whenDistanceLessThan',\n },\n ev3_whenBrightnessLessThan: {\n defaultMessage: 'when brightness < {DISTANCE}',\n translationKey: 'ev3.whenBrightnessLessThan',\n },\n ev3_buttonPressed: {\n defaultMessage: 'button {PORT} pressed?',\n translationKey: 'ev3.buttonPressed',\n type: BOOLEAN_BLOCK,\n remap: {\n PORT: 'sensorPorts',\n },\n },\n ev3_getDistance: {\n defaultMessage: 'distance',\n translationKey: 'ev3.getDistance',\n type: REPORTER_BLOCK,\n },\n ev3_getBrightness: {\n defaultMessage: 'brightness',\n translationKey: 'ev3.getBrightness',\n type: REPORTER_BLOCK,\n },\n ev3_beep: {\n defaultMessage: 'beep note {NOTE} for {TIME} secs',\n translationKey: 'ev3.beepNote',\n },\n gdxfor_whenGesture: {\n defaultMessage: 'when {GESTURE}',\n translationKey: 'gdxfor.whenGesture',\n remap: {\n GESTURE: 'gestureOptions',\n },\n },\n gdxfor_whenForcePushedOrPulled: {\n defaultMessage: 'when force sensor {PUSH_PULL}',\n translationKey: 'gdxfor.whenForcePushedOrPulled',\n remap: {\n PUSH_PULL: 'pushPullOptions',\n },\n },\n gdxfor_getForce: {\n defaultMessage: 'force',\n translationKey: 'gdxfor.getForce',\n type: REPORTER_BLOCK,\n },\n gdxfor_whenTilted: {\n defaultMessage: 'when tilted {TILT}',\n translationKey: 'gdxfor.whenTilted',\n remap: {\n TILT: 'tiltAnyOptions',\n },\n },\n gdxfor_isTilted: {\n defaultMessage: 'tilted {TILT}?',\n translationKey: 'gdxfor.isTilted',\n type: BOOLEAN_BLOCK,\n remap: {\n TILT: 'tiltAnyOptions',\n },\n },\n gdxfor_getTilt: {\n defaultMessage: 'tilt angle {TILT}',\n translationKey: 'gdxfor.getTilt',\n type: REPORTER_BLOCK,\n remap: {\n TILT: 'tiltOptions',\n },\n },\n gdxfor_isFreeFalling: {\n defaultMessage: 'falling?',\n translationKey: 'gdxfor.isFreeFalling',\n type: BOOLEAN_BLOCK,\n },\n gdxfor_getSpinSpeed: {\n defaultMessage: 'spin speed {DIRECTION}',\n translationKey: 'gdxfor.getSpin',\n type: REPORTER_BLOCK,\n remap: {\n DIRECTION: 'axisOptions',\n },\n },\n gdxfor_getAcceleration: {\n defaultMessage: 'acceleration {DIRECTION}',\n translationKey: 'gdxfor.getAcceleration',\n type: REPORTER_BLOCK,\n remap: {\n DIRECTION: 'axisOptions',\n },\n },\n makeymakey_whenMakeyKeyPressed: {\n defaultMessage: 'when {KEY} key pressed',\n translationKey: 'makeymakey.whenKeyPressed',\n },\n makeymakey_whenCodePressed: {\n defaultMessage: 'when {SEQUENCE} pressed in order',\n translationKey: 'makeymakey.whenKeysPressedInOrder',\n },\n microbit_whenButtonPressed: {\n defaultMessage: 'when {BTN} button pressed',\n translationKey: 'microbit.whenButtonPressed',\n remap: {\n BTN: 'buttons',\n },\n },\n microbit_isButtonPressed: {\n defaultMessage: '{BTN} button pressed?',\n translationKey: 'microbit.isButtonPressed',\n type: BOOLEAN_BLOCK,\n remap: {\n BTN: 'buttons',\n },\n },\n microbit_whenGesture: {\n defaultMessage: 'when {GESTURE}',\n translationKey: 'microbit.whenGesture',\n remap: {\n GESTURE: 'gestures',\n },\n },\n microbit_displaySymbol: {\n defaultMessage: 'display {MATRIX}',\n translationKey: 'microbit.displaySymbol',\n },\n microbit_displayText: {\n defaultMessage: 'display text {TEXT}',\n translationKey: 'microbit.displayText',\n },\n microbit_displayClear: {\n defaultMessage: 'clear display',\n translationKey: 'microbit.clearDisplay',\n },\n microbit_whenTilted: {\n defaultMessage: 'when tilted {DIRECTION}',\n translationKey: 'microbit.whenTilted',\n remap: {\n DIRECTION: 'tiltDirectionAny',\n },\n },\n microbit_isTilted: {\n defaultMessage: 'tilted {DIRECTION}?',\n translationKey: 'microbit.isTilted',\n type: BOOLEAN_BLOCK,\n remap: {\n DIRECTION: 'tiltDirectionAny',\n },\n },\n microbit_getTiltAngle: {\n defaultMessage: 'tilt angle {DIRECTION}',\n translationKey: 'microbit.tiltAngle',\n type: REPORTER_BLOCK,\n remap: {\n DIRECTION: 'tiltDirection',\n },\n },\n microbit_whenPinConnected: {\n defaultMessage: 'when pin {PIN} connected',\n translationKey: 'microbit.whenPinConnected',\n remap: {\n PIN: 'touchPins',\n },\n },\n wedo2_motorOnFor: {\n defaultMessage: 'turn {MOTOR_ID} on for {DURATION} seconds',\n translationKey: 'wedo2.motorOnFor',\n },\n wedo2_motorOn: {\n defaultMessage: 'turn {MOTOR_ID} on',\n translationKey: 'wedo2.motorOn',\n },\n wedo2_motorOff: {\n defaultMessage: 'turn {MOTOR_ID} off',\n translationKey: 'wedo2.motorOff',\n },\n wedo2_startMotorPower: {\n defaultMessage: 'set {MOTOR_ID} power to {POWER}',\n translationKey: 'wedo2.startMotorPower',\n },\n wedo2_setMotorDirection: {\n defaultMessage: 'set {MOTOR_ID} direction to {MOTOR_DIRECTION}',\n translationKey: 'wedo2.setMotorDirection',\n },\n wedo2_setLightHue: {\n defaultMessage: 'set light color to {HUE}',\n translationKey: 'wedo2.setLightHue',\n },\n wedo2_playNoteFor: {\n defaultMessage: 'play note {NOTE} for {DURATION} seconds',\n translationKey: 'wedo2.playNoteFor',\n },\n wedo2_whenDistance: {\n defaultMessage: 'when distance {OP} {REFERENCE}',\n translationKey: 'wedo2.whenDistance',\n },\n wedo2_whenTilted: {\n defaultMessage: 'when tilted {TILT_DIRECTION_ANY}',\n translationKey: 'wedo2.whenTilted',\n },\n wedo2_getDistance: {\n defaultMessage: 'distance',\n translationKey: 'wedo2.getDistance',\n type: REPORTER_BLOCK,\n },\n wedo2_isTilted: {\n defaultMessage: 'tilted {TILT_DIRECTION_ANY}?',\n translationKey: 'wedo2.isTilted',\n type: BOOLEAN_BLOCK,\n },\n wedo2_getTiltAngle: {\n defaultMessage: 'tilt angle {TILT_DIRECTION}',\n translationKey: 'wedo2.getTiltAngle',\n type: REPORTER_BLOCK,\n },\n};\n\nconst effects = {\n COLOR: {\n translationKey: 'LOOKS_EFFECT_COLOR',\n defaultMessage: 'color',\n },\n FISHEYE: {\n translationKey: 'LOOKS_EFFECT_FISHEYE',\n defaultMessage: 'fisheye',\n },\n WHIRL: {\n translationKey: 'LOOKS_EFFECT_WHIRL',\n defaultMessage: 'whirl',\n },\n PIXELATE: {\n translationKey: 'LOOKS_EFFECT_PIXELATE',\n defaultMessage: 'pixelate',\n },\n MOSAIC: {\n translationKey: 'LOOKS_EFFECT_MOSAIC',\n defaultMessage: 'mosaic',\n },\n BRIGHTNESS: {\n translationKey: 'LOOKS_EFFECT_BRIGHTNESS',\n defaultMessage: 'brightness',\n },\n GHOST: {\n translationKey: 'LOOKS_EFFECT_GHOST',\n defaultMessage: 'ghost',\n },\n};\n\nconst backdrops = {\n 'next backdrop': {\n translationKey: 'LOOKS_NEXTBACKDROP',\n defaultMessage: 'next backdrop',\n },\n 'previous backdrop': {\n translationKey: 'LOOKS_PREVIOUSBACKDROP',\n defaultMessage: 'previous backdrop',\n },\n 'random backdrop': {\n translationKey: 'LOOKS_RANDOMBACKDROP',\n defaultMessage: 'random backdrop',\n },\n};\n\nconst numberName = {\n number: {\n translationKey: 'LOOKS_NUMBERNAME_NUMBER',\n defaultMessage: 'number',\n },\n name: {\n translationKey: 'LOOKS_NUMBERNAME_NAME',\n defaultMessage: 'name',\n },\n};\n\nconst soundEffects = {\n PITCH: {\n translationKey: 'SOUND_EFFECTS_PITCH',\n defaultMessage: 'pitch',\n },\n PAN: {\n translationKey: 'SOUND_EFFECTS_PAN',\n defaultMessage: 'pan',\n },\n};\n\nconst keyOptions = {\n space: {\n translationKey: 'EVENT_WHENKEYPRESSED_SPACE',\n defaultMessage: 'space',\n },\n 'up arrow': {\n translationKey: 'EVENT_WHENKEYPRESSED_UP',\n defaultMessage: 'up arrow',\n },\n 'down arrow': {\n translationKey: 'EVENT_WHENKEYPRESSED_DOWN',\n defaultMessage: 'down arrow',\n },\n 'right arrow': {\n translationKey: 'EVENT_WHENKEYPRESSED_RIGHT',\n defaultMessage: 'right arrow',\n },\n 'left arrow': {\n translationKey: 'EVENT_WHENKEYPRESSED_LEFT',\n defaultMessage: 'left arrow',\n },\n any: {\n translationKey: 'EVENT_WHENKEYPRESSED_ANY',\n defaultMessage: 'any',\n },\n};\n\nconst colorParam = {\n color: {\n translationKey: 'pen.colorMenu.color',\n defaultMessage: 'color',\n },\n saturation: {\n translationKey: 'pen.colorMenu.saturation',\n defaultMessage: 'saturation',\n },\n brightness: {\n translationKey: 'pen.colorMenu.brightness',\n defaultMessage: 'brightness',\n },\n transparency: {\n translationKey: 'pen.colorMenu.transparency',\n defaultMessage: 'transparency',\n },\n};\n\nconst assignKey = (o, keyPrefix) => {\n for (const k of Object.keys(o)) o[k].translationKey = `${keyPrefix}.${k}`;\n return o;\n};\n\nconst translateLanguages = assignKey(\n {\n sq: {\n defaultMessage: 'Albanian',\n },\n am: {\n defaultMessage: 'Amharic',\n },\n ar: {\n defaultMessage: 'Arabic',\n },\n hy: {\n defaultMessage: 'Armenian',\n },\n az: {\n defaultMessage: 'Azerbaijani',\n },\n eu: {\n defaultMessage: 'Basque',\n },\n be: {\n defaultMessage: 'Belarusian',\n },\n bg: {\n defaultMessage: 'Bulgarian',\n },\n ca: {\n defaultMessage: 'Catalan',\n },\n 'zh-tw': {\n defaultMessage: 'Chinese (Traditional)',\n },\n hr: {\n defaultMessage: 'Croatian',\n },\n cs: {\n defaultMessage: 'Czech',\n },\n da: {\n defaultMessage: 'Danish',\n },\n nl: {\n defaultMessage: 'Dutch',\n },\n en: {\n defaultMessage: 'English',\n },\n eo: {\n defaultMessage: 'Esperanto',\n },\n et: {\n defaultMessage: 'Estonian',\n },\n fi: {\n defaultMessage: 'Finnish',\n },\n fr: {\n defaultMessage: 'French',\n },\n gl: {\n defaultMessage: 'Galician',\n },\n de: {\n defaultMessage: 'German',\n },\n el: {\n defaultMessage: 'Greek',\n },\n ht: {\n defaultMessage: 'Haitian Creole',\n },\n hi: {\n defaultMessage: 'Hindi',\n },\n hu: {\n defaultMessage: 'Hungarian',\n },\n is: {\n defaultMessage: 'Icelandic',\n },\n id: {\n defaultMessage: 'Indonesian',\n },\n ga: {\n defaultMessage: 'Irish',\n },\n it: {\n defaultMessage: 'Italian',\n },\n ja: {\n defaultMessage: 'Japanese',\n },\n kn: {\n defaultMessage: 'Kannada',\n },\n ko: {\n defaultMessage: 'Korean',\n },\n ku: {\n defaultMessage: 'Kurdish (Kurmanji)',\n },\n la: {\n defaultMessage: 'Latin',\n },\n lv: {\n defaultMessage: 'Latvian',\n },\n lt: {\n defaultMessage: 'Lithuanian',\n },\n mk: {\n defaultMessage: 'Macedonian',\n },\n ms: {\n defaultMessage: 'Malay',\n },\n ml: {\n defaultMessage: 'Malayalam',\n },\n mt: {\n defaultMessage: 'Maltese',\n },\n mi: {\n defaultMessage: 'Maori',\n },\n mr: {\n defaultMessage: 'Marathi',\n },\n mn: {\n defaultMessage: 'Mongolian',\n },\n my: {\n defaultMessage: 'Myanmar (Burmese)',\n },\n fa: {\n defaultMessage: 'Persian',\n },\n pl: {\n defaultMessage: 'Polish',\n },\n pt: {\n defaultMessage: 'Portuguese',\n },\n ro: {\n defaultMessage: 'Romanian',\n },\n ru: {\n defaultMessage: 'Russian',\n },\n gd: {\n defaultMessage: 'Scots Gaelic',\n },\n sr: {\n defaultMessage: 'Serbian',\n },\n sk: {\n defaultMessage: 'Slovak',\n },\n sl: {\n defaultMessage: 'Slovenian',\n },\n es: {\n defaultMessage: 'Spanish',\n },\n sv: {\n defaultMessage: 'Swedish',\n },\n te: {\n defaultMessage: 'Telugu',\n },\n th: {\n defaultMessage: 'Thai',\n },\n tr: {\n defaultMessage: 'Turkish',\n },\n uk: {\n defaultMessage: 'Ukrainian',\n },\n uz: {\n defaultMessage: 'Uzbek',\n },\n vi: {\n defaultMessage: 'Vietnamese',\n },\n cy: {\n defaultMessage: 'Welsh',\n },\n zu: {\n defaultMessage: 'Zulu',\n },\n he: {\n defaultMessage: 'Hebrew',\n },\n 'zh-cn': {\n defaultMessage: 'Chinese (Simplified)',\n },\n },\n 'special.translate'\n);\n\n// Used by buildscript\nexport const _unkeyedTextToSpeechLanguages = {\n ar: {\n defaultMessage: 'Arabic',\n },\n 'zh-cn': {\n defaultMessage: 'Chinese (Mandarin)',\n },\n da: {\n defaultMessage: 'Danish',\n },\n nl: {\n defaultMessage: 'Dutch',\n },\n en: {\n defaultMessage: 'English',\n },\n fr: {\n defaultMessage: 'French',\n },\n de: {\n defaultMessage: 'German',\n },\n hi: {\n defaultMessage: 'Hindi',\n },\n is: {\n defaultMessage: 'Icelandic',\n },\n it: {\n defaultMessage: 'Italian',\n },\n ja: {\n defaultMessage: 'Japanese',\n },\n ko: {\n defaultMessage: 'Korean',\n },\n nb: {\n defaultMessage: 'Norwegian',\n },\n pl: {\n defaultMessage: 'Polish',\n },\n 'pt-br': {\n defaultMessage: 'Portuguese (Brazilian)',\n },\n pt: {\n defaultMessage: 'Portuguese (European)',\n },\n ro: {\n defaultMessage: 'Romanian',\n },\n ru: {\n defaultMessage: 'Russian',\n },\n es: {\n defaultMessage: 'Spanish (European)',\n },\n 'es-419': {\n defaultMessage: 'Spanish (Latin American)',\n },\n sv: {\n defaultMessage: 'Swedish',\n },\n tr: {\n defaultMessage: 'Turkish',\n },\n cy: {\n defaultMessage: 'Welsh',\n },\n};\nconst ttsLanguages = assignKey(_unkeyedTextToSpeechLanguages, 'special.tts');\n\nconst boostMotorId = {\n A: {\n defaultMessage: 'A',\n },\n B: {\n defaultMessage: 'B',\n },\n C: {\n defaultMessage: 'C',\n },\n D: {\n defaultMessage: 'D',\n },\n AB: {\n defaultMessage: 'AB',\n },\n ALL: {\n defaultMessage: 'ABCD',\n },\n};\n\nconst boostColor = {\n red: {\n translationKey: 'boost.color.red',\n defaultMessage: 'red',\n },\n blue: {\n translationKey: 'boost.color.blue',\n defaultMessage: 'blue',\n },\n green: {\n translationKey: 'boost.color.green',\n defaultMessage: 'green',\n },\n yellow: {\n translationKey: 'boost.color.yellow',\n defaultMessage: 'yellow',\n },\n white: {\n translationKey: 'boost.color.white',\n defaultMessage: 'white',\n },\n black: {\n translationKey: 'boost.color.black',\n defaultMessage: 'black',\n },\n any: {\n translationKey: 'boost.color.any',\n defaultMessage: 'any color',\n },\n};\n\nconst boostTilt = {\n up: {\n translationKey: 'boost.tiltDirection.up',\n defaultMessage: 'up',\n },\n down: {\n translationKey: 'boost.tiltDirection.down',\n defaultMessage: 'down',\n },\n left: {\n translationKey: 'boost.tiltDirection.left',\n defaultMessage: 'left',\n },\n right: {\n translationKey: 'boost.tiltDirection.right',\n defaultMessage: 'right',\n },\n};\n\nconst ev3MotorPorts = {\n 0: {\n defaultMessage: 'A',\n },\n 1: {\n defaultMessage: 'B',\n },\n 2: {\n defaultMessage: 'C',\n },\n 3: {\n defaultMessage: 'D',\n },\n};\n\nconst ev3SensorPorts = {\n 0: {\n defaultMessage: '1',\n },\n 1: {\n defaultMessage: '2',\n },\n 2: {\n defaultMessage: '3',\n },\n 3: {\n defaultMessage: '4',\n },\n};\n\nconst gdxforTilt = {\n front: {\n translationKey: 'gdxfor.tiltDirectionMenu.front',\n defaultMessage: 'front',\n },\n back: {\n translationKey: 'gdxfor.tiltDirectionMenu.back',\n defaultMessage: 'back',\n },\n left: {\n translationKey: 'gdxfor.tiltDirectionMenu.left',\n defaultMessage: 'left',\n },\n right: {\n translationKey: 'gdxfor.tiltDirectionMenu.right',\n defaultMessage: 'right',\n },\n};\n\nconst gdxforTiltAny = Object.assign({}, gdxforTilt, {\n any: {\n translationKey: 'gdxfor.tiltDirectionMenu.any',\n defaultMessage: 'any',\n },\n});\n\nconst gdxforAxis = {\n x: {\n defaultMessage: 'x',\n },\n y: {\n defaultMessage: 'y',\n },\n z: {\n defaultMessage: 'z',\n },\n};\n\nconst makeMakeymakeyCombs = (keyPrefix, ...combinations) =>\n Object.fromEntries(\n combinations.map(c => [\n c.toUpperCase(),\n {\n defaultMessage: c,\n translationKey: `${keyPrefix}.${c.replace(/ /g, '.')}`,\n },\n ])\n );\n\nconst makeymakeySequences = makeMakeymakeyCombs(\n 'special.makeymakey',\n 'left up right',\n 'right up left',\n 'left right',\n 'right left',\n 'up down',\n 'down up',\n 'up right down left',\n 'up left down right',\n 'up up down down left right left right'\n);\n\nconst microbitButtons = {\n A: {\n defaultMessage: 'A',\n },\n B: {\n defaultMessage: 'B',\n },\n any: {\n translationKey: 'microbit.buttonsMenu.any',\n defaultMessage: 'any',\n },\n};\n\nconst microbitTilt = {\n front: {\n translationKey: 'microbit.tiltDirectionMenu.front',\n defaultMessage: 'front',\n },\n back: {\n translationKey: 'microbit.tiltDirectionMenu.back',\n defaultMessage: 'back',\n },\n left: {\n translationKey: 'microbit.tiltDirectionMenu.left',\n defaultMessage: 'left',\n },\n right: {\n translationKey: 'microbit.tiltDirectionMenu.right',\n defaultMessage: 'right',\n },\n};\n\nconst microbitTiltAny = Object.assign({}, microbitTilt, {\n any: {\n translationKey: 'microbit.tiltDirectionMenu.any',\n defaultMessage: 'any',\n },\n});\n\nconst wedo2Motors = {\n motor: {\n translationKey: 'wedo2.motorId.default',\n defaultMessage: 'motor',\n },\n 'motor A': {\n translationKey: 'wedo2.motorId.a',\n defaultMessage: 'motor A',\n },\n 'motor B': {\n translationKey: 'wedo2.motorId.b',\n defaultMessage: 'motor B',\n },\n 'all motors': {\n translationKey: 'wedo2.motorId.all',\n defaultMessage: 'all motors',\n },\n};\n\nconst wedo2Tilt = {\n up: {\n translationKey: 'wedo2.tiltDirection.up',\n defaultMessage: 'up',\n },\n down: {\n translationKey: 'wedo2.tiltDirection.down',\n defaultMessage: 'down',\n },\n left: {\n translationKey: 'wedo2.tiltDirection.left',\n defaultMessage: 'left',\n },\n right: {\n translationKey: 'wedo2.tiltDirection.right',\n defaultMessage: 'right',\n },\n};\n\nconst wedo2TiltAny = Object.assign({}, wedo2Tilt, {\n any: {\n translationKey: 'wedo2.tiltDirection.any',\n defaultMessage: 'any',\n },\n});\n\nexport const allMenus = {\n motion_pointtowards: {\n _mouse_: {\n translationKey: 'MOTION_POINTTOWARDS_POINTER',\n defaultMessage: 'mouse-pointer',\n },\n _random_: {\n translationKey: 'MOTION_POINTTOWARDS_RANDOM',\n defaultMessage: 'random position',\n },\n },\n motion_goto: {\n _mouse_: {\n translationKey: 'MOTION_GOTO_POINTER',\n defaultMessage: 'mouse-pointer',\n },\n _random_: {\n translationKey: 'MOTION_GOTO_RANDOM',\n defaultMessage: 'random position',\n },\n },\n motion_glideto: {\n _mouse_: {\n translationKey: 'MOTION_GLIDETO_POINTER',\n defaultMessage: 'mouse-pointer',\n },\n _random_: {\n translationKey: 'MOTION_GLIDETO_RANDOM',\n defaultMessage: 'random position',\n },\n },\n motion_setrotationstyle: {\n 'left-right': {\n translationKey: 'MOTION_SETROTATIONSTYLE_LEFTRIGHT',\n defaultMessage: 'left-right',\n },\n \"don't rotate\": {\n translationKey: 'MOTION_SETROTATIONSTYLE_DONTROTATE',\n defaultMessage: \"don't rotate\",\n },\n 'all around': {\n translationKey: 'MOTION_SETROTATIONSTYLE_ALLAROUND',\n defaultMessage: 'all around',\n },\n },\n looks_changeeffectby: effects,\n looks_seteffectto: effects,\n looks_switchbackdropto: backdrops,\n looks_gotofrontback: {\n front: {\n translationKey: 'LOOKS_GOTOFRONTBACK_FRONT',\n defaultMessage: 'front',\n },\n back: {\n translationKey: 'LOOKS_GOTOFRONTBACK_BACK',\n defaultMessage: 'back',\n },\n },\n looks_goforwardbackwardlayers: {\n forward: {\n translationKey: 'LOOKS_GOFORWARDBACKWARDLAYERS_FORWARD',\n defaultMessage: 'forward',\n },\n backward: {\n translationKey: 'LOOKS_GOFORWARDBACKWARDLAYERS_BACKWARD',\n defaultMessage: 'backward',\n },\n },\n looks_backdropnumbername: numberName,\n looks_costumenumbername: numberName,\n looks_switchbackdroptoandwait: backdrops,\n sound_seteffectto: soundEffects,\n sound_changeeffectby: soundEffects,\n event_whengreaterthan: {\n LOUDNESS: {\n translationKey: 'EVENT_WHENGREATERTHAN_LOUDNESS',\n defaultMessage: 'loudness',\n },\n TIMER: {\n translationKey: 'EVENT_WHENGREATERTHAN_TIMER',\n defaultMessage: 'timer',\n },\n },\n event_whenkeypressed: keyOptions,\n control_stop: {\n all: {\n translationKey: 'CONTROL_STOP_ALL',\n defaultMessage: 'all',\n },\n 'this script': {\n translationKey: 'CONTROL_STOP_THIS',\n defaultMessage: 'this script',\n },\n 'other scripts in sprite': {\n translationKey: 'CONTROL_STOP_OTHER',\n defaultMessage: 'other scripts in sprite',\n },\n },\n control_create_clone_of: {\n _myself_: {\n translationKey: 'CONTROL_CREATECLONEOF_MYSELF',\n defaultMessage: 'myself',\n },\n },\n sensing_touchingobject: {\n _mouse_: {\n translationKey: 'SENSING_TOUCHINGOBJECT_POINTER',\n defaultMessage: 'mouse-pointer',\n },\n _edge_: {\n translationKey: 'SENSING_TOUCHINGOBJECT_EDGE',\n defaultMessage: 'edge',\n },\n },\n sensing_distanceto: {\n _mouse_: {\n translationKey: 'SENSING_DISTANCETO_POINTER',\n defaultMessage: 'mouse-pointer',\n },\n },\n sensing_keypressed: keyOptions,\n sensing_setdragmode: {\n draggable: {\n translationKey: 'SENSING_SETDRAGMODE_DRAGGABLE',\n defaultMessage: 'draggable',\n },\n 'not draggable': {\n translationKey: 'SENSING_SETDRAGMODE_NOTDRAGGABLE',\n defaultMessage: 'not draggable',\n },\n },\n sensing_of: {\n _stage_: {\n translationKey: 'SENSING_OF_STAGE',\n defaultMessage: 'Stage',\n },\n 'x position': {\n translationKey: 'SENSING_OF_XPOSITION',\n defaultMessage: 'x position',\n },\n 'y position': {\n translationKey: 'SENSING_OF_YPOSITION',\n defaultMessage: 'y position',\n },\n direction: {\n translationKey: 'SENSING_OF_DIRECTION',\n defaultMessage: 'direction',\n },\n 'costume #': {\n translationKey: 'SENSING_OF_COSTUMENUMBER',\n defaultMessage: 'costume #',\n },\n 'costume name': {\n translationKey: 'SENSING_OF_COSTUMENAME',\n defaultMessage: 'costume name',\n },\n size: {\n translationKey: 'SENSING_OF_SIZE',\n defaultMessage: 'size',\n },\n volume: {\n translationKey: 'SENSING_OF_VOLUME',\n defaultMessage: 'volume',\n },\n 'backdrop #': {\n translationKey: 'SENSING_OF_BACKDROPNUMBER',\n defaultMessage: 'backdrop #',\n },\n 'backdrop name': {\n translationKey: 'SENSING_OF_BACKDROPNAME',\n defaultMessage: 'backdrop name',\n },\n },\n sensing_current: {\n YEAR: {\n translationKey: 'SENSING_CURRENT_YEAR',\n defaultMessage: 'year',\n },\n MONTH: {\n translationKey: 'SENSING_CURRENT_MONTH',\n defaultMessage: 'month',\n },\n DATE: {\n translationKey: 'SENSING_CURRENT_DATE',\n defaultMessage: 'date',\n },\n DAYOFWEEK: {\n translationKey: 'SENSING_CURRENT_DAYOFWEEK',\n defaultMessage: 'day of week',\n },\n HOUR: {\n translationKey: 'SENSING_CURRENT_HOUR',\n defaultMessage: 'hour',\n },\n MINUTE: {\n translationKey: 'SENSING_CURRENT_MINUTE',\n defaultMessage: 'minute',\n },\n SECOND: {\n translationKey: 'SENSING_CURRENT_SECOND',\n defaultMessage: 'second',\n },\n },\n operator_mathop: {\n abs: {\n translationKey: 'OPERATORS_MATHOP_ABS',\n defaultMessage: 'abs',\n },\n floor: {\n translationKey: 'OPERATORS_MATHOP_FLOOR',\n defaultMessage: 'floor',\n },\n ceiling: {\n translationKey: 'OPERATORS_MATHOP_CEILING',\n defaultMessage: 'ceiling',\n },\n sqrt: {\n translationKey: 'OPERATORS_MATHOP_SQRT',\n defaultMessage: 'sqrt',\n },\n sin: {\n translationKey: 'OPERATORS_MATHOP_SIN',\n defaultMessage: 'sin',\n },\n cos: {\n translationKey: 'OPERATORS_MATHOP_COS',\n defaultMessage: 'cos',\n },\n tan: {\n translationKey: 'OPERATORS_MATHOP_TAN',\n defaultMessage: 'tan',\n },\n asin: {\n translationKey: 'OPERATORS_MATHOP_ASIN',\n defaultMessage: 'as