JSON API

Overview

Mepo offers an extensive JSON API which is utilized for user configuration (via ~/.config/mepo/config.json), savestates (via ~/.cache/mepo/savestate.json), and can be used for arbitrary scripting and end-user customization.

The basic syntax for the JSON API is that anywhere JSON API commands may be passed, you can pass an array of commands as:

[
  {"cmd": "command_name", "args": {"arg_name": "arg_value"}},
  {"cmd": "command_name2", "args": {"arg_name": "arg_value"}}
]

For a quickstart on how to use the JSON API for user configuration see user guide configuration file section; and if you are interested in writing your own scripts - see the scripting guide.

The rest of this document outlines the functionality of all JSON API commands, shellpipe env vars, and the base configuration.


Version

This document was compiled against mepo version: 1.3.0.

The following sections for API, preferences, shellpipe env variables, and base configuration are dependent on / assume the above version of mepo this document was compiled against, you may check your version of mepo with mepo -v.


API Commands

bind_button

Create a UI button which executes a JSON commands. UI buttons appear aligned in the bottom right of the screen or the top left alongside the pin details overlay (see first argument).

Arguments:

Name Datatype Description
pin_only Number Set to 1 to only show button in top bar if there is a currently activated pin.
group Number Group number (0-9) to associate with button. A Colorbar will match group # and button will highlight when group active. Use -1 for no associated group.
text Text Text that will be shown on the button
exps_click Text JSON API expressions to run on single clicking the button
exps_hold Text JSON API expressions to run on holding the button

bind_click

Bind a particular number of successive clicks to run a JSON API expressions.

Arguments:

Name Datatype Description
button Number Mousebutton to bind (1 = left, 2 = right, 3 = middle)
clicks Number Number of successive clicks to trigger action
exps Text JSON API expressions to run

bind_gesture

Bind a multitouch gesture event to execute JSON API expressions.

Arguments:

Name Datatype Description
action Text Gesture action (set to either pan or rotate)
fingers Number Number of fingers to trigger expression
direction Number Direction for gesture (e.g. 1 for in or -1 for out)
exps Text JSON API expressions to run

bind_key

Bind a key combination to execute a JSON API expressions.

Arguments:

Name Datatype Description
mod Text Modifier combination (c=control, s=shift, a=alt); ex. cs would mean control and shift
key Text Key to bind; note case indiscriminate since modifier handled by modifier argument
exps Text JSON expressions to run

bind_signal

Bind a signal to execute JSON API expressions.

Arguments:

Name Datatype Description
sig Text Signal name; can be USR1, USR2, TERM, or INT
exps Text JSON API expressions to run

bind_timer

Bind a timer to execute JSON API expressions at the given interval.

Arguments:

Name Datatype Description
secs Number Number of seconds between successive runs of given JSON API expression
exps Text JSON API expressions to run

bind_quit

Bind JSON API expressions to run on quitting the application.

Arguments:

Name Datatype Description
exps Text JSON API expressions to run

cache_dlbbox

Queue tiles for a bounding box to download to the cache in the background for the given zoom levels. Writes directly to filesystem cache (path determined by tile_cache_dir preference) as tiles are downloaded.

Arguments:

Name Datatype Description
a_lat Number Starting latitude
a_lon Number Starting longitude
b_lat Number Ending latitude
b_lon Number Ending longitude
zoom_min Number Minimum zoom level
zoom_max Number Maximum zoom level

cache_queueclear

Clear any queued background downloading process queued with cache_dlbbox or cache_dlradius. Note this does not remove filesystem tiles, but simply stops in-progress downloading.


center_on_mouse

Center the map on the current position of the mouse.


center_on_pin

Center the map on the currently active pin.


clipcopy

Copy the current map coordinates to the clipboard; will be in format: lat lon.


clippaste

Extract clipboard contents and either center on coordinate (if clipboard content matches lat lon format); otherwise run clipboard contents as JSON API expressions.


fileload

Load JSON API expressions from an arbitrary filesystem file.

Arguments:

Name Datatype Description
filepath Text Path to file to load

filedump

Save the current state of pins and/or preferences to a file as JSON API expressions.

Arguments:

Name Datatype Description
datatypes Text Types of data to save (p = pins, r = prefsets); ex. pr would save both pins and preferences
filepath Text Path to file to save state to

move_relative

Move the map by a relative x/y amount.

Arguments:

Name Datatype Description
rel_x Number Relative x amount
rel_y Number Relative y amount

pin_activate

Activate a pin by its handle.

Arguments:

Name Datatype Description
group Number Group number
handle Text Pin's handle to activate

pin_add

Add a pin to the map.

Arguments:

Name Datatype Description
group Number Group number (or if -1 add to the current active group)
structural Number If set to 1, will be a 'structural' pin which is useful for curved paths and similar
lat Number Latitude
lon Number Longitude
handle Text Unique handle to refer to pin; can use this handle subsequently with pin_meta to update pin metadata

pin_cycle

Cycle the currently focused pin group pin.

Arguments:

Name Datatype Description
viewport_only Number Use 1 to only cycle between pins in viewport
delta Number Delta amount (positive or negative) for number of pins to skip

pin_deactivate

Deactivate currently active pin.


pin_groupactivate

Activate the pin group specified.

Arguments:

Name Datatype Description
group Number Group number

pin_delete

Delete a pin by its handle.

Arguments:

Name Datatype Description
group Number Optional group number (if unset uses the current group)
handle Text Optional pin handle to delete (if unset uses the current pin)

pin_meta

Update a pin's metadata.

Arguments:

Name Datatype Description
group Number Group number
handle Text Pin handle
key Text Metadata key to update
value Text New value for metadata key

pin_transfer

Transfer a pin from one group to another.

Arguments:

Name Datatype Description
from_group Number Group number, or -1 for the current group number.
handle Text Handle of the pin to transfer; or empty string will transfer the current pin. Use the string all for all pins in group.
to_group Number Group number

pin_purge

Purge all pins in the currently active pin group.


prefinc

Increase or decrease a preference by the given delta value.

Arguments:

Name Datatype Description
pref Text Preference name
delta Number Delta value to increment/decrement (positive or negative)

prefset_n

Set a preference number value.

Arguments:

Name Datatype Description
pref Text Preference name
value Number Preference number value

prefset_t

Set a preference text value.

Arguments:

Name Datatype Description
pref Text Preference name
value Text Preference number value

preftoggle

Toggle a boolean number preference between 1 and 0.

Arguments:

Name Datatype Description
pref Text Preference name

quit

Quit the application.


shellpipe_async

Run a system (shell) command and pipe asynchronously; STDOUT returned from command will be executed back as a jsonapi expression.

Arguments:

Name Datatype Description
unique_handle_id Number Optional id to deduplicate individual async shellpipe requests
shellcode Text Shell statement to execute

shellpipe_sync

Run a system (shell) command synchronously and pipe; STDOUT returned from command will be executed back as a JSON API expressions. Note state of application can be introspected by examining ENV vars (documented in API doc) and also state is saved as JSON API commands to $XDG_CACHE_HOME/mepo/shellpipe_savestate.json

Arguments:

Name Datatype Description
shellcode Text Shell statement to execute

zoom_relative

Update the map's zoom level by a relative delta.

Arguments:

Name Datatype Description
zoom_delta Number Zoom level relative delta

Preferences

Internally mepo keeps track of a number of preferences which control all state for the application. These preferences can be set with the commands preset_n for numerical preferences and prefset_t for textual preferences. You can also use filedump to examine the current values of all preferences.

Below is an exhaustive list of all available preferences:

Name Description Datatype Min Max Default Value
lat Latitude of the map Number (float) -90 90 40.78392
lon Longitude of the map Number (float) -180 180 -73.96442
zoom Zoom level of the map (should be set between 0-19) Number (u8) 0 19 14
debug_message_enabled Whether debug overlay message should be shown in the UI Number (bool) 1
distance_unit_tf_km_mi Whether to show distance in km (0) or mi (1) Number (bool) 0
overlay_debugbar Whether to show the debug bar Number (bool) 1
help Whether to show the help overlay Number (bool) 0
overlay_pindetails Whether to show the pin detail overlay Number (bool) 1
overlay_pindetails_expanded Whether to show the pin detail overlay as expanded Number (bool) 1
crosshair_size Pixel size of the crosshairs Number (u8) 0 300 15
drag_scale Scale for dragging Number (u8) 1 200 2
fontsize_ui Size of the font in the UI Number (u8) 1 49 20
debug_stderr Send debug information to STDERR (note the commandline flag -e overrides this setting) Number (bool) 1
tile_cache_max_n_transfers Maximum number of concurrent transfers for curl Number (u8) 1 9999 20
tile_cache_expiry_seconds Number of seconds before a downloaded tiledata should be considered invalid Number (float) -1 99999999 -1
tile_cache_network Whether to download new tiledata from external servers; if 0 that means you're offline Number (bool) 1
tile_cache_dir Path of directory to store the downloaded tiles Text
tile_cache_url URL source for the tiles, uses %1/%2/%3 to represent X/Y/Z Text
pingroup_0_ordered Whether pingroup 0 should be ordered Number (bool) 0
pingroup_1_ordered Whether pingroup 1 should be ordered Number (bool) 0
pingroup_2_ordered Whether pingroup 2 should be ordered Number (bool) 0
pingroup_3_ordered Whether pingroup 3 should be ordered Number (bool) 0
pingroup_4_ordered Whether pingroup 4 should be ordered Number (bool) 0
pingroup_5_ordered Whether pingroup 5 should be ordered Number (bool) 0
pingroup_6_ordered Whether pingroup 6 should be ordered Number (bool) 0
pingroup_7_ordered Whether pingroup 7 should be ordered Number (bool) 0
pingroup_8_ordered Whether pingroup 8 should be ordered Number (bool) 0
pingroup_9_ordered Whether pingroup 9 should be ordered Number (bool) 0
pingroup_0_color Color to indicate pingroup 0 Number (u24) 0
pingroup_1_color Color to indicate pingroup 1 Number (u24) 0
pingroup_2_color Color to indicate pingroup 2 Number (u24) 0
pingroup_3_color Color to indicate pingroup 3 Number (u24) 0
pingroup_4_color Color to indicate pingroup 4 Number (u24) 0
pingroup_5_color Color to indicate pingroup 5 Number (u24) 0
pingroup_6_color Color to indicate pingroup 6 Number (u24) 0
pingroup_7_color Color to indicate pingroup 7 Number (u24) 0
pingroup_8_color Color to indicate pingroup 8 Number (u24) 0
pingroup_9_color Color to indicate pingroup 9 Number (u24) 0

Shellpipe ENV Variables

State from shellpipe_sync and shellpipe_async can be accessed in two ways. Raw state (equivilant to using the filedump JSON API command) is written to ~/.config/mepo/shellpipe_savestate.json before executing the shellpipe. This state can be read with jq or any JSON parser.

Additionally for simple scripts that don't need to access the full state of Mepo, you may consider using a number of simple ENV vars accessible to the target script called.

Available ENV vars:

  • MEPO_WIN_W: Width of the UI window
  • MEPO_WIN_H: Height of the UI window
  • MEPO_ZOOM: Current zoom level
  • MEPO_CENTER_LAT: Latitude of the center point of the screen
  • MEPO_CENTER_LON: Longitude of the center point of the screen
  • MEPO_TL_LAT: Latitude of the top left point on the screen
  • MEPO_TL_LON: Longitude of the top left point on the screen
  • MEPO_BR_LAT: Latitude of the bottom right point on the screen
  • MEPO_BR_LON: Longitude of the bottom right point on the screen
  • MEPO_CURSOR_LAT: Latitude of the cursor position
  • MEPO_CURSOR_LON: Longitude of the cursor position
  • MEPO_PINGROUPACTIVE: Number of the currently active pingroup

Base Configuration

The following base configuration was built into Mepo as of the current release version. These defaults are automatically built into the mepo binary and can be overriden using the user configuration file.

Note, preferences can be overridden directly for example with prefset_n and prefset_t. And bindings can be removed / overriden by assinging a nop command / empty expression list [] as the JSON expressions passed.

[
  {"cmd": "prefset_n", "args": {"pref": "debug_stderr", "value":  1}},
  {"cmd": "prefset_n", "args": {"pref": "lat", "value":  40.78392}},
  {"cmd": "prefset_n", "args": {"pref": "lon", "value":  -73.96442}},
  {"cmd": "prefset_n", "args": {"pref": "fontsize_ui", "value":  16}},
  {"cmd": "prefset_n", "args": {"pref": "distance_unit_tf_km_mi", "value":  1}},
  {"cmd": "prefset_n", "args": {"pref": "crosshair_size", "value":  15}},
  {"cmd": "prefset_n", "args": {"pref": "debug_message_enabled", "value":  1}},
  {"cmd": "prefset_n", "args": {"pref": "overlay_debugbar", "value":  1}},
  {"cmd": "prefset_n", "args": {"pref": "overlay_pindetails", "value":  1}},
  {"cmd": "prefset_n", "args": {"pref": "overlay_pindetails_expanded", "value":  1}},
  {"cmd": "prefset_n", "args": {"pref": "zoom", "value":  14}},
  {"cmd": "prefset_n", "args": {"pref": "tile_cache_network", "value":  1}},
  {"cmd": "prefset_n", "args": {"pref": "tile_cache_max_n_transfers", "value":  20}},
  {"cmd": "prefset_n", "args": {"pref": "tile_cache_expiry_seconds", "value":  2592000}},
  {"cmd": "prefset_t", "args": {"pref": "tile_cache_dir",   "value": "$XDG_CACHE_HOME/mepo/tiles"}},
  {"cmd": "prefset_t", "args": {"pref": "tile_cache_url",   "value": "https://tile.openstreetmap.org/%3$d/%1$d/%2$d.png"}},
  {"cmd": "prefset_t", "args": {"pref": "pingroup_0_color", "value": "#0000ff"}},
  {"cmd": "prefset_t", "args": {"pref": "pingroup_1_color", "value": "#116e0e"}},
  {"cmd": "prefset_t", "args": {"pref": "pingroup_2_color", "value": "#7502ab"}},
  {"cmd": "prefset_t", "args": {"pref": "pingroup_3_color", "value": "#cf0064"}},
  {"cmd": "prefset_t", "args": {"pref": "pingroup_4_color", "value": "#b89600"}},
  {"cmd": "prefset_t", "args": {"pref": "pingroup_5_color", "value": "#00b0aa"}},
  {"cmd": "prefset_t", "args": {"pref": "pingroup_6_color", "value": "#ff8308"}},
  {"cmd": "prefset_t", "args": {"pref": "pingroup_7_color", "value": "#004a0c"}},
  {"cmd": "prefset_t", "args": {"pref": "pingroup_8_color", "value": "#ff00a2"}},
  {"cmd": "prefset_t", "args": {"pref": "pingroup_9_color", "value": "#fff673"}},
  {"cmd": "prefset_n", "args": {"pref": "pingroup_0_ordered", "value":  0}},
  {"cmd": "prefset_n", "args": {"pref": "pingroup_1_ordered", "value":  0}},
  {"cmd": "prefset_n", "args": {"pref": "pingroup_2_ordered", "value":  0}},
  {"cmd": "prefset_n", "args": {"pref": "pingroup_3_ordered", "value":  0}},
  {"cmd": "prefset_n", "args": {"pref": "pingroup_4_ordered", "value":  0}},
  {"cmd": "prefset_n", "args": {"pref": "pingroup_5_ordered", "value":  0}},
  {"cmd": "prefset_n", "args": {"pref": "pingroup_6_ordered", "value":  0}},
  {"cmd": "prefset_n", "args": {"pref": "pingroup_7_ordered", "value":  1}},
  {"cmd": "prefset_n", "args": {"pref": "pingroup_8_ordered", "value":  1}},
  {"cmd": "prefset_n", "args": {"pref": "pingroup_9_ordered", "value":  1}},


  {"cmd": "bind_key", "args": { "mod": "_", "key": "j", "exps": [{"cmd": "move_relative", "args": { "rel_y": 10}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "j", "exps": [{"cmd": "move_relative", "args": { "rel_y": 100}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "k", "exps": [{"cmd": "move_relative", "args": { "rel_y": -10}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "k", "exps": [{"cmd": "move_relative", "args": { "rel_y": -100}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "h", "exps": [{"cmd": "move_relative", "args": { "rel_x": -10 }}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "h", "exps": [{"cmd": "move_relative", "args": { "rel_x": -100}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "l", "exps": [{"cmd": "move_relative", "args": { "rel_x": 10  }}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "l", "exps": [{"cmd": "move_relative", "args": { "rel_x": 100 }}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "=", "exps": [{"cmd": "zoom_relative", "args": { "zoom_delta": 1}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "-", "exps": [{"cmd": "zoom_relative", "args": { "zoom_delta": -1}}]}},

  {"cmd": "bind_key", "args": { "mod": "_", "key": "1", "exps": [{"cmd": "pin_groupactivate", "args": { "group": 0}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "2", "exps": [{"cmd": "pin_groupactivate", "args": { "group": 1}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "3", "exps": [{"cmd": "pin_groupactivate", "args": { "group": 2}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "4", "exps": [{"cmd": "pin_groupactivate", "args": { "group": 3}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "5", "exps": [{"cmd": "pin_groupactivate", "args": { "group": 4}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "6", "exps": [{"cmd": "pin_groupactivate", "args": { "group": 5}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "7", "exps": [{"cmd": "pin_groupactivate", "args": { "group": 6}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "8", "exps": [{"cmd": "pin_groupactivate", "args": { "group": 7}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "9", "exps": [{"cmd": "pin_groupactivate", "args": { "group": 8}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "0", "exps": [{"cmd": "pin_groupactivate", "args": { "group": 9}}]}},

  {"cmd": "bind_key", "args": { "mod": "s", "key": "1", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "", "to_group": 0}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "2", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "", "to_group": 1}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "3", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "", "to_group": 2}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "4", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "", "to_group": 3}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "5", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "", "to_group": 4}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "6", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "", "to_group": 5}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "7", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "", "to_group": 6}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "8", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "", "to_group": 7}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "9", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "", "to_group": 8}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "0", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "", "to_group": 9}}]}},

  {"cmd": "bind_key", "args": { "mod": "cs", "key": "1", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "all", "to_group": 0}}]}},
  {"cmd": "bind_key", "args": { "mod": "cs", "key": "2", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "all", "to_group": 1}}]}},
  {"cmd": "bind_key", "args": { "mod": "cs", "key": "3", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "all", "to_group": 2}}]}},
  {"cmd": "bind_key", "args": { "mod": "cs", "key": "4", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "all", "to_group": 3}}]}},
  {"cmd": "bind_key", "args": { "mod": "cs", "key": "5", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "all", "to_group": 4}}]}},
  {"cmd": "bind_key", "args": { "mod": "cs", "key": "6", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "all", "to_group": 5}}]}},
  {"cmd": "bind_key", "args": { "mod": "cs", "key": "7", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "all", "to_group": 6}}]}},
  {"cmd": "bind_key", "args": { "mod": "cs", "key": "8", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "all", "to_group": 7}}]}},
  {"cmd": "bind_key", "args": { "mod": "cs", "key": "9", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "all", "to_group": 8}}]}},
  {"cmd": "bind_key", "args": { "mod": "cs", "key": "0", "exps": [{"cmd": "pin_transfer", "args": { "from_group": -1, "handle": "all", "to_group": 9}}]}},

  {"cmd": "bind_key", "args": { "mod": "_", "key": "d", "exps": [ {"cmd": "pin_delete", "args": {}}, {"cmd": "pin_cycle", "args": { "viewport_only": 0, "delta": 1}} ]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "d", "exps": [{"cmd": "pin_purge", "args": {}}]}},

  {"cmd": "bind_key", "args": { "mod": "_", "key": "/", "exps": [{"cmd": "preftoggle", "args": {"pref": "help"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "e", "exps": [{"cmd": "preftoggle", "args": {"pref": "overlay_pindetails"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "s", "exps": [{"cmd": "preftoggle", "args": {"pref": "overlay_debugbar"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "m", "exps": [{"cmd": "preftoggle", "args": {"pref": "tile_cache_network"}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "c", "exps": [{"cmd": "center_on_mouse", "args": {}}]}},


  {"cmd": "bind_key", "args": { "mod": "_", "key": "n", "exps": [{"cmd": "pin_cycle", "args": { "viewport_only": 1, "delta": 1}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "p", "exps": [{"cmd": "pin_cycle", "args": { "viewport_only": 0, "delta": -1}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "n", "exps": [ {"cmd": "pin_cycle", "args": { "viewport_only": 0, "delta": 1}}, {"cmd": "center_on_pin", "args": {}} ]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "p", "exps": [ {"cmd": "pin_cycle", "args": { "viewport_only": 0, "delta": -1}}, {"cmd": "center_on_pin", "args": {}} ]}},

  {"cmd": "bind_key", "args": { "mod": "_", "key": "o", "exps": [{"cmd": "pin_deactivate", "args": {}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "o", "exps": [{"cmd": "pin_purge", "args": {}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "w", "exps": [{"cmd": "cache_queueclear", "args": {}}]}},
  {"cmd": "bind_key", "args": { "mod": "c", "key": "c", "exps": [{"cmd": "quit", "args": {}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "y", "exps": [{"cmd": "clipcopy", "args": {}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "y", "exps": [{"cmd": "clippaste", "args": {}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "=", "exps": [{"cmd": "prefinc", "args": {"pref": "fontsize_ui", "delta": 1}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "-", "exps": [{"cmd": "prefinc", "args": {"pref": "fontsize_ui", "delta": -1}}]}},


  {"cmd": "bind_key", "args": { "mod": "_", "key": "c", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_central_menu.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "i", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_pref_statesave.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "u", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_pref_stateload.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "f", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_pin_drop.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "g", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_reposition_nominatim.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "g", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_search_nominatim.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "b", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_search_overpass.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "r", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_route_mobroute.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "r", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_route_graphhopper.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "z", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_pref_fontsize.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "z", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_pref_zoom.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "v", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_pref_url.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "q", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_dbg_queuedownloadinteractive.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "s", "key": "q", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_dbg_queuedownloadnoninteractive.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "_", "key": "x", "exps": [{"cmd": "shellpipe_sync", "args": { "shellcode": "mepo_ui_menu_user_pin_updater.sh droppinactivateandcenter"}}]}},
  {"cmd": "bind_key", "args": { "mod": "c", "key": "f", "exps": [{"cmd": "shellpipe_sync", "args": {"shellcode": "DIM=h MULT=1  mepo_ui_helper_pref_pan.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "c", "key": "b", "exps": [{"cmd": "shellpipe_sync", "args": {"shellcode": "DIM=h MULT=-1  mepo_ui_helper_pref_pan.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "cs", "key": "f", "exps": [{"cmd": "shellpipe_sync", "args": {"shellcode": "DIM=w MULT=1  mepo_ui_helper_pref_pan.sh"}}]}},
  {"cmd": "bind_key", "args": { "mod": "cs", "key": "b", "exps": [{"cmd": "shellpipe_sync", "args": {"shellcode": "DIM=w MULT=-1  mepo_ui_helper_pref_pan.sh"}}]}},


  {"cmd": "bind_button", "args": { "text": "Menu", "exps_click": [ {"cmd": "shellpipe_sync", "args": {"shellcode":  "mepo_ui_central_menu.sh"}} ]}},

  {"cmd": "bind_button", "args": { "text": "Save", "exps_click": [ {"cmd": "shellpipe_sync", "args": {"shellcode":  "mepo_ui_menu_pref_statesave.sh"}} ]}},
  {"cmd": "bind_button", "args": { "text": "Load", "exps_click": [ {"cmd": "shellpipe_sync", "args": {"shellcode":  "mepo_ui_menu_pref_stateload.sh"}} ]}},

  {"cmd": "bind_button", "args": { "text": "Relocate", "exps_click": [ {"cmd": "shellpipe_sync", "args": {"shellcode":  "mepo_ui_menu_reposition_nominatim.sh"}} ]}},
  {"cmd": "bind_button", "args": { "text": "Nm", "exps_click": [ {"cmd": "shellpipe_sync", "args": {"shellcode":  "mepo_ui_menu_search_nominatim.sh"}} ]}},
  {"cmd": "bind_button", "args": { "text": "Op", "exps_click": [ {"cmd": "shellpipe_sync", "args": {"shellcode":  "mepo_ui_menu_search_overpass.sh"}} ]}},
  {"cmd": "bind_button", "args": { "text": "Dl", "exps_click": [ {"cmd": "shellpipe_sync", "args": {"shellcode":  "mepo_ui_menu_dbg_queuedownloadnoninteractive.sh"}} ]}},

  {"cmd": "bind_button", "args": { "text": "~", "pin_only": 1,  "exps_click": [ {"cmd": "preftoggle", "args": {"pref":  "overlay_pindetails_expanded"}} ]}},
  {"cmd": "bind_button", "args": { "text": "Purge", "pin_only": 1,  "exps_click": [ {"cmd": "pin_purge", "args": {}} ]}},
  {"cmd": "bind_button", "args": { "text": "Del", "pin_only": 1,  "exps_click": [
    {"cmd": "pin_delete", "args": {}},
    {"cmd": "pin_cycle", "args": { "viewport_only": 0, "delta": 1}},
    {"cmd": "center_on_pin", "args": {}}
  ]}},
  {"cmd": "bind_button", "args": { "text": ">", "pin_only": 1,  "exps_click": [ {"cmd": "pin_cycle", "args": { "viewport_only": 0, "delta": 1}}, {"cmd": "center_on_pin", "args": {}} ]}},
  {"cmd": "bind_button", "args": { "text": "<", "pin_only": 1,  "exps_click": [ {"cmd": "pin_cycle", "args": { "viewport_only": 0, "delta": -1}}, {"cmd": "center_on_pin", "args": {}} ]}},

  {"cmd": "bind_button", "args": { "pin_only": 1, "group": 9 , "text": "9",
    "exps_click": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "", "to_group": 9}}],
    "exps_hold": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "all", "to_group": 9}}]
  }},
  {"cmd": "bind_button", "args": { "pin_only": 1, "group": 8 , "text": "8",
    "exps_click": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "", "to_group": 8}}],
    "exps_hold": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "all", "to_group": 8}}]
  }},
  {"cmd": "bind_button", "args": { "pin_only": 1, "group": 7 , "text": "7",
    "exps_click": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "", "to_group": 7}}],
    "exps_hold": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "all", "to_group": 7}}]
  }},
  {"cmd": "bind_button", "args": { "pin_only": 1, "group": 6 , "text": "6",
    "exps_click": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "", "to_group": 6}}],
    "exps_hold": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "all", "to_group": 6}}]
  }},
  {"cmd": "bind_button", "args": { "pin_only": 1, "group": 5 , "text": "5",
    "exps_click": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "", "to_group": 5}}],
    "exps_hold": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "all", "to_group": 5}}]
  }},
  {"cmd": "bind_button", "args": { "pin_only": 1, "group": 4 , "text": "4",
    "exps_click": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "", "to_group": 4}}],
    "exps_hold": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "all", "to_group": 4}}]
  }},
  {"cmd": "bind_button", "args": { "pin_only": 1, "group": 3 , "text": "3",
    "exps_click": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "", "to_group": 3}}],
    "exps_hold": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "all", "to_group": 3}}]
  }},
  {"cmd": "bind_button", "args": { "pin_only": 1, "group": 2 , "text": "2",
    "exps_click": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "", "to_group": 2}}],
    "exps_hold": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "all", "to_group": 2}}]
  }},
  {"cmd": "bind_button", "args": { "pin_only": 1, "group": 1 , "text": "1",
    "exps_click": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "", "to_group": 1}}],
    "exps_hold": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "all", "to_group": 1}}]
  }},
  {"cmd": "bind_button", "args": { "pin_only": 1, "group": 0 , "text": "0",
    "exps_click": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "", "to_group": 0}}],
    "exps_hold": [{"cmd": "pin_transfer", "args": {"from_group": -1, "handle": "all", "to_group": 0}}]
  }},


  {"cmd": "bind_click", "args": { "button": 1, "clicks": -1, "exps": [{"cmd": "shellpipe_sync", "args": {"shellcode": "mepo_ui_central_menu.sh"}}]}},
  {"cmd": "bind_click", "args": { "button": 1, "clicks": 2, "exps": [{"cmd": "zoom_relative", "args": {"zoom_delta": 1}}]}},
  {"cmd": "bind_click", "args": { "button": 1, "clicks": 3, "exps": [{"cmd": "zoom_relative", "args": {"zoom_delta": -2}}]}},
  {"cmd": "bind_click", "args": { "button": 2, "clicks": 1, "exps": [{"cmd": "zoom_relative", "args": {"zoom_delta": -1}}]}},

  {"cmd": "bind_gesture", "args": { "action": "pan", "fingers": 2, "direction": 1, "exps": [{"cmd": "zoom_relative", "args": {"zoom_delta": 1}}]}},
  {"cmd": "bind_gesture", "args": { "action": "pan", "fingers": 2, "direction": -1, "exps": [{"cmd": "zoom_relative", "args": {"zoom_delta": -1}}]}},
  {"cmd": "bind_gesture", "args": { "action": "rotate", "fingers": 3, "direction": 1, "exps": [{"cmd": "prefinc", "args": {"pref": "fontsize_ui", "delta": 1 }}]}},
  {"cmd": "bind_gesture", "args": { "action": "rotate", "fingers": 3, "direction": -1, "exps": [{"cmd": "prefinc", "args": {"pref": "fontsize_ui", "delta": -1}}]}},

  {"cmd": "bind_signal", "args": { "sig": "USR1", "exps": [{"cmd": "zoom_relative", "args": {"zoom_delta": 1}}]}},
  {"cmd": "bind_signal", "args": { "sig": "USR2", "exps": [{"cmd": "zoom_relative", "args": {"zoom_delta": -1}}]}},
  {"cmd": "bind_signal", "args": { "sig": "TERM", "exps": [{"cmd": "quit", "args": {}}]}},
  {"cmd": "bind_signal", "args": { "sig": "INT", "exps": [{"cmd": "quit", "args": {}}]}},

  {"cmd": "bind_timer", "args": { "secs": 20, "exps": [ {"cmd": "shellpipe_async", "args": {"shellcode":  "mepo_ui_menu_user_pin_updater.sh droppin"}} ]}},
  {"cmd": "shellpipe_async", "args": {"shellcode":  "mepo_ui_menu_user_pin_updater.sh droppin"}},

  {"cmd": "bind_key", "args": { "mod": "c", "key": "s", "exps": [{"cmd": "filedump", "args": {"datatypes": "rp", "filepath": "$XDG_CACHE_HOME/mepo/savestate.json"}}]}},
  {"cmd": "bind_key", "args": { "mod": "c", "key": "l", "exps": [{"cmd": "fileload", "args": { "filepath": "$XDG_CACHE_HOME/mepo/savestate.json"}}]}},

  {"cmd": "fileload", "args": { "filepath": "$XDG_CONFIG_HOME/mepo/config.json"}},
  {"cmd": "fileload", "args": { "filepath": "$XDG_CONFIG_HOME/mepo/bookmarks.json"}}
]