From 6ff7afcc8b28b8c5cda240c58701f371754a5c3e Mon Sep 17 00:00:00 2001 From: German Khokhlov Date: Mon, 12 Oct 2026 18:32:28 +0400 Subject: [PATCH] fix(i18n): translate the Street Level and Draw panels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both panels landed after the original string extraction, so they rendered English in every locale. Mark their markup and runtime text (status, SINCE stops, provider tooltips, coverage meta, viewer captions, draw hints and colours), the layer-list names kept in PANEL_LABELS, and add 90 es and ru entries. Street Level is «Уличные снимки» / «A pie de calle». Co-Authored-By: Claude Opus 5.5 --- scripts/package-boundaries.json | 6 +- src/annotations/drawMode.js | 24 ++-- src/annotations/drawTool.js | 7 +- src/i18n/locales/es.json | 110 ++++++++++++++++- src/i18n/locales/ru.json | 114 +++++++++++++++++- .../providers/mapillary/coverage.js | 6 +- src/layers/streetLevel/uiState.js | 9 +- src/streetLevelMarkup.test.mjs | 5 +- src/ui/layerPanel.js | 16 +-- src/ui/streetLevelControls.js | 17 ++- src/ui/streetLevelPresentation.js | 96 ++++++++++----- src/ui/templates/display-controls.html | 30 ++--- src/ui/templates/layer-panels.html | 36 +++--- 13 files changed, 378 insertions(+), 98 deletions(-) diff --git a/scripts/package-boundaries.json b/scripts/package-boundaries.json index c3970214a..12ac3e34c 100644 --- a/scripts/package-boundaries.json +++ b/scripts/package-boundaries.json @@ -1316,7 +1316,11 @@ "src/layers/streetLevel/selection.js", "src/layers/streetLevel/providers/mapillary/viewer.js", "src/layers/streetLevel/providers/mapillary/source.js", - "scripts/qa-street-level.mjs" + "scripts/qa-street-level.mjs", + "src/i18n/index.js", + "src/i18n/locale.js", + "src/i18n/locales/es.json", + "src/i18n/locales/ru.json" ], "external": ["cesium", "pbf", "@mapbox/vector-tile", "mapillary-js"] }, diff --git a/src/annotations/drawMode.js b/src/annotations/drawMode.js index f28a7ae6f..34f08e8f1 100644 --- a/src/annotations/drawMode.js +++ b/src/annotations/drawMode.js @@ -1,3 +1,5 @@ +import { t, tn } from '../i18n/index.js'; + /** * Manual whiteboard drawing: the pure half. * @@ -284,20 +286,26 @@ export function closeRing(pairs) { /** One line of guidance for the person drawing, by state. */ export function drawHint(session) { - if (!session) return 'Pick a shape, then click the map.'; + if (!session) return t('Pick a shape, then click the map.'); const n = session.vertices.length; if (session.shape === 'pin') return n - ? 'Enter to place the pin, Esc to cancel.' - : 'Click where the pin goes.'; + ? t('Enter to place the pin, Esc to cancel.') + : t('Click where the pin goes.'); const need = MIN_VERTICES[session.shape] - n; - if (need > 0) return `Click ${need} more point${need === 1 ? '' : 's'}.`; + if (need > 0) + return tn(need, 'Click {count} more point.', 'Click {count} more points.'); if (finishReason(session) === 'degenerate') { return session.shape === 'area' - ? 'Those points are in a line — move one off it to enclose an area.' - : 'That line has no length — click somewhere further away.'; + ? t('Those points are in a line — move one off it to enclose an area.') + : t('That line has no length — click somewhere further away.'); } const full = - n >= MAX_VERTICES ? ` · ${MAX_VERTICES}-point limit reached` : ''; - return `${formatMeasure(session)} · double-click or Enter to finish, Backspace undoes, Esc cancels.${full}`; + n >= MAX_VERTICES + ? t(' · {max}-point limit reached', { max: MAX_VERTICES }) + : ''; + return t( + '{measure} · double-click or Enter to finish, Backspace undoes, Esc cancels.{full}', + { measure: formatMeasure(session), full }, + ); } diff --git a/src/annotations/drawTool.js b/src/annotations/drawTool.js index 7f164b54f..5ffe1e6df 100644 --- a/src/annotations/drawTool.js +++ b/src/annotations/drawTool.js @@ -48,6 +48,7 @@ import { removeLastVertex, } from './drawMode.js'; +import { t } from '../i18n/index.js'; /** The id this tool claims the pointer under. */ export const DRAW_POINTER_OWNER = 'draw'; const PREVIEW_DATA_SOURCE_NAME = 'gev-draw-preview'; @@ -200,7 +201,7 @@ export function initDrawTool({ viewer, annotations }) { `That shape already has ${MAX_VERTICES} points — finish it or press Backspace.`, ); else if (reason === 'invalid') - setHint('That point is off the globe — click on the world.'); + setHint(t('That point is off the globe — click on the world.')); }; const onMove = (event) => { if (!session || session.shape === 'pin' || destroyed) return; @@ -236,7 +237,7 @@ export function initDrawTool({ viewer, annotations }) { flyTo: false, }); if (destroyed || attempt !== generation) return result; - if (result?.drawn === 0) setHint('That shape could not be placed.'); + if (result?.drawn === 0) setHint(t('That shape could not be placed.')); return result; } catch (error) { if (destroyed || attempt !== generation) return null; @@ -258,7 +259,7 @@ export function initDrawTool({ viewer, annotations }) { if (session) session = createDrawSession(shape); annotations.clear(); syncPreview(); - if (!destroyed && !active) setHint('Board cleared.'); + if (!destroyed && !active) setHint(t('Board cleared.')); }; // ---- keys: only while drawing, never while typing in another field ---- diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index 3ee5163c1..68adfd532 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -847,7 +847,7 @@ "Next session: {pendingId} — this session stays on {modelId}": "Sesión siguiente: {pendingId} — esta sesión sigue en {modelId}", "Voice model: {pendingId} — click to switch to {target}; applies next session": "Modelo de voz: {pendingId} — haz clic para cambiar a {target}; se aplica en la próxima sesión", "Estimated session cost on {modelId} — {responses} response(s). Warns at {warn}, ends the session at {cap}.": "Costo de sesión estimado en {modelId} — {responses} respuesta(s). Avisa a {warn} y cierra la sesión a {cap}.", - "Street-level imagery and coverage in the Street Level layer. Free: register an app in the Mapillary developer dashboard and paste its Client Token": "Imágenes y cobertura a nivel de calle en la capa Street Level. Gratis: registra una app en el panel de desarrolladores de Mapillary y pega su Client Token", + "Street-level imagery and coverage in the Street Level layer. Free: register an app in the Mapillary developer dashboard and paste its Client Token": "Imágenes y cobertura a nivel de calle en la capa A pie de calle. Gratis: registra una app en el panel de desarrolladores de Mapillary y pega su Client Token", "Voice control — API key or ChatGPT OAuth": "Control de voz — clave de API u OAuth de ChatGPT", "WITHIN {km} KM": "A MENOS DE {km} KM", "Syncing flow · Roads: {source}": "Sincronizando flujo · Vías: {source}", @@ -873,5 +873,111 @@ "Scanlines": "Líneas de barrido", "Sensitivity": "Sensibilidad", "WHOT/BHOT": "WHOT/BHOT", - "Ironbow": "Ironbow" + "Ironbow": "Ironbow", + "Pick a shape, then click the map.": "Elige una forma y haz clic en el mapa.", + "Enter to place the pin, Esc to cancel.": "Enter para colocar el pin, Esc para cancelar.", + "Click where the pin goes.": "Haz clic donde va el pin.", + "Click {count} more points.": { + "one": "Haz clic en {count} punto más.", + "many": "Haz clic en {count} de puntos más.", + "other": "Haz clic en {count} puntos más." + }, + "Those points are in a line — move one off it to enclose an area.": "Esos puntos están en línea: mueve uno fuera de ella para cerrar un área.", + "That line has no length — click somewhere further away.": "Esa línea no tiene longitud: haz clic más lejos.", + " · {max}-point limit reached": " · límite de {max} puntos alcanzado", + "{measure} · double-click or Enter to finish, Backspace undoes, Esc cancels.{full}": "{measure} · doble clic o Enter para terminar, Backspace deshace, Esc cancela.{full}", + "That point is off the globe — click on the world.": "Ese punto está fuera del globo: haz clic sobre el mundo.", + "That shape could not be placed.": "No se pudo colocar esa forma.", + "Board cleared.": "Tablero borrado.", + "Draw on the world — click vertices, double-click or Enter to finish, Esc to cancel": "Dibuja sobre el mundo: haz clic en los vértices, doble clic o Enter para terminar, Esc para cancelar", + "Draw": "Dibujo", + "Shape": "Forma", + "Shape to draw": "Forma a dibujar", + "Area": "Área", + "Line": "Línea", + "Pin": "Pin", + "Label (optional)": "Etiqueta (opcional)", + "Label for the drawn shape": "Etiqueta de la forma dibujada", + "Colour of the drawn shape": "Color de la forma dibujada", + "Primary": "Principal", + "Amber": "Ámbar", + "Cyan": "Cian", + "Green": "Verde", + "Red": "Rojo", + "Clear": "Borrar", + "Remove every mark from the board": "Quitar todas las marcas del tablero", + "Point the camera at the globe for street-level coverage": "Apunta la cámara al globo para ver la cobertura a pie de calle", + "No street-level imagery providers configured": "No hay proveedores de imágenes a pie de calle configurados", + "Selected": "Seleccionada", + "Live Vessels": "Buques en vivo", + "Bike Share": "Bicis compartidas", + "Cameras": "Cámaras", + "Street Level": "A pie de calle", + "Mapped ALPR Cameras": "Cámaras ALPR cartografiadas", + "Data Centers": "Centros de datos", + "Active Fires": "Incendios activos", + "Street Level could not start": "No se pudo iniciar A pie de calle", + "Street Level toggle failed": "No se pudo cambiar A pie de calle", + "Street-level image": "Imagen a pie de calle", + "SHRINK": "REDUCIR", + "EXPAND": "AMPLIAR", + "Shrink": "Reducir", + "Expand": "Ampliar", + "ANY DATE": "CUALQUIER FECHA", + "LAST 10 YEARS": "ÚLTIMOS 10 AÑOS", + "LAST 5 YEARS": "ÚLTIMOS 5 AÑOS", + "LAST 3 YEARS": "ÚLTIMOS 3 AÑOS", + "LAST 2 YEARS": "ÚLTIMOS 2 AÑOS", + "LAST YEAR": "ÚLTIMO AÑO", + "LAST 6 MONTHS": "ÚLTIMOS 6 MESES", + "LAST 3 MONTHS": "ÚLTIMOS 3 MESES", + "LAST MONTH": "ÚLTIMO MES", + "LAST {count} DAYS": { + "one": "ÚLTIMO {count} DÍA", + "many": "ÚLTIMOS {count} DE DÍAS", + "other": "ÚLTIMOS {count} DÍAS" + }, + "{window} · SINCE {date}": "{window} · DESDE {date}", + "Turn Street Level off": "Desactivar A pie de calle", + "Turn Street Level on": "Activar A pie de calle", + "KEY REJECTED": "CLAVE RECHAZADA", + "{name} imagery on": "Imágenes de {name} activadas", + "{name} imagery off": "Imágenes de {name} desactivadas", + "Image by {creator}": "Imagen de {creator}", + "Camera follows view: move the globe camera wherever the street-level view looks": "La cámara sigue la vista: mueve la cámara del globo hacia donde mira la vista a pie de calle", + "Camera follow needs the Google 3D map: choose Google 3D under MAP SOURCE": "Seguir con la cámara requiere el mapa Google 3D: elige Google 3D en FUENTE DEL MAPA", + "Switch a provider on to draw its coverage.": "Activa un proveedor para dibujar su cobertura.", + "Loading this sequence…": "Cargando esta secuencia…", + "{n} images in this sequence · Esc clears": { + "one": "{n} imagen en esta secuencia · Esc la quita", + "many": "{n} de imágenes en esta secuencia · Esc la quita", + "other": "{n} imágenes en esta secuencia · Esc la quita" + }, + "{n} sequences in view · click a line for its photos": { + "one": "{n} secuencia a la vista · haz clic en una línea para ver sus fotos", + "many": "{n} de secuencias a la vista · haz clic en una línea para ver sus fotos", + "other": "{n} secuencias a la vista · haz clic en una línea para ver sus fotos" + }, + "STREET LEVEL": "A PIE DE CALLE", + "Expand the street-level view (Esc shrinks it)": "Ampliar la vista a pie de calle (Esc la reduce)", + "Image fit": "Ajuste de la imagen", + "FIT": "AJUSTAR", + "Fit: show the whole photo, with dark bars where its shape differs from the frame": "Ajustar: muestra la foto entera, con barras oscuras donde su forma no coincide con el marco", + "FILL": "RELLENAR", + "Fill: fill the frame edge to edge, cropping the photo": "Rellenar: llena el marco de borde a borde, recortando la foto", + "Camera follows view": "La cámara sigue la vista", + "FOLLOW": "SEGUIR", + "Close the image and deselect it on the map": "Cerrar la imagen y quitar la selección en el mapa", + "Close the street-level image": "Cerrar la imagen a pie de calle", + "Street-level viewer": "Visor a pie de calle", + "Open this image on the provider's site": "Abrir esta imagen en el sitio del proveedor", + "Imagery providers": "Proveedores de imágenes", + "PROVIDERS": "PROVEEDORES", + "Imagery filters": "Filtros de imágenes", + "IMAGERY": "IMÁGENES", + "Panorama filter": "Filtro de panoramas", + "ALL": "TODAS", + "FLAT": "PLANAS", + "SINCE": "DESDE", + "Coverage colours": "Colores de cobertura" } diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index 46d99e42a..40fa121c2 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -73,7 +73,7 @@ "Remove this key from your saved configuration?": "Удалить этот ключ из сохранённой конфигурации?", "Removed from {store}. Restarting — this page reloads itself.": "Удалено: {store}. Перезапуск — страница перезагрузится сама.", "More flight-polling credits (anonymous works without)": "Больше кредитов на опрос рейсов (анонимно работает и без ключа)", - "Street-level imagery and coverage in the Street Level layer. Free: register an app in the Mapillary developer dashboard and paste its Client Token": "Уличные снимки и покрытие в слое «Street Level». Бесплатно: зарегистрируйте приложение в панели разработчика Mapillary и вставьте его Client Token", + "Street-level imagery and coverage in the Street Level layer. Free: register an app in the Mapillary developer dashboard and paste its Client Token": "Уличные снимки и покрытие в слое «Уличные снимки». Бесплатно: зарегистрируйте приложение в панели разработчика Mapillary и вставьте его Client Token", "Higher space-missions request allowance": "Повышенный лимит запросов для космических миссий", "The photorealistic 3D planet + place search": "Фотореалистичная 3D-планета + поиск мест", "Places context + Street View fallback; optional separate key": "Контекст Places + резервный Street View; отдельный ключ — по желанию", @@ -880,5 +880,115 @@ "Scanlines": "Строки развёртки", "Sensitivity": "Чувствительность", "WHOT/BHOT": "WHOT/BHOT", - "Ironbow": "Ironbow" + "Ironbow": "Ironbow", + "Pick a shape, then click the map.": "Выберите фигуру и щёлкните по карте.", + "Enter to place the pin, Esc to cancel.": "Enter — поставить метку, Esc — отменить.", + "Click where the pin goes.": "Щёлкните, где поставить метку.", + "Click {count} more points.": { + "one": "Щёлкните ещё {count} точку.", + "few": "Щёлкните ещё {count} точки.", + "many": "Щёлкните ещё {count} точек.", + "other": "Щёлкните ещё {count} точки." + }, + "Those points are in a line — move one off it to enclose an area.": "Точки лежат на одной линии — сдвиньте одну, чтобы получилась площадь.", + "That line has no length — click somewhere further away.": "У линии нет длины — щёлкните дальше.", + " · {max}-point limit reached": " · достигнут предел в {max} точек", + "{measure} · double-click or Enter to finish, Backspace undoes, Esc cancels.{full}": "{measure} · двойной щелчок или Enter — завершить, Backspace — отменить точку, Esc — отменить.{full}", + "That point is off the globe — click on the world.": "Эта точка вне глобуса — щёлкните по Земле.", + "That shape could not be placed.": "Не удалось разместить фигуру.", + "Board cleared.": "Доска очищена.", + "Draw on the world — click vertices, double-click or Enter to finish, Esc to cancel": "Рисовать на карте мира — щёлкайте вершины, двойной щелчок или Enter — завершить, Esc — отменить", + "Draw": "Рисование", + "Shape": "Фигура", + "Shape to draw": "Фигура для рисования", + "Area": "Область", + "Line": "Линия", + "Pin": "Метка", + "Label (optional)": "Подпись (необязательно)", + "Label for the drawn shape": "Подпись нарисованной фигуры", + "Colour of the drawn shape": "Цвет нарисованной фигуры", + "Primary": "Основной", + "Amber": "Янтарный", + "Cyan": "Голубой", + "Green": "Зелёный", + "Red": "Красный", + "Clear": "Очистить", + "Remove every mark from the board": "Убрать все пометки с доски", + "Point the camera at the globe for street-level coverage": "Наведите камеру на глобус, чтобы увидеть покрытие уличных снимков", + "No street-level imagery providers configured": "Источники уличных снимков не настроены", + "Selected": "Выбранная", + "Live Vessels": "Суда в реальном времени", + "Bike Share": "Прокат велосипедов", + "Cameras": "Камеры", + "Street Level": "Уличные снимки", + "Mapped ALPR Cameras": "Камеры ALPR на карте", + "Data Centers": "Дата-центры", + "Active Fires": "Активные пожары", + "Street Level could not start": "Не удалось запустить «Уличные снимки»", + "Street Level toggle failed": "Не удалось переключить «Уличные снимки»", + "Street-level image": "Уличный снимок", + "SHRINK": "СВЕРНУТЬ", + "EXPAND": "РАЗВЕРНУТЬ", + "Shrink": "Свернуть", + "Expand": "Развернуть", + "ANY DATE": "ЛЮБАЯ ДАТА", + "LAST 10 YEARS": "ЗА 10 ЛЕТ", + "LAST 5 YEARS": "ЗА 5 ЛЕТ", + "LAST 3 YEARS": "ЗА 3 ГОДА", + "LAST 2 YEARS": "ЗА 2 ГОДА", + "LAST YEAR": "ЗА ГОД", + "LAST 6 MONTHS": "ЗА 6 МЕСЯЦЕВ", + "LAST 3 MONTHS": "ЗА 3 МЕСЯЦА", + "LAST MONTH": "ЗА МЕСЯЦ", + "LAST {count} DAYS": { + "one": "ЗА {count} ДЕНЬ", + "few": "ЗА {count} ДНЯ", + "many": "ЗА {count} ДНЕЙ", + "other": "ЗА {count} ДНЯ" + }, + "{window} · SINCE {date}": "{window} · С {date}", + "Turn Street Level off": "Выключить «Уличные снимки»", + "Turn Street Level on": "Включить «Уличные снимки»", + "KEY REJECTED": "КЛЮЧ ОТКЛОНЁН", + "{name} imagery on": "Снимки {name} включены", + "{name} imagery off": "Снимки {name} выключены", + "Image by {creator}": "Автор снимка: {creator}", + "Camera follows view: move the globe camera wherever the street-level view looks": "Камера следует за видом: камера глобуса поворачивается туда, куда смотрит уличный снимок", + "Camera follow needs the Google 3D map: choose Google 3D under MAP SOURCE": "Слежению камеры нужна карта Google 3D: выберите Google 3D в разделе «ИСТОЧНИК КАРТЫ»", + "Switch a provider on to draw its coverage.": "Включите источник, чтобы показать его покрытие.", + "Loading this sequence…": "Загрузка последовательности…", + "{n} images in this sequence · Esc clears": { + "one": "{n} снимок в последовательности · Esc — сбросить", + "few": "{n} снимка в последовательности · Esc — сбросить", + "many": "{n} снимков в последовательности · Esc — сбросить", + "other": "{n} снимка в последовательности · Esc — сбросить" + }, + "{n} sequences in view · click a line for its photos": { + "one": "{n} последовательность в кадре · щёлкните линию, чтобы открыть снимки", + "few": "{n} последовательности в кадре · щёлкните линию, чтобы открыть снимки", + "many": "{n} последовательностей в кадре · щёлкните линию, чтобы открыть снимки", + "other": "{n} последовательности в кадре · щёлкните линию, чтобы открыть снимки" + }, + "STREET LEVEL": "УЛИЧНЫЕ СНИМКИ", + "Expand the street-level view (Esc shrinks it)": "Развернуть уличный снимок (Esc сворачивает)", + "Image fit": "Масштаб снимка", + "FIT": "ВПИСАТЬ", + "Fit: show the whole photo, with dark bars where its shape differs from the frame": "Вписать: показать снимок целиком, с тёмными полосами там, где его форма не совпадает с рамкой", + "FILL": "ЗАПОЛНИТЬ", + "Fill: fill the frame edge to edge, cropping the photo": "Заполнить: растянуть на всю рамку, обрезав снимок", + "Camera follows view": "Камера следует за видом", + "FOLLOW": "СЛЕДИТЬ", + "Close the image and deselect it on the map": "Закрыть снимок и снять выделение на карте", + "Close the street-level image": "Закрыть уличный снимок", + "Street-level viewer": "Просмотр уличных снимков", + "Open this image on the provider's site": "Открыть снимок на сайте источника", + "Imagery providers": "Источники снимков", + "PROVIDERS": "ИСТОЧНИКИ", + "Imagery filters": "Фильтры снимков", + "IMAGERY": "СНИМКИ", + "Panorama filter": "Фильтр панорам", + "ALL": "ВСЕ", + "FLAT": "ПЛОСКИЕ", + "SINCE": "С ДАТЫ", + "Coverage colours": "Цвета покрытия" } diff --git a/src/layers/streetLevel/providers/mapillary/coverage.js b/src/layers/streetLevel/providers/mapillary/coverage.js index 5b9b5246c..7057f5229 100644 --- a/src/layers/streetLevel/providers/mapillary/coverage.js +++ b/src/layers/streetLevel/providers/mapillary/coverage.js @@ -33,6 +33,7 @@ import { SEQUENCE_VIEW_RANGE_PER_HEIGHT, } from './policy.js'; +import { msg } from '../../../../i18n/index.js'; /** Draped lines stay at most this long while a tile's cast lines build. */ export const SWAP_MAX_WAIT_MS = 4000; /** Tiles touched by new mesh samples are redrawn at most this often. */ @@ -694,8 +695,9 @@ export function createCoverage({ state, source }) { if (kind === 'overview' && (!bbox || zoom <= 1)) bbox = [-180, -85, 180, 85]; if (zoom == null || !bbox) { - state.coverage.hint = - 'Point the camera at the globe for street-level coverage'; + state.coverage.hint = msg( + 'Point the camera at the globe for street-level coverage', + ); clear(); notify(); return; diff --git a/src/layers/streetLevel/uiState.js b/src/layers/streetLevel/uiState.js index a2420314f..09c81d03f 100644 --- a/src/layers/streetLevel/uiState.js +++ b/src/layers/streetLevel/uiState.js @@ -1,5 +1,6 @@ import { COLORS } from './policy.js'; +import { msg, t } from '../../i18n/index.js'; /** * @typedef {object} ProviderSnapshot * @property {string} id @@ -29,7 +30,7 @@ export function summarizeCoverage(providers) { loading: active.some((p) => p.loading), hint: providers.length === 0 - ? 'No street-level imagery providers configured' + ? msg('No street-level imagery providers configured') : active.find((p) => p.hint)?.hint || '', error: active.find((p) => p.error)?.error || null, keyRequired: @@ -63,7 +64,11 @@ export function composeUIState({ color: provider.color, })); if (active.length) - legend.push({ key: 'selected', label: 'Selected', color: COLORS.selected }); + legend.push({ + key: 'selected', + label: t('Selected'), + color: COLORS.selected, + }); return { enabled, keyRequired, diff --git a/src/streetLevelMarkup.test.mjs b/src/streetLevelMarkup.test.mjs index de1878a79..4bf34f676 100644 --- a/src/streetLevelMarkup.test.mjs +++ b/src/streetLevelMarkup.test.mjs @@ -25,7 +25,10 @@ test('Street Level is an ordinary collapsible GEV panel that starts collapsed', html, /
- Shape -
- - - + Shape +
+ + +
- - + - +
diff --git a/src/ui/templates/layer-panels.html b/src/ui/templates/layer-panels.html index a48bb28a0..51d039b39 100644 --- a/src/ui/templates/layer-panels.html +++ b/src/ui/templates/layer-panels.html @@ -76,7 +76,7 @@
- STREET LEVEL + STREET LEVEL @@ -86,53 +86,53 @@