on master help sign in
Merge pull request #1549 from urbit/move-dojo-tools

move dojo tools to user manual and delete dist FAQ

commit3ffbe7472dfd271c898252860408fae8762e98af authortinnus-napbus <77721746+tinnus-napbus@users.noreply.github.com> dateMon 27 Jun 2022, 23:54 (4 years ago) parentde1f7e2cfdbc8d
5 files changed+226−320
content/docs/userspace/dist/_index.md−4 content/docs/userspace/dist/dist.md+1−3 content/docs/userspace/gall-guide/3-imports-and-aliases.md+1−2 content/using/os/dist-faq.md−162 content/docs/userspace/dist/tools.md → content/using/os/dojo-tools.md+224−149
content/docs/userspace/dist/_index.md−4
@@ -23,7 +23,3 @@ Documentation of `glob`s (client bundles).
2323## [Guide](/docs/userspace/dist/guide)
2424
2525A walkthrough of creating, installing and publishing a new desk with a tile and front-end.
26−
27−## [Dojo Tools](/docs/userspace/dist/tools)
28−
29−Documentation of useful generators for managing and distributing desks.
content/docs/userspace/dist/dist.md+1−3
@@ -73,7 +73,7 @@ Suspending a desk turns off all its agents, saving their states in Gall. If ther
7373
7474Turning agents on and off is managed declaratively, rather than imperatively. Kiln maintains state for each desk about which agents should be forced on and which should be forced off. The set of running agents is now a function of the desk's `/desk/bill` manifest file and that user configuration state in Kiln. This means starting or stopping an agent is idempotent, both in Kiln and Gall.
7575
76−For details of the generators for managing desks and agents in Kiln, see the [`Dojo Tools`](/docs/userspace/dist/tools) document.
76+For details of the generators for managing desks and agents in Kiln, see the [`Dojo Tools`](/using/os/dojo-tools) document.
7777
7878### Landscape apps
7979
@@ -101,5 +101,3 @@ For further details of globs, see the [Glob](/docs/userspace/dist/glob) document
101101- [Docket Files](/docs/userspace/dist/docket) - Documentation of docket files.
102102
103103- [Guide](/docs/userspace/dist/guide) - A walkthrough of creating, installing and publishing a new desk with a tile and front-end.
104−
105−- [Dojo Tools](/docs/userspace/dist/tools) - Documentation of useful generators for managing and distributing desks.
content/docs/userspace/gall-guide/3-imports-and-aliases.md+1−2
@@ -219,8 +219,7 @@ we can try out `dbug`. To start it, run the following in the dojo:
219219```
220220
221221For details of using the `|rein` generator, see the [Dojo
222−Tools](/docs/userspace/dist/tools#rein) section of the software distribution
223−documentation.
222+Tools](/using/os/dojo-tools#rein) documentation.
224223
225224Now our agent should be running, so let's try out `dbug`. In the dojo, let's try
226225poking our agent with the `+dbug` generator:
content/using/os/dist-faq.mddeleted−162
@@ -1,162 +0,0 @@
1−+++
2−title = "Software Distribution FAQ"
3−template = "doc.html"
4−weight = 9
5−+++
6−
7−This document concerns the September 2021 release of the software distribution OTA, codenamed "Grid." It is current as of 2021-10-01 at 05:52 AM EST.
8−
9−## Changes
10−
11−**How do I know the OTA succeeded?`**
12−
13−Run `+trouble`.
14−You should see entries for five desks: `%bitcoin`, `%base`, `%landscape`, `%webterm`, and `%garden`.
15−
16−**How do I get back to Landscape to see my DMs?**
17−
18−What was formerly called "Landscape" is now the Groups app. You can access DMs and groups via the "Groups" tile.
19−
20−**Where did my app tiles in Landscape go?**
21−
22−For apps ported to software distribution, tiles will be shown in the home screen.
23−
24−If you're already running non-Tlon apps, those apps will stop running, but the state will be preserved.
25−
26−If the developer provides a version of the app over software distribution and you install it, the new app will migrate the old state.
27−
28−**What's the base hash?**
29−
30−After this OTA there is a base hash _per app desk_:
31−
32−However, this may differ from ship to ship for now, so instead check the %cz hash.
33−The table lists the suffixes (last 5 characters) of the %cz hashes.
34−
35−| Software | Desk | %cz Hash |
36−| ------------ | ---------- | --------- |
37−| Arvo/OS | %base | `krdh3` |
38−| Home Screen | %garden | `7ai82` |
39−| Groups | %landscape | `m1nt8` |
40−| BTC Wallet | %bitcoin | `8kkfo` |
41−| Web Terminal | %webterm | `b2pme` |
42−
43−
44−
45−Run `+trouble` to see these hashes.
46−
47−**How do I see the base hashes for my ship?**
48−
49−The `+trouble` generator is now an alias for `+vats`.
50−Running either one will show the base hashes for every installed app desk.
51−
52−Clicking the settings icon on the top left of the home screen provides an 'About' choice.
53−Selecting this will bring up an app info widget for the system app, which will show the base hash of the `%garden` desk.
54−
55−Selecting the menu icon in the top right of an application tile provides an 'App Info' choice.
56−Selecting this will bring up an app info widget for the selected application, which will show its desk name and the base hash of its desk.
57−
58−Groups (formerly Landscape) will no longer show a base hash within the app.
59−
60−## Troubleshooting
61−
62−**The OTA is taking a long time.**
63−
64−This is expected and unfortunately unavoidable.
65−Your ship will be unresponsive for several minutes, possibly up to half an hour.
66−This is normal.
67−
68−Technical note: this is because OTAs are run as a single Arvo event which must compile the OTA and run migrations.
69−
70−**I saw crashes and stack traces during the OTA.**
71−
72−Some stack traces are expected. The `%goad` and `%publish` apps will not be present in the OTA,
73−and Clay will complain about not being able to build them. You will also see some Clay `read-at-aeon-fail` errors.
74−
75−**I haven't gotten the OTA yet and I can't post in some groups or DM some people.**
76−
77−This OTA includes breaking changes to `%graph-store` which stores and shares messages, notebooks, and collections.
78−Ships with the OTA will not be able to communicate over graph store with ships without the OTA.
79−
80−**I have gotten the OTA and I can't post in some groups or DM some people.**
81−
82−See above. Once your peers receive the OTA, you will be able to communicate again.
83−
84−Your sponsor or your sponsor's sponsor also might have only gotten the first OTA
85−but not the latest one, if either of them are not Tlon stars/galaxies. Try
86−installing from one of Tlon's stars with
87−
88−```
89−|install ~litzod %kids, =local %base
90−|install ~litzod %garden
91−|install ~litzod %landscape
92−|install ~litzod %webterm
93−|install ~litzod %bitcoin
94−```
95−
96−**Can I still `|hi` between pre and post OTA ships?**
97−
98−`|hi` will continue to work between pre and post OTA ships.
99−
100−**Can I still use `|ota` to select my OTA provider?**
101−
102−`|ota` will continue to work on ships without the OTA, even if their OTA provider is running the OTA.
103−After the OTA, the `|ota` command is removed and is replaced by the `|install` command.
104−
105−**The OTA failed for me with `%error-validating`.**
106−
107−Tlon is aware of [this issue](https://github.com/urbit/urbit/issues/5271) and is working on a fix.
108−
109−The error will print near the bottom of the output from the failed OTA, and will be similar to:
110−
111−```
112−[ %error-validating
113− /backup/ship/~littel-wolfur/vim/~2020.12.11..06.50.27..c12d/graph-update
114−]
115−[ %validate-page-fail
116− /backup/ship/~littel-wolfur/vim/~2020.12.11..06.50.27..c12d/graph-update
117− %from
118− %graph-update
119−]
120−```
121−
122−This is caused by some leftover backup files from a previous migration for which Clay no longer has marks.
123−
124−As a workaround: you can remove these files and retry the OTA:
125−
126−dojo:
127−
128−```
129−|unmount %home
130−|mount /=home=
131−```
132−
133−bash:
134−
135−```bash
136−rm -r your-ship/home/backup
137−```
138−
139−dojo:
140−
141−```
142−|commit %home
143−|ota (sein:title our now our) %kids
144−```
145−
146−**The OTA failed for me with `%mate-conflict`**
147−
148−You can instruct Clay to simply override the contents of the relevant files with the version from your sponsor:
149−
150−dojo:
151−
152−```
153−|merge %home (sein:title our now our) %kids, =gem %take-that
154−```
155−
156−This will start the upgrade. Note that on a galaxy, star, or planet, you should also run
157−
158−```
159−|merge %kids (sein:title our now our) %kids, =gem %only-that
160−```
161−
162−to make sure OTAs go out to your sponsored ships (stars, planets, or moons).
content/docs/userspace/dist/tools.md → content/using/os/dojo-tools.mdrenamed+224−149
@@ -1,86 +1,17 @@
11+++
22title = "Dojo Tools"
3−weight = 5
3+weight = 9
44template = "doc.html"
55+++
66
7−A number of generators are included for managing and viewing the status of desks and their agents. Each of these are documented below.
7+## Desks, apps and updates
88
9−Note that some old generators have been replaced:
10−
11−- `|start` - Replaced with [`|rein`](#rein).
12−- `|ota` - Replaced with [`|install`](#install), [`|uninstall`](#uninstall), [`|pause`](#pause) and [`|resume`](#resume).
13−- `|fade` - Replaced with [`|nuke`](#nuke).
14−- `|doze` - Replaced with [`|rein`](#rein) or [`|suspend`](#suspend).
15−- `|wake` - Replaced with [`|rein`](#rein) or [`|revive`](#revive).
16−- `+trouble` - This still exists but is deprecated, and is now an alias for [`+vats`](#vats).
17−
18−---
19−
20−## `+vats`
21−
22−Print out the status of each installed desk.
23−
24−Desks in Clay which aren't installed will be omitted.
25−
26−Fields:
27−
28−- `/sys/kelvin` - The version of `%zuse` the desk is compatible with.
29−- `base hash` - The merge base (common ancestor) between the desk and its upstream source.
30−- `%cz hash` - The hash of the desk.
31−- `app status` - May be `suspended` or `running`.
32−- `force on` - The set of agents on the desk which have been manually started despite not being on the `desk.bill` manifest.
33−- `force off` - The set of agents on the desk which have been manually stopped despite being on the `desk.bill` manifest.
34−- `publishing ship` - The original publisher if the source ship is republishing the desk.
35−- `updates` - May be `local`, `tracking` or `paused`. Local means it will receive updates via commits on the local ship. Tracking means it will receive updates from the `source ship`. Paused means it will not receive updates.
36−- `source desk` - The desk on the `source ship`.
37−- `source aeon` - The revision number of the desk on the `source ship`.
38−- `pending updates` - Updates waiting to be applied due to incompatibility.
39−
40−#### Arguments
41−
42−None.
43−
44−#### Examples
45−
46−```
47−> +vats
48−%base
49− /sys/kelvin: [%zuse 418]
50− base hash: ~
51− %cz hash: 0v6.2nqmu.oqm24.ighl6.n0gp9.s8res.feql1.dl8ap.isli3.jk0hu.acrd2
52− app status: running
53− force on: ~
54− force off: ~
55− publishing ship: ~
56− updates: tracking
57− source ship: ~zod
58− source desk: %base
59− source aeon: 3
60− pending updates: ~
61−::
62−%garden
63− /sys/kelvin: [%zuse 418]
64− base hash: ~
65− %cz hash: 0v1e.2h7hs.elq3g.1sdt7.qfga6.ganga.7p95j.aog44.8p5fe.kpr6v.7ai82
66− app status: running
67− force on: ~
68− force off: ~
69− publishing ship: ~
70− updates: tracking
71− source ship: ~zod
72− source desk: %garden
73− source aeon: 3
74− pending updates: ~
75−```
76−
77−---
78−
79−## `+agents`
9+### `+agents`
8010
8111Print out the status of Gall agents on a desk.
8212
83−Agents may either be `archived` or `running`. Nuked or unstarted agents which are not on the manifest are omitted.
13+Agents may either be `archived` or `running`. Nuked or unstarted agents which
14+are not on the manifest are omitted.
8415
8516#### Arguments
8617
@@ -101,53 +32,58 @@ status: running %hark-store
10132
10233---
10334
104−## `|suspend`
35+### `|bump`
10536
106−Shut down all agents on a desk, archiving their states.
37+Try to apply a kernel update.
10738
108−The tile in the homescreen (if it has one) will turn gray and say "Suspended" in the top-left corner. This generator does the same thing as selecting "Suspend" from an app tile's hamburger menu.
39+If `%zuse`'s kelvin version has decreased, try to apply the update. If any desks
40+are incompatible with the new `%zuse` version, the update will fail. The update
41+can be forced with the optional `force` argument, in which case incompatible
42+desks will be `|suspend`ed. The `set` of desks to omit (and therefore suspend)
43+can also be explicitly specified with the optional `except` argument.
10944
11045#### Arguments
11146
47+All optional:
48+
11249```
113−desk
50+, =force ?, =except (set desk)
11451```
11552
11653#### Examples
11754
55+Try to apply update, failing if blocked by any desks:
56+
11857```
119−|suspend %bitcoin
58+|bump
12059```
12160
122−---
123−
124−## `|revive`
125−
126−Revive all agents on a desk, migrating archived states.
127−
128−All agents specified in `desk.bill` which are suspended will be restarted. If updates to the agents have occurred since their states were archived, they'll be migrated with the state transition functions in the agent. This generator does the same thing as selecting "Resume App" from the app tile's hamburger menu.
129−
130−#### Arguments
61+Force the update, suspending incompatible desks:
13162
13263```
133−desk
64+|bump, =force &
13465```
13566
136−#### Examples
67+Apply kernel update, omitting and suspending the specified desks:
13768
13869```
139−|revive %bitcoin
70+|bump, =except (silt ~[%bitcoin %webterm])
14071```
14172
14273---
14374
144−## `|install`
75+### `|install`
14576
14677Install a desk, starting its agents and listening for updates.
14778
148−If it's a remote desk we don't already have, it will be fetched. The agents started will be those specified in the `desk.bill` manifest. If it has a docket file, its tile will be added to the homescreen and its glob fetched. If we already have the desk, the source for updates will be switched to the ship specified.
79+If it's a remote desk we don't already have, it will be fetched. The agents
80+started will be those specified in the `desk.bill` manifest. If it has a docket
81+file, its tile will be added to the homescreen and its glob fetched. If we
82+already have the desk, the source for updates will be switched to the ship
83+specified.
14984
150−It takes a `ship` and `desk` as its mandatory arguments. The desk may be installed with a different name specified in the optional `local` argument.
85+It takes a `ship` and `desk` as its mandatory arguments. The desk may be
86+installed with a different name specified in the optional `local` argument.
15187
15288#### Arguments
15389
@@ -171,53 +107,61 @@ ship desk, =local desk
171107
172108---
173109
174−## `|uninstall`
110+### `|nuke`
175111
176−Uninstall a desk, suspending its agents and ignoring updates.
177−
178−The specified desk will be retained in Clay, but its agents will all be stopped and have their states archived like [`|suspend`](#suspend). This is the reverse of [`|install`](#install).
112+Shut down an agent and permanently delete its state.
179113
180−Note that this will not remove the tile or glob from the homescreen, so if the desk has a tile it should be uninstalled with the "Remove App" button in the tile's hamburger menu.
114+The default behaviour is to shut down the specified Gall agent and discard its
115+state, similar to the now-deprecated `|fade` generator. **Note this irreversibly
116+wipes the app's state**. Additionally, if the optional `desk` argument is `%.y`,
117+it takes a desk rather than an agent name and nukes every agent on the specified
118+desk.
181119
182120#### Arguments
183121
184122```
185−desk
123+@tas, =desk ?
186124```
187125
188126#### Examples
189127
128+Nuke a single agent:
129+
190130```
191−|uninstall %bitcoin
131+|nuke %btc-wallet
192132```
193133
194−---
134+Nuke every agent on a desk:
195135
196−## `|pause`
136+```
137+|nuke %bitcoin, =desk &
138+```
197139
198−Pause updates on a desk.
140+---
199141
200−The specified desk will stop tracking updates from its upstream source.
142+### `|ota`
143+
144+Set the source of updates for the `%base` desk (the kernel and core apps) to the
145+specified ship. Automatic updates will be enabled, and any new updates available
146+will be fetched and installed.
201147
202148#### Arguments
203149
204150```
205−desk
151+ship
206152```
207153
208154#### Examples
209155
210−```
211−|pause %bitcoin
212−```
156+`|ota ~marzod` is equivalent to `|install ~marzod %kids, =local %base`.
213157
214158---
215159
216−## `|resume`
160+### `|pause`
217161
218−Resume updates on a desk.
162+Pause updates on a desk.
219163
220−Start tracking previously [`|pause`](#pause)d updates from a desk's upstream source.
164+The specified desk will stop tracking updates from its upstream source.
221165
222166#### Arguments
223167
@@ -228,115 +172,246 @@ desk
228172#### Examples
229173
230174```
231−|resume %bitcoin
175+|pause %bitcoin
232176```
233177
234178---
235179
236−## `|nuke`
180+### `|rein`
237181
238−Shut down an agent and permanently delete its state.
182+Adjust the state of a desk.
239183
240−The default behaviour is to shut down the specified Gall agent and discard its state, similar to the now-deprecated `|fade` generator. **Note this irreversibly wipes the app's state**. Additionally, if the optional `desk` argument is `%.y`, it takes a desk rather than an agent name and nukes every agent on the specified desk.
184+This allows you to stop and start agents on a desk, regardless of whether
185+they're on the manifest. Stopped agents have their states archived. It can also
186+suspend and revive the whole desk with the optional `liv` argument.
241187
242188#### Arguments
243189
244190```
245−@tas, =desk ?
191+desk (list [? dude:gall]), =liv ?
246192```
247193
248194#### Examples
249195
250−Nuke a single agent:
196+Start an agent:
251197
252198```
253−|nuke %btc-wallet
199+|rein %bitcoin [& %btc-provider]
254200```
255201
256−Nuke every agent on a desk:
202+Stop an agent, archiving its state:
257203
258204```
259−|nuke %bitcoin, =desk &
205+|rein %bitcoin [| %btc-wallet]
206+```
207+
208+Stop one agent, start another:
209+
210+```
211+|rein %bitcoin [| %btc-wallet] [& %btc-provider]
212+```
213+
214+Suspend a desk:
215+
216+```
217+|rein %bitcoin, =liv |
218+```
219+
220+Revive a desk:
221+
222+```
223+|rein %bitcoin
260224```
261225
262226---
263227
264−## `|bump`
228+### `|resume`
265229
266−Try to apply a kernel update.
230+Resume updates on a desk.
267231
268−If `%zuse`'s kelvin version has decreased, try to apply the update. If any desks are incompatible with the new `%zuse` version, the update will fail. The update can be forced with the optional `force` argument, in which case incompatible desks will be `|suspend`ed. The `set` of desks to omit (and therefore suspend) can also be explicitly specified with the optional `except` argument.
232+Start tracking previously [`|pause`](#pause)d updates from a desk's upstream
233+source.
269234
270235#### Arguments
271236
272−All optional:
273−
274237```
275−, =force ?, =except (set desk)
238+desk
276239```
277240
278241#### Examples
279242
280−Try to apply update, failing if blocked by any desks:
281−
282243```
283−|bump
244+|resume %bitcoin
284245```
285246
286−Force the update, suspending incompatible desks:
247+---
248+
249+### `|revive`
250+
251+Revive all agents on a desk, migrating archived states.
252+
253+All agents specified in `desk.bill` which are suspended will be restarted. If
254+updates to the agents have occurred since their states were archived, they'll be
255+migrated with the state transition functions in the agent. This generator does
256+the same thing as selecting "Resume App" from the app tile's hamburger menu.
257+
258+#### Arguments
287259
288260```
289−|bump, =force &
261+desk
290262```
291263
292−Apply kernel update, omitting and suspending the specified desks:
264+#### Examples
293265
294266```
295−|bump, =except (silt ~[%bitcoin %webterm])
267+|revive %bitcoin
296268```
297269
298270---
299271
300−## `|rein`
272+### `|suspend`
301273
302−Adjust the state of a desk.
274+Shut down all agents on a desk, archiving their states.
303275
304−This allows you to stop and start agents on a desk, regardless of whether they're on the manifest. Stopped agents have their states archived. It can also suspend and revive the whole desk with the optional `liv` argument.
276+The tile in the homescreen (if it has one) will turn gray and say "Suspended" in
277+the top-left corner. This generator does the same thing as selecting "Suspend"
278+from an app tile's hamburger menu.
305279
306280#### Arguments
307281
308282```
309−desk (list [? dude:gall]), =liv ?
283+desk
310284```
311285
312286#### Examples
313287
314−Start an agent:
315−
316288```
317−|rein %bitcoin [& %btc-provider]
289+|suspend %bitcoin
318290```
319291
320−Stop an agent, archiving its state:
292+---
293+
294+### `|uninstall`
295+
296+Uninstall a desk, suspending its agents and ignoring updates.
297+
298+The specified desk will be retained in Clay, but its agents will all be stopped
299+and have their states archived like [`|suspend`](#suspend). This is the reverse
300+of [`|install`](#install).
301+
302+Note that this will not remove the tile or glob from the homescreen, so if the
303+desk has a tile it should be uninstalled with the "Remove App" button in the
304+tile's hamburger menu.
305+
306+#### Arguments
321307
322308```
323−|rein %bitcoin [| %btc-wallet]
309+desk
324310```
325311
326−Stop one agent, start another:
312+#### Examples
327313
328314```
329−|rein %bitcoin [| %btc-wallet] [& %btc-provider]
315+|uninstall %bitcoin
330316```
331317
332−Suspend a desk:
318+---
319+
320+### `+vat`
321+
322+Print out the status of a single installed desk.
323+
324+Desks in Clay which aren't installed will be omitted. See the related
325+[`+vats`](#vats) command for details of the individual status fields.
326+
327+#### Arguments
328+
329+`desk`
330+
331+#### Examples
333332
334333```
335−|rein %bitcoin, =liv |
334+> +vat %base
335+%base
336+ /sys/kelvin: [%zuse 418]
337+ base hash: ~
338+ %cz hash: 0v2.r1lbp.i9jr2.hosbi.rvg16.pqe7u.i3hnp.j7k27.9jsgv.8k7rp.oi98q
339+ app status: running
340+ force on: ~
341+ force off: ~
342+ publishing ship: ~
343+ updates: local
344+ source ship: ~
345+ source desk: ~
346+ source aeon: ~
347+ pending updates: ~
348+::
336349```
337350
338−Revive a desk:
351+---
352+
353+### `+vats`
354+
355+Print out the status of each installed desk.
356+
357+Desks in Clay which aren't installed will be omitted. Also see the related
358+[`+vat`](#vat) command, which prints the status of a single desk rather than all
359+desks.
360+
361+Fields:
362+
363+- `/sys/kelvin` - The version of `%zuse` the desk is compatible with.
364+- `base hash` - The merge base (common ancestor) between the desk and its upstream source.
365+- `%cz hash` - The hash of the desk.
366+- `app status` - May be `suspended` or `running`.
367+- `force on` - The set of agents on the desk which have been manually started
368+ despite not being on the `desk.bill` manifest.
369+- `force off` - The set of agents on the desk which have been manually stopped
370+ despite being on the `desk.bill` manifest.
371+- `publishing ship` - The original publisher if the source ship is republishing
372+ the desk.
373+- `updates` - May be `local`, `tracking` or `paused`. Local means it will
374+ receive updates via commits on the local ship. Tracking means it will receive
375+ updates from the `source ship`. Paused means it will not receive updates.
376+- `source desk` - The desk on the `source ship`.
377+- `source aeon` - The revision number of the desk on the `source ship`.
378+- `pending updates` - Updates waiting to be applied due to incompatibility.
379+
380+#### Arguments
381+
382+None.
383+
384+#### Examples
339385
340386```
341−|rein %bitcoin
387+> +vats
388+%base
389+ /sys/kelvin: [%zuse 418]
390+ base hash: ~
391+ %cz hash: 0v6.2nqmu.oqm24.ighl6.n0gp9.s8res.feql1.dl8ap.isli3.jk0hu.acrd2
392+ app status: running
393+ force on: ~
394+ force off: ~
395+ publishing ship: ~
396+ updates: tracking
397+ source ship: ~zod
398+ source desk: %base
399+ source aeon: 3
400+ pending updates: ~
401+::
402+%garden
403+ /sys/kelvin: [%zuse 418]
404+ base hash: ~
405+ %cz hash: 0v1e.2h7hs.elq3g.1sdt7.qfga6.ganga.7p95j.aog44.8p5fe.kpr6v.7ai82
406+ app status: running
407+ force on: ~
408+ force off: ~
409+ publishing ship: ~
410+ updates: tracking
411+ source ship: ~zod
412+ source desk: %garden
413+ source aeon: 3
414+ pending updates: ~
342415```
416+
417+---