Translation files live here: the .pot template, one .po per language, the .mo PHP reads, and the
.json files the Studio's JavaScript reads.

The interface is written in ENGLISH and every string goes through the `aipb` text domain, on both
sides: `__()` and friends in PHP, `wp.i18n.__()` in the JS (see the wrapper at the top of
assets/studio.js, assets/brand.js and assets/model.js; assets/studio-style.js borrows the Studio's).


Which language a site sees
--------------------------

By default the one WordPress is already speaking — `determine_locale()`, so an editor who has set a
language on their own profile gets Aura in that language even on a site set to another.

Aura → Settings has an override, «Interface language», for the case where the tool's language and
the site's language are not the same wish. It applies to the `aipb` domain and to nothing else: the
rest of the admin, the other plugins and the site itself are untouched. See includes/class-i18n.php.

English needs no catalogue: it is the language the sources are written in, so choosing it simply
means no file is found and gettext falls back to what is in the code.


Rebuilding, in order
--------------------

    php bin/make-pot.php     # the template, read straight from the sources
    php bin/merge-po.php     # every .po back in line with it, translations kept
    php bin/make-mo.php      # the .mo PHP reads
    php bin/make-json.php    # the .json files the Studio reads

None of the four has any dependency: they read and write the formats themselves, because WP-CLI is
not on every machine that builds a zip and a catalogue that only builds on one laptop ships stale.
With WP-CLI available these are the equivalents:

    wp i18n make-pot . languages/aipb.pot
    wp i18n update-po languages/aipb.pot languages/
    wp i18n make-mo languages/
    wp i18n make-json languages/ --no-purge

ALL FOUR OUTPUTS ARE COMMITTED. `bin/` is excluded from the released zip, so whatever is on disk
here is what the customer gets.

`php bin/test.php --only=i18n` checks that the .mo and the .json files match their .po, that no
entry survives for a string the sources no longer contain, and that no translation has lost a
placeholder or a tag along the way. Run it after touching a .po.


Adding a language
-----------------

Copy aipb.pot to languages/aipb-<locale>.po, fill in the `Language:` and `Plural-Forms:` headers,
translate, then run make-mo and make-json. The language appears in the Settings menu on its own —
the list is read from the .mo files on disk — but its NAME comes from a short map in
includes/class-i18n.php (`aipb_language_names`); without an entry there the menu shows the locale
code.
