The two Update-branch merges resolved the locale conflicts by keeping
this branch's side, which dropped nine strings main had added (Utilities
panel, drawing colours, cockpit exit). Rebuild each catalog as main's copy
plus Sea Marks and Ski Pistes, and re-pin the voice tool schema length and
digests on top of main's Utilities target.
- A motion waiting on a voice fly-to follows a later fly-to in the
same reply that cancels it, within one deadline, instead of
reporting that its flight did not arrive. A stale reply stops
following.
- The wait is 15 s, down from 30 s: it holds the tool output, and on
Gemini the later tools in the turn.
- Beyond 1,000 km of range a tilt happens in place instead of
swinging thousands of km about the crosshair point.
- The tilt-nudge limits read the pivot pitch the motion starts from,
including for a voice tilt from a tracked view, whose follow camera
is released before it moves.
- move_camera's argument checks run before the flight wait, so a
malformed call is refused at once.
- Tests: t.after cleanup in the fly-then-motion loop, the pitchDeg
pin asserts the field before removing it, and the handoff-order
pin follows the extracted argument checks.
- A zoom during a pivoting tilt now scales the range the tilt holds,
as it already did for orbit, instead of being undone on the next
frame while reporting success. The zoom limits no longer move a view
the wrong way: a zoom in leaves a view closer than 80 m in place, and
a zoom out leaves an orbit beyond 5,000 km where it is.
- A grab, touch or wheel on the map while a voice fly-to is in flight
drops the motion queued behind it. Cesium lands the flight anyway,
so the orbit or tilt would otherwise take the camera back. Chained
fly-tos in one reply keep the earliest snapshot.
- A pivot tilt toward the horizon stops lowering the camera at 150 m
above the pivot and tilts the rest in place, so a close view no
longer ends inside tiles or a hillside.
- pitchDeg is an absolute angle. A direction that contradicts it is
refused, judged from the pitch the swing starts at, and the tool
description says so.
"Fly to Paris and orbit it" reaches the app as two sibling tool calls,
which OpenAI runs at once. With a place that needs a lookup, the orbit
started over the old view and the late flight then replaced it; with a
known place, pan and rotate cancelled the flight already in the air.
Orbit, pan and rotate now wait for a pending voice flight the same way
tilt does: up to 30 s, and not run (saying so) if the flight is
cancelled, finds nothing or times out. Stop and rotate_globe do not
wait. Orbit keeps its own arming for flights the voice runner does not
track.
"Fly to London and tilt the camera" reaches the app as two sibling tool
calls, and OpenAI runs them concurrently. The tilt's navigation step
cancelled the flight already in the air, so the camera tilted where it
was; when the place still needed a lookup, the late flight replaced the
tilt and London came out top-down.
The voice runner now tracks its latest flight. A tilt sent while that
flight is still looking up or flying waits for it to land (up to 30 s),
then tilts at the destination. If the flight is cancelled, finds nothing
or times out, the tilt is not run and says so.
A voice fly-to frames a city top-down, at pitch -90. The tilt clamp
rejected any step that left the pitch below -89, so the first frame of
"tilt up" stopped the motion and "tilt down" was refused: from the view
voice lands on, no tilt ever moved the camera. A bare "tilt the camera"
also failed because tilt required a direction.
- Clamp tilt only in the direction of travel, so -90 can tilt up.
- Swing the camera about the ground under the crosshair, so the place
stays centred and the heading is kept. A tracked view still tilts in
place, and a pivot tilt yields when tracking takes the camera.
- Add an optional move_camera pitchDeg for "tilt 45 degrees"; a tilt
with neither angle nor direction settles at -45 (oblique view).
- Re-derive the voice tool schema pins for the new argument and wording,
and keep the Realtime prompt under its 52,000-character budget.
One provenanceLine() builds STATE | text | LAYERS for the HUD and
get_hud_caption. hasWord is one lookaround regex, capAtWord one grapheme
pass. Feed-state helpers are imported from layerSnapshot.js directly, and the
kept-whole sanitizer cases are one table.
A dial click shorter than the device start-up let suspend() run on a still-suspended context, so the later resume() left it running with no nodes. Cover paused, connecting and voice-fallback releases in radioNextState tests.
A building word ending the ask ('… Chapel', '… Library', '… Hall') now
passes the last-word rule only when the result is one a building ask
would accept, so a campus, zoo or district whose name merely starts the
ask (Duke University, Old Town) no longer answers it.
- A building word ("Burj Khalifa Tower", "Sagrada Familia Church") passes
the last-word rule on a building-like result; enclosures stay out.
- The anchor chooses only among the best-named outlines, so a worse name
never wins by containment alone.
- An ask without a quadrant takes only the quadrant of the matching street
nearest the point; a leading quadrant ("SE Main St") may go unsaid too.
- On an unbuffered tile edge a fragment shows as an edge along the
boundary, so a whole building touching it at a corner is not cut.
- Drop two orphaned comments and correct the place-name key wording.
Opening Utilities while Data Layers is open no longer forgets that Contact
was folded for the first, and closing one of them leaves Contact folded
while the other is still open. Enter and Esc in a drawn shape's name keep
focus in the field instead of dropping it to the page. The draw tool's
destroy test now checks it stops following the board, and the Draw gate's
amber-count comment sits on its function again.
- One place-name key for server and tiles, so "St. Paul" and "Saint Paul"
agree in Nominatim name checks.
- Tile street names: a lone letter is a direction only beside another name
word ("E Street" is not "East Street"), and a trailing quadrant ("E St NW")
may go unsaid in the ask.
- A building cut at the tile edge that is nearer the point than any whole
one leaves the point instead of a farther neighbour standing in; an edge
without a tile buffer counts as a cut, so a cut area never answers grounds.
- A batch building install re-judges only results that installed; a late
timeout during caption conversion keeps the pending point drawn; a failed
plain recaption keeps the old mark addressable.
- An interrupted Nominatim dispatch is reclaimed by the next lock owner ten
minutes after the start its marker names; node:sqlite loads on first use
without its experimental warning.
- PHOTON_URL accepts only https, which the page's connect-src allows.
- Shared OpenFreeMap tiles decode each layer when a consumer first selects
it; outline selection reuses the shared ring area and simplification, and
ground probes the shared ring centroid; the grounds word list lives once.