Compare commits

..
3 Commits
Author SHA1 Message Date
HarelM 2b7a092ad3 Remove comment 2026-08-21 13:58:48 +03:00
HarelM 705233241f Fix double sidebars 2026-08-21 13:47:44 +03:00
HarelM 3c1c3b6a74 Adopted changes to have a sidebar that's dragable 2026-08-21 13:02:35 +03:00
43 changed files with 1172 additions and 1788 deletions
-4
View File
@@ -31,10 +31,6 @@ updates:
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "daily"
groups:
codeql-action:
patterns:
- "github/codeql-action*"
cooldown: cooldown:
default-days: 3 default-days: 3
# no semver support for github-actions # no semver support for github-actions
+7 -11
View File
@@ -6,10 +6,6 @@ on:
push: push:
branches: [ main ] branches: [ main ]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs: jobs:
build-node: build-node:
@@ -53,7 +49,7 @@ jobs:
- run: npm ci - run: npm ci
- run: npm run build - run: npm run build
- name: artifacts/maputnik - name: artifacts/maputnik
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: maputnik name: maputnik
path: dist path: dist
@@ -70,19 +66,19 @@ jobs:
run: npm run build-desktop run: npm run build-desktop
- name: Artifacts/linux - name: Artifacts/linux
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: maputnik-linux name: maputnik-linux
path: ./desktop/bin/linux/ path: ./desktop/bin/linux/
- name: Artifacts/darwin - name: Artifacts/darwin
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: maputnik-darwin name: maputnik-darwin
path: ./desktop/bin/darwin/ path: ./desktop/bin/darwin/
- name: Artifacts/windows - name: Artifacts/windows
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: maputnik-windows name: maputnik-windows
path: ./desktop/bin/windows/ path: ./desktop/bin/windows/
@@ -102,7 +98,7 @@ jobs:
- run: npm ci - run: npm ci
- run: npm run test-unit-ci - run: npm run test-unit-ci
- name: Upload coverage reports to Codecov - name: Upload coverage reports to Codecov
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1 uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with: with:
files: ${{ github.workspace }}/coverage/coverage-final.json files: ${{ github.workspace }}/coverage/coverage-final.json
verbose: true verbose: true
@@ -125,13 +121,13 @@ jobs:
- name: Playwright run - name: Playwright run
run: npm run test-e2e run: npm run test-e2e
- name: Upload coverage reports to Codecov - name: Upload coverage reports to Codecov
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1 uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with: with:
files: ${{ github.workspace }}/coverage/coverage-final.json files: ${{ github.workspace }}/coverage/coverage-final.json
verbose: true verbose: true
- name: Upload Playwright report - name: Upload Playwright report
if: ${{ !cancelled() }} if: ${{ !cancelled() }}
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: playwright-report name: playwright-report
path: playwright-report/ path: playwright-report/
+3 -7
View File
@@ -20,10 +20,6 @@ on:
schedule: schedule:
- cron: '17 0 * * 6' - cron: '17 0 * * 6'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs: jobs:
analyze: analyze:
name: Analyze name: Analyze
@@ -46,7 +42,7 @@ jobs:
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1 uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@@ -57,7 +53,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1 uses: github/codeql-action/autobuild@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
# ℹ️ Command-line programs to run using the OS shell. # ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
@@ -71,4 +67,4 @@ jobs:
# make release # make release
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1 uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
+1 -1
View File
@@ -45,7 +45,7 @@ jobs:
steps: steps:
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0 uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
+1 -1
View File
@@ -73,7 +73,7 @@ jobs:
- name: Tag commit and push - name: Tag commit and push
id: tag_version id: tag_version
uses: mathieudutour/github-tag-action@af99e60ce8132224b8e6ebab5023449fe256ed46 # v7.0.0 uses: mathieudutour/github-tag-action@a22cf08638b34d5badda920f9daf6e72c477b07b # v6.2
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
custom_tag: ${{ steps.package-version.outputs.current-version }} custom_tag: ${{ steps.package-version.outputs.current-version }}
-8
View File
@@ -5,19 +5,11 @@
- Upgrade to MapLibre GL JS 6 and Vite 8, and update the remaining dependencies - Upgrade to MapLibre GL JS 6 and Vite 8, and update the remaining dependencies
- Serve the RTL text plugin from `@mapbox/mapbox-gl-rtl-text` instead of a pinned CDN URL, so its version is tracked in `package.json` - Serve the RTL text plugin from `@mapbox/mapbox-gl-rtl-text` instead of a pinned CDN URL, so its version is tracked in `package.json`
- Exported HTML now loads MapLibre GL JS as an ES module, since v6 no longer ships a UMD bundle - Exported HTML now loads MapLibre GL JS as an ES module, since v6 no longer ships a UMD bundle
- Add `font-faces`, `sky`, `roll` and `centerAltitude` to the style settings modal
- The sidebar can now be resized, both as a whole and in the split between the layer list and the layer editor - The sidebar can now be resized, both as a whole and in the split between the layer list and the layer editor
- Allow viewing and changing the map's max zoom in the debug modal
- _...Add new stuff here..._ - _...Add new stuff here..._
### 🐞 Bug fixes ### 🐞 Bug fixes
- Prevent a crash when converting a function to an expression
- Prevent a crash when deleting either stop from a function with two stops
- Preserve expanded layer groups when deleting layers, including the first layer of a group
- The map's data listener now fires on tile loads again, so source and vector layer field autocompletion is populated - The map's data listener now fires on tile loads again, so source and vector layer field autocompletion is populated
- The `maputnik` desktop binary now opens the default browser automatically on startup (opt out with `--no-browser`)
- Keyboard shortcuts now keep working while the map has focus, instead of going dead until the map is blurred
- The map no longer stays blank on load until it is moved, when the style loads before the map is ready
- _...Add new stuff here..._ - _...Add new stuff here..._
## 3.1.0 ## 3.1.0
+8 -3
View File
@@ -7,16 +7,21 @@ require (
github.com/fsnotify/fsnotify v1.6.0 github.com/fsnotify/fsnotify v1.6.0
github.com/gorilla/handlers v1.5.1 github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0 github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.5.3 github.com/gorilla/websocket v1.5.0
github.com/maputnik/desktop v1.0.7 github.com/maputnik/desktop v1.0.7
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/urfave/cli v1.22.12 github.com/urfave/cli v1.22.12
) )
require ( require (
github.com/GeertJohan/go.incremental v1.0.0 // indirect
github.com/akavel/rsrc v0.8.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/daaku/go.zipexe v1.0.2 // indirect github.com/daaku/go.zipexe v1.0.2 // indirect
github.com/felixge/httpsnoop v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect
github.com/jessevdk/go-flags v1.4.0 // indirect
github.com/nkovacs/streamquote v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
golang.org/x/sys v0.1.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.0.1 // indirect
golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect
) )
+9 -6
View File
@@ -1,7 +1,9 @@
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg=
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
github.com/GeertJohan/go.rice v1.0.3 h1:k5viR+xGtIhF61125vCE1cmJ5957RQGXG6dmbaWZSmI= github.com/GeertJohan/go.rice v1.0.3 h1:k5viR+xGtIhF61125vCE1cmJ5957RQGXG6dmbaWZSmI=
github.com/GeertJohan/go.rice v1.0.3/go.mod h1:XVdrU4pW00M4ikZed5q56tPf1v2KwnIKeIdc9CBYNt4= github.com/GeertJohan/go.rice v1.0.3/go.mod h1:XVdrU4pW00M4ikZed5q56tPf1v2KwnIKeIdc9CBYNt4=
github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw=
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@@ -18,14 +20,14 @@ github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/maputnik/desktop v1.0.7 h1:rdFg7emIJOT3YsZpwqSChmWtMOvu+T4h6WwVQAZP9n4= github.com/maputnik/desktop v1.0.7 h1:rdFg7emIJOT3YsZpwqSChmWtMOvu+T4h6WwVQAZP9n4=
github.com/maputnik/desktop v1.0.7/go.mod h1:wmDjHUztx9jOBz0I22589yWguAGdV/sEM57YANpN8oQ= github.com/maputnik/desktop v1.0.7/go.mod h1:wmDjHUztx9jOBz0I22589yWguAGdV/sEM57YANpN8oQ=
github.com/nkovacs/streamquote v1.0.0 h1:PmVIV08Zlx2lZK5fFZlMZ04eHcDTIFJCv/5/0twVUow=
github.com/nkovacs/streamquote v1.0.0/go.mod h1:BN+NaZ2CmdKqUuTUXUEm9j95B2TRbpOWpxbJYzzgUsc= github.com/nkovacs/streamquote v1.0.0/go.mod h1:BN+NaZ2CmdKqUuTUXUEm9j95B2TRbpOWpxbJYzzgUsc=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
@@ -39,11 +41,12 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8= github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8=
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+2 -26
View File
@@ -2,7 +2,6 @@ package main
import ( import (
"fmt" "fmt"
"net"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
@@ -10,7 +9,6 @@ import (
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/maputnik/desktop/filewatch" "github.com/maputnik/desktop/filewatch"
"github.com/pkg/browser"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@@ -38,10 +36,6 @@ func main() {
Name: "static", Name: "static",
Usage: "Serve directory under /static/", Usage: "Serve directory under /static/",
}, },
&cli.BoolFlag{
Name: "no-browser",
Usage: "Do not automatically open the default browser",
},
} }
app.Action = func(c *cli.Context) error { app.Action = func(c *cli.Context) error {
@@ -77,26 +71,8 @@ func main() {
loggedRouter := handlers.LoggingHandler(os.Stdout, router) loggedRouter := handlers.LoggingHandler(os.Stdout, router)
corsRouter := handlers.CORS(handlers.AllowedHeaders([]string{"Content-Type"}), handlers.AllowedMethods([]string{"GET", "PUT"}), handlers.AllowedOrigins([]string{"*"}), handlers.AllowCredentials())(loggedRouter) corsRouter := handlers.CORS(handlers.AllowedHeaders([]string{"Content-Type"}), handlers.AllowedMethods([]string{"GET", "PUT"}), handlers.AllowedOrigins([]string{"*"}), handlers.AllowCredentials())(loggedRouter)
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", c.Int("port"))) fmt.Printf("Exposing Maputnik on http://localhost:%d\n", c.Int("port"))
if err != nil { return http.ListenAndServe(fmt.Sprintf(":%d", c.Int("port")), corsRouter)
return err
}
url := fmt.Sprintf("http://localhost:%d", c.Int("port"))
fmt.Printf("Exposing Maputnik on %s\n", url)
// Listener is already accepting connections, so this can't race http.Serve below.
// xdg-open is known to hang on some headless Linux setups, so this runs in its own
// goroutine to keep a stuck opener from stalling server startup.
if !c.Bool("no-browser") {
go func() {
if err := browser.OpenURL(url); err != nil {
fmt.Printf("Could not open browser automatically: %s\nPlease open %s manually.\n", err, url)
}
}()
}
return http.Serve(listener, corsRouter)
} }
app.Run(os.Args) app.Run(os.Args)
-16
View File
@@ -1,16 +0,0 @@
{
"version": 8,
"name": "Grouped layers",
"sources": {},
"layers": [
{ "id": "background", "type": "background" },
{ "id": "park-a", "type": "background" },
{ "id": "park-b", "type": "background" },
{ "id": "park-c", "type": "background" },
{ "id": "road", "type": "background" },
{ "id": "park-d", "type": "background" },
{ "id": "park-e", "type": "background" },
{ "id": "water-a", "type": "background" },
{ "id": "water-b", "type": "background" }
]
}
-17
View File
@@ -62,22 +62,5 @@ describe("keyboard", () => {
await when.typeKeys("!"); await when.typeKeys("!");
await then(get.elementByTestId("modal:debug")).shouldBeVisible(); await then(get.elementByTestId("modal:debug")).shouldBeVisible();
}); });
describe("while the map has focus", () => {
beforeEach(async () => {
await when.typeKeys("m");
await then(get.canvas()).shouldBeFocused();
});
test("'!' should show debug modal", async () => {
await when.typeKeys("!");
await then(get.elementByTestId("modal:debug")).shouldBeVisible();
});
test("'s' should show settings modal", async () => {
await when.typeKeys("s");
await then(get.elementByTestId("modal:settings")).shouldBeVisible();
});
});
}); });
}); });
+1 -16
View File
@@ -289,20 +289,6 @@ describe("layer editor", () => {
}); });
}); });
test("should leave a plain editable value after deleting a stop", async () => {
await when.setFunctionStopValue("circle-radius", "Output value", 1, "0");
await when.deleteFunctionStop("circle-radius");
await then(get.elementByTestId("spec-field:circle-radius")).shouldBeVisible();
await then(get.styleFromLocalStorage()).shouldDeepNestedInclude({
layers: [{ id, paint: { "circle-radius": 0 } }],
});
await when.setValue("spec-field-input:circle-radius", "7");
await then(get.styleFromLocalStorage()).shouldDeepNestedInclude({
layers: [{ id, paint: { "circle-radius": 7 } }],
});
});
test("should set the base", async () => { test("should set the base", async () => {
await when.setFunctionBase("circle-radius", "2"); await when.setFunctionBase("circle-radius", "2");
await then(get.styleFromLocalStorage()).shouldDeepNestedInclude({ await then(get.styleFromLocalStorage()).shouldDeepNestedInclude({
@@ -324,9 +310,8 @@ describe("layer editor", () => {
}); });
}); });
test("should convert to an expression without crashing", async () => { test("should convert to an expression", async () => {
await when.makeExpression("circle-radius"); await when.makeExpression("circle-radius");
await then(get.element("[data-wd-key='spec-field-container:circle-radius'] .maputnik-expression-editor")).shouldBeVisible();
await then(get.styleFromLocalStorage()).shouldDeepNestedInclude({ await then(get.styleFromLocalStorage()).shouldDeepNestedInclude({
layers: [{ id, paint: { "circle-radius": ["interpolate", ["linear"], ["zoom"], 6, 5, 10, 5] } }], layers: [{ id, paint: { "circle-radius": ["interpolate", ["linear"], ["zoom"], 6, 5, 10, 5] } }],
}); });
+1 -78
View File
@@ -1,4 +1,4 @@
import { beforeEach, describe, expect, test } from "./utils/fixtures"; import { beforeEach, describe, test } from "./utils/fixtures";
import { MaputnikDriver } from "./maputnik-driver"; import { MaputnikDriver } from "./maputnik-driver";
describe("layers list", () => { describe("layers list", () => {
@@ -47,14 +47,6 @@ describe("layers list", () => {
}); });
}); });
test("should title the visibility button with the action it performs", async () => {
const key = "layer-list-item:" + id + ":toggle-visibility";
// A visible layer is about to be hidden, and a hidden one to be shown.
await expect(get.elementByTestId(key)).toHaveAttribute("title", "hide");
await when.click(key);
await expect(get.elementByTestId(key)).toHaveAttribute("title", "show");
});
describe("when clicking hide", () => { describe("when clicking hide", () => {
beforeEach(async () => { beforeEach(async () => {
await when.click("layer-list-item:" + id + ":toggle-visibility"); await when.click("layer-list-item:" + id + ":toggle-visibility");
@@ -306,75 +298,6 @@ describe("layers list", () => {
}); });
describe("groups", () => { describe("groups", () => {
for (const control of ["menu", "trash"] as const) {
describe(`after deletion using ${control}`, () => {
beforeEach(async () => {
await when.setStyle("grouped_layers");
});
test("keeps all groups expanded when an earlier layer is deleted", async () => {
await when.click("skip-target-layer-list");
await then(get.elementByTestId("layer-list-item:park-b")).shouldBeVisible();
await when.deleteLayer("background", control);
await then(get.elementByTestId("layer-list-item:background")).shouldNotExist();
await then(get.elementByTestId("layer-list-group:park-0")).shouldExist();
await expect(get.elementByTestId("layer-list-group:water-6").getByRole("button")).toHaveAttribute("aria-expanded", "true");
await then(get.elementByTestId("layer-list-item:park-b")).shouldBeVisible();
await then(get.elementByTestId("layer-list-item:park-e")).shouldBeVisible();
await then(get.elementByTestId("layer-list-item:water-b")).shouldBeVisible();
});
test("preserves separate states for groups with the same prefix", async () => {
await when.click("layer-list-group:park-1");
await when.deleteLayer("background", control);
await then(get.elementByTestId("layer-list-group:park-0")).shouldExist();
await when.click("layer-list-item:road");
await expect(get.elementByTestId("layer-list-group:park-0").getByRole("button")).toHaveAttribute("aria-expanded", "true");
await expect(get.elementByTestId("layer-list-group:park-4").getByRole("button")).toHaveAttribute("aria-expanded", "false");
await then(get.elementByTestId("layer-list-item:park-b")).shouldBeVisible();
await then(get.elementByTestId("layer-list-item:park-e")).shouldNotBeVisible();
});
test("keeps a group expanded when its first layer is deleted", async () => {
await when.click("layer-list-group:park-1");
await when.deleteLayer("park-a", control);
await then(get.elementByTestId("layer-list-item:park-a")).shouldNotExist();
await when.click("layer-list-item:road");
await expect(get.elementByTestId("layer-list-group:park-1").getByRole("button")).toHaveAttribute("aria-expanded", "true");
await then(get.elementByTestId("layer-list-item:park-c")).shouldBeVisible();
});
for (const expandedGroup of ["park-1", "park-5"]) {
test(`keeps a merged group expanded when ${expandedGroup} was expanded`, async () => {
await when.click("layer-list-group:" + expandedGroup);
await when.deleteLayer("road", control);
await then(get.elementByTestId("layer-list-item:road")).shouldNotExist();
await expect(get.elementByTestId("layer-list-group:park-1").getByRole("button")).toHaveAttribute("aria-expanded", "true");
await then(get.elementByTestId("layer-list-item:park-b")).shouldBeVisible();
await then(get.elementByTestId("layer-list-item:park-e")).shouldBeVisible();
});
}
test("keeps a merged group collapsed when both groups were collapsed", async () => {
await when.deleteLayer("road", control);
await then(get.elementByTestId("layer-list-item:road")).shouldNotExist();
await when.click("layer-list-item:background");
await expect(get.elementByTestId("layer-list-group:park-1").getByRole("button")).toHaveAttribute("aria-expanded", "false");
await then(get.elementByTestId("layer-list-item:park-b")).shouldNotBeVisible();
await then(get.elementByTestId("layer-list-item:park-e")).shouldNotBeVisible();
});
test("preserves later groups after deleting an entire group", async () => {
await when.click("skip-target-layer-list");
await when.deleteLayer("park-a", control);
await when.deleteLayer("park-b", control);
await when.deleteLayer("park-c", control);
await expect(get.elementByTestId("layer-list-group:water-4").getByRole("button")).toHaveAttribute("aria-expanded", "true");
await then(get.elementByTestId("layer-list-item:water-b")).shouldBeVisible();
});
});
}
test("simple", async () => { test("simple", async () => {
await when.setStyle("geojson"); await when.setStyle("geojson");
+2 -26
View File
@@ -1,6 +1,5 @@
import { PlaywrightHelper } from "./playwright-helper"; import { PlaywrightHelper } from "./playwright-helper";
import { ModalDriver } from "./modal-driver"; import { ModalDriver } from "./modal-driver";
import emptyStyle from "../src/config/empty-style.json" with { type: "json" };
const baseUrl = "http://localhost:8888/"; const baseUrl = "http://localhost:8888/";
const isMac = process.platform === "darwin"; const isMac = process.platform === "darwin";
@@ -40,7 +39,6 @@ export class MaputnikDriver {
"example-style-with-zoom-7-and-center-0-51.json", "example-style-with-zoom-7-and-center-0-51.json",
"example-style-with-zoom-5-and-center-50-50.json", "example-style-with-zoom-5-and-center-50-50.json",
"access-token-style.json", "access-token-style.json",
"grouped-layers-style.json",
]; ];
for (const fixture of styleFixtures) { for (const fixture of styleFixtures) {
await this.helper.given.interceptAndMockResponse({ await this.helper.given.interceptAndMockResponse({
@@ -57,11 +55,6 @@ export class MaputnikDriver {
url: "https://www.glyph-server.com/*", url: "https://www.glyph-server.com/*",
response: ["Font 1", "Font 2", "Font 3"], response: ["Font 1", "Font 2", "Font 3"],
}); });
await this.helper.given.interceptAndMockResponse({
method: "GET",
url: /cdn\.jsdelivr\.net\/.*\/empty-style\.json$/,
response: emptyStyle,
});
}, },
}; };
@@ -70,18 +63,6 @@ export class MaputnikDriver {
modal: this.modalDriver.when, modal: this.modalDriver.when,
deleteLayer: async (id: string, control: "menu" | "trash" = "menu") => {
if (control === "trash") {
await this.helper.when.hover("layer-list-item:" + id);
await this.helper.when.click("layer-list-item:" + id + ":delete");
return;
}
await this.helper.when.click("layer-list-item:" + id);
await this.helper.when.click("skip-target-layer-editor");
await this.helper.when.click("menu-delete-layer");
},
setStyle: async ( setStyle: async (
styleProperties: styleProperties:
| "geojson" | "geojson"
@@ -92,7 +73,6 @@ export class MaputnikDriver {
| "font" | "font"
| "zoom_7_center_0_51" | "zoom_7_center_0_51"
| "access_tokens" | "access_tokens"
| "grouped_layers"
| "", | "",
zoom?: number zoom?: number
) => { ) => {
@@ -105,7 +85,6 @@ export class MaputnikDriver {
font: "example-style-with-fonts.json", font: "example-style-with-fonts.json",
zoom_7_center_0_51: "example-style-with-zoom-7-and-center-0-51.json", zoom_7_center_0_51: "example-style-with-zoom-7-and-center-0-51.json",
access_tokens: "access-token-style.json", access_tokens: "access-token-style.json",
grouped_layers: "grouped-layers-style.json",
}; };
const url = new URL(baseUrl); const url = new URL(baseUrl);
@@ -182,9 +161,8 @@ export class MaputnikDriver {
await this.helper.when.typeText(text); await this.helper.when.typeText(text);
}, },
setTextInJsonEditor: async (text: string, selector?: string) => { setTextInJsonEditor: async (text: string) => {
const scope = selector ? this.helper.get.elementByTestId(selector).locator(".cm-line") : this.helper.get.element(".cm-line"); await this.helper.get.element(".cm-line").first().click();
await scope.first().click();
await this.helper.when.typeKeys("{selectall}"); await this.helper.when.typeKeys("{selectall}");
await this.helper.when.typeText(text); await this.helper.when.typeText(text);
}, },
@@ -365,8 +343,6 @@ export class MaputnikDriver {
skipTargetLayerEditor: () => this.helper.get.elementByTestId("skip-target-layer-editor"), skipTargetLayerEditor: () => this.helper.get.elementByTestId("skip-target-layer-editor"),
jsonEditorErrors: (selector: string) => this.helper.get.elementByTestId(selector).locator(".cm-lint-marker-error"),
styleFromLocalStorage: () => this.helper.query(() => this.readStoredStyle()), styleFromLocalStorage: () => this.helper.query(() => this.readStoredStyle()),
fixture: (name: string) => this.helper.readFixture(name), fixture: (name: string) => this.helper.readFixture(name),
-60
View File
@@ -64,30 +64,6 @@ describe("modals", () => {
}); });
}); });
describe("debug", () => {
beforeEach(async () => {
await when.setStyle("zoom_7_center_0_51");
await then(get.locationHash()).shouldInclude("#7/51/0");
await when.typeKeys("!");
});
test("max zoom is empty until the user sets it", async () => {
await then(get.elementByTestId("modal:debug.max-zoom")).shouldHaveValue("");
});
test("lowering the max zoom zooms the map out to it", async () => {
await when.setValue("modal:debug.max-zoom", "3");
await then(get.locationHash()).shouldInclude("#3/51/0");
});
test("typing a multi-digit max zoom keeps the map in place", async () => {
await when.type("modal:debug.max-zoom", "{selectall}{backspace}22");
// Let the debounced update reach the map
await when.wait(1000);
await then(get.locationHash()).shouldInclude("#7/51/0");
});
});
describe("export", () => { describe("export", () => {
beforeEach(async () => { beforeEach(async () => {
await when.click("nav:export"); await when.click("nav:export");
@@ -362,29 +338,6 @@ describe("modals", () => {
}); });
}); });
test("font faces", async () => {
const fontFaces = { "Noto Sans Regular": [{ url: "http://example.com/font.ttf", "unicode-range": ["U+1780-17FF"] }] };
await when.setTextInJsonEditor(JSON.stringify(fontFaces), "modal:settings.font-faces");
await when.click("modal:settings.name");
await then(get.styleFromLocalStorage()).shouldDeepNestedInclude({
"font-faces": fontFaces,
});
});
test("unset font faces show an empty editor without errors", async () => {
await when.wait(1000);
await then(get.jsonEditorErrors("modal:settings.font-faces")).shouldNotExist();
await when.setTextInJsonEditor(JSON.stringify({ Font: "http://example.com/font.ttf" }), "modal:settings.font-faces");
await when.click("modal:settings.name");
await when.setTextInJsonEditor("", "modal:settings.font-faces");
await when.typeKeys("{backspace}");
await when.click("modal:settings.name");
await when.wait(1000);
await then(get.jsonEditorErrors("modal:settings.font-faces")).shouldNotExist();
await then(get.styleFromLocalStorage()).shouldNotHaveProperty("font-faces");
});
test("maptiler access token", async () => { test("maptiler access token", async () => {
const apiKey = "testing123"; const apiKey = "testing123";
await when.setValue("modal:settings.maputnik:openmaptiles_access_token", apiKey); await when.setValue("modal:settings.maputnik:openmaptiles_access_token", apiKey);
@@ -425,24 +378,11 @@ describe("modals", () => {
await when.setValue("modal:settings.zoom", "4"); await when.setValue("modal:settings.zoom", "4");
await when.setValue("modal:settings.bearing", "12"); await when.setValue("modal:settings.bearing", "12");
await when.setValue("modal:settings.pitch", "30"); await when.setValue("modal:settings.pitch", "30");
await when.setValue("modal:settings.roll", "15");
await when.setValue("modal:settings.center-altitude", "100");
await when.click("modal:settings.name"); await when.click("modal:settings.name");
await then(get.styleFromLocalStorage()).shouldDeepNestedInclude({ await then(get.styleFromLocalStorage()).shouldDeepNestedInclude({
zoom: 4, zoom: 4,
bearing: 12, bearing: 12,
pitch: 30, pitch: 30,
roll: 15,
centerAltitude: 100,
});
});
test("sky and fog blends", async () => {
await when.setValue("modal:settings.sky-horizon-blend", "0.3");
await when.setValue("modal:settings.fog-ground-blend", "0.2");
await when.click("modal:settings.name");
await then(get.styleFromLocalStorage()).shouldDeepNestedInclude({
sky: { "sky-horizon-blend": 0.3, "fog-ground-blend": 0.2 },
}); });
}); });
-3
View File
@@ -135,9 +135,6 @@ export class Assertable<T> {
shouldDeepNestedInclude = (value: Record<string, unknown> | unknown[]) => shouldDeepNestedInclude = (value: Record<string, unknown> | unknown[]) =>
this.assertValue((actual) => assertDeepNestedInclude(actual, value)); this.assertValue((actual) => assertDeepNestedInclude(actual, value));
shouldNotHaveProperty = (property: string) =>
this.assertValue((actual) => expect(actual).not.toHaveProperty([property]));
} }
async function typeSequence(page: Page, text: string): Promise<void> { async function typeSequence(page: Page, text: string): Promise<void> {
+1 -1
View File
@@ -1,7 +1,7 @@
import { defineConfig } from "i18next-cli"; import { defineConfig } from "i18next-cli";
export default defineConfig({ export default defineConfig({
locales: ["az", "de", "fr", "he", "it", "ja", "ko", "tr", "zh"], locales: ["de", "fr", "he", "it", "ja", "ko", "tr", "zh"],
extract: { extract: {
input: ["src/**/*.{js,jsx,ts,tsx}"], input: ["src/**/*.{js,jsx,ts,tsx}"],
output: "src/locales/{{language}}/{{namespace}}.json", output: "src/locales/{{language}}/{{namespace}}.json",
+1032 -902
View File
File diff suppressed because it is too large Load Diff
+28 -28
View File
@@ -29,16 +29,16 @@
"dependencies": { "dependencies": {
"@codemirror/lang-json": "^6.0.2", "@codemirror/lang-json": "^6.0.2",
"@codemirror/lint": "^6.9.7", "@codemirror/lint": "^6.9.7",
"@codemirror/state": "^6.7.6", "@codemirror/state": "^6.7.1",
"@codemirror/theme-one-dark": "^6.1.3", "@codemirror/theme-one-dark": "^6.1.3",
"@codemirror/view": "^6.43.15", "@codemirror/view": "^6.43.9",
"@dnd-kit/core": "^6.3.1", "@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0", "@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2", "@dnd-kit/utilities": "^3.2.2",
"@mapbox/mapbox-gl-rtl-text": "^0.4.0", "@mapbox/mapbox-gl-rtl-text": "^0.4.0",
"@maplibre/maplibre-gl-geocoder": "^1.9.4", "@maplibre/maplibre-gl-geocoder": "^1.9.4",
"@maplibre/maplibre-gl-inspect": "^1.9.0", "@maplibre/maplibre-gl-inspect": "^1.9.0",
"@maplibre/maplibre-gl-style-spec": "^26.5.0", "@maplibre/maplibre-gl-style-spec": "^26.2.1",
"array-move": "^4.0.0", "array-move": "^4.0.0",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"classnames": "^2.5.1", "classnames": "^2.5.1",
@@ -48,8 +48,8 @@
"downshift": "^9.4.0", "downshift": "^9.4.0",
"events": "^3.3.0", "events": "^3.3.0",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"i18next": "^26.5.11", "i18next": "^26.3.6",
"i18next-browser-languagedetector": "^8.2.3", "i18next-browser-languagedetector": "^8.2.1",
"i18next-resources-to-backend": "^1.2.3", "i18next-resources-to-backend": "^1.2.3",
"json-stringify-pretty-compact": "^4.0.0", "json-stringify-pretty-compact": "^4.0.0",
"json-to-ast": "^2.1.0", "json-to-ast": "^2.1.0",
@@ -60,23 +60,23 @@
"lodash.get": "^4.4.2", "lodash.get": "^4.4.2",
"lodash.isequal": "^4.5.0", "lodash.isequal": "^4.5.0",
"lodash.throttle": "^4.1.1", "lodash.throttle": "^4.1.1",
"maplibre-gl": "^6.16.0", "maplibre-gl": "^6.4.1",
"maputnik-design": "github:maputnik/design#172b06c", "maputnik-design": "github:maputnik/design#172b06c",
"ol": "^10.11.0", "ol": "^10.10.0",
"ol-mapbox-style": "^13.8.0", "ol-mapbox-style": "^13.4.2",
"pmtiles": "^4.5.0", "pmtiles": "^4.5.0",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"react": "^19.3.1", "react": "^19.2.8",
"react-accessible-accordion": "^5.0.1", "react-accessible-accordion": "^5.0.1",
"react-aria-menubutton": "^8.0.0", "react-aria-menubutton": "^8.0.0",
"react-aria-modal": "^5.0.2", "react-aria-modal": "^5.0.2",
"react-collapse": "^5.1.1", "react-collapse": "^5.1.1",
"react-color": "^2.19.3", "react-color": "^2.19.3",
"react-dom": "^19.3.1", "react-dom": "^19.2.8",
"react-i18next": "^17.1.9", "react-i18next": "^17.0.11",
"react-icons": "^5.7.0", "react-icons": "^5.7.0",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
"react-resizable-panels": "^4.15.0", "react-resizable-panels": "^4.11.0",
"reconnecting-websocket": "^4.4.0", "reconnecting-websocket": "^4.4.0",
"slugify": "^1.6.9", "slugify": "^1.6.9",
"string-hash": "^1.1.3", "string-hash": "^1.1.3",
@@ -102,7 +102,7 @@
"devDependencies": { "devDependencies": {
"@eslint/js": "^10.0.1", "@eslint/js": "^10.0.1",
"@istanbuljs/nyc-config-typescript": "^1.0.2", "@istanbuljs/nyc-config-typescript": "^1.0.2",
"@playwright/test": "^1.64.1", "@playwright/test": "^1.62.1",
"@stylistic/eslint-plugin": "^5.10.0", "@stylistic/eslint-plugin": "^5.10.0",
"@types/codemirror": "^5.60.18", "@types/codemirror": "^5.60.18",
"@types/color": "^4.2.1", "@types/color": "^4.2.1",
@@ -117,36 +117,36 @@
"@types/lodash.isequal": "^4.5.8", "@types/lodash.isequal": "^4.5.8",
"@types/lodash.throttle": "^4.1.9", "@types/lodash.throttle": "^4.1.9",
"@types/randomcolor": "^0.5.9", "@types/randomcolor": "^0.5.9",
"@types/react": "^19.3.0", "@types/react": "^19.2.18",
"@types/react-aria-menubutton": "^6.2.14", "@types/react-aria-menubutton": "^6.2.14",
"@types/react-aria-modal": "^5.0.0", "@types/react-aria-modal": "^5.0.0",
"@types/react-collapse": "^5.0.4", "@types/react-collapse": "^5.0.4",
"@types/react-color": "^3.0.13", "@types/react-color": "^3.0.13",
"@types/react-dom": "^19.3.0", "@types/react-dom": "^19.2.4",
"@types/string-hash": "^1.1.3", "@types/string-hash": "^1.1.3",
"@types/wicg-file-system-access": "^2023.10.7", "@types/wicg-file-system-access": "^2023.10.7",
"@vitejs/plugin-react": "^6.1.2", "@vitejs/plugin-react": "^6.0.5",
"@vitest/coverage-v8": "^5.0.5", "@vitest/coverage-v8": "^4.1.11",
"cors": "^2.8.6", "cors": "^2.8.6",
"eslint": "^10.13.0", "eslint": "^10.8.1",
"eslint-plugin-react": "^7.37.5", "eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.7", "eslint-plugin-react-refresh": "^0.5.4",
"i18next-cli": "^1.80.5", "i18next-cli": "^1.71.0",
"istanbul": "^0.4.5", "istanbul": "^0.4.5",
"istanbul-lib-coverage": "^3.2.2", "istanbul-lib-coverage": "^3.2.2",
"nyc": "^18.0.0", "nyc": "^18.0.0",
"postcss": "^8.5.32", "postcss": "^8.5.26",
"react-hot-loader": "^4.13.1", "react-hot-loader": "^4.13.1",
"sass": "^1.106.1", "sass": "^1.102.0",
"stylelint": "^17.16.0", "stylelint": "^17.14.1",
"stylelint-config-recommended-scss": "^17.0.1", "stylelint-config-recommended-scss": "^17.0.1",
"stylelint-scss": "^7.4.0", "stylelint-scss": "^7.2.0",
"typescript": "^6.0.3", "typescript": "^6.0.3",
"typescript-eslint": "^8.72.1", "typescript-eslint": "^8.67.0",
"uuid": "^14.0.3", "uuid": "^14.0.2",
"vite": "^8.3.5", "vite": "^8.2.1",
"vite-plugin-istanbul": "^9.0.1", "vite-plugin-istanbul": "^9.0.1",
"vitest": "^5.0.5" "vitest": "^4.1.11"
} }
} }
-5
View File
@@ -1,10 +1,6 @@
import { cpus } from "node:os";
import { defineConfig, devices } from "@playwright/test"; import { defineConfig, devices } from "@playwright/test";
const isCI = !!process.env.CI; const isCI = !!process.env.CI;
// Playwright defaults to CPU / 2 workers,
// capping the number of workers to 4 to avoid overloading browsers.
const workers = Math.min(4, Math.max(1, Math.floor(cpus().length / 2)));
// When the app is already served elsewhere (e.g. the docker e2e job) set // When the app is already served elsewhere (e.g. the docker e2e job) set
// E2E_NO_WEBSERVER=1 so Playwright does not start its own dev server. // E2E_NO_WEBSERVER=1 so Playwright does not start its own dev server.
const useExternalServer = !!process.env.E2E_NO_WEBSERVER; const useExternalServer = !!process.env.E2E_NO_WEBSERVER;
@@ -17,7 +13,6 @@ export default defineConfig({
globalTeardown: "./e2e/utils/e2e-teardown.ts", globalTeardown: "./e2e/utils/e2e-teardown.ts",
fullyParallel: true, fullyParallel: true,
forbidOnly: isCI, forbidOnly: isCI,
workers,
retries: isCI ? 2 : 0, retries: isCI ? 2 : 0,
reporter: isCI ? [["list"], ["html", { open: "never" }]] : "list", reporter: isCI ? [["list"], ["html", { open: "never" }]] : "list",
use: { use: {
+1 -18
View File
@@ -83,22 +83,6 @@ function updateRootSpec(spec: any, fieldName: string, newValues: any) {
}; };
} }
/**
* Whether the given element consumes keystrokes as text.
*
* Shortcuts have to stay out of the way while the user is typing, but asking
* whether the focus is on `document.body` answers a different question: the map
* canvas is not a text field, yet focusing it used to disable every shortcut.
*/
function isTextEntryElement(element: Element | null): boolean {
if (!element) return false;
const node = element as HTMLElement;
return node.isContentEditable ||
node.tagName === "INPUT" ||
node.tagName === "TEXTAREA" ||
node.tagName === "SELECT";
}
type AppState = { type AppState = {
errors: MappedError[], errors: MappedError[],
infos: string[], infos: string[],
@@ -181,7 +165,6 @@ export class App extends React.Component<any, AppState> {
showTileBoundaries: false, showTileBoundaries: false,
showCollisionBoxes: false, showCollisionBoxes: false,
showOverdrawInspector: false, showOverdrawInspector: false,
maxZoom: undefined,
}, },
openlayersDebugOptions: { openlayersDebugOptions: {
debugToolbox: false, debugToolbox: false,
@@ -259,7 +242,7 @@ export class App extends React.Component<any, AppState> {
(e.target as HTMLElement).blur(); (e.target as HTMLElement).blur();
document.body.focus(); document.body.focus();
} }
else if(this.state.isOpen.shortcuts || !isTextEntryElement(document.activeElement)) { else if(this.state.isOpen.shortcuts || document.activeElement === document.body) {
const shortcut = shortcuts.find((shortcut) => { const shortcut = shortcuts.find((shortcut) => {
return (shortcut.key === e.key); return (shortcut.key === e.key);
}); });
+1
View File
@@ -4,6 +4,7 @@ import { ScrollContainer } from "./ScrollContainer";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { IconContext } from "react-icons"; import { IconContext } from "react-icons";
// Keep these in sync with $layout-list-width/$layout-editor-width in _vars.scss
const DEFAULT_LIST_WIDTH = 200; const DEFAULT_LIST_WIDTH = 200;
const DEFAULT_DRAWER_WIDTH = 370; const DEFAULT_DRAWER_WIDTH = 370;
const DEFAULT_SIDEBAR_WIDTH = DEFAULT_LIST_WIDTH + DEFAULT_DRAWER_WIDTH; const DEFAULT_SIDEBAR_WIDTH = DEFAULT_LIST_WIDTH + DEFAULT_DRAWER_WIDTH;
+12 -6
View File
@@ -129,10 +129,16 @@ type FieldFunctionProps = {
* https://www.mapbox.com/mapbox-gl-style-spec/#types-function-zoom-property * https://www.mapbox.com/mapbox-gl-style-spec/#types-function-zoom-property
*/ */
export const FieldFunction: React.FC<FieldFunctionProps> = (props) => { export const FieldFunction: React.FC<FieldFunctionProps> = (props) => {
const [dataType, setDataType] = React.useState(
getDataType(props.value, props.fieldSpec)
);
const [isEditing, setIsEditing] = React.useState(false); const [isEditing, setIsEditing] = React.useState(false);
// Keep the expression editor mounted while typing, but otherwise select the
// editor from the current value so a collapsed function never renders as stops. React.useEffect(() => {
const dataType = isEditing ? "expression" : getDataType(props.value, props.fieldSpec); if (!isEditing) {
setDataType(getDataType(props.value, props.fieldSpec));
}
}, [props.value, props.fieldSpec, isEditing]);
const getFieldFunctionType = (fieldSpec: any) => { const getFieldFunctionType = (fieldSpec: any) => {
if (fieldSpec.expression.interpolated) { if (fieldSpec.expression.interpolated) {
@@ -167,7 +173,7 @@ export const FieldFunction: React.FC<FieldFunctionProps> = (props) => {
const deleteExpression = () => { const deleteExpression = () => {
const { fieldSpec, fieldName } = props; const { fieldSpec, fieldName } = props;
props.onChange(fieldName, fieldSpec.default); props.onChange(fieldName, fieldSpec.default);
setIsEditing(false); setDataType("value");
}; };
const deleteStop = (stopIdx: number) => { const deleteStop = (stopIdx: number) => {
@@ -227,10 +233,10 @@ export const FieldFunction: React.FC<FieldFunctionProps> = (props) => {
type: "identity", type: "identity",
property: value[1], property: value[1],
}); });
setIsEditing(false); setDataType("value");
} else if (isLiteralExpression(value)) { } else if (isLiteralExpression(value)) {
props.onChange(fieldName, value[1]); props.onChange(fieldName, value[1]);
setIsEditing(false); setDataType("value");
} }
}; };
+3 -17
View File
@@ -10,14 +10,12 @@ import type { StylePropertySpecification } from "maplibre-gl";
import type { TransactionSpec } from "@codemirror/state"; import type { TransactionSpec } from "@codemirror/state";
export type InputJsonProps = { export type InputJsonProps = {
value: object | undefined value: object
className?: string className?: string
onChange(object: object | undefined): void onChange(object: object): void
onFocus?(...args: unknown[]): unknown onFocus?(...args: unknown[]): unknown
onBlur?(...args: unknown[]): unknown onBlur?(...args: unknown[]): unknown
lintType: "layer" | "style" | "expression" | "json" lintType: "layer" | "style" | "expression" | "json"
/** When set, an empty editor is valid and means the value is unset */
optional?: boolean
spec?: StylePropertySpecification | undefined spec?: StylePropertySpecification | undefined
/** /**
* When setting this and using search and replace, the editor will scroll to the selected text * When setting this and using search and replace, the editor will scroll to the selected text
@@ -51,10 +49,6 @@ class InputJsonInternal extends React.Component<InputJsonInternalProps, InputJso
} }
getPrettyJson(data: any) { getPrettyJson(data: any) {
// An unset value is shown as an empty editor
if (data === undefined) {
return "";
}
return stringifyPretty(data, {indent: 2, maxLength: 40}); return stringifyPretty(data, {indent: 2, maxLength: 40});
} }
@@ -66,8 +60,7 @@ class InputJsonInternal extends React.Component<InputJsonInternalProps, InputJso
onChange: (value:string) => this.onChange(value), onChange: (value:string) => this.onChange(value),
onFocus: () => this.onFocus(), onFocus: () => this.onFocus(),
onBlur: () => this.onBlur(), onBlur: () => this.onBlur(),
spec: this.props.spec, spec: this.props.spec
optional: this.props.optional
}); });
} }
@@ -114,13 +107,6 @@ class InputJsonInternal extends React.Component<InputJsonInternalProps, InputJso
const newCode = this._view!.state.doc.toString(); const newCode = this._view!.state.doc.toString();
if (this.state.prevValue !== newCode) { if (this.state.prevValue !== newCode) {
if (this.props.optional && newCode.trim() === "") {
this.props.onChange(undefined);
this.setState({
prevValue: newCode,
});
return;
}
let parsedLayer, err; let parsedLayer, err;
try { try {
parsedLayer = JSON.parse(newCode); parsedLayer = JSON.parse(newCode);
+4 -36
View File
@@ -106,13 +106,13 @@ class LayerListContainerInternal extends React.Component<LayerListContainerInter
}); });
}; };
groupedLayers(layers = this.props.layers): (LayerSpecification & {key: string})[][] { groupedLayers(): (LayerSpecification & {key: string})[][] {
const groups = []; const groups = [];
const layerIdCount = new Map(); const layerIdCount = new Map();
for (let i = 0; i < layers.length; i++) { for (let i = 0; i < this.props.layers.length; i++) {
const origLayer = layers[i]; const origLayer = this.props.layers[i];
const previousLayer = layers[i-1]; const previousLayer = this.props.layers[i-1];
layerIdCount.set(origLayer.id, layerIdCount.set(origLayer.id,
layerIdCount.has(origLayer.id) ? layerIdCount.get(origLayer.id) + 1 : 0 layerIdCount.has(origLayer.id) ? layerIdCount.get(origLayer.id) + 1 : 0
); );
@@ -192,39 +192,7 @@ class LayerListContainerInternal extends React.Component<LayerListContainerInter
return propsChanged; return propsChanged;
} }
/**
* Preserves group state through surviving layer IDs when group indices change.
* If deletion joins groups, the result stays expanded when either group was.
*/
private preserveLayerGroupState(previousLayers: LayerSpecification[]) {
if (previousLayers === this.props.layers) return;
const collapsedByLayer = new Map<string, boolean>();
let idx = 0;
for (const layers of this.groupedLayers(previousLayers)) {
const collapsed = this.isCollapsed(layerPrefix(layers[0].id), idx);
for (const layer of layers) {
collapsedByLayer.set(layer.id, collapsed);
}
idx += layers.length;
}
const collapsedGroups: {[key: string]: boolean} = {};
idx = 0;
for (const layers of this.groupedLayers()) {
const lookupKey = [layerPrefix(layers[0].id), idx].join("-");
collapsedGroups[lookupKey] = layers.every(layer => collapsedByLayer.get(layer.id) !== false);
idx += layers.length;
}
if (!lodash.isEqual(collapsedGroups, this.state.collapsedGroups)) {
this.setState({ collapsedGroups });
}
}
componentDidUpdate (prevProps: LayerListContainerProps) { componentDidUpdate (prevProps: LayerListContainerProps) {
this.preserveLayerGroupState(prevProps.layers);
if (prevProps.selectedLayerIndex !== this.props.selectedLayerIndex) { if (prevProps.selectedLayerIndex !== this.props.selectedLayerIndex) {
const selectedItemNode = this.selectedItemRef.current; const selectedItemNode = this.selectedItemRef.current;
if (selectedItemNode && selectedItemNode.node) { if (selectedItemNode && selectedItemNode.node) {
+2 -10
View File
@@ -32,8 +32,6 @@ const DraggableLabel: React.FC<DraggableLabelProps> = (props) => {
type IconActionProps = { type IconActionProps = {
action: string action: string
/** Tooltip text, for buttons whose action reads differently from their icon. */
title?: string
onClick(...args: unknown[]): unknown onClick(...args: unknown[]): unknown
wdKey?: string wdKey?: string
classBlockName?: string classBlockName?: string
@@ -64,7 +62,7 @@ class IconAction extends React.Component<IconActionProps> {
return <button return <button
tabIndex={-1} tabIndex={-1}
title={this.props.title ?? this.props.action} title={this.props.action}
className={`maputnik-layer-list-icon-action ${classAdditions}`} className={`maputnik-layer-list-icon-action ${classAdditions}`}
data-wd-key={this.props.wdKey} data-wd-key={this.props.wdKey}
onClick={this.props.onClick} onClick={this.props.onClick}
@@ -113,12 +111,7 @@ export const LayerListItem = React.forwardRef<HTMLLIElement, LayerListItemProps>
opacity: isDragging ? 0.5 : 1, opacity: isDragging ? 0.5 : 1,
}; };
// The icon and the CSS modifier describe the layer's current visibility, const visibilityAction = visibility === "visible" ? "show" : "hide";
// while the tooltip has to describe what clicking the button does, which is
// the opposite of it.
const isVisible = visibility === "visible";
const visibilityAction = isVisible ? "show" : "hide";
const visibilityTitle = isVisible ? "hide" : "show";
// Cast ref to MutableRefObject since we know from the codebase that's what's always passed // Cast ref to MutableRefObject since we know from the codebase that's what's always passed
const refObject = ref as React.MutableRefObject<HTMLLIElement | null> | null; const refObject = ref as React.MutableRefObject<HTMLLIElement | null> | null;
@@ -162,7 +155,6 @@ export const LayerListItem = React.forwardRef<HTMLLIElement, LayerListItemProps>
<IconAction <IconAction
wdKey={"layer-list-item:" + props.layerId + ":toggle-visibility"} wdKey={"layer-list-item:" + props.layerId + ":toggle-visibility"}
action={visibilityAction} action={visibilityAction}
title={visibilityTitle}
classBlockName="visibility" classBlockName="visibility"
classBlockModifier={visibilityAction} classBlockModifier={visibilityAction}
onClick={_e => onLayerVisibilityToggle!(props.layerIndex)} onClick={_e => onLayerVisibilityToggle!(props.layerIndex)}
+2 -2
View File
@@ -107,7 +107,7 @@ class MapMaplibreGlInternal extends React.Component<MapMaplibreGlInternalProps,
shouldComponentUpdate(nextProps: MapMaplibreGlInternalProps, nextState: MapMaplibreGlState) { shouldComponentUpdate(nextProps: MapMaplibreGlInternalProps, nextState: MapMaplibreGlState) {
let should = false; let should = false;
try { try {
should = JSON.stringify(this.props) !== JSON.stringify(nextProps) || (Object.keys(nextState) as (keyof MapMaplibreGlState)[]).some(key => key !== "zoom" && this.state[key] !== nextState[key]); should = JSON.stringify(this.props) !== JSON.stringify(nextProps) || JSON.stringify(this.state) !== JSON.stringify(nextState);
} catch(_e) { } catch(_e) {
// no biggie, carry on // no biggie, carry on
} }
@@ -126,7 +126,6 @@ class MapMaplibreGlInternal extends React.Component<MapMaplibreGlInternalProps,
map.showTileBoundaries = this.props.options?.showTileBoundaries!; map.showTileBoundaries = this.props.options?.showTileBoundaries!;
map.showCollisionBoxes = this.props.options?.showCollisionBoxes!; map.showCollisionBoxes = this.props.options?.showCollisionBoxes!;
map.showOverdrawInspector = this.props.options?.showOverdrawInspector!; map.showOverdrawInspector = this.props.options?.showOverdrawInspector!;
map.setMaxZoom(this.props.options?.maxZoom);
// set the map view when the prop was updated from outside // set the map view when the prop was updated from outside
if (this.props.mapView._from === "app") { if (this.props.mapView._from === "app") {
@@ -153,6 +152,7 @@ class MapMaplibreGlInternal extends React.Component<MapMaplibreGlInternalProps,
container: this.container!, container: this.container!,
style: this.props.mapStyle, style: this.props.mapStyle,
hash: true, hash: true,
maxZoom: 24,
// make root relative urls in stylefiles work as maplibre gl js does // make root relative urls in stylefiles work as maplibre gl js does
// not support this for everything: // not support this for everything:
// https://github.com/maplibre/maplibre-gl-js/issues/6818 // https://github.com/maplibre/maplibre-gl-js/issues/6818
+3 -24
View File
@@ -1,19 +1,16 @@
import React from "react"; import React from "react";
import { debounce } from "lodash";
import { Trans, type WithTranslation, withTranslation } from "react-i18next"; import { Trans, type WithTranslation, withTranslation } from "react-i18next";
import type { MapOptions } from "maplibre-gl";
import { Modal } from "./Modal"; import { Modal } from "./Modal";
import { FieldNumber } from "../FieldNumber";
type ModalDebugInternalProps = { type ModalDebugInternalProps = {
isOpen: boolean isOpen: boolean
renderer: string renderer: string
onChangeMaplibreGlDebug(key: string, value: boolean | number | undefined): unknown onChangeMaplibreGlDebug(key: string, checked: boolean): unknown
onChangeOpenlayersDebug(key: string, checked: boolean): unknown onChangeOpenlayersDebug(key: string, checked: boolean): unknown
onOpenToggle(): void onOpenToggle(): void
maplibreGlDebugOptions?: Partial<MapOptions> maplibreGlDebugOptions?: object
openlayersDebugOptions?: object openlayersDebugOptions?: object
mapView: { mapView: {
zoom: number zoom: number
@@ -26,15 +23,6 @@ type ModalDebugInternalProps = {
class ModalDebugInternal extends React.Component<ModalDebugInternalProps> { class ModalDebugInternal extends React.Component<ModalDebugInternalProps> {
// Typing "22" would otherwise apply 2 first and zoom the map out of the current view
onChangeMaxZoom = debounce((value: number | undefined) => {
this.props.onChangeMaplibreGlDebug("maxZoom", value);
}, 500);
componentWillUnmount() {
this.onChangeMaxZoom.cancel();
}
render() { render() {
const {t, mapView} = this.props; const {t, mapView} = this.props;
@@ -51,9 +39,8 @@ class ModalDebugInternal extends React.Component<ModalDebugInternalProps> {
<section className="maputnik-modal-section maputnik-modal-shortcuts"> <section className="maputnik-modal-section maputnik-modal-shortcuts">
<h1>{t("Options")}</h1> <h1>{t("Options")}</h1>
{this.props.renderer === "mlgljs" && {this.props.renderer === "mlgljs" &&
<>
<ul> <ul>
{Object.entries(this.props.maplibreGlDebugOptions!).filter((entry): entry is [string, boolean] => typeof entry[1] === "boolean").map(([key, val]) => { {Object.entries(this.props.maplibreGlDebugOptions!).map(([key, val]) => {
return <li key={key}> return <li key={key}>
<label> <label>
<input type="checkbox" checked={val} onChange={(e) => this.props.onChangeMaplibreGlDebug(key, e.target.checked)} /> {key} <input type="checkbox" checked={val} onChange={(e) => this.props.onChangeMaplibreGlDebug(key, e.target.checked)} /> {key}
@@ -61,14 +48,6 @@ class ModalDebugInternal extends React.Component<ModalDebugInternalProps> {
</li>; </li>;
})} })}
</ul> </ul>
<FieldNumber
label={t("Max Zoom")}
data-wd-key="modal:debug.max-zoom"
value={this.props.maplibreGlDebugOptions!.maxZoom ?? undefined}
min={0}
onChange={this.onChangeMaxZoom}
/>
</>
} }
{this.props.renderer === "ol" && {this.props.renderer === "ol" &&
<ul> <ul>
+1 -107
View File
@@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json"; import latest from "@maplibre/maplibre-gl-style-spec/dist/latest.json";
import type {LightSpecification, ProjectionSpecification, SkySpecification, StyleSpecification, TerrainSpecification, TransitionSpecification} from "maplibre-gl"; import type {LightSpecification, ProjectionSpecification, StyleSpecification, TerrainSpecification, TransitionSpecification} from "maplibre-gl";
import { type WithTranslation, withTranslation } from "react-i18next"; import { type WithTranslation, withTranslation } from "react-i18next";
import { FieldArray } from "../FieldArray"; import { FieldArray } from "../FieldArray";
@@ -81,24 +81,6 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
}); });
} }
changeSkyProperty(property: keyof SkySpecification, value: any) {
const sky = {
...this.props.mapStyle.sky,
};
if (value === undefined) {
delete sky[property];
}
else {
sky[property] = value;
}
this.props.onStyleChanged({
...this.props.mapStyle,
sky,
});
}
changeProjectionType(value: any) { changeProjectionType(value: any) {
const projection = { const projection = {
...this.props.mapStyle.projection, ...this.props.mapStyle.projection,
@@ -142,7 +124,6 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
const transition = this.props.mapStyle.transition || {}; const transition = this.props.mapStyle.transition || {};
const terrain = this.props.mapStyle.terrain || {} as TerrainSpecification; const terrain = this.props.mapStyle.terrain || {} as TerrainSpecification;
const projection = this.props.mapStyle.projection || {} as ProjectionSpecification; const projection = this.props.mapStyle.projection || {} as ProjectionSpecification;
const sky = this.props.mapStyle.sky || {};
return <Modal return <Modal
data-wd-key="modal:settings" data-wd-key="modal:settings"
@@ -168,7 +149,6 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
<Block label={t("Sprite URL")} fieldSpec={latest.$root.sprite} data-wd-key="modal:settings.sprite"> <Block label={t("Sprite URL")} fieldSpec={latest.$root.sprite} data-wd-key="modal:settings.sprite">
<FieldJson <FieldJson
lintType="json" lintType="json"
optional
value={this.props.mapStyle.sprite as any} value={this.props.mapStyle.sprite as any}
onChange={(value) => this.changeStyleProperty("sprite", value)} onChange={(value) => this.changeStyleProperty("sprite", value)}
/> />
@@ -182,15 +162,6 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
onChange={(value) => this.changeStyleProperty("glyphs", value)} onChange={(value) => this.changeStyleProperty("glyphs", value)}
/> />
<Block label={t("Font faces")} fieldSpec={latest.$root["font-faces"]} data-wd-key="modal:settings.font-faces">
<FieldJson
lintType="json"
optional
value={this.props.mapStyle["font-faces"] as any}
onChange={(value) => this.changeStyleProperty("font-faces", value)}
/>
</Block>
<FieldString <FieldString
label={fsa.maputnik.maptiler_access_token.label} label={fsa.maputnik.maptiler_access_token.label}
fieldSpec={fsa.maputnik.maptiler_access_token} fieldSpec={fsa.maputnik.maptiler_access_token}
@@ -260,23 +231,6 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
onChange={(value) => this.changeStyleProperty("pitch", value)} onChange={(value) => this.changeStyleProperty("pitch", value)}
/> />
<FieldNumber
label={t("Roll")}
data-wd-key="modal:settings.roll"
fieldSpec={latest.$root.roll}
value={mapStyle.roll}
default={latest.$root.roll.default}
onChange={(value) => this.changeStyleProperty("roll", value)}
/>
<FieldNumber
label={t("Center altitude")}
data-wd-key="modal:settings.center-altitude"
fieldSpec={latest.$root.centerAltitude}
value={mapStyle.centerAltitude}
onChange={(value) => this.changeStyleProperty("centerAltitude", value)}
/>
<FieldEnum <FieldEnum
label={t("Light anchor")} label={t("Light anchor")}
fieldSpec={latest.light.anchor} fieldSpec={latest.light.anchor}
@@ -331,66 +285,6 @@ class ModalSettingsInternal extends React.Component<ModalSettingsInternalProps>
onChange={(value) => this.changeTerrainProperty("exaggeration", value)} onChange={(value) => this.changeTerrainProperty("exaggeration", value)}
/> />
<FieldColor
label={t("Sky color")}
fieldSpec={latest.sky["sky-color"]}
value={sky["sky-color"] as string}
default={latest.sky["sky-color"].default}
onChange={(value) => this.changeSkyProperty("sky-color", value)}
/>
<FieldColor
label={t("Horizon color")}
fieldSpec={latest.sky["horizon-color"]}
value={sky["horizon-color"] as string}
default={latest.sky["horizon-color"].default}
onChange={(value) => this.changeSkyProperty("horizon-color", value)}
/>
<FieldColor
label={t("Fog color")}
fieldSpec={latest.sky["fog-color"]}
value={sky["fog-color"] as string}
default={latest.sky["fog-color"].default}
onChange={(value) => this.changeSkyProperty("fog-color", value)}
/>
<FieldNumber
label={t("Sky horizon blend")}
data-wd-key="modal:settings.sky-horizon-blend"
fieldSpec={latest.sky["sky-horizon-blend"]}
value={sky["sky-horizon-blend"] as number}
default={latest.sky["sky-horizon-blend"].default}
onChange={(value) => this.changeSkyProperty("sky-horizon-blend", value)}
/>
<FieldNumber
label={t("Horizon fog blend")}
data-wd-key="modal:settings.horizon-fog-blend"
fieldSpec={latest.sky["horizon-fog-blend"]}
value={sky["horizon-fog-blend"] as number}
default={latest.sky["horizon-fog-blend"].default}
onChange={(value) => this.changeSkyProperty("horizon-fog-blend", value)}
/>
<FieldNumber
label={t("Fog ground blend")}
data-wd-key="modal:settings.fog-ground-blend"
fieldSpec={latest.sky["fog-ground-blend"]}
value={sky["fog-ground-blend"] as number}
default={latest.sky["fog-ground-blend"].default}
onChange={(value) => this.changeSkyProperty("fog-ground-blend", value)}
/>
<FieldNumber
label={t("Atmosphere blend")}
data-wd-key="modal:settings.atmosphere-blend"
fieldSpec={latest.sky["atmosphere-blend"]}
value={sky["atmosphere-blend"] as number}
default={latest.sky["atmosphere-blend"].default}
onChange={(value) => this.changeSkyProperty("atmosphere-blend", value)}
/>
<FieldNumber <FieldNumber
label={t("Transition delay")} label={t("Transition delay")}
data-wd-key="modal:settings.transition-delay" data-wd-key="modal:settings.transition-delay"
-1
View File
@@ -4,7 +4,6 @@ import resourcesToBackend from "i18next-resources-to-backend";
import { initReactI18next } from "react-i18next"; import { initReactI18next } from "react-i18next";
export const supportedLanguages = { export const supportedLanguages = {
"az": "Azərbaycan",
"de": "Deutsch", "de": "Deutsch",
"en": "English", "en": "English",
"fr": "Français", "fr": "Français",
+9 -19
View File
@@ -15,21 +15,6 @@ type LinterError = {
message: string; message: string;
}; };
type EditorProps = {
parent: HTMLElement,
value: string,
lintType: LintType,
onChange: (value: string) => void,
onFocus: () => void,
onBlur: () => void,
spec?: StylePropertySpecification,
/**
* An empty optional editor means the value is unset, which is valid
*/
optional?: boolean,
};
function getDiagnosticsFromExpressionErrors(errors: LinterError[], ast: ValueNode | PropertyNode) { function getDiagnosticsFromExpressionErrors(errors: LinterError[], ast: ValueNode | PropertyNode) {
const diagnostics: Diagnostic[] = []; const diagnostics: Diagnostic[] = [];
for (const error of errors) { for (const error of errors) {
@@ -143,7 +128,15 @@ function createMaplibreExpressionLinter(spec?: StylePropertySpecification) {
}; };
} }
export function createEditor(props: EditorProps): EditorView { export function createEditor(props: {
parent: HTMLElement,
value: string,
lintType: LintType,
onChange: (value: string) => void,
onFocus: () => void,
onBlur: () => void,
spec?: StylePropertySpecification,
}): EditorView {
let specificLinter: (view: EditorView) => Diagnostic[] = () => []; let specificLinter: (view: EditorView) => Diagnostic[] = () => [];
switch (props.lintType) { switch (props.lintType) {
case "style": case "style":
@@ -188,9 +181,6 @@ export function createEditor(props: EditorProps): EditorView {
}), }),
lintGutter(), lintGutter(),
linter((view: EditorView) => { linter((view: EditorView) => {
if (props.optional && view.state.doc.toString().trim() === "") {
return [];
}
const jsonErrors = jsonParseLinter()(view); const jsonErrors = jsonParseLinter()(view);
if (jsonErrors.length > 0) { if (jsonErrors.length > 0) {
return jsonErrors; return jsonErrors;
-1
View File
@@ -46,7 +46,6 @@ The following users can help you with the relevant languages:
| ISO Code | Language | User | | ISO Code | Language | User |
|----------|--------------------|--------------------------------------------| |----------|--------------------|--------------------------------------------|
| az | Azerbaijani | [@jamalkamaladdin](https://github.com/jamalkamaladdin) |
| de | German | [@josxha](https://github.com/josxha) | | de | German | [@josxha](https://github.com/josxha) |
| en | English | [@HarelM](https://github.com/HarelM) | | en | English | [@HarelM](https://github.com/HarelM) |
| fr | French | [@lhapaipai](https://github.com/lhapaipai) | | fr | French | [@lhapaipai](https://github.com/lhapaipai) |
-216
View File
@@ -1,216 +0,0 @@
{
"<0>Open in OSM</0>. Opens the current view on openstreetmap.org": "<0>OSM-də aç</0>. Cari görünüşü openstreetmap.org saytında açır",
"Achromatopsia filter": "Axromatopsiya süzgəci",
"Active Sources": "Aktiv Mənbələr",
"Add a new source to your style. You can only choose the source type and id at creation time!": "Üslubunuza yeni mənbə əlavə edin. Mənbə növünü və ID-ni yalnız yaradılma zamanı seçə bilərsiniz!",
"Add filter": "Süzgəc əlavə et",
"Add Layer": "Qat Əlavə Et",
"Add New Source": "Yeni Mənbə Əlavə Et",
"Add one of the publicly available sources to your style.": "Üslubunuza ictimai mənbələrdən birini əlavə edin.",
"Add Source": "Mənbə Əlavə Et",
"Add stop": "Dayanacaq əlavə et",
"Add value": "Dəyər əlavə et",
"Add Variable": "Dəyişən Əlavə Et",
"any filter matches": "istənilən süzgəc uyğun gəlirsə",
"API key for Stadia Maps.": "Stadia Maps üçün API açarı.",
"Atmosphere blend": "Atmosfer qarışığı",
"Base": "Baza",
"Bearing": "İstiqamət",
"Cancel": "Ləğv et",
"Center": "Mərkəz",
"Center altitude": "Mərkəzin hündürlüyü",
"Choose Public Source": "İctimai Mənbə Seç",
"Choose the default Maputnik renderer for this style.": "Bu üslub üçün defolt Maputnik renderer-ini seçin.",
"Click to close the editor": "Redaktoru bağlamaq üçün klikləyin",
"Close": "Bağla",
"Close modal": "Modalı bağla",
"Close popup": "Popapı bağla",
"Cluster": "Klaster",
"Code Editor": "Kod Redaktoru",
"Collapse": "Yığ",
"Color accessibility": "Rəng əlçatanlığı",
"Comment...": "Şərh...",
"Comments": "Şərhlər",
"Comments for the current layer. This is non-standard and not in the spec.": "Cari qat üçün şərhlər. Bu, standart deyil və spesifikasiyada yoxdur.",
"Convert property into a elevation function": "Xassəni hündürlük funksiyasına çevir",
"Convert property into a zoom function": "Xassəni yaxınlaşma funksiyasına çevir",
"Convert property to data function": "Xassəni məlumat funksiyasına çevir",
"Convert to expression": "İfadəyə çevir",
"Coord bottom left": "Koordinat aşağı sol",
"Coord bottom right": "Koordinat aşağı sağ",
"Coord top left": "Koordinat yuxarı sol",
"Coord top right": "Koordinat yuxarı sağ",
"CORS policy won't allow fetching resources served over http from https, use a <1>https://</1> domain": "CORS siyasəti https-dən http üzərindən verilən resursların alınmasına icazə vermir, <1>https://</1> domenindən istifadə edin",
"Create HTML": "HTML Yarat",
"Data Sources": "Məlumat Mənbələri",
"Data Sources modal": "Məlumat Mənbələri modalı",
"Data value": "Məlumat dəyəri",
"Debug": "Sazlama",
"Debug modal": "Sazlama modalı",
"Decrease the pitch by 10 degrees.": "Meyli 10 dərəcə azalt.",
"Decrease the rotation by 15 degrees.": "Fırlanmanı 15 dərəcə azalt.",
"Decrease the zoom level by 1.": "Yaxınlaşma səviyyəsini 1 azalt.",
"Decrease the zoom level by 2.": "Yaxınlaşma səviyyəsini 2 azalt.",
"Default": "Defolt",
"Delete": "Sil",
"Delete expression": "İfadəni sil",
"Delete filter block": "Süzgəc blokunu sil",
"Deuteranopia filter": "Deuteranopiya süzgəci",
"Drag and drop a style JSON file here or click to browse": "Üslub JSON faylını buraya sürükləyib buraxın və ya seçmək üçün klikləyin",
"Drag to resize the layer list": "Qat siyahısının ölçüsünü dəyişmək üçün sürükləyin",
"Drag to resize the sidebar": "Yan panelin ölçüsünü dəyişmək üçün sürükləyin",
"Duplicate": "Dublikat et",
"Encoding": "Kodlaşdırma",
"Enter URL...": "URL daxil edin...",
"every filter matches": "bütün süzgəclər uyğun gəlirsə",
"Expand": "Genişlət",
"Export modal": "İxrac modalı",
"Filter": "Süzgəc",
"Focus map": "Xəritəyə fokuslan",
"Fog color": "Duman rəngi",
"Fog ground blend": "Duman-yer qarışığı",
"Font faces": "Şrift faylları",
"Function": "Funksiya",
"Gallery Styles": "Qalereya Üslubları",
"General layout properties": "Ümumi düzülüş xassələri",
"GeoJSON": "GeoJSON",
"GeoJSON (JSON)": "GeoJSON (JSON)",
"GeoJSON (URL)": "GeoJSON (URL)",
"GeoJSON URL": "GeoJSON URL",
"Global State": "Qlobal Vəziyyət",
"Global State Variables": "Qlobal Vəziyyət Dəyişənləri",
"Glyphs URL": "Şriftlər URL-i",
"Help": "Kömək",
"Hide": "Gizlət",
"Horizon color": "Üfüq rəngi",
"Horizon fog blend": "Üfüq-duman qarışığı",
"Icon layout properties": "İkon düzülüş xassələri",
"Icon paint properties": "İkon boyama xassələri",
"If the Map is in focused you can use the following shortcuts": "Xəritə fokusdadırsa aşağıdakı qısayollardan istifadə edə bilərsiniz",
"Image": "Şəkil",
"Image URL": "Şəkil URL-i",
"Increase the pitch by 10 degrees.": "Meyli 10 dərəcə artır.",
"Increase the rotation by 15 degrees.": "Fırlanmanı 15 dərəcə artır.",
"Increase the zoom level by 1.": "Yaxınlaşma səviyyəsini 1 artır.",
"Increase the zoom level by 2.": "Yaxınlaşma səviyyəsini 2 artır.",
"Input a data property to base styles off of.": "Üslubların əsaslanacağı məlumat xassəsini daxil edin.",
"Input value": "Giriş dəyəri",
"Inspect": "Yoxla",
"JSON Editor": "JSON Redaktoru",
"Key": "Açar",
"Layer": "Qat",
"Layer editor": "Qat redaktoru",
"Layer ID already exists": "Qat ID artıq mövcuddur",
"Layers": "Qatlar",
"Layers list": "Qatlar siyahısı",
"Layout properties": "Düzülüş xassələri",
"Learn More": "Ətraflı Öyrən",
"Light anchor": "İşıq lövbəri",
"Light color": "İşıq rəngi",
"Light intensity": "İşıq intensivliyi",
"Light position": "İşıq mövqeyi",
"Links": "Keçidlər",
"Load from a URL. Note that the URL must have <1>CORS enabled</1>.": "URL-dən yüklə. Qeyd edin ki, URL-də <1>CORS aktiv olmalıdır</1>.",
"Load from URL": "URL-dən yüklə",
"Loading": "Yüklənir",
"Loading style": "Üslub yüklənir",
"LocationIQ Access Token": "LocationIQ Giriş Tokeni",
"Map": "Xəritə",
"Map view": "Xəritə görünüşü",
"MapTiler Access Token": "MapTiler Giriş Tokeni",
"Maputnik on GitHub": "GitHub-da Maputnik",
"Max Zoom": "Maks. Yaxınlaşma",
"Min Zoom": "Min. Yaxınlaşma",
"Move layer down": "Qatı aşağı köçür",
"Move layer up": "Qatı yuxarı köçür",
"Must provide protocol: <1>http://</1> or <3>https://</3>": "Protokol göstərilməlidir: <1>http://</1> və ya <3>https://</3>",
"Must provide protocol: <1>https://</1>": "Protokol göstərilməlidir: <1>https://</1>",
"Name": "Ad",
"Nested filters are not supported.": "İç-içə süzgəclər dəstəklənmir.",
"no filter matches": "heç bir süzgəc uyğun gəlmirsə",
"No global state variables defined. Add variables to create reusable values in your style.": "Heç bir qlobal vəziyyət dəyişəni təyin edilməyib. Üslubunuzda təkrar istifadə oluna bilən dəyərlər yaratmaq üçün dəyişən əlavə edin.",
"Open": "Aç",
"Open a local JSON style from your computer.": "Kompüterinizdən yerli JSON üslubunu açın.",
"Open local Style": "Yerli Üslubu Aç",
"Open modal": "Modalı aç",
"Open one of the publicly available styles to start from.": "Başlamaq üçün ictimai üslublardan birini açın.",
"Open Style": "Üslubu Aç",
"OpenLayers (experimental)": "OpenLayers (eksperimental)",
"Options": "Seçimlər",
"Output value": "Çıxış dəyəri",
"Owner": "Sahib",
"Owner ID of the style. Used by Mapbox or future style APIs.": "Üslubun sahib ID-si. Mapbox və ya gələcək üslub API-ləri tərəfindən istifadə olunur.",
"Paint properties": "Boyama xassələri",
"Pan down by 100 pixels.": "100 piksel aşağı sürüşdür.",
"Pan left by 100 pixels.": "100 piksel sola sürüşdür.",
"Pan right by 100 pixels.": "100 piksel sağa sürüşdür.",
"Pan up by 100 pixels.": "100 piksel yuxarı sürüşdür.",
"Pitch": "Meyl",
"PMTiles URL": "PMTiles URL",
"Press <1>ESC</1> to lose focus of any active elements, then press one of:": "İstənilən aktiv elementin fokusunu itirmək üçün <1>ESC</1> düyməsini basın, sonra bunlardan birini basın:",
"Projection": "Proyeksiya",
"Protanopia filter": "Protanopiya süzgəci",
"Public access token for LocationIQ services.": "LocationIQ xidmətləri üçün ictimai giriş tokeni.",
"Public access token for MapTiler Cloud.": "MapTiler Cloud üçün ictimai giriş tokeni.",
"Public access token for Thunderforest services.": "Thunderforest xidmətləri üçün ictimai giriş tokeni.",
"Raster (Tile URLs)": "Rastr (Kafel URL-ləri)",
"Raster (TileJSON URL)": "Rastr (TileJSON URL)",
"Raster DEM (TileJSON URL)": "Rastr DEM (TileJSON URL)",
"Raster DEM (XYZ URLs)": "Rastr DEM (XYZ URL-ləri)",
"Remove '{{sourceId}}' source": "'{{sourceId}}' mənbəsini sil",
"Remove array item": "Massiv elementini sil",
"Remove variable": "Dəyişəni sil",
"Remove zoom level from stop": "Dayanacaqdan yaxınlaşma səviyyəsini sil",
"Revert from expression": "İfadədən geri qaytar",
"Roll": "Fırlanma",
"Save": "Yadda saxla",
"Save as": "Fərqli yadda saxla",
"Save Style": "Üslubu Yadda Saxla",
"Save the JSON style to your computer.": "JSON üslubunu kompüterinizə yadda saxlayın.",
"Scheme Type": "Sxem Növü",
"Search": "Axtar",
"Select a type of data scale (default is 'categorical').": "Məlumat şkalasının növünü seçin (defolt 'categorical'dır).",
"Shortcuts": "Qısayollar",
"Shortcuts menu": "Qısayollar menyusu",
"Show": "Göstər",
"Sky color": "Səma rəngi",
"Sky horizon blend": "Səma-üfüq qarışığı",
"Source": "Mənbə",
"Source ID": "Mənbə ID",
"Source Layer": "Mənbə Qatı",
"Source Type": "Mənbə Növü",
"Sources": "Mənbələr",
"Sprite URL": "Sprite URL-i",
"Stadia Maps API Key": "Stadia Maps API Açarı",
"Stops": "Dayanacaqlar",
"Style Renderer": "Üslub Renderer-i",
"Style Settings": "Üslub Parametrləri",
"Style Settings modal": "Üslub Parametrləri modalı",
"Style URL": "Üslub URL-i",
"Switch to filter editor.": "Süzgəc redaktoruna keç.",
"switch to layer": "qata keç",
"Terrain exaggeration": "Relyef şişirdilməsi",
"Terrain source": "Relyef mənbəyi",
"Text layout properties": "Mətn düzülüş xassələri",
"Text paint properties": "Mətn boyama xassələri",
"Thunderforest Access Token": "Thunderforest Giriş Tokeni",
"Tile Size": "Kafel Ölçüsü",
"Tile URL": "Kafel URL-i",
"TileJSON URL": "TileJSON URL",
"Toggle inspect": "Yoxlamanı aç/bağla",
"Transition delay": "Keçid gecikməsi",
"Transition duration": "Keçid müddəti",
"Tritanopia filter": "Tritanopiya süzgəci",
"Type": "Növ",
"Unique ID that identifies the source and is used in the layer to reference the source.": "Mənbəni müəyyən edən və qatda mənbəyə istinad üçün istifadə olunan unikal ID.",
"Upgrade to expression": "İfadəyə yüksəlt",
"Value": "Dəyər",
"Vector (PMTiles)": "Vektor (PMTiles)",
"Vector (Tile URLs)": "Vektor (Kafel URL-ləri)",
"Vector (TileJSON URL)": "Vektor (TileJSON URL)",
"Video": "Video",
"Video URL": "Video URL-i",
"View": "Görünüş",
"You've entered an old style filter.": "Köhnə üslub süzgəci daxil etmisiniz.",
"Zoom": "Yaxınlaşma"
}
+3 -13
View File
@@ -13,12 +13,10 @@
"Add Variable": "Variable hinzufügen", "Add Variable": "Variable hinzufügen",
"any filter matches": "irgendein Filter passt", "any filter matches": "irgendein Filter passt",
"API key for Stadia Maps.": "API-Schlüssel für Stadia Maps.", "API key for Stadia Maps.": "API-Schlüssel für Stadia Maps.",
"Atmosphere blend": "Atmosphärenüberblendung",
"Base": "Basis", "Base": "Basis",
"Bearing": "Ausrichtung", "Bearing": "Ausrichtung",
"Cancel": "Abbrechen", "Cancel": "Abbrechen",
"Center": "Mittelpunkt", "Center": "Mittelpunkt",
"Center altitude": "Höhe des Mittelpunkts",
"Choose Public Source": "Öffentliche Quelle auswählen", "Choose Public Source": "Öffentliche Quelle auswählen",
"Choose the default Maputnik renderer for this style.": "Wähle den Standard-Renderer für diesen Stil aus.", "Choose the default Maputnik renderer for this style.": "Wähle den Standard-Renderer für diesen Stil aus.",
"Click to close the editor": "Klicken Sie hier, um den Editor zu schließen", "Click to close the editor": "Klicken Sie hier, um den Editor zu schließen",
@@ -56,7 +54,6 @@
"Delete expression": "Ausdruck löschen", "Delete expression": "Ausdruck löschen",
"Delete filter block": "Filterblock löschen", "Delete filter block": "Filterblock löschen",
"Deuteranopia filter": "Deuteranopie-Filter", "Deuteranopia filter": "Deuteranopie-Filter",
"Drag and drop a style JSON file here or click to browse": "Ziehen Sie eine Style-JSON-Datei hierher oder klicken Sie, um zu durchsuchen",
"Drag to resize the layer list": "Ziehen, um die Ebenenliste zu skalieren", "Drag to resize the layer list": "Ziehen, um die Ebenenliste zu skalieren",
"Drag to resize the sidebar": "Ziehen, um die Seitenleiste zu skalieren", "Drag to resize the sidebar": "Ziehen, um die Seitenleiste zu skalieren",
"Duplicate": "Duplizieren", "Duplicate": "Duplizieren",
@@ -67,9 +64,6 @@
"Export modal": "Modale Fenster exportieren", "Export modal": "Modale Fenster exportieren",
"Filter": "Filter", "Filter": "Filter",
"Focus map": "Karte fokussieren", "Focus map": "Karte fokussieren",
"Fog color": "Nebelfarbe",
"Fog ground blend": "Nebel-Boden-Überblendung",
"Font faces": "Schriftdateien",
"Function": "Funktion", "Function": "Funktion",
"Gallery Styles": "Galerie-Stile", "Gallery Styles": "Galerie-Stile",
"General layout properties": "Allgemeine Layouteigenschaften", "General layout properties": "Allgemeine Layouteigenschaften",
@@ -82,8 +76,6 @@
"Glyphs URL": "Glyphen-URL", "Glyphs URL": "Glyphen-URL",
"Help": "Hilfe", "Help": "Hilfe",
"Hide": "Verstecken", "Hide": "Verstecken",
"Horizon color": "Horizontfarbe",
"Horizon fog blend": "Horizont-Nebel-Überblendung",
"Icon layout properties": "Icon-Layouteigenschaften", "Icon layout properties": "Icon-Layouteigenschaften",
"Icon paint properties": "Icon-Darstellungseigenschaften", "Icon paint properties": "Icon-Darstellungseigenschaften",
"If the Map is in focused you can use the following shortcuts": "Wenn die Karte fokussiert ist, kannst du die folgenden Shortcuts benutzen", "If the Map is in focused you can use the following shortcuts": "Wenn die Karte fokussiert ist, kannst du die folgenden Shortcuts benutzen",
@@ -131,11 +123,11 @@
"No global state variables defined. Add variables to create reusable values in your style.": "Keine globalen Zustandsvariablen definiert. Füge Variablen hinzu, um wiederverwendbare Werte in deinem Stil zu erstellen.", "No global state variables defined. Add variables to create reusable values in your style.": "Keine globalen Zustandsvariablen definiert. Füge Variablen hinzu, um wiederverwendbare Werte in deinem Stil zu erstellen.",
"Open": "Öffnen", "Open": "Öffnen",
"Open a local JSON style from your computer.": "Öffne einen lokalen JSON Stil von deinem Computer.", "Open a local JSON style from your computer.": "Öffne einen lokalen JSON Stil von deinem Computer.",
"Open Layers (experimental)": "Ebenen öffnen (experimentell)",
"Open local Style": "Lokalen Stil öffnen", "Open local Style": "Lokalen Stil öffnen",
"Open modal": "Modale Fenster öffnen", "Open modal": "Modale Fenster öffnen",
"Open one of the publicly available styles to start from.": "Öffne einen der öffentlich verfügbaren Stile, um zu starten.", "Open one of the publicly available styles to start from.": "Öffne einen der öffentlich verfügbaren Stile, um zu starten.",
"Open Style": "Stil öffnen", "Open Style": "Stil öffnen",
"OpenLayers (experimental)": "OpenLayers (experimentell)",
"Options": "Optionen", "Options": "Optionen",
"Output value": "Ausgabewert", "Output value": "Ausgabewert",
"Owner": "Besitzer", "Owner": "Besitzer",
@@ -162,7 +154,6 @@
"Remove variable": "Variable entfernen", "Remove variable": "Variable entfernen",
"Remove zoom level from stop": "Zoom-Stufe vom Stopp entfernen", "Remove zoom level from stop": "Zoom-Stufe vom Stopp entfernen",
"Revert from expression": "Vom Ausdruck zurücksetzen", "Revert from expression": "Vom Ausdruck zurücksetzen",
"Roll": "Rollwinkel",
"Save": "Speichern", "Save": "Speichern",
"Save as": "Speichern unter", "Save as": "Speichern unter",
"Save Style": "Stil Speichern", "Save Style": "Stil Speichern",
@@ -173,8 +164,6 @@
"Shortcuts": "Shortcuts", "Shortcuts": "Shortcuts",
"Shortcuts menu": "Shortcuts-Menü", "Shortcuts menu": "Shortcuts-Menü",
"Show": "Anzeigen", "Show": "Anzeigen",
"Sky color": "Himmelsfarbe",
"Sky horizon blend": "Himmel-Horizont-Überblendung",
"Source": "Quelle", "Source": "Quelle",
"Source ID": "Quellen-ID", "Source ID": "Quellen-ID",
"Source Layer": "Quellenebene", "Source Layer": "Quellenebene",
@@ -212,5 +201,6 @@
"Video URL": "Video-URL", "Video URL": "Video-URL",
"View": "Ansicht", "View": "Ansicht",
"You've entered an old style filter.": "Du hast einen alten Filter-Stil eingegeben.", "You've entered an old style filter.": "Du hast einen alten Filter-Stil eingegeben.",
"Zoom": "Zoom" "Zoom": "Zoom",
"Drag and drop a style JSON file here or click to browse": "Ziehen Sie eine Style-JSON-Datei hierher oder klicken Sie, um zu durchsuchen"
} }
+3 -13
View File
@@ -13,12 +13,10 @@
"Add Variable": "Ajouter une variable", "Add Variable": "Ajouter une variable",
"any filter matches": "l'un des filtres correspond", "any filter matches": "l'un des filtres correspond",
"API key for Stadia Maps.": "Clé d'API pour Stadia Maps.", "API key for Stadia Maps.": "Clé d'API pour Stadia Maps.",
"Atmosphere blend": "Fondu de l'atmosphère",
"Base": "Base", "Base": "Base",
"Bearing": "Orientation", "Bearing": "Orientation",
"Cancel": "Annuler", "Cancel": "Annuler",
"Center": "Centre", "Center": "Centre",
"Center altitude": "Altitude du centre",
"Choose Public Source": "Choisir une source publique", "Choose Public Source": "Choisir une source publique",
"Choose the default Maputnik renderer for this style.": "Choisissez le moteur de rendu Maputnik par défaut pour ce style.", "Choose the default Maputnik renderer for this style.": "Choisissez le moteur de rendu Maputnik par défaut pour ce style.",
"Click to close the editor": "Cliquez pour fermer l'éditeur", "Click to close the editor": "Cliquez pour fermer l'éditeur",
@@ -56,7 +54,6 @@
"Delete expression": "Supprimer l'expression", "Delete expression": "Supprimer l'expression",
"Delete filter block": "Supprimer le bloc de filtre", "Delete filter block": "Supprimer le bloc de filtre",
"Deuteranopia filter": "Filtre Deutéranopie", "Deuteranopia filter": "Filtre Deutéranopie",
"Drag and drop a style JSON file here or click to browse": "Faites glisser un fichier JSON de style ici ou cliquez pour parcourir",
"Drag to resize the layer list": "Glisser pour redimensionner la liste des calques", "Drag to resize the layer list": "Glisser pour redimensionner la liste des calques",
"Drag to resize the sidebar": "Glisser pour redimensionner la barre latérale", "Drag to resize the sidebar": "Glisser pour redimensionner la barre latérale",
"Duplicate": "Dupliquer", "Duplicate": "Dupliquer",
@@ -67,9 +64,6 @@
"Export modal": "Exporter (modale)", "Export modal": "Exporter (modale)",
"Filter": "Filtre", "Filter": "Filtre",
"Focus map": "Focus sur la carte", "Focus map": "Focus sur la carte",
"Fog color": "Couleur du brouillard",
"Fog ground blend": "Fondu brouillard-sol",
"Font faces": "Fichiers de police",
"Function": "Fonction", "Function": "Fonction",
"Gallery Styles": "Styles de la galerie", "Gallery Styles": "Styles de la galerie",
"General layout properties": "Propriétés générales de mise en page", "General layout properties": "Propriétés générales de mise en page",
@@ -82,8 +76,6 @@
"Glyphs URL": "URL des glyphes", "Glyphs URL": "URL des glyphes",
"Help": "Aide", "Help": "Aide",
"Hide": "Cacher", "Hide": "Cacher",
"Horizon color": "Couleur de l'horizon",
"Horizon fog blend": "Fondu horizon-brouillard",
"Icon layout properties": "Propriétés de mise en page de l'icône", "Icon layout properties": "Propriétés de mise en page de l'icône",
"Icon paint properties": "Propriétés de peinture de l'icône", "Icon paint properties": "Propriétés de peinture de l'icône",
"If the Map is in focused you can use the following shortcuts": "Si la carte a le focus, vous pouvez utiliser les raccourcis suivants", "If the Map is in focused you can use the following shortcuts": "Si la carte a le focus, vous pouvez utiliser les raccourcis suivants",
@@ -131,11 +123,11 @@
"No global state variables defined. Add variables to create reusable values in your style.": "Aucune variable d'état global définie. Ajoutez des variables pour créer des valeurs réutilisables dans votre style.", "No global state variables defined. Add variables to create reusable values in your style.": "Aucune variable d'état global définie. Ajoutez des variables pour créer des valeurs réutilisables dans votre style.",
"Open": "Ouvrir", "Open": "Ouvrir",
"Open a local JSON style from your computer.": "Ouvrir un style JSON local depuis votre ordinateur.", "Open a local JSON style from your computer.": "Ouvrir un style JSON local depuis votre ordinateur.",
"Open Layers (experimental)": "Open Layers (expérimental)",
"Open local Style": "Ouvrir un style local", "Open local Style": "Ouvrir un style local",
"Open modal": "Ouvrir (modale)", "Open modal": "Ouvrir (modale)",
"Open one of the publicly available styles to start from.": "Ouvrez l'un des styles publics disponibles pour commencer.", "Open one of the publicly available styles to start from.": "Ouvrez l'un des styles publics disponibles pour commencer.",
"Open Style": "Ouvrir le style", "Open Style": "Ouvrir le style",
"OpenLayers (experimental)": "OpenLayers (expérimental)",
"Options": "Options", "Options": "Options",
"Output value": "Valeur de sortie", "Output value": "Valeur de sortie",
"Owner": "Propriétaire", "Owner": "Propriétaire",
@@ -162,7 +154,6 @@
"Remove variable": "Supprimer la variable", "Remove variable": "Supprimer la variable",
"Remove zoom level from stop": "Supprimer le niveau de zoom de l'arrêt", "Remove zoom level from stop": "Supprimer le niveau de zoom de l'arrêt",
"Revert from expression": "Annuler l'expression", "Revert from expression": "Annuler l'expression",
"Roll": "Roulis",
"Save": "Enregistrer", "Save": "Enregistrer",
"Save as": "Enregistrer sous", "Save as": "Enregistrer sous",
"Save Style": "Enregistrer le style", "Save Style": "Enregistrer le style",
@@ -173,8 +164,6 @@
"Shortcuts": "Raccourcis", "Shortcuts": "Raccourcis",
"Shortcuts menu": "Menu des raccourcis", "Shortcuts menu": "Menu des raccourcis",
"Show": "Afficher", "Show": "Afficher",
"Sky color": "Couleur du ciel",
"Sky horizon blend": "Fondu ciel-horizon",
"Source": "Source", "Source": "Source",
"Source ID": "ID de la source", "Source ID": "ID de la source",
"Source Layer": "Calque Source", "Source Layer": "Calque Source",
@@ -212,5 +201,6 @@
"Video URL": "URL de la vidéo", "Video URL": "URL de la vidéo",
"View": "Vue", "View": "Vue",
"You've entered an old style filter.": "Vous avez entré un ancien style de filtre.", "You've entered an old style filter.": "Vous avez entré un ancien style de filtre.",
"Zoom": "Zoom" "Zoom": "Zoom",
"Drag and drop a style JSON file here or click to browse": "Faites glisser un fichier JSON de style ici ou cliquez pour parcourir"
} }
+3 -13
View File
@@ -13,12 +13,10 @@
"Add Variable": "הוסף משתנה", "Add Variable": "הוסף משתנה",
"any filter matches": "אחד הסינוים מתאימים", "any filter matches": "אחד הסינוים מתאימים",
"API key for Stadia Maps.": "API key for Stadia Maps", "API key for Stadia Maps.": "API key for Stadia Maps",
"Atmosphere blend": "מיזוג אטמוספרה",
"Base": "בסיס", "Base": "בסיס",
"Bearing": "כיוון", "Bearing": "כיוון",
"Cancel": "ביטול", "Cancel": "ביטול",
"Center": "מרכז", "Center": "מרכז",
"Center altitude": "גובה המרכז",
"Choose Public Source": "בחירת מקור ציבורי", "Choose Public Source": "בחירת מקור ציבורי",
"Choose the default Maputnik renderer for this style.": "בחירת צייר ברירת המחדל של מפוטניק עבור הסטייל הזה", "Choose the default Maputnik renderer for this style.": "בחירת צייר ברירת המחדל של מפוטניק עבור הסטייל הזה",
"Click to close the editor": "לחץ לסגירת העורך", "Click to close the editor": "לחץ לסגירת העורך",
@@ -56,7 +54,6 @@
"Delete expression": "מחיקת ביטוי", "Delete expression": "מחיקת ביטוי",
"Delete filter block": "מחיקת גוש מסנן", "Delete filter block": "מחיקת גוש מסנן",
"Deuteranopia filter": "Deuteranopia filter", "Deuteranopia filter": "Deuteranopia filter",
"Drag and drop a style JSON file here or click to browse": "גרור ושחרר כאן קובץ JSON של סגנון או לחץ כדי לעיין",
"Drag to resize the layer list": "יש לגרור כדי לשנות את גודל רשימת השכבות", "Drag to resize the layer list": "יש לגרור כדי לשנות את גודל רשימת השכבות",
"Drag to resize the sidebar": "יש לגרור כדי לשנות את גודל סרגל הצד", "Drag to resize the sidebar": "יש לגרור כדי לשנות את גודל סרגל הצד",
"Duplicate": "שכפול", "Duplicate": "שכפול",
@@ -67,9 +64,6 @@
"Export modal": "חלונית ייצוא", "Export modal": "חלונית ייצוא",
"Filter": "סינון", "Filter": "סינון",
"Focus map": "פיקוס המפה", "Focus map": "פיקוס המפה",
"Fog color": "צבע ערפל",
"Fog ground blend": "מיזוג ערפל עם הקרקע",
"Font faces": "קבצי גופנים",
"Function": "פונקציה", "Function": "פונקציה",
"Gallery Styles": "גלריית סטיילים", "Gallery Styles": "גלריית סטיילים",
"General layout properties": "תכונות פריסה כלליות", "General layout properties": "תכונות פריסה כלליות",
@@ -82,8 +76,6 @@
"Glyphs URL": "כתובת סמלילים", "Glyphs URL": "כתובת סמלילים",
"Help": "עזרה", "Help": "עזרה",
"Hide": "הסתרה", "Hide": "הסתרה",
"Horizon color": "צבע האופק",
"Horizon fog blend": "מיזוג ערפל באופק",
"Icon layout properties": "תכונות פריסה של סמליל", "Icon layout properties": "תכונות פריסה של סמליל",
"Icon paint properties": "תכונות ציור של סמליל", "Icon paint properties": "תכונות ציור של סמליל",
"If the Map is in focused you can use the following shortcuts": "אם המפה נמצאת בפוקוס תוכלו להשתמש בקיצורי הדרך", "If the Map is in focused you can use the following shortcuts": "אם המפה נמצאת בפוקוס תוכלו להשתמש בקיצורי הדרך",
@@ -131,11 +123,11 @@
"No global state variables defined. Add variables to create reusable values in your style.": "לא הוגדרו משתני מצב גלובלי. הוסף משתנים כדי ליצור ערכים שניתן לעשות בהם שימוש חוזר בסטייל שלך.", "No global state variables defined. Add variables to create reusable values in your style.": "לא הוגדרו משתני מצב גלובלי. הוסף משתנים כדי ליצור ערכים שניתן לעשות בהם שימוש חוזר בסטייל שלך.",
"Open": "פתיחה", "Open": "פתיחה",
"Open a local JSON style from your computer.": "פתיחת סטייל JSON מקומי מהמחשב שלך.", "Open a local JSON style from your computer.": "פתיחת סטייל JSON מקומי מהמחשב שלך.",
"Open Layers (experimental)": "Open Layers (experimental)",
"Open local Style": "פתיחת סטייל מקומי", "Open local Style": "פתיחת סטייל מקומי",
"Open modal": "פתיחת חלונית", "Open modal": "פתיחת חלונית",
"Open one of the publicly available styles to start from.": "פתיחת אחד הסטייליםפ הציבוריים על מנת להתחיל מהם.", "Open one of the publicly available styles to start from.": "פתיחת אחד הסטייליםפ הציבוריים על מנת להתחיל מהם.",
"Open Style": "פתיחת סטייל", "Open Style": "פתיחת סטייל",
"OpenLayers (experimental)": "OpenLayers (experimental)",
"Options": "אפשרויות", "Options": "אפשרויות",
"Output value": "ערך החזרה", "Output value": "ערך החזרה",
"Owner": "שייך ל", "Owner": "שייך ל",
@@ -162,7 +154,6 @@
"Remove variable": "הסר משתנה", "Remove variable": "הסר משתנה",
"Remove zoom level from stop": "הסרת רמת זום מעצירה", "Remove zoom level from stop": "הסרת רמת זום מעצירה",
"Revert from expression": "החזרה מביטוי", "Revert from expression": "החזרה מביטוי",
"Roll": "גלגול",
"Save": "שמור", "Save": "שמור",
"Save as": "שמירה בשם", "Save as": "שמירה בשם",
"Save Style": "שמירת הסטייל", "Save Style": "שמירת הסטייל",
@@ -173,8 +164,6 @@
"Shortcuts": "קיצורי דרך", "Shortcuts": "קיצורי דרך",
"Shortcuts menu": "תפריט קיצורי דרך", "Shortcuts menu": "תפריט קיצורי דרך",
"Show": "הצגה", "Show": "הצגה",
"Sky color": "צבע השמיים",
"Sky horizon blend": "מיזוג שמיים ואופק",
"Source": "מקור", "Source": "מקור",
"Source ID": "מזהה מקור", "Source ID": "מזהה מקור",
"Source Layer": "שכבת מקור", "Source Layer": "שכבת מקור",
@@ -212,5 +201,6 @@
"Video URL": "כתובת וידאו", "Video URL": "כתובת וידאו",
"View": "תצוגה", "View": "תצוגה",
"You've entered an old style filter.": "הכנסתם סינון מסוג ישן,", "You've entered an old style filter.": "הכנסתם סינון מסוג ישן,",
"Zoom": "זום" "Zoom": "זום",
"Drag and drop a style JSON file here or click to browse": "גרור ושחרר כאן קובץ JSON של סגנון או לחץ כדי לעיין"
} }
+3 -13
View File
@@ -13,12 +13,10 @@
"Add Variable": "Aggiungi variabile", "Add Variable": "Aggiungi variabile",
"any filter matches": "qualsiasi filtro corrisponde", "any filter matches": "qualsiasi filtro corrisponde",
"API key for Stadia Maps.": "Chiave API per Stadia Maps.", "API key for Stadia Maps.": "Chiave API per Stadia Maps.",
"Atmosphere blend": "Sfumatura dell'atmosfera",
"Base": "Base", "Base": "Base",
"Bearing": "Direzione", "Bearing": "Direzione",
"Cancel": "Annulla", "Cancel": "Annulla",
"Center": "Centro", "Center": "Centro",
"Center altitude": "Altitudine del centro",
"Choose Public Source": "Scegli una sorgente pubblica", "Choose Public Source": "Scegli una sorgente pubblica",
"Choose the default Maputnik renderer for this style.": "Scegli il renderer predefinito di Maputnik per questo stile.", "Choose the default Maputnik renderer for this style.": "Scegli il renderer predefinito di Maputnik per questo stile.",
"Click to close the editor": "Clicca per chiudere l'editor", "Click to close the editor": "Clicca per chiudere l'editor",
@@ -56,7 +54,6 @@
"Delete expression": "Elimina espressione", "Delete expression": "Elimina espressione",
"Delete filter block": "Elimina blocco filtro", "Delete filter block": "Elimina blocco filtro",
"Deuteranopia filter": "Filtro deuteranopia", "Deuteranopia filter": "Filtro deuteranopia",
"Drag and drop a style JSON file here or click to browse": "Trascina e rilascia qui un file JSON dello stile o fai clic per sfogliare",
"Drag to resize the layer list": "Trascina per ridimensionare l'elenco dei livelli", "Drag to resize the layer list": "Trascina per ridimensionare l'elenco dei livelli",
"Drag to resize the sidebar": "Trascina per ridimensionare la barra laterale", "Drag to resize the sidebar": "Trascina per ridimensionare la barra laterale",
"Duplicate": "Duplica", "Duplicate": "Duplica",
@@ -67,9 +64,6 @@
"Export modal": "Esporta finestra modale", "Export modal": "Esporta finestra modale",
"Filter": "Filtro", "Filter": "Filtro",
"Focus map": "Metti a fuoco la mappa", "Focus map": "Metti a fuoco la mappa",
"Fog color": "Colore della nebbia",
"Fog ground blend": "Sfumatura nebbia-suolo",
"Font faces": "File dei font",
"Function": "Funzione", "Function": "Funzione",
"Gallery Styles": "Galleria degli stili", "Gallery Styles": "Galleria degli stili",
"General layout properties": "Proprietà generali del layout", "General layout properties": "Proprietà generali del layout",
@@ -82,8 +76,6 @@
"Glyphs URL": "URL Glyphs", "Glyphs URL": "URL Glyphs",
"Help": "Aiuto", "Help": "Aiuto",
"Hide": "Nascondi", "Hide": "Nascondi",
"Horizon color": "Colore dell'orizzonte",
"Horizon fog blend": "Sfumatura orizzonte-nebbia",
"Icon layout properties": "Proprietà di layout dell'icona", "Icon layout properties": "Proprietà di layout dell'icona",
"Icon paint properties": "Proprietà di pittura dell'icona", "Icon paint properties": "Proprietà di pittura dell'icona",
"If the Map is in focused you can use the following shortcuts": "Se la mappa è attiva, puoi utilizzare le seguenti scorciatoie:", "If the Map is in focused you can use the following shortcuts": "Se la mappa è attiva, puoi utilizzare le seguenti scorciatoie:",
@@ -131,11 +123,11 @@
"No global state variables defined. Add variables to create reusable values in your style.": "Nessuna variabile di stato globale definita. Aggiungi variabili per creare valori riutilizzabili nel tuo stile.", "No global state variables defined. Add variables to create reusable values in your style.": "Nessuna variabile di stato globale definita. Aggiungi variabili per creare valori riutilizzabili nel tuo stile.",
"Open": "Apri", "Open": "Apri",
"Open a local JSON style from your computer.": "Apri uno stile JSON dal tuo computer.", "Open a local JSON style from your computer.": "Apri uno stile JSON dal tuo computer.",
"Open Layers (experimental)": "Apri livelli (sperimentale)",
"Open local Style": "Apri stile locale", "Open local Style": "Apri stile locale",
"Open modal": "Apri finestra modale", "Open modal": "Apri finestra modale",
"Open one of the publicly available styles to start from.": "Apro uno degli stili pubblici a partire da.", "Open one of the publicly available styles to start from.": "Apro uno degli stili pubblici a partire da.",
"Open Style": "Apri stile", "Open Style": "Apri stile",
"OpenLayers (experimental)": "OpenLayers (sperimentale)",
"Options": "Opzioni", "Options": "Opzioni",
"Output value": "Valore di output", "Output value": "Valore di output",
"Owner": "Proprietario", "Owner": "Proprietario",
@@ -162,7 +154,6 @@
"Remove variable": "Rimuovi variabile", "Remove variable": "Rimuovi variabile",
"Remove zoom level from stop": "Rimuovi il livello di zoom dalla fermata", "Remove zoom level from stop": "Rimuovi il livello di zoom dalla fermata",
"Revert from expression": "Ripristina dall'espressione", "Revert from expression": "Ripristina dall'espressione",
"Roll": "Rollio",
"Save": "Salva", "Save": "Salva",
"Save as": "Salva con nome", "Save as": "Salva con nome",
"Save Style": "Opzioni stile", "Save Style": "Opzioni stile",
@@ -173,8 +164,6 @@
"Shortcuts": "Scorciatoie", "Shortcuts": "Scorciatoie",
"Shortcuts menu": "Scorciatoie del menu", "Shortcuts menu": "Scorciatoie del menu",
"Show": "Mostra", "Show": "Mostra",
"Sky color": "Colore del cielo",
"Sky horizon blend": "Sfumatura cielo-orizzonte",
"Source": "Sorgente", "Source": "Sorgente",
"Source ID": "ID sorgente", "Source ID": "ID sorgente",
"Source Layer": "Livello sorgente", "Source Layer": "Livello sorgente",
@@ -212,5 +201,6 @@
"Video URL": "Indirizzo video", "Video URL": "Indirizzo video",
"View": "Vista", "View": "Vista",
"You've entered an old style filter.": "Hai inserito uno stile filtro obsoleto.", "You've entered an old style filter.": "Hai inserito uno stile filtro obsoleto.",
"Zoom": "Zoom" "Zoom": "Zoom",
"Drag and drop a style JSON file here or click to browse": "Trascina e rilascia qui un file JSON dello stile o fai clic per sfogliare"
} }
+3 -13
View File
@@ -13,12 +13,10 @@
"Add Variable": "変数を追加", "Add Variable": "変数を追加",
"any filter matches": "いずれかのフィルタが一致", "any filter matches": "いずれかのフィルタが一致",
"API key for Stadia Maps.": "Stadia Maps の API キー", "API key for Stadia Maps.": "Stadia Maps の API キー",
"Atmosphere blend": "大気のブレンド",
"Base": "ベース", "Base": "ベース",
"Bearing": "方位", "Bearing": "方位",
"Cancel": "キャンセル", "Cancel": "キャンセル",
"Center": "中央", "Center": "中央",
"Center altitude": "中央の高度",
"Choose Public Source": "公開ソースから選択", "Choose Public Source": "公開ソースから選択",
"Choose the default Maputnik renderer for this style.": "このスタイルのデフォルトの Maputnik レンダラを選択してください", "Choose the default Maputnik renderer for this style.": "このスタイルのデフォルトの Maputnik レンダラを選択してください",
"Click to close the editor": "エディタを閉じるにはクリックしてください", "Click to close the editor": "エディタを閉じるにはクリックしてください",
@@ -56,7 +54,6 @@
"Delete expression": "式を削除", "Delete expression": "式を削除",
"Delete filter block": "フィルタブロックを削除", "Delete filter block": "フィルタブロックを削除",
"Deuteranopia filter": "緑色盲フィルタ", "Deuteranopia filter": "緑色盲フィルタ",
"Drag and drop a style JSON file here or click to browse": "ここにスタイルのJSONファイルをドラッグ&ドロップするか、クリックして参照してください",
"Drag to resize the layer list": "ドラッグしてレイヤーリストのサイズを変更", "Drag to resize the layer list": "ドラッグしてレイヤーリストのサイズを変更",
"Drag to resize the sidebar": "ドラッグしてサイドバーのサイズを変更", "Drag to resize the sidebar": "ドラッグしてサイドバーのサイズを変更",
"Duplicate": "複製", "Duplicate": "複製",
@@ -67,9 +64,6 @@
"Export modal": "書き出しのモーダル", "Export modal": "書き出しのモーダル",
"Filter": "フィルタ", "Filter": "フィルタ",
"Focus map": "地図にフォーカス", "Focus map": "地図にフォーカス",
"Fog color": "霧の色",
"Fog ground blend": "霧と地面のブレンド",
"Font faces": "フォントファイル",
"Function": "関数", "Function": "関数",
"Gallery Styles": "ギャラリースタイル", "Gallery Styles": "ギャラリースタイル",
"General layout properties": "一般レイアウトプロパティ", "General layout properties": "一般レイアウトプロパティ",
@@ -82,8 +76,6 @@
"Glyphs URL": "フォントグリフURL", "Glyphs URL": "フォントグリフURL",
"Help": "ヘルプ", "Help": "ヘルプ",
"Hide": "非表示", "Hide": "非表示",
"Horizon color": "地平線の色",
"Horizon fog blend": "地平線と霧のブレンド",
"Icon layout properties": "アイコンレイアウトプロパティ", "Icon layout properties": "アイコンレイアウトプロパティ",
"Icon paint properties": "アイコンペイントプロパティ", "Icon paint properties": "アイコンペイントプロパティ",
"If the Map is in focused you can use the following shortcuts": "地図がフォーカスされている場合、以下のショートカットを使用できます", "If the Map is in focused you can use the following shortcuts": "地図がフォーカスされている場合、以下のショートカットを使用できます",
@@ -131,11 +123,11 @@
"No global state variables defined. Add variables to create reusable values in your style.": "グローバルステート変数が定義されていません。スタイルで再利用可能な値を作成するには、変数を追加してください。", "No global state variables defined. Add variables to create reusable values in your style.": "グローバルステート変数が定義されていません。スタイルで再利用可能な値を作成するには、変数を追加してください。",
"Open": "開く", "Open": "開く",
"Open a local JSON style from your computer.": "コンピュータからローカルJSONスタイルを開きます。", "Open a local JSON style from your computer.": "コンピュータからローカルJSONスタイルを開きます。",
"Open Layers (experimental)": "Open Layers (実験的)",
"Open local Style": "ローカルスタイルを開く", "Open local Style": "ローカルスタイルを開く",
"Open modal": "モーダルを開く", "Open modal": "モーダルを開く",
"Open one of the publicly available styles to start from.": "公開スタイルを選んで開始しましょう。", "Open one of the publicly available styles to start from.": "公開スタイルを選んで開始しましょう。",
"Open Style": "スタイルを開く", "Open Style": "スタイルを開く",
"OpenLayers (experimental)": "OpenLayers (実験的)",
"Options": "設定", "Options": "設定",
"Output value": "値", "Output value": "値",
"Owner": "所有者", "Owner": "所有者",
@@ -162,7 +154,6 @@
"Remove variable": "変数を削除", "Remove variable": "変数を削除",
"Remove zoom level from stop": "ズームレベルをストップから削除", "Remove zoom level from stop": "ズームレベルをストップから削除",
"Revert from expression": "式から戻す", "Revert from expression": "式から戻す",
"Roll": "ロール",
"Save": "保存", "Save": "保存",
"Save as": "名前を付けて保存", "Save as": "名前を付けて保存",
"Save Style": "スタイルを保存", "Save Style": "スタイルを保存",
@@ -173,8 +164,6 @@
"Shortcuts": "ショートカット", "Shortcuts": "ショートカット",
"Shortcuts menu": "ショートカットメニュー", "Shortcuts menu": "ショートカットメニュー",
"Show": "表示", "Show": "表示",
"Sky color": "空の色",
"Sky horizon blend": "空と地平線のブレンド",
"Source": "ソース", "Source": "ソース",
"Source ID": "ソースID", "Source ID": "ソースID",
"Source Layer": "ソースレイヤ", "Source Layer": "ソースレイヤ",
@@ -212,5 +201,6 @@
"Video URL": "動画URL", "Video URL": "動画URL",
"View": "表示", "View": "表示",
"You've entered an old style filter.": "旧型フィルタを使用しております。", "You've entered an old style filter.": "旧型フィルタを使用しております。",
"Zoom": "ズーム" "Zoom": "ズーム",
"Drag and drop a style JSON file here or click to browse": "ここにスタイルのJSONファイルをドラッグ&ドロップするか、クリックして参照してください"
} }
+3 -13
View File
@@ -13,12 +13,10 @@
"Add Variable": "변수 추가", "Add Variable": "변수 추가",
"any filter matches": "일부 필터 일치", "any filter matches": "일부 필터 일치",
"API key for Stadia Maps.": "Stadia Maps용 API 키 입니다.", "API key for Stadia Maps.": "Stadia Maps용 API 키 입니다.",
"Atmosphere blend": "대기 블렌드",
"Base": "베이스", "Base": "베이스",
"Bearing": "방위각", "Bearing": "방위각",
"Cancel": "취소", "Cancel": "취소",
"Center": "중심 좌표", "Center": "중심 좌표",
"Center altitude": "중심 고도",
"Choose Public Source": "공개 소스 선택", "Choose Public Source": "공개 소스 선택",
"Choose the default Maputnik renderer for this style.": "이 스타일의 기본 Maputnik 렌더러를 선택하세요.", "Choose the default Maputnik renderer for this style.": "이 스타일의 기본 Maputnik 렌더러를 선택하세요.",
"Click to close the editor": "편집기를 닫으려면 클릭하세요", "Click to close the editor": "편집기를 닫으려면 클릭하세요",
@@ -56,7 +54,6 @@
"Delete expression": "표현식 삭제", "Delete expression": "표현식 삭제",
"Delete filter block": "필터 블록 삭제", "Delete filter block": "필터 블록 삭제",
"Deuteranopia filter": "녹색맹 필터", "Deuteranopia filter": "녹색맹 필터",
"Drag and drop a style JSON file here or click to browse": "여기에 스타일 JSON 파일을 끌어다 놓거나 클릭하여 찾아보세요",
"Drag to resize the layer list": "드래그하여 레이어 목록 크기 조정", "Drag to resize the layer list": "드래그하여 레이어 목록 크기 조정",
"Drag to resize the sidebar": "드래그하여 사이드바 크기 조정", "Drag to resize the sidebar": "드래그하여 사이드바 크기 조정",
"Duplicate": "복제", "Duplicate": "복제",
@@ -67,9 +64,6 @@
"Export modal": "모달 내보내기", "Export modal": "모달 내보내기",
"Filter": "필터", "Filter": "필터",
"Focus map": "포커스 맵", "Focus map": "포커스 맵",
"Fog color": "안개 색상",
"Fog ground blend": "안개-지면 블렌드",
"Font faces": "폰트 파일",
"Function": "함수", "Function": "함수",
"Gallery Styles": "갤러리 스타일", "Gallery Styles": "갤러리 스타일",
"General layout properties": "일반 레이아웃 속성", "General layout properties": "일반 레이아웃 속성",
@@ -82,8 +76,6 @@
"Glyphs URL": "글리프 URL", "Glyphs URL": "글리프 URL",
"Help": "도움말", "Help": "도움말",
"Hide": "숨기기", "Hide": "숨기기",
"Horizon color": "지평선 색상",
"Horizon fog blend": "지평선-안개 블렌드",
"Icon layout properties": "아이콘 레이아웃 속성", "Icon layout properties": "아이콘 레이아웃 속성",
"Icon paint properties": "아이콘 페인트 속성", "Icon paint properties": "아이콘 페인트 속성",
"If the Map is in focused you can use the following shortcuts": "맵에 포커스가 맞춰진 경우 다음 단축키를 사용할 수 있습니다", "If the Map is in focused you can use the following shortcuts": "맵에 포커스가 맞춰진 경우 다음 단축키를 사용할 수 있습니다",
@@ -131,11 +123,11 @@
"No global state variables defined. Add variables to create reusable values in your style.": "전역 상태 변수가 정의되지 않았습니다. 스타일에서 재사용 가능한 값을 생성하려면 변수를 추가하세요.", "No global state variables defined. Add variables to create reusable values in your style.": "전역 상태 변수가 정의되지 않았습니다. 스타일에서 재사용 가능한 값을 생성하려면 변수를 추가하세요.",
"Open": "열기", "Open": "열기",
"Open a local JSON style from your computer.": "컴퓨터에서 로컬 JSON 스타일을 엽니다.", "Open a local JSON style from your computer.": "컴퓨터에서 로컬 JSON 스타일을 엽니다.",
"Open Layers (experimental)": "레이어 열기 (실험적)",
"Open local Style": "로컬 스타일 열기", "Open local Style": "로컬 스타일 열기",
"Open modal": "모달 열기", "Open modal": "모달 열기",
"Open one of the publicly available styles to start from.": "공개 스타일 중 하나를 선택하여 시작하세요.", "Open one of the publicly available styles to start from.": "공개 스타일 중 하나를 선택하여 시작하세요.",
"Open Style": "스타일 열기", "Open Style": "스타일 열기",
"OpenLayers (experimental)": "OpenLayers (실험적)",
"Options": "옵션", "Options": "옵션",
"Output value": "값", "Output value": "값",
"Owner": "소유자", "Owner": "소유자",
@@ -162,7 +154,6 @@
"Remove variable": "변수 제거", "Remove variable": "변수 제거",
"Remove zoom level from stop": "기준점에서 줌 레벨 제거", "Remove zoom level from stop": "기준점에서 줌 레벨 제거",
"Revert from expression": "표현식에서 되돌리기", "Revert from expression": "표현식에서 되돌리기",
"Roll": "롤 각도",
"Save": "저장", "Save": "저장",
"Save as": "다른 이름으로 저장", "Save as": "다른 이름으로 저장",
"Save Style": "스타일 저장", "Save Style": "스타일 저장",
@@ -173,8 +164,6 @@
"Shortcuts": "단축키", "Shortcuts": "단축키",
"Shortcuts menu": "단축키 메뉴", "Shortcuts menu": "단축키 메뉴",
"Show": "표시", "Show": "표시",
"Sky color": "하늘 색상",
"Sky horizon blend": "하늘-지평선 블렌드",
"Source": "소스", "Source": "소스",
"Source ID": "소스 ID", "Source ID": "소스 ID",
"Source Layer": "소스 레이어", "Source Layer": "소스 레이어",
@@ -212,5 +201,6 @@
"Video URL": "비디오 URL", "Video URL": "비디오 URL",
"View": "보기", "View": "보기",
"You've entered an old style filter.": "이전 스타일 필터를 입력했습니다.", "You've entered an old style filter.": "이전 스타일 필터를 입력했습니다.",
"Zoom": "줌" "Zoom": "줌",
"Drag and drop a style JSON file here or click to browse": "여기에 스타일 JSON 파일을 끌어다 놓거나 클릭하여 찾아보세요"
} }
+1 -11
View File
@@ -13,12 +13,10 @@
"Add Variable": "Değişken Ekle", "Add Variable": "Değişken Ekle",
"any filter matches": "herhangi bir filtre eşleşirse", "any filter matches": "herhangi bir filtre eşleşirse",
"API key for Stadia Maps.": "Stadia Maps için API anahtarı.", "API key for Stadia Maps.": "Stadia Maps için API anahtarı.",
"Atmosphere blend": "Atmosfer karışımı",
"Base": "Temel", "Base": "Temel",
"Bearing": "Yön", "Bearing": "Yön",
"Cancel": "İptal", "Cancel": "İptal",
"Center": "Merkez", "Center": "Merkez",
"Center altitude": "Merkez yüksekliği",
"Choose Public Source": "Herkese Açık Kaynak Seç", "Choose Public Source": "Herkese Açık Kaynak Seç",
"Choose the default Maputnik renderer for this style.": "Bu stil için varsayılan Maputnik işleyicisini seçin.", "Choose the default Maputnik renderer for this style.": "Bu stil için varsayılan Maputnik işleyicisini seçin.",
"Click to close the editor": "Düzenleyiciyi kapatmak için tıklayın", "Click to close the editor": "Düzenleyiciyi kapatmak için tıklayın",
@@ -67,9 +65,6 @@
"Export modal": "Dışa aktarma modalı", "Export modal": "Dışa aktarma modalı",
"Filter": "Filtre", "Filter": "Filtre",
"Focus map": "Haritaya odaklan", "Focus map": "Haritaya odaklan",
"Fog color": "Sis rengi",
"Fog ground blend": "Sis-zemin karışımı",
"Font faces": "Yazı tipi dosyaları",
"Function": "Fonksiyon", "Function": "Fonksiyon",
"Gallery Styles": "Galeri Stilleri", "Gallery Styles": "Galeri Stilleri",
"General layout properties": "Genel yerleşim özellikleri", "General layout properties": "Genel yerleşim özellikleri",
@@ -82,8 +77,6 @@
"Glyphs URL": "Glif URL'si", "Glyphs URL": "Glif URL'si",
"Help": "Yardım", "Help": "Yardım",
"Hide": "Gizle", "Hide": "Gizle",
"Horizon color": "Ufuk rengi",
"Horizon fog blend": "Ufuk-sis karışımı",
"Icon layout properties": "Simge yerleşim özellikleri", "Icon layout properties": "Simge yerleşim özellikleri",
"Icon paint properties": "Simge boyama özellikleri", "Icon paint properties": "Simge boyama özellikleri",
"If the Map is in focused you can use the following shortcuts": "Harita odaktaysa aşağıdaki kısayolları kullanabilirsiniz", "If the Map is in focused you can use the following shortcuts": "Harita odaktaysa aşağıdaki kısayolları kullanabilirsiniz",
@@ -131,11 +124,11 @@
"No global state variables defined. Add variables to create reusable values in your style.": "Genel durum değişkeni tanımlanmadı. Stilinizde yeniden kullanılabilir değerler oluşturmak için değişken ekleyin.", "No global state variables defined. Add variables to create reusable values in your style.": "Genel durum değişkeni tanımlanmadı. Stilinizde yeniden kullanılabilir değerler oluşturmak için değişken ekleyin.",
"Open": "Aç", "Open": "Aç",
"Open a local JSON style from your computer.": "Bilgisayarınızdan yerel bir JSON stili açın.", "Open a local JSON style from your computer.": "Bilgisayarınızdan yerel bir JSON stili açın.",
"Open Layers (experimental)": "Open Layers (deneysel)",
"Open local Style": "Yerel Stili Aç", "Open local Style": "Yerel Stili Aç",
"Open modal": "Modalı aç", "Open modal": "Modalı aç",
"Open one of the publicly available styles to start from.": "Başlamak için herkese açık stillerden birini açın.", "Open one of the publicly available styles to start from.": "Başlamak için herkese açık stillerden birini açın.",
"Open Style": "Stili Aç", "Open Style": "Stili Aç",
"OpenLayers (experimental)": "OpenLayers (deneysel)",
"Options": "Seçenekler", "Options": "Seçenekler",
"Output value": "Çıkış değeri", "Output value": "Çıkış değeri",
"Owner": "Sahip", "Owner": "Sahip",
@@ -162,7 +155,6 @@
"Remove variable": "Değişkeni kaldır", "Remove variable": "Değişkeni kaldır",
"Remove zoom level from stop": "Duraktan yakınlaştırma seviyesini kaldır", "Remove zoom level from stop": "Duraktan yakınlaştırma seviyesini kaldır",
"Revert from expression": "İfadeden geri dön", "Revert from expression": "İfadeden geri dön",
"Roll": "Yuvarlanma",
"Save": "Kaydet", "Save": "Kaydet",
"Save as": "Farklı kaydet", "Save as": "Farklı kaydet",
"Save Style": "Stili Kaydet", "Save Style": "Stili Kaydet",
@@ -173,8 +165,6 @@
"Shortcuts": "Kısayollar", "Shortcuts": "Kısayollar",
"Shortcuts menu": "Kısayollar menüsü", "Shortcuts menu": "Kısayollar menüsü",
"Show": "Göster", "Show": "Göster",
"Sky color": "Gökyüzü rengi",
"Sky horizon blend": "Gökyüzü-ufuk karışımı",
"Source": "Kaynak", "Source": "Kaynak",
"Source ID": "Kaynak Kimliği", "Source ID": "Kaynak Kimliği",
"Source Layer": "Kaynak Katmanı", "Source Layer": "Kaynak Katmanı",
+3 -13
View File
@@ -13,12 +13,10 @@
"Add Variable": "添加变量", "Add Variable": "添加变量",
"any filter matches": "任何过滤器匹配", "any filter matches": "任何过滤器匹配",
"API key for Stadia Maps.": "Stadia Maps 的 API 密钥", "API key for Stadia Maps.": "Stadia Maps 的 API 密钥",
"Atmosphere blend": "大气混合",
"Base": "基础", "Base": "基础",
"Bearing": "方位", "Bearing": "方位",
"Cancel": "取消", "Cancel": "取消",
"Center": "中心", "Center": "中心",
"Center altitude": "中心海拔",
"Choose Public Source": "选择公共源", "Choose Public Source": "选择公共源",
"Choose the default Maputnik renderer for this style.": "为这种样式选择默认的Maputnik渲染器。", "Choose the default Maputnik renderer for this style.": "为这种样式选择默认的Maputnik渲染器。",
"Click to close the editor": "点击关闭编辑器", "Click to close the editor": "点击关闭编辑器",
@@ -56,7 +54,6 @@
"Delete expression": "删除表达式", "Delete expression": "删除表达式",
"Delete filter block": "删除过滤器块", "Delete filter block": "删除过滤器块",
"Deuteranopia filter": "绿色盲滤镜", "Deuteranopia filter": "绿色盲滤镜",
"Drag and drop a style JSON file here or click to browse": "将样式 JSON 文件拖放到此处或点击以浏览",
"Drag to resize the layer list": "拖动以调整图层列表大小", "Drag to resize the layer list": "拖动以调整图层列表大小",
"Drag to resize the sidebar": "拖动以调整侧边栏大小", "Drag to resize the sidebar": "拖动以调整侧边栏大小",
"Duplicate": "复制", "Duplicate": "复制",
@@ -67,9 +64,6 @@
"Export modal": "导出模态框", "Export modal": "导出模态框",
"Filter": "过滤器", "Filter": "过滤器",
"Focus map": "聚焦地图", "Focus map": "聚焦地图",
"Fog color": "雾颜色",
"Fog ground blend": "雾与地面混合",
"Font faces": "字体文件",
"Function": "函数", "Function": "函数",
"Gallery Styles": "画廊样式", "Gallery Styles": "画廊样式",
"General layout properties": "常规布局属性", "General layout properties": "常规布局属性",
@@ -82,8 +76,6 @@
"Glyphs URL": "字形URL", "Glyphs URL": "字形URL",
"Help": "帮助", "Help": "帮助",
"Hide": "隐藏", "Hide": "隐藏",
"Horizon color": "地平线颜色",
"Horizon fog blend": "地平线与雾混合",
"Icon layout properties": "图标布局属性", "Icon layout properties": "图标布局属性",
"Icon paint properties": "图标绘制属性", "Icon paint properties": "图标绘制属性",
"If the Map is in focused you can use the following shortcuts": "如果地图处于焦点状态,您可以使用以下快捷键", "If the Map is in focused you can use the following shortcuts": "如果地图处于焦点状态,您可以使用以下快捷键",
@@ -131,11 +123,11 @@
"No global state variables defined. Add variables to create reusable values in your style.": "未定义全局状态变量。添加变量以在样式中创建可重用的值。", "No global state variables defined. Add variables to create reusable values in your style.": "未定义全局状态变量。添加变量以在样式中创建可重用的值。",
"Open": "打开", "Open": "打开",
"Open a local JSON style from your computer.": "从您的计算机打开本地JSON样式。", "Open a local JSON style from your computer.": "从您的计算机打开本地JSON样式。",
"Open Layers (experimental)": "开放图层(实验性)",
"Open local Style": "打开本地样式", "Open local Style": "打开本地样式",
"Open modal": "打开模态框", "Open modal": "打开模态框",
"Open one of the publicly available styles to start from.": "打开一个公开可用的样式开始。", "Open one of the publicly available styles to start from.": "打开一个公开可用的样式开始。",
"Open Style": "打开样式", "Open Style": "打开样式",
"OpenLayers (experimental)": "OpenLayers(实验性)",
"Options": "选项", "Options": "选项",
"Output value": "输出值", "Output value": "输出值",
"Owner": "所有者", "Owner": "所有者",
@@ -162,7 +154,6 @@
"Remove variable": "移除变量", "Remove variable": "移除变量",
"Remove zoom level from stop": "从停靠点移除缩放级别", "Remove zoom level from stop": "从停靠点移除缩放级别",
"Revert from expression": "从表达式恢复", "Revert from expression": "从表达式恢复",
"Roll": "翻滚角",
"Save": "保存", "Save": "保存",
"Save as": "另存为", "Save as": "另存为",
"Save Style": "保存样式", "Save Style": "保存样式",
@@ -173,8 +164,6 @@
"Shortcuts": "快捷键", "Shortcuts": "快捷键",
"Shortcuts menu": "快捷方式菜单", "Shortcuts menu": "快捷方式菜单",
"Show": "显示", "Show": "显示",
"Sky color": "天空颜色",
"Sky horizon blend": "天空与地平线混合",
"Source": "源", "Source": "源",
"Source ID": "源ID", "Source ID": "源ID",
"Source Layer": "源图层", "Source Layer": "源图层",
@@ -212,5 +201,6 @@
"Video URL": "视频URL", "Video URL": "视频URL",
"View": "视图", "View": "视图",
"You've entered an old style filter.": "您输入了一个旧风格的过滤器。", "You've entered an old style filter.": "您输入了一个旧风格的过滤器。",
"Zoom": "缩放" "Zoom": "缩放",
"Drag and drop a style JSON file here or click to browse": "将样式 JSON 文件拖放到此处或点击以浏览"
} }
+3
View File
@@ -13,6 +13,9 @@
//APP LAYOUT //APP LAYOUT
.maputnik-layout { .maputnik-layout {
// Kept up to date by AppLayout as the sidebar is resized.
--sidebar-width: #{vars.$layout-list-width + vars.$layout-editor-width};
font-family: vars.$font-family; font-family: vars.$font-family;
color: vars.$color-white; color: vars.$color-white;
+3
View File
@@ -21,6 +21,9 @@ $font-family: Roboto, sans-serif;
$toolbar-height: 40px; $toolbar-height: 40px;
$toolbar-offset: 0; $toolbar-offset: 0;
$layout-list-width: 200px;
$layout-editor-width: 370px;
// 'menu-down' from 'https://materialdesignicons.com/' // 'menu-down' from 'https://materialdesignicons.com/'
// See <https://github.com/Templarian/MaterialDesign/blob/master/LICENSE> // See <https://github.com/Templarian/MaterialDesign/blob/master/LICENSE>
$icon-down-arrow: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24'><path fill='white' d='M7,10L12,15L17,10H7Z' /></svg>" $icon-down-arrow: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24'><path fill='white' d='M7,10L12,15L17,10H7Z' /></svg>"