The Chess Variant Pages
Custom Search

Betza notation (extended)


WX H D W ## W D H WX
Moves of (extended) atoms
(## is the starting square;
shows only forward moves)

Capitals represent the set of symmetrically equivalent moves with a certain leap (an 'atom', e.g. N = the 8 Knight moves). It is shown on the right which letter corresponds to which board step. The capital can optionally be followed by a number indicating the maximum number of times a step can be repeated. (E.g. W4 is a range-4 Rook.) Riders with unlimited range can be indicated by doubling the letter of the atom (e.g. NN for Nightrider). There are shortcuts for the often used unlimited-range sliding moves of Bishop and Rook (B = FF, R = WW), and also for the compound pieces Queen and King (Q = RB, K = WF). R4 means the same as W4.

The atom can be prefixed with a number of lower-case 'modifiers', to specify a sub-set of the possible directions (e.g. fB, a Bishop that only has the two forward slides), or a restriction to what the move can do (e.g. cQ, a Queen that can only capture). Multiple modifiers for a similar aspect usually add their individual effects; mc would mean the move can capture or move to an empty square. (This is however the default meaning of the atoms, so it would be pointless to write it.)

Compound pieces are indicated by concatenating the description of all their moves. E.g. fmWfcF describes the move of the Shatranj Pawn, and BN the Archbishop.

Directional modifiers

  • f forward
  • b backward
  • l left
  • r right
  • v vertical; shorthand for f or b
  • s sideways; shorthand for l or r
  • h half; only in combination with a direction
  • While the first four indicate single directions for the orthogonal (e.g. W) atoms, they indicate pairs of moves for diagonal (e.g. B) or oblique (e.g. N) atoms, where there are always two moves that go equally far in the mentioned direction. A second modifier prefix for the perpendicular direction can then combine with it to specify an individual move. (So frB is one diagonal slide to the forward right, frR is two slides, one forward, the other to the right!) In combinations with a 'two-way' direction (v or s) the other direction is distributed: vr means fr or br. When combining is not desired, it can be prevented by doubling the modifier for the direction (e.g. ffrrN describes a piece with 4 of the Knight's 8 moves: the two forwardmost, and the two furthest to the right). An h can combine with a preceding direction on oblique atoms to extend the meaning from a pair to all four moves that have a component in that direction (fhN). It can also combine with with a following l or r, to indicate a 'chiral set' of four moves of an oblique atom that are related only through rotation (as opposed to reflection), and stray left or right of the orthogonal axes. (E.g. a hrN on e4 has moves to f6, g3, d2 and c5.)

    Modes and other

    • m ('move') can move to empty square
    • c can capture enemy piece
    • p can hop over an occupied square (the 'mount') in its path
    • g ('grasshop') like p, but must land one step behind the obstacle
    • n ('non-jumping') a leap (possibly part of a rider move) cannot jump over an occupied square
    • j ('jumping') opposite of n, leap that only can be made if the jumped square is occupied
    • o ('cylinder') can move off board on left and right edges, to renter on the opposite edge
    • z ('zig-zag') a rider that alternates two directions of the leap it repeats
    • q ('circular') a rider that rotates the directions of the leap it repeats on every step by the same amount

    The above list gives the meaning of some mode modifiers when they are used on simple moves, as in Betza's original notation system. Note that the n and j are meaningless on steps (W, F), and ambiguous when used on an oblique atom. Jumping and hopping are independent properties; an npDD on a1 can hop over a mount on a3 or a5, but not over obstacles on a2 or a4. Also note that hops are basically two-leg moves (hop-on, hop-off), and that g involves some kind of a range toggle: a move that could make arbitrarily many steps to reach the 'mount', can only make a single leap to hop off it, as if a rider turned into a leaper at the location of the mount. It thus requires the mount to be on the last square the move visited before the destination. We could define it to do the reverse on a leaper atom: hop on with a single leap, but make arbitrarily many leaps after hopping off, so that the mount must be on the first visited square (gK = Contra-Grasshopper).

    The XBetza extension

    XBetza is the move notation used by the XBoard user interface to allow communication of game rules with the engine, and by the Interactive Diagrams used on this website. It is an extended version of the original Betza notation. This involves addition of a number of 'convenience' modifiers and atoms for common things that otherwise would be cumbersome or impossible: e for en-passant capture, O for castling (with the piece on the board edge), a U for a Universal Leaper.

    But the most important extension is that it allows description of 'multi-leg moves', which are a succession of elementary leaper or rider moves. Splitting a move into legs can be necessary not only because the legs have different directions or steps, but also because some condition has to be satisfied at the 'transition square' (e.g. that it must be empty), or some task has to be performed there (like making a capture). With the aid of multi-leg moves, it becomes possible to precisely describe all kinds of exotic pieces, such as lame leapers, bent riders, hook movers, locusts and multi-capturers, pieces that push other pieces, or induce extra moves in those... Most variants would not use such pieces at all, and if you are not interested in using them, you can safely skip the rest of this section.

    The a modifier ('again') is used to indicate multi-leg moving, and it acts as punctuation of the other modifiers, dividing the latter into groups, each group applying to a different leg. Thus camK would mean an initial cK leg, mandatorily followed by an mK leg, i.e. a hit-and-run capture by a double-moving King. It would not be allowed to capture two pieces (as the second leg is only m), or pass through an empty square to a non-adjacent target. And it cannot stay at the adjacent square where it captured a piece either; a multi-leg move must always be made in its entirety, or not at all.

    Non-final legs of a move have a wider variety of modes than final (or only) legs, for it is not necessary that a former occupant of the transit square has to be cleared away to make room for the piece, as that piece has no intention to stay there and will move away with the continuation leg. The meaning of the familar modifiers is therefore often slightly different depending on which leg of the move (final/non-final or initial/continuation) they are used. For instance, directions on continuation legs are always specified relative to the preceding leg, as we want the notation to specify moves of a fixed shape. Thus, f should be read as "in the same direction", (e.g. mafF is a lame Alfil.) and fs as "deflected by 45 degrees left or right". This rotation of the frame of reference means that continuation legs always use the same system for specifying directions as the K atom: even for oblique and diagonal atoms, f in a continuation leg specifies only a single move.

    Repeated leaps of a purely orthogonal or diagonal atom can always be described in the orthogonal system (f, b, r or l). But for added flexibility, XBetza also allows specification of diagonal continuation of those. Such continuations then belong to a different atom as the previous leg: W interchanges with F, D with A and G with H ('atom rotation'). The atom used to describe a multi-leg move thus merely applies to the initial leg of the move; how the move continues from there is fully specified by the directional modifiers. Thus mafsW is the Xiangqi Horse, and after the initial mW the second leg is really an F move.

    Besides atom rotation, XBetza also allows the range to differ from leg to leg. Here also the atom, possibly together with an explicit range suffix, only specifies the range of the initial leg. Normally, continuation legs would be rider or leaper, inheriting the range from the previous leg. But some modifiers (in particular g and y) cause 'range toggling', continuing slider as leaper, and vice versa.

    The p and g modifiers have a slightly different meaning in non-final legs than they had in the original Betza system; they only describe the hop onto the mount, and leave it for a subsequent leg to describe the hop off. We could say that on final legs, where staying on the same square as the mount would not be allowed, these modifiers imply an extra leg in the same direction, which then does not have to be written explicitly. So pR is really shorthand for pafR, and gQ shorthand for gafQ, where the g only differs from the p by specifying an additional range toggle. This allows us to specify a different kind of hop-off when we need it, e.g. pafsR for a hopping 'bifurcator' that turns a corner at the mount. It also explains why p and g really are modes like m and c, rather than independent properties that could be combined with a mode, as the Pao capture cpR suggests; the latter really means pafcR when we write the 'hidden leg' for hopping off explicitly, so that the p and c apply to different legs. On the same leg, specifying two modes in general means that it can do one as well as the other: cpafR = cafRpafR, a compound of a (possibly double capturing) Rook locust and a normal Rook hopper.

    XBetza uses y to indicate range toggling should occur at the end of a leg that ends on an empty square. This can be used when you need leaper-slider alternation in pieces that change direction on their own steam, rather than on encountering an obstacle in their path.

    Betza notation derives its compactness from smart choice of defaults, making modifiers redundant in the most common cases. E.g. by default the mode of the move is mc, and the direction set 'all directions implied by the atom'. To retain this virtue in multi-leg moves, we adopt the rule that non-final legs (before an a) by default have mode m, while continuation legs (after an a) by default move in all directions belonging to the atom, except to squares that it already visited on an earlier leg (or the square it started from). So aK means a double-moving King, but does not include a turn pass, or any locust capture.

    Click here to open color legend

    satellite=betza files=12 ranks=12 graphicsDir=/membergraphics/MSelven-chess/ whitePrefix=w blackPrefix=b graphicsType=png squareSize=34 useMarkers=1 maxPromote=0 symmetry=rotate checker:P:fmFcafmFimfD:pawn:a2-l2 betza1:X:mRpafscRifhN:marshall:h1 betza2:Y:gQ:archbishop:e1 rook::::a1,l1 king::::g1

    XBetza sandbox

    Type a move definition below, and then click
    on the move above you want to replace.

    Betza string:

    To practice a bit with (X)Betza notation you can use this interactive diagram, which allows you to (re)define the moves for all piece in it, through the text entry below the piece table.

    The diagram supports most of the Betza notation as discussed above; the modifiers n and j only work predictably on diagonal and orthogonal atoms, though. It also supports the XBetza extension (but not more than one locust capture per turn). The new atoms are:

    • U Universal Leaper (Kraken), can teleport to every square except the one it is on.
    • O Castling with the piece at the board edge in the given direction. The range specifies the King step.
    • C Camel. Synonymous with L.
    • Z Zebra. Synonymous with J.
    • X Extended. Suffix to leaper atoms, and boosts those by 3 orthogonal steps. (FX = Giraffe)
    • Y Similar to X, but gives a 2-step diagonal boost. (DY = Di-Knight)
    • I Imitator. Represents all moves of the last-moved non-imitator. See below.

    Multi-leg moves (changing mode, range and/or direction between legs) are defined by joining groups of modifiers for the individual legs by a ('again') modifiers. (More about a...) New modifiers, or modifiers with a slightly different meaning on non-final legs:

    • e ('en passant') new mode: capture a lame leaper on a square it just passed through. in and nn moves create e.p. rights.
    • d ('destroy') new mode: capture own piece.
    • k ('king') new mode: move can only be used to capture a royal piece (deliver check). (WfkR = Xiangqi King)
    • x ('excite') activate a piece without moving, that piece making the remaining legs of the specified move. (mNxaN) Works in reverse when no move follows, by borrowing the moves from the target piece. (xK)
    • u ('unload') the (empty) starting square of the leg will receive the piece captured by the move. (udQ = Swapper)
    • p ('hop') in non-final leg: leg ends on an occupied square, without disturbing the contents. (mRpafscR)
    • g ('grasshop') in non-final leg: as p, but next leg will have different range (leaper <-> rider).
    • y ('fork') in non-final leg: as g, but on an empty square. (FyafsF = Griffon)
    • j on sliding move makes the first step of the slide double the size, skipping one square. (jB = Ski-Bishop)
    • oo ('cylinder') moves wrap in toroidal fashion (left <-> right and top <-> bottom).
    • q ('circular') rider bends 45-degrees in same direction on every step. (qN = Rose)
    • i ('initial') as leading modifier: the described move is available only on a piece's initial move. (KimN)
    • i ('iso') in continuation leg: slider leg has as many steps as a previous slider leg. (aivsQ = Sissa)
    • n on a (repeated) stepper atom (W, F, B, R): creates e.p. rights on the square(s) it steps to or slides through.
    • in besides the normal meaning of non-jumping initial move, this creates e.p. rights on the squares it could be blocked.
    • nn besides the normal meaning of non-jumping, this creates e.p. rights on the squares the move could be blocked.
    • hr ('chiral'). new direction set: all oblique moves bending right of orthogonals. (hrN)
    • hl mirror image of hr. Do not confuse these with rh/lh, (right and left half ).

    The diagram recognizes an asterisk * as a special range indicator, indicating a location-dependent range, namely the number of ranks between the current square and the enemy board half (but at least 1). A move with this range will always create e.p. rights on the squares it passes through.

    The Imitator

    A new atom in XBetza is I. Unlike the other atoms, it does not represent a fixed move: it stands for "all moves of the most recently moved (or imitated) piece type". Not all modifiers are meaningful on an Imitator. Directions are limited to the vertical ones, f (default) and b. The latter would flip the moves of the imitated piece, like the opponent would move it. (So when imitating a Pawn you could only move it backwards!) The modes m, c, e, k and d would only cause imitation of moves of the corresponding modes in the imitated piece. Note that c implies k, so kI could capture a King when imitating pieces without an explicit k mode (but could not use the captures of the latter to capture anything else).

    Some tricks

    Legs of a move can be 'seamlessly' connected by specifying mode mp for the first leg of the pair. This means 'hop' (i.e. move over an occupied square) or 'move' (i.e. over an unoccupied square), so that the move continues with the next leg no matter what the square contained. This can be useful to mimic larger leaps in a multi-leg move of a King atom. E.g. mpafsK would be a Knight: after the first King step it always continues with a second one at 45-degree angle (fs).

    Unusual capture methods can often be obtained by moving to the destination through a detour that visits the piece that must disappear, with a non-final leg that captures. E.g. rifle capture by a Rook would be caibR, making a normal Rook capture, but moving back exactly afterwards.

    You can mimic advance sensing of a piece in your path by hopping on it, and then stepping off in the opposite direction. E.g. a Bifurcator, which moves as Rook but deflects 45 degrees on the square before an obstacle is gabyabsR. The g-type hop toggles the Rook range to 1, so the second leg steps back to the square before the mount, but since it is a 'y' leg the range toggles back to sliding for the third leg, in the desired diagonal directions.

    Ideas for the future

    XBetza is not a finished project; as the need arises, other atoms can be added, and the meaning of modifiers could be extended. (Sadly adding entirely new modifiers will be difficult, as only the letter w is still unused.) Some ideas for what might be useful enough to justify adding it are mentioned below.

    We could have more 'flexible' atoms, similar to I. E.g. M (for 'Mirror'), which targets all squares containing pieces that target it, with the same modes.

    The meaning of o could be extended to only imply wrapping when used in a final leg, but allow pieces to venture off-board without wrapping in non-final legs. This would allow moves to 'probe' for the presence of a board edge by attempting to step off-board and back. E.g. oabyaK for a (partial) Edge-Hog move.

    There currently is no type-selectivity in XBetza, other than k, which distinguishes royal types from others. Perhaps a more general method should be devised to restrict moves depending on the piece type in the target square, rather than just its color.

    It could be indicated that a move must promote (e.g. as a + suffix behind the entire description).

    We could allow a number behind a modifiers, to indicate the preceding leg can be made repeatedly, up to the given number of times. To be more precise, it would group the a with the directional modifiers of the leg after it, and the other modifiers of the leg before it, and repeat that group. E.g. spa2fcR would repeat the paf group, and thus (amongst others) mean spafpafcR a sideway capture that hops over 2 pieces.

    Perhaps it should be allowed to enclose larger groups of (multiple-)a-containing modifiers in parentheses suffixed by a number, to indicate potential repetition of that entire group. (s(paf)2cR)

    Appendix: some case studies

    Lame leapers (Falcon) - To unambiguously define a lame leap, specify it as a multi-leg move with a path that visits all squares where the move can be blocked before it reaches its target. Usually the move has to be broken down into King steps for that, and the atom to be used will be K, W or F, depending on the allowed first steps. E.g. a Xiangqi Horse would step to a W square, then continue at 45-degree angle (i.e. fs) for a second step, so you get afsW. That the W square must be empty and that it can both move and capture to the N squares (mafsmcW) is by default. A lame Camel needs 3 steps: afafsW, blockable on W and D squares. Another path for it would be afsafF, blockable on F and N squares. A third path would be afraflW, blockable on W and N squares. Unfortunately this path cannot be described together with its mirror image aflafrW with the use of s, like the others, as there would be no way to force deflection in opposite directions. So a multi-path lame Camel would be the combination of all three: afafsWafsafFafraflWaflafrW. Pretty awful, but what can you expect from a piece with three different moves, all complex? The Falcon has three similar paths to the Zebra squares, and in fact their shape is so similar that they can be described by the same turning of corners, but just starting in intermediate directions. The W and F of the Camel destinations then combine with the F or W for the Zebra destinations, so that we get: Falcon = afafsKafsafKafraflKaflafrK.

    Hook movers (Sissa) - A hook mover is a slider that can turn a corner anywhere in its trajectory. Its move thus has two variable-length legs, giving it a 2-dimensonal set of target squares. The Hook Mover of Dai Dai Shogi is a Rook that can turn one 90-degree corner both left and right: asR. To also include moves that do not step sideways, we have to add a plain R to its description: RasR. XBetza offers a method to force the slider moves to have equal number of steps, by putting an i ('iso') on the later one: RaisR would be a hook mover with equal length legs, reaching the same targets as a Bishop, but through an entirely different path. The Sissa combines equal-length orthogonal and diagonal legs, starting with any Queen move, and turning 45-degree or 135-degree corners for a following R or B leg. This can be written as aivsQ, because vertical (straight ahead or back) and sideways (90-degree left or right) directions on Q combine to intermediate ones, and vs = (f+b)s = fs+bs = f(r+l)+b(r+l) = fr+fl+br+bl.

    Bent sliders (Griffon) - These combine a single slider leg with a fixed-length slide (usually a single step): the Griffon starts stepping to an F square, but then slides as R away from those. We have to draw on XBetza's range-toggling feature for doing that, in this case y, which means "m and continue with 'opposite' range". So yafF would be a Ferz step followed by a second FF (= B) leg in the same direction. This differs from a normal B because it cannot capture on the first step (as the default mode there is m) and thus describes the Tamerlane Picket. The only difference with the Griffon is that the latter makes the second leg in a 45-degree bent direction (fs), so we get yafsF, where s indicates deflection to the left as well as right is allowed. Like the Picket, this move cannot end on an F square; the second leg makes at least one step. But that move can be added separately. So Griffon = FyafsF.

    Area moves - In Tenjiku Shogi some pieces can make up to 3 King steps in arbitrary directions. XBetza can handle that by specifying no directions at all on the continuation legs. This defaults to "all directions except return", where return means visiting a square that was visited earlier. (This is to not automatically include null moves, which can always be specified separately if they are desired.) So aK would be a piece that makes two K steps, but the second doesn't go exactly back. It can thus reach all K, N, A and D squares on an empty board. Similarly aaK would make three King steps, and the area move = KaKaaK.

    Locusts (Checker) - Locusts capture pieces from other squares than those they move to. (Like e.p. capture!) XBetza describes this with a multi-leg move that first makes the capture in the ordinary way, followed my a leg that moves to the destination. A Checker captures by jumping to the second square diagonally (which must be empty), capturing what it jumped over. This becomes a fcF capture, followed by mfF, so fcafmF. Together with the non-capturing move we get Checker = fmFfcafmF.

    Multi-capture (Lion) - The Chu Shogi Lion can make up to two K moves per turn, not having to stop at a capture. It can also make the combination of the two as direct leap (over other pieces), if it wants. A compact way to describe this is mpcaK, where the first leg can now visit an empty square, hop onto an occupant, or capture an enemy there, whatever it choses, and then continues with another King move (which, by default, can also move or capture). The single K moves can always be made though a (possibly hopping) detour. But moves back to the starting square are not included in this, by the directional default for continuation legs. And the Lion can make those both as capture or as move (but not as hop!) in the first leg. So the total Lion would be mpcaKmcabK. It is less obscure to mention all targets that could be reached through a direct leap explicitly, though, and reserve the multi-leg description for the locust captures and the (conditional) turn pass: Lion = KNADcaKmcabK.

    Rifle capture (Rifle Rook) - In Rifle Chess captures are made without moving, by just removing pieces that could have been captured in orthodox Chess from the board. This is a special form of locust capture, and can be described in XBetza by a back-and-forth two-leg move (as was already done in the Lion's cabK above). For sliders you would have to make sure that they end up on the square they started, i.e. that both legs were equally long. The XBetza i can enforce this: Rifle Rook = caibR.

    Bifurcator (Collider) - A bifurcator is a bent hopper. Hoppers basically have two-leg moves (hop-on, hop-off), which normally are taken in the same direction. XBetza generalizes the meaning of the Betza p and g modifiers by having them imply the hop-off when used on a final leg: pR means pafR, where the first p leg hops onto the mount, and the fR then hops off in the same direction. For bifurcator this direction gets changed: pafsR would turn a 45-degree corner at the mount, to continue as a Bishop. In principle the hop-on and hop-off slides can be bent themselves: we can conceive a 'Griffonhopper', which moves as a Griffon but can only land behind a piece in its path. A Collider is a slider that deflects at an angle on the square just before an obstacle in its primary path. This can be described as a hop that uses the obstructing piece as a mount, but then hops off exactly backwards to land on the square where it should turn the corner, and then does turn that corner (which is now 135 degrees (bs), relative to the direction it is now going. So three legs, slide - step - slide, and thus two range toggles. The first range toggle happens on the mount, so we use g rather than p for the mode of that leg. The second toggle happens on an empty square, so y rather than m there. This gives us gabyabsR for the Collider.

    Displacing pieces (Valkyrie) - Where a Locust just removes pieces from 'other' squares, XBetza also allows such pieces to re-appear elsewhere. This is specified by a u modifier, which is not an alternative to the leg modes m, c, d, y, p and g, but can combine with any of those. Because it specifies what happens on the starting square of the leg, rather than at the end. Namely that anything captured by the move must reappear there. So dQ is a Queen that captures friendly pieces, but udQ is a piece that can swap location with any friendly piece a Queen move away. To swap with pieces of all creeds you would use ucdQ. This can also be used in a multi-leg setting. The Valkyrie from Odin's Rune Chess moves as Q, but can make a captured friend reappear not only on its starting square, but on any square it moved through. This can be described by a two-leg move first visiting the square where the friend must appear (still empty at that time), and then continuing in the same direction to kick the friend to that intermediate square, through afudQ, where the second leg now deposits the friend on its starting square, which must be between the pieces. This does not include a pure swap move, so the full Valkyrie = QudQafudQ.

    Move induction (Relay Knight) - In Knight-Relay Chess Knights cannot capture. But they endow friendly pieces that are one Knight leap away with the capability to make a Knight leap themselves. XBetza treats such induced moves as moves of the inducer, rather than of the piece that will make them. The induction process and the move it results in must be coupled to one multi-leg move, the first (induction) part ending in a leg with an x mode ('excite'), the second part the move that the piece at the x target will now be able to make. Each of these parts can in principle be multi-leg as well. But in Knight-Relay Chess they are just Knight leaps, so we get a two-leg move xaN (on Knights), i.e. xN for the first (induction) leg to reach a friend on an N square, and then allow that friend to make the second leg, a normal N move. The full Relay Knight is thus mNxaN.

    Move borrowing - There is no use for x in the above meaning on a final leg, as there would be no later legs left to induce on the target. So XBetza interprets x in that case as reverse induction, where the target induces moves in the source. So xK describes a piece that can move like all friendly pieces adjacent to it: it reaches those through a K step, and borrows their moves. The King of Odin's Rune Chess moves this way.

    e.p. capture (FIDE and Metamachy Pawn) - XBetza has a separate mode for e.p. capture (e). To provide targets for that mode, it also has a way to specify which moves generate e.p. rights. This has gone through some evolution; the legacy method is that any move (initial leg) that carries an in modifier combination will create e.p. rights on the squares it passes through (in addition to the normal meaning of being non-jumping and only being available as initial move). This allowed a full decription of the FIDE Pawn: fmWfceFifmnD. Metamachy allows non-initial double pushes, and e.p. capture of thus moved Pawns (fmWfceFfmnnD and Princes (KfmnnD). To handle that a doubling of n was also made to create rights (and otherwise mean the same as a single n). A new, more precise method allows creation of an arbitrary number of e.p. squares by visiting those in a multi-leg move consisting of K steps, by putting an n on the leg leading to the square. (This n would otherwise be meaningless on a K step.) Usually variants allow e.p. capture only on squares where the move could be blocked, so you would have to lead the move over the square anyway to specify the lameness. In a hypothetical CV where Pawns have a move as a (forward) Xiangqi Horse, XBetza could describe it as fnafsmW to make sure they could be e.p. captured on the W square they moved through. This would also work on repeated stepper atoms; e.g. ifnmW6 would describe an initial (non-capturing) move of up to 6 (orthogonal) steps forward, creating e.p. rights on every square passed through, while ifmW6 would not create any rights.

    This 'user submitted' page is a collaboration between the posting user and the Chess Variant Pages. Registered contributors to the Chess Variant Pages have the ability to post their own works, subject to review and editing by the Chess Variant Pages Editorial Staff.

    By H. G. Muller.
    Web page created: 2020-06-03. Web page last updated: 2020-06-17