diff --git a/data/core.yaml b/data/core.yaml index b6c13418c..962a05932 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -1931,7 +1931,7 @@ en: chapters: "You can use the buttons below to skip chapters at any time or to restart a chapter if you get stuck. Let's begin! **Press '{next}' to continue.**" navigation: title: "Navigation" - drag: "The main map area shows OpenStreetMap data on top of a background.{br}You can click-and-drag the map with the left mouse button to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**" + drag: "The main map area shows OpenStreetMap data on top of a background.{br}You can click-and-drag the map with the {leftclick} left mouse button to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**" drag_touch: "The main map area shows OpenStreetMap data on top of a background.{br}You can tap-and-drag the map to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**" zoom: "You can zoom the map by scrolling with a mouse wheel or trackpad, or by pressing the {plus} / {minus} buttons. **Zoom the map!**" zoom_touch: "You can zoom the map by pinching it with two fingers, double-tapping a location, or pressing the {plus} / {minus} buttons. **Zoom the map!**" @@ -1944,100 +1944,100 @@ en: editor_townhall: "When a feature is selected, the *feature editor* is displayed alongside the map." preset_townhall: "The top part of the feature editor shows the feature's type. This point is a {preset}." fields_townhall: "The middle part of the feature editor contains *fields* showing the feature's attributes, such as its name and address." - close_townhall: "**Close the feature editor by hitting escape or pressing the {button} button in the upper corner.**" + close_townhall: "**Close the feature editor by pressing `{esc}` or the {button} button in the upper corner.**" search_street: "You can also search for features in the current view, or worldwide. **Search for '{name}'.**" choose_street: "**Choose {name} from the list to select it.**" selected_street: "Great! {name} is now selected." - editor_street: "The fields shown for a street are different than the fields that were shown for the town hall.{br}For this selected street, the feature editor shows fields like '{field1}' and '{field2}'. **Close the feature editor by hitting escape or pressing the {button} button.**" + editor_street: "The fields shown for a street are different than the fields that were shown for the town hall.{br}For this selected street, the feature editor shows fields like '{field1}' and '{field2}'. **Close the feature editor by pressing `{esc}` the {button} button.**" play: "Try exploring the map and selecting some other features to see what kinds of things can be added to OpenStreetMap. **When you are ready to continue to the next chapter, press '{next}'.**" points: title: "Points" - add_point: "*Points* can be used to represent features such as shops, restaurants, and monuments.{br}They mark a specific location, and describe what's there. **Press the {button} Point button to add a new point.**" - place_point: "To place the new point on the map, position your mouse cursor where the point should go, then left-click or press the spacebar. **Move the mouse pointer over this building, then left-click or press the spacebar.**" + add_point: "*Points* can be used to represent features such as shops, restaurants, and monuments.{br}They mark a specific location, and describe what's there. **Press the {point_icon} {point} button to add a new point.**" + place_point: "To place the new point on the map, position your mouse cursor where the point should go, then {leftclick} left-click or press `{space}`. **Move the mouse pointer over this building, then left-click or press `{space}`.**" place_point_touch: "To place the new point on the map, tap the location where it should go. **Tap the center of this building.**" search_cafe: "There are many different features that can be represented by points. The point you just added is a cafe. **Search for '{preset}'.**" choose_cafe: "**Choose {preset} from the list.**" feature_editor: "The point is now marked as a cafe. Using the feature editor, we can add more information about the cafe." add_name: "In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure.{br}Let's pretend that you have local knowledge of this cafe, and you know its name. **Add a name for the cafe.**" - add_close: "The feature editor will remember all of your changes automatically. **When you are finished adding the name, hit escape, enter, or press the {button} button to close the feature editor.**" + add_close: "The feature editor will remember all of your changes automatically. **When you are finished adding the name, press `{esc}`, `{return}`, or the {button} button to close the feature editor.**" reselect: "Often points will already exist, but have mistakes or be incomplete. We can edit existing points. **Select the cafe you just created.**" update: "Let's fill in some more details for this cafe. You can change its name, add a cuisine, or add an address. **Change the cafe details.**" - update_close: "**When you are finished updating the cafe, hit escape, enter, or press the {button} button to close the feature editor.**" - rightclick: "You can right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed.{br}A right-click might be the same as a control-click, or a two-finger tap on a trackpad. **Right-click to select the point you created and show the edit menu.**" + update_close: "**When you are finished updating the cafe, press `{esc}`, `{return}`, or the {button} button to close the feature editor.**" + rightclick: "You can {rightclick} right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed.{br}A right-click might be the same as a control-click or two-finger click. **Right-click to select the point you created and show the edit menu.**" edit_menu_touch: "You can long-press on any feature to see the *edit menu*, which shows a list of editing operations that can be performed. **Press-and-hold the point you created to show the edit menu.**" - delete: "It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Press the {button} button to delete the point.**" - undo: "You can always undo any changes up until you save your edits to OpenStreetMap. **Press the {button} button to undo the delete and get the point back.**" + delete: "It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Press the {delete_icon} {delete} button to remove the point.**" + undo: "You can always undo any changes up until you save your edits to OpenStreetMap. **Press the {undo_icon} {undo} button to get the point back.**" play: "Now that you know how to create and edit points, try creating a few more points for practice! **When you are ready to continue to the next chapter, press '{next}'.**" areas: title: "Areas" - add_playground: "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can also be used for more detailed mapping of many features you might normally map as points. **Press the {button} Area button to add a new area.**" - start_playground: "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Click or press spacebar to place a starting node on one of the corners of the playground.**" + add_playground: "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can also be used for more detailed mapping of many features you might normally map as points. **Press the {area_icon} {area} button to add a new area.**" + start_playground: "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Click or press `{space}` to place a starting node on one of the corners of the playground.**" start_playground_touch: "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Tap to place a starting node on one of the corners of the playground.**" - continue_playground: "Continue drawing the area by placing more nodes along the playground's edge. It is OK to connect the area to the existing walking paths.{br}Tip: You can hold down the '{alt}' key to prevent nodes from connecting to other features. **Continue drawing an area for the playground.**" - finish_playground: "Finish the area by pressing enter, or clicking again on either the first or last node. **Finish drawing an area for the playground.**" - finish_playground_touch: "Finish the area by tapping again on either the first or last node, or by pressing enter on a keyboard. **Finish drawing an area for the playground.**" + continue_playground: "Continue drawing the area by placing more nodes along the playground's edge. It is OK to connect the area to the existing walking paths.{br}Tip: You can hold down the `{alt}` key to prevent nodes from connecting to other features. **Continue drawing an area for the playground.**" + finish_playground: "Finish the area by pressing `{return}`, or clicking again on either the first or last node. **Finish drawing an area for the playground.**" + finish_playground_touch: "Finish the area by tapping again on either the first or last node, or by pressing `{return}` on a keyboard. **Finish drawing an area for the playground.**" search_playground: "**Search for '{preset}'.**" choose_playground: "**Choose {preset} from the list.**" - add_field: "This playground doesn't have an official name, so we won't add anything in the Name field.{br}Instead let's add some additional details about the playground to the Description field. **Open the Add Field list.**" + add_field: "This playground doesn't have an official name, so we won't add anything in the {name} field.{br}Instead let's add some additional details about the playground to the {description} field. **Open the Add Field list.**" choose_field: "**Choose {field} from the list.**" retry_add_field: "You didn't select the {field} field. Let's try again." describe_playground: "**Add a description, then press the {button} button to close the feature editor.**" play: "Good job! Try drawing a few more areas, and see what other kinds of area features you can add to OpenStreetMap. **When you are ready to continue to the next chapter, press '{next}'.**" lines: title: "Lines" - add_line: "*Lines* are used to represent features such as roads, railroads, and rivers. **Click the {button} Line button to add a new line.**" + add_line: "*Lines* are used to represent features such as roads, railroads, and rivers. **Click the {line_icon} {line} button to add a new line.**" start_line: "Here is a road that is missing. Let's add it!{br}In OpenStreetMap, lines should be drawn down the center of the road. You can drag and zoom the map while drawing if necessary. **Start a new line by clicking at the top end of this missing road.**" - intersect: "Click or press spacebar to add more nodes to the line.{br}Roads, and many other types of lines, are part of a larger network. It is important for these lines to be connected properly in order for routing applications to work. **Click on {name} to create an intersection connecting the two lines.**" + intersect: "Click or press `{space}` to add more nodes to the line.{br}Roads, and many other types of lines, are part of a larger network. It is important for these lines to be connected properly in order for routing applications to work. **Click on {name} to create an intersection connecting the two lines.**" retry_intersect: "The road needs to intersect {name}. Let's try again!" continue_line: "Continue drawing the line for the new road. Remember that you can drag and zoom the map if needed.{br}When you are finished drawing, click on the last node again. **Finish drawing the road.**" choose_category_road: "**Select {category} from the list.**" choose_preset_residential: "There are many different types of roads, but this one is a residential road. **Choose the {preset} type.**" retry_preset_residential: "You didn't select the {preset} type. **Click here to choose again.**" - name_road: "**Give this road a name, then hit escape, enter, or click the {button} button to close the feature editor.**" + name_road: "**Give this road a name, then press `{esc}`, `{return}`, or the {button} button to close the feature editor.**" did_name_road: "Looks good! Next we will learn how to update the shape of a line." update_line: "Sometimes you will need to change the shape of an existing line. Here is a road that doesn't look quite right." add_node: "We can add some nodes to this line to improve its shape. One way to add a node is to double-click the line where you want to add a node. **Double-click on the line to create a new node.**" - start_drag_endpoint: "When a line is selected, you can drag any of its nodes by clicking and holding down the left mouse button while you drag. **Drag the endpoint to the place where these roads should intersect.**" - finish_drag_endpoint: "This spot looks good. **Release the left mouse button to finish dragging.**" + start_drag_endpoint: "When a line is selected, you can drag any of its nodes by clicking and holding down the {leftclick} left mouse button while you drag. **Drag the endpoint to the place where these roads should intersect.**" + finish_drag_endpoint: "This spot looks good. **Release the {leftclick} left mouse button to finish dragging.**" start_drag_midpoint: "Small triangles are drawn at the *midpoints* between nodes. Another way to create a new node is to drag a midpoint to a new location. **Drag the midpoint triangle to create a new node along the curve of the road.**" - continue_drag_midpoint: "This line is looking much better! Continue to adjust this line by double-clicking or dragging midpoints until the curve matches the road shape. **When you're happy with how the line looks, click OK.**" + continue_drag_midpoint: "This line is looking much better! Continue to adjust this line by double-clicking or dragging midpoints until the curve matches the road shape. **When you're happy with how the line looks, click {ok}.**" delete_lines: "It's OK to delete lines for roads that don't exist in the real world.{br}Here's an example where the city planned a {street} but never built it. We can improve this part of the map by deleting the extra lines." - rightclick_intersection: "The last real street is {street1}, so we will *split* {street2} at this intersection and remove everything above it. **Right click on the intersection node.**" - split_intersection: "**Click on the {button} button to split {street}.**" - retry_split: "You didn't click the Split button. Try again." + rightclick_intersection: "The last real street is {street1}, so we will *split* {street2} at this intersection and remove everything above it. **{rightclick} Right-click on the intersection node.**" + split_intersection: "**Press the {split_icon} {split} button to divide {street}.**" + retry_split: "You didn't press the {split_icon} {split} button. Try again." did_split_multi: "Good job! {street1} is now split into two pieces. The top part can be removed. **Click the top part of {street2} to select it.**" did_split_single: "**Click the top part of {street2} to select it.**" - multi_select: "{selected} is now selected. Let's also select {other1}. You can shift-click to select multiple things. **Shift-click on {other2}.**" - multi_rightclick: "Good! Both lines to delete are now selected. **Right-click on one of the lines to show the edit menu.**" - multi_delete: "**Click on the {button} button to delete the extra lines.**" - retry_delete: "You didn't click the Delete button. Try again." + multi_select: "{selected} is now selected. Let's also select {other1}. You can hold `{shift}` while clicking to select multiple things. **Shift-click on {other2}.**" + multi_rightclick: "Good! Both lines to delete are now selected. **{rightclick} Right-click on one of the lines to show the edit menu.**" + multi_delete: "**Press the {delete_icon} {delete} button to remove the extra lines.**" + retry_delete: "You didn't press the {delete_icon} {delete} button. Try again." play: "Great! Use the skills that you've learned in this chapter to practice editing some more lines. **When you are ready to continue to the next chapter, press '{next}'.**" buildings: title: "Buildings" - add_building: "OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Press the {button} Area button to add a new area.**" - start_building: "Let's add this house to the map by tracing its outline.{br}Buildings should be traced around their footprint as accurately as possible. **Click or press spacebar to place a starting node on one of the corners of the building.**" - continue_building: "Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details.{br}Finish the building by pressing enter, or clicking again on either the first or last node. **Finish tracing the building.**" + add_building: "OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Press the {area_icon} {area} button to add a new area.**" + start_building: "Let's add this house to the map by tracing its outline.{br}Buildings should be traced around their footprint as accurately as possible. **Click or press `{space}` to place a starting node on one of the corners of the building.**" + continue_building: "Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details.{br}Finish the building by pressing `{return}`, or clicking again on either the first or last node. **Finish tracing the building.**" retry_building: "It looks like you had some trouble placing the nodes at the building corners. Try again!" choose_category_building: "**Choose {category} from the list.**" choose_preset_house: "There are many different types of buildings, but this one is clearly a house.{br}If you're not sure of the type, it's OK to just choose the generic Building type. **Choose the {preset} type.**" - close: "**Hit escape or click the {button} button to close the feature editor.**" - rightclick_building: "**Right-click to select the building you created and show the edit menu.**" - square_building: "The house that you just added will look even better with perfectly square corners. **Press the {button} button to square the building shape.**" - retry_square: "You didn't press the {button} button. Try again." + close: "**Press `{esc}` or the {apply} button to close the feature editor.**" + rightclick_building: "**{rightclick} Right-click to select the building you created and show the edit menu.**" + square_building: "The house that you just added will look even better with perfectly square corners. **Press the {orthogonalize_icon} {orthogonalize} button to tidy up the building shape.**" + retry_square: "You didn't press the {orthogonalize_icon} {orthogonalize} button. Try again." done_square: "See how the corners of the building moved into place? Let's learn another useful trick." - add_tank: "Next we'll trace this circular storage tank. **Press the {button} Area button to add a new area.**" - start_tank: "Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge. **Click or press spacebar to place a starting node on the edge of the tank.**" - continue_tank: "Add a few more nodes around the edge. The circle will be created outside the nodes that you draw.{br}Finish the area by pressing enter, or clicking again on either the first or last node. **Finish tracing the tank.**" + add_tank: "Next we'll trace this circular storage tank. **Press the {area_icon} {area} button to add a new area.**" + start_tank: "Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge. **Click or press `{space}` to place a starting node on the edge of the tank.**" + continue_tank: "Add a few more nodes around the edge. The circle will be created outside the nodes that you draw.{br}Finish the area by pressing `{return}`, or clicking again on either the first or last node. **Finish tracing the tank.**" search_tank: "**Search for '{preset}'.**" choose_tank: "**Choose {preset} from the list.**" - rightclick_tank: "**Right-click to select the storage tank you created and show the edit menu.**" - circle_tank: "**Press the {button} button to make the tank a circle.**" - retry_circle: "You didn't click the Circularize button. Try again." + rightclick_tank: "**{rightclick} Right-click to select the storage tank you created and show the edit menu.**" + circle_tank: "**Press the {circularize_icon} {circularize} button to make the tank a circle.**" + retry_circle: "You didn't click the {circularize_icon} {circularize} button. Try again." play: "Great Job! Practice tracing a few more buildings, and try some of the other commands on the edit menu. **When you are ready to continue to the next chapter, press '{next}'.**" startediting: title: "Start Editing" - help: "You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by pressing the {button} Help button or the '{key}' key." - shortcuts: "You can view a list of commands along with their keyboard shortcuts by pressing the '{key}' key." + help: "You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by pressing the {help_icon} {help} button or the `{help_key}` key." + shortcuts: "You can view a list of commands along with their keyboard shortcuts by pressing the `{shortcuts_key}` key." save: "Don't forget to regularly save your changes!" start: "Start mapping!" shortcuts: diff --git a/data/presets.yaml b/data/presets.yaml index 251bb7530..e056721dc 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -2499,6 +2499,7 @@ en: support: # support=* label: Support + terms: '[translate with synonyms or related terms for ''Support'', separated by commas]' surface: # surface=* label: Surface diff --git a/dist/locales/en.json b/dist/locales/en.json index 2c79d226b..020fa655f 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -2406,7 +2406,7 @@ }, "navigation": { "title": "Navigation", - "drag": "The main map area shows OpenStreetMap data on top of a background.{br}You can click-and-drag the map with the left mouse button to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**", + "drag": "The main map area shows OpenStreetMap data on top of a background.{br}You can click-and-drag the map with the {leftclick} left mouse button to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**", "drag_touch": "The main map area shows OpenStreetMap data on top of a background.{br}You can tap-and-drag the map to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**", "zoom": "You can zoom the map by scrolling with a mouse wheel or trackpad, or by pressing the {plus} / {minus} buttons. **Zoom the map!**", "zoom_touch": "You can zoom the map by pinching it with two fingers, double-tapping a location, or pressing the {plus} / {minus} buttons. **Zoom the map!**", @@ -2419,43 +2419,43 @@ "editor_townhall": "When a feature is selected, the *feature editor* is displayed alongside the map.", "preset_townhall": "The top part of the feature editor shows the feature's type. This point is a {preset}.", "fields_townhall": "The middle part of the feature editor contains *fields* showing the feature's attributes, such as its name and address.", - "close_townhall": "**Close the feature editor by hitting escape or pressing the {button} button in the upper corner.**", + "close_townhall": "**Close the feature editor by pressing `{esc}` or the {button} button in the upper corner.**", "search_street": "You can also search for features in the current view, or worldwide. **Search for '{name}'.**", "choose_street": "**Choose {name} from the list to select it.**", "selected_street": "Great! {name} is now selected.", - "editor_street": "The fields shown for a street are different than the fields that were shown for the town hall.{br}For this selected street, the feature editor shows fields like '{field1}' and '{field2}'. **Close the feature editor by hitting escape or pressing the {button} button.**", + "editor_street": "The fields shown for a street are different than the fields that were shown for the town hall.{br}For this selected street, the feature editor shows fields like '{field1}' and '{field2}'. **Close the feature editor by pressing `{esc}` the {button} button.**", "play": "Try exploring the map and selecting some other features to see what kinds of things can be added to OpenStreetMap. **When you are ready to continue to the next chapter, press '{next}'.**" }, "points": { "title": "Points", - "add_point": "*Points* can be used to represent features such as shops, restaurants, and monuments.{br}They mark a specific location, and describe what's there. **Press the {button} Point button to add a new point.**", - "place_point": "To place the new point on the map, position your mouse cursor where the point should go, then left-click or press the spacebar. **Move the mouse pointer over this building, then left-click or press the spacebar.**", + "add_point": "*Points* can be used to represent features such as shops, restaurants, and monuments.{br}They mark a specific location, and describe what's there. **Press the {point_icon} {point} button to add a new point.**", + "place_point": "To place the new point on the map, position your mouse cursor where the point should go, then {leftclick} left-click or press `{space}`. **Move the mouse pointer over this building, then left-click or press `{space}`.**", "place_point_touch": "To place the new point on the map, tap the location where it should go. **Tap the center of this building.**", "search_cafe": "There are many different features that can be represented by points. The point you just added is a cafe. **Search for '{preset}'.**", "choose_cafe": "**Choose {preset} from the list.**", "feature_editor": "The point is now marked as a cafe. Using the feature editor, we can add more information about the cafe.", "add_name": "In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure.{br}Let's pretend that you have local knowledge of this cafe, and you know its name. **Add a name for the cafe.**", - "add_close": "The feature editor will remember all of your changes automatically. **When you are finished adding the name, hit escape, enter, or press the {button} button to close the feature editor.**", + "add_close": "The feature editor will remember all of your changes automatically. **When you are finished adding the name, press `{esc}`, `{return}`, or the {button} button to close the feature editor.**", "reselect": "Often points will already exist, but have mistakes or be incomplete. We can edit existing points. **Select the cafe you just created.**", "update": "Let's fill in some more details for this cafe. You can change its name, add a cuisine, or add an address. **Change the cafe details.**", - "update_close": "**When you are finished updating the cafe, hit escape, enter, or press the {button} button to close the feature editor.**", - "rightclick": "You can right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed.{br}A right-click might be the same as a control-click, or a two-finger tap on a trackpad. **Right-click to select the point you created and show the edit menu.**", + "update_close": "**When you are finished updating the cafe, press `{esc}`, `{return}`, or the {button} button to close the feature editor.**", + "rightclick": "You can {rightclick} right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed.{br}A right-click might be the same as a control-click or two-finger click. **Right-click to select the point you created and show the edit menu.**", "edit_menu_touch": "You can long-press on any feature to see the *edit menu*, which shows a list of editing operations that can be performed. **Press-and-hold the point you created to show the edit menu.**", - "delete": "It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Press the {button} button to delete the point.**", - "undo": "You can always undo any changes up until you save your edits to OpenStreetMap. **Press the {button} button to undo the delete and get the point back.**", + "delete": "It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Press the {delete_icon} {delete} button to remove the point.**", + "undo": "You can always undo any changes up until you save your edits to OpenStreetMap. **Press the {undo_icon} {undo} button to get the point back.**", "play": "Now that you know how to create and edit points, try creating a few more points for practice! **When you are ready to continue to the next chapter, press '{next}'.**" }, "areas": { "title": "Areas", - "add_playground": "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can also be used for more detailed mapping of many features you might normally map as points. **Press the {button} Area button to add a new area.**", - "start_playground": "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Click or press spacebar to place a starting node on one of the corners of the playground.**", + "add_playground": "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can also be used for more detailed mapping of many features you might normally map as points. **Press the {area_icon} {area} button to add a new area.**", + "start_playground": "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Click or press `{space}` to place a starting node on one of the corners of the playground.**", "start_playground_touch": "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Tap to place a starting node on one of the corners of the playground.**", - "continue_playground": "Continue drawing the area by placing more nodes along the playground's edge. It is OK to connect the area to the existing walking paths.{br}Tip: You can hold down the '{alt}' key to prevent nodes from connecting to other features. **Continue drawing an area for the playground.**", - "finish_playground": "Finish the area by pressing enter, or clicking again on either the first or last node. **Finish drawing an area for the playground.**", - "finish_playground_touch": "Finish the area by tapping again on either the first or last node, or by pressing enter on a keyboard. **Finish drawing an area for the playground.**", + "continue_playground": "Continue drawing the area by placing more nodes along the playground's edge. It is OK to connect the area to the existing walking paths.{br}Tip: You can hold down the `{alt}` key to prevent nodes from connecting to other features. **Continue drawing an area for the playground.**", + "finish_playground": "Finish the area by pressing `{return}`, or clicking again on either the first or last node. **Finish drawing an area for the playground.**", + "finish_playground_touch": "Finish the area by tapping again on either the first or last node, or by pressing `{return}` on a keyboard. **Finish drawing an area for the playground.**", "search_playground": "**Search for '{preset}'.**", "choose_playground": "**Choose {preset} from the list.**", - "add_field": "This playground doesn't have an official name, so we won't add anything in the Name field.{br}Instead let's add some additional details about the playground to the Description field. **Open the Add Field list.**", + "add_field": "This playground doesn't have an official name, so we won't add anything in the {name} field.{br}Instead let's add some additional details about the playground to the {description} field. **Open the Add Field list.**", "choose_field": "**Choose {field} from the list.**", "retry_add_field": "You didn't select the {field} field. Let's try again.", "describe_playground": "**Add a description, then press the {button} button to close the feature editor.**", @@ -2463,61 +2463,61 @@ }, "lines": { "title": "Lines", - "add_line": "*Lines* are used to represent features such as roads, railroads, and rivers. **Click the {button} Line button to add a new line.**", + "add_line": "*Lines* are used to represent features such as roads, railroads, and rivers. **Click the {line_icon} {line} button to add a new line.**", "start_line": "Here is a road that is missing. Let's add it!{br}In OpenStreetMap, lines should be drawn down the center of the road. You can drag and zoom the map while drawing if necessary. **Start a new line by clicking at the top end of this missing road.**", - "intersect": "Click or press spacebar to add more nodes to the line.{br}Roads, and many other types of lines, are part of a larger network. It is important for these lines to be connected properly in order for routing applications to work. **Click on {name} to create an intersection connecting the two lines.**", + "intersect": "Click or press `{space}` to add more nodes to the line.{br}Roads, and many other types of lines, are part of a larger network. It is important for these lines to be connected properly in order for routing applications to work. **Click on {name} to create an intersection connecting the two lines.**", "retry_intersect": "The road needs to intersect {name}. Let's try again!", "continue_line": "Continue drawing the line for the new road. Remember that you can drag and zoom the map if needed.{br}When you are finished drawing, click on the last node again. **Finish drawing the road.**", "choose_category_road": "**Select {category} from the list.**", "choose_preset_residential": "There are many different types of roads, but this one is a residential road. **Choose the {preset} type.**", "retry_preset_residential": "You didn't select the {preset} type. **Click here to choose again.**", - "name_road": "**Give this road a name, then hit escape, enter, or click the {button} button to close the feature editor.**", + "name_road": "**Give this road a name, then press `{esc}`, `{return}`, or the {button} button to close the feature editor.**", "did_name_road": "Looks good! Next we will learn how to update the shape of a line.", "update_line": "Sometimes you will need to change the shape of an existing line. Here is a road that doesn't look quite right.", "add_node": "We can add some nodes to this line to improve its shape. One way to add a node is to double-click the line where you want to add a node. **Double-click on the line to create a new node.**", - "start_drag_endpoint": "When a line is selected, you can drag any of its nodes by clicking and holding down the left mouse button while you drag. **Drag the endpoint to the place where these roads should intersect.**", - "finish_drag_endpoint": "This spot looks good. **Release the left mouse button to finish dragging.**", + "start_drag_endpoint": "When a line is selected, you can drag any of its nodes by clicking and holding down the {leftclick} left mouse button while you drag. **Drag the endpoint to the place where these roads should intersect.**", + "finish_drag_endpoint": "This spot looks good. **Release the {leftclick} left mouse button to finish dragging.**", "start_drag_midpoint": "Small triangles are drawn at the *midpoints* between nodes. Another way to create a new node is to drag a midpoint to a new location. **Drag the midpoint triangle to create a new node along the curve of the road.**", - "continue_drag_midpoint": "This line is looking much better! Continue to adjust this line by double-clicking or dragging midpoints until the curve matches the road shape. **When you're happy with how the line looks, click OK.**", + "continue_drag_midpoint": "This line is looking much better! Continue to adjust this line by double-clicking or dragging midpoints until the curve matches the road shape. **When you're happy with how the line looks, click {ok}.**", "delete_lines": "It's OK to delete lines for roads that don't exist in the real world.{br}Here's an example where the city planned a {street} but never built it. We can improve this part of the map by deleting the extra lines.", - "rightclick_intersection": "The last real street is {street1}, so we will *split* {street2} at this intersection and remove everything above it. **Right click on the intersection node.**", - "split_intersection": "**Click on the {button} button to split {street}.**", - "retry_split": "You didn't click the Split button. Try again.", + "rightclick_intersection": "The last real street is {street1}, so we will *split* {street2} at this intersection and remove everything above it. **{rightclick} Right-click on the intersection node.**", + "split_intersection": "**Press the {split_icon} {split} button to divide {street}.**", + "retry_split": "You didn't press the {split_icon} {split} button. Try again.", "did_split_multi": "Good job! {street1} is now split into two pieces. The top part can be removed. **Click the top part of {street2} to select it.**", "did_split_single": "**Click the top part of {street2} to select it.**", - "multi_select": "{selected} is now selected. Let's also select {other1}. You can shift-click to select multiple things. **Shift-click on {other2}.**", - "multi_rightclick": "Good! Both lines to delete are now selected. **Right-click on one of the lines to show the edit menu.**", - "multi_delete": "**Click on the {button} button to delete the extra lines.**", - "retry_delete": "You didn't click the Delete button. Try again.", + "multi_select": "{selected} is now selected. Let's also select {other1}. You can hold `{shift}` while clicking to select multiple things. **Shift-click on {other2}.**", + "multi_rightclick": "Good! Both lines to delete are now selected. **{rightclick} Right-click on one of the lines to show the edit menu.**", + "multi_delete": "**Press the {delete_icon} {delete} button to remove the extra lines.**", + "retry_delete": "You didn't press the {delete_icon} {delete} button. Try again.", "play": "Great! Use the skills that you've learned in this chapter to practice editing some more lines. **When you are ready to continue to the next chapter, press '{next}'.**" }, "buildings": { "title": "Buildings", - "add_building": "OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Press the {button} Area button to add a new area.**", - "start_building": "Let's add this house to the map by tracing its outline.{br}Buildings should be traced around their footprint as accurately as possible. **Click or press spacebar to place a starting node on one of the corners of the building.**", - "continue_building": "Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details.{br}Finish the building by pressing enter, or clicking again on either the first or last node. **Finish tracing the building.**", + "add_building": "OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Press the {area_icon} {area} button to add a new area.**", + "start_building": "Let's add this house to the map by tracing its outline.{br}Buildings should be traced around their footprint as accurately as possible. **Click or press `{space}` to place a starting node on one of the corners of the building.**", + "continue_building": "Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details.{br}Finish the building by pressing `{return}`, or clicking again on either the first or last node. **Finish tracing the building.**", "retry_building": "It looks like you had some trouble placing the nodes at the building corners. Try again!", "choose_category_building": "**Choose {category} from the list.**", "choose_preset_house": "There are many different types of buildings, but this one is clearly a house.{br}If you're not sure of the type, it's OK to just choose the generic Building type. **Choose the {preset} type.**", - "close": "**Hit escape or click the {button} button to close the feature editor.**", - "rightclick_building": "**Right-click to select the building you created and show the edit menu.**", - "square_building": "The house that you just added will look even better with perfectly square corners. **Press the {button} button to square the building shape.**", - "retry_square": "You didn't press the {button} button. Try again.", + "close": "**Press `{esc}` or the {apply} button to close the feature editor.**", + "rightclick_building": "**{rightclick} Right-click to select the building you created and show the edit menu.**", + "square_building": "The house that you just added will look even better with perfectly square corners. **Press the {orthogonalize_icon} {orthogonalize} button to tidy up the building shape.**", + "retry_square": "You didn't press the {orthogonalize_icon} {orthogonalize} button. Try again.", "done_square": "See how the corners of the building moved into place? Let's learn another useful trick.", - "add_tank": "Next we'll trace this circular storage tank. **Press the {button} Area button to add a new area.**", - "start_tank": "Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge. **Click or press spacebar to place a starting node on the edge of the tank.**", - "continue_tank": "Add a few more nodes around the edge. The circle will be created outside the nodes that you draw.{br}Finish the area by pressing enter, or clicking again on either the first or last node. **Finish tracing the tank.**", + "add_tank": "Next we'll trace this circular storage tank. **Press the {area_icon} {area} button to add a new area.**", + "start_tank": "Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge. **Click or press `{space}` to place a starting node on the edge of the tank.**", + "continue_tank": "Add a few more nodes around the edge. The circle will be created outside the nodes that you draw.{br}Finish the area by pressing `{return}`, or clicking again on either the first or last node. **Finish tracing the tank.**", "search_tank": "**Search for '{preset}'.**", "choose_tank": "**Choose {preset} from the list.**", - "rightclick_tank": "**Right-click to select the storage tank you created and show the edit menu.**", - "circle_tank": "**Press the {button} button to make the tank a circle.**", - "retry_circle": "You didn't click the Circularize button. Try again.", + "rightclick_tank": "**{rightclick} Right-click to select the storage tank you created and show the edit menu.**", + "circle_tank": "**Press the {circularize_icon} {circularize} button to make the tank a circle.**", + "retry_circle": "You didn't click the {circularize_icon} {circularize} button. Try again.", "play": "Great Job! Practice tracing a few more buildings, and try some of the other commands on the edit menu. **When you are ready to continue to the next chapter, press '{next}'.**" }, "startediting": { "title": "Start Editing", - "help": "You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by pressing the {button} Help button or the '{key}' key.", - "shortcuts": "You can view a list of commands along with their keyboard shortcuts by pressing the '{key}' key.", + "help": "You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by pressing the {help_icon} {help} button or the `{help_key}` key.", + "shortcuts": "You can view a list of commands along with their keyboard shortcuts by pressing the `{shortcuts_key}` key.", "save": "Don't forget to regularly save your changes!", "start": "Start mapping!" } @@ -4826,7 +4826,8 @@ "terms": "guarded,manned" }, "support": { - "label": "Support" + "label": "Support", + "terms": "" }, "surface": { "label": "Surface", diff --git a/modules/ui/cmd.js b/modules/ui/cmd.js index c2203adb1..66784056a 100644 --- a/modules/ui/cmd.js +++ b/modules/ui/cmd.js @@ -53,7 +53,7 @@ uiCmd.display = function(code) { '↘': mac ? '↘ ' + t('shortcuts.key.pgdn') : t('shortcuts.key.pgdn'), '⇞': mac ? '⇞ ' + t('shortcuts.key.home') : t('shortcuts.key.home'), '⇟': mac ? '⇟ ' + t('shortcuts.key.end') : t('shortcuts.key.end'), - '↵': mac ? '↵ ' + t('shortcuts.key.return') : t('shortcuts.key.enter'), + '↵': mac ? '⏎ ' + t('shortcuts.key.return') : t('shortcuts.key.enter'), '⎋': mac ? '⎋ ' + t('shortcuts.key.esc') : t('shortcuts.key.esc'), '☰': mac ? '☰ ' + t('shortcuts.key.menu') : t('shortcuts.key.menu'), }; diff --git a/modules/ui/intro/area.js b/modules/ui/intro/area.js index 78a69ef64..27fa81204 100644 --- a/modules/ui/intro/area.js +++ b/modules/ui/intro/area.js @@ -13,14 +13,14 @@ import { t } from '../../core/localizer'; import { modeBrowse } from '../../modes/browse'; import { modeSelect } from '../../modes/select'; import { utilRebind } from '../../util/rebind'; -import { uiCmd } from '../cmd'; -import { icon, pad, transitionTime } from './helper'; +import { helpString, icon, pad, transitionTime } from './helper'; export function uiIntroArea(context, reveal) { var dispatch = d3_dispatch('done'); var playground = [-85.63552, 41.94159]; var playgroundPreset = presetManager.item('leisure/playground'); + var nameField = presetManager.field('name'); var descriptionField = presetManager.field('description'); var timeouts = []; var _areaID; @@ -60,7 +60,7 @@ export function uiIntroArea(context, reveal) { timeout(function() { var tooltip = reveal('button.add-area', - t('intro.areas.add_playground', { button: icon('#iD-icon-area', 'pre-text') })); + helpString('intro.areas.add_playground')); tooltip.selectAll('.popover-inner') .insert('svg', 'span') @@ -92,13 +92,13 @@ export function uiIntroArea(context, reveal) { timeout(function() { var textId = context.lastPointerType() === 'mouse' ? 'start_playground' : 'start_playground_touch'; revealPlayground(playground, - t('intro.areas.' + textId), { duration: 250 } + helpString('intro.areas.' + textId), { duration: 250 } ); timeout(function() { context.map().on('move.intro drawn.intro', function() { revealPlayground(playground, - t('intro.areas.' + textId), { duration: 0 } + helpString('intro.areas.' + textId), { duration: 0 } ); }); context.on('enter.intro', function(mode) { @@ -124,14 +124,14 @@ export function uiIntroArea(context, reveal) { _areaID = null; revealPlayground(playground, - t('intro.areas.continue_playground', { alt: uiCmd.display('⌥') }), + helpString('intro.areas.continue_playground'), { duration: 250 } ); timeout(function() { context.map().on('move.intro drawn.intro', function() { revealPlayground(playground, - t('intro.areas.continue_playground', { alt: uiCmd.display('⌥') }), + helpString('intro.areas.continue_playground'), { duration: 0 } ); }); @@ -169,13 +169,13 @@ export function uiIntroArea(context, reveal) { _areaID = null; var textId = context.lastPointerType() === 'mouse' ? 'finish_playground' : 'finish_playground_touch'; revealPlayground(playground, - t('intro.areas.' + textId), { duration: 250 } + helpString('intro.areas.' + textId), { duration: 250 } ); timeout(function() { context.map().on('move.intro drawn.intro', function() { revealPlayground(playground, - t('intro.areas.' + textId), { duration: 0 } + helpString('intro.areas.' + textId), { duration: 0 } ); }); }, 250); // after reveal @@ -220,7 +220,7 @@ export function uiIntroArea(context, reveal) { .on('keyup.intro', checkPresetSearch); reveal('.preset-search-input', - t('intro.areas.search_playground', { preset: playgroundPreset.name() }) + helpString('intro.areas.search_playground', { preset: playgroundPreset.name() }) ); }, 400); // after preset list pane visible.. @@ -244,7 +244,7 @@ export function uiIntroArea(context, reveal) { .on('keyup.intro', checkPresetSearch); reveal('.preset-search-input', - t('intro.areas.search_playground', { preset: playgroundPreset.name() }) + helpString('intro.areas.search_playground', { preset: playgroundPreset.name() }) ); context.history().on('change.intro', null); @@ -256,7 +256,7 @@ export function uiIntroArea(context, reveal) { if (first.classed('preset-leisure-playground')) { reveal(first.select('.preset-list-button').node(), - t('intro.areas.choose_playground', { preset: playgroundPreset.name() }), + helpString('intro.areas.choose_playground', { preset: playgroundPreset.name() }), { duration: 300 } ); @@ -328,7 +328,10 @@ export function uiIntroArea(context, reveal) { timeout(function() { reveal('.more-fields .combobox-input', - t('intro.areas.add_field'), + helpString('intro.areas.add_field', { + name: nameField.label(), + description: descriptionField.label() + }), { duration: 300 } ); @@ -393,7 +396,7 @@ export function uiIntroArea(context, reveal) { }, 300); reveal('div.combobox', - t('intro.areas.choose_field', { field: descriptionField.label() }), + helpString('intro.areas.choose_field', { field: descriptionField.label() }), { duration: 300 } ); @@ -430,7 +433,7 @@ export function uiIntroArea(context, reveal) { }); reveal('.entity-editor-pane', - t('intro.areas.describe_playground', { button: icon('#iD-icon-apply', 'pre-text') }), + helpString('intro.areas.describe_playground', { button: icon('#iD-icon-apply', 'pre-text') }), { duration: 300 } ); @@ -454,7 +457,7 @@ export function uiIntroArea(context, reveal) { context.container().select('.inspector-wrap .panewrap').style('right', '0%'); reveal('.entity-editor-pane', - t('intro.areas.retry_add_field', { field: descriptionField.label() }), { + helpString('intro.areas.retry_add_field', { field: descriptionField.label() }), { buttonText: t('intro.ok'), buttonCallback: function() { continueTo(clickAddField); } }); @@ -473,7 +476,7 @@ export function uiIntroArea(context, reveal) { function play() { dispatch.call('done'); reveal('.ideditor', - t('intro.areas.play', { next: t('intro.lines.title') }), { + helpString('intro.areas.play', { next: t('intro.lines.title') }), { tooltipBox: '.intro-nav-wrap .chapter-line', buttonText: t('intro.ok'), buttonCallback: function() { reveal('.ideditor'); } diff --git a/modules/ui/intro/building.js b/modules/ui/intro/building.js index ebd5fc0c0..551e60efc 100644 --- a/modules/ui/intro/building.js +++ b/modules/ui/intro/building.js @@ -9,7 +9,7 @@ import { t } from '../../core/localizer'; import { modeBrowse } from '../../modes/browse'; import { modeSelect } from '../../modes/select'; import { utilArrayUniq, utilRebind } from '../../util'; -import { icon, pad, isMostlySquare, selectMenuItem, transitionTime } from './helper'; +import { helpString, pad, isMostlySquare, selectMenuItem, transitionTime } from './helper'; export function uiIntroBuilding(context, reveal) { @@ -65,7 +65,7 @@ export function uiIntroBuilding(context, reveal) { timeout(function() { var tooltip = reveal('button.add-area', - t('intro.buildings.add_building', { button: icon('#iD-icon-area', 'pre-text') })); + helpString('intro.buildings.add_building')); tooltip.selectAll('.popover-inner') .insert('svg', 'span') @@ -95,10 +95,10 @@ export function uiIntroBuilding(context, reveal) { context.map().zoomEase(20, 500); timeout(function() { - revealHouse(house, t('intro.buildings.start_building')); + revealHouse(house, helpString('intro.buildings.start_building')); context.map().on('move.intro drawn.intro', function() { - revealHouse(house, t('intro.buildings.start_building'), { duration: 0 }); + revealHouse(house, helpString('intro.buildings.start_building'), { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -123,10 +123,10 @@ export function uiIntroBuilding(context, reveal) { _houseID = null; - revealHouse(house, t('intro.buildings.continue_building')); + revealHouse(house, helpString('intro.buildings.continue_building')); context.map().on('move.intro drawn.intro', function() { - revealHouse(house, t('intro.buildings.continue_building'), { duration: 0 }); + revealHouse(house, helpString('intro.buildings.continue_building'), { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -162,12 +162,12 @@ export function uiIntroBuilding(context, reveal) { function retryHouse() { var onClick = function() { continueTo(addHouse); }; - revealHouse(house, t('intro.buildings.retry_building'), + revealHouse(house, helpString('intro.buildings.retry_building'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); context.map().on('move.intro drawn.intro', function() { - revealHouse(house, t('intro.buildings.retry_building'), + revealHouse(house, helpString('intro.buildings.retry_building'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick } ); }); @@ -198,7 +198,7 @@ export function uiIntroBuilding(context, reveal) { var button = context.container().select('.preset-category-building .preset-list-button'); reveal(button.node(), - t('intro.buildings.choose_category_building', { category: buildingCatetory.name() }) + helpString('intro.buildings.choose_category_building', { category: buildingCatetory.name() }) ); button.on('click.intro', function() { @@ -247,7 +247,7 @@ export function uiIntroBuilding(context, reveal) { var button = context.container().select('.preset-building-house .preset-list-button'); reveal(button.node(), - t('intro.buildings.choose_preset_house', { preset: housePreset.name() }), + helpString('intro.buildings.choose_preset_house', { preset: housePreset.name() }), { duration: 300 } ); @@ -294,7 +294,7 @@ export function uiIntroBuilding(context, reveal) { timeout(function() { reveal('.entity-editor-pane', - t('intro.buildings.close', { button: icon('#iD-icon-apply', 'pre-text') }) + helpString('intro.buildings.close') ); }, 500); @@ -329,7 +329,7 @@ export function uiIntroBuilding(context, reveal) { }); context.map().on('move.intro drawn.intro', function() { - revealHouse(house, t('intro.buildings.rightclick_building'), { duration: 0 }); + revealHouse(house, helpString('intro.buildings.rightclick_building'), { duration: 0 }); }); context.history().on('change.intro', function() { @@ -356,7 +356,7 @@ export function uiIntroBuilding(context, reveal) { var wasChanged = false; reveal('.edit-menu', - t('intro.buildings.square_building', { button: icon('#iD-operation-orthogonalize', 'pre-text') }), + helpString('intro.buildings.square_building'), { padding: 50 } ); @@ -373,7 +373,7 @@ export function uiIntroBuilding(context, reveal) { if (!wasChanged && !node) { return continueTo(rightClickHouse); } reveal('.edit-menu', - t('intro.buildings.square_building', { button: icon('#iD-operation-orthogonalize', 'pre-text') }), + helpString('intro.buildings.square_building'), { duration: 0, padding: 50 } ); }); @@ -404,7 +404,7 @@ export function uiIntroBuilding(context, reveal) { function retryClickSquare() { context.enter(modeBrowse(context)); - revealHouse(house, t('intro.buildings.retry_square', { button: icon('#iD-operation-orthogonalize', 'pre-text') }), { + revealHouse(house, helpString('intro.buildings.retry_square'), { buttonText: t('intro.ok'), buttonCallback: function() { continueTo(rightClickHouse); } }); @@ -418,7 +418,7 @@ export function uiIntroBuilding(context, reveal) { function doneSquare() { context.history().checkpoint('doneSquare'); - revealHouse(house, t('intro.buildings.done_square'), { + revealHouse(house, helpString('intro.buildings.done_square'), { buttonText: t('intro.ok'), buttonCallback: function() { continueTo(addTank); } }); @@ -440,7 +440,7 @@ export function uiIntroBuilding(context, reveal) { timeout(function() { reveal('button.add-area', - t('intro.buildings.add_tank', { button: icon('#iD-icon-area', 'pre-text') }) + helpString('intro.buildings.add_tank') ); context.on('enter.intro', function(mode) { @@ -464,10 +464,10 @@ export function uiIntroBuilding(context, reveal) { _tankID = null; timeout(function() { - revealTank(tank, t('intro.buildings.start_tank')); + revealTank(tank, helpString('intro.buildings.start_tank')); context.map().on('move.intro drawn.intro', function() { - revealTank(tank, t('intro.buildings.start_tank'), { duration: 0 }); + revealTank(tank, helpString('intro.buildings.start_tank'), { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -492,10 +492,10 @@ export function uiIntroBuilding(context, reveal) { _tankID = null; - revealTank(tank, t('intro.buildings.continue_tank')); + revealTank(tank, helpString('intro.buildings.continue_tank')); context.map().on('move.intro drawn.intro', function() { - revealTank(tank, t('intro.buildings.continue_tank'), { duration: 0 }); + revealTank(tank, helpString('intro.buildings.continue_tank'), { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -538,7 +538,7 @@ export function uiIntroBuilding(context, reveal) { .on('keyup.intro', checkPresetSearch); reveal('.preset-search-input', - t('intro.buildings.search_tank', { preset: tankPreset.name() }) + helpString('intro.buildings.search_tank', { preset: tankPreset.name() }) ); }, 400); // after preset list pane visible.. @@ -562,7 +562,7 @@ export function uiIntroBuilding(context, reveal) { .on('keyup.intro', checkPresetSearch); reveal('.preset-search-input', - t('intro.buildings.search_tank', { preset: tankPreset.name() }) + helpString('intro.buildings.search_tank', { preset: tankPreset.name() }) ); context.history().on('change.intro', null); @@ -574,7 +574,7 @@ export function uiIntroBuilding(context, reveal) { if (first.classed('preset-man_made-storage_tank')) { reveal(first.select('.preset-list-button').node(), - t('intro.buildings.choose_tank', { preset: tankPreset.name() }), + helpString('intro.buildings.choose_tank', { preset: tankPreset.name() }), { duration: 300 } ); @@ -615,7 +615,7 @@ export function uiIntroBuilding(context, reveal) { timeout(function() { reveal('.entity-editor-pane', - t('intro.buildings.close', { button: icon('#iD-icon-apply', 'pre-text') }) + helpString('intro.buildings.close') ); }, 500); @@ -646,10 +646,10 @@ export function uiIntroBuilding(context, reveal) { }, 50); // after menu visible }); - revealTank(tank, t('intro.buildings.rightclick_tank')); + revealTank(tank, helpString('intro.buildings.rightclick_tank')); context.map().on('move.intro drawn.intro', function() { - revealTank(tank, t('intro.buildings.rightclick_tank'), { duration: 0 }); + revealTank(tank, helpString('intro.buildings.rightclick_tank'), { duration: 0 }); }); context.history().on('change.intro', function() { @@ -678,7 +678,7 @@ export function uiIntroBuilding(context, reveal) { var wasChanged = false; reveal('.edit-menu', - t('intro.buildings.circle_tank', { button: icon('#iD-operation-circularize', 'pre-text') }), + helpString('intro.buildings.circle_tank'), { padding: 50 } ); @@ -695,7 +695,7 @@ export function uiIntroBuilding(context, reveal) { if (!wasChanged && !node) { return continueTo(rightClickTank); } reveal('.edit-menu', - t('intro.buildings.circle_tank', { button: icon('#iD-operation-circularize', 'pre-text') }), + helpString('intro.buildings.circle_tank'), { duration: 0, padding: 50 } ); }); @@ -726,7 +726,7 @@ export function uiIntroBuilding(context, reveal) { function retryClickCircle() { context.enter(modeBrowse(context)); - revealTank(tank, t('intro.buildings.retry_circle'), { + revealTank(tank, helpString('intro.buildings.retry_circle'), { buttonText: t('intro.ok'), buttonCallback: function() { continueTo(rightClickTank); } }); @@ -740,7 +740,7 @@ export function uiIntroBuilding(context, reveal) { function play() { dispatch.call('done'); reveal('.ideditor', - t('intro.buildings.play', { next: t('intro.startediting.title') }), { + helpString('intro.buildings.play', { next: t('intro.startediting.title') }), { tooltipBox: '.intro-nav-wrap .chapter-startEditing', buttonText: t('intro.ok'), buttonCallback: function() { reveal('.ideditor'); } diff --git a/modules/ui/intro/helper.js b/modules/ui/intro/helper.js index 7249d2e81..cdae6582d 100644 --- a/modules/ui/intro/helper.js +++ b/modules/ui/intro/helper.js @@ -1,6 +1,6 @@ -import { t } from '../../core/localizer'; +import { t, localizer } from '../../core/localizer'; import { geoSphericalDistance, geoVecNormalizedDot } from '../../geo'; - +import { uiCmd } from '../cmd'; export function pointBox(loc, context) { var rect = context.surfaceRect(); @@ -42,6 +42,91 @@ export function icon(name, svgklass, useklass) { (useklass ? ' class="' + useklass + '"' : '') + '>'; } +var helpStringReplacements; + +// Returns the localized string for `id` with a standardized set of icon, key, and +// label replacements suitable for tutorials and documentation. Optionally supplemented +// with custom `replacements` +export function helpString(id, replacements) { + // only load these the first time + if (!helpStringReplacements) helpStringReplacements = { + // insert icons corresponding to various UI elements + point_icon: icon('#iD-icon-point', 'pre-text'), + line_icon: icon('#iD-icon-line', 'pre-text'), + area_icon: icon('#iD-icon-area', 'pre-text'), + note_icon: icon('#iD-icon-note', 'pre-text add-note'), + plus: icon('#iD-icon-plus', 'pre-text'), + minus: icon('#iD-icon-minus', 'pre-text'), + move_icon: icon('#iD-operation-move', 'pre-text operation'), + merge_icon: icon('#iD-operation-merge', 'pre-text operation'), + delete_icon: icon('#iD-operation-delete', 'pre-text operation'), + circularize_icon: icon('#iD-operation-circularize', 'pre-text operation'), + split_icon: icon('#iD-operation-split', 'pre-text operation'), + orthogonalize_icon: icon('#iD-operation-orthogonalize', 'pre-text operation'), + disconnect_icon: icon('#iD-operation-disconnect', 'pre-text operation'), + layers_icon: icon('#iD-icon-layers', 'pre-text'), + data_icon: icon('#iD-icon-data', 'pre-text'), + inspect: icon('#iD-icon-inspect', 'pre-text'), + close: icon('#iD-icon-close', 'pre-text'), + apply: icon('#iD-icon-apply', 'pre-text'), + help_icon: icon('#iD-icon-help', 'pre-text'), + undo_icon: icon(localizer.textDirection() === 'rtl' ? '#iD-icon-redo' : '#iD-icon-undo', 'pre-text'), + redo_icon: icon(localizer.textDirection() === 'rtl' ? '#iD-icon-undo' : '#iD-icon-redo', 'pre-text'), + save_icon: icon('#iD-icon-save', 'pre-text'), + leftclick: icon('#iD-walkthrough-mouse', 'pre-text mouseclick', 'left'), + rightclick: icon('#iD-walkthrough-mouse', 'pre-text mouseclick', 'right'), + + // insert keys; may be localized and platform-dependent + shift: uiCmd.display('⇧'), + alt: uiCmd.display('⌥'), + return: uiCmd.display('↵'), + esc: t('shortcuts.key.esc'), + space: t('shortcuts.key.space'), + add_note_key: t('modes.add_note.key'), + help_key: t('help.key'), + shortcuts_key: t('shortcuts.toggle.key'), + + // reference localized UI labels directly so that they'll always match + save: t('save.title'), + undo: t('undo.title'), + redo: t('redo.title'), + upload: t('commit.save'), + point: t('modes.add_point.title'), + line: t('modes.add_line.title'), + area: t('modes.add_area.title'), + note: t('modes.add_note.title'), + delete: t('operations.delete.title'), + move: t('operations.move.title'), + orthogonalize: t('operations.orthogonalize.title'), + circularize: t('operations.circularize.title'), + merge: t('operations.merge.title'), + disconnect: t('operations.disconnect.title'), + split: t('operations.split.title'), + map_data: t('map_data.title'), + fields: t('inspector.fields'), + tags: t('inspector.tags'), + relations: t('inspector.relations'), + new_relation: t('inspector.new_relation'), + turn_restrictions: t('presets.fields.restrictions.label'), + background_settings: t('background.description'), + imagery_offset: t('background.fix_misalignment'), + start_the_walkthrough: t('splash.walkthrough'), + help: t('help.title'), + ok: t('intro.ok') + }; + + var reps; + if (replacements) { + reps = Object.assign(replacements, helpStringReplacements); + } else { + reps = helpStringReplacements; + } + + return t(id, reps) + // use keyboard key styling for shortcuts + .replace(/\`(.*?)\`/g, '$1'); +} + function slugify(text) { return text.toString().toLowerCase() diff --git a/modules/ui/intro/line.js b/modules/ui/intro/line.js index 289ab266e..a7a522cb9 100644 --- a/modules/ui/intro/line.js +++ b/modules/ui/intro/line.js @@ -11,7 +11,7 @@ import { geoSphericalDistance } from '../../geo'; import { modeBrowse } from '../../modes/browse'; import { modeSelect } from '../../modes/select'; import { utilRebind } from '../../util/rebind'; -import { icon, pad, selectMenuItem, transitionTime } from './helper'; +import { helpString, icon, pad, selectMenuItem, transitionTime } from './helper'; export function uiIntroLine(context, reveal) { @@ -66,7 +66,7 @@ export function uiIntroLine(context, reveal) { timeout(function() { var tooltip = reveal('button.add-line', - t('intro.lines.add_line', { button: icon('#iD-icon-line', 'pre-text') })); + helpString('intro.lines.add_line')); tooltip.selectAll('.popover-inner') .insert('svg', 'span') @@ -95,13 +95,13 @@ export function uiIntroLine(context, reveal) { var padding = 70 * Math.pow(2, context.map().zoom() - 18); var box = pad(tulipRoadStart, padding, context); box.height = box.height + 100; - reveal(box, t('intro.lines.start_line')); + reveal(box, helpString('intro.lines.start_line')); context.map().on('move.intro drawn.intro', function() { padding = 70 * Math.pow(2, context.map().zoom() - 18); box = pad(tulipRoadStart, padding, context); box.height = box.height + 100; - reveal(box, t('intro.lines.start_line'), { duration: 0 }); + reveal(box, helpString('intro.lines.start_line'), { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -128,7 +128,7 @@ export function uiIntroLine(context, reveal) { var box = pad(tulipRoadMidpoint, padding, context); box.height = box.height * 2; reveal(box, - t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }) + helpString('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }) ); context.map().on('move.intro drawn.intro', function() { @@ -136,7 +136,7 @@ export function uiIntroLine(context, reveal) { box = pad(tulipRoadMidpoint, padding, context); box.height = box.height * 2; reveal(box, - t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }), + helpString('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }), { duration: 0 } ); }); @@ -186,7 +186,7 @@ export function uiIntroLine(context, reveal) { var box = pad(tulipRoadIntersection, 80, context); reveal(box, - t('intro.lines.retry_intersect', { name: t('intro.graph.name.flower-street') }) + helpString('intro.lines.retry_intersect', { name: t('intro.graph.name.flower-street') }) ); timeout(chapter.restart, 3000); @@ -200,7 +200,7 @@ export function uiIntroLine(context, reveal) { context.map().centerEase(tulipRoadIntersection, 500); - reveal('.surface', t('intro.lines.continue_line')); + reveal('.surface', helpString('intro.lines.continue_line')); context.on('enter.intro', function(mode) { if (mode.id === 'draw-line') @@ -236,7 +236,7 @@ export function uiIntroLine(context, reveal) { context.container().select('.inspector-wrap .panewrap').style('right', '-100%'); reveal(button.node(), - t('intro.lines.choose_category_road', { category: roadCategory.name() }) + helpString('intro.lines.choose_category_road', { category: roadCategory.name() }) ); button.on('click.intro', function() { @@ -276,7 +276,7 @@ export function uiIntroLine(context, reveal) { timeout(function() { reveal(subgrid.node(), - t('intro.lines.choose_preset_residential', { preset: residentialPreset.name() }), + helpString('intro.lines.choose_preset_residential', { preset: residentialPreset.name() }), { tooltipBox: '.preset-highway-residential .preset-list-button', duration: 300 } ); }, 300); @@ -304,7 +304,7 @@ export function uiIntroLine(context, reveal) { var button = context.container().select('.entity-editor-pane .preset-list-button'); reveal(button.node(), - t('intro.lines.retry_preset_residential', { preset: residentialPreset.name() }) + helpString('intro.lines.retry_preset_residential', { preset: residentialPreset.name() }) ); button.on('click.intro', function() { @@ -329,7 +329,7 @@ export function uiIntroLine(context, reveal) { timeout(function() { reveal('.entity-editor-pane', - t('intro.lines.name_road', { button: icon('#iD-icon-apply', 'pre-text') }), + helpString('intro.lines.name_road', { button: icon('#iD-icon-apply', 'pre-text') }), { tooltipClass: 'intro-lines-name_road' } ); }, 500); @@ -345,7 +345,7 @@ export function uiIntroLine(context, reveal) { context.history().checkpoint('doneAddLine'); timeout(function() { - reveal('.surface', t('intro.lines.did_name_road'), { + reveal('.surface', helpString('intro.lines.did_name_road'), { buttonText: t('intro.ok'), buttonCallback: function() { continueTo(updateLine); } }); @@ -372,14 +372,14 @@ export function uiIntroLine(context, reveal) { var box = pad(woodRoadDragMidpoint, padding, context); var advance = function() { continueTo(addNode); }; - reveal(box, t('intro.lines.update_line'), + reveal(box, helpString('intro.lines.update_line'), { buttonText: t('intro.ok'), buttonCallback: advance } ); context.map().on('move.intro drawn.intro', function() { var padding = 250 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragMidpoint, padding, context); - reveal(box, t('intro.lines.update_line'), + reveal(box, helpString('intro.lines.update_line'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance } ); }); @@ -400,12 +400,12 @@ export function uiIntroLine(context, reveal) { var padding = 40 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadAddNode, padding, context); - reveal(box, t('intro.lines.add_node')); + reveal(box, helpString('intro.lines.add_node')); context.map().on('move.intro drawn.intro', function() { var padding = 40 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadAddNode, padding, context); - reveal(box, t('intro.lines.add_node'), { duration: 0 }); + reveal(box, helpString('intro.lines.add_node'), { duration: 0 }); }); context.history().on('change.intro', function(changed) { @@ -438,7 +438,7 @@ export function uiIntroLine(context, reveal) { } var padding = 100 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragEndpoint, padding, context); - reveal(box, t('intro.lines.start_drag_endpoint')); + reveal(box, helpString('intro.lines.start_drag_endpoint')); context.map().on('move.intro drawn.intro', function() { if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) { @@ -446,7 +446,7 @@ export function uiIntroLine(context, reveal) { } var padding = 100 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragEndpoint, padding, context); - reveal(box, t('intro.lines.start_drag_endpoint'), { duration: 0 }); + reveal(box, helpString('intro.lines.start_drag_endpoint'), { duration: 0 }); var entity = context.entity(woodRoadEndID); if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) <= 4) { @@ -468,7 +468,7 @@ export function uiIntroLine(context, reveal) { var padding = 100 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragEndpoint, padding, context); - reveal(box, t('intro.lines.finish_drag_endpoint')); + reveal(box, helpString('intro.lines.finish_drag_endpoint')); context.map().on('move.intro drawn.intro', function() { if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) { @@ -476,7 +476,7 @@ export function uiIntroLine(context, reveal) { } var padding = 100 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragEndpoint, padding, context); - reveal(box, t('intro.lines.finish_drag_endpoint'), { duration: 0 }); + reveal(box, helpString('intro.lines.finish_drag_endpoint'), { duration: 0 }); var entity = context.entity(woodRoadEndID); if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) > 4) { @@ -506,7 +506,7 @@ export function uiIntroLine(context, reveal) { var padding = 80 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragMidpoint, padding, context); - reveal(box, t('intro.lines.start_drag_midpoint')); + reveal(box, helpString('intro.lines.start_drag_midpoint')); context.map().on('move.intro drawn.intro', function() { if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) { @@ -514,7 +514,7 @@ export function uiIntroLine(context, reveal) { } var padding = 80 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragMidpoint, padding, context); - reveal(box, t('intro.lines.start_drag_midpoint'), { duration: 0 }); + reveal(box, helpString('intro.lines.start_drag_midpoint'), { duration: 0 }); }); context.history().on('change.intro', function(changed) { @@ -553,7 +553,7 @@ export function uiIntroLine(context, reveal) { continueTo(deleteLines); }; - reveal(box, t('intro.lines.continue_drag_midpoint'), + reveal(box, helpString('intro.lines.continue_drag_midpoint'), { buttonText: t('intro.ok'), buttonCallback: advance } ); @@ -564,7 +564,7 @@ export function uiIntroLine(context, reveal) { var padding = 100 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragEndpoint, padding, context); box.height += 400; - reveal(box, t('intro.lines.continue_drag_midpoint'), + reveal(box, helpString('intro.lines.continue_drag_midpoint'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance } ); }); @@ -597,7 +597,7 @@ export function uiIntroLine(context, reveal) { box.height += 400; var advance = function() { continueTo(rightClickIntersection); }; - reveal(box, t('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }), + reveal(box, helpString('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }), { buttonText: t('intro.ok'), buttonCallback: advance } ); @@ -606,7 +606,7 @@ export function uiIntroLine(context, reveal) { var box = pad(deleteLinesLoc, padding, context); box.top -= 200; box.height += 400; - reveal(box, t('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }), + reveal(box, helpString('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }), { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance } ); }); @@ -636,14 +636,14 @@ export function uiIntroLine(context, reveal) { timeout(function() { var padding = 60 * Math.pow(2, context.map().zoom() - 18); var box = pad(eleventhAvenueEnd, padding, context); - reveal(box, t('intro.lines.rightclick_intersection', + reveal(box, helpString('intro.lines.rightclick_intersection', { street1: t('intro.graph.name.11th-avenue'), street2: t('intro.graph.name.washington-street') }) ); context.map().on('move.intro drawn.intro', function() { var padding = 60 * Math.pow(2, context.map().zoom() - 18); var box = pad(eleventhAvenueEnd, padding, context); - reveal(box, t('intro.lines.rightclick_intersection', + reveal(box, helpString('intro.lines.rightclick_intersection', { street1: t('intro.graph.name.11th-avenue'), street2: t('intro.graph.name.washington-street') }), { duration: 0 } ); @@ -691,8 +691,8 @@ export function uiIntroLine(context, reveal) { var wasChanged = false; _washingtonSegmentID = null; - reveal('.edit-menu', t('intro.lines.split_intersection', - { button: icon('#iD-operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') }), + reveal('.edit-menu', helpString('intro.lines.split_intersection', + { street: t('intro.graph.name.washington-street') }), { padding: 50 } ); @@ -700,8 +700,8 @@ export function uiIntroLine(context, reveal) { var node = selectMenuItem(context, 'split').node(); if (!wasChanged && !node) { return continueTo(rightClickIntersection); } - reveal('.edit-menu', t('intro.lines.split_intersection', - { button: icon('#iD-operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') }), + reveal('.edit-menu', helpString('intro.lines.split_intersection', + { street: t('intro.graph.name.washington-street') }), { duration: 0, padding: 50 } ); }); @@ -734,14 +734,14 @@ export function uiIntroLine(context, reveal) { var padding = 60 * Math.pow(2, context.map().zoom() - 18); var box = pad(eleventhAvenueEnd, padding, context); - reveal(box, t('intro.lines.retry_split'), + reveal(box, helpString('intro.lines.retry_split'), { buttonText: t('intro.ok'), buttonCallback: advance } ); context.map().on('move.intro drawn.intro', function() { var padding = 60 * Math.pow(2, context.map().zoom() - 18); var box = pad(eleventhAvenueEnd, padding, context); - reveal(box, t('intro.lines.retry_split'), + reveal(box, helpString('intro.lines.retry_split'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance } ); }); @@ -769,7 +769,7 @@ export function uiIntroLine(context, reveal) { var padding = 200 * Math.pow(2, context.map().zoom() - 18); var box = pad(twelfthAvenue, padding, context); box.width = box.width / 2; - reveal(box, t(string, { street1: street, street2: street }), + reveal(box, helpString(string, { street1: street, street2: street }), { duration: 500 } ); @@ -780,7 +780,7 @@ export function uiIntroLine(context, reveal) { var padding = 200 * Math.pow(2, context.map().zoom() - 18); var box = pad(twelfthAvenue, padding, context); box.width = box.width / 2; - reveal(box, t(string, { street1: street, street2: street }), + reveal(box, helpString(string, { street1: street, street2: street }), { duration: 0 } ); }); @@ -850,7 +850,7 @@ export function uiIntroLine(context, reveal) { } reveal(box, - t('intro.lines.multi_select', { selected: selected, other1: other, other2: other }) + helpString('intro.lines.multi_select', { selected: selected, other1: other, other2: other }) ); context.map().on('move.intro drawn.intro', function() { @@ -869,7 +869,7 @@ export function uiIntroLine(context, reveal) { } reveal(box, - t('intro.lines.multi_select', { selected: selected, other1: other, other2: other }), + helpString('intro.lines.multi_select', { selected: selected, other1: other, other2: other }), { duration: 0 } ); }); @@ -909,12 +909,12 @@ export function uiIntroLine(context, reveal) { var padding = 200 * Math.pow(2, context.map().zoom() - 18); var box = pad(twelfthAvenue, padding, context); - reveal(box, t('intro.lines.multi_rightclick')); + reveal(box, helpString('intro.lines.multi_rightclick')); context.map().on('move.intro drawn.intro', function() { var padding = 200 * Math.pow(2, context.map().zoom() - 18); var box = pad(twelfthAvenue, padding, context); - reveal(box, t('intro.lines.multi_rightclick'), { duration: 0 }); + reveal(box, helpString('intro.lines.multi_rightclick'), { duration: 0 }); }); d3_select(window).on('click.intro contextmenu.intro', function() { @@ -967,13 +967,13 @@ export function uiIntroLine(context, reveal) { if (!node) return continueTo(multiRightClick); reveal('.edit-menu', - t('intro.lines.multi_delete', { button: icon('#iD-operation-delete', 'pre-text') }), + helpString('intro.lines.multi_delete'), { padding: 50 } ); context.map().on('move.intro drawn.intro', function() { reveal('.edit-menu', - t('intro.lines.multi_delete', { button: icon('#iD-operation-delete', 'pre-text') }), + helpString('intro.lines.multi_delete'), { duration: 0, padding: 50 } ); }); @@ -1006,7 +1006,7 @@ export function uiIntroLine(context, reveal) { var padding = 200 * Math.pow(2, context.map().zoom() - 18); var box = pad(twelfthAvenue, padding, context); - reveal(box, t('intro.lines.retry_delete'), { + reveal(box, helpString('intro.lines.retry_delete'), { buttonText: t('intro.ok'), buttonCallback: function() { continueTo(multiSelect); } }); @@ -1020,7 +1020,7 @@ export function uiIntroLine(context, reveal) { function play() { dispatch.call('done'); reveal('.ideditor', - t('intro.lines.play', { next: t('intro.buildings.title') }), { + helpString('intro.lines.play', { next: t('intro.buildings.title') }), { tooltipBox: '.intro-nav-wrap .chapter-building', buttonText: t('intro.ok'), buttonCallback: function() { reveal('.ideditor'); } diff --git a/modules/ui/intro/navigation.js b/modules/ui/intro/navigation.js index 8fe4cc3f5..e0dbb807b 100644 --- a/modules/ui/intro/navigation.js +++ b/modules/ui/intro/navigation.js @@ -10,7 +10,7 @@ import { t } from '../../core/localizer'; import { modeBrowse } from '../../modes/browse'; import { modeSelect } from '../../modes/select'; import { utilRebind } from '../../util/rebind'; -import { icon, pointBox, transitionTime } from './helper'; +import { helpString, icon, pointBox, transitionTime } from './helper'; export function uiIntroNavigation(context, reveal) { @@ -60,9 +60,9 @@ export function uiIntroNavigation(context, reveal) { var textId = context.lastPointerType() === 'mouse' ? 'drag' : 'drag_touch'; - reveal('.surface', t('intro.navigation.' + textId)); + reveal('.surface', helpString('intro.navigation.' + textId)); context.map().on('drawn.intro', function() { - reveal('.surface', t('intro.navigation.' + textId), { duration: 0 }); + reveal('.surface', helpString('intro.navigation.' + textId), { duration: 0 }); }); context.map().on('move.intro', function() { @@ -88,18 +88,12 @@ export function uiIntroNavigation(context, reveal) { var textId = context.lastPointerType() === 'mouse' ? 'zoom' : 'zoom_touch'; reveal('.surface', - t('intro.navigation.' + textId, { - plus: icon('#iD-icon-plus', 'pre-text'), - minus: icon('#iD-icon-minus', 'pre-text') - }) + helpString('intro.navigation.' + textId) ); context.map().on('drawn.intro', function() { reveal('.surface', - t('intro.navigation.' + textId, { - plus: icon('#iD-icon-plus', 'pre-text'), - minus: icon('#iD-icon-minus', 'pre-text') - }), { duration: 0 } + helpString('intro.navigation.' + textId), { duration: 0 } ); }); @@ -120,12 +114,12 @@ export function uiIntroNavigation(context, reveal) { function features() { var onClick = function() { continueTo(pointsLinesAreas); }; - reveal('.surface', t('intro.navigation.features'), + reveal('.surface', helpString('intro.navigation.features'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); context.map().on('drawn.intro', function() { - reveal('.surface', t('intro.navigation.features'), + reveal('.surface', helpString('intro.navigation.features'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick } ); }); @@ -139,12 +133,12 @@ export function uiIntroNavigation(context, reveal) { function pointsLinesAreas() { var onClick = function() { continueTo(nodesWays); }; - reveal('.surface', t('intro.navigation.points_lines_areas'), + reveal('.surface', helpString('intro.navigation.points_lines_areas'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); context.map().on('drawn.intro', function() { - reveal('.surface', t('intro.navigation.points_lines_areas'), + reveal('.surface', helpString('intro.navigation.points_lines_areas'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick } ); }); @@ -158,12 +152,12 @@ export function uiIntroNavigation(context, reveal) { function nodesWays() { var onClick = function() { continueTo(clickTownHall); }; - reveal('.surface', t('intro.navigation.nodes_ways'), + reveal('.surface', helpString('intro.navigation.nodes_ways'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); context.map().on('drawn.intro', function() { - reveal('.surface', t('intro.navigation.nodes_ways'), + reveal('.surface', helpString('intro.navigation.nodes_ways'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick } ); }); @@ -188,13 +182,13 @@ export function uiIntroNavigation(context, reveal) { if (!entity) return; var box = pointBox(entity.loc, context); var textId = context.lastPointerType() === 'mouse' ? 'click_townhall' : 'tap_townhall'; - reveal(box, t('intro.navigation.' + textId)); + reveal(box, helpString('intro.navigation.' + textId)); context.map().on('move.intro drawn.intro', function() { var entity = context.hasEntity(hallId); if (!entity) return; var box = pointBox(entity.loc, context); - reveal(box, t('intro.navigation.' + textId), { duration: 0 }); + reveal(box, helpString('intro.navigation.' + textId), { duration: 0 }); }); context.on('enter.intro', function() { @@ -227,7 +221,7 @@ export function uiIntroNavigation(context, reveal) { var box = pointBox(entity.loc, context); var onClick = function() { continueTo(editorTownHall); }; - reveal(box, t('intro.navigation.selected_townhall'), + reveal(box, helpString('intro.navigation.selected_townhall'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); @@ -235,7 +229,7 @@ export function uiIntroNavigation(context, reveal) { var entity = context.hasEntity(hallId); if (!entity) return; var box = pointBox(entity.loc, context); - reveal(box, t('intro.navigation.selected_townhall'), + reveal(box, helpString('intro.navigation.selected_townhall'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick } ); }); @@ -263,7 +257,7 @@ export function uiIntroNavigation(context, reveal) { var onClick = function() { continueTo(presetTownHall); }; reveal('.entity-editor-pane', - t('intro.navigation.editor_townhall'), + helpString('intro.navigation.editor_townhall'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); @@ -301,7 +295,7 @@ export function uiIntroNavigation(context, reveal) { var onClick = function() { continueTo(fieldsTownHall); }; reveal('.entity-editor-pane .section-feature-type', - t('intro.navigation.preset_townhall', { preset: preset.name() }), + helpString('intro.navigation.preset_townhall', { preset: preset.name() }), { buttonText: t('intro.ok'), buttonCallback: onClick } ); @@ -335,7 +329,7 @@ export function uiIntroNavigation(context, reveal) { var onClick = function() { continueTo(closeTownHall); }; reveal('.entity-editor-pane .section-preset-fields', - t('intro.navigation.fields_townhall'), + helpString('intro.navigation.fields_townhall'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); @@ -365,7 +359,7 @@ export function uiIntroNavigation(context, reveal) { var href = d3_select(selector).attr('href') || '#iD-icon-close'; reveal('.entity-editor-pane', - t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') }) + helpString('intro.navigation.close_townhall', { button: icon(href, 'pre-text') }) ); context.on('exit.intro', function() { @@ -378,7 +372,7 @@ export function uiIntroNavigation(context, reveal) { var href = d3_select(selector).attr('href') || '#iD-icon-close'; reveal('.entity-editor-pane', - t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') }), + helpString('intro.navigation.close_townhall', { button: icon(href, 'pre-text') }), { duration: 0 } ); }); @@ -401,7 +395,7 @@ export function uiIntroNavigation(context, reveal) { timeout(function() { reveal('.search-header input', - t('intro.navigation.search_street', { name: t('intro.graph.name.spring-street') }) + helpString('intro.navigation.search_street', { name: t('intro.graph.name.spring-street') }) ); context.container().select('.search-header input') @@ -417,7 +411,7 @@ export function uiIntroNavigation(context, reveal) { if (!firstName.empty() && firstName.text() === name) { reveal(first.node(), - t('intro.navigation.choose_street', { name: name }), + helpString('intro.navigation.choose_street', { name: name }), { duration: 300 } ); @@ -451,7 +445,7 @@ export function uiIntroNavigation(context, reveal) { box.height = 500; reveal(box, - t('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }), + helpString('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }), { duration: 600, buttonText: t('intro.ok'), buttonCallback: onClick } ); @@ -462,7 +456,7 @@ export function uiIntroNavigation(context, reveal) { var box = pointBox(entity.loc, context); box.height = 500; reveal(box, - t('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }), + helpString('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }), { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick } ); }); @@ -501,7 +495,7 @@ export function uiIntroNavigation(context, reveal) { var href = d3_select(selector).attr('href') || '#iD-icon-close'; reveal('.entity-editor-pane', - t('intro.navigation.editor_street', { + helpString('intro.navigation.editor_street', { button: icon(href, 'pre-text'), field1: onewayField.label(), field2: maxspeedField.label() @@ -518,7 +512,7 @@ export function uiIntroNavigation(context, reveal) { var href = d3_select(selector).attr('href') || '#iD-icon-close'; reveal('.entity-editor-pane', - t('intro.navigation.editor_street', { + helpString('intro.navigation.editor_street', { button: icon(href, 'pre-text'), field1: onewayField.label().toLowerCase(), field2: maxspeedField.label().toLowerCase() @@ -537,7 +531,7 @@ export function uiIntroNavigation(context, reveal) { function play() { dispatch.call('done'); reveal('.ideditor', - t('intro.navigation.play', { next: t('intro.points.title') }), { + helpString('intro.navigation.play', { next: t('intro.points.title') }), { tooltipBox: '.intro-nav-wrap .chapter-point', buttonText: t('intro.ok'), buttonCallback: function() { reveal('.ideditor'); } diff --git a/modules/ui/intro/point.js b/modules/ui/intro/point.js index 5daf86937..e69e9aab0 100644 --- a/modules/ui/intro/point.js +++ b/modules/ui/intro/point.js @@ -5,12 +5,12 @@ import { } from 'd3-selection'; import { presetManager } from '../../presets'; -import { t, localizer } from '../../core/localizer'; +import { t } from '../../core/localizer'; import { actionChangePreset } from '../../actions/change_preset'; import { modeBrowse } from '../../modes/browse'; import { modeSelect } from '../../modes/select'; import { utilRebind } from '../../util/rebind'; -import { icon, pointBox, pad, selectMenuItem, transitionTime } from './helper'; +import { helpString, icon, pointBox, pad, selectMenuItem, transitionTime } from './helper'; export function uiIntroPoint(context, reveal) { @@ -48,7 +48,7 @@ export function uiIntroPoint(context, reveal) { timeout(function() { var tooltip = reveal('button.add-point', - t('intro.points.add_point', { button: icon('#iD-icon-point', 'pre-text') })); + helpString('intro.points.add_point')); _pointID = null; @@ -78,11 +78,11 @@ export function uiIntroPoint(context, reveal) { var pointBox = pad(building, 150, context); var textId = context.lastPointerType() === 'mouse' ? 'place_point' : 'place_point_touch'; - reveal(pointBox, t('intro.points.' + textId)); + reveal(pointBox, helpString('intro.points.' + textId)); context.map().on('move.intro drawn.intro', function() { pointBox = pad(building, 150, context); - reveal(pointBox, t('intro.points.' + textId), { duration: 0 }); + reveal(pointBox, helpString('intro.points.' + textId), { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -112,7 +112,7 @@ export function uiIntroPoint(context, reveal) { .on('keyup.intro', checkPresetSearch); reveal('.preset-search-input', - t('intro.points.search_cafe', { preset: cafePreset.name() }) + helpString('intro.points.search_cafe', { preset: cafePreset.name() }) ); context.on('enter.intro', function(mode) { @@ -133,7 +133,7 @@ export function uiIntroPoint(context, reveal) { .on('keyup.intro', checkPresetSearch); reveal('.preset-search-input', - t('intro.points.search_cafe', { preset: cafePreset.name() }) + helpString('intro.points.search_cafe', { preset: cafePreset.name() }) ); context.history().on('change.intro', null); @@ -150,7 +150,7 @@ export function uiIntroPoint(context, reveal) { .on('keyup.intro', null); reveal(first.select('.preset-list-button').node(), - t('intro.points.choose_cafe', { preset: cafePreset.name() }), + helpString('intro.points.choose_cafe', { preset: cafePreset.name() }), { duration: 300 } ); @@ -176,7 +176,7 @@ export function uiIntroPoint(context, reveal) { } timeout(function() { - reveal('.entity-editor-pane', t('intro.points.feature_editor'), { + reveal('.entity-editor-pane', helpString('intro.points.feature_editor'), { tooltipClass: 'intro-points-describe', buttonText: t('intro.ok'), buttonCallback: function() { continueTo(addName); } @@ -209,7 +209,7 @@ export function uiIntroPoint(context, reveal) { // Give them an OK button instead. var entity = context.entity(_pointID); if (entity.tags.name) { - var tooltip = reveal('.entity-editor-pane', t('intro.points.add_name'), { + var tooltip = reveal('.entity-editor-pane', helpString('intro.points.add_name'), { tooltipClass: 'intro-points-describe', buttonText: t('intro.ok'), buttonCallback: function() { continueTo(addCloseEditor); } @@ -217,7 +217,7 @@ export function uiIntroPoint(context, reveal) { tooltip.select('.instruction').style('display', 'none'); } else { - reveal('.entity-editor-pane', t('intro.points.add_name'), + reveal('.entity-editor-pane', helpString('intro.points.add_name'), { tooltipClass: 'intro-points-describe' } ); } @@ -252,7 +252,7 @@ export function uiIntroPoint(context, reveal) { }); reveal('.entity-editor-pane', - t('intro.points.add_close', { button: icon(href, 'pre-text') }) + helpString('intro.points.add_close', { button: icon(href, 'pre-text') }) ); function continueTo(nextStep) { @@ -279,14 +279,14 @@ export function uiIntroPoint(context, reveal) { timeout(function() { var box = pointBox(entity.loc, context); - reveal(box, t('intro.points.reselect'), { duration: 600 }); + reveal(box, helpString('intro.points.reselect'), { duration: 600 }); timeout(function() { context.map().on('move.intro drawn.intro', function() { var entity = context.hasEntity(_pointID); if (!entity) return chapter.restart(); var box = pointBox(entity.loc, context); - reveal(box, t('intro.points.reselect'), { duration: 0 }); + reveal(box, helpString('intro.points.reselect'), { duration: 0 }); }); }, 600); // after reveal.. @@ -322,7 +322,7 @@ export function uiIntroPoint(context, reveal) { }); timeout(function() { - reveal('.entity-editor-pane', t('intro.points.update'), + reveal('.entity-editor-pane', helpString('intro.points.update'), { tooltipClass: 'intro-points-describe' } ); }, 400); @@ -349,7 +349,7 @@ export function uiIntroPoint(context, reveal) { timeout(function() { reveal('.entity-editor-pane', - t('intro.points.update_close', { button: icon('#iD-icon-apply', 'pre-text') }) + helpString('intro.points.update_close', { button: icon('#iD-icon-apply', 'pre-text') }) ); }, 500); @@ -369,14 +369,14 @@ export function uiIntroPoint(context, reveal) { var box = pointBox(entity.loc, context); var textId = context.lastPointerType() === 'mouse' ? 'rightclick' : 'edit_menu_touch'; - reveal(box, t('intro.points.' + textId), { duration: 600 }); + reveal(box, helpString('intro.points.' + textId), { duration: 600 }); timeout(function() { context.map().on('move.intro', function() { var entity = context.hasEntity(_pointID); if (!entity) return chapter.restart(); var box = pointBox(entity.loc, context); - reveal(box, t('intro.points.' + textId), { duration: 0 }); + reveal(box, helpString('intro.points.' + textId), { duration: 0 }); }); }, 600); // after reveal @@ -409,14 +409,14 @@ export function uiIntroPoint(context, reveal) { if (!node) { return continueTo(rightClickPoint); } reveal('.edit-menu', - t('intro.points.delete', { button: icon('#iD-operation-delete', 'pre-text') }), + helpString('intro.points.delete'), { padding: 50 } ); timeout(function() { context.map().on('move.intro', function() { reveal('.edit-menu', - t('intro.points.delete', { button: icon('#iD-operation-delete', 'pre-text') }), + helpString('intro.points.delete'), { duration: 0, padding: 50 } ); }); @@ -448,9 +448,8 @@ export function uiIntroPoint(context, reveal) { continueTo(play); }); - var iconName = '#iD-icon-' + (localizer.textDirection() === 'rtl' ? 'redo' : 'undo'); reveal('.top-toolbar button.undo-button', - t('intro.points.undo', { button: icon(iconName, 'pre-text') }) + helpString('intro.points.undo') ); function continueTo(nextStep) { @@ -463,7 +462,7 @@ export function uiIntroPoint(context, reveal) { function play() { dispatch.call('done'); reveal('.ideditor', - t('intro.points.play', { next: t('intro.areas.title') }), { + helpString('intro.points.play', { next: t('intro.areas.title') }), { tooltipBox: '.intro-nav-wrap .chapter-area', buttonText: t('intro.ok'), buttonCallback: function() { reveal('.ideditor'); } diff --git a/modules/ui/intro/start_editing.js b/modules/ui/intro/start_editing.js index 75cd23db1..47ba615fe 100644 --- a/modules/ui/intro/start_editing.js +++ b/modules/ui/intro/start_editing.js @@ -4,7 +4,7 @@ import { } from 'd3-selection'; import { t } from '../../core/localizer'; -import { icon } from './helper'; +import { helpString } from './helper'; import { uiModal } from '../modal'; import { utilRebind } from '../../util/rebind'; @@ -20,7 +20,7 @@ export function uiIntroStartEditing(context, reveal) { function showHelp() { reveal('.map-control.help-control', - t('intro.startediting.help', { button: icon('#iD-icon-help', 'pre-text'), key: t('help.key') }), { + helpString('intro.startediting.help'), { buttonText: t('intro.ok'), buttonCallback: function() { shortcuts(); } } @@ -29,7 +29,7 @@ export function uiIntroStartEditing(context, reveal) { function shortcuts() { reveal('.map-control.help-control', - t('intro.startediting.shortcuts', { key: t('shortcuts.toggle.key') }), { + helpString('intro.startediting.shortcuts'), { buttonText: t('intro.ok'), buttonCallback: function() { showSave(); } } @@ -39,7 +39,7 @@ export function uiIntroStartEditing(context, reveal) { function showSave() { context.container().selectAll('.shaded').remove(); // in case user opened keyboard shortcuts reveal('.top-toolbar button.save', - t('intro.startediting.save'), { + helpString('intro.startediting.save'), { buttonText: t('intro.ok'), buttonCallback: function() { showStart(); } } diff --git a/modules/ui/intro/welcome.js b/modules/ui/intro/welcome.js index 841606d57..d4300748d 100644 --- a/modules/ui/intro/welcome.js +++ b/modules/ui/intro/welcome.js @@ -1,5 +1,6 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; +import { helpString } from './helper'; import { t } from '../../core/localizer'; import { utilRebind } from '../../util/rebind'; @@ -15,21 +16,21 @@ export function uiIntroWelcome(context, reveal) { function welcome() { context.map().centerZoom([-85.63591, 41.94285], 19); reveal('.intro-nav-wrap .chapter-welcome', - t('intro.welcome.welcome'), + helpString('intro.welcome.welcome'), { buttonText: t('intro.ok'), buttonCallback: practice } ); } function practice() { reveal('.intro-nav-wrap .chapter-welcome', - t('intro.welcome.practice'), + helpString('intro.welcome.practice'), { buttonText: t('intro.ok'), buttonCallback: words } ); } function words() { reveal('.intro-nav-wrap .chapter-welcome', - t('intro.welcome.words'), + helpString('intro.welcome.words'), { buttonText: t('intro.ok'), buttonCallback: chapters } ); } @@ -38,7 +39,7 @@ export function uiIntroWelcome(context, reveal) { function chapters() { dispatch.call('done'); reveal('.intro-nav-wrap .chapter-navigation', - t('intro.welcome.chapters', { next: t('intro.navigation.title') }) + helpString('intro.welcome.chapters', { next: t('intro.navigation.title') }) ); } diff --git a/modules/ui/panes/help.js b/modules/ui/panes/help.js index 64592355b..48924d7d1 100644 --- a/modules/ui/panes/help.js +++ b/modules/ui/panes/help.js @@ -1,14 +1,13 @@ import marked from 'marked'; import { svgIcon } from '../../svg/icon'; -import { uiCmd } from '../cmd'; import { uiIntro } from '../intro/intro'; import { uiShortcuts } from '../shortcuts'; import { uiPane } from '../pane'; import { t, localizer } from '../../core/localizer'; import { uiTooltip } from '../tooltip'; -import { icon } from '../intro/helper'; +import { helpString } from '../intro/helper'; export function uiPaneHelp(context) { @@ -231,73 +230,15 @@ export function uiPaneHelp(context) { 'help.qa.issues_h': 3 }; - var replacements = { - // insert icons corresponding to various UI elements - point_icon: icon('#iD-icon-point', 'pre-text'), - line_icon: icon('#iD-icon-line', 'pre-text'), - area_icon: icon('#iD-icon-area', 'pre-text'), - note_icon: icon('#iD-icon-note', 'pre-text add-note'), - plus: icon('#iD-icon-plus', 'pre-text'), - minus: icon('#iD-icon-minus', 'pre-text'), - move_icon: icon('#iD-operation-move', 'pre-text operation'), - merge_icon: icon('#iD-operation-merge', 'pre-text operation'), - delete_icon: icon('#iD-operation-delete', 'pre-text operation'), - orthogonalize_icon: icon('#iD-operation-orthogonalize', 'pre-text operation'), - disconnect_icon: icon('#iD-operation-disconnect', 'pre-text operation'), - layers_icon: icon('#iD-icon-layers', 'pre-text'), - data_icon: icon('#iD-icon-data', 'pre-text'), - inspect: icon('#iD-icon-inspect', 'pre-text'), - close: icon('#iD-icon-close', 'pre-text'), - undo_icon: icon(localizer.textDirection() === 'rtl' ? '#iD-icon-redo' : '#iD-icon-undo', 'pre-text'), - redo_icon: icon(localizer.textDirection() === 'rtl' ? '#iD-icon-undo' : '#iD-icon-redo', 'pre-text'), - save_icon: icon('#iD-icon-save', 'pre-text'), - leftclick: icon('#iD-walkthrough-mouse', 'pre-text mouseclick', 'left'), - rightclick: icon('#iD-walkthrough-mouse', 'pre-text mouseclick', 'right'), - - // insert localized, platform-dependent keys - shift: uiCmd.display('⇧'), - alt: uiCmd.display('⌥'), - return: uiCmd.display('↵'), - space: t('shortcuts.key.space'), - add_note_key: t('modes.add_note.key'), - shortcuts_key: t('shortcuts.toggle.key'), - - // reference localized UI labels directly so that they'll always match - save: t('save.title'), - undo: t('undo.title'), - redo: t('redo.title'), - upload: t('commit.save'), - point: t('modes.add_point.title'), - line: t('modes.add_line.title'), - area: t('modes.add_area.title'), - note: t('modes.add_note.title'), - delete: t('operations.delete.title'), - move: t('operations.move.title'), - orthogonalize: t('operations.orthogonalize.title'), - merge: t('operations.merge.title'), - disconnect: t('operations.disconnect.title'), - map_data: t('map_data.title'), - fields: t('inspector.fields'), - tags: t('inspector.tags'), - relations: t('inspector.relations'), - new_relation: t('inspector.new_relation'), - turn_restrictions: t('presets.fields.restrictions.label'), - background_settings: t('background.description'), - imagery_offset: t('background.fix_misalignment'), - start_the_walkthrough: t('splash.walkthrough'), - - // insert iD's version number - version: context.version - }; - // For each section, squash all the texts into a single markdown document var docs = docKeys.map(function(key) { var helpkey = 'help.' + key[0]; + var helpPaneReplacements = { version: context.version }; var text = key[1].reduce(function(all, part) { var subkey = helpkey + '.' + part; var depth = headings[subkey]; // is this subkey a heading? var hhh = depth ? Array(depth + 1).join('#') + ' ' : ''; // if so, prepend with some ##'s - return all + hhh + t(subkey, replacements) + '\n\n'; + return all + hhh + helpString(subkey, helpPaneReplacements) + '\n\n'; }, ''); return {